关于技术探索与实践的一些经验
上周五晚上 9 点半,我坐在公司工位上,盯着屏幕上 Spring Boot 应用启动失败的日志——Error creating bean with name 'dataSource'...。窗外天已经全黑了,隔壁工位的同事早已溜之大吉,只有我和产品经理小王还在“深情对望”。他刚在企业微信里发来一句:“这个功能双11前必须上线啊,老板很看重。”
那一刻我真的想砸电脑。
但转念一想,这不就是我们这群写代码的人的日常吗?一边被 deadline 追着跑,一边还得琢磨怎么把代码写得既快又稳。今天这篇文章,就聊聊我在过去几年折腾技术时踩过的坑、攒下的经验,以及为什么我这个在老东家待了三年多的“老人”,开始认真考虑换个环境了。
我是谁?一个不想再当“人肉补丁”的试用期员工
对,你没看错——试用期员工。虽然我已经在这家公司干了三年多,但今年初内部转岗到了新成立的创新产品线,按流程重新走了一遍入职,现在正处于三个月试用期的尾巴上。说起来有点讽刺:明明是老员工,却要像新人一样写日报、做周报、参加各种“破冰”会议。
不过话说回来,这次转岗也让我有机会重新审视自己的技术栈和职业路径。之前一直在维护一个古老的单体系统,代码像意大利面条一样缠在一起,连加个日志都得小心翼翼。而新团队主推微服务 + Spring Boot 技术栈,要求高内聚、低耦合、可测试、可回滚……嗯,听起来很美好,但现实总是骨感的。
也正是在这种“既要又要还要”的压力下,我才真正意识到:技术探索不是为了炫技,而是为了活下去。
产品需求 vs. 工程现实:一场永无止境的拉锯战
我们正在做的是一款面向 C 端用户的智能推荐产品。产品经理小王(对,就是那个周五晚上还在催我的人)的想法天马行空:“我们要做千人千面!实时更新!毫秒级响应!”
听起来很酷,但落到工程层面,问题就来了:
- 数据源来自五个不同的上游系统
- 用户行为日志每秒上万条
- 推荐算法模型需要每天凌晨训练
- 前端要求接口响应时间 ≤200ms
更惨的是,项目立项时只给了两个月开发周期。运维同学一听就摇头:“你们这架构,怕是要在双11当天给用户送‘404 礼包’。”
怎么办?硬上呗。
第一步:别急着写代码,先画边界
很多新人(包括曾经的我)一接到需求就打开 IDE 开干。结果往往是:写到一半发现上下游接口没对齐,或者某个依赖服务压根不支持你需要的功能。
这次我学乖了。花了整整两天时间,拉着后端、前端、算法、测试开“需求澄清会”。用白板画出了整个数据流:
[用户点击] → [埋点上报] → [Kafka] → [Flink 实时计算] → [Redis 缓存]
↘ [离线 Hive 表] → [Spark 训练] → [模型服务]
→ [Spring Boot API] ← [MySQL + Elasticsearch]
明确每个环节的 SLA、容错机制和降级策略。比如 Redis 挂了怎么办?直接走 MySQL 冷查询,虽然慢点但不至于崩盘。
这个过程虽然“浪费”了两天,但避免了后期返工。代码可以重构,但信任一旦崩了,再难重建。
Spring Boot:不是银弹,但能救命
新项目用 Spring Boot 3.x + Java 17。说实话,一开始我是抗拒的——毕竟老系统还在用 Spring Boot 1.5,升级成本太高。但这次是全新项目,正好借机上新版本。
不过,Spring Boot 的“约定优于配置”是一把双刃剑。新手觉得它开箱即用,老手知道它暗藏玄机。
踩坑实录:自动配置的“善意陷阱”
有一次,我在 application.yml 里配了两个数据源:
spring:
datasource:
primary:
url: jdbc:mysql://...
secondary:
url: jdbc:mysql://...
结果启动时报错:No qualifying bean of type 'javax.sql.DataSource' available。
查了半天才发现,Spring Boot 的 DataSourceAutoConfiguration 默认只会绑定到 spring.datasource 下的配置。自定义多数据源?得自己写 @Configuration 类,手动注入 DataSource Bean。
后来我干脆封装了一个通用的多数据源 Starter,加了详细的注释:
/**
* 多数据源配置 - 注意:不要和 Spring Boot 默认的 DataSourceAutoConfiguration 冲突
* 使用方式:
* 1. 在 application.yml 中定义 ds1, ds2...
* 2. 在 Service 上用 @DS("ds1") 注解指定数据源
*/
@Configuration
public class MultiDataSourceConfig {
// ... 省略实现
}
这种“看起来很简单,其实很坑”的地方,在 Spring Boot 里比比皆是。自动配置省了你 80% 的活,但也偷走了你对系统的掌控感。所以我的建议是:至少读一遍官方文档的 Auto-configuration 章节,再决定要不要用。
代码人生:可读性比性能更重要(在大多数情况下)
我是个 Mac 党,Windows 只用来测兼容性。不是装,是真的觉得 macOS 的终端 + VS Code + iTerm2 组合太香了。但有一次,我写的代码在 Windows 测试机上跑不起来——因为路径分隔符用了 / 而不是 File.separator。
测试妹子直接在 JIRA 里@我:“MacBoy,你的代码又飘了!”
这件事让我反思:我们写代码,到底是为了机器执行,还是为了人阅读?
在高压交付环境下,很多人会说:“能跑就行,别管格式。”但等你半年后回头看自己写的代码,发现连自己都看不懂,那种绝望感……懂的都懂。
所以我现在坚持几个原则:
- 方法不超过 30 行:超过就拆
- 变量命名拒绝缩写:
userPaymentService比ups强一百倍 - 复杂逻辑必须写注释:不是解释“做了什么”,而是说明“为什么这么做”
- 提交信息写清楚上下文:
fix bug是垃圾,fix NPE in OrderService when user is null (see JIRA-123)才是专业
举个真实例子。我们有个订单状态机,最初是用一堆 if-else 写的:
if (status == PAID && action == SHIP) {
// ...
} else if (status == SHIPPED && action == DELIVER) {
// ...
}
后来我把它改成了状态模式 + 策略模式,虽然代码量多了,但新增状态只需要加一个类,不用动主流程。短期看是“过度设计”,长期看是“救命稻草”。
简历上的“技术亮点”,往往来自深夜的崩溃
说到简历,最近我在偷偷更新。三年多的经验,不能只写“熟悉 Spring Boot”、“参与过多个项目”这种废话。
HR 看简历平均只有 6 秒。怎么在 6 秒内抓住眼球?用结果说话。
比如:
❌ “使用 Spring Boot 开发后端服务”
✅ “通过 Spring Boot 自定义 Starter 封装多数据源组件,降低团队接入成本 70%,支撑日均 500w 请求”
❌ “优化系统性能”
✅ “重构订单状态机,将状态变更错误率从 5% 降至 0.1%,减少客诉 200+/月”
这些数字哪来的?都是被线上事故逼出来的。
记得去年双11,我们的推荐接口因为缓存穿透,QPS 瞬间打爆数据库。半夜三点被 PagerDuty 叫醒,手抖着回滚版本。第二天复盘会上,CTO 盯着我说:“你要对你的代码负责,不只是写完就跑。”
那之后,我给所有对外接口加了熔断、限流、降级三件套:
@CircuitBreaker(name = "recommendation", fallbackMethod = "fallbackRecommend")
@RateLimiter(name = "recommendation", limitForPeriod = 1000)
public List<Item> getRecommendations(String userId) {
// ...
}
private List<Item> fallbackRecommend(String userId, Exception e) {
log.warn("Fallback to default recommendations due to: {}", e.getMessage());
return defaultItems;
}
现在这段代码成了我简历里的“明星案例”。
技术选型:没有最好,只有最合适
经常看到网上争论:“Spring Boot vs. Go”、“Kafka vs. RabbitMQ”、“MySQL vs. MongoDB”……
但在真实业务中,技术选型从来不是纯技术问题,而是成本、风险、团队能力的综合权衡。
我们团队只有 5 个后端,3 个刚毕业。如果强行上一套复杂的 Event Sourcing + CQRS 架构,估计三天就得崩。所以最终我们选择了:
| 组件 | 选择 | 原因 |
|---|---|---|
| Web 框架 | Spring Boot 3.x | 团队熟悉,生态成熟 |
| 消息队列 | Kafka | 高吞吐,已有运维支持 |
| 缓存 | Redis Cluster | 支持数据分片,社区方案多 |
| 数据库 | MySQL 8.0 | ACID 强一致,DBA 有经验 |
有人可能会说:“这不够酷。”但能稳定跑一年的平庸架构,远胜于三天就崩的‘先进’架构。
写在最后:为什么我想换个环境?
说了这么多,其实有个心结一直没解开。
在这家公司三年多,我从 Junior 成长为能独立负责模块的工程师,也积累了不少实战经验。但最近越来越觉得:舒适区待久了,技术会生锈。
团队氛围不错,领导也认可我的能力,但业务进入平稳期,技术挑战越来越少。每天的工作变成了“修修补补”、“救火救火”。而我想做的,是参与从 0 到 1 的产品构建,尝试更前沿的技术(比如云原生、Serverless),而不是在旧系统上打补丁。
所以,我开始更新简历,也开始写这样的技术总结。不是为了炫耀,而是梳理自己的知识体系,看清下一步该往哪走。
技术探索的本质,从来不是追新,而是在约束条件下找到最优解。而所谓“代码人生”,就是在无数次崩溃与修复中,慢慢学会与不确定性共处。
哦对了,上周五那个 dataSource 的问题,最后发现是 YAML 缩进错了两格。😅
P.S. 如果你也在经历类似的职业倦怠,不妨问问自己:现在的环境,还能让你每周学到新东西吗? 如果答案是否定的,也许,是时候出发了。

评论 0