@TOC
前言
本系列为面试专题,主要记录一些易混淆、易忘记的知识点;
目前共有四个部分:Java基础、计算机基础、数据库与框架;
3. 数据库
3.1 MySQL
1. MyISAM 与 InnoDB:
比较项 | MyISAM | InnoDB |
---|---|---|
版本 | 5.5之前 | 5.5之后 |
锁级别 | 表级锁(共享锁、排他锁) | 表级锁、行级锁(共享锁、排他锁) |
事务 | 不支持 | 支持(通过 redo log) |
崩溃后安全恢复 | 有崩溃修复能力 | |
外键 | 不支持 | 支持 |
MVCC | 不支持 | 支持 |
索引 | 非聚簇索引。索引与数据分离(不支持hash索引) | 聚簇索引。数据文件本身就是索引 |
存储结构 | 三个文件(表格定义、数据文件、索引文件) | 数据文件 |
数据检索 | 叶节点的data域存放的是数据记录的地址。需要根据地址读取数据 | 叶节点data域保存了完整的数据记录 |
存储顺序 | 按记录插入顺序保存 | 按主键大小有序插入 |
默认隔离级别 | 可重复读(使用 Next-Key Lock 锁算法可避免幻读) | |
应用范围 | SELECT密集型 | INSERT和UPDATE密集型 |
2. InnoDB 引擎4大特性:插入缓冲
(要插入的索引页不在内存中时放进 change buffer)、二次写
(两次操作 redo log 表)、自适应哈希索引
(自动根据访问频率和模式建立 hash 索引)、预读
(异步将磁盘页读取到缓存池中);
3. MVCC:
MVCC | |
---|---|
是什么 | 多版本并发控制 |
目的 | 为了实现读-写冲突时不加锁的并发控制,是一个抽象概念 |
实现方式 | 快照读 (当前读-读取时加悲观锁) |
实现原理 | 依赖3个隐式字段 (最近修改事务ID,回滚指针,隐式自增ID)+undo日志 (链表,记录历史数据)+read view (做可见性判断,记录某个事务快照读时其他事务活跃状态) |
具体过程 | 事务A对某行数据执行快照读,数据库对该行数据生成read view读视图,其中有 up_limit_id (活跃事务ID列表里最小值)、活跃事务 ID 列表 、low_limit_id (当前尚未分配的下一个事务ID),判断最近修改事务ID是否在read view读视图范围内,不在时说明符合可见性,可以并发修改 |
应用 | MVCC (解决读写冲突)+乐/悲观锁 (解决写写冲突)提高并发性能 |
4. 共享锁、排它锁: |
对比项 | 共享锁 | 排它锁 |
---|---|---|---|
说明 | 用户要进行数据的读 取时,对数据加上共享锁 |
用户要进行数据的写 入时,对数据加上排他锁 |
5. 乐观锁、悲观锁:
比较项 | 乐观锁 | 悲观锁 |
---|---|---|
说明 | 假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性(修改数据时上锁) | 假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作(查询完数据就锁起来) |
适用 | 多读 场景 |
多写 场景 |
6. 事务的四大特性(ACID):原子性、一致性(事务前后数据一致)、隔离性(事务不被其他事务干扰)、持久性(事务对数据库修改是持久的);
7. 并发事务问题:脏读(读取到未提交的事务)、丢失修改(修改了未提交的事务)、不可重复读(读取到已修改的数据)、幻读(读取到已增删的数据);
8. 隔离级别:读未提交、读已提交、可重复读、可串行化;
9. join:对数据库中的两张或两张以上表进行连接操作。分为内连接、外连接(左外连接、右外连接、全外连接)
10. 大表优化:限定查询数据范围、加缓存redis、读/写分离、垂直拆分(缺点是出现冗余)、水平拆分(缺点是可能造成分布式事务)、引擎(MyISAM适合SELECT密集型的,InnoDB适合INSERT和UPDATE密集型的表);
11. 分库分表后的问题:事务支持(分布式事务)、跨库join、跨节点的count,order by,group by以及聚合函数问题、数据迁移,容量规划,扩容等问题、ID问题(雪花算法);
12. 慢查询原因及解决方法:
序号 | 原因 | 解决 |
---|---|---|
1 | 加载了额外的数据列 | 使用limit |
2 | 索引没有命中 | 重写SQL,避免在 where 子句使用 !=、<>、or操作符 |
3 | 数据量太大 | 大表优化 |
4 | 总是返回全部列 | 避免使用SELECT * |
5 | 重复查询相同的数据 | 加缓存redis |
6 | 存在锁竞争 | 执行单个查询 |
7 | 统计所有列数使用count(*)-忽略所有的列 |
13. 索引使用场景:where、order by(没有时:分批从硬盘读取数据后排序合并,有时:索引本身有序)、join(对 on 涉及的字段建立索引);
14. 索引类型:主键索引、唯一索引、普通索引、全文索引;
15. 创建索引的原则:最左前缀匹配原则(MySQL匹配到范围查询就停止匹配)、频繁查的字段建立索引、更新频繁的字段不建立索引、区分度低的数据不建立索引、有外键的数据列必须建立索引、重复值多的列不建立索引、text/image/bit类型的列不建立索引;
16. 添加索引优化查询:PRIMARY KEY(主键索引)、UNIQUE(唯一索引) 、INDEX(普通索引)、FULLTEXT(全文索引) 、多列索引 ;
17. 查询 SQL 如何执行:连接器(权限校验)、(查询缓存)、分析器(词法、语法分析)、优化器、执行器、引擎;
18. 更新 SQL 如何执行:连接器(权限校验)、(查询缓存)、分析器(词法、语法分析)、执行器、引擎、redo log prepare
(重做日志)、binlog
(归档日志)、redo log commit
;
19. binlog录入格式:statement(记录每条会修改数据的sql,节省IO提高性能)、row(记录每行改动,性能较差)、mixed(折中方案)
20. SQL 偶尔执行慢:数据库在刷新脏页(redolog写满导致数据库全身心执行数据同步,内存不够换页频繁)、拿不到锁(show processlist命令查看);
21. SQL 总是执行慢:字段没有索引、数据库选错索引;
22. InnoDB存储引擎锁算法:
比较项 | Record lock | Gap lock | Next-key lock |
---|---|---|---|
锁算法 | 单个行记录上的锁 | 间隙锁,锁定一个范围,不包括记录本身 | record+gap 锁定一个范围,包含记录本身 |
应用 | 查询的索引含有唯一属性时 | 为了阻止多个事务将记录插入到同一范围内 | 行的查询,解决幻读 |
23. 数据库三大范式:列不可再分、属性完全依赖主键、属性不依赖其他非主属性;
24. MySQL 的权限表:user
权限表(用户账号)、db
权限表(账号对应操作权限)、table_priv
(表的操作权限)、columns_priv
(列的权限)、host
(更细致的一种);
25. B 树、B+ 树和 hash 索引:
比较项 | B 树 | B+ 树 | hash 索引 |
---|---|---|---|
内部节点 | 键和值 | 键 | \ |
叶子节点 | 键和值 | 键和值,有链连接 | \ |
好处 | 将重复查询是数据靠近根节点,提高效率 | 内部节点内存小,一次读取可以获取更多键,缩小查找范围。通过叶子节点的链遍历数据提高效率。IO次数少 | 等值查询更快(但是不稳定、性能不可预测-hash碰撞) |
缺点 | 不稳定 | 不支持:范围查询(无序)、模糊查询、最左前缀匹配 | |
适用 | 随机检索 | 随机检索、顺序检索 |
26. MySQL 为什么不用红黑树:红黑树特点:保证深度一致、数据量大时深度大。B+树特点:节点存数据、每层节点多、节点小,层数少。MySQL通过减少磁盘IO提高效率,B+树每层节点多,层数少,节点小,能在较少IO下加载更多key进内存。AVL和红黑树更多是存储在内存,红黑树可能导致树的深度过大造成磁盘IO读写过于频繁;
27. 键:超键(唯一标识元组的属性集)、候选键(最小超键)、主键(唯一数据行)、外键(一个表存在另一个表的主键);
28. SQL 约束:not null(非空)、unique(独一)、primary key(主键)、foreign key(外键)、check(控制值范围);
29. int(10)、char(10)、varchar(10):
比较项 | int(10) | char(10) | varchar(10) |
---|---|---|---|
含义 | 10位数字长度 | 10位固定字符串 | 10位可变字符串 |
实际长度 | 占32个字节,int型4位 | 不足补空格(空格不算字符) | 不足补空格(空格算字符) |
30. drop、delete、truncate
比较项 | Delet | Truncate | Drop |
---|---|---|---|
类型 | DML | DDL | DDL |
回滚 | 可 | 不可 | 不可 |
删除内容 | 表结构在,删除全部或者一部分数据行 | 表结构在,删除所有数据 | 表结构不在 |
删除速度 | 速度慢,逐行删除 | 速度快 | 速度最快 |
3.2 Redis
1. 分布式缓存区别:Memcached 和 Redis:
比较项 | Memcached | Redis |
---|---|---|
数据类型 | 只有 key/value | 多种 |
持久化 | 内存 | RDB AOF |
容灾恢复 | 无 | 基于持久化 |
内存溢出 | 报错 | 持久化到硬盘 |
集群 | 无原生集群 | 支持 cluster 模式 |
线程模型 | 多线程非阻塞IO复用 | 单线程IO多路复用 |
高级功能 | 发布订阅模型、Lua 脚本、事务、支持更多的编程语言 | |
过期数据删除 | 惰性删除 | 惰性删除与定期删除 |
2. 数据结构:SDS、链表、字典、跳跃表、整数集合、压缩列表、对象;
3. 文件事件处理器:多个 socket、IO 多路复用程序、文件事件分派器、事件处理器;
4. 过期数据删除策略:惰性删除(CPU友好)、定期删除(内存友好);
5. 内存淘汰机制:最近最少未使用、即将过期、任意选择、最近最少使用、报错;
6. 持久化:RDB(默认,存数据)、AOF(实时性好,存操作);
7. Redis 事务:MULTI,EXEC,DISCARD 和 WATCH 等命令。不支持原子性,不支持回滚;
8. 缓存问题(数据库本身,数据,业务):缓存穿透(,缓存无效 key,布隆过滤器,参数校验)、缓存雪崩(集群+哨兵,数据过期时间,限流)、缓存击穿(数据库加锁,热数据不过期,热点限流)
9. 服务器的复制:设置主服务器的地址和端口、建立套接字连接、发送 PING 命令、身份验证、发送端口信息、同步、命令传播;
10. Sentinel 连接:Sentinel 默认每 10 秒向主服务器发送 INFO 命令。Sentinel 默认每 2 秒向被监视的主从服务器发送命令。Sentinel 默认每秒向所有实例发送 PING 命令;
11. Sentinel 主服务器下线:发送 PING 命令判断主观下线、询问其他 Sentinel 判断客观下线、协商选出领头 Sentinel(Raft 算法)、选新主服务器(状态良好、数据完整)、通过 SLAVEOF 复制新主服务器、将下线的主服务器设置为从服务器;
最后
::: hljs-center
新人制作,如有错误,欢迎指出,感激不尽!
:::
::: hljs-center
:::
::: hljs-center
如需转载,请标注出处!
:::
::: hljs-center
:::