java框架面试题汇总

一 spring

1. IOC 和AOP两个核心特性

Spring 是一个开源框架,Spring可以做很多事情,它为企业级开发提供这些功能的底层都依赖于它的两个核心特性:IOC和AOP。

1.IOC:IOC控制反转也叫依赖注入,IOC 利用 java 反射机制,所谓控制反转是指,本来被调用者的实例是有调用者来创建的,这样的缺点是耦合性太强,IOC 则是统一交给 spring 容器来管理创建,将对象交给容器管理,你只需要在 spring 配置文件中配置相应的 bean,以及设置相关的属性,让spring 容器来生成类的实例对象以及管理对象。就比如:原来我的service层要调用dao层,service就要创建dao,但spring发现你的service层要依赖dao层后,就可以给你注入。

2.AOP:为 Aspect Oriented Programming 的缩写,意为:面向切面编程,可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
(1)比如说现在有一个类 iA,里面有增删改的方法,现在要在每个目标方法执行前后进行开启事务和提交事务。传统的思想是纵向继承:要想实现事务的功能的话,不得不采用 子类继承父类的方法,通过重写父类的目标方法,在此基础上加上事务,开启事务/提交事务,这样的话,代码重复率很高,每个方法都要写开启事务/提交事务,代码重复率太高。
(2)AOP 采取横向抽取机制:就是说,鉴于纵向继承出现重复的代码,把重复的代码提取出来放到一个类 B 中,然后 spring 生成一个代理类,他和目标类也就是类 A 实现相同的接口,拥有相同的方法,那么代理类就可以把类 B 和目标类都拿来,进行组合,对外访问的话,就是访问的代理类。
(3)就达到和纵向继承一样的效果。他在 spring 中是用反射去做,我们要做的就是编写目标类 A 和切面类类 B。然后告诉 spring,让 Spring 生成代理就行了,代码少了很多,但是功能一个不少。

举个例子在具体说说AOP吧。
在实现 jdk 动态代理之前必有存在接口。我们需要准备的就是:

  1. 目标类:就是接口与实现类。
  2. 切面类:就是上面提到的切面类B (切面类怎么理解呢,就是说我们想知道 这个目标方法到底执行了多长的时间,我们可以在每一个方法前后,加上一个时间戳,这样两个时间戳一剪就可以的出来。但是为每个方法都这样做的话,就跟静态代理差不多了。所以们横向的把这个计算时间的方法的给他提出来,单独的放到后一个类里面去。那这个就是切面类,用来存放,需要加强目标方法的那些个代码)。
  3. 工厂类:他用来生成代理。
    a.我们的思想就是要将这个切面类和目标类在代码执行的时候自动组合在一块。
    b.我们在写好接口、目标类和切面类后。重点是实现那个生成代理的工厂类。
    c.我们的工厂类必须得依赖目标类和切面类存在。
  4. 下来就是生成代理类了。
    我们调一个方法 Proxy.newInstance 方法,里面需要三个参数,
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
throws IllegalArgumentException

第一个参数就是类加载器,一般用的是当前类的类加载器。
第二个参数就是接口,就是代理类需要实现的接口。
第三个参数就是 InvocationHandler 处理类,这是一个接口,采用匿内部类实现它,实现 invoke 方法,实现它也需要参数。

Object invoke(Object proxy, Method method, Object[] args) throws Throwable 

第一个参数就是:代理对象本身
第二个参数就是:代理对象要 执行当前方法的 一个对象
第三个参数就是:实际的参数。我们准备好以后就是具体实现那个 invoke 方法,在 invoke 方法里面组合切面类的方法和目标类的方法。目标类的方法是 通过方法对象.invoke 方法传入目标和实际的参数实现的。
5. 这样就实现了动态代理。这就是我理解的 AOP。
.

2. spring优点

(1)方便解耦,简化开发(高内聚,低耦合)
Spring就是一个容器,可以将所有对象创建和依赖关系维护,都交给spring管理,spring工厂用于生成bean
(2)AOP编程的支持
可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术
(3)声明式事务的支持
只需要通过配置就可以完成对事务的管理,无需手动编程
(4)方便程序的测试
spring对Junit4支持,可以通过注解方便的测试spring程序
(5)方便集成各种优秀框架
spring内部提供了对各种优秀框架的支持,如mybatis等

3. 在 Spring 中,有几种依赖注入方式?

通常,依赖注入可以通过三种方式完成
即:构造函数注入、setter 注入、接口注入,在 Spring Framework 中,仅使用构造函数和 setter 注入。

<!-- 1、构造方法注入 --> 
    <bean id="teacher1" class="com.pojo.Teacher">
       <constructor-arg name="name" value="老刘"></constructor-arg>
        <constructor-arg name="age" value="36"></constructor-arg>
    </bean>
<!--  setter方法注入 -->  
    <bean id="stu" class="com.pojo.Student">
       <property name="name" value="lisi44"></property>
       <property name="age" value="99"></property>
   </bean>
4. 在 Spring 中,有几种配置 Bean 的方式?

三种,分别为:基于XML的配置、基于注解的配置、基于Java的配置
1.基于XML的配置:

<bean id="stu" class="com.pojo.Student">
       <property name="name" value="lisi"></property>
       <property name="age" value="22"></property>
   </bean>

2.基于注解的配置

@Autowired
	Student stu;

3.基于java 显式配置

@Bean
	public Clazz createClazz() {
		
		Clazz clazz=new Clazz();
		clazz.setName("自动化专业");
		return clazz;
	}
5. 区分 BeanFactory 和 ApplicationContext。

在这里插入图片描述

6. BeanFactory 实现原理

Spring 中的 BeanFactory 用到的就是简单工厂模式。
要想实现 Spring 中的 BeanFactory,无非就用到了以下几个技术:
1.使用简单工厂模式来处理 bean 容器。
2.解析 xml 文件,获取配置中的元素信息。
3.利用反射获实例化配置信息中的对象。
4.如果有对象注入,使用 invoke()方法。
5.实例化的对象放入 bean 容器中,并提供 getBean 方法。
通过以上步骤就实现了 spring 的 BeanFactory 功能,只要在配置文件中配置好,实例化对象
的事情交给 BeanFactory 来实现,用户不需要通过 new 对象的方式实例化对象,直接调用
getBean 方法即获取对象实例。

7 Spring 的事务传播行为

如果在开始当前事务之前,一个事务上下文已经存在了,此时有若干选项可以指定一个事务性方法的执行行为。
1.int PROPAGATION_REQUIRED = 0 (required 需要)
如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
2.int PROPAGATION_SUPPORTS = 1 (support 支持)
如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
3.int PROPAGATION_MANDATORY = 2 (mandatory 必须的,强制的)
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
4.int PROPAGATION_REQUIRES_NEW = 3; (required_new 需要新事务)
创建一个新的事务,如果当前存在事务,则把当前事务挂起。
5.int PROPAGATION_NOT_SUPPORTED = 4; (不支持)
以非事务方式运行,如果当前存在事务,则把当前事务挂起。i
6.int PROPAGATION_NEVER = 5 (never 绝不)
以非事务方式运行,如果当前存在事务,则抛出异常。
7. int PROPAGATION_NESTED =6 (nested 嵌套)
如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;

8 你用过哪些重要的 Spring 注解?

@Controller - 用于 Spring MVC 项目中的控制器类。
@Service - 用于服务类。
@Repository :用于dao
@RequestMapping - 用于在控制器处理程序方法中配置 URI 映射。
@ResponseBody - 用于发送 Object 作为响应,通常用于发送 XML 或 JSON 数据作为响应。
@PathVariable - 用于将动态值从 URI 映射到处理程序方法参数。
@Autowired - 用于在 spring bean 中自动装配依赖项。
@Qualifier - 使用 @Autowired 注解,以避免在存在多个 bean 类型实例时出现混淆。
@Scope - 用于配置 spring bean 的范围。
@Configuration,@ComponentScan 和 @Bean - 用于基于 java 的配置。
@Aspect,@Before,@After,@Around,@Pointcut - 用于切面编程(AOP)。

9 Spring Bean 有哪些作用域,它们之间有什么区别?

singleton :这种 bean 范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个 bean 的实例,单例的模式由 bean factory 自身来维护 。
prototype :原形范围与单例范围相反,为每一个 bean 请求提供一个实例 。
request :在请求 bean 范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后, bean 会失效并被垃圾回收器回收 。
Session :与请求范围类似,确保每个 session 中有一个 bean 的实例,在 session 过期后, bean 会随之失效 。
global-session : global-session 和 Portlet 应用相关 。 当你的应用部署在 Portlet 容器中工作时,它包含很多 portlet。 如果你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全局变量需要存储在 global-session 中 。

10 请解释一下,Spring 框架有哪些自动装配模式,它们之间有何区别?
  • no :这是 Spring 框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在 bean 定义中用标签明确的设置依赖关系 。
  • byName :该选项可以根据bean 名称设置依赖关系 。 当向一个 bean 中自动装配一个属性时,容器将根据 bean 的名称自动在在配置文件中查询一个匹配的 bean。 如果找到的话,就装配这个属性,如果没找到的话就报错 。
  • byType :该选项可以根据 bean 类型设置依赖关系 。 当向一个 bean 中自动装配一个属性时,容器将根据 bean 的类型自动在在配置文件中查询一个匹配的 bean。 如果找到的话,就装配这个属性,如果没找到的话就报错 。
  • constructor :构造器的自动装配和 byType 模式类似,但是仅仅适用于与有构造器相同参数的 bean ,如果在容器中没有找到与构造器参数类型一致的 bean ,那么将会抛出异常 。
  • autodetect :该模式自动探测使用构造器自动装配或者 byType 自动装配 。 首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在 bean 内部没有找到相应的构造器或者是无参构造器,容器就会自动选择 byTpe 的自动装配方式 。
11. Spring 框架中用到了哪些设计模式?请举例说明

Spring 框架中使用到了大量的设计模式,下面列举了比较有代表性的:
代理模式 — 在 AOP 和 remoting 中被用的比较多 。
单例模式 — 在 spring 配置文件中定义的 bean 默认为单例模式 。
工厂模式 —BeanFactory 用来创建对象的实例 。

12.请解释一下 Spring Bean 的生命周期?

spring bean 容器的生命周期流程如下:

  1. Spring 容器根据配置中的 bean 定义中实例化 bean。
  2. Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。
  3. 如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用 setBeanName()。
  4. 如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。
  5. 如果存在与 bean 关联的任何 BeanPostProcessors,则调preProcessBeforeInitialization() 方法。
  6. 如果为 bean 指定了 init 方法( 的 init-method 属性),那么将调用它。
  7. 最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
  8. 如果 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
  9. 如果为 bean 指定了 destroy 方法( 的 destroy-method 属性),那么将调用它。
13.前置后置环绕异常通知

Spring切面可以应用5种类型的通知:

  • 前置通知(Before):在目标方法被调用之前调用通知功能;
  • 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
  • 返回通知(After-returning):在目标方法成功执行之后调用通知;
  • 异常通知(After-throwing):在目标方法抛出异常后调用通知;
  • 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为;
14 Aop 的事务

Spring 的事务管理其实就是基于 DataSource 的事务理,也就是基于数据库的事务管理。Spring 提供的事务管理有两种:
编程式事务:(粒度控制在代码块,需要手动提交)
声明式事务:使用 xml,注解。粒度控制在 public 方法。
Spring 事务的隔离级别:在 mysql 中定义了 4 中隔离级别,读未提交 读已提交 可重复读 可串行化
在 spring 的事务管理中,定义了 5 种隔离级别。再此基础上 添加 默认隔离

二 springMVC

1.MVC

模型Model-视图View-控制器Controller(MVC)是一个众所周知的以设计界面应用程序为基础的设计模式。它主要通过分离模型、视图及控制器在应用程序中的角色将业务逻辑从界面中解耦。
model 考虑给用户展示什么。关注支撑业务的信息构成。构建成模型。
control 调用业务逻辑产生合适的数据以及传递数据给视图用于呈献。
view怎样对数据进行布局,以一种优美的方式展示给用户。
MVC模式的核心思想是:将业务逻辑从界面中分离出来,允许它们单独改变而不会相互影响。

2.Spring MVC
    Spring MVC,又名Spring Web MVC,是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架。

应用:分离了控制器、模型对象。
1.SpringMVC的体系结构
[外链图片转存失败(img-HymE4ETb-1567342734959)(./images/1567339548049.png)]

  • @RequestMapping 提供初步的请求信息,在请求离开浏览器时 ,会带有用户所请求内容的信息,至少会包含请求的 URL。但是还可能带有其他的信息,例如用户提交的表单信息。
  • DispacherServlet 截获请求后,所以 DispatcherServlet 会查询一个或多个处理器映射(handler mapping) 来确定请求的下一站在哪里。通过handel adapter将请求发送给 控制器。
  • 控制器(controller)在完成逻辑处理后,通常会产生一些信息,这些信息需要返回给用户并在浏览器上显示。这些信息被称为模型(model)。
  • 不过仅仅给用户返回原始的信息是不够的——这些信息需要以用户友好的方式进行格式化,一般会是 HTML。所以,信息需要发送给一个视图(view),通常会是 JSP。
  • 控制器所做的最后一件事就是将模型数据打包,并且标示出用于渲染输出的视图名。它接下来会将请求连同模型和视图名发送回 DispatcherServlet 。
  • 这样,控制器就不会与特定的视图相耦合,传递给 DispatcherServlet 的视图名并不直接表示某个特定的 JSP。实际上,它甚至并不能确定视图就是 JSP。相反,它仅仅传递了一个逻辑名称,这个名字将会用来查找产生结果的真正视图。DispatcherServlet 将会使用视图解析器(view resolver)来将逻辑视图名匹配为一个特定的视图实现,它可能是也可能不是 JSP。
  • 既然 DispatcherServlet 已经知道由哪个视图渲染结果,那请求的任务基本上也就完成了。它的最后一站是视图的实现(可能是JSP) ,在这里它交付模型数据。请求的任务就完成了。视图将使用模型数据渲染输出,这个输出会通过响应对象传递给客户端(不会像听上去那样硬编码) 。

三 Mybatis

1.Mybatis简介
Mybatis是一款优秀的持久层框架,它支持定制化SQL,存储过程以及高级映射。Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XM或注解来配置和映射原生类类型、接口和java的POJO(Plain Old Java Objects,普通老式java对象)为数据了中的记录。
Mybatis是一个半自动化的ORM框架,需要手工匹配提供POJO、SQL和映射关系。
2.为什么选择Mybatis?

它消除了大量的JDBC冗余代码
它有低的学习曲线
它能更好的与传统数据库协同工作
它可以接受SQL语句
它性能好
容易与第三方框架集成

3.Mybatis 缓存机制

(1)一级缓存
MyBatis 对缓存提供支持,俣是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个 SqlSession 而言。所以在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对像调用同一个Mapper 的方法,往往只执行一次 SQL,因为使用 SqlSession 第一次查询后,MyBatis 会将其在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没超时的情况下SqlSession 都只会取出当前缓存的数据,而不会再次发 SQL 到数据库。
(2)二级缓存
SqlSessionFactory 层面上的二级缓存是不开启的,二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的,也就是要求实现Serializable接口,配置的方法很简单,只需要在你的 SQL 映射文件中添加一行:
java <cache/>
这个简单语句的效果如下:
映射语句文件中的所有 select 语句的结果将会被缓存。
映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
缓存不会定时进行刷新(也就是说,没有刷新间隔)。
缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

(3)自定义缓存
除了上述自定义缓存的方式,你也可以通过实现你自己的缓存,或为其他第三方缓存方案创建适配器,来完全覆盖缓存行为。
java <cache type="com.domain.something.MyCustomCache"/>
使用一个自定义的缓存。type 属性指定的类必须实现 org.mybatis.cache.Cache 接口,且提供一个接受 String 参数作为 id 的构造器

4.动态 sql 概念

MyBatis 的强大特性之一便是它的动态 SQL。摆脱根据不同条件拼接 SQL 语句的痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。
MyBatis 中用于实现动态 SQL 的元素主要有:
1.if 语句 (简单的条件判断)
2. choose (when,otherwize) ,相当于 java 语言中的 switch ,与 jstl 中的choose 很类似.
3. where (主要是用来简化 sql 语句中 where 条件判断的,能智能的处理 and or , 不必担心多余导致语法错误)
4. set (主要用于更新时,功能和 where 标签元素差不多,主要是在包含的语句前输出一个 set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果 set 标签最终返回的内容为空的话则可能会出错( update set name = #{name}, where … ? )
5. trim (trim 元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是 prefix 和 suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是 prefixOverrides 和 suffixOverrides;正因为 trim 有这样的功能,它可以用来实现 where 和 set 的效果)
6. foreach (java中有for, 可通过for循环, 同样, mybatis中有foreach, 可通过它实现循环,循环的对象当然主要是java集合或数组。)

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值