news 2026/8/31 2:43:27

Java后端面试高频考点清单:集合/并发/MySQL/Redis全覆盖

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java后端面试高频考点清单:集合/并发/MySQL/Redis全覆盖

8月是Java后端面试的高峰期,也是很多人最容易焦虑的一段时间。一方面岗位竞争确实激烈,另一方面面试考察的范围又很散:Java基础、集合源码、并发编程、JVM、Spring、MySQL、Redis、消息队列、系统设计,几乎每一块都可能被问到。与其漫无目的地刷题,不如先建立一张高频考点地图,知道大厂面试官真正关心什么,再按优先级逐个击破。

这篇文章不是简单的题库堆砌,而是一份可以直接照着准备的Java后端面试高频题梳理清单。我会按Java基础、集合框架、并发编程、JVM、Spring、MySQL、Redis、消息队列与分布式这几个大方向展开,每个模块给出核心考点、高频问题、答题思路和容易踩的坑。文章末尾还会给出一套面试答题框架和备考节奏建议,帮助你从“会做题”过渡到“能讲清楚原理”。

适合正在准备Java后端实习、校招、社招的读者。无论你是刚开始复习,还是已经进入刷题冲刺阶段,都可以把这份清单作为自检表,对着它逐项排查自己的知识盲区。

1. Java后端面试核心考点速览

先给一张总览表,方便你在复习时核对覆盖面。

考点模块高频面试题方向优先级预计复习耗时
Java基础String、equals与hashCode、泛型、异常、反射3-5天
集合框架ArrayList、LinkedList、HashMap、ConcurrentHashMap极高5-7天
并发编程synchronized、volatile、CAS、线程池、锁、AQS极高7-10天
JVM内存区域、垃圾回收、类加载、调优、OOM排查7-10天
SpringIOC、AOP、Bean生命周期、循环依赖、事务极高5-7天
MySQL索引、事务、隔离级别、MVCC、锁、SQL优化极高7-10天
Redis数据结构、持久化、过期策略、缓存穿透击穿雪崩5-7天
消息队列与分布式MQ选型、消息可靠性、幂等、分布式事务、分布式锁中高5-7天
算法与代码题字符串、链表、二叉树、动态规划、LRU持续刷题

这个列表基本覆盖了当前Java后端面试的主流考察范围。从近期面试反馈来看,HashMap与并发编程是出现频率最高的两个方向,建议优先复习。

2. 适合人群与面试准备节奏

2.1 谁需要重点准备这些面试题

第一类是准备校招和实习的应届生。校招面试通常更看重基础是否扎实,尤其是Java集合源码、并发编程、JVM和MySQL索引这部分,面试官会通过连续追问来判断你是不是背答案,而是真正理解原理。

第二类是准备跳槽的社招开发。社招面试除了基础题,还会增加项目经验、系统设计、线上问题排查等内容,但基础题依然是第一轮和第二轮的筛选项,基础不过关,项目再丰富也很难进入后续环节。

第三类是准备转岗后端开发的测试、前端或运维同学。这部分读者最需要的是系统化的考点地图,因为零散刷题很难形成完整知识体系,反而容易越刷越慌。

2.2 推荐的复习节奏

如果你离面试还有4到8周,可以按下面的节奏安排:

  • 第1周:Java基础 + 集合框架,配合源码阅读。
  • 第2周:并发编程,重点理解synchronized、volatile、AQS和线程池。
  • 第3周:JVM内存与垃圾回收,配合线上OOM排查案例。
  • 第4周:Spring核心 + MySQL,这两个方向在面试中占比很大。
  • 第5周:Redis + 消息队列 + 分布式。
  • 第6周:算法题专项 + 模拟面试 + 项目复盘。

如果你只有1到2周,那就优先吃透集合、并发、Spring、MySQL这四个模块,它们是Java后端面试的“基本盘”。

3. Java基础高频面试题梳理

3.1 String、StringBuilder、StringBuffer 的区别

这道题几乎是Java基础面试的必考题。核心答题点有三个:

  • String是不可变类,底层使用final char数组(JDK 9之后是byte数组)存储,每次拼接都会创建新对象,适合少量字符串操作。
  • StringBuilder是可变类,非线程安全,但性能最好,适合单线程下的字符串拼接。
  • StringBuffer也是可变类,内部方法加了synchronized,线程安全但性能略低,适合多线程环境。

面试官通常会继续追问:为什么String要设计成不可变?答案可以从安全、常量池复用、哈希缓存、线程安全四个角度展开。尤其要提到String作为HashMap的key时需要保证hashCode稳定,这是不可变性的重要收益。

答题示范:

String s1 = "hello"; String s2 = "hello"; System.out.println(s1 == s2); // true,字符串常量池复用 String s3 = new String("hello"); System.out.println(s1 == s3); // false,堆中新对象 String s4 = s1 + " world"; String s5 = "hello world"; System.out.println(s4 == s5); // false,拼接结果是新对象

3.2 equals 与 hashCode 的关系

这也是高频基础题。答题要点:

  • 如果两个对象通过equals方法比较相等,那么它们的hashCode必须相同。
  • 反过来不成立,hashCode相同不代表equals相等。
  • 重写equals时必须重写hashCode,否则在HashMap、HashSet等散列集合中会出现逻辑错误。

举个例子说明为什么必须同时重写。假设一个Person类只有name字段,如果只重写equals不重写hashCode,那么new两个name相同但hashCode不同的Person对象放入HashSet时,会落在不同的桶里,Set就无法去重。

3.3 反射与动态代理

反射考察点通常包括:

  • 什么是反射,能拿到哪些信息。
  • 反射的优缺点。
  • Class对象的获取方式。
  • 动态代理与静态代理的区别。
  • JDK动态代理与CGLIB代理的区别。

大厂面试更偏向问动态代理,因为它是Spring AOP的底层基础。注意回答三个关键点:JDK动态代理基于接口,使用Proxy和InvocationHandler;CGLIB基于继承,通过生成子类来代理目标类;Spring默认如果目标类实现了接口就用JDK代理,否则用CGLIB。

4. 集合框架高频面试题梳理

4.1 ArrayList 与 LinkedList 的对比

这是很基础但很容易说错的题。建议从存储结构、时间复杂度、内存占用三个维度回答:

  • ArrayList底层是Object数组,查询快,增删需要移动元素。
  • LinkedList底层是双向链表,增删快,但需要遍历定位。
  • ArrayList在指定位置插入需要System.arraycopy迁移元素,LinkedList插入只需修改节点指针。

这里有个容易踩坑的点:LinkedList的“增删快”是有条件的。如果按索引插入,LinkedList为了找到对应节点,会遍历链表,时间复杂度是O(n),并不比ArrayList快。只有在头部插入或已知节点引用时,LinkedList才有真正的优势。

4.2 HashMap 核心原理

HashMap是Java后端面试的“王牌考点”,从一面到三面都可能出现。建议按这个顺序展开:

底层结构:JDK 1.8之后是数组+链表+红黑树。数组默认初始容量是16,负载因子是0.75,当链表长度达到8且数组长度达到64时,链表转为红黑树。

put流程:

// 简化版put逻辑描述 1. 计算key的hash值:h = key.hashCode() ^ (h >>> 16) 2. 定位桶位置:index = (n - 1) & hash 3. 如果桶为空,直接放入节点 4. 如果桶不为空,遍历链表或红黑树 5. 找到相同key则覆盖value 6. 未找到则插入新节点 7. 插入后判断size是否超过阈值 threshold = capacity * loadFactor 8. 超过阈值则扩容resize()

扩容机制:JDK 1.8的扩容不是简单重新哈希,而是利用原数组长度是2的幂次这个特性,通过判断hash的“新增参与位”是0还是1,将节点分散到原位置或“原位置+旧容量”的位置。这样做的好处是rehash效率更高,且能保持节点相对顺序。

为什么链表长度为8时转红黑树:这是基于泊松分布的统计结果。当负载因子为0.75时,链表长度达到8的概率极低,约为千万分之六。转红黑树是为了防止极端情况下hash碰撞过多导致查询退化为O(n)。

4.3 ConcurrentHashMap 如何保证线程安全

这道题是并发模块和集合模块的连接点,面试官很喜欢问。JDK 1.8的ConcurrentHashMap放弃了分段锁,改为CAS+synchronized锁住桶的头节点。put流程大致是:

  • 如果桶为空,使用CAS直接插入节点,无锁操作。
  • 如果桶不为空,使用synchronized锁住头节点,再执行插入。
  • 如果正在扩容,当前线程会协助扩容。
  • 节点数量使用baseCount和CounterCell数组来统计。

答题时突出“CAS + synchronized锁头节点”这个设计就够了,不需要背过多源码细节。如果能补充“并发度从Segment数量提升到每个桶一个锁”这个对比,会更有说服力。

4.4 ArrayList 线程安全替代方案

高频追问:在多线程环境下如何安全的ArrayList?常用的方案有:

  • Vector,老牌的线程安全类,方法级synchronized,性能一般。
  • Collections.synchronizedList,通过包装类加锁。
  • CopyOnWriteArrayList,写时复制,读多写少场景非常好用。

CopyOnWriteArrayList是重点,ArrayList替代方案里它的回答效果最好。它的核心思想是:读操作不加锁,写操作先复制一份新数组,在新数组上修改,然后用volatile数组引用替换旧数组。写操作通过可重入锁保证互斥,读操作永远读到一致的快照。

5. 并发编程高频面试题梳理

5.1 volatile 关键字

volatile保证可见性和有序性,但不保证原子性。三个考点:

  • 可见性:变量被修改后,其他线程能立即看到最新值,底层通过缓存一致性协议和内存屏障实现。
  • 有序性:禁止指令重排序,底层是内存屏障,也就是load屏障和store屏障。
  • 不保证原子性:比如volatile int count,执行count++时,读写虽然可见,但“读-改-写”三步依然不是原子的。

面试官紧接着会问:volatile和synchronized有什么区别?回答要点:volatile是轻量级同步,只能修饰变量;synchronized可以修饰方法和代码块。volatile不阻塞线程,synchronized会阻塞。volatile适合状态标志位和单例模式双重检查锁中的字段,不适合复合操作。

5.2 synchronized 的锁升级过程

这道题主要考察对偏向锁、轻量级锁、重量级锁的理解。JDK 1.6之后synchronized做了大量优化,锁可以升级但不可降级:

  • 无锁状态。
  • 偏向锁:只有一个线程访问时,在对象头中记录线程ID,避免重复CAS。
  • 轻量级锁:多个线程交替访问,用CAS自旋获取锁,不阻塞。
  • 重量级锁:竞争激烈时,升级为监视器锁,未获取锁的线程会阻塞。

回答时建议补充对象头Mark Word的布局,说明锁标志位如何变化。能画出锁升级流程的候选人,面试官通常会认为底层理解比较扎实。

5.3 CAS 与 ABA 问题

CAS是Compare And Swap的缩写,核心是三个值:内存值V、期望值A、新值B。只有当V等于A时,才会把V改成B,否则不操作。CAS是Java中很多原子类的基础,例如AtomicInteger、AtomicLong等。

CAS的典型问题:

  • ABA问题:值从A变成B再变成A,CAS无法感知中间变化。解决方案是使用AtomicStampedReference,为变量增加版本号。
  • 自旋开销:高竞争场景下CAS会一直重试,消耗CPU。
  • 只能保证单个变量的原子性。

5.4 线程池

线程池是Java后端面试出现频率极高的考点,几乎没有一场面试会漏掉它。核心问题包括:

  • 为什么要用线程池。
  • 线程池的核心参数。
  • 线程池的拒绝策略。
  • 线程池的执行流程。
  • 如何合理配置线程池参数。

线程池的核心参数有七个:核心线程数、最大线程数、空闲线程存活时间、时间单位、任务队列、线程工厂、拒绝策略。

执行流程要描述清楚:提交任务后,如果当前线程数小于核心线程数,创建核心线程执行;如果等于核心线程数,任务进入队列;如果队列已满且线程数小于最大线程数,创建非核心线程;如果线程数达到最大线程数,则执行拒绝策略。

拒绝策略有四种:AbortPolicy直接抛异常、CallerRunsPolicy调用者线程执行、DiscardPolicy直接丢弃、DiscardOldestPolicy丢弃最老任务。实际项目中更推荐自定义拒绝策略,落地到告警或持久化,避免任务静默丢失。

线程池参数配置建议:

// CPU密集型任务:核心线程数约等于CPU核数+1 int cpuCoreCount = Runtime.getRuntime().availableProcessors(); ThreadPoolExecutor cpuPool = new ThreadPoolExecutor( cpuCoreCount + 1, cpuCoreCount * 2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new ThreadPoolExecutor.CallerRunsPolicy() ); // IO密集型任务:核心线程数建议 2 * CPU核数 或 CPU核数 / (1 - 阻塞系数) ThreadPoolExecutor ioPool = new ThreadPoolExecutor( 2 * cpuCoreCount, 2 * cpuCoreCount, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(500), new ThreadPoolExecutor.CallerRunsPolicy() );

6. JVM高频面试题梳理

6.1 JVM 内存区域划分

JVM内存区域是JVM面试的必考题,建议按线程私有和线程共享来分类:

线程私有区域:

  • 程序计数器:当前线程执行的字节码行号指示器,不会OOM。
  • Java虚拟机栈:每个方法调用创建栈帧,栈帧包含局部变量表、操作数栈、动态链接、返回值。栈深度超过限制会抛出StackOverflowError。
  • 本地方法栈:为native方法服务。

线程共享区域:

  • 堆:对象实例分配的主要区域,也是GC主要工作区域。
  • 方法区:存储类元信息、常量、静态变量。JDK 1.8之后,字符串常量池和静态变量转移到堆中,方法区实现改为元空间。

回答时需要区分各个区域的OOM表现:堆内存溢出是Java heap space,栈内存溢出是最常见的StackOverflowError,元空间超出是Metaspace。

6.2 垃圾回收与垃圾回收器

垃圾回收需要掌握三个概念:

  • 如何判断对象是否存活:引用计数法和可达性分析算法。JVM使用可达性分析算法,GC Roots包括虚拟机栈引用、静态属性引用、常量引用、本地方法栈引用。
  • 主流垃圾回收算法:标记-清除、复制、标记-整理。
  • 分代收集理论:新生代用复制,老年代用标记-整理或标记-清除。

垃圾回收器在面试中主要问G1和ZGC。G1是区域化分代收集器,把堆划分为若干Region,维护可预测的停顿时间模型,适合大堆场景。ZGC是低延迟垃圾回收器,通过染色指针和读屏障实现并发转移,暂停时间极短。

答题时的加分点是能结合实际调优经验:多大的堆、用什么回收器、为什么会出现Full GC、有没有看过GC日志。

6.3 JVM 类加载机制

类加载过程包括:加载、验证、准备、解析、初始化。重点说准备阶段和初始化阶段:

  • 准备阶段:为类变量分配内存并设置默认值,例如static int a在准备阶段被赋值为0。
  • 初始化阶段:执行clinit方法,为静态变量赋真实值。

类加载器需要掌握双亲委派模型。核心逻辑是:当一个类加载器收到类加载请求时,先委托给父加载器加载,父加载器无法加载时才自己加载。这样做的目的是防止核心API被篡改。

高频追问:如何打破双亲委派模型?SPI的典型场景就是通过线程上下文类加载器来加载JDBC驱动,这个方法需要理解但不一定每个候选人都能讲透。

6.4 线上OOM怎么排查

这个问题在社招面试里出现频率很高,推荐按“定位-分析-解决”的流程回答:

  • 通过jps找到进程ID。
  • jmap -dump:format=b,file=heap.hprof 导出堆转储文件。
  • 使用MAT或VisualVM分析大对象和内存泄漏链路。
  • 通过jstat查看GC频率和GC耗时,判断是内存泄漏还是内存分配压力过大。
  • 如果是Metaspace内存溢出,检查CGLIB动态生成类或反射使用。
  • 如果是栈溢出,检查递归调用和循环调用深度。

如果能补充一次真实的线上OOM排查过程,这道题会变成你的亮点。

7. Spring与Spring Boot高频面试题梳理

7.1 说说IOC与AOP

IOC问的是控制反转和依赖注入。回答重点是:Spring容器负责对象创建和依赖管理,对象本身不需要自己new依赖对象,而是通过构造器、Setter、字段三种方式注入。控制反转的关键在于“对象的控制权从代码转移到了容器”。

AOP问的是面向切面编程。核心概念:切面、通知、切入点、连接点。Spring AOP默认使用动态代理,JDK代理和CGLIB代理的适用场景要能说清楚。

高频追问:Spring AOP和AspectJ有什么区别?Spring AOP是运行时代理,只能对Spring管理的Bean生效;AspectJ是编译期或加载期织入,功能更强大但配置更复杂。

7.2 Spring Bean的生命周期

这道题非常经典,建议按照完整流程记忆:

  • 实例化Bean。
  • 属性填充。
  • Aware接口回调,例如BeanNameAware、ApplicationContextAware。
  • BeanPostProcessor的前置处理。
  • 执行InitializingBean的afterPropertiesSet方法或自定义init-method。
  • BeanPostProcessor的后置处理,这里是AOP代理生成的地方。
  • Bean就绪,可以被使用。
  • 容器销毁时,执行DisposableBean的destroy方法或自定义destroy-method。

7.3 三级缓存与循环依赖

循环依赖是指A依赖B,B依赖A。Spring解决单例Bean的循环依赖依赖三个缓存:

  • 一级缓存singletonObjects:存储完全初始化好的单例对象。
  • 二级缓存earlySingletonObjects:存储提前暴露的半成品对象。
  • 三级缓存singletonFactories:存储对象工厂,用于生成代理对象。

答题时要说明关键流程:A创建时先把ObjectFactory放入三级缓存,在属性填充时发现需要B,于是创建B;B创建时发现需要A,从三级缓存拿到A的早期引用;B创建完成后,A再从缓存中拿到B完成注入。

还需要说明:默认的单例模式可以解决循环依赖,但原型模式和构造器注入不能解决循环依赖。

7.4 Spring Boot自动配置原理

Spring Boot面试题中,自动配置是必问题。核心答案围绕@SpringBootApplication注解展开,它由三个注解组成:

  • @SpringBootConfiguration,表明这是一个配置类。
  • @ComponentScan,扫描当前包及其子包下的组件。
  • @EnableAutoConfiguration,开启自动配置。

自动配置的核心机制是通过Spring FactoriesLoader加载META-INF/spring.factories文件中的自动配置类。每个自动配置类通常配合@ConditionalOnClass、@ConditionalOnMissingBean等条件注解,只有满足条件时配置才会生效。

加分回答:说明怎么自定义自动配置类,或者怎么排除某个自动配置类,例如在application.yml中设置spring.autoconfigure.exclude。

7.5 Spring事务传播行为与失效场景

事务传播行为高频考的是REQUIRED和REQUIRES_NEW,默认是REQUIRED,意思是如果当前存在事务就加入,不存在就新建。

Spring事务失效的经典场景:

  • 方法不是public导致AOP代理无法应用。
  • 自调用问题,同类内部方法调用不会经过代理。
  • 异常被捕获后没有抛出,事务无法回滚。
  • 抛出的是Error或非RuntimeException,并且没有配置rollbackFor。
  • 数据库引擎不支持事务,例如MyISAM。

自调用问题是高频中的高频,要能讲清楚为什么同类内调用不生效,本质是因为调用的是this对象的方法,而不是代理对象的方法。

8. MySQL高频面试题梳理

8.1 索引原理与优化

MySQL索引是后端面试的重头戏,几乎每场面试都会涉及。核心考点:

  • B+树索引结构,为什么用B+树不用B树。B+树非叶子节点不存数据,可以存储更多索引,树高度更低,磁盘IO更少;叶子节点用链表连接,范围查询效率高。
  • 聚簇索引与非聚簇索引的区别。InnoDB主键索引就是聚簇索引,叶子节点存储整行数据;二级索引的叶子节点存储主键值,回表查询需要再走一次主键索引。
  • 联合索引的最左前缀原则。查询条件没有从联合索引最左列开始时,索引可能失效。
  • 覆盖索引:在二级索引中就能拿到查询所需字段,不需要回表,是常见的SQL优化手段。

索引优化建议:

-- 避免对索引列使用函数运算 SELECT * FROM user WHERE DATE(create_time) = '2024-08-01'; -- 应改为范围查询 SELECT * FROM user WHERE create_time >= '2024-08-01 00:00:00' AND create_time < '2024-08-02 00:00:00'; -- 联合索引 (user_id, create_time) -- 正确用法 SELECT * FROM order WHERE user_id = 1001 AND create_time > '2024-01-01'; -- 错误用法,跳过最左列 SELECT * FROM order WHERE create_time > '2024-01-01';

8.2 事务与隔离级别

MySQL事务的ACID特性需要记住,但更重要的是掌握四种隔离级别:

  • 读未提交:可能产生脏读。
  • 读已提交:解决脏读,但可能产生不可重复读。
  • 可重复读:解决不可重复读,InnoDB默认隔离级别,通过MVCC实现。
  • 串行化:解决幻读,但性能最低。

InnoDB在可重复读级别下,通过当前读配合next-key lock解决了幻读问题,这一点要重点说明。普通快照读不存在幻读,但当前读如果只使用行锁,间隙中插入新数据时会触发幻读,所以需要间隙锁。

8.3 MVCC 原理

MVCC是多版本并发控制,核心机制由三个隐藏字段、undo log和ReadView组成:

  • DB_TRX_ID:最近修改该行的事务ID。
  • DB_ROLL_PTR:指向undo log中的历史版本。
  • DB_ROW_ID:隐藏主键。

ReadView的生成规则是核心。在可重复读隔离级别下,ReadView在事务第一次读取时生成,整个事务期间复用;在读已提交级别下,每次读取都生成新的ReadView。

8.4 锁机制

MySQL锁需要掌握:

  • 共享锁与排他锁。
  • 行锁、表锁、间隙锁、临键锁。
  • 死锁的原因和排查方法。

死锁排查可以提一下命令:

-- 查看当前事务 SELECT * FROM information_schema.innodb_trx; -- 查看锁等待 SELECT * FROM information_schema.innodb_lock_waits; -- 查看InnoDB引擎状态,包含最近死锁信息 SHOW ENGINE INNODB STATUS;

8.5 SQL优化思路

遇到SQL慢的排查思路可以按以下顺序回答:

  • 查看慢查询日志,确认慢SQL语句。
  • 用EXPLAIN分析执行计划,重点看type、key、rows、Extra字段。
  • 检查是否有全表扫描,是否缺少索引。
  • 优化LIMIT深分页问题,使用延迟关联或游标分页。

深分页优化示例:

-- 普通深分页在offset很大时性能差 SELECT * FROM order WHERE status = 1 LIMIT 100000, 20; -- 延迟关联优化 SELECT o.* FROM order o INNER JOIN ( SELECT id FROM order WHERE status = 1 ORDER BY id LIMIT 100000, 20 ) tmp ON o.id = tmp.id;

9. Redis高频面试题梳理

9.1 Redis 数据结构与底层实现

Redis面试第一个问题通常是:Redis有哪些数据结构?分别适用于什么场景?

  • String:缓存、计数器、分布式锁。
  • Hash:对象存储,例如用户信息。
  • List:消息队列、最新列表。
  • Set:去重、交集并集。
  • ZSet:排行榜、延时队列。

底层实现也要了解。String底层是SDS,简单动态字符串,避免C字符串的缓冲区溢出问题。ZSet底层由跳表和哈希表组合实现,跳表保证了有序性和范围查询能力。

9.2 缓存穿透、缓存击穿、缓存雪崩

这三个问题是Redis面试的“三兄弟”,一定要区分清楚:

  • 缓存穿透:查询一个不存在的key,请求直接打到数据库。解决方法是布隆过滤器或缓存空值。
  • 缓存击穿:某一个热点key在缓存过期瞬间,大量请求打到数据库。解决方法是互斥锁或逻辑过期。
  • 缓存雪崩:大量key在同一时间段集中过期,或Redis服务宕机,导致请求全部打到数据库。解决方法是过期时间加随机值、多级缓存、集群高可用。

9.3 缓存一致性方案

缓存与数据库的一致性是分布式系统设计的经典问题。常见的策略有:

  • Cache Aside Pattern:先更新数据库,再删除缓存。这是最常用的方案。
  • 延迟双删:先删除缓存,更新数据库,再延时删除缓存,降低并发窗口下的脏数据概率。
  • 订阅binlog异步同步缓存。

面试被追问时,重点说你如何选择、为什么这样选、存在什么极端情况。没有方案是完美的,面试官想看到你的思考过程。

9.4 Redis 分布式锁

分布式锁的问题也是高频。核心要点:

  • 用setnx key value作为加锁命令,配合过期时间防止死锁。
  • 释放锁时要判断是不是自己的锁,通过Lua脚本保证比较和删除的原子性。
  • 单点问题会导致锁不可靠,更稳妥的方案是Redisson或Redlock。
  • 锁续期机制。Redisson通过看门狗机制自动续期,防止业务执行时间过长导致锁提前过期。

这里要提醒:面试时不要只背Redisson,要把setnx的缺陷讲清楚,再说Redisson如何解决,才能体现理解深度。

10. 消息队列与分布式高频面试题梳理

10.1 如何选型消息队列

不同消息队列有不同特点:

  • Kafka适合高吞吐、日志收集、大数据场景,但功能相对简单。
  • RocketMQ功能丰富,支持事务消息和延迟消息,适合电商等业务场景。
  • RabbitMQ适合中小规模业务,基于Erlang开发,简单易用。

核心要理解消息队列的价值:异步解耦、削峰填谷、数据同步。面试官会追问:你用了消息队列,带来了什么问题?能识别引入MQ带来的复杂度,比单纯说优点更能加分。

10.2 如何保证消息不丢失

消息丢失可能发生在三个环节:生产者发送、Broker存储、消费者消费。

解决思路:

  • 生产者端:使用同步发送或事务消息,确认消息到达Broker。
  • Broker端:开启持久化,刷盘策略设置为同步刷盘,主从同步。
  • 消费者端:关闭自动ack,消费成功后手动提交offset。

10.3 如何保证消息不重复消费

重复消费在分布式系统中几乎是不可避免的,关键在幂等设计。常见的幂等方案:

  • 数据库唯一主键或唯一索引。
  • Redis setnx。
  • 状态机幂等。
  • 引入全局分布式ID。

10.4 分布式事务

分布式事务不要只背2PC和3PC,面试官更希望听到你结合业务讲过实际方案。可选方案:

  • 2PC/3PC:强一致性,但性能差、协调者单点风险。
  • TCC:补偿事务,需要业务方实现try、confirm、cancel三个方法。
  • 本地消息表:借助本地事务和消息表保证最终一致性。
  • 事务消息:RocketMQ实现了事务消息,先发半消息,本地事务成功后commit。

回答时要表达:没有“银弹”,不同一致性级别对应不同方案,业务允许短暂不一致时首选最终一致性方案。

10.5 分布式锁与分布式唯一ID

分布式唯一ID的生成方案也是高频率考点:

  • UUID:简单但不适合做数据库主键,因为无序且太长。
  • 数据库自增ID:单点性能瓶颈。
  • Redis INCR:依赖Redis,需要考虑持久化。
  • 雪花算法:64位的长整型ID,由时间戳、机器ID、序列号组成,有序且性能高。

雪花算法的时钟回拨问题也是常问点,回答时可以提一下解决方案,例如等待时钟追平或直接抛出异常。

11. 算法与代码题高频考点

Java后端面试的算法题通常不会太难,但需要保持手感。高频题型包括:

  • 反转链表、链表中环的检测、合并两个有序链表。
  • 有效的括号、最长回文子串。
  • 二叉树前中后序遍历、层序遍历、最近公共祖先。
  • 斐波那契数列、爬楼梯。
  • 两数之和、三数之和。
  • 手写LRU缓存。
  • 最大子数组和、买卖股票的最佳时机。

LRU考察频率非常高,因为它能一次性考察你对HashMap+双向链表的掌握程度,也可以用LinkedHashMap简化实现。

class LRUCache { private final int capacity; private final Map<Integer, Integer> map; public LRUCache(int capacity) { this.capacity = capacity; this.map = new LinkedHashMap<>(capacity, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) { return size() > capacity; } }; } public int get(int key) { return map.getOrDefault(key, -1); } public void put(int key, int value) { map.put(key, value); } }

12. 高频面试题速记表与答题框架

12.1 高频题速查表

模块最高频问题一句话答题核心
Java基础String为什么不可变安全、常量池、hash缓存、线程安全
集合HashMap put流程计算索引、链表插入、树化、扩容
并发线程池执行流程核心线程 -> 队列 -> 最大线程 -> 拒绝
并发volatile与synchronized可见性有序性 vs 互斥性
JVMOOM排查流程jps -> jmap -> MAT -> 定位大对象
SpringBean生命周期实例化 -> 填充 -> Aware -> 前置 -> init -> 后置
Spring自动配置原理条件注解 + spring.factories
MySQL索引失效场景隐式转换、函数运算、左模糊、最左前缀违反
MySQLMVCCundo log + ReadView + 隐藏字段
Redis缓存三大问题穿透、击穿、雪崩的成因与方案
分布式消息重复消费唯一约束、setnx、状态机幂等
算法LRUHashMap + 双向链表

12.2 面试答题框架

很多候选人知识点都会,但表达混乱。推荐使用“总-分-总”结构:

  • 先给结论,比如“HashMap的底层是数组+链表+红黑树”。
  • 再展开细节,讲结构、流程、阈值、影响因素。
  • 最后补充优缺点或使用场景,让回答有完整闭环。

遇到不会的问题不要直接说不知道,可以回答相关思路:“这个场景我还没有直接处理过,但基于我对xxx的理解,我会从xxx方向排查。”这种方式更稳。

13. 备考中的常见问题与排查方法

13.1 为什么HashMap源码看了就忘

这是正常现象。原因是单纯阅读源码没有结合场景,建议用“画图+复述”的方式:自己画一遍put流程图,拿空数组模拟插入、冲突、扩容三个步骤。能画出来,就是真理解。

13.2 并发编程知识点太散,怎么串起来

推荐以synchronized为起点,延伸到锁升级、volatile、CAS、AQS、线程池、并发容器,形成一条线。每次面试复盘后,把新问题挂到这条线的对应节点上。

13.3 SQL优化题目没有真实场景

可以用在线练习平台刷题,也可以自己用本机MySQL构造百万级数据量测试。关键是理解EXPLAIN输出的每个字段,而不是背优化方案。

13.4 面试被追问就卡住

卡住的原因通常是对底层原理只停留在名词层面。解决办法是准备一个“项目案例”钩子,主动把问题引导到自己熟悉的场景。比如面试官问MySQL索引,你可以顺势说“我们系统里有一个订单查询接口之前很慢,后来通过加联合索引和覆盖索引把耗时从2秒降到50毫秒”,然后展开细节。

13.5 刷题与项目复习时间冲突

建议遵循“三七法则”:七成时间复习基础和算法,三成时间复盘项目。项目不追求多,但要把缓存、消息队列、分布式锁、数据库设计这些点讲透,并准备好“为什么这么设计”的答案。

14. 面试准备最佳实践

第一,建立自己的错题本。不要只记录正确答案,还要记录自己当时的错误理解。面试前三天只看错题本,效率远高于重刷题库。

第二,学会讲项目。每个项目准备两个版本:三分钟精简版和十分钟详细版。项目里用到Redis、MQ、分布式锁等技术点时,提前准备好“技术选型原因”和“遇到的坑”两个故事。

第三,多轮模拟面试。找朋友或同学搭模拟面试,重点是练习口述表达。你会发现很多想法只有真正说出来,才发现自己没有想透。

第四,保持代码手感。每天至少做两到三道算法题,重点练习手写LRU、快排、二分查找和单例模式,这些是面试现场手写概率最高的题目。

第五,关注最新的技术栈问题。Spring Boot 3、Spring Cloud Alibaba、Java 17和Java 21的新特性、虚拟线程、以及云原生相关的话题,在大厂面试中出现频率正在上升。对新技术保持敏感,是面试加分项。

15. 总结与后续复习建议

这份清单覆盖了Java后端面试的核心高频模块,从Java基础到集合,从并发到JVM,从Spring到MySQL,再到Redis、消息队列与分布式,基本对应大厂一轮、二轮面试的考察重点。你不需要一次性全部掌握,建议按照“集合 -> 并发 -> Spring -> MySQL -> Redis”的顺序优先复习,这几个模块性价比最高。

最容易踩的坑有两个:一是只背结论不追原理,面试官连续追问两层就会露馅;二是只看不练,算法题和SQL优化如果不实际动手,考场上的速度完全跟不上。

接下来的动作很简单:打开你的题库,从HashMap开始,先自己画一遍put流程,再对照本文梳理的答题核心做一次复述。如果每个高频题都能用自己的话讲清楚,同时能接住一个追问,那么8月这场面试,你的胜算已经明显提升了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 2:41:42

一条 Trajectory,如何解释 Agent Benchmark 的成败?

上一篇&#xff0c;我们沿着 RLHF、PPO、GRPO 和 DAPO&#xff0c;看了不同后训练算法“吃”的数据有什么区别。 这一次先不急着进入训练。我们从一次 Benchmark 开始。 假设同一个 Coding Benchmark 上&#xff0c;旧模型通过了 74 个任务&#xff0c;新模型只通过 68 个。最…

作者头像 李华
网站建设 2026/8/31 2:41:30

差一个字就能仿冒?账号防伪从字符相似度到可验证流程

在二手交易平台上&#xff0c;经常能看到卖家在商品介绍里重复一句话&#xff1a;认准店铺全名&#xff0c;用户名差一个字&#xff0c;都是假冒。我第一次遇到这种提醒时&#xff0c;以为只是普通客服话术。但看得多了&#xff0c;才发现这句话其实是一种被反复验证过的安全经…

作者头像 李华
网站建设 2026/8/31 2:40:58

上下水扫拖机器人怎么选?T90 Pro安装调试全指南

1. 为什么我建议你先别急着“闭眼买”如果你最近在看扫拖机器人&#xff0c;大概率会刷到“闭眼买”这个说法。尤其是科沃斯这类头部品牌&#xff0c;T系列常年霸榜&#xff0c;上下水版听起来更是“一步到位”的终极答案。但作为一个折腾过智能家居设备的开发者&#xff0c;我…

作者头像 李华
网站建设 2026/8/31 2:38:31

全价位密码锁选购清单:场景化选锁与安装测试指南

开锁这件事&#xff0c;看着简单&#xff0c;选起来其实非常容易翻车。这次我们不聊概念&#xff0c;直接看一份以“价位 场景”为主线的密码锁月度清单&#xff1a;16 款家用门锁、挂锁、车锁&#xff0c;覆盖 0-50 元到 800-1900 元全价位段&#xff0c;把租房党、家庭入户、…

作者头像 李华
网站建设 2026/8/31 2:38:00

深信服校招C/C++F卷考点全解析:从指针到epoll的备考指南

深信服校园招聘C/C软件开发F卷&#xff0c;这个标题在我印象里挺有分量的。当时我正准备投深信服的安全研发岗&#xff0c;刷了不少往年的笔经&#xff0c;直到自己真正坐到F卷的答题页面&#xff0c;才发现这套题的最大特征不是“难”&#xff0c;而是“杂”——编程题、语言细…

作者头像 李华
网站建设 2026/8/31 2:37:20

C# vs Java:上位机与Web后端的真实技术拆解与选型建议

每次面试问“你学 Java 还是 C#”&#xff0c;都像是要把程序员分成两个阵营。 但如果你真的在 Windows 上写过上位机、调过串口、接过工业相机&#xff0c;或者维护过一个需要跟硬件设备实时通信的桌面系统&#xff0c;你大概率会有一个真实体感&#xff1a;这个场景下&#…

作者头像 李华