第一套

1.以下Java程序运行的结果是:

public class Tester{
public static void main(String[] args){
   Integer var1=new Integer(1);
   Integer var2=var1;
   doSomething(var2);
   System.out.print(var1.intValue());
   System.out.print(var1==var2);
}
public static void doSomething(Integer integer){
    integer=new Integer(2);
    }
}

正确答案: A
1true
2true
1false
2false

Java中处理8种基本的数据类型用的是值传递,其他所有类型都用的是引用传递,由于这8种基本数据类型的包装类型都是不可变类,因此增加了对“按引用传递”的理解难度。其实还是很好理解的,题目中doSomething方法中new了一个对象,这是误导大家选择答案C的原因。其实,按引用传递的实质是将地址值的副本作为实参代替方法中的形参,因此var2与var1里面存储的地址值仍然是一样的,方法中操作的只是var2的一个副本值,并不影响var2本身存储的地址值,所以答案选择A。

在doSomething函数中执行 integer=new Integer(2)改变了引用对象,所以执行这个指令的另一个赋值功能,对原来的对象没有效果,也就是说var2的值不会变为2。

第二套

1.应用程序的main方法中有以下语句,则输出的结果( )

String s1=new String( ” xyz ” );
String s2=new String( ” xyz ” );
Boolean b1=s1.equals(s2);
Boolean b2=(s1==s2);
System .out.print(b1+ ” ” +b2);

正确答案: A

true false
 false true
 true true
 false falseString a = “a”;
 String b = “a”;


这样定义的a和b指向的是字符串常量区变量,地址是一样的,即用equals为true,用==也为true。

但是

String a =new String( “a”);
 String b = new String( “a”);


这样是定义了两个堆内存对象,只能equals,不能==
String类重写了equals方法,比较两个new对象的值是否相同,如果值相同则返回true。

2.下列关于异常处理的描述中,错误的是()。

正确答案: D
程序运行时异常由Java虚拟机自动进行处理
使用try-catch-finally语句捕获异常
可使用throw语句抛出异常
捕获到的异常只能在当前方法中处理,不能在其他方法中处理

编译时异常必须显示处理,运行时异常交给虚拟机。
运行时异常可以不处理。当出现这样的异常时,总是由虚拟机接管。比如我们从来没有人去处理过Null Pointer Exception异常,它就是运行时异常,并且这种异常还是最常见的异常之一。出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往不对它处理罢了。也就是说,如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。

3.下面有关JVM内存,说法错误的是?
正确答案: C
程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的

虚拟机栈描述的是Java方法执行的内存模型,用于存储局部变量,操作数栈,动态链接,方法出口等信息,是线程隔离的

方法区用于存储JVM加载的类信息、常量、静态变量、以及编译器编译后的代码等数据,是线程隔离的

原则上讲,所有的对象都在堆区上分配内存,是线程之间共享的

大多数 JVM 将内存区域划分为 Method Area(Non-Heap)(方法区) ,Heap(堆) , Program Counter
Register(程序计数器) , VM Stack(虚拟机栈,也有翻译成JAVA 方法栈的),Native Method Stack
( 本地方法栈 ),其中Method Area 和 Heap 是线程共享的 ,VM Stack,Native Method Stack
和Program Counter Register 是非线程共享的。为什么分为 线程共享和非线程共享的呢?请继续往下看。

首先我们熟悉一下一个一般性的 Java 程序的工作过程。一个 Java 源程序文件,会被编译为字节码文件(以 class
为扩展名),每个java程序都需要运行在自己的JVM上,然后告知 JVM 程序的运行入口,再被 JVM
通过字节码解释器加载运行。那么程序开始运行后,都是如何涉及到各内存区域的呢?

概括地说来,JVM初始运行的时候都会分配好 Method Area(方法区) 和Heap(堆) ,而JVM 每遇到一个线程,就为其分配一个
Program Counter Register(程序计数器) , VM Stack(虚拟机栈)和Native Method Stack
(本地方法栈),
当线程终止时,三者(虚拟机栈,本地方法栈和程序计数器)所占用的内存空间也会被释放掉。这也是为什么我把内存区域分为线程共享和非线程共享的原因,非线程共享的那三个区域的生命周期与所属线程相同,而线程共享的区域与JAVA程序运行的生命周期相同,所以这也是系统垃圾回收的场所只发生在线程共享的区域(实际上对大部分虚拟机来说知发生在Heap上)的原因。

4.假设 a 是一个由线程 1 和线程 2 共享的初始值为 0 的全局变量,则线程 1 和线程 2 同时执行下面的代码,最终 a 的结果不可能是()

boolean isOdd = false;
for(int i=1;i<=2;++i){
    if(i%2==1)isOdd = true;
    else isOdd = false;
    a+=i*(isOdd?1:-1);
}

正确答案: D 你的答案: C (错误)
-1
-2
0
1

不管怎样线程对a的操作就是+1后-2
1.线程1执行完再线程2执行,1-2+1-2=-2
2.线程1和2同时+1,再-2不同时,1-2-2=-3
3.线程1和2不同时+1,同时-2,1+1-2=0
4.线程1和2既同时+1又同时-2,1-2=-1
没有结果为1的情况

5.以下哪些方法是Object类中的方法
正确答案: A B C D

clone()
 toString()
 wait()
 finalize()registerNatives() //私有方法
 getClass() //返回此 Object 的运行类。
 hashCode() //用于获取对象的哈希值。
 equals(Object obj) //用于确认两个对象是否“相同”。
 clone() //创建并返回此对象的一个副本。
 toString() //返回该对象的字符串表示。
 notify() //唤醒在此对象监视器上等待的单个线程。
 notifyAll() //唤醒在此对象监视器上等待的所有线程。
 wait(long timeout) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或 者超过指定的时间量前,导致当前线程等待。
 wait(long timeout, int nanos) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
 wait() //用于让当前线程失去操作权限,当前线程进入等待序列
 finalize() //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

第三套

1.Java 的屏幕坐标是以像素为单位,容器的左下角被确定为坐标的起点。
正确答案: B
正确
错误

以屏幕左上角为坐标的起点

2.在创建派生类对象,构造函数的执行顺序()
正确答案: A
基类构造函数,派生类对象成员构造函数,派生类本身的构造函数
派生类本身的构造函数,基类构造函数,对象成员构造函数
基类构造函数,派生类本身的构造函数,派生类对象成员构造函数
对象成员构造函数,基类构造函数,派生类本身的构造函数

类的初始化过程也就是方法执行的过程。
父类的静态域-子类的静态域 父类的非静态域-父类的构造函数 子类的非静态域-子类的构造函数 规律就是 父类先于子类 静态的先于非静态的
其中静态域包含静态代码块与静态方法,这个谁在前面,则先执行谁。
非静态域同理

父类静态域——》子类静态域——》父类成员初始化——》父类构造块——》1父类构造方法——》2子类成员初始化——》子类构造块——》3子类构造方法;