c#题例-2025-07-13 02:25:15
日期: 2025-07-13 分类: AI写作 11次阅读
当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涵盖了 **委托、泛型、闭包、异步编程、线程安全**等多个高级概念,适合考察候选人的综合编程能力和对 .NET 底层机制的理解。
---
### 🧠 面试题:实现一个线程安全的缓存订阅系统
#### 背景描述:
你需要为一个金融数据平台设计一个组件,该组件可以从多个数据源(如股票价格、汇率等)接收更新,并将这些更新通知给已注册的回调函数。每个数据源由一个唯一的字符串标识符(例如 `"Stock.AAPL"` 或 `"Currency.USD.EUR"`)表示。
#### 任务要求:
请使用 C# 编写一个 `DataUpdateNotifier
1. **支持订阅与取消订阅**:
- 提供方法允许用户通过提供数据源 ID 和一个回调函数 `Action
- 提供方法用于取消订阅。
2. **推送更新**:
- 提供一个方法 `Notify(string sourceId, T data)`,当某个数据源有新数据时调用此方法,所有订阅了该 `sourceId` 的回调都应该被调用,并传入 `data`。
3. **异步执行**:
- 所有回调必须在后台线程中异步执行(不能阻塞主线程),但要确保回调之间是串行执行的(即不能并发执行回调)。
4. **线程安全**:
- 多个线程可能同时调用 `Subscribe`, `Unsubscribe`, 和 `Notify` 方法,你的实现必须保证线程安全。
5. **防止内存泄漏**:
- 回调应以弱引用方式存储(或使用其他机制)以避免订阅者无法被垃圾回收。
6. **性能优化建议**:
- 不需要为没有订阅者的 `sourceId` 维护额外结构。
---
### 示例代码结构(可作为参考):
```csharp
public class DataUpdateNotifier
{
public void Subscribe(string sourceId, Action
{
// TODO: 实现
}
public void Unsubscribe(string sourceId, Action
{
// TODO: 实现
}
public void Notify(string sourceId, T data)
{
// TODO: 实现
}
}
```
---
### 💡 考察点解析:
| 技术点 | 考察内容 |
|--------|----------|
| 委托与事件 | 如何管理回调函数 |
| 泛型 | 对泛型类型参数的合理使用 |
| 线程安全 | 使用 `ConcurrentDictionary`, 锁机制或其它同步策略 |
| 异步编程 | 是否使用 `Task.Run` 或队列+线程池机制 |
| 串行执行 | 是否使用队列或信号量限制并发 |
| 内存管理 | 是否使用 `WeakReference` 或自定义封装避免内存泄漏 |
| 架构设计 | 类的设计是否清晰、扩展性强 |
---
### ✅ 可加分项(如果候选人主动提及):
- 使用 `ConditionalWeakTable` 来追踪订阅者对象生命周期。
- 使用 `Channel
- 使用 `Interlocked` 或 `CompareExchange` 实现无锁读操作。
- 对 `sourceId` 进行规范化处理(如大小写不敏感或哈希优化)。
- 单元测试思路或异常处理策略。
---
如果你需要这道题的参考答案或者想了解如何评估候选人的实现,请告诉我 😄
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
上一篇:无
精华推荐