如何通过C#面试:高级别热门问题

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

如何通过C#面试:高级别热门问题



高级C#开发者职位的面试,不仅考察语法知识,更看重对.NET内部机制、性能优化和架构决策的深入理解。本文将解析技术面试中常见的关键主题。你将学会如何回答复杂问题,并获得现成的代码示例来展示你的技能。



1. 异步编程:async/await 与 Task



关于async和await

典型问题:“如果在UI线程中对异步方法调用.Result或.Wait()会发生什么?”



答案:会发生死锁,因为主线程在等待结果时被阻塞,而异步方法的延续(continuation)试图返回到同一个已被占用的同步上下文。解决方案是使用ConfigureAwait(false),或者完全采用异步调用。



public async Task<string> GetDataAsync(){    // 正确处理上下文    var result = await SomeHttpCallAsync().ConfigureAwait(false);    return result;}

// 错误:在UI/ASP.NET Core中导致死锁(.NET Core 2.1之前)// var data = GetDataAsync().Result;


附加问题:“Task.Run和Task.Factory.StartNew有什么区别?”



Task.Run使用默认线程池并自动展开嵌套任务。StartNew提供更多控制(例如可以指定TaskCreationOptions.LongRunning),但对于异步委托需要手动管理Unwrap()。



2. LINQ与延迟执行(Deferred Execution)



LINQ是一个强大的工具,但使用不当可能导致性能下降。高级问题常涉及IQueryable与IEnumerable的区别以及查询的物化。



问题:“为什么以下代码会对数据库执行多次查询?”



var query = context.Products.Where(p => p.Price > 100);foreach (var product in query){    Console.WriteLine(product.Name);}var count = query.Count(); // 第二次查询!


答案:IQueryable表示一个表达式树,会被转换为SQL。每次你迭代或调用聚合函数(Count、Sum)时,都会重新发送SQL。为避免这种情况,需要物化数据:var list = query.ToList();



高级细节:First()和FirstOrDefault()的区别——First()在序列为空时会抛出异常,这在错误处理方面可能代价更高。



3. 内存管理与垃圾回收器(GC)



理解GC的工作原理是高级开发者的标志。问题可能涉及代(Generations)、终结化以及Dispose模式。



问题:“什么是大型对象堆(LOH),为什么需要谨慎对待它?”



答案:LOH是用于大小超过85,000字节的对象的堆。与小对象堆不同,LOH(在.NET 4.5.1之前)不进行压缩,导致内存碎片化。这可能会引发OutOfMemoryException,即使空闲内存很多。建议:使用对象池或将大数组拆分成小块。



// 不良实践示例byte[] largeBuffer = new byte[100_000]; // 进入LOH

// 更好的做法:使用ArrayPoolbyte[]

博客

书籍推荐