百度后端開發一面

在這里插入圖片描述

mutex, rwmutex

在Go語言中,Mutex(互斥鎖)和RWMutex(讀寫鎖)是用于管理并發訪問共享資源的核心工具。以下是它們的常見問題、使用場景及最佳實踐總結:


1. Mutex 與 RWMutex 的區別

  • Mutex:
    • 互斥鎖,保證同一時刻只有一個 goroutine 訪問共享資源。
    • 適用于讀寫操作都需要獨占的場景(如計數器)。
  • RWMutex:
    • 讀寫鎖,允許多個讀操作并行,但寫操作完全獨占。
    • 適用于讀多寫少的場景(如配置信息讀取)。

2. 常見問題及解決方案

2.1 死鎖
  • 原因: 未釋放鎖、重復加鎖或鎖競爭導致永久阻塞。
  • 解決:
    • 使用 defer mu.Unlock() 確保釋放鎖。
    • 避免在同一個 goroutine 中重復加鎖(不可重入)。
2.2 數據競爭
  • 原因: 未對共享資源的所有訪問路徑加鎖。
  • 解決:
    • 明確鎖的保護范圍,確保所有訪問共享數據的操作都被鎖覆蓋。
    • 使用 go test -race 檢測數據競爭。
2.3 鎖拷貝
  • 原因: 復制包含鎖的結構體導致鎖狀態異常。
  • 解決:
    • 通過指針傳遞包含鎖的結構體。
    • 避免直接復制 sync.Mutexsync.RWMutex
2.4 寫饑餓(RWMutex)
  • 原因: 大量讀操作阻塞寫操作。
  • 解決:
    • 評估場景是否需要 RWMutex,或通過優先級隊列優化寫操作。
    • Go 1.18+ 的 Mutex 支持饑餓模式,避免長時間等待。

3. 使用場景

  • Mutex:
    var counter int
    var mu sync.Mutexfunc increment() {mu.Lock()defer mu.Unlock()counter++
    }
    
  • RWMutex:
    var config map[string]string
    var rwmu sync.RWMutexfunc readConfig(key string) string {rwmu.RLock()defer rwmu.RUnlock()return config[key]
    }func updateConfig(key, value string) {rwmu.Lock()defer rwmu.Unlock()config[key] = value
    }
    

4. 最佳實踐

  1. 鎖的作用域:
    • 鎖應保護數據而非代碼,確保所有訪問共享資源的路徑都被覆蓋。
  2. 優先使用 defer:
    • 避免忘記解鎖,尤其在復雜邏輯或異常處理中。
  3. 替代方案:
    • 對簡單數值操作(如計數器)使用 atomic 包。
    • 通過 Channel 實現“通過通信共享內存”。
  4. 性能優化:
    • 減少鎖的持有時間(如僅在讀寫共享數據時加鎖)。
    • 在高并發場景中,評估鎖競爭是否成為瓶頸。

5. 注意事項

  • 不可重入: Go 的鎖不支持重入,同一 goroutine 重復加鎖會導致死鎖。
  • 零值可用: sync.Mutexsync.RWMutex 的零值可直接使用,無需初始化。
  • 避免嵌套鎖: 多個鎖的嵌套使用可能導致復雜死鎖,需按固定順序加鎖。

通過合理選擇 MutexRWMutex,并遵循最佳實踐,可以有效避免并發問題,編寫高效且安全的 Go 代碼。

協程線程區別

協程(Coroutine)和線程(Thread)都是用于實現并發執行的機制,但它們在調度方式、資源消耗、通信機制等方面有顯著區別。線程是操作系統級別的并發單位,由內核調度;而協程是用戶態的輕量級線程,由程序自身調度。

  • 解答思路
  1. 首先明確兩者的基本定義和使用場景。
  2. 對比它們的調度機制:線程由操作系統調度器管理,而協程由用戶程序或運行時系統管理。
  3. 比較它們的開銷:線程切換代價高,需要操作系統參與;協程切換快,僅需保存寄存器狀態。
  4. 分析資源占用:線程擁有獨立的棧空間,內存占用較大;協程共享線程資源,更節省內存。
  5. 總結適用場景:CPU密集型適合多線程,IO密集型或多任務協作適合協程。
  • 深度知識講解

一、基本概念

  • 線程(Thread)
    線程是進程內的一個執行單元,多個線程共享同一進程的地址空間和資源。每個線程有自己獨立的棧和寄存器上下文。線程由操作系統負責創建、銷毀和調度。

  • 協程(Coroutine)
    協程是一種用戶態的非搶占式多任務機制,可以看作是“輕量級線程”。它不像線程那樣被操作系統調度,而是由程序員顯式控制其切換。協程之間通常是協作式的,即當前協程主動讓出控制權給下一個協程。

二、核心區別

  1. 調度機制不同
  • 線程是搶占式的,操作系統根據優先級、時間片等策略決定哪個線程運行。
  • 協程是協作式的,必須由當前協程主動 yield 控制權,才能切換到下一個協程。
  1. 上下文切換開銷
  • 線程切換涉及內核態與用戶態的切換,需要保存/恢復更多的寄存器和狀態信息,開銷大。
  • 協程切換完全在用戶態進行,只需保存少量寄存器,開銷極小。
  1. 資源占用
  • 線程通常默認分配較大的棧空間(如1MB),因此不能大量創建。
  • 協程棧空間較小(可配置為幾KB),支持同時運行成千上萬個協程。
  1. 同步與通信
  • 線程間通信需要互斥鎖、信號量等機制,容易引發競態條件。
  • 協程可以通過通道(channel)、事件循環等方式進行安全高效的通信。
  1. 并發模型
  • 多線程屬于并行模型,適用于 CPU 密集型任務。
  • 協程屬于異步/協作式并發模型,適用于 IO 密集型任務(如網絡請求、文件讀寫)。

GMP調度

Go語言的GPM調度模型是Go運行時中用于處理并發的核心機制之一,它將Goroutine(輕量級線程)有效地映射到系統線程上,以最大化并發性能。GPM模型主要由三個部分組成:G(Goroutine)、P(Processor)、M(Machine)。讓我們逐一詳細介紹:

1. G(Goroutine)

  • Goroutine 是Go語言中用于并發執行的輕量級線程,每個Goroutine都有自己的棧和上下文信息。
  • Goroutine相對于操作系統的線程更加輕量級,可以在同一時間內運行成千上萬的Goroutine。

2. P(Processor)

  • P 是處理Goroutine的調度器的上下文,每個P包含一個本地運行隊列(Local Run Queue),用于存儲需要運行的Goroutine。
  • P的數量由GOMAXPROCS設置決定,它決定了并行執行的最大線程數。
  • P不僅管理Goroutine,還負責與M協作,將Goroutine分配給M執行。

3. M(Machine)

  • M 代表操作系統的線程,負責執行Goroutine。一個M一次只能執行一個Goroutine。
  • M是實際執行代碼的工作單元,M與P綁定后才能執行Goroutine。
  • M可以通過調度器從全局運行隊列中拉取新的Goroutine,也可以與其他M協作完成工作。

4. GPM模型的調度過程

  • 調度器工作機制:Goroutine創建后會被放入P的本地隊列,P會從該隊列中選擇Goroutine,并將其分配給M執行。如果本地隊列為空,P可以從全局運行隊列或其他P的隊列中竊取任務。
  • 工作竊取機制:如果一個P的本地隊列為空,而另一個P的本地隊列中有多個Goroutine,前者可以從后者中竊取任務,從而保持系統的高效利用率。
  • 阻塞與調度:當M執行的Goroutine阻塞(例如I/O操作)時,M會釋放當前的P并等待P重新分配任務,從而避免資源浪費。

5. 模型優點

  • 高效的并發調度:GPM模型使得Go語言可以高效地管理數百萬個Goroutine的并發執行。
  • 可伸縮性:通過P與M的動態調度,GPM模型可以充分利用多核處理器的性能。
  • 輕量級:Goroutine非常輕量,創建和切換的成本比系統線程要低得多。

redis 常見數據類型

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

壓縮列表

連續內存塊組成的順序型數據結構
在這里插入圖片描述
在這里插入圖片描述
O(1)定位首尾元素,其他需要遍歷,不適合存儲太多數據。
在這里插入圖片描述
在這里插入圖片描述

整數集合

在這里插入圖片描述

跳表

跳表的優勢是能支持平均O(logN)復雜度的節點查找
zset存儲member和score
在這里插入圖片描述
在這里插入圖片描述

quicklist代替雙向鏈表

在這里插入圖片描述

在這里插入圖片描述

listpack代替壓縮列表

在這里插入圖片描述
在這里插入圖片描述

redis跳表的增刪改查復雜度

O(logN)
在這里插入圖片描述

redis跳表數據結構,高度創建,怎么刪改

在這里插入圖片描述
跳躍表(Skip List)的刪除和修改操作需要結合其多層鏈表結構的特點進行調整,以下是具體實現步驟和原理:


一、刪除操作

刪除節點的核心步驟是:找到目標節點在所有層的引用,并更新這些層的指針以跳過該節點

1. 刪除流程
  1. 查找目標節點

    • 從最高層開始,向右遍歷,直到找到等于或大于目標值的節點。
    • 如果當前層的下一個節點等于目標值,記錄該層的前驅節點(即指向目標節點的節點)。
    • 逐層向下重復此過程,直到最底層(Level 0)。
    • 時間復雜度:O(log n),與查找操作相同。
  2. 調整指針

    • 對每一層(從最高層到最底層):
      • 如果該層存在指向目標節點的前驅節點,將其指針指向目標節點的下一個節點。
      • 例如,若前驅節點在 Level 2 指向目標節點,則將前驅節點的 Level 2 指針指向目標節點的 Level 2 后繼節點。
    • 操作示例
      原結構(刪除節點 30):
      Level 2: 10 --------------------------> 50
      Level 1: 10 -------> 30 -------> 50
      Level 0: 10 -> 20 -> 30 -> 40 -> 50刪除后:
      Level 2: 10 --------------------------> 50
      Level 1: 10 -------> 50
      Level 0: 10 -> 20 -> 40 -> 50
      
  3. 釋放內存

    • 刪除節點后,釋放該節點的內存(在 Redis 等語言中可能由 GC 自動處理)。
2. 關鍵注意事項
  • 多線程安全:如果跳躍表支持并發操作,刪除時需加鎖(如 Redis 單線程模型無需考慮)。
  • 更新最大層高:若刪除的節點是最高層的唯一節點,需降低跳躍表的最大層高。

二、修改操作

修改操作分為兩種情況:僅修改值(Value)修改鍵(Score)

1. 僅修改值(Value)
  • 流程
    1. 查找目標節點:時間復雜度 O(log n)。
    2. 直接更新值:無需調整指針,直接修改節點的值字段。
  • 時間復雜度:O(log n)(僅查找時間)。
2. 修改鍵(Score)

由于跳躍表是按鍵(Score)有序排列的,修改鍵后需保證順序性,因此需要先刪除舊節點,再插入新節點

  • 流程

    1. 刪除舊節點:O(log n)。
    2. 插入新節點:按新鍵值插入,O(log n)。
  • 總時間復雜度:O(log n) + O(log n) = O(log n).

  • 示例

    原結構(修改節點 30 的 Score 為 35):
    Level 1: 10 -------> 30 -------> 50
    Level 0: 10 -> 20 -> 30 -> 40 -> 50修改后:
    Level 1: 10 --------------------------> 50
    Level 0: 10 -> 20 -> 40 -> 50
    新插入節點 35:
    Level 1: 10 ----------> 35 -------> 50
    Level 0: 10 -> 20 -> 35 -> 40 -> 50
    

redis持久化AOF怎么做

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

數組中重復的數據

https://leetcode.cn/problems/find-all-duplicates-in-an-array/description/

func findDuplicates(nums []int) []int {n := len(nums)ans := []int{}for i:=0;i<n;i++{x := nums[i]if x<0{x = -x}if nums[x-1]<0{ans = append(ans, x)}else{nums[x-1] = -nums[x-1]}}return ans
}

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

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

相關文章

STM32 IIC總線

目錄 IIC協議簡介 IIC總線系統結構 IIC總線物理層特點 IIC總線協議層 空閑狀態 應答信號 數據的有效性 數據傳輸 STM32的IIC特性及架構 STM32的IIC結構體 0.96寸OLED顯示屏 SSD1306框圖及引腳定義 4針腳I2C接口模塊原理圖 字節傳輸-I2C 執行邏輯框圖 命令表…

【unity游戲開發入門到精通——UGUI】整體控制一個UGUI面板的淡入淡出——CanvasGroup畫布組組件的使用

注意&#xff1a;考慮到UGUI的內容比較多&#xff0c;我將UGUI的內容分開&#xff0c;并全部整合放在【unity游戲開發——UGUI】專欄里&#xff0c;感興趣的小伙伴可以前往逐一查看學習。 文章目錄 前言CanvasGroup畫布組組件參數 實戰專欄推薦完結 前言 如果我們想要整體控制…

大型語言模型個性化助手實現

大型語言模型個性化助手實現 目錄 大型語言模型個性化助手實現PERSONAMEM,以及用戶資料和對話模擬管道7種原位用戶查詢類型關于大語言模型個性化能力評估的研究大型語言模型(LLMs)已經成為用戶在各種任務中的個性化助手,從提供寫作支持到提供量身定制的建議或咨詢。隨著時間…

生成式 AI 的未來

在人類文明的長河中,技術革命始終是推動社會躍遷的核心引擎。從蒸汽機解放雙手,到電力點亮黑夜,再到互聯網編織全球神經網絡,每一次技術浪潮都在重塑人類的生產方式與認知邊界。而今天,生成式人工智能(Generative AI)正以一種前所未有的姿態登上歷史舞臺——它不再局限于…

【序列化與反序列化詳解】

文章目錄 一、序列化與反序列化是什么&#xff1f;1. 為什么需要序列化&#xff1f;2. 反序列化的作用 二、常見的序列化格式三、不同編程語言的序列化與反序列化示例1. Python 的序列化與反序列化JSON 序列化Pickle 序列化&#xff08;僅限 Python&#xff09; 2. Java 的序列…

【單例模式】簡介

目錄 概念理解使用場景優缺點實現方式 概念理解 單例模式要保證一個類在整個系統運行期間&#xff0c;無論創建多少次該類的對象&#xff0c;始終只會有一個實例存在。就像操作系統中的任務管理器&#xff0c;無論何時何地調用它&#xff0c;都是同一個任務管理器在工作&#…

目標檢測YOLO實戰應用案例100講- 無人機平臺下露天目標檢測與計數

目錄 知識儲備 基于YOLOv8改進的無人機露天目標檢測與計數 一、環境配置與依賴安裝 二、核心代碼實現(帶詳細注釋) 1. 改進YOLOv8模型定義(添加注意力機制) 2. 無人機視角數據增強(drone_augment.py ) 3. 多目標跟蹤與計數(tracking_counter.py ) 4. 完整推理流…

【在Spring Boot中集成Redis】

在Spring Boot中集成Redis 依賴在application.yml中配置Redis服務地址創建Redis配置類緩存工具類使用 依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency&…

計算機視覺——基于樹莓派的YOLO11模型優化與實時目標檢測、跟蹤及計數的實踐

概述 設想一下&#xff0c;你在多地擁有多個倉庫&#xff0c;要同時監控每個倉庫的實時狀況&#xff0c;這對于時間和精力而言&#xff0c;都構成了一項艱巨挑戰。從成本和可靠性的層面考量&#xff0c;大規模部署計算設備也并非可行之策。一方面&#xff0c;大量計算設備的購…

通信協議記錄儀-產品規格書

以下是為 ??通信協議記錄儀(ProtoLogger Pro)?? 的??詳細產品規格書??,覆蓋 ??技術細節、場景需求、競品差異化??,確保可作為產品開發、市場營銷及競品分析的核心依據。 ??通信協議記錄儀產品規格書?? ??產品名稱??:ProtoLogger Pro(中文名稱:蹲守…

python:sklearn 決策樹(Decision Tree)

5. 決策樹&#xff08;Decision Tree&#xff09; - 第5章 算法思想&#xff1a;基于信息增益&#xff08;ID3&#xff09;或基尼不純度&#xff08;CART&#xff09;遞歸劃分特征。 編寫 test_dtree_1.py 如下 # -*- coding: utf-8 -*- """ 5. 決策樹&…

【2-sat】2-sat算法內容及真題

A.2-sat簡介 2-sat算法可以求解給定推出關系下的一種合法情況。題目中重常常&#xff0c;給定一些布爾變量A、B、C、D…&#xff0c;再給出一系列形如 B ? A , C ? D B \longrightarrow A , C \longrightarrow \neg D B?A,C?D的推出關系&#xff0c;詢問使得所有推出關系…

【git】獲取特定分支和所有分支

1 特定分支 1.1 克隆指定分支&#xff08;默認只下載該分支&#xff09; git clone -b <分支名> --single-branch <倉庫URL> 示例&#xff08;克隆 某一個 分支&#xff09;&#xff1a; git clone -b xxxxxx --single-branch xxxxxxx -b &#xff1a;指定分支…

LWIP帶freeRTOS系統移植筆記

以正點原子學習視頻為基礎的文章 LWIP帶freeRTOS系統移植 準備資料/工程 1、lwIP例程1 lwIP裸機移植 工程 &#xff0c; 作為基礎工程 改名為LWIP_freeRTOS_yizhi工程 2、lwIP例程6 lwIP_FreeRTOS移植 工程 3、freeRTO源碼 打開https://www.freertos.org/網址下載…

組網技術知識點

1.port-isloate enable命令用于實現兩個接口之間的二層數據隔離&#xff0c;三層數據互通。 2.交換機最多支持4096個VLAN&#xff0c;編號為1-4094 3.display bfd session all&#xff1a;查看BFD會話狀態是否UP 4.RJ45通過雙絞線連接以太網&#xff1b; AUI端口&#xff1…

Linux系統:進程程序替換以及相關exec接口

本節重點 理解進程替換的相關概念與原理掌握相關程序替換接口程序替換與進程創建的區別程序替換的注意事項 一、概念與原理 進程程序替換是操作系統中實現多任務和資源復用的關鍵機制&#xff0c;允許進程在運行時動態加載并執行新程序。 1.1 定義 進程程序替換是指用新程…

從此,K8S入門0門檻!

前言 當你想要入門K8S的時候&#xff0c;往往會被各種概念搞的暈乎乎的&#xff0c;什么API Server&#xff0c;Scheduler&#xff0c;Controller manager&#xff0c;Etcd&#xff0c;Pod&#xff0c;Kubelet&#xff0c;kube-proxy&#xff0c;deployment…… 哪怕你使用了…

[Python開發] 如何用 VSCode 編寫和管理 Python 項目(從 PyCharm 轉向)

在 Python 開發領域,PyCharm 一直是廣受歡迎的 IDE,但其遠程開發功能(如遠程 SSH 調試)僅在付費版中提供。為了適應服務器部署需求,很多開發者開始將目光轉向更加輕量、靈活且免費擴展能力強的 VSCode。本篇文章將詳細介紹,從 PyCharm 轉向 VSCode 后,如何高效搭建和管理…

處方流轉平臺權限控制模塊設計(基于RBAC模型)

這是基于筆者的一些經驗設計并加以完善的方案&#xff0c;僅供參考。 處方流轉平臺權限控制模塊設計&#xff08;基于RBAC模型&#xff09; 1. 需求分析 處方流轉平臺需要嚴格的權限控制&#xff0c;確保&#xff1a; 患者隱私數據保護處方開具、審核、調配、發藥等流程的合…

基于BM1684X+RK3588的智能工業視覺邊緣計算盒子解決方案

智能工業視覺邊緣計算終端技術方案書? ?1. 產品概述? 1.1 產品定位 面向工業自動化場景的高性能AI視覺處理設備集成BM1684X&#xff08;8TOPS INT8&#xff09;AI加速芯片 RK3588&#xff08;6TOPS NPU&#xff09;異構計算支持工業級多相機接入、實時缺陷檢測、高精度定…