文章目錄
- 引言
- 正文
- 八股
- MySQL熟悉嗎?講一下MySQL索引的結構?
- 追問:MySQL為什么要使用B+樹?
- 在使用MySQL的時候,如何避免索引失效?
- 講一下MySQL的事物有哪幾種特征?
- MySQL的原子性可以實現什么效果?
- MySQL幾種隔離級別?常用的隔離級別是什么?
- 為什么電商是讀已提交?
- 如果主要采用讀已提交的話,怎么樣防止超賣?庫存有限的時候?秒拍的場景下?單說隔離級別的情況!以買票為例子,比如說一張票!實際業務系統里怎么防止超賣?
- 你對飛書了解嗎?
- 總結
引言
- 這是我面試體驗感最好的一次,騰訊、拼多多、華為都沒有這個好,不僅僅是單方面接受拷打,是會和我討論我的方法有什么不對,然后還會認真聽我的研究方向,然后探討如何改良。之前所有的面試,基本上沒啥人會認真聽我的研究方向,以后我應該還會投字節,能去那里工作真的不錯,很棒!主要是飛書部門!
- 正常面試下來我發現我的八股不行并且算法也不行
- 八股是只會背這一道題,一旦跟我深入討論,我就不能順利答出來了
- 算法是緊張了,沒寫出來,沒有考慮好!
- 今天主要是把八股過一遍,算法已經過過了!
正文
八股
MySQL熟悉嗎?講一下MySQL索引的結構?
我的回答
- 幫助查詢數據的一種數據結構,底層是用B+數保存索引,是否需要展開講一下B+樹的具體內容?
追問:MySQL為什么要使用B+樹?
- 多叉樹,相同節點的情況下,樹的層高更低,磁盤IO次數更少,查詢效率更快
- 葉子節點使用雙項鏈表保存,適用于范圍查找
- 非葉子節點保存索引,葉子節點存儲數據,B數全部都存數據,搜索更快
個人問題
- MySQL會將索引加入到內存中嗎?如果可以加載到內存中的話,就是會更快,如果沒有的話,就沒有意義了。
- MySQL會將索引加載到內存中,從而提高查詢速度。具體來說,MySQL使用一種叫做“緩存”的機制來將索引數據存儲在內存中。這些緩存主要包括:
- InnoDB Buffer Pool:這是InnoDB存儲引擎使用的主要緩存區,用于緩存數據頁和索引頁。通過將索引加載到緩沖池中,MySQL可以更快速地訪問和處理索引,從而加快查詢速度
在使用MySQL的時候,如何避免索引失效?
- 這個題目一下子忘記了,太久沒背了,而且沒有具體使用過索引,底層并不了解,所以這里沒回答出來!或者說在胡扯!
- 不能使用聚合函數的操作?扯淡,這個用不到!
**這里暫時先貼一下GPT的回答,這里每次都掛,今天準備抽時間,把這個索引這個章節從使用到原理都看一遍,再重寫一篇,這里先放在這里,今天寫完了,在貼鏈接! **
講一下MySQL的事物有哪幾種特征?
- 原子性:一個操作要么成功要么失敗,
- 隔離性:
- 持久性:保證事物不會因為執行失敗的斷電
- 一致性:保證一個SQL語句執行前后的結果是一致的
這里說的不夠詳細,或者說不夠具體,很混亂,沒有一開始的那種從容和淡定了!緊張了!
-
原子性:
- 確保事務中的所有操作要么全部完成,要么完全不執行。如果事務中的任何操作失敗,整個事務將回滾,數據庫會回到事務開始前的狀態。
-
一致性(Consistency):
- 一致性保證事務將數據庫從一個一致狀態轉移到另一個一致狀態。在事務開始和結束時,數據庫的完整性約束沒有被破壞。
-
隔離性(isolated)
- 隔離性確保并發事務彼此之間不會互相干擾。每個事務在其執行過程中所做的更改對其他事務是不可見的,直到該事務提交。
-
持久性(Durability):
- 持久性保證一旦事務提交,其結果將永久保存在數據庫中,即使發生系統崩潰也不會丟失
MySQL的原子性可以實現什么效果?
- 網購購買成功,減庫存操作
- 原子性主要是通過undolog保證實現的,事物執行失敗進行回滾,要么執行失敗,要么全部執行。
MySQL幾種隔離級別?常用的隔離級別是什么?
- 電商常用的是讀已提交,MySQL的InoDB默認的隔離級別是可重復讀
- 4種隔離級別,列舉出來了
為什么電商是讀已提交?
- 電商對于并發性的要求比較高,然后可重復讀的會限制并發性,對于數據不一致可以容忍。
- 1、性能考慮
- 減少鎖爭用:在高并發環境下,“讀已提交”隔離級別減少了鎖的持有時間和范圍,避免了長時間的行級鎖定,從而減少了鎖爭用和死鎖的風險。相比于“可重復讀”或“串行化”隔離級別,“讀已提交”對系統性能的影響較小。
- 提高吞吐量:降低鎖的粒度和持有時間有助于提高系統的并發處理能力,從而提高整體吞吐量。這對于高流量的電商平臺至關重要。
-
- 業務需求
- 及時性要求:電商平臺需要及時反饋用戶的操作結果,如訂單創建、庫存查詢等。在“讀已提交”隔離級別下,用戶可以更快地看到最新的已提交數據,滿足了業務的及時性需求。
- 一致性要求相對較低:對于許多電商業務場景,如商品瀏覽和搜索,對數據一致性的要求相對較低,允許一定程度的臟讀。
-
- 事務沖突減少
- 降低事務沖突:在“讀已提交”隔離級別下,讀操作不會阻塞寫操作,寫操作也不會阻塞讀操作,減少了事務之間的沖突,提高了系統的并發處理能力。
-
- 適當的并發控制
- 樂觀鎖和悲觀鎖的結合使用:在需要嚴格控制并發的場景,如庫存扣減和訂單處理,可以結合使用樂觀鎖或悲觀鎖,以確保數據的一致性和正確性。通過這種方式,可以在保持較高性能的同時,防止關鍵業務場景下的數據沖突和不一致
如果主要采用讀已提交的話,怎么樣防止超賣?庫存有限的時候?秒拍的場景下?單說隔離級別的情況!以買票為例子,比如說一張票!實際業務系統里怎么防止超賣?
- 通過redis這種分布式鎖,通過鎖來控制訪問
- 查的時候可以查有票,但是實際購買的時候,使用分布式鎖進行處理。
搜索回答
悲觀鎖
- 讀取庫存的時候,鎖住相應的記錄,防止其他事物同時獲取或者修改記錄,使用select 。。。。for update實現
start transactionselect stock from ticks where ticket_id = 1 for update;
-- 檢查庫存是否足夠
IF stock > 0 THEN-- 執行購買操作UPDATE tickets SET stock = stock - 1 WHERE ticket_id = 1;-- 提交事務COMMIT;
ELSE-- 庫存不足,回滾事務ROLLBACK;
END IF;
樂觀鎖
- 在更新庫存時,通過檢查庫存的版本號或者是時間戳來保證數據的一致性,在更新賬號時發現版本好發生變化,說明其他事物已經更新過了,需要重試
START TRANSACTION;-- 讀取庫存和版本號
SELECT stock, version FROM tickets WHERE ticket_id = 1;-- 檢查庫存是否足夠
IF stock > 0 THEN-- 嘗試更新庫存和版本號UPDATE tickets SET stock = stock - 1, version = version + 1 WHERE ticket_id = 1 AND version = @version;-- 檢查是否有行受影響IF ROW_COUNT() > 0 THEN-- 更新成功,提交事務COMMIT;ELSE-- 更新失敗,回滾事務并重試ROLLBACK;-- 重試邏輯(如重新開始事務)END IF;
ELSE-- 庫存不足,回滾事務ROLLBACK;
END IF;
原子操作
- 使用數據的原子操作,如update中的判斷語句,在高并發的情況下,確保操作的原子性
START TRANSACTION;-- 嘗試更新庫存
UPDATE tickets SET stock = stock - 1 WHERE ticket_id = 1 AND stock > 0;-- 檢查是否有行受影響
IF ROW_COUNT() > 0 THEN-- 更新成功,提交事務COMMIT;
ELSE-- 更新失敗(庫存不足或其他原因),回滾事務ROLLBACK;
END IF;
分布式鎖
- 在分布式系統中,使用分布式鎖,確保同一時間只能有一個實例在操作數據庫。
你對飛書了解嗎?
- 不了解
- 尷尬!
補充
- 企業級協同辦公平臺
- 特點
- 即時消息
- 文檔協作,提供強大的文檔掛你和權限控制功能,支持多人同時編輯和評論
- 任何和項目管理
- 提供任務管理 工具,創建、分配和跟蹤任務管理
- 支持甘特圖等
- 集成應用
- 支持與第三方應用的集成,github和JIRA等
- 提供API和Webhook,方便企業進行自定義開發和集成
總結
- 大概率是進不去了,不過我學到了很多東西,后續會進一步進行改良,今天就加把勁,把MySQL的東西給補上,尤其是索引這一塊。
- 也許這就是不斷面試的作用吧,不斷面試,不斷補全自己的知識網絡,然后不斷提高自己的能力!加油!