8-1
1.Java语言中,按照一定格式生成程序的文档的工具是?
- javac
- javah
- javadoc
- jar
解析:
- jar:将许多文件组合成一个jar文件
- javac:编译
- javadoc:它从程序源代码中抽取类,方法,成员等注释形成一个和源代码配套的API帮助文档
- javah:把Java代码声明的JNI方法转化成C/C++头文件。
2.
- 静态内部类才可以声明静态方法
- 静态方法不可以使用非静态变量
- 抽象方法不可以有函数体
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的区别:
- 这两个方法来自不同的类分别是Thread和Object
- 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得敏感词线程可以使用同步控制块或方法
- 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定义如下:
1.class Parent{
2.public float aFun(float a, float b) { }
3.}
4.class Child extends Parent{
5.
6.}
哪个插入到行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中,数据类型分为基本数据(或叫做原生类,内置类型)和引用数据类型。
那么原生类为基本数据类型,有八种,这样转换的时候就有表达范围问题
- 所占位数少的可以转换为所占位数多的类型,比如byte转char,char转int等
- 而所占位数多的转为所占位数少的默认情况下不能实现转换,需要强制类型转换,这样可能会丢失一部分原始数据
- 此外,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
解析:
- 基本型和基本封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,显然返回true
- 两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否则返回false,这跟Integer.valueOf()的缓冲对象有关。
- 两个基本型的封装进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true。
- 基本型封装类调用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=1;
int 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.初始化过程:
- 初始化父类的静态成员变量和静态代码块
- 初始化子类中的静态成员变量和静态代码块
- 初始化父类的普通成员变量和代码块,再执行父类的构造方法
- 初始化子类的普通成员变量和代码块,再执行子类的构造方法
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.
- 静态内部类才可以声明静态方法
- 静态方法不可以使用非静态变量
- 抽象方法不可以有函数体
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
8-19
1.以下有关构造方法的说法正确的是
- 一个类的构造方法可以有多个
- 构造方法在类定义时被调用
- 构造方法只能由对象中的其他方法调用
- 构造方法可以和类同名,也可以和类名不同
解析:
A:一个类有多个构造方法比那是重载的表现。重载参数列表不同,A正确
B:构造方法是再对象创建时就被调用,用于初始化
C:构造方法是给与之对应的对象进行初始化,初始化的动作只执行一次
D:构造方法必须与所在类的名称同名
2.Java语言中,如果”xyz”没有被创建过,String s =new String(“xyz”);创建了几个string object?
- 2
解析:
第一个在堆中
第二个在字符串常量池中
如果在Java字符串常量池中已经存在,就只会创建一个
3.String str1 = “abc”,”abc”分配在内存哪个区域?
- 堆
- 栈
- 字符串常量区
- 寄存器
解析:
用new创建的对象在堆区
函数中的临时变量在栈区
Java中的字符串在字符串常量区
栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
堆:存放用New产生的数据
静态域:存放在对象中用static定义的静态成员
常量池:存放常量
4.下面关于abstract关键字描述错误的是()
- abstract关键字可以修饰类或方法
- final类的方法都不能是abstract,因为final类不能有子类
- abstract类不能实例化
- abstract类的子类必须实现其超类的所有abstract方法
解析:
abstract类的子类可以实现超类所有的抽象方法,也可以实现超类的部分抽象方法
如果超类还有抽象方法未被子类实现,那么该子类也是abstract
5.
- 父类静态对象,父类静态代码块
- 子类静态对象,子类静态代码块
- 父类非静态对象,父类非静态代码块
- 父类构造方法
- 子类非静态对象,子类非静态代码块
- 子类构造函数
8-20
1.有以下程序片段且Interesting不是内部类,下列哪个选项不能插入到行1
1.
2.public class Interesting{
3. // 省略代码
4.}
- import java.awt.*;
- package mypackage;
- class OtherClass{ }
- public class MyClass{ }
解析:
一个.java文件中,可以有多个类,包括内部类和外部类。考虑到内部类的原因,一个.java文件中可以有多个public类但是对于外部类而言,一个.java文件必须只能有一个public类,同时这个类的类名必须和.java文件名一致(包括大小写)
2.以下关于集合类ArrayList,LinkedList,HashMap描述错误的是:
- HashMap实现Map接口,它允许任何类型的键和值对象,并允许将null用作键或值
- ArrayList和LinkedList均实现了List接口
- 添加和删除元素时,ArrayList表现更佳
- ArrayList的访问速度比LinkedList快
解析:
A:HashMap实现了Map接口,它的key和value都可以是null,但是Hashtable中,key和value都不能是null
B:ArrayList与LinkedList都实现了List接口,继承了AbstractList类
C:ArrayList底层是动态数组的实现,随机位置添加和删除,都需要移动数组的数据,而LinkedList底层是双向链表,只需要修改Node节点的引用
D:随机访问数组比链表快
3.抽象类方法的访问权限默认都是public
- 正确
- 错误
解析:
JDK以后,抽象类或者抽象方法改为默认dedault
4.jre判断程序是否执行结束的标准是
- 所有的前台线程执行完毕
5.以下哪些类是线程安全的
- Vector
- StringBuffer
- Properties
解析:
A,Vector相当于一个线程安全的List
B,HashMap是非线程安全的,其对应的线程安全类是HashTable
C,Arraylist是非线程安全的,其对应的线程安全类是Vector
D,StringBuffer是线程安全的,相当于一个线程安全的StringBuilder
E,Properties继承了Hashtable,是线程安全的
8-21
1.Which expression returns true?
public class Cat
{
long length;
public Cat(long l)
{
length = 1;
}
public static void main(String arg[])
{
Cat c1, c2, c3;
c1 = new Cat(10L);
c2 = new Cat(10L);
c3 = c2;
long m = 21L;
}
}
- c1==c2
- c2==3
- m==c1
- c1.equals(m)
解析:
A ,c1和c2是两个参数相同的不同对象,c1!=c2,返回false
B ,c2和c3指向同一个引用,所以c2==c3,返回true
C, m与c1是不同类型,不相等,返回false
D,c1没有定义equals方法,默认调用Object类的equals方法,返回false
new关键字生成的对象存在堆内存中,c1和c2指向的是不同的对象,==判断两个变量是否相等,若为基本类型,且都是数值类型返回true,引用类型则必须指向同一个对象才会返回true,故c1和从c2不相等;
c2直接赋值给c3,二者指向的是同一个堆内对象,故二者相等
m为基本类型,c1为对象,二者不相等;
2.下面代码的输出结果是什么?
public class ZeroTest {
public static void main(String[] args) {
try{
int i = 100 / 0;
System.out.print(i);
}catch(Exception e){
System.out.print(1);
throw new RuntimeException();
}finally{
System.out.print(2);
}
System.out.print(3);
}
}
- 12
解析:
try catch 是直接处理,处理完成之后程序继续往下执行,throw则是将异常抛给它的上一级处理,程序便不往下执行了,throw则是将异常抛给它的上一级处理,程序便不往下执行了。
本题的catch 语句块里面,打印完1之后,又抛出一个RuntimeException,程序并没有处理他,而是直接抛出,因此执行完finally语句块之后,程序终止了
3.以下结果输出位false的是
Integer i01 = 59;
int i02 = 59;
Integer i03 =Integer.valueOf(59);
Integer i04 = new Integer(59);
- System.out.println(i03 == i04);
- System.out.println(i02 == i04);
解析:
Integer的valueOf方法
这个方法就是返回一个Integer对象,只是在返回之前,看作了一个判断,判断当前i的值是否在[-128,127]区间,且IntegerCache中是否存在此对象,如果存在,则直接返回引用,否则,创建一个新的对象。
这里,程序初次运行,没有59,所以直接创建一个新对象
- int i02=59;//基本类型,存储在栈中
- Integer i03=Integer.valueOf(59)//因为IntegerCache中已经存在此对象,所以,直接返回引用
- Integer i04 = new Integer(59)//直接创建一个新对象
- System. out .println(i01== i02);i01 是 Integer 对象, i02 是 int ,这里比较的不是地址,而是值。 Integer 会自动拆箱成 int ,然后进行值的比较。所以,为真。
- System. out .println(i01== i03); 因为 i03 返回的是 i01 的引用,所以,为真。
- System. out .println(i03==i04); 因为 i04 是重新创建的对象,所以 i03,i04 是指向不同的对象,因此比较结果为假。
- System. out .println(i02== i04); 因为 i02 是基本类型,所以此时 i04 会自动拆箱,进行值比较,所以,结果为真。
4.以下代码执行的结果显示是多少( )?
public class Demo {
class Super{
int flag=1;
Super(){test();}
void test(){
System.out.println("Super.test() flag="+flag);
}
}
class Sub extends Super{
Sub(int i){
flag=i;
System.out.println("Sub.Sub()flag="+flag);
}
void test(){
System.out.println("Sub.test()flag="+flag);
}
}
public static void main(String[] args) {
new Demo().new Sub(5);
}
}
- Sub.test() flag=1;Sub.Sub() flag=5
- Sub.Sub() flag=5;Sub.test() flag=5
解析:
在继承中代码的执行顺序为:
1. 父类静态对象,父类静态代码块
2. 子类静态对象,子类静态代码块
3. 父类非静态对象,父类非静态代码块
4. 父类构造函数
5. 子类非静态对象,子类非静态代码块
6. 子类构造函数
8-24
1.如何跳出Array的foreach循环?
- break
- return true
- return false
- 以上都不是
解析:
2.在main()方法中给出的整型数组,如果将其写到一个文件中,需要()
- 建立数据字节输出流
- 建立数据字节输入流
3.以下叙述正确的是
- 实例方法可直接调用超类的实例方法
- 实例方法可直接调用超类的类方法
- 实例方法可直接调用子类的实例方法
- 实例方法可直接调用本类的实例方法
解析:
A:类的实例方法是与该类的实例对象相关联的,不能直接调用,只能通过创建超类的一个实例对象,再进行调用
B:当父类的类方法定义为private时,对子类是不可见的,所以子类无法调用。
C:子类具体的实例方法对父类是不可见的,所以无法直接调用,只能通过创建子类的一个实例对象,再进行调用
D:实例方法可以调用自己类中的实例方法。
8-25
1.Java程序中使用赋值运算符进行对象赋值时,可以得到两个完全相同的对象
- 正确
- 错误
解析:
只是在栈中两个变量的符号引用指向了同一个对象的地址,不是产生了两个对象。
2.关于Socket通信编程,以下描述错误的是
- 服务器端通过new ServerSocket()创建TCP连接对象
- 服务器端通过TCP连接对象调用accept()方法创建通信的Socket对象
- 客户端通过new Socket()方法创建通信的Socket对象
- 客户端通过new ServerSocket()创建TCP连接对象
解析:
Socket套接字
就是源Ip地址,目标Ip地址,源端口号和目标端口号的组合
3.如果语句通过算术运算和逻辑运算之后i和j的结果是
int i=0;
int j=0;
if((++i>0)||(++j>0))
{
//打印出i和j的值。
}
- i=1;j=1;
- i=1;j=0;
解析:
&&和||为短路与,短路或
&&若前面的表达式为false,整个逻辑表达式为false,所以后面的表达式无论true和false都无法影响整个表达式的逻辑结果,所以为了提高代码执行速率,后面的表达式就不会执行。
同理,若前面为true,则后面的表达式无需计算
&和|为不短路与,不短路或
无论什么情况,前面的和后面的都要执行
4.在Java多态调用中,new的是那一个类就是调用的哪个类的方法
- 错
解析:
public class Father {
public void say(){
System.out.println("father");
}
public static void action(){
System.out.println("爸爸打儿子!");
}
}
public class Son extends Father{
public void say() {
System.out.println("son");
}
public static void action(){
System.out.println("打打!");
}
public static void main(String[] args) {
Father f=new Son();
f.say();
f.action();
}
}
输出:son
爸爸打儿子!
当调用say方法执行的是Son的方法,也就是重写say方法
而当调用action方法时,执行的是father的方法
普通方法:运用的是动态单分配,是根据new的类型确定对象,从而确定调用的方法
静态方法:运用的是静态多分配,即根据静态类型确定对象,因此不是根据new的类型确定调用的方法。
5.对于子类的构造函数,下列叙述错误的是
- 子类不能继承父类的无参构造函数
- 子类可以在自己的构造函数中使用super关键字来调用父类的含参构造函数,但是这个调用语句必须是子类构造函数的第一个可执行语句
- 在创建子类的对象时,若不含带参构造函数,将先执行父类的无参构造函数,然后再执行自己的无参构造函数
- 子类不但可以继承父类的无参构造函数,也可以继承父类的有参构造函数。
解析:
构造函数不能被继承,构造方法只能被显示或隐式的调用
6.用命令方式运行以下代码的运行结果是
public class f{
public static void main(String[] args){
String foo1 = args[1];
String foo2 = args[2];
String foo3 = args[3];
}
}
命令是:java T11 a b c
- 程序编译错误
- abc
- 程序运行错误
- t11
解析:
运行Java命令,没有T11对应的类,会报找不到或者无法加载主类。
7.有关hashMap跟hashTable的区别,说法正确的是?
- HashMap和Hashtable都实现了Map接口
- HashMap是非synchronized,而Hashtable是synchronized
- HashTable使用Enumeration,HahsMap使用Iterator
- Hashtable直接使用对象的hashcode,HashMap重新计算hash值,而且用与代替求模
8-26
1.
B继承A,new B会:
1. 把A的静态的执行完,执行B的静态的
2. 再执行A的初始化代码块,构造函数
3. 再执行B的初始化代码块,构造函数
2.下列选项中符合Java命名规则的标识符是
- 2japro
- &Class
- const
- _123
解析:
除去Java中关键字,Java中标识符是:字下美人数
字母——下划线——美元符号——人民币——数字
数字不能放首位
3.如下代码输出结果是什么
public class Test {
public int aMethod(){
static int i = 0;
i++;
return i;
}
public static void main(String args[]){
Test test = new Test();
test.aMethod();
int j = test.aMethod();
System.out.println(j);
}
}
- 0
- 1
- 2
- 编译失败
解析:
静态变量只能在类主体中定义,不能在方法中定义。
静态变量属于类所有而不属于方法
4.在Java7中,下列哪些说法是正确的?
- ConcurrentHashMap使用synchronized关键字保证线程安全
- HashMap实现了Collection接口
- Arrays.asList方法返回java.util.ArrayList对象
- SimpleDateFormat对象是线程不安全的
解析:
hashMap在单线程中使用大大提高效率,在多线程的情况下使用hashTable来确保安全。
hashTable中使用synchronized关键字来实现安全机制,但是synchronized是对整张hash表进行锁定即让线程独享整张hash表,在安全同时造成了浪费。
concurrentHashMap采用分段加锁的机制来确保安全。
Arrays.asList():将一个数组转化为一个List对象,这个方法会返回一个ArrayList类型的对象,这个ArrayList类并非java.util.ArrayList类,而是Arrays类的静态内部类。用这个对象对列表进行CRUD操作,会报UnsupportedOperationException异常。
5.关于访问权限说法正确的是?
- 类定义前面可以修饰public,protected和private
- 内部类前面可以修饰public,protected和private
- 局部内部类前面可以修饰public,protected和private
- 以上说法都不正确
解析:
1. 类只能用public,abstract,final修饰
2. 内部类和成员变量一样可以用所有访问权限修饰符修饰
3. 局部内部类和局部变量一样不能用访问权限修饰符
6.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 code fails to compile at the “if” statement.
- An exception is thrown at run-time at the “if” statement.
- The text“true” is displayed
- The text“false”is displayed.
- Nothing is displayed.
解析:
Boolean修饰的变量为包装类型,初始化值为false,进行赋值时会调用Boolean.valueOf(boolean b)方法自动拆箱为基本数据类型,因此赋值后flag值为true,输出文本true。如果使用==比较,则输出文本false。if的语句比较,除boolean外的其他类型都不能使用赋值语句,否则会提示无法转成布尔值。
7.下列说法正确的是
- 我们直接调用Thread对象的run方法会报异常,所以我们应该使用start方法来开启一个线程
- 一个进程是一个独立的运行环境,可以被看做一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进程。线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源
- synchronized可以解决可见性问题,volatile可以解决原子性问题
- ThreadLocal用于创建线程的本地变量,该变量是线程之间不共享的
解析:
volatile与synchronized的区别:
volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
volatile仅能实现变量的修改可见性,但不具备原子特性,而synchronized则可以保证变量的修改可见性和原子性.
volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.
volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化.
8-27
1.Math.round(11.5) 等于多少 (). Math.round(-11.5) 等于多少 ( ).
- 12,-11
解析:
floor:意味地板,指向下取整,返回不大于它的最大整数
cell:意味天花板,指向上取整,返回不小于它的最小整数
round:意味大约,+0.5然后floor。即当前值+0.5向下取整。
参考
(1)负数
Math.round(-11.6) = -12
Math.round(-11.5) = -11
(2)正数
Math.round(11.5) = 12
Math.round(11.6) = 12
2.关于sleep和wait以下描述错误的是
- sleep是线程类的方法,wait是object的方法
- sleep不释放对象锁,wait放弃对象锁
- sleep暂停线程,但监控状态依然保持,结束后会自动恢复
- wait进入等待锁定池,只有针对此对象发出notify方法获得对象锁进入运行状态
解析:
wait方法会导致对象放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
注意:是准备获取对象锁进入运行状态,而不是立即获得
也就是说,wait进入等待锁定池,只有针对此对象发出notify方法获得对象锁进入“就绪”状态。是就绪状态而不是运行状态
3.根据下面的程序代码,哪些选项的值返回true?
public class Square {
long width;
public Square(long l) {
width = l;
}
public static void main(String arg[]) {
Square a, b, c;
a = new Square(42L);
b = new Square(42L);
c = b;
long s = 42L;
}
}
- a == b
- s == a
- b == c
- a.equals(s)
解析:
D:程序会把s封装成一个Long类型,由于Square没有重写Object的equals方法,所以调用的是Object类的equals方法,源码如下:
public boolean equals(Object obj) {
return (this == obj);
}
其实就是判断两个引用是否相等,所以D错。
4.我们在程序中经常使用“System.out.println()”来输出信息,语句中的System是包名,out是类名,println是方法名。
- 对
- 错
解析:
System是java.lang中的类,out是System中的一个静态成员,out是java.io.PrintStream类的对象,而println()是java.io.PrintStream类的方法。
5.输出是?
class Foo {
final int i;
int j;
public void doSomething() {
System.out.println(++j + i);
}
}
- 0
- 1
- 2
- 不能执行,因为编译有错
解析:
final作为成员对象存在时,必须初始化;但是,如果不初始化,也可以在类的构造函数中初始化。
因为Java允许将数据成员声明为final,却不赋值。但是,blank final必须在使用前初始化,且必须在构造函数中初始化。
6.
父类没有无参构造函数,所以子类需要在自己的构造函数中显示调用父类的构造函数。否则报错。
7.
堆区:只存放类对象,线程共享
方法区:又叫静态存储区,存放class文件和静态数据,线程共享
栈区:存放局部变量,基本类型变量区,执行上下文,操作指令区,线程不共享。
8.Java反射机制主要提供以下哪些功能?
- 在运行时判断一个对象所属的类
- 在运行时构造一个类的对象
- 在运行时判断一个类所具有的成员变量和方法
- 在运行时调用一个对象的方法
解析:
全部正确
普通的Java对象是通过new关键字把对应类的字节码文件加载到内存,然后创建该对象的。
反射是通过一个名为Class的特殊类,用Class.forName(“className”);得到类的字节码对象,然后用newInstance()方法在虚拟机内部构造这个对象(针对无参构造函数)
也就是说,反射机制让我们可以先拿到Java类对应的字节码对象,然后动态的进行任何可能的操作。
使用反射的主要作用是方便程序的扩展。
9.
Java中true,false,null在Java中不是关键字,也不是保留字,它们只是显式常量值,但是你在程序中不能使用它们作为标识符。
8-28
1.下列关于Java并发的说法正确的是
- CopyOnWriteArrayList适用于写多读少的并发场景
- ReadWriteLock适用于读多写少的并发场景
- ConcurrentHashMap的写操作不需要加锁,读操作需要加锁
- 只要在定义int类型的成员变量i的时候加上volatile关键字,那么多线程并发执行i++这样的操作的时候就是线程安全的了
解析:
A:CopyOnWriteArrayList适用于写少读多的并发场景
B:ReadWriteLock即为读写锁,他要求写与写之间互斥,读与写之间互斥,读与读之间可以并发执行。在读多写少的情况下可以提高效率
C:ConcurrentHashMap是同步的HashMap,读写都加锁
D:volatile只保证多线程操作的可见性,不保证原子性
2.下面的类哪些可以处理Unicode字符?
- InputStreamReader
- BufferedReader
- Writer
- PipedInputStream
解析:
简单说,字符流是字节流根据字节流所要求的编码集解析获得的
也就是:字符流=字节流+编码集
所以和字符流有关的类都有操作编码集(Unicode)的能力
后缀是Stream的都是字节流,其他的都是字符流
3.下列选项中正确的方法声明的是?
- protected abstract void f1();
- public final void f1() {}
- static final void fq(){}
- private void f1() {}
解析:
A:抽象方法只可以被public,protected修饰
B:final可以修饰类,方法,变量,分别表示:类不可被继承,方法不能重写,该变量是常量
C:static final可以表达在一起来修饰方法,表示的是该方法是静态的不可重写的方法
D:private修饰方法(很常见)表示私有方法,本类可以访问,外界不能访问
8-30
1.下面属于Java合法变量定义的是?
- final
- 1var1
- _var2
- var3&
标识符:
字母,数字,下划线,$,数字
开头不能是数字不能是关键字
2.What will be printed when you execute the following code?
class C {
C() {
System.out.print("C");
}
}
class A {
C c = new C();
A() {
this("A");
System.out.print("A");
}
A(String s) {
System.out.print(s);
}
}
class Test extends A {
Test() {
super("B");
System.out.print("B");
}
public static void main(String[] args) {
new Test();
}
}
- CBB
- None of the above
解析:
初始化过程是这样的:
1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化;
2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化;
3.其次,初始化父类的普通成员变量和代码块,在执行父类的构造方法;
4.最后,初始化子类的普通成员变量和代码块,在执行子类的构造方法;
(1)初始化父类的普通成员变量和代码块,执行 C c = new C(); 输出C
(2)super(“B”); 表示调用父类的构造方法,不调用父类的无参构造函数,输出B
(3) System.out.print(“B”);
所以输出CBB
注意:
1.是先执行父类的构造函数再执行子类的构造函数,这个执行顺序是没有错的。但是还有一个逻辑顺序,为什么平白无故的执行父类的构造函数呢?因为子类调用了(或默认调用了)父类的构造函数,在逻辑上是子类先执行
2.因为已经显式调用父类带参构造函数super(“B”)了,所以子类调用的父类构造器是A(String s),而不是无参构造器,除非在子类构造器里没有显式调用父类构造器,编译器才在子类构造器为其默认添加super();
3.
finally中return语句会覆盖try-catch中的return语句
4.关于匿名内部类叙述正确的是?
- 匿名内部类可以继承一个基类,不可以实现一个接口
- 匿名内部类不可以定义构造器
- 匿名内部类不能用于形参
- 以上说法都不正确
解析
由于构造器的名字必须与类名相同,而匿名类没有类名,所以匿名类不能有构造器。
1. 使用匿名内部类时,必须继承一个类或实现一个接口
2. 匿名内部类由于没有名字,因此不能定义构造函数
3. 匿名内部类中不能含有静态成员变量和静态方法
5.在java中重写方法应遵循规则的包括()
- 访问修饰符的限制一定要大于被重写方法的访问修饰符
- 可以有不同的访问修饰符
- 参数列表必须完全与被重写的方法相同
- 必须具有不同的参数列表
解析:
总结来说为:
方法名相同,参数类型相同
子类返回类型等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。
详细的说明为:
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。 即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常IOException,但是在重写这个方法的时候不能抛出Exception异常,因为Exception是IOException的父类,只能抛出IOException的子类异常。
8-31
1.在Java中,无论在和处调用,使用静态属性必须以类名做前缀
- 错误
- 正确
解析:
1. 如果是本类使用,可以直接就用静态变量名
2. 如果是其它类使用,可以使用类名来调用,也可以创建一个实例对象来调用
3. 如果静态变量所在的类是静态类,那么不管在本类或其它外部类,都可以直接使用静态变量名
2.关于Java语言中的final关键字的使用,下列说法正确的是
- 在使用final关键字定义的方法里面使用final关键字定义变量。
- 使用final关键字定义变量,必须在变量定义的同时给定变量的具体数值,完成变量初始化。
- final关键字可以用来修饰方法,表明此方法不可以被子类重写。
- 使用final关键字定义变量,必须同时使用static关键字。
解析:
A:在final定义的方法里,不是必须要用final定义变量
B:final定义的变量不是必须要在定义的同时完成初始化,也可以在构造方法中完成初始化
C:final修饰方法,不能被子类重写,但是可以重载
D:final定义变量,可以用static也可以不用
3. 以下会产生信息丢失的类型转换是
- float a=10
- int a=(int)8846.0
- byte a=10; int b=-a
- double d=100
解析:
会产生信息丢失不如说丢失精度,而精度丢失只会发生在从大范围到小范围的转换。
byte 1字节
char 2字节
short 2字节
int 4字节
float 4字节
long 8字节
double 8字节
boolean 1字节
4.如下语句通过算术运算和逻辑运算之后i和 j的结果是( )
int i=0;
int j=0;
if((++i>0)||(++j>0))
{
//打印出i和j的值。
}
- i=1;j=1
- i=1;j=0
解析:
&& || 短路与 和 短路或,所谓的短路就是前部分能确定结果就不执行后面部分
5.This调用语句必须是构造函数中的第一个可执行语句
- 正确
- 错误
解析:
this()才必须是构造函数中的第一个可执行语句,this调用语句并不需要
this()和super()为构造方法,作用是在JVM堆中构建一个对象。因此避免多次创建对象,同一方法内只能调用一次this()或super()。同时为了避免操作对象时对象还没构建成功,需要this()和super()的调用在第一行实现(以此来创建对象)
6.下面那个叙述是正确的
- java中的集合类(如Vector)可以用来存储任何类型的对象,且大小可以自动调整。但需要事先知道所存储对象的类型,才能正常使用。
- 在java中,我们可以用违例(Exception)来抛出一些并非错误的消息,但这样比直接从函数返回一个结果要更大的系统开销。
- java接口包含函数声明和变量声明。
- java中,子类不可以访问父类的私有成员和受保护的成员。
解析:
A:vector是线程安全的ArrayList,在内存中占用连续的空间。初始时有一个初始大小,当数据条数大于这个初始大小后会重写分配一个更大的连续空间。如果Vector定义为保存Object则可以存放任意类型
B:try{}catch{}会增加额外的开销
C:接口中不能有变量,其中的属性必然是常量,只能读不能改,这样才能为实现接口的对象提供一个统一的属性。
D:子类可以访问父类受保护的成员
7.下面关于程序编译说法正确的是
- java语言是编译型语言,会把java程序编译成二进制机器指令直接运行
- java编译出来的目标文件与具体操作系统有关
- java在运行时才进行翻译指令
- java编译出来的目标文件,可以运行在任意jvm上
解析:
注意jvm的版本,好比人穿裤子,一条裤子能被任何人穿上吗