如何提升自己的工作成效 -《卓有成效的工程师》读后感

249 阅读16分钟

背景

近几年来,『内卷』已成为互联网行业不可忽视的痛。大家疲于奔命、拼命加班,因忙碌的工作而缺乏思考和总结,形成恶性循环,阻碍了自己的成长。比如有的人被动地接需求,机械式地敲着重复的代码,头顶永远悬着一把叫『deadline』的达摩克利斯之剑,但却从未思考过实现方式是否合理,逐渐成为团队的工具人;有的人被迫接了前人留下的烂摊子,疲于排查和处理线上问题,但却从未思考过如何收敛和解决;有的人固守于自己的一亩三分地,不愿接触新知识和新领域,在自己的舒适区消磨光阴...... 因此,很有必要探讨下如何提升自己的工作成效。这里的自己特指软件工程师。

IMG-20240404220436464.png

衡量工作成效

在探讨如何提升工作成效之前,我们首先得明确如何度量工作成效。可参考『卓有成效的工程师』一书中的杠杆率概念,杠杆率是衡量工作成效的标准,关注所投入时间的 ROI,即单位时间内所产生的价值或影响。杠杆率越高说明你的工作越有成效,反之则越低效。杠杆率定义如下: 杠杆率 = 产生的影响/投入的时间 从上面的定义我们可以找到提高杠杆率的三种方法:

  1. 减少分母,想办法更快地完成一项工作
  2. 增大分子,扩大工作的影响力
  3. 转向杠杆率更高的工作 下面以杠杆率为抓手,结合实际工作经验,和大家一起探讨如何提升工作成效。

如何提升工作成效

预估杠杆率的分子和分母

计算杠杆率需要两个重要因子:项目时间和工作价值。因此预估杠杆率就需要具备预估这俩因子的能力。

项目时间预估

项目时间估算是软件工程师必不可少的技能。小到一个feature,大到一个系统的重构,都需要时间估算。《软件估算的艺术》一书中对好的估算给出了定义:一个好的估算能够对项目的实际情况提供足够清晰的视角,使项目负责人能够就如何控制项目以达到目标做出正确的决定。准确的估算有益于团队和个人的良性发展,那么如何做呢,这里给出一些建议:

  1. 将项目分解为细粒度的任务。任务粒度拆细后其要实现的功能就会越明确,估算的工作量也就越精确。
  2. 根据任务需要的时间进行估算,而不是根据自己或别人的希望。估算工作量一定要客观,不要被其他因素影响,客观给出估时是一个软件工程师的基本操守。
  3. 将估算结果视为概率分布,而不是最佳情况。日常工作中难免临时会有更紧急的工作插入,比如线上问题排查,所以你的估算并不是最佳情况,如果有必要,可以对估时加个概率分布,让项目负责人尽早预案。
  4. 让执行实际任务的人来做估算。最终谁来执行任务,就由谁来估时,往往越简单的道理越容易被我们忽视。
  5. 使用多种方法估算同一任务。对于复杂任务可以通过多维度的方式估算,比如任务拆细后估算每一个子任务的时间、收集历史类似项目的耗时
  6. 当心『人月神话』。通常情况下,时间估算会给出人天,即一个软件工程师完成项目所需的工作天数。但是一定要谨防一个陷进:人和时间是不能等价互换的。比如估时5人天,即一个工程师完成此项任务需要5天的时间,现在5个工程师,只需要花费1天的时间,这明显是不可能的。
  7. 借助技术详设评审进一步验证估算合理性。在开始行动(开发)前一定要有技术详设,对需求(项目)有一个清晰的理解,完成必要的前期调研工作。邀请组内相关成员参加自己的详设评审,借助集体的智慧再次检查方案的合理性和每个功能点的成本。一定要记住:想比做更加重要!
  8. 通过后验数据进行自我修正,提升估算能力。根据项目实际完成情况,对估算做一个复盘,好的点、不好的点都需要总结,不断修正和提供自己估算项目的能力,即所谓的数据飞轮。

工作价值衡量

相信很多工程师都曾被领导这样问过:这个工作的收益是什么?有具体的量化数据么?对业务有什么贡献? 其实,这里的一个核心问题就是:工作价值如何衡量,对应杠杆率公式中的分子。要提升自己的工作成效,首先得弄明白怎么衡量自己的工作产出。 首先要找到能够度量工作进展的指标,并建立监控,有了基准数据后可以做为今后工作的benchmark,也可以帮助我们进行工作价值的大概推算。但有一点值得注意,指标的选取有很多学问。一定要谨慎选择,不同指标会激励不同的行为,确保正确的方向。举个反例,之前工作中为了提升团队研发效率,制订了研发效率衡量指标,研发时间=提交第一行代码时间开始计算,一直到提交测试为止。导致很多工程师故意积压代码,等到开发自测完成后统一提交代码,大幅增加代码评审难度,更糟糕的是,有些问题的暴露延后导致整体项目的交付延期。因此,指标的选取至关重要,选取不合适,会适得其反。当单一指标不能完整度量时,需要找到合适的指标群(多个指标的组合)。要记住:拥有糟糕的指标比没有指标更糟糕。 但是有些工作确实很难找到可度量的指标,这时候怎么办?个人的经验是反向思考,即如果不做这个工作,会有什么后果。比如,一个饱经沧桑的系统,经历了一代又一代工程师的雕琢,模块结构、业务逻辑都已经复杂到难以维护,这个时候有个人站出来,提出要重构系统,那么如何衡量这个工作的价值呢?降低系统的熵复杂度?提升研发效率?嗯,很难有量化指标来度量这个工作的价值。这个时候不妨反过来思考,如果不做这个重构,会怎样?日常需求迭代无法继续、线上一旦出问题无法快速止损和修复,进一步可以给出 一些预估的数字来表达这些结果的严重性。一个项目做之前需要花时间想清楚背后的逻辑,想比做更加重要。我相信,在这些事实面前,你的主管一定会鼎力支持。有的时候,记住,宁要模糊的正确,也不要精确的错误。 确立度量指标后,要尽早且频繁地验证想法,建立反馈循环,以便收集指标数据并评估工作的价值和有效性。不要做出一个重要的决定后就蒙头前进,要养成及时验证决策的习惯,反馈很重要,一旦发现和预期有偏差,要及时调整方向。这里建议在工作中采用最小化产品的思路,先把mvp版本做出来,收集用户反馈,小步快步,通过每次快速迭代来验证自己的想法,不断验证不断修正。对于周期较长的项目,比如复杂系统的重构,可以设立阶段性的里程碑,定期回顾项目目标,以免偏离航道。

提升工作成效方法1:定期调整优先级,专注于完成杠杆率最高的工作

具备估算工作价值和工作时间的能力后,我们就能预估出每项工作的杠杆率,那么提升工作成效的最直观想法就是:定期调整优先级,专注于完成杠杆率最高的工作。这里给出4个小tips:

  1. 写下todolist并定期回顾,将精力和脑力花在调整任务的优先级及处理任务上,而不是试图记住它们。那么,如何确定哪项工作比当前所做的杠杆率更高呢?就是接下来的2点:关注直接创造价值的工作,以及关注重要但不紧急的工作。
  2. 关注直接创造价值的工作。黄易山根据他在Facebook领导软件工程团队多年的经验解释说,"工作不一定有产出",而且许多工作"并不直接贡献有用的产出。诸如撰写状态报告、整理工作、创建组织制度、反复记录事情、开会、回复低优先级的邮件都是没有直接产出的例子"。这些任务与创造价值只有微弱而间接的联系。所以我的做法事:不要试图完成所有工作,要专注于重要的工作——就是那些直接创造价值的工作。
  3. 关注重要但不紧急的工作。我们每天都会被很多紧急请求淹没:会议、消息、电话、bug、报警。如果不加以区分就立即响应任何紧急事项,我们的工作安排就会被这些日常干扰打乱,而无法按待办事项清单中的优先级来进行。因此,在优先完成直接创造价值工作的同时,我们还需要优先考虑那些能够提升我们的能力、在未来创造更多价值的工作。举一个工作中常见的例子:线上频繁报警需要我们排查处理,打乱我们的工作安排,那是不是得问下自己,是否每次处理的方式都是指标不治本,没有找到问题的根源?是否可以实现自动修复,避免人工介入?基于工程师的创造力将紧急不重要的工作逐步转换成重要不紧急的工作,走上效率大幅提升的康庄大道。
  4. 减少上下文切换。为创造性的产出留出大块时间,并限制同时进行的项目数量,从而避免将心力浪费在应付各种任务上。

提升工作成效方法2:善于利用工具提升效率

但是日常工作中,存在很多并非高价值的工作(其中很大一部分就是方法1中紧急但不重要的工作),比如局部小功能优化、系统功能联调、事务性数据统计、线上case排查和修复等。这类工作的特点往往就是琐碎,提升这这类工作的有效方法就是利用合适好用的工具,实现事务性工作自动化,解放我们的精力。

  1. 投资节省时间的工具。Twitter平台工程前副总裁会不断提醒团队,"如果某个任务必须手动两次以上,那么第三次就去编写一个工具"。一天中的工作时间是有限的,所以我们影响力的扩展是无法通过加班来实现的。工具是一个倍增器,它使我们能超越工作时间的限制,扩大自己的影响力。从开发、代码cr、流水线执行、自测、联调、测试、到最终发布,各个环节都有可工具化的点,通过工具化实现事务性工作的SOP,大幅提升我们的工作效率。
  2. 持续推进机械任务自动化。这项其实和第一项有交集,自动化本身也是工具化的一种。但这里主要聚焦的是机械任务,比如某类线上报警处理(无论何时、无论何地)。由于业务特点,团队凌晨有很多重要任务,一旦发生报警需要第一时间进行处理。更令人沮丧是,你在凌晨4点被叫醒,最后发现是上游数据的问题,然后等待1小时就绪后,重新执行几条命令即可。采用一个临时的人工解决方案可能要比创建自动化解决方案花的时间更少,但从长远看,使用自动化解决问题将产生复利效应并带来更多的回报。当然,并不是无脑将所有人工解决方案都转换为自动化解决,也要看此类问题处理的频率,估算自动化工具的ROI。

提升工作成效方法3:构建长期价值

正如方法1,为了提升工作成效,我们要聚焦杠杆率最高的工作,其中迭代速度(分母)可以通过方法2中的方法进行提升,那么假设在不考虑分母这个变量的情况下(控制变量法),高杠杆率工作其实就等价于高影响的工作,即我们平时说的『重要但不紧急』的工作。也就引出了提升工作成效的第三种方法:构建长期价值。很多工作短期不做也不会有问题,但是从长远来看,这部分工作对团队对业务的健康发展有显著影响。近年来,与各大互联网公司提倡的『长期主义』理念不谋而合。 以下是我总结的具备长期价值的工作

  1. 通过代码审查来关注高质量代码 Code Review 执行不彻底的万能借口:太忙!正如下图所展现的,大家宁可用着低效的工具,忙的不可开交,也不愿停下来,用点时间更换高效的轮子。就像大家虽然知道:可通过人工审代码降低风险、增强可维护性和提升研发效率,同时可以有效提升个人和团队技术能力,但是在项目排期紧急面前,还是会用各种理由不执行code review。

IMG-20240409083528562.png

  1. 构建正确的软件抽象 《软件抽象》(Software Abstractions)一书中,阐述了选择正确的抽象的重要性。选择正确的抽象,你的设计就能自然而然地转换为程序,模块的接口将会小而简单,新的功能也更易于适配而不需要进行大规模重组。如果选择了错误的抽象,编程时将出现一系列令人头疼的意外: 接口会因为要被迫适应意料之外的交互而变得怪异和笨拙,甚至难以实现最简单的变更。好的抽象具备如下特点:

    • 易于学习
    • 易于使用,甚至无须文档。
    • 难以误用
    • 足够强大,能满足需求
    • 易于扩展
    • 适合于受众 好的抽象将复杂的概念分解为简单的概念,难题只需要处理和解决一次,其解决方案每使 用一次就会得到一份额外的回报。
  2. 管理技术债 在讲code review的时候有提到过为了短期的排期,牺牲代码质量的问题,其实这就是一种典型的技术债。为了赶排期,我们会以一种在短期内合理,但从长远来看可能代价高昂的方式来开发软件,从而形成技术债。技术债是指为了改善代码库的健康度和质量必须做的却被延迟的所有工作,如果不加以解决就会减慢迭代速度。正如《重构》一书的作者马丁·福勒所指出的,“最常见的问题是开发组织失去对技术债的控制,并将未来大部分的开发工作花在支付 技术债的巨额利息上”。但不要盲目地偿还任何情况下的技术债,而是将有限的时间花在偿还杠杆率最高的技术债上—用最少的时间,修复代码库中被调用得最频繁的代码。

  3. 制定故障预案 我们很难保证团队中所有成员的工作都靠谱,一旦出现问题,没有故障预案,会导致严重的业务损失和人力浪费。如何最小化线上运维负担?减轻团队线上运维压力?答案是:制定故障预案,而且尽量自动化,降低预案过程中的人为参与比例。这里有个亲身的经验分享:在开发功能时,要考虑接口和功能的幂等性,幂等意味着可以自动重试,从而降低故障率。

  4. 培养一种学习和持续改进的文化 在匆忙完成任务的过程中,我们经常从一个任务切换到另 一个任务,从一个项目转移到另一个项目,而没有停下来思考如何有效地利用时间,或者是否可以做得更好。同样的问题可能在接下来的大项目中重蹈覆辙,浪费大量时间和人力,如果我们能够花几个小时定期对一些项目进行复盘,坦诚地总结团队的经验和教训,为下一个长达一个月的团队项目增加成功的机会,那么这无疑是一项杠杆率很高的活动。所以请不要吝啬花时间和精力在沉淀集体智慧这件事上面。

总结

本文做为《卓有成效的工程师》一书读后感,围绕如何提升工作效率,从杠杆率概念出发,介绍了如何预估项目耗时和项目收益,然后总结了3种有效的方法:专注于完成杠杆率最高的工作、善于利用工具提效、构建长期价值。期望大家在自己的工作中都能做到卓有成效!