Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-19 14:32:24

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涉及 **多线程、异步编程、锁机制、委托与事件** 等多个高级知识点,考察候选人对底层机制和并发编程的理解。

---

### 🧠 面试题:并发控制与事件通知的陷阱

#### 背景描述:

你正在开发一个多线程任务调度系统,其中多个线程会并发地访问一个共享资源 `SharedResource`。你希望实现一个 `ResourceMonitor` 类,它监控资源的访问并提供事件通知机制。当资源被访问时,它会触发一个事件,但你希望确保:

1. **事件通知必须在主线程中执行**(假设主线程是一个 UI 线程)。
2. **资源访问必须是线程安全的**,使用最小粒度的锁。
3. **事件不能丢失**,即使在资源被频繁访问的情况下。

---

#### 问题描述:

请实现以下类结构:

```csharp
public class SharedResource
{
public int Value { get; set; }
}

public class ResourceMonitor
{
public event EventHandler ResourceAccessed;

public SharedResource GetResource()
{
// TODO: 实现线程安全的访问逻辑
}

public void SetResource(int value)
{
// TODO: 实现线程安全的设置逻辑
}
}

public class ResourceAccessEventArgs : EventArgs
{
public int NewValue { get; }

public ResourceAccessEventArgs(int newValue)
{
NewValue = newValue;
}
}
```

---

#### 要求:

1. 实现 `GetResource()` 和 `SetResource()` 方法,确保共享资源的线程安全。
2. 每当资源被设置(`SetResource` 被调用)时,触发 `ResourceAccessed` 事件。
3. **事件必须在主线程中执行**,即使设置资源的是后台线程。
4. **不允许使用 `async/await`**(即不使用基于任务的异步模式)。
5. **不要使用 `Invoke` 或 `BeginInvoke`**(假设没有 `Control` 类型或 UI 上下文)。

---

#### 候选人需要思考的问题点:

- 如何确保线程安全?(使用什么锁?`lock`, `ReaderWriterLockSlim`, `Interlocked`?)
- 如何在非 UI 线程中发布事件,并调度到主线程?
- 如何避免事件丢失?(是否需要队列?)
- 是否需要使用同步上下文(`SynchronizationContext`)?
- 如何模拟主线程?

---

### ✅ 示例答案(部分)

```csharp
public class ResourceMonitor
{
private readonly object _lock = new object();
private SharedResource _resource = new SharedResource();
private readonly SynchronizationContext _uiContext;

public ResourceMonitor(SynchronizationContext uiContext)
{
_uiContext = uiContext ?? throw new ArgumentNullException(nameof(uiContext));
}

public event EventHandler ResourceAccessed;

public SharedResource GetResource()
{
lock (_lock)
{
return new SharedResource { Value = _resource.Value };
}
}

public void SetResource(int value)
{
SharedResource updatedResource = null;

lock (_lock)
{
if (_resource.Value != value)
{
_resource = new SharedResource { Value = value };
updatedResource = _resource;
}
}

if (updatedResource != null)
{
var handler = ResourceAccessed;
if (handler != null)
{
// Post 到主线程执行事件
_uiContext.Post(_ =>
{
handler(this, new ResourceAccessEventArgs(updatedResource.Value));
}, null);
}
}
}
}
```

---

### 🧪 测试场景(可选扩展):

你可以要求候选人编写一个测试程序,模拟多个线程频繁调用 `SetResource`,并在主线程监听事件,并验证事件是否都在主线程执行,且资源访问是线程安全的。

---

### 📌 考察点总结:

| 技术点 | 是否考察 |
|--------|----------|
| 多线程与锁机制 | ✅ |
| 事件与委托 | ✅ |
| 同步上下文(SynchronizationContext) | ✅ |
| 线程安全资源访问 | ✅ |
| 异步通信机制 | ✅ |
| 架构设计能力 | ✅ |

---

如果你需要更多类似级别的题目(比如涉及表达式树、反射、内存模型、TPL、TPL Dataflow、C# 10+ 特性等),我也可以继续出题。是否需要?

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

上一篇: c#题例-2025-07-19 21:18:26

下一篇: c#题例-2025-07-19 08:58:55

精华推荐