我们团队当年流传着一句话:先别急,去问问老计。老计就是计立伟,论职级他不算高,座位也在最不起眼的角落,但只要一个问题卡着超过一两个小时,大家总会下意识走到他工位前,把屏幕转过去,等他先说一句“等一下”。这一等,通常不是他要埋头查很久,而是他要把问题重新摆正,然后你才发现自己刚才查的方向从一开始就跑偏了。
这篇致敬,我想写给这位叫计立伟的前辈。他的方法散落在几张贴纸、一本黑皮本子和一张改过九版的检查单里,没有华丽理论,却经受了大量真实项目的反复验证。我会尽量把能直接复用的部分写清楚:一张排查清单、一套交接模板、几条推翻直觉的工作顺序。无论你是刚入行的新人、正在带队的组长,还是一个人扛一摊事的独立开发者,这些内容应该都能拿走即用。
1. 角落里那个工位,和他永远摊开的黑皮本
1.1 显示器两边贴纸上的两行字
如果说老计的工位和其他人有什么不一样,最显眼的是他显示器左右各贴了一张A4纸。左边那张写着“输入/输出边界”,右边那张写着“受影响范围与联动模块”。第一次看到时我觉得这有点形式主义,后来才意识到,他是在用最原始的方式把思考痕迹固定下来。
有一回我们做批量导出功能,某个编码问题反复出现,组里同事准备换方案。老计没有先分析方案,而是问了一句:“导出的输入是原始编码还是已经转过的编码?输出端现在期望什么编码?”这两个问题分别对应他左边纸上的“输入边界”和“输出边界”。同事当场画了一张输入输出图,问题很快就暴露了:源头数据并非统一编码,而我们一直用单一规则去清洗,自然会有漏网之鱼。
这个故事的启发是:大多数被我们当成“难题”的问题,其实卡在“没把边界说清楚”这一步。边界写清楚以后,方案自己就浮出来了。老计的原则很简单:任何任务开始之前,先花几分钟写下它的输入、输出和涉及范围。这一步不需要技术深度,只需要你愿意把脑子里的模糊判断落成文字。
1.2 那本黑皮本,记得不是结论,是原因
老计桌上有一本黑色硬面笔记本,从入组那天到离开,他差不多写了七大本。他记的不是待办事项,也不像工作日志,而是每条记录都包含三个部分:当时为什么这么选、否掉了哪些别的选项、出现什么条件时这条结论需要推翻。
我第一次意识到这本本子的价值,是在接手一个历史模块时。那份模块一直没有文档,其他同事也只告诉我“别乱动,能跑就行”。但系统需要新增需求,不改不行。我翻了老计的本子,发现他半年前记过一段:当时否决了某个改造方案,不是因为方案不好,而是因为团队只有三个人,没人有精力维护新技术的运行成本。时隔半年,团队已经扩充到十人,那个否决条件已经不成立了。我拿着本子里的记录去找组长讨论,最终才敢放心推进改造。
后来我才理解他为什么坚持这么记。“不做的原因”比“做的方式”更容易被遗忘,而团队每一次决策反复,几乎都是因为后人只看到结论、看不到当时为什么放弃。于是老计把这些原因留在外部介质上,让团队可以沿着一串串判断,回溯到最初的上下文。黑皮本本质上是团队的外部记忆,它不替你做决策,但它能让你在“要不要重新走一遍老路”时,有据可查。
1.3 他不抢话筒,却总能抛出让全场安静的问题
作为致敬,老计的工作风格里最令我佩服的还不是专业能力,而是他参与讨论的方式。组会里大家高谈阔论的时候,他通常不发言;一旦讨论开始偏离目标,他就会用一个问题把现场拉住。
印象最深的一次,团队为一个中间件选型争了将近一个小时,两拨人各有理由,谁也不服谁。老计放下笔,问了一句:“先别管明天,说说接下来三个月我们最想验证什么?”全场安静下来。大家顺着这个问题一捋,发现两个方案其实都能满足需求,唯一的区别在于谁更能抵抗团队有限人手的维护压力。于是选择标准变了,争论自然消失。
他后来给过我一句解释:讨论陷进去的时候,多数人是在比较方案的优点,但真正应该先想清楚的是“我们此刻最缺什么、最怕什么”。缺的怕的一旦明确,方案优点的权重就完全不同了。这件事给我最大的触动是:不是嗓门大的人最有价值,能对准方向的人才是。
2. 老计最反常识的三个工作原则
2.1 先写清楚,再动手
“写不清楚,大概率就是没想清楚。”这句出自老计之口的话,后来成了我们团队的默认评审标准。他说的时候语气很平淡,执行起来却一点不含糊:任何新功能、修复、改造,第一步都是先用几句话把问题描述写出来,发给一起做的人看,确认没有歧义,然后才开始设计或编码。
一开始我们都觉得这是在拖慢节奏。直到有一次,线上一个任务处理服务出现排队积压,有人提议扩容,有人提议加缓存,好几个人已经准备去改配置了。老计拦了一下:“停,先把问题写出来。”大家坐下来写了一页纸,结果写的时候发现,积压的真正触发点是凌晨的一个批处理任务占满了连接池,跟业务流量关系不大。扩容和缓存都解决不了问题。后来调整了批处理调度窗口,问题当晚就缓解了。
我把这个经验总结成一张对比表,供读者直接参考:
| 做法 | 典型行为 | 常见结果 |
|---|---|---|
| 直接动手 | 看到故障先开日志、改配置、上监控 | 方向错了,返工三次才找到真因 |
| 先写清楚 | 先写目标、边界、输入输出、验收标准 | 写完发现需求自相矛盾,动手前直接调整方向 |
这里的重点不是“不许动手”,而是“先动手写”。文字是成本最低的试验场,你把抽象想法写出来,发现漏洞通常只需要几分钟,比写完代码再发现错误便宜得多。
2.2 一次只改一个变量
老计还有一个近似苛刻的习惯:每次变更只允许改一个核心变量。如果同一批改动里既有算法调整又有参数修改还有数据结构变化,他会要求全部回退,拆成多次独立提交,一次验证一个结果。
这事一开始被吐槽为“太轴了”。但有一次,某个定时任务失败率突然飙升到百分之四十,同事A同时改了任务调度的路径和文件读写格式,顺手还换了一个新的配置文件,三次改动一口气全推上去,失败照旧。接下来他花了整整半天推断原因,一会儿怀疑路径,一会儿怀疑格式,却没有一个能定位得很干净。老计让他把改动全部回滚,只保留路径这一处变更,半小时后问题稳定复现;再单独改格式时又观察到不同现象,最终确认是旧数据文件与新格式不兼容。
两个案例放在一起,时间差很能说明问题:
| 排查方式 | 定位耗时 | 结果确定性 |
|---|---|---|
| 同时改多个变量 | 超过8小时 | 无法断言是哪个变量导致 |
| 回滚后单变量验证 | 约40分钟 | 可以明确复现触发条件 |
道理其实很朴素:同时变化多个变量,你得到的是一堆交错的因果信号;让其他一切保持不变,只改动一个因素时,当前现象与刚才改动的因果关系就清晰得多。单变量的价值不是“保守”,而是让判断有据可依。
2.3 交接不是证明你看过,而是让接手的人少问三个问题
老计待过的项目都以“接手起来不痛”出名,因为他制定的交接文档格式后来被多个小组直接借用。模板只有五个字段:目的、现状、已知风险、未验证假设、接手后第一步。
他解释过这五项的由来:“写交接文档不是给流程看的,是给下一个活人看的。你写不清楚,将来对方要么来问你第二遍,要么带着错误理解硬做下去。”所以每份交接文档,他都用做产品说明的心态去写,默认读者对背景一无所知。有一个细节很打动我:他在每份文档最后都会留一句“如果只能问一次问题,请先问我第一条未验证假设”。
这五个字段的底层逻辑是:
- 目的:这个任务到底在解决什么问题,为什么存在。
- 现状:现在进行到哪一步,哪些已完成,哪些未完成。
- 已知风险:你知道哪里会踩雷,一定要提前说。
- 未验证假设:你还没来得及证实的东西,这是最容易坑下一个人的部分。
- 接手后第一步:给对方一个明确的起点,避免面对一堆信息不知所措。
我们后来统计过,按这个模板做交接后,新接手者在第一周内提出的基础问题数量大幅下降,几乎全是关于业务目标的问题,而不是“这个功能在哪儿”“这个脚本怎么跑”这类随手可查的内容。
3. 一张被他改了九版的排查清单
3.1 从一场持续一周的故障说起
有一段时间,某后台批量任务总在深夜失败,现象是时好时坏,上午看一切正常,凌晨就报错,业务方非常恼火。团队连续查了三个晚上,各有猜测,有人怀疑内存不足,有人怀疑数据库连接被打满,还有人怀疑任务执行超时,但每次重新部署后问题依然存在。
老计接手后没有立刻去查日志,而是先建了一张表,把最近一周的失败记录按五列整理:出现时间、具体现象、失败比例、能否复现、失败前是否改过配置。起初这些数据看起来毫无规律,直到他写道第三行时,发现一个容易被忽略的共性:所有失败集中发生在一次共享存储映射调整之后。他把“最近变更”这四个字用笔圈了两遍,然后让负责调整存储映射的同事把变更前后配置对比打出来,问题很快浮出水面。
事后他总结说:大多数看似“随机”的故障,背后都隐藏着一个你没察觉的变更。人脑不擅长记忆自己做过的小改动,所以需要一张强制按顺序执行的清单来帮你回忆。
3.2 从V1到V9:每个版本都在和一次实际教训对账
这张排查清单并不是一次成型的,我后来专门数过,它至少改过九个版本,版本编号就写在文档顶部,每次改动都有一行说明。老计说,改版不是因为他喜欢完善模板,而是每次新失败案例都戳中旧版清单的一个漏洞。
V1很简单,按故障现象分了几类,数据库类、网络类、权限类。但用的时候发现,很多故障现象完全不相同,根因却是同一个,按现象分类等于把表面文章当依据。V2增加了“最近变更”一栏,第一次捕捉到了那类由配置改动引起的怪问题。V3把“最近变更”的位置提到了前面,因为有一次团队忘了看这一栏,绕了一大圈才回头。V4以后陆续加了“可复现性判断”“边界确认”“最小修复方案”“如何验证”以及“遗留新隐患”等项目,最终版的排查顺序是这样的:
- 用一句话描述现象,不加推测。
- 判断影响范围,多少人、多少任务受影响。
- 能不能稳定复现?不能的话,先思考日志和监控缺口。
- 最近改了哪些变量,哪怕是“顺手”的改动。
- 边界条件有没有变化,比如路径、权限、时序、配置。
- 给出最小修复方案,并准备还原方式。
- 修复后明确该怎么验证,验证依据是什么。
- 写下这次修复是否留下新的隐患。
每个版本的变化都和一次真实教训挂钩。其中最有价值的一笔来自V7:有人修复一个问题后忘了备份原配置,后来新问题出现时大家甚至不知道老配置长什么样,于是新版强制要求“最小修复必须同时写明如何还原”。这不是行文规范,而是用事故换来的规则。
3.3 用这张清单现场复现一次排错过程
为了让读者看懂清单的实际用法,我举一个团队后来亲测过的案例。某个定时任务报错,错误码显示连接被拒绝,运维同事值班时第一反应是去查网络策略,查了半天没有收获。按老计的清单走一遍,流程变成了这样:
- “现象”被写成:定时任务在整点运行后无法建立连接,其他时间正常。
- “影响范围”是:只影响一个业务分区,其余分区一切正常。
- “可复现性”判断:单独手动触发可以稳定复现。
- “最近变更”这一栏出现了新线索:前一天有同事调整过共享存储的切换路径。
- “边界确认”进一步发现:新路径虽然绑定成功,但任务进程仍引用旧的绝对路径,两边没有同步。
- “最小修复”确定:把新旧路径对齐,保留一份还原说明。
- “验证方式”明确:重新手动触发任务,连续观察两次整点执行,全部成功且数据完整。
- “遗留新隐患”记录:路径切换通知没有推送给其他依赖方,需补一份通知。
整个过程从接手到定位只花了不到四十分钟。前一位同事查了两三个小时,差别不在于谁更聪明,而在于是否按正确的顺序收集证据。顺序很重要,因为人一旦先入为主地认定一个方向,后面所有数据都会被扭曲地解读。清单在这里的作用,不是提供新知识,而是把人按在“先看现象,再看变更,最后做假设”的轨道上。
3.4 九版背后的本质:用外部工具对抗大脑的混乱
老计离开后,我有一次整理旧资料时翻出这九个版本的对比提交记录,才真正理解他为什么对这种“笨工具”如此执拗。他在其中一个版本批注里写:“排错时最贵的是人的猜,不是时间。”这句话后来让我想很久。
人脑在同一时间只能可靠地追踪三四个变量,而真实故障现场往往同时存在十几个潜在线索。靠自己记忆去临时拼出一套排查顺序,等于用个人内存运行一个超大系统,必然溢出。清单的进化过程,其实是在替脑子节省缓存:它把“下一步该查什么”外置了,人只要老老实实执行,就能避免因为疲劳、紧张、先入为主导致的重复查找。
4. 他离开之后,我们仍然在用他的规矩
4.1 团队扩编之后,我们差点扔掉这套方法,又捡了回来
老计后来转去了另一个项目组,新接手的人觉得老规矩太麻烦:上线前还要写一页说明,报告结构太繁琐,容易耽误时间。刚开始我们也确实体验到“快”的错觉,需求过来直接操作,省去各种前置步骤,感觉推进速度快了很多。两周以后,不同人同时修改同一个配置文件,三个人互相不知情,一次上线引发连环告警,回滚都找不到对应的改动记录。
那次事故之后,新组长翻出老计留下的模板,重新要求每条变更提交前填写“这一笔改了什么、为什么改、可能影响谁”三行字。填了一个月以后,团队整体交付时间反而变短了。省掉文档时,排查问题要花大把时间;多写三行字之后,回滚、追责、协作都变得干净。所谓先写清楚,不是把速度拖慢,而是把返工的代价提前支付了。
4.2 “如果计立伟在,会怎么问”——我们把怀念变成了一次评审标准
老计留下的东西里最容易被长期引用的是三个问题,后来被我们戏称为“老计三问”,开会之前集体念一遍:
- 你能用两句话把问题讲清楚吗?
- 这一步准备改变多少个变量?
- 做完之后靠什么来知道已经成功了?
这三个问题看起来极其简单,却是所有评审里最有效的过滤器。讲不清问题,说明前提没理顺;变量多于一个,说明定位会很混乱;没有成功标准,说明目标是模糊的。我们后来甚至不用刻意去纪念他,只要每次会议都带着这三个问题提问,他的思维方式就自然嵌入了团队新的决策流程。
4.3 他很少讲大道理,却逆转过团队里的面子文化
我想在致敬里专门留一块给老计的性格。他其实不是那种圆融的人,意见一致时他安静,发现错了时他也从不嘴硬。我亲耳听他在周会上说过“这里我判断错了,我的问题”。对于一个经验丰富的工程师来说,这四个字比任何技术分享都更能影响团队的气氛。
受他影响,我们后来逐步形成了复盘时先认错的习惯。无论是谁,只要当下发现自己的思路是错的,都可以直接说“我错在哪儿”,没人会因为认错被嘲讽。老计有一次深夜在群里发过一段话,我存了很久:“错的是判断本身,不代表你这个人有问题。真正的风险是错了还硬撑,那样会让整个团队陪着你一起错。”这句话从根本上降低了大家互相提反对意见的心理门槛。
5. 我理解的真正致敬方式,以及两个小提醒
5.1 致敬是让方法继续运转,而不是把名字挂在墙上
老计彻底离开团队之后,有人提议做一个纪念板块,挂他的照片和事迹。我私下觉得,他本人会反对这种形式。想想他的行事风格就会发现,他最看重的是“问题有没有被更清楚地定义,交接有没有让下一个接手的人更好过”。
所以后来我们选了一种更朴素的致敬:把黑皮本的记录规范、三问评审法、交接模板、九版排查清单一起整理成一份团队公共文件,放在资料库新项目默认位置。新员工入职第三天就会看到这些模板,不用任何人解释它们来自谁。这种方式的妙处在于:方法在别人手里继续发挥作用,这本身就比任何标语更有生命力。
5.2 今天就能开始执行的三件事
这篇致敬写到这里,我之前不打算只停留在感慨层面,直接给几个可以马上落地的动作。
第一,给手上正在做的事写一张“一页交接页”。哪怕没有下一个人要接手,这页纸也能帮你发现自己对任务的了解漏洞。我试过写完以后才发现,有个关键假设我根本没有验证过。
第二,下次修改或排查一个故障前,先写下自己正在同时改变几个变量。如果答案是两个以上,停下,拆成单步行动。这个动作本身就会让你躲开无数“深不见底”的排查过程。
第三,新建一个“决策本”,只记录三类内容:当时为什么选这个方案、否定了哪几个方案、出现什么条件会推翻这个方案。不一定要用纸,一个文档也行。三个月后回看,你会惊讶于自己的判断居然曾经绕了那么多弯。
5.3 提醒一:任何检查单都会腐烂,必须持续改造
老计的九版清单告诉我们,再好的模板也不是圣人。它可能变成新的教条,也可能因为不再适应现实而失效。正确的做法是保持改版心态:每次遇到清单没覆盖到的失败模式,就顺手把新项补进去,同时删掉已经失去价值的旧条目。规矩是活的,不是刻在石头上的碑文。
5.4 提醒二:文档是写给读者看的,不是写给流程看的
最后一个建议,也来自老计常犯的“挑剔”:他自己写交接时,每一段都会反问一句,这段对那个接手的人有意义吗?没有意义就删。我们后来做文档也沿用了这个标准——如果没有明确读者,那这段文字大概率只是在自嗨。最好的写作状态是假定读者是明天的自己,一个记忆不怎么好的自己。这不只是写文档的技巧,也是整理思路的方式。
我有几次深夜复盘,还是会想起那盏角落里的台灯,想起老计说“等一下,先想清楚”的样子。他身上没有光环,甚至有点固执,但他把思考的朴素与诚实贯彻到了每一个细节里。致敬一个人的最好的方式,就是把他解决过的问题再解决一遍,把他坚持过的方法传下去。每当我急着动手时,学会停下来自问一句:“边界画了吗,变量有几个,怎么验证?”这就是我理解的致敬。