Skip to content

Latest commit

 

History

History
203 lines (118 loc) · 17.8 KB

2016-01-10 人月神话 读书摘要.md

File metadata and controls

203 lines (118 loc) · 17.8 KB
  • tags: other
  • date: 2016-01-10

人月神话 读书摘要

2015-12-23 08:35:47

必须追求完美。因为计算机也是以这样的方式来变戏法:如果咒语中的一个字符、一个停顿,没有与正确的形式一致,魔术就不会出现。(现实中,很少的人类活动要求完美,所以人类对它本来就不习惯。)实际上,我认为学习编程的最困难部分,是将做事的方式往追求完美的方向调整。

2015-12-23 08:38:28

最后一个苦恼,有时也是一种无奈--当投入了大量辛苦的劳动,产品在即将完成或者终于完成的时候,却已显得陈旧过时。可能是同事和竞争对手已在追逐新的、更好的构思;也许替代方案不仅仅是在构思,而且已经在安排了。 现实情况比上面所说的通常要好一些。当产品开发完成时,更优秀的新产品通常还不能投入使用,而仅仅是为大家谈论而已。另外,它同样需要数月的开发时间。事实上,只有实际需要时,才会用到最新的设想,因为所实现的系统已经能满足要求,体现了回报。

2015-12-23 08:39:00

诚然,产品开发所基于的技术在不断地进步。一旦设计被冻结,在概念上就已经开始陈旧了。不过,实际产品需要一步一步按阶段实现。实现落后与否的判断应根据其它已有的系统,而不是未实现的概念。因此,我们所面临的挑战和任务是在现有的时间和有效的资源范围内,寻找解决实际问题的切实可行方案。

2015-12-23 08:41:28

这,就是编程。一个许多人痛苦挣扎的焦油坑以及一种乐趣和苦恼共存的创造性活动。 对于许多人而言,其中的乐趣远大于苦恼。

2015-12-23 08:45:56

在众多软件项目中,缺乏合理的时间进度是造成项目滞后的最主要原因,它比其他所有因素加起来的影响还大。导致这种普遍性灾难的原因是什么呢? 首先,我们对估算技术缺乏有效的研究,更加严肃地说,它反映了一种悄无声息,但并不真实的假设--一切都将运作良好。 第二,我们采用的估算技术隐含地假设人和月可以互换,错误地将进度与工作量相互混淆。 第三,由于对自己的估算缺乏信心,软件经理通常不会有耐心持续地进行估算这项工作。 第四,对进度缺少跟踪和监督。其他工程领域中,经过验证的跟踪技术和常规监督程序,在软件工程中常常被认为是无谓的举动。 第五,当意识到进度的偏移时,下意识(以及传统)的反应是增加人力。这就像使用汽油灭火一样,只会使事情更糟。越来越大的火势需要更多的汽油,从而进入了一场注定会导致灾难的循环。

2015-12-23 08:53:33

对于软件任务的进度安排,以下是我使用了很多年的经验法则: 1/3计划 1/6编码 1/4构件测试和早期系统测试 1/4系统测试,所有的构件已完成

2015-12-23 08:57:23

观察一下编程人员,你可能会发现,同厨师一样,某项任务的计划进度,可能受限于顾客要求的紧迫程度,但紧迫程度无法控制实际的完成情况。就像约好在两分钟内完成一个煎蛋,看上去可能进行得非常好。但当它无法在两分钟内完成时,顾客只能选择等待或者生吃煎蛋。软件顾客的情况类似。 厨师还有其他的选择:他可以把火开大,不过结果常常是无法"挽救"的煎蛋--一面已经焦了,而另一面还是生的。

2015-12-23 08:59:23

我并不认为软件经理内在的勇气和坚持不如厨师,或者不如其他工程经理。但为了满足顾客期望的日期而造成的不合理进度安排,在软件领域中却比其他的任何工程领域要普遍得多。而且,非阶段化方法的采用,少得可怜的数据支持,加上完全借助软件经理的直觉,这样的方式很难生产出健壮可靠和规避风险的估计。

2015-12-24 07:54:31

向进度落后的项目中增加人手,只会使进度更加落后。

2015-12-24 07:55:23

项目的时间依赖于顺序上的限制,人员的数量依赖于单个子任务的数量。从这两个数值可以推算出进度时间表,该表安排的人员较少,花费的时间较长(唯一的风险是产品可能会过时)。相反,分派较多的人手,计划较短的时间,将无法得到可行的进度表。总之,在众多软件项目中,缺乏合理的时间进度是造成项目滞后的最主要原因,它比其他所有因素加起来的影响还要大。

2015-12-24 07:58:35

软件经理很早就认识到优秀程序员和较差的程序员之间生产率的差异,但实际测量出的差异还是令我们所有的人吃惊。在他们的一个研究中,Sackman、Erikson和Grand曾对一组具有经验的程序人员进行测量。在该小组中,最好的和最差的表现在生产率上平均为10:1;在运行速度和空间上具有5:1的惊人差异!简言之,$20,000/年的程序员的生产率可能是$10,000/年程序员的10倍。数据显示经验和实际的表现没有相互联系(我怀疑这种现象是否普遍成立。)

2015-12-24 08:12:29

需要协作沟通的人员的数量影响着开发成本,因为成本的主要组成部分是相互的沟通和交流,以及更正沟通不当所引起的不良结果(系统调试)。这一点,也暗示系统应该由尽可能少的人员来开发。实际上,绝大多数大型编程系统的经验显示出,一拥而上的开发方法是高成本的、速度缓慢的、不充分的,开发出的是无法在概念 上进行集成的产品。OS/360、Exec 8、Scope 6600、Multics、TSS、SAFE等等--这个列表可以不断地继续下去。 得出的结论很简单:如果一个200人的项目中,有25个最能干和最有开发经验的项目经理,那么开除剩下的175名程序员,让项目经理来编程开发。

2015-12-24 08:15:34

对于效率和概念的完整性来说,最好由少数干练的人员来设计和开发,而对于大型系统,则需要大量的人手,以使产品能在时间上满足要求。

2015-12-24 08:16:35

Harlan Mills的提议提供了一个崭新的、创造性的解决方案2,3。Mills建议大型项目的每一个部分由一个团队解决,但是该队伍以类似外科手术的方式组建,而并非一拥而上。 也就是说,同每个成员截取问题某个部分的做法相反,由一个人来进行问题的分解,其他人给予他所需要的支持,以提高效率和生产力。 注 解决需要很多人手的大型项目问题

2015-12-24 08:18:57

外科医生。Mills称之为首席程序员。

2015-12-24 08:20:15

副手。他是外科医生的后备,能完成任何一部分工作,但是相对具有较少的经验。他的主要作用是作为设计的思考者、讨论者和评估人员。外科医生试图和他沟通设计,但不受到他建议的限制。副手经常在与其他团队的功能和接口讨论中代表自己的小组。他需要详细了解所有的代码,研究设计策略的备选方案。显然,他充当外科医生的保险机制。他甚至可能编制代码,但针对代码的任何部分,不承担具体的开发职责。

2015-12-24 08:41:04

对于计算机系统而言,尽管它们通常没有花费几个世纪的时间来构建,但绝大多数系统体现出的概念差异和不一致性远远超过欧洲的大教堂。这通常并不是因为它由不同的设计师们开发,而是由于设计被分成了由若干人完成的若干任务。 我主张在系统设计中,概念完整性应该是最重要的考虑因素。也就是说为了反映一系列连贯的设计思路,宁可省略一些不规则的特性和改进,也不提倡独立和无法整合的系统,哪怕它们其实包含着许多很好的设计。在本章和以下的两章里,我们将解释在编程系统设计中,这个主题的重要性。 注 概念的一致性与完整性不仅仅是在UI层面,程序系统设计上也是如此,那么就要求一个程序系统的设计人员要尽可能少,大多数情况下可能只有一个人,即前面提到的外科医生

2015-12-24 08:53:33

目标是易用性,功能与理解上复杂程度的比值才是系统设计的最终测试标准。单是功能本身或者易于使用都无法成为一个好的设计评判标准。

注 程序系统设计的目标包括易用性

2015-12-24 09:01:02

概念的完整性要求设计必须由一个人,或者非常少数互有默契的人员来实现。 而进度压力却要求很多人员来开发系统。有两种方法可以解决这种矛盾。第一种是仔细地区分设计方法和具体实现。第二种是前一章节中所讨论的、一种崭新的组建编程开发团队的方法。 对于非常大型的项目,将设计方法、体系结构方面的工作与具体实现相分离是获得概念完整性的强有力方法。我亲眼目睹了它在IBM的Stretch计算机和360计算机产品线上的巨大成功。但同时我也看到了这种方法在360操作系统的开发中,由于缺乏广泛应用所遭受的失败。 注 第二种即是外科医生式团队组建

2015-12-24 19:07:31

概念的完整性的确要求系统只反映唯一的设计理念,用户所见的技术说明来自少数人的思想。实际工作被划分成体系结构、设计实现和物理实现,但这并不意味着该开发模式下的系统需要更长的时间来创建。经验显示恰恰相反,整个系统将会开发得更快,所需要的测试时间将更少。同工作的水平分割相比,垂直划分从根本上大大减少了劳动量,结果是使交流彻底地简化,概念完整性得到大幅提高。

2015-12-24 19:12:28

第二个系统是设计师们所设计的最危险的系统。而当他着手第三个或第四个系统时,先前的经验会相互验证,得到此类系统通用特性的判断,而且系统之间的差异会帮助他识别出经验中不够通用的部分。 一种普遍倾向是过分地设计第二个系统,向系统添加很多修饰功能和想法,它们曾在第一个系统中被小心谨慎地推迟了。结果如同Ovid所述,是一个"大馅饼"。例如,后来被嵌入到7090的IBM 709系统,709是对非常成功和简洁的704系统进行升级的二次开发项目。709的操作集合被设计得如此丰富和充沛,以至于只有一半操作被常规使用。

2015-12-25 08:21:06

他们还缺乏些什么?两个方面--交流,以及交流的结果--组织。

注 为什么巴比伦塔项目会失败

2016-01-05 07:48:26

战略上突破常来自数据或表的重新表达--这是程序的核心所在。如果提供了程序流程图,而没有表数据,我仍然会很迷惑。而给我看表数据,往往就不再需要流程图,程序结构是非常清晰的。

2016-01-05 07:47:01

战略上突破常来自数据或表的重新表达--这是程序的核心所在。

2016-01-05 07:50:16

由于缺乏空间而绞尽脑汁的编程人员,常常能通过从自己的代码中挣脱出来,回顾、分析实际情况,仔细思考程序的数据,最终获得非常好的结果。实际上,数据的表现形式是编程的根本。

2016-01-05 08:02:24

他观察到不愿意为设计书写文档的原因,不仅仅是由于惰性或者时间压力。相反,设计人员通常不愿意提交尝试性的设计决策,再为它们进行辩解。"通过设计文档化,设计人员将自己暴露在每个人的批评之下,他必须能够为他的每个结果进行辩护。如果团队架构因此受到任何形式的威胁,则没有任何东西会被文档化,除非架构是完全受到保护的。

2016-01-05 08:12:43

程序维护中的一个基本问题是--缺陷修复总会以(20-50)%的机率引入新的bug。所以整个过程是前进两步,后退一步。 为什么缺陷不能更彻底地被修复?首先,看上去很轻微的错误,似乎仅仅是局部操作上的失败,实际上却是系统级别的问题,通常这不是很明显。修复局部问题的工作量很清晰,并且往往不大。但是,更大范围的修复工作常常会被忽视,除非软件结构很简单,或者文档书写得非常详细。其次,维护人员常常不是编写代码的开发人员,而是一些初级程序员或者新手。

2016-01-05 08:15:00

模块数量随版本号的增加呈线性增长,但是受到影响的模块以版本号指数的级别增长。所有修改都倾向于破坏系统的架构,增加了系统的混乱程度。用在修复原有设计上瑕疵的工作量越来越少,而早期维护活动本身的漏洞所引起修复工作越来越多。随着时间的推移,系统变得越来越无序,修复工作迟早会失去根基。每一步前进都伴随着一步后退。尽管理论上系统一直可用,但实际上,整个系统已经面目全非,无法再成为下一步进展的基础。而且,机器在变化,配置在变化,用户的需求在变化,所以现实系统不可能永远可用。崭新的、对于原有系统的重新设计是完全必要的。

2016-01-05 08:16:10

系统软件开发是减少混乱度(减少熵)的过程,所以它本身是处于亚稳态的。软件维护是提高混乱度(增加熵)的过程,即使是最熟练的软件维护工作,也只是放缓了系统退化到非稳态的进程。

2016-01-06 08:14:57

有两种掀开毯子把污垢展现在老板面前的方法,它们必须都被采用。一种是减少角色冲突和鼓励状态共享,另一种是猛地拉开地毯。

2016-01-06 08:21:43

除了程序的使用方法,还必须附带一些程序正确运行的证明,即测试用例。 注 待发布的程序与文档中需要包含测试用例

2016-01-06 08:27:18

每一份发布的程序拷贝应该包括一些可以例行运行的小测试用例,为用户提供信心--他拥有了一份可信赖的拷贝,并且正确地安装到了机器上。 然后,需要得到更加全面的测试用例,在程序修改之后,进行常规运行。这些用例可以根据输入数据的范围划分成三个部分。

  1. 针对遇到的大多数常规数据和程序主要功能进行测试的用例。它们是测试用例的主要组成部分。
  2. 数量相对较少的合法数据测试用例,对输入数据范围边界进行检查,确保最大可能值、最小可能值和其他有效特殊数据可以正常工作。
  3. 数量相对较少的非法数据测试用例,在边界外检查数据范围边界,确保无效的输入能有正确的数据诊断提示。

2016-01-06 08:30:43

现实中,流程图被鼓吹的程度远大于它们的实际作用。我从来没有看到过一个有经验的编程人员,在开始编写程序之前,会例行公事地绘制详尽的流程图。在一些要求流程图的组织中,流程图总是事后才补上。一些公司则很自豪地使用工具软件,从代码中生成这个"不可缺少的设计工具"。我认为这种普遍经验并不是令人尴尬和惋惜的对良好实践的偏离(似乎大家只能对它露出窘迫的微笑),相反,它是对技术的良好评判,向我们传授了一些流程图用途方面的知识。 注 流程图可以帮助我们进行有效沟通,在思路不清晰时是很有必要的

2016-01-06 08:32:55

把文档整合到源代码

2016-01-06 08:37:42

自文档化方法激发了高级语言的使用,特别是用于在线系统的高级语言--无论是对批处理还是交互式,它都表现出最强的功效和应用的理由。如同我曾经提到的,上述语言和系统强有力地帮助了编程人员。因为是机器为人服务,而不是人为机器服务。因此从各个方面而言,无论是从经济上还是从以人为本的角度来说,它们的应用都是非常合情合理的。

2016-01-07 08:27:52

现在有两种差异非常大的AI定义被广泛使用。AI-1:使用计算机来解决以前只能通过人类智慧解决的问题。AI-2:使用启发式和基于规则的特定编程技术。在这种方法中,对人类专家进行研究,判断他们解决方法的启发性思维或者经验法则..。程序被设计成以人类解决问题的方式来运作。

2016-01-07 08:29:43

如何把它应用在软件开发工作中?可以通过很多途径:建议接口规则、制订测试策略、记录各种bug产生的频率、提供优化建议等等。 注 基于AI的专家系统在软件工程领域的用途

2016-01-07 08:43:30

软件开发人员为客户所承担的最重要的职能是不断重复地抽取和细化产品的需求。事实上,客户不知道他们自己需要什么。他们通常不知道哪些问题是必须回答的。并且,连必须确定的问题细节常常根本不予考虑,甚至只是简单地回答--"开发一个类似于我们已有的手工处理过程的新软件系统"--实际上都过于简单。客户决不会仅仅要求这些。复杂的软件系统往往是活动的、变化的系统。活动的动态部分是很难想象的。所以,在计划任何软件活动时,要让客户和设计人员之间进行多次广泛的交流沟通,并将其作为系统定义的一部分。这是非常必要的。

2016-01-08 08:09:04 面向对象应用在整个开发周期中,但是真正的获益只有在后续开发、扩展和维护活动中才能体现出来。Coggin说:"面向对象技术不会加快首次或第二次的开发,产品族中第五个项目的开发才会异乎寻常的迅速。

2016-01-08 08:17:40

人们通常期望项目在接近结束时,(bug、工作时间)能收敛得快一些,然而软件项目的情况却是越接近完成,收敛得越慢 .. 产品在即将完成时总面临着陈旧过时的威胁

2016-01-08 08:33:43

程序员不愿意为设计书写文档的原因,不仅仅是由于惰性。更多的是源于设计人员的踌躇--要为自己尝试性的设计决策进行辩解。(Cosgrove)