一、集合与流式编程高级技巧
1. Stream 进阶优化,避免隐形性能损耗
- 短路操作优先 :
findFirst()/anyMatch()/limit()会中断流遍历,大数据集优先使用短路算子。
java
// 高效:找到第一个匹配就停止
Optional<String> target = list.stream()
.filter(s -> s.startsWith("A"))
.findFirst();
- 原始流减少装箱开销 :
IntStream/LongStream/DoubleStream替代Stream<Integer>,规避自动装箱拆箱。
java
// 高性能求和
int sum = IntStream.range(1, 1000).filter(i -> i % 2 == 0).sum();
Collectors.toMap防键冲突 默认重复键会抛异常,提供合并函数兜底:
java
Map<Long, User> userMap = users.stream()
.collect(Collectors.toMap(
User::getId,
Function.identity(),
(oldVal, newVal) -> newVal // 冲突取新值
));
- 并行流慎用 并行流底层依赖
ForkJoinPool.commonPool(),IO 密集、数据量小时并行会因线程切换变慢;CPU 密集、百万级数据 再用.parallelStream(),可自定义线程池隔离并行任务。
2. Map 高效操作
computeIfAbsent缓存式赋值,避免重复判断 key 是否存在:
java
Map<String, List<String>> groupMap = new HashMap<>();
// 一行实现分组,不用if判断
groupMap.computeIfAbsent("key", k -> new ArrayList<>()).add("value");
merge聚合累加,统计计数极简写法:
java
countMap.merge("apple", 1, Integer::sum);
- 只读集合防篡改:
Collections.unmodifiableList()/ Java9+List.of()(不可变,不支持 null)
二、并发编程高级实战(Java 并发核心)
1. 线程池规范使用,禁止裸创建 Thread
生产统一使用 ThreadPoolExecutor 手动构造,拒绝 Executors 快捷方法(易 OOM):
java
ExecutorService pool = new ThreadPoolExecutor(
5, 20, 60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(1000),
new ThreadPoolExecutor.CallerRunsPolicy() // 队列满由调用线程执行,防止丢任务
);
2. CompletableFuture 异步编排(Java8+ 替代 Future)
支持多任务组合、超时、异常回调,摆脱阻塞 get():
java
// 并行两个接口,全部完成后合并结果
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> queryUser());
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> queryScore());
CompletableFuture<String> res = f1.thenCombine(f2, (u, s) -> u + s);
// 超时控制,避免无限阻塞
res.orTimeout(3, TimeUnit.SECONDS);
// 异常兜底
res.exceptionally(ex -> "默认值");
3. 锁优化:分段锁、读写锁、自旋锁
ReentrantReadWriteLock:读多写少场景(缓存、配置),读共享、写互斥,大幅提升并发吞吐量;StampedLock:乐观读锁,无锁读阶段性能高于读写锁;- 减少
synchronized锁粒度:只锁共享变量,不锁整个方法; - 并发容器选型:
- 读多写少:
CopyOnWriteArrayList - 高并发读写:
ConcurrentHashMap(JDK8 分段锁改为 CAS + 同步锁,性能大幅提升)
- 读多写少:
4. ThreadLocal 正确使用
- 用途:存储线程私有数据(登录用户、链路 TraceId);
- 必做:使用完
remove(),防止线程池复用导致内存泄漏、数据串扰;
java
private static final ThreadLocal<User> USER_TL = new ThreadLocal<>();
// 使用完清除
USER_TL.remove();
三、JVM 性能调优 & 内存高级技巧
- 避免长生命周期大对象 大字符串、大数组直接进入老年代,频繁触发 Full GC;分批拆分加载数据。
- 对象复用,减少 GC 压力 高频创建临时对象(循环内 new 对象)改用对象池、
StringBuilder、基本类型替代包装类。 - String 优化
- 拼接循环必须用
StringBuilder,不要+; intern()慎用:JDK7 后常量池移至堆,大量调用会占用堆内存;- 字符串判空工具类:
StringUtils.isBlank,避免空指针。
- 软引用 / 弱引用做本地缓存
WeakHashMap自动回收无引用 key,适合临时缓存,减少手动清理。
四、泛型、反射、注解高级进阶
1. 泛型通配符上下界,灵活约束
? extends T:上界,只读(不能 add);? super T:下界,只写;
java
// 生产者用extends,消费者用super(PECS原则)
public static <T> void copy(List<? extends T> src, List<? super T> dest) {
dest.addAll(src);
}
2. 类型擦除补偿:TypeReference 获取泛型真实类型
普通反射无法获取 List<User>,使用 ParameterizedType / Spring TypeReference 捕获泛型:
java
Type type = new TypeReference<List<User>>() {}.getType();
3. 反射性能优化
反射慢核心是每次获取 Method/Field 开销大:
- 缓存
Method、Field对象; - 开启
setAccessible(true)关闭权限校验; - 高频反射替换为 LambdaMetafactory 动态生成代理,性能接近直接调用。
4. 元注解 & 自定义注解处理器(APT)
编译期注解处理,自动生成代码(Lombok、Mybatis Mapper 底层原理),减少手写模板代码,无运行时性能损耗。
五、Lambda & 函数式高级技巧
- 方法引用简化代码,减少匿名内部类
java
list.forEach(System.out::println);
list.stream().map(User::getName).collect(Collectors.toList());
- 自定义函数式接口,实现策略模式
java
@FunctionalInterface
public interface BizHandler<T> {
void handle(T data);
}
// 动态传入不同处理逻辑
public void execute(BizHandler<String> handler) {
handler.handle("data");
}
- Lambda 捕获变量限制:只能捕获 final/effectively final 若要在 lambda 内修改变量,使用
AtomicReference、数组包装。
六、异常处理高级规范
- 区分受检异常与非受检异常 业务错误自定义
RuntimeException,避免大量throws污染方法签名; - 禁止吞异常:不要
catch(Exception e){},至少打印日志; - try-with-resources 自动关闭实现 AutoCloseable 的资源(IO、连接、流),不用手动 finally 关闭:
java
try (FileInputStream fis = new FileInputStream("test.txt")) {
// 读写
} catch (IOException e) {
log.error("文件读取失败", e);
}
- 异常链传递:
initCause()保留原始异常堆栈,方便定位根因。
七、面向对象高级设计技巧
- 建造者模式构建复杂对象 替代多参数构造器,可读性强,Lombok
@Builder一键生成; - 不可变对象设计(线程安全) 类加
final、字段private final、无 setter、构造器初始化所有字段,天然并发安全,无需加锁; - 枚举高级用法
- 枚举单例(最安全单例模式,防反射、序列化破坏);
- 枚举实现接口,分业务逻辑;
java
public enum OrderStatus implements StatusHandler {
PAID {
@Override
public void handle() {}
};
}
- 单例模式最优方案:枚举单例
java
public enum Singleton {
INSTANCE;
public void doSomething() {}
}
八、序列化高级避坑
transient关键字:序列化忽略字段;- 自定义
readObject/writeObject控制序列化逻辑; - 固定
serialVersionUID,类修改后不兼容旧序列化对象; - 生产慎用 Java 原生序列化,推荐 JSON、Protobuf 序列化(体积小、跨语言、安全)。
九、Java 9+ 新特性高阶用法
- 模块化 Module(JPMS):隔离依赖,精简 JRE 镜像;
- 不可变集合工厂:
List.of() Set.of() Map.of(),线程安全、不允许 null; - Stream 新增:
takeWhile/dropWhile条件截取流; - 私有接口方法:接口内抽取公共逻辑,减少重复代码;
- 文本块
""" """,多行字符串不用转义换行、引号。
十、生产避坑高级经验
- equals 重写规范 重写
equals必须重写hashCode,否则 HashMap、HashSet 逻辑异常;Objects 工具类简化判空比较:
java
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
- 浮点数运算禁止用
==,使用BigDecimal处理金额; - 日期时间抛弃
Date/Calendar,Java8LocalDateTime线程安全,自带格式化与时区; - 避免循环创建数据库连接,统一使用连接池;
- 大分页禁止
limit offset,采用游标分页(ID > 上一页最大值),提升数据库性能。
十一、性能对比总结
- 简单循环 > 串行 Stream > 并行 Stream(小数据)
- 原始类型 > 包装类
- 读写锁 > synchronized(读多写少)
- 枚举单例 > 双重检查锁单例 > 静态内部类单例
- try-with-resources > 手动 finally 关闭流