Java EE技术面试常见问题

messishow

贡献于2011-11-15

字数:57394 关键词: 面试题目 Java

华腾软件学院 J2EE最新面试常见问题题库 华腾软件学院 项目部 就业面试题 2009 年 6 月 华腾软件学院 J2EE最新面试常见问题题库 目录 数据结构: 3 用java代码实现链表?(代码) 3 用java代码实现基本的二叉树?(代码) 4 用java代码实现栈结构?(代码) 5 算法: 7 各种排序的算法?(代码) 7 各种排序的优点和使用场合? 8 递归算法的使用和使用场合 9 模式: 9 设计模式的分类?每种类型的作用? 9 什么是工厂模式?在程序中如何使用? 11 什么是单例,多例模式?在程序中如何使用? 11 什么是适配器模式?在程序中如何使用? 13 JAVA基础: 16 描述面向对象特征?用一个例子说明,比方说车? 16 对象实例化方式?有什么区别? 16 基本数据类型有那些?它和包装类的区别? 17 LinkedList、ArrayList和Vector集合类型的区别和联系? 18 hashmap,hashtable,TreeMap, WeakHashMap的区别和联系? 18 类反射的作用和使用场合? 19 什么是线程同步? 19 序列化的作用? 20 WEB: 22 gbk,gb2312,gb18030, utf-8字符集类型的区别? 22 过滤器如何配置(javax.servlet.Filter)? 23 如何使用request,forword,include,error过滤器 24 网页: 27 不同浏览器的JS如何兼容? 27 STRUTS: 28 MVC设计模式与struts的联系? 28 struts控制器有那些关键类? 28 struts标签库的分类?在程序中常用的是那些,如何使用? 30 struts生命周期? 30 HIBERNATE: 31 什么是ORM? 31 hibernate的优点和缺点? 32 华腾软件学院 J2EE最新面试常见问题题库 hibernate与JDBC的区别? 32 hibernate中 dialect,lazy,inverse,cascade属性的用途? 33 hibernate中延迟加载的用途和使用场合? 34 hibernate中如何配置oracle序列 38 hibernate中缓存是什么? 38 hibernate的生命周期? 41 OpenSessionInViewFilter在程序中使用? 41 hibernate中有几种检索方式?每种方式的区别? 44 SPRING: 45 SSH整合过程? 45 spring的优点和缺点? 46 spring中的过滤器如何配置? 46 ioc的解释?注入方式?在程序中的使用? 47 AOP的解释?注入方式?在程序中的使用? 50 spring中的事务处理? 51 数据库: 51 视图的用法? 51 数据库的优化(程序优化,sql语句优化,数据库实例优化)? 52 oracle中过程和函数的区别? 55 内链接查询如何使用? 55 名词解释: 55 正文 数据结构: 用java代码实现链表?(代码) public class SortableLinkedList> extends LinkedList { public void addinOrder(E target) { Predecessor prev=this; ListNode node =getNext(); while((node!=null) && (node.getitem().compareTo(target)<0)){ prev=node; node=node.getNext(); } prev.setNext(new ListNode(target,node)); 华腾软件学院 J2EE最新面试常见问题题库 } /*链表排序*/ public void insertSort(){ SortableLinkedList newList =new SortableLinkedList(); for(E e:this){ newList.addinOrder(e); } setNext(newList.getNext()); } public static void main(String [] args) { SortableLinkedList slist =new SortableLinkedList(); slist.add("3"); slist.add("5"); slist.add("2"); slist.insertSort(); System.out.println(slist); } } 用java代码实现基本的二叉树?(代码) public class Tree{ public Node root=new Node(); //树的节点类 private class Node{ private Node left; private Node right; private Integer object; } public void add(Integer o){ if(root.object==null){ root.object=o; return; } Node node=root; while(node.object!=null){ 华腾软件学院 J2EE最新面试常见问题题库 //小的在左边,大的在右边 if(o.compareTo(node.object) <=0){ if(node.left!=null){ node=node.left; }else{ node.left=new Node(); node=node.left; } }else{ if(node.right!=null){ node=node.right; }else{ node.right=new Node(); node=node.right; } } } node.object=o; } } 用java代码实现栈结构?(代码) public class StackX { private int maxSize; // 栈的队列大小 private long[] stackArray; private int top = -1; //栈的顶部 /** * 初始化 * 根据参数规定的容量创建一个新栈,栈的域包括表示最大容量的变量 * 数组本身及变量top,它存储栈顶元素的下标 */ public StackX(int s) { maxSize = s; //set array size this.stackArray = new long[maxSize]; //create array } /** * 入栈 * 将top值增加一,使它指向原顶端数据项上面的一个位置 * 并在一个位置存储一个数据项 */ public void push(long j) { 华腾软件学院 J2EE最新面试常见问题题库 this.stackArray[++top] = j; //take item from top of stack } /** * 出栈 * 返回top标识的数据项值,然后top减一 * 其效果是从栈中移除一个数据项 */ public long pop() { return this.stackArray[top--]; //access item, decrement top } /** * 返回位于栈top的值,但不做任何改动 */ public long peek() { return this.stackArray[top]; } /** * 判断是否空栈,栈空时top变量为-1 */ public boolean isEmpty() { return this.top == -1; } /** * 判断栈是否以满,栈满时top变量为maxSize-1 */ public boolean isFull() { return top == this.maxSize - 1; } } 测试类 public class StackApp { public static void main(String[] args) { //初始化栈,设置栈的队列大小 StackX sx = new StackX(10); //入栈 sx.push(100); sx.push(200); sx.push(300); sx.push(400); 华腾软件学院 J2EE最新面试常见问题题库 sx.push(500); //判断是否为空栈 String temp; if(sx.isEmpty()) temp = "空栈"; else temp = "非空栈"; System.out.println("sx栈为: " + temp); //打印顶栈 System.out.println("top of stack: " + sx.peek()); //循环输出栈值 while(!sx.isEmpty()) { long value = sx.pop(); System.out.println("出栈值为: " + value); } } } 算法: 各种排序的算法?(代码) 冒泡排序: // 初始化变量 int[] data = { 12, 8, 3, 59, 132, 1236, 3400, 8, 352, 37 }; // 是否打印排序后结果 // 循环整个数组 for (int i = 0; i data[j + 1]) { // 将两个数字的位置进行对调 int temp = data[j]; data[j] = data[j + 1]; data[j + 1] = temp; } } for (int k = 0; k < data.length; k++) System.out.print(data[k] + " "); System.out.println(); } 华腾软件学院 J2EE最新面试常见问题题库 插入排序: int[] data = new int[] { 12, 8, 3, 59, 132, 1236, 3400, 8, 352, 37 }; int in, out; for (out = 1; out < data.length; out++) { int temp = data[out]; in = out; while (in > 0 && data[in - 1] >= temp) { data[in] = data[in - 1]; --in; } data[in] = temp; } 选择排序: int[] data = new int[] { 12, 8, 3, 59, 132, 1236, 3400, 8, 352, 37 }; int minValue; int indexMin; int temp; for (int i = 0; i < data.length; i++) { int lowIndex = i; for (int j = data.length - 1; j > i; j--) { if (data[j] < data[lowIndex]) { lowIndex = j; } } temp = data[i]; data[i] = data[lowIndex]; data[lowIndex] = temp; for (int k = 0; k < data.length; k++) System.out.print(data[k] + " "); System.out.println(); } 各种排序的优点和使用场合? 冒泡排序: 排序方法:相邻两元素进行比较,如有需要则进行交换, 每完成一次循环就将最大元素排在最后(如从小到大排序), 下一次循环是将其他的数进行类似操作。 优点 – 若数据已有部分排好序,则使用冒泡排序法可以很快的完成排序。 华腾软件学院 J2EE最新面试常见问题题库 缺点 – 会造成反复扫描数据,比较相邻的两个数据,速度不快也没有效率。 插入排序: 排序方法:每一趟从待排序的数据元素中选出最小(或最大)的一个元素, 顺序放在已排好序的数列的最后, 直到全部待排序的数据元素排完。 优点: – 最简单的排序 缺点 – 比其他排序消耗时间多 选择排序: 排序方法:将一个记录插入到已排好序的有序表(有可能是空表)中, 从而得到一个新的记录数增1的有序表 优点 – 利用一个一个的元素的插入比较,将元素放入适当的位置,也属于简单排序 缺点 – 但是每次都与之前数据相比较,故耗费时间 递归算法的使用和使用场合 递归算法的使用   递归过程一般通过函数或子过程来实现。   递归算法:在函数或子过程的内部,直接或者间接地调用自己的算法。   递归算法的实质:是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。 递归算法解决问题的特点:   (1) 递归就是在过程或函数里调用自身。   (2) 在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口。   (3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。   (4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。 案例分析: l 思考一下,13×4的答案是如何算出的呢,13×4是不是13连加四次呢?那我们如何得到13还要连加几次呢?何时停止呢? l 分析:递归的实例 步骤1:了解是否为适合用递归解题 步骤2:决定递归的结束条件 步骤3:决定递归执行部分 public static int mul(int a, int b) { 华腾软件学院 J2EE最新面试常见问题题库 int result; if(b == 1) { //结束条件 result = a; } else { //执行部分 result = a + mul(a, b - 1); } return result; } 模式: 设计模式的分类?每种类型的作用? 设计模式可以分为三大类,分别是创建型设计模式、行为型设计模式以及结构型设计模式。 创建型的设计模式: 单例模式(Singleton) 构建模式(Builder) 原型模式(Prototype) 抽象工厂模式(Abstract Factory) 工厂方法模式(Factory Method) 行为设计模式: 策略模式(Strategy) 状态模式(State) 责任链模式(Chain of Responsibility) 解释器模式(Interpreter) 命令模式(Command) 观察者模式(Observer) 备忘录模式(Memento) 迭代器模式(Iterator) 模板方法模式(Template Method) 访问者模式(Visitor) 中介者模式(Mediator) 结构型设计模式: 装饰者模式(Decorator) 代理模式(Proxy) 组合模式(Composite) 桥连接模式(Bridge) 适配器模式(Adapter) 华腾软件学院 J2EE最新面试常见问题题库 蝇量模式(Flyweight) 外观模式(Facade) =================================================================== 各种模式的表述: 单例模式(Singleton):确保有且只有一个对象被创建。 抽象工厂模式(Abstract Factory):允许客户创建对象的家族,而无需指定他们的具体类。 工厂方法模式(Factory Method):由子类决定要创建的具体类是哪一个。 装饰者模式(Decorator):包装一个对象,以提供新的行为。 状态模式(State):封装了基于状态的行为,并使用委托在行为之间切换。 迭代器模式(Iterator):在对象的集合之中游走,而不暴露集合的实现。 外观模式(Facade):简化一群类的接口。 策略模式(Strategy):封装可以互换的行为,并使用委托来决定要使用哪一个。 代理模式(Proxy):包装对象,以控制对此对象的访问。 适配器模式(Adapter):封装对象,并提供不同的接口。 观察者模式(Observer):让对象能够在状态改变时被通知。 模板方法模式(Template Method):有子类决定如何实现一个算法中的步骤。 组合模式(Composite):客户用一致的方法处理对象集合和单个对象。 命令模式(Command):封装请求成为对象。 什么是工厂模式?在程序中如何使用? 工厂模式,也叫做说虚构造器,在简单工厂中间插入了一个具体产品工厂,这个工厂知道产品构造时候的具体细节,而简单工厂模式的产品具体构造细节是在一个个 if/else分支,或者在switch/case分支里面的。工厂模式的好处就在于将工厂和产品之间的耦合降低,将具体产品的构造过程放在了具体工厂类里面。在以后扩展产品的时候方便很多,只需要添加一个工厂类,一个产品类,就能方便的添加产品,而不需要修改原有的代码。而在简单工厂中,如果要增加一个产品,则需要修改工厂类,增加if/else分支,或者增加一个case分支,工厂模式符合软件开发中的OCP原则(open close principle),对扩展开放,对修改关闭。 什么是单例,多例模式?在程序中如何使用? 1.谁给我讲讲在Java中什么是单例模式,它主要用在什么地方。[此问题的推荐答案]比如调用连接数据库的时候 public class DBopen { private Connection conn; private static DBopen db; private DBopen() { conn = this.getConnection(); } 华腾软件学院 J2EE最新面试常见问题题库 public static DBopen open() { if (db == null) { db = new DBopen(); } return db; } 其他类在生成DBopen对象的时候 DBopen db = DBopen.open(); 这样保证只连接一次 2.我也说说: 单例模式就是只能创建一个实例,就是只能一个对象。这个实例在全局被所有类都能调用。 public class Singleton{ private Singleton(){ } private static Singleton S; public static Singleton getS(){ if(S==null){ S=new Singleton(); } return S; } } 3.java模式之单例模式: 单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。 特点: 1,一个类只能有一个实例 2,自己创建这个实例 3,整个系统都要使用这个实例 例: 在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。 Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。一些资源管理器常常设计成单例模式。 外部资源: 譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口被两个请求同时调用。内部资源,譬如,大多数的软件都有一个(甚至多个)属性文件存放系统配置。这样的系统应当由一个对象来管理这些属性文件。 华腾软件学院 J2EE最新面试常见问题题库 一个例子:Windows 回收站。 在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且回收站自行提供自己的实例。因此,回收站是单例模式的应用。 两种形式: 1,饿汉式单例类 public class Singleton { private Singleton(){} //在自己内部定义自己一个实例,是不是很奇怪? //注意这是private 只供内部调用 private static Singleton instance = new Singleton(); //这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance() { return instance; } } 2,懒汉式单例类 public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance() { //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次 //使用时生成实例,提高了效率! if (instance==null) instance=new Singleton(); return instance; } } 第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。 什么是适配器模式?在程序中如何使用? 适配器是英语adapter的汉语翻译。适配器可以是一个独立的硬件接口设备,也可以是信息接口。比如:电源适配器、三角架基座转接部件、USB与串口的转接设备等。 在实际开发过程中,我们经常遇到这样的事情,我们根据初步的需求制定了一个基类,在开发过程中才了解到详细的需求或者需求发生了变动。而开发工作中的接口早已经定义完毕,并已经大规模投入编码。此时若改动接口的定义会造成很多编码上重复性的修改工作,并进而有可能造成修改不完全而导致的语义错误或逻辑错误。语义错误尚可以在编译阶段发现,而一旦发生逻辑性的错误,后果将会非常严重,甚至足以导致系统崩溃。此时就需要用到适配器模式的设计方法。 华腾软件学院 J2EE最新面试常见问题题库 适配器模式主要应用于,当接口里定义的方法无法满足客户的需求,或者说接口里定义的方法的名称或者方法界面与客户需求有冲突的情况。 适配器模式的使用方法: 用一个类同时继承接口和已知类,利用已知类中定义的方法和属性等,实现接口中的定义(主要利用了重载接口方法的办法)。用此类作为其他业务类的基类,也就是这个类适配了接口和已知类。若已知类发生变化,只需修改类适配器,就可以满足接口的实现。 适配器模式和代理模式是二个比较容易混淆的模式,我想谈一下这两个模式的差别,不过我先分别介绍一下这二个模式,然后再做比较,我想这样大家可能会比较容易理解,对于不懂这两个模式的人来说也多个了解的机会。 适配器说通俗点就是把一个东西包装一下变成另外一个东西,为什么要包装而不直接就用这个东西呢?呵呵,如果能直接用就犯不着适配了,要适配当然就是由于某些原因你用不了当前这个东西。最容易理解的就是电器的例子,比如你在中国买的电器使用电压是220V,结果你跑到国外去了,国外提供的电压是110V,问题就来了,你必须使用的是220V的,国外提供给你的却只有110V的,所以你根本就用不了,除非你能够将110V的转化成为220V才能行。此时适配器就排上用场了,你使用一个转压器不就可以把110V专成220V了吗?对于程序设计亦然。 下面举一个例子,假如你开始做一个项目的时候你需要写一个集合的枚举接口如下: public interface Enumeration{ bool HasMoreElement(); object nextElement(); } 调用的方法如下: public void BeforeDisplay(Enumeration e){ while (e.HasMoreElement()){ e.nextElement(); } } 后来由于某一种原因(可能是代码重构、或者类库升级),你定义了另外一个新的集合枚举接口如下: public interface Iterator{ bool MoveNext(); object Current(); void Reset(); } 使用新的接口调用方法如下: public void OldDisplay(Iterator e){ while (e.MoveNext()){ e.Current(); } } 现在如果要求新的方法都只使用新的接口一切都很顺利,但是由于原来的很多方法用的仍然是旧的接口,而由于逻辑的重用或者 为了升级后类库的向前兼容,你需要将当前的新接口Iterator转换成旧的接口Enumeration以调用原来的方法,这时候就需要我们写一个适配器。 华腾软件学院 J2EE最新面试常见问题题库 如何编写适配器?由于我们需要用的是Enumeration接口,所以适配器必须是Enumeration的,即必须继承自Enumeration;接着想我们需要利用新的Iterator做业务,简单点就是我们需要用Iterator中的方法,所以最容易想到的一个方法就是拥有一个Iterator的实例,直接调用该实例的方法实现Enumeration接口不就可以了吗?(如果Iterator是个具体的类,我们还可以再继承该类,来个双重继承,利用该具体类的方法实现Enumeration接口,效果一致) 示例代码如下: public class Itermeration:Enumeration{ private Iterator it; public Itermeration(Iterator it){ this.it=it; } public bool HasMoreElement(){ return it.MoveNext(); } public object nextElement(){ return it.Current(); } } 注意:由于我们需要将新接口Iterator转换成旧的接口Enumeration,所以新的类必须继承旧的接口Enumeration,将传入的Iterator转换成Enumeration接口。这样调用方法如下: public void Display(Iterator e){ BeforeDisplay(new Itermeration(e)); //此处将Iterator转化为Itermeration,而Itermeration又是继承自Enumeration,所以实际上就是将Iterator转化为Enumeration } 注意:我们为了将Iterator转化成Enumeration,采用的方式是在他们之间增加了一层,使用Itermeration类来转化,这是面向对象设计中抽象的一个主要思想,贯穿很多设计模式。 适配器模式有两种,我现在举的这个例子是对象的适配器模式,还有一种是类的适配器模式(对应上边括弧中的注释),这两种方式网上介绍的已经太多,我这里就不再赘述,当然现实中以对象的适配器模式使用最多,这也是为什么我举这种类型例子的原因。 其实适配器的思想是很容易理解的,很多人觉得困惑的原因常常不是他们不知道什么是适配器,而是他们联系自己曾有的经验,找不到要这么做的理由,所以内心深处总是对这么做感觉疑惑,当然很多其他的模式也是如此。 那到底什么时候需要用适配器呢?一个根本的理由就是系统需要使用现有的类,但是这个类的接口不符合当前的要求。 注意我这里说的是根本理由,因为这个理由是适配器出现的致命原因,由于这个理由出现了适配器,然后我们仔细揣摩出现后的适配器突然就发现他还有其它的好处,也就冒出了其它的理由。我强调这个的主要原因就是因为很多人开始看一篇文章描述觉得好像是这么回事,结果又看其它人的文章反而觉得越来越迷糊,实际上很大程度上的原因是很多文章往往为了强调全面而花了很多笔墨去写那些后来想起来的好处,而对根本理由轻轻带过,导致很多人误以为导出这种模式的原因是为了使用后来这些好处,结果就越搅越迷糊了。 华腾软件学院 J2EE最新面试常见问题题库 这里我给出另外一个使用理由,如果你看不太懂没有关系,完全可以忽略不看。 另一个理由就是我们系统中有很多彼此不大关联的类,而且这些类的接口都非常简单,(注意是接口都非常简单,如果都比较复杂用这种方法就是没事找事)。现在我想建立一个可以重复使用的类来跟这些简单类打交道,于是就使用适配,个人认为纯粹是为了方便。 java基础: 描述面向对象特征?用一个例子说明,比方说车? 面向对象的3个基本特征:封装性、继承性和多态性。 (1)所有东西都是对象。 (2)程序是一大堆对象的组合。 (3)每个对象都有自己的存储空间,可容纳其他对象。 (4)每个对象都有一种类型。 (5)同一类所有对象都能接收相同的消息。 1.封装 封装是面向对象编程的特征之一,也是类和对象的主要特征。封装将数据以及加在这些数据上的操作组织在一起,成为有独立意义的构件。外部无法直接访问这些封装了的数据,从而保证了这些数据的正确性。如果这些数据发生了差错,也很容易定位错误是由哪个操作引起的。 2. 继承 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类的继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且派生类可以修改或增加新的方法使之更适合特殊的需求。这也体现了大自然中一般与特殊的关系。继承性很好地解决了软件的可重用性问题。比如说,所有的Windows应用程序都有一个窗口,它们可以看作都是从一个窗口类派生出来的。但是有的应用程序用于文字处理,有的应用程序用于绘图,这是由于派生出了不同的子类,各个子类添加了不同的特性。 3.多态性 多态性是指允许不同类的对象对同一消息作出响应。比如同样的加法,把两个时间加在一起和把两个整数加在一起肯定完全不同。又比如,同样的选择"编辑"、"粘贴"操作,在字处理程序和绘图程序中有不同的效果。多态性包括参数化多态性和运行时多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好地解决了应用程序函数同名问题。 对象实例化方式?有什么区别? 直接new对象,Class.forName(xxx.xx.xx) ,Spring的注入机制,反射。 Class.forName(xxx.xx.xx) 返回一个类 首先你要明白在java里面任何class都要装载在虚拟机上才能运行。这句话就是装载类用的(和new 不一样,要分清楚)。 可以考虑一下这个问题,给出一个字符串变量,它代表一个类的包名和类名,怎么实例化它?只有提到的这个方法了,不过要再加一点。 A a = (A)Class.forName("pacage.A").newInstance(); 这和 A a = new A(); 是一样的效果。 华腾软件学院 J2EE最新面试常见问题题库 Spring将会使用默认的构造方法来建立Bean实例. 好处是调用静态工厂方法的对象不用了解对象建立的细节。 基本数据类型有那些?它和包装类的区别? 在Java中,一共有8种基本数据类型:4种整型,int,short,long,byte,两个浮点型,float,double,一个char类型和一个boolean(布尔)类型。 int 是基本类型,直接存数值 integer是对象,用一个引用指向这个对象  1.Java 中的数据类型分为基本数据类型和复杂数据类型   int 是前者>>integer 是后者(也就是一个类)  2.初始化时>> int i =1; Integer i= new Integer(1);(要把integer 当做一个类看)   int 是基本数据类型(面向过程留下的痕迹,不过是对java的有益补充) Integer 是一个类,是int的扩展,定义了很多的转换方法 类似的还有:float Float;double Double;string String等 举个例子:当需要往ArrayList,HashMap中放东西时,像int,double这种内建类型是放不进去的,因为容器都是装object的,这是就需要这些内建类型的外覆类了。 Java中每种内建类型都有相应的外覆类。 java 提供两种不同的类型:引用类型(或者封装类型,Warpper)和原始类型(或内置类型,Primitive)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型 封装类 boolean Boolean char Character byte Byte short Short int Integer long Long float Float double Double 引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的 数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。   int 是基本类型,(int)(Math.Random()*100)就是一个数,可以进行加见乘除。 Integer是class ,那么 new Integer(temp)就是一个对象了,可以用到Integer这个class的方法,例如用intvalue()可以返回这个int的值。 华腾软件学院 J2EE最新面试常见问题题库 LinkedList、ArrayList和Vector集合类型的区别和联系?   LinkedList类:LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部. ArrayList类: ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步. Vector类: Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出. Vector和ArrayList区别: 1, vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用 arraylist效率比较高。 2, 如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度 的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。 3, 如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用vector和arraylist都可以。而 如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用linklist,因为它移动一个指定位置的数据 所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。 ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快! arraylist和linkedlist 1, ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 2, 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 3, 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 4, 这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。 但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。   hashmap,hashtable,TreeMap, WeakHashMap的区别和联系? 在Map对象中,每一个关键字最多有一个关联的值。 华腾软件学院 J2EE最新面试常见问题题库 Map:不能包括两个相同的键,一个键最多能绑定一个值。null可以作为键,这样的键只有一个;可以有一个或多个键所对应的 值为null。当get()方法返回null值时,即可以表示Map中没有该键,也可以表示该键所对应的值为null。因此,在Map中不能由get()方法来判断Map中是否存在某个键,而应该用containsKey()方法来判断。 继承Map的类有:HashMap,HashTable HashMap:Map的实现类,缺省情况下是非同步的,可以通过Map Collections.synchronizedMap(Map m)来达到线程同步 HashTable:Dictionary的子类,确省是线程同步的。不允许关键字或值为null 当元素的顺序很重要时选用TreeMap,当元素不必以特定的顺序进行存储时,使用HashMap。Hashtable的使用不被推荐,因为HashMap提供了所有类似的功能,并且速度更快。当你需要在多线程环境下使用时,HashMap也可以转换为同步的。 映射: HashTable: 实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。 HashMap: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。 WeakHashMap: 实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。 TreeMap: 实现这样一个映象,对象是按键升序排列的。 类反射的作用和使用场合? Reflection 是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。 Java有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。 涉及到的类和方法主要有:java.lang.Class,以及java.lang.reflect中的Method、Field、Constructor等等classes。 什么是线程同步? 1、线程同步的目的是为了保护多个线程反问一个资源时对资源的破坏。 2、线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他非同步方法。 华腾软件学院 J2EE最新面试常见问题题库 3、对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,当在一个同步方法中访问另外对象上的同步方法时,会获取这两个对象锁。 4、对于同步,要时刻清醒在哪个对象上同步,这是关键。 5、编写线程安全的类,需要时刻注意对多个线程竞争访问资源的逻辑和安全做出正确的判断,对“原子”操作做出分析,并保证原子操作期间别的线程无法访问竞争资源。 6、当多个线程等待一个对象锁时,没有获取到锁的线程将发生阻塞。 7、死锁是线程间相互等待锁锁造成的,在实际中发生的概率非常的小。真让你写个死锁程序,不一定好使,呵呵。但是,一旦程序发生死锁,程序将死掉。 序列化的作用? 序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。 序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例 序列化的什么特点: 如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态, transient代表对象的临时数据。 什么时候使用序列化: 1. 对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。 2. java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。 ======================= 可以看看接口java.io.serializable的中文解释: Serializable public interface Serializable 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。 要允许不可序列化类的子类型序列化,可以假定该子类型负责保存和还原超类型的公用 (public)、受保护的 (protected) 和(如果可访问)包 (package) 字段的状态。仅在子类型扩展的类有一个可访问的无参数构造方法来初始化该类的状态时,才可以假定子类型有此责任。如果不是这种情况,则声明一个类为可序列化类是错误的。该错误将在运行时检测到。 在反序列化过程中,将使用该类的公用或受保护的无参数构造方法初始化不可序列化类的字段。可序列化的子类必须能够访问无参数的构造方法。可序列化子类的字段将从该流中还原。 当遍历一个图形时,可能会遇到不支持可序列化接口的对象。在此情况下,将抛出 NotSerializableException,并将标识不可序列化对象的类。 华腾软件学院 J2EE最新面试常见问题题库 在序列化和反序列化过程中需要特殊处理的类必须使用下列准确签名来实现特殊方法: private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法可以还原它。通过调用 out.defaultWriteObject 可以调用保存 Object 的字段的默认机制。该方法本身不需要涉及属于其超类或子类的状态。状态是通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream 来保存的。 readObject 方法负责从流中读取并还原类字段。它可以调用 in.defaultReadObject 来调用默认机制,以还原对象的非静态和非瞬态字段。defaultReadObject 方法使用流中的信息来分配流中通过当前对象中相应命名字段保存的对象的字段。这用于处理类发展后需要添加新字段的情形。该方法本身不需要涉及属于其超类或子类的状态。状态是通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream 来保存的。 将对象写入流时需要指定要使用的替代对象的可序列化类,应使用准确的签名来实现此特殊方法: ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException; 此 writeReplace 方法将由序列化调用,前提是如果此方法存在,而且它可以通过被序列化对象的类中定义的一个方法访问。因此,该方法可以拥有私有 (private)、受保护的 (protected) 和包私有 (package-private) 访问。子类对此方法的访问遵循 java 访问规则。 在从流中读取类的一个实例时需要指定替代的类应使用的准确签名来实现此特殊方法。 ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException; 此 readResolve 方法遵循与 writeReplace 相同的调用规则和访问规则。 序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID: ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; 如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修改器显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于立即声明类 -- serialVersionUID 字段作为继承成员没有用处。 华腾软件学院 J2EE最新面试常见问题题库 web: gbk,gb2312,gb18030, utf-8字符集类型的区别? GB2312 GB2312是基于区位码设计的,区位码把编码表分为94个区,每个区对应94个位,每个字符的区号和位号组合起来就是该汉字的区位码。区位码一般 用10进制数来表示,如1601就表示16区1位,对应的字符是“啊”。在区位码的区号和位号上分别加上0xA0就得到了GB2312编码。 区位码中01-09区是符号、数字区,16-87区是汉字区,10-15和88-94是未定义的空白区。它将收录的汉字分成两级:第一级是常用汉字计3755个,置于16-55区,按汉语拼音字母/笔形顺序排列;第二级汉字是次常用汉字计3008个,置于56-87区,按部首/笔画顺序排列。一级汉字是按照拼音排序的,这个就可以得到某个拼音在一级汉字区位中的范围,很多根据汉字可以得到拼音的程序就是根据这个原理编写的。 GB2312字符集中除常用简体汉字字符外还包括希腊字母、日文平假名及片假名字母、俄语西里尔字母等字符,未收录繁体中文汉字和一些生僻字。可以用繁体汉字测试某些系统是不是只支持GB2312编码。 GB2312的编码范围是0xA1A1-0x7E7E,去掉未定义的区域之后可以理解为实际编码范围是0xA1A1-0xF7FE。 EUC-CN可以理解为GB2312的别名,和GB2312完全相同。 区位码更应该认为是字符集的定义,定义了所收录的字符和字符位置,而GB2312及EUC-CN是实际计算机环境中支持这种字符集的编码。HZ和ISO-2022-CN是对应区位码字符集的另外两种编码,都是用7位编码空间来支持汉字。区位码和GB2312编码的关系有点像 Unicode和UTF-8。 GBK GBK编码是GB2312编码的超集,向下完全兼容GB2312,同时GBK收录了Unicode基本多文种平面中的所有CJK汉字。同 GB2312一样,GBK也支持希腊字母、日文假名字母、俄语字母等字符,但不支持韩语中的表音字符(非汉字字符)。GBK还收录了GB2312不包含的汉字部首符号、竖排标点符号等字符。 GBK的整体编码范围是为0x8140-0xFEFE,不包括低字节是0×7F的组合。高字节范围是0×81-0xFE,低字节范围是0x40-7E和0x80-0xFE。 低字节是0x40-0x7E的GBK字符有一定特殊性,因为这些字符占用了ASCII码的位置,这样会给一些系统带来麻烦。 有些系统中用0x40-0x7E中的字符(如“|”)做特殊符号,在定位这些符号时又没有判断这些符号是不是属于某个 GBK字符的低字节,这样就会造成错误判断。在支持GB2312的环境下就不存在这个问题。需要注意的是支持GBK的环境中小于0x80的某个字节未必就是ASCII符号;另外就是最好选用小于0×40的ASCII符号做一些特殊符号,这样就可以快速定位,且不用担心是某个汉字的另一半。Big5编码中也存在相应问题。 CP936和GBK的有些许差别,绝大多数情况下可以把CP936当作GBK的别名。 GB18030 GB18030编码向下兼容GBK和GB2312,兼容的含义是不仅字符兼容,而且相同字符的编码也相同。GB18030收录了所有Unicode3.1中的字符,包括中国少数民族字符,GBK不支持的韩文字符等等,也可以说是世界大多民族的文字符号都被收录在内。 华腾软件学院 J2EE最新面试常见问题题库 GBK和GB2312都是双字节等宽编码,如果算上和ASCII兼容所支持的单字节,也可以理解为是单字节和双字节混合的变长编码。GB18030编码是变长编码,有单字节、双字节和四字节三种方式。 GB18030的单字节编码范围是0x00-0x7F,完全等同与ASCII;双字节编码的范围和GBK相同,高字节是0x81-0xFE,低字节的编码范围是0x40-0x7E和0x80-FE;四字节编码中第一、三字节的编码范围是0x81-0xFE,二、四字节是0x30-0x39。 Windows中CP936代码页使用0x80来表示欧元符号,而在GB18030编码中没有使用0x80编码位,用其他位置来表示欧元符号。这可以理解为是GB18030向下兼容性上的一点小问题;也可以理解为0x80是CP936对GBK的扩展,而GB18030只是和GBK兼容良好。 UTF-8 Unicode Transformation Format-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。 过滤器如何配置(javax.servlet.Filter)? Filter过滤器配置: 在web配置文件中添加如下配置: 自定义一个名称 自定义过滤器类的路径 encoding gbk 自定义的名称注:要与filter-name节点名称一致 /* 如果是url的get提交参数带中文的 ,可以改下面这个文件,加入一个URIEncoding="GBK"  文件目录在:X:\Tomcat 5.5\conf\Server.xml    华腾软件学院 J2EE最新面试常见问题题库 如何使用request,forword,include,error过滤器 Request过滤器: 这种过滤器的工作方式比较简单,大家也经常遇到,如下图所示: 以下是web.xml文件配置方式:     myFilter     xx.MyFilter   myFilter   目标资源一 下面我们更改一下web.xml文件的配置,如下方式:     myFilter     xx.MyFilter   myFilter   目标资源一   myFilter   目标资源二 也就是说此过滤器对目标资源一和目标资源二都进行过滤,然后当目标资源一被访问的时候我们将请求 华腾软件学院 J2EE最新面试常见问题题库 转发给目标资源二,那么这个时候过滤器是怎么工作的呢?如下图所示:     我们可以看到,当我们访问目标资源一时过滤器截取了请求,然后再转发给目标资源一,然后再转发给目标资源二,从图中我们可以看到过滤器没有截取转发到目标资源二的请求,但是我们已经在web.xml文件中配置了该过滤器对目标资源二的过滤,为什么又没有起到过滤作用呢?     答案就在于,目标资源一是客户端直接访问,而目标资源二是被转发过来的,这时过滤器就不能过滤目标资源二。如果你直接访问目标资源二,你会发现该过滤器起到了作用?     我们上面的web.xml文件配置与以下方式等价: myFilter     myFilter     xx.MyFilter   myFilter   目标资源一   REQUEST   myFilter   目标资源二   REQUEST 这种方式的配置,说明只有直接访问该目标资源时该过滤器才会起作用,对转发到该目标资源的请求将忽略不处理。     那如果我想对转发到目标资源二的请求进行过滤,那怎么办呢?答案见,下一种过滤器,forward过滤器。 Forward过滤器: 华腾软件学院 J2EE最新面试常见问题题库 我们将web.xml文件的配置修改如下: myFilter     myFilter     xx.MyFilter   myFilter   目标资源一   REQUEST   myFilter   目标资源二   FORWARD 工作方式如下图所示:     我们看对目标资源二过滤的配置方式,这时过滤方式为forward,也就是说对转发到目标资源二的请求过滤,如果直接访问目标资源二,过滤器将不起作用。 include过滤器: 理解了forward过滤器之后,include过滤器就不难理解了。以下方式:   myFilter   目标资源二   INCLUDE     此表示对包含了目标资源二的请求过滤,如果直接访问目标资源二,则此过滤器将不起作用。     include包含以下语句:     在JSP页面中的动作:指令包含,这时此过滤器不工作 华腾软件学院 J2EE最新面试常见问题题库 Error过滤器: web.xml文件的配置:   myFilter   /error.jsp   ERROR     404     /error.jsp     当我们访问一个不存在的文件时,就会访问error.jsp,但是配置了过滤器对错误页面进行过滤,所以过滤器先接受到请求,然后再转发给error.jsp。 网页: 不同浏览器的JS如何兼容? ie和firefox不兼容js的解决方法集合2009-04-26 23:081、firefox和ie事件event处理。在ie中,事件对象是作为一个全局变量来保存和维护的。 所有的浏览器事件,不管是用户触发的,还是其他事件, 都会更新window.event 对象。 所以在代码中,只要轻松调用 window.event就可以轻松获取 事件对象, 再 event.srcElement 就可以取得触发事件的元素进行进一步处理在ff中, 事件对象却不是全局对象,一般情况下,是现场发生,现场使用,ff把事件对象自动传递给对应的事件处理函数。 在代码中,函数的第一个参数就是ff下的事件对象了。 firefox和ie对手型指针cursor不兼容 手型指针有cursor:hand和cursor:pointer两种写法,其中cursor:hand在ff中不支持,返回错误!只要使用cursor:pointer即可,ff和ie都支持! struts: MVC设计模式与struts的联系? struts是帮助V和C更好地分开,它处理的是v和c之间的东西。 它是一个框架,支持MVC,不能说它属于哪一部分。 就像脖子那部分,不属于头也不属于身体,不知道这个比喻准不准确。 servlet模式中,请求提交到servlet,是通过指定文件名; 而struts中,请求统一提交给struts的一个类,由struts根据.do这个调用不同的servlet 清楚处理完毕,servlet是必须自己刷新页面; 而struts中,你是指定forward,struts根据这个forward决定显示哪个页面。 struts控制器有那些关键类? 1.ActionServlet类:是一个前端控制器,将request转发给RequestProcessor来处理。提供了一组能够被Action对象使用的方法: (1) 动态的添加和删除,只影响应用程序当前的实例 public void addFormBean(ActionFormBean formBean) public void removeFormBean(ActionFormBean formBean) public void addForward(ActionForward actionForward) public void removeForward(ActionForward actionForward) public void addMapping(ActionMaping actionMapping) public void removeMapping(ActionMaping actionMapping) (2) 根据名称查找对象 public ActionFormBean findFormBean(String name) public ActionForward findForward(String name) 华腾软件学院 J2EE最新面试常见问题题库 public ActionMapping findMapping(String name) (3) 用来处理数据源 public void addDataSource(String key, DataSource ds) public DataSource findDataSource(String key) (4) 使用destroy()方法结束ActionServlet (5) 使用reload()方法从struts配置文件将信息重新加载。 2.ActionMapping类:是ActionConfig的子类,实质上是对struts-config.xml的一个映射类,从中可以取得所有的配置信息。将特定请求映射到特定Action的相关信息存储在ActionMapping中,ActionServlet将ActionMapping传送到Action类的perform()方法,Action将使用ActionMapping的findForward()方法,此方法返回一个指定名称的ActionForward,这样Action就完成了本地转发。若没有找到具体的ActionForward,就返回一个null。ActionMapping类的方法: (1) 可以在映射中动态添加ActionForward public ActionForward findForward(String name) (2) 可以返回与映射关联的表单bean public void addForward(ActionForward forward) (3) 可以返回映射的属性域(回话或请求) public String getName() (4) 可以返回映射的作用域 public String getScope() 3.RequestProcessor类 :根据提交过来的url,如*.do从ActionMapping中得到相应的ActionForm和Action,然后将request参数对应到ActionForm中,进行验证。如果验证通过则调用Action的execute()方法来执行Action,最终返回ActionForward。 4.ActionForward类:是对mapping中一个forward的包装,对应于一个url。 5.Action类:是框架包的核心,链接客户请求和业务操作,真正实现应用程序的事务逻辑,负责处理请求。其方法有: (1) 所有Action类都扩展org.apache.struts.action.Action类,且覆盖类中定义的一个execute()方法。 处理非HTTP请求: public ActionForward execute(ActionMapping action, ActionForm form, ServletRequest request, ServletResponse response) thorws IOException, ServletException 处理HTTP请求: public ActionForward execute(ActionMapping action, ActionForm form, HttpServletRequest request, HttpServletResponse response) thorws IOException, ServletException (2) 可以获得或设置与请求相关联的区域: public Local getLocal(HttpServletRequest request) public void setLocal(HttpServletRequest request, Local local) (3) 为应用程序获得消息资源: public MessageResources getResources() 华腾软件学院 J2EE最新面试常见问题题库 (4) 检查用户是否点击表单上的“取消”键,如果是,返回true: public Boolean isCancelled(HttpServletRequest request) (5) 当应用程序发生错误时,Action类存储错误信息: public void saveErrors(HttpServletRequest request, ActionErrors errors) 6.DispatchAction类: Struts提供了多种Action供选择使用。普通的Action只能通过调用execute执行一项任务,而DispatchAction可以根据配置参数执行,而不是仅进入execute()函数,这样可以执行多种任务。如insert,update等。LookupDispatchAction可以根据提交表单按钮的名称来执行函数。 struts标签库的分类?在程序中常用的是那些,如何使用? 有五个分类:html标签 logic标签 bean标签 Template标签 Nested标签 在程序中经常使用的是logic,bean标签 Html标签: 描述: Struts html标签库 = html元素 分类: 用于生成基本和HTML的标签 用于生成HTML表单的标签 显示消息(正确/错误)的标签 Bean标签: 描述: 可以访问已经存在的JavaBean以及它们的属性,可以把它们放到(Page,request, session……)范围中保存,也有一些Bean可以方便访问HTTP请求的Header信息,或请求 参数,或Cookie。 分类: 用于访问HTTP请求信息或JSP隐式对象的Bean标签 用于访问WEB资源(作用域中值)的Bean标签 用于定义或输出的JavaBean的标签 Logic标签: 描述: 可以根据特定的逻辑条件来控制输出网页的内容,或者循环标签元素。 分类: 进行比较运算的Logic标签 进行字符串匹配的Logic标签 判断对象是否存在的Logic标签 进行循环遍历的Logic标签 进行请求转发或者重定向的Logic标签 标签通用属性 华腾软件学院 J2EE最新面试常见问题题库 struts生命周期? Web容器启动后,struts加载需要依靠ActionServlet,但是ActionServlet的加载要从两个方面进行。 (1)优先级最高则先加载ActionServlet (2)如果不是最高的,则等到有用户发出请求是ActionServlet被加载。如用户提交表单时,利用form属性Action发出*.do的请求,这时ActionServlet将被加载。Actionservlet启动后,和一般的Servlet相同,要先执行init()方法来完成初始化工作。在初始化过程中,Struts的Struts-config.XML被加载。Struts的配置数据被加载和初始化,struts的相关组件也被加载。如街道了用户的请求,要根据请求类型执行Servlet的doGet()或doPost()方法,在方法中调用process()方法,在Process()方法中获得处理请求的请求处理器对象RequestProcessor。执行RequestProcessor对象的Porcessor()方法对请求进行处理,然后开始对请求进行处理。 华腾软件学院 J2EE最新面试常见问题题库 hibernate: 什么是ORM? ORM把应用程序世界表示为具有角色(关系中的部分)的一组对象(实体或值)。ORM有时也称为基于事实的建模,因为它把相关数据描述为基本事实。  · 简单。以最基本的形式建模数据。  · 传达性。数据库结构被任何人都能理解的语言文档化。  · 精确性。基于数据模型创建正确标准化了的结构。   典型地,建模者通过收集来自那些熟悉应用程序但不熟练的数据建模者的人的信息开发信息模型。建模者必须能够用非技术企业专家可以理解的术语在概念层次上与数据结构进行通讯。建模者也必须能以简单的单元分析信息,对样本数据进行处理。ORM专门被设计为改进这种联系。 图 1. 对象角色模型   图中的圆代表对象;矩形代表论断。在ORM中,象在逻辑中一样,一个论断只是带有对象洞的语句。箭头和点代表系统中的约束。   例如,在"人有电话"这个事实的诊断上的箭头可以翻译为:   有可能某个人有多于一个电话,并且至少有一个人有电话。   在"人生于某个日期"这个事实中,在论断上的箭头与连接对象与论断的点的结合表明:   每个人确切地出生于一个日期。   与 ER的比较   实体关系(ER)是另一种类型的数据库建模。ORM模型的简单性与ER相应部分的比较:  图 2. 实体关系   ORM以简单对象和论断的形式描述企业事实,而实体关系方法论以术语实体(拥有属性并参与关系)描述世界。在图1的ORM例子中,人,电话,地址和日期都表示为扮演有相互联系的角色的对象。在ER例子中,人是一个实体,它由属性:地址和电话进行描述。   例如,如果要把地址分解为街道,城市,州,ZIP码,那么必须把地址改变为具有相应属性的实体类型,结果会改变人与地址间的关系。尽管在上面的ORM模型中表示的约束也可以在ER中表示,但只要向模型中增加节点,或编写应用程序代码对模型进行补充,就可以表示其它约束。   ORM的优点   ORM提供的不只是描述不同对象间关系的一个简单而直接的方式。从示例中,可以看出ORM还提供了灵活性。使用ORM创建的模型比使用其它方法创建的模型更有能力适应系统的变化。另外,ORM允许非技术企业专家按样本数据谈论模型,因此他们可以使用真实世界的数据验证模型。因为ORM允许重用对象,数据模型能自动映射到正确标准化的数据库结构。   ORM模型的简单性简化了数据库查询过程。使用ORM查询工具,用户可以访问期望数据,而不必理解数据库的底层结构。   数据库生成和遍历引挚   象所有优秀的模型方法一样,ORM也不只是一个概念。它包含了不同的设计过程以帮助建模者映射概念的和逻辑的模型,或使用转换引挚在这些模型间转换。   ORM模型也能够自动地映射到大多数流行的关系型数据库所实现的数据库结构。检查前面的例子,ORM模型能自动生成ER图表或逻辑模型(可以翻译为SQL 代码,并适用于所选择的数据库)。   总结   利用非技术企业专家的知识对于确保应用程序满足企业需求是重要的。ORM,Visual Studio .NET的一个特性,是一个最初的、易于使用的概念性数据模型方法。通过使用不只是只有数据库专家才能理解的语言,ORM使那些充分理解了企业对应用程序需求的人能直接参与设计。 华腾软件学院 J2EE最新面试常见问题题库   ORM还支持完全的遍历引挚,因此一旦定义了企业需求,它们就能迅速的转化为逻辑和物理数据库图表。使用ORM,组织可以提高应用程序开发的效率,确保企业需求能被正确交付。 hibernate的优点和缺点? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序实用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。 大多数开发机构经常采取创建各自独立的数据持久层。一旦底层的数据结构发生改变,那么修改应用的其余部分使之适应这种改变的代价将是十分巨大的。Hibernate适时的填补了这一空白,它为Java应用提供了一个易用的、高效率的对象关系映射框架。hibernate是个轻量级的持久性框架,功能却非常丰富。 优点: a.Hibernate 使用 Java 反射机制 而不是字节码增强程序来实现透明性。 b.Hibernate 的性能非常好,因为它是个轻量级框架。 映射的灵活性很出色。 c. 它支持各种关系数据库,从一对一到多对多的各种复杂关系。 缺点:   它限制您所使用的对象模型。(例如,一个持久性类不能映射到多个表)其独有的界面和可怜的市场份额也让人不安,尽管如此,Hibernate 还是以其强大的发展动力减轻了这些风险。其他的开源持久性框架也有一些,不过都没有 Hibernate 这样有市场冲击力。 hibernate与JDBC的区别? 1.hibernate和jdbc主要区别就是,hibernate先检索缓存中的映射对象( 即hibernate操作的是对象),而jdbc则是直接操作数据库. 2.Hibernate是JDBC的轻量级的对象封装,它是一个独立的对象持久层框架,和App Server,和EJB没有什么必然的联系。Hibernate可以用在任何JDBC可以使用的场合 3.Hibernate是一个和JDBC密切关联的框架,所以Hibernate的兼容性和JDBC驱动,和数据库都有一定的关系,但是和使用它的Java程序,和App Server没有任何关系,也不存在兼容性问题。 还有一点,正确的使用JDBC技术,它的效率一定比hibernate要好,因为hibernate是基于jdbc的技术. 华腾软件学院 J2EE最新面试常见问题题库 hibernate中 dialect,lazy,inverse,cascade属性的用途? 在开发hibernate的程序时,需要进行SessionFactory的配置,简单地说,也就是建立与数据库之间连接的配置,在hibernate中一般使用xml文件来进行配置, dialect: 但是在该文件的配置中需要设置dialect方言属性值,对于不同的数据库,方言的值dialect是不同的,那么下面就列出在不同的数据库中如何设置该dialect值。常用的有 1. org.hibernate.dialect.MySQLDialect 2. org.hibernate.dialect.Oracle9Dialect 3. org.hibernate.dialect.HSQLDialect…… lazy: hibernate3.0中lazy有三个值,true,false,proxy,默认的是lazy="proxy". 具体设置成什么要看你的需求,并不是说哪个设置就是最好的。 假如在student对象中包含一个head对象 如果你确定在用student对象的时候就要用到head对象里的属性,那你就设置立即加载,因为设置立即加载那么在查询student的同时就会查询student的head,hibernate就会在查询的时候关联两张表从而生成的sql就可能只有一条。而如果你设置的是延迟加载,那么肯定会要生成1+N条sql语句:其中“1”是查询student的语句,“N”是根据N个student的id去查询head的N条语句。而且,延迟加载是要用到的时候才去执行查询,这样系统判断那里需要加载,那里不需要加载也需要时间,性能上肯定就不如立即加载了! 如果,你是有的地方需要用到student的时候才用到head属性,那么你就设置成延迟加载,因为查询2张表的数据肯定要比查询1张表的数据消耗大。 到低要怎样设置就要看你的实际需求了 inverse: 1)inverse中提及的side其实是指一个类或者表的概念,双向关联其实是指双方都可以取得对方的应用。 2)维护关系这个名词还是稍显模糊或者晦涩。我们一般说A类或者A表(这里的表的是指多对多的连接表)有责任维护关系,其实这里的意思是说,我在应 用在更新,创建,删除(读就不用说了,双向引用正是为了方便读而出现)A类或者A表时,此时创建的SQL语句必须有责任保证关系的正确修改。 3)inverse=false的side(side其实是指inverse=false所位于的class元素)端有责任维护关系,而inverse=true端无须维护这些关系。 4)我们说inverse设立不当会导致性能低下,其实是说inverse设立不当,会产生多余重复的SQL语句甚至致使JDBC exception的throw。这是我们在建立实体类关系时必须需要关注的地方。一般来说,inverse=true是推荐使用,双向关联中双方都设置 inverse=false的话,必会导致双方都重复更新同一个关系。但是如果双方都设立inverse=true的话,双方都不维护关系的更新,这也是 不行的,好在一对多中的一端:many-to-one默认是inverse=false,避免了这种错误的产生。但是多对多就没有这个默认设置了,所以很 多人经常在多对多的两端都使用inverse=true,结果导致连接表的数据根本没有记录,就是因为他们双分都没有责任维护关系。所以说,双向关联中最 好的设置是一端为inverse=true,一端为inverse=false。一般inverse=false会放在多的一端,那么有人提问了, many-to-many两边都是多的,inverse到底放在哪儿?其实hibernate建立多对多关系也是将他们分离成两个一对多关系,中间连接一 个连接表。所以通用存在一对多的关系,也可以这样说:一对多是多对多的基本组成部分。 华腾软件学院 J2EE最新面试常见问题题库 cascade: cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或删除对像时更方便一些,只要在cascade的源头上插入或是删除,所有 cascade的关系就会被自己动的插入或是删除。便是为了能正确的cascade,unsaved-value是个很重要的属性。Hibernate通 过这个属性来判断一个对象应该save还是update,如果这个对象的id是unsaved-value的话,那说明这个对象不是 persistence object要save(insert);如果id是非unsaved-value的话,那说明这个对象是persistence object(数据库中已存在),只要update就行了。saveOrUpdate方法用的也是这个机制。 hibernate中延迟加载的用途和使用场合?   延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。下面我们就分别介绍这些种类的延迟加载的细节。 A、实体对象的延迟加载: 如果想对实体对象使用延迟加载,必须要在实体的映射配置文件中进行相应的配置,如下所示:     …… 通过将class的lazy属性设置为true,来开启实体的延迟加载特性。如果我们运行下面的代码: User user=(User)session.load(User.class,”1”);(1) System.out.println(user.getName());(2) 当运行到(1)处时,Hibernate并没有发起对数据的查询,如果我们此时通过一些调试工具(比如JBuilder2005的Debug工具),观察此时user对象的内存快照,我们会惊奇的发现,此时返回的可能是User$EnhancerByCGLIB$$bede8986类型的对象,而且其属性为null,这是怎么回事?还记得前面我曾讲过session.load()方法,会返回实体对象的代理类对象,这里所返回的对象类型就是User对象的代理类对象。在Hibernate中通过使用CGLIB,来实现动态构造一个目标对象的代理类对象,并且在代理类对象中包含目标对象的所有属性和方法,而且所有属性均被赋值为null。通过调试器显示的内存快照,我们可以看出此时真正的User对象,是包含在代理对象的CGLIB$CALBACK_0.target属性中,当代码运行到(2)处时,此时调用user.getName()方法,这时通过CGLIB赋予的回调机制,实际上调用CGLIB$CALBACK_0.getName()方法,当调用该方法时,Hibernate会首先检查CGLIB$CALBACK_0.target属性是否为null,如果不为空,则调用目标对象的getName方法,如果为空,则会发起数据库查询,生成类似这样的SQL语句:select * from user where id=’1’;来查询数据,并构造目标对象,并且将它赋值到CGLIB$CALBACK_0.target属性中。     这样,通过一个中间代理对象,Hibernate实现了实体的延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。所以实体的延迟加载是用通过中间代理类完成的,所以只有session.load()方法才会利用实体延迟加载,因为只有session.load()方法才会返回实体类的代理类对象。 华腾软件学院 J2EE最新面试常见问题题库 B、集合类型的延迟加载: 在Hibernate的延迟加载机制中,针对集合类型的应用,意义是最为重大的,因为这有可能使性能得到大幅度的提高,为此Hibernate进行了大量的努力,其中包括对JDK Collection的独立实现,我们在一对多关联中,定义的用来容纳关联对象的Set集合,并不是java.util.Set类型或其子类型,而是net.sf.hibernate.collection.Set类型,通过使用自定义集合类的实现,Hibernate实现了集合类型的延迟加载。为了对集合类型使用延迟加载,我们必须如下配置我们的实体类的关于关联的部分:     …..     通过将元素的lazy属性设置为true来开启集合类型的延迟加载特性。我们看下面的代码: User user=(User)session.load(User.class,”1”); Collection addset=user.getAddresses();       (1) Iterator it=addset.iterator();                (2) while(it.hasNext()){ Address address=(Address)it.next(); System.out.println(address.getAddress()); } 当程序执行到(1)处时,这时并不会发起对关联数据的查询来加载关联数据,只有运行到(2)处时,真正的数据读取操作才会开始,这时Hibernate会根据缓存中符合条件的数据索引,来查找符合条件的实体对象。 这里我们引入了一个全新的概念——数据索引,下面我们首先将接一下什么是数据索引。在Hibernate中对集合类型进行缓存时,是分两部分进行缓存的,首先缓存集合中所有实体的id列表,然后缓存实体对象,这些实体对象的id列表,就是所谓的数据索引。当查找数据索引时,如果没有找到对应的数据索引,这时就会一条select SQL的执行,获得符合条件的数据,并构造实体对象集合和数据索引,然后返回实体对象的集合,并且将实体对象和数据索引纳入Hibernate的缓存之中。另一方面,如果找到对应的数据索引,则从数据索引中取出id列表,然后根据id在缓存中查找对应的实体,如果找到就从缓存中返回,如果没有找到,在发起select SQL查询。在这里我们看出了另外一个问题,这个问题可能会对性能产生影响,这就是集合类型的缓存策略。如果我们如下配置集合类型:     ….. 华腾软件学院 J2EE最新面试常见问题题库     这里我们应用了配置,如果采用这种策略来配置集合类型,Hibernate将只会对数据索引进行缓存,而不会对集合中的实体对象进行缓存。如上配置我们运行下面的代码: User user=(User)session.load(User.class,”1”); Collection addset=user.getAddresses();       Iterator it=addset.iterator();                while(it.hasNext()){ Address address=(Address)it.next(); System.out.println(address.getAddress()); } System.out.println(“Second query……”); User user2=(User)session.load(User.class,”1”); Collection it2=user2.getAddresses(); while(it2.hasNext()){ Address address2=(Address)it2.next(); System.out.println(address2.getAddress()); } 运行这段代码,会得到类似下面的输出: Select * from user where id=’1’; Select * from address where user_id=’1’; Tianjin Dalian Second query…… Select * from address where id=’1’; Select * from address where id=’2’; Tianjin Dalian 我们看到,当第二次执行查询时,执行了两条对address表的查询操作,为什么会这样?这是因为当第一次加载实体后,根据集合类型缓存策略的配置,只对集合数据索引进行了缓存,而并没有对集合中的实体对象进行缓存,所以在第二次再次加载实体时,Hibernate找到了对应实体的数据索引,但是根据数据索引,却无法在缓存中找到对应的实体,所以Hibernate根据找到的数据索引发起了两条select SQL的查询操作,这里造成了对性能的浪费,怎样才能避免这种情况呢?我们必须对集合类型中的实体也指定缓存策略,所以我们要如下对集合类型进行配置:     …..     华腾软件学院 J2EE最新面试常见问题题库 此时Hibernate会对集合类型中的实体也进行缓存,如果根据这个配置再次运行上面的代码,将会得到类似如下的输出: Select * from user where id=’1’; Select * from address where user_id=’1’; Tianjin Dalian Second query…… Tianjin Dalian 这时将不会再有根据数据索引进行查询的SQL语句,因为此时可以直接从缓存中获得集合类型中存放的实体对象。 C、       属性延迟加载:    在Hibernate3中,引入了一种新的特性——属性的延迟加载,这个机制又为获取高性能查询提供了有力的工具。在前面我们讲大数据对象读取时,在User对象中有一个resume字段,该字段是一个java.sql.Clob类型,包含了用户的简历信息,当我们加载该对象时,我们不得不每一次都要加载这个字段,而不论我们是否真的需要它,而且这种大数据对象的读取本身会带来很大的性能开销。在Hibernate2中,我们只有通过我们前面讲过的面性能的粒度细分,来分解User类,来解决这个问题(请参照那一节的论述),但是在Hibernate3中,我们可以通过属性延迟加载机制,来使我们获得只有当我们真正需要操作这个字段时,才去读取这个字段数据的能力,为此我们必须如下配置我们的实体类: ……     通过对元素的lazy属性设置true来开启属性的延迟加载,在Hibernate3中为了实现属性的延迟加载,使用了类增强器来对实体类的Class文件进行强化处理,通过增强器的增强,将CGLIB的回调机制逻辑,加入实体类,这里我们可以看出属性的延迟加载,还是通过CGLIB来实现的。CGLIB是Apache的一个开源工程,这个类库可以操纵java类的字节码,根据字节码来动态构造符合要求的类对象。根据上面的配置我们运行下面的代码: String sql=”from User user where user.name=’zx’ ”; Query query=session.createQuery(sql);    (1) List list=query.list(); for(int i=0;i PERSON_KEY 在配置文件中这么写,插入的时候不用管id这个就行了 hibernate中缓存是什么?   缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。   缓存的介质一般是内存,所以读写速度很快。但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期。   Hibernate的缓存包括Session的缓存和SessionFactory的缓存,其中SessionFactory的缓存又可以分为两类:内置缓存和外置缓存。Session的缓存是内置的,不能被卸载,也被称为Hibernate的第一级缓存。SessionFactory的内置缓存和Session的缓存在实现方式上比较相似,前者是SessionFactory对象的一些集合属性包含的数据,后者是指Session的一些集合属性包含的数据。SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句,映射元数据是映射文件中数据的拷贝,而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来,SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此SessionFactory不需要进行内置缓存与映射文件的同步。SessionFactory的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的拷贝,外置缓存的介质可以是内存或者硬盘。SessionFactory的外置缓存也被称为Hibernate的第二级缓存。   Hibernate的这两级缓存都位于持久化层,存放的都是数据库数据的拷贝,那么它们之间的区别是什么呢?为了理解二者的区别,需要深入理解持久化层的缓存的两个特性:缓存的范围和缓存的并发访问策略。   持久化层的缓存的范围   缓存的范围决定了缓存的生命周期以及可以被谁访问。缓存的范围分为三类。   1 事务范围: 华腾软件学院 J2EE最新面试常见问题题库   缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。在此范围下,缓存的介质是内存。事务可以是数据库事务或者应用事务,每个事务都有独自的缓存,缓存内的数据通常采用相互关联的的对象形式。   2 进程范围:   缓存被进程内的所有事务共享。这些事务有可能是并发访问缓存,因此必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖于进程的生命周期,进程结束时,缓存也就结束了生命周期。进程范围的缓存可能会存放大量的数据,所以存放的介质可以是内存或硬盘。缓存内的数据既可以是相互关联的对象形式也可以是对象的松散数据形式。松散的对象数据形式有点类似于对象的序列化数据,但是对象分解为松散的算法比对象序列化的算法要求更快。   3 集群范围:   在集群环境中,缓存被一个机器或者多个机器的进程共享。缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致性,缓存中的数据通常采用对象的松散数据形式。   对大多数应用来说,应该慎重地考虑是否需要使用集群范围的缓存,因为访问的速度不一定会比直接访问数据库数据的速度快多少。   持久化层可以提供多种范围的缓存。如果在事务范围的缓存中没有查到相应的数据,还可以到进程范围或集群范围的缓存内查询,如果还是没有查到,那么只有到数据库中查询。事务范围的缓存是持久化层的第一级缓存,通常它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常是可选的。   持久化层的缓存的并发访问策略   当多个并发的事务同时访问持久化层的缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。   在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。因此可以设定以下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。   事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。   读写型:提供了Read Committed事务隔离级别。仅仅在非集群的环境中适用。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。   非严格读写型:不保证缓存与数据库中数据的一致性。如果存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。   只读型:对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。   事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低。   什么样的数据适合存放到第二级缓存中?   1 很少被修改的数据   2 不是很重要的数据,允许出现偶尔并发的数据   3 不会被并发访问的数据   4 参考数据   不适合存放到第二级缓存的数据?   1 经常被修改的数据   2 财务数据,绝对不允许出现并发   3 与其他应用共享的数据。   Hibernate的二级缓存 华腾软件学院 J2EE最新面试常见问题题库   如前所述,Hibernate提供了两级缓存,第一级是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,不允许而且事实上也无法比卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。 第二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此第二级缓存是进程范围或者集群范围的缓存。这个缓存中存放的对象的松散数据。第二级对象有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate集成。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存 。   Hibernate的二级缓存策略的一般过程如下:   1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。   2) 把获得的所有数据对象根据ID放入到第二级缓存中。   3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。   4) 删除、更新、增加数据的时候,同时更新缓存。 Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query缓存。   Hibernate的Query缓存策略的过程如下:   1) Hibernate首先根据这些信息组成一个Query Key,Query Key包括条件查询的请求一般信息:SQL, SQL需要的参数,记录范围(起始位置rowStart,最大记录个数maxRows),等。   2) Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key放入到Query缓存中。   3) Query Key中的SQL涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关的Query Key都要从缓存中清空。 hibernate的生命周期? 华腾软件学院 J2EE最新面试常见问题题库 实体对象的生命周期有三种状态:    1.Transient(自由状态)    此时的实体对象和数据库中的记录无关联,只是一个普通的JavaBean。    2.Persistent(持久状态)    此时的实体对象和数据库中的记录有关联,其变更将由Hibernate固化到数据库中。该实体对象处于由Hibernate框架所管理的状态。     3.Detached(游离状态)    处于Persistent状态的对象,其对应的Session实例关闭之后,那么,此对象就处于"Detached"状态。Detached状态和Transient状态的区别在于Detached状态的对象可以再次与某个Session实例相关联而成为Persistent对象。    从实体对象是否被纳入Hibernate实体管理容器的角度,Transient和Detached状态的实体对象可以统称为VO(Value Object),而被管理的实体对象称为PO(Persistent Object)。两者的区别:    1.VO是相对独立的实体对象,处于非管理状态。    2.PO是Hibernate纳入其实体管理容器(Entity Map)的对象,它代表了与数据中某条记录对应的Hibernate实体,PO的变化在事务提交时将反映到实际数据库中。    3.如果一个PO与其对应的Session实例分离,那么此时,它又会变成一个VO。 OpenSessionInViewFilter在程序中使用? 假设在你的应用中Hibernate是通过spring 来管理它的session.如果在你的应用中没有使用OpenSessionInViewFilter或者OpenSessionInViewInterceptor。session会在transaction结束后关闭。 如果你采用了spring的声明式事务模式,它会对你的被代理对象的每一个方法进行事务包装(AOP的方式)。如下: PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED,readOnly 华腾软件学院 J2EE最新面试常见问题题库 目标类org.appfuse.service.impl.BaseManager 的 save *方法的事务类型PROPAGATION_REQUIRED ,remove* 方法的事务类型PROPAGATION_REQUIRED其他的方法的事务类型是PROPAGATION_REQUIRED,readOnly。所以给你的感觉是调用这个名为“manager”的bean的方法之后session就关掉了。 如果应用中使用了OpenSessionInViewFilter或者OpenSessionInViewInterceptor,所有打开的session会被保存在一个线程变量里。在线程退出前通过 OpenSessionInViewFilter或者OpenSessionInViewInterceptor断开这些session。 为什么这么做?这主要是为了实现Hibernate的延迟加载功能。基于一个请求 一个hibernate session的原则。 spring中对OpenSessionInViewFilter的描述如下: 它是一个Servlet2.3过滤器,用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。 例如: 它允许在事务提交之后延迟加载显示所需要的对象。 这个过滤器和 HibernateInterceptor 有点类似:它是通过线程实现的。无论是没有事务的应用,还是有业务层事务的应用(通过HibernateTransactionManager 或 JtaTransactionManager的方式实现)它都适用。在后一种情况下,事务会自动采用由这个filter绑定的Session来进行相关的操作以及根据实际情况完成提交操作。 警告: 如果在你的应用中,一次请求的过程中使用了单一的一个HIbernate Session,在这种情况下,采用这个filter会产生一些以前没遇到的问题。特别需要注意的是通过 Hibernate Session重新组织持久化对象之间关系的相关操作需要在请求的最开始进行。以免与已经加载的相同对象发生冲突。 或者,我们可以通过指定"singleSession"="false"的方式把这个过滤器调到延期关闭模式。这样在一次请求的过程中不会使用一个单一的Session.每一次数据访问或事务相关操作都使用属于它自己的session(有点像不使用Open Session in View).这些session都被注册成延迟关闭模式,即使是在这一次的请求中它相关操作已经完成。 "一次请求一个session" 对于一级缓存而言很有效,但是这样可以带来副作用。例如在saveOrUpdate的时候或事物回滚之后,虽然它和“no Open Session in View”同样安全。但是它却允许延迟加载。 它会在spring的web应用的上下文根中查找Session工厂。它也支持通过在web.xml中定义的“SessionFactoryBeanName”的init-param元素 指定的Session工厂对应的bean的 名字来查找session工厂。默认的bean的名字是"sessionFactory".他通过每一次请求查找一次SessionFactory的方式来避免由初始化顺序引起的问题(当使用ContextLoaderServlet 来集成spring的时候 ,spring 的应用上下文是在这个filter 之后才被初始化的)。 默认的情况下,这个filter 不会同步Hibernate Session.这是因为它认为这项工作是通过业务层的事务来完成的。而且HibernateAccessors 的FlushMode为FLUSH_EAGER.如果你 想让这个filter在请求完成以后同步session.你需要覆盖它的closeSession方法,在这个方法中在调用父类的关闭session操作之前同步session.此外你需要覆盖它的getSession() 华腾软件学院 J2EE最新面试常见问题题库 方法。返回一个session它的FlushMode 不是默认的FlushMode.NEVER。需要注意的是getSession()和closeSession()方法只有在single session的模式中才被调用。 在myfaces的wiki里提供了OpenSessionInViewFilter的一个子类如下: public class OpenSessionInViewFilter extends org.springframework.orm.hibernate3.support.OpenSessionInViewFilter { /** * we do a different flushmode than in the codebase * here */ protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { Session session = SessionFactoryUtils.getSession(sessionFactory, true); session.setFlushMode(FlushMode.COMMIT); return session; } /** * we do an explicit flush here just in case * we do not have an automated flush */ protected void closeSession(Session session, SessionFactory factory) { session.flush(); super.closeSession(session, factory); } } hibernate中有几种检索方式?每种方式的区别? 在hibernate开发过程中,查询是最多用到的。我们肯定会问自己一个问题: Hibernate的检索方式有很多,load/get检索,HQL(find,Query)检索,QBC(Criteria,QBE)检索以及本地数据库SQL检索. 那么,在实际应用中到底选择哪一种检索好?它们之间的检索有哪些联系和区别呢? 答: 哪一种检索并无根本的优劣,而是要看不同的情况,结合各种查询的优点和缺点,考虑采用哪种检索会更加简单和合适一点。 HQL功能最强大,适合各种情况,但是动态条件查询构造起来很不方便 Criteria最适合动态条件查询,不太适合统计查询,QBE还不够强大,只适合相当简单的查询 NativeSQL可以实现特定数据库的SQL,但是可移植性就牺牲了 Hibernate2的Criteria功能不够完善,所以Hibernate2上面可用的只有HQL和NativeSQL,Hibernate3的Criteria已经非常强大了。 华腾软件学院 J2EE最新面试常见问题题库 针对web应用来说,大部分常规查询都是动态条件查询,所以首选使用Criteria,并且Hibernate3提供了DetachedCriteria,可以在web层构造好DetachedCriteria再进入session执行查询,非常方便实用的特性。 但是涉及到统计查询和非常复杂的关联查询,Criteria就无能为力了,这种情况下我选择使用HQL。 最后如果必须使用某些数据库的特性,例如Oracle的"...connect with ... by"这样的SQL,则选择使用NativeSQL。 在hibernate开发过程中,查询是最多用到的。我们肯定会问自己一个问题: Hibernate的检索方式有很多,load/get检索,HQL(find,Query)检索,QBC(Criteria,QBE)检索以及本地数据库SQL检索. 那么,在实际应用中到底选择哪一种检索好?它们之间的检索有哪些联系和区别呢? 答: 哪一种检索并无根本的优劣,而是要看不同的情况,结合各种查询的优点和缺点,考虑采用哪种检索会更加简单和合适一点。 HQL功能最强大,适合各种情况,但是动态条件查询构造起来很不方便 Criteria最适合动态条件查询,不太适合统计查询,QBE还不够强大,只适合相当简单的查询 NativeSQL可以实现特定数据库的SQL,但是可移植性就牺牲了 Hibernate2的Criteria功能不够完善,所以Hibernate2上面可用的只有HQL和NativeSQL,Hibernate3的Criteria已经非常强大了。 针对web应用来说,大部分常规查询都是动态条件查询,所以首选使用Criteria,并且Hibernate3提供了DetachedCriteria,可以在web层构造好DetachedCriteria再进入session执行查询,非常方便实用的特性。 但是涉及到统计查询和非常复杂的关联查询,Criteria就无能为力了,这种情况下我选择使用HQL。 最后如果必须使用某些数据库的特性,例如Oracle的"...connect with ... by"这样的SQL,则选择使用NativeSQL。 1 导航对象图检索方式 根据已经加载的对象,导航到其他对象,例如:对于已经加载的Customer对象,调用它的getOrders().iterator()方法就可以导航到所有相关联的Order对象。 2 OID检索方式 按照对象的OID来检索对象。Session的get()和load()方法提供了这种功能。 华腾软件学院 J2EE最新面试常见问题题库 spring: SSH整合过程? struts、spring、hibernate的整合步骤: 1.导入struts、spring、hibernate所必须的包 2.在web.xml中配置 contextConfigLocation /WEB-INF/applicationContext.xml org.springframework.web.context.ContextLoaderListener< stener-class> < stener> 3.在struts-config.xml中配置 spring的优点和缺点? Spring的优势不言而喻: 1. 提供了一种管理对象的方法,可以把中间层对象有效地组织起来。一个完美的框架“黏合剂”。 2. 采用了分层结构,可以增量引入到项目中。 3. 有利于面向接口编程习惯的养成。 4. 目的之一是为了写出易于测试的代码。 5. 非侵入性,应用程序对Spring API的依赖可以减至最小限度。 6. 一致的数据访问介面。 7. 一个轻量级的架构解决方案。 spring的缺点: 1. 中断了应用程序的逻辑,使代码变得不完整,不直观。此时单从Source无法完全把握应用的所有行为。 2. 将原本应该代码化的逻辑配置化,增加了出错的机会以及额外的负担。 3. 时光倒退,失去了IDE的支持。在目前IDE功能日益强大的时代,以往代码重构等让人头痛的举动越来越容易。而且IDE还提供了诸多强大的辅助功能,使得编程的门槛降低很多。通常来说,维护代码要比维护配置文件,或者配置文件+代码的混合体要容易的多。 4. 调试阶段不直观,后期的bug对应阶段,不容易判断问题所在。 华腾软件学院 J2EE最新面试常见问题题库 spring中的过滤器如何配置?        Spring character encoding filter       org.springframework.web.filter.CharacterEncodingFilter                  encoding           GBK                    Spring character encoding filter       /*      注意:org.springframework.web.filter.CharacterEncodingFilter类是spring内置的字符集过滤器,在org.springframework.web.filter还有其他内置过滤器 ioc的解释?注入方式?在程序中的使用? Spring有三个注入方式,type1,type2,type3 type1 接口依赖 type2 setter/getter type3 构造方法 type2,type3较用常用 首先来看一下type2 type2 setter/getter(引用注入) 例如,存在一个User类和Home类 user类里一个userName;一个Home对象的属性. public class User {        private String userName;     private Home myHome;        public Home getMyHome() { return myHome;}        public void setMyHome(Home myHome) { this.myHome = myHome;}        public String getUserName() { return userName;}        public void setUserName(String userName) { this.userName = userName;} } public class Home {        private String homeAddr;        public String getHomeAddr() { return homeAddr;}        public void setHomeAddr(String homeAddr) { this.homeAddr = homeAddr;} } public class TestMain { 华腾软件学院 J2EE最新面试常见问题题库     public static void main(String[] args) {         ApplicationContext context=new FileSystemXmlApplicationContext("test/lyx/applicationContext.xml");         User user1=(User)context.getBean("user");             System.out.println(“姓名为: ”+user1.getUserName());         System.out.println(“家庭住址是: ”+user1.getMyHome().getHomeAddr());     } } 将两个bean的注入:(applicationContext.xml配置如下)                                           大连                                                                liuyuanxi                                                                这里的user bean,引用了home bean, 运行时会打出  姓名为:liuyuanxi 家庭住址是:大连 这种方式就是setter/getter方式注入,习惯用JavaBean的人应该很容易理解这种方法,也就是能过来指定属性. liuyuanxi来指定属性所对应的值.多少个属性就有多少个 这里一个人,和家是两个类,也提到了两个bean之间的引用.也就是user bean给名字赋了值,home bean给地址赋了值.如果在user bean中想引入 home bean中的地址.就用不再用 type3 构造方法注入 这里我们在User里加入一个构造器 public User(Home myHome){ this.myHome=myHome; } 然后 把配置文件改一下:autowire=constructor;                                           大连                                                                liuyuanxi                                                                运行时会打出  姓名为:liuyuanxi 家庭住址是:大连 这种方式就是构造器注入 我们再来看看spring的绑定 也就是通过bean属性autowire来设置 1.      通过bean属性autowire="byType"的设置可以使用bean在运行时候根据去寻找同类型的已定义属性,如果找不到则处于未绑定状态.(已定义好指在applicationContext.xml中初始化)这里我们把配置文件的 user bean的autowire改成autowire="byType",注意一定要把User的构造器去掉,要不然先找构造器,会出错.这里的home bean是属于,test.lyx.Home类型的,而user bean里有两个属性一个属性已经初始化,而另一个属性Home,就会自动找到. applicationContext.xml配置如下:                                           大连                                                                liuyuanxi                                                                华腾软件学院 J2EE最新面试常见问题题库 运行时会打出  姓名为:liuyuanxi 家庭住址是:大连 这种方式就是构造器注入 但这样的寻找方式有一个弱点, 假如再注入一个Home bean,叫home1,运行时就会找到两个bean,出错.                                           beijing                      如果我们想解决这种问题也很简单,我们可以把autowire改为,autowire="byName"方式来寻找. 但是这里一定要注意:Home bean的id名,一定要和属性名字一样.这里应该改成,id="myHome"                                           dalian                                                                北京                      这样的话 运行时会打出  姓名为:liuyuanxi 家庭住址是:北京 而不在是大连了,这种寻找方式就是byName,也就是按属性的名字进行查询.注意:id一定要属性的名字一样. 2.我们来比较一个byname和 bytype这两种方式. byname要比bytype精确些,因为id,是不能重名的. 而且假如存在一这样一种情况,两个user bean,分别为user1,user2,那么user1,user2都可以,打出北京.重用性很好. 到这可能有人会想到.user1,和user2调用的是同一个Home吗.你可以把他们的hashcode();打出来,你会发现地址是一样的,也就是说,是同一个bean.这里是因为singleton="true"的原因,如果你把singleton改成了"false"那就不是一个对象了. 3.如果把autowire=” constructor”也就是构造器注入一定要注意了,他是以byType进行查找,也就是说,Home bean,是不能出现两次,否则就会出错了. 华腾软件学院 J2EE最新面试常见问题题库 4.如果autowire设置成为autodetect,他会一直找,直到找到一个合适的为止.constructor,bytype,byname的顺序去找.这种方式是不推荐使用的.因为你很难判断出执行的是那个. AOP的解释?注入方式?在程序中的使用? AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向方面编程。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的 解耦,AOP可以说也是这种目标的一种实现。 所谓AOP(面向方面)编程的核心实质就是对方法的拦截和注入。离开它,就不会有AOP了。 AOP的使用,在Spring2.X下的切面有两种实现方式,一种是以Java文件定义切面(其只是普通的Java类),然后在配置文件中声明定义的切面;另一种是在Java类中引入和 AOP相关的元数据(注释)。 spring中的事务处理? 对在上下文中配置的属性的处理,这里涉及的类是TransactionAttributeSourceAdvisor,这是一个通知器,用它来对属性值进行处理,属性信息放在TransactionAttribute 中来使用,而这些属性的处理往往是和对切入点的处理是结合起来的。对属性的处理放在类TransactionAttributeSource中完成。 创建事物的过程,这个过程是委托给具体的事物管理器来创建的,但Spring通过TransactionStatus来传递相关的信息。 对事物的处理通过对相关信息的判断来委托给具体的事物管理器完成。 数据库: 视图的用法? sqlserver 2005 例一、创建一个视图,用于查看产品、类别和供应商,其代码如下: --创建视图 CREATE VIEW view_例一 AS SELECT 产品.产品ID,产品.产品名称,类别.类别名称,供应商.公司名称 FROM 产品 JOIN 类别 ON 产品.类别ID = 类别.类别ID JOIN 供应商 ON 产品.供应商ID = 供应商.供应商ID GO --查看视图 SELECT * FROM view_例一 华腾软件学院 J2EE最新面试常见问题题库 GO Oracle数据库-视图的概念 一 视图的概念   视图是原始数据库数据的一种变换,是查看表中数据的另外一种方式。可以将视图看 成是一个移动的窗口,通过它可以看到感兴趣的数据。 视图是从一个或多个实际表中获得的,这些表的数据存放在数据库中。那些用于产生视 图的表叫做该视图的基表。一个视图也可以从另一个视图中产生。 视图的定义存在数据库中,与此定义相关的数据并没有再存一份于数据库中。通过视图 看到的数据存放在基表中。 视图看上去非常象数据库的物理表,对它的操作同任何其它的表一样。当通过视图修改 数据时,实际上是在改变基表中的数据;相反地,基表数据的改变也会自动反映在由基表 产生的视图中。由于逻辑上的原因,有些视图可以修改对应的基表,有些则不能(仅仅能 查询)。 二 视图的作用 * 简单性。看到的就是需要的。视图不仅可以简化用户对数据的理解,也可以简化他们 的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次 指定全部的条件。 * 安全性。通过视图用户只能查询和修改他们所能见到的数据。数据库中的其它数据则既 看不见也取不到。数据库授权命令可以使每个用户对数据库的检索限制到特定的数据库对 象上,但不能授权到数据库特定行和特定的列上。通过视图,用户可以被限制在数据的不 同子集上: 使用权限可被限制在基表的行的子集上。 使用权限可被限制在基表的列的子集上。 使用权限可被限制在基表的行和列的子集上。 使用权限可被限制在多个基表的连接所限定的行上。 使用权限可被限制在基表中的数据的统计汇总上。 使用权限可被限制在另一视图的一个子集上,或是一些视图和基表合并后的子集上。 * 逻辑数据独立性。视图可帮助用户屏蔽真实表结构变化带来的影响。 三 视图的 视图的安全性可以防止安全性未授权用户查看特定的行或列,是用户只能看到表中特定 行的方法如下: 1 在表中增加一个标志用户名的列; 2 建立视图,是用户只能看到标有自己用户名的行; 3 把视图授权给其他用户。 四 逻辑数据独立性 视图可以使应用程序和数据库表在一定程度上独立。如果没有视图,应用一定是建立在 表上的。有了视图之后,程序可以建立在视图之上, 从而程序与数据库表被视图分割开来。视图可以在以下几个方面使程序与数据独立: 1 如果应用建立在数据库表上,当数据库表发生变化时,可以在表上建立视图,通过视 图屏蔽表的变化,从而应用程序可以不动。 2 如果应用建立在数据库表上,当应用发生变化时,可以在表上建立视图,通过视图屏 蔽应用的变化,从而使数据库表不动。 3 如果应用建立在视图上,当数据库表发生变化时,可以在表上修改视图,通过视图屏 蔽表的变化,从而应用程序可以不动。 4 如果应用建立在视图上 华腾软件学院 J2EE最新面试常见问题题库 数据库的优化(程序优化,sql语句优化,数据库实例优化)? 在Apache, PHP, MySQL的体系架构中,MySQL对于性能的影响最大,也是关键的核心部分。对于Discuz!论坛程序也是如此,MySQL的设置是否合理优化,直接影响到论坛的速度和承载量!同时,MySQL也是优化难度最大的一个部分,不但需要理解一些MySQL专业知识,同时还需要长时间的观察统计并且根据经验进行判断,然后设置合理的参数。 下面我们了解一下MySQL优化的一些基础,MySQL的优化我分为两个部分,一是服务器物理硬件的优化;二是MySQL自身(my.cnf)的优化。 (1) 服务器硬件对MySQL性能的影响 a) 磁盘寻道能力(磁盘I/O),以目前高转速SCSI硬盘(7200转/秒)为例,这种硬盘理论上每秒寻道7200次,这是物理特性决定的,没有办法改变。MySQL每秒钟都在进行大量、复杂的查询操作,对磁盘的读写量可想而知。所以,通常认为磁盘I/O是制约MySQL性能的最大因素之一,对于日均访问量在100万PV以上的Discuz!论坛,由于磁盘I/O的制约,MySQL的性能会非常低下!解决这一制约因素可以考虑以下几种解决方案: 使用RAID-0+1磁盘阵列,注意不要尝试使用RAID-5,MySQL在RAID-5磁盘阵列上的效率不会像你期待的那样快; 抛弃传统的硬盘,使用速度更快的闪存式存储设备。经过Discuz!公司技术工程的测试,使用闪存式存储设备可比传统硬盘速度高出6-10倍左右。 b) CPU 对于MySQL应用,推荐使用S.M.P.架构的多路对称CPU,例如:可以使用两颗Intel Xeon 3.6GHz的CPU。 c) 物理内存对于一台使用MySQL的Database Server来说,服务器内存建议不要小于2GB,推荐使用4GB以上的物理内存。 (2) MySQL自身因素当解决了上述服务器硬件制约因素后,让我们看看MySQL自身的优化是如何操作的。对MySQL自身的优化主要是对其配置文件my.cnf中的各项参数进行优化调整。下面我们介绍一些对性能影响较大的参数。 由于my.cnf文件的优化设置是与服务器硬件配置息息相关的,因而我们指定一个假想的服务器硬件环境: CPU: 2颗Intel Xeon 2.4GHz 内存: 4GB DDR 硬盘: SCSI 73GB 下面,我们根据以上硬件配置结合一份已经优化好的my.cnf进行说明: # vi /etc/my.cnf 以下只列出my.cnf文件中[mysqld]段落中的内容,其他段落内容对MySQL运行性能影响甚微,因而姑且忽略。 [mysqld] port = 3306 serverid = 1 socket = /tmp/mysql.sock skip-locking # 避免MySQL的外部锁定,减少出错几率增强稳定性。 skip-name-resolve 禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求! 华腾软件学院 J2EE最新面试常见问题题库 back_log = 384 指定MySQL可能的连接数量。当MySQL主线程在很短的时间内接收到非常多的连接请求,该参数生效,主线程花费很短的时间检查连接并且启动一个新线程。 back_log参数的值指出在MySQL暂时停止响应新请求之前的短时间内多少个请求可以被存在堆栈中。 如果系统在一个短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP/IP连接的侦听队列的大小。不同的操作系统在这个队列大小上有它自己的限制。 试图设定back_log高于你的操作系统的限制将是无效的。默认值为50。对于Linux系统推荐设置为小于512的整数。 key_buffer_size = 256M # key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。 对于内存在4GB左右的服务器该参数可设置为256M或384M。 注意:该参数值设置的过大反而会是服务器整体效率降低! max_allowed_packet = 4M thread_stack = 256K table_cache = 128K sort_buffer_size = 6M 查询排序时所能使用的缓冲区大小。注意:该参数对应的分配内存是每连接独占!如果有100个连接,那么实际分配的总共排序缓冲区大小为100 × 6 = 600MB。所以,对于内存在4GB左右的服务器推荐设置为6-8M。 read_buffer_size = 4M 读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每连接独享! join_buffer_size = 8M 联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享! myisam_sort_buffer_size = 64M table_cache = 512 thread_cache_size = 64 query_cache_size = 64M 指定MySQL查询缓冲区的大小。可以通过在MySQL控制台执行以下命令观察: # > SHOW VARIABLES LIKE '%query_cache%'; # > SHOW STATUS LIKE 'Qcache%'; # 如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况; 如果Qcache_hits的值非常大,则表明查询缓冲使用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓冲;Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多。 tmp_table_size = 256M max_connections = 768 指定MySQL允许的最大连接进程数。如果在访问论坛时经常出现Too Many Connections的错误提 示,则需要增大该参数值。 max_connect_errors = 10000000 wait_timeout = 10 指定一个请求的最大连接时间,对于4GB左右内存的服务器可以设置为5-10。 thread_concurrency = 8 华腾软件学院 J2EE最新面试常见问题题库 该参数取值为服务器逻辑CPU数量×2,在本例中,服务器有2颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为4 × 2 = 8 skip-networking 开启该选项可以彻底关闭MySQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MySQL数据库服务器则不要开启该选项!否则将无法正常连接! oracle中过程和函数的区别? 从参数的返回情况来看: 如果返回多个参数值最好使用存储过程,如果只有一个返回值的话可以使用函数; 从调用情况来看: 如果在SQL语句(DML或SELECT)中调用的话一定是存储函数或存储的封装函数不可以是存储过程,但调用存储函数的时候还有好多限制以及函数的纯度等级的问题 如果是在过程化语句中调用的话,就要看你要实现什么样的功能。函数一般情况下是用来计算并返回一个计算结果而存储过程一般是用来完成特定的数据操作(比如修改、插入数据库表或执行某些DDL语句等等),所以虽然他们的语法上很相似但用户在使用他们的时候所需要完成的功能大部分情况下是不同的。 内链接查询如何使用? 1.内链接(inner join on) 结果集是返回两个表中符合条件的数据,而舍弃不符合条件的语句 select * from table1 inner join table2 on table1_id=table2_id 后面可以跟条件 名词解释: 1. HTTP: Hypertext Transfer Protocol 2. J2EE: Java 2 Platform,Enterprise Edition 3. JNDI: Java Naming and Directory Interface 4. SOAP: Simple Object Access Protocol 5. UDDI: Universal Description Discovery and Integration 6. OOP: Object Oriented Programming 7. AOP: Aspect Oriented Programming 8. IOC: Inversion of Control 9. DI: Dependence Injection 10. web: World Wide Web 11. ORM: Object/Relation Mapping 华腾软件学院 J2EE最新面试常见问题题库 12. DOM: Document Object Model 13. TCP: Transmission Control Protocol 14. UDP: User Datagram Protocol 15. IP: Internet Protocol

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享文档获得金币 ]
5 人已下载

下载文档

相关文档