人月神话📒

这本书问世了40年,内容经久而不衰。其中的银弹、人月等概念和思考早已潜移默化间成为当今社会常识。
专门学习和记录一下

第1章 焦油坑

  1. 编程系列产品(programming systems product)开发的工作量是供个人使用的独立开发的构建程序的9倍。我估计,软件构建产品化引起了3倍的工作量,将软件构建整合成完整系统所需要的设计、集成和测试又强加了3倍的工作量。这些高成本的构建,在根本上是相互独立的。
  2. 编程行业满足我们内心深处的创造渴望和愉悦所有人的共享情感,其提供了5种乐趣:
    • 创造事物的快乐
    • 开发对其它人有用的东西的乐趣
    • 将可以活动相互啮合的零部件,组成类似迷宫的东西,这个过程所体现出令人神魂颠倒的魅力
    • 面对不重复的任务,不断学习的乐趣
    • 工作在如此易于驾驭的介质上的乐趣——纯粹的思维活动——其存在移动和运转方式完全不同于实际物体
  3. 同样,这个行业具有一些内在固有的苦恼:
    • 将做事方式调整到追求完美是学习编程的最困难部分
    • 由其它人来设定目标,并且必须依靠自己无法控制的事物(特别是程序);权威不等同于责任
    • 实际情况看起来要比这一点好一些;真正的权威来自于每次任务的完成
    • 任何创造性活动都伴随着枯燥艰巨的劳动,编程也不例外
    • 人们通常期望项目在接近结束时,软件项目能收敛的快一些,然而情况却是越接近完成,收敛的越慢
    • 产品在完成前总面临着陈旧过时的威胁,只有实际需要时,才会用到最新的设想

第2章 人月神话

  1. 缺乏合理的时间进度,是造成项目滞后的最主要原因,它比其它所有因素的总和影响还大
  2. 良好的烹饪需要时间,某些任务无法在不损害结果的情况下加快速度
  3. 所有的编程人员都是乐观主义者,“一切都将运作良好”
  4. 由于编程人员通过纯粹的思维活动来开发,我们期待在实践过程中不会碰到困难
  5. 但是我们的构思本身有缺陷的,因此总会有bug
  6. 围绕着成本核算的估计技术,混淆了工作量和项目进展。人月是危险和带有欺骗性的神话,因为它暗示人员数量和时间是可以相互替换的。
  7. 在若干人员中分解任务会引发额外的沟通工作量——培训和相互沟通
  8. 关于进度安排,我的经验是1/3计划,1/6编码,1/4构建测试以及1/4系统测试
  9. 作为一门学科,我们缺乏数据估计
  10. 我们对自己的估计技术不确定。因此,在管理和客户的压力下,我们常常缺乏坚持的勇气
  11. Brooks法则:为进度落后的项目增加人数,只会使进度更加落后
  12. 向软件项目中增派人手,从三个方面增加了项目必要的总体工作量:
    • 任务重新分配本身和所造成的工作中断
    • 培训新人员
    • 额外的相互沟通

第3章 外科手术队伍

  1. 同样有两年经验,而且在受到同样培训的情况下,优秀的专业程序员的生产率是较差的程序员的十倍(Sackman、Ericson和Grant)
  2. Sackman、Ericson和Grant的数据显示,经验和实际表现之间没有相互联系。我怀疑这种现象是否普遍成立
  3. 小型精干的队伍是最好的——思绪尽可能少
  4. 两个人的团队,其中一个是领导者,常常是最佳的人员使用方法
  5. 对于真正意义上的大型系统,小型精干的队伍太慢了
  6. 实际上,绝大多数大型编程系统的经验显示,一拥而上的开发方法是高成本、速度缓慢、低效的,开发出的产品无法进行概念上的集成
  7. 一位首席程序员,类似于外科手术队伍中的团队架构提供了一种方法——既能获得由少数头脑产生的产品完整性,又能得到多位协助人员的总体生产率,还彻底的减少了沟通的工作量

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

  1. “概念完整显示系统设计中最重要的考虑因素”
  2. “功能和理与理解上的复杂程度的比值,才是系统设计的最终测试标准”,而不仅仅是丰富的功能。(该比值是对易用性的一种测量,由简单和复杂应用共同验证)
  3. 为了获得概念完整性,设计必须由一个人或者具有共识的小型团队来完成
  4. “对于非常大型的项目,将体系结构方面的工作与具体实现相分离,是获得概念完整性的强有力方法”,(其同样适用于小型项目)
  5. 如果要得到系统概念上的完整性,必须有人控制这些概念,这实际上是一种无需任何歉意的贵族专制统治
  6. 纪律规则对行业是有益的,外部的体系结构规定实际上是增强,而不是限制实现小组的创造性
  7. 概念上统一的系统能更快的开发和测试
  8. 体系结构(architecture)、设计实现(implementation),物理实现(realization)的许多工作可以并行(软件和硬件设计同样可以并行)

第5章 画蛇添足

  1. 尽早交流和持续沟通能使架构设计师、结构师有较良好的成本意识,使开发人员获得对设计的信心,并且不会混淆各自的责任分工
  2. 结构师如何成功的影响实现
    1. 牢记是开发人员承担创造性的实现责任,结构师只能提出建议
    2. 时刻准备着为所指定的说明建议,一种实现的方法,准备接受任何其它可行的方法
    3. 对上述建议保持低调和平静
    4. 准备对所建议的改进放弃
    5. 坚持听取开发人员在结构体系结构上改进的建议
  3. 第二个系统是人们所设计的最危险的系统,通常的倾向是过分的进行设计
  4. OS/360是典型的画蛇添足的例子(windows NT似乎是20世纪90年代的例子)
  5. 为功能分配一个字节和微秒的优先权值是一个很有价值的规范化方法

第6章 贯彻执行

  1. 即使是大型的设计团队,设计结果也必须由一个或两个人来完成,以确保这些决定是一致的
  2. 必须明确定义体系结构中与原先定义不同的地方,重新定义的详细程度应与原先的说明一致
  3. 出于精确性的考虑,我们需要形式化的设计定义,同样我们需要继续性定义来加深理解
  4. 必须采用形式化定义和记叙性定义中的一种作为标准,另一种作为辅助措施,它们都可以作为表达的标准
  5. 设计实现,包括模拟仿真,可以充当一种体系结构的定义。这种方法有一些严重的缺点
  6. 直接整合是一种强制推行软件的结构性标准的方法(硬件上也是如此——考虑内建在ROM内的MAC WIMP接口)
  7. 如果起初至少有两种以上的实现,(体系结构)定义会更加整洁和规范
  8. 允许体系结构师对实现人员的询问做出电话应答,解释是非常重要的,而且必须进行日志记录和整理发布(电子邮件是现在可选的介质)
  9. “项目经理,最好的朋友就是它每天要面对的对手,独立的产品测试机构或小组”

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

  1. 巴比伦塔项目的失败,是因为缺乏交流以及交流的结果——组织交流
  2. “因为左手不知道右手在做什么,从而进入灾难、功能的不合理和系统缺陷纷纷出现”。由于存在对其它人的各种假设,团队成员之间的理解开始出现偏差
  3. 团队应该以尽可能多的方式进行相互之间的交流:非正式的进行简要技术陈述的常规项目会议,共享的正式项目工作手册[以及通过电子邮件]项目工作手册
  4. 项目工作手册“不是独立的一篇文档,它是对项目必须产生的一系列文档进行组织的一种结构”
  5. “项目所有的文档都必须是该[工作手册]结构的一部分”
  6. 需要尽早和仔细的设计工作手册结构
  7. 事先制定良好结构的工作手册,可以将后来书写的文字放置在合适的章节中,并且可以提高产品手册的质量
  8. 每一个团队成员应该了解所有的材料(工作手册)(每个团队成员应该能够看到所有的材料网页即可满足要求)
  9. 实时更新是至关重要的
  10. 工作手册的使用者应该将注意力集中在上次阅读后的变更,以及关于这些变更重要性的评述上
  11. OS/360项目工作手册开始采用的是纸介质,后来换成了微缩胶片
  12. 今天(即使在1975年),共享的电子手册是能达到所有这些目标的更好的、更加廉价的、更加简单的机制。
  13. 仍然需要用变更条和修订日期[或具备同等功能的方法]来标记文字,仍然需要先进后出后进先出(LIFO)的电子化变更小结
  14. Parnas强烈的认为是每个人看到的每件事的目标是完全错误的;各个部分应该被封装,从而没有人需要或者允许看到其它部分的内部结构,只需要了解接口
  15. Parnas的建议的确是灾难的处方

组织架构

  1. 团队组织的目标是为了减少必要的交流和协作量。
  2. 为了减少交流,组织架构,包括了人力划分(division of labor)和限定职责范围(specialization of function)
  3. 传统的树状组织结构反映了权力的结构原理——不允许双重领导
  4. 组织中的交流是网状,而不是树状结构。因此,所有的特殊组织机制(往往体现为组织结构图中的虚线部分)都是为了进行调整,以克服树状组织结构中交流缺乏的困难
  5. 每个子项目就有两个领导角色——产品负责人、技术主管或结构师。这两个角色的职能有很大的区别,需要不同的技能
  6. 两种角色的任意组合都可以是非常有效的
    • 产品负责人和技术主管是同一个人
    • 产品负责人作为一种指挥技术主管,充当其左右手
    • 技术主管从作为总指挥,产品负责人充当其左右手

第8章 胸有成竹

  1. 仅仅通过对编码部分时间的估计,然后乘以其它部分的相对系数,是无法得出对整项工作的精确估计的
  2. 构建独立小型程序的数据不适用于编程系统项目
  3. 程序开发随程序规模的大量增长而增长
  4. 一些发表的研究报告表示,指数约为1.5。(Boehm的数据并不完全一致,在1.05和1.2之间变化。)
  5. Portman的ICL数据显示,相对于其它活动,全职程序员仅将50%的时间用于编程和调试
  6. Aron IBM的数据显示,生产率是系统各个部分交互库的函数,在1.5千代码行/人-年至10千代码行/人-年的范围内变化。
  7. Harr的贝尔实验室数据显示,对于已完成的产品,操作系统内的生产率大约是0.6千LOC/人-年,编译类工作的生产率大约为2.2千LOC/人-年
  8. Brooks的OS/360数据与Harr的数据一致,操作系统0.6~0.8千LOC/人-年,编译器2~3千LOC/人-年
  9. Corbato的MIT项目MULTICS数据显示,在操作系统和编译器混合类型上的生产率是1.2千LOC/人-年,但这些是PL/I的代码行,而其它所有的数据是汇编代码行
  10. 在基本语句级别,生产率看上去是一个常数
  11. 当使用适当的高级语言时,编程程序编制的生产率可以提高5倍

第9章 削足适履

  1. 除了运行时间以外,程序所占据的内存空间也是主要开销。特别是对于操作系统,它的很多程序是永久驻留在内存中的
  2. 即使如此,花费在驻留程序所占据的内存上的金钱仍是物有所值的,比其它任何在配置上的投资的效果都要好。规模本身不是坏事,但不必要的规模是不可取的
  3. 软件开发人员必须设立规模目标,控制规模,发明一些减少规模的方法,就如同硬件开发人员为减少元器件所做的事情一样
  4. 规模预算不仅仅在占据内存方面是明确的,同时还应该指明程序对硬盘的访问次数。
  5. 规模预算必须与分配的功能相关联,在指明规模化块大小的同时,确切定义模块的功能
  6. 在大型项目中,各个小组倾向于不断的局部优化,以满足自己的目标,而较少考虑对用户的整体影响。这种方向性的问题是大型项目的主要危险
  7. 在整个实现的过程期间,结构系统结构是必须保持持续的警觉,确保系统的系统连贯的系统完整性。
  8. 从系统整体出发以及面向用户的态度是,原软件编程管理人员最重要的职能
  9. 在早期应该制定策略,以决定用户可选项目的粗细程度,因为将它们作为整体打包,能够节省内存空间,常常还可以节约市场成本
  10. 暂存区空间的尺寸以及每次访问磁盘的程序数量是很关键的决策。因为性能是规模的非线性函数(这个整体决策已显得过时。起初是由于虚拟内存,后来则是成本低廉的内存,现在的用户通常会购买能容纳主要应用程序所有代码的内存)
  11. 为了取得良好的空间—时间折衷,开发队伍需要得到特定的某种语言或者机型的编程技能培训,特别是在使用新语言或者新机型机器时
  12. 编程需要技术积累,每个项目需要自己的标准组件库
  13. 精炼、充分和快速的程序往往是战略性突破的结果,而不仅仅是技巧上的提高。这种突破常常是一种新型算法
  14. 更普遍的是,战略上的突破常来自于对数据或表的重新表达。数据的表现形式是编程的根本

第10章 提纲擎领

  1. “前提:在一篇文件的汪洋中,少数文档成为了关键的枢纽。每个项目管理的工作都围绕着它们运转,它是经历人们的主要个人工具”
  2. 对于计算机硬件开发项目,关键文档是目标、手册、进度、预算、组织机构图、空间分配以及机器本身的报价、预测和价格
  3. 对于大学科系,关键文档类似于目标、课程描述、学位要求、研究报告、课程表和课程的安排预算教师分配、教师和研究生助手的分配
  4. 对于软件项目,要求是相同的:目标、用户手册、内部文档、进度预算、组织机构图和空间,工作空间分配
  5. 因此,即使是小型项目,项目经理也应该在项目早期对上述的一系列文档进行规范化
  6. 在以上集合中,每一个文档的准备工作都将注意力集中在思索和对讨论的提炼上,而书写这项活动需要上百次的细小决定。正是由于它们的存在,人们才能从令人迷惑的现象中得到清晰、确定的策略
  7. 对每个关键文档的维护提供了状态监督和预警机制
  8. 每个文档本身就可以作为检查列表或者数据库
  9. 项目经理的基本职责是使每个人都向着相同的方向前进
  10. 项目经理的主要日常工作是沟通,而不是做出决定;文档使各项计划和决策在整个团队范围内得到交流。
  11. 只有一小部分管理人员的时间——可能只有20%——用来从自己头脑外部获取信息的
  12. 出于这个原因,广受吹捧的市场概念——支持管理人员的完全信息管理系统”,并不基于反映管理人员行为的有效模型

第11章 未雨绸缪

  1. 化学工程师已经认识到,无法一步将实验室工作台上的反应过程移到工厂中去,需要一个是实验性工厂(pilot plant)来为提高产量和在缺乏保护的环境下运作提供宝贵经验
  2. 对于编程产品而言,这样的中间步骤同样是必要的。但是软件工程师在着手发布产品之前,却并不会常规的进行试验性的系统的现场测试(现在这已经成为了一项普遍的实践,beta版本不同于有限功能的原型,alpha版本同样是所倡导的实践。)
  3. 第一个开发的系统对于大多数项目并不合用,它可能太慢、太大,而且难以使用,或者三者兼而有之
  4. 系统的丢弃和重新设计可以一步完成,也可以一块一块的实现,但这是必须完成的步骤
  5. 将开发的第一个系统——丢弃原型——发布给客户,用户可以获得时间,但是它的代价高昂——对于用户使用极其痛苦;对于重新开发的人员分散了精力;对于产品,影响了声誉,即使最好的再设计也难以挽回名声
  6. 因此,为舍弃而计划,无论如何,你一定要这样做
  7. “开发人员交付的是用户满意程度,而不仅仅是实际的产品(Cosgrove)”
  8. 用户的实际需要和用户感觉会随着程序的构建,测试和使用而变化
  9. 软件产品易于掌握的特性和不可见性,导致它的构建人员(特别容易)面临着永恒的需求变更
  10. 目标上(和开发策略上)的一些正常变化无可避免,事先为它们做准备,总比假设它们不会出现要好得多
  11. 为变更而计划软件产品的技术,特别是拥有细致的模块接口文档的结构化编程广为人知,但并没有相同规模的实践,尽可能的使用表驱动技术同样是有所帮助的(现在内存的成本和规模使这项技术越来越出众)
  12. 高级语言的使用、编译时操作、通过引用的声明整合和自文档技术,能减少变更引起的错误
  13. 采用定义良好的数字化版本,将变更量子(阶段)化(当今的标准实践)为变更计划组织架构
  14. 程序员不愿意为设计书写文档,不仅仅是因为惰性,更多的是源于设计人员的踌躇——要为自己尝试性的设计决策进行辩解(Cosgrove)
  15. 为变更团组建团队比为变更进行设计更加困难
  16. 只要管理人员和技术人才的天赋允许,老板必须对他们的能力培养给予巨大的关注,使管理人员和技术人才具有互换性,特别是希望在技术和管理角色之间自由的分配人手的时候
  17. 具有两条晋升线的高效组织机构存在着一些社会性的障碍,人们必须警惕并积极的同它做持续的斗争
  18. 很容易为不同的晋升线建立相互一致的薪水级别。但同等威信的建立需要一些强烈的心理措施:相同的办公室、一样的技术以及技术调动的优先补偿
  19. 组建外科手术队伍式的软件开发团队,是对上述问题所有方面的彻底冲击。对于灵活组织架构问题,这的确是一个长期行之有效的解决方案

前进两步,后退一步——程序维护

  1. 程序维护基本上不同于硬件的维护,它主要由各种变更组成。如修复设计缺陷,新增功能,或者是使用环境或配置变化引起的调整。
  2. 对于一个广泛使用的程序,其维护成本通常是开发成本的40%或者更多
  3. 维护成本受用户数目的影响,用户越多,所发现的错误也越多
  4. Campbell指出了一个显示产品生命周期中每月bug数的有趣曲线,其先是下降,然后上升
  5. 缺陷修复总会有20%到50%的几率引入新的bug
  6. 每次修复之后,必须重新运行先前的所有测试用例,确保系统不会以更隐蔽的方式被破坏
  7. 能消除至少是能指明副作用的程序设计方法,对维护成本有很大的影响
  8. 同样实现设计的人员越少,接口越少,产生的错误也就越少

前进一步,后退一步——系统熵随时间增加

  1. Lehman和Belady,发现模块数量处于大型操作系统(OS/360)版本号增加呈线性增长。但是模块随版本号指数的增长而受到影响
  2. 所有的修改都倾向于破坏系统的架构,增加了系统的混乱程度(熵)。即使是最熟练的软件维护操作,也只是延缓了系统退化到不可修复的混乱状态的进程,以致必须要重新进行设计(许多程序升级的真正需要,如性能等,尤其会冲击它的内部结构边界。原有边界引发的不足常常在日后才会出现。)

第12章 干将莫邪

  1. 项目经理应该制定一套策略,并为通用工具的开发分配资源。与此同时,他还必须意识到专业工具的需求
  2. 开发操作系统的队伍需要自己的目标机器进行调试开发工作。相对于最快的速度而言,它更需要最大限度的内存,还需要安排一名系统程序员,以保证机器上的标准软件是及时更新和实时可用的
  3. 同时还需要配置调试机器或者软件,以便在调试过程中所有类型的程序参数可以被自动计数和测量
  4. 目标机器的使用需求是一种特殊曲线,刚开始使用率非常低,突然出现爆发式的增长,接着趋于平缓
  5. 同天文工作者一样,大部分系统调试工作总是在夜间完成
  6. 抛开理论不谈,一次分配给某个小组的连续的目标时间块被证明是最好的的安排方法,比起不同小组的穿插使用更为有效
  7. 尽管技术不断变化,这种采用时间块来安排匮乏,计算机资源的方式仍能够延续20年。在1975年,这是因为它的生产率最高。在1995年依然如此
  8. 如果目标机器是新产品,就需要一个目标机器的逻辑仿真装置,这样可以更快的得到辅助调试平台。即使在真正机器出现之后,仿真装置仍可提供可靠的调试平台
  9. 主程序库应该被划分成:
    • 一系列独立的私有开发库
    • 正处在系统测试下的系统集成子库
    • 发布版本

    正式的分离和进度提供了控制

  10. 在编制程序的项目中,节省最大工作量的工具可能是文本编辑系统
  11. 系统文档中的巨大容量产生了新的不易理解问题[例如,看看unix],但是它比大多数未能详细描述编程系统特性的短小文章更加可取
  12. 自上而下、彻底的开发一个性能仿真装置。尽早的开始这项工作,仔细的听取“它们表达的意见”

高级语言

  1. 只有懒散和惰性会妨碍高级语言和交互式编程的广泛应用(如今,它们已经在全世界使用)
  2. 高级语言不仅提高了生产率,还改进了调试:bug更少,而且更容易寻找
  3. 传统的反对意见——功能,目标代码的尺寸,目标代码的速度,随着语言和编译器技术的进步,已不再成为问题

交互式编程

  1. 某些应用上,批处理系统绝不会被交互式系统所替代
  2. 调试是系统编程中较慢和较困难的部分,而漫长的调试周转时间是调试的祸根
  3. 有限的数据表明,系统软件开发中,交互式编程的生产率至少是原来的两倍

第13章 整体部分

  1. 第4、5、6章所意味的煞费苦心详尽体系结构工作不但使产品更加易于使用,而且使开发更容易进行运行,且bug更不容易产生
  2. Vyssotsky提出:“许许多多的失败,完全源于那些产品未精确定义的地方”
  3. 在编写任何代码之前,规格说明必须提交给外部测试小组,以详细的检查说明的完整性和明确性。开发人员自己无法完成这项工作(Vyssotsky)
  4. “10年内(1965到1975年),Wirth自上而下的进行设计(逐步细化)将会是最重要的新型形式化软件开发的方法”
  5. Wirth主张在每个步骤中都尽可能的使用级别较高的表达方法
  6. 好的自上而下的设计从四个方面避免了bug
    • 清晰的结构和表达方式更容易对需求和模块功能进行精确的描述
    • 模块分割和模块独立性避免了系统级的bug
    • 细节的抑制使结构上的缺陷更加容易识别
    • 设计在每个精化步骤上都是可以调试的,所以测试可以尽早开始,并且每个步骤的重点可以放在合适的级别上
  7. 有时必须回退,推翻顶层设计,重新开始
  8. 结构化编程中程序的控制结构仅由支配代码块(相对于任意的跳转)的给定集合所组成。这种方法很好的避免了bug,是一种正确的思考方式
  9. Gold的实验结果显示,在交互式调试过程中,第一次交互取得的工作进展是后续交互的三倍,这实际上获益于在调试开始之前仔细的调试计划
  10. 我发现对良好的交互式调试做出快速反应系统的正确使用,往往要求每两个小时的终端会话对应于两个小时的桌面工作:1小时会话后的清理和文档工作,1小时为下一次变更计划、变更和测试
  11. 系统调试(相对于单元测试)所发挥的时间会比预料的更长
  12. 系统调试的困难程度证明了需要一种完备系统化和可视化的方法
  13. 系统调试仅仅应该在所有部件能够运作之后开始(这既不同于为了查出接口bug所采取的“合在一起尝试”的方法,也不同于在所有构建单元的bug已知但未修复的情况下,即开始系统调试的做法。对于多个团队尤其如此)
  14. 开发大量的辅助调试平台和测试代码是很值得的,代码量甚至可能有测试对象的一半
  15. 必须有人对变更和版本进行控制和文档化,团队成员应该使用开发库的各种受控拷贝来工作
  16. 系统测试期间,一次只添加一个构件
  17. Lehman和Belady出示了证据,变更的阶段(量子)要么很大,间隔很宽,要么小而频繁,后者很容易变得不稳定[Microsoft的一个团队使用了非常小而频繁的阶段(量子)。结果每天晚上都需要重新编译生成增长中的系统]

第14章 祸起萧墙

  1. “项目是怎样被延迟了整整一年时间的······一次一天”
  2. 一天一天的进度落后,比起重大灾难更难以识别,更不容易防范和更加难以弥补
  3. 根据一个严格的进度表来控制大型项目的第一个步骤是制定进度表,进度表由里程碑和日期组成
  4. 里程碑必须是具体的、特定的和可度量的事件,能进行清晰的定义
  5. 如果里程碑定义的非常明确,以至于无法自欺欺人时,程序员很少会就里程碑的进展弄虚作假
  6. 对于大型开发项目中的估计行为,政府的承包商所做的研究显示:每两周进行仔细修订的活动时间估计,随着开始时间的临近不会有太大的变化;期间内对时间长短的过高估计会随活动的进行持续下降;过低估计直到计划的结束日期之前大约三周左右,才会有所变化
  7. 慢性进度偏离是士气杀手[Microsoft的Jim McCarthy说,如果你错过了一个最终极限(deadline),确保完成下一条最终极限]
  8. 同优秀的棒球队伍一样,进取对于杰出的软件开发团队是不可缺少的必要品德
    进取提供了缓冲和储备,使开发队伍能够处理常规的灾祸,可以预计和防止小的灾祸。而对任务进行计算和对工作量进行度量,会对进度超前造成一些消极的影响
  9. 不存在关键路径进度的替代品,使人们能够辨别计划偏移的情况
  10. PERT的准备工作是PERT图使用中最有价值的部分。它包含了整个网状结构的展开、任务之间依赖关系的识别和各个任务链的估计。估计这些都要求在项目早期进行非常专业的计划
  11. 第一份PERT图总是很恐怖,不过人们总是不断努力,运用才智来制定下一份PERT图
  12. PERT图为使那个使人泄气的借口——“其他的部分反正会落后”,提供了答案
  13. 每个老板同事需要采取行动的异常信息以及用来进行分析和早期预警的状态数据
  14. 状态的获取是困难的,因为下属经理有充分的理由不提供信息共享
  15. 有两种掀开毯子把污垢展现在老板面前的方法,它们必须都被采用:
    • 减少角色冲突和鼓励状态共享
    • 猛地拉开地毯
  16. 老板的不良反应肯定会对信息的完全公开造成压制;相反,仔细区分状态报告、毫无惊慌的接收报告、绝不越俎代庖,能够鼓励诚实的汇报
  17. 必须有评审机制,使所有成员可以通过它了解真正的状态。出于这个目的,里程碑的进度和完成文档是关键
  18. Vyssotosky:“我发现在里程碑报告中很容易记录‘计划(老板的日期)’和‘估计(最基层经理的日期)’的日期。项目经理必须停止对估计日期的怀疑”
  19. 对于大型项目,一个对里程碑报告进行维护的计划和控制小组是非常可贵的。
    对计划和控制职能进行适度的技术人力投资是非常值得赞赏的。它在项目的贡献方式和直接开发软件产品方面差异较大。计划和控制小组作为监督人员,明白的指出了不易察觉的延迟,并强调关键的因素。他们是早期的预警系统,防止项目以一次一天的方式落后一年

第15章 另外一面

  1. 对于软件编程产品来说,程序向用户所呈现的面貌——文档,与提供给机器识别的内容同样重要
  2. 即使是完全开发给自己使用的程序,描述性文字也是必须的,因为它们会被用户-作者所遗忘
  3. 培训和管理人员基本上没有向编程人员成功的灌输对待文档的基本积极态度——文档能在整个生命周期对克服懒惰和轻度的压力起促进和激励作用
  4. 这样的失败并不都是因为缺乏热情或者说服力,而是没能正确的展示如何有效和经济的编制文档
  5. 大多数文档只提供了很少的总结性内容,必须放慢脚步,稳妥的进行
  6. 由于关键的用户文档包含了与软件相关的基本决策,因此它的绝大多部分需要在软程序编制之前书写。它包括了9项内容
    • 目的
      主要的功能是什么?开发程序的原因是什么?
    • 环境
      程序运行在什么样的机器、硬件配置和操作系统上?
    • 范围输入的有效范围是什么?允许现实的合法输出范围是什么?
    • 实现功能和使用的算法
      精确的阐述它做了什么
    • “输入—输出”格式
      必须是确切完整的
    • 操作指令
      包括控制台及输出内容中正常和异常结束的行为
    • 选项
      用户的功能选项有哪些?如何在选项之间进行挑选?
    • 运行时间
      在指定的配置下,解决特定规模问题所需要的时间?
    • 精度和校验
      期望结果的精确程度?如何进行精度的检测?
  7. 每一份发布的程序拷贝应该包括一些测试用例,其中一部分用于校验输入数据,一部分用于边界输入数据,另一部分用于无效的输入数据
  8. 对于必须修改程序的人而言,它们需要程序内部结构文档,同样要求一份清晰明了的概述。它包括了5项内容:
    • 流程图或子系统的结构图
    • 对所用算法的完整描述,或者是类似算法的参考资料
    • 对所有文件规划的解释
    • 数据流处理的概要描述——从磁盘中获取数据或程序处理的序列——以及在每个处理过程中完成的操作
    • 初始设计中,对已预见修改的讨论:特性、功能回调以及出口的位置;原作者对可能会修改的地方以及可能处理方案的一些意见。另外,对隐藏缺陷的观察也同样很有价值
  9. 流程图是被吹捧的最过分的一种程序文档,详细逐一记录的流程图是一件令人生厌的事情,而且高级语言的出现,使它显得你的陈旧过时(流程图是图形化的高级语言)
  10. 如果这样,很少有程序需要一页纸以上的流程图
  11. 即使的确需要一张程序结构图,也并不需要遵守ANSI的流程图标准
  12. 为了使文档易于维护,将它们合并至源程序是至关重要的,而不是作为独立文档进行保存
  13. 最小化文档担负的三个关键思路:
    • 借助那些必须存在的语句,如声明和名称等,来附加尽可能多的文档信息
    • 使用空格和格式来表现从属和嵌套关系,提高程序的可读性
    • 以段落注释,特别是模块标题的形式,向程序中插入必要的继续性文字
  14. 程序修改人员所使用的文档中,除了描述事情如何,还应阐述它为什么那样。对于加深理解,目的是非常关键的。即使是高级语言的语法,也不能表达目的
  15. 在线系统的高级语言(应该使用的工具)中,自文档化技术发现了它的绝佳应用和强大功能

第一版结束语

  1. 软件系统可能是人类创造中最复杂、错综复杂的事物(从不同类型组成部分数量的角度出发)
  2. 软件工程的焦油坑在将来很长一段时间仍然会使人们举步维艰,无法自拔

发表回复

您的电子邮箱地址不会被公开。