c#题例-2025-06-15 23:12:37
日期: 2025-06-15 分类: AI写作 52次阅读
好的!以下是一道专家级别的 C# 程序员逻辑面试题,涉及多线程、并发和性能优化方面的知识:
---
### 面试题:实现一个高效的线程安全的缓存系统
**问题描述:**
你需要设计并实现一个线程安全的缓存系统 `ThreadSafeCache
1. **缓存键值对**:支持存储任意类型的键值对(`key-value`),其中键是 `string` 类型,值是泛型类型 `T`。
2. **过期机制**:每个缓存项可以设置一个过期时间(以秒为单位),如果超过这个时间,该项将被自动移除。
3. **线程安全**:允许多个线程同时访问缓存,而不会导致数据竞争或不一致。
4. **高效性**:尽量减少锁的使用范围,避免性能瓶颈。
5. **清理机制**:提供一种机制定期清理过期的缓存项。
**接口定义:**
```csharp
public class ThreadSafeCache
{
// 添加缓存项,并指定过期时间(秒)
public void Add(string key, T value, int expirationInSeconds);
// 获取缓存项,如果不存在或已过期,返回默认值
public T Get(string key);
// 删除缓存项
public void Remove(string key);
// 清理所有过期的缓存项
public void CleanupExpiredItems();
}
```
**额外要求:**
- 使用 C# 的 `ConcurrentDictionary` 或其他线程安全集合来实现。
- 考虑如何优化锁的粒度,避免全局锁带来的性能问题。
- 如果可能,使用 `Task` 或 `Timer` 来定期清理过期项。
---
### 提示与思考方向:
1. **线程安全集合的选择**:C# 提供了多种线程安全的集合类,如 `ConcurrentDictionary`。你可以利用这些类来简化线程安全的实现。
2. **过期机制的设计**:你可以为每个缓存项维护一个时间戳(`DateTime` 或 `TimeSpan`),并在 `Get` 和 `CleanupExpiredItems` 方法中检查是否过期。
3. **锁的优化**:尽量避免在整个缓存操作中使用全局锁。例如,可以只在更新特定键值对时加锁,或者使用读写锁(`ReaderWriterLockSlim`)来提高并发性能。
4. **定时任务**:可以使用 `System.Threading.Timer` 或 `Task.Delay` 来定期触发 `CleanupExpiredItems` 方法。
---
### 示例代码框架:
以下是一个简单的代码框架,供参考:
```csharp
using System;
using System.Collections.Concurrent;
using System.Threading;
public class ThreadSafeCache
{
private readonly ConcurrentDictionary
private readonly Timer _cleanupTimer;
public ThreadSafeCache(int cleanupIntervalInSeconds)
{
_cleanupTimer = new Timer(CleanupExpiredItems, null, TimeSpan.Zero, TimeSpan.FromSeconds(cleanupIntervalInSeconds));
}
public void Add(string key, T value, int expirationInSeconds)
{
var expirationTime = DateTime.UtcNow.AddSeconds(expirationInSeconds);
var cacheItem = new CacheItem
_cache[key] = cacheItem; // 使用 TryAdd 或 AddOrUpdate 根据需求
}
public T Get(string key)
{
if (_cache.TryGetValue(key, out var cacheItem) && cacheItem.ExpirationTime > DateTime.UtcNow)
{
return cacheItem.Value;
}
return default(T); // 返回默认值
}
public void Remove(string key)
{
_cache.TryRemove(key, out _);
}
private void CleanupExpiredItems(object state)
{
var keysToRemove = new List
foreach (var kvp in _cache)
{
if (kvp.Value.ExpirationTime <= DateTime.UtcNow)
{
keysToRemove.Add(kvp.Key);
}
}
foreach (var key in keysToRemove)
{
_cache.TryRemove(key, out _);
}
}
private class CacheItem
{
public TValue Value { get; set; }
public DateTime ExpirationTime { get; set; }
}
}
```
---
### 扩展问题:
1. 如果缓存项的数量非常大(例如百万级别),如何进一步优化性能?
2. 如何处理高并发场景下的内存占用问题?
3. 是否可以引入异步方法来进一步提升性能?
希望这道题目能够挑战你的 C# 编程能力和并发编程思维!
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
精华推荐