和腾讯大牛的技术面谈,手撕面试官
作者:互联网
### 正文
谈到 MYSQL 的事物, 相信大家对这几个概念都不会陌生:
* **四大特性**:ACID
* **并发问题**
* 脏读
* 不可重复读
* 幻读
* **隔离级别**
* Read Uncommitted(读未提交)
* Read Committed(读提交)
* Repeatable Read(可重读)
* Serializable(可串行化)
下面的思维导图可能更表达得清晰??
![](http://www.icode9.com/i/li/?n=2&i=images/20210630/1625059693907728.jpg)
MySQL 的默认事物隔离级别是 `RR (Repeatable Read)` ,可重复读级别是能够解决脏读、不可重复读的这两个事物并发问题的,但是幻读的问题仍会存在,如果使用`Serializable`的隔离级别,对于高并发的业务来说是不实际的。那么 MySQL 是如何解决幻读这个棘手的问题呢?
没错,MySQL 通过`MVCC`(多版本并发控制)和`Gap Lock`(间隙锁)这两个机制解决了幻读的问题~
那么这两种方式具体又是如何实现的呢?
这里我们先讲一下 MySQL 的**"读"的区别**。因为在事物隔离级别中的**"读"**,分为`快照读(snapshot read)`和`当前读(current read)`
##### 1\. 当前读(current read)
> select...lock in share mode (共享读锁) select...for update update , delete , insert
读取的是最新的数据,并且对读取的记录加锁,**阻塞其他事物对当前事物查询数据的修改和插入**,从而解决幻读。
实现方式:`Next-key Locks(临键锁)`
官方对临键锁的定义是:
> A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.
简单来说就是 临键锁 = 行记录锁 + 间隙锁
行锁、间隙锁这个锁的概念,下文会介绍。所以这里我们只要知道的是,对于事物的当前读模式,是通过 Gap-Key-Locks 解决的。
##### 2\. 快照读(snapshot read)
> select * from table
单纯的 select 操作
Read Committed 隔离级别:每次select都生成一个快照读。
Read Repeatable 隔离级别:**开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读。**
实现方式:undolog 和 MVCC
undolog 用于数据的撤回操作,它记录了修改的反向操作,比如,插入对应删除,修改对应修改为原来的数据,通过undo log 可以实现事务回滚,并且可以根据 undo log 回溯到某个特定的版本的数据。
MVCC 就是上文提到的多版本并发控制。
### 实现方式
#### MVCC
MVCC 只是工作在两种事务级别底下:
* Read Committed
* Repeatable Read
MVCC 每行记录后面保存三个隐藏的列,其中其主要作用的有两列
**DB_TRX_ID**: 记录行数据创建时的事物版本号。每开启一个事物,事物版本号都会递增。
**DB_ROLL_PTR**: 记录行数据何时过期(或者被删除)。指向前一个版本的 undolog 记录,组成 undo 链表。如果更新了行,则撤消日志记录包含在更新行之前重建行内容所需的信息。
* INSERT
插入数据时, DB_TRX_ID 记录的是当前新增数据的事物版本号
* DELETE
删除数据时,DB_ROLL_PTR 记录的是当前操作删除的事物版本号
* UPDATE
1. 更新数据时,插入一条新的数据,DB_TRX_ID 记录的是当前更新数据的事物版本号
2. 将旧数据的 DB_ROLL_PTR 值更新为当前更新数据的事物版本号
* SELECT
查询规则如下:
1. 查找**数据行版本号早于当前事务版本号**的数据行记录,也就是说(当前的查询的事物版本号 >= `DB_TRX_ID` 中的值)
这样就能确保事物读取的数据,要么是当前事物已经存在的,要么是当前事物所操作过的。
2. 查找**删除版本号**要么为NULL,要么**大于当前事务版本号**的记录。也就是说 (`DB_ROLL_PTR` IS NULL OR `DB_ROLL_PTR` > 当前的查询的事物版本号)
这样确保查询出来的数据行记录在事务开启之前没有被删除。
### 最后
**给读者们一个小福利,有需要这些资料的朋友们[可以点击我,即可免费](https://docs.qq.com/doc/DSmxTbFJ1cmN1R2dB)领取资料!**
### ActiveMQ消息中间件面试专题
* 什么是ActiveMQ?
* ActiveMQ服务器宕机怎么办?
* 丢消息怎么办?
* 持久化消息非常慢怎么办?
* 消息的不均匀消费怎么办?
* 死信队列怎么办?
* ActiveMQ中的消息重发时间间隔和重发次数吗?
**ActiveMQ消息中间件面试专题解析拓展:**
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](http://www.icode9.com/i/li/?n=2&i=images/20210630/1625059696707359.jpg)
* * *
# redis面试专题及答案
* 支持一致性哈希的客户端有哪些?
* Redis与其他key-value存储有什么不同?
* Redis的内存占用情况怎么样?
* 都有哪些办法可以降低Redis的内存使用情况呢?
* 查看Redis使用情况及状态信息用什么命令?
* Redis的内存用完了会发生什么?
* Redis是单线程的,如何提高多核CPU的利用率?
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](http://www.icode9.com/i/li/?n=2&i=images/20210630/1625059698499078.jpg)
* * *
# **Spring面试专题及答案**
* 谈谈你对 Spring 的理解
* Spring 有哪些优点?
* Spring 中的设计模式
* 怎样开启注解装配以及常用注解
* 简单介绍下 Spring bean 的生命周期
**Spring面试答案解析拓展**
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](http://www.icode9.com/i/li/?n=2&i=images/20210630/1625059699547187.jpg)
* * *
# 高并发多线程面试专题
* 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
* Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
* Java 中 wait 和 sleep 方法有什么区别?
* 如何在 Java 中实现一个阻塞队列?
* 如何在 Java 中编写代码解决生产者消费者问题?
* 写一段死锁代码。你在 Java 中如何解决死锁?
**高并发多线程面试解析与拓展**
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](http://www.icode9.com/i/li/?n=2&i=images/20210630/1625059700273217.jpg)
* * *
# jvm面试专题与解析
* JVM 由哪些部分组成?
* JVM 内存划分?
* Java 的内存模型?
* 引用的分类?
* GC什么时候开始?
**JVM面试专题解析与拓展!**
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](http://www.icode9.com/i/li/?n=2&i=images/20210630/1625059701677248.jpg)
标签:面试官,并发,版本号,大牛,事物,面谈,面试,Spring,ActiveMQ 来源: https://blog.51cto.com/u_15288758/2961721