小型甩锅现场: 小公司程序员如何生存

96 阅读7分钟

这个Bug,你是不是上次就没改好? 当项目经理(兼职产品)在钉钉上@我,风轻云淡地打出你提个事故报告吧,说明一下是修复了又重新复现,还是第一次时,我的脑子嗡的一下——心想完了,这锅怕是要砸我头上了。

看似美好的优化

首先,得交代下背景。

我们之前优化或者说重构了对账模块。

原方案: 实时查询订单相关的N张表,又慢又复杂还各种计算。

新方案: 我们定义规则,DBA团队每天T+1 + 实时把数据清洗到对账表里。我们只需要查这张干净的表就行。

这个架构升级,看起来很美好,性能上去了,代码也清晰了。

被现金退款干翻的现实

一切都很完美,直到上周,有商户反馈:对账数据不对!

我立刻去排查。

很快,技术问题定位了: 一个诡异的幽灵Bug!

商户通过微信/支付宝收款,这没问题。 但当这笔订单后续发生了现金退款时, 我们的系统,错误地把这笔现金退款的金额,记在了原始的微信/支付宝渠道上!

导致商户的线上渠道(微信/支付宝)的账面金额平白无故少了钱,跟他们实际提现的数据根本对不上! ,数据能对上才有鬼。

锅是怎么到我头上的?

技术问题不难定位。 难的是人的问题。

这个锅,为什么到我头上了? 因为真空!

流程真空: 这个模块当初压根就没测试!(不是QA没介入,是我们很早就已经没有测试了)

产品/验收真空: 负责这个模块的,是我们的项目经理...兼职的产品! 他自己都不记得当初的需求逻辑了!最要命的是,当初还是他自己验收通过的!

责任真空: DBA团队只负责清洗,他们不背业务逻辑的锅!

所以绕了一大圈,穿过流程、产品、DBA... 自然而然地,精准砸在了我这个开发身上。

那句必杀的提问

如果只是背锅,我也认了。裸奔纯靠自测和产品验收,出问题可不就是开发背嘛。

但杀人诛心的来了!

那个兼职PM(那个自己验收通过的PM!)@我:

@我,这个现金退款的问题,我好像有点印象,前段时间是不是出现过? 你提个事故报告吧,说明一下是复现了,还是第一次?

他是个天才! 这是必死局!

我如果回答是复现了:

翻译:你上次没修好!代码质量有问题!这锅你背死!

我如果回答是第一次:

翻译:你这次没考虑到!需求理解有问题!这锅你还是背死!

我怎么回答都是死!

最要命的是... 我的脑子里...确实有点印象... 我好像...真的...修复过...

老油条绝不相信记忆

在那一瞬间,我慌了。 但是作为一个小公司的老油条!

一定要明白永远不要相信你的记忆,尤其是在高压和甩锅现场! 你的记忆会欺骗你,它会根据当前的指控,伪造出合理的回忆!

我顶住压力,在钉钉上回了一句:

稍等,我查下上下文,这个逻辑有点复杂。

(翻译:别催,老子在找证据!)

我立刻去查!查的不是代码,是工单! 因为我们修改线上数据需要提交工单。

果不其然!被我找到了!

证据一: 前几个月,我确实处理过!但我是直接修改了对应的对账表数据!

然后,我马上去查Git Log,查那几天的前后分支提交情况!

证据二(Git Log): 一根毛的代码提交记录都没有!

真相大白! 我的记忆偏差了:我只记得我处理过,却忘了我是用数据订正(Data Patch)的土炮方式处理的!

我根本没改过代码!

釜底抽薪:从Bug到逻辑缺陷

证据链完整了。 我该怎么回?

A选项(菜鸟死法):

@PM 我查了,我没改代码,我是改的数据库。

(翻译:锅还是我的,只是我上次偷懒了,治标不治本。 -> 死路一条!)

B选项:

结合现在证据推理还原当时情况。 做过这种通过数据清洗进行优化的同学们都懂: 标准操作是:如果是逻辑问题,应该是去修改源表(比如订单表),然后重新触发DBA的清洗逻辑,让数据自动刷新到对账表。

我为什么反着干? 因为当时重跑清洗逻辑没用!

唯一的推论: DBA团队的清洗逻辑本身就是错的!

清洗逻辑处理不了微信付现金退款这个场景,所以源表数据对了也没用! 我才会去强行修改最终的对账表!

这个锅,完美地甩出去了!

降低影响:私信PM,搞定收工

证据链完整了。 但汇报是艺术!

背景分析:

PM很忙,他没空去核实DBA的细节。 他信任我的排查。 他只想要结论和立刻修复!

核心思路:

  1. 这不是我的代码Bug,这是DBA的数据逻辑缺陷!
  2. 这不是修复,这是历史遗留的临时数据订正!
  3. 这不是事故,这是二期优化需求!

我立刻私信PM(最好不要在群里公开处刑DBA):

@PM 查清楚了,这个事比想象的复杂点,我得跟你同步下。

确实之前出现过,是历史遗留问题。

我查了工单

和Git Log(截图附上),上次我没改代码,是跑了数据订正,直接改的对账表。 (摆证据,证明我没修复失误。)

我之所以直接改数据,是因为我发现源表数据是对的,但DBA的清洗逻辑(V1版)本身就处理不了现金退款这个场景。我改源表重跑也没用。

所以,这不是我代码复现了,而是DBA的清洗逻辑一直还没改。加上这个场景商户用的比较少,所以暴露了。

5.(给方案)要彻底解决,DBA那边的清洗规则也要调整。我先紧急修复一下保证线上没问题,但这事得排个二期优化,不然下次还得爆。

事故报告我来写,我会写成历史数据逻辑缺陷导致,你看OK不?

小公司的生存法则

一场必死局,就这么被我乾坤大挪移了。

锅, 从我的代码Bug,变成了DBA的逻辑缺陷/项目的二期需求。

责任, 从我的修复失误,变成了PM的需求优先级。

我, 从背锅侠,变成了主动推进项目、逻辑缜密的积极贡献者!

最后,总结几条小公司的生存法则:

永远不要相信你的高压记忆,马上去查证据(工单、Git Log、聊天记录、需求文档)。

你的操作就是证据:你如何修复的(改源表 vs 改结果表),反过来证明了锅在哪里!

永远不要在真空流程下干活(没有测试、兼职产品、自己验收)。干了,就要留下所有的书面证据!

学会重新定义问题:把你的Bug(点),上升到DBA的逻辑(面);把修复,偷换概念成升级!

永远不要自己背决策锅。把决策权还给产品经理,他才是背得动需求锅的人!

私信永远比公屏好用!