面试题–开源框架
1 hibernate 和 mybatis 的区别?
- 相同点
- 都属于 ORM 框架
- 都是对 jdbc 的包装
- 都属于持久层的框架
- 不同点
- hibernate 是面向对象的;mabatis 是面向 sql 的。
- hibernate 是全自动的 orm;mabatis 是半自动的 orm。
- hibernate 查询映射实体类对象必须全字段查询;mybatis 可以不用。
- hibernate 可以级联操作;mybatis 则没有。
- hibernate 编写 sql 查询数据库大大降低了对象和数据库的耦合性;mybatis 提供动态 sql,需要手写 sql,与数据库之间的耦合性取决于程序员缩写的 sql 的方法,所以 hebernate 的移植性要远大于 mybatis。
- hibernate 有方言跨数据库;mybatis 依赖于具体的数据库。
- hibernate 拥有完整的日志系统,mybatis 则相对比较欠缺。
2 MyBatis 的优点?
-
- 基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML 里,解除 SQL 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用。
- 与 JDBC 相比,减少了 50% 以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接。
- 很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的数据库 MyBatis 都支持)。
- 能够与 Spring 很好的集成。
- 提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
3 MyBatis 的缺点?
- SQL 语句的编写工作量较大,尤其当字段多,关联表多时,对开发人员编写 SQL 语句的功底有一定要求。
- SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
4 MyBatis 是如何将 SQL 执行结果封装为目标对象?都有哪些映射形式?
-
- 使用 《 resultMap 》 标签,逐一定义数据库列名和对象属性名之间的映射关系。
- 使用 SQL 列的别名功能,将列的别名写为对象属性名。
- 有了列名与属性名的映射关系后,MyBatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,哪些找不到映射关系的属性,是无法完成赋值的。
5 MyBatis 中 #{} 和 ${} 的区别是什么?
-
- . #{} 是预编译处理, ${} 是字符串替换。
- MyBatis 在处理 #{} 时,会将 sql 中的 #{} 替换为 ?号,调用 PreparedStatement 的 set 方法来赋值;
MyBatis 在处理 ${} 时,就是把它替换成变量的值; - 使用 #{} 可以有效的防止 sql 注入,提高系统安全性。
6 MyBatis 框架使用的场合?
-
- MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案;
- 对性能的要求很高,或者需求变化较多的项目,如:互联网项目,MyBatis 将是不错的选择。
7 Spring 运行原理?
-
- 内部最核心的就算 IOC 了,之前是 new 对象,现在可以直接从容器中获取,动态注入,这其实就算利用 Java 里的反射。反射其实就是在运行时动态去创建,调用对象,Spring 就是在运行时,根据 Spring XML 的配置文件来动态的创建对象和调用对象里的方法。
- Spring 另一个核心就算 AOP 面向切面编程,可以为某一类对象,进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块的扩充的功能。这些都是通过配置类达到的(日志,事务等)。
- Spring 目的:就算让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring 根据这些配置,内部通过反射去动态的组装对象)要记住:Spring 是一个容器,凡是在容器里的对象才会有 Spirng 所提供的这些服务和功能。
- Spring 里用的最经典设计模式:模版方法模式。(有兴趣同学可以了解一下),核心容器组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
8 Spring 框架中都用到了哪些设计模式?
- 代理模式
在 AOP 中被使用最多 - 单例模式
在 Spring 配置文件中定义 bean 的时候默认的是单例模式 - 工厂模式
BeanFactory 用来创建对象的实例 - 模板方法
用来解决重复性代码 - 前段控制器
Spring 提供了 DisPatcherSerclet 来对请求进行分发 - 视图帮助
Spring 提供了一系列的 JSP 标签 - 依赖注入
它是贯穿于 BeanFactory / ApplicationContext 接口的核心理念
9 SpringIOC注入的几种方式?
- 构造器注入
- set 方法注入
- 接口注入
10 SpringIOC 是什么?
- SpringIOC 负责创建对象,管理对象(通过依赖注入(DI),扎u那个陪对象,配置对象,并且管理这些对象的整个生命周期)。
11 什么是控制反转(IOC),什么是依赖注入(DI)?
- IOC:
就是对象之间的依赖关系由容器来创建,对象之间的关系本来就是由我们开发者自己创建和维护的,在我们使用 Spring 框架后,对象之间的关系有容器来创建和维护,将开发者做的事让容器做,这就是控制反转。BeanFactory 接口是Spring IoC 容器的核心接口。 - DI:
我们在使用 Spring 容器的时候,容器通过调用 set 方法或者是构造器来建立对象之间的依赖关系。 - 控制反转是目标,依赖注入是我们实现控制反转的一种手段。
12 在Spring 中如何注入一个 java 集合?
- Spring 提供理论四种集合类的配置元素:
- List
该标签用来装配有重复值的 list 值; - set
该标签用来装配没有重复值的 set 值; - map
该标签可以用来注入键值对; - props
该标签用来注入键值对和字符串类型键值对。
- List
13 Spring 中的事件处理?
-
- Spring 的核心是 ApplicationContext,它负责管理 bean 的完整的生命周期。Spring 提供了一下内置事件:ContextRefreshedEvent,ContextStartedEvent,ContextStoppedEvent,ContextClosedEvent,RequestHandleEvent
- 由于 Spring 的事件处理是单线程的,所以如果一个事件被发布,直至并且除非所有的接受者得到该消息,该进程被阻塞并且线程将不会继续。因此,如果事件处理被使用,在设计应用程序时应注意。
- 监听上下文事件
- 自定义事件
14 使用 Spring 框架的好处是什么?
-
- 简化开发,解耦,集成其它框架
- 底侵入式设计,代码污染级别低。
- Spring 的 DI 机制降低看业务对象替换的复杂性,提高了软件之间解耦。
- SpringAOP 支持将一些通用的任务进行集中式的管理,例如:安全,事务,日志等,从而使代码能更好的服用。
15 Spring 中 beanFactory 和 ApplicationContext 的联系和区别?
- BeanFactory 是 spring 中较为原始的 Factory,无法支持 spring 的许多插件,如 AOP 功能,Web 应用等。
- ApplicationContext 接口是通过 BeanFactory 接口派生而来的,除了具备 BeanFactory 接口的功能外,还具备资源访问,事件传播,国际化消息访问等功能。
- 总体区别如下:
- 使用 AppliccationContext,配置 bean 默认配置是 singleton,无论是否使用,都会被实例化;优点是预先加载,缺点是浪费内存。
- 使用 BeanFactory 实例化对象时,配置的 bean 等到使用的时候才会被实例化。优点是节约内存,缺点是速度比较慢,多用于移动设备的开发。
- 没有特殊要求的情况下,应该使用 ApplicationContext 完成,ApplicationContext 可以实现 BeanFactory 所有可实现的功能,还具备其他更多的功能。
16 什么是 Spring bean?
- Bean 是构成用户应用程序主干的对象
- Bean 是由 Spring IOC 容器管理;
- Bean 由 Spring IOC 容器实例化,配置,装配和管理;
- Bean 是基于用户提供给容器的配置元数据创建。
17 Spring bean 的生命周期?
-
- Spring 容器根据配置中的 bean 定义实例化 bean。
- Spring 使用依赖注入填充所有属性,如 bean中定义的配置。
- 如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用 setBeanName() 。
- 如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。
- 如果存在与 bean 关联的任何 BeanPostProcessors,则调用 preProcessBeforeInitialization() 方法。
- 如果为 bean 指定了 init 方法( 的 init-method 属性),那么将嗲偶用它。
- 最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
- 如果 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
- 如果 bean 指定了 destory() 方法(《bean》 的 destroy-method 属性),那么将会调用它。
18 解释 Spring 支持的几种 bean 的作用域?
- 当通过 Spring 容器创建一个 Bean 实例的时候,不仅可以完成 bean 实例的实例化,还可以为 bean 指定作用域。
Spring bean 元素支持一下五种作用域:- Singleton 单例模式
在整个 SpringIOC 容器中,使用 singleton 定义的 bean 将只有一个实例。 - Prototype 多例模式
每次通过容器中的 getBean 方法获取 prototype 定义的 beans 时,都会产生一个新的 bean 的实例。 - Request
对于每次 Http 请求,使用 request 定义的 bean 都会产生一个新的实例。只有在 Web 应用的时候,该作用域才会生效。 - Session
对于每次 Http Session ,使用 session 定义的 bean 都将产生一个新的实例。 - Globalsession
每个全局的 Http Session ,使用 session 定义的 bean 都将产生一个新的实例。
- Singleton 单例模式
19 Spring 的重要注解?
- @Controller
用于 Spring MVC 项目中的控制器类; - @Service
用于服务类; - @RequertMapping
用于在控制器处理程序方法中配置 URL 映射; - @ResponseBody
用于发送 Object 作为响应,通常用于发送 XML 或者 JSON 数据作为响应; - @PathVariable
用于将动态值从 URL 映射到处理程序方法参数; - @Autowired
用于在 spring bean 中自动装配依赖项; - @Qualifier
使用 @Autowired 注解,以避免在存在多个 bean 类型实例时出现混淆; - @Scope
用于配置 spring bean 的范围; - @Configuration,@ComponenScan 和 @Bean
用于基于 java 的配置; - @Aspect,@Before,@After,@Around,@Pointcut
用于切面编程(AOP)。
20 Spring 中 @Autowire 与 @Resource 的区别?
- @Autowire 默认按照类型装配,默认情况下它要求依赖对象必须存在,如果允许为 null,可以设置它 required 属性为 false, 如果我们向使用按照名称配置,可以结合 @Qualifier 注解一起使用;
- @Resouce 默认按照名称装配,当找不到与名称匹配的 bean 才会按照类型装配,可以通过 name 属性指定,如果没有指定 name 属性,当注解标注在字段上,即默认取字段的名称作为 bean 名称寻找依赖对象,当注解标注在属性的 steer 方法上,即默认取属性名作为 bean 名称作为依赖对象。
21 @Component,@Controller,@Repository,@Service 有何区别?
-
- @Component
将 java 类标记为 bean。它是任何 Spring 管理组件 的通用构造型。Spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。 - @Controller
这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会导入到 IoC 容器中。 - @Service
此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。你可以在服务层类中使用 @Service 而不是 @Component,因此它以更好的方式指定意图。 - @Repository
这儿注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 SpringDataAccessException。
- @Component
22 列举 spring 支持的事务管理类型?
- spring 支持两种类型的事务管理:
- 程序化事务管理:
在此过程中,在编程的帮助下管理事务。它为你提供极大的灵活性,单维护起来非常困难。 - 声明式事务管理:
在此,事务管理与业务代码分离。进使用注解或基于XML的配置来管理事务。
- 程序化事务管理:
23 Spirng 框架的事务管理有哪些优点?
-
- 它为不同的事务 API (如JTA,JDBC,Hibernate,JPA 和 JDO) 提供了统一的编程模型。
- 它为编程式事务管理提供了一个简单的 API 而非一系列复杂的事务 API (如JTA)。
- 它支持声明式事务管理。
- 它可以和 Spring 的多种数据访问技术很好的融合。
24 Spring 的事务传播行为?
-
PROPAGATION(蔓延,传播,传输)
事务传播行为类型 说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务;如果已经存在一个事务,就加入到这个事务中。这是默认是事务传播行为。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 使用当前事务,如果当前没有事务,就跑出异常。
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,就把当前事务挂起;(一个新的事务将启动,而且如果有一个现有事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。)
PROPAGATION_NOT_SUPPORTED 以非事务的方式执行操作,如果当前存在事务,酒吧当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。(外层事务抛出异常回滚,那么内层事务必须回滚,反之内层事务并不影响外层事务)
25 什么是 Spring 自动装配?
- 就算将一个 Bean 注入到其它的 Bean 的 Property 中,默认情况下,容器不会自动装配,需要我们手动设定。Spring 可以通过向 Bean Factory 中注入的方式来搞定 bean 之间的依赖关系,达到自动装配的目的。
- 自动装配建议少用,如果要使用,建议使用 ByName 。
26 自动装配有哪些方式?
-
- no
这是默认设置,表示没有自动装配。应使用显式 bean 引用进行装配。 - byName
他根据 bean 的名称注入对象依赖项。他匹配并装配其属性与 XML 文件中由形同名称定义的 bean。 - byType
它根据类型注入对象依赖项。如果属性的类型与 XML 文件中的一个 bean 名称匹配,则匹配并装配属性。 - 构造函数
它通过调用类的构造函数来注入依赖项。它有大量的参数。 - autodetect
首先容器尝试通过构造函数使用 autowire 装配,如果不能,则尝试通过 byType 自动装配。
- no
27 自动装配有什么局限?
-
- 覆盖的可能性
始终可以使用《constructor》和《property》设置指定的依赖项,这将覆盖自动装配。 - 基本元数据类型
简单属性(如原数据类型,字符串和类)无法自动装配。 - 令人困惑的性质
总是喜欢使用明确的装配,因为自动装配不太精确。
- 覆盖的可能性
28 Spring AOP(面向切面)编程的原理?
-
- AOP 面向切面编程,他说一种思想。它就算针对业务处理过程中的切面进行提取,以达到优化代码的目的,减少重复代码的目的。就比如,在编写业务逻辑代码的时候,我们习惯性的都要写:日志记录,事务控制以及权限控制等,每一个子模块都要写这些代码,代码明显存在重复。这时候我们运用面向切面的编程思想,采用横切技术,将代码中重复的部分,不影响业务逻辑的部分抽取出来,放在某个地方进行集中式管理,调用。形成日志切面,事务控制切面,权限控制切面。这样,我们就只需要关系业务的逻辑处理,即提高了工作的效率,又使得代码变得简洁优雅。这就是面向切面的编程思想,他就是面向对象编程思想的一种扩展。
- AOP 的使用场景:
缓存,权限管理,内容传递,错误处理,懒加载,记录跟踪,优化,校准,持久化,资源池,同步管理,事务控制等。AOP 的相关概念:切面(Aspect),连接点(JoinPoint),通知(Advice),切入点(Pointcut),代理(Proxy):织入(WeaVing) - Spring AOP 的编程原理:
代理机制 JDK 的动态代理:只能用于实现了接口的类产生代理。
Cglib 代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强技术,生成当前类的子类对象。
29 AOP 有哪些实现方法?
实现 AOP 的技术,主要分为两大类:
- 静态代理
指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可以生成 AOP 代理类,因此也称为编译时增强;
编译时编织(特殊编译器实现)
类加载时编织(特殊的类加载器实现) - 动态代理
在运行时在内存中“临时“ 生成 AOP 动态代理类,因此也被称为运行时增强。
JDK 动态代理,CGLIB
30 解释一下代理模式?
- 代理模式
代理模式就是本该自己做的事情,自己不做,交给代理人去完成。
代理模式的使用,需要有本类和代理类,本类和代理类共同实现统一的接口。在后在 main 中调用就可以了。本类中的业务逻辑一般是不会变动的,在我们需要的时候可以不断的添加代理对象,或者修改代理类来实现业务的变更。 - 代理模式划分
- 静态代理
优点:可以做到在不修改目标对象功能的前提下,对目标功能扩展。
缺点:因为本来和代理类要实现统一的接口,所以会产生很多的代理类,类太多,一旦接口增加方法,目标对象和代理对象都要维护。 - 动态代理(JDK 代理/ 接口代理)
JDK 代理:代理对象不需要实现接口,代理对象的生成,是利用JDK 的 API ,动态的在内存中构建代理对象,需要我们指定代理对象/ 目标对象实现的接口的类型。
Cglib 代理:在内存中构建一个子类对象,从而实现对目标对象功能的扩展。
- 静态代理
- 使用场景
修改代码的时候,不用随便修改别人已经写好的代码,如果需要修改的话,可以通过代理的方式来扩展该方法。
隐藏某个类的时候,可以为其提供代理类,当我们要扩展某个类功能的时候,可以使用代理类来实现。
减少本类代码量的时候,需要提升处理速度的时候,就可以采用代理模式,当雨哦拿过来需要的时候才生产实例,这样就能提高访问速度。
31 Spring MVC框架有什么用?
- Spring Web MVC 框架提供 模型-视图-控制器 架构和随时可用的组件,用于开发灵活且松散耦合的 Web 应用程序。MVC 模式有助于分离应用程序的不同方面,如输入逻辑,业务逻辑 和 UI 逻辑,同时在所以这些元素之间提供松散耦合。
32 SpringMVC 工作流程?
-
- 用户发送请求至前段控制器 DispatcherServlet;
- DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器;
- 处理器映射器根据请求 url 找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)并返回给 DispatcherServlet;
- DispatcherServlet 通过 HandlerAdapter 处理器适配器调用处理器;
- 执行处理器(Controller,也叫后端控制器);
- Controller 执行完成返回 ModelAndView;
- HandlerAdapter 将 Controller 执行结果 ModelAndView 返回给 DispatcherServlet;
- DispatcherServlet 将 ModelAndView 传给 ViewReslover 试图解析器;
- ViewReslover 解析后返回具体 View
- DispatcherServlet 对 VIew 进行渲染视图(即将模型数据填充至视图中);
- DispatcherServlet 响应用户
33 Spring MVC 的运行流程?
- DispatcherServlet 前置控制器
| HandlerMapping 请求映射(到 Controller)
| HandlerAdapter 请求映射 (到 Controller 类的方法上) | Controller 控制器
| HandlerIntercepter 拦截器 | ViewResolver 视图映射 | View 视图处理
34 Spring MVC 和 struts2 的区别有哪些?
- 拦截机制不同:
- Struts2 是类级别的拦截,每次请求就会创建一个 Action,和 Spring 整合时 Struts2 的 ActionBean 注入作用域是原型模式 prototype,通过 setter,getter 把 request 数据注入到属性。Struts2中,一个 Action 对于一个 request,response 上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。Struts2 中 Action 的一个方法可以对应一个 url’。而其类属性却被所有方法共享,这也就无法用注解或其它方式标识其所属方法了,只能设计为多例。
- Spring MVC 是方法级别的拦截,一个方法对应一个 Request 上下文,所以方法直接基本上是独立的,独享 request,response 数据。而每个方法同时又和一个 url 对应,参数的传递是直接注入到方法中,是方法所独有的。处理结果通过 ModeMap 返回给框架。在 Spring 整合时,Spring MVC 的 Controller Bean 默认为单例模式 Singleton,所以默认对所有的请求只会创建一个 Controller,又因为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加 @Scope 注解修改。
- Struts2 有自己的拦截 Interceptor 机制, Spring MVC 用的是独立的 AOP 方式,这样导致 Struts2 的配置文件量还是比 Spring MVC 大。
- 底层框架的不同:
Struts2 采用 Filter(StrutsPrepareAndExecuteFilter)实现;
Spring MVC(DispatcherServlet)则采用 Servlet 实现。
Filter 在容器启动之后即初始化;服务器停止后坠毁,晚于 Selvet。
Selvet 在调试时初始化,先于 Filter 调用,服务器停止后销毁。 - 性能方面:
Struts2 是类级别的拦截,每次请求对应实例一个新的 Action,需要加载所有的属性值注入,Spring MVC 实现了零配置,由于 Spring MVC 基于方法的拦截,有加载一次单例模式 bean 注入。所以,Spring MVC 开发效率和性能高于 Struts2。 - 配置方面:
Spring MVC 和 Spring 是无缝的。所以在项目的管理和安全上也比 Struts2 高。
35 拦截器与过滤器的区别?
-
- 拦截器是基于 java 的反射机制的,而过滤器是基于函数回调;
- 拦截器不依赖与 servlet 容易,过滤器依赖于 servlet 容器;
- 拦截器只能对 action 请求起作用,而过滤器则可以对几乎所有的请求起作用;
- 拦截器只能对 action 请求起作用,而过滤器则可以对几乎所有的请求起作用;
- 在 action 的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
36 介绍一下 WebApplicationContext?
- WebApplicationContext 是 ApplicationContext 的扩展。它具有 Web 应用程序所需的一些额外功能。
- 它与普通的 ApplicationContext 在解析主题和决定与哪个 servlet 关联的能力方面有所不同。