TikTok 面试真题:设计一个高并发线程安全资源管理器 – 面试辅助 – 代面试 – 一亩三分地 – VO help

这是一道 TikTok 面试中出现的系统设计 / Coding Design 类题目。题目看起来只有一句话,但实际上同时覆盖了并发控制、任务调度、缓存、取消机制以及事件通知,需要候选人在较短时间内快速拆解需求,并给出一个能够实际落地的设计。

英文原题

Design a thread-safe resource manager that prioritizes, loads, cancels, caches, and notifies multiple component requests efficiently under high concurrency.

设计一个线程安全的资源管理器,在高并发环境下,高效处理多个组件发起的资源请求,并支持优先级、加载、取消、缓存以及通知

这道题真正考什么?

这类题最容易犯的错误,是看到 thread-safe 就立刻开始加 Lock。

实际上,锁只是其中很小的一部分。

面试官真正想看的,是候选人能不能先把整个系统拆成几个清晰的职责:

Request → Scheduling → Loading → Cache → Notification

例如,不同 Component 可能同时请求同一个 Resource:

Component A ──┐
Component B ──┼──> Resource Manager ──> Loader
Component C ──┘

这时候就会出现第一个关键问题:

如果 A、B、C 请求的是同一个资源,是否真的需要启动三次加载?

显然不应该。

一个比较合理的设计,是维护一个 in-flight request registry

第一次请求到来时创建真正的加载任务,后续相同资源的请求只需要注册成为 subscriber:

Resource X

A ──┐
B ──┼──> One Loading Task
C ──┘

加载完成以后,再统一通知所有仍然有效的调用方。

Priority 怎么处理?

题目中特别强调了 prioritizes

因此简单的 FIFO Queue 通常不够。

可以考虑:

Priority Queue
    ↓
Worker Pool
    ↓
Resource Loader

例如:

HIGH    UI 当前立即需要
MEDIUM  即将展示
LOW     Prefetch

Scheduler 根据 priority 选择下一个任务。

但是这里还有一个面试中很值得讨论的问题:

如果一个 LOW priority 的资源正在等待,此时另一个 Component 对同一个资源发出了 HIGH priority 请求怎么办?

好的设计不应该创建第二个任务,而应该考虑将已有任务的 effective priority 提升。

这也是这道题从普通 Coding 题进入系统设计思维的地方。

Cancel 并不是简单删除任务

取消也是这道题非常容易踩坑的部分。

假设:

A ──┐
B ──┼──> Resource X
C ──┘

现在 A cancel 了请求。

这并不代表 Resource X 的加载应该被取消,因为 B 和 C 仍然需要这个资源。

因此 Cancel 更合理的粒度是:

取消 subscriber,而不是直接取消 shared loading task。

只有当:

subscriber count == 0

并且加载任务本身允许取消时,才真正停止底层资源加载。

否则一个 Component 的取消操作可能会影响其他 Component。

Cache 又带来了新的并发问题

Resource Manager 一般还会维护 Cache:

Request
   ↓
Cache Hit? ── Yes ──> Return
   │
   No
   ↓
Check In-flight Request
   ↓
Schedule Loading

这里至少需要考虑:

  • 多线程同时读取 Cache
  • Cache miss 后重复创建任务
  • Cache eviction
  • Resource loading 完成与 cancel 同时发生
  • Cache update 和 subscriber notification 的顺序

所以这道题真正困难的地方,并不是写一个 Dictionary,而是保证整个状态转换在并发情况下仍然一致。

Notification 怎么设计?

资源加载完成以后,还需要通知所有请求它的 Component。

这里通常可以设计成 callback / future / promise / event listener。

例如:

Resource Loaded
      ↓
Update Cache
      ↓
Remove In-flight Task
      ↓
Notify Subscribers

同时还要注意:

不要在持有核心 Lock 的情况下执行用户 callback。

因为 callback 本身可能:

  • 执行很慢
  • 再次请求 Resource Manager
  • acquire 其他 lock
  • 触发新的 callback

如果直接在锁内部执行,很容易造成严重的 contention,甚至 deadlock。

更安全的方式通常是:

先在锁内更新共享状态并复制 subscriber 列表,然后释放锁,再执行 notification。

面试中最值得讲清楚的几个点

这道题如果只写出一个能运行的 ResourceManager,通常还不够。

真正拉开差距的是候选人能不能主动讨论:

同一资源请求如何去重

Priority 是否可以动态提升

多个 subscriber 中一个取消怎么办

什么时候真正取消底层加载

Cache 和 in-flight request 如何保证原子性

Callback 是否可以在 Lock 内执行

高并发下如何减少锁竞争

异常加载之后如何通知多个调用方

这些才是面试官继续追问的地方。


这种题的难点,也正是技术面试里最容易出现的情况:

题目本身不长,但隐藏条件很多。

候选人不仅要写代码,还要一边和面试官沟通,一边判断:

面试官现在更关心线程安全吗?
还是 Priority Queue?
还是取消语义?
为什么突然开始追问 cache?
下一步应该先写代码还是先解释架构?

这也是 csoahelp 实时文本面试辅助比较适合发挥作用的场景。

我们可以在面试过程中根据面试官的问题实时分析当前考察点,帮助候选人快速整理:

需求拆解 → 数据结构 → 并发模型 → Edge Case → Follow-up

特别是这种 System Design + Coding 混合题,很多时候并不是候选人完全不会,而是现场几十秒内很难把所有并发场景同时考虑完整。

除了正式面试中的实时文本辅助,我们也提供 Mock Interview,可以针对 TikTok、Google、Meta、Amazon 等公司的 Coding / System Design 风格提前模拟追问,把这种「第一问很简单,后面不断加条件」的面试节奏提前练熟。

我们也有代面试,面试辅助,OA代写等服务助您早日上岸~

Leave a Reply

Your email address will not be published. Required fields are marked *