这是最近看《人月神话》时中途记录的一些笔记,目前计划是1-8章写一篇,9-17章写一篇,剩余章节和后记一篇。这本书篇幅不长,内容主要是项目管理的相关经验,还算是比较轻度,可以放松点看。
由于中文版的封面并不好看,所以我选择了英文版的封面作为标题图
简介
- 人月神话这书,看名字像是奇幻小说吧,实际上却是计算机软件工程的经典著作
- 人月神话中的人月,指的是人力/月(Man-Mouth),是项目管理中的一大资源单位,这本书主要讨论的就是计算机软件工程中,项目管理的种种经验和问题对策
- 这本书首版出版于1975年,至今已45年,书中的很多观点和经验在现在看来都有些过时。但这毕竟不是一本技术书籍,主要内容是讲管理的,管理的经验可没有那么快过时
- 书中的一些过时的和我个人没有太大感觉的内容就没有记录在这里了,记录也和我之前的笔记一样,会比较杂乱。
- 这本书是由于我想要稍微了解下软件工程的内容,而这本书正是软件工程的入门书而看,我自己并没有本书所讨论的大型项目经验,因此也只能先把其中一些观点记住,并在日常小项目开发时拿来约束自己罢了
焦油坑
- 大型系统开发如同一个焦油坑,将人们困在其中,只有少数团队能爬出来
- 编程系统产品的演进如下图,体现了做出好产品需要什么
- 水平需要风格统一,接口合理
- 垂直需要是维护良好,稳定鲁棒
- 右下才是真正系统开发所需的东西,而最好的产品的工作量是普通程序A的9倍
- 编程是快乐的,这在于创造事物的快乐,开发给他人的快乐,组装零件的快乐,学习的快乐,在稳定易于驾驭的介质上工作从而可以凭空想象工作的快乐
- 编程是苦恼的,来自追求完美,来自依赖他人的目标资源和信息,苦恼于对他人的依赖,苦恼于概念性的设计的有趣可解决bug很无聊,来自于由于调试和差错的耗时是线性收敛的,最后一个错误要比第一个错误难找也难解决得多,还来自于若开发不够快程序就容易过时
- 缺乏合理进度安排的原因:
- 对估算方法缺乏有效的研究
- 隐含地假设了人月(人力/月)是可以互换的,从而将进度与工作量混淆了
- 对自己的估算缺乏信心
- 对进度缺乏跟踪和监督
- 意识到进度落后时第一反应是传统的方法即增加人力
- 编程人员总是乐观主义,总只假设了任务“应该花费的时间”,这是因为编程接近于纯粹的思维活动使我们过于信任自己的理性
- 但实际上我们的构思总是有缺陷的,问题的延迟是概率曲线,大型系统不遇到问题的几率接近于零
- 实际上人月并不是总能相互交换的,只有当任务可以分解为无需交流的独立任务时才可以交换。因此其中最重要的影响因素是是否可分解,不可分解的任务加人力无用,可分解但需沟通的任务加人力有些用,但随人力的增加效用不断减小甚至负反馈
- 这里面沟通的成本来自培训和交流,由于沟通会消耗负责沟通的人力,所以复杂的任务加人力可能反而有害
- 单元调试和系统测试是会产生巨大影响的部分
- 我们常常只给他安排过短的时间,实际上它应有一半以上的时间,由于这部分常常在最后才出现所以一旦安排不好就会成为灾难
- 当项目达不到里程碑时,一定要把握好增加人力还是减少任务的尺度,很多时候增加人力带来的培训成本,调配走的用来作为导师的工作人员,可能会使任务发生更加可怕的延期,所以一开始就要有一份足够精确的时间表确保进度的稳定
- 当延期成本非常高时,一定要果断对任务进行削减而非加人
- 项目的时间依赖于顺序的限制,而人员的数量依赖于可独立的子任务的数量
- 牢记Brooks法则:向进度落后的项目中增加人手只会使进度更加落后
外科手术队伍
- 好程序员与差程序员的生产率可能是10:1的差距
- 一拥而上的大队伍是高成本而低效的,但是小的高质量队伍对于大型系统来说又太慢了
- 为了保证效率和概念的完整性(下一节描述),最好将大型项目的每个部分拆给一个小团队解决,即【外科手术队伍】。一个人负责做主刀医生分解问题并实际编程(首席程序员),一个副手与首席交流并完成部分编辑,其他的一系列人员负责外围工作,服务于中心的外科医生
- 为了保证整个概念的完整性,要有一个系统架构师从上而下完成所有设计,使工作易于管理,同时要划清结构设计与具体实现的区别
贵族专制,民主政治和系统设计
- 系统设计中,概念的完整性应是最重要的因素,即程序应从头到尾思路一致代码近似
- 获得概念的完整性的目的:
- 程序的易用性是开发的目标
- 功能与理解上复杂程度的比值才是系统设计的最终测试标准
- 简洁来自概念的完整性,每个部分必须有一样的风格,用一样的技巧,相似的语义最终得到易用性
- 而获得概念完整性必须由一个人或非常少数有默契的人完成,这就是贵族专制与民主政治的冲突
- 架构师是用户的代言人,他需要陈述好需求,设计好完整的接口声明,然后由下级以外科手术法进行实现
- 因此架构师自然是贵族专制的,这是其所处位置和工作目的决定的。但是要清楚知道架构师的工作并不比具体实现更有创造性,因为这是两个不同的创造过程
- 底层的实现很大程度上决定了产品的成本,架构师的设计则是很大程度决定了产品的易用性
- 过高的预算,过大的自由度反而会由于太大的想法的争议使得结果实现较少,这在历史上很常见
- 为了概念的完整性,最好在项目设计完成后再准备实现团队,好的设计会事半功倍
- 但是有时项目对时间要求很紧,所以现实中最好还是让体系设计,具体实现,物理实现并行执行,设计从宽到紧深入,实现者也从宽到紧一步步进行工作
- 如果像这样进行的垂直划分会大大减少了劳动量又保证了实现对外的产品来自于少数人的相符从而易用而实用
画蛇添足
- 架构师越早与实现人员沟通越好,能使开发者有信心并更好地分工
- 估算成本过高时,可以削减设计或使用更低成本的实现方法。其中使用更低成本的实现方法风险比较大,要时刻准备好被开发人员拒绝的计划
- 当开发人员对架构师的某些体系设计提出质疑时,好好思考,很可能说得对
- 画蛇添足指的是对生涯第二个系统的设计,第二个系统是最危险的系统,很可能会由于之前的经验和未来的野心造成过度设计
- 过度设计可能使基本系统的设想都出现变化,漫长的开发还会使有些技术会显得落后
- 因此要运用特别的自我约束功能,让自己避免过度修饰,例如设定每个小功能的限定成本充当所有人的警示
- 最好有有经验的架构师来帮忙度过这个阶段
贯彻执行
- 手册是产品的外部规格说明,描述了用户所见的每个细节,是架构师的主要工作产物,是贯彻执行架构师思路的关键
- 手册的修改需要有详细的版本记录,避免描述用户看不到的东西,那些是实现人员的范畴
- 手册在规定该做什么时,也要描述好哪些是未定义的,且避免二义性
- 手册要标记好正确的输入和输出,进行约束
- 小组应有周例会和年度大会来决定开发的设计:其中周例会每周举行半天,所有设计人员需要参加,首席架构师主持,任何人都可以提出意见和问题,然后决定问题,达成共识,无法达成共识的地方由首席架构师拍板;年度大会则持续两周,六个月一次,解决周会搁置堆积的问题
- 当某功能存在多个实现版本时,应按照手册预计的开销要求决定去留
- 实现人员有疑问时应直接问架构人员,且讨论的结果也应记录为日志以供后人参考
- 要有作为用户的代理人的产品测试小组,专门寻找缺陷和与手册不同的地方
为什么巴比伦塔会失败
- 团队间的交流和组织是项目成功的前提,这也是巴比伦塔失败的根本原因
- 可以使用项目工作手册帮忙文档设计,他不是文档而是对项目应产生的文档的一种结构,控制确保信息流向需要的人手中
- 由于编程人员在仅了解自己负责的部分时工作效率最高,所以这方法的先决条件是在一开始就精确完整地定义了所有接口,编程人员才能按照手册进行实现
- 交流过多会降低效率,减少交流频次的方法是划分人力和限定职责范围,可以考虑树状编程队伍来解决人力划分问题
- 树状组织需要让每个子树有各自的任务,产品负责人,技术主管/架构师,进度,人力划分,接口定义
- 组织中最重要的是产品负责人和技术主管。产品负责人负责向外交流,市场营销,人员分配之类;技术主管负责系统技术上的架构思考和分配
- 小项目中产品负责人和技术主管可以是一个人,至少产品负责人和技术主管需要有相似的观点,产品负责人需要对技术主管表现出足够的尊重,因为终究实现才是根源
- 有技术主管为主的组织也有产品负责人为主的组织,但在大项目中比较常见的是技术主管作为幕后总指挥,产品负责人作为辅助但是在台面前
胸有成竹
- 工作量=常数*指令数^1.5
- 由于实际中的进度常常是理想进度的1/2,所以估算进度时要留有很多余地
- 随着人员工作时间的增长工作效率会有所提高,但那时候也临近尾声
- 本章由于过时很多编配工作量的经验于今日没有太大意义了