人月神话读书笔记

人月神话这本书是偏向项目管理的一本管理型书籍。主要内容就如其名:人和月。人是程序员,月是工作时间,人和月是两个独立的单位,是无法相乘的。

简单来说就是:一个女人怀胎10月可以生下一个孩子,但是10个女人怀胎1月当然不可能生下一个孩子。

以下内容是我阅读<<人月神话(40周年中文纪念版)>>的读书笔记。我将书中一些重要观点摘录出来,部分观点下加了我自己的理解(以注的形式添加的)。

  • 在很多方面,管理一个大型的计算机编程项目与管理其他行业的大型工程很相似——比大多数程序员所认为的还要相似;在另外一些方面,它又有差别——比大多数职业经理人所认为的差别还要大。

    注: 这句话很普通,且仅出现在序言上,但我对这句话感触很深。很多时候程序员觉得很难的事情,在项目经理眼里并没有那么难(道理是相通的);而其他时候项目经理觉得简单的事情,在程序员看来很难(差异是难以调和的)。两者矛盾的根由我觉得通过这句话就足以概括了。
    
  • 编程系统产品的演进

左上部分是程序,它本身是完整的,可以由作者在所开发的系统平台上运行,他通常是车库中产出的产品,以及作为单个程序员生产率的评估标准。

有两种途径可以视程序转变成更有用但是成本更高的产物,这两种途径表现为图中的边界。

图中右下部分是编程系统产品,与以上所有简单程序都不同的是,它的成本高达9倍,然而,只有它才算真正有用的产品,是大多数系统开发的目标。

  • 对于软件任务的进度安排,以下是我使用了很多年的经验法则:

    1/3 计划
    1/6 编码
    1/4 构建测试和早期系统测试
    1/4 系统测试,所有的构建已完成

    注: 1. 很多时候我们以为编码时间就是全部的时间了,因此导致预估的时间和实际的开发时间有很大差异。
        2. 这里的编码时间仅仅占了1/6,目前我还做不到。要么就是自己开发能力弱,要么就是自己花在非编码工作的时间不足
    
  • 向进度落后的项目中增加人手,只会使进度更加落后。

  • 在开发第一个系统时,结构师倾向于精炼和简洁,他知道自己对正在进行的任务不够了解,所以会谨慎、仔细的工作。当他着手第三个或第四个系统时,先前的经验会相互验证,得到对此类系统通用特性的判断,而且系统之间的差异也会帮助他识别出经验中不够通用的部分。而第二个系统是设计师们所设计的最危险的系统。一种普遍倾向是过分地设计第二个系统,向系统添加很多修饰功能和想法,他们曾在第一个系统中被小心谨慎地放在次要位置。开发第二个系统所引起的吼过的另一个表现是存在对某些技术进行细化、精炼的趋势,即使这些技术已经显得明显落后。

    架构师如何避免开发第二个系统所引起的后果,从而避免画蛇添足?是的,虽然他无法跳过二次系统,但他可以有意识的关注这个系统的特殊危险,运用特别的自我约束准则,来避免那些功能上 的过于修饰;根据系统基本原理及目的变更,舍弃一些功能。

    项目经理如何避免开发第二个系统所引起的后果,从而避免画蛇添足?他必须坚持至少拥有两个系统以上开发经验架构师的决定。同时,保持对特殊诱惑的警觉,他可以不断提出正确的问题,确保原则上的概念和目标在详细设计中得到完整的体现。

  • 产品负责人与技术主管

    产品负责人的角色是什么? 他组建团队,划分工作及制定进度表。他争取并一直保证必要的资源。这意味他主要的工作是与团队外部进行向上的沟通和水平的沟通。

    技术主管的角色是什么?他对设计进行构思,识别系统中的子部分,指明从外部看上去的样子,勾画它的内部结构。他提供整个设计的一致性和概念完整性;他控制着系统的复杂程序。当某个技术问题出现时,他提供问题的解决方案,或者根据需要调整系统设计。他的工作几乎完全是技术性的。

    产品负责人与技术主管三种可能的关系。

    1. 产品负责人与技术主管是同一个人。这种方式可以非常容易的应用在小型的队伍中,这样的队伍可能有3-6个开发人员,而在大型项目中则不容易获得应用。原因有两个:第一,同时具有管理技能和技术技能的人很难找到。思考者很少,实干家更少,既是思考者又是实干家的太少了。第二,大型项目中,每个角色都必须全职工作,设置还要加班。对产品负责人来说,很难在承担全部管理责任的同时还能抽出时间进行技术工作。对技术主管来说,很难在保证设计的概念完整性没有任何妥协的前提下,担任管理工作。
    2. 产品负责人作为总指挥,技术主管充当其左右手。这种方法有一些肯难,很难在技术主管不参与任何管理工作的同时,建立其在技术决策上的权威。显然,产品负责人必须预先声明技术主管的技术权威,在即将出现的绝大部分测试用例中,他必须支持后者的技术决定。
    3. 技术主管作为总指挥,产品负责人充当其左右手。

      最后一种安排对小型的团队是最好的选择。而对于大型项目中的一些开发队伍,我认为产品负责人作为管理者是更合适的安排。

      注:各司其职是最吼的。我的一个偏见是:技术主管兼任产品,往往在考虑产品功能时先想自己是否容易实现,而不是该功能是否必须。

  • 对于大多数项目,第一个开发的系统并不合用。它可能太慢、太大,而且难以使用,或者三者兼而有之。要解决所有的问题,除了重新开始以外,没有其他的办法——即开发一个更灵巧或更好的系统。系统的丢弃和重新设计可以一步完成,也可以一块块地实现。所有大型系统的经验都显示,这是必须完成的步骤。而且,新的系统概念或新技术会不断出现,必须构建一个用来抛弃的系统,因为即使是最优秀的项目经理,也不能无所不知地在最开始解决这些问题

    为舍弃而计划,无论如何,你一定要这样做。

    注: 模块化设计很重要! 解耦很重要!
    
  • 唯一不变的就是变化本身。一旦认识到实验性的系统必须被构建和丢弃,具有变更思想的重新设计将不可避免,那么,面对整个变化现象就是非常有用的。第一步是接受这样的事实:变化是与生俱来的,不是不合时宜和令人生厌的异常情况。如何为变化设计系统是一个众所周知的问题,它们包括细致的模块化、可扩展的函数、精确完整的模块间接口设计和完备的文档。

    注:上面2段说的很好,尤其是一开始只是尝试实现一个系统,或者说是Demo,代码粗糙、hard code、无法扩展等等。但随着人员流动,该系统或Demo就这样流传下来,甚至被当作真理了,后来的开发者或维护者不能动、不敢动。与其这样,不如一开始就进行模块化设计,然后搭建一个Demo时就是拼装不同的模块,这样该Demo就可以随时抛弃,或者说随时重新实现、重构。因为此时大部分模块都是可复用的,不可复用的仅仅是实现Demo时的一些具体业务逻辑,而这些逻辑通用在重构前就早已是抛弃掉的。
    
  • 就工具而言,即使是现在,很多软件项目仍然像经营一家五金店。每个骨干人员都仔细地保管自己工作生涯中搜集的一套工具集,这些工具成为个人技能的直观证明。这种方法对软件项目来说是愚蠢的,首先,项目的关键问题是沟通,个性化的工具会妨碍而非促进沟通,其次,当机器和工作语言发生变化时,技术也会随之变化,所有工具的生命周期都是很短的。最后,毫无疑问,开发和维护公共的通用编程工具的效率更高。

    注:深有体会,项目组之间没有沟通,各组甚至各人都有自己的一套工具(开发工具及通用算法代码片段)。
    
  • 编程系统产品开发的工作量是供个人使用的、独立开发的构件程序的九倍

    注:又有多少程序员或者项目经理能明白这句大白话呢。
    
  • 缺乏合理的时间进度是造成项目滞后的最主要原因,它比其他所有因素加起来影响还大。
  • 围绕成本核算的估计技术,混淆了工作量和项目进展。人月是危险和带有欺骗性的神话,因为它暗示人员数量和时间是可以相互替换的

    注: 切记,在软件开发过程中,人和月是不可以替换的,两者不可以相乘。
    
  • Brook法则:向进度落后的项目中增加人手,只会使进度更加落后。

    注: 如果是增加在前期从没有参与到该项目中的人员,就更严重了。
    
  • 向软件项目中增派人手从三个方面增加了项目必要的总体工作量:任务重新分配本身和所造成的工作中断;培训新人员;额外的相互沟通。

  • 团队应该以尽可能多的方式进行相互之间的交流:非正式、常规项目会议,会上进行简要的技术陈述、共享的正式项目工作手册。
  • 项目经理的主要日常工作是沟通,而不是作出决定;文档使各项计划和决策在整个团队范围内得到交流。
  • 项目是怎样延迟了整整一年的时间?…一次一天。
  • 一天一天的进度落后比起重大灾难,更难以识别,更不容易防范和更加难以弥补。

    注:如果当前进度已经晚于预计的时间节点,那么就必须保证不能在到达下一时间节点时,进度仍然是落后的,否则项目就真的可能延迟了一整年了。
    
念念不忘,必有回响