2019年11月9日 java2

考点1

下列说法正确的有( )

  • A class中的constructor不可省略
  • B constructor必须与class同名,但方法不能与class同名
  • C constructor可在一个对象被new时执行
  • D 一个class只能定义一个constructor

正确答案: C

解析

a. 类中的构造方法可以省略不写的
b. 构造方法必须跟类名相同,普通的类方法能与类同名的,但是要返回一个值。
c. 构造方法都在new 对象的时候调用的
d. 一个类可以定义多个构造方法的

考点2

1
2
3
4
5
6
static String str0="0123456789";
static String str1="0123456789";
String str2=str1.substring(5);
String str3=new String(str2);
String str4=new String(str3.toCharArray());
str0=null;

假定str0,…,str4后序代码都是只读引用。
Java 7中,以上述代码为基础,在发生过一次FullGC后,上述代码在Heap空间(不包括PermGen)保留的字符数为()

  • A 5
  • B 10
  • C 15
  • D 20

正确答案: C

解析

这是一个关于java的垃圾回收机制的题目。垃圾回收主要针对的是堆区的回收,因为栈区的内存是随着线程而释放的
堆区分为三个区:

  • 年轻代(Young Generation)、
  • 年老代(Old Generation)、
  • 永久代(Permanent Generation,也就是方法区)。

年轻代:对象被创建时(new)的对象通常被放在Young(除了一些占据内存比较大的对象),经过一定的Minor GC(针对年轻代的内存回收)还活着的对象会被移动到年老代(一些具体的移动细节省略)。
年老代:就是上述年轻代移动过来的和一些比较大的对象。**Minor GC(Full GC)是针对年老代的回收**
永久代:存储的是final常量,static变量,常量池。

str3,str4都是直接new的对象,而substring的源代码其实也是new一个string对象返回。
经过full gc之后,年老区的内存回收,则年轻区的占了15个,不算PermGen。所以答案选C

垃圾回收机制这方面了解的比较少,有时间了解一下

考点3

运行代码,结果正确的是:

1
2
3
4
5
6
Boolean flag = false;
if(flag = true){
System.out.println("true");
}else{
System.out.println("false");
}
  • A 编译错误
  • B TRUE
  • C FALSE
  • D 什么也没有输出

解析

显示答案/隐藏答案 正确答案: B

注意 if判断条件flag = true是赋值语句,返回true 不会执行else里面内容

考点4

从运行层面上来看,从四个选项选出不同的一个。

  • A JAVA
  • B Python
  • C objectC
  • D C#

解析

显示答案/隐藏答案 正确答案: B

A,C,D都是类C语言,B不是
Python是解释执行的,其他语言都需要先编译

考点5

有以下一个对象:

1
2
3
4
5
6
7
8
9
10
public class DataObject implements Serializable{
private static int i=0;
private String word=" ";
public void setWord(String word){
this.word=word;
}
public void setI(int i){
Data0bject. i=I;
}
}

创建一个如下方式的DataObject:

1
2
3
DataObject object=new DataObject ( );
object.setWord("123");
object.setI(2);

将此对象序列化为文件,并在另外一个JVM中读取文件,进行反序列化,请问此时读出的DataObject对象中的word和i的值分别为:

  • A “”, 0
  • B “”, 2
  • C “123”, 2
  • D “123”, 0

正确答案: D

解析

序列化保存的是对象的状态,静态变量属于类的状态,因此,序列化并不保存静态变量。所以i是没有改变的
Java在序列化时不会实例化static变量和transient修饰的变量,因为static代表类的成员,transient代表对象的临时数据,被声明这两种类型的数据成员不能被序列化

考点6

下面有关java threadlocal说法正确的有?

  • A ThreadLocal存放的值是线程封闭,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递
  • B 线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收
  • C 在Thread类中有一个Map,用于存储每一个线程的变量的副本。
  • D 对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式

正确答案: ABCD

解析

ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量。
ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程的上下文。
可以总结为一句话:
ThreadLocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度

ThreadLocal设计的初衷:提供线程内部的局部变量,在本线程内随时随地可取,隔离其他线程。

ThreadLocal的使用场景

数据库连接:在多线程中,如果使用懒汉式的单例模式创建Connection对象,由于该对象是共享的,那么必须要使用同步方法保证线程安全,这样当一个线程在连接数据库时,那么另外一个线程只能等待。这样就造成性能降低。
如果改为哪里要连接数据库就来进行连接,那么就会频繁的对数据库进行连接,性能还是不高。这时使用ThreadLocal就可以既可以保证线程安全又可以让性能不会太低。但是ThreadLocal的缺点时占用了较多的空间。

考点7

对接口的描述正确的是()

  • A 一个类可以实现多个接口
  • B 接口可以有非静态的成员变量
  • C 在jdk8之前,接口可以实现方法
  • D 实现接口的任何类,都需要实现接口的方法

正确答案: A

解析

A,一个类只能有一个直接父类,但是继承是有传递性的。一个类可以实现多的接口。一个接口可以继承多个类。
B,接口中没有普通变量(普通成员变量),接口的成员变量都是常量,默认修饰符:public static final
C,

  • JDK8之前接口中的方法都是默认public abstract的,抽象方法没有方法体
  • JDK8时接口中可以有static、default的修饰的方法,static、default修饰的方法必须有方法。接口中的方法都不能被private和protected修饰。
  • 外部接口、类只能被public修饰或者不写,
  • 内部接口、类可以被四个访问修饰符修饰。

D, 实现接口,其实就是需要重写接口中的abstract方法,一旦实现的类没有重写完,那么这个类必须是个抽象类(抽象类中可以没有抽象方法,但是有抽象方法的类必须是抽象类)。

考点8

java7后关键字 switch 支不支持字符串作为条件:()

  • A 支持
  • B 不支持

正确答案: A

解析

在Java7之前,switch只能支持
byte、short、char、int或者其对应的封装类以及Enum类型。
在Java7中,呼吁很久的String支持也终于被加上了。

在switch语句中,表达式的值不能是null,否则会在运行时抛出NullPointerException。
在case子句中也不能使用null,否则会出现编译错误。
同时,case字句的值是不能重复的。对于字符串类型的也一样,但是字符串中可以包含Unicode转义字符。重复值的检查是在Java编译器对Java源代码进行相关的词法转换之后才进行的。也就是说,有些case字句的值虽然在源代码中看起来是不同的,但是经词法转换之后是一样的,就会在成编译错误。比如:“男”和“\u7537”就是一个意思。

可以看出,字符串类型在switch语句中利用hashcode的值与字符串内容的比较来实现的;但是在case字句中对应的语句块中仍然需要使用String的equals方法来进一步比较字符串的内容,这是因为哈希函数在映射的时候可能存在冲突。
switch(exp),在JDK7之前,只能是byte、short、char、int或者对应的包装类,或者枚举常量(内部也是由整型或字符类型实现)。
为什么必须是这些呢,因为其实exp只是对int型支持的,其他都是因为可以自动拆卸或者自动向上转型到int,所以才可以。
到了JDK7的时候,String被引入了,为什么String能被引入呢?
其实本质上还是对int类型值得匹配。
原理如下,通过对case后面得String对象调用hashCode方法,得到一个int类型得hash值,然后用这个hash值来唯一标识这个case。那么当匹配时,首先调用exp的hashCode,得到exp的hash值,用这个hash值来匹配所有case,如果没有匹配成功,就说明不存在;如果匹配成功了,接着会调用字符串的equals方法进行匹配。(hash值一致,equals可不一定返回的就是true)。
所以,exp不能为null,cas子句使用的字符串也不能为null,不然会出现空指针异常。

考点9

已知如下类定义:
class Base {
public Base (){
//…
}
public Base ( int m ){
//…
}
public void fun( int n ){
//…
}
}
public class Child extends Base{
// member methods
}
如下哪句可以正确地加入子类中?

  • A private void fun( int n ){ //…}
  • B void fun ( int n ){ //… }
  • C protected void fun ( int n ) { //… }
  • D public void fun ( int n ) { //… }

正确答案: D

解析

方法的重写(override)两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。

考点10

如下代码的 结果是什么 ?
class Base {
Base() {
System.out.print(“Base”);
}
}
public class Alpha extends Base {
public static void main( String[] args ) {
new Alpha();
//调用父类无参的构造方法
new Base();
}
}

  • A Base
  • B BaseBase
  • C 编译失败
  • D 代码运行但没有输出
  • E 运行时抛出异常

正确答案: B

解析

考点11

关于下面程序,哪些描述是正确的: ( )
public class While {
public void loop() {
int x= 10;
while ( x ) {
System.out.print(“x minus one is “ + (x - 1));
x -= 1;
}
}
}

  • A 行1有语法错误
  • B 行4有语法错误
  • C 行5有语法错误
  • D 行6有语法错误
  • E 行2有语法错误,loop是关键字
  • F 程序能够正常编译和运行

正确答案: B

解析

while()括号里的参数要是boolean类型,int类型不行

考点12

假设如下代码中,若t1线程在t2线程启动之前已经完成启动。代码的输出是()
public static void main(String[]args)throws Exception {
final Object obj = new Object();
Thread t1 = new Thread() {
public void run() {
synchronized (obj) {
try {
obj.wait();
System.out.println(“Thread 1 wake up.”);
} catch (InterruptedException e) {
}
}
}
};
t1.start();
Thread.sleep(1000);//We assume thread 1 must start up within 1 sec.
Thread t2 = new Thread() {
public void run() {
synchronized (obj) {
obj.notifyAll();
System.out.println(“Thread 2 sent notify.”);
}
}
};
t2.start();
}

  • A Thread 1 wake up Thread 2 sent notify.
  • B Thread 2 sent notify. Thread 1 wake up
  • C A、B皆有可能
  • D 程序无输出卡死

正确答案: B

解析

选择B
执行obj.wait();时已释放了锁,所以t2可以再次获得锁,然后发消息通知t1执行,但这时t2还没有释放锁,所以肯定是执行t2,然后释放锁,之后t1才有机会执行。

考点13

对于线程局部存储TLS(thread local storage),以下表述正确的是

  • A 解决多线程中的对同一变量的访问冲突的一种技术
  • B TLS会为每一个线程维护一个和该线程绑定的变量的副本
  • C 每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了
  • D Java平台的java.lang.ThreadLocal是TLS技术的一种实现

正确答案: ABD

解析

ThreadLocal可以给一个初始值,而每个线程都会获得这个初始化值的一个副本,这样才能保证不同的线程都有一份拷贝。
ThreadLocal
不是用于解决共享变量的问题的,不是为了协调线程同步而存在,而是为了方便每个线程处理自己的状态而引入的一个机制.
ThreadLocal确实是保证了每一个线程都拥有一个变量的副本,而且这个副本的初始值取决于ThreadLoacl中initialValue方法的重写,如果initialValue方法中引用了一个全局的变量的地址,那么其他线程对全局变量的修改还是会影响到此线程中引用变量的内容。

考点14

哪个是不正确的字符常量?

  • A ”\n”
  • B ”1”
  • C ”a”
  • D ”\101”

正确答案: ABCD

解析

  • 单引号才是字符常量
  • 双引号是字符串常量