Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-15 12:25:19

当然可以!以下是一道**专家级别**的 C# 逻辑面试题,考察候选人对 **委托、事件、异步编程、闭包捕获、线程安全以及设计模式** 的理解:

---

### 🧠 面试题:观察者模式与异步事件处理

#### 场景描述:
你正在开发一个多线程数据采集系统。系统中有多个传感器(`Sensor`),每个传感器会在采集到新数据时触发事件,并通知所有注册的观察者(`Observer`)。观察者可能执行耗时操作(如网络请求或日志写入)。

你的任务是实现一个 `EventAggregator` 类,用于聚合这些事件并以**异步非阻塞**的方式通知所有订阅者。同时,要保证在并发环境下不会出现内存泄漏或异常中断。

---

### ✅ 要求如下:

1. 实现一个泛型事件发布/订阅机制:`EventAggregator.Publish(T event)` 和 `EventAggregator.Subscribe(Func handler)`。
2. 所有订阅的 `Func` 必须**异步执行**,互不阻塞。
3. 多个线程调用 `Publish()` 时应保证线程安全。
4. 支持取消订阅功能(可选进阶)。
5. 避免因某个 `handler` 抛出异常导致整个发布流程中断。
6. 不允许使用第三方库(如 Reactive Extensions)或 `System.Reactive`。

---

### 📌 示例代码框架:

```csharp
public class EventAggregator
{
// TODO: 实现构造函数、Subscribe、Publish 等方法

public void Subscribe(Func handler)
{
// 实现订阅逻辑
}

public async Task Publish(T @event)
{
// 实现事件广播逻辑
}
}
```

---

### 💡 进阶问题(供面试追问):

- 如何防止内存泄漏?如果观察者持有外部对象引用怎么办?
- 如何支持取消订阅?
- 如果某些观察者需要同步执行,如何扩展接口?
- 如何优化性能,在高并发下避免线程爆炸?
- 如何测试这个类的线程安全性?

---

### 🔍 面试官期望看到的要点:

| 技术点 | 关键词 |
|--------|--------|
| 委托与泛型 | `Func`、类型安全 |
| 异步编程 | `Task.Run`, `await Task.CompletedTask`, 异常处理 |
| 线程安全 | 使用 `ConcurrentDictionary` 或 `lock` 同步访问订阅列表 |
| 内存管理 | 使用弱引用、支持取消订阅、避免事件泄露 |
| 异常处理 | 捕获每个 handler 的异常,不影响其他订阅者 |

---

### 🧪 参考答案片段(部分):

```csharp
public class EventAggregator
{
private readonly ConcurrentDictionary> _handlers = new();

public void Subscribe(Func handler)
{
_handlers
.GetOrAdd(typeof(T), _ => new List())
.Add(handler);
}

public async Task Publish(T @event)
{
if (_handlers.TryGetValue(typeof(T), out var handlers))
{
var tasks = handlers.OfType>()
.Select(async handler =>
{
try
{
await handler(@event).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error in handler: {ex}");
}
});

await Task.WhenAll(tasks).ConfigureAwait(false);
}
}
}
```

---

是否需要我为这道题提供一份完整的单元测试代码?或者想看它如何应用于实际项目中?

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

上一篇:无

下一篇: c#题例-2025-07-15 06:51:50

精华推荐