Java后端面试:框架篇高频面试(Spring、SpringMVC、SpringBoot、MyBatis)

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:Java后端面试:MySQL面试篇(底层事务、SQL调优)
📚订阅专栏:Java后端面试
希望文章对你们有所帮助

框架篇高频面试(Spring、SpringMVC、SpringBoot、MyBatis)

  • Spring
    • 单例bean是线程安全的吗?
    • AOP相关面试题
    • Spring事务失效的场景
    • bean的生命周期
    • bean的循环依赖(循环引用)
  • SpringMVC-执行流程
    • 视图阶段(JSP)
    • 前后端分离阶段
  • SpringBoot-自动装配原理
  • Spring框架常见注解(Spring、SpringMVC、SpringBoot)
  • MyBatis
    • 执行流程
    • 延迟加载使用及原理
    • 一级、二级缓存

Spring

单例bean是线程安全的吗?

通过@Scope注解可以设置bean是单例的还是多例的,默认是单例的。
而单例bean线程不安全

Spring的bean中都是注入无状态的对象,也就是说无法修改,不会有线程安全问题。
但是如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,当然可以使用多例模式或者加锁来解决。

AOP相关面试题

AOP很重要,在Spring也算是一个难点吧,但是像IOC、AOP这种Spring核心,不会的话说不过去,这里就简单说说。

1、何为AOP?
AOP称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被称为切面(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

2、常见的AOP使用场景?

1、记录操作日志(自行学习@Aspect、切点、环绕通知)
2、缓存处理
3、Spring中内置的事务处理

3、Spring中的事务是如何实现的?(一定要提到AOP!)

Spring支持编程式事务管理和声明式事务管理两种方式,主要使用的是声明式事务
声明式事务管理是建立在AOP上的。本质是通过AOP功能,对方法的前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行目标方法之后执行情况提交或者回滚事务。(@Transactional注解就是这样的,其底层的实现(开启事务、提交/回滚事务)就是AOP追加的)

Spring事务失效的场景

这种问题能够体现出我们对Spring框架的深入理解,以及复杂业务的编码经验。

有三种非常常见的事务失效的情况:

1、异常捕获处理

对于转账的业务,我们会给整个业务增加@Transactional注解,如果中途发生了异常我们就会回滚。
但是如果这个业务方法中使用了try…catch,中途发生异常以后,@Transactional将会失效。
原因:事务通知只有捉到了目标抛出的异常,才能进行后续的回滚处理,如果目标自己处理掉异常,事务通知将会无法知悉
解决方法:在catch块中添加throw new RuntimeException(E),将异常给抛出,不要处理。

2、抛出检查异常

依旧是转账业务,这次不用try…catch,而是在方法体使用throws来抛出检查异常(类似FileNotFoundException这种非运行异常),这种情况也会导致事务失效。
原因:Spring默认只会回滚非检查异常
解决方法:配置rollbackFor属性:@Transactional(rollbackFor=Exception.class),这样事务回滚就不只是针对运行时异常了。

3、非public方法

如果没有用public修饰方法,就会导致事务失效。
原因:Spring为方法创建代理、添加事务通知,前提条件都是该方法是public的
解决:改为public方法

bean的生命周期

这个在业务开发过程中重要吗?可能真的不太重要,这就是个纯八股。但是面试官还是挺喜欢问的,可能是掌握生命周期能显得你更了解框架,方便调试和解决问题。

1、通过BeanDefinition获取bean的定义信息
2、调用构造函数实例化bean
3、bean的依赖注入
4、处理Aware接口
5、Bean的后置处理器BeanPostProcessor-前置
6、初始化方法
7、Bean的后置处理器BeanPostProcessor-后置
8、销毁bean

bean的循环依赖(循环引用)

如果是两个bean,成员变量分别用对方来注入,这就是循环依赖。
这种方式是会出现死循环的,对于A,先实例化bean,再初始化,初始化的过程中需要设置b属性,而b是B类型的对象,可是容器中不存在B对象,就会去实例化B的bean对象,再去初始化,初始化的时候需要设置a属性,a是A类型的对象,但是容器中也不存在A对象,最后造成了死循环。

Spring框架已经帮助我们解决了大部分的循环依赖问题,通过的是三级缓存:

一级缓存:单力池,缓存已经经历了完整声明周期,即已经初始化完成的bean对象
二级缓存:缓存早期的bean对象(生命周期还没走完)
三级缓存:缓存的是对象工厂ObjectFactory,用来创建某个对象的

整体流程非常的复杂,大家可以自行去看相关资料来理解,写起来很麻烦,但要记住一级缓存+二级缓存可以解决大部分的循环依赖问题,但是解决不了存在代理对象时的问题,而一级+二级+三级可以解决代理对象的循环依赖问题,过程需要理解。

这些都是发生在初始化的时候,而如果我们在声明周期的构造方法换发出现了循环依赖,也就是注入的方式是用构造函数。解决是使用@Lazy进行懒加载,什么时候需要对象了再进行bean对象的创建就好了。

SpringMVC-执行流程

如果要问到SpringMVC,那么执行流程可以说是非常重要的。
但是其实开发分为了两个阶段,一个是视图阶段(老旧的JSP等),另外一个是前后端分离阶段(接口开发,异步),现在我们都是用的前后端分离的开发,但是视图阶段的开发也是面试可能会问到的,很繁琐,得记住。

视图阶段(JSP)

在这里插入图片描述
1、对于一个浏览器发起的请求,视图阶段的执行流程如下:

1、浏览器发起请求给前端控制器DispatcherServlet
2、查询handler:前端控制器根据前端请求,去处理器映射器HandlerMapping中查询对应的执行方法
3、返回处理器执行链:因为对于一个请求,除了要找到这个路径对应的类名.方法名,还需要判断它是否会被拦截器拦截,因此处理器映射器不是直接返回方法给前端控制器,而是返回一个处理器执行链(处理器执行链可以暂且理解成方法handler+拦截器
4、请求执行handler:处理器执行链不会被拦截,那么前端控制器就要开始执行方法handler,这个执行需要向处理器适配器去请求,而不是直接到处理器中(适配器模式),用适配器有两个好处:
(1)可以处理请求的参数
(2)处理返回值
5、处理器适配器向处理器请求
6、处理器将响应返回给处理器适配器,这个响应就是ModelAndView
7、处理器适配器再将ModelAndView返回给前端控制器
8、前端控制器返回视图解析器ViewResolver,这个视图解析器的作用是将逻辑视图解析为真正的视图View
9、视图解析器将真正的视图View返回给前端控制器
10、前端控制器将视图渲染

2、SpringMVC执行过程中重要的四个组件

1、前端控制器DispatcherServlet(调度中心,处理所有的请求)
2、处理器映射器HandlerMapping(通过路径,查询方法handler,返回处理器执行链)
3、处理器适配器HandlerAdaptor(执行handler、处理handler中的参数)
4、视图解析器ViewResolver(将逻辑视图ModelAndView解析为真正的视图View)

前后端分离阶段

现在的开发不太一样,没有ModelAndView了,而是返回的Json数据,流程将会简化为:
在这里插入图片描述
这时候处理器Handler的执行是变化了:

1、处理器Handler的方法上添加@ResponseBody注解
2、底层会通过一个转化器HttpMessageConverter将返回结果转化为JSON格式响应给前端

SpringBoot-自动装配原理

这是SpringBoot最高频的面试题了,也是框架的最核心思想。

我们的SpringBoot启动类中一定会有一个注解:@SpringBootApplication,这个注解底层包含了三个部分:

@SpringBootConfiguration:与@Configuration相同,用来声明当前是个配置类
@ComponentScan:组件扫描,默认扫描当前引导类所在包及其子包
@EnableAutoConfiguration:SpringBoot实现自动化配置的核心注解

其中,@EnableAutoConfiguration是实现自动化配置的核心注解,该注解底层通过@Import来导入对应的配置选择器。

其内部就是读取该项目和该项目引用的jar包的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。
这个条件判断会有@ConditionalOnClass这样的注解,判断是否有对应的class文件(字节码文件),若有则加载该类,把这个配置类中所有的Bean都放入Spring容器中使用。

Spring框架常见注解(Spring、SpringMVC、SpringBoot)

Spring的注解主要是用来进行bean的实例化以及依赖注入的,SpringMVC的注解主要是用来处理请求和响应的,而SpringBoot的注解尽量说一下跟自动装配有关系的,被问到不要混淆着讲。
1、Spring注解:

注解说明
@Componennt、@Controller、@Service、@Repository使用在类上,用于实例化bean
@Autowired在字段上根据类型依赖注入
@Qualifier结合@Autowired一起使用,用于根据名称进行依赖注入
@Scope标注Bean的作用返回(单例or多例)
@Configuration指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
@ComponentScan用于指定Spring在初始化容器时要扫描的包
@Bean用在方法上,标注该方法的返回值会存到Spring容器中
@Import该注解导入的类会被Spring加载到IOC容器中
@Aspect、@Before、@After、@Around、@Pointcut用于AOP(切面、前置通知、后置通知、环绕通知、切入点表达式)

2、SpringMVC注解:

注解说明
@RequestMapping(也有衍生的PostMapping、GetMapping等)用于映射请求路径,定义在类上或方法上,用在类上则该类中的所有方法都是以该地址作为父路径的
@RequestBody接受http请求的json数据,将json转化为java对象
@ResponseBody将controller方法返回的对象转化为json对象响应给客户端
@RequestParam指定请求参数的名称(和数据库字段名不一致时使用)
@PathViriable从请求路径下获取请求参数/user/{id},传递给方法的形式参数(Restful风格)
@RequestHeader获取指定的请求头数据
@RestController@Controller+@ResponseBody

3、SpringBoot注解:

注解说明
@SpringBootConfiguration配置文件
@EnableAutoConfiguration打开自动配置
@ComponentScanSpring组件扫描

MyBatis

执行流程

1、读取MyBatis配置文件mybatis-config.xml,加载运行环境(数据库相关信息)和mapper映射文件
2、构造会话工厂SqlSessionFactory,会话工厂是全局唯一的
3、会话工厂创建SqlSession对象(包含了执行SQL语句的所有方法),每次操作都会创建出一个会话
4、Executor执行器是真正操作数据库的接口,同时负责了查询缓存的维护
5、Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息
6、输入参数的映射(将java类型转化为数据库处理的类型)
7、输出结果映射(将数据库操作的结果映射成java类型)

延迟加载使用及原理

1、延迟加载是需要用到数据的时候才会加载,不需要的时候就不会加载。
2、MyBatis是支持延迟加载的,但是默认是没有开启的。可以局部开启或者全局开启。
3、延迟加载的底层原理:

(1)使用CGLIB创建目标对象的代理对象
(2)当调用方法的时候,进入拦截器invoke方法,发现目标方法是null值,执行SQL查询
(3)获取数据后,调用set方法设置属性值,再继续查询目标方法,就有值了

一级、二级缓存

一级缓存:基于HashMap本地缓存,其存储作用域为SqlSession,当SqlSession进行flush或close之后,该Session中的Cache就被清空(默认开启)
二级缓存:基于namespace和mapper的作用域起作用的,不依赖于SqlSession,默认也是基于HashMap存储,需要单独开启(通过核心配置文件)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/278809.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac os 配置两个github账号

1. 清空git全局配置的username和email git config --global --unset user.name git config --global --unset user.emailgit config --list 可以查看是否清空了 2. 定义两个标识符,这两个标识符以后会被用来代替“github.com”来使用。 假设两个账号的邮箱地址分别是a@gmai…

JAVA实战开源项目:农村物流配送系统(Vue+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理:2.2.2 位置信息管理:2.2.3 配送人员分配:2.2.4 路线规划:2.2.5 个人中心:2.2.6 退换快递处理:…

【算法与数据结构】二叉树(前中后)序遍历

文章目录 📝前言🌠 创建简单二叉树🌉二叉树的三种遍历🌠前序🌉中序遍历 🌠后序遍历 🌠二叉树节点个数🌉二叉树节点个数注意点 🚩总结 📝前言 一棵二叉树是结…

云原生 PaaS 服务:构建现代应用的利器(分布式应用服务、配置中心、数据库服务、定时任务、实时监控、服务网关、技术组件)

在当今数字化时代,企业需要面对不断变化的市场需求和竞争压力,以及日益复杂的应用开发和部署挑战。在这样的背景下,云原生 PaaS(Platform as a Service)服务应运而生,为企业提供了一种现代化的应用开发和部…

计算机视觉之三维重建(1)---摄像机几何

文章目录 一、针孔模型和透镜1.1 针孔摄像机1.2 近轴折射模型1.3 透镜问题 二、摄像机几何2.1 像平面和像素平面2.2 齐次坐标下的投影变换2.3 摄像机倾斜2.4 规范化摄像机2.5 世界坐标系2.6 Faugeras定理2.7 投影变换性质: 三、其他投影摄像机模型3.1 弱透视投影摄像…

【ZooKeeper3、Watcher机制

本文基于 Apache ZooKeeper Release 3.7.0 版本书写 作于 2022年5月15日 17:22:11 转载请声明 演示前的ZooKeeper目录状态,只有zookeeper默认目录: 在客户端直接输入 --help 命令,可以看到以下文字: 可以看到 addWatch 命令&am…

HTML5球体下落粒子爆炸特效

HTML5球体下落粒子爆炸特效,源码由HTMLCSSJS组成,双击html文件可以本地运行效果,也可以上传到服务器里面 下载地址 HTML5球体下落粒子爆炸特效

Java代码审计安全篇-反序列化漏洞

前言: 堕落了三个月,现在因为被找实习而困扰,着实自己能力不足,从今天开始 每天沉淀一点点 ,准备秋招 加油 注意: 本文章参考qax的网络安全java代码审计和部分师傅审计思路以及webgoat靶场,记录…

智慧城市物联网建设:提升城市管理效率与居民生活品质

目录 一、智慧城市物联网建设的意义 1、提升城市管理效率 2、改善居民生活品质 3、促进城市可持续发展 二、智慧城市物联网建设面临的挑战 1、技术标准与互操作性问题 2、数据安全与隐私保护问题 3、投资与回报平衡问题 三、智慧城市物联网建设的实施策略 1、制定统一…

Python和R的区别是什么,Python与R的应用场景是什么?

如果你这么问,那么你可能正站在数据科学的起点。对于志在成为数据专业人员的你来说,学习编程是无疑的。我想行你早就听过Python 与R的比较之声,并在选择中感到困惑。在此,我想说,也算是一种安慰吧:对于语言…

uniapp+vue3+setup语法糖开发微信小程序时不能定义globalData的解决方法

在使用 uniapp 开发小程序的时候, 发现使用了setup 语法糖 ,定义 globalData 时,要不是定义不了, 要不就是使用 getApp()取不到,后来想到一个不伦不类的方法解决了, 这个方法有点难看, 但是解决…

学习笔记Day8:GEO数据挖掘-基因表达芯片

GEO数据挖掘 数据库:GEO、NHANCE、TCGA、ICGC、CCLE、SEER等 数据类型:基因表达芯片、转录组、单细胞、突变、甲基化、拷贝数变异等等 常见图表 表达矩阵 一行为一个基因,一列为一个样本,内容是基因表达量。 热图 输入数据…

智能合约 - 部署ERC20

Remix介绍 Remix是一个由以太坊社区开发的在线集成开发环境(IDE),旨在帮助开发者编写、测试和部署以太坊智能合约。它提供了一个简单易用的界面,使得开发者可以在浏览器中直接进行智能合约的开发,而无需安装任何额外的…

Error response from daemon Get server gave HTTP response to HTTPS client

使用docker compose拉起docker镜像时,若出现如下报错 Error response from daemon: Get "https://devops.test.cn:5000/v2/": http: server gave HTTP response to HTTPS client表示Docker守护进程无法从指定url获取响应, 可能原因有以下&…

java Flink(四十二)Flink的序列化以及TypeInformation介绍(源码分析)

Flink的TypeInformation以及序列化 TypeInformation主要作用是为了在 Flink系统内有效地对数据结构类型进行管理,能够在分布式计算过程中对数据的类型进行管理和推断。同时基于对数据的类型信息管理,Flink内部对数据存储也进行了相应的性能优化。 Flin…

烫烫烫VS屯屯屯,为什么我们再编程中会遇到一些奇怪的中文汉字呢?【函数的栈帧】

一、奇怪的汉字是怎么产生的呢? 当我们上网查询的时候,我们会发现网上用了一句简单的话来概括: 在VC 的debug模式下,在栈中新分配的内存会初始化为 0xcc,在堆中新分配的内存会初始化为 0xcd,这时打印出来分…

Jenkins 一个进程存在多个实例问题排查

Jenkins 一个进程存在多个实例问题排查 最近Jenkins升级到2.440.1​版本后,使用tomcat​服务部署,发现每次定时任务总会有3-4个请求到我的机器人上,导致出现奇奇怪怪的问题。 问题发现 机器人运行异常,总有好几个同时请求的服务。…

C++进阶之路---手撕“红黑树”

顾得泉:个人主页 个人专栏:《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂,年薪百万! 一、红黑树的概念与性质 1.概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点…

matlab矩形薄板小挠度弯曲有限元编程 |【Matlab源码+理论文本】|板单元| Kirchoff薄板 | 板壳单元

专栏导读 作者简介:工学博士,高级工程师,专注于工业软件算法研究本文已收录于专栏:《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现,并提供所有案例完整源码;2.单元…

后端工程师快速使用axios

文章目录 01.AJAX 概念和 axios 使用模板目标讲解代码解析案例前端后端结果截图 02.URL 查询参数模板目标讲解案例前端后端结果截图 03.常用请求方法和数据提交模板目标讲解案例前端后端结果截图 04.axios 错误处理模板目标讲解案例前端后端结果截图 01.AJAX 概念和 axios 使用…