代码写了十年,我给自己报了个生活补课班

上上个周末,我家洗衣机突然开始发出一种像是有人在里面摇骰子的声音。

要搁以前,我的第一反应是打开购物软件,直接换一台新的。但那天不知道哪根筋搭错了,我蹲下来看了看它,心想:不就是异响吗,我又不是没排查过线上故障。

于是那个周末,我人生第一次拆开了洗衣机。

人生第一次拆洗衣机:排查很顺利,拧螺丝很狼狈

# 排查问题我会,拧螺丝我是真的菜

故事的结局先说:堵住排水泵的,是一枚发卡。外加两枚硬币和一团不明黑色织物。

排查过程其实很顺利。异响只在排水的时候出现,那大概率是排水泵;排水泵在洗衣机前下方,拆开面板就能看到。这套「根据现象缩小范围」的思路,跟我在生产环境里追一个偶发 bug 没有任何区别——看日志、二分、定位、验证。我甚至下意识地在心里给每一步打了个「假设:排水泵有异物」的标记。

但一上手,我就露馅了。

面板上有四颗螺丝。我找了一圈家里的工具,只找到一把随某个家电附赠的、型号不知道匹不匹配的螺丝刀。拧第一颗的时候还行,拧第二颗的时候滑了一次丝,拧到第三颗,我的手心已经开始出汗。四颗螺丝,我拧了十分钟。一个在代码里把「一切皆可自动化」当信仰的人,被四颗物理螺丝按在地板上摩擦。

那一刻我意识到一件事:我排查问题的能力是十年工作练出来的,但我动手的能力,可能还停留在普通用户的水平。我的工具箱,比我的 IDE 寒酸多了。

我的工具箱,和 IDE 摆在一起确实有点寒酸

# 生活里没有 npm install

后来我开始留意这种落差,发现不止是修东西。

比如做饭。我做饭的水平长期停留在「能熟」这一档,因为在我原来的世界观里,做饭是个效率问题:填饱肚子,消耗最少的注意力和时间。外卖出现之后,这个问题被彻底外包了。

直到有一次朋友要来家里吃饭,我决定认真做一次红烧肉。我照着菜谱一步步来。菜谱写得很清楚,像一份文档:焯水、炒糖色、小火四十分钟。但我很快就发现了菜谱这份「文档」和真正的技术文档的区别——它不告诉你参数的边界条件。「小火」是多小的火?我家灶拧到第几格才算小火?「炒糖色到枣红色」,枣红色和炒糊之间隔几秒?

菜谱默认你有一些我没学过的先验知识。就像一份假设你读过整个项目历史的代码,注释写得再好,落到没上过手的人身上,还是步步惊心。那天那锅红烧肉,糖色糊了半锅,最后靠加水和糖硬救回来。朋友很给面子地说好吃,我自己心里清楚,那是幸存者偏差。

灶台上小火慢炖的那锅红烧肉,糖色炒糊过一次

# 代码思维能迁移一半

有意思的是,也不是所有东西都要从零学。那个周末之后我大概盘了一下,程序员的职业病里,有一部分在生活里其实特别好使:

  • 排查思维。异响、漏水、灯不亮,任何「现象」都可以当成日志来读。先缩小范围再动手,能省一半力气。
  • 读手册的习惯。我以前修东西全靠瞎拧,现在会先花十分钟把说明书翻到故障排查那一页。大部分家电的说明书里真的写了,就是没人看。
  • 「先备份再动手」。拆之前拍照,记下每颗螺丝的位置。这条习惯救了我至少两次。

但另一部分,是真迁移不过去的。

比如「手感」。螺丝拧到什么程度算紧而不滑丝,糖色炒到什么颜色算刚好,面揉到什么程度算醒好了——这些东西没有报错信息,没有类型标注,没有一个 CI 会跑过来说你失败了。它们只存在于你的手上,只能靠一次次做错来校准。

我把这类东西叫做「具身知识」。写代码十年,我攒了一脑袋的抽象知识,但具身知识几乎是零。而生活恰恰是由具身知识撑着的:火候、手感、分寸。这些东西买不来,搜索不来,AI 也替你练不了。

# 修好那一刻,跟 debug 通了是一样的

洗衣机修好之后,我把它推回原位,插上电,按下启动键。滚筒转起来,安安静静。那枚发卡现在躺在我的工具箱里当纪念品。

那个瞬间的爽感,我非常熟悉——就是 debug 到凌晨,突然发现那个 off-by-one 的瞬间。现象消失,假设验证,世界恢复秩序。一模一样的多巴胺,而且不用写复盘,不用排期,没有 oncall。

我不觉得这是什么「程序员必须学生活技能」的大道理。我只是发现,以前我把生活里的问题都当成了干扰项:漏水了找人修,吃饭点外卖,坏了就换新。我以为这叫效率,其实是我把自己的生活一点点外包了出去,外包到我自己的手越来越笨。

现在我给自己定了个小规矩:生活里坏掉的小东西,先试着修,修不好再买。上个月修好了洗衣机,这个月换掉了卫生间的密封条,下周打算挑战那把从搬进来就晃悠的椅子。

傍晚窗台上的一杯茶,世界恢复秩序

代码写了十年,是时候补一补生活这门课了。学费是四颗螺丝、半锅糖色,和一把拧秃了的螺丝刀。不贵。