.net面試題及詳解

時(shí)間:2022-07-03 11:30:23 面試 我要投稿
  • 相關(guān)推薦

.net面試題及詳解

1.什么是CLR

.net面試題及詳解

公共語(yǔ)言運行時(shí)(Comman language Runtime),是一個(gè)可由多種編程語(yǔ)言使用的“運行時(shí)”。CLR的核心功能:程序集加載,異常處理,線(xiàn)程同步,內存管理等可由CLR

的所有語(yǔ)言使用.

2.什么是IL

Intermediate language

中間語(yǔ)言,.net程序在經(jīng)過(guò)編譯后就成為IL代碼。運行時(shí)CLR將IL語(yǔ)言編譯成CPU能識別的CRU指令。IL也可以叫做托管代碼,IL可以訪(fǎng)問(wèn)CLR所提供的所有功能。

3.什么是JIT,它是如何工作的?

即時(shí)編譯器,由CLR調用,負責將IL語(yǔ)言編譯成本地CPU指令。

工作原理:

當程序被第一次調用的時(shí)候,CLR會(huì )指向包含在CLR內部定義的特殊函數,這個(gè)函數就是JITCompiler。JITComliler負責將IL代碼編譯成本地指令。

JITCompiler知道實(shí)際調用了哪個(gè)方法,以及該方法是哪些類(lèi)型定義的。JITCompiler會(huì )在定義該類(lèi)型的程序集的元數據中查找該方法的IL代碼。

并將IL編譯成本地CPU指令。編譯好的結果被放在一個(gè)內存塊中,JITCompiler返回CLR為類(lèi)型定義的內部數據結構。找到被調用方法對應的那條記錄,

并修改最初對于JITCompiler的引用。讓其指向內存塊中被調用方法剛剛編譯好的CPU指令地址,最后執行被調用方法的CPU指令。

4.GC是什么,簡(jiǎn)述一下GC的工作方式?

垃圾回收(garbage collection)

Dot Net的垃圾回收可以分為兩個(gè)步驟,第一步進(jìn)行“標記”,垃圾回收器假設所有的對象都是垃圾,然后開(kāi)始遍歷每一個(gè)“根”(根包含指向引用類(lèi)型對象的一個(gè)指針,值類(lèi)型對象永遠不會(huì )被認為是一個(gè)根),如果發(fā)現一個(gè)根引用了一個(gè)對象(非NULL),就對對象進(jìn)行標記。沒(méi)有被標記的對象被認為是垃圾。第二個(gè)階段就是“壓縮”,其實(shí)就是將后面的對象移動(dòng)到已經(jīng)成為垃圾的對象位置,使得原來(lái)的托管堆更為緊湊。從而釋放了托管堆。

GC類(lèi)中的方法影響何時(shí)對對象進(jìn)行垃圾回收以及何時(shí)釋放對象所分配的資源。此類(lèi)中的屬性提供以下信息:系統可用內存總量、分配給對象的內存的周期類(lèi)別(代)。

GC跟蹤并回收托管內存中分配的對象。垃圾回收器定期執行垃圾回收以回收分配給沒(méi)有有效引用的對象的內存。當使用可用內存不能滿(mǎn)足內存請求時(shí),垃圾回收會(huì )自動(dòng)進(jìn)行;蛘,應用程序可以使用 Collect 方法強制進(jìn)行垃圾回收。

垃圾回收由以下步驟組成:

GC搜索托管代碼中引用的托管對象。

GC嘗試完成沒(méi)有被引用的對象。

GC釋放沒(méi)有被引用的對象并回收它們的內存。

在回收期間,如果GC在托管代碼中找到對某對象的一個(gè)或多個(gè)引用,則不會(huì )釋放該對象。然而,GC不識別非托管代碼中對對象的引用,因此,除非明確禁止,否則它有可能釋放非托管代碼中以獨占方式使用的對象。KeepAlive 方法提供一種機制,該機制可防止垃圾回收器回收在非托管代碼中仍使用的對象。

5.在.NET程序運行過(guò)程中,什么是堆,什么是棧?什么情況下會(huì )在堆(棧)上分配數據?它們有性能上的區別嗎?“結構”對象可能分配在堆上嗎?什么情況下會(huì )發(fā)生,有什么需要注意的?

.NET進(jìn)程被創(chuàng )建時(shí)就會(huì )有一個(gè)堆隨之被創(chuàng )建, 用來(lái)保存該進(jìn)程在運行中需要使用的對象/數據; 當一個(gè)線(xiàn)程被創(chuàng )建時(shí), 會(huì )有一個(gè)棧被創(chuàng )建,用來(lái)保存方法調用參數, 局部變量等輕量型數據.

當一個(gè)類(lèi)里面包含一個(gè)結構體類(lèi)型的變量時(shí), 該結構體類(lèi)型會(huì )被分配在堆上.

>泛型的作用是什么?它有什么優(yōu)勢?它對性能有影響嗎?它在執行時(shí)的行為是什么?.NET BCL中有哪些泛型類(lèi)型?舉例說(shuō)明平時(shí)編程中您定義的泛型類(lèi)型

泛型的作用是什么?

泛型的作用在于“算法的重用”。(這點(diǎn)其實(shí)很好理解,原來(lái)的ArrayList只能接受Object,現在通過(guò)List可以接受任何類(lèi)型,也就是說(shuō)ArrayList的方法都被各個(gè)類(lèi)型重用了。但是Dot Net的泛型有個(gè)比較制肘地方,就是你很難對數值類(lèi)型(值類(lèi)型)進(jìn)行算法抽象,因為這牽涉到運算符重載的問(wèn)題,同時(shí)Dot Net的泛型的類(lèi)型參數也不能約束成一個(gè)基元值類(lèi)型(如int、double、float) 。)

它有什么優(yōu)勢?

第一:源代碼保護。(如果你知道C++模板對泛型的實(shí)現機制,就會(huì )知道C++在編譯的時(shí)候根據對泛型的調用,自動(dòng)“內聯(lián)”了一個(gè)實(shí)現,這樣泛型的內容就暴露了,爾DotNet的實(shí)現方式就不同了,泛型類(lèi)和方法會(huì )被編譯成IL,在執行的時(shí)候由JIT負責將IL變化為指定類(lèi)型參數的本地代碼,從而保護了源代碼)

第二:類(lèi)型安全。(這點(diǎn)是最顯而易見(jiàn)的,拋棄了使用ArrayList時(shí)各種丑陋的強制類(lèi)型轉換)

第三:更清晰地代碼。因為沒(méi)有了強制類(lèi)型轉換,所以代碼自然顯得更清晰,但是使用泛型時(shí)候帶來(lái)的<>有時(shí)候確實(shí)也會(huì )讓人搞糊涂,幸好泛型方法可以用類(lèi)型推斷或者using語(yǔ)句來(lái)進(jìn)一步簡(jiǎn)化寫(xiě)法。

第四:更好的性能,因為值類(lèi)型可以避免裝箱和拆箱所帶來(lái)的損耗(垃圾回收的次數也會(huì )減少)。(這點(diǎn)正是泛型神奇的地方,開(kāi)發(fā)歷史上抽象能力的上升往往意味著(zhù)性能的下降,但是泛型卻不是!泛型抽象了算法,但是C++和DotNet對泛型的實(shí)現能夠讓性能無(wú)損,并且更快。Java的擦除法泛型就沒(méi)有這種性能上的好處。)

它對性能有影響嗎?

對性能有積極的影響,因為值類(lèi)型可以避免裝箱和拆箱所帶來(lái)的負面影響,避免了垃圾回收,使得性能顯著(zhù)提高。但是對引用類(lèi)型這種影響就不明顯了。但是需要注意的是首次為一個(gè)特定數據類(lèi)型調用方法時(shí),CLR都會(huì )為這個(gè)方法生成本地代碼。這會(huì )增大應用程序的工作集大小,從而影響性能。

它在執行時(shí)的行為是什么?

使用泛型類(lèi)型參數的一個(gè)方法在進(jìn)行JIT編譯時(shí),CLR獲取IL,用指定的類(lèi)型實(shí)參進(jìn)行替換,然后創(chuàng )建本地代碼。需要特別注意的是引用類(lèi)型是共享代碼的,而對值類(lèi)型就會(huì )為每一種生成獨立的一份類(lèi)型代碼。但是需要指出的是引用類(lèi)型的這種代碼共享并不會(huì )造成封閉類(lèi)型只執行一次構造函數(就算是靜態(tài)構造函數也是這樣的)。

.NET BCL中有哪些泛型類(lèi)型?

List、Dictionary、Queue、Stack、SortedList和SortedDictionary、LinkedList等等。

舉例說(shuō)明平時(shí)編程中您定義的泛型類(lèi)型。

泛型的出現會(huì )替換原來(lái)一部分使用多態(tài)的地方從而提高性能和帶來(lái)更好的編譯時(shí)檢查,這樣就不需要在子類(lèi)和超類(lèi)(接口)間頻繁轉換了。比如你要根據情況打出各種報表,那么先把報表類(lèi)定義成泛型類(lèi)從而可以共享報表一系列的算法。

> 異常的作用是什么?.NET BCL中有哪些常見(jiàn)的異常?在代碼中您是如何捕獲/處理異常的?在“catch (ex)”中,“throw”和“throw ex”有什么區別?您會(huì )如何設計異常的結構,什么情況下您會(huì )拋出異常?

異常的作用是什么?

異常用于處理系統級或者應用程序級的錯誤狀態(tài)。這就會(huì )引發(fā)另外幾個(gè)問(wèn)題,異常相比原來(lái)使用的返回錯誤代碼的優(yōu)點(diǎn)在哪里?異常處理是一種結構化的處理過(guò)程,個(gè)人認為他最大的優(yōu)點(diǎn)就在于將“成功場(chǎng)景”剝離出來(lái),使得代碼更加清晰自然。但是異常處理相對于返回錯誤碼有一個(gè)缺點(diǎn),那就是他會(huì )失去發(fā)生異常的位置。不過(guò)異常本身提供了很多幫助調試問(wèn)題的工具,一般都帶有棧跟蹤,這樣位置的問(wèn)題就得到一定程度的解決。還有就是IF和異常之間的選擇,我記得以前有人討論過(guò)在各種分支下是使用異常來(lái)處理各種“失敗場(chǎng)景”的分支還是使用IF或者SWITCH來(lái)處理呢?這其實(shí)是一個(gè)假問(wèn)題,因為異常和錯誤是有概念上的不同的,這里的錯誤是指有違“主成功場(chǎng)景”的“異常場(chǎng)景”,爾異常是指當程序不能完成其名字所表示功能時(shí)的錯誤。所以需要強調不要使用異常來(lái)區分各種失敗場(chǎng)景,異常壓根就不是用來(lái)干這件事情的!

.NET BCL中有哪些常見(jiàn)的異常?

隨便說(shuō)幾個(gè),最著(zhù)名的恐怕就是那句像繞口令一樣的“未將對象引用設置到對象實(shí)例”了,還有那些基本一出現整個(gè)應用程序就被判死刑的“堆棧溢出”、“內存無(wú)法分配”異常了。

在代碼中您是如何捕獲/處理異常的?

這道題的回答可以體現你是什么“級別”的程序員,這個(gè)級別倒不是說(shuō)水平的高低,是指經(jīng)常寫(xiě)哪一類(lèi)的程序,如果對異常的捕獲比較“激進(jìn)”(經(jīng)常捕獲異常)那么這個(gè)人應該是一個(gè)應用級的程序員。如果對捕獲異常比較謹慎那么應該是框架級別的程序員,這些人經(jīng)常寫(xiě)給別人使用的代碼,如果無(wú)故的使用異常處理來(lái)越俎代庖,那后果很?chē)乐亓,這里說(shuō)一個(gè)我經(jīng)歷的事,剛畢業(yè)的時(shí)候我和同事做一個(gè)WEB的項目,項目里用第三方的Grid,那個(gè)Grid在發(fā)生異常的時(shí)候會(huì )自己報一個(gè)錯誤,你知道我們有多傻眼了吧,我們需要的是我們來(lái)抓住異常,然后報出一句對用戶(hù)友好的錯誤,但是那個(gè)控件卻干了這么個(gè)蠢事。

我覺(jué)得普通程序員用的最多的CATCH就是抓住數據的異常,然后回滾數據庫來(lái)事務(wù)處理。這是一個(gè)典型的場(chǎng)景,因為你明確并且能夠很好的恢復狀態(tài)。

在“catch (ex)”中,“throw”和“throw ex”有什么區別?

throw 重新拋出異常但是不破壞異常發(fā)生的調用棧爾“throw ex”會(huì )重置調用棧這樣捕獲異常的人會(huì )以為代碼出錯在這里。

您會(huì )如何設計異常的結構,什么情況下您會(huì )拋出異常?

首先我會(huì )盡量的使用系統定義的那些異常,如果我需要處理某一特定類(lèi)別的異常,而且處理方式和通常處理方式不同那么就考慮自定義異常,還有如果需要調用方用一種統一的方式來(lái)處理異常那么自定義異常就是一個(gè)好的選擇。結構的話(huà)當然基類(lèi)是Sysytem.Exception,盡量使用扁平化異常的層次?梢钥紤]用泛型類(lèi)來(lái)定義異常。

我寫(xiě)的代碼不能完成名字所說(shuō)明的功能,那么我就會(huì )拋出異常。

> List和T[]的區別是什么,平時(shí)你如何進(jìn)行選擇?Dictionary是做什么的?.NET BCL中還有哪些常用的容器?它們分別是如何實(shí)現的(哪種數據結構)?分別是適用于哪些場(chǎng)景?

List和T[]的區別明顯有本質(zhì)的區別,List 是動(dòng)態(tài)分配內存的鏈表,

【.net面試題及詳解】相關(guān)文章:

2011最新asp.net面試題與答案07-11

資深HR詳解面試題的潛臺詞07-13

關(guān)于一道.NET程序員面試題的遐想07-13

WAP網(wǎng)絡(luò )與NET網(wǎng)絡(luò )的區別于定義!07-10

京東為什么在用.net07-11

面試題07-13

《濟南的秋天》詳解07-04

除夕的由來(lái)詳解07-04

房屋保險詳解07-13

牛軋糖的做法詳解08-04

99久久精品免费看国产一区二区三区|baoyu135国产精品t|40分钟97精品国产最大网站|久久综合丝袜日本网|欧美videosdesexo肥婆