Java 30 组高频技术 / 知识点多角度对比
覆盖基础、集合、并发、流、JVM、框架、新特性每组多维度详细区分1. ArrayList vs LinkedList对比维度底层结构、查询、头尾增删、中间插入、内存开销、遍历、适用场景底层ArrayList 动态数组LinkedList 双向链表查询随机下标ArrayList O (1)直接寻址LinkedList O (n)需遍历节点尾部新增ArrayList 扩容时复制数组平均快LinkedList 仅修改指针无扩容中间 / 头部插入删除ArrayList 需要数组后移性能差LinkedList 只改前后指针速度快内存ArrayList 连续内存缓存友好LinkedList 每个节点存 prev/next额外内存开销大遍历ArrayList fori/foreach 更快LinkedList 仅 foreach 友好fori 巨慢场景ArrayList 绝大多数业务查询多、尾部新增LinkedList 频繁头尾增删、实现队列 / 栈2. HashMap vs ConcurrentHashMap(JDK8)维度线程安全、锁机制、并发性能、扩容、null 键值、数据结构线程安全HashMap 不安全并发丢数据、死循环CHM 线程安全锁HashMap 无锁CHM CAS synchronized 锁住链表 / 红黑树头节点粒度细nullHashMap 允许 1 个 null key、多个 null valueCHM key/value 都不允许 null扩容HashMap 并发扩容链表死循环CHM 分段迁移并发扩容安全结构数组 链表 红黑树同 HashMap 结构增加并发控制性能单线程 HashMap 更快多线程 CHM 远优于 Collections.synchronizedMap3. HashMap vs TreeMap vs LinkedHashMap维度有序性、底层、查询速度、排序规则、使用场景HashMap无序哈希表O (1)无排序普通键值存储LinkedHashMap插入 / 访问有序哈希表 双向链表O (1)有序遍历、简易 LRU 缓存TreeMapkey 升序红黑树O (logn)需要按 key 自然排序场景4. ArrayList vs CopyOnWriteArrayList维度线程安全、读写性能、内存、迭代、适用场景安全ArrayList 不安全COWAL 线程安全读COWAL 无锁读取极快ArrayList 单线程读快写COWAL 写入复制完整新数组开销极大ArrayList 写轻量迭代COWAL 迭代快照无并发修改异常ArrayList 遍历修改抛异常场景COWAL 读多写少配置缓存ArrayList 单线程操作5. synchronized vs Lock(ReentrantLock)维度底层、锁粒度、公平锁、中断、超时、可重入、释放、性能底层synchronized JVM 底层实现Lock API 层面AQS 队列公平锁synchronized 仅非公平Lock 支持公平 / 非公平切换中断等待synchronized 阻塞不可中断lockInterruptibly () 可中断限时等待synchronized 无限阻塞tryLock (time) 超时自动放弃释放synchronized 自动释放Lock 必须 finally 手动 unlock否则死锁条件变量synchronized 只能 1 个 waitLock 支持多个 Condition性能低竞争 synchronized 优化后接近 Lock高并发 Lock 性能更好6. volatile vs synchronized维度作用、原子性、可见性、重排、锁、使用场景volatile仅保证可见性、禁止指令重排不保证原子性无锁synchronized可见性 原子性 禁止重排独占锁计数场景volatile i 并发错乱synchronized 自增安全开销volatile 轻量synchronized 存在阻塞、上下文切换场景volatile 状态标记、双重检查锁单例synchronized 复合操作并发保护7. Runnable vs Callable维度返回值、异常、线程池、run 方法、FutureRunnable run () 无返回值不能抛出受检异常Callable call () 有返回值可抛异常线程池提交submit (Runnable) 无返回submit (Callable) 返回 Future 获取结果异常Runnable 异常只能内部捕获Callable 异常可通过 Future.get () 捕获配合Runnable 基础线程Callable 异步需要获取执行结果场景8. CountDownLatch vs CyclicBarrier维度复用、计数归 0 逻辑、使用场景CountDownLatch一次性主线程等多个子任务完成计数归零不可重置CyclicBarrier可循环复用多个线程互相等待全部到达屏障再一起执行举例CDL 主线程等待批量查询全部完成CB 多分段计算全部算完合并结果9. 并行流 parallelStream vs 自定义线程池 CompletableFuture维度线程池、IO 阻塞、线程隔离、控制、异常parallelStream共用全局 ForkJoinPool无隔离IO 阻塞拖垮全局所有并行流CompletableFuture可传入自定义线程池任务隔离不影响其他业务控制力度并行流无法自定义线程数线程池可自定义核心、最大线程适用parallelStream 纯内存计算CompletableFuture IO、RPC、隔离异步任务10. Stream 中间操作 vs 终止操作维度执行时机、返回值、是否消费流、作用中间操作 (filter/map/sorted/peek)惰性执行返回新 Stream不消费流仅构建执行链终止操作 (collect/forEach/count/findFirst)触发实际计算消耗流无 Stream 返回关键无终止操作中间代码完全不执行流只能执行一次终止操作11. map() vs flatMap()维度返回类型、嵌套集合、使用场景mapT - R一对一转换返回 StreamR嵌套 List 会变成 StreamListTflatMapT - StreamR扁平化拆解嵌套集合输出单层流场景简单字段映射用 map集合嵌套拆解用 flatMap12. orElse() vs orElseGet()维度执行时机、性能、参数类型orElse (T obj)无论 Optional 是否为空入参对象 / 方法一定会执行适合轻量常量orElseGet (Supplier)仅空值时才执行 Supplier适合耗时查询、IO 操作性能耗时逻辑优先 orElseGet避免无用计算13. Optional.of() vs Optional.ofNullable()维度入参 null 处理、使用场景Optional.of (obj)obj 为 null 直接抛出 NPE确定对象非空时使用Optional.ofNullable (obj)obj 为 null 返回 Optional.empty ()不确定对象是否为空通用14. String 拼接 vs StringBuilder vs StringBuffer维度线程安全、性能、适用场景String 编译期少量拼接会优化 StringBuilder循环大量拼接生成大量中间对象性能极差StringBuilder非线程安全单线程高性能日常循环字符串拼接首选StringBuffer加 synchronized线程安全性能更低极少多线程拼接场景使用15. vs equals()维度比较内容、对象 / 基本类型、重写规则基本类型比较值引用类型比较内存地址equals ()Object 默认同 String、包装类重写为比较内容自定义实体需手动重写 equalshashCode 才能按业务字段对比16. 基本数据类型 vs 包装类维度存储位置、默认值、null、装箱拆箱、缓存基本类型栈内存有默认值不能为 null无对象头开销小包装类堆对象默认 null自动装箱 valueOf、拆箱 xxxValue-128~127 缓存超出 失效17. final 修饰变量 / 方法 / 类 三者对比final 变量基本类型值不可改引用类型地址不可改内部属性可修改final 方法不可被子类重写运行期避免动态绑定小幅优化final 类禁止继承所有方法隐式 final如 String、Integer18. 接口 (Interface JDK8) vs 抽象类 abstract class维度构造方法、成员变量、多继承、方法、构造、静态代码块抽象类有构造方法成员变量可任意修饰单继承可实例变量、代码块接口无构造变量默认 public static final可多实现JDK8 default/static 方法、JDK9 私有方法仅行为契约无状态19. 重载 Overload vs 重写 Override维度位置、方法名、参数、返回值、权限、异常重载同类同名参数列表不同返回值无要求任意权限重写父子类同名同参数同返回子类权限不能更严格受检异常不能抛出更宽泛20. try-with-resources vs 手动 close ()维度关闭时机、异常、代码冗余、泄漏风险try-with-resources实现 AutoCloseable 自动关闭无论正常 / 异常关闭异常附 suppressed 异常无资源泄漏代码简洁手动 close必须 finally 关闭代码冗余忘记关闭导致文件句柄、连接泄漏21. Error vs Exception维度是否捕获、产生原因、处理策略Error系统级致命错误 (OutOfMemory、StackOverflow)无需捕获程序无法恢复Exception业务异常分运行时异常 (无需捕获)、受检异常 (编译强制捕获)可业务兜底处理22. 受检异常 vs 运行时异常维度编译校验、抛出声明、适用场景受检异常继承 Exception 非 RuntimeException编译强制 try-catch 或 throwsIO、文件、网络等外部不可控异常运行时异常RuntimeException编译不校验空指针、数组越界、参数错误等代码逻辑问题23. JVM 栈 vs 堆 vs 元空间 Metaspace维度存储内容、生命周期、GC、内存溢出虚拟机栈局部变量、栈帧方法执行完毕释放栈深度不够 StackOverflow堆所有对象实例、数组GC 回收对象过多 OOM 堆溢出元空间类元信息、常量、注解本地内存类加载过多 Metaspace 溢出24. 标记清除 / 复制 / 标记整理 GC 算法对比标记清除速度快产生大量内存碎片老年代 CMS 使用复制算法无碎片需要预留一半内存新生代 Minor GC标记整理无碎片移动对象开销大老年代 G1、Serial Old25. 泛型extends T vs ? super T维度读写、使用场景? extends T上界通配符只能读不能写生产者场景 (获取数据)? super T下界通配符只能写不能读消费者场景 (存入数据)PECS 原则Producer ExtendsConsumer Super26. Iterator 迭代器 vs fori 普通循环维度并发修改、遍历范围、索引操作Iterator遍历中调用迭代器 remove 安全无下标无法精准定位元素fori 循环可获取下标支持随机访问遍历内集合 add/remove 触发并发修改异常27. Transactional public 方法 vs private 方法维度AOP 拦截、事务生效publicSpring AOP 动态代理可拦截事务正常生效private代理无法拦截私有方法注解失效无事务控制28. new Thread () 手动创建 vs 线程池 ThreadPoolExecutor维度复用、开销、管控、拒绝策略new Thread线程一次性频繁创建销毁开销巨大无线程管控线程无限暴涨无限制线程池复用线程控制最大并发、阻塞队列、拒绝策略统一管控异步任务生产环境强制使用29. List.subList () vs 新建 ArrayList 拷贝集合维度数据关联、内存、修改影响subList原集合视图不创建新对象修改分片 / 原集合互相影响clear 仅清空视图不释放原数据new ArrayList(list)完整拷贝新集合数据完全隔离互不影响占用双倍内存30. 串行流 stream () vs 并行流 parallelStream ()维度线程池、顺序、IO 任务、数据量、性能串行流单线程执行有序无全局线程池抢占适合小数据、有序业务逻辑并行流ForkJoin 公共池多线程不保证遍历顺序适合纯内存大数据计算禁止 IO、RPC 阻塞任务会污染全局并行任务池

相关新闻