抽象不是免费的午餐接口、工厂、策略、适配器设计模式本是好东西可一旦泛滥就成枷锁。一个简单查询非要过五层抽象Controller调ServiceService调ManagerManager调RepositoryRepository再调DAO。每层都做点转换每层都写点日志。每多一层抽象就多一次入栈出栈、多一次对象拷贝、多一次反射调用。奥卡姆剃刀说如无必要勿增实体。代码世界里这把刀该天天磨。抽接口之前先问真的会有第二种实现吗没有就直接写类。过早通用化是效率的头号杀手。集合与流方便背后的代价Java 8的Stream写起来行云流水可流水之下是装箱拆箱、临时对象、多次遍历。一个list.stream().filter().map().collect()比朴素for循环多出若干中间对象GC压力陡增。HashMap默认容量16你塞一万条数据不扩容链表变红黑树查询从O(1)跌到O(log n)。不是Stream慢是你不知道它什么时候慢。该用IntStream就别用StreamInteger该预设容量就别让数组反复复制。工具越高级越要懂它的底牌。数据库与缓存的隐形陷阱代码慢有时慢在代码之外。循环里查数据库一次请求打出一百条SQLN1问题把连接池榨干。缓存用得猛却忘了过期策略内存里堆满永不释放的对象。你以为在优化其实在给系统埋雷。每次查询前问这条SQL走索引了吗这个缓存真的需要吗批量操作能不能合并慢查询和慢代码往往是一对孪生兄弟。内存泄漏看不见的沙漏静态集合只增不减ThreadLocal用完不remove监听器注册了不注销。对象活得好好的GC却收不走。老年代越来越满Full GC越来越频繁每次停顿几百毫秒。内存泄漏是代码的慢性病等发现时系统已在ICU。用jmap看堆直方图用MAT查引用链别等OOM才翻日志。能提前删的代码比能提前加的代码更值钱。做减法才是真功夫老子说为学日益为道日损。写代码何尝不是。加功能是本能删冗余是本事。每个版本留一天做重构删掉没人调的接口合并重复的工具类干掉过期的配置。快代码不是写出来的是删出来的。下次觉得代码变慢先别怪JVM翻翻提交记录看看这半年你往项目里塞了多少“以后可能用”。真相就是你一直在做加法却指望它跑出减法的速度。