大教堂与集市-part1

《The Cathedral & the Bazaar》 By:Eric Steven Raymond, 1997 基础版本:https://github.com/crazyangelo/Cathedral-and-Bazaar 基础版译注:原始版本為 1999 年 5 月 5 日,由謝志昌所翻譯;英文最新版為 2002 年 8 月 2 日的 3.0 版,由於內容更動處不少,因此逐一更新;翻譯以語句通順達意為主要考量,難免與英文版的字詞有所不同,為求盡善盡美,以 CC 授權釋出,希望各方同好自由修改散佈。 本版译注:将繁体字改成简体,并修正了一些词汇表达 第一章 教堂与市集 Linux 打破了许多软件发展的传统,这个世界级的操作系统在五年前(1991 年)仅仅靠着如丝般的网际网路,神奇地联合了散布在全世界数以千计兼职的玩家们来发展它,谁曾料到会发生这样的事情呢? 我当然也没料到,Linux 出现在我电脑萤幕是在 1993 年初,当时我埋首于 UNIX 及开放性原始码的软件发展已有十年,1980 年代中期,我是 GNU 专案首批的贡献者之一,我写过许多开放性原始码的软件放到网路上供人使用,也曾独立或协同发展好几个程序(nethack,Emacs 的 VC 和 GUD 功能,xlife,…等等),这些程序到今天仍广泛地为人所用,我想我知道这是怎么办到的。 GNU 是自由软件基金会(Free Software Fundation)的一个专案,目标是发展出 UNIX 上所有程序的自由版本,Emacs 是自由软件基会发展出来的一支程序,可做文字编辑器,提供写程序的整合发展环境,用来读电子邮件,新闻群组,甚至浏览网页。更详细的资讯请参考 http://www.gnu.org。 ―― 译注。 Linux 扭转了许多我认为我已知道的观念。多年来我一直宣扬使用小工具集、快速原型发展及程序进化的 UNIX 福音。但我也相信对于有一定复杂度的程序必需使用集中和有经验的方法来开发,我相信最重要的软件(操作系统以及庞大的工具程序如 Emacs)必须如建造一座教堂般,由个别的高手或一小群专家在光辉的孤立中小心翼翼地精雕细琢,时机未到之前,不会释出测试版。 Linus Torvald[^2] 的软件发展风格(尽早并经常发表新版本,授权每一件作者可以委托的事,不拒绝几乎到混乱程度的程序)的出现如同一个惊奇,没有令人肃然起敬的教堂,甚至 Linux 的同好们似乎组成了一个有不同流程和不同方式的大市集(Linux 的档案服务站台就是它适切的象征,每个人都服从着自由的规则),以这个风格发展出来的 Linux 既一致又稳定,表面上看来真是一连串的奇迹。...

December 9, 2022 · 3 min · Yuanhao

大教堂与集市-part2

第五章 有多少眼球驯服了复杂度 可以很明显地观察到市集模式极大地加速了除错与程序演化。另一件可以清楚明白的是,在微观上,开发者与测试者的每天活动中,市集模式如何与为何可以达到这样的成果。在本章(初版完成三年后,依据开发者多次亲身体验过的洞察力),我们将仔细的检查它的实际机制。非技术性倾向的读者可以略过这一章,直接跳到下一章去。 一个关键点是,为何没有源代码意识的使用者所报告的错不会太有用。没有源代码意识的使用者倾向报告表面上的问题,他们把自己的使用环境视为理所当然,所以他们会忽视重要的背景资料,报告错误时很少会包括可信赖的过程。 这里的问题是测试者与开发者对问题的视角不同,测试者由外向内看,开发者由内向外看。在封闭源代码的体系中,两者只会固守自己的角度谈论事情,因而对另一方深深的失望。 开源的体系则打破这条界线,使测试者与开发者可以站在同样的角度来讨论事情,这有高效多了。实践中,这将有巨大的差异,一者是只报告表象的症状,一者是以开发者那种以源代码为基础的角度来看问题。 大部分的时候,大多数的bug是可以由描述开发层级的特征来除错的,即使是不完整的描述。当一个 beta 测试者告诉你在那一行代码有边界的问题时,或告诉你在 X、Y 跟 Z 的情形下,有个变量有问题,指出有问题的代码通常就足够找出问题并修正它。 因此,对于 beta 测试者与核心开发者来说,有源代码意识的人对于双方都可以强化沟通与合作。换句话说,核心开发者的时间被节省了,即使是在有很多共同开发者的情形下。 另一个开源方式的特征是节省开发者的时间,而这是典型开源项目的沟通结构。上面我使用了「核心开发者」(core developer)这个字来区别项目核心(project core,通常很小;一个开发者是常见的,一到三个开发者则是很典型的)与项目圈(project halo)的 beta 测试者跟贡献者(通常有数百个)。 传统软件开发组织的根本问题是「Brooks法则」︰在落后的项目,增加越多程序员会使得项目更落后。一般的状况下,「Brooks法则」的预测是,随着开发者的人数增加,复杂度与沟通成本随着人数的平方上升,而完成的工作却只成线性上升。 「Brooks法则」依据的经验是,bug会在由不同的人编写的代码的接口上大量出现,而沟通损耗会随着项目参与人数的升高而升高。因此,问题的规模会随着开发者间的沟通路径而呈现平方上升。(精确的说,是 N x (N-1)/2,N 是开发者的数目。) 「Brooks法则」的分析建立在一个隐藏的假设基础上︰项目的沟通结构必须是完全图(complete graph),每个人都可以跟每个人沟通。但是在开源的项目中,开发者在有效平行分割的子项目中彼此很少互动;程序更改与bug报告是透过核心团体来处理的,只有在这样的小团体中,「Brooks法则」的分析才成立1。 还有其它原因让源代码层级的bug报告变得有效率。事实是一个错误常常会有许多可能的症状,取决于使用的的使用状况与使用环境。这些错误是一些复杂与微妙的bug(像是内存管理错误或视窗的随意中断),也是最难被发现或靠静态分析来捕捉的,这在长期的开发中造成最多的问题。 当一个测试者发出一个尝试性的源代码层级的多症状bug报告(例如,我看来在第 1250 行代码有个窗口在做讯号处理,或你在哪里把那个缓存清空),可能会给开发者一个关键的线索来发现半打的症状,这些开发者通常因为太靠近底层代码而无法发现这样的问题。在这种案例中,很难找出可从外部看见的不正确动作是从哪个bug引起的,甚至是不可能的 ―― 但是透过经常发布,就不需要知道了。其他的合作者会迅速找出bug是否已被修正。在很多案例中,导致不正常动作的源代码层级bug将被移除,甚至在还没有被报告之前就被移除。 复杂的多症状错误,通常有很多从表面症状来的方式可以找出真正的bug。这种能让测试者与开发者找出问题的方式,可能与开发环境有关,也可能会随着时间而有无法预期的变化。实际上,当测试者或开发者追踪一个症状时,都是在程序空间的一个集合中「半随机」(semi-random)取样。bug越微妙复杂,越难找出相关的样本。 对于简单与容易复现的bug,重点在于「半」(semi)而非在「随机」(random);debug技巧、对程序与架构的熟练都是关键。但对于复杂的bug来说,重点就是「随机」(random),这时人多比人少好 ―― 即使这些少数人是平均技巧较高的。 如果从表面的症状找出bug的难度大,像是一些无法从表面症状预测的,上述的结果会进一步增强。单一的开发者可能会以一个困难的方式来做第一次尝试,但其实也可以从简单的方式达到同样的结果。另一方面,假如很多人随着频繁的版本一起测试,可能就会有一个人可以用最简单的方式找到bug,节省了大量的时间。项目管理者将会发现,随着新版本发布,许多人一起用各种复杂方法追踪同一个bug的时代将会过去,尤其是在众人浪费太多时间之前2。 第六章 今花非昨花? 由 Linus 行为的研究中,我们得到了一个能解释他为什么成功的理论,所以我想要在我的新项目(当然不如 Linux 内核程序复杂和雄心勃勃)中来测试这个理论。 但我做的第一件事情是大力重组和简化 popclient 的程序,Carl Harris 的实现非常扎实,可是却像许多的 C 程序员一样,含括了一种不必要的复杂,他以代码为主,数据结构为辅,因此代码看起来漂亮,但数据结构却很特殊,甚至可以说是丑陋的(至少以这位老资格 Lisp 高手的高标准而言)。 然而,我重写程序除了改良原来代码和数据结构的设计外,还有其他目的,就是把它发展到我可以完全了解,否则负责修补你不懂的程序是一件很无趣的事。 项目进行的第一个月,我简单地依循着 Carl 原来基本设计的用意,第一个重大的改变是我加入 IMAP 协议的支持,我重构原来处理协议的程序,改成一个较为通用的驱动程序再加上三个驱动它的方法表(即 POP2,POP3 和 IMAP)。这个改变阐释了一个广义的原则,特别在像 C 这种先天上未提供动态类型的程序语言,程序员们最好谨记在心︰ 格言9︰聪明的数据结构配上笨拙的代码要比相反的组合好。3 Brooks 在《人月神话》的第九章中也说︰「光给我看你的代码,而不给我看它用的数据结构,我会一头雾水。给我看你程序的数据结构,我通常不需要再看你的代码,因为已经够明白了4。」...

December 9, 2022 · 2 min · Yuanhao

大教堂与集市-part3

第九章 由 Fetchmail 学到的一些经验 在我们回头讨论一般软件工程的议题前,由 fetchmail 得来的一些特殊教训值得深思。 Fetchmail 配置文件(rc file)的语法包括可有可无的关键字,这些如「噪音」般的字眼会被语法分析程序忽略,这些字的加入,使得配置文件的语法和英文很接近,和传统中简洁的「关键字 ―― 设定值」配对表示法(把噪音字去掉就可以得到)比较起来,要来得容易阅读。 这个教训开始于某一个夜晚的实验,我注意到配置文件中的宣告语法可以组成一个迷你的祈使语言。(这也是为什么我把原来 popclient 中的关键字 server 改成 poll)。 对我而言,如果把这个祈使语言弄得更像英文,那会让 fetchmail 更易于使用,虽然我现在信服如 Emacs、HTML 及许多数据库引擎制定出来的模范语言,在正常情况下我也不那么迷英文的语法。 传统的程序员喜欢非常精确而简洁的配置语法,不希望有任何冗余在其中,这是因为早期的电脑计算资源昂贵而遗留下来的观念,他们认为语法分析的过程要节约计算资源,并要尽可能的简单。英文的语句大约有百分之五十的冗余,所以不利于做为配置语法。 但这并非我在正常的情况下不用英文语法的原因,我在此提及是为了推翻像英文的语法不适合作配置语法的论点,当中央处理器和内存都变得便宜时,配置语法的简洁已不再是我们的目标,现在的情况是︰一个电脑语言中符合人性易于使用的重要性已超过节约电脑的计算资源。 然而还是有好几个地方要小心,其中之一是语法分析过程变得比较复杂的代价 ―― 你不会想把这个特点(使用像英文的配置语法)变成程序错误的来源及使用者的疑惑处。另一个是当我们要订出一个像英文的语言时,通常需要做些修改,表面上看起来修改过后的语法可重组出自然语言,但可能也会因修改过以致于和传统的配置语法一样,令人感到疑惑。(我们可以在许多所谓的第四代程序语言和商业用的数据库查询语言看到这个现象) Fetchmail 的控制语法看起来免除了这个问题,因为我严格地限制控制语法的范围,它不是一个以通用为目的的语言,它简单并不很复杂,所以在极小的英文子集和真正的控制语言之间的相混处很少,我认为这里还有一个更广义的教训︰ 格言16︰当你设计的语言没有一处是 Turing-complete,你可以采用比较平易的语法。 另有一个教训是关于含糊的保密性,有一些 fetchmail 的使用者要我修改程序,以把经保密处理的凭证储存于配置文件内,这样一来,偷窥者就没办法看到真正的密码了。 我并没有这么做,因为这个做法并不能达到真正的安全,能拿到读取你配置文件权限的人,也能以你的身份执行 fetchmail ―― 如果你的密码经保密处理存在配置文件中,他们可以由 fetchmail 中取得解码程序来得到你真正的密码。 如果我把程序改成可以在 fetchmail 的配置文件中储存保密的密码,那会给认为这并不难的人们对保密性的错误观念。一般的守则应该是: 格言17︰一个保密系统是否安全依存于它隐藏的秘密,注意不要有「虚拟秘密」。1 第十章 市集模式必要的条件 早先看过这篇文章的书评家和试读者都提出同样的问题,那就是以市集模式发展软件,获得成功的先决条件为何?包括项目领导人的资格,代码到什么样的程度,才对社群发布并开始成立协同发展团队。 相当明显的,任何人无法以市集模式建立软件基础2,但是可以用市集模式来测试,debug,改进软件,在一个项目的起始点很难运用市集模式,Linus 没试过,我也没有。项目初始的协同发展团队需要有一些东西可以测试,可以执行。 当你开始召募项目团队时,你必须能提出大致合理的保证,你的程序不需要运作得很好,它可以暴力,有错,不完整,及注释贫乏,只要它可以使潜在的协同开发者相信,这个程序在可预见的未来大有可为。 Linux 和 fetchmail 公开发布时都具有强健及吸引人的设计,许多人认为这和我所报告的市集模式有所不同,并以为这样的设计很重要,甚至进一步做出一个他们的结论 ―― 高度的设计直觉和聪明是一个项目领导人不可或缺的特质。 但是 Linus 的设计由 UNIX 而来,我的设计由原先的 popclient 而来(虽然它后来改变甚大,比例上说来还超过 Linux),所以市集模式项目的领导人或协调者真的需要格外的设计技巧?或者能提升别人的设计技巧呢? 我想对于项目协调者是否能做出耀眼的设计并不重要,最重要的是协调者是否能认知别人在设计上的好点子。 Linux 和 fetchmail 都证明了这件事,Linus 这位仁兄如同之前所讨论的,他并不是伟大的创新设计师,但他展现了另一种卓越的技巧,即认同别人好的设计点子,且将这些好的设计整合到 Linux 的核心中。而我之前描述过 fetchmail 最有力的设计(藉 SMTP 转发邮件)也来自他人。...

December 9, 2022 · 3 min · Yuanhao