作為一個.NET程序員,應該知道的不僅僅是拖拽一個控件到設計時窗口中。就像一個賽車手,一定要了解他的愛車 – 能做什么不能做什么。
本文參考Scott Hanselman給出的.NET問題列表,整理如下。包括WinForms,asp.net,xml以及C#和.NET基礎相關的問題,有興趣的自我檢測一下吧~
參考答案另附在文章末尾,由于水平有限,難免有謬誤,歡迎指正。
這里問的是強名稱概念。Assembly.Load("foo.dll")加載程序集的方法是否正確?
public class c{ public c(string a) : this() {;}; public c() {;} } 這個構造函數有用嗎?
· 什么叫作ViewState?是什么編碼?加密了嗎?到底是誰在使用ViewState?
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
一個程序至少有一個進程,一個進程至少有一個線程。線程的劃分尺度小于進程,使得多線程程序的并發性高。
這個解釋很形象:鏈接
Windows服務可以在計算機啟動時自動啟動,可以暫停和重新啟動而且不顯示任何用戶界面。
EXE 可執行程序通常有一個用戶界面,Console或 GUI,通常由用戶來啟動或停止。
以32位操作系統為例,最大尋址是4G(含虛擬內存),是通過2的32次方計算的; 當物理內存小于4G時,進程訪問的內存量隨著虛擬內存的增加而增加,直到4G; 4GB內存實際上包含了程序的所有部分--包括可執行代碼,代碼加載的所有dll,以及程序運行時使用的所有變量的內容。這個4GB內存稱為虛擬地址空間,或虛擬內存。
對設計有明顯影響的有2點:
在.NET中區別最明顯的是int的使用,在32位下和64位下存儲的數據不一樣(int 4個字節32位, 8個字節64位);另外一個是編譯的程序為X86則可在32、64位下同時運行。
DLL中雖然包含了可執行代碼卻不能單獨執行,而應由Windows應用程序直接或間接調用。EXE就不用說了吧~
強類型是指盡量早的檢查變量的類型, 通常在編譯的時候就檢查.
弱類型是指盡量推后對變量類型的檢查, 通常在運行時檢查。
到底哪個好? 其實各有各的好, 像ruby, javascript, 都屬于week-typing, 好處是寫代碼的時候比較快. C#屬于strong-typing, 好處是如果變量類型不對的話, 編譯不會通過, Visual Studio 還會有提示. 至于寫代碼的速度上講, 自從C# 3.0以來, 使用var來定義變量, 簡單了很多。
PID全稱是 Process Identifier, 就是進程的一個號碼, 通常當系統哪個程序不聽使喚的時候, 可以用它來把這個程序關閉. 而且Debug的時候, 也有用。
TCP/IP端口可以被多少個進程分享
Socket socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);Socket socket2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);socket1.Bind(new IPEndPoint(IPAddress.Parse(”127.0.0.1″),8235));socket1.Listen(10);socket2.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);socket2.Bind(new IPEndPoint(IPAddress.Parse(”127.0.0.1″), 8235));socket2.Listen(10);Console.Read();
GAC 是指 Global Assembly Cache, 用處是放在這里的程序集可以被多個程序共同調用, .NET 中的大部分程序集都在這里. 解決的問題是節省硬盤空間以及防止Dll Hell。
面向接口:定義要實現某類功能應該遵循的統一規范,而具體實現過程由實現該接口的類型決定。
面向對象:強調對具有相同行為和屬性事物的封裝,更注重封裝的完整性和功能的完整性。
面向方面:主要提供與業務邏輯無關的操作。比如系統中有多個地方都用到文件上傳功能,可以使用面向方面的思想在所有上傳文件之前對文件的大小、格式等信息進行過濾操作,而不是在每處上傳代碼里面完成對這些信息的過濾。
接口(Interface): 不能實列化,自己沒有狀態,方法也沒有具體的實現,被繼承時,繼承類需要實現接口的所有方法。接口就像租房時網上下載的一個租房合同模板。
類 (Class): 可以被實例化,有狀態,被繼承時,繼承類也不需要重新實現被繼承類中的方法。但是如果被繼承類的方法中有abstract修飾的,繼承類則需要實現這個方法。類像是已經被填上內容的租房合同的模板。
代碼在運行過程中動態獲取程序集的信息,對象的信息,或者直接調用對象的方法或屬性。 e.g. var i = 100; i.GetType(); 輸出System.Int32。
XML Web service: 是開放標準,使用Http/SOAP協議交互。
.NET Remoting: 是微軟自己的技術,只能在.NET里面使用。
early-binding: 是指編譯的時候綁定,late-binding是指運行時綁定。
動態引用。
Assembly.LoadFile只載入相應的dll文件,其他文件并不會被載入。
Assembly.LoadFrom會載入dll文件及其引用的其他dll
這里問的是強名稱概念。
它不是一個文件名,相比文件名,Assembly Qualified Name更能確定一個程序集,它包含文件名,但同時包含版本,公鑰,和區域。因為同樣一個名稱的文件可能有不同的版本和區域,此時單獨靠文件名稱,可能會造成不能確定程序集的正確性。
不對,正確方式為:Assembly.Load("foo, Version=1.0.2004.0, Culture=neutral, PublicKeyToken=8744b20f8da049e3")
通過簽發具有強簽名的程序集合,可以確保名稱的全局唯一性!因為強名稱是依賴于唯一的密鑰對來確保名稱的唯一性,其他人不會生成與你相同的程序集名稱(不同的私鑰產生的名稱不同)。強名稱保護程序集的版本沿襲,因為強名稱的唯一性能夠確保沒有其他人能夠生成你的程序集的后續版本。強名稱提供可靠的完整性檢查,通過.NET Framework安全檢查后,可以確保程序集內容在生成后未被更改過!
DateTime 不能為null。因為其為Struct,屬于值類型,值類型不能為null,只有引用類型才能被賦值null。
JIT(Just In Time),這是我們通過.NET編譯器生成的應用程序最終面向機器的編譯器
本機映像生成器 (Ngen) 是一種提高托管應用程序性能的工具。 Ngen.exe 創建本機映像(包含經編譯的特定于處理器的機器代碼的文件),并將它們安裝到本地計算機上的本機映像緩存中。運行時可從緩存中使用本機映像,而不必使用實時 (JIT) 編譯器編譯原始程序集。
由于 JIT 編譯器會在調用程序集中定義的單個方法時將該程序集的 MSIL 轉換為本機代碼,因而必定會對運行時的性能造成影響。在大多數情況下,這種性能影響是可以接受的。更為重要的是,由 JIT 編譯器生成的代碼會綁定到觸發編譯的進程上。它無法在多個進程之間進行共享。為了能在多個應用程序調用或共享一組程序集的多個進程之間共享生成的代碼,公共語言運行庫支持一種提前編譯模式。此提前編譯模式使用本機映像生成器 (Ngen.exe) 將 MSIL 程序集轉換為本機代碼,其作用與 JIT 編譯器極為相似。但是,Ngen.exe 的操作與 JIT 編譯器的操作有三點不同:
· 它在應用程序運行之前而不是運行過程中執行從 MSIL 到本機代碼的轉換。
· 它一次編譯一個完整的程序集,而不是一次編譯一個方法。
· 它將本機映像緩存中生成的代碼以文件的形式持久保存在磁盤上。
.NET的垃圾回收分為3代,可通過GC.Collect強制處理。
一個對象實例沒有被任何地方引用時就稱為垃圾,當內存不夠是GC就會將該對象實例占用的空間清理出來
Finalize只釋放非托管資源;
Dispose釋放托管和非托管資源
Finalize和Dispose共享相同的資源釋放策略,因此他們之間也是沒有沖突的。
有用,限定資源作用域并自動釋放。
IDisposable是一個接口,有一個方法Dispose(),可以在對象出作用域的時候調用,如在Using出界后調用這個接口。
列出所有使用符合引號內pattern的dll的進程.
In-proc 發生在一個進程之內, Out-of-proc 發生在不同進程之間。
.NET remoting
Xp : aspnet_Wp.exe
Windows 2000 : inetinfo.exe
Windows 2003 : w3wp.exe
一般使用DateTime.TryParse解析。
PDBs是源碼編譯文件-全稱Program Database,這個文件主要會存儲對應模塊(dll或者exe)內部的所有符號,以及符號對應的地址、文件名和行號。調試的時候應用程序和源文件之間的一個橋梁。
一種代碼復雜度的衡量標準。
可以用來衡量一個模塊判定結構的復雜程度,數量上表現為獨立現行路徑條數,也可理解為覆蓋所有的可能情況最少使用的測試用例數。圈復雜度大說明程序代碼的判斷邏輯復雜,可能質量低且難于測試和維護。程序的潛在風險和高的圈復雜度有著很大關系。
lock 關鍵字可確保當一個線程位于代碼的臨界區時,另一個線程不會進入該臨界區。 如果其他線程試圖進入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。
public class MySingleton {private static object myLock = new object();private static volatile MySingleton mySingleton = null;private MySingleton() {}public static MySingleton GetInstance() {if (mySingleton == null) { //第一次檢查lock (myLock) {if (mySingleton == null) { // 第二次檢查mySingleton = new MySingleton();}}}return mySingleton;}}
FullTrust即為完全信任,也稱為盲目信任.
GAC:有FullTrust權限
更加靈活的設置對代碼的訪問權限,實現代碼級保護,防止被移動代碼惡意利用
全局程序集緩存中如果有Corillian就更新該程序集,沒有就安裝。
顯示程序集的公鑰標記。
因DCOM的端口號是隨機分配的,默認情況下,會分配1024以上的端口號,所以默認情況下,DCOM不能穿越防火墻。
135是遠程過程調用(RPC)的默認端口
OOP是一種編程模型,將復雜的邏輯分解出小的模塊,特性是繼承,封裝和多態。而SOA是一個技術框架。 SOA的思想是將業務邏輯封裝成服務或者中間件提供給應用程序來調用,當然其組件化思想是繼承和發揚了OOP的優點。
XmlSerializer是將對象的屬性和字段進行序列化和反序列化的,序列化成為xml數據,反序列化再將xml轉換成對象。應該至少需要ACL權限中的讀權限。
因為try-catch有性能損失,在性能要求高的場景下,頻繁使用效果很差。同時,catch(Exception)后,可能會破壞程序的正常執行邏輯,導致閱讀、調試代碼難度增大。
Catch的時候應該捕捉具體的Exception類型,而不是通用的Exception
Debug只在debug狀態下會輸出,Trace在release下也會輸出,在release下Debug的內容會消失。Debug會產生pdb文件,release不會。
Debug和Release編譯產出物不一樣,Release下無調試信息,如Assert無法使用。對程序運行速度而言,無明顯區別。建議在開發環境下用Debug編譯,發布環境下用Release,為了使用Assert斷言。
方法,因對于一次運行,很可能只用到一個程序集中極少數類型和對象,而大部分可能并不會被使用。
接口(Interface)是用來定義行為規范的,不會有具體實現,而抽象類除定義行為規范外,可以有部分實現,但一個類能實現多個接口,但只能繼承一個基類。接口是是一種契約,定義了繼承它的類必須聲明接口中的方法。
區別:
接口只有方法、屬性、事件和索引符;類除了這四種成員之外還可以別的成員(如字段)。接口沒有構造函數,類有構造函數。
接口不能進行運算符的重載,類可以進行運算符重載。
接口的成員沒有任何修飾符,其成員總是公共的,而類的成員則可以有修飾符。派生于接口的類必須實現接口中所有成員的執行方式,而從類派生的則不然。
equals:比較兩個變量的內容是否相等
==:操作比較的是兩個變量的值是否相等,對于引用型變量表示的是兩個變量在堆中存儲的地址是否相同,即棧中的內容是否相同。
對象一致指的是引用相同。對象相等指的是內容相等。
深復制將會在新對象中創建引用類型字段引用的所有對象,改變新對象中引用的任何對象,不會影響到原來的對象中對應字段的內容。
ICloneable 接口可以提供創建現有對象中復制的自定義實現。
拆箱就是引用類型轉換為值類型,通常伴隨著從堆中復制對象實例的操作
裝箱就是值類型數據轉換為Object類型的引用對象
引用類型
把不參與序列化的對象標注出來,只序列化有用的數據,而不是序列化整個對象。去除沒必要的數據冗余,和提升序列化時的性能。
之所以說out參數不好,是因為通過out參數傳值,間接了破壞了封裝性和函數的可讀性。但筆者認為有的時候還是很實用很方便的。
可以。至少比較省事。
/// <summary>The EnableWindow Function.</summary> [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnableWindow(System.IntPtr hWnd, [MarshalAs(UnmanagedType.Bool)]bool enable);
override new在基類沒有virtual關鍵字的情況下必須使用。副作用是破壞了繼承關系。
virtual:virtual 關鍵字用于修飾方法、屬性、索引器或事件聲明,并使它們可以在派生類中被重寫。例如,此方法可被任何繼承它的類重寫。
sealed:當對一個類應用 sealed 修飾符時,此修飾符會阻止其他類從該類繼承。
override:要擴展或修改繼承的方法、屬性、索引器或事件的抽象實現或虛實現,必須使用 override 修飾符。
abstract:abstract 修飾符可以和類、方法、屬性、索引器及事件一起使用。在類聲明中使用 abstract 修飾符以指示某個類只能是其他類的基類。標記為抽象或包含在抽象類中的成員必須通過從抽象類派生的類來實現。
Foo.Bar: 程序集名稱
Version=2.0.205.0: 程序集版本
Culture=neutral: 區域
PublicKeyToken: 程序集public密鑰
public: 對任何類和成員都公開, 無限制訪問;
protected: 僅僅對該類以及該類的派生類公開;
private: 僅僅對該類公開;
internal: 只能值包含該類的程序集中訪問該類(只是單獨的項目,而不是整個解決方案)
主互操作程序集(PIA)指的是官方發布的互操作程序集,如果電腦中安裝了PIA,當你添加對類庫的引用時,那么Visual Studio會自動加載PIA,微軟為Office應用程序提供了PIA,如Excel PIA就是Microsof.Office.Interop.Excel.dll,其他應用程序也類似。詳見:http://msdn.microsoft.com/zh-cn/library/aax7sdch(v=vs.110).aspx
.NET 反射,為測試方法加了Attribute
throw e; //CLR認為這里是異常的起始點
throw; //CLR不會重新設置異常的起始點
Typeof()是運算符而GetType是方法
GetType()是基類System.Object的方法,因此只有建立一個實例之后才能夠被調用(初始化以后)
Typeof()的參數只能是int,string,String,自定義類型,且不能是實例
public class c{ public c(string a) : this() {;}; public c() {;} } 這個構造函數有用嗎?
先調用了this(),即無參構造函數,再調用了自身的有參的構造函數。
因為未對a參數進行處理,故無用。
This 用于調用當前實例,無法在 static 方法中調用 this。
aspx<form method=”post” action=”test.aspx”><input name=”Button1” type=”submit” /></form>Csprotected void Page_Load(object sender, EventArgs e){if (Request["Button1"] != null){//Button1_OnClick Function Code}}
頁面數據從客戶端通過Form的Post方法傳輸到服務器端的過程叫做PostBack。
· 什么叫作ViewState?是什么編碼?加密了嗎?到底是誰在使用ViewState?
保存服務器控件在PostBack時狀態不變的技術叫做ViewState。這些狀態信息被保存在前臺的hidden元素中。默認為Base64編碼,默認不會ViewState被加密。在頁面中所有開啟了ViewState的服務器控件會使用到它。 參考
Machinekey是添加在web.config中<system></system>之間的一個標簽。它保證cookies、viewstate加密解密時的數據不會被篡改。參考
Process:優點:進程內。速度比較快,但比較難適應大型應用。
ASP.NET State Service: ASP.NET狀態服務。速度,容量上折中。如果使用專用的狀態服務器則可以擴展。
SQL Server Session State Management: 速度較慢。但可靠性是最強的。而且也有很高的擴展性,適合大型應用。
當使用線程池中的線程進行異步請求操作時,多個請求間的線程是能夠重用的。每個HttpRequest都有自己的線程。當線程重用時,應該使用Thread Local存儲。
檢查ContentType即可。更安全的做法是解析HttpHandler。
用戶輸入URL,路由將該次請求轉到DNS服務器,DNS服務器將請求轉向URL所指向的服務器IP,如果IIS中某個站點包含所請求主機頭信息,則請求成功。
服務器在告訴客戶端,需要將需要一些服務器必要信息存成cookies保存在客戶端中,而每次客戶端訪問服務器時會將cookies中的信息通過請求發送給服務器。濫用的例子比如:Cookies中保存敏感信息,用戶密碼。
驗證用戶輸入的所有內容,保證服務器的安全性和健壯性。
Header共包括通用頭、請求消息、響應消息及消息實體等數據。
Get方法為URL傳值,POST為Form表單傳值。
200 訪問成功、301 永久重定向、302暫時重定向、304服務器已緩存、404訪問資源不存在、500服務器出錯、504 網關超時。
if-not-modified-since及 last-modified是保存在Request http header中的兩個信息,客戶端在訪問資源時,對比兩個信息,就能確定需要讀取緩存文件還是更新本地緩存文件。Response.Content.Headers
Explain <@OutputCache%> and the usage of VaryByParam, VaryByHeader.
VaryByCustom,我們可以自定義輸出緩存要求的任意文本。除了在OutputCache指令里面申明該屬性之外,我們還得在應用程序的 global.asax 文件的代碼聲明塊中,重寫GetVaryByCustomString 方法來為自定義字符串指定輸出緩存的行為。
Eg:
<%@ OutputCache VaryByParam="none" VaryByCustom="CategoryPageKey" Location="server" Duration="43200" %>
這里的VaryByCustom定義的為CategoryPageKey,那么在global.asax里面我們必須定義CategoryPageKey這個字符創輸出緩存的行為,見下面代碼。
public override string GetVaryByCustomString(HttpContext context, String arg){…}
提供避免元素命名沖突的方法
DOM是一種與瀏覽器,平臺,語言無關的接口,使你可以訪問頁面其他的標準組件。 DOM解決了Netscape的Javascript和Microsoft的Jscript之間的沖突,給予web設計師和開發者一個標準方法,讓他們來訪問他們站點中的數據、腳本和表現層對像。
DOM尺寸不受限制。
它由一組非專有的 Web 服務規范以及對這些旨在促進互操作性的規范的說明和修正組成
為相關Web服務更好的一起互操作的使用提供了實現的指導方針
<?xml version="1.0" encoding="UTF-8"?><note> <to>a</to> <from>b</from></note>
數據本身應當存儲在元素中,而有關數據的信息(元數據)應當存儲在屬性
屬性不能很好地保持原文的結構
元素允許包括元元數據(有關信息的更深層次的信息)。
每個人對元數據和非元數據的理解是不一樣的。
面對以后的變化,元素更具擴展性。
對于非常簡單并且不隨文檔改變其形式的信息,使用屬性較好。特別是樣式信息和鏈接信息,作為屬性執行起來很順利
格式完好的XML不是有效的xml
不僅要格式完好而且還要遵循一定的順序規則
格式完好的(well-formed)XML文檔包括:起始標簽和結束標簽應當匹配,結束標簽是必不可少的;大小寫應一致:XML對字母的大小寫是敏感的,和是完全不同的兩個標簽,所以結束標簽在匹配時一定要注意大小寫一致;元素應當正確嵌套:子元素應當完全包括在父輩元素中。
有效的(valid)XML文檔是指一個遵守XML語法規則,并遵守相應DTD文件規范的XML文檔。
XmlReaderSettings settings = new XmlReaderSettings();settings.ValidationEventHandler += new ValidationEventHandler(this.ValidationEventCallBack);settings.ValidationType = ValidationType.Schema;settings.Schemas serch= schemaSet;
這個會遞歸搜索全部的Document節點,通常消耗會比較大。除非真的需要檢索所有叫mynode的節點,那就比較好。
XmlReader 是一個只進、只讀的游標。 它提供了對輸入的快速和非緩存的流式訪問。 它可以讀取流或文檔。 它使用戶可以提取數據,并跳過對應用程序沒有意義的記錄。 較大的差異在于 SAX 模型是一個“推送”模型,其中分析器將事件推到應用程序,在每次讀取新節點時通知應用程序,而使用 XmlReader 的應用程序可以隨意從讀取器提取節點。
XPathDocument 類讀取 XML 文檔-在內存中的快速只讀表示形式
可編輯的 XmlDocument 類讀取 XML 文檔
XML片段通常不是一個完全符合標準的XML文檔,可能沒有根節點,比如:“<foo></foo><bar></bar>”。XML文檔通常有一個根節點和一些由標記組成的內容。比如:“<root><foo></foo><bar></bar></root>”
規范化形式的XML是XML規范的一個子集。任何XML文檔都可以轉換為規范化形式的XML,因此將特定類型的微小差異去除卻仍是該XML文檔。
XML InfoSet是W3C規范,用于描述一組數據集的抽象數據模型。XML DOM是InfoSet的一個實例。
DTD通過合法元素和屬性列表定義XML文檔的文檔結構。XSD描述XML文檔的文檔結構。
支持。設置XmlReaderSettings.DtdProcessing屬性為DtdProcessing.Parse。設置XmlReaderSettings.ValidationType屬性為ValidationType.DTD。
是的。
新聞熱點
疑難解答