Java错误示例100讲

00 开篇词 | 业务代码真的会有这么多坑?

你好,我是朱晔,贝壳金服的资深架构师。我先和你说说我这 15 年的工作经历吧,以加深彼此的了解。前 7 年,我专注于.NET 领域,负责业务项目的同时,也做了很多社区工作。在 CSDN 做版主期间,我因为回答了大量有关.NET 的问题,并把很多问题的答案总结成了博客,获得了 3 次微软 MVP 的称号。后来,我转到了 Java 领域,也从程序员变为了架构师,更关注开源项目和互联网架构设计。在空中网,我整体负责了百万人在线的大型 MMO 网游《激战》技术平台的架构设计,期间和团队开发了许多性能和稳定性都不错的 Java 框架;在饿了么,我负责过日千万订单量的物流平台的开发管理和架构工作,遇到了许多只有高并发下才会出现的问题,积累了大量的架构经验;现在,我在贝壳金服的基础架构团队,负责基础组件、中间件、基础服务开发规划,制定一些流程和规范,带领团队自研 Java 后端开发框架、微服务治理平台等,在落地 Spring Cloud 结合 Kubernetes 容器云平台技术体系的过程中,摸索出了很多适合公司项目的基础组件和最佳实践。这 15 年来,我一直没有脱离编码工作,接触过大大小小的项目不下 400 个,自己亲身经历的、见别人踩过的坑不计其数。我感触很深的一点是,业务代码中真的有太多的坑:有些是看似非常简单的知识点反而容易屡次踩坑,比如 Spring 声明式事务不生效的问题;而有些坑因为“潜伏期”长,引发的线上事故造成了大量的人力和资金损失。因此,我系统梳理了这些案例和坑点,最终筛选出 100 个案例,涉及 130 多个坑点,组成了这个课程。意识不到业务代码的坑,很危险我想看到 100、130 这两个数字,你不禁要问了:“我写了好几年的业务代码了,遇到问题时上网搜一下就有答案,遇到最多的问题就是服务器不稳定,重启一下基本就可以解决,哪里会有这么多坑呢?”带着这个问题,你继续听我往下说吧。据我观察,很多开发同学没意识到这些坑,有以下三种可能:意识不到坑的存在,比如所谓的服务器不稳定很可能是代码问题导致的,很多时候遇到 OOM、死锁、超时问题在运维层面通过改配置、重启、扩容等手段解决了,没有反推到开发层面去寻找根本原因。有些问题只会在特定情况下暴露。比如,缓存击穿、在多线程环境使用非线程安全的类,只有在多线程或高并发的情况才会暴露问题。有些性能问题不会导致明显的 Bug,只