04 MySQL / Redis / MQ

这一块在面试里是干什么的

主要看你是不是只停留在 Controller 和 Service 层。

高频到不能跳过。

MySQL

什么是索引

索引是帮助数据库快速定位数据的数据结构。

一句话:

“索引像书的目录,不用每次从头翻到尾。”

为什么索引能加快查询

因为它减少了全表扫描。

索引的代价

  • 占空间
  • 写入变慢
  • 索引太多反而维护成本高

最左前缀原则

联合索引从最左边字段开始才更容易命中。

比如索引是 (a, b, c),优先命中从 a 开始的查询条件。

什么情况下索引可能失效

  • 对索引列做函数操作
  • 模糊查询以 % 开头
  • 类型隐式转换
  • 联合索引没走最左前缀

事务四大特性 ACID

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

隔离级别

短期先记 4 个名字:

  • 读未提交
  • 读已提交
  • 可重复读
  • 串行化

高频快答:

“MySQL InnoDB 默认隔离级别是可重复读。”

什么是脏读、不可重复读、幻读

  • 脏读:读到别人未提交的数据
  • 不可重复读:同一行前后读到的值不一样
  • 幻读:前后两次查询,记录条数不一样

慢 SQL 怎么排查

先答步骤:

  1. 看执行计划
  2. 看是否走索引
  3. 看 SQL 写法是否合理
  4. 看数据量和回表情况

Redis

Redis 为什么快

主要因为:

  • 基于内存
  • 单线程模型避免线程切换开销
  • IO 多路复用

Redis 常见数据类型

  • String
  • Hash
  • List
  • Set
  • ZSet

零基础先知道使用场景就够了。

缓存为什么用 Redis

  • 读快
  • 适合热点数据
  • 可以减轻数据库压力

缓存穿透

查不存在的数据,请求每次都打到数据库。

解决:

  • 缓存空值
  • 参数校验
  • 布隆过滤器

缓存击穿

一个热点 key 失效,大量请求同时打到数据库。

解决:

  • 热点不过期
  • 加互斥锁
  • 提前刷新

缓存雪崩

大量 key 同时过期,数据库瞬间被压垮。

解决:

  • 过期时间加随机值
  • 多级缓存
  • 限流降级

双写一致性怎么答

先答思路,不必追求完美:

“常见做法是更新数据库后删除缓存,而不是先更新缓存。因为缓存是辅助层,可以允许短时间不一致。”

分布式锁

Redis 可以做分布式锁,但要注意:

  • 过期时间
  • 锁误删
  • 续期问题

MQ

为什么要用消息队列

  • 解耦
  • 异步
  • 削峰

一句话:

“MQ 把同步强依赖改成异步松耦合。”

常见问题

  • 消息重复
  • 消息丢失
  • 消息顺序
  • 消费积压

如何保证消息不重复消费

通常不是“绝对不重复”,而是“幂等处理”。

常见方式:

  • 唯一业务 ID
  • 数据库去重
  • 状态机控制

如何保证消息可靠

回答框架:

  • 生产者发送确认
  • Broker 持久化
  • 消费者手动确认

如何保证顺序

顺序消息通常会牺牲一部分吞吐,常见做法是同一业务 key 路由到同一队列。

高频快答

Redis 和 MySQL 怎么分工

MySQL 负责持久化和事务一致性,Redis 负责高并发热点读。

Redis 单线程为什么还能快

因为它避免了线程切换和锁竞争,主要瓶颈在内存和网络,不在 CPU 计算。

MQ 的本质价值

异步、削峰、解耦。

这一章最小记忆包

  • MySQL 重点记索引、事务、隔离级别、慢 SQL
  • Redis 重点记为什么快、数据类型、穿透击穿雪崩
  • MQ 重点记为什么用、可靠性、幂等、顺序