Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-25 04:25:22

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,它不仅考察对语言特性的掌握,还涉及**多线程编程、异步编程、委托、闭包、线程安全**等高级概念。

---

### 💼 面试题:异步闭包陷阱与线程安全

#### 题目描述:

考虑以下 C# 代码:

```csharp
using System;
using System.Threading.Tasks;

class Program
{
static async Task Main()
{
for (var i = 0; i < 5; i++)
{
int counter = i;
Task.Run(async () =>
{
await Task.Delay(100); // 模拟异步操作
Console.WriteLine(counter);
});
}

Console.WriteLine("Main done.");
await Task.Delay(1000); // 等待所有任务完成
}
}
```

#### 问题:

1. **输出顺序是什么?**
2. **为什么会出现这个顺序?**
3. **如果将 `int counter = i;` 改为 `var counter = i;`,结果是否不同?为什么?**
4. **如何修改代码以确保每个任务打印出其对应的循环变量值(即 0 到 4)?**
5. **如果使用 `Parallel.For` 替代 `for` 循环,又会出现什么问题?如何解决?**

---

### 💡 解题思路与考察点:

这道题主要考察以下知识点:

- **闭包(Closure)与变量捕获陷阱**
- **异步编程模型(async/await)**
- **Task.Run 的执行机制**
- **线程安全与变量生命周期**
- **Parallel.For 的陷阱与线程调度机制**

---

### ✅ 参考答案概要:

#### 1. 输出顺序是什么?

输出顺序是不确定的,但通常是乱序,例如:

```
Main done.
2
3
1
0
4
```

或其它排列组合。

#### 2. 为什么?

因为:

- 每个 `Task.Run` 启动一个异步任务,延迟后打印 `counter`。
- `counter` 是在每次循环中定义的局部变量,**每次循环都会创建一个新的副本**,所以每个 lambda 捕获的是不同的变量。
- 因此,**输出顺序取决于线程调度和延迟完成的顺序**,不是按顺序执行的。

#### 3. `var counter = i;` 与 `int counter = i;` 有区别吗?

在 C# 中,**没有区别**。`var` 是隐式类型推断,编译器会将其推断为 `int`。因此,两种写法行为完全一致。

#### 4. 如何确保正确输出?

确保每个任务捕获的是当前循环变量的值。当前写法已经是对的(因为每次循环都新建了变量),但如果你使用的是传统的 `for` 循环(没有在循环体内定义变量),则需要显式“快照”变量:

```csharp
for (int i = 0; i < 5; i++)
{
int counter = i;
Task.Run(() =>
{
Console.WriteLine(counter);
});
}
```

#### 5. 如果使用 `Parallel.For`:

```csharp
Parallel.For(0, 5, i =>
{
Task.Run(async () =>
{
await Task.Delay(100);
Console.WriteLine(i);
});
});
```

此时可能会出现**变量捕获错误**,因为 `i` 是共享变量,可能在所有任务执行时已经改变了值。

**解决方案**:引入局部副本:

```csharp
Parallel.For(0, 5, (i, loopState) =>
{
int local = i;
Task.Run(async () =>
{
await Task.Delay(100);
Console.WriteLine(local);
});
});
```

---

### 🧠 总结

这道题目考察了现代 C# 开发中最容易踩坑的几个高级主题:

- 异步任务调度
- 闭包变量捕获陷阱
- 多线程编程的不确定性
- Parallel 与 Task 的交互
- 线程安全意识

---

如果你能完整解释并写出改进方案,说明你已经具备**高级 C# 工程师**甚至**架构师**级别的理解力。

需要更多类似题目吗?我可以继续出题 😎

除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog

上一篇: c#题例-2025-07-25 09:58:35

下一篇: c#题例-2025-07-24 22:52:10

精华推荐