《构建之法》 读书笔记

我能体会到邹欣老师的《构建之法》是一本很不错的书,不过三年前苏航推荐给我的时候,当时的自己还没经历过软件的项目,所以感触还没那么深刻。最近因为为了更好沉淀自己的契机,于是重新学习了这本书。

以下是我学习此书后的认知构建,我会从总到分一点点拆分出来,分为四个内容

  1. 软件是什么的概述
  2. 软件工程的理解
  3. 软件项目中的角色
  4. 人和绩效

1. 软件是什么

本书上来第一个先要阐述的,是软件是什么,软件有什么用。根据邹欣老师的定义:

软件=程序+软件工程
软件企业=软件+商业模式

程序好理解,就是代码,包括算法和数据结构;软件工程是什么呢?软件工程决定了软件的质量,它的定义为把系统、有序、可量化的方法应用到软件的开发和运维过程,这些过程统一到一个体系,就是“软件开发流程”;商业模式则是决定软件企业的成败。

2. 软件工程

软件工程可以用“软件开发流程”来体现,那从项目的维度,更多就是确保软件可以按照流程很好地执行,从而来提高开发软件的质量。之所以需要软件开发流程来约束,因为每个人都有自己的局限性和优势。把大家聚集起来后,想让大家成为一个团队,那必须要有两点:1. 大家有共同的目标;2. 大家各自分工,互相依赖合作完成任务。为了实现这两点,则需要大家来遵守的软件开发流程。

2.1 角色

正常的软件开发由五或六个角色组成,其中包括了产品,项目,交互,开发,测试,运维。其中在纯软产品开发中,产品和项目有时会是同一个人。这些角色按照软件开发流程,在一个项目的不同时期会投入不同精力。具体的结合后面开发流程逐渐展开。

2.2 开发流程

开发流程一般分为三类,写了再改模式(code and fix),瀑布模型和敏捷开发。

写了再改的模式更适用于个人学习,或者只用一次,或者演示用的场景下;瀑布是从成熟的硬件行业借鉴和迁移过来并进行变形;敏捷就是基于软件的特点,开发最小可用产品后,不断根据实际反馈迭代和开发。

写了再改的模式就不细说了。下面对瀑布型和敏捷型分别展开阐述。

2.2.1 瀑布模式

瀑布型开发是从原来成熟的硬件开发或者建筑工程借鉴过来。它的特点是因为不可逆性(返修改特别困难),是一种单向的项目流程。因此前期的评审确定和确定极为关键。但是在软件的项目过程中,因为代码是可以比较容易修改的,所以更强调了回溯,即一旦哪个环节出问题,可以回溯到上一个环节重新确认和修改。甚至极限地还引出了敏捷开发的流程。但本小节我们就先谈谈瀑布型。

2.2.1.1 瀑布模式的步骤
  • 需求引入:理解用户的使用场景和使用需求,并把需求转化为工程师能理解的需求列表,功能的约束条件,怎么验证满足需求;此处主要是产品经理来主导
  • 分析和设计:将需求进行拆分和设计,让工程师可以知道系统要分为多少模块,又有多少子系统来设计,开发可以对设计思路先用call flow画出来,UX也可以开始设计交互逻辑;此处主要是研发负责人和UX来主导
  • 软件开发:按照设计,对每个模块的功能进行实现,并进行单元测试,之后再进行模块集成并自测没问题后,提交给测试进行测试;此处主要是开发主导
  • 软件测试:根据需求和开发内容出对应TC并对集成后的软件进行系统测试,包括功能测试,异常测试和datalog测试,如果有bug则打回给开发,如果没问题,则准出软件;对于迭代项目,测试还需要进行冒烟测试和回归测试;此处主要是测试主导
  • 软件部署和运维:将项目部署到线上环境给客户使用;日常监控是否会有异常现在,有的话反馈给开发和测试进行处理;此处主要是运维主导,除了问题后开发和测试也要参与进来

而通过演变后,最后在软件开发的瀑布流程演变如下:

屏幕快照 2020-07-30 上午11.29.36.png

这样模式最大的难度在于每个子系统开发完后还需要合并,合并过后系统测试后才能交付,这段时间之前客户或者用户都是拿不到软件demo。

2.2.1.2 瀑布模式的适用项目类型

img

2.2.1.3 做B端项目--以LG项目为例子

做LG的项目的时候更多会按照上面大瀑布+小瀑布的方式来实现。因为这种B端定制项目中,一般需求不会经常变化,而且产品需要有高的可靠性,同时项目会有多人参与,所以瀑布型的会更加合适。此时,前期单线的大瀑布就是和客户确认完需求和设计路线,之后就是内部员工一起分工开发,最后再集成测试。等我们测试没问题之后,再交付给客户进行验收阶段。

而我们和客户合作过程中,就需要搭建不同的环境来满足不同的需求。

  • 企业自己的开发环境--用于开发项目和调试用
  • 企业自己的测试环境--用于测试团队的测试
  • 客户的开发环境--客户开发团队测试
  • 客户的测试环境--客户测试团队测试
  • 线上环境--用户使用的环境

当然不同企业或者客户上述会略有不同,比如开发和测试环境合并。但是这么设计主要还是为了隔离,确保环境的纯净,不会并行项目干扰。这样纯洁的环境,不仅在开发过程有用,在查bug的时候也有用。比如线上发现bug,我们就可以在之前的测试环境进行复现和解决,没问题了再上线。

为了项目有较高的鲁棒性,我们开发新功能或者bug修复后,客户一定要进行DVT和CVT,在两个环境由不同团队验证没问题后,会允许项目上线。

2.2.2 敏捷开发

敏捷开发雏形是史蒂夫·迈克康奈尔在1996年总结提出,主要就是明确了需求和架构之后,团队进入了一个不断演进的循环。

软件开发到什么程度截至呢,下面三个条件满足其一即可

  • 时间到了
  • 没钱了
  • 用户满足了,不满意不再给钱了
2.2.2.1 敏捷开发的流程步骤
  • 需求确认,找出产品需要完成的事情--Product Backlog:产品负责人领带团队对backlog条目进行细化和工作量评估,单位为:人天
  • 当前任务确认,找出当前的冲刺(Sprint)需要解决的事情--Sprint Backlog:产品的实现被划分为几个阶段,同时任务颗粒度被拆分更新(16h以内),团队成员根据自己情况来认领
  • 冲刺--Sprint:根据上面的任务开始冲刺,冲刺期间开发不允许被打扰,直到开发需求完成。
    • 每日例会:冲刺期间开每日例会,每个人汇报自己手头每个任务内容:1. 昨天什么状态,2. 今天什么状态(还需要多少时间),3. 任务做好后要交给谁,4. 有没有遇到问题
    • 燃尽图:每天跟踪三个指标:1. 实际项目全成员剩余时间综合;2. 根据每人每天进度预计剩下时间;3. 实际花费的时间
  • 发布:得到一个软件的增量版本,发布给用户后,进一步计划增量的新功能和改进
2.2.2.2 敏捷常见注意点
  • 各任务之间的依赖关系要体现好
  • 需求转化为技术要求,一定要细致才好实现
  • 要注意每日站会要有收获以及从燃尽图中发现问题
  • 任务完成的标志是什么?基础功能开发好?品质测试过关?可能基本功能开发后,后面20%功能,如两端对齐,不同屏幕适配等会花80%的时间
  • 一个增量循环完成后,要确认产出是否满足需求
  • 如果冲刺过程中,发现有问题怎么办,一般都还是完成冲刺,然后之后再改需求
2.2.2.3 选择用敏捷的标准

除了上述瀑布型的表格,还可以通过下列问题串可以确定视频否偏向用敏捷型

  1. 项目有明确spec吗?
  2. 项目没有明确用户,或没办法联系用户沟通
  3. 软件系统是大型的吗
  4. 软件系统是复杂的么?比如实时系统
  5. 软件的生命周期很长么
  6. 软件合作工具比较差吗
  7. 软件项目组成员分布在不同地方吗
  8. 团队是否“文档优先”的传统
  9. 团队编程技术比较差
  10. 交付是否要通过某种行业规定或行政法规批准

如果上述问题中,yes偏多,则可以偏向瀑布型;no偏多,则可以用偏向敏捷型

2.2.2.4 内部项目中对敏捷的运用

在内部的项目中,我们对敏捷的运用主要是在软件中台的内部项目日常迭代上,包括云端和APP。采用就是版本列车的方式

  • 一旦需求进来后,产品经理会把需求汇总在项目需求池(Backlog)。此处的需求不仅包含外部需求,还有包含bug转需求的部分
  • 每一个迭代版本,和开发协定好要做的功能,把这部分需求放到这一期的Sprint Backlog
  • 当开始冲刺,那么就不允许新的需求进来

然后重复以上的工作。三周发一个版本列车。

3. 软件项目中的角色

3.1 开发工程师

开发工程师除了开发代码以外,还要参加质量保证的工作中去。一般来说,越高级的开发,码代码的时间可能占20%,其他时间都是在保证软件质量工作中。具体可以看第二小节。该小节更多先阐述除了写程序以外,作为开发工程师应该做的两件事

3.1.1 单元测试
  • 开发除了开发代码,单元测试原则上必须由写代码的开发完成。因为他是对自己的代码最熟悉的人
  • 单元测试应该在最基础的功能/参数上验证程序的正确性
  • 单元测试后,机器状态应该保持不变,这样就可以不断进行测试,而不会机器状态被单元测试影响
  • 单元测试要快,应该是秒级别的而非分钟级别
  • 重复测试的单元测试结果应该一致
  • 单元测试应该覆盖所有代码路径
  • 产品代码升级时,单元测试的代码也应该升级,要一起维护
  • 单元测试应该集成到自动测试的框架中
3.1.2 能效分析

可以通过能效分析工具,对自己的代码进行分析,这样可以提升代码能效和开发工程师的编程水平

3.1.3 个人项目耗时对比记录表

作为开发,每一次项目过程中,都可以去研究对比自己项目预计时间和实际时间,这样也可能看出自己哪些需要补足。

另外,在研究对比中,发现越高级的开发,在需求分析测试花费的时间会越多,具体编码花费的时间会越少。

PSP--personal software process 个人开发流程 Personal Software Process Stages Time(%)
Planning 计划
Estimate 估计这个任务需要多少时间
Development 开发
Analysis 需求分析
Design Spec 生成设计文档
Design Review 设计复审(和同事审核设计文档)
Coding Standard 代码规范(为目前的开发制定合适的规范)
Design 具体设计
Coding 具体编码
Code Review 代码复审
Test 测试(自测,修改代码,提交修改)
Reporting 报告
Test Report 测试报告
Size Measurement 计算工作量
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划

3.2 质量保证和测试

3.2.1 质量保证和测试定义和区别

在书本中。区分了质量保证和测试。我们可以先看下软件质量的定义是什么。

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

程序质量的表征就是外在功能的实现。这种不仅在正常功能,还有一些极限条件下的功能等等,各种情况是否都被考虑到。

软件工程质量的表征就是“快,好,便宜”,通俗说就是在“功能,成本,时间”三方面满足利益相关方的需求

那测试和质量保证区别在哪里

  • 测试定义:运用一定的流程和工具,验证软件能实现预先设计的功能和特点,工作流程和结果通常都是可量化的。
  • 质量保证定义:为了让软件达到事先定义的质量标准而进行的所有活动,包括测试
3.2.2 软件质量保证的成本

软件质量不是只有QA来干,从下面可以看出,开发,测试,项目都应该参与到软件质量保证中来

  • 预防:为了防止事故发生,软件团队要改进软件流程,质量监测的基本建设和工具,包括相关培训
  • 评审:为了评价软件质量,要对需求文档,开发代码和测试用例进行评审
  • 测试:对所有功能,极限情况进行测试,能效分析测试,若有bug修复要先进行冒烟测试,若有大版本发布还要考虑回归测试
  • 内测bug处理:内测过程发生的问题都要处理,处理过程要有bug report,文档记录复现过程,出问题原因,代码修改,TC增加,影响面等)
  • 公测bug处理:同内测bug处理
  • 流程分析改进:分析bug多发的原因,和队友沟通讨论怎么改进
  • 提高职业技能:参加一些培训和讨论;或者练习写一些自动化测试脚本
  • 投资软件工具:购买合适软件工具,并学习这些工具让其发挥最大化功效

回归测试:把以前发现的所有bug一个个再验证一遍,确保原来的问题没有再次出现

3.2.3 测试的角色要独立么

正常来说,测试的角色应该独立出来,不应该是开发来承担,但是若是下面三类情况,则可以不用额外测试

  • 项目特别小
  • 项目刚起步,分工还不明确
  • 资源严重不足,比如项目只有2个人

但是一旦要做交付类产品,还是要有专职测试会更合适

3.3 项目经理/Program manager

3.3.1 三类PM

product manager:产品经理——正确地做产品。核心就是根据市场和用户需求,协调部门资源,把握产品定位和方向。

project manager:项目经理——正确地做流程。对项目流程负责,从项目立项到上线,负责资源协调,风险管控等。

program manager:微软的职位名称。负责开发和测试以外所有事情,是上述两种PM的综合。

  • 开发和测试以外,还有啥事?
    • 功能设计,需要计算机专业知识
    • 商业理解,对商业和用户有深度理解和洞察能力
    • 流程驱动,推动项目进程和管控
    • 专业领域,对某一领域有专业和深入了解
    • 科研转产,把前言科技引入主流产品,做技术转化

Program Manager vs. Project Manager

Project Manager Program Manager
是团队的行政领导,带领大家在项目中工作 和大家平等工作,推动团队完成软件的功能
通常是团队和外界打交道的唯一代表 一个团队可以有很多PM
对项目的功能有最后的决定权 管事不管人
不一定做具体工作 一定做具体工作
  • 为啥不领导,而是平等工作?——平等沟通和职级可以更好激发讨论并取得客观好的结果;平等的PM要凭着自己的能力说服其他团队成员,这样才能更赢得团队的信服和尊重。若从上至下,则可能推动但赢得不了尊重,内在凝聚力涣散。
  • PM最独特的贡献是什么?——带领团队达成最重要的目标,并保持团队的平衡(最好的结果就是软件工程的好,省,快)
  • PM文化的副作用?——如果PM无强烈的责任感和强大推动力,满足于通过平等而反复的讨论得到团队公示,可能的后果就是“委员会设计”,设计出来的产品跟不上市场变化,用户体验平平无奇,最后连团队内部都忍受不了这样的中庸产品。
3.3.2 项目风险的类别和应对

PM要在整个项目的生命周期管理风险。对于软件项目来说,风险是在正常软件生命周期事件之外的、可能发生的影响项目的成功的事件。——今天的意外,就是昨天的风险。

项目风险的类别和来源:

风险的类别 风险的来源
人员 客户,最终用户,利益关系人,项目成员,合作伙伴
流程 项目的预算,成本,需求
技术 开发和测试工具,平台,安全性,发布产品的技术,与我们产品相关的技术
环境 法律,法规,市场竞争环境,经济情况,技术大趋势,商业模式,自然界

应对风险的手段

应对手段 具体例子
进一步研究 比如新的技术协议要出来了,原来的旧产品可能会被淘汰。此时最好重新做扎实的技术研究
接受 比如高层可能有人事变动,会影响到项目--掌控不了的事情,就课题分离
规避 比如新法规对隐私有了新的限制,开发过程能否加入设计来规避
转移 比如出海项目遇到专利指控,请法务部或者当地代理负责--把风险转交给有能力处理的部门
降低 比如做好评审和回归,降低可能的bug风险
应急方案 比如公司突然砍预算,要制定plan B来保证项目目标可以正常达成
3.3.3 PM的能力要求和任务
能力要求: 解释
观察、理解和快速学习能力 新领域快速上手能力;同理心来理解同事,用户,老板,利益相关人;
对技术能快速理解并传达,让开发和需求端可以互相理解
分析管理能力 面对项目能快速找到问题点,理清优先级,并做判断和决策
一定的专业能力 心理理解;对各种文字,图纸,表格等方式表达自己想法;行业技术
自省的能力 需要自省和自我改进

作为PM的任务:

  1. 带领团队形成团队的目标/远景,把抽象的目标转化为可执行的、具体的、优美的设计;
  2. 管理软件的具体功能的生命周期。
  3. 创建并维护软件的规格说明书,让它成为开发/测试人员及时准确的指导,而不是障碍;
  4. 代表客户和用户的利益,主动收集用户反馈,预判用户新的需求。协调并决定各种需求的优先级;
  5. 分析并带领其他成员对缺陷/变更需求形成一致意见,并确保实施;
  6. 带领其他成员确保项目保持功能/时间/资源的合理平衡,跟踪项目进展,确保团队发布令客户满意的软件;
  7. 收集团队项目管理和软件工程的各种数据,客观分析项目实施过程中的优缺点,推动项目成员持续改进,从而提振士气。

4. 人和绩效

在管理项目的时候,为了激励团队成员,绩效自然是逃不过的话题。

4.1 猪,鸡和鹦鹉合伙的故事

三种动物合伙创业,做早餐店。其中猪提供猪肉;鸡提供鸡蛋;鹦鹉提供咨询,每天阅读大量资料,给其他成员提供意见。

那这个创业,对三种动物负担一样的么,它们各自应该占有多少股份?一旦失败,各自承受的代价是什么?

  • 猪:他们或者辞掉了工作, 投入创业中; 或者这一门软件工程课是他们的必修课, 他们一定要拿到高分, 才能提高自己的GPA, 申请到好学校。 对他们来说, 要想项目成功, 他们要拿出自己身上的肉, 背水一战; 一旦失败, 自己的老本也赔进去了. 他们的投入级别是 - 全身心投入 (committed).
  • 鸡:他们能做重要的贡献, 但是项目一旦失败, 他们的损失并不大, 他们的生活还可以继续下去。例子: 有些人周末来给项目帮忙, 平时自己上班; 或者是选修软件工程课; 或者他们已经保研, 只要这门课混及格就行。 他们的投入级别是 - 参与 (involved).
  • 鹦鹉:他们有漂亮的羽毛, 能说会道, 联系广泛, 能提出很多建议, 很多点子. 但是他们不执行, 除了一些人云亦云的观点和一些关于架构的空谈之外, 他们没有其他投入. 一旦项目失败, 他们就会飞到另一个项目中去。 他们的投入级别是 – 围观 (bystander).

一个人可以同时做很多事,这些事情对每个人的轻重缓急各不相同。 加入一个团队时要弄清楚自己在团队中投入的级别是什么,别人的期望值是什么。 不要拿着卖白菜的钱,操那卖白粉的心 - 太不值得。 人可以在 n 个地方做鸡,或者 n×m 个地方做鹦鹉,但不可能在两个地方同时做猪。

在做一个事情的事情,团队成员多元化也很关键,但是也要分清楚团队成员中不同的角色--投入/承诺/责任。

在遵循敏捷原则的团队里, 成员们并不忌讳谈论不同的投入和负责程度 - 因为这就是现实。 但是他们一般有一个原则: 重大决定由 “猪” 来定夺。

衍生出来,在跨部门合作或者评绩效的时候,要理清不同部门的权力, 责任和流程,可以用下面RASCI的模型

R: Responsible, 负责把具体事情做好。

A: Accountable, 对任务负全责, 有批准的权力

S: Support, 对任务提供支持, 辅助任务的完成

C: Consulted, 咨询, 拥有完成项目所需的信息或能力的角色。

I: Informed, 知会者, 应该事后及时通知结果的角色

面对多个部门,分清他们属于RASCI的哪一个角色, 然后依照相应的规范行事即可。

4.2 绩效管理

绩效管理是个很难回答的问题。作者其实罗列了各种办法,但每一种办法的不足之处,但是最后还是没有一个通用解,只能说根据实际情况。

现在市场上比较通用的,就是用2:7:1的方式划分出三类员工,然后用以下两种方式评绩效。它们的弊端也附在后面

  • 等级划分并公开刺激——为了保住自己的位置,招聘会倾向招比自己能力差的人,进而长久整个团队素质下降
  • 闷声领导直接决定,然后反馈给员工是钱和具体工作反馈,但员工不知道排名和标签——各级评分人会给自己人高分,给别的部门低分。

img