东方国信JAVA面经

东方国信JAVA面经

题目选自牛客面经!!! 内容来自个人整理!!!

1、mybatis使用流程

参考地址 中文官网

介绍

MyBatis的底层操作封装了JDBC的API,其工作原理和核心流程与JDBC的使用步骤一脉相承

MyBatis的基本工作原理就是:先封装SQL,接着调用JDBC操作数据库,最后把数据库返回的表结果封装成Java类

JDBC对象

名称描述
DriverMananger用于注册数据库连接
Connection与数据库连接
Statement/PrepareStatement操作数据库SQL语句的对象
ResultSet结果集或一张虚拟表

Mybatis对象

名称描述
SqlSession包含了所有SQL语句,但是并不是执行者,类似Connection
Executor根据SqlSession对象传来的参数动态生成SQL语句,同时负责查询缓存的维护
MappedStatement对映射SQL的封装,用于存储要映射SQL语句的ID、参数等信息
ResultHandler对返回结果进行处理,最终得到自己想要的数据格式或类型,可以自定义返回类型

tips: 在JDBC中,Connection不直接执行SQL方法,而是利用Statement或者PrepareStatement来执行方法。在使用JDBC建立了连接之后,可以使用Connection接口的createStatement()方法来获取Statement对象,也可以调用prepareStatement()方法获得PrepareStatement对象,通过executeUpdate()方法来执行SQL语句。而在MyBatis中,SqlSession对象包含了执行SQL语句的所有方法,但是它是委托Executor执行的。从某种意义上来看,MyBatis里面的SqlSession类似于JDBC中的Connection,他们都是委托给其他类去执行.

工作流程

以下内容均摘自:MyBatis中文官网 详细且易懂

在这里插入图片描述

流程描述
1、读取MyBatis配置文件。MyBatis-config.xml文件是全局配置文件,用于配置数据库连接信息
2、加载映射文件。映射文件即SQL文件,该文件配置了操作数据库的SQL语句,需要在全局配置文件加载,可以加载多个映射文件,每个映射文件对应一张表
3、构造会话工厂(会不会跟线程池一个目的),在全局配置文件中配置该信息
4、创建会话对象,由会话工厂创建SqlSession,该对象包含了所有SQL语句
5、执行器,操作数据库的底层接口,将会话对象传递的参数动态生成SQL语句,同时负责查询缓存的维护
6、MappedStatement对象,在执行器接口的执行方法中有一个MappedStatement类型的参数
7、入参数映射。输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于JDBC对preparedStatement对象设置参数的过程
8、输出结果映射。输出结果类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输出结果映射过程类似于JDBC对结果集的解析过程

2、JDBC使用流程

参考上面

3、Java垃圾回收器

介绍垃圾回收是什么 ->  垃圾回收器(一个专门负责垃圾回收的)—>既然是个机器,那么肯定会具有多样化,有哪些类型,以及特点->机器的性能,如何评价机器的好坏-> 如何运行的

概念:

垃圾回收(Garbage Collection, GC)是内存管理的核心组成部分,它负责回收不再使用的内存空间。在Java中,程序员不需要手动释放对象占用的内存,一旦对象不再被引用,GC就会在适当的时机回收他们所占用的内存。可以避免内存泄露和野指针。从而减轻了程序员的负担,也使得Java成为一个相对安全,易于开发的编程语言。

垃圾回收的基本步骤:

1、查找内存中不再被使用的对象(回收谁); 2、释放这些对象占用的内存(如何回收)。

垃圾回收器分类

分类详细描述理解
按照功能模式分**并发式垃圾回收器:**与应用程序线程交替工作,以尽量减少应用程序的停顿时间
**独占式垃圾回收器:**stop-the-world,一旦运行,停止应用程序,直至过程完全结束。
按照线程分**串行垃圾回收器:**同一时间段内只允许有一个CPU用于执行GC,要暂停工作内容,直至垃圾收集工作结束。
并行垃圾回收器:同一时间段内允许多个,但是也是"stop-the-world"。
这哥俩都是:清理垃圾ing,暂停营业。
按照碎片处理方式压缩式垃圾回收器:在垃圾回收之后,对存活对象进行压缩整理,消除回收的碎片
非压缩式垃圾回收器:不执上述步骤。
按照工作的内存空间可以分为年轻代垃圾回收器老年代垃圾回收器

GC的性能指标

  • 吞吐量:运行应用程序的时间占总运行时间;
  • 暂停时间:执行垃圾收集时,应用程序被暂停的时间

垃圾回收器的运行机制

1、Java对象的生命周期:

**状态:**创建、使用、不可达、回收、终结、死亡;

不可达:失去强引用的身份

回收:被GC带走了

终结:如果对象定义了finalize方法,会被在回收之前调用(这不就是保护罩吗,我还可以挣扎一下)

死亡:对象的内存被回收,对象完成其生命周期(家没了,就彻底没了)

大白话时间:
java之中被new的对象是一个强引用,是不回被垃圾回收的,因此会导致java内存泄露。
什么时候会失去强引用的身份:
1、设置为null(显示)
2、在一个方法内部有一个强引用,这个引用保存在栈中,而引用的对象保存在堆中。当这个方法运行完成后,就会退出方法栈,引用对象的引用数就是0,这个对象就可以被回收
内存泄露:已经分配的资源没有被正确地释放和回收,随着时间的推移,这些无法回收的内存资源持续积累,导致应用程序可能内存不足,甚至崩溃。
再写就多了 再去了解一下,四个引用的关系吧!

tips:不知不觉写了那么多,真复杂。

GC判断策略(回收谁)

应该就是判断一个对象是不是强引用,如果不是那就是可以回收,否则不能回收。

策略描述
引用计数算法给对象加一个计数器,增加一个引用,计数器加1,引用失效,计数器减为0的对象可被回收。(如果两人循环引用,可以非常优秀,因此java虚拟机不使用引用计数算法,很好奇如何循环引用,比如一个对象的成员或者方法引用另一个对象,同样)
可达性分析(JVM使用)我要开始贴图了(…)

可达性分析算法

思路:

将一些称为GC Roots的对象,作为根节点,向下搜索,若某对象不可达,判定是可回收对象
在这里插入图片描述

在可达性分析算法中,宣告一个对象的"死亡"至少要两次标记,因为finalize方法会暂时救它一命。(finalize翻译为最后确定,所以做重大决定之前,一定要再确定一下,否则就death了)

在这里插入图片描述

垃圾回收算法

经过上述已经确定了行动目标,那么如何消灭行动目标呢?因此如何有效回收不再使用的对象?

1、标记-清除

最基础的收集算法: Mark-Sweep算法,分为标记和清除阶段:

  • 标记:在GC Roots遍历时,标记所有可回收对象
  • 清除:遍历整个堆,清楚被标记的对象

算法缺点:

  • 效率问题:标记和清除过程效率都不高;
  • 空间问题:清除之后会产生大量不连续的碎片

在这里插入图片描述

2、复制

目的:为了解决效率问题

思路:将可用内存按容量大小划分为大小相等的两块,每次只使用其中的一块。当一块内 存使用完了,就将还存活着的对象复制到另一块上面,然后再把已使用过的内存空 间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用 考虑内存碎片等复杂情况。

缺点: 将内存缩小为了原来的一半。

tips:现代的商业虚拟机都采用这种收集算法来回收新生代,IBM公司的专门研究表明, 新生代中对象98%对象是“朝生夕死”的,所以不需要按照1:1的比例来划分内存空 间,而是将内存分为较大的Eden空间和两块较小的Survivor空间,每次使用Eden 和其中一块SurvivorHotSpot虚拟机中默认Eden和Survivor的大小比例是8: 1。

3、分代收集算法

一般是把Java堆分为新生代老年代,这样就可以根据各个年代的特点采用最适当 的收集算法。

在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法。

在老年代中,因为对象存活率高、没有额外空间对它进行分配担保,就必须采用“标 记-清除”或“标记-整理”算法来进行回收。

4、标记-整理算法

​ 复制收集算法在对象存活率较高时,就要进行较多的复制操作,效率就会变低。 根 据老年代的特点,提出了“标记-整理”算法。 标记过程仍然与”标记-清除“算法一样,但后续步骤不是直接对可回收对象进行清 理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。

在这里插入图片描述

tips: 肝不动了,大量芝士进入脑子,关于GC暂时就这样了。

参考

知乎

4、TCP和UDP的区别

两者都传输层的协议,可以从传输数据类型、是否建立连接、头部长度等区分

区别

  • TCP面向连接,UDP面向无连接
  • TCP面向字节流,UCP面向报文
  • TCP提供安全可靠的传输服务、UDP尽最大努力传输
  • TCP首部20字节,UDP首部8字节
  • TCP连接是点对点的,UDP是一对多,多对多等通信

Tips: 发现找工作的时候会写熟悉TCP/IP协议,是需要在编程中应用吗,比如Java的套接字等

5、ArrayList和LinkedList区别

自我理解:

1、应该是和数据结构中的数组和链表相类似,数组是连续的内存空间,链表不要求是连续的内存空间

2、两者都是实现了Java中的接口List

查询资料整理

  • ArrayList 底层是由数组实现的, LinkedLsit底层是由链表实现的; 所以ArrayList比LinkedList查询快
  • Java的原生数组是不支持扩容的,但ArrayList支持动态扩容 (扩容问题可以单独拿来考察)
  • ArrayList是线程不安全的

Tips: 这个问题问的很少,但是细节展开又是很多,所以可以整理一下List的实现类,然后对比分析.

6、你有使用过Kafka

如果是问我

嗯…,这是啥,不了解,不明白,不知道;不过好像是消息队列? 开始查一下资料

tips: 参考学习地址:kafka

7、主键索引和唯一索引的区别

唯一性要求:主键索引要求索引列的值在整个表中是唯一的,任何两行数据的主键值不能相同。而唯一索引也要求索引列的值是唯一的,但允许有部分行没有索引值(即允许为NULL)。

空值(NULL):主键索引不允许索引列的值为空(NULL),每一行都必须有一个主键值。而唯一索引允许索引列的值为空(NULL),允许有多行为空值。
表中数量:每个表只能有一个主键索引,用于唯一标识表中的每一行数据。而唯一索引可以有多个,可以在一个表中创建多个唯一索引。
自动增长:通常情况下,主键索引使用自动增长(AUTO_INCREMENT)来生成唯一的主键值。而唯一索引不一定需要使用自动增长。
在使用时,主键索引通常用于唯一标识表中的每一行数据,而唯一索引用于确保索引列的值是唯一的,但允许部分行为空值。你可以根据实际需求选择适当的索引类型。

表中数量:每个表只能有一个主键索引,用于唯一标识表中的每一行数据。而唯一索引可以有多个,可以在一个表中创建多个唯一索引。

**自动增长:**通常情况下,主键索引使用自动增长(AUTO_INCREMENT)来生成唯一的主键值。而唯一索引不一定需要使用自动增长。

在使用时,主键索引通常用于唯一标识表中的每一行数据,而唯一索引用于确保索引列的值是唯一的,但允许部分行为空值。你可以根据实际需求选择适当的索引类型。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值