给大家分享一个自己搜集的java面试题

===========================List、Set、Map、Collection 区别
Collection、List、Set、Map都是接口,不能实例化。
Collection集合:
list数组:有序可重复,根据索引访问元素
|-ArrayList:数组,线程不安全,增删慢,查找快
|-LinkedList:链表,线程不安全,增删快,查找慢
|-Vector:老版数组,线程安全,效率低,增删慢,查找慢

Set接口:链表,无序,不可重复
	|—HashSet:红黑树,线程不安全,只能放入一个null
		|——LinkedHashSet:根据元素的hashCode值来决定元素的存储位置,它同时使用链表维护元素的次序,遍历集合以添加顺序访问元素,迭代访问性能高
	|-TreeSet:哈希表,线程不安全,允许null,有序且支持自然排序和定制排序
	
Map:哈希表-链表,无序,key-value存储数据,Key惟一,value可以重复,根据键找值
	|-HashMap: 底层散列表,允许一个空键多个空值,线程不安全(可使用Collections中静态方法SynchronizedMap()实现线程安全),高效
		|-LinkedHashMap:是 HashMap 的一个子类,保存了记录的插入顺序
	|-Hashtable : 底层散列表,不允许空键空值,线程安全,低效
	|-TreeMap:底层红黑树,可导航获取有序的key集合,实现了Cloneable接口能被克隆

===========================String、Stringbuffer、Stringbuilder
String:字符串常量,是不可改变的对象
StringBuffer:字符串变量
StringBuilder:字符串变量
执行速度:
StringBuilder > StringBuffer > String
安全性:
StringBuilder线程不安全,StringBuffer线程安全
使用场景:
少量数据:
String,
大量数据:
多线程用StringBuffer
单线程用StringBuilder

===========================重构、重写、重载
重构:代码优化,即代码修改
重载:同一类中,方法名相同,参数列表不同
重写:父子类中,子类中有一个方法名,参数列表和返回值类型与父类相同的方法完全相同

===========================同步和异步的区别
同步:提交请求->等待服务器处理->处理完毕返回响应,期间客户端不能干任何事
异步: 请求通过事件触发->服务器处理-期间客户端能干别的事>处理完毕返回响应
举例:普通B/S模式(同步)如打电话,AJAX技术(异步)如发消息

===========================解析xml
使用.DOM 或 .SAX 或 .DOM4J 或 .JDOM
DOM4J是一个非常优秀的解析xml工具,性能优异、功能强大,极端易用,且开源

===========================jsp九大内置对象和四大作用域
九大内置对象:Request、Response、Session、Application、Out、Config、Page、PageContext、Exception
1、Request对象
封装了用户提交的信息,可以获取用户提交的信息
2、Response对象
向客户端发送数据,分为转发和重定向
3、Session对象
从客户打开浏览器并连接到服务器开始到客户关闭浏览器离开这个服务器结束为一个会话。当一个客户访问一个服务器时可能会在这个服务器的多个页面之间切换,服务器通过Session确认是同一用户。
4、Application对象
服务器启动后就产生Application对象,直到服务器关闭,所有客户共享这个内置的Application对象
5、Out对象
是一个输出流,用来向客户端输出数据
7、Page对象
页面对象
8、PageContext对象
页面上下文对象
9、Exception对象
异常处理对象。
四个作用域:pageContext, request, session, application
pageContext
有效范围只在当前jsp页面里,到jsp页面结束,你都可以使用这个变量
request
有效范围是当前请求周期,请求发起到服务器返回响应的整个过程中,无论forward多少jsp页面,都可以使用这个变量
session
有效范围是当前会话,从用户打开浏览器开始到关闭浏览器整个过程的所有请求都可以使用
application
有效范围是整个应用,从服务器启动到关闭

===========================常见的SpringMVC注解

  1. @Controller
    定义控制器
  2. @RequestMapping
    (1)将URL映射到整个类,映射特定的请求路径到表单控制器上
    (2)将URL映射到特定的处理方法上,映射为一个特定的HTTP方法请求(“GET”,“POST”等)或HTTP请求参数。
    @Controller
    @RequestMapping("/favsoft")
    public class AnnotationController {
    @RequestMapping(method=RequestMethod.GET)
    public String get(){
    return “”;
    }
    @RequestMapping(value="/getName", method = RequestMethod.GET)
    public String getName(String userName) {
    return userName;
    }
    }
  3. @PathVariable
    将请求参数绑定到方法中的参数上
    请求:href=“springmvc/testPathVariable/1”
    @RequestMapping("/testPathVariable/{id}")
    public String testPathVariable(@PathVariable(“id”) Integer id){
    System.out.println(“testPathVariable:”+id);
    return SUCCESS;
    }
  4. @RequestParam
    将请求参数绑定到方法中的参数上,可以对传入参数指定参数名,可配置是否一定要传,参数为int类型时要配置defaultValue,否则不传时报错
    接收的参数是来自requestHeader中即请求头,常用于GET请求
    @RequestMapping(value = “/testRequestParam”)
    public String testRequestParam(@RequestParam(value=“username”)String un,@RequestParam(value = “age”,required = false,defaultValue = “0”) int age){
    System.out.println(“testRequestParam,username:”+un+",age,"+age);
    return “success”;
    }
  5. @RequestBody
    类似@RequestParam
    接收的参数是来自requestBody中即请求体,处理json、xml等类型的数据,常用于POST请求
  6. @ResponseBody
    将返回结果直接输入到HTTP response body中,常用于异步获取json数据

===========================删除list集合重复元素
1.遍历list集合判断后赋给另一个list集合
//遍历后判断赋给另一个list集合
public static void main(String[] args){
List list = new ArrayList();
List newList = new ArrayList();
for (String cd:list) {
if(!newList.contains(cd)){
newList.add(cd);
}
}
}
2.赋给set集合再返回给list集合(因为set不可重复)
//set集合去重,不打乱顺序
public static void main(String[] args){
List list = new ArrayList();
Set set = new HashSet();
List newList = new ArrayList();
for (String cd:list) {
if(set.add(cd)){//重复值无法添加到set,直接被过滤掉
newList.add(cd);
}
}
}
3.用treeset,去重并且按照自然顺序排列
List newList = new ArrayList(new TreeSet(list));

===========================数据库索引是什么、优缺点、类型、创建方式
索引好比书的目录,能加快数据库的查询速度,是对表中一列或多列的值进行排序
优点:
1.加快检索速度
2.创建唯一性索引,保证该数据唯一性
3.加速表和表之间的连接
4.在使用分组和排序子句进行数据检索时,可以显著减少检索时间。
缺点:
  1.索引需要占用物理存储空间
  2.创建和维护索引花费时间
  3.更新表数据时,索引需重建,降低了数据的写入速度。
类型:
唯一索引、主键索引、聚集索引
唯一索引: UNIQUE 例如:create unique index stusno on student(sno);
此索引的每一个索引值只对应唯一的数据记录
单列:保证单列值唯一
多列:保证多个值的组合唯一
主键索引: primary key
主键索引是唯一索引的特例,给表定义主键将自动创建主键索引
数据库表经常有一列或列组合,其值唯一标识表中的每一行,该列或列组合称为表的主键
聚集索引(聚簇索引):cluster
行的物理顺序与键值的逻辑(索引)顺序相同,一个表只能包含一个聚集索引,与非聚集索引相比,聚集索引通常提供更快的访问速度。
方式:
B+树、散列、位图

===========================springmvc和spring整合需要注意哪些问题
在spring mvc配置文件里只配置扫描controller层,在spring配置文件里扫描service和dao层,避免spring mvc重复扫server使得事务失效

===========================Spring中 Map、Model 、ModelMap、ModelAndView概念、区别、如何使用、底层浅谈
概念:
模型视图,合称Model大家族,用来封装后台返回前端的数据
区别:
LinkedHashMap接口
|-ModelMap:spring自动创建实例并作为controller的入参
|-Model:spring自动创建实例并作为controller的入参,实现类为ExtendedModelMap

ModelAndView:模型和视图的集合,既包含模型又包含视图,用户手动创建
			  构建ModelAndView实例时课设置跳转地址
					ModelAndView view = new ModelAndView("test");
					或
					ModelAndView view = new ModelAndView();
					view.setViewName("test");

===========================抽象类和接口的区别、使用场景
抽象类是对根源的抽象,表示这个对象是什么,只能单继承
接口是对动作的抽象,表示这个对象能做什么,可以多继承
关注事物本质时候用抽象类;关注动作操作时候用接口
抽象类的功能要远超过接口,但是定义抽象类的代价高,因为每个类只能继承一个类
虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述,一个类可实现多个接口,在设计阶段会降低难度

举例:金毛,折耳猫
抽象类:

金毛继承

折耳猫继承
接口:
吃东西
金毛、折耳猫都能吃东西,让金毛、折耳猫去实现
跑步
金毛、折耳猫都能跑步,让金毛、折耳猫去实现

===========================JAVA的三大特性,五大原则、简单理解面向对象思想
三大特性
封装:
属性——描述一类事物的特征
方法——描述一类事物的操作
概念:封装就是把属于同一类事物的共性属性与方法归到一个类中,以方便使用
优点:
(1)专业分工
(2)隐藏信息
继承:
概念:一个类继承另一个类,则称继承的类为子类,被继承的类为父类。
优点:代码复用
注意:子类可以写自己特有的属性和方法实现功能的扩展,也可以重写父类的方法,但是父类的私有属性和构造方法不能被继承

多态:
	概念:多态就是在抽象的层面上定义一个统一行为,到具体层面上时,这个统一的行为会因为具体的形态特征而实施自己的特征行为
	实际开发中是指程序中定义的引用变量所指向的具体类型和通过该引用变量引发的方法调用在编程时并不确定,而是在程序运行期间才确定
	
举例:造汽车(对象)
	抽象——首先,你要知道车要有哪些最基本的部件,如发动机、轮毂等,这一过称作抽象
	封装——因为工作量很庞大,需要找人一起造,但是不想让他知道造车的技术,可以把造车的技术隐藏起来,告诉别人只需要知道他自己要做什么就好了,这一过程称作封装
	继承——需要造很多车,想用之前造出来的某个车作为模板,进行“克隆”,用模板创出来的车具有模板的特征,就像孩子一样具有父母的性状,这一过程称作继承
	多态——很多车都是用模板“克隆”出来的,为了让品类更丰富多彩一些,对它们又进行了改变,这一过程称作多态

五大原则:
单一职责:
就一个类而言,应该仅有一个引起它变化的原因。
例如:不要将数据库的操作、文件的操作、算法的运用等都写在一个类中,应该按照功能不同各自分开,可实现代码复用
开发封闭:
是软件实体(类、模块、函数等),可以扩展的,但是不可修改
依赖倒置:抽象不应该依赖细节,细节应该依赖于抽象
例如:客户端向数据库插入数据,最初保存到MySql,现在改为保存到Oracle,应该对插入业务进行抽象,使客户端依赖插入业务,而不是依赖MySql或Oracle数据库操作。
里氏替换:子类必须能够替换掉他们的父类,意思是子类必须具有父类的所有特性
接口隔离:多个专用的接口优于一个单一的通用接口,不要把所有的方法都添加到一个接口中

===========================浅谈成员变量、局部变量区别和注意事项,static成员变量和非static成员变量的区别,finnl修饰变量、方法、类
成员变量、局部变量区别:
类中位置不同
成员变量:在类内方法外
局部变量:在方法内定义或者方法声明上。
内存位置不同:
成员变量:在堆内存
局部变量:在栈内存
生命周期不同:
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同:
成员变量:有默认值初始化
局部变量:没有默认值初始化,必须定义、赋值,然后才能使用
注意事项:局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。

static成员变量和非static成员变量的区别:
作用范围:
static成员变量:有全局变量的作用,被所有对象共享,当在类中改变他的值时,他在每个对象里面的值都会随之改变
非static变量:只会在具体所在的那个对象中改变,不会影响其它对象
加载方式:
static变量:在加载类时即即加载
非static变量:在实例对象时才加载
调用方式:
static成员变量:可以直接调用,可以直接通过类.name来调用
非static成员变量:需要对象来调用
生命周期:
static成员变量:从类被加载开始到类被卸载
非static成员变量:从创建对象开始到销毁对象
finnl修饰:
修饰变量:表示常量,只能被赋值一次,赋值后值不再改变
修饰方法:方法不能被子类方法覆盖,但可以被继承
修饰类:类不能被继承,没有子类,final类中所有方法都是final的

===========================mybatis中的#和KaTeX parse error: Expected 'EOF', got '#' at position 5: 的区别 #̲id#相当于对数据加上双引号“…iKaTeX parse error: Expected 'EOF', got '#' at position 11: 相当于直接显示数据 #̲方式能够很大程度防止sql注入…方式无法防止Sql注入,一般能用#的就别用$。
方 式 一 般 用 于 传 入 数 据 库 对 象 , 例 如 传 入 表 名 , M y B a t i s 排 序 时 使 用 o r d e r b y 动 态 参 数 时 需 要 注 意 , 用 方式一般用于传入数据库对象,例如传入表名, MyBatis排序时使用order by 动态参数时需要注意,用 ,MyBatis使orderby而不是#

===========================谈谈Spring的ioc、aop
Inversion of Control 控制反转
控制反转
spring的基础核心,指的是我们之前获取一个对象是主动new一个或使用反射获得,现在变成被动接受,也就是说我们在编写一个类的时候,
只需要提供一个接口不需要具体的实现类,而是使用者在使用的时候提供实现类,这样就降低了程序的耦合度。
依赖注入
是控制反转的一种实现方式,另一种是依赖查询,日常开发中,依赖注入使用的是最多的,实现依赖注入的方式有有两种,构造方法注入,set方法注入。
在Spring中的注入方式就有很多了,constructor-arg元素,property元素,p命名空间等等。
控制反转
|-依赖注入
|-构造方法注入
|-set方法注入
|-Spring中的注入方式
|-constructor-arg元素
|-property元素
|-p命名空间
|-依赖查询
AOP 面向切面编程
实际开发中,我们都会有一根业务主线,程序员要做的就是围绕业务主线上的需求,
实现功能,但是不可避免的,会有一些功能与业务主线没有关系又不能不做,
比如权限的控制,事务的控制,日志的记录等等,这些功能绝大多数时候和业务主线没有关系,但是却和很多业务核心方法交织在一起,使我们的开发变得麻烦,并且冗余代码增多。
而spring的提供了一种思想,把这些和业务主线没有关系的功能剥离出来,而在需要使用这些公共方法时,适时适地的把它加到我们的代码中去,
使程序员在开发时,把更多的精力放在理解需求,实现业务核心功能上,并且让我们的代码变得简洁。这种思想就是面向切面编程。
Spring实现面向切面编程使用的是动态代理技术,并且会根据实际情况来选择使用基于子类的还是基于接口的动态代理。

===========================进程和线程的区别,Runnable接口和Thread类的区别,线程用什么流最合适
进程
|-线程
<1>线程属于某个进程
<2>进程是CPU内存等资源占用的基本单位,线程不可以独立拥有这些资源。
<3>线程之间共享一块内存区域,通信比较方便。
<4>进程在执行的过程中,会包含比较固定的入口,执行的顺序和出口,线程的这些过程会被应用程序所控制。

<1>如果线程类继承了Thread类那么不可以再继承其他的类,而Runnable接口是可以的,因为Java支持单继承。
<2>如果要使用很多的线程的方法,使用Thread更方便。
<3>实现Runnable接口的线程类的多个线程,可以更方便地访问同一个变量。

管道流
多线程间的通信主要通过两种方式:共享变量和管道流。
共享变量一般通过加锁的方式来保证线程的安全性。
管道流主要用来实现两个线程之间的二进制数据的传播。

===========================转发和重定向的区别
Forward和Redirect代表了两种请求转发方式:直接转发和间接转发。
直接转发方式(Forward),客户端发出一次请求,服务器发现请求的资源无法完成客户端想要的响应,于是将请求转发给另外一个信息资源来响应该请求,
在请求对象request中保存的对象对于这两个信息资源是共享的,并且客户端浏览器的地址栏是没有变化的,也就是说客户端不知道服务器端做了转发操作。
间接转发方式(Redirect)实际是客户端发送了两次HTTP请求,服务器端在响应第一次请求的时候,告诉浏览器,你发送的地址不能获取想要的响应,
你应该请求另外一个资源,并将新的地址告诉浏览器,然后浏览器再向另外一个URL发出请求,从而达到转发的目的,此时浏览器地址栏会有变化。
举个通俗的例子:
直接转发就相当于:“A找B借钱,B说没有,B去找C借,借到借不到都会把消息传递给A”;
间接转发就相当于:“A找B借钱,B说没有,让A去找C借”。

===========================连接池的工作机制
一句话到位----连接池的实现是以空间换时间。
详细解释:
连接池的核心思想是连接的复用,建立一个数据库连接池以及一套连接使用、分配和管理策略,
使得该连接池中的连接可以得到高效,安全的复用,避免了数据库连接频繁建立和关闭的开销。
第一、连接池的建立。系统初始化时,连接池根据配置建立,并在池中建立指定数量的连接对象,以便使用时能从连接池中获取。
第二、连接池的管理。连接池管理策略是连接池机制的核心,连接的分配和释放对系统的性能有很大的影响。其策略是:
当请求数据库连接时,首先查看是否有空闲连接,有就分配使用;如没有则查看当前所开的连接数是否已经达到最大连接数,
如没有达到就重新创建一个连接供使用;如果达到,按设定的最大等待时间进行等待,超出最大等待时间,则抛出异常。
当使用者释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如超过就从连接池中销毁该连接,否则就保留为其他客户服务。
该策略保证了数据库连接的有效复用,避免了频繁建立释放连接所带来的系统资源的开销。
第三、连接池的关闭。当应用程序退出时,关闭连接池中所有的链接,释放连接池相关资源。

===========================你是否接触过AJAX,可以做什么使用
JavaScript能流行,一个很重要的原因是AJAX技术的应用。

直白地说,就是没用AJAX的网页,你点一个按钮就要刷新一下页面,尽管新页面上只有一行字,还是要无聊地等待页面刷新。
用了AJAX之后,点击按钮,页面上的一行字就变化了,页面本身不用刷。
1、 在搜索中,我们输入关键字时,网页会实时展现搜索结果;这是用AJAX实现的;
2、 使用地图时,地图会根据用户显示的位置不停的更新。这也是通过AJAX实现;
3、 开发中常见的用户保存操作,会验证用户名是否唯一啊,预留电话是否唯一啊等等。

谈谈你对HTTP、SOAP、MVC的理解?
HTTP是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。
SOAP 是一种简单的基于 XML 的协议,它使应用程序通过 HTTP 来交换信息。
MVC是Model—View—Controler的简称。即模型—视图—控制器。MVC是一种设计模式,它强制性的把应用程序的输入、处理和输出分开。

===========================Struts中如何体现(实现)MVC思想的
MVC = 模型、视图、控制器
模型:这个一般不由Struts来做
视图:视图也不算struts的强项,但是struts提供优秀的标签来支持视图的展示,利用标签,struts可以将数据合理的展示给用户
控制器:struts的重要功能,提供struts的过滤器,拦截用户的请求,查找struts配置文件,为其匹配一个对应的Action,
这个Action负责调用模型,获得数据,然后对数据做部分处理,接着Action再为处理后的数据选择一个视图进行输出。

===========================hibernate查询数据的方式
1.导航对象图查询
2.OID方式
3.HQL检索方式
4.QBC检索方式

===========================hibernate延迟加载(get和load的区别)
一种是通过session.get()方法,另一种就是通过session.load()方法,
然后其实这两种方法在获得一个实体对象时是有区别的,在查询性能上两者是不同的。
一.load加载方式
当使用load方法来得到一个对象时,此时hibernate会使用延迟加载的机制来加载这个对象,
即:当我们使用session.load()方法来加载一个对象时,此时并不会发出sql语句,当前得到的这个对象其实是一个代理对象,
这个代理对象只保存了实体对象的id值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出sql语句,从数据库中去查询我们的对象。
二、get加载方式
相对load,get就直接的多,使用session.get()方法来得到一个对象时,不管使不使用这个对象,此时都会发出sql语句去从数据库中查询出来:
因此,使用load的加载方式比get的加载方式性能要好一些,因为load加载时,得到的只是一个代理对象,当真正需要使用这个对象时再去从数据库中查询。
三、使用get和load时的一些小问题
①如果使用get方式来加载对象,当我们试图得到一个id不存在的对象时,此时会报NullPointException的异常
这是因为通过get方式我们会去数据库中查询出该对象,但是这个id值不存在,所以此时user对象是null,所以就会报NullPointException的异常了。
②如果使用load方式来加载对象,当我们试图得到一个id不存在的对象时,此时会报ObjectNotFoundException异常:
为什么异常不同呢?是因为load的延迟加载机制,使用load时,此时的user对象是一个代理对象,仅仅保存了当前的这个id值,
当我们试图得到该对象的username属性时,这个属性其实是不存在的,所以就会报出ObjectNotFoundException这个异常了。

===========================servlet的生命周期是什么
Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,
service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。

===========================JDBC的编码步骤
JDBC–java数据库连接,主要由接口组成。

0、前提:拷贝数据库的驱动到构建路径中(classpath)
1、注册驱动
2、获取与数据库的链接
3、创建代表SQL语句的对象
4、执行SQL语句
5、如果是查询语句,需要遍历结果集
6、释放占用的资源

===========================JDBC中的Statement和PreparedStatement的区别?用哪个更好?
1.statement每次执行sql语句,相关数据库都要执行sql语句的编译,PreparedStatement是预编译的,对于批量处理可以大大提高效率,也叫JDBC存储过程。
2.在对数据库只执行一次性存取的时侯,用Statement对象进行处理,PreparedStatement对象的开销比Statement大,对于一次性操作并不会带来额外的好处。
选择PreparedStatement对象与否,在于相同句法的SQL语句是否执行了多次,而且多次之间的差别仅仅是变量的不同。

===========================Hibernate中的update()和saveOrUpdate()的区别
答:update是修改的方法,saveOrUpdate是保存或者更新
saveorupdate()如果传入的对象在数据库中有就做update操作,如果没有就做save操作。
save()在数据库中生成一条记录,如果数据库中有,会报错说有重复的记录。
update()就是更新数据库中的记录

===========================spring和hibernate管理事务有啥区别
1、从编码上说,hibernate的事务管理是硬编码,是写在程序之中的,如果需要调整,就要修改源码,重新编译
2、从事务控制的位置来说,hibernate是持久层框架,事务控制在持久层造成了越权操作,事务应放在业务层
3、从代码维护上来说,hibernate控制事务要在每个需要事务支持的地方编写代码,后期维护不便

===========================spring中自动装配的方式
1、 No:
即不启用自动装配。
2、 byName:
通过属性的名字的方式查找JavaBean依赖的对象并为其注入。
3、 byType:
通过属性的类型查找JavaBean依赖的对象并为其注入。
4、 constructor:
同byType一样,也是通过类型查找依赖对象。与byType的区别在于它不是使用Seter方法注入,而是使用构造子注入。
5、 autodetect:
在byType和constructor之间自动的选择注入方式。
6、 default:
由上级标签的default-autowire属性确定。

===========================spring管理事务有几种方式,事务的特性,事务的实现方式
有两种方式:
1、编程式事务,在代码中硬编码。(不推荐使用)
2、声明式事务,在配置文件中配置(推荐使用)
声明式事务又分为两种:
a、基于XML的声明式事务
b、基于注解的声明式事务

特性:
1.原子性:一个事务中所有对数据库的操作是一个不可分割的操作序列,要么全做要么全不做
2.一致性:数据不会因为事务的执行而遭到破坏
3.隔离性:一个事物的执行,不受其他事务的干扰,即并发执行的事物之间互不干扰
4.持久性:一个事物一旦提交,它对数据库的改变就是永久的

基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,
在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。

===========================spring的理解
它是一个轻量级的开源框架,提供了从表现层到业务层再到持久层的一套完整的解决方案。
我们在项目中可以只使用spring一个框架,它就可以提供表现层的mvc框架,持久层的Dao框架。
它的两大核心IoC和AOP更是为我们程序解耦和代码简洁易维护提供了支持。
1、它的核心之一IoC,降低了我们程序的耦合度,使我们可以把项目设计成为一个可插拔的组件式工程。
2、它的另一大核心AOP,使我们在开发过程中,精力得到释放,可以更专注的去理解客户的需求。并且在后期维护时,可以只维护很少的一部分。
3、它提供的事务管理机制,采用声明的方式来配置事务,从而在维护时无需改动源码,解决了程序硬编码的弊端。
4、它提供的DAO模板使我们的持久层开发又多了一种途径。
5、它可以整合其他时下流行的框架,使我们在管理项目时,更加清晰,明确。

===========================hibernate的理解
hibernate框架是一个ORM的持久层框架,ORM的含义是对象关系映射,简单理解就是通过对象和关系型数据库之间建立映射信息,以后再操作对象就相当于操作数据库了。
hibernate框架是对JDBC进行了轻量级的封装,可以更方便简单的对数据库完成增删改查的操作。同时也提供了查询的方式和查询的策略。例如HQL和QBC的查询方式等。
还提供了缓存的策略,效率会更高。

===========================struts2的工作流程
1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求?
2.这个请求经过一系列的过滤器(Filter)
(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3.接着StrutsPrepareAndExecuteFilter被调用,StrutsPrepareAndExecuteFilter调用ActionMapper来解析和判断该次请求是否需要由struts2框架来处理;
4.如果ActionMapper判断需要struts2来处理请求,StrutsPrepareAndExecuteFilter会把请求的处理交给ActionProxy;
5.ActionProxy通过Configuration Manager加载框架的配置文件,找到需要调用的Action以及拦截器配置信息;
6.ActionProxy创建一个ActionInvocation的实例;
7.ActionInvocation实例使用命名模式来调用Action,在调用的过程前后,执行相关Intercepter拦截器;
8.Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果配置。
根据配置找到对应的Result处理类来处理结果集,大多数情况输出会交由模版语言(JSP,FreeMarker模板)完成输出内容拼装,
有时候也会跳转到其他的action链。

===========================Spring MVC 工作流程
1:用户向服务器发送请求,请求被前端控制Servelt DispatcherServlet捕获;
2:前端控制器对请求URL进行解析,得到请求资源标识符(URI),根据该URI调用HandlerMapping获得Handler以及该Handler配置的所有相关的对象
(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式向前端控制器返回Handler;
(可以根据xml配置、注解进行查找)
3:前端控制器调用处理器适配器HandlerAdapter,首先提取Request中的模型数据,填充Handler入参,然后执行Handler(Controller)。
在填充Handler的入参过程中,根据配置,Spring将做一些额外的工作:
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中,
执行完成后处理器适配器向前端控制器返回ModelAndView(ModelAndView是springmvc框架的一个底层对象,包括Model和view);
4:前端控制器请求视图解析器View resolver去进行视图解析,并向前端控制器返回View;
根据逻辑视图名解析成真正的视图(jsp)
5:前端控制器对视图View 进行渲染,并向用户响应结果;
视图渲染将模型数据(在ModelAndView对象中)填充到request域

组件:
1、前端控制器DispatcherServlet(不需要程序员开发)
作用接收请求,响应结果,相当于转发器,中央处理器。

2、处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的url查找Handler

3、处理器适配器HandlerAdapter
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler

4、处理器Handler(需要程序员开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler

5、视图解析器View resolver(不需要程序员开发)
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)

6、视图View(需要程序员开发jsp)
View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)

===========================Hibernate执行流程

1.通过配置文件管理器读取并解析hibernate.cfg.xml配置文件
Configuration config = new Configuration().configure();
2.由hibernate.cfg.xml中的读取并解析映射信息
3.通过Session工厂SessionFactory sf = config.buildSessionFactory();//创建Session-----Session session = sf.openSession();//打开Sesssion
4.Transaction tx = session.beginTransaction();//创建并启动事务Transation
5.persistent operate操作数据,持久化操作
6.tx.commit();//提交事务
7.关闭Session
8.关闭SesstionFactory

===========================Spring优缺点
----Spring优点:
1.解耦合
Spring框架主要用于与其他技术(struts,hibernate等)进行整合,充当了管理容器的角色。可将应用程序中的Bean组件实现低耦合关联,最终可以提高系统扩展和维护性。
例如:SSH框架的流程大致是:Jsp页面----Struts------Service(业务逻辑处理类)—Hibernate,
struts负责控制Service(业务逻辑处理类),这样层与层之间的依赖很强,属于耦合。使用spring框架可以控制Strus中的Action对象和Service类,
两者之间的关系就松散了,起到解耦合的作用。
Spring的Ioc(控制反转和依赖注入)
控制反转:由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控
依赖注入:组件之间的依赖关系由容器在运行期决定,由容器动态的将某种依赖关系注入到组件之中。

 从上面我们不难看出:从头到尾Action仅仅是充当了Service的控制工具,这些具体的业务方法是怎样实现的,

他根本就不会管,也不会问,他只要知道这些业务实现类所提供的方法接口就可以了。而在以往单独使用Struts框架的时候,
所有的业务方法类的生命周期,甚至是一些业务流程都是由Action来控制的。层与层之间耦合性太紧密了,既降低了数据访问的效率又使业务逻辑看起来很复杂,代码量也很多。
Spring容器控制所有Action对象和业务逻辑类的生命周期,由于上层不再控制下层的生命周期,层与层之间实现了完全脱耦,使程序运行起来效率更高,维护起来也方便。

2.事务的处理:
在以往的JDBCTemplate中事务提交成功,异常处理都是通过Try/Catch 来完成,而在Spring中容器集成了TransactionTemplate,
封装了所有对事务处理的功能,包括异常时事务回滚,操作成功时数据提交等复杂业务功能。这都是由Spring容器来管理,大大减少了程序员的代码量,
也对事务有了很好的管理控制。Hibernate中也有对事务的管理,hibernate中事务管理是通过SessionFactory创建和维护Session来完成。而Spring对SessionFactory配置也进行了整合,
不需要在通过hibernate.cfg.xml来对SessionaFactory进行设定。这样就可以很好的利用Sping对事务管理强大功能。
避免了每次对数据操作都要现获得Session实例来启动事务/提交/回滚事务还有繁琐的Try/Catch操作。
3.AOP思想
使开发业务逻辑更清晰、专业分工更加容易进行,更好的专注于客户的核心功能需求,将非客户需求却必须涉及的代码分开剥离,进行重复使用。

-----Spring缺点:
无明显缺点

===========================SpringMVC优缺点

--------优点:
和Struts2的比较,我们用struts2时采用的传统的配置文件的方式,并没有实现传说中的0配置。spring mvc基本可以认为已经100%零配置了(除了配置spring mvc-servlet.xml外)。

Spring MVC和Struts2的区别:
机制:spring mvc的入口是servlet,而struts2入口是filter(filter和servlet是不同的。以前认为filter是servlet的一种特殊)。

1.性能快:
spring比struts快。sturts是基于类设计,每次发一次请求都会实例一个action,每个action都会被注入属性,而mvc是基于方法的设计,粒度更细。
struts2是类级别拦截,每次来了请求就创建一个Action,然后调用setter、getter方法把request中的数据注入,
mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去,因此MVC效率更高。

2.配置简单,开发效率高
spring mvc的配置文件比struts简单,虽然struts的配置能继承,mvc使用更加简洁,开发效率上Spring MVC确实比struts2高。
3.验证亮点,支持JSR303
处理ajax的请求更是方便,只需一个注解@ResponseBody,然后直接返回响应文本即可。

--------缺点:
1.Spring与MVC 的Servlet API 耦合,难以脱离容器独立运行
2.过度追求完美,有过度设计的危险

===========================Struts2优缺点
-----Struts2 的优点:
1.对框架API和Servlet API的依赖少

Struts2的Action可以实现框架提供的Action接口也可以不实现这个接口。实际上框架Strut2的Action的要求很低,只要一个类,包含一个无参的、返回值类型为String的方法就行。
其实Struts2的Action就是一个POJO。如果用户写一个类实现框架提供的Action接口或者继承框架提供的ActionSupport类, 则可以利用框架中的其他一些功能。
比如,Action接口中定义了一些常量,这些常量通常作为返回值供处理方法调用。由于Struts2的Action对框架API和Servlet API的依赖减少,因此可测程度大大提高。

2.可扩展性提高
Struts2的核心jar包中由一个struts-default.xml文件,在该文件中设置了一些默认的bean,resultType类型,默认拦截器栈等,
所有这些默认设置,用户都可以利用配置文件更改,可以更改为自己开发需要的bean,resultType等。
因此用户开发了插件的话只要很简单的配置就可以很容易的和Struts2框架融合,实现了框架对插件可插拔的特性。

3.面向切面编程思想
最主要的体现就是拦截器的使用,拦截器就是一个个小功能单位,开发人员可以将这些拦截器合并成一个大的拦截器,
这个合成的拦截器就像单独的拦截器一样,只要将它配置到一个Action中就可以。

-----Struts2 的缺点:
1.在并发量比较大的场景中,每次请求都要创建一个Action,并维护很长的调用链(至少18个拦截器+OGNL解析+Action+Result),资源消耗比较大。
(缺点解决方案:SSH对于中小型项目提供了一套完整的解决方案.在表关系相对简单,数据量不大,并发量不高的项目中,能够极大的提高开发效率;
表关系复杂或数据量比较大时,可以使用Mybatis替换Hibernate;并发量很高时可以使用SpringMVC替换struts。)

===========================Hibernate 优缺点

--------Hibernate优点:
1.对象/关系映射型持久化框架(ORM),直接操纵对象等同操作数据库,开发更对象化,完全的面向对象思想;
2.它没有侵入性(没有侵入hibernate任何的API),即所谓的轻量级框架;
3.移植性会很好(作为持久层,极少或者不用存储过程和自定义函数,不使用触发器,可以让项目具有最好的可移植性。)
4.缓存机制,提供一级缓存和二级缓存(一级是Session级别,一个Session做了一个查询操作,会把这个操作的结果放在一级缓存中,
短时间内这个session(一定要同一个session)又做了同一个操作,hibernate直接从一级缓存中拿,而不会再去连数据库取数据。
二级缓存是SessionFactory级别的缓存,查询的时候会把查询结果缓存到二级缓存中,如果同一个sessionFactory创建的某个session执行了相同的操作,
hibernate就会从二级缓存中拿结果,而不会再去连接数据库。);
5.简洁的HQL、QBC等编程方式;
6.透明持久化(persistent)
带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。这些对象可能是普通的JavaBeans/POJO,这个对象没有实现第三方框架或者接口,唯一特殊的是他们正与(
仅仅一个)Session相关联。一旦这个Session被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用。(例如,用作跟表示层打交道的数据传输对象。) ?
--------Hibernate缺点:
1.Hibernate在批量数据处理时有弱势;
单一对象简单的增删查改,适合于Hibernate,批量的修改删除,不适合用Hibernate,这也是OR框架的弱点
2.要使用数据库的特定优化机制的时候,不适合用,优化策略应用不当会导致大量的资源消耗。

===========================MyBatis 优缺点
--------优点:

  1. 与JDBC相比,减少了50%以上的代码量。
  2. 简单小巧易学。
  3. 灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,降低耦合度,便于统一管理和优化,并可重用。
  4. 提供XML标签,支持编写动态SQL语句。
  5. 提供映射标签,支持对象与数据库的ORM字段关系映射。

--------缺点:

  1. SQL语句的编写工作量较大,尤其是字段多关联表多时,对SQL语句的功底有一定要求。
  2. SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

===========================Hibernate和mybatis有什么区别
1)mybatis是把sql语句与java代码分离了,sql语句在xml文件配置的
2)hibernate是ORM框架,它对jdbc进行了封装,在分层结构中处于持久化层,
它能建立面向对象的域模型和关系数据模型之间的映射.它大大简化了dao层的编码工作
3)mybatis是半自动的,hibernate是全自动的,就是说mybatis可以配置sql语句,
对于sql调优来说是比较好的,hibernate会自动生成所有的sql语句,调优不方便,hibernate用起来难度要大于mybatis

===========================springMVC和struts2的区别有哪些
1.springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
2.springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,
可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,
并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。
Jsp视图解析器默认使用jstl。

===========================MyBatis框架适用场合:
MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。
对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。

===========================SSM优缺点、使用场景?
1.Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,
不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,
最后将sql执行的结果再映射生成java对象。

2.Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,
非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,
一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,
如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

3.Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,
提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,
以及怎样用好Hibernate需要具有很强的经验和能力才行。
4.总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值