Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-08-01 04:51:47

当然可以!下面是一道**专家级别**的 C# 逻辑面试题,涵盖了 **委托、泛型、闭包、异步编程、线程安全**等多个高级 C# 特性,适合考察候选人对语言特性的深入理解和综合运用能力。

---

### 🧠 面试题:编写一个支持异步和同步操作的通用缓存工厂

#### 背景描述:

你正在设计一个通用的缓存系统,该系统需要支持:

- 缓存数据的获取可以是同步或异步;
- 缓存项有过期时间;
- 如果缓存未命中或已过期,则调用一个工厂函数来重新生成数据;
- 多个线程同时请求同一个未缓存的键时,应避免**缓存击穿**(即只执行一次工厂函数);

---

### ✅ 要求:

编写一个泛型类 `CacheProvider`,满足以下接口和行为:

```csharp
public interface ICacheProvider
{
TValue Get(TKey key, Func factory, TimeSpan expiration);
Task GetAsync(TKey key, Func> factory, TimeSpan expiration);
}
```

#### 方法说明:

- `Get(...)`:同步获取缓存值。如果不存在或已过期,调用 `factory` 函数生成新值并缓存。
- `GetAsync(...)`:异步获取缓存值,逻辑与同步类似。
- 所有方法需线程安全,并避免多个线程同时调用 `factory` 来生成相同键的值(缓存击穿)。

---

### 💡 提示:

1. 使用 `ConcurrentDictionary` 来保存缓存;
2. 对于并发控制,可以使用 `SemaphoreSlim` 或 `AsyncLock` 来防止多个线程重复生成;
3. 可定义一个私有类 `CacheItem` 来保存值和过期时间;
4. 异步方法中,可使用 `Task` 缓存来共享异步结果;
5. 注意闭包捕获和线程安全问题。

---

### 📌 示例:

```csharp
var cache = new CacheProvider(...);

string result = cache.Get("key1", k =>
{
Console.WriteLine("Generating value for key1");
return "value1";
}, TimeSpan.FromSeconds(10));

string result2 = cache.Get("key1", k =>
{
Console.WriteLine("This won't be printed");
return "another value";
}, TimeSpan.FromSeconds(10));

// 输出应只有一次 "Generating value for key1"
```

---

### 🎯 考察点:

- 泛型编程;
- 委托与函数式编程;
- 异步编程(async/await);
- 线程安全(ConcurrentDictionary、锁机制);
- 缓存击穿的处理;
- 对闭包、委托捕获的理解;
- 代码结构设计能力与异常处理意识;

---

如果你需要我提供一个**参考实现**或者对某个部分进行扩展讲解,也可以告诉我!

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

上一篇: c#题例-2025-08-01 10:25:23

下一篇: c#题例-2025-07-31 23:18:26

精华推荐