C#高級特性面試問題的詳細分析,涵蓋核心概念、應用場景和最佳實踐

序列化與反序列化

1. 什么是序列化和反序列化?用途是什么?

// 序列化示例
Person person = new Person { Name = "Alice", Age = 30 };
string json = JsonSerializer.Serialize(person); // 序列化為JSON// 反序列化示例
Person deserialized = JsonSerializer.Deserialize<Person>(json);
  • 核心概念
    • 序列化:將對象狀態轉換為可存儲/傳輸格式(如JSON、XML、二進制)
    • 反序列化:將數據流還原為對象
  • 關鍵用途
    • 網絡傳輸(API通信)
    • 數據持久化(保存到文件/數據庫)
    • 進程間通信
    • 緩存機制

2. JSON vs XML 序列化的優缺點

特性JSONXML
可讀性高(輕量級)中(標簽冗余)
數據體積小(無標簽)大(標簽占40%+空間)
解析性能快(比XML快2-10倍)慢(DOM解析復雜)
類型安全弱(無schema)強(XSD支持)
二進制支持Base64編碼原生支持(CDATA)
適用場景Web API、移動應用企業系統、SOAP服務

3. 循環引用處理

// Newtonsoft.Json解決方案
var settings = new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
string json = JsonConvert.SerializeObject(obj, settings);// System.Text.Json解決方案
options.ReferenceHandler = ReferenceHandler.Preserve;
  • 根本原因:對象相互引用形成閉環(如 Parent.ChildChild.Parent
  • 解決方案
    1. 忽略循環引用(ReferenceLoopHandling.Ignore
    2. 使用[JsonIgnore]標記屬性
    3. DTO模式(僅序列化必要數據)
    4. 自定義ID追蹤(PreserveReferencesHandling

4. 自定義序列化

// 實現ISerializable接口
[Serializable]
public class CustomObject : ISerializable
{public void GetObjectData(SerializationInfo info, StreamingContext context){info.AddValue("customField", _value);}protected CustomObject(SerializationInfo info, StreamingContext context){_value = info.GetString("customField");}
}// JSON自定義轉換器
public class DateTimeConverter : JsonConverter<DateTime>
{public override DateTime Read(ref Utf8JsonReader reader, ...) => DateTime.Parse(reader.GetString());public override void Write(Utf8JsonWriter writer, DateTime value, ...)=> writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
}

5. 版本控制策略

  • 向前兼容
    • 使用[OptionalField]特性
    • 反序列化回調(OnDeserializing
  • 向后兼容
    • 避免刪除已序列化字段
    • 新字段添加默認值
  • 最佳實踐:
    • 語義版本控制(SemVer)
    • 自定義版本字段
    • 使用協議緩沖區(protobuf)等版本容忍格式

泛型

1. 泛型核心優勢

// 類型安全集合
List<string> strings = new List<string>();
strings.Add("text");  // 編譯時類型檢查
// strings.Add(42);   // 編譯錯誤// 避免裝箱
List<int> numbers = new List<int>(); // 無裝箱開銷
  • 三大優勢
    1. 編譯時類型檢查
    2. 消除裝箱/拆箱(值類型性能提升20-50%)
    3. 代碼復用(同一算法處理不同類型)

2. 泛型約束類型

public class Processor<T> where T : IComparable,      // 接口約束new(),            // 構造函數約束struct            // 值類型約束
{public void Sort(T[] data) { /*...*/ }
}
約束類型語法應用場景
接口約束where T : IDisposable確保類型實現特定行為
基類約束where T : Stream限制繼承層次
構造函數約束where T : new()創建實例(new T()
值類型/引用類型約束where T : struct優化值類型操作
非托管約束where T : unmanaged不安全代碼/指針操作

3. 協變(in)與逆變(out)

// 協變:子類→父類 (out)
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;  // 安全// 逆變:父類→子類 (in)
Action<object> logObject = obj => Console.Write(obj);
Action<string> logString = logObject;  // 安全
logString("text");  // 實際執行logObject
  • 核心規則
    • 協變(out):返回值類型,支持更具體的子類型
    • 逆變(in):參數類型,支持更通用的父類型
    • 只適用于接口和委托

4. 泛型與反射交互

// 創建泛型類型實例
Type openType = typeof(Dictionary<,>);
Type closedType = openType.MakeGenericType(typeof(int), typeof(string));
object dict = Activator.CreateInstance(closedType);// 調用泛型方法
MethodInfo method = typeof(Serializer).GetMethod("Serialize");
MethodInfo closedMethod = method.MakeGenericMethod(typeof(Person));
closedMethod.Invoke(null, new object[] { person });

5. 泛型接口設計模式

public interface IRepository<TEntity, TKey> where TEntity : IEntity<TKey>
{TEntity GetById(TKey id);void Add(TEntity entity);
}public class UserRepository : IRepository<User, int> 
{public User GetById(int id) { /* DB查詢 */ }public void Add(User entity) { /* DB插入 */ }
}

集合

1. List vs Array

// Array - 固定大小
int[] array = new int[10]; 
array[0] = 1; // 賦值
// array[10] = 1; // 運行時越界錯誤// List<T> - 動態擴展
List<int> list = new List<int>(capacity: 100);
list.Add(1); // 自動擴容
list.RemoveAt(0); // 動態收縮
特性ArrayList
大小固定動態擴展
內存分配連續塊動態數組+緩沖池
插入/刪除性能O(n)O(n)(尾部O(1))
隨機訪問O(1)O(1)
線程安全

2. Dictionary工作原理

var dict = new Dictionary<string, int>();
dict.Add("key1", 42); // 內部實現偽代碼:
// 1. 計算哈希:key.GetHashCode() -> bucketIndex
// 2. 處理沖突:鏈地址法(鏈表存儲沖突項)
// 3. 存儲鍵值對:entries[bucketIndex] = new Entry(key, value)
  • 哈希沖突解決方案
    • 開放尋址法(.NET Core+)
    • 鏈地址法(.NET Framework)
  • 時間復雜度
    • 查找/插入/刪除:平均O(1),最壞O(n)
  • 最佳實踐
    • 實現GetHashCode()Equals()的規范重寫
    • 設置合理初始容量減少擴容

3. 集合接口層次

IEnumerable
ICollection
IList
ISet
IQueryable
  • 核心接口
    • IEnumerable<T>:基本迭代(GetEnumerator
    • ICollection<T>:添加/刪除(Count, Add, Remove
    • IList<T>:索引訪問(this[index], Insert
    • ISet<T>:集合操作(UnionWith, IntersectWith

4. 自定義集合實現

public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged
{protected override void InsertItem(int index, T item){base.InsertItem(index, item);OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);}protected virtual void OnCollectionChanged(...) => CollectionChanged?.Invoke(this, args);
}
  • 繼承Collection<T>基類
  • 重寫關鍵方法:InsertItem, SetItem, RemoveItem
  • 實現通知機制(如INotifyCollectionChanged

5. 線程安全集合

// 并發字典
var concurrentDict = new ConcurrentDictionary<string, int>();
concurrentDict.TryAdd("key", 42);// 生產者-消費者隊列
BlockingCollection<int> queue = new BlockingCollection<int>();
// 生產者
queue.Add(1);  
// 消費者
int item = queue.Take(); 
集合類型適用場景
ConcurrentDictionary高頻讀/寫的鍵值存儲
ConcurrentQueue任務隊列(生產者-消費者)
ConcurrentBag無序對象池
BlockingCollection有界/無界阻塞隊列

Lambda表達式

1. Lambda vs 匿名方法

// 匿名方法(C# 2.0)
Func<int, int> square = delegate(int x) { return x * x; };// Lambda表達式(C# 3.0+)
Func<int, int> square = x => x * x;
特性匿名方法Lambda表達式
語法簡潔性冗長簡潔
參數類型推斷需顯式聲明可推斷
表達式樹支持不支持支持
閉包支持支持支持
單行返回值需return語句自動返回

2. 閉包與變量捕獲

int factor = 2;
Func<int, int> multiplier = x => x * factor;
Console.WriteLine(multiplier(5)); // 10// 修改捕獲變量
factor = 3;
Console.WriteLine(multiplier(5)); // 15
  • 閉包原理
    • 編譯器生成隱藏類(closure類)
    • 捕獲變量轉為類的字段
    • Lambda成為實例方法
  • 陷阱
    • 循環變量捕獲問題(所有迭代共享同一變量)
    • 解決方案:循環內聲明臨時變量

3. 表達式樹(Expression Trees)

Expression<Func<int, bool>> expr = x => x > 5 && x < 10;// 解析表達式樹
BinaryExpression body = (BinaryExpression)expr.Body;
ParameterExpression param = (ParameterExpression)expr.Parameters[0];
  • 核心特性
    • 將代碼轉為可遍歷的數據結構
    • LINQ to SQL等ORM的核心技術
  • 應用場景
    • 動態SQL生成
    • 運行時條件組合
    • 自定義查詢翻譯

4. 變量作用域規則

int outer = 10;
Action action = () => 
{int inner = 20;Console.WriteLine(outer + inner); // 訪問外部變量
};
// Console.WriteLine(inner); // 錯誤:inner不可訪問
  • 作用域層次
    1. Lambda參數
    2. Lambda內部聲明
    3. 外部方法變量
    4. 類成員變量
  • 生命周期
    • 捕獲變量的生命周期延至所有委托被GC回收

5. Lambda性能優化

// 避免:高頻調用中重復編譯表達式樹
Expression<Func<Person, bool>> expr = p => p.Age > 18;
Func<Person, bool> compiled = expr.Compile(); // 緩存此委托// 優先使用靜態Lambda(C# 9.0+)
Func<int, int> square = static x => x * x; // 不捕獲上下文
  • 優化策略:
    • 緩存編譯后的委托
    • 避免在高頻循環中捕獲變量
    • 使用靜態Lambda減少內存分配
    • 避免深層嵌套的Lambda

LINQ

1. 延遲執行 vs 立即執行

// 延遲執行(未真正執行)
IEnumerable<int> query = data.Where(x => x > 5);// 觸發執行的操作:
var list = query.ToList();      // 立即執行
int count = query.Count();      // 立即執行
var first = query.First();      // 立即執行// 流式執行(yield return)
foreach (var item in query)     // 遍歷時逐步執行
{// 每次迭代處理一個元素
}

2. Select vs SelectMany

// Select:一對一轉換
var names = persons.Select(p => p.Name);// SelectMany:集合展開
var allPhones = persons.SelectMany(p => p.Phones);// 模擬SQL JOIN
var orders = customers.SelectMany(c => c.Orders,(customer, order) => new { customer.Name, order.Id }
);

3. LINQ性能優化

// 數據庫查詢優化
var results = context.Users.Where(u => u.Age > 18)    // 在數據庫執行.AsNoTracking()             // 禁用變更追蹤.Select(u => new { u.Name }) // 僅選擇必要字段.ToList();// 內存集合優化
var local = data.Where(x => x.IsActive).OrderBy(x => x.Name)     // 先過濾再排序.Take(20)                 // 盡早限制數量.ToList();
  • 關鍵優化點
    • 數據庫:使用投影減少數據傳輸
    • EF Core:AsNoTracking()用于只讀查詢
    • 內存:避免N+1查詢模式
    • 使用Any()替代Count() > 0

4. IQueryable vs IEnumerable

// IEnumerable - 客戶端執行
var result = context.Users.AsEnumerable()            // 切換為客戶端評估.Where(u => ComplexLogic(u)); // 在內存中執行// IQueryable - 數據庫執行
var result = context.Users.Where(u => u.Age > 18)    // 轉換為SQL.ToList();                 // 在數據庫執行
特性IEnumerableIQueryable
執行位置客戶端內存數據源(如數據庫)
查詢能力LINQ to Objects支持提供程序翻譯(如SQL)
延遲執行支持支持
性能特點適合內存數據集減少數據傳輸量

5. 自定義LINQ提供程序

public class CustomQueryable<T> : IQueryable<T>
{public Type ElementType => typeof(T);public Expression Expression { get; }public IQueryProvider Provider { get; }// 實現GetEnumerator和必要接口
}public class CustomProvider : IQueryProvider
{public IQueryable CreateQuery(Expression expression) { ... }public object Execute(Expression expression){// 解析表達式樹var translator = new CustomTranslator();translator.Visit(expression);// 執行自定義查詢邏輯return ExecuteDatabaseQuery(translator.GetQuery());}
}
  • 實現步驟
    1. 實現IQueryableIQueryProvider
    2. 解析表達式樹(ExpressionVisitor
    3. 轉換為目標查詢語言(如SQL)
    4. 執行查詢并映射結果
  • 難點
    • 表達式樹的完整解析
    • 參數化查詢處理
    • 嵌套查詢支持

綜合問題深度分析

1. 泛型+集合+LINQ綜合應用

public class DataService<T> where T : class
{public List<T> FilterAndSort(List<T> data, Func<T, bool> filter,Func<T, object> sorter){return data.Where(filter).OrderBy(sorter).ToList();}
}// 使用
var userService = new DataService<User>();
var activeUsers = userService.FilterAndSort(users, u => u.IsActive, u => u.LastLoginDate
);

2. 多格式序列化服務

public interface ISerializer<T>
{string Serialize(T obj);T Deserialize(string data);
}public class JsonSerializer<T> : ISerializer<T> { /*...*/ }
public class XmlSerializer<T> : ISerializer<T> { /*...*/ }public class SerializationService<T>
{private readonly ISerializer<T> _serializer;public SerializationService(ISerializer<T> serializer) => _serializer = serializer;public string ToString(T obj) => _serializer.Serialize(obj);public T FromString(string data) => _serializer.Deserialize(data);
}

3. 表達式樹工作原理

Lambda表達式
表達式樹
表達式樹節點
參數表達式
二元表達式
常量表達式
查詢提供程序
翻譯機制
SQL查詢
數據庫執行

4. 大型數據集處理策略

// 流式JSON反序列化
await using var stream = File.OpenRead("large.json");
var data = JsonSerializer.DeserializeAsyncEnumerable<Person>(stream);await foreach (var person in data)
{// 單條處理,內存占用恒定
}// 分塊處理
const int chunkSize = 1000;
for (int i = 0; i < data.Count; i += chunkSize)
{var chunk = data.Skip(i).Take(chunkSize);ProcessChunk(chunk);
}

5. Lambda實現策略模式

public class PaymentProcessor
{private Func<Order, PaymentResult> _paymentStrategy;public void SetPaymentStrategy(Func<Order, PaymentResult> strategy) => _paymentStrategy = strategy;public PaymentResult ProcessOrder(Order order)=> _paymentStrategy?.Invoke(order) ?? throw new InvalidOperationException();
}// 使用
var processor = new PaymentProcessor();
processor.SetPaymentStrategy(order => order.Total > 1000 ? ProcessCreditCard(order) : ProcessCash(order));

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88453.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88453.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88453.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【電腦】內存的基礎知識

內存&#xff08;Memory&#xff09;是計算機中用于臨時存儲數據和程序的地方&#xff0c;它直接影響到系統的運行速度和性能。以下是關于內存的詳細知識&#xff1a;1. 內存類型常見的內存類型包括以下幾個主要種類&#xff1a;SDRAM (Synchronous Dynamic Random Access Memo…

Java---IDEA

IDEA概述 IDEA&#xff1a;全稱Intellij IDEA&#xff0c;是用于Java語言開發的集成開發環境 集成環境&#xff1a;把代碼編寫&#xff0c;編譯&#xff0c;運行&#xff0c;調試等多種功能綜合到一起的開發工具 下載與安裝 下載&#xff1a;IntelliJ IDEA – the IDE for …

【每日刷題】x 的平方根

69. x 的平方根 - 力扣&#xff08;LeetCode&#xff09; 方法一&#xff1a;暴力 從0開始遍歷&#xff0c;直到 ans*ans > x 為止&#xff0c;這時ans-1就是答案。需要注意可能會爆int&#xff0c;所以ans要開為long&#xff0c;最后再轉換為int。 class Solution {publ…

C#元組:從基礎到實戰的全方位解析

C#元組&#xff1a;從基礎到實戰的全方位解析 在 C# 編程中&#xff0c;元組&#xff08;Tuple&#xff09;是一種輕量級的數據結構&#xff0c;用于臨時存儲多個不同類型的元素。無論是方法返回多個值、LINQ 查詢中的臨時投影&#xff0c;還是簡化數據傳遞&#xff0c;元組都以…

Django母嬰商城項目實踐(二)

2、母嬰商城項目環境配置 環境配置: Python3.12 解釋器Pycharm Professional 2025.1 編輯器Django 4.2(或 Django 5.x)MySQL 8.0.28 數據庫 1、Django框架 介紹 Django是一個高級的Python Web應用框架,可以快速開發安全和可維護的網站。由經驗豐富的開發者構建,Django負責…

Go語言的Channel通道的含義。區分緩沖通道和非緩沖通道,并討論通道的發送、接收、關閉以及如何安全地從已關閉的通道讀取數據。

非緩沖通道&#xff1a;非緩沖通道在確定時沒有聲明容量大小&#xff0c;發送和接收操作會同步阻塞&#xff0c;直到另一端準備好。發送方和接收方必須同時就緒才能完成數據交換&#xff0c;否則會阻塞。常用于goroutine之間的同步通信。緩沖通道&#xff1a;緩沖通道在確定時就…

tensor

&#x1f609;如果您想用jupyter notebook跑我的筆記&#xff0c;可以在下面獲取ipynb版本 &#x1f60a;麻煩給個免費的star&#x1f618; ??主包也更建議這種形式&#xff0c;上面的筆記也更加全面&#xff0c;每一步都有直觀的輸出 文章目錄&#x1f4da; PyTorch張量操作…

STM32-DAC數模轉換

DAC數模轉換&#xff1a;將數字信號轉換成模擬信號特性&#xff1a;2個DAC轉換器每個都擁有一個轉換通道8位或12位單調輸出&#xff08;8位右對齊&#xff1b;12位左對齊右對齊&#xff09;雙ADC通道同時或者分別轉換外部觸發中斷電壓源控制部分&#xff08;外部觸發3個APB1&am…

前后端集合如何傳遞

前端vue后端rest風格&#xff1a;1.路徑傳參&#xff08;參數必傳&#xff09;&#xff0c;通過pathvarible注解后端&#xff1a;DeleteMapping("/{YYIDs}")public R<Void> remove(NotEmpty(message "主鍵不能為空")PathVariable String[] YYIDs) {…

1353. 最多可以參加的會議數目

1353. 最多可以參加的會議數目 題目鏈接&#xff1a;1353. 最多可以參加的會議數目 代碼如下&#xff1a; class Solution { public:int maxEvents(vector<vector<int>>& events) {int mx 0;for (auto& e : events) {mx max(mx, e[1]); // 找到最大的結…

OCR 本地版本

UMI OCR 支持本地部署&#xff0c;支持HTTP OCR

大數據驅動的酒店用品需求預測模型研究 開發——畢業論文,畢業設計——仙盟創夢IDE

主頁酒店用品 平臺協議促銷畢業論文摘要本研究旨在構建基于大數據分析的酒店用品需求預測模型&#xff0c;以提高酒店用品批發企業的庫存管理效率和供應鏈響應速度。研究整合了酒店歷史采購數據、季節因素、市場趨勢、節假日信息等多源數據&#xff0c;通過對比傳統時間序列模型…

Windows11桌面解鎖守護腳本

使用python程序加bat一鍵運行腳本&#xff0c;媽媽再也不用擔心我的電腦桌面了import os import time import cv2 import pyautogui import psutil from datetime import datetimeclass UnlockMonitor:def __init__(self):"""初始化監控器"""sel…

Linux Ubuntu系統的用戶管理

一.關于root用戶默認我們安裝完系統后 注冊的用戶就是管理員用戶標識符 $ 管理員標識符#最高管理員在Ubuntu系統中,root是最高管理員,擁有最大的權限,默認情況下root用戶沒有啟用密碼,而是通過sudo機制來獲取管理員權限二.Ubuntu系統中root用戶的默認狀態root用戶存在,但未啟用…

ROS1學習第三彈

ROS1學習第二彈 本文純屬記錄學習過程&#xff0c;所學教程來自B站古月居ROS入門21講 tf工具的使用 命令行中 1.rosrun tf view_frames 生成當前各個坐標的結構圖&#xff0c;導出pdf文件到當前終端所在文件夾下面2.rosrun rviz rviz -d rospackage find turtle_tf /rviz/tu…

技術演進中的開發沉思-30 MFC系列:五大機制

MFC&#xff0c;記得我剛畢業時在 CRT 顯示器前敲下第一行 MFC 代碼時&#xff0c;那時什么都不懂&#xff0c;沒有框架的概念。只覺得眼前的 CObject 像位沉默且復雜的大家族&#xff0c; 就像老北京胡同里的大家族&#xff0c;每個門牌號都藏著自己的故事。但現在看看&#x…

機器學習-06(Optimization-自動調整學習率)

臨界點其實不一定是在訓練神經網絡過程中遇到的最大阻礙。隨著對參數的不斷更新&#xff0c;Loss值會不斷下降&#xff0c;直至幾乎沒有變化&#xff0c;不再下降。當參數更新到臨界點時&#xff0c;意味著gradient非常小&#xff0c;所以要認定參數是否到達臨界點應當確認grad…

Uniapp中的uni.scss

uni.scss為uni-app新建項目自帶工程文件&#xff0c;使用的預處理器為sass/scss&#xff0c;由此可見&#xff0c;uni-app官方推薦的是scss。 uni.scss特點 無需引入&#xff0c;uni-app在編譯時&#xff0c;會自動引入此文件在此中定義的scss變量&#xff0c;可以全局使用&…

PreparedStatement 實現分頁查詢詳解

PreparedStatement 實現分頁查詢詳解 在 JDBC 中使用 PreparedStatement 實現分頁查詢是高效安全的方式&#xff0c;可以避免 SQL 注入并提升性能。下面我將詳細說明實現步驟和原理。 &#x1f4d0; 分頁查詢核心參數參數名說明計算公式pageNum當前頁碼&#xff08;從1開始&…

ClamAV 和 FreshClam:Linux 服務器上的開源殺毒解決方案

ClamAV 和 FreshClam:Linux 服務器上的開源殺毒解決方案 1. 概述 ClamAV 是一款開源的防病毒引擎,專為 Linux 服務器設計,用于檢測惡意軟件、病毒、木馬和其他安全威脅。它廣泛應用于郵件服務器、文件存儲系統和 Web 服務器,提供高效的病毒掃描功能。 主要特點: 免費開…