跳到主要内容
阅微漫记
返回

如何把一次失败,写成一份「事故复盘报告」而不是自责

有些失败,我会记很久。

一件事情没有做好。

一次重要的机会没有抓住。

一个项目最后没有达到预期。

一次尝试没有得到结果。

有时候甚至只是一次表达失误。

事情已经过去了。

但脑子里还会不断重放:

“当时为什么这么做?”

“我怎么会犯这么低级的错误?”

“如果当时换一种方式,是不是结果就不一样?”

然后开始责怪自己。

能力不够。

判断错了。

执行力差。

准备不足。

是不是自己真的不行?

这种状态持续久了以后,我发现一个很奇怪的问题:

失败本身可能只发生了一次,但自责会让它重复发生很多遍。

而且每重复一次,都没有产生新的信息。

只是让自己越来越相信:

“我是一个失败的人。”

后来我突然想到:

如果这是线上系统发生了一次严重事故,我会怎么处理?

我不会坐在服务器旁边骂:

“你怎么这么没用?”

我会打开日志。

看监控。

还原现场。

分析时间线。

寻找触发条件。

定位根因。

检查影响范围。

制定修复方案。

然后:

写一份事故复盘报告。

为什么面对系统,我可以这么理性?

面对自己,却经常只剩下自责?


失败不是身份,而是一次系统事件

这是我后来特别想改变的一件事情。

以前失败以后,我很容易把:

事情失败

变成:

我失败了。

最后甚至变成:

我是一个失败的人。

这其实发生了一次非常危险的“类型转换”。

Event
↓
Failure
↓
Self Judgment
↓
Identity

一个具体事件,最后被转换成了对整个人的定义。

但如果换成工程视角:

System
↓
Incident
↓
Impact
↓
Root Cause
↓
Fix
↓
Prevent

失败只是:

一次系统事件。

它可以很严重。

可以造成损失。

可以暴露能力问题。

甚至可能意味着原来的方案根本不成立。

但它依然只是:

一个事件。

不是你的身份。


事故复盘最重要的第一原则:先还原事实

程序员做事故复盘的时候,第一件事情不是讨论:

“谁的问题?”

而是:

到底发生了什么?

时间是什么?

发生了什么操作?

系统处于什么状态?

哪个指标开始异常?

什么时候出现第一个错误?

影响了哪些用户?

持续了多久?

这叫:

事实还原。

放到人生里也一样。

比如:

“我做副业失败了。”

这句话其实信息量非常低。

可以继续拆:

什么时候开始?
投入了多少时间?
投入了多少钱?
原本期待什么结果?
实际结果是什么?
做了哪些动作?
获得了哪些反馈?
哪个环节最早出现偏差?
什么时候决定继续?
什么时候决定停止?

你会发现:

一旦开始写事实,自责就会减少。

因为你的大脑开始从:

“我是怎么回事?”

切换成:

“这件事情到底发生了什么?”


第二步:区分“事实”和“解释”

这是我觉得最有价值的一步。

例如:

“没人喜欢我的内容。”

这到底是事实,还是判断?

事实可能是:

发布了10篇文章,平均阅读量低于预期,没有获得预期的咨询。

“没人喜欢”其实已经是一个解释。

再比如:

“我不适合做副业。”

也不是事实。

事实可能是:

连续尝试三个月,没有形成稳定收入。

再比如:

“我的能力已经不值钱了。”

依然是解释。

事实可能是:

原来负责的某类工作需求减少,部分工作已经可以被AI辅助完成。

这两者差别非常大。

因为:

事实可以分析。

而一个笼统的自我判断,通常只能让你难受。


第三步:建立事故时间线

很多失败之所以让人痛苦,是因为我们只记得最后那个结果。

“失败了。”

但真正重要的信息,可能隐藏在过程里面。

所以我现在会尝试建立一个简单时间线:

T0
产生想法

T1
开始行动

T2
第一次获得反馈

T3
发现异常

T4
继续投入

T5
问题扩大

T6
最终停止

T7
复盘

然后问:

第一个可以被改变的节点在哪里?

这个问题非常重要。

因为真正有价值的复盘,不是找到:

“最后为什么失败?”

而是找到:

“如果让我重新来一次,我最早应该在哪个地方做出不同选择?”


很多失败,其实不是最后一步失败

比如一个项目最后失败了。

表面上看:

“产品没人用。”

但继续往前看:

可能是:

用户问题判断错了。

用户问题判断对了,但目标用户错了。

目标用户对了,但验证太晚。

验证太晚以后,又投入了大量开发成本。

最后才发现:

根本没人需要。

所以真正的问题可能不是:

“产品做得不好。”

而是:

在没有验证需求之前,就投入了大量资源。

这就是事故复盘的价值:

把结果往前追。


第四步:区分直接原因和根本原因

技术事故里经常有一个陷阱。

服务器挂了。

然后发现:

数据库连接池满了。

于是结论:

“数据库连接池配置不合理。”

问题解决了吗?

不一定。

继续往下追:

为什么连接池会满?

因为某个接口响应时间突然增加。

为什么响应时间增加?

因为一个查询没有走索引。

为什么没有走索引?

因为数据量增长以后,原来的设计没有重新评估。

这时候才开始接近:

根因。

人生失败也是一样。

比如:

“我这次面试失败了。”

直接原因:

面试表现不好。

再往下:

为什么表现不好?

准备不足。

为什么准备不足?

没有提前了解岗位。

为什么没有了解?

因为默认认为自己经验够。

再往下:

为什么会有这种默认?

因为过去很长时间里,我习惯用经验解决问题。

于是真正值得修复的可能不是:

“这次面试准备少了。”

而是:

“我对自己的经验产生了过高的确定性。”

这就是根因和表象的区别。


第五步:不要急着寻找“谁的错”

事故复盘最容易变成:

甩锅大会。

人生复盘也一样。

“都是环境不好。”

“都是别人影响的。”

“都是公司不给机会。”

“都是运气不好。”

或者反过来:

“全都是我的问题。”

这两种极端其实都不利于复盘。

因为真正需要问的是:

哪些因素我可以控制?哪些因素我不能控制?

可以拆成三个区域:

我能控制
↓
我能影响
↓
我无法控制

例如:

市场变化:

可能无法控制。

行业环境:

只能部分影响。

自己的选择:

可以控制。

自己的准备:

可以控制。

投入多少资源:

可以控制。

什么时候停止:

可以控制。

什么时候调整方向:

可以控制。

这样一拆:

自责会逐渐变成责任。

这是一个非常重要的变化。


自责和责任,其实不是一回事

自责说:

“都是我不好。”

责任说:

“这里有一部分是我可以改进的。”

自责攻击的是:

自己。

责任关注的是:

行为。

自责希望:

惩罚过去的自己。

责任希望:

改善未来的系统。

所以我越来越觉得:

真正成熟的复盘不是:

“我要狠狠记住这次教训。”

而是:

“我要让系统发生一次真实的变化。”


第六步:给失败做“损失评估”

事故复盘里必须看影响范围。

人生也一样。

有时候我们会因为一个小失败,产生巨大的心理损失。

比如:

一次面试失败。

就觉得职业生涯完了。

一篇文章没人看。

就觉得自己不适合写作。

一个项目失败。

就觉得自己没有创业能力。

但如果真正做一次损失评估:

实际损失:
时间:20小时
金钱:500元
机会成本:一些
经验:增加
认知:增加
能力:增加

你会发现:

事情可能没有想象中那么严重。

当然,也有一些失败的损失确实很大。

这时候更应该认真分析。

但:

损失大小应该由事实决定,而不是由情绪决定。


第七步:把失败转化成“系统补丁”

复盘做到这里,还没有结束。

因为:

知道原因 ≠ 问题被解决。

真正重要的是:

下一次怎么办?

比如:

这次项目失败,因为没有提前验证需求。

那么补丁可能是:

以后任何新项目
↓
先找3~5个真实用户
↓
确认问题是否真实存在
↓
再投入开发资源

这就不是一句:

“以后注意。”

而是一条:

新的系统规则。

再比如:

这次因为准备不足错过机会。

补丁:

重要机会出现
↓
建立机会Checklist
↓
至少提前48小时准备
↓
完成模拟
↓
再进入正式场景

再比如:

这次因为高估自己导致判断失误。

补丁:

重大决策
↓
写出自己的假设
↓
寻找反例
↓
找一个外部反馈
↓
再执行

这才叫:

从失败中提取系统升级。


最好的复盘,不应该只有“改进项”

还有一个东西经常被忽略:

保留项。

因为一次失败不意味着所有东西都错了。

比如:

方向可能错了。

但执行方式可能是对的。

结果可能不好。

但某个能力已经得到验证。

项目没有成功。

但获得了一批真实用户反馈。

一次机会没有拿到。

但发现了自己的能力缺口。

所以复盘应该同时问:

什么应该删除?

什么应该修改?

什么应该保留?

什么应该加强?

而不是:

“以后我什么都不要做了。”


失败之后最危险的行为:停止部署

这是我后来特别警惕的事情。

一次失败以后:

“算了。”

“以后不搞了。”

“我还是老老实实工作吧。”

“我不适合。”

然后整个系统进入:

FAILED
↓
ROLLBACK
↓
STOP

问题是:

Rollback是恢复,不是永久停止。

真正成熟的系统应该是:

FAILED
↓
ROLLBACK
↓
ANALYZE
↓
PATCH
↓
REDEPLOY

失败以后恢复。

分析。

修改。

再部署。

这才是迭代。


我现在特别喜欢一句话

失败是数据,不是判决。

这句话对我来说非常重要。

因为一旦把失败当成数据,你就会开始问:

数据是什么?

样本多大?

有没有偏差?

哪一个变量出了问题?

哪个假设被证伪?

哪个假设还没有验证?

下一次应该测试什么?

但如果把失败当成判决:

“我不行。”

那整个分析过程就结束了。


当然,也不能把所有失败都“正向解释”

这里我也越来越警惕一种东西:

失败美化。

不是每一次失败都值得继续。

不是所有失败都是成长。

不是坚持就一定有意义。

有些失败是在告诉你:

这个方向可能不成立。

有些失败是在告诉你:

这个成本太高。

有些失败是在告诉你:

你需要换一种方式。

有些失败甚至是在告诉你:

应该停止。

所以复盘的目的不是:

“怎么证明这次失败其实很好?”

而是:

“这次失败到底告诉了我什么?”

然后根据证据决定:

CONTINUE
继续

PIVOT
转向

PAUSE
暂停

STOP
停止

这四种结果都可以是有效的复盘结论。


给自己建立一份“人生事故报告”

如果以后再遇到一件让我很难受的失败,我希望自己能够先写这样一份东西:

【事故名称】
发生了什么?

【影响范围】
损失了什么?

【预期】
原本希望发生什么?

【实际】
实际发生了什么?

【时间线】
问题从哪里开始?

【直接原因】
表面发生了什么?

【根本原因】
为什么会发生?

【可控因素】
哪些是我能改变的?

【不可控因素】
哪些不是我的责任?

【保留项】
什么其实没有问题?

【修复项】
下一次需要改变什么?

【预防措施】
以后如何避免重复?

【下一次实验】
下一步准备做什么?

【结论】
继续 / 转向 / 暂停 / 停止

我觉得这张表最大的价值不是:

帮我把失败分析得多专业。

而是:

把情绪和事实分开。


写给未来自己的代码注释

// 发生故障,不要先责怪系统
// 先保存现场

incident = capture();

facts = collect(incident);

timeline = reconstruct(facts);

rootCause = analyze(timeline);

impact = evaluate(incident);

controllable = classify(rootCause);

patch = design(controllable);

if (patch.isValid()) {
    deploy(patch);
}

// 不要把一次失败
// 转换成自己的身份

failure != identity;

// 失败应该产生新的信息
// 信息应该产生新的规则
// 新规则应该改变下一次行为

failure
    → data
    → insight
    → patch
    → iteration;

写在最后

以前失败的时候,我最想做的事情是:

忘掉它。

现在我越来越觉得:

真正应该忘掉的,是那些反复攻击自己的话。

而真正应该留下的,是:

事故现场。

发生了什么。

为什么发生。

哪里判断错了。

哪里做得不够。

哪些因素不是自己能控制的。

哪些地方需要改变。

下一次怎么做。

这些东西才是真正属于自己的经验。

因为一个人真正的成长,可能不是:

从此以后再也不失败。

而是:

每失败一次,都能让系统升级一点。

如果第一次失败之后,我只是觉得:

“我不行。”

那这次失败只产生了痛苦。

如果我能够继续往下追:

“我为什么失败?”

“我的哪个假设错了?”

“我的哪个能力存在缺口?”

“我的哪个流程需要修改?”

“下一次我准备怎么验证?”

那么这次失败就开始产生:

数据。

数据经过分析,变成认知。

认知经过行动,变成新的能力。

新的能力再进入下一次实践。

这才是真正的:

失败 → 复盘 → 重构 → 迭代。

40岁以后,我越来越觉得:

我们没有办法保证自己以后不犯错。

也没有办法保证每一次选择都正确。

真正能够建立的,是另外一种能力:

出错以后,能够快速恢复;失败以后,能够认真复盘;发现问题以后,能够修改自己的系统。

所以以后再遇到失败,我希望自己少问一句:

“我怎么这么差?”

多问一句:

“这次事故,究竟暴露了我的哪个系统问题?”

然后把它写下来。

不是为了惩罚过去的自己。

而是为了:

让未来的自己少踩一次同样的坑。

我是语霖。

执笔为语,心落成霖。

记录一个40岁程序员重新设计人生系统的过程。

我越来越相信:

人生真正的稳定,不是永远不出Bug。

而是:

每一次Bug发生以后,我们都有能力把它变成下一版系统的代码。


分享这篇文章:

上一篇
如何为自己的核心能力做压力测试
下一篇
如何设计属于自己的「熔断机制」,避免情绪或工作过载