參考資料:html
面試出現頻率:歷來沒人問過。事實上我都不知道怎麼問,考背書嗎?卻是能夠問問知不知道如今.NET最新版本是什麼,考察面試者是否對新技術足夠敏感。git
重要程度:3/10程序員
須要理解的程度:知道這些縮寫(CLR,BCL,FCL,CTS,CLS)各表明什麼便可。仔細讀一遍http://www.tracefact.net/CLR-and-Framework/DotNet-Framework.aspxgithub
.NET框架是以一種採用系統虛擬機(即CLR)運行的,面向CLR的編程平臺,以CLR爲基礎。.NET的基礎類庫運行於CLR之上(類比Java的虛擬機),做爲其餘各類功能的基石。.NET框架支持多種語言(C#、F#、VB.NET、C++、Python等)的開發。它的前身是Windows DNA。如今.NET框架的擴展性甚至超過Java,其的Mono爲Mac OS提供了支持,Xamarin可媲美安卓開發,能夠在任何手機上開發。面試
.NET框架是開源的。它的代碼在https://github.com/dotnet/。若是你的commit有幸被接受,即便改動有多麼微小,也是無上的榮耀,你絕對應該把它寫到你簡歷的第一行,這個成就能夠和「爲Linux內核優化作過貢獻」相比,那可比曾經在BAT作過幾年的經歷牛逼多了。數據庫
全部.NET支持的語言編寫出來的程序,在支持.NET的編譯器編譯以後,會先產出程序集,其主要內容是IL和元數據。以後,JIT再將其翻譯爲機器碼。編程
甲骨文公司的Java EE是.NET平臺的競爭對手之一。json
.NET框架如今已經出到了版本4.6.1。在3.0以前,.NET框架的Web解決方案是ASP.NET(Webform & MVC),數據庫鏈接爲ADO.NET(支持過去的ODBC,OLE等,並支持SQL Server和Oracle),Windows Form則做爲Windows下的應用解決方案。緩存
.NET最重大的一個版本更新是3.0,其中,提出了WCF(統一了過去Web服務混亂的形式,造成了一個統一的格式,並採用SOAP),WPF(做爲Windows form的加強版)以及WF。安全
.NET3.5集成了LINQ。另外Entity Framework取代ADO.NET,它對應VS2008。
.NET4.0提出了任務並行庫和PLINQ。
.NET 5 (即.NET Core 1.0)在2016年6月27日推出。是次推出伴隨着ASP.NET Core (即ASP.NET 6)和Entity Framework 7。這些產品將支持Windows,OS X和Linux三種操做系統。
新版本的.NET項目使用.json文件代替了過去的.xxproj,.sln和.suo文件,這符合目前的主流,即用json代替XML。新版本的.NET框架要傳輸給咱們的理念是:這是一個跨平臺的,開源的框架。一切都是依賴注入,一切都是nuget,開發完全組件化,能解耦的全都解耦。ASP.NET Core完全擺脫了System.Web這個頑疾,在其中,咱們甚至連MVC都是注入進去的。若是想獲得什麼組件,要麼經過依賴注入,要麼就使用nuget。永遠不要手動add reference,目前我知道的惟一的例外是System.Configuration。當你和團隊其餘人並行開發系統的不一樣模塊時,大家能夠用nuget互相獲得對方模塊中的工程。Nuget相比add reference,更不容易出錯,界面更友好,且不會輕易陷入dll陷阱。
通過.NET牌編譯器編譯以後的程序集有兩種形態:類庫(.dll)形態和可執行文件(.exe)形態。.NET自帶了不少類庫,統稱爲FCL。BCL是FCL的一個子集。
Base Class Library (BCL) 是微軟所提出的一組標準庫,可提供給.NET Framework全部語言使用。隨着 Windows 以及.NET Framework 的成長,BCL 已近乎成爲在.NET上的 Windows API。mscorlib.dll程序集幾乎就是基礎類庫的代名詞。
當安裝.NET Framework時,全部的基礎類庫被部署到全局程序集緩存(GAC)。它的位置通常在C:\Windows\assembly。因此你不須要在你的工程中手動引用任何的基礎類庫,它們會被自動引用。若是你從GAC中刪除了mscorlib.dll,你的IDE將變成一個什麼都不懂的白癡。由於沒有mscorlib.dll,意味着沒有基礎類庫,沒有整型,字符串,控制檯…你什麼都作不了。
部分mscorlib.dll包括的命名空間:
然而在C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\咱們還有一個System.dll,這個參考是每次新建工程時VS自動引用的若干參考之一。這個程序集中也有一個System命名空間,它的內容和mscorlib.dll中的不一樣。能夠看到,System這個命名空間存在於不止一個程序集中。這意味着不一樣的程序集能夠共享一個命名空間。
在System.dll中,System類型擁有Uri這個成員,mscorlib.dll中System類型擁有int這個成員(基元類型)。因此咱們能夠作個試驗,若是咱們將工程中對System的引用去掉,那麼咱們就不能定義一個Uri類型的對象。但咱們仍然可使用int類型,由於它雖然也在System這個類型裏面,但位於mscorlib.dll中。當你去掉對System的引用時,你僅僅去掉了System.dll和裏面的功能,但你沒有去掉mscorlib.dll中System類型的功能。
BCL是屬於整個.NET框架的,並不是某種語言的一個基礎類庫。例如,C#的string類型的全部功能和定義來源於mscrolib.dll中的System.String,而VB的string類型的功能和定義也來源於相同的地方。基礎類庫中定義的類型稱爲基元類型,它也是爲.NET框架全部的語言共享。
在.NET Core中,BCL更名換姓變成了Corefx。源碼在https://github.com/dotnet/corefx。
做爲一名.NET程序員,天天都要打交道的就是FCL了(框架類庫)。BCL是FCL的一個子集。簡單來講FCL除了BCL的那部分,就是咱們要引用的外部參考。
簡單的說,CTS就是說話的語法和規範。你能夠理解爲,英語是一種語言,英語的CTS(至少絕大一部分)就是「實用英語語法(張道真)」這本書。若是C#沒了語法,那就沒有class,沒有接口,變成了僞碼。
參考資料中的第一個連接講的很好,我就在這裏總結一下吧:
很明顯,CLS是CTS的一個子集,並且是最小的子集。(最小功能集)
圖片來自CLR via C#。
.NET程序集能夠在非微軟操做系統如Mac OS,各類版本的Linux,以及iOS和Android移動設備上開發和執行。.NET的平臺無關性主要體現爲:.NET程序集能夠在任何的平臺上運行,無論是Windows,仍是Mac,只要這個平臺擁有將IL轉換爲機器碼,以及加載其餘相關程序集的能力(即CLR),而任何機器均可以運行機器碼。這相似於Java的虛擬機,只要平臺裝了Java虛擬機,則這個平臺就能夠運行Java程序。
CLR是讓程序執行所需的外部服務的集合,相似Java須要JVM虛擬機才能夠運行。
它的核心功能(好比即時編譯,內存管理,程序集加載,安全性,異常處理和線程同步)可由面向CLR的全部語言使用。例如,CLR容許建立線程,因此面向CLR的全部語言都能建立線程。
CLR是.NET的運行基礎,管理.NET程序集的執行。它運行於Windows之上,不少功能僅僅是Windows上的一個wrapper,例如線程,內存管理等,這些其實是Windows在管理。但JIT則是它獨有的,若是沒有它,就不能把IL變成機器碼,計算機也就不認識C#,你也就不能運行C#程序。
在開始運行.NET程序以前,編譯器將代碼轉換爲IL。IL代碼並不能直接運行,CLR將真正須要用到的程序集導入內存,讀取元數據,接着爲類型開闢內存空間,執行全部須要的安全檢查,並最終運行代碼:
在程序運行時,CLR還負責:
託管代碼是必須在CLR下執行的代碼,而非託管代碼則不須要CLR的支持就能夠運行。CLR自己用於管理託管代碼,所以它是由非託管代碼編寫的,並非一個包含了託管代碼的程序集,也不能使用IL DASM進行查看。它位於C:\%SystemRoot%\Microsoft.NET\Framework\版本號下,視安裝的機器不一樣有兩個版本,一個是工做站版本的mscorwks.dll,一個是服務器版本的mscorsvr.dll。wks和svr分別表明workstation和server。
CLR via C#這本書選擇經過C#做爲視角,討論CLR的各類功能。經過對這本書的閱讀,你會對一些實際由CLR進行管理的行爲例如垃圾回收,線程管理有更加深入的認識。
面試出現頻率:低。不排除部分IL專家會試探性問你一些IL命令,但我相信你答不出來他們也不會在乎。學了IL和沒學,通常人看不出來區別,學了IL,也不意味着你就很厲害。我的認爲,學IL惟一的用處就在於證實你看到的書上寫的各類結論,或者驗證一些性能方面的想法。你能夠參看這篇文章:http://blog.zhaojie.me/2009/06/my-view-of-il-2-il-shows-little-about-clr.html
重要程度:3/10,常識性瞭解便可
須要理解的程度:知道IL是中間代碼,知道JIT的優勢(帶緩存的編譯),以及它可能會對你的代碼進行優化。
在.NET的開發過程當中, IL的官方術語是MSIL或CIL(Common Intermediate Language,即公共中間語言)。所以,IL,MSIL和CIL指的是同一種東西。
當使用支持.NET的編譯器編譯以後,生成.dll或.exe文件。這文件稱做.NET程序集,包含IL和元數據。不一樣語言(例如C#和VB)通過不一樣編譯器(例如C#編譯器和VB編譯器),編譯一段功能類似的代碼(區別僅僅在於語法),其IL也基本類似。雖然IL相對C#較爲底層,但它仍然是一個十分高級的語言。它並非彙編語言。
能夠經過ildasm(在cmd中運行)工具加載任意的.NET程序集並分析它的內容,包括它所包含的IL代碼和元數據。注意,高級語言只公開了CLR的全部功能的一個子集,而IL容許開發人員訪問CLR全部的功能。
關於IL的擴展閱讀,可參看老趙談IL系列:
http://blog.zhaojie.me/2009/06/my-view-of-il-1-il-and-asm.html
即時編譯(英語:Just-in-time compilation)是動態編譯的一種形式,是一種提升程序運行效率的方法。一般,程序有兩種運行方式:靜態編譯與動態編譯。靜態編譯的程序在執行前所有被翻譯爲機器碼,而動態編譯執行的則是一句句,邊運行邊翻譯。
即時編譯則混合了這兩者,一句句編譯源代碼,可是會將翻譯過的代碼緩存起來以下降性能損耗。相對於靜態編譯代碼,即時編譯的代碼能夠處理延遲綁定並加強安全性。
CLR的JIT負責將IL編譯成機器碼。 當程序編譯成程序集以後,CLR加載任何須要用到的其餘程序集,並開始使用JIT將CIL編譯爲機器碼。JIT編譯器會在方法的首次調用時,從類型的元數據中查找方法,並進行檢查,例如檢查類型是否安全。若是出現了問題,則觸發運行時錯誤。之後對方法的全部調用都以本地代碼的形式全速運行,無須從新檢查。
CLR的JIT編譯器會對本地代碼進行優化。例如字符串駐留中對常量字符串相加的優化。和沒有優化相比,優化以後的代碼將得到更出色的性能。但過分的優化可能會出現問題,在CLR via C#的易失構造中,做者舉了一個例子。
1 class Program 2 { 3 private static bool s_stopWorker = false; 4 5 static void Main() 6 { 7 Console.WriteLine("Main: letting worker run for 2 seconds"); 8 Thread t = new Thread(Worker); 9 t.Start(); 10 11 Thread.Sleep(2000); 12 s_stopWorker = true; 13 Console.WriteLine("Main: waiting for worker to stop"); 14 t.Join(); 15 } 16 17 private static void Worker(object o) 18 { 19 int x = 0; 20 while (!s_stopWorker) 21 { 22 x++; 23 } 24 Console.WriteLine("Worker: stopped when x = {0}", x); 25 } 26 }
若是使用f5呼叫出Visual Studio的調試模式,則程序會像預期的那樣正常運行直到結束。使用調試器會形成JIT編譯器在Debug模式進行編譯,它生成未優化的代碼,目的是方便你進行單步調試。若是是選擇了x86的Release模式進行編譯:
它將會生成被CLR優化的代碼。值得一提的是,x86編譯器是一個更成熟的編譯器,執行優化比x64更大膽。x64不會執行上面所說的特定的優化。在再次用f6進行編譯以後,用ctrl+f5運行程序,程序將會陷入無限循環。
注意:必須用x86+Release編譯,而後以非調試模式運行(即Ctrl+F5),才能看到這個效果。問題發生的緣由是,x86的編譯優化過分。它發現變量s_stopWorker要麼爲true要麼爲false。它還發現這個值在worker方法自己中歷來沒有變化。所以,編譯器會生成代碼檢查s_stopWorker,若是s_stopWorker爲true,就顯示「Worker: stopped when x = 0」。若是s_stopWorker爲false編譯器就生成代碼進入一個無限循環,並一直遞增x。解決的辦法是爲s_stopWorker加入修飾詞volatile。
PDB文件包含了能夠令調試器在本地工做的信息。能夠這麼說:有了PDB文件,本地的debug才成爲可能。若是你打算髮布Release版本,則不須要該文件。使用Release模式編譯的結果中也不包含PDB文件。例如,你寫了一個小的控制檯程序給別人用,那麼你不須要把\bin\debug裏面全部的文件都拷貝給別人,你只須要程序自己,必要的dll和config文件便可。