人月神话-学习记录
由于人员的分工,大型编程项目碰到的管理问题和小项目区别很大;关键需要是维持产品自身的概念完整性。
焦油坑(The Tar Pit)
大型软件的开发就像是在焦油坑里挣扎,表面上看起来单独的问题都很简单,但是纠缠在一起时会导致团队迟缓,看不清问题的本质。
- 程序:完整的,可以在所开发的系统平台上运行。它通常是车库中产出的产品,以及作为单个程序员生产率的评估标准
- 编程产品(Programming Product)。这是可以被任何人运行、测试、修复和扩展的程序。它可以运行在多种操作系统平台上,供多套数据使用。
要成为这样的产品,必须按照普遍认可的方式编写,经过彻底的测试(保证稳定可靠)还要配备完备的文档。 - 编程系统(Programming System)中的一个构件单元。它是在功能上能相互协作的程序集合,具有规范的格式,可以进行交互,并可以用来组装和搭建整个系统。
程序需要按要求编制(接口一致)、符合预先设定的资源限制(内存,IO,时间)、经过组合测试。 - 编程系统产品(Programming Systems Product)真正可用的产品,=编程产品+编程系统。成本约为程序的9倍(3*3)
人月神话(The Mythical Man-Month)
缺乏合理的时间进度是项目滞后的主要原因。
- 对估算技术缺乏有效的研究。
- 错误将进度与工作量混淆。(有的部分简单,有的需要攻坚)
- 对估算本身缺乏信心。(软件经理会不耐烦)
- 对进度缺少跟踪和监督。(软工不像其他的工程,其他的比较看重监督)
- 当进度偏移时,下意识的反应是增加人力,但这可能会引起管理混乱,导致结果更加糟糕。
乐观主义
第一中思维谬误是乐观主义:系统编程的进度安排背后的第一个假设是:一切都将运作良好,每一项任务仅花
费它所“应该”花费的时间。
程序员总带有乐观病,总是坚信这次能行,即使刚刚改完10个bug。另外编程本质上是纯思维活动,不受物理规则的限制,这种灵活性也让程序员们容易低估困难。
人月
第二章思维谬误就是:人-月,即人们往往认为投入人力与项目时间是可以替换的。
很多管理者认为 “1 个人 12 个月完成的项目,派 12 个人 1 个月就能搞定”,但这是错的:
- 新增成员需要培训(比如熟悉代码框架),老员工要花时间带新人,反而挤占开发时间;
- 团队沟通成本呈指数级增长:3 个人需要 3 次沟通,4 个人需要 6 次沟通,10 个人则需要 45 次沟通,效率反而降低。
就像包饺子时,1 个人擀皮 1 小时能包 100 个,但若硬塞 10 个人,可能因为场地拥挤、分工混乱,1 小时反而包得更少
人数和时间的互换仅仅适用于以下情况:某个任务可以分解给参与人员,并且他们之间不需要相互的交流。(但是这样在编程系统中几乎不可能。)
而当次序上不可分割时,增加人手根本没用。(无论有多少个母亲,孕育一个生命都要10个月,书里原版的举例)
对于可分解的任务,也必须在计划中考虑沟通的工作量,因此,相同人月的前提下,采用增加人手来减少时间得到的最好情况,也比未调整前要差一些。(可以看到与第一个图对比,人数越多,曲线比图一越上扬。)
如果任务的每个部分必须分别和其他部分单独协作,则工作量按照 n(n-1)/2 递增。一对一交流的情况下,三个人的工作量是两个人的三倍,四个人则是两个人的六倍。而对于需要在三四个人之间召开会议、进行协商、一同解决的问题,情况会更加恶劣。
系统测试
在时间/次序限制上,没有那个部分比单元调试与系统测试所受到的牵扯更加彻底。测试时理论上bug肯定是零,但是这是由于我们的“乐观主义”,实际上肯定多的多,所以系统测试往往是最不合理的部分。
建议:三分之一计划,六分之一编码,四分之一构件测试和早期系统测试,四分之一系统测试。
- 分配给计划的时间比寻常的多。即便如此,仍不足以产生详细和稳定的计划规格说明,也不足以容纳对全新技术的研究和摸索。
- 对所完成代码的调试和测试,投入近一半的时间,比平常的安排多很多。(因为许多项目实际上是花费了一半的时间,而且如果测试不好,也会付出相当高的商业代价。)
- 容易估计的部分,即编码,仅仅分配了六分之一的时间
空泛的估算
软件开发中因缺乏科学依据与有效方法,导致估算结果脱离实际的现象。(原因就是上面写的乐观主义内容)
- 表现及原因:在软件项目中,空泛的估算表现为对项目进度和工作量的估计缺乏科学依据,过于依赖主观直觉,且常基于 “一切都将运作良好” 的不切实际假设。这是因为缺乏有效的估算技术研究,同时估算时错误地将人和月看作可互换的单位,混淆了进度与工作量。此外,软件经理对估算工作缺乏耐心和信心,也不重视对进度的跟踪和监督。例如,在一些项目中,仅根据编码部分的估计,乘以任务其他部分的相对系数来得出对整项工作的估计,这种方法忽略了项目中诸多复杂因素,如系统测试、文档编写等工作所需的时间和精力,从而导致估算结果与实际情况相差甚远。
- 影响:空泛的估算会使项目进度安排不合理,导致项目容易出现滞后的情况。当实际进度与计划进度出现偏差时,若采用增加人力的传统方式来解决,往往会因为新成员需要培训以及沟通成本增加等问题,进一步延长项目时间,增加项目成本,形成恶性循环。如在一些项目中,当发现进度落后时增加人手,新成员在适应项目、与原有成员沟通协作等方面花费大量时间,使得项目进度不仅没有加快,反而更加滞后。
重复产生的监督灾难
Brooks 法则:向进度落后的项目中增加人手,只会使进度更加落后。(Adding manpower to a late
software project makes it later)
- 表现及原因:重复产生的监督灾难主要体现在当软件项目进度落后时,通常采取增加人力的措施,但这往往无法解决问题,甚至使情况更糟。这是因为在项目管理中,人们常常下意识地认为增加人手就能加快进度,却忽略了软件开发工作的复杂性和特殊性。软件开发不是简单的体力劳动,任务之间存在着复杂的依赖关系,新成员加入后,需要时间熟悉项目,这期间会增加培训成本和沟通成本,而且可能会打乱原有的工作节奏和团队协作模式。例如,在一个原本按计划进行的项目中,因为进度落后而增加人员,新成员需要花费时间了解项目的技术架构、业务逻辑等,在这个过程中,原有成员需要分出精力来帮助新成员,导致整体工作效率下降,项目进度进一步延误。
- 影响:这种重复产生的监督灾难会导致项目成本大幅增加,包括人力成本、培训成本以及因进度延误可能带来的机会成本等。同时,项目进度的一再延误也会影响团队成员的士气,降低团队的工作积极性和效率,最终可能导致项目无法按时交付,影响项目的成功实施,给企业带来巨大损失。
外科手术队伍(The Surgical Team)
问题( 传统团队模式的困境)
- 程序员生产率差异大:研究(还有经验)表明,优秀程序员和较差程序员在生产率上平均为10:1 ,且经验与实际表现并无必然联系。在软件开发中,这种差异会显著影响项目进度和质量。
- 团队规模与沟通成本的矛盾:大型编程项目若采用一拥而上的开发方式,会增加沟通成本,降低开发效率。因为沟通成本是开发成本的主要组成部分,涉及相互交流以及更正沟通不当引起的问题(如系统调试)。
试想:一个产品在最初设计的 10 年后才出现,还有人会对它感兴趣吗?或者它是否会随着软件开发技术的快速进步,而显得过时呢?
Mills 的建议(外科手术队伍模式)
大型项目的每个部分由一个团队以类似外科手术的方式组建来解决问题,改变每个成员截取问题部分的传统做法,由一人进行问题分解,其他人提供支持,以此提高效率和生产力。
-
外科医生(首席程序员):承担核心职责,亲自定义功能和性能技术说明书、设计程序、编制源代码、测试并书写技术文档。这要求其具备极高天分、十年以上经验,以及应用数学、业务数据处理等多方面的丰富知识。
-
副手:作为外科医生后备,能完成部分工作,经验相对较少。主要作用是参与设计思考、讨论和评估,协助外科医生,代表团队与其他团队沟通功能和接口问题,熟悉所有代码并研究设计策略备选方案,但不承担具体开发职责。
-
管理员:负责控制财务、人员、工作地点安排和机器等事务,充当团队与组织中其他管理机构的接口。在项目有法律、合同、报表和财务需求时为全职,否则可服务于两个团队,让外科医生专注于技术工作。管理员一般需要秘书。
-
编辑:依据外科医生提供的草稿或口述内容,进行文档的分析、重组,提供参考信息和书目,维护多个版本并监督文档生成机制,确保文档的清晰度和规范性。编辑一般需要秘书,管理员的秘书负责项目的协作一致和非产品文件。
-
程序职员:承担编程产品库中所有团队技术记录的维护工作,管理机器码文件和可读文件,对计算机输入输出进行记录、标识和归档,保障技术资料的有序管理。
程序职员的专业化分工,使程序员从书记的杂事中解放出来,同时还可以对那些杂事进行系统整理,确保了它们的质量。 -
工具维护人员:保障团队使用的基本工具和服务的可靠性,负责特殊工具的构建、维护和升级。即使有集中式服务,每个团队仍需配备,以满足外科医生的特定工具需求。
-
测试人员:为外科医生设计系统测试用例和日常调试测试数据,同时负责计划测试步骤和搭建测试平台,确保软件质量。
-
语言专家:擅长掌握复杂编程语言,为团队提供简洁有效的编程方法,解决复杂、晦涩或棘手的编程问题,通常可为两到三个外科医生服务。
如何运作
- 确保概念完整性:10人团队中,系统主要由1 - 2人思考设计,保证了概念的一致性。与传统团队每人负责一部分设计实现不同,外科手术队伍中的外科医生和副手都熟悉所有设计和代码,避免了因分工导致的概念混乱,节省了空间分配、磁盘访问等工作量。
- 减少沟通成本:传统团队成员平等,观点差异易导致策略和接口不一致,需要大量讨论和妥协。而外科手术队伍中,观点不一致由外科医生统一,且团队其他成员职能专业化分工明确,交流模式简单,减少了沟通成本和误解。
团队的扩建
- 团队扩建原则:当项目规模扩大,需要面对几百人参与的大型任务时,外科手术队伍模式的扩建依赖于每个部分概念完整性的提高。例如,200人的项目,可通过协调20个“外科医生”的思路来推进工作,即把大型项目分解为多个小部分,每个小部分由一个类似的外科手术团队负责。
- 系统结构师的作用:整个系统需要有系统结构师进行自上而下的设计,清晰划分体系结构设计和实现的界线,确保系统的整体架构和概念完整性。结构师专注于体系结构,各团队的外科医生在其指导下开展工作,保证各个部分的设计和实现符合整体要求。