《构建之法》读书笔记

1 概论

软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护上的过程

程序=数据结构+算法; 软件=程序+软件工程; 软件企业=软件+商业模式

关键词

概念 名称
软件架构 Software Architecture
软件设计与实现 Software Design, Implementation and Debug
源代码管理 Source Code Control
配置管理 Software Configuration Management
质量保障 Quality Assurance
需求分析 Requirement Analysis
程序理解 Program Comprehension
软件维护 Sofware Maintenance
服务运营 Service Operation
软件生命周期 Sofware Life Cycle, SLC
软件项目管理 Project Management
用户体验 User Experience
国际化和本地化 Globalization & Localization

知识点

软件的特殊性

  1. 复杂性(Complexity)
  2. 不可见性(Invisibility)
  3. 易变性(Changeability)
  4. 服从性(Conformity)
  5. 非连续性(Discontinuity)

计算机科学与软件工程的不同侧重点
计算机科学:理想化、确定、完美、通用、原创、正确、客观、真理
软件工程:实际、折衷、不确定、成熟、可靠、风险、解决问题

哲学家:我思,故我在

科学家:我发现,故我在

工程师:我构建,故我在

Build To Win 足够好,赢得用户

  1. 用户满意度
  2. 可靠性
  3. 软件流程的质量
  4. 可维护性

2 个人技术和流程

关键词

概念 名称
回归测试 Regression Test
(功能)基准线 Baseline
功能倒退/退化 Regression
代码注入 Instrumentation
本函数时间 Exlusive Time
所有时间 Inclusive Time
个人软件开发流程 PSP(Personal Software Process)
单一职责原则 SRP(Single Responsibility Principle)

知识点

好的单元测试标准

  1. 必须由最熟悉代码的人来写
  2. 单元测试后,机器状态保持不变
  3. 单元测试要快
  4. 产生的结果可重复、一致
  5. 独立性,结果不依赖别的测试
  6. 覆盖所有的代码路径
  7. 集成到自动测试框架
  8. 必须和产品代码一起保存

PSP阶段

  1. 计划
  2. 开发(需求,设计,评审,代码规范,具体设计,编码,代码复审,测试)
  3. 报告(测试,计算工作量,总结)

3 软件工程师的成长

关键词

概念 名称
代码行数 Line Of Code, LOC
功能点 Function Point
团队软件流程 Team Software Process, TSP

知识点

初级软件工程师的成长

  1. 技术技能
  2. 问题领域的知识和经验
  3. 对软件设计、工程思想的理解
  4. 职业技能(自我管理,表达和交流,合作,质量)
  5. 实际成果

工作量和质量如何衡量

  1. 项目/任务多大(LOC,FP)
  2. 花了多少时间(人月)
  3. 质量如何(给测试,给顾客,bug数量/KLOC)
  4. 是否按时交付(稳定,一致更重要)

软件领域可以分为两个方面:一方面是技艺创新的大爆发;而另一方面是坚持不懈的工程工作,包括软件的改善、维护和测试等,这一方面占了90%~95%。
一个成熟的软件工程师应该能够降低任务交付时间的标准方差。如果你能长时间稳定而按时地交付工作的结果,内部和外部的顾客就会对你的工作有信息,更喜欢与你合作。

团队对个人的期望

  1. 交流
  2. 说到做到
  3. 接受角色并按要求工作
  4. 全力投入团队工作
  5. 按照团队流程的要求工作
  6. 做好准备工作(开始新功能之前,讨论之前)
  7. 理性的工作(按流程,今天继续昨天的,明天继续今天的,终会有所成就)

软件工程师的思维误区

  1. 分析麻痹(弄清楚所有细节)
  2. 不分主次,想解决所有依赖
  3. 过早优化
  4. 过大扩大化/泛化

软件工程师的职业发展

  1. 临时的寄托或工作
  2. 工作
  3. 职业(Profession)
  4. 投身的事业(Commitment/vocation)
  5. 理想的呼唤(Calling)

4 两人合作

4.2 代码风格规范

简明,易读,无二义性

具体的:

  1. 缩进:4个空格
  2. 括号
  3. 断行与独占一行的{}
  4. 分行:不要把多个变量定义在一行
  5. 命名要有意义,和简洁
  6. 驼峰与下划线的使用
  7. 注释有意义

4.3 代码设计规范

  1. 一个函数只做一件事
  2. 错误处理:验证参数,断言
  3. 异常处理

4.4 代码复审

目的:

  1. 找出错误:不符合团队代码规范,编码错误
  2. 发现逻辑错误
  3. 发现算法错误:优化,边界条件
  4. 发现潜在错误或者回归性错误
  5. 发现可能需要改进的地方
  6. 教育,传授经验

步骤:

  1. 代码必须先成功编译
  2. 开发者必须先自测过
  3. 提交PR,能看到差异
  4. review的人有权提问题
  5. 开发者有义务解答
  6. 开发者需要让所有的问题有满意的解答
  7. 达成一致:打回去,有条件同意(小问题修改后可以直接签入),放行
  8. 记录:更正错误的commit记录,无法修正的bug记录,常犯错误的经验记录

核查内容

  1. 概要部分:是否符合需求,设计是否周全,可读性,可维护性,每一行是否都检查过
  2. 设计规范:遵循设计模式,是否有硬编码字符串,是否依赖新的平台,是否重复造轮子,是否有无用代码可以清理
  3. 代码规范:风格符合标准
  4. 具体代码:是否有错误处理,边界条件检查,是否使用断言、异常,资源的占用是否释放,数据结构是否有用不到的元素
  5. 效能:是否有明显可优化,调用超时如何处理
  6. 可读性:注释,命名
  7. 可测试性

4.5 结对编程

类似越野赛车和驾驶飞机,有一个驾驶员和一个领航员

好处:

  1. 更好的设计与代码质量,互相激励,看到别人的思路和技能,实时讲解,更多创意
  2. 带来更多信心、质量和满足感
  3. 管理上,更有效交流和传递经验,分享知识,更好应对人员流动

不间断复审:
1 传统review人对代码不一定了解,不能持久,对需求不完全了解,理解程度不一致;
2 而结对编程,责任不是某个人,而是两个人,是团队,建立集体意识,避免个人英雄主义。
3 编码不再是私人工作,是一种公开的表演:代码,工作方式,技术水平

如何操作:
1 设计文档
2 每小时休息15分钟
3 主动参与
4 只有水平上的差距,没有级别的,平等的决策权

不适合结对编程的:

  1. 探索阶段,需要一个人长时间独立钻研
  2. 后期维护,技术含量不高
  3. 验证测试要很长时间的
  4. 人员要多线程工作,结对反而影响效率的

4.6 合作不同阶段和技巧

如果软件工程师连一对一的合作都做不好,不能【有效】影响同伴,让合作双方都能从合作中受益,提高水平,那大家就别扯什么团队合作的事情了。

影响他人的方式

  1. 断言(感情)
  2. 桥梁(逻辑)
  3. 说服(逻辑)
  4. 吸引(感情)

如何正确给反馈,三种层次:

  1. 最外层:行为和后果(因为,导致了,影响是**)
  2. 中间层:习惯和动机(你是故意的,怎么又搞破坏)
  3. 最内层:本质和固有属性(自私性格,性别,种族,国籍)

建议的【三明治】方法:

  1. 先来面包:强调共同点,让对方处于安全的环境
  2. 放上肉:反馈意见,不要造成【你就是做的不好,我恨你】的情绪,而是强调【过去你做的不够,但是我们以后可以做的更好】,着重于【行为和后果】
  3. 再来一片面包:呼应开头,鼓励把工作做好

5 团队和流程

概念 名称
统一流程 Rational Unified Process, RUP
最小可行产品 Minimal Viable Product, MVP
最强最美产品 Maximal Beautiful Product, MBP
TSP原则 Team Software Process, TSP

主要是讲历史和之前不好的团队模式和工作流程

软件团队的模式

功能团队模式(Feature Team)

开发流程

  1. RUP统一流程:业务建模,需求,分析和设计,实现,测试,部署,配置和变更管理,项目管理,环境
    1. 四个阶段:初始阶段,细化阶段,构造阶段,交付阶段
  2. 渐进的交付流程

TSP的原则

  1. 使用妥善定义的流程,流程中的每一步都是可以重复、衡量的
  2. 团队各个成员对团队的目标,角色,产品都有统一的理解
  3. 使用成熟的技术和做法
  4. 多收集数据,理性决定
  5. 制定切合实际的计划和承诺
  6. 增加团队自我管理能力
  7. 专注于提高质量,办法是做全面而细致的设计工作

6 敏捷流程

沉默成本

简介

一系列价值观和方法论的集合

原则:

  1. 尽早&持续交付有价值的软件满足客户需求
  2. 欢迎需求变化,并利用变化提高竞争优势
  3. 经常发布可用的软件
  4. 业务人员和开发人员在开发过程应该每天共同工作
  5. 充分支持和信任有进取心的人
  6. 面对面交流
  7. 可用软件才是衡量指标
  8. 可持续
  9. 不断关注技术和设计
  10. 保持简明:尽可能简化工作量的技艺
  11. 自我管理
  12. 总结如何提高团队效率

步骤:

  1. 找出要做的事情:Backlog
  2. 决定当前冲刺要做的事情:Sprint Backlog
  3. 冲刺(每日例会,Kanban)
  4. 得到增量版本,发布给用户,进一步计划

问题和方法

定义好任务是什么,任务的完成(Done)是什么,完成任务还需要多少时间。

已经花了多少时间固然重要,但不是关键(这是沉没成本),关键是看离目标有多远。

最后的20%往往花费80%的时间。

总结与教训

戴明环PDCA(Plan Do Check Act/Adjust)

教训:

  1. 敏捷宣言不必当做圣旨或者教条
  2. 复杂的项目里,让一线团队成员做决定
  3. 不要和管理层谈流程,要谈结果

问答

Agile(敏捷)是一股思潮、价值观,有名的方法论:

  1. 爱抚弟弟(FDD feature driven design)
  2. Scrum
  3. 极限编程(XP)
  4. 踢弟弟(TDD test driven development)
  5. 对比:
    1. Agile(敏捷)容忍经常出错,变化,人数不多,不能开发火箭
    2. Plan-Driven(计划驱动),较高可靠性,不经常变化,人数较多,崇尚秩序,用户受不了1~2周更新一次
    3. Formal Method(形式化的开发方法),极高可靠性,精益求精,用户关系的是99.999%
  6. 左项与右项,升级的敏捷
    1. 不仅要让软件工作,更要精益求精
    2. 不仅要响应变化,更要稳步增加价值
    3. 不仅要有个人与交互,更要形成专业人士的社区
    4. 不仅要与客户合作,更要建立卓有成效的伙伴关系