《人月神话》整理

写在前面

实习后,发现自己一些薄弱的点,需要好好加固一些。好在现在又学校可回,索性逃回学校重新修炼,学一些想学的,加固自己薄弱的,至少不要在职场坑了队友。

《人月神话》一书,其主要介绍人/月等方面的项目管理,从项目经理角度对产品的一些想法及经验,帮助对产品的管理有了较深刻的理解。43年前出版至今依然畅销,不仅感叹作者的独特眼光、软件工程发展的缓慢。也使得我对这一学科有了更深的理解。

编程的乐趣

  • 创建事物的快乐
  • 开发对其他人有用的乐趣
  • 将类似可以组装的零部件组装,这个过程本身具有魅力
  • 面对重复任务,不断学习的乐趣
  • 软件的存在形式不同于其他实际物体,工作在轻易驾驭的介质上的乐趣

编程的烦恼

  • 将做事的方式调整到追求完美是最困难的部分
  • 有其他人来设定目标,必须依靠自己无法控制的程序来完成事情
  • 真正的权威来自于每次任务的完成
  • 伴随着枯燥艰苦的劳动
  • 越接近目标收敛越慢
  • 只有实际需要才会想到最新的设想

人月神话

  • 缺乏合理的时间进度是造成项目滞后最主要的原因——比其他原因都大
  • 某些任务在不损害结果的情况下加快速度
  • 所有编程人员都是乐观主义者——“一切都将良好运行”
  • 构思本身就有缺陷,因此总会有bug
  • 人员数量和时间是不可替换的——1个孕妇10月怀胎生子,10个孕妇不可能1个月生子
  • 分解任务会话费额外的时间——培训和相互沟通
  • 进度安排——1/3计划, 1/6编程, 1/4构建测试, 1/4系统测试
  • Brooks法则:为进度落后的项目增加人手,只会似的进度更加落后 —— 重新分配任务的打断;培训新人;额外的沟通

团队的组建

team

  • 小型精干的团队是最好的

  • 一位首席程序员、类似于外科手术队伍的团队架构提供了一种方法—既能获得由少数头脑产生的产品完整性,又能得到多位协助人员的总体生产率,还彻底地减少了沟通的工作量。

  • 结构师的使命

    ​ 结构师只能提出建议,牢记开发人员实现创造性的使命

    ​ 时刻准备为制定说明建议一种实现方法,准备接受任何可行方法

    ​ 对建议保持平静及低调

    ​ 准备对建议改进及坚持放弃

    ​ 听取开发人员在系统结构上的改进

系统的设计

  • 概念的完整性是重中之重

  • “功能与理解上的复杂程度比值才是系统设计最终目标”

  • 将系统结构方面的工作与具体实现分离是获得概念完整性的最好方法

  • 外部的体系结构规定实习上是增强小组的创造性

  • 尽早交流和持续沟通能够使得结构师有较好的成本意识,是开发人员对设计有信心

  • 第二个系统通常是人们所设计的最危险的系统,通常是过分的进行设计

  • 为了概念完整性,设计必须又一个人或者具有共识的小型团队完成,设计结果必须由一个或者两个人来完成,以保证结果一致

  • 必须明确定义系统结构中与先前定义不同的地方,重新定义详细程度应该与之前保持一致

  • 出于精确性,需要形式化的定义,也需要一些记叙性的定义来加深理解

  • 起初至少有两种以上的实现,定义会更加整洁和规范

  • 结构师对实现人员的询问作出电话的解释和问答是非常重要的,必须进行日志整理和发布

项目成功的要点

交流

  • 因为团队之间不知道在做什么,从而出现进度灾难、功能不合理和系统缺陷。由于存在对他人进度的各种假设,团队之间成员开始理解出现偏差
  • 团队应该以尽可能多的方式进行相互之间的交流,非正式的进行简要技术趁熟的常规会议项目,共享的正式项目工作手册【以及电子邮件】

项目工作手册

​ ——是对项目必须产生一系列文档进行的一种组织结构

  • 项目所有文档都是工作手册的一部分
  • 需要尽早仔细的设计工作手册结构
  • 项目成员应该只能看到自己需要的部分,没有人需要或者看到其他部分结构,只需要了解接口
  • 及时跟新十分重要

组织架构

  • 团队的目标是为了减少必要的交流和协作量

  • 为了减少交流,组织结构包括了人力划分及限定职责范围

  • 组织交流应该是网状的,而不是树状的

  • 每个子产品应该具有两个领导角色——产品负责人,技术主管(结构师)

    ​ —— 产品负责人和技术主管可以是同一个人

    ​ —— 产品经理为总指挥,技术主管左右手

    ​ —— 技术主管为总指挥,产品经理左右手

未雨绸缪

  • 软件工程师在着手发布产品之前,应该进行试验性系统的现场测试
  • 第一个开发的系统对于大多数项目可能并不太合用,太多问题,系统的丢弃和重新设计可以一步完成也可以一步步完成,但这是必须完成的步骤
  • 为舍弃而计划,这是无论如何要做的一个步
  • 用户的实际需要会随着程序的构件、测试和使用而变化
  • 由于软件产品易于掌握的特性和不可见性,导致构件人员面临着永恒的需求变更
  • 灵活的组织架构对于软件开发是一个长期有效的解决方案
  • 为变更组建团队比为变更进行设计更加困难
  • 每次修复之后应该重新编译一边系统,确保系统不会因为隐蔽的方式破坏
  • 所有修改都倾向于破坏系统的架构,增加了系统的混乱程度,以至于系统退化到必须重新设计
  • 一次分给某个小组连续的目标时间块被证明是最好的安排方法

项目相关知识点

  • 仅仅通过对编码的部分时间估计,然后乘以其他部分相对系数,是无法得出整个工作精度估计的
  • 构件独立小型程序数据并不适应与编程系统项目
  • 程序开发随程序规模的增大而增长
  • 一些研究报告表明时间指数大约在1.5倍预计时间
  • 相对于其他活动,全职程序员50%时间在用于编程和调试
  • 对于广泛使用的产品,其维护总成本通常是开发成本的40%或更多
  • 用户越多,维护成本越多
  • 缺陷修复总会以20%~50%的几率引入新的bug
  • 大部分系统调试在夜间进行
  • 测试数据应该有一部分校验数据,一部分边界数据,一部分无效数据

项目的文档

1
2
3
4
5
6
7
8
9
10
11
—— 应当包括:

目的:功能是什么,开发原因是什么
环境:运行在怎样的机器
范围:有效输入范围,允许显示格式
实现功能和使用算法:精确阐述它做什么
输入——输出格式:必须确切完整
操作指令:包括控制台输出正确及异常内容
选项:用户功能有哪些,应该怎样进行挑选
运行时间:特定运行时间
精度和校验:期望精度和如何进行精度检测
  • 软件开发关键文档应该包括:目标,用户手册,内部文档,进度,预算,组织机构图和工作空间分配
  • 项目经理应该在项目早期对项目一系列文档进行规范化
  • 对每个关键文档的维护提供状态监督及预警机制
  • 每个文档本身就可以作为检查列表或者数据库
  • 项目经理的主要日常工作是沟通,而不是作出决定;文档使个项目计划和决策在整个团队范围内得到交流
  • 即使是完全开发给自己的程序,描述性的文字也是必须的,因为会被遗忘
  • 文档能在整个生命周期客服克服懒惰和进度压力起促进和激励作用
  • 大多数文档缺少总结性的内容,必须放慢脚步,稳妥进行
  • 为了使文档易于维护,将他们合并到源程序至关重要,而不是独立文档进行保存
  • 程序修改人员所使用的文档之中,出了描述事情如何,还应该阐述为什么那样做,目的非常关键

项目的整体

整体部分

  • 详尽体系结构工作不但使产品更加易用,而且使开发更容易进行,bug更不容易产生

  • 许许多多失败源于产品未精确定义的地方

  • 编写代码之前,规格说明必须提交外部测试小组,以详细的检查说明项目完整性和明确性,否则开发人员会自行摸索

  • 自上而下的设计方式更容易细化,从四个方面减少bug

    —— 清晰结构

    —— 模块分割

    —— 细节的抑制

    —— 测试

  • 大量的辅助性测试代码是有必要的

  • 必须有人对变更和版本进行控制和文档化

  • 系统测试期间,一次只增加一个构件

  • 有时必须回退,推翻顶层设计

祸起萧墙

  • 一天天的进度落后比重大灾难更难以识别
  • 根据一个严格的进度表来控制大型项目,进度表由里程碑和日期组成
  • 里程碑必须是具体的特定的和可度量的事件进行清晰定义
  • 项目没两周进行仔细修订的活动时间估计,随着开始事件到临近结束不会有太大变化,否则过高或过低的估计在项目结束前三周左右才会有所变化
  • 如果错过了一个deadline 确保不会错过第二个deadline
  • 必须有评审机制,使得所有成员可以通过它了解真正的状态,出于这个目的,里程碑的进度和完成文档是关键

软件工程中根本及次要问题

根本困难:

软件开发中最困难的部分是规格说明、设计和测试这些概念上的结构,而不是对概念进行表达和实现逼真程度进行验证

1、复杂度:由多方面形成,不仅仅是由于技术产生困难导致的管理问题,管理层面:全面理解问题变得困难->妨碍概念上的完整性->使所有离散出口难以寻找和控制->引起学习和理解上的负担

2、一致性:由于兼容等问题,导致一致性降低

3、可变性:由于平台变化,应用变化,用户等变化导致软件可变性

4、不可见性:由于软件是不存在具有空间的形体特征,所以很难关联和理解依赖

解决的希望:

1、OO编程:仅仅消除设计表达上的次要困难

2、人工智能、专家系统:接收数据,对系统推论,诊断及构件,建议接口规则,制定测试策略,记录各种bug产生及优化(目前尚未出现?

3、自动编程:通过较少的参数迅速描述特征,给定参数前提,制定清晰规则

4、图形化编程:存在变量范围嵌套,交叉引用等多方面问题

5、程序验证:进行技术规格测试

6、环境和工具:统一接口和通用工具,只是消除语法错误

7、工作站:强大的工作站并不能有魔术般的提高

概念上根本解决方案:

1、购买及自行开发

2、需求提炼和快速原型

3、卓越的设计人员