1.类加载机制
- 过程:加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载。
- 双亲委派模型:当一个类加载器收到类加载请求时,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。只有当父类加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
- 目的:保证核心类库的安全(防止自定义String类),避免重复加载。
2.JVM内存模型
- 物理结构:堆(Heap,存对象实例)、栈(Stack,存局部变量、方法调用链)、方法区(元空间,存类信息、常量)、程序计数器、本地方法栈。
3.介绍下垃圾回收(GC)
- 判断对象存活:引用计数法(已淘汰,无法解决循环引用)、可达性分析算法(GC Roots)。
- GC Roots包括 :虚拟机栈中引用的对象、静态属性引用的对象(字符串常量池、static final 等)、常量引用的对象、本地方法栈中JNI引用的对象(Native 方法(C/C++)通过 JNI 引用的 Java 对象)。
- 分代收集:新生代(Young Gen)、老年代(Old Gen)、元空间(Metaspace)。
4.垃圾回收算法
- 标记-清除:效率低,产生碎片。
- 标记-复制:将内存分为两块,每次只用一块,存活对象复制到另一块。无碎片,但浪费空间(新生代常用)。
- 标记-整理:存活对象向一端移动。无碎片,但移动成本高(老年代常用)。
- 分代收集算法:综合上述,新生代用复制,老年代用标记-整理/清除。
- 常见收集器:CMS(低停顿,有碎片)、G1(Region划分,可预测停顿)、ZGC/Shenandoah(超低停顿,并发整理,现代主流)。
5.StringBuffer 和 StringBuilder区别
- 线程安全 :
StringBuffer是线程安全的(方法加了synchronized),StringBuilder是非线程安全的。 - 性能 :
StringBuilder性能优于StringBuffer。 - 场景 :单线程字符串拼接用
StringBuilder;多线程共享变量拼接用StringBuffer(实际开发中多线程通常用ThreadLocal或锁控制,较少直接用StringBuffer)。
6.线程池原理
- 核心参数 :
corePoolSize(核心线程数),maximumPoolSize(最大线程数),keepAliveTime,workQueue(任务队列),threadFactory,handler(拒绝策略)。 - 工作流程 :
- 提交任务,若核心线程未满,创建核心线程执行。
- 若核心满,放入队列。
- 若队列满,创建非核心线程执行(直到达到最大线程数)。
- 若达到最大线程数且队列满,执行拒绝策略(抛异常、丢弃、调用者运行等)。
- 状态:RUNNING, SHUTDOWN, STOP, TIDYING, TERMINATED。
7.threadlocal是什么
- 定义:线程本地变量,为每个使用该变量的线程提供独立的变量副本,隔离线程间数据。
- 原理 :每个Thread内部维护一个
ThreadLocalMap,Key是ThreadLocal实例本身,Value是存储的值。
8.使用ThreadLocal注意事项
- 内存泄漏 :
ThreadLocalMap的Key是弱引用,Value是强引用。如果ThreadLocal对象被回收,但线程还在运行(如线程池),Value无法回收。 - 解决 :使用完必须手动调用
remove()方法。 - 线程池坑:线程复用导致脏数据,必须在任务结束清理。
9.线程池原理
spring框架
10.IOC原理
- 概念:控制反转,将对象创建和依赖关系的管理交给容器。
- 实现:依赖注入(DI)。
- 底层 :反射 + 工厂模式 + 配置文件/注解。Spring启动时扫描包,解析注解,实例化Bean,放入
BeanFactory/ApplicationContext,处理依赖注入。
11.bean是什么
- 由Spring IoC容器实例化、组装和管理的对象。
- 作用域:Singleton (默认,单例), Prototype (多例), Request, Session, Application。
12.spring常见注解
- 声明Bean :
@Component,@Service,@Controller,@Repository,@Configuration,@Bean. - 依赖注入 :
@Autowired,@Resource,@Qualifier. - 配置 :
@Value,@PropertySource. - AOP :
@Aspect,@Before,@After,@Around. - 事务 :
@Transactional.
mysql
13.慢查询优化
- SQL层面 :避免
SELECT *,避免LIKE '%...',避免在索引列上做计算/函数,优化分页 (limit offset)。 - 索引层面:添加合适索引,检查是否命中索引(Explain),覆盖索引。
- 架构层面:读写分离,分库分表,引入缓存(Redis)。
14redis持久化,挂了重启,数据会丢失吗
RDB (Redis Database):定时快照,恢复快,文件小,但可能丢数据。
- AOF (Append Only File):记录每条写命令,数据安全,文件大,恢复慢。
- 混合持久化 (4.0+):RDB做镜像 + AOF做增量。
- 取决于持久化配置。
- 无持久化:全丢。
- RDB:丢失最后一次快照后的数据。
- AOF:丢失最后几次写入(取决于fsync策略)。
- 混合持久化:兼顾速度与完整性。
15项目中遇到的麻烦问题及解决 (示例模板)
- 建议回答策略 :采用 STAR法则 (Situation背景, Task任务, Action行动, Result结果)。
- 示例 :
- 问题:在大促期间,订单系统出现接口响应变慢,数据库CPU飙升。
- 排查:通过Slow Query Log发现某条关联查询未走索引,且存在深分页问题。
- 解决 :
- 优化SQL,利用覆盖索引避免回表。
- 将深分页改为"游标法"(基于上一页最大ID查询)。
- 引入本地缓存(Caffeine)热点数据。
- 结果:接口TP99从500ms降至50ms,数据库负载下降80%。