神译局是36氪旗下编译团队,关注科技、商业、职场、生活等领域,重点介绍国外的新技术、新观点、新风向。
编者按:定义和衡量程序员的生产效率是工程经理或CTO的职位描述里面最困难的部分之一了。当你所做的一切都是看不见的时候,应该怎么去衡量呢?或者说究竟能不能衡量呢?Isaac Lyman对业界用来衡量开发人员工作绩效的若干指标进行了分析,认为目前大部分用来衡量程序员表现的指标其实都是非常糟糕的,并给出了他的建议方案。原文发表在StackOverFlow官方博客上,标题是:Can developer productivity be measured?
划重点:
定义和衡量开发人员的效率是个难题
用输入来衡量效率,职场会变成大家在“摸鱼”的地方
软件开发很抽象很复杂,需要专注,所以对开发人员的心理状态非常敏感
金钱和工时都属于同一类:这两个不仅属于输入,而且属于辅助性的输入,只能稍微提高一点生产率
代码行数或提交次数几乎是最糟糕的衡量指标
写出来的东西没有解决问题永远都要比不写还要糟
当措施本身成为目标时,就不再是好措施
软件是团队努力的结果,个体工作之间的相关性是外部观察者无法衡量的
衡量团队绩效的关键是看速度,看他们有没有在数周乃至数月的时间范围内持续开发出有用的软件
在软件行业里面,定义和衡量程序员的生产效率是类似大白鲸一样的东西。这是巨额投资的基础,是众多初创企业的价值主张,也是工程经理或CTO的职位描述里面最困难的部分之一。这还是各种不同经验水平的开发者的焦虑之源:怎么才能知道自己已经做够了(不管是工作时间还是非工作时间)?当你所做的一切都是看不见的时候,你应该怎么去衡量呢?或者说究竟能不能衡量呢?在本文中,我会讨论衡量生产效率的最大陷阱是什么,以及若干好的衡量手段。
跟其他领域一样,很多人也是从投入和产出的角度来考虑软件开发的生产力。在美国,全职开发人员每周要工作40个小时,平均年薪为107510美元。工时和工资都是可见的,且易于量化的输入。然后,开发人员会定期开发软件功能,编写文档,进行部署及/或错误修复。这些则是输出。如果开发人员写软件像我们想象的那么样简单的话,那么提高他们的生产力应该就跟要求他们延长工作时间或者支付更高薪水一样简单。当然,这种想象只是童话。开发人员和软件的工作方式都不是那样的。
用来衡量工作绩效有好些指标都是错误的,“工作时间”就是其中之一。我之所以要先提这个,是因为这个经常不做审查就被当作默认,是阻力最小的做法。如果公司不可以避免这种做法的话,迟早会恶化成为只论工作时长的环境。在远程办公成为常态的疫情之外,这种只看时间的环境是很容易看出来的。上班时间被认为是没有商量余地的,而在办公室出现被看成是正在工作的证据。谁要是想提前几个小时离开办公室都会遇到敌意(有时候可能就是侧目一下,有时候可能会更加无礼)。任何开夜车或者周末来加班的行为都会被看成是高效的表现。不幸的是,这种“最后一个离开健身房”文化的激励措施很不幸:除了把生活的更多时间花在工作上以外,开发者人员没有任何其他方式来证明自己的价值,还会造成工作成功反而变成了次要的关注对象。慢慢地,工作场所逐渐变成人人都在工作但无所事事的地方(摸鱼)。
问题还不止这些。如果我们假设所有的工作都属于“正功”,也就是说,所有的工作都代表朝着目标逼近的话,那你就大错特错了。开发者如果是在精疲力竭,分心或生病的时候工作的话,那种工作往往属于“负功”:工作做得很差,以至于必须撤消或者事后补窟窿,导致剩余工作量不是减少而是增加。软件开发很抽象很复杂,需要专注,所以对开发人员的心理状态非常敏感。也就是说,有一些隐藏的输入会影响工作表现:如焦虑,沮丧,倦怠,恶劣的工作氛围,悲伤,微攻击等一百多种可以在任何一天降低或逆转个人工作效率的东西。如果公司文化要求连续长时间的工作,或者甚至只是朝九晚五而没有灵活性或休假时间的话,那开发人员把时间用来做“负功”将不可避免:熬夜做出来的成果甚至还不如早点回家做出来的好。由于疲劳,他们第二天的工作量也会减少。
另一方面,只看时间的环境还不是最坏的情况。这里面还有一个公平的幽灵:如果两个开发者工作的时长都是一样的话,则两人有一个明确的维度说明大家是相同的。两人似乎都没有懈怠,似乎也没有多做。如果他们的产出不达预期,至少人家投入了时间。而且,“工作时间”这个指标不会像某些指标那么明显地鼓励写出不好的代码。所以,虽然这是一个很糟糕的指标,甚至在很多情况下还会影响到生产效率,但还有更糟糕的指标值得我们讨论。
不妨考虑软件开发另一个显然的输入:钱。我曾经跟我的经理开过一两次玩笑,说生产效率应该用薪水来衡量,如果给我的薪水加倍的话,我就会用世界级软件架构师的水平来写代码。当然,你凭直觉就知道这很荒谬。多给钱并不能马上提高开发者的生产力(尽管间接可能会,但规模有限)。不过,在我看来,金钱和工时都属于同一类:这两个不仅属于输入,而且属于辅助性的输入,只能稍微提高一点生产率。只不过一种是由雇主提供的输入,而另一种是由雇员提供的,但是这种交换只是开发有用软件的陪衬。
长话短说,通过输入来衡量效率是不充分的,因为软件开发不是方程式,代码没法靠组装线开发出来。所以,我们就来谈谈输出吧。
在输出这里你会发现很多软件世界里面最糟糕的衡量指标,这一点也许会有违直觉。有些人会掉进这样的陷阱里面,他们以为软件开发的工作输出就是代码行数或者提交到版本控制的次数。当然,这些是流程的一部分,但那更像是副产品,而不是最终结果。严格来说,写出来的东西没有解决问题永远都要比不写还要糟。也就是说,靠看开发者贡献了多少代码来衡量生产效率,就好像靠产生的废物量来衡量发电厂的绩效,或者靠通过多少法案来衡量国会的绩效一样;这跟实际价值毫无关系。
更糟糕的是,这些指标作弊非常容易。如果薪水是按代码行数计费的话,开发人员在一天之内就能轻轻松松赚走一年的薪水,但却不能产生任何的商业价值。大多数的开发人员做法会更加微妙一些,但基本都是换汤不换药,你最好管理好自己的预期。
当措施本身成为目标时,就不再是好措施。
——古德哈特定律
开发人员基本上都了解这一点,但是令人尴尬的是,我们往往还是把提交和代码行作为考核的目标。当我们看到Google开发的代码量超过20亿行(Google旗下所有产品,当时是2015年)的消息,或者Windows团队每天的代码push超过8400次时,我们都会瞪大眼睛,即便我们知道这两个都不是让Google或Windows变得有用的关键。有时社区甚至会折腾出类似这样的废话:
(顺便说一句,我还是要对他养成这种几乎每天都写代码的习惯表示祝贺,也对他偶尔不写表示祝贺。尽管在没有看过他们的贡献历史的情况下,我不会对这个人的工作效率下结论)
不管怎样,我们都可以将这些衡量措施添加到无效手段清单里面。用修复的bug数量、完成的任务数,或者交付的功能数来衡量同样是徒劳的。如果目标是修复更多的错误的话,那开发人员可以故意写出有bug的软件,然后再去写大量的修复程序;或者,为了实现相反的目标,他们可以用慢工出细活为理由来减少错误数量。如果目标是功能发布的话,他们可以写得很快很幼稚,导致软件运行缓慢且几乎无法运行。如果目标是完成的任务数,那么整个团队都会卷入内斗,因为大家都会去争夺最简单(或最被高估)的任务。高素质的团队也许会不理睬你的衡量措施,只顾干好本分工作,但就算是在最好的情况下,糟糕的衡量措施也是很难无视的障碍。
有些组织在这方面已经走火入魔,开始在员工的计算机上安装间谍软件,妄图用鼠标的移动,按键以及屏幕截图等手段来跟踪每时每刻的工作细节。在这种监视下,还有谁能够开展创造性的工作呢?我觉得大多数的开发人员都会马上自己炒老板鱿鱼。但是,就像前面讨论过的衡量措施一样,这里最明显的失败在于,它没有捕捉任何到对企业或客户真正有意义的东西。你会因为某位高效表现的开发人员在Reddit上面逛的时间太长,移动鼠标的频率高而对他进行惩罚吗?你会因为某位开发人员花来很多时间在Visual Studio上面敲代码而提拔他吗(就算他们很难跟别人合作)?有的经理显然就是这么做的,我唯有希望我们大多数人都能做得更聪明些。
好了,我已经警告过你最好不要用哪些最糟糕的衡量手段了,接下来我们再来谈一谈哪些才是好的手段。不幸的是,个人的绩效几乎没法靠“这个团队成员有贡献”或者“这个团队成员没有贡献”这种非此即彼的二分法来衡量。而且,也不能远距离地进行衡量。
软件开发团队不是一群人在那里单干;每个团队成员的工作成果都是所有其他队友工作成果的函数,更不用说一天当中那些有意义的,不可衡量的互动了。个体工作之间的相关性以及微妙之处实在是太复杂了,是外部观察者无法衡量的。比方说,某些团队成员是团队其余成员的力量倍增器——那些人也许没法独立完成很多工作,但如果没有他们的帮助和影响,其他团队成员的生产效率就会大大降低。像这样的人是高效工程组织的秘密武器,但是他们的生产效率是没办法在个人层面来衡量的。有的团队成员未必能开发出很多的功能,而是随时随地充当“代码管理员”的角色,对代码进行仔细的测试,清理以及重构,从而让团队成员可以更快、更轻松地开发功能。作为个人,这些人的生产力也是无法衡量的,但是其对团队生产力的影响却是指数性的。哪怕对于要定期发布新功能的程序员来说,生产效率在短期内往往也会有很大差异,导致难以进行具体的跟踪。出于这样的原因,个人的绩效最好留给个人贡献者自己以及彼此进行衡量。
而反过来看,团队的绩效则要好评价得多。跟踪绩效的最好办法也许是问。这个团队有没有在数周乃至数月的时间范围内持续开发出有用的软件?这一点正好跟敏捷的第三项原则呼应:“频繁地交付可工作的软件,周期从两周到两个月不等,最好所用的时间跨度较短。” 能够定期地做出有用的软件的团队就是高效的团队。如果不能,那就要问问为什么。缺乏效率一般都会有正当的理由。大多数生产效率不高的团队都希望提高生产效率,而生产效率高的团队大都希望更上一层楼。
可以通过简单的,整体的观察从组织的规模上去衡量团队的生产力。而且由于团队成员之间往往很了解彼此的贡献(无论这种贡献是不是可以衡量),所以通过良好的组织习惯就可以发现个人生产力方面存在的任何严重缺陷,比方说,经理跟自己的直接下属之间可以经常进行一对一的会面;定期收集匿名的真实反馈;鼓励每一位团队成员汇报自己取得的成绩,对失败承担责任,通过这样加强个人责任感。
这里面很多都要取决于人,而不是靠趋势图和原始数据。这是软件不可回避的事实:软件更多跟人有关,远不止是0和1,而且一直都是这样。生产力跟踪工具和激励计划永远不会像职场的积极文化那样能够产生巨大的影响。当问责制和健康的沟通融入到这种文化里面时,最有能力解决这些问题的人很快就会意识到生产力的关键时刻。
很多组织把速度作为衡量团队生产力的首选指标,如果做法合适的话,这可以是了解软件开发过程的一个有用工具。速度是一个聚合的衡量措施,用来考量团队随时间转移完成的任务情况,一般会考虑到开发人员自己对每项任务相对复杂性的估计。它要回答诸如“这支团队在接下来的两周里可以做多少工作?”之类的问题。基准的答案是“大概跟前两周一样”,而速度就是这一陈述的背景。这项措施是计划性的,而不是追溯性的,任何人如果想给它施加激励,最终都会发现它的准确性会在压力下逐渐消失(有关这部分内容,可参阅Ron Jeffries写的《软件开发的本质》)。当你要确定功能开发的优先级,要建立客户的预期,以及进行未来产品规划时,了解一个团队、一个部门或者整个公司的速度如何是基础。
再也没有比“任务乘以复杂性”更有效的衡量手段了。就像某些工具一样,衡量团队这个级别的提交数,代码行数或者编码所花费的时间并不必个人层面上有用。看团队写出的代码量,看他们花在代码上的时间,这些跟所做贡献的价值之间根本就没有关系。
很多组织在没有任何不可改变的衡量措施的情况下也能做得红红火火。如果有用的软件对于目标以及开发工作的主要衡量手段(虽然难以量化)来说都很容易理解,并且输入被相应降低了优先级的话,那这个指标的潜在意义要大得多。这样一来,开发人员可以无拘束地去做出自己的最好的表现,而不用受到时间和地点的限制。这可以是朝九晚五,也可以不是。有些人会出于个人喜好或者需要,选择在早上或者深夜完成大部分的工作。而有的人则可能更适合零敲碎打:这个时候干1小时,然后过一阵子再干几个小时。有的人喜欢在家里干活,有的愿意在办公室工作,有的喜欢在路上干活。这属于功能,而不是错误。这种做法强调真正的生产力,而不是生搬硬套进某种可观察的机械主义,而且这样还可以为更加深厚的人才库提供支持,比方说那些上班族父母以及残疾人。关于结果导向的工作环境(ROWE),关于远程办公,关于减少在会议上花费的时间,以及灵活的工作时间的好处的文章有很多,也讨论了很多。所有这些都是真正精明的生产效率指标的体现。
有个说法叫做你考核什么就得到什么。按照这个说法,你就应该只考核你真正想要的东西,而不管这个东西能不能画成折线图。对于某些人来说,去做或管理没法简化成数字的工作可能会令人沮丧。但是对于像软件开发这样微妙而抽象的工作来说,我们越是深入细节,就越无法实现自己的目标。有用的软件是我们的目标,除此以外,我们不应接受(或衡量)任何其他的东西。
译者:boxi。