第1章 焦油坑
1.1 编程系统产品(Programming Systems Product)开发的工作量是供个人
使用的、独立开发的构件程序的九倍。我估计软件构件产品化引起了3倍
工作量,将软件构件整合成完整系统所需要的设计、集成和测试又强加了
3倍的工作量,这些高成本的构件在根本上是相互独立的。
《编程系统产品与供个人使用的、独立开发的构件程序(小型程序)之间的
工作量的差距与差距的产生的原因》
1.2 编程行业“满足我们内心深处的创造渴望和愉悦所有人的共有情感”,
□创建事物的快乐
□开发对其他人有用的东西的乐趣
□将可以活动、相互啮合的零部件组装成类似迷宫的东西,这个过程
□工作在如此易于驾驭的介质上的乐趣——纯粹的思维活动,其存在、 1.3 同样,这个行业具有一些内在固有的苦恼:《职业的苦恼》
□将做事方式调整到追求完美,是学习编程的最困难部分
□由其他人来设定目标,并且必须依靠自己无法控制的事物(特别是程序) □权威不等同于责任
□实际情况看起来要比这一点好一些:真正的权威来自于每次任务的完成 □任何创造性活动都伴随着枯燥艰苦的劳动,编程也不例外 □人们通常期望项目在接近结束时,(bug、工作时间)能收敛得快一些, 《焦油坑我理解是,人数少的项目,灵活而容易控制,但人数众多的大型项目
像史前巨兽在焦油坑里挣扎一样,很难控制进程,很难推进,而且很难看清
无法推进的本质原因。并且我们无法用小型团队来开发大型系统。我觉得
可能中国还没有(或非常非常少)真正意义上的参加人数众多的大型项目,
焦油坑对于末端程序员的表现是,很多没有解决的或自己没掌握的问题,
天天加班熬夜来解决,但自己始终解决不了,上头天天催促,压力倍增,
看不到尽头,觉得提交物(或大家做的东西)是一堆垃圾。》
---------------------------------------------------------------------
2.1 缺乏合理的时间进度是造成项目滞后的最主要原因,它比其他所有因素
《合理的时间进度我觉得是最难把握的,可能人数较少的项目某个个人
能控制进度,但人数众多时,应该是推测的性质很大,好像只能展开
项目并推动项目,好像无法(或很难)控制项目》
2.2 良好的烹饪需要时间,某些任务无法在不损害结果的情况下加快速度。
《质量是需要相应时间的,某些时候不牺牲质量是无法加快速度
这里的质量观应该和中国程序员的质量观有本质的区别,不仅仅是
2.3 所有的编程人员都是乐观主义者:“一切都将运作良好”。 《我们进行项目时尽管有很多问题,但都会倾向于乐观》
2.4 由于编程人员通过纯粹的思维活动来开发,所以我们期待在实现过程中 不会碰到困难。
2.5 但是,我们的构思是有缺陷的,因此总会有bug。
2.6 我们围绕成本核算的估计技术,混淆了工作量和项目进展。人月是危险和
带有欺骗性的神话,因为它暗示人员数量和时间是可以相互替换的。
《大型项目的预算是按照人月(一个人一个月的工作量)来计算的,
这里是说比如1个人10月的工作总量,与10个人一个月的总量,不能
等同,也就是人员数量和时间是不可以相互替换的》
2.7 在若干人员中分解任务会引发额外的沟通工作量——培训和相互沟通。
《人多了以后会引发额外的沟通工作量,培训和相互沟通(也就是
我们长说的边学习边干活)》
2.8 关于进度安排,我的经验是为1/3计划、1/6编码、1/4构件测试以及
《需求分析,基本设计,详细设计是需要整个开发期间的1/3的时间,
编写代码是需要整个开发期间的1/6的时间,然后单元测试、集成测试、
需要1/4的时间,确认测试和系统测试(及发版测试)需要1/4.时间。
在国内应该很少有这样的标准开发了》
2.9 作为一个学科,我们缺乏数据估计。
《人多了以后会我觉得很多都是未定,很难或不可能估计得到》 2.10 因为我们对自己的估计技术不确定,所以在管理和客户的压力下, 《我理解是无法争取充分的时间》
2.11 Brook法则:向进度落后的项目中增加人手,只会使进度更加落后。 《我觉得100%正确,无论多厉害的人也不可能马上知道项目独有的
业务,(除非是他设计的),这就意味着想让新加的人干活,就需
要额外的很多时间和工作量,人数越多,工作量就越大》
2.12 向软件项目中增派人手从三个方面增加了项目必要的总体工作量:
任务重新分配本身和所造成的工作中断;培训新人员;额外的相互沟通。
《我觉得100%正确,所以加的人越多就意味着得让更多的人通过沟通
理解你的东西,这谈何容易,人与人的沟通在任何行业都是非常
《我的理解:这一章的主要表示,软件开发中的工作量的预测问题(也可以
是预算的问题),解释工作量的产生原因。这里非常想强调的是在一个
---------------------------------------------- 3.1 同样有两年经验而且在受到同样的培训的情况下,优秀的专业程序员的
工作效率是较差程序员的十倍。(Sackman、Erikson和Grand)
《这句话100%赞同,每个程序员的效率都是不一样的,会干活的
效率高,不会干活的效率低,这与技术的高低无关,取决于个人》
3.2 Sackman、Erikson和Grand的数据显示经验和实际表现之间没有相互联系。
《人员少沟通的工作量,培训的工作量就少,容易控制推进项目》
3.4 两个人的团队,其中一个项目经理,常常是最佳的人员使用方法。
3.5 对于真正意义上的大型系统,小型精干的队伍太慢了。
《确实。。比如像windows这样的系统,几个人开发出来是绝不可能》
3.6 实际上,绝大多数大型编程系统的经验显示出,一拥而上的开发方法是
高成本、速度缓慢、不充分的,开发出的产品无法进行概念上的集成。
《确实。。一拥而上的后果,出现大量的培训工作,也无法统一概念
也就是无法正确传达要做成什么样子,我觉得应该是少数人开始,
每过一段时间慢慢增加人手,在这个一段时间内传播概念,然后再
让他们传播下一批增加的人,慢慢增加人手,达到顶峰以后,又慢慢
3.7 一位首席程序员、类似于外科手术队伍的团队架构提供了一种方法——
既能获得由少数头脑产生的产品完整性,又能得到多位协助人员的总体
《确实,一个小项目以小型团队以外科手术队伍的模式进行可能是
最好的,因为所有的问题集中到这个人身上,并由这个人来解决问题,
分派任务,监督控制并推进项目,但一旦这个首席程序员出错时,也
意味着项目的失败,这个觉得和外科手术失败和主治医生有很大关系,
但一个大项目呢?也能这样吗?高级手术队伍中有个主治医生和几个
助手,这几个助手又是中级手术队伍中的主治医生,并又有几个助手,
并且这几个助手又是,末端手术队伍中的主治医生,并也有几个最
--------------------------------------------------------
4.1 “概念完整性是系统设计中最重要的考虑因素”。
《可能每个人都有自己的逻辑,参加设计(外部设计)的人越多,
也就设计越乱,也就是人脑中的概念(思想)很难统一》
4.2 “功能与理解上的复杂程度的比值才是系统设计的最终测试标准”,
而不仅仅是丰富的功能。[该比值是对易用性的一种测量,由简单和
4.3 为了获得概念完整性,设计必须由一个人或者具有共识的小型团队来完成。 《非常赞同:人多了,思想很难统一,所以设计人要少》 4.4 “对于非常大型的项目,将设计方法、体系结构方面的工作与具体 《我理解是,为了统一概念,先做一些设计方法、体系结构等的
4.5 “如果要得到系统概念上的完整性,那么必须控制这些概念。 《概念没有绝对的对错,也有好多种,可能因人而异,但具体要用什么
概念是强制决定的,并所有人强制执行,我理解这是人数较多项目
4.6 纪律、规则对行业是有益的。外部的体系结构规定实际上是增强, 《外部的体系结构规定我理解是基本设计也就是外部设计,
而不是限制,要是无规则,每个人(每个小组)做出来的东西
全都不一样,10个人10个样子,最后出来一堆垃圾》
《概念上不统一的系统,开发人员,测试人员,谁知道这个模块
4.8 体系结构(architecture)、设计实现(implementation)、
物理实现(realization)的许多工作可以并发进行。[软件和
《一起并发做,也就是相互考虑的意思吧,体系结构时,考虑 ---------------------------------------------------------- 5.1 尽早交流和持续沟通能使结构师有较好的成本意识,以及使开发
人员获得对设计的信心,并且不会混淆各自的责任分工。
《尽早交流和持续沟通,一针见血,就是说尽量不要把问题
留给以后,要不然这些问题,是谁的责任?》
5.2 结构师如何成功地影响实现:
《结构师应该是基本设计者,也就是外部设计者(Input output设计)》
?□牢记是开发人员承担创造性的实现责任; 《开发人员是实现的人,不是自己,也就是说得为他们考虑某些事情》
□结构师只能提出建议。 《建议的形式提出意见(毕竟人家做东西)》
□时刻准备着为所指定的说明建议一种实现的方法,准备接受 《毕竟你自己也是人,会犯错误,有没想到的地方,所以必须倾听 《没必要高调自己的建议,假如是正确的建议,开发人员会认同 《我理解是,即便建议是对的,但假如不被采纳时应该放弃》 《很有必要,因为可否实现的主要责任,应该由结构设计师来负责,
次要责任是开发人员负责,也就是说实现不了不仅仅是开发人员的
5.3 第二个系统是人们所设计的最危险的系统,通常的倾向是过分地进行设计。
《正确,第一个一般做的小心,但成功以后信心倍增,第二个系统想要做一个
更好的东西,很多时候信息无限膨胀,导致设计脱离实际。会有过分设计
(要求过分多),危险》
5.4 OS/360是典型的画蛇添足(second-system effect)的例子。[Windows
《这两个东西我都没见过,但作者的意思我猜是,做这两个东西的人们
当初可能设想做个[完美?]的东西,但效果远远不如设想?》
5.5 为功能分配一个字节和微秒的优先权值是一个很有价值的规范化方法。
----------------------------------------------------- 1. 问题:项目经理如何确保每个人听从、理解并实现结构师的决策?对于有多个结构师
的小组如何保持系统概念上的完整性。 2. 手册、或者书面规格说明,是一个非常必要的工具。手册是产品的外部规格说明,它
描述和规定了用户所见的每一个细节;同样的,它也是结构师主要的工作产物。 手册不但要描述包括所有界面在内的用户可见的一切,它同时还要描述用户看不见的事物。
后者是编程实现人员的工作范畴,而实现人员的设计和创造是不应该被限制的。体系结构
设计人员必须为自己描述的任何特性准备一种实现方法,但是他不应该试图支配具体的实
现过程。 规格说明的风格必须清晰、完整和准确。用户常常会单独提到某个定义,所以每条说明都
必须重复所有的基本要素,所以所有文字都要相互一致。 3. 规格说明中,形式化定义是精确的,它们倾向于更加完整;差异得更加明显,可以更
快地完成。但是形式化定义的缺点是不易理解。记叙性文字则可以显示结构性的原则,描
述阶段上或层次上的结构,以及提供例子。应同时包括形式化和记叙性定义两种方式。 4. 通过会议的方式,开发人员进行沟通和讨论问题。 5. 不同实现之间严格要求相互兼容。如果起初至少有两种以上的实现,那么定义会更加
整洁和规范。 6. 对于存有疑问的实现人员,应鼓励他们打电话询问相应的结构师,而不是一边自行猜
测一边工作。 一种有用的机制是由结构师保存电话日志。日志中,他记录了每一个问题和相应的回答。
每周,对若干结构师的日志进行合并,重新整理,并发布给用户和实现人员。这种机制很
不正式,但非常快捷和易于理解。 7. 在最后的分析中,用户是独立的监督人员。在残酷的现实使用环境中,每个细微缺陷
都将无从遁形。产品测试小组则是顾客的代理人,专门寻找缺陷。不时地,细心的产品测
试人员总会发现一些没有贯彻执行、设计决策没有正确理解或准确实现的地方。出于这方
面的原因,设立测试小组是使设计决策得以贯彻执行的必要手段,同样也是需要尽早着手
,与设计同时实现的重要环节。 -------------------------------------------------------- 1. 项目人员之间的交流和沟通是项目能否顺利和成功的一个重要因素。 2. 缺乏交流引起进度灾难、功能的不合理和系统缺陷纷纷出现。随着工作的
进行,许多小组慢慢地修改自己程序的功能、规模和速度,他们明确或者隐含
地更改了一些有效输入和输出结果用法上的约定。 清晰定义小组内部的相互关系和充分利用电话,能鼓励大量的电话沟通,从而
达到对所书写文档的共同理解。 常规项目会议。会议中,团队一个接一个地进行简要的技术陈述。这种方式非
常有用,能澄清成百上千的细小误解。 3. 项目工作手册不是独立的一篇文档,它是对项目必须产出的一系列文档进
行组织的一种结构。 项目所有的文档都必须是该结构的一部分。这包括目的、外部规格说明、接口
说明、技术标准、内部说明和管理备忘录。 技术说明几乎是必不可少的。如果某人就硬件和软件的某部分,去查看一系列
相关的用户手册。他发现的不仅仅是思路,而且还有能追溯到最早备忘录的许
多文字和章节,这些备忘录对产品提出建议或者解释设计。 正确的文档结构非常重要。事先将项目工作手册设计好,能保证文档的结构本
身是规范的。另外,有了文档结构,后来书写的文字就可以放置在合适的章节
中。 控制信息发布,确保信息能到达所有需要它的人的手中。 5. 团队组织的目的是减少不必要的交流和合作的数量。减少交流的方法是人
力划分和限定职责范围。当使用人力划分和职责限定时,树状管理结构所映出
对详细交流的需要会相应减少。 ----------------------------------------------------------- 1. 问题:系统编程需要花费多长时间?需要多少工作量?如何进行估计? Portman的数据:工作花费的时间大约是估计的两倍。 Aron、Harr、OS/360的数据:生产率会根据任务本身的复杂度和困难程度表现出
显著差异。 Carbato的数据:对常用的编程语句而言。生产率似乎是固定的。这个固定的生产
率包括了编程中需要注释,并可能存在错误的情况。使用适当的高级语言,编程的
生产率可以提高5倍。 ----------------------------------------------------------- 1. 系统的空间规模:规模是软件系统产品用户成本中如此大的一个组成部分,开发
人员必须设置规模的目标,控制规模,考虑减小规模的方法。同任何开销一样,规模
本身不是坏事,但不必要的规模是不可取的。 2. 对项目经理而言,规模控制既是技术工作的一部分,也是管理工作的一部分。必
须研究用户和他们的应用,以设置将开发系统的规模。接着,把这些系统划分成若干
部分,并设定每个部分的规模目标。由于规模--速度权衡方案的结果在很大的范围内
变化,规模目标的设置是一件颇具技巧的事情,需要对每个可用方案有深刻的了解。
聪明的项目经理还会给自己预留一些空间,在工作推行时分配。 仅对核心程序设定规模目标是不够的,必须把所有的方面都编入预算。 3. 在速度不变的情况下,更多的功能意味着需要更多的空间。其中一个技巧是用功
能交换尺寸。设计人员必须决定用户可选项目的精细程度。 4. 考虑空间--时间的折衷。对于给定的功能,空间越多,速度越快。 项目经理可以做两件事来帮助他的团队取得良好的空间--时间折衷。一是确保他们在
编程技能上得到培训,而不仅仅是依赖他们自己掌握的知识和先前的经验。特别是使
用新语言或者新机器时,培训显得尤其重要。另一种方法是认识到编程需要技术积累,
需要开发很多公共单元构件。 5. 战略上的突破常来自数据或表的重新表达--这是程序的核心所在。数据的表现形
式时编程的根本。 ------------------------------------------------------------ 1. 文档的跟踪维护是项目监督和预警的机制。文档本身可以作为检查
列表、状态控制,也可以作为汇报的数据基础。 目标。待完成的目标、迫切需要的资源、约束和优先级。 首先,书面记录决策是必要的。人们能从令人迷惑的现象中得到清晰、确
定的决策。 第二,文档能作为同其他人沟通的渠道。项目经理的基本职责是使每个人
都向着相同的方向前进,所以他的工作主要是沟通,而不是做出决定。文
档能极大地减轻他的负担。 最后,文档可以作为数据基础和检查列表。通过周期性的回顾,他能清楚
项目所处的状态,以及哪些需要重点进行更改和调整。 项目经理的任务是制订计划,并根据计划实现。只有书面计划是精确和可
以沟通的。通过遵循文档开展工作,项目经理能更清晰和快速地设定自己
的方向。 ---------------------------------------------------------- 1. 对于大多数项目,第一个开发的系统并不合用。可能太慢、太大,而且难以
使用,或者三者兼而有之。要解决所有的问题,除了重新开始以外,没有其他的
办法--即开发一个更灵巧或者更好的系统。系统的丢弃和重新设计可以一步完成
,也可以一块块地实现。所有大型系统的经验都显示,这是必须完成的步骤。
-- 构建一个试验性的系统,然后抛弃它。 2. 一旦认识到实验性的系统必须被构建和丢弃,具有变更思想的重新设计不可
避免。 3. 为变化设计系统,包括细致的模块化、可扩展的函数、精确完整的模块间接
口设计、完备的文档。另外,还可能会采用包括调用队列和表驱动技术。 最重要的措施是使用高级语言和自文档技术,以减少变更引起的错误。采用编译
时的操作来整合标准说明,在很大程度上帮助了变化的调整。 变更的阶段化是一种必要的技术。每个产品都应该有数字版本号,每个版本都应
该有自己的日程表和冻结日期。在此之后的变更属于下一个版本的范畴。 5. 程序维护中的一个基本问题是 -- 缺陷修复总会以(20%--50%)的机率引入新
的bug。整个过程是前进两步,后退一步。作为引入新bug的一个后果,程序每条
语句的维护需要的系统测试比其他编程要多,成本非常高。 首先,看上去很轻微的错误,似乎仅仅是局部操作上的失败,实际上却是系统级
别的问题。其次,维护人员通常不是编写代码的开发人员。 5. 使用能消除、至少是能指明副作用的程序设计方法,会在维护成本上有很大
的回报。设计实现的人员越少、接口越少,产生的错误也就越少。 6. 维护工作破坏系统的架构,增加了系统的混乱程度。随着时间的推移,系统
变得越来越无序,无法再成为下一步进展的基础。这时,系统的重新设计完全是
必要的。 系统软件开发是减少混乱度的过程,软件维护是提高混乱度的过程,即使是最熟
练的软件维护工作,也只是放缓了系统退化的进程。 |