整理整理就心浮气躁了,所以,这次没有总结(一)详细,至少我本人觉得有点水了,平复心情还会再战的
第十二,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关键字
抽象类可以实现接口,但是接口不能实现抽象类
抽象类可以继承实体类,前提是实体类必须有无参构造函数
我的个人理解:
- 没有构造函数的类是无法实例化的;
- 抽象类是可以有构造方法的,但是它的构造方法不能直接调用,因为它不能实例化;
- 抽象类的实例化是通过子类来实现的;
- 只要子类继承了父类,而子类想要创建构造方法,它的构造方法第一句就默认调用父类的无参构造器
- 但我觉得面试的话,这句话是否有点多余因为实体类即使不自定义创建构造器,也会有一个java默认创建的构造器。
第二十三,启动一个线程是用run()还是start()?
答:启动一个线程是调用start()方法,这并不意味着线程就会立即运行,只是进入了可运行状态。直接调用run()方法不会产生线程,而是把它当作普通的方法调用,马上执行。
我的理解:
- java线程的两种实现方法:extends继承Thread类;implements实现Runnable接口,并且都需要重写run()方法;
- 启动线程既可以使用run(),也可以使用start(),但start()最终还是要调用run();
- 使用run()启动线程,程序中只有一个主线程,只有当run()的方法体执行完,才会执行其他代码,实际上就是没有创建一个线程,单纯是调用了普通的方法,按照顺序执行;
- 使用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;
}
}