牛客网日常刷题错题汇总2017-09-04

如下代码输出结果为:
public class Base{
  private String basename = "base";
  Base(){
    callName();
  }
  public void callName(){
    System.out.println(basename);
  }
}
public class Sub extends Base{
  private String basename = "sub";
  @Override
  public void callName(){
    System.out.println(basename);
  }
}
public class Test{
  public static void main(String[] args){
    Base b = new Sub();
  }
}
如下代码输出结果为:null———>因为当调用new Sub()调用它的默认无参构造器时,默认就是调用父类的无参构造器,而在父类的无参构造器中调用了callName(),在基类中已经Override重写了该方法,所以这里是要调用基类重写的callName方法,而此时基类并没有被实例化,因此此时调用callName输出的baseName值为null(还未被实例化)
这里需要知道类加载的顺序:父类的静态代码块->子类的静态代码块->父类的非静态代码块->父类的构造器->子类的非静态代码块->子类的构造器->


关于HashMap和HashTable说法错误的是B:
A.两者都是用key-value方式获取数据
B.Hashtable允许null值作为key和value,而HashMap不可以
C.HashMap不是同步的,而Hashtable是同步的
D.迭代HashMap采用快速失败机制,而Hashtable不是
HashTable和HashMap都实现了Map接口,因此都是使用key-value键值对来保存和获取数据;
对HashMap来说,他的键和值都可以为null,而对HashTable来说,他的键和值都不可以为null
HashTable的方法是Synchronized线程同步的,而HashMap不是,多个线程对HashMap的方法进行访问时,需要手动设置他的方法为线程同步


如下代码的运行结果:
public class Example{
    String str=new String("tarena");
    char[]ch={'a','b','c'};
    public static void main(String args[]){
        Example ex=new Example();
        ex.change(ex.str,ex.ch);
        System.out.print(ex.str+" and ");
        System.out.print(ex.ch);
    }
    public void change(String str,char ch[]){
   //引用类型变量,传递的是地址,属于引用传递。
        str="test ok";
        ch[0]='g';
    }
}
java中只有值传递,没有引用传递;对于引用类型来说,传递的值他的地址,因此引用类型变量的变量传递是会改变原来的值的;而String类型是一个特殊,因为在java中String类型是不可变的,java在内存中专门为String开辟了一个字符串常量池,用来锁定数据不被篡改,因此在change方法中,str是一个新的字符串对象,与原来的str对象毫无关系;因此最后的输出结果为: tarena and gbc


最终s的值为:
int i = 5;
int s = (i++)+(++i)+(i--)+(--i);
最终s的值为24,而在s中的括号其实对于自增和自减都是没有用的,就是说s右边的运算式有没有括号都是一样的,i++仍然在括号之外才进行自增,i–仍然在括号之外才进行自减,最终s的值为5+7+7+5=24;而不是6+7+6+5


子类重写父类方法需要满足两同两小一大原则:方法名相同、参数列表相同;子类返回值类型要小于等于父类返回值类型、子类抛出的异常要小于等于父类抛出的异常类型;子类访问权限要大于等于父类的访问权限


如下代码编译运行是否能通过
class Test {
    public static void hello() {
        System.out.println("hello");
    }
}
public class MyApplication {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Test test=null;
        test.hello();
    }
}
最终能通过编译运行并打印hello;因为hello是Test的静态成员方法,属于类,所以不管是否new创建了该类的对象,它都会进行初始化一次;因此最终还是能够正确调用hello方法


java的访问权限有public/protectes/default/private,其中default不能用于修饰变量;


StringBuffer和StringBuilder都可以用来创建可变字符串变量,区别在于StringBuffer是线程安全的,而StringBuilder是非线程安全的


对于一个ArrayList集合类的对象,在进行迭代的过程中进行指定的删除操作时,如何进行安全且正确的删除操作:
Iterator it = list.iterator();
int index = 0;
while (it.hasNext())
{
    Object obj = it.next();
    if (needDelete(obj))  //needDelete返回boolean,决定对应的数据是否要删除
    {
        //todo delete
    }
    index ++;
}

A.it.remove();
B.list.remove(obj);
C.list.remove(index);
D.list.remove(obj,index);
正确答案为A,因为在进行删除操作时,迭代器已经获取到了,而此时如果使用list对象的remove方法进行删除删除操作的话,就会产生错误;因此,处于安全的顾虑,在这里我们可以直接使用迭代器Iterator的remove方法来删除此时遍历到的数据


下面定义了两个线程,假设在线程t1在线程t2启动之前已经完成启动,则下面输出结果为:
public static void main(String[]args)throws Exception {
    final Object obj = new Object();
    Thread t1 = new Thread() {
        public void run() {
            synchronized (obj) {
                try {
                    obj.wait();
                    System.out.println("Thread 1 wake up.");
                } catch (InterruptedException e) {
                }
            }
        }
    };
    t1.start();
    Thread.sleep(1000);//We assume thread 1 must start up within 1 sec.
    Thread t2 = new Thread() {
        public void run() {
            synchronized (obj) {
                obj.notifyAll();
                System.out.println("Thread 2 sent notify.");
            }
        }
    };
    t2.start();
}

A.Thread 1 wake up
  Thread 2 sent notify.

B.Thread 2 sent notify.
  Thread 1 wake up

C.A、B皆有可能

D.程序无输出卡死
最终结果为B,因为已经t1在t2启动之前已经启动了,这时候t1获得了obj对象的锁进入运行状态,此时在t1的run中调用了wait方法释放了锁并处于等待状态,而后t2启动,调用了notifyAll方法来通知唤醒obj对象对应的所有等待线程,而此时t2还没有释放obj锁,所以t1还是处于就绪装台;因此先执行t2线程,然后t2线程执行完之后t1才由就绪状态进入运行状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值