本文是衔接上文(史上最全的Java面试题总汇,不再惧怕面试官,成功坐等offer)的带答案版本,答案已经整理完毕。希望大家采纳。
本文内容偏多,建议收藏阅读。 小编整理不易,给个关注吧~
四、反射
57.什么是反射?
Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。)语言的一个关键性质。
58.什么是 java 序列化?什么情况下需要序列化?
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
当 Java 对象需要在网络上传输 或者 持久化存储到文件中时,就需要对 Java 对象进行序列化处理。
59.动态代理是什么?有哪些应用?
动态代理:当想要给实现了某个接口的类中的方法,加一些额外的处理。比如说加日志,加事务等。可以给这个类创建一个代理,故名思议就是创建一个新的类,这个类不仅包含原来类方法的功能,而且还在原来的基础上添加了额外处理的新类。这个代理类并不是定义好的,是动态生成的。具有解耦意义,灵活,扩展性强。
动态代理的应用:Spring的AOP,加事务,加权限,加日志。
60.怎么实现动态代理?
动态代理实现:首先必须定义一个接口,还要有一个InvocationHandler(将实现接口的类的对象传递给它)处理类。再有一个工具类Proxy(习惯性将其称为代理类,因为调用他的newInstance()可以产生代理对象,其实他只是一个产生代理对象的工具类)。利用到InvocationHandler,拼接代理类源码,将其编译生成代理类的二进制码,利用加载器加载,并将其实例化产生代理对象,最后返回。
五、对象拷贝
61.为什么要使用克隆?
想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要克隆了。克隆分浅克隆和深克隆,浅克隆后的对象中非基本对象和原对象指向同一块内存,因此对这些非基本对象的修改会同时更改克隆前后的对象。深克隆可以实现完全的克隆,可以用反射的方式或序列化的方式实现。
62.如何实现对象克隆?
有两种方式: 1). 实现Cloneable接口并重写Object类中的clone()方法;
2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,。
63.深拷贝和浅拷贝区别是什么?
在有指针成员的情况下,浅拷贝只是将指针指向已存在的内存。即两个对象的指针成员指向的是同一内存区域。深拷贝的做法是申请一个内存复制一份,并将新对象指针指向备份区。
安全性:浅拷贝如果修改了指针指向的内容,将对两个对象都有影响。
六、Java Web
64.jsp 和 servlet 有什么区别?
jsp 是 html 页面中内嵌的 Java 代码,侧重页面显示;
Servlet 是 html 代码和 Java 代码分离,侧重逻辑控制,mvc 设计思想中 jsp 位于视图层,servlet 位于控制层Jsp 运行机制.
65.jsp 有哪些内置对象?作用分别是什么?
Page,pageContext,request,response,session,application,out,config,exception
Page指的是JSP被翻译成Servlet的对象的引用.
pageContext对象可以用来获得其他8个内置对象,还可以作为JSP的域范围对象使用.pageContext中存的值是当前的页面的作用范围》
request代表的是请求对象,可以用于获得客户机的信息,也可以作为域对象来使用,使用request保存的数据在一次请求范围内有效。
Session代表的是一次会话,可以用于保存用户的私有的信息,也可以作为域对象使用,使用session保存的数据在一次会话范围有效
Application:代表整个应用范围,使用这个对象保存的数据在整个web应用中都有效。
Response是响应对象,代表的是从服务器向浏览器响应数据.
Out:JSPWriter是用于向页面输出内容的对象
Config:指的是ServletConfig用于JSP翻译成Servlet后 获得Servlet的配置的对象.
Exception:在页面中设置isErrorPage=”true”,即可使用,是Throwable的引用.用来获得页面的错误信息。
66.说一下 jsp 的 4 种作用域?
67.session 和 cookie 有什么区别?
1. Cookie以文本文件格式存储在浏览器中,而session存储在服务端它存储了限制数据量。它只允许4kb它没有在cookie中保存多个变量。
2.cookie的存储限制了数据量,只允许4KB,而session是无限量的
3.我们可以轻松访问cookie值但是我们无法轻松访问会话值,因此它更安全
4.设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
68.说一下 session 的工作原理?
整个流程大概分成这样的几步: 第一步将本地的cookie中的session标识和用户名,密码带到后台中
第二步后台检测有没有对应的session标识,我们以php为例,那么就是检测有没有接收到对应的PHPSESSID
没有的话直接生成一个新的session。
有的话,检测对应的文件是否存在并且有效 失效的话,我们需要清除session然后生成新的session。不失效,使用当前的session
69.如果客户端禁止 cookie 能实现 session 还能用吗?
设置php.ini配置文件中的“session.use_trans_sid = 1”,或者编译时打开打开了“--enable-trans-sid”选项,让PHP自动跨页传递Session ID。
手动通过URL传值、隐藏表单传递Session ID。
用文件、数据库等形式保存Session ID,在跨页过程中手动调用。
70.spring mvc 和 struts 2的区别是什么?
1. 底层实现机制 struts2:filter springmvc:servlet
2. 运行效率 struts2:底层是Servlet,参数基于属性封装,如果配置单例,会出现线程安全问题,所以配置多例 springmvc:底层是Servlet,单例
3. 参数封装 struts2:基于属性封装 springmvc:基于方法进行封装
71.如何避免 sql 注入?
不要使用动态SQL
不要将敏感数据保留在纯文本中
限制数据库权限和特权
避免直接向用户显示数据库错误
对访问数据库的Web应用程序使用Web应用程序防火墙(WAF)
定期测试与数据库交互的Web应用程序
将数据库更新为最新的可用修补程序
72.什么是 XSS 攻击,如何避免?
XSS攻击又称CSS,全称Cross Site Script (跨站脚本攻击),其原理是攻击者向有XSS漏洞的网站中输入恶意的 HTML 代码,当用户浏览该网站时,这段 HTML 代码会自动执行,从而达到攻击的目的。XSS 攻击类似于 SQL 注入攻击,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制,获取用户的一些信息。 XSS是 Web 程序中常见的漏洞,XSS 属于被动式且用于客户端的攻击方式。
1.利用 php htmlentities()函数对传入参数的非法的 HTML 代码包括单双引号等进行转义。但是,中文情况下, htmlentities() 却会转化所有的 html 代码,连同里面的它无法识别的中文字符也给转化了。
2.利用 php htmlspecialchars()函数对传入参数的非法的 HTML 代码包括单双引号等进行转义,需要注意的是第二个参数默认是 ENT_COMPAT,函数默认只是转化双引号("),不对单引号(')做转义。更多的时候要加上第二个参数,应该这样用 : htmlspecialchars($string,ENT_QUOTES)对单双引号都进行转义。如果需要不转化任何的引号第二个参数使用ENT_NOQUOTES。
3.通过正则表达式过滤传入参数的html标签来防范XSS攻击
73.什么是 CSRF 攻击,如何避免?
CSRF(Cross-site request forgery)也被称为 one-click attack或者 session riding,中文全称是叫跨站请求伪造。一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗取账号、转账、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为。
1.验证 HTTP Referer 字段
2.使用验证码
3.在请求地址中添加token并验证
4.在HTTP 头中自定义属性并验证
5.AngularJS提供的CSRF方案
七、异常
74.throw 和 throws 的区别?
throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理。而throw则是指抛出的一个具体的异常类型。
75.final、finally、finalize 有什么区别?
final是关键字,当final用于修饰类时,这个类不可以被继承,所以自然也就不能是抽象类(abstract);当final修饰方法时,这个方法不能够被重写;当final修饰变量时,这个变量不能被修改。
finally是异常处理的出口,在异常处理流程中,如果有了finally代码块,则程序不管是否被捕捉到异常或者异常是否被处理,都要执行finally代码块中的程序。
finalize是方法名称,是Object中的方法,这个方法在对象被垃圾回收集收集之前进行调用,可以在此进行一些扩展,如果调用这个方法时,抛出了无法补货的异常,GC将终止对这个对象的回收,等到下次GC时再进行回收。
76.try-catch-finally 中哪个部分可以省略?
catch 和 finally 语句块可以省略其中一个。
77.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
一定会, catch 中 return会等finally中的代码执行完之后才会执行。
78.常见的异常类有哪些?
NullPointerException 空指针异常
ClassNotFoundException 指定类不存在
NumberFormatException 字符串转换为数字异常
IndexOutOfBoundsException 数组下标越界异常
ClassCastException 数据类型转换异常
FileNotFoundException 文件未找到异常
NoSuchMethodException 方法不存在异常
IOException IO 异常
SocketException Socket 异常
八、网络
79.http 响应码 301 和 302 代表的是什么?有什么区别?
301表示网页永久性转移到另一个地址 302表示临时性转移
区别: 301是永久的重定向,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址 302重定向是临时的重定向,搜索引擎抓取新的内容而保留旧的网址
80.forward 和 redirect 的区别?
forward 是服务器的内部重定向
redirect 是服务器收到请求后发送一个状态头给客户,客户将在重新请求一次
81.简述 tcp 和 udp的区别?
tcp 面向连接,udp 面向非连接即发送数据前不需要建立链接;
tcp 提供可靠的服务(数据传输),udp 无法保证;
tcp 面向字节流,udp 面向报文; tcp 数据传输慢,udp 数据传输快
82.tcp 为什么要三次握手,两次不行吗?为什么?
如果采用两次握手,那么只要服务器发出确认数据包就会建立连接,但由于客户端此时并未响应服务器端的请求,那此时服务器端就会一直在等待客户端,这样服务器端就白白浪费了一定的资源。若采用三次握手,服务器端没有收到来自客户端的再此确认,则就会知道客户端并没有要求建立请求,就不会浪费服务器的资源
83.说一下 tcp 粘包是怎么产生的?
tcp 粘包可能发生在发送端或者接收端,分别来看两端各种产生粘包的原因:
发送端粘包:发送端需要等缓冲区满才发送出去,造成粘包;
接收方粘包:接收方不及时接收缓
84.OSI 的七层模型都有哪些?
物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
数据链路层:负责建立和管理节点间的链路。
网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。
传输层:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。
会话层:向两个实体的表示层提供建立和使用连接的方法。
表示层:处理用户信息的表示问题,如编码、数据格式转换和加密解密等。
应用层:直接向用户提供服务,完成用户希望在网络上完成的各种工作。
85.get 和 post 请求有哪些区别?
get请求的参数在URL中,而post 请求在请求body中
get请求传参有长度限制,post请求没有长度限制
get请求的参数只能是ASCII码,post请求传参没有这个限制冲区的包,造成多个包接收。
86.如何实现跨域?
使用CORS技术
使用JSONP
87.说一下 JSONP 实现原理?
jsonp是一种轻量级的数据交换格式。
jsonp:JSON with Padding,它是利用script标签的 src 连接可以访问不同源的特性,加载远程返回的“JS 函数”来执行的。
九、设计模式
88.说一下你熟悉的设计模式?
单例模式:保证被创建一次,节省系统开销。
工厂模式(简单工厂、抽象工厂):解耦代码。
观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
外观模式:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。
模版方法模式:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。
状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
89.简单工厂和抽象工厂有什么区别?
简单工厂:用来生产同一等级结构中的任意产品,对于增加新的产品,无能为力。
工厂方法:用来生产同一等级结构中的固定产品,支持增加任意产品。
抽象工厂:用来生产不同产品族的全部产品,对于增加新的产品,无能为力;支持增加产品族
十、Spring/Spring MVC
90.为什么要使用 spring?
spring是一个开源框架,是个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架
方便结构简化开发
AOP编码的支持
声明式事物的支持
方便程序的测试
方便集成各种优势框架
降低Java EE API 的使用难度
91.解释一下什么是 aop?
AOP即面向切面编程,是OOP编程的有效补充。使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。
AOP分为静态AOP和动态AOP:
静态AOP是指AspectJ实现的AOP,他是将切面代码直接编译到Java类文件中。
动态AOP是指将切面代码进行动态织入实现的AOP,JDK动态代理。
92.解释一下什么是 ioc?
即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
93.spring 有哪些主要模块?
spring core:框架的最基础部分,提供 ioc 和依赖注入特性。
spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框架式的对象访问方法。
spring dao:Data Access Object 提供了JDBC的抽象层。
spring aop:提供了面向切面的编程实现,让你可以自定义拦截器、切点等。
spring Web:提供了针对 Web 开发的集成特性,例如文件上传,利用 servlet listeners 进行 ioc 容器初始化和针对 Web 的 ApplicationContext。
spring Web mvc:spring 中的 mvc 封装包提供了 Web 应用的 Model-View-Controller(MVC)的实现。
94.spring 常用的注入方式有哪些?
构造方法注入
setter注入
基于注解注入
95.spring 中的 bean 是线程安全的吗?
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。 实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。
有状态就是有数据存储功能。
无状态就是不会保存数据。
96.spring 支持几种 bean 的作用域?
singleton、prototype、request、session、globalSession五中作用域。
singleton:spring ioc 容器中只存在一个 bean 实例,bean 以单例模式存在,是系统默认值;
prototype:每次从容器调用 bean 时都会创建一个新的示例,既每次 getBean()相当于执行 new Bean()操作;
Web 环境下的作用域: request:每次 http 请求都会创建一个 bean;
session:同一个 http session 共享一个 bean 实例;
global-session:用于 portlet 容器,因为每个 portlet 有单独的 session,globalsession 提供一个全局性的 http session
97.spring 自动装配 bean 有哪些方式?
byName:按照bean的属性名称来匹配要装配的bean
byType:按照bean的类型来匹配要装配的bean
constructor:按照bean的构造器入参的类型来进行匹配
autodetect(自动检测):先使用constructor进行装配,如果不成功就使用byType来装配
98.spring 事务实现方式有哪些?
声明式事务:声明式事务也有两种实现方式,基于 xml 配置文件的方式和注解方式。
编码方式:提供编码的形式管理和维护事务。
99.说一下 spring 的事务隔离?
spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:
ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
ISOLATIONREADUNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);
ISOLATIONREADCOMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别;
ISOLATIONREPEATABLEREAD:可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别; ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
不可重复读 :是指在一个事务内,多次读同一数据。
幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了
100.说一下 spring mvc 运行流程?
spring mvc 先将请求发送给 DispatcherServlet。
DispatcherServlet 查询一个或多个 HandlerMapping,找到处理请求的 Controller。
DispatcherServlet 再把请求提交到对应的 Controller。
Controller 进行业务逻辑处理后,会返回一个ModelAndView。
Dispathcher 查询一个或多个 ViewResolver 视图解析器,找到 ModelAndView 对象指定的视图对象。 视图对象负责渲染返回给客户端
101.spring mvc 有哪些组件?
前置控制器 DispatcherServlet
映射控制器 HandlerMapping
处理器 Controller
模型和视图 ModelAndView
视图解析器 ViewResolver
102.@RequestMapping 的作用是什么?
将 http 请求映射到相应的类/方法上
103.@Autowired 的作用是什么?
可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,通过@Autowired 的使用来消除 set/get 方法
十一、Spring Boot/Spring Cloud
104.什么是 spring boot?
Spring Boot是一个构建在Spring框架顶部的项目。它提供了一种更简单、更快捷的方法来设置、配置和运行简单和基于Web的应用程序。
105.为什么要用 spring boot?
配置简单,独立运行,自动装配,无代码生成和 xml 配置,提供应用监控,易上手,提升开发效率。
106.spring boot 核心配置文件是什么?
bootstrap (. yml 或者 . properties):boostrap 由父 ApplicationContext 加载的,比 applicaton 优先加载,且 boostrap 里面的属性不能被覆盖 application (. yml 或者 . properties):用于 spring boot 项目的自动化配置
107.spring boot 配置文件有哪几种类型?它们有什么区别?
配置文件有 . properties 格式和 . yml 格式,它们主要的区别是书法风格不同。
. properties 配置如下:
spring. RabbitMQ. port=5672
. yml 配置如下:
spring:
RabbitMQ:
port: 5672
. yml 格式不支持 @PropertySource 注解导入
108.spring boot 有哪些方式可以实现热部署?
使用 devtools 启动热部署,添加 devtools 库,在配置文件中把 spring. devtools. restart. enabled 设置为 true
使用 Intellij Idea 编辑器,勾上自动编译或手动重新编译
109.jpa 和 hibernate 有什么区别?
jpa 全称 Java Persistence API,是 Java 持久化接口规范,hibernate 属于 jpa 的具体实现。
110.什么是 spring cloud?
spring cloud 是一系列框架的有序集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 spring boot 的开发风格做到一键启动和部署。
111.spring cloud 断路器的作用是什么?
在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
112.spring cloud 的核心组件有哪些?
Eureka:服务注册于发现
Feign:基于动态代理机制,根据注解和选择的机器,拼接请求 url 地址,发起请求
Ribbon:实现负载均衡,从一个服务的多台机器中选择一台
Hystrix:提供线程池,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题
Zuul:网关管理,由 Zuul 网关转发请求给对应的服务
十二、Hibernate
113.为什么要使用 hibernate?
hibernate 是对 jdbc 的封装,大大简化了数据访问层的繁琐的重复性代码。
hibernate 是一个优秀的 ORM 实现,很多程度上简化了 DAO 层的编码功能。
可以很方便的进行数据库的移植工作。 提供了缓存机制,是程序执行更改的高效。
114.什么是 ORM 框架?
ORM(Object Relation Mapping)对象关系映射,是把数据库中的关系数据映射成为程序中的对象。
使用 ORM 的优点:提高了开发效率降低了开发成本、开发更简单更对象化、可移植更强。
115.hibernate 中如何在控制台查看打印的 sql 语句?
在 Config 里面把 hibernate. show_SQL 设置为 true 就可以。但不建议开启,开启之后会降低程序的运行效率。 116.hibernate 有几种查询方式? 三
种:hql、原生 SQL、条件查询 Criteria。
116.hibernate 有几种查询方式?
三种:hql、原生 SQL、条件查询 Criteria。
117.hibernate 实体类可以被定义为 final 吗?
实体类可以定义为 final 类,但这样的话就不能使用 hibernate 代理模式下的延迟关联提供性能了,所以不建议定义实体类为 final。
118.在 hibernate 中使用 Integer 和 int 做映射有什么区别?
Integer 类型为对象,它的值允许为 null,而 int 属于基础数据类型,值不能为 null。
119.hibernate 是如何工作的?
读取并解析配置文件。
读取并解析映射文件,创建 SessionFactory。
打开 Session。
创建事务。
进行持久化操作。
提交事务。
关闭 Session。
关闭 SessionFactory。
120.get和 load的区别?
数据查询时,没有 OID 指定的对象,get() 返回 null;load() 返回一个代理对象。
load()支持延迟加载;get() 不支持延迟加载。
121.说一下 hibernate 的缓存机制?
hibernate 常用的缓存有一级缓存和二级缓存:
一级缓存:也叫 Session 缓存,只在 Session 作用范围内有效,不需要用户干涉,由 hibernate 自身维护,可以通过:evict(object)清除 object 的缓存;clear()清除一级缓存中的所有缓存;flush()刷出缓存;
二级缓存:应用级别的缓存,在所有 Session 中都有效,支持配置第三方的缓存,如:EhCache。
122.hibernate 对象有哪些状态?
临时/瞬时状态:直接 new 出来的对象,该对象还没被持久化(没保存在数据库中),不受 Session 管理。 持久化状态:当调用 Session 的 save/saveOrupdate/get/load/list 等方法的时候,对象就是持久化状态。 游离状态:Session 关闭之后对象就是游离状态。
123.在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?
getCurrentSession 会绑定当前线程,而 openSession 则不会。 getCurrentSession 事务是 Spring 控制的,并且不需要手动关闭,而 openSession 需要我们自己手动开启和提交事务。
124.hibernate 实体类必须要有无参构造函数吗?为什么?
hibernate 中每个实体类必须提供一个无参构造函数,因为 hibernate 框架要使用 reflection api,通过调用 ClassnewInstance() 来创建实体类的实例,如果没有无参的构造函数就会抛出异常。
十三、Mybatis
125.mybatis 中 #{}和 ${}的区别是什么?
#{}是预编译处理,${}是字符替换。 在使用 #{}时,MyBatis 会将 SQL 中的#{}替换成“?”,配合 PreparedStatement 的 set 方法赋值,这样可以有效的防止 SQL 注入,保证程序的运行安全。
126. MyBatis 有几种分页方式?
分页方式:逻辑分页和物理分页。
逻辑分页: 使用 MyBatis 自带的 RowBounds 进行分页,它是一次性查询很多数据,然后在数据中再进行检索。
物理分页: 自己手写 SQL 分页或使用分页插件 PageHelper,去数据库查询指定条数的分页数据的形式。
127. RowBounds 是一次性查询全部结果吗?为什么?
RowBounds 表面是在“所有”数据中检索数据,其实并非是一次性查询出所有数据,因为 MyBatis 是对 jdbc 的封装,在 jdbc 驱动中有一个 Fetch Size 的配置,它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,它会在你执行 next()的时候,去查询更多的数据。就好比你去自动取款机取 10000 元,但取款机每次最多能取 2500 元,所以你要取 4 次才能把钱取完。只是对于 jdbc 来说,当你调用 next()的时候会自动帮你完成查询工作。这样做的好处可以有效的防止内存溢出。
128. MyBatis 逻辑分页和物理分页的区别是什么?
逻辑分页是一次性查询很多数据,然后再在结果中检索分页的数据。这样做弊端是需要消耗大量的内存、有内存溢出的风险、对数据库压力较大。 物理分页是从数据库查询指定条数的数据,弥补了一次性全部查出的所有数据的种种缺点,比如需要大量的内存,对数据库查询压力较大等问题。
129. MyBatis 是否支持延迟加载?延迟加载的原理是什么?
MyBatis 支持延迟加载,设置 lazyLoadingEnabled=true 即可。
延迟加载的原理是调用的时候触发加载,而不是在初始化的时候就加载信息。比如调用 a. getB(). getName(),这个时候发现 a. getB() 的值为 null,此时会单独触发事先保存好的关联 B 对象的 SQL,先查询出来 B,然后再调用 a. setB(b),而这时候再调用 a. getB(). getName() 就有值了,这就是延迟加载的基本原理。
130. 说一下 MyBatis 的一级缓存和二级缓存?
一级缓存:基于 PerpetualCache 的 HashMap 本地缓存,它的声明周期是和 SQLSession 一致的,有多个 SQLSession 或者分布式的环境中数据库操作,可能会出现脏数据。当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认一级缓存是开启的。
二级缓存:也是基于 PerpetualCache 的 HashMap 本地缓存,不同在于其存储作用域为 Mapper 级别的,如果多个SQLSession之间需要共享缓存,则需要使用到二级缓存,并且二级缓存可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态)。 开启二级缓存数据查询流程:二级缓存 -> 一级缓存 -> 数据库。 缓存更新机制:当某一个作用域(一级缓存 Session/二级缓存 Mapper)进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
131. MyBatis 和 hibernate 的区别有哪些?
灵活性:MyBatis 更加灵活,自己可以写 SQL 语句,使用起来比较方便。 可
移植性:MyBatis 有很多自己写的 SQL,因为每个数据库的 SQL 可以不相同,所以可移植性比较差。
学习和使用门槛:MyBatis 入门比较简单,使用门槛也更低。
二级缓存:hibernate 拥有更好的二级缓存,它的二级缓存可以自行更换为第三方的二级缓存。
132. MyBatis 有哪些执行器(Executor)?
MyBatis 有三种基本的Executor执行器:
SimpleExecutor:每执行一次 update 或 select 就开启一个 Statement 对象,用完立刻关闭 Statement 对象;
ReuseExecutor:执行 update 或 select,以 SQL 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后不关闭 Statement 对象,而是放置于 Map 内供下一次使用。简言之,就是重复使用 Statement 对象;
BatchExecutor:执行 update(没有 select,jdbc 批处理不支持 select),将所有 SQL 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理,与 jdbc 批处理相同。
133. MyBatis 分页插件的实现原理是什么?
分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 SQL,然后重写 SQL,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。 史上最全的Java面试题总汇,成功坐等offer(答案版)中
134. MyBatis 如何编写一个自定义插件?
自定义插件实现原理 MyBatis
自定义插件针对 MyBatis 四大对象(Executor、StatementHandler、ParameterHandler、ResultSetHandler)进行拦截:
Executor:拦截内部执行器,它负责调用 StatementHandler 操作数据库,并把结果集通过 ResultSetHandler 进行自动映射,另外它还处理了二级缓存的操作;
StatementHandler:拦截 SQL 语法构建的处理,它是 MyBatis 直接和数据库执行 SQL 脚本的对象,另外它也实现了 MyBatis 的一级缓存;
ParameterHandler:拦截参数的处理;
ResultSetHandler:拦截结果集的处理。
自定义插件实现关键 MyBatis 插件要实现 Interceptor 接口,接口包含的方法,如下:
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
setProperties 方法是在 MyBatis 进行配置插件的时候可以配置自定义相关属性,即:接口实现对象的参数配置;
plugin 方法是插件用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理,可以决定是否要进行拦截进而决定要返回一个什么样的目标对象,官方提供了示例:return Plugin. wrap(target, this);
intercept 方法就是要进行拦截的时候要执行的方法。 自定义插件实现示例 官方插件实现:
@Intercepts({@Signature(type = Executor. class, method = "query",
args = {MappedStatement. class, Object. class, RowBounds. class, ResultHandler. class})})public class TestInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation. getTarget(); //被代理对象
Method method = invocation. getMethod(); //代理方法
Object[] args = invocation. getArgs(); //方法参数
// do something . . . . . . 方法拦截前执行代码块
Object result = invocation. proceed();
// do something . . . . . . . 方法拦截后执行代码块
return result;
}
public Object plugin(Object target) {
return Plugin. wrap(target, this);
}
}
剩余的部分在下文中哦,敬请期待。请关注小编