常識及資料庫面試2

2021-06-26 15:50:16 字數 4178 閱讀 4846

一、預備知識―程式的記憶體分配 

乙個由c/c++編譯的程式占用的記憶體分為以下幾個部分

1、棧區(stack)― 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。

2、堆區(heap) ― 一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶,呵呵。

3、全域性區(靜態區)(static)―,全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域, 未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。 - 程式結束後有系統釋放

4、文字常量區 ―常量字串就是放在這裡的。 程式結束後由系統釋放

5、程式**區―存放函式體的二進位制**。

二、堆和棧的理論知識 

2.1申請方式

stack:

由系統自動分配。 例如,宣告在函式中乙個區域性變數 int b; 系統自動在棧中為b開闢空間

heap:

需要程式設計師自己申請,並指明大小,在c中malloc函式

如p1 = (char *)malloc(10);

在c++中用new運算子

如p2 = (char *)malloc(10);

但是注意p1、p2本身是在棧中的。

2.2

申請後系統的響應

棧:只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常提示棧溢位。

會遍歷該鍊錶,尋找第乙個空間大於所申請空間的堆結點,然後將該結點從空閒結點鍊錶中刪除,並將該結點的空間分配給程式,另外,對於大多數系統,會在這塊記憶體空間中的首位址處記錄本次分配的大小,這樣,**中的delete語句才能正確的釋放本記憶體空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閒鍊錶中。

2.3申請大小的限制

棧:在windows下,棧是向低位址擴充套件的資料結構,是一塊連續的記憶體的區域。這句話的意思是棧頂的位址和棧的最大容量是系統預先規定好的,在windows下,棧的大小是2m(也有的說是1m,總之是乙個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。

堆:堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用鍊錶來儲存的空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由低位址向高位址。堆的大小受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。

2.4申請效率的比較:

棧由系統自動分配,速度較快。但程式設計師是無法控制的。

堆是由new分配的記憶體,一般速度比較慢,而且容易產生記憶體碎片,不過用起來最方便.

另外,在windows下,最好的方式是用virtualalloc分配記憶體,他不是在堆,也不是在棧是直接在程序的位址空間中保留一快記憶體,雖然用起來最不方便。但是速度快,也最靈活。

2.5堆和棧中的儲存內容

棧: 在函式呼叫時,第乙個進棧的是主函式中後的下一條指令(函式呼叫語句的下一條可執行語句)的位址,然後是函式的各個引數,在大多數的c編譯器中,引數是由右往左入棧的,然後是函式中的區域性變數。注意靜態變數是不入棧的。

堆:一般是在堆的頭部用乙個位元組存放堆的大小。堆中的具體內容有程式設計師安排。

2.6訪問效率的比較 

char s1 = "aaaaaaaaaaaaaaa";

char *s2 = "bbbbbbbbbbbbbbbbb";

aaaaaaaaaaa是在執行時刻賦值的;

而bbbbbbbbbbb是在編譯時就確定的;

但是,在以後的訪問中,在棧上的陣列比指標所指向的字串(例如堆)快。

2.7小結: 

堆和棧的區別可以用如下的比喻來看出:

使用棧就象我們去飯館裡吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。

使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由度大。

假設兩條鍊錶的頭指標分別為p1和p2,遍歷到結尾,如果兩條鍊錶的結尾指向了同乙個節點,則它們相交。

那麼,在何處相交呢?

我們換乙個思路,如果兩條單鏈相交,則相交的那部分一定會是另外一條的一部分(直到結尾)。

我們可以先算出p1鏈的長度l1,p2長l2。

假設l2>l1(相反的情況做法相同)

那麼我們先看p2指向的節點與p1是否相同,不同的話看p2->next與p1,p2=p2->next且l2--,直到它們指向相同或l2next,如此反覆,直到遍歷到結尾即可找到相交處的節點。

使用追趕的方法,設兩個指標slow和fast,前者每次走一步,後者每次走兩步,若有環,則兩者相遇,無環則fast遇到null退出。

怎麼算出環長呢,記錄下之前的碰撞點,計算它們再次碰撞所用的運算元即為環的長度。

至於連線點,有乙個定理:頭指標到連線點的距離=碰撞點到連線點的距離+大於等於0的整數個環長

則分別從頭指標和碰撞點同時出發,相遇的點就是連線點。

最後,頭指標走到連線點的運算元+環的長度=鏈的長度

(atomic)(atomicity)

事務必須是原子工作單元;對於其

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

(consistent)(consistency)

事務在完成時,必須使所有的資料都保持一致狀態。在相關資料庫中,所有規則都必須應用於事務的修改,以保持所有資料的完整性。事務結束時,所有的內部

資料結構(如 b 樹索引或雙向鍊錶)都必須是正確的。某些維護一致性的責任由

應用程式開發人員承擔,他們必須確保應用程式已強制所有已知的完整性約束。例如,當開發用於轉帳的應用程式時,應避免在轉帳過程中任意移動小數點。

(insulation)(isolation)

由併發事務所作的修改必須與任何其它併發事務所作的修改隔離。事務檢視資料時資料所處的狀態,要麼是另一併發事務修改它之前的狀態,要麼是另一事務修改它之後的狀態,事務不會檢視中間狀態的資料。這稱為隔離性,因為它能夠重新裝載起始資料,並且重播一系列事務,以使資料結束時的狀態與原始事務執行的狀態相同。當事務可序列化時將獲得最高的

隔離級別。在此級別上,從一組可並行執行的事務獲得的結果與通過連續執行每個事務所獲得的結果相同。由於高度隔離會限制可並行執行的事務數,所以一些應用程式降低隔離級別以換取更大的吞吐量。

(duration)(durability)

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

那麼資料庫是怎麼做事務的災難恢復的呢,我的想法是:

資料庫每對一行記錄做操作的時候,後台的日誌log程式會相應地做記錄,當事務開始,則先log一條事務開始標記記錄,然後每行log一條資料操作記錄,當發生斷電或意外情況時,從log的尾部知道事務開始標記處進行恢復。

從形式上而言,索引分為聚集索引(clustered indexes)和非聚集索引(nonclustered indexes)。

聚集索引相當於書籍脊背上那個特定的編號。如果對一張表建立了聚集索引,其索引頁中就包含著建立索引的列的值(下稱索引鍵值),那麼表中的記錄將按照該索引鍵值進行排序。比如,我們如果在「姓名」這一字段上建立了聚集索引,則表中的記錄將按照姓名進行排列;如果建立了聚集索引的列是數值型別的,那麼記錄將按照該鍵值的數值大小來進行排列。

非聚集索引用於指定資料的邏輯順序,也就是說,表中的資料並沒有按照索引鍵值指定的順序排列,而仍然按照插入記錄時的順序存放。其索引頁中包含著索引鍵值和它所指向該行記錄在資料頁中的物理位置,叫做行定位符(rid:row id)。好似書後面的的索引表,索引表中的順序與實際的頁碼順序也是不一致的。而且一本書也許有多個索引。比如主題索引和作者索引。

sql server在預設的情況下建立的索引是非聚集索引,由於非聚集索引不對錶中的資料進行重組,而只是儲存索引鍵值並用乙個指標指向資料所在的頁面。乙個表如果沒有聚集索引時,理論上可以建立249個非聚集索引。每個非聚集索引提供訪問資料的不同排序順序。

在sql server中,索引是通過二叉樹的資料結構來描述的,聚集索引的葉節點就是資料節點,而非聚集索引的葉節點仍然是索引節點,是乙個指向對應資料塊的指標。聚集索引對經常要搜尋範圍值的列特表有效,使用聚集索引找到包含第乙個值的行後,便可以確保包含後續索引值的行在物理相鄰。

資料庫常識

資料儲存的發展史,最開始由手動管理,後來發展為檔案管理。檔案儲存的缺點 1.在儲存資料時,沒有一定的結構 2.不便於修改資料 3.資料越來越多,檔案容易丟失 後來發展為使用資料庫進行資料的儲存和管理。tcp協議的埠號 1521 oracle預設的 http協議的埠號 8080 sid為資料庫的唯一識...

資料庫的一些面試常識

1 請說出關係型資料庫的典型產品 特點及應用場景?sqlserver 特點 真正的客戶機 伺服器體系結構 圖形化使用者介面 豐富的程式設計介面工具 與windows nt完全整合 具有很好的伸縮性 應用場景 主機為windows系統,主要應用於web 的建設,承載中小型web後台資料。mysql m...

資料庫常識(小細節)

insert可以插入部分字段,其餘字段自動為null,刪除表的語句是 drop table if exists 表名 12.表的複製語句是create table emp2 as select empno,ename from emp 更新語句是update dept1 set loc shangh...