如何成为更好的程序员(之一)

我在极客时间上学的课程《10x程序员工作法》最近完结了,我很有收获。我来总结一下我从这门课程中都学到了些什么。预计连载若干篇。

1. 10x

标题中10x的意思是十倍,意思是说程序员和程序员之间效率的差距是有数量级差距的。我很认同这一点,我对我职业发展的期待,基本就是参照吴军老师的”五级工程师”理论。五级工程师理论,把软件工程师的能力分为5级,每个等级之间是有数量级的差距的,不论是他们的能力,还是影响力。

课程的脉络很明确,一上来就说会讲四个原则,分别是:

  • 以终为始:确定好真实目标
  • 任务分解:找到实施路径
  • 沟通反馈:解决与人打交道时出现的问题
  • 自动化:解决与机器打交道时出现的问题

我认为,这门课给我最大的收获(包括极客时间上其他的一些卖给程序员的软技能课),就是让我减少了一些”不知道自己不知道”,多了一些”知道自己不知道”。代码习惯不好可以改,沟通能力不好可以练习,需求整不明白可以多想,但无知的话就不会有任何可能性。

2. 以终为始

以终为始的意思很简单,就是多看看结果,多想想结果。

产品经理交给我一个需求,我应当关心:为什么要做这个特性?它能给用户带来什么价值?

我认为,任何提出需求的人,不论是产品经理,或是程序员自己,都应当能回答这两个问题。尤其是那些并不是由客户直接提出的需求。在实际的开发过程中,太容易出现没有意义的需求了,比如:

  • PM认为这个需求需要做,因为我们以前的老产品上也有。(实际上,老产品上的这个功能可能就是鸡肋)
  • 程序员觉得这个重构应该进行,因为重构后的性能会”快100%”(实际上,就算这个模块的性能再慢上300%,客户也不会在意)

没想明白这两个问题的需求,基本都是自嗨。

我犯过这样的一个错误。我给我们的产品写过一个系统状态检测的模块,说实话当初为什么要做这个功能,我已经想不起来了,推测的话,很可能是因为上一代产品中也有同样的功能,所以这一代产品也应该有这个功能。但是,对于我们当前的系统来说,状态检测模块的实现难度要大上不少,但是,我想都没想过这个需求是否是合理的,我认为这是一件很显然的事,就是这个模块能实现的功能很牛逼,很优雅,我们的产品当然需要这个模块(但我从来没想过的事,客户在他们的业务场景下,是否真正需要这个模块)。

从后来的交付来看,这个状态检测模块因为复杂度比较高,容易出现bug,产生了额外的时间成本,而且客户似乎也不是很在意这个模块的好坏。一次典型的得不偿失。

默认所有的需求都不做,直到弄清楚为什么要做这件事。我觉得这在这方面做得还不错。

3. 对完成的定义

产品经理和程序员产生了争执,PM认为这个需求完全没完成,程序员认为他已经做完了所有该干的事。似乎谁也没错,对吧?从我的经验来看,软件开发过程中太容易出现这种”谁也没有过错”的事,但是,事情本身却没做成。如果一个团队乃至一个公司都充斥着”谁也没有过错”但”什么事都没做成”的氛围,这个集体必然走不长远。

对完成的定义也很简单,比如我是程序员的话,让我接收到一个PM发起的需求,我应当和PM对称清楚,哪些是你想要交付的东西,交付的标准是什么。当有了这种验收清单后,做事就只会有两种状态,”做完了”和”没做完”。问题就在于,软件开发的过程中总是有一些”差不多做完了”或是”我负责的这部分做完了”的说辞,这种中间状态应当尽可能减少。

其实我认为,严格来说,从大局的角度来看,比如我是leader,首先我自己就有过错,其次是负责验收任务的人有过错。比如,程序员提交了Python代码的MR,但是没做auto pep8,但是研发组长认为提交代码怎么可能不做代码格式自动化整理呢?于是研发组长认为这个事情完成。程序员也委屈,你也没让我做auto pep8啊?

问题出在哪?问题在于auto pep8没有制度化。不论是明确口头的制度,还是在CI里把pep8做成机器负责验收的制度,都比没有制度的约束好。

做任何需求和任务之前,先定好验收标准。

但是,这里可能存在一个问题,那就是对于一些比较大的任务,或是一些预研性质的任务,如果一上来就定了太细太具体的验收标准,可能是没有意义的。我认为这个问题的解决之道是,要么在生命周期的维度上拆分任务,比如把一个新模块的需求拆分为预研阶段和实现阶段,我们首先确定预研阶段的交付物(比如,评估该模块是否具有技术可行性),如果预研阶段通过了,咱们再定实现阶段的交付物。

要么就是把一个需求拆成很多平行的子需求,这样的话确定交付物应该也会容易些,不过这样往往也就太麻烦了。还是应当尽可能地把通常的交付物制度化,以及上CI以实现自动化。交付标准的详细程度,应当是由大家的默契和需求的交付效率共同平衡,最终达到一个比较恰当的详细程度。

4. 程序员的视野

作者说程序员不应当只关注自己的技术实现,应当关注软件开发的全生命周期。也就是”在更大的上下文中工作”。

关于这点我也算是一直在践行,反倒是我常常过多关注技术实现之外的东西,有时候会分散自己的注意力。其实也很简单,我应当关注什么东西?我把我设想成我当前做的这款产品的创业者,这个团队就是我所在的创业公司,我们公司安身立命的产品就是我手里正在做的产品,那我会关注产品的哪些东西?市场部门对产品的了解,产品部门的计划,研发部门的todo-list,这都会是我关注的东西。

其实也是因为我们团队小,我相信在大厂的话也没什么这种机会,每个人工作都会很饱和,搞自己那摊子事都搞不过来呢(猜测)。

当我作为一个程序员时,我看到的是需求,还是一个要解决的技术问题呢?我希望看到的是需求。当然不是所有的程序员都喜欢关注技术之外的东西,其实那也很好。但从我的经验来看,有时候程序员关注具体技术之外的东西,不仅仅是对团队好,还能防止自己走进坑里。

#