Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-03 10:25:06

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,它不仅考察语言语法知识,还涉及 **委托、事件、闭包、线程安全、异步编程、内存模型等高级主题**,适合用于考察资深 C# 开发者的综合理解能力。

---

### 🧠 面试题:请分析并预测以下程序的输出结果,并解释原因

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

class Program
{
static async Task Main(string[] args)
{
var results = new int[3];

for (var i = 0; i < 3; i++)
{
int counter = i;
Task.Run(async () =>
{
await Task.Delay(100); // 模拟异步操作
results[counter] = counter * 2;
});
}

await Task.Delay(500); // 给任务足够时间完成

for (int i = 0; i < results.Length; i++)
{
Console.WriteLine($"results[{i}] = {results[i]}");
}
}
}
```

---

### ✅ 考察点解析:

1. **循环变量捕获(Closure)问题**:
- 在 C# 5.0 及以上版本中,`for` 循环中的 `i` 被“隐式重新定义”在每次迭代中,因此使用 `counter = i` 是为了确保每个 lambda 表达式都捕获到不同的值。
- 如果你写成 `results[i] = i * 2`,会存在潜在的闭包陷阱吗?在这里不会,因为有 `counter = i` 这个局部变量拷贝。

2. **Task.Run 和异步 Lambda 的使用**:
- 使用了 `async` lambda 表达式,意味着该委托返回一个 `Task`,并且会在后台线程中运行。

3. **线程安全性问题**:
- 是否多个线程同时写入 `results` 数组会有并发冲突?
- 答案是:**不会有冲突**。因为每个任务写入的是数组的不同索引位置(`counter` 是唯一的),不存在共享数据竞争。

4. **延迟等待是否合理**:
- 主函数用了 `await Task.Delay(500)` 来保证所有后台任务执行完毕。
- 实际开发中应使用 `Task.WaitAll()` 更可靠地等待任务完成,但这里假设延迟足够长。

---

### 🔍 正确输出应该是:

```
results[0] = 0
results[1] = 2
results[2] = 4
```

---

### 💡 扩展提问(可选):

- 如何改进这段代码以确保线程安全和更健壮的任务等待机制?
- 如果去掉 `counter = i`,会发生什么?为什么?
- 如果改为 `List` 并使用 `await Task.WhenAll(...)`,如何改写?

---

如果你需要更多类似级别的题目(如与 LINQ 表达式树、反射、自定义 awaiter、内存池、Span、Source Generator 等相关的),我也可以继续提供。

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

上一篇: c#题例-2025-07-03 15:58:30

下一篇: c#题例-2025-07-03 04:51:55

精华推荐