java基础知识回顾

    CoreJava部分:(共95题:基础91道,中等难度4道)

    面向对象的特征有哪些方面?【基础】

答:面向对象的特征主要有以下几个方面:

1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地

注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一

部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

2)继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了

一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称

为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原

始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,

并且类可以修改或增加新的方法使之更适合特殊的需要。

3)封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。

面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封

装的对象,这些对象通过一个受保护的接口访问其他对象。

4)多态性:多态性是指允许不同类的对象对同一消息作出响应。多态性包括参

数化多态性和包含多态性。方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。

    作用域public,private,protected,以及不写时的区别?【基础】

答:区别如下:

作用域

当前类

同包

子孙类

其他

public

protected

×

default

×

×

private

×

×

×

不写时默认为default。

    String是最基本的数据类型吗?【基础】

答:不是。

    float型floatf=3.4是否正确?【基础】

答:不正确;精度不准确,应该用强制类型转换,如下所示:floatf=(float)3.4。

    语句floatf=1.3;编译能否通过?【基础】

答:不能;应该用强制类型转换,如下所示:floatf=(float)1.3;。

    shorts1 = 1; s1 = s1 + 1;有什么错?【基础】

答:shorts1 = 1; s1 = s1 + 1;会报错,s1+1运算结果是int型,需要强制转换类型;

shorts1 = 1; s1 += 1;可以正确编译,自动类型提升。

    Java有没有goto?【基础】

答:goto是java中的保留字,现在没有在java中使用。

    int和Integer有什么区别?【基础】

答:Java提供两种不同的类型:引用类型和原始类型(或内置类型);

int是java的原始数据类型,Integer是java为int提供的封装类。

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

原始类型:boolean,char,byte,short,int,long,float,double

封装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和

原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种

类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的

缺省值。对象引用实例变量的缺省值为null,而原始类型实例变量的缺省值与

它们的类型有关。

    &和&&的区别?【基础】

答:&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。

    简述逻辑操作(&,|,^)与条件操作(&&,||)的区别?【基础】

答:区别主要有两点:

a.条件操作只能操作布尔型的,而逻辑操作不仅可以操作布尔型,而且可以操作数值型

b.逻辑操作不会产生短路:

当使用条件操作符时,我们会遇到一种“短路”现象。即一旦能够明确无误地确定整个表达式的值,就不会再计算表达式剩余的部分了。因此,整个逻辑表达式靠后的部分有可能不会被运算。

System.out.println(false||true);//输出true,||不存在短路现象,表达式中有任意一部分为true就返回true,所以||逻辑操作符必须要将整个表达式运算完毕才能得出结果。

System.out.println(false && true);//输出false。表达式中有任意一部分为false,整个表达式就返回false。不必将整个表达式运算完毕。

    如何实现将一个单项链表结构中的数据实现反转?

http://dsh.iteye.com/blog/565844

    heap(堆区)和stack(栈区)有什么区别?【基础】

答:栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。要点:堆:顺序随意,栈:后进先出(Last-In/First-Out);

栈是一种线形集合,其添加和删除元素的操作应在同一段完成,栈按照后进

先出的方式进行处理;堆是栈的一个组成元素。

    后序遍历下列二叉树,访问结点的顺序是?【基础】

A

/ \

B C

/ \ \

D E F

/ / \

G N I

/ \

J K

答:顺序为:DJGEBKNIFCA。

    Math.round(11.5)等于多少?Math.round(-11.5)等于多少?【基础】

答:Math.round(11.5)==12Math.round(-11.5)==-11

round方法返回与参数最接近的长整数,参数加1/2后求其floor。

    swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?【基础】

答:switch(expr1)中,expr1是一个整数表达式。因此传递给switch和case

语句的参数应该是int、short、char或者byte;long,string都不能作用

于swtich。

    编程题:用最有效率的方法算出2乘以8等於几?【基础】

答:2<< 3。

    有没有length()这个方法?String有没有length()这个方法?【基础】

答:数组没有length()这个方法,有length的属性。String有length()这个

方法。

Stringa[]={"a","b","c"};

inti1=a.length;

Stringb="";

inti2=b.length();

    在JAVA中,如何跳出当前的多重嵌套循环?【基础】

答:在最外层循环前加label标识,然后用break:label方法即可跳出多重循环。

publicclass LoopTest{public static void main(String[] args){loop:for(int i=0;i<6;i++){for(int j=0;j<7;j++){

System.out.println("内循环");if(j>=0){break loop;}}System.out.println("外循环");}System.out.println("循环外语句");}}之需要在要跳出的循环前面加上个表达式就可以了当满足条件时用break:表达式。

    两个对象值相同(x.equals(y)== true),但却可有不同的hashcode,这

句话对不对?【基础】

答:不对,有相同的hashcode。

    Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?【基础】

答:Set里的元素是不能重复的,用equals()方法来区分重复与否。覆盖

equals()方法用来判断对象的内容是否相同,而”==”判断地址是否相等,用来

决定引用值是否指向同一对象。

    以下二条语句返回值为true的有:

A:“beijing”==“beijing”;

B:“beijing”.equalsIgnoreCase(newString(“beijing”));【基础】

答:A和B。

    是否可以继承String类?【基础】

答:String类是final类,故不可以继承。

    当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?【基础】

答:是值传递。Java编程语言只有值传递参数。当一个对象实例作为一个参数

被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的

方法中改变,但对象的引用是永远不会改变的。

    我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种编码的字符串?【基础】

答:publicString translate(String str){

StringtempStr = "";

try{

tempStr= new String(str.getBytes("ISO-8859-1"), "GBK");

tempStr= tempStr.trim();

}catch(Exception e){

System.err.println(e.getMessage());

}

returntempStr;

}

    String和StringBuffer的区别?【基础】

答:JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。

String类提供了数值不可改变的字符串。

StringBuffer类提供的字符串可以进行修改。

当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。

    String,StringBuffer StringBuilder的区别。【基础】

答:String的长度是不可变的;

StringBuffer的长度是可变的,如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使

用StringBuffer的toString()方法;线程安全;

StringBuilder是从JDK5开始,为StringBuffer该类补充了一个单个线程使用的等价类;通常应该优先使用StringBuilder类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。

    Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?【基础】

答:方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参

数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用

子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。

如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,与方法的返回值类型无关,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

java中重载解析的过程是分两个阶段运行的,第一阶段选取所有可获得并且可以应用的方法或构造器,第二阶段在第一阶段选取的方法或构造器中选取最精确的一个.,如果一个方法或构造器可以接受传递给另一个方法或构造器的任何参数,那么说明第一个方法币第二个方法缺乏精确性。

    构造器Constructor是否可被override?【基础】

答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被重

载Overloading。

    java中实现多态的机制是什么?【基础】

答:方法的覆盖Overriding和重载Overloading是java多态性的不同表现;覆

盖Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个

类中多态性的一种表现。

    定义类A和类B如下:【基础】

classA {

int a=1;

double d=2.0;

void show(){

System.out.println("ClassA: a="+a +"\td="+d);

}

}

class B extends A{

float a=3.0f;

String d="Java program.";

void show(){

super.show();

System.out.println("ClassB: a="+a +"\td="+d);

}

}

(1)若在应用程序的main方法中有以下语句:

Aa=new A();

a.show();

则输出的结果如何?

(2)若在应用程序的main方法中定义类B的对象b:

Ab=new B();

b.show();

则输出的结果如何?

答:输出结果为:

1)ClassA: a=1 d=2.0;

2)ClassA: a=1 d=2.0

ClassB: a=3.0 d=Java program。

    描述一下JVM加载class文件的原理机制?【基础】

答:JVM中类的装载是由ClassLoader和它的子类来实现的。JavaClassLoader是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。

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

答:能够定义成为一个中文的,因为java中以unicode编码,一个中文占2个字节,一个char占16位也就是2个字节,所以放一个中文是没问题的。1Byte=8Bit

    abstractclass和interface有什么区别?【基础】

答:1.abstractclass在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。  2.在abstractclass中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是staticfinal的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。  3.abstractclass和interface所反映出的设计理念不同。其实abstractclass表示的是"is-a"关系,interface表示的是"like-a"关系。  4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。  5.接口中定义的变量默认是publicstatic final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。  6.抽象类中的变量默认是friendly型,其值可以在子类中重新定义,也可以重新赋值。  7.接口中的方法默认都是public,abstract类型的。  结论  abstractclass和interface是Java语言中的两种定义抽象类的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系(虽然都能够实现需求的功能)。

    abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?【基础】

答:都不能。

    静态变量和实例变量的区别?【基础】

答:静态变量也称为类变量,归全类共有,它不依赖于某个对象,可通过类名直

接访问;而实例变量必须依存于某一实例,只能通过对象才能访问到它。

    是否可以从一个static方法内部发出对非static方法的调用?【基础】

答:不可以,如果其中包含对象的method(),不能保证对象初始化。

    写clone()方法时,通常都有一行代码,是什么?【基础】

答:Clone有缺省行为:super.clone(),他负责产生正确大小的空间,并逐位

复制。

    java中会存在内存泄漏吗,请简单描述。【基础】

答:会;存在。无用但可达的对象,这些对象不能被GC回收,导致耗费内存资源。

    GC是什么?为什么要有GC?【基础】

答:GC是垃圾收集的意思(GabageCollection),内存处理是编程人员容易出

现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,

Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc()或Runtime.getRuntime().gc()。

    垃圾回收的优点和原理。并考虑2种回收机制。【基础】

答:Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

    垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?【基础】

答:对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。

可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。

    Strings=new String(“xyz”);创建了几个StringObject?【基础】

答:两个对象,一个是"xyx",一个是指向"xyx"的引用对象s。

    接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承实体类(concreteclass)?【基础】

答:接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承实体

类,但前提是实体类必须有明确的构造函数。

    Java的接口和C++的虚类的相同和不同处。【基础】

答:由于Java不支持多继承,而有可能某个类或对象要使用分别在几个类或对

象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有

更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类

要实现接口里面所有的方法和属性,并且接口里面的属性在默认状态下面都是

publicstatic,所有方法默认情况下是public.一个类可以实现多个接口。

    一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制?【基础】

答:可以;必须只有一个类名与文件名相同。

    弱引用的特点。

只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

43、说出一些常用的类,包,接口,请各举5个。【基础】

答:常用的类:BufferedReader BufferedWriter FileReader FileWirter

String Integer;

常用的包:java.lang java.awt java.io java.util java.sql;

常用的接口:Remote List Map Document NodeList

47、在java中一个类被声明为final类型,表示了什么意思?【基础】

答:表示该类不能被继承,是顶级类或终态类。

48、下面哪些类可以被继承?【基础】

1)java.lang.Thread(T)

2)java.lang.Number(T)

3)java.lang.Double(F)

4)java.lang.Math(F)

5)java.lang.Void(F)

6)java.lang.Class(F)

7)java.lang.ClassLoader(T)

答:1、2、7可以被继承。

49、指出下面程序的运行结果:【基础】

classA{

static{

System.out.print("1");

}

publicA(){

System.out.print("2");

}

}

classB extends A{

static{

System.out.print("a");

}

publicB(){

System.out.print("b");

}

}

publicclass Hello{

publicstatic void main(String[] ars){

A ab =new B(); //执行到此处,结果:1a2b

ab =new B(); //执行到此处,结果:1a2b2b

}

}

答:输出结果为1a2b2b;类的static代码段,可以看作是类首次加载(虚拟机加

载)执行的代码,而对于类加载,首先要执行其基类的构造,再执行其本身的构造。

50、继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么?【基础】

父类:

packagetest;

publicclass FatherClass {

publicFatherClass() {

System.out.println("FatherClassCreate");

}

}

子类:

packagetest;

importtest.FatherClass;

publicclass ChildClass extends FatherClass {

publicChildClass() {

System.out.println("ChildClassCreate");

}

publicstatic void main(String[] args) {

FatherClassfc = new FatherClass();

ChildClasscc = new ChildClass();

}

}

答:输出结果为:

FatherClassCreate

FatherClassCreate

ChildClassCreate

    AnonymousInner Class (匿名内部类)是否可以extends(继承)其它类?是否可以implements(实现)interface(接口)?【基础】

答:可以继承其他类或实现其他接口,在swing编程中常用此方式。

    StaticNested Class和InnerClass的不同?【基础】

答:StaticNested Class是被声明为静态(static)的内部类,它可以不依赖

于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。

    内部类可以引用他包含类的成员吗?有没有什么限制?【基础】

答:一个内部类对象可以访问创建它的外部类对象的内容。

    内部类的实现方式?【基础】

答:示例代码如下:

packagetest;

publicclass OuterClass {

privateclass InterClass {

publicInterClass() {

System.out.println("InterClassCreate");

}

}

publicOuterClass() {

InterClassic = new InterClass();

System.out.println("OuterClassCreate");

}

publicstatic void main(String[] args) {

OuterClassoc = new OuterClass();

}

}

输出结果为:

InterClassCreate

OuterClassCreate

    关于内部类:【基础】

publicclass OuterClass {

privatedouble d1 = 1.0;

//insertcode here

}

Youneed to insert an inner class declaration at line 3,Whichtwoinnerclass declarations are valid?(Choose two.)

A.class InnerOne{

publicstatic double methoda() {return d1;}

}

B.public class InnerOne{

staticdouble methoda() {return d1;}

}

C.private class InnerOne{

doublemethoda() {return d1;}

}

D.static class InnerOne{

protecteddouble methoda() {return d1;}

}

E.abstract class InnerOne{

publicabstract double methoda();

}

答:答案为C、E;说明如下:

1)静态内部类可以有静态成员,而非静态内部类则不能有静态成员;故A、B

错;

2)静态内部类的非静态成员可以访问外部类的静态变量,而不可访问外部类

的非静态变量;故D错;

3)非静态内部类的非静态成员可以访问外部类的非静态成员或者静态成员;故C正确。

    java之守护线程和用户线程

Java有两种Thread:“守护线程Daemon”与“用户线程User”。

守护线程是为其他线程的运行提供便利的线程。守护线程不会阻止程序的终止。

非守护线程包括常规的用户线程或诸如用于处理GUI事件的事件调度线程。

例:我们所熟悉的Java垃圾回收线程就是一个典型的守护线程,当我们的程序中不再有任何运行中的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是Java虚拟机上仅剩的线程时,Java虚拟机会自动离开。

http://blog.csdn.net/lanniao1/archive/2007/10/18/1831626.aspx

    java虚拟机中的守护线程有哪些?【无限讯奇面试题】

    设计4个线程,其中两个线程每次对j增加1,另两个线程对j每次减少1;写出程序。【中等难度】

答:以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题:

publicclass TestThread {

privateint j;

publicTestThread(int j) {this.j = j;}

privatesynchronized void inc(){

j++;

System.out.println(j+ "–Inc–" +Thread.currentThread().getName());

}

privatesynchronized void dec(){

j–;

System.out.println(j+ "–Dec–" +Thread.currentThread().getName());

}

publicvoid run() {

(newDec()).start();

newThread(new Inc()).start();

(newDec()).start();

newThread(new Inc()).start();

}

classDec extends Thread {

publicvoid run() {

for(inti=0; i<100; i++){

dec();

}

}

}

classInc implements Runnable {

publicvoid run() {

for(inti=0; i<100; i++){

inc();

}

}

}

publicstatic void main(String[] args) {

(newTestThread(5)).run();

}

}

53、数据类型之间的转换:

1)如何将数值型字符转换为数字?

2)如何将数字转换为字符?

3)如何取小数点前两位并四舍五入?【基础】

答:1)调用数值类型相应包装类中的方法parse***(String)或valueOf(String)即可返回相应基本类型或包装类型数值;

2)将数字与空字符串相加即可获得其所对应的字符串;另外对于基本类型数字还可调用String类中的valueOf(…)方法返回相应字符串,而对于包装类型

数字则可调用其toString()方法获得相应字符串;

3)可用该数字构造一java.math.BigDecimal对象,再利用其round()方法

进行四舍五入到保留小数点后两位,再将其转换为字符串截取最后两位。

54、字符串操作:如何实现字符串的反转及替换?【基础】

答:可用字符串构造一StringBuffer对象,然后调用StringBuffer中的reverse

方法即可实现字符串的反转,调用replace方法即可实现字符串的替换。

55、编码转换:怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?【基础】

答:示例代码如下:

Strings1 = "你好";

Strings2 = new String(s1.getBytes("GB2312"), "ISO-8859-1");

56、写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分隔。【基础】

答:函数代码如下:

publicString[] split(String str, int chars){

int n= (str.length()+ chars – 1)/chars;

Stringret[] = new String[n];

for(inti=0; i<n; i++){

if(i <n-1){

ret[i]= str.substring(i*chars , (i+1)*chars);

}else{

ret[i]= str.substring(i*chars);

}

}

returnret;

}

57、写一个函数,2个参数,1个字符串,1个字节数,返回截取的字符串,要求字符串中的中文不能出现乱码:如(“我ABC”,4)应该截为“我AB”,输入(“我ABC汉DEF”,6)应该输出为“我ABC”而不是“我ABC+汉的半个”。【基础】

答:代码如下:

publicString subString(String str, int subBytes) {

intbytes = 0; //用来存储字符串的总字节数

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

if(bytes == subBytes) {

returnstr.substring(0, i);

}

char c= str.charAt(i);

if (c< 256) {

bytes+= 1; //英文字符的字节数看作1

} else{

bytes+= 2; //中文字符的字节数看作2

if(bytes- subBytes == 1){

returnstr.substring(0, i);

}

}

}

returnstr;

}

58、日期和时间:

1)如何取得年月日、小时分秒?

2)如何取得从1970年到现在的毫秒数?

3)如何取得某个日期是当月的最后一天?

4)如何格式化日期?【基础】

答:1)创建java.util.Calendar实例(Calendar.getInstance()),调用其get()

方法传入不同的参数即可获得参数所对应的值,如:

calendar.get(Calendar.YEAR);//获得年

2)以下方法均可获得该毫秒数:

Calendar.getInstance().getTimeInMillis();

System.currentTimeMillis();

3)示例代码如下:

Calendartime = Calendar.getInstance();

time.set(Calendar.DAY_OF_MONTH,

time.getActualMaximum(Calendar.DAY_OF_MONTH));

4)利用java.text.DataFormat类中的format()方法可将日期格式化。

59、Java编程,打印昨天的当前时刻。【基础】

答:publicclass YesterdayCurrent{

publicstatic void main(String[] args){

Calendarcal = Calendar.getInstance();

cal.add(Calendar.DATE,-1);

System.out.println(cal.getTime());

}

}

【html&JavaScript&Ajax部分】

60、java和javasciprt的区别。【基础】

答:JavaScript与Java是两个公司开发的不同的两个产品。Java是SUN公司推

出的新一代面向对象的程序设计语言,特别适合于Internet应用程序开发;而

JavaScript是Netscape公司的产品,其目的是为了扩展NetscapeNavigator

功能,而开发的一种可以嵌入Web页面中的基于对象和事件驱动的解释性语言,

它的前身是LiveScript;而Java的前身是Oak语言。下面对两种语言间的异

同作如下比较:

1)基于对象和面向对象:

Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;

JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用

的复杂软件。它是一种基于对象(ObjectBased)和事件驱动(EventDriver)

的编程语言。因而它本身提供了非常丰富的内部对象供设计人员使用;

2)解释和编译:

Java的源代码在执行之前,必须经过编译;

JavaScript是一种解释性编程语言,其源代码不需经过编译,由浏览器解释

执行;

3)强类型变量和类型弱变量:

Java采用强类型变量检查,即所有变量在编译之前必须作声明;

JavaScript中变量声明,采用其弱类型。即变量在使用前不需作声明,而是

解释器在运行时检查其数据类型;

4)代码格式不一样。

Java

JavaScript

真正的程序设计语言

脚本语言

面向对象

基于对象,事件驱动

sun公司的

netscape公司的

服务器端技术,可以与服务器端交互

只能在客户端执行

代码需要编译成二进制代码才能执行

解释性语言

强类型变量,用前必须先声明

弱类型变量:使用之前不需声明

61判断第二个日期比第一个日期大

如何用脚本判断用户输入的的字符串是下面的时间格式2004-11-21必须要保证用户的输入是此格式,并且是时间,比如说月份不大于12等等,另外我需要用户输入两个,并且后一个要比前一个晚,只允许用JAVASCRIPT,请详细帮助作答,,

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

<scripttype="text/javascript">

window.onload= function()

{

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

document.getElementById("form1").onsubmit=

function()

{

vardate1 = this.date1.value;

vardate2 = this.date2.value;

if(!verifyDate(date1)) {alert("第一个日期格式不对");returnfalse;}

if(!verifyDate(date2)) {alert("第二个日期格式不对");returnfalse;}

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

};

}

functioncompareDate(d1,d2)

{

vararrayD1 = d1.split("-");

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

vararrayD2 = d2.split("-");

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

if(date1> date2) return false;

returntrue;

}

functionverifyDate(d)

{

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

returndatePattern.test(d);

}

</script>

<formid="form1" action="xxx.html">

<inputtype="text" name="date1" />

<inputtype="text" name="date2" />

<inputtype="submit"/>

</form>

    异常部分:(共8题:基础8道)

    关于抛异常的处理以及好处

什么时候trow,什么时候catch,处理异常为用户异常。

好处:可以对程序中的异常进行捕获,方便问题的排查。

36.业务层出现例外(异常),应向控制层抛出,由控制层向用户提示错误信息。

    Java中的异常处理机制的简单原理和应用?【基础】

答:当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。

违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。

另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。

    error和exception有什么区别?【基础】

答:error表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困

难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;

exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现

问题;也就是说,它表示如果程序运行正常,从不会发生的情况。

    try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?【基础】

答:会执行,在return前执行。

    JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?【基础】

答:Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并

提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一

般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws)一个

异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺

省处理器来处理;

try用来指定一块预防所有“异常”的程序;

catch子句紧跟在try块后面,用来指定你想要捕捉的“异常”的类型;

throw语句用来明确地抛出一个“异常”;

throws用来标明一个成员函数可能抛出的各种“异常”;

Finally为确保一段代码不管发生什么“异常”都被执行一段代码;

可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,“异常”的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种“异常”进行处理,堆栈就会展开,直到遇到有处理这种“异常”的try语句。

    运行时异常与一般异常有何异同?【基础】

答:Java提供了两类主要的异常:runtimeexception和checkedexception。checked异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。

但是另外一种异常:runtimeexception,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。

出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。

如果不想终止,则必须扑捉所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。在这个场景这样处理可能是一个比较好的应用,但并不代表在所有的场景你都应该如此。如果在其它场景,遇到了一些错误,如果退出程序比较好,这时你就可以不太理会运行时异常,或者是通过对异常的处理显式的控制程序退出。

异常处理的目标之一就是为了把程序从异常中恢复出来。

    给我一个你最常见到的runtimeexception?【基础】

答:ArithmeticException,ArrayStoreException, BufferOverflowException,

BufferUnderflowException,CannotRedoException, CannotUndoException,

ClassCastException,CMMException, ConcurrentModificationException,

DOMException,EmptyStackException, IllegalArgumentException,

IllegalMonitorStateException,IllegalPathStateException,

IllegalStateException,ImagingOpException, IndexOutOfBoundsException,

MissingResourceException,NegativeArraySizeException,

NoSuchElementException,NullPointerException, ProfileDataException,

ProviderException,RasterFormatException, SecurityException,

SystemException,UndeclaredThrowableException,

UnmodifiableSetException,UnsupportedOperationException

    final,finally, finalize的区别?【基础】

答:final:修饰符(关键字);如果一个类被声明为final,意味着它不能再

派生出新的子类,不能作为父类被继承,因此一个类不能既被声明为abstract

的,又被声明为final的;将变量或方法声明为final,可以保证它们在使用中

不被改变;被声明为final的变量必须在声明时给定初值,而在以后的引用中只

能读取,不可修改;被声明为final的方法也同样只能使用,不能重载。

finally:再异常处理时提供finally块来执行任何清除操作;如果抛出一

个异常,那么相匹配的catch子句就会执行,然后控制就会进入finally块(如

果有的话)。

finalize:方法名;Java技术允许使用finalize()方法在垃圾收集器将

对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定

这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所

有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清

理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

    类ExampleA继承Exception,类ExampleB继承ExampleA;【基础】

有如下代码片断:

try{

thrownew ExampleB(“b”);

}catch(ExampleAe){

System.out.printfln(“ExampleA”);

}catch(Exceptione){

System.out.printfln(“Exception”);

}

输出的内容应该是:

A:ExampleAB:ExceptionC:bD:无

答:输出为A。

    【集合】

    介绍JAVA中的CollectionFrameWork(及如何写自己的数据结构)【基础】

答:CollectionFrameWork如下:

Collection(接口)

├List(接口)

│├LinkedList

│├ArrayList

│└Vector

│ └Stack

└Set(接口)

Map(接口)

├Hashtable

├HashMap

├TreeMap

└WeakHashMap

Collection是最基本的集合接口,一个Collection代表一组Object,即

Collection的元素(Elements);Map提供key到value的映射。

    List,Set,Map是否继承自Collection接口?【基础】

答:List,Set是;Map不是。

    你所知道的集合类都有哪些?主要方法?【基础】

答:最常用的集合类是List和Map。List的具体实现包括ArrayList和

Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元

素列表。List适用于按数值索引访问元素的情形。Map提供了一个更通用的

元素存储方法。Map集合类用于存储元素对(称作“键”和“值”),其中每

个键映射到一个值。

    说出ArrayList,Vector,LinkedList的存储性能和特性?【基础】

答:ArrayList和Vector都是使用数组方式存储数据,其操作基本上是对数组的操作,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

    Collection和Collections的区别?【基础】

答:Collection是java.util下的接口,它是各种集合的父接口,继承于它的

接口主要有Set和List;Collections是个java.util下的类,是针对集合的

帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

    HashMap和Hashtable的区别?【基础】

答:二者都实现了Map接口,是将惟一键映射到特定的值上;主要区别在于:

1)HashMap没有排序,允许一个null键和多个null值,而Hashtable不允许;

2)HashMap把Hashtable的contains方法去掉了,改成containsvalue和

containsKey,因为contains方法容易让人引起误解;

3)Hashtable继承自Dictionary类,HashMap是Java1.2引进的Map接口的实现;

4)Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问

Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供另外同步。

Hashtable和HashMap采用的hash/rehash算法大致一样,所以性能不会有很大的差异。

    Arraylist与Vector区别?【基础】

答:就ArrayList与Vector主要从二方面来说:

1)同步性:Vector是线程安全的(同步),而ArrayList是线程序不安全的;

2)数据增长:当需要增长时,Vector默认增长一倍,而ArrayList却是一半。

    List、Set、Map三个接口,存取元素时,各有什么特点?【基础】

答:List以特定次序来存取元素,可有重复元素。

Set具有元素唯一性,内部排序。

Map保存key-value值,value可多值。

首先要搞清楚java中有序和无序的概念有序指的是存储顺序与添加顺序相同,并且可以通过下标访问,List就是这样。无序刚好相反,指的是存储顺序与添加顺序无关,没有下标,当然也不可能通过下标访问,Set就是如此。而TreeSet是无序,但又是排好序的。即添加顺序与存储顺序无关,但是其中的对象实现了排序。

    用程序给出随便大小的10个数,序号为1-10,按从小到大顺序输出,并输出相应的序号。【基础】

答:代码如下:

packagetest;

importjava.util.ArrayList;

importjava.util.Collections;

importjava.util.Iterator;

importjava.util.List;

importjava.util.Random;

publicclass RandomSort {

publicstatic void printRandomBySort() {

Randomrandom = new Random(); //创建随机数生成器

Listlist = new ArrayList();

//生成10个随机数,并放在集合list中

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

list.add(random.nextInt(1000));

}

Collections.sort(list);//对集合中的元素进行排序

Iteratorit = list.iterator();

intcount = 0;

while(it.hasNext()) { //顺序输出排序后集合中的元素

System.out.println(++count+ ": " + it.next());

}

}

publicstatic void main(String[] args) {

printRandomBySort();

}

}

    用JAVA实现一种排序,JAVA类实现序列化的方法?在COLLECTION框架中,实现比较,要实现什么样的接口?【基础】

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

packagetest;

importjava.util.*;

classInsertSort {

ArrayListal;

publicInsertSort(int num,int mod) {

al =new ArrayList(num);

Randomrand = new Random();

System.out.println("TheArrayList Sort Before:");

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

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

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

}

}

publicvoid SortIt(){

IntegertempInt;

intMaxSize=1;

for(inti=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("TheArrayList Sort After:");

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

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

}

}

publicstatic void main(String[] args){

InsertSortis = new InsertSort(10,100);

is.SortIt();

}

}

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

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

    线程部分:(共10题:基础7道,中等难度3道)

    线程的基本概念、线程的基本状态以及状态之间的关系?【基础】

答:线程指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身;

Java中的线程有四种状态分别是:就绪、运行、挂起、结束。

    sleep()和wait()有什么区别?【基础】

答:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行

机会给其他线程,但是监控状态依然保持,到时侯会自动恢复。调用sleep不会释放对象锁。wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

    当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?【基础】

答:其它线程只能访问该对象的其它非同步方法,同步方法则不能进入。

    请说出你所知道的线程同步的方法。【基础】

答:wait():使一个线程处于等待状态,并且释放所持有的对象的lock;

sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常;

notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级;

notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

    多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?【基础】

答:多线程有两种实现方法,分别是继承Thread类与实现Runnable接口。

同步的实现方面有两种,分别是synchronized,wait与notify。

    同步和异步有何异同,在什么情况下分别使用他们?举例说明。【基础】

答:如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,

或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,

必须进行同步存取。当应用程序在对象上调用了一个需要花费很长时间来执行的

方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况

下采用异步途径往往更有效率。

    启动一个线程是用run()还是start()?【基础】

答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行

状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。

run()方法可以产生必须退出的标志来停止一个线程。

    java.util.concurrent包详解

专门处理并发的。

    简述synchronized和java.util.concurrent.locks.Lock的异同?【中等难度】

答:主要相同点:Lock能完成synchronized所实现的所有功能;

主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。

synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在

finally从句中释放。

    java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?

    stop()和suspend()方法为何不推荐使用?【中等难度】

答:有两种实现方法,分别是继承Thread类与实现Runnable接口;

用synchronized关键字修饰同步方法;

反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而

且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它

们。结果很难检查出真正的问题所在;

suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,

但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,

除非被“挂起”的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,

同时又试图使用任何一个锁定的资源,就会造成死锁。故不应该使用suspend(),

而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志

指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,

则用一个notify()重新启动线程。

    volatile

http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

    IO流及Socket部分:(共5题:基础5道)

    什么是java序列化,如何实现java序列化?【基础】

答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进

行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之

间。序列化是为了解决在对对象流进行读写操作时所引发的问题;

序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需实

现的方法,implementsSerializable只是为了标注该对象是可被序列化的,然

后使用一个输出流(如FileOutputStream)来构造一个ObjectOutputStream(对

象流)对象,接着,使用ObjectOutputStream对象的writeObject(Objectobj)

方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

92、java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?【基础】

答:字节流,字符流。字节流继承于InputStream、OutputStream,字符流继承

于Reader、Writer。在java.io包中还有许多其他的流,主要是为了提高性能

和使用方便。

93、文件和目录(IO)操作:

1)如何列出某个目录下的所有文件?

2)如何列出某个目录下的所有子目录?

3)如何判断一个文件或目录是否存在?

4)如何读写文件?【基础】

答:1)示例代码如下:

Filefile = new File("e:\\总结");

File[]files = file.listFiles();

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

if(files[i].isFile())System.out.println(files[i]);

}

2)示例代码如下:

Filefile = new File("e:\\总结");

File[]files = file.listFiles();

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

if(files[i].isDirectory())System.out.println(files[i]);

}

3)创建File对象,调用其exsit()方法即可返回是否存在,如:

System.out.println(newFile("d:\\t.txt").exists());

4)示例代码如下:

//读文件:

FileInputStreamfin = new FileInputStream("e:\\tt.txt");

byte[]bs = new byte[100];

while(true){

intlen = fin.read(bs);

if(len<= 0) break;

System.out.print(newString(bs,0,len));

}

fin.close();

//写文件:

FileWriterfw = new FileWriter("e:\\test.txt");

fw.write("helloworld!" + System.getProperty("line.separator"));

fw.write("你好!北京!");

fw.close();

94、写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出

现的次数。【基础】

答:代码如下:

publicint countWords(String file, String find) throws Exception

{

intcount = 0;

Readerin = new FileReader(file);

int c;

while((c = in.read()) != -1) {

while(c == find.charAt(0)) {

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

c =in.read();

if (c!= find.charAt(i)) break;

if (i== find.length() – 1) count++;

}

}

}

returncount;

}

    Java的通信编程,编程题(或问答),用JAVASOCKET编程,读服务器几个字符,再写入本地显示?【基础】

答:Server端程序:

packagetest;

importjava.net.*;

importjava.io.*;

publicclass Server{

privateServerSocket ss;

privateSocket socket;

privateBufferedReader in;

privatePrintWriter out;

publicServer(){

try {

ss=newServerSocket(10000);

while(true){

socket= ss.accept();

StringRemoteIP =

socket.getInetAddress().getHostAddress();

StringRemotePort = ":"+socket.getLocalPort();

System.out.println("Aclient come in!IP:"

+RemoteIP+RemotePort);

in =new BufferedReader(new

InputStreamReader(socket.getInputStream()));

Stringline = in.readLine();

System.out.println("Cleintsend is :" + line);

out =

newPrintWriter(socket.getOutputStream(),true);

out.println("YourMessage Received!");

out.close();

in.close();

socket.close();

}

}catch(IOException e){

out.println("wrong");

}

}

publicstatic void main(String[] args){

newServer();

}

}

Client端程序:

packagetest;

importjava.io.*;

importjava.net.*;

publicclass Client {

Socketsocket;

BufferedReaderin;

PrintWriterout;

publicClient(){

try {

System.out.println("Tryto Connect to

127.0.0.1:10000");

socket= new Socket("127.0.0.1",10000);

System.out.println("TheServer Connected!");

System.out.println("Pleaseenter some Character:");

BufferedReaderline = new BufferedReader(new

InputStreamReader(System.in));

out =new PrintWriter(socket.getOutputStream(),true);

out.println(line.readLine());

in =new BufferedReader(

newInputStreamReader(socket.getInputStream()));

System.out.println(in.readLine());

out.close();

in.close();

socket.close();

}catch(IOExceptione){

out.println("Wrong");

}

}

publicstatic void main(String[] args) {

newClient();

}

}

    反射部分

2、Class.forName的作用?为什么要用?

答:按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。

有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。

9.什么是类的返射机制?

通过类(Class对象),可以得出当前类的fields、method、construtor、interface、superClass、modified等,同是可以通过类实例化一个实例、设置属性、唤醒方法。Spring中一切都是返射、struts、hibernate都是通过类的返射进行开发的。

    综合

    java实例化一个类有哪几种方法?

1.直接new调用默认构造器实例化对象:newObject();

2.通过工厂方法返回对象:如:Stringstr = String.valueOf(23);

Calendarcd = Calendar.getInstance();

3.通过反射,如:Class.forName(“java.lang.Object”).newInstance();还可以变形为,先得到Class对象,然后再得到Constructor,再生成对象。

4、通过I/O流(包括反序列化)。

5.克隆,是复制一个对象,要求对象必须能够被克隆,即要么实现了Cloneable接口,要么覆盖Object中的clone()方法

    inta=2; int b=10;如何对i、j的值进行交换,而且不借助于第三方变量?

在学习程序语言和进行程序设计的时候,交换两个变量的值是经常要使用的。通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完成交换。代码如下:

int a,b;

a=10; b=15;

int t;

t=a; a=b; b=t;

这种算法易于理解,特别适合帮助初学者了解计算机程序的特点,是赋值语句的经典应用。在实际软件开发当中,此算法简单明了,不会产生歧义,便于程序员之间的交流,一般情况下碰到交换变量值的问题,都应采用此算法(以下称为标准算法)。

上面的算法最大的缺点就是需要借助一个临时变量。那么不借助临时变量可以实现交换吗?答案是肯定的!这里我们可以用三种算法来实现:1)算术运算;2)指针地址操作;3)位运算。

1)算术运算

简单来说,就是通过普通的+和-运算来实现。代码如下:

int a,b;

a=10;b=12;

a=b-a;//a=2;b=12

b=b-a;//a=2;b=10

a=b+a;//a=10;b=10

通过以上运算,a和b中的值就进行了交换。表面上看起来很简单,但是不容易想到,尤其是在习惯标准算法之后。

它的原理是:把a、b看做数轴上的点,围绕两点间的距离来进行计算。

具体过程:第一句“a=b-a”求出ab两点的距离,并且将其保存在a中;第二句“b=b-a”求出a到原点的距离(b到原点的距离与ab两点距离之差),并且将其保存在b中;第三句“a=b+a”求出b到原点的距离(a到原点距离与ab两点距离之和),并且将其保存在a中。完成交换。

此算法与标准算法相比,多了三个计算的过程,但是没有借助临时变量。(以下称为算术算法)

2)指针地址操作

因为对地址的操作实际上进行的是整数运算,比如:两个地址相减得到一个整数,表示两个变量在内存中的储存位置隔了多少个字节;地址和一个整数相加即“a+10”表示以a为基地址的在a后10个a类数据单元的地址。所以理论上可以通过和算术算法类似的运算来完成地址的交换,从而达到交换变量的目的。即:

int *a,*b; //假设

*a=new int(10);

*b=new int(20); //&a=0x00001000h,&b=0x00001200h

a=(int*)(b-a);//&a=0x00000200h,&b=0x00001200h

b=(int*)(b-a);//&a=0x00000200h,&b=0x00001000h

a=(int*)(b+int(a));//&a=0x00001200h,&b=0x00001000h

通过以上运算a、b的地址真的已经完成了交换,且a指向了原先b指向的值,b指向原先a指向的值了吗?上面的代码可以通过编译,但是执行结果却令人匪夷所思!原因何在?

首先必须了解,操作系统把内存分为几个区域:系统代码/数据区、应用程序代码/数据区、堆栈区、全局数据区等等。在编译源程序时,常量、全局变量等都放入全局数据区,局部变量、动态变量则放入堆栈区。这样当算法执行到“a=(int*)(b-a)”时,a的值并不是0x00000200h,而是要加上变量a所在内存区的基地址,实际的结果是:0x008f0200h,其中0x008f即为基地址,0200即为a在该内存区的位移。它是由编译器自动添加的。因此导致以后的地址计算均不正确,使得a,b指向所在区的其他内存单元。再次,地址运算不能出现负数,即当a的地址大于b的地址时,b-a<0,系统自动采用补码的形式表示负的位移,由此会产生错误,导致与前面同样的结果。

有办法解决吗?当然!以下是改进的算法:

if(a<b)

{

a=(int*)(b-a);

b=(int*)(b-(int(a)&0x0000ffff));

a=(int*)(b+(int(a)&0x0000ffff));

}

else

{

b=(int*)(a-b);

a=(int*)(a-(int(b)&0x0000ffff));

b=(int*)(a+(int(b)&0x0000ffff));

}

算法做的最大改进就是采用位运算中的与运算“int(a)&0x0000ffff”,因为地址中高16位为段地址,后16位为位移地址,将它和0x0000ffff进行与运算后,段地址被屏蔽,只保留位移地址。这样就原始算法吻合,从而得到正确的结果。

此算法同样没有使用第三变量就完成了值的交换,与算术算法比较它显得不好理解,但是它有它的优点即在交换很大的数据类型时,它的执行速度比算术算法快。因为它交换的时地址,而变量值在内存中是没有移动过的。(以下称为地址算法)

3)位运算

通过异或运算也能实现变量的交换,这也许是最为神奇的,请看以下代码:

int a=10,b=12; //a=1010^b=1100;

a=a^b;//a=0110^b=1100;

b=a^b;//a=0110^b=1010;

a=a^b;//a=1100=12;b=1010;

此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变。

即:a^b^b=a。将a=a^b代入b=a^b则得b=a^b^b=a;同理可以得到a=b^a^a=b;轻松完成交换。

以上三个算法均实现了不借助其他变量来完成两个变量值的交换,相比较而言算术算法和位算法计算量相当,地址算法中计算较复杂,却可以很轻松的实现大类型(比如自定义的类或结构)的交换,而前两种只能进行整形数据的交换(理论上重载“^”运算符,也可以实现任意结构的交换)。

介绍这三种算法并不是要应用到实践当中,而是为了探讨技术,展示程序设计的魅力。从中可以看出,数学中的小技巧对程序设计而言具有相当的影响力,运用得当会有意想不到的神奇效果。而从实际的软件开发看,标准算法无疑是最好的,能够解决任意类型的交换问题。

    OOA/D与UML部分:(共6题:基础2道,中等难度4道)

96、UML是什么?常用的几种图?【基础】

答:UML(UnifiedModelingLanguage)是统一建模语言;常用图包括:用例图,静态图(包括类图、对象图和包图),行为图,交互图(顺序图,合作图),实现图。

    你对软件开发中迭代的含义的理解;【中等难度】

答:软件开发中,各个开发阶段不是顺序执行的,应该是并行执行,也就是迭代

的意思。这样对于开发中的需求变化,及人员变动都能得到更好的适应。

    XML部分:(共4题:基础1道,中等难度1道,较难2道)

    XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?【基础】

答:1)两种形式:dtd以及schema;

2)本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD

上发展schema的根本目的);

3)解析方式:有DOM,SAX,STAX等:

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

构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问;

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

处理XML文件,适合对XML的顺序访问;

STAX:StreamingAPI for XML (StAX)。

    你在项目中用到了xml技术的哪些方面?如何实现的?【中等难度】

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

数据组装成XML文件,然后将XML文件压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再同XML文件中还原相关信息进行处理。在做软件配置时,利用XML可以很方便的进行,软件的各种配置参数都存贮在XML文件中。

    用jdom解析xml文件时如何解决中文问题?如何解析?【较难】

答:看如下代码,用编码方式加以解决

packagetest;

importjava.io.*;

publicclass DOMTest{

privateString inFile = "c:\people.xml";

privateString outFile = "c:\people.xml";

publicstatic void main(String args[]){

newDOMTest();

}

publicDOMTest(){

try{

javax.xml.parsers.DocumentBuilderbuilder =

javax.xml.parsers.DocumentBuilderFactory.

newInstance().newDocumentBuilder();

org.w3c.dom.Documentdoc = builder.newDocument();

org.w3c.dom.Elementroot = doc.createElement("老师");

org.w3c.dom.Elementwang = doc.createElement("王");

org.w3c.dom.Elementliu = doc.createElement("刘");

wang.appendChild(doc.createTextNode("我是王老师"));

root.appendChild(wang);

doc.appendChild(root);

javax.xml.transform.Transformertransformer =

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),

newjavax.xml.transform.stream.StreamResult(outFile));

}catch(Exception e){

System.out.println(e.getMessage());

}

}

}

105、编程用JAVA解析XML的方式。【较难】

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

<?xmlversion="1.0" encoding="gb2312"?>

<person>

<name>王小明</name>

<college>信息学院</college>

<telephone>6258113</telephone>

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

</person>

事件回调类SAXHandler.java:

importjava.io.*;

importjava.util.Hashtable;

importorg.xml.sax.*;

publicclass SAXHandler extends HandlerBase{

privateHashtable table = new Hashtable();

privateString currentElement = null;

privateString currentValue = null;

publicvoid setTable(Hashtable table){

this.table= table;

}

publicHashtable getTable(){

returntable;

}

publicvoid startElement(String tag, AttributeList attrs)

throwsSAXException{

currentElement= tag;

}

publicvoid characters(char[] ch, int start, int length)

throwsSAXException{

currentValue= new String(ch, start, length);

}

publicvoid 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" %>

<%

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

FileReaderreader = new FileReader(file);

Parserparser;

SAXParserFactoryspf = SAXParserFactory.newInstance();

SAXParsersp = spf.newSAXParser();

SAXHandlerhandler = new SAXHandler();

sp.parse(newInputSource(reader), handler);

HashtablehashTable = handler.getTable();

out.println("<TABLEBORDER=2><CAPTION>" +

"教师信息表</CAPTION>");

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

(String)hashTable.get(newString("name")) +

"</TD></TR>");

out.println("<TR><TD>学院</TD>"+ "<TD>" +

(String)hashTable.get(newString("college"))

+"</TD></TR>");

out.println("<TR><TD>电话</TD>"+ "<TD>" +

(String)hashTable.get(newString("telephone"))

+"</TD></TR>");

out.println("<TR><TD>备注</TD>"+ "<TD>" +

(String)hashTable.get(newString("notes"))

+"</TD></TR>");

out.println("</TABLE>");

%>

</BODY>

</HTML>

    数据结构、算法及计算机基础部分:(共8题:基础6道,中等难度1道,较难1道)

181、常用UNIX命令(Linux的常用命令)(至少10个)【基础】

答:lspwd mkdir rm cp mv cd ps ftp telnet ping env more echo

    排序都有哪几种方法?请列举。用JAVA实现一个快速排序。【基础】

答:排序的方法有:插入排序(直接插入排序、希尔排序),交换排序(冒泡排

序、快速排序),选择排序(直接选择排序、堆排序),归并排序,分配排序(箱

排序、基数排序);

快速排序的伪代码:

//使用快速排序方法对a[0 :n- 1 ]排序

从a[0 :n- 1 ]中选择一个元素作为middle,该元素为支点;

把余下的元素分割为两段left和right,使得left中的元素都小于等于支点,

而right中的元素都大于等于支点;

递归地使用快速排序方法对left进行排序;

递归地使用快速排序方法对right进行排序;

所得结果为left+ middle + right。

184、写一种常见排序。【基础】

答:C++中冒泡排序:

voidswap( int& a, int& b ){

intc=a; a = b; b = c;

}

voidbubble( int* p, int len ){

boolbSwapped;

do {

bSwapped= false;

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

if(p[i-1]>p[i] ){

swap(p[i-1], p[i] );

bSwapped= true;

}

}

}while(bSwapped );

}

    写一个一小段程序检查数字是否为质数;以上的程序你采用的哪种语言写的?采用该种语言的理由是什么?【基础】

答:代码如下:

#include<math.h>

boolprime( int n ){

if(n<=0)exit(0);

for(int i=2; i<=n; i++ )

for(int j=2; j<=sqrt(i); j++)

if((n%j==0)&& (j!=n))

returnfalse;

returntrue;

}

采用C++,因为其运行效率高。

186、编程题:设有n个人依围成一圈,从第1个人开始报数,数到第m个人出

列,然后从出列的下一个人开始报数,数到第m个人又出列,…,如此反复到所有的人全部出列为止。设n个人的编号分别为1,2,…,n,打印出出列的顺序;要求用java实现。【中等难度】

答:代码如下:

packagetest;

publicclass CountGame {

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

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

if(p[i]==n){

returntrue;

}

}

returnfalse;

}

publicstatic void play(int playerNum, int step){

int[]p=new int[playerNum];

intcounter = 1;

while(true){

if(counter> playerNum*step){

break;

}

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

while(true){

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

elsei=i+1;

}

if(i >playerNum)break;

if(counter%step==0){

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

p[counter/step-1]=i;

}

counter+=1;

}

}

System.out.println();

}

publicstatic void main(String[] args) {

play(10,7);

}

}

187、写一个方法1000的阶乘。【较难】

答:C++的代码实现如下:

#include<iostream>

#include<iomanip>

#include<vector>

usingnamespace std;

classlongint {

private:

vector<int>iv;

public:

longint(void){ iv.push_back(1); }

longint&multiply(const int &);

friendostream& operator<<(ostream &, const longint &);

};

ostream&operator<<(ostream &os, const longint &v) {

vector<int>::const_reverse_iteratoriv_iter = v.iv.rbegin();

os <<*iv_iter++;

for (; iv_iter < v.iv.rend(); ++iv_iter) {

os <<setfill(‘0’) << setw(4) << *iv_iter;

}

returnos;

}

longint&longint::multiply(const int &rv) {

vector<int>::iteratoriv_iter = iv.begin();

intoverflow = 0, product = 0;

for (; iv_iter < iv.end(); ++iv_iter) {

product= (*iv_iter) * rv;

product+= overflow;

overflow= 0;

if(product > 10000) {

overflow= product / 10000;

product-= overflow * 10000;

}

iv_iter= product;

}

if (0!= overflow) {

iv.push_back(overflow);

}

return*this;

}

intmain(int argc, char **argv) {

longintresult;

int l= 0;

if(argc==1){

cout<< "like: multiply 1000" << endl;

exit(0);

}

sscanf(argv[1],"%d", &l);

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

result.multiply(i);

}

cout<< result << endl;

return0;

}

11、LINUX下线程,GDI类的解释?

答:LINUX实现的就是基于核心轻量级进程的"一对一"线程模型,一个线程实体对应一个核心轻量级进程,而线程之间的管理在核外函数库中实现;GDI类为图像设备编程接口类库。

12、Jdo是什么?

答:JDO是Java对象持久化的新的规范,为javadata object 的简称,也是一

个用于存取某种数据仓库中的对象的标准化API。JDO提供了透明的对象存储,

因此对开发人员来说,存储数据对象完全不需要额外的代码(如JDBCAPI的使用)。这些繁琐的例行工作已经转移到JDO产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC只是面向关系数据库(RDBMS)JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMS)等等,使得应用可移植性更强。

16:程序中文乱码怎么解决:

1、所有HTML/JSP页面全部采用UTF-8编码

2、在后台程序中转码。

    JAVA代码分析题目

1.

abstractclass Name {

privateString name;

publicabstract boolean isStupidName(String name) {}

}

大侠们,这有何错误?

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

2.

publicclass Something {

voiddoSomething () {

privateString s = "";

intl = s.length();

}

}

有错吗?

答案:错。局部变量前不能放置任何访问修饰符(private,public,和protected)。final可以用来修饰局部变量(final如同abstract和strictfp,都是非访问修饰符,strictfp只能修饰class和method而非variable)。

3.

abstractclass Something {

privateabstract String doSomething ();

}

这好像没什么错吧?

答案:错。abstract的methods不能以private修饰。abstract的methods就是让子类implement(实现)具体细节的,怎么可以用private把abstract

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

4.

publicclass Something {

publicint addOne(final int x) {

return++x;

}

}

这个比较明显。

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

5.

publicclass Something {

publicstatic void main(String[] args) {

Othero = new Other();

newSomething().addOne(o);

}

publicvoid addOne(final Other o) {

o.i++;

}

}

classOther {

publicint i;

}

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

答案:正确。在addOnemethod中,参数o被修饰成final。如果在addOnemethod里我们修改了o的reference(比如:o = new Other();),那么如同上例这题也是错的。但这里修改的是o的membervairable(成员变量),而o的reference并没有改变。

6.

classSomething {

inti;

publicvoid doSomething() {

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

}

}

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

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

instantvariable有defaultvalue。int的defaultvalue是0。

7.

classSomething {

finalint i;

publicvoid doSomething() {

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

}

}

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

答案:错。finalint i是个final的instantvariable (实例变量,或叫成员变量)。final的instantvariable没有defaultvalue,必须在constructor(构造器)结束之前被赋予一个明确的值。可以修改为"finalint i = 0;"。

8.

publicclass Something {

publicstatic void main(String[] args) {

Somethings = new Something();

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

}

publicString doSomething() {

return"Do something …";

}

}

看上去很完美。

答案:错。看上去在main里calldoSomething没有什么问题,毕竟两个methods都在同一个class里。但仔细看,main是static的。staticmethod不能直接callnon-static methods。可改成"System.out.println("s.doSomething()returns " + s.doSomething());"。同理,staticmethod不能访问non-staticinstant variable。

9.

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

classSomething {

privatestatic void main(String[] something_to_do) {

System.out.println("Dosomething …");

}

}

这个好像很明显。

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

10.

interface A{

intx = 0;

}

classB{

intx =1;

}

classC extends B implements A {

publicvoid pX(){

System.out.println(x);

}

publicstatic void main(String[] args) {

newC().pX();

}

}

答案:错误。在编译时会发生错误(错误描述不同的JVM有不同的信息,意思就是未明确的x调用,两个x都匹配(就象在同时importjava.util和java.sql两个包时直接声明Date一样)。对于父类的变量,可以用super.x来明确,而接口的属性默认隐含为publicstatic final.所以可以通过A.x来明确。

11.

interfacePlayable {

voidplay();

}

interfaceBounceable {

voidplay();

}

interfaceRollable extends Playable, Bounceable {

Ballball = new Ball("PingPang");

}

classBall implements Rollable {

privateString name;

publicString getName() {

returnname;

}

publicBall(String name) {

this.name= name;

}

publicvoid play() {

ball= new Ball("Football");

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

}

}

这个错误不容易发现。

答案:错。"interfaceRollable extends Playable,Bounceable"没有问题。interface可继承多个interfaces,所以这里没错。问题出在interfaceRollable里的"Ballball = new Ball("PingPang");"。任何在interface里声明的interfacevariable (接口变量,也可称成员变量),默认为publicstatic final。也就是说"Ballball = new Ball("PingPang");"实际上是"publicstatic final Ball ball = newBall("PingPang");"。在Ball类的Play()方法中,"ball= new Ball("Football");"改变了ball的reference,而这里的ball来自Rollableinterface,Rollable

interface里的ball是publicstatic final的,final的object是不能被改变reference的。因此编译器将在"ball= new Ball("Football");"这里显示有错。

    JAVA编程题

1.现在输入n个数字,以逗号,分开;然后可选择升或者降序排序;按提交键就在另一页面显示按什么排序,结果为,提供reset。

importjava.util.*;

publicclass bycomma{

publicstatic String[] splitStringByComma(String source){

if(source==null||source.trim().equals(""))

returnnull;

StringTokenizercommaToker = new StringTokenizer(source,",");

String[]result = new String[commaToker.countTokens()];

inti=0;

while(commaToker.hasMoreTokens()){

result[i]= commaToker.nextToken();

i++;

}

returnresult;

}

publicstatic void main(String args[]){

String[]s = splitStringByComma("5,8,7,4,3,9,1");

int[]ii = new int[s.length];

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

ii[i]=Integer.parseInt(s[i]);

}

Arrays.sort(ii);

//asc

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

System.out.println(ii[i]);

}

//desc

for(inti=(s.length-1);i>=0;i–){

System.out.println(ii[i]);

}

}

}

    逻辑推理题

    一群人开舞会,每人头上都戴着一顶帽子。帽子只有黑白两种,黑的至少有一顶。每个人都能看到其它人帽子的颜色,却看不到自己的。主持人先让大家看看别人头上戴的是什颜色帽子,然后关灯,如果有人认为自己戴的是黑帽子,就打自己一个耳光。第一次关灯,没有声音。于是再开灯,大家再看一遍,关灯时仍然鸦雀无声。一直到第三次关灯,才有劈劈啪啪打耳光的声音响起。问有多少人戴着黑帽子?【无限讯奇面试题】

因为:只有一个人带白帽子:

所以:随便谁看见其他人除了一个白帽子,其他的都是黑帽子,但是自己的是什么呢?所以不敢下定论自己是黑帽子,所以第一次关灯没有反映,同理其他人也是这样,但是哪个带白帽子的人看见所有人都是黑帽子,所以肯定自己是白帽子,所以第二次关灯时还是没有反映,但是就因为哪个白帽子没有在第二次关灯时打自己耳光,那么其他人可以肯定,哪个带白帽子的人已经知道自己是白帽子了,既:他看见了其他人都是带的黑帽子!所以所有黑帽子打响了自己的耳光,

所以答案是:

只有一个人带白帽子,其他人都带黑帽子

伟人之所以伟大,是因为他与别人共处逆境时,

java基础知识回顾

相关文章:

你感兴趣的文章:

标签云: