集市中迷失的一代:FreeBSD核心开发者反思开源软件质量

摘要:本文作者Poul-Henning Kamp (phk@FreeBSD.org) ,26年的计算机程序员,他编写的软件以底层构建块的形式广泛被开源和商业产品采用。讲述作者在看完《设计原本》这本书后所引发的共鸣!

13年前,新兴的草根开源软件运动如火如荼,而Eric Raymond的《大教堂与集市》(O'Reilly Media, 2001)一书则重新定义了我们的词汇表,几乎预言了瀑布模型和大型软件公司的终结。这本书有煽动性,但却没有说服我。与此同时,由于我正全身心投入开源运动,也就情不自禁地宁愿相信他是对的。

而今年夏天我带到海滨别墅来的这本书,同样有煽动性,比Raymond那本更甚(但这本书在提到《大教堂与集市》时是相当正面的),那就是 Frederick P. Brooks的《设计原本》(Addison-Wesley Professional, 2010)。Brooks这本书不断引发我的共鸣,我也越来越佩服他的语言表达能力和他提出的观点,然而越是有共鸣,就越感到难过和失望。

enter image description here

13年前,正值.COM热潮涌动,年轻的Web程序员比比皆是,辍学创业的大学生也屡见不鲜。在向其中一些人传授过去那些编程技巧的同时,我也获得了很多乐趣。像什么测试恢复备份、写脚本安装操作系统、版本控制等等。当然,现在再看,也就那么回事(有些事并不像你印象中那么激动人心,对吧)。而且,我们已经无路可逃,整个.COM时代总体上对IT/CS而言就是一场灾难,尤其对软件质量和Unix来说,更是如此。

好像从来没有人分析过.COM泛滥那些年,IT行业增长了多少。以我个人的经验,我估计整个行业(包括IT行业由此新增的就业机会)大概增长了两个数量级,或者更确切地说,达到了原来的百分之一万(100倍)。

学会计算机编程很容易,就像学会用钉子把两块木板钉到一起一样简单。但问题是——打个不恰当的比方,市场对“钉在一起的两块木板”的需求,除了“自豪的爷爷”的那点天伦之乐以外,真的是太小了。而且,由此再进一步学习钉椅子或做碗橱,都需要天分、实践和训练。我们增长的这99倍恰恰都来自那些既没有实践经验,又没有受过良好训练的人。等这些人有时间学习和接受训练了,聚会已然结束,大多数人失去了工作。可以乐观地假定那些坚持下来的人最有天分,而且经验也最多,即便如此我们还是无路可逃,因为作为IT专业人士,由于缺乏基本功,他们大多数都很滥!

不幸的是,Raymond鼓吹的——与.COM泡沫之前精心建造大教堂的理念恰恰相反的集市模因(meme)1——“对付过去就行”,并没有随.COM泡沫破裂死去。今天,Unix这艘大船正因为难堪重负而迅速沉没。

模因论是基于达尔文进化论的观点解释文化进化规律的新理论。参见这里。——译者注

我刚升级了自己的笔记本电脑。到现在,我运行FreeBSD开发版已经足足有18个年头了,但从源代码编译我的Spartan工作环境仍然要花一整天时间,因为它必须理清头绪,在Raymond那乱糟糟的软件集市中建起一座大教堂来。

宏观上讲,FreeBSD的Ports Collection会尽力为这个集市画一幅地图,以便FreeBSD用户轻易找到自己的应用。目前来看,这幅地图由22198个文件构成,而这些文件就是集市中每个摊位的简要说明:用寥寥数语告诉你某个摊位卖什么,要了解详细信息再去哪里找。此外,还有23214个Makefile,告诉你可以对每个摊位上的软件做什么。这些Makefile还想让你知道自己都有哪些选择,要选择什么,以及不作选择时用什么默认值比较明智。为方便起见,这幅地图还提供24400个补丁文件,以便弥补这些玩艺儿在制作工艺上的瑕疵,但一般来说,还是因为它们携带(portability)不便,所以才催生了这些补丁。

最后,地图提供一些建设性意见,比如要是你想要www/firefox,那得先得到devel/nspr、security/nss、databases/sqlite3,等等。在你手拿地图,查到这些依赖,以及这些依赖的依赖之后,你会发现自己的购物清单上已经记满了122个包,你必须在能买www/firefox之前买全它们。

当然啦,模块化和代码重用都是好主意。可是,就算在最简单的情况下,CS/IT的代码重用信条在集市里也没有用武之地:FreeBSD Ports Collection中的软件最少都包含1342个复制粘贴加密算法。

如果有人奋不顾身或者偏听偏信,非要代码重用,结果真制造出了自身完备且无依赖的软件包,那要换得这个容易管理的包,享受代码重用的成果,就算多花点银子也值啊!但这样的事并没有发生过:各种包把Web搞得一团糟, 随便依赖,互相纠缠,代码越重用,浪费越严重。

举个浪费的例子吧。Sam Leffler的graphics/libtiff是前面提到在安装www/firefox之前必须安装的122个包中的一个,但安装后的Firefox浏览器却无法渲染TIFF图片。问题出在哪里我还没来得及查清楚,但这122个包中的10个需要Perl,7个需要Python;这其中又有一个devel/glib20,同时有赖于Perl和Python,至于为什么,我到现在都没想通。

继续往下看你的购物清单,你会不断会发现满足彼得定律的应用。所谓彼得定律,就是说在一个根据人的业绩、成就和价值来提拔人的组织中,最终会把一些人提拔到他们并不胜任的位置上。这个定律经常被通俗地说成“把员工提拔到他们不胜任的职位上”。软件行业也一样,你会发现自己需要三个不同版本的make程序、一个宏处理器、一个汇编器和其他一些必要的包。而在这个“食物链”的末端,则是libtool,它试图掩盖一个事实,即在Unix中没有构建共享库的标准方式。的确没有适用于所有Unix变体的标准方式——比如给ld(1)命令加个标签之类的;而此时彼得定律就适用了:这个工作被交给了libtool。此时此刻,彼得定律确实牛,devel/libtool的源代码达到了414 740行,而其中有一半是测试用例。原则上讲,这倒是值得称赞的,但实际上这却是彼得定律的结果:这些测试煞费苦心地在那里验证一个本来就不该存在的问题的复杂方案是否功能齐备!更让抓狂的是,其中31 085行代码都保存一个叫configure的shell脚本里,代码格式之乱,任谁也难看明白。这样做是想让configure脚本执行大约200个自动测试,从而免除用户手工配置libtool之苦。这个想法很滥,早在1980年代刚刚出现时,就招来很多非议。因为源代码是靠configure脚本的伪装才让人感觉它可移植的,而实际上并非真正可移植。可以说它是配置思想的余孽。

1980年代出现过很多不同的Unix实现:Cray-1s及其24位指针、Amdahl UTS主机Unix、来自微机制造商的大量的SysV+BSD混搭、Data General等公司开发的准Unix“垫片”,甚至连油漆厂Mark Williams都有纯粹的Unix克隆Coherent。

当时的configure脚本是用手写的,用于检测当前系统是BSD还是SysV风格的Unix,然后根据检测结果把一个或另一个Makefile(有时候还带一个.h文件)复制到指定位置。后来,这个configure脚本的神通越来越大,而且不折不扣地印证了彼得定律。我们没有看到Unix采用标准做法来消除对该脚本的依赖,反倒是有人写了一个叫autoconf的程序,用来自动生成configure脚本。

今天,Unix/Posix一脉的操作系统,就连IBM的z/OS主机版,都跟1980年代那些完全一样;libtool这个configure脚本中的31 085行代码仍然还要检测<sys/stat.h><stdlib.h>是否存在,即便是没有这两个文件的Unix变体,在既没有足够内存执行libtool,也没有足够硬盘保存其16MB源代码的情况下。

为什么会这样呢?

由于尚不知晓的原因,autoconf是用晦涩的M4宏语言写的,因而实际的测试代码如下:

 
 
  1. ## Whether `make' supports order-only prerequisites.  
  2. AC_CACHE_CHECK([whether ${MAKE-make} supports order-only prerequisites],  
  3.   [lt_cv_make_order_only],  
  4.   [mkdir conftest.dir  
  5.    cd conftest.dir  
  6.    touch b  
  7.    touch a  
  8. cat >confmk << 'END'  
  9. a: b | c  
  10. a b c:  
  11.        touch $[]@  
  12. END  
  13.   touch c  
  14.   if ${MAKE-make} -s -q -f confmk >/dev/null 2>&1; then  
  15.     lt_cv_make_order_only=yes 
  16.   else  
  17.     lt_cv_make_order_only=no 
  18.   fi  
  19.   cd ..  
  20.   rm -rf conftest.dir  
  21. ])  
  22. if test $lt_cv_make_order_only = yes; then  
  23.   ORDER='|' 
  24. else  
  25.   ORDER='' 
  26. fi  
  27. AC_SUBST([ORDER])  

毋庸讳言,这超出了大多数程序员的承受能力。即便有人有这个能力,但给autoconf指定输入文件都是用复制粘贴的,所以就让人不容易发现日益膨胀的那些涵盖诸如前述“标准测试”的标准宏,这些宏都是为了处理20年前并不存在的兼容性问题。

可能这就是为什么针对我系统里根本没有的Fortan编译器,libtool的配置探针就有不少于26个名字,而且还要再执行26个测试,检测这些根本不存在的Fortran编译器分别支不支持-g选项的原因。

这是由Raymond在其书中称颂的集市模式导致的悲哀的现实:一坨脓包似的权宜代码,被一群盲目的根本不知IT架构为何物的所谓IT“专业人士” 永无休止地复制着,粘贴着。这事儿放在今天你也许很难相信,但就是在这令人无比尴尬的混沌之下,沉睡着美轮美奂的Unix大教堂的遗迹,而它正是因设计简约、功能实用、执行优雅而著称于世的。(世间荣耀就此消失……)

Brooks提出了很多有见地的观点,其中一个就是所谓质量,只有在某人对它负责时才有意义,而这个“某人”只能是一个人,不能是几个人——二重奏除外。我有点奇怪,为什么Brooks不把Unix作为他这个观点的论据,因为我们可以精确地指出Unix走向分裂的时间点:1990年代初,AT&T抛弃Unix,将其商业化,抢走其架构师的那一刻。

最近几年,不止一个人像Brooks一样得出相同的结论。有些人企图粉饰太平,假装正经,还有人通过制定技术标准的形式来达到类似立法的目的,希冀着在集市中引入秩序和结构。到目前为止,他们的努力全部以失败告终,因为集市迷失的这一代.COM神奇小子,从来就没有见过大教堂,也不可能知道你为什么需要大教堂,更不用说去想象教堂是个什么样子了。这么挖苦别人,其实我心里也很难过。真的,那些最需要看看《设计原本》的人,可能会发现这本书完全无法理解。但对于那些怀疑过构建一个Web浏览器要使用M4宏来配置autoconf,要写shell脚本,要检测26种Fortran编译器,而感觉这怎么说都有点南辕北辙的人,Brooks也谨慎地指出了方向:还有更好的方式。

作者:Poul-Henning Kamp (phk@FreeBSD.org) ,26年的计算机程序员,个人网站http://bikeshed.org/。他编写的软件以底层构建块的形式广泛被开源和商业产品采用。他最近正在做的项目叫Varnish HTTP加速器,用于加快Facebook这样访问量网站的响应速度。

原文出自:A Generation Lost in the Bazaar

译文来自:图灵社区


目录 第I部分. 基础 第1章 介绍 1.1 在 FreeBSD 上进行开发 1.2 BSD 理念 1.3 指导性架构设计原则 1.4 /usr/src的层次结构 第2章 编程工具 2.1 概述 2.2 介绍 2.3 编程初步 2.4 用 cc 编译 2.5 Make 2.6 调试 2.7 使用 Emacs 作为开发环境 2.8 补充阅读 第3章 安全的编程 3.1 提要 3.2 安全的设计方法 3.3 缓冲区溢出 3.4 SetUID 问题 3.5 限制你的程序环境 3.6 信任 3.7 竞态条件 第4章 本地化与国际化 - L10N 和 I18N 4.1 编写适应国际化的应用程序 4.2 使用 POSIX.1 本地语言支持 (NLS) 的本地化消息 第5章 源代码树指南和维护发展策略 5.1 Makefile 的 MAINTAINER 5.2 第三方软件 5.3 妨碍性的 (Encumbered) 文件 5.4 共享库 第6章 回归与性能测试 6.1. 微性能测试列表 第II部分. 进程间通信 第7章 套接字 7.1 概述 7.2 联网和多样性 7.3 协议 7.4 套接字模型 7.5 重要的套接字函数 7.6 辅助函数 7.7 并发服务器 第8章 IPv6内部 8.1 IPv6/IPsec的实现 第III部分. 内核 第9章 联编并安装 FreeBSD 内核 9.1 以 “传统” 方式联编内核 9.2 以 “新” 方式联编内核 第10章 调试内核 10.1 如何将内核的崩溃转存数据保存成文件 10.2 使用 kgdb 调试内核的崩溃转存 10.3 使用 DDD 调试崩溃转存文件 10.4 使用 DDB 进行在线内核调试 10.5 使用远程 GDB 进行联机内核调试 10.6 如何调试控制台驱动 10.7 调试死锁 10.8 用于调试的内核选项术语表 第IV部分. 系统结构 第11章 x86 汇编语言 11.1 概述 11.2 工具 11.3 系统调用 11.4 返回值 11.5 建立可移植的代码 11.6 编写第一个程序 11.7 编写 UNIX® 过滤程序 11.8 缓存 I/O 11.9 命令行参数 11.10 UNIX® 的环境 11.11 文件处理 11.12 One-Pointed Mind 11.13 Using the FPU 11.14 忠告 11.15 致谢
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值