19861 字
99 分钟
2026-11-04 AI Agent 面试训练
AI Agent 面试训练
2026-11-04

2026-11-04 AI Agent 面试训练#

今日学习主题#

驻留与生效的分离:为留着的状态付费,为生效的状态负责

今天的五道题都在问同一件事——系统里”留着的东西”和”此刻真正起作用的东西”不是同一份。副本里留着旧版本,quorum 决定哪一份生效;模型显存里留着全部专家,每个 token 只激活两个;Agent 手里留着用户令牌,下游据以鉴权的却是另一个身份;一个没提交的事务让整张表的旧行版本继续”可见”,VACUUM 迟迟收不回;滑动窗口里留着一串候选下标,只有两个队首决定窗口能否继续向右。共同结论是:不要只盯着生效的那一份,必须为驻留的部分单独建账——它的容量成本、回收责任与撤销路径,才是故障时真正决定系统行为的地方。

  • B01:R + W > N 成立的前提是读写落在同一组固定的 N 个副本上,故障期的 sloppy quorum 会让交集消失。
  • B02:MoE 的标称参数与激活参数分离,显存按驻留算、算力按激活算,两笔账不能互相代入。
  • S01:Agent 代持令牌时,委托链与下游鉴权对象分离,审计必须回答”谁授权、谁执行、谁生效”。
  • S02:idle-in-transaction 让旧快照持续生效,回收责任落在事务边界与超时策略,而不是 VACUUM 的勤奋程度。
  • L01:两个单调队列各自驻留候选,只有队首生效,出窗即回收。

题目速览#

编号题目 ID题目名称题型一级类型难度一句话考察点
B01Q-20261104-B01R + W > N 就能保证强一致吗:Quorum 读写的成立条件与失效边界非 Agent 基础分布式系统基础题(中高)N/R/W 的隐含前提、sloppy quorum 打破交集、读修复与反熵的归属,以及与共识的区别
B02Q-20261104-B0247B 的模型每个 token 只用了 13B:MoE 的驻留参数与激活参数Agent 基础AI 与大模型基础基础题(中高)稀疏激活的定义与边界、两笔容量账、专家路由与负载倾斜、与量化/蒸馏/集成的区别
S01Q-20261104-S01工单被改了,审计里只有 Agent:代持令牌下的身份传播与责任归属Agent 场景AI 安全与治理(兼工具与互操作协议)场景题(高)delegation vs impersonation、act 链的访问控制边界、交集授权、撤销不自动传播
S02Q-20261104-S02报表任务开着事务不提交,全表查询慢了 6 倍:长事务与 MVCC 膨胀非 Agent 场景数据库与存储(兼分布式系统)场景题(高)快照使死元组持续可见、autovacuum 不是回收保证、超时策略与 hot_standby_feedback 的取舍
L01Q-20261104-L011438. 绝对差不超过限制的最长连续子数组LeetCode数组与字符串(双单调队列 / 滑动窗口)medium(未直接核验)把任意两元素差转成窗口 max − min,用两个单调队列 O(n) 维护并支持左侧删除

B01 · 非 Agent 基础题#

题目 ID:Q-20261104-B01
一级类型:分布式系统
二级主题:Quorum 读写与可调一致性(N/R/W、sloppy quorum、读修复与反熵、与共识的区别)
标签:Quorum、最终一致、sloppy-quorum、向量时钟、共识

题目#

一个分布式 KV 存储配置为 N = 3, R = 2, W = 2。设计文档里写着:“R + W > N,因此读写参与的副本集合必然相交,读一定能看到最新写。” 上线后出现两类问题:

  1. 一次机房网络分区期间,写入返回成功,随后的读取仍返回旧值。
  2. 两个客户端并发修改同一个 key,两次写入都返回成功;之后读取拿到两个版本,应用随手挑了一个,丢了一次更新。

请回答:

  1. N、R、W 各自的定义是什么?R + W > N 在 Dynamo 原文里如何表述?它成立依赖哪些隐含前提?
  2. 分别解释两类现象的机制,说明为什么 R + W > N 推不出”读一定看到最新写”。
  3. 这类系统与 Raft / Paxos 这类共识系统在”谁能裁决顺序”上的区别是什么?若业务确实需要线性一致读,有哪些可选路径及代价?

先思考#

  • 先别急着算交集:读写参与的副本集合,是”固定的那 N 个”,还是”当时能连上的 N 个健康节点”?
  • 再问”最新”由谁定义:两次并发写没有先后时,系统靠什么决定谁覆盖谁?
  • 然后想交集到底保证了什么:它保证的是节点集合相交,还是读到的那个值一定最新?
  • 最后想顺序:如果所有写必须有一个全局次序,由谁分配这个次序,代价落在哪里?

参考答案#

结论:R + W > N 只在”读写作用于同一组固定的 N 个副本、写串行且无并发冲突”的前提下构成 quorum-like 系统;Dynamo 类系统为可用性主动放弃严格成员,交集不再保证,且并发写会产生多个版本。它提供的是最终一致与可调的 (N, R, W) 取舍,不是线性一致性。

准确定义(依据 Amazon Dynamo 论文原文):

  • §4.3:Each data item is replicated at N hosts, where N is a parameter configured "per-instance".
  • §4.5:R is the minimum number of nodes that must participate in a successful read operation.;W is the minimum number of nodes that must participate in a successful write operation.
  • §4.5:To maintain consistency among its replicas, Dynamo uses a consistency protocol similar to those used in quorum systems.;Setting R and W such that R + W > N yields a quorum-like system. 注意原文用词是 quorum-like,不是 linearizable。
  • §6:The common (N,R,W) configuration used by several instances of Dynamo is (3,2,2).

适用边界:R + W > N 的集合相交论证依赖四个隐含前提,Dynamo 至少主动放弃了其中两个:

  1. 严格成员:读写必须落在同一组 N 个副本上。§4.6 明确 it does not enforce strict quorum membership and instead it uses a "sloppy quorum"; all read and write operations are performed on the first N healthy nodes from the preference list, which may not always be the first N nodes encountered while walking the consistent hashing ring. 分区时写会带 hint 落到替代节点(hinted handoff),读落在另一批健康节点,两个集合可以完全不相交。
  2. 写成功即已落 W 份且无并发分支:§4.5 If at least W-1 nodes respond then the write is considered successful.;§4.4 A put() call may return to its caller before the update has been applied at all the replicas, which can result in scenarios where a subsequent get() operation may return an object that does not have the latest updates. 返回成功不等于 N 份落盘。
  3. 写之间存在全序:§4.4 每次修改都产生新的不可变版本,version branching may happen, in the presence of failures combined with concurrent updates, resulting in conflicting versions of an object。系统用向量时钟判因果,无法 syntactic reconciliation 时交给客户端做 semantic reconciliation。没有全序,“最新”一词本身就没有定义。
  4. 版本判据可靠:§6 提到某些实例由 Dynamo 自身执行 timestamp based reconciliation logic of "last write wins",物理时钟与并发写叠加时会静默丢写。

两类现象的机制:

  • 现象 ①:§4.6 的例子是 A 临时不可达时,本该落在 A 的副本改发到 D,D 保留带 hint 的副本并周期性扫描,A 恢复后才回传;Using hinted handoff, Dynamo ensures that the read and write operations are not failed due to temporary node or network failures. 这是 §2.3 明确的设计目标 an "always writeable" data store 与 This requirement forces us to push the complexity of conflict resolution to the reads in order to ensure that writes are never rejected. 的必然代价,不是实现 bug。
  • 现象 ②:§4.5 If the coordinator ends up gathering multiple versions of the data, it returns all the versions it deems to be causally unrelated. 应用”随手挑一个”等于主动丢弃另一分支。购物车语义可以 merge(§2.3 原文举例),但计数器、余额、幂等键这类不可合并语义必须换方案,否则就是丢写。

简洁示例:N=3, R=2, W=2,正常时写 {A,B}、读 {A,C} 必相交于 A,因此至少能看到 A 上那份值。若分区把节点切成 {A,B} 与 {C,D} 两侧,写侧的前 N 个健康节点是 {C,D}(其中 D 是 hinted 临时节点),读侧是 {A,B}——两个集合不相交,读到的仍是旧值。这解释了现象 ①:R + W > N 的算术没错,错在参与集合已经不是同一组 N。

与相近概念的区别:

对比前者后者
quorum-like(Dynamo) vs 共识(Raft / Paxos)无全局次序,允许并发分支,优先可用性由 leader / 提案分配全序,写入需多数派提交,可提供线性一致
R + W > N vs 线性一致读只保证健康、串行、固定成员下集合相交要求读看到所有已完成写,需要全序与提交判定
strict quorum vs sloppy quorum成员固定,故障时宁可拒绝服务成员随健康状态漂移,用 hinted handoff 保可用
read repair / anti-entropy vs 一致性来源事后收敛:§5 repairs replicas that have missed a recent update at an opportunistic time;§4.7 用 Merkle tree 后台同步 divergent replicas读路径上的保证,必须在返回结果前生效
LWW vs 向量时钟语义合并按时间戳取一个,静默丢分支保留 causally unrelated 的多个版本,交业务裁决

典型应用(通用工程):

  • 购物车、会话、计数近似值、可合并配置等可容忍陈旧且冲突可合并的场景,适合可调 (N,R,W)。§6 指出 if W is set to 1, then the system will never reject a write request as long as there is at least one node in the system...,但紧接着警告 This also introduces a vulnerability window for durability when a write request is successfully returned to the client even though it has been persisted at only a small number of nodes.
  • 余额、库存、唯一约束、幂等键等不可丢写的场景,必须走共识或单主 + 确定性版本(CAS / 版本号),并在接口上显式声明一致性级别,不能靠调 W 蒙混。
  • 容量与延迟:§4.5 the latency of a get (or put) operation is dictated by the slowest of the R (or W) replicas,因此监控要看”参与副本里最慢的那个分位”,而非平均延迟;§6 把 (N,R,W) 定位为 tune ... to achieve their desired levels of performance, availability and durability 的 SLA 旋钮,不是”提高一致性等级”的旋钮。
  • 若必须线性一致读:把写放进共识组由 leader 分配全序,读走 leader(ReadIndex / lease read,后者依赖时钟假设);或让该 key 走单主 + 同步复制。代价是分区期间不可写、读延迟升高、leader 成为热点。

面试现场回答(1–2 分钟版本):

R + W > N 出自 Dynamo 论文 §4.5,原话是 “yields a quorum-like system”,注意是 quorum-like。它成立的隐含前提有三个:读写落在同一组固定的 N 个副本上;写成功意味着已落 W 份且没有并发分支;“最新”有一个全序可判。Dynamo 为了 “always writeable” 主动放弃了第一个前提——§4.6 明确用 sloppy quorum,读写取 preference list 的前 N 个健康节点,分区时写会带 hint 落到临时节点,读可能落在另一批节点上,集合可以不相交,所以现象 ① 是设计取舍不是 bug。现象 ② 是并发写:每次修改是一个新版本,版本分支用向量时钟判因果,无法自动合并的交应用语义合并;应用随手挑一个就是丢写,论文把冲突解决推到读侧是有意的设计。

要真正的线性一致,必须把写放进共识组由 leader 分配全序,读走 leader 或做带版本校验的读,代价是分区时不可写、延迟上升。所以我的结论是:R + W > N 只保证”健康、串行、固定成员”下集合相交,它是可用性与持久性的调参,不是一致性保证。

关键点#

  1. quorum-like ≠ 线性一致:原文用词与 §2.3 的 “always writeable” 目标共同决定了它是最终一致系统。
  2. sloppy quorum 打破交集:故障期成员可变,hinted handoff 让写落到非首选节点,读可能落在另一批节点。
  3. 写成功 ≠ N 份已落盘,且并发写产生分支;向量时钟判因果,语义合并交业务,LWW 会静默丢写。
  4. read repair 与 anti-entropy(Merkle tree)是收敛机制,不是读路径上的一致性来源。
  5. 延迟由 R / W 中最慢副本决定;调 (N,R,W) 是在性能、可用性、持久性之间交换,不是提高一致性等级的旋钮。

常见误区#

  1. 把 R + W > N 当成”读一定看到最新写”。错误原因:忽略成员可变与并发分支,且”最新”需要全序。§4.5 只说 quorum-like,§4.6 明确不强制严格成员。
  2. 认为把 W 调大就线性一致。错误原因:W 只影响写参与度与 §6 所说的 durability “vulnerability window”,既不解决并发写次序,也不解决 sloppy quorum 成员漂移。
  3. 认为做了 read repair 就能收敛到唯一正确值。错误原因:read repair 只在被读到的 key 上机会性修复,未读 key 靠 anti-entropy 后台同步;并发写下”唯一正确值”可能不存在,交给 LWW 就是丢写。

追问#

追问:如果业务要求”读己之所写”,在 Dynamo 类系统上最小改动是什么?

回答要点:

  • 把会话级保证与全局一致分开:让用户会话绑定到同一个协调者,或把该读请求定向到参与过该写的节点集合,并携带写返回的版本上下文(§4.4 要求更新时带上从先前读到的 context)。
  • 读侧做版本比较:读 R 个副本取向量时钟最新者;若发现 causally unrelated 的分支,应返回冲突而不是静默挑一个,这是读路径上的额外代价。
  • 明确边界:分区期间刚写入的 hinted 副本可能还没回传,仍可能读不到;若要无条件保证,必须换一致性模型或接受失败返回,不能靠调 R / W。
  • 观测:把”陈旧读”与”冲突读”分成两个指标,并监控 hinted 副本积压量与回传时延,否则修复是否生效无从判断。

延伸学习#

  • Amazon《Dynamo: Amazon’s Highly Available Key-value Store》(SOSP 2007)官方 PDF:https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf —— §2.3、§4.4–4.7、§5、§6 原文(已核验)。
  • Apache Cassandra 官方文档关于 consistency level 与 read repair 的条目(未核验本轮页面,仅作延伸方向)。

B02 · AI Agent 基础题#

题目 ID:Q-20261104-B02
一级类型:AI 与大模型基础
二级主题:MoE 与条件计算(稀疏激活、总参数量 vs 激活参数量、专家路由与容量口径)
标签:MoE、稀疏激活、专家路由、容量规划、模型选型

题目#

团队做模型选型时看到两个候选:稠密模型 A(7B 参数)与稀疏模型 B(Mixtral 8x7B,标称 47B 参数、13B 激活参数)。运维问:“B 是 47B,是不是要按 47B 准备显存,推理算力也按 47B 算?” 另一位同事说:“MoE 就是多个模型投票,效果等于 8 个 7B 集成,还更省。”

请回答:

  1. MoE / 稀疏激活的准确定义是什么?“总参数量”与”每 token 激活参数量”分别决定哪一类工程成本?
  2. 47B / 13B 是怎么来的(依据论文)?路由发生在什么粒度?“激活参数少”是否等于”延迟按 13B 算”?
  3. MoE 与量化、蒸馏、模型集成(ensemble)的区别是什么?把 MoE 模型接入 Agent 系统时,选型阶段要额外评估哪些风险?

先思考#

  • 先区分”存着”和”算着”:权重是否都要驻留显存?一次前向实际经过哪些权重?
  • 再问路由粒度:是”每个请求选一个专家”,还是”每层、每 token 各选一次”?
  • 然后想负载:如果一批请求大多路由到同一个专家,稀疏还省吗?
  • 最后问可迁移性:显存、显存带宽、批大小、跨卡通信,哪一项会因稀疏而变复杂?

参考答案#

结论:MoE 是”按输入选择不同参数”的稀疏激活模型;总参数量决定权重驻留显存、加载与跨卡通信成本,激活参数量决定单 token 的算术量,两笔账不能互相代入。把 MoE 当成模型集成,或把”13B 激活”直接当成”13B 延迟”,都会低估显存与路由开销。

准确定义(依据两篇原始论文摘要,均已核验):

  • arXiv:2101.03961《Switch Transformers》(Fedus、Zoph、Shazeer;v1 2021-01-11,v3 2022-06-16):Mixture of Experts (MoE) defies this and instead selects different parameters for each incoming example. The result is a sparsely-activated model -- with outrageous numbers of parameters -- but a constant computational cost. 同一摘要把推广障碍列为 complexity, communication costs and training instability。
  • arXiv:2401.04088《Mixtral of Experts》(Jiang 等;v1 2024-01-08):each layer is composed of 8 feedforward blocks (i.e. experts);For every token, at each layer, a router network selects two experts to process the current state and combine their outputs.;each token has access to 47B parameters, but only uses 13B active parameters during inference.

由此得到两条口径:总参数(47B) = 所有需驻留的权重;每 token 激活参数(13B) = 一次前向真正参与算术的权重。8 个专家 × 7B ≠ 56B,是因为注意力层等非专家参数在各专家间共享(论文摘要只明确专家层为 FFN,共享部分的具体构成本轮未核验正文,不展开断言)。

适用边界:

  • constant computational cost 是相对”总参数量”而言,不是相对一个同规模稠密模型。算术量由激活专家数决定,但推理延迟还取决于:① 全部专家权重仍须驻留显存(按 47B、FP16 每参数 2 字节粗算,仅权重约 94 GB,不含 KV Cache 与激活;该数值为算术推算,随精度与并行策略变化);② 路由网络有额外计算,专家并行时 token 需按路由结果跨设备分发(all-to-all);③ 批内路由分布不均会造成专家负载倾斜,一批的完成时间由最慢专家决定;④ 专家容量上限与显存碎片会影响连续批处理的效率。Switch 摘要点名的 communication costs 正是这类代价。
  • 论文中的 up to 7x increases in pre-training speed with the same computational resources 与 achieve a 4x speedup over the T5-XXL model 是训练吞吐对比,不能当作推理延迟结论引用。
  • 适用前提:显存足以容纳全部专家权重、且有办法承受路由倾斜;若部署规格只能装下一个 13B 稠密模型,MoE 再”省算力”也部署不上。

简洁示例:8 专家、每 token top-2 的模型处理 1024 个 token 的 prompt。每个 token 在每层只经过 2 个 FFN 专家,算术量约为”2/8 的 FFN + 共享主干”;但 8 个专家权重必须全部在显存里。若这批 token 有 60% 路由到专家 3,该专家所在卡成为热点,整批 completion time 被它拖住。与一个 13B 稠密模型相比,算术量可能相近,但显存占用、跨卡通信量和尾延迟方差完全不是一个量级。

与相近概念的区别:

对比前者后者
MoE vs 量化改变”哪些参数参与计算”(结构性稀疏)改变”每个参数用多少位表示”(数值精度);两者可叠加,不可互替
MoE vs 蒸馏推理时按输入动态选参数离线用教师输出训练一个结构固定的小模型,推理无路由
MoE vs ensemble一次前向共享主干,每层只走被选中专家,router 可学习多个完整模型各自前向再合并结果,全部模型都算一遍
稀疏激活 vs 稀疏注意力 / 权重剪枝按 token 选 FFN 专家,仍是一次完整前向裁剪注意力连接或权重,改变的是计算图形状

典型应用(在 Agent 系统中的落点):

  • 容量规划:Agent 服务的并发上界通常由权重显存 + KV Cache 共同决定。MoE 下”权重驻留”按总参数算、“每 token 算力”按激活参数算,必须分开做预算;不能因为标称 13B 激活就按 13B 稠密模型申请显存。
  • 模型路由与降级:把 MoE 模型加入路由表时,质量/成本/延迟评测要按真实输入分布跑,路由倾斜会拉大 P95 与均值之差;降级到稠密小模型时,显存、TTFT 与吞吐曲线都要重新标定。
  • 批处理观测:批内专家分布影响吞吐,应把”每专家 token 数”与”最慢专家耗时”作为一等指标,而不是只看 GPU 利用率——后者是代理指标,无法表达负载倾斜。
  • 多租户与提示缓存:不同租户的 token 可能共享同一专家设备,噪声隔离需按专家维度看;路由抖动会改变 TTFT 方差,但不改变提示缓存的前缀匹配条件。

面试现场回答(1–2 分钟版本):

MoE 的定义是”按输入选择不同的参数”,Switch 论文原话是 “sparsely-activated model — with outrageous numbers of parameters — but a constant computational cost”。Mixtral 8x7B 每层有 8 个 FFN 专家,router 对每个 token 在每层选两个专家合并输出,所以每个 token 能访问 47B 参数,推理只用 13B 激活参数。这里要分开两笔账:总参数决定权重驻留显存、加载时间、多卡通信和 checkpoint 大小;激活参数决定单 token 算术量。47B 按 FP16 粗算权重就约 94 GB,跟 13B 稠密模型完全不是一个部署规格。

而且 13B 激活不等于 13B 延迟:路由有额外计算,专家并行要 all-to-all,批内路由倾斜时最慢专家决定整批完成时间,Switch 摘要也把 communication costs 和 training instability 列为主要推广障碍。至于”8 个 7B 集成”是错的,ensemble 是每个模型完整前向,MoE 是一次前向里共享主干、只走被选中的专家;8×7 也不是 56B,因为非专家参数共享。在 Agent 系统里我会把它落到容量规划:并发上界按权重显存加 KV Cache 算,评测按真实输入的路由分布看 P95,并把”每专家 token 数”作为一等观测指标。

关键点#

  1. 总参数与激活参数分属两笔账:驻留显存 / 通信 / checkpoint vs 单 token 算术量。
  2. 路由粒度是”每层、每 token”,不是每请求选一个专家,也不是整个模型一次选择。
  3. 稀疏不省显存,并引入路由计算、跨卡通信与负载倾斜;Switch 摘要点名三类推广障碍。
  4. 论文里的 7x / 4x 是训练吞吐对比,不是推理延迟结论。
  5. MoE ≠ ensemble ≠ 量化 ≠ 蒸馏;47B 而非 56B 的原因是共享主干。

常见误区#

  1. “13B 激活就按 13B 模型部署”。错误原因:全部专家权重仍须驻留,显存、加载、checkpoint 与多卡通信按总参数算,47B 按 FP16 粗算权重约 94 GB。
  2. “MoE 就是多个模型投票 / 集成”。错误原因:ensemble 是每个模型完整前向;MoE 一次前向共享主干,每层只走被选中专家,router 本身参与训练;8×7 不等于 56B 正说明参数共享。
  3. “稀疏激活一定更快更省”。错误原因:批内路由倾斜、all-to-all 通信、专家容量限制会吃掉理论算术优势;constant computational cost 说的是相对总参数,不是相对同规模稠密模型。

追问#

追问:把 MoE 模型接入已有 Agent 服务,上线前你会补哪三项评测?为什么不能用公开榜单分数代替?

回答要点:

  • 真实分布的延迟 / 成本评测:按线上 prompt 长度分布与并发度测 TTFT / TPOT,并按专家维度记录 token 数与最慢专家耗时,看 P95 而非均值。
  • 路由稳定性与批处理退化:构造同类任务集中的偏斜输入,观察专家热点、批大小变化下的吞吐曲线,以及降级与重试路径是否被放大。
  • 任务级成功率回归:用自建 golden set(工具调用、长上下文、多轮)与现有模型对比,锁定模型版本、提示词版本与工具清单版本。
  • 公开分数不能代替:它不覆盖本系统的输入分布、工具链、上下文长度与并发形态,也不反映 P95 与成本;且榜单污染与 reward hacking 是已知的评测风险,需自建回归集。

延伸学习#

  • arXiv:2101.03961《Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity》:https://arxiv.org/abs/2101.03961 —— 摘要原文与版本日期(已核验)。
  • arXiv:2401.04088《Mixtral of Experts》:https://arxiv.org/abs/2401.04088 —— 8 专家 / top-2 / 47B vs 13B / 32k 上下文(已核验)。论文正文关于 capacity factor 与 load balancing loss 的具体条文本轮未核验,仅作延伸方向。

S01 · AI Agent 场景题#

题目 ID:Q-20261104-S01
一级类型:AI 安全与治理(兼工具与互操作协议)
二级主题:Agent 身份与权限传递、代持令牌与责任归属设计
标签:代持令牌、delegation、act-claim、最小代理原则、审计链、撤销

题目#

某企业内部”运维助手” Agent 接入 42 个工具,日调用约 8 万次,服务 3000 名员工。当前架构:用户经 SSO 登录后,前端把用户访问令牌交给 Agent 编排服务;编排服务为简化实现,把用户令牌换成一张 Agent 自身的服务身份令牌(client credentials),再用它调用下游工单系统、CMDB 与发布系统。下游一律按”Agent 服务账号”鉴权,该账号为了减少权限配置被授予跨所有业务线的读写权限;审计日志只记录调用方 service_id 与工具名。

已知现象与风险:

  • 一次 Agent 误解析用户指令,改掉了另一个业务线的生产配置;事后追责时,审计里既看不到原始用户,也看不到该用户实际被授权的范围。
  • 安全团队发现:某员工离职、SSO 令牌已撤销后,Agent 手里那张服务令牌仍在有效期内,还能继续调用下游。

目标:在不改变”用户一句话就能让 Agent 代办”体验的前提下,重建授权、执行与审计链。

限制条件:① 下游三个系统短期无法改造为逐用户鉴权,只能接受令牌;② 用户原始令牌不得下发给模型或工具进程;③ 高风险写操作必须可追责、可撤销;④ 授权服务短暂不可用时,读操作不能全部失败,但写操作一律不得放行。

请回答(3–5 分钟作答框架):

  1. 现有链路错在哪一步?模型、Agent 编排、确定性系统各应承担什么?“用服务令牌替换用户令牌”破坏了哪条不变量?
  2. 给出委托链的令牌设计与下游鉴权策略,说明 delegation 与 impersonation 的语义与取舍。
  3. 审计链要记录哪些字段才能回答”谁授权、谁执行、谁生效”?为什么撤销不能假设自动传播?
  4. 授权服务不可用、令牌过期、工具超时重试、用户中途撤销,分别如何处理?
  5. 上线验证指标与观测方式。

先思考#

  • 先定位”权限被放大”的那一步:用户令牌换成服务令牌之后,谁的权限变成了谁的权限?
  • 再问审计必须回答的三个问题:原始主体、当前执行者、下游实际据以鉴权的对象,现在缺哪一个?
  • 然后想令牌交换:delegation 与 impersonation 的差别在于下游”看到的是谁”,哪一种更适合需要追责的场景?
  • 最后想撤销:如果令牌交换是一次性事件,原始令牌被撤销后,派生出去的令牌由谁负责收回?

参考答案#

结论:根因不是”模型误解析”,而是编排层把用户令牌换成了权限更大的服务令牌,使授权边界与执行主体同时丢失。修法是把授权判定放到模型之外的确定性执行点,用 delegation 语义的令牌交换保留 subject 与 actor 双主体,权限取”用户授权 ∩ 本次操作允许范围”,并把审计链绑定到操作指纹;撤销必须显式做,不能假设派生令牌随原始令牌失效。

问题拆解:

  • 现象 A(越权改配置):权限从”用户被授予的范围”放大为”服务账号的全业务线读写”,且模型输出之后没有任何确定性检查。这是典型的混淆代理(confused deputy)。
  • 现象 B(审计无归因):日志只有 service_id,缺 subject(谁授权)、actor(谁执行)、操作指纹(改了什么)与决策结果(凭什么允许)。
  • 现象 C(撤销不生效):RFC 8693 §2.1 明确 the exchange is a one-time event and does not create a tight linkage between the input and output tokens, so that (for example) while the expiration time of the output token may be influenced by that of the input token, renewal or extension of the input token is not expected to be reflected in the output token's properties. 同节还写道 It may still be appropriate or desirable to propagate token-revocation events. However, doing so is not a general property of the STS protocol and would be specific to a particular implementation, token type, or deployment.
  • 三者共同点:把”身份”当作调用链里可随手替换的字段,而不是必须端到端携带、逐跳校验的不变量。

核心方案:

  1. 单一确定性执行点:在编排层与工具之间设策略网关(PEP / PDP),所有工具调用必经。模型只产出”意图 + 参数”,不产出”权限”。风险分级表是配置数据,不是提示词;高风险写的授权判定在网关完成,依据用户当前授权状态与规范化后的操作指纹,不依据模型输出里的”用户已确认”字样。
  2. 选 delegation 而非 impersonation:RFC 8693 §1.1 对 delegation 的定义是 principal A still has its own identity separate from B, and it is explicitly understood that while B may have delegated some of its rights to A, any actions taken are being taken by A representing B;对 impersonation 是 A is given all the rights that B has within some defined rights context and is indistinguishable from B in that context,且 insofar as any entity receiving such a token is concerned, they are actually dealing with B。追责需要可区分的 actor,故选择 delegation。
  3. 复合令牌:顶层 sub 为用户(subject),act 声明 Agent 为 current actor;§4.1 允许 A chain of delegation can be expressed by nesting one "act" claim within another,且 The outermost "act" claim represents the current actor while nested "act" claims represent prior actors。关键边界:§4.1 的 MUST 规则是 For the purpose of applying access control policy, the consumer of a token MUST only consider the token's top-level claims and the party identified as the current actor by the "act" claim.,嵌套历史 actor are informational only and are not to be considered in access control decisions。因此审计必须单独完整保存整条链,不能指望下游从令牌里”顺便”读出全部历史。
  4. 权限取交集:scope = 用户当前有效授权 ∩ 本次操作允许的工具与资源范围,并绑定单一 audience、短 TTL 与操作指纹(规范化参数哈希)。§2.1.1 提醒 the requested access rights of the token are the Cartesian product of all the scopes at all the target services —— 一次换发覆盖多个目标服务会放大权限,故”一服务一令牌”。§5 建议 The use of the "scope" claim (in addition to other typical constraints such as a limited token lifetime) is suggested to mitigate potential for such abuse(注意:这是 suggested,RFC 8693 并未把”派生令牌不得比原始令牌更特权”写成通用 MUST;该约束属于本系统的部署策略)。
  5. 撤销显式化:维护”用户会话 → 派生令牌 id”台账;登出、离职、权限变更时按台账主动撤销派生令牌并清空网关授权缓存。下游无法逐用户鉴权时,用短 TTL + 网关每次在线查授权状态收口,而不是依赖下游自己校验。

执行流程:① 用户 SSO,编排服务持有用户令牌(不进入模型上下文)→ ② 模型产出工具意图(概率性)→ ③ 编排层规范化参数、生成操作指纹(确定性)→ ④ 网关校验用户当前授权、scope、audience、风险等级、指纹匹配(确定性,写操作 fail-closed)→ ⑤ 通过后按目标服务做一次 token exchange,签发短 TTL 复合令牌(sub = 用户,act = Agent)→ ⑥ 工具执行,令牌只存在于网关到下游的传输层 → ⑦ 审计写入 subject / actor / 完整委托链 / 操作指纹 / 决策结果 / 令牌 id / 工具与资源 / 是否降级 → ⑧ 高风险写进入可撤销窗口与人工复核。

技术选型:令牌用 JWT + RFC 8693 token exchange(标准协议,不绑定任何 Agent 框架);§4.4 的 may_act 可用于预声明哪些 Agent 有资格成为 actor,由授权服务在换发时判定。策略网关集中实现 PEP,规则作为版本化配置。备选 A:impersonation(下游完全按用户身份鉴权)——最小权限最彻底,但需下游改造且接收方无法区分 Agent 操作与用户本人操作,作为演进目标态。备选 B:保留服务令牌 + 网关白名单——改动最小,可短期止血,但审计仍缺 subject、撤销仍不联动,不得作为终态。备选 C:把用户原始令牌透传下游——违反限制 ②,令牌泄露面扩散到工具进程与日志,不采纳。

方案取舍:delegation vs impersonation 是”可追责性 vs 下游改造成本”;权限交集 vs 并集没有折中余地,并集正是本次越权的成因;短 TTL + 每次在线换发 vs 长 TTL + 缓存,前者撤销时效好但增加 STS 压力与延迟,故读操作用有界缓存 + 后台刷新、写操作每次换发并强制在线校验;实时撤销 vs 批量撤销按风险分级——高风险写实时撤销,低风险读允许 ≤ TTL 的窗口但由网关在线校验收口;自动化程度 vs 安全性上,高风险写保留一次性确认令牌绑定操作指纹,其余自动。

失败路径、边界条件、超时、重试、幂等与恢复:

  • 授权服务 / STS 不可用:读操作允许在”最近一次已验证且未过期”的短窗口内 fail-static 降级只读并打降级标记写审计;写操作一律 fail-closed 拒绝并转人工。不可用绝不降级为”沿用上次授权结果执行写”。
  • 令牌过期 / 换发失败:鉴权类错误不可重试;换发失败返回明确错误让编排层转人工,不得悄悄回退到服务令牌。
  • 工具超时:超时是三态(可能已执行),写操作必须由幂等键 + 操作指纹去重;同一指纹在 TTL 内只允许执行一次,重试不得换令牌签出更大 scope。
  • 用户中途撤销:网关在线校验授权状态,撤销事件按台账主动作废派生令牌;下游无法校验时靠短 TTL + 网关拦截收口。
  • 委托链过长:设链长上限,超过拒绝;嵌套 act 仅作信息,不参与访问控制。
  • 边界:模型输出的参数默认不可信(注入、越权字段),规范化函数必须在网关与执行侧共用同一份;用户令牌绝不进入模型上下文、工具日志与错误消息。
  • 恢复:撤销台账与授权缓存须能从 SSO 事件流回放重建;故障期间的降级只读记录要可回放,恢复后补做一次全量派生令牌扫描与对账。

安全、成本、延迟与可靠性:最小代理原则 + scope / audience / TTL 三约束 + 操作指纹 + 不可抵赖审计;§6 要求令牌 MUST only be transmitted over encrypted channels,§2.1 警告 omitting client authentication allows for a compromised token to be leveraged via an STS into other tokens by anyone possessing the compromised token,故 STS 的 client authentication 不可省略。成本上,换发 QPS 与审计存储随 8 万次/日线性增长,按风险分级只对写与高敏读做在线换发,审计按指纹去重存储。延迟上,每次写多一次 STS 往返 + 一次策略查询,用连接池与并行校验消化,并把”授权耗时”作为独立 span 观测,不混进模型延迟。可靠性上,STS 与策略服务多副本、降级矩阵预定义且可灰度;审计写入失败时高风险写应拒绝——审计是授权链的一部分,不是旁路日志。

验证指标:越权率(工具调用中 scope 超出用户授权的比例,目标 0,用可断言回放集测);审计完整率(含 subject / actor / 操作指纹 / 决策结果 / 令牌 id 的调用占比,目标 100%);撤销生效时延 P95 与”撤销后仍成功调用”计数(目标 0);降级比例与降级只读时长、STS 错误率与 P99、写操作 fail-closed 触发次数、人工接管率与审批疲劳。上线后按工具、租户、风险等级分桶观测,并把”服务令牌越权""撤销后仍可调用""多 audience 换发”写成回归用例,每次策略变更跑门禁。

三层能力的区分:模型提供的是概率性能力——理解意图、生成工具意图与参数,其输出是待校验的提案,不能作为授权依据;Agent 编排提供的是必须确定性实现的状态与工作流能力——参数规范化、操作指纹、状态机、重试预算、降级路由、审计字段组装;传统软件系统提供确定性能力——SSO 与授权状态、STS 令牌交换、策略网关判定、下游鉴权、撤销台账、审计存储与对账。授权边界只能落在第三层。

面试官追问 1:为什么不把用户令牌直接透传给下游,最小权限不是更彻底?

回答要点:违反限制 ②,令牌会扩散到工具进程、日志与错误消息;下游三个系统短期无法逐用户鉴权;追责需要可区分的 actor,透传反而让接收方把 Agent 操作当成用户本人操作;且透传无法把令牌绑定到本次操作指纹,撤销仍需台账。

面试官追问 2:如果下游将来支持逐用户鉴权,架构怎么演进?

回答要点:可切换为 impersonation 语义但仍保留 act 链作审计;网关从”每次换发”退化为”校验 + 传递”,撤销可逐步交给下游;操作指纹、风险分级、人工确认与 fail-closed 边界不能撤;演进期双写审计并对账,防止两套口径出现归因空窗。

关键点#

  1. 授权判定必须在模型之外的确定性执行点,且权限取交集而非并集。
  2. delegation 保留 subject 与 actor 双主体;impersonation 在接收方不可区分,不适合追责场景。
  3. 访问控制只看顶层 claims 与 current actor(§4.1 MUST),嵌套链仅作信息,故审计必须单独存全链。
  4. 派生令牌与原始令牌无 tight linkage(§2.1),撤销必须显式按台账收口。
  5. 写操作 fail-closed、读操作有界降级,两者不可共用一套降级策略。

追问#

追问 1:用户说”把 A 的配置改成 X”,但工具参数里被塞进了 B 的资源 ID,网关怎么判?

回答要点:操作指纹绑定规范化后的参数与用户当前资源范围;模型输出默认不可信;网关与执行侧共用同一份规范化函数做比对;不匹配即拒绝并写审计(含决策结果),不交给模型”自己纠正”;同时把这类参数变形作为独立错误类统计,用于发现提示注入或工具契约漂移。

追问 2:授权服务不可用 30 秒,8 万次/日调用里有多少能降级?

回答要点:按读写与风险分级,只有”只读、低敏、授权状态在短窗口内已验证”的调用走 fail-static 降级并打标记;写与高敏读全部 fail-closed;统计降级比例与持续时长,超过守护窗口自动切断降级并告警;恢复后补做派生令牌全量扫描与审计对账;降级只降低自动化程度,不降低判定标准。

追问 3:审计里 subject 与 actor 都有了,为什么还要记”决策结果”和”令牌 id”?

回答要点:只有主体回答不了”这次调用凭什么被允许”;决策结果(允许 / 拒绝 / 降级 / 风险等级)是归责依据;令牌 id 是把一次调用与撤销台账、STS 日志对齐的唯一连接键,撤销生效时延与”撤销后仍成功”两个指标都依赖它;缺任一项都无法做完整复盘。

常见误区#

  1. 用服务身份令牌”简化”鉴权。错误原因:权限取了并集、审计主体丢失、撤销不联动,本次越权是这一设计的必然结果,而非模型偶发失误。
  2. 把 impersonation 当成”更安全的代理”。错误原因:RFC 8693 §1.1 明确接收方在该授权上下文内无法区分 A 与 B;追责场景需要可区分的 actor。
  3. 认为原始令牌撤销后派生令牌会自动失效。错误原因:§2.1 明确交换是一次性事件、不创建 tight linkage,撤销传播是实现或部署特性。
  4. 让模型在提示词里判断”用户是否已授权”。错误原因:授权边界应置于模型之外;且嵌套 act 历史不参与访问控制决策,模型更无权解释它。

小型实践(30–60 分钟)#

用 20 条模拟调用(含 3 条越权参数、2 条撤销后调用、2 条多 audience 换发)实现一个最小策略网关:输入用户授权集合与工具意图,输出规范化参数、操作指纹、scope ∩ 授权、决策结果(allow / deny / degrade)与完整审计字段;再用 5 条可断言用例验证”越权必拒、撤销后必拒、多 audience 必拆分”,并统计审计完整率与降级比例。

延伸学习#

  • IETF RFC 8693《OAuth 2.0 Token Exchange》:https://www.rfc-editor.org/rfc/rfc8693.txt —— §1.1 delegation / impersonation、§2.1 linkage 与 client authentication、§4.1 act 与访问控制 MUST、§4.4 may_act、§5 / §6 安全与隐私(已核验)。
  • IETF RFC 7523 与 SPIFFE 工作负载身份规范(未核验本轮页面,仅作延伸方向)。

S02 · 非 AI Agent 场景题#

题目 ID:Q-20261104-S02
一级类型:数据库与存储(兼分布式系统)
二级主题:长事务 / idle-in-transaction 与 MVCC 膨胀治理(快照可见性、VACUUM 回收、超时策略与备库反馈)
标签:MVCC、VACUUM、长事务、表膨胀、XID回卷、hot-standby-feedback

题目#

某订单库使用 PostgreSQL 18:一主两只读副本,日写入约 400 万行,核心订单表 2.4 亿行。报表服务每天 09:00 通过连接池取一条连接执行 BEGIN; SELECT ...(大范围聚合),但代码里先做了几步远程调用才决定后续 SQL,个别连接因此停在 idle in transaction 长达 40 分钟。

近期现象:① 订单表 P95 查询从 18 ms 涨到 110 ms,索引没变、执行计划没变、CPU 与 I/O 均未打满;② 表体积从 210 GB 涨到 268 GB,autovacuum 日志显示一直在跑,但 n_dead_tup 不降;③ 只读副本偶发”查询被取消”报错;④ DBA 发现 XID age 正在接近告警线。

团队有三个提议:把 autovacuum 调得更激进;把这些报表连接直接 kill;把 hot_standby_feedback 打开。

限制:报表任务不能取消,可调整执行时间但不能改语义;主库写入不能停;不允许 VACUUM FULL(需要 ACCESS EXCLUSIVE 锁)。目标:24 小时内把 P95 压回 30 ms 以内,并给出不再复发的机制。

请回答(3–5 分钟作答框架):

  1. 一个 idle 事务为什么会让全表变慢?把”事务快照 → 死元组可见性 → VACUUM → 查询成本”的因果链讲清楚。
  2. 三个提议各自解决什么、带来什么新风险?哪个是止血、哪个是根治、哪个会加重问题?
  3. 给出超时与连接池侧的规则、备库复制冲突的治理,以及监控与演练口径。

先思考#

  • 先问”谁还看得见旧版本”:VACUUM 删除死元组的判据是什么,它与当前活跃事务集合有什么关系?
  • 再问”表变大为什么查询变慢”:计划没变、索引没变、CPU 也没打满,多出来的成本落在哪一层?
  • 然后看三个提议的方向:调 vacuum 改的是回收者,kill 改的是持有者,hot_standby_feedback 改的是谁在反馈——哪个方向才对?
  • 最后想防线:XID 回卷是另一个时间尺度的风险,它和表膨胀是不是同一套机制?

参考答案#

结论:根因是长事务持有的快照让”最近死元组”对某个事务仍然可见,VACUUM 因此不能回收;堆与索引膨胀同时抬高每次查询要读的页数,所以执行计划不变而 P95 变慢。止血是终止或超时化这些会话,根治是把事务边界与超时策略固化进连接池和报表框架;把 autovacuum 调激进只增加 I/O 不解决可见性,打开 hot_standby_feedback 会把同样的阻塞从备库搬回主库。

因果链(依据 PostgreSQL 18 官方文档原文,均已核验):

  • 24.1.2:In PostgreSQL, an UPDATE or DELETE of a row does not immediately remove the old version of the row... the row version must not be deleted while it is still potentially visible to other transactions. 回收判据是”是否仍可能被任何事务看见”,不是”到期时间”。
  • 19.11 idle_in_transaction_session_timeout 的 Note 原文:Even when no significant locks are held, an open transaction prevents vacuuming away recently-dead tuples that may be visible only to this transaction; so remaining idle for a long time can contribute to table bloat. 即使没持有显著锁,空闲事务也会钉住回收下界——这正是题目现象。
  • 24.1.2:标准 VACUUM 只把空间标记为可复用,it will not return the space to the operating system, except in the special case where one or more pages at the end of a table become entirely free;VACUUM FULL 需要 ACCESS EXCLUSIVE 锁且需额外磁盘,题目明确禁止。
  • 24.1.5:XID 回卷是同机制的长周期风险,it is necessary to vacuum every table in every database at least once every two billion transactions。官方给出的处置 runbook 明确列出三类阻塞源:End long-running open transactions(查 pg_stat_activity 中 age(backend_xid) / age(backend_xmin))、Resolve old prepared transactions(pg_prepared_xacts)、Drop any old replication slots(pg_replication_slots),并明确 Do not use VACUUM FULL in this scenario。
  • 19.6.3:hot_standby_feedback 原文 This parameter can be used to eliminate query cancels caused by cleanup records, but can cause database bloat on the primary for some workloads... The default value is off.;max_standby_archive_delay 默认 30 秒,wal_receiver_status_interval 默认 10 秒且反馈不会比它更频繁。

问题拆解:① 与 ② 同源——40 分钟快照钉住 backend_xmin,热点表的 UPDATE / DELETE 产生的死元组持续堆积,堆与索引页数增长,每次扫描要读更多页、缓冲命中率下降,于是 P95 上升;执行计划没变是因为估算行数与代价尚未跨过切换阈值,且统计信息本身也是近似值。③ 是反方向:主库 VACUUM 产生的 cleanup records 与备库正在执行的长查询冲突,备库按 max_standby_*_delay 取消查询。④ 是更长的时间尺度:XID age 增长,若长期被长事务、prepared transactions 或陈旧复制槽阻塞,会逼近强制 autovacuum 与回卷防线。

核心方案(三层):

  1. 止血(小时级):按官方 runbook 定位并终止阻塞者——查 pg_stat_activity 中 age(backend_xid) / age(backend_xmin) 最大且状态为 idle in transaction 的会话,确认无未提交写后 pg_terminate_backend;同时扫 pg_prepared_xacts 与 pg_replication_slots。随后对热点表执行标准 VACUUM(不是 FULL),让 n_dead_tup 回落;空间不会立刻归还 OS,但变为可复用,P95 随扫描页数与缓存命中恢复。
  2. 根治(机制级):把”BEGIN 之后先做远程调用”改成”先算完参数、再开事务”;报表改为只读事务 + 物化中间结果,或把事务缩短到只剩 SQL 执行窗口。连接池侧设置 idle_in_transaction_session_timeout(默认 0 = 禁用)与 PG 18 的 transaction_timeout(默认 0,Terminate any session that spans longer than the specified amount of time in a transaction;注意 Prepared transactions are not subject to this timeout)。statement_timeout 与 lock_timeout 官方明确 Setting ... in postgresql.conf is not recommended because it would affect all sessions,应按角色 / 会话设置并给合法长报表留白名单。另一个易忽略点:19.11 原文 If transaction_timeout is shorter or equal to idle_in_transaction_session_timeout or statement_timeout then the longer timeout is ignored. 三个参数组合后实际生效的是谁,必须验证而不是想当然。
  3. 防线(长期):XID age、relfrozenxid age、死元组率、表 / 索引膨胀比、autovacuum “有效回收量”的告警与月度演练;每周期扫一次长事务 + 陈旧复制槽;把官方 24.1.5 的处置顺序写成 runbook。

执行流程:① 观测定位(最长事务 / 最老 xmin / 复制槽 / prepared xacts / 死元组 Top-N 表)→ ② 分级处置(先终止确认为空闲的会话,对正在执行的合法长查询改为调整执行窗口而非 kill)→ ③ 定向标准 VACUUM(按表优先级、控 I/O、避开写入高峰)→ ④ 复核 P95、扫描页数与 n_dead_tup → ⑤ 灰度上线事务边界改造与超时参数(按报表角色分桶)→ ⑥ 备库冲突治理 → ⑦ 补齐告警与演练。

技术选型:标准 VACUUM vs VACUUM FULL——前者可与生产并行、只标记空间可复用,后者需 ACCESS EXCLUSIVE 锁且需额外磁盘,本题排除。idle_in_transaction_session_timeout vs transaction_timeout——前者管”事务内空闲”,后者管”整个事务时长”,互补;不能只靠后者,因为远程等待正是最典型的空闲态。应用改造 vs 数据库参数——优先改事务边界,参数只是兜底。备选:把报表迁到只读副本并开启 hot_standby_feedback,可隔离主库查询压力,但反馈会把阻塞带回主库,只适合”报表确实要跑 40 分钟且副本资源独立”的场景,需配套 max_standby_streaming_delay 与明确的主库膨胀预算,本轮不采纳为默认。

方案取舍:回收速度 vs 主库 I/O——快照仍被持有时,更激进的 autovacuum 不做功,只增加 I/O 争用,顺序必须是”先解除持有者,再谈调参”。kill 会话 vs 等待——“空闲 40 分钟”不是报表语义的必需部分,先改代码消除空闲段,kill 只作一次性止血,避免常态化误杀。备库查询不被取消 vs 主库膨胀——hot_standby_feedback 官方明说 can cause database bloat on the primary,当前主库已在膨胀,打开等于加重;先按 delay 参数与执行窗口治理。强一致读 vs 报表可执行性——报表可接受时间点快照,用只读事务 + 物化结果,避免长事务长期持有主库快照。

失败路径、边界条件、超时、重试、幂等与恢复:kill 掉的是空闲事务,未提交工作会回滚,须先确认无写操作;报表结果按”业务日 + 版本”唯一键重跑,保证幂等。超时阈值过短会中断合法大聚合,须按角色分级、灰度,并观测”超时终止次数”与”报表成功率”。VACUUM 被中断可重跑,标准 VACUUM 幂等;XID 告急时不得用 VACUUM FULL 或 VACUUM FREEZE(官方 Tip 明确禁止)。删除陈旧复制槽前必须确认对应副本是否仍存在,否则该副本可能需要重建。恢复判据是 P95、死元组率、每次扫描页数三项同时回落,而不是”VACUUM 跑完了”;空间不会归还 OS,若确需归还只能在维护窗口做表重写并评估额外磁盘与锁。边界上,autovacuum 日志”在跑”不等于”有进展”;hot_standby_feedback 基于时间戳,官方提示备库时钟被前后调整时反馈可能不按间隔发出,极端情况会长期不回收主库死行。

安全 / 权限、成本、性能与可用性:终止会话与 VACUUM 需要相应权限,runbook 应限定角色;报表账号只读、不得持有写事务。成本上,膨胀直接是存储成本,vacuum 的 I/O 预算与副本延迟是隐性成本,按表优先级排期。性能上观测堆 / 索引页数、缓冲命中率、每查询扫描页数、死元组率与按接口分层的 P95。可用性上主库写入不停,终止空闲事务只影响报表,备库查询取消由 delay 参数与执行窗口控制,只读副本不承担强一致读。可靠性靠”告警 + 演练 + runbook”三件套,XID age 是硬防线,不能只靠人工巡检。

验证指标:最长事务年龄(max / P95)、idle in transaction 会话数与时长分布;n_dead_tup 与死元组率、表 / 索引体积与膨胀比、每次扫描页数与缓存命中率;订单查询 P95(目标 ≤ 30 ms)及执行计划是否变化;autovacuum 完成次数与有效回收量、age(relfrozenxid)、XID 剩余余量与 24.1.5 提到的四千万交易警告;备库查询取消次数、max_standby_streaming_delay 命中、feedback 是否启用及其对主库死元组的影响。上线后按角色分桶看超时终止次数与报表成功率,每月做一次”长事务 + 复制槽”扫描与恢复演练。

面试官追问 1:autovacuum 一直在跑,为什么 n_dead_tup 不降?

回答要点:回收判据是”是否仍可能对任何事务可见”,不是”是否到期”;长事务、陈旧复制槽、prepared transactions 会把可见性下界钉住;调参只改变尝试频率与 I/O 预算,不改变下界;先查 pg_stat_activity.backend_xmin、复制槽位点与 pg_prepared_xacts,再谈 vacuum 参数。

面试官追问 2:为什么不让报表直接在只读副本跑并打开 hot_standby_feedback?

回答要点:官方明确该参数会 cause database bloat on the primary for some workloads,当前主库正因此膨胀,等于把阻塞搬回主库;反馈还基于时间戳,备库时钟漂移会放大风险。可行前提是给副本独立资源与执行窗口、接受主库保留窗口并设预算;更稳的顺序是先把报表事务拆短、把空闲段移出事务。

关键点#

  1. 回收判据是”仍可能被任何事务看见”,不是过期时间;空闲事务即使不持锁也阻塞回收(19.11 Note 原文)。
  2. idle_in_transaction_session_timeout 与 transaction_timeout 默认都是 0(禁用),且事务边界改造优先于参数兜底。
  3. 标准 VACUUM 只标记空间可复用、不归还 OS;VACUUM FULL 被 ACCESS EXCLUSIVE 锁排除,XID 告急场景官方还明确禁用。
  4. hot_standby_feedback 默认 off,打开会把备库的查询保护转为主库膨胀。
  5. XID 回卷是同机制的长周期风险,官方三类阻塞源(长事务 / prepared xacts / 复制槽)必须一起扫。

追问#

追问 1:kill 掉一个 idle in transaction 会话,报表结果怎么办?

回答要点:未提交工作回滚;先判断该会话是否有未提交写;报表按业务日 + 版本唯一键重跑并保证结果写入幂等;重跑要避开主库写入高峰;把”远程调用在事务内”这段移出去才是根治,否则下周同一时刻会重演。

追问 2:超时阈值怎么定,为什么不能全局设 statement_timeout?

回答要点:官方明确 Setting statement_timeout in postgresql.conf is not recommended because it would affect all sessions;按角色 / 会话分级,阈值取报表执行时长 P99 × 安全系数并灰度观察误杀率;注意 transaction_timeout 与 idle_in_transaction_session_timeout、statement_timeout 的组合生效关系(较短者会使较长者被忽略);超时终止次数与报表成功率必须一起看。

追问 3:表体积从 268 GB 回不到 210 GB,是否算恢复失败?

回答要点:不算。标准 VACUUM 不归还 OS,恢复判据是 P95、死元组率、扫描页数三项同时回落;已回收的空间会被后续写入复用,体积不降反而是预期行为。若确需归还空间,须在维护窗口评估表重写 / VACUUM FULL 的锁与额外磁盘,且 XID 告急场景下官方明确禁止后者。

常见误区#

  1. 把 autovacuum 调激进当作解法。错误原因:下界由事务快照决定,调参不改变可见性,只增加 I/O 争用;日志”在跑”不等于”有进展”。
  2. 认为”没持有锁就不会影响 VACUUM”。错误原因:19.11 的 Note 明确空闲事务即使无显著锁,也阻止回收仅对它可见的最近死元组。
  3. 打开 hot_standby_feedback 解决备库查询被取消。错误原因:官方写明它 can cause database bloat on the primary,当前主库正因此膨胀;且反馈基于时间戳,时钟漂移会延长风险窗口。
  4. 用 VACUUM FULL 快速回收空间。错误原因:需 ACCESS EXCLUSIVE 锁且需额外磁盘;在 XID 回卷风险场景官方明确 Do not use VACUUM FULL in this scenario。

小型实践(30–60 分钟)#

在测试库开一个 BEGIN; SELECT 1; 且不提交,另一会话批量 UPDATE 1 万行,观察提交前后与手动 VACUUM 后的 n_dead_tup 变化;再把 idle_in_transaction_session_timeout 设为 5 秒,验证会话被终止后死元组可被回收;记录三步中 pg_stat_activity.backend_xmin 与 autovacuum 日志的差异,形成一张”下界被谁钉住”的对照表。

延伸学习#


L01 · LeetCode#

题目 ID:Q-20261104-L01
一级类型:数组与字符串(双单调队列 / 滑动窗口)
二级主题:把任意两元素差转成窗口 max − min,并用两个单调队列 O(n) 维护极值
标签:LeetCode、单调队列、滑动窗口、不变式

题目#

给定整数数组 nums 和整数 limit,返回最长非空连续子数组的长度,要求该子数组中任意两个元素之差的绝对值都小于或等于 limit。

注意:约束作用于窗口内任意两个元素,不只是相邻元素——官方示例 1 特别指出,元素对 (2, 7) 并不相邻,仍需要比较。

先思考#

  • “任意两个元素的最大绝对差”能化简成什么?是不是等价于窗口内 max − min?
  • 若窗口 [left, right] 原本合法,加入 nums[right+1] 后不合法,左端至少要推进到哪里?只推进一格够不够?
  • 需要 O(1) 拿到窗口最大值与最小值,同时支持”从左侧删除”——什么结构同时满足这两点?

参考答案#

题号 / 名称 / 难度 / 链接:

题目描述、输入输出与约束:

  • 输入:整数数组 nums、整数 limit;输出:一个整数(最长合法子数组长度)。
  • 约束(中英文页面一致):
    • 1 <= nums.length <= 10^5
    • 1 <= nums[i] <= 10^9
    • 0 <= limit <= 10^9

示例(官方三例,原样保留数字):

示例 1:nums = [8,2,4,7], limit = 4 -> 2
说明:[2,4] 与 [4,7] 是长度 2 的合法子数组;[2,4,7] 中 (2,7) 差为 5 > 4,不合法。
示例 2:nums = [10,1,2,4,7,2], limit = 5 -> 4
说明:[2,4,7,2] 合法(最大差 |7-2| = 5);向左扩展为 [1,2,4,7,2] 时 (1,7) 差为 6 > 5。
示例 3:nums = [4,2,2,2,4,4,2,2], limit = 0 -> 3
说明:limit = 0 要求窗口内元素全相等,最长为 [2,2,2]。

解题思路:

  1. 直观方案及其局限:枚举所有子数组并维护 max / min 是 O(n²),在 n ≤ 10^5 下不可接受;用平衡树 / 有序容器维护窗口并二分删除可做到 O(n log n),是可行的但不是最优。另一个常见错误是把条件读成”相邻元素差 ≤ limit”——示例 1 的 (2, 7) 就是专门用来否定这个读法的反例。

  2. 推荐方案的推导:

    • 等价转换:窗口内”任意两元素绝对差 ≤ limit” ⟺ max(window) − min(window) <= limit。这一步把 O(n²) 的两两比较压成两个可维护的聚合量。
    • 两个单调队列:max_q 存下标,对应值从队首到队尾非递增,队首即窗口最大值;min_q 对应值非递减,队首即窗口最小值。新元素 right 入队前,从队尾弹出所有被它”支配”的下标(max_q 弹出值小于 nums[right] 的,min_q 弹出值大于 nums[right] 的)——这些下标更靠右、值更极端,被弹出的旧下标在当前及以后所有窗口中都不可能再成为极值。
    • 收缩左端:若 nums[max_q[0]] − nums[min_q[0]] > limit,则窗口不合法。违反约束的两个端点中较早的那个必须出窗,因此可以把 left 一次跳到 min(max_q[0], min_q[0]) + 1 并弹出过期队首;但跳一次后新的极值对仍可能违反约束(例如 nums=[10,1,2,4,7],跳过 10 之后 7 与 1 仍差 6),所以必须放在 while 循环里重复判定。参考代码采用等价且更易证明的”每次 left += 1 并弹出队首”写法,二者都要循环到窗口合法为止。
    • 取答案:循环结束后 [left, right] 是以 right 结尾的最长合法窗口(任何更小的 left 都会包含刚才被判非法的极值对),更新 best = max(best, right − left + 1)。
  3. 正确性说明:对队列不变式做归纳——初始为空,平凡成立;入队时从尾部淘汰被支配下标,保持”下标递增 + 值单调”;每次 left 推进时弹出下标 <= left 的队首,保证队首始终落在 [left, right] 内,故队首确为窗口极值。对收缩循环——只要 max − min > limit,当前窗口不合法;每次迭代 left 严格递增且最多推进 n 次,循环必然终止;终止时窗口合法,且因循环是按”最小必要收缩”推进的,不存在更长的以 right 结尾的合法窗口被跳过。枚举全部 right 取最大,即得全局最优。

  4. 复杂度:每个下标最多入队两次(各队列一次)、出队两次,时间 O(n);两个队列最坏与窗口等长,空间 O(n)。

Python 参考代码:

from collections import deque
from typing import List
class Solution:
def longestSubarray(self, nums: List[int], limit: int) -> int:
max_q = deque() # 下标;对应值非递增,队首为窗口最大值
min_q = deque() # 下标;对应值非递减,队首为窗口最小值
left = 0
best = 0
for right, value in enumerate(nums):
while max_q and nums[max_q[-1]] < value:
max_q.pop()
max_q.append(right)
while min_q and nums[min_q[-1]] > value:
min_q.pop()
min_q.append(right)
while nums[max_q[0]] - nums[min_q[0]] > limit:
if max_q and max_q[0] <= left:
max_q.popleft()
if min_q and min_q[0] <= left:
min_q.popleft()
left += 1
best = max(best, right - left + 1)
return best

边界情况:

  1. limit = 0:只允许全相等窗口,示例 3 覆盖;重复值用严格 < / > 弹出而保留相等下标,不会提前丢掉窗口内仍有效的极值。
  2. n = 1:单元素差为 0,答案必为 1。
  3. 非相邻元素对:示例 1 的 (2, 7) 必须比较;用”相邻差”判断会得到错误答案 3。
  4. 收缩必须循环:示例 2 中跳过 10 之后仍需继续收缩;只跳一次会留下不合法窗口。
  5. 数值范围:nums[i] ≤ 10^9,max − min 不超过 10^9 − 1,32 位整数不会溢出;Python 无此问题。
  6. 整个数组都合法:left 始终为 0,答案为 n,两个队列各自最多保存 n 个下标。

测试用例:

#输入期望输出覆盖点
1nums=[8,2,4,7], limit=42官方示例 1;非相邻对 (2,7) 排除
2nums=[10,1,2,4,7,2], limit=54官方示例 2;连续收缩后保留 [2,4,7,2]
3nums=[4,2,2,2,4,4,2,2], limit=03官方示例 3;limit=0 与重复值
4nums=[1], limit=01单元素边界
5nums=[1,1,1,1], limit=04全相等,left 不推进
6nums=[1,10,1,1], limit=22大跳变后连续收缩([1,1] 而非 [1,1,1])

(以上用例已在本机对参考代码执行并全部通过;另与 O(n²) 暴力解做了 3000 组随机数组对拍,结果完全一致,并在 n = 100000 上做了规模冒烟测试。)

面试官可能提出的变体或追问:

变体:如果把条件改成”相邻元素之差的绝对值 ≤ limit”,算法怎么变?

回答要点:约束不再依赖窗口全局极值,扫描时只要 abs(nums[i] - nums[i-1]) > limit 就把当前段起点重置为 i,一次扫描 O(n)、O(1) 空间,单调队列完全不需要。这反过来说明原题的难点正是”任意两元素”引入的全局聚合约束——从全局约束化成可撤销的局部聚合量(max / min),是滑动窗口题的核心动作。若进一步改成”允许删除最多一个元素后满足条件”,则约束不再能用单个 max − min 表达,需要固定窗口 + 次大 / 次小值或有序结构,复杂度会上浮。

可迁移的解题能力:

  1. 把全局约束转成可维护的聚合量:“任意两元素差 ≤ limit” ⟺ max − min ≤ limit,把 O(n²) 的两两比较压成两个极值;判断标准是”这个聚合量能否在左端删除时 O(1) 更新”(min / max 可以,中位数不可以)。
  2. 单调队列处理”入右出左”:入队从尾部淘汰被支配候选,出队按过期下标淘汰队首,每个元素至多进出各一次,这是把 O(n log n) 降到 O(n) 的通用模式。
  3. 不变式驱动的证明:先写清”队首即窗口极值且下标在 [left, right] 内”,再让每个操作去维护它,比”先写 push 再想 pop”稳得多。
  4. 与 AI Agent 工程的自然联系:上下文窗口内”任意两条事实的冲突度不超过阈值”这类有界约束,与本题同构——需要维护窗口内聚合量并支持左侧淘汰。但要先判断该约束能否用可撤销的聚合量表达;不能表达时(如语义冲突)应退回显式状态与校验,而不是硬套单调队列。

关键点#

  1. 等价转换:任意两元素差 ≤ limit ⟺ max − min ≤ limit,且 max − min 随窗口扩展单调不减。
  2. 两个单调队列的不变式:下标递增、值单调、队首落在当前窗口内。
  3. 收缩必须循环:一次跳跃后新的极值对仍可能越界;left 单调不减保证总复杂度仍为 O(n)。
  4. 每个下标进出各一次,时间 O(n)、空间 O(n);用有序容器是 O(n log n),可行但非最优。
  5. limit = 0、重复值、非相邻元素对是三个最容易出错的边界。

常见误区#

  1. 只比较相邻元素。错误原因:题目明确”任意两个元素”,示例 1 的 (2, 7) 就是官方给出的反例;按相邻差会得到长度 3 的错误答案。
  2. 收缩左端只处理一次。错误原因:跳过旧的最大值后,新的最大值与最小值仍可能违反约束(示例 2);必须用 while 反复判定到窗口合法。
  3. 把 O(n log n) 的有序容器方案当作最优答案且说不出代价。错误原因:有序容器每次插入 / 删除是 O(log n),且常数更大;本题存在 O(n) 的双单调队列解,面试中应能主动指出这一点并说明为什么极值可以 O(1) 撤销。

延伸学习#

  • LeetCode 官方题页(中英文链接见上):题号、三示例与三约束的原始出处,本次已核验两页可访问且内容一致。
  • 延伸训练方向(本轮未核验页面内容,仅作下一步方向):LeetCode 239 滑动窗口最大值(同一单调队列模式的直接应用,难度 Hard,不在本题库选题范围)、LeetCode 946 验证栈序列(栈应用型轮换)。

延伸资料#

按「官方文档 / 标准规范 > 原始论文 > 官方工程博客 > 可信技术组织 > 可验证技术文章」的优先级给出。以下标注已核验的来源均为本次任务逐页核对的一手材料;标注未核验者仅作延伸方向,不作为事实依据。

B01 · Quorum 与最终一致

  1. Amazon《Dynamo: Amazon’s Highly Available Key-value Store》(SOSP 2007)官方 PDF:https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf —— §2.3 “always writeable”、§4.4 版本分支、§4.5 N/R/W 与 R + W > N、§4.6 sloppy quorum 与 hinted handoff、§4.7 Merkle tree 反熵、§5 read repair、§6 (3,2,2) 与 durability vulnerability window(已核验)。
  2. Apache Cassandra 官方文档关于 consistency level 与 read repair 的条目(未核验,仅作延伸方向)。

B02 · MoE 与稀疏激活

  1. arXiv:2101.03961《Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity》(Fedus、Zoph、Shazeer;v1 2021-01-11,v3 2022-06-16):https://arxiv.org/abs/2101.03961 —— 摘要原文(已核验)。
  2. arXiv:2401.04088《Mixtral of Experts》(Jiang 等;v1 2024-01-08):https://arxiv.org/abs/2401.04088 —— 8 专家 / top-2 / 47B vs 13B / 32k 上下文(已核验)。
  3. 两篇论文正文关于 capacity factor、load balancing loss 与专家并行通信开销的具体条文(未核验,本轮仅核验摘要页,文中相关表述按工程通识降格处理)。

S01 · 身份委托与授权边界

  1. IETF RFC 8693《OAuth 2.0 Token Exchange》:https://www.rfc-editor.org/rfc/rfc8693.txt —— §1.1 delegation / impersonation、§2.1 input/output token 无 tight linkage 与 client authentication、§4.1 act 与访问控制 MUST、§4.4 may_act、§5 / §6 安全与隐私(已核验)。核对说明:RFC 8693 全文没有”派生令牌不得比原始令牌更特权”的 MUST 条文;文中把该约束按本系统的部署策略表述,未写成规范强制。
  2. IETF RFC 7523 与 SPIFFE 工作负载身份规范(未核验,仅作延伸方向)。

S02 · 长事务与 MVCC 回收

  1. PostgreSQL 18 官方文档《24.1 Routine Vacuuming》:https://www.postgresql.org/docs/18/routine-vacuuming.html —— 24.1.2 可见性与空间复用、24.1.5 XID 回卷与三类阻塞源的处置 runbook(已核验)。
  2. PostgreSQL 18 官方文档《19.11 Client Connection Defaults》:https://www.postgresql.org/docs/18/runtime-config-client.html —— idle_in_transaction_session_timeout 的 Note、transaction_timeout(默认 0,prepared transactions 不受约束)、statement_timeout / lock_timeout 默认 0 且不推荐全局设置(已核验)。
  3. PostgreSQL 18 官方文档《19.6 Replication》:https://www.postgresql.org/docs/18/runtime-config-replication.html —— hot_standby_feedback 默认 off 与 “can cause database bloat on the primary”、max_standby_archive_delay 默认 30 s、wal_receiver_status_interval 默认 10 s(已核验)。

L01 · LeetCode 1438

  1. LeetCode 官方题页(中文 https://leetcode.cn/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/ ;英文 https://leetcode.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/ )—— 题号、三示例、三约束(已核验)。两侧页面本次均未渲染难度标签,难度 medium 按 LeetCode 标准分类记录,标注「未直接核验」;英文页通过率 58.2% 为实时数据,会变动。
  2. 延伸训练方向(未核验页面内容):LeetCode 239、LeetCode 946。

当日重点#

  1. 驻留与生效要分开建账:副本、专家权重、派生令牌、旧行版本、窗口候选都是”留着但未必生效”的状态,容量成本与回收责任不能按生效的那一份计算。
  2. 集合相交不等于一致性:R + W > N 的前提是固定成员、串行写、有全序;sloppy quorum 与并发分支各自打破一条,因此它是可用性调参而非强一致保证。
  3. 总参数决定显存,激活参数决定算力:MoE 的稀疏是结构性选参数,不省权重驻留;路由倾斜与跨卡通信会让尾延迟偏离算术量的直觉。
  4. 授权边界必须落在模型之外的确定性执行点:delegation 保留 subject 与 actor 双主体,权限取交集;撤销是显式台账动作,不是令牌交换协议的默认属性。
  5. VACUUM 的回收判据是可见性而非勤奋程度:空闲事务即使不持锁也钉住下界;超时策略与事务边界改造才是根治,调 autovacuum 与开 hot_standby_feedback 都可能加重问题。
  6. 算法层面:把”任意两元素差”化成窗口 max − min,再用两个单调队列让极值在左端删除时 O(1) 可撤销——这是全局约束转可维护聚合量的通用模式。

归档与去重记录#

配置读取状态#

  • 配置读取:成功。文件 ../题库配置.md,版本 8(last_maintained: 2026-11-02;运行前已用 stat 确认 mtime 为 2026-11-02 10:37,早于本次运行,git status 未列出该文件,确认未被修改)。
  • 本次为 v8 生效后第 3 次每日出题。配额:非 Agent 基础 1、Agent 基础 1、Agent 场景 1、非 Agent 场景 1、LeetCode 1,共 5 道。
  • 13 个一级类型均为 active;无暂停类型;「观察中的新技术」8 项均未标记「允许试学」,本次未从观察项出题。配置文件只读,未修改。
  • 运行前已确认 better/、Plan/、仓库根三级目录均无 AGENTS.md / CLAUDE.md;已按 better/README.md 的约定在导航表追加当日记录。

去重结果#

  • 去重窗口:30 天(2026-10-05 至 2026-11-04)。参考来源:题目索引.md(100 条 / indexed_runs: 18 / total_featured: 4)、精选/README.md(4 条)、README.md,以及窗口内 18 份每日训练文件的 frontmatter 与题目速览(逐个校验版本、LeetCode 题号、题目 ID 与状态;全部为 generated,无作答记录)。未读取窗口外的完整题目正文。
  • 索引与原始文件元数据未发现冲突;滚动索引窗口为 2026-08-04 至 2026-11-04,现有全部记录均在窗口内,本次无需剪除旧行。
  • 逐题比对结论:
题目 ID与近期题目的关系结论
Q-20261104-B01与 2026-10-22 B01(时钟、因果序与全局顺序)、2026-10-30 B01(Raft 共识与选主)同属分布式系统不重复。前两者分别考察”时间戳能否判定先后”与”多数派如何分配全序”;本题考察 R + W > N 的集合相交论证在 sloppy quorum 与并发分支下为何失效,核心结论是 quorum-like ≠ 线性一致
Q-20261104-B02与 2026-10-13 B04(微调 / LoRA / 量化蒸馏)、2026-10-19 B02(Attention、KV Cache、上下文窗口)、2026-10-26 B02(位置编码与长度外推)同属 AI 与大模型基础不重复。本题考”稀疏激活下总参数与激活参数的工程口径分离”,属模型结构与容量规划,未涉及训练方法、注意力机制或位置编码
Q-20261104-S01与 2026-10-10 B05(最小代理原则与代持令牌,基础定义)、2026-10-20 S02(mTLS 证书轮换与 TLS 会话恢复,非 Agent)、2026-10-27 S01(高风险审批与人工接管)相邻不重复。故障形态是”编排层把用户令牌换成服务令牌导致权限放大 + 审计无 subject + 撤销不联动”;核心方案是 delegation 复合令牌、交集授权、显式撤销台账与读写分级降级,不涉及证书 / PSK 会话恢复,也不以审批流程为核心考点
Q-20261104-S02与 2026-10-28 B01(统计信息与执行计划回归)、2026-11-02 S02(备份 / PITR / 恢复演练)同属数据库与存储不重复。本题考”事务快照可见性阻止死元组回收”这一 MVCC 内部机制及超时 / 复制反馈的取舍,故障现象是 P95 随表膨胀上升但执行计划未变;前者考优化器估算,后者考灾难恢复
Q-20261104-L01已用题号:146、3、215、739、875、124、207、142、547、560、39、1109、435、208、92、516、31、155(另 322 已删未登记,仍规避)无题号重复。算法模式「双单调队列 + 滑动窗口极值维护」为窗口内首次出现,符合上一轮”下次建议轮换单调队列应用型”的指引
  • 类型集中度自查:上一轮建议优先覆盖 AI 安全与治理(4)、LLM 应用工程(4)、上下文工程与能力封装(6)、数据库与存储(9)、分布式系统(9)。本轮 S01 落在覆盖最低的 AI 安全与治理,B01 落在分布式系统的全新二级主题,S02 落在数据库与存储的全新场景,B02 落在 AI 与大模型基础(避免上下文工程 / RAG / 评测在最近 5 轮连续集中)。工具与互操作协议本轮未出题,延续 11-02 之后的轮换。
  • 场景题类型使用情况:本轮新增「Agent 身份与权限传递、代持令牌和责任归属设计」(Agent 场景,首次)与「长事务与 MVCC 膨胀治理」(非 Agent 场景,首次)。

覆盖变化与下一周期建议#

  • 覆盖次数(索引窗口内,写入索引前的值 +1):AI 安全与治理 4→5、AI 与大模型基础 5→6、分布式系统 9→10、数据库与存储 9→10。
  • 下一周期优先方向:LLM 应用工程(4,批处理与延迟联合调优、跨厂商缓存收益对比)、上下文工程与能力封装(6,剩余缺口「上下文写入与选择策略」)、Agent 评测与可观测性(5,成本与延迟的按任务归因)、RAG 与搜索(6,引用溯源的评测与知识更新下的评测漂移)、软件工程与平台工程(8,契约测试与制品供应链)。
  • LeetCode 下一轮建议轮换:栈与队列应用型(232 / 946)、Trie 变体(211)、二维差分、状压 / 位运算、二叉树层次遍历;避免连续出现单调队列 / 滑动窗口极值、栈设计、原地数组变换、区间 DP、链表操作、Trie、贪心、差分 / 前缀和、回溯、并查集、图论、二分主导模式。

本次参考的历史题目与文件#

  • 题目索引.md(100 条主表、indexed_runs: 18、total_featured: 4)
  • 精选/README.md(4 条精选题目,含复习节奏表)
  • README.md(每日训练导航表)
  • 题库配置.md(版本 8,只读)
  • 窗口内 18 份 YYYY-MM-DD-AI-Agent-面试训练.md 的 frontmatter 与题目速览(元数据层校验,未通读正文)
  • 未读取窗口外的历史训练文件正文;未修改任何历史训练文件正文

保存与同步状态#

  • 本地保存:成功(路径 2026-11/2026-11-04-AI-Agent-面试训练.md)。
  • 远端同步:未验证。写入本地 Obsidian 目录不等于 iCloud 或其他远端已同步,本次未做独立验证,不声称已同步。
  • 本次执行未触发精选(用户未提出明确精选请求),未收到作答反馈,未修改 题库配置.md,未修改任何历史训练文件正文。
2026-11-04 AI Agent 面试训练
https://vissssa.github.io/posts/ai-agent-interview-2026-11-04/
作者
Siegward
发布于
2026-11-04
许可协议
CC BY-NC-SA 4.0