YIKUN DING / INTERVIEW ATLAS

面试知识图谱

六个模块 · 中文笔记与英文术语 · 可离线阅读

English · 交互总览

算法与解题模式

把题目归纳为可识别的模式,训练正确性、复杂度分析和限时表达。

复习方法

每次选一个问题,先脱稿讲解,再补笔记。记录依据、尚未验证的假设和下一次复习时间。

熟练度:待复习 → 能解释 → 能独立完成 → 能应对追问。

本模块资料

解题训练与错题复盘

模式地图

数组与哈希(Array / Hashing)、双指针(Two Pointers)、滑动窗口(Sliding Window)、二分查找(Binary Search)、树与图(Tree / Graph)、堆(Heap)、回溯(Backtracking)、动态规划(Dynamic Programming)。

每题记录

日期题目链接模式首次思路卡点复杂度下次复习

脱稿表达

  1. 明确输入约束与边界情况。
  2. 给出基线解法,再解释改进依据。
  3. 说明不变量(Invariant)与正确性。
  4. 编码后手动覆盖空输入、重复值、极端规模。
  5. 记录错误成因,下一次从空白重新完成。

模块导航

网络基础

网络设计决定请求经过哪些节点、各层提供什么保证,以及拥塞、断连和跨区域访问时服务如何退化。先把一条请求走通,再讨论协议、连接管理和负载分配,比直接堆组件更容易说明设计依据。

网络请求的主要环节

一次 HTTPS 请求的完整路径

以浏览器查询训练任务为例:GET /training-jobs/job-42。客户端先通过域名系统(DNS)找到目标地址;没有可复用的连接时,再建立传输连接和 TLS 安全会话;随后发送 HTTP 请求。请求可能经过 CDN、负载均衡器、应用服务和数据库,响应沿相应连接返回。

这里有三种不同的时间:建立连接的时间、网络往返时间(Round-trip Time,RTT)和服务处理时间。即使数据库查询很快,跨洲 RTT、首次握手或代理排队仍可能占据主要延迟。连接复用(Connection Reuse)避免每次请求重新建立连接,因此不能把每次 HTTP 请求都画成一次全新的 TCP 握手。

DNS 记录有缓存和生存时间(TTL)。调整域名解析不意味着所有客户端立刻迁移,区域故障切换必须考虑旧地址缓存、已有连接与重新连接行为。TCP 连接在传输层建立成功,也不代表应用层任务已创建或事务已提交。

分层:IP、传输协议和应用协议各管什么

层次负责的事情不自动提供的保证
网络层(L3):IP地址与跨网络路由,尽力交付数据包。不保证包一定到达,也不保证到达顺序。
传输层(L4):TCP、UDP;QUIC 提供现代传输能力端到端通信;具体保证由协议决定。不保证业务操作只执行一次。
应用层(L7):HTTP、DNS、WebSocket 等定义请求、响应或消息的业务可理解格式。不替应用设计鉴权、恢复或一致性规则。

端口(Port)区分同一主机上的通信端点。客户端连接的是某个地址与端口,不是抽象的“用户服务”;服务发现(Service Discovery)和负载均衡负责把逻辑服务映射到可用实例。

TCP、UDP 与 QUIC

TCP 提供有序的可靠字节流,包含重传、流量控制(Flow Control)和拥塞控制(Congestion Control)。它不保留应用消息边界:一次写入的数据可能被拆成多次读取,应用需要长度前缀、分隔符或上层协议来分帧。发生丢包时,后续字节可能等待重传,影响尾延迟。

UDP 以数据报(Datagram)发送,不内建可靠交付、排序或拥塞控制。它适合由应用自己管理丢失和时效性的场景,例如实时媒体;过时的语音片段往往没有继续等待的价值。但“用了 UDP 就一定更快”不成立,补上的可靠性、拥塞控制与重传机制仍然有成本。

QUIC 建立在 UDP 之上,加入可靠流、加密和连接管理。HTTP/3 使用 QUIC;HTTP/1.1 和 HTTP/2 通常使用 TCP。QUIC 的独立流减少了某个流丢包对其他流的传输层队头阻塞(Head-of-line Blocking),但不等于消除了所有拥塞或等待。

HTTP、TLS 与接口语义

HTTP 定义方法、状态码、头部和消息体。HTTP/1.1 可以复用连接;HTTP/2 可在一个连接中多路复用(Multiplexing)多个流。选择版本时应说明希望改善的瓶颈,而不是只把版本号当作性能结论。MDN 的 HTTP 概览说明了客户端、服务器与中间代理的关系。

HTTPS 在传输中提供机密性和完整性,并验证服务端身份。TLS 终止(TLS Termination)可以发生在边缘、负载均衡器或应用服务上;终止之后到后端的一段是否继续加密,是另外的部署选择。

加密不等于鉴权。请求体里写着 owner_id=42,不能证明发起者拥有该任务。服务端仍应验证身份、资源归属和操作权限。HTTP 的无状态语义也不意味着底层没有连接状态,或服务端不能使用会话。

REST、GraphQL 与 gRPC 的位置

方式适用场景要说明的代价
REST面向资源的公开 Web 接口,例如查询和创建任务。复杂页面可能需要聚合接口或多次请求。
GraphQL不同客户端需要不同字段和关联数据。解析器、查询复杂度、N+1 访问、缓存和权限控制更复杂。
gRPC有稳定服务契约的内部调用,或流式服务通信。浏览器端通常需要 gRPC-Web 或其他适配,运维链路也要支持。

gRPC 常用 Protocol Buffers 和 HTTP/2,并可以生成多语言客户端。二进制格式有利于减少部分序列化成本,但是否改善端到端延迟要看实际负载。REST、GraphQL 是接口设计方式,TCP、UDP 是传输方式,不能放在同一个层级直接替代比较。

实时更新:轮询、SSE 与 WebSocket

轮询(Polling)由客户端定期查询,实现简单,代价是重复请求和最多一个轮询间隔的额外等待。低频状态刷新可能已经足够,未必需要长连接。

服务器发送事件(Server-Sent Events,SSE)在 HTTP 响应流上从服务端向客户端推送文本事件,适合训练进度、通知和生成式输出。事件可以带 id;浏览器 EventSource 会尝试重新连接,并可用 Last-Event-ID 帮助服务器恢复游标。服务器是否保存事件、保存多久、如何补发,仍需应用实现,不能把自动重连当作不丢消息的保证。

SSE 还要处理代理缓冲、空闲超时和心跳;HTTP/1.1 环境下也要注意浏览器连接数限制。具体事件格式见 MDN 的 SSE 文档。

WebSocket 提供持久的双向消息通道。常见 HTTP/1.1 建连方式是先发起 HTTP Upgrade,再交换 WebSocket 帧;其他 HTTP 版本可以使用不同的建立机制。它适合频繁双向交互,例如协作操作和聊天。应用仍需定义消息类型、确认、顺序、心跳与恢复协议;一条 TCP 连接的可靠性不覆盖断线后的业务消息重放。

WebRTC:媒体连接与 NAT 穿透

WebRTC 常用于浏览器音视频通信。信令(Signaling)交换双方的会话和连接候选信息;信令服务不必承载最终媒体流。ICE 负责收集和检查连接候选,STUN 帮助发现外部可达地址,无法直连时可以通过 TURN 中继。

所以“WebRTC 等于永远点对点、不需要服务器”是错误的。TURN 会带来中继带宽成本;多人会议常使用选择性转发单元(SFU)等服务器架构,避免每个参与者向所有其他人分别发送媒体流。MDN 的连接说明可用于核对连接建立与候选交换机制。

负载均衡:分配请求还是分配连接

客户端负载均衡由客户端或其库发现实例并选择目标,省去一个集中转发点,但需要管理发现、健康状态和客户端版本。独立负载均衡器集中接收流量,便于统一策略,也要考虑其容量和故障切换。

选择能依据什么分配设计影响
L4 负载均衡IP、端口、连接等传输信息。常按连接分配,不理解 HTTP 路径;具体实现可能透传或代理连接。
L7 负载均衡HTTP 主机、路径、头部或 Cookie。可做内容路由、TLS 终止和更细的应用策略,但需要应用协议处理。

L7 也可以支持 WebSocket;不能因为是长连接就机械地要求 L4。选择取决于是否需要检查 Upgrade 请求、按路径路由、执行应用策略,以及产品的实际支持能力。连接建立后通常固定到后端,新增实例不一定自动分担已有长连接。

轮询(Round Robin)、最少连接(Least Connections)、权重和一致性哈希解决的是不同负载模型。连接数量相同不代表 CPU 或请求量相同;健康检查通过也不保证实例没有过载。会话粘滞(Sticky Session)可以减少状态搬迁,却会增加倾斜与故障恢复难度。

跨区域与故障处理

CDN 缓存可复用内容,减少用户到源站的距离;它不能消除所有动态写请求的远程协调。区域化(Regionalization)把服务部署到用户附近,但必须另行决定数据归属、跨区复制、写入位置和故障接管。

超时(Timeout)约束一次调用的等待,截止时间(Deadline)约束整个操作的总预算。重试(Retry)要限次数、受总预算约束,并配合指数退避与随机抖动。多层各自重试会放大流量;存在副作用的调用还需要幂等键。熔断(Circuit Breaker)在下游持续失败时暂时停止调用,并通过有限探测判断恢复,避免故障扩散。AWS 的重试设计文章提供了这些机制的工程背景。

在训练平台里,可以把任务创建做成带幂等键的普通 HTTPS 请求,把进度展示做成可从事件游标恢复的 SSE,把高频交互单独放在 WebSocket 上。这样每种连接都有清晰职责,不需要用一种实时协议承载所有操作。

关联与学习入口

API 设计 · 缓存 · 容量估算 · 模块导航

已通过现有登录会话核对 Hello Interview 的 Networking Essentials 书面章节。本页按请求路径重新组织,并补充规范解释和训练平台例子;不转录课程视频或测验。

API 设计

接口契约(API Contract)要明确谁能对哪些资源做什么、输入如何表达、结果与错误如何返回,以及网络重试会产生什么影响。下面用一个训练平台贯穿说明,重点是可实现的业务语义。

API 设计的主要决策

从资源与操作开始

先识别实验(Experiment)、任务(Training Job)和检查点(Checkpoint)。资源身份放在路径中,可选筛选放查询参数,创建或修改的内容放请求体:

POST /training-jobs
GET /training-jobs/job-42
GET /training-jobs?experiment_id=exp-7&state=running&limit=20
POST /training-jobs/job-42/cancellations

取消可以建模为取消请求资源,也可以使用明确的 RPC 操作。URL 是否“漂亮”不如取消究竟是同步完成、接受后异步执行,还是可能被重复提交重要。

方法与状态码表达什么

方法常见语义重试时要注意
GET读取资源,应当是安全操作。响应可能变化,但不应因此产生业务副作用。
POST创建资源或提交操作。默认不保证幂等,需要应用去重。
PUT在指定地址完整替换或创建资源。相同请求应有幂等效果。
PATCH局部修改。“设为某值”和“追加一次”具有不同幂等性质。
DELETE删除资源。最终状态可幂等,重复请求的状态码可以不同。

创建已经完成可返回 201 Created;只是接受了异步工作可返回 202 Accepted 和状态查询位置。400 表示输入问题,401 表示缺少有效身份,403 表示权限不足,409 表示资源状态冲突,429 表示请求受到限流。状态码只表达类别,业务错误还应有稳定的错误标识。

异步操作需要可观察的状态

任务创建接口可以立即返回任务编号、当前状态与 Location。之后查询返回 queued → running → succeeded/failed/cancelled 中的状态。取消请求已接受,不等于 GPU 工作进程已经停止。

{
  "id": "job-42",
  "state": "queued",
  "attempt": 1,
  "status_url": "/training-jobs/job-42"
}

状态和尝试编号应来自同一份受控数据。失败原因、是否可重试、结果位置也属于契约,不应让客户端从日志文字里猜测。

幂等键要和业务提交绑定

客户端在一次逻辑创建开始时生成幂等键(Idempotency Key),网络重试继续使用同一个键。服务端按调用者、接口和键记录请求摘要与处理结果;同键不同参数应返回冲突,不能悄悄复用旧结果。

最容易遗漏的是原子性:如果任务创建成功后,进程在保存去重结果前崩溃,重试仍可能创建第二个任务。可以在同一事务中保存幂等记录和任务记录,并通过唯一约束处理并发请求。进行中的重复请求、去重记录的保留期和过期后的语义都需要定义。

分页、排序与查询成本

偏移分页(Offset Pagination)适合稳定的小列表或需要按页跳转的界面,但大偏移可能扫描大量数据,列表变动也可能导致重复与漏读。游标分页(Cursor Pagination)保存排序边界,适合持续增长的数据。

WHERE owner_id = :owner
  AND (created_at, id) < (:last_time, :last_id)
ORDER BY created_at DESC, id DESC
LIMIT 20;

时间相同的记录需要唯一编号打破平局。游标还应绑定筛选条件和排序方向;游标分页本身不保证跨页快照一致性。服务端应限制 limit、允许的筛选字段与排序组合,以免接口暴露无法有效执行的任意查询。API 参数与底层索引要一起设计。

身份、授权和错误格式

认证(Authentication)回答“你是谁”,授权(Authorization)回答“能否操作这个资源”。即使 JWT 验证成功,读取 job-42 时仍应检查任务归属或团队权限,不能仅相信请求中的 owner_id。

错误响应使用稳定的机器标识和可读信息,例如 {"error":{"code":"JOB_ALREADY_TERMINAL","message":"Job cannot be cancelled"}}。避免返回内部堆栈或凭据。限流可按用户、租户和接口成本分别计算;重试提示必须和客户端的总截止时间一起考虑。

GraphQL、gRPC 与兼容演进

GraphQL 把数据形状的选择交给客户端,适合多个客户端访问重叠但不同的数据;后台要限制查询深度和成本、批量加载关联数据,并在解析器中执行资源级授权。一个 GraphQL 请求也可能触发许多数据库查询。

gRPC 用服务方法与消息类型表达契约,适合内部训练调度器和执行器通信。应明确截止时间、取消、流式响应和错误映射。选择二进制格式并不自动解决服务端计算或数据库瓶颈。

演进时,增加可选字段通常比改字段含义更容易兼容,但仍取决于客户端解析方式。删除字段、改变排序或错误语义都可能破坏客户端;版本号不能替代清晰的弃用和迁移规则。

关联与来源

网络基础 · 数据建模 · 索引 · 模块导航

学习入口:Hello Interview · API Design(已登录核对书面章节)。上面的训练任务接口、事务去重和查询示例为独立组织的讲解。

数据建模

数据模型不是只列几张表,而是把访问模式(Access Pattern)、业务不变量(Invariant)和数据生命周期转成可执行的结构。数据库选型、索引和分片都应从这些要求出发。

从查询到存储的建模路径

先写清读写与不变量

训练平台可能需要按用户列出实验、按实验查询最近任务、读取成功检查点,以及处理任务重试。不变量包括:实验归属明确;旧尝试不能覆盖新尝试的结果;只有写完并确认的检查点才可用于恢复。

这些约束比“使用 SQL 还是 NoSQL”更具体。先给出主要查询、排序、过滤、写入频率与数据规模,再判断哪些约束能由数据库直接维护,哪些需要应用协议。

实体、主键和关系

实验与任务通常是一对多,任务与检查点也是一对多;用户与团队可以通过关联表表达多对多。主键(Primary Key)选择稳定的系统标识,避免用可能修改的电子邮箱承担内部身份。自然键(Natural Key)仍可加唯一约束。

experiments(id PRIMARY KEY, owner_id, config_version, created_at)
jobs(id PRIMARY KEY, experiment_id, state, active_attempt, version, created_at)
job_attempts(job_id, attempt, worker_id, state, PRIMARY KEY(job_id, attempt))
checkpoints(id PRIMARY KEY, job_id, attempt, step, object_key, state)

这里把逻辑任务和执行尝试分开,同一任务重试不会丢掉先前执行历史。实际建表时还应添加外键、非空约束和必要的唯一约束,而不是让每个调用方自行记住规则。

不同数据模型改变了哪些操作

模型适合的访问要承担的代价
关系型(Relational)有明确关系、约束、事务和组合查询的数据。高负载下仍要处理索引、锁竞争和分布式扩展。
文档型(Document)经常整体读取、结构嵌套且可合理聚合的数据。无界数组、重复字段更新和跨文档一致性。
键值(Key-value)明确键查找,例如会话、配置或缓存。任意筛选和关联查询通常不是其强项。
宽列(Wide-column)围绕分区键、按排序键读取的大规模数据。需要提前设计查询模式,避免热分区。
图(Graph)路径遍历本身是核心工作负载的关系数据。多一套存储与查询复杂度,不能仅因“有关联”就选择。

产品名称不直接等于一致性或事务能力。应说明具体数据库提供哪些操作与保证,而不是声称某一整类数据库都不能做事务。

规范化与反规范化

规范化(Normalization)减少重复和更新异常,例如用户信息只存一份,任务保存 owner_id。反规范化(Denormalization)则针对实际读取成本增加冗余,例如在实验列表保存最近任务的摘要。

反规范化之后要回答三个问题:哪一份是事实源(Source of Truth)、由什么机制更新副本、失败后如何重建。异步物化视图(Materialized View)可以减轻读取成本,但会产生可见延迟和修复任务。历史快照中的“提交时配置”不一定是需要纠正的冗余,它可能是有意保留的业务事实。

用条件更新保护并发状态

ACID 的一致性并不意味着所有并发执行都会得到期望结果。隔离级别(Isolation Level)、锁与条件更新决定应用看到和修改什么状态。PostgreSQL 的隔离文档区分了这些行为。

UPDATE jobs
SET state = 'running', version = version + 1
WHERE id = :job_id AND state = 'queued' AND version = :expected_version;

受影响行数为零表示记录已变化,调用方不能假定领取成功。工作进程完成时还应验证尝试编号或栅栏令牌(Fencing Token),防止超时的旧工作进程覆盖新执行。

大对象与元数据的提交边界

权重、日志归档和数据集通常放对象存储,数据库保存位置、大小、校验和、版本和发布状态。对象存储与数据库通常不共享一个本地事务,因此“文件上传成功”和“元数据提交成功”必须分开处理。

可先把文件写入唯一的临时位置,校验完成后再提交可用状态;中途失败留下的对象通过垃圾回收清理。读取者只使用已发布的记录。对象版本、尝试编号和幂等发布有助于避免覆盖与重复登记。

索引、分片与生命周期一起考虑

“某实验最近任务”可以使用 (experiment_id, created_at, id) 索引;“某用户全部任务”可能需要另一种访问路径。以实验编号分片能保持局部查询,却可能让超大实验成为热点。

保留期限(Retention)、归档、逻辑删除、硬删除和审计记录也会影响模型。逻辑删除不等于存储已经回收;清理数据库记录与清理对象需要可重试流程和保留边界。模型应在这些情况下仍能说明每份数据由谁管理。

关联与来源

索引 · 分片 · CAP · 强化学习系统

学习入口:Hello Interview · Data Modeling(已登录核对书面章节)。任务、尝试与检查点模型为本页独立示例。

数据库索引

索引(Index)是一条额外维护的访问路径。它的价值是减少查询需要检查的数据、读取的数据页或执行的排序;代价是占用空间、缓存和写入维护资源。评价索引应从具体查询开始,而不是给每个字段都创建一个。

索引设计与验证

从数据页理解索引的收益

表数据以页组织,数据库把所需页读入内存再处理。没有可用索引时,可能需要扫描很多页;索引先缩小候选记录,再访问必要的表数据。缓存命中、顺序读取和随机读取的成本不同,因此不能把一次逻辑查找直接等同于一次物理磁盘操作。

返回整张表的大部分记录时,顺序扫描(Sequential Scan)可能比通过索引逐条回表更划算。查询优化器会综合选择性、统计信息、数据分布和成本选择执行计划。

B-tree 与复合索引

B-tree 通过有序的多分支结构支持等值、范围和排序。它的高度通常比较小,但真实延迟还取决于数据是否在缓存、是否回表和返回多少记录。

CREATE INDEX jobs_by_experiment_recent
ON jobs (experiment_id, created_at DESC, id DESC);

SELECT id, state, created_at
FROM jobs
WHERE experiment_id = 42
ORDER BY created_at DESC, id DESC
LIMIT 20;

这个顺序先定位实验,再沿目标顺序取记录。若查询改为只过滤时间,访问方式就不同。设计列序应依据等值条件、范围条件、排序和实际数据分布,不能只背“选择性最高的放第一列”。某些数据库能使用跳跃扫描等优化,最左前缀也不应被说成任何实现都绝对不能越过的规则。

覆盖、部分和表达式索引

覆盖索引(Covering Index)包含查询所需字段,可能减少回表。在 PostgreSQL 中,可以使用 INCLUDE (state) 存放返回列;能否真正执行高效的仅索引扫描(Index-only Scan),还取决于可见性信息等条件。

部分索引(Partial Index)只保存满足条件的记录,例如活跃任务。它适合小而重要的子集,但查询条件需要能匹配该条件。表达式索引(Expression Index)可以支持 lower(email) 等查询;仅对原字段建普通索引不意味着任意函数条件都能直接利用它。相关机制见 PostgreSQL 的索引文档。

LSM 的写入与合并

日志结构合并树(Log-structured Merge Tree,LSM)通常把写入先记录到写前日志(WAL)和内存结构,再刷新为有序磁盘文件(SSTable)。后台合并(Compaction)整理多个文件和旧版本。具体顺序与持久性以数据库配置为准。

这样可把部分随机更新转换成批量写入,但读取可能要检查多个层和文件;布隆过滤器(Bloom Filter)可跳过不可能包含某键的文件。合并带来额外读写和后台资源消耗。比较 B-tree 和 LSM 时,应同时讨论读放大、写放大、空间放大及尾延迟,不能把它们简化成“一个只读、一个只写”。

哈希、倒排与空间索引

结构主要解决的问题关键限制
哈希索引(Hash Index)根据完整键做等值定位。不保留一般排序关系,不能直接支持范围或有序扫描。
倒排索引(Inverted Index)把词项映射到包含它的文档集合。分词、相关性、更新可见性和索引维护都需要设计。
空间索引(Spatial Index)根据空间邻近和包围关系缩小候选。候选过滤后通常还需要精确几何判断。

Geohash 用空间网格编码位置,邻近区域可能跨编码边界,查询需要覆盖相邻格子。四叉树(Quadtree)递归细分二维区域;R-tree 家族用包围区域组织对象。PostGIS 可使用基于 GiST 的空间索引;“知道经纬度就给两列分别建普通索引”并不自动得到高效半径检索。

索引为什么会拖慢写入

新增、更新和删除可能同时修改多个索引,增加日志、页维护、缓存压力和存储。把经常变化的宽字段塞进覆盖索引尤其可能得不偿失。唯一索引还能参与约束检查,不能只按读取收益随意删除。

监测索引使用情况、维护成本和实际查询模式,比固定规定“每张表最多几个索引”更有意义。线上建索引的方法还要考虑锁、额外空间和失败后的清理。

用执行计划核实,而不是猜测

EXPLAIN 展示规划,EXPLAIN ANALYZE 会实际执行语句并报告观测结果;对写语句或昂贵查询不能把它当作无副作用的检查。

观察扫描方式、估算行数与实际行数的差距、过滤掉的行数、排序与临时文件、缓存命中和磁盘读取。若估计与实际差异很大,应先检查统计信息和数据倾斜。索引让一个查询更快,不代表整个系统在写入压力和冷缓存条件下也更快。

关联与来源

API 查询 · 数据模型 · 缓存 · 分片

学习入口:Hello Interview · Database Indexing(已登录核对书面章节)。本页围绕查询执行与维护成本独立组织,不复刻课程中的图表或示例。

缓存策略与失效

缓存(Cache)保存可以重复使用的数据或计算结果,用额外空间和一致性复杂度换取更低延迟、更少后端工作。设计起点是可测量的瓶颈与可接受的新鲜度,而不是在每个架构里先放一台 Redis。

旁路缓存的读取路径

放在哪一层,影响什么成本

位置主要收益主要代价
客户端或浏览器可以完全省去一次网络调用。客户端版本、容量和失效通知不容易统一控制。
CDN 边缘让可复用内容靠近用户,减轻源站流量。缓存键、权限隔离、区域副本与失效规则。
应用进程不需要访问远程缓存,延迟很低。每个实例各有副本,扩缩容和失效更分散。
共享缓存多个服务实例共用热点数据。增加网络依赖、节点容量与可用性管理。

公共文档、用户专属响应和带权限的任务日志不能无条件共用缓存键。缓存键不仅是资源编号,也可能需要租户、版本、查询参数或权限范围。

读取与写入模式

旁路缓存(Cache-aside)由应用先查缓存,未命中时访问数据库并回填。读穿(Read-through)则由缓存层或封装库负责回源,应用不必自己处理每次未命中。这是职责边界的区别,不是随便换一个 Redis 命令。

写穿(Write-through)在确认写入前同步更新持久层;写回(Write-back)先接受缓存写入,再异步刷入后端。后者可降低某些写入成本,但确认后的数据仍可能暴露在缓存丢失风险中。把应用独立写 Redis 和数据库两次,不会自动变成原子的写穿协议。

TTL 与淘汰解决不同问题

生存时间(TTL)描述何时过期;淘汰(Eviction)描述容量紧张时删除谁。LRU 偏向保留最近使用的数据,LFU 偏向保留高频数据,FIFO 根据进入顺序;实现可能使用近似策略。

选择策略要看热点持续多久、是否有一次性扫描和对象大小。TTL 也不是从业务修改时刻计算的天然陈旧度上限:旧读取可能在较晚时刻回填并重新开始计时。Redis 的策略与内存限制见官方淘汰说明。

数据库更新后,缓存怎样失效

常见旁路方案先提交数据库,再删除缓存,之后由读请求重新填充。它减少了显式双写的步骤,却并不提供跨数据库与缓存的原子性。

一个典型竞态是:请求 A 读到旧数据库值;请求 B 更新数据库并删缓存;A 随后把旧值写回缓存。仅说“更新后删缓存”没有消除这个窗口。可以根据业务需求使用版本化键、条件回填、变更事件驱动失效或更严格的读写协调,并明确失效失败后的补偿与 TTL 兜底。

对于要求精确余额、库存或配额的最终决策,缓存通常不应充当未经校验的事实源。能容忍几秒陈旧的展示数据则可能适合更简单的策略。

击穿、穿透、热点与整体故障

现象根因常见处理
热键到期后大量请求回源(Stampede)同一个结果被并发重建。Single-flight 合并回源、提前刷新、允许受控旧值。
不存在的键反复回源未命中结果也有高请求量。短时负缓存;适合时用布隆过滤器,但要处理误报与更新。
大量键同时过期生命周期高度同步。TTL 随机抖动、分批预热、限制重建并发。
单个热键压满节点热度集中,和键数量是否均匀无关。进程缓存、读取副本或业务拆分;另行处理一致性。
缓存服务不可用所有请求同时落回数据库。回源限流、并发上限、降级与熔断。

“缓存故障就直接访问数据库”只有在数据库仍有足够余量时才安全。故障策略需要和后端容量一起设计。

命中率如何变成后端负载

假设读取流量为 12,000 次/秒,请求命中率为 95%,理想稳态下回源约为 600 次/秒。缓存失效时可能重新接近 12,000 次/秒,远大于正常后端流量。这个算式还未考虑请求合并、多键查询和额外刷新。

平均命中率也会掩盖尾延迟:少数未命中请求仍可能很慢。应同时监控请求命中率、字节命中率、回源率、p95/p99、淘汰量、内存占用和热点分布。不能把命中和未命中的 p99 简单加权成系统 p99。

训练平台里的具体落点

已结束任务的不可变摘要、版本化配置和公开模型说明适合缓存。正在运行的进度需要明确刷新周期;故障恢复和配额分配应以受控状态为准。把尝试编号加入键,可以避免重试前后的状态互相覆盖;给缓存条目附带生成时间,也能帮助展示与排障区分新旧数据。

关联与来源

数据模型 · 一致性 · 容量估算

学习入口:Hello Interview · Caching(已登录核对书面章节)。本页以新鲜度、失效竞态和故障流量独立组织说明。

数据分片

分片(Sharding)把一份逻辑数据集分布到多台机器,目的是扩展容量或分担负载。它不只是路由公式,还会改变事务、查询、迁移和运维的边界。

分片键通过路由映射到不同分片

分区、分片与复制的区别

单实例表分区(Partitioning)把表拆成较小的管理单元,可以帮助分区裁剪、归档和维护,但不一定增加机器。分片通常把子集放到不同机器。复制(Replication)给同一份数据增加副本,主要服务于容错或特定读取扩展。

三者可以同时存在:每个分片有副本,每个数据库内部也可以分区。不能因为增加了读副本,就认为单个写入主节点的热点已经被解决。

判断是否值得承担分布式复杂度

观察限制来自存储、IO、CPU、写日志、锁竞争,还是单个热点。查询和索引调整、连接池、批处理、纵向扩容、缓存或读副本可能已经足够。

只有当目标负载、增长、恢复时间或地域约束确实超出单机方案时,再引入分片。某个固定 GB 或 QPS 数值不是适用于所有数据库的分片门槛。容量之外,备份、恢复和迁移时间也可能是约束。

先选键,再选分布规则

分片键(Shard Key)决定数据的归属单元。好的键既能分散数据量与访问量,也能让常用操作落在少数分片。键的基数(Cardinality)很高不代表流量均匀;某个实验仍可能独占大部分写入。

规则优点代价
范围(Range)范围查询和相邻数据管理直观。单调增长的时间或编号可能把新写入集中到末端。
哈希(Hash)通常更容易分散大量不同键。失去范围局部性,扩容方式需要额外设计。
目录(Directory)显式映射可以迁移大租户并调整放置。路由元数据需要高可用、缓存和版本管理。

AWS 的分区键设计说明强调活动量分布,而不只是记录数量。

热点需要改变负载单位

如果 experiment_id=42 贡献了一半写流量,对这个编号再做均匀哈希也只会得到一个结果。可把日志分成 (experiment_id, time_bucket, subshard),让一个大实验拥有多个可独立路由的写入单元。

代价是查询一个实验时需要读取多个分片并合并。子分片数量、时间桶边界和路由元数据应能被查询端发现;盲目加随机后缀却没有读取计划,会让写入变快、读取失控。

跨分片读取与事务

跨分片查询需要扇出(Fan-out)和结果聚合。全局最近 20 条可以让各分片返回局部候选再归并,但深分页、过滤和某个分片超时会使语义更复杂。二级索引可以另建访问路径,却需要讨论更新延迟与一致性。

跨分片事务可能使用分布式提交协议;也可以重新安排数据归属,使关键不变量留在一个事务边界内。Saga 等补偿流程适合可撤销的业务步骤,但不等价于单个原子事务。全局唯一编号也不自动保证全局业务唯一性。

在线扩容是一段迁移协议

一种迁移思路是:准备目标分片 → 搬迁存量快照 → 追赶增量变化 → 校验 → 切换路由版本 → 保留回滚窗口 → 清理旧副本。不同数据库会采用不同协议,但每一步都要明确读写由谁负责。

直接复制数据后立刻改路由,可能漏掉复制期间的新写入。没有协调规则的双写也可能只写成功一侧。迁移期间需要处理重复、乱序、墓碑(Tombstone)与旧路由请求,并通过写入版本或路由代次防止旧节点继续承诺写入。

托管分片仍然需要数据建模

数据库可以替你实现物理拆分和再平衡,但不能替你选择正确的访问单元。热点键、跨分区事务和二级索引仍然可能决定成本与性能。也不能假定所有托管数据库都使用相同的哈希环算法;应以产品文档描述其放置和路由机制。

关联与来源

数据模型 · 一致性哈希 · CAP · 容量估算

学习入口:Hello Interview · Sharding(已登录核对书面章节)。迁移步骤与训练日志例子是独立的工程推导。

一致性哈希

一致性哈希(Consistent Hashing)解决的是节点集合变化时,如何减少键的重新分配。它是一种放置与路由方法,不负责让多个副本自动达成一致,也不替代持久化、复制或故障恢复。

从键到哈希环和归属节点

取模路由为什么不利于直接扩容

固定数量节点时,hash(key) % N 简单而有效。但从 N 个节点改成 N+1 个节点,相当于改变大量键的路由规则。对缓存来说可能产生大面积未命中;对持久化存储来说,则需要搬迁和兼容旧位置。

问题不在于取模运算本身,而在于让物理节点数量直接参与键的归属计算。固定逻辑分区再映射到物理节点,是另一种可以降低这种耦合的方法。

哈希环怎样定位数据

把哈希空间首尾连接成环,将节点和键都映射到环上的位置。常见规则是从键的位置顺时针找到第一个节点,将其作为归属节点;超过最大位置则绕回开头。

假设环上位置为 A=10, B=50, C=90:键 30 归 B,键 70 归 C,键 95 绕回归 A。加入 D=35 后,原来归 B 的区间 (10,35] 转给 D,其他区间不因这次插入而改变。这个例子使用简化的整数位置,只用于说明归属规则。

旧位置:10(A) ---- 30(key) -------- 50(B) -------- 90(C)
新位置:10(A) ---- 30(key) -- 35(D) -- 50(B) ----- 90(C)

理想均匀分布、节点等权时,增加一个节点平均大约接管 1/(N+1) 的键。这是关于分布和期望的近似,不代表每次扩容都恰好迁移这个比例,也不代表字节数和流量同样均衡。

虚拟节点改善什么

若每台机器只有一个位置,某台机器退出后可能让它的后继承担过多数据。虚拟节点(Virtual Node)让同一台物理机器拥有多个分散位置,把接管区间分散给更多机器。更强的机器可以配置更多位置,表达权重。

代价是更多路由元数据、区间管理和迁移任务。虚拟节点改善统计分布,不能把一个超热键拆成多份;键大小差异很大时,按键数平衡也不等于内存平衡。

路由还需要成员与版本协议

客户端、代理或服务端需要知道当前节点集合及环版本。节点加入、退出和故障检测会改变视图;如果不同请求使用不同版本,同一个键可能被发往不同位置。

迁移期间可以转发旧路由请求、提供重定向,或在受控阶段读取新旧位置。写入必须有明确的所有权和切换边界。单靠本地超时就把节点从环中移除,可能把网络分区误判成节点消失,从而造成多个写入方。

放置算法与复制恢复是两层问题

环决定“应该在哪里”,复制决定“还有哪些副本”。选择副本时,要区分不同物理机器、机架和可用区,不能把同一机器上的多个虚拟节点误当独立容灾副本。

缓存节点失败时可以从事实源重新构建;持久数据需要已存在的副本或恢复来源。扩容时的数据搬迁则要追踪存量与增量,并验证切换后的完整性。这些步骤不会因为使用了哈希环而自动完成。

热点与其他放置方案

热键可以使用进程缓存、读取复制、应用拆分或限流;每种方法都需要独立的一致性与失效策略。Rendezvous Hashing 等方法也能在成员变化时减少重映射,不能把“减少迁移”限定为只有环能实现。

Redis Cluster 是很好的反例:它用固定的 16,384 个哈希槽(Hash Slot)映射到节点,扩容时迁移槽,而不是直接使用这里画出的虚拟节点哈希环。Redis Cluster 规范说明了槽位和重定向机制。讨论具体产品时,应区分算法思想与实际实现。

关联与来源

分片 · 缓存 · CAP

学习入口:Hello Interview · Consistent Hashing(已登录核对书面章节)。整数环例子和路由版本说明为独立讲解。

CAP 与一致性取舍

CAP 用来解释分布式数据在网络分区时不能同时满足的一组保证。它最有用的地方,是帮助我们把“出故障时怎样处理读写”讲清楚,而不是给整个产品贴一个 CP 或 AP 标签。

根据业务不变量选择分区期间的行为

先准确理解三个词

一致性(Consistency)在 CAP 的常见形式中指线性一致性(Linearizability):操作看起来像在调用与返回之间的某个时刻生效,并尊重真实时间先后。如果一次写已经返回成功,之后发起的读取不能返回被它覆盖的旧值。

可用性(Availability)要求非故障节点接收到的请求最终得到相应的操作结果;让节点一直等或一律报错,并不能满足这个要求。它不是月度 99.9% 可用率,也不直接给出固定的延迟上限。

分区(Partition)指节点之间的通信可能中断或消息被持续丢弃。工程上不能通过口头选择“不要 P”来排除网络隔离。网络没有分区时,CAP 也不要求系统主动放弃一致性或可用性。

两个区域断连时的具体矛盾

假设美国和欧洲各有一个 GPU 配额副本,初始都显示剩余 1。断连之后,两边各收到一次分配请求。如果两边都立即承诺成功,就可能承诺了两份资源;如果欧洲无法确认最新状态而拒绝或等待,它就牺牲了这部分操作在分区期间的可用性。

一致性优先并不意味着所有节点、所有功能全部停止。有多数派协议的系统可能继续在能形成多数派的一侧处理写入,而隔离少数派停止承诺;这一行为仍取决于协议、故障假设和读路径。不能只在架构图上画一个 Leader 就宣称强一致。

按操作选择,而不是按公司或数据库类型选择

操作需要维护的约束分区时可能的策略
分配最后一份 GPU 配额不能重复承诺同一份资源。只允许授权写入方提交,其他请求失败或等待。
展示训练进度可以容忍短暂落后。返回已知进度,并表达时间或版本。
浏览公开模型介绍可接受旧内容。继续读本地副本,恢复通信后更新。
发布可恢复检查点不得把未完成对象标为可用。由受控提交路径决定可见状态。

“涉及资金就整个系统强一致”过于粗糙。真正要描述的是哪些记录、哪些读写和哪些不变量不能被破坏,以及故障时允许哪些操作继续。

几种一致性保证不能混为一谈

线性一致性关注单个对象或规定范围内操作的实时顺序;可串行化(Serializability)关注多个事务的效果是否等价于某种串行执行,两者并不自动互相推出。严格可串行化(Strict Serializability)再加入真实时间约束。

读己之写(Read-your-writes)保证会话能看到自己已完成的写;单调读(Monotonic Reads)避免同一会话倒退。它们不等于全局线性一致。最终一致性(Eventual Consistency)要求在停止新写入并满足通信与修复等条件后收敛,不自动承诺几秒内完成,也不规定冲突如何解决。

ACID 中的一致性是数据库约束与合法状态的概念,不是 CAP 里的同一个 C。SQL、NoSQL、事务和复制这些词,也都不能单独证明跨区域的端到端保证。

复制、Quorum 与读取路径

同步复制增加确认前的协调;异步复制允许更快返回,但读副本可能落后。读请求是否经过最新 Leader、是否读取已提交版本,以及故障切换是否可能丢失已确认写入,都会影响用户看到的保证。

读写 Quorum 满足 R + W > N 可以让集合相交,但集合相交本身并不是线性一致性的完整证明。并发写、版本选择、失败写入、成员变更和故障恢复仍需要正确的协议。

不同访问路径也可能有不同语义。例如 DynamoDB 文档区分表、局部二级索引与全局二级索引的读取保证。不能因为主表支持强一致读取,就推断所有查询入口都一样。

没有分区时,延迟也有代价

PACELC 强调:发生分区时讨论可用性与一致性;正常通信时仍可能在延迟(Latency)与一致性之间付出协调成本。跨洲确认通常比本地副本读取需要更多网络等待,但具体保证取决于实现,不能只靠地理距离给系统分类。

从接口到客户端的完整路径都要保持约定:如果数据库读是强一致的,但前面返回旧缓存,用户看到的接口仍然可能是陈旧的。设计讨论应把缓存、会话、复制和故障切换放在一起。

关联与来源

缓存 · 数据建模 · 分片

学习入口:Hello Interview · CAP Theorem(已登录核对书面章节)。本页用配额分配与具体读路径解释语义,不把定理简化成任何时候任选两个。

容量估算与数量级

容量估算(Capacity Estimation)用于支持一个架构决策:单机能否承担、缓存是否必要、存储保留多久、失去一个区域后是否仍有余量。数字应来自明确假设与测量,不能把某次厂商跑分背成通用上限。

从负载假设走向峰值与余量

先把问题转换成负载

日活用户(DAU)不等于同时在线用户,也不直接等于每秒请求数。先估计每个用户每天的操作次数,再区分每次操作触发多少服务调用、数据库读取、写入或消息。

平均请求/秒 = 每日操作数 / 86,400
峰值请求/秒 = 平均请求/秒 × 明确假设的峰值系数
后端读取/秒 ≈ 请求/秒 × 每请求读取次数 × 未命中率

峰值系数不是行业常数,应考虑时区、定时任务、事件爆发和租户倾斜。扇出(Fan-out)、重试和后台任务会让内部流量高于外部请求量。

一个完整的训练日志估算

假设每天 1,000 万条日志,每条 2 KB,使用十进制单位,峰值为平均的 10 倍。这些数字是讲解假设,不是实测结果。

项目算式结果
平均写入10,000,000 / 86,400约 116 条/秒。
峰值写入116 × 10约 1,160 条/秒。
每日原始数据10,000,000 × 2,000 B20 GB/天。
30 天原始保留20 × 30600 GB。
三副本原始数据600 × 31.8 TB。
峰值有效载荷带宽1,160 × 2,000 B/s × 8约 18.6 Mb/s。

这还没有包括索引、对象元数据、协议头、复制流量、备份和压缩。三副本也不等于拥有三份独立历史备份:误删可能同步复制到所有副本。

延迟、吞吐与并发的关系

延迟(Latency)是一个请求所花的时间;吞吐(Throughput)是一段时间内完成的工作量;并发(Concurrency)是在系统中同时存在的工作数量。三者不能直接互换。

稳定系统里的利特尔定律(Little’s Law)使用平均值:平均在途数 = 平均到达率 × 平均停留时间。例如 2,000 请求/秒、平均停留 0.1 秒,对应约 200 个在途请求。不能用 p99 替换平均值,也不能把长期不稳定、队列持续增长的状态当作稳态。

端到端 p99 也不能简单相加成各组件 p99 之和;多个依赖的扇出、相关故障和排队会改变尾部。应给各阶段分配延迟预算,再通过端到端观测核实。

资源维度要分别计算

CPU 要看每次请求的计算成本和并行效率;内存要看常驻数据、连接缓冲与对象开销;磁盘要看容量、IOPS、带宽和日志持久化;网络要看请求体、响应体、复制和跨区流量。

假设每个活跃连接平均占 32 KiB 内存,10 万连接仅该部分就约 3.05 GiB。这个结果来自假设,不代表某种服务器的固定连接开销;TLS、应用对象和内核状态可能另计。带宽上限也不等于小请求吞吐上限,后者可能受 CPU 或包处理限制。

为什么不能记死数据库或缓存的 QPS

相同硬件上,单键读取、复杂 JOIN、大事务、同步持久化和大对象返回的成本不同。索引数量、数据是否在内存、连接数、批量大小和锁竞争都会改变上限。

一次有效测量需要说明数据规模、请求分布、读写比、对象大小、持久性、缓存状态、延迟目标与错误率。容量应取满足目标延迟和错误率时的可持续吞吐,而不是短时间内把系统压到崩溃前的最高值。

预留故障与恢复的余量

正常情况下刚好够用的集群,可能无法承担单节点或单可用区故障。容量规划应按允许的故障情景计算剩余能力,还要预留重新复制、缓存预热、积压清理和部署期间的资源。

队列也只是把时间和容量问题推迟。若进入队列为 1,500 条/秒、处理为 1,200 条/秒,积压每秒增长 300 条。恢复后必须让处理速率超过新增速率,才有机会清空;清空时间近似为 积压量 / (处理率 - 新增率),同样需要稳定负载假设。

用估算推动选择

先找最紧的资源,再比较小范围改动:减少查询、优化索引、批处理或增加单机资源。只有测量和增长预测显示这些不足时,才讨论缓存、异步化或分片。

如果不确定某个参数,可以计算两个情景,例如记录大小翻倍、峰值系数从 10 变 20。观察哪个假设改变了设计结论,比报出许多没有用途的数字更有说服力。云价格变化较快,真实成本比较需要按实际区域和配置重新查价。

关联与来源

索引 · 缓存 · 分片 · 强化学习系统

学习入口:Hello Interview · Numbers to Know(已登录核对书面章节)。本页的负载、连接和积压数字都是明确假设下的独立算例,不当作厂商性能承诺。

Core Concepts 全章导航

这里是九篇可连续阅读的主题讲解。所有正文直接平铺,不需要点击展开,也不包含自测或测验。每章解释概念、工作机制、适用场景和代价,并用具体例子连接设计决策。

章节正文内容
网络基础请求路径、分层与协议、实时通信、负载均衡、区域化与故障恢复。
API 设计资源契约、异步操作、幂等、分页、授权与兼容演进。
数据建模访问模式、实体关系、约束、并发状态、对象存储与生命周期。
数据库索引数据页、B-tree 与 LSM、复合和覆盖索引、执行计划与维护成本。
缓存策略与失效缓存位置、读写模式、新鲜度、失效竞态、热点与故障回源。
数据分片分片键、放置规则、热点、跨分片操作和在线迁移。
一致性哈希取模重映射、哈希环、虚拟节点、成员版本与复制边界。
CAP 与一致性取舍分区下的读写行为、不同一致性模型和端到端读取语义。
容量估算与数量级请求与数据量、带宽、并发、资源限制、队列与故障余量。

阅读顺序

网络与 API → 数据模型与索引 → 缓存 → 分片与一致性哈希 → CAP → 容量估算。这个顺序先讲一条请求如何执行,再讨论如何扩展和处理故障;也可以直接按左侧链接进入需要的主题。

图示与离线阅读

每章正文内附有可直接预览的 SVG。系统设计交互总览可下载为独立 HTML;完整阅读包包含全部中英文正文、图示和 Obsidian 笔记。

阅读依据

已通过现有登录会话核对 Hello Interview 的九个书面主题。本站按系统问题重新组织讲解,并引用相关规范、官方文档与独立算例;没有转录课程视频或测验。其他 Patterns、Key Technologies 和设计题不属于本组九篇的范围。

Hello Interview 课程目录 · 返回系统设计模块

AI 辅助工程实战

用 AI 完成可验证的工程交付,练习上下文、调试、评审与验收。

复习方法

每次选一个问题,先脱稿讲解,再补笔记。记录依据、尚未验证的假设和下一次复习时间。

熟练度:待复习 → 能解释 → 能独立完成 → 能应对追问。

本模块资料

实战交付与验收清单

一次练习的完整闭环

需求澄清 → 最小实现 → 工具验证 → 人工评审 → 复盘。先定义验收条件(Acceptance Criteria),再让 AI 拆解任务。

  • 上下文(Context):输入、输出、已有接口、运行环境、不可改变的约束。
  • 工具(Tools):文件搜索、运行测试、检查日志与查看差异。
  • 调试(Debugging):复现 → 缩小范围 → 提出假设 → 验证 → 修复。
  • 评审(Review):正确性、失败路径、依赖、凭据处理与可维护性。
  • 证据(Evidence):实际运行结果、尚未覆盖的边界和下一步。

练习记录

任务时间限制验收条件AI 的错误我的修正验证结果

API 设计 · 项目深挖 · 模块导航

强化学习与训练系统

连接算法目标、数据流与训练基础设施,定位吞吐、稳定性和评估问题。

复习方法

每次选一个问题,先脱稿讲解,再补笔记。记录依据、尚未验证的假设和下一次复习时间。

熟练度:待复习 → 能解释 → 能独立完成 → 能应对追问。

本模块资料

强化学习系统知识地图

本页是待填充的复习框架,不代表已有项目经历或已掌握程度。

维度需要回答的问题
目标与算法(Objective / Algorithm)优化什么目标?优势估计、裁剪、KL 约束如何影响训练?
数据流(Data Flow)提示词 → 采样(Rollout)→ 奖励(Reward)→ 训练批次如何流转?
系统执行(Execution)训练与推理资源如何分配?同步和异步各有什么代价?
性能(Performance)吞吐、GPU 利用率、长尾、显存、通信分别怎么测?
稳定性(Stability)旧策略数据、版本错配、数值异常、奖励投机怎样发现?
恢复(Recovery)检查点、重试、去重与可复现性需要保存什么?
评估(Evaluation)怎样区分奖励提升、泛化改善和评估污染?

每个知识点的答题模板

定义 → 数学目标或数据流 → 系统约束 → 失败模式 → 可测量证据。

容量估算 · 数据建模 · 项目深挖 · 模块导航

公司与岗位研究

把公开证据整理为岗位匹配、技术判断和高质量反问。

复习方法

每次选一个问题,先脱稿讲解,再补笔记。记录依据、尚未验证的假设和下一次复习时间。

熟练度:待复习 → 能解释 → 能独立完成 → 能应对追问。

本模块资料

公司与岗位调研模板

基本信息

公司、岗位、级别、团队、面试日期:待补充。

证据表

判断公开来源链接发布日期核对日期事实或推断对岗位的意义

优先使用招聘说明(Job Description)、工程博客(Engineering Blog)、论文、公开代码和官方产品材料。变化较快的信息在面试前重新核对。

形成面试观点

  • 团队解决什么问题?成功指标(Success Metric)是什么?
  • 我的哪个项目能对应其技术挑战?证据是否足够?
  • 准备三个有依据的反问,避免猜测未公开的内部架构。

项目深挖模板 · 模块导航

项目复盘与技术深挖

用真实证据解释个人贡献、关键决策、结果与失败后的改进。

复习方法

每次选一个问题,先脱稿讲解,再补笔记。记录依据、尚未验证的假设和下一次复习时间。

熟练度:待复习 → 能解释 → 能独立完成 → 能应对追问。

本模块资料

项目深挖模板

不填造经历、数据或贡献;以下均待实际材料补充。

90 秒介绍

问题与背景 → 我的责任 → 关键技术决策 → 可验证结果 → 最重要的反思。

技术证据

维度需要补充的材料
范围(Scope)我做了什么、团队做了什么、哪些没有做。
架构(Architecture)数据流、接口、存储、依赖和部署边界。
决策(Trade-off)候选方案、约束、选择依据和放弃原因。
结果(Outcome)基线、测量方法、样本规模、误差与实际指标。
故障(Failure)复现条件、根因、修复、如何避免复发。
深挖(Follow-up)规模十倍、节点故障、数据陈旧时怎样调整。

追问演练

为什么是你提出的方案?最难的技术点是什么?如果重做,哪一项选择会改变?如何证明结果来自你的改动?

系统设计 · 强化学习系统 · 公司研究 · 模块导航