網際網路面試知識技術總結(javacore、jvm、redis、kafka、zookeeper、mysql、hystrix)-第四章

forrunning發表於2019-04-08

<3>Dubbo的負載均衡策略 負載均衡的實現是在客戶端實現的,當服務提供方是叢集的時候,為了避免大量請求一直落到一個或幾個服務提供方機器上,從而使這些機器負載很高,甚至打死,需要做一定的負載均衡策略。Dubbo提供了多種均衡策略,預設為random,也就是每次隨機呼叫一臺服務提供者的機器。 Dubbo提供的負載均衡策略 Random LoadBalance:隨機策略。按照概率設定權重,比較均勻,並且可以動態調節提供者的權重。 RoundRobin LoadBalance:輪詢策略。輪詢,按公約後的權重設定輪詢比率。會存在執行比較慢的服務提供者堆積請求的情況,比如一個機器執行的非常慢,但是機器沒有掛呼叫(如果掛了,那麼當前機器會從Zookeeper的服務列表刪除),當很多新的請求到達該機器後,由於之前的請求還沒有處理完畢,會導致新的請求被堆積,久而久之,所有消費者呼叫這臺機器上的請求都被阻塞。 LeastActive LoadBalance:最少活躍呼叫數。如果每個提供者的活躍數相同,則隨機選擇一個。在每個服務提供者裡面維護者一個活躍數計數器,用來記錄當前同時處理請求的個數,也就是併發處理任務的個數。所以如果這個值越小說明當前服務提供者處理的速度很快或者當前機器的負載比較低,所以路由選擇時候就選擇該活躍度最小的機器。如果一個服務提供者處理速度很慢,由於堆積,那麼同時處理的請求就比較多,也就是活躍呼叫數目越大,這也使得慢的提供者收到更少請求,因為越慢的提供者的活躍度越來越大。 ConsistentHash LoadBalance:一致性Hash策略。一致性Hash,可以保證相同引數的請求總是發到同一提供者,當某一臺提供者掛了時,原本發往該提供者的請求,基於虛擬節點,平攤到其他提供者,不會引起劇烈變動

簡單總結:常見負載均衡策略有(權重)輪詢,隨機,最小連線數,一致性hash等等 參考:www.cnblogs.com/xhj123/p/90…

<4>Dubbo的核心角色 Provider: 暴露服務的服務提供方。 Consumer: 呼叫遠端服務的服務消費方。 Registry: 服務註冊與發現的註冊中心。 Monitor: 統計服務的呼叫次調和呼叫時間的監控中心。

呼叫關係說明: 服務容器負責啟動,載入,執行服務提供者。 服務提供者在啟動時,向註冊中心註冊自己提供的服務。 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連線推送變更資料給消費者。 服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一臺提供者進行呼叫,如果呼叫失敗,再選另一臺呼叫。 服務消費者和提供者,在記憶體中累計呼叫次數和呼叫時間,定時每分鐘傳送一次統計資料到監控中心。 <5>Dubbo支援的協議

dubbo:Dubbo預設協議是dubbo協議,採用單一長連線和NIO非同步通訊,適合於小資料量大併發的服務呼叫,以及服務消費者機器數遠大於服務提供者機器數的情況。 反之,Dubbo 預設協議不適合傳送大資料量的服務,比如傳檔案,傳視訊等,除非請求量很低。 rmi:RMI協議採用阻塞式(同步)短連線和JDK標準序列化方式。適用範圍:傳入傳出引數資料包大小混合,消費者與提供者個數差不多,可傳檔案。 hessian:Hessian底層採用Http通訊(同步),採用Servlet暴露服務。適用於傳入傳出引數資料包較大,提供者比消費者個數多,提供者壓力較大,可傳檔案。 dubbo還支援的其他協議有:http, webservice, thrift, memcached, redis

<6>如果Dubbo的服務端未啟動,消費端能起來嗎? <dubbo:reference id="" interface="" /> 備註:其中reference的check預設=true,啟動時會檢查引用的服務是否已存在,不存在時報錯,因此預設是起不來

<7>叢集容錯策略 正常情況下,當我們進行系統設計時候,不僅要考慮正常邏輯下程式碼該如何走,還要考慮異常情況下程式碼邏輯應該怎麼走。當服務消費方呼叫服務提供方的服務出現錯誤時候,Dubbo提供了多種容錯方案,預設模式為failover,也就是失敗重試。 Dubbo提供的叢集容錯模式: Failover Cluster:失敗重試 當服務消費方呼叫服務提供者失敗後自動切換到其他服務提供者伺服器進行重試。這通常用於讀操作或者具有冪等的寫操作,需要注意的是重試會帶來更長延遲。可通過 retries="2" 來設定重試次數(不含第一次)。 介面級別配置重試次數方法 <dubbo:reference retries="2" /> ,如上配置當服務消費方呼叫服務失敗後,會再重試兩次,也就是說最多會做三次呼叫,這裡的配置對該介面的所有方法生效。當然你也可以針對某個方法配置重試次數。 Failfast Cluster:快速失敗 當服務消費方呼叫服務提供者失敗後,立即報錯,也就是隻呼叫一次。通常這種模式用於非冪等性的寫操作。 Failsafe Cluster:失敗安全 當服務消費者呼叫服務出現異常時,直接忽略異常。這種模式通常用於寫入審計日誌等操作。 Failback Cluster:失敗自動恢復 當服務消費端用服務出現異常後,在後臺記錄失敗的請求,並按照一定的策略後期再進行重試。這種模式通常用於訊息通知操作。 Forking Cluster:並行呼叫 當消費方呼叫一個介面方法後,Dubbo Client會並行呼叫多個服務提供者的服務,只要一個成功即返回。這種模式通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks="2" 來設定最大並行數。 Broadcast Cluster:廣播呼叫 當消費者呼叫一個介面方法後,Dubbo Client會逐個呼叫所有服務提供者,任意一臺呼叫異常則這次呼叫就標誌失敗。這種模式通常用於通知所有提供者更新快取或日誌等本地資源資訊。 如上,Dubbo本身提供了豐富的叢集容錯模式,但是如果您有定製化需求,可以根據Dubbo提供的擴充套件介面Cluster進行定製。在後面的消費方啟動流程章節會講解何時/如何使用的叢集容錯。

Dubbo面試題:www.cnblogs.com/shan1393/p/…

50,Redis到底是多執行緒還是單執行緒?執行緒安全嗎 redis是單執行緒,執行緒安全 redis可以能夠快速執行的原因: (1) 絕大部分請求是純粹的記憶體操作(非常快速),因此瓶頸在io (2) 採用單執行緒,避免了不必要的上下文切換和競爭條件 (3) 非阻塞IO - IO多路複用 redis內部實現採用epoll,採用了epoll+自己實現的簡單的事件框架。epoll中的讀、寫、關閉、連線都轉化成了事件,然後利用epoll的多路複用特性,絕不在io上浪費一點時間

51,資料庫常見引擎區別

InnoDB(b+樹,聚簇索引):支援事務處理,支援外來鍵,支援崩潰修復能力和併發控制。如果需要對事務的完整性要求比較高(比如銀行),要求實現併發控制(比如售票),那選擇InnoDB有很大的優勢。如果需要頻繁的更新、刪除操作的資料庫,也可以選擇InnoDB,因為支援事務的提交(commit)和回滾(rollback)(用於事務處理應用程式,具有眾多特性,包括ACID事務支援。(提供行級鎖))

MyISAM(b+樹,非聚簇索引):插入資料快,空間和記憶體使用比較低。如果表主要是用於插入新記錄和讀出記錄,那麼選擇MyISAM能實現處理高效率。如果應用的完整性、併發性要求比較低,也可以使用(MyISAM型別不支援事務處理等高階處理,因此也不支援資料的回滾修復)。

MEMORY(hash結構):所有的資料都在記憶體中,資料的處理速度快,但是安全性不高。如果需要很快的讀寫速度,對資料的安全性要求較低,可以選擇MEMOEY。它對錶的大小有要求,不能建立太大的表。所以,這類資料庫只使用在相對較小的資料庫表。

52,mysql資料庫引擎的對應的索引資料結構

53,b樹和b+樹的比較,blog.csdn.net/z_ryan/arti… 1,在範圍查詢方面,B+樹的優勢更加明顯,B樹的範圍查詢需要不斷依賴中序遍歷。首先二分查詢到範圍下限,在不斷通過中序遍歷,知道查詢到範圍的上限即可。整個過程比較耗時,而B+樹的範圍查詢則簡單了許多。首先通過二分查詢,找到範圍下限,然後同過葉子結點的連結串列順序遍歷,直至找到上限即可,整個過程簡單許多,效率也比較高。(b+樹的資料都分佈在子節點上)

54,常見二叉樹 1,二叉查詢樹,它保證所有節點的左子樹都小於該節點,所有節點的右子樹都大於該節點。就可以通過大小比較關係來進行快速的檢索,在一棵滿二叉平衡樹的情況下,檢索的效率可以達到logn(類似二分檢索),然後插入和刪除的效率也是穩定的logn

普通二叉查詢樹的一些問題:二叉搜尋樹是個很好的資料結構,可以快速地找到一個給定關鍵字的資料項,並且可以快速地插入和刪除資料項。但是二叉搜尋樹有個很麻煩的問題,如果樹中插入的是隨機資料,則執行效果很好,但如果插入的是有序或者逆序的資料,那麼二叉搜尋樹的執行速度就變得很慢。因為當插入數值有序時,二叉樹就是非平衡的了,排在一條線上,其實就退化成了一個連結串列……它的快速查詢、插入和刪除指定資料項的能力就喪失了(blog.csdn.net/eson_15/art…

2,AVL樹不僅是一顆二叉查詢樹,它還有其他的性質。如果我們按照一般的二叉查詢樹的插入方式可能會破壞AVL樹的平衡性。同理,在刪除的時候也有可能會破壞樹的平衡性,所以我們要做一些特殊的處理,包括:單旋轉和雙旋轉 參考:www.cnblogs.com/zhuwbox/p/3… 3,紅黑樹:www.cnblogs.com/chenssy/p/3…

紅黑樹的特徵: 1.每個節點不是紅色就是黑色的; 2.根節點總是黑色的; 3.如果節點是紅色的,則它的子節點必須是黑色的(反之不一定); 4.從根節點到葉節點或空子節點的每條路徑,必須包含相同數目的黑色節點(即相同的黑色高度)。

使用場景:一般用於記憶體空間的資料排序,處理的資料量比較小(避免樹的深度變的很深,導致查詢深度變大),大資料排序儘量使用b+樹

4,紅黑樹和AVL樹的比較(www.cnblogs.com/aspirant/p/…

  1. 紅黑樹並不追求“完全平衡”——它只要求部分地達到平衡要求,降低了對旋轉的要求,從而提高了效能。 紅黑樹能夠以O(log2 n) 的時間複雜度進行搜尋、插入、刪除操作。此外,由於它的設計,任何不平衡都會在三次旋轉之內解決。當然,還有一些更好的,但實現起來更復雜的資料結構,能夠做到一步旋轉之內達到平衡,但紅黑樹能夠給我們一個比較“便宜”的解決方案。紅黑樹的演算法時間複雜度和AVL相同,但統計效能比AVL樹更高。 當然,紅黑樹並不適應所有應用樹的領域。如果資料基本上是靜態的,那麼讓他們待在他們能夠插入,並且不影響平衡的地方會具有更好的效能。如果資料完全是靜態的,做一個雜湊表,效能可能會更好一些。 紅黑樹是一個更高效的檢索二叉樹,因此常常用來實現關聯陣列。典型地,JDK 提供的集合類 TreeMap 本身就是一個紅黑樹的實現

55,為什麼Mysql用B+樹做索引而不用B-樹或紅黑樹(blog.csdn.net/xiedelong/a… B+樹只有葉節點存放資料,其餘節點用來索引,而B-樹是每個索引節點都會有Data域。所以從Mysql(Inoodb)的角度來看,B+樹是用來充當索引的,一般來說索引非常大,尤其是關係性資料庫這種資料量大的索引能達到億級別,所以為了減少記憶體的佔用,索引也會被儲存在磁碟上。 那麼Mysql如何衡量查詢效率呢?– 磁碟IO次數。 B-樹/B+樹 的特點就是每層節點數目非常多,層數很少,目的就是為了就少磁碟IO次數,但是B-樹的每個節點都有data域(指標),這無疑增大了節點大小,說白了增加了磁碟IO次數(磁碟IO一次讀出的資料量大小是固定的,單個資料變大,每次讀出的就少,IO次數增多,一次IO多耗時),而B+樹除了葉子節點其它節點並不儲存資料,節點小,磁碟IO次數就少。這是優點之一。 另一個優點是: B+樹所有的Data域在葉子節點,一般來說都會進行一個優化,就是將所有的葉子節點用指標串起來。這樣遍歷葉子節點就能獲得全部資料,這樣就能進行區間訪問啦。在資料庫中基於範圍的查詢是非常頻繁的,而B樹不支援這樣的遍歷操作。

B樹相對於紅黑樹的區別 AVL 數和紅黑樹基本都是儲存在記憶體中才會使用的資料結構。在大規模資料儲存的時候,紅黑樹往往出現由於樹的深度過大而造成磁碟IO讀寫過於頻繁,進而導致效率低下的情況。為什麼會出現這樣的情況,我們知道要獲取磁碟上資料,必須先通過磁碟移動臂移動到資料所在的柱面,然後找到指定盤面,接著旋轉盤面找到資料所在的磁軌,最後對資料進行讀寫。磁碟IO代價主要花費在查詢所需的柱面上,樹的深度過大會造成磁碟IO頻繁讀寫。根據磁碟查詢存取的次數往往由樹的高度所決定,所以,只要我們通過某種較好的樹結構減少樹的結構儘量減少樹的高度,B樹可以有多個子女,從幾十到上千,可以降低樹的高度。

因為B樹是平衡樹,每個節點到葉子節點的高度都是相同的,這樣可以保證B樹的查詢是穩定的

資料庫系統的設計者巧妙利用了磁碟預讀原理,將一個節點的大小設為等於一個頁,這樣每個節點只需要一次I/O就可以完全載入。為了達到這個目的,在實際實現B-Tree還需要使用如下技巧:每次新建節點時,直接申請一個頁的空間,這樣就保證一個節點物理上也儲存在一個頁裡,加之計算機儲存分配都是按頁對齊的,就實現了一個node只需一次I/O。

紅黑樹和平衡二叉樹區別如下: 1、紅黑樹放棄了追求完全平衡,追求大致平衡,在與平衡二叉樹的時間複雜度相差不大的情況下,保證每次插入最多隻需要三次旋轉就能達到平衡,實現起來也更為簡單。 2、平衡二叉樹追求絕對平衡,條件比較苛刻,實現起來比較麻煩,每次插入新節點之後需要旋轉的次數不能預知。 3,紅黑樹的查詢效能略微遜色於AVL樹,因為其比AVL樹會稍微不平衡最多一層,也就是說紅黑樹的查詢效能只比相同內容的AVL樹最多多一次比較,但是,紅黑樹在插入和刪除上優於AVL樹,AVL樹每次插入刪除會進行大量的平衡度計算,而紅黑樹為了維持紅黑性質所做的紅黑變換和旋轉的開銷,相較於AVL樹為了維持平衡的開銷要小得多 4,紅黑樹的關鍵性質: 從根到葉子的最長的可能路徑不多於(<=)最短的可能路徑的兩倍長。結果是這個樹大致上是平衡的。因為操作比如插入、刪除和查詢某個值的最壞情況時間都要求與樹的高度成比例,這個在高度上的理論上限允許紅黑樹在最壞情況下都是高效的,而不同於普通的二叉查詢樹 參考:www.jianshu.com/p/37436ed14…

總結:實際應用中,若搜尋的次數遠遠大於插入和刪除,那麼選擇AVL,如果搜尋,插入刪除次數幾乎差不多,應該選擇RB(red black tree)

紅黑樹往往出現由於樹的深度過大而造成磁碟IO讀寫過於頻繁,進而導致效率低下的情況在資料較小,可以完全放到記憶體中時,紅黑樹的時間複雜度比B樹低。 如linux中程式的排程用的是紅黑樹,反之資料量較大,外存中佔主要部分時,B樹因其讀磁碟次數少,而具有更快的速度。

補充: 1,由於b+樹的子節點(節點結構是陣列,為了二分查詢提交效率)儲存了所有的資料(並且各個子節點的資料是有指標關聯形成的連結串列),因此只需要第一次遞迴查詢就可以確定查詢的起始位置,再遍歷子節點就可以獲取到指定範圍的資料了 2,b+樹和b樹都是多叉樹,因此可以減少因為檔案過大,導致樹的深度越來越深(廣度換深度)。 3,AVL數和紅黑樹基本都是儲存在記憶體中才會使用的資料結構(比如hashMap),整體儲存的資料量少,查詢資料量小,要求的效能更高。

56,hashmap,為什麼用紅黑樹?連結串列(長度大於8)升級為紅黑樹之後,查詢效率更高(二分查詢),那為什麼不用普通二叉查詢樹?紅黑樹本身就是二叉查詢樹,紅黑樹自身保持平衡,避免樹變成了單連結串列,導致深度變大,查詢效能降低。為什麼不用b樹?節點的插入效率沒有紅黑樹高(紅黑樹不需要保持完全平衡,翻轉次數較少,b樹需要保持完全平衡,翻轉次數比較多,導致耗時較長), 為什麼不用b+樹?節點的插入效率沒有紅黑樹高,資料佔用的空間比較大(子節點儲存所有的資料),不利於在記憶體中做排序。 57,跳躍表:被問到如何讓連結串列的元素查詢接近線性時間,其實類似於二叉查詢樹,時間複雜度是log(n)

58,二分查詢(遞迴非遞迴),字串倒序,連結串列倒序,連結串列交叉(減除多餘步長,同時開始遍歷)

59,mysql的聚簇索引和非聚簇索引的區別,聚簇索引(innodb)對應的b+樹的子節點儲存了主鍵索引和其它資料域(輔助索引和非索引資料),非聚簇索引對應的b+樹的子節點儲存了主鍵索引和輔助索引,對應的資料是另外儲存的,非聚簇索引比聚簇索引多了一次讀取資料的IO操作,所以查詢效能上會差(blog.csdn.net/qq_27607965…

60,mysql的mvcc(多版本控制器) 阿里資料庫核心'2017/12'月報中對MVCC的解釋是: 多版本控制: 指的是一種提高併發的技術。最早的資料庫系統,只有讀讀之間可以併發,讀寫,寫讀,寫寫都要阻塞。引入多版本之後,只有寫寫之間相互阻塞,其他三種操作都可以並行,這樣大幅度提高了InnoDB的併發度。在內部實現中,與Postgres在資料行上實現多版本不同,InnoDB是在undolog中實現的,通過undolog可以找回資料的歷史版本。找回的資料歷史版本可以提供給使用者讀(按照隔離級別的定義,有些讀請求只能看到比較老的資料版本),也可以在回滾的時候覆蓋資料頁上的資料。在InnoDB內部中,會記錄一個全域性的活躍讀寫事務陣列,其主要用來判斷事務的可見性。

61,mysql,丟失更新,髒讀,幻讀,不可重複讀,幻讀(www.jianshu.com/p/d8bc0a843…

丟失更新:由於事務A與事務B互相不知道對方的存在,導致更新不一致,解決方案:樂觀鎖的方式,執行修改時,加上先前獲取的資料作為判斷條件。 髒讀:mysql中一個事務讀取了另一個未提交的並行事務寫的資料(可能被回滾),那這個讀取就是髒讀。解決方案:一個事務只能讀取另一個事務已經提交的資料。 不可重複讀:即不能多次重複去讀,因為讀出來的結果不一樣,因此認為存在不可重複讀的問題。解決方案:一個事務只能讀取另一個事務已經提交的資料,這就會出現不可重複讀的問題。 幻讀:事務A一開始查詢沒有資料,但是插入記錄失敗,提示主鍵衝突,這種查詢明明沒有,插入卻提示已經存在的現象,叫做幻讀。解決方案:Repeatable read及以上級別通過間隙鎖來防止幻讀的出現,即鎖定特定資料的前後間隙讓資料無法被插入

小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表

62,mysql的事務隔離級別 事務隔離級別 髒讀 不可重複讀 幻讀 讀未提交(read-uncommitted) 是 是 是 讀已提交(read-committed) 否 是 是 可重複讀(repeatable-read) 否 否 是 序列化(serializable) 否 否 否

serializable級別是最高的 mysql預設的事務隔離級別為repeatable-read

63,mysql的mvcc如何解決幻讀? 參考樂觀鎖,每開啟一個事務,都獲取一個版本號,後續的操作根據版本號去對比,通過版本號控制是否正常操作 InnoDB的MVCC,是通過在每行記錄後面儲存兩個隱藏的列來實現的。這兩個列,一個儲存了行的建立時間,一個儲存行的過期時間(或刪除時間)。當然儲存的並不是實際的時間值,而是系統版本號(systemversionnumber)。每開始一個新的事務,系統版本號都會自動遞增。事務開始時刻的系統版本號會作為事務的版本號,用來和查詢到的每行記錄的版本號進行比較。

舉例: 此時books表中有5條資料,版本號為1 事務A,系統版本號2:select * from books;因為1<=2所以此時會讀取5條資料。 事務B,系統版本號3:insert into books ...,插入一條資料,新插入的資料版本號為3,而其他的資料的版本號仍然是2,插入完成之後commit,事務結束。 事務A,系統版本號2:再次select * from books;只能讀取<=2的資料,事務B新插入的那條資料版本號為3,因此讀不出來,解決了幻讀的問題。

64,mysql四大特性 1.原子性 2.一致性 3.隔離性 4.永續性

65,mysql 七種傳播行為:

1.PROPAGATION_REQUIRED:(支援事務)如果當前沒有事務,就建立一個新事務,如果當前存在事務,就加入該事務,該設定是最常用的設定。 2.PROPAGATION_SUPPORTS:(支援事務)支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。 3.PROPAGATION_MANDATORY:(支援事務)支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就丟擲異常。 4.PROPAGATION_REQUIRES_NEW:(支援事務)建立新事務,無論當前存不存在事務,都建立新事務。 5.PROPAGATION_NOT_SUPPORTED:(不支援事務)以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。 6.PROPAGATION_NEVER:(不支援事務)以非事務方式執行,如果當前存在事務,則丟擲異常。 7.PROPAGATION_NESTED:(不支援事務)如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作

事務傳播特性例子講解:

//ServiveA
@Transactional (propagation = Propagation.REQUIRED )
public void dealA(){
Article a = new Article();
a.setTitlename("1");
this.sql.insert("com.faj.dao.ArticleMapper.insert",a);//插入

serviceB.dealB();//呼叫另一個Service方法  
複製程式碼

}

//ServiceB
@Transactional (propagation = Propagation.REQUIRED )
public void dealB(){
Article a = new Article();
a.setTitlename("3");
this.sqlSession.insert("com.faj.dao.ArticleMapper.insert",a);
throw new ApplicationException();
//ApplicationException是一個繼承RunTimeExcepiotn的異常處理類
}

REQUIRED是重可重入級別的,dealA呼叫了dealB,因為事務的傳播行為是PROPAGATION_REQUIRED(如果有事務,那麼加入事務,沒有的話新建立一個),dealB加入到dealA的事務中,也就是兩個方法共享一個事務,因為是共享事務,所以兩條插入語句都會回滾。 參考:angelbill3.iteye.com/blog/193847…

66,mysql關聯插敘方式 1,內查詢(類似普通的聯合查詢),返回兩個表的交集,例子: select * from a_table a inner join b_table b on a.a_id = b.b_id; 2,左連線(左外連線),left join 是left outer join的簡寫,它的全稱是左外連線,是外連線中的一種。左(外)連線,左表(a_table)的記錄將會全部表示出來,而右表(b_table)只會顯示符合搜尋條件的記錄。右表記錄不足的地方均為NULL。例子:select * from a_table a left join b_table bon a.a_id = b.b_id; 3,右連線(右外連線),right join是right outer join的簡寫,它的全稱是右外連線,是外連線中的一種。與左(外)連線相反,右(外)連線,左表(a_table)只會顯示符合搜尋條件的記錄,而右表(b_table)的記錄將會全部表示出來。左表記錄不足的地方均為NULL。例子:select * from a_table a right outer join b_table b on a.a_id = b.b_id;

67,連線查詢(join on) 為什麼比子查詢(in),聯合查詢(from table1,table2)效率高? 表連線的時候都要先形成一張笛卡爾積表,如果兩張表的資料量都比較大的話,那樣就會佔用很大的記憶體空間這顯然是不合理的。所以,我們在進行表連線查詢的時候一般都會使用JOIN xxx ON xxx的語法,ON語句的執行是在JOIN語句之前的,也就是說兩張表資料行之間進行匹配的時候,會先判斷資料行是否符合ON語句後面的條件,再決定是否JOIN,此時生成的笛卡爾積臨時表比較小。避免使用 FROM table1,table2 WHERE xxx 的語法,因為會在記憶體中先生成一張資料量比較大的笛卡爾積表,增加了記憶體的開銷。in子查詢也是先生成臨時表,再做一次笛卡爾積生成新臨時表,導致效率比較低。

68,mysql索引類別 1.普通索引 2.唯一索引 3.主鍵索引 4.組合索引 5.全文索引(目前只有MyISAM引擎支援,對搜尋引擎稍微有點了解的同學,肯定知道分詞這個概念,FULLTEXT索引也是按照分詞原理建立索引的。西文中,大部分為字母文字,分詞可以很方便的按照空格進行分割。但很明顯,中文不能按照這種方式進行分詞。那又怎麼辦呢?這個向大家介紹一個Mysql的中文分詞外掛Mysqlcft)

69,什麼是覆蓋索引 select的資料列只用從索引中就能夠取得,不必從資料表中讀取,換句話說查詢列要被所使用的索引覆蓋。(通過explain命令可以測試是否被索引命中“返回using index”)

70,為什麼選用自增量作為主鍵索引 mysql的innodb和myisam是mysql最常見的兩種資料庫引擎,底層實現都是使用了b+樹,b+樹的葉子節點都是儲存了有序片段資料,如果順序自增鍵插入子節點更加高效,避免隨機插入頻繁導致節點的裂變。(非單調的主鍵會造成在插入新記錄時資料檔案為了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增欄位作為主鍵則是一個很好的選擇)

71,mysql死鎖的條件及應對措施 原因:兩個事務執行邏輯,各自的內部邏輯相互等待另外一個事務釋放鎖。

例子: 事務1 START TRANSACTION; UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';#(獲取行鎖) UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';#(獲取行鎖) COMMIT;#釋放事務裡面的兩個行鎖 事務2 START TRANSACTION; UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date = '2002-05-02';#(獲取行鎖) UPDATE StockPrice SET close = 41.50 WHERE stock_id = 4 and date = '2002-05-01';#(獲取行鎖) COMMIT;#釋放事務裡面的兩個行鎖

解決辦法: 1,新增超時策略,超時回滾事務,避免鎖被持續競爭 2,以固定的順序訪問你的表和行。則事務形成良好定義的查詢並且沒有死鎖。 參考:blog.csdn.net/wwd0501/art…

72,談談sql查詢優化 1,要利用索引查詢。 2,儘量利用主鍵查詢。 3,連線查詢代(join on)替子查詢(in)和聯合查詢(from t1,t2),避免在記憶體從形成巨大的笛卡爾積。 4,批量掃表時,每次查詢應該使用上次查詢返回的主鍵id作為查詢條件,提高查詢效率。

73,mysql常見的叢集方案(blog.51cto.com/mingongge/2… a,一主多從 將master資料庫中的DDL和DML操作通過二進位制日誌(BINLOG)傳輸到slave資料庫上,然後將這些日誌重新執行(重做);從而使得slave資料庫的資料與master資料庫保持一致。 主從複製基本原理: 從庫生成兩個執行緒,一個I/O執行緒,一個SQL執行緒;i/o執行緒去請求主庫 的binlog,並將得到的binlog日誌寫到relay log(中繼日誌) 檔案中;主庫會生成一個 log dump 執行緒,用來給從庫 i/o執行緒傳binlog;SQL線 程,會讀取relay log檔案中的日誌,並解析成具體操作,來實現主從的操作一致,而最終資料一致。 參考:blog.51cto.com/13266497/21…

mysql主從複製存在的問題: 1,主庫當機後,資料可能丟失 2,從庫只有一個sql Thread,主庫寫壓力大,複製很可能延時

解決方法: 半同步複製---解決資料丟失的問題 非同步複製----解決從庫複製延遲的問題 全同步複製:當主庫提交事務之後,所有的從庫節點必須收到、APPLY並且提交這些事務,然後主庫執行緒才能繼續做後續操作。但缺點是,主庫完成一個事務的時間會被拉長,效能降低。 非同步複製,主庫將事務 Binlog 事件寫入到 Binlog 檔案中,此時主庫只會通知一下 Dump 執行緒傳送這些新的 Binlog,然後主庫就會繼續處理提交操作,而此時不會保證這些 Binlog 傳到任何一個從庫節點上。 半同步複製:一個事務在主伺服器上執行完成後,必須至少確保至少在一臺從伺服器上執行完成後,事務才算提交成功。 主庫寫入一個事務commit提交併執行完之後,並不直接將請求反饋給前端應用使用者,而是等待從庫也接收到binlog日誌併成功寫入中繼日誌後,主庫才返回commit操作成功給客戶端。半同步複製保障了事物執行後,至少有兩份日誌記錄,一份在主庫的binlog上 ,另一份至少在從庫的中繼日誌Relay log上,這樣就極大的保證了資料的一致性

Mysql的master和slave切換,心跳檢測程式檢測到master掛掉,slave之間會檢測binlog的最新操作記錄,確定誰是最新的就成為master,再回寫到配置中心(類似zk的實現lion),並且通知業務方主庫更新。

74,mysql三大正規化(baijiahao.baidu.com/s?id=159195… 第一正規化:所有屬性都不能在分解為更基本的資料單位時,簡記為1NF。滿足第一正規化是關聯式資料庫的最低要求。 第二正規化:每個非主鍵屬性完全依賴於主鍵屬性,資料存在冗餘,或者部分資料無法入表,如:學生表和課程表不應該整合在一塊,課程資訊可能冗餘,也可以插不進去。 第三正規化:資料不傳遞依賴關係(屬性都跟主鍵有直接關係而不是間接關係),資料存在冗餘,如:(學號,姓名,年齡,性別,所在院校,院校地址,院校電話)可拆成(學號,姓名,年齡,性別,所在院校)和(所在院校,院校地址,院校電話)。 75,mysql索引最左原則 針對類似建立的索引是聯合索引(a,b,c),如果查詢使用a,ab,abc,ac都會呼叫索引查詢

76,mysql組合索引的b+樹結構(www.2cto.com/database/20… 聯合索引(col1, col2,col3)也是一棵B+Tree,其非葉子節點儲存的是第一個關鍵字的索引(第一列),而葉節點儲存的則是三個關鍵字col1、col2、col3三個關鍵字的資料,且按照col1、col2、col3的順序進行排序,只有這樣做才符合最左原則的查詢

77,redis有哪些資料結構 string(普通的k-v儲存), hash,常見的物件儲存,如存一個shopDTO list(底層實現是連結串列,儲存重複的資料),場景:好友最新訊息,基於list可以實現佇列或者棧,頭插或者尾插 set(HashMap實現的,Set只用了HashMap的key列來儲存物件,不允許有重複資料),集合有取交集、並集、差集等操作,因此可以求共同好友、共同興趣、分類標籤等。 zset(有序集合,內部使用HashMap和跳躍表(SkipList)來保證資料的儲存和有序),

79,redis常見面試題:blog.csdn.net/u010682330/…

80,Redis叢集最大節點個數是多少? 16384個 81,Redis相比memcached有哪些優勢? memcached所有的值均是簡單的字串,redis作為其替代者,支援更為豐富的資料型別 redis可以持久化其資料 備註:  Memcached是多執行緒,非阻塞IO複用的網路模型,分為監聽主執行緒和worker子執行緒,監聽執行緒監聽網路連線,接受請求後,將連線描述字pipe 傳遞給worker執行緒,進行讀寫IO, 網路層使用libevent封裝的事件庫,多執行緒模型可以發揮多核作用

Redis使用單執行緒的IO複用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,對於單純只有IO操作來說,單執行緒可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單執行緒模型實際會嚴重影響整體吞吐量,CPU計算過程中,整個IO排程都是被阻塞住的 參考:www.2cto.com/database/20…

82,redis何時觸發淘汰資料的動作

一個客戶端執行指令,導致資料的增加時。 Redis檢測到記憶體的使用已經達到上限。 Redis自身執行指令時

補充:Redis為了避免反覆觸發淘汰策略,每次會淘汰掉一批資料。

Redis的記憶體淘汰策略 Redis的記憶體淘汰策略是指在Redis的用於快取的記憶體不足時,怎麼處理需要新寫入且需要申請額外空間的資料。

83,redis記憶體淘汰策略(LRU演算法) allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的key。 allkeys-random:當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個key。 volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的key。 volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,隨機移除某個key。 volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的key優先移除。 noeviction:當記憶體不足以容納新寫入資料時,新寫入操作會報錯。

Redis中同時使用了惰性過期(對cpu友好,對記憶體不友好,長期佔用記憶體才能,使用的時候檢查有效期),定期過期(集中使用cpu),過時立馬刪除(非同步執行緒掃描所有資料),底層是有一個字典結構,在惰性刪除時,會掃描檢查key是否超時。

連結:www.jianshu.com/p/8aa619933…

84,MySQL裡有2000w資料,redis中只存20w的資料,如何保證redis中的資料都是熱點資料? redis記憶體資料集大小上升到一定大小的時候,就會施行資料淘汰策略(計算一下 20W 資料大約佔用的記憶體,然後設定一下 Redis 記憶體限制即可)

85,Redis叢集會有寫操作丟失嗎?為什麼? Redis並不能保證資料的強一致性,這意味這在實際中叢集在特定的條件下可能會丟失寫操作。

86、Redis叢集之間是如何複製的? 非同步複製

87,Reactor模式,參考:www.cnblogs.com/doit8791/p/…

88,Lucene倒排索引原理

倒排索引(hash表) 倒排索引在全文檢索(如單詞檢索)環境中的利器,而mysql的b+樹對於全文檢索非常困難,因此mysql的b+樹索引是基於數值排序(如主鍵索引)。

簡述正排索引和倒排索引 舉例:如有兩個文件,doc1,doc2,裡面有很多單詞,我們查詢單詞”hello“出現的頻次

正排索引實現:doc1->每個單詞->詞頻 檢索過程:先逐個遍歷文件,再找單詞詞頻,如果是海量檔案,查詢效率很慢(需要遍歷所有的檔案)

倒排索引實現:每個單詞->{(doc1,10),(doc2,13),...(文件id,頻次)} 檢索過程:先找單詞,再找文件,再找單詞詞頻,對於海量檔案,查詢效率非常高

備註:正排索引是文件id到單詞,而倒排索引是單詞到文件id

參考:www.cnblogs.com/zlslch/p/64…

88,Lucene倒排索引壓縮演算法

為了減小索引檔案的大小,Lucene對索引還使用了壓縮技術。 首先,對詞典檔案中的關鍵詞進行了壓縮,關鍵詞壓縮為<字首長度,字尾>,例如:當前詞為“阿拉伯語”,上一個詞為“阿拉伯”,那麼“阿拉伯語”壓縮為<3,語>。 其次大量用到的是對數字的壓縮,數字只儲存與上一個值的差值(這樣可以減小數字的長度,進而減少儲存該數字需要的位元組數)。例如當前文章號是16389(不壓縮要用3個位元組儲存),上一文章號是16382,壓縮後儲存7(只用一個位元組)。

www.cnblogs.com/ygj0930/art…

89,Lucene&Solr&ElasticSearch <1>Elasticsearch是一個實時的分散式搜尋和分析引擎。可以快速處理大規模資料。可以用於全文搜尋、結構化搜尋和分析   利用zk實現分散式實時檔案儲存,並將每一個欄位都編入索引,使其可以被搜尋;   實時分析的分散式搜尋引擎;   可以擴充套件到上百臺伺服器,處理PB級別的結構化或非結構化資料

<2>Solr是Apache Lucene專案的開源企業搜尋平臺。主要功能包括全文檢索、命中標示、分面搜尋、動態聚類、資料庫整合,以及富文字的處理。是高度可擴充套件的,並提供了分散式搜尋和索引複製。是最流行的企業級搜尋引擎。是一個獨立的全文搜尋伺服器,solr自帶分散式實現的協調器。

Solr的缺點:建立索引時,搜尋效率下降,實時索引搜尋效率不高(實時建立索引時,Solr會產生io阻塞,查詢效能較差,Elasticsearch具有更明顯的優勢)。 Solr的優點:單純的對已有資料進行搜尋時,Solr更快 Solr 是傳統搜尋應用的有力解決方案,但 Elasticsearch 更適用於新興的實時搜尋應用。 es內對對索引構建採取了多執行緒,效率比solr高很多

參考:blog.csdn.net/Ms_lang/art…

90,solr和es的一些面試題 blog.csdn.net/Ms_lang/art…

91,Elasticsearch叢集部署(整合zk) cluster:代表一個叢集,叢集中有多個節點,其中有一個為主節點,這個主節點是可以通過選舉產生的,主從節點是對於叢集內部來說的。es的一個概念就是去中心化,字面上理解就是無中心節點,這是對於叢集外部來說的,因為從外部來看es叢集,在邏輯上是個整體,你與任何一個節點的通訊和與整個es叢集通訊是等價的。

shards:代表索引分片,es可以把一個完整的索引分成多個分片,這樣的好處是可以把一個大的索引拆分成多個,分佈到不同的節點上。構成分散式搜尋。分片的數量只能在索引建立前指定,並且索引建立後不能更改。

replicas:代表索引副本,es可以設定多個索引的副本,副本的作用一是提高系統的容錯性,當某個節點某個分片損壞或丟失時可以從副本中恢復。二是提高es的查詢效率,es會自動對搜尋請求進行負載均衡。

參考:www.cnblogs.com/aubin/p/801…

92,es叢集調優 www.cnblogs.com/guguli/p/52…

93,如何提高ElasticSearch 索引速度 因為ES裡大量採用執行緒池,構建索引的時候,是有單獨的執行緒池做處理的,加大執行緒池,提高併發處理能力

94,tair原理:

一個Tair叢集主要包括3個必選模組:config server、data server和client,以及一個可選模組:invalid server。

通常情況下,一個叢集中包含2臺config server及多臺data server。兩臺config server互為主備並通過維護和data server之間的心跳獲知叢集中存活可用的data server, 構建資料在叢集中的分佈資訊(對照表)。Data server負責資料的儲存,並按照config server的指示完成資料的複製和遷移工作。 Client在啟動的時候,從config server獲取資料分佈資訊,根據資料分佈資訊和相應的data server互動完成使用者的請求。 Invalid server主要負責對等叢集的刪除和隱藏操作,保證對等叢集的資料一致。

從架構上看,config server的角色類似於傳統應用系統的中心節點,整個叢集服務依賴於config server的正常工作。但實際上相對來說, tair的config server是非常輕量級的,當正在工作的伺服器當機的時候另外一臺會在秒級別時間內自動接管。 而且,如果出現兩臺伺服器同時當機的最惡劣情況,只要應用伺服器沒有新的變化,tair依然服務正常。 而有了config server這個中心節點,帶來的好處就是應用在使用的時候只需要配置config server的地址(現在可以直接配置Diamond key), 而不需要知道內部節點的情況。

ConfigServer的功能 負責管理所有的data server, 維護data server的狀態資訊。 通過維護和dataserver心跳來獲知叢集中存活節點的資訊 根據存活節點的資訊來構建資料在叢集中的分佈表。 提供資料分佈表的查詢服務。 排程dataserver之間的資料遷移、複製。

DataServer的功能 對外提供各種資料服務, 並以心跳的形式將自身狀況彙報給config server。 提供儲存引擎 接受client的put/get/remove等操作 執行資料遷移,複製等 外掛:在接受請求的時候處理一些自定義功能 訪問統計

InvalidServer的功能 接收來自client的invalid/hide等請求後,對屬於同一組的叢集(雙機房獨立叢集部署方式)做delete/hide操作,保證同一組叢集的一致。 叢集斷網之後的,髒資料清理。 訪問統計。

client的功能 在應用端提供訪問Tair叢集的介面。 更新並快取資料分佈表和invalidserver地址等。 LocalCache,避免過熱資料訪問影響tair叢集服務。 流控

參考:blog.csdn.net/sunjin9418/…

tair的特點 <1> Tair有四種引擎:mdb, rdb, kdb和ldb。分別基於四種開源的key/value資料庫:memcached, Redis, Kyoto Cabinet和leveldb。Tair可以讓你更方便地使用這些KV資料庫。 Tair預設包含兩個儲存引擎:mdb和fdb。 <2>Version支援,類似mysql的mvcc機制,支援寫入資料時對版本號控制。 <3>多機架和多資料中心的支援 對照表在構建時,可以配置將資料的備份分散到不同機架或資料中心的節點上。Tair當前通過設定一個IP掩碼來判斷機器所屬的機架和資料中心資訊。 比如你配置備份數為3,叢集的節點分佈在兩個不同的資料中心A和B,則Tair會確保每個機房至少有一份資料。假設A資料中心包含兩份資料時,Tair會盡可能將這兩份資料分佈在不同機架的節點上。這可以減少整個資料中心或某個機架發生故障是資料丟失的風險。 <4>tair實現了一個叢集多中心部署,這是redis 3.0沒有實現的。 <5>DataServer負責資料的物理儲存,並根據configserver構建的對照表完成資料的複製和遷移工作。DataServer具備抽象的儲存引擎層,可以很方便地新增新儲存引擎。DataServer還有一個外掛容器,可以動態地載入/解除安裝外掛

參考:www.jianshu.com/p/ccb17daed…

tair 的負載均衡演算法是什麼 tair 的分佈採用的是一致性雜湊演算法, 對於所有的key,分到Q個桶中, 桶是負載均衡和資料遷移的基本單位。 config server 根據一定的策略把每個桶指派到不同的data server上。 因為資料按照key做hash演算法, 所以可以認為每個桶中的資料基本是平衡的. 保證了桶分佈的均衡性, 就保證了資料分佈的均衡性。

tair擴容 資料遷移時data server對外提供服務的策略,假設data server A要把桶1,2,3遷移到data server B,因為遷移完成前,客戶端的路由表沒有變化,客戶端對1,2,3的訪問請求都會路由到A,現在假設1還沒遷移,2正在遷移,3已經遷移完成,那麼如果訪問1,則還是訪問data server A,如果訪問3,則A會把請求轉發給B,並且將B的返回結果返回給客戶,如果訪問2,則在A上處理,同時如果是對2的修改操作,會記錄修改log,當桶2完成遷移的時候,還有把log傳送給B,在B上應用這些log,最終AB資料一致才是真正完成遷移。如果A是由於當機而引發的遷移,客戶端會收到一張中間臨時狀態的分配表,把當機的data server負責的桶臨時指派給有其備份的data server來處理,此時服務是可用的,負載可能不均衡,當遷移完成後,又能達到一個新的負載均衡狀態

tair的資料備份: config server會發現哪些桶的備份數目減少了, 然後根據負載情況在負載較低的data server上增加這些桶的備份,因此可以理解某個data server的資料是備份在其他的data server 如果是因為某data server當機而引發的遷移,客戶端會收到一張中間臨時狀態的分配表。 這張表中,把當機的data server所負責的桶臨時指派給有其備份data server來處理。這個時候,服務是可用的,但是負載可能不均衡。 當遷移完成之後,才能重新達到一個新的負載均衡的狀態。

參考:blog.csdn.net/death_kada/…

歡迎打賞

網際網路面試知識技術總結(javacore、jvm、redis、kafka、zookeeper、mysql、hystrix)-第四章

相關文章