java错题mark_8

来源:互联网 发布:软件开发需要学什么 编辑:程序博客网 时间:2024/06/03 13:29

一般情况下,以下哪个选项不是关系数据模型与对象模型之间匹配关系?
正确答案: D 你的答案: C (错误)

表对应类
记录对应对象
表的字段对应类的属性
表之间的参考关系对应类之间的依赖关系

目前ORMapping只是规定了数据结构和数据集的映射关系,还没到规定赖关系的阶段



说明输出结果。package test;import java.util.Date; public class SuperTest extends Date{     private static final long serialVersionUID = 1L;     private void test(){        System.out.println(super.getClass().getName());     }     public static void main(String[]args){        new SuperTest().test();     } }正确答案: C   你的答案: A (错误)SuperTestSuperTest.classtest.SuperTesttest.SuperTest.class

TestSuper和Date的getClass都没有重写,他们都是调用Object的getClass,而Object的getClass作用是返回的是运行时的类的名字。这个运行时的类就是当前类,所以
super.getClass().getName()
返回的是test.SuperTest,与Date类无关
要返回Date类的名字需要写super.getClass().getSuperclass()



检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。

package algorithms.com.guan.javajicu;
public class Inc {
public static void main(String[] args) {
Inc inc = new Inc();
int i = 0;
inc.fermin(i);
i= i ++;
System.out.println(i);

} void fermin(int i){    i++; } 

}
正确答案: A 你的答案: C (错误)

0
1
2
3

(每个栈帧中包含了局部变量表和操作数栈,i++只是在局部变量表中进行自增,需要赋值才能放入操作数栈中,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。)

大神回答:
如果你理解JVM的内存模型,就不难理解为什么答案返回的是0,而不是1。
我们单独看问题中的这两句代码。
1
int i = 0; i = i++;
Java虚拟机栈(JVM Stack)描述的是Java方法执行的内存模型,而JVM内存模型是基于“栈帧”的,每个栈帧中都有 局部变量表 和 操作数栈 (还有动态链接、return address等),那么JVM是如何执行这个语句的呢?通过javap大致可以将上面的两行代码翻译成如下的JVM指令执行代码。
0: iconst_0
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: iload_1

接下来分析一下JVM是如何执行的:
第0:将int类型的0入栈,就是放到操作数栈的栈顶
第1:将操作数栈栈顶的值0弹出,保存到局部变量表 index (索引)值为1的位置。(局部变量表也是从0开始的,0位置一般保存当前实例的this引用,当然静态方法例外,因为静态方法是类方法而不是实例方法)
第2:将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)
第3:iinc是对int类型的值进行自增操作,后面第一个数值1表示,局部变量表的index值,说明要对此值执行iinc操作,第二个数值1表示要增加的数值。(这时局部变量表index为1的值因为执行了自增操作变为1了,但是操作数栈中栈顶的值仍然是0)
第6:将操作数栈顶的值弹出(值0),放到局部变量表index为1的位置(旧值:1,新值:0),覆盖了上一步局部变量表的计算结果。
第7:将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)

总结:从执行顺序可以看到,这里第1和第6执行了2次将0赋值给变量i的操作(=号赋值),i++操作是在这两次操作之间执行的,自增操作是对局部变量表中的值进行自增,而栈顶的值没有发生变化,这里需要注意的是保存这个初始值的地方是操作数栈而不是局部变量表,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。

有兴趣的同学可以去了解一下JVM的栈帧(Stack Frame)

关于第二个陷阱(为什么 fermin方法没有影响到i的值 )的解答看下面。
1
inc.fermin(i);
1. java方法之间的参数传递是 值传递 而不是 引用传递
2. 每个方法都会有一个栈帧,栈帧是方法运行时的数据结构。这就是说每个方法都有自己独享的局部变量表。(更严谨的说法其实是每个线程在执行每个方法时都有自己的栈帧,或者叫当前栈帧 current stack frame)
3. 被调用方法fermin()的形式参数int i 实际上是调用方法main()的实际参数 i 的一个副本。
4. 方法之间的参数传递是通过局部变量表实现的,main()方法调用fermin()方法时,传递了2个参数:
第0个隐式参数是当前实例(Inc inc = new Inc(); 就是inc引用的副本,引用/reference 是指向对象的一个地址,32位系统这个地址占用4个字节,也就是用一个Slot来保存对象reference,这里传递的实际上是reference的一个副本而不是 reference本身 );
第1个显示参数是 i 的一个副本。所以 fermin()方法对 i 执行的操作只限定在其方法独享或可见的局部变量表这个范围内,main()方法中局部变量表中的i不受它的影响;

如果main()方法和fermin()方法共享局部变量表的话,那答案的结果就会有所不同。 其实你自己思考一下,就会发现, JVM虚拟机团队这么设计是有道理的。



有关hashMap跟hashTable的区别,说法正确的是?
正确答案: A B C D 你的答案: A B (错误)

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

A正确。Map是一个接口,hashtable,hashmap都是它的实现。
B正确。由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
C正确。 HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
D正确。 哈希值的使用不同,HashTable直接使用对象的hashCode,代码是这样的:
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
而HashMap重新计算hash值,而且用与代替求模:
int hash = hash(k);
int i = indexFor(hash, table.length);

HashTable和HashMap区别
①继承不同。
public class Hashtable extends Dictionary implements Map public class HashMap extends AbstractMap implements Map

Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

Hashtable中,key和value都不允许出现null值。
在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。
④两个遍历方式的内部实现上不同。
Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数



如果一个try程序段中有3个catch语句,则这些catch语句最多会执行 1 次。

try语句
try语句用大括号{}指定了一段代码,该段代码可能会抛弃一个或多个例外。

catch语句
catch语句的参数类似于方法的声明,包括一个例外类型和一个例外对象。例外类型必须为Throwable类的子类,它指明了catch语句所处理的例外类型,例外对象则由运行时系统在try所指定的代码块中生成并被捕获,大括号中包含对象的处理,其中可以调用对象的方法。
catch语句可以有多个,分别处理不同类的例外。Java运行时系统从上到下分别对每个catch语句处理的例外类型进行检测,直到找到类型相匹配的catch语句为止。这里,类型匹配指catch所处理的例外类型与生成的例外对象的类型完全一致或者是它的父类,因此,catch语句的排列顺序应该是从特殊到一般。
也可以用一个catch语句处理多个例外类型,这时它的例外类型参数应该是这多个例外类型的父类,程序设计中要根据具体的情况来选择catch语句的例外处理类型。

try语句块内抛出第一个异常时,便匹配并执行相应的catch语句,接下来不会再执行try语句块,所以最多执行一次catch语句



class A {}
class B extends A {}
class C extends A {}
class D extends B {}
Which four statements are true ?
正确答案: A C D G 你的答案: B F

 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 referenceThe 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既是点也是范围,当表示范围时,表示最大范围

下面是代码

public static void main(String[] args) {        List<A> a;        List list;        list = a;   //A对,因为List就是List<?>,代表最大的范围,A只是其中的一个点,肯定被包含在内        List<B> b;        a = b;      //B错,点之间不能相互赋值        List<?> qm;        List<Object> o;        qm = o;     //C对,List<?>代表最大的范围,List<Object>只是一个点,肯定被包含在内        List<D> d;        List<? extends B> downB;        downB = d;  //D对,List<? extends B>代表小于等于B的范围,List<D>是一个点,在其中        List<?extends A> downA;        a = downA;  //E错,范围不能赋值给点        a = o;      //F错,List<Object>只是一个点        downA = downB;  //G对,小于等于A的范围包含小于等于B的范围,因为B本来就比A小,B时A的子类嘛    }
原创粉丝点击