面試總結-OS篇(windows與linux核心對比)
首先明確作業系統的幾大模組:
1. 系統初始化
2. 程序管理
3. 檔案系統
4. 儲存系統管理
5. I/O管理
那麼windows核心和linux核心在這幾個模組上有哪些相同之處呢?又有哪些不同之處呢?
首先,作為os,他們的理念都是相似的。
1. 一切皆檔案。 可能讀寫檔案很好實現把,linux不管修改個什麼東東其實都是在修改檔案
2. 程序是執行的實體。 幾乎對於作業系統的一切操作,都要通過程序來實現的,這個才是管理資源的真正實體。
3. 中斷。 在西電學習時,劉西洋做過這樣一個比喻。一個作業系統其實就是一個主迴圈加中斷,我覺得其實還是蠻生動的,很能突出中斷對於整個作業系統的意義。
下面,對於windows和linux做一個簡單的評析,以及提出一些在面試中遇到的問題,估計也是實際開發中的問題,核心之間肯定還是有不小區別的。
定位:windows vs linux
眾所周知,windows是商用系統,面向大眾的。既然是商用的,商用的很大一個特點就是向後相容。而linux是開源系統,核心之間的升級很多時候並不相容,主要是為了加入更多更新的東西把,但是升級真的很麻煩。
其次,windows只是pc領域的霸主,而linux在設計之初,很多時候是針對伺服器的。這個也導致了他們在實現的很多區別。
系統初始化:
略。不是很關鍵吧。但是實現過程都應該差不多,有興趣大家可以去查下。
程序管理:fork+exevc vs createProcess
Linux的程序建立函式?當然是fork了。Linux中程序本身是可以執行的。在windows中,程序只表示是資源的擁有者,不能單獨執行,執行必須要一個執行緒。
fork()的含義是把程序本身clone一個新的出來。也就是說,fork之後子程序和父程序都執行同樣的一段程式碼。想要區分,必須通過fork的返回值來區分。
int pid = fork();
if (pid < 0) {// printf("error");} //小於0,發生錯誤
else if( pid == 0 ) {// printf("
else{ // printf("父程序! ");} // >0,父程序
為什麼這個樣子呢?Linux主要應用於伺服器。而伺服器最多用到的是把同一個資源開闢很多個程序給n多個使用者來同時使用啊。這樣開銷夠小,響應夠快。所以fork快速複製父程序,子程序直接使用父程序的地址。那麼子程序需要執行其他的資源呢?用exevc族,這個時候才為子程序開闢自己的地址空間,傳入需要執行的檔案,就可以執行具體的內容了。
而windows中,createProcess有一大堆的引數,不過很多時候都預設為null。它的作用相當於fork+execv吧。
那麼怎麼理解linux和windows下的程序管理呢?
一個程序最基本的內容:PCB、程式段、資料段
一個執行緒包含的內容:執行緒ID,當前指令指標(PC),暫存器集合和堆疊組成。
執行緒是程序中的一個實體,是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點在執行中必不可少的資源,但它可與同屬一個程序的其它執行緒共享程序所擁有的全部資源。
資源在外存上時候,往往都是程式碼、資源什麼的,就是程式本身。而在記憶體上的時候,就有了程序,程序相當於程式碼的一次生命週期,準備了一些最基本的能為執行做準備的上下文情況。而程序總要在cpu上跑一次把,執行一條一條的指令,這個時候就是執行緒在管理,執行緒相當於程序的一次生命週期,它真正的活了一把啊。
那麼os在執行時,就是程序執行緒都要準備好的。而linux在實現的時候,其實相當於是新建了很多指標指向同一塊資源,能夠直接給你執行,在執行時大家都控制處理它,夠快吧。而在需要執行不同的檔案內容時,才為他在記憶體中分配相應的記憶體空間,做個替換工作,就有新的實體了。而windows下程序是資源的擁有者,你們誰想用就新建個執行緒自己去跑吧。
檔案格式:PE vs ELF
windows可執行檔案格式是PE(portable and executable,可攜帶可執行)。而linux使用的ELF(executable and linkable format,可執行和可連結格式)。兩者都有相似的東西,比如都分成了幾個section,包括程式碼段,資料段等。但是兩個又不一樣。
由於windows核心固定,而linux核心之間往往不相容。linux軟體安裝問題往往讓人很抓狂。在windows中只需要next、next一步步繼續就好了,而linux的軟體包則有很多,.deb、.rpm、.tar.gz什麼的。而核心版本不固定帶來的效果是可以升級很快,但向後相容問題則讓我們抓狂的要死。安裝過程往往需要更改軟體依賴關係什麼的!!!Oh, fucking linux。而這些核心理念上的不同很大程度上導致了他們檔案格式的不同。
檔案系統:ntfs vs ext2&ext3
NTFS 提供長檔名、資料保護和恢復,並通過目錄和檔案許可實現安全性。NTFS 支援大硬碟和在多個硬碟上儲存檔案(稱為卷)。例如,一個大公司的資料庫可能大得必須跨越不同的硬碟。NTFS 提供內建安全性特徵,它控制檔案的隸屬關係和訪問。從DOS或其他作業系統上不能直接訪問 NTFS 分割槽上的檔案。如果要在DOS下讀寫NTFS分割槽檔案的話可以藉助第三方軟體;現如今,Linux系統上已可以使用 NTFS-3G進行對 NTFS 分割槽的完美讀寫,不必擔心資料丟失。
Ext2是 GNU/Linux 系統中標準的檔案系統,其特點為存取檔案的效能極好,對於中小型的檔案更顯示出優勢,這主要得利於其簇快取層的優良設計。
Ext3是一種日誌式檔案系統,是對ext2系統的擴充套件,它相容ext2。
1、高可用性
2、資料的完整性
3、檔案系統的速度 儘管使用ext3檔案系統時,有時在儲存資料時可能要多次寫資料,但是,從總體上看來,ext3比ext2的效能還要好一些。這是因為ext3的日誌功能對磁碟的驅動器讀寫頭進行了優化。所以,檔案系統的讀寫效能較之Ext2檔案系統並來說,效能並沒有降低。
4、資料轉換 由ext2檔案系統轉換成ext3檔案系統非常容易
5、多種日誌模式
比較:從技術而言,windows在做這些方面真的很不入流。它對檔案系統的以及裝置的管理遠遠不及linux,windows下的重新整理鍵不知道毒害了多少人呢?
Linux可以同時管理幾千個處理器,windows呢?兩個都夠嗆。Linux連續使用很多天,使用越來越快,windows一會就不行了。Linux的檔案使用越多碎片就越少,windows一會就卡的要死。
中斷與I/O:
1. 中斷是由非同步的外部事件引起的。外部事件與中斷響應及中斷響應與正執行的指令沒有關係
2. 異常是執行指令器件檢測到不正常的或非法的條件引起的。異常與正執行的指令有直接的聯絡。根據引起一場的程式是否可被回覆和恢復點不同,把異常分為故障(fault)、陷阱(trap)和中止(abort)。
故障是在引起異常的指令之前,把異常情況通知給系統的一種異常。
陷阱是在引起異常的指令之後,把異常情況通知給系統的一種異常。
中止就是中止處理了
Windows中IRQL(Interrupt ReQuest Level)的概念,而linux中沒有。
一個常規的IRQL如下:
31:高
30:掉點
29:處理器間中斷
28:時鐘
27:配置檔案
26
。
。
。
3:裝置中斷(其實只用了16個)
2:DPC/排程
1:APC
0:無源
Windows中有32級,而linux中似乎只有5級。更多的優先順序可以使響應各級服務時更加的好,但是巢狀深度太多總是容易帶來一些不必要的麻煩。
相似之處:
都將中斷分為了兩部分。在LINUX中叫ISR(還是其他?)和BOTTOM HALF。而WINODWS中,DPC(Deferred Procedure Calls)和APC(Asynchronous Procedure Calls)就非常類似BOTTOM HALF。
以linux為例:
上半部響應中斷,下半部分為中斷處理函式。
下半部分處理機制有tasklet、工作佇列、軟中斷
一. 軟中斷
軟中斷是靜態分配的,這也就意味這如果想定義新的軟中斷就必須重新編譯核心。軟中斷可以併發的執行在多處理器上,即使同一個軟中斷也是這樣。所以,軟中斷函式必須是可重入函式,而且需要使用自選鎖來保護資料結構。
二. tasklet
tasklet也是一種軟中斷,但是tasklet比軟中斷有著更好的併發特性。是io驅動程式首選的可延遲函式方法。tasklet有如下的特性:
(1)tasklet可以在核心執行的時候定義
(2)相同型別的tasklet不能在用一個CPU上併發執行,也不能在不同的CPU上併發運
(3)不同型別的tasklet不能在同一個CPU上併發執行,但是可以在不同的CPU上併發執行。所以如果不同的tasklet訪問相同的資料結構,需要加一定的鎖保護
三. 工作佇列
工作佇列由核心執行緒來執行。主要的資料結構是workqueue_struct結構。這個結構是是一個cpu_workqueue_struct的陣列。cpu_workqueue_struct結構是工作哦佇列的基本結構。主要有此工作佇列工作的連結串列,還有核心執行緒的程序描述符的指標。 工作佇列的工作是由work_struct結構組成,這個結構有需要執行的函式,以及傳輸的資料等欄位。建立工作佇列是一項非常耗時的操作,因為它會建立一個核心執行緒。所以linux預設建立了一個工作佇列來供使用。每一個CPU一個這樣的工作佇列。
管理:
登錄檔
這個是windows特色,而linux中每個軟體有自己的配置檔案即可,靈活性很大
軟體使用
其實windows下的軟體絕大多數都有linux的對應東西。比如說word,在linux下使用latex做出來效果往往非常只好,而且不會因為移植問題二格式發生變化。用vim與ide相比呢?其實什麼軟體最好,當然是diy的了,定製的總是最好的咯
如何深入核心: shell?(常用命令)
Linux很多時候通過shell來訪問核心,命令列模式為在經常接觸核心的過程中算是個很好的選擇了。總比windows下用資源瀏覽器或者ie總出現未響應要好得多吧。
核心樹與補丁?
其實就是核心原始碼
Linux核心開發流程當前包括一些主核心分支,和很多不同的子系統專有的核心分支。它們是:
- 主 2.6.x 核心樹
- 2.6.x.y -stable 核心樹
- 2.6.x -git 核心補丁
- 2.6.x -mm 核心補丁
- 子系統專有核心樹和補丁
常用命令
cat 檔名 輸出檔案內容到基本輸出(螢幕 or 加>fileName 到另一個檔案)
cb 格式化原始碼
chmod //chang mode,改變檔案的許可權
cp copy
date 當前的時間和日期
echo $abc 在變數賦值之後,只需在變數前面加一個$去引用.
lint 語法檢查程式
ls dir
man help
more type
du 檢視磁碟空間狀況
ps 檢視當前程序狀況
who 你的使用者名稱和終端型別
定義變數 name=abc? (bash/pdksh) || set name = abc (tcsh)
mkdir 建立目錄
rmdir 刪除目錄
cd 進入目錄
rm 刪除檔案
more 顯示檔案
echo 顯示指定文字
mv 改檔名
pwd 顯示目錄路徑命令
uname -r 檢視自己的linux核心的版本
理念:
補丁? 真想不通windows為什麼那麼麻煩,有缺陷通過打補丁的方式,還不斷的更新。有病毒買防毒軟體花錢,整理系統花錢,什麼都花錢,費勁。
核心為何使用了C,而非C++?
根據linus torvalds的解釋:C++語言想解決的問題都不對路,都是一些皮毛問題,而沒有涉及真正深層次的問題。 C++的物件、模板和函式過載都基本上純粹是C的語法擴充套件,是語法糖,總體上把C的語法和型別系統都弄得更糟。他建議,在系統程式設計裡直接用C就可以,非系統程式設計裡,應該選擇一種有垃圾收集的語言,C++語言的特性基本無用,只會搗亂。因此,什麼時候C++都不可能是正確的選擇。
Linus也承認,在其他一些情況下,可能需要更多語言支援,語言級的記憶體分配機制如垃圾收集、併發、動態程式碼生成等等。但是核心開發不需要。
很多時候c++的stl、boost庫都已經很成熟了,但是都有一定的程式設計模型什麼的在裡面。但是在對核心進行更改的時候,這些東西很可能讓核心更改陷入困境。簡潔就是美吧,抽象程度太高在某些時候未必奏效吧!!!
面試中常見OS問題:
程序與執行緒區別?執行緒安全?
程序狀態切換?
死鎖?死鎖條件?
建立程序、子程序?
常見linux命令?
中斷?Windows下linux下的區別?
IPC?那兩大類?主要的ipc方式?
Linux建立工程編譯等問題?
Linux編譯核心?核心移植?
Socket程式設計?
Gdb除錯程式?Makefile熟悉?
驅動開發熟悉否?編寫驅動?
。。。
總評:
Windows在很多設計上遠不及linux的。Windows好比一坨屎,大家都在吃屎;linux好比一個美女,大家想上而不得。沒那麼高的能力把,所以大家yy下linux還是回去接著吃屎吧!!!!