牛客选择题错题集
2019-04-26
1. 以下代码执行的结果显示是多少( )?

A.true,false,true
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。B.false,true,false
C.true,true,false
D.false,false,true
正确答案: D 你的答案: A (错误)
解答:
当我们在为Integer赋值的时候,java编译器会将其翻译成调用valueOf()方法。比如Integer i=127翻译为Integer i=Integer.valueOf(127) 然后我们来看看valueOf()函数的源码:1 public static Integer valueOf(int i) 2 { 3 //high为127 4 if(i >= -128 && i <= IntegerCache.high) 5 return IntegerCache.cache[i + 128]; 6 else 7 return new Integer(i); 8 }可以看出,对于-128到127之间的数,Java会对其进行缓存。而超出这个范围则新建一个对象。 所以现在回到这道问题 i1和i2为128,超出范围,所以都需要新建对象,对象比较为false; i5和i6为100,在范围之内,在执行Integer i5=100时,就会直接缓存到内存中,但执行执行Integer i6=100时,就直接从缓存里取,而不需要新建对象,所以为true。
这归结于java对于Integer与int的自动装箱与拆箱的设计,是一种模式:享元模式(flyweight)
为了加大对简单数字的重利用,java定义:在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象。
而如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象;以上的现象是由于使用了自动装箱所引起的,如果你没有使用自动装箱,而是跟一般类一样,用new来进行实例化,就会每次new就都一个新的对象。
享元模式
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式,换句话说就是共享对象,在某些对象需要重复创建,且最终只需要得到单一结果的情况下使用。因为此种模式是利用先前创建的已有对象,通过某种规则去判断当前所需对象是否可以利用原有对象做相应修改后得到想要的效果,如以上教程的实例,创建了20个不同效果的圆,但相同颜色的圆只需要创建一次便可,相同颜色的只需要引用原有对象,改变其坐标值便可。此种模式下,同一颜色的圆虽然位置不同,但其地址都是同一个,所以说此模式适用于结果注重单一结果的情况。
举一个简单例子,一个游戏中有不同的英雄角色,同一类型的角色也有不同属性的英雄,如刺客类型的英雄有很多个,按此种模式设计,利用英雄所属类型去引用原有同一类型的英雄实例,然后对其相应属性进行修改,便可得到最终想得到的最新英雄;比如说你创建了第一个刺客型英雄,然后需要设计第二个刺客型英雄,你利用第一个英雄改变属性得到第二个刺客英雄,最新的刺客英雄是诞生了,但第一个刺客英雄的属性也随之变得与第二个相同,这种情况显然是不可以的。
2.下列代码执行结果为()
public static void main(String args[])throws InterruptedException{ Thread t=new Thread(new Runnable() { public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.print("2"); } }); t.start(); t.join(); System.out.print("1"); }
A. 21
B. 12
C. 可能为12,也可能为21
D. 以上答案都不对
正确答案: A 你的答案: 空 (错误)
thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。t.join(); //使调用线程 t 在此之前执行完毕。
t.join(1000); //等待 t 线程,等待时间是1000毫秒本题在主线程中调用了子线程的join函数,因此主线程必须等待子线程执行完毕才结束因此输出结果只能是21。
3. jdk1.8中,下面有关java 抽象类和接口的区别,说法错误的是?
A. 抽象类可以有构造方法,接口中不能有构造方法
B. 抽象类中可以包含非抽象的普通方法,接口中的方法必须是抽象的,不能有非抽象的普通方法
C. 一个类可以实现多个接口,但只能继承一个抽象类
D. 接口中可以有普通成员变量,抽象类中没有普通成员变量
我们知道,抽象类是不能被实例化的。但抽象类是否可以有构造函数?答案是可以有。抽象类的构造函数用来初始化抽象类的一些字段,而这一切都在抽象类的派生类实例化之前发生。不仅如此,抽象类的构造函数还有一种巧妙应用:就是在其内部实现子类必须执行的代码。
