C# 常見面試問題彙總

一、c#垃圾回收機制html

    從如下方面入手展開:  一、壓縮合並算法   二、代的機制  三、GC調用終結器 Garbage Collectorc++

   . NET採用了和Java相似的方法由CLR(Common Language Runtime)來管理 程序員

     .NET的GC機制有這樣兩個問題:web

  首先,GC並非能釋放全部的資源。它不能自動釋放非託管資源。面試

  第二,GC並非實時性的,這將會形成系統性能上的瓶頸和不肯定性。redis

  GC並非實時性的,這會形成系統性能上的瓶頸和不肯定性。因此有了IDisposable接口,IDisposable接口定義了Dispose方法,這個方法用來供程序員顯式調用以釋放非託管資源。使用using語句能夠簡化資源管理。算法

       具體詳見:http://www.javashuo.com/article/p-gazsdfaq-ck.htmlsql

二、委託和事件數據庫

     先說它的定義:委託的本質是類,類型安全的指針,而後從用途上考慮,事件是包裝的委託,但事件不是委託。事件是由一個私有委託和add、remove 方法組成。編程

     事件、索引器、屬性本質都是方法。接口只能夠定義方法。因此接口也能夠定義「事件、索引器、屬性」,由於他們的本質也是add、remove 方法。

     委託是一種能夠指向方法的數據類型,能夠聲明委託類型變量。

     聲明委託的方式:delegate返回值類型   委託類型名(參數)

     好比delegate void MyDel(int n) 。C#中默認寫了2中委託Action<>,Func<>,Action基本上都是void沒有返回值,Func是有返回值的

    

 1 using System.Collections.Generic;
 2 using System.Linq;
 3 using System.Text;
 4 using System.Threading.Tasks;
 5 
 6 namespace TestConsole
 7 {
 8     delegate void MyDel();
 9     class Program
10     {
11 
12         static void Main(string[] args)
13         {
14             person p = new person();
15             p.QingZhu += ShowMsg;
16             p.age = 24;
17             Console.ReadKey();
18         }
19         static void ShowMsg()
20         {
21             Console.WriteLine("今年是你的本命年!恭喜你");
22         }
23     }
24     class person
25     {
26         private int Age;
27         public int age
28         {
29             get
30             {
31                 return age;
32             }
33             set
34             {
35                 if (value % 12 == 0)
36                 {
37                     if (QingZhu != null)
38                     {
39                         QingZhu();//執行事件
40                     }
41                 }
42             }
43         }
44         public event MyDel  QingZhu;
45     }
46 }
View Code

 

 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace TestConsole
 9 {
10     delegate void MyDel();
11     class Program
12     {
13 
14         static void Main(string[] args)
15         {
16             person p = new person();
17             p.qingzhu += ShowMsg;
18             p.age = 24;
19             Console.ReadKey();
20         }
21         static void ShowMsg()
22         {
23             Console.WriteLine("今年是你的本命年!恭喜你");
24         }
25     }
26     class person
27     {
28         private int Age;
29         public int age
30         {
31             get
32             {
33                 return age;
34             }
35             set
36             {
37                 if (value % 12 == 0)
38                 {
39                     if (this.QingZhu != null)
40                     {
41                         this.QingZhu();//執行事件
42                     }
43                 }
44             }
45         }
46         private  MyDel  QingZhu;
47         public event MyDel qingzhu
48         {
49             add
50             {
51                 this.QingZhu += value;
52             }
53             remove
54             {
55                 this.QingZhu -= value;
56             }
57         }
58 
59     }
60 }
View Code

三、c#索引

    索引能夠是字符串類型的,能夠容許有多個索引參數,下面的方法我就能夠定義多個參數。常見的Dictory<string,string>也是索引的一種。在IL中本質實際上是Get_Item 方法(無參數)、Set_Item 方法(參數:value)。

 1 class MyIntIndex
 2     {
 3         private static string[] name = { "dandan", "chizi", "jianguo" };
 4         public string this[int index]
 5         {
 6             get
 7             {
 8                 string n = name[index];
 9                 return n;
10             }
11             set
12             {
13                 name[index] = value;
14             }
15         }
16     }
17 }
View Code

四、裝箱和拆箱

    值類型和引用類型之間的轉換。頻繁裝箱和拆箱會致使系統性能下降,可考慮用泛型。值類型賦值給object爲裝箱操做,值類型賦值給object拆箱(顯示轉換)。裝什麼類型拆箱就是什麼類型,除非C#中convert.toInt32 等內置的這些方法能夠強制拆箱。

五、泛型

   考得很少,但咱們日常用的比較多。因此對泛型的一些東西須要瞭解,如泛型約束等。 

   泛型約束 public void GetEntity<T>() where T:class

    where T :struct //約束T必須爲值類型
    where K : class //約束K必須爲引用類型
    where V : IComparable //約束V必須是實現了IComparable接口
    where W : K //要求W必須是K類型,或者K類型的子類
    where X :class ,new () // 或者寫出 new class() ;   X必須是引用類型,而且要有一個無參的構造函數(對於一個類型有多有約束,中間用逗號隔開)

六、c#如何調用c++ 的dll?爲何能夠調用

     右擊添加類中的「TypeLib中的MFC類」選項實現跨平臺調用。添加好後會生成h文件和cpp文件

   tjdmwj2tjdmwj3tjdmwj4

   填寫完後Function.h文件會報錯,錯誤類型以下。這裏須要在C++項目裏面設置,讓動態庫受到公共語言運行時的支持。以下圖所示:打開項目屬性

   tjdmwj4tjdmwj5tjdmwj6

     C#和C++在vs中的語法類型都會編譯成CTS(Common Type System通用數據類型)生成.net 中有CLS(Common Language Specification公共語言允規範) 並在IL代碼中的CLR(Common Language Runtime 公共語言運行池)中運行。

     Int和Int32,string與String的區別,一個是C#代碼中的類型,一個是IL中的CTS通用數據類型

七、託管資源和非託管資源

    問題:一、定義  二、如何釋放

   託管資源是指由CLR管理分配和釋放的資源。託管資源有GC釋放,非託管資源由程序員本身釋放,能夠實現dispose接口。

   關於託管資源,就不用說了撒,像簡單的int,string,float,DateTime等等,.net中超過80%的資源都是託管資源。

   非託管資源如何釋放,.NET Framework 提供 Object.Finalize 方法,它容許對象在垃圾回收器回收該對象使用的內存時適當清理其非託管資源。

   值類型在棧內存中,方法結束自動釋放,引用類型在堆內存中須要GC來回收

   

~MyClass()
{
  // Perform some cleanup operations here.
}
  該代碼隱式翻譯爲下面的代碼。
protected override void Finalize()
{
  try
  {
    // Perform some cleanup operations here.
  }
  finally
  {
    base.Finalize();
  }
}

 

在一個包含非託管資源的類中,關於資源釋放的標準作法是:

(1) 繼承IDisposable接口;

(2) 實現Dispose()方法,在其中釋放託管資源和非託管資源,並將對象自己從垃圾回收器中移除(垃圾回收器不在回收此資源);

(3) 實現類析構函數,在其中釋放非託管資源。

 

 1 PublicclassBaseResource:IDisposable
 2 {
 3   PrivateIntPtr handle; // 句柄,屬於非託管資源
 4   PrivateComponet comp; // 組件,託管資源
 5   Privateboo isDisposed = false;// 是否已釋放資源的標誌
 6    PublicBaseResource()
 7    {
 8    }
 9    //實現接口方法
10    //由類的使用者,在外部顯示調用,釋放類資源
11    Publicvoid Dispose()
12    {
13      Dispose(true);// 釋放託管和非託管資源
14      //將對象從垃圾回收器鏈表中移除,
15     // 從而在垃圾回收器工做時,只釋放託管資源,而不執行此對象的析構函 
16 17     GC.SuppressFinalize(this);
18     }
19     //由垃圾回收器調用,釋放非託管資源
20     ~BaseResource()
21      {
22       Dispose(false);// 釋放非託管資源
23      }
24     //參數爲true表示釋放全部資源,只能由使用者調用
25     //參數爲false表示釋放非託管資源,只能由垃圾回收器自動調用
26    //若是子類有本身的非託管資源,能夠重載這個函數,添加本身的非託管 
27     資源的釋放
28    //可是要記住,重載此函數必須保證調用基類的版本,以保證基類的資源 
29     正常釋放
30     Protected virtual void Dispose(booldisposing)
31    {
32      If(!this.disposed)// 若是資源未釋放 這個判斷主要用了防止對象被多 
33 34       釋放
35     {
36      If(disposing)
37      {
38       Comp.Dispose();// 釋放託管資源
39      }
40        closeHandle(handle);// 釋放非託管資源
41        handle= IntPtr.Zero;
42       }
43       this.disposed=true;// 標識此對象已釋放
44     }
45 }
View Code

 

八、MVC原理

   路由機制,我以爲此題,根據本身的理解回答便可,可深刻回答  從view上請求到controller組織model,反映到view上.詳細框架原理,能夠查看:https://blog.csdn.net/jehuyang/article/details/100575686

九、MVC中,後臺向前臺頁面傳對象的方式

   強類型的模型綁定、ViewData、ViewBag 。其中ViewData是ViewDataDictory類型,而VieBag是dynamic類型. dynamic 能夠動態給不一樣的類型。例如:dynamic p1=new Expandobject(); p1.Age=10; p1.Age="222";這樣也不會報錯。

十、MVC中過濾器

   Filter過濾器.AOP 面向切面編程。

   IAuthorizationFilter 通常檢查用戶是否有Action執行權限。在每一個Action以前執行OnAuthorization方法。

   IActionFilter在每一個Action以前執行OnActionExcuting方法,在每一個Action執行完成後執行OnActionExecuted 方法. IAuthorizationFilter在IActionFilter執行以前執行,因此檢查權限通常寫在IAuthorizationFilter中的OnAuthorization方法中。

   IResultFilter在每一個ActionResult的先後執行,通常不多用

   IExceptionFilter當每一個Action有未處理的異常執行OnException 方法。MVC中可使用Application_Error,但建議使用IExceptionFilter方法。

   定義的類能夠在Global中Global.Filters.Filter.Add(new XXXFilter())添加使用。

十一、c#擴展方法如何寫?

    靜態類+靜態方法+this,例以下面代碼:

class Program
    {
        static void Main(string[] args)
        {
            string str = "Hello World!";
            str.ShowMsg(str);
            Console.ReadKey();
        }
  }
    #region 擴展方法
    static class MyString
    {
        public static void ShowMsg(this string a, string msg)
        {
            Console.WriteLine(msg);
        }
    }
    #endregion 擴展方法

十二、.NET Core Api 安全驗證以及中間件 (本人沒有了解過,代深刻了解

     採用jwt,生成token驗證,好比咱們用來錯誤處理的中間件,能夠定義其它功能的中間件。瞭解詳細頁面:https://www.cnblogs.com/savorboard/p/aspnetcore-authentication.html

1三、設計模式(本人沒有了解過,代深刻了解)

     經常使用的設計模式:工廠、抽象工廠、代理、適配器、模板、策略、單例、觀察者等,根據本身在項目中的使用狀況,能夠談一談。介紹連接:http://www.javashuo.com/article/p-pidygqoa-cp.html

1四、單點登陸

      單點登陸(Single Sign On),簡稱爲 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,用戶只須要登陸一次就能夠訪問全部相互信任的應用系統。使用「單點登陸」整合後,只須要登陸一次就能夠進入多個系統,而不須要重        新登陸,這不只僅帶來了更好的用戶體驗,更重要的是下降了安全的風險和管理的消耗。介紹連接:http://www.javashuo.com/article/p-brhboyeu-bo.html

1五、彙集索引和非彙集索引

      彙集索引:也叫聚簇(cu)索引。數據行的物理順序與列值(通常是主鍵的那一列)的邏輯順序相同,一個表中只能擁有一個彙集索引。

      非彙集索引:該索引中索引的邏輯順序與磁盤上行的物理存儲順序不一樣,一個表中能夠擁有多個非彙集索引。

1六、char,varchar、nvarchar區別   

char 

char是定長的,這個怎麼說呢,好比你用char(10),當你輸入6個字符時,它會用英文的空格給補全。當你輸入的15個字符時,它會自動截取前10個字符。取值範圍1-8000

優勢:適合存儲定長的數據,存儲效率快

缺點:使用不當會形成存儲空間的浪費
varchar

varchar可變長度的,存儲的大小爲輸入數據的字節的實際長度,所輸入的數據字符長度能夠爲0。取值範圍0-8000

優勢:適合存儲不固定長度的數據,它能夠識別出字節用於保存實際使用多大的長度。合理的利用的存儲空間。

缺點:存儲效率低

nvarchar

咱們都知道英文字母佔一個字節,漢字佔兩個字節,若是咱們的數據中又有英文,又有漢字,這時nvarchar就該上場了,nvarchar不管是英文仍是漢字都是用兩個字節來表示。

優勢:適合存儲既有英文和漢字的數據

缺點:它最多能存儲4000個字符,對英文存儲上有些損失

1七、數據庫死鎖產生的緣由及解決辦法(本人沒有了解過,代深刻了解)

      兩個進程各自佔有資源,而後它們都還想獲得對方的資源,而本身不願釋放資源。我以爲死鎖的活該,誰叫你那麼貪婪。

1八、有用過緩存嗎?有用過redis嗎?

     你若回答用過,面試官繼續追問;你若回答沒用過,他會以爲這都沒有用過。

     緩存爲了提升應用程序性能,由於請求數據庫的次數少了。redis有不少特色:一、key-value   二、內存數據庫,能夠持久化到硬盤上  三、能夠用做消息隊列

1九、IOC、依賴注入、容器

      IOC是一種思想,控制反轉,反轉的是對象的控制權,把生成對象的權利交到外部。好比在方法中要使用一個Student對象,有三種方法,一、用的時候,直接New一個對象  二、從方法參數中傳入Student對象   三、從容器中獲取一個Student對象

20、大文件上傳與下載,如何考慮?好比說50G的大文件

      能夠分段下載,webconfig中必須配置大小。具體沒有研究過待研究       

2一、Linq

2二、AOP

    面向切面的編程。好比給每一個Controller,添加日誌功能,AOP是橫向思惟的一種體現。和問題10有重複

2三、SOA、Webservice、WCF  (具體沒有研究過待研究 )      

    問題:Webservice與WCF區別

    WCF是一個統一的框架,包括了remotting、Webservice,msmq,能夠採用tcp和http等協議。也能夠進行安全設置和驗證。缺點:配置複雜

2四、有研究過Docker嗎

    Docker是一個平臺,解決部署問題。須要理解Image(鏡像)和Container的關係,瞭解運行機理

2五、有研究過微服務嗎

2六、sql性能優化

      查看sql執行計劃、拆庫、拆表、優化語句等

2七、你瞭解串口編程嗎

     就是控制攝像頭之類的設備編程,得了解計算機的基本原理

2八、js字符串和數組相互轉化

2九、請設計一個遞歸算法

      好比5的階乘,遞歸算法的一個要點是要設置結束條件,不然會棧溢出。

30、如何考慮作一個網站

3一、線性表和鏈表的區別

3二、談談你對js閉包的理解

3三、多線程中的同步、異步、Task

     異步主要爲了提高吞吐量,防止阻塞。Task主要提供了一個管理線程的接口,好比獲取線程的結果、狀態、取消線程的執行等

3四、用過NoSql嗎

    redis  、Memcached、MongoDB等

    redis 的優勢: 

       1)  支持 string、list、set、geo 等複雜的數據結構。

       2)  高命中的數據運行時是在內存中,數據最終仍是能夠保存到磁盤中,這樣服務器重啓以後數據還在。

       3)  服務器是單線程的,來自全部客戶端的全部命令都是串行執行的,所以不用擔憂併發修改(串行操做固然仍是有併發問題)的問題,編程模型簡單;

       4)  支持消息訂閱/通知機制,能夠用做消息隊列;

       5)  Key、Value 最大長度容許 512M; 

     redis 的缺點: 

1)  Redis 是單線程的,所以單個 Redis 實例只能使用一個 CPU 核,不能充分發揮服務器的性能。能夠在一臺服務器上運行多個 Redis 實例,不一樣實例監聽不一樣端口,再互相組成集羣。

2)  作緩存性能不如 Memcached; 

    Memcached 的優勢:
              1) 多線程,能夠充分利用 CPU 多核的性能; 2) 作緩存性能最高;

    Memcached 的缺點: 

       1)  只能保存鍵值對數據,鍵值對只能是字符串,若是有對象數據只能本身序列化成 json 字符串;

       2)  數據保存在內存中,重啓後會丟失;

       3)  Key 最大長度 255 個字符,Value 最長 1M。 

redis 命令行管理客戶端:
1)直接啓動 redis 安裝目錄下的 redis-cli 便可。不用管噁心的自動提示。 執行 set name yzk,就是設置鍵值對 name=yzk

執行 get name 就是查找名字是 name 的值;

keys *是查找全部的 key

key *n*是查找全部名字中含有 n 的 key

2) 和 Redis 同樣,Redis 也是不一樣系統放到 Redis 中的數據都是不隔離的,所以設定 Key 的 時候也要選擇好 Key。

3) Redis 服務器默認建了 16 個數據庫,Redis 的想法是讓你們把不一樣系統的數據放到不一樣 的數據庫中。可是建議你們不要這樣用,由於 Redis 是單線程的,不一樣業務都放到同一個 Redis 實例的話效率就不高,建議放到不一樣的實例中。所以儘可能只用默認的 db0 數據庫。

命令行下能夠用 select 0、select 1 這樣的指令切換數據庫,最高爲 15。試試在不一樣數據 庫下新建、查詢數據。

3五、用過負載均衡嗎

3六、大數據處理

3七、數據庫表數據量特別大時,如何優化查詢,提升速度?

3八、數據庫中如何循環讀取數據庫表中的記錄?

      遊標

3九、數據庫中刪除重複數據

40、Session有什麼缺點,微軟如何改進

   這是道筆試題,咱們知道IIS會回收資源,因此可能會致使Session失效

4一、有沒有用過消息隊列

     RabbitMQ

4二、設計一個老鼠、貓和主人的程序,要求可擴展性強,老鼠的叫聲驚動貓和主人

    真無趣的一道題,用事件

4三、Vue權限管理,如何控制界面的顯示

4四、WCF的部署方式

     通常在IIS上,還有人部署在Window服務上

4五、簡介應用程序池

4六、冒泡算法

      c#寫一個,雙層循環

4七、簡述應用程序域

4八、數據庫設計三範式

4九、SQL 事務的隔離級別有哪幾個?

     sql 事務隔離級別有四種分種爲:

     一 Read Uncommitted(未提交讀)

     二 Read Committed(提交讀)

     三 Repeated Read(可重複讀)

      四 Serializable(序列)

      資料連接:http://www.javashuo.com/article/p-tzedstaa-cs.html

50、IQueryable和IEnumberable and IList與List區別      

 基本概念:
IEnumerable:使用的是LINQ to Object方式,它會將AsEnumerable()時對應的全部記錄都先加載到內存,而後在此基礎上再執行後來的Query
IQeurable(IQuerable<T>):不在內存加載持久數據,由於這傢伙只是在組裝SQL,(延遲執行) 到你要使用的時候,例如 list.Tolist() or list.Count()的時候,數據才從數據庫進行加載 (AsQueryable())。
IList(IList<T>):泛型接口是 ICollection 泛型接口的子代,做爲全部泛型列表的基接口,在用途方面若是做爲數據集合的載體這是莫有問題的,只是若是須要對集合作各類的操做,例如 排序 編輯 統計等等,它不行。
List <> :泛型類,它已經實現了IList <> 定義的那些方法,IList<T> list=new List<T>();只是想建立一個基於接口IList<Class1>的對象的實例,這個接口是由List<T>實現的。只是但願使用到IList<T>接口規定的功能而已抽象場景:
其實在咱們以前沒有使用 ORM 的的好久好久之前,咱們 在ADO.net 裏面使用的 DataReader 和 DataAdapter or DataSet 和這幾個貨的基本原理都接近的,就是讀取數據的時候,一個必須獨佔着數據庫的鏈接,而另外一個就是先把數據庫的的局加載到了本身本地,而後再進行操做。
使用場景模擬:
//IList
IList users = res.ToList(); //此時已把users加載到內存,而每一個user的關聯實體 
                               //UserInfos)未被加載,因此下一行代碼沒法順利經過
var ss = users.Where(p => p.UserInfos.ID != 3); //此處報錯,由於P的UserInfos實體沒法被加載  
// IQuerable的
IQueryable users = res.AsQueryable(); //users未被當即加載,關聯實體可經過「延遲加載」得到
var ss = users.Where(p => p.UserInfos.ID != 3);//此處順利得到對應的ss

  總結: 

基於性能和數據一致性這兩點,使用IQueryable時必須謹慎,而在大多數狀況下咱們應使用IList。 

1.當你打算立刻使用查詢後的結果(好比循環做邏輯處理或者填充到一個table/grid中), 而且你不介意該查詢即時被執行後的結果能夠供調用者(Consummer)做後續查詢(好比這是一個"GetAll"的方法),或者你但願該查執行,使用ToList()

2.當你但願查詢後的結果能夠供調用者(Consummer)做後續查詢(好比這是一個"GetAll"的方法),或者你但願該查詢延時執行,使用AsQueryable()

3.按照功能由低到高:List<T> IList<T> IQueryable<T> IEnumerable<T>

4.按照性能由低到高:IEnumerable<T> IQueryable<T> IList<T> List<T>

       參考連接:http://www.javashuo.com/article/p-gccyyuzg-cv.html

相關文章
相關標籤/搜索