逻辑先行:90%程序员忽略的三大编码铁律
|
去年双十一,老周在IDC机房蹲了三十七小时,最后那会儿他蹲在冷通道里啃包子,铝箔纸没撕干净,一咬半张黏在下嘴唇上。我原以为是流量压垮了服务,结果查到半夜三点,发现是订单超时逻辑写在重试之后——重试都跑完了才判超时,判完直接扔进死信队列,连日志都懒得打。你猜怎么着?这个逻辑上线前走的是“快速发布流程”,评审记录里写着“业务方确认OK”。OK?OK个锤子。那个“确认”的人当天下午还在我工位旁边接了个电话,说他闺女发烧三十九度二,挂完号就跑,工牌都没摘全,卡在门禁那儿“嘀”了一声又退回来取。 第一铁律:状态变更永远早于副作用触发。去年六月我就栽在这条上。不是测试没过,是测试用例压根没覆盖“用户取消订单但退款服务已开始异步调用”的竞态。我们写了十七行补偿逻辑,结果主干里一行“if (order.isCanceled()) return;”插在调用退款SDK之前——看起来天衣无缝,直到支付网关切了新路由,延迟从八百毫秒抖动到两千三百毫秒。那一刻我盯着Kibana看实时流,嘴里含着最后一口冰美式,咖啡渣子硌牙。我敢打包票:那行return前面缺个CAS锁或者version字段校验。但当时谁看?没人看。连我自己都以为“这不可能并发”——直到DBA甩来一张死锁图,三张表,六个事务,其中两个还是同一个用户ID。 第二铁律:分支判断必须穷尽所有可达路径,哪怕它“理论上不会发生”。上周二下午四点零七分,运维小陈冲进开放区喊“对账单崩了”,手里拎着台刚摔过的笔记本,键盘盖裂了条缝,按F12时右下角按键一直卡住。我扫了一眼代码——switch里default分支写着//TODO,底下空着。上面五个case全是有业务含义的,唯独漏了上游传来的字符串“NULL”(注意引号,不是null)。它来自一个三年前下线的老渠道,中间经过三次数据迁移、两次协议转换,最后在redis里存成JSON串时把双引号吞了,变成真正的NULL字面量。可没人删掉那条注释。现在它炸了。我一边改,一边听见隔壁组在吵灰度比例,声音很大,像有人在拍白板。 第三铁律:任何依赖外部系统的调用,其失败路径必须能回滚到一个确定、可验证、无副作用的状态。这条最虚——虚到连我都不好意思提。前天我翻自己三年前写的登录模块,居然发现一处用了try-catch包裹整个token刷新+缓存写入+消息推送,catch里只打了一行error日志,然后return false。错在哪?错在return false之后,前端还在用旧token续请求,而Redis里的token其实已经过期——但缓存key没删,值是空字符串,ttl还剩十四分钟。这个bug活了四百零三天,没人报。直到上周五财务部导出报表时突然卡在“获取用户偏好”接口,堆栈末尾赫然挂着那次refreshToken()里的NullPointerException。你说气不气?气。但我改的时候手抖了,把cache.remove(key)挪到了catch外面,又忘了加else——于是无论成功失败,缓存全清了。这事儿我没敢告诉老周,怕他把我那盒没拆封的薄荷糖顺走。
文章配图,仅供参考 说到薄荷糖……昨天保洁阿姨擦我显示器边框,抹布蹭过右上角,带下一块干涸的咖啡渍,像地图上某块未命名的飞地。她没说话,只是抬眼看了看我,又低头继续擦。我盯着那块渍看了八秒,忽然想起2025年6月那个凌晨——我们上线前最后一轮压测,监控面板上QPS曲线平滑得像PPT做的假图,大家击掌,行政买了西瓜,切片后撒了薄盐,籽被挑得一颗不剩。结果凌晨两点十七分,首笔“积分抵扣满减券”订单生成失败,错误码是-9997,查文档写着“系统保留,非业务错误”。没人知道为啥。后来查源码才发现,那个错误码出自一段被git ignore掉的本地调试代码,就藏在utils包里一个叫LogHelper.java的文件里——它根本没进编译。可它在运行时生效了。因为classloader碰巧加载了某个test-jar里的同名类。这件事我说不准是不是配置问题,反正我那天凌晨三点换的Nginx upstream权重,手一滑把backup节点设成了primary,而那个backup机器的JVM参数里Xmx比别人小三百七十二兆。 所以啊,逻辑先行真不是口号。是当你写完if-else闭上眼,脑子里能浮现出那三条路径分别打在哪个表的哪条记录上,哪个字段变,哪个字段不动,哪个日志在哪个磁盘的第几块扇区里等着被tail -f。而不是等告警电话响了再翻Git blame。现在我把所有新建分支都强制要求提交前跑check-logic.sh——脚本是我写的,只做三件事:检查所有if里有没有else;检查所有switch有没有default且非空;检查所有@FeignClient方法有没有对应fallback。别的不管。它报错我就改,不解释,不争论。老周说这脚本傻,我说对,就得傻。聪明人容易忘,傻东西才记得住。至于那个NULL字面量……我已经让小陈把下游所有渠道的原始日志归档路径抄给我了。今晚回去,先把三年前的数据拉出来看看,到底还有多少个“NULL”在黑箱里呼吸。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


14年程序员亲测:运营中心服务器响应提速40%,操作零等待
14年程序员忠告:代码即文档,逻辑清晰规范至上
DBA视角:程序员必追的数据库技术周报
VR电商:从看商品到进商品的14年程序员洞察

