个人学习笔记INTERVIEW / 105Q

AUTHORED_MARKDOWN / 2026-08-11

AI + 全栈开发面试前高频精挑题

105 道高频问题,按“结论、原理、取舍、项目落点”组织,用来训练能解释工程决策的回答,而不是背诵术语。

.MD
字符
21,775
标题节点
124
预计阅读
44 分钟
内容状态
持续整理

AI + 全栈开发面试前高频精挑题

定位:面试前最后 1~3 天使用的核心题库。只保留最容易被问、最能体现理解深度、最容易结合项目追问的题目。

技术栈边界:前端以 React + TypeScript + Next.js 为主,后端覆盖 Node.js、Python/FastAPI、Go、Java SE,AI 覆盖 LLM、RAG、Agent、MCP/A2A、LoRA/QLoRA 与模型部署

回答原则:先说结论,再说机制;最后补充一个取舍、一个故障场景或一个项目落点。不要只背名词。

目录

0. 使用方法与回答模板

面试前怎么刷

  1. **第一遍:**只看问题,强制自己在 30~60 秒内说出结论。
  2. **第二遍:**补上原理、边界条件和一个真实项目例子。
  3. **第三遍:**只看带 P0 的题目;如果时间允许,再看 P1
  4. 每道题都追问自己:“如果线上出问题,我怎样定位?”这比单纯背定义更接近真实面试。

通用回答模板

结论 → 原理 → 取舍 → 项目落点

  • 结论:先用一句话回答“是什么、为什么这样做”。
  • 原理:讲关键链路,不要把所有实现细节都倒出来。
  • 取舍:说明什么时候不用它,以及替代方案的代价。
  • 项目落点:说明你在项目里如何使用、遇到什么问题、如何验证效果。

高频追问模板

  • 为什么这样设计?有没有更简单的方案?
  • 数据量、并发量、上下文长度或错误率变大后怎么办?
  • 失败时如何重试?如何避免重复执行?
  • 你怎样证明优化有效?看哪些指标?
  • 这个方案的安全边界在哪里?

1. 浏览器、JavaScript、TypeScript、React、Next.js

Q001(P0)浏览器输入 URL 后发生了什么?

**答:**大致链路是:解析 URL → 查缓存 → DNS → 建立 TCP/TLS → 发送 HTTP 请求 → 服务端处理 → 接收 HTML/CSS/JS/图片 → 解析 DOM/CSSOM → 生成渲染树 → Layout → Paint → Composite。实际项目中还要考虑 CDN、Service Worker、HTTP 缓存、预加载和 React/Next.js 的渲染阶段。

**面试加分点:**不要把“页面显示出来”只归因于后端返回 HTML;浏览器渲染、脚本执行、网络并发和资源优先级都会影响首屏。

Q002(P0)重排、重绘、合成有什么区别?如何优化?

答:

  • 重排(Layout):几何尺寸或位置变化,需要重新计算布局,影响面通常较大。
  • 重绘(Paint):颜色、阴影等视觉变化,不一定重新计算布局。
  • 合成(Composite):把已经绘制好的图层重新合成,适合处理某些 transformopacity 动画。

**优化:**批量修改 DOM、避免循环中反复读写布局属性、使用 transform/opacity 做动画、减少复杂选择器和大范围布局依赖。不要机械地给所有元素加 will-change,它会增加内存和合成层管理成本。

Q003(P0)强缓存和协商缓存如何工作?

**答:**强缓存命中时浏览器直接使用本地资源,常见响应头是 Cache-Control: max-age=...。需要向服务端确认时使用协商缓存,常见组合是 ETag/If-None-MatchLast-Modified/If-Modified-Since;未修改时服务端返回 304

**实际策略:**带内容哈希的 JS/CSS 可以长时间强缓存;HTML 通常要更短或必须重新验证。更新静态资源时依靠文件名哈希避免旧资源和新 HTML 不匹配。

Q004(P0)JavaScript 事件循环、宏任务和微任务是什么关系?

**答:**JavaScript 主线程一次执行一个任务。当前同步代码执行完后,会优先清空微任务队列(如 Promise.thenqueueMicrotask),再进入下一个宏任务(如定时器、I/O、用户事件)。微任务如果不断追加,会饿死渲染和宏任务,所以不能把大量工作无边界地塞进微任务。

**常见追问:**setTimeout(fn, 0) 不等于立刻执行;它至少要等当前调用栈、微任务和调度条件满足后才可能执行。

Q005(P0)Promise.allallSettledraceany 如何选择?

答:

  • Promise.all:全部成功才成功,一个失败就失败;适合有强依赖的并行任务。
  • Promise.allSettled:等待全部结束并收集每个结果;适合批量任务、部分成功可接受的场景。
  • Promise.race:第一个 settled 的结果决定整体;常用于超时控制,但要配合取消底层请求。
  • Promise.any:第一个成功的结果决定整体;适合多副本或多模型兜底。

**关键点:**Promise 的失败不会自动取消已经发出的网络请求;需要 AbortController 或业务层取消协议。

Q006(P0)闭包、this 和原型链最容易错在哪里?

**答:**闭包是函数保存对外部词法环境的引用,因此可以实现私有状态,但也可能因为长期持有对象而造成内存无法及时回收。普通函数的 this 由调用方式决定;箭头函数没有自己的 this,取定义时外层的 this。属性查找找不到自身属性时才沿原型链向上查找。

**易错点:**不要把“箭头函数不能改变 this”理解成所有场景都不能调用;它只是没有自己的 thiscall/apply/bind 不能改它捕获到的外层绑定。

Q007(P0)TypeScript 中 anyunknownnever 的区别是什么?

**答:**any 关闭类型检查,短期方便但会把错误推迟到运行时;unknown 表示未知值,使用前必须通过类型缩小或校验;never 表示不可能出现的值,常用于永不返回的函数和穷尽性检查。外部输入、接口响应和 catch 错误更适合从 unknown 开始,再用 schema 校验收窄类型。

**面试加分点:**TypeScript 只在编译期提供约束,不能替代运行时校验;用户输入和后端响应仍需要 Zod、Pydantic 等运行时 schema。

Q008(P0)React 组件重新渲染的触发条件和基本过程是什么?

**答:**组件首次挂载或自身 state 更新、父组件重新渲染、订阅的 context/store 变化时可能重新渲染。React 会执行组件函数得到新的 React element tree,再通过 reconciliation 比较新旧树,最后在 commit 阶段把必要变更提交到 DOM。重新渲染不等于每次都真实修改 DOM。

**易错点:**父组件渲染时子组件通常也会重新计算;是否真正需要优化,要结合子组件计算成本和 props 引用稳定性判断,而不是见到渲染就认为是 bug。

Q009(P0)React state 为什么推荐函数式更新?批处理会带来什么影响?

**答:**React 会批量合并同一事件或调度周期内的更新,连续使用旧闭包值可能得到错误结果。依赖前一个 state 时使用函数式更新,例如 setCount(previous => previous + 1),让 React 基于最新排队值计算。对象和数组要使用不可变更新,避免直接修改旧引用导致比较和调试失真。

**追问方向:**异步回调里的闭包可能拿到旧 state;可以使用函数式更新、正确依赖、useRef 保存最新可变值,或重新设计状态边界。

Q010(P0)useEffect 应该怎么理解?为什么会出现重复请求和旧闭包?

**答:**useEffect 用来同步 React 与外部系统,例如订阅、计时器、网络请求或 DOM API;它不是“组件生命周期万能替代品”。依赖数组描述 effect 读取的外部值,清理函数要取消订阅、清除计时器或中止请求。依赖遗漏会形成 stale closure,开发模式下的额外执行则可能暴露不安全的副作用。

**实践:**请求要有取消或过期判断,避免旧请求覆盖新查询;如果只是根据 props 计算值,优先在 render 中计算,不要为了计算派生值再加一个 effect。

Q011(P0)React 列表中的 key 为什么不能随便使用数组下标?

**答:**key 用于标识跨渲染仍然是同一个逻辑节点。使用稳定、唯一、来自业务实体的 ID,React 才能正确复用组件状态。列表中间插入、删除或排序时使用下标会让状态错位,表现为输入框、动画或选中状态跑到别的行。

**原则:**key 需要在同一列表的同级节点中稳定;不要把随机数作为 key,否则每次都会被视为新节点。

Q012(P0)受控组件和非受控组件怎么选?

**答:**受控组件的值由 React state 驱动,校验、联动和提交逻辑清晰,但高频输入可能带来更多渲染;非受控组件由 DOM 自己保存值,通过 refFormData 读取,适合简单表单或超大表单场景。文件上传通常依赖非受控方式,因为浏览器不允许随意设置文件输入值。

Q013(P0)useMemouseCallbackuseRef 分别解决什么问题?

**答:**useMemo 缓存计算结果,useCallback 缓存函数引用,二者都是性能优化工具,不是正确性工具;useRef 保存跨渲染持久化的可变容器,修改 ref.current 不会触发渲染,适合 DOM 引用、定时器句柄和最新值镜像。

**易错点:**缓存本身有依赖比较和内存成本;如果计算很轻或子组件没有引用比较,盲目使用反而增加复杂度。

Q014(P0)React 页面卡顿通常如何定位和优化?

**答:**先用 React Profiler 和浏览器 Performance 判断是 JS 计算、组件渲染、布局绘制、网络还是大列表导致,再针对性处理:拆分状态边界、稳定必要的 props、避免昂贵计算、虚拟化长列表、懒加载、代码分割、缓存请求、减少无效 effect。优化后要用渲染次数、主线程耗时、交互延迟和真实用户指标验证。

Q015(P0)Next.js 中 CSR、SSR、SSG、ISR 如何选择?

**答:**CSR 主要在浏览器取数据并渲染,交互灵活但首屏和 SEO 依赖客户端;SSR 每次请求生成 HTML,数据新鲜但服务端成本更高;SSG 构建时生成,速度快但内容更新需要重新构建;ISR 在静态页面基础上按时间或事件重新验证。选择依据是数据新鲜度、SEO、交互复杂度和缓存成本,而不是追求某一种渲染模式。

**补充:**Next.js 的 Server/Client Component 边界要清晰:服务器侧适合取数据和减少浏览器 JS,依赖浏览器 API、事件处理或交互状态的部分放到客户端。

2. HTTP、后端、认证授权与安全

Q016(P0)HTTP 常见方法、状态码和幂等性怎么回答?

**答:**GET 读取,POST 通常创建或触发动作,PUT 语义上是整体替换,PATCH 是部分更新,DELETE 删除。2xx 表示成功,3xx 表示重定向,4xx 通常是客户端请求问题,5xx 通常是服务端或上游问题。幂等性指同一请求执行一次或多次,最终效果相同;GET、PUT、DELETE 通常按语义设计为幂等,POST 默认不是。

**注意:**幂等不代表每次响应完全相同,也不代表请求不会产生副作用;它是业务语义和接口实现共同保证的属性。

Q017(P0)TCP、TLS、HTTPS 的关系是什么?

**答:**TCP 提供可靠、有序的字节流和拥塞控制;TLS 在传输层之上提供加密、完整性和服务端身份认证;HTTPS 是 HTTP 通过 TLS 在网络上传输。TLS 握手会协商密码套件、验证证书并建立会话密钥,之后使用对称加密传输数据。

Q018(P0)JWT 认证的完整流程、优缺点和注销方案是什么?

**答:**登录成功后服务端签发包含 claims 的 access token,客户端携带它访问接口,服务端验证签名、过期时间、签发方和受众。JWT 自包含、适合跨服务验证,但签发后默认难以立即撤销,也不能把敏感信息直接放进 payload。

**常见改进:**短期 access token + 可撤销的 refresh token;refresh token 轮换并检测重放;服务端维护 token version、黑名单或会话记录。浏览器场景要结合 HttpOnly、Secure、SameSite Cookie 和 CSRF 防护设计。

Q019(P0)认证(Authentication)和授权(Authorization)有什么区别?

**答:**认证回答“你是谁”,授权回答“你能做什么”。RBAC 以角色分配权限,适合组织结构稳定的系统;ABAC 根据用户、资源、动作、环境等属性做策略判断,表达力更强但策略治理更复杂。生产系统通常还要校验资源归属,不能只判断用户是否登录。

Q020(P0)Cookie、CORS、CSRF 是什么关系?

**答:**Cookie 是浏览器自动附带的状态凭证;CORS 是浏览器对跨源读响应的安全策略;CSRF 是攻击者借助浏览器自动携带凭证诱导用户发起状态修改请求。CORS 配置正确不能自动解决 CSRF,通常还需要 SameSite、CSRF token、检查 Origin/Referer 和避免用 GET 做写操作。

Q021(P0)XSS、SQL 注入、SSRF 如何防御?

答:

  • XSS:输出时按上下文转义,避免把不可信字符串当 HTML/脚本执行,配合 CSP 和 HttpOnly Cookie。
  • SQL 注入:参数化查询或 ORM 绑定参数,不拼接不可信输入;数据库账号最小权限。
  • SSRF:限制出站目标和协议,解析后再次校验 IP,阻止访问内网、元数据服务和本机管理接口。

**共同原则:**输入校验是第一层,输出编码、权限、网络隔离和审计是后续层,不能只靠一个黑名单。

Q022(P0)如何设计限流?固定窗口、滑动窗口和令牌桶有什么区别?

**答:**固定窗口实现简单,但边界处可能出现突发流量;滑动窗口更平滑,但需要保存更多时间片或请求记录;令牌桶允许一定突发,同时限制长期平均速率,适合 API 网关。限流维度可以是用户、租户、IP、API key 或全局资源,超限应返回明确错误并带重试提示。

Q023(P0)什么是幂等接口?支付、创建任务如何避免重复执行?

**答:**客户端生成幂等键,服务端在事务或可靠存储中记录“幂等键 → 请求摘要/结果/状态”。相同 key 且参数一致时返回原结果;参数不一致直接拒绝。真正执行副作用的地方还需要唯一约束、状态机和消息去重,不能只在内存里放一个标记。

Q024(P0)SSE 和 WebSocket 如何选择?

**答:**SSE 是服务端到客户端的单向长连接,基于 HTTP,自动重连和代理兼容性较好,适合 LLM token 流、进度事件和通知;WebSocket 是双向通信,适合协作编辑、实时游戏和需要客户端高频上行的场景。两者都要处理心跳、断线重连、连接数、鉴权、背压和消息顺序。

Q025(P0)Node.js 为什么适合 I/O 密集型服务?什么会阻塞它?

**答:**Node.js 通过事件循环和非阻塞 I/O 在单个主线程上处理大量连接;文件、网络等操作由运行时和系统异步完成。CPU 密集型循环、同步文件 API、复杂 JSON 处理、正则灾难回溯和大规模序列化会阻塞事件循环,导致所有请求延迟上升。可用 Worker Threads、子进程、任务队列或拆分服务处理重计算。

Q026(P0)FastAPI 中 async 不是“自动变快”,为什么?

**答:**async 只有在等待真正异步 I/O 时才能释放事件循环;如果在 async def 中调用同步数据库驱动、同步 HTTP 客户端或 CPU 密集逻辑,仍会阻塞。应使用异步驱动、线程池或任务队列,并限制并发和超时。依赖注入适合统一处理数据库会话、鉴权、配置和资源生命周期。

Q027(P0)Go 的 goroutine、channel、context 分别解决什么问题?

**答:**goroutine 是轻量并发执行单元;channel 用于在 goroutine 之间传递数据和同步;context 用于传递截止时间、取消信号和请求范围值。生产代码必须处理 channel 关闭、goroutine 退出、错误传播和取消,否则容易出现 goroutine 泄漏、死锁或请求取消后后台任务仍运行。

Q028(P1)Java SE 面试最常追问哪些基础?

**答:**重点包括集合的时间复杂度和线程安全、equals/hashCode 契约、异常边界、接口与抽象类、泛型擦除、线程池、锁与可见性,以及 JVM 的堆、栈、垃圾回收和类加载。回答时不要只背某个集合“快不快”,要说明访问模式、内存开销、并发读写和数据规模。

Q029(P0)后端统一错误处理和参数校验应放在哪里?

**答:**边界层负责解析请求和基础 schema 校验;业务层负责业务不变量和权限;数据层负责约束和事务;统一错误中间件负责把内部异常映射成稳定的错误码、消息和 trace ID,同时记录完整内部日志。不要把数据库异常堆栈、token 或提示词泄露给客户端。

Q030(P1)同步、异步、并发、并行有什么区别?

**答:**同步/异步描述任务是否需要等待当前调用完成;并发描述多个任务在时间上交错推进;并行描述多个任务同时在不同执行资源上运行。I/O 密集型通常通过异步或线程提高并发,CPU 密集型更依赖多进程、Worker 或多核并行;无论哪种方式,都必须有超时、取消、限流和资源上限。

3. 数据库、缓存、向量检索与一致性

Q031(P0)B+Tree 索引为什么适合数据库?联合索引如何遵循最左匹配?

**答:**B+Tree 通过多叉有序节点降低磁盘访问次数,叶子节点按顺序连接,适合等值、范围和排序。联合索引 (a, b, c) 通常能有效支持从最左列开始的连续条件;跳过 a 只查询 b 往往不能充分利用索引。还要关注选择性、回表、覆盖索引、排序和隐式类型转换。

Q032(P0)事务 ACID、隔离级别和常见问题是什么?

**答:**原子性保证事务要么全成功要么全失败,一致性保证约束和业务不变量,隔离性控制并发事务相互影响,持久性保证提交结果可恢复。隔离级别越高通常并发代价越大;常见问题有脏读、不可重复读、幻读和写偏差。回答时要结合具体数据库的 MVCC、锁和实现细节。

Q033(P0)MVCC 解决什么问题?

**答:**MVCC 通过保存记录版本和事务可见性规则,让读操作读取符合快照的版本,从而减少读写互相阻塞。它不等于完全无锁,也不能自动解决所有并发更新;写写冲突、唯一约束、范围锁和隔离级别仍可能导致等待或失败。

Q034(P0)线上 SQL 变慢如何定位?

**答:**先确认是数据库慢、连接池等待、网络慢还是应用处理慢;再看慢查询日志、执行计划、扫描行数、索引使用、锁等待和数据分布。优化可能包括改写 SQL、联合/覆盖索引、减少返回列、拆分大事务、分页、归档或读写分离。优化后用真实数据和基准测试验证,不能只看 EXPLAIN 的估算。

Q035(P0)分页为什么推荐游标分页而不是深分页?

**答:**OFFSET 越大,数据库通常需要扫描并丢弃更多记录,性能和稳定性变差;游标分页记录上一页最后一条的有序键,下一页用 WHERE (created_at, id) < (...) 一类条件继续查。游标必须基于稳定、唯一或可补充唯一 ID 的排序,并定义数据在翻页期间变化时的可见性策略。

Q036(P0)MySQL、PostgreSQL、SQLite 如何选?

**答:**MySQL 适合成熟的通用 OLTP 和常见 Web 业务;PostgreSQL 在复杂查询、类型系统、扩展能力、地理/JSON 等方面更强;SQLite 是嵌入式单文件数据库,适合本地应用、测试、小型服务和边缘场景。选择还要看团队运维、并发写入、备份恢复、生态和部署约束,而不是只看功能列表。

Q037(P0)Redis 常见数据结构和使用场景是什么?

**答:**String 适合缓存、计数和简单锁;Hash 适合对象字段;List 可做简单队列;Set 适合去重;Sorted Set 适合排行榜和按分数取范围;Stream 适合带消费组的消息流。使用时要设置 TTL、控制 value 大小、避免大 key 和热 key,并考虑持久化、淘汰策略和故障恢复。

Q038(P0)缓存穿透、击穿、雪崩怎么处理?

**答:**穿透是请求不存在的数据,可用参数校验、缓存空值或布隆过滤器;击穿是热点 key 过期瞬间大量请求打到后端,可用互斥重建、逻辑过期和热点预热;雪崩是大量 key 同时过期或缓存整体故障,可用随机 TTL、分批预热、限流、降级和多级缓存。任何方案都要保护数据库本身。

Q039(P0)分布式锁需要注意什么?

**答:**锁要有唯一 token、过期时间和安全释放逻辑,释放时必须确认 token 属于当前持有者;业务执行时间可能超过 TTL,需要续期或使用 fencing token。Redis 锁可以解决一部分互斥需求,但不自动保证数据库事务、消息投递和外部副作用的一致性;关键业务要优先使用数据库唯一约束、状态机或可靠队列兜底。

Q040(P0)向量数据库的核心概念是什么?

**答:**文本经过 embedding 得到向量,查询向量与文档向量按余弦相似度、点积或欧氏距离比较;大规模数据通常使用 ANN 索引,如 HNSW 或 IVF,以较小精度损失换取检索速度。向量检索还需要 metadata filter、分区、版本、删除和重建策略,不能把它当成普通模糊搜索。

Q041(P0)什么是混合检索?为什么需要 Rerank?

**答:**混合检索把关键词检索的精确匹配能力和向量检索的语义召回能力结合起来,再用 RRF 等方法融合候选。Rerank 模型在较小候选集上重新判断查询与文档的相关性,通常能提升 Top-K 质量,但会增加延迟和成本。生产上常用“粗召回 → 融合 → Rerank → 截断”的分层结构。

Q042(P0)消息、数据库和缓存怎样保持一致?

**答:**不要在一个本地事务里同时假设数据库和消息系统能原子提交。常见方案是事务内写业务数据和 outbox 事件,再由可靠发布器投递;消费者使用幂等键、状态机和重试队列。缓存通常采用失效或更新策略,并接受最终一致性,关键读路径要定义短暂不一致的业务容忍度。

Q043(P1)数据库连接池为什么会耗尽?

**答:**连接未释放、慢查询、事务范围过大、并发上限配置过高、连接泄漏或数据库本身承载不足都可能耗尽连接池。定位要看池中 active/idle/wait、请求耗时、事务时长和数据库连接数;不能简单把池调大,因为应用并发可能因此把数据库压垮。

Q044(P0)N+1 查询和大事务如何避免?

**答:**N+1 是先查一批主记录,再为每条记录单独查关联数据;可用 join、批量 IN、预加载或 DataLoader 合并查询。大事务会增加锁持有、日志和回滚成本,应缩小事务边界、分批处理、使用状态机和异步任务,并明确失败后的重试语义。

4. 工程化、Git、Linux、Docker、测试与可观测性

Q045(P0)mergerebase 如何选择?

**答:**merge 保留分支历史并产生合并提交,适合多人协作和已经共享的分支;rebase 把提交重新放到新基线上,历史更线性,但会改写提交 ID。原则是不要对他人正在使用的公共分支随意 rebase;个人分支可以在合并前整理提交。

Q046(P0)resetrevertcherry-pick 分别做什么?

**答:**reset 移动当前分支指针,可能改写历史;revert 创建一个反向提交,适合撤销已经推送的公共提交;cherry-pick 把指定提交的变更复制到当前分支。面试时要说明工作区、暂存区、提交历史分别会怎样变化,实际操作前先检查 git status 和分支。

Q047(P0)Linux 排查服务问题最常用哪些命令?

**答:**先用 pstop/htop 看进程和资源,ss 看端口连接,df/du 看磁盘,free 看内存,journalctl 或应用日志看错误,curl 验证接口,rg/grep 定位关键日志。排查顺序是“现象 → 时间范围 → 请求 ID → 资源指标 → 依赖服务”,不要一上来盲目重启。

Q048(P0)Docker 镜像、容器、Volume、Network 的区别?

**答:**镜像是不可变的分层模板,容器是镜像运行后的隔离进程,Volume 用于持久化容器生命周期之外的数据,Network 用于容器之间的发现和通信。容器不是虚拟机,宿主机内核仍被共享;生产镜像要最小化、非 root 运行、固定依赖并避免把密钥写进镜像层。

Q049(P0)为什么使用多阶段构建和 Compose?

**答:**多阶段构建把编译环境和运行环境分开,只把产物复制到最终镜像,减少体积和攻击面;Compose 用于本地或简单环境编排多个服务、网络和依赖。生产环境还要补充健康检查、资源限制、日志策略、秘密管理和可回滚发布。

Q050(P0)单元测试、集成测试、端到端测试如何分工?

**答:**单元测试快、定位精确,验证纯逻辑和边界;集成测试验证数据库、队列、外部服务适配;E2E 验证关键用户链路。测试金字塔不是数量口号,关键是把高风险逻辑放到可重复、可隔离的测试层,并在 CI 中提供稳定反馈。

Q051(P1)Mock 应该怎么用才不会“测了假系统”?

**答:**Mock 用来隔离不稳定或昂贵的外部依赖,但不能把所有依赖都替换掉。接口契约、序列化、重试、超时和错误响应要有集成测试或契约测试;Mock 数据要覆盖空值、超时、部分失败和异常格式,而不是只返回一个完美成功结果。

Q052(P0)一条可靠的 CI/CD 流水线应该包含什么?

**答:**安装锁定依赖 → 格式与静态检查 → 单元/集成测试 → 构建不可变产物 → 安全扫描 → 部署到灰度环境 → 健康检查和冒烟测试 → 分批放量 → 监控并可回滚。数据库迁移要向前兼容,发布和回滚不能依赖手工修改服务器。

Q053(P0)日志、指标、链路追踪分别解决什么问题?

**答:**日志记录单次事件的上下文,指标做聚合趋势和告警,链路追踪把一次请求跨服务的耗时和错误串起来。三者要共享 trace ID、租户/用户等脱敏后的关联字段;AI 系统还要记录模型、版本、token、检索命中、工具调用和评测结果。

Q054(P0)配置、密钥、健康检查和回滚如何设计?

**答:**配置通过环境或配置中心注入,密钥放在专门的 secret 管理系统,不进入仓库和镜像;启动时校验必需配置。区分存活探针和就绪探针,只有准备好依赖后才接收流量;发布使用版本化产物、数据库兼容迁移和明确回滚路径,不能把“重新部署旧代码”当成完整回滚方案。

5. LLM、Transformer、Prompt、Tool Calling 与结构化输出

Q055(P0)token、logits、temperature、top-p 分别是什么?

**答:**文本先被 tokenizer 切成 token,模型输出每个候选 token 的 logits,再经过 softmax 得到概率。temperature 调整分布尖锐程度,越高通常越随机;top-p 从累计概率达到阈值的候选集合中采样。要注意 temperature/top-p 是采样参数,不会修复事实错误或上下文不足。

Q056(P0)Transformer 的 Attention 在做什么?

**答:**每个 token 通过 Query、Key、Value 与其他 token 计算相关性,再按权重聚合信息;多头注意力让模型在不同表示子空间关注不同关系。位置编码提供顺序信息,前馈层和残差/归一化帮助深层训练。自回归生成时使用 causal mask,防止看到未来 token。

Q057(P0)上下文窗口为什么会影响质量、成本和延迟?

**答:**输入越长,token 成本、预填充计算和延迟通常越高;内容过多还会稀释注意力,导致模型忽略中间关键信息。生产上要做历史摘要、相关上下文检索、去重、优先级排序和预算控制,而不是把所有对话和文档全塞进去。

Q058(P0)Prompt 应该如何分层?

**答:**把稳定的角色、约束和安全边界与动态用户输入、检索上下文、工具结果分开;明确任务、输入格式、输出 schema、失败处理和禁止事项。外部内容应被标注为“数据”而不是指令,并在模型调用前后做权限和格式校验。

Q059(P0)为什么要使用结构化输出?如何保证它可靠?

**答:**结构化输出让模型结果能被程序稳定消费,减少正则解析和字段缺失。使用 JSON Schema 或 SDK 提供的结构化模式,并在服务端再次做 schema 校验;校验失败要有限重试或降级,不能直接把未经校验的模型输出写入数据库或执行工具。

Q060(P0)Tool Calling 的完整生命周期是什么?

**答:**模型先根据工具 schema 选择工具并生成参数;服务端校验参数、鉴权、限流和幂等性后执行工具;把工具结果以结构化消息回传给模型;模型再生成最终答复或继续调用。模型“想调用”不等于服务端“允许调用”,真正的安全边界必须在工具执行层。

Q061(P0)流式输出如何实现?最容易遗漏什么?

**答:**服务端从模型供应商读取增量事件,通过 SSE 或 WebSocket 转发给前端;前端按事件拼接内容,并区分文本、工具调用、错误、完成和用量事件。要处理断线、重复片段、半个 JSON、客户端取消、代理缓冲、心跳、超时和最终落库,不能只把字符串逐字打印。

Q062(P0)幻觉为什么产生?如何降低?

**答:**模型是在概率分布上生成最可能的文本,不等于数据库查询;当知识缺失、问题歧义、上下文冲突或提示约束不足时容易编造。可以通过 RAG、工具查询、结构化约束、引用要求、拒答策略、低温度、领域微调和离线评测降低风险,但不能宣称完全消除。

Q063(P0)LLM 应用如何同时控制质量、成本和延迟?

**答:**先定义任务质量指标,再做模型路由、上下文压缩、缓存、批处理、并发控制、输出长度限制和失败降级。简单任务使用小模型,复杂任务才升级;缓存必须包含模型版本、prompt 版本、输入摘要和权限维度,不能把不同用户的结果混在一起。

Q064(P0)Prompt Injection 和数据外泄如何防御?

**答:**把用户输入、网页、文档和工具结果视为不可信数据;工具执行前做服务端权限校验、参数白名单、目标限制和敏感操作审批;限制模型能看到的最小上下文,输出前做敏感信息检测和策略检查。不要把“请模型忽略恶意指令”当成唯一防线。

Q065(P0)模型调用的重试、超时、降级怎么设计?

**答:**区分可重试错误(限流、临时网络失败)和不可重试错误(参数非法、权限不足、上下文超限);使用带抖动的指数退避、总超时预算和最大尝试次数。重试前要确认请求是否产生外部副作用;模型生成本身通常可重试,工具写操作必须依赖幂等键。

Q066(P0)如何评测一个 LLM 应用,而不是只看“感觉不错”?

**答:**建立包含真实分布、难例、拒答样本和对抗样本的数据集,分别评测正确性、相关性、完整性、引用准确率、格式遵循、工具成功率、延迟、成本和安全性。离线评测用于回归,线上用采样、用户反馈和人工复核监控漂移;评测集不能和提示调优数据完全重合。

Q067(P0)Prompt、RAG、微调如何选择?

**答:**规则和输出格式变化优先改 Prompt;知识需要频繁更新或按权限检索优先用 RAG;需要稳定改变风格、格式、工具选择或领域行为时考虑微调。三者可以组合,但微调不能替代实时知识库,RAG 也不能替代真正的行为学习。

6. RAG:切分、召回、Rerank、引用与评测

Q068(P0)标准 RAG 链路是什么?

**答:**文档接入 → 解析和清洗 → 结构化切分 → embedding → 建索引 → 查询改写/过滤 → 关键词和向量召回 → 融合 → Rerank → 上下文编排 → 生成 → 引用校验 → 评测和观测。任何一环有问题,都可能表现成“模型回答不好”,所以要分段记录中间结果。

Q069(P0)文档切分如何决定 chunk 大小?

**答:**按标题、段落、列表、代码块和表格等语义边界优先切分,再用 token 或字符上限控制长度,必要时保留少量 overlap。chunk 太小会丢失上下文,太大会降低召回精度并浪费上下文;应通过检索命中率、上下文完整性和最终答案指标调参,而不是照搬固定数字。

Q070(P0)Embedding 模型怎么评估?

**答:**不只看通用榜单,要用自己的查询—相关文档标注集评估 Recall@K、MRR、nDCG、语义相似和跨语言表现。还要检查文档长度、领域术语、表格/代码、版本、权限过滤和 embedding 模型升级带来的索引兼容问题。

Q071(P0)混合召回和 Rerank 的参数怎么调?

**答:**先分别测关键词和向量召回的覆盖率,再比较融合策略和候选数量;Rerank 的输入应该是相对小而有质量的候选集。候选过少会漏召回,过多会拉高延迟和成本;最终需要在 Recall、答案质量、延迟和成本之间做分层预算。

Q072(P0)metadata filter 为什么必须在检索层做?

**答:**租户、用户、文档版本、权限和时间范围属于访问边界,必须在向量/关键词检索前或检索过程中限制候选;先检索全库再在应用层过滤,可能泄漏文档存在性、浪费资源,甚至在生成前已把不该看的内容放进上下文。权限条件要和索引更新、缓存 key、引用展示一致。

Q073(P0)查询改写、分解和 HyDE 什么时候有用?

**答:**用户问题口语化、包含指代、多跳需求或和文档措辞差异较大时,查询改写或分解能提升召回;多跳问题可以拆成子问题再合并证据。它们会引入额外模型调用和错误改写风险,需要保留原始查询、限制改写次数,并比较改写前后的检索质量。

Q074(P0)如何处理“Lost in the Middle”和上下文太长?

**答:**先去重、压缩和按相关性排序;高价值证据可放在模型更容易关注的位置,同时保留来源和必要上下文。不要只扩大上下文窗口,还要限制候选 token 预算,按问题类型选择摘要、表格化或直接引用。

Q075(P0)RAG 怎样生成可信引用?

**答:**每个 chunk 要携带稳定的文档 ID、版本、标题、页码/段落和权限信息;生成时要求引用对应证据,输出后校验引用是否存在且能支持陈述。引用是可追溯性的组成部分,不等于答案一定正确,仍需评测“引用准确率”和“引用覆盖率”。

Q076(P0)RAG 评测要拆成哪些层?

**答:**检索层看 Recall@K、MRR、nDCG、过滤正确性和版本一致性;生成层看 groundedness、答案相关性、完整性和拒答正确性;系统层看延迟、成本、失败率、引用可追溯性和安全性。检索差和生成差要分开定位,否则容易用更大的模型掩盖数据问题。

Q077(P0)“检索到了但答案仍错”如何排查?

**答:**检查证据是否真正支持问题、chunk 是否缺上下文、排序是否把关键证据压后、上下文是否超预算、提示是否要求引用、模型是否被冲突文档干扰。把原始查询、候选、Rerank 分数、最终上下文、模型版本和答案一起记录,逐层重放。

Q078(P1)文档更新、删除和 embedding 升级怎么处理?

**答:**索引记录文档版本、解析版本、embedding 模型版本和更新时间;更新时采用新版本构建、校验后切换别名或指针,删除要有 tombstone 或可靠删除任务。升级 embedding 不应在原索引上混用不同向量空间,需重建或分版本检索并做回归评测。

7. Agent、LangGraph、Memory、MCP、A2A 与多 Agent

Q079(P0)Workflow 和 Agent 的区别是什么?

**答:**Workflow 的步骤、分支和退出条件主要由程序定义,确定性和可测试性更好;Agent 让模型在约束下动态选择下一步,适合开放式任务,但成本、延迟、可预测性和安全风险更高。能用固定流程解决的部分不必交给 Agent。

Q080(P0)ReAct 的基本思想和风险是什么?

**答:**模型在受控循环中交替进行思考/决策和工具观察,根据结果选择下一步,直到满足完成条件。风险包括无限循环、工具参数错误、把不可信观察当指令、重复副作用和上下文膨胀;必须有最大步数、预算、超时、状态检查和人工审批边界。

Q081(P0)为什么要用状态图或 LangGraph,而不是 while 循环?

**答:**状态图把节点、边、条件、重试、暂停和恢复显式化,便于可视化、持久化、回放和测试。LangGraph 类框架的价值在于把 Agent 运行从隐式循环变成可检查的状态机;但业务状态仍要有明确 schema,不能把所有东西塞进一个无类型字典。

Q082(P0)Checkpoint 和 Human-in-the-loop 解决什么问题?

**答:**Checkpoint 保存关键状态,让任务可以从中断处恢复、重放和审计;Human-in-the-loop 在高风险操作、低置信度或需要确认时暂停,等待人工批准、修改或拒绝。恢复必须保证工具调用幂等,不能因为重放节点再次扣款、发邮件或修改数据。

Q083(P0)短期记忆和长期记忆如何设计?

**答:**短期记忆是当前任务的状态和对话上下文,重点是窗口、摘要、工具结果和任务进度;长期记忆是跨会话的用户偏好、事实或经验,需要提取、更新、冲突处理、权限、删除和过期策略。不要把所有历史对话原样存入长期记忆,写入前要判断价值和敏感性。

Q084(P0)MCP 解决什么问题?

**答:**MCP 为模型应用连接外部工具、资源和提示提供统一的协议化接口,使能力提供方和 Agent 客户端解耦。关键概念包括 server、client、tools、resources、prompts、能力协商和生命周期。MCP 统一的是交互方式,不会自动解决权限、数据可信、工具幂等和部署隔离。

Q085(P1)A2A 和工具调用有什么区别?

**答:**工具调用通常是对一个明确能力的函数式调用,输入输出 schema 相对固定;A2A 更关注 Agent 之间发现能力、委派任务、交换状态和交付结果。跨 Agent 协作要定义身份、能力声明、任务状态、超时、取消、重试和结果验证,否则只是把不确定性从一个模型转移到多个模型。

Q086(P0)多 Agent 为什么不一定比单 Agent 好?

**答:**多 Agent 可以分工、隔离上下文并引入专业角色,但会增加通信、协调、重复推理、成本和故障面。只有当任务边界清晰、并行收益明显、角色有不同工具或上下文时才值得拆分;共享状态、冲突解决、终止条件和预算要先设计。

Q087(P0)如何让工具可靠、可审计、可重试?

**答:**工具 schema 要明确参数类型、枚举、权限和失败语义;服务端执行前校验身份、资源归属、范围和幂等键;执行时有超时、重试、熔断和日志;执行后记录调用者、输入摘要、结果摘要、状态和 trace ID。写操作最好先预览,再审批,再提交。

Q088(P0)Agent 的安全边界应该放在哪里?

**答:**模型只能提出计划,策略引擎和工具服务决定是否允许;网络出站、文件系统、数据库、密钥和高风险动作都要在执行层隔离。对提示注入、越权、数据外泄和无限循环做独立防护,不能只通过系统提示“提醒模型小心”。

8. LoRA/QLoRA、训练数据与模型部署

Q089(P0)LoRA 为什么能降低微调成本?

**答:**LoRA 冻结基础模型参数,只在目标层旁路学习低秩矩阵,将权重更新表示为较低秩的分解,因此可训练参数和显存明显减少。它适合领域风格、格式和行为适配,但效果取决于数据质量、目标层、秩、学习率和训练稳定性。

Q090(P0)QLoRA 与 LoRA 有什么差别?

**答:**QLoRA 通常把基础模型以低比特量化加载,同时训练 LoRA adapter,在减少基础模型显存的同时尽量保持训练能力。量化会带来精度和算子兼容性问题,训练前要确认 GPU、量化实现、梯度类型、序列长度和 checkpoint 合并流程。

Q091(P0)训练数据为什么比“换一个超参数”更重要?

**答:**数据要有清晰任务定义、正确答案、覆盖真实输入分布、难例和拒答样本;要去重、去污染、去敏感信息并划分独立验证集。错误、矛盾、格式不一致或只覆盖理想输入的数据,会让模型学到错误模式,最终线上表现不稳定。

Q092(P0)量化、LoRA 合并和推理部署有哪些坑?

**答:**量化需要评估精度、长上下文、工具调用和中文表现;LoRA adapter 可以运行时加载,也可以合并到基础模型,但合并后要重新验证 tokenizer、权重、版本和许可证。部署时要考虑启动时间、显存、并发、批处理、KV cache、流式输出、超时和模型回滚。

Q093(P0)如何提高模型推理吞吐?

**答:**使用连续批处理、合理的并发和队列、KV cache、合适的量化和硬件;把长输入预填充和逐 token 解码的瓶颈分开看。吞吐提高可能牺牲单请求延迟和公平性,要同时监控首 token 延迟、每 token 延迟、P95/P99、队列等待和 GPU 利用率。

Q094(P1)如何判断应该继续微调还是停止?

**答:**比较基线模型、Prompt、RAG 和微调模型在同一独立评测集上的质量、成本、延迟和维护复杂度。如果收益只来自训练集或离线样例,说明过拟合或评测污染;如果问题来自实时知识、权限或工具可靠性,微调通常不是第一解法。

9. AI 全栈系统设计、项目表达与算法

Q095(P0)如何设计一个支持引用的企业知识库问答系统?

**答:**先拆成上传/解析、文档版本、权限、索引、查询编排、生成、引用、反馈和观测模块。查询链路做租户和权限过滤,再混合召回、Rerank、上下文预算、流式输出和引用校验;异步索引要有任务状态、重试和死信。回答吞吐、延迟、索引一致性、成本和安全边界,而不只是画一个“前端—LLM—数据库”。

Q096(P0)AI 流式回答接口如何设计?

**答:**创建会话/消息后返回 SSE 或 WebSocket 流;事件至少区分 message_starttokentool_callcitationerrormessage_end 和 usage。服务端保存最终状态,客户端断线可按 message ID 恢复或查询;取消请求要传播到模型、检索和工具层,避免后台继续消耗资源。

Q097(P0)多租户 AI 系统怎样防止数据串租户?

**答:**租户 ID 必须来自可信身份上下文,而不是直接信任请求体;数据库、缓存、向量检索、对象存储和日志都带租户维度,权限过滤尽量下沉到数据访问层。缓存 key、异步任务、引用链接、embedding 索引和模型评测集都要做租户隔离,测试要专门覆盖越权查询。

Q098(P0)AI 系统要观测哪些指标?

**答:**基础层看请求量、错误率、P50/P95/P99、队列和依赖健康;模型层看 token、成本、首 token 延迟、生成时延、拒答、结构化校验失败;RAG 层看召回、Rerank、引用和上下文长度;Agent 层看步数、工具成功率、重试、循环和人工介入。指标必须能按模型、版本、租户、功能和 trace 关联。

Q099(P0)如何用两分钟介绍一个 AI 全栈项目?

**答:**按“背景/用户 → 关键难点 → 架构 → 我的职责 → 结果 → 取舍/复盘”讲。结果尽量量化,例如响应时间、召回率、成本、并发、错误率或人工节省;不要只说“用了某框架”,要说框架解决了哪一个问题,以及你如何验证它。

Q100(P0)面试官问“为什么不用更简单的方案”怎么答?

**答:**先承认简单方案在当前规模下可能更合适,再说明当时的约束、风险和未来扩展点。例如先用固定 Workflow 而不是 Agent,先用 PostgreSQL + pgvector 而不是单独引入向量平台,先用 SSE 而不是 WebSocket。优秀回答不是堆技术,而是解释复杂度与收益的边界。

Q101(P0)线上 AI 回答质量突然下降,你如何排查?

**答:**先按时间、模型版本、Prompt 版本、索引版本、租户和功能切片;重放同一输入,比较检索候选、最终上下文、工具结果、模型响应和引用。再检查依赖限流、缓存命中、数据更新、token 截断、结构化解析和安全策略变化。先止损(回滚、降级或关闭高风险工具),再定位根因,最后补回归样例。

Q102(P0)两数之和为什么用哈希表?

**答:**遍历到 x 时检查目标值 target - x 是否已经出现;哈希表把查找平均降到 O(1),总复杂度 O(n),空间 O(n)。要说明重复值、同一元素不能使用两次以及哈希冲突会影响常数但不改变平均分析。

Q103(P0)二分查找最容易错在哪里?

**答:**先明确区间是闭区间还是半开区间、循环不变量和最终要找的是“某个值”还是“第一个满足条件的位置”。mid 计算、边界收缩和不存在时的返回值要保持同一套定义;不要只背一段模板。

Q104(P0)滑动窗口适合解决什么问题?

**答:**当目标条件可以随着左右指针移动而增量维护时,用窗口表示连续子数组/子串,通常把 O(n²) 降为 O(n)。关键是定义窗口不变量、右指针扩张条件、左指针收缩条件和答案更新时机;遇到负数、计数约束或非单调条件时,不能盲套模板。

Q105(P0)LRU 和 Top-K 怎么快速讲清楚?

**答:**LRU 用哈希表定位节点,用双向链表维护最近使用顺序,访问和淘汰平均 O(1);Top-K 根据数据规模和是否流式选择小根堆、快速选择或计数结构,常见复杂度是 O(n log k)。面试时补充容量、重复值、并发安全和内存边界。

10. 最后冲刺清单

必须能脱口而出的 P0 主题

  • React:render/commit、state 批处理、useEffect、key、性能优化、Next.js 渲染模式。
  • 后端:HTTP 幂等、JWT、RBAC、CORS/CSRF、限流、SSE、事件循环和异步边界。
  • 数据:联合索引、事务隔离、MVCC、慢查询、缓存三大问题、分布式锁、向量检索。
  • 工程:Git 分支策略、Docker、测试分层、CI/CD、日志/指标/追踪和回滚。
  • LLM:Attention、上下文、结构化输出、Tool Calling、流式、成本、注入防御和评测。
  • RAG:切分、混合召回、Rerank、权限过滤、引用、评测和逐层排障。
  • Agent:Workflow/Agent、状态图、Checkpoint、Memory、工具可靠性、MCP/A2A 和安全边界。
  • 微调与系统设计:LoRA/QLoRA、数据质量、推理吞吐、多租户、项目量化和故障止损。

每个项目至少准备 6 个数字

  1. 规模:用户数、文档量、请求量、并发或数据量。
  2. 质量:准确率、召回率、引用覆盖率、任务成功率。
  3. 性能:P95、首 token 延迟、吞吐、索引耗时。
  4. 成本:单次请求 token、月度成本、缓存命中率。
  5. 稳定性:错误率、重试率、可用性、回滚时间。
  6. 个人贡献:你具体设计、实现、排查和验证了什么。

结束前自测

  • 能否不用术语堆砌,在 60 秒内讲清一个完整链路?
  • 能否说出至少一个失败场景和对应监控指标?
  • 能否解释为什么选择当前方案,以及何时会换方案?
  • 能否把每个 AI 技术点落到权限、成本、延迟、可观测性和用户体验?
  • 能否在代码题中先说复杂度、边界和不变量,再开始写代码?

返回顶部