从DBA到后端:我如何放下代码洁癖,拥抱工程现实
上周五晚上十点半,成都的夜雨刚停,办公室只剩我和隔壁组的测试小哥。他一脸疲惫地跑过来:“哥,你那个接口又超时了,线上用户刷不出订单。” 我心头一紧——这接口是我重构过的,自认为“干净优雅”,结果在双11压测峰值下直接崩了。
那一刻,我坐在工位上盯着屏幕,脑子里全是大学时期导师那句:“数据库不是艺术品,是工具。” 当年我嗤之以鼻,觉得那是对美的亵渎。如今,作为一名从DBA转岗做后端开发的老程序员,我终于明白了这句话的分量。
一、我的“洁癖”是怎么养成的?
我是典型的DBA出身。早年在一家金融公司干SQL调优,整天跟执行计划、索引碎片、锁等待打交道。那段日子让我养成了近乎强迫症的“整洁”标准:
- 表名必须全小写+下划线
- 每个字段都要有注释
- JOIN不能超过三层
- 存储过程?不存在的,能用视图解决的绝不写逻辑
后来转做后端,我把这套“美学”带到了Java和Go代码里:
- 方法体超过20行?拆!
- 变量命名不语义化?重写!
- 魔法数字?必须抽成常量!
团队新来的实习生私下叫我“格式警察”。产品经理每次提需求都小心翼翼:“这次加个字段……应该不用改太多吧?” 其实他们不知道,我光是为了把一个DTO字段从userId改成user_id,就能花两小时重构上下游三个微服务。
听起来很专业?但现实狠狠打了脸。
二、现实的耳光:优雅≠可用
去年我们接了一个紧急项目——给一个老电商系统加实时库存扣减。时间紧(两周上线),技术债多(代码还是Spring Boot 1.x),数据库居然是MySQL 5.6,连窗口函数都不支持。
我第一反应是:“先重构数据模型,建库存流水表,加分布式锁,用Redis做缓存一致性……” 结果被CTO一句话打回:“兄弟,用户现在下单就超卖,你搞这些花里胡哨的,明天就失业。”
于是,我被迫用最“脏”的方式解决问题:
// 直接在原有订单表加个version字段,CAS更新
@Transactional
public boolean deductStock(Long skuId, Integer count) {
int rows = jdbcTemplate.update(
"UPDATE product_stock SET stock = stock - ?, version = version + 1 " +
"WHERE sku_id = ? AND stock >= ? AND version = ?",
count, skuId, count, currentVersion
);
return rows > 0;
}
没有领域模型,没有防腐层,甚至连异常都没细分。但——它跑了。而且扛住了当天3万QPS。
那一刻我意识到:在工程世界里,能跑通的丑代码,远胜于完美的纸上架构。
三、工具与资源:让“脏活”变得可控
当然,我不是鼓吹写烂代码。而是学会在“洁癖”和“交付”之间找平衡。这几年我摸索出一套方法论,核心就两个字:工具化。
1. 自动化格式校验:让机器当“洁癖警察”
我不再手动检查缩进或命名,而是靠工具兜底:
- Java:Spotless + Checkstyle,CI流水线卡死
- SQL:sqlfluff,强制统一风格
- Git:pre-commit hook自动格式化
# .github/workflows/ci.yml 片段
- name: Check code style
run: ./gradlew spotlessCheck
这样既保证了基础一致性,又不用我天天盯着别人改空格。
2. 教程要“反着学”:先看事故复盘,再看最佳实践
以前我总迷信官方文档和《Clean Code》这类神书。现在更爱看:
- SRE事故报告(比如Google的Postmortem)
- GitHub Issues里的血泪史
- Stack Overflow高赞“踩坑”回答
比如最近研究Kafka重复消费,我没先看官方Consumer API文档,而是搜“kafka duplicate message production incident”,直接看Uber和LinkedIn怎么翻车的。效率高多了。
3. 资源要“综合”筛选,别信单一来源
我建了个Notion库,分类整理各类资源:
| 类型 | 推荐来源 | 使用场景 |
|---|---|---|
| 数据库优化 | Percona博客、阿里云RDS白皮书 | 线上慢SQL分析 |
| 后端架构 | ThoughtWorks技术雷达、InfoQ案例 | 技术选型参考 |
| 心态调整 | 《The Manager's Path》、程序员副业社群 | 避免内耗 |
关键不是“收藏”,而是带着问题去查。比如“MySQL主从延迟导致脏读”,直接搜这个关键词+“实战”,比泛读十篇理论文章有用。
四、心态转变:从“完美主义者”到“价值交付者”
最大的成长,其实是认知升级。
以前我觉得:代码=我的作品,所以必须精致。
现在我认为:代码=解决问题的工具,所以够用就好。
这不代表放弃质量。而是把精力花在刀刃上:
- 核心交易链路?必须高内聚、低耦合、全覆盖测试
- 临时运营活动?能跑就行,加个TODO注释,后续下线
上周我们又遇到一个需求:临时加个导出功能。我用了最糙的方式——直接拼SQL字符串:
query := fmt.Sprintf("SELECT * FROM orders WHERE create_time BETWEEN '%s' AND '%s'", start, end)
(别骂,我知道SQL注入风险!但这是内网后台,且输入做了白名单校验)
产品经理惊了:“这么快就搞定了?”
我说:“因为我不纠结它漂不漂亮,只关心它能不能跑。”
五、给同样“洁癖”的同行几点建议
如果你也像我一样,曾为一个缩进失眠,为一个命名纠结半天,不妨试试:
给自己设个“容忍阈值”
比如:非核心模块允许存在“脏代码”,但必须加// DIRTY: 待重构注释,并登记到技术债看板。用监控代替洁癖
与其反复检查日志格式,不如上ELK+告警。代码再乱,只要异常能及时发现,就是可控的。接受“阶段性丑陋”
就像数据库有历史分区表,代码也有生命周期。早期版本粗糙点没关系,关键是留好演进路径。多跟运维和测试聊天
他们才是线上问题的第一见证人。你会发现,90%的故障跟“代码美不美”无关,而是配置错、网络抖、依赖挂。
写在最后
现在的我,依然会在深夜盯着一段SQL发呆,琢磨能不能再少一次回表。但第二天晨会,我会对产品经理说:“这个需求,三天能上线,但可能有点糙,你接受吗?”
他点头,我就干。
毕竟,在成都这座慢节奏的城市里,我早已明白:生活不必事事精致,代码亦然。能解决问题的,就是好代码。
而那些曾经让我失眠的“不完美”,如今成了我交付能力的勋章。
P.S. 如果你也在和代码洁癖斗争,欢迎留言交流。顺便推荐几个我常用的综合资源清单,私信我“洁癖自救”即可获取(纯干货,无广告)。

评论 0