从程序员的角度来看DNA

  最近看了一篇老外的文章:DNA seen through the eyes of a coder,觉得写得挺有意思的,DNA和程序的种种相似的地方,百度GOOGLE了下,好象没有翻译的,我就试着翻译了一下,各位如果觉得有兴趣的就来了解下这个地球上最伟大的软件工程吧,呵呵。

  原文:http://ds9a.nl/amazing-dna/,里面讲生物方面讲得挺多,有些地方太专业了翻译得不是很好,另外删掉了一些无关紧要的东西,有些地方如果文不达意还请各位海涵了。

  译文:

  这只是一个计算机程序员关于DNA的杂想,我并不是一个分子遗传学专家。

 

       源代码

这里,这不是在开玩笑。这些源代码可以通过一个叫做‘Ensembl’的perl脚本查看。

       DNA并不像C的代码,更像在虚拟机上编译的代码,我们叫它‘核’。这让人怀疑到底有没有源代码来进行这些编译,或者说,这就是这样的。

       DNA的代码语言是数字形式的,但不是二进制的。二进制是0和1两种数字组成的编码,但是DNA有4种:T,C,G和A。

       我们常用的1个字节有8位,而DNA的1个字节(称为‘编码子’)有3位,每一位有可以有4个值,而不是2个值(0和1)。所以一个基因编码子有64个可能的值。

       DNA编码子的一个典型的例子是‘GCC’,氨基酸丙氨酸由它编码而成。大量的这些氨基酸的聚合体成为‘多肽'’或者‘蛋白’,而这些就是在生命诞生过程中的不可缺少的化学活性物质

 

       位置独立的代码

       动态链接库(大家应该都用过吧),在DNA里也有类似的,被称为‘置换代码’:

       将近一半的人类基因组是由一些可以换位的片段或者一些跳跃基因组成,这是20世纪40年代Dr. Barbara McClintock在研究一种在印度玉米上发现的有关颜色奇特遗传方式时首次发现的,跳跃基因是指DNA的某些片段不是很稳定并且会‘换位’,例如,他们会在染色体的前后移动。(作者的意思大概是指这些‘置换代码’,也就是动态链接库,会被加载到染色体代码的前面或者后面)

 

       条件编译

       一般认为大概有20000到30000个基因在人类基因组里,大部分细胞只使用了很小一部分基因的功能,这是有道理的,1个肝细胞只需要整个DNA代码的很小一部分来完成它的功能:作用于神经元。

       但是几乎所有的细胞都携带着一个基因组的完整拷贝,所以这整套基因代码里必须有 #ifdef这样的条件语句来指定哪些代码是不需要的,那么这些细胞是如何工作的就说得通了。基因代码里充满了大量的 #if/#endif 这样的语句。

       这就是为什么现在‘干细胞’这么火,这些细胞具有分化成其他任何一种细胞的能力。可以这么说:这些代码还没有被加上 #ifdef 。

       说得更准确些,干细胞并不是同时把自身的一切都转化----他们不能立即变成肝细胞和神经元细胞。细胞可以被当做是一个状态机,最开始,它是一个干细胞,在这个细胞的生命周期内,它可以克隆很多次,每次它都在向一个特殊的方向分化。每次向一个特殊的方向分化都可以视为在一根大枝干上选择一根小枝干(N叉树?)。

       每个细胞都可以决定(或者说是被诱导到)自己的未来,每次它的决定都会导致它更加特殊化。这些选择带来的改变都具有持久性,因为在克隆过程中是使用转录因子修改DNA来存储选择带来的改变(‘立体效应’)。

       肝细胞,虽然它携带的基因让它做肝细胞该做的事,而且一般不会起到一个皮肤细胞的作用。有迹象表明有可能‘培育’细胞让它沿着分化体系‘前进’,(有点类似于C++里的派生?)进而使他们具有其他的各种功能。

       垃圾代码

       基因组里遍布一些基因的旧副本,这是在大概50万年前到现在之间的某段时期里,出了问题的一些实验性质的基因。这些代码存在但是没有被激活。他们被称为‘伪基因’。

       此外,你的DNA里面有97%的代码是被注释掉的。DNA可以像捋一根线一样的从头读到尾,而那些没有被解码过的部分则显示得很清楚,就像C里的注释。那些在3%里直接被使用的基因被成为‘外显子’,而其余那些注释,被称为‘内含子’。

       这些注释,他们表现出的一些特性很让人着迷。像C里面的注释一样,他们也有一个起始符,就像 /*,并且他们也有一个结束符,就像 */。不过他们有着更多的结构。DNA更像是一卷磁带,那些注释必须要用物理的方式给剪切掉!注释的开头几乎总是显示成‘GT’,与 /* 对应,结尾则显示成‘AG’,对应 */。

       但是由于剪断了DNA,则需要一些‘胶水’把在注释之前的代码和注释之后的代码粘起来,这些更像是HTML的注释,以‘<!--'’标志着开始,‘-->’则是结束。

 

       一段有着外显子和内含子的基因片段看起来就像如下所示:

ACTUAL CODE<!-- blah blah blah blah ---- blah -->ACTUAL CODE
  |         |            |           |        |        |
外显子1  注释开头    内含子 1     分支   注释结尾  外显子 2
 

       注释的开头是很清晰的,接下是许多没有编码的DNA。在很接近注释结尾的某处有一个‘分支’(符号),表明注释很快就要结束,‘分支’后面还有一小段注释,最后就是结尾。

       在DNA转录成RNA之后,就开始注释的剪切,首先循环遍历注释段并把一段段代码合在一起,然后RNA会在接近注释结尾的‘分支’处被切断,在这之后注释开头和注释结尾会连接起来。

       那么,这些注释到底有什么用呢?关于这个的讨论可以同VI和EMACS之争相媲美。当比较不同的物种时,我们发现一些内含子比邻近的外显子表现出了更少的代码改动,这表明这些注释起着一些重要的作用。

       Fork() 分裂炸弹(‘肿瘤’)

       与UNIX一样,细胞不是孵化的,而是分裂出来的。所有的细胞都是从最开始的卵细胞分裂多次而来。就像进程一样,执行fork()(fork()是UNIX里的一个函数,可以启动一个子线程,子线程是父进程的拷贝)的2部分(几乎)是相同的初始状态,之后就由他们所执行的功能来决定他们的不同

       与UNIX一样,当细胞不断分裂时会出现大麻烦。他们很快就用尽了资源,有时甚至导致死亡。这就是肿瘤。细胞里充斥着’ulimits’ and ‘watchdogs’(ulimit是UNIX里一个改善系统性能的命令,watchdogs是UNIX里一个计时用的函数)来阻止这种事情的发生。分裂的数量由端粒缩短来限制,例如:

       一个细胞一般情况下不能克隆,除非满足非常严格的条件---一个‘默认的安全体系’的配置。只有这些安全体系失效时肿瘤才会发生。就像计算机的安全体系,很难在安全与可用性之间取得平衡。

       与此相比的是著名的Halting Problem,计算机科学的创始人,Alan Turing首先提出的。也许创造一个不会得癌症的基因组,就像预言一个程序是否结束那样是不可能的。

       镜像,失效转移

      每条DNA螺旋本身是多余的,你可以看见,基因组像一个扭曲的梯子,每个阶梯上都有2个碱---这就是‘碱基’这个词的由来。如果其中一个碱丢失了,它可以从另外一边的碱那里复制过来。T总是和A绑定,C对应G。所以,我们可以说,基因是螺旋结构形成的镜像。‘RAID-1’就是如此。

       此外,每一个染色体都是成对存在的,除了那个众所周知的只存在于男性中的Y染色体。这其中的细节比较复杂,不过大部分基因都有备份。在某种情况下其中一个损坏或者不幸变异了,就能通过与备份的对照很快纠正错误,并进行修补。这就是我们通常所说的‘失效转移’。

       混乱的API,见鬼的依存关系

       蛋白质在细胞内的互相作用,依赖于他们彼此的特性。不久前才发现的一个事实是,那些与大量其他蛋白质互相作用的蛋白质不会产生进化,或者至少,这样的比率非常小。

       他们解释这是因为有非常多的内部依存关系在抑制着这些蛋白质之间‘合作关系’的变化。他们同时指出,进化确定在发生,但是非常缓慢,因为依存关系的双方需要在同一时间以合适的方式一起进化。

       病毒,蠕虫

       最近有人在一个讨论中提到,如果能破解基因组,让它向我们开放权限,那么我们就可以插入一段代码进去,使它可以把其他基因组复制成他本身,并用它的宿主作为载体,这办法真是酷毙了。‘就像尼姆达病毒’。

       然后他马上意识到这不就是生物病毒在这几百万中中所作的吗,的确他们非常擅长这个。

       许多病毒都成为了我们基因组的一个固定部分,并借此在我们之间传播。要做到这些,他们必须隐藏自身避免被那些病毒扫描系统发现,这些病毒扫描系统会检测一些外来的代码并阻止他们进入到DNA里去。

       中心法则:.c -> .o -> a.out/.exe

       当科学家们在探索遗传学的本质时,他们碰到了数量巨大的相互作用还不是很清楚的化合物。总有一天,当一切都搞明白的时候,他们会欣喜若狂,并称呼这为‘中心法则’。

       这个法则告诉我们DNA被用来生成RNA,RNA被用来生成蛋白质,这是不是跟:.c文件生成.o文件,并生成一个可执行文件(a.out/exe)这个过程很相象呢。这是信息传递的唯一顺序。

       但是这个中心法则最近被发现有一些污点。就像那些存在了几亿年的古老软件项目,其中被插入了许多病毒代码,并且有时候信息传递会走另外一条道。有时候RNA会修补DNA,而在某些时候,DNA在蛋白质生成之前就被修改了。

       不过总的来说,这些依存关系是很明确的,所以中心法则仍然是很重要的。

       二进制补丁,又名‘基因疗法’

       我们可以尽可能的改动DNA。有一些公司就做这个,你可以把一个由DNA字符组成的ASCII文件发给他们,然后他们会把这个综合成一个对应的‘输出’给你。我们同样可以通过动植物的遗传把DNA接入到动物或者植物体内。

       但是更难的是‘为运行中的程序打补丁’,许多程序员都为这个犯难。这就如同基因组。要改变一个运行中的拷贝(‘一个人类’),如果你要为他的基因组打上补丁,你就必须修改每一个与基因组相关的拷贝。

       许多年以来,医学家们试图对患有‘联合免疫缺陷病’的病人的DNA进行修复。‘联合免疫缺陷病’是一种棘手的病症,它会让你的免疫系统失效,进而让你患上一些重症。我们需要找出并修补那段被插入了恶意代码的DNA片段才能治愈这些人。

       他们做了许多尝试去修复这些‘正在运行’的‘人类系统’,包括使用病毒来插入新的DNA片段到保持活力的有机体组织中,不过这都被证明是非常困难的。基因体的防御无懈可击,即使是最简单的方式也没有任何作用----细胞们在保护他们的代码这方面做得比微软好多了。

       不过,最近发现了一种特殊的病毒,它可以冲破基因们的防线,并且修复被损坏的字节,让患者们重回健康。

       修补BUG

       当修复一个电脑程序的BUG时,我们总是又带来了另外一个BUG。基因组里也充斥着此类事情。许多非洲裔美国人对疟疾免疫,但是同时又患有镰状细胞性贫血。

       里德-索罗门码:‘前向纠错’

       就像电脑存储一样,DNA(以及它的中间物‘RNA’)也会出错。为了防止‘single bit errors’,从单独的DNA字节到一个蛋白质的编码过程是可退化的。有4种RNA符号,U,C,G和A,即一个‘位’相当于我们通常的2个比特。3个RNA字符组成一个氨基酸。6个比特可以组合成64种氨基酸,但是只有20种有用。举个例子,UCU,UCC,UCA和UCG编码成‘丝氨酸’,但是UGG却只对应‘色氨酸’。

       现在,事实证明,一些相似的‘错误’(UCU –)UCC)在编码过程中会形成相同的氨基酸,这令人费解。

       上帝码:/* you are not expected to understand this */

       有些代码很神秘。我们不知道是谁写的,为什么而写----我们只知道它有用。或许写这些代码的人已经离开了公司,因为这些代码从未被修改过。

       DNA似乎知道‘分子钟‘的概念。基因组的有些部分正在积极的发生变化而有些则显得神圣而不可侵犯。后者的一个很好的例子就是H3和H4蛋白基因。

       这些基因对整个基因组来说至关重要,它的重要性是最高等级的。如果这段代码出了错,就会产生一个没有任何功能的有机体。

       这些代码从未被修改过,H3和H4基因在人类进化过程中的变异率为零。但还远远不止如此,这些代码也同样存在于其他物种的DNA内,像鸡,草,霉菌之类。

       现在,我们可以确定有2种方式保证基因代码不发生变异。第一种在前面已经说过了。

       此外,在细胞的复制过程中,基因的复制可早可晚,取决于复制条件的好坏。

       这样看来H3和H4是被非常小心的编写出来的,因为他们有太多的‘synonymous changes’,这些正是通过前面所说的的技术保证结果不会被改变。

       桢错误:启动和停止位

       ...0 0000 0001   0000 0010  0000 0011 0...

       这些清楚的描述了8位值:1,2和3。我添加的这些空格清楚的表明了一个字节的开始和停止。许多串行设备采用启动和停止位来标记你该从哪读起。如果我们稍微改变一下这个顺序:

       ...00 0000 0010   000 00100  000 00110 ...

       它突然读到了2,4,6!为了阻止这样的错误在DNA里发生,有一些特殊的标记来告诉细胞该从哪开始。有趣的是,有一些基因片段可以从不同的起始位置开始进行读取,并且每种方式都产生有用的(但是不同)的结果。我称这为‘cool hack’。

       海量多线程:每个细胞都是一个宇宙

       DNA跟电脑编程语言不一样。实际上它也并不是。但是有一些惊人的相似之处。我们可以把每个细胞看做是一个CPU,运行着自己的内核。每个细胞都有整个内核的拷贝,不过只选择激活那些跟自己有关的部分。可以这么说,它有选择性的加载对自己有用的驱动或者模块。

       如果一个细胞想做某件事(调用一个函数),它会激活基因组的某个片段并转录成RNA。RNA马上转化成一系列的氨基酸,然后这些氨基酸组合成蛋白质。

       这些蛋白质被标记上了运送地址。这是一个由许多氨基酸组合而成的标记,这个标记告诉细胞这个蛋白质要去的位置。然后依照这些指示细胞运用一些机械方法将蛋白质运送出去,这时候蛋白质可能在细胞外的某个位置。

       然后这个运送指令会被卸除,其他一些运行步骤被相继被传达过来,也许是激活这个蛋白----这很好,因为运送途中活性蛋白会发挥它应有的作用。

       自托管和引导

       如果我们销毁这个星球上所有的C编译器,并且只留下某个编译器的源代码,我们将会有很大的麻烦。是的,我们有能编译出编译器的C代码,却缺少一个C编译器来编译它。

       事实上,要解决这个,不是用C写一个C编译器,而是需要一个已经支持编译的语言:B。

       这同样适用于基因组。要创建一个新的‘二进制’样品,需要一个‘活着的’拷贝。基因组需要一个复杂的工具链来传递活性物质。代码自身是无能为力的。这个工具链被称为‘your parents’

       这样看来,RNA,一个介于DNA和蛋白质之间的中间码,将是DNA所需要的‘B语言’。有趣的是外星物质经常包含有氨基酸。

       The Makefile

       有机体的形成通常从一个单细胞开始,如同我们前面说的包含有整个基因组的2个拷贝。就像整个压缩包,已经准备要解压出所有的文件。然后呢?

       我们来看看同源盒基因(是一段在果蝇中发现的编码60个氨基酸的DNA序列),细胞开始被复制并且被赋予了一个未来的走向,这时同源盒基因开始运作,首先会形成一个‘从上至下’的‘建造’关系,这个‘建造’关系从‘头部发育’开始。为了让这一切发生,需要创造一个化学梯度,这样细胞可以感应到他们在哪里,才能决定是否要做些对头部发育有用的事情,或者生成一个原生脊索。

       自从在1983年被发现,同源盒基因的研究到现在为止都是一个激动人心的研究领域。有趣的是,就像一个MakeFile,‘HOX’基因只起到激活其他基因的作用,它本身并不参与发育过程。

       同源盒基因的‘语法’在上面提到的过程里似乎是很‘神圣’的。如果你把一只老鼠的‘HOX’基因里的‘腿的selector’的这一段复制并粘贴到一只果蝇的同源盒基因里,那样会发生什么呢:

       ‘事实上,当一只老鼠的Hox-B6基因插入到果蝇里时,它会代替掉Antennapedia(一段基因片段),并且会在原来长出触须的地方长出腿来’

       果蝇和人类的基因组并不是在数百万年产生的分支,而是在数百个百万年前。你复制并粘贴Makefile的某个部分(用基因的语言来说就是‘Selector’)以后它仍旧可以接合起来。请注意,‘长出一条腿’这个在果蝇里的例行程序跟老鼠的是完全不一样的,但是‘Selector’准确的触发了正确的指示。

posted on 2010-11-01 21:13  用力中...  阅读(1691)  评论(1编辑  收藏  举报

导航