前几年有一次半夜上线业务方在群里连环日志一行一行刷过去我盯着屏幕忽然走神了如果有一天这套系统、这份工作、这台笔记本都不在了我手里还剩什么真正值钱的东西这个问题没有当场答案但我后来想了很久断断续续想明白了一些。写这篇东西是想把那些想法整理出来。它不是一个纯技术的教程更像是一个老程序员在重构了无数代码之后回头重构自己人生逻辑的过程。如果你也正在天天写CRUD、感觉自己不值钱的焦虑里打转这篇东西应该能给你一些不一样的坐标。1. 值钱的不是代码是需求先说一个我踩过的坑。前年我接手一个内部老系统大概跑了十年技术栈旧得离谱文档约等于没有业务方也换了好几茬。我一开始以为这系统最大的问题是技术老化于是兴冲冲地列了一堆重构计划准备大干一场。结果跟业务方聊了三次之后我整个人都不好了——这套系统真正支撑的需求早在五年前就已经不存在了。当时的业务方负责人自己都说不清楚某些页面是干嘛的只知道老领导在的时候就有数据库不能动动了怕出事。于是系统就这么一直跑着每个月花着云资源费用每次发版都要小心翼翼的像供着一个没人知道原理的老祖宗。那一刻我意识到一个特别扎心的道理代码本身没有值钱不值钱的问题需求才有。一个需求如果还成立哪怕下面的代码丑得没法看它每天也在产生价值一个需求如果已经消亡了代码写得再优雅、再干净也只是负债——它吃你的维护成本吃你的注意力吃团队的心智。从那以后我接任何系统、做任何方案第一件事永远是问一句这个需求还成立吗它为谁解决问题解决的是真问题还是大家习惯了所以觉得应该存在的问题搞清楚了再谈技术选型。这个顺序一旦反了后面全是白忙。这几年我带团队面试新人特别喜欢问一个问题你上一个项目的核心价值是什么你能说清楚自己用了什么框架、写了多少接口、解决了什么技术难点但很少有人能一句话说出这个模块为谁、解决了什么问题、省了多少钱或者多少时间。大部分人的反应是愣一下然后开始讲功能清单。这不是表达问题是需求感的缺失。我后来跟团队讲过一个很极端的例子。某次做报表需求产品经理提了一堆筛选条件、图表类型、导出格式前前后后排期三个月。开发做完了上线两周后台看埋点数据使用量几乎为零。后来回访才发现业务方真正想要的只是每天下午五点自动收到一封昨日数据的邮件他们甚至没时间打开系统去看那些炫酷的图表。需求感强的人第一反应应该是问为什么需要筛选谁在用他拿到这个数据之后要做什么决定问到最后答案可能就是一个定时邮件加一张Excel。三个月的工作量压到三天就能交付。这就是真需求和伪需求的差别。这个道理放到人生维度上其实一样成立。人这一辈子最值钱的不是你掌握多少技能、写了多少行代码、攒了多少年的工龄而是你能不能持续分清自己真正需要的东西是什么那些被社会、被焦虑、被别人的眼光塞进来的需求哪些是伪需求。我们会把想要误当成需要。想要更大的房子是因为觉得别人都有了想要更高的职级是因为怕自己掉队想要更多收入是因为被消费主义植入了一个钱永远不够的脚本。这些需求的共同特点是满足一个马上冒出下一个永远填不满。真需求长什么样它一般能回答得更朴素——这件事做了我的能力边界是不是扩大了我的身体和精神状态是不是变好了我身边的人是不是也变好了答案如果是肯定的那你是在满足真需求如果只是缓解了当下某种焦虑那你大概率是在给伪需求打工。所以我现在的答案第一层是值钱的核心不在做什么而在判断哪个需求值得投入的能力。这个能力恰恰也是我后来重构代码之外最先想重构的东西。2. 一个具体的重构案例十年老项目重写的取舍空谈道理没用拿一个真实做过的项目拆给你看。某个内部系统X是一个记账改成了订单管理又改成数据中台的老系统前后被三拨人改过代码里什么风格都有。它有一个最痛的点订单状态流转里被历任开发塞了十多个if补丁什么老客户专享赠送某渠道优惠券过期不发赠送后端重推时必须跳过状态快照各种逻辑纠缠在一起。新人看了直接想跑路老人也不敢乱碰。所有人都觉得该重写了。但这个系统每天有几百个运营在点说实话是当时公司的吃饭工具停一秒钟都有人嗷嗷叫。所以我们当时做了一个看起来反直觉的决定不重写做渐进式重构。2.1 为什么该重写却不能重写我把决策过程摊开来说。想推倒重写的人理由都很正当代码烂、耦合深、测试没有、技术旧。但这些理由有一个共同前提——你能完整地预知这个系统在真实世界里的所有行为。现实是这个系统跑了十年积累了大量边界行为散落在代码里、甚至散落在资深运营的脑子里。比如一个订单如果同时命中两个优惠活动到底给哪个优惠客户改过一次地址之后物流单上为什么还显示旧地址某一步点快了会触发重复提交但系统居然能自我修复。这些行为没有文档没有测试用例它们就像老员工脑子里的隐知识你问十个新人九个没听过。重写一个这样的系统相当于在废弃老发动机之前先把满地图的暗礁全部标出来。做不到这一点所谓重写就是重新踩一遍十年埋下的雷。当时我们评估了一下全量重写保守估计要四个全职加三个月的周期而且上线之后还得经历漫长的行为对齐期中间业务还不能停。而渐进式重构可以先挑最痛的模块动刀每一刀都能拆开看、能回滚、能被验证。当然这里面有个很重要的前提团队得有那么几个人能同时看懂老代码和愿意接受新架构。如果没有这个人渐进式重构也会变成改了个寂寞。2.2 重构时我留下的东西和扔掉的东西这次重构里我们做了一件当时看起来很笨的事花三周时间把老系统的所有已知行为整理成了一张行为清单。清单长这样业务行为老逻辑现状重构后逻辑对应测试用例用户重复提交订单数据库唯一索引代码幂等判断偶尔报错但不丢单保留幂等统一异常提示OrderSubmitIdempotentTest库存超卖兜底冻结库存异步扣减超卖时发告警邮件保持扣减顺序优化锁粒度StockOverSaleGuardTest优惠券过期提醒每天凌晨定时任务扫一次次日站内信改为事件触发定时补偿CouponExpireNotifyTest现在看会觉得很简单但在当时光是确认这些行为是不是正确的就废了无数口舌。很多逻辑连现任业务方都不知道为什么存在我们只能一个一个去对历史邮件、对工单记录、找老同事打电话最后把已知行为全部收敛成测试用例作为重构的验收底线。做完这件事之后重构反而变得轻松了我们不是用新代码重写老代码而是用新代码去满足一份明确的行为契约。重构时我们扔掉了什么扔掉了大量路径依赖式的复杂度。比如早期对接的一个旧支付渠道已经三年没有订单走那个渠道了但代码里还有完整的回调处理逻辑比如一个只在某次活动里用过一次的老会员等级判断分支一直没删。这些就是代码世界里的沉没成本不是因为还有用而存在而是因为没人敢删所以一直在。删掉这些死分支之后接口返回时间直接快了一半真让人哭笑不得。2.3 一个可迁移的价值公式那次重构复盘时我给团队写了个公式价值 行为正确性 × 未来维护效率 ÷ 复杂度行为正确性是基础东西能用、行为对价值才能为正。维护效率取决于结构清不清楚、文档有没有、新人上手的坡度缓不缓。复杂度是分母每多一个没人理解的历史分支每多一处业务规则的重叠都会把整体价值往下拉。这个公式放在代码上成立放在人身上也成立。一个人的总分不是技能堆出来的加法和而是一个类似的结构价值 解决真实问题的能力 × 持续学习的能力 ÷ 内在复杂度。内在复杂度是什么就是那些让你同时忙很多事、却每件事都做不透的焦虑是明知道某段关系在消耗你还不敢结束的犹豫是熬夜透支健康攒下来的疲惫。这些东西不清理你能力再强总分的分母太大最后也输出不了多少有效价值。那次重构给我最大的改变不是把系统改快了、改稳了而是它给了我一个思考框架任何一次改动之前先想想你是在增加分子的能力还是在减少分母的复杂度。两件事都值得做但后者常常被我们忽略。3. 关于积累我以为的和我现在信的3.1 二十多岁时以为的积累刚入行那会儿我对积累的理解特别朴素会的越多越值钱。于是我跟集邮似的学东西。今天看到某新框架火了赶紧学明天看到别人在考证也报名GitHub上收藏了上百个必学清单收藏完就再也没打开过。简历上的技术栈越写越长真正能说清楚在什么场景解决过什么问题的一只手数得过来。我有个同期入职的同事老K比我更极致。他的业余时间基本全在追新语言、新框架、新架构誓要做技术前沿的弄潮儿。他确实懂得多前几年业内什么新词他都能接上话。但时间一长问题就出来了他什么项目都沾一点没有哪个是深度扎进去做透的。有一次我们内部做一个高并发模块要一个能把存储方案讲透的人他反而讲不到底层因为他一直在追新东西没时间沉淀那块地基。后来组织调整我们那个小组被拆了一部分老K首当其冲。我后来跟他吃饭他说了句让我印象很深的话我一直在给简历打工忘了给自己打工。我听懂了。他那些积累实质上是资产吗更像是库存。东西堆了很多但没有形成能持续产出的生产线。3.2 十年后我重新排序的积累清单三十岁以后特别是经历了几个项目延期、带团队踩坑、身体报警之后我把积累这件事重新排了个序。这个排序不是我拍脑袋写的是从一次次试错里拎出来的。按抗贬值的程度排第一等判断力。知道什么该做、什么不该做什么值得坚持、什么需要放弃。这玩意儿别人拿不走也最难速成。第二等信誉。包括技术信誉和人际信誉。你说的话大家信不信你承诺的事能不能交付你在关键时刻靠不靠得住。这是最硬通货的社交货币。第三等健康的身体和稳定的情绪。没有这两样前面的判断力和信誉都是空中楼阁。身体垮一次你可能要拿三年去还债。第四等通用的底层能力。表达、复盘、抽象建模、把复杂事情讲简单、带人的能力。这些跨项目、跨行业都能迁移。第五等具体的技能。语言、框架、工具、平台。这些会过时但它们是前面几等的载体缺了它们你也没法干活。这个排序最反直觉的地方是它跟简历好不好看的顺序几乎是反的。简历最容易写的是第五等最难写的是第一等。但越到后面你越会发现市场上真正稀缺的不是谁会某种冷门技术而是谁能判断我们该不该用某种技术。积累不是往仓库里堆更多东西而是把一堆零散的零件组装成一个能运转的系统。系统运转久了会长出流程、长出经验、长出信任这些才是真正的复利。4. 慢下来以后我把值钱的标准重写了一遍4.1 代码里的慢即是快与我人生的慢写代码这么多年我发现一个特别有意思的规律线上事故很少发生在慢慢来的时候几乎都发生在赶工的时候。代码写得急了逻辑就不清楚测试就不敢写发布就跟赌博似的赌它今天不出问题。某次重构系统X的时候我们把发布节奏从每周一次改成两周一次重要模块上线前强制在压测环境跑满三天还要过了行为清单上的全部用例才允许灰度。表面上看整个团队的交付速度慢了但那个季度的事故数反而降到了历史最低。业务方也不再抱怨你们怎么又挂了他们甚至会主动问这次改动稳不稳我们那边要不要配合降量。人其实也一样。我一直觉得自己应该跑得比周围人快后来发现很多问题恰恰是慢下来才看得见的。你整天忙得脚不沾地的时候根本不会去想我这件事为什么要做你只会想赶紧做完交差。而那些真正能改变轨迹的决定——要不要换个方向、要不要停掉某个项目、要不要跟某个人深聊一次——几乎都是在没那么多事的时候才会浮上来的。我现在会刻意给自己留一些看似浪费的时间每天午后十五分钟什么都不干就想想今天最重要的一件事是什么、明天最重要的一件事是什么每周留半天空挡不接新需求专门清理上周的技术债和情绪债。这些时间不直接产出代码、不直接回复消息但它们像代码里的定期重构——短期看是开销长期看是在给未来的自己省时间。4.2 人生里的开源节流减掉没必要的复杂度代码系统里有一套经典的优化手段死代码清理、接口收敛、依赖最小化、配置集中化。以前我只把这套东西用在技术上后来发现它也是一套非常好用的人生方法论。所谓死代码清理对应到生活里就是取消那些有它不多没它不少的社交退出那些不知道当初为什么要进的群停掉那些别人都在做所以我也想做的计划。我前年清点了一下自己加了上百个技术交流群真正会点开看的不超过五个剩下全是数字噪音。退了之后微信清爽了注意力也回来了。接口收敛对应的是尽量少开新的承诺接口。能不答应的事就不答应能合并解决的需求就不单独开会。我见过很多人活得累本质上是给自己开了太多并发的接口每个接口都要维护每个承诺都要兑现最后CPU全被占用真正重要的进程没有资源跑。依赖最小化对应的是少依赖外部评价。以前我很在意别人怎么看我绩效出来了要焦虑朋友圈点赞少了要失落。后来想明白你的运行不应该依赖一个不可控的外部服务你自己的评价体系才应该是本地优先、离线可用。开源节流落到实处我给自己建了一张人生时间预算表方法很简单每周168个小时先扣掉睡眠、通勤、吃饭这些硬支出剩下的可支配时间里给重要不紧急的事阅读、运动、复盘、陪家人预留固定的额度然后再去分配那些紧急但不重要的琐事。如果这周琐事挤占了重要额度下周就做减法把一些会砍掉别让它们回来。这套东西本质上就是代码里的资源调度给核心进程留足资源及时终止那些消耗大、回报低的野进程。5. 如果非要一个答案我的源码是这样写的5.1 一个老程序员现在的日常配置很多人问我说你想清楚了之后现在的一天是怎么过的我现在的时间大致分成三块三分之一给团队和业务三分之一留给写作、复盘和一些带人的事另外三分之一雷打不动地给睡眠和运动。这个配置听起来一点也不奋斗但我知道它就是我目前能稳定运行、长期不出事故的最优参数。我给自己设了几个监控指标跟看系统一样睡眠时长、静息心率、对一件事能连续专注的时间。这三个指标只要不出告警我心里就有底一旦哪个亮了红灯我就知道该降载了。也给自己留了降级预案忙到实在顶不住的时候第一刀砍无效会议第二刀砍不必要的社交最后一刀宁可砍掉一个新项目的排期也不能砍掉睡觉。为什么因为睡觉和休息是我的核心路径核心路径一崩全链路都崩。5.2 最后想对年轻时的自己说的话如果我能回到刚入行那一天我会对自己说几句话别急着把简历写满先把手头这件事做到行为正确——你先搞清楚这个需求到底为谁解决什么问题再谈用什么框架。多问几个为什么少收藏几个必学清单。收藏夹里的东西不会变成能力做完、复盘、教会别人才会。把每一个新计划都当成人生代码里的一个分支提交。合入之前先检查它对核心路径是不是必需的如果不是必需再潮、再流行、别人再说好也不要合进去。人这一辈子说短不短说长不长。最值钱的不是某个技能、某段履历甚至不是某个亮眼的头衔而是你内心那套稳定运行的判定逻辑——知道什么真正重要什么不重要并且敢为重要的事留出足够的时间。代码可以重构人生也可以。重写的过程往往很慢甚至显得低效但没关系。别停就行。