Java面试临时复习题总结(二)

整理整理就心浮气躁了,所以,这次没有总结(一)详细,至少我本人觉得有点水了,平复心情还会再战的

 

第十二,sleep() 和 wait() 有什么区别? 搞线程的最爱。

答:

拓展1:sleep()

hread.sleep(long millis)和Thread.sleep(long millis, int nanos)静态方法强制当前正在执行的线程休眠(暂停执行),以“减慢线程”。

当线程睡眠时,它睡在某个地方,在苏醒之前不会返回到可运行状态。

当睡眠时间到期,则返回到可运行状态。

线程睡眠的原因:线程执行太快,或者需要强制进入下一轮,因为Java规范不保证合理的轮换。

睡眠的实现:调用静态方法。

        try {

            Thread.sleep(1000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

睡眠的位置:为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内。这样才能保证该线程执行过程中会睡眠。

注意:

1、线程睡眠是帮助所有线程获得运行机会的最好方法。

2、线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。

3、sleep()是静态方法,只能控制当前正在运行的线程。

拓展2:wait(), notify(), notifyAll()等方法介绍

1.wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒(进入“就绪状态”)

2.notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。

3.wait(long timeout)让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的notify()方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”)。

(1)wait()一定要使用sycronized进行同步,否则会报“java.lang.IllegalMonitorStateException”异常。这是因为wait方法会释放对象锁,而此时因为没有用sycronized同步,就没有锁,就会报异常。

(2)锁指的是sycronized修饰的方法、对象、代码块,如下实例中的value。

(3)因为wait()释放了锁,故其他线程可以执行本来由sycronized修饰的内容。

第十三,Java有没有goto? 很十三的问题,如果哪个面试的问到这个问题,我劝你还是别进这家公司。

 

第十四,数组有没有length()这个方法? String有没有length()这个方法?

答:数组没有length()方法,有length属性;

   String有length()方法

拓展:js中获得字符串长度用的是length属性

第十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? 常问。

答:

Overload重载:发生在同一个类中,是指方法名相同,但参数列表不同(1.参数类型不同;2.参数个数不同)的方法,且与返回类型无关。

Override重写:发生在子父类,或子父接口中,方法声明相同。

Overload的方法可以改变返回值的类型,因为与返回值类型无关。

第十六,Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

答:Set 里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。

关于==和equals()的区别:

1)“==”用于比较引用和比较基本数据类型时具有不同的功能:

比较基本类型,如果两个值相等,结果为true

比较引用,如果引用指向内存中同一对象,结果为true

2)equals(Object obj):

  当参数obj引用的对象与对当前对象是同一个对象时,返回true,否则返回false

注:equals()方法的本意是确定两个对象的引用相同。

拓展:

1.JDK中有些类覆盖了Object类的equals()方法,比较规则为:如果两个对象类型一致,并且内容一致,则返回true。(这些类有:java.io.file,java.util.Date,java.lang.string,包装类(Integer,Double等))

例如:String中的equals()方法被覆盖,使其意义变为对比两个对象内容是否一致。

2.自定义的覆盖equals()方法。需要重写equals()和hashCode()方法。

 拓展1:为什么在重写equals()的时候要重写hashCode()?

equals()和hashCode()的关系

-》如果两个对象相同(即,用equals()比较返回true时),它们对的hashCode()一定要相同;

-》如果两个对象的hashCode()相同,它们却并不一定相同(即,用equals()比较返回false时)。

②  hashCode()的作用

    为了提高程序的效率。两个对象比较,先比较hashCode(),如果不同,就没必要比较equals(),

大大减少了equals()的比较次数。

为什么要重写hashCode()方法?简单的说就是为了保证同一个对象,保证在equals()相同的情况下hashCode值必定相同。

如果重写了equals()而未重写hashCode方法,可能会出现两个没有关系的对象equals()相同(此时的equals()是根据对象的特征重写的),但hashCode()却是不相同的。

拓展2:equals()作为方法,可以推测知道,它的实现是使用==运算符的,那为什么还要有equals()呢?

    因为==是不允许我们覆盖,也就是重写的,不能满足我们不同的需求。而对于equals()方法,我们可以通过重写,来实现根据对象特征比较对象内容是否相同的目的。而这些==无法做到。

第十七,给我一个你最常见到的runtime exception。 如果你这个答不出来,面试的人会认为你没有实际编程经验。

Java.lang.NullPointerException - 空指针异常

Java.lang.IndexOutOfBoundsException - 索引超出异常,下标越界异常

Java.lang.ClassCastException - 类型强制转换异常。

IllegalArgumentException - 传递非法参数异常

IllegalStateException - 非法语句异常

NumberFormatException - 数字格式异常

 

第十八,error和exception有什么区别?

答:

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

或者

error 是我门在编程中因语法错误,逻辑错误所导致的

exception是软件在运行中所遇到的不正常反映

第十九,List, Set, Map是否继承自Collection接口?

List,Set继承自Collection接口,Map不是

拓展1:Map没有显示的继承父类,它继承自java.long.Object,没有实现任何接口

拓展2:ArrayList和Vector的区别

类型\区别

安全性

数据增长

ArrayList

线程不安全,不同步

默认增长为原来的一半

Vector

线程安全,同步

默认增长为原来的一倍

第二十,abstract class和interface有什么区别? 常问。

答:比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。

第二十一,abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

答:都不可以。

拓展:

1.抽象方法不能用private修饰

抽象方法没有方法体,是用来被继承的,不能用private修饰。

2.抽象方法不能用static修饰

static修饰的方法可以用类名访问(方法体),抽象方法用static修饰没有意义。

3.抽象方法不能用synchronized修饰

Synchronized关键字是为该方法加锁。如果该方法是static修饰的,那么该锁就是class变量锁。如果是修饰类方法,则用this变量锁。但抽象类不能实例化对象,因为该方法不是在该抽象类中实现的。是在其子类实现的。所以锁应该归其子类所有,所以抽象方法也不能用synchronized修饰。

4.抽象方法不能用native修饰

native本身就和abstract冲突,他们都是方法声明,abstract是把方法实现移交给子类,native是把方法实现移交给本地操作系统。如果同时出现,相当于,既把方法实现移交给子类又把它移交给本地操作系统。

第二十二,接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

答:接口可以继承接口,使用的是extends关键字

抽象类可以实现接口,但是接口不能实现抽象类

抽象类可以继承实体类,前提是实体类必须有无参构造函数

我的个人理解:

  1. 没有构造函数的类是无法实例化的;
  2. 抽象类是可以有构造方法的,但是它的构造方法不能直接调用,因为它不能实例化;
  3. 抽象类的实例化是通过子类来实现的;
  4. 只要子类继承了父类,而子类想要创建构造方法,它的构造方法第一句就默认调用父类的无参构造器
  5. 但我觉得面试的话,这句话是否有点多余因为实体类即使不自定义创建构造器,也会有一个java默认创建的构造器。

第二十三,启动一个线程是用run()还是start()?

答:启动一个线程是调用start()方法,这并不意味着线程就会立即运行,只是进入了可运行状态。直接调用run()方法不会产生线程,而是把它当作普通的方法调用,马上执行。

我的理解:

  1. java线程的两种实现方法:extends继承Thread类;implements实现Runnable接口,并且都需要重写run()方法;
  2. 启动线程既可以使用run(),也可以使用start(),但start()最终还是要调用run()
  3. 使用run()启动线程,程序中只有一个主线程,只有当run()的方法体执行完,才会执行其他代码,实际上就是没有创建一个线程,单纯是调用了普通的方法,按照顺序执行;
  4. 使用start()启动线程,是让线程处于就绪状态,当得到CPU的时间片时,就会执行run()方法,而且无需等待run()中的代码执行完毕,就可以接着执行下面的代码,当run()方法执行结束后,这个线程也就结束了。

第二十四,构造器Constructor是否可被override?

答:构造器constructor不能被继承,因此不能被override,但是可以被overload.

每一个类都必须有自己的构造函数,负责构造自己这部分的构造。子类不会覆盖父类的构造函数,相反必须负责在一开始调用父类的构造函数。

第二十五,是否可以继承String类?

答:不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。

第二十六,当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

答:这个题的答案本来是:不能,一个对象的一个synchronized方法只能由一个线程访问。

但是我怎么看都觉得怪怪的,于是乎百度了那些追根究底的好学大神,应当分情况考虑。

我觉得最好的回答是这样的:

分几种情况:

 1)查看其它方法是否使用了同步关键字(synchronized)修饰,如果没有的话就可以调用相关的方法。

2)在当前synchronized方法中是否调用了wait方法,如果调用了,则对应的锁已经释放,可以访问了。

3)如果其它方法也使用synchronized修饰,并且当前同步方法中没有调用wait方法的话,这样是不允许访问的。

4)如果其它方法是静态方法的话,由于静态方法和对象是扯不上什么关系,对于静态同步方法而言,其对应的同步监视器为当前类的字节码

           所以肯定可以访问的了。

来源:http://www.cnblogs.com/xiohao/p/4151408.html

http://topmanopensource.iteye.com/blog/1738178

第二十七,try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

会执行,在return前执行。

比较合理靠谱的解释:

try 中的return在执行的时候,要返回的结果就已将准备好了,这是转去执行finally,在转去之前try先把要返回的结果放到一个临时空间,就算返回的结果在finally中被做了改变,也不会影响return的结果,执行完finally之后,再取出return的结果。

第二十八,编程题: 用最有效率的方法算出2乘以8等於几? 有C背景的程序员特别喜欢问这种问题。

答:用移位运算,左移2<<3

第二十九,两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

答:不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。

具体请参照第十六题拓展。

第三十,当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

答:是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。

第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

 

第三十二,编程题: 写一个Singleton出来

//方式一:醉汉式
public class Singleton{
    private static Singleton test  = new Singleton();//静态的。保留自身的引用。
    //必须是私有的构造函数
    private Singleton(){}
    //公共的静态的方法。
    public static Singleton getInstance(){
        return test;
    }
}
//方式二:懒汉式
public class Singleton{
    private static Singleton test  =  null;//静态的。保留自身的引用。
    //必须是私有的构造函数
    private Singleton(){}
    //公共的静态的方法。
    public static Singleton getInstance(){
        if(test == null){
          test = new Singleton();
        }
        return test;
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值