软件工程

本文基于邹欣老师所著《构建之法》整理,并用其它途径获取的知识补充说明。

如果按照经典瀑布模型讲这门课,教学情形是

  1. 需求阶段:学生不知道什么是需求,什么是业务。
  2. 设计阶段:学生画了不少矩形、菱形。
  3. 实现阶段:设计图被扔到一边,学生开始讨论非常细节的问题,测试只存在文档中。
  4. 稳定阶段:学生开始写代码,大部分代码不能工作,测试都无从开始。
  5. 发布阶段:学生还在调试程序,美化 PPT 。
  6. 维护阶段:课程结束,学生放假,不再维护。

最后大部分学生都说这门课没用。

工作情形刚好相反

  1. 维护阶段:由师傅带领维护已有软件。
  2. 发布阶段:修正小 Bug 并发布更新版本。
  3. 稳定阶段:在原软件基础上作少量增减。
  4. 实现阶段:重构小模块。
  5. 设计阶段:有机会设计大模块,并撰写设计文档。
  6. 需求阶段:有机会计划新项目。

与经典瀑布模型相对,这种模式称为“大马哈鱼洄游模型”。显然,按照工作情形来设计课程,效果更佳。

1 概论

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

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

学校希望学生通过软件工程这门课掌握

  1. 能收集推导提炼来源于实际的需求。
  2. 能在预计时间内发布足够好的软件。
  3. 有配套设施使得发布的软件可维护可持续发展。

而企业希望学生通过软件工程这门课掌握

  1. 如何跟不懂技术的客户交流。
  2. 如何在团队内更有效率地工作。
  3. 如何改进缺少文档的老代码。这一点最重要。

2 个人技术和流程

单元测试应该在最基本的功能或参数上验证程序的正确性,例如类,最好由该单元的作者来写。单元测试一定要快。如果软件分层次,那测试也分层次,每次修改后自动测试有修改的层次。

效能分析主要有两种方法

  • 抽样。每间隔一段时间记录当前运行函数,统计估算各函数运行时间。
  • 代码注入。在代码里注入检测代码,输出运行时间。

及时分析,但不要过早优化。

3 软件工程师的成长

  • 积累通用技术技能。
  • 积累通用设计思想。
  • 积累通用职场技能。
  • 收获专业领域经验。
  • 收获专业项目成果。

软件工程师还可以参加职业资格考试,全国统考证书的说服力往往不及顶级大公司相关产品的职业认证。

精通的标准:能发现问题,能解决问题,能分析问题。

4 两人合作

规范代码风格,包括缩进、行宽、括号、分行、断行、命名、下划线、大小写、注释等。

规范代码设计,包括函数、 goto 、错误处理、类与结构体、成员、虚函数、构造析构函数、 new 和 delete 、运算符、异常、类型继承等。

相互复审代码,目的是发现错误、规范代码、传播知识,包括概要、风格规范、设计规范、效能、可读性、可测试性等。

作者称结对编程大有好处,但我持怀疑态度。

5 团队和流程

太多不看。

6 敏捷开发

敏捷开发原则

  1. 通过早期和持续交付有价值的软件,实现客户满意度。
  2. 欢迎不断变化的需求,即使是在项目开发的后期。要善于利用需求变更,帮助客户获得竞争优势。
  3. 不断交付可用的软件,周期通常是几周,越短越好。
  4. 项目过程中,业务人员与开发人员必须在一起工作。
  5. 项目必须围绕那些有内在动力的个人而建立,他们应该受到信任。
  6. 面对面交谈是最好的沟通方式。
  7. 可用性是衡量进度的主要指标。
  8. 提倡可持续的开发,保持稳定的进展速度。
  9. 不断关注技术是否优秀,设计是否良好。
  10. 简单性至关重要,尽最大可能减少不必要的工作。
  11. 最好的架构、要求和设计,来自团队内部自发的认识。
  12. 团队要定期反思如何更有效,并相应地进行调整。

敏捷开发流程

  1. 整理需要做的事情。
  2. 从挑出当前冲刺的目标。
  3. 冲刺,勿扰,问题留到例会讨论。

敏捷开发团队

  1. 一个强有力的项目经理。
  2. 一群有自我管理能力、自我组织能力的全栈工程师。

敏捷开发本质

敏捷开发源自经典开发,大部分早就在实践中运用,只不过因为有人总结经验并抛出了“敏捷宣言”,才形成了一股思潮。宣言令人激动,但它没有带来新的东西,仅仅告诫了人们需要注意什么。事实上许多号称敏捷的项目最终也没敏捷到哪里去。

7 微软解决方案框架

假大空。

8 需求分析

分析需求需要天赋。

9 项目经理

经理项目更需要天赋。

10 典型用户和场景

  • 功能说明书,黑盒说明书
    • 定义好概念
    • 规范好假设
    • 界定边界条件
    • 描述主流交互步骤
    • 坦白副作用
    • 声明服务质量
  • 技术说明书,白盒说明书
    • 抽象
    • 内聚\耦合\模块化
    • 信息隐藏和封装
    • 界面和实现的分离
    • 错误处理
    • 环境和输入要求
    • 变化应对
    • 大量数据的处理能力

功能驱动设计只适合开发不熟悉的业务系统。

11 软件设计与实现

几个有趣的开发阶段情景

  • 闭门造车
  • 每日构建
  • 构建大师
  • 宽严皆误
  • 小强地狱

12 用户体验

用户体验要素

  • 用户的第一印象
  • 从用户的角度考虑问题
  • 软件服务始终都要记得用户的选择
  • 短期刺激和长期影响
  • 不让用户犯简单的错误
  • 用户体验和质量
  • 情感设计

用户体验评价标准

  • 尽快提供可感触的反馈
  • 符合用户的现实惯例
  • 用户有自由控制权
  • 一致性和标准化
  • 适合各种类型的用户
  • 帮助用户识别、诊断并修复错误
  • 有必要的提示和帮助文档

13 软件测试

Test Case 是测试用例, Test Suite 是测试用例集。

按测试的设计分类

  • 黑盒测试
  • 白盒测试
  • 灰盒测试
    • 黑白混合

按测试的目的分类

  • 功能测试
    • 单元测试
      • 代码覆盖率不能衡量优劣
    • 模块测试
    • 集成/场景/系统测试
    • 用户测试
  • 非功能测试
    • 压力测试
    • 性能测试
    • 残障测试
    • 本地化/全球化测试
    • 兼容测试
    • 配置测试
    • 易用性测试
    • 安全测试

按测试的时机分类

  • 冒烟测试
    • 构建测试
  • 验收测试

按测试的方法分类

  • 回归测试
    • 用以往的测试用例测试,避免退化
  • 探索测试
    • 有不同的路线可以到达目的地
  • 伙伴测试
    • 给小组配备常驻测试人员

VSTS 有各种测试套件可供选用。

14 质量保证

软件质量 = 程序质量 + 软件工程质量

不用测试人员的三种原因

  • 人太牛
  • 事太小
  • 人不够

15 稳定和发布阶段

口口声声要求高质量的人士,往往出于下列情况

  • 缺乏对用户、行业、软件开发的洞察力,对高质量没有具体定义。
  • 没有具体招数让软件达到所谓的高质量。
  • 害怕真实世界的反馈,不发布软件,能拖一天是一天。

常用版本名词

  • ALPHA 版本是集成主要功能的内测版,或称技术预览版,或称 CB 。
  • BETA 版本是功能基本完备的外测版。
  • GAMMA 版本是候选发布版,或称 RC 。
  • RTM/RTW/RTO/RTS 最终发布版,刻盘/挂网/运营/上架。
  • ZBB 0 bug 版本,限时修复版。

金丝雀对瓦斯特别敏感。以前旷工们会提着一个装有金丝雀的鸟笼下井,如果金丝雀昏倒,就说明有瓦斯泄露,需要立即撤离。

设计变更 DRC 是一个严肃的任务,要说明变更影响,要比较方案优劣,要新开修改分支。

临近发布,壮士断腕。后续迭代,逐步冻结。

退军时的疑兵之计

  • 我们一定会补上文档的!
  • 我们一定会继续开发的!

16 IT 行业的创新

难。都是无招胜有招。

在机械打字机时代,由于相邻字符的机械臂会发生碰撞,不等不将常用字符拆开,形成 QWERTY 键盘布局,以减小碰撞的几率。后来打字机抛弃了机械臂设计,即使 Dvorak 拥有理论上更好的键盘布局,人们也无意改变已经养成的习惯。

了解技术成熟曲线,谨防不良媒体炒作。

  • 专注于你真正想做的事,也许比较寂寞,因为它不是网上热捧的高科技。
  • 解决天下普罗大众的问题很难,从解决自己的问题、身边的问题开始。
  • 真正做好服务,不管用户有多少,保护用户的数据和隐私,就想你希望别人保护你的隐私一样,不要找借口。
  • 找至少一个伙伴,一起成长。
  • 自我管理,按照自己的节奏来分享体会和成果。
  • 享受工作和生活,当别人询问你的工作职位时,能够情绪稳定地说我自己干。

17 人,绩效和职业道德

有些人虽然对项目具体情况不了解,也很忙,但是项目的一些决定非得由他们来做,而且他们做完决定就拍拍翅膀飞走了。