年薪50万的Java工程师,和普通开发者之间的差距,往往不在掌握了多少框架,而在日复一日的编码习惯。以下10个习惯,看似简单,却能在长期积累中拉开巨大差距。
1. 命名即注释,拒绝拼音和缩写
变量名、方法名、类名,永远用完整、准确的英文表达。getUserInfoById比getUsrInf清晰一百倍,orderList比ddlb专业得多。好的命名让代码自解释,省去大量注释维护成本。年薪50万的工程师深知:代码是写给人看的,顺便让机器执行。
2. 方法单一职责,不超过一屏
一个方法只做一件事,超过50行就要考虑拆分。长方法意味着高耦合、难测试、难复用。把“校验参数、查询数据库、组装数据、发送消息”塞进一个方法,后续改任何一步都心惊胆战。拆分后,每个方法可独立测试、独立优化,出问题也能快速定位。
3. 防御式编程,参数校验前置
对外部传入的参数,永远先校验再使用。Objects.requireNonNull、StringUtils.isBlank、自定义业务校验,把非法输入挡在核心逻辑之外。很多线上事故,不是逻辑写错,而是边界没考虑。年薪50万的工程师不会假设调用方永远正确,而是让代码在异常输入下也能优雅失败。
4. 异常不吞,日志带上下文
catch (Exception e) {}是埋雷。要么处理,要么包装后抛出,绝不能静默吞掉。记录日志时,必须带上关键上下文:订单号、用户ID、请求参数。只打一句“系统异常”,排查时等于大海捞针。好的异常处理,能让故障定位从两小时缩短到两分钟。
5. 用Optional代替null返回
返回null是Java中最常见的空指针来源。用Optional<T>明确表达“可能为空”,强制调用方处理。findById返回Optional<User>,调用方必须orElseThrow或ifPresent,从编译期就减少NPE风险。这个习惯需要团队共识,但一旦推行,线上空指针异常会大幅下降。
6. 集合初始化指定容量
new ArrayList<>()默认容量10,扩容时涉及数组复制。如果能预估数据量,直接new ArrayList<>(expectedSize),避免多次扩容。HashMap同理,还能减少哈希冲突。这个细节对单次请求影响微乎其微,但在高并发、大数据量场景下,积少成多,性能收益可观。
7. 优先使用不可变对象和final
能加final的字段、参数、局部变量都加上。不可变对象天生线程安全,无需额外同步。String、Integer、LocalDate都是不可变类的典范。自定义类时,尽量让字段private final,不提供setter,需要修改时返回新对象。这能大幅减少并发bug和意外修改。
8. 并发代码先想清楚线程安全
写多线程代码前,先问三个问题:共享变量有哪些?谁读谁写?用什么同步机制?优先使用java.util.concurrent包下的并发容器和原子类,而不是自己用synchronized和wait/notify造轮子。线程池参数要结合业务场景设置,避免Executors.newCachedThreadPool这类无界队列导致OOM。
9. 单元测试覆盖核心逻辑
不要求100%覆盖率,但核心业务逻辑、边界条件、异常分支必须有测试。JUnit 5 + Mockito + AssertJ 是标配。测试不仅是验证,更是文档:后来者通过测试用例就能理解方法意图。重构时,有测试兜底才敢动手。年薪50万的工程师,提交代码前跑一遍测试是肌肉记忆。
10. 代码审查不是走过场
认真看别人的代码,也认真对待别人的审查意见。审查时关注:命名是否清晰、边界是否处理、异常是否合理、是否有重复代码、是否影响性能。提出问题时给出建议,而不是简单说“不行”。代码审查是团队技术交流的最佳场所,也是自己查漏补缺的机会。
这10个习惯,单看都不难,难的是日复一日坚持。年薪50万不是终点,而是这些习惯长期复利的结果。从今天起,挑一个习惯开始践行,三个月后回头看,你的代码质量会明显不同。