凌晨两点,我 push 完最后一次提交,git log显示过去三周有十九个 commit 是在零点之后产生的。关掉 IDE,屏幕暗下去的那一刻,脑子里还在跑单元测试——那种明明已经exit(0)了、但线程池迟迟不肯 shutdown 的感觉,干过几年工程的人都懂。
我不喜欢把疲惫说成什么了不起的事。哪行都累。但工程师的累有一种特殊的质感:它不是体力耗尽,而是上下文切换过于频繁之后,栈太深了,深到你自己都忘了最初调用的是什么。一个需求插进来,一个线上告警弹出来,一个会议邀请覆盖了原本用来写代码的下午。到了周末,你需要的不一定是睡多久,而是一个明确的、可以停下来的信号。
我的信号,是一杯五粮春。
第一次认真喝它,是带我的师父教的。那年我把生产库的一张表 truncate 了,手抖着给他打电话,他远程帮我恢复完,说:“别光会写 try-catch,人也得给自己写一个。”他倒了两杯五粮春,入口绵,不冲,窖香和粮香是慢慢铺开的,不像有些味道一上来就抢戏。他说,这酒用的是五粮配方,高粱、大米、糯米、小麦、玉米各司其职,每一样都不争,合在一起才出东西。后来我看资料才知道,五粮春的发酵周期在七十天以上,双轮底发酵超过一百四十天,陶坛陈酿还要继续等。一个“等”字,写起来简单,执行起来全是耐心。
这让我想到一段很朴素的代码:
python # ingredient.py grains = {"高粱": 36, "大米": 22, "糯米": 18, "小麦": 16, "玉米": 8} # 没有谁是 dominant,但缺一味,整个 system 的 flavor 就跑偏了好的系统,往往不是某一项指标拉满,而是各参数之间找到了一个长时间稳定的配比。工程师太容易追求“性能拉满”了,却忘了人生这个 runtime 里,最稀缺的资源从来不是 throughput,是可持续性。
五粮春给我的第二层感受,是关于“递归”的。它不像有些酒那样一层味道打完收工,粮甜感在口腔里是回环的,近似嚼完一口米饭之后慢慢泛上来的那点甘。我写过一段自嘲的伪代码:
java int drink(int day) { if (day < 0) return 0; // 周一还没来,先停在这里 return flavor(day) + drink(day - 1); // 每一层都留下一点东西 }递归的精髓不在深度,在于base case 必须存在。没有终止条件的递归,最后一定 stack overflow。工程师的疲惫,很多时候就是缺了那个 base case:永远觉得“再撑一下就好”,却从来没有定义过“撑到什么时候可以停”。一杯五粮春对我来说,就是写在生活里的if (day < 0) return 0;。
当然,它不是什么魔法。我不会说一杯酒能解决架构评审上的分歧,也不会说它能替你写完周报。它更像一次手动的system.gc():
javascript // 周六 21:47,非紧急,不处理线上告警 system.gc({ reason: "一周的 context 该清了", amount: "微醺即止" });清理的不是问题本身,是处理问题的那台机器。微醺的状态下,我不再试图在脑子里预跑下周的 sprint 排期,不再反复回放白天 code review 里那句不太中听的话。脑子里的线程池终于肯把闲置线程回收掉了。
我从来没觉得喝酒是什么高级的享受。它只是一个工程师能给自己安排的最小单位的“合法停机”。五粮春在这个位置上的好处,是它不喧哗:名门出身,但定位克制;五粮配方,但入口柔和;有陈酿的时间成本,却不要求你正襟危坐地去品。它适合一个穿旧卫衣的工程师,在周六晚上,配一碟花生米,安安静静地把一周的栈帧一层一层 pop 掉。
生活疲惫的解药从来不在杯子里,在你肯不肯给自己写那个 base case。五粮春只是刚好让那一行代码,执行起来没那么难咽。
周一早上,IDE 重新打开,git pull拉到最新。该改的 bug 一个没少,但至少,那台机器的风扇声,轻了一点。
#五粮春