互聯網公司面試必問的mysql題目(上)


互聯網公司面試必問的mysql題目(上)


介紹:MySQL是一個關係型數據庫管理系統,目前屬於 Oracle 旗下產品。雖然單機性能比不上oracle,但免費開源,單機成本低且藉助於分佈式集群所以受到互聯網公司的青睞,是互聯網公司的主流數據庫。

01

什麼是數據庫事務?如果沒有事物會有什麼後果?事務的特性是什麼?

事務是指作為單個邏輯工作單元執行的一系列操作,可以被看作一個單元的一系列SQL語句的集合。要麼完全地執行,要麼完全地不執行。

如果不對數據庫進行併發控制,可能會產生 髒讀、非重複讀、幻像讀、丟失修改的異常情況。

事務的特性(ACID)

A, atomacity 原子性 事務必須是原子工作單元;對於其數據修改,要麼全都執行,要麼全都不執行。通常,與某個事務關聯的操作具有共同的目標,並且是相互依賴的。如果系統只執行這些操作的一個子集,則可能會破壞事務的總體目標。原子性消除了系統處理操作子集的可能性。

C, consistency 一致性

事務將數據庫從一種一致狀態轉變為下一種一致狀態。也就是說,事務在完成時,必須使所有的數據都保持一致狀態(各種 constraint 不被破壞)。

I, isolation 隔離性 由併發事務所作的修改必須與任何其它併發事務所作的修改隔離。事務查看數據時數據所處的狀態,要麼是另一併發事務修改它之前的狀態,要麼是另一事務修改它之後的狀態,事務不會查看中間狀態的數據。換句話說,一個事務的影響在該事務提交前對其他事務都不可見。

D, durability 持久性

事務完成之後,它對於系統的影響是永久性的。該修改即使出現致命的系統故障也將一直保持。


互聯網公司面試必問的mysql題目(上)


“A向B匯錢100”

  1. 讀出A賬號餘額(500)。
  2. A賬號扣錢操作(500-100)。
  3. 結果寫回A賬號(400)。
  4. 讀出B賬號餘額(500)。
  5. B賬號做加法操作(500+100)。
  6. 結果寫回B賬號(600)。

原子性:

保證1-6所有過程要麼都執行,要麼都不執行。如果異常了那麼回滾。

一致性

轉賬前,A和B的賬戶中共有500+500=1000元錢。轉賬後,A和B的賬戶中共有400+600=1000元。

隔離性

在A向B轉賬的整個過程中,只要事務還沒有提交(commit),查詢A賬戶和B賬戶的時候,兩個賬戶裡面的錢的數量都不會有變化。

持久性

一旦轉賬成功(事務提交),兩個賬戶的裡面的錢就會真的發生變化

02

什麼是髒讀?幻讀?不可重複讀?什麼是事務的隔離級別?Mysql的默認隔離級別是?

  • 髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據
  • 不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果 不一致。
  • 幻讀:系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。

Read uncommitted

讀未提交,顧名思義,就是一個事務可以讀取另一個未提交事務的數據。

Read committed

讀提交,顧名思義,就是一個事務要等另一個事務提交後才能讀取數據。


互聯網公司面試必問的mysql題目(上)


小A去買東西(卡里有1萬元),當他買單時(事務開啟),系統事先檢測到他的卡里有1萬,就在這個時候!!小A的妻子要把錢全部轉出充當家用,並提交。當系統準備扣款時,再檢測卡里的金額,發現已經沒錢了(第二次檢測金額當然要等待妻子轉出金額事務提交完)。A就會很鬱悶

分析:這就是讀提交,若有事務對數據進行更新(UPDATE)操作時,讀操作事務要等待這個更新操作事務提交後才能讀取數據,可以解決髒讀問題。但在這個事例中,出現了一個事務範圍內兩個相同的查詢卻返回了不同數據,這就是不可重複讀。

Repeatable read

重複讀,就是在開始讀取數據(事務開啟)時,不再允許修改操作

事例:小A去買東西(卡里有1萬元),當他買單時(事務開啟,不允許其他事務的UPDATE修改操作),收費系統事先檢測到他的卡里有1萬。這時候他的妻子不能轉出金額了。接下來收費系統就可以扣款了。

分析:重複讀可以解決不可重複讀問題。寫到這裡,應該明白的一點就是,不可重複讀對應的是修改,即UPDATE操作。但是可能還會有幻讀問題。因為幻讀問題對應的是插入INSERT操作,而不是UPDATE操作。

什麼時候會出現幻讀?

事例:小A去買東西,花了2千元,然後他的妻子去查看他的消費記錄(全表掃描FTS,妻事務開啟),看到確實是花了2千元,就在這個時候,小A花了1萬買了一部電腦,INSERT了一條消費記錄,並提交。當妻子打印小A的消費記錄清單時(妻子事務提交),發現花了1.2萬元,似乎出現了幻覺,這就是幻讀。

Serializable 序列化

Serializable 是最高的事務隔離級別,在該級別下,事務串行化順序執行,可以避免髒讀、不可重複讀與幻讀。但是這種事務隔離級別效率低下,比較耗數據庫性能,一般不使用。

Mysql的默認隔離級別是Repeatable read。

03

事物隔離是怎麼實現的?

是基於鎖實現的.

有哪些鎖?分別介紹下

在DBMS中,可以按照鎖的粒度把數據庫鎖分為行級鎖(INNODB引擎)、表級鎖(MYISAM引擎)和頁級鎖(BDB引擎 )。

行級鎖

行級鎖是Mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少數據庫操作的衝突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖 和 排他鎖。

特點

開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。

表級鎖

表級鎖是MySQL中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖,它實現簡單,資源消耗較少,被大部分MySQL引擎支持。最常使用的MYISAM與INNODB都支持表級鎖定。表級鎖定分為表共享讀鎖(共享鎖)與表獨佔寫鎖(排他鎖)。

特點

開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發出鎖衝突的概率最高,併發度最低。

頁級鎖

頁級鎖是MySQL中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。

特點

開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般

04

什麼是死鎖?怎麼解決?(前幾問題是我個人最喜歡的連環炮,基本可以看出面試者的基礎功)

死鎖是指兩個或多個事務在同一資源上相互佔用,並請求鎖定對付的資源,從而導致惡性循環的現象。

常見的解決死鎖的方法

1、如果不同程序會併發存取多個表,儘量約定以相同的順序訪問表,可以大大降低死鎖機會。

2、在同一個事務中,儘可能做到一次鎖定所需要的所有資源,減少死鎖產生概率;

3、對於非常容易產生死鎖的業務部分,可以嘗試使用升級鎖定顆粒度,通過表級鎖定來減少死鎖產生的概率;

如果業務處理不好可以用分佈式事務鎖或者使用樂觀鎖

05

SQL的生命週期?關鍵字的先後順序?

  1. 應用服務器與數據庫服務器建立一個連接
  2. 數據庫進程拿到請求sql
  3. 解析並生成執行計劃,執行
  4. 讀取數據到內存並進行邏輯處理
  5. 通過步驟一的連接,發送結果到客戶端
  6. 關掉連接,釋放資源


互聯網公司面試必問的mysql題目(上)


1、 FROM:對 FROM 子句中的前兩個表執行笛卡爾積(交叉聯接),生成虛擬表 VT1。

2、 ON:對 VT1 應用 ON 篩選器,只有那些使為真才被插入到 TV2。

3、 OUTER (JOIN):如果指定了 OUTER JOIN(相對於 CROSS JOIN 或 INNER JOIN),保留表中未找到

匹配的行將作為外部行添加到 VT2,生成 TV3。如果 FROM 子句包含兩個以上的表,則對上一個聯接生成的

結果表和下一個表重複執行步驟 1 到步驟 3,直到處理完所有的表位置。

4、 WHERE:對 TV3 應用 WHERE 篩選器,只有使為 true 的行才插入 TV4。

5、 GROUP BY:按 GROUP BY 子句中的列列表對 TV4 中的行進行分組,生成 TV5。

6、 CUTE|ROLLUP:把超組插入 VT5,生成 VT6。

7、 HAVING:對 VT6 應用 HAVING 篩選器,只有使為 true 的組插入到 VT7。

8、 SELECT:處理 SELECT 列表,產生 VT8。

9、 DISTINCT:將重複的行從 VT8 中刪除,產品 VT9。

10、 ORDER BY:將 VT9 中的行按 ORDER BY 子句中的列列表順序,生成一個遊標(VC10)。

11、 TOP:從 VC10 的開始處選擇指定數量或比例的行,生成表 TV11,並返回給調用者。

06

什麼是樂觀鎖?悲觀鎖?實現方式?

悲觀鎖

悲觀鎖指對數據被意外修改持保守態度,依賴數據庫原生支持的鎖機制來保證當前事務處理的安全性,防止其他併發事務對目標數據的破壞或破壞其他併發事務數據,將在事務開始執行前或執行中申請鎖定,執行完後再釋放鎖定。這對於長事務來講,可能會嚴重影響系統的併發處理能力。 自帶的數據庫事務就是典型的悲觀鎖。

樂觀鎖:

樂觀鎖(Optimistic Lock),顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個數據。樂觀鎖適用於讀多寫少的應用場景,這樣可以提高吞吐量。

一般是加一個版本號字段 每次更新時候比較版本號

07

大數據情況下如何做分頁?

可以參考阿里巴巴java開發手冊上的答案


互聯網公司面試必問的mysql題目(上)


08

什麼是數據庫連接池?

從上一個sql生命週期題目,可以看到其中的連接在裡面發揮著重大作用,但頻繁的創建和銷燬,非常浪費系統資源。由於數據庫更適合長連接,也就有個連接池,能對連接複用,維護連接對象、分配、管理、釋放,也可以避免創建大量的連接對DB引發的各種問題;另外通過請求排隊,也緩解對DB的衝擊。

原文地址:https://mp.weixin.qq.com/s/XL_l-6LvE0TVAlgRBRzVkw


分享到:


相關文章: