第一套
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子类构造方法;