自己总结jvm,mysql, mybatis常见面试题(2)

JVM

1,谈谈JVM

JVM主要分为:两个子系统,两个组件。

两个子系统分为:Class loader(类加载器)、Execution engine(执行引擎);

两个组件为Runtime data area(运行时数据区)、Native Interface(本地接口)。

Class loader(类加载器):根据给定的全限定名(如:java.lang.Object)将class文件加载到JVM内存中。

Execution engine(执行引擎):执行classes中的指令。

Native Interface(本地接口):与native libraries交互,是其它编程语言交互的接口。

Runtime data area(运行时数据区域):这就是我们常说的JVM的内存。

在这里插入图片描述

JVM的内存分为:方法区,java堆,java栈,本地方法栈,

方法区:是一个抽象的概念,具体的实现是元空间,主要用于存储类的信息(包括内的名称,方法信息,字段信息)、常量、静态变量等。

栈:每一个线程都有自己的栈,方法在执行的时候会进栈,方法执行完成后会弹栈。

本地方法栈:每个线程启动的时候,还会分配本地方法栈内存,来给那些其他语言实现的方法使用(本地方法),Native Method (哪些用native修饰的方法)

java堆:被线程共享。在虚拟机启动的时候创建。这个区域唯一的作用就是存放对象的实例。对象实例,数组,字符串常量池。分为新生代,老年代。新生代又分为伊甸园区和幸存区。

2,谈谈GC垃圾回收

当堆区满了后 ,就应该进行垃圾回收,首先判断对象是否可以被回收。然后通过垃圾回收器进行回收。

判断对象是否可以被回收有两种方法

1, 引用计数算法,通过判断对象的引用数量,来决定对象是否可以被回收。

2,可达性分析算法。GCroots , 当一个对象到 GC Roots 没有任何引用链相连则对象可以被回收。

垃圾回收算法有:

1,标记清除(从GCroots向下进行遍历,可达的标记。碎片过多)

2,标记整理,整理是指存活对象向一端移动来减少内存碎片,相对效率较低

3,复制算法,开辟两份大小相等空间,一份空间始终空着,垃圾回收时,将存活对象拷贝进入空闲空间,优点是不会有内存碎片,但占用空间多。 from 区,to 区

4,分带垃圾回收,GC分代的基本假设:绝大部分对象的生命周期都非常短暂,存活时间短。根据各个年代的特点采用最适当的收集算法。新生代对象一般很少存活,采用『复制算法』、老年代对象生存时间长,适合采用『标记-清除算法』或『标记-整理算法』

5,垃圾回收器有:7种

经典的有串行回收器,多线程回收器,

G1(G one)回收器,G1是分区的概念 将内存分为一格一格的小区域,回收只回收一部分。基本没有延迟

优化工具:JDK 自带的Visual VM

3, 什么时候会出现内存溢出

1,方法调用过深(递归)

2,方法内局部变量太多

3,比如用EasyExcel将Excel读到内存中,一次读的过多。

4,什么是类加载器,类加载器的分类

类加载器:将class文件加载进入JVM内存中。

类加载的时机:类在使用的时候加载

分类:

(1)启动类加载器:负责加载的是JAVA_HOME/lib下的类库

(2)扩展类加载器 :加载JAVA_HOME/jre/lib/ext下的扩展类库

(3)应用程序类加载器:加载classPath下的类。用户类

5,类加载的过程

在这里插入图片描述

加载:通过包名+ 类名 用流的方式,将这个类加载进入到内存当中。系统为这个类建立一个Class对象,用于存储这个类中的信息(成员变量,成员方法)。

验证:Class文件字节流中,信息是否腹黑虚拟机规范,有没有安全隐患。

准备:为类中的静态变量分配内存,赋值为null

解析:本类中如果用到了其他的类,此时就需要找到对应的类。将符号引用换为直接引用。

初始化:给静态变量赋值,以及初始化其他资源。

6,双亲委派模型

每个加载器都有自己的加载范围,当发起一个加载请求的时候,先从底层的向上委派,当父类的加载器无法完成时,就会向下返回,保障每个类只加载一次。这样的类加载器的层次模型,就称之为双亲委派模型。
在这里插入图片描述

sql优化

load指令,导入百万数据

1,索引

在这里插入图片描述

索引的作用:索引是为了加速对表数据行的查询(检索)而创建的一种分散存储的数据结构

索引的分类:

按照属性分类:主键索引,唯一索引,全文索引,普通索引

按照数据存储方式分类:聚簇/聚集索引 ,非聚簇索引/辅助索引/二级索引

(聚簇索引的叶子节点挂的是这一行的数据,myspl的数据是基于索引去存储的。聚簇索引表中必须存在。主键就是聚集索引

二级索引:给其他字段创建索引 。 二级索引的叶子节点挂的是主键

(还有个复合索引,就是将几个字段使用一个索引 )

索引的结构:

B+Tree : B+Tree是 Btree的变种, (B树是一种多路平衡查找树)

最大的区别是B+Tree内部节点不保存数据,只保存索引信息,所有数据都保存在叶子节点,叶子节点是一个双向列表。

**索引的设计原则:**索引不是越多越好 ,维护索引需要代价。索引的创建存储在硬盘上,读取需要进行I/O

**索引失效:**1,以%开头的Like模糊查询,索引失效, 2,复合索引,不遵循最左前缀法则。3,用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,也不走索引。 4,字符串不加单引号,造成索引失效。 5,不要在索引列上进行运算操作, 索引将失效 等

2,sql优化

查看数据库 增删改查比例

explain查看sql执行的计划 ,将type的值 从null (全表)至少优化为 index

1, 避免使用select * 进行查询,因为会出现回表

2,在联合索引时,遵循最左前缀法则

3,**对插入语句的优化:**尽量使用多个值表的insert语句,在事务中进行数据插入。数据有序插入
4,在查询的时候尽量避免子查询,使用联合查询替代。
5,在or 查询两边都要建立索引,避免索引失效。
6,使用覆盖索引进行查询,避免回表。
(如果要查询辅助索引中不含有的字段,得先遍历辅助索引,再遍历聚集索引,而如果要查询的字段值在辅助索引上就有,就不用再查聚集索引了,这显然会减少IO操作。
普通索引(单字段)和联合索引,以及唯一索引都能实现覆盖索引的作用。)

3,sql的执行顺序

在这里插入图片描述

4,mysql的查询一对一,一对多
5,mysql的引擎

mysql数据库默认的存储引擎是InnnerDB

早些年用的是myIsam

InnnerDB 和 myIsam 做比较, InnnerDB 支持事务,支持行锁,支持外键,这些 myIsam都不支持,

但 myIsam支持 全文索引,但现在 InnnerDB也支持全文索引

目前公司用的mysql版本是5.1

6,三范式

第一范式(1NF):原子性,保证每一列不可再分

第二范式(1NF):在满足第一范式的前提下,第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

第三范式(1NF):确保每列都和主键列直接相关,而不是间接相关

7,limit第一个和第二个参数

limit 2,7 从索引2开始,查询7条数据。

8、Mysql中char和varchar有什么区别?

char : 固定长度字符串

varchar : 可变长度字符串

可变与不可变的区别就是char(10)是直接分配10 ,varchar(10)就是如果是1个字符的话就分配一个。

9、Mysql中float和double的区别是什么? decimal

float: 单精度浮点,4个字节、7位有效数字;效率高、不精确
double: 双精度浮点,8个字节、16位有效数字;效率低、较为精确
decimal: 用于存放金额等需要高精确度的数据,9位十进制存储4个字节 decimal(总长度M,小数长度D)

10、Mysql中date和datetime类型的区别?

date: YYYY-MM-DD,精确到天
datetime: YYYY-MM-DD HH:mm:ss,精确到秒,跨时区易出现问题

11、说一下MySQL数据库事务的三个安全性问题?

脏读: 读到未提交的数据

不可重复读: 在一个事务中读取到另一个事务已提交的数据。

幻读:查询某个数据不存在,但在执行插入此记录时,显示记录已存在,

某记录不存在,但你删除时却发现删除成功了。好像出现幻觉一样。

12、MySQL 事务 ACID (酸)

A 原子性:一个事务中的sql语句,要么同时成功,同时失败

C 一致性:总金额不变

I 隔离性:当并发访问同一张表时,数据库为每个用户开启事务,这些事务之间互不影响

D 持久性:提交后就存储到硬盘中

13,mysql数据库的隔离级别

read uncommited: 读未提交;脏读、不可重复读、幻读
read commited: 读已提交;不可重复读、幻读
repeatable read: 可重复读;幻读------default
serialize: 串行化。

14,mysql的锁

按照粒度划分: 表锁和行锁

锁的类型:

InnoDB 实现了标准的行级锁,也就是共享锁(Shared Lock)和互斥锁(Exclusive Lock)。

  • 共享锁(读锁),允许事务读一行数据。
  • 排他锁(写锁),允许事务删除或更新一行数据。

mysql的死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象

共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁,直到已释放所有共享锁。获准共享锁的事务只能读数据,不能修改数据。 排他锁(X锁):如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的锁,直到在事务的末尾将资源上的锁释放为止。获准排他锁的事务既能读数据,又能修改数据。

互斥锁(排它锁、独占锁、写锁、X锁)和共享锁(读锁、S锁) 自旋锁

15,Mysql中 的约束

约束是一种限制,它通过对表的行或列的数据做出限制,来确保数据的完整性、一致性。

非空约束、主键约束、唯一约束、自增、外键约束

16,Mybatis如何实现分页,分页插件的原理是什么?

使用PageHelper分页插件实现,其原理是通过拦截器实现的,在执行时往所有要执行的sql语句后加上limit限制条件。

PageHelper.startPage(1, 5);

PageInfo 中保存分页的所有信息

17,Mybatis中${} 和#{}有什么区别?

${} 会产生spl注入攻击 , Statement对象执行sql语句时,会将密码内容进行拼接 到sql中 当作查询条件来执行。
在这里插入图片描述

PreparedStatement预编译执行者对象,在执行sql之前会预先编译。明确sql格式,剩下的是变量。使用?占位符。

<insert id="insert" parameterType="User">
INSERT INTO user (name) VALUES (#{name});
</insert>

16:00:00.691 [main] DEBUG com.tianshouzhi.dragon.common.mappers.UserMapper.insert - ==>  Preparing: INSERT INTO user (name) VALUES (?); // 这里发现是?占位符
16:00:00.750 [main] DEBUG com.tianshouzhi.dragon.common.mappers.UserMapper.insert - ==> Parameters: tianshozhi(String)
18,动态sql

使用foreach可以循环数组,list集合,一般使用在in语句中,批量插入数据。

in:

//SELECT * FROM student  WHERE id IN (1,2,5)。
<select id="findByIds" parameterType="list" resultType="student">
    select * from student
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

批量插入数据

<!-- MySql批量插入,并返回主键Id -->
<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id" parameterType="java.util.List">
    insert into xxxx values
    <foreach collection="list" item="item" index="index" separator=",">
        xxx
    </foreach>
</inser>

if:

//比如在 id如果不为空时可以根据id查询,如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
<select id="findByCondition" parameterType="student" resultType="student">
    select * from student
    <where>
        <if test="id!=0">
            and id=#{id}
        </if>
        <if test="username!=null">
            and username=#{username}
        </if>
    </where>
</select>
19,mybatis⼀级缓存和⼆级缓存?

MyBatis提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。 Mybatis中缓存分为一级缓存,二级缓存。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q49hcVio-1623606519786)(C:\Users\www27\Desktop\images\1623604751605.png)]

Mybatis的一级缓存:同一个sqlSession对象

Mybatis默认开启一级缓存,如果用同一个SqlSession对象查询相同的数据,则只会在第一次查询时,向数据库发送SQL语句,将查询的结果放入到SQLSession中,后续再次查询该同样的对象时,则直接从缓存对象中查询该对象即可。

Mybatis的二级缓存:同一个namespace

如果是同一个SqlSession对象进行多次相同的查询,则直接进入一级缓存查询,如果不是同一个SqlSession对象进行多次相同的查询(但是该均来自同一个namespace),则进入二级缓存查询。 (二级缓存默认没有开启)

开启二级缓存

在这里插入图片描述

20,Mybatis中resulttype和resultmap区别?

在mybatis的mapper.xml中,我们需要定义查询结果返回类型,常见的属性有resultType和resultMap,

若是实体类的字段和数据库的字段一一对应,则可直接用resultType,resultType的值为返回的对象,

<mapper namespace="com.example.demo.DAO.HelloWorldDAO">
    <select id="query"  resultType="student">
        select * from student
    </select>
</mapper>

如果数据库字段和实体类字段不是一一对应的,则需要采用resultMap属性,两者字段之间进行映射,写法如下:

<mapper namespace="com.example.demo.DAO.HelloWorldDAO">

    <select id="query"  resultMap="studentResult">
        select * from student
    </select>

```
    <resultMap type="student" id="studentResult">
       <result property="studentId" column="student_id"/>
       <result property="studentName" column="student_name"/>
    </resultMap>
```

</mapper>

21,1对1查询,1对多查询?

(一对一,一对多查询其实就是链表查询 )

<!-- 一对一查询的结果封装 -->
<resultMap id="" type="全类名">
	<id property="类中属性名" column="表中字段名"/>
    <result property="类中属性名" column="表中字段名"/>
    <association property="类中属性名" javaType="对应的java全类名">
        <id property="类中属性名" column="表中字段名"/>
    	<result property="类中属性名" column="表中字段名"/>
    </association>
</resultMap>
<!-- 一对多,多对多查询结果封装 -->
<resultMap id="" type="全类名">
	<id property="类中属性名" column="表中字段名"/>
    <result property="类中属性名" column="表中字段名"/>
    <collection property="类中属性名" ofType="对应的java全类名">
        <id property="类中属性名" column="表中字段名"/>
    	<result property="类中属性名" column="表中字段名"/>
    </collection>
</resultMap>
22、JDBC入门

(1)创建mysql数据库的驱动

(2)获取连接Connection

(3)获取执行者对象 Statement

(4)执行sql,返回结果,ResultSet

(5)遍历结果

(6)释放对象rs.close , stat.close , con.close

23,解决Maven中依赖冲突问题 (不兼容)

1,路径优先,直接依赖优于传递依赖。

2,排除,在发生传递依赖冲突时,如果依赖不是项目需要的,可以在对应的传递依赖声明中进行排除。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值