第一周

JVM

1

假如某个JAVA进程的JVM参数配置如下:
-Xms1G -Xmx2G -Xmn500M -XX:MaxPermSize=64M -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=3,
请问eden区最终分配的大小是多少?

  • A:64M
  • B:500M
  • C:300M
  • D:100M
查看答案 答案:C

解析:

-Xms1G -Xmx2G -Xmn500M -XX:MaxPermSize=64M -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=3,

-Xms1G 设置Java堆最小值为1G

-Xmx2G 设置Java堆最大值为2G

-Xmn500M 设置新生代大小为500M(一个Eden区,两个Survivor区)

-XX:MaxPermSize=64M 设置永久代大小为64M

-XX:+UseConcMarkSweepGC 设置使用CMS收集器

-XX:SurvivorRatio=3 设置Eden区与Survivor区大小的比例

本题看新生代大小,新生代为500M,三个区比例为3:1:1,很容易计算出Eden大小为300M

2

对于JVM内存配置参数:

-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3

,其最小内存值和Survivor区总大小分别是()

  • A:5120m,1024m
  • B:5120m,2048m
  • C:10240m,1024m
  • D:10240m,2048m

解析:

查看答案 答案:D

-Xmx:最大堆大小

-Xms:初始堆大小

-Xmn:年轻代大小

-XXSurvivorRatio:年轻代中Eden区与Survivor区的大小比值

年轻代5120m, Eden:Survivor=3,Survivor区大小=1024m(Survivor区有两个,即将年轻代分为5份,每个Survivor区占一份),总大小为2048m。

-Xms初始堆大小即最小内存值为10240m

3

(多选)关于OutOfMemoryError,下面说法正确的是()?

  • java.lang.OutOfMemoryError: PermGen space 增加-XX:MaxPermSize这个参数的值的话,这个问题通常会得到解决。
  • java.lang.OutOfMemoryError: Requested array size exceeds VM limit当你正准备创建一个超过虚拟机允许的大小的数组时,这条错误将会出现
  • java.lang.OutOfMemoryError: Java heap space 一般情况下解决这个问题最快的方法就是通过-Xmx参数来增加堆的大小
  • java.lang.OutOfMemoryError: nativeGetNewTLA这个异常只有在jRockit虚拟机时才会碰到
查看答案 答案:ABC

解析:

A:属于运行时常量池导致的溢出,设置-XX:MaxPermSize可以解决这个问题,

B:属于堆空间不足导致的错误,解决方式和C相同,

C:属于java堆内存问题,一般的手段是通过内存映像分析工具,对Dump出来的堆转储存快照进行分析,重点是确认内存中的对象是否是有必要的,也就是要判断是出现了内存泄漏,还是出现了内存溢出。如果是内存泄露,通过工具检查泄露对象打GC Roots的引用链信息,可以准确的确定出泄露代码的位置,不存在泄露,就应该检查虚拟机的堆参数,如果可以继续调大,可以设置-Xmx解决问题

D:java.lang.OutOfMemoryError: nativeGetNewTLA指当虚拟机不能分配新的线程本地空间(Thread Local Area)的时候错误信息,此错误是线程申请一个新的TLA时产生的,这个异常一般只会发生在jRockit虚拟机,只有过于绝对。

4

下面有关java classloader说法错误的是()?

  • A: Java默认提供的三个ClassLoader是BootStrap ClassLoader,Extension ClassLoader,App ClassLoader、
  • B:ClassLoader使用的是双亲委托模型来搜索类的
  • C:VM在判定两个class是否相同时,只用判断类名相同即可,和类加载器无关
  • D:ClassLoader就是用来动态加载class文件到内存当中用的
查看答案 答案:C

解析:

比较两个类是否相等,只有这两个类是由同一个类加载器加载才有意义。否则,即使这两个类是来源于同一个Class文件,只要加载它们的类加载器不同,那么这两个类必定不相等。

补充:

1. 什么是类加载器?

把类加载的过程放到Java虚拟机外部去实现,让应用程序决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。

2. 有哪些类加载器,分别加载哪些类

类加载器按照层次,从顶层到底层,分为以下三种:
(1)启动类加载器 : 它用来加载 Java 的核心库,比如String、System这些类
(2)扩展类加载器 : 它用来加载 Java 的扩展库。

(3) 应用程序类加载器 : 负责加载用户类路径上所指定的类库,一般来说,Java 应用的类都是由它来完成加载的。

3. 双亲委派模型

我们应用程序都是由以上三种类加载器互相配合进行加载的,还可以加入自己定义的类加载器。称为 类加载器的双亲委派模型 ,这里类加载器之间的父子关系一般不会以继承的关系来实现,而是都使用 组合关系 来复用父加载器的。

4. 双亲委托模型的工作原理

是当一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法加载这个加载请求的时候,子加载器才会尝试自己去加载。

5. 使用双亲委派模型好处?(原因)

第一:可以避免重复加载,当父亲已经加载了该类的时候,子类不需要再次加载。

第二:考虑到安全因素,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的类装载器。

5

(多选)关于Java中的ClassLoader下面的哪些描述是错误的:( )

  • A:默认情况下,Java应用启动过程涉及三个ClassLoader: Boostrap, Extension, System
  • B:一般的情况不同ClassLoader装载的类是不相同的,但接口类例外,对于同一接口所有类装载器装载所获得的类是相同的
  • C:类装载器需要保证类装载过程的线程安全
  • D:ClassLoader的loadClass在装载一个类时,如果该类不存在它将返回null
  • E:ClassLoader的父子结构中,默认装载采用了父优先
  • F:所有ClassLoader装载的类都来自CLASSPATH环境指定的路径
查看答案 答案:BDF

解析:

A.Java系统提供3种类加载器:启动类加载器(Bootstrap ClassLoader) 扩展类加载器(Extension ClassLoader) 应用程序类加载器(Application ClassLoader). A正确

B.《深入理解Java虚拟机》P228:对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间。这句话可以表达得更通俗一些:比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个类必定不相等。接口类是一种特殊类,因此对于同一接口不同的类装载器装载所获得的类是不相同的。B错误

C.类只需加载一次就行,因此要保证类加载过程线程安全,防止类加载多次。C正确

D. Java程序的类加载器采用双亲委派模型,实现双亲委派的代码集中在java.lang.ClassLoader的loadClass()方法中,此方法实现的大致逻辑是:先检查是否已经被加载,若没有加载则调用父类加载器的loadClass()方法,若父类加载器为空则默认使用启动类加载器作为父类加载器。如果父类加载失败,抛出ClassNotFoundException异常。D错误

E.双亲委派模型的工作过程:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。E正确

F.应用程序类加载器(Application ClassLoader)负责加载用户类路径(ClassPath)上所指定的类库,不是所有的ClassLoader都加载此路径。F错误

6

以下代码执行的结果显示是多少()?

  • A:505000
  • B:0
  • C:运行时错误
  • D:5050
查看答案 答案:B

解析:

count = count++ 原理是 temp = count; count = count+1 ; count = temp; 因此count始终是0 这仅限于java 与c是不一样的

count=count++就是先把局部变量表中count的值0放入操作数栈中,然后直接对局部变量表中的count加1,然后再把操作数栈中的0出栈赋值给局部变量表中的count,最终局部变量表中的count值仍为0

基础

7

在java中,下列对继承的说法,正确的是( )

  • A:子类能继承父类的所有成员
  • B:子类继承父类的非私有方法和状态
  • C:子类只能继承父类的public方法和状态
  • D:子类只能继承父类的方法
查看答案 答案:A

解析:

使用反射可以看出子类是继承了父类的私有方法的(不管是否是final),只是直接调用父类的私有方法是不可以的,但是利用反射的方式可以调用。字段同理。

其实private方法是可以继承的,只是不能调用

8

有如下一段程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test{
private static int i=1;
public int getNext(){
return i++;
}
public static void main(String [] args){
Test test=new Test();
Test testObject=new Test();
test.getNext();
testObject.getNext();
System.out.println(testObject.getNext());
}
}

请问最后打印出来的是什么?()

  • A:2
  • B:3
  • C:4
  • D:5
查看答案 答案:B

解析:

return i++, 先返回i,然后i+1;

第一次调用getNext()方法时,返回的是1,但此时i=2;

第二次调用 getNext()方法时,返回的是2,但此时i=3;

第三次调用 getNext()方法时,返回的是3,但此时i=4;

9

(多选)下面的switch语句中,x可以是哪些类型的数据:()

1
2
3
4
5
switch(x)
{
default:
System.out.println("Hello");
}
  • A:long
  • B:char
  • C:float
  • D:byte
  • E:double
  • F:Object
查看答案 答案:BD

解析:

jdk1.7之前byte,short ,int ,char

jdk1.7之后加入String

10

输出结果为:

1
2
String str ="";
System.out.print(str.split(",").length);
  • A:0
  • B:1
  • C:出现异常
查看答案 答案:B

解析:

String split() 这个方法默认返回一个数组,如果没有找到分隔符,会把整个字符串当成一个长度为1的字符串数组,返回到结果, 所以此处结果就是1 。

11

以下程序执行的结果是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class X{
Y y=new Y();
public X(){
System.out.print("X");
}
}
class Y{
public Y(){
System.out.print("Y");
}
}
public class Z extends X{
Y y=new Y();
public Z(){
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
  • A:ZYXX
  • B:ZYXY
  • C:YXYZ
  • D:XYZX
查看答案 答案:C

解析:

java对象初始化顺序
先说结论:

  1. 父类静态代码块,父类静态成员变量(同级,按代码顺序执行)
  2. 子类静态代码块,子类静态成员变量(同级,按代码顺序执行)
  3. 父类普通代码块,父类普通成员变量(同级,按代码顺序执行)
  4. 父类构造方法
  5. 子类普通代码块,子类普通成员变量(同级,按代码顺序执行)
  6. 子类构造方法

注意点:

  1. 静态内容只在类加载时执行一次,之后不再执行。
  2. 默认调用父类的无参构造方法,可以在子类构造方法中利用super指定调用父类的哪个构造方法。

(1)初始化父类的普通成员变量和代码块,执行 Y y=new Y(); 输出Y

(2)再执行父类的构造方法;输出X

(3) 初始化子类的普通成员变量和代码块,执行 Y y=new Y(); 输出Y

(4)再执行子类的构造方法;输出Z

12

设三个整型变量 x = 1 , y = 2 , z = 3,则表达式 y+=z--/++x 的值是( )。

  • A:3
  • B:3.5
  • C:4
  • D:5
查看答案 答案:A

解析:

y是2,返回的结果是2+(z–/++x),再来看z–/++x,结果应该是3/2,但是因为x,y,z都是int型的,所以最后的返回值只能是int,这时候z–/++x的值就是1,那么最终的结果就是2+1=3

13

instanceof运算符能够用来判断一个对象是否为:

  • A:一个类的实例
  • B:一个实现指定接口的类的实例
  • C:全部正确
  • D:一个子类的实例
查看答案 答案:C

解析:

instance是java的二元运算符,用来判断他左边的对象是否为右面类(接口,抽象类,父类)的实例

14

以下代码将打印出

1
2
3
4
 public static void main (String[] args) { 
String classFile = "com.jd.". replaceAll(".", "/") + "MyClass.class";
System.out.println(classFile);
}
  • A:com. jd
  • B:com/jd/MyClass.class
  • C:///////MyClass.class
  • D:com.jd.MyClass
查看答案 答案:C

解析:

由于replaceAll方法的第一个参数是一个正则表达式,而”.”在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成”/“。如果想替换的只是”.”,那么久要写成”\.”.

1
2
3
4
5
byte b1=1,b2=2,b3,b6; 
final byte b4=4,b5=6;
b6=b4+b5;
b3=(b1+b2);
System.out.println(b3+b6);

15

关于上面代码片段叙述正确的是()

  • A:输出结果:13
  • B:语句:b6=b4+b5编译出错
  • C:语句:b3=b1+b2编译出错
  • D:运行期抛出异常
查看答案 答案:C

解析:

被final修饰的变量是常量,这里的b6=b4+b5可以看成是b6=10;在编译时就已经变为b6=10了

而b1和b2是byte类型,java中进行计算时候将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,编译不会通过,需要进行强制转换。

Java中的byte,short,char进行计算时都会提升为int类型。

16

下面有关java基本类型的默认值和取值范围,说法错误的是?

  • A:字节型的类型默认值是0,取值范围是-2^7—2^7-1
  • B:boolean类型默认值是false,取值范围是true\false
  • C:字符型类型默认是0,取值范围是-2^15 —2^15-1
  • D:long类型默认是0,取值范围是-2^63—2^63-1
查看答案 答案:C

解析:

More Actions 默认值 存储需求(字节) 取值范围 示例
byte 0 1 -2^7—2^7-1 byte b=10;
char ‘ \u0000′ 2 0—2^16-1 char c=’c’ ;
short 0 2 -2^15—2^15-1 short s=10;
int 0 4 -2^31—2^31-1 int i=10;
long 0 8 -2^63—2^63-1 long o=10L;
float 0.0f 4 -2^31—2^31-1 float f=10.0F
double 0.0d 8 -2^63—2^63-1 double d=10.0;
boolean false 1 true\false boolean flag=true;

17

java有8种基本类型,请问byte、int、long、char、float、double、boolean各占多少个字节?

  • A:1 2 8 2 4 8 1
  • B:1 4 8 2 4 8 1
  • C:1 4 4 2 4 4 2
  • D:1 4 4 2 4 8 2
查看答案 答案:B

18

对于abstract声明的类,下面说法正确的是

  • A:可以实例化
  • B:不可以被继承
  • C:子类为abstract
  • D:只能被继承
  • E:可以被抽象类继承
查看答案 答案:E

解析:

A:抽象类不能实例化,因为有抽象方法未实现

B:可以被继承。派生类可以实现抽象方法

C:子类可以是抽象的,也可以非抽象的

D:只能被继承说法太肯定,不正确

E:可以被抽象类继承,也可以被非抽象类继承

19

(多选)final、finally和finalize的区别中,下述说法正确的有?

  • A:final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
  • B:finally是异常处理语句结构的一部分,表示总是执行。
  • C:finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源的回收,例如关闭文件等。
  • D:引用变量被final修饰之后,不能再指向其他对象,它指向的对象的内容也是不可变的。
查看答案 答案:AB

解析:

A,D考的一个知识点,final修饰变量,变量的引用(也就是指向的地址)不可变,但是引用的内容可以变(地址中的内容可变)。

B,finally表示总是执行。但是其实finally也有不执行的时候,但是这个题不要扣字眼。

  1. 在try中调用System.exit(0),强制退出了程序,finally块不执行。

  2. 在进入try块前,出现了异常,finally块不执行。

C,finalize方法,这个选项错就错在,这个方法一个对象只能执行一次,只能在第一次进入被回收的队列,而且对象所属于的类重写了finalize方法才会被执行。第二次进入回收队列的时候,不会再执行其finalize方法,而是直接被二次标记,在下一次GC的时候被GC。

20

(多选)以下关于final关键字说法错误的是()

  • A:final是java中的修饰符,可以修饰类、接口、抽象类、方法和属性
  • B:final修饰的类肯定不能被继承
  • C:final修饰的方法不能被重载
  • D:final修饰的变量不允许被再次赋值
查看答案 答案:AC

解析:

1.final修饰变量,则等同于常量

2.final修饰方法中的参数,称为最终参数。

3.final修饰类,则类不能被继承

4.final修饰方法,则方法不能被重写。

5.final 不能修饰抽象类

6.final修饰的方法可以被重载 但不能被重写

21

(多选)下面属于java包装类的是?

  • A:String
  • B:Long
  • C:Character
  • D:Short
查看答案 答案:BCD

解析:

包装类是针对 基本数据类型 的。

基本数据类型 包装类
byte Byte
boolean Boolean
short Short
char Character
int Integer
long Long
float Float
double Double

22

(多选)在java中重写方法应遵循规则的包括()

  • A:访问修饰符的限制一定要大于被重写方法的访问修饰符
  • B:可以有不同的访问修饰符
  • C:参数列表必须完全与被重写的方法相同
  • D:必须具有不同的参数列表
查看答案 答案:BC

解析:

A:错在访问修饰符还可以相等。

方法重写的规则:


  • ​ 1)参数列表必须完全与被重写方法的相同;
  • ​ 2)返回类型必须完全与被重写方法的返回类型相同;(备注:这条信息是标准的重写方法的规则,但是在java1.5 版本之前返回类型必须一样,1.5(包含) 版本之后java放宽了限制,返回类型必须小于或者等于父类方法的返回类型 才有了子类返回类型小于等于父类方法返回类型。
  • ​ 3)访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  • ​ 4)父类的成员方法只能被它的子类重写。
  • ​ 5)声明为final的方法不能被重写。
  • ​ 6)声明为static的方法不能被重写,但是能够被再次声明。
  • ​ 7)子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
  • ​ 8)子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
  • ​ 9)重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • ​ 10)构造方法不能被重写。
  • ​ 11)如果不能继承一个方法,则不能重写这个方法。

23

以下代码段执行后的输出结果为()

1
2
3
4
5
6
7
public class Test {
public static void main(String args[]) {
int x = -5;
int y = -12;
System.out.println(y % x);
}
}
  • A:-1
  • B:2
  • C:1
  • D:-2
查看答案 答案:D

解析:

取模运算,结果的符号和被除数符号一致,切记切记

24

(多选)以下关于final关键字说法错误的是

  • A:final是java中的修饰符,可以修饰类、接口、抽象类、方法和属性
  • B:final修饰的类肯定不能被继承
  • C:final修饰的方法不能被重载
  • D:final修饰的变量不允许被再次赋值
查看答案 答案:AC

解析:

  • final修饰类、方法、属性!不能修饰抽象类,因为抽象类一般都是需要被继承的,final修饰后就不能继承了。

  • final修饰的方法不能被重写而不是重载!

  • final修饰属性,此属性就是一个常量,不能被再次赋值!

  • final也不能修饰接口,接口可以只能被public&abstract修饰

  • final如果修饰的是基本类型的变量,那么这个变量就表示为一个常数,只能赋值一次,要么在定义时赋值,要么在初始化时赋值;final修饰应用类型的变量是,变量不能再次被赋值意思是变量的地址(引用)不可以被改变,当变量所指向的内容可以被改变。

25

静态内部类不可以直接访问外围类的非静态数据,而非静态内部类可以直接访问外围类的数据,包括私有数据。( )

  • A:正确
  • B:错误
查看答案 答案:A

解析:

  1. 静态内部类:

    1. 静态内部类本身可以访问外部的静态资源,包括静态私有资源。但是不能访问非静态资源,可以不依赖外部类实例而实例化。
  2. 成员内部类:

    1. 成员内部类本身可以访问外部的所有资源,但是自身不能定义静态资源,因为其实例化本身就还依赖着外部类。
  3. 局部内部类:

    1. 局部内部类就像一个局部方法,不能被访问修饰符修饰,也不能被static修饰。
    2. 局部内部类只能访问所在代码块或者方法中被定义为final的局部变量。
  4. 匿名内部类:

    1. 没有类名的内部类,不能使用class,extends和implements,没有构造方法。

    ​ 2. 多用于GUI中的事件处理。

    ​ 3. 不能定义静态资源

    ​ 4. 只能创建一个匿名内部类实例。

    ​ 5. 一个匿名内部类一定是在new后面的,这个匿名类必须继承一个父类或者实现一个接口。

    ​ 6. 匿名内部类是局部内部类的特殊形式,所以局部内部类的所有限制对匿名内部类也有效。

26

有如下4条语句:()

1
2
3
4
Integer i01=59;
int i02=59;
Integer i03=Integer.valueOf(59);
Integer i04=new Integer(59);

以下输出结果为false的是:

  • System.out.println(i01==i02);
  • System.out.println(i01==i03);
  • System.out.println(i03==i04);
  • System.out.println(i02==i04);
查看答案 答案:D

解析:

  • 无论如何,Integer与new Integer不会相等。不会经历拆箱过程,
  • 两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false;java在编译Integer i2 = 128的时候,被翻译成-> Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存

Integer.valueOf方法中也有判断,如果传递的整型变量>= -128并且小于127时会返回IntegerCache类中一个静态数组中的某一个对象, 否则会返回一个新的Integer对象,代码如下

1
2
3
4
5
6
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.[i + (-IntegerCache.low)];
return new Integer(i);
}
  • 两个都是new出来的,都为false
  • int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比

27

定义有StringBuffer s1=new StringBuffer(10);s1.append(“1234”)则s1.length()和s1.capacity()分别是多少?

  • A:4 10
  • B:4 4
  • C:10 10
  • D:10 4
查看答案 答案:A

解析:

StringBuffer s = new StringBuffer(x); x为初始化容量长度

s.append(“Y”); “Y”表示长度为y的字符串

length始终返回当前长度即y;

对于s.capacity():

1.当y<x时,值为x

以下情况,容器容量需要扩展

2.当x<y<2x+2时,值为 2x+2

3.当y>2x+2时,值为y

28

(多选)有关静态初始化块说法正确的是?

  • A:无法直接调用静态初始化块
  • B:在创建第一个实例前或引用任何静态成员之前,将自动调用静态初始化块来初始化
  • C:静态初始化块既没有访问修饰符,也没有参数
  • D:在程序中,用户可以控制合适执行静态初始化块
查看答案 答案:ABC

解析:

java对象初始化顺序
先说结论:

  1. 父类静态代码块,父类静态成员变量(同级,按代码顺序执行)
  2. 子类静态代码块,子类静态成员变量(同级,按代码顺序执行)
  3. 父类普通代码块,父类普通成员变量(同级,按代码顺序执行)
  4. 父类构造方法
  5. 子类普通代码块,子类普通成员变量(同级,按代码顺序执行)
  6. 子类构造方法

注意点:

  1. 静态内容只在类加载时执行一次,之后不再执行。
  2. 默认调用父类的无参构造方法,可以在子类构造方法中利用super指定调用父类的哪个构造方法。

29

执行如下程序代码

char chr = 127;

int sum = 200;

chr += 1;

sum += chr;

后,sum的值是 ; ( )

备注:同时考虑c/c++和Java的情况的话

  • A:72
  • B:99
  • C:328
  • D:327
查看答案 答案:D

解析:

java中只有byte, boolean是一个字节, char是两个字节, 所以对于java来说127不会发生溢出, 输出328

但是对于c/c++语言来说, char是一个字节, 会发生溢出, 对127加一发生溢出, 0111 1111 –> 1000 0000, 1000 0000为补码-128, 所以结果为200-128=72

30

下列关于包(package)的描述,正确的是()

  • A:包(package)是Java中描述操作系统对多个源代码文件组织的一种方式。
  • B:import语句将所对应的Java源文件拷贝到此处执行。
  • C:包(package)是Eclipse组织Java项目特有的一种方式。
  • D:定义在同一个包(package)内的类可以不经过import而直接相互使用。
查看答案 答案:D

解析:

1、为了更好地组织类,Java提供了包机制。包是类的容器,用于分隔类名空间。如果没有指定包名,所有的示例都属于一个默认的无名包。Java中的包一般均包含相关的类,java是跨平台的,所以java中的包和操作系统没有任何关系,java的包是用来组织文件的一种虚拟文件系统。A错

2、import语句并没有将对应的java源文件拷贝到此处仅仅是引入,告诉编译器有使用外部文件,编译的时候要去读取这个外部文件。B错
3、Java提供的包机制与IDE没有关系。C错
4、定义在同一个包(package)内的类可以不经过import而直接相互使用。

31

(多选)哪个是不正确的字符常量?

  • A:”\n”
  • B:”1”
  • C:”a”
  • D:”\101”
查看答案 答案:ABCD

解析:文字游戏注意是字符常量(’’)而不是字符串常量(””)

32

(多选)以下关于JAVA语言异常处理描述正确的有?

  • A:throw关键字可以在方法上声明该方法要抛出的异常。
  • B:throws用于抛出异常对象。
  • C:try是用于检测被包住的语句块是否出现异常,如果有异常,则抛出异常,并执行catch语句。
  • D:finally语句块是不管有没有出现异常都要执行的内容。
    在try块中不可以抛出异常
查看答案 答案:CD

解析:

Java语言中的异常处理包括声明异常、抛出异常、捕获异常和处理异常四个环节。

  • throws关键字可以在方法上声明该方法要抛出的异常,然后在方法内部通过throw抛出异常对象。A选项应该为throws B选项应该为throw

  • C选项不严谨,这个异常不是用try抛出来的,而是用了try能检测到底层抛出的异常,然后进行处理。这里应该用“捕获”这个异常才对。

    这个“如果有异常,则抛出异常”。在捕获异常的时候使用throw,才会抛出这个异常,否则只是捕获到,而不是抛出。这个是需要显式写出来的。

    但是答案中存在,忽略这个细节。AB错误太明显。

33

下列语句正确的是:

  • A:形式参数可被字段修饰符修饰
  • B:形式参数不可以是对象
  • C:形式参数为方法被调用时真正被传递的参数
  • D:形式参数可被视为local variable
查看答案 答案:D

解析:

34

关于C++/JAVA类中static 成员和对象成员的说法正确的是?

  • A:static 成员变量在对象构造时生成
  • B:static 成员函数在对象成员函数中无法调用
  • C:虚成员函数不可能是static 成员函数
  • D:static 成员函数不能访问static 成员变量
查看答案 答案:C

解析:

  • static为成员变量或函数,在类初始化是加载完成,可以被成员函数调用或访问
  • static成员函数既可以通过类名直接调用,也可以通过对象名进行调用
  • 虚函数是C++中的,虚函数不可能是static的
  • static成员函数可以访问static成员变量

35

给定以下JAVA代码,这段代码运行后输出的结果是()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Test
{
public static int aMethod(int i)throws Exception
{
try{
return i / 10;
}
catch (Exception ex)
{
throw new Exception("exception in a Method");
} finally{
System.out.printf("finally");
}
}

public static void main(String [] args)
{
try
{
aMethod(0);
}
catch (Exception ex)
{
System.out.printf("exception in main");
}
System.out.printf("finished");
}
}
  • A:exception in main finished
  • B:finally finished
  • C:exception in main finally
  • D:finally exception in main finished
查看答案 答案:B

解析:

题目中是i/10 不是 10/i 绝对不会报异常

1、finally块一定会执行,无论是否try…catch。

2、finally前有return,会先执行return语句,并保存下来,再执行finally块,最后return。

3、finally前有return、finally块中也有return,先执行前面的return,保存下来,再执行finally的return,覆盖之前的结果,并返回。

36

What is the result?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Test
{
static boolean foo(char c)
{
System.out.print(c);
return true;
}
public static void main( String[] argv )
{
int i = 0;
for ( foo('A'); foo('B') && (i < 2); foo('C'))
{
i++ ;
foo('D');
}
}
}
  • A:ABDCBDCB
  • B:ABCDABCD
  • C:Compilation fails.
  • D:An exception is thrown at runtime.
查看答案 答案:A

解析:

for(条件1;条件2;条件3) {

​ //语句

}

执行顺序是条件1->条件2->语句->条件3->条件2->语句->条件3->条件2……..

如果条件2为true,则一直执行。如果条件2位false,则for循环结束21.

37

Which lines of the following will produce an error?

1
2
3
4
1. byte a1 = 2, a2 = 4, a3;
2. short s = 16;
3. a2 = s;
4. a3 = a1 * a2;
  • A:Line 3 and Line 4
  • B:Line 1 only
  • C:Line 3 only
  • D:Line 4 only
查看答案 答案:A

解析:

short类型转为byte类型出错

a1*a2结果为int类型,转为byte类型出错

java中如果碰到char、byte和short参与运算时,会自动将这些值转换为int类型然后再进行运算。这里a1和a2就自动转为int类型了,结果也为Int类型。把一个int类型赋值给byte需要转型。

38

What is displayed when the following is executed;

1
2
3
double d1=-0.5;
System.out.println("Ceil d1="+Math.ceil(d1));
System.out.println("floor d1="+Math.floor(d1));
  • A:Ceil d1=-0.0
    floor d1=-1.0
  • B:Ceil d1=0.0
    floor d1=-1.0
  • C:Ceil d1=-0.0
    floor d1=-0.0
  • D:Ceil d1=0.0
    floor d1=0.0
  • E:Ceil d1=0
    floor d1=-1
查看答案 答案:A

解析:

ceil:天花板数,向上取整。

floor:地板数,向下取整

这里主要是有一点:

1
`Math.ceil(d1) `

ceil 方法上有这么一段注释:If the argument value is less than zero but greater than -1.0, then the result is negative zero

如果参数小于0且大于-1.0,结果为 -0

1
`Math.floor(d1)`

ceil 和 floor 方法 上都有一句话:If the argument is NaN or an infinity or positive zero or negative zero, then the result is the same as the argument,意思为:如果参数是 NaN、无穷、正 0、负 0,那么结果与参数相同,

如果是 -0.0,那么其结果是 -0.0

39

java中将ISO8859-1字符串转成GB2312编码,语句为 ?

  • A:new String(“ISO8859-1”.getBytes(“ISO8859-1”),”GB2312”)
  • B:new String(String.getBytes(“GB2312”), ISO8859-1)
  • C:new String(String.getBytes(“ISO8859-1”))
  • D:new String(String.getBytes(“GB2312”))
查看答案 答案:A

解析:

注意这里”ISO8859-1”是一个普通字符串,不要被迷惑了

new String(“这是要转换的字符串”.getBytes(“ISO-8859-1”), “GB2312”);

40

(多选)已知String a=”a”,String b=”b”,String c=a+b,String d=new String(“ab”) 以下操作结果为true的是

  • A:(a+b).equals(c)
  • B:a+b==c
  • C:c==d
  • D:c.equals(d)
查看答案 答案:AD

解析:

1.== 和 equals():

(1)“==” 用于比较基本数据类型时比较的是值,用于比较引用类型时比较的是引用指向的地址。

(2)Object 中的equals() 与 “==” 的作用相同,但String类重写了equals()方法,比较的是对象中的内容。

2.String对象的两种创建方式:

(1)第一种方式: String str1 = “aaa”; 是在常量池中获取对象(“aaa” 属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象,如果常量池中已经存在该字符串对象则直接引用)

1
System.out.println(str1==str2);//false

3.String类型的常量池比较特殊。它的主要使用方法有两种

(1)直接使用双引号声明出来的String对象会直接存储在常量池中。

(2)如果不是用双引号声明的String对象,可以使用 String 提供的 intern 方法。 String.intern() 是一个 Native 方法,它的作用是: 如果运行时常量池中已经包含一个等于此 String 对象内容的字符串,则返回常量池中该字符串的引用; 如果没有,则在常量池中创建与此 String 内容相同的字符串,并返回常量池中创建的字符串的引用。

1
2
3
4
5
6
String s1 = new String("AAA");
String s2 = s1.intern();
String s3 = "AAA";
System.out.println(s2);//AAA
System.out.println(s1 == s2);//false,因为一个是堆内存中的String对象一个是常量池中的String对象,
System.out.println(s2 == s3);//true, s1,s2指向常量池中的”AAA“

4字符串拼接:

1
2
3
4
5
6
7
8
9
String a = "a";
String b = "b";

String str1 = "a" + "b";//常量池中的对象
String str2 = a + b; //在堆上创建的新的对象
String str3 = "ab";//常量池中的对象
System.out.println(str1 == str2);//false
System.out.println(str1 == str3);//true
System.out.println(str2 == str3);//false

41

对于java类型变量char c,short s,float f,double d,表达式c*s+f+d的结果类型为()

  • A:float
  • B:char
  • C:short
  • D:double
查看答案 答案:D

解析:

基本数据类型的运算,会自动向上转型。boolean不可以和其他基本数据类型相互转换。

byte->short,char -> int -> long

float -> double

int -> float

long -> double

42

在运行时,由java解释器自动引入,而不用import语句引入的包是()。

  • A:java.lang
  • B:java.system
  • C:java.io
  • D:java.util
查看答案 答案:A

解析:

java.lang包是java语言的核心包,lang是language的缩写

java.lang包定义了一些基本的类型,包括Integer,String之类的,是java程序必备的包,有解释器自动引入,无需手动导入

43

由3 个“1”和 5 个“0”组成的 8 位二进制补码,能表示的最小整数()

  • A:-126
  • B:-125
  • C:-32
  • D:-3
查看答案 答案:B

解析:

既然求最小整数,那肯定先想到负数,则最高位(符号位)一定为1,原码中肯定是1所在的位数越高,值越小,而补码是由原码取反加1(符号位不变)得到的,则在补码中1所在的位数一定要越低,即补码为1000 0011;由补码求得原码:1111 1101=-(64+32+16+8+4+1)=-125;

44

关于访问权限,说法正确的是? ( )

  • A:类A和类B在同一包中,类B有个protected的方法testB,类A不是类B的子类(或子类的子类),类A可以访问类B的方法testB
  • B:类A和类B在同一包中,类B有个protected的方法testB,类A不是类B的子类(或子类的子类),类A不可以访问类B的方法testB
  • C:访问权限大小范围:public > 包权限 > protected > private
  • D:访问权限大小范围:public > 包权限 > private > protected
查看答案 答案:A

解析:

45

以下程序程序运行后的输出结果是()

1
2
3
4
5
public static void main(String[] args){
int m=12,n=34;
System.out.printf("%d%d",m++,++n);
System.out.printf("%d%d\n",n++,++m);
}
  • A:12353514
  • B:12353513
  • C:12343514
  • D:12343513
查看答案 答案:A

解析:

不要忘记前面已经自加过后,变量的值已经改变了(明白了这个肯定就没问题了)

​ 第一个输出:m++值:12,m的值:13

​ ++n值:35,n的值:35

​ 第一个输出:n++值:35,n的值:36

​ ++m值:14,n的值:14

​ 故最终输出:12353514

46

在jdk1.8之前,下列哪一种叙述是正确的( )

  • A:abstract修饰符可修饰字段、方法和类
  • B:抽象方法的body部分必须用一对大括号{ }包住
  • C:声明抽象方法,大括号可有可无
  • D:声明抽象方法不可写出大括号
查看答案 答案:D

解析:

A:abstract修饰方法和类

B、C:抽象方法没有方法体,有没有方法体看有没有大括号。

47

以下不是修饰符final的作用的是( )。

  • A:修饰常量
  • B:修饰不可被继承的类
  • C:修饰不可变类
  • D:修饰不可覆盖的方法
查看答案 答案:C

解析:

final的作用:

​ 1. 修饰变量,变量的引用地址不可变,但是地址中的内容可以变。

​ 2. 修饰方法,方法不可被重写,但是还是可以重载

​ 3. 修饰类,类不可继承。

不可变类:说的是一个类一旦被实例化,就不可改变自身的状态。常见的比如String和基本数据类型的包装类,对于这种不可变类,一旦在进行引用传递的时候,形参一开始就和实际参数指向的不是一个地址,所以在方法中对形参的改变,并不会影响实际参数。

计算机基础

48

在一个基于分布式的游戏服务器系统中,不同的服务器之间,哪种通信方式是不可行的()?

  • A:管道
  • B:消息队列
  • C:高速缓存数据库
  • D:套接字
查看答案 答案:A

解析:

管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

既然是不同的服务器之间进行通信,怎么可能会是具有亲缘关系的进程呢?

49

以下哪个式子有可能在某个进制下成立()?

  • A:13 * 14=204
  • B:12 * 34=568
  • C:14*14=140
  • D:1+1=3
查看答案 答案:A

解析:

A: 假设为x进制

13用10进制表示为 1 * x^1 + 3 * x ^ 0 = x + 3

同理 14 :x + 4

204:2x^2 + 4

(x + 3)(x + 4 ) = 2x^2 + 4

解得 x1 = 8 x2 = -1

BCD同理可计算

50

以下JAVA程序代码的输出是

1
2
3
public static void main(String args[]) {
System.out.println(17^5);
}
  • A:12
  • B:22
  • C:20
  • D:1419857
查看答案 答案:C

解析:

位异运算符号。

运算规则是:两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1。

17:0001 0001

5: 0000 0101

结果:0001 0100 转10进制:20

51

变量a是一个64位有符号的整数,初始值用16进制表示为:0x7FFFFFFFFFFFFFFF;变量b是一个64位有符号的整数,初始值用16进制表示为:0x8000000000000000。则a+b的结果用10进制表示为多少?

  • A:1
  • B:-1
  • C:2^63+2^62+…+2^2+2^1+2^0
  • D:–(2^63+2^62+…+2^2+2^1+2^0)
查看答案 答案:B

解析:

0x7FFFFFFFFFFFFFFF + 0x8000000000000000 = 0xFFFFFFFFFFFFFFFF

(1)a+b的16进制表示为:OxFFFFFFFFFFFFFFF(16位F),转为2进制为111……111(64位1,每个F->4位2进制)。

(2)有符号数:是针对二进制来讲的。用最高位作为符号位,“0”代表“+”,“1”代表“-”。所以a+b的结果是一个负数。

(3)计算机中负数是以补码的形式保存的,将补码转换成原码的计算方式如下:

​ ①. 对于正数,原码与补码相同。

​ ②.对于负数:

​ (1)符号位保持不变,按位取反,末位加1,即得到原码。

​ (2)符号位保持不变,先-1,然后其他位按位取反

​ 这两种方法都可以

(4)a + b = 111……111(64位1)

​ 取反:100……000(1位1,后面63位0)

​ 加一:100……00(中间62位0)

​ 结果10进制:-1。

52

存根(Stub)与以下哪种技术有关

  • A:交换
  • B:动态链接
  • C:动态加载
  • D:磁盘调度
查看答案 答案:B

解析:

存根类是一个类,它实现了一个接口,它的作用是:如果一个接口有很多方法,如果要实现这个接口,就要实现所有的方法。但是一个类从业务来说,可能只需要其中一两个方法。如果直接去实现这个接口,除了实现所需的方法,还要实现其他所有的无关方法。而如果通过继承存根类就实现接口,就免去了这种麻烦。
RMI 采用stubs 和 skeletons 来进行远程对象(remote object)的通讯。stub 充当远程对象的客户端,有着和远程对象相同的远程接口,远程对象的调用实际是通过调用该对象的客户端对象stub来完成的。
每个远程对象都包含一个对象stub,当运行在本地Java虚拟机上的程序调用运行在远程Java虚拟机上的对象方法时,它首先在本地创建该对象的对象stub, 然后调用对象上匹配的方法。每一个远程对象同时也包含一个skeleton对象,skeleton运行在远程对象所在的虚拟机上,接受来自stub对象的调用。这种方式符合等到程序要运行时将目标文件动态进行链接的思想

集合

53

(多选)对Collection和Collections描述正确的是

  • A:Collection是java.util下的类,它包含有各种有关集合操作的静态方法
  • B:Collection是java.util下的接口,它是各种集合结构的父接口
  • C:Collections是java.util下的接口,它是各种集合结构的父接口
  • D:Collections是java.util下的类,它包含有各种有关集合操作的静态方法
查看答案 答案:BD

解析:

  • java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

  • java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

54

java8中,下面哪个类用到了解决哈希冲突的开放定址法

  • A:LinkedHashSet
  • B:HashMap
  • C:ThreadLocal
  • D:TreeMap
查看答案 答案:C

解析:

ThreadLocalMap中使用开放地址法来处理散列冲突,而HashMap中使用的是分离链表法。之所以采用不同的方式主要是因为:在ThreadLocalMap中的散列值分散得十分均匀,很少会出现冲突。并且ThreadLocalMap经常需要清除无用的对象,使用纯数组更加方便。

55

列表(List)和集合(Set)下面说法正确的是? ( )

  • A:Set中至多只能有一个空元素
  • B:List中至多只能有一个空元素
  • C:List和Set都可以包含重复元素的有序集合
  • D:List和Set都是有序集合
查看答案 答案:A

解析:

  • Set 不能有重复的元素,且是无序的,要有空值也就只能有一个。因为它不允许重复。 L ist 可以有重复元素,且是有序的,要有空值也可以有多个,因为它可重复。
  • java里面讲的有序无序,指的是你按照顺序存进去数据,然后再按照顺序取出来,两者是一样的。比如List(0)我放的是“a”,那么我list.get(0)取出来也是“a”。并不代表我存了打乱顺序存1到10十个数,它会自己给按照升序或者降序给你排好序。

56

(多选)关于java集合下列说法不正确的有哪些()

  • A:HashSet 它是线程安全的,不允许存储相同的对象
  • B:ConcurrentHashMap 它是线程安全的,其中存储的键对象可以重复,值对象不能重复
  • C:Collection接口是List接口和Set接口的父接口,通常情况下不被直接使用
  • D:ArrayList线程安全的,允许存放重复对象
查看答案 答案:ABD

解析:

注意:常见并非全部

线程安全(Thread-safe)的集合对象:

  • Vector 线程安全:
  • HashTable 线程安全:
  • StringBuffer 线程安全:

非线程安全的集合对象:

  • ArrayList :
  • LinkedList:
  • HashMap:
  • HashSet:
  • TreeMap:
  • TreeSet:
  • StringBulider:

57

list是一个ArrayList的对象,哪个选项的代码填到//todo delete处,可以在Iterator遍历的过程中正确并安全的删除一个list中保存的对象?()

1
2
3
4
5
6
7
8
9
10
11
Iterator it = list.iterator();
int index = 0;
while (it.hasNext())
{
Object obj = it.next();
if (needDelete(obj)) //needDelete返回boolean,决定是否要删除
{
//todo delete
}
index ++;
}
  • A:it.remove();
  • B:list.remove(obj);
  • C:list.remove(index);
  • D:list.remove(obj,index);
查看答案 答案:A

解析:

源码是这么描述的:ArrayList 继承了 AbstractList, 其中AbstractList 中有个modCount 代表了集合修改的次数。在ArrayList的iterator方法中会判断 expectedModCount与 modCount是否相等,如果相等继续执行,不相等报错,只有iterator的remove方在调用自身的remove之后让 expectedModCount与modCount再相等,所以是安全的。

58

(多选)Hashtable 和 HashMap 的区别是:

  • A:Hashtable 是一个哈希表,该类继承了 AbstractMap,实现了 Map 接口
  • B:HashMap 是内部基于哈希表实现,该类继承AbstractMap,实现Map接口
  • C:Hashtable 线程安全的,而 HashMap 是线程不安全的
  • D:Properties 类 继承了 Hashtable 类,而 Hashtable 类则继承Dictionary 类
  • E:HashMap允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
查看答案 答案:BCDE

解析:

Hashtable

(1)Hashtable 是一个散列表,它存储的内容是键值对(key-value)映射。

(2)Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。

(3)HashTable直接使用对象的hashCode。

HashMap:

(1)由数组+链表(jdk1.8以前)组成的,基于哈希表的Map实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。

(2)不是线程安全的,HashMap可以接受为null的键(key)和值(value)。

(3)HashMap重新计算hash值

Hashtable,HashMap,Properties继承关系如下:

1
2
3
4
5
public class Hashtable<K,V> extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
public class Properties extends Hashtable<Object,Object>
1
2
3
4
java.lang.Objecct
java.util.Dictionary<K,V>
java.util.Hashtable<Object,Object>
java.util.Properties

59

(多选)对 Map 的用法,正确的有:

  • A:new java.util.Map().put(“key” , “value”) ;
  • B:new java.util.SortedMap().put(“key” , “value”) ;
  • C:new java.util.HashMap().put( null , null ) ;
  • D:new java.util.TreeMap().put( 0 , null ) ;
查看答案 答案:CD

解析:

选C、D。考察的是Map接口实现类的创建对象以及对象类型包含的方法

A选项Map属于接口类型,不可以new的方式创建对象。所以A错误。

B选项SortedMap属于接口类型,不可以new的方式创建对象。所以B错误。

C选项HashMap基于哈希表实现Map接口的类,并允许null的值和null键

D选项TreeMap通过红黑树实现Map接口的类,key不可以为null,会报NullPointerException异常,value可以为null。

60

(多选)以下哪些继承自 Collection 接口()

  • A:List
  • B:Set
  • C:Map
  • D:Array
查看答案 答案:AB

解析:

├List

​ │├LinkedList

​ │├ArrayList

​ │└Vector

​ │└Stack

└Set

Map

​ ├Hashtable

​ ├HashMap

​ └WeakHashMap

61

(多选)下面哪些类实现或继承了 Collection 接口?

  • A:HashMap
  • B:ArrayList
  • C:Vector
  • D:Iterator
查看答案 答案:BC

解析:

多线程

62

(多选)下列哪些操作会使线程释放锁资源?

  • A:sleep()
  • B:wait()
  • C:join()
  • D:yield()
查看答案 答案:BC

解析:

所谓的释放锁资源实际是通知对象内置的monitor对象进行释放,而只有所有对象都有内置的monitor对象才能实现任何对象的锁资源都可以释放。又因为所有类都继承自Object,所以wait()就成了Object方法,也就是通过wait()来通知对象内置的monitor对象释放,而且事实上因为这涉及对硬件底层的操作,所以wait()方法是native方法,底层是用C写的。

其他都是Thread所有,所以其他3个是没有资格释放资源的

而join()有资格释放资源其实是通过调用wait()来实现的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 代码如下: 
wait()方法
public final native void wait(long timeoutMillis) throws InterruptedException;

// join()方法
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;

if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}

if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

63

(多选)在Java线程状态转换时,下列转换不可能发生的有()?

  • A:初始态->运行态
  • B:就绪态->运行态
  • C:阻塞态->运行态
  • D:运行态->就绪态
查看答案 答案:AC

解析:

64

(多选)Java.Thread的方法resume()负责重新开始被以下哪个方法中断的线程的执行()。

  • A:stop
  • B:sleep
  • C:wait
  • D:suspend
查看答案 答案:D

解析:

resume与suspended一起使用
wait与notify/notifyAll一起使用
sleep会让线程暂时不执行

Thread类的suspend()和resume()方法都已经被声明已废弃了

65

下列程序的运行结果

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String args[]) {
Thread t = new Thread() {
public void run() {
pong();
}
};
t.run();
System.out.print("ping");
}
static void pong() {
System.out.print("pong");
}
  • A:pingpong
  • B:pongping
  • C:pingpong和pongping都有可能
  • D:都不输出
查看答案 答案:B

解析:

这里需要注意Thread的start和run方法

用start方法才能真正启动线程,此时线程会处于就绪状态,一旦得到时间片,则会调用线程的run方法进入运行状态。

而run方法只是普通方法,如果直接调用run方法,程序只会按照顺序执行主线程这一个线程。

IO

66

BufferedReader的父类是以下哪个?

  • A:FilterReader
  • B:InputStreamReader
  • C:PipedReader
  • D:Reader
查看答案 答案:D

解析: