Java访谈的40个热门问答集

毫无疑问,java集合是最重要的领域之一,无论您是初级还是高级,您都可以在任何位置对其进行测试。范围如此之广,几乎不可能涵盖所有问题。但是,根据我以前的访谈,我尝试提出您必须知道的尽可能多的GOOD Java Collection访谈问题

我的目标是初学者和高级问题,所以如果您发现一些基本问题,请多多包涵,因为它们对某些初级开发人员可能有用。

Java Collection面试题

一般的问题

1)什么是Java Collections API?列出其优势?
2)解释馆藏层次?
3)为什么Collection接口没有扩展Cloneable和Serializable接口?
4)为什么Map接口没有扩展Collection接口?

列表界面相关

5)为什么要使用List接口?什么是实现List接口的主要类?
6)如何将String数组转换为ArrayList?
7)如何反转列表?

设置界面相关

8)为什么要使用Set接口?什么是实现Set接口的主要类?
9)HashSet如何存储元素?
10)是否可以将null元素添加到TreeSet或HashSet中?

地图界面相关

11)为什么要使用Map界面?什么是实现Map接口的主要类?
12)什么是IdentityHashMap和WeakHashMap?
13)解释ConcurrentHashMap吗?怎么运行的?
14)哈希图如何工作?
15)如何为哈希表设计一个好的密钥?
16)Map界面提供哪些不同的Collection视图?
17)什么时候使用HashMap或TreeMap?

告诉差异问题

18)Set和List之间的区别?
19)列表和地图之间的区别?
20)HashMap和HashTable之间的区别?
21)Vector和ArrayList之间的区别?
22)迭代器和枚举之间的区别?
23)HashMap和HashSet之间的区别?
24)Iterator和ListIterator之间的区别?
25)TreeSet和SortedSet之间的区别?
26)ArrayList和LinkedList之间的区别?

更多问题

27)如何使收藏集只读?
28)如何使收集线程安全?
29)为什么没有像Iterator.add()这样的方法将元素添加到集合中?
30)有哪些不同的方法可以遍历列表?
31)通过迭代器快速失败属性您了解什么?
32)快速故障和故障安全之间有什么区别?
33)如何在迭代集合时避免ConcurrentModificationException?
34)什么是UnsupportedOperationException?
35)哪些集合类提供对其元素的随机访问?
36)什么是BlockingQueue?
37)什么是队列和堆栈,列出它们的区别?
38)什么是可比较和比较器界面?
39)什么是Collections和Arrays类?
40)推荐资源

不要浪费时间,让我们深入研究Java集合的概念。

Java Collection面试一般问题

1)什么是Java Collection框架?列出其优势?

根据定义,集合是代表一组对象的对象。像集合论一样,集合是一组元素。很容易!

在JDK 1.2之前,JDK具有一些实用程序类,例如Vector和HashTable,但是没有Collection框架的概念。从JDK 1.2以后,JDK感到需要对可重用数据结构提供一致的支持。最后,集合框架主要由Joshua Bloch设计和开发,并在JDK 1.2引入

Java集合最明显的好处可以列为:

  • 随时可用的代码,减少了编程工作
  • 由于数据结构和算法的高性能实现而提高了性能
  • 通过建立公共语言来回传递集合,从而在不相关的API之间提供互操作性
  • 仅学习一些顶级接口和支持的操作即可轻松学习API

2)解释馆藏的等级?

Java集合层次结构
Java集合层次结构

如上图所示,收集框架顶部有一个接口,即Collection。它由Set,List和Queue接口扩展。然后在这3个分支中还有其他类别的负载,我们将在以下问题中学习。

记住Collection接口的签名。它会在很多问题上帮助您。

public interface Collection extends Iterable {
//method definitions
}

框架还包括Map接口,它是收集框架的一部分。但它不会扩展Collection接口。我们将在此问题库中的第四个问题中看到原因。

3)为什么Collection接口没有扩展Cloneable和Serializable接口?

好吧,最简单的答案是“ 没有必要做 ”。扩展接口仅表示您正在创建接口的子类型,换句话说,不希望使用更专门的行为和Collection接口来实现Cloneable和Serializable接口。

另一个原因是并非每个人都有理由拥有Cloneable集合,因为如果它具有非常大的数据,那么每个不必要的克隆操作都将消耗大量内存。初学者可能在不知道后果的情况下使用它。

另一个原因是Cloneable和Serializable是非常特殊的行为,因此仅在需要时才应实现。例如,集合中的许多具体类都实现了这些接口。因此,如果您想要此功能。使用这些收集类,否则使用其替代类。

4)为什么Map接口没有扩展Collection接口?

这个访谈问题的一个很好的答案是“ 因为它们不兼容 ”。集合具有方法add(Object o)。Map无法使用这种方法,因为它需要键值对。还有其他原因,例如Map支持keySet,valueSet等。Collection类没有此类视图。

由于存在如此大的差异,因此在Map界面中未使用Collection界面,而是在单独的层次结构中构建。

Java集合访谈–列出接口问题

5)为什么要使用List接口?什么是实现List接口的主要类?

Java列表是元素“有序”集合。该排序是从零开始的索引。它不关心重复项。除了在Collection接口中定义的方法外,它还有自己的方法,这些方法主要是根据element的索引位置来操纵集合。这些方法可以分为搜索,获取,迭代和范围视图。以上所有操作均支持索引位置。

实现List接口的主要类为:Stack,Vector,ArrayList和LinkedList。在Java文档中阅读有关它们的更多信息。

6)如何将String数组转换为arraylist?

这更多是一个程序性问题,在初学者水平上可以看到。目的是检查收集实用程序类中申请人的知识。现在,让我们了解Collection框架中有两个实用程序类,它们在访谈中最常见,即Collections和Arrays

集合类提供了一些静态函数来对集合类型执行特定操作。数组提供了要在数组类型上执行的实用程序功能。

//String array
String[] words = {"ace""boom""crew""dog""eon"};
//Use Arrays utility class
List wordList = Arrays.asList(words);
//Now you can iterate over the list

请注意,此函数并非特定于String类,它将返回数组属于任何类型的元素的List。例如

//String array
Integer[] nums = {1234};
//Use Arrays utility class
List numsList = Arrays.asList(nums);

7)如何反转列表?

这个问题就像上面一样,测试您对Collections实用程序类的了解。使用它的reverse()方法可以反转列表。

Collections.reverse(list);

Java集合面试–设置接口问题

8)为什么要使用Set接口?什么是实现Set接口的主要类?

在集合论中对数学集合进行建模。Set接口类似于List接口,但有一些区别。首先,它不是有序的collection。因此,添加或删除元素时不会保留任何顺序。它确实提供的主要功能是“ 元素的唯一性 ”。它不支持重复元素。

Set还对equals和hashCode操作的行为增加了更强的约定,从而即使它们的实现类型不同,也可以有意义地比较Set实例。如果两个Set实例包含相同的元素,则它们相等。

基于上述原因,它没有基于List元素的索引的操作。它只有由Collection接口继承的方法。

实现Set接口的主要类为:EnumSet,HashSet,LinkedHashSet,TreeSet。阅读更多有关Java文档的信息。

9)HashSet如何存储元素?

您必须知道HashMap存储键-值对,其条件是一个条件,即键将是唯一的。HashSet使用Map的此功能来确保元素的唯一性。在HashSet类中,映射声明如下:

private transient HashMap<E,Object> map;
//This is added as value for each key
private static final Object PRESENT = new Object();

因此,当您将元素存储在HashSet中时,它将元素存储为map中的键,而将“ PRESENT”对象存储为value。(请参见上面的声明)。

public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

我强烈建议您阅读这篇文章:HashMap如何在Java中工作?这篇文章将帮助您轻松地回答所有与HashMap相关的问题。

10)是否可以将null元素添加到TreeSet或HashSet中?

如您所见,上一个问题的add()方法中没有null检查。而且HashMap还允许一个null键,因此HashSet中允许一个“ null”

TreeSet使用与HashSet相同的概念进行内部逻辑,但是使用NavigableMap来存储元素。

private transient NavigableMap<E,Object> m;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

NavigableMap是SortedMap的子类型,不允许使用null键。因此,从本质上讲TreeSet也不支持null键。如果您尝试在TreeSet中添加null元素,它将抛出NullPointerException。

Java集合面试– Map接口问题

11)为什么要使用Map界面?什么是实现Map接口的主要类?

Map接口是一种特殊的集合类型,用于存储键值对。因此,它不会扩展Collection接口。该界面提供了在地图的各种视图上添加,删除,搜索或迭代的方法。

实现Map接口的主要类为:HashMap,Hashtable,EnumMap,IdentityHashMap,LinkedHashMap和Properties。

12)什么是IdentityHashMap和WeakHashMap?

IdentityHashMap与HashMap相似,除了在比较元素时使用引用相等。IdentityHashMap类不是一种广泛使用的Map实现。尽管此类实现了Map接口,但它有意违反Map的常规协定,后者要求在比较对象时使用equals()方法。IdentityHashMap设计为仅在少数情况下使用,其中需要引用相等语义。

WeakHashMap是Map接口的实现,该接口仅存储对其键的弱引用。当不再在WeakHashMap外部引用键值对时,仅存储弱引用将允许对键值对进行垃圾回收。该类主要用于与equals方法使用== Operator 测试对象标识的键对象一起使用。一旦丢弃了这样的密钥,就永远无法重新创建它,因此以后不可能在WeakHashMap中对该密钥进行查找,并且会惊讶地发现它的条目已被删除。

13)解释ConcurrentHashMap吗?怎么运行的?

从Java文档中获取:

一个哈希表,它支持检索的完全并发性和可更新的可调整预期并发性。此类遵循与Hashtable相同的功能规范,并且包括与Hashtable的每个方法相对应的方法的版本。但是,即使所有操作都是线程安全的,检索操作也不需要进行锁定,并且不支持以阻止所有访问的方式锁定整个表。在依赖于其线程安全性但不依赖于其同步详细信息的程序中,此类可与Hashtable完全互操作。

阅读有关ConcurrentHashMap面试问题的更多信息。

14)哈希图如何工作?

最重要的问题在面试的每一个层次上可以看出这是最有可能的。您必须在这个主题上非常清楚。,不仅因为它是最常被问到的问题,而且还将使您对与集合API相关的其他问题敞开心mind。

这个问题的答案非常大,您应该阅读我的文章:HashMap如何工作?现在,让我们记住HashMap是基于Hashing原理工作的。根据定义,映射是:“将键映射到值的对象”。为了存储这种结构,它使用一个内部类Entry

static class Entry implements Map.Entry
{
final K key;
V value;
Entry next;
final int hash;
...//More code goes here
}

此处,键和值变量用于存储键-值对。整个条目对象存储在数组中。

/**
* The table, re-sized as necessary。 Length MUST Always be a power of two.
*/
transient Entry[] table;

数组的索引是根据Key对象的哈希码计算的。阅读更多链接主题。

15)如何为哈希表设计一个好的密钥?

在回答哈希图如何工作后,通常会跟进另一个好问题。好吧,最重要的约束是您将来必须能够取回值对象。否则,没有使用这种数据结构。如果您了解hashmap的工作原理,将会发现它很大程度上取决于Key对象的hashCode()和equals()方法。

因此,一个好的关键对象必须一次又一次地提供相同的hashCode(),无论它被获取了多少次。同样,与equals()方法比较时,相同的键必须返回true,而不同的键必须返回false

因此,不可变的类被认为是HashMap键的最佳候选者

阅读更多:如何为HashMap设计一个好的密钥?

16)Map界面提供哪些不同的Collection视图?

Map界面提供了3个存储在其中的键值对的视图:

  • 键集视图
  • 值集视图
  • 条目集视图

可以使用迭代器浏览所有视图。

17)什么时候使用HashMap或TreeMap?

HashMap是众所周知的类,我们所有人都知道。因此,我将离开这部分,说它用于存储键值对,并允许对这样的对集合执行许多操作。

TreeMap是HashMap的特殊形式。它维护 HashMap类中缺少的键的顺序默认情况下,此排序为“自然排序”。通过提供Comparator类的实例,可以覆盖默认顺序,该类的compare方法将用于维护键的顺序。

请注意,插入到映射中的所有键都必须实现Comparable接口(确定顺序是必需的)。此外,所有这些键必须相互可比较:k1.compareTo(k2)不得为映射中的任何键k1和k2抛出ClassCastException。如果用户尝试将键放入违反此约束的映射中(例如,用户尝试将字符串键放入其键为整数的映射中),则put(Object key,Object value)调用将引发ClassCastException 。

Java集合访谈–讲述差异问题

18)Set和List之间的区别?

最明显的区别是:

  • Set是无序集合,其中List是基于零索引的有序集合。
  • 列表允许重复元素,但Set不允许重复。
  • List不会阻止插入空元素(随您喜欢),但是Set将只允许一个空元素。

19)列表和地图之间的区别?

也许是最简单的问题。List是元素的集合,而map是键值对的集合。实际上,有很多差异源自第一个陈述。它们具有单独的顶层接口,单独的一组通用方法,不同的受支持方法和不同的collection视图

我会花很多时间来回答这个问题,仅作为第一个区别就足够了。

20)HashMap和HashTable之间的区别?

Java中的HashMap和Hashtable之间有一些区别:

  • Hashtable是同步的,而HashMap不是同步的。
  • 哈希表不允许使用空键或空值。HashMap允许一个空键和任意数量的空值。
  • HashMap与Hashtable之间的第三个重要区别是HashMap中的Iterator是快速失​​败的迭代器,而Hashtable的枚举器则不是。

21)Vector和ArrayList之间的区别?

让我们记下差异:

  • Vector的所有方法都是同步的。但是,ArrayList的方法不同步。
  • Vector是在JDK的第一个版本中添加的旧类。当在Java中引入收集框架时,ArrayList是JDK 1.2的一部分。
  • 默认情况下,Vector在内部调整大小时会将其数组的大小加倍。但是,重新调整大小时,ArrayList的大小增加一半。

22)迭代器和枚举之间的区别?

迭代器与枚举在以下三个方面有所不同:

  • 迭代器允许调用方使用其remove()方法在迭代过程中从基础集合中删除元素。使用枚举器时,不能从集合中添加/删除元素。
  • 枚举在旧类(例如Vector / Stack等)中可用,而Iterator在所有现代集合类中可用。
  • 另一个小的区别是Iterator改进了方法名称,例如Enumeration.hasMoreElement()变为Iterator.hasNext(),Enumeration.nextElement()变为Iterator.next()等。

23)HashMap和HashSet之间的区别?

HashMap是键值对的集合,而HashSet是唯一元素的无序集合。而已。无需进一步描述。

24)Iterator和ListIterator之间的区别?

有三个区别:

  • 我们可以使用Iterator遍历Set和List以及Map的Object类型。但是列表迭代器可用于遍历列表类型的对象,但不能遍历对象的集合类型。
  • 通过使用Iterator,我们只能从正向检索Collection对象中的元素,而List Iterator则允许您使用hasPrevious()和previous()方法在任一方向上遍历。
  • ListIterator允许您使用add()remove()方法修改列表。使用Iterator不能添加,只能删除元素。

25)TreeSet和SortedSet之间的区别?

SortedSet是TreeSet实现的接口。就是这样!

26)ArrayList和LinkedList之间的区别?

  • LinkedList将元素存储在双链列表数据结构中。ArrayList将元素存储在动态调整大小的数组中。
  • LinkedList允许进行固定时间的插入或删除,但只允许顺序访问元素。换句话说,您可以向前或向后浏览列表,但是在中间抓取一个元素所花费的时间与列表的大小成正比。另一方面,ArrayList允许随机访问,因此您可以在固定时间内抓取任何元素。但是,从末端开始的任何地方添加或删除,都需要将后面的所有元素移开,以形成开口或填补空白。
  • LinkedList比ArrayList具有更多的内存开销,因为在ArrayList中,每个索引仅保存实际的对象(数据),但是在LinkedList的情况下,每个节点都保存下一个和上一个节点的数据以及地址。

更多采访访谈问题

27)如何使收藏集只读?

使用以下方法:

  • Collections.unmodifiableList(list);
  • Collections.unmodifiableSet(set);
  • Collections.unmodifiableMap(map);

这些方法采用collection参数,并返回一个具有与原始collection中相同的元素的新的只读collection。

28)如何使收集线程安全?

使用以下方法:

  • Collections.synchronizedList(list);
  • Collections.synchronizedSet(set);
  • Collections.synchronizedMap(map);

上面的方法将collection作为参数,并返回同步且线程安全的相同类型的collection。

29)为什么没有像Iterator.add()这样的方法将元素添加到集合中?

迭代器的唯一目的是通过集合进行枚举。所有集合都包含add()方法以实现您的目的。添加Iterator毫无意义,因为可能会或可能不会排序集合对于有序和无序集合add()方法不能具有相同的实现

30)有哪些不同的方法可以遍历列表?

您可以使用以下方式遍历列表:

  • 迭代器循环
  • 对于循环
  • 对于循环(高级)
  • While循环

了解更多:http : //www.mkyong.com/java/how-do-loop-iterate-a-list-in-java/

31)通过迭代器快速失败属性您了解什么?

失败快速迭代器一旦意识到自迭代开始以来就已经改变了Collection的结构,它就会失败。结构更改意味着在一个线程迭代该集合时,从集合中添加,删除或更新任何元素。

通过保留修改次数来实现快速失败行为,如果迭代线程实现了修改次数的更改,则会引发ConcurrentModificationException。

32)快速故障和故障安全之间有什么区别?

您已经在上一个问题中理解了快速失败。故障安全迭代器与快速故障相反。如果您修改要在其上进行迭代的基础集合,则它们永远不会失败,因为它们在Collection的克隆上而不是原始集合上起作用,这就是为什么将它们称为故障保护迭代器。

CopyOnWriteArrayList的迭代器是故障安全迭代器的示例,而且ConcurrentHashMap keySet编写的迭代器也是故障安全迭代器,并且永远不会抛出ConcurrentModificationException。

33)如何在迭代集合时避免ConcurrentModificationException?

首先,您应该尝试寻找另一种故障安全的替代迭代器。例如,如果您正在使用List,则可以使用ListIterator。如果它是旧式集合,则可以使用枚举。

如果上述选项不可行,则可以使用以下三种更改之一:

  • 如果使用的是JDK1.5或更高版本,则可以使用ConcurrentHashMap和CopyOnWriteArrayList类。这是推荐的方法。
  • 您可以将列表转换为数组,然后在数组上进行迭代。
  • 您可以通过将列表放在同步块中来在迭代时锁定列表。

请注意,最后两种方法会导致性能下降。

34)什么是UnsupportedOperationException?

实际的集合类型不支持的调用方法将引发此异常。

例如,如果您使用“ Collections.unmodifiableList(list)”创建一个只读列表列表,然后调用add()或remove()方法,那将会发生什么。它应该明确抛出UnsupportedOperationException。

35)哪些集合类提供对其元素的随机访问?

ArrayList,HashMap,TreeMap,Hashtable类提供对其元素的随机访问。

36)什么是BlockingQueue?

队列还支持以下操作:在检索元素时等待队列变为非空,并在存储元素时等待队列中的空间变为可用。

BlockingQueue方法有四种形式:一种抛出异常,第二种返回一个特殊值(根据操作的不同,返回null或false),第三种无限期地阻塞当前线程,直到操作成功为止;第四种仅针对a在放弃之前给出最大时间限制。

阅读post中的阻塞队列示例用法:如何使用阻塞队列?

37)什么是队列和堆栈,列出它们之间的差异?

设计用于在处理之前容纳元素的集合。除了基本的“收集”操作外,队列还提供其他插入,提取和检查操作。
队列通常但不一定以FIFO(先进先出)的方式对元素进行排序。

堆栈也是Queue的一种形式,但有一个区别,它是LIFO(后进先出)。

无论使用哪种顺序,队列的开头都是该元素,可以通过调用remove()或poll()将其删除。另请注意,堆栈和向量都已同步。

用法:如果要按接收顺序处理传入 Stream ,请使用队列。适用于工作列表和处理请求。
如果只想从堆栈顶部推入并弹出,请使用堆栈。适用于递归算法。

38)什么是可比较和比较器界面?

在Java中。所有具有自动排序功能的集合都使用比较方法来确保元素的正确排序。例如,使用排序的类为TreeSet,TreeMap等。

为了对数据元素进行排序,类需要实现Comparator或Comparable接口。这就是所有Wrapper类(例如Integer,Double和String类)都实现Comparable接口的原因。

可比有助于保留默认的自然排序,而比较器有助于按某些特殊的必需排序模式对元素进行排序。比较器的实例,如果通常在支持集合中作为集合的构造函数参数传递。

39)什么是Collections和Arrays类?

集合和数组类是特殊的实用程序类,用于支持集合框架核心类。它们提供实用程序功能以获取只读/同步集合,以各种方式对集合进行排序等。

数组还帮助对象数组转换为集合对象。数组还具有一些功能,有助于复制或处理部分数组对象。

40)推荐资源

好吧,这不是面试的问题.。 :-)。这只是为了好玩。但是您应该真正阅读我的博客,以获取有关收集框架知识的更多帖子。

希望这些Java集合面试问题对您的下一次面试有所帮助。此外,除了本文之外,我建议您阅读更多有关上述问题的信息。更多的知识只会帮助您。

 

saigon has written 1445 articles

Leave a Reply