c#题例-2025-07-12 02:58:42
日期: 2025-07-12 分类: AI写作 9次阅读
当然可以!以下是一道**专家级别**的 C# 程序员逻辑面试题,涵盖了 **委托、泛型、异步编程、闭包捕获、线程安全**等多个高级概念,适合考察候选人对 C# 语言特性和底层机制的理解深度。
---
### 🧠 面试题:分析并解释以下代码的输出,并说明如何修正
```csharp
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var tasks = new Task[10];
for (int i = 0; i < 10; i++)
{
int counter = i;
tasks[i] = Task.Run(async () =>
{
await Task.Delay(100); // 模拟异步工作
Console.WriteLine($"Value: {counter}");
});
}
await Task.WhenAll(tasks);
}
}
```
---
### ✅ 考察点:
1. **闭包与变量捕获(Closure & Variable Capture)**
2. **值类型 vs 引用类型的捕获行为**
3. **Task.Run 和异步 lambda 的执行顺序**
4. **多线程环境下的输出顺序是否确定?**
5. **如何确保输出是 0 到 9 的顺序?**
---
### 💡 延伸问题(可选):
- 如果将 `int counter = i;` 替换为 `ref int counter = ref i;`,会发生什么?
- 如何使用 `ConcurrentDictionary` 或锁来保证线程安全?
- 如果我们希望按顺序输出 0 到 9,应该如何修改代码?
---
### 📌 示例答案要点:
#### 输出结果:
- 输出的顺序是**不确定的**,因为任务在不同的线程中并发运行。
- 尽管每个 `counter` 是在循环内定义的局部变量(值类型),但由于它被分配到每次迭代的新副本,所以不会出现典型的“循环变量共享”问题(这是 C# 5.0 及以后版本的行为)。
- 因此,最终会打印出从 `0` 到 `9` 的数字,但顺序不固定。
#### 关键知识点:
- 在 C# 5.0 及以上版本中,循环变量在 `for` 循环中被捕获时,会在每次迭代中创建一个新的变量实例,避免了早期版本中常见的陷阱。
- 使用 `await Task.Delay()` 使每个任务真正异步地挂起,释放线程资源。
- 多线程环境下,除非显式控制调度或同步,否则任务完成顺序是不可预测的。
#### 如何保证输出顺序?
- 使用 `Parallel.For` 并配合索引处理。
- 或者,使用顺序化的队列系统(如 `DataflowBlock`)。
- 或者,在主线程中等待每一个任务按顺序完成(不太推荐,牺牲性能)。
---
如果你需要更多类似难度的题目,比如涉及表达式树、内存模型、自定义 awaiter、LINQ 行为等,也可以继续问我。
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
上一篇:无
精华推荐