面试题打卡——第九天

Posted Code_BinBin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题打卡——第九天相关的知识,希望对你有一定的参考价值。

这几天放假了,马上要去江苏了,没怎么搞学习,摸了几天鱼

Spring是如何简化开发的?

​ 基于POJO的轻量级和最小侵入性编程

​ 通过依赖注入和面向接口实现松耦合

​ 基于切面和惯例进行声明式编程

​ 通过切面和模板减少样板式代码

说说你对Aop的理解?

​ AOP全称叫做 Aspect Oriented Programming 面向切面编程。它是为解耦而生的,解耦是程序员编码开发过程中一直追求的境界,AOP在业务类的隔离上,绝对是做到了解耦,在这里面有几个核心的概念:

  • 切面(Aspect): 指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP中,切面可以使用通用类基于模式的方式(schema-based approach)或者在普通类中以@Aspect注解(@AspectJ 注解方式)来实现。

  • 连接点(Join point): 在程序执行过程中某个特定的点,例如某个方法调用的时间点或者处理异常的时间点。在Spring AOP中,一个连接点总是代表一个方法的执行。

  • 通知(Advice): 在切面的某个特定的连接点上执行的动作。通知有多种类型,包括“around”, “before” and “after”等等。通知的类型将在后面的章节进行讨论。 许多AOP框架,包括Spring在内,都是以拦截器做通知模型的,并维护着一个以连接点为中心的拦截器链。

  • 切点(Pointcut): 匹配连接点的断言。通知和切点表达式相关联,并在满足这个切点的连接点上运行(例如,当执行某个特定名称的方法时)。切点表达式如何和连接点匹配是AOP的核心:Spring默认使用AspectJ切点语义。

  • 引入(Introduction): 声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被通知的对象上。例如,可以使用引入来使bean实现 IsModified接口, 以便简化缓存机制(在AspectJ社区,引入也被称为内部类型声明(inter))。

  • 目标对象(Target object): 被一个或者多个切面所通知的对象。也被称作被通知(advised)对象。既然Spring AOP是通过运行时代理实现的,那么这个对象永远是一个被代理(proxied)的对象。

  • AOP代理(AOP proxy):AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。

  • 织入(Weaving): 把切面连接到其它的应用程序类型或者对象上,并创建一个被被通知的对象的过程。这个过程可以在编译时(例如使用AspectJ编译器)、类加载时或运行时中完成。 Spring和其他纯Java AOP框架一样,是在运行时完成织入的。

    这些概念都太学术了,如果更简单的解释呢,其实非常简单:

    任何一个系统都是由不同的组件组成的,每个组件负责一块特定的功能,当然会存在很多组件是跟业务无关的,例如日志、事务、权限等核心服务组件,这些核心服务组件经常融入到具体的业务逻辑中,如果我们为每一个具体业务逻辑操作都添加这样的代码,很明显代码冗余太多,因此我们需要将这些公共的代码逻辑抽象出来变成一个切面,然后注入到目标对象(具体业务)中去,AOP正是基于这样的一个思路实现的,通过动态代理的方式,将需要注入切面的对象进行代理,在进行调用的时候,将公共的逻辑直接添加进去,而不需要修改原有业务的逻辑代码,只需要在原来的业务逻辑基础之上做一些增强功能即可。

说说你对IOC的理解?

	IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.
	IOC与大家熟知的依赖注入同理,. 这是一个通过依赖注入对象的过程 也就是说,它们所使用的对象,是通过构造函数参数,工厂方法的参数或这是从工厂方法的构造函数或返回值的对象实例设置的属性,然后容器在创建bean时注入这些需要的依赖。 这个过程相对普通创建对象的过程是反向的(因此称之为IoC),bean本身通过直接构造类来控制依赖关系的实例化或位置,或提供诸如服务定位器模式之类的机制。

​ 如果这个过程比较难理解的话,那么可以想象自己找女朋友和婚介公司找女朋友的过程。如果这个过程能够想明白的话,那么我们现在回答上面的问题:

1、谁控制谁:在之前的编码过程中,都是需要什么对象自己去创建什么对象,有程序员自己来控制对象,而有了IOC容器之后,就会变成由IOC容器来控制对象,
2、控制什么:在实现过程中所需要的对象及需要依赖的对象
3、什么是反转:在没有IOC容器之前我们都是在对象中主动去创建依赖的对象,这是正转的,而有了IOC之后,依赖的对象直接由IOC容器创建后注入到对象中,由主动创建变成了被动接受,这是反转
4、哪些方面被反转:依赖的对象

BeanFactory和ApplicationContext有什么区别

相同:

  • Spring提供了两种不同的IOC 容器,一个是BeanFactory,另外一个是ApplicationContext,它们都是Java interface,ApplicationContext继承于BeanFactory(ApplicationContext继承ListableBeanFactory。
  • 它们都可以用来配置XML属性,也支持属性的自动注入。
  • 而ListableBeanFactory继承BeanFactory),BeanFactory 和 ApplicationContext 都提供了一种方式,使用getBean(“bean name”)获取bean。

不同:

  • 当你调用getBean()方法时,BeanFactory仅实例化bean,而ApplicationContext 在启动容器的时候实例化单例bean,不会等待调用getBean()方法时再实例化。
  • BeanFactory不支持国际化,即i18n,但ApplicationContext提供了对它的支持。
  • BeanFactory与ApplicationContext之间的另一个区别是能够将事件发布到注册为监听器的bean。
  • BeanFactory 的一个核心实现是XMLBeanFactory 而ApplicationContext 的一个核心实现是ClassPathXmlApplicationContext,Web容器的环境我们使用WebApplicationContext并且增加了getServletContext 方法。
  • 如果使用自动注入并使用BeanFactory,则需要使用API注册AutoWiredBeanPostProcessor,如果使用ApplicationContext,则可以使用XML进行配置。
  • 简而言之,BeanFactory提供基本的IOC和DI功能,而ApplicationContext提供高级功能,BeanFactory可用于测试和非生产使用,但ApplicationContext是功能更丰富的容器实现,应该优于BeanFactory

简述spring bean的生命周期?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sVm0frc2-1624905178596)(images/bean的生命周期.png)]

1、实例化bean对象

​ 通过反射的方式进行对象的创建,此时的创建只是在堆空间中申请空间,属性都是默认值

2、设置对象属性

​ 给对象中的属性进行值的设置工作

3、检查Aware相关接口并设置相关依赖

​ 如果对象中需要引用容器内部的对象,那么需要调用aware接口的子类方法来进行统一的设置

4、BeanPostProcessor的前置处理

​ 对生成的bean对象进行前置的处理工作

5、检查是否是InitializingBean的子类来决定是否调用afterPropertiesSet方法

​ 判断当前bean对象是否设置了InitializingBean接口,然后进行属性的设置等基本工作

6、检查是否配置有自定义的init-method方法

​ 如果当前bean对象定义了初始化方法,那么在此处调用初始化方法

7、BeanPostProcessor后置处理

​ 对生成的bean对象进行后置的处理工作

8、注册必要的Destruction相关回调接口

​ 为了方便对象的销毁,在此处调用注销的回调接口,方便对象进行销毁操作

9、获取并使用bean对象

​ 通过容器来获取对象并进行使用

10、是否实现DisposableBean接口

​ 判断是否实现了DisposableBean接口,并调用具体的方法来进行对象的销毁工作

11、是否配置有自定义的destory方法

​ 如果当前bean对象定义了销毁方法,那么在此处调用销毁方法

spring支持的bean作用域有哪些?

① singleton

使用该属性定义Bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例。

② prototype

使用该属性定义Bean时,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。

③ request

该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于WebApplicationContext环境。

④ session

该属性仅用于HTTP Session,同一个Session共享一个Bean实例。不同Session使用不同的实例。

⑤ global-session

该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例。

Spring框架中的单例Bean是线程安全的么?

​ Spring中的Bean对象默认是单例的,框架并没有对bean进行多线程的封装处理

​ 如果Bean是有状态的,那么就需要开发人员自己来保证线程安全的保证,最简单的办法就是改变bean的作用域把singleton改成prototype,这样每次请求bean对象就相当于是创建新的对象来保证线程的安全

​ 有状态就是由数据存储的功能

​ 无状态就是不会存储数据,你想一下,我们的controller,service和dao本身并不是线程安全的,只是调用里面的方法,而且多线程调用一个实例的方法,会在内存中复制遍历,这是自己线程的工作内存,是最安全的。

​ 因此在进行使用的时候,不要在bean中声明任何有状态的实例变量或者类变量,如果必须如此,也推荐大家使用ThreadLocal把变量变成线程私有,如果bean的实例变量或者类变量需要在多个线程之间共享,那么就只能使用synchronized,lock,cas等这些实现线程同步的方法了。

spring框架中使用了哪些设计模式及应用场景

​ 1.工厂模式,在各种BeanFactory以及ApplicationContext创建中都用到了

​ 2.模版模式,在各种BeanFactory以及ApplicationContext实现中也都用到了

​ 3.代理模式,Spring AOP 利用了 AspectJ AOP实现的! AspectJ AOP 的底层用了动态代理

​ 4.策略模式,加载资源文件的方式,使用了不同的方法,比如:ClassPathResourece,FileSystemResource,ServletContextResource,UrlResource但他们都有共同的借口Resource;在Aop的实现中,采用了两种不同的方式,JDK动态代理和CGLIB代理

​ 5.单例模式,比如在创建bean的时候。

​ 6.观察者模式,spring中的ApplicationEvent,ApplicationListener,ApplicationEventPublisher

​ 7.适配器模式,MethodBeforeAdviceAdapter,ThrowsAdviceAdapter,AfterReturningAdapter

​ 8.装饰者模式,源码中类型带Wrapper或者Decorator的都是

spring事务的实现方式原理是什么?

​ 在使用Spring框架的时候,可以有两种事务的实现方式,一种是编程式事务,有用户自己通过代码来控制事务的处理逻辑,还有一种是声明式事务,通过@Transactional注解来实现。

​ 其实事务的操作本来应该是由数据库来进行控制,但是为了方便用户进行业务逻辑的操作,spring对事务功能进行了扩展实现,一般我们很少会用编程式事务,更多的是通过添加@Transactional注解来进行实现,当添加此注解之后事务的自动功能就会关闭,有spring框架来帮助进行控制。

​ 其实事务操作是AOP的一个核心体现,当一个方法添加@Transactional注解之后,spring会基于这个类生成一个代理对象,会将这个代理对象作为bean,当使用这个代理对象的方法的时候,如果有事务处理,那么会先把事务的自动提交给关系,然后去执行具体的业务逻辑,如果执行逻辑没有出现异常,那么代理逻辑就会直接提交,如果出现任何异常情况,那么直接进行回滚操作,当然用户可以控制对哪些异常进行回滚操作。

TransactionInterceptor

spring事务的隔离级别有哪些?

​ spring中的事务隔离级别就是数据库的隔离级别,有以下几种:

​ read uncommitted

​ read committed

​ repeatable read

​ serializable

​ 在进行配置的时候,如果数据库和spring代码中的隔离级别不同,那么以spring的配置为主。

spring的事务传播机制是什么?

​ 多个事务方法相互调用时,事务如何在这些方法之间进行传播,spring中提供了7中不同的传播特性,来保证事务的正常执行:

​ REQUIRED:默认的传播特性,如果当前没有事务,则新建一个事务,如果当前存在事务,则加入这个事务

​ SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,则以非事务的方式执行

​ MANDATORY:当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常

​ REQUIRED_NEW:创建一个新事务,如果存在当前事务,则挂起改事务

​ NOT_SUPPORTED:以非事务方式执行,如果存在当前事务,则挂起当前事务

​ NEVER:不使用事务,如果当前事务存在,则抛出异常

​ NESTED:如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样

​ NESTED和REQUIRED_NEW的区别:

​ REQUIRED_NEW是新建一个事务并且新开始的这个事务与原有事务无关,而NESTED则是当前存在事务时会开启一个嵌套事务,在NESTED情况下,父事务回滚时,子事务也会回滚,而REQUIRED_NEW情况下,原有事务回滚,不会影响新开启的事务

​ NESTED和REQUIRED的区别:

​ REQUIRED情况下,调用方存在事务时,则被调用方和调用方使用同一个事务,那么被调用方出现异常时,由于共用一个事务,所以无论是否catch异常,事务都会回滚,而在NESTED情况下,被调用方发生异常时,调用方可以catch其异常,这样只有子事务回滚,父事务不会回滚。

spring事务什么时候会失效?

​ 1、bean对象没有被spring容器管理

​ 2、方法的访问修饰符不是public

​ 3、自身调用问题

​ 4、数据源没有配置事务管理器

​ 5、数据库不支持事务

​ 6、异常被捕获

​ 7、异常类型错误或者配置错误

什么的是bean的自动装配,它有哪些方式?

​ bean的自动装配指的是bean的属性值在进行注入的时候通过某种特定的规则和方式去容器中查找,并设置到具体的对象属性中,主要有五种方式:

​ no – 缺省情况下,自动配置是通过“ref”属性手动设定,在项目中最常用
​ byName – 根据属性名称自动装配。如果一个bean的名称和其他bean属性的名称是一样的,将会自装配它。
​ byType – 按数据类型自动装配,如果bean的数据类型是用其它bean属性的数据类型,兼容并自动装配它。
​ constructor – 在构造函数参数的byType方式。
​ autodetect – 如果找到默认的构造函数,使用“自动装配用构造”; 否则,使用“按类型自动装配”。

spring、springmvc、springboot的区别是什么?

​ spring和springMvc:

  1. spring是一个一站式的轻量级的java开发框架,核心是控制反转(IOC)和面向切面(AOP),针对于开发的WEB层(springMvc)、业务层(Ioc)、持久层(jdbcTemplate)等都提供了多种配置解决方案;

  2. springMvc是spring基础之上的一个MVC框架,主要处理web开发的路径映射和视图渲染,属于spring框架中WEB层开发的一部分;

springMvc和springBoot:

1、springMvc属于一个企业WEB开发的MVC框架,涵盖面包括前端视图开发、文件配置、后台接口逻辑开发等,XML、config等配置相对比较繁琐复杂;

2、springBoot框架相对于springMvc框架来说,更专注于开发微服务后台接口,不开发前端视图,同时遵循默认优于配置,简化了插件配置流程,不需要配置xml,相对springmvc,大大简化了配置流程;

总结:

1、Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring的ioc、aop等. ioc 提供了依赖注入的容器, aop解决了面向横切面编程,然后在此两者的基础上实现了其他延伸产品的高级功能;

2、springMvc主要解决WEB开发的问题,是基于Servlet 的一个MVC框架,通过XML配置,统一开发前端视图和后端逻辑;

3、由于Spring的配置非常复杂,各种XML、JavaConfig、servlet处理起来比较繁琐,为了简化开发者的使用,从而创造性地推出了springBoot框架,默认优于配置,简化了springMvc的配置流程;但区别于springMvc的是,springBoot专注于单体微服务接口开发,和前端解耦,虽然springBoot也可以做成springMvc前后台一起开发,但是这就有点不符合springBoot框架的初衷了;

以上是关于面试题打卡——第九天的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥集训(附加面试题)第九天

蓝桥集训(附加面试题)第九天

面试题打卡——第十天

每日算法&面试题,大厂特训二十八天——第九天(位运算)

冲刺大厂每日算法&面试题,动态规划21天——第九天

面试题打卡第十天(前端 优化打包构建速度)