拼多多社招面經:Redis是重點,https是怎麼做到安全的?

1、簡單做一下自我介紹把,爲什麼這麼快就想換工作。簡單說下你簡歷中的項目。

2、看你在項目中用了redis,我們先聊聊redis吧,常用的數據結構有哪幾種,在你的項目中用過哪幾種,以及在業務中使用的場景,redis的hash怎麼實現的,rehash過程講一下和JavaHashMap的rehash有什麼區別?

redis cluster有沒有了解過,怎麼做到高可用的?

3redis集羣和哨兵機制有什麼區別?redis的持久化機制瞭解嗎?你們在項目中是怎麼做持久化的?遇到過redis的hotkey嗎?怎麼處理的?

4redis是單線程的嗎?單線程爲什麼還這麼快?講一講redis的內存模型?

5.我看你還用了RabbitMQ,簡單說一下RabbitMQ的工作原理?如何保證消息的順序執行?Kafka瞭解嗎?和RabbitMQ有什麼區別?你爲啥不用kafka來做,當時怎麼考慮的?

6、我看你簡歷裏說熟悉計算機網絡,來聊一聊計算機網絡吧。了不瞭解tcp/udp,簡單說下兩者的區別?tcp爲什麼要三次握手和四次揮手?兩次握手可以不?會有什麼問題?

tcp怎麼保證有序傳輸的,講下tcp的快速重傳和擁塞機制,知不知道time_wait狀態,這個狀態出現在什麼地方,有什麼用?

7、http與https有啥區別?https是怎麼做到安全的?

8、有沒有了解過協程?說下協程和線程的區別?用過哪些linux命令?如查看內存使用、網絡情況?

9、你瞭解哪些設計模式啊。挑一個熟悉的講講?(除了單例模式)在項目中有用過設計模式嗎?講講你怎麼用的?簡單說一下適配器模式和裝飾器模式?

10、你們數據庫有沒有用到分庫分表,怎麼做的?分庫分表以後全局id怎麼生成的?

11、索引的常見實現方式有哪些,有哪些區別?MySQL的存儲引擎有哪些,有哪些區別?InnoDB使用的是什麼方式實現索引,怎麼實現的?說下聚簇索引和非聚簇索引的區別?

12、看你簡歷提到了raft算法,講下raft算法的基本流程?raft算法裏面如果出現腦裂怎麼處理?有沒有了解過paxos和zookeeper的zab算法,他們之前有啥區別?

13、聊聊java基礎吧,如果我是想一個人的姓名一樣就認爲他們equal,能現場寫下我們怎麼重寫equals嗎?如果兩個對象,一個是cat,一個是dog,我們認爲他們的name屬性一樣就一樣,怎麼重寫equals

14,還有點時間,寫個題吧

leetcode406. 根據身高重建隊列

假設有打亂順序的一羣人站成一個隊列。 每個人由一個整數對(h, k)表示,其中h是這個人的身高,k是排在這個人前面且身高大於或等於h的人數。 編寫一個算法來重建這個隊列。

注意:

總人數少於1100人。

示例

輸入:

[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]

輸出:

[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

 


 

一:看你在項目中用了redis,我們先聊聊redis吧,常用的數據結構有哪幾種,在你的項目中用過哪幾種,以及在業務中使用的場景,redis的hash怎麼實現的,rehash過程講一下和JavaHashMap的rehash有什麼區別?redis cluster有沒有了解過,怎麼做到高可用的?

 

(1)常用的數據結構:

字符串(String),散列/哈希(hash),列表(list),無序集合類型(set),有序集合類型(sorted set)

(2)Redis的hash 實現:

Redis散列/哈希是鍵值對的集合。Redis散列/哈希是字符串字段和字符串值之間的映射,但字段值只能是字符串,不支持其他類型。因此,他們用於表示對象。應用場景:存儲用戶的基本信息,等等、

(3)redis cluster:

redis最開始使用主從模式做集羣,若master宕機需要手動配置slave轉爲master;後來爲了高可用提出來哨兵模式,該模式下有一個哨兵監視master和slave,若master宕機可自動將slave轉爲master,但它也有一個問題,就是不能動態擴充;所以在3.x提出cluster集羣模式。

Redis-Cluster採用無中心結構,每個節點保存數據和整個集羣狀態,每個節點都和其他所有節點連接。

 

拼多多社招面經:Redis是重點,https是怎麼做到安全的?

 

 

其結構特點:

1、所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬。

2、節點的fail是通過集羣中超過半數的節點檢測失效時才生效。

3、客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連接集羣所有節點,連接集羣中任何一個可用節點即可。

4、redis-cluster把所有的物理節點映射到[0-16383]slot上(不一定是平均分配),cluster 負責維護node<->slot<->value。

5、Redis集羣預分好16384個桶,當需要在 Redis 集羣中放置一個 key-value 時,根據 CRC16(key) mod 16384的值,決定將一個key放到哪個桶中。

 

二.redis集羣和哨兵機制有什麼區別?redis的持久化機制瞭解嗎?你們在項目中是怎麼做持久化的?遇到過redis的hotkey嗎?怎麼處理的?

 

(1)redis集羣和哨兵機制有什麼區別?

談到Redis服務器的高可用,如何保證備份的機器是原始服務器的完整備份呢?這時候就需要哨兵和複製。

哨兵(Sentinel):可以管理多個Redis服務器,它提供了監控,提醒以及自動的故障轉移的功能。

複製(Replication):則是負責讓一個Redis服務器可以配備多個備份的服務器。

Redis正是利用這兩個功能來保證Redis的高可用。

 

哨兵是Redis集羣架構中非常重要的一個組件,哨兵的出現主要是解決了主從複製出現故障時需要人爲干預的問題。

Redis哨兵主要功能

(1)集羣監控:負責監控Redis master和slave進程是否正常工作

(2)消息通知:如果某個Redis實例有故障,那麼哨兵負責發送消息作爲報警通知給管理員

(3)故障轉移:如果master node掛掉了,會自動轉移到slave node上

(4)配置中心:如果故障轉移發生了,通知client客戶端新的master地址

Redis哨兵的高可用

原理:當主節點出現故障時,由Redis Sentinel自動完成故障發現和轉移,並通知應用方,實現高可用性。

 

拼多多社招面經:Redis是重點,https是怎麼做到安全的?

 

 

1.哨兵機制建立了多個哨兵節點(進程),共同監控數據節點的運行狀況。

2.同時哨兵節點之間也互相通信,交換對主從節點的監控狀況。

3.每隔1秒每個哨兵會向整個集羣:Master主服務器+Slave從服務器+其他Sentinel(哨兵)進程,發送一次ping命令做一次心跳檢測。

 

這個就是哨兵用來判斷節點是否正常的重要依據,涉及兩個新的概念:主觀下線和客觀下線。

1. 主觀下線:一個哨兵節點判定主節點down掉是主觀下線。

2.客觀下線:只有半數哨兵節點都主觀判定主節點down掉,此時多個哨兵節點交換主觀判定結果,纔會判定主節點客觀下線。

原理:基本上哪個哨兵節點最先判斷出這個主節點客觀下線,就會在各個哨兵節點中發起投票機制Raft算法(選舉算法),最終被投爲領導者的哨兵節點完成主從自動化切換的過程。

 

Redis 複製

Redis爲了解決單點數據庫問題,會把數據複製多個副本部署到其他節點上,通過複製,實現Redis的高可用性,實現對數據的冗餘備份,保證數據和服務的高度可靠性。

 

1.數據複製原理(執行步驟)

 

拼多多社招面經:Redis是重點,https是怎麼做到安全的?

 

 

①從數據庫向主數據庫發送sync(數據同步)命令。

②主數據庫接收同步命令後,會保存快照,創建一個RDB文件。

③當主數據庫執行完保持快照後,會向從數據庫發送RDB文件,而從數據庫會接收並載入該文件。

④主數據庫將緩衝區的所有寫命令發給從服務器執行。

⑤以上處理完之後,之後主數據庫每執行一個寫命令,都會將被執行的寫命令發送給從數據庫。

注意:在Redis2.8之後,主從斷開重連後會根據斷開之前最新的命令偏移量進行增量複製

 

拼多多社招面經:Redis是重點,https是怎麼做到安全的?

 

 

Redis 主從複製、哨兵和集羣這三個有什麼區別

主從複製是爲了數據備份,哨兵是爲了高可用,Redis主服務器掛了哨兵可以切換,集羣則是因爲單實例能力有限,搞多個分散壓力,簡短總結如下:

主從模式:備份數據、負載均衡,一個Master可以有多個Slaves。

sentinel發現master掛了後,就會從slave中重新選舉一個master。

cluster是爲了解決單機Redis容量有限的問題,將數據按一定的規則分配到多臺機器。

sentinel着眼於高可用,Cluster提高併發量。

 

1.主從模式:讀寫分離,備份,一個Master可以有多個Slaves。

2.哨兵sentinel:監控,自動轉移,哨兵發現主服務器掛了後,就會從slave中重新選舉一個主服務器。

3.集羣:爲了解決單機Redis容量有限的問題,將數據按一定的規則分配到多臺機器,內存/QPS不受限於單機,可受益於分佈式集羣高擴展性。

 

4:redis是單線程的嗎?單線程爲什麼還這麼快?講一講redis的內存模型?

 

Redis內存劃分:

Redis作爲內存數據庫,在內存中存儲的內容主要是數據(鍵值對);通過前面的敘述可以知道,除了數據以外,Redis的其他部分也會佔用內存。

Redis的內存佔用主要可以劃分爲以下幾個部分:

1、數據

作爲數據庫,數據是最主要的部分;這部分佔用的內存會統計在used_memory中。

Redis使用鍵值對存儲數據,其中的值(對象)包括5種類型,即字符串、哈希、列表、集合、有序集合。這5種類型是Redis對外提供的,實際上,在Redis內部,每種類型可能有2種或更多的內部編碼實現;此外,Redis在存儲對象時,並不是直接將數據扔進內存,而是會對對象進行各種包裝:如redisObject、SDS等;這篇文章後面將重點介紹Redis中數據存儲的細節。

 

2、進程本身運行需要的內存

Redis主進程本身運行肯定需要佔用內存,如代碼、常量池等等;這部分內存大約幾兆,在大多數生產環境中與Redis數據佔用的內存相比可以忽略。這部分內存不是由jemalloc分配,因此不會統計在used_memory中。

補充說明:除了主進程外,Redis創建的子進程運行也會佔用內存,如Redis執行AOF、RDB重寫時創建的子進程。當然,這部分內存不屬於Redis進程,也不會統計在used_memory和used_memory_rss中。

 

3、緩衝內存

緩衝內存包括客戶端緩衝區、複製積壓緩衝區、AOF緩衝區等;其中,客戶端緩衝存儲客戶端連接的輸入輸出緩衝;複製積壓緩衝用於部分複製功能;AOF緩衝區用於在進行AOF重寫時,保存最近的寫入命令。在瞭解相應功能之前,不需要知道這些緩衝的細節;這部分內存由jemalloc分配,因此會統計在used_memory中。

 

4、內存碎片

內存碎片是Redis在分配、回收物理內存過程中產生的。例如,如果對數據的更改頻繁,而且數據之間的大小相差很大,可能導致redis釋放的空間在物理內存中並沒有釋放,但redis又無法有效利用,這就形成了內存碎片。內存碎片不會統計在used_memory中。

內存碎片的產生與對數據進行的操作、數據的特點等都有關;此外,與使用的內存分配器也有關係:如果內存分配器設計合理,可以儘可能的減少內存碎片的產生。後面將要說到的jemalloc便在控制內存碎片方面做的很好。

如果Redis服務器中的內存碎片已經很大,可以通過安全重啓的方式減小內存碎片:因爲重啓之後,Redis重新從備份文件中讀取數據,在內存中進行重排,爲每個數據重新選擇合適的內存單元,減小內存碎片。

 

5. 我看你還用了RabbitMQ,簡單說一下RabbitMQ的工作原理?如何保證消息的順序執行?Kafka瞭解嗎?和RabbitMQ有什麼區別?你爲啥不用kafka來做,當時怎麼考慮的?

拼多多社招面經:Redis是重點,https是怎麼做到安全的?

 

組成部分說明如下:

Broker:消息隊列服務進程,此進程包括兩個部分:Exchange和Queue。

Exchange:消息隊列交換機,按一定的規則將消息路由轉發到某個隊列,對消息進行過慮。

Queue:消息隊列,存儲消息的隊列,消息到達隊列並轉發給指定的消費方。

Producer:消息生產者,即生產方客戶端,生產方客戶端將消息發送到MQ。

Consumer:消息消費者,即消費方客戶端,接收MQ轉發的消息。

消息發佈接收流程:

 

-----發送消息-----

1、生產者和Broker建立TCP連接。

2、生產者和Broker建立通道。

3、生產者通過通道消息發送給Broker,由Exchange將消息進行轉發。

4、Exchange將消息轉發到指定的Queue(隊列)

 

----接收消息-----

1、消費者和Broker建立TCP連接

2、消費者和Broker建立通道

3、消費者監聽指定的Queue(隊列)

4、當有消息到達Queue時Broker默認將消息推送給消費者。

5、消費者接收到消息。

 

6、我看你簡歷裏說熟悉計算機網絡,來聊一聊計算機網絡吧。了不瞭解tcp/udp,簡單說下兩者的區別?tcp爲什麼要三次握手和四次揮手?兩次握手可以不?會有什麼問題?tcp怎麼保證有序傳輸的,講下tcp的快速重傳和擁塞機制,知不知道time_wait狀態,這個狀態出現在什麼地方,有什麼用?

(1)區別:

1、TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發送數據之前不需要建立連接

2、TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付

3、TCP面向字節流,實際上是TCP把數據看成一連串無結構的字節流;UDP是面向報文的

UDP沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)

4、每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信

5、TCP首部開銷20字節;UDP的首部開銷小,只有8個字節

6、TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道

 

兩次握手爲什麼不可以?

採用三次握手是爲了防止失效的連接請求報文段突然又傳送到主機B,因而產生錯誤。失效的連接請求報文段是指:主機A發出的連接請求沒有收到主機B的確認,於是經過一段時間後,主機A又重新向主機B發送連接請求,且建立成功,順序完成數據傳輸。考慮這樣一種特殊情況,主機A第一次發送的連接請求並沒有丟失,而是因爲網絡節點導致延遲達到主機B,主機B以爲是主機A又發起的新連接,於是主機B同意連接,並向主機A發回確認,但是此時主機A根本不會理會,主機B就一直在等待主機A發送數據,導致主機B的資源浪費。

 

爲什麼要四次揮手?

TCP關閉鏈接四次握手原因在於tpc鏈接是全雙工通道,需要雙向關閉。client向server發送關閉請求,表示client不再發送數據,server響應。此時server端仍然可以向client發送數據,待server端發送數據結束後,就向client發送關閉請求,然後client確認。

 

tcp怎麼保證有序傳輸的:

1)應用數據被分割成TCP認爲最適合發送的數據塊。

2)超時重傳:當TCP發出一個段後,它啓動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。

3)TCP給發送的每一個包進行編號,接收方對數據包進行排序,把有序數據傳送給應用層。

4)校驗和:TCP將保持它首部和數據的檢驗和。這是一個端到端的檢驗和,目的是檢測數據在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP將丟棄這個報文段和不確認收到此報文段。

5)TCP的接收端會丟棄重複的數據。

6)流量控制:TCP連接的每一方都有固定大小的緩衝空間,TCP的接收端只允許發送端發送接收端緩衝區能接納的我數據。當接收方來不及處理髮送方的數據,能提示發送方降低發送的速率,防止包丟失。TCP使用的流量控制協議是可變大小的滑動窗口協議。

7)擁塞控制:當網絡擁塞時,減少數據的發送。

 

time_wait狀態,這個狀態出現在什麼地方,有什麼用?

1.爲實現TCP全雙工連接的可靠釋放

當服務器先關閉連接,如果不在一定時間內維護一個這樣的TIME_WAIT狀態,那麼當被動關閉的一方的FIN到達時,服務器的TCP傳輸層會用RST包響應對方,這樣被對方認爲是有錯誤發生,事實上這只是正常的關閉連接工程,並沒有異常

 

2.爲使過期的數據包在網絡因過期而消失

在這條連接上,客戶端發送了數據給服務器,但是在服務器沒有收到數據的時候服務器就斷開了連接

現在數據到了,服務器無法識別這是新連接還是上一條連接要傳輸的數據,一個處理不當就會導致詭異的情況發生

 

下面講講大量的TIME_WAIT產生需要的條件:

1.高併發

2.服務器主動關閉連接

如果服務器不主動關閉連接,那麼TIME_WAIT就是客戶端的事情了

 

7、http與https有啥區別?https是怎麼做到安全的?

https安全的原因:

https把http消息進行加密之後再傳送,這樣就算壞人攔截到了,得到消息之後也看不懂,這樣就做到了安全,具體來說,https是通過對稱加密和非對稱加密和hash算法共同作用,來在性能和安全性上達到一個平衡,加密是會影響性能的,尤其是非對稱加密,因爲它的算法比較複雜,那麼加密了就安全了嗎?不是的,https除了對消息進行了加密以外還會對通信的對象進行身份驗證。

https並不是一種新的協議,而是使用了一種叫做TLS(Transport layer secure)的安全層,這個安全層提供了數據加密的支持,讓http消息運行在這個安全層上,就達到了安全,而運行在這個安全層上的http就叫做https(http secure)

 

8,還有點時間,寫個題吧

leetcode406. 根據身高重建隊列

假設有打亂順序的一羣人站成一個隊列。 每個人由一個整數對(h, k)表示,其中h是這個人的身高,k是排在這個人前面且身高大於或等於h的人數。 編寫一個算法來重建這個隊列。

注意:

總人數少於1100人。

示例

輸入:

[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]

輸出:

[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

 

思路:

第一步排序:

people:

[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]

排序後:

[[7,0], [7,1], [6,1], [5,0], [5,2], [4,4]]

然後從數組people第一個元素開始,放入到數組result中,放入的位置就是離result開始位置偏移了元素第二個數字後的位置。如下:

1. people: [7,0]

插入到離開始位置偏移了0個距離的位置。

result: [[7,0]]

 

2. people: [7,1]

插入到離開始位置偏移了1個距離的位置,即插入到[7,0]的後面。

result: [[7,0], [7,1]]

 

3. people: [6,1]

插入到離開始位置偏移了1個距離的位置,即插入到[7,0]的後面。

result: [[7,0], [6,1], [7,1]]

 

4. people: [5,0]

插入到離開始位置偏移了0個距離的位置,即插入到[7,0]的前面。

result: [[5,0], [7,0], [6,1], [7,1]]

 

5. people: [5,2]

插入到離開始位置偏移了2個距離的位置,即插入到[7,0]的後面。

result: [[5,0], [7,0], [5,2], [6,1], [7,1]]

 

6. people: [4,4]

插入到離開始位置偏移了4個距離的位置,即插入到[6,1]的後面。

result: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

這種算法體現了元素第二個數字與其插入位置的關係,所以通過簡單的一個for循環就可以搞定。

代碼

 

拼多多社招面經:Redis是重點,https是怎麼做到安全的?

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章