WCY笔记

  1. 简言之,我相信由于人员的分工,大型编程项目碰到的管理问题和小项目区别很大;我相信关键需要是维持产品自身的概念完整性

    WCYTIP:也是架构师要做的

  2. 职业的乐趣

    1. 编程为什么有趣?作为回报,它的从业者期望得到什么样的快乐?
      1. 【创建事物的快乐】首先是一种创建事物的纯粹快乐。如同小孩在玩泥巴时感到愉快一样,成年人喜欢创建事物,特别是自己进行设计。我想这种快乐是上帝创造世界的折射,一种呈现在每片独特、崭新的树叶和雪花上的喜悦。
      2. 【开发对其他人有用的东西的乐趣】其次,快乐来自于开发对其他人有用的东西。内心深处,我们期望其他人使用我们的劳动成果,并能对他们有所帮助。从这个方面,这同小孩用粘土为”爸爸办公室”捏制铅笔盒没有本质的区别。
      3. 【将可以活动、相互啮合的零部件组装成类似迷宫的东西,这个过程所体现出令人神魂颠倒的魅力】第三是整个过程体现出魔术般的力量—将相互啮合的零部件组装在一起,看到它们精妙地运行,得到预先所希望的结果。比起弹珠游戏或点唱机所具有的迷人魅力,程序化的计算机毫不逊色。
      4. 【面对不重复的任务,不间断学习的乐趣】第四是学习的乐趣,来自于这项工作的非重复特性。人们所面临的问题,在某个或其它方面总有些不同。因而解决问题的人可以从中学习新的事物:有时是实践上的,有时是理论上的,或者兼而有之。
      5. 【工作在如此易于驾驭的介质上的乐趣—纯粹的思维活动,其存在、移动和运转方式完全不同于实际物体】最后,乐趣还来自于工作在如此易于驾驭的介质上。
    2. 程序员,就像诗人一样,几乎仅仅工作在单纯的思考中。程序员凭空地运用自己的想象,来建造自己的”城堡”。
    3. 很少有这样的介质—创造的方式如此得灵活,如此得易于精炼和重建,如此得容易实现概念上的设想。(不过我们将会看到,容易驾驭的特性也有它自己的问题)然而程序毕竟同诗歌不同,它是实实在在的东西;可以移动和运行,能独立产生可见的输出;能打印结果,绘制图形,发出声音,移动支架。
    4. 神话和传说中的魔术在我们的时代已变成了现实。在键盘上键入正确的咒语,屏幕会活动、变幻,显示出前所未有的或是已经存在的事物。
  3. 职业的苦恼
    1. 然而这个过程并不全都是喜悦。我们只有事先了解一些编程固有的烦恼,这样,当它们真的出现时,才能更加坦然地面对。
      1. 【将做事方式调整到追求完美,是学习编程的最困难部分】首先,必须追求完美。因为计算机也是以这样的方式来变戏法:如果咒语中的一个字符、一个停顿,没有与正确的形式一致,魔术就不会出现。(现实中,很少的人类活动要求完美,所以人类对它本来就不习惯。)实际上,我认为学习编程的最困难部分,是将做事的方式往追求完美的方向调整。
      2. 【由其他人来设定目标,并且必须依靠自己无法控制的事物(特别是程序);权威不等同于责任】其次,是由他人来设定目标,供给资源,提供信息。编程人员很少能控制工作环境和工作目标。用管理的术语来说,个人的权威和他所承担的责任是不相配的。不过,似乎在所有的领域中,对要完成的工作,很少能提供与责任相一致的正式权威。而现实情况中,实际(相对于正式)的权威来自于每次任务的完成。
      3. 【实际情况看起来要比这一点好一些:真正的权威来自于每次任务的完成】对于系统编程人员而言,对其他人的依赖是一件非常痛苦的事情。他依靠其他人的程序,而往往这些程序设计得并不合理,实现拙劣,发布不完整(没有源代码或测试用例),或者文档记录得很糟。所以,系统编程人员不得不花费时间去研究和修改,而它们在理想情况下本应该是可靠完整的。
      4. 【任何创造性活动都伴随着枯燥艰苦的劳动,编程也不例外】下一个烦恼—概念性设计是有趣的,但寻找琐碎的bug却只是一项重复性的活动。伴随着创造性活动的,往往是枯燥沉闷的时间和艰苦的劳动。程序编制工作也不例外。
      5. 【人们通常期望项目在接近结束时,(bug、工作时间)能收敛得快一些,然而软件项目的情况却是越接近完成,收敛得越慢】另外,人们发现调试和查错往往是线性收敛的,或者更糟糕的是,具有二次方的复杂度。结果,测试一拖再拖,寻找最后一个错误比第一个错误将花费更多的时间。
      6. 【产品在即将完成时总面临着陈旧过时的威胁】最后一个苦恼,有时也是一种无奈—当投入了大量辛苦的劳动,产品在即将完成或者终于完成的时候,却已显得陈旧过时。可能是同事和竞争对手已在追逐新的、更好的构思;也许替代方案不仅仅是在构思,而且已经在安排了。
    2. 现实情况比上面所说的通常要好一些。当产品开发完成时,更优秀的新产品通常还不能投入使用,而仅仅是为大家谈论而已。另外,它同样需要数月的开发时间。事实上,只有实际需要时,才会用到最新的设想,因为所实现的系统已经能满足要求,体现了回报。
    3. 诚然,产品开发所基于的技术在不断地进步。一旦设计被冻结,在概念上就已经开始陈旧了。不过,实际产品需要一步一步按阶段实现。实现落后与否的判断应根据其它已有的系统,而不是未实现的概念。因此,我们所面临的挑战和任务是在现有的时间和有效的资源范围内,寻找解决实际问题的切实可行方案。
    4. 这,就是编程。一个许多人痛苦挣扎的焦油坑以及一种乐趣和苦恼共存的创造性活动。
    5. 编程非常有趣,在于它不仅满足了我们内心深处进行创造的渴望,而且还愉悦了每个人内在的情感。
  4. 首先,我们对估算技术缺乏有效的研究,更加严肃地说,它反映了一种悄无声息,但并不真实的假设 — 一切都将运作良好

    WCYTIP:工作量、风险估算等必须要有保留,因为一定不会良好运作

  5. 我们采用的估算技术隐含地假设人和月可以互换,错误地将进度与工作量相互混淆

  6. 对于创造者,只有在实现的过程中,才能发现我们构思的不完整性和不一致性。因此,对于理论家而言,书写、试验以及”工作实现”是非常基本和必要的。
  7. 对于软件任务的进度安排,以下是我使用了很多年的经验法则:
    1. 1/3计划
    2. 1/6编码
    3. 1/4构件测试和早期系统测试
    4. 1/4系统测试,所有的构件已完成
  8. 人数和时间的互换仅仅适用于以下情况:某个任务可以分解给参与人员,并且他们之间不需要相互的交流(图2.1)。这在割小麦或收获棉花的工作中是可行的;而在系统编程中近乎不可能。
    1. image.png
  9. 显然我们需要两种解决方案。开发并推行生产率图表、缺陷率、估算规则等等,而整个组织最终会从这些数据的共享上获益。或者,在基于可靠基础的估算出现之前,项目经理需要挺直腰杆,坚持他们的估计,确信自己的经验和直觉总比从期望派生出的结果要强得多
  10. 向进度落后的项目中增加人手,只会使进度更加落后。
  11. 缺乏合理的时间进度是造成项目滞后的最主要原因,它比其他所有因素加起来的影响还要大阿
  12. 两个方面—交流,以及交流的结果—组织。他们无法相互交谈,从而无法合作
  13. 他们发现模块总数量随版本号的增加呈线性增长,但是受到影响的模块数量随版本号呈指数增长。所有修改都倾向于破坏系统的架构,增加了系统的混乱程度(熵)
  14. 带来坏消息的人不受欢迎
  15. 程序文档质量声名狼藉,文档的维护更是低劣:程序变动总是不能及时精确地反映在文档中。我认为相应的解决方案是”合并文件“,即把文档整合到源代码。这对正确维护是直接有力的推动,保证编程用户能方便、即时地得到文档资料。这种程序被称为自文档化(self-documenting)。

    WCYTIP:不追求文档,应该把文档合入代码中(注释中?)

  16. 软件非常难以可视化

  17. 其中的秘密就是逐步发育成长,而不是一次性搭建,增量地开发整个系统(敏捷、迭代)
  18. 一个良好的经验法则是,可重用的构件的工作量是“一次性”构件的两倍 -》因此,我对工作量比率的估计是三倍
  19. “如果要得到系统概念上的完整性,那么必须控制这些概念。这实际上是一种无需任何歉意的贵族专制统治。”

    WCYTIP:架构的规范就是专制,不用问为什么

  20. 团队组织的目标是为了减少必要的交流和协作量

    WCYTIP:不能减少交流和协作的的团队划分,就没有意义,所以讨论团队划分的时候一定要能解决交流和协作的问题

  21. 为了减少交流,组织结构包括了人力划分(division of labor)和限定职责范围(specialization of function)

  22. 传统的树状组织结构反映了权力的结构原理—不允许双重领导
  23. 仅仅通过对编码部分的估计,然后乘以任务其他部分的相对系数,是无法得出对整项工作的精确估计的
  24. 开发人员交付的是用户满意程度,而不仅仅是实际的产品。”(Cosgrove)

    WCYTIP:价值交付意识

  25. 里程碑必须是具体的、特定的、可度量的事件,能进行清晰能定义。

    书评

    作为软件工程的经典著作,《人月神话》的主要贡献是对软件开发过程的几个重要关键点,提出了独到的见解。

    这几个关键内容就是:
    (1)提倡外科手术式的团队组织:
    [在软件开发组织上的过份民主,往往带来的是没有效率和责任,参与其中的人想法太多,层面参差不齐。所以,软件开发的组织,应该借鉴外科手术式的团队方式,有一个主要的负责人,其他人都是分工协作的副手,这样效率最好,结果最好。]
    (2)软件项目的核心概念要由很少的人来完成,以保证概念的完整性:
    [少就是多,项目的定位需要和功能多少的权衡。太多的想法,使项目没有焦点,什么都要放进去,结果什么都做不象;]
    (3)软件开发过程中必要的沟通手段;
    [ 软件开发中最大的风险往往不是技术的缺陷,而是缺少沟通;]
    (4)如何保持适度的文档:
    [ 在开发中,保持适度的文档。喜欢过度多的文档的人,忘记了文档不是最终的产品,不是用户需要的,最后以为文档好,就是好的开发,其实完全不是。]
    (5)在软件开发的过程中,只有适度改进,没有包治百病的银弹。
    [在软件开发的过程中,重要的不是采用了什么工具,而是不论用何种工具,都要达到项目本身的客户需求。任何方法论之前,先要探求问题的来源,否则,对各种方法论的依赖或滥用,有害无益。]