安卓中高级开发面试之数据核心——数组集合高频面试题及解析

简介: 为什么这两个放在一起说,而没有分开写呢?诚然,集合或者数组二者随便其一,都不是一篇博客能写完的。但是在面试中,面试官一般不会出很多这方面的面试题,所以我们把数组和集合放在一起写一篇博客。

为什么这两个放在一起说,而没有分开写呢?

诚然,集合或者数组二者随便其一,都不是一篇博客能写完的。但是在面试中,面试官一般不会出很多这方面的面试题,所以我们把数组和集合放在一起写一篇博客。本文只罗列几个高频题,不罗列难题和全面集合或数组的知识点。如果想知道更多集合或者数组的知识点,可以私我向我索取。

话不多说,集合底层其实也是数组。

1.Java集合框架是什么?说出一些集合框架的优点?

每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。在保证线程安全的情况下使用泛型和并发集合类,Java已经经历了很久。它还包括在Java并发包中,阻塞接口以及它们的实现。集合框架的部分优点如下:

(1)使用核心集合类降低开发成本,而非实现我们自己的集合类。

(2)随着使用经过严格测试的集合框架类,代码质量会得到提高。

(3)通过使用JDK附带的集合类,可以降低代码维护成本。

(4)复用性和可操作性。

2.集合框架中的泛型有什么优点?

Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。它也给运行时带来好处,因为不会产生类型检查的字节码指令。

3.Iterator是什么?

Iterator接口提供遍历任何Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例。迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者在迭代过程中移除元素。

4.Iterater和ListIterator之间有什么区别?

(1)我们可以使用Iterator来遍历Set和List集合,而ListIterator只能遍历List。

(2)Iterator只可以向前遍历,而LIstIterator可以双向遍历。

(3)ListIterator从Iterator接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。

5.在Java中,HashMap是如何工作的?

HashMap在Map.Entry静态内部类实现中存储key-value对。HashMap使用哈希算法,在put和get方法中,它使用hashCode()和equals()方法。当我们通过传递key-value对调用put方法的时候,HashMap使用Key

hashCode()和哈希算法来找出存储key-value对的索引。Entry存储在LinkedList中,所以如果存在entry,它使用equals()方法来检查传递的key是否已经存在,如果存在,它会覆盖value,如果不存在,它会创建一个新的entry然后保存。当我们通过传递key调用get方法时,它再次使用hashCode()来找到数组中的索引,然后使用equals()方法找出正确的Entry,然后返回它的值。下面的图片解释了详细内容。

其它关于HashMap比较重要的问题是容量、负荷系数和阀值调整。HashMap默认的初始容量是32,负荷系数是0.75。阀值是为负荷系数乘以容量,无论何时我们尝试添加一个entry,如果map的大小比阀值大的时候,HashMap会对map的内容进行重新哈希,且使用更大的容量。容量总是2的幂,所以如果你知道你需要存储大量的key-value对,比如缓存从数据库里面拉取的数据,使用正确的容量和负荷系数对HashMap进行初始化是个不错的做法

6.hashCode()和equals()方法有何重要性?(这一个问题我在前文中有专门写一篇博客讲述)

HashMap使用Key对象的hashCode()和equals()方法去决定key-value对的索引。当我们试着从HashMap中获取值的时候,这些方法也会被用到。如果这些方法没有被正确地实现,在这种情况下,两个不同Key也许会产生相同的hashCode()和equals()输出,HashMap将会认为它们是相同的,然后覆盖它们,而非把它们存储到不同的地方。同样的,所有不允许存储重复数据的集合类都使用hashCode()和equals()去查找重复,所以正确实现它们非常重要。equals()和hashCode()的实现应该遵循以下规则:

(1)如果o1.equals(o2),那么o1.hashCode()== o2.hashCode()总是为true的。

(2)如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。

7.HashMap和HashTable有何不同?

(1)HashMap允许key和value为null,而HashTable不允许。

(2)HashTable是同步的,而HashMap不是。所以HashMap适合单线程环境,HashTable适合多线程环境。

(3)在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的。

(4)HashMap提供对key的Set进行遍历,因此它是fail-fast的,但HashTable提供对key的Enumeration进行遍历,它不支持fail-fast。

(5)HashTable被认为是个遗留的类,如果你寻求在迭代的时候修改Map,你应该使用CocurrentHashMap。

8.ArrayList和Vector有何异同点?

ArrayList和Vector在很多时候都很类似。

(1)两者都是基于索引的,内部由一个数组支持。

(2)两者维护插入的顺序,我们可以根据插入顺序来获取元素。

(3)ArrayList和Vector的迭代器实现都是fail-fast的。

(4)ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。

以下是ArrayList和Vector的不同点。

(1)Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。

(2)ArrayList比Vector快,它因为有同步,不会过载。

(3)ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。

9.Array和ArrayList有何区别?什么时候更适合用Array?

Array可以容纳基本类型和对象,而ArrayList只能容纳对象。

Array是指定大小的,而ArrayList大小是固定的。

Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。尽管ArrayList明显是更好的选择,但也有些时候Array比较好用。

(1)如果列表的大小已经指定,大部分情况下是存储和遍历它们。

(2)对于遍历基本数据类型,尽管Collections使用自动装箱来减轻编码任务,在指定大小的基本类型的列表上工作也会变得很慢。

(3)如果你要使用多维数组,使用[][]比List<List<>>更容易

10.当一个集合被作为参数传递给一个函数时,如何才可以确保函数不能修改它?

在作为参数传递之前,我们可以使用Collections.unmodifiableCollection(Collection c)方法创建一个只读集合,这将确保改变集合的任何操作都会抛出UnsupportedOperationException。

11.说一下链表跟数组的区别

链表:用一组任意储存单元存放线性表的数据元素,并且通过指针链相接结点的序列称为链表。是一种常见的数据组织形式,它采用了动态分配内存的形式实现。需要时可以用new分配内存空间,不需要时用delete将已分配的空间释放,不会造成内存空间的浪费。不靠数组实现,没有下标。数组必须事先定义固定的长度,不能适应数据动态增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成数据浪费。在使用的时候还要数组初始化,注意数组的下标越界。

12.ArrayList集合加入1万条数据,应该怎么提高效率

因为ArrayList的底层是数组实现,并且数组的默认值是10,如果插入10000条要不断的扩容,耗费时间,所以我们调用ArrayList的指定容量的构造器方法ArrayList(int size) 就可以实现不扩容,就提高了性能

最后给大家出一个高频面试题:队列和栈是什么,列出它们的区别?各位自己去查吧,这个问题我就不做解答了。

给大家一个提示:栈和队列两者都被用来预存储数据。java.util.Queue是一个接口,它的实现类在Java并发包中。队列允许先进先出(FIFO)检索元素,但并非总是这样。Deque接口允许从两端检索元素。

栈与队列很相似,但它允许对元素进行后进先出(LIFO)进行检索。

Stack是一个扩展自Vector的类,而Queue是一个接口。

队列的两个基本操作:一个是插入一个数据项,即把一个数据项放入队尾另一个是移除一个数据项,即移除队头的数据项.


最后给大家来一个开心一笑


img_f4820e7a1b235b232ed4c105f46ad42d.png
给你一个写注释的机会,写完就走吧
相关文章
|
7天前
|
存储 安全 Android开发
安卓应用开发:构建一个高效的用户登录系统
【5月更文挑战第3天】在移动应用开发中,用户登录系统的设计与实现是至关重要的一环。对于安卓平台而言,一个高效、安全且用户体验友好的登录系统能够显著提升应用的用户留存率和市场竞争力。本文将探讨在安卓平台上实现用户登录系统的最佳实践,包括对最新身份验证技术的应用、安全性考量以及性能优化策略。
|
9天前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
1天前
|
Java API 开发工具
java与Android开发入门指南
java与Android开发入门指南
8 0
|
1天前
|
XML 存储 开发框架
c#教你网站数据轻松解析抓取,HtmlAgilityPack解析的奇妙之处
c#教你网站数据轻松解析抓取,HtmlAgilityPack解析的奇妙之处
7 0
|
2天前
|
Android开发 Kotlin
Kotlin开发Android之基础问题记录
Kotlin开发Android之基础问题记录
14 1
|
2天前
|
Java Android开发
Android开发@IntDef完美替代Enum
Android开发@IntDef完美替代Enum
10 0
|
3天前
|
Linux 开发工具 Android开发
移动应用与系统:开发与操作系统的深度解析
【5月更文挑战第6天】 在数字化时代,移动应用和操作系统是信息技术的核心组成部分。本文深入探讨了移动应用的开发过程、关键技术以及移动操作系统的架构和功能。通过对这些技术的详细分析,我们可以更好地理解移动应用和系统的工作原理,以及它们如何影响我们的生活和工作。
|
3天前
|
JSON 安全 前端开发
解析FormData格式数据:Python实践指南
解析FormData格式数据:Python实践指南
12 1
|
3天前
|
Android开发
Android 盒子开发过程中遇到的问题及解决方法
Android 盒子开发过程中遇到的问题及解决方法
7 2
|
4天前
|
机器学习/深度学习 算法 Android开发
安卓应用开发:打造高效通知管理系统
【5月更文挑战第6天】 在现代移动应用的海洋中,用户经常面临信息过载的挑战。一个精心设计的通知管理系统对于提升用户体验至关重要。本文将探讨在安卓平台上如何实现一个高效的通知管理系统,包括最佳实践、系统架构设计以及性能优化技巧。通过分析安卓通知渠道和优先级设置,我们的目标是帮助开发者构建出既能吸引用户注意,又不会引发干扰的智能通知系统。
16 2

推荐镜像

更多