金三銀四面試:C#程式設計師經常遇到的30道基礎面試題,想你所想

語言: CN / TW / HK

轉自:DotNet開發跳槽

目錄

1、請解釋new與override的區別?

2、請解釋virtual的含義?

3、請解釋介面的顯示實現有什麼意義?

4、請以圖示的方式解釋.net framework?

5、什麼是.net?

6、ref與out有什麼不同?

7、值型別與引用型別有什麼不同?請舉例說明?並分別列舉幾種相應的資料型別。

8、結構體是值型別還是引用型別?

9、裝箱與拆箱是什麼含義?

10、沒有經過裝箱的物件可不可以拆箱?

11、C#中有沒有靜態建構函式,如果有是做什麼用的?

12、在C#中如何實現多型?

13、什麼是反射?如何實現反射?

14、請解釋流與檔案有什麼不同?

15、程式集與名稱空間有什麼不同?

16、請編寫一個捕獲所有異常的異常處理程式碼?

17、委託與事件是什麼關係?為什麼要使用委託?

18、一個類中有幾種元素?

19、請解釋這種語法現象

20、一個建構函式能否呼叫另一個建構函式,如果能請寫出簡單程式碼?

21、params是什麼含義?

22、C#中沒有運算子過載?能否使用指標?

23、C#中有很多類被定義為public有什麼意義?

24、internal修飾符有什麼含義?

25、JAVA的程式碼是半編譯半解釋的,C#程式碼是否也是這樣的?

26、私有程式集與共享程式集有什麼區別?

27、請解釋程序與執行緒的區別?程序與程式的區別?

28、CLR與IL分別是什麼含義?

29、物件能否呼叫靜態方法?

30、請編寫建立一個執行緒的程式碼?

1、請解釋new與override的區別?

在C#中,new關鍵字可用作運算子和修飾符。

(1)new運算子用於在堆上建立物件和呼叫建構函式。

(2)new修飾符用於隱藏基類成員的繼承成員。

使用override修飾符來修改方法、屬性、索引器或事件。重寫方法提供從基類繼承的成員的新實現。由重寫宣告重寫的方法稱為重寫基方法。重寫基方法必須與重寫方法具有相同的簽名。

不能重寫非虛方法或靜態方法。重寫基方法必須是虛擬的、抽象的或重寫的。

重寫宣告不能更改虛方法的可訪問性。重寫方法和虛方法必須具有相同的訪問級的修飾符。不能使用下列修飾符修改重寫方法:new、static、virtual、abstract。

重寫屬性宣告必須指定與繼承屬性完全相同的訪問修飾符、型別和名稱,並且重寫屬性必須是虛擬的、抽象的或重寫的。

2、請解釋virtual的含義?

virtual關鍵字用於修改方法和屬性的宣告,在這種情況下,方法或屬性被稱作虛擬成員。虛擬成員的實現可由派生類中的重寫成員更改。

呼叫虛方法時,將為重寫成員檢查該物件的執行時型別。將呼叫大部分派生類中的該重寫成員,如果沒有派生類重寫該成員,則它可能是原始成員。預設情況下,方法是非虛擬的。

不能重寫非虛方法。不能將virtual修飾符與以下修飾符一起使用:static、abstract、override。

除了宣告和呼叫語法不同外,虛擬屬性的行為與抽象方法一樣。

(1)在靜態屬性上使用virtual修飾符是錯誤的。

(2)通過包括使用override修飾符的屬性宣告,可在派生類中重寫虛擬繼承屬性。

3、請解釋介面的顯示實現有什麼意義?

介面是其他型別為確保它們支援某些操作而實現的引用型別。介面從不直接建立而且沒有實際的表示形式,其他型別必須轉換為介面型別。一個介面定義一個協定。實現介面的類或結構必須遵守其協定。介面可以包含方法、屬性、索引器和事件作為成員。

4、請以圖示的方式解釋.net framework?

5、什麼是.net?

.net是一種平臺和框架,.net不是單純的語言也不是單純的工具,它是從底層平臺開始構建起來的一個整體框架。

6、ref與out有什麼不同?

方法引數上的ref方法引數關鍵字使方法引用傳遞到方法的同一個變數。當控制傳遞迴呼叫方法時,在方法中對引數所做的任何更改都將反映在在該變數中。若要使用ref引數,必須將變數作為ref引數顯示傳遞到方法。變數的值被傳遞到ref引數。傳遞到ref引數的變數必須要先初始化。

與out引數相比,變數在傳遞到out引數之前不必顯示初始化。屬性不是變數,不能作為ref引數傳遞。如果兩個方法的宣告僅在它們對ref的使用方面不同,則將出現過載。但是,無法定義僅在ref和out方面不同的過載。

方法引數上的out方法引數關鍵字使方法引用傳遞到方法的同一個變數。當控制傳遞迴呼叫方法時,在方法中對引數所做的任何更改都將反映在該變數中。

當希望方法返回多個值時,宣告out方法非常有用。使用out引數的方法仍然可以返回一個值。一個方法可以有一個以上的out引數。若要使用out引數,必須將變數作為out引數顯示傳遞到方法。out變數的值不會傳遞到out引數。屬性不是變數,不能作為out引數傳遞。如果兩個方法的宣告僅在out的使用方面不同,則會發生過載。不過,無法定義僅在ref和out方面不同的過載。

7、值型別與引用型別有什麼不同?請舉例說明?並分別列舉幾種相應的資料型別。

大多數程式語言提供內建的資料型別(比如整數和浮點數),這些資料型別會在作為引數傳遞時被複制(即,它們通過值來傳遞)。在.NET Framework中,這些稱為值型別。您可以建立值型別的例項,將它們作為引數傳遞,將它們儲存為區域性變數,或將它們儲存在另一值型別或物件的欄位中。值型別沒有與儲存類的例項相關的系統開銷,並且它們不需要建構函式。值型別可以有欄位、屬性和事件。它們也有靜態和非靜態方法。當它們被裝箱時,會從System.ValueType繼承虛方法,並可實現零個或更多介面。值型別是密封的,這意味著不能從它們派生出其他型別。但是,可以直接對值型別定義虛方法,並且即可對該型別的已裝箱形式,也可對未裝箱形式呼叫這些方法。儘管不能從一種值型別派生出另一種型別,但是當所用語言處理虛方法比處理非虛方法或靜態方法更方便時,可以對值型別定義虛方法。

引用型別的變數又稱為物件,可儲存對實際資料的引用。以下用於宣告引用型別的關鍵字:

(1)class

(2)interface

(3)delegate

8、結構體是值型別還是引用型別?

是值型別

9、裝箱與拆箱是什麼含義?

裝箱是值型別到object型別(引用型別)或到該值型別所實現的任何介面型別的隱式轉換。將一個值型別的值裝箱會分配一個物件例項並將該值複製到新的物件中。

拆箱是從object型別(引用型別)到值型別或從介面型別到實現該介面的值型別的顯示轉換,拆箱包括:

(1)檢查物件例項,確保它是給定值型別的一個裝箱值。

(2)將該值從例項複製到值型別變數中。

10、沒有經過裝箱的物件可不可以拆箱?

不能。但是可以通過型別轉換實現物件值向值型別變數的轉化,比如Convert.ToXXX(obj.ToString());和int.TryParse();

11、C#中有沒有靜態建構函式,如果有是做什麼用的?

有。靜態建構函式用於初始化類。在建立第一個例項或引用任何靜態成員之前,將自動呼叫靜態建構函式來初始化類。靜態建構函式既沒有訪問修飾符,也沒有引數。在建立第一個例項或引用任何靜態成員之前,將自動呼叫靜態建構函式來初始化類。無法直接呼叫靜態建構函式。在程式中,使用者無法控制何時執行靜態建構函式。

靜態建構函式的典型用途是:當類使用日誌檔案時,將使用這種建構函式向日志文件中寫入項。

12、在C#中如何實現多型?

“多型性”指定義具有功能不同但名稱相同的方法或屬性的多個類的能力,這些類可由客戶端程式碼在執行時交換使用。也就是由過載和重寫實現多型。過載一般是同一類中的一組同名方法,但簽名。重寫主要是在繼承中體現,就是在基類中定義方法並在派生類中使用新實現重寫它們。

13、什麼是反射?如何實現反射?

反射提供了訪問程式集、模組和型別資訊的一種機制。您可以使用反射動態的建立型別的例項,將型別繫結到現有物件,或從現有物件中獲取型別。然後,可以呼叫型別的方法或訪問其欄位和屬性。通過反射名稱空間中的類以及System.Type,您可以獲取有關已載入的程式集和在其中定義的型別(如類、介面和值型別)的資訊。您也可以使用反射在執行時建立型別例項,然後呼叫和訪問這些例項。

14、請解釋流與檔案有什麼不同?

檔案是一些具有永久儲存及特定順序的位元組組成的一個有序的、具有名稱的集合。因此,對於檔案,人們常會想到目錄路徑、磁碟儲存、檔案和目錄名等方面。相反,流提供一種向後備儲存器寫入位元組和從後備儲存器讀取位元組的方式,後備儲存器可以為多種儲存媒介之一。正如除磁碟外在多種後備儲存器一樣,除檔案流之外也存在多種流。例如,還存在網路流、記憶體流和磁帶流等。

15、程式集與名稱空間有什麼不同?

名稱空間是用於避免命名衝突,專用於組織程式碼,當代碼要在其他某個應用程式中重用時,可以降低複雜性。

程式集是重用程式碼的一種方式,通常對應一個工程類庫(dll),在一個程式集中可以有屬於不同名稱空間的類和介面。可以將相同名稱空間中的類部署到不同的程式集中,也可以將不同名稱空間中的類部署到一個程式集中。

名稱空間程式集

有邏輯編譯時機制有物理編譯時機制

不是執行時實體是執行時實體

為原始碼元素的名稱提供邏輯結構為可執行檔案的執行時提供物理結構

16、請編寫一個捕獲所有異常的異常處理程式碼?

try

{

...

}

catch(Exception ex)

{

...

}

17、委託與事件是什麼關係?為什麼要使用委託?

委託提供了封裝方法的方式,事件是某動作已發生的說明,事件是建立於委託之上的。

(1)程式執行時同一個委託能夠用來呼叫不同的方法只要改變它引用的方法即可。

(2)同一個委託能夠用來呼叫不同的方法,只要改變它引用的方法即可,因此委託調節器用的方法不是在編譯時決定的,而是在執行時確定的。

18、一個類中有幾種元素?

類由欄位、屬性、方法組成。

19、請解釋這種語法現象

Session["name"] = 20;

給類的索引器賦值。

20、一個建構函式能否呼叫另一個建構函式,如果能請寫出簡單程式碼?

能。

class Class1

{

int y;

public Class1()

{

new Class1(5);

}

public Class1(int i)

{

this.y = i;

}

public void X()

{

Console.WriteLine(y.ToString());

}

static void Main(string[] args)

{

Class1 c1 = new Class1();

c1.X();

}

}

21、params是什麼含義?

params關鍵字可以指定在引數數目可變處定義引數的方法。在方法宣告中的params關鍵字之後不允許任何其他引數,並且在方法宣告中只允許一個params關鍵字。

22、C#中沒有運算子過載?能否使用指標?

過載操作符意味著使該操作符具有不同的行為,使用操作符可以使方程式簡單易懂。C# 允許使用者定義的型別通過使用 operator 關鍵字定義靜態成員函式來過載運算子。注意必須用public修飾且必須是類的靜態的方法。

C#為了型別安全,預設並不支援指標。但是也並不是說C#不支援指標,我們可以使用unsafe關鍵詞,開啟不安全程式碼(unsafe code)開發模式。在不安全模式下,我們可以直接操作記憶體,這樣就可以使用指標了。在不安全模式下,CLR並不檢測unsafe程式碼的安全,而是直接執行程式碼。unsafe程式碼的安全需要開發人員自行檢測。

在下列情況中可以開啟不安全程式碼使用指標

(1)處理磁碟上的現有結構

(2)涉及內部包含指標的結構的高階COM或平臺呼叫方案

(3)效能關鍵程式碼

不鼓勵在其他情況下使用不安全上下文。具體地說,不應該使用不安全上下文嘗試在C#中編寫C程式碼。

23、C#中有很多類被定義為public有什麼意義?

public關鍵字將公共訪問許可權授予一個或多個被宣告的程式設計元素。對公共元素的可訪問性沒有限制。

24、internal修飾符有什麼含義?

internal關鍵字是型別和型別成員的訪問修飾符。內部成員只有在同一程式集中的檔案內才是可訪問的。內部訪問通常用於基於元件的開發,因為它使用一組元件能夠以私有方式進行合作,而不必嚮應用程式程式碼的其餘部分公開。例如,用於生成圖形使用者介面的框架可以提供“控制元件”類和“窗體”類,這些類通過使用具有內部訪問能力的成員進行合作。由於這些成員是內部的,它們不向正在使用框架的程式碼公開。在定義具有內部訪問能力的成員的程式集外部引用該成員是錯誤。

25、JAVA的程式碼是半編譯半解釋的,C#程式碼是否也是這樣的?

C#原始碼經過語言編譯器執行第一次編譯,變為中間語言,然後再由CLR編譯成可執行程式碼。

26、私有程式集與共享程式集有什麼區別?

私有程式集:

(1)預設情況下,C#程式編譯為私有程式集。

(2)需要放在應用程式所在的資料夾中。

(3)程式集的名稱在應用程式中應當是唯一的。

共享程式集:

(1)可以被不同的應用程式共享。

(2)在所有使用程式集的應用程式中,程式集名稱應當是唯一的。

(3)放在全域性程式集快取中。

27、請解釋程序與執行緒的區別?程序與程式的區別?

用最簡短的話來說,程序就是當前執行的應用程式。執行緒是作業系統向其分配處理器時間的基本單位。執行緒可執行程序的任何一部分程式碼,包括當前由另一執行緒執行的部分。

28、CLR與IL分別是什麼含義?

CLR(共同語言執行庫):能管理記憶體,能夠輕鬆地設計其物件可以跨語言互動的元件和應用程式,編譯一次,並可以在任何支援執行庫的CPU和作業系統上執行,跨語言整合(特別是跨語言繼承)。

IL(中間語言):可用於語言互操作性,IL不是位元組程式碼,但很接近位元組程式碼,因此執行應用程式時,IL到機器程式碼的轉換要快很多。獨立於CPU的指令集。由CLR轉換為特定於CPU的程式碼。

29、物件能否呼叫靜態方法?

物件能呼叫靜態方法。

30、請編寫建立一個執行緒的程式碼?

public class ThreadDemo

{

public static void Main(string[] args)

{

System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(DoWork));

}





public static void DoWork()

{

try

{

while(true)

{

Console.WriteLine("進入執行緒執行...");

System.Threading.Thread.Sleep(2000);

}

}

catch(Exception ex)

{

Console.WriteLine(ex.Message);

}

}

}

原文連結:https://blog.csdn.net/zlbdmm/article/details/103788924

版權申明:本文來源於網友收集或網友提供,僅供學習交流之用,如果有侵權,請轉告版主或者留言,本公眾號立即刪除。