1、为什么要使用 spring?
- spring 提供 ioc 技术,容器会帮你管理依赖的对象,从而不需要自己创建和管理依赖对象了,更轻松的实现了程序的解耦。
- spring 提供了事务支持,使得事务操作变的更加方便。
- spring 提供了面向切面编程,这样可以更方便的处理某一类的问题。
- 更方便的框架集成,spring 可以很方便的集成其他框架,比如 MyBatis、hibernate 等。
2、解释一下什么是 AOP ?
- AOP 是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
- 简单来说就是统一处理某一“切面”(类)的问题的编程思想,比如统一处理日志、异常等。
3、解释一下什么是 IOC ?
- IOC :Inversionof Control(中文:控制反转)是 spring 的核心,对于 spring 框架来说,就是由spring 来负责控制对象的生命周期和对象间的关系。
- 简单来说,控制指的是当前对象对内部成员的控制权;控制反转指的是,这种控制权不由当前对象管理了,由其他(类,第三方容器)来管理。
4、说一下@Autowired与@Resource?
- @Autowired和@Resource都是做bean的注入时使用;
- @Autowired由Spring提供,@Resource由J2EE提供,两种注入方式spring均支持;
- @Autowired只按照byType注入,但配合@Qualifier可实现byName注入;@Resource默认按照ByName自动注入,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。
5、说一下 spring mvc 运行流程?
- spring mvc 先将请求发送给 DispatcherServlet。
- DispatcherServlet 查询一个或多个 HandlerMapping,找到处理请求的 Controller。
- DispatcherServlet 再把请求提交到对应的 Controller。
- Controller 进行业务逻辑处理后,会返回一个ModelAndView。
- Dispathcher 查询一个或多个 ViewResolver 视图解析器,找到ModelAndView 对象指定的视图对象。
- 视图对象负责渲染返回给客户端。
6、spring mvc 有哪些组件?
- 前置控制器 DispatcherServlet。
- 映射控制器 HandlerMapping。
- 处理器 Controller。
- 模型和视图 ModelAndView。
- 视图解析器 ViewResolver。
7、spring mvc 和 struts 的区别是什么?
- 拦截级别:struts2 是类级别的拦截;spring mvc 是方法级别的拦截。
- 数据独立性:spring mvc 的方法之间基本上独立的,独享 request 和 response 数据,请求数据通过参数获取,处理结果通过 ModelMap 交回给框架,方法之间不共享变量;而 struts2 虽然方法之间也是独立的,但其所有 action 变量是共享的,这不会影响程序运行,却给我们编码和读程序时带来了一定的麻烦。
- 拦截机制:struts2 有以自己的 interceptor 机制,spring mvc 用的是独立的 aop 方式,这样导致struts2 的配置文件量比 spring mvc 大。
- 对 ajax 的支持:spring mvc 集成了ajax,所有 ajax 使用很方便,只需要一个注解@ResponseBody 就可以实现了;而 struts2 一般需要安装插件或者自己写代码才行。
8、什么是 spring boot?
- spring boot 是为 spring 服务的,是用来简化新 spring 应用的初始搭建以及开发过程的。
9、 为什么要用 spring boot?
- 配置简单
- 独立运行
- 自动装配
- 无代码生成和 xml 配置
- 提供应用监控
- 易上手
- 提升开发效率
10、spring boot 核心配置文件是什么?
- bootstrap (. yml 或者 . properties):boostrap 由父 ApplicationContext 加载的,比 applicaton 优先加载,且 boostrap 里面的属性不能被覆盖;
- application (. yml 或者 . properties):用于 spring boot 项目的自动化配置。
11、什么是 spring cloud?
- spring cloud 是一系列框架的有序集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 spring boot 的开发风格做到一键启动和部署。
12、spring cloud 断路器的作用是什么?
- 在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
13、spring cloud 的核心组件有哪些?
- Eureka:服务注册与发现。
- Feign:基于动态代理机制,根据注解和选择的机器,拼接请求 url 地址,发起请求。
- Ribbon:实现负载均衡,从一个服务的多台机器中选择一台。
- Hystrix:提供线程池,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题。
- Zuul:网关管理,由 Zuul 网关转发请求给对应的服务。
14、为什么要使用 hibernate?
- hibernate 是对 jdbc 的封装,大大简化了数据访问层的繁琐的重复性代码。
- hibernate 是一个优秀的 ORM 实现,很多程度上简化了 DAO 层的编码功能。
- 可以很方便的进行数据库的移植工作。
- 提供了缓存机制,使程序执行更高效。
15、什么是 ORM 框架?
- ORM(Object Relation Mapping)对象关系映射,是把数据库中的关系数据映射成为程序中的对象。
- 使用 ORM 的优点:提高了开发效率降低了开发成本、开发更简单更对象化、可移植更强。
16、hibernate 是如何工作的?
- 读取并解析配置文件。
- 读取并解析映射文件,创建 SessionFactory。
- 打开 Session。
- 创建事务。
- 进行持久化操作。
- 提交事务。
- 关闭 Session。
- 关闭 SessionFactory。
17、hibernate 的 get() 和 load() 的区别?
- get()和load()都会使用缓存,都是首先从一级缓存Session中查找,当找不到的时候再去二级缓存中查找,当查询不到的时候get()返回的是null,而load()则返回代理对象。
- get()方法被调用的时候就会立即发出SQL语句,调用load()方法的时候会返回一个目标对象的代理对象,在这个代理对象中只存储了目标对象的ID值,只有当调用除ID值以外的属性值的时候才会发出SQL查询的。
18、说一下 hibernate 的缓存机制?
- hibernate 常用的缓存有一级缓存和二级缓存:
- 一级缓存:Session缓存(又称作事务缓存),Hibernate内置的,不能卸除。缓存只能被当前Session对象访问。缓存的生命周期依赖于Session的生命周期,当Session被关闭后,缓存也就结束生命周期。可以通过evict(object)清除 object 的缓存;clear()清除一级缓存中的所有缓存;flush()刷出缓存。
- 二级缓存:SessionFactory级别缓存(又称作应用缓存),使用第三方插件,可插拔。它可以跨越Session存在,可以被多个Session所共享。二级缓存的生命周期依赖于应用的生命周期,应用结束时,缓存也就结束了生命周期。应用:多线程同时去load一个对象,这个对像本来可以放到内存中的,可是由于是多线程,是分布在不同的session当中的,所以每次都要从数据库中取,这样会带来查询性能较低的问题,这时候二级缓存的优势就提现出来了。
19、MyBatis 中 #{}和 ${}的区别是什么?
- #{} 是预编译处理, ${} 是字符替换。
- 在使用 #{} 时,MyBatis 会将 SQL 中的 #{} 替换成“?”,配合PreparedStatement 的 set 方法赋值,在使用 $ { } 时,MyBatis 会把 ${ } 直接替换成变量的值。
- 使用 #{}可以有效的防止 SQL 注入,保证程序的运行安全。
20、MyBatis 有几种分页方式?
- 分页方式:逻辑分页和物理分页。
- 逻辑分页: 使用 MyBatis 自带的 RowBounds 进行分页,它是一次性查询很多数据,然后在数据中再进行检索。
- 物理分页: 自己手写 SQL 分页或使用分页插件 PageHelper,去数据库查询指定条数的分页数据的形式。
21、MyBatis 分页插件的实现原理是什么?
- 分页插件 PageHelper 的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 SQL,然后重写 SQL,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。
22、MyBatis 是否支持延迟加载?延迟加载的原理是什么?
- MyBatis 支持延迟加载,设置 lazyLoadingEnabled=true 即可。相当于 Hibernate 的 load() 。
- 延迟加载的原理的是调用的时候触发加载,而不是在初始化的时候就加载信息。比如调用 a. getB().getName(),这个时候发现 a. getB() 的值为 null,此时会单独触发事先保存好的关联 B 对象的 SQL,先查询出来 B,然后再调用 a. setB(b),而这时候再调用 a. getB(). getName() 就有值了,这就是延迟加载的基本原理。
23、说一下 MyBatis 的一级缓存和二级缓存?
- 一级缓存:它的声明周期是和 SQLSession 一致的,有多个 SQLSession 或者分布式的环境中数据库操作,可能会出现脏数据。
- 二级缓存:其存储作用域为 Mapper级别的,如果多个SQLSession之间需要共享缓存,则需要使用到二级缓存,并且二级缓存可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable 序列化接口(可用来保存对象的状态)。
24、MyBatis 和 hibernate 的区别有哪些?
- 灵活性:MyBatis 更加灵活,自己可以写 SQL 语句,使用起来比较方便。
- 可移植性:MyBatis 有很多自己写的 SQL,因为每个数据库的 SQL 可以不相同,所以可移植性比较差。
- 学习和使用门槛:MyBatis 入门比较简单,使用门槛也更低。
- 二级缓存:hibernate 拥有更好的二级缓存,它的二级缓存可以自行更换为第三方的二级缓存。