定义和衡量程序员的生产力是工程经理和 CTO 工作中最困难的部分之一。当一项工作的大部分成果都是无形的我们究竟该如何衡量它开发者生产力真的可以被量化吗在软件行业如何定义和衡量程序员生产力一直是一个棘手问题。它既关系到巨额投资也构成了许多初创公司的核心价值主张同时它也是工程经理和 CTO 最难处理的职责之一。对不同经验水平的开发者来说这同样是焦虑的来源如何判断自己是否已经尽职尽责无论是在工作时间内还是在工作时间之外。当所有工作成果看起来都如此抽象、难以触摸时我们究竟该如何衡量它真的可以被衡量吗本文将讨论衡量开发者生产力时最常见的几个陷阱并介绍一些更有效的思路包括为什么不能只看工作时长、代码行数、提交次数以及如何从团队交付、开发速度和工程文化等角度理解真正的程序员效率。在软件开发领域和许多其他领域一样人们常常从“投入”和“产出”的角度理解生产力。以美国为例一名全职开发者每周工作 40 小时平均年薪约为 107,510 美元。工作时长和薪水都是显而易见且容易量化的投入。相应地开发者会定期交付软件功能、编写文档、完成部署或修复缺陷。这些看起来就是产出。如果开发者像我们想象中他们编写的软件一样简单那么提升生产力似乎也应该很简单让他们工作更久或者给他们更高的薪水就可以了。当然这只是一个美好的想象。开发者不是这样运转的软件开发也不是这样运转的。衡量开发者生产力时只看投入有什么问题“工作时长”是众多错误绩效指标之一。我先提到它是因为它常常被忽视却又很容易成为默认选项成为一种最省力的管理方式。如果一家公司不刻意避免这种倾向迟早会形成一种只看工作时长的环境。在远程办公成为常态之前这类环境的迹象非常容易辨认工作时长被视为不可商量出现在办公室就被视为“正在工作”的证据任何想提前几个小时离开办公室的人都会遭到敌意对待有时只是别人微微挑眉有时则更加直接。相反那些加班到深夜、周末也来办公室的人往往会被视为高绩效员工。这种“最后一个离开健身房”的文化会制造出非常危险的激励机制开发者被迫投入越来越多时间却没有其他方式证明自己的价值最终反而开始对真正的工作产出失去关注。久而久之工作场所就会变成这样一种地方每个人看起来都在工作但真正完成的事情却越来越少。问题还不止于此。如果我们假设所有工作都是“正向工作”——也就是说所有工作都代表着目标正在推进——那就大错特错了。那些在疲惫、分心或生病状态下工作的开发者往往并不陌生于“负向工作”的概念有些工作完成得非常糟糕以至于之后必须返工或补救结果反而增加了剩余工作量。软件开发是一项复杂、抽象且高度依赖专注力的工作因此对开发者的精神状态极为敏感。换句话说许多隐藏因素都会影响开发者的实际效率焦虑、抑郁、职业倦怠、糟糕的工作氛围、悲伤、微歧视以及其他许多可能降低甚至反转个人效率的因素。如果公司文化要求员工每周长时间工作或者要求每天固定工作八小时、没有弹性和假期那么开发者不可避免地会花大量时间从事负向工作。他们加班加点完成的工作量可能还不如早点回家休息后完成得多。更糟的是由于疲劳他们第二天的效率也会继续下降。不过单纯以工作时长衡量绩效还不是最糟糕的情况。它似乎至少带有一点公平感如果两位开发者工作时长相同那么在这一点上他们是平等的。看起来没人偷懒也没人承担了超过自己份额的工作。即使他们的产出低于预期至少他们也投入了时间。而且“工作时长”不像某些指标那样会直接鼓励开发者写出低质量代码。因此尽管工作时长是一个糟糕指标甚至在很多情况下会降低生产力但还有更糟糕的指标值得讨论。再来看软件开发中另一个显而易见的投入金钱。我曾经半开玩笑地对经理说应该用薪水来衡量生产力如果我的薪水翻倍我就能写出世界级软件架构师水平的代码。当然直觉告诉我们这很荒唐。给某人涨工资并不会立刻提升他的生产力尽管它可能通过间接方式、在一定程度上产生积极影响。在我看来金钱和工作时长属于同一类指标它们不仅是投入更是辅助性投入对生产力的直接影响非常有限。金钱由雇主提供时间由员工提供但这种交换只是创造有用软件的外围条件而不是软件价值本身。简而言之衡量投入是一种并不可靠的方法因为软件开发不是一道线性方程代码也不是流水线产品。所以接下来我们谈谈产出。用代码行数和提交次数衡量程序员效率的陷阱或许有些出人意料软件开发领域中许多最糟糕的衡量指标恰恰出现在“产出”这一侧。有些人误以为软件开发的产出就是代码行数或者版本控制系统中的提交次数。确实这些都是开发过程的一部分但它们更像是副产品而不是最终结果。严格来说一行不能解决问题的代码比没有代码更糟。因此用代码贡献量来衡量开发者生产力就好比用发电厂的排放量衡量发电效率或者用议会通过的法案数量衡量政绩一样它与实际价值没有直接关系。更糟糕的是这类指标极其容易被操纵。按代码行计费的开发者一天就能轻松“赚到”一年的薪水而不必创造任何商业价值。大多数开发者会采取更隐蔽的方式但无论如何你都应该谨慎选择自己想要的东西。当一项指标本身成为目标时它就不再是一个好的指标。——古德哈特定律大多数开发者其实都明白这一点。尴尬的是我们仍然常常倾向于把提交次数和代码行数当作炫耀资本。当我们看到某大型科技公司的产品代码量超过 20 亿行或者某操作系统团队每天提交超过 8,400 次代码时仍然会感到惊讶尽管我们知道这些并不是这些产品真正有价值的地方。有时技术社区甚至会制造出更加荒谬的说法把某些连续提交图、贡献热力图或提交次数当作开发者生产力的直接证明。顺便说一句如果一位开发者养成了每日编程的习惯并且偶尔也会休息一天我会为他感到高兴。在我看来这两点都是积极信号。但如果没有更深入了解他的贡献历史我不会仅凭一张提交图就断言此人非常高效。总之我们可以把这些指标加入“无效替代指标”的名单中。用修复的 bug 数量、完成的任务数量或发布的功能数量来衡量生产力同样问题重重尽管它们可能稍微不那么容易被操纵。如果目标是修复更多 bug开发者可以有意无意地编写更多缺陷然后再提交大量修复或者为了减少 bug 数量他们也可以尽可能缓慢地编写功能。如果目标是发布更多功能开发者可能会快速而草率地开发最终导致软件运行缓慢、体验糟糕、功能不完善。如果目标是完成更多任务团队可能会陷入内部博弈每个开发者都争相选择最简单或被高估的任务。一个优秀团队或许能够主动忽略这些指标继续专注于真正重要的工作。但即使在最好的情况下糟糕指标依然会成为一个难以忽视的障碍。还有一些组织出于极度不信任会在员工电脑上安装监控软件追踪工作中的每一个细微动作例如鼠标移动、按键操作和屏幕截图。我很难想象在这种严密监视下员工还能如何进行创造性工作。大多数开发者很可能会立刻选择离开。和前面讨论过的指标一样这种做法最明显的缺陷在于它无法捕捉任何对企业或客户真正有意义的信息。你会因为一位高效开发者花太多时间浏览某个海外社交论坛或者鼠标移动不够频繁而惩罚他吗你会因为另一位开发者在某集成开发环境里敲了很久键盘即使他难以合作也提拔他吗有些管理者显然会这么做。但我们最好比这更明智。如何正确衡量开发者生产力既然已经讨论了最糟糕的衡量方法接下来我们来谈谈一些更合理的思路。遗憾的是个人绩效的衡量往往只能粗略落在两种状态之间这个团队成员确实在做出贡献或者这个团队成员没有做出贡献。而且这种判断通常无法完全远程、完全依赖数据完成。软件开发团队并不是一群孤立工作的个体。每个团队成员的工作产出都依赖其他队友的工作产出更不用说一天之中那些无数重要却难以量化的互动。个人工作之间的相互依赖和细微差别过于复杂外部观察者很难准确衡量。例如有些团队成员是其他人的“倍增器”他们个人或许没有交付最多功能但如果没有他们的帮助、建议和影响其他队友的效率会大幅下降。这类成员是高效工程组织的秘密武器但他们的生产力无法用传统个人指标衡量。还有一些团队成员交付的新功能并不多但他们扮演着“代码清理者”的角色。无论走到哪里他们都会认真测试、清理和重构代码从而让其他人更快、更轻松地开发功能。他们的个人生产力同样很难衡量但他们对团队生产力的影响可能是指数级的。即使对于那些经常发布新功能的程序员来说短期生产力也常常波动很大这使得追踪个人生产力变得非常困难。因此个人绩效最好由贡献者自己衡量也由他们的同伴在真实协作中彼此感知。相比之下团队绩效要更直观一些。也许追踪团队绩效的最佳问题是这个团队能否在几周到几个月的周期内持续交付可用的软件这与敏捷开发第三条原则相呼应频繁交付可工作的软件周期可以从几周到几个月不等但越短越好。一个能够定期交付可用软件的团队就是高效团队。一个无法做到这一点的团队则应该认真探究原因。在实践中团队如果希望避免陷入代码行数、工时等错误指标就需要把目标、需求、开发、测试、发布和知识沉淀等过程串联起来结合真实交付质量来观察研发效能。智能化研发管理工具可以帮助团队覆盖研发全生命周期管理并打通研发工具链让过程数据、质量数据和知识经验更顺畅地流转。通常来说团队效率低下往往有其合理原因。大多数低效团队都渴望提高效率而大多数高效团队也希望继续提升。团队生产力可以通过简单而全面的组织观察来衡量。由于团队成员通常都了解彼此的贡献无论这些贡献能否量化因此严重的个人生产力问题通常可以通过良好的组织习惯被发现。例如管理者与直接下属之间保持高质量的一对一沟通定期收集诚实、匿名的反馈鼓励每位团队成员通过展示工作成果和承担责任来履行个人职责。这里的关键更多在于人而不是趋势图和原始数据。这是软件开发中无法回避的事实它远不只是 0 和 1 的组合而且一直如此。生产力追踪工具和激励计划永远无法替代积极健康的职场文化。当责任感和健康沟通融入文化之中那些最有能力解决生产力问题的人就能迅速发现并处理这些问题。用开发速度理解团队生产力许多组织会将开发速度作为衡量团队生产力的首选指标。如果使用得当它确实可以成为理解软件开发流程的有效工具。开发速度是对团队在一段时间内完成工作量的综合衡量通常会纳入开发者对每项任务相对复杂度的估算。它可以回答类似这样的问题这个团队在未来两周内大概能完成多少工作基准答案通常是大约和他们过去两周完成的工作量差不多。开发速度就是为这个判断提供上下文。它是一种计划指标而不是复盘指标。任何试图把开发速度与激励机制绑定的人最终都会发现在压力之下这个指标的准确性会迅速下降。理解团队、部门或公司的开发速度对于确定功能优先级、与客户沟通预期以及规划产品未来方向都很重要。但它并不是越精细越好。没有必要寻找比“任务数量乘以复杂度”更细的衡量标准。像某些工具那样衡量提交次数、代码行数或编码时长无论在团队层面还是个人层面都没有太大意义。团队生成的代码数量、提交次数或花费时间与他们创造的真实价值之间并不存在稳定关联。事实上许多组织即使没有任何硬性生产力指标也能蓬勃发展。那些把“可用的软件”视为目标和主要开发成果的组织往往会相应降低对投入指标的优先级。虽然可用软件本身很难精确量化但这种取向会产生深远影响。在这样的组织中开发者可以自由选择最适合自己的时间和地点发挥最佳水平。这未必符合朝九晚五的传统模式。有些人因为个人偏好或工作需要会在清晨或深夜完成大部分工作有些人则会把工作拆成零散时间一会儿工作一小时一会儿又连续工作几个小时。有些人在家工作有些人在办公室工作还有些人在旅途中工作。这是一种优势而不是缺陷。它强调的是真正的生产力而不是试图把生产力生硬塞进容易观察的启发式指标里。它也让工作场所能够容纳更广泛的人才例如在职父母、残障人士以及其他需要灵活工作方式的人。关于结果导向型工作环境、远程办公、减少会议时间和弹性工作制的好处人们已经写了很多也讨论了很多。归根结底这些都是更聪明的生产力管理方式的体现。对于跨职能团队来说弹性协作也需要清晰的任务、文档、日历和审批机制支撑 通用项目协作系统就可以帮助不同角色在更灵活的工作方式下保持协同。结语真正值得衡量的是有用的软件人们常说你衡量什么就会得到什么。因此你应该只衡量你真正想要的东西不管它是否能被画成折线图。对某些人来说从事或管理一项无法用数字精确量化的工作可能会令人沮丧。但对于软件开发这样细致、抽象且高度依赖判断力的工作而言我们越是沉迷于细枝末节就越容易偏离真正的目标。我们的目标是开发出有用的软件。除此之外我们不应该满足于任何低于这一标准的替代物也不应该把那些替代物误当成真正值得衡量的东西。因此衡量开发者生产力的关键不是找到一个看似精确的数字而是判断团队是否能够持续交付有价值、可工作的软件并在健康的工程文化中不断提升协作效率和交付质量。