c#题例-2025-06-26 22:18:44
日期: 2025-06-26 分类: AI写作 12次阅读
当然可以!下面是一道**专家级别**的 C# 逻辑面试题,它考察了 **委托、泛型、闭包、异步编程、线程安全、设计模式** 等多个高级知识点,非常适合用于筛选资深的 C# 开发者。
---
### 🧠 面试题:实现一个线程安全的事件总线(Event Bus)系统
#### 背景:
在现代应用程序中,特别是在解耦模块化架构中,常常使用“事件总线”来实现组件之间的通信。你需要实现一个简单的线程安全的事件总线系统,支持订阅、发布和取消订阅功能。
---
### ✅ 需求:
1. 实现一个泛型接口 `IEventBus
2. 接口定义如下:
```csharp
public interface IEventBus
{
void Subscribe(Action
void Unsubscribe(Action
void Publish(T @event);
}
```
3. 要求:
- 支持多线程环境下的并发订阅/发布。
- 订阅者回调不能阻塞发布线程(可选为同步或异步)。
- 同一订阅者多次订阅应去重。
- 处理异常时不能中断其他订阅者的执行。
- 尽量避免内存泄漏(比如弱引用机制可作为加分项)。
---
### 💡 可扩展问题(进阶讨论):
- 如何让这个事件总线支持异步处理(返回 `Task` 的 handler)?
- 如何让它支持优先级排序?
- 如何实现一次性订阅(只触发一次就自动取消)?
- 如果要支持跨 AppDomain 或跨进程通信,你会如何设计?
---
### 🔍 示例代码框架:
```csharp
public class ThreadSafeEventBus
{
private readonly List
private readonly object _lock = new();
public void Subscribe(Action
{
if (handler == null) throw new ArgumentNullException(nameof(handler));
lock (_lock)
{
// 去重 + 弱引用管理(可选)
if (!_handlers.Any(r => r.TryGetTarget(out var existing) && existing == handler))
{
_handlers.Add(new WeakReference
}
}
}
public void Unsubscribe(Action
{
if (handler == null) throw new ArgumentNullException(nameof(handler));
lock (_lock)
{
_handlers.RemoveAll(r =>
{
if (r.TryGetTarget(out var target))
return target == handler;
return true; // Remove dead references
});
}
}
public void Publish(T @event)
{
List
lock (_lock)
{
snapshot = _handlers
.Where(r => r.TryGetTarget(out var handler))
.Select(r => r.Target!)
.ToList();
}
foreach (var handler in snapshot)
{
try
{
handler(@event);
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error invoking handler: {ex}");
}
}
}
}
```
---
### 🧪 单元测试建议:
你可以要求候选人写出几个单元测试,例如:
- 多个线程同时订阅和发布是否安全?
- 是否能正确处理异常?
- 是否能防止重复订阅?
- 弱引用是否释放得当?
---
### 📌 本题考察点总结:
| 技术点 | 描述 |
|--------|------|
| 委托与事件模型 | 对 Action
| 线程安全 | 使用 lock、并发集合等保证并发访问安全 |
| 异常处理 | 不因个别 handler 出错而中断整个流程 |
| 内存管理 | 使用弱引用来防止内存泄漏 |
| 设计能力 | 结构清晰,职责分明,易于扩展 |
---
如果你需要这道题的详细解答或者扩展版本(如异步版、带过滤条件的 EventBus),我也可以继续补充。是否需要?
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
精华推荐