.NET基礎(chǔ)面試題整理小結(jié)

今年畢業(yè),本學(xué)期找工作期間在面試前做的一些臨時(shí)的準(zhǔn)備
以下的關(guān)于老趙分享的面試題解答參考了手頭的書(shū)籍和視頻教程,以及網(wǎng)上的資料,現(xiàn)整理出來(lái)希望對(duì)大家有所幫助,不對(duì)或欠佳的地方望大家指出來(lái)我好改正。
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),公共類型系統(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í)將受到類型安全性方面檢查,這實(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.類(class)和結(jié)構(gòu)(struct)的區(qū)別是什么?它們對(duì)性能有影響嗎?
1. 值類型與引用類型
結(jié)構(gòu)是值類型:值類型在棧上分配地址,所有的基類型都是結(jié)構(gòu)類型,例如:int 對(duì)應(yīng)System.int32 結(jié)構(gòu),通過(guò)使用結(jié)構(gòu)可以創(chuàng)建更多的值類型
類是引用類型:引用類型在堆上分配地址堆棧的執(zhí)行效率要比堆的執(zhí)行效率高,可是堆棧的資源有限,不適合處理大的邏輯復(fù)雜的對(duì)象。所以結(jié)構(gòu)處理作為基類型對(duì)待的小對(duì)象,而類處理某個(gè)商業(yè)邏輯因?yàn)榻Y(jié)構(gòu)是值類型所以結(jié)構(gòu)之間的賦值可以創(chuàng)建新的結(jié)構(gòu),而類是引用類型,類之間的賦值只是復(fù)制引用
注:1.雖然結(jié)構(gòu)與類的類型不一樣,可是他們的基類型都是對(duì)象(object),c#中所有類型的基類型都是object
2.雖然結(jié)構(gòu)的初始化也使用了New 操作符可是結(jié)構(gòu)對(duì)象依然分配在堆棧上而不是堆上,如果不使用“新建”(new),那么在初始化所有字段之前,字段將保持未賦值狀態(tài),且對(duì)象不可用
2.繼承性
結(jié)構(gòu):不能從另外一個(gè)結(jié)構(gòu)或者類繼承,本身也不能被繼承,雖然結(jié)構(gòu)沒(méi)有明確的用sealed聲明,可是結(jié)構(gòu)是隱式的sealed .
類:完全可擴(kuò)展的,除非顯示的聲明sealed 否則類可以繼承其他類和接口,自身也能被繼承注:雖然結(jié)構(gòu)不能被繼承 可是結(jié)構(gòu)能夠繼承接口,方法和類繼承接口一樣
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ò)誤的
類: 有默認(rèn)的構(gòu)造函數(shù) 有析構(gòu)函數(shù) 可以使用 abstract 和 sealed 有protected 修飾符
必須使用new 初始化
4..NET BCL里有哪些是類(結(jié)構(gòu)),為什么它們不是結(jié)構(gòu)(類)?
結(jié)構(gòu):System.Boolean Byte Char Decimal Double Int32
堆棧的空間有限,對(duì)于大量的邏輯的對(duì)象,創(chuàng)建類要比創(chuàng)建結(jié)構(gòu)好一些 大多數(shù)情況下該類型只是一些數(shù)據(jù)時(shí),結(jié)構(gòu)時(shí)最佳的選擇
類:String Object Delegate 接口 等等 包含了大量的邏輯對(duì)象,表現(xiàn)抽象
5.在自定義類型時(shí),您如何選擇是類還是結(jié)構(gòu)?
1). 堆棧的空間有限,對(duì)于大量的邏輯的對(duì)象,創(chuàng)建類要比創(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í),類是最好的選擇
4). 大多數(shù)情況下該類型只是一些數(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è)方法(或類型)被調(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)值類型一般分配在對(duì)上面,引用類型分配在堆上面。棧的效率要高于堆。
2)可能,當(dāng)在類中定義一個(gè)結(jié)構(gòu)類型時(shí),該結(jié)構(gòu)就分配在堆上
8.泛型的作用是什么?它有什么優(yōu)勢(shì)?它對(duì)性能有影響嗎?它在執(zhí)行時(shí)的行為是什么?
作用:為了促進(jìn)代碼的重用,尤其是算法的重用
優(yōu)勢(shì):(1)可重用性(2)類型安全,在參數(shù)化的類中只有成員明確希望的數(shù)據(jù)類型才可以使用(3)性能:避免了從Object的強(qiáng)制轉(zhuǎn)換和值類型的裝箱(4)減小了內(nèi)存消耗:避免裝箱也就不在需要消耗堆上的內(nèi)存。
執(zhí)行時(shí)的行為:泛型也是對(duì)象,泛型類的“類型參數(shù)”變成了元數(shù)據(jù);CLR會(huì)在需要的時(shí)候構(gòu)造利用它們的類。一個(gè)泛型類經(jīng)過(guò)編譯好之后和普通的類并沒(méi)有什么區(qū)別。編譯的結(jié)果只有元數(shù)據(jù)和CIL。基于值類型的泛型實(shí)例化:CLR會(huì)講指定的類型參數(shù)放到CIL中合適的位置,從而創(chuàng)建一個(gè)具體化的泛型類型。所以CLR會(huì)為沒(méi)個(gè)新的參數(shù)值創(chuàng)建具體的泛型類型
基于引用類型的實(shí)例化:CLR會(huì)創(chuàng)建一個(gè)具體化的泛型類型。以后,每次用一個(gè)引用類型參數(shù)來(lái)說(shuō)實(shí)例化一個(gè)構(gòu)造好的類型時(shí),并在CIL中用Object引用替換類型參數(shù),CLR都會(huì)重用以前生成好的泛型版本
9..NET BCL中有哪些泛型類型?舉例說(shuō)明平時(shí)編程中您定義的泛型類型。
List<T>:通過(guò)索引訪問(wèn)強(qiáng)類型的列表
Dictionary<T>:表示鍵值對(duì)的集合
Queue<T>:隊(duì)列 Stack<T>: 棧
購(gòu)物車用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抽象類和接口有什么區(qū)別?使用時(shí)有什么需要注意的嗎?
如何選擇是定義一個(gè)“完全抽象”的抽象類,還是接口?什么是接口的“顯式實(shí)現(xiàn)”?為什么說(shuō)它很重要?
相同點(diǎn):都不能被直接實(shí)例化,都通過(guò)繼承實(shí)現(xiàn)其抽象方法
不同點(diǎn):
(1) 接口支持多繼承;抽象類不能實(shí)現(xiàn)多繼承。
(2) 接口只能定義行為;抽象類既可以定義行為,還可能提供實(shí)現(xiàn)。
(3) 抽象類允許包含實(shí)現(xiàn)的virtual成員,所以能為派生類成員提供一個(gè)默認(rèn)的實(shí)現(xiàn),而接口所有的成員自動(dòng)成為virtual成員,而且不能包含任何實(shí)現(xiàn)
13.字符串是引用類型類型還是結(jié)構(gòu)類型? 引用類型
它和普通的引用類型相比有什么特別的地方嗎?不可變的
使用字符串時(shí)有什么需要注意的地方?為什么說(shuō)StringBuilder比較高效?
當(dāng)拼接兩個(gè)字符串時(shí),系統(tǒng)先是把兩個(gè)字符串寫入內(nèi)存,接著刪除原來(lái)的String對(duì)象,然后創(chuàng)建一個(gè)String對(duì)象,并讀取內(nèi)存中的數(shù)據(jù)賦給該對(duì)象。這一來(lái)二去的,耗了不少時(shí)間。而使用System.Text命名空間下面的StringBuilder類就不是這樣了,它提供的Append方法,能夠在已有對(duì)象的原地進(jìn)行字符串的修改,簡(jiǎn)單而且直接。
在連接多個(gè)字符串時(shí),它無(wú)論何時(shí)都比直接相加更高效嗎?
不一定,在1000個(gè)字符以內(nèi)效果一樣,達(dá)到10000時(shí)StringBuilder類的效率會(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中哪些類庫(kù)和這些特性有關(guān)?您平時(shí)最常用哪些?
委托可以把一個(gè)方法作為參數(shù)代入另一個(gè)方法。
委托可以理解為指向一個(gè)函數(shù)的指針。
匿名方法:就是沒(méi)有實(shí)際方法聲明的委托實(shí)例?;蛘哒f(shuō),它們的定義是直接內(nèi)嵌在代碼中的。
Lambda表達(dá)式:是比匿名方法更加簡(jiǎn)潔的一種匿名函數(shù)語(yǔ)法
委托和事件沒(méi)有可比性,因?yàn)槲惺穷愋?,事件是?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è)自己+=、注銷自己-=”,外界不可以注銷其他的注冊(cè)者,外界不可以主動(dòng)觸發(fā)事件,因此如果用Delegate就沒(méi)法進(jìn)行上面的控制,因此誕生了事件這種語(yǔ)法。事件是用來(lái)閹割委托實(shí)例的,類比用一個(gè)自定義類閹割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法將客戶端的元素值傳遞給服務(wù)端,即使是表單元素也只能傳遞value值,對(duì)于其他屬性值,比如背景顏色,大小等也是無(wú)法傳遞的,因此對(duì)于這些值都要存在隱藏字段中。Viewstate是跟頁(yè)面相關(guān)的,不用的頁(yè)面viewstate也會(huì)不同,不會(huì)相互影響。ViewState對(duì)需要PostBack處理的頁(yè)面才可能有用,對(duì)于新聞?wù)故具@類頁(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ù)查詢性能優(yōu)化
1)select中只返回需要的列
2)在減少使用列的同時(shí),考慮減少行,使用where子句
3)只在需要的時(shí)候用order by
4)避免在from,where和having子句中隱式數(shù)據(jù)類型的轉(zhuǎn)換
常見(jiàn)的排序算法:
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); } } } }
到此這篇關(guān)于.NET基礎(chǔ)面試題整理小結(jié)的文章就介紹到這了,更多相關(guān).NET面試題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
作者:張雪飛
出處:https://zhangxuefei.site
相關(guān)文章
- 這篇文章主要介紹了程序員面試的幾個(gè)小技巧,在平時(shí)面試的時(shí)候,除了實(shí)打?qū)嵉募寄苓€需要更多的技巧,雙管齊下才能贏得更大的勝算,技能方面就不多說(shuō)了,下面來(lái)分享幾個(gè)面試2023-04-23
- 面試中,問(wèn)鎖主要是兩方面:鎖的日常使用場(chǎng)景 + 鎖原理,鎖的日常使用場(chǎng)景主要考察對(duì)鎖 API 的使用熟練度,看看你是否真的使用過(guò)這些 API,而不是紙上談兵,鎖原理主要就是2022-05-19
Mybatis常見(jiàn)面試題詳細(xì)總結(jié)
這篇文章主要介紹了Mybatis常見(jiàn)面試題詳細(xì)總結(jié),通過(guò)總結(jié)列舉大量的mybatis面試常見(jiàn)題目供給大家參考,希望對(duì)大家有所幫助2021-08-242020Java后端開(kāi)發(fā)面試題總結(jié)(春招+秋招+社招)
這篇文章主要介紹了2020Java后端開(kāi)發(fā)面試題總結(jié)(春招+秋招+社招),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-02-18MySQL數(shù)據(jù)庫(kù)選擇題小結(jié)
這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)選擇題小結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-02-07- 這篇文章主要介紹了30道有趣的JVM面試題(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-11-26
Python面試題爬蟲(chóng)篇小結(jié)(附答案)
這篇文章主要介紹了Python面試題爬蟲(chóng)篇小結(jié)(附答案),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-10-28還不理解B樹(shù)和B+樹(shù),那就看看這篇文章吧
這篇文章主要介紹了還不理解B樹(shù)和B+樹(shù),那就看看這篇文章吧,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一2020-09-10Java面試通關(guān)要點(diǎn)匯總(備戰(zhàn)秋招)
這篇文章主要介紹了Java面試通關(guān)要點(diǎn)匯總(備戰(zhàn)秋招),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-09-08- 這篇文章主要介紹了10道JVM常見(jiàn)面試題解析(附答案),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)2020-09-04