Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-01 11:32:56

当然可以!下面是一道**专家级别**的 C# 逻辑面试题,涵盖了 **委托、泛型、异步编程、闭包捕获、线程安全和性能优化意识**等多个高级概念:

---

### 🧠 面试题:实现一个支持并发的缓存装饰器(Cache Decorator)

#### 背景:
你正在设计一个通用的服务层组件,该组件需要频繁调用一些外部服务方法(如数据库查询、远程 API 等),这些方法通常具有以下特征:

- 输入参数为一个或多个值。
- 输出结果可缓存一段时间。
- 方法本身是耗时的(I/O 密集)。

你需要实现一个通用的缓存装饰器 `CachedServiceDecorator`,它可以自动为任何符合签名的方法添加缓存功能。

---

### ✅ 题目要求:

编写一个泛型类 `CachedServiceDecorator`,它接收一个 `Func>` 类型的服务方法,并提供一个带有缓存功能的新方法 `Task GetAsync(T key, CancellationToken ct)`。

具体要求如下:

1. 缓存应基于传入的 `key` 值进行存储。
2. 每个缓存项应在指定的时间后过期(例如:30秒)。
3. 如果多个线程同时请求相同的 `key`,只能有一个线程执行原始方法,其余线程等待其结果(防击穿)。
4. 实现优雅地处理取消操作(CancellationToken)。
5. 尽可能减少内存泄漏风险,合理使用弱引用或缓存清理机制。
6. 支持自定义缓存过期时间(通过构造函数传入)。
7. 【加分项】实现滑动过期(Sliding Expiration)或绝对过期(Absolute Expiration)策略之一。

---

### 💡 示例代码结构提示:

```csharp
public class CachedServiceDecorator
{
private readonly Func> _serviceFunc;
private readonly TimeSpan _cacheDuration;
private readonly ConcurrentDictionary _cache;

public CachedServiceDecorator(Func> serviceFunc, TimeSpan cacheDuration)
{
// TODO: 实现构造函数
}

public async Task GetAsync(T key, CancellationToken ct)
{
// TODO: 实现缓存逻辑
}

private class CacheEntry
{
public Task TaskResult { get; }
public DateTime ExpiryTime { get; }

public CacheEntry(Task taskResult, DateTime expiryTime)
{
TaskResult = taskResult;
ExpiryTime = expiryTime;
}
}
}
```

---

### 🔍 高级考察点:

| 技术点 | 考察内容 |
|--------|----------|
| 泛型与委托 | 是否理解如何抽象任意输入输出的服务方法 |
| 异步编程 | 正确使用 `Task` 和避免死锁 |
| 线程安全 | 使用 `ConcurrentDictionary` 或锁机制防止并发问题 |
| 缓存穿透防护 | 使用“缓存占位”或同步上下文确保只有一个线程真正调用原方法 |
| 取消令牌 | 合理传递并响应 `CancellationToken` |
| 内存管理 | 使用合适的缓存结构避免内存泄漏(比如考虑弱引用、定时清理等) |

---

### 🧪 示例测试场景:

```csharp
var decorated = new CachedServiceDecorator(
async key =>
{
await Task.Delay(1000); // 模拟耗时操作
return $"Processed-{key}";
},
TimeSpan.FromSeconds(30));

var result1 = await decorated.GetAsync("test", CancellationToken.None);
var result2 = await decorated.GetAsync("test", CancellationToken.None);

Console.WriteLine(result1 == result2); // 应输出 True,说明命中缓存
```

---

如果你希望我提供这个题目的参考实现或解析,也可以告诉我。这道题非常适合用来评估一个 C# 开发者是否具备架构思维和系统级设计能力。

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

上一篇:无

下一篇: c#题例-2025-07-01 05:59:27

精华推荐