最近在学习郑老师的 10X 程序员工作法,课程里面有很多值得学习和借鉴的地方,也有很多有趣的地方,做个整理,希望在整理的过程中能学习到更多的技巧,通过实践去达到融汇贯通的目的。

综述

到目前为止工作满打满算也有2年多一点了,从最初的懵懵懂懂到现在的独当一面,从最初自动化入手,到现在各种需求的开发以及 bug 的解决,我对自己的进步还是相对比较满意的,直到我在 《10X 程序员工作法》课程中看到了一句话:

优秀程序员的开发效率是普通程序员的10倍。 — 《人月神话》

想想自己的效率离这个结论还是差了十万八千里,路漫漫其修远兮,吾需继续努力呼。

既然有了差距,那么就需要定个目标,怎么定呢?郑老师给出了一个思考框架:

  • 我现在在哪?
  • 我将要到哪去?
  • 我用什么方法才能达到目的?

其实这三步分别是认识到自己的现状、确定自己的目标、确定达到目标的现状。针对我自己情况,三个问题的答案如下:

  • 我现在在哪? 不太扎实的中级程序员
  • 我将要到哪去?短期目标:Android 方面做到高级工程师;长期目标:全栈工程师
  • 用什么方法达到目标?Android 方面需要学习源码及 FrameWork 层,学习性能优化;利用空闲时间学习全栈的技能。

短期目标是与我工作相关的,是必须要实现的,而长期目标则是自己的兴趣爱好,本人比较热衷于技术所以想在技术方面深究。

上述三个问题课程中也做了解答,答案是遇到具体问题的思考方法,也是整个课程的提纲:

  • 我们现在在哪?即目前遇到的问题或者需要完成的任务
  • 我们要到哪去?以终为始
  • 我们如何到达哪里?
    • 任务分解
    • 沟通反馈
    • 自动化

我们平常工作的过程中所遇到的困难大多数都是偶然复杂度造成的,上述方法论则是通过前期工作方法很大程度上降低了偶然复杂度,提升工作效率。

以终为始

如何让自己的努力不白费 — 学会反直觉思维

很多人(包括我在学习本课程之前)在工作中接受一个需求或者功能的时候大多数情况下都是直接开始计划并着手开始写代码,大多数情况下不会思考这个需求或者任务的目的是什么?是针对什么群体?等等?忽略这些内容很可能会导致自己前期的努力都白费。

这是为什么呢?因为大多数人都欠缺一种逆向思维或者反直觉思维,也就是以终为始的思维习惯。如果我们在接受任务的时候先考虑,逆向思考,将后期遇到的坑前期考虑并计划到,则会避免很多的偶然复杂度的问题,也不会在后期加班加点的填坑。

该怎么做呢?在接受一个任务或者需求的时候先考虑这个任务的终,也就是这个任务或者需求的目的,搞明白为什么要这么做,做的价值是什么。之后需要在脑海中推演,进行一次创造,之后才付诸实践。

任何事物都要经过两次创造:一次是在头脑中的创造,也就是智力上的或者第一次创造(Mental/First Creation),然后才是付诸实践,也就是实际的构建或第二次创造(Physical/Second Creation)

上面的第一次创造也是预演,先推演过程中遇到的问题提前解决,避免后面紧紧张张。

在软件开发过程中,我们就假设软件已经就绪,看就绪之后,要做哪些事情,比如,如何上线、如何推广等等,这样的推演过程会帮我们发现前期准备的不足之处,进一步丰富我们的工作计划。为了不让我们总在“最后一公里”摔跟头,前期的推演是不可或缺的,也是想让团队进入有条不紊状态的前提。

总之一句话:遇到事情,倒着想。

明确完成的定义和标准

上面说到了,我们可以理解为完成,但是我们自己说的完成就真的是完成?例如对于一个需求任务来说,我们的定义或许是代码上传到服务器上,但是对于领导呢?领导所谓的完成或许就不是这样了,领导或许会考虑是否经过测试?是否编写测试用例?是否需求澄清?等等。这就是对完成的定义(DOD, Define Of Done)不同。

DOD 不紧可以按某个项目或者需求任务定义,也可以按时间,比如迭代等来进行定义。DOD 必须满足以下几个条件:

  • DoD是一个清单,内部是由很多可检查项组成
  • DoD内部项目是可检查的,项目只有两种状态,完成和未完成;

当我们接到一个需求时也一样,需要做的就是需求澄清,需要将需求进行分解,针对每个小的需求可以用一个用户故事进行描述,同时确定好每个小需求的验收标准。

需求分解也可以跟项目经理讨论砍需求。

尽早进行集成 — 减少集成所需要的时间

我们都工作在一个团队中,需求的开发或者项目运作都需要团队的成员来进行配合的,我们仅仅编写代码进行上传就可以了吗?答案是否定的,个人可能负责一个小需求或者小任务,这个小需求需要与团队其他成员的功能进行整合才能满足大需求的要求。

如果我们等到团队中所有人把所有的代码编写完成之后再进行联调和集成,则需要额外付出大量的时间和精力来做这个事。

有什么可以改善的地方吗?当然有,那就是每日构建,也就是没天都集成一次。再更进一步则是每次代码提交则立即触发集成,这也就是持续集成。说到持续集成那想到了持续集成服务器 Jenkins,可以将 Jenkins 服务器和 Git工具进行配合做到持续集成。

总之只有一句话:尽早的做代码集成。

默认所有需求都不做,直到弄清楚为什么要做这件事

这点其实和前面说过的完成的定义以及反直觉思维是有点像的。接收到新需求的任务时,需要搞需求时处于什么目的,达到什么状态,针对哪些客户群体,这么做的意义时什么,防止做无用功。

提升自己的上下文

提升自己的上下文也可以理解为扩大自己的上下文,再说的更直白一点就是换个角度思考问题。

遇到问题时,将自己放在第三者的位置,可以想象如果自己是领导我会怎么解决,如果无法确定,那么可以去找领导反馈问题。你可能会发现自己原来难以解决的难点换个角度则可以轻松解决或者避免。这就是换角度思考的亮点所在。

角度其实就是上下文,不同的工作角色往往差异就是上下文不一样。我们需要跳出程序员的思维,切换到不同的上下文、更大的上下文中去思考问题,去了解别人的工作逻辑

迭代0 — 开发前期的准备

迭代0 可以采用DOD清单的方式去记录一些在项目正式开发或者任务完成之前需要确认、解决的一些问题。主要包括以下几个方面:

需求方面

  • 细化需求,细化需求后需要根据优先级从需求中挑出迭代1中所需要完成的需求。优先级是根据我们要完成开发**最小可行产品(minimum viable product,MVP)**来确定的
  • 确认交互和视效

技术方面

  • 确定技术选型,架构,方案等
  • 持续集成
  • 测试用例
  • 发布准备

总结

以终为始的中心思想就是倒着想或者预演,把问题在前期暴漏出来,不要等到后期遇到的时候才去解决。对待需求也是,需要细化需求,确定需求的具体目的,搞明白需求的具体含义才去实现。