读书笔记 --《人月神话》
(1975版) The Mythical Man-Month
岸上的船儿,如同海上的灯塔,无法移动。
A ship on the beach is a lighthouse to the sea...
史前史中,没有别的场景比巨兽在焦油坑中垂死挣扎的场面更令人震撼。上帝见证着恐龙,猛犸象,剑齿虎在焦油坑中挣扎。它们挣扎得越是猛烈,焦油纠缠得越紧,没有任何猛兽足够强壮或具有强壮或具有足够的技巧,能够挣脱束缚,它们都沉到了坑底。
过去几十年的大型系统开发就犹如这样一个焦油坑,表面上看起来好像没有任何一个单独的问题。会导致困难,每个都能被解决,但是当它们相互纠缠和累积在一起的时候,团队的行动就会变得越来越慢。不过,如果我们想解决问题,就必须试图先去理解它。
编程产品(Programming Product)
这是可以被任何人运行,测试,修复和扩展的程序。它可以运行在多种操作系统平台上,供多套数据使用。要成为通用的编程产品,程序必须按照普遍认可的风格来编写,特别是输入的范围和形式必须扩展,以适用于所有可以合理使用的基本算法。接着,对程序进行彻底的测试,确保它的稳定性和可靠性,使其值得信赖。这就意味着必须准备,运行和记录详尽的测试用例库,用来检查输入的边界和范围。此外,要将程序提升为程序产品,还需要有完备的文档,每个人都可以加以使用,修复和扩展。经验数据表明,相同功能的编程产品的成本,至少是已经经过测试的程序的3倍。
编程系统(Programming System)
这是在功能上能相互协作的程序集合,具有规范的格式,可以进行交互,并可以用来组装和搭建整个系统。要成为系统构件,程序必须按照一定的要求编制,使输入和输出在语法和语义上与精确定义的接口一致。同时程序还要符合预先定义的资源限制——内存空间,输入输出设备,计算机时间。最后,程序必须同其它系统构件单元一道,以任何能想象到的组合进行测试。由于测试用例会随着组合不断增加,所以测试的范围非常广。因为一些意想不到的交互会产生许多不易察觉的bug,测试工作将会非常耗时,因此相同功能的编程系统构件的成本至少是独立程序的三倍。
编程系统产品(Programming Systems Product)
其成本高达9倍,然而,只有它才是真正有用的产品,是大多数系统开发的目标。
编程系统产品:
职业的乐趣:
首先是一种创建事物的纯粹快乐。如同小孩在玩泥巴时感到愉快一样,成年人喜欢创建事物,特别是自己进行设计。我想这种快乐是上帝创造世界的折射,一种呈现在每片独特,崭新的树叶和雪花上的喜悦。乐趣还来自于工作在如此易于驾驭的介质上。程序员,就像诗人一样,几乎仅仅工作在单纯的思考中。程序员凭空地运用自己的想象,来捏造自己的城堡。很少有这样的介质——创造的方式如此灵活,如此得易于精炼和重建,如此得容易实现概念上的设想。(不过我们将会看到,容易驾驭的特性也有它自己的问题)
编程非常有趣,在于它不仅满足了我们内心深处进行创造的渴望,而且还愉悦了每个人内在的情感。
职业的苦恼:
然而这个过程并不全都是喜悦。我们只有事先了解一些编程固有的烦恼,这样,当它们真正出现时,才能更加坦然地面对。
- 必须追求完美
- 由他人来设定目标,供给资源,提供信息
- 依赖其他程序员,共同合作
- 概念设计是有趣的,但寻找琐碎的bug却是一项重复性活动
- 无奈——投入了大量劳动后,却已显得陈旧过时
美酒的酿造需要年头,美食的烹调需要时间;片刻等待,更多美味,更多享受。
Good cooking takes time, if you are made to wait, it is to serve you better, and to please you...
项目滞后的原因:
- 不真实的假设——一切都将运作良好
- 估算时隐含地假设人和月可以互换
- 没有耐心持续地进行估算并不断更新,调整
- 对进度缺少跟踪和监督
- 当意识到进度偏离时,下意识的反应是增加人力,但只是火上浇油,让事情更糟
乐观主义
计算机编程基于十分容易掌握的介质,编程人员通过非常纯粹的思维活动——概念,以及灵活的表现形式来开发程序。正由于介质的易于驾驭,我们期待在实现过程中不会碰到困难,因此造成了乐观主义的弥漫。
软件任务进度
1/3 计划
1/6 编码
1/4 构件测试和早期系统测试
1/4 系统测试
外科手术队伍(The Surgical Team)
这些研究表明,效率高和效率低的实施者之间具体差别非常大。经常达到了数量级水平。
The studies revealed large individual differences between high and low performers, often by an order of magnitude...
外科医生,Mills称之为首席程序员。他亲自定义功能和性能技术说明书,设计程序,编制源代码,测试以及书写技术文档。他使用例如PL/I的结构化编程语言,拥有对计算机系统的访问能力,该计算机系统不仅仅能进行测试,还存储程序的各种版本,以允许简单的文件更新,并对他的文档提供文本编辑能力。首席程序员需要极高的天分,十年的经验和应用教学,业务数据处理或其他方面的大量系统和应用知识。
贵族专制,民主政治和系统设计(Aristocracy,Democracy,and System Design)
大教堂是艺术史上无与伦比的成就。它的原则既不乏味也不混乱......真正达到了风格上的极致,完成这件作品的艺术家们,完全领会和吸收了以往的成功经验,也完全掌握了他们那个时代的技术,而且在应用的时候做到了恰如其分,绝不轻率,也绝不花哨。如同旅游指南所示,风格的一致和完整性来自于系统拥有自我约束和牺牲精神的建筑师们,他们每个人牺牲了自己的一些创意,以获得纯粹的设计。同样,这不仅显示了上帝的荣耀,同时也体现了他拯救那些沉醉在自我骄傲中人们的力量。
在系统设计中,概念完整性应该是最重要的考虑因素。也就是说为乐反映一系列连贯的设计思路,宁可省略一些不规则的特性和改进,也不提倡独立和无法整合的系统,哪怕它们其实包含着许多很好的设计。概念的完整性要求设计必须由一个人,或者非常少数互有默契的人员来实现。而进度压力却要求很多人员来开发系统。有两种方法可以解决这种矛盾。第一种是仔细地区分设计方法和具体实现。第二种是前一章节中所讨论的,一种崭新的组建编程开发团队的方法。
对于非常大型的项目,将设计方法,体系结构方面的工作与具体实现相分离是获得概念完整性的强有力方法。
系统的体系结构(architecture)指的是完整和详细的用户接口说明。对于计算机,它是编程手册,对于编译器,它是语言手册;对于控制程序,它是语言和函数调用手册,对于整个系统,它是用户要完成自己全部工作所需参考的手册的集合。因此,系统的结构师,如同建筑的结构师一样,是用户的代理人。结构师的工作,是运用专业技术知识来支持用户的真正利益,而不是维护销售人员所鼓吹的利益。体系结构同实现必须仔细区分开来。如同Blaauw所说的,“体系结构陈述的是发生了什么,而实现描述的是如何实现。”
作者的经验观念:
系统的概念完整性决定了使用的容易程度。不能与系统基本概念进行整合的良好想法和特色,最好放到一边,不予考虑。
如果出现了很多非常重要但不兼容的构想,就应该抛弃原来的设计,对不同基本概念进行合并,在合并之后的系统上重新开始。
没有规矩,不成方圆。——纪律和规则对行业是有益的。
外部的体系结构规定实际上是增强,而不是限制实现小组的创造性。一旦他们将注意力集中在没有人解决过的问题上,创意就开始奔涌而出。
如同Blaaw所指出的,整个创造性活动包括了三个独立的阶段:体系结构(architecture),设计实现(implementation),物理实现(realization)。在实际情况中,它们往往可以同时开始和并发地进行。在开发第一个系统的时候,结构师倾向于精炼和简洁。他知道自己对正在进行的任务不够了解,所以他会谨慎仔细地工作。第二个系统是设计师们所设计的最危险的系统。而当他着手第三个或第四个系统时,先前的经验会相互验证,得到此类系统通用特性的判断,而且系统之间的差异会帮助他识别出经验中不够通用的部分。
贯彻执行(Passing the word)
文档手册读起来枯燥乏味,但是精确比生动更加重要。
为什么巴比伦塔会失败?
既然他们具备了所有的这些条件,为什么项目还会失败呢?他们还缺乏些什么?
——两个方面:交流以及交流的结果,组织。
通过史书的字里行间,我们推测交流的缺乏导致了争辩,沮丧和群体猜忌。很快,部落开始分裂:大家选择了孤立,而不是互相争吵。
大型编程项目的组织架构:
如果项目有n个工作人员,则有n(n-1)/2个相互交流的接口,有将近能2^n个必须合作的潜在团队。团队组织的目的是减少不必要的交流和合作的数量,因此良好的团队组织是解决上述交流问题的关键措施。减少交流的方法是人力划分(Division of labor)和限定职责范围(Specialization of function)。当使用人力划分和职责限定时,树状管理结构所映出对详细交流需要会相应减小。
那么技术主管的角色是什么?他对设计进行构思,识别系统的子部分,指明从外部看上去的样子,勾画它的内部结构。他提供整个设计的一致性和概念的完整性;他控制系统的复杂程度。当某个技术问题出现时,他提供问题的解决方案,或者根据需要调整系统设计。用Al Capp所喜欢的一句谚语,他是“攻坚小组中的独行侠”(inside-man at the skunk works)他的沟通交流在团队中是首要的。他的工作几乎完全是技术性的。
巴比伦塔可能是第一个工程上的彻底失败,但它不是最后一个。交流和交流的结果——组织,是成功的关键。交流和组织的技能需要管理者仔细考虑,相关经验的积累和能力的提高,同软件技术本身一样重要。
胸有成竹(Calling the Shot)
实践是最好的老师。但是,如果不能从中学习,再多的实践也没有用。
附录:
从哈佛大学Aiken和Iverson名下毕业终于让我的职业梦想变成了现实,并且,就这样沉迷了一辈子。感谢上帝,让我成为了为数不多的那些开开心心做着自己喜欢工作的人之一。我实在无法想象还有哪种生活会比热爱计算机更加激动人心,自从从真空管发展到集成电路以来,计算机技术已经飞速发展。我用来工作的第一台计算机,是从哈佛刚刚出炉的IBM 7030 Stretch超级计算机,Stretch在1961到1964年间都是世界上运算速度最快的计算机,一共卖出了9台。而我现在用的计算机,Macintosh Powerbook,不但快,还有大容量内存和硬盘,而且便宜了1000倍(如果按定价美元来算,便宜了5000倍)。我们依次看到了计算机革命,电子计算机革命,小型计算机革命,微型计算机革命,这些技术上的革命每一次都带来了计算机数量上的剧增。
在计算机技术进步的同时,计算机相关学科知识也在飞速发展。当我在五十年代刚从学校毕业的时候,我能看完当时所有的期刊和会议报告,掌握所有的潮流动向。而我现在只能对层出不穷的学科分支遗憾地说再见,对我所关注的东西也越来越难以全部掌握。兴趣太多,令人兴奋的学习,研究和思考的机会也太多——多么不可思议的矛盾啊!这个神奇的时代远远没有结束,它依然在飞速发展。
更多的乐趣,尽在将来。