JAVA基础面试题

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

    可以有多个类(class),但只能有一个公共类(public class),并且public的类名必须与文件名一致,否则报错。

2、Java 有没有 goto? 

    goto是java中的保留字,现在在java中不在使用了

3、说说&和&&的区别。 

    &和&&都可以用作逻辑与的运算符,表示逻辑与(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。 

4、在 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; 
                              } 
                } 
} 

        不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,例如,要在二维数组中查找到某个数字。 

5、switch 语句能否作用在 byte 上,能否作用在 long 上,能否作用在 String上? 

        在switch(egs)中,egs只能是整数表达式或枚举常量;整数表达式可以是int或integer包装类型,而因为byte,short,char都能隐式的转换成int,long和string并不能被隐式的转换,所以不能作用于long和string上。

6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 

        因为short s1=1;s1=s1+1;在运算时右边的s1+1会自动提升为int类型,因此在赋值时会报强制类型转换错误。

而s1+=1;中+=是java语言中规定的运算符,执行中Java编译器会对它进行特殊处理。

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

        char 型变量是用来存储 Unicode 编码的字符的,unicode 编码字符集中包含了汉字,所以是可以的。当然若有特殊汉字不在unicode中,自然也就不可以存储。注意:unicode 编码占用两个字节,所以,char 类型的变量也是占用两个字节。 

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

        使用一个final关键字修饰变量时,是指引用变量不能变,而引用变量所指向对象的内容是可以改变的。eg:

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

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

a=new StringBuffer(""); 

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

a.append(" broken!");   

9、"=="和 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。

10、静态变量和实例变量的区别? 

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

在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。

11、是否可以从一个 static 方法内部发出对非 static 方法的调用?

        不可以,因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在对该对象上进行方法调用,而static方法调用时不需要创建对象,可直接调用。当一个static方法呗调用时,可能没有创建任何实例对象。如果从一个 static 方法中发出对非static 方法的调用,那么非static方法的对象从何处来?

12、Integer 与 int 的区别 

        int是 java提供的8种原始数据类型之一。Java为每个原始类型提供了封装类,Integer是 java为 int 提供的封装类。int 的默认值为0,而 Integer 的默认值为 null,即 Integer 可以区分出未赋值和值为0的区别,int 则无法表达出未赋值的情况。

13、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。 

14、下面的代码有什么不妥之处? 

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

   username 可能为 NULL,会报空指针错误;改为"zxx".equals(username)

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

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

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

重写 Override 表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。如果父类的方法是 private 类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。 

如果几个 Overloaded 的方法的参数列表不一样,它们的返回者类型当然也可以不一样。如果两个方法的参数列表完全一样,是否可以让它们的返回值不同来实现重载 Overload。这是不行的。

重写的注意事项:

1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果; 
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致; 
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类; 

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

重载的注意事项:

1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是 fun(int,float),但是不能为 fun(int,int)); 
2、不能通过访问权限、返回类型、抛出的异常进行重载; 
3、方法的异常类型和数目不会对重载造成影响; 

4、对于继承来说,如果某一方法在父类中是访问权限是 priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。 

16、构造器 Constructor 是否可被 override? 

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

17、面向对象的特征有哪些方面 

封装:

    封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装的最基本单位,面向对象的封装比传统语言的封装更为清晰、更为有力。面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。通常情况下,只要记住让变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义成私有的,只有这个类自己的方法才可以访问到这些成员变量,这就基本上实现对象的封装,就很容易找出要分配到这个类上的方法了,就基本上算是会面向对象的编程了。把握一个原则:把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类中。 

抽象: 

        抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。

继承:

    在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。

多态: 

        多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。多态性增强了软件的灵活性和扩展性。

18、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.  一个类可以实现多个接口,但只能继承一个抽象类。 

19、Anonymous Inner Class (匿名内部类)是否可以 extends(继承)其它类,是否可以 implements(实现)interface(接口)? 

可以继承其他类或实现其他接口。不仅是可以,而是必须! (如若不知道什么是匿名内部类可查看此文章

20、String 是最基本的数据类型吗? 

基本数据类型包括:byte、int、char、long、float、double、boolean和short

java.lang.String 类是 final 类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用 StringBuffer 类 

21、String s = new String("xyz");创建了几个 String Object?二者之间有什么区别? 

        两个或一个,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。New String 每写一遍,就创建一个新的对象,它一句那个常量”xyz”对象的内容来创建出一个新 String 对象。如果以前就用过’xyz’,这句代表就不会创建”xyz”自己了,直接从缓冲区拿。 

22、String 和 StringBuffer 的区别 

        JAVA 平台提供了两个类:String 和 StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个 String 类提供了数值不可改变的字符串而这个 StringBuffer 类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用 StringBuffer。典型地,你可以使用 StringBuffers 来动态构造字符数据。另外,String 实现了 equals 方法,new String(“abc”).equals(newString(“abc”)的结果为 true,而 StringBuffer 没有实现 equals 方法,所以,new StringBuffer(“abc”).equals(newStringBuffer(“abc”)的结果为 false。 

接着要举一个具体的例子来说明,我们要把1到100的所有数字拼起来,组成一个串。 
StringBuffer sbf = new StringBuffer();   
for(int i=0;i<100;i++) 

              sbf.append(i); 

上面的代码效率很高,因为只创建了一个 StringBuffer 对象,而下面的代码效率很低,因为创建了101个对象。 
String str = new String();   
for(int i=0;i<100;i++) 

              str = str + i; 

String 覆盖了 equals 方法和 hashCode 方法,而 StringBuffer 没有覆盖 equals 方法和hashCode 方法,所以,将 StringBuffer 对象存储进 Java 集合类中时会出现问题。 


23、数组有没有 length()这个方法? String 有没有 length()这个方法? 
数组没有 length()这个方法,有 length 的属性。String 有有 length()这个方法。 

24、final, finally, finalize 的区别。 

final  用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 内部类要访问局部变量,局部变量必须定义成 final 类型,例如,一段代码…… 
finally 是
异常处理语句结构的一部分,表示总是执行。 

finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM 不保证此方法总被调用 

25、运行时异常与一般异常有何异同? 

异常表示程序运行过程中可能出现的非正常状态运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 

25、error 和 exception 有什么区别? 
error  表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。  exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。 


26、Java 中的异常处理机制的简单原理和应用。 

Java 对异常进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根类java.lang.ThrowableThrowable 下面又派生了两个子类:Error 和 ExceptionError 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception 表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的

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

throws 捕获并向外抛出异常 
throw 抛出异常 
try catch 是内部捕获异常并做自定义处理 

finally 是无论是否有异常都会被处理的语句,除非在 finally 前存在被执行的System.exit(int i)时除外 

28、java 中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和 suspend()方法为何不推荐使用? 

   

有两种实现方法,分别使用 new Thread()和 new Thread(runnable)形式,第一种直接调用thread 的 run 方法,所以,我们往往使用 Thread 子类,即 new SubThread()。第二种调用runnable 的 run 方法。 

有两种实现方法,分别是继承 Thread 类与实现 Runnable 接口 用 synchronized 关键字修饰同步方法 反对使用 stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用 suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用 suspend(),而应在自己的 Thread 类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用 wait()命其进入等待状态。若标志指出线程应当恢复,则用一个 notify()重新启动线程。 

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

30、多线程有几种实现方法?同步有几种实现方法? 


多线程有两种实现方法,分别是继承 Thread 类与实现 Runnable 接口 
同步的实现方面有两种,分别是 synchronized,wait 与 notify 

wait():使一个线程处于等待状态,并且释放所持有的对象的 lock。 
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉
InterruptedException(中断异常)异常。 
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒 某一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且不是按优先级。 

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

   
31、启动一个线程是用 run()还是 start()? . 
启动一个线程是调用 start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。 
   

32、当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其它方法? 

分几种情况: 

          1.  其他方法前是否加了 synchronized 关键字,如果没加,则能。 

          2.  如果这个方法内部调用了 wait,则可以进入其他 synchronized 方法。 

          3.  如果其他个方法都加了 synchronized 关键字,并且内部没有调用 wait,则不能

         4.  如果其他方法是 static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是 this。

33、简述 synchronized 和 java.util.concurrent.locks.Lock 的异同? 
主要相同点:Lock 能完成 synchronized 所实现的所有功能 
主要不同点:Lock 有比 synchronized 更精确的线程语义和更好的性能。synchronized 会自动释放锁,而 Lock 一定要求程序员手工释放,并且必须在 finally 从句中释放。Lock 还有更强大的功能,例如,它的 tryLock 方法可以非阻塞方式去拿锁。 

34、ArrayList 和 Vector 的区别  
        这两个类都实现了 List 接口(List 接口继承了 Collection 接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的数据是允许重复的,这是 HashSet 之类的集合的最大不同处,HashSet 之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与 hashset 没有任何关系,但为了说清楚 ArrayList 与 Vector 的功能,我们使用对比方式,更有利于说明问题)。 
   接着才说 ArrayList 与 Vector 的区别,这主要包括两个方面:. 
    (1)同步性: 
              Vector 是线程安全的,也就是说是它的方法之间是线程同步的,而 ArrayList 是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用 ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用 Vector,因为不需要我们自己再去考虑和编写线程安全的代码。 
   
备注:对于 Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住 Vector与 Hashtable 是旧的,是 java 一诞生就提供了的,它们是线程安全的,ArrayList 与 HashMap是 java2时才提供的,它们是线程不安全的。所以,我们讲课时先讲老的。 
    (2)数据增长: 
              ArrayList 与 Vector 都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加 ArrayList 与 Vector 的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector 默认增长为原来两倍,而 ArrayList 的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍 )。ArrayList 与 Vector 都可以设置初始的空间大小,Vector 还可以设置增长的空间大小,而 ArrayList 没有提供设置增长空间的方法。 
        总结:即 Vector 增长原来的一倍,ArrayList 增加原来的0.5倍。

35、HashMap 和 Hashtable 的区别 
(条理上还需要整理,也是先说相同点,再说不同点) 

HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口,主要区别在于 HashMap 允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于 Hashtable。 

HashMap 允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。 

HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsvalue 和 containsKey。因为contains 方法容易让人引起误解。 

Hashtable 继承自 Dictionary 类 ,而 HashMap 是 Java1.2引进的 Map interface 的一个实现。 最大的不同是,Hashtable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供外同步。 
Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样,所以性能不会有很大的差异。 
就 HashMap 与 HashTable 主要从三方面来说。 
一.历史原因:    Hashtable 是基于陈旧的 Dictionary 类的,HashMap 是 Java 1.2引进的 Map 接口的一个实现 
二.同步性:    Hashtable 是线程安全的,也就是说是同步的,而 HashMap 是线程序不安全的, 不是同步的 
三.值:    只有 HashMap 可以让你将空值作为一个表的条目的 key 或 value 

36、List 和  Map 区别? 
        一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List 中存储的数据是有顺序,并且允许重复;Map 中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。 

37、List, Set, Map 是否继承自 Collection 接口? 

      List,Set 是,Map 不是 

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

39、去掉一个 Vector 集合中重复的元素 
Vector newVector = new Vector(); 
For (int i=0;i<vector.size();i++) 

Object obj = vector.get(i); 
              if(!newVector.contains(obj); 
                            newVector.add(obj); 

还有一种简单的方式,HashSet set = new HashSet(vector); 

40、Collection 和  Collections 的区别。 
Collection 是集合类的上级接口,继承与他的接口主要有 Set 和 List. 

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

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

        Set 里的元素是不能重复的,元素重复与否是使用 equals()方法进行判断的。equals()和==方法决定引用值是否指向同一对象 equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。 

42、两个对象值相同(x.equals(y) == true),但却可有不同的 hash code,这句话对不对? 
        对。 
        如果对象要保存在 HashSet 或 HashMap 中,它们的 equals 相等,那么,它们的 hashcode
值就必须相等。如果不是要保存在HashSet或HashMap,则 与hashcode没有什么关系了,这时候hashcode不等是可以的,例如 arrayList 存储的对象就不用实现 hashcode,当然,我们没有理由不实现,通常都会去实现的。 

42、说出一些常用的类,包,接口,请各举 5 个    
    常用的类:BufferedReader BufferedWriter    FileReader FileWirter    String    Integer ,java.util.Date,System,Class,List,HashMap 
     常用的包:java.lang    java.io java.util,java.sql,javax.servlet,org.apache.strtuts.action,org.hibernate 
     常用的接口:Remote List Map Document、
NodeList,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate)、Session(Hibernate),HttpSession 

43、java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 
      字节流,字符流。字节流继承于 InputStream OutputStream,字符流继承于InputStreamReaderOutputStreamWriter。在 java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。 

44、字节流与字符流的区别 

        字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备,这为我们向 IO 设别写入或读取字符串提供了一点点方便。字符向字节转换时,要注意编码的问题,因为字符串转成字节数组, 其实是转成该字符的某种编码的字节形式

45、描述一下 JVM 加载 class 文件的原理机制? 
        JVM 中类的装载是由 ClassLoader 和它的子类来实现的,Java ClassLoader 是一个重要的Java 运行时系统组件。它负责在运行时查找和装入类文件的类。 

 

46、heap 和 stack 有什么区别。 
        java 的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。 堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用 new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用 final修饰后,放在堆中,而不是栈中。 

47、GC 是什么?为什么要有 GC? 
GC 是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java 提供的 GC 功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java 语言没有提供释放已分配内存的显示操作方法。 

48、垃圾回收的优点和原理。并考虑 2 种回收机制。 

        垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

49. Java 代码查错 

1. 
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; 

 
答案:  正确。在 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 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-staticmethods。可改成"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("Dosomething ..."); 
        } 

答案:  正确。从来没有人说过 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 staticfinal.所以可以通过 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 = newBall("Football"); 
                System.out.println(ball.getName()); 
        } 
}  

答案:  错。"interfaceRollable extends Playable, Bounceable"没有问题。interface 可继承多个 interfaces,所以这里没错。问题出在 interface Rollable 里的"Ball ball =new Ball("PingPang");"。任何在 interface 里声明的 interface variable (接口变量,也可称成员变量),默认为 public static final。也就是说"Ball ball = new Ball("PingPang");"实际上是"public staticfinal Ball ball = new Ball("PingPang");"。在 Ball 类的 Play()方法中,"ball = newBall("Football");"改变了ball的reference,而这里的ball来自Rollable interface,Rollable interface 里的 ball 是 public static final 的,final 的 object 是不能被改变 reference 的。因此编译器将在"ball = newBall("Football");"这里显示有错。


JAVA WEB

1、Tomcat 的优化经验 
答:去掉对 web.xml 的监视,把 jsp 提前编辑成 Servlet。 有富余物理内存的情况,加大 tomcat 使用的 jvm 的内存 

   

2、解释一下什么是 servlet; 
答:servlet 有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由 javax.servlet.Servlet 接口的 init,service 和 destroy 方法表达。 

3、SERVLET API 中 forward()与 redirect()的区别? 

答:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用 forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用 sendRedirect()方法。

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

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

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

request 表示 HttpServletRequest 对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取 cookie, header,和 session 数据的有用的方法。

      response 表示 HttpServletResponse 对象,并提供了几个用于设置送回浏览器的响应的方法(如 cookies,头信息等) 

      out 对象是 javax.jsp.JspWriter 的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。 

      pageContext 表示一个 javax.servlet.jsp.PageContext 对象。它是用于方便存取各种范围的名字空间、servlet 相关的对象的 API,并且包装了通用的 servlet 相关功能的方法。 

      session 表示一个请求的 javax.servlet.http.HttpSession 对象。Session 可以存贮用户的状态信息 

      applicaton  表示一个 javax.servle.ServletContext 对象。这有助于查找有关 servlet 引擎和 servlet 环境的信息 

      config 表示一个 javax.servlet.ServletConfig 对象。该对象用于存取 servlet 实例的初始化参数。 

      page 表示从该页面产生的一个 servlet 实例 

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

8、两种跳转方式分别是什么?有什么区别? 

答:有两种,分别为: 
<jsp:include page=included.jsp flush=true> 
<jsp:forward page= nextpage.jsp/> 

        前者页面不会转向 include 所指的页面,只是显示该页的结果,主页面还是原来的页面。执行完后还会回来,相当于函数调用。并且可以带参数.后者完全转向新页面,不会再回来。相当于 go to  语句。 

   
9、页面间对象传递的方法 

request,session,application,cookie 等 

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

11、MVC 的各个部分都有那些技术来实现?如何实现? 

答:MVC 是 Model-View-Controller 的简写。Model 代表的是应用的业务逻辑(通过 JavaBean,EJB 组件实现),View 是应用的表示面(由 JSP 页面产生),Controller 是提供 应用的处理过程控制(一般是一个 Servlet),通过这种设计模型把应用逻辑,处理过程和显 示逻辑分成不同的组件实现。这些组件可以进行交互和重用。 

   


数据库部分技术


1、说出数据连接池的工作机制是什么? 
        J2EE 服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。 实现方式,返回的 Connection 是原始 Connection 的代理,代理 Connection 的 close 方法不是真正关连接,而是把它代理的 Connection 对象还回到连接池中。 

2、为什么要用  ORM?  和  JDBC 有何不一样? 
        orm 是一种思想,就是把 object 转变成数据库中的记录,或者把数据库中的记录转变成objecdt,我们可以用 jdbc 来实现这种思想,其实,如果我们的项目是严格按照 oop 方式编写的话,我们的 jdbc 程序不管是有意还是无意,就已经在实现 orm 的工作了。 现在有许多 orm 工具,它们底层调用 jdbc 来实现了 orm 工作,我们直接使用这些工具,就省去了直接使用 jdbc 的繁琐细节,提高了开发效率,现在用的较多的 orm 工具是 hibernate。也听说一些其他 orm 工具,如 toplink,ojb 等。 


3、你对 Spring 的理解。

1.    Spring 实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory(实际上是一个接口),在程序中通常 BeanFactory 的子类 ApplicationContext。Spring 相当于一个大的工厂类,在其配置文件中通过<bean>元素配置用于创建实例对象的类名和实例对象的属性。 
2.     Spring 提供了对 IOC 良好支持,IOC 是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦。IOC 也称为 DI(Depency Injection),什么叫依赖注入呢? 譬如,Class Programmer 

              Computer computer =null; 
              public void code() 
              { 
                            //Computercomputer = new IBMComputer(); 
                            //Computercomputer = beanfacotry.getComputer(); 
                            computer.write(); 
              } 
              public voidsetComputer(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>

4、Jdo 是什么? 
    JDO 是 Java 对象持久化的新的规范,为 java data object 的简称,也是一个用于存取某种数据仓库中的对象的标准化 API。JDO 提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码(如 JDBC API 的使用)。这些繁琐的例行工作已经转移到
JDO 产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,
JDO 很灵活,因为它可以在任何数据底层上运行。JDBC 只是面向关系数据库(RDBMS)
JDO 更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML 以及对象数据库(ODBMS)等等,使得应用可移植性更强。 


一、你如何理解static

一,static 变量:

    1,静态局部变量:

     静态局部变量属于静态存储方式,它具有以下特点:

  (1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。生命周期为整个源程序

  (2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它。作用域为此函数

  (3)声明即为初值为0;所有静态变量(包括静态全局变量、静态成员变量)的共同特点;这是区别普通变量的一个重要地方;声明即初始化为0;

  (4)自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜

2.静态全局变量

      (1)作用域为整个源程序;但不可被extern引用到其他文件,这是区别于普通全局变量的地方,普通全局变量可被extern到工程中任意文件;

      (2)生命周期为整个源程序;

      (3)声明即为初始化为0;

     (4)和静态局部变量重名无冲突,可同时存在;此处调用容易产生错误,注意调用操作;

  全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

静态变量

  除范围之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和公用变量的值。但是,对于 Dim 声明的局部变量以及声明局部变量的过程,仅当过程在执行时这些局部变量才存在。通常,当一个过程执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。

  但可将局部变量定义成静态的,从而保留变量的值。在过程内部用 Static 关键字声明一个或多个变量,其用法和 Dim 语句完全一样:

二,static函数:

三,static成员变量:

作用于整个类,从属于整个类,而不是类的某个对象;对于任意此类的某对象,静态成员变量起到的作用是共享此静态数据;

四,static成员函数:

五,作用域:、

    静态局部作用域在整个函数;静态全局作用域在整个源文件;静态成员变量是整个类而不是某个对象,即没有对象同样可以使用

六,生命周期:

     生命周期都是整个源文件,注意区别不是整个工程;而全局变量则是整个工程;

七,内存分配:

     声明即为初始化为0或者用户自定义值,分配内存在静态数据区;


深圳区域部分面试题

1、简述AOPIOC

AOP:面向(方面)切面的编程,Filter(过滤器)也是一种AOP,AOP是一种新的方法论,是对传统OOP的补充,AOP的主要编程对象是切面,而切面模块化横切关注点,可以举例通过事务说明

IOC:控制反转也称为DI(依赖注入)其思想是反转资源获取的方向,传统的资源查找方式要求组件向容器发起请求查找资源,作为回应,容器适时的返回资源,而应用了IOC之后,则是容器主动的将推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源,这种行为也被称为查找的被动形式

2、说明什么是事物

事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取。

3、JDBC代码实现事务

        在JDBC中,打开一个连接对象Connection时,缺省是auto-commit模式,每个SQL语句都被当作一个事务,即每次执行一个语句,都会自动的得到事务确认。为了能将多个SQL语句组合成一个事务,要将auto-commit模式屏蔽掉。在auto-commit模式屏蔽掉之后,如果不调用commit()方法,SQL语句不会得到事务确认。在最近一次commit()方法调用之后的所有SQL会在方法commit()调用时得到确认。

public int delete(int sID) {
 dbc = new DataBaseConnection();
 Connection con = dbc.getConnection();
 try {
  con.setAutoCommit(false);// 更改JDBC事务的默认提交方式
  dbc.executeUpdate("delete from bylaw where ID=" + sID);
  dbc.executeUpdate("delete from bylaw _content where ID=" + sID);
  dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID);
  con.commit();//提交JDBC事务
  con.setAutoCommit(true);// 恢复JDBC事务的默认提交方式
  dbc.close();
  return 1;
 }
 catch (Exception exc) {
  con.rollBack();//回滚JDBC事务
  exc.printStackTrace();
  dbc.close();
  return -1;
 }
}

4、简述OOPOOD、OOA

OOP:

        面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)是一种计算机编程架构。OOP 的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成。OOP 达到了软件工程的三个主要目标:重用性、灵活性和扩展性。为了实现整体运算,每个对象都能够接收信息、处理数据和向其它对象发送信息。OOP 主要有以下的概念和组件:

  组件 - 数据和功能一起在运行着的计算机程序中形成的单元,组件在 OOP 计算机程序中是模块和结构化的基础。

  抽象性 - 程序有能力忽略正在处理中信息的某些方面,即对信息主要方面关注的能力。

  封装 - 也叫做信息封装:确保组件不会以不可预期的方式改变其它组件的内部状态;只有在那些提供了内部状态改变方法的组件中,才可以访问其内部状态。每类组件都提供了一个与其它组件联系的接口,并规定了其它组件进行调用的方法。

  多态性 - 组件的引用和类集会涉及到其它许多不同类型的组件,而且引用组件所产生的结果得依据实际调用的类型。

  继承性 - 允许在现存的组件基础上创建子类组件,这统一并增强了多态性和封装性。典型地来说就是用类来对组件进行分组,而且还可以定义新类为现存的类的扩展,这样就可以将类组织成树形或网状结构,这体现了动作的通用性。

OOD:

     面向对象设计(Object-Oriented Design,OOD)方法是OO方法中一个中间过渡环节。其主要作用是对OOA分析的结果作进一步的规范化整理,以便能够被OOP直接接受。

OOA:

        OOA(面向对象的分析)模型由5个层次(主题层、对象类层、结构层、属性层和服务层)和5个活动(标识对象类、标识结构、定义主题、定义属性和定义服务)组成。在这种方法中定义了两种对象类之间的结构,一种称为分类结构,一种称为组装结构。分类结构就是所谓的一般与特殊的关系。组装结构则反映了对象之间的整体与部分的关系。

5、谈谈你对范型的理解

java中类型的参数化,用一个变量来表示某种类型。

6、何为Collection
  collection是集合类的上级接口,继承与它的接口主要有setlist

7、何为Collections
 是一个集合类的帮助类,它提供一系列静态方法实现对各种集合的搜索、排序以及线程安全化。

8、写出spring中实现事务的模式

实现spring事务的两种方式分别为:

(1)编程式事务管理:需要手动编写代码,在实际开发中很少使用

(2)声明式事务管理:

(2.1)基于TransactionProxyFactoryBean的方式,需要为每个进行事务管理的类做相应配置

(2.2)基于AspectJ的XML方式,不需要改动类,在XML文件中配置好即可

(2.3)基于注解的方式,配置简单,需要在业务层类中添加注解

9、写出java中创建对象的几种方式并写出关键实例代码

Java中有5种创建对象的方式,下面给出它们的例子还有它们的字节码

使用new关键字} → 调用了构造函数
使用Class类的newInstance方法} → 调用了构造函数
使用Constructor类的newInstance方法} → 调用了构造函数
使用clone方法} → 没有调用构造函数
使用反序列化} → 没有调用构造函数

1.使用new关键字

这是最常见也是最简单的创建对象的方式了。通过这种方式,我们可以调用任意的构造函数(无参的和带参数的)。

Employee emp1 = new Employee();

2.使用Class类的newInstance方法

我们也可以使用Class类的newInstance方法创建对象。这个newInstance方法调用无参的构造函数创建对象。

我们可以通过下面方式调用newInstance方法创建对象:

Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance();

或者

Employee emp2 = Employee.class.newInstance();

3.使用Constructor类的newInstance方法

和Class类的newInstance方法很像, java.lang.reflect.Constructor类里也有一个newInstance方法可以创建对象。我们可以通过这个newInstance方法调用有参数的和私有的构造函数。

Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();

4.使用clone方法

无论何时我们调用一个对象的clone方法,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone方法创建对象并不会调用任何构造函数。

要使用clone方法,我们需要先实现Cloneable接口并实现其定义的clone方法。

Employee emp4 = (Employee) emp3.clone();

5.使用反序列化

当我们序列化和反序列化一个对象,jvm会给我们创建一个单独的对象。在反序列化时,jvm创建对象并不会调用任何构造函数。
为了反序列化一个对象,我们需要让我们的类实现Serializable接口

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();

10、java中常见的异常类型

算术异常类:ArithmeticExecption

空指针异常类:NullPointerException

类型强制转换异常:ClassCastException

数组负下标异常:NegativeArrayException

数组下标越界异常:ArrayIndexOutOfBoundsException

违背安全原则异常:SecturityException

文件已结束异常:EOFException

文件未找到异常:FileNotFoundException

字符串转换为数字异常:NumberFormatException

操作数据库异常:SQLException

输入输出异常:IOException

方法未找到异常:NoSuchMethodException

java.lang.AbstractMethodError

抽象方法错误。当应用试图调用抽象方法时抛出。

java.lang.AssertionError


11、JSP 中的include 与静态include 的区别

        includejso: include动作实现,它总是会检查所包含文件的变化,适合包含动态页面,并可以带参数。静态include用伪代码实现,但不会检查包含的文件的变化,适合用于静态页面。

12、写出EJB 的基本架构,并用代码实现

        EJB6个角色,3个对象组成,这三个对象分别为:remote(local),home(localhome),bean类,同时bean又分为sessionbean(有状态的sessionbean,无状态的sessionbean),实体beanCMP,BMP),消息驱动bean;远程客服端通过remote调用相应业务方法。

13、请说出Class.forName() 的作用

   其作用要求JVM查询并加载指定的类。

14、简述B/S架构与C/S架构的区别?B/S架构分为几层?

  B/S模式是一种三层结构的系统。第一层客户机是用户与整个系统的接口。第二层Web服务器将启动相应的进程来响应这一请求,并动态生成一串HTML代码,其中嵌入处理的结果,返回给客户机的浏览器。如果客户机提交的请求包括数据的存取,Web服务器还需与数据库服务器协同完成这一处理工作。第三层数据库服务器的任务类似于C/S模式,负责协调不同的Web服务器发出的SQ请求,管理数据库。

      所谓"C/S"是指Client/Server(客户机/服务器)。C/S模式是一种两层结构的系统:第一层是在客户机系统上结合了表示与业务逻辑;第二层是通过网络结合了数据库服务器。


15、tomact是什么?

是使用Java进行Web开发的应用服务器(Application Server)软件

16、数据库是什么?

数据库(Database)是按照数据结构来组织、存储和管理数据的仓库

17、java中常见的接口有

Comparable 
Collection
Map
List
Runnable(java.lang.Runnable 该接口的定义public interface Runnable)

18、thread了解吗?如何解决thread在产生和消除时的占用系统资源的问题?



19、spring MVCstruts MVC有什么不同?

1. 核 心控制器(前端控制器、预处理控制器):对于使用过 mvc框架的人来说这个词应该不会陌生,核心控制器的主要用途是处理所有的请求,然后对那些特殊的请求 (控制器)统一的进行处理(字符编码、文件上传、参数接受、异常处理等等),spring mvc核心控制器是Servlet,而 Struts2是  Filter

2.控制器实例:Spring  Mvc会比  Struts快一些(理论上)。Spring   Mvc是基于方法设计,而Sturts是基于对象,每次发一次请求都会实例一个  action,每个 action都会被注入  属性,而Spring 更像 Servlet 一样,只有一个实例,每次请求执行对应的方法即可(注意:由于是单例实例,所以应当避免全局变量的修改,这样会产生线程安全问题)

3. 管理方式:大部分的公司的核心架构中,就会使用到 spring,而 spring   mvc又是  spring的一个模块,所以 spring对于spring  mvc的控制器管理更加简单方便,而且提供了全   注解方式进行管理,各种功能的注解都比较全面,使用简单,而 struts2需要采用  XML很多的配置参数来管理(虽然也可以采用注解,但是几乎没有公司那 样使用)。

4.参数传递:Struts2 中自身提供多种参数接受,其实都是通过(ValueStack)进行传递和赋值,而 SpringMvc是通过方法的参数进行接收。

5.intercepter 的实现机制:struts有以自己的  interceptor机制,spring  mvc用的是独立的   AOP方式。这样导致 struts的配置文件量还是比  spring  mvc大,虽然  struts的配置能继承,所以我觉得论使用上来讲,spring  mvc使用更加简洁,开发效率Spring  MVC确实比  struts2高。spring mvc是方法级别的拦截,一个方法对应一个  request上下文,而方法同时又跟一个  url对应,所以说从架构本身上 spring3 mvc就容易实现  restful urlstruts2是类级别的拦截,一个类对应一个 request上下文;实现  restful  url要费劲,因为   struts2  action的一个方法可以对应一个  url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。spring3 mvc的方法之间基本上独立的,独享  request response数据,请求数据通过参数获取,处理结果通过 ModelMap 交回给框架方法之间不共享变量,而 struts2  搞的就比较乱,虽然方法之间 也是独立的,但其所有 Action变量是共享的,这不会影响程序运行,却给我们编码,读程序时带来麻烦。

6.spring mvc处理  ajax请求,直接通过返回数据,方法中使用注解@ResponseBodyspring  mvc自动帮我们对象转换为 JSON数据。而  struts2是通过插件的方式进行处理在 SpringMVC流行起来之前,Struts2在   MVC框架中占核心地位,随着 SpringMVC的出现,SpringMVC慢慢的取代  struts2,但是很多企业都是原来搭建的框架,使用 Struts2较多。

20、 jsp的标签有哪些?

Include指令 、Forward指令 、UseBean指令 、GetProperty指令、SetProperty指令 、Plugin指令 

21、用一条SQL语句 查询出每门课都大于80分的学生姓名

 

name   kecheng   fenshu  

张三     语文            81 

张三     数学            75 

李四     语文            76 

李四     数学            90 

王五     语文            81 

王五     数学           100 

王五     英语            90 


  1. select distinct name from score  where  name not in (select distinct name from score where score<=80)  
[sql]  view plain  copy
  1. select distinct name from student s where not exists (select * from student s2 where fenshu <= 80 and s2.name = s.name);  
22、请描述数据连接池的工作机制是什么?

  J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。

23、Action是不是线程安全的?

线程安全概念

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

  或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。

  线程安全问题都是由全局变量及静态变量引起的。

若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

24、 java如何读取随机数?

方法1
(数据类型)(最小值+Math.random()*(最大值-最小值+1))
例:
(int)(1+Math.random()*(10-1+1))
从1到10的int型随数
方法2
获得随机数
for (int i=0;i<30;i++)
{System.out.println((int)(1+Math.random()*10));}
(int)(1+Math.random()*10)
通过java.Math包的random方法得到1-10的int随机数
公式是:最小值---最大值(整数)的随机数
(类型)最小值+Math.random()*最大值
方法3
Random ra =new Random();
for (int i=0;i<30;i++)
{System.out.println(ra.nextInt(10)+1);}
通过java.util包中的Random类的nextInt方法来得到1-10的int随机数
 
生成0到1之间的任意随机小数:


25、Spring中事务的几种隔离级别?

Isolation 属性一共支持五种事务设置:

1、DEFAULT 使用数据库设置的隔离级别 (默认) ,由 DBA 默认的设置来决定隔离级别 . 
2、READ_UNCOMMITTED 会出现脏读、不可重复读、幻读 (隔离级别最低,并发性能高)
3、READ_COMMITTED 会出现不可重复读、幻读问题(锁定正在读取的行,适合于大多数系统) 
4、REPEATABLE_READ 会出现幻读(锁定所读取的所有行) 
5、SERIALIZABLE 保证所有的情况不会发生(锁表)

26、解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。

堆区:专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中)

1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身.
3.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
栈区:对象实例在Heap 中分配好以后,需要在Stack中保存一个4字节的Heap内存地址,用来定位该对象实例在Heap 中的位置,便于找到该对象实例。
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
4.由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.
静态区/方法区:
1.方法区又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
3.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

附:

栈是运行时的单位,而堆是存储时的单位。

堆中存的是对象。栈中存的是基本数据类型和堆中对象的引用。一个对象的大小是不可估计的,或者说是可以动态变化的,但是在栈中,一个对象只对应了一个4btye的引用(堆栈分离的好处)。

27、String和StringBuilder,StringBuffer的区别?

     1.  在执行速度方面的比较:StringBuilder >  StringBuffer   

     2.  StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。

     3.StringBuilder:线程非安全的

        StringBuffer:线程安全的

  当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

对于三者使用的总结:1.如果要操作少量的数据用 = String

                                    2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

                                    3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

28. 抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?

都不能。
抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。 本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。 synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。

1、abstract与static

what 
abstract:用来声明抽象方法,抽象方法没有方法体,不能被直接调用,必须在子类overriding后才能使用。 
static:用来声明静态方法,静态方法可以被类及其对象调用。

how 
static与abstract不能同时使用。

why 
用static声明方法表明这个方法在不生成类的实例时可直接被类调用,而abstract方法不能被调用,两者矛盾。

2、abstract与native

what 
native:用来声明本地方法,该方法的实现由非java 语言实现,比如C。一般用于java与外环境交互,或与操作系统交互。 
参考:java中 本地方法 Native Method

how 
native可以与所有其它的java 标识符连用,但是abstract除外。

why 
因为 native 暗示这些方法是有实现体的,只不过这些实现体是非java 的,但是abstract却显然的指明这些方法无实现体。

3、abstract与synchronized

what 
synchronized:用于防止多个线程同时调用一个对象的该方法,与static连用可防止多个线程同时调用一个类的该方法。

how 
abstract与synchronized不能同时使用

why 
从synchronized的功能也可以看出,用synchronized的前提是该方法可以被直接调用,显然和abstract连用。


29、spring的七大模块作用分别是什么

核心容器(Spring core):提供Spring框架的基本功能,提供了IOC特性,管理bean与bean之间的依赖。

Spring上下文(Spring context):是一个配置文件,向Spring框架提供上下文信息(包括企业服务如EJB,JNDI,电子邮件,国际化,校验,调度功能)。

Spring 面向切面编程(Spring AOP):通过配置管理特性,将面向切面的编程用到Spring框架中,提供了事务管理。

Spring Dao :支持包括一致的异常处理和编程方式

Spring web : 提供web 应用程序的支持

Spring orm:用于与流行的ORM框架的整合

Spring mvc:针对web应用的MVC思想

30、oracle数据库表空间有哪几种各有什么区别

系统表空间(SYSTEM):用于存放Oracle系统内部表和数据字典的数据,如表名、列名、用户明等,不建议将用户创建的表、索引等对象放入

辅助表空间(SYSAUX):用于存放Oracle系统内部的常用样例对象,一般不存用户的数据,由Oracle系统内部自动维护

撤销表空间(UNDO):用于存放撤销信息

用户表空间(USERS):建议使用的表空间,可以创建表、索引等。

临时表空间(TEMP):存放临时数据

系统表空间(SYSTEM):用于存放Oracle系统内部表和数据字典的数据,如表名、列名、用户明等,不建议将用户创建的表、索引等对象放入

辅助表空间(SYSAUX):用于存放Oracle系统内部的常用样例对象,一般不存用户的数据,由Oracle系统内部自动维护

撤销表空间(UNDO):用于存放撤销信息

用户表空间(USERS):建议使用的表空间,可以创建表、索引等。

临时表空间(TEMP):存放临时数据

31、URL和URI的区别。

URI、URL和URN
URI :Uniform Resource Identifier,统一资源标识符;
URL:Uniform Resource Locator,统一资源定位符;
URN:Uniform Resource Name,统一资源名称。
其中,URL,URN是URI 的子集

Web上地址的基本形式是URI,它代表统一资源标识符。有两种形式:
URL:目前URI的最普遍形式就是无处不在的URL或统一资源定位器。
URN:URL的一种更新形式,统一资源名称(URN, Uniform Resource Name)不依赖于位置,并且有可能减少失效连接的个数。但是其流行还需假以时日,因为它需要更精密软件的支持。
URI是以某种统一的(标准化的)方式标识资源的简单字符串。

32、排序的实现(冒泡、选择、快速等)

冒泡排序Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

package com.xjtu.cruise;

public class Sort {

	/**
	 * 冒泡排序
	 * 
	 * @param data
	 *            目标数组
	 */
	public static void bubbleSort(int[] data) {

		for (int i = 0; i < data.length - 1; i++) {// 控制趟数
			for (int j = 0; j < data.length - i - 1; j++) {

				if (data[j] > data[j + 1]) {
					int tmp = data[j];
					data[j] = data[j + 1];
					data[j + 1] = tmp;
				}
			}
		}

	}

	/**
	 * 选择排序
	 * 
	 * @param data
	 *            目标数组
	 */
	public static void selectSort(int[] data) {
		if (data == null || data.length == 0) {
			return;
		}

		for (int i = 0; i < data.length - 1; i++) {
			int min = i;// 将当前下标定为最小值下标
			for (int j = i + 1; j < data.length; j++) {
				if (data[j] < data[min]) {
					min = j;
				}
			}

			if (i != min) {
				int tmp = data[i];
				data[i] = data[min];
				data[min] = tmp;
			}
		}
	}

	/**
	 * 选择排序 此算法效率不如上面的高
	 * 
	 * @param sort
	 */
	public static void selectSort2(int[] data) {

		for (int i = 0; i < data.length - 1; i++) {
			for (int j = i + 1; j < data.length; j++) {
				if (data[j] < data[i]) {
					int temp = data[j];
					data[j] = data[i];
					data[i] = temp;
				}
			}
		}
	}

	/**
	 * 快速排序算法
	 * 
	 * @param data
	 *            目标数组
	 * @param start
	 *            起始位
	 * @param end
	 *            结束位
	 */
	public static void quickSort(int[] data, int start, int end) {
		// 设置关键数据key为要排序数组的第一个元素,
		// 即第一趟排序后,key右边的数全部比key大,key左边的数全部比key小
		int key = data[start];
		// 设置数组左边的索引,往右移动比key大的数
		int i = start;
		// 设置数组右边的索引,往左移动比key小的数
		int j = end;
		// 如果左边索引比右边索引小,则还有数据没有排序
		while (i < j) {
			while (data[j] > key && j > i) {
				j--;
			}
			data[i] = data[j];

			while (data[i] < key && i < j) {
				i++;
			}
			data[j] = data[i];
		}
		// 此时 i==j
		data[i] = key;

		// 递归调用
		if (i - 1 > start) {
			// 递归调用,把key前面的完成排序
			quickSort(data, start, i - 1);
		}
		if (i + 1 < end) {
			// 递归调用,把key后面的完成排序
			quickSort(data, i + 1, end);
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int[] p = { 34, 21, 54, 18, 23, 76, 38, 98, 45, 33, 27, 51, 11, 20, 79,
				30, 89, 41 };

		long start = System.currentTimeMillis();

//		Sort.bubbleSort(p);// 冒泡排序
//		Sort.selectSort(p);// 选择排序
//		Sort.selectSort2(p);// 选择排序2
		Sort.quickSort(p, 0, p.length - 1);// 快速排序

		System.out.println("所用时间:" + (System.currentTimeMillis() - start));
		for (int i = 0; i < p.length; i++) {
			System.out.print(p[i] + " ");
		}
	}

}

以上便是我整理的部分内容,虽然有些乱。但知识点都是比较常用、常考的。要是有什么问题只管说就行我会改正滴。大笑


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值