Java基础是技术面试的起点,其中集合框架的考察频率尤为突出。Java集合体系主要分为两大分支:java.util包下的非线程安全集合与java.util.concurrent包中的线程安全集合。理解两者的设计差异,是应对集合类面试题的关键。
ArrayList与LinkedList作为List接口的核心实现类,其差异贯穿底层数据结构与使用场景。ArrayList基于动态数组实现,支持O(1)时间复杂度的随机访问,但插入/删除操作(尤其在中间位置)需移动元素,时间复杂度升至O(n);LinkedList采用双向链表结构,插入/删除仅需调整相邻节点指针(O(1)),但随机访问需遍历链表(O(n))。实际开发中,若需频繁随机访问应优先选择ArrayList,而频繁增删操作则更适合LinkedList。
HashMap作为最常用的键值对存储结构,其底层通过“数组+链表+红黑树”实现。当哈希冲突发生时,JDK1.8前仅用链表解决,当链表长度超过8且数组长度≥64时,链表会转换为红黑树(时间复杂度从O(n)优化至O(logn))。扩容机制触发于元素数量超过“容量×负载因子”(默认0.75),扩容时采用2的幂次长度(如初始16→32),通过位运算替代取模操作提升效率。
LinkedHashMap在HashMap基础上增加双向链表,支持插入顺序或访问顺序排序(通过构造参数accessOrder控制),这一特性使其成为实现LRU(最近最少使用)缓存的理想选择——当元素被访问时调整至链表尾部,容量不足时移除头部最久未使用元素。
TreeMap基于红黑树实现,要求键对象必须实现Comparable接口(或通过构造器传入Comparator),以元素有序。其在一致性哈希算法中应用广泛,通过将节点哈希值映射到环上,利用TreeMap的有序性快速定位数据存储节点。
并发编程是Java技术栈的高阶考察点,涉及锁机制、原子操作、线程同步等核心概念。掌握synchronized、CAS、AQS等底层原理,是应对并发类面试题的关键。
synchronized作为Java内置锁,其实现经历偏向锁→轻量级锁→重量级锁的升级过程。偏向锁通过记录线程ID减少无竞争场景的开销;当多线程竞争时升级为轻量级锁(通过CAS自旋尝试获取);竞争激烈时进一步升级为重量级锁(依赖操作系统Mutex)。与ReentrantLock相比,synchronized自动释放锁(作用域结束),而ReentrantLock支持可中断、超时获取及公平/非公平策略,灵活性更高。
CAS(Compare-And-Swap)是原子类(如AtomicInteger)的核心实现机制,通过“比较-交换”原子操作实现无锁编程。但需注意ABA问题(通过AtomicStampedReference添加版本号解决),且在高竞争场景下自旋次数过多会导致性能下降。
AbstractQueuedSynchronizer(AQS)是ReentrantLock、Semaphore等同步工具的底层框架。其通过volatile变量state表示同步状态,配合CLH队列管理等待线程。当线程尝试获取锁失败时,会被封装为节点加入队列尾部,并通过LockSupport.park()挂起;释放锁时唤醒队首节点(unpark)。
基于AQS实现的典型组件包括:
ThreadPoolExecutor的核心参数包括:corePoolSize(核心线程数)、maximumPoolSize(线程数)、keepAliveTime(非核心线程空闲超时时间)、workQueue(任务队列)及handler(拒绝策略)。任务提交时,若核心线程未满则创建新线程;否则加入队列;队列满则创建非核心线程;若线程数达值则执行拒绝策略(默认AbortPolicy)。
高频问题示例:
随着技术栈的扩展,中间件与存储系统(如Spring、Redis、MySQL)的考察占比逐渐增加。理解其设计原理与常见问题,是突破中高级面试的关键。
Spring的Bean生命周期包含实例化→属性注入→初始化(Aware接口回调→BeanPostProcessor前置处理→init-method→BeanPostProcessor后置处理)→销毁(destroy-method)四个阶段。循环依赖问题在构造器注入中无法解决(实例化阶段已需依赖),但属性注入可通过三级缓存(singletonFactories)解决——提前暴露未完全初始化的Bean。
AOP通过动态代理实现:若目标类实现接口则用JDK动态代理(基于接口),否则用CGLIB(基于继承)。事务传播机制定义了不同方法调用时的事务行为(如REQUIRED:当前有事务则加入,否则新建;REQUIRES_NEW:新建独立事务)。
Redis作为高性能内存数据库,其单线程模型(处理命令)+多线程(持久化、集群)设计确保了高并发能力。持久化支持RDB(快照,全量备份)与AOF(日志,增量记录),可通过配置混合使用。分布式锁通过set命令的NX(仅当键不存在时设置)+EX(过期时间)实现,需注意锁的原子性(Lua脚本释放时校验Owner)。
MySQL的InnoDB引擎采用B+树作为索引结构,其叶子节点存储完整数据(聚簇索引)或主键(非聚簇索引)。最左匹配原则要求联合索引的查询条件需从左到右依次匹配,否则无法使用索引。慢查询优化可通过EXPLAIN分析执行计划,重点关注type(访问类型)、key(实际使用索引)等字段。
RocketMQ通过主从架构(Master/Slave)高可用,消息顺序通过同一主题下的MessageQueue绑定实现(局部有序)。事务消息采用两阶段提交:先发送Prepared消息,执行本地事务后提交/回滚,未确认的消息通过回查机制补偿。
ZooKeeper基于ZAB协议实现分布式协调,其临时节点特性可用于Master选举(节点失效自动删除,触发重新选举)。分布式锁通过创建有序临时节点,判断当前节点是否为最小节点(是则获取锁,否则监听前一节点)。
Java面试考察范围广、深度大,建议采用“分层突破”策略:先夯实基础(集合、并发),再攻克核心(JVM、Spring),最后扩展中间件(Redis、MySQL)。对于算法部分,可通过LeetCode刷100-200道Easy/Medium题,重点掌握链表、二叉树、动态规划等高频题型。
面试时需注重“知其然更知其所以然”,例如被问及“HashMap为何用红黑树”时,需结合哈希冲突概率(泊松分布)、链表与红黑树的时间复杂度对比等底层原理作答。同时,结合项目经验说明技术应用场景(如用LinkedHashMap实现LRU缓存),可显著提升回答的说服力。