如何準備數據庫方面的面試問題

作爲面試官,我會按如下層次考覈求職者數據庫方面的技能。

1 問基本的操作技能,這裏當然不會直接問sql語法,而會挑些點來問,比如左連接怎麼做,with語句或merge語句的含義和用法。

2 問些高級技能,其中包括事務等,比如問事務隔離級別和傳播機制。也包括索引,比如索引的底層,索引的數據結構和索引的種類。

以上都是比較基礎的,如果是初級開發的話,能說好上面的問題就好了,如果是要面試3年及以上的高級開發,還會問如下的調優技能和分佈式組件技能。

3 調優技能一般會問,在你們的項目裏,一般是怎麼發現慢sql,發現慢sql以後會用什麼方式來排查和解決?或者問,你們設計數據庫表和數據庫索引的時候,一般是怎麼考慮的?或者就問個開放性的問題,你們是怎麼排查和解決數據庫性能問題的?

4 數據庫方面的組件一般包括redis緩存組件和mycat分庫組件,一般會問,你們項目裏有沒有用過?結合一個例子告訴我怎麼用?如果是面高級或資深開發時,還會深入問些,比如用到的redis是集羣還是單機版?怎麼做redis持久化?redis的緩存穿透問題有沒有遇到過?Mycat怎麼實現分庫的?mycat組件上線後是怎麼做數據遷移的?

在對應準備數據庫方面的面試時,題好背,如果不知道怎麼背題,多看看網文多參加幾次面試就行,但數據庫調優方面的問題,是無法迴避的,比如面試官就一句,你們項目是怎麼分析和排查數據庫性能問題的?

在系統寫調優方面的回答模版前,先說下如下回答的價值,如果初級開發(工作經驗少於3年)能說好,能超越大多數的競爭者,而哪怕高級開發說好這些話,也能讓面試官感覺你很資深,而對於架構師而言,這些回答是基本的標配項。下面具體說下數據庫調優方面該怎麼說?

1 總是先要發現待調優的sql語句,這塊可以通過new relic,或zabbix或cat組件來發現,比如通過配置把這些組件連接到對應的數據庫服務器上,如果出現超過閾值的慢sql,或發郵件告警。如果再不濟,可以直接說,把mysql數據庫配置到linux服務器上,運維人員做來配置,所以一旦出現運行時間超過10秒(或其他配置值)的sql語句,我會收到告警郵件。

這塊一定要說,否則連哪些sql要優化也不知道,怎麼做優化?事實上如果這塊好好準備,還能說好系統監控組件這一塊。

2 發現慢sql以後,首先用執行計劃(sql explain)去分析下該sql語句耗時主要耗在哪塊?一般耗時長的點會有,沒建索引或沒走索引,大表關聯導致耗時長,或長sql語句裏,同一個sql塊被之行多次。當然還有其他可能會費時間的點,但上述點經常會遇到,也好準備。

通過執行計劃分析到慢sql的原因後,就可以針對性地說解決方案。可以是建索引,但這裏要注意,被建索引的表規模至少十萬級,而被建索引的字段應當重複率低,否則索引建了白建,這些原因自己查,但我在面試求職者時,真聽說過爲幾千條表規模建索引,以及爲性別字段建索引的說辭。

調優要點還可以是在建表層面,比如預估一個業務點(比如商品業務)數據表規模很大,到至少十萬級,那麼就別再按三範式建表,因爲三範式雖然不會有冗餘數據,但表關聯起來喫不消,遇到這種情況,可以把商品的所有字段放到一個大表,也就是用反範式來建表。但如果求職者是表設計好以後入項目組的,就別說這種話了。

調優要點還包括,用with語句把長sql裏運行多次的sql塊提出來,或者乾脆重寫sql。當然還有些說辭,比如更改mysql裏關於鎖的配置,或者跳低oracle的水平位,但這種話別說,因爲做項目時不大可能全局性地修改mysql或oracle的配置,這樣風險太大。

3 以上是單機版的調優手段,說好這塊還可以說redis緩存調優,這塊該怎麼說呢?先準備個業務點,比如發訂單,在這過程中會多次訪問用戶表,此時第一次訪問時,就可以把數據放入緩存,然後準備下放入緩存用戶數據的結構(無非是list或hash型),然後準備下java訪問redis的api,應該是用Jedis或RedisTemplate。

在此基礎上,可以說下解決過redis的緩存穿透問題,無非是緩存空數據或不存在的數據,同時可以說下,爲了避免緩存的數據一直存在於內存,所以需要設置緩存數據的超時時間。

如果是初級開發,說到這個程度就可以了,而且還可以說是用到單機版的redis,如果是高級開發,還可以說下用了redis集羣,但用的時候基本上是主從集羣,向主節點寫,主節點向從節點同步數據,從從節點讀緩存。但別說用哨兵集羣,因爲現在不怎麼用了,如果要說用cluster集羣也行,但cluster集羣單點失效方面的問題很難回答,這要自擔風險,其實如果感覺不怎忙好準備,說個主從redis集羣也行。

4 如果再想往深了說,可以說引入了mycat分庫分表組件。這塊基本的該怎麼說呢?有張千萬級別(至少百萬級別)的大表,比如訂單流水錶,通過配置mycat參數,按id取模的方式,把它們分散到5個表結構一樣的字表裏,比如id%5是1分到1號子表,依次類推。

用了mycat前,需要排查針對該表的所有sql語句,即所有sql語句都要包含分庫字段,比如id,而且不能有針對全表的操作,比如group by等,如果遇到全表操作,需要改寫,或用java業務實現。

說到這種程度,就能從發現到排查的流程角度,全面地展示自己數據庫調優方面的技能。而且不僅能展示單機版的調優技能,還能展示分佈式組件級別的調優技能。這套話說下來,哪怕去面需要5年工作經驗的高級開發,至少在數據庫層面能及格,更何況去面只要3年以內的初級開發崗。

 

如果大家想進一步瞭解我的情況,可以關注我。

 

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