📄 00000006.htm
字号:
发布/测试/改进的过程。 <BR> <BR> (FSF的试图把代码放入GPL之下的策略有一个未曾预料到的副作用,它让FSF <BR>难以采取市集模式,因为他们认为每个想贡献二十行以上代码的人都必须得到一 <BR>个授权,以使受到GPL的代码免受版权法的侵扰,具有BSD和MITX协会的授权的用 <BR>户不会有这个问题,因为他们并不试图保留那些会使人可能受到质询的权力)。 <BR> <BR> 四. 早发布、常发布 <BR> <BR> 尽量早尽量频繁的发布是Linux开发模式的一个重要部分,多数开发人员(包 <BR>括我)过去都相信这对大型工程来说是个不好的策略,因为早期版本都是些充满错 <BR>误的版本,而你不想耗光用户的耐心。 <BR> 这种信仰强化了建造大教堂开发方式的必要性,如果目标是让用户尽可能少 <BR>的见到错误,那你怎能不会仅仅每六个月发布一次(或更不经常),而且在发布之 <BR>间象一只狗一样辛勤“捉虫”呢? Emacs C内核就是以这种方式开发的,Lisp库, <BR>实际上却相反,因为有一些有FSF控制之外的Lisp库,在那里你可以独立于Emacs <BR>发布周期地找寻新的和开发代码版本。 <BR> <BR> 这其中最重要的是Ohio州的elisp库,预示了今天的巨大的Linux库的许多特 <BR>征的精神,但是我们很少真正仔细考虑我们在做什么,或者这个库的存在指出了 <BR>FSF建造教堂式开发模式的什么问题,1992年我曾经做了一次严肃的尝试,想把 <BR>Ohio的大量代码正式合并到Emacs的官方Lisp库中,结果我陷入了政治斗争中,彻 <BR>底失败了。 <BR> <BR> 但是一年之后,在Linux广泛应用之后,很清楚,一些不同的更加健康的东西 <BR>诞生了,Linus的开发模式正好与建造教堂方式相反,Sunsite和tsx-11的库开始 <BR>成长,推动了许多发布。所有这些都是闻所未闻的频繁的内核系统的发布所推动 <BR>的。 <BR> <BR> Linus以所有实际可能的方式把它的用户作为协作开发人员。 <BR> <BR> 7. 早发布、常发布、听取客户的建议 <BR> Linus的创新并不是这个(这在Unix世界中是一个长期传统),而是把它扩展到 <BR>和他所开发的东西的复杂程度相匹配的地步,在早期一天一次发布对他来说都不 <BR>是罕见的!而且因为他培育了他的协作开发者基础,比其他任何人更努力地充分利 <BR>用了Internet进行合作,所以这确实能行。 <BR> <BR> 但是它是怎样进行的呢?它是我能模仿的吗?还是这依赖于Linus的独特天才? <BR> <BR> 我不这样想,我承认Linus是一个极好的黑客(我们有多少人能够做出一个完 <BR>整的高质量的操作系统内核?),但是Linux并不是一个令人敬畏的概念上的飞跃, <BR>Linus不是(至少还不曾是)象Richard stallman或James Gosling一样的创新天 <BR>才,在我看来,Linus更象一个工程天才,具有避免错误和开发失败的第六感觉, <BR>掌握了发现从A点到B点代价最小的路径的决窍,确实,Linux的整个设计受益于这 <BR>个特质,并反映出Linus的本质上保守和简化设计的方法。 <BR> <BR> 如果快速的发布和充分利用Internet不是偶然而是Linus的对代价最小的路径 <BR>的洞察力的工程天才的内在部分,那么他极大增强了什么?他创建了什么样的方法? <BR> <BR> 问题回答了它自己,Linus保持他的黑客用户经常受到激励和奖赏:被行动的 <BR>自我满足的希望所激励,而奖赏则是经常(甚至每天)都看到工作在进步。 <BR> <BR> Linus直接瞄准了争取最多的投入调试和开发的人时,甚至冒代码不稳定和一 <BR>旦有非常棘手的错误而失去用户基础的险,Linus似乎相信下面这个: <BR> 8. 如果有一个足够大的beta测试人员和协作开发人员的基础,几乎所有的问题 <BR>都可以被快速的找出并被一些人纠正。 <BR> <BR> 或者更不正式的讲:“如果有足够多的眼睛,所有的错误都是浅显的”(群众 <BR>的眼睛是雪亮的),我把这称为“Linus定律”。 <BR> <BR> 我最初的表述是每个问题“对某些人是透明的”,Linus反对说,理解和修订 <BR>问题的那个人不一定非是甚至往往不是首先发现它的人,“某个人发现了问题”, <BR>他说,“另一个理解它,我认为发现它是个更大的挑战”,但是要点是所有事都趋 <BR>向于迅速发生。 <BR> <BR> 我认为这是建造教堂和集市模式的核心区别,在建造教堂模式的编程模式看 <BR>来,错误和编程问题是狡猾的、阴险的、隐藏很深的现象,花费几个月的仔细检 <BR>查,也不能给你多大确保把它们都挑出来的信心,因此很长的发布周期,和在长 <BR>期等待之后并没有得到完美的版本发布所引起的失望都是不可避免的。 <BR> <BR> 以市集模式观点来看,在另一方面,我们认为错误是浅显的现象,或者至少 <BR>当暴露给上千个热切的协作开发人员,让他们来对每个新发布进行测试的时候, <BR>它们很快变得浅显了,所以我们经常发布来获得更多的更正,作为一个有益的副 <BR>作用,如果你偶尔做了一个笨拙的修改,也不会损失太多。也许我们本不应该这 <BR>样的惊奇,社会学家在几年前已经发现一群相同专业的(或相同无知的)观察者的 <BR>平均观点比在其中随机挑选一个来得更加可靠,他们称此为“Delhpi效应”, <BR>Linus所显示的证明在调试一个操作系统时它也适用——Delphi效应甚至可以战胜 <BR>操作系统内核一级的复杂度。 <BR> <BR> 我受Jeff Dutky (dutky @ wam.umd.edu)的启发指出Linus定律可以重新表述 <BR>为“调试可以并行”,Jeff观察到虽然调试工作需要调试人员和对应的开发人员 <BR>相交流,但它不需要在调试人员之间进行大量的协调,于是它就没有陷入开发时 <BR>遇到的平方复杂度和管理开销。 <BR> 在实际中,由于重复劳动而导致的理论上的丧失效率的现象在Linux世界中并 <BR>不是一个大问题,“早发布、常发布策略”的一个效果就是利用快速的传播反馈 <BR>修订来使重复劳动达到最小。 <BR> <BR> Brooks甚至做了一个与Jeff相关的更精确的观察:“维护一个广泛使用的程 <BR>序的成本一般是其开发成本的40%,奇怪的是这个成本受到用户个数的强烈影响, <BR>更多的用户发现更多的错误”(我的强调)。 <BR> 更多的用户发现更多的错误是因为更多的用户提供了更多测试程序的方法, <BR>当用户是协作开发人员时这个效果被放大了,每个找寻错误的人都有自己稍微不 <BR>同的感觉和分析工具,从不同角度来看待问题。“Delphi效应”似乎因为这个变 <BR>体工作变得更加精确,在调试的情况下,这个变体同时减小了重复劳动。 <BR> <BR> 所以加入更多的beta测试人员虽不能从开发人员的P.O.V中减小“最深”的错 <BR>误的复杂度,但是它增加了这样一种可能性,即某个人的工具和问题正好匹配, <BR>而这个错误对这个人来说是浅显的。 <BR> <BR> Linus也做了一些改进,如果有一些严重的错误,Linux内核的版本在编号上 <BR>做了些处理,让用户可以自己选择是运行上一个“稳定”的版本,还是冒遇到错 <BR>误的险而得到新特征,这个战略还没被大多数Linux黑客所仿效,但它应该被仿 <BR>效,存在两个选择的事实让二者都很吸引 人。 <BR> <BR>五. 什么时候玫瑰不是玫瑰? <BR> <BR> 在研究了Linus的行为和形成了为什么它成功的理论之后,我决定在我的工程 <BR>(显然没有那么复杂和雄心勃勃)里有意识的测试这个理论。 <BR> 但我首先做的事是熟悉和简化Popclient。 Carl Harris的实现非常好,但是 <BR>有一种对许多C程序来说没有必要的复杂性。他把代码当作核心而把数据结构当作 <BR>对代码的支持,结果是代码非常漂亮但是数据结构设计得很特别,相当丑陋(至少 <BR>对以这个老LISP黑客的标准来看),然而除了提高代码和数据结构设计之外,重写 <BR>它还有一个目的,就是要把它演化为我彻底理解的东西,对修改你不理解的程序 <BR>中的错误负责可不是一件有趣的事。 <BR> <BR> 第一个月我只是在领会Carl's的基本设计的含义,我所做的第一个重大修改 <BR>是加入了IMAP支持,我把协议机重新组织为一个通用驱动程序和三个方法表(对应 <BR>POP2、POP3和IMAP),这个前面的修改指出一个需要程序员(特别是象C这种没有自 <BR>然的动态类型支持的语言)记在脑中的一般原理: <BR> <BR> 9. 聪明的数据结构和笨拙的代码要比相反的搭配工作的更好 <BR> <BR> Fred Brooks也在他第11章中讲道:“让我看你的[代码],把你的[数据结 <BR>构]隐藏起来,我还是会迷惑;让我看看你的[数据结构],那我就不需要你的[代 <BR>码]了,它是显而易见的”。 <BR> <BR> 实际上,他说的是“流程图”和“表”,但是在三十年的术语/文化演进之 <BR>后,事情还是一样的。 <BR> <BR> 此时(1996年9月初,在从零开始六个月后),我开始想接下来修改名字——毕 <BR>竟,它已不仅仅是一个POP客户,但我犹豫了,因为还没有什么新的漂亮设计呢, <BR>我的popclient版本需要有自己的特色。 <BR> <BR> 当fetehmail学会怎样把取到的邮件转送到SMTP端口时,事情就完全改变了, <BR>但是首先:上面我说过我决定使用这个工程来测试我关于Linus Torualds所做的 <BR>行为的理论,(你可能会问)我怎样做到这点呢? 以下面的方式: <BR> <BR> 1. 我尽早尽量频繁的发布(几乎从未少于每十天发布一次;在密集开发的时候 <BR>是每天一次)。 <BR> <BR> 2. 我把每一个和我讨论fetchmail的人加入一个beta表中。 <BR> <BR> 3. 每当我发布我都向beta表中的人发出通告,鼓励人们参与。 <BR> <BR> 4. 我听取beta测试员的意见,向他们询问设计决策,对他们寄来的补丁和反馈 <BR>表示感谢。 <BR> <BR> 这些简单的手段立即收到的回报,在工程的开始,我收到了一些错误报告, <BR>其质量足以使开发者因此被杀掉,而且经常还附有补丁、我得到了理智的批评, <BR>有趣的邮件,和聪明的特征建议,这导致了: <BR> <BR> 10. 如果你象对待最宝贵的资源一样对待你的beta测试员,他们就会成为你最 <BR>宝贵的资源。 <BR> <BR>六. popclient变成了Fetchmail <BR> <BR> 这个工程的真正转折点是Harry Hochleiser寄给我他写的代码草稿,他把邮 <BR>件转发到客户端机器的SMTP端口,我立即意识到这个特征的可靠实现将淘汰所有 <BR>其他的递送模式。 <BR> <BR> 几个星期以来我一直在修改而不是改进fetchmail,因为我觉得界面设计虽然 <BR>有用但是太笨拙琐碎了,到处充满了太多的粗陋的细小选项。 <BR> <BR> 当我思考SMTP转发时我发现popclient试图做的事太多了,它被设计成既是一 <BR>个邮件传输代理(MTA)也是一个本地递送代理(MDA)。使用SMTP转发,它就可以从 <BR>MDA的事务中解脱出来而成为一个纯MTA,而象sendmail一样把邮件交给本地递送 <BR>程序来处理。 <BR> <BR> 既然端口25在所有支撑TCP/IP的平台上早已被预留,为什么还要为一个邮件 <BR>传输代理的配置或为一个邮箱设置加锁的附加功能而操心呢?尤其是当这意味着抽 <BR>取的邮件就象一个正常的发送者发出的SMTP邮件一样,而这就是我们需要的。 <BR> <BR> 这里有几个教益:第一,SMTP转发的想法是我有意识地模拟Linus的方法以来 <BR>的最大的单个回报,一个用户告诉我这个非同寻常的想法——我所需做的只是理 <BR>解它的含义。 <BR> <BR> 11. 想出好主意是好事,从你的用户那里发现好主意也是好事,有时候后者更 <BR>好。 <BR> <BR> 很有趣的是,你很快将发现,如果你完全承认你从其他人那里得到多少教益 <BR>的话,整个世界将会认为所有的发明都是你做出的,而你会对你的天才变得谦 <BR>虚。我们可以看到这在Linus身上体现得多明显!(当我在1997年8月的Perl会议上 <BR>发表这个论文时,Larry Wall坐在前排,当我讲到上面的观点时,他激动的叫了 <BR>出来:“对了!说对了!哥们!”所有的听众都哄堂大笑起来,因为他们知道同样的 <BR>事情也发生在Perl的发明者身上)。 <BR> <BR> 于是在同样精神指导下工程进行了几个星期,我开始不光从我的用户那儿也 <BR>从听说我的系统的人那儿得到类似的赞扬,我把一些这种邮件收藏起来,我将在 <BR>我开始怀疑自己的生命是否有价值时重新读读这些信。:) <BR> <BR> 但是有两个更基本的,非政治性的对所有设计都有普遍意义的教益。 <BR> <BR> 12. 最重要和最有创新的解决方案常常来自于你认识到你对问题的概念是错误 <BR>的。 <BR> <BR> 一个衡量fetchmail成功的有趣方式是工程的beta测试人员表(fegtchmail的 <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -