SSH常识问题

Struts2

1、为什么每次请求都要创建一个Action对象?

是出于对线程安全的考虑,每次请求的时候都会创建一个action的实例,这样会保证线程的安全。Struts1只是在第一次请求的时候创建一个action的实例,以后每次相同的请求都直接从内存中去读取,它是单例模式,多线程情况下不安全。

2、ModelDriven拦截器的配置中refreshModelBeforeResult解决了什么?

更新ValueStack中的model对象,先把旧的model对象从ValueStack中移除,然后再把新的model对象压进ValueStack!
官方解释:
set to true if you want the model to be refreshed on the value stack after action execution and before result execution. The setting is useful if you want to change the model instance during the action execution phase, like when loading it from the data layer. This will result in getModel() being called at least twice.

3、为什么在web.xml中配置的StrutsPrepareAndExecuteFilter要过滤所有的请求?

实在这里可以选择性的过滤,但是一般大家都是<url-pattern>/*</url-pattern>,所有的请求都必须经过StrutsPrepareAndExecuteFilter这个请求转发器。 它会往找struts.xml文件,一般放在src下面的第一层目录,然后找到相应的资源往转发。

4、请你给我谈谈ValueStack?

所谓值栈就是在一个栈里面堆了一大坨的数值,在action中可以这样获得ValueStack vs1 = ActionContext.getContext().getValueStack();
实在值栈就类似于一个map的容器,里面存放的是键值对,但是有个区别,这个值栈的键都是String类型的。我们一般可以这样来拿出值栈里面的内容
名字属性获取 :<s:property value="user.username"/> 也可以用el表达式${aa}或者ognl表达式<s:property value="#request.user.username"/>
其中ognl表达式主要就是往访问值栈,它的查找路线为用于按request > session > application顺序访问其属性(attribute),#user.username相当于按顺序在以上三个范围(scope)内读取user.username属性,直到找到为止。

5、Struts2是如何实现MVC设计模式的?

准确的说Struts2集中体现在VC两层,然而Model层应该是有如Spring、JavaBean等具体实现的。当用户发送request,请求首先经过拦截器,至核心控制器查找Action并转发,这一部分可以叫做控制器层,由拦截器、核心控制器实现,然后由业务控制器Action处理或调用底层Model处理请求,这一部分可以叫做业务层,由具体用户业务逻辑实现,最后处理完毕后,返回结果页面逻辑路径,生成Result对象,根据配置的模版技术生成用户响应,这一部分可以叫做View层,由各模版技术支持实现,包括:Jsp、Freemarker、Velocity等。

Spring

1、你为什么要用Spring?

其实最关键使用Spring的AOP、IOC功能,可以实现日志、权限控制、对象管理、安全机制等功能,最主要的是可以降低耦合。Spring还可以作为粘合剂,将多种框架集成在一起使用,如Struts2、Hibernate,这样不仅降低了开发量,而且也降低了耦合度,使得Struts2、Hibernate无须耦合,就可以做到之间的调用及数据传输。

2、请你聊一聊IOC/DI?

依赖注入和控制反转Spring的两大基础作用主要是将所有组件在Spring提供的外部容器中加载,提高安全性,减低耦合性,使各个框架或者类之间的依赖性降低。

3、什么是声明式的事务管理?为什么要使用声明式的事务管理?Spring如何实现声明式的事务管理?

声明事物管理主要是将在进行对数据库中数据进行添加或者修改的时候需要执行事物管理。主要是避免在执行数据修改和添加的时候数据添加或者修改不完全,导致数据丢失。

Spring 的声明式事务治理的底层是建立在 AOP 的基础之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加进一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。 使用声明式的事务治理可重用性高。

4、把spring和hibernate集成,定义事务管理特性的时候,为何要将除了添加、删除、更新操纵之外的方法,即主要执行查询任务的方法定义为read-only?

因为添加和删除和更新都涉及到数据库的修改,而查询并为涉及数据修改,所以只需要定义只读,这样可以提高效率,进行更加方便的事物管理。而事务管理主要是为添加和删除和更新设计的。

Hibernate

1、请你谈谈你对OR映射的理解?

对象关系映射,把关系数据库的数据结构与你的对象关联起来,以操纵对象操纵关系数据库。

2、很多人说Hibernate不适合大项目,性能有问题,你是如何理解的?

因为Hibernate属于大型框架,里面对许多方法的封装比较多,让SQL控制权降低。这样的话,适用性就会降低,在不必要的操作上会浪费时间。但是只要将Hibernate里的配 置进行优化,也能提高其性能。但不一定用了hibernate就不使用sql了,一些复杂的比如说统计需要的数据一般都是直接用sql执行的。使用hibernate最重要的一点是看你如何使用懒加载,在适当的时候使用懒加载会进一步提高性能。

3、Hibernate为什么一定要定义一个数据库标识 ?

可以让映射文件变得简洁,消除无用的噪音(比如TBL_前缀等)。Hibernate使用的默认策略是几乎什么都不做,所以使用标识的作用就是使数据操作更加简洁和方便

4、为什么Hibernate建议你的实体类实现hashCode和equals方法?

多对多双向关系时,假如hashCode和equals正常写之,将出现load不上的问题。经常使用Set集合来保存相关对象,而Set集合是不答应重复的。而hibernate正是用"=="比较两个对象是否是同一个,所以它会用比较hashCode和用equals来比较。

5、谈谈你对Hibernate实体类中的数据库标识与数据库主键之间关系的认识?

数据库标识是为了方便和简洁映射文件,而主键是为了使数据不会重复。

6、谈谈你对Hibernate关联映射与数据库外键之间关系的认识?

关系映射中一个外键就相当于一个对象的实例,这样就形成了1-1 ,1-N,N-1,N-N这种关系。Hibernate在进行映射的时候会将数据库的关系也进行映射将数据库中的外键也使用标签的形式进行管理,这样在人为操作的时候就不需要手动的管理数据库关系了。

7、调用session.save()方法,hibernate一定会发出insert语句吗?谈谈你的理解

save, 把一个瞬态的实例持久化标识符,及时的产生,它要返回标识符,在save之前hibernate会往根据主键查一次,看能否保存。

不会,具体执行步骤如下:

1. 首先在Session内部缓存中进行查找,如果发现则直接返回。

2. 执行实体类对应的Interceptor.isUnsaved方法(如果有的话),判断对象是否为未保存状态。

3. 根据unsaved-value判断对象是否处于未保存状态。

4. 如果对象未保存(Transient状态),则调用save方法保存对象。

5. 如果对象未已保存(Detached状态),则调用update方法将对象与Session重新关联。

8、调用session.update()方法,hibernate一定会发出update语句吗?谈谈你的理解

update是把一个脱管状态的对象或自由态对象(一定要和一个记录对应)更新到数据库。在update之前hibernate会往根据主键查一次,看能否可以更新。 具体执行步骤同上。

9、请你聊一下以下名词、概念或用法:lazy、lazy=”extra”、inverse、fetch、fetch=”join”、fetch=”subselect”、batch-size。

lazy:只有真正使用该对象内普通属性时,才会创建,对于hibernate而言,正真使用的时候才会发出sql,load支持lazy(懒加载),get不支持懒加载。
extra:一种比较聪明的懒加载策略,即调用集合的size/contains等方法的时候,hibernate lazy=”extra”时并不会往加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才往发出查询语句加载所有对象的数据。
inverse:标记由哪一方来维护关联关系(双向关联中会用到,inverse默认值为false。假如inverse设置为true,表示将由对方维护两者之间的关联关系)。
fetch是抓取策略:
fetch = "select"是在查询的时候先查询出一个实体,然后在根据一个查询出多个实体,会产生1+n条sql语句。
fetch = "join"是在查询的时候使用外连接进行查询,不会差生1+n的现象。
fetch = "subselect”发送一条select语句抓取在前面查询到的所有实体对象的关联集合。
batch-size 是来设置批量更新的HQL/SQL数目 假如达到此数目会提交给数据库 但是天生的HQL/SQL语句一个也不会少。

10、配置了lazy=”true”一定会实现懒加载吗?

get()是不能实现懒加载的。必须使用load(),fetch要使用select。

11、请你谈谈Hibernate中的“N+1“问题

一对多是查询一次会带出N次查询。就是一些主外键关系的对象。当进行一个表的查询时,当这个表与另外的表是多对一,或者是一对多关联时,就会出现N+1题目,当查询一条语句时,比如主键name=1,而与这个 name相关联的另一张表对应name的有N个记录,这时就出另外发出N条语句往查询,而我又不要那些记录,这时就是N+1问题。

 

posted on 2013-02-17 16:05  阡陌行者  阅读(251)  评论(0编辑  收藏  举报

导航