c#题例-2025-07-31 05:25:15
日期: 2025-07-31 分类: AI写作 16次阅读
当然可以!以下是一道**专家级别**的 C# 逻辑面试题,它结合了 **委托、泛型、闭包、异步编程和线程安全** 等多个高级知识点,适合考察资深 C# 开发者的综合能力。
---
### 🧠 面试题:实现一个线程安全的事件总线(Event Bus)
#### 📌 题目描述:
请你实现一个简单的**线程安全的事件总线(Event Bus)系统**,满足以下要求:
1. 支持订阅任意类型的事件(使用泛型)。
2. 支持异步处理事件(即事件处理器是 `Func
3. 支持取消订阅。
4. 支持发布事件,并广播给所有匹配的订阅者。
5. 必须是线程安全的(多个线程发布或订阅时不会出错)。
6. 避免内存泄漏(比如处理订阅对象生命周期)。
#### 📝 示例接口定义:
```csharp
public interface IEventBus
{
void Subscribe
void Unsubscribe
Task Publish
}
```
---
### 🧩 考察点解析:
1. **泛型和委托的使用**:如何处理泛型事件类型和异步委托。
2. **线程安全设计**:使用 `ConcurrentDictionary` 或锁机制来保证并发安全。
3. **闭包与内存泄漏**:是否考虑到匿名函数、闭包导致的生命周期问题。
4. **弱引用(加分项)**:使用 `WeakReference` 或 `WeakEventManager` 避免订阅者无法被回收。
5. **异步编程模型**:是否正确地使用 `await Task.WhenAll(...)` 处理多个异步事件处理器。
6. **设计模式**:是否使用了观察者模式、工厂模式等。
---
### ✅ 示例答案(参考实现):
```csharp
public class EventBus : IEventBus
{
private readonly ConcurrentDictionary
new ConcurrentDictionary
private readonly object _lock = new object();
public void Subscribe
{
GetOrCreateCollection
}
public void Unsubscribe
{
if (_handlers.TryGetValue(typeof(TEvent), out var list))
{
var handlerList = (List
lock (_lock)
{
handlerList.Remove(handler);
}
if (handlerList.Count == 0)
{
_handlers.TryRemove(typeof(TEvent), out _);
}
}
}
public async Task Publish
{
if (_handlers.TryGetValue(typeof(TEvent), out var handlersObj))
{
var handlers = (List
var tasks = handlers.Select(h => h(@event)).ToArray();
await Task.WhenAll(tasks);
}
}
private List
{
return (List
typeof(TEvent),
_ =>
{
return new List
});
}
}
```
---
### 🧠 进阶问题(可选追问):
1. 如何支持基于事件类型的继承关系订阅(比如发布 `Dog` 事件,也能被 `Animal` 类型的处理器捕获)?
2. 如果订阅者是一个实例方法,会不会导致内存泄漏?如何避免?
3. 如何优化性能?比如使用不可变集合或 `IProducerConsumerCollection`?
4. 如何支持同步和异步混合的处理器?
---
如果你需要,我也可以提供一份使用 `WeakReference` 的高级实现版本来避免内存泄漏。
是否需要我继续给出这个版本?
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
精华推荐