Java基础与集合框架

面向对象编程特性深度解析

在Java面试题库中,面向对象(OOP)是必考的基础板块。面试官不仅关注你对封装、继承、多态的定义,更侧重于实际场景中的应用。例如,多态如何通过方法重写和方法重载实现?继承中构造函数的调用顺序是怎样的?

【封装】不仅仅是私有化字段,还包括通过Getter/Setter进行数据校验;【继承】强调代码复用,但过度继承会导致耦合度高,建议优先使用组合而非继承;【多态】是Java灵活性的核心,它允许父类引用指向子类对象,实现运行时多态,关键在于动态绑定。

基本数据类型与包装类

Java提供了8种基本数据类型,面试中常问Integer缓存机制。Integer在-128到127之间会复用对象,超出范围则新建对象。这是面试中区分初级与中级开发者的关键点。

Integer a = 127; Integer b = 127; System.out.println(a == b); // true, 缓存池命中 Integer c = 128; Integer d = 128; System.out.println(c == d); // false, 新建对象

HashMap底层原理与线程安全

HashMap是Java面试题库中出现频率极高的考点。它基于哈希表实现,允许null键和null值。在JDK 1.8中,当链表长度超过8且数组长度超过64时,链表会转换为红黑树,以提高查询效率从O(n)提升至O(log n)。

面试官常问:为什么HashMap不是线程安全的?因为并发put可能导致数据覆盖或死循环(JDK 1.7)。解决方案包括使用ConcurrentHashMap,它通过分段锁(JDK 1.7)或CAS+synchronized(JDK 1.8)实现高并发下的线程安全。

ArrayList vs LinkedList

ArrayList基于动态数组,支持随机访问,查询快,增删慢(需移动元素)。LinkedList基于双向链表,增删快,查询慢(需遍历)。面试中应根据业务场景选择,大多数情况下推荐使用ArrayList。

HashSet去重原理

HashSet底层由HashMap实现。添加元素时,计算哈希值确定桶位置,若桶为空直接放入;若冲突,则比较equals()。因此,自定义对象需重写hashCode()和equals()方法。

异常体系与处理机制

Java异常分为受检异常(Checked Exception)和非受检异常(RuntimeException)。受检异常必须在编译期处理,如IOException;非受检异常是编程错误,如NullPointerException,无需强制处理。

面试中常问:try-catch-finally中,如果try和finally都有return,哪个生效?答案是finally。但如果finally中修改了基本数据类型返回值,不会影响try中的返回值(因为值已拷贝),但修改引用类型内容会影响。

多线程与并发编程

线程生命周期与状态转换

Java线程有6种状态:NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED。面试中需理解这些状态的转换条件,例如wait()进入WAITING,sleep()进入TIMED_WAITING,join()可能导致BLOCKED或WAITING。

【RUNNABLE】状态包含Ready和Running,操作系统调度决定具体运行状态。Java线程模型依赖于底层操作系统的原生线程实现(1:1模型)。

创建线程的四种方式

1. 继承Thread类;2. 实现Runnable接口;3. 实现Callable接口(有返回值);4. 线程池创建。推荐使用线程池,避免资源浪费。面试中常问:为什么实现Runnable比继承Thread好?因为Java单继承限制,且Runnable更符合面向对象设计(分离任务与执行)。

ConcurrentHashMap源码解析

ConcurrentHashMap在JDK 1.8中摒弃了分段锁,采用Node数组+链表+红黑树,并使用CAS+synchronized保证线程安全。putVal方法中,首先通过CAS插入首个节点,若桶位已有元素,则synchronized锁住链表或树头节点进行插入。

sizeCtl变量控制初始化及扩容行为。扩容时,多线程协作迁移数据,提高效率。

ReentrantLock vs synchronized

synchronized是JVM层面实现,自动加锁解锁;ReentrantLock是API层面实现,需手动lock/unlock。ReentrantLock支持公平锁、非公平锁、可中断锁、条件变量,更灵活但易死锁。

CountDownLatch vs CyclicBarrier

CountDownLatch用于一个线程等待多个线程完成(不可重用);CyclicBarrier用于多个线程互相等待到达屏障点(可重用)。

AQS原理与LockSupport

AQS(AbstractQueuedSynchronizer)是构建锁和同步器的核心框架。它使用一个int类型的state变量表示同步状态,通过FIFO队列管理等待线程。ReentrantLock、CountDownLatch等底层均基于AQS。

LockSupport.park()和unpark()用于线程阻塞与唤醒,不依赖同步器,可跨线程操作。

JVM虚拟机深度解析

Java内存区域划分

JVM内存分为线程私有(程序计数器、虚拟机栈、本地方法栈)和线程共享(堆、方法区/元空间)。堆是GC主要区域,分为新生代(Eden, S0, S1)和老年代。方法区存储类信息、常量、静态变量,JDK 8后使用元空间(本地内存)。

面试常问:OOM(OutOfMemoryError)常见原因?堆内存不足(大对象、内存泄漏)、栈溢出(递归过深)、元空间不足(加载类过多)。

垃圾回收算法与收集器

【标记-清除】:产生碎片;【标记-复制】:新生代使用,效率高;【标记-整理】:老年代使用。主流收集器包括Serial、ParNew、Parallel Scavenge、CMS、G1、ZGC。

G1(Garbage-First)是JDK 9默认收集器,将堆划分为多个Region,可预测停顿时间,避免全堆扫描。面试中需了解G1的混合回收(Mixed GC)过程。

如何判断对象可回收

引用计数法(有循环引用问题,Java不用);可达性分析法(GC Roots出发,不可达则回收)。GC Roots包括:虚拟机栈局部变量、方法区静态属性、常量、JNI引用。

强软弱虚引用

强引用(Strong):不回收;软引用(Soft):内存不足时回收;弱引用(Weak):GC时回收;虚引用(Phantom):配合引用队列,用于对象回收通知。

类加载过程

加载、验证、准备、解析、初始化。准备阶段为静态变量分配内存并赋默认值;初始化阶段执行<clinit>方法,赋初始值。双亲委派模型:类加载器向上委托,除非父加载器无法找到。

破坏双亲委派:Tomcat、Spring Boot等框架通过自定义类加载器实现隔离和热部署。

Spring生态与微服务

IoC与DI原理

IoC(控制反转)将对象创建权交给Spring容器;DI(依赖注入)是IoC的实现方式,通过构造函数、Setter、字段注入。Spring Bean生命周期:实例化、属性赋值、初始化(Aware接口、BeanPostProcessor前置、init-method、BeanPostProcessor后置)、销毁。

BeanPostProcessor是Spring扩展点,可用于AOP代理创建。

AOP面向切面编程

AOP用于横切关注点(日志、事务、安全)模块化。Spring AOP基于动态代理:JDK动态代理(接口)和CGLIB(子类)。@AspectJ注解支持声明式切面。

事务传播行为:REQUIRED(默认,加入现有事务)、REQUIRES_NEW(新建事务)、NESTED(嵌套事务)等。

自动装配原理

Spring Boot通过@SpringBootApplication注解,结合@EnableAutoConfiguration,扫描classpath下META-INF/spring.factories文件,加载自动配置类。@Conditional注解控制条件装配(如@ConditionalOnClass)。

Starter依赖:将常用依赖打包,简化配置。如spring-boot-starter-web包含Tomcat、Spring MVC等。

微服务架构组件

【注册中心】:Eureka、Nacos、Consul,服务发现与注册。【配置中心】:Spring Cloud Config、Nacos,统一管理配置。【网关】:Spring Cloud Gateway,路由过滤、限流。【熔断降级】:Sentinel、Hystrix,防止雪崩效应。【分布式事务】:Seata、TCC、本地消息表。

面试中常问:微服务拆分粒度如何把握?按业务领域(DDD)拆分,避免过细导致运维复杂,过粗导致耦合度高。

数据库与Redis缓存

索引优化与B+树

MySQL索引基于B+树实现,非叶子节点只存键值,叶子节点存数据,适合范围查询。聚簇索引(主键)与二级索引(非主键,回表)。联合索引遵循最左前缀原则。

覆盖索引:查询列包含在索引中,无需回表。EXPLAIN分析执行计划,关注type(ALL, index, range, ref, eq_ref, const)、key、rows。

事务隔离级别

读未提交、读已提交(Oracle默认)、可重复读(MySQL默认,解决幻读通过MVCC+间隙锁)、串行化。MVCC通过undo log和Read View实现。

锁机制

共享锁(S)、排他锁(X)、间隙锁(Gap)、临键锁(Next-Key)。死锁检测与回滚。

Redis数据结构与应用场景

String:缓存、计数器;Hash:对象存储;List:消息队列;Set:去重、交集;ZSet:排行榜。持久化:RDB(快照)和AOF(日志),混合持久化(Redis 4.0+)。

缓存穿透(查不存在数据):布隆过滤器、缓存空值;缓存击穿(热点key过期):互斥锁、逻辑过期;缓存雪崩(大量key过期):随机过期时间、集群。

分布式锁实现

基于Redis SETNX命令实现,需设置过期时间防止死锁。Redlock算法解决单点故障问题。ZooKeeper也可实现分布式锁,基于临时顺序节点。

面试备考时间轴

第1-2周:夯实基础

Java基础与集合

复习基本数据类型、String、集合框架(HashMap、ArrayList)、IO/NIO、反射、注解。完成LeetCode简单题10道。

第3-4周:深入并发与JVM

多线程与虚拟机

深入线程池、Lock、AQS、CAS。理解JVM内存模型、GC算法、类加载。阅读《深入理解Java虚拟机》核心章节。

第5-6周:框架与数据库

Spring与MySQL

掌握Spring IoC/AOP、事务。MySQL索引优化、事务隔离、锁机制。Redis数据结构、缓存场景、分布式锁。

第7-8周:微服务与项目复盘

微服务与项目亮点

学习Spring Cloud组件,理解服务注册、配置、网关、熔断。复盘项目经历,准备STAR法则案例。模拟面试,查漏补缺。