Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-31 05:25:15

当然可以!以下是一道**专家级别**的 C# 逻辑面试题,它结合了 **委托、泛型、闭包、异步编程和线程安全** 等多个高级知识点,适合考察资深 C# 开发者的综合能力。

---

### 🧠 面试题:实现一个线程安全的事件总线(Event Bus)

#### 📌 题目描述:

请你实现一个简单的**线程安全的事件总线(Event Bus)系统**,满足以下要求:

1. 支持订阅任意类型的事件(使用泛型)。
2. 支持异步处理事件(即事件处理器是 `Func` 类型)。
3. 支持取消订阅。
4. 支持发布事件,并广播给所有匹配的订阅者。
5. 必须是线程安全的(多个线程发布或订阅时不会出错)。
6. 避免内存泄漏(比如处理订阅对象生命周期)。

#### 📝 示例接口定义:

```csharp
public interface IEventBus
{
void Subscribe(Func handler);
void Unsubscribe(Func handler);
Task Publish(TEvent @event);
}
```

---

### 🧩 考察点解析:

1. **泛型和委托的使用**:如何处理泛型事件类型和异步委托。
2. **线程安全设计**:使用 `ConcurrentDictionary` 或锁机制来保证并发安全。
3. **闭包与内存泄漏**:是否考虑到匿名函数、闭包导致的生命周期问题。
4. **弱引用(加分项)**:使用 `WeakReference` 或 `WeakEventManager` 避免订阅者无法被回收。
5. **异步编程模型**:是否正确地使用 `await Task.WhenAll(...)` 处理多个异步事件处理器。
6. **设计模式**:是否使用了观察者模式、工厂模式等。

---

### ✅ 示例答案(参考实现):

```csharp
public class EventBus : IEventBus
{
private readonly ConcurrentDictionary _handlers =
new ConcurrentDictionary();

private readonly object _lock = new object();

public void Subscribe(Func handler)
{
GetOrCreateCollection().Add(handler);
}

public void Unsubscribe(Func handler)
{
if (_handlers.TryGetValue(typeof(TEvent), out var list))
{
var handlerList = (List>)list;
lock (_lock)
{
handlerList.Remove(handler);
}

if (handlerList.Count == 0)
{
_handlers.TryRemove(typeof(TEvent), out _);
}
}
}

public async Task Publish(TEvent @event)
{
if (_handlers.TryGetValue(typeof(TEvent), out var handlersObj))
{
var handlers = (List>)handlersObj;
var tasks = handlers.Select(h => h(@event)).ToArray();
await Task.WhenAll(tasks);
}
}

private List> GetOrCreateCollection()
{
return (List>)_handlers.GetOrAdd(
typeof(TEvent),
_ =>
{
return new List>();
});
}
}
```

---

### 🧠 进阶问题(可选追问):

1. 如何支持基于事件类型的继承关系订阅(比如发布 `Dog` 事件,也能被 `Animal` 类型的处理器捕获)?
2. 如果订阅者是一个实例方法,会不会导致内存泄漏?如何避免?
3. 如何优化性能?比如使用不可变集合或 `IProducerConsumerCollection`?
4. 如何支持同步和异步混合的处理器?

---

如果你需要,我也可以提供一份使用 `WeakReference` 的高级实现版本来避免内存泄漏。

是否需要我继续给出这个版本?

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

上一篇: c#题例-2025-07-31 10:58:43

下一篇: c#题例-2025-07-30 23:51:54

精华推荐