面试题汇总
MySQL
- 索引的种类
- 主键索引
- 唯一索引
- 普通索引
- 复合索引
- 单列索引
- 全文索引
- 聚簇索引和非聚簇索引的区别
- 聚簇索引的叶子节点存放的是
实际数据
- 非聚簇索引的叶子节点存放的是
主键值+索引值
,因此在使用非聚簇索引的时候,会出现**回表**
的情况。
- 聚簇索引的叶子节点存放的是
- 索引失效
- 最左匹配原则
like '%xxxx'
- 计算、函数、类型转换导致索引失效
!=
、<>
索引失效is null
可以使用索引,is not null
无法使用索引or
前后存在非索引的列,索引失效
- B+树的结构
- B树和B+树的区别
- B 树:M 阶的 B 树,每个节点最多
M-1
个数据,最多M
个子节点。(B 树的每个节点都包含数据(索引+记录)) - B+ 树:叶子节点才会存放数据(索引+记录),非叶子节点只会放索引。
- MySQL 为什么选择 B+树呢?
- 非叶子节点不存具体数据,只存索引,这样一个非叶子节点能存储更多的索引,使得树的高度降低,IO次数也就降低。
- 插入和删除的效率比 B 树高,B 树可能会导致整棵树发送复杂的形变。但是 B+树只用和删除叶子节点。
- 范围查询更有优势,B+ 树的叶子节点间有一个链表进行链接(InnoDB中使用的是一个双向链表)。
- B 树:M 阶的 B 树,每个节点最多
- MySQL 优化
- 具有唯一性的字段
- 频繁作为 where 、group by、order by 、distinct、join 字段需要创建索引
- 选取列的类型小的创建索引,例如 tinyint、mediumint、int、bigint
- 区分度高的列适合作为 索引
- 根据最左匹配原则,可以将最频繁使用的列放在最左侧。
- 字符串很长时,使用字符串前缀创建索引
- 限制索引的数量
- 最左匹配原则
- 覆盖索引
- 索引下推
- 在遍历索引的时候可以把不符合的数据过滤掉,就不用进行回表操作了。
- 回表
- 执行计划,是否使用到索引
type
,key
,key_len
InnoDB
和MyISAM
的区别- InnoDB 支持索引,MyISAM 不支持索引。
- 主从复制
- 集群
MQ
- 消息丢失
- 消息持久化
- 消息确认机制
- 消息重发机制(死信队列)
- 消息重复消费(确保消息幂等)
- RabbitMQ 的工作模式
- simple
- work
- publish/subscribe
- routing
- topic
- RabbitMQ Exchanger
- fanout
- direct
- topic
Redis
- 缓存雪崩、击穿、穿透的区别,解决方案
- RDB
- AOF
- 缓存一致性问题
- 分布式锁(CAS)
- keys 与 scan 命令
- Redis 的线程模型
- 内存淘汰机制
- LRU
- LFU
- 主从
- 哨兵
- 集群(分片)
JVM
- 调优案例
- 堆的内存结构
- 死锁如何解决?
- JVM 主要组成部分
- 类加载器
- 本地接口
- 执行引擎
- 运行时数据区
- 程序计数器
- 虚拟机栈
- 本地方法栈
- 堆
- 方法区
- 常量池的关系
- class 常量池
- 运行时常量池
- 全局字符串常量池
- 基本类型包装类常量池
- 9 种 OOM
- StackOverFlowError
- java heap space 堆内存不够
- metaspace 元空间不足
- GC overflow limit exceeded ,GC 耗费 98% 的时间,释放不到 2% 的内存
- 创建超过堆内存空间的对象
- 创建一个超大的数组
- 直接内存溢出(通过 NIO 的 native 方法直接分配堆外内存)
- kill process or sacrifice child
- out of swap space
- GC
- 如何判断是否为垃圾对象
- 引用计数法
- 可达性分析算法
- 指针碰撞
- 空闲列表
- 垃圾回收算法
- 标记-清除:先标记,再回收标记的对象。 会有很对碎片化的空间。
- 标记-复制:将内存分为两半,每次只使用其中的一半,当这一般内存用完后,将其中存活的对象复制到另一半。浪费空间
- 标记-整理:先标记-将存活的对象向前复制。会造成频繁的复制
- 分代收集
- 新生代:标记-复制算法
- 老年代:标记-清除、标记-整理
- 垃圾回收的时机
- 垃圾回收器
- CMS 回收过程
- G1 的回收过程
- 一次完整的 GC 过程
- Minor GC、Major GC、Full GC 的区别
- Minor GC:回收新生代对象
- Major GC:回收老年代对象
- Full GC:回收整个堆
- 空间分配担保原则
- 如何判断是否为垃圾对象
- 类加载过程
- 详细描述类的加载过程
- 加载
- 确认
- 准备
- 解析
- 初始化
- 类加载器类型
- 启动类加载器
- 扩展类加载器
- 应用类加载器
- 自定义类加载器
- 双亲委派模型
- 为什么需要双亲模型
- 如何打破双亲委派模型
- 详细描述类的加载过程
- 四种引用的作用
- 强引用
- 软引用
- 弱引用
- 虚引用
- Java 创建对象的过程
- 判断类是否加载
- 分配内存
- 线程安全
- 同步
- 使用本地线程分配缓冲
- 对对象进程必要的设置
- JVM 调优
- 垃圾收集器
- serial:串行收集器,单独的线程,会阻塞其他线程
- ParNew:
JDK
- 集合
- ThreadLocal 使用场景。
- Thread
- 锁的种类
- 线程池的参数
- 创建线程的几种方法
- HashMap 源码
- 底层数据结构
- 扩容机制
- hashcode 算法
- HashMap 与 HashTable 的区别
- Set、List 区别
- ArrayList、LinkedList 区别,增删改的复杂度
- 有序 map 有没有用到过? (TreeMap、LinkedHashMap)
设计模式
- 单例模式:配置
- 模板:导出 excel,定义一个抽象父类,定义 一个导出的方法,子类实现导出的逻辑
- 策略:数据上传到上游,有多个接口
- 责任链:数据上报审批的工作流
- 工厂模式:创建对象
- 代理模式:静态代理、动态代理
Spring
- 用到了哪些设计模式
- 自动配置原理(源码)
- Spring AOP
- Spring Ioc
- Spring 如何解决循环依赖
- Spring 的三级缓存
- Spring 实现异步的方式 @Async、线程池
- 依赖注入
- Spring 事务
- Spring 事务失效的情况
- 代理
- 静态代理
- 动态代理
- 基于接口的动态代理 JDK
- 基于子类的动态代理 cglib
ORM
- MyBatis 分页插件的原理
实战
- Excel 导出
- 优化
- 瓶颈
- 压力测试
- SM2、SM3、SM4加密的流程
Vue
- 数据传递有哪些?
- 生命周期函数
- 数据双向绑定的原理
- diff 算法(同级比较,循环从两边向中间比较)
- axios 的使用
其他
- 分布式事务
- DNS 解析过程
- HTTP 请求流程
- 三次握手、四次挥手
- RESTful 风格
- Accept 的值
- 有没有使用到 Docker
- ES6