全部博文(272)
分类: LINUX
2009-11-27 11:54:43
尽早和尽量频繁的发布是Linux开发模式的一个重要部分。包括我在内的大多数开发人员都曾一贯认为——对于一个大型工程来说这并不是个好办法。因为早期版本几乎就是问题版的同义词,而你却并不想过早地把用户的耐心消耗殆尽 。
这种信念促使人们普遍采用大教堂式的开发模式。如果首要目标是令用户尽可能少的遭遇错误,那么何不半年(或者更久)发布一次呢?这样我们就有充足的时间在各版本间努力进行调试。Emacs的C核心就是这样开发的,而Lisp库则恰恰相反——在软件基金会所辖以外,有很多独立的新版本或研发代码可供选择。【注1】
其中最重要的,俄亥俄州立大学的Emacs Lisp 存档,在当时就已经具有了今天Linux大型数据管理的许多精神与气质。但是我们之中少有人深思过究竟要做什么,以及这个存档的存在暴露了软件基金会大教堂模式的哪些问题。在1992年前后,我曾尽力想把大量的俄亥俄代码融入官方数据库,但是却在政治纠葛下半途而废了。
一年后,Linux的影响逐步扩大。显然,这要归结于一些另类不过更加有益的理念。李纳斯的开放性方针与大教堂模式大不相同。Linux的网络存档枝繁叶茂,各色发行版在坊间流传。而所有这一起都要归功于这种前所未有的核心发布模式。
以最有效的方法,李纳斯把用户视作合作伙伴:
7.早发布,常发布。并听取用户意见。
Release early. Release often. And listen to your customers.
快速发布,汲取用户反馈并不是李纳斯的创新(Unix世界历来如此),而他的创举在于将这个方法推升到了能和开发中的复杂度相匹敌的高度。早先(1991年前后)我不是没听过他那个一天之内不止一次发布核心的故事!因为他比其他任何人都辛勤的培养合作群体,促成网络协作。这是卓有成效的。
这是如何生效的?难道是源于李纳斯的天赋?
我不这么认为。无可厚非,李纳斯是个骨灰级的黑客(我们之中有几个可以从无到有创造一个企业级的操作系统内核呢?),但是Linux并不代表任何理念上的飞跃。李纳斯也不像(至少目前没有)理查德·斯多曼和詹姆斯·戈士林(NeWS和JAVA之父)那样在在设计领域天赋异禀,在我看来,他的才智更多的表现在操控和执行中。凭借着规避错误和防止陷入僵局的第六感,他能够发现解决问题的捷径。事实上,整个Linux的设计都散发出这种气质,处处体现出他质朴简洁的设计风格。
承上所述,如果快速发布和淋漓尽致的使用网络协作并非天成,而是源自李纳斯的操控天赋和对捷径的洞见。那么他究竟要把什么挥洒至极,又打算从中释放什么呢?
这样一问,答案自明。李纳斯让他的用户/黑客们不断得到激励和奖赏:激励源自参与过程中的自我实现,而奖赏则是那些持续(甚至是每天)的改进。
李纳斯直接锁定了在开发和调试中“人力—时间”绩效最大化的目标,甚至牺牲程序的稳定性以及因为难以修正的错误而流失用户也在所不惜。似乎他坚信:
8.只要有足够多的人手参与公测和开发,任何问题都会显而易见并被很快化解。
Givena large enough beta-tester and co-developer base, almost every problemwill be characterized quickly and the fix obvious to someone.
更通俗一点,就是:“足够多的眼睛,就可让所有问题浮现”,我称之为“李纳斯定律”
我最初的表述是:“(任何问题)都会被某人化解”,李纳斯却对此存有异议,他认为问题的发现和解决并不一定要由同一个人来完成,甚至可以说解决问题的通常不是发现者本人,我想这个纠正是必要的。“有人发现问题”,他说道。“其他人解决问题,而我要特别强调——发现问题才是重头戏。”在下面的章节,我们会深入探讨在调试时会发生什么。而关键是,在Linux的世界里无论发现还是修补问题都很迅速。
这就是大教堂与市集模式的区别。在修建教堂时,你所面临的错误和开发中的问题狡黠凶险、隐伏至深。哪怕几个人在几个月的时间里竭尽全力也不见得能把它们通通解决。一旦漫长的等待换来不尽如人意的产品,那么失望就在所难免了。
另一方面,站在市集的角度。你可以假设所有问题都是显而易见的——至少在上千个热情参与者的反复推敲下,它们都会变得显而易见。频繁的发布可以换取更多的修正,所以偶尔捅个大漏子也没什么大不了的!
这足可以说明问题了。如果“李纳斯定律”是错的,那么一个像Linux内核这么杂糅的东西,早该毁于一旦了。罪魁祸首自然是那些根深蒂固的错误和持续的恶性循环。换个角度,如果它是对的,也足够解释为什么Linux历来罕有错误,并且能经年累月的持续运营。
大可不必为“三个臭皮匠顶个诸葛亮”而感到诧异。多年以前,社会学家就证实:一群同样内行(或白痴)的人做出的平均预测要比其中任意一个都准确。这被称为“德尔菲效应”。[1]显然,李纳斯是把这用在操作系统调试上了。然而即使面对如同操作系统内核这样的复杂之事,“德尔菲效应”也能应对自如。【注2】
在Linux世界里,每个贡献者都是自愿参与的,这也是促成“德尔菲效应”的特别之处。早期有评论指出,这些贡献者不是随机产生的,而是要经过层层过滤。这包括:要有足够的兴趣使用软件;意图了解其运行机理;尝试自己解决遇到的问题;并且能做出实质性改进。最终产生的贡献者往往是有真材实料的家伙。
“李纳斯定律”也可以描述成“平行调试”。有时调试者可能需要和开发人员取得联系,但是他们彼此之间却不需要多少协调。故而增加开发者并不会带来成指数增长的复杂度和边际成本。
理论上,重复劳动带来的能效消耗在Linux世界一直算不上个大问题。“早发布,常发布”策略的一个结果,就是用准确及时的反馈来尽可能的减少了重复劳动。【注3】
甚至对此,布鲁克斯(《人月神话》的作者)曾做过一个非正式的论述:“一款广泛使用的软件,其维护费用是开发成本的40%以上。令人惊讶的是,其受用户影响很大,用户越多发现的错误就越多”【这是我所要强调的】
增加用户意味着增加检测程序的角度,自然发现的问题就更多。当用户参与协同开发的时候这个效应便扩大了。在纠错的时候,大家可以用不同的观察方法和分析工具,从不同视角逼近同一个问题。“德尔菲效应”便应运而生了。在这个特定的调试环境下,多样性也有助于减少重复劳动。
从开发者的角度看,更多的公测参与也许不能让最棘手的问题易于梳理。但是却能增加为解决问题找到合适人选的机会,对于这些人来说,某些问题或许称不上问题。
李纳斯还留了一手。Linux可以在出现重大缺陷的时候,为用户提供两个选择——选用上一个稳定版本或冒险体验实验版。这个策略还没有被Linux黑客普遍采用,也许他们真应该这么做。因为无论选择哪一个都能让彼此更具魅力。【注4】
注释:
1.采用市集模式的开源软件成功先例,在因特网热潮之前就出现了。所以这当然不会源自Unix和因特网传统。比如在1990年到92年初首先出现在DOS机上的info-Zip压缩工具就是一例,另外就是同样始于DOS的RBBS电子公告板系统。从1983年发展起来的强大的RBBS社团,使其至今(1999年中)都充满活力——无论其间网络邮件和文件共享技术发生了多么翻天覆地的变化。如果说info-Zip社团还或多或少的使用了网络邮件的话,那么RBBS开发则纯粹的依托于一个以TCP/IP为基础形成的在线社团。
2.对于扫清操作系统开发的复杂障碍,公开平等的审视是大有助益的,其实,这算不上是个新观点。在1956年考巴托和维萨斯基共同设计了一个名为Multics的早期分时操作系统。[2]他们希望当Multics运行良好并满足下面两个条件的时候能得以发布:首先,它要经受的起来自用户无偿地公开审视和批评。其次,当自身越来越复杂的时候,其有责任对未来的开发者做出贡献,以便令他们可以尽己所能开发出内核明晰的操作系统。换言之,就是有责任公开自己的最基础版本。
3.对于在开源开发中,为何重复劳动算不上个大问题的原因,约翰·哈斯勒(John Hasler)做过一个有趣的解释。他建议我命名为哈斯勒定律:重复劳动开销的增长趋向低于由开发团队扩大带来的指数式成本增长。也就是说,开发团队扩大所带来计划和管理成本增速要远高于重复做功的开销。
这与布鲁克斯定律并不冲突,总体而言,抚平复杂度和纠正错误的成本是与开发团队规模成平方正比增长的,然而重复做功带来的开销则是其中同比增速缓慢的一个独特环节。我们不难为此找到一个看似可信的原因:以一个既定的目标开始工作比让一群自主的开发者达成一致要简单的多,而且可以预防重复做功。但是却不能有效的阻止开发陷入无法预期的恶性循环,最终导致整个系统置身错误之中。
将李纳斯定律和哈斯勒定律结合起来,我们不难找到三种软件工程的对应模式:对于开发者不超过三人的小工程,无需领导和预设管理结构。对于中型工程,采用传统的管理模式成本则相对较低。并且可以有效的防止重复劳动,错误追踪,并且能很快的发现详细资料是否有遗漏,从而确保万无一失。
在此之上,李纳斯定律和哈斯勒定律共同说明了:对于大型工程,传统管理模式带来的问题和成本增幅,远超过预期的重复劳动的开销。而这种调动大家参与所带来的微小开销并不是一个结构上的缺陷,相反(我们看到)这能比传统方法更有力的保证错误和细节无一遗漏。在大型工程中,应用这两则定律可以让那些传统模式下的本息(沉默成本和边际成本——译者按)趋近于零。
4. Linux拆分稳定版和实验版的作法,除了分担风险之外还有一个作用——干掉发布期限。实际上,一旦程让序员同时面对刻版的功能列表和该死发布时间,软件的质量就会大打折扣。这是研发中的一个重要问题。感谢来自哈佛商学院的马可·伊恩斯蒂(Marco Iansiti)和艾伦·麦科马克(Alan MacCormack)让我明白了一个道理——放松二者任意一个,都可以让工作进程更加有效。
一个做法就是制定发布日期,但让功能列表可以变通调整。也就是说,在发布时允许舍弃部分功能。这是稳定版内核开发的基本策略;艾伦·考克斯(Alan Cox,稳定版内核的维护者)定期发布稳定版,但是不承诺何时解决某个问题或者何时添加某个实验版的新功能。
另一个做法则是,锁定开发列表但不制定发布时间。这是实验版内核开发的基本策略。我们称之为:“做完再叫醒我(wake me up when it's done)策略”。达·马可(De Marco)和利斯特(Lister)的研究表明这不仅可以提高软件质量,而且平均而言,它比任何“激进”或“保守”的策略都节省研发时间。
2000年初,我开始怀疑自己在前作(指本书的前期版本——译者按)中严重低估了这种反发布时间(做完再叫醒我)策略对于开源社区的生产力以及质量的重要性。1999年GNOME仓促1.0版的教训表明:即使是开源项目,为了赶进度而草率发布,也会严重影响软件质量。
有充分的理由可以表明:开发过程的透明化、“做完在叫醒我”的策略以及开发者自主选择研发对象的方法。是影响开源项目质量的三个同等重要的作用力。
译者按:
1.德尔菲效应, Delphi effect。德尔菲(Delphi)是希腊古都,宏伟的阿波罗(Apollo,太阳神)神殿便座落于此。相传阿波罗经常在此宣布神谕,而在决断之前会广泛争取意见。故而这里成为古希腊先哲聚集论道的场所。20世纪中期,美国军方和兰德(RAND)公司合作开展国防项目——“德尔菲项目”。顾名思义,其着重采用广泛收集观点意见的方法,从而产生了“德尔非法”(Delphi method)。日后“德尔菲法”被广泛应用于工程和管理领域,形成了“立论-驳论-综述”的三段式方法。
本书中的“德尔菲效应”则是作者的创造。德尔菲法强调广泛征集专家的建议。而作者则并不认为必须专家参与,而且参与者的广泛度和涵盖面都远超过德尔菲法。德尔菲法是一种方法,众多专家参与,是其前提条件。而德尔菲效应则是强调一种广泛平等参与所带来的结果。
简而言之,我认为这就是我们中国人说的“兼听则明,偏信则暗”。
2.考巴托:费尔南多·考巴托(Fernando J. Corbató)杰出的计算机学家,1990年图灵奖的得主。
维萨斯基:维克托·A·维萨斯基(Victor A. Vyssotsky)著名数学家、计算机学家。
二人曾共同设计了Multics的内核,在该计划停止之后,由贝尔实验室的工程师以C语言为基础借此开发而成了Unix。