【Java开发】Java面试七大专题第9篇:数据库篇【附代码文档】

🏆🏆🏆教程全知识点简介:基础篇 1. 二分查找 2. 冒泡排序 7. ArrayList 8. Iterator 9. LinkedList 10. HashMap 1)基本数据结构 2)树化与退化 3)索引计算 4)put 与扩容 5)并发问题 11. 单例模式 并发篇 1. 线程状态 3. wait vs sleep 4. lock vs synchronized 虚拟机篇 1. JVM 内存结构 4. 内存溢出 5. 类加载 6. 四种引用 7. finalize 框架篇 1. Spring refresh 流程 2. Spring bean 生命周期 6. Spring 注解 7. SpringBoot 自动配置原理 数据库篇 1. 隔离级别 2. 快照读与当前读 3. InnoDB vs MyISAM 4. 索引 索引基础 5. 查询语句执行流程 6. undo log 与 redo log 7. 锁 缓存篇 1. Redis 数据类型 2. keys 命令问题 3. 过期 key 的删除策略 5. 缓存问题 6. 缓存原子性 7. LRU Cache 实现 分布式篇 1. CAP 定理 2. Paxos 算法 4. Gossip 协议 5. 分布式通用设计 6. 一致性 Hash(补充)

📚📚仓库code.zip 👉直接-->: https://gitee.com/xiaoshuai112/Backend/blob/master/Java/Java面试七大专题/note.md 🍅🍅
✨ 本教程项目亮点
🧠 知识体系完整:覆盖从基础原理、核心方法到高阶应用的全流程内容
💻 全技术链覆盖:完整前后端技术栈,涵盖开发必备技能
🚀 从零到实战:适合 0 基础入门到提升,循序渐进掌握核心能力
📚 丰富文档与代码示例:涵盖多种场景,可运行、可复用
🛠 工作与学习双参考:不仅适合系统化学习,更可作为日常开发中的查阅手册
🧩 模块化知识结构:按知识点分章节,便于快速定位和复习
📈 长期可用的技术积累:不止一次学习,而是能伴随工作与项目长期参考
🎯🎯🎯全教程总章节
🚀🚀🚀本篇主要内容
数据库篇
1. 隔离级别
要求
- 掌握四种隔离级别与相关的错误现象
未提交读
-
读到其它事务未提交的数据(最新的版本)
-
错误现象:有脏读、不可重复读、幻读现象
脏读现象
tx1 | tx2 |
---|---|
set session transaction isolation level read uncommitted; | |
start transaction; | |
select * from account; /两个账户都为 1000/ | |
start transaction; | |
update account set balance = 2000 where accountNo=1; | |
select * from account; /1号账户2000, 2号账户1000/ |
- tx2 未提交的情况下,tx1 仍然读取到了它的更改
提交读(RC)
-
读到其它事务已提交的数据(最新已提交的版本)
-
错误现象:有不可重复读、幻读现象
-
使用场景:希望看到最新的有效值
不可重复度现象
tx1 | tx2 |
---|---|
set session transaction isolation level read committed; | |
start transaction; | |
select * from account; /两个账户都为 1000/ | |
update account set balance = 2000 where accountNo=1; | |
select * from account; /1号账户2000, 2号账户1000/ |
- tx1 在同一事务内,两次读取的结果不一致,当然,此时 tx2 的事务已提交
可重复读(RR)
-
在事务范围内,多次读能够保证一致性(快照建立时最新已提交版本)
-
错误现象:有幻读现象,可以用加锁避免
-
使用场景:事务内要求更强的一致性,但看到的未必是最新的有效值
幻读现象
tx1 | tx2 |
---|---|
set session transaction isolation level repeatable read; | |
start transaction; | |
select * from account; /存在 1,2 两个账户/ | |
insert into account values(3, 1000); | |
select * from account; /发现还是只有 1,2 两个账户/ | |
insert into account values(3, 5000); / ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY' / |
- tx1 查询时并没有发现 3 号账户,执行插入时却发现主键冲突异常,就好像出现了幻觉一样
加锁避免幻读
| tx1 | tx2 | | -------
2. 快照读与当前读
要求
- 理解快照读与当前读
- 了解快照产生的时机
当前读
即读取最新提交的数据
- select … for update
- select ... lock in share mode
- insert、update、delete,都会按最新提交的数据进行操作
当前读本质上是基于锁的并发读操作
快照读
读取某一个快照建立时(可以理解为某一时间点)的数据,也称为一致性读。快照读主要体现在 select 时,而不同隔离级别下,select 的行为不同
-
在 Serializable 隔离级别下 - 普通 select 也变成当前读,即加共享读锁
-
在 RC 隔离级别下 - 每次 select 都会建立新的快照
-
在 RR 隔离级别下
- 事务启动后,首次 select 会建立快照
- 如果事务启动选择了 with consistent snapshot,事务启动时就建立快照
- 基于旧数据的修改操作,会重新建立快照
快照读本质上读取的是历史数据(原理是回滚段),属于无锁查询
[Spring MVC 文档]
RR 下,快照建立时机 - 第一次 select 时
tx1 | tx2 |
---|---|
set session transaction isolation level repeatable read; | |
start transaction; | |
select * from account; / 此时建立快照,两个账户为 1000 / | |
update account set balance = 2000 where accountNo=1; | |
select * from account; / 两个账户仍为 1000 / |
- 快照一旦建立,以后的查询都基于此快照,因此 tx1 中第二次 select 仍然得到 1 号账户余额为 1000
如果 tx2 的 update 先执行
tx1 | tx2 |
---|---|
set session transaction isolation level repeatable read; | |
start transaction; | |
update account set balance = 2000 where accountNo=1; | |
select * from account; / 此时建立快照,1号余额已经为2000 / |
RR 下,快照建立时机 - 事务启动时
如果希望事务启动时就建立快照,可以添加 with consistent snapshot 选项
tx1 | tx2 |
---|---|
set session transaction isolation level repeatable read; | |
start transaction with consistent snapshot; / 此时建立快照,两个账户为 1000 / |
[Velocity 文档]
| | update account set balance = 2000 where accountNo=1; | | select * from account; / 两个账户仍为 1000 / | |
RR 下,快照建立时机 - 修改数据时
tx1 | tx2 |
---|---|
3. InnoDB vs MyISAM
要求
[Unirest Java]
- 掌握 InnoDB 与 MyISAM 的主要区别
- 尤其注意它们在索引结构上的区别
InnoDB
- 索引分为聚簇索引与二级索引
- 聚簇索引:主键值作为索引数据,叶子节点还包含了所有字段数据,索引和数据是存储在一起的
-
二级索引:除主键外的其它字段建立的索引称为二级索引。被索引的字段值作为索引数据,叶子节点还包含了主键值
-
支持事务
- 通过 undo log 支持事务回滚、当前读(多版本查询)
- 通过 redo log 实现持久性
- 通过两阶段提交实现一致性
-
通过当前读、锁实现隔离性
-
支持行锁、间隙锁
-
支持外键
MyISAM
- 索引只有一种
- 被索引字段值作为索引数据,叶子节点还包含了该记录数据页地址,数据和索引是分开存储的
-
不支持事务,没有 undo log 和 redo log
-
仅支持表锁
-
不支持外键
[Undertow 文档]
- 会保存表的总行数
[Hazelcast 文档]
InnoDB 索引特点
聚簇索引:主键值作为索引数据,叶子节点还包含了所有字段数据,索引和数据是存储在一起的
[Maven 官方文档]
- 主键即 7369、7499、7521 等
二级索引:除主键外的其它字段建立的索引称为二级索引。被索引的字段值作为索引数据,叶子节点还包含了主键值
[Dropwizard Metrics]
