Java集合相關面試題(2024大廠高頻面試題系列)

1、說一說Java提供的常見集合?(畫一下集合結構圖)
在這里插入圖片描述

在java中提供了量大類的集合框架,主要分為兩類:

第一個是Collection 屬于單列集合,第二個是Map 屬于雙列集合

在Collection中有兩個子接口List和Set。在平常開發的過程中用的比較多的list接口中的實現類ArrarList和LinkedList。 在Set接口中有實現類HashSet和TreeSet。

在map接口中有很多的實現類,平時比較常見的是HashMap、TreeMap,還有一個線程安全的map:ConcurrentHashMap。

2、ArrayList底層是如何實現的?

我閱讀過arraylist的源碼,我主要說一下add方法吧
在這里插入圖片描述

第一:確保數組已使用長度(size)加1之后足夠存下下一個數據
第二:計算數組的容量,如果當前數組已使用長度+1后的大于當前的數組長
度,則調用grow方法擴容(原來的1.5倍)
第三:確保新增的數據有地方存儲之后,則將新元素添加到位于size的位置上。
第四:返回添加成功布爾值。

3、ArrayList list=new ArrayList(10)中的list擴容幾次

在ArrayList的源碼中提供了一個帶參數的構造方法,這個參數就是指定的集合初始長度,所以給了一個10的參數,就是指定了集合的初始長度是10,這里面并沒有擴容。

4、如何實現數組和List之間的轉換?

數組轉list,可以使用jdk自動的一個工具類Arrars,里面有一個asList方法
可以轉換為數組。

List 轉數組,可以直接調用list中的toArray方法,需要給一個參數,指定數組的類型,需要指定數組的長度。

5、用Arrays.asList轉List后,如果修改了數組內容,list受影響嗎?List用toArray轉數組后,如果修改了List內容,數組受影響嗎?

Arrays.asList轉換list之后,如果修改了數組的內容,list會受影響,因為它的底層使用的Arrays類中的一個內部類ArrayList來構造的集合,在這個集合的構造器中,把我們傳入的這個集合進行了包裝而已,最終指向的都是同一個內存地址。

list用了toArray轉數組后,如果修改了list內容,數組不會影響,當調用了toArray以后,在底層是它是進行了數組的拷貝,跟原來的元素就沒啥關系了,所以即使list修改了以后,數組也不受影響。

6、ArrayList 和 LinkedList 的區別是什么?
它們兩個主要是底層使用的數據結構不一樣,ArrayList 是動態數組,LinkedList 是雙向鏈表。數組易于查詢操作,鏈表易于增刪操作。

7、ArrayList和LinkedList都不是線程安全的,是如何解決這個的線程安全問題的?

主要有兩種解決方案:
第一:我們使用這個集合,優先在方法內使用,定義為局部變量,這樣的話,就不會出現線程安全問題。

第二:如果非要在成員變量中使用的話,可以使用線程安全的集合來替代
ArrayList可以通過Collections 的 synchronizedList 方法將 ArrayList 轉換成線程安全的容器后再使用。
LinkedList 換成ConcurrentLinkedQueue來使用。

8、說一下HashMap的實現原理?
它主要分為了一下幾個部分:
1,底層使用hash表數據結構,即數組+(鏈表 | 紅黑樹)
2,添加數據時,計算key的值確定元素在數組中的下標key相同則替換不同則存入鏈表或紅黑樹中
3,獲取數據通過key的hash計算數組下標獲取元素

9、HashMap的jdk1.7和jdk1.8有什么區別?

JDK1.8之前采用的拉鏈法,數組+鏈表
JDK1.8之后采用數組+鏈表+紅黑樹,鏈表長度大于8且數組長度大于64則會鏈表轉化為紅黑樹,紅黑樹拆分成的樹結點小于等于6個會轉化為鏈表。

10、你能說下HashMap的put方法的具體流程嗎?

1.判斷鍵值對數組table是否為空或為null,否則執行resize()進行擴容(初始化)
2. 根據鍵值key計算hash值得到數組索引
3. 判斷table[i]==null,條件成立,直接新建節點添加
4. 如果table[i]==null ,不成立
判斷table[i]的首個元素是否和key一樣,如果相同直接覆蓋value
判斷table[i] 是否為treeNode,即table[i] 是否是紅黑樹,如果是紅黑樹,則直接在樹中插入鍵值對
遍歷table[i],鏈表的尾部插入數據,然后判斷鏈表長度是否大于8,大于8的話把鏈表轉換為紅黑樹,在紅黑樹中執行插入操 作,遍歷過程中若發現key已經存在直接覆蓋value
5.插入成功后,判斷實際存在的鍵值對數量size是否超多了最大容量threshold(數組長度*0.75),如果超過,進行擴容。

11、能講一講HashMap的擴容機制嗎?

1.在添加元素或初始化的時候需要調用resize方法進行擴容,第一次添加數據初始化數組長度為16,以后每次每次擴容都是達到了擴容閾值(數組長度 * 0.75)
2.每次擴容的時候,都是擴容之前容量的2倍;
3.擴容之后,會新創建一個數組,需要把老數組中的數據挪動到新的數組中
4.沒有hash沖突的節點,則直接使用 e.hash & (newCap - 1) 計算新數組的索引位置
5.如果是紅黑樹,走紅黑樹的添加
6.如果是鏈表,則需要遍歷鏈表,可能需要拆分鏈表,判斷(e.hash & oldCap)是否為0,該元素的位置要么停留在原始位置,要么移動到原始位置+增加的數組大小這個位置上

12、你了解hashMap的尋址算法嗎?

這個哈希方法首先計算出key的hashCode值,然后通過這個hash值右移16位后的二進制進行按位異或運算得到最后的hash值。

在putValue的方法中,計算數組下標的時候使用hash值與數組長度取模得到存儲數據下標的位置,hashmap為了性能更好,并沒有直接采用取模的方式,而是使用了數組長度-1 得到一個值,用這個值按位與運算hash值,最終得到數組的位置。

13、為什么HashMap的數組長度一定是2的次冪?
hashmap這么設計主要有兩個原因:
第一:
計算索引時效率更高:如果是 2 的 n 次冪可以使用位與運算代替取模
第二:
擴容時重新計算索引效率更高:在進行擴容是會進行判斷 hash值按位與運算舊數組長度是否 == 0
如果等于0,則把元素留在原來位置 ,否則新位置是等于舊位置的下標+舊數組長度

14、你知道hashmap在1.7情況下的問題嗎?
存在死循環問題
jdk7的的數據結構是:數組+鏈表

在數組進行擴容的時候,因為鏈表是頭插法,在進行數據遷移的過程中,有可能導致死循環

當然,JDK 8 將擴容算法做了調整,不再將元素加入鏈表頭(而是保持與擴容前一樣的順序),尾插法,就避免了jdk7中死循環的問題

15、hashmap是線程安全的嗎,如果不安全怎么做,講下其原理?

不是線程安全的

我們可以采用ConcurrentHashMap進行使用,它是一個線程安全的
HashMap,jdk1.7和1.8也做了很多調整。

JDK1.7的底層采用是分段的數組+鏈表 實現
JDK1.8 采用的數據結構跟HashMap1.8的結構一樣,數組+鏈表/紅黑二叉樹

在jdk1.7中 ConcurrentHashMap 里包含一個 Segment 數組。Segment 的結構和HashMap類似,是一 種數組和鏈表結構,一個 Segment 包含一個HashEntry 數組,每個 HashEntry 是一個鏈表結構 的元素,每個 Segment 守護著一個HashEntry數組里的元素,當對 HashEntry 數組的數據進行修 改時,必須首先獲得對應的 Segment的鎖。

Segment 是一種可重入的鎖 ReentrantLock,每個 Segment 守護一個
HashEntry 數組里得元 素,當對 HashEntry 數組的數據進行修改時,必須首先獲得對應的 Segment 鎖

在jdk1.8中的ConcurrentHashMap 做了較大的優化,性能提升了不少。首先是它的數據結構與jdk1.8的hashMap數據結構完全一致。其次是放棄了Segment的設計,取而代之的是采用Node + CAS + Synchronized來保 證并發安全進行實現,synchronized只鎖定當前鏈表或紅黑二叉樹的首節點,這樣只要hash不沖 突,就不會產生并發 , 效率得到提升

16、HashSet與HashMap的區別?
HashSet底層其實是用HashMap實現存儲的, HashSet封裝了一系列HashMap的方法. 依靠HashMap來存儲元素值,(利用hashMap的key鍵進行存儲), 而value值默認為Object對象. 所以HashSet也不允許出現重復值, 判斷標準和HashMap判斷標準相同, 兩個元素的hashCode相等并且通過equals()方法返回true。

17、HashTable與HashMap的區別?
第一,數據結構不一樣,hashtable是數組+鏈表,hashmap在1.8之后改為了數組+鏈表+紅黑樹
第二,hashtable存儲數據的時候都不能為null,而hashmap是可以的
第三,hash算法不同,hashtable是用本地修飾的hashcode值,而hashmap經常了二次hash
第四,擴容方式不同,hashtable是當前容量翻倍+1,hashmap是當前容量翻倍
第五,hashtable是線程安全的,操作數據的時候加了鎖synchronized,
hashmap不是線程安全的,效率更高一些

在實際開中不建議使用HashTable,在多線程環境下可以使用
ConcurrentHashMap類

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/712045.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712045.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712045.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【力扣hot100】刷題筆記Day14

前言 又是新的一周,快樂的周一,快樂地刷題,今天把鏈表搞完再干活! 114. 二叉樹展開為鏈表 - 力扣(LeetCode) 前序遍歷 class Solution:def flatten(self, root: Optional[TreeNode]) -> None:if not r…

回溯 Leetcode 51 N皇后

N皇后 Leetcode 51 學習記錄自代碼隨想錄 按照國際象棋的規則,皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。 n 皇后問題 研究的是如何將 n 個皇后放置在 nn 的棋盤上,并且使皇后彼此之間不能相互攻擊。 給你一個整數 n ,返回所…

Linux —— 鏈接文件

硬鏈接 一般情況下,文件名和inode號碼是"一一對應"關系,每個inode號碼對應一個文件名。但是,Unix/Linux系統允許,多個文件名指向同一個inode號碼。 這意味著,可以用不同的文件名訪問同樣的內容;對…

軟件開發常見模型解析

軟件開發常見模型解析 摘要:本文將為您詳細介紹軟件開發過程中常見的幾種模型,包括瀑布模型、敏捷開發模型、螺旋模型、迭代模型和原型模型。通過了解這些模型的原理、優缺點,幫助您在不同的軟件項目中選擇最適合的開發模型。 一、引言 在…

【IC前端虛擬項目】inst_buffer子模塊DS與RTL編碼

【IC前端虛擬項目】數據搬運指令處理模塊前端實現虛擬項目說明-CSDN博客 需要說明一下的是,在我所提供的文檔體系里,并沒有模塊的DS文檔哈,因為實際項目里我也不怎么寫DS畢竟不是每個公司都和HISI一樣對文檔要求這么嚴格的。不過作為一個培訓的虛擬項目,還是建議在時間充裕…

Docker技術概論(3):Docker 中的基本概念

Docker技術概論(3) Docker 中的基本概念 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://…

基于java+springboot女士電商平臺系統源碼+文檔設計

基于javaspringboot女士電商平臺系統源碼文檔設計 博主介紹:多年java開發經驗,專注Java開發、定制、遠程、文檔編寫指導等,csdn特邀作者、專注于Java技術領域 作者主頁 央順技術團隊 Java畢設項目精品實戰案例《1000套》 歡迎點贊 收藏 ?留言 文末獲取源…

C語言----動態內存管理(2)

1.這里總結動態內存管理里面的錯誤 (1)使用malloc開辟空間以后直接賦值 這個就是malloc開辟失敗返回空指針,直接給空指針賦值就是錯誤的, tip1:使用malloc開辟空間以后一定要判斷是否為空 (2) 越界訪問…

Python批量提取文件夾中圖片的名稱及路徑到指定的.txt文件中

目錄 一、代碼二、提取效果 一、代碼 import os# 定義要保存的文件名 file_name "TestImage/Image_Visible_Gray.txt"# 讀取文件夾路徑 folder_path "TestImage/Image_Visible_Gray"# 遍歷文件夾中的所有文件 with open(file_name, "w") as f…

IO進程線程day1

編寫鏈表&#xff0c;鏈表里面隨便搞點數據&#xff0c;使用fprintf將鏈表中所有的數據保存到文件中&#xff0c;用fscanf讀取文件中的數據寫入鏈表中 #include <stdio.h> #include <stdlib.h>typedef struct Node {int data;struct Node* next; } Node;// 創建新…

可移植性(兼容性)測試指南

可移植性是指應用程序能夠安裝到不同的環境中&#xff0c;在不同的環境中使用&#xff0c;甚至可以移動到不同的環境中。當然&#xff0c;前兩者對所有系統都很重要。就PC軟件而言&#xff0c;鑒于操作系統、共存和互操作應用程序、硬件、帶寬可用性等方面的快速變化&#xff0…

抖店如何運營?新手應該怎么做?從入門到精通詳細講解!

我是電商珠珠 做抖店必須先搞懂它的基礎流程&#xff0c;流程搞懂了&#xff0c;才能有進一步的可能。不要急功近利&#xff0c;想要一口吃個胖子&#xff0c;這樣做就會直接造成店鋪被清店&#xff0c;扣除保證金&#xff0c;甚至還會埋怨自己沒用。 我做電商已經三年多的時…

vue3 日期延后一天

問題&#xff1a;提交信息時要求將所選日期延后一天進行提交解決過程&#xff1a;1.定義延后一天的計算方法&#xff0c;在提交前&#xff0c;將提交日期傳入調用該方法 2.對延后的日期進行格式化&#xff0c;最后格式為yy-mm-dd解決結果&#xff1a; const…

c++ - pointer convert - class member function‘s pointer <==> void*

文章目錄 c - pointer convert - class member functions pointer <> void*概述筆記END c - pointer convert - class member function’s pointer <> void* 概述 想將結構體中的void指針賦值為類成員函數的指針, 用于回調. 這個結構體相關的函數寫完, 就不用再因…

Stable Diffusion中的Clip模型

基礎介紹 Stable Diffusion 是一個文本到圖像的生成模型&#xff0c;它能夠根據用戶輸入的文本提示&#xff08;prompt&#xff09;生成相應的圖像。在這個模型中&#xff0c;CLIP&#xff08;Contrastive Language-Image Pre-training&#xff09;模型扮演了一個關鍵的角色&a…

Biotin aniline,生物素苯胺,用于研究蛋白質結構和功能

您好&#xff0c;歡迎來到新研之家 文章關鍵詞&#xff1a;769933-15-5&#xff0c;Biotin aniline&#xff0c;生物素苯胺&#xff0c;Biotin-aniline&#xff0c;生物素-苯胺 一、基本信息 【產品簡介】&#xff1a;Biotin aniline is composed of three parts: biotin, w…

個人或者小團隊選擇C語言還是c++?

個人或者小團隊選擇C語言還是c? 在開始前我有一些資料&#xff0c;是我根據網友給的問題精心整理了一份「C語言的資料從專業入門到高級教程」&#xff0c; 點個關注在評論區回復“888”之后私信回復“888”&#xff0c;全部無償共享給大家&#xff01;&#xff01;&#xff0…

使用Python語言實現一個基于動態數組的序列隊列

一、動態數組的實現 首先&#xff0c;我們需要創建一個DynamicArray類&#xff0c;該類將管理我們的動態數組。 動態數組能夠動態地調整其大小&#xff0c;以容納更多的元素。 目錄 一、動態數組的實現 代碼示例&#xff1a; 二、序列隊列的實現 接下來&#xff0c;我…

學習JAVA的第八天(基礎)

目錄 多態 前提 形式 測試類 調用成員的特點 優勢 劣勢 包 注意事項&#xff1a; final關鍵字 常量 命名規范&#xff1a; 注意事項&#xff1a; 權限修飾符 分類 代碼塊 局部代碼塊 構造代碼塊 靜態代碼塊 抽象類 抽象類&#xff1a; 定義格式 抽象…

代碼隨想錄算法訓練營第五天

● 自己看到題目的第一想法 242. 有效的字母異位詞 方法&#xff1a; 方法一&#xff1a; 暴力法 1. 分別對s, t排序 2. 遍歷s與t 判斷s[i]!t[i] 返回 false 否則 返回true思路&#xff1a; 注意&#xff1a; 代碼&#xff1a; bool cmp(char a, char b){return a<b;…