当前位置: 首页 > news >正文

Java面试题全网最全整理(附答案),已按模块分类,从基础到实战一篇搞定

最近帮团队面了 20 多个 3-5 年经验的 Java 候选人,发现一个共性问题:简历上列满了 "精通 SpringBoot"" 熟练 Redis""熟悉分布式事务",但一深问就露馅 —— 说懂 HashMap,却讲不清红黑树转链表的阈值为什么是 8;提过项目用了缓存,却答不出缓存和数据库一致性的具体解决方案。

3-5 年这个阶段,面试官早已不满足于 "你用过什么",而是要看 "你吃透了什么",更重要的是 "你怎么用技术解决实际问题"。本文结合近百场面试经验,拆解这个阶段的核心考察点,附上面试官期待的 "深度回答模板" 和 "项目结合案例"。

一、Java 基础与并发:从 "会用" 到 "懂原理"

1. HashMap 源码:不止是 "数组 + 链表 + 红黑树"

初级回答:"HashMap 底层是数组加链表,JDK1.8 后当链表长度超过 8 会转红黑树,默认负载因子 0.75,初始容量 16。"(这是应届生都该知道的)

3 年 + 该有的深度

  • 为什么链表转红黑树的阈值是 8?"因为 HashMap 的作者通过泊松分布计算,链表长度超过 8 的概率低于千万分之一,所以用 8 作为转树阈值,平衡查询效率和内存开销。而转回链表的阈值是 6,避免频繁在树和链表间转换( hysteresis 机制)。"
  • 项目中的实际应用:"我们订单系统之前用 HashMap 存用户购物车,发现高并发下偶尔出现死循环。排查后发现是 JDK1.7 的头插法在扩容时导致的循环链表,后来升级 JDK1.8 并用 ConcurrentHashMap 替代,同时初始化时指定容量(如 new HashMap<>(1024))减少扩容次数,性能提升了 30%。"

2. synchronized 锁升级:从偏向锁到重量级锁的触发条件

必问点:JDK1.6 后 synchronized 的优化机制。

深度回答:" 锁升级是 JVM 对 synchronized 的性能优化,过程是无锁→偏向锁→轻量级锁→重量级锁:

  • 偏向锁:单线程场景下,通过 CAS 在对象头 Mark Word 记录线程 ID,后续该线程可直接获取锁,避免每次 CAS 操作。
  • 轻量级锁:当有第二个线程竞争时,偏向锁撤销,线程通过 CAS 将 Mark Word 替换为锁记录指针,此时线程交替执行(自旋),不阻塞。
  • 重量级锁:当竞争加剧(自旋次数超过 10 或线程数超过 CPU 核心数一半),轻量级锁膨胀为重量级锁,依赖操作系统 mutex 锁实现,线程会阻塞挂起。

项目中我们在用户登录接口用了 synchronized,初期以为会性能差,后来发现多数情况是单用户操作,锁停留在偏向锁状态,实际性能损耗很小。但当遇到爬虫高频请求时,锁升级为重量级锁,接口响应变慢,最后用 Redis 分布式锁替代解决了问题。"

3. 线程池:不止是 7 个参数,而是 "动态调整" 的智慧

面试官想听的不是参数背诵,而是 "为什么这么配置"

结合项目的回答:" 我们支付系统的线程池配置是核心线程数 10,最大线程数 20,队列用 ArrayBlockingQueue (1000),拒绝策略 CallerRunsPolicy。

  • 核心线程数 10:根据压测,每秒 100 笔支付请求,每笔请求平均耗时 100ms,10 个线程刚好能扛住(100×0.1=10)。
  • 最大线程数 20:应对瞬时峰值(如秒杀时每秒 200 笔),临时线程在峰值过后会在 60 秒后销毁(keepAliveTime=60s)。
  • 有界队列:防止订单量暴增时 OOM,队列满时通过 CallerRunsPolicy 让调用线程处理,变相限流。

后来发现凌晨对账时,核心线程长期空闲,通过设置 allowCoreThreadTimeOut (true) 让核心线程超时销毁,减少了 20% 的内存占用。"

二、JVM:从 "理论" 到 "实战调优"

1. G1 收集器:如何把 Full GC 控制在 50ms 内

初级回答:"G1 是区域化分代式收集器,把堆分成多个 Region,兼顾吞吐量和延迟。"

3 年 + 该有的调优经验:" 我们订单系统用 G1 时,曾因 Full GC 频繁导致接口超时。排查步骤:

  1. 用 jstat -gcutil 发现 Old 区占比达 90%,FGC 间隔不到 1 分钟,每次耗时 150ms。
  2. 分析 heap dump 发现大量 Order 对象未回收,追溯到订单状态机设计缺陷,导致历史订单对象被静态集合引用。
  3. 修复后仍有偶发 FGC,通过 - XX:InitiatingHeapOccupancyPercent=40(默认 45)让 Mixed GC 提前触发,同时调大 - XX:G1HeapRegionSize=16m(原 8m),减少大对象跨 Region 分配的碎片。
    最终 FGC 消失,Young GC 耗时稳定在 20ms 内。"

2. 内存泄漏:从 "知道" 到 "定位解决"

面试官想听到的排查链路

" 之前用户中心服务频繁 OOM,排查过程:

  1. 用 jmap -histo:live <pid>发现 char [] 占比 60%,推测是字符串缓存未清理。
  2. 生成堆快照(jmap -dump)后用 MAT 分析,发现一个 HashMap 中存储了千万级用户 Token,且没有过期清理机制。
  3. 追溯代码发现是早期为了减少 Redis 访问,用 HashMap 做了本地缓存,但忘了设置过期时间。
  4. 解决:改用 Caffeine 缓存(设置 expireAfterWrite=30 分钟),并限制最大容量 10 万,内存占用从 4G 降到 1.5G。"

三、框架:从 "会用注解" 到 "懂源码设计"

1. Spring 事务:为什么加了 @Transactional 却没生效?

初级回答:"可能是方法不是 public,或者没加 @Service 注解。"

3 年 + 该有的踩坑经验:" 项目中遇到过三种事务失效场景:

  1. 自调用问题:同一类中 A 方法调用 B 方法(B 加了 @Transactional),因未经过 Spring 代理,事务不生效。解决:用 AopContext.currentProxy () 获取代理对象调用。
  2. 异常被捕获:B 方法中 try-catch 了异常但未抛出,事务无法感知。解决:在 catch 中手动 throw new RuntimeException (),或设置 rollbackFor=Exception.class。
  3. 多线程调用:A 方法启动新线程调用 B 方法,B 的事务和 A 不在同一线程,无法回滚。解决:用消息队列保证最终一致性,或分布式事务。"

2. SpringBoot 自动装配:为什么引入 starter 就能用?

深度回答:" 自动装配的核心是 @EnableAutoConfiguration,它通过 @Import 导入 AutoConfigurationImportSelector,这个类会加载 META-INF/spring.factories 中的自动配置类(如 RedisAutoConfiguration)。

这些配置类通过 @Conditional 注解判断是否生效,比如 RedisAutoConfiguration 上的 @ConditionalOnClass (RedisOperations.class),只有类路径存在 RedisOperations 时才会生效。

我们项目自定义了支付 starter,核心是在 spring.factories 中配置 PayAutoConfiguration,并用 @ConditionalOnProperty (prefix="pay", name="enabled", havingValue="true") 让用户通过配置开关控制,同时用 @ConditionalOnMissingBean 允许用户自定义支付实现类。"

四、数据库与缓存:从 "会写 SQL" 到 "懂优化本质"

1. MySQL 索引:为什么加了索引还是慢?

结合案例的回答:" 订单表(1000 万行)查用户最近 30 天的订单,加了索引 idx_user_create_time (user_id, create_time) 还是慢,排查发现:

  1. 索引失效:SQL 用了 create_time > now () - interval 30 day,虽然联合索引前缀 user_id 是等值查询,但函数操作导致索引失效?不,这里是范围查询,联合索引中范围条件后的字段无法使用索引,但前缀 user_id 是有效的。
  2. 实际原因:用户 ID 是高频用户(如商家账号),该用户的订单占了 300 万行,即使走索引,扫描 300 万行还是慢。
  3. 优化:按 create_time 分表(每月一张),查询时先定位到最近 30 天所在的表,再用索引,查询时间从 500ms 降到 50ms。"

2. Redis 缓存:如何解决缓存与数据库一致性问题?

不是只说 "先删缓存再更新 DB",而是分场景

" 我们根据业务一致性要求选择方案:

  1. 商品详情页(允许短暂不一致):用 ' 更新 DB 后删缓存 ',配合 Redis 过期时间兜底。删缓存失败时用消息队列重试,避免缓存脏数据。
  2. 库存系统(强一致性):用 ' 分布式锁 + 先更新 DB 再更缓存 ',更新 DB 时加行锁,保证同一商品的库存更新串行执行,缓存更新失败则回滚 DB。
  3. 历史订单查询(最终一致性):异步更新缓存,DB 更新后发消息到 RocketMQ,消费者更新缓存,失败则死信队列重试,适合非实时场景。"

五、分布式:从 "知道概念" 到 "落地权衡"

1. 分布式事务:不是只有 TCC,而是 "选对方案"

面试官想听的是权衡思维

" 我们不同场景用了不同方案:

  • 转账业务(强一致性):用 Seata 的 AT 模式,基于 undo log 自动回滚,开发成本低,性能满足每秒 500 笔的需求。
  • 订单创建(最终一致性):用本地消息表,订单表插入时同时写消息表,本地事务保证两者原子性,然后异步发送消息给库存服务,失败则定时任务重试。
  • 积分兑换(高并发):用 TCC 模式,Try 阶段冻结积分和库存,Confirm 实际扣减,Cancel 解冻,适合秒杀场景(每秒 2000 单),但开发成本高,需要手写 3 个接口。"

2. 消息队列:如何保证消息不丢失、不重复?

项目实战经验:" 基于 RocketMQ 的方案:

  • 不丢失:
  1. 生产者:用同步发送 + 事务消息,发送失败重试 3 次,确保消息到 Broker。
  2. Broker:开启持久化(刷盘策略 ASYNC_FLUSH),主从同步,避免单点故障。
  3. 消费者:关闭 autoCommit,处理完业务再手动 ack,失败则稍后重试。
  • 不重复:消费者端用消息 ID + 业务唯一键(如订单号)做幂等,存 Redis(set nx 5 分钟),重复消息直接返回成功。

我们在秒杀场景中,即使消息重复,也能保证库存不超卖,因为扣减库存时会检查 ' 库存 >= 购买量 ',且用了 Redis 分布式锁。"

六、3-5 年面试的 3 个突围技巧

  1. 用 "问题 - 方案 - 数据" 结构讲项目:别说 "我负责订单系统",而要说 "订单系统在秒杀时 QPS 从 500 涨到 5000,出现库存超卖和接口超时(问题),我引入 Redis 预扣库存 + 消息队列异步下单 + 本地缓存热点商品(方案),最终支撑了 10 万单 / 秒,接口响应时间从 800ms 降到 50ms(数据)"。
  2. 主动暴露 "踩坑经历":面试官喜欢听你解决过的问题,比如 "之前用 HashMap 存缓存导致内存泄漏,后来换成 Caffeine 并设置过期时间",这比说 "我精通各种缓存" 更可信。
  3. 讲清 "技术选型的权衡":比如 "为什么不用 TCC 而用本地消息表?因为团队当时对 TCC 理解不深,本地消息表更易实现,虽然一致性弱一点,但满足业务需求,后期再迭代优化"—— 体现务实的工程思维。

结语:3-5 年,拼的是 "技术深度 × 项目落地能力"

这个阶段的面试,早已不是 "背源码"" 列技术栈 " 能应付的。面试官更看重你对技术的理解深度(如为什么这么设计)、解决问题的思路(如排查 OOM 的步骤),以及在项目中如何权衡技术选型(如一致性与性能的取舍)。

把每个技术点和实际项目结合,讲清 "你遇到了什么问题,用什么技术解决,为什么这么选,带来了什么效果",这才是 3-5 年 Java 后端突围的关键。祝你面试顺利,拿到心仪的薪资!

面试题笔记分享

为了助力朋友们跳槽面试、升职加薪、职业困境,提高自己的技术,本文给大家整了一套涵盖Java后端面试所有技术栈的快速学习方法和笔记。目前已经收到了七八个网友的反馈,说是面试问到了很多这里面的知识点。

通过大数据总结发现,其实Java后端面试都是差不多的。常问的有下面这几块知识点:

【文末可以无偿领取Java后端面试全套资料】

基础篇

  • Java语言有哪些特点?
  • 面向对象和面向过程的区别?
  • 八种基本数据类型的大小,以及他们的封装类?
  • 标识符的命名规则?
  • instanceof关键字的作用重载和重写的区别?
  • equals与==的区别?

JVM篇

  • 类加载与卸载?
  • 简述一下JVM的内存模型?
  • 堆和栈的区别?
  • 什么时候会触发FullGC?
  • 什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"?
  • Java内存结构?

多线程&并发篇

  • Java中实现多线程有几种方法?
  • 如何停止一个正在运行的线程?
  • notify()和notifyAll()有什么区别?
  • sleep()和wait()有什么区别?
  • volatile 是什么?可以保证有序性吗?
  • Thread 类中的start()和run()方法有什么区别?

Spring篇

  • Spring的IOC和AOP机制?
  • Spring中Autowired和Resource关键字的区别?
  • 依赖注入的方式有几种,各是什么?
  • 讲一下什么是Spring?
  • Spring MVC流程?
  • SpringMVC怎么样设定重定向和转发的?

MyBatis篇

  • 什么是MyBatis?
  • MyBatis的优点和缺点?
  • #和$的区别是什么?
  • 当实体类中的属性名和表中的字段名不一样,怎么办?
  • Mybatis是如何进行分页的?分页插件的原理是什么?

SpringBoot篇

  • 什么是SpringBoot?为什么要用SpringBoot
  • Spring Boot的核心注解是哪个?它主要由哪几个注解组成的?
  • 运行Spring Boot有哪几种方式?
  • 如何理解Spring Boot 中的Starters?

MySQL篇

  • 数据库的三范式是什么?
  • 数据库引擎有哪些?
  • InnoDB与MyISAM的区别?
  • 数据库的事务?
  • 索引问题?
  • SQL优化?

Redis篇

  • Redis持久化机制?
  • 缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题?
  • 热点数据和冷数据是什么?
  • Memcache与Redis的区别都有哪些?

SpringCloud篇

  • 什么是SpringCloud?
  • 什么是微服务?
  • SpringCloud有什么优势?
  • 什么是服务熔断?什么是服务降级?

Nginx篇

  • 简述—下什么是Nginx,它有什么优势和功能?
  • Nginx是如何处理一个HTTP请求的呢?
  • 列举—些Nginx的特性?
  • 请列举Nginx和Apache之间的不同点?

zookeeper篇

  • ZooKeeper 是什么?
  • ZooKeeper提供了什么?
  • Zookeeper 文件系统?
  • ZAB 协议?
  • 四种类型的数据节点Znode?
  • ZookeeperWatcher机制-数据变更通知?

kafka篇

  • 如何获取topic主题的列表?
  • 生产者和消费者的命令行是什么?
  • consumer是推还是拉?
  • 讲讲kafka维护消费状态跟踪的方法
  • 讲一下主从同步?

MQ篇

  • 为什么使用MQ
  • MQ优缺点?
  • 如何保证高可用的?
  • 如何保证消息的顺序?

Elasticsearch篇

  • elasticsearch了解多少,说说你们公司es的集群架构,索引数据大小,分片有多少,以及一些调优手段。
  • elasticsearch 的倒排索引是什么
  • elasticsearch索引数据多了怎么办,如何调优,部署
  • elasticsearch是如何实现 master 选举的

Linux篇

  • 绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示?切换目录用什么命令?
  • 怎么查看当前进程?怎么执行退出?怎么查看当前路径?
  • 怎么清屏?怎么退出当前命令?怎么执行睡眠?怎么查看当前用户id?查看指定帮肋用什么
  • Ls命令执行什么功能?可以带哪些参数,有什么区别?
  • 建立软链接(快捷方式),以及硬链接的命令。

最后作为一位过来人也是希望大家少走一些弯路,在这里我给大家分享一些Java后端面试的学习资料,这些资料希望能给你前进的路上带来帮助。【点击下方名片无偿领取Java后端面试全套资料】

http://www.jsqmd.com/news/797424/

相关文章:

  • 大连奢侈品包包变现服务测评:五家平台分级解析,收的顶以专业引领行业 - 奢侈品回收测评
  • py每日spider案例之某插件请求接口加密参数逆向(aes 难度一般)
  • HYMiniMall项目实战:如何基于现有架构快速扩展新功能模块的完整指南
  • CANN Ascend C SetStride API
  • CANN/asc-devkit SetStartPosition API文档
  • 紧急更新!Midjourney v6.2.1已悄然调整Pokeberry印相底层LUT加载机制:3小时内必须重校准的2个关键变量
  • 重庆川岳机电设备:高新区可靠的设备吊装哪家好 - LYL仔仔
  • Gemini如何重构Google搜索体验:3个被90%开发者忽略的AI增强接口与调用陷阱
  • 2026年 不锈钢工程厂家推荐排行榜:房屋、商场、写字楼、会展中心等多场景不锈钢工程优质之选! - 速递信息
  • CANN/Ascend C WholeReduceSum API文档
  • Qt 软件外包开发流程
  • 3分钟上手FanControl:让Windows电脑风扇更智能更安静
  • Springboot+Vue3|毕业设计美食分享平台(源码)
  • 2026交调系统排行榜,广州聚杰芯科凭多系列产品覆盖全场景监测 - 品牌速递
  • 2026年云南省汽车后市场观察:V-KOOL威固陆良金锋旗舰店打造本地化贴膜服务标杆 - 速递信息
  • 温州市方氏建材:苍南专业的建材批发工厂 - LYL仔仔
  • 从零到一:基于STM32F030的SPI驱动74HC595实战解析
  • CANN/asc-devkit SPM缓冲区写入API
  • 黄金变现选对平台少走弯路,厦门 5 家机构测评:收的顶全国连锁更放心 - 奢侈品回收测评
  • AI-Trader API完全参考手册:从注册到交易的完整接口指南
  • 【信息科学与工程学】【制造工程】【通信工程】第一百篇 核心路由器参数构建框架04
  • 2026年多模态中医四诊仪行业选型分析:主流品牌核心能力与场景适配指南 - 产业观察网
  • Triplet Loss调参实战:Margin设多少?Batch Size怎么选?我的模型为什么收敛慢?
  • 2026年旱地冰壶定制厂家推荐:张家口市中聚新材料科技有限公司 - 品牌推荐官
  • APEX硬件运动引擎+8KB FIFO:ICM-45686的片上算法与数据管理能力
  • 微信小程序交互实战(1)— 从bindtap到setData的数据驱动视图更新
  • 西安高新鑫伟瑞家具维修:高陵专业的沙发翻新公司有哪些 - LYL仔仔
  • 靶向心血管系统的腺相关病毒(AAV)血清型及启动子选择
  • 无锡留学中介机构哪家好?2026年稳定可靠之选 - 速递信息
  • 动态投资组合优化与量子计算应用