2021金九银十的面经之JAVA开源框架

基础篇

1、springcloud 的组件都用过哪些?
  a. Eureka 组件
  Eureka 主要是作用就是服务注册与服务发现机制,实现微服务的自动化管理。
  Eureka Server
  Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
  Eureka Server本身也是一个服务,默认情况下会自动注册到Eureka注册中心。
  如果搭建单机版的Eureka Server注册中心,则需要配置取消Eureka Server的自动注册逻辑。毕竟当前服务注册到当前服务代表的注册中心中是一个说不通的逻辑。
  Eureka Server通过Register、Get、Renew等接口提供服务的注册、发现和心跳检测等服务。
  Eureka Client
  Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
  Eureka Client分为两个角色,分别是:Application Service(Service Provider)和Application Client(Service Consumer)
  1>Application Service
  服务提供方,是注册到Eureka Server中的服务。
  2> Application Client
  服务消费方,通过Eureka Server发现服务,并消费。
  在这里,Application Service和Application Client不是绝对上的定义,因为Provider在提供服务的同时,也可以消费其他Provider提供的服务;Consumer在消费服务的同时,也可以提供对外服务。
  b.Feign 组件
  Spring Cloud 为了简化服务间的调用,在Ribbon的基础上进行了进一步的封装。单独抽出了一个组件,就是Spring Cloud Feign。在引入Spring Cloud Feign后,我们只需要创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。
  Spring Cloud Feign具备可插拔的注解支持,并扩展了Spring MVC的注解支持。
  其实Feign底层主要是靠动态代理来实现这整个服务的调用过程的。
  主要逻辑如下:
  1>如果一个接口上定义了@FeignClient注解,Feign就会根据这个接口生成一个动态代理类。
  2> 如果调用方,在调用这个定义了@FeignClient注解的接口时,本质上是会调用Feign生成的代理类。
  3>Feign生成的动态代理类,会根据具体接口方法中的@RequestMapping等注解,来动态构造出需要请求的服务地址。
  c.gateway
  gateway能做什么?
  反向代理;鉴权;流量控制;熔断;日志监控
  它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,。
  三大核心概念
  Route (路由): 路由是构建网关的基本模块,它由 ID,目标 URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
  Predicate(断言):参考的是 java8 的 java.util.function.Predicate 开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
  Filter(过滤):指的是 Spring 框架中 GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
  工作流程
  1>客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。
  2>Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
  3>过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前( “pre” )或之后( “post” )执行业务逻辑。
  4>Filter 在 “pre” 类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在 "post” 类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。
  核心逻辑是:路由转发 + 执行过滤器链
2.什么是spring boot?它的优点是什么?
  Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重xml的配置,提供了各种启动器,在运行过程中自定配置, 开发者能快速上手。
  优点是:a.大大简化了像传统SSM 项目 那样复杂的配置,约定大于配置
      b.内嵌tomcat容器,可独立运行,无需部署war文件
      c.大量的自动配置,简化开发
3.Spring Boot 的核心配置文件有哪几个?它们的区别是什么?
  Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。
  application 配置文件 主要用于 Spring Boot 项目的自动化配置。
  bootstrap 配置文件有以下几个应用场景:
  a.使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
  b.一些固定的不能被覆盖的属性;
  c.一些加密/解密的场景;
3.Spring Boot 的配置文件有哪几种格式?它们有什么区别?
  .properties 和 .yml,它们的区别主要是书写格式不同。
  1).properties
  app.user.name = javastack
  2).yml
  app:
   user:
    name: javastack
4.SpringBoot的核心注解是哪个?它主要由哪几个注解组成的?
  启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
  @SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
  @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能:
  @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
  @ComponentScan:Spring组件扫描。
  拓展:EnableAutoConfiguration是如何实现自动配置功能?
5.运行SpringBoot有哪几种方式?
  a.打包用命令或者放到容器中运行
  b.用 Maven/ Gradle 插件运行
  c.直接执行 main 方法运行
6.Spring Boot 自动配置原理是什么?
  注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。
7.你如何理解 Spring Boot 中的 Starters?
  Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包。如你想使用 Spring JPA 访问数据库,只要加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。
  Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。
8.Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?
  Spring Boot 支持 Java Util Logging, Log4j2, Logback 作为日志框架,如果你使用 Starters 启动器,Spring Boot 将使用 Logback 作为默认日志框架
9.Spring Boot 如何定义多套不同环境配置?
  提供多套配置文件,如:
  applcation.properties
  application-dev.properties
  application-test.properties
  application-prod.properties
  要指定使用哪套环境,需要使用Profile,Spring Boot可以对不同环境或者指令来读取不同的配置文件,在yml中配置即可,jar包运行也时可指定。
  java -jar xx.jar --spring.profiles.active=prod
10.如何重新加载Spring Boot上的更改,而无需重新启动服务器?
  这可以使用DEV工具来实现。通过这种依赖关系,您可以节省任何更改,嵌入式tomcat将重新启动。
  Spring Boot有一个开发工具(DevTools)模块,它有助于提高开发人员的生产力。Java开发人员面临的一个主要挑战是将文件更改自动部署到服务器并自动重启服务器。
开发人员可以重新加载Spring Boot上的更改,而无需重新启动服务器。这将消除每次手动部署更改的需要。Spring Boot在发布它的第一个版本时没有这个功能。
  这是开发人员最需要的功能。DevTools模块完全满足开发人员的需求。该模块将在生产环境中被禁用。它还提供H2数据库控制台以更好地测试应用程序。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>

11如何实现Spring Boot应用程序的安全性?
  为了实现Spring Boot的安全性,我们使用 spring-boot-starter-security依赖项,并且必须添加安全配置。它只需要很少的代码。配置类将必须扩展WebSecurityConfigurerAdapter并覆盖其方法。
12.如何使用Spring Boot实现分页和排序?
  使用Spring Boot实现分页非常简单。使用Spring Data-JPA可以实现将可分页的  org.springframework.data.domain.Pageable传递给存储库方法
  拓展:我做的项目中 分页是如何实现的?
13. Spring @RestController、@Controller区别
  用@Controller,返回的是页面;@Controller加上@ResponseBody,返回的是JSON、XML或其他文本。
  用@RestController,意味着这个Controller的所有方法上面都加了@ResponseBody,不论你在每个方法前加、或不加@ResponseBody,都一样。所以这种Controller不会返回页面。
14、springmvc分三层 控制层 业务层 持久层 用到的注解
  @Controller控制层,就是我们的action层
  @Service 业务逻辑层,就是我们的service或者manager层
  @Repository 持久层,就是我们常说的DAO层
  而@Component (字面意思就是组件),它在你确定不了事哪一个层的时候使用。
其实,这四个注解的效果都是一样的,spring都会把它们当做需要注入的Bean加载在上下文中;
   a控制层
  @Controller // 注释为controller
  @RequestMapping("/login")
  public class LoginAction {
   b.服务层
  @Autowired
  @Qualifier(“userService”) //注释指定注入 Bean
   private IUserService userService;
  @Service(“userService”)
  public class UserServiceImpl implements IUserService {
  @Autowired
  @Qualifier(“userDao”)
  private IUserDao userDao;
  c.持久层
  @Repository(“userDao”)

public class UserDaoImpl implements IUserDao {
 private static Logger logger = LoggerFactory.getLogger(UserDaoImpl.class);
 private DataSource dataSource;  
    private JdbcTemplate template;  
 @Autowired  
    public UserDaoImpl(DataSource dataSource){  
        this.dataSource= dataSource;  
        template = new JdbcTemplate(this.dataSource);  
    }

15、spring Aop实际项目中使用过么,怎么用的?
  AOP:是一种面向切面的编程范式,是一种编程思想,旨在通过分离横切关注点,提高模块化,可以跨越对象关注点。Aop的典型应用即spring的事务机制,日志记录。
实际项目中用于做了安全性的控制,记录用户操作,若写一个方法去保存操作,则需要每次手动去调用。由于是非业务性的操作,并且大量的重复操作,Spring AOP就能很好的解决这个问题。
  a,创建自定义注解。
  b,在要记录的方法中加上自定义注解。
  c,拦截浏览器发送的请求。
  d,加载访问的类
  e,获取这个方法的方法名,然后根据AOP拦截的请求进行判断是否是同一个。
  f,判断这个拦截的方法有没有自定义的注解。
  g,获取注解的值,然后写入数据库。
拓展:我们的项目中是如何使用AOP的?AOP的底层实现原理是什么?
16、mybatis 写实现类,持久层 主要写哪些东西 ?
  a.在mapper.xml中,namespace等于mapper接口地址。
  b.mapper.java接口中的方法名和mapper.xml中的statement的ID一直
  c.mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致
  d.mapper.java接口中的方法返回值类型和mapper.xml的statement的resultType指定的类型一致
  e.编写UserMapper.java
  f.编写UserMapper.xml
17、mybatis里面的标签
  select:映射查询语句
  insert:映射插入语句
  update:映射更新语句
  delete:映射删除语句
  sql:可以重用的sql代码块
  resultMap:最复杂,最有力量的元素,用来描述如何从数据库结果集中加载你的对象
cache:配置给定命名空间的缓存
cache-ref:从其他命名空间引用缓存配置
  标签中有对应的属性,
**18、mybatis KaTeX parse error: Expected 'EOF', got '#' at position 2: 和#̲ 的区别?**  &… {} 则将传入的参数拼接到Sql上去执行,一般用于表名和字段名参数,$ 所对应的参数应该由服务器端提供,前端可以用参数进行选择,避免 Sql 注入的风险。
  #{} 在mybatis 做sql转换 会变成 占位符 ? ,PreparedStatement
19 springmvc 中 @RequestParam和@PathVariable的区别和使用
  请求路径上的区别:很明显一个是 https:url ?键值对,一个是https:url /参数 ,区别很明显
  @PathVariable主要用于接收http://host:port/path/{参数值}数据。@RequestParam主要用于接收http://host:port/path?参数名=参数值数据,这里后面也可以不跟参数值。
  @RequestParam用于获取参数,可获取?username="sss"这种?后面的参数值
20、SpringMVC的执行流程?
  请求旅程的第一站是Spring的DispatcherServlet。与大多数基于Java的Web框架一样,Spring MVC所有的请求都会通过一个前端控制器(front controller)Servlet。前端控制器是常用的Web应用程序模式,在这里一个单实例的Servlet将请求委托给应用程序的其他组件来执行实际的处理。在Spring MVC中,DispatcherServlet就是前端控制器。
  DispatcherServlet的任务是将请求发送给控制器(Controller)。控制器是一个用于处理请求的Spring组件。在典型的应用程序中可能会有多个控器,DispatcherServlet需要知道应该将请求发送给哪个控制器。所DispatcherServlet以会查询一个或多个处理器映射(HandlerMapping) 来确定请求的下一站在哪里。处理器映射会根据请求所携带的URL信息来进行决策。
  一旦选择了合适的控制器,DispatcherServlet会将请求发送给选中的控制器 。到了控制器,请求会卸下其负载(用户提交的信息)并耐心等待控制器处理这些信息。(实际上,设计良好的控制器本身只处理很少甚至不处理工作,而是将业务逻辑委托给一个或多个服务对象进行处理。)
控制器在完成逻辑处理后,通常会产生一些信息,这些信息需要返回给用户并在浏览器上显示。这些信息被称为模(Model)。不过仅仅给用户返回原始的信息是不够的——这些信息需要以用户友好的方式进行格式化,一般会是HTML。所以,信息需要发送给一个视图(View),通常会是JSP。
  控制器所做的最后一件事就是将模型数据打包,并且标示出用于渲染输出的视图名。它接下来会将请求连同模型和视图名发送回DispatcherServlet 。这样,控制器就不会与特定的视图相耦合,传递给DispatcherServlet的视图名并不直接表示某个特定的JSP。实际上,它甚至并不能确定视图就是JSP。相反,它仅仅传递了一个逻辑名称,这个名字将会用来查找产生结果的真正视图。DispatcherServlet将会使用视图解析器(ViewResolver)来将逻辑视图名匹配为一个特定的视图实现,它可能是也可能不是JSP。
既然DispatcherServlet已经知道由哪个视图渲染结果,那请求的任务基本上也就完成了。它的最后一站是视图的实现(可能是JSP) ,在这里它交付模型数据。请求的任务就完成了。视图将使用模型数据渲染输出,这个输出会通过响应对象传递给客户端(不会像听上去那样硬编码) 。
可以看到,请求要经过很多的步骤,最终才能形成返回给客户端的响应。大多数的步骤都是在Spring框架内部完成的,也就是上图所示的组件中。
21、mybatis 一二级缓存
  区别:
  一级缓存的作用域是一个sqlsession内;
  二级缓存作用域是针对mapper进行缓存;
  一级缓存:
  在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。
  一级缓存时执行commit,close,增删改等操作,就会清空当前的一级缓存;当对SqlSession执行更新操作(update、delete、insert)后并执行commit时,不仅清空其自身的一级缓存(执行更新操作的效果),也清空二级缓存(执行commit()的效果)。
  二级缓存:
  二级缓存指的就是同一个namespace下的mapper,二级缓存中,也有一个map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
  a、在配置文件中 开启二级缓存的总开关

<setting name="cacheEnabled" value="true" />

  b、 在mapper映射文件中开启二级缓存
@Scheduled(fixedRate = 2000) public void fixedRate() { System.out.println("fixedRate>>>"+new Date()); } @Scheduled(fixedDelay = 2000) public void fixedDelay() { System.out.println("fixedDelay>>>"+new Date()); } @Scheduled(initialDelay = 2000,fixedDelay = 2000) public void initialDelay() { System.out.println("initialDelay>>>"+new Date()); }

  1.fixedRate 表示任务执行之间的时间间隔,具体是指两次任务的开始时间间隔,即第二次任务开始时,第一次任务可能还没结束。
  2.fixedDelay 表示任务执行之间的时间间隔,具体是指本次任务结束到下次任务开始之间的时间间隔。
   3.initialDelay 表示首次任务启动的延迟时间。
  所有时间的单位都是毫秒。
  上面这是一个基本用法,除了这几个基本属性之外,@Scheduled 注解也支持 cron 表达式,使用 cron 表达式,可以非常丰富的描述定时任务的时间。cron 表达式格式如下:
[秒] [分] [小时] [日] [月] [周] [年]
第二种方式: Quartz实现定时任务
  @Scheduled 注解来解决定时任务,否则大部分情况可能都是使用 Quartz 来做定时任务。在 Spring Boot 中使用 Quartz ,只需要在创建项目时,添加 Quartz 依赖即可。
项目创建完成后,也需要添加开启定时任务的注解:@EnableScheduling注解放在主方法上用于开启自动任务。
  Quartz 在使用过程中,有两个关键概念,一个是JobDetail(要做的事情),另一个是触发器(什么时候做),要定义 JobDetail,需要先定义 Job,Job 的定义有两种方式:
第一种方式,直接定义一个Bean,这种方式需要将 Job 注册到 Spring 容器中,存在一个缺陷,就是无法传参。
  第二种定义方式,则是继承 QuartzJobBean 并实现默认的方法,任务启动时,executeInternal 方法将会被执行。Job 有了之后,接下来创建类,配置 JobDetail 和 Trigger 触发器。
27.spring用到哪些设计模式?
  a.工厂设计模式:Spring使用工厂模式可以通过 BeanFactory 或 ApplicationContext 创建 bean 对象。
  b.单例设计模式:Spring中bean的默认作用域就是singleton(单例)的,Spring实现单例的方式:
xml:
注解:@Scope(value = “singleton”)
  c.代理模式:Spring AOP就是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,Spring AOP会使用Cglib,这时候Spring AOP会使用Cglib生成一个被代理对象的子类来作为代理。
  d.模板方法:模板方法模式是一种行为设计模式,它定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤的实现方式,Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
  e.适配器模式:适配器模式(Adapter Pattern) 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。Spring AOP 的增强或通知(Advice)使用到了适配器模式,与之相关的接口是AdvisorAdapter 。Advice 常用的类型有:BeforeAdvice(目标方法调用前,前置通知)、AfterAdvice(目标方法调用后,后置通知)
28.Spring 的作用域有哪些?
  a.singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
  b.prototype : 每次请求都会创建一个新的 bean 实例。
  c.request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
  d.session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。
29.Spring 中的单例 bean 的线程安全问题了解吗?
  大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例bean存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。

你可能感兴趣的:(Java面试官,java,spring,restful)