網際網路公司面試必問的mysql題目(上)

codeyuyu發表於2018-09-26

圖片描述
又到了招聘的旺季,被要求準備些社招、校招的題庫。

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

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

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

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

事務的特性(ACID)

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

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

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

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

圖片描述
01

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

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

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

事務的特性(ACID)

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

C, consistency 一致性

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

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

D, durability 永續性

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

圖片描述

“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賬戶的時候,兩個賬戶裡面的錢的數量都不會有變化。

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

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

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

Read uncommitted 讀未提交,顧名思義,就是一個事務可以讀取另一個未提交事務的資料。 Read committed 讀提交,顧名思義,就是一個事務要等另一個事務提交後才能讀取資料。

小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。

事物隔離是怎麼實現的?

是基於鎖實現的.

有哪些鎖?分別介紹下

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

行級鎖 行級鎖是Mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少資料庫操作的衝突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖 和 排他鎖。
特點:
開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。

表級鎖 表級鎖是MySQL中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖,它實現簡單,資源消耗較少,被大部分MySQL引擎支援。最常使用的MYISAM與INNODB都支援表級鎖定。表級鎖定分為表共享讀鎖(共享鎖)與表獨佔寫鎖(排他鎖)。
特點:
開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發出鎖衝突的概率最高,併發度最低。

頁級鎖 頁級鎖是MySQL中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。
特點:
開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般

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

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

常見的解決死鎖的方法

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

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

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

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

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

  1. 應用伺服器與資料庫伺服器建立一個連線
  2. 資料庫程式拿到請求sql
  3. 解析並生成執行計劃,執行
  4. 讀取資料到記憶體並進行邏輯處理
  5. 通過步驟一的連線,傳送結果到客戶端
  6. 關掉連線,釋放資源
    圖片描述

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,並返回給呼叫者。

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

悲觀鎖: 悲觀鎖指對資料被意外修改持保守態度,依賴資料庫原生支援的鎖機制來保證當前事務處理的安全性,防止其他併發事務對目標資料的破壞或破壞其他併發事務資料,將在事務開始執行前或執行中申請鎖定,執行完後再釋放鎖定。這對於長事務來講,可能會嚴重影響系統的併發處理能力。 自帶的資料庫事務就是典型的悲觀鎖。
樂觀鎖: 樂觀鎖(Optimistic Lock),顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個資料。樂觀鎖適用於讀多寫少的應用場景,這樣可以提高吞吐量。
一般是加一個版本號欄位 每次更新時候比較版本號。

大資料情況下如何做分頁?

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

圖片描述

什麼是資料庫連線池?

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

推薦閱讀

網際網路公司面試必問的Redis題目

網際網路公司面試必問的mysql題目(下)

最近,我組建了個群聊。學習Java進階技術乾貨、實踐分享,職位內推,一起聊聊理想。志同道合的朋友,歡迎你的加入。

網際網路公司面試必問的mysql題目(上)
最後,祝大家面試順利!歡迎長按關注~不定期送書

網際網路公司面試必問的mysql題目(上)

相關文章