集合高级面试题

1. ArrayList 和 Vector 的区别?

参考答案

  这两个类都实现了 List 接口(List 接口继承了 Collection 接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的数据是允许重复的,这是同 HashSet 之类的集合的最大不同处,HashSet 之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与 hashset 没有任何关系,但为了说清楚 ArrayList 与 Vector 的功能,我们使用对比方式,更有利于说明问题接着才说 ArrayList 与 Vector 的区别)。两者的区别主要包括两个方面:1. 同步性:Vector 是线程安全的,也就是说是它的方法之间是线程同步的,而 ArrayList 是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用 ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用 Vector,因为不需要我们自己再去考虑和编写线程安全的代码。2. 数据增长:ArrayList 与 Vector 都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加 ArrayList 与 Vector 的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector 默认增长为原来两倍,而 ArrayList 的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的 1.5 倍)。ArrayList 与 Vector 都可以设置初始的空间大小,Vector 还可以设置增长的空间大小,而 ArrayList 没有提供设置增长空间的方法。总结:即 Vector 增长原来的一倍,ArrayList 增加原来的 1.5 倍。
2. HashMap 的负载因子是什么意思,数值是多少?

参考答案

  负载因子表示一个哈希表的空间的使用程度,有这样一个公式:HashMap 的容量 = 初识化容量(initailCapacity)* 负载因子(loadFactor)所以负载因子越大则哈希表的装填程度越高,也就是能容纳更多的元素,元素多了,链表大了,所以此时索引效率就会降低。反之,负载因子越小则链表中的数据量就越稀疏,此时会对空间造成浪费,但是此时索引效率会高。
HashMap 有三个构造函数,可以选用有参构造函数设置初始化容量和负载因子,也可以选用无参构造函数,不进行设置,此时会使用默认值,分别是 16 和 0.75。
3. HashMap 的负载因子设置过大或过小会有什么问题?

参考答案

  首先负载因子的大小决定了 HashMap 的数据密度的。负载因子越大数据密度越大,可能发生碰撞的几率越高,数组中的链表也会越容易长,这样查询和插入时的比较次数增多,性能会下降。(ps:此处可能又引出一个面试题:如何解决 Hash 碰撞问题?答:利用拉链法)如果负载因子越小,就会越容易触发扩容,虽然数据密度也越小,发生碰撞几率小,数组中链表越短对于查询和插入时比较次数也会少一些,性能也会提高。但是扩容也会影响性能,所以建议初始化预设大一点空间。
4. 你觉得 HashMap 的负载因子设置为多少较为合理?

参考答案

  HashMap 初始容量大小默认是 16,这是为了减少冲突发生的概率,当 HashMap 的数组长度到达一个临界值的时候,就会触发扩容:把所有元素 rehash 之后再放在扩容后的容器中,这是一个相当耗时且浪费性能的操作,所以扩容是件影响性能的事。而这个临界值就是由负载因子和当前容器的容量大小来确定的。临界值:默认容量大小 = 16 * 负载因子,即:默认 16 乘 0.75=12 此时就会发生扩容操作。考虑将负载因子设置为 0.7~0.75,因为此时平均检索长度接近于常数,这样会更好一些。
5. 请描述一下 HashMap 的扩容机制?

参考答案

  HashMap 的扩容会有以下接个步骤:1、HashMap 在 Java7 时是基于数组 + 链表存储的。默认长度是 0,第一次添加数据时数组扩容到 16,临界值(threshold)是 16 * 负载因子(loadFactor 是 0.75)= 12。2、如果数组的使用到了临界值 12,就会扩容到 16 * 2 = 32,新的临界值就是 32 * 0.75 = 24,依次类推。3、Java8 以后,HashMap 引入了红黑树机制,如果一条链表中的元素个数到达 TREEIFY_THRESHOLD(默认是 8),并且 table(哈希表)的大小 >= MIN_TREEIFY_CAPACITY(默认 64),就会进行树化(红黑树),否则仍然采用数组扩容机制。
6. HashMap 的树化链表默认值为什么是 8?

参考答案

  对于 HashMap 来说,完整的表述应该是:**当链表长度为 8 时会链表转树,长度为 6 时会树转链表。** 这里可以看到中间存在一个差值,这么设计是为了防止链表和树之间频繁的转换。假如只把转化的长度限制为 8 的话,那么一个 HashMap 如果不停的插入或删除数据,并且链表长度恰巧在 8 左右徘徊,这时就会不停的树转链表,链表转树,效率很低。为什么链表长度为 8 时会实现链表转树呢?因为红黑树的平均查找长度是 log(n),长度为 8 的时候,平均查找长度为 3,而链表的平均查找长度为 n/2,当长度为 8 时,平均查找长度为 8/2=4。所以,当长度大于等于 8 的时候,树的查找效率更高。另外在 HashMap 源码中可以看出,8的长度符合数学中的泊松分布概念。一个链表中出现 8 个节点的概率不到千万分之一,概率已经非常低了,此时树化性价比会很高。既不会因为链表太长(8)导致复杂度加大,也不会因为概率太高导致太多节点树化。
7. HashMap 有反向树化的操作吗?

参考答案

  HashMap 解决 hash 冲突是使用了 **拉链法**。jdk1.8 中,当一个桶链表节点超过 TREEIFY_THRESHOLD=8 后,链表会转换为红黑树,当桶中节点移除或重新哈希少于 UNTREEIFY_THRESHOLD=6 时,红黑树会转变为普通的链表。
8. 快速失败 (fail-fast) 和安全失败 (fail-safe) 的区别是什么?(扩展知识点)

参考答案

1、快速失败(fail-fast)在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行修改(增加、删除、修改),则会抛出 Concurrent Modification Exception。原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变 modCount 的值。每当迭代器使用 hashNext() / next() 遍历下一个元素之前,都会检测 modCount 变量是否为 expectedmodCount 值,是的话就返回遍历;否则抛出异常,终止遍历。注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount 这个条件。如果集合发生变化时修改 modCount 值刚好又设置为了 expectedmodCount 值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的 bug。场景:java.util 包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。
2、安全失败(fail-safe)采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发 Concurrent Modification Exception。缺点:基于拷贝内容的优点是避免了 Concurrent Modification Exception,但同样,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的场景:java.util.concurrent 包下的容器都是安全失败,可以在多线程下并发使用,并发修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/588168.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js获取某天日期

获取某天日期 getSomeDay(someDay) {let currentDate new Date();let targetday_milliseconds currentDate.getTime() 1000 * 60 * 60 * 24 * someDay;currentDate.setTime(targetday_milliseconds);const doHandleMonth (month) > {let m month;if (month.toString()…

2023-12-30 AIGC-LangChain介绍

摘要: 2023-12-30 AIGC-LangChain介绍 LangChain介绍 1. https://youtu.be/Ix9WIZpArm0?t353 2. https://www.freecodecamp.org/news/langchain-how-to-create-custom-knowledge-chatbots/ 3. https://www.pinecone.io/learn/langchain-conversational-memory/ 4. https://de…

SQL高级:存储过程和触发器

在前面的内容中,我们学习了视图的概念和使用,视图实际上代表了一种自定义的结果集,可以理解为一个虚拟表。它诠释了部分数据的逻辑关系,但并不会操作数据。 如果有一些需求可以通过多个DML SQL组合起来完成,我们就可以使用存储过程。存储过程可以类比其他编程语言中的方法…

乒乓球室计时计费软件,乒乓球馆怎么计时

一,软件程序问答 1、软件有计时功能吗,有会员管理功能吗? 如下图,软件以 佳易王乒乓球馆计时计费软件 为例说明 软件既可以既可以计时计费,也可以会员管理,会员可以用卡片也可以直接用手机号即可。 2、软…

2023年度总结——关于如何认清自己是个FW

前言 不到各位有没有今年过得特别快的感觉。写总结时候一整理,我敲,我今年这么忙? 从三月份开说 三月份 这段时间刚开学,还算比较懵懂。不过初生牛犊不怕虎,那个寒假学了点怎么挖edusrc,开学迫不及待地…

SpireCV项目实战——电诈园区人员及房屋情况识别

项目介绍前言 随着科技的进步和大数据时代的到来,计算机视觉技术逐渐渗透到各个行业领域,为人们的生活和工作带来了诸多便利。近年来,电信诈骗案件频发,给社会带来了巨大的经济损失和心理负担。电诈园区作为电信诈骗的高发区域&a…

弱电工程计算机网络系统基础知识

我们周围无时无刻不存在一张网,如电话网、电报网、电视网、计算机网络等;即使我们身体内部也存在许许多多的网络系统,如神经系统、消化系统等。最为典型的代表即计算机网络,它是计算机技术与通信技术两个领域的结合。 计算机网络的…

【QT】qt各模块描述

【未完待续】 QT主要版本,各个模块的作用描述。 QT5.12 版本(只有部分) qtgamepad: 提供了对游戏手柄的支持。qtandroidextras: 提供了一些特定于Android的功能。qtmacextras: 提供了一些特定于macOS的功能。qtx11extras: 提供了一些特定于X11的功能。qtsensors:…

spring ioc源码-refresh();

主要作用是刷新应用上下文 Override public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 启动刷新的性能跟踪步骤StartupStep contextRefresh this.applicationStartup.start("spring.context.refre…

Typescript面向对象

面向对象 面向对象是程序中一个非常重要的思想,它被很多同学理解成了一个比较难,比较深奥的问题,其实不然。面向对象很简单,简而言之就是程序之中所有的操作都需要通过对象来完成。 举例来说: 操作浏览器要使用windo…

Windows 10启用Hyper-V

Windows 10启用Hyper-V 官网教程PowerShell 启用 Hyper-V启用 Hyper-V 角色 我们知道VMware是创建虚拟机的好工具,那Windows平台上有没有虚拟工具呢? 今天我们要讲解的就是Windows才入局的虚拟工具:Hyper-V 官网教程 https://learn.microsof…

2024年的学习规划和碎碎念

2023最后一天,仿佛都要将自己变成小孩子,在等待新的一年。春节与我的意义不大,我反而期待元旦,好似跨过去,我就蜕变成新的人啦,全身血液换了个变,人也不是之前的灵魂。 当然那不可能。回顾自己…

table表格中使用el-popover 无效问题解决

实例只针对单个的按钮管用在表格里每一列都有el-popover相当于是v-for遍历了 所以我们在触发按钮的时候并不是单个的触发某一个 主要执行 代码 <el-popover placement"left" :ref"popover-${scope.$index}"> 动态绑定了ref 关闭弹窗 执行deltask…

【数据结构和算法】找出两数组的不同

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 哈希类算法题注意事项 2.2 方法一&#xff1a;哈希法 三、代码 3.1 方法一&#xff1a;哈希法 四…

Linux文件类型

在 Linux 系统中&#xff1a; b 文件类型&#xff1a;代表块设备文件。块设备文件通常是对应于设备&#xff0c;如硬盘驱动器或其他块设备&#xff0c;使用块级别的 I/O 操作。 c 文件类型&#xff1a;代表字符设备文件。字符设备文件通常是对应于设备&#xff0c;如串口、键盘…

[年终总结]人生就是大闹一场

讲真的,感觉过去这一年的体验,非常精彩,哈哈哈哈 体验了 裸辞,并没有想象中那么可怕,也没有想象中那么焦虑 经历了 入职之后又被裁员,心情没有那么大的起伏 解锁了 深圳/佛山/珠海/澳门/昆明/大理/新疆/成都 ,见了很多人,碰撞出了很多 idea 体会了 没有目的的去做一件事情,是什…

GitHub的2FA验证问题解决工具

文章目录 前言认识2FA开源工具使用&#xff1a;AuthenticatorPro获取AuthenticatorPro的安卓APK如何使用 参考文章 前言 打开GitHub跳出来这个提示&#xff0c;需要进行验证&#xff1a; 如何解决呢&#xff1f;方案有很多&#xff0c;我们可以使用开源的一个工具&#xff1a;…

vue 动态添加style样式

示例1 <div class"qrcode" :style"{display: qrcodeShow?:none}"><img src"../assets/images/qrcode.jpg"> </div>{display: qrcodeShow?:none} 为JS对象。 示例2 <div class"qrcode" :style"qrcodeSt…

爬虫工作量由小到大的思维转变---<第三十一章 Scrapy Redis 初启动/conn说明书)>

前言: 重点在读connection.py的源码,这个组件主要是用来连接的; 因为连接都无法做到,后面想更改点自定义就白扯了; 正文: 翻译版的connection.py源码: import sys import six from scrapy.utils.misc import load_object from . import defaults# 快捷方式映射 设置名称 -&…

Kotlin 属性

1、声明 关键字 var 声明为可变的 关键字 val 声明为只读的 class Address {val name: String "Holmes, Sherlock"val street: String "Baker"var city: String "London"var state: String? nullvar zip: String "123456" } …