Java面试大全(全面)

时间:2022-09-16 19:03:47
特别需要注意的知识点 :
多线程
数据库 (SQL 优化 , 索引 , 引擎 , 事务 )
数据结构
1 spring ioc aop  的原理
Spring IOC  依赖注入其实就是控制反转,用 spring 时用 xml 配置的方式的话,都是将 bean 配置在 spring 中,也有 bean property 属性。 spring 容器在初始化时就通过反射将容器中的 bean 实例化,假如 bean 配置中有 property 属性,就会反射 property 属性注入到 bean 中。这就是依赖注入。它分为构造方法注入, set 方法注入,接口注入,我们最常用的就是 set 方法注入

spring AOP AOP 就是面向切面编程。它主要运用了动态代理中的 Proxy 类和 InvicationHandler 接口实现。举例简单来说假如想要在原来的目标类的前后要加入日志的功能,目标类一定要实现一个接口,如果没有实现接口, spring 就会用 cglib 包实现 AOP 。推荐的还是要实现一个接口。实现过程大概就是实现了一个 InvicationHandler 接口的方法,里边有一个属性是目标类,在 invoke 方法中利用反射执行目标类的方法,并在其前后加入日志的方法。然后将目标类的类加载器,目标类实现的接口和实现了 InvicationHandler 接口的方法传入到 Proxy newProxyInstance 方法中。这样就实现了 AOP 。这样的话我们就可以在不修改任何代码的情况下在任何目标类中都可以动态的加入记日志的功能。

2 hibernate  延迟加载原理
lazy="true", 则代表对对象实施延迟加载,即,使用 load 函数返回由 CGLIB 或者 javaassist 产生的代理对象, a. 当不需要取得对象(非主键属性)时,不真正载入内存,从而节约内存空间,并且可以减少对数据的访问频率,高效的返回查询的对象; b. 当需要取得对象 ( 非主键属性 ) 时, hibernate 会先从 session 缓存寻找,再从二级缓存寻找,都找不到,才会使用 select 语句访问数据库。

3  事务隔离级别  什么情况下用低的或者用高的
         ( 事务 (Transaction) 是访问并可能更新数据库中各种数据项的一个程序执行单元 (unit))

事务隔离级别指的是事务与事务之间的隔离程度 ,  事务隔离程度越高,并发性越差、性能越低;事务隔离程度越低,并发性越强、性能越高。

4  事务传播方式哪几种
          新建事务
required 如无事务就新建事务
          required _new  如有事务挂起当前事务再新建

          非事务方式运行
      Supports              支持当前事务,如果当前没有事务,就以非事务方式执行。
      not_supported  -  挂起当前
      never 
 
       嵌套事务:
      Nested   如果当前事务存在,则以嵌套事务的方式执行。否则就按照它自己的事务方式执行。
 
       抛异常
      mandatory   支持当前事务,如果当前没有事务,就抛出异常  
      never   非事务方式执行,如果当前存在事务,则抛出异常。
5 ajax  跨域如何实现
         ajax 跨域调用有两种方式,一种是 iframe 的方式,通过设置 document.domain 来实现,一种则是通过设置 jsonp 来实现
 
7  乐观锁与悲观锁,举例场景
1 、悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,加锁机制,也无法保证外部系统不会修改数据即使在本系统中实现了)。
2 、乐观锁(  Optimistic Locking 
相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。

8 cookie  session  区别和联系, http  协议是无状态的,怎么区分不同登录用户
Cookie  session 的区别 :      
1 session 保存在服务器,客户端不知道其中的信息; cookie 保存在客户端,服务器能够知道其中的信息。   
   
  2 session 中保存的是对象, cookie 中保存的是字符串。   
   
  3 session 不能区分路径,同一个用户在访问一个网站期间,所有的 session 在任何一个地方都可以访问到。而 cookie 中如果设置了路径参数,那么同一个网站中不同路径下的 cookie 互相是访问不到的。

  区分不同登录用户 :
         session 就是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过 SessionID 来区分不同的客户 .
9  阐述 opensessionview 一下,  用和不用  数据库连接、 transaction session  之间  开启和关闭顺序

1. 说说值对象与引用对象的区别?  
值对象描述了一种不可变的对象,这些对象完全由其所含的数据值在定义,并不介意副本的存在。
引用对象描述了一种可以被共享(复用)的对象,这些对象的类往往在设计之初就考虑到共享的可能性或者打算用于共享。每个对象对应一个抽象化的实体,这个实体会被多次引用,并且希望这些引用对应一个相同的实例,通过任何一个引用都可以使用或改变这个对象的状态。可以使用相等操作符( == )检查两个对象是否相等
2. 谈谈你对反射机制的理解及其用途?  
Java 反射机制主要提供了以下功能:在运行时构造一个类的对象;判断一个类所具有的成员变量和方法;调用一个对象的方法;生成动态代理。
主要用途是:通过传递一个字符串值  去调用某一个类的方法。例如根据 spec0 去调用 SpecValue 下的 setSpce0 ()方法。


3.ArrayList Vector LinkedList 的区别及其优缺点? HashMap HashTable 的区别及其优缺点?  

  1. ArrayList,LinkedList是不同步的,而Vestor是同步的。所以如果不要求线程安全的话,可以使用ArrayListLinkedList,可以节省为同步而耗费的开销。但在多线程的情况下,有时候就不得不使用Vector了。

  2. ArrayListVector都是使用Object的数组形式来存储的。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%,

  3. ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

  4. 对于随机访问getsetArrayList觉得优于LinkedList,因为LinkedList要移动指针。

  5. 对于新增和删除操作addremoveLinedList比较占优势,因为ArrayList要移动数据。\
hashMap,hashTable 的区别 :
HashTable  中的方法是同步的  HashMap 的方法在缺省情况下是非同步的  因此在多线程环境下需要做额外的同步机制

HashTable 不允许有 null   key value 都不允许,而 HashMap 允许有 null   key value 都允许  因此 HashMap  使用 containKey ()来判断是否存在某个键

HashTable  使用 Enumeration  ,而 HashMap 使用 iterator

Hashtable Dictionary 的子类, HashMap Map 接口的一个实现类


3. 列出线程的实现方式?如何实现同步?  

线程的实现方式有两种:实现 Runnable 接口或者继承 Thread

实现同步的方法也有两种:一种是用同步方法,一种是用同步块  wait() notify()

同步方法就是在方法返回类型后面加上 synchronized

同步块就是直接写 synchronized (这里写需要同步的对象) {}


         4.  如何实现线程安全、高可用的 hashMap
                  
方法一 : 通过 Collections.synchronizedMap() 返回一个新的 Map, 这个新的 map 就是线程安全的 .  是一种悲观锁 . 在进入之前需要获得锁 , 确保独享当前对象 , 然后做相应的修改 / 读取 .  这个要求大家习惯基于接口编程 , 因为返回的并不是 HashMap, 而是一个 Map 的实现 .
方法二 : 重新改写了 HashMap,  使用的是乐观锁 , 只有在需要修改对象时 , 比较和之前的值是否被人修改了 , 如果被其他线程修改了 , 那么就会返回失败 .

5.  条件查询慢如何优化
          索引  分区(垂直  水平)  缓存  表优化  SQL 优化
6.String indexof  的实现       
先把 String 转换为 char[] ,然后首先找到 target 的的第一个字符开始匹配 .
7.  重写 equal  的同时为什么必须重写 hashcode
         hashCode 是编译器为不同对象产生的不同整数,根据 equal 方法的定义:如果两个对象是相等( equal )的,那么两个对象调用 hashCode 必须产生相同的整数结果,即: equal true hashCode 必须为 true equal false hashCode 也必须为 false ,所以必须重写 hashCode 来保证与 equal 同步。

8.  判断两个对象是否相等
         (1) 判断两个对象的 hashCode 是否相等
     如果不相等,认为两个对象也不相等,完毕
     如果相等,转入 2
(2) 判断两个对象用 equals 运算是否相等
     如果不相等,认为两个对象也不相等
     如果相等,认为两个对象相等
9.  为什么要重载 equal 方法?
          因为 Object equal 方法默认是两个对象的引用的比较,意思就是指向同一内存 , 地址则相等,否则不相等;如果你现在需要利用对象里面的值来判断是否相等,则重载 equal  方法

10. 为什么重载 hashCode 方法?
答案:一般的地方不需要重载 hashCode ,只有当类需要放在 HashTable HashMap HashSet 等等 hash 结构的集合时才会重载 hashCode ,就 HashMap 来说,好比 HashMap 就是一个大内存块,里面有很多小内存块,小内存块里面是一系列的对象,可以利用 hashCode 来查找小内存块 hashCode%size( 小内存块数量 ) ,所以当 equal 相等时, hashCode 必须相等,而且如果是 object 对象,必须重载 hashCode equal 方法。
11.  为什么 equals() 相等, hashCode 就一定要相等,而 hashCode 相等,却不要求 equals 相等 ?
(1) 因为是按照 hashCode 来访问小内存块,所以 hashCode 必须相等。
     (2)HashMap 获取一个对象是比较 key hashCode 相等和 equal true
之所以 hashCode 相等,却可以 equal 不等,就比如 ObjectA ObjectB 他们都有属性 name ,那么 hashCode 都以 name 计算,所以 hashCode 一样,但是两个对象属于不同类型,所以 equal false
12   为什么需要 hashCode?
(1) 通过 hashCode 可以很快的查到小内存块。
(2) 通过 hashCode 比较比 equal 方法快,当 get 时先比较 hashCode ,如果 hashCode 不同,直接返回 false

13. sleep wait 有什么区别
         sleep Thread 类的静态方法。 sleep 的作用是让线程休眠制定的时间,在时间到达时恢复,也就是说 sleep 将在接到时间到达事件事恢复线程执行,
         wait Object 的方法,也就是说可以对任意一个对象调用 wait 方法,调用 wait 方法将会将调用者的线程挂起,直到其他线程调用同一个对象的 notify 方法才会重新激活调用者

14. InputStream Reader 的区别
         InputStream Reader 都是 java.io 下的抽象类 . InputStream 是表示字节输入流的所有类的超类 . Reader 是用于读取字符流的抽象类 . InputStream 提供的是字节流的读取,而非文本读取,这是和 Reader 类的根本区别。用 Reader 读取出来的是 char 数组或者 String  ,使用 InputStream 读取出来的是 byte 数组 .

15. UNICODE,GBK,UTF-8 区别
         unicode gbk 和大五码就是编码的值,而 utf-8,uft-16 之类就是这个值的表现形式.而前面那三种编码是一兼容的,同一个汉字,那三个码值是完全不一样的.如"汉"的 uncode 值与 gbk 就是不一样的,假设 uncode a040 gbk b030 ,而 uft-8 码,就是把那个值表现的形式. utf-8 码完全只针对 uncode 来组织的,如果GBK要转UTF-8必须先转 uncode 码,再转 utf-8 就OK了.

16.  字节流与字符流的区别
          java.io 包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用 OutputStream 完成,输入使的是 InputStream ,在字符流中输出主要是使用 Writer 类完成,输入流主要使用 Reader 类完成。
          字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组。所以字符流是由 Java 虚拟机将字节转化为 2 个字节的 Unicode 字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点

17. excel 操作的两种方法
           一种是使用 jxl.jar, 另一种是使用 poi.jar
两者的区别 :
 Poi  主要是提供一组操作 windows 文档的 Java API.
JavaExcel 俗称 jxl 是一开放源码项目,通过它 Java 开发人员可以读取 Excel 文件的内容、创建新的 Excel 文件、更新已经存在的 Excel 文件。

jxl 优点:
Jxl 对中文支持非常好,操作简单,方法看名知意。
Jxl 是纯 javaAPI ,在跨平台上表现的非常完美,代码可以再 windows 或者 Linux 上运行而无需重新编写
生成 Excel 2000 标准格式
支持字体、数字、日期操作
能够修饰单元格属性
支持图像和图表 , 但是这套 API 对图形和图表的支持很有限,而且仅仅识别 PNG 格式。
缺点:效率低,图片支持不完善,对格式的支持不如 POI 强大

POI 优点:
效率高
支持公式,宏,一些企业应用上会非常实用
能够修饰单元格属性
支持字体、数字、日期操作
缺点:不成熟 , 代码不能跨平台,貌似不少同行在使用工程中还碰到让人郁闷的 BUG

  1. iint Integer 的区别
int 是基本数据类型 ,Integer  是包装类 . 这里还涉及装箱和拆箱问题 , 装箱是指把基本数据类型用它们相应的引用类型包装起来 , 使具有对象的性质 . 拆箱是将引用类型的对象简化成值类型的数据 .
Integer  有两中实例化方法 , 第一种是 new Integer(10), 这个是不提倡的 , 第二种是 Integer.valueOf(), 这种是比较提倡的 , 也是默认的 .valueof -128-127 之间的值有缓存 , 如果 int 值的范围 -128-127, valueof(int) , 它会直接返回 IntegerCache 的缓存给你 .
Integer a=10,Integer b=10  会被翻译成 -> Integer a =Integer.valueOf(100); 所以 a b 得到都是一个 Cache 对象,并且是同一个!而 c d 是新创建的两个不同的对象,所以 c 自然不等于 d
  1. 抽象类和接口有什么区别?
  1. Abstract class java中表示的是一种继承关系,一个类只能使用一次继承,但是一个类可以实现多个interface..
  2. abstract class 可以有自己的数据,也可以有非abstract 的成员方法,interface,只能够有静态的不能被修改的数据成员.
  3. Abstract class 表示的是”is-a”关系,interface 表示的是”like-a”关系
  4. 抽象类中的变量默认是friendly ,其值可以在子类中重新定义,也可以重新赋值.
  1. overrideoverload 的区别
override ( 重写 )
  1. 方法名,参数,返回值相同
  2. 子类方法不能缩小父类方法的访问权限
  3. 子类方法不能抛出比父类方法更多的异常
  4. 存在父类和子类之间,
  5. 方法被定义为final不能被重写
特点 :
  1. 覆盖的方法标志必须要和被覆盖的方法标志完全相同,才能达到覆盖的效果
  2. 覆盖的方法的返回值必须和被覆盖的方法返回一直
  3. 所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者其子类
  4. 被覆盖的方法不能为private.
Overload
  1. 参数类型,个数,顺序至少有一个不同
  2. 不能重载只有返回值不同的方法名
  3. 存在父类和子类,同类中.
特点 :
(1) 在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是 fun(int, float)   但是不能为 fun(int, int) );  
(2) 不能通过访问权限、返回类型、抛出的异常进行重载;  
(3) 方法的异常类型和数目不会对重载造成影响;  
Overriding  overload  java 多态性的不同表现 .
  1. 拦截器与过滤器的区别
拦截器  :是在 service 或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串,也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
过滤器:是在 java web 中,你传入的 request,response 提前过滤掉一些信息,或者提前设置一些参数,然后再传入 servlet 或者 struts   action 进行业务逻辑,比如过滤掉非法 url, 或者在传入 servlet 或者  struts action 前统一设置字符集,或者去除掉一些非法字符 .
区别 :
(1) 拦截器是基于 java 的反射机制的,而过滤器是基于函数回调
(2) 过滤器依赖与 servlet 容器,而拦截器不依赖与 servlet 容器
(3) 拦截器只能对 action 请求起作用,而过滤器则可以对几乎所有的请求起作用
(4) 拦截器可以访问 action 上下文、值栈里的对象,而过滤器不能
(5) action 的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
Final,finally finalize 的区别
              Final  用于声明属性 , 方法和类 , 分别表示属性不可变 , 方法不可覆盖 , 类不可继承 .
              Finally  是异常处理语句结构的一部分 , 表示总是执行
              Finalize  Object  类的一个方法 , 在垃圾收集器执行的时候回调用被回收对象的此方法 , 可以覆盖方法提供垃圾收集时的其他资源回收 , 例如关闭文件 .
       5.java 的反射机制
               开发性和原因连接是反射系统的两大基本要素
6. java 中如何实现多线程
继承 Thread  , 覆盖方法 run(), 我们在创建的 Thread 类的子类中重写 run(), 加入线程所要执行的代码 .
实现 Runnable 接口 ,Runnable  接口只有一个方法 run(), 我们声明一个类实现 Runnable 接口并提供这一方法 , 将我们的线程嗲吗写入其中 , 就完成了这一部分的任务 , 但是 Runnable 接口并没有任何对线程的支持 , 我们还必须创建 Thread 类的实例 , 这一点通过 Thread 类的构造函数来实现 .
Redis的基本数据类型:
String。set。list。hash。sorted set(受特的)





Hibernate/mybatis

  1. 什么是MyBatis
  MyBatis  是一个可以自定义 SQL 、存储过程和高级映射的持久层框架。 MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索。 MyBatis 可以使用简单的 XML 或注解用于配置和原始映射,将接口和 Java POJO Plain Old Java Objects ,普通的 Java 对象)映射成数据库中的记录。
.mybatis  ibatis  的区别
         1 Mybatis 实现了接口绑定,使用更加方便。
ibatis2.x 中我们需要在 DAO 的实现类中指定具体对应哪个 xml 映射文件,
Mybatis 实现了 DAO 接口与 xml 映射文件的绑定,自动为我们生成接口的具体实现,使用起来变得更加省事和方便。
这可以说是 Mybatis 最重要的改进。
2 、对象关系映射的改进,效率更高
3 MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。
MyBatis 采用 OGNL 表达式简化了配置文件的复杂性,使用起来更简洁。

Mybatis hibernate 的区别
          相同点 :Hibernate Mybatis 都是 orm 对象关系映射框架,都是用于将数据持久化的框架技术。
Hiberante mybatis 都对 jdbc 进行了封装 , 但是 hibernate 较深度的封装了 jdbc ,对开发者写 sql 的能力要求的不是那么的高,我们只要通过 hql 语句操作对象即可完成对数据持久化的操作了。 Mybatis 封装的没有 hibernate 那么深,我们可以再配置文件中写 sql 语句,可以根据需求定制 sql 语句,数据优化起来较 hibernate 容易很多。
hibernate 可移植性好,需要修改数据库的时候 , 使用 hibernate 只需改变一下数据库方言即可搞定。用 hibernate 框架,数据库的移植变的非常方便。
e 它也提供了一些优化策略,比如说懒加载、缓存、策略模式等都是针对于它的优化方案。
Mybatis 要求程序员写 sql 的能力要相对使用 hibernate 的开发人员要高的多,且可移植性也不是很好。
涉及到大数据的系统使用 Mybatis 比较好,因为优化较方便。涉及的数据量不是很大且对优化没有那么高,可以使用 hibernate

Mybatis  侧重于 sql 映射 , hibernate 侧重于 orm
三.基本 API 
 1 SessionFactory
  2 Session(save,update,saveOrUpdate,delete,load,get) 
 3 Query  
4 Transaction 


四. hibernate.cfg.xml 配置文件的加载  
使用 XML 文件进行配置时,可以在配置文件中找到对象类映射文件位置, XML 配置文件的位置默认在 Classpath 下,使用下面的方式来读入 XML 文件以配置 Hibernate    
Configuration config = new Configuration().configure(); 
默认的 XML 配置文件名称是 hibernate.cfg.xml ,您也可以自行指定名称,例如:  Configuration config = new Configuration().configure("db.cfg.xml"); 


五. SessionFactory 的创建
  Configuration 的实例管理 Hibernate 的配置信息,通常用于建立 SessionFactory    例如: SessionFactory sessionFactory = config.buildSessionFactory();  SessionFactory 一旦建立,就被赋予 Configuration 的配置信息,之后改变 Configuration   不会影响已建立的  SessionFactory 实例,如果对 Configuration 改变,则要建立一个新的   SessionFactory 实例,新的实例中才会包括新的配置信息。  


   六.主键生成方式   
1. increment:   Hibernate 自动以递增的方式生成标识符 每次递增
2. identity:    由底层数据库生成标识符 前提是底层数据库支持自动增长字段类型  
3. sequence:  Hibernate 根据底层数据库的序列生成标识符 前提是底   层数据库支持序列  
4. hilo:  适用于代理主键 , Hibernate 根据 hi/low 算法生成标识符 . Hibernate 把特定的字段   作为 "high". 
5. native:  适用于代理主键 根据底层数据库对自动生成标识符的支持能力 来选择  identity, sequence,  hilo 
6. uuid.hex:   适用于代理主键 , Hibernate 采用 128 位的 UUID(Universal Identification)   法生成标识符 .  
7. assigned:   适用于自然主键 ,  Java 应用程序生成标识符 . 为了能让 Java 应用程序设  OID, 不要把方法声明为 private 类型 . 应当尽量避免使用自然主键 .

  七.  get() load() 的区别
 (1) get() 执行时会立即发送 sql 语句,查询结果,查询后 session 关闭没有影响, load() 执行时不会立即发送 sql 语句,在使用返回结果的时候才查询,如果 session 关闭,就会出  现惰性加载异常;
(2)get() 查询时 , 如果所传的 id 没有对应的记录,直接返回 null ,不会报错,而 load() 查询时,若果没有对应的 id 会出现 org..hibernate.ObjectNotFoundException
3   load() 可返回实体的代理类实例, get() 直接返回实体  
4   load() 可在一、二级缓存查找数据, get() 只在一级缓存找,若无则直接调  SQL 语句在数据库中找

八.关于 query 查询
  Query.list() 若果没有记录也不是 null ,而是空集合 get(0) 的时候会出现越界异常。   Query.uniqueResult() 有一条记录的时候用此方法。
九.事务    
Hibernate 事务默认不自动提交,这种不自动提交是在获得 session 的时候设置的。    session.beginTransaction() 是对 session 中事务的设置做检查。
十.类到表的映射的两种方法
 1.  在配置文件中配置 hbm2ddl.auto 属性,其值有以下四种: create validate update   create-drop ,然后在编写加载配置文件的类
          注意 :
create
每次加载 hibernate 时都会删除上一次的生成的表,然后根据你的 model 类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
create-drop 
每次加载 hibernate 时根据 model 类生成表,但是 sessionFactory 一关闭 , 表就自动删除。
update
最常用的属性,第一次加载 hibernate 时根据 model 类会自动建立起表的结构(前提是先建立好数据库),以后加载 hibernate 时根据  model 类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等  应用第一次运行起来后才会。
validate 
每次加载 hibernate 时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
2.  用类来完成   Configration config = new Configration () .configue();  SchemaExport export = new SchemaExport(config);  Export.create(true,true); 

十一.实体对象的生命周期  
1. transient (临时状态)实体对象在内存中存在,与数据库中的记录无关,不受 session  管理,对对象的修改不会影响数据库。  
2. persisent (持久状态)与表记录相关联,受 session 管理,对对象的修改,在事务提  交或 session 关闭前会执行 update 操作。
 3. detached (游离状态)有表记录关联,不受 session 管理。  各个状态间的转换:

十二.缓存
 (1) Session 缓存,实例状态及生命周期由 session 缓存生命周期决定, Session 生命周期  存在,持久化对象缓存在 session 中, session 消亡,缓存的持久化对象也就消亡。
(2) 不同的 session ,缓存存储的对象也不同。
(3) Session 缓存持久化实例对象,不持久化实例的某些属性
(4)  一级 session 缓存可以将查询到的持久化实体对象缓存到 session 中,而普通的查询  实体的某属性时,不会在 session 中缓存。  下面方法将实体对象放入 Session 缓存中: load()   get()    save()   iterate()  session 范围缓存的对象,当 session 执行 clear() evict(Object o) 方法后,缓存就会清除所有或某个持久化对象,这样 session 缓存就被清理。   session.flush();  session.clear();          
(5)  二级缓存:进程缓存,一个数据库对应一个 SessionFactory 。二级缓存由 SessionFactory 来理。  二级缓存可以通过配置 SessionFactory 来配置打开与关闭。  <property name="cache.use_second_level_cache">false</property>  二级缓存需要第三方插件来设置

十三 hibernate 的优缺点
优点: 1 、程序更加面向对象;
        2 、提高了生产率;
        3 、方便移植(修改配置文件);
        4 、无侵入性。
   缺点:
        1 、效率比 JDBC 略差;
        2 、不适合批量操作。

        3 、只能配置一种关联关系

十四 . hibernate 的工作原理   
1. 配置好 hibernate 的配置文件和与类对应的配置文件后,启动服务器
2. 服务器通过实例化 Configuration 对象,读取 hibernate.cfg.xml 文件的配置内容,并根据相关的需求建好表或者和表建立好映射关系
3. 通过实例化的 Configuration 对象就可以建立 sessionFactory 实例,进一步,通过 sessionFactory 实例可以创建  session 对象
4. 得到 session 之后,便可以对数据库进行增删改查操作了,除了比较复杂的全文搜索外,简单的操作都可以通过 hibernate 封装好的  session 内置方法来实现
5. 此外,还可以通过事物管理,表的关联来实现较为复杂的数据库设计

十五 .Hibernate 的二级缓存策略

   1)  条件查询的时候,总是发出一条 select * from table_name where  .  (选择所有字段)这样的 SQL 语句查询数据库,一次获得所有的数据对象。

   2)  把获得的所有数据对象根据 ID 放入到第二级缓存中。

   3)  Hibernate 根据 ID 访问数据对象的时候,首先从 Session 一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照 ID 放入到缓存。

4)  删除、更新、增加数据的时候,同时更新缓存。

缓存的范围 :
1).  事务范围:缓存只能被当前事务访问;缓存的生命周期依赖于事务的生命周期;  缓存的介质是内存。  
2).  进程范围:缓存被进程内的所以事务共享;缓存的生命周期依赖于进程的生命  周期;缓存的介质是内存或者硬盘。  
3).  集群范围:在集群环境中缓存被一个计算机或者多个计算机共享。    

事务范围的缓存是持久化层的第一级缓存,通常是必须的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常可选。进程范围或集群范围的缓存会出现并发问题,可采用 4 中并发访问策略,每种策略对应一种事务级别:  
1.  事务型:仅在受管理环境中适用。提供“可重复读”事务隔离级别。(高)
2.  读写型:仅在非集群的环境中适用。提供“已提交读”事务隔离级别。
 3.  非严格读写型:不保证缓存与数据库中数据的一致性。极少改,允许偶尔脏读
 4.  只读型:从不修改的数据。(最低)    隔离级别越高,并发性能就越低

十六 . Hibernate  的初始化 .
1) 创建 Configeration 类的实例。
它的构造方法:将配置信息 (Hibernate config.xml) 读入到内存。
一个 Configeration  实例代表 Hibernate  所有 Java 类到 Sql 数据库映射的集合。
2) 创建 SessionFactory 实例
Configeration  对象中的所有配置信息拷贝到 SessionFactory 的缓存中。
SessionFactory 的实例代表一个数据库存储员源,创建后不再与 Configeration  对象关联。

3) 调用 SessionFactory 创建 Session 的方法

十七 .  状态转换

临时状态  (transient)
1 】不处于 Session  缓存中
2 】数据库中没有对象记录

Java 如何进入临时状态
1 】通过 new 语句刚创建一个对象时
2 】当调用 Session  delete() 方法,从 Session  缓存中删除一个对象时。


持久化状态 (persisted)
1 】处于 Session  缓存中
2 】持久化对象数据库中有对象记录
3 Session  在特定时刻会保持二者同步

Java 如何进入持久化状态
1 Session  save() 把临时-》持久化状态
2 Session  load(),get() 方法返回的对象
3 Session  find() 返回的 list 集合中存放的对象
4 Session  update(),saveOrupdate() 使游离-》持久化


游离状态 (detached)
1 】不再位于 Session  缓存中
2 】游离对象由持久化状态转变而来,数据库中可能还有对应记录。

Java 如何进入持久化状态-》游离状态
1 Session  close() 方法
2 Session  evict() 方法,从缓存中删除一个对象。提高性能。少用。

十八 . Hibernate 设置事务隔离级别
 1.  读操作未提交 (Read Uncommited) :允许脏读取,不允许更新丢失,该  隔离级别可以通过“排他写锁”实现; 1
2.  读操作已提交 (Read Commited) :允许不可重复读取,不允许脏读取 2
3.  可重复读 (Repeatable Read) :禁止不可重复读和脏读取,但有时可能出  现幻像数据;
4.  可串行化 (Serializable) :提供严格的事务隔离。 8  
hibernate.cfg.xml 中配置隔离级别:   <session-factory>  <propertyname=”hibernate.connection_isolation”>4</property> </session-factory>

十九 .  乐观锁,悲观锁  
org.hibernate 包下有一个名为 LockMode 的类:   包含了主要锁定模式:
 1). LockMode.None   
2). LockMode.Read   
3). LockMode.UPGRADE: 
当数据库支持悲观锁,就执行 select for update, 反之普通 select 
4). LockMode.UPGRADE_NOWAIT :对 oracle 执行 select for update nowait 语句  5).LockMode.WRITE :当 Hibernate 向数据库保存或者更新一个对象时,会自动使用
此模式。  
6).LockMode.FORCE :对于使用了 version 的记录会强制增加 version 的值  
 
悲观锁:  
Hibernate 中主要通过显式地设定锁定模式来设置悲观锁定。  

有以下几种方式:  
    1).  调用 Session.load() 指定锁定模式;  
    2).  调用 Session.lock() 可以为对象设定锁定模式;  
    3).  调用 Query.setLockMode() 可以设定查询语句获取对象的锁定。   
乐观锁:
主要由 Hibernate 提供的版本控制功能来实现乐观锁定。  
<version>: 利用一个递增的整数来根据数据库表中记录的版本。  <timestamp>: 用时间戳来跟踪数据库表中记录的版本

二十 .N+1 查询问题
          当你查询时首先 hibernate 会发出一天查询所有主键的 sql 语句,然后跟新缓存。 N 就是指首先 hiberante 会到缓存中查询,如果缓存中不存在与之匹配的数据,再会发出 sql 查询。
主要的原因是:默认情况下 iterate 利用缓存数据来查询,当缓存为空会多查询一次,把 ID 加进来。
          解决方案 :
Hibernate:

  1. 设置fetch=FetchType.LAZY,这种方法在合适的时候(具体使用到对象时)还是会发出select语句。

  2. session.createCriteria()做查询

  3. 使用join fetch做外连接查询。
Mybatis:

  1. 使用一条SQL语句,主外键相关表的信息全部查询处理

  2. 使用MyBatis的延迟加载机制. MyBatis的延迟加载机制需要使用cglib包,因此应向工程中添加此包,在配置文件中配置: <settingname="lazyLoadingEnabled"value="true"/>
<settingname="aggressiveLazyLoading"value="false"/>
二十一 .mybatis  SQL 映射

SQL 映射实现  
1 、在包 com/xunpoit/pojo 下创建 User 类,包含相关属性定义  
2 、新建 SQL 映射文件 com/xunpoit/pojo/User.xml ,文件中包含 SQL 代码和映射定义信息,与 User 类同包  
<mapper namespace="com.xunpoit.pojo"> 
<select id="selectUser" parameterType="int“  resultType="com.xunpoit.pojo.User">  select * from t_user where id = #{id} </select> 
<select id="selectAllUser" resultType="com.xunpoit.pojo.User">  select * from t_user </select> 
<insert id="addUser" parameterType="com.xunpoit.pojo.User"> insert into t_user(id,username,password,addr) values(#{id},#{userName},#{password},#{addr}) </insert> </mapper> 
3. SQL  映射 XML  文件仅仅只有一些初级的元素:  
 cache    配置给定模式的缓存  
 cache-ref    从别的模式中引用一个缓存  
 resultMap    这是最复杂而却强大的一个元素了,它描述如何从结果集中加载对象  
 sql    一个可以被其他语句复用的 SQL    insert    映射 INSERT  语句   update    映射 UPDATE  语句   delete    映射 DELEETE  语句   select    映射 SELECT  语句

二十二 .mybatis #  $ 的区别
         
1. # 将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。  
2. $ 将传入的数据直接显示生成在 sql 中。  
3. # 方式能够很大程度防止 sql 注入。 $ 方式无法防止 Sql 注入。
4.$ 方式一般用于传入数据库对象,例如传入表名 .   
5. 一般能用 # 的就别用 $.
6.MyBatis 排序时使用 order by  动态参数时需要注意,用 $ 而不是 #


. Spring 特点  
◆方便解耦,简化开发  
通过 Spring 提供的 IoC 容器,我们可以将对象之间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。有了 Spring ,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。  
AOP 编程的支持  
通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付。  
◆声明式事务的支持  
Spring 中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。  
◆方便程序的测试  
可以用非容器依赖的编程方式进行几乎所有的测试工作,在 Spring 里,测试不再是昂贵的操作,而是随手可做的事情。  
◆方便集成各种优秀框架  
Spring 不排斥各种优秀的开源框架,相反, Spring 可以降低各种框架的使用难度, Spring 提供了对各种优秀框架(如 Struts,Hibernate Hessian Quartz )等的直接支持。  
◆降低 Java EE API 的使用难度  
Spring 对很多难用的 Java EE API (如 JDBC JavaMail ,远程调用等)提供了一个薄薄的封装层,通过 Spring 的简易封装,这些 Java EE API 的使用难度大为降低。  


.spring 框架

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
1 、核心容器 (Core) :核心容器提供  Spring  框架的基本功能 (Spring Core) 。核心容器的主要组件是 BeanFactory ,它是工厂模式的实现。 BeanFactory 使用控制反转( IOC )模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。  
2 Spring  上下文: Spring  上下文是一个配置文件,向  Spring 框架提供上下文信息。 Spring  上下文包括企业服务,例如 JNDI EJB 、电子邮件、国际化、校验和调度功能。  
3 Spring AOP :通过配置管理特性, Spring AOP 模块直接将面向切面的编程功能集成到了  Spring  框架中。所以,可以很容易地使  Spring  框架管理的任何对象支持 AOP Spring AOP 模块为基于  Spring  的应用程序中的对象提供了事务管理服务。通过使用  Spring AOP ,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。  
4 Spring DAO JDBCDAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。 Spring DAO  的面向 JDBC 的异常遵从通用的  DAO  异常层次结构。  
5 Spring ORM Spring  框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO Hibernate iBatisSQL Map 。所有这些都遵从  Spring  的通用事务和  DAO  异常层次结构。  

6 Spring Web  模块: Web  上下文模块建立在应用程序上下文模块之上,为基于  Web  的应用程序提供了上下文。所以, Spring 框架支持与  Jakarta Struts  的集成。 Web  模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。  

7 Spring MVC 框架: MVC 框架是一个全功能的构建  Web 应用程序的 MVC 实现。通过策略接口, MVC 框架变成为高度可配置的, MVC 容纳了大量视图技术,其中包括 JSP Velocity Tiles iText  POI 。模型由 javabean 构成,存放于 Map ;视图是一个接口,负责显示模型;控制器表示逻辑代码,是 Controller 的实现。 Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。 Spring  的核心要点是:支持不绑定到特定  J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE  环境( Web  EJB )、独立应用程序、测试环境之间重用。

. 声明式事务
          声明式事物管理意味着你无需在 Bean 中编写任何事物管理代码,只需将事物配置在 Bean 上就可以了。想要到达这个目的,最简单的方法就是使用代理——代理会拦截所有的方法的调用。如果方法名位于事物配置中,代理就是起到通知 (around) 的作用。它会在目标方法调用前开启事物,然后在一个 try/catch 块执行目标方法。如果目标方法正常完成,代理就会提交事物;如果目标抛出运行时异常,代理就会进行回滚。为了完成这些事情,代理需要配置好 PlatfromTransactionManager 。这是声明式事务管理的核心概念,其独特指出就是创建代理的方式不同。

事务的传播特性
1. PROPAGATION_REQUIRED(required):  如果存在一个事务,则支持当前事务。如果没有事务则开启(常用的配置)
2. PROPAGATION_SUPPORTS(supports):  如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
3. PROPAGATION_MANDATORY(mandatory):  如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4. PROPAGATION_REQUIRES_NEW(requires_new):  总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
5. PROPAGATION_NOT_SUPPORTED(not_supported):  总是非事务地执行,并挂起任何存在的事务。
6. PROPAGATION_NEVER(never):  总是非事务地执行,如果存在一个活动事务,则抛出异常

Spring 配置声明式事务:

*  配置 SessionFactory
*  配置事务管理器
*  事务的传播特性
*  那些类那些方法使用事务
具体配置如下 :
<!--  配置 SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation">
     <value>classpath:hibernate.cfg.xml</value>
    </property>
</bean>

<!--  配置事务管理器  -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<!--  事务的传播特性  -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
     <tx:method name="add*" propagation="REQUIRED"/>
     <tx:method name="del*" propagation="REQUIRED"/>
     <tx:method name="modify*" propagation="REQUIRED"/>
     <tx:method name="*" propagation="REQUIRED" read-only="true"/>
    </tx:attributes>
</tx:advice>

<!--  哪些类哪些方法使用事务  -->
<aop:config>
    <aop:pointcut expression="execution(* com.biped.service.*.*(..))" id="transactionPC"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPC"/>
</aop:config>

<!--  普通 IOC 注入  -->
<bean id="userManager" class="com.biped.service.UserManagerImpl">
    <property name="logManager" ref="logManager"/>
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="logManager" class="com.biped.service.LogManagerImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

. 事务配置方式 :
  第一种 : 每个 bean 一个代理
第二种方式:所有 Bean 共享一个代理基类
第三种方式:使用拦截器
第四种方式:使用 tx 标签配置的拦截器
第五种方式:全注解

. 事务管理方式
1.annotation( 注解 )
2.xml 配置 (aop 技术 )

<!-- 1. 注解方式配置事务   --> 
    <bean id="txManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
        <property name="dataSource" ref="dataSource" /> 
    </bean> 
 
    <tx:annotation-driven transaction-manager="txManager" /> 
 
 
 
    <!-- 2.xml 方式配置事务 . 利用 aop 技术   
        <aop:config> 
        <aop:pointcut id="transactionPointcut" expression="execution(* com.test.service..*.*(..))"/> 
        <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/> 
        </aop:config>  
        <tx:advice id="txAdvice" transaction-manager="txManager"> 
        <tx:attributes> 
        <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/> 
        <tx:method name="*"/> 
        </tx:attributes> 
        </tx:advice> 
    --> 
. 注入方式
         1. 通过 setter 方式
         2. 构造方式
         3. 注解方式
                  @Resource
@Autowired
 
两者的区别: 1. @Resource 标注是由 JDK 提供的,而 @Autowired 标注是由 Spring 提供的,因而 @Autowired 标注会与 Spring 紧密耦合,所以推荐使用 @Resource 标注;
                  2. @Resource 默认是按照名称来装配注入的,当找不到与名称匹配的 bean 才会按照类型来装配注入;
                  3. @Autowired 默认是按照类型装配注入的,假如想按照名称来转配注入,则需要结合 @Qualifier 一起使用;
                  4. @Resource @Autowired 都可以用来标注字段或者 setter 方法。

.  什么是 Spring
------ 开源的,控制反转( Inversion of Control )和面向切面的容器框架。
Spring 核心:
IOC (控制反转) ------- 创建对象并且组装对象之间的关系。
IOC: 应用程序本身不负责依赖对象的创建和维护,依赖对象的创建和维护是由外部容器负责的。这样控制权就由应用程序转移到了外部容器。控制权的转移就是所谓的反转。

依赖注入: Dependency Injection :在运行时由外部容器将依赖对象注入到组件中。

.  为什么使用 Spring
1 :降低组件之间的耦合度,实现各层之间的解耦
2 :可以使用容器提供的众多服务。如:
-- 事务管理服务
--JMS
--Spring core 核心服务
-- 持久化服务
-- 其他
3 :提供了单例模式支持。开发人员不需要自己编写实现代码
4 :提供了 AOP 技术。实现如:权限拦截,运行监控等功能
5 :提供了众多的辅助类。如 JDBC Template HIbernate Template
6 :对主流的应用框架提供了集成支持。集成 Struts JPA Hibernate


. spring 7 个模块
spring 核心容器 (Core)
spring 上下文
springAOP
SpringDAO
SpringORM
springWeb 支持 struts 集成
springMVC 自带的 mvc 框架

. spring 实现的 2 种设计模式
单列模式:接受容器管理的 bean ,默认采用单态模式管理。
工厂模式: spring 就是实例化和管理全部 bean 的工厂。 spring 的上下文也就是工厂,也被设计成单态的

十一 . Spring 实例化 bean 的三种方式
1 :默认使用类加载器
2 :使用静态工厂方法实例化 bean 对象
<bean id=" 名称 " class=" 工厂类 " factory-method=" 工厂类中创建 bean 实例的方法 "/>
3 :使用实例工厂方法实例化 bena 对象
<bean id=" 实例工厂名称 " class=" 工厂类的路径 "/>
<bean id=" 名称 "  factory-bean=" 实例工厂名称 " method=" 实例工厂里边的创建 bena 对象的方法 "/>


十二 . Bean 的作用域

Singleton

Spring 容器只存在一个共享的 bean 实例,默认的配置。

<bean id="example" class="com.yz.bean.Example"/>

Prototype

每次对 bean 的请求都会创建一个新的 bean 实例。

<bean id="example" class="com.yz.bean.Example" singleton=”false”/>
两者如何选择?原则:所有有状态的 bean 都使用 Prototype 作用域,而对无状态的 bean 则应该使用 singleton 作用域。

十三 . Spring 的生命周期
bean 的实例化:
1 :当作用域范围为 singleton 时,在初始化 Spring 容易的时候实例化 bean 实例。
---1 :如果 lazy-init 的值为 true ,则为延迟 bean 的实例化,即在 Spring 容器启动时不实例化 bean 的对象
2 :当作用域范围为 prototype 时,在调用 Spring getBean 的方法时实例化 bean 对象
注入依赖对象可以采用手工装配或者自动装配,在实际应用中建议采用手工装配。因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。


十四 .AOP 中的概念
         Aspect   Aspect  声明类似于  Java  中的类声明,在  Aspect  中会包含着一些  Pointcut  以及相应的  Advice
   Joint point (连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它  joint point
   Pointcut (切入点):表示一组  joint point ,这些  joint point  或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的  Advice  将要发生的地方。
Advice (通知): Advice  定义了在  pointcut  里面定义的程序点具体要做的操作,它通过  before after    around  来区别是在每个  joint point  之前、之后还是代替执行的代码。
Weaving (织入) : 织入,指将通知插入到目标对象。
Target (目标对象) : 目标对象,指需要织入切面的对象。
Proxy (代理对象) : 代理对象,指切面织入目标对象之后形成的对象。

十五 .spring AOP  动态代理的过程
(1)  将切面使用动态代理的方式动态织入到目标对象(被代理类),形成一个代理对象;

(2)  目标对象如果没有实现代理接口,那么 Spring 会采用 CGLib 来生成代理对象,该代理对象是目标对象的子类;

(3)  目标对象如果是 final 类,并且也没实现代理接口,就不能运用 AOP

十六 .  配置过程:

   1 )配置目标对象

   2 )配置通知

   3 )利用 ProxyFactoryBean 将通知织入到目标对象,形成一个动态代理对象

   4 )客户端使用动态代理来访问目标对象的方法。

十七 .  关于 Spring EJB

  Spring EJB3.0 之间的关系是竞争关系。

     Spring 是一个开源的框架,而 EJB3.0 是一个标准(标准意味着将得到广泛的支持以及良好的兼容性),并且,采用 EJB3.0 ,项目的后期维护得到了保证。

     Spring 是一个轻量级框架, EJB3.0 是一个重量级框架(完整的容器,包含所有的服务)。

     Spring IoC AOP 集成了大量的开源框架,可扩展性良好。 EJB3.0 的可扩展性则完全依赖于新的容器。

     Spring 对事务支持不如 EJB3.0 成熟, Spring 对集群的兼容也不够。

  Spring EJB3.0 都是一个企业级开发框架,都支持声明式事务。


十八 .springMVC 常用注解 :
         @Controller  负责注册一个 bean  spring  上下文中, bean  ID  默认为类名称开头字母小写 , 你也可以自己指定
         @RequestMapping 用来定义访问的 URL ,你可以为整个类 / 方法定义一个
         @RequestBody  HTTP 请求正文转换为适合的 HttpMessageConverter 对象。
@ResponseBody  将内容或对象作为  HTTP  响应正文返回,并调用适合 HttpMessageConverter Adapter 转换对象,写入输出流。

@CookieValue  获取 cookie 信息
@RequestHeader  获取请求的头部信息


十九 . 什么 springbatch
         Spring Batch 是一个轻量级的,完全面向 Spring 的批处理框架,可以应用于企业级大量的数据处理系统。 Spring Batch POJO 和大家熟知的 Spring 框架为基础,使开发者更容易的访问和利用企业级服务。 Spring Batch 可以提供大量的,可重复的数据处理功能,包括日志记录 / 跟踪,事务管理,作业处理统计工作重新启动、跳过,和资源管理等重要功能。

二十 .springbatch 的执行流程
          Java面试大全(全面)
每个 Batch 都会包含一个 Job Job 就像一个容器,这个容器里装了若干 Step Batch 中实际干活的也就是这些 Step Step 主要是读取数据,处理数据,然后将这些数据存储起来 (ItemReader 用来读取数据, ItemProcessor 用来处理数据, ItemWriter 用来写数据 )  JobLauncher 用来启动 Job JobRepository 是上述处理提供的一种持久化机制,它为 JobLauncher Job ,和 Step 实例提供 CRUD 操作。
     外部控制器调用 JobLauncher 启动一个 Job Job 调用自己的 Step 去实现对数据的操作, Step 处理完成后,再将处理结果一步步返回给上一层,这就是 Batch 处理实现的一个简单流程。

Struts:
.


Rest

  1. 什么是rest
REST REpresentational State Transfer 的缩写(一般中文翻译为表述性状态转移)。一种体系结构。而 HTTP 是一种包含了 REST 架构属性的协议。在 REST 中所有东西都被看作资源。每一个资源都有一个 URI 和它对应。每个 REST 请求都是孤立的,请求中包含了所需的全部信息。 REST 服务端不存储状态。 REST 支持不同的通信数据格式,比如 XML JSON


  1. rest 的原则
URL 表示资源
HTTP 方法表示操作
GET 只是用来请求操作, GET 操作永远都不应该修改服务器的状态。
服务应该是无状态的
WebService
. 什么是 webservice
是一个 SOA 的架构 , 它是不依赖与语言 , 不依赖于平台 , 可以实现不同的语言见的相互调用 , 通过 Internet  进行基于 http 协议的网络应用间的交互 .
WebService  实现不同语言间的调用 , 是依托于一个标准 ,webservice 是需要遵守 WSDL/SOAP  规范的 . 通过标准的协议和接口 , 可以让不同的程序集成的一种 SOA 架构 .
.webservice 的优点
1. 跨平台的程序相互访问
2. 松耦合
3. 基于标准协议
.WebService 的基本原理
         1.Service provider  采用 WSDL  描述服务
         2.Service Provider  采用 UUDI 将服务的描述文件发布到 UDDI 服务器
         3. Service Requestor UDDI 服务器上查询并  获取 WSDL 文件
4. Service Requestor 将请求绑定到 SOAP ,并访问相应的服务。
.webservice  名词解释
         JAXP(Java API for XML Parsing)  定义了在 Java 中使用 DOM, SAX, XSLT 的通用的接口。这样在你的程序中你只要使用这些通用的接口,当你需要改变具体的实现时候也不需要修改代码。

   JAXM(Java API for XML Messaging)  是为 SOAP 通信提供访问方法和传输机制的 API

   WSDL(Web Services Description Language) 是一种  XML  格式,用于将网络服务描述为一组端点,这些端点对包含面向文档信息或面向过程信息的消息进行操作。这种格式首先对操作和消息进行抽象描述,然后将其绑定到具体的网络协议和消息格式上以定义端点。相关的具体端点即组合成为抽象端点(服务)。

   SOAP 即简单对象访问协议 (Simple Object Access Protocol) ,它是用于交换 XML 编码信息的轻量级协议。

   UDDI (Universal Description, Discovery, and Integration)     的目的是为电子商务建立标准; UDDI 是一套基于 Web 的、分布式的、为 Web Service 提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的 Web Service 注册,以使别的企业能够发现的访问协议的实现标准。

在用户能够调用 Web 服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服务端来编制软件, UDDI 是一种根据描述文档来引导系统查找相应服务的机制。 UDDI 利用 SOAP 消息机制(标准的 XML/HTTP )来发布,编辑,浏览以及查找注册信息。它采用 XML 格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

. 什么是 SOA
         
面向服务的架构( Service Oriented Architecture SOA )是表示所谓服务的自包含功能单元的一种软件设计原则和架构设计模式。 SOA 推崇松耦合、复用性和粗粒度的服务设计原则。在企业架构方面, SOA 带来的好处包括对业务需求的敏捷交付和迅速反应,通过降低集成成本提高投资回报率,通过复用组件降低开放成本。企业架构一般使用企业服务总线 (ESB) 作为大型企业线上应用的集成层

.  应用集成方式有哪些
         
1.  共享数据库

2.  批量文件传输

3.  远程过程调用( RPC

4.  通过消息中间件来交换异步信息( MOM


.  应用集成可以采用的 Web 服务方式有什么?
         SOAP WS Simple Object Access Protocal   RESTful Web Service REpresentational State Transfer

. SOAP WS  RESTful Web Service 之间有什么不同呢?
         1.SOAP WS 支持既远程过程调用(例如, RPC )又支持消息中间件( MOM )方式进行应用集成。而 Restful Web Service 仅支持 RPC 集成方式。
2.SOAP WS 是传输协议无关的。它支持多种协议,比如, HTTP(S)   Messaging TCP UDP SMTP 等等。而 REST 是协议相关的,只支持 HTTP 或者 HTTPS 协议。
3.SOAP WS 仅允许使用 XML 数据格式。定义的操作通过 POST 请求发送。其重点是通过操作名来获取服务,并将应用逻辑封装为服务。而 REST 方式则允许多种数据格式,而且由于 REST 方式采用标准 GET PUT PSOT DELETE  方法,因此所有的浏览器都可以支持。其重点是通过资源名来获取服务,并将数据封装为服务。 AJAX 支持 REST 方式,它可以使用 XMLHttpRequest 对象。无状态 CRUD 操作(创建、读、更新和删除)更加适合这种方式。

. SOA Web service 的区别是什么?
         SOA 是一种软件设计准则,一种实现松耦合,高可复用性和粗粒度的 web 服务的设计模式。开发者可以选择任意协议实现 SOA ,例如, HTTP HTTPS JMS SMTP RMI IIOP (例如,采用 IIOP EJB )、 RPC 等。消息可以采用 XML 或者数据传输对象( Data Transfer Objects DTOs )。

Web Service 是实现 SOA 的技术之一。也可以不用 Web service 来实现 SOA 应用:例如,用一些传统的技术,像 Java RMI EJB JMS 消息等。但是 Web service 提供的是标准的平台无关的服务,这些服务采用 HTTP XML SOAP WSDL UDDI 技术,因此可以带来 J2EE .NET 这些异构技术( heterogeneous technologies )之间的互操作性。

.  如果可以使用传统的中间件方式,例如, RPC CORBA RMI DCOM ,为什么还要选择 Web service
          传统的中间件跟应用关系紧密,对应用的任何修改都可能会引起对应中间件的修改。因此这种方式下应用不好维护,复用性也比较差。一般情况下也无法支持异质系统( heterogeneity )。另外,采用这种方式应尽量避免互联网访问应用。还有,这种方式代价更高并且可用性差。

Web service 采用松耦合连接,即在客户端和服务器端之间提供了一个抽象层。这种松耦合应用可以减少维护成本并增加可复用性。 Web service 提供了一种基于 XML Web 的新的中间件形式。 Web service 是语言和平台无关的,任何语言都可以用来开发一个 Web service ,并且部署到任何平台上,包括小型设备到大型超级计算机。 Web service 采用语言无关协议,例如 HTTP ,并且通过 Web API 来在不同的应用程序之间传输 XML 消息。 Web service 可以通过互联网访问,开销少并且可用性好。

十一 .  开发基于 SOAP Web service 有哪些方式呢?
          契约先行(也称为自顶向下, contract-first )方式:通过 XSD WSDL 来定义 contract ,然后根据 contract 生成 Java 类;
契约后行(也称为自底向上, contract-last )方式:先定义 Java 类,然后生成约定,也就是从 Java 类得到 WSDL 文件。


Dubbo+zookeeper

  1. dubbo的出现是为了解决什么问题

  1. 当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。

  2. 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系

  3. 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?

  1. dubbo 是什么
Dubbo 是一个分布式服务框架,以及 SOA 治理方案。其功能主要包括:高性能 NIO 通讯及多协议集成,服务动态寻址与路由,软负载均衡与容错,依赖分析与降级等。

  1. Zookeeper是如何完成注册的

保存了服务提供方和服务消费方的的 URI dubbo 自定义的一种 URI ),服务消费方找到 zookeeper ,向 zookeeper 要到服务提供方的 URI ,然后就找到提供方,并调用提供方的服务。

  1. Dubbo 在安全机制方面是如何解决的
Dubbo 主要针对内部服务,对外的服务,阿里有开放平台来处理安全和流控,所以 Dubbo 在安全方面实现的功能较少,基本上只防君子不防小人,只防止误调用。 Dubbo 通过 Token 令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。 Dubbo 还提供服务黑白名单,来控制服务所允许的调用方。

  1. dubbo的工作原理
Java面试大全(全面)
节点角色说明:
Provider:  暴露服务的服务提供方。
Consumer:  调用远程服务的服务消费方。
Registry:  服务注册与发现的注册中心。
Monitor:  统计服务的调用次调和调用时间的监控中心。
Container:  服务运行容器。

工作原理 :
服务运行容器启动 , 加载 , 运行服务提供者 , 在服务提供者启动适合 , 就向注册中心注册自己提供的服务 , 服务消费者在启动的时候 , 向注册中心订阅自己所需要的服务 . 注册中心返回服务提供者地址给消费者 , 如果有变更 , 注册中心将基于长连接推送变更数据给消费者 . 消费者从提供者地址列表中 , 基于软负载均衡算法 , 选一台提供者进行调用 , 如果调用失败 , 再选另一台调用 . 服务消费者和提供者 , 在内存中累计调用次数和调用时间 , 定时每分钟发送一次统计数据懂啊监控中心 .


支付系统开发
          支付平台:往小说就是个中间件,可以帮助你转发各种付款,收款,查询的要求。但是做大了就是公司的资金出入口,负责公司和银行之间资金流向的桥梁,随着时代发展,电子商务飞速发展,第三方支付也是层出不穷,可以说几乎每个时刻都在突出新的支付类型,各个银行推出网上支付,代扣,代收付,这种便利的交易方式,使得我们可以不出门就可以东西,但是随这支付方式的增加,电子商务公司就需要把所有支付方式放在一个系统进行统一管理,这就是支付平台,我个人理解支付平台最大的功能,有效的系统的管理公司所有的资金流向,确保资金交易不会出错。即便出错才可以自我补救。


  1. 支付平台需要注意哪些?

1. 入口统一。而且不应经常变化,  无论收款,付款,查询,对账都应是一个入口(这也是我做了几种类型后才发现的。)入口统一的好处,集成方便,客户群只需要知道接口和参数便可方便集成
 
 
2. 支付渠道可以来回切换。支付平台的支付功能接口可以固定,譬如  (支付,代扣,转账)可以固定,但是选取那个银行接口应是可以切换的,这就需要将支付方式活配,客户可以指定那个银行进行支付,也可以不指定,我们根据客户的要求自动分配合理方案。
 
 
3. 支付数据存储方式应统一化。刚开始做的时候为每一个支付渠道,后来出现数据表泛滥,这也是弯路所有的支付渠道都有共同点,所以在数据库设计这里应该谨慎,必先出现表泛滥,应当将渠道统一化,个别的可以采用扩展表方式
 
 
4. 为客户提供补充处理。有些银行在支付过程中无法提供明确的结果回应,这就需要采用延时查询结果功能,大多采用定时处理进行。
 
 
5. 业务主流程要清晰。不应随意改变,建议采用控制反转。
 
 
6. 对于重复支付的控制。除了网上银行的方式我们无法控制,但是实时类支付应当做到尽量控制重复支付的情况


  1. 商户网站接入支付结果有几种方式
有两种方式 , 分别是通过浏览器进行跳转通知  , 通过服务器异步通知
浏览器跳转通知:这种方式主要是基于用户访问的浏览器,如果用户在银行页面支付成功后,直接关闭了页面,并未等待银行跳转到支付结果页面,那么商户网站就收不到支付结果的通知,导致支付结果难以处理。而且浏览器端数据很容易被篡改,而降低安全性。所以我们推荐技术人员开发时使用后端服务器通知做技术判断,而只将前台通知进行支付相关显示,不进行逻辑处理。

服务器异步通知:该方式是支付公司服务器后台直接向用户指定的异步通知 URL 发送参数,采用 POST GET 的方式。商户网站接收异部参数的 URL 对应的程序中,要对支付公司返回的支付结果进行签名验证,成功后进行支付逻辑处理,如验证金额、订单信息是否与发起支付时一致,验证正常则对订单进行状态处理或为用户进行网站内入账等。


  1. 现在支付公司提供的结算周期模式
T+0  T+1  模式
T+1 模式时,即用户支付完毕后,支付公司将在第二天进行结算,商户即可将资金提取到自己的银行卡,或支付公司直接结算到约定的商户收款账户中。
T+0 的模式,则支付资金可以随时清算,并提现到商户银行卡。

  1. 收款流程
商户网站将支付信息提供给支付网关后,网站引导用户进入相关银行网关进行支付,完成后银行扣款,并将支付结果返回给第三方支付公司,支付公司收到结果后将为商户进行支付平台内的入账处理,等待结算。结算完成后,商户即可登录第三方支付平台进行提现,将资金通过第三方支付平台转入到自己的银行卡中。

  1. 开发流程
与支付公司签约后,网站将获得相关开商户号、密钥、支付网关以及开发文档。技术人员通过阅读文档,获取需要使用的相关数据参数,如商品名称、金额等,并通过约定的加密方式及密钥进行加密处理,将以 FORM 表单 POST GET 的方式发送给支付公司提供的支付网关 URL

支付网关收到商户提供的相关参数后将进行数据处理及加密验证,如果数据合格且密钥验证成功,将引导用户进入各家银行选择页面,用户在选择自己使用的银行后,将进入相关银行的支付网关进行支付。

用户在银行网关成功付款后,银行进行扣款,并将支付结果回传给支付公司,支付公司收到银行的结果,同样进行签名验证,并将支付结果信息传递给商户网站。

支付公司将支付结果传递给商户网站也是通过 FORM 表单的方式,只是该数据传递属于服务器后端处理的。商户网站向支付公司发起支付请求传递支付相关参数时,就包含一个或两个 URL ,用于指定接收支付结果的 URL 中。


  1. 有几种接入方案
两种接入方案 .
  直接与银行对接与通过中间公司间接与银行对接

直接与银行对接
优缺点 :
  因为直接与银行进行财务结算 , 交易资金结算比较安全 , 适合资金流量比较大的企业 , 这种方案适合于 : 每月结算金额百万以上的企业 .
缺点 : 开发工作量比较大 , 而且银行会不定期升级系统交易系统 , 随着银行系统的升级 , 企业也需要做相应改动 , 所以维护工作量比较大 , 而且企业每年还需要向银行交纳一定数量的接口使用费 .

通过中间公司与银行对接
优点 :
           开发工作量少 , 因为使用的是中间企业提供的接入规范 , 所以银行升级系统 , 不需要企业做相应修改 , 除非中间企业的接入规范发生了改变 , 企业才作相应修改 . 相对前一种接入方案 , 这种方案的维护工作量比较少 , 因为只与一家企业对接 , 所以接入费用相对比较低 , 这种方案适合于 : 每个月结算金额在几十万以下的中小企业 .
缺点 : 因为是与中间企业进行资金结算 , 目前所有中间企业都是私企 , 资金安全是一个大问题 .


  1. 中间支付公司有哪些
首信易支付
           每年需要交纳一定的接口费用 , 并且从交易金额中扣除 1% 的手续费 , 当当网 , 红孩儿 , 京东商城使用了首信易支付
易宝支付
           接入免费 , 只从交易金额中扣除 1% 的手续费 . 例如 E 网往 , 巴巴运动网


  1. 易宝支付接入规范
MD5-hmac
Hmac  是一种秘密的密钥验证算法 .Hmac  提供的数据完整性和源省份验证完全取决于密钥分配范恩 , 如果只有发起者和接收者知道 Hmac  密钥 . 这么就对两者间发送的数据提供了源身份验证和完整性保证 .
StringBUffer sValue = new StringBuffer();
sValue.append(“tanghuan”);
sValue.appernd(“012345”);
String hmacMD5 = DigestUtil.hmacSign(sValue.toString(),”123456”);

  1. 易宝的支付流程
通过 http 请求方式像易宝支付网关发起一个支付请求 , 就是向 https://www.yeepay/.com/app-merchat-proxy/node  发起请求 , 请求可以是 get post 方式提交 , 页面采用 GBK/GB2312 编码 .
易宝支付网关对企业发来的数据使用用户的密钥生成 MD5-hmac , 然后跟企业发来的 MD5-hmac 码比较是否相同 , 如果相同即把请求转发到银行网关 , 当用户支付完成后 , 银行网关会引导用户的浏览器重定向到易宝支付网关 , 然后易宝支付网关再引导用户的浏览器重定向到企业提供的 url

  1. 给易宝支付网关发送的数据
业务类型 , 商户编号 , 商户订单号 , 支付金额 , 交易币种 , 商户接收支付成功数据的地址 , 商户扩展信息 , 银行编码 , 应答机制 (0—200 状态  成功 ;1— 返回 success 字符串 ), 商品名称 , 商品种类 , 商品描述 , 送货地址 ( 后四个可选 )

十一 . 使用易宝支付常见问题
          问题一:
请求查询绑卡信息的时候,报 {"error_code":"600000","error_msg":"illegal request"}
解决方案:
与易宝沟通,易宝说我们的测试服务器的 ip 必须在易宝那边报备,才不会出现这个问题。
 
问题二:
在本地环境中,前台回调地址可以接收到,但是后台异步通知地址始终接受不到?
解决方案 :
后台异步通知地址必须是外网可以访问的,所以必须在测试服务器上面进行,才能接收到。

十二 . 支付接口中的异步通知和同步通知的区别
         1  异步通知和同步通知都需要有回调地址,如果没有回调地址,易宝支付平台是没有任何回调的。
2  异步通知和同步通知,如果是易宝支付平台自动回调的话,那么回调地址必须能够公网访问。
3  同步通知:商户服务器发起请求,易宝支付平台处理完成之后,通过浏览器跳转的方式,通知我们交易完成或者失败。
异步通知:商户服务器发起请求,易宝支付平台处理完成后,不以浏览器跳转的方式通知商户,而是服务器与服务器之间通信,将处理的结果通过我们的异步回调地址通知我们,这时候我们会按照事先和易宝平台协定的方式回应易宝支付,如果没有回应易宝支付会隔断时间再以服务器与服务器之间通信的方式,通知我,我只有按照商定的方式返回给他才行。

十三 .  很多时候我们登陆需要验证码,一个用户对应一个验证码, 1000 万个用户对应 1000 万个验证码,那么如何知道这个验证码是这个用户,那个验证码是那个用户的呢?
          解决方案:
其实每生成一个验证码,会生成 seesion 存储,这时候会在浏览器生成一个 cookie 来存储 seesionid ,这个 sessionid 可以帮助服务器找到合适的 session 文件。

Nginx
.  什么是 Nginx
                   Nginx  是一个非常优秀的 HTTP 服务器 , 由于其并发能力强 , 并且体积很小 , 所以被称为轻量级 http 服务软件 .nginx  不单可以作为强大的 web 服务器 , 还可以作为一个反向代理服务器 . 而且 nginx 还可以按照调度规则实现动态、静态页面的分离,可以按照轮询、 ip 哈希、 URL 哈希、权重等多种方式对后端服务器做负载均衡,同时还支持后端服务器的健康检查。

. 如何配置负载均衡
http 节点里添加 :

# 定义负载均衡设备的  Ip 及设备状态
upstream myServer {  

    server 127.0.0.1:9090 down;
    server 127.0.0.1:8080 weight=2;
    server 127.0.0.1:6060;
    server 127.0.0.1:7070 backup;
}

在需要使用负载的 Server 节点下添加

proxy_pass  http://myServer ;

upstream  每个设备的状态 :

down  表示单前的 server 暂时不参与负载
weight   默认为 1.weight 越大,负载的权重就越大。
max_fails  :允许请求失败的次数默认为 1. 当超过最大次数时,返回 proxy_next_upstream  模块定义的错误
fail_timeout:max_fails  次失败后,暂停的时间。
backup   其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻。


  1. 使用nginx常出现什么问题

  1. session不同享,登陆状态不一致
2.

  1. 如何实现多台服务器之间的session共享
1 、不使用 session ,换用 cookie

session 是存放在服务器端的, cookie 是存放在客户端的,我们可以把用户访问页面产生的 session 放到 cookie 里面,就是以 cookie 为中转站。你访问 web 服务器 A ,产生了 session 然后把它放到 cookie 里面,当你的请求被分配到 B 服务器时,服务器 B 先判断服务器有没有这个 session ,如果没有,再去看看客户端的 cookie 里面有没有这个 session ,如果也没有,说明 session 真的不存,如果 cookie 里面有,就把 cookie 里面的 sessoin 同步到服务器 B ,这样就可以实现 session 的同步了。

说明:这种方法实现起来简单,方便,也不会加大数据库的负担,但是如果客户端把 cookie 禁掉了的话,那么 session 就无从同步了,这样会给网站带来损失; cookie 的安全性不高,虽然它已经加了密,但是还是可以伪造的。

2 session 存在数据库( MySQL 等)中

PHP 可以配置将 session 保存在数据库中,这种方法是把存放 session 的表和其他数据库表放在一起,如果 mysql 也做了集群了话,每个 mysql 节点都要有这张表,并且这张 session 表的数据表要实时同步。

说明:用数据库来同步 session ,会加大数据库的 IO ,增加数据库的负担。而且数据库读写速度较慢,不利于 session 的适时同步。

3 session 存在 memcache 或者 redis

memcache 可以做分布式, php 配置文件中设置存储方式为 memcache ,这样 php 自己会建立一个 session 集群,将 session 数据存储在 memcache 中。

说明:以这种方式来同步 session ,不会加大数据库的负担,并且安全性比用 cookie 大大的提高,把 session 放到内存里面,比从文件中读取要快很多。但是 memcache 把内存分成很多种规格的存储块,有块就有大小,这种方式也就决定了, memcache 不能完全利用内存,会产生内存碎片,如果存储块不足,还会产生内存溢出。

4 nginx 中的 ip_hash 技术能够将某个 ip 的请求定向到同一台后端,这样一来这个 ip 下的某个客户端和某个后端就能建立起稳固的 session ip_hash 是在 upstream 配置中定义的:
[html] view plaincopy CODE 上查看代码片派生到我的代码片
upstream nginx.example.com
    {  
             server 192.168.74.235:80;  
             server 192.168.74.236:80; 
             ip_hash; 
    } 
    server 
    { 
             listen 80; 
             location / 
             { 
                     proxy_pass 
             } 
 }  

互联网开发需要掌握的知识 :
http
         HTTP 协议( HyperText Transfer Protocol ,超文本传输协议)是用于从 WWW 服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示 ( 如文本先于图形 ) 等。 HTTP 是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。 HTTP 是一个无状态的协议。

设计模式 :
 Spring 中使用到的设计模式 :
         
1. 工厂方法( Factory Method  
定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method 使一个类的实例化延迟到其子类。  
spring 中的 FactoryBean 就是典型的工厂方法模式。如下图:  
Java面试大全(全面) 

2. 单例( Singleton  
保证一个类仅有一个实例,并提供一个访问它的全局访问点。  
spring 中的单例模式完成了后半句话,即提供了全局的访问点 BeanFactory 。但没有从构造器级别去控制单例,这是因为 spring 管理的是是任意的 java 对象。  

3. 适配器( Adapter  
将一个类的接口转换成客户希望的另外一个接口。 Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。  
spring 中在对于 aop 的处理中有 Adapter 模式的例子,见如下图:  
Java面试大全(全面) 
由于 Advisor 链需要的是 MethodInterceptor 对象,所以每一个 Advisor 中的 Advice 都要适配成对应的 MethodInterceptor 对象。  



4. 代理( Proxy  
为其他对象提供一种代理以控制对这个对象的访问。  
从结构上来看和 Decorator 模式类似,但 Proxy 是控制,更像是一种对功能的限制,而 Decorator 是增加职责。  
Java面试大全(全面) 
spring Proxy 模式在 aop 中有体现,比如 JdkDynamicAopProxy Cglib2AopProxy  

5. 观察者( Observer  
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。  
Java面试大全(全面) 
spring Observer 模式常用的地方是 listener 的实现。如 ApplicationListener  

6. 策略( Strategy  
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
应用地方 第一个地方,加载资源文件的方式,使用了不同的方法,比如: ClassPathResourece FileSystemResource ServletContextResource UrlResource 但他们都有共同的借口 Resource ;第二个地方就是在 Aop 的实现中,采用了两种不同的方式, JDK 动态代理和 CGLIB 代理;
7. 模板方法( Template Method  
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。  
Java面试大全(全面) 
Template Method 使用的模板方法模式
这里想要探讨另一种对 Template Method 的理解。 spring 中的 JdbcTemplate ,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用到 JdbcTemplate 已有的稳定的、公用的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出来作为一个参数传入 JdbcTemplate 的方法中。但是变化的东西是一段代码,而且这段代码会用到 JdbcTemplate 中的变量。怎么办?那我们就用回调对象吧。在这个回调对象中定义一个操纵 JdbcTemplate 中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到 JdbcTemplate ,从而完成了调用。这可能是 Template Method 不需要继承的另一种实现方式吧。  

合道金融项目 :
合道金融项目  主要功能和定位是小额 p2p 借款业务的线下核心管理系统 , 它的功能包括管理模块 , 功能区 , 财富流程 , 抵押借款流程 , 系统批处理模块  等功能模块 . 提供给业务人员和风控人员进行统一协同工作 , 便于总比对各机构与部门的规划管理 . 采用 Web 系统主流框架 Struts2,spring,mybatis  提高系统的开发效率 , 简化数据操作统一规范开发标准 . 为降低服务维护成本 , 提高稳定性与数据安全性服务器采用阿里云主机 .
我所负责负责财富端流程和借款客户抵押借款流程审批功能的开发;负责合同管理模块的开发 ; 财富端流程的需求是为出借客户提供出借申请网银支付 , 提前撤资等投资理财的需要 , 为公司提供申请信息录入 , 撮合匹配 , 回款确认 , 金额明细等一些完整的理财流程 . 它依赖于第三方支付易宝支付 , 借款申请 , 流程模块 . 申请好生成规范为 L+ 机构 12 + 时间 8 + 序号 4 .
抵押借款流程的需求是为借款客户提供借款申请 , 还款还息等借款需要 , 为公司提供申请信息录入 , 撮合匹配 , 风险审核 , 放款确认 , 收支明细等一系列完整的借款流程 . 它依赖于第三方支付 , 出借申请 , 流程模块 . 申请号生成规范 B+ 机构 12 + 时间 8 + 序号 4