汇总题

一、Java基础

1.写出下面代码的执行结果

public class Foo {
    public static void main(String[] args) {
        String strValue="ABCDEFG"; 
        strValue.substring(3); 
        strValue.concat("123");
        System.out.println("result=" + strValue);       
        String value = new String ("ABCDEFG");
        System.out.println(strValue== value); 
    }
}
result=ABCDEFG
false

2.写出下面代码的执行结果

public class Foo{  (分值5分)
    public static void main(String args[]) {
        int x = 100;
        int y = 200;
        if (x = y)
            System.out.println("Not equal");
        else
            System.out.println("Equal");
    }
}
编译报错if (true或false)x = y结果为int类型不兼容

3.写出下面代码的执行结果 (此题需写出分析过程,没有分析过程不得分,分值10分)

public static void main(String args[]) {
    try {
        new TestAll().methodA(5);
    } catch (IOException e) {
        System.out.println("caught IOException");
    } catch (Exception e) {
        System.out.println("caught Exception");
    }finally{
        System.out.println("no Exception");
    }
}

void methodA(int i) throws IOException {
    if (i%2 != 0)
        throw new IOException("methodA IOException");
}
caught IOException
no Exception
try{}
catch(){}
finally{}
try catch捕获相应的异常类型,finally始终会执行

4.写出下面代码执行的结果(此题需写出分析过程,没有分析过程不得分,分值10分)

static boolean isTrue() {
    System.out.println("isTrue");
    return true;
}

static boolean isFalse() {
    System.out.println("isFalse");
    return false;
}

public static void main(String[] args) {
    if (isTrue() || isFalse()) {
        System.out.println(" || operate return true");
    }
    if (isFalse() & isTrue()) {
        System.out.println(" & operate return true");
    }
}
isTrue
 || operate return true
isFalse
isTrue

||具有“短路功能”当左边为真后 右边不在执行

5.写出下面代码执行的结果(此题需写出分析过程,没有分析过程不得分)

class MyThread extends Thread{
    public void run(){
        try {
            Thread.currentThread().sleep(3000);
        } catch (InterruptedException e) {
        }
        System.out.println("MyThread running");
    }
}



public class ThreadTest{
    public static void main(String argv[]) {
        MyThread t = new MyThread();
        t.run();
        t.start();
        System.out.println("Thread Test");
      }

}
MyThread running
Thread Test
MyThread running

t.run();调用 MyThread 的run()方法,当前线程为主线程main睡眠3s
t.start();启动一个新的线程,先的线程睡眠3s所以Thread Test会先打印

6.执行B.main的结果是什么?(此题需写出分析过程,没有分析过程不得分,分值10分)

class A {
  void fun1() {
    System.out.println(this.fun2());
  }
  int fun2() {
    return 123;
  }
}

class B extends A {
  int fun2() {
    return 456;
  }
  public static void main(String argv[]) {
    A a;
    B b = new B();
    b.fun1();
    a = b;
    a.fun1();
  }
}
456
456
this调用的是当前对象,a = b a指向new B();

7.执行ListTest.main的结果是什么?(此题需写出分析过程,没有分析过程不得分,分值10分)

class Data {
    int val;
    int getVal() {
        return val;
    }
    void    setVal(int val) {
        this.val = val;
    }
}

public class ListTest {

    public static void main(String argv[]) {
        Data data = new Data();
        ArrayList list = new ArrayList();

        for (int i=100; i<103; i++) {
            data.setVal(i);
            list.add(data);
        }

        int j = 0;
        while (j < list.size()) {
            Data tmp = (Data )list.get(j);
            System.out.println("list(" + j + ") = " + tmp.getVal());
            j++;
        }
    }
}
list(0) = 102
list(1) = 102
list(2) = 102
for循环当中每次改变的都是同一个date对象中的值,应该在for循环内创建(new)对象

8.请指出以下代码有哪些错误(分值15分)

1. 
abstract class Name {
private String name;
// 抽象类中的抽象方法,不应该有方法体
public abstract boolean isStupidName(String name) {}
}
2. 
public class Something {
    void doSomething () 
    {
        private String s = ""; // 方法中的修饰符不能是private,这个只能在类中使用
        int l = s.length();
    }
}
3.
abstract class Something {
    private abstract String doSomething ();// 抽象方法不应该是private的,因为注定要被继承, 如果是private,就继承不了啦
}
4.
public class Something {
    public int addOne(final int x) {
        return ++x; // final 修饰的x,不能被修改
    }
}
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;
}

6. 没错
class Something {
    int i;
    public void doSomething() {
        System.out.println("i = " + i);
    }
}

7.
class Something {
    final int i; // final修饰的变量要被初始化
    public void doSomething() {
        System.out.println("i = " + i);
    }
}
8.
public class Something {
    public static void main(String[] args) {
        Something s = new Something();
         
        // 静态方法main中调用doSomething, 但是doSomething不是static修饰的
        System.out.println("s.doSomething() returns " + doSomething());
    }
    public String doSomething() {
        return "Do something ...";
    }
}

9. 写法没错,但是和文件名称不统一
class Something {
    private static void main(String[] something_to_do) 
    {
        System.out.println("Do something ...");
    }
}

9.写出以下正则表达式(分值10分)
1-6位字母或数字: ^[0-9a-zA-Z]{1,6}$
手机号(只能以139或159开通,11位数字):
"^(139|159)\d{8}$"

10.写一个方法,实现字符串的反转,如:输入abc,输出cba(分值10分)

Java code
String str = "abc";
String reStr = new StringBuilder(str).reverse().toString();

或者
/**
 * 将字符串变成数组
 * 对数组反转,将数组变成字符串
 */
public static String reverseString(String s, int start, int end) {
    //字符串变数组。
    char[] chs = s.toCharArray();
    //反转数组。
    reverse(chs, start, end);
    //将数组变成字符串。
    return new String(chs);
}

private static void reverse(char[] arr, int x, int y) {
    for (int start = x, end = y - 1; start < end; start++, end--) {
        swap(arr, start, end);
    }
}

private static void swap(char[] arr, int x, int y) {
    char temp = arr[x];
    arr[x] = arr[y];
    arr[y] = temp;

11.写一个延迟加载的单例模式(Singleton)的例子(分值10分)

//懒汉
public class Singleton {
    private Singleton(){}
    private static class LazyHodler{
        private static Singleton Instance = new Singleton();
    }
    public static Singleton getInstance(){
        return LazyHodler.Instance;
    }
}
public class OuterClass { 
  private double d1 = 1.0; 
    //insert code here 
} 
把下列答案存放在指定code位置上,哪两个答案是正确的。阐述原因。
A. class InnerOne{
     public static double methoda() {return d1;}
   } 
B. public class InnerOne{
     static double methoda() {return d1;}
   } 
C. private class InnerOne{
     double methoda() {return d1;}
   } 
D. static class InnerOne{
     protected double methoda() {return d1;}
   } 
E. abstract class InnerOne{
     public abstract double methoda();
   }

说明如下:
静态内部类可以有静态成员,而非静态内部类不能有静态成员AB错,
静态内部类的非静态成员可以访问外部类的静态变量,而不可访问外部类的非静态变量return d1;出错故D错
非静态内部类的非静态成员可以访问外部类的非静态变量 故C正确
CE

题目补充

1、Java里的传引用和传值的区别是什么?
答案:传引用是指传递的是地址而不是值本身,传值则是传递值的一份拷贝。

2、为什么Java里没有全局变量?
答案:全局变量是全局可见的,Java不支持全局可见的变量,因为:全局变量破坏了引用透明性原则。全局变量导致了命名空间的冲突。

3、如何将String类型转化成Number类型?
答案:Integer类的valueOf方法可以将String转成Number。

4、面向对象编程的原则是什么?
答案:主要有三点,多态,继承和封装。

5、所有类的父类是什么?
答案:object

6、Java的基本类型有哪些?
答案:byte,char, short, int, long, float, double, boolean。

7、怎么判断数组是null还是为空?
答案:输出array.length的值,如果是0,说明数组为空。如果是null的话,会抛出空指针异常。

8、JDK和JRE的区别是什么?
答案:Java运行时环境(JRE)是将要执行Java程序的Java虚拟机。它同时也包含了执行applet需要的浏览器插件。Java开发工具包(JDK)是完整的Java软件开发包,包含了JRE,编译器和其他的工具(比如:JavaDoc,Java调试器),可以让开发者开发、编译、执行Java应用程序。

9、Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?
答案:Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。

10、Java支持多继承么?
答案:不支持,Java不支持多继承。每个类都只能继承一个类,但是可以实现多个接口。

11、进程和线程的区别是什么?
答案:进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。

12、创建线程有几种不同的方式?你喜欢哪一种?为什么?
答案:有三种方式可以用来创建线程:
继承Thread类
实现Runnable接口
实现Callable接口
应用程序可以使用Executor框架来创建线程池
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。

13、什么是死锁(deadlock)?
答案:两个进程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是两个进程都陷入了无限的等待中。

14、简单的说下HashMap和TreeMap的区别?
答案:HashMap:适用于在Map中插入、删除和定位元素。TreeMap:适用于按自然顺序或自定义顺序遍历键(key)。HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。

18、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
答案:会执行,在return前执行。

19、在JAVA中,如何跳出当前的循环?
答案:用break; return方法。

20、在Java中,如何跳出当前的多重嵌套循环?
答案:在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。

21、在书写代码记录操作日志时,是先写日志 还是后写日志?哪个会好些?
答案:先写日志。 先写日志-->处理业务-->更新日志状态。

25、说出几种java中的修饰符?
答案:public、protect、default、private

27、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
答案:当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块;当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

28、Collection 和 Collections的区别?
答案:Collection是集合类的上级接口,继承与他的接口主要有Set 和List。Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

29、在java中一个类被声明为final类型,表示了什么意思?
答案:表示该类不能被继承,是顶级类。

30、存在使i + 1 < i的数吗?
答案:存在,解析:如果i为int型,那么当i为int能表示的最大整数时,i+1就溢出变成负数了,此时不就<i了吗。

31、Java接口的修饰符可以为(D)
A private B protected C final D abstract

32、不通过构造函数也能创建对象吗(A)
A 是 B 否
(1)用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。

33、swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
答:早期的JDK中,switch(expr)中,expr可以是byte、short、char、int。从1.5版开始,Java中引入了枚举 类型(enum),expr也可以是枚举,从JDK 1.7版开始,还可以是字符串(String)。长整型(long)是不可以的。

34、是否可以继承String 类?
答:String类是final类,不可以被继承。

35、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答:是值传递。Java编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对象的引用是永远不会改变的。

36、String 和StringBuilder、StringBuffer的区别?
答:Java 平台提供了两种类型的字符串:String和StringBuffer / StringBuilder,它们可以储存和操作字符串。其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的。而 StringBuffer和StringBuilder类表示的字符串对象可以直接进行修改。StringBuilder是JDK 1.5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer略高。

37、char 型变量中能不能存贮一个中文汉字?为什么?
答:char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16bit),所以放一个中文是没问题的。
补充:使用Unicode意味着字符在JVM内部和外部有不同的表现形式,在JVM内部都是Unicode,当这个字符被从JVM内部转移到外部时 (例如存入文件系统中),需要进行编码转换。所以Java中有字节流和字符流,以及在字符流和字节流之间进行转换的转换流,如 InputStreamReader和OutputStreamReader,这两个类是字节流和字符流之间的适配器类,承担了编码转换的任务;

38、抽象类(abstract class)和接口(interface)有什么异同?
答:抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其 中的方法全部都是抽象方法。抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。抽象 类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。

39、静态变量和实例变量的区别?
答:静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有 且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。在Java开发中,上下文 类和工具类中通常会有大量的静态成员。

40、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?
答:不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,因此在调用静态方法时可能对象并没有被初始化。

41、如何实现对象克隆?
答:有两种方式:
1.实现Cloneable接口并重写Object类中的clone()方法;
2.实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

42、GC 是什么?为什么要有GC?

答:GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理, 因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc()或Runtime.getRuntime().gc(),但JVM可以屏蔽掉显示的垃圾回收调用。

43、String s=new String(“xyz”);创建了几个字符串对象?
答:两个对象,一个是静态存储区的"xyz",一个是用new创建在堆上的对象。

44、接口是否可继承(extends)接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)?
答:接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承具体类,但前提是具体类必须有明确的构造函数。

45、什么时候用assert?
答:assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。在实现中,断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为true;如果表达式计算为false,那么系统会报告一个AssertionError。

46、Error和Exception有什么区别?
答:Error 表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情 况;Exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。

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

48、sleep()和yield()有什么区别?
答:sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;sleep()方法比yield()方法(跟操作系统相关)具有更好的可移植性。

49、请说出与线程同步相关的方法。
答:
1.wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
2.sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常,不会释放锁;
3.notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;
4.notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争;
5.JDK 1.5通过Lock接口提供了显式(explicit)的锁机制,增强了灵活性以及对线程的协调。Lock接口中定义了加锁(lock())和解锁 (unlock())的方法,同时还提供了newCondition()方法来产生用于线程之间通信的Condition对象;
6.JDK 1.5还提供了信号量(semaphore)机制,信号量可以用来限制对某个共享资源进行访问的线程的数量。在对资源进行访问之前,线程必须得到信号量的 许可(调用Semaphore对象的acquire()方法);在完成对资源的访问后,线程必须向信号量归还许可(调用Semaphore对象的release()方法)。

50、什么是线程池(thread pool)?
答:
在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每 一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销 毁,这就是"池化资源"技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
在Java 5+中的Executor接口定义一个执行线程的工具。它的子类型即线程池接口是ExecutorService。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,因此在工具类Executors面提供了一些静态工厂方法,生成一些常用的线程池,如下所示:
newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
newCachedThreadPool: 创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可 以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。
如果希望在服务器上使用线程池,强烈建议使用newFixedThreadPool方法来创建线程池,这样能获得更好的性能。

82、简述synchronized和java.util.concurrent.locks.Lock的异同?
答:Lock是Java 5以后引入的新的API,和关键字synchronized相比主要相同点:Lock 能完成synchronized所实现的所有功能;主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally 块中释放(这是释放外部资源的最好的地方)。

83、Java中如何实现序列化,有什么意义?
答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来。构造一个对象输出流并通过writeObject(Object obj)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对 象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆。

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

1、谈谈你对面向对象的理解
答:
面向对像的程序是由类组成的,每个类包含对用户公开的特定功能部分和隐藏的实现部分。传统的结构化程序设计通过设计一系列的过程(即算法)来求解问题。这一些过程一旦被确定,就要开始考考虑存储数据的方式,这就明确的表述了程序员的工作方式。但面相对像却调换了这个顺序,它不必关心数据对象的具体实现,只要能满足用户的需求即可。面向对象有三个最基本的特性,即:封装,继承,多态。

2、ClassLoader如何加载class 。
答:
jvm里有多个类加载,每个类加载可以负责加载特定位置的类,例如,bootstrap类加载负责加载jre/lib/rt.jar中的类, 我们平时用的jdk中的类都位于rt.jar中。extclassloader负责加载jar/lib/ext/*.jar中的类,appclassloader负责classpath指定的目录或jar中的类。除了bootstrap之外,其他的类加载器本身也都是java类,它们的父类是ClassLoader。

3、如何实现线程通讯

①同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信。
这种方式,本质上就是“共享内存”式的通信。多个线程需要访问同一个共享变量,谁拿到了锁(获得了访问权限),谁就可以执行。
③wait/notify机制
②while轮询的方式

二、jsp/servlet/jquery/ajax

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

2、什么情况下调用doGet()和doPost()?
答:Jsp页面中的FORM标签里的method属性为get时调用doGet(),为post时调用doPost()。
15、自定义标签要继承哪个类?
答案:这个类可以继承TagSupport或者BodyTagSupport,两者的差别是前者适用于没有主体的标签,而后者适用于有主体的标签。如果选择继承TagSupport,可以实现doStartTag和doEndTag两个方法实现Tag的功能,如果选择继承BodyTagSupport,可以实现doAfterBody这个方法。

3、request.getAttribute()和request.getParameter() 有何区别?

答:getAttribute是返回对象,getParameter返回字符串 。总的来说:request.getAttribute()方法返回request范围内存在的对象,而request.getParameter()方法是获取http提交过来的数据。

4、jsp有哪些内置对象?作用分别是什么? 分别有什么方法?

答:
JSP中九大内置对象为:

对象 含义 类型 作用域
request 请求对象 javax.servlet.ServletRequest Request
response 响应对 javax.servlet.SrvletResponse Page
pageContext 页面上下文对象 javax.servlet.jsp.PageContext Page
session 会话对象 javax.servlet.http.HttpSession Session
application 应用程序对象 javax.servlet.ServletContext Application
out 输出对象 javax.servlet.jsp.JspWriter Page
config 配置对象 javax.servlet.ServletConfig Page
page 页面对象 javax.lang.Object Page
exception 例外对象 javax.lang.Throwable page
相关方法:

request对象代表的是来自客户端的请求,例如我们在FORM表单中填写的信息等,是最常用的对象。常用的方法有:getParameter、getParameterNames 和getParameterValues通过调用这几个方法来获取请求对象中所包含的参数的值。
response 对象代表的是对客户端的响应,也就是说可以通过response 对象来组织发送到客户端的数据。但是由于组织方式比较底层,所以不建议普通读者使用,需要向客户端发送文字时直接使用
pageContext对象直译时可以称作“页面上下文”对象,代表的是当前页面运行的一些属性。常用的方法有 :findAttribute、getAttribute、getAttributesScope 和getAttributeNamesInScope。一般情况下pageContext对象用到得也不是很多,只有在项目所面临的情况比较复杂的情况下,才会利用到页面属性来辅助处理。
session对象代表服务器与客户端所建立的会话,当需要在不同的JSP页面中保留客户信息的情况下使用,比如在线购物、客户轨迹跟踪等。“session” 对象建立在cookie的基础上,所以使用时应注意判断一下客户端是否打开了cookie。常用的方法包括getId、 getValue、 getValueNames和putValue等。

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

答:request,session,application,cookie等。

6、J2EE是技术还是平台还是框架? 什么是J2EE

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

7、什么是MVC模式?

MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。
这个模式认为,程序不论简单或复杂,从结构上看,都可以分成三层:

1)最上面的一层,是直接面向最终用户的"视图层"(View)。它是提供给用户的操作界面,是程序的外壳。
2)最底下的一层,是核心的"数据层"(Model),也就是程序需要操作的数据或信息。
3)中间的一层,就是"控制层"(Controller),它负责根据用户从"视图层"输入的指令,选取"数据层"中的数据,然后对其进行相应的操作,产生最终结果。
这三层是紧密联系在一起的,但又是互相独立的,每一层内部的变化不影响其他层。每一层都对外提供接口(Interface),供上面一层调用。这样一来,软件就可以实现模块化,修改外观或者变更数据都不用修改其他层,大大方便了维护和升级。

8、解析xml有哪几种方式,优缺点?

1、JDOM生成和解析XML
为减少DOM、SAX的编码量,出现了JDOM。优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。
2、SAX生成和解析XML文档
为解决DOM的问题,出现了SAX,SAX事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个文档,占用资源少。SAX解析器代码比DOM解析器代码小,适于Applet下载。缺点:不是持久的,事件过后若没保存数据,那么数据就丢了。无状态性,从事件中只能得到文本,但不知该文本属于哪个元素。使用场合:Applet。只需XML文档的少量内容,很少回头访问,机器内存少。
3、DOM生成和解析XML文档
为XML文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用DOM 接口来操作这个树结构。优点:整个文档树在内存中,便于操作,支持删除、修改、重新排列等多种功能。缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间。使用场合:一旦解析了文档还需多次访问这些数据,硬件资源充足(内存、CPU)。

4、DOM4J生成和解析XML文档

DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java 软件都在使用DOM4J来读写XML,特别值得一提的是连 Sun 的JAXM也在用DOM4J。

题目补充

1、静态include和动态include的区别

<% @ include file="include.html" %>静态include主要是对静态页面的引入,不会检查所包含文件的变化

<jsp:include>动态include主要是对动态页面的引入,它总是会检查所引入的页面的变化,如果所包含的资源在请求间发生变化,则下一次请求包含<jsp:include>动作的jsp时,将包含资源的新内容。

<jsp:include>动作包含的属性:
page:指定所包含资源的相对url路径,该资源必须时同一web应用程序的组成部分。
flush:指定在执行include动作后是否应刷新缓冲区,在jsp1.1中,该属性必须设置为真。
使用动态include动作时,根据jsp1.1规范,jsp容器允许判断通过include指令包含的资源是否发生变化。如果发生变化。则容器可以重新编译包含该资源的jsp,然而,该规范并没有提供向容器表明某个包含的资源发生变化的机制。

动态include的优点和不足:

优点:
1:引入和同步一个动态的页面,使jsp页面更具灵活性
2:能和不同页面之间进行信息的交互和快捷的实现方式。
3:改变了原始的所有页面编码都放在一个jsp上,使不同的功能分别写在不同页里,通过动态include方式引用到页面,更易于编码,更易于管理。

不足:
动态的引入时需要频繁的变化和页面信息的更新和交互,要占用大量的资源开销。降低页面的访问速度。如果在没必要动态引入的情况下,不要使用动态include
应该注意事项:

1:<jsp:include>动作的flush属性必须要定义,不定义会出现转换错误。而且设置的flush必须要为true
2:在<jsp:include>动作中指定的页面必须是同一web应用程序的一部分。如果引入的是非同一web应用的页面将导致请求时错误。

16、jsp页面是在服务器端运行还是在客户端运行?
答案:服务器端。JSP与Java Servlet一样

三、Spring/SpringMVC/mybatis/hibernate

22、什么是ORM框架?
答案:ORM(Object Relational Mapping)框架采用元数据来描述对象一关系映射细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。通过某种关系来维持实体对象和数据库之间的关系,然后通过实体对象的操作来实现数据库的操作。也就是对象关系映射。

23、你了解哪几种orm框架?
答案:Hibernate/myBatis 等。myBatis不完全是orm,需要手动写sql。

24、你用过哪几个版本控制工具?
答案:GIT等。

未完待续...
四、数据库
五、编程题
六、编程题

webservice是什么?
一言以蔽之:WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然!跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。

所谓远程调用,就是一台计算机a上的一个程序可以调用到另外一台计算机b上的一个对象的方法,譬如,银联提供给商场的pos刷卡系统,商场的POS机转账调用的转账方法的代码其实是跑在银行服务器上。再比如,amazon,天气预报系统,淘宝网,校内网,百度等把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能,这样扩展了自己系统的市场占有率,往大的概念上吹,就是所谓的SOA应用。

其实可以从多个角度来理解WebService,从表面上看,WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API,也就是说能用编程的方法通过Web来调用这个应用程序。我们把调用这个WebService的应用程序叫做客户端,而把提供这个WebService的应用程序叫做服务端。从深层次看,WebService是建立可互操作的分布式应用程序的新平台,是一个平台,是一套标准。它定义了应用程序如何在Web上实现互操作性,你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问。

WebService平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和类型系统。要实现互操作性,WebService平台必须提供一套标准的类型系统,用于沟通不同平台、编程语言和组件模型中的不同类型系统。Web service平台必须提供一种标准来描述Web service,让客户可以得到足够的信息来调用这个Web service。最后,我们还必须有一种方法来对这个Web service进行远程调用,这种方法实际是一种远程过程调用协议(RPC)。为了达到互操作性,这种RPC协议还必须与平台和编程语言无

WebService平台技术
XML+XSD,SOAP和WSDL就是构成WebService平台的三大技术。
XML+XSD:
WebService采用HTTP协议传输数据,采用XML格式封装数据(即XML中说明调用远程服务对象的哪个方法,传递的参数是什么,以及服务对象的返回结果是什么)。XML是WebService平台中表示数据的格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关的。无关性是比技术优越性更重要的:软件厂商是不会选择一个由竞争对手所发明的技术的。
XML解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。例如,整形数到底代表什么?16位,32位,64位?这些细节对实现互操作性很重要。XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。WebService平台就是用XSD来作为其数据类型系统的。当你用某种语言(如VB.NET或C#)来构造一个Web service时,为了符合WebService标准,所有你使用的数据类型都必须被转换为XSD类型。你用的工具可能已经自动帮你完成了这个转换,但你很可能会根据你的需要修改一下转换过程。
SOAP:
WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议。SOAP提供了标准的RPC方法来调用Web Service。
SOAP协议 = HTTP协议 + XML数据格式
SOAP协议定义了SOAP消息的格式,SOAP协议是基于HTTP协议的,SOAP也是基于XML和XSD的,XML是SOAP的数据编码方式。打个比喻:HTTP就是普通公路,XML就是中间的绿色隔离带和两边的防护栏,SOAP就是普通公路经过加隔离带和防护栏改造过的高速公路。
WSDL:
好比我们去商店买东西,首先要知道商店里有什么东西可买,然后再来购买,商家的做法就是张贴广告海报。 WebService也一样,WebService客户端要调用一个WebService服务,首先要有知道这个服务的地址在哪,以及这个服务里有什么方法可以调用,所以,WebService务器端首先要通过一个WSDL文件来说明自己家里有啥服务可以对外调用,服务是什么(服务中有哪些方法,方法接受的参数是什么,返回值是什么),服务的网络地址用哪个url地址表示,服务通过什么方式来调用。
WSDL(Web Services Description Language)就是这样一个基于XML的语言,用于描述Web Service及其函数、参数和返回值。它是WebService客户端和服务器端都能理解的标准格式。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档,又能导入WSDL文档,生成调用相应WebService的代理类代码。
WSDL文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址。WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。

webservice有几种实现方式?
1.Axis2
  Axis是apache下一个开源的webservice开发组件,出现的算是比较早了,也比较成熟。这里主要介绍Axis+eclipse开发webservice,当然不用eclipse也可以开发和发布webservice,只是用eclipse会比较方便。
2.Apche CXF
  CXF开发webservice也是比较方便和简单的,它和spring的集成可以说是非常地好。
3.JDK开发webservice(jdk自带的jaxws)

webservice配置步骤?

施用Spring+CXF开发WebService,使用注解方式

Webservice如何控制事务?

WebService入门详解

推荐阅读更多精彩内容