软件工程之美

开篇词

开篇词 | 你为什么应该学好软件工程

  • 书推荐

    • 项目管理

      • 《项目管理修炼之道》

      • 《项目管理 - 计划、进度和控制的系统方法》

      • 《软件项目成功之道》

      • 《做项目,就得这么干!》

    • 软件工程

      • 《构建之法》

        • 多所高校进行了软件工程的教学实践,在此基础上对软件工程的各个知识点和技能要求进行了系统性整理,形成教材。

      • 《人月神话》

        • 关注 “软件开发” 本身

      • 《人件》

        • 关注软件开发中的 “人”

      • 《知行合一: 实现价值驱动的敏捷和精益开发》

        • 书写的特别接地气,文章有很多真实案例,对敏捷开发和 CMMI 都有很深入描述

      • 《软件工程 —— 实践者的研究方法》

        • 大部分高校采用的软件工程标准教材

        • Software Engineering – A Practitioner’s Approach

        • 作者是 Roger S. Pressman

      • 《持续交付》

        • 如何实现更快、更可靠、低成本的自动化软件交付,描述了如何通过增加反馈,并改进开发人员、测试人员、运维人员和项目经理之间的协作来达到这个目标。

      • 《走出软件作坊》

        • 生动的描述了国内小型 IT 企业在发展过程中遇到的一系列项目管理问题,以及作者是如何去解决这些问题的。

      • 其他

        • 〖大道至简〗

        • 机械工业出版社出的《软件工程》

          • 作者是 Ian Sommerville

    • 敏捷相关

      • 《敏捷实践指南》

      • 《敏捷武士》

      • 《高效程序员的 45 个习惯》

      • 《敏捷革命》

结束语

  • 提升代码的质量

      1. 架构设计:好的架构设计,降低实现的复杂度;

      1. 自动化测试:通过自动化测试和持续集成,将 Bug 发现在摇篮中;

      1. 代码审查:通过代码审查,让水平高的带动水平低的,水平低的学习水平高的,从而提升团队整体的代码质量。

基础理论 (9 讲)

01 | 到底应该怎样理解软件工程?

  • 定义

    • 为研究和克服软件危机而生

    • 1968“软件危机”讨论会

      • 为了经济地获得在真实机器上可靠、高效工作的软件而制定和使用的合理工程原则

      • Software engineering is the establishment and use of sound engineering principles in order to obtain economically software that is reliable and works efficiently on real machines.

    • 1993 年,电气电子工程师学会(IEEE)

      • 将系统化的、规范的、可度量的方法用于软件的开发、运行和维护的过程,即将工程化应用于软件开发中

      • The application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software; that is, the application of engineering to software.

    • 本质

      • 用工程化方法去规范软件开发,让项目可以按时完成、成本可控、质量有保证

  • 演化史

    • 瀑布模型

      • 演化:试图改善瀑布模型存在的一些缺陷。即:缩短项目周期,快速迭代

        • V 模型

        • 原型设计

        • 增量模型

        • 螺旋模型

    • 敏捷开发

      • Scrum

      • 极限编程

      • 用户故事

      • 持续集成

    • 云计算、微服务

  • 总结

    • 软件工程的核心,就是围绕软件项目开发,对开发过程的组织,对方法的运用,对工具的使用。

    • 具备基本的工程思维

      • 模块化思维

      • 抽象思维

    • 具备一些关键的意识

      • 质量意识

      • 风险意识

      • 交付意识

02 | 工程思维:把每件事都当作一个项目来推进

  • 定义

    • 软件工程是一门用工程化方法解决软件项目问题的学科,其本质也是一门工程学科

    • Everything is a project

    • 把一件事情分成几个阶段:分析、设计、实施、测试、完成

  • 工程方法

    • 定义

      • 有目的、有计划、有步骤地解决问题的方法就是工程方法

    • 工程方法通常会分成六个阶段:想法、概念、计划、设计、开发和发布

      • 想法:想法阶段通常是想要解决问题。最开始问题通常是模糊的,所以需要清晰地定义好问题,研究其可行性,检查是否有可行的解决方案。

      • 概念:概念阶段就是用图纸、草图、模型等方式,提出一些概念性的解决方案。这些方案可能有多个,最终会确定一个解决方案。

      • 计划:计划阶段是关于如何实施的计划,通常会包含人员、任务、任务持续时间、任务的依赖关系,以及完成项目所需要的预算。

      • 设计:设计阶段就是要针对产品需求,将解决方案进一步细化,设计整体架构和划分功能模块,作为分工合作和开发实施的一个依据和参考。

      • 开发:开发阶段就是根据设计方案,将解决方案构建实施。开发阶段通常是一个迭代的过程,这个阶段通常会有构建、测试、调试和重新设计的迭代。

      • 发布:将最终结果包括文档发布。

  • 工程思维

    • 本质上是一种思考问题的方式,在解决日常遇到的问题时,尝试从一个项目的角度去看待问题、尝试用工程方法去解决问题、站在一个整体而不是局部的角度去看问题。

  • 站在整体而非局部去看问题

    • 用工程方法去处理事情,有两点好处

      • 有一个被有效论证过的方法论指导你,可以帮助你提高成功概率,也可以提高效率。

      • 当你用工程方法去思考的时候,你会更多的站在整体而非局部去思考,更有大局观。

    • 问题的核心

      • 并不在于是不是用工程方法,而是有没有把这件事当作一个项目,是不是能看到这件事的全貌,而不是只看到局部。

03 | 瀑布模型:像工厂流水线一样把软件开发分层化

  • 瀑布模型把整个项目过程分成了六个主要阶段

    • 一、问题的定义及规划

      • 需求文档和可行性研究报告

    • 二、需求分析

      • 需求分析文档

    • 三、软件设计

      • 架构设计文档

    • 四、程序编码

      • 程序代码

    • 五、软件测试

      • 测试报告

    • 六、运行维护

      • 使用说明文档

  • 文档的目的主要是两点

      1. 写文档的过程中帮助你梳理清楚逻辑

      1. 写出来的文档是要用来沟通的,让其他人通过文档明白你的思路

04 | 瀑布模型之外,还有哪些开发模型?

  • 快速开发快速改

    • 快速原型模型

      • 为了要解决客户的需求不明确和需求多变的问题

      • 优点

        • 原型模型因为能快速修改,所以能快速对用户的反馈和变更作出响应,同时原型模型注重和客户的沟通,所以最终开发出来的软件能够真正反映用户的需求。

      • 缺点

        • 这种快速原型开发往往是以牺牲质量为代价的

      • 特点

        • 快速、低质量

      • 两种处理策略

        • 抛弃策略和附加策略

  • 大瀑布拆小瀑布

    • 增量模型 —— 按模块分批次交付

      • 根基是模块化

        • 如果系统不能模块化,那么将很难采用增量模型的模式来开发

        • 对模块的划分很抽象,这本身对于系统架构的水平是要求很高的

      • 适用于

        • 需求比较清楚,能模块化的软件系统,并且可以按模块分批次交付

    • 迭代模型 —— 每次迭代都有一个可用的版本

      • 定义

        • 每次只设计和实现产品的一部分,然后逐步完成更多功能

        • 每次设计和实现一个阶段叫做一个迭代

      • 说明

        • 在一个迭代中都会包括需求分析、设计、实现和测试,类似于一个小瀑布模型。迭代结束时要完成一个可以运行的交付版本。

      • 最难的部分

        • 在于规划每次迭代的内容和要达到的目标

    • 区别

      • 增量模型是按照功能模块来拆分;而迭代模型则是按照时间来拆分,看单位时间内能完成多少功能。

05 | 敏捷开发到底是想解决什么问题?

  • 敏捷宣言

    • 内容

      • 个体和互动高于流程和工具

      • 工作的软件高于详尽的文档

      • 客户合作高于合同谈判

      • 响应变化高于遵循计划

    • 背景

      • 软件工业具备轻资产、知识密集型、从业人员素质高等特点

      • 充分发挥人的创造力和价值,是其相较传统工业更高阶的要求

      • 加之软件工程面对的不确定性与复杂度更显著

  • 定义

    • 敏捷宣言

      • 敏捷不是一种方法论,也不是一种软件开发的具体方法,更不是一个框架或过程,而是一套价值观和原则

    • 当你开发做决策的时候,遵守了敏捷开发的价值观和原则,不管你是不是用 Scrum 或者极限编程,那么都可以算是敏捷开发

      • 各种敏捷框架、方法论和工具,就像是“术”,告诉你敏捷开发的方式,而敏捷则是“道”,是一套价值观和原则,指导你在软件项目开发中做决策。

  • 想解决的问题

    • 瀑布模型的典型问题

      • 周期长

      • 发布烦

      • 变更难

    • 敏捷开发

      • 快速迭代

      • 持续集成

      • 拥抱变化

    • 有苛刻的条件要求

      • 需要客户紧密配合,可以方便确认需求

  • 实践

    • 操作

      • 通过用户故事,理解用户需求

      • 在迭代中采用渐进的架构设计

      • 定期重构解决技术债务

      • 功能开发的同时编写自动测试代码

      • 自动化持续构建

    • 本质

      • 由于淡化了部分工业思维中兼顾稳定、质量、效率、成本的传统手段,敏捷思想的最终落地,需要素质极高的从业人员参与其中,且数量不宜过多,以此来弥补流程上的缺失。

      • 同时要团队与客户紧密协作,上级的充分信任,才能够有效发挥其灵活应变,又万变不离其宗的优势。

      • 这是大胆的返璞归真,好似回到了瀑布模型前的蛮荒时代,实则是更高级的打法,就像独孤九剑一般。所以,敏捷开发“道”的属性更浓。

    • 新人的传承

        1. 团队要有自己的知识库或WIKI,常用的知识要花时间整理上去,这样新人来了可以自己查

        1. 先给他简单的任务,再慢慢稍微复杂一点,给予必要的指导,做中学是最快速有效的

        1. 遇到一些典型的问题可以通过结对编程的方式带着一起做

    • 项目文档有两个主要目的

      • 帮助写的人理清楚思路

      • 用来交流沟通

      • 文档的关键不是细,而是达到文档的写作目的

        • 至于粒度,可以站在文档读者的角度,结合日常开发维护场景,去思考这个文档

  • 推荐书籍

    • 《用户故事与敏捷方法》

    • 敏捷武士︰看敏捷高手交付卓越软件》

    • https://mp.weixin.qq.com/s/puMNz91hiQgio4wSCIrTgQ

    • http://www.woshipm.com/user-research/553736.html

06 | 大厂都在用哪些敏捷方法?(上)

  • 参考

    • 文章

      • 《敏捷开发的根本矛盾是什么?从业十余年的工程师在思考》

      • 阮一峰

        • 《Git 工作流程》

        • 《持续集成是什么?》

      • 《Code Review最佳实践》

        • https://www.cnblogs.com/dotey/p/11216430.html

  • 和敏捷开发相关的主要流程规范

    • 关键定义

      • Scrum Master

        • 处理对外的对内的杂事,保证其他人可以专注的工作

      • 问题停车场

        • 需要进一步讨论的问题暂时集中地,以防止干扰正常站立会议

      • Backlog(任务清单)

        • 未进入本次迭代的任务集中地

      • Sprint(迭代)

        • ToDo

        • In Progress

        • Done

      • Ticket(Issue,任务)

        • 所有与开发相关的任务也都和 Ticket 挂钩

        • 举例

            1. 报一个 Bug,提交一个 Ticket

            1. 提一条需求,提交一个 Ticket

            1. 要重构一下代码,提交一个 Ticket

        • 一切以Ticket为准

          • 不用担心问题被遗忘,会被跟踪,直到被解决或决定不解决

    • Git&CI

      • master(主干)

      • 代码审查(Code Review)

      • 自动化测试

      • PR(Pull Request,合并请求)

      • CI (持续集成)

        • 步骤

          • 检查代码格式是不是符合规范

          • 运行单元测试代码

          • 运行集成测试

    • 每日站立会议

      • 重点是要高效沟通反馈

      • 三个话题

          1. 成员轮流发言

          • 昨天干了什么事情,今天计划做什么事情,工作上有没有障碍无法推进

  • 实践

    • DevOps三个关键优点

        1. 高度自动化

        1. 透明可量化

        1. 紧密协作

    • 开发写的集成测试和测试写的自动化测试区别

      • 开发是用程序模拟的操作的模拟的固定数据

      • 测试用的是真实的数据真实的环境

07 | 大厂都在用哪些敏捷方法?(下)

  • 小组标准配置 7 人

    • 说明

      • 4 个程序员(至少有一个资深程序员,有架构能力)

      • 1 个产品经理(Scrum 里面叫 Product Owner)

      • 1 个测试

      • 1 个项目经理(Scrum 里面叫 Scrum Master)

    • 分工

      • 产品经理:写需求设计文档,将需求整理成 Ticket,随时和项目成员沟通确认需求;

      • 开发人员:每天从看板上按照优先级从高到低领取 Ticket,完成日常开发任务;

      • 测试人员:测试已经部署到测试环境的程序,如果发现 Bug,提交 Ticket;

      • 项目经理:保障日常工作流程正常执行,让团队成员可以专注工作,提供必要的帮助,解决问题。

        • 呵护 develop team 的保护神

        • 其中一个职责是保护每一次迭代的工作量是 dev team 能按时完成的,而且保护 dev team 能专注于现有 sprint back log 的实现,不会被其他干系人的新需求所打断

    • 时间点

      • 每日早上站立会议

      • 每周五分支切割

      • 每周一部署生产环境

      • 每周二开迭代回顾会议,总结上个 Sprint

      • 每周四迭代规划会,计划下周工作

  • 结对编程(英语:Pair programming)

    • 一种敏捷软件开发的方法,两个程序员在一个计算机上共同工作。 一个人输入代码,而另一个人审查他输入的每一行代码。 输入代码的人称作驾驶员,审查代码的人称作观察员(或导航员)。 两个程序员经常互换角色。

08 | 怎样平衡软件质量与时间成本范围的关系?

  • 软件项目管理金三角

    • 时间

    • 成本

    • 范围

    • 做产品想“多、快、好、省”都占着,是不可能的

  • 极限编程(eXtreme Programming,XP)

    • 敏捷开发主流的工程实践方法

    • 极限编程的“极限”(Extreme),意思就是如果某个实践好,就将其做到极限

      • 如果做测试好,就让每个开发人员都做测试 ;

        • 自动化测试

      • 如果集成测试重要,就每天都做几次测试和集成 ;

        • 持续集成

      • 如果简单的就是好,那么我们就尽可能的选择简单的方法实现系统功能 ;

        • 重构

  • MVP(minimum viable product,最小化的可行性产品)模式

    • 一种快速推出产品的模式

      • 一开始只推出最核心的功能,满足用户最核心的需求,然后在用户的使用过程中收集反馈,进一步升级迭代

  • 总结

    • 平衡好软件质量与时间成本范围的关系并不难,你只需要记住,最重要的是根据“金三角”的三条边,找出来固定的一条或两条边,然后去调整剩下的边,达到平衡

    • 重构策略

      • 架构设计上,一定要定期需要重构,优化设计

        • 不然后续新需求效率会降低,包括代码上也会越来越臃肿

      • 每 1-2 年会有一次大的架构升级调整

      • 日常每隔几周会有小的架构优化

项目规划篇 (8 讲)

09 | 为什么软件项目普遍不重视可行性分析

  • 软件项目的可行性研究

    • 经济可行性

      • 从成本和收益角度分析,看投入产出比

      • 不仅要分析短期利益,还要分析长期利益,看是不是值得做

    • 技术可行性

      • 如果有技术上解决不了的问题又能否规避

    • 社会可行性

      • 涉及法律、道德、社会影响等社会因素

  • 可行性分析更多维度

    • 政治(Political)

    • 经济(Economic)

    • 社会(Sociological)

    • 科技(Technological)

    • 法律(Legal)

    • 环境(Environmental)

  • 如果可行性研究并不能给你一个很明确的结果,也可以考虑小范围试点,先实现一个最小化可行产品,等验证了可行性,再逐步加大投入。

  • 实践

    • 扑克牌为什么是个好机制

        1. 公平合理,每个人都有机会不受他人影响的表达

        1. 不用背锅,估错了也没关系,意见不一致还可以讨论

10 _ 如果你想技术转管理,先来试试管好一个项目

  • 技术人员转型管理的障碍

    • 专注技术实现,沉浸于细节中,而忽视了其他事情

      • 要钻研技术,这些是非常好的优点

      • 要转管理,这反而会是一种障碍

    • 管理,最重要的一点就是大局观,要能从整个项目的角度,从整个团队的角度去思考,去确定方向,去发现问题,对问题及时解决及时调整。

  • 怎么样去管理一个软件项目

    • “道” 就是管好人、管好事

    • 管好软件项目中的人

        1. 管理好客户的预期

        • 质量达标:交付产品是高质量的,满足客户需求的。

        • 完整交付:按照约定的功能范围交付最终产品。

        • 按时交付:项目按照客户认可的进度完成。

        • 预算之内:在预算内完成项目。

        1. 管理好项目成员(流程和规范)

        • 好的项目管理,不需要直接去管人,而是管理好流程规范

        • 项目成员不需要按照项目经理的指令做事,而是遵循流程规范。

    • 管好软件项目中的事

        1. 选择适合项目的开发模式

        • 瀑布模型

        • 敏捷开发

        1. 制定好项目计划

        • 工作分解结构

        • 估算时间

        • 排任务路径

        1. 对计划进行跟踪和控制,同时做好风险管理

        • 跟踪计划

        • 调整计划

        • 风险管理

  • 技术转管理的一些经验教训

    • 控制你想写代码的冲动

      • 如果你带的项目进度吃紧时,你要做的不是去写代码,而是去帮助团队从其他角度想办法

      • 写不写代码是管理风格的一部分

        • 要把握好度

        • 重点是要有全局视角

    • 团队的成功,才是你的成功

      • 不是你把上级的工作做了就能升职

      • 而是你的下级都成长了,能替代你的位置了,你就可以升职了

    • 形成自己的管理风格

      • 根据自己的特点,找到适合自己的管理风格

    • 坚持就是胜利

  • 实践

    • 技术转管理心得

      • 站在全局考虑问题

        • 张一鸣说“工作时不分哪些是我该做的,哪些是我不该做的”

        • 做事不设边界,才能有更大的成长,而这些对管理来说尤为如此

      • 流程规范

        • 先重点、全局,慢慢一步步优化

        • 每周进步一点,强调其中1、2点规范

    • 培养出来的下属替代你怎么办?

      • 看长远些

        • 人生不只是一个下属不只是一个老板也不只是一个项目

      • 提高自己

        • 能培养好一个下属还能培养更多的下属

        • 能做好一个项目还能做好更多项目

        • 不需要靠一个老板的赏识与否来证明自己

    • 架构师和管理

      • 相同

        • 都需要大局观

        • 都需要好的沟通能力,让团队清晰的理解自己的意图

        • 都需要用好流程和工具

        • 都要善于 “分而治之”,把复杂的问题拆分成小的具体的问题

      • 不同

        • 项目经理更多的是跟人打交道,对项目负责

        • 架构设计更多是专注技术,对架构负责

    • 如何做到和组员目标一致性

      • 多一对一沟通

        • 了解组员想法

        • 让组员知道你的期望

      • 建立激励机制

11 _ 项目计划:代码未动,计划先行

  • 计划的重要性

    • 没有计划,你的项目可能会陷入一种无序和混乱中

      • 计划,就像我们出行用的导航

      • 可以清楚地看到项目整体的安排

      • 时刻提醒我们目标是什么,不要偏离方向

    • 光有目标还不够的

      • 必须得要付诸行动

        • 需要对目标进行分解,进而变成可以执行的计划

  • 如何制定计划

    • 第一步:任务分解

      • 任务分解:专业词汇叫 WBS

        • 工作分解结构(Work Breakdown Structure, WBS)

        • 定义:把要做的事情,按照一个树形结构去组织,逐级分解,分割成小而具体的可交付结果,直到不能再拆分为止

    • 第二步:估算时间

      • 有很多方法可以参考,主要还是得依靠以前的经验

      • 要想估算准确

        • 任务拆分的越细致,想的越清楚,就能估算的越准确。

        • 要让负责这个任务的人员参与估算。

    • 第三步:排任务路径

      • 排路径就是要根据任务之间的关系,资源的占用情况,排出合适的顺序

    • 工具

      • MS Project

    • 注意

      • 制定计划时不要担心不够准确

      • 先有一个基本的计划,可以粒度比较粗,不那么准确,让事情先推进起来。

  • 设置里程碑

    • 里程碑的时间点确定后,计划可以灵活调整,但里程碑一般不会轻易改变,因为里程碑代表着一份承诺。

    • 对于项目成员来说,有两个重要的影响

      • 一方面,成员会有很明显的来自 DeadLine 的进度压力,自古 DeadLine 就是第一生产力

      • 另一方面,就是在里程碑完成后,大家会获得一种正面激励

    • 示例

      • 第一个时间点就是确定和 PC 客户端的通信协议,这样 PC 客户端可以根据这个协议开始开发功能了;

      • 第二个时间点就是服务端开发完成,PC 客户端可以服务端联调了;

      • 第三个时间点就是测试验收通过,可以上线了。

  • 计划需要跟踪和调整

    • 跟踪进度的方式主要有两种

      • 一种是项目经理定期收集跟踪

      • 一种是项目成员主动汇报

    • 意义

      • 通过对项目计划的跟踪,可以很容易的看出来执行的情况,也会发现偏差

        • 计划出现偏差是很常见的,所以需要定期进行调整,也不需要太频繁,例如可以每周一对计划做一次调整

  • 总结

    • 项目计划是保障软件项目成功非常重要的手段

      • 制定计划的过程,可以让你对项目有全面的了解

      • 跟踪计划让你知道项目进展情况,出现问题也可以及时调整

    • 将任务分解、估算时间、排路径,三步就可以制定出一个项目计划

      • 制定计划不要追求完美,制定好一个初步计划后,就可以先按照计划推进起来,进行过程中还可以继续调整细化。

      • 设置里程碑可以有效的保证项目的按时交付。

    • 生活中每件事都可以当作一个项目,都可以去制定计划来帮助你实现目标。

  • 实践

    • 总结

      • 计划一定是要有的,不然就完全不可控了

      • 计划一定是个迭代的过程,计划也是个粗到细的过程。

        • 一开始不建议特别细的计划,整体粗一点,定好大的时间节点,也就是里程碑,然后对于下一阶段的计划细化。

      • 细化过程中要拉上具体参与的人一起制定

        • 这样结果才科学也不会导致抵触。

      • 里程碑定了后不要轻易变

        • 不然就失去了DeadLine的意义,即使变也不能过于随意和频繁。

    • 项目组成员进度出现偏差了,要怎么调整

      • 最基本的原则就三条:

          1. 恢复生产

          1. 总结原因

          1. 防患未然

12 _ 流程和规范:红绿灯不是约束,而是用来提高效率

  • 流程规范的意义

    • 定义

      • 约束了如何做一件事

      • 约束了用什么标准做事

      • 约束了用特定的顺序做事

    • 提升团队效率

      • 从个体来看,流程规范的存在,确实可能存在效率降低的情况

      • 从团队的角度来看,好的流程规范反而是提升效率的

    • 将好的实践标准化流程化,让大家可以共享经验

    • 借助流程规范,让项目管理从人治到“法治”

      • 好的项目管理,不需要直接管人管事,而是管理好计划和流程规范

      • 项目成员不需要按照项目经理的指令做事,而是遵循计划和流程规范

  • 如何制定好流程规范

    • 制定流程规范的四个步骤

      • 第一步:明确要解决的问题

      • 第二步:提出解决方案

        • 参考借鉴软件工程中,大家公认的好的实践

          • 敏捷开发的流程

          • 代码规范

            • Airbnb JavaScript Style Guide

            • Google Java Style Guide

            • .NET Guide

          • 源代码管理流程

            • Github 官方出品的《Understanding the GitHub flow》

            • Gitlab 官方推荐的《Introduction to GitLab Flow》

            • 阮一峰老师

              • 《 Git 使用规范流程》

              • 《Git 工作流程》

              • 《Git 分支管理策略》

          • 部署流程

      • 第三步:达成共识,推广执行

        • 只有大家认可,达成共识,才能共同遵守,保障制度的执行

        • 配合一些奖惩制度,以保障其执行

          • 流程规范的执行和绩效考评挂钩

      • 第四步: 持续优化,不断改进

    • 将流程规范工具化

      • 应该尽可能借助技术手段来推动甚至替代流程规范

        • 例:go fmt

        • “软件工程”和“质量工程”需要依靠架构技术,而不是依靠 CMM 和 QA 管理流程。

        • 一切工程问题,首先要思考能否通过技术解决,当前技术无法解决的问题,暂时由管理手段代劳,同时不停止寻找技术手段。

  • 实践

13 _ 白天开会,加班写代码的节奏怎么破?

  • 开会是有价值的

    • 项目立项会议(创建一种仪式感,让每个人都知道项目的关键信息)

      • 项目目标:这个项目是要干什么的,达到一个什么目标;

      • 项目里程碑:项目的开始结束时间,项目的阶段划分,以及各个阶段的时间点;

      • 角色分工:项目成员的分工和角色是什么,每个人知道自己的任务是什么,知道遇到问题该找谁;

      • 流程规范:项目开发的主要流程是什么,基于瀑布还是敏捷。

  • 开会是有成本的

  • 什么样的会议是有效率的?

    • 建议的会议方式:人少,面对面沟通

    • 会议是不是有效率,取决于它创造的价值是不是高于其成本

  • 如何提高开会效率?

    • 金三角理论

      • 减少开会的成本

      • 增加开会创造的价值

    • 前提

      • 要让大家意识到开会是有成本的,如果开会创造的价值不能大于其成本,就是浪费

    • 方法

        1. 砍掉一些没价值的会议

        • 没有目标的会议

        • 不能形成决策,没有会后行动

        • 你属于可有可无的角色

        1. 减少参与会议的人

        • 会议的成本和两个因素相关:一个是人数,一个是时间。如果减少人数,就能减少成本。

        1. 缩短开会时间

        • 当话题开始发散的时候,果断制止,放到 “停车场问题” 环节,也就是会议的最后专门讨论

        1. 提升会议所创造的价值

          • 每个会议要有明确的目的和主题

          • 问题的讨论不能偏离会议的主题

          • 开会后,要有明确的结论,有后续的待办事项

            • 落实到个人,对待办事项有跟踪

14 _ 项目管理工具:一切管理问题,都应思考能否通过工具解决

  • 感悟

    • 一切管理问题,都应思考能否通过工具或技术解决,如果当前工具或技术无法解决,暂时由流程规范代替,同时不停止寻找工具和技术。

    • 梳理好简洁高效的流程规范,能自动化的自动化——技术 Leader的首要任务

  • 项目管理工具软件发展史

    • 没有项目管理工具的年代

      • 余晟

        • 《“阿波罗“登月中的工程管理一瞥》

      • 阿波罗登月项目巨型计划图

        • 需要专业人士花大量时间,而且每次修改调整,都要再花费大量时间精力

    • 最初的项目管理软件:项目计划工具

      • 微软的 MS Project

      • 优点

        • 解决了计划制订的问题

      • 缺点

        • 不方便跟踪任务进度

        • 进度不直观

    • 基于 Ticket 的任务跟踪系统

      • 一个 Ticket 应该包含哪些主要信息

        • 标题:摘要性的描述 Ticket 内容;

        • 类型:属于什么类型的 Ticket:Bug、需求、任务;

        • 内容:Ticket 的详细内容,例如,如果是 Bug 的话,除了要写清楚 Bug 内容,还需要重现步骤。如果是需求的话,要有需求的描述,可能还需要额外的文档链接辅助说明;

        • 创建人:谁创建的这条 Ticket;

        • 优先级:这个 Ticket 的优先级高还是低;

        • 状态:Ticket 的状态,例如:未开始、处理中、已解决、重新打开、关闭等;

        • 指派给谁:这个 Ticket 被指派给谁了,谁来负责;

        • 历史记录:整个 Ticket 改变的历史信息,用以跟踪;

      • 优点

        • 能够清晰地看到整个项目的蓝图

      • 缺点

        • 结构化程度太高,不够灵活,不能适应项目执行期间遇到的变化

      • 适用于

        • 在规划和任务分解阶段,生成蓝图

    • 基于看板的可视化任务管理

      • 优点

        • 灵活

      • 缺点

        • 缺乏结构化,各任务之间的关系不明确,容易只见树木不见森林,因此不适合做项目规划和任务分解

      • 适用于

        • 把分解后的任务做成一个个ticket,做项目跟踪

  • 有哪些项目管理软件可以选择

    • 项目计划工具

      • MS Project

      • OmniPlan

      • Merlin Project

    • 基于 Ticket 的任务跟踪系统

      • Atlassian公司出品的Jira软件

      • 微软的Azure DevOps

      • 国内同类

        • 禅道:为数不多提供开源版本可以自己搭建的;

        • Worktile:集成了即时消息软件;

        • 云效:阿里巴巴出品,可以和阿里的服务很好整合,例如阿里云和钉钉;

15 _ 风险管理:不能盲目乐观,凡事都应该有B计划

  • 什么是风险管理

    • 风险定义

      • 指不确定的事件,一旦发生,将会造成消极的影响

      • 风险包含两个方面的内容

        • 发生后,会造成什么样的损失?

        • 发生的概率有多大?

      • 风险 = 损失 x 发生概率

    • 对软件项目风险的管理,才是体现项目管理水平的地方

    • 应对风险的层次

      • 被动应对

        • 风险已经发生,造成了问题才被动应对

      • 有备无患

        • 事先制定好风险发生后的补救方案,但没有任何防范措施

      • 防患未然

        • 对可能的风险做出防范,并把风险防范作为项目任务的一部分

  • 如何做好风险管理?

      1. 培养风险意识

      • 项目中的任务,不能盲目乐观,都思考一下它最坏的结果是什么,如果最坏的结果不能接受,就说明要有个 B 计划,考虑风险管理了。

      1. 管理风险

      • 第一步:风险识别,识别可能的风险

        • 一个识别风险的方法叫检查表法

        • 软件项目的风险主要分成以下几类

          • 项目风险:项目预算、进度、用户和需求等方面的问题;

          • 人员风险:人员离职、人手不足等问题;

          • 技术风险:采用的技术所可能带来的风险;

          • 商业风险:与市场、产品策略等有关的商业风险。

      • 第二步:风险量化,对风险进行评估量化

        • 从两个方面去评估

          • 发生的概率多大?

          • 发生后,后果多严重?

      • 第三步:应对计划,对风险制定应对策略

        • 回避风险 —— 更改导致风险的方案

          • 放弃或者修改导致风险的方案

          • 从根源上消除了风险,简单而彻底

        • 转移风险 —— 将损失转嫁出去

            • 购买云服务

        • 缓解风险 —— 降低风险发生概率或减少可能造成的损失

            • 定期备份数据库

            • 涨点工资,避免人才流失

        • 接受风险 —— 明知山有虎偏向虎山行

      • 第四步:风险监控,对风险进行监控预警

        • 要做好监控

          • 第一要能对监控的内容量化

          • 第二要设置阈值

          • 第三就是要有后续的报警和处理机制

16 _ 怎样才能写好项目文档?

  • 短期高估文档的重要性,而长期低估文档的重要性

  • 为什么要写文档?

    • 帮助写文档的人理清楚思路

      • 先写文档,就会抛开代码细节,去站在全局思考

      • 真正的障碍是没想清楚,在心中只有一些未成型的混乱的想法和概念,必须要努力把这些模糊的想法确定化和具体化,才能写出来。

    • 便于未来的维护和交接

    • 便于团队更好的协作沟通

  • 如何写好文档?

      1. 从模仿开始

      • 模仿就是最好的写文档方式

      1. 从小文档开始

      1. 从粗到细,迭代更新

      • 从脑图开始

      • 第二步就是写 PPT

      • 给别人讲解,收集反馈

      • 搭骨架

      • 对细节补充

      1. 一些基本的画图的技巧

      • 线框图

      • 流程图

      • 时序图

  • 实践

    • 大脑是用来计算的,并不是用来记忆的

      • 记忆一个索引就好了

    • 示例

      • 产品需求文档模板

        • https://www.jianshu.com/p/e89e97858be1

      • 微服务:从设计到部署

        • https://docshome.gitbooks.io/microservices/content/2-using-an-api-gateway.html

    • 需要文档列表

      • 项目立项

        • 原始需求文档

        • 可行性分析报告

        • 立项说明书

      • 需求相关

        • 原型设计文档

        • 产品设计文档

        • 其他

          • 产品需求分析文档(PRD)

          • 产品需求规格说明书

      • 系统设计

        • 技术方案文档

        • 详细设计文档

      • 开发相关

        • 代码规范文档

      • 测试相关

        • 测试用例

        • 测试验收报告

      • 运维相关

        • 部署文档

        • 故障报告

    • 文档分类

        1. 设计类文档

        • 作用

          • 主要用来说明、讨论需求设计、架构设计

          • 可以用来了解、讨论和评审,以及记录后续结果

        1. 说明类文档

        • 作用

          • 用来对规范、API、配置、操作等做说明,便于规范和统一

        1. 报告类文档

        • 作用

          • 对事情结果的报告和说明

        • 示例

          • 验收报告、故障报告、调研

    • 哪些文档

        1. 这件事需要讨论需要评审,要有文档作为讨论的依据,以及记录讨论的结果。比如各种设计文档

        1. 这件事要有规范,要有文档保证规范统一。比如各种规范文档

        1. 这件事要记录下来,作为以后的一个参考。比如各种报告、环境配置、操作手册、API 文档等

    • 从几个角度去思考文档好坏

        1. 文档是否讲清楚了它的目的是什么?

        1. 文档是否解释了为什么要这么做?

        1. 文档是否描述清楚了如何实现?

需求分析篇 (5 讲)

17 _ 需求分析到底要分析什么?怎么分析?

  • 需求分析是要分析什么?

    • 第一步:挖掘真实需求

      • 目标用户:用户不同,诉求也不一样;

      • 使用场景:使用场景不一样,解决方案也会有所不同;

      • 想要解决的问题:用户背后想要解决的问题是什么。

    • 第二步:提出解决方案

    • 第三步:筛选和验证方案

  • 怎样做需求分析?

      1. 收集需求

      • 头脑风暴

      • 用户调研

      • 竞品分析

      • 快速原型

      1. 分析需求

      • 作用

        • 对需求进行分析,挖掘用户真实需求

      • 表层需求:用户对解决问题的期望

        • 例如马车更快

      • 深层需求:用户的深层动机,诉求产生的原因

        • 例如乘客对出行速度的要求

      • 底层需求:人性本能的需求

        • 人性本能的需求,例如对安全感对舒适的追求

      1. 需求评估

      • 作用

        • 筛选过滤掉不可行的需求

      • 可行性:技术能否实现

      • 成本:人工成本、时间成本

      • 商业风险和收益:有没有商业的风险,收益是否合理

      • 紧急性与重要性:是不是用户迫切的需求

      • 评估其优先级:紧急重要四象限

      1. 需求设计

      • 针对用户需求提出解决方案,设计成产品方案

      1. 验证需求

      • 验证方案是否可行

18 _ 原型设计:如何用最小的代价完成产品特性?

  • 什么是原型设计?

    • 原型设计,是产品经理确认需求、设计产品最重要的沟通工具。

  • 原型设计的发展历史

    • 快速原型模型

      • 开发软件项目的一种模式,还不是工具

      • 第一阶段确认界面布局和内容

      • 第二阶段确认交互

      • 第三阶段实现

    • 历史

      • 低保真原型设计

        • 手工草图

      • 中等保真原型设计

        • Axure

      • 高保真原型设计

        • 甚至完成后都无需再做 UI 设计

  • 怎么做好原型设计?

    • 第一步:分析

    • 第二步:设计

      • 从信息架构的维度,考虑清楚整个产品的信息架构,划分出模块;

        • 思维导图

      • 从使用流程的维度,考虑清楚界面之间的流程。

        • 流程图

    • 第三步:实施

    • 第四步:验证

  • 如何选择合适的原型设计工具?

    • 几个维度

      • 面向的平台:Web、桌面、手机;

      • 保真度:中等保真度还是高保真度;

      • 功能:是否满足你的要求;

      • 成本:价钱是否可以接受。

    • 原型设计工具

      • Axure RP

        • 缺点是专业度较高,价格高

      • 墨刀

        • 优秀的国产原型设计工具

      • Adobe XD

        • 对于设计师尤其容易上手

      • ProtoPie

        • 高保真原型设计工具

      • Framer X

        • 高保真原型设计工具

        • 需要一定的编程基础,尤其适合程序员使用

19 _ 作为程序员,你应该有产品意识

  • 程序员的价值

    • 第一,你的价值体现在你所做的产品之上。

    • 第二,你的价值体现在团队中的稀缺性。

  • 什么是产品意识

    • 商业意识

      • 定义

        • 所做的产品是要有商业价值的

      • 如果程序员有商业意识,就可以在项目中有更好的成本意识,为项目节约时间、经济等成本,帮助团队打造更有价值的产品。

    • 用户意识

      • 定义

        • 做产品时,你要能挖掘出用户的真实需求,让产品有好的用户体验。这需要你要有同理心,能站在用户的角度去思考和体验产品。

    • 数据意识

      • 定义

        • 在产品设计、产品运营时,通过数据来发现问题、证实结果

  • 如何培养产品意识?

    • 首先要解放思想

      • 技术思维会关注用什么技术,关注技术细节,关注功能“如何”实现

      • 产品思维会关注用户体验,关注一个功能所创造的价值,会去思考为什么要或者不要一个功能

    • 然后要改变习惯

      • 定义

        • 在日常使用产品、开发产品的时候,多站在产品的角度思考,去思考它的商业价值、用户体验、使用场景等等。

    • 最后要多实践

20 _ 如何应对让人头疼的需求变更问题?

  • 管理需求变更的解决方案

    • 方案一:增强需求变更流程,让需求变更规范起来。

    • 方案二:快速迭代,缩短版本周期。

  • 如何解决需求变更问题?

    • 从源头着手

      • 提升需求确定性,把需求分析做好,减少需求变更;

      • 提高需求变更的成本,让客户或者产品经理不能太容易就变更需求,这样就可以达到减少需求变更的目的。

    • 从解决方案着手

      • 降低响应需求变更的成本,可以方便快捷地响应需求变更。

      - 第一步:规范变更流程,提升客户变更成本。
    
      - 第二步:用原型设计低成本响应需求变更;做好需求分析和确认,减少需求变更。
    
      - 第三步:通过灵活的架构和强大的配置,低成本响应客户需求变更。
    

会议

  • 项目启动会议

    • Kick off meeting

    • 几个关键信息

      • 项目目标:这项目是要干什么的,达到一个什么目标;

      • 项目里程碑:项目的开始结束时间,项目的阶段划分,以及各个阶段的时间点;

      • 角色分工:项目成员的分工和角色是什么,每个人知道自己的任务是什么,知道遇到问题该找谁;

      • 流程规范:项目开发的主要流程是什么,基于瀑布还是敏捷。

  • 瀑布模型各个阶段的评审会议

    • 典型的

      • 需求评审会议

      • 架构设计评审会议

    • 主要目的是用来收集意见

  • 瀑布模型各阶段的说明会议

    • 需求设计说明会

    • 架构设计说明会

  • 进度报告会议

    • 分类

      • 瀑布模型通常是以周为单位的周例会

      • 敏捷开发是以天为单位的每日站会

    • 目的

      • 了解项目的进展,了解当前的困难和瓶颈,及时调整计划,解决问题

      • 每个人都要当众讲一下做过的事情和计划要做的事情,也是一种无形的监督和约束

  • 项目计划会

    • 敏捷开发

      • 每个 Sprint 开始前都会有一个 Sprint 计划会(Sprint Planning)

    • 瀑布模型

      • 每个版本开始之前也会有项目计划会

  • 产品演示验收会

  • 项目总结会议

    • Sprint 回顾会议(Sprint Retrospective)

  • 一对一会议

系统设计篇 (4 讲)

21 _ 架构设计:普通程序员也能实现复杂系统?

  • 为什么软件项目需要架构设计?

    • 复杂的软件项目

      • 特点

        • 需求不确定

        • 技术复杂

    • 技术的复杂性,主要体现在四个方面

        1. 需求让技术变复杂

        1. 人员会让技术变复杂

        • 让这一群人有效地协作是很大的考验

        1. 技术本身也是复杂的

        1. 要让软件稳定运行是复杂的

    • 架构设计恰恰可以很好地解决技术复杂的问题

      • 首先,架构设计可以降低满足需求和需求变化的开发成本。

      • 其次,架构设计可以帮助组织人员一起高效协作。

      • 再次,架构设计可以帮助组织好各种技术。

      • 最后,架构设计可以保障服务稳定运行。

  • 什么是架构设计?

    • 架构设计的目标

      • 用最小的人力成本来满足需求的开发和响应需求的变化,用最小的运行成本来保障软件的运行

    • 架构设计的方法示例

      • 微服务

        • 把复杂系统拆分成一系列小的服务,服务再拆成功能模块,让人员更好地分工协作

      • 前后端分离

        • 让程序员更专注于某个知识领域,降低开发难度

      • 分层设计

        • 隔离业务逻辑,减少需求变更带来的影响

    • 架构设计的道

      • 组织人员和技术把系统和团队拆分,并安排好切分后的排列关系,让拆分后的部分能通过约定好的协议相互通信,共同实现最终的结果。

  • 如何做好架构设计?

    • 第一步:分析需求

    • 第二步:选择相似的成熟的架构设计方案

    • 第三步:自顶向下层层细化

      • 部署架构

      • 分层和分模块

      • API 设计、数据库设计、模块的设计

    • 第四步:验证和优化架构设计方案

      • 方案的验证是贯穿整个设计始终的

        • 一个完整的架构设计方案,需要有多次的评审会议,充分收集各方面的反馈,反复修改后才能最终确定下来

  • 推荐学习材料

    • 《Software Architecture Patterns》

      • O’Reilly

    • 软件架构入门

      • 阮一峰老师

    • 《架构师之路》

    • 《图解:从单个服务器扩展到百万用户的系统》

    • 《以 “前浪微博” 场景为例,谈谈架构设计流程四步曲》

    • 《架构整洁之道》

      • 架构设计书籍中写的最透彻最浅显易懂的一本

    • 《极客邦池建强:难的不是从零打造一款产品,而是……》

      • https://www.infoq.cn/article/q7xlHaaiZ-9H6SwHXCNg

22 _ 如何为项目做好技术选型?

  • 技术选型就是项目决策

    • 技术选型看起来是个技术的选择,但其实是一个和项目情况密切相关的项目决策

    • 受制于时间、范围和成本的约束

      • 时间

      • 范围

      • 成本

    • 要分析可行性和风险

    • 要考虑利益相关人

    • 项目决策中常见的坑

      • 把听到的观点当事实

      • 先入为主,有了结论再找证据

  • 如何做好技术选型?

    • 问题定义

      • 只有明确了技术选型的目标,才能有一个标准可以来评判该选择哪一个方案。

    • 调研

    • 验证

    • 决策

  • 实践

    • 开源技术选型

        1. 先找朋友推荐,少走一点弯路

        1. 没有推荐的话,就去网上搜索,找几个满足需求的备选。

        1. 对比以下几个指标:

        • 代码质量、有无测试

        • 文档健全度

        • 看Issue处理情况、最后更新时间(无人维护的项目后续恐怕有问题都没法解决)

        • 看Star数量,通过Google和StackOverflow看使用情况

        1. 自己按照说明试试看

23 _ 架构师:不想当架构师的程序员不是好程序员

  • 什么是架构师思维?

    • 对于架构师来说,要控制技术复杂性,有几种有效的方式

      • 抽象

      • 分治

      • 复用

      • 迭代

    • 抽象思维

      • 在软件项目中,遇到类似的场景,就会考虑抽象出来,总结一个规则和方法

    • 分治思维

      • 对复杂系统要分而治之,分解成小的、简单的部分。但光分解还是不够的,同时还需要保证分解后的部分能够通过约定好的协议集成在一起。

    • 复用思维

      • 一种非常简单有效的提升开发效率的方法,通过对相同内容的抽象,让其能复用于不同的场景。

    • 迭代思维

      • 好的架构设计,通常不是一步到位,而是先满足好当前业务需求,然后随着业务的变化而逐步演进

  • 好的架构师什么样?

    • 一个好的架构师,不仅技术要好,还要懂业务;能从整体设计架构,也能在局部实现功能。

    • 要成为好的架构师,需要具备几个条件

        1. 有架构师思维:具备良好的抽象思维、分治思维、复用思维和迭代思维;

        1. 懂业务需求:能很好地理解业务需求,能针对业务特点设计好的架构;

        1. 有丰富的编码经验:像抽象、分治、复用这些能力,都需要大量的编码练习才能掌握;另外保持一定量的编码经验也有助于验证架构设计;

        1. 良好的沟通能力:架构师需要沟通确认需求,需要让团队理解架构设计。

  • 如何成为好的架构师?

    • 要成为一个优秀的程序员

    • 多模仿多学习

    • 选择好行业和平台

  • 实践

    • 架构师之路

      • https://www.w3cschool.cn/architectroad/

    • 张开涛亿级流量网站架构核心技术》

    • 陈康贤的《大型分布式网站架构设计与实践》

    • 李智慧的《大型网站技术架构:核心原理与案例分析》

24 _ 技术债务:是继续修修补补凑合着用,还是推翻重来?

  • 什么是技术债务?

    • 技术债务,就是软件项目中对架构质量和代码质量的透支。

    • 技术债务是有利息的

    • 技术债务不一定都是坏的

  • 技术债务产生的原因

    • 轻率 / 有意的债务

      • 短期可能还好,但是因为技术债务会一直积累,会导致利息越来越多

    • 谨慎 / 有意的债务

      • 因为能及时偿还,所以既可以短期有一定时间上的收益,长期也不会造成负面影响

    • 轻率 / 无意的债务

      • 反映了团队不知道技术债务

      • 这样产生的债务是最危险的

    • 谨慎 / 无意的债务

      • 及时的对架构升级、重构

  • 如何管理技术债务?

    • 识别技术债务

      • 开发速度降低

      • 单元测试代码覆盖率低

      • 代码规范检查的错误率高

      • Bug 数量越来越多

    • 选择处理技术债务策略

      • 重写:推翻重来,一次还清

      • 维持:修修补补,只还利息

      • 重构:新旧交替,分期付款

    • 实施策略

      • 对于重写的策略,要当作一个正式的项目来立项,按照项目流程推进;

      • 对于重构的策略,要把整个重构任务拆分成一个个小任务,放到项目计划中,创建成 Ticket,放到任务跟踪系统中跟踪起来;

      • 对于维持的策略,也要把需要做的修补工作作为任务,放到计划中,放到任务跟踪系统中。

      • 关键

        • 实施策略的关键就在于要落实成开发任务,作为项目计划的一部分。

    • 预防才是最好的方法

      • 预先投资:好的架构设计、高质量代码就像一种技术投资,能有效减少技术债务的发生;

      • 不走捷径:大部分技术债务的来源都是因为走捷径,如果日常能做好代码审查、保障单元测试代码覆盖率,这些行之有效的措施都可以帮助你预防技术债务;

      • 及时还债:有时候项目中,因为进度时间紧等客观原因,导致不得不走捷径,那么就应该把欠下的技术债务记下来,放到任务跟踪系统中,安排在后续的开发任务中,及时还债及时解决,就可以避免债务越来越多。

  • 实践

    • 重构的要领

      • 第一:你要先写一部分自动化测试代码,保证重构后这些测试代码能帮助你检测出来问题

      • 第二:在重构模块的时候,老的代码先保留,写新的代码,然后指向新代码,或者用特定开关控制新旧代码的指向,然后让自动化测试通过,再部署测试,新代码没问题了,删除旧代码

开发编码篇 (7 讲)

25 | 有哪些方法可以提高开发效率?

  • 积极主动,行动起来改变自己

    • 不要一开始就否定

      • 单元测试

      • 持续集成

    • 减少关注圈,扩大影响圈

      • 不要总盯着自己无法改变的部分,你需要要多花时间精力在影响圈上。

      • 接受不能改变的,改变能改变的,尽量扩大可改变项的范围。

  • 以终为始,想清楚再开工

    • 经常停下来想想目标

    • 制定原则

      • 先运行再优化 (Make it Work Make It Right Make It Fast)

      • 不复制粘贴代码 (Don’t repeat yourself)

      • 每个 Pull Request 要尽可能小

    • 公开自己的计划

  • 要事第一,把时间用在刀刃上

    • 重要紧急的事情马上处理

      • 利用状态最好的时间

    • 重要不紧急的要事,要花最多的时间在上面

      • 制定计划

    • 紧急不重要的事凑一起集中做

    • 不重要不紧急的事情能不做就不做

  • 实践

    • 程序员如何准确的估算开发时间

        1. 充分理解清楚需求

        1. 加入非功能性的需求时间

        1. 将任务分解的尽可能细

        1. 综合考虑任务并行的情况(线上 bug、开会等)

        1. 计划保持及时更新

        1. 留一点余量,应对突发情况

    • 参考书

      • 《人件》

        • 经典的软件工程书

        • 对如何提高效率,讲了很多方法

      • 《高效能人士的七个习惯》

26 _ 持续交付:如何做到随时发布新版本到生产环境?

  • 集成的发展演变

    • 集成的原始阶段

      • 每次集成都是很痛苦的过程

        • 编译无法通过

        • hard code 了开发环境地址

        • 类库版本不一致

        • API 格式不一致

      • 要持续几天甚至几周才能逐步有一个相对稳定的版本

    • 持续集成

      • 《重构》的作者 Martin Fowler

        • 如果一件事很痛苦,那么就更频繁的做(if it hurts, do it more often. )

      • 说明

        • 分支程序自动合并到主干程序

  • 部署和交付的发展史

    • 部署和交付的原始阶段

      • 开发人员自己部署

      • 运维人员负责部署

    • 脚本自动化部署

      • 每日构建(Daily Build)

    • 持续交付

      • 对于生产环境的部署,依然需要有手动确认的环节

      • 说明

        • 在持续集成的基础上自动部署测试环境

    • 持续部署

      • 把新功能用功能开关(Feature flag)隐藏起来,设置特定的 Cookie 或者 Header 才打开

      • 说明

        • 在持续交付的基础上自动部署生产环境

  • 实践

    • 参考书

      • 《持续交付 : 发布可靠软件的系统方法》

    • 分支开发注意事项

      • 要有一个稳定的分支,可以随时发布的那种

      • 合并之前要有代码审查和自动化测试

    • 一个完整的自动化测试要包括

      • 验证功能是不是正确

      • 覆盖边界条件

      • 异常和错误处理

27,28 _ 软件工程师的核心竞争力是什么?

  • 软件工程师的核心竞争力

    • 软件工程师的核心竞争力,不是单一能力的体现,而是几种能力和价值的合集

      • 学习能力

      • 解决问题能力(软件工程师日常开发工作的核心)

        • 发现问题

        • 分析问题

        • 解决问题

      • 影响力

        • 不是一朝一夕能形成的,但却是一个软件工程师最核心的价值体现

  • 如何提升学习能力?

    • 关键

      • 构建好自己的知识体系

    • 首先需要在一个技术领域深耕

      • 只有一个领域的知识你真正吃透,才能有效地共享到其他领域,构成一个知识领域的森林。

    • 然后往相近的领域逐步横向拓展

  • 如何提高解决问题的能力?

    • 关键

      • 形成自己的方法论,去发现问题,分析问题和解决问题

    • 第一步:明确问题

    • 第二步:拆分和定位问题

    • 第三步:提出解决方案并总结

      • 每次解决完问题,提出一个预防问题发生的方案

  • 如何提升影响力?

    • 关键

      • 在一个领域深入打造自己独特的有价值的能力,让自己做事情能超出别人的预期,同时乐于分享和帮助他人

    • 在某个领域做出了足够牛的成绩

      • 要实力、要机缘、还要坚持

    • 做事情超出预期

      • 了解别人对你的期望

      • 降低别人对你的期望

      • 最后做出高于期望的事

    • 帮助其他人就是在帮助自己

    • 分享就是学习和打造影响力

  • 实践

    • 参考书

      • 《提问的智慧(How To Ask Questions The Smart Way)》

    • 核心竞争力

      • 软素质(做事态度)

          1. 自驱动意识

          1. 沟通协调,刨根问底

          1. 经常自省

          1. 敢于担责

        • 5.ownership

      • 方法论(做事方法)

          1. 二八原则

          1. 时间管理四象限

        • 3.SOP

        • 4.ARCI

          1. 敏捷迭代

    • 如何看书

      • 书看一遍肯定记不住,得经常翻才行

      • 看完得思考

      • 思考完了还得实践

      • 实践完了还得总结思考

      • 最后才能变成自己的知识

    • 实践

      • 学习之前有思考

      • 学习有总结

      • 学习之后有行动

29 _ 自动化测试:如何把Bug杀死在摇篮里?

  • 有哪些类型的自动化测试?

      • 单元测试

      • 没有外部服务的依赖,都是要模拟的

      • 集成测试

        • 接口测试

      • 契约测试

        • 《聊一聊契约测试

          • https://insights.thoughtworks.cn/about-contract-test/

      • 所有的测试几乎都不需要依赖其他服务器的资源,如果有涉及其他机器的服务,则本地模拟,这样本机就可以完成测试

      • 系统测试

        • 端到端测试

      • 几乎不模拟,直接访问相关的外部服务

    • 比例

      • 小型测试:中型测试:大型测试比例大约为 7:2:1

      • 小型测试尽可能多覆盖,不要求 100%,谷歌是 85%

      • 中型测试覆盖大部分用户使用场景

      • 大型测试覆盖主要用户场景

  • 怎么写好自动化测试代码?

    • 步骤

      • 准备

      • 执行

      • 断言

      • 清理

    • 一个完整的自动化测试要包括

      • 验证功能是不是正确:例如说输入正确的用户名和密码,要能正常注册账号;

      • 覆盖边界条件: 比如说如果用户名或密码为空,应该不允许注册成功;

      • 异常和错误处理:比如说使用一个已经用过的用户名,应该提示用户名被使用

  • 实践

    • 参考书

      • 《how we test software at microsoft》中文版《微软的软件测试之道》

30 _ 用好源代码管理工具,让你的协作更高效

  • 源代码管理工具发展简史

    • 没有源代码管理工具的时代

    • 本地版本管理

      • SCCS(Source Code Control System)

        • 1972 年

        • 对单个文件保留多个版本

      • RCS (Revision Control System)

        • 更好的文件比较算法

      • 只能本机使用,而且一次只能修改一个文件

    • 集中式版本管理

      • CVS(Concurrent Versions System)

        • 1986 年

      • SVN(Subversion)

        • 2000 年后逐步取代了 CVS 成为主流的源代码管理工具

    • 分布式版本管理

      • Git

  • 如何用好源代码管理工具?

    • 原则一:要频繁的提交

      • 频繁提交,不意味着提交不完整的内容,而是将要提交的内容分拆,并且保证完整性。

    • 原则二:每次提交后要跑自动化测试

    • 原则三:提交的代码要有人审查

      • 怎么做好代码审查呢?

        • 审查出来的问题分成三个类型

          • 问题:如果对代码有不清楚的地方,可以作为问题提出,进一步澄清确认;

          • 建议:原来的实现没有太大问题,但是可以有不同的或者更好的实现;

          • 阻塞:代码有明显问题,必须要修改。

  • 基于源代码的开发流程

    • 有一个稳定的代码分支;

    • 在合并分支之前,对代码有审查,自动化测试要能通过。

软件测试篇 (4 讲)

31 _ 软件测试要为产品质量负责吗?

  • 什么是软件产品质量?

    • 不同的人对软件质量好坏的评判角度是不同的

      • 对用户来说,更看重产品是不是满足需求,是不是美观好用

      • 对开发来说,看重的是代码质量是不是高,是不是好维护

      • 对于软件测试人员而言,看重的是 Bug 数量、安全、性能等指标

      • 对于项目负责人,看重的是整个开发过程的质量,是不是成本可控、如期完成

    • David Chappell

      • 《The Three Aspects of Software Quality: Functional, Structural, and Process》

      • 功能

        • 功能质量

          • 功能的质量直接决定了产品的质量

      • 结构

        • 代码质量

          • 代码的可维护性,也就是在不影响稳定性的前提下,是否能方便地添加或者修改现有的代码;

          • 代码的可读性,代码是否容易理解,是否能快速上手;

          • 代码的执行效率,代码执行效率直接影响了软件性能;

          • 代码的安全性,是否有安全漏洞,安全性是代码质量很重要的一个指标;

          • 代码的可测试性,代码是否能使用单元测试、集成测试进行测试验证。

      • 流程

        • 过程质量

          • 软件开发过程的质量决定了你的项目是否能如期完成,开发成本是否在预算之内

  • 谁该为产品质量负责?

    • 首要负责人是项目负责人

    • 其次是开发人员

    • 然后才是软件测试

32 _ 软件测试:什么样的公司需要专职测试?

  • 软件测试的主要工作是什么?

    • 小总结

      • 发现 Bug

      • 报告 Bug

      • 跟踪 Bug

    • 软件测试怎么发现 Bug?

      • 尽可能做到覆盖所有用户操作的可能

        • 理论上来说这是不可能的,因为组合是有无限多个的

        • 从测试的角度看,没有必要每一个可能都去测试,可以通过一些科学的方法来通过有限的测试用例,保证尽可能多的测试覆盖

      • 方法

        • 等价类划分

          • 如:1-100 之间的整数

            • 1 到 100 之间都是等价的

            • 0和任意负数也是等价的

            • 101 和之上的整数也是等价的

        • 边界值分析

          • 0,1,100,101 都是边界值

        • 探索性测试

          • 根据前面的测试结果,通过有效的策略进行测试

        • 场景设计;

        • 因果图;

        • 错误推测法。

    • 软件测试怎么报告 Bug?

    • 软件测试怎么跟踪 Bug?

      • 回归测试

  • 参考

    • 左耳朵耗子老师写的《我们需要专职的 QA 吗?》

    • 邹欣老师对此回复《测试 QA 的角色和分工》

    • 《微软的软件测试之道》

    • 《探索性测试揭秘》

  • 实践

    • 测试用例模板

      • testrail

      • 标题、描述、优先级、分类

      • 测试类型:功能测试、性能测试、回归测试、冒烟测试

      • 自动化状态:没有自动化、只能手动测试、只能自动化、集成 CI

      • 先决条件:这个用例需要满足好什么条件

      • 测试步骤:写清楚一步步的执行步骤

      • 期望结果:操作完成后结果应该是什么样的

33 _ 测试工具:为什么不应该通过QQ_微信_邮件报Bug?

  • 历史Bug 跟踪工具

    • GNATS

      • 1992 年第一个专业的 Bug 跟踪软件

    • Bugzilla、Jira、MantisBT

  • Bug 跟踪工具

    • 任务跟踪系统

      • Jira、禅道、TAPD、云效

    • Bugzilla

      • Mazilla 公司提供的一款开源免费的 bug 跟踪系统。这是一款历史很悠久的产品

    • MantisBT

      • 一个简单但功能强大的开源 bug 跟踪系统,可以通过各种插件来扩展其功能。

    • Redmine

      • 开源的综合性的项目管理工具,不仅可以用于 Bug 跟踪,还可以用来跟踪项目进度。

  • 自动化测试工具

    • Selenium

      • Web 端的自动化测试工具,直接运行在浏览器中,用来模拟用户操作

      • 类似

        • WebDriverIO

        • Nightwatch.js

    • Appium

      • 一个开源、跨平台的自动化测试工具,用于测试移动原生应用

      • 支持 iOS, Android 系统

    • Macaca

      • 阿里巴巴开源的一款面向多端的自动化测试工具

      • 支持桌面端、Web、移动端、真实设备和模拟器

    • 参考

      • 自动化测试工具

        • 《Best Automation Testing Tools for 2019 (Top 10 reviews)》

  • 压力测试工具

    • Apache JMeter

      • 开源的压力测试工具,纯 Java 应用程序

    • LoadRunner

      • 惠普旗下的一款商业自动负载测试工具

    • 阿里云性能测试 PTS

      • 模拟从全国各地域运营商网络发起的流量,真实地反映使用情况,生成有价值的性能测试报告

    • WebPageTest

      • 用来测试和分析网页性能的在线工具

  • 安全性测试工具

    • HP Fortify On Demand

      • 可以通过分析源代码、二进制程序或者应用程序 URL 检测程序安全漏洞

    • Sqlmap

      • 开源免费的检测 SQL 注入的工具

    • IBM Application Security APPScan

      • 一款漏洞扫描工具,支持网站和移动 App

    • fortify

    • appscan

    • Veracode、Checkmarx 和 CodeSecure

  • 浏览器兼容性测试工具

    • Browsera

    • Browslering

    • TestRail

    • 飞蛾

34 _ 账号密码泄露成灾,应该怎样预防?

  • 安全问题本质是技术风险

    • 风险管理

      • 风险识别

      • 风险量化

      • 应对计划

      • 风险监控

    • 安全问题来源

      • 第一类:恶意输入

        • SQL 注入

        • XSS 攻击

      • 第二类:假冒身份

      • 第三类:数据泄露

  • 如何预防软件中的安全问题?

    • 需求阶段

      • 提出了安全性的需求

      • 从源头上就让大家有了安全方面的意识

    • 设计阶段

      • 把安全加入到设计目标

      • 安全相关的设计原则

        • 攻击面最小化

        • 权限最小化

        • 纵深防御

          • 设计原则

            • 从不同的维度去实施安全保护措施,从而缓解被攻击的风险

    • 开发阶段

      • 编码规范中加入安全相关内容

      • 要有代码审查

      • 增加安全相关的自动化测试

    • 测试阶段

      • 增加对安全性方面的测试

      • 借助一些安全测试工具测试

    • 上线维护

      • 不部署源代码,只对编译后程序部署

      • 删除 Debug 文件

      • 对服务器进行安全设置

        • 严格限制端口

        • 严格限制端口

        • 对访问目录设置最小的权限

  • 如果真的出现安全问题怎么办?

    • 首先,要设立应急的流程。

    • 其次,要分析程序的漏洞在哪里

    • 最后,要总结原因

运行维护篇 (6 讲)

35 _ 版本发布:软件上线只是新的开始

  • 关于软件版本

    • 主版本号.子版本号.[. 修正版本号.[构建版本号]]

      • 1.2.1、2.0、3.0.1 build-123

    • 主版本号和子版本号用来标识功能变化

    • 修正版本号则表示功能不变化的情况下修复 Bug

    • 构建版本号表示一次新的构建

  • 版本发布前,做好版本发布的规划

    • 首先是规划好要发布的功能

    • 再有就是要设计好发布的策略

      • 灰度测试

    • 最后,就是有一个综合性的版本发布计划

  • 规范好发布流程,保障发布质量

    • 有几个需要注意的问题

      • 首先是必须保证要编译部署的是正确的版本

      • 然后要保证版本稳定可靠

      • 再就是要在发布失败后能回滚

    • 流程

      • 在发布之前要做代码冻结

      • 对代码冻结后发现的 Bug 要分级

      • 每次修复 Bug 后,发布新的候选版本

      • 每次部署新的候选发布版本后,要做回归测试

      • 申请上线发布

        • 审批

      • 部署发布

      • 上线后的测试

    • 如何应用不同环境下的不同配置

      • 参考这篇文章:《大型项目程序配置管理演化之路》

  • 软件上线只是新的开始

    • 对发布的版本进行监控

      • 收集 App Crash 的 Log

      • 监控服务器资源占用情况

      • 监控 API 出错的比例

      • 监控网页响应的速度等数据

36 _ DevOps工程师到底要做什么事情?

  • 传统的运维模式以及面临的挑战

    • 第一,服务器规模快速增长和虚拟化技术的高速发展。

    • 第二,高频的部署发布。

  • 什么是 DevOps?

    • 定义

      • 可以理解为一种开发(Development)和运维(Operations)一起紧密协作的工作方式,从而可以更快更可靠的构建、测试和发布软件

    • 采用 DevOps 好处

      • 整个软件的构建、测试和发布过程高度自动化

      • 信息更加透明和易于测量

      • 培养跨职能协作的文化

  • DevOps 工程师到底要做什么事情?

    • 首先,DevOps 工程师要帮助团队建立基于持续集成和持续交付工作流程。

    • 其次,要建立一套基于日志的监控报警的系统,以及故障响应的流程。

    • 然后,要构建基于云计算和虚拟化技术的基础设施。

    • 最后,要形成 DevOps 的文化。

37 _ 遇到线上故障,你和高手的差距在哪里?

  • 处理流程

    • 首先,对故障进行评级。

    • 其次,要马上恢复生产,避免进一步损失。

    • 另外,要分析故障原因,修复故障。

    • 最后,记录故障发生处理全过程,分析故障原因,提出后续改进方案。

  • 线上故障处理机制

    • 故障报警和轮值机制

      • 让最熟悉服务的开发人员第一时间去处理

    • 实战演习

      • Chaos Monkey(混乱猴子)

      • 混沌工程

    • 日志记录和分析工具

  • 线上故障处理的流程参考书

    • 《SRE:Google 运维解密》

    • 《阿里如何应对电商故障?》

    • 《滴滴是如何高效率处理线上故障的?》

  • 实践

    • 谁主导线上故障

      • 要懂技术懂业务,这样出现故障,能对故障进行评级

      • 能调动开发和运维去协调处理,这样出现故障能找到合适的人去处理

38 _ 日志管理:如何借助工具快速发现和定位产品问题 ?

  • 如何快速发现和定位问题?

    • 首先,日志集中式管理后,就可以方便地对所有日志进行统一的检索

    • 然后,对日志进行集中式管理后,可以通过图表直观的看到应用运行情况

    • 最后,可以根据日志的数值设置规则自动报警

  • 参考

    • 阿里云:《基于 ELK 实时日志分析的最佳实践》

    • 新浪:《ELK Stack 在新浪微博的最佳实践》《新浪是如何分析处理 32 亿条实时日志的?》

    • 七牛:《如何快速搭建智能化的统一日志管理系统》

39 _ 项目总结:做好项目复盘,把经验变成能力

  • 什么是项目复盘?

    • 软件项目中的复盘,也是通过分析、讨论开发中出现的问题,进而总结成功经验,吸取失败教训,提升团队能力。

    • 常见问题

      • 总结不出来有效的结论

      • 没做好是客观原因导致的

      • 知道什么原因,但不知道该怎么办

  • 如何做好项目复盘?

      1. 回顾项目目标

      1. 评估项目结果

      1. 分析原因

      1. 总结规律,落实行动

经典案例解析篇 (7 讲)

40 _ 最佳实践:小团队如何应用软件工程?

  • 团队建设方面

    • 招人

      • 找一些有潜力的培养,也要注意梯队建设,中间有技术骨干补充

    • 培养人

      • 给新人安排师傅的方式培养新人

      • 日常注意代码审查

      • 内部技术分享是个不错的共同提高的方式

      • 技术高手要注意不只是闷头干活,也要承担一定的带人的工作

    • 管理人

      • 核心在于营造好的氛围,鼓励成员自我驱动去做事

    • 开人

      • 不适合团队的人也不要手软,及时的淘汰

  • 流程建设方面

    • 选择合适的软件开发模型,建立项目开发流程

    • 构建基于源代码管理工具的开发流程

    • 建立外部提交需求和任务的流程

41 _ 为什么程序员的业余项目大多都死了?

    1. 想法大,时间少

    1. 过于追求技术,缺少约束

    1. 缺少产品能力和运营能力

42 _ 反面案例:盘点那些失败的软件项目

  • 成功的项目必须满足六个条件

    • 项目管理协会(PMI)

      1. 按时交付

      1. 成本在预算范围内

      1. 能按照当初的设计正常运行

      1. 有人使用

      1. 满足项目最初的目标

      1. 项目出资方对项目满意

  • 分析失败软件项目的原因

    • 外部环境

    • 技术管理

    • 项目管理

    • 组织文化

  • 参考书

    • 《梦断代码》

    • 《梦醒时分 - 梦断代码读后感》

      • 邹欣老师

43 _ 以VS Code为例,看大型开源项目是如何应用软件工程的?

44 _ 微软、谷歌、阿里巴巴等大厂是怎样应用软件工程的?

45 _ 从软件工程的角度看微服务、云计算、人工智能这些新技术