【數據結構】之散列

一、定義與基本術語

(一)、定義

散列(Hash)是一種將鍵(key)通過散列函數映射到一個固定大小的數組中的技術,因為鍵值對的映射關系,散列表可以實現快速的插入、刪除和查找操作。在這里分辨一下散列表和哈希表(Hash table和Hash Map):

  • 散列表:可能是一個更通用的概念,不一定強調鍵值對的映射關系。
  • 哈希表:通常強調鍵值對的映射關系,類似于?HashMap?或?Dictionary

不過呢,散列表和哈希表在本質上是相同的,我們平時使用一般也不會做很詳細的區分。都是基于散列函數的數據結構,用于高效地存儲和查找數據。

(二)、基本術語

  • 哈希函數(Hash Function):也叫散列函數,將鍵映射到散列表中的索引位置的函數。

哈希函數的作用是將鍵(key)轉換為一個索引值,這個索引值用于在底層的數組(或其他數據結構)中定位存儲值(value)的位置。這個過程可以概括為以下幾個步驟:

  1. 鍵到哈希值的轉換:哈希函數接收一個鍵作為輸入,并輸出一個哈希值。這個哈希值通常是整數。

  2. 哈希值到索引的映射:哈希值通過某種映射機制(如取模運算)轉換成數組的索引。這個索引決定了鍵值對在哈希表中的具體存儲位置。

  3. 存儲和檢索:在存儲數據時,鍵值對被放置在由鍵通過哈希函數和映射機制確定的索引處。在檢索數據時,同樣的鍵通過哈希函數和映射機制計算出索引,然后直接訪問該索引處的值。

常見的散列(哈希)函數:

  • 除留余數法:hash(key) = key % table_size
  • 乘留余數法:hash(key) = (key * A) % table_size,其中?A?是一個常數。
  • 平方取中法:適用于鍵是字符串的情況。
  • 哈希沖突(Hash Collision):兩個不同的鍵通過散列函數映射到同一個索引位置。

由于哈希值的范圍通常遠小于鍵的總數,不同的鍵可能會經過哈希函數計算后得到相同的索引值,這種現象稱為哈希沖突。為了解決哈希沖突,常用的方法包括:

  • 鏈地址法:在每個數組索引位置維護一個鏈表,所有映射到該索引的鍵值對都存儲在這個鏈表中。(是不是可以想到操作系統里的地址表)

  • 開放尋址法:當發生沖突時,使用某種探測序列在數組中尋找下一個空閑位置。

  • 再哈希法:使用另一個哈希函數計算一個新的索引值。

  • 負載因子(Load Factor):散列表中元素數量與表的容量的比值,衡量哈希表的空間利用率,>0.75會引發重哈希。

如果負載因子過高,意味著更多的鍵被映射到同一個桶中,這會增加哈希沖突的概率,降低哈希表的性能;

相反,如果負載因子過低,意味著哈希表的存儲空間沒有得到充分利用,導致額外的空間浪費。

實例 1:理想的哈希函數

假設我們有一個哈希表,總桶數量為10,哈希函數設計得非常完美,將5個鍵均勻地分布在這10個桶中。

  • 已使用的桶的數量:5

  • 總桶的數量:10

  • 負載因子:105?=0.5

在這種情況下,負載因子為0.5,表示哈希表的使用率為50%,沖突的概率較低,性能較好。

實例 2:不理想的哈希函數

假設我們有同樣的哈希表,總桶數量為10,但哈希函數設計得不理想,將5個鍵都映射到了前5個桶中。

  • 已使用的桶的數量:5

  • 總桶的數量:10

  • 負載因子:105?=0.5

盡管負載因子仍然是0.5,但由于鍵的分布不均勻,實際上前5個桶已經滿了,而后5個桶是空的。這種情況下,雖然負載因子顯示哈希表的使用率不高,但實際上已經出現了性能問題。

實例 3:高負載因子

假設我們有一個哈希表,總桶數量為5,但存儲了8個鍵。

  • 已使用的桶的數量:8

  • 總桶的數量:5

  • 負載因子:8/5?=1.6

在這種情況下,負載因子為1.6,表示哈希表的使用率超過了100%,這意味著平均每個桶中有兩個鍵,哈希沖突非常頻繁,性能會顯著下降。

實例 4:動態擴容

假設我們有一個動態擴容的哈希表,初始總桶數量為10,存儲了15個鍵。

  • 已使用的桶的數量:15

  • 總桶的數量:10

  • 負載因子:15/10?=1.5

當負載因子達到一定閾值(例如1.0)時,哈希表會自動擴容,比如將桶的數量增加到20。擴容后,原有的鍵會重新通過哈希函數計算新的桶位置,從而降低負載因子,減少沖突。

  • 擴容后的總桶的數量:20

  • 負載因子:15/20?=0.75

通過動態擴容,負載因子降低,哈希表的性能得到改善。

二、特點

  1. 高效性

    • 平均時間復雜度為?O(1) 的插入、刪除和查找操作。
    • 在最壞情況下(如所有鍵都映射到同一索引),時間復雜度為?O(n)。
  2. 靈活性

    • 可以處理任意類型的鍵(如整數、字符串等)。
    • 可以通過選擇合適的散列函數和沖突解決方法優化性能。
  3. 空間利用率

    • 散列表通常需要預留一定的空間來降低沖突概率。
    • 負載因子通常控制在 0.5 到 0.8 之間。

三、基本操作實現

基本操作就包括:

定義、插入,刪除,查找

1. 散列表的基本操作

class HashTable{
private:vector<int> table;int size;// 哈希函數int hashFunction(int key) {return key % size;}public:// 構造函數HashTable(int s) : size(s) {table.resize(size, -1);}// 插入元素void insert(int key) {int index = hashFunction(key);while (table[index] != -1) {index = (index + 1) % size;}table[index] = key;}// 查找元素bool search(int key) {int index = hashFunction(key);int start = index;while (table[index] != -1) {if (table[index] == key) {return true;}index = (index + 1) % size;if (index == start) {break;}}return false;}// 刪除元素void remove(int key) {int index = hashFunction(key);int start = index;while (table[index] != -1) {if (table[index] == key) {table[index] = -1;return;}index = (index + 1) % size;if (index == start) {break;}}}// 打印哈希表void printTable() {for (int i = 0; i < size; ++i) {cout << "Index " << i << ": ";if (table[i] != -1) {cout << table[i];} else {cout << "Empty";}cout << endl;}}
};int main() {HashTable hashTable(10);// 插入元素hashTable.insert(12);hashTable.insert(22);hashTable.insert(3);// 打印哈希表cout << "After insertion:" << endl;hashTable.printTable();// 查找元素cout << "\nSearching for 22: " << (hashTable.search(22) ? "Found" : "Not found") << endl;cout << "Searching for 10: " << (hashTable.search(10) ? "Found" : "Not found") << endl;// 刪除元素hashTable.remove(22);cout << "\nAfter deletion of 22:" << endl;hashTable.printTable();return 0;
}

2. 使用內置函數

以上都是為了幫助理解,在實際的代碼中,std::unordered_map?和std::unordered_set?都屬于標準庫中的哈希表實現,借助它我們可以直接運用其內置函數來完成基本操作,無需手動實現哈希表。兩者適用的問題不同:

  • std::unordered_map:存儲的是鍵值對(key - value),每個元素由一個鍵和一個與之關聯的值組成。鍵是唯一的,通過鍵可以快速查找對應的值。例如,我們可以用?unordered_map?來存儲學生的學號和對應的姓名,學號作為鍵,姓名作為值。Leetcode例題參考:??????
  • std::unordered_set:只存儲單一的元素,每個元素都是唯一的。它更側重于判斷某個元素是否存在于集合中。例如可以用?unordered_set?來存儲一組不重復的單詞。Leetcode例題參考:202. 快樂數

具體來說,常用的內置函數包括:

1. 插入元素

  • insert:把鍵值對插入到?unordered_map?中。若鍵已存在,則不會插入新元素。
  • emplace:原位構造并插入一個新元素,若鍵已存在,則不插入。
  • operator[]:若鍵存在,返回對應的值;若鍵不存在,則插入該鍵,并默認初始化其值。

2. 查找元素

  • find:查找指定鍵的元素,若找到則返回指向該元素的迭代器;若未找到,則返回?end()?迭代器。(所以我們判斷指定鍵的元素在不在表中一般用的代碼類似:if(seen.find(n)==seen.end()) )
  • count:返回指定鍵的元素數量,由于?unordered_map?中鍵是唯一的,所以返回值要么是 0(鍵不存在),要么是 1(鍵存在)。

3. 刪除元素

  • erase:刪除指定鍵的元素,可接受鍵或迭代器作為參數。

4. 其他常用函數

  • size:返回表中元素的數量。
  • empty:判斷表是否為空。
  • clear:清空表中的所有元素。

在這里也給出一個應用的例子:

#include <iostream>
#include <unordered_map>
#include <unordered_set>int main() {// 使用 std::unordered_mapstd::unordered_map<int, std::string> myMap;myMap[1] = "apple";myMap[2] = "banana";auto itMap = myMap.find(1);if (itMap != myMap.end()) {std::cout << "Value for key 1 in map: " << itMap->second << std::endl;}// 使用 std::unordered_setstd::unordered_set<std::string> mySet;mySet.insert("apple");mySet.insert("banana");auto itSet = mySet.find("apple");if (itSet != mySet.end()) {std::cout << "Element 'apple' found in set." << std::endl;}return 0;
}

四、練習

1. 基本概念練習

首先明確單射、滿射的含義:
理想的單射哈希函數:每個鍵都映射到一個唯一的索引,沒有任何兩個鍵共享同一個索引。這可以完全避免哈希沖突,使得每個鍵都可以直接映射到一個唯一的桶或數組位置。

理想的滿射哈希函數:所有的桶或數組索引至少被一個鍵映射到。這確保了數組的空間被充分利用,沒有浪費的桶或索引。

但以上都屬于理想情況,在實際設計哈希函數時,目標是盡量減少沖突(接近單射),同時盡可能均勻地分布鍵到所有可用的索引(接近滿射)。

由此分析:?

A:錯誤。由于 ∣A∣<∣S∣,即地址空間小于詞條空間,不可能每個詞條都映射到一個唯一的地址,因此 h 不可能是滿射。

B:正確。從A的分析就能知道,由于 ∣A∣<∣S∣,不同的詞條必須映射到相同的地址以避免某些詞條無法映射,因此 h 不可能是單射。

C:錯誤。雖然 ∣A∣<∣S∣,但 h 仍然可以是滿射,只要每個地址都至少被一個詞條映射到。

D:錯誤。單射要求每個地址只能映射到一個詞條。在哈希表中,由于沖突的存在,一個地址可能映射到多個詞條,因此 h 不一定是單射。

我們從構造散列函數的目的進行分析,可以找出正確和錯誤的說法。

  • 單射:在散列表的上下文中,單射并不是一個好的特性,因為不同的鍵映射到同一個索引是不可避免的,這是由于散列表的大小有限。

  • 值域覆蓋:一個好的散列函數應該盡可能覆蓋散列表的所有地址,這樣可以提高空間利用率和減少沖突。

  • 一致性:同一個詞條每次計算得到的哈希值應該是相同的,這樣才能保證數據的一致性。

  • 效率:散列函數的計算應該簡單快速,以便于快速定位和檢索數據。

  • 均勻分布:散列函數應該能夠將不同的詞條均勻地分布在散列表中,避免某些區域過于擁擠,這有助于減少沖突。

  • 沖突幾率:一個好的散列函數應該設計得能夠最小化沖突的概率,這樣可以提高散列表的性能。

?

對于?h1(key)=key%12,計算每個元素的哈希值:

  • 0%12=0

  • 8%12=8

  • 16%12=4

  • 24%12=0 (與0沖突)

  • 32%12=8 (與8沖突)

  • 40%12=4 (與16沖突)

  • 48%12=0 (與0, 24, 32沖突)

  • 56%12=8 (與8, 32, 48沖突)

  • 64%12=4 (與16, 40沖突)

不同的哈希值有:{0,4,8},共3個不同的元素。

對于?h2(key)=key%11,計算每個元素的哈希值:

  • 0%11=0

  • 8%11=8

  • 16%11=5

  • 24%11=2

  • 32%11=10

  • 40%11=7

  • 48%11=4

  • 56%11=1

  • 64%11=9

所有的哈希值都是不同的,因此有9個不同的元素。

A. 錯誤。獨立鏈法中,每個桶(數組的每個位置)都鏈接到一個鏈表,沖突的詞條存放在對應的鏈表中,而不是桶數組內部。

B.?正確。開放定址法中,當發生沖突時,詞條會嘗試在數組中找到下一個空閑位置存放,因此實際存放位置可能與散列函數計算出的位置不同。

C. 錯誤。開放定址法不會使用鏈表存放詞條,而是在數組中尋找下一個空閑位置。

D. 錯誤。即使散列函數設計得再好,由于散列表的大小有限,不同的鍵仍然可能映射到同一個索引,需要沖突解決策略。

h(4)=(3×4+5)%11=17%11=6

也就是說詞條4應該被放在數組索引6的位置,但是我們發現索引6處非空閑,存儲的是15,需要使用線性試探來尋找下一個空閑位置。線性試探的公式通常是 hi?=(h+i)%size,其中 i 是探測次數,從0開始。

  • 第一次試探:h0?=6(已占用)

  • 第二次試探:h1?=(6+1)%11=7(已被26占用)

  • 第三次試探:h2?=(6+2)%11=8(空)

所以鍵4的實際存放位置是數組索引8的位置,即 A[8]。

開放定址法是一種處理哈希表沖突的方法,其中平方試探法是開放定址法的一種。在平方試探法中,如果發生沖突,我們按照 hi?=(h+i2)%size 的公式來探測下一個可能的空槽位。

當使用平方試探法時,為了保證哈希表中至少有一個空槽位,裝填因子load factor也就是負載因子不能超過 0.5。

這是因為在最壞的情況下,如果裝填因子超過 0.5,那么在探測過程中可能會遇到一個“循環”,即所有的槽位都被占用,沒有空槽位可以插入新的詞條。

(1) H(9)=9%11=9

所以關鍵字為9的節點應該被存儲在索引為9的位置。先對給出的散列表中元素進行插入:

給定的關鍵字已經按順序插入散列表,我們先計算它們的哈希值并確定它們的存儲位置:

  • 15: 15%11=4 → 存儲在位置 4

  • 31: 31%11=9 → 存儲在位置 9

  • 27: 27%11=5 → 存儲在位置 5

  • 14: 14%11=3 → 存儲在位置 3

  • 10: 10%11=10 → 存儲在位置 10

  • 16: 16%11=5 → 與關鍵字 27 沖突,線性探測到位置 6

  • 11: 11%11=0 → 存儲在位置 0

查找后發現索引為9的位置已被占用,那就線性探測繼續找下一個空位。

  • 位置 10 已被關鍵字 10 占用

  • 位置 11 為空

因此,關鍵字 9 將被存儲在位置 11。

A={11,31,?,14,?,0,15,26,16,5,9,?}

(2) 平均成功查找長度

  • 15: 直接在位置 4 找到,長度為 1

  • 31: 直接在位置 9 找到,長度為 1

  • 27: 直接在位置 5 找到,長度為 1

  • 14: 直接在位置 3 找到,長度為 1

  • 10: 直接在位置 10 找到,長度為 1

  • 16: 在位置 5 沖突,探測到位置 6,長度為 2

  • 11: 直接在位置 0 找到,長度為 1

  • 9: 在位置 9 沖突,探測到位置 11,長度為 2

總長度 = 1+1+1+1+1+2+1+2=10 ,關鍵字數量 = 8

ASL(成功) =10/8 =5/4

(3) 失敗的平均查找長度

采用線性探測法處理沖突時,若該地址有元素,從該地址開始,依次探測下一個地址,直到找到空地址。將每個散列地址查找失敗的比較次數相加,再除以散列地址的個數,就能得到失敗的平均查找長度。

A={11,31,?,14,?,0,15,26,16,5,9,?}

位置0:依次探測0,1,2,在索引為2處找到空桶,比較次數3;

位置1:依次探測1,2,在索引為2處找到空桶,比較次數2;

位置2:在索引為2處找到空桶,比較次數1;

位置3:依次探測3,4,在索引為4處找到空桶,比較次數2;

位置4:在索引為4處找到空桶,比較次數1;

位置5:依次探測5,6,7,8,9,10,11,在索引為11處找到空桶,比較次數為7;

位置6:依次探測6,7,8,9,10,11,在索引為11處找到空桶,比較次數為6;

位置7:依次探測7,8,9,10,11,在索引為11處找到空桶,比較次數為5;

位置8:依次探測8,9,10,11,在索引為11處找到空桶,比較次數為4;

位置9:依次探測9,10,11,在索引為11處找到空桶,比較次數為3;

位置10:依次探測10,11,在索引為11處找到空桶,比較次數為2;

位置11:在索引為11處找到空桶,比較次數為1;

總長度 = 3+2+1+2+1+7+6+5+4+3+2+1=11 空桶數量 = 3

ASL(失敗)?= 11

五、Leetcode練習題匯總

題號題目名稱難度等級關鍵詞
1兩數之和簡單哈希表、數組
202快樂數簡單哈希表、數學、雙指針
217存在重復元素簡單哈希表、數組、排序
219存在重復元素 II簡單哈希表、數組
242有效的字母異位詞簡單哈希表、字符串、排序
349兩個數組的交集簡單哈希表、雙指針、二分查找、排序
350兩個數組的交集 II簡單哈希表、雙指針、二分查找、排序
409最長回文串簡單哈希表、字符串、貪心
451根據字符出現頻率排序中等哈希表、字符串、排序、堆(優先隊列)
560和為 K 的子數組中等哈希表、數組、前綴和
705設計哈希集合簡單哈希表、設計
706設計哈希映射簡單哈希表、設計
771寶石與石頭簡單哈希表、字符串
811子域名訪問計數簡單哈希表、字符串
953驗證外星語詞典簡單哈希表、字符串
1207獨一無二的出現次數簡單哈希表、數組
1365有多少小于當前數字的數字簡單哈希表、數組、排序、計數
1481不同整數的最少數目中等哈希表、貪心、排序、堆(優先隊列)

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

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

相關文章

How AI could empower any business - Andrew Ng

How AI could empower any business - Andrew Ng References 人工智能如何為任何業務提供支持 empower /?m?pa??(r)/ vt. 授權&#xff1b;給 (某人) ...的權力&#xff1b;使控制局勢&#xff1b;增加 (某人的) 自主權When I think about the rise of AI, I’m reminded …

微服務的服務調用詳解以及常見解決方案對比

微服務服務調用詳解 1. 服務調用分類 服務調用根據通信方式、同步性、實現模式可分為以下類型&#xff1a; 按通信協議分類 類型典型協議/框架特點RPC&#xff08;遠程過程調用&#xff09;Dubbo、gRPC、Apache Thrift高性能、二進制協議、強類型定義HTTP/RESTSpring RestTe…

MySQL:B+樹索引

InnoDB索引方案 為了使用二分法快速定位具體的目錄項&#xff0c;假設所有目錄項都可以在物理存儲器上連續存儲&#xff0c;有以下問題&#xff1a; InnoDB使用頁為管理存儲空間的基本單位&#xff0c;最多只能保證16KB的連續存儲空間&#xff0c;記錄數據量多可能需要非常大…

THCON 2025

Crypto OTPas_ouf 用10個字符異或加密的jpg圖片&#xff0c;通過頭得到key再恢復原圖 Mammoths Personnal Slot Machine 梅森旋轉恢復 from pwn import * from randcrack import RandCrack from tqdm import trange context.log_level errorp remote(74.234.198.209, 33…

3.8 字符串的常用函數

重點&#xff1a;字符串的常用函數 #1.測試轉換大小寫 lower:大寫->小寫 upper&#xff1a;小寫->大寫 swapcase&#xff1a;自動將大寫轉小寫小寫轉大寫 print("ABC".lower()) #abcprint("abc".upper()) #ABCprint…

Docker:SkyWalking 鏈路追蹤的技術指南

1、簡述 Apache SkyWalking 是一個開源的 APM(應用性能監控)工具,能夠實現分布式系統的全鏈路監控、性能分析以及服務依賴關系分析。SkyWalking 支持多種語言的探針,提供強大的可視化監控和分析能力,是微服務架構下性能調優和問題排查的利器。 樣例代碼: https://gitee.…

[Lc] 最長公共子序列 | Fenwick Tree(樹狀數組):處理動態前綴和

目錄 LCR 095. 最長公共子序列 題解 Fenwick Tree&#xff08;樹狀數組&#xff09;&#xff1a;處理動態前綴和 一、問題背景&#xff1a;當傳統方法遇到瓶頸 二、Fenwick Tree核心設計 2.1 二進制索引的魔法 2.2 關鍵操作解析 更新操作&#xff08;O(log n)&#xff0…

python3.13.0環境安裝及python-docx庫安裝指南

1. Python環境安裝 1.1 Windows系統安裝Python 下載Python安裝包 ? 訪問Python官網 ? 點擊"Download Python 3.x.x"&#xff08;推薦使用3.8及以上版本&#xff09; 2. 運行安裝程序 ? 雙擊下載的安裝包 ? 重要&#xff1a;勾選"Add Python to environmen…

前端VUE框架理論與應用(4)

一、計算屬性 模板內的表達式非常便利,但是設計它們的初衷是用于簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護。例如: <div id="example">{{ message.split().reverse().join() }}</div> 在這個地方,模板不再是簡單的聲明式邏輯。你…

MySQL:存儲函數和存儲過程

系列文章目錄 1.MySQL編程基礎 2.程序控制流語句 3.存儲過程 4.游標 5.嵌入式SQL 文章目錄 系列文章目錄前言一、程序控制流語句&#xff1a;二、存儲函數&#xff1a; 1.存儲函數的特點&#xff1a;2.存儲函數的定義&#xff1a;3.調用存儲函數 三、存儲過程&#xff1a;…

基礎貪心算法集合2(10題)

目錄 1.單調遞增的數字 2.壞了的計算器 3.合并區間 4.無重疊區間 5. 用最少數量的箭引爆氣球 6.整數替換 解法1&#xff1a;模擬記憶化搜索 解法2位運算貪心 7.俄羅斯套娃信封問題 補充.堆箱子 8.可被3整除的最大和 9.距離相等的條形碼 10.重構字符串 1.單調遞增的數字…

RaabitMQ 快速入門

&#x1f389;歡迎大家觀看AUGENSTERN_dc的文章(o゜▽゜)o☆?? &#x1f389;感謝各位讀者在百忙之中抽出時間來垂閱我的文章&#xff0c;我會盡我所能向的大家分享我的知識和經驗&#x1f4d6; &#x1f389;希望我們在一篇篇的文章中能夠共同進步&#xff01;&#xff01;&…

語音識別——根據聲波能量、VAD 和 頻譜分析實時輸出文字

SenseVoiceSmall網絡結構圖 ASR(語音識別)是將音頻信息轉化為文字的技術。在實時語音識別中,一個關鍵問題是:如何決定將采集的音頻數據輸入大模型的最佳時機?固定時間間隔顯然不夠靈活,太短可能導致頻繁調用模型,太長則會延遲文字輸出。有沒有更智能的方式?答案是肯定…

AI大模型如何重塑科研范式:從“假說驅動”到“數據涌現”

??個人主頁??:慌ZHANG-CSDN博客 ????期待您的關注 ???? 一、引言:科研進入“模型共研”時代 傳統科研范式通常以“假設→實驗→驗證→理論”的方式推進,這一經典路徑建立在人類的認知能力與邏輯推理基礎上。然而,隨著數據規模的爆炸式增長與知識系統的高度復雜…

使用Python寫入JSON、XML和YAML數據到Excel文件

在當今數據驅動的技術生態中&#xff0c;JSON、XML和YAML作為主流結構化數據格式&#xff0c;因其層次化表達能力和跨平臺兼容性&#xff0c;已成為系統間數據交換的通用載體。然而&#xff0c;當需要將這類半結構化數據轉化為具備直觀可視化、動態計算和協作共享特性的載體時&…

面試題:Eureka和Nocas的區別

Eureka 與 Nacos 核心區別對比 一、功能定位與核心能力 ?維度??Eureka??Nacos??核心功能?專注服務注冊與發現&#xff0c;無配置管理功能?:ml-citation{ref“1,3” data“citationList”}集成服務注冊、發現、配置管理、動態DNS等?:ml-citation{ref“1,3” data“c…

2025年4月15日 百度一面 面經

目錄 1. 代理相關 從靜態代理到動態代理 2. cglib可以代理被final修飾的類嗎,為什么 3. JVM 體系結構 4. 垃圾回收算法 5. 什么是注解 如何使用 底層原理 6. synchronized和reentrantlock 7. 講一下你項目中 redis的分布式鎖 與java自帶的鎖有啥區別 8. post 請求和 ge…

AI改變生活

AI改變生活 人工智能&#xff08;AI&#xff09;在我們生活中的應用越來越廣泛&#xff0c;深刻地改變了我們的工作和生活方式。以下是一些AI實際應用的實例&#xff0c;以及它們如何影響我們的日常生活。 1. 智能助手 智能助手如Siri、Alexa和Google Assistant等&#xff0…

信奧賽之c++基礎(取模運算與數位分離)

?? 數字拆解大冒險——取模運算與數位分離魔法課 ?? 第一章:糖果分裝術——取模運算 ?? 分糖果游戲 7顆糖每人分3顆: 每人得到:7 / 3 = 2顆剩余糖果:7 % 3 = 1顆(%就是取模符號) 就像把糖果裝袋后剩下的零散糖粒!?? 取模運算說明書 算式比喻結果10 % 310顆糖分…

揭秘大數據 | 21、軟件定義計算

老夫先將這個小系列的前兩篇內容鏈接奉上&#xff0c;方便感興趣的朋友一氣讀之。 揭秘大數據 | 19、軟件定義的世界-CSDN博客 揭秘大數據 | 20、軟件定義數據中心-CSDN博客 今天&#xff0c;書接上文&#xff0c;開聊軟件定義計算的那些事兒&#xff01; 虛擬化是軟件定義…