每天十道面試題-20200325

題目

  • 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關鍵字,從而保證原子性。提升了性能。

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