一、JVM底层原理与性能调优
在 java面试宝典2021 中,JVM(Java虚拟机)是必考的核心模块。面试官不仅关注你对内存模型的理论掌握,更重视实际OOM排查和GC调优经验。
1.1 JVM内存区域划分
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。根据《Java虚拟机规范》,这些区域有的随虚拟机启动而创建,有的则随用户线程启动和结束而建立和销毁。
| 内存区域 | 线程共享/私有 | 生命周期 | 异常类型 |
|---|---|---|---|
| 程序计数器 | 线程私有 | 线程生命周期 | 无 |
| Java虚拟机栈 | 线程私有 | 线程生命周期 | StackOverflowError, OutOfMemoryError |
| 本地方法栈 | 线程私有 | 线程生命周期 | StackOverflowError, OutOfMemoryError |
| Java堆 | 线程共享 | 虚拟机生命周期 | OutOfMemoryError |
| 方法区 | 线程共享 | 虚拟机生命周期 | OutOfMemoryError |
1.1.1 堆内存详解
堆是JVM所管理的内存中最大的一块,是被所有线程共享的内存区域。在 java面试宝典2021 中,堆内存的划分是重点。现代JVM将堆分为新生代和老年代。新生代又分为Eden区和两个Survivor区(From和To)。
- Eden区:新对象创建的默认区域,大部分对象在这里生命周期结束。
- Survivor区:用于复制算法,存活对象在两个Survivor区间移动。
- 老年代:存放生命周期较长的对象,如长期存活的缓存对象。
1.2 垃圾回收算法与垃圾收集器
垃圾回收(Garbage Collection, GC)是JVM自动管理内存的核心机制。判断对象是否存活主要有两种方法:引用计数法和可达性分析算法。
1.2.1 可达性分析算法
JVM通过“GC Roots”作为起始点,沿着引用链向下搜索,若某对象到GC Roots没有任何引用链相连,则证明该对象是不可用的。可作为GC Roots的对象包括:
- 虚拟机栈中引用的对象(局部变量表)
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI引用的对象
1.2.2 常见垃圾收集器对比
| 收集器 | 算法 | 适用区域 | 特点 |
|---|---|---|---|
| Serial | 标记-复制 | 新生代 | 单线程,简单高效 |
| ParNew | 标记-复制 | 新生代 | Serial的多线程版本 |
| Parallel Scavenge | 标记-复制 | 新生代 | 吞吐量优先,适合后台计算 |
| Serial Old | 标记-整理 | 老年代 | 单线程,CMS的后备方案 |
| Parallel Old | 标记-整理 | 老年代 | 多线程,吞吐量优先 |
| CMS | 标记-清除 | 老年代 | 低延迟,但产生内存碎片 |
| G1 | 标记-整理 | 全区域 | 可预测停顿,现代JVM默认 |
1.3 性能调优实战
在 java面试宝典2021 中,调优经验是区分初级和中高级开发者的关键。常见的调优目标包括:缩短GC停顿时间(Stop-The-World)、提高吞吐量、减少内存占用。
1.3.1 常用JVM参数
1.3.2 OOM排查步骤
当发生OutOfMemoryError时,首先通过jmap -dump:format=b,file=heap.hprof <pid>导出堆转储文件,然后使用MAT(Memory Analyzer Tool)或JVisualVM进行分析,重点查看Dominators树,定位大对象和内存泄漏点。
二、多线程与并发编程核心
高并发是Java后端开发的核心竞争力。本章节梳理了 java面试宝典2021 中关于线程池、锁机制、JUC包及CAS原理的深度解析。
线程池工作流程详解
三、Spring全家桶核心机制
Spring框架是企业级Java开发的事实标准。在 java面试宝典2021 中,Spring IoC、AOP、事务管理及Spring Boot自动装配原理是高频考点。
3.1 IoC与AOP深度解析
IoC(控制反转) 是Spring的基石,通过DI(依赖注入)将对象创建和依赖关系管理交给Spring容器,降低了组件间的耦合度。主要注入方式包括构造器注入、Setter注入和字段注入(@Autowired)。
AOP(面向切面编程) 基于动态代理实现,Spring默认使用JDK动态代理(接口)和CGLIB(类)。AOP常用于事务管理、日志记录、权限校验等横切关注点。
3.2 Spring Bean生命周期
| 阶段 | 说明 | 关键接口/方法 |
|---|---|---|
| 实例化 | 通过构造函数或工厂方法创建Bean实例 | InstantiationAwareBeanPostProcessor |
| 属性填充 | 注入依赖属性,处理@Value、@Autowired | AutowiredAnnotationBeanPostProcessor |
| 初始化前置 | BeanPostProcessor.postProcessBeforeInitialization | BeanPostProcessor |
| 初始化 | 执行init-method或InitializingBean.afterPropertiesSet | InitializingBean, @PostConstruct |
| 初始化后置 | BeanPostProcessor.postProcessAfterInitialization | BeanPostProcessor (AOP代理创建点) |
| 销毁 | 容器关闭时执行销毁逻辑 | DisposableBean, @PreDestroy |
3.3 Spring Boot自动装配原理
Spring Boot的核心在于@SpringBootApplication注解,它组合了@Configuration、@EnableAutoConfiguration和@ComponentScan。自动装配通过@EnableAutoConfiguration加载META-INF/spring.factories文件中的配置类,根据@Conditional注解的条件判断是否加载相应的Bean。
四、MySQL与Redis实战优化
4.1 MySQL索引优化策略
索引是提升查询性能的关键。MySQL默认使用B+树作为索引结构,InnoDB引擎支持聚簇索引和非聚簇索引(二级索引)。
4.1.1 最左前缀法则
联合索引(a, b, c)遵循最左前缀匹配原则。查询条件必须从左到右连续匹配,若跳过中间列,则后续列无法使用索引。
4.1.2 覆盖索引与回表
若查询的列都在索引树中,称为覆盖索引,无需回表查询,性能极高。否则需通过主键ID回表查询,增加I/O开销。
4.1.3 索引失效场景
- 对索引列进行函数运算或表达式计算
- 隐式类型转换(如字符串字段不加引号)
- 模糊查询以%开头(如LIKE '%abc')
- OR连接的条件中有一方无索引
4.2 事务隔离级别与MVCC
MySQL InnoDB支持四种事务隔离级别:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)、串行化(Serializable)。默认级别为可重复读。
MVCC(多版本并发控制) 是InnoDB实现高并发和隔离性的核心机制。通过Undo Log保存数据的历史版本,结合Read View(读视图)判断数据的可见性,从而实现非阻塞的快照读。
4.3 Redis缓存架构设计
Redis作为高性能键值存储,在 java面试宝典2021 中常与MySQL结合使用,解决高并发读场景。
4.3.1 缓存穿透与击穿
- 缓存穿透:查询不存在的数据,绕过缓存直接查DB。解决方案:布隆过滤器或缓存空值。
- 缓存击穿:热点Key过期瞬间大量请求直达DB。解决方案:互斥锁或逻辑过期。
- 缓存雪崩:大量Key同时过期或Redis宕机。解决方案:随机过期时间或多级缓存。
4.3.2 数据一致性方案
保证Redis与MySQL数据一致性的常见策略有:先更新DB再删除缓存(Cache Aside Pattern)、延迟双删、订阅Binlog异步更新。
五、分布式与微服务架构
随着业务规模扩大,单体架构难以满足需求。Spring Cloud + Dubbo构成的微服务生态成为主流。本章节涵盖服务注册发现、负载均衡、熔断降级、分布式事务等核心概念。