百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

程序员面试大厂,一定要警惕的10道SSM框架技能题,别被虐哭了

ccwgpt 2024-10-29 13:31 37 浏览 0 评论

今日分享开始啦,请大家多多指教~

本篇总结 SSM 三大框架相关面试题~

1、什么是有状态登录和无状态登录?

  • 有状态登录:

当客户端第一次请求服务器时(请求登录),服务器创建 Session ,然后将登录用户身份信息保存到 Session 中,并将用户身份信息作为 “门卡”,响应回客户端,客户端将服务器响应的 “门卡” 信息保存在本地 Cookie 中。

当下一次客户端再次请求服务器时,这时候就直接将客户端的 Cookie 中存放的 “门卡” 带到服务器端,服务器端从 Session 中拿出数据和 “门卡” 进行对比,判断是否可以同行。

  • 无状态登录的缺点:

服务端保存大量用户身份标识,增加服务端压力。

客户端请求依赖服务端,多次请求必须访问同一台服务器(如果是集群,相当于启动了多个 Tomcat,这时候无法在多个 Tomcat 直接共享 Session 数据)。

  • 无状态登录:

服务器不保存任何客户端用户的登录信息!

客户端的每次请求服务器必须自己具备身份信息标识(jwt),服务器端通过身份信息标识识别客户端身份。

  • 无状态登录的好处:

客户端请求不依赖服务端的信息,任何多次请求不需要必须访问到同一台服务器。

减小服务端存储压力。

如何实现无状态登录?

如图所示:

  • 当客户端第一次请求服务时,服务端对用户进行信息认证(登录)。
  • 认证通过,将用户身份信息(不包含密码)进行加密形成 token,返回给客户端,作为登录凭证。
  • 以后每次请求,客户端都携带认证的 token。
  • 服务的对 token 进行解密,判断是否有效。

2、过滤器,拦截器,Aop区别?

过滤器和拦截器均体现了AOP的编程思想,都可以实现诸如日志记录、登录鉴权等功能,但二者的不同点也是比较多的。

1、实现原理不同

过滤器和拦截器 底层实现方式大不相同,过滤器是基于函数回调的,拦截器则是基于Java的反射机制(动态代理)实现的。

2、使用范围不同

我们看到过滤器实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。

而拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。

3、触发时机不同

过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。

拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。

4、拦截的请求范围不同

5、注入Bean情况不同

在实际的业务场景中,应用到过滤器或拦截器,为处理业务逻辑难免会引入一些service服务。

6、控制执行顺序不同

实际开发过程中,会出现多个过滤器或拦截器同时存在的情况,不过,有时我们希望某个过滤器或拦截器能优先执行,就涉及到它们的执行顺序。

3、什么是SpringMvc,说一说它的几个核心组成?

① 前端控制器(DispatcherServlet):主要用于接收客户端发送的 HTTP 请求、响应结果给客户端。

② 处理器映射器(HandlerMapping):根据请求的 URL 来定位到对应的处理器(Handler)。

③ 处理器适配器(HandlerAdapter):在编写处理器(Handler)的时候要按照处理器适配器(HandlerAdapter) 要求的规则去编写,通过适配器可以正确地去执行 Handler。

④ 处理器(Handler):就是我们经常写的 Controller 层代码,例如:UserController。

⑤ 视图解析器(ViewResolver):进行视图的解析,将 ModelAndView 对象解析成真正的视图(View)对象返回给前端控制器。

⑥ 视图(View):View 是一个接口, 它的实现类支持不同的视图类型(JSP,FreeMarker,Thymleaf 等)。

4、Springmvc执行流程?

① 首先,用户发送 HTTP 请求给 SpringMVC 前端控制器 DispatcherServlet。

② DispatcherServlet 收到请求后,调用HandlerMapping 处理器映射器,根据请求 URL 去定位到具体的处理器 Handler,并将该处理器对象返回给 DispatcherServlet 。

③ 接下来,DispatcherServlet 调用 HandlerAdapter 处理器适配器,通过处理器适配器调用对应的 Handler 处理器处理请求,并向前端控制器返回一个 ModelAndView 对象。

④ 然后,DispatcherServlet 将 ModelAndView 对象交给 ViewResoler 视图解析器去处理,并返回指定的视图 View 给前端控制器。

⑤ DispatcherServlet 对 View 进行渲染(即将模型数据填充至视图中)。View 是一个接口, 它的实现类支持不同的视图类型(JSP,FreeMarker,Thymleaf 等)。

⑥ DispatcherServlet 将页面响应给用户。

5、什么是MyBatis 一、二级缓存?

一级缓存:作用域是 SqlSession,同一个 SqlSession 中执行相同的 SQL 查询(相同的SQL和参数),第一次会去查询数据库并写在缓存中,第二次会直接从缓存中取。

  • 一级缓存是基于 PerpetualCache 的 HashMap 本地缓存,默认打开一级缓存。
  • 失效策略:当执行 SQL 时候两次查询中间发生了增删改的操作,即 insert、update、delete 等操作 commit 后会清空该 SqlSession 缓存。

二级缓存:作用域是 NameSpace 级别,多个 SqlSession 去操作同一个 NameSpace 下的 Mapper 文件的 sql 语句,多个 SqlSession可以共用二级缓存,如果两个 Mapper 的 NameSpace 相同,(即使是两个 Mapper,那么这两个 Mapper 中执行 sql 查询到的数据也将存在相同的二级缓存区域中)。

  • 二级缓存也是基于 PerpetualCache 的 HashMap 本地缓存,可自定义存储源,如 Ehcache/Redis等。默认是没有开启二级缓存。
  • 操作流程:第一次调用某个 NameSpace 下的 SQL 去查询信息,查询到的信息会存放该 Mapper对应的二级缓存区域。第二次调用同个 NameSpace 下的 Mapper 映射文件中的相同的 sql 去查询信息时,会去对应的二级缓存内取结果。
  • 失效策略:执行同个 NameSpace 下的 Mapepr 映射文件中增删改 sql,并执行了commit 操作,会清空该二级缓存。

注意:实现二级缓存的时候,MyBatis 建议返回的 POJO 是可序列化的, 也就是建议实现 Serializable 接口。

如图所示:

当 Mybatis 调用 Dao 层查询数据库时,先查询二级缓存,二级缓存中无对应数据,再去查询一级缓存,一级缓存中也没有,最后去数据库查找。

6、为什么说 Mybatis 是半自动ORM映射工具?它与全自动的区别在哪里?

ORM 是什么?

ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数据与简单 Java 对象(POJO)建立映射关系的技术。

为什么说 Mybatis 是半自动ORM映射工具?它与全自动的区别在哪里?

  • 首先,像 Hibernate、JPA 这种属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
  • 而 Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。
  • 换句话来解释就是说 MyBatis 是 半自动 ORM 最主要的一个原因是,它需要在 XML 或者注解里通过手动或插件生成 SQL,才能完成 SQL 执行结果与对象映射绑定。

7、能否简单说下Mybatis加载的流程?

  • MyBatis 是以一个 SqlSessionFactory 实例为核心,SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。
  • SqlSessionFactoryBuilder 可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
  • SqlSessionFactory 实例工厂可以生产 SqlSession ,它里面提供了在数据库执行 SQL 命令所需的所有方法。

具体流程:

① 加载配置文件:需要加载的配置文件包括全局配置文件(mybatis-config.xml)和 SQL(Mapper.xml) 映射文件,其中全局配置文件配置了Mybatis 的运行环境信息(数据源、事务等),SQL映射文件中配置了与 SQL 执行相关的信息。

② 创建会话工厂:MyBatis通过读取配置文件的信息来构造出会话工厂(SqlSessionFactory),即通过SqlSessionFactoryBuilder 构建 SqlSessionFactory。

③ 创建会话:拥有了会话工厂,MyBatis就可以通过它来创建会话对象(SqlSession)。会话对象是一个接口,该接口中包含了对数据库操作的增删改查方法。

④ 创建执行器:因为会话对象本身不能直接操作数据库,所以它使用了一个叫做数据库执行器(Executor)的接口来帮它执行操作。

⑤ 封装SQL对象:执行器(Executor)将待处理的SQL信息封装到一个对象中(MappedStatement),该对象包括SQL语句、输入参数映射信息(Java简单类型、HashMap或POJO)和输出结果映射信息(Java简单类型、HashMap 或 POJO)。

⑥ 操作数据库:拥有了执行器和SQL信息封装对象就使用它们访问数据库了,最后再返回操作结果,结束流程。

8、什么是 Spring 三级缓存?

所谓三级缓存,其实就是org.springframework.beans.factory包下DefaultSingletonBeanRegistry类中的三个成员属性:

  • Spring一级缓存:用来保存实例化、初始化都完成的对象

Key:beanName

Value: Bean实例

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

  • Spring二级缓存:用来保存实例化完成,但是未初始化完成的对象

Key:beanName

Value: Bean实例

和一级缓存一样也是保存BeanName和创建bean实例之间的关系,与singletonObjects不同之处在于,当一个单例bean被放在里面后,那么bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来循环检测引用!

private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

  • Spring三级缓存:用来保存一个对象工厂,提供一个匿名内部类,用于创建二级缓存中的对象

Key:beanName

Value: Bean的工厂

private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

如图所示,除了三级缓存是一个HashMap,其他两个都是ConcurrentHashMap:

Spring之所以引入三级缓存,目的就是为了解决循环依赖问题!

除了上面三个Map集合,还有另一个集合这里也说一下:

用来保存当前所有已注册的Bean

private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

9、什么是 Spring循环依赖问题?如何解决?

首先,Spring 解决循环依赖有两个前提条件:

  • Setter方式注入造成的循环依赖(构造器方式注入不可以)
  • 必须是单例

本质上解决循环依赖的问题就是依靠三级缓存,通过三级缓存提前拿到未初始化的对象。下面我们来看一个循环依赖的例子:

A 对象的创建过程:

1.创建对象A,实例化的时候把A对象工厂放入三级缓存

2.A 注入属性时,发现依赖 B,转而去实例化 B

3.同样创建对象 B,注入属性时发现依赖 A,一次从一级到三级缓存查询 A,从三级缓存通过对象工厂拿到 A,把 A 放入二级缓存,同时删除三级缓存中的 A,此时,B 已经实例化并且初始化完成,把 B 放入一级缓存。

4.接着继续创建 A,顺利从一级缓存拿到实例化且初始化完成的 B 对象,A 对象创建也完成,删除二级缓存中的 A,同时把 A 放入一级缓存。

5.最后,一级缓存中保存着实例化、初始化都完成的A、B 对象。

从上面5步骤的分析可以看出,三级缓存解决循环依赖是通过把实例化和初始化的流程分开了,所以如果都是用构造器的话,就没法分离这个操作(因为构造器注入实例化和初始是一起进行的)。因此构造器方式注入的话是无法解决循环依赖问题的。

解决循环依赖为什么必须要要三级缓存?二级不行吗?

答案:不可以!

使用三级缓存而非二级缓存并不是因为只有三级缓存才能解决循环引用问题,其实二级缓存同样也能很好解决循环引用问题。

使用三级而非二级缓存并非出于IOC的考虑,而是出于AOP的考虑,即若使用二级缓存,在AOP情形下,往二级缓存中放一个普通的Bean对象,BeanPostProcessor去生成代理对象之后,覆盖掉二级缓存中的普通Bean对象,那么多线程环境下可能取到的对象就不一致了。

  • 一句话总结就是,在 AOP 代理增强 Bean 后,会对早期对象造成覆盖,如果多线程情况下可能造成取到的对象不一致~

10、说说Spring 里用到了哪些设计模式?

单例模式:Spring 中的 Bean 默认情况下都是单例的。无需多说。

工厂模式:工厂模式主要是通过 BeanFactory 和 ApplicationContext 来生产 Bean 对象。

代理模式:最常见的 AOP 的实现方式就是通过代理来实现,Spring主要是使用 JDK 动态代理和 CGLIB 代理。

单例模式

单例模式使?场景:

  • 业务系统全局只需要?个对象实例,?如发号器、 redis 连接对象等。
  • Spring IOC容器中的 Bean 默认就是单例。
  • Spring Boot 中的 Controller、Service、Dao 层中通过 @Autowire的依赖注?对象默认都是单例的。

单例模式分类:

  • 懒汉:就是所谓的懒加载,延迟创建对象,需要用的时候再创建对象。
  • 饿汉:与懒汉相反,提前创建对象。

单例模式实现步骤:

  • 私有化构造函数。
  • 提供获取单例的?法。

工厂模式

??模式介绍:它提供了?种创建对象的最佳?式,在创建对象时 不会对客户端暴露创建逻辑,并且是通过使??个共同的接?来指向新创建的对象。

??模式有 3 种不同的实现?式:

① 简单??模式(静态工厂):通过传?相关的类型来返回相应的类,这 种?式?较单 ?,可扩展性相对较差。

② ???法模式:通过实现类实现相应的?法来决定相应的返回结果,这种?式的可扩展性?较强。

③ 抽象??模式:基于上述两种模式的拓展,且?持细化产品。

应?场景:

解耦:分离职责,把复杂对象的创建和使?的过程分开。

复?代码 降低维护成本:如果对象创建复杂且多处需?到,如果每处都进?编写,则很多重复代码,如果业务逻辑发?了改 变,需?四处修改;使???模式统?创建,则只要修改??类即可, 降低成本。

代理模式

代理模式最直观的解释就是,通过代理,将被代理对象 “增强”!(即,扩展被代理对象的功能)

代理模式分为静态代理,和动态代理:动态代理的代理类是动态生成的 , 静态代理的代理类是我们提前写好的逻辑。

Java 中实现动态代理的方式有 2 种:

  • JDK 动态代理
  • CGLIB 动态代理

今日份分享已结束,请大家多多包涵和指点!

相关推荐

Java七大热门技术框架源码解析(25章) 完结

获课》aixuetang.xyz/5699/Hibernate与MyBatis源码级PK:ORM框架的两种哲学在Java持久层框架领域,Hibernate与MyBatis代表了两种截然不同的设计哲学。...

【25章】Java七大热门技术框架源码解析

获课》aixuetang.xyz/5699/Java高级面试:七大框架源码精讲与实战解析在当今Java技术生态中,对主流框架源码的深入理解已成为高级开发者面试的核心竞争力。掌握Spring、MyBat...

饿了么董事长吴泽明兼任CEO,韩鎏分管即时物流中心

饿了么调整组织架构。2月11日,饿了么董事长吴泽明(花名:范禹)通过公司全员信宣布饿了么最新组织调整:即日起,吴泽明将兼任饿了么CEO,韩鎏(花名:昊宸)专注分管即时物流中心,继续向吴泽明汇报。吴泽明...

饿了么100%迁至阿里云,快速扩容可支持1亿人同时点单

来源:环球网6月17日,记者获悉,饿了么已完成100%上云,所有业务系统、数据库设施等均已迁移至阿里云。高峰期,饿了么可在阿里云上快速扩容,可以支持1亿人同时在线点单,这意味着饿了么的服务能力再次全面...

饿了么组织架构调整:董事长吴泽明兼任CEO 韩鎏专注即时物流中心管理

近日,饿了么董事长吴泽明(花名:范禹)通过公司全员信宣布饿了么最新组织调整:即日起,吴泽明将兼任饿了么CEO,韩鎏(花名:昊宸)专注分管即时物流中心,继续向吴泽明汇报。吴泽明在内部信中表示,考虑即时物...

饿了么组织架构调整:董事长吴泽明兼任CEO

Tech星球2月11日消息,据新浪科技报道,今日饿了么董事长吴泽明(花名:范禹)通过公司全员信宣布饿了么最新组织调整:即日起,吴泽明将兼任饿了么CEO,韩鎏(花名:昊宸)专注分管即时物流中心,继续向吴...

饿了么又调整了组织架构,董事长吴泽明兼任CEO

2月11日,饿了么董事长,花名为范禹的吴泽明,通过公司全员信宣布最新组织调整:从即日起,吴泽明将兼任饿了么CEO。公司原CEO,花名为昊宸的韩鎏今后专注分管即时物流中心,继续向吴泽明汇报。在内部信中,...

SpringBoot项目快速开发框架JeecgBoot——Web处理!

Web处理JeecgBoot框架主要用于Web开发领域。下面介绍JeecgBoot在Web开发中的常用功能,如控制器、登录、系统菜单、权限模块的角色管理和用户管理。首先启动后台项目,将其导入IDE...

腾讯即将开源Kuikly:基于Kotlin的纯原生跨端解决方案

IT之家3月4日消息,腾讯日前在端服务网站发布预告,即将开源Kuikly跨端开发框架。预告海报介绍称,Kuikly是基于KotlinKMM技术、客户端开发友好的全新跨端解决方案,可...

Python构建MCP服务器完整教程:5步打造专属AI工具调用系统

模型控制协议(ModelControlProtocol,MCP)是一种专为实现AI代理与工具解耦而设计的通信协议,为AI驱动应用程序的开发提供了高度的灵活性和模块化架构。通过MCP服务器,AI代...

Python3使用diagrams生成架构图(python模块制作)

目录技术背景diagrams的安装基础逻辑关系图组件簇的定义总结概要参考链接技术背景对于一个架构师或者任何一个软件工程师而言,绘制架构图都是一个比较值得学习的技能。这就像我们学习的时候整理的一些Xmi...

Python 失宠!Hugging Face 用 Rust 新写了一个 ML框架,现已低调开源

大数据文摘受权转载自AI前线整理|褚杏娟近期,HuggingFace低调开源了一个重磅ML框架:Candle。Candle一改机器学习惯用Python的做法,而是Rust编写,重...

Python Web 框架(Python Web 框架)

Tornado、Flask、Django三个PythonWeb框架的主要区别和适用场景:特点/框架TornadoFlaskDjango类型异步非阻塞Web服务器和框架轻量级微框架全功能...

构建并发布你的自定义 Python 包(python如何创建自定义模块)

Python让你可以重用代码,并将代码分享给他人以节省时间和精力。所以,当你编写了一些方便的脚本,希望你的同事或其他人也能使用时,接下来该怎么做呢?这篇文章就来解决打包和分发的问题。我们将专注于将你...

Python 应用开发框架 BeeWare 简明实用教程

1.BeeWare简介BeeWare是一个Python框架,用于开发跨平台原生应用。它支持Android、iOS、Windows、macOS和Linux,并提供原生用户体验。2.安装B...

取消回复欢迎 发表评论: