場景題一


參考:

海量數據處理思路

一 TOP-K問題

(1)TOP=K問題=  
        在海量數據中找出出現次數最大 數值最大的前k個數
(2) 常規方法  
        分冶    +
        hash || Trie (用於 去重|| 檢測頻率)    +
        堆排序 

1. TOP-K 數值問題

    (1) 10000個數據 建立 size=10000  小頂堆 
    (2) 繼續添加剩余數據, 
             val> 堆頂(最小數) ,則val替換堆頂,並調整堆為小頂堆
             val< 堆頂,則跳過
    
    (3) heap.size=10000 , 堆調整次數 = 十億
        時間復雜度 = Om (初始建堆)+  Onlogm = Onlogm
    核心
    (4) 優化  冶:處理內存不足問題
             十億數據存儲在1000個文件中
            通過堆排序 將每個文件中10^6數據挑選出 10000個最大數據 
            將數據合並 ,通過快速排序獲得前10000大的數據 

2. TOP-K 頻率問題

(1) 分冶 通過 hash 10^9 個數據 存儲在多個文件中     // 同一hash值的 元素 
(2) 通過 hash || Trie(針對String) 統計重復頻率,再通過堆排序選取每個文件中頻率前10000的元素,建一個結構體作為堆結點元素
(3) 合並結果,再次通過hash || Trie統計頻率,進行堆排序

二. 海量數據中 重復字符串 = 布隆過濾器

1. 布隆過濾器

k個哈希函數,一個大小為kn的位數組,n是value個數,每個value元素分別使用這k個哈希函數計算出k個位下標,把位數組中這k個位下標都置為1,在把所有元素都加入到這個位數組中后,如果要判斷某個元素是否存在於這個value集合中,只需把這個要判斷的元素根據k個哈希函數計算出k個為位下標后,判斷維數組中這k個下標的元素,如果不是全為1,說明這個元素不存在,否則是可能存在。之間存在誤判。
eg: 給定a、b兩個文件,各存放50億個url,每個url各占64字節,內存限制是4G,讓你找出a、b文件共同的url?
如果用byte數組,50億 = 5 * 0.93 * 2^30 = 4.65G,如果用bit數組,50億 = 4.65G / 8 = 0.58G
  (1)    n個元素的位圖 占用nbit
    (2)     一個val 通過多個 hash函數生成多個hash
    (3)     每個hash值對應的 bit1 
    (4)     當輸入數據量很大,布隆過濾器長度較小時 容易誤判 

三. 海量數據中 重復數字 = 位圖

① 去重

一個位數組,每一個bit為表示一個數字,數組的長度取決於數字的最大值。把每個元素對應的為都置位1,最后遍歷一次這個位數組,就可以得到去除重復之后的元素集合。

② 找出不重復元素的個數

2.5億個整數中找出不重復的整數的個數,內存空間不足以容納這2.5億個整數。
    將bit-map擴展一下,用2bit表示一個數即可,0表示未出現,1表示出現一次,2表示出現2次及以上,在遍歷這些數的時候,如果對應位置的值是0,則將其置為1;如果是1,將其置為2;如果是2,則保持不變。
    1. N個數中,尋找未出現的數 
    2. 構建 bit[] 數組, size=N 
            內存受限時, 
            分區間檢測,
            [2M , 3M]中元素數量少於M
            則不存在元素出現在[2m,3m]范圍內
    3. 每當出現一個數據,則bit1 

必讀

海量數據處理面試題集錦
教你如何迅速秒殺掉:99%的海量數據處理面試題

大數據類場景題

1、10億個數值,找最大的一萬個

設置一個buf,固定size,每次讀一個buf大小的文件, 維持一個大小為1萬的小頂堆,遍歷效率是o(nlogK)
大數的問題,你應該計算一下這個數組整體大小,然后詢問數據是否重復,如果重復,先對文件hash,然后保存不同文件。

2、1億個正整數,范圍是0-42億。求出現次數是2的數字,空間復雜度

32位機器最大能表示的數字是42億9千多萬。
將bit-map擴展一下,用2bit表示一個數即可,0表示未出現,1表示出現一次,2表示出現2次,3表示出現3次即以上,在遍歷這些數的時候,如果對應位置的值是0,則將其置為1;如果是1,將其置為2;如果是2,則將其置為3;如果是3,則保持不變。
42億 * 2 = 86億  = 86 * 10^8 = 8G, 所以空間開銷為8G

3、2g內存,要求一個10g文件的中位數

4、有一個IP地址庫,假設有幾十萬條ip,如何判斷某個ip地址是否在這個庫中?

思路一:分治法,將ip地址根據前三位分成256份,然后看這個ip地址對應的網段,只比對這個網段里面是否有這個ip,當然還可以繼續分下去,根據數據量來決定分成多少份。
思路二:位圖,將每一條ip對應位圖中的一個位,2^32次方(42億多)個數據只需要512M空間。可以實現O(1)的時間搜索,O(n)的時間存儲。

5、一個5T的文件,里面全是id,1-10^9 ,如何計算不同id的個數?

思路一:哈希到不同的文件,再逐個文件內找不同的。
思路二:使用redis的HyperLoglog可以大致估算出不同id的個數。

其他場景題

1、一個每秒只能處理10w請求的系統,突然有50w的請求過來了,怎么處理使得這個系統不發生異常

阻塞隊列
降級控制: 就是對每一個任務設置一個級別,優先處理級別高的,級別低的任務的話可能價值不高或者沒有價值,所以可能不執行或者稍后執行

作者:星__塵 來源:牛客網

2、掃碼登錄是如何實現的?

3、B+樹和紅黑樹

紅黑樹和一般的平衡二叉樹,增、刪、改、查的過程和效率、時間復雜度 https://www.cnblogs.com/ArleneZhangfj/articles/10067570.html

4、讓你設計一個微信發紅包的api,你會怎么設計,不能有人領到的紅包里面沒錢,紅包數值精確到分。

傳入參數有總錢數,分的份數,隨機分還是等分。先判斷錢數能不能分那么多份,這個直接用總錢數>=0.01*份數判斷就可以了。然后根據分發策略,選擇隨機還是等分,隨機的話就給 1到總錢數-(總份數-1)*0.01 的隨機數(總錢數以分為單位),等分的話直接除判斷能不能除開,有余數就將余數加到最后一份里面。

5、需求:誰關注了我,我關注了誰,誰與我互相關注。表該如何設計,索引怎么建。查詢語句怎么寫

1、使用mysql實現

粉絲關注表使用四列,主鍵id,userId,fansId,是否互相關注。用兩行數據來保存互相的關注關系,這樣查詢起來更方便,用空間換時間。
主鍵有主鍵索引,剩下的字段不適合建索引,因為字段重復太多。

2、使用redis來實現

因為這個表的字段太少,所以考慮使用redis來實現。用一個set存儲每個用戶的關注列表和粉絲列表,關注列表的鍵是“follow:" + 當前用戶id,  粉絲列表的鍵是”當前用戶的id" + "follow", 這樣很容易就能得到某個用戶的所有粉絲和關注的人,相互關注的只需讓兩個set取交集即可。

6、分布式多個機器生成id,如何保證不重復?

1.snowflake方案

snowflake是Twitter開源的分布式ID生成算法,結果是一個long型的ID。其核心思想是:使用41bit作為毫秒數,10bit作為機器的ID(5個bit是數據中心,5個bit的機器ID),12bit作為毫秒內的流水號(意味着 每個節點在每毫秒可以產生 4096 個 ID ),最后還有一個符號位,永遠是0。
優點
1.毫秒數在高位,自增序列在低位,整個ID都是趨勢遞增的。
2.不依賴數據庫等第三方系統,以服務的方式部署,穩定性更高,生成ID的性能也是非常高的。
3.可以根據自身業務特性分配bit位,非常靈活。
缺點
強依賴機器時鍾,如果 機器上時鍾回撥 ,會導致發號重復或者服務會處於不可用狀態。

2.用Redis生成ID:

因為Redis是單線程的,也可以用來生成全局唯一ID。可以用Redis的原子操作INCR和INCRBY來實現。
此外,可以使用Redis集群來獲取更高的吞吐量。假如一個集群中有5台Redis,可以初始化每台Redis的值分別是1,2,3,4,5,步長都是5,各Redis生成的ID如下:
A:1,6,11,16
B:2,7,12,17
C:3,8,13,18
D:4,9,14,19
E:5,10,15,20
這種方式是負載到哪台機器提前定好,未來很難做修改。3~5台服務器基本能夠滿足需求,都可以獲得不同的ID,但步長和初始值一定需要事先確定,使用Redis集群也可以解決單點故障問題。
另外,比較適合使用Redis來生成每天從0開始的流水號,如訂單號=日期+當日自增長號。可以每天在Redis中生成一個Key,使用INCR進行累加。
優點:
1)不依賴於數據庫,靈活方便,且性能優於數據庫。
2)數字ID天然排序,對分頁或需要排序的結果很有幫助。
缺點:
1)如果系統中沒有Redis,需要引入新的組件,增加系統復雜度。
2)需要編碼和配置的工作量較大。

7、LRU算法知道嗎,怎么實現的?

LRU算法:最近最少使用算法,常用於進程調度,緩存淘汰,內存頁面置換等場景。
使用 LinkedHashMap 可以實現,相對於HashMap,增加了雙向鏈表,用於記錄節點之間的先后順序。LinkedHashMap的構造函數提供了一個參數 accessOrder, 這個參數可以指定鏈表是按照 插入順序 排隊還是按照 訪問順序 排隊。參數為true時,就是按照訪問順序(插入,查詢)排隊,每次訪問后這個節點就會被放到鏈表頭,而長時間不被訪問的節點逐漸就到了列表尾部,當需要淘汰時,就將鏈表尾部的節點拋棄。

8、數據庫連接池怎么設計?

需要考慮的問題:
  1. 限制連接池中最多、可以容納的連接數目,避免過度消耗系統資源。
  2. 當客戶請求連接,而連接池中所有連接都已被占用時,該如何處理呢?一種方式是讓客戶一直等待,直到有空閑連接,另一種方式是為客戶分配一個新的臨時連接。
  3. 當客戶不再使用連接,需要把連接重新放回連接池。
  4. 連接池中允許處於空閑狀態的連接的最大項目。假定允許的最長空閑時間為十分鍾,並且允許空閑狀態的連接最大數目為5,
那么當連接池中有n個(n>5)連接處於空閑狀態的時間超過十分鍾時,就應該把n-5個連接關閉,並且從連接池中刪除,這樣才能更有效的利用系統資源。

其他場景題

場景分析題:如果讓你實現一個用戶在另一台手機上登錄微信后把他之前登錄的那台手機上微信號頂掉你該怎么設計?說下你的思路

情景分析題:如果讓你來實現一個對高考成績的分類下的前100名成績你該怎么實現?說說你的思路(我也不知道對不對 我答的是使用hash函數將不同科目的成績分配到不同的文件然后在使用堆排序或者快排求解topk問題)

10億大數加和,怎么寫,我知道怎么多線程分別加和,但不知道什么數據結構可以存儲每個線程的和,我說了String,面試官說太慢了,好像用Bigint也不夠
設計一個錯誤類,輸入范圍內的整數,返回一個錯誤碼。寫了個類,但沒想到怎么處理這個輸入范圍。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM