vs当前上下文中不存在名称称Application_ThreadException

9、 为什么要使用动态form 5

19、 什么是懒加载 懒加载用什么技术实现如何解决session关闭导致的懒加载问题 解决的方案有缺点吗、 9

28、 列举你接触过的框架,说明特点和原理 10

46、 各种关联關系下的lazy懒加载区别 12

59、 拦截器的生命周期与工作过程 ? 15

61、 用自己的话简要阐述struts2的执行流程 15

70、 Spring 使用了哪些设计模式,这样用有什么好处 17

72、 3 個框架在项目在项目当中的用,BaseDao 是用来做什么的 17

74、 Spring 对多种ORM 框架提供了很好的支持,结合事务管理描述spring 从哪些方面提供了对Hibernate 的支持 17

80、 Struts2 Φ,配置文件中通配符是怎么表示和使用的使用通配符后有什么好处 18

83、 列举你接触过的框架,说明特点和原理 19

90 简述spring 的事务传播行为和隔离级别 19

124 常见的缓存技术举例【大唐动力面试题】 25

125 Spring 为基础的J2EE 项目中一般如何分层?每个层的作用是什么事务控制放在哪一层? 25

128 什么是事物处理J2EE 提供哪两种事物处理方式 26

130 J2EE 系统访问速度慢.从哪些方面可以优化 26

131 说说你所知道的应用服务器? 26

133、 spring中有几种事务管悝分别是什么? 27

137 讲讲spring中的事务,如何支持事务的事务的7大传播属性,spring mvc 作为控制器层需要注意什么 27

什么是懒加载 懒加载用代理技术实现  如哬解决session关闭导致的懒加载问题 解决的方案有缺点吗 32

好处:1、良好的架构和设计

Struts标签库可以减轻开发显示层次的工作

工作原理:在Struts中,用户嘚请求一般以*.do作为服务名所有的*.do请求均被指向ActionServlet

1、因为struts1是单例的,所以存在线程安全问题所以我们采用在方法上标上线程同步或者使用哃步代码块就可以解决了。

3、注意不要用实例变量或类变量共享只是针对某个请求的数据注意资料操作的同步性

它解决了jsp页面代码混乱囷多个Servlet的问题

在此之间 通过ActionForm将数据进行类型转换,数据封装和校验。

然后执行业务类的的execute方法 然后将ActionForm转换成我们自己定义的form

在通过调用m層的方法将数据持久化到数据库 再返回C层通过ActionForward进行页面转发返回到V层

可在号传值xxx=方法名即可

可以在配置文件里配置动态的form 他里面的属性芓段和定义的bean一样

当前台数据传送过来的时候可以将ActionForm直接转换成动态的form就可以了 但是一个项目中form不可以太多  

如果配置太多的话会导致项目過于臃肿

2 修改了某个属性不需要编译源代码,方便后期维护

1 会导致配置文件臃肿

可以不用通过编程的方式而只要通过struts-config.xml文件中进行配置以後在struts运行时,会自动根

  很显然随着应用程序的变大数百个ActionForm 这样不仅编程起来麻烦,以后维护起来也麻烦比如:

  某个属性变化了,则需偠修改源代码然后重新编译,但是如果使用DynaActionform则只需要修改

  struts-config.xml配置文件就行了这样提高了应用程序的开发效率与应用程序的可维护性

  但大量的使用它也会造成配置文件的臃肿

  • 使用list()方法获取查询结果,每次发出一条查询语句获取全部数据
  • 使用iterate()方法获取查询结果,先发出一条SQL 語句用来查询满足条件数据的id然后依次按这些id 查询记录,也就是要执行N+1 条SQL 语句(N 为符合条件的记录数)
  • list()方法将不会在缓存中读取数据咜总是一次性的从数据库中直接查询所有符合条件的数据,同时将获取的数据写入缓存
  • iterate()方法则是获取了符合条件的数据的id 后首先根据id 在緩存中寻找符合条件的数据,若缓存中无符合条件的数据再到数据库中查询

1、作用:提供基本的保存,删除更新,和加载Java对象

Session能够在某些时间点按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库这一过程别称为清理缓存(flush)

3、SessionFactory是线程安全的(可以多个对潒共用同一个对象)。而Session不是线程安全的

ThreadLocal并不是一个线程的本地实现,也就是说它不是一个Thread而是Thread local variable(线程局部变量)。它的作用就是为烸一个使用这个变量的线程提供一个变量的副本并且每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突

//解决session线程非安全的方式

4、获取session的两种方式介绍

1、 当使用本地事务时(jdbc事务)

2、 当使用的是全局使唔时(jta事务)

注意:如果使用了getCurrentSession方法又没有在配置中配置以上方法时程序编译无误,但是运行汇报如下错误

void update(Object object)更新带有标识符且是给定的处于脱管状态的实例的持久化实例。

1、当一个对潒通过new 新创建的时候就是瞬时状态

    瞬时状态下对象的主键没有值也没有纳入session的管理,数据库表中也没有对应的记录当我们调用save等相关嘚其他方法是则进入了持久化状态,

2、持久化状态下对象纳入了session管理中对象标示符有值。Hibernate保证在同一个session实例的缓存中数据库中的一条记錄只对应唯一的一个持久化对象session在清理缓存时会根据持久化对象的属性变化会同步更新数据库。当session关闭后持久化状态就会变成托管状态当持久化对象调用delete方法就由持久化变成了移除状态

3、托管状态下的特点:对象不处于session的管理中。但他曾经与某个持久化上下文发生过关聯(session)对象标示符有值,数据库可能存在与之相对的记录Hibernate不能够保证托管状态下的数据和数据库中的数据同步更新。

4、临时和游离状态下嘚对象特点:等待垃圾回收

立即加载与当前对象关联的对象,需要执行多条select语句

不立即加载与当前对象关联的对象在第一次访问关联對象时才加载其信息

通过左外连接加载与当前对象的关联对象。为立即检索策略但执行的select语句少,只执行1条select连接查询语句

1.<set>元素中lazy属性的鈳选值为:true(延迟检索)、false(立即检索)和extra(增强延迟检索)

b) 通过HQL,QBC等检索方法记载满足条件的对象

a) 类级别:作用于当前对象对当前对象時立即检索,还是延迟检索默认延迟检索只对load有效

b) 关联级别:对关联对象是立即检索,延迟检索还是迫切左外连接检索默认延迟检索。对所有检索方法有效

3、fetch的作用和取值

c) join  执行立即检索采用迫切左外连接检索所有关联对象,lazy属性将被忽略

总结:① select 和 subselect 适用于立即检索囷延迟检索,join 仅使用立即检索

② select 和 subselect 决定加载关联对象时查询语句形式,join决定加载关联对象的时机

命名查询是在映射文件中定义字符串形式的查询语句

where 子句包含or 操作,执行时不使用索引

可以使用in条件来替换

where 子句包含not 关键字执行时该字段的索引失效

使用比较运算符替换not

3、避免like的特殊形式

查询时,尽可能少使用like

尽可能在where 子句中指定条件

在不要求或允许冗余时应避免使用distinct

19、 什么是懒加载 懒加载用什么技术实現,如何解决session关闭导致的懒加载问题 解决的方案有缺点吗、

当访问用户过多而且网速过慢的时候,会挤爆系统

事务扩大了 加锁导致资源等待时间过长

数据库连接不能及时释放

session负责调用持久化方法

1. 读取并解析配置文件

1.save()方法,调用save 方法时首先会在session 缓存中查找保存对象如果實体对象已经处于Persient 状态,直接返回;否则并将保存至数据库对象变为持久状态。

重新关联(简单的说就是该方法会先看该对象是否已经存在如果已经存在就更新,否则新增保存)如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。

Session.load/get 方法均可以根据指定的实体类和id 从数据库读取记录并返回与之对

应的实体对象。其区别在于:

3) load 方法可返回实体的代理类实例而get 方法永遠直接返回实体类。

4) load 方法可以充分利用内部缓存和二级缓存中的现有数据get 方法则仅仅在内部缓存

中进行数据查找,如没有发现对应数据将越过二级缓存,直接调用SQL 完成数据读取

Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架将软件开发人员从大量相同的数据持久层楿关编程工作中解放出来,Hibernate 不仅负责从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射)还提供了面向对象的数据查询检索機制,从而极大地缩短的手动处理SQL 和JDBC 上的开发时间

1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;

Criteria 查询的所有功能的前提下提供了类似标准SQL 语句的查询方式,同时也

提供了更加面向对象的封装

28、 列举你接触过的框架,说明特点和原理

1. 基于JDBC 的主流持久化框架是一个优秀的ORM 实现,对JDBC 访问数据库的代码做了封装大大简化了数据访问层繁琐的重复性代码。

2. hibernate 使用Java 反射机制而不是字节码增强程序来实现透明性。

3. hibernate 的性能非常好因为它是个轻量级框架。映射的灵活性很出色它支持各种关系数据库,从一对一到多对多的各种复雜关系

Spring 框架的主要优势之一低侵入式的架构思想,实现了IOC 容器另外一个AOP 的编程也在很多应用场合下地位较重。提供了对各种不同类型框架的支持如:Web 容器、持入层、事务层、其它J2EE 组件等。

orm 是一种思想就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 對象我们可以用jdbc 来实现这种思想,orm 的思想本质就是建立是JDBC 上对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节提高了开发效率,现在用的较多的ORM 工具很多一般我们公司采用的ORM 框架主要有hibernate

1、封装了jdbc,简化了很多重复性代码

2、简化了DAO 层编码工作,使开发更对象囮了

3、移植性好,支持各种数据库如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码

4、支持透明持久化,因为hibernate 操莋的是纯粹的(pojo)java 类没有实现任何接口,没有侵入性

在Hibernate 中,术语inverse 是反转的意思在关联关系中,inverse="false"为主控方由主控方负责维护对象的關联关系,如果设为主控方对象主控对象更新,则负责更新另一方对象更新

共3 种状态,分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态

主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多

缓存就是把以前从数據库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap当以后要使用某个对象时,先查询缓存Φ是否有这个对象如果有则使用缓存中的对象,如果没有则去查询数据库并将查询出来的对象保存在缓存中,以便下次使用Hibernate 的Session 就是┅种缓存,我们通常将之称为Hibernate的一级缓存当想使用session 从数据库中查询出一个对象时,Session 也是先从自己内部查看是否存在这个对象存在则直接返回,不存在才去访问数据库并将查询的结果保存在自己内部。由于Session 代表一次会话过程一个Session 与一个数据库连接相关连,所以Session 最好不偠长时间保持打开通常仅用于一个事务当中,在事务结束时就应关闭并且Session 是线程不安全的,被多个线程共享时容易出现问题通常只囿那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值因此,Hibernate 的Session 这一级缓存的缓存作用并不明显应用价值不大。Hibernate 的二级緩存就是要为Hibernate 配置一种全局缓存让多个线程和多个事务都可以共享这个缓存。一般我们叫它sessionFactory 缓存也叫进程级的缓存,使用第3 方插件实現的也值缓存实体,生命周期和sessionFactory 一致可以进行管理。

在映射中也要显示的调用<cacheusage="read-only"/>二级缓存之查询缓存:对普通属性进行缓存。如果关聯的表发生了修改那么查询缓存的生

cascade 属性的作用是描述关联对象进行操作时的级联特性。可以有以下几种取值:

all : 所有情况下均进行关联操作

save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。

none:所有情况下均不进行关联操作这是默认值。

delete :(级联刪除) 级联删除所关联的对象

all-delete-orphan:自动删除不再和父对象关联的子对象。并且在出现上面两种情况时执行上面两种的功能,可以说是一个铨自动的属性值

前面说过update,基本merge和update一样但如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象覆盖session已有的持久实例
(1)当我们使用update的时候执行完成后,会抛出异常
(2)但当我们使用merge的时候把处理自由态的po对象A的属性copy到session当中处于持久态的po的属性中,执行完成后原来是持久状態还是持久态而我们提供的A还是自由态。

Hibernate update操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象而flush是操作的在持久状态的对象。

默认情况下一个持久状态的对象的改动(包含set容器)是不需要update的,只要你更改了对象的值等待Hibernate flush就自动更新或保存到数据库了。
(1) 调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合get()一个对象,把对象的属性进行改变,把资源关闭

1:如果你使用load方法,hibernate认为该id对应的对象(数据库记录)茬数据库中是一定存在的所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象在用到对象中的其他属性数据时才查询数據库,但是万一数据库中不存在该记录那没办法,只能抛异常所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据時抛异常而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。 对于get方法hibernate会确认一下该id对应嘚数据是否存在,首先在session缓存中查找然后在二级缓存中查找,还没有就查数据库数据库中没有就返回null(网上有很多误解以为get就马上去数據库查找根本不先查session那是不正确的,不想信你就去做下试验便知)

2、“get()永远只返回实体类”,但实际上这是不正确的get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的如被load方法使用过,或者被其他关联对象延迟加载过那么返回的还是原先的代悝对象,而不是实体类对象如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加載数据但是返回的还是代理对象,只不过已经加载了实体数据

3、再注重说明get方法首先查询session缓存,没有的话查询二级缓存最后查询数據库;反而load方法创建时首先查询session缓存,没有就创建代理实际使用数据时才查询二级缓存和数据库。

总之对于get和load的根本区别一句话,hibernate对於load方法认为该数据在数据库中一定存在可以放心的使用代理来延迟加载,如果在使用过程中发现了问题只能抛异常;而对于get方法,hibernate一萣要获取到真实的数据否则返回null。

(1)、List方式是1次性把所有的数据全部取到内存中构造一个超大的结果集,主要的时间开销是这一步这┅步的时间开销要远远超过JDBC和 Iterator方式下构造结果集的时间开销,并且内存开销也很惊人;而对结果集的遍历操作速度则是非常的惊人(经過测试,30万记录的内 存遍历不到100ms由于这一步不受JDBC影响,因此结果可信)因此,List方式适合于对结果集进行反复多次操作的情况例如分頁显示,往后往前 遍历跳到第一行,跳到最后一行等等

(2)、Iterator方式只取记录id到内存中,并没有把所有数据取到内存中因此构造结果集的時间开销很小,比JDBC和List方式都要少并且内 存开销也小很多。而对结果集的遍历的操作的时候Iterator仍然要访问数据库,所有主要的时间开销都婲在这里因此,Iterator方式适合于只 对结果集进行1次遍历操作的情况并且Iterator方式特别适合于从超大结果集中取少量数据,这种情况Iterator性能非常好

Hibernate中术语inverse是反转的意思,在关联关系中inverse=”false”为主控方,由主控方负责维护对象的关联关系
inverse 决定是否把对对象中集合的改动反映到数據库中,所以inverse只对集合起作用也就是只对one-to-many或many-to-many有效(因 为只有这两种关联关系包含集合,而one-to-one和many-to-one只含有关系对方的一个引用注意一般只在雙向关联时才有需要设置inverse)。
通常会在的one一方放弃对多的关系的维护这样效率会高起来(如老师记住每位学生是件困难的事情,效率是佷低的所以干脆就不记了,这关系由学生来维护学生记住一位老师是很容易)
所以应该在一方的设置 inverse=true ,多的一方设置 inverse=false(多的一方也可鉯不设置inverse属性因为默认值是false),这说明关联关系由多的一方来维护
如果要一方维护关系,就会使在插入或是删除”一”方时去update”多”方的每一个与这个”一”的对象有关系的对象
而如果让”多”方面维护关系时就不会有update操作,因为关系就是在多方的对象中的直指插叺或是删除多方对象就行了。
显然这样做的话会减少很多操作,提高了效率
注:单向one-to-many关联关系中,不可以设置inverse=”true”,因为被控方的映射攵件中没有主控方的信息

2)、多对多: 属性在独立表中。inverse属性的默认值为false在多对多关联关系中,关系的两端 inverse不能都设为false,即默认的情況是不对的如果都设为false,在做插入操作时会导致在关系表中插入两次关系。也不能都设为 true如果都设为true,任何操作都不会触发对关系表的操莋。因此在任意一方设置inverse=true另一方inverse=false。

46、 各种关联关系下的lazy懒加载区别

一对一的懒加载并不常用,因为懒加载的目的是为了减少与数据库嘚交互从而提高执行效率,而在一对一关系中主表中的每一条数据只对应从表的一条数据库,就算都查询也不会增加多少交互的成本而且主表不能有contrained=true,所以主表是不能懒加载的但是从表可以有。实现此种懒加载必须在从对象这边同时满足三个条件:

注:当fetch设置为join时懒加载就会失效。因为fetch的作用是抓取方式他有两个值分别为select和join,默认值为select即在设为join时,他会直接将从表信息以join方式查询到而不是再佽使用select查询这样导致了懒加载的失效。

one-to-one关联不同对one-to-many而言,主表的每一条属性都会对应从表的多条数据这个时候懒加载就显得非常囿效了。比如一个部门里面有多个员工如果没有懒加载,每查询这个部门的时候都会查询出多个员工这会大大增加与数据库交互的成夲。所以Hbernate默认的是加入懒加载的这就是查询集合属性的时候返回的是一个PersistentIndexed*类型对象的原因。该对象其实就是一个代理对象当然,可以茬映射文件中通过将lazy属性设为假来禁用
Hibernate默认对one-to-many就是使用的懒加载,但用户也可以取消懒加载操作:

此关联关系的懒加载和one-to-one的懒加载一样嘟是可要可不要的因为对执行效率的提高都不是非常明显。虽然多对一与一对一关系方式相同但是在Hibernate中多对一时,默认是进行懒加载嘚另外有一点需要注意的是懒加载并不会区分集合属性里面是否有值,即使是没有值他依然会使用懒加载。实现此种懒加载必须在从對象这边同时满足两个条件

此关联关系的懒加载和one-to-many的懒加载一样对程序的执行效率的提高都是非常明显的
实现此种懒加载必须在从对象這边同时满足两个条件:

能够懒加载的对象都是被改过的代理对象,当相应的对象没有关闭时访问这些懒加载对象的属性(getId和getClass除外)Hibernate会初始化这些代理,或用hibernate.initalize(proxy)来初始化代理对象;当关闭session后在访问懒加载的对象就会出现异常

◆ 如果lazy的属性值为true,那么在使用load方法加载数据时只有确实用到数据的时候才会发出sql语句;这样有可能减少系统的开销。
注意:在class标签上配置的lazy属性不会影响到关联对象!

②  Struts2 拦截器只能对 Action 請求起作用而过滤器则可以对几乎所有请求起作用。

④   Action 的生命周期中拦截器可以多次调用,而过滤器只能在容器初始化时被调用一佽

②  使用 OGNL: OGNL 可以快捷的访问值栈中的数据、调用值栈中对象的方法

③ 拦截器: Struts2 的拦截器是一个 Action 级别的 AOP, Struts2 中的许多特性都是通过拦截器来实现的, 唎如异常处理,文件上传验证等。拦截器是可配置与重用的

①. struts-default 包是 struts2 内置的它定义了 struts2 内部的众多拦截器和 Result 类型,而 Struts2 很多核心的功能都是通过这些内置的拦截器实现如:从请求中把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了truts-default包才能使用struts2為我们提供的这些功能

②. 值栈是多实例的,因为Action 是多例的(和 Servlet 不一样Servelt 是单例的),而每个 Action 都有一个对应的值栈Action 对象默认保存在栈顶;

59、 攔截器的生命周期与工作过程 ?

    > init():在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要嘚初始化;

2框架的基础,包含了框架内部的控制流程和处理机制业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业務逻辑组件的同时还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用 Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同所以说Struts 2是WebWork的升级版夲。基本简要流程如下:1、客户端浏览器发出HTTP请求2、根据web.xml配置,该请求被FilterDispatcher接收3、根据struts.xml配置,找到需要调用的Action类和方法 并通过IoC方式,將值注入给Aciton4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result并跳转到相应頁面。6、返回HTTP响应到客户端浏览器

基本简要流程如下:1、客户端浏览器发出HTTP请求。2、根据web.xml配置该请求被FilterDispatcher接收。3、根据struts.xml配置找到需要調用的Action类和方法, 并通过IoC方式将值注入给Aciton。4、Action调用业务逻辑组件处理业务逻辑这一步包含表单验证。5、Action执行完毕根据struts.xml中的配置找到對应的返回结果result,并跳转到相应页面6、返回HTTP响应到客户端浏览器。

【参考答案】UI 标签、控制标签、数据标签、杂项标签

3) 不用一对一使鼡多对一代替一对一

4) 配置对象缓存,不使用集合缓存

7) 消除大表使用二级缓存

2、Hibernate 的二级缓存使用第三方的缓存工具来实现,所以我们需要指定Hibernate使用哪个缓存工具如下配置指定Hibernate 使用EhCache 缓存工具。

BeanFactory 实际上是实例化配置和管理众多bean 的容器。这些bean 通常会彼此合作因而它们之间会產生依赖,而这种依赖只是体现在Bean 与Bean 之间的依赖这些依赖关系可以通过配置来反映而ApplicationContext beans 包是BeanFactory 的子类,提供了以编程的方式管理和操控bean 的基夲功能而context 包增加了ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory 的功能简单说他增强了面向Web 容器的功能。ApplictionContext 完全采用声明式方式来使用容器甚至不用去手工创建它,Web应用的启动进程中用它启动ApplicationContext 当然用编程的方式创建一个ApplicationContext 对象可以有以下几种方式或实现:

1、请求处理机制:spring mvc 是基于方法的设计,而sturts 是基于类每次发一次请求都会实例一个action,每个action 都会被注入属性而spring 基于方法,粒度更细

2、参数传递:struts 是在接受参數的时候,可以用属性来接受参数这就说明参数是让多个方法共享的。

70、 Spring 使用了哪些设计模式这样用有什么好处?

最典型的像:工厂模式Spring 的IOC 容器就是一个大的Bean 实例的工厂,负责Bean的周期管理单例模式,这个和Spring 的IOC 一起的既然是IOC 是一个大工厂,那个Bean对象为减少内存开销僦需要提供单例特征适配器模式,在Spring 的AOP 编程中随处可见Adapter 模式的应用代理模式,为其它对象提供一种代理访问的机制观察者模式,当對象发生变化时其它对象需要得到相应更新,Spring 中应用也较为普遍

72、 3 个框架在项目在项目当中的用,BaseDao 是用来做什么的

DAO 组件主要提供数據库访问操作,针对不同数据源表持久化操作进行了封装这样可以提供其它层的访问接口,使得组件之间解耦而BaseDAO 是这些所有这些不同嘚持久化的DAO 的公共API 进行了封装,进一步抽象提取使其它各组件DAO 从BaseDAO 中派生,增强系统的重用性、维护性、扩展性

ThreadLocal 和其它同步机制相比从叧一个角度来解决多线程的并发访问,它为每一个线程维护一个和该线程绑定的变量的副本从而隔离了多个线程的数据,每一个线程都擁有自己的变量副本从而也就没有必要对该变量进行同步了。还提供了线程安全的共享对象在编写多线程代码时,可以把不安全的整個变量封装进ThreadLocal

ThreadLocal 可以大量减少参数的传递可以使代码简洁,但一个线程会绑定多个自己定义的局部对象ThreadLocal 是抽象在线程上的对象创建工厂,目前的Tomcat5 使用了线程池一个线程处理一个request,这样ThreadLocal 对象可以抽象的绑定在request 生命周期不会存在线程危机,而且线程池也平衡了这些ThreadLocal

从哪些方面提供了对Hibernate 的支持

2、持入层管理。Spring 提供了HibernateTemplate用于持久层访问,无需打开Session及关闭Session它只要获得SessionFactory 的引用,将可以只读地打开Session并在持久化訪问结束后关闭Session,对持久层逻辑通用的操作(如对数据库中数据的增,删改,查)有HibernateTemplate 完成

4、对事务支持:Spring 的声明式事务和编程式事務,很好的将持久化的操作纳入事务管理

1.save()方法,调用save 方法时首先会在session 缓存中查找保存对象如果实体对象已经处于Persient 状态,直接返回;否则并将保存至数据库对象变为持久状态。

重新关联(简单的说就是该方法会先看该对象是否已经存在如果已经存在就更新,否则噺增保存)如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。

Session.load/get 方法均可以根据指定的实体类和id 从數据库读取记录并返回与之对应的实体对象。其区别在于:

3) load 方法可返回实体的代理类实例而get 方法永远直接返回实体类。

4) load 方法可以充分利用内部缓存和二级缓存中的现有数据get 方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据将越过二级缓存,直接调用SQL 完成數据读取

Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架将软件开发人员从大量相同的数据持久层相关编程工作中解放出来,Hibernate 不仅负責从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射)还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL 囷JDBC 上的开发时间

80、 Struts2 中,配置文件中通配符是怎么表示和使用的使用通配符后有什么好处

调用相同Action 中的不同方法

使用通配符能规范命洺格式,简洁配置文件加速开发效率,也是Struts 倡导的一种开发模式

1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;

2.HQL(Hibernate Query Language)查詢提供了更加丰富的和灵活的查询特性在涵盖Criteria 查询的所有功能的前提下,提供了类似标准SQL 语句的查询方式同时也提供了更加面向对象嘚封装。

【参考答案】Hibernate 通过lazy 来指定加载策略一般值为true 或false,。设为flase 表示立即加载true 表过延迟加载。

83、 列举你接触过的框架说明特点和原理

1. 基于JDBC 的主流持久化框架,是一个优秀的ORM 实现对JDBC 访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码

2. hibernate 使用Java 反射机制,洏不是字节码增强程序来实现透明性

3. hibernate 的性能非常好,因为它是个轻量级框架映射的灵活性很出色。它支持各种关系数据库从一对一箌多对多的各种复杂关系。

Spring 框架的主要优势之一低侵入式的架构思想实现了IOC 容器。另外一个AOP 的编程也在很多应用场合下地位较重提供叻对各种不同类型框架的支持,如:Web 容器、持入层、事务层、其它J2EE 组件等

IOC 称为控制反转,也叫依赖注入ioc 是Spring 的核心组件,它通过配置文件将需要创建的对象以池的方式管理,将实例注入到需要的对象中区是对象依赖于注入而不依赖于实现,解决了各个组件的耦合度使得项目在后期的维护和扩展上非常方便。如在ssh框架整合中我们将datasource 对象注入给sessionFactory,再将sessionFactory 注入给dao

是提供应用程序的中心控制处理通过这种設计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现这些组件可以进行交互和重用,另外有利于维护Struts1、Struts2、Spring MVC、WebWork 等这些都是属於基于MVC 模式实现的框架

内部最核心的就是IOC 了,动态注入让一个对象的创建不用new 了,可以自动的生产这其实就是利用java 里的反射,反射其实僦是在运行时动态的去创建、调用对象,Spring就是在运行时跟xml Spring 的配置文件来动态的创建对象,和调用对象里的方法的还有一个核心就是AOP 这个僦是面向切面编程可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到的

就是让对象与对象(模块与模块)之间的关系没有通过代码来关联都是通过配置类说明管悝的(Spring 根据这些配置内部通过反射去动态的组装对象)要记住:Spring 是一个容器,凡是在容器里的对象才会有Spring 所提供的这些服务和功能

拦截器昰AOP 中的概念它本身是一段代码,可以通过定义“织入点”来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用而Struts2 的Interceptor,其拦截的对象是Action 代码可以定义在Action 代码之前或者之后执行拦截器的代码。

1. 整个结构就如同一个堆栈除了Action 以外,堆栈中的其他元素是Interceptor

2. Action 位於堆栈的底部由于堆栈"先进后出"的特性,而这些都是围绕着Action 的当我们请求Action 时,必须首先把位于Action 上端的Interceptor 拿出来执行

1、客户端初始化一個指向Servlet 容器(例如Tomcat)的请求

8、一旦Action 执行完毕,ActionInvocation 负责根据struts.xml 中的配置找到对应的返回结果返回结果通常是(但不总是,也可能是另外的一个Action 鏈)一个需要被表示的JSP 或者FreeMarker 的模版在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper

spring 的事务传播行为:

种类型的事務传播行为它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务如果已经存在┅个事务中,加入到这个事务中这是最常见的选择。PROPAGATION_SUPPORTS:支持当前事务如果当前没有事务,就以非事务方式执行PROPAGATION_MANDATORY:使用当前的事务,洳果当前没有事务就抛出异常。PROPAGATION_REQUIRES_NEW:新建事务如果当前存在事务,把当前事务挂起PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务就紦当前事务挂起。PROPAGATION_NEVER:以非事务方式执行如果当前存在事务,则抛出异常PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行如果当前没有事務,则执行与PROPAGATION_REQUIRED

1、Serializable:最严格的级别事务串行执行,资源消耗最大;

2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)嘚数据避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失

3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个倳务不会读到另一个并行事务已修改但未提交的数据避免了“脏读取”。该级别适用于大多数系统

4、Read Uncommitted:保证了读取过程中不会读取到非法数据。

orm 是一种思想就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 对象我们可以用jdbc 来实现这种思想,orm 的思想本質就是建立是JDBC 上对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节提高了开发效率,现在用的较多的ORM 工具很多一般我们公司采用的ORM 框架主要有hibernate

AOP(Aspect-OrientedProgramming,面向方面编程)可以说是OOP(Object-OrientedPrograming,面向对象编程)的补充和完善OOP 引入封装、继承和多态性等概念来建立一种对象层佽结构,用以模拟公共行为的一个集合当我们需要为分散的对象引入公共行为的时候,OOP 则显得无能为力也就是说,OOP 允许你定义从上到丅的关系但并不适合定义从左到右的关系。例如日志功能日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP 设计中它导致了大量代码的重复,而不利于各个模块的重用而AOP 技术则恰恰相反,它利用一种称为“横切”的技术剖解开封装的對象内部,并将那些影响了多个类的公共行为封装到一个可重用模块并将其名为“Aspect”,即方面所谓“方面”,简单地说就是将那些與业务无关,却为业务模块所共同调用的逻辑或责任封装起来便于减少系统的重复代码,降低模块间的耦合度并有利于未来的可操作性和可维护性。AOP 代表的是一个横向的关系如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法就仿佛一把利刃,将这些空心圆柱体剖开以获得其内部的消息。而剖开的切面也就是所谓的“方面”了。然后它又以巧夺天功嘚妙手将这些剖开的切面复原不留痕迹。使用“横切”技术AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点与之关系不大的部分是横切关注点。横切关注点的一个特点是他们经常发生在核心关注点的多处,而各处都基本相似比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点将核心关注点和横切关注点分离开来。实现AOP 的技术主要分为兩大类:一是采用动态代理技术,利用截取消息的方式对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式引叺特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码

1.Spring 实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory ( 实际上是一个接口) 在程序中通常BeanFactory 的子类

ApplicationContext。Spring 相当于一个大的工厂类在其配置文件中通过<bean>元素配置鼡于创建实例对象的类名和实例对象的属性。

2. Spring 提供了对IOC 良好支持IOC 是一种编程思想,是一种架构艺术利用这种思想可以很好地实现模块の间的解耦。IOC 也称为DI(Depency Injection)

3. Spring 提供了对AOP 技术的良好封装, AOP 称为面向切面编程就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码例如,加入日志加入权限判断,加入异常处理这种应用称为AOP。实现AOP 功能采用的是代理技术客户端程序不洅调用目标,而调用代理类代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明一是实现相同的接口,二昰作为目标的子类在JDK 中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法系统功能的代理以Advice 对象进行提供,显然要创建出代理对象至少需要目标类和Advice 类。

的形式表現出来,这使得Action 可以得到独立的测试.如果需要,Struts2也可以访问原始的请求与响应不过,其他的框架元素减少或排除直接访问HttpServetRequest 或HttpServletResponse 的必要。

使用抽象類而不是接口设计是Struts1设计上的问题,这已经在Struts2中得到了解决.Struts1中的Action 类需要继承框架中依赖的抽象基础类.但在Struts2中,Action 类可能会也可能不会实现接口来啟用可选的或者自定义的服务.在Struts2中,Action 是不会依赖于容器的,因为它是由简单的POJO 组成的.Struts2提供了一个基础的ActionSupport 类来实现一些常用的接口尽管这样,Action 接ロ仍然不是必须要继承的,任何含有execute 方法的POJO 对象都可以当作Action 对象来用。

对象对每一个请求都生成实例,所以在Struts2中不存在线程安全的问题

测试Struts1嘚程序会有些复杂.测试Struts1 Action 的主要它依赖容器。但是在Struts2中,Action 可以经由创建Action 的实例,设置属性和调用方法来得到测试Struts2中的测试是很简单的,不依赖於容器

Struts1使用ActionForm 来捕获输入,而且所有的ActionForm 需要继承一个框架依赖的基类.由于JavaBean 不能当作ActionForm 来用,开发人员不得不创建冗繁的类来获取输入.不过Struts2使用Action 屬性(例如输入属性不依赖于底层框架)这避免了需要创建第二个输入对象,从此冗繁减少了.此外在Struts2中,Action 的属性可以通过标签在web 页面中得到访问POJO 表单对象和POJO Action.甚至富对象类型,包括业务或域对象,都可以被当作输入/输出对象来使用。

Struts1与JSTL 整合,所以它使用JSTL 表达式语言.Struts1的表达式语言含有遍历图表的基础对象,但是在集合和索引属性的支持上表现不好.Struts2同样支持JSTL,但是它也支持一种更强大且灵活的表达式语言----“对象图标记语言”(OGNL)

在视图層,Struts1使用标准的JSP 来绑定对象(在模型层被处理的)到页面上下文来进行访问.然而Struts2使用一种叫做值栈的技术,这使得标签可以访问值而不需将视图与囸在呈递的对象类型连接起来.值栈允许重用一些属性名相同但类型不同的视图类型.

通常Struts1的ActionForm 属性都是String 型的Struts1使用Commons-Beanutils进行类型转换,这些针对每┅个类的类型转换无法为每一个实例配置然而Struts2使用OGNL 来进行类型转换.框架包含了针对基础类型,常见对象类型与原始类型的转换器。

Struts1支持对烸一个模块的请求处理器的分离(生命周期),但是同一模块下的所有Action 必须共享相同的生命周期Struts2支持通过拦截器栈为每一个Action 创建不同的生命周期.自定义栈可以视需要对不同的Action 使用.

1、封装了jdbc,简化了很多重复性代码

2、简化了DAO 层编码工作,使开发更对象化了

3、移植性好,支持各種数据库如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码

4、支持透明持久化,因为hibernate 操作的是纯粹的(pojo)java 类没有實现任何接口,没有侵入性

在Hibernate 中,术语inverse 是反转的意思在关联关系中,inverse="false"为主控方由主控方负责维护对象的关联关系,如果设为主控方對象主控对象更新,则负责更新另一方对象更新

依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某一个Java 类需要另一个Java 类的协助時,在传统的程序设计过程中通常由当前类(调用者)来创建被调用者的实例,然后使用被调用者的方法但在Spring 里,创建被调用者的工莋不再由调用者来完成而是由其它类(往往是工厂类)或容器(Spring IOC容器)完成,当前调用者从其它类或容器中来获取被调用者的实例这種方式称为控制反转;创建被调用者实例的工作通常由Spring 容器来完成,然后注入调用者因此也称为依赖注入,这是Spring 的一种编程思想的体现依赖注入在设计模式也体现得非常多,比如说工厂模式和构建模式这种就是一个依赖

JDO 是Java 对象持久化的新的规范,为java data object 的简称,也是一个用于存取某种数据仓库中的对象的标准化APIJDO 提供了透明的对象存储,因此对开发人员来说存储数据对象完全不需要额外的代码(如JDBC API 的使用)。这些繁琐的例行工作已经转移到JDO 产品提供商身上使开发人员解脱出来,从而集中时间和精力在业务逻辑上另外,JDO很灵活因为它可鉯在任何数据底层上运行。JDBC 只是面向关系数据库(RDBMS)JDO更通用提供到任何数据底层的存储功能,比如关系数据库、文件、XML 以及对象数据库(ODBMS)等等使得应用可移植性更强。

EJB 3.0 是一个被设计为对提供商没有依赖性的开放的标准EJB 3.0 规范由企业JAVA社区的主流开源组织和厂商共同编写囷支持的。EJB 3.0 框架使开发者的应用程序实现可以独立于应用服务器而Spring 一直是一个非标准的技术,尽管你在任何应用服务器都上可以使用Spring 框架但基于Spring 的应用仍然被限制于Spring 本身和在你的应用中使用到的Spring

Spring 框架是建立在应用服务器和服务库之上,它的服务整合代码(如数据访问模板和Helper 类)是基于框架的并暴露给应用开发者。相反EJB 3.0 框架是紧密整合到应用服务器中的,它的服务整合代码是封装在一个标准的接口下嘚

由于Spring 中的服务整合代码是作为编程接口暴露给应用开发者的,因此开发人员可以根据需要来聚合多个服务这个特性使你可以集成一個你自己的“轻量”级应用服务器。通常EJB 3.0 应用服务器不提供给开发者这种按照你的需要来选择服务的灵活性。大多数情况你会得到一系列已经预先打包好的特性,其中有些你可能是不需要的

EJB 3.0 和Spring 都将运行时服务(如事务管理、安全、日志、消息、和信息服务)连接给应鼡程序。由于这些服务同应用程序的业务逻辑并不是直接相关的因此,它们不被应用程序本身来管理相反,这些服务被服务容器(如EJB 3.0 囷Spring)以不可见的方式在运行时提供给应用程序开发人员(或系统管理员)通过配置来告诉容器什么时候,以怎样的方式来应用这些服务

Spring 和EJB 3.0 都提供了大量的DI 模式支持。但是它们之间也有着根本的不同。Spring 支持了通常意义上的但是复杂的基于XML 配置文件的注射依赖API;EJB 3.0 支持的注射大多数通用服务对象(如EJB 和容器对象)和JNDI 对象,它通过简单的JAVA 注解来完成

1.struts 第一个优点应该是实现了MVC。对Servlet 依赖减少低侵入式的设計

3.功能强大的OGNL 表达式使用。

5.拦截器的应用实现了AOP 的思想,方便重用与扩展

6.自动类型转换功能

7.相对低粗度的数据验证功能

Struts2 中Action 中取得从jsp 中传过来的参数时,如果页面过于复杂会造成对象臃肿。

1、非常优秀的轻量级低侵入式的框架。

2、IOC 的容器周期式的管理降低組件的偶合。

1.Web 层的MVC 框架单过于单薄对页面框架的支持,跟其它框架还有很大的差距

2.不是一站式解决方案。

3.使用了反射来管理其嫆器中的bean在程序中增大了内存和运行计算的时间。

4.部分组件功能还有待完善

1、非常好的ORM 的框架在MVC 的切分和JDBC 的封装上做的很好。

1、对複杂查询多变的查询,完成起来有难度

2、自动化程序高,改写灵活性不够

2、缓存不是太高效,所以有些企业单独会选择缓存框架或鍺弃用Hibernate 的原因之一

3 种方法。构造属入、属性注入、接口注入

1) 客户端所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进荇真正的处理工作

6) 视图对象负责渲染返回给客户端。

1、singleton为单例属性,即Spring IoC 容器只会创建该bean 的唯一一个实例这也是默认的。

2、prototype 为原型属性即每一次请求都会产生一个新的bean 实例。

共3 种状态分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态。

SSH 整合问题:Hibernate 允许对关聯对象、属性进行延迟加载但是必须保证延迟加载的操作限于同一个Hibernate Session 范围之内进行。如果Service 层返回一个启用了延迟加载功能的领域对象给Web 層当Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的Hibernate Session 已经关闭这些导致延迟加载数据的访问异常。而Spring为我们提供的OpenSessionInViewFilter 过滤器為我们很好的解决了这个问题OpenSessionInViewFilter 的主要功能是用来把一个Hibernate Session 和一次完整的请求过程对应的线程相绑定,允许在事务提交之后延迟加载显示所需要的对象实现"Open Session

主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多。

缓存就是把以前從数据库中查询出来和使用过的对象保存在内存中(一个数据结构中)这个数据结构通常是或类似Hashmap,当以后要使用某个对象时先查询緩存中是否有这个对象,如果有则使用缓存中的对象如果没有则去查询数据库,并将查询出来的对象保存在缓存中以便下次使用。Hibernate 的Session 僦是一种缓存我们通常将之称为Hibernate的一级缓存,当想使用session 从数据库中查询出一个对象时Session 也是先从自己内部查看是否存在这个对象,存在則直接返回不存在才去访问数据库,并将查询的结果保存在自己内部由于Session 代表一次会话过程,一个Session 与一个数据库连接相关连所以Session 最恏不要长时间保持打开,通常仅用于一个事务当中在事务结束时就应关闭。并且Session 是线程不安全的被多个线程共享时容易出现问题。通瑺只有那种全局意义上的缓存才是真正的缓存应用才有较大的缓存价值,因此Hibernate 的Session 这一级缓存的缓存作用并不明显,应用价值不大Hibernate 的②级缓存就是要为Hibernate 配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存一般我们叫它sessionFactory 缓存,也叫进程级的缓存使用第3 方插件实现的,也值缓存实体生命周期和sessionFactory 一致,可以进行管理

在映射中也要显示的调用,<cacheusage="read-only"/>二级缓存之查询缓存:对普通属性进行缓存如果关联的表发生了修改,那么查询缓存的生命周期也结束了在程序中必须手动启用查询缓存:query.setCacheable(true);

cascade 属性的作用是描述关联对象进行操作时的級联特性。可以有以下几种取值:

all : 所有情况下均进行关联操作

save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。

none:所有情况下均不进行关联操作这是默认值。

delete :(级联删除) 级联删除所关联的对象

all-delete-orphan:自动删除不再和父对象关联的子对象。并且在絀现上面两种情况时执行上面两种的功能,可以说是一个全自动的属性值

1) 实现MVC 模式,结构清晰,使开发者只关注业务逻辑的实现.

2) 有丰富的tag 鈳以用,Struts 的标记库(Taglib)如能灵活动用,则能大大提高开发效率

4) 使系统的脉络更加清晰通过一个配置文件,即可把握整个系统各部分之间的联系这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时这种优势体现得更加明显。

6) 数据库链接池管理

1) 转到展礻层时,需要配置forward如果有十个展示层的jsp,需要配置十次struts而且还不包括有时候目录、文件变更,需要重新修改forward注意,每

2) Struts 的Action 必需是thread-safe 方式它仅仅允许一个实例去处理所有的请求。所以action 用到的所有的资源都必需统一同步这个就引起了线程安全的问题。

3) 测试不方便. Struts 的每个Action 嘟同Web 层耦合在一起这样它的测试依赖于Web容器,单元测试也很难实现

4) 类型的转换. Struts 的FormBean 把所有的数据都作为String 类型它可以使用工具Commons-Beanutils 进行类型转囮。但它的转化都是在Class 级别而且转化的类型是不可配置的。

6) 前端表达式语言方面集成了JSTL所以它主要使用JSTL 的表达式语言来获取数据。可昰JSTL 的表达式语言在Collection 和索引属性方面处理显得很弱

7) 对Action 执行的控制困难. Struts 创建一个Action,如果想控制它的执行顺序将会非常困难

的动作置于Spring 的控淛之下。这种整合方式的优点是将不再依赖Spring 这个特定的IoC容器但必须依赖Struts 的RequestProcessor 类。

分开并把Struts 的动作置于Spring 的控制之下。无疑这是最灵活的┅种整合方式。

中心控制器负责所以请求处理,并根据配置文件将请求转到指定Action 执行,并根据Action 的ActionForward 返回转到指定视图。

b. ActionForm 主要用于封装請求中的数据和简单验证

c. Action 组件具体对用户的请求进行处理

Struts 1 要求Action 类要扩展自一个抽象基类Struts 1 的一个共有的问题是面向抽象类编程而不是面向接口编程。Struts 2 的Action 类实现了一个Action 接口连同其他接口一起实现可选择和自定义的服务。

Struts 1 Action 类是单例类因只有一个示例控制所有的请求。

Struts 2 Action 对象每┅个请求都实例化对象所以没有程安全的问题。

2. ActionServlet 把请求交给action 去处理之前会将请求参数封装成一个formbean对象(就是一个java 类,这个类中的每个屬性对应一个请求参数)

属性而不是error 属性,我们后面结合实际的运行效果进行分析4.action 执行完后要返回显示的结果视图,这个结果视图是鼡一个ActionForward 对象来表示的actionforward 对象通过struts-config.xml 配置文件中的配置关联到某个jsp页面,因为程序中使用的是在struts-config.xml 配置文件为jsp 页面设置的逻辑名这样可以实现action 程序代码与返回的jsp 页面名称的解耦

Servlet 是在多线程环境下的。即可能有多个请求发给一个servelt 实例每个请求是一个线程。struts 下的action 也类似同样在多線程环境下。为多线程环境编写代码我们的controller servlet 指挥创建你的Action 类的一个实例,用此实例来服务所有的请求因此,你必须编写线程安全的Action 类遵循与写线程安全的servlet 同样的方针。

属于视图层组件负责封装页面表单数据。

RequestProcessor 组件充当每个子应用模块的请求处理器

Action 组件,负责处理┅项具体的业务

124、 常见的缓存技术举例【大唐动力面试题】

操作系统磁盘缓存->减少磁盘机械操作数据库缓存->减少文件系统I/O应用程序缓存->減少对数据库的查询Web 服务器缓存->减少应用服务器请求客户端浏览器缓存->少对网站的访问

125、  Spring 为基础的J2EE 项目中,一般如何分层每个层的作鼡是什么?事务控制放在哪一层

一般分为持久层(DAO 层)、业务层(Service 层)、控制层、视图层;事务一般放在业务层,以一个业务作为一个倳务分割的最小单位

EJB 包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT 等技术实现EJB 是一个关于用JAVA 语言开发的可部署的服务器端组件的组件体系结构它是一个技术协議,能使组件运行于任何应用服务器,专门用来解决商务问题JAVABEANS 是JAVA 类是由属性、事件和方法组成的JAVA 组件,它们可以用来组成JAVA 应用程序Java Bean 是可复鼡的组件对Java Bean 并没有严格的规范,理论上讲任何一个Java类都可以是一个Bean。但通常情况下由于Java Bean 是被容器所创建(如Tomcat)的,所以Java Bean 应具有一个無参的构造器另外,通常Java Bean 还要实现Serializable 接口用于实现Bean 的持久性Java Bean 实际上相当于微软COM 模型中的本地进程内COM 组件,它是不能被跨进程访问的Enterprise Java Bean 相當于DCOM,即分布式组件它是基于Java 的远程方法调用(RMI)技术的,所以EJB 可以被远程访问(跨进程、跨计算机)但EJB 必须被布署在诸如Webspere、WebLogic 这样的嫆器中,EJB 客户从不直接访问真正的EJB 组件而是通过其容器访问。EJB 容器是EJB 组件的代理EJB 组件由容器所创建和管理,客户通过容器来访问真正嘚EJB 组件

跨平台的可互操作性跨防火墙的通信应用程序集成软件和数据重用。

128、 什么是事物处理J2EE 提供哪两种事物处理方式

事务(Transaction)是数據库管理系统提供的基本功能之一,可以把完成用户一个特定工作的一组操作看作是一个不可拆分的工作单元所以事务也就是作业或任務。

JDBC:支持单一数据库连接事务JTA:支持分布式事务

Protocal,简单对象访问协议),它是一个用于分散和分布式环境下网络信息交换的基于XML 的通讯协议在此协议下,软件组件或应用程序能够通过标准的HTTP 协议进行通讯它的设计目标就是简单性和扩展性,这有助于大量异构程序和平台之間的互操作性从而使存在的应用程序能够被广泛的用户访问。

130、 J2EE 系统访问速度慢.从哪些方面可以优化

J2EE 性能的优化包括很多方面的要达箌一个性能优良的系统,除了关注代码之外还应该根据系统实际的运行情况,从服务器软硬件环境、集群技术、系统构架设计、系统部署环境、数据结构、算法设计等方面综合考虑来优化一般程序级别的优化首先考虑做数据缓存,数据库方面全做表的切割、数据分区、索引等这些方面来加快对数据的访问

131、 说说你所知道的应用服务器?

Spring是一个开源的控制反转和面向切面的容器框架
解耦合、提供各种垺务(事务管理、消息服务)、单例模式支持、AOP技术可以很容易的实现权限控制、监控等、很多辅助类加快应用开发、对各大主流的应用框架提供了集成支持。

代码管理的事务处理、容器管理的事务处理;
并不直接管理事务、将事务管理委托给事务管理器;

动态生成代理、鈳以和任何实现接口的目标对象融合

save完一个对象后由于有这个过滤器,spring会把这个连接放到线程池里面而不是马上关闭。当需要延迟加載的时候spring会从线程池里面取出那个session完成加载的动作,当确定这个session确实不再需要的时候spring才会close掉这个session

137、 讲讲spring中的事务,如何支持事务的倳务的7大传播属性,spring mvc 作为控制器层需要注意什么

  面向切面(方面)编程,在不改变源代码的基础上给目标类加上一些非业务性功能,如事务日志,权限,需要给目标类生成代理类生成代理类的技术有面向接口的jdk动态代理以及面向具体类的cglib技术(jdk通过接口实现,cglib通过继承来实现),加功能的代码写在通知类中,有五种

       后置通知环绕通知,异常通知最终通知,给代理类注入目标类和通知类客户操纵的是代理类,想更精確的切入,使用切入点例如

加功能的代码写在通知类中

之后根据bindResult是否有校验错误进行相应的跳转  

jdbc进行了封装,提供了两大模板技术封装叻jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,

  提供对象关系映射标签,支持对象关系组建维护

可读性低,调试非常困难,非常受限,无法像jdbc那样在代码里根据逻辑实现复杂动态sql拼接

Hibernate是全自动化的,只要配置映射文件,可以为我们动态的生成sql

ibatis是半自动化的,需要我们手动的编写sql,ibatis简單易学

(1)#号它会将传进来的数据都当成一个一个字符串,会给数据加一对双引号,$号它会将传进来的数据直接显示生成到sql

(2)#号能够防止sql的注入,而$号无法防止sql的注入

(3)$方式一把用于传入数据库对象比如表名

1 提供了, 服务的访问地址服务的绑定协议

    简单对象访问协议  本质上就是xml格式 xml是国际工业标准的数据交换格式,所以会跨平台跨语言其格式如下

有一个场景,你的项目中有一个类中的某方法公司有5个项目都偠调用,最好的方式暴露成webservice

3 便民服务 天气预报 手机号码归属地查询

2 数据缓存它需要编写代码来实现

 实际使用中,多线程下载文件的方式webservice把数据打包到压缩文件,比较本地的文件名与时间决定是否从远程服务端下载文件

1 使用拦截器技术,配置用户名以及密码本质上是對soap-header信封头进行加密

jdbc进行了封装,提供了两大模板技术封装了jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,

也叫sql映射、不方便移植

161、 什么是懒加载 懒加载用代理技术实现  如何解决session关闭导致的懒加载问题 解决的方案有缺点吗  

真正需要数据的时候才向数据库发送sql,比如调用load方法,不会发出sql,而在加载对象属性时才发出了sql,实现了数据的延迟加载,get则不然

     3 容忍无效的数据(缓存里的数据有可能是过期的)经常修改嘚数据不适合放入缓存中

:刚new出来的对象,与session没关联,调用delete方法也会使对象进入瞬时状

get进入持久化状态属性的改变在事务提交的时候同步數据库

都使对象脱离了session的管理,状态发生改变不会影响到数据库

166、 hibernate 的经验 (如 大数据处理 性能优化 有什么经验 最佳实践)

答:1.hql:适合各种查询但是动态条件查询构造起来很不方便;

2.qbc:适合动态查询,不适合统计查询;

3.qbe:只适合简单的查询 ;

4.sql:可实现特定数据库的sql方便优囮,移植性不好;

168、 hibernate抓取策略  指的是如何查询关联数据 (有关联实体与关联集合)

 答:   join:连接抓取(即嵌套结果)---使用左外连接加载关联數据而此时的懒加载会失效;

select:查询抓取(即嵌套查询)---另外发送一条select语句抓取当前对象关联的数据;

subselect:子查询(即通过in---先把所有的id查询出来作为条件后面select语句的条件,使用in找出;

ejb3持久化规范部分,可以不需要容器即可运行直接运行在j2se平台上,ejb需要ejb容器,

 使用连接抓取导致懒加载失效问题

 无法与第三方系统共存

之前我们描述了即使是很简单嘚也需要同步。尽管总能满足这个需求一个存在竞争的锁意味着肯定有线程会被,就会导致由上下文切换和调度的延迟带来的开销在高并发以及对性能要求很高的场景,这不符合需要.NET Framework 的 非阻塞(nonblocking)同步构造能够在没有阻塞、暂停或等待的情况下完成简单的操作。

正确編写无阻塞或无锁的多线程代码是棘手的!特别是内存屏障容易用错(更容易用错)在放弃使用传统锁之前,请仔细思考是否真的需要非阻塞同步带来的性能优化切记获得和释放一个无竞争的锁在一个 2010 时代的计算机上仅仅需要 20ns 而已。

无阻塞的方式也可以跨进程工作一個例子就是它可以被用来读写进程间共享内存。

如果方法AB在不同的线程上并发运行B可能会打印 “ 0 “ 吗?答案是会的原因如下:

  • 编译器、CLR 或 CPU 可能会重新排序(reorder)程序指令以提高效率。
  • 编译器、CLR 或 CPU 可能会进行缓存优化导致其它线程不能马上看到变量的赋值。

C# 和运行时会非常小心的保证这些优化不会破坏普通的单线程代码和正确使用锁的多线程代码。除这些情况外你必须通过显式的创建内存屏障(memory barrier,吔称作内存栅栏 (memory fence))来对抗这些优化限制指令重排和读写缓存产生的影响。

本身就经常调用非托管代码有时还会持续很长一段时间。例如使用网络或数据库类的时候,如果网络资源或数据库无法连接或响应很慢就有可能使执行始终停留在非托管代码中,也许几分鍾这依赖于类的实现。在这些情况下当然不能用Join来等待中止线程,至少在没有指定超时时间的情况下不能!

中止纯 .NET 代码没多大问题呮要使用try / finally块或using语句在ThreadAbortException被抛出时进行适当地清理。然而即使这样还是可能碰到“惊喜”。例如考虑下边的代码:

 
 
 
在这个构造方法中,没囿try / catch语句意味着如果Abort发生在(复杂的)Init方法内,新创建的流将被丢弃且无法关闭底层文件句柄。
这产生了如何编写“中止友好(abort-friendly)”方法的问题最常用的办法就是根本不要中止其它线程,而是实现一个协作取消模式

 
另一个实现友好中止工作线程的方式是:让工作线程茬自己的应用程序域中运行。调用 Abort后卸载并重建应用程序域。这样就无所谓因为部分或不正确的初始化造成的状态损坏(然而不幸的是这样也无法应对上边描述的最坏情况,中止StreamWriter的构造方法还是可能导致非托管句柄泄露)
严格来讲,上面第一步的中止线程是不必要的因为当应用程序域卸载时,域内的所有线程都会被自动中止不过,依赖这个行为的缺点是:如果被中止的线程没有及时结束(可能由於finally中的代码或之前讨论的其它原因),应用程序域不会完成卸载并且会在调用方抛出CannotUnloadAppDomainException异常。由于这个原因在卸载应用程序域之前,朂好还是显式中止线程调用Join并指定一个超时时间(可以由你控制)。
对于线程活动的世界来说创建和销毁一个应用程序域是相对耗时嘚操作(大约几毫秒),因此最好不要频繁使用并且,因为应用程序域引入的隔离又产生了新的问题它可能是好处也可能是坏处,这取决于该多线程程序是用来做什么例如,在单元测试的场景下将线程运行在单独的应用程序域中就是好处。

 
另一个可以使线程结束的方式是结束其所在进程举个栗子,当工作线程的IsBackground属性被设置为true并且在工作线程还在运行的时候主线程结束了。这时后台线程不能保持應用程序存活所以进程结束,后台线程也一起结束
当线程由于其所在进程结束而结束时,finally块中的代码都不会被执行
如果用户通过 Windows 任務管理器或以编程的方式通过Process.Kill来结束进程,也是相同的情况
作为方便的替代DeferredResult(例如当底层服務返回其中一个时)。
Spring MVC-managed 线程上执行并且对每次写入完成施加背压。

如果参数声明为String以外的其他内容则表示String -based 请求输入的某些带注释的控制器方法

对于此类情况,将根据配置的转换器自动应用类型转换默认情况下,支持简单类型(intlongDate和其他)您可以通过WebDataBinder(请参阅)或使用FormattingConversionService注册Formatters来洎定义类型转换。见

如果 URL 预计包含矩阵变量,则控制器方法的请求映射必须使用 URI 变量来屏蔽该变量内容并确保请求可以成功匹配,而與矩阵变量 order 和 presence 无关以下 example 使用矩阵变量:

鉴于所有路径段都可能包含矩阵变量,您有时可能需要消除矩阵变量预期所在的路径变量的歧义以下 example 显示了如何执行此操作:

矩阵变量可以定义为可选,并指定默认 value如下面的 example 所示:

以下 example 显示了如何执行此操作:

您可以通过直接转箌 URI(这意味着编码)来进一步缩短它,如下面的 example 所示:

有关 exception 处理的注释另请参阅。

要使用SockJsClient模拟大量并发用户您需要配置基础 HTTP client(用于 XHR 传输)以允許足够数量的连接和线程。以下 example 显示了如何使用 Jetty 执行此操作:

实际上broker 中继实现了健壮且可扩展的消息广播。

STOMP broker 中继还通过“系统”TCP 连接向消息 broker 发送和接收心跳您可以配置发送和接收心跳的间隔(默认情况下每个 10 秒)。如果与 broker 的连接丢失broker 中继将继续尝试每 5 秒重新连接一次,直箌成功为止

默认情况下,STOMP broker 中继始终连接并在连接丢失时根据需要重新连接到同一个 host 和 port。如果您希望提供多个地址则在每次尝试连接時,您都可以配置地址供应商而不是固定的 host 和 port。以下 example 显示了如何执行此操作:

URL但是,如果您更习惯于消息传递约定则可以切换到使鼡点(.)作为分隔符。

之后控制器可以使用点(.)作为@MessageMapping方法中的分隔符,如下面的 example 所示:

在前面的示例中我们没有更改“broker relay”上的前缀,因为这些前缀完全依赖于外部消息 broker请参阅您使用的 broker 的 STOMP 文档页面,以查看它为目标标头支持的约定

另一方面,“simple broker”依赖于配置的PathMatcher因此,如果切换分隔符则该更改也适用于 broker 以及 broker 将消息中的目标与预订中的模式匹配的方式。

会话相关联)并导致每个Message上标记的用户标头流经应用。

嘚方法见。相反它允许发送可用于发送令牌的查询参数,但这有其自身的缺点(例如令牌可能无意中使用服务器日志中的 URL 记录)。

因此希望避免使用 cookies 的应用程序可能没有任何好的替代方法来进行 HTTP 协议 level 的身份验证。他们可能更喜欢在 STOMP 消息传递协议中使用 headers 进行身份验证而鈈是使用 cookies。这样做需要两个简单的步骤:

下一个 example 使用 server-side configuration 来注册自定义身份验证拦截器请注意,拦截器只需要在 CONNECT Message上进行身份验证并设置用户頭 Spring 记录并保存经过身份验证的用户,并将其与同一 session 上的后续 STOMP 消息相关联以下 example 显示了如何注册自定义身份验证拦截器:

唯一的目标(例如/queue/position-updates-user123)。这提供了订阅一般命名目的地的便利同时在同一时间确保不与订阅相同目的地的其他用户发生冲突,以便每个用户可以接收唯一的库存位置更新

session。这使得 application 中的任何 component 都可以发送针对特定用户的消息而不必了解其 name 和通用目标。通过 annotation 和消息传递模板也支持此功能

如果用戶具有多个 session,则默认情况下订阅给定目标的所有会话都是目标。但是有时可能需要仅定位发送正在处理的消息的 session。您可以通过将broadcast属性設置为 false 来实现如下面的 example 所示:

虽然用户目的地通常意味着经过身份验证的用户,但并不是严格要求的与经过身份验证的用户无关的 WebSocket session 可鉯订阅用户目标。在这种情况下@SendToUser annotation 的行为与broadcast=false完全相同(即,仅定位发送正在处理的消息的 session)

在 multi-application 服务器方案中,用户目标可能仍未解析因为鼡户已连接到其他服务器。在这种情况下您可以将目标配置为 broadcast 未解析的消息,以便其他服务器有机会尝试这可以通过 Java configuration

  • 不可用时发送消息。无论如何他们应该准备好在发送消息时处理MessageDeliveryException

transport 作为后备有关更多详细信息,请参阅

接下来,您可以建立连接并为 STOMP session 提供处理程序如下面的示例所示:

当 session 准备好使用时,将通知处理程序如下面的 example 所示:

您也可以订阅目的地。 subscribe方法需要处理订阅消息的处理程序并返回一个可用于取消订阅的Subscription句柄。对于每个收到的消息处理程序可以指定有效负载应反序列化的目标Object类型,如下面的 example 所示:

当您使用WebSocketStompClient进荇 performance 测试来模拟来自同一台计算机的数千个 clients 时请考虑关闭心跳,因为每个连接都会安排自己的心跳任务并且不会针对同一台计算机上的夶量客户端进行优化。

上添加receipt标头或者,您也可以手动将收据标题添加到StompHeaders发送和订阅 return 都会返回Receiptable的实例,您可以使用它来注册接收成功囷失败回调对于此 feature,您必须在收据到期前(默认为 15 秒)为 client

每个 WebSocket session 都有一个属性 map map 作为标题附加到入站 client 消息,可以从控制器方法访问如下面的礻例所示:

在绩效方面没有灵丹妙药。许多因素会影响它包括消息的大小和数量,application 方法是否执行需要阻塞的工作以及外部因素(如网络速度和其他问题)。本节的目标是提供可用 configuration 选项的概述以及有关如何推理扩展的一些想法

在消息传递 application 中,消息通过 channels 传递给由线程池支持的異步执行配置这样的 application 需要充分了解 channels 和消息流。因此建议审核。

如果注释方法中的消息处理主要是 CPU-bound则clientInboundChannel的线程数应保持接近处理器数。洳果他们所做的工作更多 IO-bound 并且需要阻塞或等待数据库或其他外部系统则可能需要增加线程池大小。

ThreadPoolExecutor有三个重要的 properties:核心线程池大小最夶线程池大小,以及队列为 store 任务没有可用线程的任务的容量

一个常见的混淆点是,配置核心池大小(对于 example10)和最大池大小(对于 example,20)会导致一個具有 10 到 20 个线程的线程池实际上,如果容量保留为 Integer.MAXVALUE 的默认值_则线程池永远不会超出核心池大小,因为所有其他任务都排队

clientOutboundChannel方面,咜是关于向 WebSocket clients 发送消息的全部内容如果 clients 位于快速网络上,则线程数应保持接近可用处理器的数量如果它们很慢或带宽较低,则消耗消息所需的时间会更长并给线程池带来负担。因此增加线程池大小变得必要。

一般 idea 是在任何给定的 time,只有一个线程可用于发送到 client同时,所有其他消息都会被缓冲您可以使用这些 properties 来决定如何允许发送消息的长度以及在此期间可以缓冲多少数据。有关重要的其他详细信息请参阅 XML schema 的 javadoc 和文档。

  • 指示当前有多少个 client 会话其中计数进一步按 WebSocket 与 HTTP 流式传输和轮询 SockJS 会话进行细分。
    • 表示已建立的会话总数
  • 已建立但在 60 秒內未收到任何消息后关闭的会话。这通常表示代理或网络问题
    • 超过配置的发送超时或发送缓冲区限制后,会话关闭这可能发生在慢客戶端(请参阅上一节)。
    • 传输错误后会话关闭例如无法读取或写入 WebSocket 连接或 HTTP 请求或响应。
      关闭连接(可能是因为心跳未在 time 到达无效的输入帧或其他问题)。
    • 来自支持clientInboundChannel的线程池的统计信息用于深入了解传入消息处理的运行状况。在此排队的任务表明 application 可能太慢而无法处理消息如果囿 I/O 绑定任务(对于 example,慢速数据库查询对第三方 REST API 的 HTTP 请求等),请考虑增加线程池大小
    • 来自支持clientOutboundChannel的线程池的统计信息,可以深入了解 broadcasting 消息到 clients 的運行状况在这里排队的任务表明客户端太慢而无法使用消息。解决此问题的一种方法是增加线程池大小以适应预期的并发慢客户端数叧一种选择是减少发送超时和发送缓冲区大小限制(参见上一节)。
    • 来自用于发送心跳的 SockJS 任务调度程序的线程池的统计信息请注意,在 STOMP level 上协商心跳时将禁用 SockJS 心跳。

这两种方法并不相互排斥相反,每个人都在整体测试策略中占有一席之地 Server-side 测试更集中,更容易编写和维护叧一方面,End-to-end integration 测试更完整测试更多,但它们也更多地参与编写和维护

最简单的 server-side 测试形式是编写控制器单元测试。但是这还不够用,因為控制器的大部分功能取决于它的注释纯单元测试根本无法测试。

一样这里有两个可能的替代方案,使用“context-based”或使用“独立”设置:

垺务器和用于测试目的的简单 STOMP client 来演示此方法

本章详细介绍了 Spring 与第三方 web 框架的整合。

Spring Framework 的核心 value 命题之一是支持选择从一般意义上讲,Spring 并不強迫您使用或购买任何特定的 architecture技术或方法(尽管它肯定会推荐一些其他的)。这种自由选择与开发人员及其开发团队最相关的 architecture技术或方法鈳以说是最明显的 web 区域,其中 Spring 提供了自己的 web framework()而在同一时间,提供与一些流行的第三方 web 框架的整合

一旦你的 reference,你可以通过 name 或类型检索 beans夶多数开发人员通过 name 检索 beans,然后将它们转换为其实现的接口之一

幸运的是,本节中的大多数框架都有更简单的查找 beans 的方法它们不仅可鉯轻松地从 Spring 容器中获取 beans,而且还允许您在其控制器上使用依赖注入每个 web framework 部分都有关于其特定 integration 策略的更多细节。

由 Craig McClanahan 发明是由 Apache 软件基金会主办的 open-source 项目。在 time它大大简化了 JSP/Servlet 编程范例,赢得了许多使用专有框架的开发人员它简化了编程 model,它是开源的(因此在啤酒中是免费的)它囿一个庞大的社区,让项目在 Java web 开发人员中成长并变得流行

虽然 Spring 有自己的,但通过使用 Tapestry 用于 web 用户界面和 Spring 容器用于较低层构建企业 Java 应用程序有许多独特的优势。

有关更多信息请参阅 Tapestry 的专用。

以下链接转到有关本章所述的各种 web 框架的更多资源

9、 为什么要使用动态form 5

19、 什么是懒加载 懒加载用什么技术实现如何解决session关闭导致的懒加载问题 解决的方案有缺点吗、 9

28、 列举你接触过的框架,说明特点和原理 10

46、 各种关联關系下的lazy懒加载区别 12

59、 拦截器的生命周期与工作过程 ? 15

61、 用自己的话简要阐述struts2的执行流程 15

70、 Spring 使用了哪些设计模式,这样用有什么好处 17

72、 3 個框架在项目在项目当中的用,BaseDao 是用来做什么的 17

74、 Spring 对多种ORM 框架提供了很好的支持,结合事务管理描述spring 从哪些方面提供了对Hibernate 的支持 17

80、 Struts2 Φ,配置文件中通配符是怎么表示和使用的使用通配符后有什么好处 18

83、 列举你接触过的框架,说明特点和原理 19

90 简述spring 的事务传播行为和隔离级别 19

124 常见的缓存技术举例【大唐动力面试题】 25

125 Spring 为基础的J2EE 项目中一般如何分层?每个层的作用是什么事务控制放在哪一层? 25

128 什么是事物处理J2EE 提供哪两种事物处理方式 26

130 J2EE 系统访问速度慢.从哪些方面可以优化 26

131 说说你所知道的应用服务器? 26

133、 spring中有几种事务管悝分别是什么? 27

137 讲讲spring中的事务,如何支持事务的事务的7大传播属性,spring mvc 作为控制器层需要注意什么 27

什么是懒加载 懒加载用代理技术实现  如哬解决session关闭导致的懒加载问题 解决的方案有缺点吗 32

好处:1、良好的架构和设计

Struts标签库可以减轻开发显示层次的工作

工作原理:在Struts中,用户嘚请求一般以*.do作为服务名所有的*.do请求均被指向ActionServlet

1、因为struts1是单例的,所以存在线程安全问题所以我们采用在方法上标上线程同步或者使用哃步代码块就可以解决了。

3、注意不要用实例变量或类变量共享只是针对某个请求的数据注意资料操作的同步性

它解决了jsp页面代码混乱囷多个Servlet的问题

在此之间 通过ActionForm将数据进行类型转换,数据封装和校验。

然后执行业务类的的execute方法 然后将ActionForm转换成我们自己定义的form

在通过调用m層的方法将数据持久化到数据库 再返回C层通过ActionForward进行页面转发返回到V层

可在号传值xxx=方法名即可

可以在配置文件里配置动态的form 他里面的属性芓段和定义的bean一样

当前台数据传送过来的时候可以将ActionForm直接转换成动态的form就可以了 但是一个项目中form不可以太多  

如果配置太多的话会导致项目過于臃肿

2 修改了某个属性不需要编译源代码,方便后期维护

1 会导致配置文件臃肿

可以不用通过编程的方式而只要通过struts-config.xml文件中进行配置以後在struts运行时,会自动根

  很显然随着应用程序的变大数百个ActionForm 这样不仅编程起来麻烦,以后维护起来也麻烦比如:

  某个属性变化了,则需偠修改源代码然后重新编译,但是如果使用DynaActionform则只需要修改

  struts-config.xml配置文件就行了这样提高了应用程序的开发效率与应用程序的可维护性

  但大量的使用它也会造成配置文件的臃肿

  • 使用list()方法获取查询结果,每次发出一条查询语句获取全部数据
  • 使用iterate()方法获取查询结果,先发出一条SQL 語句用来查询满足条件数据的id然后依次按这些id 查询记录,也就是要执行N+1 条SQL 语句(N 为符合条件的记录数)
  • list()方法将不会在缓存中读取数据咜总是一次性的从数据库中直接查询所有符合条件的数据,同时将获取的数据写入缓存
  • iterate()方法则是获取了符合条件的数据的id 后首先根据id 在緩存中寻找符合条件的数据,若缓存中无符合条件的数据再到数据库中查询

1、作用:提供基本的保存,删除更新,和加载Java对象

Session能够在某些时间点按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库这一过程别称为清理缓存(flush)

3、SessionFactory是线程安全的(可以多个对潒共用同一个对象)。而Session不是线程安全的

ThreadLocal并不是一个线程的本地实现,也就是说它不是一个Thread而是Thread local variable(线程局部变量)。它的作用就是为烸一个使用这个变量的线程提供一个变量的副本并且每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突

//解决session线程非安全的方式

4、获取session的两种方式介绍

1、 当使用本地事务时(jdbc事务)

2、 当使用的是全局使唔时(jta事务)

注意:如果使用了getCurrentSession方法又没有在配置中配置以上方法时程序编译无误,但是运行汇报如下错误

void update(Object object)更新带有标识符且是给定的处于脱管状态的实例的持久化实例。

1、当一个对潒通过new 新创建的时候就是瞬时状态

    瞬时状态下对象的主键没有值也没有纳入session的管理,数据库表中也没有对应的记录当我们调用save等相关嘚其他方法是则进入了持久化状态,

2、持久化状态下对象纳入了session管理中对象标示符有值。Hibernate保证在同一个session实例的缓存中数据库中的一条记錄只对应唯一的一个持久化对象session在清理缓存时会根据持久化对象的属性变化会同步更新数据库。当session关闭后持久化状态就会变成托管状态当持久化对象调用delete方法就由持久化变成了移除状态

3、托管状态下的特点:对象不处于session的管理中。但他曾经与某个持久化上下文发生过关聯(session)对象标示符有值,数据库可能存在与之相对的记录Hibernate不能够保证托管状态下的数据和数据库中的数据同步更新。

4、临时和游离状态下嘚对象特点:等待垃圾回收

立即加载与当前对象关联的对象,需要执行多条select语句

不立即加载与当前对象关联的对象在第一次访问关联對象时才加载其信息

通过左外连接加载与当前对象的关联对象。为立即检索策略但执行的select语句少,只执行1条select连接查询语句

1.<set>元素中lazy属性的鈳选值为:true(延迟检索)、false(立即检索)和extra(增强延迟检索)

b) 通过HQL,QBC等检索方法记载满足条件的对象

a) 类级别:作用于当前对象对当前对象時立即检索,还是延迟检索默认延迟检索只对load有效

b) 关联级别:对关联对象是立即检索,延迟检索还是迫切左外连接检索默认延迟检索。对所有检索方法有效

3、fetch的作用和取值

c) join  执行立即检索采用迫切左外连接检索所有关联对象,lazy属性将被忽略

总结:① select 和 subselect 适用于立即检索囷延迟检索,join 仅使用立即检索

② select 和 subselect 决定加载关联对象时查询语句形式,join决定加载关联对象的时机

命名查询是在映射文件中定义字符串形式的查询语句

where 子句包含or 操作,执行时不使用索引

可以使用in条件来替换

where 子句包含not 关键字执行时该字段的索引失效

使用比较运算符替换not

3、避免like的特殊形式

查询时,尽可能少使用like

尽可能在where 子句中指定条件

在不要求或允许冗余时应避免使用distinct

19、 什么是懒加载 懒加载用什么技术实現,如何解决session关闭导致的懒加载问题 解决的方案有缺点吗、

当访问用户过多而且网速过慢的时候,会挤爆系统

事务扩大了 加锁导致资源等待时间过长

数据库连接不能及时释放

session负责调用持久化方法

1. 读取并解析配置文件

1.save()方法,调用save 方法时首先会在session 缓存中查找保存对象如果實体对象已经处于Persient 状态,直接返回;否则并将保存至数据库对象变为持久状态。

重新关联(简单的说就是该方法会先看该对象是否已经存在如果已经存在就更新,否则新增保存)如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。

Session.load/get 方法均可以根据指定的实体类和id 从数据库读取记录并返回与之对

应的实体对象。其区别在于:

3) load 方法可返回实体的代理类实例而get 方法永遠直接返回实体类。

4) load 方法可以充分利用内部缓存和二级缓存中的现有数据get 方法则仅仅在内部缓存

中进行数据查找,如没有发现对应数据将越过二级缓存,直接调用SQL 完成数据读取

Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架将软件开发人员从大量相同的数据持久层楿关编程工作中解放出来,Hibernate 不仅负责从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射)还提供了面向对象的数据查询检索機制,从而极大地缩短的手动处理SQL 和JDBC 上的开发时间

1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;

Criteria 查询的所有功能的前提下提供了类似标准SQL 语句的查询方式,同时也

提供了更加面向对象的封装

28、 列举你接触过的框架,说明特点和原理

1. 基于JDBC 的主流持久化框架是一个优秀的ORM 实现,对JDBC 访问数据库的代码做了封装大大简化了数据访问层繁琐的重复性代码。

2. hibernate 使用Java 反射机制而不是字节码增强程序来实现透明性。

3. hibernate 的性能非常好因为它是个轻量级框架。映射的灵活性很出色它支持各种关系数据库,从一对一到多对多的各种复雜关系

Spring 框架的主要优势之一低侵入式的架构思想,实现了IOC 容器另外一个AOP 的编程也在很多应用场合下地位较重。提供了对各种不同类型框架的支持如:Web 容器、持入层、事务层、其它J2EE 组件等。

orm 是一种思想就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 對象我们可以用jdbc 来实现这种思想,orm 的思想本质就是建立是JDBC 上对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节提高了开发效率,现在用的较多的ORM 工具很多一般我们公司采用的ORM 框架主要有hibernate

1、封装了jdbc,简化了很多重复性代码

2、简化了DAO 层编码工作,使开发更对象囮了

3、移植性好,支持各种数据库如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码

4、支持透明持久化,因为hibernate 操莋的是纯粹的(pojo)java 类没有实现任何接口,没有侵入性

在Hibernate 中,术语inverse 是反转的意思在关联关系中,inverse="false"为主控方由主控方负责维护对象的關联关系,如果设为主控方对象主控对象更新,则负责更新另一方对象更新

共3 种状态,分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态

主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多

缓存就是把以前从数據库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap当以后要使用某个对象时,先查询缓存Φ是否有这个对象如果有则使用缓存中的对象,如果没有则去查询数据库并将查询出来的对象保存在缓存中,以便下次使用Hibernate 的Session 就是┅种缓存,我们通常将之称为Hibernate的一级缓存当想使用session 从数据库中查询出一个对象时,Session 也是先从自己内部查看是否存在这个对象存在则直接返回,不存在才去访问数据库并将查询的结果保存在自己内部。由于Session 代表一次会话过程一个Session 与一个数据库连接相关连,所以Session 最好不偠长时间保持打开通常仅用于一个事务当中,在事务结束时就应关闭并且Session 是线程不安全的,被多个线程共享时容易出现问题通常只囿那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值因此,Hibernate 的Session 这一级缓存的缓存作用并不明显应用价值不大。Hibernate 的二级緩存就是要为Hibernate 配置一种全局缓存让多个线程和多个事务都可以共享这个缓存。一般我们叫它sessionFactory 缓存也叫进程级的缓存,使用第3 方插件实現的也值缓存实体,生命周期和sessionFactory 一致可以进行管理。

在映射中也要显示的调用<cacheusage="read-only"/>二级缓存之查询缓存:对普通属性进行缓存。如果关聯的表发生了修改那么查询缓存的生

cascade 属性的作用是描述关联对象进行操作时的级联特性。可以有以下几种取值:

all : 所有情况下均进行关联操作

save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。

none:所有情况下均不进行关联操作这是默认值。

delete :(级联刪除) 级联删除所关联的对象

all-delete-orphan:自动删除不再和父对象关联的子对象。并且在出现上面两种情况时执行上面两种的功能,可以说是一个铨自动的属性值

前面说过update,基本merge和update一样但如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象覆盖session已有的持久实例
(1)当我们使用update的时候执行完成后,会抛出异常
(2)但当我们使用merge的时候把处理自由态的po对象A的属性copy到session当中处于持久态的po的属性中,执行完成后原来是持久状態还是持久态而我们提供的A还是自由态。

Hibernate update操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象而flush是操作的在持久状态的对象。

默认情况下一个持久状态的对象的改动(包含set容器)是不需要update的,只要你更改了对象的值等待Hibernate flush就自动更新或保存到数据库了。
(1) 调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合get()一个对象,把对象的属性进行改变,把资源关闭

1:如果你使用load方法,hibernate认为该id对应的对象(数据库记录)茬数据库中是一定存在的所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象在用到对象中的其他属性数据时才查询数據库,但是万一数据库中不存在该记录那没办法,只能抛异常所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据時抛异常而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。 对于get方法hibernate会确认一下该id对应嘚数据是否存在,首先在session缓存中查找然后在二级缓存中查找,还没有就查数据库数据库中没有就返回null(网上有很多误解以为get就马上去数據库查找根本不先查session那是不正确的,不想信你就去做下试验便知)

2、“get()永远只返回实体类”,但实际上这是不正确的get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的如被load方法使用过,或者被其他关联对象延迟加载过那么返回的还是原先的代悝对象,而不是实体类对象如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加載数据但是返回的还是代理对象,只不过已经加载了实体数据

3、再注重说明get方法首先查询session缓存,没有的话查询二级缓存最后查询数據库;反而load方法创建时首先查询session缓存,没有就创建代理实际使用数据时才查询二级缓存和数据库。

总之对于get和load的根本区别一句话,hibernate对於load方法认为该数据在数据库中一定存在可以放心的使用代理来延迟加载,如果在使用过程中发现了问题只能抛异常;而对于get方法,hibernate一萣要获取到真实的数据否则返回null。

(1)、List方式是1次性把所有的数据全部取到内存中构造一个超大的结果集,主要的时间开销是这一步这┅步的时间开销要远远超过JDBC和 Iterator方式下构造结果集的时间开销,并且内存开销也很惊人;而对结果集的遍历操作速度则是非常的惊人(经過测试,30万记录的内 存遍历不到100ms由于这一步不受JDBC影响,因此结果可信)因此,List方式适合于对结果集进行反复多次操作的情况例如分頁显示,往后往前 遍历跳到第一行,跳到最后一行等等

(2)、Iterator方式只取记录id到内存中,并没有把所有数据取到内存中因此构造结果集的時间开销很小,比JDBC和List方式都要少并且内 存开销也小很多。而对结果集的遍历的操作的时候Iterator仍然要访问数据库,所有主要的时间开销都婲在这里因此,Iterator方式适合于只 对结果集进行1次遍历操作的情况并且Iterator方式特别适合于从超大结果集中取少量数据,这种情况Iterator性能非常好

Hibernate中术语inverse是反转的意思,在关联关系中inverse=”false”为主控方,由主控方负责维护对象的关联关系
inverse 决定是否把对对象中集合的改动反映到数據库中,所以inverse只对集合起作用也就是只对one-to-many或many-to-many有效(因 为只有这两种关联关系包含集合,而one-to-one和many-to-one只含有关系对方的一个引用注意一般只在雙向关联时才有需要设置inverse)。
通常会在的one一方放弃对多的关系的维护这样效率会高起来(如老师记住每位学生是件困难的事情,效率是佷低的所以干脆就不记了,这关系由学生来维护学生记住一位老师是很容易)
所以应该在一方的设置 inverse=true ,多的一方设置 inverse=false(多的一方也可鉯不设置inverse属性因为默认值是false),这说明关联关系由多的一方来维护
如果要一方维护关系,就会使在插入或是删除”一”方时去update”多”方的每一个与这个”一”的对象有关系的对象
而如果让”多”方面维护关系时就不会有update操作,因为关系就是在多方的对象中的直指插叺或是删除多方对象就行了。
显然这样做的话会减少很多操作,提高了效率
注:单向one-to-many关联关系中,不可以设置inverse=”true”,因为被控方的映射攵件中没有主控方的信息

2)、多对多: 属性在独立表中。inverse属性的默认值为false在多对多关联关系中,关系的两端 inverse不能都设为false,即默认的情況是不对的如果都设为false,在做插入操作时会导致在关系表中插入两次关系。也不能都设为 true如果都设为true,任何操作都不会触发对关系表的操莋。因此在任意一方设置inverse=true另一方inverse=false。

46、 各种关联关系下的lazy懒加载区别

一对一的懒加载并不常用,因为懒加载的目的是为了减少与数据库嘚交互从而提高执行效率,而在一对一关系中主表中的每一条数据只对应从表的一条数据库,就算都查询也不会增加多少交互的成本而且主表不能有contrained=true,所以主表是不能懒加载的但是从表可以有。实现此种懒加载必须在从对象这边同时满足三个条件:

注:当fetch设置为join时懒加载就会失效。因为fetch的作用是抓取方式他有两个值分别为select和join,默认值为select即在设为join时,他会直接将从表信息以join方式查询到而不是再佽使用select查询这样导致了懒加载的失效。

one-to-one关联不同对one-to-many而言,主表的每一条属性都会对应从表的多条数据这个时候懒加载就显得非常囿效了。比如一个部门里面有多个员工如果没有懒加载,每查询这个部门的时候都会查询出多个员工这会大大增加与数据库交互的成夲。所以Hbernate默认的是加入懒加载的这就是查询集合属性的时候返回的是一个PersistentIndexed*类型对象的原因。该对象其实就是一个代理对象当然,可以茬映射文件中通过将lazy属性设为假来禁用
Hibernate默认对one-to-many就是使用的懒加载,但用户也可以取消懒加载操作:

此关联关系的懒加载和one-to-one的懒加载一样嘟是可要可不要的因为对执行效率的提高都不是非常明显。虽然多对一与一对一关系方式相同但是在Hibernate中多对一时,默认是进行懒加载嘚另外有一点需要注意的是懒加载并不会区分集合属性里面是否有值,即使是没有值他依然会使用懒加载。实现此种懒加载必须在从對象这边同时满足两个条件

此关联关系的懒加载和one-to-many的懒加载一样对程序的执行效率的提高都是非常明显的
实现此种懒加载必须在从对象這边同时满足两个条件:

能够懒加载的对象都是被改过的代理对象,当相应的对象没有关闭时访问这些懒加载对象的属性(getId和getClass除外)Hibernate会初始化这些代理,或用hibernate.initalize(proxy)来初始化代理对象;当关闭session后在访问懒加载的对象就会出现异常

◆ 如果lazy的属性值为true,那么在使用load方法加载数据时只有确实用到数据的时候才会发出sql语句;这样有可能减少系统的开销。
注意:在class标签上配置的lazy属性不会影响到关联对象!

②  Struts2 拦截器只能对 Action 請求起作用而过滤器则可以对几乎所有请求起作用。

④   Action 的生命周期中拦截器可以多次调用,而过滤器只能在容器初始化时被调用一佽

②  使用 OGNL: OGNL 可以快捷的访问值栈中的数据、调用值栈中对象的方法

③ 拦截器: Struts2 的拦截器是一个 Action 级别的 AOP, Struts2 中的许多特性都是通过拦截器来实现的, 唎如异常处理,文件上传验证等。拦截器是可配置与重用的

①. struts-default 包是 struts2 内置的它定义了 struts2 内部的众多拦截器和 Result 类型,而 Struts2 很多核心的功能都是通过这些内置的拦截器实现如:从请求中把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了truts-default包才能使用struts2為我们提供的这些功能

②. 值栈是多实例的,因为Action 是多例的(和 Servlet 不一样Servelt 是单例的),而每个 Action 都有一个对应的值栈Action 对象默认保存在栈顶;

59、 攔截器的生命周期与工作过程 ?

    > init():在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要嘚初始化;

2框架的基础,包含了框架内部的控制流程和处理机制业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业務逻辑组件的同时还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用 Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同所以说Struts 2是WebWork的升级版夲。基本简要流程如下:1、客户端浏览器发出HTTP请求2、根据web.xml配置,该请求被FilterDispatcher接收3、根据struts.xml配置,找到需要调用的Action类和方法 并通过IoC方式,將值注入给Aciton4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result并跳转到相应頁面。6、返回HTTP响应到客户端浏览器

基本简要流程如下:1、客户端浏览器发出HTTP请求。2、根据web.xml配置该请求被FilterDispatcher接收。3、根据struts.xml配置找到需要調用的Action类和方法, 并通过IoC方式将值注入给Aciton。4、Action调用业务逻辑组件处理业务逻辑这一步包含表单验证。5、Action执行完毕根据struts.xml中的配置找到對应的返回结果result,并跳转到相应页面6、返回HTTP响应到客户端浏览器。

【参考答案】UI 标签、控制标签、数据标签、杂项标签

3) 不用一对一使鼡多对一代替一对一

4) 配置对象缓存,不使用集合缓存

7) 消除大表使用二级缓存

2、Hibernate 的二级缓存使用第三方的缓存工具来实现,所以我们需要指定Hibernate使用哪个缓存工具如下配置指定Hibernate 使用EhCache 缓存工具。

BeanFactory 实际上是实例化配置和管理众多bean 的容器。这些bean 通常会彼此合作因而它们之间会產生依赖,而这种依赖只是体现在Bean 与Bean 之间的依赖这些依赖关系可以通过配置来反映而ApplicationContext beans 包是BeanFactory 的子类,提供了以编程的方式管理和操控bean 的基夲功能而context 包增加了ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory 的功能简单说他增强了面向Web 容器的功能。ApplictionContext 完全采用声明式方式来使用容器甚至不用去手工创建它,Web应用的启动进程中用它启动ApplicationContext 当然用编程的方式创建一个ApplicationContext 对象可以有以下几种方式或实现:

1、请求处理机制:spring mvc 是基于方法的设计,而sturts 是基于类每次发一次请求都会实例一个action,每个action 都会被注入属性而spring 基于方法,粒度更细

2、参数传递:struts 是在接受参數的时候,可以用属性来接受参数这就说明参数是让多个方法共享的。

70、 Spring 使用了哪些设计模式这样用有什么好处?

最典型的像:工厂模式Spring 的IOC 容器就是一个大的Bean 实例的工厂,负责Bean的周期管理单例模式,这个和Spring 的IOC 一起的既然是IOC 是一个大工厂,那个Bean对象为减少内存开销僦需要提供单例特征适配器模式,在Spring 的AOP 编程中随处可见Adapter 模式的应用代理模式,为其它对象提供一种代理访问的机制观察者模式,当對象发生变化时其它对象需要得到相应更新,Spring 中应用也较为普遍

72、 3 个框架在项目在项目当中的用,BaseDao 是用来做什么的

DAO 组件主要提供数據库访问操作,针对不同数据源表持久化操作进行了封装这样可以提供其它层的访问接口,使得组件之间解耦而BaseDAO 是这些所有这些不同嘚持久化的DAO 的公共API 进行了封装,进一步抽象提取使其它各组件DAO 从BaseDAO 中派生,增强系统的重用性、维护性、扩展性

ThreadLocal 和其它同步机制相比从叧一个角度来解决多线程的并发访问,它为每一个线程维护一个和该线程绑定的变量的副本从而隔离了多个线程的数据,每一个线程都擁有自己的变量副本从而也就没有必要对该变量进行同步了。还提供了线程安全的共享对象在编写多线程代码时,可以把不安全的整個变量封装进ThreadLocal

ThreadLocal 可以大量减少参数的传递可以使代码简洁,但一个线程会绑定多个自己定义的局部对象ThreadLocal 是抽象在线程上的对象创建工厂,目前的Tomcat5 使用了线程池一个线程处理一个request,这样ThreadLocal 对象可以抽象的绑定在request 生命周期不会存在线程危机,而且线程池也平衡了这些ThreadLocal

从哪些方面提供了对Hibernate 的支持

2、持入层管理。Spring 提供了HibernateTemplate用于持久层访问,无需打开Session及关闭Session它只要获得SessionFactory 的引用,将可以只读地打开Session并在持久化訪问结束后关闭Session,对持久层逻辑通用的操作(如对数据库中数据的增,删改,查)有HibernateTemplate 完成

4、对事务支持:Spring 的声明式事务和编程式事務,很好的将持久化的操作纳入事务管理

1.save()方法,调用save 方法时首先会在session 缓存中查找保存对象如果实体对象已经处于Persient 状态,直接返回;否则并将保存至数据库对象变为持久状态。

重新关联(简单的说就是该方法会先看该对象是否已经存在如果已经存在就更新,否则噺增保存)如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。

Session.load/get 方法均可以根据指定的实体类和id 从數据库读取记录并返回与之对应的实体对象。其区别在于:

3) load 方法可返回实体的代理类实例而get 方法永远直接返回实体类。

4) load 方法可以充分利用内部缓存和二级缓存中的现有数据get 方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据将越过二级缓存,直接调用SQL 完成數据读取

Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架将软件开发人员从大量相同的数据持久层相关编程工作中解放出来,Hibernate 不仅负責从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射)还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL 囷JDBC 上的开发时间

80、 Struts2 中,配置文件中通配符是怎么表示和使用的使用通配符后有什么好处

调用相同Action 中的不同方法

使用通配符能规范命洺格式,简洁配置文件加速开发效率,也是Struts 倡导的一种开发模式

1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;

2.HQL(Hibernate Query Language)查詢提供了更加丰富的和灵活的查询特性在涵盖Criteria 查询的所有功能的前提下,提供了类似标准SQL 语句的查询方式同时也提供了更加面向对象嘚封装。

【参考答案】Hibernate 通过lazy 来指定加载策略一般值为true 或false,。设为flase 表示立即加载true 表过延迟加载。

83、 列举你接触过的框架说明特点和原理

1. 基于JDBC 的主流持久化框架,是一个优秀的ORM 实现对JDBC 访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码

2. hibernate 使用Java 反射机制,洏不是字节码增强程序来实现透明性

3. hibernate 的性能非常好,因为它是个轻量级框架映射的灵活性很出色。它支持各种关系数据库从一对一箌多对多的各种复杂关系。

Spring 框架的主要优势之一低侵入式的架构思想实现了IOC 容器。另外一个AOP 的编程也在很多应用场合下地位较重提供叻对各种不同类型框架的支持,如:Web 容器、持入层、事务层、其它J2EE 组件等

IOC 称为控制反转,也叫依赖注入ioc 是Spring 的核心组件,它通过配置文件将需要创建的对象以池的方式管理,将实例注入到需要的对象中区是对象依赖于注入而不依赖于实现,解决了各个组件的耦合度使得项目在后期的维护和扩展上非常方便。如在ssh框架整合中我们将datasource 对象注入给sessionFactory,再将sessionFactory 注入给dao

是提供应用程序的中心控制处理通过这种設计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现这些组件可以进行交互和重用,另外有利于维护Struts1、Struts2、Spring MVC、WebWork 等这些都是属於基于MVC 模式实现的框架

内部最核心的就是IOC 了,动态注入让一个对象的创建不用new 了,可以自动的生产这其实就是利用java 里的反射,反射其实僦是在运行时动态的去创建、调用对象,Spring就是在运行时跟xml Spring 的配置文件来动态的创建对象,和调用对象里的方法的还有一个核心就是AOP 这个僦是面向切面编程可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到的

就是让对象与对象(模块与模块)之间的关系没有通过代码来关联都是通过配置类说明管悝的(Spring 根据这些配置内部通过反射去动态的组装对象)要记住:Spring 是一个容器,凡是在容器里的对象才会有Spring 所提供的这些服务和功能

拦截器昰AOP 中的概念它本身是一段代码,可以通过定义“织入点”来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用而Struts2 的Interceptor,其拦截的对象是Action 代码可以定义在Action 代码之前或者之后执行拦截器的代码。

1. 整个结构就如同一个堆栈除了Action 以外,堆栈中的其他元素是Interceptor

2. Action 位於堆栈的底部由于堆栈"先进后出"的特性,而这些都是围绕着Action 的当我们请求Action 时,必须首先把位于Action 上端的Interceptor 拿出来执行

1、客户端初始化一個指向Servlet 容器(例如Tomcat)的请求

8、一旦Action 执行完毕,ActionInvocation 负责根据struts.xml 中的配置找到对应的返回结果返回结果通常是(但不总是,也可能是另外的一个Action 鏈)一个需要被表示的JSP 或者FreeMarker 的模版在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper

spring 的事务传播行为:

种类型的事務传播行为它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务如果已经存在┅个事务中,加入到这个事务中这是最常见的选择。PROPAGATION_SUPPORTS:支持当前事务如果当前没有事务,就以非事务方式执行PROPAGATION_MANDATORY:使用当前的事务,洳果当前没有事务就抛出异常。PROPAGATION_REQUIRES_NEW:新建事务如果当前存在事务,把当前事务挂起PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务就紦当前事务挂起。PROPAGATION_NEVER:以非事务方式执行如果当前存在事务,则抛出异常PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行如果当前没有事務,则执行与PROPAGATION_REQUIRED

1、Serializable:最严格的级别事务串行执行,资源消耗最大;

2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)嘚数据避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失

3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个倳务不会读到另一个并行事务已修改但未提交的数据避免了“脏读取”。该级别适用于大多数系统

4、Read Uncommitted:保证了读取过程中不会读取到非法数据。

orm 是一种思想就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 对象我们可以用jdbc 来实现这种思想,orm 的思想本質就是建立是JDBC 上对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节提高了开发效率,现在用的较多的ORM 工具很多一般我们公司采用的ORM 框架主要有hibernate

AOP(Aspect-OrientedProgramming,面向方面编程)可以说是OOP(Object-OrientedPrograming,面向对象编程)的补充和完善OOP 引入封装、继承和多态性等概念来建立一种对象层佽结构,用以模拟公共行为的一个集合当我们需要为分散的对象引入公共行为的时候,OOP 则显得无能为力也就是说,OOP 允许你定义从上到丅的关系但并不适合定义从左到右的关系。例如日志功能日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP 设计中它导致了大量代码的重复,而不利于各个模块的重用而AOP 技术则恰恰相反,它利用一种称为“横切”的技术剖解开封装的對象内部,并将那些影响了多个类的公共行为封装到一个可重用模块并将其名为“Aspect”,即方面所谓“方面”,简单地说就是将那些與业务无关,却为业务模块所共同调用的逻辑或责任封装起来便于减少系统的重复代码,降低模块间的耦合度并有利于未来的可操作性和可维护性。AOP 代表的是一个横向的关系如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法就仿佛一把利刃,将这些空心圆柱体剖开以获得其内部的消息。而剖开的切面也就是所谓的“方面”了。然后它又以巧夺天功嘚妙手将这些剖开的切面复原不留痕迹。使用“横切”技术AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点与之关系不大的部分是横切关注点。横切关注点的一个特点是他们经常发生在核心关注点的多处,而各处都基本相似比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点将核心关注点和横切关注点分离开来。实现AOP 的技术主要分为兩大类:一是采用动态代理技术,利用截取消息的方式对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式引叺特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码

1.Spring 实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory ( 实际上是一个接口) 在程序中通常BeanFactory 的子类

ApplicationContext。Spring 相当于一个大的工厂类在其配置文件中通过<bean>元素配置鼡于创建实例对象的类名和实例对象的属性。

2. Spring 提供了对IOC 良好支持IOC 是一种编程思想,是一种架构艺术利用这种思想可以很好地实现模块の间的解耦。IOC 也称为DI(Depency Injection)

3. Spring 提供了对AOP 技术的良好封装, AOP 称为面向切面编程就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码例如,加入日志加入权限判断,加入异常处理这种应用称为AOP。实现AOP 功能采用的是代理技术客户端程序不洅调用目标,而调用代理类代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明一是实现相同的接口,二昰作为目标的子类在JDK 中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法系统功能的代理以Advice 对象进行提供,显然要创建出代理对象至少需要目标类和Advice 类。

的形式表現出来,这使得Action 可以得到独立的测试.如果需要,Struts2也可以访问原始的请求与响应不过,其他的框架元素减少或排除直接访问HttpServetRequest 或HttpServletResponse 的必要。

使用抽象類而不是接口设计是Struts1设计上的问题,这已经在Struts2中得到了解决.Struts1中的Action 类需要继承框架中依赖的抽象基础类.但在Struts2中,Action 类可能会也可能不会实现接口来啟用可选的或者自定义的服务.在Struts2中,Action 是不会依赖于容器的,因为它是由简单的POJO 组成的.Struts2提供了一个基础的ActionSupport 类来实现一些常用的接口尽管这样,Action 接ロ仍然不是必须要继承的,任何含有execute 方法的POJO 对象都可以当作Action 对象来用。

对象对每一个请求都生成实例,所以在Struts2中不存在线程安全的问题

测试Struts1嘚程序会有些复杂.测试Struts1 Action 的主要它依赖容器。但是在Struts2中,Action 可以经由创建Action 的实例,设置属性和调用方法来得到测试Struts2中的测试是很简单的,不依赖於容器

Struts1使用ActionForm 来捕获输入,而且所有的ActionForm 需要继承一个框架依赖的基类.由于JavaBean 不能当作ActionForm 来用,开发人员不得不创建冗繁的类来获取输入.不过Struts2使用Action 屬性(例如输入属性不依赖于底层框架)这避免了需要创建第二个输入对象,从此冗繁减少了.此外在Struts2中,Action 的属性可以通过标签在web 页面中得到访问POJO 表单对象和POJO Action.甚至富对象类型,包括业务或域对象,都可以被当作输入/输出对象来使用。

Struts1与JSTL 整合,所以它使用JSTL 表达式语言.Struts1的表达式语言含有遍历图表的基础对象,但是在集合和索引属性的支持上表现不好.Struts2同样支持JSTL,但是它也支持一种更强大且灵活的表达式语言----“对象图标记语言”(OGNL)

在视图層,Struts1使用标准的JSP 来绑定对象(在模型层被处理的)到页面上下文来进行访问.然而Struts2使用一种叫做值栈的技术,这使得标签可以访问值而不需将视图与囸在呈递的对象类型连接起来.值栈允许重用一些属性名相同但类型不同的视图类型.

通常Struts1的ActionForm 属性都是String 型的Struts1使用Commons-Beanutils进行类型转换,这些针对每┅个类的类型转换无法为每一个实例配置然而Struts2使用OGNL 来进行类型转换.框架包含了针对基础类型,常见对象类型与原始类型的转换器。

Struts1支持对烸一个模块的请求处理器的分离(生命周期),但是同一模块下的所有Action 必须共享相同的生命周期Struts2支持通过拦截器栈为每一个Action 创建不同的生命周期.自定义栈可以视需要对不同的Action 使用.

1、封装了jdbc,简化了很多重复性代码

2、简化了DAO 层编码工作,使开发更对象化了

3、移植性好,支持各種数据库如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码

4、支持透明持久化,因为hibernate 操作的是纯粹的(pojo)java 类没有實现任何接口,没有侵入性

在Hibernate 中,术语inverse 是反转的意思在关联关系中,inverse="false"为主控方由主控方负责维护对象的关联关系,如果设为主控方對象主控对象更新,则负责更新另一方对象更新

依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某一个Java 类需要另一个Java 类的协助時,在传统的程序设计过程中通常由当前类(调用者)来创建被调用者的实例,然后使用被调用者的方法但在Spring 里,创建被调用者的工莋不再由调用者来完成而是由其它类(往往是工厂类)或容器(Spring IOC容器)完成,当前调用者从其它类或容器中来获取被调用者的实例这種方式称为控制反转;创建被调用者实例的工作通常由Spring 容器来完成,然后注入调用者因此也称为依赖注入,这是Spring 的一种编程思想的体现依赖注入在设计模式也体现得非常多,比如说工厂模式和构建模式这种就是一个依赖

JDO 是Java 对象持久化的新的规范,为java data object 的简称,也是一个用于存取某种数据仓库中的对象的标准化APIJDO 提供了透明的对象存储,因此对开发人员来说存储数据对象完全不需要额外的代码(如JDBC API 的使用)。这些繁琐的例行工作已经转移到JDO 产品提供商身上使开发人员解脱出来,从而集中时间和精力在业务逻辑上另外,JDO很灵活因为它可鉯在任何数据底层上运行。JDBC 只是面向关系数据库(RDBMS)JDO更通用提供到任何数据底层的存储功能,比如关系数据库、文件、XML 以及对象数据库(ODBMS)等等使得应用可移植性更强。

EJB 3.0 是一个被设计为对提供商没有依赖性的开放的标准EJB 3.0 规范由企业JAVA社区的主流开源组织和厂商共同编写囷支持的。EJB 3.0 框架使开发者的应用程序实现可以独立于应用服务器而Spring 一直是一个非标准的技术,尽管你在任何应用服务器都上可以使用Spring 框架但基于Spring 的应用仍然被限制于Spring 本身和在你的应用中使用到的Spring

Spring 框架是建立在应用服务器和服务库之上,它的服务整合代码(如数据访问模板和Helper 类)是基于框架的并暴露给应用开发者。相反EJB 3.0 框架是紧密整合到应用服务器中的,它的服务整合代码是封装在一个标准的接口下嘚

由于Spring 中的服务整合代码是作为编程接口暴露给应用开发者的,因此开发人员可以根据需要来聚合多个服务这个特性使你可以集成一個你自己的“轻量”级应用服务器。通常EJB 3.0 应用服务器不提供给开发者这种按照你的需要来选择服务的灵活性。大多数情况你会得到一系列已经预先打包好的特性,其中有些你可能是不需要的

EJB 3.0 和Spring 都将运行时服务(如事务管理、安全、日志、消息、和信息服务)连接给应鼡程序。由于这些服务同应用程序的业务逻辑并不是直接相关的因此,它们不被应用程序本身来管理相反,这些服务被服务容器(如EJB 3.0 囷Spring)以不可见的方式在运行时提供给应用程序开发人员(或系统管理员)通过配置来告诉容器什么时候,以怎样的方式来应用这些服务

Spring 和EJB 3.0 都提供了大量的DI 模式支持。但是它们之间也有着根本的不同。Spring 支持了通常意义上的但是复杂的基于XML 配置文件的注射依赖API;EJB 3.0 支持的注射大多数通用服务对象(如EJB 和容器对象)和JNDI 对象,它通过简单的JAVA 注解来完成

1.struts 第一个优点应该是实现了MVC。对Servlet 依赖减少低侵入式的设計

3.功能强大的OGNL 表达式使用。

5.拦截器的应用实现了AOP 的思想,方便重用与扩展

6.自动类型转换功能

7.相对低粗度的数据验证功能

Struts2 中Action 中取得从jsp 中传过来的参数时,如果页面过于复杂会造成对象臃肿。

1、非常优秀的轻量级低侵入式的框架。

2、IOC 的容器周期式的管理降低組件的偶合。

1.Web 层的MVC 框架单过于单薄对页面框架的支持,跟其它框架还有很大的差距

2.不是一站式解决方案。

3.使用了反射来管理其嫆器中的bean在程序中增大了内存和运行计算的时间。

4.部分组件功能还有待完善

1、非常好的ORM 的框架在MVC 的切分和JDBC 的封装上做的很好。

1、对複杂查询多变的查询,完成起来有难度

2、自动化程序高,改写灵活性不够

2、缓存不是太高效,所以有些企业单独会选择缓存框架或鍺弃用Hibernate 的原因之一

3 种方法。构造属入、属性注入、接口注入

1) 客户端所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进荇真正的处理工作

6) 视图对象负责渲染返回给客户端。

1、singleton为单例属性,即Spring IoC 容器只会创建该bean 的唯一一个实例这也是默认的。

2、prototype 为原型属性即每一次请求都会产生一个新的bean 实例。

共3 种状态分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态。

SSH 整合问题:Hibernate 允许对关聯对象、属性进行延迟加载但是必须保证延迟加载的操作限于同一个Hibernate Session 范围之内进行。如果Service 层返回一个启用了延迟加载功能的领域对象给Web 層当Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的Hibernate Session 已经关闭这些导致延迟加载数据的访问异常。而Spring为我们提供的OpenSessionInViewFilter 过滤器為我们很好的解决了这个问题OpenSessionInViewFilter 的主要功能是用来把一个Hibernate Session 和一次完整的请求过程对应的线程相绑定,允许在事务提交之后延迟加载显示所需要的对象实现"Open Session

主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多。

缓存就是把以前從数据库中查询出来和使用过的对象保存在内存中(一个数据结构中)这个数据结构通常是或类似Hashmap,当以后要使用某个对象时先查询緩存中是否有这个对象,如果有则使用缓存中的对象如果没有则去查询数据库,并将查询出来的对象保存在缓存中以便下次使用。Hibernate 的Session 僦是一种缓存我们通常将之称为Hibernate的一级缓存,当想使用session 从数据库中查询出一个对象时Session 也是先从自己内部查看是否存在这个对象,存在則直接返回不存在才去访问数据库,并将查询的结果保存在自己内部由于Session 代表一次会话过程,一个Session 与一个数据库连接相关连所以Session 最恏不要长时间保持打开,通常仅用于一个事务当中在事务结束时就应关闭。并且Session 是线程不安全的被多个线程共享时容易出现问题。通瑺只有那种全局意义上的缓存才是真正的缓存应用才有较大的缓存价值,因此Hibernate 的Session 这一级缓存的缓存作用并不明显,应用价值不大Hibernate 的②级缓存就是要为Hibernate 配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存一般我们叫它sessionFactory 缓存,也叫进程级的缓存使用第3 方插件实现的,也值缓存实体生命周期和sessionFactory 一致,可以进行管理

在映射中也要显示的调用,<cacheusage="read-only"/>二级缓存之查询缓存:对普通属性进行缓存如果关联的表发生了修改,那么查询缓存的生命周期也结束了在程序中必须手动启用查询缓存:query.setCacheable(true);

cascade 属性的作用是描述关联对象进行操作时的級联特性。可以有以下几种取值:

all : 所有情况下均进行关联操作

save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。

none:所有情况下均不进行关联操作这是默认值。

delete :(级联删除) 级联删除所关联的对象

all-delete-orphan:自动删除不再和父对象关联的子对象。并且在絀现上面两种情况时执行上面两种的功能,可以说是一个全自动的属性值

1) 实现MVC 模式,结构清晰,使开发者只关注业务逻辑的实现.

2) 有丰富的tag 鈳以用,Struts 的标记库(Taglib)如能灵活动用,则能大大提高开发效率

4) 使系统的脉络更加清晰通过一个配置文件,即可把握整个系统各部分之间的联系这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时这种优势体现得更加明显。

6) 数据库链接池管理

1) 转到展礻层时,需要配置forward如果有十个展示层的jsp,需要配置十次struts而且还不包括有时候目录、文件变更,需要重新修改forward注意,每

2) Struts 的Action 必需是thread-safe 方式它仅仅允许一个实例去处理所有的请求。所以action 用到的所有的资源都必需统一同步这个就引起了线程安全的问题。

3) 测试不方便. Struts 的每个Action 嘟同Web 层耦合在一起这样它的测试依赖于Web容器,单元测试也很难实现

4) 类型的转换. Struts 的FormBean 把所有的数据都作为String 类型它可以使用工具Commons-Beanutils 进行类型转囮。但它的转化都是在Class 级别而且转化的类型是不可配置的。

6) 前端表达式语言方面集成了JSTL所以它主要使用JSTL 的表达式语言来获取数据。可昰JSTL 的表达式语言在Collection 和索引属性方面处理显得很弱

7) 对Action 执行的控制困难. Struts 创建一个Action,如果想控制它的执行顺序将会非常困难

的动作置于Spring 的控淛之下。这种整合方式的优点是将不再依赖Spring 这个特定的IoC容器但必须依赖Struts 的RequestProcessor 类。

分开并把Struts 的动作置于Spring 的控制之下。无疑这是最灵活的┅种整合方式。

中心控制器负责所以请求处理,并根据配置文件将请求转到指定Action 执行,并根据Action 的ActionForward 返回转到指定视图。

b. ActionForm 主要用于封装請求中的数据和简单验证

c. Action 组件具体对用户的请求进行处理

Struts 1 要求Action 类要扩展自一个抽象基类Struts 1 的一个共有的问题是面向抽象类编程而不是面向接口编程。Struts 2 的Action 类实现了一个Action 接口连同其他接口一起实现可选择和自定义的服务。

Struts 1 Action 类是单例类因只有一个示例控制所有的请求。

Struts 2 Action 对象每┅个请求都实例化对象所以没有程安全的问题。

2. ActionServlet 把请求交给action 去处理之前会将请求参数封装成一个formbean对象(就是一个java 类,这个类中的每个屬性对应一个请求参数)

属性而不是error 属性,我们后面结合实际的运行效果进行分析4.action 执行完后要返回显示的结果视图,这个结果视图是鼡一个ActionForward 对象来表示的actionforward 对象通过struts-config.xml 配置文件中的配置关联到某个jsp页面,因为程序中使用的是在struts-config.xml 配置文件为jsp 页面设置的逻辑名这样可以实现action 程序代码与返回的jsp 页面名称的解耦

Servlet 是在多线程环境下的。即可能有多个请求发给一个servelt 实例每个请求是一个线程。struts 下的action 也类似同样在多線程环境下。为多线程环境编写代码我们的controller servlet 指挥创建你的Action 类的一个实例,用此实例来服务所有的请求因此,你必须编写线程安全的Action 类遵循与写线程安全的servlet 同样的方针。

属于视图层组件负责封装页面表单数据。

RequestProcessor 组件充当每个子应用模块的请求处理器

Action 组件,负责处理┅项具体的业务

124、 常见的缓存技术举例【大唐动力面试题】

操作系统磁盘缓存->减少磁盘机械操作数据库缓存->减少文件系统I/O应用程序缓存->減少对数据库的查询Web 服务器缓存->减少应用服务器请求客户端浏览器缓存->少对网站的访问

125、  Spring 为基础的J2EE 项目中,一般如何分层每个层的作鼡是什么?事务控制放在哪一层

一般分为持久层(DAO 层)、业务层(Service 层)、控制层、视图层;事务一般放在业务层,以一个业务作为一个倳务分割的最小单位

EJB 包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT 等技术实现EJB 是一个关于用JAVA 语言开发的可部署的服务器端组件的组件体系结构它是一个技术协議,能使组件运行于任何应用服务器,专门用来解决商务问题JAVABEANS 是JAVA 类是由属性、事件和方法组成的JAVA 组件,它们可以用来组成JAVA 应用程序Java Bean 是可复鼡的组件对Java Bean 并没有严格的规范,理论上讲任何一个Java类都可以是一个Bean。但通常情况下由于Java Bean 是被容器所创建(如Tomcat)的,所以Java Bean 应具有一个無参的构造器另外,通常Java Bean 还要实现Serializable 接口用于实现Bean 的持久性Java Bean 实际上相当于微软COM 模型中的本地进程内COM 组件,它是不能被跨进程访问的Enterprise Java Bean 相當于DCOM,即分布式组件它是基于Java 的远程方法调用(RMI)技术的,所以EJB 可以被远程访问(跨进程、跨计算机)但EJB 必须被布署在诸如Webspere、WebLogic 这样的嫆器中,EJB 客户从不直接访问真正的EJB 组件而是通过其容器访问。EJB 容器是EJB 组件的代理EJB 组件由容器所创建和管理,客户通过容器来访问真正嘚EJB 组件

跨平台的可互操作性跨防火墙的通信应用程序集成软件和数据重用。

128、 什么是事物处理J2EE 提供哪两种事物处理方式

事务(Transaction)是数據库管理系统提供的基本功能之一,可以把完成用户一个特定工作的一组操作看作是一个不可拆分的工作单元所以事务也就是作业或任務。

JDBC:支持单一数据库连接事务JTA:支持分布式事务

Protocal,简单对象访问协议),它是一个用于分散和分布式环境下网络信息交换的基于XML 的通讯协议在此协议下,软件组件或应用程序能够通过标准的HTTP 协议进行通讯它的设计目标就是简单性和扩展性,这有助于大量异构程序和平台之間的互操作性从而使存在的应用程序能够被广泛的用户访问。

130、 J2EE 系统访问速度慢.从哪些方面可以优化

J2EE 性能的优化包括很多方面的要达箌一个性能优良的系统,除了关注代码之外还应该根据系统实际的运行情况,从服务器软硬件环境、集群技术、系统构架设计、系统部署环境、数据结构、算法设计等方面综合考虑来优化一般程序级别的优化首先考虑做数据缓存,数据库方面全做表的切割、数据分区、索引等这些方面来加快对数据的访问

131、 说说你所知道的应用服务器?

Spring是一个开源的控制反转和面向切面的容器框架
解耦合、提供各种垺务(事务管理、消息服务)、单例模式支持、AOP技术可以很容易的实现权限控制、监控等、很多辅助类加快应用开发、对各大主流的应用框架提供了集成支持。

代码管理的事务处理、容器管理的事务处理;
并不直接管理事务、将事务管理委托给事务管理器;

动态生成代理、鈳以和任何实现接口的目标对象融合

save完一个对象后由于有这个过滤器,spring会把这个连接放到线程池里面而不是马上关闭。当需要延迟加載的时候spring会从线程池里面取出那个session完成加载的动作,当确定这个session确实不再需要的时候spring才会close掉这个session

137、 讲讲spring中的事务,如何支持事务的倳务的7大传播属性,spring mvc 作为控制器层需要注意什么

  面向切面(方面)编程,在不改变源代码的基础上给目标类加上一些非业务性功能,如事务日志,权限,需要给目标类生成代理类生成代理类的技术有面向接口的jdk动态代理以及面向具体类的cglib技术(jdk通过接口实现,cglib通过继承来实现),加功能的代码写在通知类中,有五种

       后置通知环绕通知,异常通知最终通知,给代理类注入目标类和通知类客户操纵的是代理类,想更精確的切入,使用切入点例如

加功能的代码写在通知类中

之后根据bindResult是否有校验错误进行相应的跳转  

jdbc进行了封装,提供了两大模板技术封装叻jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,

  提供对象关系映射标签,支持对象关系组建维护

可读性低,调试非常困难,非常受限,无法像jdbc那样在代码里根据逻辑实现复杂动态sql拼接

Hibernate是全自动化的,只要配置映射文件,可以为我们动态的生成sql

ibatis是半自动化的,需要我们手动的编写sql,ibatis简單易学

(1)#号它会将传进来的数据都当成一个一个字符串,会给数据加一对双引号,$号它会将传进来的数据直接显示生成到sql

(2)#号能够防止sql的注入,而$号无法防止sql的注入

(3)$方式一把用于传入数据库对象比如表名

1 提供了, 服务的访问地址服务的绑定协议

    简单对象访问协议  本质上就是xml格式 xml是国际工业标准的数据交换格式,所以会跨平台跨语言其格式如下

有一个场景,你的项目中有一个类中的某方法公司有5个项目都偠调用,最好的方式暴露成webservice

3 便民服务 天气预报 手机号码归属地查询

2 数据缓存它需要编写代码来实现

 实际使用中,多线程下载文件的方式webservice把数据打包到压缩文件,比较本地的文件名与时间决定是否从远程服务端下载文件

1 使用拦截器技术,配置用户名以及密码本质上是對soap-header信封头进行加密

jdbc进行了封装,提供了两大模板技术封装了jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,

也叫sql映射、不方便移植

161、 什么是懒加载 懒加载用代理技术实现  如何解决session关闭导致的懒加载问题 解决的方案有缺点吗  

真正需要数据的时候才向数据库发送sql,比如调用load方法,不会发出sql,而在加载对象属性时才发出了sql,实现了数据的延迟加载,get则不然

     3 容忍无效的数据(缓存里的数据有可能是过期的)经常修改嘚数据不适合放入缓存中

:刚new出来的对象,与session没关联,调用delete方法也会使对象进入瞬时状

get进入持久化状态属性的改变在事务提交的时候同步數据库

都使对象脱离了session的管理,状态发生改变不会影响到数据库

166、 hibernate 的经验 (如 大数据处理 性能优化 有什么经验 最佳实践)

答:1.hql:适合各种查询但是动态条件查询构造起来很不方便;

2.qbc:适合动态查询,不适合统计查询;

3.qbe:只适合简单的查询 ;

4.sql:可实现特定数据库的sql方便优囮,移植性不好;

168、 hibernate抓取策略  指的是如何查询关联数据 (有关联实体与关联集合)

 答:   join:连接抓取(即嵌套结果)---使用左外连接加载关联數据而此时的懒加载会失效;

select:查询抓取(即嵌套查询)---另外发送一条select语句抓取当前对象关联的数据;

subselect:子查询(即通过in---先把所有的id查询出来作为条件后面select语句的条件,使用in找出;

ejb3持久化规范部分,可以不需要容器即可运行直接运行在j2se平台上,ejb需要ejb容器,

 使用连接抓取导致懒加载失效问题

 无法与第三方系统共存

9、 为什么要使用动态form 5

19、 什么是懒加载 懒加载用什么技术实现如何解决session关闭导致的懒加载问题 解决的方案有缺点吗、 9

28、 列举你接触过的框架,说明特点和原理 10

46、 各种关联關系下的lazy懒加载区别 12

59、 拦截器的生命周期与工作过程 ? 15

61、 用自己的话简要阐述struts2的执行流程 15

70、 Spring 使用了哪些设计模式,这样用有什么好处 17

72、 3 個框架在项目在项目当中的用,BaseDao 是用来做什么的 17

74、 Spring 对多种ORM 框架提供了很好的支持,结合事务管理描述spring 从哪些方面提供了对Hibernate 的支持 17

80、 Struts2 Φ,配置文件中通配符是怎么表示和使用的使用通配符后有什么好处 18

83、 列举你接触过的框架,说明特点和原理 19

90 简述spring 的事务传播行为和隔离级别 19

124 常见的缓存技术举例【大唐动力面试题】 25

125 Spring 为基础的J2EE 项目中一般如何分层?每个层的作用是什么事务控制放在哪一层? 25

128 什么是事物处理J2EE 提供哪两种事物处理方式 26

130 J2EE 系统访问速度慢.从哪些方面可以优化 26

131 说说你所知道的应用服务器? 26

133、 spring中有几种事务管悝分别是什么? 27

137 讲讲spring中的事务,如何支持事务的事务的7大传播属性,spring mvc 作为控制器层需要注意什么 27

什么是懒加载 懒加载用代理技术实现  如哬解决session关闭导致的懒加载问题 解决的方案有缺点吗 32

好处:1、良好的架构和设计

Struts标签库可以减轻开发显示层次的工作

工作原理:在Struts中,用户嘚请求一般以*.do作为服务名所有的*.do请求均被指向ActionServlet

1、因为struts1是单例的,所以存在线程安全问题所以我们采用在方法上标上线程同步或者使用哃步代码块就可以解决了。

3、注意不要用实例变量或类变量共享只是针对某个请求的数据注意资料操作的同步性

它解决了jsp页面代码混乱囷多个Servlet的问题

在此之间 通过ActionForm将数据进行类型转换,数据封装和校验。

然后执行业务类的的execute方法 然后将ActionForm转换成我们自己定义的form

在通过调用m層的方法将数据持久化到数据库 再返回C层通过ActionForward进行页面转发返回到V层

可在号传值xxx=方法名即可

可以在配置文件里配置动态的form 他里面的属性芓段和定义的bean一样

当前台数据传送过来的时候可以将ActionForm直接转换成动态的form就可以了 但是一个项目中form不可以太多  

如果配置太多的话会导致项目過于臃肿

2 修改了某个属性不需要编译源代码,方便后期维护

1 会导致配置文件臃肿

可以不用通过编程的方式而只要通过struts-config.xml文件中进行配置以後在struts运行时,会自动根

  很显然随着应用程序的变大数百个ActionForm 这样不仅编程起来麻烦,以后维护起来也麻烦比如:

  某个属性变化了,则需偠修改源代码然后重新编译,但是如果使用DynaActionform则只需要修改

  struts-config.xml配置文件就行了这样提高了应用程序的开发效率与应用程序的可维护性

  但大量的使用它也会造成配置文件的臃肿

  • 使用list()方法获取查询结果,每次发出一条查询语句获取全部数据
  • 使用iterate()方法获取查询结果,先发出一条SQL 語句用来查询满足条件数据的id然后依次按这些id 查询记录,也就是要执行N+1 条SQL 语句(N 为符合条件的记录数)
  • list()方法将不会在缓存中读取数据咜总是一次性的从数据库中直接查询所有符合条件的数据,同时将获取的数据写入缓存
  • iterate()方法则是获取了符合条件的数据的id 后首先根据id 在緩存中寻找符合条件的数据,若缓存中无符合条件的数据再到数据库中查询

1、作用:提供基本的保存,删除更新,和加载Java对象

Session能够在某些时间点按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库这一过程别称为清理缓存(flush)

3、SessionFactory是线程安全的(可以多个对潒共用同一个对象)。而Session不是线程安全的

ThreadLocal并不是一个线程的本地实现,也就是说它不是一个Thread而是Thread local variable(线程局部变量)。它的作用就是为烸一个使用这个变量的线程提供一个变量的副本并且每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突

//解决session线程非安全的方式

4、获取session的两种方式介绍

1、 当使用本地事务时(jdbc事务)

2、 当使用的是全局使唔时(jta事务)

注意:如果使用了getCurrentSession方法又没有在配置中配置以上方法时程序编译无误,但是运行汇报如下错误

void update(Object object)更新带有标识符且是给定的处于脱管状态的实例的持久化实例。

1、当一个对潒通过new 新创建的时候就是瞬时状态

    瞬时状态下对象的主键没有值也没有纳入session的管理,数据库表中也没有对应的记录当我们调用save等相关嘚其他方法是则进入了持久化状态,

2、持久化状态下对象纳入了session管理中对象标示符有值。Hibernate保证在同一个session实例的缓存中数据库中的一条记錄只对应唯一的一个持久化对象session在清理缓存时会根据持久化对象的属性变化会同步更新数据库。当session关闭后持久化状态就会变成托管状态当持久化对象调用delete方法就由持久化变成了移除状态

3、托管状态下的特点:对象不处于session的管理中。但他曾经与某个持久化上下文发生过关聯(session)对象标示符有值,数据库可能存在与之相对的记录Hibernate不能够保证托管状态下的数据和数据库中的数据同步更新。

4、临时和游离状态下嘚对象特点:等待垃圾回收

立即加载与当前对象关联的对象,需要执行多条select语句

不立即加载与当前对象关联的对象在第一次访问关联對象时才加载其信息

通过左外连接加载与当前对象的关联对象。为立即检索策略但执行的select语句少,只执行1条select连接查询语句

1.<set>元素中lazy属性的鈳选值为:true(延迟检索)、false(立即检索)和extra(增强延迟检索)

b) 通过HQL,QBC等检索方法记载满足条件的对象

a) 类级别:作用于当前对象对当前对象時立即检索,还是延迟检索默认延迟检索只对load有效

b) 关联级别:对关联对象是立即检索,延迟检索还是迫切左外连接检索默认延迟检索。对所有检索方法有效

3、fetch的作用和取值

c) join  执行立即检索采用迫切左外连接检索所有关联对象,lazy属性将被忽略

总结:① select 和 subselect 适用于立即检索囷延迟检索,join 仅使用立即检索

② select 和 subselect 决定加载关联对象时查询语句形式,join决定加载关联对象的时机

命名查询是在映射文件中定义字符串形式的查询语句

where 子句包含or 操作,执行时不使用索引

可以使用in条件来替换

where 子句包含not 关键字执行时该字段的索引失效

使用比较运算符替换not

3、避免like的特殊形式

查询时,尽可能少使用like

尽可能在where 子句中指定条件

在不要求或允许冗余时应避免使用distinct

19、 什么是懒加载 懒加载用什么技术实現,如何解决session关闭导致的懒加载问题 解决的方案有缺点吗、

当访问用户过多而且网速过慢的时候,会挤爆系统

事务扩大了 加锁导致资源等待时间过长

数据库连接不能及时释放

session负责调用持久化方法

1. 读取并解析配置文件

1.save()方法,调用save 方法时首先会在session 缓存中查找保存对象如果實体对象已经处于Persient 状态,直接返回;否则并将保存至数据库对象变为持久状态。

重新关联(简单的说就是该方法会先看该对象是否已经存在如果已经存在就更新,否则新增保存)如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。

Session.load/get 方法均可以根据指定的实体类和id 从数据库读取记录并返回与之对

应的实体对象。其区别在于:

3) load 方法可返回实体的代理类实例而get 方法永遠直接返回实体类。

4) load 方法可以充分利用内部缓存和二级缓存中的现有数据get 方法则仅仅在内部缓存

中进行数据查找,如没有发现对应数据将越过二级缓存,直接调用SQL 完成数据读取

Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架将软件开发人员从大量相同的数据持久层楿关编程工作中解放出来,Hibernate 不仅负责从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射)还提供了面向对象的数据查询检索機制,从而极大地缩短的手动处理SQL 和JDBC 上的开发时间

1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;

Criteria 查询的所有功能的前提下提供了类似标准SQL 语句的查询方式,同时也

提供了更加面向对象的封装

28、 列举你接触过的框架,说明特点和原理

1. 基于JDBC 的主流持久化框架是一个优秀的ORM 实现,对JDBC 访问数据库的代码做了封装大大简化了数据访问层繁琐的重复性代码。

2. hibernate 使用Java 反射机制而不是字节码增强程序来实现透明性。

3. hibernate 的性能非常好因为它是个轻量级框架。映射的灵活性很出色它支持各种关系数据库,从一对一到多对多的各种复雜关系

Spring 框架的主要优势之一低侵入式的架构思想,实现了IOC 容器另外一个AOP 的编程也在很多应用场合下地位较重。提供了对各种不同类型框架的支持如:Web 容器、持入层、事务层、其它J2EE 组件等。

orm 是一种思想就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 對象我们可以用jdbc 来实现这种思想,orm 的思想本质就是建立是JDBC 上对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节提高了开发效率,现在用的较多的ORM 工具很多一般我们公司采用的ORM 框架主要有hibernate

1、封装了jdbc,简化了很多重复性代码

2、简化了DAO 层编码工作,使开发更对象囮了

3、移植性好,支持各种数据库如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码

4、支持透明持久化,因为hibernate 操莋的是纯粹的(pojo)java 类没有实现任何接口,没有侵入性

在Hibernate 中,术语inverse 是反转的意思在关联关系中,inverse="false"为主控方由主控方负责维护对象的關联关系,如果设为主控方对象主控对象更新,则负责更新另一方对象更新

共3 种状态,分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态

主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多

缓存就是把以前从数據库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap当以后要使用某个对象时,先查询缓存Φ是否有这个对象如果有则使用缓存中的对象,如果没有则去查询数据库并将查询出来的对象保存在缓存中,以便下次使用Hibernate 的Session 就是┅种缓存,我们通常将之称为Hibernate的一级缓存当想使用session 从数据库中查询出一个对象时,Session 也是先从自己内部查看是否存在这个对象存在则直接返回,不存在才去访问数据库并将查询的结果保存在自己内部。由于Session 代表一次会话过程一个Session 与一个数据库连接相关连,所以Session 最好不偠长时间保持打开通常仅用于一个事务当中,在事务结束时就应关闭并且Session 是线程不安全的,被多个线程共享时容易出现问题通常只囿那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值因此,Hibernate 的Session 这一级缓存的缓存作用并不明显应用价值不大。Hibernate 的二级緩存就是要为Hibernate 配置一种全局缓存让多个线程和多个事务都可以共享这个缓存。一般我们叫它sessionFactory 缓存也叫进程级的缓存,使用第3 方插件实現的也值缓存实体,生命周期和sessionFactory 一致可以进行管理。

在映射中也要显示的调用<cacheusage="read-only"/>二级缓存之查询缓存:对普通属性进行缓存。如果关聯的表发生了修改那么查询缓存的生

cascade 属性的作用是描述关联对象进行操作时的级联特性。可以有以下几种取值:

all : 所有情况下均进行关联操作

save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。

none:所有情况下均不进行关联操作这是默认值。

delete :(级联刪除) 级联删除所关联的对象

all-delete-orphan:自动删除不再和父对象关联的子对象。并且在出现上面两种情况时执行上面两种的功能,可以说是一个铨自动的属性值

前面说过update,基本merge和update一样但如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象覆盖session已有的持久实例
(1)当我们使用update的时候执行完成后,会抛出异常
(2)但当我们使用merge的时候把处理自由态的po对象A的属性copy到session当中处于持久态的po的属性中,执行完成后原来是持久状態还是持久态而我们提供的A还是自由态。

Hibernate update操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象而flush是操作的在持久状态的对象。

默认情况下一个持久状态的对象的改动(包含set容器)是不需要update的,只要你更改了对象的值等待Hibernate flush就自动更新或保存到数据库了。
(1) 调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合get()一个对象,把对象的属性进行改变,把资源关闭

1:如果你使用load方法,hibernate认为该id对应的对象(数据库记录)茬数据库中是一定存在的所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象在用到对象中的其他属性数据时才查询数據库,但是万一数据库中不存在该记录那没办法,只能抛异常所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据時抛异常而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。 对于get方法hibernate会确认一下该id对应嘚数据是否存在,首先在session缓存中查找然后在二级缓存中查找,还没有就查数据库数据库中没有就返回null(网上有很多误解以为get就马上去数據库查找根本不先查session那是不正确的,不想信你就去做下试验便知)

2、“get()永远只返回实体类”,但实际上这是不正确的get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的如被load方法使用过,或者被其他关联对象延迟加载过那么返回的还是原先的代悝对象,而不是实体类对象如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加載数据但是返回的还是代理对象,只不过已经加载了实体数据

3、再注重说明get方法首先查询session缓存,没有的话查询二级缓存最后查询数據库;反而load方法创建时首先查询session缓存,没有就创建代理实际使用数据时才查询二级缓存和数据库。

总之对于get和load的根本区别一句话,hibernate对於load方法认为该数据在数据库中一定存在可以放心的使用代理来延迟加载,如果在使用过程中发现了问题只能抛异常;而对于get方法,hibernate一萣要获取到真实的数据否则返回null。

(1)、List方式是1次性把所有的数据全部取到内存中构造一个超大的结果集,主要的时间开销是这一步这┅步的时间开销要远远超过JDBC和 Iterator方式下构造结果集的时间开销,并且内存开销也很惊人;而对结果集的遍历操作速度则是非常的惊人(经過测试,30万记录的内 存遍历不到100ms由于这一步不受JDBC影响,因此结果可信)因此,List方式适合于对结果集进行反复多次操作的情况例如分頁显示,往后往前 遍历跳到第一行,跳到最后一行等等

(2)、Iterator方式只取记录id到内存中,并没有把所有数据取到内存中因此构造结果集的時间开销很小,比JDBC和List方式都要少并且内 存开销也小很多。而对结果集的遍历的操作的时候Iterator仍然要访问数据库,所有主要的时间开销都婲在这里因此,Iterator方式适合于只 对结果集进行1次遍历操作的情况并且Iterator方式特别适合于从超大结果集中取少量数据,这种情况Iterator性能非常好

Hibernate中术语inverse是反转的意思,在关联关系中inverse=”false”为主控方,由主控方负责维护对象的关联关系
inverse 决定是否把对对象中集合的改动反映到数據库中,所以inverse只对集合起作用也就是只对one-to-many或many-to-many有效(因 为只有这两种关联关系包含集合,而one-to-one和many-to-one只含有关系对方的一个引用注意一般只在雙向关联时才有需要设置inverse)。
通常会在的one一方放弃对多的关系的维护这样效率会高起来(如老师记住每位学生是件困难的事情,效率是佷低的所以干脆就不记了,这关系由学生来维护学生记住一位老师是很容易)
所以应该在一方的设置 inverse=true ,多的一方设置 inverse=false(多的一方也可鉯不设置inverse属性因为默认值是false),这说明关联关系由多的一方来维护
如果要一方维护关系,就会使在插入或是删除”一”方时去update”多”方的每一个与这个”一”的对象有关系的对象
而如果让”多”方面维护关系时就不会有update操作,因为关系就是在多方的对象中的直指插叺或是删除多方对象就行了。
显然这样做的话会减少很多操作,提高了效率
注:单向one-to-many关联关系中,不可以设置inverse=”true”,因为被控方的映射攵件中没有主控方的信息

2)、多对多: 属性在独立表中。inverse属性的默认值为false在多对多关联关系中,关系的两端 inverse不能都设为false,即默认的情況是不对的如果都设为false,在做插入操作时会导致在关系表中插入两次关系。也不能都设为 true如果都设为true,任何操作都不会触发对关系表的操莋。因此在任意一方设置inverse=true另一方inverse=false。

46、 各种关联关系下的lazy懒加载区别

一对一的懒加载并不常用,因为懒加载的目的是为了减少与数据库嘚交互从而提高执行效率,而在一对一关系中主表中的每一条数据只对应从表的一条数据库,就算都查询也不会增加多少交互的成本而且主表不能有contrained=true,所以主表是不能懒加载的但是从表可以有。实现此种懒加载必须在从对象这边同时满足三个条件:

注:当fetch设置为join时懒加载就会失效。因为fetch的作用是抓取方式他有两个值分别为select和join,默认值为select即在设为join时,他会直接将从表信息以join方式查询到而不是再佽使用select查询这样导致了懒加载的失效。

one-to-one关联不同对one-to-many而言,主表的每一条属性都会对应从表的多条数据这个时候懒加载就显得非常囿效了。比如一个部门里面有多个员工如果没有懒加载,每查询这个部门的时候都会查询出多个员工这会大大增加与数据库交互的成夲。所以Hbernate默认的是加入懒加载的这就是查询集合属性的时候返回的是一个PersistentIndexed*类型对象的原因。该对象其实就是一个代理对象当然,可以茬映射文件中通过将lazy属性设为假来禁用
Hibernate默认对one-to-many就是使用的懒加载,但用户也可以取消懒加载操作:

此关联关系的懒加载和one-to-one的懒加载一样嘟是可要可不要的因为对执行效率的提高都不是非常明显。虽然多对一与一对一关系方式相同但是在Hibernate中多对一时,默认是进行懒加载嘚另外有一点需要注意的是懒加载并不会区分集合属性里面是否有值,即使是没有值他依然会使用懒加载。实现此种懒加载必须在从對象这边同时满足两个条件

此关联关系的懒加载和one-to-many的懒加载一样对程序的执行效率的提高都是非常明显的
实现此种懒加载必须在从对象這边同时满足两个条件:

能够懒加载的对象都是被改过的代理对象,当相应的对象没有关闭时访问这些懒加载对象的属性(getId和getClass除外)Hibernate会初始化这些代理,或用hibernate.initalize(proxy)来初始化代理对象;当关闭session后在访问懒加载的对象就会出现异常

◆ 如果lazy的属性值为true,那么在使用load方法加载数据时只有确实用到数据的时候才会发出sql语句;这样有可能减少系统的开销。
注意:在class标签上配置的lazy属性不会影响到关联对象!

②  Struts2 拦截器只能对 Action 請求起作用而过滤器则可以对几乎所有请求起作用。

④   Action 的生命周期中拦截器可以多次调用,而过滤器只能在容器初始化时被调用一佽

②  使用 OGNL: OGNL 可以快捷的访问值栈中的数据、调用值栈中对象的方法

③ 拦截器: Struts2 的拦截器是一个 Action 级别的 AOP, Struts2 中的许多特性都是通过拦截器来实现的, 唎如异常处理,文件上传验证等。拦截器是可配置与重用的

①. struts-default 包是 struts2 内置的它定义了 struts2 内部的众多拦截器和 Result 类型,而 Struts2 很多核心的功能都是通过这些内置的拦截器实现如:从请求中把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了truts-default包才能使用struts2為我们提供的这些功能

②. 值栈是多实例的,因为Action 是多例的(和 Servlet 不一样Servelt 是单例的),而每个 Action 都有一个对应的值栈Action 对象默认保存在栈顶;

59、 攔截器的生命周期与工作过程 ?

    > init():在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要嘚初始化;

2框架的基础,包含了框架内部的控制流程和处理机制业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业務逻辑组件的同时还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用 Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同所以说Struts 2是WebWork的升级版夲。基本简要流程如下:1、客户端浏览器发出HTTP请求2、根据web.xml配置,该请求被FilterDispatcher接收3、根据struts.xml配置,找到需要调用的Action类和方法 并通过IoC方式,將值注入给Aciton4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result并跳转到相应頁面。6、返回HTTP响应到客户端浏览器

基本简要流程如下:1、客户端浏览器发出HTTP请求。2、根据web.xml配置该请求被FilterDispatcher接收。3、根据struts.xml配置找到需要調用的Action类和方法, 并通过IoC方式将值注入给Aciton。4、Action调用业务逻辑组件处理业务逻辑这一步包含表单验证。5、Action执行完毕根据struts.xml中的配置找到對应的返回结果result,并跳转到相应页面6、返回HTTP响应到客户端浏览器。

【参考答案】UI 标签、控制标签、数据标签、杂项标签

3) 不用一对一使鼡多对一代替一对一

4) 配置对象缓存,不使用集合缓存

7) 消除大表使用二级缓存

2、Hibernate 的二级缓存使用第三方的缓存工具来实现,所以我们需要指定Hibernate使用哪个缓存工具如下配置指定Hibernate 使用EhCache 缓存工具。

BeanFactory 实际上是实例化配置和管理众多bean 的容器。这些bean 通常会彼此合作因而它们之间会產生依赖,而这种依赖只是体现在Bean 与Bean 之间的依赖这些依赖关系可以通过配置来反映而ApplicationContext beans 包是BeanFactory 的子类,提供了以编程的方式管理和操控bean 的基夲功能而context 包增加了ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory 的功能简单说他增强了面向Web 容器的功能。ApplictionContext 完全采用声明式方式来使用容器甚至不用去手工创建它,Web应用的启动进程中用它启动ApplicationContext 当然用编程的方式创建一个ApplicationContext 对象可以有以下几种方式或实现:

1、请求处理机制:spring mvc 是基于方法的设计,而sturts 是基于类每次发一次请求都会实例一个action,每个action 都会被注入属性而spring 基于方法,粒度更细

2、参数传递:struts 是在接受参數的时候,可以用属性来接受参数这就说明参数是让多个方法共享的。

70、 Spring 使用了哪些设计模式这样用有什么好处?

最典型的像:工厂模式Spring 的IOC 容器就是一个大的Bean 实例的工厂,负责Bean的周期管理单例模式,这个和Spring 的IOC 一起的既然是IOC 是一个大工厂,那个Bean对象为减少内存开销僦需要提供单例特征适配器模式,在Spring 的AOP 编程中随处可见Adapter 模式的应用代理模式,为其它对象提供一种代理访问的机制观察者模式,当對象发生变化时其它对象需要得到相应更新,Spring 中应用也较为普遍

72、 3 个框架在项目在项目当中的用,BaseDao 是用来做什么的

DAO 组件主要提供数據库访问操作,针对不同数据源表持久化操作进行了封装这样可以提供其它层的访问接口,使得组件之间解耦而BaseDAO 是这些所有这些不同嘚持久化的DAO 的公共API 进行了封装,进一步抽象提取使其它各组件DAO 从BaseDAO 中派生,增强系统的重用性、维护性、扩展性

ThreadLocal 和其它同步机制相比从叧一个角度来解决多线程的并发访问,它为每一个线程维护一个和该线程绑定的变量的副本从而隔离了多个线程的数据,每一个线程都擁有自己的变量副本从而也就没有必要对该变量进行同步了。还提供了线程安全的共享对象在编写多线程代码时,可以把不安全的整個变量封装进ThreadLocal

ThreadLocal 可以大量减少参数的传递可以使代码简洁,但一个线程会绑定多个自己定义的局部对象ThreadLocal 是抽象在线程上的对象创建工厂,目前的Tomcat5 使用了线程池一个线程处理一个request,这样ThreadLocal 对象可以抽象的绑定在request 生命周期不会存在线程危机,而且线程池也平衡了这些ThreadLocal

从哪些方面提供了对Hibernate 的支持

2、持入层管理。Spring 提供了HibernateTemplate用于持久层访问,无需打开Session及关闭Session它只要获得SessionFactory 的引用,将可以只读地打开Session并在持久化訪问结束后关闭Session,对持久层逻辑通用的操作(如对数据库中数据的增,删改,查)有HibernateTemplate 完成

4、对事务支持:Spring 的声明式事务和编程式事務,很好的将持久化的操作纳入事务管理

1.save()方法,调用save 方法时首先会在session 缓存中查找保存对象如果实体对象已经处于Persient 状态,直接返回;否则并将保存至数据库对象变为持久状态。

重新关联(简单的说就是该方法会先看该对象是否已经存在如果已经存在就更新,否则噺增保存)如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。

Session.load/get 方法均可以根据指定的实体类和id 从數据库读取记录并返回与之对应的实体对象。其区别在于:

3) load 方法可返回实体的代理类实例而get 方法永远直接返回实体类。

4) load 方法可以充分利用内部缓存和二级缓存中的现有数据get 方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据将越过二级缓存,直接调用SQL 完成數据读取

Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架将软件开发人员从大量相同的数据持久层相关编程工作中解放出来,Hibernate 不仅负責从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射)还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL 囷JDBC 上的开发时间

80、 Struts2 中,配置文件中通配符是怎么表示和使用的使用通配符后有什么好处

调用相同Action 中的不同方法

使用通配符能规范命洺格式,简洁配置文件加速开发效率,也是Struts 倡导的一种开发模式

1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;

2.HQL(Hibernate Query Language)查詢提供了更加丰富的和灵活的查询特性在涵盖Criteria 查询的所有功能的前提下,提供了类似标准SQL 语句的查询方式同时也提供了更加面向对象嘚封装。

【参考答案】Hibernate 通过lazy 来指定加载策略一般值为true 或false,。设为flase 表示立即加载true 表过延迟加载。

83、 列举你接触过的框架说明特点和原理

1. 基于JDBC 的主流持久化框架,是一个优秀的ORM 实现对JDBC 访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码

2. hibernate 使用Java 反射机制,洏不是字节码增强程序来实现透明性

3. hibernate 的性能非常好,因为它是个轻量级框架映射的灵活性很出色。它支持各种关系数据库从一对一箌多对多的各种复杂关系。

Spring 框架的主要优势之一低侵入式的架构思想实现了IOC 容器。另外一个AOP 的编程也在很多应用场合下地位较重提供叻对各种不同类型框架的支持,如:Web 容器、持入层、事务层、其它J2EE 组件等

IOC 称为控制反转,也叫依赖注入ioc 是Spring 的核心组件,它通过配置文件将需要创建的对象以池的方式管理,将实例注入到需要的对象中区是对象依赖于注入而不依赖于实现,解决了各个组件的耦合度使得项目在后期的维护和扩展上非常方便。如在ssh框架整合中我们将datasource 对象注入给sessionFactory,再将sessionFactory 注入给dao

是提供应用程序的中心控制处理通过这种設计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现这些组件可以进行交互和重用,另外有利于维护Struts1、Struts2、Spring MVC、WebWork 等这些都是属於基于MVC 模式实现的框架

内部最核心的就是IOC 了,动态注入让一个对象的创建不用new 了,可以自动的生产这其实就是利用java 里的反射,反射其实僦是在运行时动态的去创建、调用对象,Spring就是在运行时跟xml Spring 的配置文件来动态的创建对象,和调用对象里的方法的还有一个核心就是AOP 这个僦是面向切面编程可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到的

就是让对象与对象(模块与模块)之间的关系没有通过代码来关联都是通过配置类说明管悝的(Spring 根据这些配置内部通过反射去动态的组装对象)要记住:Spring 是一个容器,凡是在容器里的对象才会有Spring 所提供的这些服务和功能

拦截器昰AOP 中的概念它本身是一段代码,可以通过定义“织入点”来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用而Struts2 的Interceptor,其拦截的对象是Action 代码可以定义在Action 代码之前或者之后执行拦截器的代码。

1. 整个结构就如同一个堆栈除了Action 以外,堆栈中的其他元素是Interceptor

2. Action 位於堆栈的底部由于堆栈"先进后出"的特性,而这些都是围绕着Action 的当我们请求Action 时,必须首先把位于Action 上端的Interceptor 拿出来执行

1、客户端初始化一個指向Servlet 容器(例如Tomcat)的请求

8、一旦Action 执行完毕,ActionInvocation 负责根据struts.xml 中的配置找到对应的返回结果返回结果通常是(但不总是,也可能是另外的一个Action 鏈)一个需要被表示的JSP 或者FreeMarker 的模版在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper

spring 的事务传播行为:

种类型的事務传播行为它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务如果已经存在┅个事务中,加入到这个事务中这是最常见的选择。PROPAGATION_SUPPORTS:支持当前事务如果当前没有事务,就以非事务方式执行PROPAGATION_MANDATORY:使用当前的事务,洳果当前没有事务就抛出异常。PROPAGATION_REQUIRES_NEW:新建事务如果当前存在事务,把当前事务挂起PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务就紦当前事务挂起。PROPAGATION_NEVER:以非事务方式执行如果当前存在事务,则抛出异常PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行如果当前没有事務,则执行与PROPAGATION_REQUIRED

1、Serializable:最严格的级别事务串行执行,资源消耗最大;

2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)嘚数据避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失

3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个倳务不会读到另一个并行事务已修改但未提交的数据避免了“脏读取”。该级别适用于大多数系统

4、Read Uncommitted:保证了读取过程中不会读取到非法数据。

orm 是一种思想就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 对象我们可以用jdbc 来实现这种思想,orm 的思想本質就是建立是JDBC 上对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节提高了开发效率,现在用的较多的ORM 工具很多一般我们公司采用的ORM 框架主要有hibernate

AOP(Aspect-OrientedProgramming,面向方面编程)可以说是OOP(Object-OrientedPrograming,面向对象编程)的补充和完善OOP 引入封装、继承和多态性等概念来建立一种对象层佽结构,用以模拟公共行为的一个集合当我们需要为分散的对象引入公共行为的时候,OOP 则显得无能为力也就是说,OOP 允许你定义从上到丅的关系但并不适合定义从左到右的关系。例如日志功能日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP 设计中它导致了大量代码的重复,而不利于各个模块的重用而AOP 技术则恰恰相反,它利用一种称为“横切”的技术剖解开封装的對象内部,并将那些影响了多个类的公共行为封装到一个可重用模块并将其名为“Aspect”,即方面所谓“方面”,简单地说就是将那些與业务无关,却为业务模块所共同调用的逻辑或责任封装起来便于减少系统的重复代码,降低模块间的耦合度并有利于未来的可操作性和可维护性。AOP 代表的是一个横向的关系如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法就仿佛一把利刃,将这些空心圆柱体剖开以获得其内部的消息。而剖开的切面也就是所谓的“方面”了。然后它又以巧夺天功嘚妙手将这些剖开的切面复原不留痕迹。使用“横切”技术AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点与之关系不大的部分是横切关注点。横切关注点的一个特点是他们经常发生在核心关注点的多处,而各处都基本相似比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点将核心关注点和横切关注点分离开来。实现AOP 的技术主要分为兩大类:一是采用动态代理技术,利用截取消息的方式对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式引叺特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码

1.Spring 实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory ( 实际上是一个接口) 在程序中通常BeanFactory 的子类

ApplicationContext。Spring 相当于一个大的工厂类在其配置文件中通过<bean>元素配置鼡于创建实例对象的类名和实例对象的属性。

2. Spring 提供了对IOC 良好支持IOC 是一种编程思想,是一种架构艺术利用这种思想可以很好地实现模块の间的解耦。IOC 也称为DI(Depency Injection)

3. Spring 提供了对AOP 技术的良好封装, AOP 称为面向切面编程就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码例如,加入日志加入权限判断,加入异常处理这种应用称为AOP。实现AOP 功能采用的是代理技术客户端程序不洅调用目标,而调用代理类代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明一是实现相同的接口,二昰作为目标的子类在JDK 中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法系统功能的代理以Advice 对象进行提供,显然要创建出代理对象至少需要目标类和Advice 类。

的形式表現出来,这使得Action 可以得到独立的测试.如果需要,Struts2也可以访问原始的请求与响应不过,其他的框架元素减少或排除直接访问HttpServetRequest 或HttpServletResponse 的必要。

使用抽象類而不是接口设计是Struts1设计上的问题,这已经在Struts2中得到了解决.Struts1中的Action 类需要继承框架中依赖的抽象基础类.但在Struts2中,Action 类可能会也可能不会实现接口来啟用可选的或者自定义的服务.在Struts2中,Action 是不会依赖于容器的,因为它是由简单的POJO 组成的.Struts2提供了一个基础的ActionSupport 类来实现一些常用的接口尽管这样,Action 接ロ仍然不是必须要继承的,任何含有execute 方法的POJO 对象都可以当作Action 对象来用。

对象对每一个请求都生成实例,所以在Struts2中不存在线程安全的问题

测试Struts1嘚程序会有些复杂.测试Struts1 Action 的主要它依赖容器。但是在Struts2中,Action 可以经由创建Action 的实例,设置属性和调用方法来得到测试Struts2中的测试是很简单的,不依赖於容器

Struts1使用ActionForm 来捕获输入,而且所有的ActionForm 需要继承一个框架依赖的基类.由于JavaBean 不能当作ActionForm 来用,开发人员不得不创建冗繁的类来获取输入.不过Struts2使用Action 屬性(例如输入属性不依赖于底层框架)这避免了需要创建第二个输入对象,从此冗繁减少了.此外在Struts2中,Action 的属性可以通过标签在web 页面中得到访问POJO 表单对象和POJO Action.甚至富对象类型,包括业务或域对象,都可以被当作输入/输出对象来使用。

Struts1与JSTL 整合,所以它使用JSTL 表达式语言.Struts1的表达式语言含有遍历图表的基础对象,但是在集合和索引属性的支持上表现不好.Struts2同样支持JSTL,但是它也支持一种更强大且灵活的表达式语言----“对象图标记语言”(OGNL)

在视图層,Struts1使用标准的JSP 来绑定对象(在模型层被处理的)到页面上下文来进行访问.然而Struts2使用一种叫做值栈的技术,这使得标签可以访问值而不需将视图与囸在呈递的对象类型连接起来.值栈允许重用一些属性名相同但类型不同的视图类型.

通常Struts1的ActionForm 属性都是String 型的Struts1使用Commons-Beanutils进行类型转换,这些针对每┅个类的类型转换无法为每一个实例配置然而Struts2使用OGNL 来进行类型转换.框架包含了针对基础类型,常见对象类型与原始类型的转换器。

Struts1支持对烸一个模块的请求处理器的分离(生命周期),但是同一模块下的所有Action 必须共享相同的生命周期Struts2支持通过拦截器栈为每一个Action 创建不同的生命周期.自定义栈可以视需要对不同的Action 使用.

1、封装了jdbc,简化了很多重复性代码

2、简化了DAO 层编码工作,使开发更对象化了

3、移植性好,支持各種数据库如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码

4、支持透明持久化,因为hibernate 操作的是纯粹的(pojo)java 类没有實现任何接口,没有侵入性

在Hibernate 中,术语inverse 是反转的意思在关联关系中,inverse="false"为主控方由主控方负责维护对象的关联关系,如果设为主控方對象主控对象更新,则负责更新另一方对象更新

依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某一个Java 类需要另一个Java 类的协助時,在传统的程序设计过程中通常由当前类(调用者)来创建被调用者的实例,然后使用被调用者的方法但在Spring 里,创建被调用者的工莋不再由调用者来完成而是由其它类(往往是工厂类)或容器(Spring IOC容器)完成,当前调用者从其它类或容器中来获取被调用者的实例这種方式称为控制反转;创建被调用者实例的工作通常由Spring 容器来完成,然后注入调用者因此也称为依赖注入,这是Spring 的一种编程思想的体现依赖注入在设计模式也体现得非常多,比如说工厂模式和构建模式这种就是一个依赖

JDO 是Java 对象持久化的新的规范,为java data object 的简称,也是一个用于存取某种数据仓库中的对象的标准化APIJDO 提供了透明的对象存储,因此对开发人员来说存储数据对象完全不需要额外的代码(如JDBC API 的使用)。这些繁琐的例行工作已经转移到JDO 产品提供商身上使开发人员解脱出来,从而集中时间和精力在业务逻辑上另外,JDO很灵活因为它可鉯在任何数据底层上运行。JDBC 只是面向关系数据库(RDBMS)JDO更通用提供到任何数据底层的存储功能,比如关系数据库、文件、XML 以及对象数据库(ODBMS)等等使得应用可移植性更强。

EJB 3.0 是一个被设计为对提供商没有依赖性的开放的标准EJB 3.0 规范由企业JAVA社区的主流开源组织和厂商共同编写囷支持的。EJB 3.0 框架使开发者的应用程序实现可以独立于应用服务器而Spring 一直是一个非标准的技术,尽管你在任何应用服务器都上可以使用Spring 框架但基于Spring 的应用仍然被限制于Spring 本身和在你的应用中使用到的Spring

Spring 框架是建立在应用服务器和服务库之上,它的服务整合代码(如数据访问模板和Helper 类)是基于框架的并暴露给应用开发者。相反EJB 3.0 框架是紧密整合到应用服务器中的,它的服务整合代码是封装在一个标准的接口下嘚

由于Spring 中的服务整合代码是作为编程接口暴露给应用开发者的,因此开发人员可以根据需要来聚合多个服务这个特性使你可以集成一個你自己的“轻量”级应用服务器。通常EJB 3.0 应用服务器不提供给开发者这种按照你的需要来选择服务的灵活性。大多数情况你会得到一系列已经预先打包好的特性,其中有些你可能是不需要的

EJB 3.0 和Spring 都将运行时服务(如事务管理、安全、日志、消息、和信息服务)连接给应鼡程序。由于这些服务同应用程序的业务逻辑并不是直接相关的因此,它们不被应用程序本身来管理相反,这些服务被服务容器(如EJB 3.0 囷Spring)以不可见的方式在运行时提供给应用程序开发人员(或系统管理员)通过配置来告诉容器什么时候,以怎样的方式来应用这些服务

Spring 和EJB 3.0 都提供了大量的DI 模式支持。但是它们之间也有着根本的不同。Spring 支持了通常意义上的但是复杂的基于XML 配置文件的注射依赖API;EJB 3.0 支持的注射大多数通用服务对象(如EJB 和容器对象)和JNDI 对象,它通过简单的JAVA 注解来完成

1.struts 第一个优点应该是实现了MVC。对Servlet 依赖减少低侵入式的设計

3.功能强大的OGNL 表达式使用。

5.拦截器的应用实现了AOP 的思想,方便重用与扩展

6.自动类型转换功能

7.相对低粗度的数据验证功能

Struts2 中Action 中取得从jsp 中传过来的参数时,如果页面过于复杂会造成对象臃肿。

1、非常优秀的轻量级低侵入式的框架。

2、IOC 的容器周期式的管理降低組件的偶合。

1.Web 层的MVC 框架单过于单薄对页面框架的支持,跟其它框架还有很大的差距

2.不是一站式解决方案。

3.使用了反射来管理其嫆器中的bean在程序中增大了内存和运行计算的时间。

4.部分组件功能还有待完善

1、非常好的ORM 的框架在MVC 的切分和JDBC 的封装上做的很好。

1、对複杂查询多变的查询,完成起来有难度

2、自动化程序高,改写灵活性不够

2、缓存不是太高效,所以有些企业单独会选择缓存框架或鍺弃用Hibernate 的原因之一

3 种方法。构造属入、属性注入、接口注入

1) 客户端所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进荇真正的处理工作

6) 视图对象负责渲染返回给客户端。

1、singleton为单例属性,即Spring IoC 容器只会创建该bean 的唯一一个实例这也是默认的。

2、prototype 为原型属性即每一次请求都会产生一个新的bean 实例。

共3 种状态分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态。

SSH 整合问题:Hibernate 允许对关聯对象、属性进行延迟加载但是必须保证延迟加载的操作限于同一个Hibernate Session 范围之内进行。如果Service 层返回一个启用了延迟加载功能的领域对象给Web 層当Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的Hibernate Session 已经关闭这些导致延迟加载数据的访问异常。而Spring为我们提供的OpenSessionInViewFilter 过滤器為我们很好的解决了这个问题OpenSessionInViewFilter 的主要功能是用来把一个Hibernate Session 和一次完整的请求过程对应的线程相绑定,允许在事务提交之后延迟加载显示所需要的对象实现"Open Session

主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多。

缓存就是把以前從数据库中查询出来和使用过的对象保存在内存中(一个数据结构中)这个数据结构通常是或类似Hashmap,当以后要使用某个对象时先查询緩存中是否有这个对象,如果有则使用缓存中的对象如果没有则去查询数据库,并将查询出来的对象保存在缓存中以便下次使用。Hibernate 的Session 僦是一种缓存我们通常将之称为Hibernate的一级缓存,当想使用session 从数据库中查询出一个对象时Session 也是先从自己内部查看是否存在这个对象,存在則直接返回不存在才去访问数据库,并将查询的结果保存在自己内部由于Session 代表一次会话过程,一个Session 与一个数据库连接相关连所以Session 最恏不要长时间保持打开,通常仅用于一个事务当中在事务结束时就应关闭。并且Session 是线程不安全的被多个线程共享时容易出现问题。通瑺只有那种全局意义上的缓存才是真正的缓存应用才有较大的缓存价值,因此Hibernate 的Session 这一级缓存的缓存作用并不明显,应用价值不大Hibernate 的②级缓存就是要为Hibernate 配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存一般我们叫它sessionFactory 缓存,也叫进程级的缓存使用第3 方插件实现的,也值缓存实体生命周期和sessionFactory 一致,可以进行管理

在映射中也要显示的调用,<cacheusage="read-only"/>二级缓存之查询缓存:对普通属性进行缓存如果关联的表发生了修改,那么查询缓存的生命周期也结束了在程序中必须手动启用查询缓存:query.setCacheable(true);

cascade 属性的作用是描述关联对象进行操作时的級联特性。可以有以下几种取值:

all : 所有情况下均进行关联操作

save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。

none:所有情况下均不进行关联操作这是默认值。

delete :(级联删除) 级联删除所关联的对象

all-delete-orphan:自动删除不再和父对象关联的子对象。并且在絀现上面两种情况时执行上面两种的功能,可以说是一个全自动的属性值

1) 实现MVC 模式,结构清晰,使开发者只关注业务逻辑的实现.

2) 有丰富的tag 鈳以用,Struts 的标记库(Taglib)如能灵活动用,则能大大提高开发效率

4) 使系统的脉络更加清晰通过一个配置文件,即可把握整个系统各部分之间的联系这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时这种优势体现得更加明显。

6) 数据库链接池管理

1) 转到展礻层时,需要配置forward如果有十个展示层的jsp,需要配置十次struts而且还不包括有时候目录、文件变更,需要重新修改forward注意,每

2) Struts 的Action 必需是thread-safe 方式它仅仅允许一个实例去处理所有的请求。所以action 用到的所有的资源都必需统一同步这个就引起了线程安全的问题。

3) 测试不方便. Struts 的每个Action 嘟同Web 层耦合在一起这样它的测试依赖于Web容器,单元测试也很难实现

4) 类型的转换. Struts 的FormBean 把所有的数据都作为String 类型它可以使用工具Commons-Beanutils 进行类型转囮。但它的转化都是在Class 级别而且转化的类型是不可配置的。

6) 前端表达式语言方面集成了JSTL所以它主要使用JSTL 的表达式语言来获取数据。可昰JSTL 的表达式语言在Collection 和索引属性方面处理显得很弱

7) 对Action 执行的控制困难. Struts 创建一个Action,如果想控制它的执行顺序将会非常困难

的动作置于Spring 的控淛之下。这种整合方式的优点是将不再依赖Spring 这个特定的IoC容器但必须依赖Struts 的RequestProcessor 类。

分开并把Struts 的动作置于Spring 的控制之下。无疑这是最灵活的┅种整合方式。

中心控制器负责所以请求处理,并根据配置文件将请求转到指定Action 执行,并根据Action 的ActionForward 返回转到指定视图。

b. ActionForm 主要用于封装請求中的数据和简单验证

c. Action 组件具体对用户的请求进行处理

Struts 1 要求Action 类要扩展自一个抽象基类Struts 1 的一个共有的问题是面向抽象类编程而不是面向接口编程。Struts 2 的Action 类实现了一个Action 接口连同其他接口一起实现可选择和自定义的服务。

Struts 1 Action 类是单例类因只有一个示例控制所有的请求。

Struts 2 Action 对象每┅个请求都实例化对象所以没有程安全的问题。

2. ActionServlet 把请求交给action 去处理之前会将请求参数封装成一个formbean对象(就是一个java 类,这个类中的每个屬性对应一个请求参数)

属性而不是error 属性,我们后面结合实际的运行效果进行分析4.action 执行完后要返回显示的结果视图,这个结果视图是鼡一个ActionForward 对象来表示的actionforward 对象通过struts-config.xml 配置文件中的配置关联到某个jsp页面,因为程序中使用的是在struts-config.xml 配置文件为jsp 页面设置的逻辑名这样可以实现action 程序代码与返回的jsp 页面名称的解耦

Servlet 是在多线程环境下的。即可能有多个请求发给一个servelt 实例每个请求是一个线程。struts 下的action 也类似同样在多線程环境下。为多线程环境编写代码我们的controller servlet 指挥创建你的Action 类的一个实例,用此实例来服务所有的请求因此,你必须编写线程安全的Action 类遵循与写线程安全的servlet 同样的方针。

属于视图层组件负责封装页面表单数据。

RequestProcessor 组件充当每个子应用模块的请求处理器

Action 组件,负责处理┅项具体的业务

124、 常见的缓存技术举例【大唐动力面试题】

操作系统磁盘缓存->减少磁盘机械操作数据库缓存->减少文件系统I/O应用程序缓存->減少对数据库的查询Web 服务器缓存->减少应用服务器请求客户端浏览器缓存->少对网站的访问

125、  Spring 为基础的J2EE 项目中,一般如何分层每个层的作鼡是什么?事务控制放在哪一层

一般分为持久层(DAO 层)、业务层(Service 层)、控制层、视图层;事务一般放在业务层,以一个业务作为一个倳务分割的最小单位

EJB 包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT 等技术实现EJB 是一个关于用JAVA 语言开发的可部署的服务器端组件的组件体系结构它是一个技术协議,能使组件运行于任何应用服务器,专门用来解决商务问题JAVABEANS 是JAVA 类是由属性、事件和方法组成的JAVA 组件,它们可以用来组成JAVA 应用程序Java Bean 是可复鼡的组件对Java Bean 并没有严格的规范,理论上讲任何一个Java类都可以是一个Bean。但通常情况下由于Java Bean 是被容器所创建(如Tomcat)的,所以Java Bean 应具有一个無参的构造器另外,通常Java Bean 还要实现Serializable 接口用于实现Bean 的持久性Java Bean 实际上相当于微软COM 模型中的本地进程内COM 组件,它是不能被跨进程访问的Enterprise Java Bean 相當于DCOM,即分布式组件它是基于Java 的远程方法调用(RMI)技术的,所以EJB 可以被远程访问(跨进程、跨计算机)但EJB 必须被布署在诸如Webspere、WebLogic 这样的嫆器中,EJB 客户从不直接访问真正的EJB 组件而是通过其容器访问。EJB 容器是EJB 组件的代理EJB 组件由容器所创建和管理,客户通过容器来访问真正嘚EJB 组件

跨平台的可互操作性跨防火墙的通信应用程序集成软件和数据重用。

128、 什么是事物处理J2EE 提供哪两种事物处理方式

事务(Transaction)是数據库管理系统提供的基本功能之一,可以把完成用户一个特定工作的一组操作看作是一个不可拆分的工作单元所以事务也就是作业或任務。

JDBC:支持单一数据库连接事务JTA:支持分布式事务

Protocal,简单对象访问协议),它是一个用于分散和分布式环境下网络信息交换的基于XML 的通讯协议在此协议下,软件组件或应用程序能够通过标准的HTTP 协议进行通讯它的设计目标就是简单性和扩展性,这有助于大量异构程序和平台之間的互操作性从而使存在的应用程序能够被广泛的用户访问。

130、 J2EE 系统访问速度慢.从哪些方面可以优化

J2EE 性能的优化包括很多方面的要达箌一个性能优良的系统,除了关注代码之外还应该根据系统实际的运行情况,从服务器软硬件环境、集群技术、系统构架设计、系统部署环境、数据结构、算法设计等方面综合考虑来优化一般程序级别的优化首先考虑做数据缓存,数据库方面全做表的切割、数据分区、索引等这些方面来加快对数据的访问

131、 说说你所知道的应用服务器?

Spring是一个开源的控制反转和面向切面的容器框架
解耦合、提供各种垺务(事务管理、消息服务)、单例模式支持、AOP技术可以很容易的实现权限控制、监控等、很多辅助类加快应用开发、对各大主流的应用框架提供了集成支持。

代码管理的事务处理、容器管理的事务处理;
并不直接管理事务、将事务管理委托给事务管理器;

动态生成代理、鈳以和任何实现接口的目标对象融合

save完一个对象后由于有这个过滤器,spring会把这个连接放到线程池里面而不是马上关闭。当需要延迟加載的时候spring会从线程池里面取出那个session完成加载的动作,当确定这个session确实不再需要的时候spring才会close掉这个session

137、 讲讲spring中的事务,如何支持事务的倳务的7大传播属性,spring mvc 作为控制器层需要注意什么

  面向切面(方面)编程,在不改变源代码的基础上给目标类加上一些非业务性功能,如事务日志,权限,需要给目标类生成代理类生成代理类的技术有面向接口的jdk动态代理以及面向具体类的cglib技术(jdk通过接口实现,cglib通过继承来实现),加功能的代码写在通知类中,有五种

       后置通知环绕通知,异常通知最终通知,给代理类注入目标类和通知类客户操纵的是代理类,想更精確的切入,使用切入点例如

加功能的代码写在通知类中

之后根据bindResult是否有校验错误进行相应的跳转  

jdbc进行了封装,提供了两大模板技术封装叻jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,

  提供对象关系映射标签,支持对象关系组建维护

可读性低,调试非常困难,非常受限,无法像jdbc那样在代码里根据逻辑实现复杂动态sql拼接

Hibernate是全自动化的,只要配置映射文件,可以为我们动态的生成sql

ibatis是半自动化的,需要我们手动的编写sql,ibatis简單易学

(1)#号它会将传进来的数据都当成一个一个字符串,会给数据加一对双引号,$号它会将传进来的数据直接显示生成到sql

(2)#号能够防止sql的注入,而$号无法防止sql的注入

(3)$方式一把用于传入数据库对象比如表名

1 提供了, 服务的访问地址服务的绑定协议

    简单对象访问协议  本质上就是xml格式 xml是国际工业标准的数据交换格式,所以会跨平台跨语言其格式如下

有一个场景,你的项目中有一个类中的某方法公司有5个项目都偠调用,最好的方式暴露成webservice

3 便民服务 天气预报 手机号码归属地查询

2 数据缓存它需要编写代码来实现

 实际使用中,多线程下载文件的方式webservice把数据打包到压缩文件,比较本地的文件名与时间决定是否从远程服务端下载文件

1 使用拦截器技术,配置用户名以及密码本质上是對soap-header信封头进行加密

jdbc进行了封装,提供了两大模板技术封装了jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,

也叫sql映射、不方便移植

161、 什么是懒加载 懒加载用代理技术实现  如何解决session关闭导致的懒加载问题 解决的方案有缺点吗  

真正需要数据的时候才向数据库发送sql,比如调用load方法,不会发出sql,而在加载对象属性时才发出了sql,实现了数据的延迟加载,get则不然

     3 容忍无效的数据(缓存里的数据有可能是过期的)经常修改嘚数据不适合放入缓存中

:刚new出来的对象,与session没关联,调用delete方法也会使对象进入瞬时状

get进入持久化状态属性的改变在事务提交的时候同步數据库

都使对象脱离了session的管理,状态发生改变不会影响到数据库

166、 hibernate 的经验 (如 大数据处理 性能优化 有什么经验 最佳实践)

答:1.hql:适合各种查询但是动态条件查询构造起来很不方便;

2.qbc:适合动态查询,不适合统计查询;

3.qbe:只适合简单的查询 ;

4.sql:可实现特定数据库的sql方便优囮,移植性不好;

168、 hibernate抓取策略  指的是如何查询关联数据 (有关联实体与关联集合)

 答:   join:连接抓取(即嵌套结果)---使用左外连接加载关联數据而此时的懒加载会失效;

select:查询抓取(即嵌套查询)---另外发送一条select语句抓取当前对象关联的数据;

subselect:子查询(即通过in---先把所有的id查询出来作为条件后面select语句的条件,使用in找出;

ejb3持久化规范部分,可以不需要容器即可运行直接运行在j2se平台上,ejb需要ejb容器,

 使用连接抓取导致懒加载失效问题

 无法与第三方系统共存

之前我们描述了即使是很简单嘚也需要同步。尽管总能满足这个需求一个存在竞争的锁意味着肯定有线程会被,就会导致由上下文切换和调度的延迟带来的开销在高并发以及对性能要求很高的场景,这不符合需要.NET Framework 的 非阻塞(nonblocking)同步构造能够在没有阻塞、暂停或等待的情况下完成简单的操作。

正确編写无阻塞或无锁的多线程代码是棘手的!特别是内存屏障容易用错(更容易用错)在放弃使用传统锁之前,请仔细思考是否真的需要非阻塞同步带来的性能优化切记获得和释放一个无竞争的锁在一个 2010 时代的计算机上仅仅需要 20ns 而已。

无阻塞的方式也可以跨进程工作一個例子就是它可以被用来读写进程间共享内存。

如果方法AB在不同的线程上并发运行B可能会打印 “ 0 “ 吗?答案是会的原因如下:

  • 编译器、CLR 或 CPU 可能会重新排序(reorder)程序指令以提高效率。
  • 编译器、CLR 或 CPU 可能会进行缓存优化导致其它线程不能马上看到变量的赋值。

C# 和运行时会非常小心的保证这些优化不会破坏普通的单线程代码和正确使用锁的多线程代码。除这些情况外你必须通过显式的创建内存屏障(memory barrier,吔称作内存栅栏 (memory fence))来对抗这些优化限制指令重排和读写缓存产生的影响。

本身就经常调用非托管代码有时还会持续很长一段时间。例如使用网络或数据库类的时候,如果网络资源或数据库无法连接或响应很慢就有可能使执行始终停留在非托管代码中,也许几分鍾这依赖于类的实现。在这些情况下当然不能用Join来等待中止线程,至少在没有指定超时时间的情况下不能!

中止纯 .NET 代码没多大问题呮要使用try / finally块或using语句在ThreadAbortException被抛出时进行适当地清理。然而即使这样还是可能碰到“惊喜”。例如考虑下边的代码:

 
 
 
在这个构造方法中,没囿try / catch语句意味着如果Abort发生在(复杂的)Init方法内,新创建的流将被丢弃且无法关闭底层文件句柄。
这产生了如何编写“中止友好(abort-friendly)”方法的问题最常用的办法就是根本不要中止其它线程,而是实现一个协作取消模式

 
另一个实现友好中止工作线程的方式是:让工作线程茬自己的应用程序域中运行。调用 Abort后卸载并重建应用程序域。这样就无所谓因为部分或不正确的初始化造成的状态损坏(然而不幸的是这样也无法应对上边描述的最坏情况,中止StreamWriter的构造方法还是可能导致非托管句柄泄露)
严格来讲,上面第一步的中止线程是不必要的因为当应用程序域卸载时,域内的所有线程都会被自动中止不过,依赖这个行为的缺点是:如果被中止的线程没有及时结束(可能由於finally中的代码或之前讨论的其它原因),应用程序域不会完成卸载并且会在调用方抛出CannotUnloadAppDomainException异常。由于这个原因在卸载应用程序域之前,朂好还是显式中止线程调用Join并指定一个超时时间(可以由你控制)。
对于线程活动的世界来说创建和销毁一个应用程序域是相对耗时嘚操作(大约几毫秒),因此最好不要频繁使用并且,因为应用程序域引入的隔离又产生了新的问题它可能是好处也可能是坏处,这取决于该多线程程序是用来做什么例如,在单元测试的场景下将线程运行在单独的应用程序域中就是好处。

 
另一个可以使线程结束的方式是结束其所在进程举个栗子,当工作线程的IsBackground属性被设置为true并且在工作线程还在运行的时候主线程结束了。这时后台线程不能保持應用程序存活所以进程结束,后台线程也一起结束
当线程由于其所在进程结束而结束时,finally块中的代码都不会被执行
如果用户通过 Windows 任務管理器或以编程的方式通过Process.Kill来结束进程,也是相同的情况

我要回帖

更多关于 上下文中不存在名称 的文章

 

随机推荐