javaWeb开发面试题目

1.编码转换:怎样将 GB2312 编码的字符串转换为 ISO-8859-1 编码的字符串 ?
【基础】
答:示例代码如下 :
String s1 = " 你好 ";
String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1");


2.写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分
隔。 【基础】
答:函数代码如下:
public String[] split(String str, int chars){
    int n = (str.length()+ chars - 1)/chars;
    String ret[] = new String[n];


    for(int i=0; i         if(i < n-1){
            ret[i] = str.substring(i*chars , (i+1)*chars);
        }else{
            ret[i] = str.substring(i*chars);
        }
    }
    return ret;
}


3.写一个函数, 2 个参数, 1 个字符串, 1 个字节数,返回截取的字符串,要
求字符串中的中文不能出现乱码:如( “ 我 ABC ” , 4 )应该截为 “ 我 AB ” ,输入 ( “ 我
ABC 汉 DEF ” , 6 )应该输出为 “ 我 ABC ” 而不是 “ 我 ABC+ 汉的半个 ” 。 【基础】
答:代码如下:
public String subString(String str, int subBytes) {
    int bytes = 0; // 用来存储字符串的总字节数
    for (int i = 0; i < str.length(); i++) {
        if (bytes == subBytes) {
            return str.substring(0, i);
        }
        char c = str.charAt(i);
        if (c < 256) {
            bytes += 1; // 英文字符的字节数看作 1
        } else {
            bytes += 2; // 中文字符的字节数看作 2
        if(bytes - subBytes == 1){
            return str.substring(0, i);
        }
        }
    }
    return str;
}


4.List,Set,Map 是否继承自 Collection 接口?【基础】
答: List,Set 是; Map 不是。


5.你所知道的集合类都有哪些?主要方法?【基础】
答:最常用的集合类是 List 和 Map 。
List 的具体实现包括 ArrayList 和Vector ,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的 元素列表。List 适用于按数值索引访问元素的情形.
add(index,element); addAll(index,Collection);remove(index);set(index,element);
get(index);subList(from,to);listIterator();


Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作 “ 键 ” 和 “ 值 ” ),其中每
个键映射到一个值.
1。添加
put(K key, V value)


2。删除
clear()
remove(Object key)


3。判断
containsKey(Object key)
containsValue(Object value)
isEmpty()


4。获取
get(Object key)
size()
values()


entrySet()
keySet()


6.说出 ArrayList,Vector, LinkedList 的存储性能和特性?【基础】
答: ArrayList 和 Vector:数组方式存储数据,索引数据快而插入数据慢
Vector 由于使用了 synchronized 方法(线程安全),通常性能上较 ArrayList 差


LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历 ,
但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。


7.Collection 和 Collections 的区别?【基础】
答: Collection 是 java.util 下的接口,它是各种集合的父接口,继承于它的
接口主要有 Set 和 List ;
Collections 是个 java.util 下的类,是针对集合的帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作 。


8.HashMap 和 Hashtable 的区别 ? 【基础】
答:二者都实现了 Map 接口,是将惟一键映射到特定的值上;主要区别在于:
1)HashMap 没有排序,允许一个 null 键和多个 null 值 , 而 Hashtable 不允许 ;
2)HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsvalue 和
containsKey, 因为 contains 方法容易让人引起误解;
3)Hashtable 继承自 Dictionary 类 , HashMap 是 Java1.2 引进的 Map 接口的实 现 ;
4)Hashtable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问
Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供 外
同步。
Hashtable 和 HashMap 采用的 hash/rehash 算法大致一样,所以性能不会有 很
大的差异。


9.Arraylist 与 Vector 区别?【基础】
答:就 ArrayList 与 Vector 主要从二方面来说:
1 )同步性: Vector 是线程安全的(同步),而 ArrayList 是线程序不安全的;
2 )数据增长:当需要增长时 ,Vector 默认增长一倍,而 ArrayList 却是一半。




10.List 、 Map 、 Set 三个接口,存取元素时,各有什么特点?【基础】
答: List 以特定次序来持有元素,可有重复元素。
Set 无法拥有重复元素,内部排序。
Map 保存 key-value 值,value 可多值。


11.Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢 ? 是用 == 还
是 equals()? 它们有何区别 ? 【基础】
答: Set 里的元素是不能重复的,用 equals () 方法来区分重复与否。 覆盖
equals() 方法 用来判断对象的内容是否相同,而 ” == ” 判断地址是否相等 , 用来
决定引用值是否指向同一对象。


12.sleep() 和 wait() 有什么区别 ? 【基础】
答: sleep 是线程类( Thread )的方法,导致此线程暂停执行指定时间,把执行
机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用 sleep 不 会
释放对象锁。
wait 是 Object 类的方法,对此对象调用 wait 方法导致本线程放
弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出 notify 方法( 或
notifyAll )后本线程才进入对象锁定池准备获得对象锁进入运行状态。


13.请说出你所知道的线程同步的方法。【基础】
答: wait(): 使一个线程处于等待状态,并且释放所持有的对象的 lock ;
sleep(): 使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此 方
法要捕捉 InterruptedException 异常;
notify(): 唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,
并不能确切的唤醒某一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而 且
不是按优先级;
notifyAll(): 唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程 一
个对象的锁,而是让它们竞争。


14.同步和异步有何异同,在什么情况下分别使用他们?举例说明。【基础】
答:如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,
或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,
必须进行同步存取。当应用程序在对象上调用了一个需要花费很长时间来执行 的
方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情 况
下采用异步途径往往更有效率。


15.线程的基本概念、线程的基本状态以及状态之间的关系?【基础】
答:线程指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序 至
少都有一个线程,也就是程序本身;
Java 中的线程有四种状态分别是:运行、就绪、挂起、结束。


96 、 UML 是什么?常用的几种图?【基础】
答: UML 是标准建模语言;常用图包括:用例图 , 静态图 ( 包括类图、对象图和 包
图 ), 行为图 , 交互图 ( 顺序图 , 合作图 ), 实现图。


98 、说说你所熟悉或听说过的 j2ee 中的几种常用模式 ? 及对设计模式的一些看
法。【中等难度】
答: Session Facade Pattern :使用 SessionBean 访问 EntityBean ;
Message Facade Pattern :实现异步调用;
EJB Command Pattern :使用 Command JavaBeans 取代 SessionBean ,实现
轻量级访问;
Data Transfer Object Factory :通过 DTO Factory 简化 EntityBean 数据
提供特性;
Generic Attribute Access :通过 AttibuteAccess 接口简化 EntityBean
数据提供特性;
Business Interface :通过远程(本地)接口和 Bean 类实现相同接口规范
业务逻辑一致性;
EJB 架构的设计好坏将直接影响系统的性能、可扩展性、可维护性、组件 可
重用性及开发效率。项目越复杂,项目队伍越庞大则越能体现良好设计的重要 性 。


99 、 Java 中常用的设计模式?说明工厂模式?【中等难度】
Factory,Singleton,Facade,Decorator,Command,Iterator


答 : Java 中的 23 种设计模式: Factory (工厂模式), Builder (建造模式), Factory
Method (工厂方法模式), Prototype (原始模型模式), Singleton (单例模 式 ),
Facade (门面模式), Adapter (适配器模式), Bridge (桥梁模式), Comp osite
(合成模式), Decorator (装饰模式), Flyweight (享元模式), Proxy ( 代
理模式), Command (命令模式), Interpreter (解释器模式), Visitor ( 访
问者模 式), Iterator (迭代子模式), Mediator (调停者模式), Memento
(备忘录模式), Observer (观察者模式), State (状态模式), Strategy ( 策
略模式), Template Method (模板方法模式), Chain Of Responsibleity ( 责
任链模式)。
工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以 根
据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象 父
类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。 首
先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后 需
要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的 实
例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的 实
例。


100 、开发中都用到了那些设计模式 ? 用在什么场合 ? 【中等难度】
答:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问 题
的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,
无需在重复相同的工作。主要用到了 MVC 的设计模式,用来开发 JSP/Servlet
或者 J2EE 的相关应用;及简单工厂模式等。


101 、你对软件开发中迭代的含义的理解;【中等难度】
答:软件开发中,各个开发阶段不是顺序执行的,应该是并行执行 , 也就是迭代
的意思。这样对于开发中的需求变化,及人员变动都能得到更好的适应。


102 、 XML 文档定义有几种形式?它们之间有何本质区别?解析 XML 文档有哪几
种方式?【基础】
答: 1 )两种形式: dtd 以及 schema ;
2 )本质区别: schema 本身是 xml 的,可以被 XML 解析器解析 ( 这也是从 DT D
上发展 schema 的根本目的 ) ;
3 )解析方式:有 DOM,SAX,STAX 等:
DOM: 处理大型文件时其性能下降的非常厉害。这个问题是由 DOM 的树结
构所造成的,这种结构占用的内存较多,而且 DOM 必须在解析文件之前把整个 文
档装入内存 , 适合对 XML 的随机访问;
SAX: 不同于 DOM,SAX 是事件驱动型的 XML 解析方式。它顺序读取 XML 文
件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签 开
头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码 来
处理 XML 文件,适合对 XML 的顺序访问;
STAX:Streaming API for XML (StAX) 。


103 、你在项目中用到了 xml 技术的哪些方面 ? 如何实现的 ? 【中等难度】
答 : 用到了数据存贮,信息配置两方面。在做数据交换平台时,将不能数据源的
数据组装成 XML 文件,然后将 XML 文件压缩打包加密后通过网络传送给接收者,
接收解密与解压缩后再同 XML 文件中还原相关信息进行处理。在做软件配置时,
利用 XML 可以很方便的进行,软件的各种配置参数都存贮在 XML 文件中。


110 、 数据库,比如 100 用户同时来访,要采取什么技术解决 ?【基础】
答:可采用连接池。C3P0连接池是Hibernate推荐使用的连接池。


126 、说出数据连接池的工作机制是什么 ? 【基础】
答: J2EE 服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的
池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将 其
表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建 连
接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接 表
记为空闲,其他调用就可以使用这个连接。


111 、什么是 ORM ? 【基础】
答:对象关系映射( Object — Relational Mapping ,简称 ORM )是一种为了解 决
面向对象与面向关系数据库存在的互不匹配的现象的技术;简单的说, ORM 是 通
过使用描述对象和数据库之间映射的元数据,将 java 程序中的对象自动持久化
到关系数据库中;本质上就是将数据从一种形式转换到另外一种形式。


112 、 Hibernate 有哪 5 个核心接口?【基础】
答: Configuration 接口:配置 Hibernate ,根据其启动 hibernate ,创建SessionFactory 对象;
SessionFactory 接口:初始化 Hibernate ,充当数据存储源的代理,创建session 对象, sessionFactory 是线程安全的,意味着它的同一个实例可以被 应用的多个线程共享,是重量级、二级缓存;
Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,避免多个线程共享同一个 session ,是轻量级、一级缓存;
Transaction 接口:管理事务;
Query 和 Criteria 接口:执行数据库的查询。


113 、关于 hibernate: 【基础】
1 )在 hibernate 中,在配置文件呈标题一对多,多对多的标签是什么;
2 ) Hibernate 的二级缓存是什么;
3 ) Hibernate 是如何处理事务的;
答: 1 )一对多的标签为 ;多对多的标签为
2 ) sessionFactory 的缓存为 hibernate 的二级缓存;
3 ) Hibernate 的 事务 实际上是底层的 JDBC Transaction 的封装或者是 JTA
Transaction 的封装 ; 默认情况下使用 JDBCTransaction 。


115 、什么是重量级?什么是轻量级?【基础】
答:轻量级是指它的创建和销毁不需要消耗太多的资源,意味着可以在程序中 经
常创建和销毁 session 的对象;
重量级意味不能随意的创建和销毁它的实例, 会占用很多的资源。


117 、事务处理?【基础】
答: Connection 类中提供了 3 个事务处理方法:
setAutoCommit(Boolean autoCommit): 设置是否自动提交事务,默认为自 动
提交事务,即为 true ,通过设置 false 禁止自动提交事务;
commit(): 提交事务;
rollback(): 回滚事务。


118 、 Java 中访问数据库的步骤? Statement 和 PreparedStatement 之间的区别 ?
【基础】
答: Java 中访问数据库的步骤如下:
1 )注册驱动;
2 )建立连接;
3 )创建 Statement ;
4 )执行 sql 语句;
5 )处理结果集(若 sql 语句为查询语句);
6 )关闭连接。
PreparedStatement 被创建时即指定了 SQL 语句,通常用于执行多次结构相
同的 SQL 语句。
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery("select * from user");


122 、说出 Servlet 的生命周期,并说出 Servlet 和 CGI 的区别 ? 【基础】
答: Web 容器加载 Servlet 并将其实例化后, Servlet 生命周期开始,容器运行
其 init 方法进行 Servlet 的初始化,请求到达时运行其 service 方法, servic e
方法自动派遣运行与请求对应的 doXXX 方法( doGet , doPost )等,当服务器决
定将实例销毁的时候调用其 destroy 方法。


与 cgi 的区别在于 servlet 处于服 务
器进程中,它通过多线程方式运行其 service 方法,一个实例可以服务于多个 请
求,并且其实例一般不会销毁,而 CGI 对每个请求都产生新的进程,服务完成 后
就销毁,所以效率上 低于 servlet 。


146 、 Servlet 执行时一般实现哪几个方法?【基础】
答:


 public void init(ServletConfig config)
public ServletConfig getServletConfig()
public String getServletInfo()
public void service(ServletRequest request,ServletResponse
response)
public void destroy()


124 、 forward 和 redirect 的区别 ? 【基础】
答: forward 是容器中控制权的转向,是服务器请求资源,服务器直接访问目 标
地址的 URL ,把那个 URL 的响应内容读取过来,然后把这些内容再发给浏览器,
浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原 来
的地址。
redirect 就是服务端根据逻辑 , 发送一个状态码 , 告诉浏览器重新去 请
求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以
session,request 参数都可以获取,并且从浏览器的地址栏中可以看到跳转后 的
链接地址。


前者更加高效,在前者可以满足需要时,尽量使用 forwa rd() 方法,
并且,这样也有助于隐藏实际的链接;在有些情况下,比如,需要跳转到一个 其
它服务器上的资源,则必须使用 sendRedirect() 方法。






130 、 jsp 有哪些内置对象 ? 作用分别是什么 ? 【基础】
答: JSP 共有以下 9 种基本内置组件(可与 ASP 的 6 种内部组件相对应):
request :用户端请求,此请求会包含来自 GET/POST 请求的参数;
response :网页传回用户端的回应;
pageContext :网页的属性是在这里管理;
session :与请求有关的会话期;
application : servlet 正在执行的内容;
out :用来传送回应的输出;
config : servlet 的构架部件;
page : JSP 网页本身;
exception :针对错误网页,未捕捉的例外。


128 、 JSP 的常用指令?【基础】
答: < %@page language= ” java ” contenType= ” text/html;charset=gb2312 ”
session= ” true ” buffer= ” 64kb ” autoFlush= ” true ” isThreadSafe= ” tr ue ”
info= ” text ” errorPage= ” error.jsp ” isErrorPage= ” true ” isELIgnore d= ”
true ” pageEncoding= ” gb2312 ” import= ” java.sql.* ” %>


isErrorPage :是否能使用 Exception 对象;


isELIgnored :是否忽略 EL 表达式 ;


< %@include file= ” filename ” %>


< %@taglib prefix= ” c ” uri= ” http:// ……” %>


129 、 jsp 有哪些动作 ? 作用分别是什么 ? 【基础】
答: JSP 共有以下 6 种基本动作:
jsp:include :在页面被请求的时候引入一个文件;
jsp:useBean :寻找或者实例化一个 JavaBean 。;
jsp:setProperty :设置 JavaBean 的属性。;
jsp:getProperty :输出某个 JavaBean 的属性;
jsp:forward :把请求转到一个新的页面;
jsp:plugin :根据浏览器类型为 Java 插件生成 OBJECT 或 EMBED 标记。


131 、 get 和 post 的区别?【基础】
答: Form 中的 get 和 post 方法,在数据传输过程中分别对应了 HTTP 协议中的
GET 和 POST 方法。二者主要区别如下:
1 ) Get 是用来从服务器上获得数据,而 Post 是用来向服务器上传递数据;
3 ) Get 是不安全的,因为在传输过程,数据被放在请求的 URL 中; Post 的
所有操作对用户来说都是不可见的;
4 ) Get 传输的数据量小,这主要是因为受 URL 长度限制;而 Post 可以传输
大量的数据,所以在上传文件只能使用 Post ;
6 ) Get 是 Form 的默认方法。


2 ) Get 将表单中数据按照 variable=value 的形式,添加到 action 所指向 的
URL 后面,并且两者使用 “ ? ” 连接,而各个变量之间使用 “ & ” 连接; Post 是 将
表单中的数据放在 form 的数据体中,按照变量和值相对应的方式,传递到 act ion
所指向 URL ;
5 ) Get 限制 Form 表单的数据集必须为 ASCII 字符,而 Post 支持整个 ISO1 0646
字符集;


132 、什么情况下调用 doGet() 和 doPost() ?【基础】
答: Jsp 页面中的 form 标签里的 method 属性为 get 时调用 doGet() ,为 post
时调用 doPost() 。


133 、如何从 form 表单中得取 checkbox 的值;【基础】
答:可在页面把 checkbox 的 name 属性取同一个, value 属性取每个条目的 id,
后台用 getParamter( “ name ” ) 能取到 checkbox 的一组值。


135 、 javascript 常用的方面;【基础】
答:常用于数据输入校验和页面特殊效果等。


136 、常用的 web 容器和开发工具;【基础】
答:最常用的容器包括: tomcat 、 weblogic ;
开发工具有: eclipse,jbuilder 。


138 、 JSP 和 Servlet 有哪些相同点和不同点,他们之间的联系是什么?【基础 】
答: JSP 是 Servlet 技术的扩展,本质上是 Servlet 的简易方式,更强调应用 的
外表表达。 JSP 编译后是 " 类 servlet" 。
Servlet 和 JSP 最主要的不同点在于,
Servlet 的应用逻辑是在 Java 文件中,并且完全从表示层中的 HTML 里分离开 来 。Servlet 主要用于控制逻辑。
而 JSP 的情况是 Java 和 HTML 可以组合成一个扩展名为 .jsp 的文件。 JSP 侧重 于
视图


139 、 jsp 的四种范围?【基础】
答: a.page 是代表与一个页面相关的对象和属性。一个页面由一个编译好的
Java servlet 类(可以带有任何的 include 指令,但是没有 include 动作)
表示。这既包括 servlet 又包括被编译成 servlet 的 JSP 页面
b.request 是代表与 Web 客户机发出的一个请求相关的对象和属性。一个
请求可能跨越多个页面,涉及多个 Web 组件(由于 forward 指令和 include 动
作的关系)
c.session 是代表与用于某个 Web 客户机的一个用户体验相关的对象和属
性。一个 Web 会话可以也经常会跨越多个客户机请求
d.application 是代表与整个 Web 应用程序相关的对象和属性。这实质上
是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域。


140 、 Request 对象的主要方法 ? 【基础】
答: setAttribute(String name,Object) :设置名字为 name 的属性值
getAttribute(String name) :返回由 name 指定的属性值
removeAttribute(String name) :删除请求中的一个属性
getAttributeNames() :返回 request 对象所有属性的名字集合 ( 枚举 )


getCookies() :返回客户端的所有 Cookie 对象,结果是一个 Cookie 数组


getSession([Boolean create]) :返回和请求相关 Session


getParameter(String name) :获得客户端请求中传送的 name 指定的参数 值
getParameterNames() :获得客户端传送给服务器端的所有参数的名字 ( 枚
举 )


getServerName() :获取服务器的名字第 41 页 共 59 页
getServletPath() :获取客户端所请求的脚本文件的路径
getServerPort() :获取服务器的端口号


getCharacterEncoding() :返回请求中的字符编码方式
getContentLength() :返回请求的 Body 的长度
getHeader(String name) :获得 HTTP 协议定义的文件头信息
getHeaders(String name) :返回指定名的 request Header 的所有值 ( 枚举 )
getHeaderNames() :返回所有 request Header 的名字 ( 枚举 )
getInputStream() :返回请求的输入流,用于获得请求中的数据
getMethod() :获得客户端向服务器端传送数据的方法
getParameterValues(String name) :获得有 name 指定的参数的所有值
getProtocol() :获取客户端向服务器端传送数据所依据的协议名称
getQueryString() :获得查询字符串
getRequestURI() :获取发出请求字符串的客户端地址
getRemoteAddr() :获取客户端的 IP 地址
getRemoteHost() :获取客户端的名字


143 、详细描述 MVC 。【基础】
答:基于 Java 的 Web 应用系统采用 MVC 架构模式,即 model (模型)、 view ( 视
图)、 control (控制)分离设计;这是目前 WEB 应用服务系统的主流设计方向 。
Model :即处理业务逻辑的模块,每一种处理一个模块;
View :负责页面显示,显示 MODEL 处理结果给用户,主要实现数据到页面 转
换过程;
Control :负责每个请求的分发,把 FORM 数据传递给 MODEL 处理,把处理 结
果的数据传递给 VIEW 显示。


144 、 MVC 的各个部分都有那些技术来实现 ? 如何实现 ? 【基础】
答: MVC 是 Model - View - Controller 的简写。
"Model" 代表的是应用的业务 逻辑(通过 JavaBean , EJB 组件实现)
"View" 是应用的表示面(由 JSP 页面 产生)
"Controller" 是提供应用的处理过程控制(一般是一个 Servlet ),通
过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些 组
件可以进行交互和重用。


145 、应用服务器有那些?【基础】
答: BEA WebLogic Server, IBM WebSphere Application Server, Oracle9i
Application Server, JBoss, Tomcat 。




147 、 struts 的入口类?【基础】
答:是 ActionServlet ,所有的 struts 请求都经由该类转发处理。


148 、 STRUTS 的应用 ( 如 STRUTS 架构 ) ?【基础】
答: Struts 是采用 Java Servlet/JavaServer Pages 技术开发 Web 应用程序的
开放源码的 framework 。 采用 Struts 能开发出基于 MVC(Model-View-
Controller) 设计模式的应用构架。 Struts 有如下的主要功能:
1) 包含一个 controller servlet ,能将用户的请求发送到相应的 Action 对 象 ;
2)JSP 自由 tag 库,并且在 controller servlet 中提供关联支持,帮助开发
人员创建交互式表单应用;
3) 提供了一系列实用对象: XML 处理、通过 Java reflection APIs 自动处理
JavaBeans 属性、国际化的提示和消息。


149 、几种会话跟踪技术?【基础】
答: cookie 、 URL 重写、设置表单隐藏域。


151 、过滤器有哪些作用?【基础】
答:可以验证客户是否来自可信的网络
可以验证用户是否登录
可以过滤掉客户的某些不应该出现的词汇
可以从系统里获得配置的信息
可以记录系统的日志等等


可以对客户提交的数据进行重新编码
可以验证客户的浏览器是否支持当前的应用


152 、过滤器的用法?(对客户端的请求统一编码和对客户端进行认证)【基础 】
答:首先要实现( implements ) Filter 接口,同时覆盖 Filter 接口的三个方 法 :
init(FilterConfig config) // 用于获得 FilterConfig 对象;
doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) // 进行过滤处理一些业务;
destroy() // 销毁 Filter 。


146 、 Servlet 执行时一般实现哪几个方法?【基础】
答: public void init(ServletConfig config)
public ServletConfig getServletConfig()
public String getServletInfo()
public void service(ServletRequest request,ServletResponse
response)
public void destroy()


153 、简述 HttpSession 的作用、使用方法,可用代码说明。( 3 分钟)【基础 】
答: HttpSession 中可以跟踪并储存用户信息,把值设置到属性中,有 2 个方 法 :
setAttribute(),getAttrribute() ;
例如:在一个方法中用 session.setAttribute( “ student ” ,student); 在
session 中设置一个属性名为 student, 值为一个名为 student 的对象。而后可 在
同一 session 范围内用 getAttribute( “ student ” ) 取出该属性,得到 student
对象。


175 、 J2EE 是什么?【中等难度】
答: J2EE 是 Sun 公司提出的多层 (multi-diered), 分布式 (distributed), 基于 组
件 (component-base) 的企业级应用模型 (enterpriese application model). 在
这样的一个应用系统中,可按照功能划分为不同的组件,这些组件又可在不同 计
算机上,并且处于相应的层次 (tier) 中。所属层次包括客户层 (clietn tier) 组
件 ,web 层和组件 ,Business 层和组件 , 企业信息系统 (EIS) 层。


176 、 J2EE 是技术还是平台还是框架?【中等难度】
答: J2EE 本身是一个标准,一个为企业分布式应用的开发提供的标准平台;
J2EE 也是一个框架,包括 JDBC 、 JNDI 、 RMI 、 JMS 、 EJB 、 JTA 等技术。


177 、请写出 spring 中 I0C 的三种实现机制。【中等难度】
答:三种机制为:通过 setter 方法注入、通过构造方法注入和接口注入。


178 、写出你熟悉的开源框架以及各自的作用。【中等难度】
答:框架: hibernate 、 spring 、 struts ;
Hibernate 主要用于数据持久化;
Spring 的控制反转能起到耦合的作用;
Struts 主要用于流程控制。


1.在数据库中如何复制一张表
create table table_name1 as select * from table_name2


2 、 int 和 Integer 有什么区别 ? 【基础】
答: Java 提供两种不同的类型:引用类型和原始类型(或内置类型);
int 是 java 的原始数据类型, Integer 是 java 为 int 提供的封装类。
引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,
对象引用实例变量的缺省值为 null ,而原始类型实例变量的缺省值与
它们的类型有关


3、垃圾回收的优点和原理。并考虑 2 种回收机制。【基础】
答:垃圾回收机制,使Java 中的对象不再有 “ 作用域 ” 的概念 ,
只有对象的引用才有 “ 作用域 ” 。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。
垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。


回收机制有分 代复制垃圾回收和标记垃圾回收,增量垃圾回收。


4、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么 办
法主动通知虚拟机进行垃圾回收?【基础】
答:对于 GC 来说,当程序员创建对象时, GC 就开始监控这个对象的地址、大 小
以及使用情况。通常, GC 采用有向图的方式记录和管理堆 (heap) 中的所有对象 。
通过这种方式确定哪些对象是 " 可达的 " ,哪些对象是 " 不可达的 " 。当 GC 确定一些对象为 " 不可达 " 时, GC 就有责任回收这些内存空间。可以。程序员可以手动
执行 System.gc() ,通知 GC 运行,但是 Java 语言规范并不保证 GC 一定会执行 。


5.HQL和SQL的区别
HQL:面向对象的,是官方推荐的标准查询方式。from 后面跟的是 类名+类对象 where 后用对象的属性作条件
SQL:结构化查询语言,面向数据库检索,不具备面向对象的特征。from 后面跟的是 表名 where 后用表中字段作条件


6.列约束:
Unique key:该列或者列的集合中所有值都是唯一的
check:限制输入值的范围
not null:确保列中不出现null值


表约束:
primary key:主键是唯一识别表的每一条记录,表中只能存在一个primary关键字
foreign key:保证系统参照完整性的手段


7.数据库对象管理
视图(view):是从一个或多个表或视图中导出的表,其结构和数据是建立在对表的查询基础上的。
优点:(1)视图集中:使用户只关心它感兴趣的某些特定数据和他们所负责的特定任务
(2)简化操作:视图本身就是一个复杂查询的结果集,每次执行相同的查询时,不必重写负责的查询语句,只需在视图中用简单的查询语句就可以了
(3)安全性:通过视图用户只能查看和修改他们所看到的数据,其他表既不可见也不可以访问


索引(index):为了提高检索的能力


序列(sequence):常用于关键字,或给数据行排序


同义词:指为表、视图和序列等对象起的另一个名字


8.游标:对从表中检索出得数据进行灵活的操作,就其本质而言,游标是一种能从包括多条数据记录的结果集中每次提取一条记录的机制


9.= = 和equals()方法的区别是什么?
    ==是指两个对象是否指向同一个内存地址
    equals是指两个对象地址中是否存拉相同的内容。


10.Jsp和Servlet中的请求转发分别如何实现?
Jsp request.getRequestDispatcher(/*.jsp).forward(request,response)
Servlet sendRedirect()


11.注册JDBC驱动的三种方式:
Class.forName("oracle.jdbc.driver.OracleDriver");


new oracle.jdbc.driver.OracleDriver();


System.setProperty("jdbc.driver","oracle.jdbc.driver.OracleDriver");


49 、指出下面程序的运行结果 : 【基础】
class A{
    static{
    System.out.print("1");
    }
    public A(){
    System.out.print("2");
    }
}
class B extends A{
    static{
    System.out.print("a");
    }
    //构造函数
    public B(){
    System.out.print("b");
    }
}
public class Hello{
public static void main(String[] ars){
A ab = new B();
ab = new B();
}
}


// 执行到此处 , 结果 : 1a2b
// 执行到此处 , 结果 : 1a2b2b


112 、 Hibernate 有哪 5 个核心接口?【基础】
Hibernate的工作原理?


答: Configuration 接口创建SessionFactory 对象;
SessionFactory 接口:创建session 对象
Session 接口:负责保存、更新、删除、加载和查询对象,
Transaction 接口:管理事务;
Query 和 Criteria 接口:执行数据库的查询。


114 、 Hibernate 的应用( Hibernate 的结构)?【基础】
答: // 首先获得 SessionFactory 的对象
SessionFactory sessionFactory = new Configuration().configure().
buildSessionFactory();
// 然后获得 session 的对象
Session session = sessionFactory.openSession();
// 其次获得 Transaction 的对象
Transaction tx = session.beginTransaction();
// 执行相关的数据库操作 : 增 , 删 , 改 , 查
session.save(user); // 增加 , user 是 User 类的对象
session.delete(user); // 删除
session.update(user); // 更新
Query query = session.createQuery( “ from User ” ); // 查询
List list = query.list();
// 提交事务
tx.commit();
// 如果有异常 , 我们还要作事务的回滚 , 恢复到操作之前
tx.rollback();
// 最后还要关闭 session, 释放资源
session.close();
117 、事务处理?【基础】
答: Connection 类中提供了 3 个事务处理方法:
setAutoCommit(Boolean autoCommit): 设置是否自动提交事务,默认为自 动
提交事务,即为 true ,通过设置 false 禁止自动提交事务;
commit(): 提交事务;
rollback(): 回滚事务。


4.JDBC 如何做事务处理?
Con. setAutoCommit(false)
Con.commit();
Con.rollback();
5.写出几个在 Jdbc 中常用的接口
DriverManager,Connection,preparedStatement,statement,ResultSet


123 、 Servlet 的基本架构。【基础】
答public class ServletName extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
}
}


5.四种会话跟踪技术
Cookie
Session
Hidden表单
url 重写


4.STRUTS的应用(如STRUTS架构)
答:采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架。
 Struts有如下的主要功能:
一.包含一个controller servlet,能将用户的请求发送到相应的Action对象。
二.JSP自由tag库,并且在controller servlet中提供关联支持,帮助开发员创建交互式表单应用。
三.提供了一系列实用对象:XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息。




2.J2EE是什么?
答:Je22是Sun公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的企业级应用模型(enterpriese application model).
在这样的一个应用系统中,可按照功能划分为不同的组件,这些组件又可在不同计算机上,并且处于相应的层次 (tier) 中。所属层次包括客户层 (clietn tier) 组件 ,web 层和组件 ,Business 层和组件 , 企业信息系统 (EIS) 层。


3.abstract class和interface的区别
    abstract类中的方法不必是抽象的。
    接口可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的,接口中的方法定义默认为Public abstract类型,接口中的成员变量默认为public static final
语法上的区别:
1.抽象类中可以有普通成员变量,接口中没有
2.抽象类和接口都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中默认的为public static final
3.抽象类中的抽象方法的访问类型可以是任意的,而接口中默认是public abstract
4.抽象类中可以有构造方法,接口中不能有
5.抽象类中可以包含静态方法,接口中不能有
6.抽象类中可以包含非抽象的普通方法,接口中的所有方法都必须是抽象的
7.一个类可以实现多个接口,但只能继承一个抽象类
应用上的区别:
    接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约;抽象类在代码实现方面发挥作用,可以实现代码的复用


静态变量与实例变量的区别?
静态变量不依赖于某一个实例,可通过类名直接访问。
实例变量必须依赖于某一个实例,只能通过对象才能访问。


&和&&的区别?
相同点:
&和&&都可以用作逻辑与的运算符,表示逻辑与,当运算符两边的表达式的结果为true时,整个运算结果才为true,否则只要有一方为false,则结果为false
不同点:
&还可以作位运算符,通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4位
&&还具有短路的功能,当第一个表达式为false,则不计算第二个表达式。


关于Servlet
1.说一说Servlet的生命周期?
答:servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。


3.Servlet的基本架构
答:
public class ServletName extends HttpServlet {
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws
 ServletException, IOException {
 }
 public void doGet(HttpServletRequest request, HttpServletResponse response) throws
 ServletException, IOException {
 }
}


11.Servlet执行时一般实现哪几个方法?
答:
public void init(ServletConfig config)
public ServletConfig getServletConfig()
public String getServletInfo()
public void service(ServletRequest request,ServletResponse response)
public void destroy()


125 、 JSP 中动态 INCLUDE 与静态 INCLUDE 的区别?【基础】
答:动态 INCLUDE 用 jsp:include 动作实现 flush="true" /> 它总是会检查所含文件中的变化,适合用于包含动态页面,并
且可以带参数;
静态 INCLUDE 用 include 伪码实现 , 它不会检查所含文件的变化 ,
适用于包含静态页面 <%@ include file="included.htm" %>


28 、 char 型变量中能不能存贮一个中文汉字 ? 为什么 ? 【基础】

答:能够定义成为一个中文的,因为 java 中以 unicode 编码,一个 char 占 16个字节,所以放一个中文是没问题的。


第四章 Jsp篇
69、forward 和redirect的区别
答:forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。
    redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取。
70、jsp有哪些内置对象?作用分别是什么?
答:JSP共有以下9种基本内置组件(可与ASP的6种内部组件相对应): 
 request 用户端请求,此请求会包含来自GET/POST请求的参数 
   response 网页传回用户端的回应 
   pageContext 网页的属性是在这里管理 
   session 与请求有关的会话期 
   application servlet 正在执行的内容 
   out 用来传送回应的输出
   config servlet的构架部件 
   page JSP网页本身 
   exception 针对错误网页,未捕捉的例外 
71、jsp有哪些动作?作用分别是什么?
答:JSP共有以下6种基本动作
   jsp:include:在页面被请求的时候引入一个文件。 
   jsp:useBean:寻找或者实例化一个JavaBean。 
   jsp:setProperty:设置JavaBean的属性。 
   jsp:getProperty:输出某个JavaBean的属性。 
   jsp:forward:把请求转到一个新的页面。 
   jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记
72、JSP中动态INCLUDE与静态INCLUDE的区别? 
答:动态INCLUDE用jsp:include动作实现
   它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数
   静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面
   <%@ include file="included.htm" %>
73、两种跳转方式分别是什么?有什么区别?
答:有两种,分别为:
 
 
前者页面不会转向include所指的页面,只是显示该页的结果,主页面还是原来的页面。执行完后还会回来,相当于函数调用。并且可以带参数.后者完全转向新页面,不会再回来。相当于go to 语句。
74、JSP的内置对象及方法。
答:request表示HttpServletRequest对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法。 
    response表示HttpServletResponse对象,并提供了几个用于设置送回 浏览器的响应的方法(如cookies,头信息等) 
    out对象是javax.jsp.JspWriter的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。 
    pageContext表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API,并且包装了通用的servlet相关功能的方法。 
    session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息 
    applicaton 表示一个javax.servle.ServletContext对象。这有助于查找有关servlet引擎和servlet环境的信息 
    config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数。 
    page表示从该页面产生的一个servlet实例
第五章 Servlet篇
75、说一说Servlet的生命周期?
答:servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。 Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。
76、JAVA SERVLET API中forward() 与redirect()的区别?
答:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用sendRedirect()方法。
77、Servlet的基本架构
答:
public class ServletName extends HttpServlet {
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws
      ServletException, IOException  {
      }
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws
      ServletException, IOException  {
      }
}
78、什么情况下调用doGet()和doPost()?
答:Jsp页面中的form标签里的method属性为get时调用doGet(),为post时调用doPost()。
79、servlet的生命周期
答:web容器加载servlet,生命周期开始。通过调用servlet的init()方法进行servlet的初始化。通过调用service()方法实现,根据请求的不同调用不同的do***()方法。结束服务,web容器调用servlet的destroy()方法。
80、如何现实servlet的单线程模式
答:<%@ page isThreadSafe="false"%>
81、页面间对象传递的方法
答:request,session,application,cookie等
82、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 
答:JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。JSP编译后是"类servlet"。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。
83、四种会话跟踪技术
答:会话作用域ServletsJSP 页面描述
page否是代表与一个页面相关的对象和属性。一个页面由一个编译好的 Java servlet 类(可以带有任何的 include 指令,但是没有 include 动作)表示。这既包括 servlet 又包括被编译成 servlet 的 JSP 页面
request是是代表与 Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个 Web 组件(由于 forward 指令和 include 动作的关系)
session是是代表与用于某个 Web 客户机的一个用户体验相关的对象和属性。一个 Web 会话可以也经常会跨越多个客户机请求
application是是代表与整个 Web 应用程序相关的对象和属性。这实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域
84、Request对象的主要方法
答:
setAttribute(String name,Object):设置名字为name的request的参数值
getAttribute(String name):返回由name指定的属性值
getAttributeNames():返回request对象所有属性的名字集合,结果是一个枚举的实例
getCookies():返回客户端的所有Cookie对象,结果是一个Cookie数组
getCharacterEncoding():返回请求中的字符编码方式
getContentLength():返回请求的Body的长度
getHeader(String name):获得HTTP协议定义的文件头信息
getHeaders(String name):返回指定名字的request Header的所有值,结果是一个枚举的实例
getHeaderNames():返回所以request Header的名字,结果是一个枚举的实例
getInputStream():返回请求的输入流,用于获得请求中的数据
getMethod():获得客户端向服务器端传送数据的方法
getParameter(String name):获得客户端传送给服务器端的有name指定的参数值
getParameterNames():获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例
getParameterValues(String name):获得有name指定的参数的所有值
getProtocol():获取客户端向服务器端传送数据所依据的协议名称
getQueryString():获得查询字符串
getRequestURI():获取发出请求字符串的客户端地址
getRemoteAddr():获取客户端的IP地址
getRemoteHost():获取客户端的名字
getSession([Boolean create]):返回和请求相关Session
getServerName():获取服务器的名字
getServletPath():获取客户端所请求的脚本文件的路径
getServerPort():获取服务器的端口号
removeAttribute(String name):删除请求中的一个属性
85、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种编码的字符串?
答:
  Public String translate (String str) {
    String tempStr = "";
    try {
      tempStr = new String(str.getBytes("ISO-8859-1"), "GBK");
      tempStr = tempStr.trim();
    }
    catch (Exception e) {
      System.err.println(e.getMessage());
    }
    return tempStr;
  }
86、Servlet执行时一般实现哪几个方法?
答:
public void init(ServletConfig config)
public ServletConfig getServletConfig()
public String getServletInfo()
public void service(ServletRequest request,ServletResponse response)
public void destroy()
Jdbc、Jdo篇
87、Class.forName的作用?为什么要用?
答:调用该访问返回一个以字符串指定类名的类的对象。
88、Jdo是什么?
答:JDO是Java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。JDO提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码(如JDBC API的使用)。这些繁琐的例行工作已经转移到JDO产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC只是面向关系数据库(RDBMS)JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMS)等等,使得应用可移植性更强。
89、说出数据连接池的工作机制是什么?
答:J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。
90、Jdo是什么? 
答:JDO是Java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。JDO提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码(如JDBC API的使用)。这些繁琐的例行工作已经转移到JDO产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC只是面向关系数据库(RDBMS)JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMS)等等,使得应用可移植性更强。
Xml篇
91、xml有哪些解析技术?区别是什么?
答:有DOM,SAX,STAX等
DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问
STAX:Streaming API for XML (StAX)
92、你在项目中用到了xml技术的哪些方面?如何实现的?
答:用到了数据存贮,信息配置两方面。在做数据交换平台时,将不能数据源的数据组装成XML文件,然后将XML文件压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再同XML文件中还原相关信息进行处理。在做软件配置时,利用XML可以很方便的进行,软件的各种配置参数都存贮在XML文件中。
93、XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式? 
答:a: 两种形式 dtd  schema,b: 本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的),c:有DOM,SAX,STAX等 
    DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问
SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问 
STAX:Streaming API for XML (StAX)
94、用jdom解析xml文件时如何解决中文问题?如何解析?
答:看如下代码,用编码方式加以解决 
package test;
import java.io.*;
public class DOMTest
{
private String inFile = "c:people.xml";
private String outFile = "c:people.xml";
public static void main(String args[])
{
new DOMTest();
}
public DOMTest()
{
try
{
javax.xml.parsers.DocumentBuilder builder =




javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder();
org.w3c.dom.Document doc = builder.newDocument();
org.w3c.dom.Element root = doc.createElement("老师");
org.w3c.dom.Element wang = doc.createElement("王");
org.w3c.dom.Element liu = doc.createElement("刘");
wang.appendChild(doc.createTextNode("我是王老师"));
root.appendChild(wang);
doc.appendChild(root);
javax.xml.transform.Transformer transformer =
javax.xml.transform.TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, "gb2312");
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");




transformer.transform(new javax.xml.transform.dom.DOMSource(doc),
new


javax.xml.transform.stream.StreamResult(outFile));
}
catch (Exception e)
{
System.out.println (e.getMessage());
}
}
}


95、编程用JAVA解析XML的方式.
答:用SAX方式解析XML,XML文件如下:
SAXHandler.java 
import java.io.*;
import java.util.Hashtable;
import org.xml.sax.*;
public class SAXHandler extends HandlerBase
{
private Hashtable table = new Hashtable();
private String currentElement = null;
private String currentValue = null;
public void setTable(Hashtable table)
{
this.table = table;
}
public Hashtable getTable()
{
return table;
}
public void startElement(String tag, AttributeList attrs)
throws SAXException
{
currentElement = tag;
}
public void characters(char[] ch, int start, int length)
throws SAXException
{
currentValue = new String(ch, start, length);
}
public void endElement(String name) throws SAXException
{
if (currentElement.equals(name))
table.put(currentElement, currentValue);
}

第六章 应用服务器篇
106、如何给weblogic指定大小的内存? 
答:在启动Weblogic的脚本中(位于所在Domian对应服务器目录下的startServerName),增加set MEM_ARGS=-Xms32m -Xmx200m,可以调整最小内存为32M,最大200M
EJB需直接实现它的业务接口或Home接口吗,请简述理由。
远程接口和Home接口不需要直接实现,他们的实现代码是由服务器产生的,程序运行中对应实现类会作为对应接口类型的实例被使用。
107、应用服务器有那些?
答:BEA WebLogic Server,IBM WebSphere Application Server,Oracle9i Application Server,jBoss,Tomcat
108、如何设定的weblogic的热启动模式(开发模式)与产品发布模式?
答:可以在管理控制台中修改对应服务器的启动模式为开发或产品模式之一。或者修改服务的启动文件或者commenv文件,增加set PRODUCTION_MODE=true。
109、如何启动时不需输入用户名与密码?
答:修改服务启动文件,增加 WLS_USER和WLS_PW项。也可以在boot.properties文件中增加加密过的用户名和密码.
110、在weblogic管理制台中对一个应用域(或者说是一个网站,Domain)进行jms及ejb或连接池等相关信息进行配置后,实际保存在什么文件中?
答:保存在此Domain的config.xml文件中,它是服务器的核心配置文件。
111、说说weblogic中一个Domain的缺省目录结构?比如要将一个简单的helloWorld.jsp放入何目录下,然的在浏览器上就可打入 http://主机:端口号//helloword.jsp就可以看到运行结果了?  又比如这其中用到了一个自己写的javaBean该如何办?
答:Domain目录服务器目录applications,将应用目录放在此目录下将可以作为应用访问,如果是Web应用,应用目录需要满足Web应用目录要求,jsp文件可以直接放在应用目录中,Javabean需要放在应用目录的WEB-INF目录的classes目录中,设置服务器的缺省应用将可以实现在浏览器上无需输入应用名。
112、在weblogic中发布ejb需涉及到哪些配置文件
答:不同类型的EJB涉及的配置文件不同,都涉及到的配置文件包括ejb-jar.xml,weblogic-ejb-jar.xmlCMP实体Bean一般还需要weblogic-cmp-rdbms-jar.xml 
86、如何在weblogic中进行ssl配置与客户端的认证配置或说说j2ee(标准)进行ssl的配置
缺省安装中使用DemoIdentity.jks和DemoTrust.jks  KeyStore实现SSL,需要配置服务器使用Enable SSL,配置其端口,在产品模式下需要从CA获取私有密钥和数字证书,创建identity和trust keystore,装载获得的密钥和数字证书。可以配置此SSL连接是单向还是双向的。
113、如何查看在weblogic中已经发布的EJB?
答:可以使用管理控制台,在它的Deployment中可以查看所有已发布的EJB
说说在weblogic中开发消息Bean时的persistent与non-persisten的差别
persistent方式的MDB可以保证消息传递的可靠性,也就是如果EJB容器出现问题而JMS服务器依然会将消息在此MDB可用的时候发送过来,而non-persistent方式的消息将被丢弃
第七章 J2EE,MVC篇
114、MVC的各个部分都有那些技术来实现?如何实现?
答:MVC是Model-View-Controller的简写。"Model" 代表的是应用的业务逻辑(通过JavaBean,EJB组件实现), "View" 是应用的表示面(由JSP页面产生),"Controller" 是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。
115、J2EE是什么? 
答:Je22是Sun公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的企业级应用模型(enterpriese application model).在这样的一个应用系统中,可按照功能划分为不同的组件,这些组件又可在不同计算机上,并且处于相应的层次(tier)中。所属层次包括客户层(clietn tier)组件,web层和组件,Business层和组件,企业信息系统(EIS)层。
116、WEB SERVICE名词解释。JSWDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI,WSDL解释。
答:Web Service描述语言WSDL
SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议。
UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。
117、J2EE是技术还是平台还是框架?
答:J2EE本身是一个标准,一个为企业分布式应用的开发提供的标准平台。
 J2EE也是一个框架,包括JDBC、JNDI、RMI、JMS、EJB、JTA等技术。
118、STRUTS的应用(如STRUTS架构)
答:Struts是采用Java Servlet/JavaServer Pages技术,开发Web应用程序的开放源码的framework。 采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架。 Struts有如下的主要功能: 
一.包含一个controller servlet,能将用户的请求发送到相应的Action对象。 
二.JSP自由tag库,并且在controller servlet中提供关联支持,帮助开发员创建交互式表单应用。 
三.提供了一系列实用对象:XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息。
119、WEB SERVICE名词解释。JSWDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI,WSDL解释。 
答:Web ServiceWeb Service是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。
JAXP(Java API for XML Parsing) 定义了在Java中使用DOM, SAX, XSLT的通用的接口。这样在你的程序中你只要使用这些通用的接口,当你需要改变具体的实现时候也不需要修改代码。
JAXM(Java API for XML Messaging) 是为SOAP通信提供访问方法和传输机制的API。
WSDL是一种 XML 格式,用于将网络服务描述为一组端点,这些端点对包含面向文档信息或面向过程信息的消息进行操作。这种格式首先对操作和消息进行抽象描述,然后将其绑定到具体的网络协议和消息格式上以定义端点。相关的具体端点即组合成为抽象端点(服务)。
SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议。 
UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。
120、C/S 与 B/S 区别:
答:有如下八个方面的不同:
1.硬件环境不同: 
  C/S 一般建立在专用的网络上, 小范围里的网络环境, 局域网之间再通过专门服务器提供连接和数据交换服务.
  B/S 建立在广域网之上的, 不必是专门的网络硬件环境,例与电话上网, 租用设备. 信息自己管理. 有比C/S更强的适应范围, 一般只要有操作系统和浏览器就行 
2.对安全要求不同 
  C/S 一般面向相对固定的用户群, 对信息安全的控制能力很强. 一般高度机密的信息系统采用C/S 结构适宜. 可以通过B/S发布部分可公开信息.
  B/S 建立在广域网之上, 对安全的控制能力相对弱, 可能面向不可知的用户。
3.对程序架构不同 
  C/S 程序可以更加注重流程, 可以对权限多层次校验, 对系统运行速度可以较少考虑.
  B/S 对安全以及访问速度的多重的考虑, 建立在需要更加优化的基础之上. 比C/S有更高的要求 B/S结构的程序架构是发展的趋势, 从MS的.Net系列的BizTalk 2000 Exchange 2000等, 全面支持网络的构件搭建的系统. SUN 和IBM推的JavaBean 构件技术等,使 B/S更加成熟. 
4.软件重用不同 
  C/S 程序可以不可避免的整体性考虑, 构件的重用性不如在B/S要求下的构件的重用性好.
  B/S 对的多重结构,要求构件相对独立的功能. 能够相对较好的重用.就入买来的餐桌可以再利用,而不是做在墙上的石头桌子 
5.系统维护不同  
  C/S 程序由于整体性, 必须整体考察, 处理出现的问题以及系统升级. 升级难. 可能是再做一个全新的系统
  B/S 构件组成,方面构件个别的更换,实现系统的无缝升级. 系统维护开销减到最小.用户从网上自己下载安装就可以实现升级. 
6.处理问题不同 
  C/S 程序可以处理用户面固定, 并且在相同区域, 安全要求高需求, 与操作系统相关. 应该都是相同的系统
  B/S 建立在广域网上, 面向不同的用户群, 分散地域, 这是C/S无法作到的. 与操作系统平台关系最小. 
7.用户接口不同 
  C/S 多是建立的Window平台上,表现方法有限,对程序员普遍要求较高
  B/S 建立在浏览器上, 有更加丰富和生动的表现方式与用户交流. 并且大部分难度减低,减低开发成本. 
8.信息流不同 
  C/S 程序一般是典型的中央集权的机械式处理, 交互性相对低
  B/S 信息流向可变化, B-B B-C B-G等信息、流向的变化, 更像交易中心。
121、什么是web容器
答:给处于其中的应用程序组件(JSP,SERVLET)提供一个环境,使JSP,SERVLET直接更容器中的环境变量接**互,不必关注其它系统问题。主要有WEB服务器来实现。例如:TOMCAT,WEBLOGIC,WEBSPHERE等。该容器提供的接口严格遵守J2EE规范中的WEB APPLICATION 标准。我们把遵守以上标准的WEB服务器就叫做J2EE中的WEB容器。122、什么是EJB容器
答:Enterprise java bean 容器。更具有行业领域特色。他提供给运行在其中的组件EJB各种管理功能。只要满足J2EE规范的EJB放入该容器,马上就会被容器进行高效率的管理。并且可以通过现成的接口来获得系统级别的服务。例如邮件服务、事务管理
123、什么是JNDI
答:(Java Naming & Directory Interface)JAVA命名目录服务。主要提供的功能是:提供一个目录系统,让其它各地的应用程序在其上面留下自己的索引,从而满足快速查找和定位分布式应用程序的功能。
124、什么是JMS
答:(Java Message Service)JAVA消息服务。主要实现各个应用程序之间的通讯。包括点对点和广播。
125、什么是JTA
答:(Java Transaction API)JAVA事务服务。提供各种分布式事务服务。应用程序只需调用其提供的接口即可。
126、什么是JAF
答:(Java Action FrameWork)JAVA安全认证框架。提供一些安全控制方面的框架。让开发者通过各种部署和自定义实现自己的个性安全控制策略。
RMI/IIOP:(Remote Method Invocation /internet对象请求中介协议)他们主要用于通过远程调用服务。例如,远程有一台计算机上运行一个程序,它提供股票分析服务,我们可以在本地计算机上实现对其直接调用。当然这是要通过一定的规范才能在异构的系统之间进行通信。RMI是JAVA特有的。
127、MVC的各个部分都有那些技术来实现?如何实现? 
答:MVC是Model-View-Controller的简写。"Model" 代表的是应用的业务逻辑(通过JavaBean,EJB组件实现), "View" 是应用的表示面(由JSP页面产生),"Controller" 是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。
第八章 设计模式方面篇
128、开发中都用到了那些设计模式?用在什么场合?
答:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。主要用到了MVC的设计模式。用来开发JSP/Servlet或者J2EE的相关应用。简单工厂模式等。
129、说说你所熟悉或听说过的j2ee中的几种常用模式?及对设计模式的一些看法
答:Session Facade Pattern:使用SessionBean访问EntityBean
Message Facade Pattern:实现异步调用
EJB Command Pattern:使用Command JavaBeans取代SessionBean,实现轻量级访问
Data Transfer Object Factory:通过DTO Factory简化EntityBean数据提供特性
Generic Attribute Access:通过AttibuteAccess接口简化EntityBean数据提供特性
Business Interface:通过远程(本地)接口和Bean类实现相同接口规范业务逻辑一致性
EJB架构的设计好坏将直接影响系统的性能、可扩展性、可维护性、组件可重用性及开发效率。项目越复杂,项目队伍越庞大则越能体现良好设计的重要性。
130、j2ee常用的设计模式?说明工厂模式。
 答:Java中的23种设计模式:
Factory(工厂模式),      Builder(建造模式),       Factory Method(工厂方法模式),
Prototype(原始模型模式),Singleton(单例模式),    Facade(门面模式),
Adapter(适配器模式),    Bridge(桥梁模式),        Composite(合成模式),
Decorator(装饰模式),    Flyweight(享元模式),     Proxy(代理模式),
Command(命令模式),      Interpreter(解释器模式), Visitor(访问者模式),
Iterator(迭代子模式),   Mediator(调停者模式),    Memento(备忘录模式),
Observer(观察者模式),   State(状态模式),         Strategy(策略模式),
Template Method(模板方法模式), Chain Of Responsibleity(责任链模式)
工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
第九章 Hibernate程序性能优化篇


  本文依照HIBERNATE帮助文档,一些网络书籍及项目经验整理而成,只提供要点和思路,具体做法可以留言探讨,或是找一些更详细更有针对性的资料。
  初用HIBERNATE的人也许都遇到过性能问题,实现同一功能,用HIBERNATE与用JDBC性能相差十几倍很正常,如果不及早调整,很可能影响整个项目的进度。
  大体上,对于HIBERNATE性能调优的主要考虑点如下:
  ? 数据库设计调整
  ? HQL优化
  ? API的正确使用(如根据不同的业务类型选用不同的集合及查询API)
  ? 主配置参数(日志,查询缓存,fetch_size, batch_size等)
  ? 映射文件优化(ID生成策略,二级缓存,延迟加载,关联优化)
  ? 一级缓存的管理
  ? 针对二级缓存,还有许多特有的策略
  ? 事务控制策略。
  1、 数据库设计
  a) 降低关联的复杂性
  b) 尽量不使用联合主键
  c) ID的生成机制,不同的数据库所提供的机制并不完全一样
  d) 适当的冗余数据,不过分追求高范式
  2、 HQL优化
  HQL如果抛开它同HIBERNATE本身一些缓存机制的关联,HQL的优化技巧同普通的SQL优化技巧一样,可以很容易在网上找到一些经验之谈。
  3、 主配置
  a) 查询缓存,同下面讲的缓存不太一样,它是针对HQL语句的缓存,即完全一样的语句再次执行时可以利用缓存数据。但是,查询缓存在一个交易系统(数据变更频繁,查询条件相同的机率并不大)中可能会起反作用:它会白白耗费大量的系统资源但却难以派上用场。
  b) fetch_size,同JDBC的相关参数作用类似,参数并不是越大越好,而应根据业务特征去设置
  c) batch_size同上。
  d) 生产系统中,切记要关掉SQL语句打印。
  4、 缓存
  a) 数据库级缓存:这级缓存是最高效和安全的,但不同的数据库可管理的层次并不一样,比如,在ORACLE中,可以在建表时指定将整个表置于缓存当中。
  b) SESSION缓存:在一个HIBERNATE SESSION有效,这级缓存的可干预性不强,大多于HIBERNATE自动管理,但它提供清除缓存的方法,这在大批量增加/更新操作是有效的。比如,同时增加十万条记录,按常规方式进行,很可能会发现OutofMemeroy的异常,这时可能需要手动清除这一级缓存:Session.evict以及Session.clear
  c) 应用缓存:在一个SESSIONFACTORY中有效,因此也是优化的重中之重,因此,各类策略也考虑的较多,在将数据放入这一级缓存之前,需要考虑一些前提条件:
  i. 数据不会被第三方修改(比如,是否有另一个应用也在修改这些数据?)
  ii. 数据不会太大
  iii. 数据不会频繁更新(否则使用CACHE可能适得其反)
  iv. 数据会被频繁查询
  v. 数据不是关键数据(如涉及钱,安全等方面的问题)。
  缓存有几种形式,可以在映射文件中配置:read-only(只读,适用于很少变更的静态数据/历史数据),nonstrict-read-write,read-write(比较普遍的形式,效率一般),transactional(JTA中,且支持的缓存产品较少)
  d) 分布式缓存:同c)的配置一样,只是缓存产品的选用不同,在目前的HIBERNATE中可供选择的不多,oscache, jboss cache,目前的大多数项目,对它们的用于集群的使用(特别是关键交易系统)都持保守态度。在集群环境中,只利用数据库级的缓存是最安全的。
  5、 延迟加载
  a) 实体延迟加载:通过使用动态代理实现
  b) 集合延迟加载:通过实现自有的SET/LIST,HIBERNATE提供了这方面的支持
  c) 属性延迟加载:
  6、 方法选用
  a) 完成同样一件事,HIBERNATE提供了可供选择的一些方式,但具体使用什么方式,可能用性能/代码都会有影响。显示,一次返回十万条记录(List/Set/Bag/Map等)进行处理,很可能导致内存不够的问题,而如果用基于游标(ScrollableResults)或Iterator的结果集,则不存在这样的问题。
  b) Session的load/get方法,前者会使用二级缓存,而后者则不使用。
  c) Query和list/iterator,如果去仔细研究一下它们,你可能会发现很多有意思的情况,二者主要区别(如果使用了Spring,在HibernateTemplate中对应find,iterator方法):
  i. list只能利用查询缓存(但在交易系统中查询缓存作用不大),无法利用二级缓存中的单个实体,但list查出的对象会写入二级缓存,但它一般只生成较少的执行SQL语句,很多情况就是一条(无关联)。
  ii. iterator则可以利用二级缓存,对于一条查询语句,它会先从数据库中找出所有符合条件的记录的ID,再通过ID去缓存找,对于缓存中没有的记录,再构造语句从数据库中查出,因此很容易知道,如果缓存中没有任何符合条件的记录,使用iterator会产生N+1条SQL语句(N为符合条件的记录数)
  iii. 通过iterator,配合缓存管理API,在海量数据查询中可以很好的解决内存问题,如:
  while(it.hasNext()){
  YouObject object = (YouObject)it.next();
  session.evict(youObject);
  sessionFactory.evice(YouObject.class, youObject.getId());
  }
  如果用list方法,很可能就出OutofMemory错误了。
  iv. 通过上面的说明,我想你应该知道如何去使用这两个方法了。
  7、 集合的选用
  在HIBERNATE 3.1文档的“19.5. Understanding Collection performance”中有详细的说明。
  8、 事务控制
  事务方面对性能有影响的主要包括:事务方式的选用,事务隔离级别以及锁的选用
  a) 事务方式选用:如果不涉及多个事务管理器事务的话,不需要使用JTA,只有JDBC的事务控制就可以。
  b) 事务隔离级别:参见标准的SQL事务隔离级别
  c) 锁的选用:悲观锁(一般由具体的事务管理器实现),对于长事务效率低,但安全。乐观锁(一般在应用级别实现),如在HIBERNATE中可以定义VERSION字段,显然,如果有多个应用操作数据,且这些应用不是用同一种乐观锁机制,则乐观锁会失效。因此,针对不同的数据应有不同的策略,同前面许多情况一样,很多时候我们是在效率与安全/准确性上找一个平衡点,无论如何,优化都不是一个纯技术的问题,你应该对你的应用和业务特征有足够的了解。
  9、 批量操作
  即使是使用JDBC,在进行大批数据更新时,BATCH与不使用BATCH有效率上也有很大的差别。我们可以通过设置batch_size来让其支持批量操作。
  举个例子,要批量删除某表中的对象,如“delete Account”,打出来的语句,会发现HIBERNATE找出了所有ACCOUNT的ID,再进行删除,这主要是为了维护二级缓存,这样效率肯定高不了,在后续的版本中增加了bulk delete/update,但这也无法解决缓存的维护问题。也就是说,由于有了二级缓存的维护问题,HIBERNATE的批量操作效率并不尽如人意!
  从前面许多要点可以看出,很多时候我们是在效率与安全/准确性上找一个平衡点,无论如何,优化都不是一个纯技术的问题,你应该对你的应用和业务特征有足够的了解,一般的,优化方案应在架构设计期就基本确定,否则可能导致没必要的返工,致使项目延期,而作为架构师和项目经理,还要面对开发人员可能的抱怨,必竟,我们对用户需求更改的控制力不大,但技术/架构风险是应该在初期意识到并制定好相关的对策。
  还有一点要注意,应用层的缓存只是锦上添花,永远不要把它当救命稻草,应用的根基(数据库设计,算法,高效的操作语句,恰当API的选择等)才是最重要的。
Hibernate程序性能优化
http://www.weaseek.com  2008-08-19 11:21:35  来源:搜讯社区
初用HIBERNATE的人也许都遇到过性能问题,实现同一功能,用HIBERNATE与用JDBC性能相差十几倍很正常,如果不及早调整,很可能影响整个项目的进度。
本文依照HIBERNATE帮助文档,一些网络书籍及项目经验整理而成,只提供要点和思路,具体做法可以探讨,或是找一些更详细更有针对性的资料。
初用HIBERNATE的人也许都遇到过性能问题,实现同一功能,用HIBERNATE与用JDBC性能相差十几倍很正常,如果不及早调整,很可能影响整个项目的进度。
大体上,对于HIBERNATE性能调优的主要考虑点如下:
? 数据库设计调整
? HQL优化
? API的正确使用(如根据不同的业务类型选用不同的集合及查询API)
? 主配置参数(日志,查询缓存,fetch_size, batch_size等)
? 映射文件优化(ID生成策略,二级缓存,延迟加载,关联优化)
? 一级缓存的管理
? 针对二级缓存,还有许多特有的策略
? 事务控制策略。
1、 数据库设计
a) 降低关联的复杂性
b) 尽量不使用联合主键
c) ID的生成机制,不同的数据库所提供的机制并不完全一样
d) 适当的冗余数据,不过分追求高范式
2、 HQL优化
HQL如果抛开它同HIBERNATE本身一些缓存机制的关联,HQL的优化技巧同普通的SQL优化技巧一样,可以很容易在网上找到一些经验之谈。
3、 主配置
a) 查询缓存,同下面讲的缓存不太一样,它是针对HQL语句的缓存,即完全一样的语句再次执行时可以利用缓存数据。但是,查询缓存在一个交易系统(数据变更频繁,查询条件相同的机率并不大)中可能会起反作用:它会白白耗费大量的系统资源但却难以派上用场。
b) fetch_size,同JDBC的相关参数作用类似,参数并不是越大越好,而应根据业务特征去设置
c) batch_size同上。
d) 生产系统中,切记要关掉SQL语句打印。
4、 缓存
a) 数据库级缓存:这级缓存是最高效和安全的,但不同的数据库可管理的层次并不一样,比如,在ORACLE中,可以在建表时指定将整个表置于缓存当中。
b) SESSION缓存:在一个HIBERNATE SESSION有效,这级缓存的可干预性不强,大多于HIBERNATE自动管理,但它提供清除缓存的方法,这在大批量增加/更新操作是有效的。比如,同时增加十万条记录,按常规方式进行,很可能会发现OutofMemeroy的异常,这时可能需要手动清除这一级缓存:Session.evict以及 Session.clear
c) 应用缓存:在一个SESSIONFACTORY中有效,因此也是优化的重中之重,因此,各类策略也考虑的较多,在将数据放入这一级缓存之前,需要考虑一些前提条件:
i. 数据不会被第三方修改(比如,是否有另一个应用也在修改这些数据?)
ii. 数据不会太大
iii. 数据不会频繁更新(否则使用CACHE可能适得其反)
iv. 数据会被频繁查询
v. 数据不是关键数据(如涉及钱,安全等方面的问题)。
缓存有几种形式,可以在映射文件中配置:read-only(只读,适用于很少变更的静态数据/历史数据),nonstrict-read- write,read-write(比较普遍的形式,效率一般),transactional(JTA中,且支持的缓存产品较少)
d) 分布式缓存:同c)的配置一样,只是缓存产品的选用不同,在目前的HIBERNATE中可供选择的不多,oscache, jboss cache,目前的大多数项目,对它们的用于集群的使用(特别是关键交易系统)都持保守态度。在集群环境中,只利用数据库级的缓存是最安全的。
Hibernate 优化
一。 inverse = ?
inverse=false(default)
用于单向one-to-many关联 
parent.getChildren().add(child) // insert child
parent.getChildren().delete(child) // delete child
inverse=true
用于双向one-to-many关联 
child.setParent(parent); session.save(child) // insert child
session.delete(child)
在分层结构的体系中 
parentDao, childDao对于CRUD的封装导致往往直接通过session接口持久化对象,而很少通过关联对象可达性 
二。 one-to-many关系 
单向关系还是双向关系? 
parent.getChildren().add(child)对集合的触及操作会导致lazy的集合初始化,在没有对集合配置二级缓存的情况下,应避免此类操作 
select * from child where parent_id = xxx;
性能口诀: 
1. 一般情况下避免使用单向关联,尽量使用双向关联 
2. 使用双向关联,inverse=“true”
3. 在分层结构中通过DAO接口用session直接持久化对象,避免通过关联关系进行可达性持久化 




三。many-to-one关系 
单向many-to-one表达了外键存储方 
灵活运用many-to-one可以避免一些不必要的性能问题 
many-to-one表达的含义是:0..n : 1,many可以是0,可以是1,也可以是n,也就是说many-to-one可以表达一对多,一对一,多对一关系 
因此可以配置双向many-to-one关系,例如: 
1. 一桌四人打麻将,麻将席位和打麻将的人是什么关系?是双向many-to-one的关系 


四。one-to-one
通过主键进行关联 
相当于把大表拆分为多个小表 
例如把大字段单独拆分出来,以提高数据库操作的性能 
Hibernate的one-to-one似乎无法lazy,必须通过bytecode enhancement


五。集合List/Bag/Set
one-to-many
1. List需要维护index column,不能被用于双向关联,必须inverse=“false”,被谨慎的使用在某些稀有的场合 


2. Bag/Set语义上没有区别 
3. 我个人比较喜欢使用Bag
many-to-many
1. Bag和Set语义有区别 
2。 建议使用Set


六。集合的过滤 
1. children = session.createFilter(parent.getChildren(), “where this.age > 5 and this.age < 10”).list()
针对一对多关联当中的集合元素非常庞大的情况,特别适合于庞大集合的分页: 
session.createFilter(parent.getChildren(),“”).setFirstResult(0).setMaxResults(10).list();
在hibernate 中用 super.getSession().createFilter( , )


七。继承关系当中的隐式多态 
HQL: from Object
1. 把所有数据库表全部查询出来 
2. polymorphism=“implicit”(default)将当前对象,和对象所有继承子类全部一次性取出 
3. polymorphism=“explicit”,只取出当前查询对象 


八。Hibernate二级缓存 
著名的n+1问题:from Child,然后在页面上面显示每个子类的父类信息,就会导致n条对parent表的查询: 
select * from parent where id = ?
.......................
select * from parent where id = ?
解决方案 
1. eager fetch
2. 二级缓存 


九。inverse和二级缓存的关系 
当使用集合缓存的情况下: 
1. inverse=“false”,通过parent.getChildren()来操作,Hibernate维护集合缓存 
2. inverse=“true”,直接对child进行操作,未能维护集合缓存!导致缓存脏数据 
3. 双向关联,inverse=“true”的情况下应避免使用集合缓存 


十。Hibernate二级缓存是提升web应用性能的法宝 
OLTP类型的web应用,由于应用服务器端可以进行群集水平扩展,最终的系统瓶颈总是逃不开数据库访问; 


哪个框架能够最大限度减少数据库访问,降低数据库访问压力, 哪个框架提供的性能就更高;针对数据库的缓存策略: 
1. 对象缓存:细颗粒度,针对表的记录级别,透明化访问,在不改变程序代码的情况下可以极大提升web应用的性能。对象缓存是ORM的制胜法宝。 
2. 对象缓存的优劣取决于框架实现的水平,Hibernate是目前已知对象缓存最强大的开源ORM
3. 查询缓存:粗颗粒度,针对查询结果集,应用于数据实时化要求不高的场合 


十一。应用场合决定了系统架构 
一、是否需要ORM
Hibernate or iBATIS? 
二、采用ORM决定了数据库设计 
Hibernate: 
倾向于细颗粒度的设计,面向对象,将大表拆分为多个关联关系的小表,消除冗余column,通过二级缓存提升性能(DBA比较忌讳关联关系的出现,但是ORM的缓存将突破关联关系的性能瓶颈);Hibernate的性能瓶颈不在于关联关系,而在于大表的操作 
iBATIS: 
倾向于粗颗粒度设计,面向关系,尽量把表合并,通过表column冗余,消除关联关系。无有效缓存手段。iBATIS的性能瓶颈不在于大表操作,而在于关联关系。 


总结: 
性能口诀 
1、使用双向一对多关联,不使用单向一对多 
2、灵活使用单向多对一关联 
3、不用一对一,用多对一取代 
4、配置对象缓存,不使用集合缓存 
5、一对多集合使用Bag,多对多集合使用Set
6、继承类使用显式多态 
7、表字段要少,表关联不要怕多,有二级缓存撑腰 




最近开始留意项目中的Hibernate的性能问题,希望可以抽出时间学习一下hiberante的性能优化。主要是对数据库连接池技术、hibernate二级缓存、hibernate的配置优化等问题进行学习! 




1.关联关系: 
普通的关联关系:是不包括一个连接表,也就是中间表如: 
create table Person(personId bigint not null primary key,addressId bigint not null)
create table Address(addressId bigint not null primary key)
也就是不会还有一个关系表如: 
create table Person(personId bigint not null primary key)
create table Address(addressId bigint not null primary key)
create table PersonAddress(personId bigint not null,ddressId bigint not null primary key)




单向many-to-one关联是最常见的,而单向one-to-many是不常见的 




2. inner join(内连接)
left (outer) join(左外连接) 
right (outer) join (右外连接)
full join (全连接,并不常用)




3.小技巧: 
统计结果数目: 
(Integer)session.iterator("select count(*) from ..").next()).intValue();
根据一个集合大小来排序: 
select user.id,user.name
from User as user.name
left join user.messages msg
group by user.id,user.name
having count(msg)>=1
-
Hibernate优化的几点建议
关键字: hibernate 优化 ssh
优化hibernate性能的几点建议
1、针对oracle数据库而言,Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数,一般设置为30、50、100。Oracle数据库的JDBC驱动默认的Fetch Size=15,设置Fetch Size设置为:30、50,性能会有明显提升,如果继续增大,超出100,性能提升不明显,反而会消耗内存。


  即在hibernate配制文件中进行配制:


1 <property name="hibernateProperties">
2 <props>
3 <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
4 <prop key="hibernate.show_sql">false</prop>
5 <!-- Create/update the database tables automatically when the JVM starts up
6 <prop key="hibernate.hbm2ddl.auto">update</prop> -->
7 <!-- Turn batching off for better error messages under PostgreSQL
8 <prop key="hibernate.jdbc.batch_size">100</prop> -->
9 <prop key="hibernate.jdbc.batch_size">50</prop>
10 </props>
11 </property>Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。
  2、如果是超大的系统,建议生成htm文件。加快页面提升速度。


  3、不要把所有的责任推在hibernate上,对代码进行重构,减少对数据库的操作,尽量避免在数据库查询时使用in操作,以及避免递归查询操作,代码质量、系统设计的合理性决定系统性能的高低。


  4、 对大数据量查询时,慎用list()或者iterator()返回查询结果, 


  (1). 使用List()返回结果时,Hibernate会所有查询结果初始化为持久化对象,结果集较大时,会占用很多的处理时间。 


  (2). 而使用iterator()返回结果时,在每次调用iterator.next()返回对象并使用对象时,Hibernate才调用查询将对应的对象初始化,对于大数据量时,每调用一次查询都会花费较多的时间。当结果集较大,但是含有较大量相同的数据,或者结果集不是全部都会使用时,使用iterator()才有优势。


  5、在一对多、多对一的关系中,使用延迟加载机制,会使不少的对象在使用时方会初始化,这样可使得节省内存空间以及减少数据库的负荷,而且若PO中的集合没有被使用时,就可减少互数据库的交互从而减少处理时间。 


  6、对含有关联的PO(持久化对象)时,若default-cascade="all"或者 “save-update”,新增PO时,请注意对PO中的集合的赋值操作,因为有可能使得多执行一次update操作。 


  7、 对于大数据量新增、修改、删除操作或者是对大数据量的查询,与数据库的交互次数是决定处理时间的最重要因素,减少交互的次数是提升效率的最好途径,所以在开发过程中,请将show_sql设置为true,深入了解Hibernate的处理过程,尝试不同的方式,可以使得效率提升。尽可能对每个页面的显示,对数据库的操作减少到100----150条以内。越少越好。


  以上是在进行struts+hibernate+spring进行项目开发中,对hibernate性能优化的几点心得
Hibernate性能优化
Java /juxinsishui 发表于2006-08-28, 18:26
 有很多人认为Hibernate天生效率比较低,确实,在普遍情况下,需要将执行转换为SQL语句的Hibernate的效率低于直接JDBC存取,然而,在经过比较好的性能优化之后,Hibernate的性能还是让人相当满意的,特别是应用二级缓存之后,甚至可以获得比较不使用缓存的JDBC更好的性能,下面介绍一些通常的Hibernate的优化策略:
    1.抓取优化
    抓取是指Hibernate如何在关联关系之间进行导航的时候,Hibernate如何获取关联对象的策略,其主要定义了两个方面:如何抓取和何时抓取
    1)如何抓取。
    Hibernate3主要有两种种抓取方式,分别应用于对象关联实例(many-to-one、one-to-one)和对象关联集合(set、map等),总共是四种变种
    JOIN抓取: 通过在SELECT语句中使用OUTER JOIN来获得对象的关联实例或者关联集合)
    SELECT抓取: 另外发送一条SELECT语句来抓取当前对象的关联实体和集合
    在我的开发经历中,此处对性能的优化是比较有限的,并不值得过多关注
    例:
    A.应用于对象关联实例(默认是false)
     
    B.应用于对象关联集合(默认是auto)
   
       ....
   

    2)何时抓取
    主要分为延迟加载和立即抓取,默认的情况下Hibernate3对对象关联实采用延迟加载,普通属性采用立即抓取,通过延迟加载和采用适当的抓取粒度,与不采用优化相比往往可以将性能提升数倍
    立即抓取:当抓取宿主对象时,同时抓取其关联对象和关联集以及属性
    延迟加载:当抓取宿主对象时,并不抓取其关联对象,而是当对其对象进行调用时才加载
    例:
    A.应用于对象关联实例(默认是延迟加载)
     
    B.应用于对象关联集合(默认是延迟加载)
   
       ....
   

    对于延迟加载,需要注意的时,对延迟对象的使用必须在Session关闭之前进行,Hibernate的LazyInitalizationException往往就是由于在Session的生命期外使用了延迟加载的对象。当我们进行Web开发时,可以使用OpenSessionInView模式,当请求开始时打开session,当请求响应结束时才关闭session,不过,在使用OpenSessionInView模式时,需要注意如果响应时间比较长(业务比较复杂或者客户端是低速网络),将Session资源(也就是数据库的连接)占用太久的话可以会导致资源耗尽
    3)抓取粒度
    抓取粒度指的是对象在关联关系之间被导航时一次预先加载的数量,Hibernate程序的性能比较差往往就在于没有对抓取粒度仔细考虑,当加载一个列表并在列表中的每个对象中对其关联进行导航时,往往导致N+1条SQL语句查询。
    例:
    A.应用于对象关联实例(默认为1),注意,对对象关联实例的设置是在被关联的对象之上的,譬如
    class User
    {
        Group g;
    }
    那么抓取粒度应该在Group的配置文件之上,见下
   
        ...
   

    对该值并没有一个约定俗成的值,根据情况而定,如果被关联表数据比较少,则可以设置地小一些,3-20,如果比较大则可以设到30-50,注意的时候,并不是越多越好,当其值超过50之后,对性能并没有多大改善但却无谓地消耗内存
    假设有如下例子:
       List users = query.list();
    如果有20个User,并对这20个User及其Group进行遍历,如果不设置batch-size(即batch-size="1"),则在最糟糕的情况
    下,需要1 + 20条SQL语句,如果设置batch-size="10",则最好的情况下只需要1 + 2条SQL语句
    B.应用于对象关联集合(默认为1)
   
       ....
   

    2.二级缓存
    Hibernate对数据的缓存包括两个级:一级缓存,在Session的级别上进行,主要是对象缓存,以其id为键保存对象,在Session的生命期间存在;二级缓存,在SessionFactory的级别上进行,有对象缓存和查询缓存,查询缓存以查询条件为键保存查询结果,在SessionFactory的生命期间存在。默认地,Hibernate只启用一级缓存,通过正确地使用二级缓存,往往可以获得意想不到的性能。
    1)对象缓存:
    当抓取一个对象之后,Hiberate将其以id为键缓存起来,当下次碰到抓取id相同的对象时,可以使用如下配置
    方法1:在缓存对象上配置
   
       
   

    useage表示使用什么类型的缓存,譬如只读缓存、读写缓存等等(具体参见Hibernate参考指南),值得注意的时,有部分缓存在Hibernate的实现中不支持读写缓存,譬如JBossCache在Hibernate的实现中只是一种只读缓存,具体缓存实现对缓存类型的支持情况,可以参见org.hibernate.cache包
    regions表示缓存分块,大部分的缓存实现往往对缓存进行分块,该部分是可选的,详细参见各缓存实现
    方法2:在hibernate.cfg.xml中配置
   
    我认为第二种更好,可以统一管理
    2)查询缓存
    查询时候将查询结果以查询条件为键保存起来,需要配置如下
    A.在hibernate.cfg.xml中配置(启用查询缓存)
    true  (前面的属性名可参见常量
org.hibernate.cfg.Enviroment.USE_QUERY_CACHE)
    B.程序
    query.setCacheable(true);
    query.setCacheRegions(...);
    需要注意的是,查询缓存与对象缓存要结合更有效,因为查询缓存仅缓存查询结果列表的主键数据
    一般情况下在开发中,对一些比较稳定而又被频繁引用的数据,譬如数据字典之类的,将其进行二级缓存,对一些查询条件和查询数据变化不频繁而又常常被使用的查询,将其进行二级缓存。由于二级缓存是放在内存中,而且Hibernate的缓存不是弱引用缓存(WeekReference),所以注意不要将大块的数据放入其中,否则可能会被内存造成比较大的压力。
    3.批量数据操作
    当进行大批量数据操作(几万甚至几十几百万)时,需要注意两点,一,批量提交,二,及时清除不需要的一级缓存数据
    1)所谓的批量提交,就是不要频繁使用session的flush,每一次进行flush,Hibernate将PO数据于数据库进行同步,对于海量级数据操作来说是性能灾难(同时提交几千条数据和提交一条数据flush一次性能差别可能会是几十倍的差异)。一般将数据操作放在事务中,当事务提交时Hibernate自动帮你进行flush操作。
    2)及时清除不需要的一级缓存数据:由于Hibernate默认采用一级缓存,而在session的生命期间,所有数据抓取之后会放入一级缓存中,而当数据规模比较庞大时,抓取到内存中的数据会让内存压力非常大,一般分批操作数据,被一次操作之后将一级缓存清除,譬如
    session.clear(User.class)
    4.杂项
    dynamic-insert,dynamic-update,动态插入和动态更新,指的是让Hibernate插入数据时仅插入非空数据,当修改数据时只修改变化的数据,譬如对于 
    class User
    {
       id
       username
       password
    }
    如果u.id=1, u.username="ayufox",u.password=null,那么如果不设置动态插入,则其sql语句是insert into users(id, username, password) values (1, 'ayufox', '),如果设置则其sql语句是insert into users(username) valeus('ayufox')
    在如上的情况下,如果修改u.password='11',那么如果不设置动态更新,则sql语句为update users set username='ayufox', password='11' where id = 1,如果设置则为update user set password='11' where d = 1
    设置是在class的映射文件中,如下
   
   

  该设置对性能的提升比较有限
 2
?Copyleft;2008-10-01; by feeling.


你可能感兴趣的:(java基础)