MySQL面试突击_面试突击

发布时间:2023-08-22 15:00

1、如果线上机器突然宕机,线程池的阻塞队列中的请求怎么办?

导致队列中积压的任务会丢失

解决 : 提交任务之前先在数据库里插入这个任务的信息,并标以状态比如 : 未提交、已提交、已完成。待机器重启后,使用一个后台线程扫描表中已提交和未提交的数据,进行重新提交

2、谈谈你对Java内存模型的理解

每条线程有自己的工作内存,工作内存中保存了被该线程使用的变量的主内存副本。线程不可以直接操作主内存,不同线程不可以访问对方工作内存中的变量,线程间变量的传递都是通过主内存来完成。

将一个int a = 0 改为 1的流程包括:

从主内存中read到 a= 0

将a = 0 load到工作内存中

线程use工作内存中的a = 0将a设置为1

将a = 1 assign到工作内存中

工作内存将a =1 通过store、write进主内存

3、Java内存模型中的原子性、可见性、有序性?

原子性:操作不可拆分,同一时刻只有一个线程可以进行操作。

可见性:一个线程中某个变量的修改能马上被其他线程知晓

有序性:jvm虚拟机为了性能优化在单线程不影响结果的情况下会进行指令重排,有序性就是禁止指令重排

4、volatile工作原理?如何保证可见性?原子性为什么不能保证?

回答顺序:内存模型 ==》 原子性、可见性、有序性 ==》volatile

volatile 和 原子性 : 不能保证,多线程会存在问题

volatile 和 可见性 :可以保证,一个被volatile修饰的变量修改之后马上会写入主内存,并且让其他线程中改变量的缓存失效。那么其他线程要读取的时候就必须要去主内存中读取

volatile 和有序性 :

5、happens-before/内存屏障是什么?

6、spring中bean是线程安全的吗?

思路 :先描述一下spring中的作用域

spring的作用域有五种 :singleton、prototype、request、session、global-session

默认的作用域是singlton,如果在某个实例中存在实例变量,那么多线程调用的时候就会出现线程不安全的情况。

7、spring事务的实现原理是什么?说一下事务传播机制?

事务的原理就是如果你加了一个@Transactional注解,此时spring就会使用AOP思想,对你的这个方法在执行之前,先去开启事务,执行完毕之后,根据你方法是否报错来判断是否执行回滚操作。

propagation_required : 默认,如果没有事务就新建一个事务,如果有事务存在就加入

propagation_supports : 如果有事务就加入事务,如果没有事务就以非事务方式运行

propagation_mandatory:使用当前事务,如果没有事务就报错

propagation_required_new : 新建事务,如果存在事务就将当前事务挂起

propagation_not_supported:以非事务方式运行,如果当前存在事务,就将事务挂起

propagation_never : 以非事务方式运行,如果存在就抛出异常

propagation_nested : 外层事务如果回滚,内层事务回滚。但是内层事务如果回滚,仅仅回滚自己的代码

8、spring bean的生命周期

实例化bean :

属性填充:实例化后的对象被封装在BeanWrapper中,spring根据BeanDefinition中的信息以及通过BeanWrapper提供的设置属性的接口完成依赖注入

处理Aware接口:Spring接口会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean:

如果实现了BeanNameAware接口,会调用他的setBeanName(String beanId)方法

如果实现了BeanFactoryAware接口,会调用setBeanFactory()方法,传递的就是工厂本身

如果实现了BeanClassLoaderAware接口,会调用setBeanClassLoader方法

BeanPostProcessor : bean自定义的一些前置处理,applyBeanPostProcessorsBeforeInitialization

PropertiesSet 和 init-method方法的调用

BeanPostProcessor :bean自定义的一些后置处理,applyBeanPostProcessorsAfterInitialization

9、spring涉及的设计模式?

工厂:

单例:

代理:

10、索引

b-树

MySQL面试突击_面试突击_第1张图片

B+树

MySQL面试突击_面试突击_第2张图片

myisam叶子节点不存数据,存的是物理地址,然后根据物理地址到数据文件中去查找到对应的数据。

innodb 默认会根据主键建立索引,称为聚簇索引。innodb的数据文件本身就是索引文件,聚簇索引的叶子节点存储了真实的数据,如果对非主键建立索引,其叶子节点存储的是主键的值,然后根据主键再查询到对应的数据,该操作称之为回表。

索引的原则 : 全值匹配、最左匹配原则、慎用like 百分号在右边、范围查找只有范围查找字段可用索引、不要使用函数修改列

11、mysql事务

ACID  ---- 事务的隔离级别

atomic :原子性,一堆sql要么一起成功要么一起失败

consistency :一致性,针对数据一致性来说的。就是一组SQL执行之前是正确的,执行之后数据也必须是准确的。

isolation : 隔离性,多个事务跑的时候不能互相干扰

durability : 持久性,事务成功后, 对数据的修改必须永久生效。

事务隔离级别:

读未提交 read uncommited :A线程可以读取到B线程未提交的数据,这个叫做脏读

读已提交 read commited : A线程跑的时候,先查询一个值为1,这时候B将这条记录改为2,并提交了事务,此时A再次查询该条记录的时候就发现变为2,这个问题叫做不可重复读

可重复读 read repeatable :A线程在运行过程中,对于某个数据的值,无论读多少次都不会改变,哪怕B线程修改了该值并提交了事务。

串行化 : 不可重复读和可重复读都存在幻读的问题,假设表中只有一条数据,事务A查询全表查询一条数据,这时候事务B插入一条记录,事务A再次查询出现了两条。如果要解决幻读,就需要使用串行化隔离级别的事务,将多个事务串行起来,不允许多个事务并发操作

MVCC :多版本并发控制

innodb在存储的时候,会在每行数据的最后加两个隐藏列,创建时间和失效时间,保存的值都是事务的id,innodb事务开始的时候都会被分配到一个事务id,依次递增

一个事务在查询的时候,innodb只会查询创建时间事务id 当前事务的id的数据

当执行update操作的时候,innodb实际上将原有列的失效时间覆盖,然后新增一条创建时间为当前事务id的数据

update操作表里肯定还是一条数据,那么事务是怎么查到之前的版本的呢?更新的时候都会在undo.log中记录一条对应版本回滚记录,然后我们只要根据当前事务id对当前值进行回滚操作,就可以看到我们应该看到的数据了。

12、数据库锁有哪些类型?锁是如何实现的?行级锁有哪两种?一定会锁定指定的行吗?为什么?悲观锁?乐观锁?使用场景是什么?mysql死锁原理以及如何解决?

mysql锁类型一般就是表锁,行锁和页锁

表锁 : 意向共享锁:就是加共享锁的时候,必须先加这个共享表锁;还有一个意向排他锁,就是给某行加排他锁的时候,必须先给表加排他锁。这个表锁是引擎自动加的

innodb行锁有共享锁(S)和排他锁(X)两种,多个事务可以加共享锁读同一行数据,但是别的事务不能写。排他锁就是一个事务可以写,别的事务只能读不能写。

innodb在insert、delete、update的时候会自动给那一行加排他锁

innodb不会自己主动加共享锁 ,必须自己手动加: select * from table where id = 5 lock in share mode

手动加排他锁 : select * from table where id =  5 for update;

悲观锁和乐观锁

悲观锁:总是害怕拿不到锁,总是先加锁

乐观锁:先查出来一条数据,修改的时候查看数据库是不是还是那个版本,如果还是那个版本就修改。不然就重新查出来再修改

死锁:

场景:

事务A : select * from table where id =  1 for update;

事务B : select * from table where id =  2 for update;

事务A : select * from table where id =  2 for update;

事务B : select * from table where id =  1 for update;

持有对方的锁,gg

解决方案 : 找下dba查一下死锁的日志

13、mysql优化

explain select * from table;

table : 哪个表

type(重要):

all:全表扫描

const : 读常量,最多一条记录匹配

eq_ref : 走主键,一般最多一条记录匹配

index :扫描全部索引

range : 扫描部分索引

possiable_keys : 显示可能使用的索引

key : 实际使用的所以

key_len : 使用索引的长度

ref :联合索引的哪一列被用

rows : 一共扫描和返回了多少行

extra :

using filesort :需要额外排序

using temporary :构建了临时表,比如排序的时候。 using temporary常见于group by会出现,这种情况是最不能忍受的。因为创建临时表会需要消耗很大的时间,也是导致sql变慢的主要原因

using where :就是根据索引出来的数据再次根据where来过滤结果

14、什么情况下会进入老年代?

熬过默认的15次垃圾回收

垃圾回收的时候s区放不下就进入老年代

大对象进入老年代

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号