Loading

新建文本文档1

什么是字符串常量池?
创建一个字符串时,JVM会首先去字符串常量池查找是否存在这个对象,如果存在,则不创建任何对象,,直接将这个对象的地址返回。如果不存在,就新创建一个对象,然后返回。
字符串常量池是JVM为了提升性能和减少内存消耗针对字符串专门开辟的一块区域。
为了避免字符串的重复创建

String为什么是不可变的?
String在定义时候声明final类型
String类全局变量都定义为private final类型,表明对象一旦初始化,属性值就无法改变

String对象真的不可变吗?
那么,用什么方式可以访问私有成员呢? 没错,用反射,可以反射出String对象中的value属性, 进而改变通过获得的value引用改变数组的结构

String s = new String("xyz");究竟产生了几个对象,从JVM角度谈谈?
1个或者两个
如果字符串池没有xyz字符串,会在字符串池中创建,会在堆内存创建
如果字符串有xyz字符串,则只会在堆内存中创建


String拼接字符串效率低,你知道原因吗?
比如在循环里面连接字符串,+在for循环内部,每次执行就会创建一个StringBuilder,如果不断产生会占用大量资源,应该在程序中直接使用StringBuilder来连接字符串,StringBuilder对象直接进行append的话,可以节省创建和销毁创建对象的时间。


你真的了解String的常见API吗?
获取字符串的长度 int length()
将自负串里面的小写字母变成大写 toUpperCase()
将字符串里面的大写字母变成小写字母toLowerCase()
比较两个字符串 equals
截取字符串 substring()
连接两个字符串 contat()
替换 replace()

浅析Java中的final关键字?
final用于声明类,属性,方法 ,即属性不可变,方法不可覆盖,类不可继承

浅析Java中的static关键字?
static关键字声明一个成员变量或者成员方法可以在没有所属的类的实例变量的情况下被访问。
Java中static方法不能被覆盖,方法覆盖是运行时动态绑定的,static方法是编译时静态绑定的

你对Java中的volatile关键字了解多少?
volatile是保证了可见性,有序性,没有原子性
volatile只是保持线程的可见性,被volatile修饰,也就有两层含义:1.线程内的修改操作可以立马被其他线程看到 2.禁止重排序
我们通过看被volatile修饰过后的编译源码可以看到有一个前缀指令.lock,这就是相当于一个内存屏障。
内存屏障有3个功能:1.保证内存屏障前的指令不会排到内存屏障的后面内存屏障后面的指令不会排到内存屏障的前面
2强制对缓存的修改操作立即写入主存
3.如果是写操作,会导致CPU中对应的缓存行失效


i++是线程安全的吗?如何解决线程安全性?
线程不安全,都没有原子性
对i++操作的方法加同步锁,同时只有一个线程执行i++操作


从字节码角度深度解析 i++ 和 ++i 线程安全性原理?
i++字节码: j = i++是一个先压栈,先将本地变量i压栈,然后本地变量自增1,再将栈顶元素弹出写到本地变量j内。此时j还是为0.
++i字节码: j = ++i的操作顺序是先将本地变量i自增一,然后再压栈,最后写入到j内。也就是此时j为i+1之后的内容。

请谈谈什么是CAS?
Compare and swap 比较并交换
CAS(compare and swap, 比较并交换),是原子操作的一种,可用于在多线程编程中实现不被打断的数据交换操作,从而避免多线程同时改写某一数据时由于执行顺序不确定性以及中断的不可预知性产生的数据不一致问题。
简单来说,CAS可以保证多线程对数据写操作时数据的一致性。
CAS的思想:三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。
CAS的缺点:
CASABA问题,循环时间长开销大和只能保证一个共享变量的原子操作。其中ABA问题作为第三部分重点说明下。

从源码角度看看ArrayList的实现原理?
Arraylist是基于数组存储的,数组有下标,可以通过数组的下标进行一次访问,所以查询速度快。增删效率低,因为定义数组的时候需要定义其长度,不灵活不方便数据的增,删。geter()和seter()方法快

手写LinkedList的实现,彻底搞清楚什么是链表?
LinkedList的底层是链表结构,是双向链表。可以通过链表中的一个节点,可以访问到它的前驱节点和后继节点。所以add()和remove()效率高

Java中方法参数的传递规则?
值传递,如果是基本类型传递基本类型的字面值的拷贝,会创建副本,参数如果是引用类型传递的是参数所引用的对象在堆中地址值的拷贝,也会产生副本

Java中throw和throws的区别是什么?
throw用来明确的抛出一个异常
throws用来表明可能抛出的各种异常
throw语句用在方法体内,用来明确的抛出一个异常
throws用于方法声明以后,表明可能抛出的各种异常,throws表示出现异常的一种可能性,不一定会发生这种异常。

重载和重写的区别?
重载发生在子类和子类,方法名必须相同,参数列表不同,实现了一个方法,可以实现类似的功能
重写发生在子类与父类,方法名,参数列表必须相同,子类的返回值要小于等于父类,抛出的异常范围要小于等于父类,子类的访问修饰符要大于等于父类,public,protected,default,private,父类如果是private,就不可以重写。父类和子类的方法必须一致


finally语句块你踩过哪些坑?
finally快不管有没有捕获异常或者处理异常都是会执行的,finally块里面不能有return,如果有的话就返回的是finally里面的return的值了

为什么重写equals方法需同时重写hashCode方法?
重写了equals方法必须重写hashCode方法,针对Set和Map集合:1.集合首先判断存储对象是不是唯一的
2.集合类判断两个对象是否相等,先用equals()方法判断是否相等,如果为true,还要判断HashCode返回值是否为true,如果为true,才认为两个对象相等


equals() 与 == 的区别?
相等于如果是基本类型的话比较的值,如果是引用类型,比较的是内存地址
equals()如果是Object.equals()和相等于类似,如果是String.equals()比较的值

StringBuffer和StringBuilder的区别,从源码角度分析?
都是可变字符序列,都继承AbstractStringBuilder
StringBuffer效率低,线程安全
StringBuilder效率高,线程是不安全的
看过StringBuffer源码可以看到,几乎所有的方法都加了synchronized,synchronized是用来加锁的,所以线城是安全的
我们通过StringBuilder源码看到,基本上方法都没有用synchronized关键字修饰,当多线程访问时候,就会出现线程安全性问题。


你知道HashMap的数据结构吗?
HashMap在jdk1.7底层是数组,链表,在jdk1.8是数组,链表,红黑树


为何HashMap的数组长度一定是2的次幂?

HashMap何时扩容以及它的扩容机制?
HashMap是基于Hashing原理的,是通过Put()方法和get()方法来存储和获取元素的,
HashMap只要不进行Put方法存储元素之前,HashMap就不会扩容。当用put方法传递键和值时候,我们先对对象调用Hashcode()方法计算并返回Hashcode,随后计算并返回的hashcode适用于找到Map数组的bucket位置来存储对象,如果bucket满了,就要进行扩容
调用resize方法进行扩容,默认的负载因子为0.75,当一个map填满了75%的bucket时候,就会扩容,扩容后table大小变味了原来的两倍

HashMap的key一般用字符串,能用其他对象吗?
一般用Integer,String这种不可变类当HashMap当key

HashMap的key和value都能为null么?如果key能为null,那么它是怎么样查找值的?
HashMap的key和value都能为null

HashMap是线程安全的吗?如何实现线程安全?
线程不安全,使用Collections的synchronizedMap方法包装一下
使用ConcurrentHashmap,使用分段锁来保证线程安全

从源码角度分析HashSet实现原理?
Hashset是基于HashMap实现的,有放入HashSet中的集合元素实际上由HashMap的key来保存,而HashMap的value则存储了一个PRESENT,它是一个静态的Object对象。
如果向HashSet中添加一个已经存在的元素,新添加的集合元素不会覆盖原来已经有的集合元素

HashTable与HashMap的实现原理有什么不同?
HashMap基于Hashing原理,是通过put方法和get方法来进行存储和获取元素的,使用put来传递键和值的时候,会先用hashcode方法,计算并返回的hashcode用于找到Map中的bucket位置来存储对象
HashMap线程不安全,底层在jdk1.7是数组,链表,在jdk1.8是数组,链表,红黑树
HashTable底层是数组,链表,是线程安全的


String方法intern() 你真的会用吗?
intern()方法设计的初衷,就是重用String对象,节省内存消耗,这个方法返回的是 返回字符串对象的规范化表示形式,当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用

什么是自动拆装箱?
将基本类型用包装器类型包装起来
将包装器类型转换为基本类型

String.valueOf和Integer.toString的区别?
相同点:都可以用于把int转换成String
不同点:String.valueOf可以应用到任何数据类型,且不会有异常报出
Integer.toString先将int转换为Interger型,然后再将Integer转换成String型

三、Java多线程

线程的生命周期包括哪几个阶段?
创建,就绪,运行,阻塞,死亡
首先是创建,这个时候线程还没有调用start方法,调用了start方法,线程进入就绪状态,还没有获取到CPU的执行指令,获取到了CPU的执行指令也就开始运行了,如果因为一些原因,丢失了CPU执行指令,也就进入了阻塞状态,这个时候必须回到就绪状态,等到重新获得CPU的执行指令,
最后状态是死亡状态,线程执行完了,线程结束生命周期

多线程有几种实现方式?
继承Thread类,重写Thread的run方法,只可以单继承
实现Runnable接口的run方法,并且将Runnable实例传给Thread类,再让Thread类去执行run方法。

 

请谈谈什么是进程,什么是线程?
进程也就是一个程序从创建,运行,消亡的过程
一个进程可以有多个线程,每个线程都有自己的程序计数器,本地方法栈,虚拟机栈

启动线程是用start()方法还是run()方法?
用start()方法,开启Start()方法就会自动启动run()方法,这才是多线程。调用run()方法启动的是main底下的run方法,就不是多线程了。

说说线程安全问题,什么实现线程安全,如何实现线程安全?
线程安全就是,我们在写的某的某个代码块,比如i++,i初始值为0,第一个线程结果是1,第二个线程为2,这个线程就是安全的,如果线程不安全,那么第一个线程结果是1,第二个线程的结果是1。也就是多个线程执行能够正常执行,不会混乱。
可以用synchronized和lock来解决线程安全问题,

sychronized和Lock的区别?
sychronized是原子性内置锁,是一个关键字,lock是一个接口
自动释放锁,需要手动释放锁,否则就会造成死锁
无法判断获取锁的状态,而lock锁可以判断是否获取到了锁
lock可以中断等待锁的线程的状态,sychronized里等待的线程会一直等待下去,不能够相应中断
sychronized适合锁少量的同步代码,lock适合锁大量的同步代码

sleep()和wait()的区别?
两者都可以暂停线程的执行,sleep()方法属于Thread类中的,wait()方法属于Object()类
sleep通常用于暂停执行,wait通常用于线程间交互/通信
调用sleep(),线程不会释放锁,调用wait(),线程会放弃锁

深入分析ThreadLocal的实现原理?

 

谈谈对synchronized的偏向锁、轻量级锁、重量级锁的理解?
这是锁的优化,锁的状态是由低到高为无锁,偏向锁,轻量级锁,重量级锁。 无锁就是没有锁,偏向锁就是通过对象头的偏向线程ID来对比,轻量级锁就是通过CAS修改对象头锁和自旋来实现的,重量级锁则是除了拥有锁拥有的线程,其他全部都塞。

通过三种方式实现生产者消费者模式?
通过一个容器来解决生产者和消费者的强耦合关系,生产者生成数据无需等待消费者索取,消费者无需直接索要数据,通过容器来进行操作。
使用synchronize以及wait()、notify()
可以自定义一个阻塞队列,当队列免了的时候,通过wait(),使生产者线程阻塞,并释放队列对象的锁,然后调用notify()方法可以唤醒消费者线程
使用lock和Condition的await()和signal()方法

JVM层面分析sychronized如何保证线程安全的?
sychronized是原子性内置锁,也被称为监视器锁,我们通过观察被sychronized修饰的编译过后的同步代码块发现,有monitor和monitertesxt字节码指令,执行monitor指令会获取锁,如果获取到了锁,其他竞争锁的线程会进入等待序列,执行了monitortext在字节码指令,锁会释放,处于等待队列中的线程在继续竞争锁

如何写一个线程安全的单例?
饿汉式单例模式,在第一次加载时就实例化
懒汉式单例模式,在第一次被引用时开始实例化
饿汉式比较好

ThreadLocal什么时候会出现OOM的情况?为什么?
1.ThreadLocal是什么?
每个线程在对内存中开辟的一块工作内存,同时把线程的共享数据拷贝了一份放进去,相当于做的本地副本,不会像synchronized一样每次修改都要同步到主内存中
2.ThreadLocal有什么用?
工作线程的数据交互主要是本地数据和主内存数据的交互,当数据存储在本地内存中,可以大大提高读取效率,避免了线程阻塞造成的cpu的吞吐下降;
在多线程中每个线程中都要维护sesion,可以提高对独有资源的工作效率;
3.发生内存泄露原因?
synchornized是保证了主内存数据的一致,是时间换空间:通过阻塞一个共享变量,共享一小块内存空间;
threadLocal是通过建立线程的副本数据,空间换时间
ThreadLocalMap的Key为弱引用,当threadlocal对象被回收(value在ThreadLocalMap调用get、set、remove的时候就会被清除),这时将key设置为null的entry。但是threadlocal一直不会被回收,导致内存的泄露
4.如何避免呢?
其实在调用threalocalMap的get/set方法时,会对key=null的entry(threadlocal对象=null)进行回收,也可以在调用结束时调用remove方法进行释放。


为什么wait, notify 和 notifyAll这些方法不在thread类里面?
Wait-notify机制是在获取对象锁的前提下不同线程间的通信机制。在Java中,任意对象都可以当作锁来使用,由于锁对象的任意性,所以这些通信方法需要被定义在Object类里。

你真的理解CountDownLatch与CyclicBarrier使用场景吗?
CountDownLatch是一个同步的辅助类,允许一个或多个线程,等待其他一组线程完成操作,再继续执行。
CyclicBarrier是一个同步的辅助类,允许一组线程相互之间等待,达到一个共同点,再继续执行。

出现死锁,如何排查定位问题?
1.在cmd窗口,使用jps指令查询该类的端口号(pid)
2.在使用jstack+pid查看日志(jstack pid)

notify和notifyAll的区别?
调用notify()方法只随机唤醒一个wait线程,这个线程会从等待池进入锁池,调用notifyAll方法会唤醒所有wait线程,而且会将该对象等待池内的所偶线程移动到锁池种,等待锁竞争。

线程池启动线程submit和execute有什么不同?
execute只能执行Runnable类型的任务,没有返回值
submit可以执行Runnable和Callable类型的任务
submit能获取返回值,并且处理异常,通过捕获Future.get()抛出的异常

SimpleDateFormat是线程安全的吗?如何解决?
SinmpleDateFormat是java提供的一个格式化和解析日期的工具类,在java中,可以使用SimpleDateFormat的format方法,将一个Date类型转化成String类型,并且可以指定输出格式。
线程不安全,被当作了共享变量在多个线程中进行使用,这就出现了线程安全问题。
解决:使用局部变量,就不会被多个线程同时访问到了,避免了线程安全问题
加同步锁,通过加锁使多个线程排队顺序执行
如果是Java8,使用DateTimeFormatter代替SimpleDateFormat

请谈谈ConcurrentHashmap底层实现原理?
ConcurrentHashMap在jdk1.7是分段的数组,链表,在jdk1.8以后是node数组,链表,红黑树。线程是安全的,那怎样实现线程安全的呢?在jdk1.7是分段锁对整个桶数组进行了分割,多线程访问容器里面不同数据段的数据,就不会存在锁竞争,提高了并发访问率。

当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其方法?
不可以

线程池的原理,为什么要创建线程池?创建线程池的方式?
原理:我们在代码中模拟了10个任务,我们配置的核心线程数是5,等待队列容量为100,所以每次只能存在5个任务同时执行,
剩下的5个任务会被放到等待队列中,当前的5个任务中如果有任务被执行完了,线程池就会去拿新的任务执行。
池化的思想主要为了减少每次获取资源的消耗,提高对资源的利用率,线程池的好处有降低资源的消耗,提高线程的可管理性。
通过构造方法实现,通过Executor框架的工具类Executors来实现。

创建线程池有哪几个核心参数?
最大线程数:maxPoolSize
核心线程数:corePoolSize
任务队列容量:queueCapacity
线程空闲时间:keepAliveTime
允许核心线程超时 allowCoreThreadTimeout
任务拒绝处理器 rejectedExecutionHandler

synchronized修饰的静态方法和非静态方法有什么区别?
修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
修饰非静态方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁

四、Java Web
什么是Servlet,Servlet生命周期方法?
Servlet就是一个接口,主要负责接收浏览器的请求,tomcat服务器调用servlet方法。
init()方法 初始化
service()方法 运行
destory()方法 销毁

什么Session和Cookie,它们之间有什么联系?
Session是一个会话,当用户打开浏览器访问一个网站开始,无论在这个网站访问了多少页面,点了多少链接,都属于同一个会话。直到浏览器关闭,都属于同一个会话。
Cookie是一种浏览器和服务器交互数据的方式。
之间的联系:因为Http协议是无状态的,即每次访问都是相当于一个新的请求,Session和Cookie就解决了这个问题,当客户端向服务端发送了一个请求,服务端收到这个请求就会创建一个Session,随之也会创建一个SeesionID,
服务端同时也会创建一个Cookie包含这个SessionID,进行响应给客户端,客户端收到了这个响应,就会设置Cookie信息。接下来客户端每次向同一个网站发送请求时,包含SessionId的cookie信息都会被服务器读取到。

JSP的八个隐含对象有哪些?
Request,Response,out 即请求,响应,输出
pageContext表示当前页面作用域
session 代表当前会话作用域
application 代表当前全局作用域
config config可以获取一些在web.xml中初始化的参数
page:表示当前对象
exception:表示异常对象

JSP的四个域对象的作用范围?
pagecontext:表示当前页面作用域,有效范围在当前jsp页面里
session:表示当前会话作用域,有效作用域就是当前会话
application:代表全局作用域,有效范围时应用启动到应用结束
request:有效范围就是当前请求周期,从http请求发起,到服务器处理结束,返回响应的整个过程

Post和Get请求的区别?
本质都是TCP链接
Post比Get安全,例如用户登陆时,如果是Get调用会把账号密码都显示在URL中,而Post调用不会显示
Post请求的时候调用的是Service方法后的doPost()方法,Get请求的时候调用的时Service方法后的doGet()方法

转发和重定向有什么区别?
请求转发Url的地址不会发生改变,是服务端行为。转发后的页面可以读取上一个页面放在request中的数据。转发请求一次
重定向Url的地址会发生改变,是客户端行为。重定向相当于直接在浏览器打开重定向的地址,跟上一个页面没任何关系。重定向至少请求2次

Http1.0和Http1.1的区别是什么?
Http1.0默认使用的是短连接,每次请求都要重新建立一次连接。Http1.1默认使用长连接,持续连接有非流水线方式和流水线方式
流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文,非流水线方式是客户在收到一个响应报文以后才能发送下一个请求
Http1.1新增了一些错误状态响应码,410表示某个资源被永久性的删除
Http1.1提供了更多的缓存控制策略

拦截器与过滤器的区别?
1.过滤器依赖servlet容器,拦截器不依赖servlet容器
2.过滤器是基于函数回调,拦截器是基于java的反射机制
3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4.在action的生命周期里,拦截器可以被多次调用,而Filter只能在容器初始化时调用一次。

五、JVM面试题

JVM内存区域如何划分?
基于jdk1.7,线程共享的有程序计数器,虚拟机栈,本地方法栈
线程私有的有:堆,方法区
直接内存
jdk1.8, 线程共享的有:程序计数器,虚拟机栈,本地方法栈
线程私有的:堆
直接内存,元空间


JVM堆中对象是如何创建的?
1.类加载检查:若对象对应的类已经经过加载,链接,初始化,则进入下一步。
2.分配内存
3.初始化
4.设置对象头
5.执行init方法

JVM对象的结构?
对象头,实例数据,对齐填充

JVM垃圾回收-如何判断对象是否是垃圾对象?
1.可达性分析算法,对象到GC root 没有引用链相连,说明是可以回收的
2.引用计数法算法,给对象添加一个引用计数器,每当有一个地方引用对象时,计数器加1,当引用失效的时候,引用计数器的值减1,当引用计数器为0,就可以回收

JVM垃圾回收算法有哪些?
标记-清除算法
标记-复制算法
标记-整理算法
分代收集算法
JVM类的加载器有哪些?
启动类加载器,扩展类加载器,应用程序类加载器

JVM垃圾收集器有哪些?
新生代有Serial,ParNew,Paraller
老年代有Serial Old,Paraller Old,
G1,CMS

JVM内存是如何分配的?
计算对象占用的空间大小,在堆中划分内存
1.若堆内存规整(使用标记整理算法进行GC),采用指针碰撞法
2.若堆内存不规整(使用标记清楚算法进行GC会残留下空间碎片),采用空闲列表

从一道面试题分析类的加载过程?
加载,链接(验证,准备,解析),初始化,使用,卸载

JVM双亲委派机制?
1.如果一个类加载器收到了类加载器请求,他并不贵在即先去加载,而是把这个请求委托给父类的加载器去执行;
2.如果父类加载器还存在父类加载器,则进一步向上委托,依次递归,请求最终到达顶层的启动类加载器;
3.如果父类加载器可以完成类加载任务,就成功返回,若父类加载器无法完成此加载任务,子加载器才尝试自己去加载。

JVM可以作为GC Root的对象有哪些?
1.本地方法栈native方法引用的对象
2.栈中引用的对象
3.静态变量,常量引用的对象

哪些情况会导致Full GC?
老生代无法分配空间,触发FGC
System.gc

六、SQL性能优化

数据库三范式是什么?
数据库的事务、ACID及隔离级别?
不考虑事务的隔离性,容易产生哪三种情况?
数据库连接池原理?
什么是B-Tree?
什么是B+Tree?
MySQL数据库索引结构?
什么是索引?什么条件适合建立索引?什么条件不适合建立索引?
索引失效的原因有哪些?如何优化避免索引失效?
MySQL如何启动慢查询日志?
MySQL如何使用show Profile进行SQL分析?
一条执行慢的SQL如何进行优化,如何通过Explain+SQL分析性能?
什么是行锁、表锁、读锁、写锁,说说它们各自的特性?
什么情况下行锁变表锁?
什么情况下会出现间隙锁?
谈谈你对MySQL的in和exists用法的理解?
MySQL的数据库引擎有哪些,如何确定在项目中要是用的存储引擎?
count(*)、count(列名)和count(1)的区别?
union和union all的区别?
七、Spring框架

Spring的IOC和AOP机制?
Spring中Autowired和Resource关键字的区别?
依赖注入的方式有几种,各是什么?
Spring容器对Bean组件是如何管理的?
Spring容器如何创建?
Spring事务分类?
Spring事务的传播特性?
Spring事务的隔离级别?
Spring的通知类型有哪些?
八、SpringMVC框架

SpringMVC完整工作流程,熟读源码流程?
SpringMVC如何处理JSON数据?
SpringMVC拦截器原理,如何自定义拦截器?
SpringMVC如何将请求映射定位到方法上面?结合源码阐述?
SpringMVC常见注解有哪些?
SpringMVC容器和Spring容器的区别?
SpringMVC的控制器是不是单例模式,如果是,有什么问题,怎么解决?
九、MyBatis框架

MyBatis中#和$的区别?
#{}是占位符,预编译处理,${}是拼接符,是用来替换字符串的
Mybatis在处理#{}的时候,会在预编译的时候把#{}换成?,调用PreparedStatement的set方法来赋值
Mybatis在处理${}的时候,会把${}直接替换成变量的值

MyBatis一级缓存原理以及失效情况?
缓存就是将用户经常查询到的数据放在缓存中,这样的话,下次用户再次去查询数据就不会去从磁盘上查询,从缓存中查询,提高了查询效率,解决了高并发系统的性能问题
一级缓存也叫本地缓存:一级缓存是默认打开的,每个SqlSession实例都拥有一个自己的本地缓存,如果创建一个新的SqlSession实例,则该实例拥有一个新的一级缓存。
失效情况:1.SqlSeesion不同
2.SqlSession相同,但查询条件不同
3.SqlSession对象相同,查询条件也相同,但两次查询之间执行了增删改操作
4.使用了ClearCache()方法

MyBatis二级缓存的使用?
工作机制:一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中,如果当前会话关闭了,这个会话对应的一级缓存就没了。但是我们想要的是,会话关闭了,一级缓存中的
数据就会放在二级缓存中,新的会话查询信息,就会在二级缓冲中获取内容。作用域在Namespace
使用步骤:1.让Mybatis框架支持二级缓存
2.让当前的映射文件支持二级缓存
3.让当前的操作支持二级缓存

MyBatis拦截器原理?
Mybatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能。Mybatis允许你在已映射语句执行过程中的某一点进行拦截调用,Mybatis允许使用插件来拦截的方法调用包括:Executor,ParameterHandler,ResultSetHandler,StatementHandler
比如在使用分页插件来完成Mybatis分页
分页插件的原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,然后在sql语句添加对应的物理分页语句和物理分页参数。

看过MyBatis源码吗,请说说它的工作流程?
1.加载配置文件
2.生成SqlSessionFactory工厂
3.使用SqlSessionFactory工厂创建SqlSession对象
4.使用SqlSession创建Dao接口的代理对象
5.使用代理对象执行方法
6.关闭SqlSession,释放资源

十、Java高级部分

Dubbo负载均衡策略?
Dubbo中Zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么?
Dubbo完整的一次调用链路介绍?
请说说SpringBoot自动装配原理?
有用过SpringCloud吗,请说说SpringCloud和Dubbo有什么不一样?
什么是WebService,如何基于WebService开发接口?
谈谈项目中分布式事务应用场景?
使用Redis如何实现分布式锁?
请谈谈单点登录原理?
Tomcat如何优化?
后台系统怎么防止请求重复提交?
Linux常见命令有哪些?
请说说什么是Maven的依赖、继承以及聚合?
Git暂存区和工作区的区别?
Git如何创建、回退以及撤销版本?

posted @ 2022-03-27 17:12  远乡人  阅读(48)  评论(0编辑  收藏  举报