Java 后端开发面试常见问题有哪些?怎么准备(校招 / 社招)
一句话概括
Java 后端面试基本围着七块转——Java 基础与集合、并发、JVM、Spring、MySQL、缓存与消息队列、分布式与系统设计,再加上一轮绕不开的项目深挖。校招看基础扎不扎实、代码写不写得出来、学东西快不快;社招看你处理过什么线上问题、做过什么技术取舍、系统量上来之后扛不扛得住;转行的同学则要用一个能讲透的完整项目,证明自己已经能干活。
- 26 道高频题
- 阅读约 39 分钟
- 内容核对于 2026-10-20
01这个岗位是做什么的?
Java 后端工程师负责用户看不见、但每一次点击都要经过的那一层:接收前端或 App 发来的请求,做业务逻辑处理,读写数据库和缓存,调用其他服务,再把结果返回回去。日常工作大致是:和产品对需求、设计接口和表结构、写业务代码和单元测试、联调、发布上线,然后盯监控、处理告警、排查线上问题。
常见方向有三类,面试侧重点会跟着变:
- 业务后端:电商交易、内容社区、营销活动、企业 SaaS、金融科技的业务系统等,最常见。重点考 Spring 全家桶熟练度、数据库设计、接口设计,以及对业务的理解——比如订单状态怎么流转、重复下单怎么防。
- 中间件 / 平台研发:消息队列、RPC 框架、配置中心、网关、任务调度、数据库中间件等。会深挖并发、网络 IO、JVM 和源码,对「为什么这么设计」的追问更多。
- 基础架构 / 稳定性方向:容器与发布平台、监控告警、全链路压测、容量规划。会问高可用设计、故障处理流程、可观测性。
级别上大致是:实习 / 初级(能按设计写好接口、写测试、修 bug)→ 中级(独立负责一个模块,从表结构到上线全流程,能处理常见线上问题)→ 高级 / 资深(负责一个系统的设计和稳定性,做容量评估和技术选型,带新人)→ 专家 / 负责人(跨系统、跨团队的架构规划)。级别越高,面试越少问「这个注解怎么用」,越多问「数据量翻十倍你怎么办」「出了故障你怎么兜底」。
02JD 怎么读?
后端 JD 的套话看起来都差不多,但每一句背后都对应着一类面试题。拿到 JD 先按下表拆一遍,就知道哪里要准备到原理层,哪里会用就行。
| 典型 JD 要求 | 面试官会怎么考 | 你该准备什么 |
|---|---|---|
| Java 基础扎实,熟悉集合、并发编程 | HashMap 结构与扩容、ConcurrentHashMap、锁、线程池参数、volatile | 每个知识点能讲到「为什么这样设计」;线程池能结合自己项目说出参数怎么定的 |
| 熟悉 JVM,有调优经验 | 内存区域、垃圾回收器选择、OOM 和 Full GC 怎么排查 | 背熟内存区域只是起点;准备一次自己动手的排查过程(哪怕是本地复现的) |
| 熟悉 Spring / Spring Boot | IoC、AOP、Bean 生命周期、事务失效场景、自动配置原理 | 能用自己的话讲清代理机制;把 @Transactional 的失效场景亲手试一遍 |
| 熟悉 MySQL,有 SQL 调优经验 | 索引结构、索引失效、执行计划、隔离级别与 MVCC、锁 | 会看 EXPLAIN 的关键列;准备 1 个有前后对比的慢 SQL 优化案例(数据用你自己的) |
| 熟悉 Redis 等缓存 | 数据结构的使用场景、穿透击穿雪崩、缓存与数据库一致性、过期与淘汰 | 说清项目里缓存了什么、过期时间怎么定、数据不一致时怎么兜底 |
| 熟悉消息队列(Kafka 等 等) | 为什么引入 MQ、消息丢失与重复、顺序消息、积压怎么处理 | 画出你项目里消息的生产、存储、消费链路,标出每一步可能丢消息的地方 |
| 有高并发、分布式系统经验(社招常见) | 系统设计题、分布式锁、分布式事务、限流熔断降级、分库分表 | 准备一个「量上来之后我们怎么改」的完整故事:瓶颈在哪、方案对比、效果数据 |
| 有良好的编码习惯和工程意识 | 代码规范、单元测试、Code Review、日志与异常处理、接口幂等 | 能说出团队实际执行的规范,以及你因为某个规范避免过的坑 |
| 有责任心、沟通协作能力 | 和产品、前端、测试的分歧怎么处理;线上故障中你的角色;带新人(社招) | 准备 2–3 个 STAR 结构的真实经历,其中一个最好是线上问题 |
小技巧:JD 里写的「加分项」(如 Go、云原生、大数据组件、搜索引擎)不一定考,但如果你真的用过,在自我介绍里主动提一句,给面试官一个追问的抓手;没用过就别写在简历上。
03面试一般几轮、每轮考什么?
不同公司轮次不完全一样,常见结构如下,具体以招聘方通知为准:
| 轮次 | 主要考什么 | 时长参考 | 准备建议 |
|---|---|---|---|
| 笔试 / 在线编程(校招多见) | 算法编程题 + 少量 Java、数据库、操作系统、网络选择题 | 60–120 分钟 | 按类型刷简单到中等难度算法题;熟悉在线判题环境的输入输出写法 |
| 技术一面 | Java 基础、集合、并发、JVM、MySQL、Redis 等基础知识 + 手写代码 + 简历初问 | 45–60 分钟 | 概念题答到「为什么」;手写题边写边说思路和边界 |
| 技术二面 | 深挖项目、线上问题、技术取舍,可能有一道开放的系统设计题 | 45–75 分钟 | 项目里每个技术点准备被追问三层;系统设计按「需求—估算—设计—扩展」走 |
| 业务面 / 主管面 | 业务理解、技术视野、协作方式、成长潜力 | 30–60 分钟 | 准备「最难的事」「做错过什么」「为什么想做后端 / 为什么换工作」 |
| 交叉面(社招中高级岗位可能有) | 其他团队的人再评估一次,常偏架构和综合能力 | 45–60 分钟 | 把核心项目的架构图能在白纸上画出来并讲清楚 |
| HR 面 | 动机、稳定性、团队协作、期望薪资、到岗时间 | 20–40 分钟 | 离职原因、为什么选这里、期望薪资提前想好,口径前后一致 |
社招常见的变化:算法题比重下降,一面就可能直接深挖项目;系统设计和线上问题复盘比重明显上升;高级岗位可能出现架构评审式的面试,让你讲一个自己负责的系统的全貌。实习面试一般是 2–3 轮技术加 1 轮 HR,难度比正式校招略低,但基础题和手写代码一样会考。转行的同学按社招或校招通道走都有可能,面试官会更关注你的项目是不是自己真正做出来的。
04高频题有哪些?怎么答?
- 练一练
01HashMap 的底层结构是什么?扩容时发生了什么?专业知识技术一面校招 · 实习 · 社招基础
考察点: 最常见的集合题,看你是只背了结论,还是理解了设计取舍。
答题思路:
- 结构(以 JDK 8 及之后为准):一个数组,每个位置叫一个桶;哈希冲突的元素先用链表挂在桶上,链表过长且数组容量足够大时转成红黑树,把最坏情况下的查找从线性降到对数级。
- 定位过程:先算 key 的
hashCode,再把高位和低位做一次异或扰动,然后用「哈希值 & (容量 - 1)」算下标。容量保持为 2 的幂,就是为了让这个与运算等价于取模且更高效。 - 扩容:元素个数超过「容量 × 负载因子」(默认负载因子 0.75)就扩容为原来的两倍。迁移时每个元素要么留在原下标,要么移动到「原下标 + 旧容量」,只需看哈希值多出来的那一位,不用重新计算完整哈希。
- 树化细节:链表长度达到阈值且数组容量达到一定值才会树化,容量小的时候优先扩容;具体阈值以所用 JDK 版本源码为准。
- 线程不安全的表现:并发
put可能丢数据、size不准;老版本 JDK 并发扩容时还可能形成环形链表导致死循环。多线程场景用ConcurrentHashMap。
校招怎么答 / 社招怎么答: 校招讲清结构、下标计算、扩容迁移和线程不安全就够;社招可以补一句实践经验,比如已知数据量时初始化给足容量,避免反复扩容,以及排查过的「对象作为 key 时 hashCode 被修改导致取不出来」这类问题。
可能的追问: 为什么负载因子取 0.75 而不是 1?为什么用红黑树而不是平衡二叉树或跳表?
HashMap允许 null 键吗? - 练一练
02ArrayList 和 LinkedList 有什么区别?实际开发怎么选?专业知识技术一面校招 · 实习基础
考察点: 数据结构基本功,以及会不会被「教科书结论」带偏。
答题思路:
ArrayList底层是动态数组,按下标随机访问快;在中间插入或删除要移动后面的元素;容量不够时按约 1.5 倍扩容并拷贝数组。LinkedList是双向链表,按下标访问要从头或尾遍历;已经拿到节点位置时插入删除快;每个节点额外存两个指针,内存占用更大。- 实际选择:大多数业务场景用
ArrayList。原因是数组内存连续、对 CPU 缓存友好,而LinkedList想在中间插入也得先遍历找到位置,理论上的优势在实践中常常体现不出来。 - 需要队列或双端队列时,优先考虑
ArrayDeque。
可能的追问:
ArrayList遍历时删除元素为什么会抛ConcurrentModificationException?怎么正确删除? - 练一练
03为什么重写 equals 时一定要重写 hashCode?专业知识技术一面校招 · 实习基础
考察点: 是否理解哈希容器的约定。
答题思路:
- 约定:两个对象
equals为 true,hashCode必须相等;hashCode相等,equals不一定为 true(哈希冲突)。 - 只重写
equals不重写hashCode:两个「逻辑上相等」的对象哈希值不同,放进HashMap/HashSet会落到不同的桶,结果是Set里出现重复元素、Map里用新对象当 key 取不到值。 - 实践:用 IDE 或
Objects.hash一起生成;参与计算的字段最好是不可变的,否则对象放进集合后字段一改,就再也找不到它了。 - Java 16 起的
record会自动按字段生成这两个方法,可以顺带提一句。
可能的追问:
==和equals有什么区别?String的hashCode是怎么算的、为什么会缓存? - 约定:两个对象
- 练一练
04String 为什么设计成不可变的?String、StringBuilder、StringBuffer 怎么选?专业知识技术一面校招 · 实习基础
考察点: 对语言设计取舍的理解。
答题思路:
- 不可变的好处:字符串常量池可以安全地共享同一个对象;天然线程安全;哈希值可以缓存,适合做
HashMap的 key;作为类名、文件路径、连接参数传递时不会被中途篡改,更安全。 - 「不可变」的实现:类用
final修饰不能被继承,内部存储字符的数组是私有且不对外暴露修改方法。 - 选择:少量拼接直接用
+(编译器会优化);循环里大量拼接用StringBuilder;StringBuffer方法加了同步,多线程共享同一个对象拼接时才需要,实际很少用。 - 可以提一句:JDK 9 起
String内部从char[]改为byte[]加编码标记,纯 Latin-1 字符串更省内存。
可能的追问:
new String("abc")创建了几个对象?intern()有什么用、有什么风险? - 不可变的好处:字符串常量池可以安全地共享同一个对象;天然线程安全;哈希值可以缓存,适合做
- 练一练
05synchronized 和 ReentrantLock 有什么区别?专业知识技术一面校招 · 社招进阶
考察点: 并发基础核心题,看你对锁的理解深度。
答题思路:
- 实现层面:
synchronized是 JVM 层面的关键字,基于对象头和监视器实现,进出代码块由 JVM 自动加锁解锁;ReentrantLock是 JDK 提供的类,基于 AQS(抽象队列同步器)实现,需要手动lock并在finally里unlock。 - 功能差异:
ReentrantLock支持可中断地等锁(lockInterruptibly)、尝试加锁和超时(tryLock)、公平锁、多个条件变量(Condition);synchronized只能用wait / notify配合一个等待队列。 - 共同点:都是可重入锁。
- 性能:JVM 对
synchronized做了很多优化(轻量级锁、自旋、锁消除、锁粗化),一般场景下性能差距不大,选择主要看功能需要。偏向锁在较新的 JDK 中已默认关闭并逐步移除,讲锁升级时注意版本。 - 选择建议:简单互斥用
synchronized,代码更不容易出错;需要超时、可中断、公平或多条件时用ReentrantLock。
校招怎么答 / 社招怎么答: 校招讲清区别和 AQS 的基本思路(一个 state 加一个等待队列);社招可以讲一次因为锁使用不当导致的问题,比如锁粒度太大导致接口变慢,或者
unlock没放在finally里导致的线程卡死。可能的追问: AQS 的核心原理是什么?公平锁和非公平锁哪个吞吐更高、为什么?什么是死锁、怎么排查?
- 实现层面:
- 练一练
06线程池的核心参数有哪些?任务提交后的执行流程是什么?参数怎么设?专业知识技术一面技术二面校招 · 社招进阶
考察点: 不只是背参数,而是能否结合业务设置并说出风险。几乎每场后端面试都会碰到。
答题思路:
- 七个参数:核心线程数、最大线程数、非核心线程空闲存活时间及单位、任务队列、线程工厂、拒绝策略。
- 执行流程:线程数小于核心数就新建线程执行;否则放进队列;队列满了且线程数小于最大数就新建非核心线程;都满了就执行拒绝策略。注意顺序是「先进队列、再扩线程」,这一点经常被说反。
- 四种内置拒绝策略:抛异常(默认)、由提交任务的线程自己执行、直接丢弃、丢弃队列里最老的任务。
- 参数估算思路:CPU 密集型任务线程数接近 CPU 核数;IO 密集型可以更多,大致按「核数 × (1 + 等待时间 / 计算时间)」估算。但这只是起点,最终要靠压测和监控调整。
- 风险点:用
Executors的快捷方法创建的固定线程池使用无界队列,任务堆积可能导致内存溢出;生产环境建议手动创建,用有界队列,给线程起有意义的名字,方便排查。
示范回答(校招版):
线程池有七个参数:核心线程数、最大线程数、空闲线程存活时间和单位、任务队列、线程工厂和拒绝策略。提交任务时,如果当前线程数还没到核心数,就直接新建线程执行;到了核心数,任务先放进队列;队列也满了,再看线程数有没有到最大值,没到就创建非核心线程;全都满了就走拒绝策略,默认是直接抛异常。参数怎么设要看任务类型,计算多的任务线程数接近 CPU 核数就行,开多了反而切换开销大;像调接口、读数据库这种等待多的任务可以多开一些。我在【课程项目 / 实习项目】里用线程池并行调用【3 个】查询接口,一开始直接用了
Executors的固定线程池,后来了解到它的队列是无界的,请求多的时候任务会一直堆积,就改成了手动创建,用了容量为【200】的有界队列,拒绝策略选了让调用线程自己执行,这样压力大时请求会变慢,但不会把内存撑爆。示范回答(社招版):
参数和流程我简单过一下:线程数没到核心数就建线程,到了就进队列,队列满了再扩到最大线程数,再满就拒绝。我想重点说一下我们在【某个聚合查询服务】里是怎么定参数的。这个接口要并行调【N 个】下游,属于典型的 IO 密集型。我们先按「核数 × (1 + 等待时间 / 计算时间)」估了一个初始值,然后在压测环境逐步加压,盯三个指标:线程池活跃线程数、队列长度、接口的较慢分位耗时,最后把核心线程数定在【X】,队列容量【Y】。拒绝策略没用默认的抛异常,而是自定义成记录日志、打点报警,再返回降级结果,因为这个接口允许部分数据缺失。另外我们踩过两个坑:一是多个业务共用一个线程池,其中一个下游变慢把线程全占满,导致其他业务一起超时,后来按业务做了线程池隔离;二是线程池参数写死在代码里,调整要发版,后来接入了配置中心支持动态调整核心数和最大线程数,并把线程池的运行指标接进了监控大盘。
可能的追问: 核心线程会被回收吗?线程池里的任务抛异常了会怎样?怎么优雅地关闭线程池?
CompletableFuture默认用的是哪个线程池、有什么风险? - 练一练
07volatile 能保证什么?不能保证什么?专业知识技术一面校招 · 实习进阶
考察点: 对 Java 内存模型的理解。
答题思路:
- 能保证可见性:一个线程修改了
volatile变量,其他线程能立刻读到最新值,而不是读自己工作内存里的旧副本。 - 能保证有序性:通过内存屏障禁止特定的指令重排序。经典例子是双重检查锁单例里,实例变量必须加
volatile,否则其他线程可能拿到一个「已分配内存但还没初始化完」的对象。 - 不能保证原子性:
count++是「读—改—写」三步,多个线程同时执行仍会丢失更新。需要用synchronized、锁或AtomicInteger这类原子类。 - 典型用法:状态标志位(比如控制线程停止的开关)、双重检查锁单例。
可能的追问: 什么是 happens-before 原则?
AtomicInteger是怎么保证原子性的?CAS 有什么问题(ABA、自旋开销)? - 能保证可见性:一个线程修改了
- 练一练
08ConcurrentHashMap 是怎么做到线程安全的?专业知识技术一面技术二面社招 · 校招进阶
考察点: 并发容器的设计思想,社招常问。
答题思路:
- 老版本(JDK 7):分段锁,把整个表分成若干段,每段一把锁,不同段之间可以并发写。
- JDK 8 及之后:取消分段,结构和
HashMap类似。写入时如果桶是空的,用 CAS 直接放入;桶不为空时,只对这个桶的头节点加synchronized,锁粒度细到单个桶。 - 读操作基本不加锁,依赖
volatile保证可见性。 - 扩容时支持多个线程协助迁移数据。
size的统计:用一个基础计数加上一组分散的计数单元,竞争激烈时把累加分散到不同单元,最后求和,思路和LongAdder类似,所以size是一个近似的瞬时值。- 和
Hashtable对比:后者整个表一把锁,并发性能差,基本不再使用。
可能的追问:
ConcurrentHashMap为什么不允许 null 键和 null 值?「先 get 判断再 put」这种复合操作安全吗、应该用什么方法? - 练一练
09JVM 内存分哪几块?哪些地方会发生内存溢出?专业知识技术一面校招 · 社招基础
考察点: JVM 基础,以及能否和线上问题联系起来。
答题思路:
- 线程共享:堆(对象实例,垃圾回收的主要区域)、方法区(类信息、常量、静态变量;JDK 8 起用本地内存中的元空间实现,替代了永久代)。
- 线程私有:虚拟机栈(每个方法调用一个栈帧,存局部变量等)、本地方法栈、程序计数器。
- 堆外:直接内存(NIO 等使用),不受堆大小参数限制,但有单独的上限。
- 对应的问题:堆满了报堆空间不足的 OOM,常见原因是内存泄漏或一次加载数据过多;元空间满了常见于动态生成大量类;栈太深报
StackOverflowError,常见于无终止条件的递归;线程创建过多可能报无法创建本地线程;直接内存不足多见于网络框架使用不当。 - 程序计数器是唯一不会发生 OOM 的区域,可以顺带一提。
校招怎么答 / 社招怎么答: 校招讲清分区和每块存什么;社招一定要带上「我遇到过哪种 OOM、怎么定位的」,比如通过堆转储文件发现是某个缓存没设上限。
可能的追问: 对象一定分配在堆上吗(逃逸分析)?对象从新生代晋升到老年代的条件有哪些?
- 练一练
10常见的垃圾回收器有哪些?项目里怎么选?专业知识技术二面社招进阶
考察点: 是否理解吞吐量和停顿时间的取舍,而不是只会背回收器名字。
答题思路:
- 先讲基础:分代思想(大部分对象朝生夕死)、可达性分析判断对象存活、标记—清除 / 标记—复制 / 标记—整理三类算法各自的优缺点。
- 回收器按目标分:Serial(单线程,适合小内存客户端);Parallel(关注吞吐量,适合后台批处理);G1(把堆划成很多大小相等的区域,优先回收垃圾最多的区域,可以设定期望停顿时间,在 JDK 9 起作为服务端默认回收器);ZGC、Shenandoah(目标是极低停顿,适合大堆、对延迟敏感的服务)。CMS 已在较新版本中移除。
- 选择思路:先明确业务目标——接口服务通常更在乎停顿时间,离线任务更在乎吞吐量;再看堆大小和 JDK 版本;最后用 GC 日志和压测验证,而不是凭感觉改参数。
- 以所用 JDK 版本的官方调优文档为准。
可能的追问: G1 的一次混合回收大致经历哪些阶段?什么情况下会触发 Full GC?你看过 GC 日志吗、看哪些指标?
- 练一练
11线上某个服务 CPU 突然飙高或者频繁 Full GC,你怎么排查?情景应变技术二面社招深挖
考察点: 线上问题处理的方法论和实际动手经验,社招重点题。
答题思路:
- 第一步先止血:看影响范围,必要时摘流量、扩容、回滚最近的发布或重启部分实例,但重启前先保留现场(线程栈、堆转储、GC 日志)。
- CPU 高的定位:用
top找到进程,再看进程内哪个线程占 CPU 高,把线程号转成十六进制,用jstack或jcmd 进程号 Thread.print导出线程栈,找到对应线程在执行什么代码。常见原因是死循环、大量正则或序列化计算、频繁 GC 本身占满 CPU。 - Full GC 频繁的定位:用
jstat观察各区的使用和 GC 次数,看老年代是不是回收后也降不下来;用jmap或jcmd导出堆转储,用内存分析工具看哪些对象占得最多、被谁引用着。常见原因是内存泄漏(静态集合不断增长、缓存没上限)、一次查询加载过多数据、大对象频繁创建。 - 也可以用 JDK 自带的飞行记录器(JFR)做低开销的持续采样。
- 最后讲修复和复盘:根因是什么、怎么修、补了哪些监控和告警、以后怎么避免。
校招怎么答 / 社招怎么答: 校招如果没有线上经历,可以说清排查思路,再讲一次在本地故意写个死循环或内存泄漏、用工具定位到的练习;社招要讲一次真实的排查经过,时间线、用了什么命令、看到了什么现象、最终根因,数字用你自己的。
可能的追问: 堆转储文件很大、线上不方便导出怎么办?如果是内存泄漏,怎么判断是哪个对象泄漏?
- 练一练
12用你自己的话讲讲 Spring 的 IoC 和 AOP。专业知识技术一面校招 · 实习基础
考察点: 是否真的理解,而不是背定义。
答题思路:
- IoC(控制反转):对象不再自己
new依赖,而是交给容器创建和组装,容器把依赖「注入」进来(依赖注入是 IoC 的实现方式)。好处是解耦:换一个实现类只改配置,不改调用方;也方便写单元测试时替换成模拟对象。 - 推荐构造器注入:依赖不可变、不会出现空指针、依赖过多时一眼就能看出这个类职责太重。
- AOP(面向切面编程):把日志、事务、权限、监控这类横跨很多业务方法的逻辑抽出来,统一织入,业务代码只关心业务本身。
- AOP 的实现:运行时生成代理对象。目标类实现了接口时可以用 JDK 动态代理,否则用基于子类的代理(CGLIB 方式);Spring Boot 默认倾向于使用基于类的代理,以所用版本配置为准。
- 结尾带一句你用 AOP 做过什么,比如统一的接口耗时日志或操作审计。
可能的追问: Bean 的生命周期大致有哪些阶段?Spring 是怎么解决循环依赖的、为什么构造器注入的循环依赖解决不了?
- IoC(控制反转):对象不再自己
- 练一练
13@Transactional 在哪些情况下会失效?专业知识技术一面技术二面校招 · 社招进阶
考察点: 是否在项目里真正踩过坑,以及对代理机制的理解。
答题思路:
- 根本原因:Spring 事务基于代理实现,只有通过代理对象调用方法时,事务逻辑才会生效。顺着这个思路就能推出大部分失效场景。
- 同一个类里的方法自调用:
this.methodB()绕过了代理,methodB上的事务注解不生效。 - 方法不是
public:在常见的代理配置下不生效(较新版本对基于类的代理有放宽,以所用版本为准)。 - 异常被吞了:方法内部
try / catch后没有重新抛出,事务管理器感知不到异常,不会回滚。 - 异常类型不对:默认只对运行时异常和
Error回滚,受检异常不回滚,需要配置rollbackFor。 - 传播行为配置:比如被调用方法配置成不支持事务或新开事务,行为和预期不同。
- 其他:类没有被 Spring 管理;在新线程里执行数据库操作(不在同一个事务上下文);数据库表引擎本身不支持事务。
- 实践建议:事务范围尽量小,不要在事务里调用远程接口或做耗时操作,否则长时间占用数据库连接。
可能的追问: 七种传播行为里最常用的是哪几种、
REQUIRED和REQUIRES_NEW的区别?大事务会带来什么问题? - 练一练
14Spring Boot 的自动配置是怎么生效的?专业知识技术二面社招 · 校招进阶
考察点: 是否理解「约定优于配置」背后的机制,排查问题时用得上。
答题思路:
- 入口:启动类上的组合注解开启了自动配置。
- 加载:Spring Boot 从各个依赖包里约定位置的清单文件读取自动配置类列表(较新版本用专门的
AutoConfiguration.imports文件,早期版本用spring.factories)。 - 条件生效:自动配置类上带着条件注解,比如「类路径上存在某个类才生效」(
@ConditionalOnClass)、「用户自己没定义这个 Bean 才生效」(@ConditionalOnMissingBean)、「某个配置项打开才生效」。所以引入一个 starter 依赖,相关组件就自动配好了;用户自己定义了 Bean,默认的就让路。 - 排查技巧:启动时开启 debug 模式能打印条件评估报告,看到哪些自动配置生效、哪些没生效、为什么;也可以用 Actuator 的相关端点查看。
- 加分:说一下你写过的自定义 starter,或者解决过的自动配置冲突(比如多数据源时默认数据源配置的冲突)。
可能的追问: starter 是怎么组织的?配置文件的加载顺序和优先级是怎样的?
- 练一练
15MySQL 的索引为什么用 B+ 树?什么情况下索引会失效?专业知识技术一面校招 · 社招基础
考察点: 数据库必考题,看能否把结构和使用联系起来。
答题思路:
- 为什么是 B+ 树(以 InnoDB 为准):数据在磁盘上,查询瓶颈是磁盘 IO 次数。B+ 树是多叉树,每个节点能存很多键,树很矮,几次 IO 就能定位到数据;非叶子节点只存键不存数据,能放更多键;叶子节点之间有链表连接,范围查询和排序很方便。对比哈希索引不支持范围查询,对比二叉树层数太高。
- 聚簇索引和二级索引:InnoDB 的主键索引叶子节点存整行数据;二级索引叶子节点存主键值,查其他列要回表。查询的列都在索引里就能避免回表,叫覆盖索引。
- 常见失效场景:联合索引不满足最左前缀;在索引列上用函数或运算;隐式类型转换(比如字符串列用数字去比较);
LIKE以通配符开头;OR连接的条件里有列没有索引;优化器判断走索引还不如全表扫描(比如区分度很低的列)。 - 验证方法:用
EXPLAIN看type、key、rows、Extra这几列,而不是凭感觉判断。
校招怎么答 / 社招怎么答: 校招讲清结构、回表、最左前缀和几种失效场景;社招结合一次真实的索引设计,比如为某个高频查询建了什么联合索引、字段顺序为什么这样排。
可能的追问: 主键为什么建议用自增 ID 而不是 UUID?索引是不是越多越好?什么是索引下推?
- 练一练
16事务的隔离级别有哪些?MVCC 是怎么实现的?专业知识技术一面技术二面校招 · 社招进阶
考察点: 对并发事务问题的理解。
答题思路:
- 四种隔离级别和对应问题:读未提交(可能脏读)、读已提交(避免脏读,可能不可重复读)、可重复读(避免不可重复读,标准定义下可能幻读)、串行化(全部避免,并发性能差)。InnoDB 默认是可重复读。
- MVCC(多版本并发控制)的核心:每行记录带有最近修改它的事务 ID 和指向旧版本的指针,旧版本存在 undo 日志里,串成一条版本链。
- 读视图(Read View):事务读数据时生成一个「快照」,记录当时哪些事务还没提交,沿着版本链找到对自己可见的那个版本。读已提交每次查询都生成新的读视图;可重复读在事务第一次查询时生成,之后一直复用,所以多次读结果一致。
- 快照读和当前读:普通
SELECT是快照读,走 MVCC;SELECT ... FOR UPDATE、UPDATE、DELETE是当前读,读最新版本并加锁。InnoDB 在可重复读下通过间隙锁、临键锁减少当前读的幻读。 - 以 InnoDB 和所用 MySQL 版本的官方文档为准。
可能的追问: 可重复读下真的完全没有幻读吗、能举个例子吗?间隙锁会带来什么问题(死锁、并发下降)?
- 练一练
17遇到一条慢 SQL,你会怎么优化?情景应变技术二面校招 · 社招深挖
考察点: 数据库调优的方法论:发现、分析、优化、验证,以及是否真的动手做过。
答题思路:
- 发现:开启慢查询日志,或通过监控和链路追踪找到耗时高的接口和对应 SQL。
- 分析:用
EXPLAIN看执行计划——是不是全表扫描、用了哪个索引、预估扫描行数、有没有Using filesort或Using temporary;必要时用EXPLAIN ANALYZE看实际执行情况。 - 优化手段由浅到深:补索引或调整联合索引的列顺序;改写 SQL(避免在索引列上用函数、避免
SELECT *、用覆盖索引减少回表);深分页改成按上一页最后一条记录的 ID 往后查;大查询拆成小查询;冗余字段减少关联;数据量真的太大再考虑归档、读写分离、分库分表。 - 验证:在相近数据量的环境里对比优化前后的执行计划和耗时;上线后看监控确认。
- 注意:线上加索引要评估表大小和锁的影响,选择低峰期执行。
示范回答(校招版):
我会按「找到它、看懂它、改掉它、验证它」四步来。我在【课程项目 / 实习项目】里做过一次:订单列表页按用户和时间范围查询,数据造到【几十万】条之后,接口要【2 秒】左右。我先开了慢查询日志确认是这条 SQL,然后用
EXPLAIN看,发现type是ALL,也就是全表扫描,原因是表上只有主键索引。查询条件是user_id等于某值、create_time在一个范围内,再按create_time倒序。我建了一个(user_id, create_time)的联合索引,把等值条件放在前面、范围条件放后面,这样既能过滤又能直接利用索引的顺序,不用再额外排序。改完再看执行计划,走了新索引,Extra里的Using filesort也没了,接口耗时降到【几十毫秒】。另外我发现翻到很后面的页还是慢,又把分页改成了「带上上一页最后一条的时间和 ID 往后查」。这些数字是我本地造数据测的,我知道线上环境还要考虑更多因素。示范回答(社招版):
我们在【某个运营后台的报表查询】上遇到过这个问题:大促前后数据量涨上来,这个接口的较慢分位耗时到了【数秒】,还拖慢了同库其他接口。排查分三步:先从慢日志和链路追踪定位到两条 SQL;然后看执行计划,第一条是多条件筛选,优化器选错了索引,选了一个区分度很低的状态字段的索引,扫描行数【几十万】;第二条是深分页,偏移量很大时要先扫过前面所有行再丢掉。对第一条,我们根据实际的查询条件组合重建了联合索引,把区分度高的条件放在前面,并去掉了一个已经被联合索引覆盖的冗余单列索引;对第二条,和产品沟通后把「跳到任意页」改成「上一页 / 下一页」,用游标方式往后查。加索引那张表有【千万级】数据,我们在低峰期用在线 DDL 执行,执行前评估了磁盘空间和主从延迟。上线后这个接口耗时降到【几百毫秒】以内。之后我们把慢查询纳入了每周巡检,新增 SQL 在评审时要求附上执行计划,这比事后救火成本低得多。
可能的追问: 优化器为什么会选错索引、怎么处理?大表加字段或加索引怎么做才不影响线上?什么时候才需要分库分表?
- 练一练
18缓存穿透、缓存击穿、缓存雪崩分别是什么?怎么解决?专业知识技术一面校招 · 社招基础
考察点: 缓存使用的基本风险意识。
答题思路:
- 缓存穿透:查询一个根本不存在的数据,缓存和数据库都没有,每次请求都打到数据库,常见于恶意请求。解决:缓存空值并设较短过期时间;用布隆过滤器提前拦截肯定不存在的 key;接口层做参数校验。
- 缓存击穿:某一个热点 key 过期的瞬间,大量请求同时打到数据库。解决:重建缓存时加互斥锁,只让一个请求去查库,其他请求等待或返回旧值;热点数据设置逻辑过期,后台异步刷新。
- 缓存雪崩:大量 key 同一时间过期,或者缓存服务整体不可用,请求全部落到数据库。解决:过期时间加随机值打散;缓存做高可用部署;数据库前加限流和降级;本地缓存做多级兜底。
- 一句话区分:穿透是「查不存在的」,击穿是「一个热点失效」,雪崩是「一大片失效」。
可能的追问: 布隆过滤器的原理和误判是怎么回事?Redis 的过期删除和内存淘汰策略有哪些?
- 练一练
19缓存和数据库的数据怎么保持一致?情景应变技术二面社招 · 校招深挖
考察点: 是否理解一致性问题没有完美解,能否根据业务做取舍。
答题思路:
- 先表态:缓存和数据库是两个系统,强一致代价很高,大多数场景追求的是最终一致,并把不一致的时间窗口控制在业务可接受的范围内。
- 常用方案:先更新数据库,再删除缓存(而不是更新缓存)。删除而不是更新,是因为并发更新缓存容易乱序,而且很多缓存值是计算出来的,删掉等下次读时再加载更省事。
- 为什么不先删缓存再更新数据库:删完缓存、数据库还没更新时,另一个读请求会把旧值重新写回缓存。
- 进一步加固:删除缓存失败时重试(可以借助消息队列);延迟双删(更新数据库后延迟一小段时间再删一次);订阅数据库变更日志,由独立的程序负责删除缓存,业务代码不用关心。
- 兜底:缓存一定要设置过期时间,即使出现不一致,也会在过期后自愈。
- 对一致性要求特别高的数据(比如余额),直接读数据库,不走缓存。
可能的追问: 「先更新数据库再删缓存」在什么极端情况下仍然会不一致?延迟双删的延迟时间怎么定?
- 练一练
20消息队列怎么保证消息不丢失、不重复消费?专业知识技术二面社招进阶
考察点: 对消息链路的完整理解,以及幂等设计。
答题思路:
- 先把链路拆成三段:生产者发送、消息队列存储、消费者消费,每一段都可能丢消息。
- 生产端:使用同步发送或带回调的异步发送,确认发送成功;失败要重试并记录。以 Kafka 为例,可以要求所有同步副本都写入后才确认,并开启生产者幂等。
- 存储端:消息持久化,设置多副本,并配置最少同步副本数,避免只写了一个节点就确认。
- 消费端:业务处理成功后再提交消费位点或确认,而不是一拿到消息就确认。
- 不重复:由于有重试,至少一次投递几乎不可避免,所以重点是消费端做幂等。常见做法:用业务唯一键(如订单号)建唯一索引;处理前查一下是否处理过;状态机只允许按顺序流转;用去重表记录已处理的消息 ID。
- 一句话:不丢靠「每一段都确认」,不重靠「消费端幂等」。
可能的追问: 消息积压了怎么处理?怎么保证消息的顺序?什么是事务消息、解决什么问题?
- 练一练
21设计一个短链接服务。案例分析技术二面校招 · 社招深挖
考察点: 系统设计的思路:先澄清需求,再估算规模,再给出设计,最后讨论扩展和取舍。
答题思路:
- 澄清需求:功能上要支持长链转短链、短链跳转、是否支持自定义短码、是否有过期时间、是否需要访问统计;非功能上关注读多写少、跳转要快、短码不可预测(防止被遍历)。
- 估算规模:和面试官对齐每天新增多少条、访问多少次,估算存储量和读写比例。数字用面试官给的或自己假设的,说清楚是假设。
- 短码生成:方案一是全局唯一的自增 ID 转成 62 进制字符串,短且不重复,但容易被猜到,可以加一层混淆;方案二是对长链做哈希后取一部分,要处理冲突。ID 生成可以用数据库号段或雪花算法这类分布式 ID 方案。
- 存储:短码到长链的映射,短码作为主键或唯一索引;同一个长链是否复用短码要提前定下来。
- 读路径:跳转请求先查缓存,未命中再查数据库并回填;热点短链可以加本地缓存。
- 跳转方式:301 永久重定向浏览器会缓存,减轻服务压力,但统计不到后续访问;302 临时重定向每次都会请求服务,方便统计。按是否需要统计来选。
- 统计:访问记录异步写入消息队列,再批量落库或进入分析系统,不阻塞跳转。
- 扩展:数据量大了按短码分库分表;防刷要做限流和恶意链接检测。
校招怎么答 / 社招怎么答: 校招把需求澄清、短码生成、存储和缓存讲清楚,有条理即可;社招要主动讨论容量估算、高可用、热点处理、数据迁移和监控,并说明每个取舍的依据。
可能的追问: 雪花算法的结构是什么、时钟回拨怎么办?如果要求同一个长链永远只生成一个短链,怎么设计?
- 练一练
22分布式锁有哪些实现方式?各有什么坑?专业知识技术二面社招深挖
考察点: 分布式场景下的并发控制,以及对边界情况的考虑。
答题思路:
- 为什么需要:多个服务实例之间,单机锁管不住,比如防止定时任务重复执行、防止库存超卖。
- 数据库实现:用唯一索引插入一条记录表示加锁,删除表示解锁;简单但性能一般,要处理锁不释放的问题。
- Redis 实现:用「不存在才设置」并带过期时间的命令一步完成加锁;value 存一个唯一标识,解锁时先比较再删除,并且这两步要用脚本保证原子性,避免删掉别人的锁。
- 坑一:锁过期了业务还没执行完,别人拿到了锁。解决:后台线程定时续期(看门狗机制)。
- 坑二:主从切换时,锁还没同步到从节点就切换了,导致锁丢失。对一致性要求极高时可以考虑基于共识协议的协调服务(如 ZooKeeper、etcd)实现的锁。
- 协调服务实现:利用临时顺序节点,客户端断开后节点自动删除,天然避免死锁;可靠性高,但性能比 Redis 低。
- 更稳妥的设计:锁只是第一道防线,关键写操作再配合版本号或「围栏令牌」做校验,防止过期的持锁者把数据写坏。
可能的追问: 可重入的分布式锁怎么实现?不用分布式锁,防超卖还有什么办法(数据库乐观锁、预扣库存)?
- 练一练
23讲一个你项目里遇到的最难的技术问题,你是怎么解决的?行为题(STAR)技术二面业务面校招 · 社招 · 实习 · 跳槽转行深挖
考察点: 真实参与度、技术深度、解决问题的思路。几乎必问,后面的追问往往决定这一轮的结果。
答题思路:
- 用 STAR 结构:背景(项目是什么、问题是什么、为什么难)→ 任务(你负责什么)→ 行动(排查和方案,重点讲你考虑过的几种方案和取舍)→ 结果(可量化的结果,用你自己的真实数据)。
- 「难」要具体:并发导致的数据错误、性能瓶颈、线上偶现的故障、老系统改造、跨团队依赖,挑一个讲透,而不是罗列一堆。
- 主动讲取舍:当时为什么没选另一个方案。
- 准备好被追问三层:「为什么这么做」「有没有更好的办法」「如果重来会怎么改」。
- 不要把团队的成果说成自己的,面试官追问两层就能听出来。
示范回答(校招版):
我讲一个我在【课程项目 / 实习项目:某个选课 / 抢购类系统】里遇到的问题。背景是这个功能在开放的那一刻会有很多人同时提交,我负责后端的下单接口。压测时我发现,【库存为 100】的商品最后卖出了【一百多】件,出现了超卖。我先在本地复现,确认问题出在「先查库存、再扣库存」这两步之间,多个请求同时查到了库存充足。我考虑了三个方案:一是在 Java 代码里加
synchronized,但服务部署多个实例就管不住了;二是用分布式锁,但所有请求排队,吞吐量会很低;三是把扣库存改成一条带条件的 SQL,只有库存大于零才扣减,靠数据库行锁保证原子性。我选了第三种,因为它最简单,而且这个场景的并发量数据库扛得住。改完再压测,没有再出现超卖。之后我又发现同一个用户快速点两次会生成两个订单,就加了「用户 ID + 商品 ID」的唯一索引做幂等。这件事让我明白,并发问题要先在本地稳定复现,再选能解决问题的最简单方案。示范回答(社招版):
我讲【某核心业务系统】的一次稳定性问题。背景是这个服务每天有几次接口超时突增,持续【几十秒】就自己恢复,监控上看不出明显规律,已经影响到上游的成功率。我是这个服务的主要负责人之一,牵头排查。第一步是收集证据:把超时时间点和 GC 日志、数据库慢日志、下游调用耗时对齐,发现每次超时都伴随一次较长的 GC 停顿,而停顿之前老年代上涨很快。第二步定位:在一次停顿前后导出堆转储,发现大量对象来自一个按天汇总的本地缓存,它在某个定时任务刷新时会整体重建,新旧两份数据同时存在,瞬间占用翻倍。第三步方案:我们对比了三种做法——调大堆、改成增量刷新、把这份数据挪到分布式缓存。调大堆只是推迟问题;挪到分布式缓存会让每次请求多一次网络调用;最后选了增量刷新,并给本地缓存加上容量上限和监控。同时把定时任务从整点改成错峰执行。上线后这类超时在【观察周期】内没有再出现,接口较慢分位耗时也从【X 毫秒】降到【Y 毫秒】。复盘时我们补了两条规则:本地缓存必须设上限并接入监控;涉及大批量数据重建的任务要做内存评估。这件事让我更相信,偶发问题要先把多个维度的时间线对齐,证据会自己说话。
可能的追问: 如果当时数据量再大十倍,你的方案还成立吗?这个问题本来可以更早发现吗?你在里面具体写了哪部分代码?
- 练一练
24需求很急,但你觉得技术方案有隐患,你会怎么办?行为题(STAR)业务面终面社招 · 跳槽转行进阶
考察点: 风险意识、沟通方式、能否在业务压力下做出负责任的取舍。
答题思路:
- 先把隐患说清楚、量化:不是说「我觉得不安全」,而是说「这样做在【某种情况】下会导致【数据重复 / 资损 / 服务不可用】,概率和影响大概是多少」。
- 给替代方案而不是只说不行:比如「先上一个简化版本满足上线,同时加上开关和监控,下个迭代补完整方案」,或者「这个功能先在小范围灰度」。
- 和需求方、上级对齐优先级:把选项和各自的风险摆出来,由有决策权的人拍板,自己负责把风险讲透。
- 留下记录:决策结论、已知风险、后续补救计划写进文档或任务单,避免以后说不清。
- 讲一个真实的例子,最后说结果和反思。避免两种极端:一味顺从不提风险,或者坚持己见拖延上线。
校招怎么答 / 社招怎么答: 校招可以讲实习或团队项目中赶截止日期时的类似经历,重点体现你会主动提出问题;社招要讲出完整的风险评估和推动过程,以及事后的机制改进,比如把类似检查加进了方案评审清单。
可能的追问: 如果最后决策者还是坚持按原方案上线,出了问题怎么办?你有没有过判断错误、其实隐患没那么大的时候?
- 练一练
25你之前做的不是 Java 后端(或者不是计算机专业),为什么想转过来?你是怎么准备的?动机与求职意向HR面业务面跳槽转行 · 校招进阶
考察点: 转行动机是否真实、稳定,学习能力和已经具备的实际能力。
答题思路:
- 动机要具体、正向:不要说「后端工资高」「原来的工作没前途」,而是说出你接触后端的契机,以及你在其中获得的兴趣和成就感,比如在原工作中写脚本提升了效率,或者参与过系统对接。
- 用事实证明能力:讲你系统学了什么(Java 基础、Spring、MySQL、Redis),做了什么完整项目(从需求到部署上线),代码放在哪里可以看。
- 把原背景变成优势:原来做测试的懂质量保障,做运维的懂部署和监控,做业务的懂需求,做前端的懂接口协作。
- 对差距要坦诚:承认在大规模系统经验上的不足,并说明你的补足计划。
- 不要编造工作经历或夸大项目规模,技术面一追问就会露馅。
校招怎么答 / 社招怎么答: 非科班校招生重点讲自学路径和项目,说明你已经补齐了数据结构、网络、数据库等基础;社招转行者重点讲原岗位经验如何迁移,以及你做出的可以运行、可以展示的项目。
可能的追问: 你的项目部署在哪里、遇到过什么问题?如果入职后发现后端工作很枯燥怎么办?你给自己定的一年目标是什么?
- 练一练
26面试最后,你有什么想问我们的吗?反问技术二面业务面HR面校招 · 社招 · 实习 · 跳槽转行基础
考察点: 你对这份工作的关注点、思考深度,以及真诚的兴趣。
答题思路:
- 不要说「没有问题」,也不要一上来就问加班和福利(可以留到 HR 面或拿到意向后再问)。
- 技术面可以问:团队负责的系统大致是做什么的、目前最大的技术挑战是什么、技术栈和研发流程是怎样的、线上问题怎么分工处理。
- 主管面可以问:这个岗位最希望新人在前几个月解决什么问题、团队里表现好的人有什么共同特点、新人怎么上手。
- HR 面可以问:后续流程和时间节点、培训和转正安排。
- 问题最好和面试中聊到的内容有关联,显得你在认真听。
可能的追问: 面试官可能顺着你的问题反问你:「如果让你来解决这个挑战,你会怎么做?」所以问之前自己先想一想。
点「练一练」会复制这道题,并跳到页面底部的下载入口;打开 OfferGod 模拟面试后粘贴即可。
05校招、社招和转行准备重点有什么不同?
| 维度 | 校招 / 实习 | 社招 | 跳槽转行 |
|---|---|---|---|
| 基础知识 | 占比高,系统地问 Java 基础、集合、并发、JVM、数据库、网络 | 占比下降,但答不上来会直接扣分 | 一样会系统地问,是证明「补齐了基础」的关键 |
| 算法与手写 | 笔试和一面常有编程题,简单到中等难度 | 视公司而定,多为中等以下,或结合场景的代码题 | 按校招标准准备,至少常见类型都练过 |
| 框架 | 会用 Spring Boot,能讲清 IoC、AOP、事务的基本原理 | 原理 + 踩过的坑 + 在项目里的最佳实践 | 会用并理解基本原理,能说清自己项目里怎么用的 |
| 项目 | 课程、比赛、实习、个人项目,看亲手写的深度 | 业务背景、你的角色、方案对比、量化结果、线上问题 | 至少一个从需求到部署的完整项目,能讲清每个技术选择 |
| 系统设计 | 可能出简单的设计题,看思路是否清晰 | 中高级岗位的重点,要讲容量、高可用、扩展和取舍 | 能讲清自己项目的架构,对常见设计题有基本思路 |
| 线上与稳定性 | 知道常见问题的排查思路 | 必须有真实案例:怎么发现、怎么止血、怎么定位、怎么复盘 | 可以讲本地或自己部署环境中的排查经历 |
| 软技能 | 学习能力、沟通、对后端的兴趣 | 跨团队协作、推动落地、带新人、业务理解 | 转行动机、学习速度、原有经验的迁移 |
| 常见减分点 | 只背八股不会写代码、项目说不出细节 | 只讲「做了什么」不讲「为什么」、没有可量化结果 | 项目照着教程做、讲不出自己的思考,或夸大经历 |
06准备清单(可打印)
投递前
- 拆一遍目标岗位的 JD,按上面的表格列出要重点准备的知识点
- 简历上每一个技术名词都确认自己能被追问三层,不熟的删掉
- 项目经历用「背景—职责—行动—结果」写,结果尽量用自己的真实数据
- 准备好可展示的代码仓库(确认能打开、README 写清楚怎么运行)
- 社招:梳理近两三年 2–3 个代表性项目和 1–2 次线上问题处理,各写一页要点
- 转行:准备一个从需求、设计、开发到部署的完整项目,并能讲出每个技术选择的原因
面试前一周
- Java 基础与集合过一遍:HashMap、ConcurrentHashMap、String、equals 与 hashCode
- 并发过一遍:锁、
volatile、线程池参数和执行流程、AQS 基本思路 - JVM 过一遍:内存区域、垃圾回收器、OOM 和 Full GC 排查步骤
- Spring 过一遍:IoC、AOP、Bean 生命周期、事务失效场景、自动配置
- MySQL 过一遍:索引结构与失效、
EXPLAIN、隔离级别与 MVCC、锁 - 缓存与消息过一遍:穿透击穿雪崩、缓存一致性、消息不丢不重
- 算法按类型练:数组字符串、哈希、双指针、链表、树、简单动态规划
- 至少完整练一道系统设计题,按「需求—估算—设计—扩展」说出来
- 准备项目深挖:每个项目写出「最难的点、方案对比、如果重来会怎么改」
- 准备 3–4 个行为题故事:最难的问题、线上故障、协作分歧、主动推动的事
面试前一天
- 远程面试:检查网络、摄像头、麦克风、共享屏幕和在线编辑器能否正常使用
- 准备一份 1–2 分钟的自我介绍,突出技术栈和代表项目
- 把简历放在手边,再读一遍自己写的项目和项目里的关键数据
- 在纸上画一遍核心项目的架构图,确认能边画边讲
- 准备 2–3 个反问问题
- 早点休息
面试后
- 当天写复盘:被问到了哪些题、哪些没答好、追问停在了哪一层
- 把没答好的题补上,整理进自己的题库
- 社招:记录每家公司的流程和反馈节奏,方便安排后续面试
- 一周左右没消息可以礼貌询问进度
07常见误区有哪些?
八股背得滚瓜烂熟,代码写不出来。
能讲清 HashMap 的扩容过程,却写不出一个线程安全的单例,面试官会觉得基础不实。每个知识点都配一段自己写过、跑过的代码。
项目只讲用了什么技术,不讲为什么。
「我用了 Redis 和 Kafka」不是亮点,「当时查询压力集中在少量热点数据上,所以加了缓存;下单后的通知不需要同步完成,所以用消息队列异步处理,并在消费端做了幂等」才是。
简历写了「熟悉高并发、分布式」,却讲不出一个真实场景。
写在简历上的每个词都可能被深挖,没做过就如实写你做过的,比被追问到答不上来好得多。
结果没有数据,或者数据编得太夸张。
优化类经历要有前后对比,但数据要真实、能解释,能说出是在什么环境、用什么方法测的。
线上问题只讲「重启了就好了」。
面试官想听的是你怎么保留现场、怎么定位根因、怎么避免再次发生。
系统设计题一上来就画架构图。
先问清需求和规模,再动手设计,边设计边说明取舍,比直接堆一堆组件名更能体现水平。
遇到不会的题硬编。
坦诚说「这块我了解不深,我的理解是……」,再说你会怎么去查证,比编一个错误答案好得多。
转行同学照着教程做一个项目就写上简历。
至少要在教程基础上做出自己的改动,比如加一个新功能、解决一个教程没处理的问题,并能讲清楚为什么这么改。
反问环节说「没有问题」。
准备两三个真诚的问题,比如团队目前最大的技术挑战是什么,能体现你的兴趣和思考。
08你被问到过类似的题吗?
你在 Java 后端面试里遇到过这页没收录的题吗?或者被某道题的追问问住过吗?欢迎通过页面底部的「发现内容有误或侵权?告诉我们」入口,把题目和当时的情况发给我们,采纳后会补进题库,帮到后面准备面试的人。
09参考来源与审稿
参考来源
作者
OfferGod 求职攻略编辑部
原创或改写,示范回答只是思路参考
内容核对于 2026 年 10 月 20 日
相关岗位与题目
- AI 应用工程师
- 数据分析师
- 前端开发工程师
- 新媒体运营
- 产品经理
- 测试开发 / 软件测试工程师
- 高频题:面试被问「你最大的缺点是什么」怎么回答?(校招 / 社招示范)
- 高频题:面试被问「未来 3–5 年职业规划」怎么回答?(校招 / 社招示范)
- 高频题:面试问「和同事 / 领导意见不合怎么办」怎么回答?(校招 / 社招示范)
- 高频题:简历空窗期怎么解释?(社招离职空档 / 校招考研考公空档示范)
- 高频题:面试问「讲一次失败的经历」怎么回答?(校招 / 社招示范)
- 高频题:面试问「你的抗压能力怎么样」怎么回答?(校招 / 社招示范)
- 高频题:面试问「你还面试了哪些公司 / 手上有别的 offer 吗」怎么回答?(校招 / 社招示范)
- 高频题:面试问「最有成就感的一件事」怎么答?(STAR 框架 + 校招 / 社招示范)
- 高频题:面试最后「你还有什么问题要问我」怎么反问?(校招 / 社招示范)
- 高频题:面试被问「期望薪资多少」怎么回答?(校招 / 社招示范)
- 高频题:面试自我介绍怎么说?(1 分钟 / 3 分钟,校招 / 社招示范)
- 高频题:面试被问「你的优点 / 优势是什么」怎么回答?(校招 / 社招示范)
- 高频题:面试被问「我们为什么要录用你」怎么回答?(校招 / 社招示范)
- 高频题:面试被问「为什么离职」怎么说?(社招离职原因 / 校招为什么不留在实习单位)
- 高频题:面试被问「为什么选择我们公司 / 为什么想来这个岗位」怎么回答?(校招 / 社招示范)
看完想开口练一练?
OfferGod 电脑端可以按岗位和轮次做模拟面试,练完看复盘报告。