目錄
本次給大家介紹的是我收集以及自己個(gè)人保存一些.NET面試題
簡(jiǎn)介1.C# 值類型和引用類型的區(qū)別
2.如何使得一個(gè)類型可以在foreach 語(yǔ)句中使用
3.sealed修飾的類有什么特點(diǎn)
4.面向?qū)ο蟮?個(gè)基本特征
5. .NET 托管資源與非托管資源
6.string str=null與string str="" 有什么區(qū)別
7.StringBuilder有什么作用
8.序列化有何作用
9.Base64編碼用在何處
10.字符串池是如何提高系統(tǒng)性能的?
11.FileInfo 和 DirectoryInfo
12.DateTime.Parse(mystring) 這行代碼有什么問題
13.System.Object的三個(gè)比較方法異同
14.GetHashCode 方法有何作用帮寻?什么時(shí)候會(huì)用到該方法
15.委托的原理
16.委托回調(diào)靜態(tài)方法和實(shí)例方法有何區(qū)別
17. 什么是鏈?zhǔn)轿校?/a>
18.ASP.NET 運(yùn)行機(jī)制
19.C#中靜態(tài)變量和方法用什么用處
正文
回到頂部
本次給大家介紹的是我收集以及自己個(gè)人保存一些.NET面試題
回到頂部
簡(jiǎn)介
此次包含的不止是.NET知識(shí),也包含少許前端知識(shí)以及.net面試時(shí)所涉及的種種考點(diǎn)捧灰,希望能給找工作的同學(xué)們哪怕一點(diǎn)點(diǎn)幫助。
古人云“溫故而知新旧烧,可以為師矣”虚吟,本人工作三年有余邀摆,一直懶于寫博客,對(duì)已有的知識(shí)只存于云筆記中,還自欺欺人以為能加以善用间唉,可惜的是放到里面就不會(huì)再看绞灼,存筆記的習(xí)慣是有了,然而卻少有回去翻看的習(xí)慣呈野。久而久之低矮,越堆越多赶促,惡心循環(huán)躬柬,存的只是安心虹曙,而不是技術(shù)娇钱,為此橘券,我決定以后多寫博客亭病,不僅是存筆記蚁堤,還得是整理并發(fā)出來(lái)遭居,這樣才能真正地鞏固幔戏。
本文面向的閱讀讀者是
[x] 剛畢業(yè)的萌新
[x] 工作不久換工作同學(xué)
大怕曜罚看到估計(jì)是下面這張圖的這個(gè)表情了,所以闲延,可以在評(píng)論區(qū)給給意見啦233痊剖。
廢話少說(shuō),直入正題:
1.C# 值類型和引用類型的區(qū)別
區(qū)別
詳解
賦值時(shí)的區(qū)別
值類型的變量將直接獲得一個(gè)真實(shí)的數(shù)據(jù)副本垒玲,初值為0陆馁;而對(duì)引用類型的賦值僅僅是把對(duì)象的引用賦給變量,這樣就可能導(dǎo)致多個(gè)變量引用到一個(gè)實(shí)際對(duì)象實(shí)例上合愈,初值為null叮贩。
內(nèi)存分配的區(qū)別
值類型的對(duì)象會(huì)在堆棧上分配內(nèi)存,而引用類型的對(duì)象將會(huì)在堆上分配內(nèi)存佛析。堆棧的控件相對(duì)有限益老,但運(yùn)行效率卻比堆高得多。
來(lái)自繼承結(jié)構(gòu)的區(qū)別
由于所有的值類型都有一個(gè)共同的基類:System.ValueType寸莫,所以值類型擁有一些引用類型不具有的共同性質(zhì)捺萌。較為重要的一點(diǎn)是值類型的比較方法Equals 方法的實(shí)現(xiàn)有了改變。所有的值類型已經(jīng)實(shí)現(xiàn)了內(nèi)容的比較膘茎,而引用類型在沒有重寫Equals方法的情況下桃纯,仍然采用引用比較。
2.如何使得一個(gè)類型可以在foreach 語(yǔ)句中使用
1.若要循環(huán)訪問集合披坏,集合必須滿足特定的要求态坦。
例如,在下面的 foreach 語(yǔ)句中:
foreach (ItemType item in myCollection)
myCollection 必須滿足下列要求:
集合類型:
①.必須是 interface棒拂、class 或 struct伞梯。
②.必須包括返回類型的名為 GetEnumerator 的實(shí)例方法,例如 Enumerator。Enumerator 類型(類或結(jié)構(gòu))必須包含:一個(gè)名為 Current 的屬性壮锻,它返回 ItemType 或者可以轉(zhuǎn)換為此類型的類型。屬性訪問器返回集合的當(dāng)前元素涮阔。一個(gè)名為 MoveNext 的 bool 方法猜绣,它遞增項(xiàng)計(jì)數(shù)器并在集合中存在更多項(xiàng)時(shí)返回 true。
2.有三種使用集合的方法:
使用上述指導(dǎo)創(chuàng)建一個(gè)集合敬特。此集合只能用于 C# 程序掰邢。
使用上述指導(dǎo)創(chuàng)建一個(gè)一般集合,另外實(shí)現(xiàn) IEnumerable 接口伟阔。此集合可用于其他語(yǔ)言(如 Visual Basic)辣之。
在集合類中使用一個(gè)預(yù)定義的集合。
3.sealed修飾的類有什么特點(diǎn)
sealed 修飾符用于防止從所修飾的類派生出其它類皱炉。如果一個(gè)密封類被指定為其他類的基類怀估,則會(huì)發(fā)生編譯時(shí)錯(cuò)誤。
密封類不能同時(shí)為抽象類合搅。
sealed 修飾符主要用于防止非有意的派生多搀,但是它還能促使某些運(yùn)行時(shí)優(yōu)化。具體說(shuō)來(lái)灾部,由于密封類永遠(yuǎn)不會(huì)有任何派生類康铭,所以對(duì)密封類的實(shí)例的虛擬函數(shù)成員的調(diào)用可以轉(zhuǎn)換為非虛擬調(diào)用來(lái)處理。
// cs_sealed_keyword.csusing System;sealed class SealedClass{ public int x; public int y;} class MainClass{ static void Main() { SealedClass sc = new SealedClass(); sc.x = 110; sc.y = 150; Console.WriteLine("x = {0}, y = {1}", sc.x, sc.y); }}輸出x = 110, y = 150在前面的示例中赌髓,如果試圖通過使用下面的語(yǔ)句從密封類繼承:class MyDerivedC: MyClass {} // Error 將收到錯(cuò)誤信息:'MyDerivedC' cannot inherit from sealed class 'MyClass'.
4.面向?qū)ο蟮?個(gè)基本特征
封裝
名詞
簡(jiǎn)介
封裝
封裝是面向?qū)ο蟮奶卣髦淮犹伲菍?duì)象和類概念的主要特性。
封裝詳解:
也就是把客觀事物封裝成抽象的類锁蠕,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象操作夷野,對(duì)不可信的進(jìn)行信息隱藏。
繼承
名詞
簡(jiǎn)介
繼承
面向?qū)ο缶幊?(OOP) 語(yǔ)言的一個(gè)主要功能就是“繼承”匿沛。繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能扫责,并在無(wú)需重新編寫原來(lái)的類的情況下對(duì)這些功能進(jìn)行擴(kuò)展。
繼承詳解:
通過繼承創(chuàng)建的新類稱為“子類”或“派生類”逃呼。
被繼承的類稱為“基類”鳖孤、“父類”或“超類”。
繼承的過程抡笼,就是從一般到特殊的過程苏揣。
要實(shí)現(xiàn)繼承,可以通過“繼承”(Inheritance)和“組合”(Composition)來(lái)實(shí)現(xiàn)推姻。在某些 OOP 語(yǔ)言中平匈,一個(gè)子類可以繼承多個(gè)基類。但是一般情況下,一個(gè)子類只能有一個(gè)基類增炭,要實(shí)現(xiàn)多重繼承忍燥,可以通過多級(jí)繼承來(lái)實(shí)現(xiàn)。
繼承概念的實(shí)現(xiàn)方式有三類:實(shí)現(xiàn)繼承隙姿、接口繼承和可視繼承
實(shí)現(xiàn)繼承是指使用基類的屬性和方法而無(wú)需額外編碼的能力梅垄;
接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實(shí)現(xiàn)的能力输玷;
可視繼承是指子窗體(類)使用基窗體(類)的外觀和實(shí)現(xiàn)代碼的能力队丝。
在考慮使用繼承時(shí),有一點(diǎn)需要注意欲鹏,那就是兩個(gè)類之間的關(guān)系應(yīng)該是“屬于”關(guān)系机久。例如,Employee 是一個(gè)人赔嚎,Manager 也是一個(gè)人膘盖,因此這兩個(gè)類都可以繼承 Person 類。但是 Leg 類卻不能繼承 Person 類尽狠,因?yàn)橥炔⒉皇且粋€(gè)人衔憨。
抽象類僅定義將由子類創(chuàng)建的一般屬性和方法,創(chuàng)建抽象類時(shí)袄膏,請(qǐng)使用關(guān)鍵字 Interface 而不是 Class践图。OO開發(fā)范式大致為:劃分對(duì)象→抽象類→將類組織成為層次化結(jié)構(gòu)(繼承和合成) →用類與實(shí)例進(jìn)行設(shè)計(jì)和實(shí)現(xiàn)幾個(gè)階段。
多態(tài)
名詞
簡(jiǎn)介
多態(tài)
多態(tài)性(polymorphisn)是允許你將父對(duì)象設(shè)置成為和一個(gè)或更多的他的子對(duì)象相等的技術(shù)沉馆,賦值之后码党,父對(duì)象就可以根據(jù)當(dāng)前賦值給它的子對(duì)象的特性以不同的方式運(yùn)作。簡(jiǎn)單的說(shuō)斥黑,就是一句話:允許將子類類型的指針賦值給父類類型的指針揖盘。
實(shí)現(xiàn)多態(tài),有二種方式锌奴,覆蓋兽狭,重載:
覆蓋,是指子類重新定義父類的虛函數(shù)的做法鹿蜀。
重載箕慧,是指允許存在多個(gè)同名函數(shù),而這些函數(shù)的參數(shù)表不同(或許參數(shù)個(gè)數(shù)不同茴恰,或許參數(shù)類型不同颠焦,或許兩者都不同)。
那么往枣,多態(tài)的作用是什么呢伐庭?
我們知道粉渠,封裝可以隱藏實(shí)現(xiàn)細(xì)節(jié),使得代碼模塊化圾另;繼承可以擴(kuò)展已存在的代碼模塊(類)霸株;它們的目的都是為了——代碼重用。而多態(tài)則是為了實(shí)現(xiàn)另一個(gè)目的——接口重用集乔!多態(tài)的作用淳衙,就是為了類在繼承和派生的時(shí)候,保證使用“家譜”中任一類的實(shí)例的某一屬性時(shí)的正確調(diào)用饺著。
- .NET 托管資源與非托管資源
非托管資源
最常見的一類非托管資源就是包裝操作系統(tǒng)資源的對(duì)象,例如文件肠牲,窗口或網(wǎng)絡(luò)連接幼衰,對(duì)于這類資源雖然垃圾回收器可以跟蹤封裝非托管資源的對(duì)象的生存期,但它不了解具體如何清理這些資源缀雳。還好.net Framework提供了Finalize()方法渡嚣,它允許在垃圾回收器回收該類資源時(shí),適當(dāng)?shù)那謇矸峭泄苜Y源肥印。如果在MSDN Library 中搜索Finalize將會(huì)發(fā)現(xiàn)很多類似的主題识椰,
這里列舉幾種常見的非托管資源:ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Font,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,Timer,Tooltip 等等資源∩罴睿可能在使用的時(shí)候很多都沒有注意到腹鹉!
托管資源
像簡(jiǎn)單的int,string,float,DateTime等等,.net中超過80%的資源都是托管資源敷硅。
6.string str=null與string str="" 有什么區(qū)別
你定義了一個(gè)變量的引用str
string str=null 把這個(gè)引用指向了一個(gè)null功咒,沒有地址沒有值的地方,即沒分配內(nèi)存空間
string str="" 把這個(gè)引用指向了一個(gè)地址绞蹦,地址里面存的是空的字符力奋,即占用了內(nèi)存空間
7.StringBuilder有什么作用
簡(jiǎn)述:String 在進(jìn)行運(yùn)算時(shí)(如賦值、拼接等)會(huì)產(chǎn)生一個(gè)新的實(shí)例幽七,而 StringBuilder 則不會(huì)景殷。所以在大量字符串拼接或頻繁對(duì)某一字符串進(jìn)行操作時(shí)最好使用 StringBuilder,不要使用 String
另外澡屡,對(duì)于 String 我們不得不多說(shuō)幾句:
1.它是引用類型猿挚,在堆上分配內(nèi)存
2.運(yùn)算時(shí)會(huì)產(chǎn)生一個(gè)新的實(shí)例
3.String 對(duì)象一旦生成不可改變(Immutable)
4.定義相等運(yùn)算符(== 和 !=)是為了比較 String 對(duì)象(而不是引用)的值
總結(jié):StringBuilder采用構(gòu)造器設(shè)計(jì)模式的思想高效地構(gòu)造一個(gè)字符串對(duì)象,在構(gòu)造過程中StringBuilder 可以有效的避免臨時(shí)字符串對(duì)象的生成挪蹭。一旦 StringBuilder的ToString方法被調(diào)用后亭饵,最終的字符串就被生成,而隨后的操作將導(dǎo)致一個(gè)新的字符串對(duì)象的分配梁厉。因?yàn)樽址畬?duì)象的不可修改特性辜羊,StringBuilder還經(jīng)常被用來(lái)和非托管代碼交互踏兜。
8.序列化有何作用
簡(jiǎn)述:通過流類型可以方便地操作各種字節(jié)流,但如何把現(xiàn)有的實(shí)例對(duì)象轉(zhuǎn)換為方便傳輸?shù)淖止?jié)流八秃,就需要用到序列化的技術(shù)碱妆。
9.Base64編碼用在何處
簡(jiǎn)述:BASE64編碼是一種用于混淆明碼的編碼方式,其算法是把原先8位字節(jié)數(shù)組順序分配到新的6位字節(jié)數(shù)組中昔驱,再在每個(gè)字節(jié)的高2位填充0來(lái)組成新的8位字節(jié)數(shù)組疹尾。.NET中Convert 類型可以用來(lái)進(jìn)行Base64字符串和8位字節(jié)數(shù)組之間的轉(zhuǎn)換。
10.字符串池是如何提高系統(tǒng)性能的骤肛?
簡(jiǎn)述: 一旦使用了字符串池機(jī)制纳本,當(dāng)CLR啟動(dòng)的時(shí)候,會(huì)在內(nèi)部創(chuàng)建一個(gè)容器腋颠,容器的鍵是字符串內(nèi)容繁成,而值是字符串在托管堆上的引用。當(dāng)一個(gè)新的字符串對(duì)象需要分配時(shí)淑玫,CLR首先檢測(cè)內(nèi)部容器中是否已經(jīng)包含了該字符對(duì)象巾腕,如果已經(jīng)包含,則直接返回已經(jīng)存在的字符串對(duì)象引用:如果不存在絮蒿,則新分配一個(gè)字符串對(duì)象尊搬,同時(shí)把其添加到內(nèi)部容器里去。但是當(dāng)程序用new關(guān)鍵字顯式地申明新分配的一個(gè)字符串對(duì)象時(shí)土涝,該機(jī)制不會(huì)起作用佛寿。
11.FileInfo 和 DirectoryInfo
簡(jiǎn)述: .NET 內(nèi)建類型中提供了 FileInfo 和 DirectoryInfo 兩個(gè)類型,分別用來(lái)操作文件和文件夾但壮。有別于 File 和 Directory 類型狗准, FileInfo 和 Directory 主要的功能在于操作文件和文件夾在文件系統(tǒng)中的結(jié)構(gòu),完成諸如創(chuàng)建茵肃、復(fù)制腔长、讀取信息、移動(dòng)验残、判斷是否存在捞附、刪除等功能。
12.DateTime.Parse(mystring) 這行代碼有什么問題
簡(jiǎn)述: 使用 TryParse 可以避免異常您没。
示例string time="2013-02-02";DateTime t;if(DateTime.TryParse(s,out t)){ //輸出}
13.System.Object的三個(gè)比較方法異同
static bool ReferenceEquals(object A ,object B)static bool Equals(object A ,object B)virtual bool Equals(object obj)
1.ReferenceEquals 實(shí)現(xiàn)了類型的引用比較鸟召,從參數(shù)類型可以看出,它不僅可以用來(lái)比較兩個(gè)引用類型對(duì)象氨鹏,也可以用來(lái)比較兩個(gè)值類型對(duì)象欧募。當(dāng)然,ReferenceEquals 方法只有應(yīng)用在引用類型上時(shí)才會(huì)有意義仆抵,比較值類型的引用將永遠(yuǎn)返回false跟继,無(wú)論他們的值是否相等种冬。甚至與下面的例子:int i=0; Console.WriteLine(Object.ReferenceEquals(i,i));
解釋:因?yàn)樯厦娴膬蓚€(gè)i都是先進(jìn)行裝箱,然后傳遞給ReferenceEquals 方法舔糖。
2.Equals 是另外一個(gè)靜態(tài)比較方法娱两,它實(shí)現(xiàn)的功能根據(jù)不同的類型而有所不同。事實(shí)上金吗,Equals 方法的功能依靠了實(shí)例Equals 方法的實(shí)現(xiàn)十兢,概括地講,靜態(tài) Equals 方法的內(nèi)容分為兩步:首先檢查兩個(gè)對(duì)象是否恒等 (==)摇庙,然后調(diào)用其中一個(gè)參數(shù)對(duì)象的實(shí)例 Equals 方法來(lái)判斷兩個(gè)對(duì)象是否恒等旱物。
14.GetHashCode 方法有何作用?什么時(shí)候會(huì)用到該方法
簡(jiǎn)述:
Object 中 GetHashCode 的算法保證了同一對(duì)象返回同一 HashCode 卫袒,而不同對(duì)象則返回不同的 HashCode异袄,但對(duì)值類型等視內(nèi)容相等的對(duì)象為相等對(duì)象的類型時(shí),默認(rèn)的GetHashCode 算法并不正確玛臂。
重寫 GetHashCode 必須保證同一對(duì)象無(wú)論何時(shí)都返回同一 HashCode 值,而相等的對(duì)象也必須返回相同的值封孙,并且在此基礎(chǔ)上迹冤,保證 HasCode 盡量隨機(jī)地散列分布。
15.委托的原理
簡(jiǎn)述:委托是一類繼承自 System.Delegate的類型, 每個(gè)委托對(duì)象至少包含了一個(gè)指向某個(gè)方法的指 針,該方法可以是實(shí)例方法,也可以是靜態(tài)方法虎忌。委托實(shí)現(xiàn)了回調(diào)方法的機(jī)制,能夠幫助程序員 設(shè)計(jì)更加簡(jiǎn)潔優(yōu)美的面向?qū)ο蟪绦颉?br>
16.委托回調(diào)靜態(tài)方法和實(shí)例方法有何區(qū)別
簡(jiǎn)述:委托回調(diào)靜態(tài)方法和實(shí)例方法有何區(qū)別 當(dāng)委托綁定靜態(tài)方法時(shí),內(nèi)部的對(duì)象成員變量 _target將會(huì)被設(shè)置成 null,而當(dāng)委托綁定實(shí)例 方法時(shí), _target 將會(huì)設(shè)置成指向該實(shí)例方法所屬類型的一個(gè)實(shí)例對(duì)象, 當(dāng)委托被執(zhí)行時(shí), 該對(duì)象 實(shí)例將被用來(lái)調(diào)用實(shí)例方法泡徙。
- 什么是鏈?zhǔn)轿校?br>
簡(jiǎn)述:鏈?zhǔn)轿惺侵敢粋€(gè)委托的鏈表,而不是指另一類特殊的委托。 當(dāng)執(zhí)行鏈上的一個(gè)方法時(shí),后續(xù)委托方法將會(huì)被依次執(zhí)行膜蠢。System.Multicast Delegate定 義了對(duì)鏈?zhǔn)轿械闹С挚懊辍T赟ystem.Delegate的基礎(chǔ)上,它增加了一個(gè)指向后續(xù)委托的指針,這樣就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的鏈表結(jié)構(gòu)。
18.ASP.NET 運(yùn)行機(jī)制
1.瀏覽器和服務(wù)器的交互原理
通俗描述:我們平時(shí)通過瀏覽器來(lái)訪問網(wǎng)站挑围,其實(shí)就相當(dāng)于你通過瀏覽器去訪問一臺(tái)電腦上訪問文件一樣礁竞,只不過瀏覽器的訪問請(qǐng)求是由被訪問的電腦上的一個(gè) WEB服務(wù)器軟件來(lái)接收處理,它會(huì)分析接收到的請(qǐng)求信息杉辙,從而按照請(qǐng)求信息來(lái)找到服務(wù)器電腦上的文件模捂,經(jīng)過處理,最終將生成的內(nèi)容發(fā)回到瀏覽器蜘矢。
簡(jiǎn)單的說(shuō)就是:由瀏覽器生成一條“命令”狂男,通過互聯(lián)網(wǎng)發(fā)給另一臺(tái)電腦的某個(gè)軟件(服務(wù)器軟件);服務(wù)器軟件接收到“命令”品腹,就分析理解這個(gè)“命令”岖食,然后按照“命令”找到服務(wù)器電腦上的文件,將文件內(nèi)容發(fā)送回瀏覽器舞吭。
通過上圖泡垃,我們看到了瀏覽器和服務(wù)器交互的簡(jiǎn)單過程∥錾海現(xiàn)在,我們要想想兔毙,瀏覽器和服務(wù)器軟件到底是神馬東東唾琼,他們之間又是如何交互信息的呢?
其實(shí)澎剥,瀏覽器和服務(wù)器軟件锡溯,就是兩個(gè)獨(dú)立的應(yīng)用程序(就如qq、office哑姚、畫圖工具一樣)祭饭。那么兩個(gè)應(yīng)用程序之間要交互信息,就牽扯到了應(yīng)用程序通信的問題叙量。那他倆是使用神馬方式通信的呢倡蝙?
答案是套接字:Socket。至于Socket的具體用法和原理绞佩,篇幅問題不在此文中寫了寺鸥,先預(yù)留位置在這,下次補(bǔ)上《基于多線程和套接字的簡(jiǎn)易WebServer軟件-沒有控件的ASP.NET》品山。
瀏覽器和服務(wù)器軟件通過套接字來(lái)發(fā)送和接收對(duì)方的信息,但現(xiàn)在的關(guān)鍵問題是,他們發(fā)送和接收的到底是什么?--- 基于Http協(xié)議的報(bào)文數(shù)據(jù)(詳見《Http協(xié)議介紹---沒有控件的ASP.NET》)胆建。
也就是說(shuō):瀏覽器和服務(wù)器軟件其實(shí)就是兩個(gè)使用Socket進(jìn)行通信的的兩個(gè)應(yīng)用程序:雙方都發(fā)送按照 Http協(xié)議語(yǔ)法規(guī)范組織的數(shù)據(jù),接收到數(shù)據(jù)后都按照 Http協(xié)議語(yǔ)法規(guī)范來(lái)解釋肘交。
2.瀏覽器和IIS(or other webserver)交互機(jī)制
上圖就是IIS (服務(wù)器軟件)
1.瀏覽器和IIS交互過程:我們都知道笆载,在互聯(lián)網(wǎng)上確定一臺(tái)電腦的位置是使用IP尋址,但為什么當(dāng)我們平時(shí)訪問網(wǎng)站時(shí)直接輸入一個(gè)域名也能夠訪問到某個(gè)服務(wù)器電腦進(jìn)而由對(duì)方的服務(wù)器軟件發(fā)送響應(yīng)頁(yè)面數(shù)據(jù)給我呢涯呻?下面我把簡(jiǎn)單步驟列出:
(1)在瀏覽器輸入網(wǎng)址:www.oumind.com/index.html凉驻,瀏覽器按照Http協(xié)議語(yǔ)法 生成請(qǐng)求報(bào)文數(shù)據(jù)。
(2).瀏覽器檢查本機(jī)是否保存了www.oumind.com/index.html.域名對(duì)應(yīng)的服務(wù)器IP地址复罐。如果沒有涝登,則發(fā)送請(qǐng)求到所在城市網(wǎng)中最近的DNS服務(wù)器(域名解析服務(wù)器),它會(huì)根據(jù)我們發(fā)送來(lái)的域名查詢到該域名對(duì)應(yīng)的服務(wù)器IP地址效诅,并發(fā)送回瀏覽器缀拭。
(3)瀏覽器從DNS服務(wù)器獲得了 www.oumind.com/index.html域名對(duì)應(yīng)的服務(wù)器電腦IP,則將 請(qǐng)求報(bào)文 通過Socket發(fā)送到服務(wù)器電腦填帽。(注意:Http協(xié)議 規(guī)定服務(wù)器軟件使用的默認(rèn)端口是80蛛淋,通俗的說(shuō),就是如果瀏覽器訪問一個(gè)網(wǎng)站頁(yè)面篡腌,瀏覽器默認(rèn)就是將 請(qǐng)求報(bào)文 發(fā)送到服務(wù)器80端口褐荷,而服務(wù)器負(fù)責(zé)監(jiān)聽這個(gè)端口的軟件一般就是服務(wù)器軟件—比如asp.net用的IIS,java用的Tomcat嘹悼。)
(4)IIS接收到 請(qǐng)求報(bào)文叛甫,分析請(qǐng)求報(bào)文层宫,從中獲取請(qǐng)求的頁(yè)面路徑 /index.html。判斷頁(yè)面的后綴名其监,如果是靜態(tài)頁(yè)面(.html/.jpg/.css/.js等)萌腿,則直接由IIS軟件的組件讀取該文件內(nèi)容,并將內(nèi)容通過Socket發(fā)送回瀏覽器抖苦。
(5)但如果此時(shí)請(qǐng)求的是一個(gè)動(dòng)態(tài)頁(yè)面(.aspx/.ashx)毁菱,IIS自己就處理不了 (因?yàn)镮IS軟件開發(fā)出來(lái)的時(shí)候,ASP.NET程序還不存在呢) 锌历。所以贮庞,IIS就去它的 擴(kuò)展程序映射表 中根據(jù)被請(qǐng)求文件后綴名 查看是否有能夠處理這種文件的擴(kuò)展程序。
而我們ASPNET中常用的文件.aspx/.ashx等 對(duì)應(yīng)的處理程序是aspnet_isapi.dll究西。如下圖:
(6)如果IIS根據(jù)后綴名找到對(duì)應(yīng)的處理程序窗慎,則通過調(diào)用此程序來(lái)處理瀏覽器發(fā)送來(lái)的請(qǐng)求報(bào)文。
IIS自身是不能處理像ASPX擴(kuò) 展名這樣的頁(yè)面卤材,只能直接請(qǐng)求像HTML這樣的靜態(tài)文件遮斥,之所以能處理ASPX這樣擴(kuò)展名的頁(yè)面,是因?yàn)镮IS有一個(gè)ISAPI過濾器扇丛,它是一個(gè)COM組件术吗。
ASP.NET服務(wù)在注冊(cè)到IIS的時(shí)候,就會(huì)添加一個(gè)Win32的擴(kuò)展動(dòng)態(tài)庫(kù)aspnet_isapi.dll晕拆。并將擴(kuò)展可以處理的頁(yè)面擴(kuò)展名(如 ASPX)注冊(cè)到IIS里面。擴(kuò)展啟動(dòng)后材蹬,就根據(jù)定義好的方式來(lái)處理IIS所不能處理的頁(yè)面实幕。
當(dāng)客戶端請(qǐng)求一個(gè)服務(wù)器資源時(shí),這個(gè)HTTP請(qǐng)求會(huì)被inetinfo.exe進(jìn)程截獲(www服務(wù))堤器,然后Check請(qǐng)求資源的類型昆庇,并依據(jù)資源映射信息(存儲(chǔ)在IIS元庫(kù)中,一種IIS專用的配置數(shù)據(jù)庫(kù))將請(qǐng)求的資源分配給特定的處理程序模塊闸溃。若請(qǐng)求的是靜態(tài)資源(img,text,html等)則由IIS處理(IIS在本地Web Server上訪問請(qǐng)求的文件)整吆,將內(nèi)容輸出到控制臺(tái),發(fā)出請(qǐng)求的瀏覽器就能接收到它了辉川。
若需要在服務(wù)器端處理的請(qǐng)求表蝙,則會(huì)被傳到已注冊(cè)的擴(kuò)展模塊 中,aspx請(qǐng)求會(huì)被分配給aspnet_isapi.dll乓旗,讓這個(gè)程序開始處理代碼府蛇,生成標(biāo)準(zhǔn)的HTML代碼,然后將這些HTML加入到原有的 HTML中屿愚,最后把完整的HTML返回給IIS汇跨,IIS再把內(nèi)容發(fā)送到客戶瀏覽器务荆。
ASP.NET FrameWork對(duì)請(qǐng)求的處理:
上面說(shuō)到IIS將像ASPX這樣的頁(yè)面分配給aspnet_isapi.dll,接著處理如下:
1穷遂、aspnet_isapi.dll則會(huì) 通過一個(gè)Http PipeLine的管道將這個(gè)Http請(qǐng)求發(fā)給w3wp.exe(iis 工作者進(jìn)程函匕,IIS6.0中叫做 w3wq.exe,IIS5.0中叫做 aspnet_wp.exe)蚪黑,之后asp.net framework就會(huì)通過HttpRuntime來(lái)處理這個(gè)Http請(qǐng)求盅惜。
2、HttpRuntime首先會(huì)確定處理該請(qǐng)求的類名祠锣,HttpRuntime通過公共接口IHttpHandler來(lái)調(diào)用該類獲取被請(qǐng)求資源的類的實(shí)例酷窥。
3、調(diào)用HttpRuntime.ProcessRequest開始處理要發(fā)送到瀏覽器的頁(yè)面伴网,具體說(shuō)就是創(chuàng)建一個(gè)HttpContext實(shí)例蓬推,它封裝了所有與請(qǐng)求有關(guān)的http特有的信息,并初始化一個(gè)Write對(duì)象用于緩存標(biāo)記代碼澡腾。
4沸伏、HttpRuntime使用上下文信息查找或新建能處理該請(qǐng)求的WEB應(yīng)用程序的對(duì)象。由HttpApplication Factory負(fù)責(zé)返回HttpApplication實(shí)例动分。
5毅糟、HttpApplication實(shí)例會(huì)讀取web.config中所有HttpModule的配置。
6澜公、HttpApplication對(duì)象使用IHttpHandlerFactory類型的實(shí)例返回HttpHandler(http處理程序)給HttpRuntime對(duì)象姆另。一個(gè)頁(yè)面只是個(gè)http處理程序?qū)ο蟆?、最后由HttpRuntime對(duì)象調(diào)用IHttpHandler的頁(yè)面對(duì)象的ProcessRequest方法坟乾。
19.C#中靜態(tài)變量和方法用什么用處
1.靜態(tài)變量簡(jiǎn)介
在C#程序中迹辐,沒有全局變量的概念,這意味著所有的成員變量只有該類的實(shí)例才能操作這些數(shù)據(jù)甚侣,這起到了“信息隱藏”的作用明吩。但有些時(shí)候,這樣做卻不是個(gè)明智的選擇殷费。
假設(shè)我們要定義一個(gè)圖書類印荔,要求該類能保存圖書的數(shù)量,即每增加一本圖書(定義一個(gè)實(shí)例)详羡,圖書的數(shù)量應(yīng)該加1仍律。如果沒有靜態(tài)變量,我們需要將圖書的數(shù)量保存在每本圖書(實(shí)例)里实柠,然而染苛,這樣的變量要在不同圖書(實(shí)例)里重復(fù)存儲(chǔ),圖書(實(shí)例)數(shù)量少的話,我們還能接受茶行,如果圖書(實(shí)例)數(shù)量較多的話躯概,比如成千上萬(wàn),我們無(wú)法想象這要造成多少資源(如內(nèi)存畔师、磁盤空間)的浪費(fèi)娶靡,更讓人無(wú)法忍受的是:因?yàn)閳D書(實(shí)例)的數(shù)量要保存在每本圖書(實(shí)例)里,該值肯定是不同的看锉。要使這些圖書(實(shí)例)中保存的圖書(實(shí)例)數(shù)量一致姿锭,我們必須在每增加一本新書(生成一個(gè)新實(shí)例)時(shí),修改其他所有圖書(實(shí)例)中保存的該值伯铣。
Oh,My God!你會(huì)重新向往面向過程的程序設(shè)計(jì)方法呻此,向往擁有全局變量的時(shí)代。但腔寡,這種局面不會(huì)出現(xiàn)焚鲜,因?yàn)镃#中為你準(zhǔn)備好了另外一種變量類型:靜態(tài)變量。它在類中類似全局變量放前,保存類的公共信息忿磅,所有該類的實(shí)例(對(duì)象)共享該值。
靜態(tài)變量的聲明方式如下:
[訪問修飾符] static 數(shù)據(jù)類型 變量名;
這里的訪問修飾符跟類的其它成員一樣凭语,可以是public,protected,private或internal等葱她。
2.靜態(tài)變量又如何使用呢?
靜態(tài)變量必須使用類名來(lái)引用似扔,而不能使用類的實(shí)例吨些,因?yàn)椋o態(tài)變量不屬于任何實(shí)例炒辉,而是共有的豪墅。
我們可以打個(gè)比方:在一個(gè)班級(jí)中,有些物品是個(gè)人的辆脸,我們想使用時(shí)但校,必須指出物品的所有者螃诅,比如說(shuō)“王三的自行車”啡氢,在C#程序中我們可以使用:王三.自行車的格式。有些物品是大家共有的物品术裸,不能以個(gè)人名義使用倘是,而是用班級(jí)的名義使用,比如班集體出資買的籃球袭艺,只能說(shuō):“班級(jí)的籃球”搀崭,而不能說(shuō):“王三的籃球”。這絕對(duì)是不行的,這對(duì)其他人絕對(duì)是不公平的瘤睹,我們可以聯(lián)想到許多貪官污吏就是使用了不屬于自己的東西升敲,或以個(gè)人名義使用公家的東西而葬送了自己。
說(shuō)一句有用的就是:靜態(tài)變量是用類名來(lái)引用它轰传。即:類名.靜態(tài)變量名;
舉個(gè)具體的例子如下:
using System;class StaticVar { public int x; public static int y; public void PrintInfo() { Console.WriteLine("非靜態(tài)變量x={0}",x); Console.WriteLine("靜態(tài)變量y = {0}",y); } } class Test { static void Main(string[] args) { StaticVar stv = new StaticVar(); stv.x = 10; // stv.y = 20; //error;無(wú)法使用實(shí)例引用訪問靜態(tài)成員“StaticVar.y”驴党;改用類型名來(lái)限定它 StaticVar.y = 20; stv.PrintInfo(); } }
程序中被注釋的部分:stv.y = 20是使用實(shí)例引用靜態(tài)變量,這將引發(fā)錯(cuò)誤获茬。
另外港庄,我想說(shuō)一句,對(duì)于靜態(tài)變量在聲明時(shí)恕曲,如果沒有給出初始值或使用前沒有賦任何值的話鹏氧,系統(tǒng)會(huì)給他們一個(gè)默認(rèn)值:對(duì)于整型數(shù)據(jù)默認(rèn)值為0;單精度數(shù)據(jù)為:0.0f佩谣;雙精度數(shù)據(jù)為0.0把还;布爾型數(shù)據(jù)為False;引用型數(shù)據(jù)為null稿存。
3.靜態(tài)方法
靜態(tài)方法與靜態(tài)變量一樣笨篷,不屬于任何特定的實(shí)例,屬于類全體成員共有瓣履,由類名來(lái)調(diào)用率翅。
但要注意以下幾點(diǎn):
靜態(tài)方法只能訪問類的靜態(tài)成員,不能訪問類的非靜態(tài)成員袖迎;
非靜態(tài)方法可以訪問類的靜態(tài)成員冕臭,也可以訪問類的非靜態(tài)成員;
靜態(tài)方法不能使用實(shí)例來(lái)調(diào)用燕锥,只能使用類名來(lái)調(diào)用辜贵。
這里用一個(gè)具體的例子來(lái)說(shuō)明:
using System; namespace TestStatic { class StaticTest { int x; static int y; public StaticTest(int a,int b) { x = a; y = b; } public void SimplePrint() { Console.WriteLine("x="+x+",y="+y); } public static void StaticPrint() { Console.WriteLine("y={0}",y); // Console.WriteLine("x={0}",x); //靜態(tài)方法中不能使用非靜態(tài)成員 } } class Test { static void Main(string[] args) { StaticTest st = new StaticTest(10,23); st.SimplePrint(); //st.StaticPrint(); //靜態(tài)方法不能使用實(shí)例來(lái)調(diào)用 StaticTest.StaticPrint(); } } }
?