目录1. Java 四种引用类型区别与场景2. HashMap 底层原理JDK 1.7 和 1.8 差异3. ConcurrentHashMap 实现原理4. ArrayList 扩容机制与 Arrays.asList 坑点5. Java8 Stream 常用操作与注意事项6. ThreadLocal 原理、内存泄漏原因与解决7. volatile 作用能否保证原子性8. CAS 原理、ABA 问题、Atomic 原子类9. ThreadPoolExecutor 七大参数、拒绝策略10. JVM 类加载过程、双亲委派及破坏场景11. JVM 内存结构堆、栈、元空间区别12. 垃圾回收算法与 G1/ZGC 特点13. Spring IoC 原理、Bean 生命周期14. Spring AOP、JDK 与 CGLIB 动态代理区别15. Spring 事务传播机制、隔离级别16. 事务失效常见场景17. SpringBoot Starter 自动配置原理1. Java 四种引用类型区别与场景引用类型回收时机主要场景强引用永不回收除非无引用可达普通Object obj new Object()软引用内存不足时回收缓存如图片缓存配合SoftReference弱引用下次 GC 时必回收WeakHashMap、ThreadLocal 中的 Key虚引用任何时候都可能被回收无法通过它获得对象跟踪对象回收状态管理直接内存如 NIO ByteBuffer补充软/弱引用需配合ReferenceQueue使用以便在对象被回收后清理相关资源。2. HashMap 底层原理JDK 1.7 和 1.8 差异底层结构1.7数组 单向链表。1.8数组 链表 红黑树链表长度 ≥8 且数组长度 ≥64 时转红黑树节点数 ≤6 退化为链表。哈希计算1.8 扰动简化高 16 位异或低 16 位一次1.7 多次扰动。扩容机制1.7扩容时头插法多线程下可能形成环形链表导致 CPU 100%。1.8尾插法避免死链通过hash oldCap判断元素在新数组的位置高位链移至原索引旧容量处。线程安全两者均非线程安全并发下应使用ConcurrentHashMap。3. ConcurrentHashMap 实现原理JDK 1.7分段锁Segment默认 16 个 Segment每个 Segment 内是小型 HashMap独立加锁ReentrantLock并发度 16。JDK 1.8CAS synchronized锁粒度细化到桶的首节点。put时若桶为空用 CAS 尝试直接插入若桶非空对首节点加synchronized锁再进行插入/更新。扩容支持多线程协同每个线程负责迁移一部分桶。同样采用红黑树优化链表过长问题。与 Hashtable 区别Hashtable 锁整个表并发度极低ConcurrentHashMap 锁粒度细不允许 null 键/值。4. ArrayList 扩容机制与 Arrays.asList 坑点扩容机制默认初始容量 10或指定。添加元素时若容量不足会调用grow新容量 oldCapacity (oldCapacity 1)即 1.5 倍然后Arrays.copyOf复制到新数组。Arrays.asList 坑点返回的是Arrays内部类ArrayList不是java.util.ArrayList是固定大小的列表不支持add/remove否则抛UnsupportedOperationException。数组修改会影响列表内容因为底层共用同一个数组。建议需要可变列表时用new ArrayList(Arrays.asList(...))包装。5. Java8 Stream 常用操作与注意事项常用操作中间操作惰性filter、map、flatMap、distinct、sorted、limit、skip。终端操作触发计算collect、forEach、reduce、count、anyMatch、findFirst。注意事项Stream不存储数据不修改数据源只能消费一次用完就关闭再使用抛异常。parallelStream并行流使用共享的ForkJoinPool注意线程安全问题尽量避免在并行流中修改外部非线程安全集合。forEach不保证顺序并行时如需顺序输出用forEachOrdered。collect归约常用Collectors.toList()、groupingBy、partitioningBy。6. ThreadLocal 原理、内存泄漏原因与解决原理每个Thread内部维护一个ThreadLocalMapKey 是ThreadLocal的弱引用Value 是实际存放的值。get()时通过当前线程获取 Map 取值。内存泄漏原因ThreadLocal 被回收后Key 变成了 null但Value 依然被 Entry 强引用且 Entry 被 Thread 的 Map 引用。若线程不结束如线程池中的线程这些 Value 永远无法被 GC造成内存泄漏。解决方法使用完必须调用remove()方法显式清除 Entry。ThreadLocalMap 在get/set时会启发式清理部分 key 为 null 的 entry但不能完全依赖。7. volatile 作用能否保证原子性两大作用可见性一个线程修改 volatile 变量后会立即刷新到主内存并通知其他线程缓存行失效保证读操作获取最新值。禁止指令重排通过内存屏障LoadStore、StoreStore 等防止 volatile 变量与其他操作的顺序被重排。能否保证原子性不能。例如count是“读-改-写”复合操作volatile 不能保证这三步不被中断。需要原子性应使用AtomicInteger或synchronized。8. CAS 原理、ABA 问题、Atomic 原子类CAS 原理Compare And Swap。比较内存当前值 V 与期望值 A如果相等则更新为 B否则不更新。是 CPU 级原子指令cmpxchg。ABA 问题变量从 A 改成 B又改回 ACAS 无法感知以为没变。解决使用版本号/时间戳如AtomicStampedReference或AtomicMarkableReference。Atomic 原子类AtomicInteger、AtomicLong、AtomicReference等底层用 CAS 循环重试自旋保证原子操作无锁适合并发竞争不激烈的场景。LongAdder高并发下比AtomicLong性能更好采用分段累加思想最后求和。9. ThreadPoolExecutor 七大参数、拒绝策略七大参数corePoolSize核心线程数maximumPoolSize最大线程数keepAliveTime非核心线程空闲存活时间unit时间单位workQueue工作队列如LinkedBlockingQueue、ArrayBlockingQueuethreadFactory线程工厂命名handler拒绝策略拒绝策略4 种AbortPolicy默认抛RejectedExecutionException异常CallerRunsPolicy由提交任务的线程自己执行产生反压DiscardPolicy静默丢弃任务DiscardOldestPolicy丢弃队列中最旧的任务重新提交当前任务10. JVM 类加载过程、双亲委派及破坏场景加载过程5 步加载通过类全限定名获取二进制字节流转为方法区运行时数据结构生成Class对象。验证文件格式、元数据、字节码、符号引用验证。准备为静态变量分配内存并赋零值final static修饰的常量直接赋定义值。解析将常量池内的符号引用替换为直接引用。初始化执行clinit方法初始化静态变量和静态代码块。双亲委派模型类加载器收到加载请求时先委托父加载器尝试加载只有父加载器无法加载时子加载器才自己加载。目的是保证核心库的类型安全如java.lang.String。破坏场景JDBC 引入线程上下文类加载器Thread.currentThread().getContextClassLoader()打破让父加载器可以请求子加载器加载类SPI 机制。Tomcat 类加载器打破实现 Web 应用的隔离与热部署。OSGi 模块化热替换网状委派结构。11. JVM 内存结构堆、栈、元空间区别堆存放对象实例和数组线程共享GC 主战场。细分新生代Eden Survivor、老年代。虚拟机栈线程私有每个方法对应一个栈帧存储局部变量表基本类型、对象引用、操作数栈、动态链接、返回地址等。会出现StackOverflowError。元空间JDK8取代永久代使用本地内存存放类元信息、运行时常量池、静态变量、JIT 代码缓存等线程共享。避免永久代 OOM但受本地内存大小限制。12. 垃圾回收算法与 G1/ZGC 特点常用算法标记-清除标记存活清除未标记。产生碎片。标记-复制分两块区域将存活对象复制到另一块清空原区。用于新生代无碎片浪费空间。标记-整理标记后存活对象向一端移动清理边界外内存。用于老年代无碎片耗时长。G1 特点将堆划分为多个 Region兼顾吞吐量与低延迟可设置暂停时间目标。采用并发标记、混合回收优先回收价值最高的 RegionGarbage First。使用SATBSnapshot-At-The-Beginning标记算法保证并发阶段一致性。ZGC 特点基于染色指针Colored Pointers和读屏障实现并发标记-整理暂停时间 1ms且停顿时间不随堆大小增加支持 TB 级堆。13. Spring IoC 原理、Bean 生命周期IoC 原理控制反转通过DI依赖注入实现。Spring 容器ApplicationContext在初始化时创建并管理 Bean通过反射、工厂等完成依赖组装。配置方式包括 XML、注解、Java Config。Bean 生命周期简化版实例化反射创建 Bean 实例。属性填充populateBean注入属性值和依赖。初始化若实现*Aware接口则回调如BeanNameAwarePostConstruct方法InitializingBean#afterPropertiesSet自定义init-method。使用Bean 就绪。销毁PreDestroy、DisposableBean#destroy、destroy-method。14. Spring AOP、JDK 与 CGLIB 动态代理区别AOP 原理基于动态代理在目标方法执行前后插入增强Advice。JDK 动态代理基于接口反射生成代理类要求被代理对象必须实现接口。通过Proxy.newProxyInstance和InvocationHandler实现。CGLIB 代理通过修改字节码生成目标类的子类适用于无接口的类。不能代理final类或final方法。Spring 选择策略默认目标实现了接口用 JDK 代理否则用 CGLIB。可通过proxy-target-classtrue强制使用 CGLIB。Spring Boot 2.x 默认使用 CGLIB即使有接口。15. Spring 事务传播机制、隔离级别传播机制7 种REQUIRED默认有则加入无则新建。SUPPORTS有则加入无则非事务运行。MANDATORY有则加入无则抛异常。REQUIRES_NEW永远新建事务挂起当前。NOT_SUPPORTED非事务运行挂起当前事务。NEVER非事务运行有事务则抛异常。NESTED嵌套事务保存点回滚。隔离级别DEFAULT使用数据库默认、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE。16. 事务失效常见场景未开启事务管理如 Spring Boot 没加EnableTransactionManagement。方法非 publicAOP 无法代理私有方法。自调用同类中方法内部调用this.method()不走代理事务失效。解决注入自身Autowired自己或抽到另一个类。异常被吞try-catch未抛出运行时异常默认仅回滚RuntimeException和Error。回滚异常类型不匹配抛出受检异常未指定Transactional(rollbackFor Exception.class)。数据库引擎不支持事务如 MyISAM。多线程Transactional不能跨线程传播。传播行为设置错误如NOT_SUPPORTED、NEVER。17. SpringBoot Starter 自动配置原理入口SpringBootApplication内含EnableAutoConfiguration。过程EnableAutoConfiguration通过Import加载AutoConfigurationImportSelector。选择器利用SpringFactoriesLoader读取所有 jar 包下的META-INF/spring.factories获取 key 为EnableAutoConfiguration的配置类列表。对每个配置类根据ConditionalOnClass、ConditionalOnMissingBean、ConditionalOnProperty等条件注解决定是否加载该 Bean。满足条件的配置类自动创建 Bean 并注册到容器如DataSourceAutoConfiguration根据 classpath 和配置自动创建数据源。自定义 Starter编写一个AutoConfiguration类并在spring.factories中注册封装默认 Bean 和属性绑定。