面試常見問題——操作系統(一)
目錄:
- 常見問題
- 動態鏈接庫和靜態鏈接庫的優缺點對比
- 輪詢任務調度和可搶佔式調度的區別
- 進程間通信機制
- 線程與進程的區別和聯繫、線程是否有相同的堆棧、DLL是否具有獨立的堆棧
- 程序應該使用線程的場景
- 多線程程序的優缺點、多進程程序的優缺點、與多線程相比的區別
- 死鎖的概念和原因,解決辦法
- 臨界區和臨界資源,臨界區互斥實現
- 操作系統管目態如何切換、系統調用、管目態區別
- 硬鏈接與軟鏈接
- 段頁式虛擬存儲管理方案的特點
一、常見問題:
1、動態鏈接庫和靜態鏈接庫的優缺點對比
- 庫:把一些常用函數的目標文件打包在一起,提供相應函數的接口,便於程序員使用。
- 動態鏈接庫(Dynamic Link Library,DLL):
- 定義:把調用的函數所在文件模塊和調用函數在文件中的位置等信息鏈接入目標程序,DLL文件不必包含在最終的EXE文件中,在EXE文件運行時才載入內存,在編譯過程中僅簡單地引用,其代碼體積小。使用方式包括:
- 動態加載(運行時動態鏈接):在被使用時才被應用程序加載
- 靜態加載(載入時動態鏈接):在應用程序啓動時加載
- 優點:
- 節省內存,減少頁面交換。多個應用程序啓動時,只需將動態庫加載到內存一次
- 不同的模塊放在不同的動態鏈接庫中,具有很強的可維護性和可擴展性
- 不同編程語言編寫的程序只要按照函數調用約定就可以調用同一個DLL函數
- 適用於大規模開發,耦合度小,便於開發和測試
- 缺點:
- 不能解決引用計數
- 使用動態鏈接的應用程序不是自完備的,它依賴的DLL模塊也要存在
- 可能造成DLL地獄(DLL HELL),指在Windows系統中,因爲動態鏈接庫的版本或兼容性的問題而造成程序無法正常運行的情況。
- 在Windows操作系統中動態鏈接庫的後綴爲.dll,在Linux操作系統中動態鏈接庫的後綴爲.so
- 定義:把調用的函數所在文件模塊和調用函數在文件中的位置等信息鏈接入目標程序,DLL文件不必包含在最終的EXE文件中,在EXE文件運行時才載入內存,在編譯過程中僅簡單地引用,其代碼體積小。使用方式包括:
- 靜態鏈接庫(Static Link Library,LIB):
- 定義:LIB文件中的指令全部被直接包含在最終生成的exe文件中,函數和數據被編譯進一個二進制文件中,代碼在編譯中已經被載入可執行程序,其體積較大。
- 優點:
- 代碼裝載速度快,因爲在編譯時只把需要的那部分內容鏈接進去,執行速度比動態鏈接庫略快
- 只需保證在開發者的計算機中有正確的.lib文件即可,以二進制形式發佈無須考慮版本問題,可避免DLL地獄
- 缺點:
- 如果一個靜態鏈接庫被多個應用程序使用,則會被加載多次,造成浪費。
- 可執行文件體積大,包含相同的公共代碼,造成浪費
- 函數可以定義在程序自身、靜態庫、動態庫。當出現同名函數時:
- 程序和靜態庫定義了同名函數,鏈接時會報重定義錯誤。
- 程序和動態庫定義了同名函數,會覆蓋動態庫中定義的函數。
- 動態庫中定義的同名函數,先鏈接覆蓋後鏈接的函數。
2、輪詢任務調度和可搶佔式調度的區別
- 輪詢任務調度::
- 定義:輪詢調度的原理是每一次把來自用戶的請求輪流的分配給內部服務器,從1開始,直到N(內部服務器的個數),然後重新開始循環。只有當前任務主動放棄CPU控制權的情況下(比如任務掛起),才允許其他任務(包括高優先級的任務)控制CPU。
- 無狀態調度(無需記錄進程的運行狀態)
- 對長作業有利,對短作業不利;有利於CPU繁忙型作業,不利於I/O繁忙型作業
- 可搶佔式調度:
- 定義:當一個進程正在處理機上執行時,若有某個更爲重要或緊迫的進程需要適用處理機,則立即暫停正在執行的進程,將處理機分配給這個更爲重要或緊迫的進程。
- 可能導致低優先級任務長期無法得到調度的飢餓現象
3、在MMO遊戲(Massively Multiplayer Online)中,服務器採用Linux操作系統,網路通信與遊戲邏輯處理進程一般是分離的。例如GameServer進程處理遊戲邏輯,TCPServer進程處理網絡通。Linux操作系統提供了很多機制可以實現GameServer和TCPServer進程之間的數據通信。請列出兩種你認爲最好的機制,並描述二者實現的框架、優缺點對比和應用中的注意事項。
- 共享存儲
- 定義:在通信的進程之間存在一塊可以直接訪問的共享空間,通過對這片共享空間進行讀/寫操作實現進程之間的信息交換。進程間通信不再需要進入內核的系統調用來實現。
- 低級方式:基於數據結構的共享
- 高級方式:基於存儲區的共享
- 優點:
- 數據的賦值只有兩次(①從輸入文件到共享內存區,②從共享內存區到輸出文件),其他方式需要四次(①由用戶空間的緩衝區中將數據拷貝到內核中。②內核將數據拷貝到內存中。③內存到內核。④內核到用戶空間的緩衝區)
- 相比消息傳遞和管道通信,共享內存時最快的進程通信方式
- 缺點:
- 需要應用程序自己實現互斥
- 定義:在通信的進程之間存在一塊可以直接訪問的共享空間,通過對這片共享空間進行讀/寫操作實現進程之間的信息交換。進程間通信不再需要進入內核的系統調用來實現。
- 消息傳遞:
- 定義:進程通過系統提供的發送消息原語(msgsnd)和接收消息原語(msgrcv)系統調用進行數據交換
- 直接通信方式:直接把消息掛到接收進程的消息隊列
- 間接通信方式:掛到某個中間實體,接收進程找實體接收消息,類似電子郵件
- 接收進程可以按照先入先出的順序接收消息,或者按類型接收。
- 缺點:
- 默認緩衝比較小,不過可以調整
- 優點:
- 適用於大部分場景
- 定義:進程通過系統提供的發送消息原語(msgsnd)和接收消息原語(msgrcv)系統調用進行數據交換
- 管道通信:
- 定義:管道是內核管理的一個環形緩衝區,允許兩個進程以生產者/消費者的模型進行通信。
- 優點:
- 不需要加鎖
- 缺點:
- 半雙工通信,如果需要雙向通信,需要建立兩個管道,不適合多個子進程
- Linux中緩衝區固定大小,只有4KB。
- 寫進程會先把緩衝區寫滿,然後才讓讀進程讀,當緩衝區中還有數據時,寫進程不會往緩衝區寫數據
- 適用場景:父子進程間通信
4、線程與進程的區別和聯繫分別是什麼?線程是否有相同的堆棧?DLL是否具有獨立的堆棧?
- 線程:
- 引入目的:減小程序在併發執行時所付出的時空開銷,提高併發性能。
- 定義:由線程ID、程序計數器、寄存器集合和堆棧組成。線程是進程中的一個實體,不擁有資源,但可與同屬一個進程的其他線程共享進程所擁有的全部資源。
- 進程:
- 引入目的:更好地使多道程序併發執行,提高資源利用率和系統吞吐量,增加併發程度
- 定義:進程是進程實體運行的過程,是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,是系統進行資源分配和調度的一個獨立單位。
- 區別與聯繫:
- 進程是資源分配的基本單位,線程是獨立調度的基本單位。(資源分給進程,處理機分給線程)
- 同一進程內的多個線程共享進程的地址空間,進程的地址空間之間相互獨立。
- 線程之間共享的內容:
- 代碼段
- 數據段
- 堆空間
- 進程打開的文件描述符
- 進程的當前目錄
- 進程的用戶ID和組ID
- 線程獨佔的資源:
- 棧
- 線程ID
- 寄存器
- 錯誤返回碼
- 線程的信號屏蔽碼(但所有線程共享相同的信號處理器)
- 線程之間共享的內容:
- 進程間通信需要進程同步和互斥手段來保證數據的一致性。而線程間可以直接讀/寫進程數據段(如全局變量)來進行通信。
- 一個線程只能屬於一個進程,一個進程可以擁有多個線程。
- 程序啓動時操作系統創建了一個主線程,每個線程有自己的堆棧。
- DLL中的代碼是被某些線程所執行,只有線程擁有堆棧。對於堆來說,每個DLL有自己的堆。
5、程序什麼時候應該使用線程?
- 耗時的操作使用線程,提高應用程序響應效率
- 並行操作時使用線程,例如基於C/S架構的服務器端併發線程響應用戶的請求
- 在多CPU系統中,使用線程提高CPU利用率
- 改善程序結構。一個複雜進程可以考慮劃分爲多個獨立或半獨立的線程
6、多線程程序有什麼優點和缺點?多進程程序有什麼優點與缺點?與多線程相比,有什麼區別?
- 多線程程序:
- 優點:
- 無須跨進程邊界
- 程序邏輯和控制方式簡單
- 所有線程可以直接共享內存和變量等
- 線程方式消耗的總資源比進程方式少
- 缺點:
- 每個線程和主程序共用地址空間,受限於2GB地址空間
- 一個線程的崩潰可能影響到整個程序的穩定性
- 線程之間的同步和加鎖控制比較麻煩
- 線程數到達一定程度,即使增加CPU也無法提高性能
- 優點:
- 多進程程序:
- 優點:
- 各進程相互獨立,不影響主程序的穩定性
- 通過增加CPU,容易擴展性能
- 每個子進程都有2GB地址空間和相關資源,總體能夠達到的性能上限非常大
- 缺點:
- 邏輯控制複雜,需要和主程序交互
- 需要跨進程邊界,不適用於大數據量傳送
- 優點:
- 最好是多進程和多線程結合,即根據實際的需要,每個CPU開啓一個子進程,這個子進程開啓多線程可以爲若干同類型的數據進行處理。也可以利用多線程+多CPU+輪詢方式來解決問題
7、死鎖的概念和原因,解決辦法
- 定義:
- 指多個進程因競爭資源而造成的相互等待,若無外力作用,這些進程都將無法向前推進
- 原因:
- 對不可剝奪資源的競爭
- 進程在運行過程中,請求和釋放資源的順序不當
- 信號量使用不當
- 滿足死鎖產生的4個必要條件
- 互斥條件:臨界資源
- 不剝奪條件:進程所獲得的資源在未使用完之前,不能被其他進程強行奪走,只能主動釋放
- 請求並保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求,而該資源已被其他進程佔用,此時請求進程被阻塞,但對自己已獲得的資源保持不放
- 循環等待條件:存在一種進程資源的循環等待鏈,鏈中每個進程已獲得的資源同時被鏈中下一個進程所請求
- 解決方法:
- 死鎖預防:
- 破壞請求並保持條件:
- 預先靜態分配法:進程在運行前一次申請完它所需要的全部資源,在它的資源未滿足前,不把它投入運行。一旦投入運行,這些資源就一直歸它所有,不再提出其他資源請求。
- 缺點:
- 系統資源浪費嚴重
- 個別資源長期被其他進程佔用時,可能導致“飢餓”現象
- 破壞循環等待條件:
- 順序資源分配法:首先給系統中的資源編號,規定每個進程必須按照編號遞增的順序請求資源,同類資源一次申請完。
- 缺點:
- 作業實際使用時和系統規定順序不同,造成系統資源浪費,同時造成編程不便
- 破壞請求並保持條件:
- 死鎖避免:
- 銀行家算法:
- 思想:操作系統視爲銀行家,操作系統管理的資源視爲銀行家管理的資金,進程向操作系統請求分配資源視爲用戶向銀行家貸款。操作系統按照銀行家指定的規則爲進程分配資源。當進程首次申請資源時,要測試該進程對資源的最大需求量,若系統現存的資源可以滿足它的最大需求量,則按當前的申請量分配資源,否則就推遲分配。
- 數據結構:
- 可利用資源向量Available
- 最大需求矩陣Max
- 分配矩陣Allocation
- 需求矩陣Need(Need = Max - Allocation)
- 銀行家算法:
- 死鎖的檢測和解除:
- 檢測:
- 利用死鎖定理化簡資源分配圖以檢測死鎖的存在
- 死鎖定理:S狀態爲死鎖的條件是當且僅當S狀態的資源分配圖是不可完全簡化的,該條件爲死鎖定理。
- 解除:
- 資源剝奪法:掛起某些死鎖進程並搶奪它的資源,以便讓其他進程繼續推進
- 撤銷進程法:強制撤銷部分、甚至全部死鎖進程並剝奪這些進程的資源
- 進程回退法:讓一個或多個進程回退到足以迴避死鎖的地步
- 檢測:
- 死鎖預防:
8、解釋一下臨界區和臨界資源,如何實現臨界區互斥
- 臨界資源:
- 定義:可被多個進程共享,但一次僅允許一個進程使用的資源,如打印機
- 臨界資源的互斥訪問過程包括4個部分:
- 進入區:在進入區要檢查是否可以進入臨界區,若能進入臨界區,則應設置正在訪問臨界區的標誌,以阻止其他進程同時進入臨界區
- 臨界區:進程中訪問臨界區的那段代碼
- 退出區:將正在訪問臨界區的標誌清除
- 剩餘區:代碼中的其餘部分
- 臨界區互斥:
- 原則:
- 空閒讓進:臨界區空閒時,可以允許一個請求進入臨界區的進程立即進入臨界區
- 忙則等待:當已有進程進入臨界區時,其他試圖進入臨界區的進程必須等待
- 有限等待:對請求訪問的進程,應保證能在有限時間內進入臨界區
- 讓權等待:當進程不能進入臨界區時,應立即釋放處理器
- 基本方法:
- 軟件實現:
- 在進入區設置並檢查一些標誌來標明是否有進程在臨界區中,若已有進程在臨界區,則在進入區通過循環檢查進行等待,進程離開臨界區後則在退出區修改標誌。
- 單標誌法:P0出來,臨界區空閒,而P1修改了標誌卻不進去,導致P0無法再次進入。違背“空閒讓進”原則
- 雙標誌法先檢查:檢查和修改操作不能一次進行,P0、P1都進入了臨界區,違背“忙則等待”原則
- 雙標誌法後檢查:互相“謙讓”,會導致“飢餓”現象
- 皮特森算法:單標誌法和雙標誌法後檢查的結合
- 硬件實現:
- 中斷屏蔽法:進區關中斷,出區開中斷
- 硬件指令法:設立原子操作指令
- 硬件方法的缺點:
- 進程等待進入臨界區時要消耗處理機時間,不能實現讓權等待。
- 從等待進程中隨機選擇一個進入臨界區,有的進程可能一直選不上,導致飢餓。
- 信號量:利用PV操作實現互斥
- 軟件實現:
- 原則:
9、操作系統管態和目態如何切換,系統調用時是管態還是目態,管態和目態的區別
- 區分執行態的目的是保護操作系統系統程序。
- 目態到管態:
- 系統調用(主動)
- 出現異常(被動)
- I/O設備的中斷(被動)
- 管態到目態:
- 中斷返回用戶程序時
- 系統調用是操作系統提供給用戶程序的接口,系統調用發生在目態,被調用程序執行在管態。
- 管態:
- 資源的訪問權限不受限制,可以執行除訪管指令外的指令系統的全集。
- 目態:
- 程序只能執行非特權指令,只能訪問這個用戶程序自己的存儲空間。
10、硬鏈接與軟鏈接:
- 硬鏈接:
- 爲文件新建一個別名,鏈接文件和原文件實際上是一個文件,在Linux中,硬鏈接的實現方式爲使多個文件名指向同一索引結點,從而使得一個文件可以擁有多個有效的路徑名。一個inode號對應多個文件名。
- 刪除一個硬鏈接文件並不影響其他有相同 inode 號的文件
- 硬鏈接不能跨文件系統,不能對目錄創建硬鏈接
- ls -l求的是硬鏈接數
- 軟鏈接:
- 類似於Windows裏的快捷方式。文件實際上是一個文本文件,其中包含有另一文件的位置信息
- 軟鏈接可以跨文件系統,可以對目錄創建軟鏈接
- 創建軟鏈接時,鏈接計數 i_nlink 不會增加
- 刪除軟鏈接並不影響被指向的文件,但若被指向的原文件被刪除,則相關軟連接被稱爲死鏈接
11、段頁式虛擬存儲管理方案的特點是什麼?
- 頁式存儲管理:把作業分成大小相等的頁(等分內存,。解決外部碎片)
- 每個進程都擁有一張頁表,且進程的頁表駐留在內存中
- 段式存儲管理:把一個程序分成若干段進行存儲,每個段都是一個邏輯實體(邏輯分段,便於實現共享和保護)
- 段頁式存儲管理:
- 先將用戶程序分成若干段(用分段方法管理作業)
- 把每個段分成若干頁,併爲每一個段賦予一個段名,頁間不要求連續(用分頁方法管理內存)
- 特點:
- 空間浪費小
- 存儲共享容易
- 存儲保護容易
- 能動態連接
參考文獻:
[1]王道論壇. 2020操作系統考研複習指導. [M]北京:電子工業出版社,2019.1;
[2]猿媛之家. JAVA程序員面試筆試真題與解析. [M]北京:機械工業出版社,2017.01;