iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >spring的13个经典面试题
  • 151
分享到

spring的13个经典面试题

2024-04-02 19:04:59 151人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录1、jdk 动态代理和 CGLIB 代理有什么区别?2、FactoryBean、BeanFactory、ApplicationContext 有什么区别?3、说一说spring

1、JDK 动态代理和 CGLIB 代理有什么区别?

  • JDK 动态代理主要是针对类实现了某个接口,AOP 则会使用 JDK 动态代理。他基于反射的机制实现,生成一个实现同样接口的一个代理类,然后通过重写方法的方式,实现对代码的增强。
  • 而如果某个类没有实现接口,AOP 则会使用 CGLIB 代理。他的底层原理是基于 ASM 第三方框架,通过修改字节码生成一个子类,然后重写父类的方法,实现对代码的增强。

详细分析参考:【Java萌新】面试常问设计模式——代理模式

2、FactoryBean、BeanFactory、ApplicationContext 有什么区别?

  • BeanFactory:是一个 Bean 工厂,使用简单工厂模式,是 Spring IoC 容器顶级接口,是用于管理 Bean 的工厂,最核心的功能是通过 getBean() 方法加载 Bean 对象,通常我们不会直接使用该接口,而是使用其子接口 ApplicationContext
  • FactoryBean:是一个工厂 Bean,使用了工厂方法模式,实现该接口的类可以自己定义要创建的 Bean 实例,只需要实现它的 getObject() 方法即可。
  • ApplicationConext:是 BeanFactory 的子接口,扩展了 BeanFactory 的功能(高级 IOC 容器)。

3、说一说Spring Bean 的生命周期?

Spring Bean 生命周期简单概括为 5 个阶段:

  1. Bean 的实例化阶段:创建一个 Bean 对象。
  2. Bean 实例的属性填充阶段:为 Bean 实例的属性赋值。
  3. Bean 实例的初始化阶段:对 Bean 实例进行初始化。
  4. Bean 实例的正常使用阶段。
  5. Bean 实例的销毁阶段:容器关闭后,将 Bean 实例销毁。

4、依赖注入的实现方法,以及相关注解?

构造方法注入、Setter 方法注入、接口注入 三种。

依赖注入的相关注解

  • @Autowired:自动按类型注入,如果有多个匹配则按照指定 Bean 的 id 查找,查找不到会报错。
  • @Qualifier:在自动按照类型注入的基础上再按照 Bean 的 id 注入,给变量注入时必须搭配@Autowired,给方法注入时可单独使用。
  • @Resource :直接按照 Bean 的 id 注入,只能注入 Bean 类型。
  • @Value :用于注入基本数据类型和 String 类型。

5、什么是 Spring IOC ?

IOC 即控制反转,简单来说就是把原来代码里需要实现的对象创建、依赖反转给容器来帮忙实现,Spring 中管理对象及其依赖关系都是通过 Spring 的 IOC 容器实现的。

IOC 的实现方式有依赖注入和依赖查找,由于依赖查找使用的很少,因此 IOC 也叫做依赖注入。

我们之前在创建一个对象的时候都是直接 new 一个对象实例,而有了 IOC ,对象实例的创建都交给容器去实现即可。

6、Spring IOC 容器的构建流程(初始化过程)

我们以 XML 方式的容器初始化为例:

通过 ClassPathXmlApplicationContext,去创建 ApplicationContext 容器对象:


ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

ClassPathXmlApplicationContext创建容器对象时,构造方法做了如下两件事:

  • ① 调用父容器的构造方法为容器先设置好 Bean 资源加载器。
  • ② 调用父类的 setConfigLocations() 方法设置 Bean 配置信息的定位路径
  • ③ 调用父类 AbstractApplicationContext 的 refresh() 方法启动整个 IOC 容器对 Bean 的载入,在创建 IOC 容器前如果已有容器存在,需要把已有的容器销毁,保证在 refresh() 方法后使用的是新创建的 IOC 容器。
  • 容器创建完成后,通过 loadBeanDefinitions() 方法加载 Bean 配置资源,该方法在加载资源时,首先解析配置文件路径,读取配置文件的内容,然后通过 XML 解析器将 Bean 的配置信息转换成文档对象,之后按照 Spring Bean 的定义规则将文档对象解析为 BeanDefinition 对象。
  • 接下来,将解析得到的 BeanDefinition 对象存入本地缓存(一个 HashMap 集合,key 是字符串,值是 BeanDefinition)中。
  • 最后,实例化所有的 Bean 实例(非懒加载):包括实例的创建,实例的属性填充,实例的初始化。

7、依赖注入的过程(Bean 的加载流程)?

源码分析可以参考我的文章:Spring源码分析——Bean的加载

先来看下面几行代码:


public class BeanFactoryTest {
	public static void main(String[] args) {
		// 加载与解析XML配置文件,获得BeanFactory:
		BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-bf.xml"));
		// 从BeanFactory中加载Bean对象
		Object a = beanFactory.getBean("componentA");
		Object b = beanFactory.getBean("componentB");
		System.out.println(a);// com.myspring.test.xmltest.ComponentA@1c93084c
		System.out.println(b);// com.myspring.test.xmltest.ComponentB@6ef888f6
	}
}
  • 首先通过 BeanFactory/ApplicationContext 调用getBean() 方法,来获取 Bean 实例,该方法中,真正获取 Bean 实例的是其内层方法 doGetBean() 方法(真正实现从 IOC 容器获取 Bean ,也是触发依赖注入的地方)。
  • doGetBean() 方法中,主要做了以下几件事:
    • beanName 的转换方法 transfORMedBeanName(name),该方法的作用是,根据传入的 name 参数,获取真正的 Bean 对应的 beanName。该方法的 name 参数,有可能是一个别名(alias 属性设置的别名),也有可能是一个&开头的 name (工厂 Bean 对象)。
    • ② 尝试从缓存中加载 Bean 的单实例,根据上面transformedBeanName方法转换 name 后得到的真实 beanName,getSingleton(beanName)方法直接尝试从缓存中获取 Bean 的共享单实例,这时候获取的是初始状态,尚未实例化。(从缓存中加载的流程就是,根据 beanName 依次从一级缓存、二级缓存、三级缓存中尝试获取,通过三级缓存机制也可以有效避免循环依赖)
    • Bean 的实例化getSingleton(beanName)方法执行后,从缓存中得到了 Bean 的原始状态,接下来需要对该 Bean 进行实例化。
    • Bean 的初始化:寻找依赖(循环依赖检查、依赖注入),因为 Bean 的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置的成依赖于其他的 Bean,那么此时应该先加载依赖的 Bean。所以在流程中,Spring初始化一个 Bean,会先初始化其依赖的所有的其他 Bean。
    • 根据不同的 scope 作用域创建 Bean,调用doCreateBean() 方法创建 Bean。
    • 类型转换,根据 scope 创建完 Bean 成功后,一般可以直接返回即可。但当传入 doGetBean 方法中的 requireType 参数不为空时,意味着我们对最后返回的 Bean 有着类型上的要求。Spring 通过 类型转换器 将第 ⑤ 步创建完成的 Bean 转换为 requireType 指定的类型。

8、Bean 的作用范围?

通过 scope 属性指定 Bean 的作用范围,包括:

  • singleton:单例模式,是默认作用域,不管收到多少 Bean 请求每个容器中只有一个唯一的 Bean 实例。
  • prototype:原型模式,和 singleton 相反,每次 Bean 请求都会创建一个新的实例。
  • request:每次 Http 请求都会创建一个新的 Bean 并把它放到 request 域中,在请求完成后 Bean 会失效并被垃圾收集器回收。
  • session:和 request 类似,确保每个 session 中有一个 Bean 实例,session 过期后 bean 会随之失效。
  • global session:当应用部署在 Portlet 容器时,如果想让所有 Portlet 共用全局存储变量,那么该变量需要存储在 global session 中。

9、Spring事务传播机制有哪些?

  • REQUIRED:Spring 默认的事务传播级别,如果上下文中已经存在事务,那么就加入到事务中执行,如果当前上下文中不存在事务,则新建事务执行。
  • REQUIRES_NEW:每次都会新建一个事务,如果上下文中有事务,则将上下文的事务挂起,当新建事务执行完成以后,上下文事务再恢复执行。
  • SUPPORTS:如果上下文存在事务,则加入到事务执行,如果没有事务,则使用非事务的方式执行。
  • MANDATORY:上下文中必须要存在事务,否则就会抛出异常。
  • NOT_SUPPORTED :如果上下文中存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文的事务。
  • NEVER:上下文中不能存在事务,否则就会抛出异常。
  • ESTED:嵌套事务。如果上下文中存在事务,则嵌套事务执行,如果不存在事务,则新建事务。

10、Spring 的事务隔离级别有哪些?

Spring 的事务隔离级别底层其实是基于数据库的,Spring 并没有自己的一套隔离级别。

  • DEFAULT:使用数据库默认隔离级别。
  • READ_UNCOMMITTED:读未提交,最低的隔离级别,会读取到其他事务还未提交的内容,存在脏读。
  • READ_COMMITTED:读已提交,读取到的内容都是已经提交的,可以解决脏读,但是存在不可重复读。
  • REPEATABLE_READ:可重复读,在一个事务中多次读取时看到相同的内容,可以解决不可重复读,但是存在幻读。
  • SERIALIZABLE:串行化,最高的隔离级别,对于同一行记录,写会加写,读会加读锁。在这种情况下,只有读读能并发执行,其他并行的读写、写读、写写操作都是冲突的,需要串行执行。可以防止脏读、不可重复度、幻读,没有并发事务问题。

11、AOP 是什么?AOP有哪些应用场景?

AOP 概念: 即面向切面编程,使用动态代理技术,在不修改源码的基础上对目标方法进行增强。

Spring 中的 AOP 目前支持 JDK 动态代理和 Cglib 代理。如果被代理对象实现了接口,则使用 JDK 动态代理,否则使用 Cglib 代理。另外,也可以通过指定 proxyTargetClass=true 来实现强制走 Cglib 代理。

应用场景:

  • 权限认证
  • 日志打印
  • 事务

12、AOP 的相关注解有哪些?

  • @Aspect:切面,声明被注解标注的类是一个切面 Bean。

@Aspect
@Component
public class LogAspect {
    ...
}
  • @Pointcut:切入点,可以通过 @Pointcut("execution(* top.csp1999.service.impl.*.*(..))") 去指定要切入的目标对象,并对其符合表达式要求的方法进行增强。

@Pointcut("execution(* top.csp1999.service.impl.*.*(..))")
public void operationLog(){}
  • @Before:前置通知,指在某个连接点之前执行的通知。

@Before("operationLog()")
public void doBeforeAdvice(JoinPoint joinPoint){
    System.out.println("进入方法前执行.....");
}
  • @After:后置通知,指某个连接点退出时执行的通知(不论正常返回还是异常退出)。

@After("operationLog()")
public void after(JoinPoint jp){
    System.out.println("方法最后执行.....");
}
  • @AfterReturning:后置返回通知,指某连接点正常完成之后执行的通知,返回值可以在返回后通知方法里接收。

@AfterReturning(returning = "ret", pointcut = "operationLog()")
public void doAfterReturning(Object ret) {
    System.out.println("方法的返回值 : " + ret);
}
  • @AfterThrowing:后置异常通知,指方法抛出异常导致退出时执行的通知,和@AfterReturning只会有一个执行,异常使用 throwing 属性接收。

@AfterThrowing(throwing = "jp", pointcut = "operationLog()")
public void throwss(JoinPoint jp){
    System.out.println("方法异常时执行.....");
}
  • @Around:环绕通知,可以用来在调用一个具体方法前和调用后来完成一些具体的任务。

@Around("operationLog()")
public Object run2(ProceedingJoinPoint joinPoint) throws Throwable {
    // 获取方法参数值数组
    Object[] args = joinPoint.getArgs();
    // 得到其方法签名
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    // 获取方法参数类型数组
    Class[] paramTypeArray = methodSignature.getParameterTypes();
    if (EntityManager.class.isAssignableFrom(paramTypeArray[paramTypeArray.length - 1])) {
         // 如果方法的参数列表最后一个参数是entityManager类型,则给其赋值
         args[args.length - 1] = entityManager;
	}
     logger.info("请求参数为{}",args);
     // 动态修改其参数
     // 注意,如果调用joinPoint.proceed()方法,则修改的参数值不会生效,必须调用joinPoint.proceed(Object[] args)
     Object result = joinPoint.proceed(args);
     logger.info("响应结果为{}",result);
     // 如果这里不返回result,则目标对象实际返回值会被置为null
     return result;
}

13、AOP 的相关术语有什么?

Aspect:切面,一个关注点的模块化,这个关注点可能会横切多个对象。

Joinpoint:连接点,程序执行过程中的某一行为,即业务层中的所有方法。。

Advice:通知,指切面对于某个连接点所产生的动作,包括前置通知、后置通知、返回后通知、异常通知和环绕通知。

Pointcut:切入点,指被拦截的连接点,切入点一定是连接点,但连接点不一定是切入点。

Proxy:代理,Spring AOP 中有 JDK 动态代理和 CGLib 代理,目标对象实现了接口时采用 JDK 动态代理,反之采用 CGLib 代理。

Target:代理的目标对象,指一个或多个切面所通知的对象。

Weaving :织入,指把增强应用到目标对象来创建代理对象的过程。

14、总结

文章会不定时更新,有时候一天多更新几篇,还请三连支持一下,后续会亿点点的更新!也希望大家可以关注编程网其他文章!

--结束END--

本文标题: spring的13个经典面试题

本文链接: https://www.lsjlt.com/news/128241.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • spring的13个经典面试题
    目录1、JDK 动态代理和 CGLIB 代理有什么区别?2、FactoryBean、BeanFactory、ApplicationContext 有什么区别?3、说一说Spring ...
    99+
    2024-04-02
  • Java经典面试题汇总:Spring
    目录1. 什么是Spring? 有哪些优点?2. 什么是 AOP?3. 什么是 IOC?4. 什么是 DI?5. Spring 有哪些核心模块?6. Spring 常...
    99+
    2024-04-02
  • Java经典面试题汇总:Spring Boot
    目录1. 什么是 Spring Boot?2. 为什么要用 Spring Boot? 3. Spring Boot 核心配置文件是什么?4. Spring Boot 提供了...
    99+
    2024-04-02
  • Java经典面试题汇总:Spring MVC
    目录1. 什么是Spring MVC ?2. Spring MVC 有哪些组件?3. 说一下 Spring MVC 运行流程?4. Spring MVC的优点:5. @Request...
    99+
    2024-04-02
  • Python经典面试题
    #1.字符串最后一个单词的长度 题目描述:计算字符串最后一个单词的长度,单词以空格隔开。 输入描述: 一行字符串,非空,长度小于5000。输出描述: 整数N,最后一个单词的长度。 示例1:输入:hello world输出:5参考代码一:...
    99+
    2023-01-31
    面试题 经典 Python
  • pyntho经典面试题
    Python基础篇 1:为什么学习Python 2:通过什么途径学习Python 3:谈谈对Python和其他语言的区别 Python的优势: 4:简述解释型和编译型编程语言 5:Python的解释器种类以及相关特点? 6:位和字节...
    99+
    2023-01-30
    面试题 经典 pyntho
  • 28个MongoDB经典面试题详解
    MongoDB是目前最好的面向文档的免费开源NoSQL数据库。 如果你正准备参加MongoDB NoSQL数据库的技术面试,你最好看看下面的MongoDB NoSQL面试问答。 这些MongoDB NoSQ...
    99+
    2024-04-02
  • Mysql经典面试题20道
    我整理的必刷SQL经典题目 SQL语句在工作与面试时都必不可少,下面我整理了20道题目供大家练习,常见的使用方法和开窗函数都有考察,来测测你的sql技能是否过关。 一、创建表 共有4个表,分别是学生信息表、课程表、老师信息表和成绩表。 1 ...
    99+
    2023-08-22
    mysql 面试 数据库
  • Nacos经典7道面试题
    Nacos中的保护阈值的作用是什么? 假如现在有一个服务,本来有10个实例,但是现在挂掉了8个,剩下2个正常实例,此时本来由10个实例处理的流量,就全部交给这个两个正常实例来处理了,此时这两个实例很有可能是处理不过来的,最终导致被压垮,为了...
    99+
    2023-08-16
    java spring cloud
  • Python经典面试题有哪些
    这篇文章主要讲解了“Python经典面试题有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python经典面试题有哪些”吧!Python面试题(一)之交换变量值平时时不时会面面实习生,大...
    99+
    2023-06-02
  • 经典MySQL面试题有哪些
    这篇文章主要讲解了“经典MySQL面试题有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“经典MySQL面试题有哪些”吧!1.数据库三范式是什么第一范式(...
    99+
    2024-04-02
  • Redis经典面试题有哪些
    本篇内容介绍了“Redis经典面试题有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、什么是Redis?简述它的优缺点?Redis本质...
    99+
    2023-06-02
  • PHP经典面试题有哪些
    这篇文章给大家分享的是有关PHP经典面试题有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1.合并两个数组有几种方式,试比较它们的异同方式:array_merge()’+’array_merge_recurs...
    99+
    2023-06-15
  • Java面试题经典面试题220道(附答案)
    Java基础: JDK 和 JRE 有什么区别? == 和 equals 的区别是什么?== 解读 两个对象的 hashCode() 相同, 那么 equals() 也一定为 true吗? final 在 Java 中有什么作用? ...
    99+
    2023-09-06
    java 面试 jvm
  • CSS的经典面试题有哪些
    这篇“CSS的经典面试题有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“CSS的经典面试题有哪些”文章吧。1、 介绍一下...
    99+
    2023-06-27
  • Java经典面试题总结(一)
    Java经典面试题总结(一) 题一:Java编译运行原理题二:JDK,JVM,JRE三者之间的关系题三:谈一下对冯诺依曼体系的了解题四:重载与重写的区别题五:拆箱装箱是指什么? 题一:Java编译运行原理 Java源代码通过...
    99+
    2023-08-30
    java 开发语言
  • Java经典面试题汇总:Mybatis
    目录1. MyBatis 中 #{}和 ${}的区别是什么?2. MyBatis 有几种分页方式?3. MyBatis 逻辑分页和物理分页的区别是什么?4. MyBatis 是否支持...
    99+
    2024-04-02
  • Linux经典面试题有哪些
    这篇文章主要介绍“Linux经典面试题有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Linux经典面试题有哪些”文章能帮助大家解决问题。1、介绍下自己?(几乎每家公司首先都会让你做个自我介绍,...
    99+
    2023-06-16
  • Java经典面试题汇总:JVM
    目录1. 说一下 JVM 的主要组成部分?及其作用?2. 说一下 JVM 运行时数据区?3. 说一下堆栈的区别?4. 解释内存中的栈(stack)、堆(heap)和静态区(stati...
    99+
    2024-04-02
  • Oracle的四道经典面试题分享
    前言 本文整理了4道Oracle 经典面试题,与大家分享学习。这也许是你一直期待的文章,下面话不多说了,来一起看看详细的介绍吧 第一题 create table test( id number(10)...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作