java笔试题 2

来源:互联网 发布:linux setfacl 编辑:程序博客网 时间:2024/06/05 07:44
1.
下面有关文件系统元数据的描述,说法错误的是(D)?
 A.元数据指用来描述一个文件的特征的系统数据,诸如访问权限、文件拥有者以及文件数据块的分布信息等等
 B.我们可以使用stat命令来查看文件更多的元数据信息
 C.Unix/Linux系统允许,多个文件名指向同一个inode号码

 D.文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B,这是文件A就称为文件B的"硬链接"

解析:我们知道文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,如文件大小、创建时间、所有者等信息。在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)才是文件的唯一标识而非文件名。文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。

硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。
若一个 inode 号对应多个文件名,则称这些文件为硬链接。换言之,硬链接就是同一个文件使用了多个别名。
若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软链接
2.
1
2
3
4
5
6
staticString str0="0123456789";
staticString str1="0123456789";
String str2=str1.substring(5);
String str3=newString(str2);
String str4=newString(str3.toCharArray());
str0=null;
假定str0,...,str4后序代码都是只读引用。

Java 7中,以上述代码为基础,在发生过一次FullGC后,上述代码在Heap空间(不包括PermGen)保留的字符数为(C)

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

解析:这是一个关于java的垃圾回收机制的题目。垃圾回收主要针对的是堆区的回收,因为栈区的内存是随着线程而释放的。堆区分为三个区:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法区)。

 年轻代:对象被创建时(new)的对象通常被放在Young(除了一些占据内存比较大的对象),经过一定的Minor GC(针对年轻代的内存回收)还活着的对象会被移动到年老代(一些具体的移动细节省略)。

年老代:就是上述年轻代移动过来的和一些比较大的对象。Minor GC(FullGC)是针对年老代的回收

永久代:存储的是final常量,static变量,常量池。

str3,str4都是直接new的对象,而substring的源代码其实也是new一个string对象返回,如下图:

 public String substring(int beginIndex, int endIndex) {if (beginIndex < 0) {    throw new StringIndexOutOfBoundsException(beginIndex);}if (endIndex > count) {    throw new StringIndexOutOfBoundsException(endIndex);}if (beginIndex > endIndex) {    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);}return ((beginIndex == 0) && (endIndex == count)) ? this :    new String(offset + beginIndex, endIndex - beginIndex, value);    }


经过fullgc之后,年老区的内存回收,则年轻区的占了15个,不算PermGen。所以答案选C

3.

子类A继承父类B
A a = new A(); 则父类B构造函数、父类B静态代码块、父类B非静态代码块、子类A构造函数、子类A静态代码块、子类A非静态代码块 执行的先后顺序是?(C)
A.父类B静态代码块->父类B构造函数->子类A静态代码块->父类B非静态代码块->子类A构造函数->子类A非静态代码块
B.父类B静态代码块->父类B构造函数->父类B非静态代码块->子类A静态代码块->子类A构造函数->子类A非静态代码块
C.父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数
D.父类B构造函数->父类B静态代码块->父类B非静态代码块->子类A静态代码块->子类A构造函数->子类A非静态代码块
解析:会先执行静态代码块,因为静态代码块是类级别的,是在创建对象之前就执行的。因为子类继承了父类,所以父类的静态代码块会先执行,接着执行子类的静态代码块。

     因为构造函数可能要给动态代码块的一些成员变量赋值,所以必须在这之前先执行动态代码块,要不然构造函数会出现相关的成员属性无定义。所以会先执行动态代码块,在执行构造函数。一般先按父类的执行,再按子类的执行。

4.What will be printed when you execute the following code?
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
classC {
   C() {
       System.out.print("C");
   }
}
 
classA {
   C c =newC();
 
   A() {
       this("A");
       System.out.print("A");
   }
 
   A(String s) {
       System.out.print(s);
   }
}
 
classTestextendsA {
   Test() {
       super("B");
       System.out.print("B");
   }
 
   publicstaticvoidmain(String[] args) {
       newTest();
   }

A. BB
B.CBB
C. BAB
D. None of the above
解析:这一题的执行顺序是:父类的动态代码块---->父类的构造方法(如果没有在子类 中写super()方法,则父类用的是默认的构造方法,如果用了则要执行重载的构造方法)->子类的构造方法。其执行顺序可参考上一题。答案是B

5.对于JVM内存配置参数:
-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3
,其最小内存值和Survivor区总大小分别是()
A.5120m,1024m
B.5120m,2048m
C.10240m,1024m
D.10240m,2048m

解析:-Xmx:表示虚拟机的最大可用内存,-Xms表示虚拟机的最小可用内存 ,-Xmn表示年轻代大小。-XXSurvivorRatio=3表示两个Survivor区与一个Eden区为2:3.Surivior=(2/5)*5120=2048.所以选D

6.Math.floor(-8.5)=( )

 A.(float)-8.0
 B.(long)-9
 C.(long)-8
 D.(double)-9.0

解析:

 floor的返回的是一个double

7.对于一个已经不被任何变量引用的对象,当垃圾回收器准备回收该对象所占用的内存时,将自动调用该对象的哪个方法(A)

  A.finalize()方法 B.notify() C.notifyAll() D.hashcode()

 解析:在Java虚拟机的垃圾回收器看来,堆区中的每个对象都可能处于以下三个状态之一。
 可触及状态:当一个对象(假定为Sample对象)被创建后,只要程序中还有引用变量引用它,那么它就始终处于可触及状态。
 可复活状态:当程序不再有任何引用变量引用Sample对象时,它就进入可复活状态。在这个状态中,垃圾回收器会准备释放它占用的内存,在释放之前,会调用它及其他处于可复活状态的对象的finalize()方法,这些finalize()方法有可能使Sample 对象重新转到可触及状态。
 不可触及状态:当Java虚拟机执行完所有可复活对象的finalize()方法后,假如这些方法都没有使Sample对象转到可触及状态,那么Sample对象就进入不可触及状态。只有当对象处于不可触及状态时,垃圾回收器才会真正回收它占用的内存。

notify唤醒线程,与wait()和同步锁synchronized()方法配合使用

8.对文件名为Test.java的java代码描述正确的是()

class Person {    String name = "No name";    public Person(String nm) {        name = nm;    }}class Employee extends Person {    String empID = "0000";    public Employee(String id) {        empID = id;    }}public class Test {    public static void main(String args[]) {        Employee e = new Employee("123");        System.out.println(e.empID);    }}
A.0000 B.123 C.编译出错 D.No name

解析:C.编译出错。

new子类时,先要调用父类的构造方法,这里:如果子类的构造方法第一行没有显式的指定调用父类的哪个构造方法,那么系统将默认调用父类的那个无参的构造方法,这里父类没有无参的构造方法并且子类也没有显式的指出调用父类的哪个带参数的构造方法,所以会编译出错。
如果这里子类的构造方法中的第一行,super(string),就是指定了调用父类的那个构造方法,并且父类也存在这样形式的构造方法,就可以成功编译通过了
new子类时,先要调用父类的构造方法,这里:如果子类的构造方法第一行没有显式的指定调用父类的哪个构造方法,那么系统将默认调用父类的那个无参的构造方法,这里父类没有无参的构造方法并且子类也没有显式的指出调用父类的哪个带参数的构造方法,所以会编译出错。
如果这里子类的构造方法中的第一行,super(string),就是指定了调用父类的那个构造方法,并且父类也存在这样形式的构造方法,就可以成功编译通过了。
9.下面有关final, finally, finalize的区别描述错误的是?(B)
 A.如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承
 B.如果一个方法被声明为final,可以被覆盖
 C.finally在异常处理时提供 finally 块来执行任何清除操作。
 D.Java使用 finalize() 方法在垃圾收集器象从内存中清除出去之前做必要的清理工作
解析:

final

修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。

finally

异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。一般异常处理块需要。

方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。 

Java中所有类都从Object类中继承finalize()方法。

当垃圾回收器(garbage colector)决定回收某对象时,就会运行该对象的finalize()方法。

10.java中,StringBuilder和StringBuffer的区别,下面说法错误的是?(C)
 A.StringBuffer是线程安全的
B.StringBuilder是非线程安全的
C.StringBuffer对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象。
D.效率比较String<StringBuffer<StringBuilder,但是在 String S1 = “This is only a” + “ simple” + “ test”时,String效率最高。

 解析  String:字符串常量

    StringBuffer:字符串变量,是线程安全的

    StringBuilder:字符串变量,非线程安全的

          

1 String s = "abcd";2 s = s+e;3 System.out.print(s);// result : abcde
这里的结果虽然变成了abcde,但是此时的s已经不再是第一行中的s,因为String是常量,所以对于第二行的代码,虚拟机会重新生成一个新的对象s,并且清楚原先的对象s。

都知道的是StringBuffer是线程安全的,stringBuilder是非线程安全的。并且有上述可知,String的效率是非常慢的。所以从执行效率上来看String<StringBuffer<StringBuilder.

StringBuffer对String类型转换的时候,是用的append()方法,这种方法并不是创建一个新的String对象,所以C是错的。



0 0
原创粉丝点击