深入 Go 底層原理(十二):map 的實現與哈希沖突

1. 引言

map 是 Go 語言中使用頻率極高的數據結構,它提供了快速的鍵值對存取能力。雖然 map 的使用非常簡單,但其底層的實現卻是一個精心設計的哈希表,它需要高效地處理哈希計算、數據存儲、擴容以及最關鍵的——哈希沖突。

本文將解剖 map 的底層數據結構,詳細闡述其查找、賦值和擴容過程,特別是它是如何解決哈希沖突的。

2. map 的核心數據結構

Go map 的運行時表示是 runtime.hmap 結構體,其關鍵字段如下:

// src/runtime/map.go
type hmap struct {count     int    // map 中元素的個數,即 len(m)flags     uint8B         uint8  // buckets 的對數,buckets 數量 = 2^Bnoverflow uint16 // 溢出桶的大致數量hash0     uint32 // 哈希種子buckets    unsafe.Pointer // 指向 bucket 數組的指針,大小為 2^Boldbuckets unsafe.Pointer // 在擴容時,指向舊的 bucket 數組nevacuate  uintptr        // 擴容進度計數器// ...
}

map 的核心是一個 bucket 數組。每個 bucket 是一個 runtime.bmap 結構:

// 一個 bucket 最多可以存放 8 個鍵值對
const bucketCnt = 8type bmap struct {tophash [bucketCnt]uint8 // 存儲每個 key 哈希值的高 8 位// keys and values follow
}
  • B: 決定了 map 有多少個 bucket,總數是 2B。

  • buckets: 是一個指針,指向一個連續的 bucket 數組。

  • bmap (bucket):

    • tophash: 這是一個巧妙的優化。它存儲了每個 key 的哈希值的高 8 位 (top hash)。在查找 key 時,可以先快速比較這 8 位,如果 tophash 都不匹配,就無需再比較完整的 key,從而加速查找。

    • 鍵和值: bmap 結構體之后,緊跟著存儲了 8 個 key 和 8 個 value。它們在內存上是連續的。

  • 溢出桶 (Overflow Bucket): 如果一個 bucket 的 8 個槽位都滿了,map 會通過一個指針將這個 bucket 與一個溢出桶鏈接起來,形成一個鏈表。

3. map 的工作流程
a) 寫入/賦值 (map[key] = value)
  1. 哈希計算: 使用哈希函數計算 key 的哈希值 hash

  2. 定位 Bucket: 使用 hash低 B 位來決定這個 key 應該落在哪個 bucket 中。例如,bucketIndex = hash & (2^B - 1)

  3. 定位槽位:

    • 計算 hash高 8 位 tophash

    • 遍歷目標 bucket 的 tophash 數組,看是否存在相同的 tophash

    • 如果 tophash 相同,再完整地比較 key 是否相同。

    • 如果 key 已存在,則更新對應的 value

    • 如果 key 不存在,就在 bucket 中找一個空槽位,存入 tophash, keyvalue

  4. 處理沖突與溢出: 如果當前 bucket 的 8 個槽位都滿了,map 會創建一個新的溢出桶,并讓當前 bucket 指向它。新的鍵值對將被存入這個溢出桶。

b) 查找 (value, ok := map[key])

查找過程與寫入類似。通過哈希值定位到 bucket,然后先比較 tophash,再比較完整的 key。會依次遍歷 bucket 和其所有鏈接的溢出桶,直到找到 key 或者遍歷完所有溢出桶。

c) 擴容 (Grow)

當以下任一條件滿足時,map 會觸發擴容:

  1. 負載因子超限: map 中元素的數量 count / bucket 數量 2^B > 6.5。

  2. 溢出桶過多: map 的溢出桶數量過多時(當 B < 15 時,noverflow >= 2^B),也會觸發擴容,這主要是為了解決因大量刪除操作導致的內存空洞問題。

擴容方式:

  • 等量擴容: 如果是因溢出桶過多觸發,map 會創建一個與原 bucket 數組大小相同的新數組,然后將數據重新排列(rehash),目的是消除內存碎片。

  • 翻倍擴容: 如果是因負載因子超限觸發,map 會創建一個兩倍大的 bucket 數組(B 會加 1)。

漸進式擴容 (Incremental Evacuation): 為了避免因擴容導致長時間的 STW,Go map 的擴容是漸進式的。

  • 擴容時,?map 不會一次性將所有數據從 oldbuckets 搬到 buckets

  • 而是每當對 map 進行一次寫入或刪除操作時,會順便“搬運”一到兩個 bucket 的數據。

  • 查詢操作可能會同時在 oldbucketsbuckets 中進行。

  • 整個搬運過程會分散到多次操作中,直到 oldbuckets 中的數據全部遷移完畢。

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

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

相關文章

Reinforcing General Reasoning without Verifiers

1.概述 DeepSeek-R1-Zero [10] 最近展示了使用可驗證獎勵的強化學習(RL)訓練大型語言模型(LLMs)可以極大地提高推理能力。在這個可驗證獎勵的強化學習(RLVR)框架 [17] 中,LLM 生成一個推理過程(即,思維鏈,CoT),然后給出最終答案。一個基于規則的程序隨后提取并評估…

Hyperbrowser MCP:重新定義網頁抓取與瀏覽器自動化的AI驅動工具

在數據驅動的時代,網頁內容的高效處理和自動化操作成為開發者和企業關注的焦點。Hyperbrowser MCP(Model Context Protocol Server)作為一款革命性的工具,通過AI與瀏覽器技術的深度融合,為網頁抓取、結構化數據提取和瀏覽器自動化提供了全新的解決方案。無論你是需要從復雜…

關于Web前端安全防御XSS攻防的幾點考慮

作為一位前端老鳥&#xff0c;總結一下web前端安全領域基礎概念、防御策略、框架實踐及新興技術等幾個維度的考慮。一、基礎概念與核心漏洞1.XSS 攻擊XSS&#xff08;跨站腳本攻擊&#xff09;是 Web 前端安全中最常見的威脅之一&#xff0c;其核心是攻擊者將惡意腳本注入到網頁…

eSIM技術深度解析:從物理芯片到數字革命

當蘋果公司在2018年首次在iPhone XS系列中引入eSIM技術時&#xff0c;許多用戶可能并未意識到這個看似微小的改變將帶來怎樣的技術革命。從1991年第一張信用卡大小的SIM卡&#xff0c;到今天僅有5mm x 5mm的eSIM芯片&#xff0c;這不僅僅是尺寸的縮小&#xff0c;更是移動通信技…

通俗易懂解釋Java8 HashMap

我們來用通俗易懂的方式解釋一下 Java 8 中 HashMap 的原理&#xff0c;讓你對它的結構、運行機制有清晰的理解。&#x1f333; 什么是 HashMap&#xff1f; HashMap 是 Java 中非常常用的數據結構&#xff0c;用于存儲鍵值對&#xff08;key-value&#xff09;。你可以把它理解…

macOS安裝配置Unbound DNS完整指南

文章目錄macOS安裝配置Unbound DNS完整指南&#x1f3af; 為什么選擇Unbound&#xff1f;&#x1f4cb; 系統要求&#x1f680; 安裝步驟1. 使用Homebrew安裝2. 查看安裝信息?? 基礎配置1. 備份默認配置2. 創建基礎配置文件3. 基礎配置內容配置53端口版本&#xff08;高級用戶…

學習模板元編程(2)std::true_type/false_type

目錄 實現原理 應用場景 條件編譯 通過特化和繼承&#xff0c;實現std::is_xxx系列 思路 舉例 例子1&#xff0c;is_bool 例子2&#xff0c;is_ptr 實現原理 std::true_type/false_type是模板intergral_constant的兩種實現&#xff1a; using true_type integral_co…

Chain-of-Thought Prompting Elicits Reasoning in Large Language Models論文閱讀筆記

Chain-of-Thought Prompting Elicits Reasoning in Large Language Models 摘要 本文探索了思維鏈&#xff08;chain of thought&#xff09;&#xff0c;即一系列中間推理過程&#xff0c;可以有效地增強大語言模型的復雜推理能力。 在三個大型語言模型上的實驗表明&#xff0…

華為核心交換機S7700的內存OID

華為S7700系列交換機 SNMP內存相關OID說明 以下列出了華為S7700核心交換機在SNMP v2c下可用的內存相關OID,包括CPU內存利用率、物理內存總量、已用內存和空閑內存,并給出每個OID的功能描述、數據類型、單位、使用說明等信息。 1. CPU內存利用率(處理器內存占用百分比) OID名…

中州養老Day02:服務管理護理計劃模塊

本日任務:服務管理的后端開發 1.學習:護理項目 (1)評估開發工期的思路和注意事項 全面熟悉項目,了解項目重點,設置開發優先級 比如,在下面圖片的接口文檔中版本有1.0,2.0,3.0也就是功能的初代,二代,三代,所以我們在大致瀏覽所有功能后,要優先關注初代功能的實現 開發計劃 …

JavaScript:Ajax(異步通信技術)

一、Ajax 核心概念Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一種異步通信技術&#xff0c;核心特點&#xff1a;無刷新更新&#xff1a;無需重新加載整個頁面異步處理&#xff1a;后臺發送/接收數據不阻塞用戶數據格式&#xff1a;支持 XML/JSON/HTML/純…

leetcode 118. 楊輝三角 簡單

給定一個非負整數 numRows&#xff0c;生成「楊輝三角」的前 numRows 行。在「楊輝三角」中&#xff0c;每個數是它左上方和右上方的數的和。示例 1:輸入: numRows 5 輸出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2:輸入: numRows 1 輸出: [[1]]提示:1 < numRows…

jmeter--While控制器--循環直到接口響應符合條件

場景描述業務場景&#xff1a;單據計算接口情況&#xff1a;單據計算&#xff0c;調用接口1發起計算&#xff0c;接口2查詢計算執行結果jmeter腳本&#xff1a;把接口1和接口2&#xff08;接口2循環調用&#xff0c;直到返回執行完成狀態&#xff09;添加到一個事務&#xff0c…

組播 | 不同 VLAN 間數據轉發實現邏輯 / 實驗

注&#xff1a;本文為 “不同 vlan 間組播數據轉發” 相關合輯。 圖片清晰度受引文原圖所限。 略作重排&#xff0c;如有內容異常&#xff0c;請看原文。 組播 VLAN&#xff1a;解決路由器為不同 VLAN 用戶復制多份流量問題 aiaiai010101 于 2018-11-16 22:42:06 發布 一、組…

滲透測試常用指令

互聯網設備的開放信息查詢網站&#xff1a; https://fofa.info/ https://www.zoomeye.org/ https://quake.360.net/quake/#/index https://x.threatbook.com/v5/mapping https://hunter.qianxin.com/ 目錄 一、網絡探測與掃描 traceroute whatweb ping fping nc n…

51單片機串行通信的設計原理有哪些?

51單片機是指由美國INTEL公司生產的一系列單片機的總稱&#xff0c;這一系列單片機包括了許多品種&#xff0c;如8031&#xff0c;8051&#xff0c;8751&#xff0c;8032&#xff0c;8052&#xff0c;8752等&#xff0c;其中8051是最早最典型的產品&#xff0c;該系列其它單片機…

設計模式十四:適配器模式(Adapter Pattern)

適配器模式&#xff08;Adapter Pattern&#xff09;是一種結構型設計模式&#xff0c;用于將一個類的接口轉換成客戶端期望的另一個接口&#xff0c;使原本不兼容的類可以一起工作。適配器模式的類型類適配器&#xff08;通過多重繼承實現&#xff09;對象適配器&#xff08;通…

力扣經典算法篇-38-組合(回溯算法)

1、題干 給定兩個整數 n 和 k&#xff0c;返回范圍 [1, n] 中所有可能的 k 個數的組合。 你可以按 任何順序 返回答案。 示例 1&#xff1a; 輸入&#xff1a;n 4, k 2 輸出&#xff1a; [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 示例 2&#xff1a; 輸入&#xff1a;…

多人命題系統

目 錄 摘 要 Abstract 1 系統概述 1.1 概述 1.2課題意義 1.3 主要內容 2 系統開發環境 2. 1 JAVA簡介 2. .2 B/S架構 2.3 SSM三大框架 2.4訪問數據庫實現方法 2.5 系統對MySQL數據庫的兩種連接方式 3 需求分析 3.1技術可行性&#xff1a;技術背景…

UDP_千兆光通信(四)Tri Mode Ethernet MAC ip核

Tri Mode Ethernet MAC ip核使用與例程分析 一、 Tri Mode Ethernet MAC ip核功能 二、 Tri Mode Ethernet MAC ip核配置 數據傳輸速率 主要設置接口 幀濾波功能選擇,以及流控選擇 三、 Tri Mode Ethernet MAC ip核使用 3.1 ip核接口 3.2 ip核接口說明 3.2.1 tx_ifg_delay 3.2…