SEO Title:
Optiver SquirrelResearch 面试题2026:OA 难题全流程拆解与高分策略
Optiver SquirrelResearch 面试题2026 是 2026 年最新高压 OA 题。
因此,这题不能只靠模板记忆。
你必须先建清晰状态机。
这是我们学员贡献的最新面经。
此外,这题同时考实现和稳定性。
你要处理初始化、入库、出库。
与此同时,你还要处理过期和回填。
换句话说,这是一道规则工程题。
2026 面试流程深度复盘:Optiver SquirrelResearch 面试题2026
首先,线上环节会先给一段长规则。
但是,很多人会漏掉失败条件。
因此,第一步是先画失败清单。
Optiver SquirrelResearch 面试题2026 常在此处拉开差距。
其次,编码一般分三段推进。
先写 init(locations)。
随后写 HideNut 的合法性校验。
最后写 RetrieveNuts 的取出策略。
此外,时间语义是核心扣分点。
timestamp + TTL 到点即过期。
因此,取出前必须先清过期。
过期删除后,nut_id 必须可复用。
与此同时,部分场次有反应力测试。
典型形式是 zap n 即时操作。
因此,手速和心态都被考察。
总而言之,Optiver SquirrelResearch 面试题2026 不只考算法。
核心题目解析
具体来说,系统可拆成三层状态。
全局层管时间和 nut_id 唯一性。
地点层管多层容量。
层结构管排序和回填。
因此,容量建议用斐波那契扩展。
三层可设为 1/2/3。
四层可扩为 1/2/3/5。
Optiver SquirrelResearch 面试题2026 常追问这里。
此外,规则可以归纳为以下不变量。
– init(locations):按地点初始化层数与容量。
– HideNut:非法地点、重复 ID、容量满都返回 False。
– HideNut:按“由深到浅”找首个可用层写入。
– RetrieveNuts:非法地点或空地点返回空列表。
– RetrieveNuts:先算可达层,再做“更重优先”。
– RetrieveNuts:同重按 nut_id 字典序。
– 访问下一层条件:上一层占用率 < 50%。
– 非顶层取走后:上层最轻坚果下落补位。
System Design 流程图
Python 参考实现(可直接改造成面试答案)
from dataclasses import dataclass
from typing import Dict, List, Optional, Tuple
import heapq
@dataclass
class Nut:
nut_id: str
weight: int
expire_at: float
location_id: str
layer: int # 0 是最上层
class Layer:
def __init__(self, cap: int) -> None:
self.cap = cap
self.ids = set()
self.max_heap: List[Tuple[int, str]] = [] # (-weight, nut_id)
self.min_heap: List[Tuple[int, str]] = [] # (weight, nut_id)
def size(self) -> int:
return len(self.ids)
def has_space(self) -> bool:
return self.size() < self.cap
def occupancy(self) -> float:
return self.size() / self.cap if self.cap else 1.0
def add(self, nut_id: str, weight: int) -> None:
self.ids.add(nut_id)
heapq.heappush(self.max_heap, (-weight, nut_id))
heapq.heappush(self.min_heap, (weight, nut_id))
def remove(self, nut_id: str) -> None:
self.ids.discard(nut_id) # 惰性删除,堆内脏数据稍后清理
def _clean_max(self) -> None:
while self.max_heap and self.max_heap[0][1] not in self.ids:
heapq.heappop(self.max_heap)
def _clean_min(self) -> None:
while self.min_heap and self.min_heap[0][1] not in self.ids:
heapq.heappop(self.min_heap)
def peek_heaviest(self) -> Optional[str]:
self._clean_max()
return self.max_heap[0][1] if self.max_heap else None
def pop_lightest(self) -> Optional[str]:
self._clean_min()
if not self.min_heap:
return None
_, nut_id = heapq.heappop(self.min_heap)
self.ids.remove(nut_id)
return nut_id
class SquirrelResearch:
def __init__(self) -> None:
self.locations: Dict[str, List[Layer]] = {}
self.nuts: Dict[str, Nut] = {}
self.expiry_heap: List[Tuple[float, str]] = []
self.last_ts = float("-inf")
def init(self, locations: Dict[str, int]) -> None:
self.locations.clear()
self.nuts.clear()
self.expiry_heap.clear()
self.last_ts = float("-inf")
for loc_id, levels in locations.items():
caps = self._fib_caps(levels)
self.locations[loc_id] = [Layer(c) for c in caps]
def HideNut(
self,
timestamp: float,
location_id: str,
nut_id: str,
nut_weight: int,
time_to_expire: float
) -> bool:
if not self._tick(timestamp):
return False
layers = self.locations.get(location_id)
if layers is None or nut_id in self.nuts:
return False
target = -1
for i in range(len(layers) - 1, -1, -1): # 深到浅
if layers[i].has_space():
target = i
break
if target < 0:
return False
exp = timestamp + time_to_expire
self.nuts[nut_id] = Nut(nut_id, nut_weight, exp, location_id, target)
layers[target].add(nut_id, nut_weight)
heapq.heappush(self.expiry_heap, (exp, nut_id))
return True
def RetrieveNuts(
self,
timestamp: float,
location_id: str,
max_squirrel_capacity_in_nuts: int
) -> List[str]:
if not self._tick(timestamp):
return []
layers = self.locations.get(location_id)
if layers is None or max_squirrel_capacity_in_nuts <= 0:
return []
if sum(layer.size() for layer in layers) == 0:
return []
ans: List[str] = []
while len(ans) < max_squirrel_capacity_in_nuts:
reachable = self._reachable_layers(layers)
pick = self._pick_best(layers, reachable)
if pick is None:
break
nut_id, layer_idx = pick
self._remove_nut(nut_id, with_backfill=True)
ans.append(nut_id)
return ans
def _fib_caps(self, levels: int) -> List[int]:
if levels <= 0:
return []
caps = [1]
if levels == 1:
return caps
caps.append(2)
for _ in range(2, levels):
caps.append(caps[-1] + caps[-2])
return caps
def _tick(self, ts: float) -> bool:
if ts <= self.last_ts: # 全局递增
return False
self.last_ts = ts
self._purge_expired(ts)
return True
def _purge_expired(self, ts: float) -> None:
while self.expiry_heap and self.expiry_heap[0][0] <= ts:
exp, nut_id = heapq.heappop(self.expiry_heap)
nut = self.nuts.get(nut_id)
if not nut or nut.expire_at != exp:
continue
self._remove_nut(nut_id, with_backfill=True)
def _reachable_layers(self, layers: List[Layer]) -> List[int]:
if not layers:
return []
r = [0]
for i in range(len(layers) - 1):
if layers[i].occupancy() < 0.5:
r.append(i + 1)
else:
break
return r
def _pick_best(
self,
layers: List[Layer],
reachable: List[int]
) -> Optional[Tuple[str, int]]:
# 跨层比较:更重优先;同重按 nut_id 字典序
best_id = None
best_layer = -1
best_weight = None
for idx in reachable:
nid = layers[idx].peek_heaviest()
if nid is None:
continue
nut = self.nuts[nid]
if (
best_id is None
or nut.weight > best_weight
or (nut.weight == best_weight and nid < best_id)
):
best_id = nid
best_weight = nut.weight
best_layer = idx
return None if best_id is None else (best_id, best_layer)
def _remove_nut(self, nut_id: str, with_backfill: bool) -> None:
nut = self.nuts.pop(nut_id, None)
if nut is None:
return
layers = self.locations[nut.location_id]
layers[nut.layer].remove(nut_id)
if with_backfill and nut.layer > 0:
self._backfill(nut.location_id, nut.layer)
def _backfill(self, location_id: str, hole_layer: int) -> None:
# 从 hole_layer 上方逐层取最轻下落,形成连锁补位
layers = self.locations[location_id]
for upper in range(hole_layer - 1, -1, -1):
moved_id = layers[upper].pop_lightest()
if moved_id is None:
break
moved_nut = self.nuts[moved_id]
layers[upper + 1].add(moved_id, moved_nut.weight)
moved_nut.layer = upper + 1
此外,这份实现的关键复杂度很稳。
HideNut 主要是堆操作,接近 O(log N)。RetrieveNuts 每次取出也以堆操作为主。因此,在大
N 与大 Q 下更安全。
BQ:核心考点
- 因此,先看你能否把长规则抽成不变量。
- 此外,看你是否能识别全部失败路径。
- 但是,也会看你如何解释时间和过期语义。
- 与此同时,还会看你如何压复杂度。
- 换句话说,代码正确只是及格线。
BQ:STAR 应对策略
S:因此先说场景。规则多且易错。T:随后说任务。要做高一致性模拟器。A:此外说行动。状态机+堆+哈希+惰性删除。R:最后说结果。复杂度可控,边界全覆盖。
专家备考策略与高频考点:Optiver SquirrelResearch 面试题2026
因此,备考 Optiver SquirrelResearch 面试题2026 时,先写断言表。
把非法地点、重复 ID、容量溢出先列完。
随后再写主流程。
这样能明显降低返工率。
此外,第二步是做专项压测。
你要造过期、回填、同重 ID 冲突样例。
与此同时,专测时间戳递增约束。
Optiver SquirrelResearch 面试题2026 很爱考这三类。
但是,表达顺序同样关键。
先讲模型,再讲不变量。
然后讲复杂度与可扩展点。
面试官会更快确认你的工程能力。
具体来说,可先看 权威算法参考。
如果你要实战演练,可 联系我们的专家进行一对一面试辅导。
🎯 面试代面 / OA辅助 — 前大厂工程师团队帮你上岸
正在为技术面试发愁?我们的北美大厂工程师团队提供专业辅导和辅助服务:
- OA代做 — HackerRank / CodeSignal / LeetCode 等全平台覆盖,保证通过
- 视频代面 — Google / Meta / Amazon 等主流平台,真实面试官在线
- 模拟面试 — 1对1真实场景还原,详细反馈与改进建议
- 简历优化 — 北美大厂HR背景,帮你打造高通过率简历
📱 微信: leetcode-king(添加请备注”面试”,回复更快)
💬 Telegram: @ayinterview(24小时在线)
⚡ 紧急面试可加急,30分钟内安排工程师对接
🚀 需要面试辅导?立即联系我们
✅ 前大厂工程师团队 · 一对一辅导 · 真实案例 · 保密协议
微信: leetcode-king | Telegram: @ayinterview
💼 北美科技大厂面试 · 面试代面 · OA辅助 · VO辅助