电竞比分网-中国电竞赛事及体育赛事平台

分享

極致的運算效率內存占用Bitmap原理、擴展、應用和面試全解析

 山峰云繞 2023-12-18 發(fā)布于貴州

https://m.toutiao.com/is/i8UekRdk/ 


Bitmap為解決海量數(shù)據(jù)處理問題而生,本文從Bitmap的由來、原理、優(yōu)缺點、擴展、應用及面試等六類視角(細分十一小節(jié))展開講解。

一 為什么會發(fā)明Bitmap

在計算機科學中,處理大規(guī)模數(shù)據(jù)時,傳統(tǒng)的數(shù)據(jù)結構和算法往往會遇到性能瓶頸。例如,當需要在大量整數(shù)中查找、去重或進行其他操作時,常規(guī)方法可能需要大量的內存和計算資源

為了解決這個問題,研究者們開始尋找更高效的數(shù)據(jù)結構。他們發(fā)現(xiàn),如果使用位(bit)來表示數(shù)據(jù),可以極大地節(jié)省內存空間。這是因為一個位只有0和1兩種狀態(tài),相比于使用字節(jié)或更大的單位來存儲數(shù)據(jù),位操作更加高效。

基于上述思路,John W. Tukey在1948年發(fā)明了Bitmap。Bitmap是一種特殊的數(shù)組,它的每個元素都可以表示為一個位。通過使用位運算,可以對Bitmap進行高效的操作,如設置、清除和檢測某個位的狀態(tài)。

二 Bitmap詳解

Bitmap 的基本原理就是用一個 bit 來標記某個元素對應的 Value,而 Key 即是該元素。由于采用一 個bit 來存儲一個數(shù)據(jù),因此可以大大的節(jié)省空間。

我們通過一個具體的例子來說明 Bitmap 的原理,假設我們要對 0-31 內的 3 個元素 (10, 17,28) 排序,那么我們就可以采用 Bitmap 方法(假設這些元素沒有重復)。

如下圖,要表示 32 個數(shù),我們就只需要 32 個 bit(4Bytes),首先我們開辟 4Byte 的空間,將這些空間的所有 bit 位都置為 0。

然后,我們要添加(10, 17,28) 這三個數(shù)到 BitMap 中,需要的操作就是在相應的位置上將0置為1即可。如下圖,比如現(xiàn)在要插入 10 這個元素,只需要將藍色的那一位變?yōu)?即可。

將這些數(shù)據(jù)插入后,假設我們想對數(shù)據(jù)進行排序或者檢索數(shù)據(jù)是否存在,就可以依次遍歷這個數(shù)據(jù)結構,碰到位為 1 的情況,就當這個數(shù)據(jù)存在。

Bitmap 也可以用來表述字符串類型的數(shù)據(jù),但是需要有一層Hash映射,如下圖,通過一層映射關系,可以表述字符串是否存在。

代碼實現(xiàn)方面,可陳述如下:

第一步:構建特定長度的byte數(shù)組(new byte[capacity/8 + 1]),其中capacity為整數(shù)數(shù)組長度(如:10億個數(shù)字等)

byte[] bits = new byte[getIndex(n) + 1];

第二步:計算數(shù)字num在byte[]中的位置(num/8和num >> 3一樣),也就是說num在byte[k],算這個k是幾

public int getIndex(int num){        return num >> 3;}

第三步:計算數(shù)字num在byte[index]中的位置,就是在byte[index]的第幾位,每個byte有8位(num % 8)

public int getPosition(int num){ return num & 0x07;}

第四步:將所在位置從0變成1,其它位置不變

public void add(byte[] bits, int num){        bits[getIndex(num)] |= 1 << getPosition(num);}

第五步:判斷指定數(shù)字num是否存在

public boolean contains(byte[] bits, int num){ return (bits[getIndex(num)] & 1 << getPosition(num)) != 0;}

第六步:重置某一數(shù)字對應在bitmap中的值

public void clear(byte[] bits, int num){        bits[getIndex(num)] &= ~(1 << getPosition(num));}

三 Bitmap優(yōu)缺點

優(yōu)點

  1. 運算效率高:Bitmap算法利用位運算進行操作,計算機處理位運算的速度非??欤虼薆itmap算法具有很高的運算效率。
  2. 內存占用少:Bitmap算法以bit為單位存儲數(shù)據(jù),相比其他數(shù)據(jù)結構(如數(shù)組、鏈表等),可以極大地節(jié)省內存空間。例如,如果需要記錄一千萬個不同的整數(shù),只需要占用內存為N/8=1250000Bytes=1.192Mb,這對于大數(shù)據(jù)處理來說是一個很大的優(yōu)勢。

缺點

  1. 數(shù)據(jù)密集才有優(yōu)勢:只有當數(shù)據(jù)比較密集時,Bitmap算法才有優(yōu)勢。如果數(shù)據(jù)非常稀疏,例如幾千個數(shù)分布在1~20億之間,那么占用的空間就會很大,遍歷的次數(shù)也多,此時使用Bitmap算法可能并不高效。
  2. 數(shù)據(jù)不能重復:Bitmap算法的一個主要缺點是它不能處理重復的數(shù)據(jù)。因為每個bit只能表示0或1兩種狀態(tài),所以無法對重復的數(shù)據(jù)進行排序和查找。
  3. 無法直接對位操作:在Bitmap中,我們不能直接對某一位進行操作,而需要通過計算得到該位的位置,這可能會增加一些計算的復雜性。

四 Bitmap的擴展--Roaring Bitmap

針對Bitmap的缺點1(數(shù)據(jù)稀疏時占用內存空間大),S. Chambi、D. Lemire、O. Kaser等人在2016年發(fā)表的論文《Better bitmap performance with Roaring bitmaps》 《Consistently faster and smaller compressed bitmaps with Roaring》中提出了RoaringBitMap,一種高效壓縮位圖,簡稱RBM。

實現(xiàn)思路

RBM主要將32位的整型(int)分為高16位和低16位(兩個short),其中高16位對應的數(shù)字使用16位整型有序數(shù)組存儲,低16位根據(jù)不同的情況選擇三種不同的container來存儲,這三種container分別為:

1 Array Container

底層數(shù)據(jù)結構為short類型的數(shù)組,直接將數(shù)字低16位的值存儲到該數(shù)組中。short類型的數(shù)組始終保持有序,方便使用二分查找,且不會存儲重復數(shù)值。因為這種Container存儲數(shù)據(jù)沒有任何壓縮,因此只適合存儲少量數(shù)據(jù)。其內部數(shù)組容量是動態(tài)變化的,當容量不夠時會進行擴容,最大容量為4096。由于數(shù)組是有序的,存儲和查詢時都可以通過二分查找快速定位其在數(shù)組中的位置。

ArrayContainer占用的空間大小與存儲的數(shù)據(jù)量為線性關系,每個short為2字節(jié),因此存儲了N個數(shù)據(jù)的ArrayContainer占用空間大致為2N字節(jié)。存儲一個數(shù)據(jù)占用2字節(jié),存儲4096個數(shù)據(jù)占用8kb。

2 Bitmap Container

底層實現(xiàn)為位圖。這種Container使用long[]存儲位圖數(shù)據(jù)。我們知道,每個Container處理16位整形的數(shù)據(jù),也就是0~65535,因此根據(jù)位圖的原理,需要65536個比特來存儲數(shù)據(jù),每個比特位用1來表示有,0來表示無。每個long有64位,因此需要1024個long來提供65536個比特。

因此,每個BitmapContainer在構建時就會初始化長度為1024的long[]。這就意味著,不管一個BitmapContainer中只存儲了1個數(shù)據(jù)還是存儲了65536個數(shù)據(jù),占用的空間都是同樣的8kb。

3 Run Container

RunContainer中的Run指的是行程長度壓縮算法(Run Length Encoding),對連續(xù)數(shù)據(jù)有比較好的壓縮效果。它的原理是,對于連續(xù)出現(xiàn)的數(shù)字,只記錄初始數(shù)字和后續(xù)數(shù)量。即:

  • 對于數(shù)列11,它會壓縮為11,0;
  • 對于數(shù)列11,12,13,14,15,它會壓縮為11,4;
  • 對于數(shù)列11,12,13,14,15,21,22,它會壓縮為11,4,21,1;

源碼中的short[] valueslength中存儲的就是壓縮后的數(shù)據(jù)。

這種壓縮算法的性能和數(shù)據(jù)的連續(xù)性(緊湊性)關系極為密切,對于連續(xù)的100個short,它能從200字節(jié)壓縮為4字節(jié),但對于完全不連續(xù)的100個short,編碼完之后反而會從200字節(jié)變?yōu)?00字節(jié)。

也就RBM在存入一個32位的整形數(shù)字時,會先按照該數(shù)字的高16位進行分桶,以確定該數(shù)字要存入到哪個桶中。確定好分桶位置后,再將該數(shù)字對應的低16位放入到當前桶所對應的container中。

舉個栗子

以十進制數(shù)字131122為例,現(xiàn)在我們要將該數(shù)字放入到RBM中。第一步,先將該數(shù)字轉換為16進制,131122對應的十六進制為0x00020032;其中,高十六位對應0x0002,首先我們找到0x0002所在的桶,再將131122的低16位存入到對應的container中,131122的低16位轉換為10進制就是50,沒有超過ArrayContainer的容量4096,所以將低16位直接放入到對應的ArrayContainer中。

如果要插入的數(shù)字低16位超過了4096,RBM會將ArrayContainer轉換為BitMapContainer。反之,如果數(shù)據(jù)在刪除之后,數(shù)組中的最大數(shù)據(jù)小于4096,RBM會將BitMapContainer轉換回ArrayContainer。

RBM處理的是32位的數(shù)字,如果我們想處理Long類型的數(shù)字怎么辦呢?這個時候可以使用Roaring64NavigableMap。Roaring64NavigableMap也是使用拆分模式,將一個long類型數(shù)據(jù),拆分為高32位與低32位,高32位代表索引,低32位存儲到對應RoaringBitmap中,其內部是一個TreeMap類型的結構,會按照signed或者unsigned進行排序,key代表高32位,value代表對應的RoaringBitmap。

空間占用對比

數(shù)據(jù)類型

操作

Bitmap內存(byte)

RoaringBitmap(byte)

連續(xù)數(shù)據(jù)

插入1000w條連續(xù)數(shù)據(jù)

10000000

1253690

稀疏數(shù)據(jù)

插入1和999w兩個數(shù)據(jù)

10000000

24

五 Bitmap的擴展--Bloom Filter

針對Bitmap的缺點2(數(shù)據(jù)不能重復),Burton Howard Bloom在1970年他發(fā)表的論文《Space/Time Trade-offs in Hash Coding with Allowable Errors》中提出了Bloom Filter。

Bloom Filter:由只存0或1的位數(shù)組和多個hash算法, 進行判斷數(shù)據(jù)一定不存在或者可能存在的算法;如果這些bit數(shù)組 有任何一個0,則被判定的元素一定不在; 如果都是1則被檢元素很可能在;對比bitmap位圖,布隆過濾器適合更多類型元素,通過hash值轉換。

每次處理元素時,

  • 將元素添加到一個bitmap數(shù)組中,每個散列函數(shù)將元素映射到bitmap數(shù)組中的一個位置
  • 如果該位置已經被占用,則將該位置置為1,否則置為0
  • 當要查詢一個元素是否存在時,只需要計算該元素的散列值,并檢查bitmap數(shù)組中對應的位置是否已經被置為1
  • 如果都是1,則該元素可能存在,否則肯定不存在。

優(yōu)點:占用空間小,查詢速度快,空間效率和查詢時間都遠遠超過一般的算法

缺點:有一定的誤識別率,有一定的誤識別率,即某個元素可能存在,但實際上并不存在;刪除困難,因為無法確定某個位置是由哪個元素映射而來的

六 Bitmap的應用--Redis

統(tǒng)計當日活躍用戶

每日活躍統(tǒng)計創(chuàng)建一個bitmap鍵,當用戶活躍了根據(jù)用戶id的偏移量來設置對應的位為1

用戶簽到

每個用戶創(chuàng)建一個位圖的鍵,以某一天為基礎,之后的天數(shù)距離這一天的天數(shù)為偏移量,如果用戶點擊了簽到,則設置對用的偏移位為1。

應對緩存穿透問題

舉例:比如爬蟲服務器在爬取電商網站的商品信息時,首先經過緩存,如果緩存查不到,再去數(shù)據(jù)庫獲取信息,因為爬蟲的效率很高,且sku很有可能是不存在或者已下架的,就會造成緩存穿透,大量請求被發(fā)送到數(shù)據(jù)庫,導致服務器受到影響。

此時,可以在緩存層之前,添加一個布隆過濾器,布隆 過濾器看作是一個bitmap,sku作為offset值,如果商品真實存在,bit值設為1。首先將商品數(shù)據(jù)初始化,當有請求時,通過getbit判斷sku是否有效。如果布隆過濾器認為商品不存在,就拒絕訪問,這樣就可以保護存儲層。

七 Bitmap的應用--阿里Hologres

技術平臺基于RoaringBitmap的畫像分析使用實踐,技術用戶畫像分析是對一個或多個指定用戶群,通過可視化的方式,可以多維、立體的展示用戶群的畫像信息,讓運營更好的理解人群,實現(xiàn)人群細分及對個性化運營策略的制定提供能力支撐;在進行數(shù)據(jù)分析時,更加便捷的獲得人群的特征信息,從而更好的進行定量的分析。

業(yè)務畫像分析流程:

1、默認情況下平臺有業(yè)務的所有標簽在MaxCompute中存儲,同時也會存儲一份Bitmap的標簽索引數(shù)據(jù),再標簽數(shù)據(jù)更新時構建。

2、業(yè)務可以使用標簽和其他用戶相關的數(shù)據(jù)圈選人群,人群圈選完成后,也會對其構建一份Bitmap索引數(shù)據(jù)。

3、圈選完人群后,就會進行畫像分析,如果標簽和人群都有Bitmap索引數(shù)據(jù),就會通過Bitmap進行分析

技術平臺早期畫像分析主要依賴于MaxCompute執(zhí)行SQL,但這種方式耗時較長,對于需要實時洞察分析的業(yè)務場景,分析需要更加快速看到結果,高延遲無法滿足業(yè)務需求。之前嘗試通過將數(shù)據(jù)導入Hologres進行加速,然而由于數(shù)據(jù)量龐大,Hologres的執(zhí)行耗時仍然超過3分鐘。

在前期,根據(jù)業(yè)務需求在技術上做了一些調研。從技術方案角度看,一些可以實現(xiàn)的畫像分析的方案和其缺點:

而Hologres原生支持RoaringBitmap數(shù)據(jù)結構,特別適合大數(shù)據(jù)量級下的交并差運算,并且在畫像分析的場景天然適合,因此我們最后選擇了RoaringBitmap方案。雖然RoaringBitmap會帶來額外的處理和優(yōu)化步驟、索引構建過程,這可能會帶來一定的初期成本上升。然而,在既定的場景中,數(shù)據(jù)更新不是那么頻繁,數(shù)據(jù)量級也在可控范圍內,因此這一成本上升在可接受范圍。而且使用RoaringBitmap帶來的效率提升非常明顯,最終還是選擇使用這一方案進行標簽和人群加速。

八 Bitmap的應用--美團Doris

Doris是美團數(shù)據(jù)加工處理的產品,其在整個數(shù)倉的位置如下圖所示

在24年約Q3前后,從位運算、內存拷貝、接口、并發(fā)等四類場景對Doris中使用的Bitmap進行優(yōu)化,如:

九 Bitmap其他應用場景

  1. 數(shù)據(jù)庫索引:Bitmap索引可以用于數(shù)據(jù)庫查詢,通過位運算快速判斷記錄是否滿足查詢條件
  2. 緩存系統(tǒng):使用Bitmap可以標記緩存中的對象,從而快速判斷對象是否存在于緩存中
  3. 網絡流量監(jiān)控:通過Bitmap標記網絡流量中的數(shù)據(jù)包,可以快速檢測異常流量
  4. 數(shù)據(jù)壓縮:使用Bitmap標記數(shù)據(jù)中的重復部分,可以減少存儲空間的使用
  5. 搜索引擎:使用Bitmap標記搜索結果中的關鍵詞,可以快速過濾掉不相關的結果
  6. 推薦系統(tǒng):使用Bitmap標記用戶或物品的特征,可以快速找到相似的用戶或物品
  7. 社交網絡分析:使用Bitmap標記用戶的行為或興趣特征,可以快速找到具有相似興趣的用戶群體
  8. 事件檢測:使用Bitmap標記事件的相關特征,可以快速判斷是否存在特定的事件
  9. 數(shù)據(jù)清洗:使用Bitmap標記重復的數(shù)據(jù)記錄,可以快速識別和處理重復的數(shù)據(jù)記錄
  10. 集合運算:在多個集合運算中,例如并集、交集、差集等,可以使用Bitmap來加速計算過程。通過將每個集合映射到一個Bitmap上,可以快速判斷元素是否屬于某個集合。
  11. 哈希表沖突解決:在哈希表中,當兩個不同的鍵哈希到同一個槽位時,可以使用Bitmap來標記這個槽位上的鍵值對,從而快速判斷該槽位上是否存在沖突的鍵值對。
  12. 位圖排序:在處理大量數(shù)據(jù)時,可以使用位圖排序算法來對數(shù)據(jù)進行排序。通過將數(shù)據(jù)元素映射到一個Bitmap上,然后根據(jù)Bitmap的狀態(tài)對元素進行排序,可以實現(xiàn)高效的數(shù)據(jù)排序。
  13. 范圍查詢:在數(shù)據(jù)庫中執(zhí)行范圍查詢時,可以使用Bitmap來加速查詢過程。通過將查詢條件映射到一個Bitmap上,可以快速判斷滿足條件的記錄是否存在于數(shù)據(jù)庫中。
  14. 加密算法應用:在加密算法中,例如分組加密算法,可以使用Bitmap來標記每個分組中的元素,從而加速加密和解密過程。
  15. 內存管理優(yōu)化:在內存管理中,可以使用Bitmap來標記已分配和未分配的內存塊。通過快速判斷某個內存塊是否已分配,可以優(yōu)化內存分配和釋放的過程。
  16. 圖像處理:在圖像處理中,可以使用Bitmap來表示像素的顏色信息。通過將每個像素的顏色信息映射到一個Bitmap上,可以實現(xiàn)高效的圖像處理操作。
  17. 自然語言處理:在自然語言處理中,可以使用Bitmap來表示文本中的單詞或短語。通過將每個單詞或短語映射到一個Bitmap上,可以實現(xiàn)高效的文本分析和處理操作。
  18. 機器學習應用:在機器學習中,可以使用Bitmap來表示特征向量中的每個特征。通過將每個特征映射到一個Bitmap上,可以加速特征向量的存儲和計算過程。
  19. 分布式系統(tǒng)應用:在分布式系統(tǒng)中,可以使用Bitmap來表示每個節(jié)點的狀態(tài)信息。通過將每個節(jié)點的狀態(tài)信息映射到一個Bitmap上,可以實現(xiàn)高效的節(jié)點狀態(tài)管理和監(jiān)控操作。

十 Bitmap經典面試題解析

題目1:什么是Bitmap?

Bitmap是一種數(shù)據(jù)結構,它使用二進制位來表示數(shù)據(jù),可以高效地處理大量數(shù)據(jù)。

題目2:Bitmap有什么優(yōu)點?

Bitmap的優(yōu)點包括:

  • 節(jié)省內存空間:使用二進制位表示數(shù)據(jù),可以有效地減少內存占用。
  • 快速操作:通過位運算,可以快速地進行數(shù)據(jù)的查找、刪除和更新等操作。
  • 適用于海量數(shù)據(jù)處理:可以處理大量的數(shù)據(jù),并且處理效率較高。

題目3:如何實現(xiàn)一個Bitmap?

實現(xiàn)一個Bitmap需要使用一個數(shù)組來存儲二進制位,每個位表示一個數(shù)據(jù)元素是否出現(xiàn)。可以使用位運算來設置、清除和檢查位的狀態(tài)。

題目4:如何使用Bitmap進行數(shù)據(jù)的查找?

使用Bitmap進行數(shù)據(jù)的查找時,首先需要將數(shù)據(jù)元素的數(shù)值轉換為對應的位索引,然后檢查該位的狀態(tài)。如果該位為1,則表示該數(shù)據(jù)元素出現(xiàn);如果該位為0,則表示該數(shù)據(jù)元素未出現(xiàn)。

題目5:如何使用Bitmap進行數(shù)據(jù)的計數(shù)?

使用Bitmap進行數(shù)據(jù)的計數(shù)時,需要遍歷所有的位,統(tǒng)計為1的位的數(shù)量即可。

題目6:如何使用Bitmap進行數(shù)據(jù)的刪除?

使用Bitmap進行數(shù)據(jù)的刪除時,需要將該數(shù)據(jù)元素對應的位設置為0,表示該數(shù)據(jù)元素不再出現(xiàn)。

題目7:如何優(yōu)化Bitmap的性能?

  • 使用緩存:將經常訪問的位緩存起來,減少磁盤訪問次數(shù)。
  • 使用壓縮技術:對Bitmap數(shù)據(jù)進行壓縮,減少內存占用和磁盤存儲空間。
  • 使用多線程:使用多線程并行處理數(shù)據(jù),提高處理效率。

題目8:Bitmap適用于哪些場景?

  • 數(shù)據(jù)庫索引:可以使用Bitmap來快速判斷某個數(shù)據(jù)元素是否存在。
  • 緩存系統(tǒng):可以使用Bitmap來快速判斷某個數(shù)據(jù)元素是否在緩存中。
  • 搜索引擎:可以使用Bitmap來快速過濾掉不需要的數(shù)據(jù)元素。
  • 數(shù)據(jù)壓縮:可以使用Bitmap來快速判斷某個數(shù)據(jù)元素是否需要被壓縮。

題目9:如何理解Bitmap的位運算?

位運算是一種二進制運算,包括與、或、異或、非等操作。在Bitmap中,可以使用位運算來設置、清除和檢查位的值。例如,將第i位設置為1可以使用“1<<i”來表示;將第i位清除可以使用“~(1<<i)”來表示;檢查第i位的值可以使用“(value & (1<<i)) != 0”來判斷。

題目10:如何理解Bitmap的存儲結構?

Bitmap的存儲結構通常是一個數(shù)組,每個元素是一個二進制位。可以使用無符號整數(shù)類型來存儲這個數(shù)組,也可以使用位向量或者位集等特殊的數(shù)據(jù)結構來存儲這個數(shù)組。具體的存儲結構取決于具體的應用場景和需求。

題目11:如何理解Bitmap的動態(tài)擴展?

當需要添加新的數(shù)據(jù)元素時,可能需要動態(tài)擴展Bitmap的大小。這可以通過創(chuàng)建一個新的更大的數(shù)組,并將原來的數(shù)據(jù)復制到新的數(shù)組中來實現(xiàn)。具體的擴展方式取決于具體的應用場景和需求。

題目12:如何理解Bitmap的內存優(yōu)化?

在處理海量數(shù)據(jù)時,需要盡可能地節(jié)省內存空間。可以使用壓縮技術來減少Bitmap所占用的內存空間。此外,還可以通過復用已經計算出來的結果來減少計算量,進一步提高效率。例如,可以將已經計算出來的結果緩存起來,避免重復計算。

題目13:如何理解Bitmap的并發(fā)操作?

在多線程環(huán)境下,需要對Bitmap進行并發(fā)操作。這需要使用線程安全的并發(fā)數(shù)據(jù)結構,例如ConcurrentHashMap或者AtomicInteger等。同時,還需要對并發(fā)操作進行合理的同步和調度,以避免數(shù)據(jù)不一致和競態(tài)條件等問題。

題目14:如何理解Bitmap的位反轉問題?

在Bitmap中,如果某個位被錯誤地設置或者清除,可能會導致位反轉問題。這通常是由于位運算的錯誤或者硬件故障等原因引起的。為了避免位反轉問題,可以使用校驗和等技術來檢測和修復錯誤。

題目15:如何理解Bitmap的索引問題?

在Bitmap中,每個位都對應一個數(shù)據(jù)元素。但是,如果需要查找某個具體的數(shù)據(jù)元素,需要遍歷所有的位,這可能會非常耗時。為了解決這個問題,可以使用索引技術來快速定位到需要查找的數(shù)據(jù)元素。例如,可以使用哈希表或者B樹等數(shù)據(jù)結構來建立索引。

題目16:如何理解Bitmap的動態(tài)擴容問題?

當Bitmap的大小不足以容納新的數(shù)據(jù)元素時,需要進行動態(tài)擴容。這需要重新分配內存空間,并將原來的數(shù)據(jù)元素復制到新的數(shù)組中。這個過程可能會非常耗時,并且可能會影響程序的性能。為了解決這個問題,可以使用預分配技術來預先分配足夠的內存空間,避免頻繁的動態(tài)擴容操作。

題目17:如何理解Bitmap的位壓縮問題?

在處理海量數(shù)據(jù)時,為了節(jié)省內存空間,需要對Bitmap進行位壓縮。但是,壓縮和解壓縮的過程可能會非常耗時,并且可能會影響程序的性能。為了解決這個問題,可以使用高效的壓縮和解壓縮算法,例如LZ77或者Huffman編碼等。

題目18:如何理解Bitmap的刪除操作?

在Bitmap中,刪除一個數(shù)據(jù)元素通常需要將該數(shù)據(jù)元素對應的位設置為0。但是,如果該數(shù)據(jù)元素對應的位已經被其他數(shù)據(jù)元素共享,那么刪除該數(shù)據(jù)元素可能會影響其他數(shù)據(jù)元素的表示。為了解決這個問題,可以使用位運算中的異或操作來刪除一個數(shù)據(jù)元素,而不會影響其他數(shù)據(jù)元素的表示。

題目19:如何理解Bitmap的位運算效率問題?

位運算是一種非常高效的運算方式,但是在進行復雜的位運算時,也可能會遇到效率問題。為了提高位運算的效率,可以使用一些優(yōu)化技巧,例如使用緩存、并行計算、硬件加速等。同時,也可以使用一些高效的位運算庫或者工具來提高效率。

題目20:如何理解Bitmap的適用場景和局限性?

Bitmap是一種非常高效的數(shù)據(jù)結構,但是也有一些局限性。例如,它不適合處理包含大量重復元素的數(shù)據(jù)集,因為這會導致大量的位被占用。此外,Bitmap也不適合處理需要頻繁更新和查找的數(shù)據(jù)集,因為這可能會導致大量的磁盤I/O操作。因此,在使用Bitmap時需要考慮到它的適用場景和局限性。

十一 Bitmap算法題解析

問題1:給定一個長度為n的整數(shù)數(shù)組,其中可能存在重復元素,要求使用Bitmap算法找出數(shù)組中只出現(xiàn)一次的元素。
解答:首先,遍歷數(shù)組并使用Bitmap記錄每個元素出現(xiàn)的次數(shù)。然后,再次遍歷Bitmap,找到只出現(xiàn)一次的元素對應的位,即為所求。

問題2:有兩個非常大的整數(shù)集合A和B,要求使用Bitmap算法求出它們的交集。
解答:首先,將集合A和B分別轉換為Bitmap。然后,對兩個Bitmap進行按位與運算,得到的結果即為它們的交集。

問題3:給定一個長度為n的整數(shù)數(shù)組和一個目標整數(shù)target,要求使用Bitmap算法判斷數(shù)組中是否存在兩個數(shù)的和等于target。
解答:首先,遍歷數(shù)組并使用Bitmap記錄每個元素的出現(xiàn)情況。然后,對于每個元素num,檢查target - num是否在Bitmap中存在,如果存在則說明存在兩個數(shù)的和等于target。

問題4:給定一個長度為n的整數(shù)數(shù)組,要求使用Bitmap算法找出數(shù)組中出現(xiàn)次數(shù)最多的k個元素。
解答:首先,遍歷數(shù)組并使用Bitmap記錄每個元素出現(xiàn)的次數(shù)。然后,對Bitmap進行排序,找到出現(xiàn)次數(shù)最多的k個元素對應的位即可。

問題5:給定一個長度為n的整數(shù)數(shù)組和一個整數(shù)k,要求使用Bitmap算法找出數(shù)組中是否存在長度為k的連續(xù)子數(shù)組的和等于某個給定值。
解答:首先,使用滑動窗口遍歷數(shù)組并計算窗口內元素的和。然后,使用Bitmap記錄每個和的出現(xiàn)情況。如果某個和的值在Bitmap中出現(xiàn)過,則說明存在長度為k的連續(xù)子數(shù)組的和等于該值。

問題6:給定兩個非常大的整數(shù)集合A和B,要求使用Bitmap算法求出它們的并集。
解答:首先,將集合A和B分別轉換為Bitmap。然后,對兩個Bitmap進行按位或運算,得到的結果即為它們的并集。

問題7:給定一個長度為n的整數(shù)數(shù)組和一個整數(shù)k,要求使用Bitmap算法找出數(shù)組中是否存在兩個數(shù)的差的絕對值等于k。
解答:首先,遍歷數(shù)組并使用Bitmap記錄每個元素的出現(xiàn)情況。然后,對于每個元素num,檢查num + k和num - k是否在Bitmap中存在,如果存在則說明存在兩個數(shù)的差的絕對值等于k。

問題8:給定一個長度為n的整數(shù)數(shù)組和一個整數(shù)m,要求使用Bitmap算法判斷數(shù)組中是否存在一個子集的和等于m。
解答:該問題可以使用動態(tài)規(guī)劃和Bitmap結合解決。首先,創(chuàng)建一個長度為m+1的Bitmap,并初始化第0位為1。然后,遍歷數(shù)組并使用動態(tài)規(guī)劃的思想更新Bitmap的每個位。最后,檢查Bitmap的第m位是否為1,如果是則說明存在一個子集的和等于m。

問題9:給定一個長度為n的整數(shù)數(shù)組和一個整數(shù)target,要求使用Bitmap算法找出數(shù)組中是否存在三個數(shù)的和等于target。
解答:首先,遍歷數(shù)組并使用Bitmap記錄每兩個數(shù)的和的出現(xiàn)情況。然后,對于每個元素num,檢查target - num是否在Bitmap中存在,如果存在則說明存在三個數(shù)的和等于target。

問題10:給定一個長度為n的整數(shù)數(shù)組和一個整數(shù)k,要求使用Bitmap算法找出數(shù)組中是否存在長度為k的子數(shù)組的異或和等于0。
解答:該問題可以使用前綴異或和和Bitmap結合解決。首先,計算數(shù)組的前綴異或和并存儲在另一個數(shù)組中。然后,遍歷前綴異或和數(shù)組并使用Bitmap記錄每個值的出現(xiàn)情況。最后,檢查是否存在兩個前綴異或和的差等于0且它們之間的距離為k-1,如果存在則說明存在長度為k的子數(shù)組的異或和等于0。

十二 參考資料

[1] BitMap 的基本原理和實現(xiàn):
https://blog.csdn.net/u010412301/article/details/89377162

[2] Bitmap的原理和應用:
https://www.cnblogs.com/felixzh/p/15746669.html

[3] Bitmap、RoaringBitmap原理分析:
https://baijiahao.baidu.com/s?id=1761206677884050539&wfr=spider&for=pc

[4]
BloomFilter概念和原理以及業(yè)務中的應用場景 :
https://blog.csdn.net/weixin_47533244/article/details/129317127

[5] Redis之bitmap類型解讀:
https://blog.csdn.net/m0_62436868/article/details/132424914

[6] Hologres RoaringBitmap實踐:千億級畫像數(shù)據(jù)秒級分析:
https://it.sohu.com/a/721472386_120583536

[7] 美團 Doris Bitmap 精確去重優(yōu)化實踐:
https://mp.weixin.qq.com/s/XNWVb4CMPCAZfEBWRPROyQ

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多