大多数自诩为开发者生产力专家的人似乎对销售产品更感兴趣,而不是为开发者提供真正有效的指导。这种现象可能会导致我们沉浸在各种缩略术语、神奇的指标和方法论当中,却没能获得严谨的系统性思考。
开发者是系统性思考者。我们的工作是建模和构建系统,我们经常绘制图表和原理图来说明这些系统是如何工作的。但我们自己的工作蓝图却要让别人来画——然而他们画得真的很差。我怀疑自己是唯一一个谨慎对待“开发者生产力专家”所说的话的开发者。
难道我们不应该从自己的经验和思维模式开始吗?难道我们不应该画一些画来描述我们所生活的世界吗?下面是我的一些尝试。
我是 SDLC。你可能在一些开发者营销活动上见过我,比如 Shift Left、DORA the DevOps Explorer 和 Agile Waterfalls。
SDLC 是软件开发过程的共同特征,是 DevOps 营销活动的支柱,它包含了将代码交付到生产环境所涉及的几个阶段。然而,SDLC 并没有定义软件开发最关键的一步:如何理解和编写代码本身。
作为一名开发者,我发现 SDLC 中不只有一个大循环,实际上是两个嵌套循环:
外部循环大致与 SDLC 各个阶段形成映射,并发生在 Sprint、项目或发布级别。
内部循环是“读——写——运行”循环,在这个循环中,你阅读代码、编写代码、运行测试,并不断重复,直到对代码感到满意,这个过程每天都会发生很多次。
在开发过程中,只要“接近源代码”,你就进入了内部循环。这种情况会在外部循环的多个阶段发生,例如:
熟悉你将要做出修改的代码。
开发新特性或修复 Bug。
修复 CI 中出现的测试错误。
评审补丁或对一个评论做出回应。
对失败的部署中出现的错误进行调试。
处理生产事故。
针对内部循环的讨论很重要,因为它是软件开发的核心。如果你不讨论它,你的组织就会把它当作无关紧要的事情来对待。
心流是内部循环的黄金状态。心流状态是指当你受到鼓舞和激励时能够达到的专注和生产力状态。当你“连续读取”了所有必要的内容后,你就可以享受乐趣了。此时,你可以按照你思维的速度编写代码。到达心流状态的理想路径如下图所示:
达到心流状态可以加速内部循环,但进入心流状态需要一段不被打断的时间。心理情境转换会导致你跳出来,我从开发者那里听到的最常见的抱怨是有太多外部干扰。许多开发者的日常生活就如下图所示:
破坏心流状态的中断事件可以是内部的,也可以是外部的。
外部上下文切换是由外部因素触发的,如预定的会议或来自团队成员的即兴提问。
内部上下文切换是由支线任务触发的,比如需要了解如何使用开发库、配置工具或解决阻塞问题。
我觉得每个程序员在他们生命中的某个时刻都经历过第一张图所示的状态,可能这种状态在早期让他们进入了编程领域——这种感觉就像是一种诱导性药品。但是,当他们开始专业编写代码时,许多人会陷入第二张图所示的状态,这是令开发者感到痛苦和失去生产力的一个重要问题来源。
前面的几张图揭示了一个问题:图中 Y 轴的“生产力”到底是什么?许多开发者都能描述这种感觉,但我们能给出更精确的定义吗?代码行数?提交代码的次数?从版本控制系统中获得的一些合成指标?所有这些似乎都不是衡量开发者生产力的好方法。
软件开发的核心是创新。与生产实物不同,软件开发的目标不是生产以前生产过的东西,而是产生有用的新知识。创新的原子单位是迭代——一个内部循环周期。
开发者生产力的原子单位应该是内部循环的一次迭代。合适的单位不是代码的数量,而是迭代的频率,我们可以把这个量的单位叫做赫兹。
在物理世界里,速度有两个分量:方向和速度。类似地,开发者的速度也可以分解为方向和大小。
速度表示你有多快可以执行完一个循环内部周期。越接近心流状态,迭代速度就越快,就能越早发布新的功能或补丁。
方向表示你所采用的技术方向——例如,是使用库 X 还是 Y。好的方向可能会成为关键的捷径。不好的方向可能意味着你以后不得不重新再走一遍。
良好的方向设定就是要做出能够尽可能快启动和运行端到端系统的选择。建立一个端到端系统可以快速降低整个项目的风险。在截止日期之前达到可交付状态意味着你可以在剩余的时间里进行进一步的改进。不要把目的地看作一个单一的点,而是一个结果区域。先进入结果区域,然后提升你的位置。
前面的图片都把软件开发看作是个体的努力,但大多数软件其实是团队合作开发的。团队合作会带来更强劲和持续的进步。正如古老的谚语所说:“如果你想走得快,就独自前行。如果你想走得远,就一起走。”
个体的速度往往是起伏不定的,所以不可避免地会花一些时间在不熟悉的代码上,或者一些外部因素中断了日常的编程进度。但是,当你把它们加在一起时,个体的凸起就变得平滑了。
如果一个团队经历了一段持续的低生产力时期,那么有必要问一问是什么因素导致了所有团队成员的生产力下降。也许是因为一个新的季度计划过程占用了过多时间,也许是因为其他更严重的因素——士气问题、技术债务或缺乏明确的目标和优先级。
人们普遍认为,软件团队的生产力会随着团队的规模呈次线性增长,并最终会下降。这里有一个并行计算和安达尔定律的例子:如果你将一台机器上的 CPU 数量增加一倍,程序可能会更快,但几乎永远不可能增加一倍那么多。
导致计算机并行化降低的因素是 CPU 上下文切换,以及如何将工作分解成可独立处理的块。在软件团队里,导致团队生产力降低的主要因素是沟通成本、工作依赖、领域专业知识和熟悉环境的速度。
如果你把一个项目分解成不同的可交付块,并在纸上画出来,你会看到最终的成品是一个金字塔,底部的积木必须比上面的先就位:
不同领域的专业知识用不同的颜色表示。如果你是一个具备多个领域经验的开发人员,可以自己构建整个项目。或者,你可以把任务委派给另外两个各自在一个领域有专长的开发人员:
这两个开发人员的优势是他们可以并行地构建单独的块,但他们的并行性受到串行依赖关系 (一些块必须先于其他块放置)、理解不熟悉的代码和沟通成本的限制。
两个开发人员完成项目的速度一定是一个开发人员的两倍,这只是一厢情愿的想法。事实上,即使是净加速度都无法保证。但如果有良好的分工和团队关系,一定程度的净加速度是可以实现的。
然而,每增加一个人,也增加了协调任务的复杂性。在大多数团队中,每增加一个人的回报率都在大大减少。这就是为什么许多组织优先招聘和留住最好的开发人员,而不只是扩大团队的规模。他们还在工具方面投入,进一步提高个人生产力,协调大规模的软件开发。
我之前说过,如果开发者不谈论生产力的这些元素,我们的组织就不会意识到它们的重要性。
然而,更糟糕的是,总会有人试图说服我们的组织:其他事情更重要。很多时候,我们发现自己被塞进了一个框架中,这个框架将软件开发看成是一个没有想象力的小部件工厂,而不是一个探索之旅。他们不重视内部循环 (充分理解并创建所有的代码),而且要求我们只是机械式地考虑外部循环。如果你甚至都无法在代码中自由地跳转,所谓的“变革失败率”又有什么用?作为工程师,我们没有在可以用提高我们生活质量的工具上投入,而是被迫陷入“人月神话”的谬误,结局就是更多的人、更多的代码和更多的问题。
这对我们、整个行业和社会都有好处,有助于提升可以反映我们工作现实并尊重其基本创造力的思维模式。
在这篇文章中,我画了一些能够引起开发者共鸣的图片。你呢?当你在思考你自己和团队的开发过程时,你看到了什么样的画面?
作者简介:
Beyang Liu 是 Sourcegraph 的首席技术官和联合创始人。Sourcegraph 是一个代码智能平台,帮助更多的人更容易地访问代码。在加入 Sourcegraph 之前,Beyang 是 Palantir Technologies 的软件工程师,为财富 500 强公司开发数据分析软件。Beyang 在斯坦福大学学习计算机科学,并发表了关于概率图形模型和计算机视觉的研究论文。
原文链接:
https://about.sourcegraph.com/blog/developer-productivity-thoughts
你也「在看」吗?👇