c#题例-2025-07-05 20:25:12
日期: 2025-07-05 分类: AI写作 27次阅读
当然可以!以下是一道**专家级别**的 C# 逻辑面试题,涉及 **泛型、委托、闭包、线程安全和延迟执行(deferred execution)** 等多个高级概念:
---
### 🧠 面试题:理解 `yield return` 和闭包在多线程下的行为
#### 问题描述:
请分析下面这段代码的输出,并解释其背后的行为机制。特别是关注闭包捕获、`yield return` 的延迟执行特性以及多线程环境下的潜在问题。
```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program
{
static IEnumerable
{
for (int i = 1; i <= 3; i++)
{
int value = i;
Task.Run(async () =>
{
await Task.Delay(100); // 模拟异步操作
Console.WriteLine($"Computed: {value}");
});
yield return $"Yielded Value: {value}";
}
}
static async Task Main(string[] args)
{
var result = GetData();
foreach (var item in result)
{
Console.WriteLine(item);
await Task.Delay(150); // 控制迭代速度
}
await Task.Delay(500); // 确保所有后台任务完成
}
}
```
---
### 💡 问题分解与考察点:
1. **`yield return` 的延迟执行机制**
- 什么时候实际执行循环体?
- 在 `foreach` 中每次迭代时才触发一次循环体。
2. **闭包与变量捕获(Closure and Variable Capture)**
- `value` 是值类型,赋值给了 lambda 表达式。
- 如果没有 `int value = i;`,会发生什么?
3. **多线程下的不确定性**
- `Task.Run` 异步执行,何时输出?顺序是否固定?
- 是否存在竞争条件或线程安全问题?
4. **输出顺序的不确定性**
- 控制台打印是同步的 `yield return` 输出还是异步任务的输出?
- 两者之间是否有依赖关系?
5. **延迟执行与副作用**
- `GetData()` 返回的是一个“惰性”序列,副作用(启动任务)会随着枚举而逐步发生。
---
### ✅ 正确回答应该包括:
- 对 `yield return` 延迟执行的理解;
- 对闭包中变量捕获机制的掌握;
- 多线程下异步任务调度可能带来的输出顺序不确定性;
- 能指出如果没有 `int value = i`,lambda 捕获的是 `i` 的引用,导致三者都输出 4;
- 意识到主线程控制台输出和后台任务输出是并发进行的,顺序不可预测;
- 理解为何最后需要 `await Task.Delay(500)` 来等待后台任务完成。
---
### 🔁 示例预期输出(可能的一种情况):
```
Yielded Value: 1
Computed: 1
Yielded Value: 2
Computed: 2
Yielded Value: 3
Computed: 3
```
但注意:由于异步任务的时间差,也可能是:
```
Yielded Value: 1
Yielded Value: 2
Yielded Value: 3
Computed: 1
Computed: 2
Computed: 3
```
甚至混合交错的情况。
---
如果你希望我再出一道不同方向的(如涉及表达式树、LINQ 优化、内存模型、设计模式等),也可以告诉我 😊
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
精华推荐