本人在網(wǎng)上結(jié)識(shí)的一個(gè)朋友,最近畢業(yè)去面試找工作片仿。佳谦。。
在這里我把他面試常被問(wèn)到的一些.net的面試題進(jìn)行了整合并附上了答案
1.什么是.NET滋戳?什么是CLI?什么是CLR啥刻?IL是什么奸鸯?
(1).net用于代碼編譯和執(zhí)行的集成托管環(huán)境,換句話可帽,它管理應(yīng)用程序運(yùn)行的方方面面娄涩,包括首次運(yùn)行的編譯,為程序分配內(nèi)存儲(chǔ)數(shù)據(jù)和指令,對(duì)于應(yīng)用程序授予或拒絕相應(yīng)的權(quán)限蓄拣,并啟動(dòng)管理應(yīng)用程序的執(zhí)行扬虚,剩余內(nèi)存的在分配。由于所有.net應(yīng)用程序 都是在.net framework上面執(zhí)行球恤,所以開(kāi)發(fā)人員只需考慮與.net framework打交道辜昵,而不必關(guān)系和底層操作系統(tǒng)上面的實(shí)現(xiàn)包括CLR和BCL
(2).CLI(common language infrastructure)公共語(yǔ)言基礎(chǔ)結(jié)構(gòu),一項(xiàng)國(guó)際性的標(biāo)準(zhǔn)咽斧,沒(méi)有規(guī)定標(biāo)準(zhǔn)具體如何實(shí)現(xiàn)堪置。相反,它描述了一個(gè)CLI平臺(tái)在符合標(biāo)準(zhǔn)的前提下應(yīng)該具有什么行為张惹。包含了:運(yùn)行時(shí)(CLR)舀锨,公共中間語(yǔ)言(CIL),公共類(lèi)型系統(tǒng)(CTS)宛逗,公共語(yǔ)言規(guī)范(CLS)坎匿,元數(shù)據(jù)(Metadata),框架(framework)
(3)CLR:公共語(yǔ)言運(yùn)行時(shí)雷激,負(fù)責(zé)加載和運(yùn)行程序
? ? IL:中間語(yǔ)言替蔬,C#編譯器將C#代碼轉(zhuǎn)換成IL,運(yùn)行時(shí)能夠理解IL侥锦,并編譯成機(jī)器碼
?2.JIT是什么进栽,它是如何工作的?GC是什么恭垦,簡(jiǎn)述一下GC的工作方式快毛?
JIT:Just in time,C#或者是VB.NET的代碼首先被編譯為IL存儲(chǔ)在本地,當(dāng)要運(yùn)行這些代碼的時(shí)候番挺,CLR對(duì)IL進(jìn)行第二次編譯轉(zhuǎn)換成機(jī)器碼運(yùn)行唠帝。好處:可移植性,而且IL在加載到內(nèi)存中時(shí)將受到類(lèi)型安全性方面檢查玄柏,這實(shí)現(xiàn)了更好的安全性和可靠性襟衰。
GC:垃圾回收(garbage collection),是根據(jù)程序的需要自動(dòng)分配和回收內(nèi)存的過(guò)程。垃圾回收器處理的是引用對(duì)象粪摘,而且只回收堆上的內(nèi)存瀑晒。這意味著假如維持對(duì)一個(gè)對(duì)象的引用,就會(huì)阻止GC重用對(duì)象使用的內(nèi)存徘意。在.NET中苔悦,垃圾回收器采用的是mark-and-compact算法。在一次垃圾回收周期開(kāi)始的時(shí)候椎咧,它要識(shí)別對(duì)象的所有跟引用玖详,根據(jù)這個(gè)引用可以遍歷每個(gè)根引用所標(biāo)識(shí)的一個(gè)樹(shù)形結(jié)構(gòu),并遞歸確定所有引用指向的對(duì)象。這樣一來(lái)蟋座,垃圾回收器就可以識(shí)別所有可達(dá)的對(duì)象拗踢,在執(zhí)行回收的時(shí)候,GC不是枚舉所有訪問(wèn)不到的對(duì)象向臀,相反巢墅,通過(guò)壓縮所有相鄰的可達(dá)的對(duì)象來(lái)執(zhí)行垃圾回收。不可訪問(wèn)的對(duì)象就會(huì)被覆蓋飒硅。垃圾回收的宗旨是提高內(nèi)存的利用率砂缩,它并不是用來(lái)清理文件句柄,和數(shù)據(jù)庫(kù)連接字符串三娩,端口或者其他有限的資源(終接器finalizer庵芭,不能被顯示調(diào)用,不能傳遞任何參數(shù)雀监,即不能被重載双吆,只有垃圾回收器才能調(diào)用終接器,使用Using語(yǔ)句進(jìn)行確定性終結(jié)
3.類(lèi)(class)和結(jié)構(gòu)(struct)的區(qū)別是什么会前?它們對(duì)性能有影響嗎好乐?
1. 值類(lèi)型與引用類(lèi)型
? 結(jié)構(gòu)是值類(lèi)型:值類(lèi)型在棧上分配地址,所有的基類(lèi)型都是結(jié)構(gòu)類(lèi)型瓦宜,例如:int 對(duì)應(yīng)System.int32
? 結(jié)構(gòu)蔚万,通過(guò)使用結(jié)構(gòu)可以創(chuàng)建更多的值類(lèi)型
? 類(lèi)是引用類(lèi)型:引用類(lèi)型在堆上分配地址堆棧的執(zhí)行效率要比堆的執(zhí)行效率高,可是堆棧的資源有限临庇,不適合處理大的邏輯復(fù)雜的對(duì)象反璃。所以結(jié)構(gòu)處理作為基類(lèi)型對(duì)待的小對(duì)象,而類(lèi)處理某個(gè)商業(yè)邏輯因?yàn)榻Y(jié)構(gòu)是值類(lèi)型所以結(jié)構(gòu)之間的賦值可以創(chuàng)建新的結(jié)構(gòu)假夺,而類(lèi)是引用類(lèi)型淮蜈,類(lèi)之間的賦值只是復(fù)制引用
注:1.雖然結(jié)構(gòu)與類(lèi)的類(lèi)型不一樣,可是他們的基類(lèi)型都是對(duì)象(object),c#中所有類(lèi)型的基類(lèi)型都是object
? 2.雖然結(jié)構(gòu)的初始化也使用了New 操作符可是結(jié)構(gòu)對(duì)象依然分配在堆棧上而不是堆上已卷,如果不使用“新建”(new)梧田,那么在初始化所有字段之前,字段將保持未賦值狀態(tài)侧蘸,且對(duì)象不可用
2.繼承性
? 結(jié)構(gòu):不能從另外一個(gè)結(jié)構(gòu)或者類(lèi)繼承裁眯,本身也不能被繼承,雖然結(jié)構(gòu)沒(méi)有明確的用sealed聲明讳癌,可是結(jié)構(gòu)是隱式的sealed .
? ? 類(lèi):完全可擴(kuò)展的未状,除非顯示的聲明sealed 否則類(lèi)可以繼承其他類(lèi)和接口,自身也能被繼承(注:雖然結(jié)構(gòu)不能被繼承可是結(jié)構(gòu)能夠繼承接口析桥,方法和類(lèi)繼承接口一樣)
? 3.內(nèi)部結(jié)構(gòu):
? ? 結(jié)構(gòu): 沒(méi)有默認(rèn)的構(gòu)造函數(shù),但是可以添加構(gòu)造函數(shù)沒(méi)有析構(gòu)函數(shù)沒(méi)有 abstract 和 sealed(因?yàn)椴荒芾^承)不能有protected 修飾符可以不使用new 初始化在結(jié)構(gòu)中初始化實(shí)例字段是錯(cuò)誤的
? ? 類(lèi): 有默認(rèn)的構(gòu)造函數(shù)有析構(gòu)函數(shù) 可以使用 abstract 和 sealed 有protected 修飾符 必須使用new 初始化
?4. .NET BCL里有哪些是類(lèi)(結(jié)構(gòu)),為什么它們不是結(jié)構(gòu)(類(lèi))泡仗?
結(jié)構(gòu):System.Boolean? Byte? Char? Decimal Double? Int32 堆棧的空間有限埋虹,對(duì)于大量的邏輯的對(duì)象,創(chuàng)建類(lèi)要比創(chuàng)建結(jié)構(gòu)好一些 大多數(shù)情況下該類(lèi)型只是一些數(shù)據(jù)時(shí)娩怎,結(jié)構(gòu)時(shí)最佳的選擇
類(lèi):String Object Delegate 接口 等等 包含了大量的邏輯對(duì)象搔课,表現(xiàn)抽象
5.在自定義類(lèi)型時(shí),您如何選擇是類(lèi)還是結(jié)構(gòu)截亦?
1). 堆棧的空間有限爬泥,對(duì)于大量的邏輯的對(duì)象,創(chuàng)建類(lèi)要比創(chuàng)建結(jié)構(gòu)好一些
2). 結(jié)構(gòu)表示如點(diǎn)崩瓤、矩形和顏色這樣的輕量對(duì)象袍啡,例如,如果聲明一個(gè)含有 1000
個(gè)點(diǎn)對(duì)象的數(shù)組却桶,則將為引用每個(gè)對(duì)象分配附加的內(nèi)存境输。在此情況下,結(jié)構(gòu)的成本較低颖系。
3). 在表現(xiàn)抽象和多級(jí)別的對(duì)象層次時(shí)嗅剖,類(lèi)是最好的選擇
4). 大多數(shù)情況下該類(lèi)型只是一些數(shù)據(jù)時(shí),結(jié)構(gòu)時(shí)最佳的選擇
6.在.NET程序運(yùn)行過(guò)程中嘁扼,什么是堆信粮,什么是棧?
棧通常保存著我們代碼執(zhí)行的步驟趁啸,而堆上存放的則多是對(duì)象强缘,數(shù)據(jù)等。我們可以把棧想象成一個(gè)接著一個(gè)疊放在一起的盒子莲绰。當(dāng)我們使用的時(shí)候欺旧,每次從最頂部取走一個(gè)盒子。棧也是如此蛤签,當(dāng)一個(gè)方法(或類(lèi)型)被調(diào)用完成的時(shí)候辞友,就從棧頂取走(called a Frame,譯注:調(diào)用幀)震肮,接著下一個(gè)称龙。堆則不然,像是一個(gè)倉(cāng)庫(kù)戳晌,儲(chǔ)存著我們使用的各種對(duì)象等信息鲫尊,跟棧不同的是他們被調(diào)用完畢不會(huì)立即被清理掉。
棧內(nèi)存無(wú)需我們管理沦偎,也不受GC管理疫向。當(dāng)棧頂元素使用完畢咳蔚,立馬釋放。而堆則需要GC(Garbage collection:垃圾收集器)清理
## 7.什么情況下會(huì)在堆(棧)上分配數(shù)據(jù)搔驼?它們有性能上的區(qū)別嗎谈火?“結(jié)構(gòu)”對(duì)象可能分配在堆上嗎?什么情況下會(huì)發(fā)生舌涨,有什么需要注意的嗎糯耍?
1)值類(lèi)型一般分配在對(duì)上面,引用類(lèi)型分配在堆上面囊嘉。棧的效率要高于堆温技。
2)可能,當(dāng)在類(lèi)中定義一個(gè)結(jié)構(gòu)類(lèi)型時(shí)扭粱,該結(jié)構(gòu)就分配在堆上
8.泛型的作用是什么舵鳞?它有什么優(yōu)勢(shì)?它對(duì)性能有影響嗎焊刹?它在執(zhí)行時(shí)的行為是什么系任?
作用:為了促進(jìn)代碼的重用,尤其是算法的重用
優(yōu)勢(shì):
(1)可重用性
(2)類(lèi)型安全虐块,在參數(shù)化的類(lèi)中只有成員明確希望的數(shù)據(jù)類(lèi)型才可以使用
(3)性能:避免了從Object的強(qiáng)制轉(zhuǎn)換和值類(lèi)型的裝箱
(4)減小了內(nèi)存消耗:避免裝箱也就不在需要消耗堆上的內(nèi)存俩滥。
執(zhí)行時(shí)的行為:泛型也是對(duì)象,泛型類(lèi)的“類(lèi)型參數(shù)”變成了元數(shù)據(jù)贺奠;CLR會(huì)在需要的時(shí)候構(gòu)造利用它們的類(lèi)霜旧。一個(gè)泛型類(lèi)經(jīng)過(guò)編譯好之后和普通的類(lèi)并沒(méi)有什么區(qū)別。編譯的結(jié)果只有元數(shù)據(jù)和CIL儡率」揖荩基于值類(lèi)型的泛型實(shí)例化:CLR會(huì)講指定的類(lèi)型參數(shù)放到CIL中合適的位置,從而創(chuàng)建一個(gè)具體化的泛型類(lèi)型儿普。所以CLR會(huì)為沒(méi)個(gè)新的參數(shù)值創(chuàng)建具體的泛型類(lèi)型
基于引用類(lèi)型的實(shí)例化:CLR會(huì)創(chuàng)建一個(gè)具體化的泛型類(lèi)型崎逃。以后,每次用一個(gè)引用類(lèi)型參數(shù)來(lái)說(shuō)實(shí)例化一個(gè)構(gòu)造好的類(lèi)型時(shí)眉孩,并在CIL中用Object引用替換類(lèi)型參數(shù)个绍,CLR都會(huì)重用以前生成好的泛型版本
9. .NET BCL中有哪些泛型類(lèi)型?舉例說(shuō)明平時(shí)編程中您定義的泛型類(lèi)型浪汪。
**List<T>**:通過(guò)索引訪問(wèn)強(qiáng)類(lèi)型的列表
**Dictionary<T>**:表示鍵值對(duì)的集合
**Queue<T>**:隊(duì)列? Stack<T>: 棧
購(gòu)物車(chē)用Dictionary模擬巴柿,OA中獲取員工列表等數(shù)據(jù)的時(shí)候,返回值是泛型的
10.異常的作用是什么死遭?.NET BCL中有哪些常見(jiàn)的異常广恢?在代碼中您是如何捕獲/處理異常的?在“catch (ex)”中呀潭,“throw”和“throw ex”有什么區(qū)別钉迷?您會(huì)如何設(shè)計(jì)異常的結(jié)構(gòu)至非,什么情況下您會(huì)拋出異常?
(1)C# 語(yǔ)言的異常處理功能可幫助您處理程序運(yùn)行時(shí)出現(xiàn)的任何意外或異常情況
(2)throw會(huì)保留堆棧信息糠聪。throw ex 不會(huì)睡蟋。當(dāng)然,如果你拋出新的異常之前設(shè)置innerException的話枷颊,可以通過(guò)innerException的堆棧訪問(wèn)原有的堆棧。
(3)靠異常才能發(fā)現(xiàn)錯(cuò)誤的该面,通過(guò)try catch finally來(lái)捕獲異常夭苗。如果是未預(yù)料到的則不處理(內(nèi)存不足,刪除文件)直接報(bào)錯(cuò)更容易發(fā)現(xiàn)錯(cuò)誤catch塊從最具體到常規(guī)排列
11.List<T>和T[]的區(qū)別是什么隔缀,平時(shí)你如何進(jìn)行選擇题造?Dictionary<TKey, TValue>是做什么的?.NET BCL中還有哪些常用的容器猾瘸?它們分別是如何實(shí)現(xiàn)的(哪種數(shù)據(jù)結(jié)構(gòu))界赔?分別是適用于哪些場(chǎng)景?
1.List<T>arrylist的泛型版本牵触,大小是可變的淮悼,T[]繼承自Array,大小是固定的。如果大小沒(méi)有怎么變化揽思,選擇T[],一般情況下選擇List<T>
2.Dictionary是hashtable的泛型版本袜腥,用來(lái)存儲(chǔ)鍵值對(duì)的.例如:sortlist,stack等
12.抽象類(lèi)和接口有什么區(qū)別钉汗?使用時(shí)有什么需要注意的嗎羹令?
如何選擇是定義一個(gè)“完全抽象”的抽象類(lèi),還是接口损痰?什么是接口的“顯式實(shí)現(xiàn)”福侈?為什么說(shuō)它很重要?
相同點(diǎn):都不能被直接實(shí)例化卢未,都通過(guò)繼承實(shí)現(xiàn)其抽象方法
不同點(diǎn):
(1) 接口支持多繼承肪凛;抽象類(lèi)不能實(shí)現(xiàn)多繼承。
(2) 接口只能定義行為尝丐;抽象類(lèi)既可以定義行為显拜,還可能提供實(shí)現(xiàn)。
(3) 抽象類(lèi)允許包含實(shí)現(xiàn)的virtual成員爹袁,所以能為派生類(lèi)成員提供一個(gè)默認(rèn)的實(shí)現(xiàn)远荠,而接口所有的成員自動(dòng)成為virtual成員,而且不能包含任何實(shí)現(xiàn)
13.字符串是引用類(lèi)型類(lèi)型還是結(jié)構(gòu)類(lèi)型失息? 引用類(lèi)型
它和普通的引用類(lèi)型相比有什么特別的地方嗎譬淳?不可變的
使用字符串時(shí)有什么需要注意的地方档址?為什么說(shuō)StringBuilder比較高效?
當(dāng)拼接兩個(gè)字符串時(shí)邻梆,系統(tǒng)先是把兩個(gè)字符串寫(xiě)入內(nèi)存守伸,接著刪除原來(lái)的String對(duì)象,然后創(chuàng)建一個(gè)String對(duì)象浦妄,并讀取內(nèi)存中的數(shù)據(jù)賦給該對(duì)象尼摹。這一來(lái)二去的,耗了不少時(shí)間剂娄。而使用System.Text命名空間下面的StringBuilder類(lèi)就不是這樣了蠢涝,它提供的Append方法,能夠在已有對(duì)象的原地進(jìn)行字符串的修改阅懦,簡(jiǎn)單而且直接和二。
在連接多個(gè)字符串時(shí),它無(wú)論何時(shí)都比直接相加更高效嗎耳胎?
不一定惯吕,在1000個(gè)字符以?xún)?nèi)效果一樣,達(dá)到10000時(shí)StringBuilder類(lèi)的效率會(huì)顯著提升
如何高效地進(jìn)行數(shù)組復(fù)制怕午?“二維數(shù)組”和“數(shù)組的數(shù)組”有什么區(qū)別废登?
數(shù)組復(fù)制的方法:for? CopyTo()? 靜態(tài)CopyTo()? Clone
14.什么是元編程,.NET有哪些元編程的手段和場(chǎng)景诗轻?什么是反射钳宪?能否舉一些反射的常用場(chǎng)景?有人說(shuō)反射性能較差扳炬,您怎么看待這個(gè)問(wèn)題吏颖?有什么辦法可以提高反射的性能嗎?
學(xué)著做OA的時(shí)候恨樟,動(dòng)態(tài)加載不同的DataProvider(Oracle和Sqlserver)半醉,方便,可以隨時(shí)替換不用重新編譯程序
15.委托是什么劝术?匿名方法是什么缩多?在C# 3.0中,Lambda表達(dá)式是什么养晋?擴(kuò)展方法是什么衬吆?LINQ是什么?您覺(jué)得C# 3.0中還有哪些重要的特性绳泉,它們帶來(lái)了什么優(yōu)勢(shì)逊抡?BCL中哪些類(lèi)庫(kù)和這些特性有關(guān)?您平時(shí)最常用哪些零酪?
委托可以把一個(gè)方法作為參數(shù)代入另一個(gè)方法冒嫡。
委托可以理解為指向一個(gè)函數(shù)的指針拇勃。
匿名方法:就是沒(méi)有實(shí)際方法聲明的委托實(shí)例⌒⒘瑁或者說(shuō)方咆,它們的定義是直接內(nèi)嵌在代碼中的。
Lambda表達(dá)式:是比匿名方法更加簡(jiǎn)潔的一種匿名函數(shù)語(yǔ)法,委托和事件沒(méi)有可比性蟀架,因?yàn)槲惺穷?lèi)型瓣赂,事件是對(duì)象,下面說(shuō)的是委托的對(duì)象(用委托方式實(shí)現(xiàn)的事件)和(標(biāo)準(zhǔn)的event方式實(shí)現(xiàn))事件的區(qū)別片拍。事件的內(nèi)部是用委托實(shí)現(xiàn)的钩述。因?yàn)閷?duì)于事件來(lái)講,外部只能“注冊(cè)自己+=穆碎、注銷(xiāo)自己-=”,外界不可以注銷(xiāo)其他的注冊(cè)者职恳,外界不可以主動(dòng)觸發(fā)事件所禀,因此如果用Delegate就沒(méi)法進(jìn)行上面的控制,因此誕生了事件這種語(yǔ)法放钦。事件是用來(lái)閹割委托實(shí)例的色徘,類(lèi)比用一個(gè)自定義類(lèi)閹割List。事件只能add操禀、remove自己褂策,不能賦值。事件只能+=颓屑、-=斤寂,不能= 。事件內(nèi)部就是一個(gè)private的委托和add揪惦、remove兩個(gè)方法遍搞。
16.工作之外您看哪些技術(shù)相關(guān)的書(shū)、網(wǎng)站器腋、社區(qū)溪猿、項(xiàng)目等等?
您還接觸哪些.NET以外的技術(shù)纫塌,能和.NET或.NET中有針對(duì)性的部分做個(gè)對(duì)比嗎诊县?
C#本質(zhì)論,SQL Server2008實(shí)戰(zhàn)措左,數(shù)據(jù)結(jié)構(gòu)依痊,ASP.NET揭秘,Javascript深入淺出
17.website和webapplication的區(qū)別
1)website修改后不需要重啟即可看到效果媳荒,webapplication需要
2)website不分namespace抗悍,webapplication有namespace
3)website為了兼容asp轉(zhuǎn)過(guò)來(lái)的開(kāi)發(fā)人員習(xí)慣
4)沒(méi)有技術(shù)上的區(qū)別驹饺,調(diào)試習(xí)慣不同
5)website為每個(gè)編譯為一個(gè)dll,webapplication生成一個(gè)dll
6)不利于工程開(kāi)發(fā)缴渊,比如代碼出錯(cuò)不容易發(fā)現(xiàn)
18.提交到服務(wù)器的表單要設(shè)置name赏壹,id可以不設(shè)置,服務(wù)器只用name衔沼,Dom用id
19.為了區(qū)分是第一次進(jìn)入頁(yè)面還是點(diǎn)擊提交以后重新進(jìn)入蝌借,form有一個(gè)隱藏字段:
<input type=“hidden” name=“ispostback” value=“true”/>,如果從Request中讀取到ispostback=true,說(shuō)明點(diǎn)擊提交按鈕提交進(jìn)入ashx指蚁,否則是第一次進(jìn)入ashx
20.Http是請(qǐng)求-響應(yīng)模型菩佑,服務(wù)器不會(huì)讀取瀏覽器的網(wǎng)頁(yè),能夠得到的就是網(wǎng)頁(yè)提交過(guò)來(lái)的數(shù)據(jù)凝化。
21.get與post提交的比較
Get:通過(guò)URL傳遞表單的值(默認(rèn))稍坯,?...&,安全性低搓劫,傳遞比較小的數(shù)據(jù)瞧哟。
Post:傳遞的值隱藏在http報(bào)文中,URL中看不到枪向,刷新頁(yè)面會(huì)彈出提示對(duì)話框如果
22. 實(shí)現(xiàn)div內(nèi)文本自增勤揩,因?yàn)榉?wù)器不記得上次給瀏覽器的值是多少,而且不像input那樣會(huì)將上次的值重新提交回來(lái)秘蛔,因此瀏覽器需要用一個(gè)隱藏的字段將上次的值保存下來(lái)
23.ViewState實(shí)現(xiàn)原理
非表單元素?zé)o法將客戶(hù)端的元素值傳遞給服務(wù)端陨亡,即使是表單元素也只能傳遞value值,對(duì)于其他屬性值深员,比如背景顏色负蠕,大小等也是無(wú)法傳遞的,因此對(duì)于這些值都要存在隱藏字段中倦畅。Viewstate是跟頁(yè)面相關(guān)的虐急,不用的頁(yè)面viewstate也會(huì)不同,不會(huì)相互影響滔迈。ViewState對(duì)需要PostBack處理的頁(yè)面才可能有用止吁,對(duì)于新聞?wù)故具@類(lèi)頁(yè)面不需要交互,完全可以禁用ViewState來(lái)提升性能燎悍。如果完全沒(méi)有ViewState敬惦,則頁(yè)面中不能有runat=server的form
24.Cookie
表單是和頁(yè)面相關(guān)的,只有瀏覽器提交了這些數(shù)據(jù)服務(wù)器才能得到谈山,Cookie是和站點(diǎn)相關(guān)的俄删,每次向服務(wù)器請(qǐng)求的時(shí)候除了發(fā)送表單數(shù)據(jù)外,還會(huì)將和站點(diǎn)相關(guān)的所有Cookie都提交給服務(wù)器,這是強(qiáng)制性的
缺點(diǎn):不能存儲(chǔ)過(guò)多的信息畴椰,安全性差
針對(duì)互聯(lián)網(wǎng)的優(yōu)化:圖片服務(wù)器和主站域名不一樣
## 25.http請(qǐng)求臊诊,css,js斜脂,圖片抓艳,單獨(dú)請(qǐng)求,200表示處理成功帚戳,301重定向玷或,400錯(cuò)誤請(qǐng)求
307臨時(shí)重定向,404頁(yè)面未找到片任,403禁止偏友,401未認(rèn)證,500server內(nèi)部錯(cuò)誤对供,503訪問(wèn)人數(shù)過(guò)多位他。
26./:網(wǎng)站根目錄,../上一級(jí)目錄产场,./當(dāng)前目錄棱诱,~/應(yīng)用程序根目錄
27.數(shù)據(jù)庫(kù)查詢(xún)性能優(yōu)化
1)select中只返回需要的列
2)在減少使用列的同時(shí),考慮減少行涝动,使用where子句
3)只在需要的時(shí)候用order by
4)避免在from,where和having子句中隱式數(shù)據(jù)類(lèi)型的轉(zhuǎn)換
常見(jiàn)的排序算法:
```java
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Sort
{
? public class Sort
? {
? ? ? ///<summary>
? ? ? /// 插入排序--穩(wěn)定排序
? ? ? ///</summary>
? ? ? ///<param name="list"></param>
? ? ? public static void InsertSort(List<int> list)
? ? ? {
? ? ? ? int j, tmp;
? ? ? ? for (int i =1; i < list.Count; i++)
? ? ? ? {
? ? ? ? ? ? j = i;
? ? ? ? ? ? tmp = list[i];
? ? ? ? ? ? while (j >0&& tmp <= list[j -1])
? ? ? ? ? ? {
? ? ? ? ? ? ? list[j] = list[j -1];
? ? ? ? ? ? ? j--;
? ? ? ? ? ? }
? ? ? ? ? ? list[j] = tmp;
? ? ? ? }
? ? ? }
? ? ? ///<summary>
? ? ? /// 希爾排序
? ? ? ///</summary>
? ? ? ///<param name="list"></param>
? ? ? public static void ShellSort(List<int> list)
? ? ? {
? ? ? ? int j, tmp;
? ? ? ? int h =3;
? ? ? ? while (h>0)
? ? ? ? {
? ? ? ? ? ? for (int i = h; i < list.Count; i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? tmp = list[i];
? ? ? ? ? ? ? j = i;
? ? ? ? ? ? ? while ((j > h -1) && tmp < list[j - h])
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? list[j] = list[j - h];
? ? ? ? ? ? ? ? ? j -= h;
? ? ? ? ? ? ? }
? ? ? ? ? ? ? list[j] = tmp;
? ? ? ? ? ? }
? ? ? ? ? ? h = (h -1) %3;
? ? ? ? }
? ? ? }
? ? ? ///<summary>
? ? ? /// 冒泡排序--穩(wěn)定排序
? ? ? ///</summary>
? ? ? ///<param name="list"></param>
? ? ? public static void BubbleSort(List<int> list)
? ? ? {
? ? ? ? if (list ==null|| list.Count <1)
? ? ? ? {
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? int tmp;
? ? ? ? for (int i =0; i < list.Count; i++)
? ? ? ? {
? ? ? ? ? ? bool flag=false;
? ? ? ? ? ? for (int j = i+1; j <list.Count; j++)
? ? ? ? ? ? {
? ? ? ? ? ? ? if (list[i] > list[j])
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? tmp = list[i];
? ? ? ? ? ? ? ? ? list[i] = list[j];
? ? ? ? ? ? ? ? ? list[j] = tmp;
? ? ? ? ? ? ? ? ? flag=true;
? ? ? ? ? ? ? }
? ? ? ? ? ? ? if(flag==false)
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? ? ///<summary>
? ? ? /// 選擇排序--直接選擇排序
? ? ? ///</summary>
? ? ? ///<param name="list"></param>
? ? ? public static void SelectSort(List<int> list)
? ? ? {
? ? ? ? int min, tmp;
? ? ? ? for (int i =0; i < list.Count; i++)
? ? ? ? {
? ? ? ? ? ? min = i;
? ? ? ? ? ? for (int j = i +1; j < list.Count; j++)
? ? ? ? ? ? {
? ? ? ? ? ? ? if (list[j] < list[min])
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? min = j;
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if (i != min)
? ? ? ? ? ? {
? ? ? ? ? ? ? tmp = list[i];
? ? ? ? ? ? ? list[i] = list[min];
? ? ? ? ? ? ? list[min] = tmp;
? ? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? ? ///<summary>
? ? ? /// 堆排序
? ? ? ///</summary>
? ? ? ///<param name="list"></param>
? ? ? public static void HeapSort(List<int> list)
? ? ? {
? ? ? ? int n = list.Count;
? ? ? ? for (int i = n/2-1; i >=0; i--)
? ? ? ? {
? ? ? ? ? ? Sift(list, i, n -1);
? ? ? ? }
? ? ? ? for (int i = n -1; i >=1; i--)
? ? ? ? {
? ? ? ? ? ? int tmp = list[0];//取堆頂元素
? ? ? ? ? ? list[0] = list[i];//讓堆中最后一個(gè)元素上移到堆頂位置
? ? ? ? ? ? list[i] = tmp;//此時(shí)list[i]已不在堆中炬灭,用于存放排好序的元素
? ? ? ? ? ? Sift(list, 0, i -1);//重新調(diào)整堆
? ? ? ? }
? ? ? }
? ? ? private static void Sift(List<int> list, int low, int high)//建堆過(guò)程
? ? ? {
? ? ? ? //i為欲調(diào)整子樹(shù)的根結(jié)點(diǎn)的索引號(hào)醋粟,j為這個(gè)結(jié)點(diǎn)的左孩子
? ? ? ? int i = low, j =2* i +1;
? ? ? ? int tmp = list[i];//記錄雙親結(jié)點(diǎn)的值
? ? ? ? while (j<=high)
? ? ? ? {//如果左孩子小于右孩子,則將欲交換的孩子結(jié)點(diǎn)指向右孩子
? ? ? ? ? ? if (j < high && list[j] < list[j +1])
? ? ? ? ? ? {
? ? ? ? ? ? ? j++;//j指向右孩子
? ? ? ? ? ? }
? ? ? ? ? ? if (tmp < list[j])//如果雙親結(jié)點(diǎn)小于它的孩子結(jié)點(diǎn)
? ? ? ? ? ? {
? ? ? ? ? ? ? list[i] = list[j];//交換雙親結(jié)點(diǎn)和它的孩子結(jié)點(diǎn)
? ? ? ? ? ? ? i = j;//以交換后的孩子結(jié)點(diǎn)為根重归,繼續(xù)調(diào)整它的子樹(shù)
? ? ? ? ? ? ? j =2* i +1;//j此時(shí)代表交換后的孩子結(jié)點(diǎn)的左孩子
? ? ? ? ? ? }
? ? ? ? ? ? else//調(diào)整完畢
? ? ? ? ? ? {
? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? list[i] = tmp;//使最初被調(diào)整的結(jié)點(diǎn)放入正確的位置
? ? ? }
? ? ? ///<summary>
? ? ? /// 歸并排序--穩(wěn)定排序
? ? ? ///</summary>
? ? ? ///<param name="list"></param>
? ? ? ///<param name="low"></param>
? ? ? ///<param name="high"></param>
? ? ? public static void MergeSort(List<int> list, int low, int high)
? ? ? {
? ? ? ? if (low < high)
? ? ? ? {
? ? ? ? ? ? int mid = (low + high) /2;
? ? ? ? ? ? MergeSort(list, low, mid);
? ? ? ? ? ? MergeSort(list, mid +1, high);
? ? ? ? ? ? Merge(list, low, mid, high);
? ? ? ? }
? ? ? }
? ? ? private static void Merge(List<int> list, int low, int mid, int high)
? ? ? {//listTmp為臨時(shí)存放空間米愿,存放合并后的數(shù)據(jù)
? ? ? ? List<int> listTmp =new List<int>(high - low +1);
? ? ? ? int i = low, j = mid +1, k =0;//k為listTmp的下標(biāo)
? ? ? ? while (i <= mid && j <= high)
? ? ? ? {
? ? ? ? ? ? listTmp[k++] = (list[i] < list[j]) ? list[i++] : list[j++];
? ? ? ? }
? ? ? ? while (i <= mid)
? ? ? ? {
? ? ? ? ? ? listTmp[k++] = list[i++];
? ? ? ? }
? ? ? ? while (j <= high)
? ? ? ? {
? ? ? ? ? ? listTmp[k++] = list[j++];
? ? ? ? }
? ? ? ? for (i = low, k=0; i <= high;i++,k++ )
? ? ? ? {
? ? ? ? ? ? list[i] = listTmp[k];
? ? ? ? }
? ? ? }
? ? ? ///<summary>
? ? ? /// 快速排序
? ? ? ///</summary>
? ? ? ///<param name="list"></param>
? ? ? public static void QuickSort(List<int> list)
? ? ? {
? ? ? ? QuickSort(list, 0, list.Count -1);
? ? ? }
? ? ? public static void QuickSort(List<int> list, int low, int high)
? ? ? {
? ? ? ? if (low < high)
? ? ? ? {
? ? ? ? ? ? int i = low, j = high, tmp = list[i];
? ? ? ? ? ? while (i < j)
? ? ? ? ? ? {
? ? ? ? ? ? ? while (i < j && list[j] >= tmp)
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? j--;
? ? ? ? ? ? ? }
? ? ? ? ? ? ? list[i] = list[j];
? ? ? ? ? ? ? while (i < j && list[i] <= tmp)
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? i++;
? ? ? ? ? ? ? }
? ? ? ? ? ? ? list[j] = list[i];
? ? ? ? ? ? }
? ? ? ? ? ? list[i] = tmp;
? ? ? ? ? ? QuickSort(list, low, i -1);
? ? ? ? ? ? QuickSort(list, i +1, high);
? ? ? ? }
? ? ? }
? }
}
```
結(jié)語(yǔ):
到此這篇關(guān)于.NET 的一些常見(jiàn)面的試題的文章就介紹到這了。希望看完這篇文章對(duì)大家今后的面試能起到幫助鼻吮,那真是太好不過(guò)了育苟,在這里我將一些問(wèn)的比較多面試題進(jìn)行了整合打包(PDF、文檔部分截圖)如果有需要的朋友可以點(diǎn)擊這里 暗號(hào):ky