10x程序员工作法总结

2020年6月18日星期四,至今最晚的一次下班打卡时间,次日凌晨1点44分。因为项目上线不顺利,我和其他小伙伴们一起留下来渡过了一次难忘的上线经历。
在这个项目中遇到了很多坑,也埋下了很多坑。后来在极客时间上学习了郑烨老师的《10X程序员工作法》之后很有感触,如果早点看到这篇工作法,也许就不会有这么多坑了,项目也不会这么曲折。在此做一下总结。

情景描述

先来回顾一下这个项目,项目不便透露细节,所以进行简单描述

  • 一句话概括:这是一个动作很大且很复杂的工程,需要打通两个不同体系的系统,将系统进行整合。
  • 工作内容:将用户体系进行合并,统一登陆机制、鉴权机制。两个系统底下的子业务模块要能够无缝衔接。

复盘

为什么上线这么不顺利

倒推到需求和开发阶段

  1. 需求不够明确

    需求粒度太大,看不到需求的终点,无法明确的定义怎样才算完成需求,缺少验收标准。

需求不仅来自产品经理,也来自一些其他技术需求,假设有“迁移角色权限”这个需求,在研发的思维里就是写个SQL或者自动化程序将角色的权限从旧库表迁移到新库表。但是很难界定完成的标准。
迁移完系统A的角色权限就算迁移完了吗?系统B的角色权限要迁移吗?
系统B是另外B部门负责的,所以他们负责迁移系统B的角色权限。
B部门知道迁移的规则吗,要不要告诉他规则和注意事项,新旧表的字段结构如何对应,需要协助B部门吗,如何协助B部门?
站在老板的角度看,“迁移角色权限”这个需求一定是A系统和B系统都迁移整合完才算完成,A系统迁移完只是阶段性的成果。
站在研发A的一亩三分地,自然认为这个需求完成了,把需求状态改为done,这时候又有新的需求分配过来,研发A就去做新需求了,过段时间研发A已经记不清到底任务完成没,只知道“迁移角色权限”他是done的状态,印象中也是完成的。
至于B部门的迁移任务在研发A里自动被忽略了。

  1. 任务分解不到位

    接到需求后马上着手开始工作,在工作被中途打断后,很难继续上次被中断的地方,造成关键步骤的遗漏。

还是以“迁移角色权限”这个需求为例,研发A看到这个需求马上就想着开始干吧,然后马上就开始写代码了。因为没有做任务分解,常常会因为任务的中断而不知道自己做到哪一步了。在日常开发中经常会有优先级更高的需求或者排查其他问题导致任务被中断,等后面回过头来时往往记不清自己做到哪一步了。
如果研发A做了“任务分解”,在任务分解过程中发现这个任务还需要B部门协助,就应该把B部门任务也列出来,列出具体步骤,并且向上沟通反馈到产品经理,产品经理知道这个需求应该要拆分成两个需求,把B部门的任务分配给B部门。

  1. 沟通不到位

    每个人所理解的世界是不一样的,在口头表述的消息传递过程中会出现信息丢失,理解偏差的问题。

在跨部门的项目中团队间沟通反馈不够及时。中途存在多个产品经理共同提需求的情况,需求需要跨部门的研发配合,存在沟通问题。其实有些需求应该是对应的产品给自己的研发团队提需求。在跨部门合作中资源协调时沟通反馈往往不够及时,是很大的一个问题。

在大项目进行中还时不时的加进来一些其他需求,而这些需求往往会干扰正在做的最重要的事。有些需求其实是可以和产品沟通,甚至和老板沟通,而可以延后做甚至不做的需求。
在不同上下文沟通中容易出的问题,研发人员往往会把自己局限在“程序员”这个角色中,在上下级沟通的时候往往只看到自己的一亩三分地。很难从更高的视角甚至站在全局去考虑问题。

  1. 系统构建问题

    没有做到每日构建,代码风格检查。构建失败问题拖延项目进度。

工程中统一用Gradle构建,但是工程的构建脚本中没有指定构建的gradle版本号,gradle的wrapper文件没有提交到git仓库。由于每个人的开发环境存在差异,下载代码后出现你构建成功我构建失败的情况。
旧项目早期就存在的构建规范和提交规范问题没有得到重视。新人接手时感觉就像在泥潭里构建系统。
系统构建问题,是研发的一个共识问题,应当保证系统每日正常构建,保证提交代码的质量,但是这些我们做的都不好。
在开发阶有人提交了一个无法编译通过的代码,合并后导致构建失败,前端小伙伴可能正在调试某个接口,突然就服务不可用了,容易影响对接进度。
还有一个很关键的问题是单元测试和集成测试的问题没有落实到位,有几个核心类库是另外一个部门提供的,我们的使用不当导致上线后出现了很严重的bug,先不说类库的设计问题,我们在使用这些核心方法的时候没有做集成测试,没有文档,凭感觉就去使用了,如果做了集成测试,这些都可以避免。

项目总结

经过这次项目,再结合10X程序员工作法,可以总结出几个问题:

  1. 需求不够明确,粒度太大看不到需求完成的标准,一个需求做的没完没了
  2. 任务分解不到位,遗漏细节和步骤
  3. 沟通反馈不够及时
  4. 日常构建不够好,经常构建失败中断测试。
    看过去大家都在忙碌的解决问题,但是解决的大多数都不是程序问题。

10X程序员工作法

大部分程序员忙碌解决的问题,都不是程序问题,而是由偶然复杂度导致的问题。
如何减少偶然复杂度引发的问题,让软件开发工作有序、高效地进行是 10X工作法要阐述的核心内容。

《10X程序员工作法》这门课程阐述的其实是互联网团队如何能更加高效率的协作,不仅适用于程序员,也很适合项目经理,产品经理等人员。

《10X程序员工作法》主要原则有如下4个:

  • 以终为始
  • 任务分解
  • 沟通反馈
  • 自动化

以终为始

在做任何事情之前,先定义完成的标准。

这是一种向后工作法,遇到问题倒着想。
“迁移角色权限”这个需求,倒着想就是系统A和系统B的角色权限都要迁移完成才算完成。应该把这个需求拆分成“系统A迁移角色权限”和“系统B迁移角色权限”这两个父需求。再把这两个父需求分配到对应的研发团队。
研发团队A接收到“系统A迁移角色权限”这个需求后,第一步也是先确定完成的标准,要把角色A、B、C、D角色的权限都迁移完才算完成。

关于完成的定义,每个团队都有自己的标准,可以列一个DoD(Definition of Done,完成的定义)清单,由一个个的检查项组成的,用来检查我们的工作完成情况。DoD 的检查项应该是实际可检查的。

你说代码写好了,代码在哪里;你说测试覆盖率达标了,怎么看到;你说你功能做好了,演示一下。

当我们有了 DoD,做事只有两种状态,即“做完”和“没做完”。在团队协作中,我们经常会听到有人说“这个事做完了 80%”,对不起,那叫没做完,根本没有 80% 做完的说法。
DoD 是一个的思维模式,是一种尽可能消除不确定性,达成共识的方式。

“以终为始”的方式,不仅仅可以帮我们规划工作,还可以帮我们发现工作中的问题。
在做事之前先想结果是什么样子的,对做软件的人来说,我们应该把“终”定位成做一个对用户有价值的软件。

任务分解

在接到一个需求之后,先做任务分解。将一个原本毫无头绪的问题分解成若干个可以尝试回答的问题,写代码只是最后一步。

如今软件行业都在提倡拥抱变化,而任务分解是我们拥抱变化的前提。
一个大问题,我们都很难给出答案,但回答小问题却是我们擅长的。
用这种思路解决问题的难点是给出一个可执行的分解。

“系统A迁移角色权限”,任务分解

1
2
3
4
5
1. 迁移模板角色A的数据
2. 迁移模板角色A权限数据
3. 迁移子角色A数据
4. 初始化子角色A的权限数据,根据所属的模板角色A进行权限复制
5. 迁移子角色B的权限数据...

可以看到一个角色权限迁移包含里很多步骤,这些步骤缺一不可,并且要按照前后顺序。比如第2步的模板A角色的权限如果没有先迁移,先做了第4步复制模板角色A权限值就会复制到空值,造成数据缺失。

与很多实践相反,任务分解是一个知难行易的过程。
不同的可执行定义差别在于,你是否能清楚地知道这个问题该如何解决。

按照完整实现一个需求的顺序去安排分解出来的任务,最好按照一个需求、一个需求的过程走,这样,任务是可以随时停下来的。
检验每个任务项是否拆分到位,就是看你是否知道它应该怎么做了。

沟通反馈

站在更大的上下文中思考问题。

日常开发中会经常的有人告诉你这个需求很着急,销售已经把话吹出去了客户今天就要。产品经理说这个是老板要的,很着急…

“任何需求的最佳完成时间都是昨天”,在时间规模为1的时间里,要同时做两个规模分别为1的需求,显然是不合理的。
“这两个需求是领导要的,都很着急”,那就跳出自己的工作上下文,在一个更大的上下文中沟通,拉着产品经理一起去找老板,让领导决策那个需求更加重要。
相信一个精明的领导是不会提出多个需求要在不够的时间内同时进行的。也许其中一个需求只是领导为了验证某种结果而提的,不马上做其实也可以,通过更大的上下文沟通知道可以放弃一个需求,就避免了可能出现的主要进度拖延问题。
如果正的两个需求同等重要且紧急,在更大的上下文中和领导沟通,能够及时的反馈出自己项目人力有限,尽早的暴露出来给领导,让领导做决策是应该砍掉其中一个需求,还是由领导将其中一个需求分配给其他项目组来做,在更大的上下文中让领导协调资源是比较推荐的。

如果自己不能决策,就将问题尽早的暴露给更大的上下文,通过沟通反馈让领导决策。

自动化

软件产品解决了领域问题给用户带来了自动化,软件研发团队也应该用自动化的工具方便自己。

关于单元测试很多小伙伴都不怎么写,现在我越来越意识到单元测试的重要性,我对自己的代码要求必须要写单元测试。
单元测试不仅是测试程序本身,还可以解决两个问题,一个是反向让自己面向接口编程写出可测试的代码,写需求之前要想着这个功能要如何验证,写出可测试的代码单元是很重要的,把方法解耦,规范自己的代码。另一个方面,提交前运行一下单元测试,可以验证是否有编译问题,最近的修改是否会影响已有代码的逻辑。如果单元测试不通过说明逻辑不通过,需要调整代码直到逻辑通过。再放心无脑的提交。

总结

我们走敏捷开发,但任务看板上的很多需求也就只有一个标题来描述需求,基本没写用户故事和需求说明。
虽然有原型图的链接,需求评审和需求会上也会描述产品原型,但是一个会议很难面面聚到,没有需求的描述补充,很容易遗漏细节,或者一个需求里包含了隐藏的子需求。导致研发在做这个需求的时候没有终点,看不到目标。

  1. 接到需求的第一件事是确定为何要做这个需求,如果没有用户故事,至少要先补充完成的标准,知道如何验证。
  2. 做需求前一定要先做任务分解,把需求分解成一个个可执行的任务,每做完一个任务,代码都是可以提交的。
  3. 跳出自己的一亩三分地,站在更大的上下文中沟通和思考问题。
  4. 在任务特别多的时候应该做一个优先级排序,把任务分解为“紧急”和“重要”两个维度。 重要且紧急的任务第一优先,重要不紧急的事情第二优先,紧急不重要的事情能不做就不做,或者与他人一起分担。不重要不紧急的事情不做
  5. 编写可测试的代码,多写单元测试,多学习好的设计,少一点问题。
0%