2020-09-05

目录   JAVA最新面试题

一、Java 基础部分

二、Java 代码查错

三、算法与编程

四、html&JavaScript&ajax 部分

五、Java web 部分

六、数据库部分

七、XML 部分

八、流行的框架与新技术

九、软件工程与设计模式

十、j2ee 部分

十一、 ejb 部分

十二、 webservice 部分

十三、 Linux

十四、 问得稀里糊涂的题

十五、 其他


 

部分面试题,不太全,留邮箱就行,发给你们

一、Java 基础部分

1. JAVA 的基本数据类型有哪些 ? String 是不是基本数据类型 ?

Java 有 8 种基本数据类型: byte

int

short

long

double

float

Boolean

char

byte int short long 都属于整数类型.

Double float 属于浮点类型.

Boolean 为布尔类型

Char 为字符型

String 不是基本数据类型.它定义的为对象

2. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?

可以有多个类,但只能有一个 public 的类,并且 public 的类名必须与文件名相一致。

3. Java 有没有 goto?

java 中的保留字,现在没有在 java 中使用。

4. 说说&&&的区别.

&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都

为 true 时,整个运算结果才为 true,否则,只要有一方为 false,则结果为 false。

&&还具有短路的功能,即如果第一个表达式为 false,则不再计算第二个表达式,例如,对

于 if(str != null && !str.equals(“”))表达式,当 str 为 null 时,后面的表达式不会执行,所以不

会出现 NullPointerException 如果将&&改为&,则会抛出 NullPointerException 异常。

If(x==33

& ++y>0) y 会增长,If(x==33 && ++y>0)不会增长

&还可以用作位运算符,当&操作符两边的表达式不是 boolean 类型时,&表示按位与操作,

我们通常使用 0x0f 来与一个整数进行&运算,来获取该整数的最低 4 个 bit 位,例如,0x31

& 0x0f 的结果为 0x01。

备注:这道题先说两者的共同点,再说出&&和&的特殊之处,并列举一些经典的例子来表

明自己理解透彻深入、实际经验丰富。

5. JAVA 中如何跳出当前的多重嵌套循环?

在 Java 中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环

体的代码中使用带有标号的 break 语句,即可跳出外层循环。例如,

ok:

for(int i=0;i<10;i++){

for(int j=0;j<10;j++){

System.out.println(“i=” + i + “,j=” + j);

if(j == 5) break ok;

}

}

另外,我个人通常并不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里

层循环体代码的控制,例如,要在二维数组中查找到某个数字。

int arr[][] = {{1,2,3},{4,5,6,7},{9}};

boolean found = false;

for(int i=0;i<arr.length && !found;i++){

for(int j=0;j<arr[i].length;j++){ 

System.out.println(“i=” + i + “,j=” + j);

if(arr[i][j] == 5) {

found = true;

break;

}

}

}

6. switch 语句能否作用在 byte 上,能否作用在 long 上,能否作用在 String ?

在 switch(expr1)中,expr1 只能是一个整数表达式或者枚举常量(更大字体),整数表达

式可以是 int 基本类型或 Integer 包装类型,由于,byte,short,char 都可以隐含转换为 int,所

以,这些类型以及这些类型的包装类型也是可以的。显然,

long 和 String 类型都不符合 switch

的语法规定,并且不能被隐式转换成 int 类型,所以,它们不能作用于 swtich 语句中。

7. short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

对于 short s1 = 1; s1 = s1 + 1; 由于 s1+1 运算时会自动提升表达式的类型,所以结果是 int 型,

再赋值给 short 类型 s1 时,编译器将报告需要强制转换类型的错误。

对于 short s1 = 1; s1 += 1;由于 += 是 java 语言规定的运算符,

java 编译器会对它进行特殊处

理,因此可以正确编译。

8. char 型变量中能不能存贮一个中文汉字?为什么?

char 型变量是用来存储 Unicode 编码的字符的,unicode 编码字符集中包含了汉字,所以,

char 型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在 unicode 编码

字符集中,那么,这个 char 型变量中就不能存储这个特殊汉字。补充说明:unicode 编码占

用两个字节,所以,char 类型的变量也是占用两个字节。

9. 用最有效率的方法算出 2 乘以 8 等於几?

2 << 3,

因为将一个数左移 n 位,就相当于乘以了 2 的 n 次方,那么,一个数乘以 8 只要将其左移 3

位即可,而位运算 cpu 直接支持的,效率最高,所以,2 乘以 8 等於几的最效率的方法是 2 <<

3。

10. 请设计一个一百亿的计算器

首先要明白这道题目的考查点是什么,一是大家首先要对计算机原理的底层细节要清楚、要

知道加减法的位运算原理和知道计算机中的算术运算会发生越界的情况,二是要具备一定的

面向对象的设计思想。

首先,计算机中用固定数量的几个字节来存储的数值,所以计算机中能够表示的数值是有一

定的范围的,为了便于讲解和理解,我们先以 byte 类型的整数为例,它用 1 个字节进行存

储,表示的最大数值范围为-128 到+127。-1 在内存中对应的二进制数据为 11111111,如果

两个-1 相加,不考虑 Java 运算时的类型提升,运算后会产生进位,二进制结果为 1,11111110,

由于进位后超过了 byte 类型的存储空间,所以进位部分被舍弃,即最终的结果为 11111110,

也就是-2,这正好利用溢位的方式实现了负数的运算。-128 在内存中对应的二进制数据为

10000000,如果两个-128 相加,不考虑 Java 运算时的类型提升,运算后会产生进位,二进

制结果为 1,00000000,由于进位后超过了 byte 类型的存储空间,所以进位部分被舍弃,即

最终的结果为 00000000,也就是 0,这样的结果显然不是我们期望的,这说明计算机中的算

术运算是会发生越界情况的,两个数值的运算结果不能超过计算机中的该类型的数值范围。

由于 Java 中涉及表达式运算时的类型自动提升,我们无法用 byte 类型来做演示这种问题和

现象的实验,大家可以用下面一个使用整数做实验的例子程序体验一下:

int a = Integer.MAX_VALUE;

int b = Integer.MAX_VALUE;

int sum = a + b;

System.out.println(“a=”+a+”,b=”+b+”,sum=”+sum);

先不考虑 long 类型,由于 int 的正数范围为 2 的 31 次方,表示的最大数值约等于

2*1000*1000*1000,也就是 20 亿的大小,所以,要实现一个一百亿的计算器,我们得自己

设计一个类可以用于表示很大的整数,并且提供了与另外一个整数进行加减乘除的功能,大

概功能如下:

(1)这个类内部有两个成员变量,一个表示符号,另一个用字节数组表示数值的二进制数

(2)有一个构造方法,把一个包含有多位数值的字符串转换到内部的符号和字节数组中

(3)提供加减乘除的功能

public class BigInteger{

int sign;

byte[] val;

public Biginteger(String val){

sign = ;

val = ;

}

public BigInteger add(BigInteger other){

}

public BigInteger subtract(BigInteger other){

}

public BigInteger multiply(BigInteger other){

}

public BigInteger divide(BigInteger other){

}

}

备注:要想写出这个类的完整代码,是非常复杂的,如果有兴趣的话,可以参看 jdk 中自带

的 java.math.BigInteger 类的源码。面试的人也知道谁都不可能在短时间内写出这个类的完整

代码的,他要的是你是否有这方面的概念和意识,他最重要的还是考查你的能力,所以,你

不要因为自己无法写出完整的最终结果就放弃答这道题,你要做的就是你比别人写得多,证

明你比别人强,你有这方面的思想意识就可以了,毕竟别人可能连题目的意思都看不懂,什

么都没写,你要敢于答这道题,即使只答了一部分,那也与那些什么都不懂的人区别出来,

拉开了距离,算是矮子中的高个,机会当然就属于你了。另外,答案中的框架代码也很重要,

体现了一些面向对象设计的功底,特别是其中的方法命名很专业,用的英文单词很精准,这

也是能力、经验、专业性、英语水平等多个方面的体现,会给人留下很好的印象,在编程能

力和其他方面条件差不多的情况下,英语好除了可以使你获得更多机会外,薪水可以高出一

千元。

11. 使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容

还是可以改变的。例如,对于如下语句:

final StringBuffer a=new StringBuffer("immutable");

执行如下语句将报告编译期错误:

a=new StringBuffer("");

但是,执行如下语句则可以通过编译:

a.append(" broken!");

有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:

public void method(final StringBuffer param){

}

实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:

param.append("a");

12. "=="equals 方法究竟有什么区别?

==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存

储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作

符。

如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块

内存(堆内存),变量也占用一块内存,例如 Objet obj = new Object();变量 obj 是一个内存,

new Object()是另一个内存,此时,变量 obj 所对应的内存中存储的数值就是对象占用的那块

内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要

看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。

equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相

同,它比较的两个对象是独立的。例如,对于下面的代码:

String a=new String("foo");

String b=new String("foo");

两条 new 语句创建了两个对象,然后用 a,b 这两个变量分别指向了其中一个对象,这是两个

不同的对象,它们的首地址是不同的,即 a 和 b 中存储的数值是不相同的,所以,表达式

a==b 将返回 false,而这两个对象中的内容是相同的,所以,表达式 a.equals(b)将返回 true。

在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input

= …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上

找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都

是使用 equals 方法。

如果一个类没有自己定义 equals 方法,那么它将继承 Object 类的 equals 方法,Object 类的

equals 方法的实现代码如下:

boolean equals(Object o){

return this==o;

}

这说明,如果一个类没有自己定义 equals 方法,它默认的 equals 方法(从 Object 类继承的)

就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用 equals

和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回 false。如果你编写的

类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖 equals 方法,由

你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。

13. 静态变量和实例变量的区别?

语法定义上的区别:静态变量前要加 static 关键字,而实例变量前则不加。

程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量

才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所

以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分

配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来

使用,静态变量则可以直接使用类名来引用。

例如,对于下面的程序,无论创建多少个实例对象,永远都只分配了一个 staticVar 变量,并

且每创建一个实例对象,这个 staticVar 就会加 1;但是,每创建一个实例对象,就会分配一

个 instanceVar,即可能分配多个 instanceVar,并且每个 instanceVar 的值都只自加了 1 次。

public class VariantTest{

public static int staticVar = 0;

public int instanceVar = 0;

public VariantTest(){

staticVar++;

instanceVar++;

System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar);

}

}

备注:这个解答除了说清楚两者的区别外,最后还用一个具体的应用例子来说明两者的差异,

体现了自己有很好的解说问题和设计案例的能力,思维敏捷,超过一般程序员,有写作能力!

14. 是否可从一个 static 方法内发出对非 static 方法的调用?

不可以。因为非 static 方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对

象上进行方法调用,而 static 方法调用时不需要创建对象,可以直接调用。也就是说,当一

个 static 方法被调用时,可能还没有创建任何实例对象,如果从一个 static 方法中发出对非

static 方法的调用,那个非 static 方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,

一个 static 方法内部发出对非 static 方法的调用。

15. Integer int 的区别

int 是 java 提供的 8 种原始数据类型之一。

Java 为每个原始类型提供了封装类,

Integer 是 java

为 int 提供的封装类。int 的默认值为 0,而 Integer 的默认值为 null,即 Integer 可以区分出

未赋值和值为 0 的区别,int 则无法表达出未赋值的情况,例如,要想表达出没有参加考试

和考试成绩为 0 的区别,则只能使用 Integer。在 JSP 开发中,Integer 的默认为 null,所以用

el 表达式在文本框中显示时,值为空白字符串,而 int 默认的默认值为 0,所以用 el 表达式

在文本框中显示时,结果为 0,所以,int 不适合作为 web 层的表单数据的类型。

在 Hibernate 中,如果将 OID 定义为 Integer 类型,那么 Hibernate 就可以根据其值是否为 null

而判断一个对象是否是临时的,如果将 OID 定义为了 int 类型,还需要在 hbm 映射文件中

设置其 unsaved-value 属性为 0。

另外,Integer 提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer

中还定义了表示整数的最大值和最小值的常量。

16. Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math 类中提供了三个与取整有关的方法:ceil、floor、round,这些方法的作用与它们的英

文名称的含义相对应,例如,

ceil 的英文意义是天花板,该方法就表示向上取整,Math.ceil(11.3)

的结果为 12,Math.ceil(-11.3)的结果是-11;floor 的英文意义是地板,该方法就表示向下取整,

Math.ceil(11.6)的结果为 11,Math.ceil(-11.6)的结果是-12;最难掌握的是 round 方法,它表示

“四舍五入”,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,

Math.round(11.5)的结果为 12,Math.round(-11.5)的结果为-11。

17. 下面的代码有什么不妥之处?

1. if(username.equals(“zxx”){}

2.int x = 1;

return x==1?true:false;

18. 请说出作用域 publicprivateprotected,以及不写时的区别

说明:如果在修饰的元素上面没有写任何访问修饰符,则表示 friendly。

作用域

当前类 同一 package 子孙类 其他 package

public

protected

×

friendly

×

×

private

×

×

×

备注:只要记住了有 4 种访问权限,4 个访问范围,然后将全选和范围在水平和垂直方向上

分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。

19. Overload Override 的区别。Overloaded 的方法是否可以改变返回值的类型?

Overload 是重载的意思,Override 是覆盖的意思,也就是重写。

重载 Overload 表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相

同(即参数个数或类型不同)。

重写 Override 表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类

创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个

完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法

时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决

父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能

更小。如果父类的方法是 private 类型,那么,子类则不存在覆盖的限制,相当于子类中增

加了一个全新的方法。

至于 Overloaded 的方法是否可以改变返回值的类型这个问题,要看你倒底想问什么呢?这

个题目很模糊。如果几个 Overloaded 的方法的参数列表不一样,它们的返回者类型当然也

可以不一样。但我估计你想问的问题是:如果两个方法的参数列表完全一样,是否可以让它

们的返回值不同来实现重载 Overload。这是不行的,我们可以用反证法来说明这个问题,因

为我们有时候调用一个方法时也可以不定义返回结果变量,即不要关心其返回结果,例如,

我们调用 map.remove(key)方法时,虽然 remove 方法有返回值,但是我们通常都不会定义接

收返回结果的变量,这时候假设该类中有两个名称和参数列表完全相同的方法,仅仅是返回

类型不同,java 就无法确定编程者倒底是想调用哪个方法了,因为它无法通过返回结果类型

来判断。

override 可以翻译为覆盖,从字面就可以知道,它是覆盖了一个方法并且对其重写,以求达

到不同的作用。对我们来说最熟悉的覆盖就是对接口方法的实现,在接口中一般只是对方法

进行了声明,而我们在实现时,就需要实现接口声明的所有方法。除了这个典型的用法以外,

我们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意以下的几点:

1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;

2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;

3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;

4、被覆盖的方法不能为 private,否则在其子类中只是新定义了一个方法,并没有对其进行

覆盖。

overload 对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同的

方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM 就会根据不同的参数

样式,来选择合适的方法执行。在使用重载要注意以下的几点:

1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不

同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是 fun(int,float),

但是不能为 fun(int,int));

2、不能通过访问权限、返回类型、抛出的异常进行重载;

3、方法的异常类型和数目不会对重载造成影响;

4、对于继承来说,如果某一方法在父类中是访问权限是 priavte,那么就不能在子类对其进

行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。

20. 同学贡献的一些题?

1.搞了多个重载方法,参数分别是 int ,char,和 double,然后将 double x = 2,传递进去,会选

择哪个方法?

2.说说对 javaee 中的 session 的理解,你是怎么用 session 的?cvs/svn 下载

3.jdk 中哪些类是不能继承的:System,String,StringBuffer 等。

4.在 eclipse 中调试时,怎样查看一个变量的值。

5.判断身份证:要么是 15 位,要么是 18 位,最后一位可以为字母,并写程序提出其中的年

月日。

6.一个房子里有椅子,椅子有腿和背,房子与椅子是什么关系,椅子与腿和背是什么关系?

7.如果房子有多个椅子,就是聚合关系,否则是一种关联关系,当然,聚合是一种特殊的关

联。椅子与腿和背时组合关系。

8.说说 has a 与 is a 的区别。

9.工厂模式的类图

21. 线程如何同步和通讯?

同学回答说 synchronized 方法或代码块!面试官似乎不太满意!

只有多个 synchronized 代码块使用的是同一个监视器对象,这些 synchronized 代码块之间才

具有线程互斥的效果,假如 a 代码块用 obj1 作为监视器对象,假如 b 代码块用 obj2 作为监

视器对象,那么,两个并发的线程可以同时分别进入这两个代码块中。 …这里还可以分析

一下同步的原理。

对于同步方法的分析,所用的同步监视器对象是 this

接着对于静态同步方法的分析,所用的同步监视器对象是该类的 Class 对象

接着对如何实现代码块与方法的同步进行分析。

22. ClassLoader 如何加载 class

jvm 里有多个类加载,每个类加载可以负责加载特定位置的类,例如,bootstrap 类加载负责

加载 jre/lib/rt.jar 中的类, 我们平时用的 jdk 中的类都位于 rt.jar 中。extclassloader 负责加载

jar/lib/ext/*.jar 中的类,appclassloader 负责 classpath 指定的目录或 jar 中的类。除了 bootstrap

之外,其他的类加载器本身也都是 java 类,它们的父类是 ClassLoader。

23. Servlet 的生命周期?

Servlet 被服务器实例化后,容器运行其 init 方法,请求到达时运行其 service 方法,service

方法自动派遣运行与请求对应的 doXXX 方法(doGet,doPost)等,当服务器决定将实例销

毁的时候调用其 destroy 方法。

与 cgi 的区别在于 servlet 处于服务器进程中,它通过多线程方式运行其 service 方法,一个

实例可以服务于多个请求,并且其实例一般不会销毁,而 CGI 对每个请求都产生新的进程,

服务完成后就销毁,所以效率上低于 servlet

24. 抽象类的作用?

25. ArrayList 如何实现插入的数据按自定义的方式有序存放?

class MyBean implements Comparable{

public int compareTo(Object obj){

if(! obj instanceof MyBean)

throw new ClassCastException() //具体异常的名称,我要查 jdk 文档。

MyBean other = (MyBean) obj;

return age > other.age?1:age== other.age?0:-1;

}

}

class MyTreeSet {

private ArrayList datas = new ArrayList();

public void add(Object obj){

for(int i=0;i<datas.size();i++){

if(obj.compareTo(datas.get(i) != 1){

datas.add(i,obj);

}

}

}

}

26. 分层设计的好处?

把各个功能按调用流程进行了模块化,模块化带来的好处就是可以随意组合,举例说明:如

果要注册一个用户,流程为显示界面并通过界面接收用户的输入,接着进行业务逻辑处理,

在处理业务逻辑又访问数据库,如果我们将这些步骤全部按流水帐的方式放在一个方法中编

写,这也是可以的,但这其中的坏处就是,当界面要修改时,由于代码全在一个方法内,可

能会碰坏业务逻辑和数据库访问的码,同样,当修改业务逻辑或数据库访问的代码时,也会

碰坏其他部分的代码。分层就是要把界面部分、业务逻辑部分、数据库访问部分的代码放在

各自独立的方法或类中编写,这样就不会出现牵一发而动全身的问题了。这样分层后,还可

以方便切换各层,譬如原来的界面是 Swing,现在要改成 BS 界面,如果最初是按分层设计

的,这时候不需要涉及业务和数据访问的代码,只需编写一条 web 界面就可以了。

下面的仅供参考,不建议照搬照套,一定要改成自己的语言,发现内心的感受:

分层的好处:1.实现了软件之间的解耦;2.便于进行分工;3.便于维护;4.提高软件组件的重

用;5.便于替换某种产品,比如持久层用的是 hibernate,需要更换产品用 toplink,就不用其他

业务代码,直接把配置一改;6.便于产品功能的扩展;7.便于适用用户需求的不断变化

27. 序列化接口的 id 有什么用?

对象经常要通过 IO 进行传送,让你写程序传递对象,你会怎么做?把对象的状态数据用某

种格式写入到硬盘,Person->“zxx,male,28,30000”àPerson,既然大家都要这么干,并且没

有个统一的干法,于是,sun 公司就提出一种统一的解决方案,它会把对象变成某个格式进

行输入和输出,这种格式对程序员来说是透明(transparent)的,但是,我们的某个类要想

能被 sun 的这种方案处理,必须实现 Serializable 接口。

ObjectOutputStream.writeObject(obj);

Object obj = ObjectInputStream.readObject();

假设两年前我保存了某个类的一个对象,这两年来,我修改该类,删除了某个属性和增加了

另外一个属性,两年后,我又去读取那个保存的对象,或有什么结果?未知!sun 的 jdk 就

会蒙了。为此,一个解决办法就是在类中增加版本后,每一次类的属性修改,都应该把版本

号升级一下,这样,在读取时,比较存储对象时的版本号与当前类的版本号,如果不一致,

则直接报版本号不同的错!

28. StringBuffer StringBuilder 的区别?

因为 StringBuilder sbuilder = ;是线程不安全的,运行效率高,如果一个字符串变量是在方法

里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用 StringBuilder。

如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用

StringBuffer。

29. hashCode 方法的作用?

首先,想要明白 hashCode 的作用,你必须要先知道 Java 中的集合。

总的来说,Java 中的集合(Collection)有两类,一类是 List,再有一类是 Set。你知道

它们的区别吗?前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重

复。那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该

依据什么来判断呢?这就是 Object.equals 方法了。但是,如果每增加一个元素就检查一次,

那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说,如果集合中

现在已经有 1000 个元素,那么第 1001 个元素加入集合时,它就要调用 1000 次 equals 方法。

这显然会大大降低效率。于是,Java 采用了哈希表的原理。可以简单理解,hashCode 方法

实际上返回的就是对象存储的物理地址(实际可能并不是)。这样一来,当集合要添加新的

元素时,先调用这个元素的 hashCode 方法,就一下子能定位到它应该放置的物理位置上。

如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果

这个位置上已经有元素了,就调用它的 equals 方法与新元素进行比较,相同的话就不存了,

不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用 equals

方法的次数就大大降低了,几乎只需要一两次。

所以,Java 对于 eqauls 方法和 hashCode 方法是这样规定的:

1、如果两个对象相同,那么它们的 hashCode 值一定要相同;

2、如果两个对象的 hashCode 相同,它们并不一定相同

上面说的对象相同指的是用 eqauls 方法比较。

你当然可以不按要求去做了,但你会发现,相同的对象可以出现在 Set 集合中。同时,增

加新元素的效率会大大下降。

30. webservice 问得很多

31. 设计出计算任意正整数的阶层?

32. oracle 数据库中需要查询出前 8 条记录的 sql 语句怎么写?

33. 什么是 SOA,谈谈你的 SOA 的理解。service orientied architecture

SOA 是指为了解决在 Internet 环境下业务集成的需要,通过连接能完成特定任务的独立功能

实体实现的一种软件系统架构。

1) 软件系统架构:SOA 不是一种语言,也不是一种具体的技术而是一种软件系统架构,

它尝试给出在特定环境下推荐采用的一种架构,从这个角度上来说,它更像一种模式

(Pattern)。因此它与很多已有的软件技术比如面向对象技术,是互补的而非互斥的。它们分

别面向不同的应用场景,用来满足不同的特定需求。

2) SOA 的使用范围:需求决定同时也限制功能。SOA 并不是包治百病的万灵丹,它最

主要的应用场合在于解决在 Internet 环境下的不同商业应用之间的业务集成问题。

34. 如何实现线程间的通讯?

在 Java 语言中,提供了各种各样的输入输出流(stream),使我们能够很方便的对数据进行

操作,其中,管道(pipe)流是一种特殊的流,用于在不同线程(threads)间直接传送数据。

一个线程发送数据到输出管道,另一个线程从输入管道中读数据。通过使用管道,实现不同

线程间的通讯。无需求助于类似临时文件之类的东西。本文在简要介绍管道的基本概念后,

将以一个具体的实例 pipeapp 加以详细说明。

1.管道的创建与使用

Java 提供了两个特殊的专门的类专门用于处理管道,它们就是 pipedinputstream 类和

pipeoutputstream 类。

Pipedinputstream 代表了数据在管道中的输出端,也就是线程向管道读数据的一端;

pipeoutputstream 代表了数据在管道中的输入端,也就是线程向管道写数据的一端,这两个

类一起使用可以提供数据的管道流。

为了创建一个管道流,我们必须首先创建一个 pipeoutstream 对象,然后,创建

pipeinputstream 对象,实例如下:

pipeout= new pipedyoutstream();

pipein= new pipedputsteam(pipepout);

一旦创建了一个管道后,就可以象操作文件一样对管道进行数据的读写。

2.演示程序: pipeapp

应用程序由三个程序组成:主线程(pipeapp.Java)及由主线程启动的两个二级线程

(ythread.Java 和 zthread.Java),它们使用管道来处理数据。程序从一个内容为一行一行"x"

字母的"input.txt"文件中读取数据,使用管道传输数据,第一次是利用线程 ythread 将数据"x"

转换为"y",最后利用线程 zthread 将"y"转换为"z",之后,程序在屏幕上显示修改后的数据。

主线程 (pipeapp.Java)

在 main()方法中,程序首先创建一个应用对象:pipeapp pipeapp=new pipeapp();

由于程序中流操作都需要使用 IOException 异常处理,所以设置了一个 try 块。在 try 中,为

了从源文件中读取数据,程序为"input.txt"文件创建了一个输入流 Xfileln,:

fileinputstream xfileln= new fileinputstream("input.txt");

新的输入流传递给 changetoy()方法,让线程 ythread 能读取该文件:

inputstream ylnpipe =pipeapp.changetoy(xfileln);

changetoy()方法创建将输入数据"x"改变到"y"的线程 ythread,并返回该线程的输入管道:

inputstream zlnpipe = pipeapp.changetoz(ylnpipe);

changetoz()方法启动将数据从"y"改变到"z"的线程 zehread,主程序将使用从 changetoz()

返回的输入管道。得到以修改的数据。

然后,程序将管道输入流定位到 datainputstream 对象,使程序能够使用 readline()方法读

取数据:

datainputstream inputstream = new datainputstream(zlnpiepe);

创建了输入流以后,程序就可以以行一行的读取数据病显示在屏幕上。

 

String str= inputstream.readline();

While(str!=null){

system.out.println(str);

str=inputstream.readline();

}

显示完成之后,程序关闭输入流:

inputstream.close();

changetoy()方法

changetoy()方法首先通过传递一个参数 inputstream 给 datainputstream 对象来定位资源的

输入流,使程序能使用 readline()方法从流中读取数据:

datainputstream xfileln =new datainutstream(inputstream);

然后,changetoy()创建输出管道和输入管道:

pipeoutstream pipeout = new pipeoutputstream();

pipeinputstream pipeln = new pipedinputsteam(pipeout);

为了能够使用 println()方法输出修改的后的文本行到管道,程序将输出管道定位到

printstream 对象:

printstream printstream = new printstream(pipeout);

现在,程序可以创建将数据从 x 改变到 y 的线程,该线程是 ythread 类的一个对象,他

传递两个参数:输入文件(xfileln)和输出管道(调用 printstream)

ythread ythread =new thread(xfileln,printstream);

之后,程序启动线程:

changetoz()方法

changetoz()方法与 changetoy()方法很相似,他从 changetoy()返回的输入流开始:

datainputstream yfileln= new datainputstream(inputstream);

程序创建一个新的管道:

pipedoutstream pipeout2 = new pipedoutputstream();

pipedinputstream pipeln2 = new pipedinputsream(pipeout2);

该线程通过这个新的管道发出修改后的数据(输入流 pipeln2)给主程序。

源程序如下:

//

//pipeapp.Java-pipeapp 的主应用程序

//

import Java.io.*

class pipeapp{

public static void main(string[] args){

pipeapp pipeapp=new pipeapp();

try{

fileinputstream xfile =new fileinputstream("input.txt");

inputstream ylnpipe = pipeapp.changetoy(xfileln);

inputstream zlnpipe=pipeapp.changetoz(ylnpipe);

system.out.println();

system.out.println("here are the results");

system.out.pringln();

datainputstream inputstream = nes datainputstream(zlnpipe);

 

string str = inputstream.readline();

while (str!=null){

system.out.println(str);

str=inputstream.readline();

}

inputstream.close();

}

catch(exception e){

system.out.println(e.tostring());

}

}

public inputstream changetoy(inputstream inputstream){

try{

datainputstream pipeout = new datainputsteam(inputstream);

pipedoutstream pipeout = new pipedoutputstream();

pipedlnsteam pipeln = new pipedlnputstream(pipeout);

printstream printstream = new printstream(pipeout);

ythread ythread = new ythread(xfileln,printstream);

ythread.start();

return pipeln;

}

catch(exeption e){

system.out.println(x.tostring());

}

return null;

}

public inputstream changetoz(inputstream inputsteam){

try{

datainputstream yfileln = new datainputstream(inputstream);

pipeoutputstream pipeln2 = new pipedinputstream(pipeout2);

printrstream printstream2 = new printsteam(pipeout2);

zthread zthread = new zthread(yfileln,printstream2);

zthread.start();

return pipeln2;

}

catch(exception e){

system.out.println(e.tostring());

}

return null;

}

}

Ythread 类和 Zthread 类

由于 ythread 类与 zthread 类基本一样,在此仅以 ythread 为例加以说明。

Ythread 的构造器接收两个参数:输入的文件和第一个管道的输出端,构造器存储这两

 

个参数作为类的数据成员:

Ythread(datainputstream xfileln,pringstream printstream){

this.xfileln = xfileln;

this.printstream = printstream;

}

线程通过 run()方法来处理数据。首先读取一行数据,确保 xstring 不为空的情况下循环

执行:

string xstring = xfileln.readline();

每读一行数据,完成一次转换

string ystring = xstring.replace('x','y');

然后将修改后的数据输出到管道的输出端:

prinstream.prinrln(ystring);

为了确保所有缓冲区的数据完全进入管道的输出端:

pringstram.flush();

循环完成后,线程关闭管道输出流:

pringstram.close();

ythread 类的源程序如下:

//

//ythread.Java

//

import Java.io.*;

class ythread exteads thread{

datainputstream xfileln;

pringstream printstream;

ythread(datainputstream xfileln,pringstream.printstream){

this.xfileln = xfileln;

this.printstream = printstream;

}

public void run(){

try{

string xstring = xfileln.readline();

while(xstring!=null){

string ystring= xstring.replace('x','y');

printstream.pringln(ystring);

printstream.flush();

xstring= xfileln.readline();

}

printstream.close();

}

catch{ioexception e}{

system.out.println(e.tostring());

}

}

}

 

35. 编程题:

编程 1.编写一个函数将一个十六进制数的字符串参数转换成整数返回。

String str = “13abf”;

int len = str.length;

int sum = 0;

for(int i=0;i<len;i++){

char c = str.charAt(len-1-i);

int n = Character.digit(c,16);

sum += n * (1<<(4*i));

}

其实,也可以用 Integer.parseInt(str,16),但面试官很可能是想考我们的编码基本功。

编程 2 :银行贷款的还款方式中最常用的是一种叫“等额本息”,还款法,即借款人在约定

还款期限内的每一期(月)归还的金额(产生的利息+部分本金)都是相等的,现有一笔总

额为 T 元的 N 年期住房贷款,年利率为 R,要求算出每一期的还款的本金和利息总额,请

写出解决思路和任意一种编程语言实现的主要代码。

思路:既然是按月还款,那我就要将 N 年按月来计算,即要还 N*12 个月,这样就可以求出

每月要还的本金。由于每月要还的那部分本金所欠的时间不同,所以,它们所产生的利息是

不同的,该部分本金的利息为:部分本金额*所欠月数*月利率。应该是这么个算法,如果利

息还计利息,如果月还款不按年利率来算,老百姓算不明白的。

int monthMoney = T/N/12;

float monthRate = R/12;

int totalMonth = N * 12;

float totalRate = 0;

for(int i=1;i<=totalMonth;i++){

totalRate += monthMoney * monthRate * i;

}

int result = monthMoney + totalRate/N/12;

36. ****Spring DI 是什么(注:除了 IOCAOP 这些概念,还不太清楚 DI 的概念)

不管是面向对象,还是面向过程,都需要分成许多的块,然后由这些部件协同工作完成任务

要协同工作就会产生依赖,一个方法调用另一个方法,一个对象包含另一个对象

如果对象 A 包含对象 B 的话,就需要在 A 里 new 一个 B

依赖注入从具体类 B 里抽象出接口 IB——IB 的具体实现可能有很多 B,B1,B2...很多种——

这样 A 可以不用再 new 具体的 B 了,而是跟 IoC 容器说:我要一个 IB(getBean("IB"))。

然后,由容器根据配置文件来做具体的 new 的工作。具体 new 的是哪个,由配置文件从代

码外部决定,要更换成 B,B1,或是 B2...修改配置文件就能做到,不用再改代码了

37. *任意数字序列“123456”之类,输出它们所有的排列组合

38. *****什么是 AOP(注:会用,但感觉说不清楚)

AOP: 面向切面编程:Aspect Oriented Programming

AOP 是 OOP 的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面编程。

主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。

主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务

逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑

 

的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一

添加功能的一种技术。AOP 实际是 GoF 设计模式的延续,设计模式孜孜不倦追求的是调用

者和被调用者之间的解耦,AOP 可以说也是这种目标的一种实现。

在 Spring 中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务

(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它

们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关

注点,例如日志或事务支持。

应用举例:

假设有在一个应用系统中,有一个共享的数据必须被并发同时访问,首先,将这个数据

封装在数据对象中,称为 Data Class,同时,将有多个访问类,专门用于在同一时刻访问这

同一个数据对象。

为了完成上述并发访问同一资源的功能,需要引入锁 Lock 的概念,也就是说,某个时

刻,当有一个访问类访问这个数据对象时,这个数据对象必须上锁 Locked,用完后就立即

解锁 unLocked,再供其它访问类访问。

使用传统的编程习惯,我们会创建一个抽象类,所有的访问类继承这个抽象父类,如下:

abstract class Worker{

abstract void locked();

abstract void accessDataObject();

abstract void unlocked();

}

我注:由上面这些题,可以看出,思想很重要,只有琢磨思想和原理的人才能很好地回答这

些问题!

2 题的答案:

String str = “xafdvs”;

char[] arr1 = str.toCharArray();

char[] arr2 = Arrays.copyOf(arr1,arr1.length);

for(int i=0;i<arr1.length-1;i++){

for(int j = i+1;j<arr2.length;j++){

syso: arr1[i] + “,” + arr2[j];

}

}

3.题的答案:

1.概念介绍:所谓 AOP,即 Aspect orientied program,就是面向方面的编程,

2.解释什么是方面:贯穿到系统的各个模块中的系统一个功能就是一个方面,

比如,记录日志,统一异常处理,事务处理,全限检查,这些功能都是软件系统

的一个面,而不是一点,在各个模块中都要出现。

3.什么是面向方面编程:把系统的一个方面的功能封装成对象的形式来处理

4.怎么进行面向方面编程:把功能模块对应的对象作为切面嵌入到原来的各个系统模块中,

采用代理技术,代理会调用目标,同时把切面功能的代码(对象)加入进来,所以,

用 spring 配置代理对象时只要要配两个属性,分别表示目标和切面对象(Advisor)。

39. 构造器 Constructor 是否可被 override?

构造器 Constructor 不能被继承,因此不能重写 Override,但可以被重载 Overload。

 

40. 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具

体类(concrete class)? 抽象类中是否可以有静态的 main 方法?

接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承具体类。抽象类

中可以有静态的 main 方法。

备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答,你想想,如果你是 java

语言的设计者,你是否会提供这样的支持,如果不提供的话,有什么理由吗?如果你没有道

理不提供,那答案就是肯定的了。

只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有 abstract 方法。

41. clone()方法时,通常都有一行代码,是什么?

clone 有缺省行为,super.clone();因为首先要把父类中的成员复制到位,然后才是复制自己

的成员。

42. 谈谈你对面向对象的理解

面向对象是一种程序的设计方法,或者说它是一种程序设计范型,其基本思想是使用对象,

类,继承,封装,消息等基本概念来进行程序设计。

它是从现实世界中客观存在的事物(即对象)出发来构造软件系统,并在系统构造中尽可能

运用人类的自然思维方式,强调直接以问题域(现实世界)中的事物为中心来思考问题,认

识问题,并根据这些事物的本质特点,把它们抽象地表示为系统中的对象,作为系统的基本

构成单位(而不是用一些与现实世界中的事物相关比较远,并且没有对应关系的其它概念来

构造系统)。这可以使系统直接地映射问题域,保持问题域中事物及其相互关系的本来面貌。

它可以有不同层次的理解:

从世界观的角度可以认为:面向对象的基本哲学是认为世界是由各种各样具有自己的运动规

律和内部状态的对象所组成的;不同对象之间的相互作用和通讯构成了完整的现实世界。因

此,人们应当按照现实世界这个本来面貌来理解世界,直接通过对象及其相互关系来反映世

界。这样建立起来的系统才能符合现实世界的本来面目。

从方法学的角度可以认为:面向对象的方法是面向对象的世界观在开发方法中的直接运用。

它强调系统的结构应该直接与现实世界的结构相对应,应该围绕现实世界中的对象来构造系

统,而不是围绕功能来构造系统。

从程序设计的角度来看,面向对象的程序设计语言必须有描述对象及其相互之间关系的语言

成分。这些程序设计语言可以归纳为以下几类:系统中一切皆为对象;对象是属性及其操作

的封装体;对象可按其性质划分为类,对象成为类的实例;实例关系和继承关系是对象之间

的静态关系;消息传递是对象之间动态联系的唯一形式,也是计算的唯一形式;方法是消息

的序列。

43. 面向对象的特征有哪些方面?

面向对象的编程语言有封装、继承 、抽象、多态等 4 个主要的特征。

1.封装:

封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、

低耦合”,防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装

的最基本单位,面向对象的封装比传统语言的封装更为清晰、更为有力。面向对象的封装就

是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变

量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。通常情况下,只要

记住让变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义成私有的,只

有这个类自己的方法才可以访问到这些成员变量,这就基本上实现对象的封装,就很容易找

 

出要分配到这个类上的方法了,就基本上算是会面向对象的编程了。把握一个原则:把对同

一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类

中。

例如,人要在黑板上画圆,这一共涉及三个对象:人、黑板、圆,画圆的方法要分配给哪个

对象呢?由于画圆需要使用到圆心和半径,圆心和半径显然是圆的属性,如果将它们在类中

定义成了私有的成员变量,那么,画圆的方法必须分配给圆,它才能访问到圆心和半径这两

个属性,人以后只是调用圆的画圆方法、表示给圆发给消息而已,画圆这个方法不应该分配

在人这个对象上,这就是面向对象的封装性,即将对象封装成一个高度自治和相对封闭的个

体,对象状态(属性)由这个对象自己的行为(方法)来读取和改变。一个更便于理解的例

子就是,司机将火车刹住了,刹车的动作是分配给司机,还是分配给火车,显然,应该分配

给火车,因为司机自身是不可能有那么大的力气将一个火车给停下来的,只有火车自己才能

完成这一动作,火车需要调用内部的离合器和刹车片等多个器件协作才能完成刹车这个动

作,司机刹车的过程只是给火车发了一个消息,通知火车要执行刹车动作而已。

2.抽象:

抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些

事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与

当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是

抽象。抽象包括行为抽象和状态抽象两个方面。例如,定义一个 Person 类,如下:

class Person{

String name;

int age;

}

人本来是很复杂的事物,有很多方面,但因为当前系统只需要了解人的姓名和年龄,所以上

面定义的类中只包含姓名和年龄这两个属性,这就是一种抽像,使用抽象可以避免考虑一些

与目标无关的细节。我对抽象的理解就是不要用显微镜去看一个事物的所有方面,这样涉及

的内容就太多了,而是要善于划分问题的边界,当前系统需要什么,就只考虑什么。

3.继承:

在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在

的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适

合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一

种关系,提高了软件的可重用性和可扩展性。

4.多态:

多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编

程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,

该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到

各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以

改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。多态性

增强了软件的灵活性和扩展性。例如,下面代码中的 UserDao 是一个接口,它定义引用变量

userDao 指向的实例对象由 daofactory.getDao()在执行的时候返回,有时候指向的是

UserJdbcDao 这个实现,有时候指向的是 UserHibernateDao 这个实现,这样,不用修改源代

 

码,就可以改变 userDao 指向的具体类实现,从而导致 userDao.insertUser()方法调用的具体

代码也随之改变,即有时候调用的是 UserJdbcDao 的 insertUser 方法,有时候调用的是

UserHibernateDao 的 insertUser 方法:

UserDao userDao = daofactory.getDao();

userDao.insertUser(user);

比喻:人吃饭,你看到的是左手,还是右手?

44. java 中实现多态的机制是什么?

靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方

法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运

行的那个对象的方法,而不是引用变量的类型中定义的方法。

45. abstract class interface 有什么区别?

含有 abstract 修饰符的 class 即为抽象类,abstract 类不能创建的实例对象。含有 abstract 方

法的类必须定义为 abstract class,abstract class 类中的方法不必是抽象的。abstract class 类中

定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方

法。如果子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为 abstract 类型。

接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口

中的方法定义默认为 public abstract 类型,接口中的成员变量类型默认为 public static final。

下面比较一下两者的语法区别:

1.抽象类可以有构造方法,接口中不能有构造方法。

2.抽象类中可以有普通成员变量,接口中没有普通成员变量

3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象

的普通方法。

4.抽象类中的抽象方法的访问类型可以是 public,protected 和(默认类型,虽然 eclipse 下不报

错,但应该也不行),但接口抽象方法只能是 public 类型的,并且默认即为 public abstract

类型。

5.抽象类中可以包含静态方法,接口中不能包含静态方法

6.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任

意,但接口中定义的变量只能是 public static final 类型,并且默认即为 public static final 类型。

7.一个类可以实现多个接口,但只能继承一个抽象类。

下面接着再说说两者在应用上的区别:

接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类

在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个

典型应用,假设某个项目的所有 Servlet 类都要用相同的方式进行权限判断、记录访问日志

和处理异常,那么就可以定义一个抽象的基类,让所有的 Servlet 都继承这个抽象基类,在

抽象基类的 service 方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中

只是完成各自的业务逻辑代码,伪代码如下:

public abstract class BaseServlet extends HttpServlet{

public final void service(HttpServletRequest request, HttpServletResponse response)

throws IOExcetion,ServletException{

记录访问日志

进行权限判断

if(具有权限){

try{

doService(request,response);

}

catch(Excetpion e){

记录异常信息

}

}

}

protected abstract void doService(HttpServletRequest request, HttpServletResponse response)

throws IOExcetion,ServletException;

//注意访问权限定义成 protected,显得既专业,又严谨,因为它是专门给子类用的

}

public class MyServlet1 extends BaseServlet{

protected void doService(HttpServletRequest request, HttpServletResponse response) throws

IOExcetion,ServletException{

本 Servlet 只处理的具体业务逻辑代码

}

}

父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。

备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,

最后再说两者的应用区别。比较两者语法细节区别的条理是:先从一个类中的构造方法、普

通成员变量和方法(包括抽象方法),静态变量和方法,继承性等 6 个方面逐一去比较回答,

接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功

底。

二、Java 代码查错

abstract class Name {

private String name;

public abstract boolean isStupidName(String name) {}

}

大侠们,这有何错误?

答案: 错。abstract method 必须以分号结尾,且不带花括号。

2.public class Something {

void doSomething () {

private String s = "";

int l = s.length();

}

}

 

有错吗?

答案: 错。局部变量前不能放置任何访问修饰符 (private,public,和 protected)。final 可以

用来修饰局部变量

(final 如同 abstract 和 strictfp,都是非访问修饰符,strictfp 只能修饰 class 和 method 而非

variable)。

3.abstract class Something {

private abstract String doSomething ();

}

这好像没什么错吧?

答案: 错。

abstract 的methods不能以private修饰。

abstract的 methods就是让子类 implement(实

现)具体细节的,怎么可以用 private 把 abstract

method 封锁起来呢? (同理,abstract method 前不能加 final)。

4.public class Something {

public int addOne(final int x) {

return ++x;

}

}

这个比较明显。

答案: 错。int x 被修饰成 final,意味着 x 不能在 addOne method 中被修改。

5.public class Something {

public static void main(String[] args) {

Other o = new Other();

new Something().addOne(o);

}

public void addOne(final Other o) {

o.i++;

}

}

class Other {

public int i;

}

和上面的很相似,都是关于 final 的问题,这有错吗?

答案: 正确。在 addOne method 中,参数 o 被修饰成 final。如果在 addOne method 里我们修

改了 o 的 reference

(比如: o = new Other();),那么如同上例这题也是错的。但这里修改的是 o 的 member vairable

(成员变量),而 o 的 reference 并没有改变。

6.class Something {

int i;

public void doSomething() {

System.out.println("i = " + i);

}

}

有什么错呢? 看不出来啊。

答案: 正确。输出的是"i = 0"。int i 属於 instant variable (实例变量,或叫成员变量)。instant

 

variable 有 default value。int 的 default value 是 0。

7.class Something {

final int i;

public void doSomething() {

System.out.println("i = " + i);

}

}

和上面一题只有一个地方不同,就是多了一个 final。这难道就错了吗?

答案: 错。final int i 是个 final 的 instant variable (实例变量,或叫成员变量)。final 的 instant

variable 没有 default value,必须在 constructor (构造器)结束之前被赋予一个明确的值。可以

修改为"final int i = 0;"。

8.public class Something {

public static void main(String[] args) {

Something s = new Something();

System.out.println("s.doSomething() returns " + doSomething());

}

public String doSomething() {

return "Do something ...";

}

}

看上去很完美。

答案: 错。看上去在 main 里 call doSomething 没有什么问题,毕竟两个 methods 都在同一个

class 里。但仔细看,main 是 static 的。static method 不能直接 call non-static methods。可改

成"System.out.println("s.doSomething() returns " + s.doSomething());"。同理,static method 不

能访问 non-static instant variable。

9.此处,Something 类的文件名叫 OtherThing.java

class Something {

private static void main(String[] something_to_do) {

System.out.println("Do something ...");

}

}

这个好像很明显。

答案: 正确。从来没有人说过 Java 的 Class 名字必须和其文件名相同。但 public class 的名字

必须和文件名相同。

10.interface A{

int x = 0;

}

class B{

int x =1;

}

class C extends B implements A {

public void pX(){

System.out.println(x);

}

 

public static void main(String[] args) {

new C().pX();

}

}

答案:错误。在编译时会发生错误(错误描述不同的 JVM 有不同的信息,意思就是未明确的

x 调用,两个 x 都匹配(就象在同时 import java.util 和 java.sql 两个包时直接声明 Date 一样)。

对于父类的变量,可以用 super.x 来明确,而接口的属性默认隐含为 public static final.所以可

以通过 A.x 来明确。

11.interface Playable {

void play();

}

interface Bounceable {

void play();

}

interface Rollable extends Playable, Bounceable {

Ball ball = new Ball("PingPang");

}

class Ball implements Rollable {

private String name;

public String getName() {

return name;

}

public Ball(String name) {

this.name = name;

}

public void play() {

ball = new Ball("Football");

System.out.println(ball.getName());

}

}

这个错误不容易发现。

答案: 错。"interface Rollable extends Playable, Bounceable"没有问题。interface 可继承多个

interfaces,所以这里没错。问题出在 interface Rollable 里的"Ball ball = new Ball("PingPang");"。

任何在 interface 里声明的 interface variable (接口变量,也可称成员变量),默认为 public static

final。也就是说"Ball ball = new Ball("PingPang");"实际上是"public static final Ball ball = new

Ball("PingPang");"。在 Ball 类的 Play()方法中,"ball = new Ball("Football");"改变了 ball 的

reference,而这里的 ball 来自 Rollable interface,Rollable interface 里的 ball 是 public static final

的,final 的 object 是不能被改变 reference 的。因此编译器将在"ball = new Ball("Football");"

这里显示有错。

三、算法与编程

108. java 实现一种排序;java 类实现序列化的方法(二种)? 如在 collection 框架中,

实现比较要实现什么样的接口?

 

用插入法进行排序代码如下

package test;

import java.util.*;

class InsertSort {

ArrayList al;

//定义一个链表

public InsertSort(int num,int mod)

//带参数的构造函数{

al = new ArrayList(num);

//实例化链表

Random rand = new Random();

//取一个随机数

System.out.println("The ArrayList Sort Before:");

for (int i=0;i<num ;i++ ) {

al.add(new Integer(Math.abs(rand.nextInt()) % mod + 1));

System.out.println("al["+i+"]="+al.get(i));

}

}

public void SortIt() {

Integer tempInt;

int MaxSize=1;

for(int i=1;i<al.size();i++) {

tempInt = (Integer)al.remove(i);

if(tempInt.intValue()>=((Integer)al.get(MaxSize-1)).intValue()) {

al.add(MaxSize,tempInt);

MaxSize++;

System.out.println(al.toString());

} else{

for (int j=0;j<MaxSize ;j++ ) {

if (((Integer)al.get(j)).intValue()>=tempInt.intValue()) {

al.add(j,tempInt);

MaxSize++;

System.out.println(al.toString());

break;

}

}

}

}

System.out.println("The ArrayList Sort After:");

for(int i=0;i<al.size();i++) {

System.out.println("al["+i+"]="+al.get(i));

}

}

public static void main(String[] args) {

InsertSort is = new InsertSort(10,100);

//定义一个类的对象

is.SortIt();

//调用类中的方法, 执行排序

}

 

}

JAVA 类实现序例化的方法是实现 java.io.Serializable 接口

Collection 框架中实现比较要实现 Comparable 接口和 Comparator 接口

109. 用反射机制声明长度为 10 int 型数组的表达式

import java.lang.reflect.Array;

public class IntArrayDemo {

public static void main(String[] args) {

Class c = int.class;

Object objArr = Array.newInstance(c, 10);

for(int i = 0; i < 10; i++) {

Array.set(objArr, i, i);

}

int[] arr=(int[])objArr;

for(int j = 0; j < arr.length; j++) {

System.out.println(arr[j]);

}

}

}

110. 编程题:设有n个人依围成一圈,从第1个人开始报数,数到第m个人出列,然后从

出列的下一个人开始报数,数到第m个人又出列,,如此反复到所有的人全部出列

为止。设n个人的编号分别为 12n,打印出出列的顺序;要求用 java 实现。

答:代码如下:

package test;

public class CountGame {

private static boolean same(int[] p, int l, int n) {

for (int i = 0; i < l; i++) {

if (p[i] == n) {

return true;

}

}

return false;

}

public static void play(int playerNum, int step) {

int[] p = new int[playerNum];

int counter = 1;

while (true) {

if (counter > playerNum * step) {

break;

}

for (int i = 1; i < playerNum + 1; i++) {

while (true) {

if (same(p, playerNum, i) == false)

 

break;

else

i = i + 1;

}

if (i > playerNum)

break;

if (counter % step == 0) {

System.out.print(i + " ");

p[counter / step - 1] = i;

}

counter += 1;

}

}

System.out.println();

}

public static void main(String[] args) {

play(10, 7);

}

}

111. 编写一个程序,将 a.txt 文件中的单词与 b.txt 文件中的单词交替合并到 c.txt 文件中,

a.txt 文件中的单词用回车符分隔,b.txt 文件中用回车或空格进行分隔。

package cn.itcast;

import java.io.File;

import java.io.FileReader;

import java.io.FileWriter;

public class MainClass {

public static void main(String[] args) throws Exception {

FileManager a = new FileManager("a.txt", new char[] { '\n' });

FileManager b = new FileManager("b.txt", new char[] { '\n', ' ' });

FileWriter c = new FileWriter("c.txt");

String aWord = null;

String bWord = null;

while ((aWord = a.nextWord()) != null) {

c.write(aWord + "\n");

bWord = b.nextWord();

if (bWord != null)

c.write(bWord + "\n");

}

while ((bWord = b.nextWord()) != null) {

c.write(bWord + "\n");

}

c.close();

 

}

}

class FileManager {

String[] words = null;

int pos = 0;

public FileManager(String filename, char[] seperators) throws Exception {

File f = new File(filename);

FileReader reader = new FileReader(f);

char[] buf = new char[(int) f.length()];

int len = reader.read(buf);

String results = new String(buf, 0, len);

String regex = null;

if (seperators.length > 1) {

regex = "" + seperators[0] + "|" + seperators[1];

} else {

regex = "" + seperators[0];

}

words = results.split(regex);

}

public String nextWord() {

if (pos == words.length)

return null;

return words[pos++];

}

}

112. 写一个程序,将 d:\java 目录下所有.java 文件复制到 d:\jad 目录,并将原来文件的扩

展名.java 改为.jad

答:listFiles 方法接受一个 FileFilter 对象,这个 FileFilter 对象就是过虑的策略对象,不同的

人提供不同的 FileFilter 实现,即提供了不同的过滤策略。

package test;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.FilenameFilter;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

public class Jad2Java {

public static void main(String[] args) throws Exception {

 

File srcDir = new File("java");

if (!(srcDir.exists() && srcDir.isDirectory()))

throw new Exception("目录不存在");

File[] files = srcDir.listFiles(new FilenameFilter() {

public boolean accept(File dir, String name) {

return name.endsWith(".java");

}

});

System.out.println(files.length);

File destDir = new File("jad");

if (!destDir.exists())

destDir.mkdir();

for (File f : files) {

FileInputStream fis = new FileInputStream(f);

String destFileName = f.getName().replaceAll("\\.java$", ".jad");

FileOutputStream fos = new FileOutputStream(new File(destDir,

destFileName));

copy(fis, fos);

fis.close();

fos.close();

}

}

private static void copy(InputStream ips, OutputStream ops)

throws Exception {

int len = 0;

byte[] buf = new byte[1024];

while ((len = ips.read(buf)) != -1) {

ops.write(buf, 0, len);

}

}

}

由本题总结的思想及策略模式的解析:

class jad2java{

1. 得到某个目录下的所有的 java 文件集合

1.1 得到目录 File srcDir = new File("d:\\java");

1.2 得到目录下的所有 java 文件:File[] files = srcDir.listFiles(new MyFileFilter());

1.3 只想得到.java 的文件: class MyFileFilter implememyts FileFilter{

public boolean accept(File pathname){

return pathname.getName().endsWith(".java")

}

 

}

2.将每个文件复制到另外一个目录,并改扩展名

2.1 得到目标目录,如果目标目录不存在,则创建之

2.2 根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。

2.3 根据表示目录的 File 和目标文件名的字符串,得到表示目标文件的 File。

//要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。

2.4 将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采

用抽象流的形式。

//方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。

}

分析 listFiles 方法内部的策略模式实现原理

File[] listFiles(FileFilter filter){

File[] files = listFiles();

//Arraylist acceptedFilesList = new ArrayList();

File[] acceptedFiles = new File[files.length];

int pos = 0;

for(File file: files){

boolean accepted = filter.accept(file);

if(accepted){

//acceptedFilesList.add(file);

acceptedFiles[pos++] = file;

}

}

Arrays.copyOf(acceptedFiles,pos);

//return (File[])accpetedFilesList.toArray();

}

四、html&JavaScript&ajax 部分

123. 判断第二个日期比第一个日期大

如何用脚本判断用户输入的的字符串是下面的时间格式 2004-11-21 必须要保证用户的输入

是此格式,并且是时间,比如说月份不大于 12 等等,另外我需要用户输入两个,并且后一

个要比前一个晚,只允许用 JAVASCRIPT,请详细帮助作答,,

//这里可用正则表达式判断提前判断一下格式,然后按下提取各时间字段内容

<script type="text/javascript">

window.onload = function(){

//这么写是为了实现 js 代码与 html 代码的分离,当我修改 js 时,不能影响 html 代

码。

document.getElementById("frm1").onsubmit =

function(){

var d1 = this.d1.value;

var d2 = this.d2.value;

if(!verifyDate (d1)) {alert("第一个日期格式不对");return false;}

if(!verifyDate (d2)) {alert("第二个日期格式不对");return false;}

if(!compareDate(d1,d2)) {alert("第二个日期比第一日期小");return false;}

};

}

 

function compareDate(d1,d2){

var arrayD1 = d1.split("-");

var date1 = new Date(arrayD1[0],arrayD1[1],arrayD1[2]);

var arrayD2 = d2.split("-");

var date2 = new Date(arrayD2[0],arrayD2[1],arrayD2[2]);

if(date1 > date2) return false;

return true;

}

function verifyDate(d){

var datePattern = /^\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/;

return datePattern.test(d);

}

</script>

<form id="frm1" action="xxx.html">

<input type="text" name="d1" />

<input type="text" name="d2" />

<input type="submit"/>

</form>

124. table 显示 n 条记录,每 3 行换一次颜色,即 123 用红色字体,456 用绿

色字体,789 用红颜色字体。

<body>

<table id="tbl">

<tr><td>1</td></tr>

<tr><td>2</td></tr>

<tr><td>3</td></tr>

<tr><td>4</td></tr>

<tr><td>5</td></tr>

<tr><td>6</td></tr>

<tr><td>7</td></tr>

<tr><td>8</td></tr>

<tr><td>9</td></tr>

<tr><td>10</td></tr>

</table>

</body>

<script type="text/javascript">

window.οnlοad=function(){

var tbl = document.getElementById("tbl");

rows = tbl.getElementsByTagName("tr");

for(i=0;i<rows.length;i++){

var j = parseInt(i/3);

if(j%2==0) rows[i].style.backgroundColor="#f00";

 

else rows[i].style.backgroundColor="#0f0";

}

}

</script>

125. HTML form 提交之前如何验证数值文本框的内容全部为数字? 否则的话提示

用户并终止提交?

<form οnsubmit=’return chkForm(this)’>

<input type="text" name="d1"/>

<input type="submit"/>

</form>

<script type=”text/javascript” />

function chkForm(this){

var value = thist.d1.value;

var len = value.length;

for(var i=0;i<len;i++){

if(value.charAt(i)>"9" || value.charAt(i)<"0"){

alert("含有非数字字符");

return false;

}

}

return true;

}

</script>

126. 请写出用于校验 HTML 文本框中输入的内容全部为数字的 javascript 代码

<input type="text" id="d1" οnblur=" chkNumber (this)"/>

<script type=”text/javascript” />

function chkNumber(eleText){

var value = eleText.value;

var len = value.length;

for(var i=0;i<len;i++){

if(value.charAt(i)>"9" || value.charAt(i)<"0"){

alert("含有非数字字符");

eleText.focus();

break;

}

}

}

</script>

除了写完代码,还应该在网页上写出实验步骤和在代码中加入实现思路,让面试官一看就明

白你的意图和检查你的结果。

127. 说说你用过那些 ajax 技术和框架,说说它们的区别

答:去掉对 web.xml 的监视,把 jsp 提前编辑成 Servlet。

 

有富余物理内存的情况,加大 tomcat 使用的 jvm 的内存

五、Java web 部分

128. Tomcat 的优化经验

答:去掉对 web.xml 的监视,把 jsp 提前编辑成 Servlet。

有富余物理内存的情况,加大 tomcat 使用的 jvm 的内存

129. HTTP 的请求过程?

当点击一个链接时,浏览器首先找到站点的 IP 地址,这是通过 DNS 来实现的,在找到 IP 地址后

就可以建立 TCP 连接了,连接建立后我们就可以发送请求了.但这个请求是什么样子的呢 ?

我们现在假设点击了一个从 www.webmonkey.com/HTML/96/47/Index2A , HTML 点击了

WWW.GRIPY.ORG/MATTARG/

这时浏览器会发出下面的请求:

Get/MATTARG/HTML/1.0

User-Agent: Mozilla/2.0(macitosh;1;PPC)

Accept: text/html: */*

Cookie: name = value

Refetet: http://www.webmonkey.com/html/96/47/index2a.html

Host: www.gtippy.org

第一行称为请求,它告诉服务器从 MATTMARG 取得文件,这是的目录一般是要加 / 的,下面

几行通知服务器你所使用的浏览器是什么类型,你所接收的数据是什么类型,如果你以前访问

过这个站点,站点可能向你发送了 Cookie ,如果你已经有了一个这样的 Cookie ,浏览器会将

这个 Cookie 返回给服务器, referer 行通知服务器用户从哪一页到达此页的.

下面服务器就要返回文件了,每次服务器返回文件时,都要返回一个 Http/1.0 响应,同进带有

状态码,在此之后是述内部的头信息,下面就是一个响应:

HTTP/1.0 200 Pound

Data: Mon 10 Feb 1997 23:48:22 GMT

Server: Apache/1.1 1 Hot&ired/1.0

Content-type: text/html

Last-Moditied: Tues,11 Feb 1997 22:45:55 GMT

不同的数据可能返回不同的 Content-type ,因此不同的内容需要不同的 Content-type ,因

此有时候这个过程是很慢的。

130. HTTP 请求的 GET POST 方式的区别

答:Form 中的 get 和 post 方法,在数据传输过程中分别对应了 HTTP 协议中的 GET 和 POST

方法。二者主要区别如下:

1)Get 是用来从服务器上获得数据,而 Post 是用来向服务器上传递数据;

2)Get 将表单中数据按照 variable=value 的形式,添加到 action 所指向的 URL 后面,

并且两者使用“?”连接,而各个变量之间使用“&”连接;Post 是将表单中的数据放在 form

的数据体中,按照变量和值相对应的方式,传递到 action 所指向 URL;

3)Get 是不安全的,因为在传输过程,数据被放在请求的 URL 中;Post 的所有操作对

用户来说都是不可见的;

4)Get 传输的数据量小,这主要是因为受 URL 长度限制;而 Post 可以传输大量的数据,

所以在上传文件只能使用 Post;

5)Get 限制 Form 表单的数据集必须为 ASCII 字符,而 Post 支持整个 ISO10646 字符集;

 

6)Get 是 Form 的默认方法。

131. 解释一下什么是 servlet

Servlet 是一种独立于平台和协议的服务器端的 Java 技术,可以用来生成动态的 Web 页面。

与传统的 CGI(计算机图形接口)和许多其他类似 CGI 技术相比,Servlet 具有更好的可移

植性、更强大的功能,更少的投资,更高的效率,更好的安全性等特点。

Servlet 是使用 Java Servlet 应用程序接口(API)及相关类和方法的 Java 程序。Java 语言

能够实现的功能,Servlet 基本上都能实现(除了图形界面之外)。Servlet 主要用于处理客

户端传来的 Http 请求,并返回一个响应。通常所说的 Servlet 就是指 HttpServlet,用于处理

Http 请求,其能够处理的请求有 doGet()、doPost()、service()等方法。在开发 Servlet 时,可

以直接继承 javax.servlet.http.HttpServlet。

Servlet 需要在 web.xml 中进行描述,例如:映射执行 Servlet 的名字,配置 Servlet 类、初

始化参数,进行安全配置、URL 映射和设置启动的优先权等。Servlet 不仅可以生成 HTML

脚本输出,也可以生成二进制表单输出。

Servlet 应用范围很广泛,我们现在用的很多流行的框架技术,其最基本的代码离不开

Servelt 的支持。比如我所熟悉的 SSH 框架,Spring 容器启动时,要在 web.xml 中装载 Spring

容器的 ActionContext 类来初始化 Spring 的一些参数,如进行依赖注入、数据库表的映射、

初始化系统的安全配置设置 read 等属性等一些相关操作。

132. 说一说 Servlet 的生命周期?

答:servlet 有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。

这个生存期由 javax.servlet.Servlet 接口的 init,service 和 destroy 方法表达。

Servlet 被服务器实例化后,容器运行其 init 方法,请求到达时运行其 service 方法,service

方法自动派遣运行与请求对应的 doXXX 方法(doGet,doPost)等,当服务器决定将实例销

毁的时候调用其 destroy 方法。

web 容器加载 servlet,生命周期开始。通过调用 servlet 的 init()方法进行 servlet 的初始化。

通过调用 service()方法实现,根据请求的不同调用不同的 do***()方法。结束服务,web 容

器调用 servlet 的 destroy()方法。

133. Servlet 的基本架构

package test;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

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 {

}

}

134. SERVLET API forward()redirect()的区别?

答:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后

者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的

地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量

使用 forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳

转到一个其它服务器上的资源,则必须使用 sendRedirect()方法。

135. 什么情况下调用 doGet()doPost()

Jsp 页面中的 FORM 标签里的 method 属性为 get 时调用 doGet(),为 post 时调用 doPost()。

136. 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):删除请求中的一个属性

137. 简述 HttpSession 的作用、使用方法,可用代码说明。

HttpSession 中 可 以 跟 踪 并 储 存 用 户 信 息 , 把 值 设 置 到 属 性 中 , 有 2 个 方 法 :

setAttribute(),getAttrribute();

 

例如:在一个方法中用 session.setAttribute(“student”,student);在 session 中设置一个属性名为

student,值为一个名为 student 的对象。而后可在同一 session 范围内用 getAttribute(“student”)

取出该属性,得到 student 对象。

六、数据库部分

160. 存储过程和函数的区别

存储过程是用户定义的一系列 sql 语句的集合,涉及特定表或其它对象的任务,用户可以调

用存储过程,而函数通常是数据库已定义的方法,它接收参数并返回某种类型的值并且不涉

及特定用户表。

161. 事务是什么?

 

事务是作为一个逻辑单元执行的一系列操作,一个逻辑工作单元必须有四个属性,称为

ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务:

原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。

一致性:事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都

必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如

B 树索引或双向链表)都必须是正确的。

隔离性:由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时

数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状

态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且

重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。

持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直

保持。

162. 游标的作用?如何知道游标已经到了最后?

游标用于定位结果集的行,通过判断全局变量@@FETCH_STATUS 可以判断是否到了最后,

通常此变量不等于 0 表示出错或到了最后。

163. 触发器分为事前触发和事后触发,这两种触发有和区别。语句级触发和行级触发有何

区别?

事前触发器运行于触发事件发生之前,而事后触发器运行于触发事件发生之后。通常事前触

发器可以获取事件之前和新的字段值。 语句级触发器可以在语句执行前或后执行,而行级

触发在触发器所影响的每一行触发一次。

164. 存储过程,触发器,范式,事务的概念及作用?

存储过程:是数据库管理系统里的一个很重要的对象。用它可以封装一些功能。把多个 SQL

语句封装到存储过程里面。起到封装功能的作用。类似面向对象里,封装对象的一个功能一

样。几乎任何可写成批处理的 Transact-SQL 代码都可用于创建存储过程。

触发器:触发器是在用户进行某项操作的时候,会触发触发器的执行。它类似于 JAVA 中图

形截面编程里的事件操作一样,是触发执行。和存储过程的主要区别在于:存储过程类似

JAVA 里面的对象一样,进行功能的封装(方法)。在调用的时候才会执行。而触发器只能

在别的操作执行的时候才会触发触发器的执行。

事务:类似于 JAVA 里面线程的同步一样,作为一个单元执行。它有四大特性:原子性,隔

离性,一致性,持久性。在 SQL SERVER 2000 里面还支持存储点的用法。大家都知道,事

务是做为一个单元运行,要么全部执行,要么全部不执行。但是有时候我们可以保证事务的

一部分可能正确执行,并且这些执行可以直接刷新到数据库里面。那么我们就可以在这个事

务的中间部分设置一个或者多个存储点。这样在这个事务大单元里就分成了几个小部分。如

果上面的部分执行正确,下面的部分执行错误,那么就没必要回滚整个事务,只需要回滚到

存储点的地方就可以了

范式:目地:规范化目的是使结构更合理,消除存储异常,使数据冗余尽量小,便于插入、

删除和更新

原则:遵从概念单一化 "一事一地"原则,即一个关系模式描述一个实体或实体间的一种联

系。规范的实质就是概念的单一化。

方法:将关系模式投影分解成两个或两个以上的关系模式。

要求:分解后的关系模式集合应当与原关系模式"等价",即经过自然联接可以恢复原关系而

不丢失信息,并保持属性间合理联系。

 

165. 写一个 SQL Server 中的存储过程:

以下为一个带有一个输入参数 Vdeptno ,返回部门为 Vdeptnor 的所有职员的信息.

create procedure Emp_dept

@Vdeptno number(2) AS

begin

select * from emp where deptno=@Vdeptno

end

166. 写一个 Oracle 中的存储过程:

带 IN 参数的过程

create or replace procedure addnew(dno IN number,

name IN varchar2,

location IN varchar2)IS

begin

insert into dept values(dno,name,location);

dbms_output.put_line(‘1 record inserted’);

end;

带 OUT 参数的过程

create or replace procedure getsal(name IN varchar2,

salary OUT number)AS

begin

select sal into salary from emp where ename=name;

end;

七、

XML 部分

200. xml 有哪些解析技术?区别是什么?

答:有 DOM,SAX,STAX 等

DOM:处理大型文件时其性能下降的非常厉害。这个问题是由 DOM 的树结构所造成的,这

 

种结构占用的内存较多,而且 DOM 必须在解析文件之前把整个文档装入内存,适合对 XML

的随机访问 SAX:不现于 DOM,SAX 是事件驱动型的 XML 解析方式。它顺序读取 XML 文

件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结

束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理 XML 文件,适合

对 XML 的顺序访问

STAX:Streaming API for XML (StAX)

201. 你在项目中用到了 xml 技术的哪些方面?如何实现的?

答:用到了数据存贮,信息配置两方面。在做数据交换平台时,将不能数据源的数据组装成

XML 文件,然后将 XML 文件压缩打包加密后通过网络传送给接收者,接收解密与解压缩

后再同 XML 文件中还原相关信息进行处理。在做软件配置时,利用 XML 可以很方便的进

行,软件的各种配置参数都存贮在 XML 文件中。

202. 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());

}

 

}

}

203. 编程用 JAVA 解析 XML 的方式.

答:用 SAX 方式解析 XML,XML 文件如下:

<?xml version=1.0 encoding=gb2312?>

<person>

<name>王小明</name>

<college>信息学院</college>

<telephone>6258113</telephone>

<notes>男,1955 年生,博士,95 年调入海南大学</notes>

</person>

事件回调类 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);

}

}

JSP 内容显示源码,SaxXml.jsp:

<HTML>

<HEAD>

<TITLE>剖析 XML 文件 people.xml</TITLE>

</HEAD>

<BODY>

 

<%@ page errorPage=ErrPage.jsp

contentType=text/html;charset=GB2312 %>

<%@ page import=java.io.* %>

<%@ page import=java.util.Hashtable %>

<%@ page import=org.w3c.dom.* %>

<%@ page import=org.xml.sax.* %>

<%@ page import=javax.xml.parsers.SAXParserFactory %>

<%@ page import=javax.xml.parsers.SAXParser %>

<%@ page import=SAXHandler %>

<%

File file = new File(c:\people.xml);

FileReader reader = new FileReader(file);

Parser parser;

SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser sp = spf.newSAXParser();

SAXHandler handler = new SAXHandler();

sp.parse(new InputSource(reader), handler);

Hashtable hashTable = handler.getTable();

out.println(<TABLE BORDER=2><CAPTION>教师信息表</CAPTION>);

out.println(<TR><TD>姓名</TD> + <TD> +

(String)hashTable.get(new String(name)) + </TD></TR>);

out.println(<TR><TD>学院</TD> + <TD> +

(String)hashTable.get(new String(college))+</TD></TR>);

out.println(<TR><TD>电话</TD> + <TD> +

(String)hashTable.get(new String(telephone)) + </TD></TR>);

out.println(<TR><TD>备注</TD> + <TD> +

(String)hashTable.get(new String(notes)) + </TD></TR>);

out.println(</TABLE>);

%>

</BODY>

</HTML>

204. 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)

 

八、流行的框架与新技术

205. 谈谈你对 SSH 的理解

典型的 JavaEE 三层结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将

业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而

是通过组件与中间层建立连接,再由中间层与数据库交互。

表现层是传统的 JSP 技术,自 1999 年问世以来,经过多年的发展,其广泛的应用和稳定的

表现,为其作为表现层技术打下了坚实的基础。

中间层采用的是流行的 Spring+Hibernate,为了将控制层与业务逻辑层分离,又细分为以下

几种。

Web 层,就是 MVC 模式里面的“C”(controller),负责控制业务逻辑层与表现层的交互,

调用业务逻辑层,并将业务数据返回给表现层作组织表现,该系统的 MVC 框架采用 Struts。

Service 层(就是业务逻辑层),负责实现业务逻辑。业务逻辑层以 DAO 层为基础,通过对

DAO 组件的正面模式包装,完成系统所要求的业务逻辑。

DAO 层,负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。

PO,持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象,很方便地实

现以面向对象方式操作数据库,该系统采用 Hibernate 作为 ORM 框架。

Spring 的作用贯穿了整个中间层,将 Web 层、Service 层、DAO 层及 PO 无缝整合,其数据

服务层用来存放数据。

206. 谈谈你对 Struts 的理解。

1. struts 是一个按 MVC 模式设计的 Web 层框架,其实它就是一个大大的 servlet,这个 Servlet

名为 ActionServlet,或是 ActionServlet 的子类。我们可以在 web.xml 文件中将符合某种特征

的 所 有 请 求 交 给 这 个 Servlet 处 理 , 这 个 Servlet 再 参 照 一 个 配 置 文 件 ( 通 常 为

/WEB-INF/struts-config.xml)将各个请求分别分配给不同的 action 去处理。

一个扩展知识点:struts 的配置文件可以有多个,可以按模块配置各自的配置文件,这样可

以防止配置文件的过度膨胀;

2. ActionServlet 把请求交给 action 去处理之前,会将请求参数封装成一个 formbean 对象(就

是一个 java 类,这个类中的每个属性对应一个请求参数),封装成一个什么样的 formbean

对象呢?看配置文件。

3.要说明的是, ActionServlet 把 formbean 对象传递给 action 的 execute 方法之前,可能会调

用 formbean 的 validate 方法进行校验,只有校验通过后才将这个 formbean 对象传递给 action

的 execute 方法,否则,它将返回一个错误页面,这个错误页面由 input 属性指定,(看配

置文件)作者为什么将这里命名为 input 属性,而不是 error 属性,我们后面结合实际的运行

效果进行分析。

4.action 执行完后要返回显示的结果视图,这个结果视图是用一个 ActionForward 对象来表示

的,actionforward 对象通过 struts-config.xml 配置文件中的配置关联到某个 jsp 页面,因为程

序中使用的是在 struts-config.xml 配置文件为 jsp 页面设置的逻辑名,这样可以实现 action

程序代码与返回的 jsp 页面名称的解耦。

你对 struts 可能还有自己的应用方面的经验,那也要一并说出来。

207. 谈谈你对 Hibernate 的理解。

1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之

间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程

 

和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差

异就表现在内存中的对象状态发生了变化。

2.为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保

存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大

量对象信息。从 Java 程序的运行功能上来讲,保存对象状态的功能相比系统运行的其他功

能来说,应该是一个很不起眼的附属功能,java 采用 jdbc 来实现这个功能,这个不起眼的

功能却要编写大量的代码,而做的事情仅仅是保存对象和恢复对象,并且那些大量的 jdbc

代码并没有什么技术含量,基本上是采用一套例行公事的标准代码模板来编写,是一种苦活

和重复性的工作。

3.通过数据库保存 java 程序运行时产生的对象和恢复对象,其实就是实现了 java 对象与关

系数据库记录的映射关系,称为 ORM(即 Object Relation Mapping),人们可以通过封装

JDBC 代码来实现了这种功能,封装出来的产品称之为 ORM 框架,Hibernate 就是其中的一

种流行 ORM 框架。使用 Hibernate 框架,不用写 JDBC 代码,仅仅是调用一个 save 方法,

就可以将对象保存到关系数据库中,仅仅是调用一个 get 方法,就可以从数据库中加载出一

个对象。

4.使用 Hibernate 的基本流程是:配置 Configuration 对象、产生 SessionFactory、创建 session

对象,启动事务,完成 CRUD 操作,提交事务,关闭 session。

5.使用 Hibernate 时,先要配置 hibernate.cfg.xml 文件,其中配置数据库连接信息和方言等,

还要为每个实体配置相应的 hbm.xml 文件,hibernate.cfg.xml 文件中需要登记每个 hbm.xml

文件。

6.在应用 Hibernate 时,重点要了解 Session 的缓存原理,级联,延迟加载和 hql 查询。

208. AOP 的作用。

面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编

程(OOP)的不足

除了类(classes)以外,AOP 提供了切面。切面对关注点进行模块化,例如横切多个类型和

对象的事务管理

Spring 的一个关键的组件就是 AOP 框架,可以自由选择是否使用 AOP 提供声明式企业服务,

特别是为了替代 EJB 声明式服务。最重要的服务是声明性事务管理,这个服务建立在 Spring

的抽象事物管理之上

允许用户实现自定义切面,用 AOP 来完善 OOP 的使用.可以把 Spring AOP 看作是对 Spring

的一种增强

209. 你对 Spring 的理解。

1.Spring 实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为

BeanFactory(实际上是一个接口),在程序中通常 BeanFactory 的子类 ApplicationContext。

Spring 相当于一个大的工厂类,在其配置文件中通过<bean>元素配置用于创建实例对象的类

名和实例对象的属性。

2. Spring 提供了对 IOC 良好支持,IOC 是一种编程思想,是一种架构艺术,利用这种思想

可以很好地实现模块之间的解耦。IOC 也称为 DI(Depency Injection),什么叫依赖注入呢?

譬如,Class Programmer{

Computer computer = null;

public void code(){

//Computer computer = new IBMComputer();

//Computer computer = beanfacotry.getComputer();

 

computer.write();

}

public void setComputer(Computer computer){

this.computer = computer;

}

}

另外两种方式都由依赖,第一个直接依赖于目标类,第二个把依赖转移到工厂上,第三个彻

底与目标和工厂解耦了。在 spring 的配置文件中配置片段如下:

<bean id=”computer” class=”cn.itcast.interview.Computer”>

</bean>

<bean id=”programmer” class=”cn.itcast.interview.Programmer”>

<property name=”computer” ref=”computer”></property>

</bean>

3. Spring 提供了对 AOP 技术的良好封装, AOP 称为面向切面编程,就是系统中有很多各

不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入

权限判断,加入异常处理,这种应用称为 AOP。实现 AOP 功能采用的是代理技术,客户端

程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式

可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类在,

JDK 中采用 Proxy

类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类,则可以用 CGLI

B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以

Advice 对象进行提供,显然要创建出代理对象,至少需要目标类和 Advice 类。spring 提供

了这种支持,只需要在 spring 配置文件中配置这两个元素即可实现代理和 aop 功能,例如,

<bean id=”proxy” type=”org.spring.framework.aop.ProxyBeanFactory”>

<property name=”target” ref=””></property>

<property name=”advisor” ref=””></property>

</bean>

210. 谈谈 Struts 中的 Action servlet

211. Struts 优缺点

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

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

3. 页面导航使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的

联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优

势体现得更加明显。

4. 提供 Exception 处理机制 .

5. 数据库链接池管理

九、软件工程与设计模式

231. UML 方面

标准建模语言 UML。用例图,静态图(包括类图、对象图和包图),行为图,交互图(顺序图,合作

图),实现图。

232. j2ee 常用的设计模式?说明工厂模式。

总共 23 种,分为三大类:创建型,结构型,行为型

我只记得其中常用的 6、7 种,分别是:

创建型(工厂、工厂方法、抽象工厂、单例)

结构型(包装、适配器,组合,代理)

行为(观察者,模版,策略)

然后再针对你熟悉的模式谈谈你的理解即可。

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(责任链模式)

工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数

据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方

法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类

通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成

不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返

回的是哪一个子类的实例。

233. 开发中都用到了那些设计模式?用在什么场合?

每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核

 

心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。主

要用到了 MVC 的设计模式。用来开发 JSP/Servlet 或者 J2EE 的相关应用。简单工厂模式等。

十、j2ee 部分

234. BS CS 的联系与区别。

C/S 是 Client/Server 的缩写。服务器通常采用高性能的 PC、工作站或小型机,并采用大型

数据库系统,如 Oracle、Sybase、InFORMix 或 SQL Server。客户端需要安装专用的客户端

软件。

B/S是Brower/Server的缩写,客户机上只要安装一个浏览器(Browser),如Netscape Navigator

或 Internet Explorer,服务器安装 Oracle、Sybase、InFORMix 或 SQL Server 等数据库。在这

种结构下,用户界面完全通过 WWW 浏览器实现,一部分事务逻辑在前端实现,但是主要

事务逻辑在服务器端实现。浏览器通过Web Server 同数据库进行数据交互。

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 等信息、流向的变化, 更像交易中心。

235. 应用服务器与 WEB SERVER 的区别?

236. 应用服务器有那些?

BEA WebLogic Server,

IBM WebSphere Application Server,Oracle9i Application Server,

jBoss,

Tomcat

237. J2EE 是什么?

答:Je22 是 Sun 公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的

企业级应用模型(enterpriese application model).在这样的一个应用系统中,可按照功能划分为

不同的组件,这些组件又可在不同计算机上,并且处于相应的层次(tier)中。所属层次包括客

户层(clietn tier)组件,web 层和组件,Business 层和组件,企业信息系统(EIS)层。

一个另类的回答:j2ee 就是增删改查。

238. J2EE 是技术还是平台还是框架? 什么是 J2EE?

J2EE 本身是一个标准,一个为企业分布式应用的开发提供的标准平台。

J2EE 也是一个框架,包括 JDBC、JNDI、RMI、JMS、EJB、JTA 等技术。

239. 请对以下在 J2EE 中常用的名词进行解释(或简单描述)

web 容器:给处于其中的应用程序组件(JSP,SERVLET)提供一个环境,使 JSP,SERVLET

直接更容器中的环境变量接口交互,不必关注其它系统问题。主要有 WEB 服务器来实现。

例如:TOMCAT,WEBLOGIC,WEBSPHERE 等。该容器提供的接口严格遵守 J2EE 规范中的

WEB APPLICATION 标准。我们把遵守以上标准的 WEB 服务器就叫做 J2EE 中的 WEB 容

器。

EJB 容器:Enterprise java bean 容器。更具有行业领域特色。他提供给运行在其中的组件 EJB

各种管理功能。只要满足 J2EE 规范的 EJB 放入该容器,马上就会被容器进行高效率的管理。

并且可以通过现成的接口来获得系统级别的服务。例如邮件服务、事务管理。

JNDI:(Java Naming & Directory Interface)JAVA 命名目录服务。主要提供的功能是:提供

一个目录系统,让其它各地的应用程序在其上面留下自己的索引,从而满足快速查找和定位

分布式应用程序的功能。

JMS:(Java Message Service)JAVA 消息服务。主要实现各个应用程序之间的通讯。包括

点对点和广播。

JTA:(Java Transaction API)JAVA 事务服务。提供各种分布式事务服务。应用程序只需调

用其提供的接口即可。

JAF:(Java Action FrameWork)JAVA 安全认证框架。提供一些安全控制方面的框架。让开

发者通过各种部署和自定义实现自己的个性安全控制策略。

RMI/IIOP:(Remote Method Invocation /internet 对象请求中介协议)他们主要用于通过远程

调用服务。例如,远程有一台计算机上运行一个程序,它提供股票分析服务,我们可以在本

地计算机上实现对其直接调用。当然这是要通过一定的规范才能在异构的系统之间进行通

 

信。RMI 是 JAVA 特有的。

240. 如何给 weblogic 指定大小的内存?

(这个问题不作具体回答,列出来只是告诉读者可能会遇到什么问题,你不需要面面俱到,

什么都精通。)

在启动 Weblogic 的脚本中(位于所在 Domian 对应服务器目录下的 startServerName),增加

set MEM_ARGS=-Xms32m -Xmx200m,可以调整最小内存为 32M,最大 200M

241. 如何设定的 weblogic 的热启动模式(开发模式)与产品发布模式?

可以在管理控制台中修改对应服务器的启动模式为开发或产品模式之一。或者修改服务的启

动文件或者 commenv 文件,增加 set PRODUCTION_MODE=true。

242. 如何启动时不需输入用户名与密码?

修改服务启动文件,增加 WLS_USER 和 WLS_PW 项。也可以在 boot.properties 文件中增加

加密过的用户名和密码.

243. weblogic 管理制台中对一个应用域(或者说是一个网站,Domain)进行 jms ejb

连接池等相关信息进行配置后,实际保存在什么文件中?

保存在此 Domain 的 config.xml 文件中,它是服务器的核心配置文件。

244. 说说 weblogic 中一个 Domain 的缺省目录结构?比如要将一个简单的 helloWorld.jsp

放入何目录下,然的在浏览器上就可打入 http://主机:端口号//helloword.jsp 就可以看

到运行结果了? 又比如这其中用到了一个自己写的 javaBean 该如何办?

Domain 目录服务器目录 applications,将应用目录放在此目录下将可以作为应用访问,如果

是 Web 应用,应用目录需要满足 Web 应用目录要求,jsp 文件可以直接放在应用目录中,

Javabean 需要放在应用目录的 WEB-INF 目录的 classes 目录中,设置服务器的缺省应用将可

以实现在浏览器上无需输入应用名。

245. weblogic 中发布 ejb 需涉及到哪些配置文件

不 同 类 型 的 EJB 涉 及 的 配 置 文 件 不 同 , 都 涉 及 到 的 配 置 文 件 包 括

ejb-jar.xml,weblogic-ejb-jar.xmlCMP 实体 Bean 一般还需要 weblogic-cmp-rdbms-jar.xml

246. 如何在 weblogic 中进行 ssl 配置与客户端的认证配置或说说 j2ee(标准)进行 ssl 的配

?

缺省安装中使用 DemoIdentity.jks 和 DemoTrust.jks KeyStore 实现 SSL,需要配置服务器使

用 Enable SSL,配置其端口,在产品模式下需要从 CA 获取私有密钥和数字证书,创建 identity

和 trust keystore,装载获得的密钥和数字证书。可以配置此 SSL 连接是单向还是双向的。

247. 如何查看在 weblogic 中已经发布的 EJB?

可以使用管理控制台,在它的 Deployment 中可以查看所有已发布的 EJB

十一、 ejb 部分

248. EJB 基于哪些技术实现的?说出 SessionBean EntityBean 区别,StatefulBean

StatelessBean 区别。

EJB 包括 Session Bean、Entity Bean、Message Driven Bean,基于 JNDI、RMI、JAT 等技术

 

实现。

SessionBean 在 J2EE 应用程序中被用来完成一些服务器端的业务操作,例如访问数据库、调

用其他 EJB 组件。EntityBean 被用来代表应用系统中用到的数据。

对于客户机,SessionBean 是一种非持久性对象,它实现某些在服务器上运行的业务逻辑。

对于客户机,EntityBean 是一种持久性对象,它代表一个存储在持久性存储器中的实体的对

象视图,或是一个由现有企业应用程序实现的实体。

Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session Bean ,这两种的

Session Bean 都可以将系统逻辑放在 method 之中执行,不同的是 Stateful Session Bean 可

以记录呼叫者的状态,因此通常来说,一个使用者会有一个相对应的 Stateful Session Bean

的实体。Stateless Session Bean 虽然也是逻辑组件,但是他却不负责记录使用者状态,也就

是说当使用者呼叫 Stateless Session Bean 的时候,EJB Container 并不会找寻特定的

Stateless Session Bean 的实体来执行这个 method。换言之,很可能数个使用者在执行某个

Stateless Session Bean 的 methods 时,会是同一个 Bean 的 Instance 在执行。从内存方面

来看, Stateful Session Bean 与 Stateless Session Bean 比较, Stateful Session Bean 会消耗

J2EE Server 较多的内存,然而 Stateful Session Bean 的优势却在于他可以维持使用者的状

态。

249. 简要讲一下 EJB 7 Transaction Level?

250. EJB JAVA BEAN 的区别?

Java Bean 是可复用的组件,对 Java Bean 并没有严格的规范,理论上讲,任何一个 Java 类

都可以是一个 Bean。但通常情况下,由于 Java Bean 是被容器所创建(如 Tomcat)的,所

以 Java Bean 应具有一个无参的构造器,另外,通常 Java Bean 还要实现 Serializable 接口用

于实现 Bean 的持久性。

Java Bean 实际上相当于微软 COM 模型中的本地进程内 COM 组件,

它是不能被跨进程访问的。Enterprise Java Bean 相当于 DCOM,即分布式组件。它是基于

Java 的远程方法调用(RMI)技术的,所以 EJB 可以被远程访问(跨进程、跨计算机)。

但 EJB 必须被布署在诸如 Webspere、WebLogic 这样的容器中,EJB 客户从不直接访问真正

的 EJB 组件,而是通过其容器访问。EJB 容器是 EJB 组件的代理,EJB 组件由容器所创建

和管理。客户通过容器来访问真正的 EJB 组件。

251. EJB 包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的?

SessionBean:Stateless Session Bean 的生命周期是由容器决定的,当客户机发出请求要建立

一个 Bean 的实例时,EJB 容器不一定要创建一个新的 Bean 的实例供客户机调用,而是随便

找一个现有的实例提供给客户机。当客户机第一次调用一个 Stateful Session Bean 时,容器

必须立即在服务器中创建一个新的Bean实例,并关联到客户机上,以后此客户机调用Stateful

Session Bean 的方法时容器会把调用分派到与此客户机相关联的 Bean 实例。

EntityBean:Entity Beans 能存活相对较长的时间,并且状态是持续的。只要数据库中的数据

存在,Entity beans 就一直存活。而不是按照应用程序或者服务进程来说的。即使 EJB 容器

崩溃了,Entity beans 也是存活的。Entity Beans 生命周期能够被容器或者 Beans 自己管理。

EJB 通过以下技术管理实务:对象管理组织(OMG)的对象实务服务(OTS),Sun Microsystems

的 Transaction Service(JTS)、Java Transaction API(JTA),开发组(X/Open)的 XA 接口。

252. EJB 容器提供的服务

主要提供声明周期管理、代码产生、持续性管理、安全、事务管理、锁和并发行管理等服务。

253. EJB 的激活机制

 

以Stateful Session Bean 为例:其 Cache大小决定了内存中可以同时存在的Bean实例的数量,

根据 MRU 或 NRU 算法,实例在激活和去激活状态之间迁移,激活机制是当客户端调用某

个 EJB 实例业务方法时,如果对应 EJB Object 发现自己没有绑定对应的 Bean 实例则从其去

激活 Bean 存储中(通过序列化机制存储实例)回复(激活)此实例。状态变迁前会调用对

应的 ejbActive 和 ejbPassivate 方法。

254. EJB 的几种类型

会话(Session)Bean ,实体(Entity)Bean 消息驱动的(Message Driven)Bean

会话 Bean 又可分为有状态(Stateful)和无状态(Stateless)两种

实体 Bean 可分为 Bean 管理的持续性(BMP)和容器管理的持续性(CMP)两种

255. 客服端调用 EJB 对象的几个基本步骤

设置 JNDI 服务工厂以及 JNDI 服务地址系统属性,查找 Home 接口,从 Home 接口调用 Create

方法创建 Remote 接口,通过 Remote 接口调用其业务方法。

十二、 webservice 部分

256. 名词解释:①WEB SERVICE JAXP JAXM SOAP UDDI WSDL

JSWDL 开发包的介绍。

Web Service:Web Service 是基于网络的、分布式的模块化组件,它执行特定的任务,遵守

具体的技术规范,这些规范使得 Web Service 能与其他兼容的组件进行互操作。

JAXP:(Java API for XML Parsing) 定义了在 Java 中使用 DOM, SAX, XSLT 的通用的接口。

这样在你的程序中你只要使用这些通用的接口,当你需要改变具体的实现时候也不需要修改

代码。

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

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

的轻量级协议。

UDDI:的目的是为电子商务建立标准;UDDI 是一套基于 Web 的、分布式的、为 Web Service

提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的 Web Service

注册,以使别的企业能够发现的访问协议的实现标准。

WSDL:是一种 XML 格式,用于将网络服务描述为一组端点,这些端点对包含面向文档信

息或面向过程信息的消息进行操作。这种格式首先对操作和消息进行抽象描述,然后将其绑

定到具体的网络协议和消息格式上以定义端点。相关的具体端点即组合成为抽象端点(服

务)。

257. CORBA 是什么?用途是什么?

CORBA 标准是公共对象请求代理结构(Common Object Request Broker Architecture),由对象

管理组织 (Object Management Group,缩写为 OMG)标准化。它的组成是接口定义语言(IDL),

语言绑定(binding:也译为联编)和允许应用程序间互操作的协议。 其目的为:用不同的程序

设计语言书写在不同的进程中运行,为不同的操作系统开发。

十三、 Linux

258. LINUX 下线程,GDI 类的解释。

LINUX 实现的就是基于核心轻量级进程的"一对一"线程模型,一个线程实体对应一个核心

 

轻量级进程,而线程之间的管理在核外函数库中实现。

GDI 类为图像设备编程接口类库。

十四、 问得稀里糊涂的题

259. 四种会话跟踪技术

会话作用域 ServletsJSP 页面描述

page 否是代表与一个页面相关的对象和属性。一个页面由一个编译好的 Java servlet 类(可

以带有任何的 include 指令,但是没有 include 动作)表示。这既包括 servlet 又包括被编

译成 servlet 的 JSP 页面

request 是是代表与 Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个

页面,涉及多个 Web 组件(由于 forward 指令和 include 动作的关系)

session 是是代表与用于某个 Web 客户机的一个用户体验相关的对象和属性。一个 Web 会

话可以也经常会跨越多个客户机请求

application 是是代表与整个 Web 应用程序相关的对象和属性。这实质上是跨越整个 Web

应用程序,包括多个页面、请求和会话的一个全局作用域

260. 简述逻辑操作(&,|,^)与条件操作(&&,||)的区别。

区别主要答两点:a.条件操作只能操作布尔型的,而逻辑操作不仅可以操作布尔型,而且可以

操作数值型

b.逻辑操作不会产生短路

十五、 其他

261. 请用英文简单介绍一下自己.

4、WEB SERVICE 名词解释。JSWDL 开发包的介绍。JAXP、JAXM 的解释。SOAP、

UDDI,WSDL 解释。

262. 请把 http://tomcat.apache.org/ 首页的这一段话用中文翻译一下?

Apache Tomcat is the servlet container that is used in the official Reference Implementation for

the Java Servlet and JavaServer Pages technologies. The Java Servlet and JavaServer Pages

specifications are developed by Sun under the Java Community Process.

Apache Tomcat is developed in an open and participatory environment and released under the

Apache Software License. Apache Tomcat is intended to be a collaboration of the best-of-breed

developers from around the world. We invite you to participate in this open development project.

To learn more about getting involved, click here.

Apache Tomcat powers numerous large-scale, mission-critical web applications across a diverse

range of industries and organizations. Some of these users and their stories are listed on the

PoweredBy wiki page.

263. 美资软件公司 JAVA 工程师电话面试题目

1. Talk about overriding, overloading.

2. Talk about JAVA design patterns you known.

3. Talk about the difference between LinkList, ArrayList and Victor.

4. Talk about the difference between an Abstract class and an Interface.

 

5. Class a = new Class(); Class b = new Class();

if(a == b) returns true or false, why?

6. Why we use StringBuffer when concatenating strings?

7. Try to explain Singleton to us? Is it thread safe? If no, how to make it thread safe?

8. Try to explain Ioc?

9. How to set many-to-many relationship in Hibernate?

10. Talk about the difference between INNER JOIN and LFET JOIN.

11. Why we use index in database? How many indexes is the maximum in one table as your

suggestion?

12. When ‘Final’ is used in class, method and property, what dose it mean?

13. Do you have any experience on XML? Talk about any XML tool you used ,e.g. JAXB, JAXG.

14. Do you have any experience on Linux?

15. In OOD what is the reason when you create a Sequence diagram?

Administrator 10:34:20

1,堆和栈的区别,有一个 64k 的字符串,是放到堆上,还是放到栈上,为什么?

2,什么时候用到接口,什么时候用到抽象类,二者区别

3,有一个 100 万的数组,里边有两个市重复的,如何设计算法找到。

4,设计数据库时,n 维,如何设计。

例如[省份][城市][网吧],这是三维关系,它的表也应该有三个,网吧有外键引用城市,城市

有外键应用省份,这个规律就是下层的要有一外键去引用上层。

264. Java1.5 的新特性

一:Java 基础部分新特性:

自动拆箱

可变参数与 for each 循环

静态导入

二:IO 流部分:

printf 格式输出

Scanner

三:其他

泛型

枚举

Annotation

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值