題目
- 1、查詢中哪些情況不會使用索引?
- 2、MySQL數據庫索引,底層是怎樣實現的,爲什麼要用B+樹索引?
- 3、Mysql主從同步的實現原理?
- 4、MySQL是怎麼用B+樹?
- 5、談談數據庫樂觀鎖與悲觀鎖?
- 6、有使用過哪些NoSQL數據庫?MongoDB和Redis適用哪些場景?
- 7、描述分佈式事務之TCC服務設計?
- 8、Redis 的數據結構以及優勢
- 9、海量數據過濾,黑名單過濾一個 url
- 10、講一講AtomicInteger,爲什麼要用CAS而不是synchronized?
解答
題目一
- 題幹:查詢中哪些情況不會使用索引?
- 分析:
-
換個思路知道哪些情況下可以用到索引就可以了:
全值匹配
匹配左邊的列
匹配範圍值
精確匹配某一列並範圍匹配另外一列
用於排序
用於分組
此外:我們要知道MySQL底層索引採用B+樹結構,做到了索引即數據,數據即索引,真正的用戶記錄都在最底層的葉子結點中,從根節點到非頁子節點都是目錄頁,聯合索引都是根據索引列的順序依次排序的。 - 回答:
-
找出一些不符合適用情況的,諸如:沒有匹配最左前綴like zhangsan%,對索引列使用函數等。
題目二
- 題幹:MySQL數據庫索引,底層是怎樣實現的,爲什麼要用B+樹索引?
- 分析:
-
考察對於MySQL數據庫的理解,首先MySQL底層的數據庫索引的實現取決於底層所使用的存儲引擎的類型,常見的有MyIsAM和InnoDB,使用最多的是InnoDB,所以我們一般都是討論InnoDB底層索引的實現。InnoDB底層索引的實現是B+樹。
- 回答:
-
底層使用B+樹來實現,如果我們建表的時候不指定主鍵,那麼MySQL會爲我們分配row-id,這個就是默認的聚簇索引,每當我們建立一個B+樹索引的時候,都會先建立一個根節點,如果表中一條數據都沒有,那麼這個根節點也不存儲用戶記錄,當我們插入用戶記錄的時候,該根節點就先存儲用戶記錄,如果用完了,再次插入用戶記錄時,那麼就建立一個新頁,然後將根節點中的所有用戶記錄移動到新頁裏,對於新頁進行頁分裂,然後根節點升級爲目錄頁。
題目三
- 題幹:Mysql主從同步的實現原理?
- 分析:
-
對讀寫分離的考察,首先說一下爲什麼需要讀寫分離,因爲單個MySQL數據庫連接有上限,當連接請求過多的時候可能會導致數據庫崩掉,我們可以通過加緩存使用Redis來緩存部分數據來緩解數據庫壓力,但是我們不能夠將MySQL所有數據都進行緩存,如果當讀寫壓力進一步增大的時候,越過緩存仍然會有很多請求發給MySQL數據庫,根據28原則大部分時讀請求,所以我們使用主從複製【讀寫分離】讓主庫進行寫操作和少部分的讀,從庫進行讀操作,原理就是需要將主庫的binlog同步過來,有兩種方式一種同步複製一種異步複製,同步複製需要等待主庫確認從庫收到消息纔會提交,這個對於性能不是很友好,所以一般使用異步複製,然而異步複製就會存在延遲問題,a、連續多次對同一數據進行變更。第一次變更後的數據還未同步到從庫,第二次變更緊接着就進行。這樣會導致,第二次變更的內容有可能是錯誤的。b、數據變更後,頁面進行列表展示,有可能展示到變更前的數據。c、內部系統調用,內部實時統計有可能讀取到舊數據。解決辦法使用緩存將對主庫更新的數據在緩存中保留一段時間,先都緩存等待從庫同步後在走庫,然後對於主從同步的參數進行一些優化配置。
- 回答:
-
步驟一:主庫db的更新事件(update、insert、delete)被寫到binlog
步驟二:從庫發起連接,連接到主庫
步驟三:此時主庫創建一個binlog dump thread線程,把binlog的內容發送到從庫
步驟四:從庫啓動之後,創建一個I/O線程,讀取主庫傳過來的binlog內容並寫入到relay log.
步驟五:還會創建一個SQL線程,從relay log裏面讀取內容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,將更新內容寫入到slave的db.
題目四
- 題幹:MySQL是怎麼用B+樹?
- 分析:
-
B+樹索引適用條件。
- 回答:
-
全值匹配
匹配左邊的列
匹配範圍值
精確匹配某一列並範圍匹配另外一列
用於排序
用於分組。
題目五
- 題幹:談談數據庫樂觀鎖與悲觀鎖?
- 分析:
-
考察樂觀鎖和悲觀鎖
- 回答:
-
樂觀鎖,顧名思義就是對數據的修改持有樂觀態度,直到修改的時候在去檢查數據是否被修改,一般通過version版本號或者時間戳的方式來實現。
悲觀鎖,就是對數據的修改持有悲觀態度,認爲數據一定會被修改,所以直接加鎖來排序修改,MySQL中實現就是for update。
題目六
- 題幹:有使用過哪些NoSQL數據庫?MongoDB和Redis適用哪些場景?
- 分析:
-
自行解決
- 回答:
-
redis支持更多數據結構,支持數據持久化。MongoDB可以支持一些複雜的查詢,如果是點贊或者熱評收藏之類可以適用redis,如果需要查詢評論內容等等其他的,可以適用MongoDB
題目七
- 題幹:描述分佈式事務之TCC服務設計?
- 分析:
-
https://www.cnblogs.com/jajian/p/10014145.html
- 回答:
-
https://www.cnblogs.com/jajian/p/10014145.html
題目八
- 題幹:Redis 的數據結構以及優勢
- 分析:
-
Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
- 回答:
-
Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
1、redis最典型的應用場景,當做緩存使用,服務在處理請求時先從redis裏獲取結果,獲取到了就可以直接返回,沒有獲取到的話再從數據庫裏獲取,然後存到redis裏以供下次使用。用redis的好處是可以做到分佈式,有狀態的數據都存在redis裏,使業務服務層無狀態,以便業務層有很高的可擴展性
2、Redis也以消息隊列的形式存在,作爲內嵌的List存在,滿足實時的高併發需求。而通常在一個電商類型的數據處理過程之中,有關商品,熱銷,推薦排序的隊列,通常存放在Redis之中,期間也包擴Storm對於Redis列表的讀取和更新。
3、Redis 分佈式鎖。
題目九
- 題幹:海量數據過濾,黑名單過濾一個 url。
- 分析:
-
https://www.jianshu.com/p/2104d11ee0a2
- 回答:
-
使用布隆過濾器進行過濾。
題目十
- 題幹:講一講AtomicInteger,爲什麼要用CAS而不是synchronized?
- 分析:
-
考察原子類,以及原子類底層實現。首先synchronized是一個悲觀的、不公平的、重量級鎖【指會調用操作系統的接口來達到線程安全,保證原子性和可見性】,但是因爲重量級性能有一定劣勢,我們可以減少使用重量級鎖,通過偏向鎖升級爲輕量級鎖在升級爲重量級鎖,單向升級不可逆。原子類底層主要是使用Unsafe類和CAS底層使用volatile 修飾 value 保證可見性,然後使用CAS保證原子性最終能夠做到了線程安全,但是在高併發場景下,同時更新一個原子變量的多個線程,最終只有一個線程的CAS操作會成功,這樣就有有很多線程的CAS操作失敗,大量的自旋操作,浪費了CPU的資源。所以後來又引入了LongAddr類。
- 回答:
-
原子類需要保證內存可見性和原子性,底層對於value屬性使用了volatile關鍵字修飾,保證了可見性,然後使用Unsafe中提供的CAS操作來避免使用synchronized關鍵字,從而保證原子性。提升了性能。