面试题整理

1、JVM内存模型,GC机制和原理;
JVM 内存分线程私有 / 共享区,堆是 GC 核心;GC 通过可达性分析判断对象是否可回收,基于分代思想用复制 / 标记 - 清除 / 整理算法,新生代 GC 快、老年代 GC 慢。
2、GC分哪两种,Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?
Minor GC(新生代 GC) 和 Full GC(全局 GC)
Minor GC 回收新生代,频率高、耗时短,用复制算法;Full GC 回收全域,频率低、停顿久,触发于老年代 / 元空间满等场景,老年代用标记 - 整理(或清除)算法。
3、JVM里的有几种classloader,为什么会有多种?
JVM 有启动、扩展、应用程序 3 种系统类加载器 + 自定义类加载器;设计多种是为了职责分离、通过双亲委派保证类加载安全,同时支持自定义加载需求。
4、什么是双亲委派机制?介绍一些运作过程,双亲委派模型的好处;
双亲委派是 “先父后子” 的类加载规则,运作时逐层向上委托、向下回退加载,核心好处是保证核心类安全、避免类重复加载。
5、什么情况下我们需要破坏双亲委派模型;
需破坏双亲委派的场景:Web 容器类隔离、类热部署、SPI 接口实现加载、自定义类加载路径;核心原因是双亲委派的 “父优先” 规则无法满足灵活的类加载需求。
6、常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值?
JVM 调优核心是配堆内存(-Xms/-Xmx/-Xmn)、选 GC 算法(G1/CMS)、控 GC 触发阈值;
参考值:8 核 16G 服务器设-Xms8g -Xmx8g -Xmn4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200,再按监控微调。
7、JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的;
JVM 内存分私有 / 共享区,堆是 GC 核心;
类加载器按双亲委派加载类,GC 通过复制 / 标记算法实现,
收集器分 Serial/Parallel/CMS/G1/ZGC;
Class 文件按魔数 - 版本 - 常量池 - 类结构的顺序解析,最终加载为 JVM 中的类对象。

java基础
1、红黑树的实现原理和应用场景;
红黑树是带颜色标记的自平衡 BST,通过旋转 + 颜色翻转保证高度平衡,时间复杂度 O (logn),核心应用于 JDK 集合、内核调度、数据库索引等需有序 + 高效增删查的场景。
2、NIO是什么?适用于何种场景?
NIO 是非阻塞 I/O,通过 Selector 实现单线程管理多连接,适用于高并发、短连接的网络场景(如 Netty 服务器、IM),低并发场景不如 BIO 简单。
3、Java9比Java8改进了什么;
Java9 核心是模块化重构 JDK,优化语法(接口私有方法、不可变集合)、工具(jshell、HTTP/2 客户端)和 JVM(G1 默认),解决 Java8 臃肿、依赖混乱问题。
4、HashMap内部的数据结构是什么?底层是怎么实现的?
HashMap 底层是数组 + 链表 + 红黑树(JDK8),通过哈希计算定位下标,链表解决冲突,红黑树优化高冲突,扩容时数组翻倍,加载因子 0.75 平衡利用率和冲突率。
5、ConcurrentHashMap与HashMap、HashTable等区别
HashMap 单线程高效但非线程安全,Hashtable 全表锁低效,ConcurrentHashMap 用分段锁(JDK7)/CAS + 节点锁(JDK8)实现高效线程安全,是并发场景首选。
6、说说反射的用途及实现,反射是不是很慢,我们在项目中是否要避免使用反射;
反射用于框架 / 工具类实现动态化,性能比普通调用慢但可缓存优化;项目中不绝对避免,高频业务逻辑少用,框架 / 通用场景可放心用。
7、说说自定义注解的场景及实现;
自定义注解通过@interface定义,结合元注解指定作用范围,反射 / AOP 解析执行逻辑;用于日志、权限、缓存等业务标记,Spring 项目常用 AOP 解析。
8、List 和 Map 区别,Arraylist 与 LinkedList 区别,ArrayList 与 Vector 区别;
List 有序可重复(ArrayList 查快改慢,LinkedList 改快查慢),Map 是键值对;ArrayList 非线程安全(扩容 1.5 倍),Vector 线程安全但低效(扩容 2 倍)。

Spring相关
1、Spring AOP的实现原理和场景?
Spring AOP 基于 JDK/CGLIB 动态代理,运行时织入切面逻辑(日志 / 权限 / 事务等),实现横切逻辑与业务解耦,核心用于统一处理非业务场景。
2、Spring bean的作用域和生命周期;
Spring Bean 默认单例(全局 1 个),原型每次获取新实例;生命周期是实例化→注属性→初始化→使用→销毁,可通过 Aware / 初始化方法扩展逻辑。
3、Spring Boot比Spring做了哪些改进? Spring 5比Spring4做了哪些改进;
Spring Boot 对 Spring 的改进:自动配置、起步依赖、内置容器,约定大于配置,简化开发部署;
Spring 5 对 Spring 4 的改进:新增 WebFlux 响应式编程、适配 Java8/JUnit5、性能优化,拥抱现代生态。
4、如何自定义一个Spring Boot Starter?
自定义 Spring Boot Starter 需创建自动配置类,通过 spring.factories 声明,结合配置属性类和条件注解实现 “开箱即用”,核心是让组件可复用、可配置。
5、Spring IOC是什么?优点是什么?
Spring IOC 是控制反转,将对象创建和依赖管理交给容器,核心优点是解耦、简化开发、便于维护和扩展。
6、SpringMVC、动态代理、反射、AOP原理、事务隔离级别;
SpringMVC 是 Web 请求处理框架,动态代理 + 反射是 AOP 底层,AOP 解耦横切逻辑,事务隔离级别解决并发脏读 / 不可重复读 / 幻读问题。


数据库篇
1、锁机制介绍:行锁、表锁、排他锁、共享锁;
行锁粒度细、并发高,表锁粒度粗、性能低;排他锁禁读写,共享锁禁写允读,InnoDB 默认行级排他锁,依赖索引生效。
2、乐观锁的业务场景及实现方式;
乐观锁适合读多写少场景(库存、余额更新),核心实现:数据库用版本号法,代码用 CAS,无锁开销但冲突时需重试。
3、事务介绍,分布式事物的理解,常见的解决方案有哪些,什么事两阶段提交、三阶段提交;
事务是 ACID 特性的操作单元,分布式事务解决跨服务 / 跨库一致性;常见方案:2PC(强一致)、TCC/SAGA(高并发)、消息队列(异步);2PC 分准备 + 提交,3PC 新增预提交减少阻塞。
4、MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?
Binlog 三种模式:SBR 记 SQL(日志小、一致性差),RBR 记行变更(一致性强、日志大),MBR 自动切换(折中);生产优先 RBR(配 MINIMAL 优化日志),简单场景用 MBR/SBR。
5、MySQL锁,悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;
悲观锁(排他 / 共享锁)预设冲突先加锁,行锁粒度细并发高、表锁粗性能低;乐观锁无锁靠版本号检查,适合读多写少,InnoDB 行锁依赖索引是核心。
6、分布式事务的原理2阶段提交,同步异步阻塞非阻塞;
2PC 是分布式事务的同步阻塞方案,分准备(预留资源等指令)和提交(统一提交 / 回滚)两步,保证强一致但性能极低;高并发场景用异步非阻塞的最终一致性方案(TCC/SAGA)替代。
7、数据库事务隔离级别,MySQL默认的隔离级别、Spring如何实现事务、JDBC如何实现事务、嵌套事务实现、分布式事务实现;
MySQL 默认可重复读隔离级别,JDBC 靠 Connection 手动控事务,Spring 用 @Transactional+AOP 封装,嵌套事务依赖保存点,分布式事务强一致用 2PC、高并发用 TCC/SAGA(最终一致)。
8、SQL的整个解析、执行过程原理、SQL行转列;
SQL 执行先连接解析生成执行计划,再调用存储引擎执行;行转列核心用 CASE WHEN + 聚合函数 + GROUP BY,动态列需拼接 SQL。

Redis篇
1、Redis为什么这么快?redis采用多线程会有哪些问题?
Redis 快是因为纯内存 + 单线程无锁 + IO 多路复用;命令执行层用多线程会引发锁竞争、上下文切换、数据不一致,性能反降且设计复杂度暴增,因此仅 IO 层用多线程。
2、Redis支持哪几种数据结构;
Redis 支持 String(缓存 / 计数)、Hash(对象)、List(队列)、Set(去重)、ZSet(排行榜)5 大基础结构,及 Bitmap(签到)、HyperLogLog(UV)、Geo(定位)3 种扩展结构,均为内存高效优化设计。
3、Redis跳跃表的问题?
Redis 跳跃表(ZSet 底层)的核心问题是内存占用高、插入删除性能波动、无内置平衡机制;但 Redis 通过限制最大层数、优化随机算法规避风险,相比红黑树,跳跃表范围查询更简单、实现成本更低,是取舍后的最优选择。
4、Redis单进程单线程的Redis如何能够高并发?
Redis 单线程高并发的核心是:纯内存操作极快,IO 多路复用处理多连接,单线程规避上下文切换和锁竞争,命令处理轻量化,6.0+ 多线程仅辅助 IO 读写,不破坏核心优势。
5、Redis如何使用Redis实现分布式锁?
Redis 分布式锁核心用 SET NX PX 原子加锁(设过期时间 + 唯一标识),Lua 脚本原子解锁(校验标识);生产用 Redisson 处理续期和集群问题,避免死锁、误删、单点故障。
6、Redis分布式锁操作的原子性,Redis内部是如何实现的?
Redis 分布式锁的原子性,加锁靠单线程执行 SET NX PX 原生原子命令,解锁靠单线程执行 Lua 脚本(整体原子块),单线程模型从根本上保证操作不可分割。

线程池篇
1、线程池的原理,为什么要创建线程池?创建线程池的方式;
线程池靠核心线程复用、任务队列缓冲、最大线程管控实现高效并发,解决手动创建线程的开销和失控问题;创建方式优先用 ThreadPoolExecutor(手动配置)或 Spring 封装的 ThreadPoolTaskExecutor,避免 Executors 的无界队列风险。
2、线程的生命周期,什么时候会出现僵死进程;
Java 线程生命周期分新建、就绪 / 运行、阻塞、无限等待、计时等待、死亡 6 态;僵死进程是操作系统中子进程退出后父进程未调用 wait () 回收资源导致,Java 仅在调用系统命令创建子进程且未回收时出现。
3、说说线程安全问题,什么实现线程安全,如何实现线程安全;
程安全是保证多线程访问共享资源结果与单线程一致,实现优先避免共享(ThreadLocal),其次用原子类 / 不可变对象,最后用加锁(synchronized/Lock)/ 并发容器,核心保证原子性、可见性、有序性。
4、创建线程池有哪几个核心参数? 如何合理配置线程池的大小?
线程池核心参数是核心线程数、最大线程数、空闲超时、任务队列、拒绝策略;线程数配置:CPU 密集型≈CPU 核心数 + 1,IO 密集型≈CPU 核心数 ×(1 + 等待时间 / 执行时间),配合有界队列和合理拒绝策略,上线后监控调优。
5、volatile、ThreadLocal的使用场景和原理;
volatile 靠内存屏障保证共享变量的可见性 / 有序性(无原子性),用于状态标记 / DCL 单例;ThreadLocal 靠 ThreadLocalMap 让每个线程独享资源副本,用于工具类隔离 / 上下文传递,使用后必须 remove () 避免内存泄漏。
6、ThreadLocal什么时候会出现OOM的情况?为什么?
ThreadLocal 引发 OOM 的核心是:长期存活的线程(如线程池核心线程)持有 ThreadLocalMap 中 Value 的强引用(未调用 remove ()),大对象堆积无法被 GC 回收,最终耗尽堆内存;解决关键是使用后调用 remove ()。
7、synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性
synchronized 保证原子性 / 可见性 / 有序性(锁粒度优先代码块),volatile 仅保证可见性 / 有序性(无原子性);死锁是多线程交叉持锁导致永久阻塞,原子性保证操作不中断,可见性保证变量修改立即可见。

posted @ 2025-12-05 01:46  堭鍙銤  阅读(8)  评论(0)    收藏  举报