把自己走回来 书架

第 01 章 / 共 16 章

第1章 · 崩溃报告:一个被优化了二十年的系统宕机了

那天下午三点十七分

我记得那个时间,是因为我一直有记时间的习惯。会议纪要要记时间,线上事故要记时间,连吵架我都会下意识看一眼时钟——好像只要打上时间戳,混乱就能变成一条可追溯的日志。

三点十七分,HR 把一份文件推到我面前,桌上那杯美式还冒着热气。她说了些话,我大部分没进脑子,只捕捉到几个词:架构调整、感谢贡献、N+1。窗外是陆家嘴,三栋亮闪闪的大楼像三个巨型主机箱杵在黄浦江边,我在其中一栋里坐了整整八年。玻璃幕墙反着六月的太阳,晃得我睁不开眼。

我四十一岁。从二十岁出头写第一行代码算起,我在这套叫"职业"的系统里跑了将近二十年。而它,在一个再普通不过的周三下午,宕机了。

奇怪的是,我没哭,也没怒。我做的第一件事,是打开手机备忘录,新建了一条,标题打上:故障复盘。手指是自己动的。二十年了,一出事就写复盘报告,这是刻进肌肉里的反射,跟膝跳一样,你拦不住。

像读一份线上事故报告一样读自己

做技术的人,遇到系统挂了,有一套固定的动作。先不慌,先定位:哪个模块崩的?是它自己坏的,还是被别人拖死的?影响面多大?有没有兜底?能不能回滚?我们管这个叫复盘,说白了就是——不急着修,先把事情想清楚是怎么发生的。

那天晚上,我回到浦东那间租了六年的公寓,泡面都没泡,就坐在飘窗上,认认真真地给自己写起了这份报告。

写着写着,一个词跳了出来,是我平时排查线上问题最怕见到的那个词:单点故障

单点故障,说人话就是:一个系统里,有那么一个零件,它一旦坏了,整个系统就全瘫了,没有任何替补能顶上。稳当的系统都会留后手——一台服务器挂了,还有另一台一模一样的立刻接管,用户根本感觉不到。留这种"看起来多余的备份",行话叫冗余。没有冗余的地方,就是那个要命的单点。

我盯着"单点故障"这四个字,后背有点发凉。因为我忽然看清了:我自己,就是一个没有任何冗余的系统。

我的收入,单点——只有一份工资。我的社交,单点——通讯录翻到底,除了同事就是前同事,能在周三晚上打过去说说话的人,一个都想不出来。我的价值感,单点——全押在"我是个好工程师"这一件事上。我的时间,过去八年几乎百分之百投给了这家公司,没有第二个入口,没有 B 计划,没有那台随时能顶上来的备用服务器。

我用一整套追求高可用的思维去搭系统,给公司的服务设计了三副本、异地容灾、自动切换,唯独把自己这台机器,跑成了全公司架构里最脆弱的单点。它一挂,没有任何东西接得住。

为什么我会把自己跑成这样

这就要说到第二个词了。它比单点故障更让我难受,因为单点是外部条件,而这个,是我亲手把自己训练成的样子。

这个词叫 过拟合

过拟合是机器学习里的毛病。你拿一堆题去训练一个模型,训着训着,它把每道练习题的答案都背得滚瓜烂熟,考试分数高得吓人。可一旦换一批没见过的新题,它就傻了、全错。为什么?因为它没在学"规律",它在死记这一批特定的题目。它对训练它的那个环境,贴合得太紧、太严丝合缝了,紧到离开那个环境就完全失灵。

我就是一个被这家公司、这个岗位过拟合了二十年的模型。

我太懂这里的一切了。我知道这套祖传代码里哪一行不能碰,知道哪个接口的返回值有个历史遗留的坑,知道半夜三点报警该找谁、哪个领导的邮件必须几点前回。这些本事,让我在这套环境里效率极高、如鱼得水,KPI 年年拿 A。

可这些本事,几乎全是针对"这一家公司"死记下来的答案。它们没有教会我任何可以迁移的、更普遍的东西。就像那个把练习题背烂了的模型——分数越高,越说明我把自己贴着这个岗位磨得越紧,紧到一旦这个岗位没了,我这个"高分模型"面对外面的世界,可能连一道新题都不会做。

公司越是稳定、待遇越是好,我就越是心安理得地往里钻,越是懒得留后手。所谓稳定,原来是麻醉剂。它让过拟合看起来像是精通,让没有冗余看起来像是忠诚。

这不是能靠加班回滚的 bug

凌晨两点,报告写了两千多字。写到最后,我习惯性地要给这次事故写"处理方案"——技术复盘的最后一栏永远是这个:根因是什么,怎么修,怎么防止再犯。

我在那一栏敲下了几个字,又删掉。再敲,再删。

因为我意识到,我下意识想写的方案,全是同一个套路:回滚

回滚,是程序员的救命稻草。新版本上线出问题了?别慌,一键切回上一个好用的旧版本,几分钟就恢复正常,好像什么都没发生过。它的前提是:曾经有一个"正确的状态",你只要退回去就行。

我这二十年,遇到任何危机,方案永远是回滚加打补丁:项目要黄了,我加班顶上去,回滚到"还行"的状态;身体亮红灯了,我吃点药扛过去,回滚到"还能跑"的状态;生活出现任何一点不对劲,我的第一反应都是——更努力一点,更自律一点,把它拉回到那个熟悉的、可控的旧版本里去。

我一直以为,人生里没有什么是一场高质量加班解决不了的。如果有,那就两场。

可这一次不一样。这一次没有"上一个好用的版本"可以退回去。不是我 KPI 没拿到,不是我技术不够硬——恰恰相反,正是我把自己优化得太好、贴合得太紧,才落到今天这一步。问题出在整套系统的设计上,而不是某一次运行的失误上。这种事,你回滚不了,加班也加不回来。你退回到昨天,昨天的你依然是个没有冗余、严重过拟合的单点——只是那时候你还不知道而已。

那一刻我承认了一件让我很不舒服的事:这不是一个 bug。bug 是"本该正常,偶然出了岔子"。而我这个,是"一直这样跑,早晚要出这个岔子"。它不是异常,它是宿命,是这套架构必然的输出。

承认这一点,比被裁员本身还难受。被裁,我可以怪大环境、怪调整、怪运气。可承认自己是被自己亲手设计成这样的——这个复盘,写不出一个能让我睡着觉的"处理方案"。

天快亮的时候,我把那份报告最后一栏空着,关了手机。窗外的陆家嘴还没亮灯,江水黑沉沉地流,不快也不慢。我第一次发现,我居然不知道这条江往哪个方向流。在这住了六年,我竟从没问过。

我不知道下一步该干什么。这种"不知道",对一个习惯了万事都有排期、有方案、有确定答案的人来说,简直像另一种宕机。但那天凌晨,我至少想明白了一件小事:我要修的,不是让这套旧系统重新跑起来。旧系统跑得越顺,我离下一次宕机就越近。

我得换台机器。或者说,我得先离开这个机房,去外面那个我过拟合了二十年、却几乎一无所知的真实世界里,走一走。

三天后,我退了房,把西装、笔记本电脑和那份没写完的复盘报告,一起锁进了储物间。然后我背上一个包,站在了上海的西边——那是我印象里,一条能一直往西、一直走向云南的方向。

把自己走回来 · 微一
面向对世界有好奇心的人 · 费曼式写法 · 由多个 AI 代理撰写与互相审校