2018-8月Java试题整理

8-1

1.Java语言中,按照一定格式生成程序的文档的工具是?

  • javac
  • javah
  • javadoc
  • jar

解析:

  1. jar:将许多文件组合成一个jar文件
  2. javac:编译
  3. javadoc:它从程序源代码中抽取类,方法,成员等注释形成一个和源代码配套的API帮助文档
  4. javah:把Java代码声明的JNI方法转化成C/C++头文件。

2.

  1. 静态内部类才可以声明静态方法
  2. 静态方法不可以使用非静态变量
  3. 抽象方法不可以有函数体

3.以下哪些JVM的垃圾回收方法采用的是复制算法回收?

  • 新生代串行收集器
  • 老年代串行收集器
  • 并行收集器
  • 新生代并行回收收集器
  • 老年代并行回收收集器
  • cms收集器

解析:

  • 复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
  • 标记清理:一块区域,标记可达对象(可达性分析),然后回收不可达对象,会出现碎片,那么引出
  • 标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象
  • 新生代:初始对象,生命周期短的
  • 永久代:长时间存在的对象
    整个Java的垃圾回收是新生代和年老代的协作,这种叫做分代回收

  • Serial New收集器是针对新生代的收集器,采用的是复制算法

  • Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理
  • Parallel Scavenge(并行)收集器,针对新生代,采用复制收集算法
  • Serial Old(串行)收集器,新生代采用复制,老年代采用标记整理
  • Parallel Old(并行)收集器,针对老年代,标记整理
  • CMS收集器,基于标记清理
  • G1收集器,整体上是基于标记整理,局部采用复制

综上:新生代基本采用复制算法,老年代用标记整理算法,cms采用标记整理


4.This调用语句必须是构造函数中的第一个可执行语句

  • zhengque
  • 错误

解析:
this()才必须是构造函数中的第一个可执行语句,用this调用语句并不需要


5.假设有以下代码

String s = "hello";
String t = "hello";
char c[] = {'h', 'e', 'l', 'l', 'o'};
  • s.equals(t);
  • t.equals(c);
  • s==t;
  • t.equals(new String (“hello”));

解析:

String s = "hello";
String t = "hello";
char c [ ] = {'h','e','1','1','o'};
System.out.println(s.equals (t)); //true  s和t指向内存常量区的同一个字符串  ;
System.out.println(t.equals (c));//false 一个返回字符串,一个返回对象 ;
System.out.println(s==t);// true  s和t指向内存常量区的同一个字符串 ;
System.out.println(t.equals (new String ("hello")));//true equal用于比较两个对象的值是否相同,和内存地址无关

8-2

1.执行语句“int a = ‘2’”后,a的值是?

  • 2
  • 50
  • 49
  • 0

解析:
常见的ASCII码值:空格为32;数字0为48;“A”为65;“a”为97
0-9:48-57
A-Z:65-90
a-z:97-122


2.下列关于Java中的wait()方法和sleep()方法的区别描述错误的是

  • wait方法属于Object类;sleep属于Thread类
  • 调用wait()方法的时候,线程会自动放弃对象锁
  • 调用sleep()方法的过程中,线程不会释放对象锁
  • sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程

解析:
sleep和wait的区别:

  1. 这两个方法来自不同的类分别是Thread和Object
  2. 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得敏感词线程可以使用同步控制块或方法
  3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
synchronized(x){
      x.notify()
     //或者wait()
   }

4.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常。

D:线程暂停执行指定的时间而不是程序暂停执行指定的时间。


3.下列说法错误的有

  • 在类方法中可用this来调用本类的类方法
  • 在类方法中调用本类的类方法时可直接调用
  • 在类方法中只能调用本类中的类方法
  • 在类方法中绝对不能调用实例方法

解析:
可以将this理解为对象,而类方法属于类,不属于对象,所以类方法前不能加this指针

A:类方法是指类中被static修饰的方法,无this指针
C:类方法是可以调用其他类的static方法的
D:可以在类方法中生成实例对象再调用实例方法。


4.Java中String str = “hello world”下列语句错误的是

  • str+=’ a’
  • int strlen = str.length
  • str=100
  • str=str+100

解析:
A:‘a’是字符串,’ a’这个是空格和a,必须要用“ a”才可以
B:String有length()方法
C:int无法直接转成String类型
D:尾部添加字符串“100”


5.在异常处理中,以下描述不正确的是

  • try块不可以省略
  • 可以使用多重catch块
  • finally块可以省略
  • catch块和finally块可以同时省略

解析:
三种组合:
try…catch…finally
try…catch
try…finally


6.对于子类的构造函数说明,下列叙述中错误的是

  • 子类可以继承父类的构造函数。
  • 子类中调用父类构造函数不可以直接书写父类构造函数,而应该用super();。
  • 用new创建子类的对象时,若子类没有带参构造函数,将先执行父类的无参构造函数,然后再执行自己的构造函数。
  • 子类的构造函数中可以调用其他函数。

解析:
Java继承中对构造函数是不继承的,只是显示或者隐式调用


7.类Parent和Child定义如下:

1class  Parent{
2public  float  aFun(float a, float b) { }
3.}
4class  Child  extends  Parent{
56.}

哪个插入到行5是不合法的?

  • float aFun(float a, float b){ }
  • public int aFun(int a, int b) { }
  • public float aFun(float p, float q){ }
  • private int aFun(int a, int b){ }

解析:
方法重写应该遵循“三同一小一大”原则:

  • “三同”:方法名相同,形参列表相同,返回值类型相同
  • “一小”:子类方法声明抛出的异常比父类方法声明抛出的异常更小或者相等
  • “一大”:子类方法的访问修饰符应比父类更大或相等

A是重写,但是默认访问修饰符比父类的小,插入第五行编译器会报错
B,D不是重写,因为形参列表和返回值类型不同,所以在第五行以普通方法对待,没有错误
C满足条件,是重写,正确。


8.以下代码将输出什么内容

public class SystemUtil{
    public static boolean isAdmin(String userId){
        return userId.toLowerCase()=="admin";
    }
    public static void main(String[] args){
        System.out.println(isAdmin("Admin"));
    }
}
  • true
  • false
  • 1
  • 编译错误

解析:
在源码中toLowerCase 是重新new String()


9.以下关于Java语言异常处理描述正确的有

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

解析:
Java语言中的异常处理包括声明异常,抛出异常,捕获异常,和处理异常四个环节。
throw用于抛出异常
throws关键字可以在方法上声明该方法要抛出的异常,然后在方法内部通过throw抛出异常对象。
try是用于检测被包住的语句块是否出现异常,如果有异常,则抛出异常,并执行catch语句
catch用于捕获从try中抛出的异常并做处理
finally语句块是不管有没有出现异常都要执行的内容


8-3

1.Java中只有整型才能使用的运算符为?

  • *
  • /
  • %
  • +

解析:
ABD选项的操作符都可用于float和double
只有%取余操作,只适合用于整型。


2.关于String,StringBuilder,StringBuffer,描述错误的是?

  • 对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象。
  • StringBuffer是线程安全
  • StringBuilder是线程安全
  • 可以修改StringBuilder和StringBuffer的内容

解析:
A:Java中的字符串存储在字符串常量区,不会改变,发生改变是会新创建一个对象
B:StringBuffer是线程安全的String Builder
C:StringBuilder跟StringBuffer功能相同,区别是StringBuilder不是线程安全
D:StringBuilder和StringBuffer底层都是以字符数组存放的,可以修改内容


3.在开发中使用泛型取代非泛型的数据类型(比如用ArrayList< String >取代ArrayList,程序运行时性能会变得更好。

解析:
泛型仅仅是Java的一颗语法糖,他不会影响Java虚拟机生成的汇编代码,在编译阶段,虚拟机就会把泛型的类型擦除,还原成没有泛型的代码,顶多编译速度稍微慢一些,执行速度是完全没有什么区别的。


4.设int x = 1,float y = 2,则表达式x / y的值是?

  • 0
  • 1
  • 2
  • 以上都不是

解析:
正解:0.5
x / y = (float) 1.0 / (float) 2.0 = 0.5;


5.public class contained in a Java program file must have the same name as the file, except for the extension “.java”.

  • FALSE
  • TRUE

解析:
内部类就不需要与文件名相同


6.下面赋值语句中正确的是?

  • double d=5.3e12;
  • float f=11.1;
  • int i=0.0;
  • Double oD=3;

解析:
B:在Java中,如果你输入一个小数,系统默认的是double类型的,这个式子相当于float f = double 11.1,明显错误。如果想要表达11.1为float类型,需要在11.1末尾加一个“f”标识你输入的是float类型即可。


7.以下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);
    }
}
  • 1true
  • 2true
  • 1false
  • 2false

解析:
Java中引用类型的实参向形参的传递,只是传递的引用,而不是传递的对象本身,如下:
这里写图片描述


8.异常:

这里写图片描述

一、运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常),IndexOutOfBoundsException(下标越界)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
二、非运行时异常(编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类,从语法角度讲必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException,SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。


9.Java中那个关键字可以对对象加互斥锁?

  • transient
  • synchronized
  • serialize
  • static

解析:

  • synchronized:用来给对象和方法或者代码块加锁,当他锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。
  • volatile:用来确保将变量和更新操作通知到其它线程,当把变量声明为volatile类型后,编译器在运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其它内存操作一起重排序。然而,在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比synvhronized关键字更轻量级的同步机制

10.

普通的类方法是可以和类名同名的,和构造方法唯一的区别就是,构造方法没有返回值。


11.以下代码结果是什么

public class foo {
public static void main(String sgf[]) {
    StringBuffer a=new StringBuffer(“A”);
    StringBuffer b=new StringBuffer(“B”);
    operate(a,b);
    System.out.println(a+”.”+b);
}
static void operate(StringBuffer x,StringBuffer y) {
    x.append(y);
    y=x;
}
}
  • 代码可以编译运行,输出“AB.AB”。
  • 代码可以编译运行,输出“A.A”。
  • 代码可以编译运行,输出“AB.B”。
  • 代码可以编译运行,输出“A.B”。

解析:
这里写图片描述

往方法中传参,传的仅仅只是地址,而不是实际内存,所以不要以为y=x程序的执行,是b=a的执行。这两者是不相等的。


8-4

1.基本数据类型均可任意互相转换

解析:
原生类是指Java中,数据类型分为基本数据(或叫做原生类,内置类型)和引用数据类型。
那么原生类为基本数据类型,有八种,这样转换的时候就有表达范围问题

  1. 所占位数少的可以转换为所占位数多的类型,比如byte转char,char转int等
  2. 而所占位数多的转为所占位数少的默认情况下不能实现转换,需要强制类型转换,这样可能会丢失一部分原始数据
  3. 此外,boolean类型数据和其它七种不能互相转换。

2.下列哪些语句关于内存回收的说明是正确的?

  • 程序员必须创建一个线程来释放内存
  • 内存回收程序负责释放无用内存
  • 内存回收程序允许程序员直接释放内存
  • 内存回收程序可以在指定的时间释放内存对象

解析:
A:JVM一旦启动,就会创建一个守护线程来检测是否需要有对象内存被释放
C:无法直接释放
D:不可以指定时间,System.gc(),只是提醒JVM可以进行一次Full GC,但是什么时候真正执行,还是不知道的。


3.有如下一段程序

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());
    }
}

最后打印出的是什么?

  • 2
  • 3
  • 4
  • 5

解析:
return i++,先返回i,然后再i+1


4.

注意:
副本与原数据是不相关的,不会相互影响。
不过一般方法传递时候,只有基本数据类型和String才会传递副本,其它的类型是按引用传递的。
Java只有值传递


5.full GC触发的条件

解析:
年老代满,持久代满,System.gc()


6.

这里写图片描述


8-5

1.一个完整的URL地址由()()。端口和文件四部分组成

  • 协议,用户名
  • 协议,主机名
  • 主机名,ip
  • 以上都不正确

解析:
URL(Uniform Resource Locator)统一资源定位符,能够对因特网的资源进行定位。
URL一般由四部分组成:<协议>://<主机>:<端口>/<路径>
现在最常用的<协议>为http协议
<主机>是指主机在因特网上的域名
hhtp协议的默认<端口>为80(可省略)
<路径>是指文件的路径


2.

继承具有传递性,子类可以无条件向上转型

3.Java程序初始化的执行顺序:

父类静态变量 -> 父类静态代码块
子类静态变量 -> 子类静态代码块
父类非静态变量 -> 父类非静态代码块
父类构造方法 -> 子类非静态变量
子类非静态代码块 -> 子类构造方法


3.一个文件的字符要写到另一个文件中,首先需要()

  • 使用标准输出流System.out.println()
  • 建立文件字符输出流
  • 建立文件字符输入流
  • 标准输入流System.in.read()

解析:
一个文件的字符要写到一个文件中,首先需要读取这个文件,所以要先建立输入流,然后写到另一个文件,这时再建立输出流,所以要先建立输入流,在建立输出流。


4.在JDK1.5之后,下列Java程序输出结果为__

int i=0;
Integer j = new Integer(0);
System.out.println(i==j);
System.out.println(j.equals(i));
  • true,true

解析:

  1. 基本型和基本封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,显然返回true
  2. 两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否则返回false,这跟Integer.valueOf()的缓冲对象有关。
  3. 两个基本型的封装进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true。
  4. 基本型封装类调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,在进行3中的比较。

5.给出以下代码,请给出结果

class Two{
    Byte x;
}
class PassO{
    public static void main(String[] args){
        PassO p=new PassO();
        p.start();
    }
    void start(){
        Two t=new Two();
        System.out.print(t.x+””);
        Two t2=fix(t);
        System.out.print(t.x+” ” +t2.x);
    }
    Two fix(Two tt){
        tt.x=42;
        return tt;
    }
}
  • null ,42 ,42

解析:
基本类型和String=“”是传值,其他类型都是传引用。当然,也可以认为Java只有传值,因为一个是拷贝了栈中的值,一个是拷贝了引用的地址值。

这里写图片描述


6.Test,main()函数执行后的输出是()

public class Test {  
    public static void main(String [] args){  
        System.out.println(new B().getValue());  
    }  
    static class A{  
        protected int value;  
        public A(int v) {  
            setValue(v);  
        }  
        public void setValue(int value){  
            this.value = value;  
        }  
        public int getValue(){  
            try{  
                value++;  
                return value;  
            } catch(Exception e){  
                System.out.println(e.toString());  
            } finally {  
                this.setValue(value);  
                System.out.println(value);  
            }  
            return value;  
        }  
    }  
    static class B extends A{  
        public B() {  
            super(5);  
            setValue(getValue() - 3);  
        }  
        public void setValue(int value){  
            super.setValue(2 * value);  
        }  
    }  
}  
  • 22,34,17

解析:
首先,super()函数指的是调用父类的构造方法

new B()
执行B的构造函数,第一行是super(5);
此时执行的是A的构造函数,A的构造函数调用的是setValue()方法,由于B重写了A的这个方法,
所以!!!执行的是B的 setValue()方法。
即传入的参数是2*5=10
此时,因为super,所以调用的是父类的 setValue()方法,即value=10
第一行执行完毕。
第二行是 setValue(getValue()-3);
B没有getValue()方法,故执行父类的此方法,
try返回的是value=10+1=11,保存在临时栈中
finally中调用this的方法,这个this指的是B的对象,又重写,故就是B的 setValue()方法
value=2*11=22,第一个打印到屏幕上的数字
接下来参数 getValue()-3=11-3=8
传入B的 setValue()方法
此时value=2*8=16
至此,new B()执行结束

new B(). getValue()
B没有 getValue(),故执行A的 getValue()
try返回16+1=17,保存到临时栈中
finally调用B的 setValue()方法
value=17*2=34,第二个打印到屏幕上面的数字
最后主函数打印返回值,也就是try保存到临时栈的17


7.Which four statements are true ?

class A {}
class B extends A {}
class C extends A {}
class D extends B {}
  • The type List < A > is assignable to List.
  • The type List< B >is assignable to List < A > .
  • The type List < Object > is assignable to List < ? > .
  • The type List < D > is assignable to List < ?extends B > .
  • The type List < ?extends A > is assignable to List < A > .
  • The type List < Object > is assignable to any List reference.
  • The type List < ?extends B > is assignable to List < ?extends A > .

解析:
1. 只看尖括号里的!!!明确点和范围两个概念
2. 如果尖括号里的是一个类,那么尖括号里的就是一个点,比如List< A > ,List < B > ,List < Object >
3. 如果尖括号里面带有问号,那么代表一个范围,< ? extends A > 代表小于等于A的范围,< ? super A >代表大于等于A的范围,< ? > 代表全部范围。
4. 尖括号里的所有点之间的赋值都是错的,除非是两个相同的点
5. 尖括号小范围赋值给大范围,对!;大范围赋值给小范围,错!;如果某个点包含在某个范围里,那么可以赋值,否则,不能赋值!
6. List < ? >和List是相等的,都代表最大范围。
7. List既是点,也是范围,当表示范围时,表示最大范围。


8-6

1.以下程序段,正确的说法是:

String s1="abc"+"def";//1
String s2=new String(s1);//2
if(s1.equals(s2))//3
System.out.println(".equals succeeded");//4
if(s1==s2)//5
System.out.println("==succeeded");//6
  • 行4执行,行6不执行

解析:
这里写图片描述


2.多个线程可同时操作一个数据,为了保证该数据的准确性,可将操作该数据的部分改为()

  • 同步
  • 异步
  • 只读
  • 只写

解析:
1. 并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。其中两种并发关系分别是同步和互斥。
2. 互斥:进程间相互排斥的使用临界资源的现象,就叫互斥
3. 同步:进程间的关系不是相互排斥临界资源的关系,而是相互依赖的关系。进一步说明:就是前一个进程的输出作为后一个进程的输入,当第一个进程没有输出时第二个进程必须等待。具有同步关系的一组并发进程相互发送的信息称为消息或事件。其中并发又有伪并发和真并发,伪并发是指单核处理器的并发,真并发是指多核处理器的并发。
4. 并行:在单处理器中多道程序设计系统中,进程被交替执行,表现出一种并发的外部特征;在多处理器系统中,进程不仅可以交替执行,并且可以重叠执行。在多处理器上的程序才可以实现并行处理。从而可知,并行是针对多处理器而言的。并行是同时发生的多个并发事件,具有并发的含义,但并发不一定并行,也亦是说并发事件之间不一定要同一时刻发生
5. 多线程:多线程是程序设计的逻辑层概念,它是进程中并发运行的一段代码。多线程可以实现线程间的切换执行。
6. 异步:异步和同步是相对的,同步就是顺序执行,执行完一个再执行下一个,需要等待,协调运行。异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一个线程的完成,从而可以让主线程干其它的事情。

异步和多线程并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段。异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事情。实现异步可以采用多线程技术或交给另外的进程来处理。


3.下列描述错误的是

  • SQL语言又称为结构化查询语言
  • Java中“static”关键字表面那个一个成员变量或者是成员方法可以在没有所属类的实例变量的情况下被访问
  • 面向对象开发中,引用传递意味着传递的并不是实际的对象,而是对象的引用,因此,外部对引用对象所做的改变不会反映到所引用的对象上
  • Java是强类型语言,JavaScript是弱类型语言
  • 面向对象的三大特征:封装,继承,多态

解析:
引用代表引用的是实际的对象,对引用的修改就是对对象的修改,可以理解为两把钥匙打开同一扇门。

值传递,传递的是原来值得副本。
引用传递,一般的引用类型在进行传递的时候,一开始形参和实参都是指向同一个地址的,这个时候形参对对象的改变会影响到实参。

传值传参的时候,我们在函数中改变了参数的值,其对应的变量的值并不改变,值类型传参就是将变量保存的内容复制到函数的形参中,他们两个是不同的变量,只不过保存的内容相同罢了
引用传参保存的是一个地址,这个地址里保存的是变量的具体值,而引用类型作为参数的时候,是将变量保存的地址值赋值到参数变量里,这样他们都指向了同一个内容,这样我们改变参数的成员的话,那么相应的变量的成员也会改变。


4.关键字super的作用是?

  • 用来访问父类被隐藏的非私有成员变量
  • 用来调用父类中被重写的方法
  • 用来调用父类的构造器
  • 以上都是

解析:
如果在子类中对父类继承来的成员变量进行重新定义,即出现了子类变量对父类变量的隐藏。
super代表父类对应的对象


5.有如下一段代码,请选择其运行结果

public class StringDemo{
  private static final String MESSAGE="taobao";
  public static void main(String [] args) {
    String a ="tao"+"bao";
    String b="tao";
    String c="bao";
    System.out.println(a==MESSAGE);
    System.out.println((b+c)==MESSAGE);
  }
}
  • true,false

解析:
首先判断a==MESSAGE同一份字符串常量在内存中只有一份,因此是同一地址,返回true
再次比较(b+c)==MESSAGE这相当于new String(b+c)==MESSAGE这里new了一个String对象,所以返回false


8-7

1.类方法中可以直接调用对象变量

  • 正确
  • 错误

解析:
静态方法中不能调用对象的变量,因为静态方法在类加载时就初始化,对象变量需要在新建对象之后才能使用


2.异常:

1.运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常),IndexOutOfException(下标越界异常),这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生
运行时异常的特点是Java编译器不会检查他,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获他,也没有throws子句声明抛出它,也会编译通过

2.非运行时异常(编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException,SQLiteException等以及用户自定义的Exception,一般情况下不自定义检查异常。


8-8

1.关于HashMap与HashTable,以下说法正确的是()

  • 两者都是用key-value方式获取数据
  • Hashtable允许null值作为key和value,而HashMap不可以
  • hashMap不是同步的,而Hashtable是同步的
  • 迭代HashMap采用快速失败机制,而Hashtable不是

解析:
A:HashMap和HashTable两个类都实现了Map接口,二者保存K-V对
B:HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)
C:HashTable的方法是Synchronize的,而HashMap不是,在多个线程访问HashTable时,不需要自己为它的方法实现同步,而HashMap就必须提供外同步


2.ArrayLists和LinkedList的区别,下述说法正确的有

  • ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构
  • 对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针
  • 对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据
  • ArrayList的控件浪费主要体现在在List列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都要消耗相当的空间。

解析:
A:ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 // 正确,这里的所谓动态数组并不是“有多少个元素就申请多少个空间”的意思,而是如果没指定数据大小,则申请默认大小为10的数据,当元素个数增加,数据无法存储时,系统会另申请一个长度为当前长度1.5倍的数组,然后把之前的数据拷贝到新建的数组
B:对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。 // 正确,ArrayList是数组,所以,直接定位到相应位置取元素,LinkedList是链表,所以需要从前往后遍历。
C:对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。// 正确 ,ArrayList的新增和删除就是数组的新增和删除,LinkList与链表一致。
D:ArrayList的空间浪费主要体现在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。
// 正确,因为ArrayList空间的增长率为1.5倍,所以很可能留下一部分空间是没有用到的,因此,会造成浪费的情况。对于LinkedList的话,优于每个节点都需要额外的指针。


3.

Java中true,false,null在Java中不是关键字,也不是保留字,它们只是显示常量值,但是你在程序中不能使用他们作为标识符。


4.下列代码片段中,存在编译错误的语句是

byte b1=1,b2=2,b3,b6,b8;
final byte b4=4,b5=6,b7;
b3=(b1+b2);  /*语句1*/
b6=b4+b5;    /*语句2*/
b8=(b1+b4);  /*语句3*/
b7=(b2+b5);  /*语句4*/
System.out.println(b3+b6);
  • 语句1,语句3,语句4

解析:
Java表达式转型规则,由低到高转换
1. 所有的byte,short,char型的值将被提升为int型
2. 如果有一个操作数是long型,计算结果是long型
3. 如果有一个操作数是float型,计算结果是float型
4. 如果有一个操作数是double型,计算结果是double型
5. 被final修饰的变量不会自动改变类型,当2个final修饰相操作时,结果会根据左边变量的类型而转换

语句1错误:b3=(b1+b2);自动转为int,所以正确写法为b3=(byte)(b1+b2);或者将b3定义为int;
语句2正确:b6=b4+b5;b4、b5为final类型,不会自动提升,所有和的类型视左边变量类型而定,即b6可以是任意数值类型;
语句3错误:b8=(b1+b4);虽然b4不会自动提升,但b1仍会自动提升,所以结果需要强转,b8=(byte)(b1+b4);
语句4错误:b7=(b2+b5); 同上。同时注意b7是final修饰,即只可赋值一次,便不可再改变。


8-9

1.Java程序中使用赋值运算符进行对象赋值时,可以的到两个完全相同的对象

  • 错误

解析:
比如A=B,只是把A对象的地址指向B对象的地址,所以其实对象只有一个,而不是产生了两个对象。


2.

Hash家族分为几个小家族,分别是HashMap,Hashtable,TreeMap。
HashMap准许自己的键值对都可以为null
Hashtable与TreeMap**允许了自己的键值对可以为”“**,但是不能触碰null的界限。


3.

finally一定会在return之前执行,但是如果finally使用了return或者throw语句,将会使try-catch中的return或者throw失效。
即,finally中return会覆盖try-catch中的return语句


8-10

1.程序Demo.java编译运行后输出的结果是:

public class Demo{
    int x=1int y;
    public static void main(String [] args){

        int z=2;

        Demo t=new Demo();
        System.out.println(t.x+t.y+z);
    }
}
  • 3

解析:
成员变量未初始化默认为0
局部变量参与运算前是必须要初始化的,比如下面的到吗就会编译出错,提示y必须要初始化!

public static void main(String[] args) {
    int x = 1;
    int y;
    int z = x + y;
}

2.我们在程序中经常使用“System.out.println()”来输出信息,语句中的System是包名,out是类名,println是方法名

解析:
System是java.lang中的类,out为System中的一个静态成员变量,out是java.io.PrintStream类的对象,而println()是java.io.PrintStream类的方法,所以可以调用类.静态方法.println()方法


3.抽象方法的访问权限默认都是Public

  • 正确
  • 错误

解析:
Java1.8,抽象类中的抽象方法和非抽象方法在不加修饰符的情况下,都是默认的default

关于抽象类
JDK 1.8以前,抽象类的方法默认访问权限为protected
JDK 1.8时,抽象类的方法默认访问权限变为default

关于接口
JDK 1.8以前,接口中的方法必须是public的
JDK 1.8时,接口中的方法可以是public的,也可以是default的
JDK 1.9时,接口中的方法可以是private的


4.对于子类的构造函数说明,下列叙述中错误的是

  • 子类不能继承父类的无参构造函数
  • 子类可以在自己的构造函数中使用,super关键字来调用父类的含参数构造函数,但这个调用语句必须是子类构造函数的第一个可执行语句
  • 在创建子类的对象时,若不含带参构造函数,将先执行父类的无参构造函数,然后再执行自己的无参构造函数
  • 子类不但可以继承父类的无参构造函数,也可以继承父类的有参构造函数。

解析:
构造函数不能被继承,构造方法只能被显示或隐式的调用


5.以下程序的输出结果为?

class Base{
    public Base(String s){
        System.out.print("B");
    }
}
public class Derived extends Base{
    public Derived (String s) {
        System.out.print("D");
    }
    public static void main(String[] args){
        new Derived("C");
    }
}
  • BD
  • 编译错误

解析:
子类构造方法再调用时必须先调用父类的,由于父类没有无参构造,必须再子类中显示调用,修改子类构造方法如下即可:

public Derived(String s){
        super("s");
        System.out.print("D");
    }

8-11

1.以下声明合法的是?

  • default String s
  • public final static native int w( )
  • abstract double d
  • abstract final double hyperbolicCosine( )

解析:
A:Java的访问权限有public,protected,private,default,default不能修饰变量
C:普通变量不能使用abstract修饰,abstract一般修饰 方法和类
D:被定义为abstract的类需要被继承,而final不需要被继承,冲突


8-12

1.下列代码执行结果是?

public class Test {
    public static int a = 1;
    public static void main(String[] args) {
        int a = 10;
        a++; Test.a++;
        Test t=new Test();
        System.out.println("a=" + a + " t.a=" + t.a);
    }
}
  • a=11,t.a=2

解析:
Java采用局部优先的思想。局部变量可以和成员变量相同,使用标识符调用时,优先使用局部变量


8-13

1.哪个说法错误:

  • 一个文件中只能有一个public class
  • 一个文件中可以有多个类
  • 一个类中可以有两个main方法
  • 若类中只含有一个main方法,则必须是public的

一个文件中可以有多个public class,即外部类为public,还可以有public的内部类
一个文件中可以有多个类,可以是多个并列的类,也可以是外部类,内部类结合
一个类中,可以有多个main方法,这是重载,但是public static void main(String[] args)的方法只能有一个
类中,可以有main方法,也可以没有main方法,而有一个main()方法的时候,也可以是任意访问权限。因为这个类不一定要执行,可以只是辅助类


2.数据的强制类型转换

自动转换按从低到高的类型转换;强制类型转换必须在代码中声明,转换顺序不受限制
自动转换按从低到高的顺序转换
byte,short,char->int->long->float->double


8-14

1.下面有关java classloader说法错误的是?

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

解析:
JVM在判断两个class是否相等时,不仅要判断两个类名是否相等,而且要判断是否由同一个类加载器实例加载的


2 .假设有以下代码:

String s=”hello”;
String t=”hello”;
char c[] ={‘h’,’e’,’l’,’l’,’o’};

下列选项中返回false的语句是:

  • s.equals(t);
  • t.equals(c);
  • s==t;
  • t.equals(new String(“hello”);

解析:
char c[]是一个数组,而且数组在堆上


3.初始化过程:

  1. 初始化父类的静态成员变量和静态代码块
  2. 初始化子类中的静态成员变量和静态代码块
  3. 初始化父类的普通成员变量和代码块,再执行父类的构造方法
  4. 初始化子类的普通成员变量和代码块,再执行子类的构造方法

4.下面论述正确的是:

  • 如果两个对象的hashcode相同,那么它们作为同一个HashMap的key时,必然返回同样的值
  • 如果a,b的hashcode相同,那么a.equals(b)必须返回true
  • 对于一个类,其所有对象的hashcode必须不同
  • 如果a.equals(b)返回true,那么a,b两个对象的hashcode必须相同

解析:
hashcode和equals的约定关系如下:
1. 如果两个对象相等,那么它们一定有相同的哈希值(hashCode)
2. 如果两个对象的哈希值相等,那么这两个对象有可能相等也有可能不相等(需再通过equals来判断)


5.What is the result of compiling and executing the following fragment of code:

Boolean flag = false;
if (flag = true)
{
    System.out.println(“true”);
}
else
{
    System.out.println(“false”);
}
  • The text“true” is displayed.

解析:
Java赋值运算是有返回值的,赋了什么值,就返回什么值。


6.有关hashMap和hashTable的区别,说法正确的是:

  • HashMap和Hashtable都实现了Map接口
  • HashMap是非synchronized,而Hashtable是synchronized
  • HashTable使用Enumeration,HashMap使用Iterator
  • Hashtable直接使用对象的hashCode,Hash Map重新计算hash值,而且用于代替求模。

7.线程安全:

Vector相当于一个线程安全的List
HashMap是非线程安全的,其对应的线程安全类是HashTable
Arraylist是非线程安全的,其对应的线程安全类是Vector
StringBuffer是线程安全的,相当于一个线程安全的StringBuilder
Properties实现了Map接口,是线程安全的


8-15

1.Java编程中,Java编译器会将Java程序转换为

  • 字节码
  • 可执行代码
  • 机器代码
  • 以上都不对

解析:
编译器将Java源代码编译成字节码class文件
类加载到JVM里面后,执行引擎把字节码转为可执行代码
执行的过程,再把可执行代码转为机器码,由底部的操作系统完成执行


2.下列代码的输出结果是

boolean b=true?false:true==true?false:true;
System.out.println(b);
  • false

解析:
== 优先级高于三目运算


3.Which statement is true?

void waitForSignal()
{
    Object obj = new Object();
    synchronized(Thread.currentThread())
    {
        obj.wait();
        obj.notify();
    }
}
  • This code may throw an InterruptedException

解析:
两个错误:
1. wait()方法要以try/catch包裹,或是掷出InterruptedException才行
2. synchronized的目标与wait()方法的物件不相同,会有IllegalMonitorStateException,不过InterruptedException会先出现。


8-16

1.下面程序的输出是:

String x="fmn";
x.toUpperCase();
String y=x.replace('f','F');
y=y+"wxy";
System.out.println(y);
  • Fmnwxy

解析:
String x = “fmn”;”fmn”是在常量池里的不可变对象
x.toUpperCase();在堆中new一个”FMN”对象,但无任何引用指向它
String y = x.replace(“f”,”F”);在堆中new一个“FMN”对象,y指向它
y=y+”wxy”;在堆中重新new一个“Fmnwxy”对象,修改y指向,现在y指向它


2.下列说法正确的是:

public class Test
{
    public int x;
    public static void main(String []args)
    {
        System. out. println("Value is" + x);
    }
}
  • 非静态变量不能够被静态方法引用
  • 程序会打出 “Value is 0”
  • 程序会抛出 NullPointerException
  • 编译器会抛出 “possible reference before assignment”的错误

解析:
非静态成员变量只能被类的实例化对象引用,因此这里在静态方法中访问x会造成编译错误


3.下列Java代码中的变量a,b,c分别在内存的__存储区存放?

class A {
    private String a = “aa”;
    public boolean methodB() {
        String b = “bb”;
        final String c = “cc”;
    }
}
  • 堆区、栈区、栈区

解析:
a是类中的成员变量,存放在堆区
b,c都是方法中的局部变量,存放在栈区
为什么不是方法区?因为题目问的是变量存放位置,而不是变量指向内容的存放位置。
堆区:只存放类对象,线程共享
方法区:又叫静态存储区,存放class文件和静态数据,线程共享
栈区:存放方法局部变量,基本类型变量区,执行环境上下文,操作执行区,线程不共享。


4.

  1. 静态内部类才可以声明静态方法
  2. 静态方法不可以使用非静态变量
  3. 抽象方法不可以有函数体

8-17

1.接口不能扩展(继承)多个接口

  • 错误

解析:
Java中类是单继承,但接口可以多继承。
Interfere1 extends Interface2,Interface3…


2.下面有关Java的一些细节问题,描述错误的是

  • 构造方法不需要同步化
  • 一个子类不可以覆盖掉父类的同步方法
  • 定义在接口中的方法默认是public的
  • 容器保存的是对象的引用

解析:
如果父类中的某个方法使用了synchronized关键字,而子类中也覆盖了这个方法,默认情况下子类中的这个方法并不是同步的,必须显示的在子类的这个方法中加上synchronized关键字才可。当然,也可以在子类中调用父类中相应的方法,这样虽然子类中的方法并不是同步的,但子类调用了父类中的同步方法,也就相当子类也同步


3.

低级向高级是隐式类型转换
高级向低级必须强制类型转换,
byte

4.以下哪些类是线程安全?

  • Vesctor
  • HashMap
  • ArrayList
  • StringBuffer
  • Properties

解析:
A:Vector相当于一个线程安全的List
B:HashMap是非线程安全的,其对应的线程安全类HashTable
C:ArrayList是非线程安全的,其对应的线程安全类是Vector
D:StringBuffer是线程安全的,相当于一个线程安全的StringBuffer
E:Properties实现Map接口,是线程安全


8-18

1.在Java中,下列标示符合法的是

  • 3kyou
  • @163
  • name
  • while

解析:
Java中,标识符,指用于给变量,类,方法等命名的名称。
1. 标识以数字,字符,下划线及$美元符号,组成(不包括@,%,空格等),不能以数字开头
2. 不能与Java关键字重复
3. 严格区分大小写


2.在Java中,无论在何处调用,使用静态属性必须以类名做前缀

  • 正确
  • 错误

解析:
1. 如果是本类使用,可以直接就用静态变量名
2. 如果是其它类使用,可以使用类名来调用,也可以创建一个实例对象来调用
3. 如果静态变量所在的类是静态类,那么不管在本类里或在其他外部类,都可以直接使用静态变量名。


3.下列外部类定义中,不正确的是:

  • class x{…}
  • class x extends y{…}
  • static class x implements y1,y2{…}
  • public class x extends Applet { …. }

解析:
内部类可以是静态static的,也可以用public,default,protected和private修饰
外部类的修饰符只能是public,abstract,final


猜你喜欢

转载自blog.csdn.net/Adonis044/article/details/81325319