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装配的过程中,经常会遇到需要调整组件目录位置,在软件设计过程中可以通过在目录树里面拖动组件来完成。 那么,如果要用程序实现组件的移动/拖动,我们要怎么做呢? 本节就完成了添加/拖动/删除组件方法的实现&…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
