JVM篇
一.谈一谈JDK、JRE、JVM分别是什么,有什么联系?
1.JDK是Java工具包,里面包含了JRE、Javac编译器等。
2.JRE是java运行环境,里面包含了JVM、JavaSE标准库类等。
3.JVM是Java虚拟机,运行编译后的.class的文件,调用系统API运行。
JDK = JRE+Javac编译器 JRE = JVM+JavaSE标准库
二.JVM运行时数据区由哪几部分构成,分别有什么作用
1.程序计数器:保存执行下一条指令的地址。(线程私有化)
2.虚拟机栈:保存局部变量,形参、调用函数关系等。(线程私有化)
3.本地方法栈:和虚拟机栈差不多,底层是C或C++代码,方法应Native修饰(线程私有化)
4.堆区:保存new的对象(线程共享)
5.方法区(元数据区):存放静态变量、常量(线程共享)
三.JVM类加载器有哪些?
1.BootstrapClass loader 标准库类加载器
2.ExcetionClass loader 扩展类加载器
3.ApplicationClass loader 第三方库类加载器
4.自定义类加载器
四.谈一谈类加载的过程以及什么是双亲委派模型
类加载的过程:
1.加载:找到对应的.class文件,打开并读取
2.验证:验证读取到的.class文件是否符合JVM规范
3.准备:为读取到的.class类分配内存空间,并且初始化为零
4.解析:将常量池中的符号引用替换为直接引用
5.初始化:执行静态代码块、静态方法等进行初始化。
双亲委派模型:
1.当请求需要加载自己的类时,首先不会自己加载,将加载的任务交给父类,如果此时父类能够加载,子类就不会加载。如果此时父类没有对应的类,才会加载自己的类。
2.双亲委派模型保证了标准库类加载器的优先级最高,保证类不会被重复加载。
3.双亲委派模型保证了加载过程中的稳定性与安全性。
五.谈一谈JVM是如何发现垃圾的有几种方法?
1.引用计数法:
JVM回收的对象主要是堆区里的不再被引用的对象,如果该对象被引用,那么计数器+1,如果该对象被断开引用,计数器-1,直到计数器为0时,回收该对象。
造成的问题: 循环引用问题,可能会导致回收错误等问题。
2.可达性分析:
可以专门拿出一条线程处理,进行全局扫面,从GCroot 开始扫描所有对象,最终构成一条引用链,如果有对象周期性扫描结束后没有在该引用链上时,就被标记为需要回收的垃圾。
一般可以选定为GCroot的引用对象的是:
1.虚拟机栈中引用的对象
2.方法区中静态成员变量所引用的对象
3.方法区中常量引用的对象
4.本地方法栈中引用的对象
六.回收垃圾的方式有几种?
1.标记-清除法
经过可达性分析之后,被视为垃圾的被标记一下,经过周期性扫面后,直接将被标记的对象清除。
缺点:会造成内存碎片化,不能够充分利用内存空间。
2.标记-清楚整理法
该方法时标记清除法的延申,当标记清除结束后,再将内存空间中存活的对象进行整理。
缺点:整理需要耗费大量时间,效率低下。
3.复制算法
每次只使用一般的空间,当使用的空间中出现垃圾,首先将存活的对象全部移动到另一半空间中,之后之间将使用过的一半空间直接清除。
缺点:空间利用率较低
4.分代回收法
将堆区划分为新生代和老年代,新生代划分为伊甸区和幸存区,当对象被创建时,首先放入伊甸区,之后经过周期性的可达性分析标记出需要回收的垃圾,通过复制算法将伊甸区的不可用对象进行回收,经过几轮筛选,将幸存的对象放入幸存区,之后同样经过可达性分析之后,经过复制算法进行垃圾回收,经过几轮筛选将还存活的对象放入老年代。此时老年代也是需要进行可达性芬分析和垃圾回收的,只不过相较于新生代频率会比较低。
大多是垃圾回收器采用分代回收的思路。
七.谈一谈JVM中所用的垃圾回收器
1.多线程垃圾回收器G1 GC :将内存划分为多个区域,优先回收垃圾最多的区域,基于复制算法回收,不再是一次性回收,而是少量多次,降低了STW发生的时间。
- CMS收集器,以获取最短停顿时间为目标,采用标记-清除算法,降低STW发生的时间,但是会造成内存碎片化问题。
八.JVM类初始化顺序
父类静态代码块和静态成员变量 -> 子类静态代码块和子类静态成员变量 -> 父类代码块和普通成员变量 -> 父类构造方法 -> 子类代码块和普通成员变量 -> 子类构造方法
MySQL篇
一.MySQL中什么是聚簇索引和非聚簇索引
1.聚簇索引指的是叶子节点中保存的是索引对应的完整行信息。
2.非聚簇索引指的是叶子节点保存的只是索引本身
二.谈一谈MyISUM与InnoBD的区别
1.MyISUM与InnoDB作为搜索引擎,MyISUM不支持事务,只能在应用层保证数据的一致性与完整性,但是InnoDB支持事务,保证了数据的一致性和完整性
2.MyISUM仅能够支持表锁,在进行写或读操作时,其他读写操作会被阻塞。InnoDB可以支持行级锁,在事务进行读写操作时,不影响其他事务的读写操作。
3.MyISUM的所有的索引使用的是非聚簇索引,查询数据时需要进行回表操作,InnoDB主键索引使用的聚簇索引,查询数据高效,但是非主键索引使用的是非聚簇索引,也需要进行回表操作,但是通过索引下推机制可以有效减少回表次数。
4.MyISUM崩溃后不能进行回复,但是InnoDB崩溃后可以恢复,利用MVCC,redo log ,undo log日志进行恢复。
5.MyISUM不支持外键约束,无法保证数据的一致性,但是InooDB支持外键约束,可以保证数据的完整性与一致性。
三.谈一谈事务的隔离级别
**1.读未提交:**当通过一个事务读取另一个事务未提交的数据
造成的问题:脏读问题,如果一个事务读完之后,另一个事务进行回滚擦操作,此时读到的数据是错误的。
**2.读已提交:**当通过一个事务可以读取另一个事务已经提交的数据。
造成的错误:不可重复读问题,当一个事务读取结束后,另一个事务对我刚刚的数据进行更新操作,此时下一次读到的数据和这一次会发现不一样了。
**3.可重复读:**开启事务后,不可以再进行修改。
造成的错误:此时一个事务读完数据以后,另一个事务进行数据的增加,数据量变多了,此时就造成了幻读问题。
**4.串行化:**该事务级别是最高的,有效避免了上述提到的三个问题,但是由于效率过低,一般不会开启。
四.MySQL中的索引种类:
**1.普通索引:**可以允许有多个,没有特殊要求,主要数位了加快查询效率
2.唯一索引:需确保索引列中的值是唯一的,可以支持NULL,也可以有多个
**3.主键索引:**特殊的唯一索引,只能有一个,且该列中的值不可重复,索引列中不支持NULL
**4.复合索引:**一个索引包含多个列,在多列查询时效率高效
**5.全文索引:**用于处理类型是Text的数据,支持对文本高效查询
五.什么是快照读和当前读
1.快照读,读的是当前数据的历史版本,且未加锁,读写效率高效,但读到的可能是会过期数据。
2.当前读,读的是当前数据的最新版本,加了间隙锁与行级锁,支持高并发。
六.MVCC是什么?
1.MVCC是多版本控制,是为了在读取数据时,不加锁来提高读取效率和并发的一种手段,我们在解决隔离级别中出现的问题时,一般有两种方式。
2.通过MVCC实现的快照读的基础上解决了读已提交的不可重复读问题与可重复读中幻读问题。
3.在读已提交的隔离级别下,每次会产生一个新的readview规则,然后每次遵循readview规则的版本连去获取读到的数据。
4.在可重复读的隔离级别下,每次读只有在第一次读的过程中才产生readview规则的undolog版本链。
七.为什么不采用B树而采用B+树?
1.B树叶子节点与非叶子节点都存储了行数据具体信息,导致每个节点能容纳的键值较少,树高相对较高
B+树非叶子节点只存储键值与指针指向,只有叶子节点才存储完整的数据信息,所以树高较低,导致IO次数减少。
2.B树的叶子节点之间没有任何关联导致,全表扫描序遍历整棵树,效率较低
B+树叶子节点存储完整信息,并且节点之间用指针连成链表,查询效率较高。
3.当表中数据进行变更,B树需要进行整体的移动,维护成本较大。
B+树只需要对叶子节点进行维护即可。
八.MySQL中有哪些锁?
1.按属性分:
共享锁(读锁):又称读锁,一个事务为表加了读锁以后,其他事务只能加读锁,不能加写锁。
排他锁(写锁):又称为写锁,一个事务为表加写锁以后,其他事务只能加写锁,不能加读锁,避免脏读问题。
2.按锁粒度分:
表锁(串行化级别加):整张表粒度大,并发小
行锁(可以解决不可重复读问题):对行加锁,粒度小,并发大。
间隙锁(可以解决幻读问题):锁住表的一个区间,只在不可重复读事务下才生效,解决了幻读问题。
九.哪些情况下索引会失效?
1.对索引列进行函数、计算等操作。
2.使用OR时,两边的表达式必须均为索引,不然就会失效
3.使用like进行模糊查询时
4.在使用复合索引时,没有遵循最左侧规则
5.索引字段发生类型转换
6.所查询的内容较多时,此时全表扫描的效率比用索引查询高,此时索引查询会失效
十.对于慢SQL如何进行优化
1.定位慢SQL:
开启慢查询日志,利用MySQL监控工具分析高频慢SQL语句。
2.分析执行计划:
使用explain查看sql执行计划,主要关注
访问类型:如果是ALL(全表扫描)需要优化
索引使用:如果查询语句中没有命中索引需要优化
扫描行数:行数过多需优化查询条件或索引等
3.优化索引:
对where、order by、join涉及的字段添加索引。
优化联合索引,遵循最左前缀原则
覆盖索引,确保索引覆盖所有查询字段,避免回表
4.重写SQL语句:
拆分嵌套子查询为join,减少零时表的使用
避免函数操作字段,函数会导致索引失效