面試問題:進程和線程,編譯步驟,const,map和unordered_map,深入理解unordered_map

目錄

進程和線程的區別

const修飾指針(左邊內容,右邊指向)

1. const 修飾指針指向的內容(指向常量)

2. const 修飾指針本身(常量指針)

3. const 同時修飾指針本身和指向的內容(指向常量的常量指針)

一句話速答版(面試用)

編譯的四個步驟

map和unordered_map的區別

底層實現

元素有序性與遍歷

性能與時間復雜度

內存占用

unordered_map的深入理解

前言

unordered_map的結構

復雜度問題

哈希沖突問題

rehash(重新構建哈希表) 和負載因子


看似不起波瀾的日復一日,相信總有一天會讓我看到堅持的意義。

????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????——2025/9/2

進程和線程的區別

進程是操作系統資源分配的基本單位,而線程是CPU調度的基本單位。

資源分配與調度

  • 進程:它擁有獨立的內存地址空間、文件句柄、I/O設備等資源。操作系統為每個進程分配這些資源。

  • 線程:它不擁有獨立的資源,而是共享其所屬進程的資源。比如,同一個進程內的所有線程都共享該進程的內存空間和文件句柄。線程是CPU調度的最小單位,也就是CPU真正執行的實體。

通信機制

進程間通信(IPC):管道、消息隊列、共享內存、信號、socket 等,開銷較大。

線程間通信:共享進程的內存空間,可以直接讀寫,但需要加鎖保證同步。

適用場景

  • 多進程:適合于隔離性要求高的任務,比如瀏覽器中的不同標簽頁,或者服務器中處理不同用戶請求的進程。一個標簽頁崩潰了,不會影響其他標簽頁。
    ?

  • 多線程:適合于需要高并發,頻繁通信和共享數據的任務,比如圖形界面(UI)的響應、高并發的網絡服務器(如 Web 服務器中的線程池)。在服務器中,一個進程可以創建多個線程來處理不同的客戶端連接,效率更高。

const修飾指針(左邊內容,右邊指向)

const 在修飾指針時主要有三種修飾方式,理解它們關鍵在于弄清楚 const 關鍵字修飾的是什么

👉 const 在星號左邊:修飾指針所指的內容;在星號右邊:修飾指針本身。

想想也對,因為?int* const p中const緊貼著p,const自然是修飾p的p又是一個指針變量,那么指針變量的值不可變,const自然修飾的是指針本身。

1. const 修飾指針指向的內容(指向常量)

在這種情況下,const 位于星號(*)的左側,無論是緊挨著類型名還是緊挨著星號,效果都是一樣的。

示例:const int *p; 或 int const *p;

int a = 10, b = 20;
const int* p = &a;
*p = 20; ? ?// ? 錯誤
p = &b; ? ? // ? 合法

含義p 是一個指向“常量整型”的指針。

特點:

  • *p 不可修改(不能通過 p 改變所指對象的值)。
  • p 本身可以修改(可以指向別的地址)。

2. const 修飾指針本身(常量指針)

含義p 是一個“常量指針”,一旦初始化,就不能再指向別的對象。

示例:int *const p = &a;

int a = 10, b = 20;
int* const p = &a;
*p = 30; ? ?// ? 合法
p = &b; ? ? // ? 錯誤

特點:

  • p 不可修改(指向固定)。
  • *p 可修改(能通過 p 改變所指對象的值)。

3. const 同時修飾指針本身和指向的內容(指向常量的常量指針)

含義p 是一個指向“常量整型”的常量指針。

示例:const int *const p = &a;

int a = 10, b = 20;
const int* const p = &a;
*p = 20; ? ?// ? 錯誤
p = &b; ? ? // ? 錯誤

特點:

  • p 不可修改(指針不能改變指向)。
  • *p 不可修改(指向的值也不能通過它改)。

一句話速答版(面試用)

const 修飾指針有三種情況:

  • const int* p:指向的值不能改,指針能改;
  • int* const p:指針不能改,指向的值能改;
  • const int* const p:指針和值都不能改。

編譯的四個步驟

從源代碼到可執行文件一般分為四步:預處理(4種處理)、編譯(又可進一步分成多個階段)、匯編(匯編代碼轉化成機器碼)、鏈接(兩種鏈接方式)。編譯階段內部又可以細分為詞法分析、語法分析、語義分析、中間代碼生成、優化和目標代碼生成。

詳細介紹請看文章:

編譯過程詳解,庫的介紹,靜態庫的制作與運用,動態庫的制作與運用,庫中的符號沖突問題和庫相互依賴問題_庫文件編譯-CSDN博客

關于什么時候使用靜態鏈接什么時候用動態鏈接也要知道,一般涉及到系統移植建議用靜態鏈接,可執行文件中包含了一切需要的庫文件,部署打包更加方便。

map和unordered_map的區別

底層實現

map:底層通常由紅黑樹實現。紅黑樹是一種自平衡二叉查找樹,它能確保在插入、刪除和查找操作后,樹的結構依然保持平衡。

unordered_map:底層由哈希表實現。它通過哈希函數將鍵(key)映射到哈希表中的一個桶(bucket)里,以實現快速訪問。

元素有序性與遍歷

有序性

  • map:自動按 key 排序(默認升序,可以自定義比較器)。
  • unordered_map:元素無序存儲,不保證遍歷順序。

遍歷

map:有序遍歷,支持區間操作(比如 lower_bound(>=)、upper_bound(>))。

unordered_map:無序遍歷,不支持按區間查找。

區間查找指的是在一個數據集合中,查找所有滿足某個特定范圍條件的元素。在 map 里,迭代器返回的位置就是“邊界點”,它把元素分成了兩部分
?

map 默認是 按鍵升序排列 的有序容器。lower_bound(key) 返回第一個 不小于(>=) key 的元素 的迭代器。

左邊(begin 到返回迭代器之前):

全部 < key → 不滿足 >= key 的條件。

右邊(從返回迭代器到 end):

全部 >= key → 滿足條件。

性能與時間復雜度

map:插入、刪除、查找的平均時間復雜度都是 O(logN)

優點:對于需要穩定性能(即最壞情況下的性能也能得到保證)和有序訪問的場景非常合適。

unordered_map:插入、刪除、查找的平均時間復雜度是 O(1)

缺點:在最壞情況下(例如,哈希沖突嚴重),時間復雜度會退化到 O(N)。此外,它的性能高度依賴于哈希函數的質量和負載因子

內存占用

map:相對較省內存(樹節點開銷)。

unordered_map:需要哈希表 + 桶結構,內存開銷更大。

unordered_map的深入理解

前言

之前我有介紹部分關于unordered_map的深入理解,可以先看一下,主要里面介紹了擴容機制,哈希沖突的解決方式(鏈地址法和開放地址法)

unordered_map和哈希表的使用_map自定義哈希函數-CSDN博客

在面試的時候unordered_map真的是一個非常非常高頻的考點!!!所以下面我將更深入地聊一下這個問題

unordered_map的結構

unordered_map 的哈希表 + 桶結構是其實現高效查找的基石

希表可以理解為unordered_map的主干,它是一個內部的數組,這個數組里的每一個元素都叫做一個桶(Bucket)

一個桶里可能存放 0 個、1 個或多個元素。為什么會有多個?

👉 因為 哈希沖突:不同的 key 經過哈希函數后可能得到相同的下標。

所以每個桶不是只放一個元素,而是通常會用 鏈表 / 動態數組 來存放同一個哈希值的所有元素。
?

比如我們有 unordered_map<string,int>,桶數是 8(N=8):

Index: ? 0 ? ?1 ? ?2 ? ?3 ? ?4 ? ?5 ? ?6 ? ?7
Bucket: [ ] ?[ ] ?[A] [ ] ?[B,C] [ ] ?[ ] ?[D]

復雜度問題

Q:為什么 unordered_map 查找是 O(1)?最壞情況為什么是 O(n)?

  • 平均情況:哈希函數分布均勻,桶內元素少,查找是 O(1)。

  • 最壞情況:所有元素都沖突到同一個桶 → 等價于鏈表查找 → O(n)。

哈希沖突問題

Q:哈希沖突是怎么解決的?

  • STL 實現里通常是 拉鏈法(separate chaining):桶里存鏈表/動態數組。

  • 也有一些實現用 開放尋址法(open addressing),不過 unordered_map 一般是拉鏈法。

為什么不用開放尋址法?

  • C++ 標準庫沒有強制規定必須用拉鏈法,但 幾乎所有主流實現(GCC 的 libstdc++、Clang 的 libc++、MSVC STL)都采用拉鏈法

  • 原因是:

    • 拉鏈法更容易處理刪除操作(直接刪鏈表節點即可)。

    • 開放尋址法刪除時需要“墓碑標記”,實現復雜。

    • 拉鏈法在裝載因子不是太高時性能更穩定。

為了解決哈希沖突(不同鍵有相同的哈希值),每個桶通常是一個鏈表(在 C++11 后,如果元素過多會轉換為紅黑樹以提高性能),當多個鍵被哈希到同一個桶時,它們會以鏈表的形式被連接起來。所以查找元素時,先通過哈希函數定位到桶,然后遍歷該桶內的鏈表來找到目標元素。

C++11 引入的性能優化


?

哈希沖突嚴重的情況

當哈希函數設計得不好,或者數據本身就存在某種規律導致大量鍵的哈希值相同或相近時,一個桶里的鏈表會變得非常長。此時,對這個桶內的元素的查找,時間復雜度會從 O(1) 退化到 O(N)(其中 N 是該鏈表的長度)。這會嚴重影響 unordered_map 的性能。


?

為了解決這個問題,從 C++11 開始,標準庫的實現引入了一個優化機制:

  • 當一個桶中的元素數量(即鏈表長度)超過一個閾值(這個閾值是編譯器實現決定的,通常是 8 或 10)時,unordered_map 會自動將該桶的數據結構從鏈表轉換為紅黑樹
  • 紅黑樹是一種自平衡的二叉查找樹。
  • 這樣一來,在這個桶內的查找、插入和刪除操作的時間復雜度就從線性的 O(N) 降到了對數的 O(logN)。

rehash(重新構建哈希表) 和負載因子

load_factor(負載因子) = 元素個數 / 桶數

unordered_map 內部維護一個 最大負載因子(max_load_factor,默認 1.0)。

如果 load_factor > max_load_factor,容器就會自動觸發 rehash。

Q:什么時候會 rehash?rehash 有什么影響?

  • 負載因子(元素數 / 桶數)超過閾值 時觸發。

  • rehash 會申請更多桶,把所有元素重新分配。

  • rehash 后:所有迭代器、引用、指針失效。

rehash 的過程:

  1. 分配更多桶(通常至少翻倍)。
  2. 對所有元素重新計算哈希并分配到新的桶里。

這樣做的目的:減少每個桶中的元素數量,讓沖突更少。

缺點:rehash 是一個 O(n) 的操作,迭代器全部失效。

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

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

相關文章

利用棒棒糖圖探索Office (US)的IMDB評分

利用棒棒糖圖探索Office (US)的IMDB評分 import numpy as np import pandas as pd import matplotlib.colors as mc import matplotlib.image as image import matplotlib.pyplot as pltfrom matplotlib.cm import ScalarMappable from matplotlib.lines import Line2D from m…

Zephyr如何注冊設備實例

設備樹 → 編譯期生成 → 運行時訪問 流程圖&#xff1a;Zephyr dev->config 工作流程設備樹 (.dts) ───────────────────────────── anx745139 {compatible "analogix,anx7451";reg <0x39>;reset-gpios <&gpio1 5 …

Spring Boot 日志框架選擇指南:Logback vs Log4j2

在 Spring Boot 應用中&#xff0c;您需要明確選擇一個日志框架 - ??不能同時使用兩種日志實現??。以下是關于 spring-boot-starter-log4j2和 spring-boot-starter-logging的全面比較和選擇建議&#xff1a;核心區別特性spring-boot-starter-log4j2(Log4j2)spring-boot-sta…

Axure科技感可視化原型案例:賦能設計與研發的寶藏資源

在當今數字化浪潮中&#xff0c;數據可視化已成為企業洞察市場、優化運營、快速決策不可或缺的工具。Axure&#xff0c;作為原型設計領域的領航者&#xff0c;憑借其強大的功能和豐富的資源&#xff0c;為數據可視化大屏的設計注入了科技活力與創新元素。本文將深入探討Axure科…

跨境電商賬號風控核心:IP純凈度與瀏覽器指紋的防護策略

對跨境電商從業者而言&#xff0c;賬號突然被封是常見卻令人頭痛的問題。即便嚴格遵守平臺規則、使用代理IP&#xff0c;賬號仍可能因風控策略而受限。這背后&#xff0c;IP純凈度與瀏覽器指紋識別是兩大常被忽視卻至關重要的技術因素。本文將從技術角度解析其原理&#xff0c;…

daily notes[7]

文章目錄perl notereferencesperl note A hash in perl can be initialized with array,for example: my %numbers ("one", 1, "two", 2); print $fruit_color{"one"}; it is wonderful that the hash can be sliced to result in an array …

WPF遷移avalonia之圖像處理(一)

從WPF遷移到avalonia中&#xff0c;對于圖像處理部分&#xff0c;在WPF常用System.Windows.Drawing中圖像處理元素&#xff0c;但是在開發avalonia應用時考慮跨平臺特性&#xff0c;則必須有對應的跨平臺替換方案。主要考慮Avalonia.Media.Imaging.Bitmap和SkiaSharp.SKBitmap …

242. 有效的字母異位詞| 349. 兩個數組的交集

242. 有效的字母異位詞 nums [0]*26 : 這行代碼創建了一個包含26個0的列表&#xff0c;這個列表通常用于計數或者作為某種映射的基礎&#xff0c;比如統計字符串中每個字母出現的次數&#xff08;假設只考慮小寫字母a-z&#xff09;。 ord() Python 中的一個內置函數&#x…

HTML第二課:塊級元素

HTML第二課&#xff1a;塊級元素塊級元素塊級元素 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang"zh-CN"> <head><meta http-equiv"Content-…

微論-突觸的作用賦能思考(可能是下一代人工智能架構的啟發式理論)

突觸智能&#xff1a;微觀結構與宏觀智慧的橋梁摘要&#xff1a;傳統人工智能模型&#xff0c;尤其是深度學習&#xff0c;將突觸簡單抽象為一個靜態的權重參數&#xff0c;這極大地簡化了生物計算的復雜性。本文受啟發于生物突觸的微觀功能&#xff0c;提出了一種新的智能架構…

ARM - GPIO 標準庫開發

一、STM32MP157AAA開發板套件介紹1.1 核心板 - 主板如圖所示&#xff1a;主板各部分介紹1.2 IO 拓展板如圖所示&#xff1a;IO拓展板各部分介紹開發板名稱&#xff08;硬件平臺&#xff09;&#xff1a;FS-MP1A主控制器&#xff1a;STM32MP157AAA3 Cortex-A7 * 2 Cortex-M4 -…

橙武低代碼:不僅僅是云SaaS,更是云端開發+本地部署的新范式

版權歸作者所有&#xff0c;轉載請注明出處。 一、低代碼的時代背景 在過去十年里&#xff0c;軟件研發模式經歷了巨大的演變。從傳統的瀑布開發&#xff0c;到敏捷、DevOps&#xff0c;再到如今的低代碼/無代碼平臺&#xff0c;研發效率和交付模式發生了根本性變化。低代碼的…

神經語言學視角:腦科學與NLP深層分析技術的交叉融合

引言&#xff1a;從“統計擬合”到“類人理解”——NLP的下一個范式近年來&#xff0c;以Transformer架構為核心的大型語言模型&#xff08;LLM&#xff09;在自然語言處理&#xff08;NLP&#xff09;領域取得了前所未有的成功 。它們能夠生成流暢的文本、回答復雜的問題&…

Coze源碼分析-工作空間-項目查詢-前端源碼

前言 本文將深入分析Coze Studio項目中用戶登錄后進入工作空間查看和管理項目的前端實現&#xff0c;通過源碼解讀來理解工作空間項目開發功能的架構設計和技術實現。Coze Studio采用了現代化的React TypeScript技術棧&#xff0c;結合微前端架構和模塊化設計&#xff0c;為用…

【系統架構師設計(9)】系統設計:結構化設計與面向對象設計

文章目錄一、核心思想&#xff1a;模塊化與對象化的設計哲學1、結構化設計的核心思想2、面向對象設計的核心思想3、兩種設計方法的本質區別二、結構化設計知識點1、設計階段2、設計原則3、 內聚類型&#xff08;從低到高&#xff09;耦合類型&#xff08;從低到高&#xff09;模…

還在從零開發AI應用?這個項目直接給你500個現成方案!!!

大家好&#xff0c;我是顧北&#xff0c;一名AI應用探索者&#xff0c;也是GitHub開源項目收集者。昨晚又在GitHub上瞎逛...咦&#xff0c;碰到了一個特別有意思的項目。說實話吧&#xff0c;作為一個天天折騰AI工具的人&#xff0c;見過的項目沒有一千也有八百了&#xff0c;但…

react+taro的使用整理

前言&#xff1a; 本文主要整理下我們跨段工具taro的具體使用方法與相關資料。 taro官網&#xff1a; 安裝及使用 | Taro 文檔 安裝&#xff1a; 全局腳手架安裝&#xff1a; npm install -g tarojs/cli 使用腳手架安裝我們的taro項目 taro init myApp 運行到不同小程序教…

從 “容器保姆” 到 “云原生王者”:K8s 全方位指南

目錄 開頭專業總結 一、先搞懂&#xff1a;K8s 到底是什么&#xff1f;能解決什么痛點&#xff1f; 1. K8s 的本質 2. 核心用處&#xff08;解決的痛點&#xff09; 二、K8s 核心知識點&#xff1a;組件與概念&#xff08;標重點&#xff01;&#xff09; &#xff08;一…

03.《交換的底層邏輯:從基礎到應用》

交換基礎 文章目錄交換基礎MAC 地址&#xff1a;設備的 “全球唯一身份證”MAC 地址的基本屬性MAC 地址的三類類型&#xff08;按通信范圍劃分&#xff09;以太幀以太幀的兩個標準格式1. Ethernet_II 格式&#xff08;常用&#xff09;2. IEEE 802.3 格式&#xff08;少用&…

火語言 RPA 界面應用生成:輕量化開發核心優勢

火語言 RPA 界面應用生成功能&#xff0c;主打 “低門檻、快落地”&#xff0c;無需復雜開發環境與專業技術&#xff0c;就能快速實現需求驗證與工具搭建&#xff0c;尤其適配中小團隊與個人&#xff0c;核心優勢如下&#xff1a;?一、1 小時搞定需求驗證&#xff1a;3 步落地…