OpenAI 面试题:15 分钟窗口内的聊天交互统计与 active session 设计 – 面试代面 – VO 辅助 – OA 代写

这次 OpenAI 面试题是一个偏工程设计的数据结构题。题目背景是:系统里不断产生 ChatGPT chat session 的交互日志,现在要做一个 in-memory analytics service,实时统计最近 15 分钟内某个 chat 的 interaction 数量。

面试开始后,面试官先给了第一部分题目:

user_id: str
chat_id: int
timestamp: int

需要实现:

process_event(user_id: str, chat_id: int, timestamp: int)

get_num_recent_interactions(user_id: str, chat_id: int) -> int

这里的 recent 指的是全局最新时间 T 下的 [T-14, T]。比如当前系统见过的最大 timestamp 是 20,那么最近 15 分钟就是 6 到 20。

候选人一开始先确认了几个细节:timestamp 是全局非递减的,chat_id 是 user 内唯一,query 也按照目前系统已经见过的最大 timestamp 来算。这个确认很重要,因为后面能不能用 queue 清理窗口,基本就靠这个条件。

我们的辅助思路是让候选人不要把所有历史事件都存下来,而是只维护当前窗口。具体做法是:

一个 global deque,保存最近 15 分钟内的事件
一个 hash map,记录每个 (user_id, chat_id) 当前窗口内的 interaction 数量

每次新的 event 进来,先加入 deque,再把对应 chat 的 count 加一。然后根据当前全局时间 T,从 deque 左边清理所有过期事件:

timestamp < T - 14

被清理的事件,对应的 count 减一。如果减到 0,就把这个 key 从 map 里删掉。

这样 query 的时候就很简单,直接返回:

count[(user_id, chat_id)]

面试中候选人基本按这个方向解释:因为事件时间是非递减的,所以旧事件一定在队列左边,清理窗口不需要全表扫描。每个事件只会进队一次、出队一次,所以 process_event 是摊还 O(1),查询是 O(1),内存也只和最近 15 分钟的事件有关。

第二部分题目加了一个字段:

event_type: str

有两种类型:

interact: 用户发送消息并收到回复
end: 用户主动结束 chat session

现在要支持:

get_active_session_count(user_id: str) -> int

一个 session 算 active,需要满足:

最近 15 分钟内有 interact
并且最新一次 interact 之后没有 end

这里有个容易错的点:end 不是永久结束这个 chat。如果后面又来了新的 interact,这个 session 又会重新变成 active。

我们在辅助时让候选人把状态拆得更清楚一点。对每个 (user_id, chat_id) 维护:

latest_interact_time
ended_after_latest_interact
is_active

同时再维护一个:

user_id -> active session count

当收到 interact 时,如果这个 chat 原来不是 active,现在就把这个 user 的 active count 加一,然后更新 latest interact,并把 ended 状态清掉。

当收到 end 时,如果这个 chat 当前是 active,就把 active count 减一,然后标记它已经 ended。

为了处理 15 分钟过期,还是需要一个 queue 保存 interact 事件。清理旧 interact 的时候不能直接把 session 关掉,因为这个 chat 后面可能已经有新的 interact。只有当被清理的 timestamp 仍然等于这个 chat 的 latest_interact_time,才说明它真的过期了。

面试里可以用这个例子解释:

process_event("u1", 1, 0, "interact")
get_active_session_count("u1") -> 1

process_event("u1", 1, 5, "end")
get_active_session_count("u1") -> 0

process_event("u1", 1, 8, "interact")
get_active_session_count("u1") -> 1

因为 8 这次 interact 发生在 end 之后,所以 session 又重新 active。

这道题整体不算特别偏算法,更像 OpenAI 常见的实时系统数据结构题。面试时如果能抓住“全局 timestamp 非递减”和“只能保留 active window”这两个限制,基本方向就比较清楚了。

我们这边辅助候选人时,主要是帮他把思路压成面试官容易接受的表达:第一部分用 sliding window queue 加 count map,第二部分在此基础上加 per-chat state 和 per-user active count。代码实现不需要特别花哨,重点是边界条件讲清楚,尤其是 [T-14, T] 的闭区间、end 之后再次 interact 重新 active、旧 interact 过期时不能误删新状态。

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

Leave a Reply

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