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 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 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 有哪些常用容器(集合)?2.Collection 和 Collections 有什么区别?3.List、Set、Map 之间的区别是什么?4.HashMap 的长度为什么是 2 的 N 次方?源码中是如何保证的?5.HashMap 和 Hasht…...
编程思想、方法论和架构模式的应用
概要编程思想是指在编写代码时所采用的基本思维方式和方法论。分类编程思想分类:面向对象编程(Object-Oriented Programming,简称OOP):把数据和对数据的操作封装在一起,通过类和对象的概念实现模块化、可重…...
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是什么?二、css的书写方式1、行内样式【不推荐使用,太固定】2、页面样式(又叫内联样式)3、外联样式【店家推荐】4、import与link标签的区别一、css是什么? css(cascade style sheet)是用来装饰和装扮页…...
Python网络爬虫 学习笔记(2)BeaufitulSoup库
文章目录BeautifulSoup库的基本介绍HTML标签的获取和相关属性HTML文档的遍历prettify()方法使用BeautifulSoup库对HTML文件进行内容查找信息的标记的相关概念(非重点)find_all()方法(重点)综合实例:爬取软科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%经验:从功能测试到自动化测试,我是如何蜕变的?
本人在今年互联网大环境如此严峻的情况下,作为一个刚毕业不到一年的初级测试,赶在“金三银四”依然拿到了一些面试机会,并且成功拿下4家公司的offer,其中不乏互联网大厂,而且最高总包给到了接近double(无炫…...
【论文速递】MMM2020 - 电子科技大学提出一种新颖的局部变换模块提升小样本分割泛化性能
【论文速递】MMM2020 - 电子科技大学提出一种新颖的局部变换模块提升小样本分割泛化性能 【论文原文】:A New Local Transformation Module for Few-shot Segmentation 【作者信息】:Yuwei Yang, Fanman Meng, Hongliang Li, Qingbo Wu,Xiaolong Xu an…...
补充前端面试题(二)
#$set数据变化视图不更新问题, 当在项目中直接设置数组的某一项的值,或者直接设置对象的某个属性值,这个时候,你会发现页面并没有更新。这是因为 Object.defineProperty()限制,监听不到变化。解决方式: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 (1)端口不同,是两套服务 (2)HTTP效率更高,HTTPS更安全 3.加密,解密,密钥 概念 4.为什么要加密? 5.常见的加密方式…...
1.9实验9:配置虚链路
1.4.4实验9:配置虚链路 实验目的(1) 实现OSPF 虚链路的配置 (2) 描述虚链路的作用 实验拓扑配置虚链路实验拓扑如图1-19所示。[1] 图1-19 配置虚链路 实验步骤...
三次握手-升级详解-注意问题
TCP建立连接的过程就是三次握手(Three-way Handshake),在建立连接的过程实际上就是客户端和服务端之间总共发送三个数据包。进行三次握手主要是就是为了确认双方都能接收到数据包和发送数据包,而客户端和服务端都会指定自己的初始…...
软件架构知识3-系统复杂度-高可用性、可扩展性、低成本、安全、规模
高可用性 系统无中断地执行其功能的能力,代表系统的可用性程度,是进行系统设计时的准则之一。 高可用的“冗余”解决方案,单纯从形式上来看,和之前讲的高性能是一样的,都是通过增加更多机 器来达到目的,但…...
SpringCloud学习笔记 - 自定义及解耦降级处理方法 - Sentinel
1. SentinelRecourse配置回顾 通过之前的学习,我们知道SentinelRecourse配置的资源定位可以通过两种方式实现:一种是URL,另一种是资源名称。这两种限流方式都要求资源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,CNN网络的缺点 难以平行化处理,比如我们要算b4b^4b4,我们需要一次将a1a^1a1~a4a^4a4依次进行放入网络中进行计算。 于是有人提出用CNN代替RNN 三角形表示输入,b1b^1b1的…...
1、第一个CUDA代码:hello gpu
目录第一个CUDA代码:hello gpu一、__global__ void GPUFunction()二、gpu<<<1,1>>>();三、线程块、线程、网格知识四、核函数中的printf();五、cudaDeviceSynchronize();第一个CUDA代码:hello gpu #include <stdio.h>void cpu(…...
UG二次开发装配篇 添加/拖动/删除组件方法的实现
我们在UG装配的过程中,经常会遇到需要调整组件目录位置,在软件设计过程中可以通过在目录树里面拖动组件来完成。 那么,如果要用程序实现组件的移动/拖动,我们要怎么做呢? 本节就完成了添加/拖动/删除组件方法的实现&…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
