首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 經典面試題精選解析:從基礎概念到進階實戰

     編輯:關於C語言

前言

本文精選 10 道經典 C# 面試題,涵蓋字符串內存模型、值類型與引用類型、委托事件、編碼與字符串長度、SQL 查詢、線程安全與鎖、數據庫連接池與異常處理、Remoting 與 WebService 對比、ListView 排序擴展、XML 遞歸遍歷等核心知識點。每題附帶標準答案與深度解析,助力面試準備與知識查漏補缺。


第 1 題:string str = null vs string str = "" 區別

問題

說明兩者在內存分配上的詳細區別。

標準答案

  • string str = null:不分配內存空間,變量為空引用,不指向任何對象實例。
  • string str = "":分配一個長度為 0 的字符串對象在托管堆上,變量指向這個有效的空字符串實例。

深度解析

null 表示「無引用」,調用任何實例成員會拋出 NullReferenceException。"" (或 String.Empty) 是一個合法的字符串對象,Length == 0,可安全調用實例方法如 ToString()、Equals()。String.IsNullOrEmpty() 可同時檢查兩種情況。字符串為引用類型且不可變,"" 可能被字符串驻留池優化為單例。


第 2 題:類 (class) 與結構 (struct) 異同

標準答案

特性Class (引用類型)Struct (值類型)
內存分配托管堆棧 (或內嵌於包含類型中)
繼承支持繼承 (單繼承),可為基類不可繼承 (隱式 sealed),不可為基類
默認構造函數編譯器生成無參構造函數無無參構造函數,成員自動初始化為 0/null
賦值語義引用拷貝 (指向同一對象)值拷貝 (創建獨立副本)
可為 null是需用 Nullable<T> 或 T?
適用場景複雜行為、身份標識、大型對象輕量級數據結構、邏輯值語義、高頻創建銷毀

核心觀點

Class 分配在堆上,通過引用訪問;Struct 分配在棧上,按值傳遞。這是面試必考的核心區別。


第 3 題:委托與事件實戰填空

問題

在用戶控件工具欄按鈕點擊事件中,正確觸發 OnNew 事件。

標準答案

if (OnNew != null)
{
    OnNew(this, e); // 注意:原題代碼中委托簽名為 void OnDBOperate() 無參數,但事件觸發通常傳送 sender 和 EventArgs
    // 若委托定確為 void OnDBOperate(),則調用 OnNew();
}

關鍵點

  1. 空檢查:必須判斷 OnNew != null,否則無訂閱者時拋出異常
  2. 線程安全:多線程環境下建議複製委托副本再調用:var handler = OnNew; handler?.Invoke(this, e);
  3. 委托簽名匹配:調用參數必須與委托聲明一致

第 4 題:編碼與字符串長度計算

代碼

string strTmp = "abcdefg某某某";
int i = Encoding.Default.GetBytes(strTmp).Length; // 字節長度
int j = strTmp.Length; // 字符長度

答案

i = 13, j = 10

解析

  • strTmp 含 7 個 ASCII 字符 (各 1 字節) + 3 個中文字符 (GB2312/默認編碼下各 2 字節) = 7 + 6 = 13 字節
  • Length 返回 Char 數量 (UTF-16 代碼單元),此處為 10 個字符
  • 注意:Encoding.Default 因系統區域設置不同而異 (中文系統通常為 GB2312/GBK),跨平台建議顯式指定 Encoding.UTF8 (中文 3 字節) 或 Encoding.Unicode (固定 2 字節)

第 5 題:SQL 獲取最後更新事務號

問題

表 table1 有 ID、LastUpdateDate,用一條 SQL 獲取最後更新的事務號。

標準答案

SELECT ID 
FROM table1 
WHERE LastUpdateDate = (SELECT MAX(LastUpdateDate) FROM table1);

進階考慮

  • 若 LastUpdateDate 有並發相同值,可能返回多行。可用 TOP 1 ORDER BY LastUpdateDate DESC 或 ROW_NUMBER() 窗口函數確保單行
  • 若 ID 為自增主鍵,通常 SELECT TOP 1 ID FROM table1 ORDER BY LastUpdateDate DESC, ID DESC 更高效

第 6 題:線程安全與鎖死鎖分析

代碼

public void test(int i) {
    lock(this) {
        if (i > 10) {
            i--;
            test(i); // 遞歸調用
        }
    }
}

答案

不會發生死鎖。

解析

  1. int 是值類型,按值傳遞。每次遞歸傳入的是副本,修改不影響外層變量
  2. 同一線程可重入同一把鎖 (lock(this) 基於 Monitor 可重入),遞歸調用同一方法同一實例會直接獲得鎖,不阻塞
  3. 若參數改為 ref int i 或引用類型 object,則共享同一變量/對象,但因鎖可重入仍不會死鎖,只會正常遞歸執行
  4. 真正死鎖場景:多線程競爭多把鎖且獲取順序不一致

第 7 題:數據庫連接池與異常處理

代碼片段

OleDbConnection conn = new OleDbConnection(connStr);
try { conn.Open(); ... }
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
finally { if (conn.State != ConnectionState.Closed) conn.Close(); }

問題 1:能否正確使用連接池?

能。關鍵條件:連接字符串完全一致 (含空格、屬性順序)。finally 中 Close() 將連接返回池中,而非真正關閉底層連接。

問題 2:異常處理是否能捕獲所有異常?

不能保證。catch 僅捕獲 try 塊內異常。finally 中的 conn.Close() 或 MessageBox.Show 若拋出異常將無法被捕獲,導致原始異常丟失或程序崩潰。最佳實踐:finally 內部再包裹 try-catch,或使用 using 語句自動釋放。


第 8 題:.NET Remoting vs WebService

核心對比

維度WebService (ASMX/WCF).NET Remoting
傳輸協議HTTP/HTTPS (穿透防火牆強)TCP/IP (默認), HTTP 等可擴展
序列化XmlSerializer / DataContractSerializer (SOAP/JSON)BinaryFormatter / SoapFormatter (二進制高效)
性能文本序列化開銷大,較低二進制序列化,高性能
互操作性跨平台、跨語言 (標準 SOAP/REST)僅限 .NET 平台
部署IIS 託管,易部署需自行宿主 (Windows Service, Console, IIS)
適用場景跨組織、異構系統集成、Web API.NET 內部高性能分布式組件通信

現代觀點:Remoting 屬於舊技術,新項目推薦 WCF / gRPC / Web API (ASP.NET Core)。


第 9 題:ListView 點擊列頭排序實現思路

標準思路

  1. 繼承 ListView,處理 ColumnClick 事件
  2. 獲取點擊列的索引 (ColumnHeader.Index)
  3. 根據該列數據類型 (文本、數字、日期) 定義比較器 (IComparer<ListViewItem>)
  4. 調用 ListView.ListViewItemSorter = comparer,然後 Sort()
  5. 切換升序/降序狀態,更新列頭排序圖標 (可選)

關鍵代碼片段

private void listView_ColumnClick(object sender, ColumnClickEventArgs e) {
    var comparer = new ListViewItemComparer(e.Column, sortOrder);
    listView.ListViewItemSorter = comparer;
    listView.Sort();
    // 切換 sortOrder (Ascending/Descending)
}

第 10 題:XML 文件遞歸遍歷所有 FileName

XML 結構

<FileSystem>
  <DriverC>
    <Dir DirName="MSDOS622">
      <File FileName="Command.com" />
    </Dir>
    <File FileName="MSDOS.SYS" />
    <File FileName="IO.SYS" />
  </DriverC>
</FileSystem>

遞歸算法流程 (偽代碼)

void FindFile(XmlNode node) {
    // 1. 處理當前節點
    if (node.Name == "File") {
        string fileName = node.Attributes["FileName"].Value;
        Console.WriteLine(fileName); // 或收集到列表
    }
    
    // 2. 遞歸處理子節點
    foreach (XmlNode child in node.ChildNodes) {
        FindFile(child);
    }
}

// 調用入口
XmlDocument doc = new XmlDocument();
doc.Load("filesystem.xml");
FindFile(doc.DocumentElement);

關鍵點

  • 使用 XmlDocument (DOM) 或 XmlReader (流式) 解析
  • DOM 適合小文件需多次遍歷;XmlReader 適合大文件單次只讀
  • 遞歸深度注意棧溢出風險,極深層級可改用顯式棧迭代

總結與面試建議

這 10 道題覆蓋了 C# 基礎類型系統、內存模型、委托事件、字符編碼、SQL 基礎、多線程同步、ADO.NET 最佳實踐、分布式技術選型、WinForms 控件擴展、XML 處理等核心領域。面試時除給出正確答案外,能結合 原理、最佳實踐、常見坑、現代替代方案 進行延伸闡述,將顯著提升評價。建議針對薄弱項深入閱讀官方文檔與 CLR Via C# 等經典著作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved