构建之法——现代软件工程
如何写读后感
发现已经不知道该怎么写这种技术类书籍的读后感了。回顾笔者之前的读后感,或者是札记,都是针对书里面的一个点,去与人对谈,深度剖析、不断思考,最后凝练成一篇长文。但是面对这样的书籍,显然是不太合适的。觉得最好的办法还是“有的放矢”,从巨大的信息密度中选出真正能够“启迪思维”的部分,以一种致用性阅读的方式,先点明重点,在有必要单拎一文讨论之时,再详细讨论。Less is more.
文化,就是当一个人把在学校所学的一切全部忘光之后,留下来的东西。——爱因斯坦
概论
软件工程的目标:在约束条件下创造“足够好”的软件。软件工程不是“De-Bug”的工程。同时 Bug 和 Feature 之间也有区分。那么,软件工程的核心就从“干活”变成“权衡”,实际上就是约束条件下求效能最大值的问题。
软件工程的核心实践能力是研发出符合用户需求(收集、分析、提炼,源于实际)的软件;遵循一定的软件流程(协作、迭代),在预定时间发布“足够好”的软件;能够证明软件具备可维护(测试,文档,Bug 修复记录)、可持续演进(文档对应)。
CS 和 SE 有什么区别?当然在国内其实 CS 和 SE 没有多大差别,要做的东西都差不多,说白了最后都是 408。但是实际上从行业角度而言,差别蛮大的。SE 可以算作 CS 的一个子类。CS 分为:
- 计算机科学理论与基础:计算的本质、什么问题可被计算、需要多少计算资源、如何描述和验证计算过程?(计算思维)
- 核心计算机系统:计算机硬件如何设计、如何工作、如何高效管理资源、计算机如何通信、如何让多计算机协同?(计组 OS 计网)
- 软件工程和信息管理:如何系统高效高质量开发和维护大型复杂软件?如何有效组织检索和管理海量数据?(软件工程)
- 人工智能和智能系统:如何让计算机学习理解感知决策?如何构建能够展现智能的系统?(机器学习 深度学习)
- 交叉领域
个人技术和流程
测试驱动开发(TDD)遵循 RGR(红 - 绿 - 重构)流程,针对功能先写测试,等待编写代码让测试通过后再重构代码。
在设计阶段的时候考虑单元测试,而不是都写好了专门写单元测试。单元测试应当相互独立,每次测试结束后应当处理副作用。单元测试代码跟着产品代码保存和维护。
把单元测试结合起来就可以形成回归测试,成功的回归测试可以确定一个 Baseline,如果新版本劣于 Baseline 还能够回滚。
测试代码覆盖率,分为函数覆盖、语句覆盖、分支覆盖、条件覆盖、MC/DC,其中 MC/DC 是指每一个条件变量都能够独立影响条件判断结果。MC/DC 是很重要的,因为它的要求比 100% 代码覆盖还要严格,能够系统性地发现潜藏的错误。
质量门禁,在 Github 上面配置 Actions 工作流,规定覆盖率阈值,来规避合入质量差的代码。
实践:设计有实际意义和技术挑战的软件工程作业,考虑复杂性(扩展数据规模、扩展需求、扩展用户)和易变性(跨平台、多语言、在线服务的不停机升级),不能简单把所有功能一股脑塞进 main()。