自己觉得比较好的面试问题
SQL
insert语句执行过程(MySQL)
MySQL架构分为server层和存储引擎层,server层包括连接器、查询缓存、分析器、优化器、执行器。存储引擎层是对应的选择的存储引擎,包括InnoDB、MyISAM、Memory三种。
- 连接器
- 负责建立连接、权限校验、维持和管理连接
- 建立连接之后修改权限,不会影响当前连接
- 查询缓存 (MySQL 8.0中已经删除)
- key「SQL」,value「查询结果」,不启用,「SQL」差一个空格也会认为是俩个
- 分析器(提示语法错误)
- 词法分析
- 语法分析
- 优化器
- 选择索引
- 选择表连接顺序
- 执行器
- 执行SQL
MySQL存储引擎区别
存储引擎区别:
- InnoDB
- 默认存储引擎,推荐使用
- 支持事务、外键、行锁
- insert速度慢
- MyISAM
- MySQL自带的
- 插入速度快
- Memory
- 所以数据放在内存中
- 速度快,但安全性低
- 对表大小有要求
三大日志
慢SQL
写SQL
- 脏页(内存数据页和磁盘数据页不一致时,那么称这个内存数据页为脏页)
- redo log写满后,会阻塞后续写入操作
- 锁
读SQL
- 没有走索引
- 脏页
- 缓存池上限是淘汰脏页,此时需要先将脏页写入DB
- explain
- ALL、index、range、 ref、eq_ref、const、system、NULL 从左到右,性能逐渐变好
SQL优化
like
中通配符放左边- 尽量不要使用
*
,而是具体的字段 - 不要在
where
中使用null
- 用
between
、exists
替代in
- 用
varchar
/nvarchar
替代char
/nchar
,节省存储空间 limit
优化- 先查出上页结束记录
- id连续,请使用
between
- id连续,请使用
- MySQL 5.5之后
in
已经变快了
Redis
雪崩、穿透、击穿
雪崩:大量key同时过期
穿透:绕过redis直接请求DB(请求不存在的数据)
击穿:热点数据过期的瞬间,大量请求涌入
解决方法:
- 雪崩:
- 在基础过期时间的基础上添加一个随机的过期时间
- 穿透:
- 返回结果为空的数据一样缓存,并设置一个较短的时间
- 布隆过滤器
- 击穿:
- 互斥锁
- 限流
- 永不过期
- 不设ttl
- 保存过期时间,取值时判断,如果过期,异步构建缓存
如何保证缓存和数据库的一致性
- Cache Aside Pattern
- 读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
- 更新的时候,先更新数据库,然后再删除缓存
- 选择删除而不是更新的一个原因是「一个更新很频繁的缓存不一定是一个经常访问的缓存」