面經總結:數據庫


  • 事務的四個特性?

四大特性是:ACID 原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)+介紹四個特性概念;

原子性:整個事務中的所有操作,要么全部完成,要么全部不完成,不可能停滯在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。

一致性:在事務開始之前和事務結束以后,數據庫的完整性約束沒有被破壞

隔離性:當兩個或者多個事務並發訪問(此處訪問指查詢和修改的操作)數據庫的同一數據時所表現出的互相關系。事務隔離分為不同的級別,包括讀未提交(Read uncommitted)、讀提交(Read committed)、可重復讀(Repeatable read)和串行化(Serializable)。隔離狀態執行事務,使它們好像是系統在給定時間內執行的唯一操作。如果有兩個事務,運行在相同的時間內,執行 相同的功能,事務的隔離性將確保每一事務在系統中認為只有該事務在使用系統。這種屬性有時稱為串行化,為了防止事務操作間的混淆,必須串行化或序列化請求,使得在同一時間僅有一個請求用於同一數據。

持久性:在事務完成以后,該事務對數據庫所作的更改便持久的保存在數據庫之中,並不會被回滾。

 

  • 事務的隔離級別

讀未提交(Read uncommitted)、讀已提交(Read committed)、可重復讀(Repeatable read)和串行化(Serializable)

  ① Serializable (串行化):可避免臟讀、不可重復讀、幻讀的發生。

  SERIALIZABLE可以防止除更新丟失外所有的一致性問題,即:

    1.語句無法讀取其它事務已修改但未提交的記錄。

    2.在當前事務完成之前,其它事務不能修改目前事務已讀取的記錄。

    3.在當前事務完成之前,其它事務所插入的新記錄,其索引鍵值不能在當前事務的任何語句所讀取的索引鍵范圍中。

  ② Repeatable read (可重復讀):可避免臟讀、不可重復讀的發生。

  REPEATABLE READ事務不會產生臟讀,並且在事務完成之前,任何其它事務都不能修改目前事務已讀取的記錄。其它事務仍可以插入新記錄,但必須符合當前事務的搜索條件——這意味着當前事務重新查詢記錄時,會產生幻讀(Phantom Read)。

  ③ Read committed (讀已提交):可避免臟讀的發生。

    語句無法讀取其它事務已修改但未提交的記錄

  ④ Read uncommitted (讀未提交):最低級別,任何情況都無法保證。

 

  • 四大沖突問題

1、臟讀

某個事務讀取的數據是另一個事務正在處理的數據。而另一個事務可能會回滾,造成第一個事務讀取的數據是錯誤的。

2、不可重復讀

在一個事務里兩次讀入數據,但另一個事務已經更改了第一個事務涉及到的數據,造成第一個事務讀入舊數據。

3、幻讀

幻讀是指當事務不是獨立執行時發生的一種現象。例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。

4、更新丟失

多個事務同時讀取某一數據,一個事務成功處理好了數據,被另一個事務寫回原值,造成第一個事務更新丟失。

 

  • 樂觀鎖和悲觀鎖?使用場景?

樂觀鎖:默認讀數據的時候不會修改,所以不會上鎖;

悲觀鎖:默認讀數據的時候會修改,所以會上鎖;

樂觀鎖適用於多讀寫比較少的情況,省去鎖的開銷,加大系統的吞吐量。

 

  • MySQL引擎的區別?

mysql兩種存儲引擎:InnoDB和MyISAM
區別:(1.事務;2.鎖;3.效率;4.查詢/插入更新)

1).MyISAM是非事務安全型的,而InnoDB是事務安全型的。

2).MyISAM鎖的粒度是表級,而InnoDB支持行級鎖定。

3).MyISAM相對簡單,所以在效率上要優於InnoDB,小型應用可以考慮使用MyISAM。

4).MyISAM管理非事務表。它提供高速存儲和檢索,以及全文搜索能力。如果應用中需要執行大量的SELECT查詢,那么MyISAM是更好的選擇。

5).InnoDB用於事務處理應用程序,具有眾多特性,包括ACID事務支持。如果應用中需要執行大量的INSERT或UPDATE操作,則應該使用InnoDB,這樣可以提高多用戶並發操作的性能。由於鎖的粒度更小,寫操作不會鎖定全表,所以在並發較高時,使用Innodb引擎會提升效率。

 

  • 數據庫索引有哪些類型?

普通索引、唯一索引、主鍵索引、組合索引;

普通索引:沒有任何限制;

唯一索引:索引列的值必須唯一,但允許有空值;

主鍵索引:特殊的唯一索引,不允許有空值;一個表只能有一個主鍵;

組合索引:多個字段組合作為索引;

 

  • 數據庫索引原理?

索引:數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現通常使用B樹及其變種B+樹

在數據之外,數據庫系統還維護着滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

 

  • B樹和B+樹原理?

為什么使用B樹?
二叉查找樹結構由於樹的深度過大而造成磁盤I/O讀寫過於頻繁,進而導致查詢效率低下。采用多叉樹結構減少樹的深度,從而達到有效避免磁盤過於頻繁的查找存取操作,從而有效提高查找效率。

動態查找樹主要有:二叉查找樹(Binary Search Tree),平衡二叉查找樹(Balanced Binary Search Tree),紅黑樹(Red-Black Tree ),B-tree/B+-tree/ B*-tree (B~Tree)。前三者是典型的二叉查找樹結構,其查找的時間復雜度O(log2N)與樹的深度相關,那么降低樹的深度自然會提高查找效率。

但是咱們有面對這樣一個實際問題:就是大規模數據存儲中,實現索引查詢這樣一個實際背景下,樹節點存儲的元素數量是有限的(如果元素數量非常多的話,查找就退化成節點內部的線性查找了),這樣導致二叉查找樹結構由於樹的深度過大而造成磁盤I/O讀寫過於頻繁,進而導致查詢效率低下(為什么會出現這種情況,待會在外部存儲器-磁盤中有所解釋),那么如何減少樹的深度(當然是不能減少查詢的數據量),一個基本的想法就是:采用多叉樹結構(由於樹節點元素數量是有限的,自然該節點的子樹數量也就是有限的)。

也就是說,因為磁盤的操作費時費資源,如果過於頻繁的多次查找勢必效率低下。那么如何提高效率,即如何避免磁盤過於頻繁的多次查找呢?根據磁盤查找存取的次數往往由樹的高度所決定,所以,只要我們通過某種較好的樹結構減少樹的結構盡量減少樹的高度,那么是不是便能有效減少磁盤查找存取的次數呢?那這種有效的樹結構是一種怎樣的樹呢?

這樣我們就提出了一個新的查找樹結構——多路查找樹。根據平衡二叉樹的啟發,自然就想到平衡多路查找樹結構,也就是這篇文章所要闡述的第一個主題B~tree即B樹結構(后面,我們將看到,B樹的各種操作能使B樹保持較低的高度,從而達到有效避免磁盤過於頻繁的查找存取操作,從而有效提高查找效率)。

 
 
什么是B樹?
(把B樹和B+樹的兩張圖多熟悉一點)
B樹是多路搜索樹;對於M階的B樹,它的特點是:
  1)每個節點存放M/2-1(上取整)到M-1個關鍵字;
  2) 根節點的兒子數是[2,M],除根節點外非葉子節點的兒子數是[M/2,M];
B樹的搜索:從根結點開始,對結點內的關鍵字(有序)序列進行二分查找,如果命中則結束,否則進入查詢關鍵字所屬范圍的兒子結點;重復,直到所對應的兒子指針為空,或已經是葉子結點。

B樹的特性:關鍵字分布在整棵樹中;搜索性能等價於在關鍵字全集內做一次二分查找;

 

什么是B+樹?

B+樹是B樹的變體,也是多路搜索樹;B+樹的特點是:

  1)非葉子結點的子樹指針P[i],指向關鍵字值屬於[K[i], K[i+1])的子樹(B-樹是開區間)

      2)所有關鍵字都在葉子結點出現;

  3)所有的非葉子節點相當於是葉子節點的索引;

  4)為所有葉子結點增加一個鏈指針;

B+的搜索與B樹也基本相同,區別是B+樹只有達到葉子結點才命中(B-樹可以在非葉子結點命中),其性能也等價於在關鍵字全集做一次二分查找;

B+樹和B+樹的區別:

       1.所有關鍵字都出現在葉子結點的鏈表中(稠密索引),且鏈表中的關鍵字恰好是有序的;

       2.只會在葉子結點命中;

       3.非葉子結點相當於是葉子結點的索引(稀疏索引),葉子結點相當於是存儲(關鍵字)數據的數據層;

B+樹相比B樹的優點: 

(1) B+樹改進了B樹, 讓內結點只作索引使用, 去掉了其中指向data的指針, 使得每個結點中能夠存放更多的key, 這樣訪問葉節點的數據的磁盤讀寫次數就更低;

(2) 由於底部的葉子結點是鏈表形式, 因此也可以實現更方便的順序遍歷, 而B樹則需要對整個樹的每一層遍歷,需要更多的磁盤讀寫;

參考:stackoverflow-B樹和B+樹

  

參考:索引、樹 

 

 

  • 為什么用數據庫連接池?

1)資源重用。連接池里的連接可以重復使用,避免了頻繁創建、釋放連接引起的大量性能開銷
2)更快的系統響應速度 。數據庫連接池在初始化過程中,往往已經創建了若干數據庫連接置於池中備用。此時連接的初始化工作均已完成。對於業務請求處理而言,直接利用現有可用連接,避免了數據庫連接初始化和釋放過程的時間開銷,從而縮減了系統整體響應時間。
 
  • 數據庫連接池配置/驅動參數?如何防止失效?

數據庫連接池?
c3p0, druid;DBCP;
DBCP配置參數:
driverClassName:連接數據庫所用的 JDBC Driver Class, 
password: 登陸數據庫所用的密碼 
url: 連接數據庫的 URL 
username: 登陸數據庫所用的帳號 
 
初始化連接數量initialSize:連接池啟動時創建的初始化連接數量;
最大連接數maxActive:如果超過maxActive,后面的連接請求加入到等待隊列中;
最大空閑連接數maxIdle:連接池中允許保持空閑狀態的最大連接數量,超過的空閑連接將被釋放;
最小空閑連接數minIdle:連接池允許空閑的最小連接數量,小於則創建新的連接;
最大等待時間maxWait;當沒有可用連接時,連接池等待連接被歸還的最大時間,超過時間則拋出異常。
 
數據庫連接池如何防止失效?
(設置參數,操作對象/空閑的時候進行驗證)
testOnBorrow:取得對象時是否進行驗證,檢查對象是否有效,默認為false  
testOnReturn:返回對象時是否進行驗證,檢查對象是否有效,默認為false 
testWhileIdle:空閑時是否進行驗證,檢查對象是否有效,默認為false 
testOnReturn,testOnBorrow這兩個參數為true,表示會在每次請求之前和之后進行連接池測試,如果連接失效,就會將這條連接對象銷毀,創建一個新的連接對象。
testWhileIdle參數。這個參數為true時候,表示空閑時是進行驗證,檢查對象是否有效。然后minEvictableIdleTimeMillis配合timeBetweenEvictionRunsMillis,每過timeBetweenEvictionRunsMillis秒對連接池進行一次檢測,將對象閑置時間超過minEvictableIdleTimeMillis秒的對象進行銷毀,創建新的對象來取代。這樣就能保證時刻都有正常的連接池對象存在。
 
  • 數據庫查詢優化?

查詢優化?
(1.數據庫:索引、分區;2.I/O:緩沖區;3.SQL語句,條目)
1)數據庫方面:1.建立有效的索引;2.對數據庫分區(如按時間分區);
2)I/O方面:增加緩沖區;
3)SQL語句方面:1.優化SQL語句,減少比較次數;如避免select * from而使用具體的字段列表代替,避免在where中使用!=或<>操作符,否則將放棄索引而進行全表掃描; 2.限制返回條目limit;
 
  • 死鎖產生的原因?必要條件?

產生死鎖原因?

死鎖:指多個進程因競爭共享資源而造成的一種僵局,若無外力作用,這些進程都將永遠不能再向前推進。

1)競爭系統資源;2)進程推進順序不當;

產生死鎖必要條件?

(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。

 

  • 死鎖的避免?如何解決死鎖?

避免死鎖:資源有序分配(避免循環等待)、避免事務交互(減少持有資源的時間)、保持事務簡短並處於一個批處理中(減少持有資源時間)

解決死鎖?

剝奪資源:從其它進程剝奪足夠數量的資源給死鎖進程,以解除死鎖狀態;

撤消進程:可以直接撤消死鎖進程或撤消代價最小的進程,直至有足夠的資源可用,死鎖狀態消除為止;所謂代價是指優先級、運行代價、進程的重要性和價值等。

 

  • 紅黑樹的實現?

紅黑樹本質是二叉搜索樹,滿足二叉搜索樹的基本性質——即樹中的任何節點的值大於它的左子節點,且小於它的右子節點。

紅黑樹節點的基本屬性有:顏色、左子節點指針、右子節點指針、父節點指針、節點值;

一顆紅黑樹必須滿足以下幾點條件:

  1)根節點必須是黑色。

  2)父子節點之間不包含連續的紅色節點。

  3)任意節點到葉子的路徑的黑色節點總數相同。

這些約束確保了紅黑樹的關鍵特性:對樹的插入和刪除操作時會維持樹的平衡。從根到葉子的最長的可能路徑不多於最短的可能路徑的兩倍長。結果是這個樹大致上是平衡的。

因為操作比如插入、刪除和查找某個值的最壞情況時間都要求與樹的高度成比例,這個在高度上的理論上限允許紅黑樹在最壞情況下都是高效的,而不同於普通的二叉查找樹。

RBTree的查找操作就是BST的查找操作,插入和刪除操作時間復雜度是O(logN);

RBTree的旋轉操作:

右旋:節點的左子樹上升到父節點; 左旋:節點的右子樹上升到父節點;

RBTree的插入操作:

RBTree的插入與BST的插入方式是一致的,只不過是在插入過后,可能會導致樹的不平衡,這時就需要對樹進行旋轉操作和顏色修復(在這里簡稱插入修復),使得它符合RBTree的定義。

新插入的節點是紅色的,插入修復操作如果遇到父節點的顏色為黑則修復操作結束。也就是說,只有在父節點為紅色節點的時候是需要插入修復操作的。

插入修復操作分為以下的三種情況,而且新插入的節點的父節點都是紅色的:

  1. 叔叔節點也為紅色。
  2. 叔叔節點為空,且祖父節點、父節點和新節點處於一條斜線上。
  3. 叔叔節點為空,且祖父節點、父節點和新節點不處於一條斜線上。

參考:知乎-RBTree紅黑樹

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM