Spring Boot面试题

什么是 Spring Boot?

Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,约定大于配置,简化了繁重的配置,提供了各种启动器,开发者能快速上手。很容易就能创建一个独立的,产品级别的应用。

背景:

J2EE笨重的开发、繁多的配置、低下的开发效率、复杂的部署流程、第三方技术集成难度大。

Spring Boot的优点:

  • 开箱即用,远离繁琐的配置。因为它无需配置XML,也无代码生成器生成代码,spring内置了非常多的 API, 只需要在配置文件中打开不同的开关即可触发不同的自动配置类。所以它容易上手,能够提升开发效率,为 Spring 开发提供一个更快、更广泛的入门体验。
  • 快速创建独立运行的Spring项目以及与主流框架集成
  • 使用嵌入式的Servlet容器,应用无需打成WAR包,这样可以更加轻松地开发和测试web应用程序。比如Tomcat就是一个Servlet容器,以前需要将项目打包成war包,放到tomcat中运行,现在可以不需要tomcat运行环境,仅需打包成一个Jar包,Jar包中内置了一个运行环境,使用Java -jar的命令就可以运行。
  • starters 自动依赖与默认版本控制,可以避免大量的 Maven 导入和各种版本冲突。
  • 提供了一系列大型项目通用的非业务性功能,例如:内嵌服务器、安全管理、运行数据监控、运行状况检查和外部化配置等。

Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?

启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:

@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。

@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能:@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。

@ComponentScan:Spring组件扫描。

Spring Boot 自动配置原理是什么?

注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心,@EnableAutoConfiguration 给容器导入META-INF/spring.factories 里定义的自动配置类。筛选有效的自动配置类。

Spring Boot中存现大量的 xxxAutoConfiguration 类,结合对应的 xxxProperties.java 读取配置文件进行自动配置功能。我们在配置文件中打开相应的开关,Spring Boot就会将这个这个场景需要的所有组件都注册到容器中,并配置好。

Spring Boot 有哪些配置加载方式?

在 Spring Boot 里面,可以使用以下几种方式来加载配置。

1)properties文件;

2)YAML文件;

3)系统环境变量;

4)命令行参数;

等等……

什么是 YAML?

YAML 是一种人类可读的数据序列化语言。它通常用于配置文件。与属性文件相比,如果我们想要在配置文件中添加复杂的属性,YAML 文件就更加结构化,而且更少混淆。可以看出 YAML 具有分层配置数据。

YAML 配置的优势在哪里 ?

YAML 现在可以算是非常流行的一种配置文件格式了,无论是前端还是后端,都可以见到 YAML 配置。那么 YAML 配置和传统的 properties 配置相比到底有哪些优势呢?

  1. 配置结构化且有序,在一些特殊的场景下,配置有序很关键
  2. 支持数组,数组中的元素可以是基本数据类型也可以是对象
  3. 简洁

相比 properties 配置文件,YAML 还有一个缺点,就是不支持 @PropertySource 注解导入自定义的 YAML 配置。

Spring Boot 是否可以使用 XML 配置 ?

Spring Boot 推荐使用 Java 配置而非 XML 配置,但是 Spring Boot 中也可以使用 XML 配置,通过 @ImportResource 注解可以引入一个 XML 配置。

spring boot 核心配置文件是什么?bootstrap.properties 和 application.properties 有何区别 ?

单纯做 Spring Boot 开发,可能不太容易遇到 bootstrap.properties 配置文件,但是在结合 Spring Cloud 时,这个配置就会经常遇到了,特别是在需要加载一些远程配置文件的时侯。

spring boot 核心的两个配置文件:

什么是 Spring Profiles?

Spring Profiles 允许用户根据配置文件(dev,test,prod 等)来注册 bean。因此,当应用程序在开发中运行时,只有某些 bean 可以加载,而在 PRODUCTION中,某些其他 bean 可以加载。假设我们的要求是 SwaggerOpenApi的前身,是一个书写API文档的规范)文档仅适用于 QA 环境,并且禁用所有其他文档。这可以使用配置文件来完成。Spring Boot 使得使用配置文件非常简单。

如何在自定义端口上运行 Spring Boot 应用程序?

为了在自定义端口上运行 Spring Boot 应用程序,您可以在application.properties 中指定端口。server.port = 8090

安全

如何实现 Spring Boot 应用程序的安全性?

为了实现 Spring Boot 的安全性,我们使用 spring-boot-starter-security 依赖项,并且必须添加安全配置。它只需要很少的代码。配置类将必须扩展WebSecurityConfigurerAdapter 并覆盖其方法。

比较一下 Spring Security 和 Shiro 各自的优缺点 ?

由于 Spring Boot 官方提供了大量的非常方便的开箱即用的 Starter ,包括 Spring Security 的 Starter ,使得在 Spring Boot 中使用 Spring Security 变得更加容易,甚至只需要添加一个依赖就可以保护所有的接口,所以,如果是 Spring Boot 项目,一般选择 Spring Security 。当然这只是一个建议的组合,单纯从技术上来说,无论怎么组合,都是没有问题的。Shiro 和 Spring Security 相比,主要有如下一些特点:

  1. Spring Security 是一个重量级的安全管理框架;Shiro 则是一个轻量级的安全管理框架
  2. Spring Security 概念复杂,配置繁琐;Shiro 概念简单、配置简单
  3. Spring Security 功能强大;Shiro 功能简单
注:Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理

什么是 CSRF 攻击?

跨站请求伪造(Cross-site request forgery,CSRF),是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。通俗的说就是攻击者自己写了一个网页,在这个网页的各个组件中都加了对某个银行账户进行转账或者购物网站进行消费的请求脚本,这样只要用户进入攻击者写的网页并点击任何一个组件,如果用户刚好在不久前访问过组件中伪造的目标请求网站,这样一旦这个组件被点击,就会向目标网站发起一个请求,这个请求就会被成功的伪造,从而让用户损失一些钱财。

防范手段

1、 检查 Referer 首部字段
Referer 首部字段位于 HTTP 报文中,用于标识请求来源的地址。服务器会检查这个首部字段并要求请求来源的地址在同一个域名下,可以极大的防止 CSRF 攻击。
这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的 Referer 字段。虽然 HTTP 协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其 Referer 字段的可能。
2、添加校验 Token(Spring Security采用的方式)
在访问敏感数据请求时,要求用户浏览器提供不保存在 Cookie 中,并且攻击者无法伪造的数据作为校验。例如服务器生成随机数并附加在表单的hidden标签中,并要求客户端回传这个随机数。如果是异步请求,需要在页面通过<meta>标签把token传递给用来处理异步请求的 js 。
3、输入验证码
因为 CSRF 攻击是在用户无意识的情况下发生的,所以要求用户输入验证码可以让用户知道自己正在做的操作

Spring Boot 中的监视器是什么

因为SpringBoot简单配置即可使用,对底层封装的比较严实,所以发现错误不太好找bug。所以我们需要监控项目的某些状态信息来方便找bug。Spring Boot提供您的项目监控组件是Spring Boot Actuator。    
    - Endpoints:监控应用的入口,Spring Boot内置很多端点,通过@EndPoints()注解即可自定义端点
    - 监控方式:HTTP 或者 JMX
    - 访问路径:例如:"/actuator/health"
    - 注意事项:按需配置暴露的端点(一共20多个端点)、需要通过Spring Security对所有端点进行权限控制,只有管理员可以访问,否则任何人都可以访问底层的代码,很不安全。
比如下面定义了一个id为 "database"的端点,用户只要用 项目名+/actuator/database即可访问这个项目的数据库连接转态信息
Spring Boot面试题

什么是 Spring Data ?

Spring Data 是 Spring 的一个子项目。用于简化数据库访问,支持NoSQL 和 关系数据存储。其主要目标是使数据库的访问变得方便快捷。Spring Data 具有如下特点:

SpringData 项目支持 NoSQL 存储:

  1. MongoDB (文档数据库)
  2. Neo4j(图形数据库)
  3. Redis(键/值存储)
  4. Hbase(列族数据库)
  5. Elasticsearch

SpringData 项目所支持的关系数据存储技术:

  1. JDBC
  2. JPA(Java Persistence API的简称,中文名Java持久层API)

Spring Data Jpa 致力于减少数据访问层 (DAO) 的开发量. 开发者唯一要做的,就是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成!Spring Data JPA 通过规范方法的名字,根据符合规范的名字来确定方法需要实现什么样的逻辑。

什么是 Apache Kafka?

Apache Kafka 是一个分布式发布 - 订阅消息系统。它是一个可扩展的,容错的发布 - 订阅消息系统,它使我们能够构建分布式应用程序。这是一个 Apache 顶级项目。Kafka 适合离线和在线消息消费。

什么是 Swagger?你用 Spring Boot 实现了它吗?

Swagger 广泛用于可视化 API,使用 Swagger UI 为前端开发人员提供在线沙箱。Swagger 是用于生成 RESTful Web 服务的可视化表示的工具,规范和完整框架实现。它使文档能够以与服务器相同的速度更新。当通过 Swagger 正确定义时,消费者可以使用最少量的实现逻辑来理解远程服务并与其进行交互。因此,Swagger消除了调用服务时的猜测。

注:

沙箱技术即是一bai个虚du拟系统程序,zhi允许你在沙盘环dao境中运行浏览器或其他zhuan程序,因此运行所产shu生的变化可以随后删除。它创造了一个类似沙盒的独立作业环境,在其内部运行的程序并不能对硬盘产生永久性的影响。其为一个独立的虚拟环境,可以用来测试不受信任的应用程序或上网行为。
沙箱是一种按照安全策略限制程序行为的执行环境。早期主要用于测试可疑软件等,比如黑客们为了试用某种病毒或者不安全产品,往往可以将它们在沙箱环境中运行。

前后端分离,如何维护接口文档 ?

前后端分离开发日益流行,大部分情况下,我们都是通过 Spring Boot 做前后端分离开发,前后端分离一定会有接口文档,不然会前后端会深深陷入到扯皮中。一个比较笨的方法就是使用 word 或者 md 来维护接口文档,但是效率太低,接口一变,所有人手上的文档都得变。在 Spring Boot 中,这个问题常见的解决方案是 Swagger ,使用 Swagger 我们可以快速生成一个接口文档网站,接口一旦发生变化,文档就会自动更新,所有开发工程师访问这一个在线网站就可以获取到最新的接口文档,非常方便。

Spring Boot 打成的 jar 和普通的 jar 有什么区别 ?

Spring Boot 项目最终打包成的 jar 是可执行 jar ,这种 jar 可以直接通过 java -jar xxx.jar 命令来在内置Servlet容器中运行,这种 jar 不可以作为普通的 jar 被其他项目依赖,即使依赖了也无法使用其中的类。

Spring Boot 的 jar 无法被其他项目依赖,主要还是他和普通 jar 的结构不同。普通的 jar 包,解压后直接就是包名,包里就是我们的代码,而 Spring Boot 打包成的可执行 jar 解压后,在 BOOT-INFclasses 目录下才是我们的代码,因此无法被直接引用。如果非要引用,可以在 pom.xml 文件中增加配置,将 Spring Boot 项目打包成两个 jar ,一个可执行,一个可引用。

 

如何使用 Spring Boot 实现异常处理?

通过@ControllerAdvice、@ExceptionHandler、@ModelAttribute、@DataBinder 4个注解来统一处理控制器类抛出的所有异常。

@ControllerAdvice:用于修饰类,表示该类是Controller的全局配置类。

 在此类中,可以对Controller进行如下三种全局配置:异常处理方案、绑定数据方案、绑定参数方案。

 @ExceptionHandler(异常处理方案):用于修饰方法,该方法会在Controller出现异常后被调用,用于处理捕获到的异常。
 @ModelAttribute(绑定数据方案):用于修饰方法,该方法会在Controller方法执行前被调用,用于为Model对象绑定参数。
 @DataBinder(绑定参数方案): 用于修饰方法,该方法会在Controller方法执行前被调用,用于绑定参数的转换器。

Spring Boot 中如何实现定时任务 ?

在 Spring Boot 中使用定时任务主要有两种不同的方式,一个就是使用 Spring 中的 @Scheduled 注解,这个注解使用的是ThreadPoolTaskScheduler来实现的。在需要定时执行的方法上加上 @Scheduled 注解来实现。编码简单。
另一个则是使用第三方框架 Quartz。实现过程中需要按照 Quartz 的方式,定义 Job 和 Trigger。编码复杂。

其中@Scheduled方式在分布式环境中会有重复执行的问题,但是Quartz在分布式环境中没问题,因为Quartz会创建专有数据库,如果发现数据库中有相同任务在执行会放弃执行当前任务,这样任务就不会被重复执行。

参考: