第一周
JVM
1
假如某个JAVA进程的JVM参数配置如下:
-Xms1G -Xmx2G -Xmn500M -XX:MaxPermSize=64M -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=3,
请问eden区最终分配的大小是多少?
- A:64M
- B:500M
- C:300M
- D:100M
解析:
-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
解析:
-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虚拟机时才会碰到
解析:
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文件到内存当中用的
解析:
比较两个类是否相等,只有这两个类是由同一个类加载器加载才有意义。否则,即使这两个类是来源于同一个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环境指定的路径
解析:
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
解析:
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:子类只能继承父类的方法
解析:
使用反射可以看出子类是继承了父类的私有方法的(不管是否是final),只是直接调用父类的私有方法是不可以的,但是利用反射的方式可以调用。字段同理。
其实private方法是可以继承的,只是不能调用
8
有如下一段程序:
1 | public class Test{ |
请问最后打印出来的是什么?()
- A:2
- B:3
- C:4
- D:5
解析:
return i++, 先返回i,然后i+1;
第一次调用getNext()方法时,返回的是1,但此时i=2;
第二次调用 getNext()方法时,返回的是2,但此时i=3;
第三次调用 getNext()方法时,返回的是3,但此时i=4;
9
(多选)下面的switch语句中,x可以是哪些类型的数据:()
1 | switch(x) |
- A:long
- B:char
- C:float
- D:byte
- E:double
- F:Object
解析:
jdk1.7之前byte,short ,int ,char
jdk1.7之后加入String
10
输出结果为:
1 | String str =""; |
- A:0
- B:1
- C:出现异常
解析:
String split() 这个方法默认返回一个数组,如果没有找到分隔符,会把整个字符串当成一个长度为1的字符串数组,返回到结果, 所以此处结果就是1 。
11
以下程序执行的结果是:
1 | class X{ |
- A:ZYXX
- B:ZYXY
- C:YXYZ
- D:XYZX
解析:
java对象初始化顺序
先说结论:
- 父类静态代码块,父类静态成员变量(同级,按代码顺序执行)
- 子类静态代码块,子类静态成员变量(同级,按代码顺序执行)
- 父类普通代码块,父类普通成员变量(同级,按代码顺序执行)
- 父类构造方法
- 子类普通代码块,子类普通成员变量(同级,按代码顺序执行)
- 子类构造方法
注意点:
- 静态内容只在类加载时执行一次,之后不再执行。
- 默认调用父类的无参构造方法,可以在子类构造方法中利用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
解析:
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:一个子类的实例
解析:
instance是java的二元运算符,用来判断他左边的对象是否为右面类(接口,抽象类,父类)的实例
14
以下代码将打印出
1 | public static void main (String[] args) { |
- A:com. jd
- B:com/jd/MyClass.class
- C:///////MyClass.class
- D:com.jd.MyClass
解析:
由于replaceAll方法的第一个参数是一个正则表达式,而”.”在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成”/“。如果想替换的只是”.”,那么久要写成”\.”.
1 | byte b1=1,b2=2,b3,b6; |
15
关于上面代码片段叙述正确的是()
- A:输出结果:13
- B:语句:b6=b4+b5编译出错
- C:语句:b3=b1+b2编译出错
- D:运行期抛出异常
解析:
被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
解析:
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
18
对于abstract声明的类,下面说法正确的是
- A:可以实例化
- B:不可以被继承
- C:子类为abstract
- D:只能被继承
- E:可以被抽象类继承
解析:
A:抽象类不能实例化,因为有抽象方法未实现
B:可以被继承。派生类可以实现抽象方法
C:子类可以是抽象的,也可以非抽象的
D:只能被继承说法太肯定,不正确
E:可以被抽象类继承,也可以被非抽象类继承
19
(多选)final、finally和finalize的区别中,下述说法正确的有?
- A:final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
- B:finally是异常处理语句结构的一部分,表示总是执行。
- C:finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源的回收,例如关闭文件等。
- D:引用变量被final修饰之后,不能再指向其他对象,它指向的对象的内容也是不可变的。
解析:
A,D考的一个知识点,final修饰变量,变量的引用(也就是指向的地址)不可变,但是引用的内容可以变(地址中的内容可变)。
B,finally表示总是执行。但是其实finally也有不执行的时候,但是这个题不要扣字眼。
在try中调用System.exit(0),强制退出了程序,finally块不执行。
在进入try块前,出现了异常,finally块不执行。
C,finalize方法,这个选项错就错在,这个方法一个对象只能执行一次,只能在第一次进入被回收的队列,而且对象所属于的类重写了finalize方法才会被执行。第二次进入回收队列的时候,不会再执行其finalize方法,而是直接被二次标记,在下一次GC的时候被GC。
20
(多选)以下关于final关键字说法错误的是()
- A:final是java中的修饰符,可以修饰类、接口、抽象类、方法和属性
- B:final修饰的类肯定不能被继承
- C:final修饰的方法不能被重载
- D:final修饰的变量不允许被再次赋值
解析:
1.final修饰变量,则等同于常量
2.final修饰方法中的参数,称为最终参数。
3.final修饰类,则类不能被继承
4.final修饰方法,则方法不能被重写。
5.final 不能修饰抽象类
6.final修饰的方法可以被重载 但不能被重写
21
(多选)下面属于java包装类的是?
- A:String
- B:Long
- C:Character
- D:Short
解析:
包装类是针对 基本数据类型 的。
基本数据类型 包装类 byte Byte boolean Boolean short Short char Character int Integer long Long float Float double Double
22
(多选)在java中重写方法应遵循规则的包括()
- A:访问修饰符的限制一定要大于被重写方法的访问修饰符
- B:可以有不同的访问修饰符
- C:参数列表必须完全与被重写的方法相同
- D:必须具有不同的参数列表
解析:
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 | public class Test { |
- A:-1
- B:2
- C:1
- D:-2
解析:
取模运算,结果的符号和被除数符号一致,切记切记
24
(多选)以下关于final关键字说法错误的是
- A:final是java中的修饰符,可以修饰类、接口、抽象类、方法和属性
- B:final修饰的类肯定不能被继承
- C:final修饰的方法不能被重载
- D:final修饰的变量不允许被再次赋值
解析:
final修饰类、方法、属性!不能修饰抽象类,因为抽象类一般都是需要被继承的,final修饰后就不能继承了。
final修饰的方法不能被重写而不是重载!
final修饰属性,此属性就是一个常量,不能被再次赋值!
final也不能修饰接口,接口可以只能被public&abstract修饰
final如果修饰的是基本类型的变量,那么这个变量就表示为一个常数,只能赋值一次,要么在定义时赋值,要么在初始化时赋值;final修饰应用类型的变量是,变量不能再次被赋值意思是变量的地址(引用)不可以被改变,当变量所指向的内容可以被改变。
25
静态内部类不可以直接访问外围类的非静态数据,而非静态内部类可以直接访问外围类的数据,包括私有数据。( )
- A:正确
- B:错误
解析:
静态内部类:
- 静态内部类本身可以访问外部的静态资源,包括静态私有资源。但是不能访问非静态资源,可以不依赖外部类实例而实例化。
成员内部类:
- 成员内部类本身可以访问外部的所有资源,但是自身不能定义静态资源,因为其实例化本身就还依赖着外部类。
局部内部类:
- 局部内部类就像一个局部方法,不能被访问修饰符修饰,也不能被static修饰。
- 局部内部类只能访问所在代码块或者方法中被定义为final的局部变量。
匿名内部类:
- 没有类名的内部类,不能使用class,extends和implements,没有构造方法。
2. 多用于GUI中的事件处理。
3. 不能定义静态资源
4. 只能创建一个匿名内部类实例。
5. 一个匿名内部类一定是在new后面的,这个匿名类必须继承一个父类或者实现一个接口。
6. 匿名内部类是局部内部类的特殊形式,所以局部内部类的所有限制对匿名内部类也有效。
26
有如下4条语句:()
1 | Integer i01=59; |
以下输出结果为false的是:
- System.out.println(i01==i02);
- System.out.println(i01==i03);
- System.out.println(i03==i04);
- System.out.println(i02==i04);
解析:
- 无论如何,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
解析:
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:在程序中,用户可以控制合适执行静态初始化块
解析:
java对象初始化顺序
先说结论:
- 父类静态代码块,父类静态成员变量(同级,按代码顺序执行)
- 子类静态代码块,子类静态成员变量(同级,按代码顺序执行)
- 父类普通代码块,父类普通成员变量(同级,按代码顺序执行)
- 父类构造方法
- 子类普通代码块,子类普通成员变量(同级,按代码顺序执行)
- 子类构造方法
注意点:
- 静态内容只在类加载时执行一次,之后不再执行。
- 默认调用父类的无参构造方法,可以在子类构造方法中利用super指定调用父类的哪个构造方法。
29
执行如下程序代码
char chr = 127;
int sum = 200;
chr += 1;
sum += chr;
后,sum的值是 ; ( )
备注:同时考虑c/c++和Java的情况的话
- A:72
- B:99
- C:328
- D:327
解析:
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而直接相互使用。
解析:
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”
解析:文字游戏注意是字符常量(’’)而不是字符串常量(””)
32
(多选)以下关于JAVA语言异常处理描述正确的有?
- A:throw关键字可以在方法上声明该方法要抛出的异常。
- B:throws用于抛出异常对象。
- C:try是用于检测被包住的语句块是否出现异常,如果有异常,则抛出异常,并执行catch语句。
- D:finally语句块是不管有没有出现异常都要执行的内容。
在try块中不可以抛出异常
解析:
Java语言中的异常处理包括声明异常、抛出异常、捕获异常和处理异常四个环节。
throws关键字可以在方法上声明该方法要抛出的异常,然后在方法内部通过throw抛出异常对象。A选项应该为throws B选项应该为throw。
C选项不严谨,这个异常不是用try抛出来的,而是用了try能检测到底层抛出的异常,然后进行处理。这里应该用“捕获”这个异常才对。
这个“如果有异常,则抛出异常”。在捕获异常的时候使用throw,才会抛出这个异常,否则只是捕获到,而不是抛出。这个是需要显式写出来的。
但是答案中存在,忽略这个细节。AB错误太明显。
33
下列语句正确的是:
- A:形式参数可被字段修饰符修饰
- B:形式参数不可以是对象
- C:形式参数为方法被调用时真正被传递的参数
- D:形式参数可被视为local variable
解析:
34
关于C++/JAVA类中static 成员和对象成员的说法正确的是?
- A:static 成员变量在对象构造时生成
- B:static 成员函数在对象成员函数中无法调用
- C:虚成员函数不可能是static 成员函数
- D:static 成员函数不能访问static 成员变量
解析:
- static为成员变量或函数,在类初始化是加载完成,可以被成员函数调用或访问
- static成员函数既可以通过类名直接调用,也可以通过对象名进行调用
- 虚函数是C++中的,虚函数不可能是static的
- static成员函数可以访问static成员变量
35
给定以下JAVA代码,这段代码运行后输出的结果是()
1 | public class Test |
- A:exception in main finished
- B:finally finished
- C:exception in main finally
- D:finally exception in main finished
解析:
题目中是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 | public class Test |
- A:ABDCBDCB
- B:ABCDABCD
- C:Compilation fails.
- D:An exception is thrown at runtime.
解析:
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 | 1. byte a1 = 2, a2 = 4, a3; |
- A:Line 3 and Line 4
- B:Line 1 only
- C:Line 3 only
- D:Line 4 only
解析:
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 | double d1=-0.5; |
- 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
解析:
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”))
解析:
注意这里”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)
解析:
1.== 和 equals():
(1)“==” 用于比较基本数据类型时比较的是值,用于比较引用类型时比较的是引用指向的地址。
(2)Object 中的equals() 与 “==” 的作用相同,但String类重写了equals()方法,比较的是对象中的内容。
2.String对象的两种创建方式:
(1)第一种方式: String str1 = “aaa”; 是在常量池中获取对象(“aaa” 属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象,如果常量池中已经存在该字符串对象则直接引用)
1 System.out.println(str1==str2);//false3.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
解析:
基本数据类型的运算,会自动向上转型。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
解析:
java.lang包是java语言的核心包,lang是language的缩写
java.lang包定义了一些基本的类型,包括Integer,String之类的,是java程序必备的包,有解释器自动引入,无需手动导入
43
由3 个“1”和 5 个“0”组成的 8 位二进制补码,能表示的最小整数()
- A:-126
- B:-125
- C:-32
- D:-3
解析:
既然求最小整数,那肯定先想到负数,则最高位(符号位)一定为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
解析:
45
以下程序程序运行后的输出结果是()
1 | public static void main(String[] args){ |
- A:12353514
- B:12353513
- C:12343514
- D:12343513
解析:
不要忘记前面已经自加过后,变量的值已经改变了(明白了这个肯定就没问题了)
第一个输出: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:声明抽象方法不可写出大括号
解析:
A:abstract修饰方法和类
B、C:抽象方法没有方法体,有没有方法体看有没有大括号。
47
以下不是修饰符final的作用的是( )。
- A:修饰常量
- B:修饰不可被继承的类
- C:修饰不可变类
- D:修饰不可覆盖的方法
解析:
final的作用:
1. 修饰变量,变量的引用地址不可变,但是地址中的内容可以变。
2. 修饰方法,方法不可被重写,但是还是可以重载
3. 修饰类,类不可继承。
不可变类:说的是一个类一旦被实例化,就不可改变自身的状态。常见的比如String和基本数据类型的包装类,对于这种不可变类,一旦在进行引用传递的时候,形参一开始就和实际参数指向的不是一个地址,所以在方法中对形参的改变,并不会影响实际参数。
计算机基础
48
在一个基于分布式的游戏服务器系统中,不同的服务器之间,哪种通信方式是不可行的()?
- A:管道
- B:消息队列
- C:高速缓存数据库
- D:套接字
解析:
管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
既然是不同的服务器之间进行通信,怎么可能会是具有亲缘关系的进程呢?
49
以下哪个式子有可能在某个进制下成立()?
- A:13 * 14=204
- B:12 * 34=568
- C:14*14=140
- D:1+1=3
解析:
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 | public static void main(String args[]) { |
- A:12
- B:22
- C:20
- D:1419857
解析:
位异运算符号。
运算规则是:两个数转为二进制,然后从高位开始比较,如果相同则为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)
解析:
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:磁盘调度
解析:
存根类是一个类,它实现了一个接口,它的作用是:如果一个接口有很多方法,如果要实现这个接口,就要实现所有的方法。但是一个类从业务来说,可能只需要其中一两个方法。如果直接去实现这个接口,除了实现所需的方法,还要实现其他所有的无关方法。而如果通过继承存根类就实现接口,就免去了这种麻烦。
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下的类,它包含有各种有关集合操作的静态方法
解析:
java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
54
java8中,下面哪个类用到了解决哈希冲突的开放定址法
- A:LinkedHashSet
- B:HashMap
- C:ThreadLocal
- D:TreeMap
解析:
ThreadLocalMap中使用开放地址法来处理散列冲突,而HashMap中使用的是分离链表法。之所以采用不同的方式主要是因为:在ThreadLocalMap中的散列值分散得十分均匀,很少会出现冲突。并且ThreadLocalMap经常需要清除无用的对象,使用纯数组更加方便。
55
列表(List)和集合(Set)下面说法正确的是? ( )
- A:Set中至多只能有一个空元素
- B:List中至多只能有一个空元素
- C:List和Set都可以包含重复元素的有序集合
- D:List和Set都是有序集合
解析:
- 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线程安全的,允许存放重复对象
解析:
注意:常见并非全部
线程安全(Thread-safe)的集合对象:
- Vector 线程安全:
- HashTable 线程安全:
- StringBuffer 线程安全:
非线程安全的集合对象:
- ArrayList :
- LinkedList:
- HashMap:
- HashSet:
- TreeMap:
- TreeSet:
- StringBulider:
57
list是一个ArrayList的对象,哪个选项的代码填到//todo delete处,可以在Iterator遍历的过程中正确并安全的删除一个list中保存的对象?()
1 | Iterator it = list.iterator(); |
- A:it.remove();
- B:list.remove(obj);
- C:list.remove(index);
- D:list.remove(obj,index);
解析:
源码是这么描述的: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 不允许。
解析:
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 ) ;
解析:
选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
解析:
├List
│├LinkedList
│├ArrayList
│└Vector
│└Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
61
(多选)下面哪些类实现或继承了 Collection 接口?
- A:HashMap
- B:ArrayList
- C:Vector
- D:Iterator
解析:
多线程
62
(多选)下列哪些操作会使线程释放锁资源?
- A:sleep()
- B:wait()
- C:join()
- D:yield()
解析:
所谓的释放锁资源实际是通知对象内置的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:运行态->就绪态
解析:
64
(多选)Java.Thread的方法resume()负责重新开始被以下哪个方法中断的线程的执行()。
- A:stop
- B:sleep
- C:wait
- D:suspend
解析:
resume与suspended一起使用
wait与notify/notifyAll一起使用
sleep会让线程暂时不执行Thread类的suspend()和resume()方法都已经被声明已废弃了
65
下列程序的运行结果
1 | public static void main(String args[]) { |
- A:pingpong
- B:pongping
- C:pingpong和pongping都有可能
- D:都不输出
解析:
这里需要注意Thread的start和run方法
用start方法才能真正启动线程,此时线程会处于就绪状态,一旦得到时间片,则会调用线程的run方法进入运行状态。
而run方法只是普通方法,如果直接调用run方法,程序只会按照顺序执行主线程这一个线程。
IO
66
BufferedReader的父类是以下哪个?
- A:FilterReader
- B:InputStreamReader
- C:PipedReader
- D:Reader
解析:









