.Net基礎知識點解答
.NET是 Microsoft XML Web services 平臺。XML Web services 允許應用程序通過 Internet 進行通訊和共享數(shù)據(jù),而不管所采用的是哪種操作系統(tǒng)、設備或編程語言。Microsoft .NET 平臺提供創(chuàng)建 XML Web services 并將這些服務集成在一起之所需。對個人用戶的好處是無縫的、吸引人的體驗。
1. 什么是.NET?什么是CLI?什么是CLR?IL是什么?JIT是什么,它是如何工作的?GC是什么,簡述一下GC的工作方式?
通俗的講,.Net是微軟開發(fā)應用程序的一個平臺;
CLI是Common Language Infrastructure,是公共語言架構;
CLR是Common Language Runtime,即公共語言運行時;
IL是.Net編譯器產(chǎn)生的中間代碼,稱為通用中間語言CIL(Common Intermediate Language),CIL常被稱為MSIL,即代表IL的微實現(xiàn)語言;
JIT是以即時編譯Just In Time的方式編譯IL代碼,和Java的字節(jié)碼ByteCode對比來說,字節(jié)碼是解釋性編譯,而JIT是即時編譯,效率上會更勝一籌。
除此之外,還有CTS 通用類型系統(tǒng),Common Type System;CLS公共語言規(guī)范Common Language Specification;FCL .Net框架類庫Framework Class Library;
引用《你必須知道的.Net》一書中的插圖做說明
GC,垃圾回收器,Garbage Collection,負責執(zhí)行內(nèi)存的清理工作,GC通過對托管堆的管理,能有效的解決C++程序中類似于內(nèi)存泄露、訪問不可達對象等問題。
一個對象若沒有被其他任何對象引用,則該對象被認為是可以回收的對象;
最好不要通過GC.Collect來強制執(zhí)行垃圾回收;
垃圾對象并非被立即執(zhí)行內(nèi)存清理,GC可以在任何時候執(zhí)行垃圾收集。
2. 類(class)和結構(struct)的區(qū)別是什么?它們對性能有影響嗎?.NET BCL里有哪些是類(結構),為什么它們不是結構(類)?在自定義類型時,您如何選擇是類還是結構?
Class是引用類型,是非配在內(nèi)存的托管堆上,能夠被實例化,屬于引用類型,類是引用傳遞的;
而struct是值類型,分配在內(nèi)存的棧上,結構體是復制傳遞的,如Int32、Boolean、DateTime都是結構體。
頻繁大量使用引用類型需要GC回收處理,在某些情況下對性能會有影響。
如果一個對象只有屬性、沒有方法的時候應該定義成struc,開銷會小一些;class適用于這個對象同時具有行為和屬性。
3. 在.NET程序運行過程中,什么是堆,什么是棧?什么情況下會在堆(棧)上分配數(shù)據(jù)?它們有性能上的區(qū)別嗎?"結構"對象可能分配在堆上嗎?什么情況下會發(fā)生,有什么需要注意的嗎?
棧是編譯期間就分配好的內(nèi)存空間,因此代碼中必須就棧的大小有明確的定義,如局部類型變量、值類型參數(shù)等;
堆是程序運行期間動態(tài)分配的內(nèi)存空間,可以根據(jù)程序的運行情況確定要分配的堆內(nèi)存的大小。
性能上棧要比內(nèi)存堆的開銷小一些,速度快;
會,當一個類里面包含結構體對象的時候,struct會分配在堆上,值類型總是分配在它聲明的地方。
4. 泛型的作用是什么?它有什么優(yōu)勢?它對性能有影響嗎?它在執(zhí)行時的行為是什么?.NET BCL中有哪些泛型類型?舉例說明平時編程中您定義的泛型類型。
泛型類似于模板,有利于代碼重用;
省去了拆箱、裝箱過程,性能上提升了很多;
本質上來講,在IL初次編譯時泛型T只是作為類型占位符;
BCL中實現(xiàn)了泛型接口的類都是反省類型,如List, Dictionary
5. 異常的作用是什么?.NET BCL中有哪些常見的異常?在代碼中您是如何捕獲/處理異常的?在"catch (ex)"中,"throw"和"throw ex"有什么區(qū)別?您會如何設計異常的結構,什么情況下您會拋出異常?
異常是系統(tǒng)容錯和規(guī)范程序的不可或缺的重要因素和手段。
BCL中常見的異常有StackOverflowException、OutOfMemoryException、NullReferenceException、IndexOutOfRangeException、ArgumentException、DivideByZeroException等;
捕獲異常使用try-catch-finally語句塊 ;
"throw"和"throw ex"的區(qū)別是:推薦使用throw來拋出異常,因為throw ex會將上次異常清空,又拋出一個新的異常,不利于堆棧跟蹤錯誤源頭。
6. List和T[]的區(qū)別是什么,平時你如何進行選擇?Dictionary是做什么的?.NET BCL中還有哪些常用的容器?它們分別是如何實現(xiàn)的(哪種數(shù)據(jù)結構)?分別是適用于哪些場景?
List長度不固定,動態(tài)變化,支持方法較多;T[]固定大小的泛型數(shù)組。
Dictionary是泛型字典,提供一對一的關系;
.Net BCL中常用的集合有Stack、Queue、LinkedList,對應的數(shù)據(jù)結構是棧、隊列和鏈表。
7. 抽象類和接口有什么區(qū)別?使用時有什么需要注意的嗎?如何選擇是定義一個"完全抽象"的抽象類,還是接口?什么是接口的"顯式實現(xiàn)"?為什么說它很重要?
相同點:都不能被實例化,都可以通過繼承實現(xiàn)其抽象方法;
不同點:接口支持多繼承,抽象類不能;接口只能定義行為,抽象類既可以定義行為,還能提供實現(xiàn);接口只包含方法、屬性、索引器和事件的簽名,不能包括自定義字段和實現(xiàn)方法,抽象類可以包含自定義字段和實現(xiàn)方法。
8. 字符串是引用類型類型還是結構類型?它和普通的引用類型相比有什么特別的地方嗎?使用字符串時有什么需要注意的地方?為什么說StringBuilder比較高效?在連接多個字符串時,它無論何時都比直接相加更高效嗎?
字符串是特殊的引用類型。
其特殊之處在于string是不可變的,即字符串恒定性(Immutability),字符串一經(jīng)創(chuàng)建,就不可改變。
當大量使用string進行拼接的時候,直接使用string+會影響效率,使用StringBuilder更為合適;
不是的,對于簡單的字符串連接操作,在性能上StringBuilder不一定總是優(yōu)于String,因為StringBuilder對象的創(chuàng)建代價比較大,在字符串連接目標較少的情況下,過度濫用StringBuilder會導致性能的浪費而非節(jié)約。只有大量的或者無法預知次數(shù)的字符串操作,才考慮以StringBuilder實現(xiàn)。
9. 如何高效地進行數(shù)組復制?"二維數(shù)組"和"數(shù)組的數(shù)組"有什么區(qū)別?在使用雙重循環(huán)遍歷一個二維數(shù)組時,如何選擇內(nèi)外層的遍歷順序?
10. 什么是元編程,.NET有哪些元編程的手段和場景?什么是反射?能否舉一些反射的常用場景?有人說反射性能較差,您怎么看待這個問題?有什么辦法可以提高反射的性能嗎?
元編程是對程序本身的編程,如反射;
程序集包含模塊,模塊又包含類型,類型下有成員,反射就是管理程序集、模塊、類型的對象,它能夠動態(tài)的創(chuàng)建類,獲取現(xiàn)有對象的類型,能調用類型的方法和訪問類型的字段屬性。它是在程序運行時創(chuàng)建和使用類型的。
11. 委托是什么?匿名方法是什么?在C# 3.0中,Lambda表達式是什么?擴展方法是什么?LINQ是什么?您覺得C# 3.0中還有哪些重要的特性,它們帶來了什么優(yōu)勢?BCL中哪些類庫和這些特性有關?您平時最常用哪些?
委托是指向函數(shù)的指針;匿名方法類似javascript中的匿名方法,無須聲明,直接使用;
Lambda表達式函數(shù)式編程,LINQ表示語言集成查詢,為CLR提供了信息查詢能力。
擴展方法,用this關鍵字標記擴展方法的第一個參數(shù),且該參數(shù)不能為指針類型。