1. 程式人生 > WINDOWS開發 >.Net/C# 面試題總結

.Net/C# 面試題總結

.Net 面試題彙總#

一、基礎概念

1. 簡述 private,protected,public,internal 修飾符的訪問許可權

  • private:私有成員,在類的內部才可以訪問(只能從其生命上下文中進行訪問)
  • protected:保護成員,該類內部和從該類派生的類中可以訪問。
  • friend: 友元,宣告friend元素的程式集中的程式碼可以訪問該元素,而不能從程式集外部訪問。
  • protected friend : 在派生類或同意程式集內部都可以訪問。
  • public : 公共成員,完全公開,沒有訪問限制。
  • internal,當前程式集內可以訪問。

2. 列舉ASP.NET 頁面之間傳遞值的幾種方式

  • 使用QueryString,如 ...?id=1; response.Redirect()
  • 使用session變數
  • 使用Server.Transfer
  • 使用Application
  • 使用Cache
  • 使用HttpContext的Item屬性
  • 使用檔案
  • 使用資料庫
  • 使用Cookie

3. C#中的委託是什麼? 事件是不是一種委託?

  • 委託可以把一個方法作為引數帶入另一個方法。
  • 委託可以理解為指向一個函式的指標。

委託和事件的區別:

  • 委託和事件沒有可比性,委託是型別,事件是物件
  • 事件的內部是用委託實現的,因為對事件來講外部只能 “ 註冊自己 += 或登出自己: -= ”,外界不可以登出其他的註冊,外界不可以主動觸發事件,因此如果用Delegate
    就沒法進行上面的控制,因此誕生類事件這種語法。
  • 事件是用來閹割委託例項的,類比用一個自定義類閹割List
  • 事件只能Add、Remove自己,不能賦值,事件只能用 +=-= 而不能用 =
  • 加分項:事件內部就是一個private的委託和add,remove兩個方法。

4.實現多型過程中,overload過載與override重寫的區別?

  • 過載時方法的名稱相同,引數或引數型別不同,進行多次過載可以適應不同的需要,過載overload是面向過程的概念
  • 重寫 override 是進行基類中函式的重寫(virtual函式),是面向物件的概念

5.描述一下C#中索引器的實現過程,是否只能根據數字進行索引?

索引器簡介

C#通過提供索引器,可以像處理陣列一樣處理物件。特別是屬性,每一個元素都以一個get或set方法暴露,索引器不單能索引數字(陣列下標),
還能索引一些HashMap的字串,所以通常來說,C# 中類的索引器通常只有一個,就是this,單也可以有無數個,只要你的引數列表不同就可以了,
索引器最大的好處是程式碼看起來很自然,很符合實際的思考模式。
  • 索引器允許類或結構的例項按照與陣列相同的方式進行索引
  • 索引器類似於屬性,不同之處在於他們的訪問採用引數

微軟範例:

class SampleCollection<T>
{
    private T[] arr = new T[100];
    //this關鍵字用於定義索引器
    public T this[int i]
    {
        get { return arr[i]; }
        set { arr[i] = value; }
    }
}

//使用索引器查詢
class Program
{
    static void Main(string[] args)
    {
        SampleCollection<string> sampleCollection = new SampleCollection<string>();
        sampleCollection[0] = "Hellow world";
        Console.WriteLine(sampleCollection[0]);
    }
}

總結:

  • 索引器使得物件可以按照與陣列相似的方法進行索引。
  • get 訪問器返回值,set訪問器分配值。
  • this 關鍵字用於定義索引器
  • value關鍵字用於定義由set索引器分配的值
  • 索引器不必根據整數值進行索引,由您決定如何定義查詢機制(即索引的index值由你自己定義型別)。
  • 索引器可被過載
  • 索引器可以有多個形態,例如訪問二維陣列時。

6.用.net 做B/S 結構的系統,您是用幾層結構來開發,每一層之間的關係以及為什麼要這樣分層?

答:一般是用 MVC 模式分層,一般分為 3 層,資料訪問層,業務層,表示層。

  • 優點:分工明確,條理清晰,易於除錯
  • 缺點:增加成本

7.ADO.NET 中的 5 個物件分別是什麼?

  • Connection:主要開啟程式和資料庫之間的連線,沒有利用連線物件將資料庫開啟,是無法從資料庫中獲取資料的。Close和Dispose的區別:Close以後還可以Open,Dispose以後則不能用。

  • Command: 主要可以用來對資料庫發出一些指令,例如可以對資料庫下達 增刪改查 資料等指令,以及呼叫存在資料庫中的儲存過程等。這個物件是架構在Connection物件上的,也就是Command物件是透過連線到資料來源。

  • DataAdapter:主要是在資料來源及DataSet之間執行資料傳輸工作,它可以透過Command物件下達命令後,並將取得的資料放入DataSet物件中。這個物件是架構在Command物件上,並提供了許多配合DataSet使用的功能。

  • DataSet: 這個物件可以看成是一個暫存區(Cache),可以把從資料庫中查詢到的資料儲存起來,甚至可以將整個資料庫顯示出來,DataSet是放在記憶體中的。 DataSet的能力不只是可以儲存多個Table而已,還可以透過DataAdapter 物件取得一些例如主鍵等的資料庫表結構,並可以記錄資料表之間的關聯。DataSet可以說是ADO.NET中重量級物件,這個物件架構在DataAdapter上,本身不具備和資料來源溝通的能力,也就是說我們是將DataAdapter物件當做DataSet物件以及資料來源間傳輸資料的橋樑。DataSet包含DataTable,DataTable包含DataRow

  • DataReader:當我們迴圈讀取資料而不需要其他操作時,可以使用DataReader物件,DataReader物件只是一次一筆向下迴圈讀取資料來源中的資料,這些資料時儲存在資料庫伺服器中的,而不是一次性載入到程式記憶體中的,只能(通過遊標)讀取當前行的資料,而這些資料是隻讀的,並並不允許其他的操作。因為DataReader限制了每次只讀一筆,而且只能只讀,所以使用起來不但節省資源,而且效率好。使用DataReader物件除效率高之外,因為不用把資料全部傳回,故降低了網路負載。

總結:

  • ADO.NET 使用 Connection 物件來連線資料庫,使用 CommandDataAdapter 物件來執行SQL語句,並將執行的結果返回給DataReaderDataAdapter,然後再使用取得的 DataReaderDataAdapter 物件操作資料結果。

8.屬性和public欄位的區別是什麼?呼叫set方法為一個屬性設值,然後用get方法讀取出來的值一定是set進去的嗎?

  • 屬性可以對值、取值的過程進行非法控制,比如年齡禁止設定成負數,而欄位不能進行這樣的設定。

  • 雖然一般情況下,get讀取的值就是set設定進去的值,但是可以讓get讀取的值不是set設定的值,例子如下:

      public class Person
      {
          public int Age
          {
              get { return 30; }// 此時get固定返回30,這裡不論set什麼值,讀取永遠返回30
              set { }
          }
      }
    
      //Main中呼叫如下
      Person person = new Person();
      person.Age = 31;
      person.Age++;
      Console.WriteLine(person.Age);// 輸出30,因為get屬性始終是30
    

9.什麼是裝箱(boxing)和拆箱(unboxing)?

Object是引用型別,但是它的子類Int32不能去Object能去的“ 要求必須是引用型別 ”的地方,違反了繼承原則,所以要把Int32 裝在Object中才能傳遞。

  • 裝箱 :從值型別介面轉換到引用型別。

  • 拆箱 :從引用型別轉換到值型別。

      object obj = null;//引用型別
      obj = 1;//裝箱(boxing),把值型別包裝成引用型別
      int i1 = (int)obj;//拆箱(unboxing),把引用型別轉換為值型別
    
  • 注意:不能將引用型別賦值給值型別,如下程式碼會報錯

      int i=10;
      object obj = i;
      int j = obj;//報錯,拆箱需要進行顯示轉換
      //這樣才行
      int j = (int)obj
    

拆箱和裝箱必須涉及瞭解CTS:

  • CTS 即通用型別系統(Common Type System),CTS是為了實現在應用程式宣告和使用於這些型別時必須遵守的規則而存在的通用型別系統。
    .NET 將整個系統型別分為兩大類,值型別和引用型別
  • CTS 中所有東西都是物件。所有物件都繼承自System.Object類。值型別的最大特點是他們不能為null,值型別的變數總有一個值,(例如用
    int x; 宣告的值型別雖然未賦值,但是預設值為0),為了 解決值型別不可以為null 而引用型別可以為null的問題,微軟在.Net中引入裝箱和拆箱。
  • 裝箱就是將值型別用引用型別包裝起來轉換為引用型別,拆箱就是從引用型別中拿到被包裝的值型別資料。

10.CTS、CLS、CLR 分別是什麼?

  • CTS:Common Type System 通用型別系統Int32、Int16→int、String→string、Boolean→bool。每種語言都定義了自己的型別,.Net通過CTS提供了公共的型別,然後翻譯生成對應的.Net型別。
  • CLS:Common Language Specification 通用語言規範。不同語言語法的不同。每種語言都有自己的語法,.Net通過CLS提供了公共的語法,然後不同語言翻譯生成對應的.Net語法。
  • CLR:Common Language Runtime 公共語言執行時,就是GC、JIT等這些。有不同的CLR,比如伺服器CLR、Linux CLR(Mono)、Silverlight CLR(CoreCLR)。相當於一個發動機,負責執行IL。
  • JIT: Just In-Time compile 即時編譯,這是.NET執行可執行程式的基本方式,也就是在需要執行的時候,才將對應的IL程式碼編譯為本機指令

11..net中,類(class)與結構(struct)的異同?

  • (class)可以被例項化,屬於 引用型別,是分配在記憶體中的 堆上 的,類是引用傳遞的。
  • 結構(struct)屬於 值型別,是分配在記憶體中的 棧上的,結構體是賦值傳遞的, Int32、Boolean 等都屬於結構體。

12.堆(Heap)和棧(Stack)的區別?

  • 棧是 編譯期間就分配好的記憶體空間,因此你的程式碼中必須就棧的大小有明確的定義。區域性值型別變數,值型別引數等都在棧記憶體中。
  • 堆是 程式執行期間動態分配的記憶體空間,你可以根據程式的執行情況確定要分配的堆記憶體大小。

13.能用foreach遍歷訪問的物件的要求是什麼?

  • 需要實現 IEnumerable 介面或宣告 GetEnumerator 方法的型別。
  • 注意:不一定要實現 IEnumerable 但是 GetEnumerator 必須要宣告。

14.GC 是什麼?為什麼要有GC?

  • GC 即垃圾收集器(Garbage Collection),程式設計師不用擔心記憶體管理,因為垃圾回收器會自動進行管理。GC 只能處理託管記憶體資源的釋放,對於非託管資源不能使用GC進行回收,必須由程式設計師手工回收,一個例子就是FileStream或者SqlConnection需要程式設計師呼叫Dispose進行資源的回收。
  • 請求垃圾回收,可以呼叫GC.Collect(),但一般這個不需要手動呼叫,當一個物件在沒有任何變數指向(不再能使用)時就可以被回收了。
  • 基礎知識:當沒有任何變數指向一個物件的時候,就可以被回收了,但不一定立即回收。

15.值型別和引用型別的區別

  • 將一個值型別變數賦給另一個值型別變數時,將複製包含的值。引用型別變數的賦值只複製對物件的引用,而不復制物件本身。
  • 值型別不可能派生出新的型別:所有的值型別均隱式派生自 System.ValueType。但與引用型別相同的是,結構也可以實現介面。
  • 值型別不可能包含 null 值:然而,可空型別(如int?)功能允許將 null 賦給值型別。
  • 每種值型別均有一個隱式的預設建構函式來初始化該型別的預設值。

16.C# 中介面和類有什麼區別?

不同點:

  • 不能直接例項化介面
  • 介面不包含方法實現
  • 介面可以多繼承,類只能單繼承
  • 類定義可在不同原始檔之間進行拆分

相同點:

  • 介面、類、結構都可以從多個介面繼承
  • 介面類似於抽象基類,繼承介面的任何非抽象型別都必須實現介面的所有成員。
  • 介面和類都可以包含事件,索引器,方法和屬性。

基礎知識:介面只能定義方法(只能定義行為,不能定義實現也就是欄位),因為事件、索引器、屬性本質上都是方法,所以介面中也可以定義事件、索引器、屬性。

17. 抽象類(abstract class)和介面(interface)有什麼區別?

相同點:

  • 都不能被直接例項化,都可以通過繼承來實現抽象方法。

不同點

  • 介面支援多繼承;抽象類不能實現多繼承。
  • 介面只能定義行為;抽象類既可以定義行為,還可以提供實現。
  • 介面只可包含方法method)、屬性property)、索引器index)、事件event)的 簽名,但 不能定義欄位包含實現的方法; 抽象類 可以定義欄位、屬性、包含有實現的方法。
  • 介面可以用於值型別struct),和引用型別class),而抽象類只能作用於 引用型別。例如struct就可以繼承介面,而不能繼承類。

18.是否可以繼承String類?

  • String 類是sealed(密封類)故不可以繼承。

19.int、DateTime、string 是否可以為null?

  • null表示不知道,而不是沒有,沒有年齡和不知道年齡是兩碼事, 資料庫中null不能用0表示,0歲和不知道多少歲數不一樣。
  • string可以為 null,而int(值型別)和DateTime(為struct型別也是值型別),值型別不能為null
  • C# 中,int值型別不可以為null,而 資料庫中int是可以為null的。 int?、DateTime?、bool? 變成了 可空型別

如下:

int i1 = null;// int是值型別,值型別不能為null,會報錯
int? i2 = null;// 值型別後面加 ? 就變成了可空型別。
int i3 = i2;//(報錯) 把可空型別賦值給值型別,一定會報錯。
int i4 = (int)i2; //可以顯示轉換,由程式設計師保證 賦值不能為空。
int? i5 = i4;// 一定會成功,因為將值型別賦值給可空型別是允許的。
//注意:
int? 翻譯生成.Net 的Nullable<int>,CTS 

注意:

int? 是微軟的一個語法糖,是一種int沒有直接關係的Nullable 型別。

Nullable<int> d1 = new Nullable<int>();//int? d1=null;
Nullable<int> d2 = new Nullable<int>(3);//int? d2=3;
Console.WriteLine(d1==null);

20.using關鍵字有什麼用?什麼是IDisposable?

  • using可以宣告namespace的引入,還可以實現非託管資源的釋放,實現了IDisposiable的類在using中建立,using結束後會自動呼叫該物件的Dispose 方法,釋放資源。

    (1)引用名稱空間

      	using System;//引用名稱空間
    

    (2)建立別名

      	using aClass = test1.MyClass; //建立別名
    

    (3)實現非託管資源釋放

      	// test類 必須實現IDisposiable 介面,using結束後會自動呼叫該物件的Dispose 方法釋放資源
      	using (test t = new test())
      	{
      	    ........
      	}
    
  • 程式在編譯階段,編譯器會自動將using語句生成為 try-finally語句,並在finally程式碼塊中呼叫Dispose方法,來清理資源。所以using語句等效於try-finally語句。(加分項

21.XML 與 HTML 的主要區別

  • XML是區分大小寫字母的,HTML不區分。

  • 在HTML中,如果上下文清楚地顯示出段落或者列表鍵在何處結尾,那麼你可以省略</p>或者</li>之類的結束 標記。在XML中,絕對不能省略掉結束標記

      HTML:<img src="1.jpg"><br><br>
      XML:<img src="1.jpg"></img><br/><br/>
    
  • 在XML中,擁有單個標記而沒有匹配的結束標記的元素必須用一個 / 字元作為結尾。這樣分析器就知道不用 查詢結束標記了。

  • 在XML中,屬性值必須分裝在引號中。在HTML中,引號是可用可不用的。

  • 在HTML中,可以擁有不帶值的屬性名。在XML中,所有的屬性都必須帶有相應的值。

切記: XML是用來 儲存和傳輸 資料的,HTML是用來顯示資料

22. string str = null 與 string str = "" 說明其中的區別。

string str = null //是不給它分配記憶體空間,而string str = \"\" 給他分配長度為空字串的記憶體空間。
string str = null //沒有string物件,string str = "" 有一個字串物件。
例如:
string s3 = string.Empty; // 反編譯發現,string.Empty就是在類建構函式中 Empty = "";

23、寫出一條Sql語句:取出表A中第31到第40記錄(SQLServer,以自動增長的ID作為主鍵,注意:ID可能不是連續的。

答:解1: select top 10 * from A where id not in (select top 30 id from A)

演變步驟:
1)select top 30 id from T_FilterWords--取前條
2)select * from T_FilterWords
where id not in (select top 30 id from T_FilterWords)--取id不等於前三十條的

--也就是把前條排除在外

3)select top 10 * from T_FilterWords    
where id not in (select top 30 id from T_FilterWords)

--取把前條排除在外的前條,也就是-40條

解2: select top 10 * from A where id > (select max(id) from (select top 30 id from A )as A)

24、.Net中,所有可以被序列化的類都標記為: [serializable]

25.什麼是code-Behind 技術?

  • 就是程式碼隱藏,在ASP.NET中通過ASPX頁面指向CS檔案的方法 實現顯示邏輯和處理邏輯的分離,這樣有助於web應用程式的建立。比如分工,美工和程式設計的可以個幹各的,不用再像以前asp那樣都程式碼和html程式碼混在一起,難以維護。 code-Behind基於部分類技術實現的,在我的專案的三層程式碼生成器中用到了部分類。

26.介面是一種型別,在介面中可以宣告(方法、屬性、索引器和事件),但不可以宣告 公有的域私有的成員變數

  • 解析:
    介面中,不能宣告欄位,只能宣告方法屬性索引器事件,最終都編譯生成方法。因為欄位屬於實現層面的東西,只有存取值的時候才會用到欄位,所以介面中不能定義欄位

27.在ADO.NET 中,對於Command物件的ExecuteNonQuery()方法和ExecuteReader()方法,下面描述錯誤的是(C

  • A) insert、update、delete等操作的Sql語句主要用 ExecuteNonQuery() 方法來執行;
  • B) ExecuteNonQuery()方法返回執行Sql語句所影響的行數。
  • C) Select操作的Sql語句只能由 ExecuteReader() 方法來執行;
  • D) ExecuteReader() 方法返回一個 DataReader 物件;

28、StringBuilder 和 String 的區別?

  • String 在進行運算時(如賦值、拼接等)會產生一個新的例項,而StringBuilder 則不會。
  • 大量字串拼接或頻繁操作某個字串時,最好用StringBuilder,不要使用String ,也就說StringBuilder 效率更高。

詳解:

  • 如果要操作一個不斷增長的字串,儘量不用String類,改用StringBuilder類。兩個類的工作原理不同:String類是一種傳統的修改字串的方式,它確實可以完成把一個字串新增到另一個字串上的工作沒錯,但是在.NET框架下,這個操作實在是划不來。因為系統先是把兩個字串寫入記憶體,接著刪除原來的String物件,然後建立一個String物件,並讀取記憶體中的資料賦給該物件。這一來二去的,耗了不少時間。

  • 例如:要s3 = s1+s2,其實是建立了新物件s3,同時將s1,s2刪除,拿出二者值賦值給s3,最終在建立新物件s3,效率是比較低的。

  • 而使用System.Text名稱空間下面的StringBuilder類就不是這樣了,它提供的Append方法,能夠在 已有物件的原地進行字串的修改,簡單而且直接。當然,一般情況下覺察不到這二者效率的差異,但如果你要對某個字串進行大量的新增操作,那麼StringBuilder類所耗費的時間和String類簡直不是一個數量級的

29.請敘述屬性與索引器的區別:

屬性 索引器
通過名稱標識 通過簽名標識
通過簡單名稱或成員來訪問 通過元素來訪問
可以為靜態成員或例項 必須為例項成員
屬性的get訪問器沒有引數 索引器的 get 訪問器具有與索引器相同的形參表。
屬性的set訪問器包含隱式value引數 除了value 引數外,索引器的set訪問器還具有與索引器相同的形參表

31.在什麼情況下,會用到虛方法(virtual)?它與介面有什麼不同?

  • 子類重新定義父類的某一個方法時,必須把父類方法定義為 virtual,在定義介面中不能有方法體,虛方法可以定義方法體。
    實現虛方法時,子類可以不重新定義虛方法,但如果一個類繼承介面,那必須實現這個介面。

32. DataReader 和 DataSet 的區別?

  • DataReader使用時始終佔用 SqlConnection,線上操作資料庫,每次只在記憶體中載入一條資料,所以佔用的記憶體是很小的,
    只進的只讀的。
  • DataSet則是將資料一次性載入在記憶體中,拋棄資料庫連線(close),讀取完畢即放棄資料庫連線( 非連線模式)
    DataSet將資料全部載入在記憶體中,所以比較消耗記憶體,但是確比DataReader要靈活,可以動態的新增行、列、資料,對資料庫進行回傳更新操作(動態操作讀入到記憶體的資料)。

33.public static const int A = 1;這段程式碼有錯誤麼?

  • 錯誤,const 不能被修飾為static,因為常量(const)定義後就是靜態的(static)。

34.傳入某個屬性的set方法的隱含引數的名稱是什麼?

  • value 它的型別和屬性所宣告的型別相同。

    例如:定義一個屬性set方法給code賦值,隱含引數就是value

      private string code;
      public string Code
      {
          get { return code; }
          set { code = value; }// value 為隱含引數
      }
    

35.C# 支援多繼承嗎?

  • 類之間不支援多繼承,介面之間支援。類對介面叫實現,不叫繼承。類是爹、介面是能力,能有多個能力但不能有多個爹。

36. C# 中所有物件的共同基類是什麼?

  • System.Object

37. 通過超連結怎麼傳遞中文引數?

  • 用URL 編碼,通過 QueryString 傳遞,用urlencode編碼,用urldecode 解碼。

38.string、String;int、Int32;Boolean、bool的區別

  • String、 Int32、 Boolean 都屬於.net中定義的類,而string、int、 bool相當於C#中對這些類定義的別名(CTS)

39.Server.Transfer和Response.Redirect的區別是什麼?(常考)

  • Server.Execute 效果和 Server.Transfer類似,但是是把執行的結果嵌入當前頁面。
Server.Transfer Response.Redirect
僅是伺服器中 控制權的轉向,在客戶端瀏覽器位址列中不會顯示出轉向後的地址 是完全的跳轉,瀏覽器將會得到跳轉的地址,並重新發送請求連結。這樣,從瀏覽器的位址列中可以看到跳轉後的連結地址
是伺服器請求資源,伺服器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,然後把這些內容再發給瀏覽器,瀏覽器根本不知道伺服器傳送的內容是從哪兒來的,所以它的位址列中還是原來的地址。 這個過程中瀏覽器和Web伺服器之間經過了一次互動。 就是服務端根據邏輯,傳送一個狀態碼,告訴瀏覽器重新去請求那個地址,一般來說瀏覽器會用剛才請求的所有引數重新請求。這個過程中瀏覽器和Web伺服器之間經過了兩次互動
不可以轉向外部網站 可以轉向外部網站

40.不是說字串是不可變的嗎?string s = "abc"; s="123"; 不就變了嗎?

  • String是不可變的在這段程式碼中,s原先指向一個String物件,內容是 "abc",然後我們將s指向"123",那麼s所指向的那個物件是否發生了改變呢? 答案是沒有。這時,s不指向原來那個物件了,而指向了另一個 String物件,內容為"123",原來那個物件還存在於記憶體之中,只是s這個引用變數不再指向它了。

41.是否可以從一個static方法內部發出對非static方法的呼叫?

  • 不可以。 因為 非static方法是要與物件關聯在一起的,必須建立一個物件後,才可以在該物件上進行方法呼叫,而static方法呼叫時不需要建立物件,可以直接呼叫。
  • 也就是說,當一個static方法被呼叫時,可能還沒有建立任何例項物件,如果從一個static方法中發出對非static方法的呼叫,那個非static方法是關聯到哪個物件上的呢?這個邏輯無法成立,所以,一個static方法內部不能發出對非static方法的呼叫。

42、說出一些常用的類、介面,請各舉5個

常用的類 常用的介面
StreamReader、WebClient、Dictionary、StringBuilder、SqlConnection、FileStream、File、Regex、List IDisposable、IEnumerable、IDbConnection、IComparable、ICollection、IList、IDictionary

43、編寫一個單例(Singleton)類

44.什麼是sql 注入?

  • 使用者根據系統的程式構造非法的引數而導致程式執行不是程式設計師期望的惡意SQL語句,使用引數化的SQL就可以避免SQL 注入。

如何防止SQL 注入攻擊:

  • 不要使用動態SQL;避免將使用者提供的輸入直接放到SQL中,最好使用準備好的語句和引數化查詢。
  • 不要將敏感資料儲存在純文字中;加密儲存在資料庫中的私有/機密資料;這樣可以提供另一級保護,以防攻擊者成功地排出敏感資料。
  • 限制資料庫許可權和特權;將資料庫使用者的功能設定為最低要求,這將限制攻擊者在設法獲取訪問許可權時可以執行的操作。
  • 避免直接向用戶展示錯誤資訊;攻擊者可以通過這些錯誤資訊來獲取資料庫的資訊。

45、資料庫三正規化是什麼?

  • 第一正規化:欄位不能有冗餘資訊,所有欄位都是必不可少的。
  • 第二正規化:滿足第一正規化並且表必須有主鍵。
  • 第三正規化:滿足第二正規化並且表引用其他的表必須通過主鍵引用。
  • 員工內部→自己的老大→外部的老大
  • 記憶順序:自己內部不重複→別人引用自己→自己引用別人。

46、post、get的區別(必考)

GET POST
get的引數會顯示在瀏覽器位址列中 post的引數不會顯示在瀏覽器位址列中
get提交點選重新整理時,瀏覽器不會提示“是否重新提交” post 提交頁面在點選重新整理按鈕時,瀏覽器一般會提示“是否重新提交”
用get的頁面可以被搜尋引擎抓取 用post則不可以
get 提交時,資料量通常比較小(2K),受限於網頁地址長度 post提交資料量可以非常大
get 不可以進行檔案提交 post 可以進行檔案提交

常用http 狀態碼

  • 1開頭:資訊狀態碼

  • 2開頭:成功狀態碼

  • 3開頭:重定向狀態碼

  • 4開頭:客戶端錯誤狀態碼

  • 5開頭:服務端錯誤狀態碼

      1XX:資訊狀態碼		
          100 |繼續| 初始的請求已經接受,請客戶端繼續傳送剩餘的部分
          101	|切換協議|	請求這要求伺服器切換協議,伺服器已確定切換
      2XX:成功狀態碼
          200 |成功| 伺服器已成功處理了請求
      3XX :重定向
          300	|多種選擇|	針對請求,伺服器可執行多種操作
      4XX:客戶端錯誤狀態碼
          400	|錯誤請求|	伺服器不理解請求的語法(Bad request)
          401	|未授權|	請求要求使用者的身份演驗證
          403	|禁止|	伺服器拒絕請求
          404	|未找到|	伺服器找不到請求的頁面
          408	|請求超時|	伺服器等候請求時發生超時
      5XX:服務端錯誤狀態碼
          500	|伺服器錯誤|	伺服器內部錯誤,無法完成請求
          501	|尚未實施|	伺服器不具備完成請求的功能
          503	|服務不可用|	伺服器目前無法使用
          504	|閘道器超時|	閘道器或代理伺服器,未及時獲取請求
    

47、.Net、ASP.Net、C#、VisualStudio之間的關係是什麼?

  • .Net一般指的是.Net Framework,提供了基礎的.Net類,這些類可以被任何一種.Net程式語言呼叫,.Net Framework還提供了CLR、JIT、GC等基礎功能。
  • ASP.Net.Net中用來進行Web開發的一種技術,ASP.Net的頁面部分寫在aspx檔案中,邏輯程式碼通常通過Code-behind的方式用C#、VB.Net等支援.Net的語言編寫。
  • C#是使用最廣泛的支援.Net的程式語言。除了C#還有VB.Net、IronPython等。
  • VisualStudio是微軟提供的用來進行.Net開發的整合開發環境(IDE),使用VisualStudio可以簡化很多工作,不用程式設計師直接呼叫csc.exe等命令列進行程式的編譯,而且VisualStudio提供了程式碼自動完成、程式碼高亮等功能方便開發。除了VisualStudio,還有SharpDevelop、MonoDevelop

48、AJAX解決什麼問題?如何使用AJAX?AJAX有什麼問題需要注意?專案中哪裡用到了AJAX?

  • Ajax 解決的問題就是“無需重新整理頁面”,使用Ajax 是非同步無需頁面重新提交重新整理。
  • Ajax 最本質的實現是在Javascript中使用XMLHttpRequest進行Http的請求.
  • AJAX最重要的問題是無法跨域請求(www.rupeng.com →so.rupeng.com),也就是無法在頁面中向和當前域名不同的頁面傳送請求,可以使用在當前頁面所在的域的服務端做代理頁面的方式解決。

49、Application 、Cookie和 Session 兩種會話有什麼不同?

  • Application是用來存取整個網站全域性的資訊,而Session是用來存取與具體某個訪問者關聯的資訊。
  • Cookie是儲存在客戶端的,機密資訊不能儲存在Cookie中,只能放小資料;Session是儲存在伺服器端的,比較安全,可以放大資料。

50.什麼是受管制(託管)的程式碼?

  • 託管程式碼是執行.NET 公共執行時CLR 的程式碼。
  • 非託管程式碼(unsafe),不經過CLR 執行,程式設計師自己分配和釋放記憶體空間,自己提供安全監測、垃圾回收等操作。

注意: Visual Basic .NET和C#只能產生託管程式碼
Visual C++可以建立非託管程式。

51.在.net中,配件的意思是?

  • 程式集(中間語言、元資料、資源、裝配清單)

52.SqlServer 伺服器中,給定表table1 中有兩個欄位ID、LastUpdateDate,ID 表示更新的事物號,LastUpdateDate 表示更新時的伺服器時間,請使用一句SQL 語句獲取最後更新的事物號。

Select ID FROM table1 Where LastUpdateDate = (Select MAX(LastUpdateDate) FROM table1)

53.String s = new String("xyz");建立了幾個String Object?

  • 兩個物件,一個是字串常量"xyz",一個是指向"xyz"的引用物件s。

解釋:

  • 第一個物件是字串常量 "xyz",儲存於常量池中,第二個物件是 new String("xyz") 時產生的,在中分配記憶體給這個物件,只不過這個物件的內容是指向字串常量 "xyz"
    另外還有一個引用 s,指向第二個物件。這是一個變數,在棧中分配記憶體。

54.如何處理幾十萬條併發資料?

  • 用儲存過程或事務,取得 最大標識的時候同時更新,注意主鍵不是自增量方式這種方法併發的時候是不會有重複主鍵的,取得最大標識通常用一個儲存過程來獲取。

55.成員變數和成員函式前加static的作用?

  • 它們被稱為常成員變數常成員函式,又稱為 類成員變數類成員函式。分別用來反映類的狀態。
  • 例如,類成員變數可以用來統計類例項的數量,類成員函式負責這種統計的動作。

56.請給出GAC 的含義

  • 全域性程式集快取,就是存放各類.net 平臺下面需要使用的dll的地方。
  • GAC 具體目錄是在windows/assembly 下面。

57.什麼是SOAP,有哪些應用?

  • Simple object access protocal(簡單物件接受協議),以xml 為基本編碼結構,建立在已有通訊協議上(如http,不過據說ms在搞最底層的架構在tcp/ip上的soap)的一種規範Web Service使用的協議。
  • 簡單說:SOAP 是用於訪問網路服務的協議,是一種通訊協議,用於應用程式之間的通訊,用於傳送訊息的格式,用來通過Internet進行通訊。
  • SOAP,獨立於平臺,獨立於語言,基於XML,簡單可擴充套件,允許繞過防火牆,被作為W3C標準來發展。

58.C# 中Property 和 Property 區別?各有什麼用處?這種機制的好處在哪裡?

在C#中有兩個屬性,分別為PropertyAttribute

  • Property比較簡單,就是我們常用的get和set,主要用於為類中的private和protected變數提供讀取和設定的介面。
  • Attribute 用來說明這個事物特徵的一種描述,它允許你將資訊與你定義的C# 類向關聯,作為型別的標註。

Attribute就是幹這事的。它允許你將資訊與你定義的C#型別相關聯,作為型別的標註。這些資訊是任意的,就是說,它不是由語言本身決定的,你可以隨意建立和關聯任何型別的任何資訊。你可以作用屬性定義設計時資訊和執行時資訊,甚至是執行時的行為特徵。關鍵在於這些資訊不僅可以被使用者取出來作為一種型別的標註,它更可以被編譯器所識別,作為編譯時的一種附屬條件參加程式的編譯。定義屬性:屬性實際上是一個派生自System.Attribute基類的類。System.Attribute類含有幾個用於訪問和檢查自定義屬性的方法。儘管你有權將任何類定義為屬性,但是按照慣例來說,從System.Attribute派生類是有意義的。

59.Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其它類,是否可以implements(實現)interface(介面)?

  • 匿名類內部不能繼承其他類,但可以實現介面

60.&&& 的區別?

  • & 是位運算子,表示按位運算,&& 是邏輯運算子,表示邏輯與(and)。

  • 一假則假,1為真,0為假,17將與23進行按位與(&)運算:得到的結果轉換為十進位制就是17

    0000 0000 0001 0001

    0000 0000 0001 0111


    0000 0000 0001 0001

61.HasMap 和Hashtable 的區別?

  • HasMapHashtable 的輕量級實現(非執行緒安全的實現),他們都完成了Map 介面,主要區別在於 HashMap 允許空(null)鍵值(key),由於非執行緒安全,效率上可能高於 Hashtable
  • C# 中是沒有HashMap 這個類的,這個型別對應的key-value 型別為HashTable 或 Dictionary (Java 中才有HashMap 這個類)

62.<%# %><% %> 有什麼區別?

  • <%# %>表示繫結的資料來源<% %>伺服器端程式碼塊

63. .net的Remoting 的工作原理是什麼?

  • 伺服器端向客戶端傳送一個程序編號,一個程式域編號,以確定物件的位置。

64.啟動一個執行緒是用run()還是start()?

  • 啟動一個執行緒是呼叫start() 方法,使得執行緒所代表的虛擬處理機處於可執行狀態,這意味著它可以由JVM 排程並執行,但這並不意味著執行緒就會立即執行。

  • run() 方法可以產生必須退出的標誌來停止一個執行緒。

  • 啟動執行緒:

      class ThreadCreationProgram
      {
          public static void CallToChildThread()
          {
              Console.WriteLine("Child thread starts");
          }
         
          static void Main(string[] args)
          {
              ThreadStart childref = new ThreadStart(CallToChildThread);// 建立執行緒物件,並傳入執行緒函式
              Thread childThread = new Thread(childref);// 建立執行緒物件
              childThread.Start();// 啟動一個執行緒,為子執行緒
              Console.ReadKey();
          }
      }
    
  • Sleep(t) 用於掛起執行緒多少毫秒,Abort() 為銷燬執行緒。

65.sleep() 和 wait() 有什麼區別?

  • sleep()方法是使執行緒停止一段時間的方法。在sleep時間間隔期滿後,執行緒不一定立即恢復執行。這是因為在那個時刻,其它執行緒可能正在執行而且沒有被排程為放棄執行,除非(a)“醒來”的執行緒具有更高的優先順序(b)正在執行的執行緒因為其它原因而阻塞。
  • wait()是執行緒互動時,如果執行緒對一個同步物件x發出一個wait()呼叫,該執行緒會暫停執行,被調物件進入等待狀態,直到被喚醒或等待時間到。

66.陣列有沒有length() 方法? String有沒有length() 方法?

  • 陣列沒有 length() 這個方法,只有 length 的屬性。
  • Stringlength() 這個方法。

67.UDP連線和TCP連線的異同。

  • TCP --- 傳輸控制協議(Transmission Control Protocol),提供的是 面向連線、可靠的位元組流服務。當客戶和伺服器彼此交換資料前,必須先在雙方之間建立一個TCP連線,之後才能傳輸資料。TCP提供超時重發,丟棄重複資料,檢驗資料,流量控制等功能,保證資料能從一端傳到另一端。

  • UDP --- 使用者資料報協議(User Datagram Protocol),是一個 簡單的面向資料報的運輸層協議。UDP不提供可靠性,它只是把應用程式傳給IP層的資料報傳送出去,但是 並不能保證它們能到達目的地。由於UDP在傳輸資料報前不用在客戶和伺服器之間建立一個連線,且沒有超時重發等機制,故而傳輸速度很快。

68.ref 和 out 的區別?

  • ref 關鍵字使引數按引用傳遞。 其效果是,當控制權傳遞迴呼叫方法時,在方法中對引數所做的任何更改都將反映在該變數中。若要使用 ref 引數,則方法定義和呼叫方法都必須顯式使用 ref 關鍵字
  • out 關鍵字會導致引數通過引用來傳遞。 這與 ref 關鍵字類似,不同之處在於 ref 要求變數必須在傳遞之前進行初始化。若要使用 out 引數,方法定義和呼叫方法都必須顯式使用 out 關鍵字。

69.const 和readonly 的區別?

  • const 用於宣告常量,readonly 用於宣告執行時常量。

常量分為:

  • 靜態常量:指編譯器在編譯的時候會對常量進行解析,並將常量的值替換成初始化的值(const

  • 動態常量:它的值是在執行的那一刻才獲得的,編譯器編譯期將其表示為只讀常量,而不用常量的值代替,這樣動態常量不用再宣告的時候就初始化,而可以延遲到建構函式中等進行初始化。(readonly)

      1. const修飾的常量在宣告的時候必須初始化; readonly修飾的常量則可以延遲到建構函式初始化
      1. const修飾的常量在編譯期間就被解析,即常量值被替換成初始化的值; readonly修飾的常量則延遲到執行的時候
      1. const修飾的常量注重的是效率; readonly修飾的常量注重靈活
      1. const修飾的常量沒有記憶體消耗; readonly因為需要儲存常量,所以有記憶體消耗
      1. const只能修飾基元型別、列舉類、或者字串型別; readonly卻沒有這個限制

例如:靜態常量const宣告,編譯時就指定,高效、不消耗記憶體。

	const double pi = 3.1415926;//初始化宣告時賦值,編譯時就解析,聲明後不能改變常量值
	static void Main(string[] args)
	{
		Console.WriteLine(pi);
	}

例如:動態常量readonly宣告,可以先不指定初值,而可以在建構函式中延遲指定

	class Person
	{
	    public readonly string Name;
	    public Person(string name)
	    {
	        this.Name = name;// 在建構函式中給readonly 常量賦值,一旦賦值,就不能再次改變
	    }
	}

70.什麼是鏈式委託?

  • 鏈式委託是指一個由委託串成的連結串列,當連結串列上的一個委託被回撥時,所有連結串列上該委託的後續委託將會被順序執行。
  • 觸發時分:單播(一次Invoke 一個)多播(Invoke 按次序觸發宣告+=的委託連結串列上的委託)。

71.C#中的 lock 關鍵字有何作用

  • C#中的lock關鍵字實質是呼叫 Monitor.EnterMonitor.Exit兩個方法的簡化語法,功能上其實現了進入和退出某個物件的同步。通常情況下,可以通過 lock一個私有的引用成員變數來完成成員方法內的執行緒同步,而通過lock一個私有的靜態引用成員變數來完成靜態方法內的執行緒同步。

72.下面這段程式碼有錯誤嗎?

switch(i){
    case(): 答://case()條件不能為空
    CaseZero();
    break;
    case1:
    CaseOne();
    break;
    case2:
    dufault; 答://wrong,格式不正確
    CaseTwo();
    break;
}

73.char和varchar和nvarchar的區別?必考

  • char(n):索引效率極高,不管儲存的資料是否到達了n個位元組,都要佔用n個位元組的空間,不足的話用空格填充,所以讀取要用 trim()
  • varchar(n):長度為n個可變長度位元組,非Unicode字元資料。儲存大小為輸入位元組的實際長度
  • nvarchar(n):包含n個可變長度字元,為Unicode字元資料。儲存大小為輸入字元的兩倍

注意:如果包含特殊字元和中文,建議使用nvarchar

74.常用字符集:

  • Unicode:英文也是用2個位元組,標點1個位元組,漢字和標點都是2個位元組,
  • ASCII:英文1個位元組,漢字2個位元組
  • UTF-8:英文1個位元組,漢字3個位元組
  • UTF-16:英文字母字元和漢字字元都是2個位元組
  • UTF-32:所有字元都需要4個位元組

75.Main 函式是什麼?在程式中使用Main函式有什麼需要注意的地方?

  • Main函式就是程式的入口函式
  • 注意:函式的名字不能改變,一個程式中有且只有一個Main函式。

76.值型別的預設值是什麼?(情況一:欄位或全域性靜態變數;情況二:區域性變數)

  • 如果是 全域性變數,並沒有賦值,就會有預設值。(int 是0;bool是false;列舉enum;結構體struct)
  • 如果是 區域性變數,就必須手動賦值。

77.宣告一個變數時在記憶體中做了什麼?初始化一個變數時又在記憶體中做了什麼?

  • 宣告變數時,在棧中開闢記憶體空間,將變數放到空間中,預設值都是null。

初始化時:

  • 如果是值型別,則直接放入棧中;如果是 引用型別,則在 堆中開闢一塊空間,將 堆中物件的地址指標放入棧中

78.new關鍵字能做的事情?

  • 開闢空間、建立物件、呼叫建構函式、返回堆地址、還可以顯示隱藏父類的同名方法。

79.陣列一旦建立後,能不能修改陣列長度?

  • 不能。 因為陣列是 引用型別,在建立時,已經根據建立的長度在記憶體中開闢了 一塊連續的記憶體空間

80.類和物件的關係?

  • 抽象具體的關係。類是抽象,物件是具體,類是對物件的抽象描述,而物件是類的具體化。

81.建立一個類的物件時,在記憶體中做了什麼?例如 Person p = new Person();

  • 開闢空間,建立物件,呼叫建構函式。(在記憶體的堆中開闢記憶體空間,然後在記憶體的 棧中開闢一個放一個 p,然後將Person物件在 堆中的引用地址賦值給物件 p

82.為什麼要有建構函式呢?

  • 主要是方便程式設計師在例項化物件時候就為物件裡的一些屬性欄位 初始化賦值。

83.類的命名規則是什麼

  • 類命名規則:首字母大寫(帕斯卡命名)。變數命名規則:駝峰命名。

84. this關鍵字在方法中使用,它代表什麼?

  • this當前類的物件,或者它 父類 的類物件。
  • base只能指向 父類 的物件。

85.值型別變數初始化(記憶體分配)?(兩種情況:一是類的成員變數,二是:方法的區域性變數)

  • 當變數是一個類的成員變數時,那麼該變數是跟隨類的物件存在於堆中的。當物件引用斷開時,等著垃圾回收器進行清理時變銷燬。
  • 當變數是一個方法的區域性變數時,那麼該變數是在方法被呼叫時,存在於棧中,方法執行完畢後被銷燬。

86.什麼是里氏替換原則?

  • 所有基類出現的地方都可以用 派生類替換 而不會產生錯誤。子類可以擴充套件父類的功能,但不能改變父類原有的功能。例如機動車必須由輪胎和發動機,子類寶馬賓士不應該改寫沒有輪胎或沒有發動機。

SOLID 原則(面向物件的五大原則)

  • 單一職責原則(SRP)- 讓一個類只做一種型別的職責,當該類需要承擔其他職責時,需要分解這個類。
  • 開放封閉原則(OCP)- 軟體實體應該是可擴充套件,而不可修改,即對擴充套件開放,對修改關閉
  • 里氏替換原則(LSP)- 所有基類出現的地方都可以用 派生類替換 而不會產生錯誤。
  • 介面分離原則(ISP)- 使用多個專門的介面比使用單一的介面要好。
  • 依賴倒置原則(DIP)- 高層模組不應該依賴於低層模組,二者都應該依賴於抽象;抽象不該依賴於細節,細節應該依賴於抽象。

87.子類和父類之間的轉換?

  • 子類可以強制轉換為父類,但父類不能轉換為子類。

88、is操作符和 as 操作符的區別是什麼?

  • is對型別的判斷,返回bool (判斷A是否是B 類,或者A 是不是B 的子類),如果一個物件是某個型別或者是其父類的話就返回true,反之false。
  • as 是用來做 型別轉換的,as只能針對引用型別的轉換。as 是先判斷,再轉換(as首先測試轉換是否合法,若合法則轉換,否則返回null,不會報錯)

注意: is 和 as 都不會丟擲異常。

二、.Net Core 相關#

1、什麼是.net core?

  • 首先,它不是Asp.net 的升級版本,它遵循了.net 的標準架構,可以執行在多個作業系統上。它更快,目前.net core 3.0 比Java 和 node.js 要快的多。 它更容易配置,更加模組化,可擴充套件性強。
  • 它可用於構建web應用程式、移動應用程式、桌面應用程式、雲服務、微服務、API、遊戲、物聯網應用。
  • 與其他框架不同,.net core 不侷限於支援單一語言,它支援C#、VB.NET、F#、XAML和TypeScript。這些語言都是開源的由獨立社群管理。

2、.net core 有哪些好的功能?

  • (1)依賴注入。
  • (2)日誌系統架構。
  • (3)引入了一個跨平臺的網路伺服器,kestrel。可以沒有iis,apache和nginx就可以單獨執行。
  • (4)可以使用命令列建立應用。
  • (5)可以使用APP Settings json file 來配置工程。
  • (6)使用start up 來建立服務。
  • (7)更好的支援非同步變成
  • (8)支援web socket 和 signal IR。
  • (9)對於跨網站的請求的預防和保護機制。

3、.net core跟 .net比,有哪些更好的地方?

  • 第一是跨平臺,可以執行在三大作業系統上,Linux、window、Mac。
  • 第二是對架構本身安裝沒有依賴,因為所有的依賴都跟程式本身在一起。
  • 第三是.net core 請求效率更高,能夠處理更多請求。
  • 第四是.net core 有更多的安裝配置的方法。

4、什麼是meta packages?

  • Meta packages是指包含所有ASP .net code 依賴的一個包。叫做Microsoft.AspNetCore

5、.net core 應用能跟.net 4.x架構一起工作嗎?

  • 可以。 .net core應該可以跟標準的.net 庫一起工作。

6、什麼是dot net core的startup class?

  • Startup class是.net core 應用的入口。所有的.net core應用必須有這個class。這個類用來配置應用。這個類的呼叫是在program main函式裡面進行配置的。類的名字可以自己定義。

7、Startup class的config service方法有什麼作用?

  • 在這個方法裡我們可以新增一些service進入依賴注入容器。

8、startup class的configure方法有什麼作用?

  • 這個方法來定義整個應用如何響應HTTP請求。它有幾個比較重要的引數,application builder,Hosting environment,logo factory, 在這裡我們可以配置一些中介軟體用來處理路徑,驗證和session等。

9、什麼是中介軟體?

  • 中介軟體在這裡是指注入到應用中處理請求和響應的元件

10、application builder的 use 和 run 方法有什麼區別?

  • 這兩個方法都在start up classconfigure方法裡面呼叫。都是用來嚮應用請求管道里面新增中介軟體的。Use方法可以呼叫下一個中介軟體的新增,而run不會。

11、dot net core 管道里面的map拓展有什麼作用?

  • 可以針對不同的路徑新增不同的中介軟體。

12、dot net core裡面的路徑是如何處理的?

  • 路徑處理是用來為進入的請求尋找處理函式的機制。所有的路徑在函式執行開始時進行註冊。
  • 主要有兩種路徑處理方式, 常規路徑處理和屬性路徑處理。常規路徑處理就是用MapRoute的方式設定呼叫路徑,屬性路徑處理是指在呼叫函式的上方設定一個路徑屬性。

13、如何在dot net core中啟用session功能?

  • 首先要新增session包. 其次要在config service方法裡面新增session。然後又在configure方法裡面呼叫usesession。

14、dot net core工程裡面有多少個工程檔案?

  • global,launch setting,app settings,bundle config,bower,package。

15、什麼是dot net core裡面的tag helper?

  • Tag helper用來在伺服器端使用Razor檢視引擎建立html元素的。

16、如何使tag helper在元素這一層上失效?

  • 使用歎號。

17、什麼是Razor頁面?

  • 是dot net core中支援ASP網頁表格的一種開發模型。@page 作為頁面的起始標誌。

18、如何在Razor頁面中實現資料模型繫結?

  • 使用bindproperty屬性。

19、 如何在controller中注入service?

  • config services方法中配置這個service
  • controller的建構函式中,新增這個依賴注入。

20、描述一下依賴注入後的服務生命週期?

  • 在.net core中,我們不需要關心如何釋放這些服務,因為系統會幫我們釋放掉。有三種服務的生命週期

  • 單例項服務, 通過add singleton方法來新增。在註冊時即建立服務,在隨後的請求中都使用這一個服務。

  • 短暫服務,通過add transient方法來新增。是一種輕量級的服務,用於無狀態服務的操作。

  • 作用域服務,一個新的請求會建立一個服務例項。使用add scoped方法來新增。