怎么提高软件开发团队的绩效?在回答这个问题之前,我们先要定义软件开发团队的效能,见:怎么定义软件开发团队的效能。
怎么去提升交付价值、响应速度、交付速率、质量和能力呢?我们需要在做事情时遵守几个原则:以终为始、持续分解、沟通反馈、自动化。
以终为始:
在工作的一开始就确定好自己的目标。我们需要看到的是真正的目标,而不是把别人交代给我们的工作当作目标。你可以看出这个原则是在帮助我们回答思考框架中,Where are we going?(我们要到哪儿去?)这个问题。
说起来很简单,但做到并不容易。因为我们习以为常的思维模式是线性而顺序的,第一步做完,做第二步;第二步做完,做第三步。
这也情有可原。我们人类都是从远古时代演化而来,在那个食不果腹的时代里,倒着思考的用途并不大,人们甚至不确定自己能否见到明天的太阳。几十万年的进化留给我们很多短视的行为和思考习惯,因为这样的做法最为节省能量,把目光放长远是需要额外消耗能量的。
“以终为始”是一种反直觉的思维方式,是大多数人不具备的。所以,日常生活中,我们看到很多有趣的现象。
比如,大学毕业时,有很多人想考研,如果你问他为什么要考研,得到的理由通常是为了找个好工作。但考研真的能帮他找个好工作吗?不一定,因为找工作和考研根本就不是同一棵技能树。
如果真的是想找个好工作,那你就应该了解工作的要求是什么,怎样才能掌握工作要求的技能。
从后面这个角度出发,你会发现考研只是通往工作诸多道路中的一条,其他的路径也是可以到达的。比如,你应该找个实习的地方锻炼一下职业技能。这就是“以终为始”思考问题的方式。
践行“以终为始”就是在做事之前,先考虑结果,根据结果来确定要做的事情。
持续分解:
将大目标拆分成一个一个可行的执行任务,工作分解得越细致,我们便越能更好地掌控工作,它是帮助我们回答思维框架中,How can we get there?(我们如何到达那里?)的问题。
一个大问题,我们都很难给出答案,但回答小问题却是我们擅长的。所以,当我们学会将问题分解,就相当于朝着问题的解决迈进了一大步。我们最熟悉的分而治之的例子,应该是将这个理念用在算法上,比如归并排序。将待排序的元素分成大小基本相同的两个子集,然后,分别将两个子集排序,最后将两个排好序的子集合并到一起。
那么,用这种思路解决问题的难点是什么呢?给出一个可执行的分解,一旦分解的结果出来,到了可执行的步骤,接下来的工作,即便不是一马平川,也是比原来顺畅很多,因为问题的规模小了。与很多实践相反,任务分解是一个知难行易的过程。知道怎么分解是困难的,一旦知道了,行动反而要相对来说容易一些。分解的重点在于可执行。不同的可执行定义差别在于,我们是否能清楚地知道这个问题该如何解决。
只有能把任务拆分得非常小,才能对自己的执行能力有一个更清楚地认识,一旦任务分解得很小,调整也会变得很容易。很多人都在说计划赶不上变化,而真正的原因就是计划的粒度太大,没法调整。
从当年的瀑布模型到今天的迭代模型,实际上,就是缩减一次交付的粒度。几周调整一次计划,也就不存在“计划赶不上变化”的情况了,因为我的计划也一直在变。
如今软件行业都在提倡拥抱变化,而任务分解是我们拥抱变化的前提。怎么缩短交付周期,任务粒度拆小是一个有效的方法。
沟通反馈:
是为了疏通与其他人交互的渠道。一方面,我们保证信息能够传达出去,减少因为理解偏差造成的工作疏漏;另一方面,也要保证我们能够准确接收外部信息,以免因为自我感觉良好,阻碍了进步。
来看一下香农信息论里的通信模型:
信息的传达要经过编码和解码两个过程,无论是编码出现问题,还是解码出现问题,都会造成信息的不准确。一方面,有些人表达不清楚,一件简单的事,他说了半天,你依然是云里雾里。这就相当于,信源发出的信息经过编码得到的信号已经不准确了。另一方面,就像听一些技术演讲,人家说得很清楚,但因为自己没有相关背景,依然无法得知人家表达的信息。这就相当于信号虽然准确,但我们没有对应的解码装置,信号无法转成有效信息。
有了理论做基础,我们就容易理解世界为什么总和我的理解不一样,这就是编解码的过程出了问题。因为每个人经历见识的差异,造成了各自编解码器的差异。
怎么消除沟通的差异呢?首先要改善编码,当我们想把信息传达给别人的时候,我们得把信息编码成一个有效的信号,至少要保证在我们这里信息不丢失。很多人抱怨别人不能理解自己,其实,首先应该想的问题是,自己到底有没有把话说清楚。其次要改善解码,当一个信号呈现在我们面前时,作为接收者,我们是否能够有效地解码信息。我们要想让自己更好地工作生活,就必须接纳真实世界的反馈,而接纳真实世界的反馈,一是需要我们打开自己的接收器,把信号接纳进来,让反馈进来,这是解码的前提;二是扩展见识,提升自己解码器的效果,更好地理解别人要表达的内容到底是什么。
沟通反馈就是改善编码、解码以及算法的方式。无论是“发送”得更清楚,还是“接收”得更明白,抑或是通过各种协调算法,都是为了让通信的双方做好准备。
自动化:
将繁琐的工作通过自动化的方式交给机器执行,这是我们程序员本职工作的一部分,我们擅长的是为其他人打造自动化的服务,但自己的工作却应用得不够,这也是我们工作中最值得优化的部分。
Perl 语言的发明人 Larry Wall 曾经说过,优秀程序员应该有三大美德:懒惰、急躁和傲慢(Laziness, Impatience and hubris)。想要成为一个优秀的程序员,就要让机器为自己很好地工作,而这需要对自动化有着很好地理解。
我们学习自动化,先要知道哪些东西不要自动化,尽最大的努力不做浪费时间的事。一方面,我们要从需求上规避那些没必要做的事;另一方面,我们也从自身防止NIH 综合症(Not Invented Here Syndrome),争取做一个懒惰的程序员。
对于要自动化的事,我们需要反思一下,在为别人打造自动化工具的同时,我们自己的工作过程有没有很好地自动化。而如果我们想拥有打造良好的自动化工具,我们需要对软件设计有着充分地理解。
参考郑晔的《10X程序员工作法》