代码改变世界

【读书笔记】《人月神话》 摘录

2014-04-15 07:54  stoneniqiu  阅读(1296)  评论(2编辑  收藏

《人月神话》开始看到书名还以为讲人类如何登陆月球滴(见笑见笑)...  读了之后发现这是一本主要讲在软件开发中的设计、管理、文档、bug等方面的认识和建议的经典之作。像“没有银弹”,就是源于这本书。但由于文中软件开发所讨论的对象是1975左右IBM开发的OS/360,对我们而言相去甚远很多概念不是很清楚,再者译文过来的句子有的地方比较绕。有些部分读起来容易迷糊,但很多观念都是很经典的。所以整理了这么一个摘录,加粗只是我认为重要的部分,绿色是我自己备注的部分。各取所需。

第一章:焦油坑

1.2 编程行业“满足我们内心深处的创造渴望和愉悦所有人的共有情感”,提供了五种

乐趣:
􀂉 创建事物的快乐
􀂉 开发对其他人有用的东西的乐趣 //这一点 我是觉得是成就感的主要来源。我们追求的不是炫酷吊炸天,是有很多人用的产品,满意你的产品
􀂉 将可以活动、相互啮合的零部件组装成类似迷宫的东西,这个过程所体现出令人神魂颠倒的魅力
􀂉 面对不重复的任务,不间断学习的乐趣 //学习总是充满了乐趣 说明你还是热爱这个领域的
􀂉 工作在如此易于驾驭的介质上的乐趣——纯粹的思维活动,其存在、移动和运转方式完全不同于实际物体

//虽然是几十年前的文章,但作者总结的很到位,现在依旧如此。
1.3 同样,这个行业具有一些内在固有的苦恼:
􀂉 将做事方式调整到追求完美,是学习编程的最困难部分
􀂉 由其他人来设定目标,并且必须依靠自己无法控制的事物(特别是程序);权威不等同于责任
􀂉 实际情况看起来要比这一点好一些:真正的权威来自于每次任务的完成
􀂉 任何创造性活动都伴随着枯燥艰苦的劳动,编程也不例外

􀂉 人们通常期望项目在接近结束时,(bug、工作时间)能收敛得快一些,然而软件项目的情况却是越接近完成,收敛得越慢

􀂉 产品在即将完成时总面临着陈旧过时的威胁

 

第2章人月神话


2.1 缺乏合理的时间进度是造成项目滞后的最主要原因,它比其他所有因素加起来影响还大//没有计划,是不行的。任务一拖再拖,无论是自己想做的事情还是工作的事情
2.2 良好的烹饪需要时间,某些任务无法在不损害结果的情况下加快速度。
2.3 所有的编程人员都是乐观主义者:“一切都将运作良好”//那些熟悉的话语:“这些肯定没有问题,我都测试过了”,“这个没有bug了",”最后一个bug已经改好了“
2.4 由于编程人员通过纯粹的思维活动来开发,所以我们期待在实现过程中不会碰到困

难。
2.5 但是,我们的构思是有缺陷的,因此总会有bug。
2.6 我们围绕成本核算的估计技术,混淆了工作量和项目进展。人月是危险和带有欺骗性的神话,因为它暗示人员数量和时间是可以相互替换的。
2.7 在若干人员中分解任务会引发额外的沟通工作量——培训和相互沟通。
2.8 关于进度安排,我的经验是为1/3计划、1/6编码、1/4构件测试以及1/4系统测试。//比例可以调整,但是步骤做到了吗?
2.9 作为一个学科,我们缺乏数据估计。
2.10 因为我们对自己的估计技术不确定,所以在管理和客户的压力下,我们常常缺乏坚持的勇气。//程序员太老实了 
2.11 Brook法则:向进度落后的项目中增加人手,只会使进度更加落后
2.12 向软件项目中增派人手从三个方面增加了项目必要的总体工作量:任务重新分配本身和所造成的工作中断;培训新人员;额外的相互沟通。

 

第3章外科手术队伍

3.1 同样有两年经验而且在受到同样的培训的情况下,优秀的专业程序员的工作效率是较差程序员的十倍。(Sackman、Erikson和Grand)
3.3 小型、精干队伍是最好的——尽可能的少。
3.5 对于真正意义上的大型系统,小型精干的队伍太慢了。
3.6 实际上,绝大多数大型编程系统的经验显示出,一拥而上的开发方法是高成本、速度缓慢、不充分的,开发出的产品无法进行概念上的集成。

 

3.7 一位首席程序员、类似于外科手术队伍的团队架构提供了一种方法——既能获得由少数头脑产生的产品完整性,又能得到多位协助人员的总体生产率,还彻底地减少了沟通的工作量。


第4章贵族专制、民主政治和系统设计


4.1 “概念完整性是系统设计中最重要的考虑因素”。//概念完整性:反映一系列连贯的设计思路,像建筑一样,风格统一,易于整合
4.3 为了获得概念完整性,设计必须由一个人或者具有共识的小型团队来完成。
4.4 “对于非常大型的项目,将设计方法、体系结构方面的工作与具体实现相分离是获得概念完整性的强有力方法。”[同样适用于小型项目。]
4.6 纪律、规则对行业是有益的。外部的体系结构规定实际上是增强,而不是限制实现小组的创造性。

4.7 概念上统一的系统能更快地开发和测试。
4.8 体系结构(architecture)、设计实现(implementation)、物理实现(realization)的许多工作可以并发进行。[软件和硬件设计同样可以并行。]


第5章 画蛇添足


5.1 尽早交流和持续沟通能使结构师有较好的成本意识,以及使开发人员获得对设计的信心,并且不会混淆各自的责任分工。
5.2 结构师如何成功地影响实现:
􀂉 牢记是开发人员承担创造性的实现责任;结构师只能提出建议。
􀂉 时刻准备着为所指定的说明建议一种实现的方法,准备接受任何其他可行的方

法。
􀂉 对上述的建议保持低调和平静。
􀂉 准备对所建议的改进放弃坚持。
􀂉 听取开发人员在体系结构上改进的建议。

//这一点有所感触,架构师的思路如果没有很好的沟通往往实现的不好。
 
第6章贯彻执行


6.1 即使是大型的设计团队,设计结果也必须由一个或两个人来完成,以确保这些决定是一致的。

6.8  日志记录和整理发布。
6.9 “项目经理最好的朋友就是他每天要面对的敌人——独立的产品测试机构/小组。”

 

第7章为什么巴比伦塔会失败?

7.1 巴比伦塔项目的失败是因为缺乏交流,以及交流的结果——组织。
7.2 “因为左手不知道右手在做什么,从而进度灾难、功能的不合理和系统缺陷纷纷出现。”由于对其他人的各种假设,团队成员之间的理解开始出现偏差。
// 多个团队负责一个项目的时候,这种情况最明显了 但交流太多比如会议 也是在浪费时间(太多会议),而且更加得不出策略

7.17 为了减少交流,组织结构包括了人力划分(division of labor)和限定职责范围(specialization of function)。

第8章胸有成竹


8.1 仅仅通过对编码部分的估计,然后乘以任务其他部分的相对系数,是无法得出对整项工作的精确估计的。
8.2 构建独立小型程序的数据不适用于编程系统项目。
8.3 程序开发呈程序规模的指数增长。
8.4 一些发表的研究报告显示指数约为1.5。[Boehm的数据并不完全一致,在1.05和1.2之间变化。1]

8.11 当使用适当的高级语言时,程序编制的生产率可以提高5倍。//高级语言就是更加容易实现和反应人的逻辑思维的


第9章削足适履

9.3 软件开发人员必须设立规模目标,控制规模,发明一些减少规模的方法——就如同硬件开发人员为减少元器件所做的一样。//程序要精简 虽然现在不是那么的计较机器的内存和性能
9.5 规模预算必须与分配的功能相关联;在指明模块大小的同时,确切定义模块的功能。
9.6 在大型的团队中,各个小组倾向于不断地局部优化,以满足自己的目标,而较少考虑队用户的整体影响。这种方向性的问题是大型项目的主要危险。//只管自己如何实现,而没有考虑到用户的操作习惯
9.8 培养开发人员从系统整体出发、面向用户的态度是软件编程管理人员最重要的职能。

9.12 编程需要技术积累,每个项目需要自己的标准组件库
9.14 精炼、充分和快速的程序。往往是战略性突破的结果,而不仅仅技巧上的提高。

第10章 提纲挈领 

//论文档的重要性...
10.1 “前提:在一片文件的汪洋中,少数文档形成了关键的枢纽,每个项目管理的工作都围绕着它们运转。它们是经理们的主要个人工具。”
10.2 对于计算机硬件开发项目,关键文档是目标、手册、进度、预算、组织机构图、空间分配、以及机器本身的报价、预测和价格。
10.4 对于软件项目,要求是相同的:目标、用户手册、内部文档、进度、预算、组织机构图和工作空间分配。
10.5 因此,即使是小型项目,项目经理也应该在项目早期规范化上述的一系列文档。
10.6 以上集合中每一个文档的准备工作都将注意力集中在对讨论的思索和提炼,而书写这项活动需要上百次的细小决定,正是由于它们的存在,人们才能从令人迷惑的现象中得到清晰、确定的策略。
10.9 项目经理的基本职责是使每个人都向着相同的方向前进。

10.10 项目经理的主要日常工作是沟通,而不是做出决定;文档使各项计划和决策在整个团队范围内得到交流。

第11章未雨绸缪

11.5 将开发的第一个系统——丢弃原型——发布给用户,可以获得时间,但是它的代价高昂——对于用户,使用极度痛苦;对于重新开发的人员,分散了精力;对于产品,影响了声誉,即使最好的再设计也难以挽回名声。//往往第一个系统存在的问题蛮多
11.6 因此,为舍弃而计划,无论如何,你一定要这样做。
11.7 “开发人员交付的是用户满意程度,而不仅仅是实际的产品。”(Cosgrove)//几十年前人家已经看到了
11.8 用户的实际需要和用户感觉会随着程序的构建、测试和使用而变化

11.9 软件产品易于掌握的特性和不可见性,导致了它的构建人员(特别容易)面临着永恒的需求变更。
11.10 目标上(和开发策略上)的一些正常变化无可避免,事先为它们做准备总比假设它们不会出现要好得多。

11.20 程序维护基本上不同于硬件的维护;它主要由各种变更组成,如修复设计缺陷、新增功能、或者是使用环境或者配置变换引起的调整。
11.21 对于一个广泛使用的程序,其维护总成本通常是开发成本的40%或更多。
11.22 维护成本受用户数目的严重影响。用户越多,所发现的错误也越多
11.23 Campbell指出了一个显示产品生命期中每月bug数的有趣曲线,它先是下降,然后攀升。
11.24 缺陷修复总会以(20-50)%的机率引入新的bug。
11.25 在每次修复之后,必须重新运行先前所有的测试用例,从而确保系统不会以更隐蔽的方式被破坏。

第12章干将莫邪

//工欲善其事,必先利其器 
12.1 项目经理应该制订一套策略,以及为通用工具的开发分配资源,与此同时,他还必须意识到专业工具的需求。//如果开发本太烂,程序员很不爽,后果很严重
12.5 同天文工作者一样,系统调试总是大部分在夜间完成。//程序员夜间小宇宙适合爆发

12.9 主程序库应该被划分成(1)一系列独立的私有开发库;(2)正处在系统测试下的系统集成子库;(3)发布版本。正式的分离和进度提供了控制。
12.10 在编制程序的项目中,节省最大工作量的工具可能是文本编辑系统。
高级语言
12.13 只有懒散和惰性会妨碍高级语言和交互式编程的广泛应用。[如今它们已经在全世界使用。]
12.14 高级语言不仅仅提升了生产率,而且还改进了调试:bug更少,以及更容易寻找//更接近人的语义了
12.15 传统的反对意见——功能、目标代码的尺寸、目标代码的速度,随着语言和编译器技术的进步已不再成为问题。
12.17 某些应用上,批处理系统决不会被交互式系统所替代。[依然成立。]
12.18 调试是系统编程中很慢和较困难的部分,而漫长的调试周转时间是调试的祸根。

第13章整体部分

13.3 在编写任何代码之前,规格说明必须提交给测试小组,以详细地检查说明的完整性和明确性。开发人员自己不会完成这项工作。(Vyssotsky)
13.7 有时必须回退,推翻顶层设计,重新开始。

13.11 系统调试(相对于单元测试)花费的时间会比预料的更长。
13.14 开发大量的辅助调试平台(scaffolding 脚手架)和测试代码是很值得的,代码量甚至可能会有测试对象的一半。

 

第14章祸起萧墙


14.1 “项目是怎样延迟了整整一年的时间?⋯一次一天。”//项目就延迟了一次,一次一年 哈哈
14.2 一天一天的进度落后比起重大灾难,更难以识别、更不容易防范和更加难以弥补。
14.3 根据一个严格的进度表来控制项目的第一个步骤是制订进度表,进度表由里程碑和日期组成。
14.4 里程碑必须是具体的、特定的、可度量的事件,能进行清晰能定义。如果里程碑定义得非常明确,以致于无法自欺欺人时,程序员很少会就里程碑的进展弄虚作假。

14.7 慢性进度偏离是士气杀手。[Microsoft的Jim McCarthy说:“如果你错过了一个最终期限(deadline),确保制订下一条deadline。2”]//拖得太长了 人心都疲敝了,然后还要考虑是不是过时了
14.8 进取对于杰出的软件开发团队,同优秀的棒球队伍一样,是不可缺少的必要品德

14.14 状态的获取是困难的,因为下属经理有充分的理由不提供信息共享。
14.16 必须有评审的机制,从而所有成员可以通过它了解真正的状态。出于这个目的,里程碑的计划和完成文档是关键。//步步为营
14.18 对于大型项目,一个对里程碑报告进行维护的计划和控制(Plan and Control)小组是非常可贵的。

第15章另外一面

15.1 对于软件编程产品来说,程序向用户所呈现的面貌与提供给机器识别的内容同样重要。
15.2 即使对于完全开发给自己使用的程序,描述性文字也是必须的,因为它们会被用户-作者所遗忘。//养成注释的好习惯。

15.13 最小化文档负担的3个关键思路:
􀂉 借助那些必须存在的语句,如名称和声明等,来附加尽可能多的“文档”信息。
􀂉 使用空格和格式来表现从属和嵌套关系,提高程序的可读性。
􀂉 以段落注释,特别是模块标题的形式,向程序中插入必要的记叙性文字。
15.14 程序修改人员所使用的文档中,除了描述事情如何以外,还应阐述它为什么那样。对于加深理解,目的是非常关键的,但即使是高级语言的语法,也不能表达目的。

没有银弹

没有任何技术或管理上的进展,能够独立地许诺十年内使生产率、可靠性或简洁性获得数量级上的进步。 

 

在所有恐怖民间传说的妖怪中,最可怕的是人狼,因为它们可以完全出乎意料地从熟悉的面孔变成可怕的怪物。为了对付人狼,我们在寻找可以消灭它们的银弹。
大家熟悉的软件项目具有一些人狼的特性(至少在非技术经理看来),常常看似简单明了的东西,却有可能变成一个落后进度、超出预算、存在大量缺陷的怪物。因此,我们听到了近乎绝望的寻求银弹的呼唤,寻求一种可以使软件成本像计算机硬件成本一样降低的尚方宝剑。

 

//由于软件行业的特殊性,计算机硬件发展太快(摩尔定律),软件的复杂性,可变性,不可见性很不同于其他传统行业。但根本的问题还是围绕生产效率,层出不穷的框架,设计思路(DDD,TDD,敏捷开发相关...),更多高级语言的出现,提供代码复用的能力等等。或许这些都不适合你,你有你信手拈来、得心应手的方式。

 

你有你的自己的银弹么?是否在寻找?