目录
在快节奏变化的时代背景下,《人月神话》这部经典之作,仍然闪耀着智慧之光,是一本值得反复咀嚼的好书。
今天,让我们再次翻开这本书,结合在实际项目中的经历,重新审视那些让我们眼前一亮的观点,看看它们是如何在现实世界中落地生根的。
前言
《人月神话》(The Mythical Man-Month)是由Frederick P. Brooks 撰写的一本软件工程学经典巨著。
- 这是一本成书于 1975 年的关于软件工程的书。
- 半个世纪以来,《人月神话》经久不衰,Brooks博士为人们管理复杂项目提供了最具洞察力的见解,既有很多发人深省的观点,又有大量软件工程的实践。
《人月神话》(The Mythical Man-Month)这本书主要基于布鲁克斯在IBM担任系统架构师期间的经验,特别是他在领导开发OS/360操作系统时所遭遇的问题及其反思。
- 书名中的“人月”(Man-month)是指衡量工作量的一个单位,即一个人一个月内完成的工作量。
- 而“神话”则指的是一个普遍存在的错误观念,即增加人手就能相应加快软件项目的进度。
- 实际上,在某些情况下,这样做反而会因为沟通成本增加而减缓进度。
时间未能改变的:软件工程中的那些顽疾
即便计算机领域已飞速发展了几十年,硬件越来越快、网络愈发迅捷、计算与存储资源日益丰富,再加上无数优秀的重用库、完善的框架、便捷的语言以及先进的思想等,这些都远超我们的想象。
这一切似乎都在暗示,软件工程领域的种种难题应当早已迎刃而解,至少也应该换一批新问题来挑战我们。
然而,现实却并非如此美好:
1. 工作量评估依然困难重重
- 尽管我们有了各种高级工具和技术手段,但在预测项目所需时间和资源方面,依然存在巨大不确定性。
- 无论是敏捷开发还是瀑布模型,准确预估依然是个挑战。
2. 合理规划进度难上加难
- 制定出既能满足业务需求又能兼顾团队实际能力的时间表仍然是一项艰巨任务。
- 如何在有限时间内完成尽可能多的功能,并保证质量,依然是每个项目经理头疼的问题。
3. 项目延期时,只能依靠加班或增员
- 当面临进度落后时,除了延长工作时间或增加人员投入外,似乎并没有更好的解决办法。
- 这种方法不仅治标不治本,还可能进一步加剧团队疲劳及沟通成本。
4. BUG层出不穷
- 尽管测试技术和自动化工具不断进步,但软件缺陷依旧频繁出现。
- 从设计到编码再到测试,任何一个环节出现问题都可能导致最终产品存在隐患。
5. 用户满意度低下
- 很多时候,辛辛苦苦开发出来的软件并不能真正打动用户的心。有时他们只用了其中一小部分功能,而对于其他大部分功能则置之不理。
- 这反映出我们在理解用户需求方面还有很长的路要走。
6. 项目失败率居高不下
- 尽管有着丰富的经验和教训积累,但依然有大量软件项目最终以失败告终。
- 无论是因为预算超支、需求变化还是技术难题,都说明了软件开发并非易事。
焦油坑:软件项目的无底深渊
为了更好地理解《人月神话》中所提到的“焦油坑”概念,我们可以借鉴一个自然界的例子——美国加州的拉布雷亚焦油坑。
这是一个非常著名的天然冰河时代古生物化石库,自古以来就是一个巨大的生物陷阱。无数史前动物因陷入其中而无法脱身,最终丧生于此,包括近700种不同的物种,如智人、猛犸象、长毛犀、剑齿虎、巨型树懒以及恐狼等。
在软件工程领域,“焦油坑”用来比喻那些看似简单,但实际上异常复杂且容易使人深陷其中难以自拔的项目。
这类项目往往具有以下几个特征:
- 表面简单:起初看起来似乎是小问题或易于解决的任务。
- 隐藏风险:随着工作的深入,问题变得越来越复杂,解决起来也越来越困难。
- 资源消耗:它会像真正的焦油坑一样,不断地吸引并吞噬更多的人力、物力和财力。
- 难以脱身:一旦介入,便很难从中抽身而出,即使明知其风险也难以及时止损。
正如拉布雷亚焦油坑吞噬了无数史前生命一般,“焦油坑”类的软件项目也会让开发团队深陷其中,耗费大量宝贵资源却难以取得预期成果。
- 因此,在软件开发过程中识别并避免“焦油坑”,对于项目成功至关重要。
- 《人月神话》中提到的许多观点至今仍具有深刻意义,提醒着我们在追求技术创新的同时,不应忽视软件工程本身固有的挑战。
- 只有正视这些问题,并不断探索有效解决方案,才能逐步推动行业向前发展。
焦油坑(The Tar Pit)
作者用“吞噬了恐龙、剑齿虎等史前巨兽的焦油坑”这一生动比喻,形象地描绘了软件系统开发的复杂性。
- 在整个的软件开发过程中,“编程系统产品”才是真正的目标,也是最具价值的产品形态。为了更清晰地阐述这一观点,作者区分了以下几个概念:
编程系统产品
- 其实写博客,就可以理解为一种编程产品文档,可以帮助我们更好的形成体系
- 平时 的算法题和看代码,写代码 就是锻炼编程能力
- 有体系+代码能力,才能写出 更好的代码
程序(Program)
由编码人员完成的编码产物,可以在所开发的系 统平台上运行。
编程产品(Programming Product)
编程产品是指一个独立的、可执行的程序,任何人都可以运行、测试、修复和扩展它。
- 它可以跨多个操作系统平台运行。
- 要将一个简单的程序转变为编程产品,需要付出更多努力——包括详尽的测试和完备的文档。
根据经验数据,相同功能的编程产品的成本 至少是已经过测试的程序的三倍。
编程系统(Programming System)
编程系统是多个能够相互协作的程序集合。
- 它是指在一个已有的编程系统平台上开发新的功能构件。
- 要使一个程序成为编程系统中的一个构件单元,不仅需要确保其接口一致,还必须遵守预定义的资源限制,并能与其他现有组件进行组合测试验证。
- 相同功能的编程系统构件的成本至少是独立程序的三倍。
如果系统包含大量组件,成本会进一步增加。
编程系统产品(Programming Systems Product)
- 编程系统产品是指一个完整的、功能齐全的软件解决方案。
- 相对于单纯的“编程(Programming)”而言,其成本可能高达九倍。
- 然而,只有这样的产品才真正具有实用价值,是大多数系统开发的目标。
编程系统产品的开发不仅涉及编码,还包括全面的设计、严格的测试以及详尽的文档,确保最终产品既可靠又易于维护。
编程的乐趣和苦恼
- 这部分见仁见智,毕竟人类的悲喜并不相通。
编程为什么有趣?
创造的喜悦
- 就像孩子在沙滩上堆砌沙堡时那种单纯的快乐,编程同样给予我们创造新事物的机会。
- 每当一行行代码跃然屏幕之上,逐渐汇聚成一款应用或游戏时,那份成就感难以言表。这也许是对上帝创造世界的一种微缩体验吧——在每一个独一无二的树叶或雪花中都能感受到这种喜悦。
共享的价值
- 编写程序并不仅仅是个人的消遣,更是一种能够惠及他人的行为。
- 当我们开发出一款软件或工具,并看到它在他人手中发挥作用时,那种内心的满足感是无价的。
- 这份喜悦源于内心深处那份希望自己的工作能够帮助到别人的愿望。
魔法般的魅力
- 编程还蕴含着一种类似魔法的魅力。
- 当你将一个个看似无关紧要的小模块拼凑起来,见证它们如何巧妙地协同运作,达到预期的效果时,那份惊喜与激动丝毫不亚于观看一场精彩的魔术表演。
持续的学习
- 由于编程领域日新月异,这意味着总有学不完的知识等着我们去探索。
- 无论是解决实际问题还是理论研究,每一次尝试都能让我们收获新的知识,这样的过程本身便充满了乐趣。
职业的苦恼
追求完美
- 计算机科学要求极高精确度,哪怕是最微小的错误也可能导致整个项目功亏一篑。
- 因此,作为程序员,必须时刻保持警惕,不断追求完美。
依赖他人
在团队合作中,我们经常需要依赖同事的工作成果。
然而,并不是每个人都会按照高标准来完成任务,这就导致后续环节可能会遇到各种意想不到的问题,需要耗费大量时间和精力去解决。
调试的艰辛
创意与灵感固然重要,但随之而来的往往是繁琐且耗时的调试过程。
在这个阶段,我们需要反复试验、查找错误,直到找到症结所在。这一过程无疑是枯燥且令人沮丧的。
时代的淘汰
- 技术发展速度之快,使得很多项目还没等完工就已经落后于市场。
- 看着自己投入心血的作品渐渐被淘汰,这对任何一位程序员来说都是不小的打击。
这就是编程——既有创造的乐趣,也有面对挑战时的困扰。
然而,正是这些复杂的情感交织在一起,构成了这份职业独特的魅力所在。对于真正热爱它的人来说,那些瞬间的快乐足以抵消一切烦恼。而本书的剩余部分将试图搭建一些桥梁,为通过 这样的焦油坑提供一些指导。
“人月”(Man-Month)概念,是指一名开发者在一个自然月内所能完成的工作量。
- 理论上讲,如果某个项目的预计工期是十个人一个月(即十个人月)才能完成,那么人们往往会直觉地认为,可以通过让十个人同时工作一个月来达到同样的效果。
- 在本章中,作者进行的点题,也就是书名人月神话的出处。在本章中作者揭示了这种想法的误区。
- 要详细了解什么是人月神话,需要对下面一个公式进行思考:
10人/月 = 1个人工作10个月 = 10个人工作1个月
在单纯的数字上,这个等式是成立的,但有点软件开发常识的人都知道这个等式是不成立的,因为有太多不确定的因素在公式的背后。
人月
在估计和进度安排中谬误的思考方式是使用的工作量单位:人月。
- 理想情况下人员数量与时间消耗之间的关系,即随着投入人力的增加,项目所需时间呈现递减趋势,这在割小麦或收获棉花的工作中是可行的;
而在系统编程 中近乎不可能,因为:
1、他们之间需不需要交流
2、任务次序能不能分解
人员和时间之间的关系——完全可以分解的任务
人员和时间之间的关系——无法分解的任务
子任务之间需要相互沟通和交流的任务,必须在计划工作中考虑沟 通的工作量。因此,相同人月的前提下,采用增加人手来减少时间得到的最好情况,也比未 调整前要差一些。
人员和时间之间的关系——需要沟通的可分解任务
如果任务的每个部分必须分别和其他部分单独协作, 则工作量按照 n(n-1)/2 递增。
- 一对一交流的情况下,三个人的工作量是两个人的三倍,四 个人则是两个人的六倍。
- 而对于需要在三四个人之间召开会议、进行协商、一同解决的问题, 情况会更加恶劣。
人员和时间之间的关系——关系错综复杂的任务
因为软件开发本质上是一项系统工作——错综复杂关系下的一种实践——沟通、交流 的工作量非常大,它很快会消耗任务分解所节省下来的个人时间。
从而,添加更多的人手, 实际上是延长了,而不是缩短了时间进度。
进度安排
针对时间进度安排作者从几个方面进行的阐述:
- 对估算技术缺乏有效的研究与应用:许多组织未能投入足够的时间和精力来发展和改进项目估算的方法论,导致估算常常基于经验主义而非科学方法。
- 估算技术隐含地假设了人与月的可互换性:这一假设忽略了团队成员之间的差异性和项目本身的复杂性,从而使得估算结果往往与实际所需的时间和资源产生偏差。
- 缺乏对自身估算的信心:由于对不确定性的恐惧,管理者倾向于避免做出长期规划或坚持既定的估算方案,这进一步加剧了时间安排上的不确定性。
- 进度跟踪与监督机制的缺失:有效的进度管理依赖于持续的监控与评估,但现实中,很多情况下并没有建立相应的机制来确保项目按照预期轨道前进。
- 盲目增加人力资源:当发现进度落后时,通常的做法是增加更多的人力,然而,如前所述,这并不总是最有效的解决方案。
除此之外,实际项目管理中还存在以下几个更为核心的问题:
- 忽视了人员与项目的匹配度:不仅仅是技能层面的匹配,更重要的是考虑到员工的发展潜力及其适应项目文化的能力,这样才能确保团队运作高效。
- 全局视野下的合理安排:项目计划制定者需要具备全面了解项目背景及目标的基础上,进行科学合理的资源配置和时间安排,而不是仅凭主观臆断。
- 项目计划的动态调整:随着项目的推进,外部环境的变化可能会要求计划进行相应的调整,这就需要管理者具备灵活应变的能力,及时作出必要的修正以保证项目顺利进行。
- 专业的任务管理工具:如今已有大量先进的任务管理工具涌现,旨在协助项目经理们更加有效地追踪和监督软件项目的各个阶段进展。一位出色的项目经理应当熟练掌握这些工具的应用,确保能够及时跟进项目中的每一个细分任务。
乐观主义
所有的编程人员都是乐观主义者。
系统编程的进度安排背后的第一个假设是:一切都将运作良好,每一项任务仅花 费它所“应该”花费的时间。
针对盲目的乐观主义,历史的经验会告诉我们:
1、历史数据参考:利用过往项目的历史数据作为参考基准
2、分阶段交付:将大型项目拆分为多个可独立完成的小模块或阶段,并设定明确的里程碑目标。
3、风险评估与管理:在项目启动之初就进行全面的风险评估,识别潜在的问题点,并制定相应的应对策略。
随着任务复杂度的提升,任务不仅更难分解,还会产生更多的沟通需求,这往往会消耗大量时间。
- 因此,在面对进度滞后的局面时,盲目增加开发人员未必能加速项目的完成,反而可能因沟通协调负担加重而进一步拖慢进度。这一现象也被称为布鲁克斯法则(Brooks's Law)
- 它指出,在项目已经出现延期的情况下,简单地增派人手,不但无助于提速,反而可能导致项目更加滞后。
- 这是因为新加入成员需要时间熟悉情况并与现有团队磨合,这期间产生的额外工作量有时会超过他们带来的生产力提升。
Brooks 法则:
向进度落后的项目中增加人手,只会使进度更加落后。(Adding manpower to a late software project makes it later)