Java面试题整理二(各种类的区别对比)

面试官:你这项目经验很丰富啊!来给我讲讲  xxxxxxxx类和yyyyyyy类的区别。

小白:NIMA我又不是Java的设计者,而且项目中又没有用过,我怎么可能知道它们的区别。(精神崩溃后的回答)

面试官:哎,这也不会。那也不会,你会啥?你前面的同学可都答上来了哟!!!

小白:那是我同学,跟我做一个项目的,我负责开发,和技术攻坚,她只会测试,而且是黑盒测试。

面试官:不可能吧,我看他回答的特别顺溜啊!

小白:那你是没看到她刷题,和背答案的认真。我只是喜欢动手写代码,不喜欢死记硬背。

这是我今年的真实面试场景,所以我也来“背”答案了!!!

问题一:抽象类和接口的区别

答:

接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对事务描述的抽象。
抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。
人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它.
所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。

区别:
第一点. 接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
第二点. 接口可以多继承,抽象类不行
第三点. 接口定义方法,不能实现,而抽象类可以实现部分方法。
第四点. 接口中基本数据类型为static 而抽类象不是的。
当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。

抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性。

虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。

问题二:Error和Exception有什么区别

答:

Exception:
1.可以是可被控制(checked) 或不可控制的(unchecked)。
2.表示一个由程序员导致的错误。
3.应该在应用程序级被处理。
Error:
1.总是不可控制的(unchecked)。
2.经常用来用于表示系统错误或低层资源的错误。
3.如何可能的话,应该在系统级被捕捉。

分析如下:

Error和Exception的联系
继承结构:Error和Exception都是继承于Throwable,RuntimeException继承自Exception

Error和RuntimeException及其子类称为未检查异常(Unchecked exception),其它异常称为受检查异常(Checked Exception)。

Error和Exception的区别
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。如Java.lang.StackOverFlowError和Java.lang.OutOfMemoryError。对于这类错误,Java编译器不去检查他们。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。

Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

运行时异常和受检查的异常
Exception又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception )。
RuntimeException:其特点是Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try……catch捕获,也没有用throws抛出,还是会编译通过,如:除数为零的ArithmeticException、错误的类型转换、数组越界访问和试图访问空指针等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。

受检查的异常(IOException等):这类异常如果没有try…catch也没有throws抛出,编译是通不过的。这类异常一般是外部错误,例如文件找不到、试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。

throw 和 throws两个关键字有什么不同(这又是一个区别,虽然我没有被问过,但是下面的程序运行结果经常考)
throw 是用来抛出任意异常的,你可以抛出任意 Throwable,包括自定义的异常类对象;throws总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常。如果方法抛出了异常,那么调用这个方法的时候就需要处理这个异常。
try-catch-finally-return执行顺序


1、不管是否有异常产生,finally块中代码都会执行;
2、当try和catch中有return语句时,finally块仍然会执行;
3、finally是在return后面的表达式运算后执行的,所以函数返回值是在finally执行前确定的。无论finally中的代码怎么样,返回的值都不会改变,仍然是之前return语句中保存的值;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

情况1:try{} catch(){}finally{} return; 
按正常顺序执行。


情况2:try{ return; }catch(){} finally{} return; 
程序执行try块中return之前(包括return语句中的表达式运算)代码; 
再执行finally块,最后执行try中return; 但是不改变try中语句的执行结果。
finally块后面的return语句不再执行。


情况3:try{ } catch(){return;} finally{} return; 
程序先执行try,如果遇到异常执行catch块, 
有异常: 则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码, 

最后执行catch块中return. finally块后面的return语句不再执行。 
无异常:执行完try再finally再执行最后的return语句.


情况4:try{ return; }catch(){} finally{return;} 
程序执行try块中return之前(包括return语句中的表达式运算)代码; 
再执行finally块,因为finally块中有return所以提前退出。


情况5:try{} catch(){return;}finally{return;} 
程序执行catch块中return之前(包括return语句中的表达式运算)代码; 
再执行finally块,因为finally块中有return所以提前退出。


情况6:try{ return;}catch(){return;} finally{return;} 
程序执行try块中return之前(包括return语句中的表达式运算)代码; 
有异常:则执行catch块中return之前(包括return语句中的表达式运算)代码; 
则再执行finally块,因为finally块中有return所以提前退出。 
无异常:则执行finally块,因为finally块中有return所以提前退出。


问题三:ArrayList、LinkedList与Vector的对比

答:

先上图,在分析。


从图中可以看出,这三者都实现了List 接口.所有使用方式也很相似,主要区别在于因为实现方式的不同,所以对不同的操作具有不同的效率。
ArrayList 是一个可改变大小的数组.当更多的元素加入到ArrayList中时,其大小将会动态地增长.内部的元素可以直接通过get与set方法进行访问,因为ArrayList本质上就是一个动态数组.


LinkedList 是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList.
当然,这些对比都是指数据量很大或者操作很频繁的情况下的对比,如果数据和运算量很小,那么对比将失去意义.
Vector 和ArrayList类似,但属于强同步类。如果你的程序本身是线程安全的(thread-safe,没有在多个线程之间共享同一个集合/对象),那么使用ArrayList是更好的选择。

Vector和ArrayList在更多元素添加进来时会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%.
而 LinkedList 还实现了 Queue 接口,该接口比List提供了更多的方法,包括 offer(),peek(),poll()等.
注意: 默认情况下ArrayList的初始容量非常小,所以如果可以预估数据量的话,分配一个较大的初始值属于最佳实践,这样可以减少调整大小的开销。


问题四:hashmap和hashtable的区别

答:

1.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类;
2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。

即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:Map Collections.synchronizedMap(Map m)
这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。
3.在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的为null。当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。

hashmap

线程不安全

允许有null的键和值

效率高一点、

方法不是Synchronize的要提供外同步

有containsvalue和containsKey方法

HashMap 是Java1.2 引进的Map interface 的一个实现

HashMap是Hashtable的轻量级实现

hashtable

线程安全

不允许有null的键和值

效率稍低、

方法是是Synchronize的

有contains方法方法

、Hashtable 继承于Dictionary 类

Hashtable 比HashMap 要旧

参考:http://blog.csdn.net/shohokuf/article/details/3932967



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值