沉默是金,总会发光
大家好,我是沉默
有的公司只招“高级 Java 开发”。 为什么?
因为每个开发都得能独立主导一个项目的全生命周期——从需求评审、技术调研、方案选型,到工时评估、上线维护,全链路全自己来。
听起来是不是有点卷?
确实卷。
但现实是:项目要跑得稳,靠的是代码质量和工程意识,而不仅仅是会写 if else。
**
**
今天这篇文,我们就来看看:
在一个“只招高级”的团队里,依然会犯哪些低级错误?
同时,也会分享公司对中、高级开发的区别观察。
**-**01-
高级开发 ≠ 写代码更好
1️⃣ 分布式锁用错了:锁活动,不如锁用户
业务背景:活动报名逻辑。
判断用户是否报名 → 插入报名记录 → 报名名额减一。
原始写法:
RLock lock = redissonClient.getLock(RedisKeyConstant.ACTIVITY_ENROLL_KEY + req.getActivityId());try { lock.lock(); service.cancelActivityEnroll(req); return Response.ok();} finally { lock.unlock();}
问题点评:
| 问题 | 说明 |
|---|---|
| 锁粒度太大 | 锁活动而非用户,导致并发受限 |
| 锁异常处理缺失 | lock() 报错时,finally 仍会 unlock |
| 无超时控制 | 可能造成锁无法释放 |
| 并发性能差 | 用户多时阻塞严重 |
优化思路:
- 锁改为:
活动ID + 用户ID - 使用
tryLock+ 超时机制 - 解锁前判断线程持有权
改进后:
RLock lock = redissonClient.getLock(RedisKeyConstant.ACTIVITY_ENROLL_KEY + req.getActivityId() + userID);try { boolean locked = lock.tryLock(0, 10, TimeUnit.SECONDS); return locked ? service.activityEnroll(req) : Result.error("网络繁忙");} finally { if (lock.isHeldByCurrentThread()) lock.unlock();}
同时,在 Service 层要缩小事务范围,并用行锁代替分布式锁:
update t_activity set num = num - 1 where id = ? and num > 0
2️⃣ 定时发送短信任务:线程安全被忽略
业务场景:
后台批量发送短信 / 语音任务,采用 RabbitMQ 延迟队列触发。
原代码:
@RabbitListener(queues = "SMS_DELAY_QUEUE")public void doSmsTask(Message message, Channel channel ) { String id = new String(message.getBody()); service.actionSendTask(id);}
问题点评:
| 问题 | 影响 |
|---|---|
| 未捕获异常 | 消息异常后无限重试 |
| 无幂等控制 | 重复消费 |
| 策略上下文非线程安全 | 多线程下策略对象错乱 |
策略类问题:
strategyContext.setSmsStrategy(StgFactory.getStrategy(type));smsStrategyContext.send(task, phones);
多线程调用时,会覆盖 smsStrategy,导致乱发。
优化方案:
- 使用 Redis 去重控制幂等;
- 每种策略独立执行,异常不影响其他;
- 使用
ThreadLocal或同步块保证线程安全。
优化后代码:
public synchronized Boolean sendByType(Task task, List<String> phones, Integer type) { ISmsStrategy strategy = StgFactory.getStrategy(type); strategy.sendSms(task, phones); strategy.sendAfterHandle(task); return true;}
并发逻辑关系如下图所示:
[MQ 消息] → [幂等检查 Redis] → [多策略并行发送] → [异常单独捕获]
3️⃣ 其他常见坑点
| 问题类型 | 错误写法 | 优化建议 |
|---|---|---|
| 分布式锁滥用 | Quartz 已集群还加 Redisson 锁 | 避免重复加锁 |
| 魔法变量 | if (status == 1) | 使用枚举常量 |
| select * 查询 | MyBatisPlus 默认全字段 | 明确字段,减少 IO |
| 异常处理 | try-catch 空 | 记录日志 + 上报 |
- 02-
“高级程序员” vs “中级程序员”
| 维度 | 中级程序员 | 高级程序员 |
|---|---|---|
| 设计能力 | 能实现功能,但结构死板 | 结合业务抽象模型,预留扩展 |
| 表结构 | 经常冗余、绕逻辑 | 简洁、高内聚 |
| 可维护性 | 可读性差,命名随意 | 命名规范,职责单一 |
| 问题排查 | 依赖搜索引擎 | 能主动 debug 源码分析 |
| 性能意识 | 不了解执行计划 | 善用 explain + 索引分析 |
| 工时评估 | 估不准 | 能提前识别风险点 |
- 03-
从中级到高级的三个关键
1. 懂原理,别只会用
比如:
-
分布式锁锁什么才是核心;
-
MQ 幂等与消息确认机制;
-
事务传播行为与隔离级别。
2. 从“写完功能”到“设计系统”
想一想:
-
这段逻辑能否复用?
-
未来扩展时要改多少地方?
-
出错了能快速定位吗?
3. 打磨规范与代码风格
高级程序员的代码,读起来像“说明书”,
而不是“解谜游戏”。
**-****04-**总结
我们团队的经验是——
代码不是写给机器的,而是写给团队的。
成为高级程序员的过程,不只是技术的堆叠,
而是从“完成任务”到“构建体系”的转变。
欢迎在评论区聊聊:
你见过最典型的“高级程序员错误”是什么?
或者,你自己从中级到高级的转变经历。
**-****05-**粉丝福利
站在职业的十字路口,我们或许都曾感到迷茫:
投出的简历总是没有回音?
面试时不知如何展现自己的优势?
未来的职场道路该如何规划?
技术管理能力提升,如何跨越第一步?
如果你正在经历这些,我很乐意用我的经验为你提供一些帮助。
无论是修改简历、1对1求职陪跑,职业规划咨询,
还是迈向技术Leader或提升管理效能,
欢迎你加我,我们像朋友一样聊聊。