Java常见面试题之异常处理与集合

本文详细探讨了Java异常处理中的throw与throws的区别,Error和Exception的分类,以及常见RuntimeException。深入讲解了集合框架,包括Collection与Map的对比,List与Set的特性,以及ArrayList、LinkedList、HashSet和HashMap的使用技巧。特别关注了线程安全的集合和反射机制的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

异常处理考核点

1. throw 和 throws 的区别?

2.Error 和 Exception 的区别?

3.请说出你最常见的5个RuntimeException

4 final. finally.finalize 的区别?

6.异常的处理机制有几种?

7.Java 反射创建对象效率高还是通过 new创建对象的效率高?

8.哪里会用到反射机制?

9.注解是什么?

集合考核点【重点】

10、请描述一下你对集合的理解?

11.Collection集合与Map集合区别?

12,List集合与Set集合区别?

13.ArrayList与LinkedList区别?

14、ArrayList与Vector区别?

15、HashSet和TreeSet区别?

16,如何去Vector集合中重复数据?

17、Collection与Collecctions区别?

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

19、HashMap与Hashtable区别?

20、集合迭代器的接口?

21、HashMap底层原理

22,总结一下Java语言中哪些集合是线程安全的


异常处理考核点


1. throw 和 throws 的区别?

位置不同
1. throws 用在函数上,后面跟的是异常类,可以跟多个;而 throw 用在函数内,后面跟的是异常对象。
功能不同:
1. throws 用来声明异常,让调用者只知道该功能可能出现的问题,可以给出预先的处理方式;throw 抛出具体的问题对象,执行到 throw,功能就已经结束了,跳转到调用者,并将具体的问题对象抛给调用者。也就是说 throw 语句独立存在时,下面不要也不能定义其他语句,因为执行不到且语法会报错。
2. throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw 则是抛出了异常,执行 throw 则一定抛出了某种异常对象。
3. 两者都是消极处理异常的方式,只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。


2.Error 和 Exception 的区别?

Error 类和 Exception 类的父类都是 Throwable 类,他们的区别如下:
Error 类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。
Exception 类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止运行。
Exception 类又分为运行时异常(Runtime Exception)和受检查的异常 (Checked Exception ),运行时异常;编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。而受检查的异常,要么用 try。catch 捕获,要么用 throws 字句声明抛出,交给它的调用类处理,否则编译不会通过。


3.请说出你最常见的5个RuntimeException

ClassCastException(类转换异常)
IndexOutOfBoundsException(数组越界)
NullPointerException(空指针)
ArrayIndexOutOfBoundsException (用非法索引访问数组时抛出的异常)
ArithmeticException (当出现异常的运算条件时,抛出此异常)
IllegaArguementException(抛出的异常表明向方法传递了一个不合法或不正确的参数。

4 final. finally.finalize 的区别?

final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,被其修饰的类不可继承。
finally:异常处理语句结构的一部分,表示总是执行。
finalize:是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM 不保证此方法总被调用


6.异常的处理机制有几种?

异常捕捉:try…catch…finally,
异常抛出:throw throws


7.Java 反射创建对象效率高还是通过 new创建对象的效率高?

通过 new 创建对象的效率比较高。通过反射时,先找查找类资源,使用类加载器创建,过程比较繁琐,所以效率较低。


8.哪里会用到反射机制?

jdbc 就是典型的反射,Class.forName('com.mysql.jdbc.Driver');//加载 MySQL 的驱动类。
还有就是,如 mybatis、spring 等框架使用反射实现


9.注解是什么?

Annotation(注解)是 Java 提供的一种对元程序中元素关联信息和元数据(metadata)的途径和方法。
Annatation(注解)是一个接口,程序可以通过反射来获取指定程序中元素的 Annotation 对象,然后通过该 Annotation 对象来获取注解中的元数据信息

集合考核点【重点】


10、请描述一下你对集合的理解?

集合用来存贮批量数据的对象,在程序中也可以使用数组完成这个需求,但是数组有个巨大的问题就是长度固定,当我们需要创建一个未知长度的数组这个问题就无法解决了,集合就可以帮助我们解决这个问题。同时集合还定义了一系列的方法例如判断是否为空,来简化操作。
集合分两大类:继承了 Collection 接口的 List 和 Set,还有 Map 接口...(自己发挥)

11.Collection集合与Map集合区别?

Collection一个是存储单列数据的集合,
Map是存储键和值这样的双列数据的集合,通过键可以找到对应的值

12,List集合与Set集合区别?

List与Set都继承Collection接口; 
List集合是有序的(有下标)可存放重复数据的集合,常用实现类:ArrayList,Vector,LinkedList
Set集合是无序的(没有下标)不能存放重复数据集合,常用实现类:HashSet,TreeSet

13.ArrayList与LinkedList区别?

ArrayList与LinkedList都是List接口的实现类;
ArrayList底层数据结构为数组,LinkedList为双向链表
对查询:ArrayList速度(元素连续),对插入与删除,效率低,因为需要移动元素;
对删除与插入操作,LinkedList效率高,只需要改变前后指针指向即可,而查询,LinkedList效率低,因需要通过指针逐个找

14、ArrayList与Vector区别?

ArrayList 和 Vector 都是List集合的实现类; ArrayList是线程非安全的,Vector是线程安全的,所以从性能来说ArrayList要优于Vector;
  扩容机制:ArrayList默认初始容量为0,第一次添加元素,会扩容为10,当满,每次扩50%;Vector初使容量为10,容量满,Vector默认扩容100%

15、HashSet和TreeSet区别?

HashSet与TreeSet都是Set集合的实现类;HashSet中的元素是无序的,不能存放重复数据,TreeSet是有序的(需要实现Comparable接口,定义比较规则);
HashSet低层为HashMap,TreeSet底层是TreeMap;
HashSet中可以添加null值 ,TreeSet不支持添加null值


16,如何去Vector集合中重复数据?

可以利用Vector. contains()方法判断是否包含该元素,若包含没有包含,就添加到集合中

Vector newVector = new Vector(); 
for (int i=0;i<vector.size();i++) { 
	Object obj = vector.get(i); 
	if(!newVector.contains(obj); 
	newVector.add(obj); 
}

还有一种简单的方式,HashSet set = new HashSet(vector)

17、Collection与Collecctions区别?

Collection 是集合类的上级接口,继承与他的接口主要有 Set 和 List.
Collections 是针对集合类的一个工具类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。


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

 Set 里的元素是不能重复的,元素重复与否是使用 equals() 方法进行判断的。
 可以重写equals与hashcode自定义比较规则

19、HashMap与Hashtable区别?

HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口,Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样,所以性能不会有很大的差异。
  主要区别在于:
  1. HashMap 允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
  2. HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsvalue 和 containsKey。因为 contains 方法容易让人引起误解。
  3. Hashtable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map 的 interface 的一个实现。
  4. Hashtable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现  同步,而 HashMap 就必须为之提供外同步。

20、集合迭代器的接口?

使用Collection集合提供的一个获取迭代器的方法,iterator()方法     

public Iterator<E> iterator();

       判断集合中是否有元素可以迭代

         public boolean hasNext();

       取出集合中可以迭代的元素

             public E next();

21、HashMap底层原理

1.底层数据结构
Java7 实现(数组 + 链表);  transient Node<K,V>[] table;
Java8 实现(数组 + 链表 + 红黑树)
2.理解hash(哈希)
 Hash是一个把任意长度的输入通过散列算法转换成固定长度的输出的函数
 哈希充突:不同的输入通过哈希产生相同的输出
 3.扩容机制
默认容量(capcity):16 -> static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 
阈值(threshold):默认为12,哈希表可存数据的最大容量(触发扩容的临界值)
加载因子(loadFactor):Hash表中元素的填满程度;默认为0.75 ->static final float DEFAULT_LOAD_FACTOR = 0.75f;
加载因子 = 填入表中的元素个数 / 散列表的长度
为什么设制加载因子?
当提高哈希表空间利用率 -->存相对多的数据 -->哈希算法计算存储位置冲突机率高(此位置已存数据);
避免哈希冲突 -->增大空间(扩容)-->带来空间利用不高

加载因子越大,填满元素越多,空间利用率越高,但发生冲突的机会变大
加载因子越小,填满的元素越少,冲突发生的机会减小,但空间浪费

需要在:“冲突的机会”与“空间利用率”之间,寻找一种平衡 -->所以Hash表设置加载因子,值通常在:0.7 --0.75之间

扩容:
默认创建哈希表,初始值为0,当首次向哈希表添加元素时,会自动扩容16
当表中的元素个数 大于 阈值(默认12),哈希表扩容1倍(16->32),阈值同步扩大1倍(12-24)

4.HashMap 进行树化的条件
链表长度大于 TREEIFY_THRESHOLD(8)
哈希数组的长度大于 MIN_TREEIFY_CAPACITY(64)

当需要存放一个元素的时候,将一对键值对封装到一个Node节点中,利用HashCode方法将键值对的key转换为哈希值,然后通过哈希算法转换为数组的下标,下标位置如果没有任何元素的话,将Node添加到这个位置上。如果说下标对应的位置上有链表,此时会拿这个k和链表上每一个节点的k进行equals,如果所有的equals都返回false,那么这个节点将会被添加到链表的末尾。如果其中有一个equals返回了true,那么这个节点的value会被覆盖。


22,总结一下Java语言中哪些集合是线程安全的

Vector,Hashtable,ConcurrentHashMap都是线程安全的


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值