栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java后端面试题攻略查漏补缺(二)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java后端面试题攻略查漏补缺(二)

1 怎么查看MySQL的执行计划

只需要在我们的查询语句前加 explain/desc即可

例如,查询执行计划

EXPLAIN SELECt * FROM SYS_USER WHERe USER_ID = 1

结果如下:

其中比较重要需要关注的几个点是:

1)id

查询执行顺序:
id 值相同时表示从上向下执行
id 值相同被视为一组
如果是子查询,id 值会递增,id 值越高,优先级越高
id为NULL最后执行。

2)type

显示连接使用了何种类型。从最好到最差的连接类型为 system > const > eq_reg > ref > range > index > ALL。

一般来说,得保证查询达到range级别,最好达到ref。

3)key

实际使用的索引。如果为 NULL,则没有使用索引。

4)ref

显示索引的哪一列被使用了,如果可能的话,是一个常量 const。

5)Extra

MYSQL 如何解析查询的额外信息。

2 Springboot自动装配原理是什么?

自动装配大致流程是通过@SpringBootApplication进行实现,这个注解声明在SpringBoot的启动类上。

1.SpringBoot启动类

2、@SpringBootApplication注解

SpringBoot启动类=>@SpringBootApplication

3、@SpringBootConfiguration注解

SpringBoot启动类=>@SpringBootApplication=>@SpringBootConfiguration

通过@SpringBootConfiguration注解标识SpringBootApplication是一个SpringBoot配置类

@AliasFor注解用于为注解属性声明别名(@SpringBootApplication注解也有@AliasFor注解)

4、@EnableAutoConfiguration注解

SpringBoot启动类=>@SpringBootApplication=>@EnableAutoConfiguration

通过@EnableAutoConfiguration注解实现自动装配

5、@AutoConfigurationPackage注解SpringBoot启动类=>@SpringBootApplication=>@EnableAutoConfiguration=>@AutoConfigurationPackage

通过@AutoConfigurationPackage注解将添加该注解的类所在的package作为自动配置package进行管理

通过AutoConfigurationPackages工具类获取自动配置package列表,也就是说当SpringBoot应用启动时默认会将启动类所在的package作为自动配置的package

6、@EnableAutoConfiguration注解最重要的是AutoConfigurationImportSelector.class,将需要装配的类装配到IoC容器中,下面重点分析一下这个类的实现

1)selectImport()

AutoConfigurationImportSelector中的selectImport方法是自动装配的核心实现,它主要是读取META-INF/spring.factories文件,经过去重、过滤,返回需要装配的配置类集合。

2)selectImport()=>AutoConfigurationMetadataLoader.loadMetadata()

在META-INF/spring-autoconfigure-metadata.properties文件内容属性中看可以看到配置了很多组件的键值对属性。

3)selectImport() => AutoConfigurationMetadataLoader.loadMetadata() => PropertiesLoaderUtils.loadProperties()

最后创建并返回的AutoConfigurationMetadata对象

4)selectImport() => getAutoConfigurationEntry()

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
		// 再次判断自动装配开关是否打开
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		// 获取 @EnableAutoConfiguration注解的 exclude 和 excludeName 属性
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		// 获取该依赖下的 spring.factories配置文件的内容
		List configurations = getCandidateConfigurations(annotationMetadata, attributes);
		// 移除重复的数据
		configurations = removeDuplicates(configurations);
		//获取spring.autoconfigure.exclude 配置文件的内容并与exclude 和 excludeName 属性合并到一个集合中
		Set exclusions = getExclusions(annotationMetadata, attributes);
		//检验configurations中需要排除的内容
		checkExcludedClasses(configurations, exclusions);
		//检验configurations中需要排除的内容
		configurations.removeAll(exclusions);
		// 再次对configurations中的内容进行过滤
		configurations = filter(configurations, autoConfigurationMetadata);
		// 关闭spring监听器中的自动装配事件
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

getAttributes方法就是获取 @EnableAutoConfiguration注解的 exclude 和 excludeName 属性

5)selectImport() => getAutoConfigurationEntry() => getCandidateConfigurations() =>SpringFactoriesLoader.loadFactoryNames()

总结:

1)通过注解@SpringBootApplication=>@EnableAutoConfiguration=>@Import({AutoConfigurationImportSelector.class})实现自动装配

2)AutoConfigurationImportSelector类中重写了ImportSelector中selectImports方法,批量返回需要装配的配置类

3)通过Spring提供的SpringFactoriesLoader机制,扫描classpath下的META-INF/spring.factories文件,读取需要自动装配的配置类

4)依据条件筛选的方式,把不符合的配置类移除掉,最终完成自动装配

3 SpringMVC执行流程是什么?

1、 用户向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。
2、DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)
3、DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller
4、HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet
5、DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,然后返回真正的视图。
6、DispatcherServlet将模型数据填充到视图中
7、DispatcherServlet将结果响应给用户

4 Spring事务传播机制是什么?

第一类是支持当前事务,有3种

1)REQUIRED (必须有)

如果当前方法没有事务,新建一个事务,如果已经存在一个事务中,则加入到这个事务中。

2)SUPPORTS (可有可无)

支持当前事务,如果当前没有事务,就以非事务方式执行

3)MANDATORY (强制)

使用当前的事务,如果当前没有事务,就抛出异常。

第二类是不支持当前事务,有3种

4)REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

5)NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

6)NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

第三类:

7)NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

5 Spring 框架中单例Bean是否线程安全?

Spring框架中的单例Bean默认是单例模式,不是线程安全的。Spring框架并没有对单例Bean进行多线程的封装处理。
关于线程是否安全,可以从Bean的状态来考虑是否要进行处理。

有状态的Bean就是有数据存储功能,例如VO视图对象,无状态的Bean是不会保存数据的,例如DAO类。

实际上大部分时候Spring Bean都是无状态的,因此某种程度上来说,Bean也是安全的,但如果Bean有状态的话,那就要开发者自己去保证线程安全了,可以通过把Bean的作用域改为“prototype”,这样可以保证线程安全。

不要在bean中声明任何有状态的实例变量或类变量,如果必须如此,那么就使用ThreadLocal把变量变为线程私有的,如果bean的实例变量或类变量需要在多个线程之间共享,那么就只能使用synchronized、lock、CAS等这些实现线程同步的方法了。

6 Spring中使用了哪些设计模式及应用场景

1.工厂模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。

2.代理模式:Spring AOP功能的实现。

3.单例模式:Spring中的bean默认都是单例的。

4.模板模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。

5.包装器模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。

6.观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。

7.适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。

8.策略模式:Spring框架的资源访问Resource接口,该接口提供了更强的资源访问能力,Spring框架本身大量使用了Resource接口来访问底层资源。

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

1.DEFAULT:采用 DB 默认的事务隔离级别

2.READ_UNCOMMITTED:读未提交

3.READ_COMMITTED:读已提交

4.REPEATABLE_READ:可重复读

5.SERIALIZABLE:串行化

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

在使用Spring框架时,有两种使用事务的方式。一种是编程式的,一种是声明式(@Transactional注解)。

首先,事务这个概念是数据库层面的,Spring只是基于数据库中的事务进行了扩展,以及提供了一些能让程序员更加方便操作事务的方式。

比如我们可以通过在某个方法上面增加@Transactional注解,就可以开启事务,这个方法中所有的sql都会在一个事务中执行,统一成功或失败。

在一个方法上加了@Transactional注解后,Spring会基于这个类生成一个代理对象,会将这个代理对象作为bean。

当在使用这个代理对象的方法时,如果这个方法上存在@Transactional注解,那么代理逻辑会先把事务的自动提交设置为false,然后再去执行原本的业务逻辑方法,如果执行中没有出现异常,那么代理逻辑就会将事务提交,如果出现了异常,那么就会将事务进行回滚。

当然,针对哪些异常回滚事务是可以配置的,可以利用@Transactional注解中的rollbackFor属性进行配置,默认情况会对RuntimeException和Error进行回滚。

9 Spring事务什么时候会失效?

1)访问权限问题

Java的访问权限主要有三种:private、protected、public,它们的权限从左到右,依次变大,spring要求被代理方法必须是public的。如果我们在开发过程中,把有某些事务方法,定义了错误的访问权限,就会导致事务功能出问题

2)方法是final修饰的

当某个方法被final修饰时,子类是无法继承和重载的,事务是基于动态代理去实现的,如果某个方法用final修饰了,那么在它的代理类中,就无法重写该方法,而添加事务功能。

3)未被Spring管理

使用spring事务的前提是:对象要被spring管理,需要创建bean实例。比如,你开发了一个Service类但忘了加@Service注解又或者XML里面配置纳入Spring管理的包文件路径配置错误等。

4)错误的传播特性

我们在使用@Transactional注解时,是可以指定propagation参数的。该参数的作用是指定事务的传播特性

5)自己吞了异常

事务不会回滚,最常见的问题是:开发者在代码中手动try…catch了异常。

这种情况下spring事务当然不会回滚,因为开发者自己捕获了异常,又没有手动抛出,换句话说就是把异常吞掉了。

如果想要spring事务能够正常回滚,必须抛出它能够处理的异常。如果没有抛异常,则spring认为程序是正常的。

6)手动抛了别的异常

即使开发者没有手动捕获异常,但如果抛的异常不正确,spring事务也不会回滚。

因为spring事务,默认情况下只会回滚RuntimeException(运行时异常)和Error(错误),对于普通的Exception(非运行时异常),它不会回滚。

7)自定义了回滚异常

@Transactional注解声明事务时,有时我们想自定义回滚的异常,spring也是支持的。可以通过设置rollbackFor参数,来完成这个功能。

@Service
 public class OrderService {
     @Transactional(rollbackFor = BusinessException.class)
     public void add(OrderVO orderVO) {
         saveData(orderVO);
   }
}

如上如果程序报错了,抛了SqlException、NullPointerException等异常。而BusinessException是我们自定义的异常,报错的异常不属于BusinessException,所以事务也不会回滚。

8)方法内部调用

有时候我们需要在某个Service类的某个方法中,调用另外一个事务方法。

 @Service
  public class OrderService {
    @Transactional
      public void add(OrderVO orderVO) {
           saveData(orderVO);
    }
  
    @Transactional
    public void saveData(OrderVO orderVO) {
          doSameThing();
   }
}

我们看到在事务方法add中,直接调用事务方法saveData。saveData方法拥有事务的能力是因为Spring Aop生成代理了对象,但是这种方法直接调用了this对象的方法,所以saveData方法不会生成事务。

由此可见,在同一个类中的方法直接内部调用,会导致事务失效。

10 Spring支持的bean作用域有哪些?

Spring容器中bean的作用域可以分为5个范围:

1)singleton

默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。

2)prototype

为每一个bean请求提供一个实例。

3)request

为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。

4)session

与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。

5)global-session

全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/831218.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号