# 软件工程之美 ## 开篇词 ### 开篇词 | 你为什么应该学好软件工程 - 书推荐 - 项目管理 - 《项目管理修炼之道》 - 《项目管理 - 计划、进度和控制的系统方法》 - 《软件项目成功之道》 - 《做项目,就得这么干!》 - 软件工程 - 《构建之法》 - 多所高校进行了软件工程的教学实践,在此基础上对软件工程的各个知识点和技能要求进行了系统性整理,形成教材。 - 《人月神话》 - 关注 “软件开发” 本身 - 《人件》 - 关注软件开发中的 “人” - 《知行合一: 实现价值驱动的敏捷和精益开发》 - 书写的特别接地气,文章有很多真实案例,对敏捷开发和 CMMI 都有很深入描述 - 《软件工程 —— 实践者的研究方法》 - 大部分高校采用的软件工程标准教材 - Software Engineering – A Practitioner’s Approach - 作者是 Roger S. Pressman - 《持续交付》 - 如何实现更快、更可靠、低成本的自动化软件交付,描述了如何通过增加反馈,并改进开发人员、测试人员、运维人员和项目经理之间的协作来达到这个目标。 - 《走出软件作坊》 - 生动的描述了国内小型 IT 企业在发展过程中遇到的一系列项目管理问题,以及作者是如何去解决这些问题的。 - 其他 - 〖大道至简〗 - 机械工业出版社出的《软件工程》 - 作者是 Ian Sommerville - 敏捷相关 - 《敏捷实践指南》 - 《敏捷武士》 - 《高效程序员的 45 个习惯》 - 《敏捷革命》 ### 结束语 - 提升代码的质量 - 1. 架构设计:好的架构设计,降低实现的复杂度; - 2. 自动化测试:通过自动化测试和持续集成,将 Bug 发现在摇篮中; - 3. 代码审查:通过代码审查,让水平高的带动水平低的,水平低的学习水平高的,从而提升团队整体的代码质量。 ## 基础理论 (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. 写文档的过程中帮助你梳理清楚逻辑 - 2. 写出来的文档是要用来沟通的,让其他人通过文档明白你的思路 ### 04 | 瀑布模型之外,还有哪些开发模型? - 快速开发快速改 - 快速原型模型 - 为了要解决客户的需求不明确和需求多变的问题 - 优点 - 原型模型因为能快速修改,所以能快速对用户的反馈和变更作出响应,同时原型模型注重和客户的沟通,所以最终开发出来的软件能够真正反映用户的需求。 - 缺点 - 这种快速原型开发往往是以牺牲质量为代价的 - 特点 - 快速、低质量 - 两种处理策略 - 抛弃策略和附加策略 - 大瀑布拆小瀑布 - 增量模型 —— 按模块分批次交付 - 根基是模块化 - 如果系统不能模块化,那么将很难采用增量模型的模式来开发 - 对模块的划分很抽象,这本身对于系统架构的水平是要求很高的 - 适用于 - 需求比较清楚,能模块化的软件系统,并且可以按模块分批次交付 - 迭代模型 —— 每次迭代都有一个可用的版本 - 定义 - 每次只设计和实现产品的一部分,然后逐步完成更多功能 - 每次设计和实现一个阶段叫做一个迭代 - 说明 - 在一个迭代中都会包括需求分析、设计、实现和测试,类似于一个小瀑布模型。迭代结束时要完成一个可以运行的交付版本。 - 最难的部分 - 在于规划每次迭代的内容和要达到的目标 - 区别 - 增量模型是按照功能模块来拆分;而迭代模型则是按照时间来拆分,看单位时间内能完成多少功能。 ### 05 | 敏捷开发到底是想解决什么问题? - 敏捷宣言 - 内容 - 个体和互动高于流程和工具 - 工作的软件高于详尽的文档 - 客户合作高于合同谈判 - 响应变化高于遵循计划 - 背景 - 软件工业具备轻资产、知识密集型、从业人员素质高等特点 - 充分发挥人的创造力和价值,是其相较传统工业更高阶的要求 - 加之软件工程面对的不确定性与复杂度更显著 - 定义 - 敏捷宣言 - 敏捷不是一种方法论,也不是一种软件开发的具体方法,更不是一个框架或过程,而是一套价值观和原则 - 当你开发做决策的时候,遵守了敏捷开发的价值观和原则,不管你是不是用 Scrum 或者极限编程,那么都可以算是敏捷开发 - 各种敏捷框架、方法论和工具,就像是“术”,告诉你敏捷开发的方式,而敏捷则是“道”,是一套价值观和原则,指导你在软件项目开发中做决策。 - 想解决的问题 - 瀑布模型的典型问题 - 周期长 - 发布烦 - 变更难 - 敏捷开发 - 快速迭代 - 持续集成 - 拥抱变化 - 有苛刻的条件要求 - 需要客户紧密配合,可以方便确认需求 - 实践 - 操作 - 通过用户故事,理解用户需求 - 在迭代中采用渐进的架构设计 - 定期重构解决技术债务 - 功能开发的同时编写自动测试代码 - 自动化持续构建 - 本质 - 由于淡化了部分工业思维中兼顾稳定、质量、效率、成本的传统手段,敏捷思想的最终落地,需要素质极高的从业人员参与其中,且数量不宜过多,以此来弥补流程上的缺失。 - 同时要团队与客户紧密协作,上级的充分信任,才能够有效发挥其灵活应变,又万变不离其宗的优势。 - 这是大胆的返璞归真,好似回到了瀑布模型前的蛮荒时代,实则是更高级的打法,就像独孤九剑一般。所以,敏捷开发“道”的属性更浓。 - 新人的传承 - 1. 团队要有自己的知识库或WIKI,常用的知识要花时间整理上去,这样新人来了可以自己查 - 2. 先给他简单的任务,再慢慢稍微复杂一点,给予必要的指导,做中学是最快速有效的 - 3. 遇到一些典型的问题可以通过结对编程的方式带着一起做 - 项目文档有两个主要目的 - 帮助写的人理清楚思路 - 用来交流沟通 - 文档的关键不是细,而是达到文档的写作目的 - 至于粒度,可以站在文档读者的角度,结合日常开发维护场景,去思考这个文档 - 推荐书籍 - 《用户故事与敏捷方法》 - 敏捷武士︰看敏捷高手交付卓越软件》 - 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 - 2. 提一条需求,提交一个 Ticket - 3. 要重构一下代码,提交一个 Ticket - 一切以Ticket为准 - 不用担心问题被遗忘,会被跟踪,直到被解决或决定不解决 - Git&CI - master(主干) - 代码审查(Code Review) - 自动化测试 - PR(Pull Request,合并请求) - CI (持续集成) - 步骤 - 检查代码格式是不是符合规范 - 运行单元测试代码 - 运行集成测试 - 每日站立会议 - 重点是要高效沟通反馈 - 三个话题 - 1. 成员轮流发言 - 昨天干了什么事情,今天计划做什么事情,工作上有没有障碍无法推进 - 实践 - DevOps三个关键优点 - 1. 高度自动化 - 2. 透明可量化 - 3. 紧密协作 - 开发写的集成测试和测试写的自动化测试区别 - 开发是用程序模拟的操作的模拟的固定数据 - 测试用的是真实的数据真实的环境 ### 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. 公平合理,每个人都有机会不受他人影响的表达 - 2. 不用背锅,估错了也没关系,意见不一致还可以讨论 ### 10 _ 如果你想技术转管理,先来试试管好一个项目 - 技术人员转型管理的障碍 - 专注技术实现,沉浸于细节中,而忽视了其他事情 - 要钻研技术,这些是非常好的优点 - 要转管理,这反而会是一种障碍 - 管理,最重要的一点就是大局观,要能从整个项目的角度,从整个团队的角度去思考,去确定方向,去发现问题,对问题及时解决及时调整。 - 怎么样去管理一个软件项目 - “道” 就是管好人、管好事 - 管好软件项目中的人 - 1. 管理好客户的预期 - 质量达标:交付产品是高质量的,满足客户需求的。 - 完整交付:按照约定的功能范围交付最终产品。 - 按时交付:项目按照客户认可的进度完成。 - 预算之内:在预算内完成项目。 - 2. 管理好项目成员(流程和规范) - 好的项目管理,不需要直接去管人,而是管理好流程规范 - 项目成员不需要按照项目经理的指令做事,而是遵循流程规范。 - 管好软件项目中的事 - 1. 选择适合项目的开发模式 - 瀑布模型 - 敏捷开发 - 2. 制定好项目计划 - 工作分解结构 - 估算时间 - 排任务路径 - 3. 对计划进行跟踪和控制,同时做好风险管理 - 跟踪计划 - 调整计划 - 风险管理 - 技术转管理的一些经验教训 - 控制你想写代码的冲动 - 如果你带的项目进度吃紧时,你要做的不是去写代码,而是去帮助团队从其他角度想办法 - 写不写代码是管理风格的一部分 - 要把握好度 - 重点是要有全局视角 - 团队的成功,才是你的成功 - 不是你把上级的工作做了就能升职 - 而是你的下级都成长了,能替代你的位置了,你就可以升职了 - 形成自己的管理风格 - 根据自己的特点,找到适合自己的管理风格 - 坚持就是胜利 - 实践 - 技术转管理心得 - 站在全局考虑问题 - 张一鸣说“工作时不分哪些是我该做的,哪些是我不该做的” - 做事不设边界,才能有更大的成长,而这些对管理来说尤为如此 - 流程规范 - 先重点、全局,慢慢一步步优化 - 每周进步一点,强调其中1、2点规范 - 培养出来的下属替代你怎么办? - 看长远些 - 人生不只是一个下属不只是一个老板也不只是一个项目 - 提高自己 - 能培养好一个下属还能培养更多的下属 - 能做好一个项目还能做好更多项目 - 不需要靠一个老板的赏识与否来证明自己 - 架构师和管理 - 相同 - 都需要大局观 - 都需要好的沟通能力,让团队清晰的理解自己的意图 - 都需要用好流程和工具 - 都要善于 “分而治之”,把复杂的问题拆分成小的具体的问题 - 不同 - 项目经理更多的是跟人打交道,对项目负责 - 架构设计更多是专注技术,对架构负责 - 如何做到和组员目标一致性 - 多一对一沟通 - 了解组员想法 - 让组员知道你的期望 - 建立激励机制 ### 11 _ 项目计划:代码未动,计划先行 - 计划的重要性 - 没有计划,你的项目可能会陷入一种无序和混乱中 - 计划,就像我们出行用的导航 - 可以清楚地看到项目整体的安排 - 时刻提醒我们目标是什么,不要偏离方向 - 光有目标还不够的 - 必须得要付诸行动 - 需要对目标进行分解,进而变成可以执行的计划 - 如何制定计划 - 第一步:任务分解 - 任务分解:专业词汇叫 WBS - 工作分解结构(Work Breakdown Structure, WBS) - 定义:把要做的事情,按照一个树形结构去组织,逐级分解,分割成小而具体的可交付结果,直到不能再拆分为止 - 第二步:估算时间 - 有很多方法可以参考,主要还是得依靠以前的经验 - 要想估算准确 - 任务拆分的越细致,想的越清楚,就能估算的越准确。 - 要让负责这个任务的人员参与估算。 - 第三步:排任务路径 - 排路径就是要根据任务之间的关系,资源的占用情况,排出合适的顺序 - 工具 - MS Project - 注意 - 制定计划时不要担心不够准确 - 先有一个基本的计划,可以粒度比较粗,不那么准确,让事情先推进起来。 - 设置里程碑 - 里程碑的时间点确定后,计划可以灵活调整,但里程碑一般不会轻易改变,因为里程碑代表着一份承诺。 - 对于项目成员来说,有两个重要的影响 - 一方面,成员会有很明显的来自 DeadLine 的进度压力,自古 DeadLine 就是第一生产力 - 另一方面,就是在里程碑完成后,大家会获得一种正面激励 - 示例 - 第一个时间点就是确定和 PC 客户端的通信协议,这样 PC 客户端可以根据这个协议开始开发功能了; - 第二个时间点就是服务端开发完成,PC 客户端可以服务端联调了; - 第三个时间点就是测试验收通过,可以上线了。 - 计划需要跟踪和调整 - 跟踪进度的方式主要有两种 - 一种是项目经理定期收集跟踪 - 一种是项目成员主动汇报 - 意义 - 通过对项目计划的跟踪,可以很容易的看出来执行的情况,也会发现偏差 - 计划出现偏差是很常见的,所以需要定期进行调整,也不需要太频繁,例如可以每周一对计划做一次调整 - 总结 - 项目计划是保障软件项目成功非常重要的手段 - 制定计划的过程,可以让你对项目有全面的了解 - 跟踪计划让你知道项目进展情况,出现问题也可以及时调整 - 将任务分解、估算时间、排路径,三步就可以制定出一个项目计划 - 制定计划不要追求完美,制定好一个初步计划后,就可以先按照计划推进起来,进行过程中还可以继续调整细化。 - 设置里程碑可以有效的保证项目的按时交付。 - 生活中每件事都可以当作一个项目,都可以去制定计划来帮助你实现目标。 - 实践 - 总结 - 计划一定是要有的,不然就完全不可控了 - 计划一定是个迭代的过程,计划也是个粗到细的过程。 - 一开始不建议特别细的计划,整体粗一点,定好大的时间节点,也就是里程碑,然后对于下一阶段的计划细化。 - 细化过程中要拉上具体参与的人一起制定 - 这样结果才科学也不会导致抵触。 - 里程碑定了后不要轻易变 - 不然就失去了DeadLine的意义,即使变也不能过于随意和频繁。 - 项目组成员进度出现偏差了,要怎么调整 - 最基本的原则就三条: - 1. 恢复生产 - 2. 总结原因 - 3. 防患未然 ### 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. 砍掉一些没价值的会议 - 没有目标的会议 - 不能形成决策,没有会后行动 - 你属于可有可无的角色 - 2. 减少参与会议的人 - 会议的成本和两个因素相关:一个是人数,一个是时间。如果减少人数,就能减少成本。 - 3. 缩短开会时间 - 当话题开始发散的时候,果断制止,放到 “停车场问题” 环节,也就是会议的最后专门讨论 - 4. 提升会议所创造的价值 - 例 - 每个会议要有明确的目的和主题 - 问题的讨论不能偏离会议的主题 - 开会后,要有明确的结论,有后续的待办事项 - 落实到个人,对待办事项有跟踪 ### 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 计划,考虑风险管理了。 - 2. 管理风险 - 第一步:风险识别,识别可能的风险 - 一个识别风险的方法叫检查表法 - 软件项目的风险主要分成以下几类 - 项目风险:项目预算、进度、用户和需求等方面的问题; - 人员风险:人员离职、人手不足等问题; - 技术风险:采用的技术所可能带来的风险; - 商业风险:与市场、产品策略等有关的商业风险。 - 第二步:风险量化,对风险进行评估量化 - 从两个方面去评估 - 发生的概率多大? - 发生后,后果多严重? - 第三步:应对计划,对风险制定应对策略 - 回避风险 —— 更改导致风险的方案 - 放弃或者修改导致风险的方案 - 从根源上消除了风险,简单而彻底 - 转移风险 —— 将损失转嫁出去 - 例 - 购买云服务 - 缓解风险 —— 降低风险发生概率或减少可能造成的损失 - 例 - 定期备份数据库 - 涨点工资,避免人才流失 - 接受风险 —— 明知山有虎偏向虎山行 - 第四步:风险监控,对风险进行监控预警 - 要做好监控 - 第一要能对监控的内容量化 - 第二要设置阈值 - 第三就是要有后续的报警和处理机制 ### 16 _ 怎样才能写好项目文档? - 短期高估文档的重要性,而长期低估文档的重要性 - 为什么要写文档? - 帮助写文档的人理清楚思路 - 先写文档,就会抛开代码细节,去站在全局思考 - 真正的障碍是没想清楚,在心中只有一些未成型的混乱的想法和概念,必须要努力把这些模糊的想法确定化和具体化,才能写出来。 - 便于未来的维护和交接 - 便于团队更好的协作沟通 - 如何写好文档? - 1. 从模仿开始 - 模仿就是最好的写文档方式 - 2. 从小文档开始 - 3. 从粗到细,迭代更新 - 从脑图开始 - 第二步就是写 PPT - 给别人讲解,收集反馈 - 搭骨架 - 对细节补充 - 4. 一些基本的画图的技巧 - 线框图 - 流程图 - 时序图 - 实践 - 大脑是用来计算的,并不是用来记忆的 - 记忆一个索引就好了 - 示例 - 产品需求文档模板 - https://www.jianshu.com/p/e89e97858be1 - 微服务:从设计到部署 - https://docshome.gitbooks.io/microservices/content/2-using-an-api-gateway.html - 需要文档列表 - 项目立项 - 原始需求文档 - 可行性分析报告 - 立项说明书 - 需求相关 - 原型设计文档 - 产品设计文档 - 其他 - 产品需求分析文档(PRD) - 产品需求规格说明书 - 系统设计 - 技术方案文档 - 详细设计文档 - 开发相关 - 代码规范文档 - 测试相关 - 测试用例 - 测试验收报告 - 运维相关 - 部署文档 - 故障报告 - 文档分类 - 1. 设计类文档 - 作用 - 主要用来说明、讨论需求设计、架构设计 - 可以用来了解、讨论和评审,以及记录后续结果 - 2. 说明类文档 - 作用 - 用来对规范、API、配置、操作等做说明,便于规范和统一 - 3. 报告类文档 - 作用 - 对事情结果的报告和说明 - 示例 - 验收报告、故障报告、调研 - 哪些文档 - 1. 这件事需要讨论需要评审,要有文档作为讨论的依据,以及记录讨论的结果。比如各种设计文档 - 2. 这件事要有规范,要有文档保证规范统一。比如各种规范文档 - 3. 这件事要记录下来,作为以后的一个参考。比如各种报告、环境配置、操作手册、API 文档等 - 从几个角度去思考文档好坏 - 1. 文档是否讲清楚了它的目的是什么? - 2. 文档是否解释了为什么要这么做? - 3. 文档是否描述清楚了如何实现? ## 需求分析篇 (5 讲) ### 17 _ 需求分析到底要分析什么?怎么分析? - 需求分析是要分析什么? - 第一步:挖掘真实需求 - 目标用户:用户不同,诉求也不一样; - 使用场景:使用场景不一样,解决方案也会有所不同; - 想要解决的问题:用户背后想要解决的问题是什么。 - 第二步:提出解决方案 - 第三步:筛选和验证方案 - 怎样做需求分析? - 1. 收集需求 - 头脑风暴 - 用户调研 - 竞品分析 - 快速原型 - 2. 分析需求 - 作用 - 对需求进行分析,挖掘用户真实需求 - 表层需求:用户对解决问题的期望 - 例如马车更快 - 深层需求:用户的深层动机,诉求产生的原因 - 例如乘客对出行速度的要求 - 底层需求:人性本能的需求 - 人性本能的需求,例如对安全感对舒适的追求 - 3. 需求评估 - 作用 - 筛选过滤掉不可行的需求 - 可行性:技术能否实现 - 成本:人工成本、时间成本 - 商业风险和收益:有没有商业的风险,收益是否合理 - 紧急性与重要性:是不是用户迫切的需求 - 评估其优先级:紧急重要四象限 - 4. 需求设计 - 针对用户需求提出解决方案,设计成产品方案 - 5. 验证需求 - 验证方案是否可行 ### 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. 需求让技术变复杂 - 2. 人员会让技术变复杂 - 让这一群人有效地协作是很大的考验 - 3. 技术本身也是复杂的 - 4. 要让软件稳定运行是复杂的 - 架构设计恰恰可以很好地解决技术复杂的问题 - 首先,架构设计可以降低满足需求和需求变化的开发成本。 - 其次,架构设计可以帮助组织人员一起高效协作。 - 再次,架构设计可以帮助组织好各种技术。 - 最后,架构设计可以保障服务稳定运行。 - 什么是架构设计? - 架构设计的目标 - 用最小的人力成本来满足需求的开发和响应需求的变化,用最小的运行成本来保障软件的运行 - 架构设计的方法示例 - 微服务 - 把复杂系统拆分成一系列小的服务,服务再拆成功能模块,让人员更好地分工协作 - 前后端分离 - 让程序员更专注于某个知识领域,降低开发难度 - 分层设计 - 隔离业务逻辑,减少需求变更带来的影响 - 架构设计的道 - 组织人员和技术把系统和团队拆分,并安排好切分后的排列关系,让拆分后的部分能通过约定好的协议相互通信,共同实现最终的结果。 - 如何做好架构设计? - 第一步:分析需求 - 第二步:选择相似的成熟的架构设计方案 - 第三步:自顶向下层层细化 - 部署架构 - 分层和分模块 - API 设计、数据库设计、模块的设计 - 第四步:验证和优化架构设计方案 - 方案的验证是贯穿整个设计始终的 - 一个完整的架构设计方案,需要有多次的评审会议,充分收集各方面的反馈,反复修改后才能最终确定下来 - 推荐学习材料 - 《Software Architecture Patterns》 - O’Reilly - 软件架构入门 - 阮一峰老师 - 《架构师之路》 - 《图解:从单个服务器扩展到百万用户的系统》 - 《以 “前浪微博” 场景为例,谈谈架构设计流程四步曲》 - 《架构整洁之道》 - 架构设计书籍中写的最透彻最浅显易懂的一本 - 《极客邦池建强:难的不是从零打造一款产品,而是……》 - https://www.infoq.cn/article/q7xlHaaiZ-9H6SwHXCNg ### 22 _ 如何为项目做好技术选型? - 技术选型就是项目决策 - 技术选型看起来是个技术的选择,但其实是一个和项目情况密切相关的项目决策 - 受制于时间、范围和成本的约束 - 时间 - 范围 - 成本 - 要分析可行性和风险 - 要考虑利益相关人 - 项目决策中常见的坑 - 把听到的观点当事实 - 先入为主,有了结论再找证据 - 如何做好技术选型? - 问题定义 - 只有明确了技术选型的目标,才能有一个标准可以来评判该选择哪一个方案。 - 调研 - 验证 - 决策 - 实践 - 开源技术选型 - 1. 先找朋友推荐,少走一点弯路 - 2. 没有推荐的话,就去网上搜索,找几个满足需求的备选。 - 3. 对比以下几个指标: - 代码质量、有无测试 - 文档健全度 - 看Issue处理情况、最后更新时间(无人维护的项目后续恐怕有问题都没法解决) - 看Star数量,通过Google和StackOverflow看使用情况 - 4. 自己按照说明试试看 ### 23 _ 架构师:不想当架构师的程序员不是好程序员 - 什么是架构师思维? - 对于架构师来说,要控制技术复杂性,有几种有效的方式 - 抽象 - 分治 - 复用 - 迭代 - 抽象思维 - 在软件项目中,遇到类似的场景,就会考虑抽象出来,总结一个规则和方法 - 分治思维 - 对复杂系统要分而治之,分解成小的、简单的部分。但光分解还是不够的,同时还需要保证分解后的部分能够通过约定好的协议集成在一起。 - 复用思维 - 一种非常简单有效的提升开发效率的方法,通过对相同内容的抽象,让其能复用于不同的场景。 - 迭代思维 - 好的架构设计,通常不是一步到位,而是先满足好当前业务需求,然后随着业务的变化而逐步演进 - 好的架构师什么样? - 一个好的架构师,不仅技术要好,还要懂业务;能从整体设计架构,也能在局部实现功能。 - 要成为好的架构师,需要具备几个条件 - 1. 有架构师思维:具备良好的抽象思维、分治思维、复用思维和迭代思维; - 2. 懂业务需求:能很好地理解业务需求,能针对业务特点设计好的架构; - 3. 有丰富的编码经验:像抽象、分治、复用这些能力,都需要大量的编码练习才能掌握;另外保持一定量的编码经验也有助于验证架构设计; - 4. 良好的沟通能力:架构师需要沟通确认需求,需要让团队理解架构设计。 - 如何成为好的架构师? - 要成为一个优秀的程序员 - 多模仿多学习 - 选择好行业和平台 - 实践 - 架构师之路 - 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. 充分理解清楚需求 - 2. 加入非功能性的需求时间 - 3. 将任务分解的尽可能细 - 4. 综合考虑任务并行的情况(线上 bug、开会等) - 5. 计划保持及时更新 - 6. 留一点余量,应对突发情况 - 参考书 - 《人件》 - 经典的软件工程书 - 对如何提高效率,讲了很多方法 - 《高效能人士的七个习惯》 ### 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. 自驱动意识 - 2. 沟通协调,刨根问底 - 3. 经常自省 - 4. 敢于担责 - 5.ownership - 方法论(做事方法) - 1. 二八原则 - 2. 时间管理四象限 - 3.SOP - 4.ARCI - 5. 敏捷迭代 - 如何看书 - 书看一遍肯定记不住,得经常翻才行 - 看完得思考 - 思考完了还得实践 - 实践完了还得总结思考 - 最后才能变成自己的知识 - 实践 - 学习之前有思考 - 学习有总结 - 学习之后有行动 ### 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. 回顾项目目标 - 2. 评估项目结果 - 3. 分析原因 - 4. 总结规律,落实行动 ## 经典案例解析篇 (7 讲) ### 40 _ 最佳实践:小团队如何应用软件工程? - 团队建设方面 - 招人 - 找一些有潜力的培养,也要注意梯队建设,中间有技术骨干补充 - 培养人 - 给新人安排师傅的方式培养新人 - 日常注意代码审查 - 内部技术分享是个不错的共同提高的方式 - 技术高手要注意不只是闷头干活,也要承担一定的带人的工作 - 管理人 - 核心在于营造好的氛围,鼓励成员自我驱动去做事 - 开人 - 不适合团队的人也不要手软,及时的淘汰 - 流程建设方面 - 选择合适的软件开发模型,建立项目开发流程 - 构建基于源代码管理工具的开发流程 - 建立外部提交需求和任务的流程 ### 41 _ 为什么程序员的业余项目大多都死了? - 1. 想法大,时间少 - 2. 过于追求技术,缺少约束 - 3. 缺少产品能力和运营能力 ### 42 _ 反面案例:盘点那些失败的软件项目 - 成功的项目必须满足六个条件 - 项目管理协会(PMI) - 1. 按时交付 - 2. 成本在预算范围内 - 3. 能按照当初的设计正常运行 - 4. 有人使用 - 5. 满足项目最初的目标 - 6. 项目出资方对项目满意 - 分析失败软件项目的原因 - 外部环境 - 技术管理 - 项目管理 - 组织文化 - 参考书 - 《梦断代码》 - 《梦醒时分 - 梦断代码读后感》 - 邹欣老师 ### 43 _ 以VS Code为例,看大型开源项目是如何应用软件工程的? ### 44 _ 微软、谷歌、阿里巴巴等大厂是怎样应用软件工程的? ### 45 _ 从软件工程的角度看微服务、云计算、人工智能这些新技术