撩課-Java每天10道面試題第6天

来源:https://www.cnblogs.com/gxq666/archive/2018/11/15/9961411.html
-Advertisement-
Play Games

51.HashMap的實現原理 HashMap的主幹是一個Entry數組。 Entry是HashMap的基本組成單元, 每一個Entry包含一個key-value鍵值對。 HashMap基於hashing原理, 我們通過put()和get()方法儲存和獲取對象。 當我們將鍵值對傳遞給put()方法時 ...


51.HashMap的實現原理
HashMap的主幹是一個Entry數組。
Entry是HashMap的基本組成單元,
每一個Entry包含一個key-value鍵值對。

HashMap基於hashing原理,
我們通過put()和get()方法儲存和獲取對象。
當我們將鍵值對傳遞給put()方法時,
它調用鍵對象的hashCode()方法
來計算hashcode,
讓後找到bucket位置來儲存值對象。
當獲取對象時,
通過鍵對象的equals()方法
找到正確的鍵值對,
然後返回值對象。
HashMap使用鏈表來解決碰撞問題,
當發生碰撞了,
對象將會儲存在鏈表的下一個節點中。
 HashMap在每個鏈表節點中儲存鍵值對對象。

當兩個不同的鍵對象的hashcode
相同時會發生什麼? 
它們會儲存在同一個bucket位置的鏈表中。
鍵對象的equals()方法用來找到鍵值對。

因為HashMap的好處非常多,
我曾經在電子商務的應用中使用HashMap作為緩存。
因為金融領域非常多的運用Java,
也出於性能的考慮,
我們會經常用到HashMap和ConcurrentHashMap。


HashMap由數組+鏈表組成的,
數組是HashMap的主體,
鏈表則是主要為瞭解決哈希衝突而存在的,
如果定位到的數組位置不含鏈表
當前entry的next指向null,
那麼對於查找,
添加等操作很快,
僅需一次定址即可;
如果定位到的數組包含鏈表,
對於添加操作,
其時間複雜度為O(n),
首先遍歷鏈表,
存在即覆蓋,
否則新增;
對於查找操作來講,
仍需遍歷鏈表,
然後通過key對象的equals方法逐一比對查找。
所以,性能考慮,HashMap中的鏈表出現越少,
性能才會越好。

 

52.List、Set、Map之間的區別
List、Set是實現了Collection介面的子介面;
而Map是另一個集合介面。


1元素重覆性:
 List允許有重覆的元素。
任何數量的重覆元素
都可以在不影響現有重覆元素的值
及其索引的情況下插入到List集合中;

Set集合不允許元素重覆。
Set以及所有實現了Set介面的類
都不允許重覆值的插入,
若多次插入同一個元素時,
在該集合中只顯示一個;

Map以鍵值對的形式對元素進行存儲。
Map不允許有重覆鍵,
但允許有不同鍵對應的重覆的值;

2.元素的有序性:

List及其所有實現類保持了
每個元素的插入順序;

Set中的元素都是無序的;
但是某些Set的實現類
以某種殊形式對其中的元素進行排序,
如:LinkedHashSet按照元素的
插入順序進行排序;

Map跟Set一樣對元素進行無序存儲,
但其某些實現類對元素進行了排序。
如:TreeMap根據鍵對其中的元素進行升序排序;

3.元素是否為空值:
1.List允許任意數量的空值;
2.Set最多允許一個空值的出現;
當向Set集合中添加多個null值時,
在該Set集合中只會顯示一個null元素
3.Map只允許出現一個空鍵,
但允許出現任意數量的空值;
---------------------------------
總結: 
List中的元素:
有序、可重覆、可為空;
Set中的元素:
無序、不重覆、只有一個空元素;
Map中的元素:
無序、鍵不重,值可重、可一個空鍵、多可空值;

 

53.HashMap 的長度為什麼是2的冪次方
1.減小哈希衝突概率 
假如當前Entry數組長度為len,
插入節點時,
需要對key的hashcode進行二次哈希,
然後跟len-1相與
得到的值一定小於len,避免數組越界

如果len是2的N次方,
那麼len-1的後N位二進位一定是全1

假設有兩個key,
他們的hashcode不同,
分別為code1和code2 
code1和code2分別與一個後N位全1的二進位相與,
結果一定也不同 
但是,如果code1和code2分別
與一個後N位非全1的二進位相與,
結果有可能相同

也就是說,
如果len是2^N,
不同hashcode的key
計算出來的數組下標一定不同; 
否則,
不同hashcode的key
計算出來的數組下標一定相同。

所以HashMap長度為全1,
可以減小哈希衝突概率。
----------------------
2.提高計算下標的效率 
如果len的二進位後n位非全1,
與len-1相與時,
0與1相與需要取反。 
如果len的二進位後n位全1,
完全不需要取反。

如果len為2^N,
那麼與len-1相與,
跟取餘len等價,
而與運算效率高於取餘。 
如果len不是2^N,
與len-1相與,
跟取餘len不等價。

 

54.集合框架中的泛型有什麼優點?
首先,
瞭解一下Java關於泛型的概念。
泛型,在C++中被稱為模板,
就是一種抽象的編程方式。
當我們定義類和方法的時候,
可以用一種通用的方式進行定義,
而不必寫出具體的類,
這些未知的東西會在真正使用的時候在確定。

對於集合類來說,
它們可以存放各種類型的元素。
如果在存放之前,
就能確定元素的類型,
那麼就可以更加直觀,
也讓代碼更加簡潔。

說明:
java的泛型是停留在編譯層的,
也就是說JVM在對待泛型數據的時候,
依然會把它們看成是Object類型,
只不過在使用這些元素的時候,
JVM會自動幫助我們進行相應的類型轉換。

總結:
集合使用泛型之後,
可以達到元素類型明確的目的,
避免了手動類型轉換的過程,
同時,也讓我們更加明確
容器保存的是什麼類型的數據。

 

55.我們能否使用任何類作為Map的key?
1、可以 
但是做為key的數據有如下要求:

2、首先,
要求明確一點Map集合存儲數據的
主要目的是為了查找 
而List集合是為了輸出

3、既然是查找那麼就要涉及到對象比較 
我們說瞭如果要進行對象比較
就必須覆寫Object類中的equals()、hasCode() 
至少覆寫equals()方法 簡單理解:
自己定義的類如果要想實現對象比較
就必須至少覆寫equals()方法

4、或則這麼說只要是自己定義的類
要想將其作為key 
就必須覆寫equals()方法

5、實際工作中 key的類型一定是String型 
(95%通用) 其餘的5%是沒事找事的

6、按標準開發、你會感到事半功倍,
不要沒事給自己找事,
當然求知精神是值得肯定的。

 

56.Map介面提供了哪些不同的集合視圖?
Map介面提供了三個集合視圖:

1.Set keyset():
返回map中包含的所有key的一個Set視圖。
集合是受map支持的,
map的變化會在集合中反映出來,
反之亦然。
當一個迭代器正在遍歷一個集合時,
若map被修改了(除迭代器自身的移除操作以外),
迭代器的結果會變為未定義。
集合支持通過
Iterator的Remove、
Set.remove、
removeAll、
retainAll和clear操作進行元素移除,
從map中移除對應的映射。
它不支持add和addAll操作。

2.Collection values():
返回一個map中包含的
所有value的一個Collection視圖。
這個collection受map支持的,
map的變化會在collection中反映出來,
反之亦然。
當一個迭代器正在遍歷一個collection時,
若map被修改了(除迭代器自身的移除操作以外),
迭代器的結果會變為未定義。
集合支持通過
Iterator的Remove、
Set.remove、
removeAll、
retainAll和clear操作進行元素移除,
從map中移除對應的映射。

它不支持add和addAll操作。

3.Set> entrySet():
返回一個map鐘包含的
所有映射的一個集合視圖。
這個集合受map支持的,
map的變化會在collection中反映出來,
反之亦然。
當一個迭代器正在遍歷一個集合時,
若map被修改了
除迭代器自身的移除操作,
以及對迭代器返回的entry進行setValue外,
迭代器的結果會變為未定義。
集合支持通過
Iterator的Remove、
Set.remove、
removeAll、
retainAll和clear操作進行元素移除,
從map中移除對應的映射。
它不支持add和addAll操作。

 

57.哪些集合類是線程安全的?
在集合框架中,有些類是線程安全的,
這些都是jdk1.1中的出現的。
在jdk1.2之後,
就出現許許多多非線程安全的類。
下麵是這些線程安全的同步的類:
vector:
就比arraylist多了個同步化機制(線程安全),
因為效率較低,
現在已經不太建議使用。
在web應用中,
特別是前臺頁面,
往往效率(頁面響應速度)是優先考慮的。

statck:堆棧類,先進後出

hashtable:就比hashmap多了個線程安全

enumeration:枚舉,相當於迭代器

除了這些之外,
其他的都是非線程安全的類和介面。

線程安全的類其方法是同步的,
每次只能一個訪問。
是重量級對象,
效率較低。

 

58.隊列和棧是什麼,列出它們的區別?
隊列(Queue):
是限定只能在表的一端進行
插入和在另一端進行刪除操作的線性表;

棧(Stack):
是限定只能在表的一端
進行插入和刪除操作的線性表。

區別如下:
一、規則不同
1. 隊列:先進先出(First In First Out)FIFO
2. 棧:先進後出(First In Last Out )FILO

二、對插入和刪除操作的限定不同
1. 隊列:只能在表的一端進行插入,
併在表的另一端進行刪除;
2. 棧:只能在表的一端插入和刪除。

三、遍曆數據速度不同
 1. 隊列:基於地址指針進行遍歷,
而且可以從頭部或者尾部進行遍歷,
但不能同時遍歷,
無需開闢空間,
因為在遍歷的過程中不影響數據結構,
所以遍歷速度要快;

 2. 棧:只能從頂部取數據,
也就是說最先進入棧底的,
需要遍歷整個棧才能取出來,
而且在遍曆數據的同時需要
為數據開闢臨時空間,
保持數據在遍歷前的一致性。

 

59.哪一個List實現了最快插入?
LinkedList和ArrayList
是另個不同變數列表的實現。
ArrayList的優勢在於動態的增長數組,
非常適合初始時總長度未知的情況下使用。
LinkedList的優勢在於在中間位置插入和刪除操作,
速度是最快的。

LinkedList實現了List介面,
允許null元素。
此外LinkedList提供額外的
get,remove,insert方法
在LinkedList的首部或尾部。
這些操作使LinkedList可被
用作堆棧(stack),
隊列(queue)
或雙向隊列(deque)。

ArrayList實現了可變大小的數組。
它允許所有元素,
包括null。 
每個ArrayList實例都有一個容量(Capacity),
即用於存儲元素的數組的大小。
這個容量可隨著不斷添加新元素而自動增加,
但是增長演算法並沒有定義。
當需要插入大量元素時,
在插入前可以調用ensureCapacity方法來
增加ArrayList的容量以提高插入效率。

 

60.什麼時候使用ConcurrentHashMap?
快速失敗的Java迭代器
可能會引發ConcurrentModifcationException
在底層集合迭代過程中被修改。
故障安全作為發生在實例中的一個副本
迭代是不會拋出任何異常的。
快速失敗的故障安全範例定義了
當遭遇故障時系統是如何反應的。
例如,用於失敗的快速迭代器ArrayList
和用於故障安全的迭代器ConcurrentHashMap。

ConcurrentHashMap被作為
故障安全迭代器的一個實例,
它允許完整的併發檢索和更新。
當有大量的併發更新時,
ConcurrentHashMap此時可以被使用。
這非常類似於Hashtable,
但ConcurrentHashMap不鎖定
整個表來提供併發,
所以從這點上ConcurrentHashMap的性能
似乎更好一些。
所以當有大量更新時
ConcurrentHashMap應該被使用。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • web前端怎麼樣才能入門,首先我們要從什麼是初級web前端工程師說起: 按照我的想法,我把前端工程師分為了入門、初級、中級、高級這四個級別, 入門級別指的是瞭解什麼是前端(前端到底是什麼其實很多人還是不清楚的),瞭解基本的html、css和javascript語法(這些語方面的東西網上隨便搜一下就有 ...
  • element vue Array數組和Map對象的添加與刪除 ...
  • DDD理解 DDD體現的是對現實的充分尊重。 1.尊重業務現實,領域專家、領域語言等概念 2.尊重團隊現實 3.尊重變化 Application 對某一業務線的整體掌控,流程組裝,進度管理,存儲時機掌控。 依賴外部模塊的業務環節實現; 儘量滿足UI需求; 落地:uow提交; Domain 業務線視作 ...
  • 一、概念 繼承的缺點:類數量爆炸、設計死板以及基類加入的新功能可能並不適用於所有的子類。 裝飾者模式:動態地將責任附加到對象上,若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。一言以蔽之 —— 動態擴展類的行為。 角色:   1、抽象組件(Component):給出一個抽象類 ...
  • 系統架構設計師-軟體水平考試高級-理論-操作系統。其中涉及進程管理(PV操作等),文件管理,存儲管理,設備管理等。 ...
  • 第1章 緒論1.1 概念模型1.2 模式世界1.2.1 Christopher Alexander1.2.2 描述格式1.2.3 關於模式的抽象程度1.3 本書中的模式1.3.1 建模實例1.3.2 模式的來源1.3.3 跨領域的模式1.4 概念模型與業務過程重組1.5 模式與框架1.6 本書的使用 ...
  • 系統: CentOS 7 IP: 192.168.11.199關閉 selinux 和防火牆 # setenforce 0 # 臨時關閉,重啟後失效 # systemctl stop firewalld.service # 臨時關閉,重啟後失效 修改字元集,否則可能報 input/output er ...
  • 歡迎到我的簡書查看我的文集 前言: 是圖形用戶界面,在 中,圖形用戶界面我們用 表示,而 的完整英文為: (圖形用戶介面), 所謂圖形用戶界面就是以圖形的方式來顯示你電腦的操作界面, 我們電腦中操作的界面就是 我們 中常說的圖形用戶界面, 這樣的操作簡單明瞭. 的英文為 , 是命令行用戶介面, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...