Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-18 03:58:22

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涉及 **多线程、异步编程、锁机制、资源竞争、死锁预防** 等高级知识点:

---

### 🧠 面试题:并发缓存刷新机制设计

#### 背景描述:

你正在开发一个高性能的缓存服务,该服务支持并发访问,并且缓存项具有过期时间。当缓存项过期后,第一次请求该缓存项时,应该触发一次**后台刷新操作**,同时返回旧值(如果存在),并在后台异步刷新新值。后续请求应等待刷新完成或使用旧值(根据策略)。

#### 要求:

实现一个泛型缓存类 `ExpiringCache`,满足以下要求:

1. 支持插入缓存项,并设置过期时间。
2. 获取缓存项时,若未过期则直接返回值。
3. 如果缓存项**已过期**:
- 如果是第一个请求,则启动后台刷新操作,返回旧值(如果允许),并在后台刷新新值。
- 如果是并发请求同一项,应该等待第一个请求完成刷新后再返回新值。
4. 刷新操作由用户提供一个 `Func> refreshFunc`。
5. 使用线程安全机制,防止并发刷新、死锁、资源竞争。
6. 支持取消刷新操作(通过 `CancellationToken`)。
7. 提供异步和同步两种获取接口。

#### 接口定义(你可以补充):

```csharp
public class ExpiringCache
{
public ExpiringCache(Func> refreshFunc);

public void Set(TKey key, TValue value, TimeSpan expiration);

public Task GetAsync(TKey key, CancellationToken ct = default);

public TValue Get(TKey key, CancellationToken ct = default);
}
```

---

### 🧪 示例:

```csharp
var cache = new ExpiringCache(async (key, ct) =>
{
await Task.Delay(1000, ct); // 模拟耗时刷新
return $"NewValue_{key}";
});

cache.Set("test", "OldValue", TimeSpan.FromSeconds(2));

// 2秒内
Console.WriteLine(cache.Get("test")); // 输出 "OldValue"

// 2秒后
Console.WriteLine(cache.Get("test")); // 应该等待刷新完成并返回 "NewValue_test"
```

---

### 🧱 考察点:

- 多线程安全访问与缓存更新机制
- 异步任务的并发控制(例如使用 `TaskCompletionSource` 或 `AsyncLock`)
- 使用 `ConcurrentDictionary` 来管理缓存
- 避免多个线程重复刷新同一个缓存项
- 正确处理取消操作和超时
- 正确使用 `CancellationToken` 和 `ConfigureAwait(false)`
- 对 `async/await` 的深入理解(如线程池切换、死锁预防)
- 面向对象设计与封装能力

---

### 💡 提示:

- 可以考虑使用 `TaskCompletionSource` 来协调多个并发请求等待刷新完成。
- 每个 key 的刷新状态可以单独管理。
- 使用 `ConcurrentDictionary` 来保存缓存项。
- `CacheEntry` 应包含值、过期时间、刷新任务等信息。

---

如果你需要,我也可以提供一个参考实现。这个题目适合考察**高级C#开发人员的并发编程能力与系统设计能力**。是否需要我给出参考答案?

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

上一篇: c#题例-2025-07-18 09:31:48

下一篇: c#题例-2025-07-17 22:24:59

精华推荐