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采用無中心結構,每個節點保存數據和整個集群狀態,每個節點都和其他所有節點連接。

其結構特點:
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自動完成故障發現和轉移,並通知應用方,實現高可用性。

1.哨兵機制建立了多個哨兵節點(進程),共同監控數據節點的運行狀況。
2.同時哨兵節點之間也互相通信,交換對主從節點的監控狀況。
3.每隔1秒每個哨兵會向整個集群:Master主服務器+Slave從服務器+其他Sentinel(哨兵)進程,發送一次ping命令做一次心跳檢測。
這個就是哨兵用來判斷節點是否正常的重要依據,涉及兩個新的概念:主觀下線和客觀下線。
1. 主觀下線:一個哨兵節點判定主節點down掉是主觀下線。
2.客觀下線:只有半數哨兵節點都主觀判定主節點down掉,此時多個哨兵節點交換主觀判定結果,才會判定主節點客觀下線。
原理:基本上哪個哨兵節點最先判斷出這個主節點客觀下線,就會在各個哨兵節點中發起投票機制Raft算法(選舉算法),最終被投為領導者的哨兵節點完成主從自動化切換的過程。
Redis 復制
Redis為了解決單點數據庫問題,會把數據復制多個副本部署到其他節點上,通過復制,實現Redis的高可用性,實現對數據的冗余備份,保證數據和服務的高度可靠性。
1.數據復制原理(執行步驟)

①從數據庫向主數據庫發送sync(數據同步)命令。
②主數據庫接收同步命令后,會保存快照,創建一個RDB文件。
③當主數據庫執行完保持快照后,會向從數據庫發送RDB文件,而從數據庫會接收並載入該文件。
④主數據庫將緩沖區的所有寫命令發給從服務器執行。
⑤以上處理完之后,之后主數據庫每執行一個寫命令,都會將被執行的寫命令發送給從數據庫。
注意:在Redis2.8之后,主從斷開重連后會根據斷開之前最新的命令偏移量進行增量復制

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來做,當時怎么考慮的?

組成部分說明如下:
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)