面試問題(非編程)彙總

1. 堆棧底層操作系統實現

   SS: 棧段寄存器,32位下是一個selector。 

   EBP:存儲棧的底部。 ESP:指向棧的頂部。

   當函數調用時:一般是

#進入函數,現在esp指向棧頂,其值即 [CS 和 EIP ]

push        ebp        #在棧中存儲ebp的值, SS[esp] 現在存儲了

mov         ebp,esp  #將當前棧頂位置存儲到ebp中.

sub         esp,0CCh #在棧中分配局部變量的空間,這裏分配了16*c+c = 204 ?

# 現在可以進行各項操作...

# SS[ebp-8] 可以存儲一個int 型變量, SS[ebp-12] 可以存儲第二個int型變量. 

# 退出函數操作:

mov esp, ebp  # 恢復棧頂.

pop ebp         # 現在棧頂指向的是[CS 和 EIP]

ret                # 恢復CS, EIP


2. linux進程間通信方式

   信號、管道、socket、信號量(互斥)、消息隊列、共享內存。

   消息隊列:當進程發消息時,將用戶空間的消息發送到內核空間,讀消息時進行相反操作。與命名管道相比,消息隊列的優勢在於,它獨立於發送和接收進程而存在,這消除了在同步命名管道的打開與關閉的可能產生的一些困難。

   管道:從管道讀數據是一次性操作,數據一旦被讀,它就從管道中被拋棄,釋放空間以便寫更多的數據。當寫者太快或讀者太慢時,寫者會被阻塞。

   共享內存:共享內存是進程間通信中最簡單的方式之一。共享內存允許兩個或更多進程訪問同一塊內存,就如同 malloc() 函數向不同進程返回了指向同一個物理內存區域的指針。當一個進程改變了這塊地址中的內容的時候,其它進程都會察覺到這個更改。解決同步的問題的常用方法是通過使用信號量進行同步。與消息隊列相比,它避免了不必要的複製。
3.
多態、動態綁定的實現原理

   c++多態是通過虛函數實現的。每個含有虛函數的類都包含了一個靜態虛函數指針。

   多態也是通過動態綁定實現的,通過動態綁定,才能找到虛函數表指針。

   java多態是通過延遲綁定實現的,除private和static不是動態綁定其它都是動態綁定。
4.
磁盤的工作調度原理

   磁盤高速緩衝區:利於快速讀寫。

   CFQ(完全公平排隊): 適用於桌面和多媒體應用。I/O請求優先級獨立於進程優先級。

   NOOP(電梯式調度): 傾向於餓死讀而利於寫。適用於閃存設備。RAM、嵌入式系統。

   Deadline(截止時間調度): 以時間和硬盤區域進行分類。適用於數據庫環境(oracle, mysql)。

   AS(預料I/O調度程序): 與Deadline一樣,在讀之後,要等6ms再進行讀寫。實際上這是把小寫入流合併成大寫入流。適用於寫入文件較多的環境,如文件服務器。不適用於數據庫。

5.  malloc 與 free:

     malloc: 分配空間是成塊分配的. 

void free(void *ptr) {

	struct mem_control_block *free;

	free = ptr - sizeof(struct mem_control_block);

	free->is_available = 1;

	return;
}
      由上面可見, free( ptr )時,只需要將ptr 向後移動一個結構體大小(內存控制塊),然後將其標記 is_isavailable 改爲 1,即這一塊是空閒的。

6. 正則式匹配:貪婪與非貪婪

    *(a) 與 *?(a)的區別:前者先匹配整個字符串,然後回溯[huí sù]到第一個a,作爲匹配的字符串。後者先匹配到(a)然後將前一部分作爲*匹配的內容。

7. linux 下線程與進程的區別:

    當線程不大於CPU時,不同的線程程運行於不同的CPU上。

    linux 系統線程數上限:1024。

8. 緩存穿透與雪蹦:

   穿透:緩存某一項對應的取值爲null,每次查找該鍵對應的值時,都要查找數據庫中取值。解決方案,設置上次查詢時間(犧牲了一致性)。

   雪蹦:緩存不能命中(如到期),形成對數據的大量訪問。解決方案,對快到期的cache,提前更新,更新cache時,加鎖防止多個線程同時對一條數據進行查詢。

9.內存屏障:

  對主存的一次訪問一般花費硬件的數百次時鐘週期。處理器通過緩存(caching)能夠從數量級上降低內存延遲的成本這些緩存爲了性能重新排列待定內存操 作的順序。也就是說,程序的讀寫操作不一定會按照它要求處理器的順序執行。當數據是不可變的,同時/或者數據限制在線程範圍內,這些優化是無害的。CPU或者編譯器的亂序是以保持顯式的因果關係不變爲前提的,但是它們都無法識別隱式的因果關係。有了內存屏障,就可以在隱式因果關係的場景中,保證因果關係邏輯正確。內存同步順序永遠不可能與時間順序完全一致,畢竟CPU是並行工作的,而內存同步是串行的。

10.將內存虛擬成硬盤:

  可以把臨時文件(熱點文件)放在虛擬的硬盤上,提高系統的速度。內存讀取速度:1333Mx2x64/8約10GBps。網卡10Gbps,但是,硬盤(即使ssd)卻不過數百兆。

11.銀行家算法與死鎖:

銀行家算法是避免死鎖的,預防死鎖是通過限制死鎖的條件。  

互斥條件(Mutual exclusion):資源不能被共享,只能由一個進程使用。
請求與保持條件(Hold and wait):已經得到資源的進程可以再次申請新的資源。
非剝奪條件(No pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。
循環等待條件(Circular wait):系統中若干進程組成環路,改環路中每個進程都在等待相鄰進程正佔用的資源。
互斥條件(Mutual exclusion):資源不能被共享,只能由一個進程使用。
請求與保持條件(Hold and wait):已經得到資源的進程可以再次申請新的資源。
非剝奪條件(No pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。
循環等待條件(Circular wait):系統中若干進程組成環路,改環路中每個進程都在等待相鄰進程正佔用的資源。
1) 預防死鎖。
這是一種較簡單和直觀的事先預防的方法。方法是通過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或者幾個,來預防發生死鎖。預防死鎖是一種較易實現的方法,已被廣泛使用。但是由於所施加的限制條件往往太嚴格,可能會導致系統資源利用率和系統吞吐量降低。
2) 避免死鎖。
該方法同樣是屬於事先預防的策略,但它並不須事先採取各種限制措施去破壞產生死鎖的的四個必要條件,而是在資源的動態分配過程中,用某種方法去防止系統進入不安全狀態,從而避免發生死鎖。
3)檢測死鎖。
這種方法並不須事先採取任何限制性措施,也不必檢查系統是否已經進入不安全區,此方法允許系統在運行過程中發生死鎖。但可通過系統所設置的檢測機構,及時地檢測出死鎖的發生,並精確地確定與死鎖有關的進程和資源,然後採取適當措施,從系統中將已發生的死鎖清除掉。
檢測方法包括定時檢測、效率低時檢測、進程等待時檢測等。
4)解除死鎖。
這是與檢測死鎖相配套的一種措施。當檢測到系統中已發生死鎖時,須將進程從死鎖狀態中解脫出來。常用的實施方法是撤銷或掛起一些進程,以便回收一些資源,再將這些資源分配給已處於阻塞狀態的進程,使之轉爲就緒狀態,以繼續運行。死鎖的檢測和解除措施,有可能使系統獲得較好的資源利用率和吞吐量,但在實現上難度也最大。
銀行家算法是一種最有代表性的避免死鎖的算法。在避免死鎖方法中允許進程動態地申請資源,但系

銀行家算法:

統在進行資源分配之前,應先計算此次分配資源的安全性,若分配不會導致系統進入不安全狀態,則分配,否則等待。

12.尋找數組中逆序數據對、尋找值爲1-N數組中重複數:

   尋找逆序對:1)可採用冒泡法,每次交換必是一個逆序對。2)採用歸併排序法,A、B分別有序時,若A的最大值小於B的最小值,則不會產生逆序對,否則會產生逆序對。

13. JDBC相關:

   preparedstatement, statement, callablestatement:前者只是預編譯SQL語句並可以設置佔位符、statement用於執行靜態語句和得到結果、callablestatement可以調用存儲過程。

14. 







   

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