进行中ENGINEERING NOTE
字节跳动面试速查表
围绕 Redis、SkipList、MySQL、缓存与常见后端问题整理的面试速查笔记,目前仍在持续补充。
Redis
Redis有哪些数据结构
String、Hash、Set、ZSet、List 新增的数据结构:BitMap、HyperLogLog、GEO、Stream
Zset使用了什么数据结构
压缩链表或者跳表,但是压缩链表已经被弃用
什么是SkipList
SkipList维护了多个层级的头指针。如果要查找一个元素,可以先跳到最近的一个元素,然后再开始遍历。这样将时间复杂度从N变成了logN 它的空间复杂度是N
为什么MySql不用SkipList
因为B+树在三层时数据量可能已经到千万级别,如果使用跳表会导致跳表层数过高,导致磁盘io次数增多。
Redis为什么性能好
- Redis的大部分操作都在内存当中,且采用了高效的数据结构。
- Redis采用单线程模型,避免了多线程间的竞争,减少了线程切换的开销。
- Redis采用了I/O多路复用机制。该机制允许内核存在多个监听Socket和已连接Socket。内核会不断监听,一旦有请求到达,就会交给Redis处理。
Redis和MySql如何保持一致性
先更新数据库,再删除缓存
MySQL
事务有哪些特性
- 原子性:事务要么全部完成,要么全部不完成
- 一致性:在事务操作前和操作后,数据满足完整性约束
- 隔离性:并发执行的事务不会互相干扰
- 持久性:事务一旦执行完毕,对数据的修改就是永久的
隔离性有哪些隔离级别
- 读未提交:事务未提交时就能看到更改
- 读提交:事务提交后能看到更改
- 可重复读:事务执行过程中看到的数据,和事务启动时看到的数据是一样的。这是MySQL InnoDB 引擎的默认隔离级别
- 串行化:对数据加上读写锁,必须按照顺序读写 可能会发生的问题
- 读未提交:脏读、幻读、不可重复读
- 读提交:不可重复读、幻读
- 可重复读:幻读
- 串行化:无 Mysql默认使用可重复读,可以很大程度减少幻读现象的发生。虽然使用串行化可以确保不发生,但是性能开销太大。
什么是间隙锁
间隙锁存在于可重复读隔离级别,用来解决数据库幻读的问题
- 如果表中存在一个(3, 5)的间隙锁,那么其他事务就无法插入id=4的记录了,事务会阻塞住,直到这条事务结束。
Mysql如何保证原子性
使用undo log日志,在开始执行事务之前记录undo log
Undo log具体怎么撤销的
当引擎对一条数据进行操作(修改、删除、新增)时,就会把要回滚的数据记录在undo log中。
- 修改一条数据:记录主键值和修改前的旧值
- 删除:记录主键值和旧值
- 新增:记录主键值
什么时候需要建立索引
- 字段名唯一
- 经常用where查询的字段
- 经常用group by和order by的字段,因为B+树中的记录都是有序的
什么时候不需要建立索引
- where、group by和order by不经常用到的字段
- 字段中包含大量重复数据,例如性别。innodb引擎有一个查询优化器,当它发现某个值在表中占比很高时,它会自动查询整个表,忽略索引
- 表数据太少
- 字段值经常发生改变
Java
线程有哪些状态
- NEW:线程创建
- RUNNABLE:就绪火正在运行
- BLOCKED:阻塞
- WAITING:等待另一线程执行操作
- TIMED_WAITING:具有指定等待时间的等待
- TERMINATED:终止
waiting中的线程如何变成running
- 等待的线程被其他线程唤醒