2024年 Java 面试八股文——java框架篇

目录

1、简单的谈一下SpringMVC的工作流程    难度系数:

2、说出Spring或者SpringMVC中常用的5个注解    难度系数:⭐

3、简述SpringMVC中如何返回JSON数据    难度系数:⭐ 

4、谈谈你对Spring的理解    难度系数:⭐ 

5、Spring中常用的设计模式    难度系数:⭐ 

6、Spring循环依赖问题    难度系数:⭐⭐

7、介绍一下Spring bean 的生命周期、注入方式和作用域    难度系数:⭐

8、请描述一下Spring 的事务管理    难度系数:⭐

9、MyBatis中 #{}和${}的区别是什么    难度系数:⭐

10、Mybatis 中一级缓存与二级缓存    难度系数:⭐ 

 11、MyBatis如何获取自动生成的(主)键值    难度系数:⭐

12、简述Mybatis的动态SQL,列出常用的6个标签及作用    难度系数:⭐ 

13、Mybatis 如何完成MySQL的批量操作    难度系数:⭐ 

14、谈谈怎么理解SpringBoot框架    难度系数:⭐⭐ 

15、Spring Boot 的核心注解是哪个 它主要由哪几个注解组成的    难度系数:⭐ 

16、Spring Boot自动配置原理是什么    难度系数:⭐ 

17、SpringBoot配置文件有哪些 怎么实现多环境配置    难度系数:⭐ 


 

1、简单的谈一下SpringMVC的工作流程    难度系数:⭐

1. 用户发送请求到前端控制器(DispatcherServlet)

2. 前 端 控 制 器 ( DispatcherServlet ) 收 到 请 求 调 用 处 理 器 映 射 器 (HandlerMapping),去查找处理器(Handler)

3. 处理器映射器(HandlerMapping)找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。

4. 前端控制器(DispatcherServlet)调用处理器映射器(HandlerMapping)

5. 处理器适配器(HandlerAdapter)去调用自定义的处理器类(Controller,叫

后端控制器)。

6.自定义的处理器类(Controller,也叫后端控制器)将得到的参数进行处理并返回结果给处理器映射器(HandlerMapping)

7. 处 理 器 适 配 器 ( HandlerAdapter ) 将 得 到 的 结 果 返 回 给 前 端 控 制 器(DispatcherServlet)

8. DispatcherServlet( 前 端 控 制 器 ) 将 ModelAndView 传 给 视 图 解 析 器 (ViewReslover)

9. 视图解析器(ViewReslover)将得到的参数从逻辑视图转换为物理视图并返回给前端控制器(DispatcherServlet)

10. 前端控制器(DispatcherServlet)调用物理视图进行渲染并返回

11. 前端控制器(DispatcherServlet)将渲染后的结果返回

 

2、说出Spring或者SpringMVC中常用的5个注解    难度系数:⭐

1.@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表 示类中的所有响应请求的方法都是以该地址作为父路径。

2.@RequestBody:注解实现接收 http 请求的 json 数据,将 json 转换为 java 对象。

3.@ResponseBody:注解实现将 conreoller 方法返回对象转化为 json 对象响应给客

户。

4.@PathVariable 用户从 url 路径上获取指定参数,标注在参数前 @PathVariabel("

要获取的参数名")。

5.@RequestParam: 标注在方法参数之前,用于对传入的参数做一些限制,支持三个

属性:

- value:默认属性,用于指定前端传入的参数名称

- required:用于指定此参数是否必传

- defaultValue:当参数为非必传参数且前端没有传入参数时,指定一个默认值

6. @ControllerAdvice 标注在一个类上,表示该类是一个全局异常处理的类。

7. @ExceptionHandler(Exception.class) 标注在异常处理类中的方法上,表示该方法可以处理的异常类型。

3、简述SpringMVC中如何返回JSON数据    难度系数:⭐ 

         

1、第一种方式是spring2时代的产物,也就是每个json视图controller配置一个Jsoniew。

如:<bean id="defaultJsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/> 

或者<bean id="defaultJsonView" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>

同样要用jackson的jar包。

2、第二种使用JSON工具将对象序列化成json,常用工具Jackson,fastjson,gson。

利用HttpServletResponse,然后获取response.getOutputStream()或response.getWriter()

直接输出。

public class JsonUtil
{
    
    private static Gson gson=new Gson();
 
 
    /**
     * @MethodName : toJson
     * @Description : 将对象转为JSON串,此方法能够满足大部分需求
     * @param src
     *            :将要被转化的对象
     * @return :转化后的JSON串
     */
    public static String toJson(Object src) {
        if (src == null) {
            return gson.toJson(JsonNull.INSTANCE);
        }
        return gson.toJson(src);
    }
}

4、谈谈你对Spring的理解    难度系数:⭐ 

1. Spring 的两大核心是:IOC(控制反转)和 AOP(面向切面编程) DI(依赖注入)

2. IOC 的意思是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和

时机是由自己把控的,而现在这种权力转移到 Spring 容器中,并由容器根据配置文件去创

建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。最

直观的表达就是,IOC 让对象的创建不用去 new 了,可以由 spring 根据我们提供的配置文

件自动生产,我们需要对象的时候,直接从 Spring 容器中获取即可.

Spring 的配置文件中配置了类的字节码位置及信息, 容器生成的时候加载配置文件识

别字节码信息, 通过反射创建类的对象.

Spring 的 IOC 有三种注入方式 :构造器注入, setter 方法注入, 根据注解注入。

3. DI 的意思是依赖注入,和控制反转是同一个概念的不同角度的描述,即应用程序在

运行时依赖 Io c 容器来动态注入对象需要的外部资源。

464. AOP,一般称为面向切面编程,作为面向对象的一种补充,用于将那些与业务无关,

但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被

命名为“切面”(Aspect). SpringAOP 使用的动态代理,所谓的动态代理就是说 AOP 框

架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个 AOP 对象,这个 AOP

对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

5. Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理:

(1)JDK 动态代理只提供接口代理,不支持类代理,核心 InvocationHandler 接口和

Proxy 类,InvocationHandler 通过 invoke()方法反射来调用目标类中的代码,动态地将

横切逻辑和业务编织在一起,Proxy 利用 InvocationHandler 动态创建一个符合某一接口

的的实例, 生成目标类的代理对象。

(2) 如果代理类没有实现 InvocationHandler 接口,那么 Spring AOP 会选择使用

CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,

可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从

而实现 AOP。CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final,

那么它是无法使用 CGLIB 做动态代理的。

5、Spring中常用的设计模式    难度系数:⭐ 

1. 工厂模式:BeanFactory 就是简单工厂模式的体现,用来创建对象的实例

2. 单例模式:Bean 默认为单例模式

3. 代理模式:Spring 的 AOP 功能用到了 JDK 的动态代理和 CGLIB 字节码生成技术

4. 模板方法 :用来解决代码重 复的问题。比如. RestTemplate, JmsTemplate,

JpaTemplate

5. 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,

所 有 依 赖 于 它 的 对 象 都 会 得 到 通 知 被 制 动 更 新 , 如 Spring 中 listener 的 实 现 -ApplicationListener

6、Spring循环依赖问题    难度系数:⭐⭐

Spring 循环依赖问题主要发生在以下场景:

1. **构造函数注入**:当使用构造函数注入时,Spring 需要通过构造函数的参数来实例化 Bean。如果 Bean A 的构造函数依赖于 Bean B,而 Bean B 的构造函数又依赖于 Bean A,那么 Spring 就无法解决这种循环依赖。
2. **单例 Bean**:循环依赖通常发生在单例 Bean 之间,因为单例 Bean 的生命周期在整个 Spring 容器中都是唯一的。如果两个单例 Bean 相互依赖,Spring 容器在初始化它们时就会遇到循环依赖问题。

为了解决这个问题,Spring 提供了以下几种解决方案:

1. **使用原型(Prototype)作用域**:将循环依赖的 Bean 之一设置为原型作用域(非单例)。这样,每次需要该 Bean 时,Spring 都会为其创建一个新的实例,从而避免循环依赖问题。但是,这可能会导致性能问题,因为每次请求都需要创建新的 Bean 实例。
2. **使用 Setter 注入**:将依赖注入方式从构造函数注入改为 Setter 注入。Setter 注入允许在 Bean 实例创建后通过 Setter 方法注入依赖,从而解决了循环依赖问题。但是,这种方式可能导致 Bean 的状态在初始化时不是完全可用的。
3. **使用 @Lazy 注解**:在依赖注入时使用 @Lazy 注解,让 Spring 在真正需要时才创建和注入 Bean。这样,循环依赖的问题就被推迟到了运行时,而不是在启动时。但是,这种方式可能会增加系统复杂性,因为你需要明确知道哪些 Bean 可能产生循环依赖。
4. **重新设计组件结构**:考虑重新设计应用程序的组件结构,以减少或消除循环依赖。这可能需要对代码进行重大重构,但长期来看,这有助于提高代码的可维护性和可扩展性。

7、介绍一下Spring bean 的生命周期、注入方式和作用域    难度系数:⭐

生命周期

1. 实例化一个 Bean,也就是我们通常说的 new

2. 按照 Spring 上下文对实例化的 Bean 进行配置,也就是 IOC 注入

3. 如果这个 Bean 实现 dao 了 BeanNameAware 接口,会调用它实现的

setBeanName(String beanId)方法,此处传递的是 Spring 配置文件中 Bean 的 ID

4. 如果这个 Bean 实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory(),

传递的是 Spring 工厂本身(可以用这个方法获取到其他 Bean)

5. 如果这个 Bean 实现了 ApplicationContextAware 接口,会调用

setApplicationContext(ApplicationContext)方法,传入 Spring 上下文,该方式同样可

以实现步骤 4,但比 4 更好,以为 ApplicationContext 是 BeanFactory 的子接口,有更多

的实现方法

6. 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用

postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor 经常被

用作是 Bean 内容的更改,并且由于这个是在 Bean 初始化结束时调用 After 方法,也可用

于内存或缓存技术

7. 如果这个 Bean在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始

化方法

8. 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用

postAfterInitialization(Object obj, String s)方法

注意:以上工作完成以后就可以用这个 Bean 了,那这个 Bean 是一个 single 的,所以

一般情况下我们调用同一个 ID 的 Bean 会是在内容地址相同的实例

注入方式:

通过 setter 方法注入

通过构造方法注入

Spring 支持如下 5 种作用域:

(1)singleton:默认作用域,单例 bean,每个容器中只有一个 bean 的实例。

(2)prototype:每次请求都会为 bean 创建实例。

(3)request:为每一个 request 请求创建一个实例,在请求完成以后,bean 会失效

并被垃圾回收器回收。

(4)session:与 request 范围类似,同一个 session 会话共享一个实例,不同会话

使用不同的实例。

(5)global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会

话共享的存储变量的话,那么这全局变量需要存储在 global-session 中

8、请描述一下Spring 的事务管理    难度系数:⭐

Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring 是

无法提供事务功能的。真正的数据库层的事务提交和回滚是通过 binlog 或者 redo log 实

现的。

spring 事务实现主要有两种方法

1、编程式,beginTransaction()、commit()、rollback()等事务管理相关的方法

2、声明式,利用注解 Transactional 或者 aop 配置

9、MyBatis中 #{}和${}的区别是什么    难度系数:⭐

#{} 是占位符,预编译处理,${}是字符串替换。

Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set

方法来赋值;

Mybatis 在处理${}时,就是把${}替换成变量的值。

使用#{}可以有效的防止 SQL 注入,提高系统安全性。

10、Mybatis 中一级缓存与二级缓存    难度系数:⭐ 

Mybatis 有两级缓存,一级缓存是 SqlSession 级别的,默认开启,无法关闭;二级缓

存是 Mapper 级别的,二级缓存默认是没有开启的,但是手动开启

1. 一级缓存:基础 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,

当 Session flush 或 close 之后,Session 中的所有 Cache 就将清空

2. 二级缓存其存储作用域为 Mapper(Namespace),使用二级缓存属性类需要实现

Serializable 序列化接口

3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存 Namespaces)

的进行了 C(增加)/U(更新)/D(删除)操作后,默认该作用域下所有 select 中的缓存将被 clear.

需要在 setting 全局参数中配置开启二级缓存,如下 conf.xml 配置:

当我们的配置文件配置了 cacheEnabled=true 时,就会开启二级缓存,二级缓存是

mapper 级别的,如果你配置了二级缓存,那么查询数据的顺序应该为:二级缓存→一级缓

存→数据库。

<insert id=”insertname” usegeneratedkeys=”true” keyproperty=”id”>
    insert into names (name) values (#{name}) 
</insert>

 11、MyBatis如何获取自动生成的(主)键值    难度系数:⭐

 在<insert>标签中使用 useGeneratedKeys和keyProperty 两个属性来获取自动生成的主键值。

12、简述Mybatis的动态SQL,列出常用的6个标签及作用    难度系数:⭐ 

1. <if>if 是为了判断传入的值是否符合某种规则,比如是否不为空.

2. <where> where 标签可以用来做动态拼接查询条件,当和 if 标签配合的时候,不

用显示的声明类型 where 1 = 1 这种无用的条件

3. <foreach> foreach 标签可以把传入的集合对象进行遍历,然后把每一项的内容

作为参数传到 sql 语句中.

4. <include> include 可以把大量的重复代码整理起来,当使用的时候直接 include

即可,减少重复代码的编写;

5. <set>适用于更新中,当匹配某个条件后,才会对该字段进行跟新操作

13、Mybatis 如何完成MySQL的批量操作    难度系数:⭐ 

 MyBatis完成MySQL的批量操作主要是通过<foreach>标签来拼装相应的SQL语句

<insert id="batchInsert">
INSERT INTO notice_scope_detail (notice_id, obj_id)
      VALUES
      <foreach collection="list" item="item" index="index" separator=",">
        (#{item.noticeId}, #{item.objId})
      </foreach>
</insert>

 

14、谈谈怎么理解SpringBoot框架    难度系数:⭐⭐ 

是 Spring 的子项目,主要简化 Spring 开发难度,去掉了繁重配置,提供各种启动器,可以

让程序员很快上手,节省开发时间.

SpringBoot 对上述 Spring 的缺点进行的改善和优化,基于约定优于配置的思想,可

以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码

编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。

版本锁定:解决是 maven 依赖版本容易冲突的问题,集合了常用的并且测试过的所有版本

使用了 Starter(启动器)管理依赖并能对版本进行集中控制,如下的父工程带有版本号,

就是对版本进行了集中控制.

<!--引入父工程-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>

起步依赖 :解决了完成某一个功能要整合的 jar 包过多的问题,集合了常用的 jar 包

自动配置:解决了整合框架或者技术的配置文件过多,集合了所有的约定的默认配置

内置 Tomcat:通过内置的 tomcat,无需再用其他外置的 Tomcat 就直接可以运行 javaEE

程序

总之:人们把 Spring Boot 称为搭建程序的脚手架。其最主要作用就是帮我们快速的构建

庞大的 spring 项目,并且尽可能的减少一切 xml 配置,做到开箱即用,迅速上手,让我们

关注与业务而非配置。

 

15、Spring Boot 的核心注解是哪个 它主要由哪几个注解组成的    难度系数:⭐ 

  1. @SpringBootConfiguration:这个注解实际上是@Configuration注解的组合,主要用于定义Spring Boot的配置类,它告诉Spring Boot这是一个Java配置类,可以用来替代传统的XML配置文件。
  2. @EnableAutoConfiguration:这个注解用于开启Spring Boot的自动配置功能。开启之后,Spring Boot会根据当前类路径下的包或类来自动配置Spring Bean。这使得开发者可以省略很多繁琐的配置工作,提高开发效率。
  3. @ComponentScan:这个注解用于开启组件扫描,即Spring Boot会自动扫描指定包下的带有@Component、@Service、@Repository、@Controller等注解的类,并把这些类注册为Spring应用上下文中的Bean。这样,开发者就可以通过自动装配的方式将这些Bean注入到其他需要的地方。

16、Spring Boot自动配置原理是什么    难度系数:⭐ 

注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心,

首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。

@EnableAutoConfiguration是实现自动配置的注解

@Configuration表示这是一个配置文件

17、SpringBoot配置文件有哪些 怎么实现多环境配置    难度系数:⭐ 

1)有哪些配置文件?

application.yml 或 application.properties

bootstrap.yml 或 bootstrap.properties

(2)上面两种配置文件有什么区别?

1. bootstrap 由父 ApplicationContext 加载, 比 application 配置文件优先被加 载.

2. bootstarp 里的属性不能被覆盖.

3. application: springboot 项目中的自动化配置.

4. bootstrap:

使用 spring cloud config 配置中心时, 需要加载连接配置中心的配置属性的, 就

可以使用 bootstrap 来完成.

加载不能被覆盖的属性.

加载一些加密/解密的数据.

(3)读取配置文件的方式?

l 读取默认配置文件

需要注入 Environment 类, 使用 environment.getProperty(peorperties 中的 key), 这

样就能获得 key 对应的 value 值

@value(${key.value}) 直接读取

l 读取自定义配置文件

n 自定义配置文件后缀必须是.propeties

编写和自定义配置文件对应的 java 类, 类上放 3 个注解

u @ConfigurationProperties(“前缀”)

u @PropertySource(“指定配置文件”)

u @Component 包扫描

n 读取的时候就跟读取默认配置文件一样.

  • 32
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java面试八股文是指在Java开发岗位面试中常见的一些核心知识点和问题。以下是Java面试八股文的主要内容: 1. Java基础知识: - Java的特点和优势 - Java的基本数据类型和包装类 - Java的运算符和表达式 - Java的流程控制语句(if-else、for、while等) - Java的异常处理机制 2. 面向对象编程: - 类和对象的概念 - 封装、继承和多态的概念和实现方式 - 接口和抽象类的区别和用法 - Java中的内部类和匿名类 3. Java集合框架: - List、Set和Map的特点和用法 - ArrayList、LinkedList、HashSet、HashMap等集合类的底层实现原理 - 集合类的遍历和常见操作 4. 多线程与并发: - 线程的生命周期和状态转换 - 线程的创建和启动方式 - 线程同步与互斥的方法(synchronized、Lock等) - 线程池的概念和使用 5. JVM与垃圾回收: - JVM的内存模型和运行时数据区域 - 垃圾回收算法和垃圾回收器的选择 - 常见的JVM调优手段和工具 6. 设计模式: - 单例模式、工厂模式、代理模式等常见设计模式的原理和应用场景 - MVC、观察者模式等常见架构模式的概念和实现方式 7. 数据库与SQL: - SQL语句的基本语法和常见操作(增删改查) - 数据库事务的特性和隔离级别 - 数据库连接池的概念和使用 8. Web开发相关: - Servlet和JSP的概念和生命周期 - MVC框架(如Spring MVC)的原理和使用 - 前端技术(HTML、CSS、JavaScript)的基本知识 以上是Java面试八股文的主要内容,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值