我对技术探索与实践的看法:在腾讯系边缘反复横跳的后端打工人视角
上周五晚上 10 点半,我盯着屏幕里那堆红得发紫的告警日志,一边狂灌冰美式一边想:这破项目再这么搞下去,我真的要提桶跑路了。
我不是没想过跳槽——坐标深圳,腾讯系公司扎堆,隔壁南山科技园每天都有人在脉脉上晒 offer。但每次打开 BOSS 直聘,看到那些“精通高并发、熟悉微服务治理、有复杂系统架构经验”的 JD,我就默默关掉页面,转头去查 redis cluster 的脑裂问题怎么处理。
毕竟,我这个重度依赖 ChatGPT / Claude 的后端仔,到底有多少真本事,自己心里门儿清。
起因:一个“简单”需求引发的技术选型风暴
事情得从去年双11说起。我们组接了个新业务——要做一个实时库存扣减服务,支撑大促秒杀。产品经理拍着胸脯说:“就一个小功能,三天上线,压力不大。”
结果呢?上线第一天,DB 直接被打爆,MySQL 主从延迟飙到 30 秒,用户下单成功却提示“库存不足”,客服电话被打爆。运维大哥在群里@我:“兄弟,你这代码是拿脚写的?”
当时真的想砸电脑。
冷静下来一想,问题出在哪儿?我们用的是最朴素的数据库行锁 + 事务回滚方案,看似安全,实则在高并发下成了性能瓶颈。更惨的是,我们连缓存都没上,全靠 DB 硬扛。
于是,领导一句话甩过来:“下周重构,必须支持万级 QPS,不然你就别干了。”(开玩笑的,但他眼神确实吓人)
我只能硬着头皮开始技术调研。这时候,ChatGPT 成了我的救命稻草——不是让它写代码,而是帮我快速梳理各种方案的优缺点,比如:
- Redis 分布式锁?
- 本地缓存 + 异步刷盘?
- 消息队列削峰?
- 或者直接上 Tair / Pika?
但光看文档哪够?面试题里问“Redis 和 ZooKeeper 分布式锁的区别”,背答案是一回事,真用起来又是另一回事。
实战踩坑:分布式锁真的那么香吗?
一开始我信心满满地用了 Redis 的 SET key value NX PX 方案,配合 Lua 脚本保证原子性。代码看起来贼优雅:
-- unlock.lua
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
// Go 伪代码
func TryLock(key, requestId string, expireMs int) bool {
return redis.SetNX(ctx, key, requestId, time.Duration(expireMs)*time.Millisecond).Val()
}
func Unlock(key, requestId string) {
redis.Eval(ctx, unlockScript, []string{key}, requestId)
}
结果压测到 5000 QPS 时,偶尔出现“超卖”。排查半天才发现:Redis 主从切换期间可能丢锁!因为 SET 是写主节点,但还没同步到从节点,主挂了,从升主,锁就没了。
这时候我才真正理解面试题里那句“Redis 锁不保证强一致性”的含义——纸上谈兵和线上事故,隔着十万八千里。
后来我试了 Redlock 算法,但部署五个 Redis 实例成本太高,团队运维直接摇头:“你是不是想让我们半夜被 PagerDuty 叫醒?”
最终妥协方案:降级为“缓存预扣 + 异步对账”。核心思路:
- 秒杀开始前,把库存加载到 Redis(带版本号)
- 扣减时只操作 Redis,不碰 DB
- 后台定时任务每 5 秒把 Redis 库存同步到 DB,并做对账
- 如果发现 Redis 和 DB 不一致(比如超卖),走补偿流程
虽然不够“完美”,但扛住了双11峰值 12000 QPS,零超卖,运维没骂我——这就够了。
技术选型对比:没有银弹,只有权衡
这次经历让我深刻意识到:技术选型不是比谁用的框架最新,而是看是否匹配团队能力和业务场景。
我把几种常见方案做了个对比(基于我们小团队的实际情况):
| 方案 | QPS 支撑 | 一致性 | 运维成本 | 开发复杂度 | 是否适合我们 |
|---|---|---|---|---|---|
| 纯 MySQL 行锁 | < 500 | 强 | 低 | 低 | ❌(已翻车) |
| Redis 单点锁 | ~8000 | 最终 | 中 | 中 | ⚠️(主从切换风险) |
| Redlock | ~10000 | 较强 | 高 | 高 | ❌(运维不同意) |
| 缓存预扣 + 对账 | ~15000 | 最终(可补偿) | 低 | 中 | ✅ |
| Kafka 削峰 + 异步处理 | 无上限(理论上) | 弱 | 高 | 高 | ❌(引入新组件风险大) |
你看,所谓“最佳实践”,往往是最不适合你的那个。我们团队就 5 个人,两个前端一个测试还经常请假,哪有精力维护 Kafka 集群?更别说还要写一堆重试、幂等、死信队列逻辑。
架构设计 vs 代码质量:我到底该卷哪个?
说到这儿,不得不吐槽一下现在的面试风气。
最近面了几家公司(没错,我还是没忍住投了简历),一面必问“你们系统的架构图能画一下吗?”,二面就开始深挖“如果 QPS 再翻十倍怎么办?”
但当我反问:“你们团队 CI/CD 流程怎么样?Code Review 严格吗?有没有静态检查?”
对方 HR 回答:“这些不重要,先看能不能扛住高并发。”
我:???
没有高质量代码兜底的高并发,都是空中楼阁。
我见过太多“架构师”画了一堆漂亮的分层图,结果 Git 提交记录里全是 fix bug、update config,单元测试覆盖率不到 20%,上线靠手动改配置文件。
我们组虽然小,但我坚持两件事:
- 所有核心逻辑必须有单元测试(哪怕用 Ginkgo 写得丑点)
- PR 必须过 SonarQube,圈复杂度 > 10 的函数不准合
有一次我因为一个 if-else 嵌套太多被卡 PR,同事笑我:“至于吗?又不是谷歌。”
我说:“不是为了装逼,是为了半夜不用爬起来修 Bug。”
跳槽焦虑下的技术探索:我为什么还在学?
说实话,我现在处于一种奇怪的状态:既想跳槽涨薪,又怕去了新地方露馅。
深圳这边,很多公司打着“对标阿里 P7”的旗号招人,结果进去发现天天 CRUD。但也有真·高并发场景的——比如某电商中台,要求候选人手写 Raft 协议。
我自问没那个水平。所以最近下班后,除了刷 LeetCode(主要是为了应付面试题),也在用 Go 重写一些经典中间件,比如简易版 etcd、Raft 日志复制模块。不是为了造轮子,是为了理解原理。
前几天用 Channel 实现了一个简单的协程池,虽然比不过 ants,但至少搞懂了 worker pool 的调度逻辑。这种“知其所以然”的感觉,比背八股文踏实多了。
而且我发现,一旦你真正动手做过,面试时聊起来就有底气。比如被问“Redis 为什么单线程还快?”,我不再只是背“I/O 多路复用”,而是能结合 epoll 和 Reactor 模型,甚至提到 Redis 6.0 的多线程 IO 优化。
结语:在迷茫中保持手感
写这篇文章的时候,已经是凌晨 1 点。窗外深圳湾的灯光还亮着,不知道又有多少程序员在加班。
我知道自己可能永远成不了架构师,也可能拿不到百万年薪。但只要还能写出干净的代码,还能在技术方案里做出合理权衡,我就没白干这行。
至于跳不跳槽?
我想明白了:与其焦虑外面的世界,不如先把手里这个库存服务的监控告警完善了。至少下次大促,我能睡个整觉。
最后送自己一句话,也送给同样迷茫的你:
技术探索不是为了成为别人眼中的高手,而是为了在深夜改 Bug 时,能对自己说一句:“这代码,是我写的,我认。”
附:几个实用建议(血泪总结)
- 别迷信“大厂方案”:人家有 SRE 团队兜底,你可能只有自己
- 面试题要背,但更要动手验证:比如 Redis 锁,自己搭个主从试试
- 代码质量 > 架构炫技:一个清晰的函数名,胜过十页 PPT
- 用好 AI 工具,但别依赖:ChatGPT 能给你思路,但不能替你 debug 线上事故
- 跳槽前,先问清楚:团队技术栈、CI/CD 流程、oncall 频率——这些比薪资数字更重要
(完)

评论 0