)面試題

來源:互聯網
上載者:User

> 什麼是.NET?什麼是CLI?什麼是CLRIL是什嗎?JIT是什麼,它是如何工作的?GC是什麼,簡述一下GC的工作方式?

CLI是規範; CLR是對CLI的實現; .NET是基於CLR構建的一套架構;

開發人員需要通過IL與CLR進行交流, 雖然IL本身支援一些物件導向的概念, 但是對於開發人員來講還是過於複雜低效, 於是C#應運而生, 程式員只需編寫C#代碼, csc編譯器會將其翻譯成IL;

雖然CLR理解IL, 但是CPU只認識二進位指令, 所以CLR需要JIT的協助, 將IL翻譯成CPU指令. JIT按需工作, 當一個.NET方法即將被執行時, JIT會介入, 把該方法(IL指令) 編譯成CPU指令, 並儲存以供重用.

GC被用來回收當前進程中已無人使用的垃圾對象; GC會被某些事件觸發(比如, 0代對象滿, 記憶體壓力大, appdomain被卸載), 隨後遍曆GC堆上的對象, 並通過”該對象是否被root直接/間接引用 (更進一步, “一個對象是否可以被回收”還會依賴於F-Reachable Queue 和GC Handle Table”)來判斷一個對象是否需要被回收.

> 類(class)和結構(struct)的區別是什嗎?它們對效能有影響嗎?.NET BCL裡有哪些是類(結構),為什麼它們不是結構(類)?在自訂類型時,您如何選擇是類還是結構?

簡單說來, 類是參考型別, 結構是實值型別;

實值型別對象直接分配在當前線程的棧上, 參考型別對象位於GC堆上, 所以實值型別對象無法在多個方法中傳遞, 而參考型別會承擔更多的任務, 比如, 用於線程同步 (Monitor.Enter(…))當一個參考型別的對象被建立時, 會需要4+4=8個byte的額外空間開銷(32bit OS), 同時過度的使用參考型別對象會增加GC堆的壓力, 頻繁的GC對程式的效能還是有一些影響的.

BCL中的Byte類型是一個結構體, 至於為什麼它不是一個類, 我覺得可能是設計者認為Byte不應該被繼承, 或者8個byte的額外開銷無法承受吧.

什麼時候使用實值型別/參考型別還是應當具體情況具體分析, 對於參考型別, 能用sealed就sealed, 在方法調用時開銷會小一些.

> .NET程式運行過程中,什麼是堆,什麼是棧?什麼情況下會在堆(棧)上分配資料?它們有效能上的區別嗎?結構對象可能分配在堆上嗎?什麼情況下會發生,有什麼需要注意的?

.NET進程被建立時就會有一個堆隨之被建立, 用來儲存該進程在運行中需要使用的對象/資料; 當一個線程被建立時, 會有一個棧被建立,用來儲存方法調用參數, 局部變數等輕量型資料.

當一個類裡麵包含一個結構體類型的變數時, 該結構體類型會被分配在堆上. (不知道有什麼需要注意的…)

> 泛型的作用是什嗎?它有什麼優勢?它對效能有影響嗎?它在執行時的行為是什嗎?.NET BCL中有哪些泛型型別?舉例說明平時編程中您定義的泛型型別

泛型有利於演算法重用.

.NET進程地址空間中, 對象和類型是分開存放的, 當我們執行個體化一個泛型的時候 (比如List<int> list = new List<int>();), 會有一個新的類型對象被建立(該對象並不位於GC堆上), 當我們在使用這個執行個體化泛型去建立新的對象時, 才會有一個對象(GC堆上)被建立. 所以效能上會有些許的損失. 當我們使用一個實值型別作為參數,去調用一個接收參考型別參數的方法是, 會有裝箱發生, 這時我們可以考慮實現一個泛型, 並在運行時確定方法的參數類型.

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

呃, 異常可以通知我們程式出錯, 比如ArgumentException, NullReferenceException…

異常的發生會導致一次stack walk, 去尋找對應的exception handler, 在這個過程中, stack trace的資訊會被一層層的收集, throw ex會清空之前收集的stack trace的資訊, 相當於拋出了一個新的異常, 而throw不會, 所以throw ex不利於找出問題所在.

不同的layer應該catch不同exception, 最上層處理最general的exception, 底層去處理一些detail的exception.

> List<T>T[]的區別是什麼,平時你如何進行選擇?Dictionary<TKey, TValue>是做什麼的?.NET BCL中還有哪些常用的容器?它們分別是如何?的(哪種資料結構)?分別是適用於哪些情境?

T[] 繼承自Array, 而List<T>僅僅是對T[]的封裝; 相比於T[], List<T>的size是動態變化的.

Dictionary<TKey, TValue>可以用來儲存鍵/值對.其他的比如HashTable, SortedList等.

> 抽象類別和介面有什麼區別?使用時有什麼需要注意的嗎?如何選擇是定義一個完全抽象的抽象類別,還是介面?什麼是介面的顯式實現?為什麼說它很重要?

抽象類別定義了一個類及其子類是什麼, 而介面更多的表現出一個類可以做什麼.

當一個類實現連個不同的介面, 而這兩個介面中包含一些相同簽名的方法時需要用到顯示實現.

> 字串是參考型別類型還是結構類型?它和普通的參考型別相比有什麼特別的地方嗎?使用字串時有什麼需要注意的地方?為什麼說StringBuilder比較高效?在串連多個字串時,它無論何時都比直接相加更高效嗎?

String是參考型別, 其特殊之處在於一個string是不可變的, 當我們對兩個string使用串連操作時, 會產生一個新的string 對象, 而原來的兩個string保持不變.

在和native代碼做interop時, 對於傳出參數 (char* outStr), 應當選擇使用stringbuilder而非string.

StringBuilder內部維護著一個char[] 數組, 在做串連字元的操作時會動態增加其大小, 但是, 當原有的數組不夠用時, StringBuilder會重新建立一個新的char[]數組, 值得注意的是原來的數組不會被拋棄, 新建立的數組只會用作儲存新添加的字元.

如果說StringBuilder有”不高效”的話,應該就是在原有數組空間用盡的情況下吧.

> 如何高效地進行數組複製?二維數組數組的數組有什麼區別?在使用雙重迴圈遍曆一個二維數組時,如何選擇內外層的遍曆順序?

不清楚, 因為數組的元素在記憶體中的分布是連續的, 我能想到的方法是直接使用記憶體拷貝API.

二維數組是二維的, 數組的數組是一維的.

根據記憶體局部性原理, CPU在讀取二維數組的第一個元素是, 第一行的資料也會被一起讀入cache, 所以應當先遍曆行,隨後遍曆列.

> 什麼是.NET?什麼是CLI?什麼是CLRIL是什嗎?JIT是什麼,它是如何工作的?GC是什麼,簡述一下GC的工作方式?

CLI是規範; CLR是對CLI的實現; .NET是基於CLR構建的一套架構;

開發人員需要通過IL與CLR進行交流, 雖然IL本身支援一些物件導向的概念, 但是對於開發人員來講還是過於複雜低效, 於是C#應運而生, 程式員只需編寫C#代碼, csc編譯器會將其翻譯成IL;

雖然CLR理解IL, 但是CPU只認識二進位指令, 所以CLR需要JIT的協助, 將IL翻譯成CPU指令. JIT按需工作, 當一個.NET方法即將被執行時, JIT會介入, 把該方法(IL指令) 編譯成CPU指令, 並儲存以供重用.

GC被用來回收當前進程中已無人使用的垃圾對象; GC會被某些事件觸發(比如, 0代對象滿, 記憶體壓力大, appdomain被卸載), 隨後遍曆GC堆上的對象, 並通過”該對象是否被root直接/間接引用 (更進一步, “一個對象是否可以被回收”還會依賴於F-Reachable Queue 和GC Handle Table”)來判斷一個對象是否需要被回收. 具體細節還這真不是半個小時能講完的J

> 類(class)和結構(struct)的區別是什嗎?它們對效能有影響嗎?.NET BCL裡有哪些是類(結構),為什麼它們不是結構(類)?在自訂類型時,您如何選擇是類還是結構?

簡單說來, 類是參考型別, 結構是實值型別;

實值型別對象直接分配在當前線程的棧上, 參考型別對象位於GC堆上, 所以實值型別對象無法在多個方法中傳遞, 而參考型別會承擔更多的任務, 比如, 用於線程同步 (Monitor.Enter(…))當一個參考型別的對象被建立時, 會需要4+4=8個byte的額外空間開銷(32bit OS), 同時過度的使用參考型別對象會增加GC堆的壓力, 頻繁的GC對程式的效能還是有一些影響的.

BCL中的Byte類型是一個結構體, 至於為什麼它不是一個類, 我覺得可能是設計者認為Byte不應該被繼承, 或者8個byte的額外開銷無法承受吧.

什麼時候使用實值型別/參考型別還是應當具體情況具體分析, 個人傾向參考型別, 因為這樣在設計的時候會少費些腦子, 不過能用sealed就sealed, 在方法調用時開銷會小一些.

> .NET程式運行過程中,什麼是堆,什麼是棧?什麼情況下會在堆(棧)上分配資料?它們有效能上的區別嗎?“結構”對象可能分配在堆上嗎?什麼情況下會發生,有什麼需要注意的嗎?

.NET進程被建立時就會有一個堆隨之被建立, 用來儲存該進程在運行中需要使用的對象/資料; 當一個線程被建立時, 會有一個棧被建立,用來儲存方法調用參數, 局部變數等輕量型資料.

當一個類裡麵包含一個結構體類型的變數時, 該結構體類型會被分配在堆上. (不知道有什麼需要注意的…)

> 泛型的作用是什嗎?它有什麼優勢?它對效能有影響嗎?它在執行時的行為是什嗎?.NET BCL中有哪些泛型型別?舉例說明平時編程中您定義的泛型型別.

泛型有利於演算法重用.

.NET進程地址空間中, 對象和類型是分開存放的, 當我們執行個體化一個泛型的時候 (比如List<int> list = new List<int>();), 會有一個新的類型對象被建立(該對象並不位於GC堆上), 當我們在使用這個執行個體化泛型去建立新的對象時, 才會有一個對象(GC堆上)被建立. 所以效能上會有些許的損失. 當我們使用一個實值型別作為參數,去調用一個接收參考型別參數的方法是, 會有裝箱發生, 這時我們可以考慮實現一個泛型, 並在運行時確定方法的參數類型.

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

呃, 異常可以通知我們程式出錯, 比如ArgumentException, NullReferenceException…

異常的發生會導致一次stack walk, 去尋找對應的exception handler, 在這個過程中, stack trace的資訊會被一層層的收集, throw ex會清空之前收集的stack trace的資訊, 相當於拋出了一個新的異常, 而throw不會, 所以throw ex不利於找出問題所在.

不同的layer應該catch不同exception, 最上層處理最general的exception, 底層去處理一些detail的exception.

> List<T>T[]的區別是什麼,平時你如何進行選擇?Dictionary<TKey, TValue>是做什麼的?.NET BCL中還有哪些常用的容器?它們分別是如何?的(哪種資料結構)?分別是適用於哪些情境?

T[] 繼承自Array, 而List<T>僅僅是對T[]的封裝; 相比於T[], List<T>的size是動態變化的.

Dictionary<TKey, TValue>可以用來儲存鍵/值對.其他的比如HashTable, SortedList等.

> 抽象類別和介面有什麼區別?使用時有什麼需要注意的嗎?如何選擇是定義一個完全抽象的抽象類別,還是介面?什麼是介面的顯式實現?為什麼說它很重要?

抽象類別定義了一個類及其子類是什麼, 而介面更多的表現出一個類可以做什麼.

當一個類實現連個不同的介面, 而這兩個介面中包含一些相同簽名的方法時需要用到顯示實現.

> 字串是參考型別類型還是結構類型?它和普通的參考型別相比有什麼特別的地方嗎?使用字串時有什麼需要注意的地方?為什麼說StringBuilder比較高效?在串連多個字串時,它無論何時都比直接相加更高效嗎?

String是參考型別, 其特殊之處在於一個string是不可變的, 當我們對兩個string使用串連操作時, 會產生一個新的string 對象, 而原來的兩個string保持不變.

在和native代碼做interop時, 對於傳出參數 (char* outStr), 應當選擇使用stringbuilder而非string.

StringBuilder內部維護著一個char[] 數組, 在做串連字元的操作時會動態增加其大小, 但是, 當原有的數組不夠用時, StringBuilder會重新建立一個新的char[]數組, 值得注意的是原來的數組不會被拋棄, 新建立的數組只會用作儲存新添加的字元.

如果說StringBuilder有”不高效”的話,應該就是在原有數組空間用盡的情況下吧.

> 如何高效地進行數組複製?二維數組數組的數組有什麼區別?在使用雙重迴圈遍曆一個二維數組時,如何選擇內外層的遍曆順序?

不清楚, 因為數組的元素在記憶體中的分布是連續的, 我能想到的方法是直接使用記憶體拷貝API.

二維數組是二維的, 數組的數組是一維的.

根據記憶體局部性原理, CPU在讀取二維數組的第一個元素是, 第一行的資料也會被一起讀入cache, 所以應當先遍曆行,隨後遍曆列.

> 什麼是元編程,.NET有哪些元編程的手段和情境?什麼是反射?能否舉一些反射的常用情境?有人說反射效能較差,您怎麼看待這個問題?有什麼辦法可以提高反射的效能嗎

對元編程瞭解十分有限, .NET的CodeDom(或者使用reflection emit動態建立類型)應當是其中的一個情境.

基於中繼資料, 反射協助我們在運行時動態擷取程式集/類型/方法/屬性等等的資訊, 可以用於載入Addin.

有得必有失, 反射功能強大, 只要不是濫用, 其帶來的益處遠大於效能上的損失.

> 委託是什嗎?匿名方法是什嗎?在C# 3.0中,Lambda運算式是什嗎?擴充方法是什嗎?LINQ是什嗎?您覺得C# 3.0中還有哪些重要的特性,它們帶來了什麼優勢?BCL中哪些類庫和這些特性有關?您平時最常用哪些

委託可以認為是型別安全的函數指標, 此處省略741個字…

> 工作之外您看哪些技術相關的書、網站、社區、項目等等?您還接觸哪些.NET以外的技術,能和.NET.NET中有針對性的部分做個對比嗎

OneCode是個不錯的項目 <http://1code.codeplex.com/>

 

http://blog.csdn.net/Sento/archive/2011/03/06/6226381.aspx

題目來源:http://blog.zhaojie.me/2011/03/my-interview-questions-for-dotnet-programmers.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.