1. 程式人生 > >面試總結-OS篇(windows與linux核心對比)

面試總結-OS篇(windows與linux核心對比)

首先明確作業系統的幾大模組:

1. 系統初始化

2. 程序管理

3. 檔案系統

4. 儲存系統管理

5. I/O管理

那麼windows核心和linux核心在這幾個模組上有哪些相同之處呢?又有哪些不同之處呢?

首先,作為os,他們的理念都是相似的。

1. 一切皆檔案。 可能讀寫檔案很好實現把,linux不管修改個什麼東東其實都是在修改檔案

2. 程序是執行的實體。  幾乎對於作業系統的一切操作,都要通過程序來實現的,這個才是管理資源的真正實體。

3. 中斷。 在西電學習時,劉西洋做過這樣一個比喻。一個作業系統其實就是一個主迴圈加中斷,我覺得其實還是蠻生動的,很能突出中斷對於整個作業系統的意義。

下面,對於windowslinux做一個簡單的評析,以及提出一些在面試中遇到的問題,估計也是實際開發中的問題,核心之間肯定還是有不小區別的。

定位: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("

子程序!");//==0,為子程序

         else{ // printf("父程序! ");}           // >0,父程序

     為什麼這個樣子呢?Linux主要應用於伺服器。而伺服器最多用到的是把同一個資源開闢很多個程序給n多個使用者來同時使用啊。這樣開銷夠小,響應夠快。所以fork快速複製父程序,子程序直接使用父程序的地址。那麼子程序需要執行其他的資源呢?用exevc族,這個時候才為子程序開闢自己的地址空間,傳入需要執行的檔案,就可以執行具體的內容了。

     而windows中,createProcess有一大堆的引數,不過很多時候都預設為null。它的作用相當於fork+execv吧。

     那麼怎麼理解linuxwindows下的程序管理呢?

     一個程序最基本的內容:PCB、程式段、資料段

     一個執行緒包含的內容:執行緒ID,當前指令指標(PC),暫存器集合和堆疊組成。

     執行緒是程序中的一個實體,是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點在執行中必不可少的資源,但它可與同屬一個程序的其它執行緒共享程序所擁有的全部資源。  

資源在外存上時候,往往都是程式碼、資源什麼的,就是程式本身。而在記憶體上的時候,就有了程序,程序相當於程式碼的一次生命週期,準備了一些最基本的能為執行做準備的上下文情況。而程序總要在cpu上跑一次把,執行一條一條的指令,這個時候就是執行緒在管理,執行緒相當於程序的一次生命週期,它真正的活了一把啊。

那麼os在執行時,就是程序執行緒都要準備好的。而linux在實現的時候,其實相當於是新建了很多指標指向同一塊資源,能夠直接給你執行,在執行時大家都控制處理它,夠快吧。而在需要執行不同的檔案內容時,才為他在記憶體中分配相應的記憶體空間,做個替換工作,就有新的實體了。而windows下程序是資源的擁有者,你們誰想用就新建個執行緒自己去跑吧。

檔案格式:PE vs ELF

    windows可執行檔案格式是PEportable and executable,可攜帶可執行)。而linux使用的ELFexecutable and linkable format,可執行和可連結格式)。兩者都有相似的東西,比如都分成了幾個section,包括程式碼段,資料段等。但是兩個又不一樣。

由於windows核心固定,而linux核心之間往往不相容。linux軟體安裝問題往往讓人很抓狂。在windows中只需要nextnext一步步繼續就好了,而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檔案系統時,有時在儲存資料時可能要多次寫資料,但是,從總體上看來,ext3ext2的效能還要好一些。這是因為ext3的日誌功能對磁碟的驅動器讀寫頭進行了優化。所以,檔案系統的讀寫效能較之Ext2檔案系統並來說,效能並沒有降低。 

4、資料轉換  由ext2檔案系統轉換成ext3檔案系統非常容易 

5、多種日誌模式 

比較:從技術而言,windows在做這些方面真的很不入流。它對檔案系統的以及裝置的管理遠遠不及linuxwindows下的重新整理鍵不知道毒害了多少人呢?

Linux可以同時管理幾千個處理器,windows呢?兩個都夠嗆。Linux連續使用很多天,使用越來越快,windows一會就不行了。Linux的檔案使用越多碎片就越少,windows一會就卡的要死。

中斷與I/O:

1. 中斷是由非同步的外部事件引起的。外部事件與中斷響應及中斷響應與正執行的指令沒有關係

2. 異常是執行指令器件檢測到不正常的或非法的條件引起的。異常與正執行的指令有直接的聯絡。根據引起一場的程式是否可被回覆和恢復點不同,把異常分為故障(fault)、陷阱(trap)和中止(abort)。

故障是在引起異常的指令之前,把異常情況通知給系統的一種異常。

陷阱是在引起異常的指令之後,把異常情況通知給系統的一種異常。

中止就是中止處理了

WindowsIRQLInterrupt ReQuest Level)的概念,而linux中沒有。

一個常規的IRQL如下:

31:高
30:掉點
29:處理器間中斷
28:時鐘
27:配置檔案
26



3:裝置中斷(其實只用了16)
2DPC/排程
1APC
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有如下的特性:
1tasklet可以在核心執行的時候定義
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做出來效果往往非常只好,而且不會因為移植問題二格式發生變化。用vimide相比呢?其實什麼軟體最好,當然是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++stlboost庫都已經很成熟了,但是都有一定的程式設計模型什麼的在裡面。但是在對核心進行更改的時候,這些東西很可能讓核心更改陷入困境。簡潔就是美吧,抽象程度太高在某些時候未必奏效吧!!!

面試中常見OS問題:

程序與執行緒區別?執行緒安全?

   程序狀態切換?

   死鎖?死鎖條件?

   建立程序、子程序?

   常見linux命令?

   中斷?Windowslinux下的區別?

   IPC?那兩大類?主要的ipc方式?

   Linux建立工程編譯等問題?

   Linux編譯核心?核心移植?

   Socket程式設計?

   Gdb除錯程式?Makefile熟悉?

   驅動開發熟悉否?編寫驅動?

   。。。

總評:

Windows在很多設計上遠不及linux的。Windows好比一坨屎,大家都在吃屎;linux好比一個美女,大家想上而不得。沒那麼高的能力把,所以大家yylinux還是回去接著吃屎吧!!!!