java面试题(仅供参考)

                                        java面试题(仅供参考)

框架阶段 概念宝典 1
自我介绍——P2P网贷项目 4
第三个月 基础框架篇 8
一、基础概念篇 8
1、Get和Post的区别? 8
2、List,Set,Collection,Collections的区别? 8
3、 StringBuffer、StringBuilder、String 区别? 8
4、MVC框架思想 9
5、HashMap和Hashtable的区别 9
6、网络七层协议 10
二、框架概念篇 12
Hibernate 12
Spring 18
Springmvc 29
三、JQuery 篇 38
1、jquery $(document).ready() 与window.onload的区别 38
2、你知道jquery中的选择器吗,请简单介绍一下? 39
3、jquery常用方法总结 40
4、JQuery 常用的事件 40
5、请谈一下你对Ajax的认识 41
6、ajax 三种使用方式 42
7、ajax 常用属性 42
8、Json 43
第四个月SSM框架篇 44
一、基础篇 44
1、Map介绍,以及map的底层;list介绍,以及list底层 44
2、接口和抽象类有什么区别?或者问你选择使用接口和抽象类的依据是什么? 45
3、乐观锁和悲观锁的区别?(最全面的分析) 46
二、 框架篇 47
一、SpringMVC 48
二、 Spring 50
三、mybatis 56
四、 SSM 60
五、linux 篇 62
第五个月 概念总结 64
一、 基础篇 64
1. 你对xml和json是怎么理解的? 64
2. final,finally,finalize 三者区别 65
3、什么叫GC? 66
二、数据库篇 66
1、索引的概述 66
2、oracle三层分页 67
3、数据库的三大范式和五大约束? 67
4、就业必会 复杂sql? 70
三、框架篇 72
1、你对maven是怎么理解的? 72
2、Mybatis介绍之缓存 72
3、Mybatis的批量操作数据库?(了解,并会使用) 73
4、easyui分页的实现思路? 74
5、easyui常用组件? 74
6、easyui常用组件属性及方法? 74
7、简述前台框架(easyui) 75
8、bootstrap常用组件? 76
9、bootstrap常用css样式? 76
10、session和cookie的区别? 79
11、如果项目中有异常该怎么处理?业务逻辑层能不能捕获异常?(了解) 79
四、技术篇 81
1、redis的三大特点以及优势,redis常用数据类型(标记理解,认识,必须掌握)? 81
2、什么是缓存穿透,什么是缓存雪崩,以及如何解决? 82
3、redis与memcache的区别分析 82
4、Redis 和 spring整合的步骤。Redis的使用业务场景。哪些东西不适合用缓存? 83
5、mongodb常用命令?(了解) 85
6、Redis 和Mongodb 的 区别? 87
7、Mongodb 和spring整合 步骤。 spring 提供的工具类,常见方法。 mongdb 使用的业务场景。哪些业务使用Mongodb 反而会麻烦? 87
8、简单介绍一下你对Webservice的理解 88
9、HttpClient的讲解 90
人事面试问题汇总 90
1.为什么要离职? 90
2.薪资多少? 91
3.以前做过的项目? 91
4.说说你的优缺点? 91
5.你能做一个自我介绍? 91
6.介绍一下你以前的公司? 91
7.你对加班有什么看法? 92
8.你还有什么问题吗? 92
9.你为什么还没有找到合适的岗位? 92
10.谈谈你未来几年的职业规划? 92
11.你的业余爱好是什么? 92
12.你觉得对这个工作感兴趣吗? 92
13.谈谈你的一个失败的经历? 92
14.说说你会在我们工作待多久? 93
15. 简单介绍一下你的缺点? 93

自我介绍——P2P网贷项目
您好,我先做一下自我介绍吧,我叫XXX,我从事java开发,到现在工作有四年的时间了。我上家公司是XXX,在这四年开发中主要接触过电商系统(易尚商城),网贷系统(优投网贷)、办公系统(协同办公)等。

【项目二】P2P网贷

我最近做了一个P2P网贷的项目。这个项目主要目的是针对个体(个人、企业或组织)和个体之间通过互联网平台实现的直接借贷。整个项目分为前台系统(用户访问平台)与后台管理系统两个项目。
前台项目主要涉及的模块:是债券模块(展示债券以及用户购买时生成订单)、出借模块、借款模块、推广模块、信息披露模块、用户管理模块(登录注册、个人中心)。判断如果为新用户还涉及到一个新手引导流程。
后台系统的模块:则分为用户管理模块,业务管理模块(债券的发布、上下架及调整、合同的POI导出),推广管理模块、统计管理模块(HighCharts报表完成用户登录及注册次数的统计、每日购买量的统计、资金统计等等)基本设置(前台信息披露模块中展示的公司基本信息)、财务管理(主要涉及到用户充值管理,线下充值,提现管理,用户信用管理,用户担保管理,不良债权转让管理,商城的退款管理,平台调账管理)等等。
我在项目中主要负责的是前台的债券模块、出借模块、借款模块、业务管理、财务管理模块。
2.1债券模块:
首先是将后台上架的债权信息展示给前台,购买流程为当用户点击购买某个债权时首先判断债券剩余的数量是否足够,如果足够则生成订单(此时订单状态为0未付款)并在库存中减去相应的数量,该订单如果在15分钟内未完成付款操作,则自动取消。生成订单后根据用户录入的银行卡信息调出相应的银行接口让用户进行付款(这里也可以添加新的银行卡)。用户这边付款后再通过银行接口返回的流水号查询是否付款成功。付款成功则将订单状态修改为1已付款,购买成功并通知用户,同时通知后台客服对订单做出处理。
如果两个用户同时购买了100份库存只有100的债权?
如果两个用户同时购买了100份库存只有100的债权。则只会有一个用户购买成功。因为此处使用RabbitMQ消息队列的原因。消息队列是根据日志信息从左到右执行的。所以即使是同时发出了生成订单的请求,在执行完左侧生成的订单消息之后,因为数据库中库存已经不够了,所以第二个订单生成是不会成功的。
业务管理模块中主要涉及的有债券管理,催收管理,合同管理,借款管理。
2.2 债券管理:
比如债券的发布、上下架及调整,当债权信息有了更新以后。在业务逻辑层直接调用前台项目中重新生成静态化页面(freemarker)的方法将之前的债券展示信息替换掉。替换成功后才会提交事务,避免前台展示的数据与后台数据库中的数据出现偏差。
催收管理模块:主要是根据用户还款的时间来及时给用户提醒。通过定时器来每天进行一次判断。比如说在距离还款还有一周的时候,调用短信接口(httpclient)来给用户发送提示短信进行通知,在还款当天再次提醒用户逾期将会产生违约金等。在逾期三天之后会提醒客服对客户进行催收以及对催收情况的统计。逾期一个月以上的用户可添加至黑名单。
订单生成后会自动添加到合同列表中。在合同管理中可以进行详情查看以及直接将合同导出为Word文档进行打印。
借款管理:首先用户选择相应的借款类型,在用户发出了借款申请后。首先是由审核部门对该用户信用级别(黑名单中的用户无法发出申请/信用等级越高的用户可申请的额度就越高,同时也根据抵押物来判断申请借款的金额)以及抵押物的一个审核。(此时默认状态为审核中),在审核通过后状态变更为已审核未发布,此时业务部门可以进行该借款的发布。发布以后前台用户就可以看到该信息并且借贷给该用户。当金额足够以后将状态变更为“已满标”。同时由财务部门将钱打给申请借款的用户。
2.3 财务管理:我在这个模块中主要负责充值管理,线下充值,提现管理这几个模块。
充值管理与线下充值管理:主要是对用户充值到此平台上的金额的一个记录的展示。考虑到安全问题,在该平台中只能对它进行查询而不能进行更改操作。且在该用户余额进行购买债券或借出操作时会有一个审核。
提现管理:用户在前台系统发出提现申请后,该条信息就会在提现管理中展示出来(状态为:申请提现),首先由业务部门核实后更改状态为(已审核,未打款),然后由财务部门进行打款。将状态更改为已提现。

后台管理系统包括:会员管理,业务管理,系统管理,财务管理,统计管理,推广管理等主要模块

2.4会员管理:是对会员信息统计和管理(包括个人信息,企业信息,机构信息),会员的认证管理,留言管理等。
会员认证管理:通过该功能新注册用户可以通过必要的用户认证后获得非0的借款信用额度而拥有有效的借款申请权限,在通过非必须、额外的用户认证来更进一步提高用户的借款信用额度,使用户可以在同一时间取得更大额度的借款。
必要的用户认证:主要包括:身份证认证,工作认证,收入认证,芝麻信用报告认证等。
额外的用户认证:主要包括:学历认证,房产认证,技术职称认证,购车证明等。
留言管理:主要是针对会员在“帮助中心”的留言,及时进行恢复。
2.5 业务管理:是我们网贷的核心模块,主要有理财管理,借款管理,催收管理,合同管理等
2.6 理财管理:有在线债券的管理和线上债券的转让管理。
2.7 借款管理:有借款管理、个人借款意向管理和企业借款意向管理。借款管理中主要是负责对借款申请的审批(主要负责审查用户的借款类型和抵押物以及其他申请是否合理),并负责在前台展示借款信息的页面进行招标。招收到的资金已满的话,后台进行审核后,做放款处理。
2.8 催收管理:代还款列表,催收记录,黑名单。
代还款列表展示的是借贷用户的信息,便于后台人员的统计和催收的通知,催收的实现使用的是定时器+Webservice来实现的,正常还款的用户通过使用定时器,在还款期限前三天通过调用Webservice短信接口,发送短信给用户,提醒用户还款。对于逾期3—7天用户,通过定时器实现线上的催收(发送短信,还款期限已逾期),对于逾期7天以上的用户,通过定时器通知后台管理人员,通过Poi技术导出相对应的逾期用户信息,通过线下催款的方式催收贷款。对于严重逾期的用户,线下催收的同时加入黑名单,不在提供服务给该用户。
2.9 系统管理:主要有后台账号,系统日志,业务推广等,需要使用shiro权限框架.
后台账号主要分为业务员账号管理,管理员账号管理,用户账号管理等,在这模块中要实现登录用户的权限限制。
因为涉及到资金的安全,所以我们做了日志记录的统计,所有增删改的操作都要生成相应的日志,做一个日志的统计,方便责任到人。
业务推广板块主要是对一些活动的推广,发送邮件和站内推广信给用户。
2.10 财务管理:主要有资金管理,资金明细等。
资金管理中包括:充值管理,线下充值管理,提现管理,放款管理,用户信用管理,用户担保管理等
资金的明细主要是对平台资金的流向做相应的统计,通过Poi导出到做线下的会议使用。
2.11 统计管理:主要有用户统计,资金统计,业务统计,统计报表等(使用highcharts技术),主要用于业务的推广方式。
用户统计:主要是针对用户注册的方式的统计,方便后期的业务推广。
资金统计:是看平台的资金的流动情况和盈亏情况。
业务统计:平台业务情况的查看,以及业务后期的推广重心。
2.12 推广管理:推广奖励,奖励金管理,活动管理等。
第三个月 基础框架篇
一、基础概念篇
1、Get和Post的区别?
1.get是从服务器上获取数据,post是向服务器传送数据,
2.get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。
3.get安全性非常低,post安全性较高。但是执行效率却比Post方法好。
4.在进行文件上传时只能使用post而不能是get。
2、List,Set,Collection,Collections的区别?
List和Set都是接口,他们都继承于接口Collection,List是一个有序的可重复的集合,而Set的无序的不可重复的集合。 Collection是集合的顶层接口,Collections是一个封装了众多关于集合操作的静态方法的工具类,因为构造方法是私有的,所以 不能实例化。
List接口实现类有ArrayList,LinkedList,Vector。ArrayList和Vector是基于数组实现的,所以查询的时候速度快,而在进行增加和删除的时候速度较慢LinkedList是基于链式存储结构,所以在进行查询的时候速度较慢但在进行增加和删除的时候速度较快。又因为Vector是线程安全的,所以他和ArrayList相比而言,查询效率要低。
3、StringBuffer、StringBuilder、String 区别?
这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。
1.首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。以下面一段代码为例:
1 String str=“abc”;
2 System.out.println(str);
3 str=str+“de”;
4 System.out.println(str);
2. 再来说线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
3. 总结一下
  String:适用于少量的字符串操作的情况
  StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
  StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
4、MVC框架思想
MVC是一种分层架构的思想,主要是将Web项目结构进行分成controller、Model、View三个层次,在初期设计中,MVC也包含了持久层。Controller层作为控制层,主要是响应用户请求,接收并校验用户参数(因为用户有可能通过某种方式跳过页面的js验证,比如直接在地址栏发起请求),调用业务逻辑层,也就是Mode层完成业务操作,最后根据业务处理的结果,完成页面跳转到View层。在Model层中,主要是完成了各种业务逻辑操作。View层主要负责视图展示,通常不应该设计业务操作,View层常用的技术包括:html、jsp等等。
5、HashMap和Hashtable的区别
HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。
1、HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。
2、HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
3、另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
4、由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
5、HashMap不能保证随着时间的推移Map中的元素次序是不变的。
6、网络七层协议
谈到任何联网的协议,我们就必须要谈到OSI(网络七层协议模型),必须遵循这个协议模型,我们的手机和电脑才可以联网通信,首先来看一下OSI
OSI
OSI是一个开放性的通信系统互连参考模型,他是一个定义得非常好的协议规范。OSI模型有7层结构,每层都可以有几个子层。
应用层
示例:TELNET,HTTP,FTP,NFS,SMTP等。
表示层
示例:加密,ASCII等。
会话层
示例:RPC,SQL等。
传输层
示例:TCP,UDP,SPX。
网络层
示例:IP,IPX等。
数据链路层
示例:ATM,FDDI等。
物理层
示例:Rj45,802.3等。
简单了解OSI之后我们来看一下我们手机与电脑通信,所能够使用的两种数据通信,一种是HTTP请求,一种是Socket通信,HTTP是属于短连接,适合新闻,订票信息等客户端发起请求,每一次请求结束,自动断开连接。而Socket是属于长连接,适合游戏,聊天等实时数据。
手机能够联网都是需要基于OSI协议模型,同时手机底层实现了TCP/IP协议。
以下为了解部分:
下面简单介绍一下TCP/IP协议
TCP/IP
建立起一个TCP连接需要经过“三次握手”:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握 手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连 接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”(过程就不细写 了,就是服务器和客户端交互,最终确定断开)
同时Socket可以支持不同的传输层协议(UDP),那我们平时为什么不使用UDP呢,我们现在来看一下UDP与TCP的区别
TCP UDP
是否连接 面向连接 面向非连接
传输可靠性 可靠 不可靠
应用场合 传输大量数据 少量数据
速度 慢 快

二、框架概念篇
Hibernate
1、hibernate的概述?
hibernate是一个对JDBC进行轻量级封装的持久层框架
hibernate是全自动的(将常用方法进行了封装,不用手动进行结果集的解析)
hibernate是跨数据库的,
hibernate的开发效率高于jdbc,
hibernate使用的hql语句,
但是在最后操作数据库是hql语句会转化成sql语句去执行,
hibernate操作的是对象from实体类名
2、Hibernate 多表联查的实现方式核心代码?
hibernate很多实现都是靠喜欢配关系,但是如果两张表,数据量都非常大的时候,并不合适配关系。
例如:student表和score表需要做联合查询。
1)sql: select s.id,s.name,sc.score from student as s,score as sc where s.id = sc.userId;(字段都是用的数据库中字段名称)
2)HQL: select s.id,s.name,sc.score from Student as s,Score as sc where s.id = sc.userId;(上面字段都是 javabean的属性)
如果我们按1)查询的话,必须调用 session.createSQLQuery();方法
如果按2)查询,还是调用 session.createQuery();
只是要注意,平时我们查询的时候,例如:“from Student ”查询的结果集封装的全都 是student对象,但是2)执行的结果集里面不是对象,而是一系列数组。需要转换成需要的样式。

3、Hibernate中的五大核心类和接口?
1.Configuration(类) : 加载配置文件hibernate.cfg.xml文件中的配置信息,从而得到:
1).hibernate的底层信息:数据库连接,jdbc驱动,方言(dialect),用户名 ,密码
2).hibernate的映射文件(*.hbm.xml)
2.SessionFactory(接口):通过configuration创建的sessionFactory,可以用来获得session.openSession(); sessionFactory是线程安全的,里面保存了数据的配置信息和映射关系
3.Session(接口):不是线程安全的,相当于jdbc中connection,我们可以使用session来操作数据库负责保存、更新、删除、加载和查询对象,是一个非线程安全的,避免多个线程共享一个session,是轻量级,一级缓存。
4.Transaction(接口):session.beginTransaction(); //由于Hibernate增删改需要使用事务所以这里要开启事务session.getTransaction().commit();//提交,我们一般使用Transaction来进行事务的管理commit(提交)rollback(回滚)
5.Query(接口):我们一般用来进行数据的查询操作
4、Hibernate中两种占位符是(?)和(:变量名)?
1). ?的赋值方式: query对象.setParameter(index,value)
2). :变量名赋值方式: query对象.setParameter(“变量名”,value)
5、Hibernate中query对象的常用方法?
query对象.executeUpdate() 方法对数据进行修改或者删除
query对象.uniqueResult() 方法返回单条记录,获取唯一结果集
query对象.setFirstResult() 方法设置结果集开始位置,查询开始条数
query对象.setMaxResults() 方法设置每页查询条数
query对象.list() 方法返回查询结果集
6、Hibernate中session 对象的常用方法有?
1.find(String queryString) 查询返回list结果集 ,根据HQL查询字符串来返回实例集合find方法在执行时会先查找缓存,如果缓存找不到再查找数据库,如果再找不到就会返回null。
2.save(Object entity) 添加 保存新的实例
3.saveOrUpdate(); 添加或修改 有id是修改 没id 是更新
4.delete(Object entity); 删除 删除指定的持久化实例
5.update(Object entity); 修改 更新实例的状态 实例必须为持久化状态
6.get(Class entityClass,Serializable id)根据ID查询 根据主键加载特定持久化实例
7.load();根据唯一标识获得 对象 延迟加载
7、 get 和 load 的区别,以及注意事项?
1).load是延迟加载(懒加载,按需加载)调用load方法后不会立即发送SQ语句,当访问实体属性的时候才会去发送SQL语句,如果访问的实体不存在,则返回ObjectNotFoundException(对象不存在异常)
2).get 是立即加载,当调用get方法后立即发送sql语句,当访问的实体不存在的时候,则返回null,get(Class entityClass,Serializable id)根据主键加载特定持久化实例。
在程序中一般先用 Assert.isTrue断言id是否大于0,若大于0继续执行,若查到数据,则返回实例,否则返回空不同于load,load若有数据则返回实例,否则报出ObjectNotFoundEcception异常,相比来说get效率高些。
注意:
load支持懒加载通过lazy=“true”设置,如果lazy=“false”,则load不再进行懒加载,默认情况下lazy=“true”。
8、五个hibernate主键生成策略并分别描述?
1).Increment:先查询出最大id,在此基础上加1;hibernate框架会自动处理
2).Sequence(Orade) :oracle 数据库会自动处理
    3).Assigned:人工指派(重复插入数据时会违反数据唯一性)
    4).native:(数据库本地生成策略,适用多个数据库),适用于mysql.oracle,sqlserver,如果是orade数据库则默认使用的序列名为hibernate-sequence
    5).uuid:生成一个32位,不会重复的主键,可以达到真正的跨数据库(通常来说对应的应该是string数据类型)
    6).foreign:通常在一对一主键的时候使用,基于外键的主键生成策略
9、Hibernate的二级缓存。Ehcache介绍
1).Hibernate缓存分为:
一级缓存即session缓存也叫事务级别的缓存以及二级缓存sessionFactory即应用级别的缓存,还有查询缓存即三级缓存。
一级缓存的生命周期和session的生命周期保持一致,hibernate默认就启用了一级缓存,不能将其关闭,可以通过session.clear()和session.evict(object)来管理一级缓存。其中get,load,iterate都会使用一级缓存,一级缓存缓存的是对象。
二级缓存的生命周期和sessionFactory的生命周期保持一致,可以跨session,被多个session共享,hibernate3默认开启二级缓存,也可以手动开启并指定缓存插件如ehcache,oscache等。二级缓存也只能缓存对象。
三级缓存也叫查询缓存,查询缓存是针对普通属性结果集的缓存,对实体对象的结果集只缓存id。对query.list()起作用,query.iterate不起作用,也就是query.iterate不使用查询缓存
2).Ehcache的介绍:
2.1).Ehcache是一个非常轻量级的缓存实现,而且从1.2之后就支持了集群,而且是hibernate默认的缓存provider。EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。
2.2).Ehcache的分布式缓存有传统的RMI,1.5版的JGroups,1.6版的JMS。分布式缓存主要解决集群环境中不同的服务器间的数据的同步问题。
2.3).使用Spring的AOP进行整合,可以灵活的对方法的返回结果对象进行缓存。
2.4).CachingFilter功能可以对HTTP响应的内容进行缓存。
2.5).主要特性:
1. 快速.
2. 简单.
3. 多种缓存策略
4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题
5. 缓存数据会在虚拟机重启的过程中写入磁盘
6. 可以通过RMI、可插入API等方式进行分布式缓存
7. 具有缓存和缓存管理器的侦听接口
8. 支持多缓存管理器实例,以及一个实例的多个缓存区域
9. 提供Hibernate的缓存实现等等。

10、事务的概述
在数据库中,所谓事务是指一组逻辑操作单元即一组sql语句。当这个单元中的一部分操作失败,整个事务回滚,只有全部正确才完成提交。
事务的ACID属性

  1. 原子性(Atomicity)
    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,
    要么都不发生。
  2. 一致性(Consistency)
    事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏)
  3. 隔离性(Isolation)
    事务的隔离性是指一个事务的执行不能被其他事务干扰.
  4. 持久性(Durability)
    持久性是指一个事务一旦被提交,
    它对数据库中数据的改变就是永久性的.
    在JDBC中,
    事务默认是自动提交的,
    每次执行一个 SQL 语句时,如果执行成功,
    就会向数据库自动提交,而不能回滚
    为了让多个 SQL 语句作为一个事务执行:
    (1)执行语句前调用 Connection 对象的 setAutoCommit(false);
    以取消自动提交事务
    (2)在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
    (3)在出现异常时,调用 rollback(); 方法回滚事务。
    11、Hibernate常用注解?
    @Entity:声明实体bean,每一个持久化POJO类都是一个实体bean,这可以通过在类的定义中使用@Entity注解来进行声明:
    @Id:注解则声明了该实体bean的标识属性,对应相应表使用id列作为主键列
    @Table:是类一级的注解, 通过@Table注解可以为实体bean映射指定表(table),目录(catalog)和schema的名字. 如果没有定义@Table,那么系统自动使用默认值:实体的短类名(不附带包名).
    @Transient:自动生成表时忽略某个字段
    @GeneratedValue:定义该标识符的生成策略
    AUTO - 可以是identity column类型,或者sequence类型或者table类型,取决于不同的底层数据库.
    TABLE - 使用表保存id值
    IDENTITY - identity column
    SEQUENCE - sequence
    @OneToOne注解可以建立实体bean之间的一对一的关联.
    @ManyToOne注解来定义多对一关联

Spring
1、spring概述
我认为spring就是一个框架的集成器,通常使用spring来管理action层和DAO层。
Spring本身有很多的组件,比如:MVC、IOC、AOP、DaoSupport等等。IOC本身也就是一个容器,它管理了所有的bean和bean之间的依赖关系。IOC也叫作控制反转,核心是BeanFactory。也就意味着IOC是基于工厂模式设计的,同时这个工厂生产的bean默认是单例的。如果想修改单例变成多实例,则需要修改bean的scope属性,值是prototype。
在没有使用IOC以前,程序员需要自己在对应的类中new相关依赖的对象。比如UserAction依赖于UserService完成业务操作,而UserService又依赖于UserDAO完成数据库操作。所以需要在action中new servcie,在service中new DAO。这样的方式,是由程序员来管理了对象的生命周期和他们之间的依赖关系,耦合度很高,不利于程序的拓展。所以通过IOC来管理bean和依赖关系,可以解耦合。我们将所有的action、service和dao等类定义成IOC的一个bean组件,此时类的实例化就交给了IOC的beanFactory,由工厂来负责实例化bean的对象。
IOC有三种注入方式,属性注入、构造器注入和接口注入。接口注入只是spring提出的设计,并没有具体的实现,所以常用的注入方式是属性注入。属性注入就是在bean的标签中,配置property标签设定注入其他的bean。要求注入的bean在被注入的bean中要存在一个全局的私有变量,并提供set方法。这样就可以实现了依赖关系的注入。如果需要很多的bean,则直接注入就可以。如此操作会导致bean标签的配置比较冗余复杂,所以spring提供了autowried的自动装配方式,可以byName也可以byType。后续的版本中,spring还提供了annotation的方式,不需要再去定义多余的bean标签,而是直接在对应的类上面声明注解就可以了。常用的注解有:@controller、@Service、@Repository、@Component、@AutoWried、@Resource等。
除了IOC以外,项目中通常通过AOP来实现事务控制。AOP就是面向切面编程,一般事务我们会控制在service层,因为一个service有可能会调用到多个DAO层的方法,所以只有当一个service方法执行成功后,再提交或者回滚事务。具体的配置方式是:在applicationContext.xml中,配置aop:config标签,指定事务控制在service层。除此还需要配置事务的管理类transactionManager,将这个transactionManager指定给事务管理的bean,并且配置事务的传播特性、隔离级别、回滚策略以及只读事务read-only等等。
Spring默认的传播特性是如果当前上下文中存在事务则支持当前事务,如果没有事务,则开启一个新的事务。还有另外一个传播特性是在项目中经常用的,REQUIRES_NEW这个配置,这个属性指的是总是开启一个新的事务,如果当前上下文中存在一个事务,则将当前的事务挂起后开启新的事务。比如说:在一个本来是只读事务的操作中,想加入写操作的时候,就使用REQUIRES_NEW。关于事务的隔离级别,一般使用默认的配置提交读。也就是说,事务提交以后,才能访问这条数据。除了事务控制以外,我们通常还可以使用AOP去完成一些特殊操作,比如日志控制、安全校验等等。这么做的目的就是将功能操作的代码从实际的业务逻辑操作出分离出来。实现的方式是通过代理模式,真正完成操作的不是实际的业务对象而是代理对象。
代理模式有静态代理和动态代理,实现的方案也有两种,一种是基于JDK的Proxy代理类,另外一种则通过CGLIB来实现。实现AOP的方式,主要是在applicationContext中定义一个AOP处理类,这就是一个普通的bean,在类中定义要执行的方法。然后去配置一个aop:config标签,在标签中定义aop:aspect切面,在切面中关联刚才定义好的处理类bean。然后在切面标签中配置aop:pointcut切入点,切入点就指的是在哪个类的哪个方法上加入代理事务,然后配置通知模型。AOP的通知模型中包含:前置通知、后置通知、最终通知、异常通知、环绕通知。这几个通知模型表示在方法执行以前、执行以后、最终执行、当遇到异常时执行以及前后都执行。在执行的AOP切面方法中,可以通过JoinPoint连接点来获得当前被代理的对象以及被代理对象要执行的方法和方法的参数。除了IOC和AOP,我们经常还会使用到spring的DaoSupport。主要是spring提供了对hibernate和myBatis等持久型框架的接口。比如HibernateDaoSupport,和sqlSessionDaoSupport。如果DAO继承了HibernateDaoSupport,则需要在对应的bean中注入sessionFactory。而sessionFactory是通过IOC加载的。

2、Spring源码学习之spring设计理念和整体架构(了解)
1.Spring的设计理念:在Java EE的应用开发中,支持POJO和使用JavaBean的开发方式, 使应用面向接口开发,充分支持00 ( 面向对象) 的设计方法。
2.Spring的整体架构:

1.SpringloC:包含了最为基本的IoC容器BeanFactory的接口与实现,也就是说,在这个Spring的核心包中,不仅定义了IoC容器的最基本接口(BeanFactory),也提供了一系列这个接口的实现,如XmlBeanFactory就是一个最基本的BeanFactory (IoC容器),从名字上可以看到,它能够支持通过XML文件配置的Bean定义信息。除此之外,SpringIoC容器还提供了一个容器系列,如SimpleJndiBeanFactory、 StaticLismbleBeanFactor等。我们知道,单纯一个IoC容器对于应用开发来说是不够的.为了让应用更方便地使用IoC容器 ,还需要在IoC容器的外围提供其他的支持 ,这些支持包括Resource访问资源的抽象和定位等 ,所有的这些 ,都是这个Spring IoC模块的基本内容。另外,在BeanFactory接口实现中,除了前面介绍的像BeanFactory那样最为基本的容器形态之夕外,Spring还设计了IoC容器的髙级形态ApplicaticmContext应用上下文供用户使用,这些ApplicationConlext应用上下文 ,如FileSystemXmlApplicationContext,ClassPathXmlAppIicationContext,对应用来说, 是IoC容器中更面向框架的使用方式,同样,为了便于应用开发,像国际化的消息源和应用支持事件这些特性,也都在这个
模块中配合IoC容器来实现,这些功能围绕着IoC基本容器和应用上下文的实现,构成了整个Spring IoC模块设计的主要内容。

2.SpringAOP: 这也是Spring的核心模块, 围绕着AOP的增强功能,Spring集成了AspectJ作为AOP的一个特定实现,同时还在JVM动态代理/CGLIB的基础上, 实现了—个AOP框架 ,作为Spring集成其他模块的工具,如TransactionProxyFactoryBean
声明式事务处理,就是通过AOP集成到Spring中的。在这个模块中,Spring AOP实现了一个完整的建立AOP代理对象,实现AOP拦截器,直至实现各种Advice通知的过程。在对这个模块的分析中可以看到,AOP模块的完整实现是我们熟悉AOP实现技术的一
个不可多得的样本。

3.Spring MVC:对于大多数企业应用而言, Web应用已经是一种普遍的软件发布方式,而在Web应用的设计中, MVC模式已经被广泛使用了。 在java的社区中,也有很多类似的MVC框架可以选择,而且这些框架往往和WebUI设计整合在一起,对于定位于提供整体平台解决方案的Spring,这样的整合也是不可缺少的。Spring MVC模块以DispatcherServlet为核心,实现了MVC模式,包括怎样与Web容器环境的集成,Web请求的拦裁.分发、处理和ModelAndView数据的返回,以及如何集成各种UI视图展现和数据表现,如PDF,Excel等, 通过这个模块,可以完成Web的前端设计。

4.Spring JDBC/SpringORM:对于关系数据库的处理, Java提供了JDBC来进行操作,但在实际的应用中,单纯使用JDBC的方式还是有些繁琐, 所以在JDBC规范的基础上,Spring对JDBC做了一层封装,使通过JDBC完成的对数据库的操作更加简洁, SpringJDBC包提供了JdbcTemplale作为模板类 ,封装了基本的数据库操作方法,如数据的査询、更新等,另外, SpringJDBC还提供了RDBMS的操作对象,这些操作对象可以使应用以更面向对象的方法来使用JDBC, 比如可以使用MappingSqlQuery将数据库数据记录直接映射到对象集合,类似一个极为简单的ORM 工具。
除了通过SpringJDBC对数据库进行操作外,Spring还提供了许多对ORM工具的封装, 这些封装包括了常用的ORM工具,如Hibernate iBatis等,这一层封装的作用是让应用更方便地使用这些ORM 工具,而不是替代这些ORM工具,比如可以把对这些工具的使用和Spring提供的声明式事务处理结合起来。同时, Spring还提供了许多模板对象,如HibernateTemaplate这样的工具来实现对Hibernate的驱动,这些模板对象往往包装使用Hibernate的一些通用过程,比如Session的获取和关闭、事务处理的关联等,从而把一些通用的恃性实现抽象到Spring中来,更充分地体现了Spring的平台作用。

5.Spring事务处理:Spring事务处理是一个通过Spring AOP实现自身功能增强的典型模块。在这个模块中, Spring把在企业应用开发中事务处理的主要过程抽象出来。这个声明式事务处理的实现,使开发人员只需要在IoC容器中对事务属性进行配置即可完成,同时, 这些事务处理的基本过程和具体的事务处理器实现是无关的,也就是说,应用可以选择不同的具体的事务处理机制,如JTA,JDBC, Hibernate等。 因为使用了声明式事务处理.具体的事务处理机制被纳入Spring事务处理的统一框架中完成 , 并完成与具体业务代码的解耦。 在这个模块中,可以看到一个通用的实现声明式事务处理的基本过程,比如怎样配置事务处理的拦截器,怎样读人事务配置属性, 并结合这些事务配置属性对事务对象进行处理,包栝事务的创建、挂起、提交、回滚等基本过程, 还可以看到具体的事务处理器(DataSourceTransactionManage,
HibernateTransactionManager、JtaTransactionManager等) 是怎样封装不同的事务处理机制(JDBC、 Hibernate, JTA等) 的。

6.Spring远端调用:Spring为应用带来的一个好处就是能够将应用解耦。应用解耦,一方面可以降低设计的复杂性,一方面,可以在解耦以后将应用模块分布式地部署,从而提髙系统整体的性能。 在后一种应用场景下, 会用到Spring的远端调用, 这种远
端调用是通过Spring的封装从Spring应用到Spring应用之间的端到端调用,在这个过程中,通过Spring的封装, 为应用屏蔽了各种通信和调用细节的实现,同时. 通过这一层的封装 ,使应用可以通过选择各种不同的远端调用来实现, 比如可以使用HTTP
调用器(以HTTP协议为基础的), 可以使用第三方的二进制通信实现Hessian/Burlap甚至还封装了传统Java技术中的RMI调用。

7.Spring应用。

小结:在我们平时的开发中,用到最多的场景就是使用SSH框架来完成企业应用的开发,取代传统的EJB笨重的开发模式。在SSH架构中 Struts作为Web UI层、 Spring作为中间件平台, Hibernate作为数据持久化工具(ORM工具) 来操作关系数据库。在这个架构中, Hibernate是一个独立的ORM数据持久化产品。比较Spring JDBC和Hibernae对数据库操作的支持,对Spring来说,其对数据持
久化的支持,虽然也有JDBC的封装,可以完成一些将简单的数据记录到Java数据对象的转换和映射工作,但和Hibernate相比, 功能上毕竞还是有一些单薄,比如Hibernate还提供了各种数据的査询、方便的对象和关系数据的映射等。因此,在大多数应用中,将Hibernate和Spring—起使用是非常普遍的,因为一方面Hibenate提供了完整的和已经成为事实标准的功能,另一方面, Spring也提供了与Hibernated的集成和封装,包括声明式事务处理的封装等。对于Web 层而言,尽管Spring提供了自己的MVC实现,但与Struts的流行程度相比,这个Spring MVC的使用并不广泛, 毕竟在Web开发领域, Struts成名更早。在这个架构组合中,Spring起到的是一个应用平台的作用,通过Spring的集成,可以让应用在直接部署在Tomcat这个Web服务器上 ,因为作为一个直接依赖JVM的轻量级框架, Spring的部署方式就是一个简单的jar包, 不需要以一个J2EE应用服务器的形式出现,从而使整个应用在Tomcat这样的Web服务器上直接运行起来,非常简洁。

Spring的优点:
1.非侵入性:其目标是使应用程序代码对框架的依赖最小化,应用代码可以在没有Spring或者其他容器的情况下正常运行
2.一致性的编程:使应用直接使用POJO开发 ,从而可以与运行环境 (如应用服务器) 隔离开来。
3.Spring推动应用的设计凤格向面向对象及面向接口编程转变,提髙了代码的重用性和可测试性。
4.Spring改进了体系结构的选择,虽然作为应用平台, Spring可以帮助我们选择不同的技术实现, 比如从Hiberante到其他ORM工具,从Struts切换到Spring MVC,尽管我们通常不会这样做,但是我们在技术方案上选择使用Spring作为应用平台, Spring至少为我们提供了这种可能性和选择, 从而降低了平台锁定的风险

3、Spring的常见注解。
1、@Controller
在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到。
@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。单单使用@Controller 标记在一个类上还不能真正意义上的说它就是SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。那么要如何做Spring 才能认识它呢?这个时候就需要我们把这个控制器类交给Spring 来管理。有两种方式:
  (1)在SpringMVC 的配置文件中定义MyController 的bean 对象。
  (2)在SpringMVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。
2、@Resource和@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。
3、@Component、@Repository、@Service
@service 声明是业务层,创建bean实例。
@Repository声明是持久层,创建bean实例。
@Component 声明是创建bean实例

4、Springmvc 和 spring的关系
springMVC位于spring web端的一个框架,是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦。附:基于请求驱动指的就是使用请求-响应模型。
从名字上就可以窥探出,Spring>SpringMVC,那么事实上,spring和SpringMVC是一种父子关系。SpringMVC是spring扩展出的一个应用于web端的框架。在这里需要注意的一点,就是到底什么是父子容器关系:
spring主要的作用是黏合其他模块组件,进行统一管理,springmvc则主要是负责web端。那么,我们都知道,我们在应用spring的时候,可以使用注入。这个时候,如果我们的web端是用的SpringMVC,这个时候,controller理论上是通过SpringMVC去注入,但是,使用spring注入,同样是可行的。同理,service等层,使用SpringMVC配置的统一扫描装配也是可以的。所以,如果说只是为了使用spring的依赖注入,是大可不必将springMVC和spring同时使用的。他们完全可以分开!
但是,尽管SpringMVC和spring都可以进行自动装配扫描,值得注意的是:
spring(父容器)并不能直接访问SpringMVC(子容器)所注入的对象,但是SpringMVC却可以访问到spring装载的对象。所以,在配置自动装配的时候,应该注意到这一点。

5、线程安全和 不安全的理解?
多线程这块我在工作中也有涉及到,我对于线程安全不安全是这么理解的,我认为线程的安全与否与java类本身无关,也就是说不能说StringBuffer是线程安全的,stringBuilder是线程不安全的,或hashMap是线程不安全的,HashTable是线程安全的,这几个类本身是与线程无关的,只有当它处于多线程的环境当中时,才可能引发线程安全不安全的问题,StringBuffer与stringBuilder的线程安全与否取决于他的append方法前面有没有开启互斥锁,对于HashMap与HashTable的线程与否,主要取决于put方法前面有没有开启线程的互斥锁,(线程本身就自带互斥锁,只不过默认不开启,当看到synchronized时会开启互斥)。
通过我的工作经验,我感觉只要不让多个线程同时操作同一个对象,一般不会涉及到线程不安全这种问题,只有到多个线程同时操作同一个对象的时候才有可能引发线程安全问题。
6、IOC的理解?
Spring 是完全面向接口的设计,降低程序耦合性(为什么),主要是事务控制并创建bean实例对象。在ssh整合时,充当黏合剂的作用。IOC(Inversion of Control) 控制反转/依赖注入,又称DI(Dependency Injection) (依赖注入) 从架构来讲默认 注入组件都是单例,有效降低java 吃内存的问题。Spring大大降低了 java 语言开发相互的内存。这是项目中使用spring的 主要原因。
IOC的作用:产生对象实例,所以它是基于工厂设计模式的
Spring IOC的注入
   通过属性进行注入,通过构造函数进行注入,工厂注入
Spring IOC 自动绑定模式:
可以设置autowire按以下方式进行绑定
按byType只要类型一致会自动寻找,
按byName自动按属性名称进行自动查找匹配.

7、AOP的理解?
AOP 面向方面(切面)编程
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向方面(切面)编程。(为啥是OOP的延续) 注:OOP(Object-Oriented Programming ) 面向对象编程
AOP 主要应用于日志记录,性能统计,安全控制,事务处理(项目中使用的)等方面。
Spring中实现AOP技术:
在Spring中可以通过代理模式来实现AOP代理模式分为:
静态代理:一个接口,分别有一个真实实现和一个代理实现。(代码 缺点)
动态代理:通过代理类的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联。(优点)。动态代理有两种实现方式,可以通过jdk的动态代理实现也可以通过cglib 来实现而AOP默认是通过jdk的动态代理来实现的。jdk的动态代理必须要有接口的支持,而cglib不需要,它是基于类的。
概念解释:
切面(Aspect): 有切点(PointCut)和通知(Advice)组成,它既包括横切逻辑的定义,也包括了连接点的定义。
切点(Pointcut):一个切点定位多个类中的多个方法。
通知也叫增强(Advice):由方位和横切逻辑构成,所谓的方位指的是前置通知,后置通知,返回后通知,环绕通知,抛出异常后通知
连接点(JoinPoint):由切点和方位构成,用来描述在在哪些类的指定方法之前或之后执行
所谓的方位包括:
前置通知(Before advice):在连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。
返回后通知(After returning advice): 在连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。
后置通知(After (finally) advice):当连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
环绕通知(Around Advice):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行

8、设计模式:单例模式
单例模式开始
Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、登记式单例。

单例模式有以下特点:
  1、单例类只能有一个实例。
  2、单例类必须自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、
缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管
理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输
出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时
被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

//懒汉式单例类.在第一次调用的时候实例化自己   
public class Singleton {  
private Singleton() {}  
private static Singleton single=null;  
//静态工厂方法   
public static Singleton getInstance() {  
     if (single == null) {    
         single = new Singleton();  
     }
    return single;
}

//饿汉式单例类.在类初始化时,已经自行实例化   
public class Singleton1 {  
private Singleton1() {}  
private static final Singleton1 single = new Singleton1();  
//静态工厂方法   
public static Singleton1 getInstance() {  
         return single;  
    }  
}  

9、代理模式:
代理分为静态代理和动态代理
静态代理:
一个接口对应一个实现类和一个代理实现类,让代理实现类去做实现类想做的事。
动态代理:
一个接口只有一个实现类,没有代理实现类,在项目运行时,动态创建一个代理类来代替实现类去做某事。
代理模式中的角色:
* 1. 抽象角色 (接口)
* 2. 真实角色 真正的执行方法所在的类
* 3. 代理角色 代理真实角色的类
阐述动态代理模式:
答:Spring AOP 基于代理设计模式(基于jdk 的动态代理)
所谓代理设计模式:在代理模式中有个接口,接口中有个代理实现,要用代理实现去代表真实实现
10、工厂设计模式:
1. 简单工厂模式
2. 工厂方法模式
3. 抽象工厂模式
好处:
不用考虑实例化对象的细节 ,spring的 ioc/di (控制反转/依赖注入)就是使用工厂设计模式实现的。

考试题:阐述工厂设计模式?
	答:使用工程设计模式可以无需关注创建bean实例的细节,
		     所有细节就交于工厂处理,而调用者只需要下发指令即可。	

Springmvc
1、SpringMVC框架
springMVC是一个基于注解型的MVC框架。它的核心控制器是dispatcherServlet,在web.xml中配置。用户发起的请求都会被核心控制器拦截,进入springMVC的核心配置文件spring-servlet.xml。在这个xml中,主要配置的是注解的开启和扫描信息。首先要开启注解模式,annotation-driven。并且指定注解所在的路径,通过component-scan标签的base-package来设置。当请求到达后,springMVC会根据请求的action名称,通过ActionMapping去找到对应的action类中的requestMapping注解,这个注解中有一个value值,需要与请求的名称保持一致。所以请求可以到达action层。当然,springMVC也有自己的拦截器Interceptor。如果需要完成自定义拦截器,则需要写一个类,去继承handlerInterceptor类。重写里面的preHandler方法,在这方法中,通过返回true或者fasle来决定请求继续执行还是被拦截。定义好拦截器类以后,需要将拦截器配置到spring-servlet中去。springMVC中,获得参数的方式很简单,只需要在方法的参数列表中定义相关的局部变量就可以了。也可以通过requestParam的注解对参数进行更具体的配置,比如require为true时,要求这个参数必须传递。如果要求传递而没有传值,则报403错误。除了这样的配置以外,requestMapping也有相关的属性配置,比如requestType可以设置成GET或者是POST,指定请求的格式必须是Get请求还是post请求。如果需要传递的是对象类型参数,直接在参数列表中定义相关的对象,页面的参数名称必须要和类型的属性保持一致。(与strust2的传值方式稍微不同,没有对象.属性的方式)action接收参数后,则调用service业务逻辑层,完成业务操作。最后,springMVC进行页面跳转时,也很灵活,可以通过string返回一个字符串,也可以通过ModelAndView来进行跳转。ModelAndView中有一个setViewName方法,可以指定跳转的路径,还有一个addObject方法,可以将对象或者集合带到页面进行数据展示。如果是通过string类型跳转,则可以通过request.setAttribute()方法往页面传参。获得request的方式可以直接在参数列表中定义request对象获得,当然response也一样。
在spring-servlet中定义了一个试图解析器,统一配置了跳转路径的前缀和后缀名。
注意:可能会被问到的问题
1、常用的注解
2、拦截器的使用
2、SpringMVC的运行原理?
整个处理过程从一个HTTP请求开始:
1.Tomcat在启动时加载解析web.xml,找到spring mvc的前端总控制器DispatcherServlet,并且通过DispatcherServlet来加载相关的配置文件信息。
2.DispatcherServlet接收到客户端请求,找到对应HandlerMapping,根据映射规则,找到对应的处理器(Handler)。
3.调用相应处理器中的处理方法,处理该请求后,会返回一个ModelAndView。
4.DispatcherServlet根据得到的ModelAndView中的视图对象,找到一个合适的ViewResolver(视图解析器),根据视图解析器的配置,DispatcherServlet将要显示的数据传给对应的视图,最后显示给用户。

3、spring mvc的优点?
1.它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是?java组件.并且和Spring提供的其他基础结构紧密集成.
2.不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的)
3.可以任意使用各种视图技术,而不仅仅局限于JSP
4.支持各种请求资源的映射策略
5.它应是易于扩展的
4、Springmvc的传参方式,批量接收的写法

/**

  • 第一种传值方式

  • @param id

  • @return http://localhost:8080/UserApplication/test2/100
    /
    @RequestMapping(value = “/test2/{id}”, method = RequestMethod.GET)
    public String test2(@PathVariable(“id”) Integer id) {
    return “id:” + id;
    }
    /
    *

  • 第二种传值方式

  • @param id

  • @return http://localhost:8080/UserApplication/test3?id=100

  • 设置默认值 这个是传参

  • 当他为false 时 使用这个注解可以不传这个参数 true时必须传 required默认值是true
    */
    @RequestMapping(value = “/test3”, method = RequestMethod.GET)
    // public String test3(@RequestParam(“id”) Integer id) {
    public String test3(@RequestParam(value = “id”, required = false, defaultValue = “0”) Integer id) {
    return “id:” + id;
    }
    5、Springmvc 对日期的处理,和附件的操作。
    日期的处理:在做web开发的时候,页面传入的都是String类型,SpringMVC可以对一些基本的类型进行转换,但是对于日期类的转换可能就需要我们配
    1、如果查询类使我们自己写,那么在属性前面加上@DateTimeFormat(pattern = “yyyy-MM-dd”),即可将String转换为Date类型,如下@DateTimeFormat(pattern = “yyyy-MM-dd”) private Date createTime;
    2、如果我们只负责web层的开发,就需要在controller中加入数据绑定:
    @InitBinder
    public void initBinder(WebDataBinder binder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);
    dateFormat.setLenient(false);
    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); //true:允许输入空值,false:不能为空值
    }
    3、可以在系统中加入一个全局类型转换器
    public class DateConverter implements Converter {
    @Override
    public Date convert(String source) {
    SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);
    dateFormat.setLenient(false);
    try {
    return dateFormat.parse(source);
    } catch (ParseException e) {
    e.printStackTrace();
    }
    return null;
    }








    4、如果将日期类型转换为String在页面上显示,需要配合一些前端的技巧进行处理。
    5、SpringMVC使用@ResponseBody返回json时,日期格式默认显示为时间戳。
    @Component(“customObjectMapper”)
    public class CustomObjectMapper extends ObjectMapper {

      public CustomObjectMapper() {  
      CustomSerializerFactory factory = new CustomSerializerFactory();  
      factory.addGenericMapping(Date.class, new JsonSerializer() {  
          @Override  
          public void serialize(Date value, JsonGenerator jsonGenerator,  
      	    SerializerProvider provider) throws IOException, JsonProcessingException {  
      	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
      	jsonGenerator.writeString(sdf.format(value));  
          }  
      });  
      this.setSerializerFactory(factory);  
      }  
    

    }
    mvc:annotation-driven
    mvc:message-converters





    6、date类型转换为json字符串时,返回的是long time值,
    如果需要返回指定的日期的类型的get方法上写上@JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”) ,即可将json返回的对象为指定的类型。
    @DateTimeFormat(pattern=“yyyy-MM-dd HH:mm:ss”)
    @JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”)
    public Date getCreateTime() {
    return this.createTime;
    }
    6、Springmvc 的常用注解?
    1、@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
    2、@PathVariable 用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。
    3、@ModelAttribute和 @SessionAttributes
    代表的是:该Controller的所有方法在调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中,可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在调用Controller时,先执行@ModelAttribute方法。
    @SessionAttributes即将值放到session作用域中,写在class上面。
    具体示例参见下面:使用 @ModelAttribute 和 @SessionAttributes 传递和保存数据
    4、@requestParam主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter(“name”),它有三个常用参数:defaultValue = “0”, required = false, value = “isApp”;defaultValue 表示设置默认值,required 铜过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。
    5、@ResponseBody 作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
    使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
    7、Springmvc 的拦截器配置步骤?(了解)
    1.首先在spring-mvc.xml文件中添加拦截器配置


	
		
		
		
			
			
				
					/loginController/verifyCheck
                    

你可能感兴趣的:(java面试题(仅供参考))