java后端面试一般问什么?

Java 后端面试的问题主要围绕基础能力、核心技术、框架应用、项目经验、性能优化、工程化 六大维度展开,不同公司 / 职级(校招 / 社招、初级 / 中高级)的侧重点不同,下面按优先级和高频度整理,方便你针对性准备:

一、Java 基础(必问,所有级别)

这是面试的 "敲门砖",校招 / 初级岗会深挖,中高级岗侧重结合场景提问。

  1. 核心语法 & 特性

    • 面向对象三大特性(封装 / 继承 / 多态)的理解 + 实际应用场景(比如多态在 Spring 中的体现)
    • 接口 vs 抽象类(区别、使用场景)
    • 重载(Overload)vs 重写(Override)(区别、底层原理)
    • 异常体系:Checked Exception vs Unchecked Exception,常见异常(NullPointerException/IndexOutOfBoundsException 等)的产生原因和解决方案,try-catch-finally 的执行顺序(比如 finally 中修改返回值的坑)
    • 泛型:作用、通配符(? extends T / ? super T)、泛型擦除及影响
    • 注解:自定义注解的实现、元注解(@Target/@Retention 等),Spring 中常用注解的原理(比如 @Autowired)
  2. JVM(重中之重)

    • 运行时数据区(方法区 / 堆 / 栈 / 程序计数器 / 本地方法栈),各区域的作用、OOM 可能发生的区域
    • 垃圾回收(GC):常见垃圾回收器(Serial/Parallel/CMS/G1/ZGC),GC 算法(标记 - 清除 / 标记 - 整理 / 复制),判断对象存活的方式(引用计数法 / 可达性分析),强 / 软 / 弱 / 虚引用的区别及使用场景(比如弱引用在 ThreadLocal 中的应用)
    • 类加载机制:双亲委派模型(原理、好处、如何打破),类加载的过程(加载 / 验证 / 准备 / 解析 / 初始化)
    • 内存泄漏 vs 内存溢出(区别、常见场景:比如静态集合持有对象、未关闭的连接)
  3. 集合框架

    • 常用集合:ArrayList vs LinkedList(底层实现、查询 / 增删效率、使用场景),HashMap(JDK7 vs JDK8 底层变化:数组 + 链表→数组 + 链表 / 红黑树,哈希冲突解决方式,扩容机制,线程不安全的原因)
    • 线程安全集合:ConcurrentHashMap(JDK7 vs JDK8 实现差异,锁粒度:分段锁→CAS+Synchronized),Vector/Hashtable(为什么不推荐用)
    • HashSet 的底层实现(基于 HashMap),TreeMap 的排序原理
  4. 多线程 & 并发

    • 线程创建方式(继承 Thread / 实现 Runnable/Callable+Future),线程的生命周期(新建 / 就绪 / 运行 / 阻塞 / 终止)
    • 线程安全问题:可见性 / 原子性 / 有序性,volatile 关键字(作用、底层原理:内存屏障)
    • 锁机制:Synchronized(底层:偏向锁 / 轻量级锁 / 重量级锁,锁升级过程)、Lock 接口(ReentrantLock、公平锁 / 非公平锁),Synchronized vs Lock 的区别
    • 并发工具类:CountDownLatch/CyclicBarrier/Semaphore(作用、使用场景、区别),ThreadPoolExecutor(核心参数、拒绝策略、常见线程池(FixedThreadPool/CachedThreadPool)的问题)
    • 线程池的核心参数:corePoolSize/maximumPoolSize/keepAliveTime/workQueue,如何合理设置线程池参数

二、Java 核心技术(中高级岗重点)

  1. IO/NIO

    • BIO/NIO/AIO 的区别、使用场景,NIO 的核心组件(Channel/Buffer/Selector),Reactor 模式
    • 零拷贝(mmap/sendfile)的原理和应用(比如 Netty、kafka)
  2. 网络编程

    • TCP/IP 三次握手 / 四次挥手(为什么三次握手、四次挥手),TCP 的可靠性机制(重传 / 滑动窗口 / 拥塞控制)
    • HTTP 协议:HTTP1.0/1.1/2.0 的区别,GET vs POST(区别、幂等性),HTTPS 的加密过程(非对称加密 + 对称加密 + CA 证书)

三、框架 & 中间件(后端核心,所有级别)

  1. Spring 全家桶(必问)

    • Spring Core:IOC 容器(原理、Bean 的生命周期、Bean 的作用域(singleton/prototype)、循环依赖的解决方式),AOP(原理:动态代理(JDK/CGLIB)、切面 / 切点 / 通知、应用场景:事务 / 日志 / 权限)
    • Spring Boot:自动配置原理(@EnableAutoConfiguration、SPI 机制),starter 的实现原理,配置优先级
    • Spring MVC:工作流程(DispatcherServlet 的作用、九大组件),参数绑定的原理
    • Spring Transaction:事务的传播特性、隔离级别,事务失效的场景(比如非 public 方法、异常捕获未抛出、多线程)
  2. MyBatis

    • 核心原理:SqlSessionFactory/SqlSession/Mapper 接口的动态代理,一级缓存 / 二级缓存
    • 动态 SQL 的实现,#{} vs ${}(区别、SQL 注入问题)
    • 分页实现(RowBounds vs 分页插件)
  3. 中间件(高频)

    • MySQL
      • 索引:聚簇索引 / 非聚簇索引,B + 树索引的原理,索引失效的场景(like % xxx、字段类型不匹配等)
      • 事务:ACID 特性,隔离级别(读未提交 / 读已提交 / 可重复读 / 串行化),MVCC 的原理(版本链 /undo log/ReadView)
      • 锁:行锁 / 表锁,乐观锁 / 悲观锁,死锁的产生和解决
      • 优化:慢查询优化(explain 执行计划),分库分表(Sharding-JDBC),主从复制原理
    • Redis
      • 数据结构:String/List/Hash/Set/ZSet 的底层实现(比如 String 的 SDS、Hash 的 ziplist/hashtable),使用场景
      • 过期策略:惰性删除 / 定期删除,内存淘汰策略(LRU/LFU 等)
      • 持久化:RDB vs AOF(区别、优缺点),主从复制原理,哨兵模式 / 集群模式
      • 缓存问题:缓存穿透 / 缓存击穿 / 缓存雪崩(原因、解决方案)
    • 消息队列(RabbitMQ/Kafka)
      • 核心概念:交换机 / 队列(RabbitMQ),主题 / 分区 / 副本(Kafka)
      • 消息可靠性:生产者确认、消费者确认、死信队列,消息重复消费的解决(幂等性)
      • Kafka:高可用原理(ISR 机制),分区分配策略,消费者 Rebalance
    • 其他:Nginx(反向代理 / 负载均衡)、Elasticsearch(倒排索引、分词、集群架构)、分布式锁(Redis/Zookeeper 实现)

四、项目经验 & 场景题(社招 / 中高级岗核心)

  1. 项目深挖

    • 项目的核心业务、技术架构(画架构图),你负责的模块和核心功能
    • 项目中的难点问题(比如性能瓶颈、高并发、数据一致性),如何分析、解决,最终效果
    • 技术选型的原因(比如为什么用 Redis 不用 Memcached,为什么用 Kafka 不用 RabbitMQ)
  2. 场景题

    • 高并发场景:秒杀系统设计(限流、削峰、防超卖),接口防刷(令牌桶 / 漏桶)
    • 数据一致性:分布式事务(2PC/TCC/SAGA/ 最终一致性),缓存与数据库的一致性
    • 高可用:服务降级 / 熔断(Sentinel/Hystrix),服务注册发现(Nacos/Eureka)

五、工程化 & 软实力

  1. 工程化:Git 版本管理(分支策略),Maven/Gradle(依赖管理、打包),Docker 容器化,CI/CD 流程
  2. 设计模式:单例模式(饿汉 / 懒汉 / 双重检查锁的坑)、工厂模式、代理模式、观察者模式等(理解 + 应用场景)
  3. 软实力:技术学习方法、项目中遇到的最大挑战、职业规划

总结

  1. 基础为王:Java 基础(JVM、多线程、集合)是所有面试的核心,必须吃透原理 + 场景;
  2. 框架 / 中间件:Spring 核心(IOC/AOP)、MySQL(索引 / 事务)、Redis(数据结构 / 缓存问题)是高频考点,要结合项目讲清应用;
  3. 项目导向:社招 / 中高级岗更看重 "解决问题的能力",准备 1-2 个核心项目,深挖难点和解决方案,而非单纯罗列功能。

不同职级的准备重点:校招 / 初级岗侧重基础 + 框架使用;中高级岗侧重原理 + 性能优化 + 架构设计;资深岗侧重技术选型 + 复杂场景解决方案。

有哪些常见的Java后端面试题及答案?

一、Java 基础(必背)

1. 面向对象三大特性及应用场景?

答案

  • 封装:隐藏对象的属性和实现细节,仅对外暴露接口。比如 JavaBean 的私有属性 + get/set 方法,Spring Bean 封装了核心逻辑,对外提供调用接口。
  • 继承 :子类继承父类的属性和方法,提高代码复用。比如 Spring 的AbstractApplicationContext作为父类,子类(AnnotationConfigApplicationContext)复用核心逻辑。
  • 多态 :同一行为不同表现形式(编译时类型和运行时类型不一致)。比如 Spring 中ApplicationContext接口的不同实现类(ClassPathXmlApplicationContext、AnnotationConfigApplicationContext),调用getBean()时表现不同,是多态的典型应用。
2. 接口和抽象类的区别?
维度 接口(Interface) 抽象类(Abstract Class)
成员变量 只能是public static final 可以有任意修饰符的成员变量
方法 JDK8 前:只能抽象方法;JDK8 后:可定义默认方法 / 静态方法 可以有抽象方法,也可以有普通方法
继承 / 实现 类可实现多个接口 类只能继承一个抽象类
构造方法
使用场景 定义规范 / 能力(比如Runnable 复用代码 + 定义规范(比如AbstractList
3. HashMap JDK7 和 JDK8 的区别?

答案

维度 JDK7 JDK8
底层结构 数组 + 链表 数组 + 链表 / 红黑树(链表长度≥8 且数组长度≥64 时转红黑树)
哈希计算 4 次位运算 + 1 次取模 扰动函数(多次异或 + 右移)+ 取模
插入方式 头插法(扩容时可能导致链表循环) 尾插法(解决循环问题)
扩容机制 扩容后重新计算所有元素的哈希 扩容后通过(hash & oldCap) == 0判断元素是否需要移动,减少计算
线程安全 不安全(并发扩容导致死循环) 不安全(但死循环问题解决)
4. volatile 关键字的作用?

答案

  • 可见性:一个线程修改 volatile 变量后,其他线程能立即看到最新值(底层通过内存屏障,禁止 CPU 缓存,直接读写主存)。
  • 有序性 :禁止指令重排序(比如 DCL 单例中,volatile 防止instance = new Singleton()被拆分为 "分配内存→初始化→赋值" 的重排序,导致其他线程拿到未初始化的对象)。
  • 不保证原子性 :比如i++(读取 - 修改 - 写入)仍会线程不安全,需配合AtomicInteger或锁。
5. 线程池的核心参数及如何合理设置?

答案:核心参数(ThreadPoolExecutor):

  1. corePoolSize:核心线程数(常驻线程,即使空闲也不销毁);
  2. maximumPoolSize:最大线程数(核心线程 + 临时线程的总数);
  3. keepAliveTime:临时线程空闲超时时间;
  4. workQueue:任务队列(核心线程满后,任务先入队,队列满才创建临时线程);
  5. handler:拒绝策略(队列满 + 线程数达最大值时触发,比如 AbortPolicy(抛异常)、CallerRunsPolicy(调用者执行))。

合理设置

  • CPU 密集型任务(比如计算):核心线程数 = CPU 核心数 + 1(减少线程切换);
  • IO 密集型任务(比如数据库 / 网络调用):核心线程数 = CPU 核心数 × 2(IO 等待时线程空闲,可利用多核);
  • 队列选择:用有界队列(比如 ArrayBlockingQueue),避免无界队列(LinkedBlockingQueue)导致内存溢出;
  • 拒绝策略:非核心任务用 CallerRunsPolicy(降级),核心任务用 AbortPolicy(快速失败)。
6. JVM 运行时数据区有哪些?OOM 可能发生在哪些区域?

答案:运行时数据区(JDK8):

  1. 程序计数器:记录线程执行的字节码行号,唯一不会 OOM 的区域;
  2. 虚拟机栈 :存储方法栈帧(局部变量、操作数栈等),栈深度超限抛StackOverflowError,创建线程过多 / 栈帧过大抛 OOM;
  3. 本地方法栈:为 Native 方法服务,和虚拟机栈类似,会抛 StackOverflowError/OOM;
  4. :存储对象实例(new 的对象),最易 OOM(java.lang.OutOfMemoryError: Java heap space);
  5. 方法区(元空间) :存储类信息、常量、静态变量等,JDK8 前是永久代,OOM 为PermGen space;JDK8 后是元空间(占用本地内存),但元空间大小不足也会 OOM。

二、Spring 全家桶(高频)

7. Spring IOC 容器的原理?

答案:IOC(控制反转):将对象的创建、依赖注入由程序员控制转为 Spring 容器控制,核心流程:

  1. 加载配置:读取 XML / 注解配置,解析出需要创建的 Bean 定义(BeanDefinition);
  2. 实例化 Bean:通过反射创建 Bean 实例(单例 Bean 默认在容器启动时创建,原型 Bean 每次获取时创建);
  3. 依赖注入:将 Bean 的依赖对象注入(比如 @Autowired);
  4. 初始化 Bean :执行@PostConstructInitializingBeanafterPropertiesSet()方法;
  5. Bean 就绪:存入单例池(singletonObjects),供后续获取;
  6. 销毁 Bean :容器关闭时,执行@PreDestroyDisposableBeandestroy()方法。
8. Spring 如何解决循环依赖?

答案 :循环依赖:A 依赖 B,B 依赖 A(仅支持单例 Bean,原型 Bean 无法解决),核心靠 "三级缓存":

  1. 一级缓存(singletonObjects):存储完全初始化的单例 Bean;
  2. 二级缓存(earlySingletonObjects):存储提前暴露的、未完成初始化的 Bean;
  3. 三级缓存(singletonFactories):存储 Bean 的工厂方法,用于创建代理对象。

核心流程:

  • A 创建时,先存入三级缓存→去创建 B;
  • B 创建时依赖 A,从三级缓存获取 A 的半成品→存入二级缓存,B 完成初始化;
  • A 从二级缓存拿到 B,完成初始化,存入一级缓存,删除二 / 三级缓存。
9. Spring AOP 的原理及应用场景?

答案 :AOP(面向切面编程):将日志、事务、权限等通用逻辑(切面)与业务逻辑分离,核心原理是动态代理

  1. JDK 动态代理:目标类实现接口时使用,生成实现相同接口的代理类,通过反射调用目标方法;
  2. CGLIB 动态代理:目标类无实现接口时使用,继承目标类生成子类,重写目标方法(需注意:目标方法不能是 final)。

核心概念

  • 切面(Aspect):通用逻辑(比如事务切面);
  • 切点(Pointcut):匹配要增强的方法(比如execution(* com.service.*.*(..)));
  • 通知(Advice):增强的时机(前置 @Before、后置 @After、返回 @AfterReturning、异常 @AfterThrowing、环绕 @Around)。

应用场景:事务管理、日志记录、权限校验、性能监控。

10. Spring 事务失效的常见场景?

答案

  1. 方法不是 public:Spring 事务基于 AOP,JDK 动态代理只拦截 public 方法;
  2. 异常被捕获且未抛出 :比如try{...} catch(Exception e) {},事务无法感知异常,不会回滚;
  3. 抛出非运行时异常 :默认事务只回滚RuntimeExceptionError,需手动指定@Transactional(rollbackFor = Exception.class)
  4. 多线程调用:事务线程和子线程不在同一个事务上下文,子线程异常不影响主线程;
  5. 自身调用:比如 A 类的 a () 方法调用本类的 b () 方法(b () 加了 @Transactional),因未走代理,事务失效;
  6. Bean 未被 Spring 管理:比如类未加 @Service/@Component,事务注解无效。
11. Spring Boot 自动配置原理?

答案 :核心是@EnableAutoConfiguration注解,流程:

  1. 加载自动配置类 :Spring Boot 启动时,通过SpringFactoriesLoader读取META-INF/spring.factories文件,加载所有AutoConfiguration类;
  2. 条件过滤 :自动配置类上的@ConditionalOnClass(存在指定类)、@ConditionalOnMissingBean(不存在指定 Bean)等注解,过滤掉不满足条件的配置;
  3. 注册 Bean :满足条件的自动配置类,通过@Bean向容器注册组件(比如 DataSourceAutoConfiguration 自动配置数据源);
  4. 配置优先级 :用户自定义配置 > 配置文件 > 自动配置(可通过@ConditionalOnMissingBean保证用户配置优先)。

三、中间件(核心)

12. MySQL 索引失效的常见场景?

答案

  1. 模糊查询以 % 开头like %xxx(无法走索引,like xxx%可以);
  2. 索引列参与计算 / 函数where id + 1 = 10where SUBSTR(name,1,1) = 'a'
  3. 索引列使用隐式类型转换 :比如索引列是 varchar,查询用where id = 123(字符串转数字);
  4. or 连接非索引列where index_col = 1 or non_index_col = 2
  5. 联合索引不满足最左匹配 :联合索引 (a,b,c),查询where b=1 and c=2(跳过 a,索引失效);
  6. 数据分布导致优化器放弃索引:比如索引列值重复率高(比如性别),优化器会走全表扫描。
13. MySQL 事务的隔离级别及 MVCC 原理?

答案隔离级别(从低到高):

  1. 读未提交(Read Uncommitted):能读到其他事务未提交的数据(脏读);
  2. 读已提交(Read Committed):只能读到其他事务已提交的数据(解决脏读,存在不可重复读);
  3. 可重复读(Repeatable Read):MySQL 默认级别,同一事务内多次读取结果一致(解决不可重复读,存在幻读);
  4. 串行化(Serializable):最高级别,完全避免脏读 / 不可重复读 / 幻读,但性能最差。

MVCC(多版本并发控制):实现可重复读的核心机制,通过 "版本链 + undo log+ReadView" 实现:

  1. 版本链 :每行数据包含trx_id(创建事务 ID)、roll_pointer(指向 undo log 的指针),修改数据时生成新版本,通过 roll_pointer 串联旧版本;
  2. undo log:存储数据的旧版本,用于回滚或读取历史版本;
  3. ReadView :事务读取数据时的 "快照",包含当前活跃事务 ID 列表,判断数据版本是否可见:
    • 若数据trx_id < ReadView最小活跃ID:可见;
    • 若数据trx_id > ReadView最大活跃ID:不可见;
    • 若在活跃 ID 范围内:不可见(未提交)。
14. Redis 缓存穿透、缓存击穿、缓存雪崩的区别及解决方案?
问题 定义 解决方案
缓存穿透 请求不存在的 key,穿透到 DB,DB 压力大 1. 空值缓存(缓存不存在的 key,设置短期过期);2. 布隆过滤器(提前过滤不存在的 key)
缓存击穿 热点 key 过期,大量请求同时打到 DB 1. 热点 key 永不过期;2. 互斥锁(比如 Redis 的 SETNX),只有一个线程去 DB 加载数据
缓存雪崩 大量 key 同时过期,或 Redis 集群宕机,DB 压垮 1. 过期时间加随机值(避免同时过期);2. Redis 集群部署(主从 + 哨兵);3. 降级 / 限流
15. Kafka 保证消息可靠性的机制?

答案

  1. 生产者端
    • acks=all:消息需被所有 ISR(同步副本)确认后才返回成功;
    • 重试机制:retries设置重试次数,retry.backoff.ms设置重试间隔;
    • 幂等性 / 事务:开启幂等性(enable.idempotence=true)避免重复发送,事务保证批量消息的原子性。
  2. Broker 端
    • 副本机制:每个分区配置多个副本(replication.factor),ISR 列表中的副本同步数据,Leader 宕机后 Follower 升级为 Leader;
    • 最小 ISR 数:min.insync.replicas设置最小同步副本数,低于该值则拒绝写入。
  3. 消费者端
    • 手动提交 offset(enable.auto.commit=false):消费完成后再提交,避免消费失败但 offset 已提交;
    • 死信队列:处理消费失败的消息,避免重复消费。

四、场景题(中高级)

16. 秒杀系统设计核心要点?

答案 :核心目标:限流、削峰、防超卖、高可用,核心步骤:

  1. 前端限流:按钮置灰、验证码、接口限流(比如每秒 1 次);
  2. 网关层:Nginx 限流(limit_req_zone)、黑白名单;
  3. 应用层
    • 接口限流(Sentinel/Guava RateLimiter);
    • 库存预扣减(Redis 原子操作decr,避免超卖);
    • 消息队列削峰(Kafka/RabbitMQ,异步处理订单);
  4. 数据层
    • 分库分表(按商品 ID 分片);
    • 库存最终一致性(Redis 预扣减 + DB 最终校验,定时任务补偿);
  5. 兜底方案:服务降级(比如秒杀失败返回 "稍后重试")、熔断(避免服务雪崩)。
17. 如何保证缓存和数据库的数据一致性?

答案 :核心原则:最终一致性(强一致性成本高),常用方案:

  1. 更新策略(推荐) :先更 DB,再删缓存(而非更缓存):
    • 原因:避免并发下 "更新缓存" 覆盖最新数据(比如 A 更 DB→B 更 DB→B 更缓存→A 更缓存,导致缓存是旧值);
    • 补偿:定时任务扫描 DB 和缓存,修复不一致数据。
  2. 延迟双删:更 DB→删缓存→延迟 1 秒→再删缓存(解决删缓存前缓存已过期,新请求加载旧值的问题);
  3. 分布式事务:比如 Seata 的 TCC 模式(成本高,仅核心场景使用)。

总结

  1. 基础核心:Java 基础(JVM、多线程、集合)是所有面试的 "底线",必须吃透原理 + 场景;
  2. 框架重点:Spring IOC/AOP、事务失效场景,MyBatis 核心原理是高频考点;
  3. 中间件核心:MySQL 索引 / MVCC、Redis 缓存问题、Kafka 可靠性机制,需结合业务场景理解;
  4. 场景题:秒杀、缓存一致性等问题,重点答 "限流、削峰、最终一致性、兜底方案" 等核心思路。
相关推荐
badhope2 小时前
OpenClaw卸载命令全解析
java·linux·人工智能·python·sql·数据挖掘·策略模式
Hello.Reader2 小时前
Flink Task Lifecycle 一篇讲透 StreamTask 与 Operator 生命周期
java·大数据·flink
小小小米粒2 小时前
Redisson 大量用了 Lua
java
free-elcmacom2 小时前
C++ 函数占位参数与重载详解:从基础到避坑
java·前端·算法
Greenland_122 小时前
Android Java使用Glide无法生成GlideApp
android·java·glide
2301_803554522 小时前
单例模式以及面试可能问的--精写
单例模式·面试·职场和发展
我叫黑大帅2 小时前
如何使用WebSocket实现一个公域聊天室? --Go
后端·面试·go
祁梦2 小时前
Redis从入门到入土 --- 黑马点评点赞功能实现详解
java·后端