2.4 早发布,常发布

    尽早和尽量频繁发布是Linux开发模式中至关重要的一部分,绝大多数开发者(包括我)都习惯性地认为:除非是很小的项目,这么做有害无益,因为软件的早期版本几乎都是问题版本(buggy version),如果早早发布,恐怕会耗尽用户们的耐心。

    这种观念使人们更倾向于支持大教堂开发模式,但如果最重要的目标是给用户提供bug尽量少的软件,为什么你只是每六个月(或者更长间隔时间)才发布一个版本,并且在版本发布的间隔里忙得喘不过气来呢?Emacs用C写的内核是按照这种方式开发的,而Lisp库却不是,因为真正起作用的Lisp代码资源库并不在FSF的控制之下,在那里你可以找到新的和不断发展中的代码版本,而且它们都独立于Emacs的发布周期。 2

    这里面最重要的要数俄亥俄州(Ohio)的Emacs Lisp代码资源库,该库早早就拥有了如今大规模Linux资源库所具备的精神和特性,但当时我们几乎没人认真去想想我们在做什么,或者想想资源库的这种存在,是否意味着FSF大教堂式的开发模式有点问题。1992年左右我做过一次认真的尝试,我从这个代码库中下载了很多代码,并将其正式融入Emacs的官方Lisp库中,很快我遇到了类似政治上的麻烦,尝试非常不成功。

    但是一年后,Linux越来越广为人知,它明显与众不同而且要健康得多。Linus开放式的开发策略简直就是和大教堂模式对着干,Linux的Internet资源库生机勃勃,多个不同版本同时流传,而这完全是由Linux内核那前所未闻的频繁发布所驱动的。

    Linus把他的用户当作开发合作者看待,并以一种尽可能最有效的方式:

    7.早发布,常发布,倾听用户的反馈。

    Linus的创新之处,并不完全在于大量采纳用户反馈并快速发布系统版本(这也是UNIX世界多年来的传统),而更多在于将这种做法强化到一种能和系统复杂度相匹配的强度。我们知道他在早期(1991年左右)发布内核的频率会超过一天一次!这要归功于他在发展合作开发群体方面的努力,Linus比其他任何人都更在意如何利用Internet杠杆促进合作,而且他真的做到了。

    他是怎么做到的?我能否加以复制?还是说只有Linus Torvalds这样的天才才能驾驭?

    我想不是。Linus无疑是一个顶级黑客,想想有多少人能从零开始建造一个完整的具有产品级质量的操作系统内核?但Linux并没有展现出多少令人赞叹的概念性突破。和Richard Stallman或者James Gosling(NeWS和Java的作者)相比,Linus不是(至少现在还不是)一个富有创造性的设计天才,他更像是一个工程实施上的天才,他具备一种避免bug和防范开发走入死胡同的第六感,而且有一种能发现从A点到B点最省力路径的真本事,事实上,Linux的整个设计,都透露着这种特质,并反映了Linus那种本质上保守而简洁的设计取向。

    所以,如果快速发布和利用互联网杠杆效应不是碰巧而为,而是Linus慧眼发现的最省力路径,那么他最想利用的是什么?什么是他最想从这种开发机制中获取的好处?

    这样一问,答案就显而易见了。Linus在持续不断地激励和回报着他的黑客/用户,用自我满足感激励他们,用持续改进(甚至每天都有改进)回报他们。

    Linus的直接目标就是将投入排错和开发的“人时”(person-hour)最大化,即便这样做可能导致代码不稳定,或者可能因为一些难以消除的严重bug导致用户群流失,Linus也在所不惜,他相信:

    8.如果有足够多的beta测试者 [1]和合作开发者,几乎所有问题都会很快显现,然后自然有人会把它解决。

    或者说得更通俗一些:“只要眼睛多,bug容易捉。”我把它称为“Linus定律”。

    最初我的表达是“每个问题都会有人弄明白”。Linus提出异议,他认为那个弄明白并修复问题的人往往不是也没有必要是那个首先发现问题的人,“有人发现问题,”他说,“另有人搞定问题,我可以公开地说,发现问题更具挑战性。”这个改正很重要。我们会在下一节仔细考查排错过程到底是怎样的,但关键在于,Linux模式下排错的两个部分(发现问题和修复问题)通常都很快。

    Linus定律道出了大教堂模式和集市模式最关键的区别:在大教堂建筑者看来,bug是棘手的、难以发现的、隐藏在深处的,要经过几个人数月的全心投入和仔细检查,才能有点信心说已经剔除了所有错误。而发布间隔越长,倘若等待已久的发布版本并不完美,人们的失望就越发不可避免。

    对集市模式而言则完全不同,在上千名合作开发者热切钻研每个新发布版本的情况下,你可以假定bug是浅显易找的,或者至少可以很快变得浅显易找。所以你会频繁发布以获取更多的修正,其副作用是良性的:即便发布中有些小问题,你也不会损失太多。

    就是这样,这就足够了。如果Linus定律是错的,那么任何一个像Linux内核这么复杂的系统,经过如此多黑客的改动,在无法预见的不良交互影响以及难以发现的“深度隐藏”bug的重压下,应该已然在某个时刻轰然倒塌了。如果Linus定律是对的,它可以很好解释Linux为什么bug相对较少,且连续运行时间能够超过数月甚至数年。

    也许人们不该为这个定律而惊讶,社会学家早在多年前就发现,一群专家(或一群无知的家伙)的平均观点要比一个随机选择的人的观点更有预见性,这就是“德尔菲效应”(Delphi effect)。看来Linus的做法表明这个理论甚至也适用于操作系统排错——“德尔菲效应”可以驯服软件开发的复杂性,甚至是操作系统内核开发这样的复杂性。 3

    Linux对“德尔菲效应”提供支持的一个特别之处在于,给定任何一个Linux软件项目,其成员都是自发选择参与的。早前有读者指出,对Linux做出贡献的人并不是没有规律的,他们是这样的个体:他们有很大的兴趣使用软件、了解其工作原理、尝试解决遇到的问题并实际给出一个明显合理的解决办法。具备这些特点的人很有可能贡献出有价值的东西。

    Linus定律也可被表述为“排错可以并行”,尽管调试人员在排错时需要协调开发人员并与之交流,但调试人员之间并不怎么需要协调,也就是说,增加调试人员并不会带来增加开发人员那样的二次方复杂性和管理成本。

    理论上,并行排错会由于重复劳动导致效率损失,但从Linux世界的实践来看,这似乎从来不是一个问题。“早发布、常发布”策略的一个效果就是快速传播反馈回来的修复,从而使重复劳动最小化。 4

    Brooks(《人月神话》的作者)曾经在非正式场合说过:“对于一个被广泛使用的软件,其维护成本通常是开发成本的40%或者更多。令人惊奇的是,这个成本受到用户数的严重影响,用户越多,发现的bug就会越多。”

    “用户越多,bug越多”是因为增加用户就会增加程序检验的方式。当用户是合作开发者时,这种效应会被放大,每个着手去发现bug的人,都会有不同的视角,并使用各自略微不同的捕捉方法和分析工具。“德尔菲效应”似乎就是因为这种差异而变得有效。在排错这个特定场合下,差异也使得重复工作倾向于变少。

    从开发者角度来看,增加更多的beta测试者似乎并不能减少当前“隐藏最深”bug的复杂度,但这种做法会使bug发现的概率变大:某人的那套环境正好匹配某个问题,使得那个bug容易被他发现。

    为防范严重bug给用户带来的影响,Linus有这么一招:在Linux内核版本号上加以标识(可以从版本号看出系统是否稳定——译者注),潜在用户要么选择上一个被标识为“稳定”的版本,要么冒着有bug的风险使用最新版本以获取新特性。这种策略还没有被Linux黑客们系统性地加以模仿,也许他们以后会这样做。事实上,给用户以选择使得两种版本都更具吸引力。 5