Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-16 22:58:27

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涉及 **委托、泛型、异步编程、闭包、线程安全** 等多个高级知识点:

---

### 🧠 面试题:异步委托链与状态捕获陷阱

#### 题目描述:

请分析以下 C# 代码,指出其输出结果,并解释为什么。同时,提出一种**线程安全**的修复方案,使其输出符合预期。

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

class Program
{
static void Main()
{
var actions = new Action[5];

for (int i = 0; i < 5; i++)
{
Task.Delay(100).ContinueWith(_ =>
{
actions[i] = () => Console.WriteLine(i);
});
}

Task.Delay(1000).ContinueWith(_ =>
{
for (int j = 0; j < 5; j++)
{
actions[j]?.Invoke();
}
});

Console.ReadLine();
}
}
```

---

### ✅ 考察点解析:

1. **闭包捕获陷阱(Closure Capturing)**
- `i` 是在 lambda 中被捕获的变量,而不是按值捕获。
- 因为异步执行,循环结束时 `i == 5`,所以所有 `actions[i]` 都打印 `5`。

2. **异步操作顺序问题**
- `ContinueWith` 是异步执行的,无法保证执行顺序。
- `i` 的值在异步回调执行时可能已经改变。

3. **线程安全问题**
- 多线程写入 `actions[i]`,没有同步机制,可能导致数据竞争。

4. **委托数组初始化的时序问题**
- 主线程继续执行,而 `actions` 可能尚未完全初始化。

---

### 🧪 预期输出(可能):

```
5
5
5
5
5
```

(也可能抛出异常或部分输出,取决于异步执行顺序)

---

### ✅ 正确修复方案(线程安全 + 闭包正确捕获):

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

class Program
{
static async Task Main()
{
var actions = new Action[5];

for (int i = 0; i < 5; i++)
{
int localCopy = i; // 捕获副本
await Task.Delay(100); // 更可控的异步等待

await Task.Run(() =>
{
actions[localCopy] = () => Console.WriteLine(localCopy);
});
}

await Task.Delay(1000); // 确保初始化完成

for (int j = 0; j < 5; j++)
{
actions[j]?.Invoke();
}

Console.ReadLine();
}
}
```

---

### 📌 总结考察维度:

| 技术点 | 是否考察 |
|----------------------|----------|
| 闭包与变量捕获 | ✅ |
| 异步编程模型 | ✅ |
| 线程安全与同步 | ✅ |
| 委托与数组操作 | ✅ |
| 异步执行顺序控制 | ✅ |
| `async/await` 使用 | ✅ |
| 代码健壮性设计 | ✅ |

---

如果你需要更多类似级别的题目(比如涉及表达式树、反射、内存模型、TPL、TPL Dataflow、RyuJIT优化等),我也可以继续提供。

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

上一篇: c#题例-2025-07-17 04:31:59

下一篇: c#题例-2025-07-16 17:25:14

精华推荐