当前位置: 首页 > news >正文

Java 基础面试题——集合

目录

  • 1.Java 有哪些常用容器(集合)?
  • 2.Collection 和 Collections 有什么区别?
  • 3.List、Set、Map 之间的区别是什么?
  • 4.HashMap 的长度为什么是 2 的 N 次方?源码中是如何保证的?
  • 5.HashMap 和 Hashtable 的异同有哪些?
  • 6.HashMap 与 ConcurrentHashMap 的异同有哪些?
  • 7.poll() 方法和 remove() 方法有什么异同?
  • 8.ArrayList 和 LinkedList 有什么区别?

1.Java 有哪些常用容器(集合)?

在这里插入图片描述
(1)从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,ListSetQueue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。

在这里插入图片描述
(2)集合框架体系如下图所示:
在这里插入图片描述

2.Collection 和 Collections 有什么区别?

(1)Collection 是 JDK 中集合层次结构中的最根本的接口,定义了集合类的基本方法。Collection 接口在 Java 类库中有很多具体的实现,其意义是为各种具体的集合提供了最大化的统一操作方式。
(2)Collections 是一个包装类,是 Collection 集合框架的工具类。它包含有各种有关集合操作的静态多态方法,不能实例化,比如排序方法: Collections. sort(list)。

3.List、Set、Map 之间的区别是什么?

(1)List:有序集合,元素可重复;
(2)Set:不重复集合,LinkedHashSet 按照插入排序,SortedSet 可排序,HashSet 无序;
(3)Map:键值对集合,存储键、值和之间的映射;Key无序且唯一;value 不要求有序,允许重复。

4.HashMap 的长度为什么是 2 的 N 次方?源码中是如何保证的?

(1)为了能让 HashMap 存数据和取数据的效率高,尽可能地减少 hash 值的碰撞,也就是说尽量把数据均匀地分配,每个链表或者红黑树的长度尽量相等。我们首先可能会想到通过取模操作来实现。取余 (%) 操作中如果除数是 2 的幂次,则等价于与其除数减一的与(&)操作,也就是说 hash % length == hash & (length - 1) 的前提是 length 是 2 的 N 次方。并且,采用二进制位操作 & ,相对于 % 能够提高运算效率。
注:HashMap 的初始长度是 16。

(2)在扩容迁移的时候不需要再重新通过哈希定位新的位置了。扩容后元素新的位置,要么在原脚标位,要么在原脚标位 + 扩容长度的位置
(3)HashMap 源码中的 tableSizeFor(int cap) 可以保证其长度永远是是 2 的 N 次方

/*** Returns a power of two size for the given target capacity.*/
static final int tableSizeFor(int cap) {int n = cap - 1;n |= n >>> 1;n |= n >>> 2;n |= n >>> 4;n |= n >>> 8;n |= n >>> 16;return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

具体分析可参考这篇文章。

5.HashMap 和 Hashtable 的异同有哪些?

(1)出现的版本不一样,Hashtable 出现于 Java 发布的第一版本 JDK 1.0,HashMap 出现于 JDK 1.2。
(2)都实现了 Map、Cloneable、Serializable(当前 JDK 版本 1.8)。
(3)HashMap 继承的是 AbstractMap,并且 AbstractMap 也实现了 Map 接口。Hashtable 继承Dictionary。
(4)Hashtable 中大部分 public 修饰普通方法都是 synchronized 字段修饰的,是线程安全的,HashMap 是非线程安全的。
(5)Hashtable 的 key 不能为 null,value 也不能为 null,这个可以从 Hashtable 源码中的 put 方法看到,判断如果 value 为 null 就直接抛出空指针异常,在 put 方法中计算 key 的 hash 值之前并没有判断 key 为 null 的情况,那说明,这时候如果 key 为空,照样会抛出空指针异常。
(6)HashMap 的 key 和 value 都可以为 null。在计算 hash 值的时候,有判断,如果 key==null ,则其 hash=0 ;至于 value 是否为 null,根本没有判断过。
(7)Hashtable 直接使用对象的 hash 值。hash 值是 JDK 根据对象的地址或者字符串或者数字算出来的 int 类型的数值。然后再使用除留余数法来获得最终的位置。然而除法运算是非常耗费时间的,效率很低。HashMap 为了提高计算效率,将哈希表的大小固定为了 2 的幂,这样在取模预算时,不需要做除法,只需要做位运算。位运算比除法的效率要高很多。
(8)Hashtable、HashMap 都使用了 Iterator。而由于历史原因,Hashtable 还使用了 Enumeration 的方式。
(9)默认情况下,初始容量不同,Hashtable 的初始长度是 11,之后每次扩充容量变为之前的 2 * n+1(n 为上一次的长度)而 HashMap 的初始长度为 16,之后每次扩充变为原来的两倍。

具体细节可参考这篇文章。

6.HashMap 与 ConcurrentHashMap 的异同有哪些?

(1)都是 key-value 形式的存储数据;
(2)HashMap 是线程不安全的,ConcurrentHashMap 是 JUC 下的线程安全的;
(3)HashMap 底层数据结构是数组 + 链表(JDK 1.8 之前)。JDK 1.8 之后是数组 + 链表 + 红黑树。当链表中元素个数达到 8 的时候,链表的查询速度不如红黑树快,链表会转为红黑树,红黑树查询速度快;
(4)HashMap 初始数组大小为 16(默认),当出现扩容的时候,变为原来的两倍;
(5)ConcurrentHashMap 在 JDK 1.8 之前是采用分段锁来现实的 Segment + HashEntry,
(6)Segment 数组大小默认是 16,2 的 n 次方;JDK 1.8 之后,采用 Node + CAS + Synchronized 来保证并发安全进行实现。

具体细节可参考这篇文章

7.poll() 方法和 remove() 方法有什么异同?

(1)相同点:poll() 和 remove() 都是从队列中取出一个元素
(2)不同点:poll() 在获取元素失败的时候会返回空,但 remove() 失败的时候会抛出异常

8.ArrayList 和 LinkedList 有什么区别?

(1)底层数据结构
ArrayList 是基于动态数组实现的,在一片连续的内存空间中存储数据。
LinkedList 是基于链表实现的,数据可以存储在分散的内存空间中。

(2)读取、插入、删除操作
由于底层数据结构的不同,读取、插入、删除操作的性能也会有所不同。
① 在读取方面 ArrayList 的性能比 LinkedList 高,ArrayList 支持通过索引访问(也称随机访问),可以在 O(1) 的时间复杂度内进行随机读取。而 LinkedList 需要从头开始遍历直到找到目标元素为止,其时间复杂度为 O(n)。
② 对于插入、删除操作,一般来说,LinkedList 的性能要比 ArrayList 高。ArrayList 在插入和删除元素时,可能需要进行元素移动甚至扩容操作;而 LinkedList 只需找到要插入的位置并实例化对象,然后修改节点指针即可。不过需要注意的是如果 ArrayList 使用尾插法并指定初始容量,这可以极大地提升性能,甚至超过 LinkedList。

(3)遍历操作
ArrayList 和 LinkedList 常见的遍历方式有 3 种:for(结合 get(i) 方法)、foreach、iterator。
① 在数据量比较小时,不同遍历方式的性能差别不大。
② 但是在数据量比较大时:
对于 ArrayList 来说,3 种遍历方式差距不是很大,其中 for 循环的效率最高,因为采用直接的下标运算。对于 LinkedList 来说,迭代器效率最高,因为其相当于维护一个当前状态指针,遍历只需要扫描一遍双向链表即可,而 for 效率最低,因为需要扫描 n 遍链表。不难看出,两种 List 中,foreach 的效率都比迭代器略低,因为其底层就是由迭代器实现的,只不过为了方便书写,做了简单的封装。

具体细节可参考 ArrayList 和 LinkedList 的三种遍历方式 这篇文章。

(4)内存空间利用率
一般来说,存储相同类型、相同大小的数据时,LinkedList 比 ArrayList 更占内存,其内存空间利用率更低,因为 LinkedList 为每一个节点存储了两个引用节点,一个指向前一个元素,另一个指向下一个元素。不过有时在 ArrayList 列表的结尾预留一定的容量空间,这也会造成一定的内存空间的浪费。

(5)扩容问题
ArrayList 使用动态数组实现,无参构造函数中默认初始化长度为 10,当需要扩容时会将原数组中的元素重新拷贝到长度为原数组的 1.5 倍的新数组中,扩容代价比较高;LinkedList 通过链表实现,所以不存在扩容问题,新增元素直接放到集合尾部,并修改相应的指针节点即可。

相关文章:

Java 基础面试题——集合

目录1.Java 有哪些常用容器&#xff08;集合&#xff09;&#xff1f;2.Collection 和 Collections 有什么区别&#xff1f;3.List、Set、Map 之间的区别是什么&#xff1f;4.HashMap 的长度为什么是 2 的 N 次方&#xff1f;源码中是如何保证的&#xff1f;5.HashMap 和 Hasht…...

编程思想、方法论和架构模式的应用

概要编程思想是指在编写代码时所采用的基本思维方式和方法论。分类编程思想分类&#xff1a;面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;&#xff1a;把数据和对数据的操作封装在一起&#xff0c;通过类和对象的概念实现模块化、可重…...

Vue|事件处理

事件处理1. 事件使用1.1 事件绑定1.2 事件参数2. 事件修饰符2.1 阻止默认事件2.2 阻止事件冒泡2.3 事件只允许触发一次2.4 事件捕获2.5 操作当前元素2.6 行为立即执行无需等待回调3. 键盘事件4. 本章小结4.1 事件使用小结4.2 事件修饰符小结4.3 键盘事件小结1. 事件使用 1.1 事…...

css书写方式

目录标题一、css是什么&#xff1f;二、css的书写方式1、行内样式【不推荐使用&#xff0c;太固定】2、页面样式&#xff08;又叫内联样式&#xff09;3、外联样式【店家推荐】4、import与link标签的区别一、css是什么&#xff1f; css(cascade style sheet)是用来装饰和装扮页…...

Python网络爬虫 学习笔记(2)BeaufitulSoup库

文章目录BeautifulSoup库的基本介绍HTML标签的获取和相关属性HTML文档的遍历prettify()方法使用BeautifulSoup库对HTML文件进行内容查找信息的标记的相关概念&#xff08;非重点&#xff09;find_all()方法&#xff08;重点&#xff09;综合实例&#xff1a;爬取软科2022中国大…...

JavaScript------内建对象

一、解构赋值 1、数组的解构 1.1、解构赋值 const arr ["孙悟空", "猪八戒", "沙和尚"];let a, b, c;[a, b, c] arr; // 等同于 [a, b, c] ["孙悟空", "猪八戒", "沙和尚"] 1.2、声明同时解构 let [d, e…...

React + Redux 处理异步请求

redux 处理异步请求 方式一:在 componentDidmount 中直接进⾏请求,在将数据同步到 redux 创建 Store 仓库 import {createStore } from redux;const defaultState = {banners: [] }const reducer =...

揭秘涨薪50%经验:从功能测试到自动化测试,我是如何蜕变的?

本人在今年互联网大环境如此严峻的情况下&#xff0c;作为一个刚毕业不到一年的初级测试&#xff0c;赶在“金三银四”依然拿到了一些面试机会&#xff0c;并且成功拿下4家公司的offer&#xff0c;其中不乏互联网大厂&#xff0c;而且最高总包给到了接近double&#xff08;无炫…...

【论文速递】MMM2020 - 电子科技大学提出一种新颖的局部变换模块提升小样本分割泛化性能

【论文速递】MMM2020 - 电子科技大学提出一种新颖的局部变换模块提升小样本分割泛化性能 【论文原文】&#xff1a;A New Local Transformation Module for Few-shot Segmentation 【作者信息】&#xff1a;Yuwei Yang, Fanman Meng, Hongliang Li, Qingbo Wu,Xiaolong Xu an…...

补充前端面试题(二)

#$set数据变化视图不更新问题, 当在项目中直接设置数组的某一项的值&#xff0c;或者直接设置对象的某个属性值&#xff0c;这个时候&#xff0c;你会发现页面并没有更新。这是因为 Object.defineProperty()限制&#xff0c;监听不到变化。解决方式&#xff1a;this.$set(你要改…...

JavaScript原型、原型链、原型方法

文章目录原型和原型链prototype、 __ proto __ 、constructor原型链原型方法instanceOfhasOwnPropertyObject.create()、new Object()总结原型和原型链 prototype、 __ proto __ 、constructor 首先我们看下面一段代码 // 构造函数Personfunction Person(name, age) {this.na…...

linux篇【14】:网络https协议

目录 一.HTTPS介绍 1.HTTPS 定义 2.HTTP与HTTPS &#xff08;1&#xff09;端口不同&#xff0c;是两套服务 &#xff08;2&#xff09;HTTP效率更高&#xff0c;HTTPS更安全 3.加密&#xff0c;解密&#xff0c;密钥 概念 4.为什么要加密&#xff1f; 5.常见的加密方式…...

1.9实验9:配置虚链路

1.4.4实验9:配置虚链路 实验目的(1) 实现OSPF 虚链路的配置 (2) 描述虚链路的作用 实验拓扑配置虚链路实验拓扑如图1-19所示。[1] 图1-19 配置虚链路 实验步骤...

三次握手-升级详解-注意问题

TCP建立连接的过程就是三次握手&#xff08;Three-way Handshake&#xff09;&#xff0c;在建立连接的过程实际上就是客户端和服务端之间总共发送三个数据包。进行三次握手主要是就是为了确认双方都能接收到数据包和发送数据包&#xff0c;而客户端和服务端都会指定自己的初始…...

软件架构知识3-系统复杂度-高可用性、可扩展性、低成本、安全、规模

高可用性 系统无中断地执行其功能的能力&#xff0c;代表系统的可用性程度&#xff0c;是进行系统设计时的准则之一。 高可用的“冗余”解决方案&#xff0c;单纯从形式上来看&#xff0c;和之前讲的高性能是一样的&#xff0c;都是通过增加更多机 器来达到目的&#xff0c;但…...

SpringCloud学习笔记 - 自定义及解耦降级处理方法 - Sentinel

1. SentinelRecourse配置回顾 通过之前的学习&#xff0c;我们知道SentinelRecourse配置的资源定位可以通过两种方式实现&#xff1a;一种是URL&#xff0c;另一种是资源名称。这两种限流方式都要求资源ID唯一 RestController public class RateLimitController {GetMapping(…...

Redis之搭建一主多从

搭建redis一主多从的过程 1.在相应位置创建一个文件夹存放redis配置文件 mkdir myredis2.复制redis配置文件到此文件夹中 cp /opt/redis/redis/bin/redis.conf /opt/myredis/redis.conf3.新建三个配置文件 touch redis6379.conf touch redis6380.conf touch redis6381.conf4…...

Transformer机制学习笔记

学习自https://www.bilibili.com/video/BV1J441137V6 RNN&#xff0c;CNN网络的缺点 难以平行化处理&#xff0c;比如我们要算b4b^4b4&#xff0c;我们需要一次将a1a^1a1~a4a^4a4依次进行放入网络中进行计算。 于是有人提出用CNN代替RNN 三角形表示输入&#xff0c;b1b^1b1的…...

1、第一个CUDA代码:hello gpu

目录第一个CUDA代码&#xff1a;hello gpu一、__global__ void GPUFunction()二、gpu<<<1,1>>>();三、线程块、线程、网格知识四、核函数中的printf();五、cudaDeviceSynchronize();第一个CUDA代码&#xff1a;hello gpu #include <stdio.h>void cpu(…...

UG二次开发装配篇 添加/拖动/删除组件方法的实现

我们在UG装配的过程中&#xff0c;经常会遇到需要调整组件目录位置&#xff0c;在软件设计过程中可以通过在目录树里面拖动组件来完成。 那么&#xff0c;如果要用程序实现组件的移动/拖动&#xff0c;我们要怎么做呢&#xff1f; 本节就完成了添加/拖动/删除组件方法的实现&…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...