程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【2017年新篇章】 .NET 面試題匯總(一),2017年新篇章

【2017年新篇章】 .NET 面試題匯總(一),2017年新篇章

編輯:C#入門知識

【2017年新篇章】 .NET 面試題匯總(一),2017年新篇章


小分享:我有幾張阿裡雲優惠券,用券購買或者升級阿裡雲相應產品最多可以優惠五折!領券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03

目錄

  • 本次給大家介紹的是我收集以及自己個人保存一些.NET面試題
  • 簡介
    • 1.C# 值類型和引用類型的區別
    • 2.如何使得一個類型可以在foreach 語句中使用
    • 3.sealed修飾的類有什麼特點
    • 4.面向對象的3個基本特征
    • 5. .NET 托管資源與非托管資源
    • 6.string str=null與string str="" 有什麼區別
    • 7.StringBuilder有什麼作用
    • 8.序列化有何作用
    • 9.Base64編碼用在何處
    • 10.字符串池是如何提高系統性能的?
    • 11.FileInfo 和 DirectoryInfo
    • 12.DateTime.Parse(mystring) 這行代碼有什麼問題
    • 13.System.Object的三個比較方法異同
    • 14.GetHashCode 方法有何作用?什麼時候會用到該方法
    • 15.委托的原理
    • 16.委托回調靜態方法和實例方法有何區別
    • 17. 什麼是鏈式委托?
    • 18.ASP.NET 運行機制
    • 19.C#中靜態變量和方法用什麼用處

 

正文

回到頂部

本次給大家介紹的是我收集以及自己個人保存一些.NET面試題

回到頂部

簡介

  • 此次包含的不止是.NET知識,也包含少許前端知識以及.net面試時所涉及的種種考點,希望能給找工作的同學們哪怕一點點幫助。
  • 古人雲“溫故而知新,可以為師矣”,本人工作三年有余,一直懶於寫博客,對已有的知識只存於雲筆記中,還自欺欺人以為能加以善用,可惜的是放到裡面就不會再看,存筆記的習慣是有了,然而卻少有回去翻看的習慣。久而久之,越堆越多,惡心循環,存的只是安心,而不是技術,為此,我決定以後多寫博客,不僅是存筆記,還得是整理並發出來,這樣才能真正地鞏固。
  • 本文面向的閱讀讀者是
  • [x] 剛畢業的萌新
  • [x] 工作不久換工作同學

  • 大牛看到估計是下面這張圖的這個表情了,所以,可以在評論區給給意見啦233。

廢話少說,直入正題:

1.C# 值類型和引用類型的區別

區別詳解 賦值時的區別 值類型的變量將直接獲得一個真實的數據副本,初值為0;而對引用類型的賦值僅僅是把對象的引用賦給變量,這樣就可能導致多個變量引用到一個實際對象實例上,初值為null。 內存分配的區別 值類型的對象會在堆棧上分配內存,而引用類型的對象將會在堆上分配內存。堆棧的控件相對有限,但運行效率卻比堆高得多。 來自繼承結構的區別 由於所有的值類型都有一個共同的基類:System.ValueType,所以值類型擁有一些引用類型不具有的共同性質。較為重要的一點是值類型的比較方法Equals 方法的實現有了改變。所有的值類型已經實現了內容的比較,而引用類型在沒有重寫Equals方法的情況下,仍然采用引用比較。

2.如何使得一個類型可以在foreach 語句中使用

1.若要循環訪問集合,集合必須滿足特定的要求。

  • 例如,在下面的 foreach 語句中:
  • foreach (ItemType item in myCollection)
  • myCollection 必須滿足下列要求:
  • 集合類型:
  • ①.必須是 interface、class 或 struct。
  • ②.必須包括返回類型的名為 GetEnumerator 的實例方法,例如 Enumerator。
    Enumerator 類型(類或結構)必須包含:
    一個名為 Current 的屬性,它返回 ItemType 或者可以轉換為此類型的類型。屬性訪問器返回集合的當前元素。
    一個名為 MoveNext 的 bool 方法,它遞增項計數器並在集合中存在更多項時返回 true。

2.有三種使用集合的方法:

3.sealed修飾的類有什麼特點

// cs_sealed_keyword.cs
using 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
在前面的示例中,如果試圖通過使用下面的語句從密封類繼承:

class MyDerivedC: MyClass {} // Error 

將收到錯誤信息:

'MyDerivedC' cannot inherit from sealed class 'MyClass'.

4.面向對象的3個基本特征

封裝

名詞簡介 封裝 封裝是面向對象的特征之一,是對象和類概念的主要特性。

封裝詳解:

  • 也就是把客觀事物封裝成抽象的類,並且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。

    繼承

    名詞簡介 繼承 面向對象編程 (OOP) 語言的一個主要功能就是“繼承”。繼承是指這樣一種能力:它可以使用現有類的所有功能,並在無需重新編寫原來的類的情況下對這些功能進行擴展。

繼承詳解:

  • 通過繼承創建的新類稱為“子類”或“派生類”。
  • 被繼承的類稱為“基類”、“父類”或“超類”。
  • 繼承的過程,就是從一般到特殊的過程。
  • 要實現繼承,可以通過“繼承”(Inheritance)和“組合”(Composition)來實現。在某些 OOP 語言中,一個子類可以繼承多個基類。但是一般情況下,一個子類只能有一個基類,要實現多重繼承,可以通過多級繼承來實現。

繼承概念的實現方式有三類實現繼承、接口繼承和可視繼承

多態

名詞簡介 多態 多態性(polymorphisn)是允許你將父對象設置成為和一個或更多的他的子對象相等的技術,賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。

實現多態,有二種方式,覆蓋,重載

那麼,多態的作用是什麼呢?

我們知道,封裝可以隱藏實現細節,使得代碼模塊化;繼承可以擴展已存在的代碼模塊(類);它們的目的都是為了——代碼重用。而多態則是為了實現另一個目的——接口重用!多態的作用,就是為了類在繼承和派生的時候,保證使用“家譜”中任一類的實例的某一屬性時的正確調用。

5. .NET 托管資源與非托管資源

非托管資源

  • 最常見的一類非托管資源就是包裝操作系統資源的對象,例如文件,窗口或網絡連接,對於這類資源雖然垃圾回收器可以跟蹤封裝非托管資源的對象的生存期,但它不了解具體如何清理這些資源。還好.net Framework提供了Finalize()方法,它允許在垃圾回收器回收該類資源時,適當的清理非托管資源。如果在MSDN Library 中搜索Finalize將會發現很多類似的主題,

    這裡列舉幾種常見的非托管資源:ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Font,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,Timer,Tooltip 等等資源。可能在使用的時候很多都沒有注意到!

托管資源

  • 像簡單的int,string,float,DateTime等等,.net中超過80%的資源都是托管資源。

6.string str=null與string str="" 有什麼區別

  • 你定義了一個變量的引用str

  • string str=null 把這個引用指向了一個null,沒有地址沒有值的地方,即沒分配內存空間

  • string str="" 把這個引用指向了一個地址,地址裡面存的是空的字符,即占用了內存空間

7.StringBuilder有什麼作用

簡述:String 在進行運算時(如賦值、拼接等)會產生一個新的實例,而 StringBuilder 則不會。
所以在大量字符串拼接或頻繁對某一字符串進行操作時最好使用 StringBuilder,不要使用 String

另外,對於 String 我們不得不多說幾句:

1.它是引用類型,在堆上分配內存

2.運算時會產生一個新的實例

3.String 對象一旦生成不可改變(Immutable)

4.定義相等運算符(== 和 !=)是為了比較 String 對象(而不是引用)的值

總結
StringBuilder采用構造器設計模式的思想高效地構造一個字符串對象,在構造過程中StringBuilder 可以有效的避免臨時字符串對象的生成。一旦 StringBuilder的ToString方法被調用後,最終的字符串就被生成,而隨後的操作將導致一個新的字符串對象的分配。因為字符串對象的不可修改特性,StringBuilder還經常被用來和非托管代碼交互。

8.序列化有何作用

簡述:通過流類型可以方便地操作各種字節流,但如何把現有的實例對象轉換為方便傳輸的字節流,就需要用到序列化的技術。

9.Base64編碼用在何處

簡述:BASE64編碼是一種用於混淆明碼的編碼方式,其算法是把原先8位字節數組順序分配到新的6位字節數組中,再在每個字節的高2位填充0來組成新的8位字節數組。.NET中Convert 類型可以用來進行Base64字符串和8位字節數組之間的轉換。

10.字符串池是如何提高系統性能的?

簡述: 一旦使用了字符串池機制,當CLR啟動的時候,會在內部創建一個容器,容器的鍵是字符串內容,而值是字符串在托管堆上的引用。當一個新的字符串對象需要分配時,CLR首先檢測內部容器中是否已經包含了該字符對象,如果已經包含,則直接返回已經存在的字符串對象引用:如果不存在,則新分配一個字符串對象,同時把其添加到內部容器裡去。但是當程序用new關鍵字顯式地申明新分配的一個字符串對象時,該機制不會起作用。

11.FileInfo 和 DirectoryInfo

簡述: .NET 內建類型中提供了 FileInfo 和 DirectoryInfo 兩個類型,分別用來操作文件和文件夾。有別於 File 和 Directory 類型, FileInfo 和 Directory 主要的功能在於操作文件和文件夾在文件系統中的結構,完成諸如創建、復制、讀取信息、移動、判斷是否存在、刪除等功能。

12.DateTime.Parse(mystring) 這行代碼有什麼問題

簡述: 使用 TryParse 可以避免異常。

示例
string time="2013-02-02";
DateTime t;
if(DateTime.TryParse(s,out t))
{
   //輸出
}

13.System.Object的三個比較方法異同

static bool ReferenceEquals(object A ,object B)
static bool Equals(object A ,object B)
virtual bool Equals(object obj)

1.ReferenceEquals 實現了類型的引用比較,從參數類型可以看出,它不僅可以用來比較兩個引用類型對象,也可以用來比較兩個值類型對象。
當然,ReferenceEquals 方法只有應用在引用類型上時才會有意義,比較值類型的引用將永遠返回false,無論他們的值是否相等。甚至與下面的例子:
int i=0; Console.WriteLine(Object.ReferenceEquals(i,i));

解釋:因為上面的兩個i都是先進行裝箱,然後傳遞給ReferenceEquals 方法。

2.Equals 是另外一個靜態比較方法,它實現的功能根據不同的類型而有所不同。事實上,Equals 方法的功能依靠了實例Equals 方法的實現,概括地講,靜態 Equals 方法的內容分為兩步:首先檢查兩個對象是否恆等 (==),然後調用其中一個參數對象的實例 Equals 方法來判斷兩個對象是否恆等。

14.GetHashCode 方法有何作用?什麼時候會用到該方法

簡述

  • Object 中 GetHashCode 的算法保證了同一對象返回同一 HashCode ,而不同對象則返回不同的 HashCode,但對值類型等視內容相等的對象為相等對象的類型時,默認的GetHashCode 算法並不正確。
  • 重寫 GetHashCode 必須保證同一對象無論何時都返回同一 HashCode 值,而相等的對象也必須返回相同的值,並且在此基礎上,保證 HasCode 盡量隨機地散列分布。

15.委托的原理

簡述:委托是一類繼承自 System.Delegate的類型, 每個委托對象至少包含了一個指向某個方法的指 針,該方法可以是實例方法,也可以是靜態方法。委托實現了回調方法的機制,能夠幫助程序員 設計更加簡潔優美的面向對象程序。

16.委托回調靜態方法和實例方法有何區別

簡述:委托回調靜態方法和實例方法有何區別 當委托綁定靜態方法時,內部的對象成員變量 _target將會被設置成 null,而當委托綁定實例 方法時, _target 將會設置成指向該實例方法所屬類型的一個實例對象, 當委托被執行時, 該對象 實例將被用來調用實例方法。

17. 什麼是鏈式委托?

簡述:鏈式委托是指一個委托的鏈表,而不是指另一類特殊的委托。 當執行鏈上的一個方法時,後續委托方法將會被依次執行。System.Multicast Delegate定 義了對鏈式委托的支持。在System.Delegate的基礎上,它增加了一個指向後續委托的指針,這樣就實現了一個簡單的鏈表結構。

18.ASP.NET 運行機制

1.浏覽器和服務器的交互原理

image

  • 答案是套接字:Socket。至於Socket的具體用法和原理,篇幅問題不在此文中寫了,先預留位置在這,下次補上《基於多線程和套接字的簡易WebServer軟件-沒有控件的ASP.NET》。
  • 浏覽器和服務器軟件通過套接字來發送和接收對方的信息,但現在的關鍵問題是,他們發送和接收的到底是什麼?--- 基於Http協議的報文數據(詳見《Http協議介紹---沒有控件的ASP.NET》)。
  • 也就是說:浏覽器和服務器軟件其實就是兩個使用Socket進行通信的的兩個應用程序:雙方都發送按照 Http協議語法規范組織的數據,接收到數據後都按照 Http協議語法規范來解釋。

    2.浏覽器和IIS(or other webserver)交互機制

上圖就是IIS (服務器軟件)

1.浏覽器和IIS交互過程:
我們都知道,在互聯網上確定一台電腦的位置是使用IP尋址,但為什麼當我們平時訪問網站時直接輸入一個域名也能夠訪問到某個服務器電腦進而由對方的服務器軟件發送響應頁面數據給我呢?下面我把簡單步驟列出:

(1)在浏覽器輸入網址:www.oumind.com/index.html,浏覽器按照Http協議語法 生成請求報文數據。

(2).浏覽器檢查本機是否保存了www.oumind.com/index.html.域名對應的服務器IP地址。如果沒有,則發送請求到所在城市網中最近的DNS服務器(域名解析服務器),它會根據我們發送來的域名查詢到該域名對應的服務器IP地址,並發送回浏覽器。

(3)浏覽器從DNS服務器獲得了 www.oumind.com/index.html域名對應的服務器電腦IP,則將 請求報文 通過Socket發送到服務器電腦。(注意:Http協議 規定服務器軟件使用的默認端口是80,通俗的說,就是如果浏覽器訪問一個網站頁面,浏覽器默認就是將 請求報文 發送到服務器80端口,而服務器負責監聽這個端口的軟件一般就是服務器軟件—比如asp.net用的IIS,java用的Tomcat。)

(4)IIS接收到 請求報文,分析請求報文,從中獲取請求的頁面路徑 /index.html。判斷頁面的後綴名,如果是靜態頁面(.html/.jpg/.css/.js等),則直接由IIS軟件的組件讀取該文件內容,並將內容通過Socket發送回浏覽器。

(5)但如果此時請求的是一個動態頁面(.aspx/.ashx),IIS自己就處理不了 (因為IIS軟件開發出來的時候,ASP.NET程序還不存在呢) 。所以,IIS就去它的 擴展程序映射表 中根據被請求文件後綴名 查看是否有能夠處理這種文件的擴展程序。

而我們ASPNET中常用的文件.aspx/.ashx等 對應的處理程序是aspnet_isapi.dll。如下圖:

(6)如果IIS根據後綴名找到對應的處理程序,則通過調用此程序來處理浏覽器發送來的請求報文。

IIS自身是不能處理像ASPX擴 展名這樣的頁面,只能直接請求像HTML這樣的靜態文件,之所以能處理ASPX這樣擴展名的頁面,是因為IIS有一個ISAPI過濾器,它是一個COM組件。

ASP.NET服務在注冊到IIS的時候,就會添加一個Win32的擴展動態庫aspnet_isapi.dll。並將擴展可以處理的頁面擴展名(如 ASPX)注冊到IIS裡面。擴展啟動後,就根據定義好的方式來處理IIS所不能處理的頁面。

當客戶端請求一個服務器資源時,這個HTTP請求會被inetinfo.exe進程截獲(www服務),然後Check請求資源的類型,並依據資源映射信息(存儲在IIS元庫中,一種IIS專用的配置數據庫)將請求的資源分配給特定的處理程序模塊。若請求的是靜態資源(img,text,html等)則由IIS處理(IIS在本地Web Server上訪問請求的文件),將內容輸出到控制台,發出請求的浏覽器就能接收到它了。

若需要在服務器端處理的請求,則會被傳到已注冊的擴展模塊 中,aspx請求會被分配給aspnet_isapi.dll,讓這個程序開始處理代碼,生成標准的HTML代碼,然後將這些HTML加入到原有的 HTML中,最後把完整的HTML返回給IIS,IIS再把內容發送到客戶浏覽器。

ASP.NET FrameWork對請求的處理

上面說到IIS將像ASPX這樣的頁面分配給aspnet_isapi.dll,接著處理如下:

1、aspnet_isapi.dll則會 通過一個Http PipeLine的管道將這個Http請求發給w3wp.exe(iis 工作者進程,IIS6.0中叫做 w3wq.exe,IIS5.0中叫做 aspnet_wp.exe),之後asp.net framework就會通過HttpRuntime來處理這個Http請求。

2、HttpRuntime首先會確定處理該請求的類名,HttpRuntime通過公共接口IHttpHandler來調用該類獲取被請求資源的類的實例。

3、調用HttpRuntime.ProcessRequest開始處理要發送到浏覽器的頁面,具體說就是創建一個HttpContext實例,它封裝了所有與請求有關的http特有的信息,並初始化一個Write對象用於緩存標記代碼。

4、HttpRuntime使用上下文信息查找或新建能處理該請求的WEB應用程序的對象。由HttpApplication Factory負責返回HttpApplication實例。

5、HttpApplication實例會讀取web.config中所有HttpModule的配置。

6、HttpApplication對象使用IHttpHandlerFactory類型的實例返回HttpHandler(http處理程序)給HttpRuntime對象。一個頁面只是個http處理程序對象。
7、最後由HttpRuntime對象調用IHttpHandler的頁面對象的ProcessRequest方法。

19.C#中靜態變量和方法用什麼用處

1.靜態變量簡介

在C#程序中,沒有全局變量的概念,這意味著所有的成員變量只有該類的實例才能操作這些數據,這起到了“信息隱藏”的作用。但有些時候,這樣做卻不是個明智的選擇。

  • 假設我們要定義一個圖書類,要求該類能保存圖書的數量,即每增加一本圖書(定義一個實例),圖書的數量應該加1。如果沒有靜態變量,我們需要將圖書的數量保存在每本圖書(實例)裡,然而,這樣的變量要在不同圖書(實例)裡重復存儲,圖書(實例)數量少的話,我們還能接受,如果圖書(實例)數量較多的話,比如成千上萬,我們無法想象這要造成多少資源(如內存、磁盤空間)的浪費,更讓人無法忍受的是:因為圖書(實例)的數量要保存在每本圖書(實例)裡,該值肯定是不同的。要使這些圖書(實例)中保存的圖書(實例)數量一致,我們必須在每增加一本新書(生成一個新實例)時,修改其他所有圖書(實例)中保存的該值。
  • Oh,My God!你會重新向往面向過程的程序設計方法,向往擁有全局變量的時代。但,這種局面不會出現,因為C#中為你准備好了另外一種變量類型:靜態變量。它在類中類似全局變量,保存類的公共信息,所有該類的實例(對象)共享該值。

靜態變量的聲明方式如下:

  [訪問修飾符] static 數據類型 變量名;

這裡的訪問修飾符跟類的其它成員一樣,可以是public,protected,private或internal等。

2.靜態變量又如何使用呢?

靜態變量必須使用類名來引用,而不能使用類的實例,因為,靜態變量不屬於任何實例,而是共有的。

  • 我們可以打個比方:在一個班級中,有些物品是個人的,我們想使用時,必須指出物品的所有者,比如說“王三的自行車”,在C#程序中我們可以使用:王三.自行車的格式。有些物品是大家共有的物品,不能以個人名義使用,而是用班級的名義使用,比如班集體出資買的籃球,只能說:“班級的籃球”,而不能說:“王三的籃球”。這絕對是不行的,這對其他人絕對是不公平的,我們可以聯想到許多貪官污吏就是使用了不屬於自己的東西,或以個人名義使用公家的東西而葬送了自己。
  • 說一句有用的就是:靜態變量是用類名來引用它。即:類名.靜態變量名;

舉個具體的例子如下:

using System;

class StaticVar
       {
              public int x;
              public static int y;
              public void PrintInfo()
             {
                    Console.WriteLine("非靜態變量x={0}",x);
                    Console.WriteLine("靜態變量y = {0}",y);
             }
        }
        class Test
        {
                  static void Main(string[] args)
                  {
                         StaticVar stv = new StaticVar();
                         stv.x = 10;
                          // stv.y = 20; //error;無法使用實例引用訪問靜態成員“StaticVar.y”;改用類型名來限定它
                         StaticVar.y = 20;
                         stv.PrintInfo();
                   }
        }

程序中被注釋的部分:stv.y = 20是使用實例引用靜態變量,這將引發錯誤。

另外,我想說一句,對於靜態變量在聲明時,如果沒有給出初始值或使用前沒有賦任何值的話,系統會給他們一個默認值:對於整型數據默認值為0;單精度數據為:0.0f;雙精度數據為0.0;布爾型數據為False;引用型數據為null。

3.靜態方法

靜態方法與靜態變量一樣,不屬於任何特定的實例,屬於類全體成員共有,由類名來調用。

但要注意以下幾點:

這裡用一個具體的例子來說明:

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);   //靜態方法中不能使用非靜態成員
                    }
            }
            class Test
            {
                    static void Main(string[] args)
                    {
                            StaticTest st = new StaticTest(10,23);
                            st.SimplePrint();
                            //st.StaticPrint();        //靜態方法不能使用實例來調用
                            StaticTest.StaticPrint();
                    }
             } 
       }
當你自認為做出了不錯的功能但描述出來時又支支吾吾的時候,不要為自己說不出來而懊惱,因為不是你發揮有問題,更不要向別人解釋用了啥高大上插件,別讓自己成為接口程序員,請靜下心回去補補基礎。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved