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