• “谈谈如何理解索引?谈谈如何理解事物?”我来带你模拟面试~


    目录

    索引

    事务

    面试官:“把原子性总结一下吧~”;

    如果面试管继续问:“除了原子性之外,另外三个特性呢?”;

    面试管引导你:“什么是并发执行呢?”。

    面试管:“那隔离是为什么呢?”。

    面试官:“为什么会‘打架’呢?”

            情况一:脏读

            情况二:不可重复读

            情况三:幻读

    面试官:“那么如何解决脏读、不可重复读、幻读问题呢?”;

    解决脏读:写加锁

    解决不可重复读:读加锁

    解决幻读问题:串行化

    面试官:“既然有利有弊,真的遇到问题了你会如何处理呢?”;

    事务的四种隔离级别

     在 mysql 数据库中,你是如何使用事务的?


    如何解决这些高频面试题?

    大致回答思路如下:

    谈谈如何理解索引?

    • 索引是干什么的(解决了什么问题)
    • 索引付出的代价
    • 索引背后的数据结构

    谈谈如何理解事务?

    • 事务是干什么的(从原子性切入)
    • 事务还有其他什么特点
    • 重点讲述隔离性,在并发事务下会有哪些问题,以及如何解决问题
    • MySQL的隔离级别有哪些,和上面的问题如何应对

    有想法了吗?


    索引

    基本认识

    1.索引的效果:本质上就是缩小扫描范围,避免全表扫描,可以加快查找效率;

    2.索引的代价:索引实际上也是一张表,保存主键和索引字段,指向实体表的记录,因此不仅需要占用一部分空间,还在每次对表的索引字段进行增删的同时,还需要更新一下索引文件,牺牲了一定的开销.

    3.背后的数据结构:B+树(N叉搜索树)

    在什么条件下,我们会考虑给字段添加索引呢?

    条件1:数据量庞大

    条件2:该字段经常出现在where的后面,以条件的形式存在。即这个字段总是被扫描。

    条件3:该字段很少的DML操作。因为DML之后索引需要重新排序

    Ps:建议不要随意添加索引,因为索引也是需要维护的。太多的话反而会降低系统的性能。建议通过主键查询,通过unique约束的字段进行查询,效率较高。

    不推荐建立索引的场景

    1、表记录太少

    2、经常增删改的表

    3、where条件里用不到的字段不建立索引主键的创建

    索引的创建和删除

    给 student 表的 id 字段创建索引,起名为 id_index

    create index id_index on student(id);

    将 student 表上的 id_index 索引对象删除

    drop index id_index on student

    这里博主已经整理出十分详细的博客啦,可以来看看~

    http://t.csdn.cn/eGCW6


    事务

            通俗来讲,就是干一件事,要么全都执行完,要么一个都不执行~

             (从特性切入讲给面试官,先从原子性开始):这里就不得不说以下他的一大特性:原子性。什么是原子性呢?都知道的是以前物理书上讲:原子是不可分割的最小单位(当时科技还不发达,其实原子还可以再分为原子核和核外电子,原子核又是中子和质子构成,夸克...哈哈扯多了)后来就把这个术语沿用到计算机领域了,事务就是用来保证原子性的

            举个栗子,例如一个转账服务,张三给王五微信转账500块钱,那么就需要从张三的微信中扣除500元,接下来给王五的微信账户中加上500元,但是万一在这个转账的过程中(执行王五收账的这条代码还没有执行)出现了故障(例如断电),那么给王五转账的那500元就收不到了~ 

            这个时候啊,需要按照原子的方式来进行,要么都执行,要么一个都不不执行(不是说真的 不执行,而是执行到一半出现问题的时候,能够自动回复如初);

            事务就能保证,如果执行到一半出问题时,自动进行还原,恢复如初,这叫做——”回滚“,在事务进行的过程中MySQL都会记录每步干了什么,一旦遇到问题,就可以根据记录回滚~;

    面试官:“把原子性总结一下吧~”;

            原子性:事务的根本所在(也是事务存在的意义),能够把多个sql语句打包成一个整体,要么都执行完,要么一个都不执行(如果出错,直接回滚);

    如果面试管继续问:“除了原子性之外,另外三个特性呢?”;

            一致性:事务执行前后,数据处在“一致”状态;(数据能对的上,合情合理)

            持久性:事务进行的改动都是在硬盘里的,不会随着主机的(重启 / 关机)而丢失数据;

            隔离性(隔离性最复杂,也是面试管最想听到的(看你能不能讲清楚~)):多个事务并发执行的时候,事务之间可以保持“隔离”,互不干扰;

    面试管引导你:“什么是并发执行呢?”。

            MySQL的本体就是服务器,执行sql语句,本质也是客户端把sql发送给服务器,让服务器去执行;事务也是将sql语句发给服务器执行,而同一时刻,多个客户端都在给服务器发送事务,让他执行,这便是“并发执行”(简单理解就是同时做很多事情~);

    面试管:“那隔离是为什么呢?”。

            如果这些并发执行的事务是对多种不同的数据库 / 不同的表 操作,那就没事了~

            但是如果操作的同一数据库,同一个表,那就可能要“打架”了!

            隔离存在的意义,就是让并发执行的事务,尽量避免“打架”(使问题控制在可控范围之内~);

    面试官:“为什么会‘打架’呢?”

            情况一:脏读

            举个栗子,我的妈妈说:“咱们中午在家吃饭吧~”,而我的媳妇却说:“咱们中午出去吃吧~”,在这种冲突之下,该做何选择?说不准吧~

            讲个有意思的栗子:你和你妈掉水里了,你救哪个?我:救我妈,然后我也跳河里,一起坠入爱河~

            在说个详细点的,想象这样一个场景,我在上班的时候敲代码,然后我的同事跟我要完成同一个任务,但他在一旁暗中观察,他看到我这样写:“class list { public int val; publi...”;然后他没看完就走了,他或许还会想:“原来要这样写,我真是给大聪明!”;是啊,真是个大聪明,顺便提一嘴,在公司工作的时候不要抄袭别人代码!!!后果很严重!!!言归正转,他走了之后,我忽然发现刚刚写的代码有点问题,我就给改了~

            这就是属于脏读问题,脏读数据,就是一个零时数据,不代表结果;

            脏读:一个事务A在修改数据之前,事务B读取了数据,然后A修改了数据,那么此时B读到的就是“无效的数据”,简称:脏读。

            情况二:不可重复读

            我说,等我整个程序做完了,交给老板后,上传码云,你再看着学习吧;等我提交之后,我突然又有了一些想法,就直接开始在码云上改,而同事真好在看码云,忽然发现,代码变了~

            不可重复读:在一个事务A中,多次读取数据发现不一样(读的过程中被修改了);

            情况三:幻读

            既然约定,你读的时候我不能改,那么我这样想,你读文件A的时候,我去修改B;(掩耳盗铃,同事刚读完的B文件,我就去修改,别人不看就说明我能修改...);

            幻读:可以视为“不可重复读”的特殊情况,两次读虽然关心的数据一样,但结果集变了。

    面试官:“那么如何解决脏读、不可重复读、幻读问题呢?”;

    解决脏读:写加锁

            我跟那个同事说,你就不要看我的代码了,等我把任务完成,提交给老板,我在把码云发出来,你可以学习以下~

            在提交之前不能读,提交之后才能读;

            相当于对写操作,加锁;

            分析:加锁前,我写的操作,和同事读的操作是并发的(效率最高),隔离性最低(准确性最低);加锁后,我写的操作时,同事不能读了,只有等我上传码云之后才能读,并发性降低了(效率变低了),隔离性变高(准确性变高了);

    解决不可重复读:读加锁

            在写加锁的基础上,同事跟我说,我读的时候你就不要修改了~

            在我写的时候,你不能读,你读的时候我不能写;

            你看的时候我不能修改,这就是读加锁;

            分析:此时并发性进一步降低(效率降低),隔离性进一步提高(准确度提高)

    解决幻读问题:串行化

            咱就是说,只要你在读代码,我就关机,什么都不要做,代码一点都不能动!

            分析:此时并发性最低(效率最低),隔离性最高(准确度最高);

    面试官:“既然有利有弊,真的遇到问题了你会如何处理呢?”;

            如果需求对于精确度要求不高,因此就可以让并发性高一点,隔离性低一点,提高效率;(例如:点赞数,浏览量...)

            如果需求对于精确度要求高,因此就可以让并发性低一点,隔离性高一点,提高准确度;(例如:有关钱财问题...)


    事务的四种隔离级别

    1. 1.read uncommitted;
    2. 允许读未提交的数据,并发程度最高,隔离性最低,可能存在 脏读/不可重复读/幻读 问题;
    3. 2.read committed;
    4. 只能读提交之后的数据,相当于写加锁,并发性降低,隔离性提高,解决脏读问题,可能存在不可重复读,幻读问题;
    5. 3.repeatable read;(默认)
    6. 相当于读和写都加锁了,并发性再次降低,隔离性再次提高,解决 脏读/不可重复读,可能存在幻读问题;
    7. 4.serializable;
    8. 严格执行串行化,并发性最低,隔离性最高,解决 脏读/不可重复读/幻读问题

     在 mysql 数据库中,你是如何使用事务的?

    在一些数据需求精确度要求高的地方,我们就可以使用事务,比如银行转账服务等...

    具体的,想象这样一个场景:张三需要从卡上取 100 元钱,那么这个时候就可以使用事务了~(因为一旦出现网络错误,或是数据库挂掉了,就有可能出现卡中的钱扣掉了,但钱没取出来~)

    (1)首先在取钱之前开启事务:start transaction;

    (2)执行取钱的 SQL 语句;

    (3)回滚或提交(若没有意外,则进行提交,否则进行回滚~):rollback/commit;

    如下:


  • 相关阅读:
    Unity——对象池
    《游戏编程模式》学习笔记(十三)组件模式 Component
    arcgis pro中的底图
    Python:一个函数可以被多个装饰器装饰
    用Auth Analyzer插件批量测试接口越权,安全测试快人一步!
    Material Design组件 - 使用BottomSheet展现扩展内容(一)
    设计模式-中介者模式
    python中怎样把一个文件夹中所有的*.ts文件都读进来形成一个视频文件?
    mybatisplus自动生成器
    存储模型:大端和小端
  • 原文地址:https://blog.csdn.net/CYK_byte/article/details/126449451