跳到主要内容

乐趣无限

面试定位

这份题目围绕乐趣无限 JD 和简历内容整理,重点覆盖中台前端、全栈开发、AI Agent、LLM 应用、RAG、Function Calling、工程化、性能优化和跨团队协作。回答都按口述场景组织,可以直接用于模拟面试。

速记提纲

30 秒定位

9 年 Web 开发经验,最近是 Web 开发负责人,主导 Swee AI 社交娱乐平台和 RYZZ Web3 直播社交平台。优势是 TypeScript + React/Next.js + Node/NestJS 全栈,同时有 AI 应用、Prompt 工程、流式对话、中台平台和工程化落地经验。

和乐趣无限 JD 的匹配点

  • 中台复用:Prompt 模板管理、事件埋点、多语言、文件管理、配置中心都属于多业务线复用能力。
  • 全栈协同:用 NestJS、PostgreSQL、MySQL、Redis、Kafka 做过接口、数据处理、缓存和异步链路。
  • Agent 基础:熟悉 LLM API、Prompt 模板、Function Calling 思路、MCP、Rules、Skills、Commands 和 AI 辅助研发链路。
  • 工程化:Turborepo、GitHub Actions、Docker、Kubernetes、灰度发布、SDK 化和代码生成都有实践。
  • 性能体验:SSE 流式渲染、requestAnimationFrame 合批、React.memo、IndexedDB、Service Worker、SSR 优化和 Web Worker 都能讲项目细节。

必讲项目

  • Swee AI 对话 PWA:SSE 流式响应、多类型内容混排、token 合批渲染、历史消息 IndexedDB、PWA 缓存。
  • Prompt 模板管理系统:100+ Prompt 模板、变量定义、版本控制、Playground、三步渲染管线、SDK、多级缓存、灰度迁移。
  • 事件埋点系统:前端 SDK、sendBeacon/fetch/XHR 降级、Kafka 削峰、PostgreSQL JSONB + GIN、埋点代码自动生成。
  • 虎牙 SSR 重构:React SSR、服务端数据预取、Hydration、请求聚合、缓存策略、灰度切流,秒开率提升 41%。
  • 凡科快图编辑器:Vue + Canvas/SVG、图层编辑、变换矩阵、碰撞检测、Web Worker + OffscreenCanvas。

Agent 深度回答公式

先讲分层:模型网关、Agent Runtime、工具层、知识库层、观测评估层。再讲约束:工具 Schema、权限、副作用分级、日志审计、人工确认。最后讲指标:任务完成率、工具成功率、人工修改率、耗时、token 成本、幻觉率和用户采纳率。

遇到短板怎么答

Vue3 和 LangChain 可以诚实说不是最近最主线,但补充方式要落到工程能力:我有 Vue 复杂编辑器经验,也理解响应式和组件化;Agent 框架方面虽然不是重度依赖某个框架,但已经做过 Prompt 资产化、工具调用、MCP、AI 辅助研发流程和可观测调试,能快速迁移到 LangChain、Dify 或团队自研框架。

高频面试题

Q1: 请先做一个和这个岗位匹配的自我介绍

答案

我叫李文杰,有 9 年 Web 开发经验,最近在广州未可信息科技担任 Web 开发负责人,主导过 Swee AI 社交娱乐平台和 RYZZ Web3 直播社交平台的 Web 架构、核心开发和团队管理。我的技术栈以 TypeScript、React、Next.js、Node.js、NestJS 为主,也做过 Vue 和 Canvas/SVG 编辑器方向的复杂前端。

和这个岗位比较匹配的点主要有三块:第一,我有比较完整的中台和全栈经验,做过 Prompt 模板管理系统、事件埋点分析系统、多语言文案管理、文件管理、配置中心等中后台系统;第二,我有 AI 应用落地经验,包括 SSE 流式对话、Prompt 模板管理、变量渲染、Playground 调试、SDK 接入和缓存策略;第三,我比较熟悉 AI 辅助研发工具链,长期使用 Claude Code、Codex、Rules、Skills、Commands、MCP 等方式提升研发效率。这个岗位强调中台复用、Agent 落地和全栈协同,这些正好是我近几年重点做的方向。

Q2: 你为什么觉得自己适合乐趣无限这个岗位?

答案

我理解这个岗位不是单纯写前端页面,而是要把前端工程化、中台平台能力和 AI Agent 能力结合起来。我的经历里有几个直接对应点:Swee 项目里我负责 AI 对话体验和 Prompt 模板管理系统,做过 LLM API 接入、流式渲染、Prompt 调试、版本控制和 SDK 化;事件埋点系统里我做过从前端 SDK 到 NestJS 服务端、Kafka、PostgreSQL、Grafana 的完整链路;多语言、文件管理和配置中心则更偏中台复用能力。

所以如果入职,我不只是能完成业务需求,也能把高频能力沉淀成组件、SDK、脚手架、模板、接口规范和 Agent 工具,让多业务线复用。

Q3: 你的技术栈和 JD 的匹配点有哪些?

答案

前端方面,我主要使用 TypeScript、React、Next.js、Zustand、SWR、Tailwind CSS、Sass,也做过 Vue 2、Canvas、SVG 编辑器。后端方面,我用 NestJS 做过生产级后端服务,涉及 MySQL、PostgreSQL、Redis、Kafka、OSS/CDN 等。工程化方面,我熟悉 Turborepo Monorepo、GitHub Actions、Docker、Kubernetes。

AI 方面,我做过 AI 对话 PWA、Prompt 模板管理系统、LLM API 接入、流式渲染、Prompt 工程、文件处理,并且深度使用 AI 编程工具和 MCP、Rules、Skills 等方式改造研发流程。

Q4: 你最近最能体现 AI 落地能力的项目是什么?

答案

我会重点讲 Swee 的 Prompt 模板管理系统。这个系统解决的是 100 多个 AI Prompt 模板分散、难调试、难审核、难复用的问题。我把 Prompt 管理做成了一个中台:支持在线编辑、变量定义、实时预览、版本控制、Playground 调试和审批发布。

技术上,前端用 Next.js 和 CodeMirror 6 做编辑器,后端用 NestJS、PostgreSQL、Redis 和 OSS。核心是三步渲染管线:先处理条件块,再处理循环块,最后做变量插值。Playground 会记录每一步中间结果,方便定位 Prompt 为什么生成异常。最后还提供 SDK 给业务方接入,通过内存、Redis、数据库三级缓存提升读取性能,Prompt 迭代周期从 2 到 3 天缩短到了分钟级。

Q5: 如果让你设计一个面向多业务线的 Agent 中间件,你会怎么做?

答案

我会分四层设计。第一层是模型网关,统一封装不同大模型 API,处理鉴权、限流、重试、超时、日志和成本统计。第二层是 Agent Runtime,负责 Prompt 组装、ReAct 循环、工具调用、上下文管理和中止控制。第三层是工具层,把业务能力封装成 Function Calling 或 MCP Tool,比如接口查询、代码生成、文档检索、数据 mock、接口校验。第四层是观测和评估层,记录输入输出、工具调用链路、命中知识、耗时、token 成本、失败原因和人工反馈。

这样业务线只需要声明场景、选择工具和知识库,就能低门槛接入 AI 能力,而不是每条业务线都重新造一套 Agent。

Q6: 你怎么理解 Agent 和普通 LLM Chat 的区别?

答案

普通 Chat 主要是一次输入、一次生成,模型更多是在回答问题。Agent 则是让模型围绕目标执行任务,它通常有规划、记忆、工具调用、观察结果、继续推理和最终输出这些步骤。

比如普通 Chat 可以回答“如何生成接口 Mock”,但 Agent 可以读取接口文档、调用代码生成工具、生成 mock 文件、执行校验脚本、根据报错修正结果。它的核心价值是把模型从“回答者”变成“执行者”,但这也要求我们做好权限边界、工具定义、可观测性和失败兜底。

Q7: 你熟悉 ReAct 模式吗?项目里会怎么落地?

答案

ReAct 可以理解为 Reasoning 和 Acting 的结合,模型先思考下一步要做什么,再调用工具,拿到观察结果后继续决策。落地时我不会把模型的思考过程完整暴露给用户,而是把它作为内部执行链路管理。

比如代码联调 Agent:第一步解析用户需求,第二步查询 OpenAPI 或接口文档,第三步生成请求类型和 mock 数据,第四步调用接口校验工具,第五步根据结果修正类型或提示后端字段不一致。每一步都要记录工具入参、返回、耗时和失败原因,方便排查和评估。

Q8: Function Calling 的工具定义你会关注哪些点?

答案

我会关注四点。第一是工具职责要单一,避免一个工具既查数据又改数据又发通知。第二是参数 Schema 要清晰,字段类型、枚举、必填项、默认值都要明确,减少模型乱传参数。第三是工具要有权限和副作用标记,比如只读、可写、危险操作,危险操作必须二次确认。第四是返回结果要结构化,最好带状态码、错误原因、可恢复建议和必要的业务数据,方便模型继续推理。

从工程角度看,工具不是给模型随便调用的函数,而是一个有契约、有权限、有审计的业务 API。

Q9: MCP、HTTP、WebSocket 作为 Agent 集成方式有什么区别?

答案

HTTP 适合请求响应式工具,比如查询接口文档、生成一段代码、校验一个 JSON Schema。WebSocket 适合长连接和实时反馈,比如 Agent 执行过程中持续推送步骤、日志、进度和中间结果。MCP 更像是面向模型和工具生态的标准协议,它把工具、资源、Prompt 这些能力用统一方式暴露给 Agent,适合做跨工具、跨客户端的能力集成。

如果是企业内部中台,我通常会用 HTTP 承载稳定业务工具,用 WebSocket 或 SSE 承载流式进度,用 MCP 连接研发工具、知识库、文件系统和 IDE 能力。

Q10: 如果做一个代码生成 Agent,你会让它生成什么?

答案

我会优先从高频、低风险、规则明确的内容开始,比如接口请求代码、TypeScript 类型、表单配置、列表页 CRUD 模板、埋点代码、i18n key、Mock 数据、单元测试骨架。原因是这些内容模式稳定、收益高,也容易自动校验。

我之前在事件埋点系统里做过埋点代码自动生成,在多语言系统里做过各端本地代码生成,在 Prompt 系统里做过 SDK 接入。这类经验可以迁移到代码生成 Agent:输入规范配置,生成代码,再跑 lint、typecheck 或 schema 校验,最后给出 diff 和人工确认。

Q11: 代码生成 Agent 最容易出问题的地方是什么?

答案

主要有三个风险。第一是上下文不准确,导致生成的代码和项目真实目录、依赖、规范不一致。第二是生成结果不可验证,只看起来像对,但编译、类型或运行时会失败。第三是越权修改,Agent 不应该随便改不相关文件或提交危险操作。

我的做法是让 Agent 先读取项目规则和目标文件,再生成最小 diff;生成后必须执行格式化、类型检查或测试;涉及删除、覆盖、跨模块修改时必须人工确认。这样既能提升效率,又能控制风险。

Q12: 你怎么设计接口联调 Agent?

答案

我会把接口联调 Agent 设计成“文档解析、代码生成、请求验证、差异反馈”四步。它先读取 OpenAPI、Apifox 或后端接口定义,生成 TypeScript 类型、请求函数和 mock 数据;然后调用真实接口或 mock 服务,校验响应字段是否符合约定;如果发现字段缺失、类型不一致、状态码异常,就输出给前后端双方确认。

这个 Agent 的价值不是替代联调,而是把重复的检查工作自动化,减少前端等接口、后端改字段不通知、mock 和真实接口不一致这类问题。

Q13: 你怎么做数据 Mock 自动化?

答案

我会优先基于接口 Schema 生成 mock,而不是人工随便写假数据。比如根据字段类型、枚举、必填项、数组长度、业务规则生成基础数据,再允许业务通过配置覆盖特殊场景,比如空列表、异常状态、分页末页、权限不足。

如果结合 Agent,它可以读取接口文档和页面需求,自动生成常规 mock、边界 mock 和异常 mock,同时生成对应的 MSW 或后端 mock 配置。这样前端能更早开发,也能覆盖更多异常路径。

Q14: 你怎么设计接口校验能力?

答案

我会把接口校验放在契约层。首先有统一的 Schema 来源,比如 OpenAPI 或后端导出的 JSON Schema;其次请求和响应都要校验,包括字段类型、枚举值、必填字段、分页结构、错误码结构;最后把校验结果接入 CI 或联调平台。

如果是运行时校验,我会只在测试环境或灰度环境打开详细校验,线上只保留关键字段监控,避免性能损耗。校验失败时要给出字段路径和期望值,比如 data.list[0].status 期望是枚举但返回了未知值。

Q15: 如果让你把 Agent 融入脚手架,你会做哪些能力?

答案

我会把 Agent 放到脚手架的几个关键节点。创建项目时,Agent 根据业务类型选择模板、组件库、状态管理和接口层方案;开发页面时,根据接口文档生成页面骨架、类型、请求函数和 mock;提交代码前,Agent 帮忙做 lint、类型检查、测试建议和变更摘要;上线前,Agent 根据变更范围生成回归 checklist。

重点是让 Agent 参与标准化流程,而不是只做一个聊天窗口。这样它才能真正提升研发效率。

Q16: 你怎么理解中台前端?

答案

我理解中台前端的核心不是页面数量,而是复用能力和一致性。它要把多个业务线都会用到的能力沉淀下来,比如组件库、权限、表单、表格、配置中心、文件上传、埋点、国际化、接口层、错误处理和发布流程。

一个好的中台前端应该让业务团队少写重复代码,同时保证体验、交互、权限和数据流一致。我的 Prompt 模板管理、埋点系统、多语言文案管理和配置中心,本质上都属于这种可复用的中台能力。

Q17: 多业务线复用组件时,你怎么避免组件越来越臃肿?

答案

我会先区分通用能力和业务差异。通用能力放在组件内部,比如表格分页、筛选、加载、错误态、权限控制;业务差异通过配置、插槽、render props 或组合式 API 暴露出来。组件不要为了所有业务写很多布尔参数,否则很快会变成难维护的巨型组件。

另外,我会配合文档、示例和版本管理。组件能力成熟后再下沉,不会一开始就抽象。先在两个以上真实业务里验证,再提炼公共 API。

Q18: 你做过哪些可复用方案?

答案

做过几类。第一是 Prompt 模板管理系统,提供模板编辑、变量、版本、审批、Playground 和 SDK,让多个业务复用 Prompt 能力。第二是事件埋点系统,提供前端 SDK、事件定义、代码生成、数据查看和服务端采集链路。第三是多语言文案管理,统一管理 8 种语言,支持微软翻译集成和各端本地代码生成。第四是文件管理和配置中心,提供 OSS 直传、CDN 刷新、多级缓存、版本控制和权限管理。

这些方案共同点是:把业务重复逻辑平台化,同时保留业务侧的配置空间。

Q19: 你怎么和后端协作设计接口?

答案

我会先对齐业务模型和页面状态,再设计接口,而不是前端页面写完后临时要字段。接口层面我会关注 RESTful 语义、分页结构、错误码、幂等性、权限、字段命名和兼容策略。对于复杂页面,我会把前端需要的聚合数据提前和后端确认,避免页面发太多散接口。

我自己也做过 NestJS 后端,所以更能理解后端的数据表、缓存、事务和性能约束。协作时会尽量把接口契约、mock 和验收标准提前明确。

Q20: 你怎么判断一个接口应该前端聚合还是后端聚合?

答案

如果只是轻量展示组合,比如两个互不依赖的小模块,前端并行请求即可。如果涉及权限过滤、复杂计算、多表关联、敏感字段、缓存复用,或者多个端都要用,我更倾向后端或 BFF 聚合。

在虎牙 SSR 重构里,我们通过服务端数据预取和异步请求聚合提升响应速度;在中台系统里,我也会把复杂数据处理放到 NestJS 服务端,前端拿到更贴近页面的数据结构,降低页面复杂度。

Q21: 你用 NestJS 做过哪些后端能力?

答案

我用 NestJS 做过 Prompt 模板管理、事件埋点服务、多语言文案管理、文件管理和配置中心。涉及的能力包括 REST API、权限校验、数据库读写、Redis 缓存、OSS 直传、CDN 刷新、版本控制、审批发布、Kafka 消费和定时报表。

我比较喜欢 NestJS 的原因是它在工程结构、依赖注入、模块拆分、Guard、Interceptor、Pipe 上比较规范,适合中后台和中台服务长期维护。

Q22: 你怎么设计 NestJS 项目的模块结构?

答案

我通常按业务域拆模块,比如 prompt、event、file、config、auth,每个模块内部有 controller、service、repository 或 model。如果有通用能力,比如日志、鉴权、缓存、错误处理、数据库连接,就放到 common 或 infrastructure 层。

Controller 只负责协议层和参数接收,Service 处理业务逻辑,Repository 处理数据访问。这样代码职责清晰,也方便测试和后续拆分。

Q23: MySQL、PostgreSQL、Redis 你分别怎么用?

答案

MySQL 和 PostgreSQL 我主要用于业务数据持久化,比如用户、配置、模板、事件定义、文件元数据。PostgreSQL 的 JSONB 和 GIN 索引适合存半结构化数据,我在事件埋点系统里用它存事件属性并做查询。Redis 主要用于缓存、热点数据、临时状态和限流,比如 Prompt 模板读取用了内存、Redis、数据库三级缓存。

选型上,我会根据数据结构、查询模式和一致性要求决定,不会为了技术栈而技术栈。

Q24: 你怎么设计缓存策略?

答案

我会先区分数据类型。读多写少、允许短暂延迟的数据适合缓存,比如 Prompt 模板、配置中心、多语言文案;强一致或频繁变化的数据要谨慎。缓存层面可以做本地内存、Redis、数据库多级兜底。

在 Prompt 模板系统里,我设计过内存 60 秒、Redis 5 分钟、数据库兜底的多级缓存。发布新版本时会主动失效缓存,同时保留灰度和回滚能力,避免缓存导致线上读到错误模板。

Q25: 你怎么处理缓存一致性?

答案

我通常用 Cache Aside 模式:读的时候先读缓存,未命中再读数据库并回填;写的时候先更新数据库,再删除缓存或发布失效事件。对于配置和模板这类数据,我更倾向发布时主动刷新或删除缓存,并用版本号控制读取结果。

如果业务不能接受短暂不一致,就不要依赖普通缓存做强一致,需要使用事务、版本校验或把一致性逻辑放到数据库层。

Q26: 你做事件埋点系统时,前端 SDK 怎么设计?

答案

我做的 SDK 重点是轻量、可靠和低侵入。上报采用双触发缓冲:达到 10 条或 5 秒超时就批量发送,减少请求次数。发送方式做多级降级:优先 sendBeacon,失败再用 fetch,最后用 XHR。页面关闭或切后台时,通过 visibilitychangebeforeunload 兜底上报。

SDK 内置 PV、页面停留时长等自动采集,同时支持业务自定义事件。这样既保证数据完整性,又不会明显影响页面性能。

Q27: 事件埋点服务端链路怎么设计?

答案

服务端收到事件后先做基础校验,比如 app、事件名、字段类型、必填属性和时间戳。校验通过后投递 Kafka,利用消息队列削峰解耦。Consumer 侧再按 500 条或 5 秒攒批写入 PostgreSQL,事件属性用 JSONB 存储,并通过 GIN 索引支持查询。

这样前端上报链路不会直接打数据库,服务端也能支撑高峰流量。后续再基于聚合数据生成 KPI 看板和定时报表。

Q28: 你怎么评价一个 Agent 的效果?

答案

我会从业务效果、技术质量和成本三方面评价。业务效果看任务完成率、人工修改率、节省时间、用户满意度;技术质量看工具调用成功率、Schema 错误率、幻觉率、响应耗时、失败可恢复性;成本看 token 消耗、模型调用次数、缓存命中率和单位任务成本。

比如代码生成 Agent,不能只看生成了多少代码,更要看生成代码一次通过类型检查的比例、人工修改量和线上缺陷率。

Q29: Agent 监控你会采集哪些指标?

答案

我会采集请求维度、模型维度、工具维度和结果维度。请求维度包括用户、业务线、场景、输入长度、耗时;模型维度包括模型名称、token 数、首 token 时间、生成速度、错误码;工具维度包括工具调用次数、成功率、失败原因、参数校验错误;结果维度包括用户采纳、人工修改、重试次数和反馈评分。

这些数据可以帮助我们判断问题出在 Prompt、模型、工具、知识库还是业务流程。

Q30: Agent 安全性你会怎么保障?

答案

我会从输入、工具、输出和权限四层做。输入层做敏感信息识别和 Prompt 注入防护;工具层做白名单、参数校验、副作用分级和二次确认;输出层做内容过滤、引用来源和结构化校验;权限层则和业务账号体系打通,用户只能调用自己有权限的工具和数据。

尤其是能改代码、发请求、改配置的 Agent,一定要默认保守,所有危险操作都要可审计、可回滚。

Q31: RAG 系统你会怎么设计?

答案

我会把 RAG 分成数据接入、切分、向量化、检索、重排、生成和评估几个环节。数据源可以是接口文档、业务知识库、组件文档、历史问题和代码规范。切分时要按语义和结构切,而不是机械按长度切。检索时可以结合向量检索和关键词检索,召回后再做重排,最后把最相关的上下文注入 Prompt。

关键是要能追溯来源和持续评估。否则 RAG 看起来接了知识库,实际可能召回无关内容,反而误导模型。

Q32: 向量数据库和普通数据库在 RAG 里分别承担什么?

答案

向量数据库主要用于语义相似度检索,比如用户问“接口联调失败怎么排查”,它能召回语义相关的文档片段。普通数据库更适合存结构化元数据,比如文档标题、版本、权限、业务线、创建时间、标签和审批状态。

实际系统里我会两者结合:向量库负责召回,数据库负责权限过滤、元数据筛选和结果展示。这样既能语义检索,也能保证数据权限和可维护性。

Q33: RAG 最常见的问题是什么?

答案

常见问题有三个。第一是切分不合理,导致召回片段缺上下文。第二是知识过期,模型引用了旧接口或旧规范。第三是权限没处理好,用户可能检索到不该看的内容。

我的做法是保留文档结构信息,比如标题层级、业务线、版本号;建立增量更新和过期策略;检索前先做权限过滤或检索后严格过滤;回答时带来源,方便用户判断可信度。

Q34: Prompt 工程你有哪些实践?

答案

我做 Prompt 工程比较关注模板化、可调试和可评估。模板化是把角色、任务、输入、约束、输出格式拆开,不让每个业务自己拼字符串。可调试是通过 Playground 展示变量、条件块、循环块和最终 Prompt 的中间结果。可评估是保留测试集和历史输出,比较不同版本的效果。

在 Swee Prompt 模板系统里,我们通过版本控制、审批发布和 SDK 接入,把 Prompt 从“散落在代码里的字符串”变成可管理资产。

Q35: Prompt 模板系统为什么需要版本控制?

答案

因为 Prompt 变化会直接影响线上 AI 输出,而且问题不一定马上暴露。版本控制可以解决三个问题:第一,知道谁在什么时候改了什么;第二,新版本效果不好可以快速回滚;第三,可以灰度对比不同版本的效果。

我之前做的时候还配合审批发布和双写兼容,让业务迁移更稳。Prompt 和代码一样,进入生产环境前需要管理流程。

Q36: 你怎么做 Prompt Playground?

答案

Playground 的核心不是简单输入输出,而是让用户看清 Prompt 是怎么生成的。我会展示变量输入、条件块命中情况、循环块展开结果、最终 Prompt、模型参数、模型输出和耗时成本。

如果输出不符合预期,用户可以定位是变量传错、条件没命中、模板写错,还是模型参数不合适。这样 Prompt 调试从黑盒变成白盒,迭代效率会高很多。

Q37: AI 对话里的 SSE 流式渲染你怎么做?

答案

前端通过 SSE 接收服务端增量 token 或结构化事件。收到数据后不要每个 token 都 setState,否则会导致频繁渲染。我在 Swee 里用 requestAnimationFrame 批量合并流式 token,再统一更新界面。

同时,消息结构要支持多类型内容混排,比如文本、图集、音频、视频、选项和业务卡片。流式过程中要处理取消、重试、断线、结束标记和异常状态,保证用户体验稳定。

Q38: 流式响应为什么不用每个 token 都渲染?

答案

因为模型输出 token 很碎,如果每个 token 都触发 React 状态更新,会造成大量 render 和 layout,尤其移动端容易卡顿。用 requestAnimationFrame 或定时批处理,可以把多个 token 合并成一帧更新,既保留流式体感,又降低渲染压力。

我在 AI 对话界面里还结合了 React.memo、媒体懒加载和骨架屏,减少历史消息重渲染和资源阻塞。

Q39: AI 聊天历史消息怎么做性能优化?

答案

首先消息数据结构要稳定,历史消息组件用 React.memo 避免新 token 导致全部重渲染。其次长列表要考虑虚拟滚动或分页加载,媒体资源要懒加载。第三,首屏可以从 IndexedDB 读取最近消息,实现秒开和离线查看。

在 Swee 项目里,我做过 IndexedDB 持久化历史消息、Service Worker 差异化缓存,以及流式 token 批量渲染,这些都是为了提升 AI 对话体验。

Q40: PWA 在你的项目里解决了什么问题?

答案

PWA 主要解决移动端访问体验、离线能力和加载速度问题。Swee 是 AI 社交娱乐平台,用户会频繁打开聊天页面,所以我用 Service Worker 做差异化缓存,用 IndexedDB 保存历史消息,让用户弱网或离线时也能查看最近内容。

PWA 不是简单加一个 manifest,而是要结合业务场景设计缓存策略。静态资源、接口数据、媒体资源和用户消息的缓存策略都不一样。

Q41: 你怎么设计前端性能优化方案?

答案

我会先定位瓶颈,再分层优化。加载层面看资源体积、代码分割、缓存、CDN 和首屏数据;渲染层面看重渲染、长列表、动画、图片和主线程阻塞;接口层面看请求数量、并发、聚合和缓存;监控层面看真实用户指标。

虎牙 SSR 重构里,我们通过 React SSR、服务端数据预取、异步请求聚合、强缓存和协商缓存,让页面秒开率平均提升 41%,白屏时间 (<1s) 占比提升 34%。

Q42: 虎牙 SSR 重构你负责的核心是什么?

答案

我参与将虎牙直播 M 站和视频站从 PHP 重构为 React SSR 架构,核心包括文件系统路由、服务端数据预取、Redux Store 注入和 Hydration。为了提升性能,我们做了 svg sprites 减少请求、组件加载优先级、异步请求聚合、TAF/TARS RPC 替代 HTTP 降低延迟,以及静态资源强缓存、HTML 协商缓存。

迁移方式上是按页面逐步切换,配合流量灰度和比例控制,避免一次性全量替换带来的风险。

Q43: 你怎么做灰度发布和风险控制?

答案

我会先保证新旧链路可以并存,再按业务、用户、比例或页面维度逐步放量。发布前准备监控指标和回滚开关,发布后观察错误率、性能指标、接口异常和用户行为。

在 Prompt 模板系统里,我用分批灰度迁移和双写兼容保证零事故上线;在虎牙 SSR 重构里,则按页面和流量比例逐步切换。核心思路是让风险可控、问题可定位、回滚路径明确。

Q44: 你怎么设计组件库或中台物料?

答案

我会先从业务高频场景出发,比如表格、表单、上传、权限、配置编辑、富文本或代码编辑器。组件层只沉淀稳定交互和状态,业务规则通过配置、组合和插件扩展。文档上要提供使用示例、API、设计约束和常见坑。

如果和 Agent 结合,还可以让 Agent 根据需求推荐组件、生成配置、补全表单字段和生成 mock 数据,这样组件库就不只是 UI 资产,而是研发流程的一部分。

Q45: CodeMirror 6 在 Prompt 模板系统里怎么用?

答案

我用 CodeMirror 6 做模板编辑器,重点实现了模板语法高亮和变量自动补全。技术上通过自定义 ViewPlugin 和 Decoration 标记条件块、循环块和变量引用,让编辑器能理解我们的模板语法。

这样业务同学编辑 Prompt 时,不只是一个普通文本框,而是能看到变量是否合法、语法结构是否正确,并且可以快速插入已有变量,减少模板配置错误。

Q46: 你怎么设计 Prompt 模板变量体系?

答案

我会把变量定义成有类型、有说明、有默认值、有来源的结构,比如字符串、数字、布尔、数组、对象。模板渲染前先校验变量是否缺失、类型是否匹配,再进入条件块、循环块和变量插值流程。

变量体系的价值是让 Prompt 可以被业务稳定复用,也方便 SDK 接入。业务方不需要知道模板内部细节,只要按变量契约传参即可。

Q47: 你做过哪些代码生成实践?

答案

做过几类比较实际的代码生成。多语言文案系统会根据各端要求生成本地语言包代码;事件埋点系统会根据事件定义生成埋点调用代码;Prompt 模板系统提供 SDK,业务只需要按模板 key 和变量调用。

这些实践和 JD 里的代码生成 Agent 很接近。区别是以前更多是规则驱动,现在可以叠加 Agent,让它根据业务描述、接口文档和项目规范生成更完整的代码,并自动校验。

Q48: 自动化测试你会怎么在中台里落地?

答案

我会按风险分层。通用工具函数、模板渲染、权限判断、接口 Schema 这类逻辑适合单元测试;组件交互、表单校验、表格筛选适合组件测试;核心业务流程,比如模板发布、配置回滚、埋点上报链路,适合 E2E 或集成测试。

如果结合 Agent,可以让 Agent 根据变更范围推荐测试用例,生成测试骨架,并在 CI 里执行。重点不是追求所有代码 100% 覆盖,而是把高风险、高复用、高变更频率的部分保护起来。

Q49: 你怎么做前端工程化标准化?

答案

我会从代码规范、项目结构、组件规范、接口规范、提交发布和监控几个方面做。代码上统一 TypeScript、ESLint、Prettier、命名规范和目录规范;工程上用 Monorepo 管理公共包;接口上统一请求封装、错误处理、类型生成和 mock;发布上接入 CI/CD、构建检查和灰度策略。

标准化的目标不是增加流程,而是让多人、多业务线协作时默认走正确路径,减少重复沟通和隐性风险。

Q50: Turborepo Monorepo 你会怎么用?

答案

我会把多应用和公共包放在一个仓库里,比如 Web 应用、管理后台、组件库、SDK、工具包、类型包和配置包。Turborepo 可以做任务编排和缓存,比如只构建受影响的包,提升 CI 和本地开发速度。

在 Swee 项目里使用 Turborepo 的价值主要是统一工程规范,复用公共能力,减少多个仓库之间版本同步成本。

Q51: Docker 和 Kubernetes 在你的项目里承担什么角色?

答案

Docker 主要用于统一运行环境,把前端构建产物、Node 服务和依赖打包成可部署镜像。Kubernetes 负责部署、扩缩容、滚动更新、健康检查和服务治理。

对前端负责人来说,了解这些不是为了替代运维,而是为了在设计服务时考虑配置、日志、健康检查、环境变量、灰度和回滚,让应用真正能稳定上线。

Q52: 你更熟 React 还是 Vue?如果岗位要求 Vue3 怎么办?

答案

我现在更熟 React 和 Next.js,最近几年主要项目都在 React 生态。但我早期做过 Vue 2 的复杂编辑器项目,包括 Canvas、SVG、图层管理、拖拽、变换矩阵和低代码平台,所以对 Vue 的组件化和响应式思想并不陌生。

如果岗位里有 Vue3,我会把已有 Vue 经验迁移到 Composition API、refreactivecomputedwatch 和 Pinia 这套体系上。对我来说,框架 API 可以快速补齐,真正长期有价值的是复杂业务抽象、组件设计和工程化能力。

Q53: React 状态管理你怎么选型?

答案

我会根据状态范围选型。组件内部状态用 useStateuseReducer;跨组件但不复杂的状态可以用 Context;全局业务状态用 Zustand、Redux 或 Recoil;服务端数据缓存用 SWR 或 TanStack Query 更合适。

在 Swee 里我用 Zustand 管理客户端状态,用 SWR 处理数据请求和缓存。核心原则是不要把服务端数据和本地 UI 状态混在一起,否则状态会越来越难维护。

Q54: WebSocket + Protobuf 实时通信你怎么设计?

答案

在 RYZZ 主站里,我们用 WebSocket + Protobuf 做实时通信层。Protobuf 相比 JSON 能减少大约 50% 带宽,适合直播互动、预测市场和状态同步这类高频消息。

封装上,我做了消息类型分发、自动重连、指数退避、心跳保活、消息队列缓冲和状态重放。这样上层业务只需要订阅事件,不需要关心底层连接状态和重连细节。

Q55: Agent 执行过程你会用 SSE 还是 WebSocket?

答案

如果只是服务端持续向前端推送执行步骤和输出,SSE 就足够,协议简单,也适合 LLM 流式响应。如果需要前后端双向实时互动,比如用户中途追加指令、暂停、恢复、多人协同观察 Agent 执行,我会选 WebSocket。

实际可以组合使用:普通 AI 对话用 SSE,复杂可视化编排或 IDE Agent 用 WebSocket。

Q56: 你怎么做文件上传和 OSS/CDN 管理?

答案

我做过文件管理系统,核心是前端选择文件后先向后端申请上传凭证,再直传 OSS,上传完成后把文件元数据回写业务服务。这样大文件流量不经过业务服务器,后端只负责鉴权、签名和元数据管理。

CDN 刷新则放到后端统一处理,避免前端直接持有敏感权限。文件系统还要考虑目录树、权限、版本、删除恢复和引用关系。

Q57: 你怎么把 AI 能力接入中后台系统?

答案

我会从低风险、高频场景开始,比如表单说明生成、配置校验、SQL 或筛选条件解释、埋点方案生成、Prompt 调试建议、接口 mock 生成。接入方式上,前端提供清晰入口,后端通过模型网关调用 LLM,再结合业务数据、权限和日志。

中后台接 AI 不能只做聊天框,最好是嵌入到具体工作流里。例如在事件定义页面里,AI 帮你根据业务描述生成事件名、属性和埋点代码;在 Prompt 编辑页里,AI 帮你检查变量缺失和输出格式风险。

Q58: 你怎么推动团队接受 Agent 工作流?

答案

我会先选一个明确场景做试点,比如接口类型生成、埋点代码生成或 PR 摘要生成,让团队看到实际节省时间。然后把有效实践沉淀成规则、模板、命令和文档,而不是靠个人经验口口相传。

同时要建立边界:Agent 生成的代码必须经过人审、类型检查和测试;高风险操作必须确认。团队文化上,我会强调 Agent 是提升研发质量和效率的工具,不是绕过工程规范的捷径。

Q59: 你用 Claude Code / Codex 这类工具有什么经验?

答案

我的使用方式不是简单让它写代码,而是把它融入研发流程。比如用 Rules 固化项目规范,用 Skills 沉淀特定领域知识,用 Commands 复用高频操作,用 MCP 接入文件、文档和工具能力。

我会让 AI 先读代码和规则,再生成计划,执行小步修改,最后跑检查并总结变更。这样 AI 的输出更贴近项目上下文,也更容易被团队复用。

Q60: 如果让你入职后前三个月推进 Agent 方向,你会怎么规划?

答案

第一个月我会先调研现有业务线、研发流程和中台能力,找出高频重复、规则明确、收益可量化的场景,比如接口联调、代码生成、数据 mock 或知识库问答。第二个月做一个最小可用 Agent,接入模型网关、工具调用、日志监控和基础评估,只覆盖一两个核心场景。第三个月再扩大到多业务线,沉淀工具规范、Prompt 模板、权限机制、评估指标和最佳实践。

我不会一开始就追求大而全,而是用可验证的业务场景证明效果,再逐步平台化。

Q61: 你怎么处理 Agent 幻觉问题?

答案

我会从减少不确定输入和增加验证两方面处理。减少不确定输入,就是让 Agent 尽量基于真实文档、代码、接口 Schema 和知识库回答,而不是凭空猜。增加验证,就是让关键输出经过工具校验,比如类型检查、接口校验、单元测试、引用来源检查。

对于不确定问题,Agent 应该明确说缺少信息并请求补充,而不是编造答案。工程上要把“可验证”作为 Agent 能力设计的核心。

Q62: Agent 成本过高你会怎么优化?

答案

我会先看成本来自哪里,是模型太贵、上下文太长、调用次数太多,还是重试太频繁。优化方式包括:简单任务用小模型,复杂任务再升级大模型;Prompt 模板和知识检索做缓存;RAG 只注入最相关片段;工具结果结构化,减少模型重复解释;多轮任务设置最大步数和超时。

还可以按业务线、用户和场景统计单位任务成本,让成本和收益可以被量化。

Q63: 如何把知识库接入代码生成 Agent?

答案

我会把知识库分成项目规范、组件文档、接口文档、业务规则和历史案例几类。代码生成前,Agent 根据任务先检索相关规范和示例,再结合当前代码上下文生成结果。

比如生成一个中台列表页,它应该先知道项目目录规范、请求封装方式、表格组件 API、权限规则和接口 Schema。这样生成的代码才像团队自己写的,而不是一段通用示例代码。

Q64: 可视化编排 Agent 你会怎么做?

答案

我会把 Agent 工作流抽象成节点和边。节点可以是模型调用、工具调用、条件判断、人工确认、数据转换和结果输出;边表示执行顺序和条件。前端负责可视化编辑、参数配置、执行状态展示和日志回放,后端负责工作流解析、执行调度、权限和审计。

可视化编排的价值是让非核心研发也能组合已有能力,但底层工具必须标准化,否则编排界面会变成另一个复杂系统。

Q65: 你怎么设计 Agent 的工具权限?

答案

我会给工具做分级:只读工具、低风险写工具、高风险写工具。只读工具可以直接调用;低风险写工具需要校验参数和记录日志;高风险工具,比如发布配置、删除数据、改线上代码,必须人工确认并支持回滚。

权限上要和用户身份绑定,Agent 不能拥有超过用户本人的权限。审计日志要记录谁在什么场景下让 Agent 调用了什么工具、输入输出是什么、结果是否成功。

Q66: 你怎么做 AI 输出的结构化约束?

答案

我会优先让模型按 JSON Schema 或明确字段输出,再由服务端做结构化解析和校验。校验失败时,不直接把错误结果给业务用,而是让模型修复一次,或者返回明确错误。

在业务里,比如生成埋点事件定义、表单配置、接口 mock,都非常适合结构化输出。只要 Schema 设计好,后续就可以自动保存、预览、校验和生成代码。

Q67: 你怎么处理多模型接入?

答案

我会通过模型网关屏蔽差异,对上层暴露统一接口,包括 chat、stream、embedding、tool calling、重试和日志。不同模型的参数、错误码、流式协议和工具调用格式由适配层处理。

这样业务不需要关心底层用哪个模型,也方便做灰度、降级和成本优化。比如简单分类任务用便宜模型,复杂代码生成用能力更强的模型。

Q68: 你怎么回答“你有什么不足”?

答案

我会如实说:我最近几年更偏 React、Next.js 和 Node.js 全栈,Vue3 的一线项目经验没有 React 多。但我过去做过 Vue 复杂编辑器,也理解响应式和组件化底层思想,所以补齐 Vue3 API 和生态不是问题。

另外 Agent 框架方面,我更多是基于 LLM API、Prompt、工具调用、MCP 和工程化流程做落地,对 LangChain、Dify 这类框架会结合团队现状选型,不会为了框架而框架。我的优势是能把 AI 能力真正落进业务和工程流程里。

Q69: 如果面试官问你期望在这个岗位解决什么问题,你怎么答?

答案

我希望解决两个问题。第一是中台研发效率问题,把多业务线重复的组件、接口、配置、埋点、国际化和发布能力沉淀下来,让业务开发更快更稳。第二是 AI Agent 的落地问题,把代码生成、接口联调、数据 mock、知识库问答和质量检查做成可复用能力,并且有监控、评估、安全和成本控制。

简单说,我希望做的不只是一个功能,而是一套能持续提升团队效率的研发基础设施。

Q70: 你有什么想问面试官的问题?

答案

我会问三个问题。第一,目前团队最希望 Agent 先解决哪个研发痛点,是代码生成、接口联调、测试、知识库,还是业务运营提效?第二,现在中台的复用资产有哪些,比如组件库、接口规范、脚手架、配置中心和监控体系,哪些已经成熟,哪些还需要建设?第三,团队对 Agent 效果的评价标准是什么,是节省人力、提升质量、缩短交付周期,还是降低接入 AI 的门槛?

这些问题能帮助我判断入职后优先级,也能体现我关注落地效果而不是只聊概念。

Agent 与项目深挖追问

Q71: 如果面试官追问“你没有直接用 LangChain,怎么证明你懂 Agent 框架思想”?

答案

我会说,Agent 框架的核心不是某个库,而是运行时抽象:模型调用、Prompt 管理、工具注册、工具选择、上下文管理、执行循环、错误恢复、观测评估和权限控制。LangChain、Semantic Kernel、Dify 都是在这些抽象上提供不同封装。

我在项目里虽然更多是基于 LLM API、Prompt 模板、SDK、MCP 和工具链做落地,但底层思想是一致的。比如 Prompt 模板系统解决 Prompt 资产化,MCP 和工具调用解决能力接入,日志和 Playground 解决可观测和调试,缓存和灰度解决稳定性。这些能力组合起来就是企业内部 Agent 平台的基础。

Q72: 如果让你在 LangChain、Dify、自研之间选型,你会怎么判断?

答案

我会看三个维度。第一是业务复杂度,如果只是知识库问答或简单工作流,Dify 这类平台能快速验证;第二是工程集成深度,如果要和内部脚手架、IDE、CI、权限、组件库深度结合,自研 Runtime 或轻量框架会更可控;第三是团队维护能力,如果团队 Agent 经验不足,可以先用成熟平台跑通,再逐步抽象内部能力。

我的倾向是先用低成本方式做 PoC,验证任务完成率、成本和维护复杂度;一旦进入核心研发链路,就要把工具协议、权限、日志、评估和灰度掌握在自己手里。

Q73: Agent 工具注册中心你会怎么设计?

答案

我会把工具注册中心设计成一个带元数据的能力市场。每个工具都要声明名称、描述、参数 Schema、返回 Schema、权限级别、副作用级别、超时时间、重试策略、负责人和版本。

Agent 调用工具前,先根据用户身份、业务线和场景过滤可用工具,再把最相关的工具暴露给模型。这样可以减少模型选择范围,也能避免越权调用。工具变更要有版本管理,避免参数改了以后影响已有 Agent 流程。

Q74: Agent 如何处理中途失败?

答案

我会按失败类型处理。如果是参数校验失败,可以把错误结构化返回给模型,让它修正参数后重试;如果是工具超时,可以按策略重试或降级;如果是权限失败,就不能让模型绕过,而是明确提示无权限;如果是模型输出不符合 Schema,可以触发一次修复或要求人工确认。

关键是失败要可恢复、可解释、可观测。Agent 不应该失败后只给一句“出错了”,而要告诉用户卡在哪一步、原因是什么、下一步能怎么处理。

Q75: 你怎么防止 Agent 在代码生成时改坏项目?

答案

我会设置几道边界。第一,Agent 必须先读取项目规则和相关文件,不能凭空生成。第二,修改范围要最小化,只改用户授权的文件。第三,生成后必须跑格式化、类型检查、测试或构建。第四,输出 diff 给人审,不允许自动提交。第五,危险操作,比如删除文件、大规模重构、改构建配置,要二次确认。

从流程上看,Agent 可以提高效率,但工程责任还是要通过规范、工具和人工 review 兜住。

Q76: RAG 知识库如何做权限隔离?

答案

我会在文档入库时就写入权限元数据,比如业务线、角色、项目、密级和可见范围。检索时先根据用户身份做过滤,或者召回后再做严格过滤,但最终返回给模型的上下文必须是用户有权限访问的内容。

另外,向量本身也可能泄露语义信息,所以不同密级的数据最好分集合或分索引管理。回答时也要带来源,方便审计模型到底引用了哪些内容。

Q77: RAG 评估集你会怎么构建?

答案

我会从真实业务问题里抽样,构建“问题、标准答案、应召回文档、禁止回答范围”的评估集。指标上看召回率、准确率、引用正确率、答案可用性和幻觉率。

比如中台知识库可以准备接口规范类、组件使用类、故障排查类、项目流程类问题。每次切分策略、embedding 模型、重排模型或 Prompt 改动后,都跑一遍评估集,避免凭感觉调参。

Q78: 你怎么把 Prompt 模板系统升级成 Agent Prompt 中台?

答案

现有 Prompt 模板系统已经有模板、变量、版本、审批、Playground 和 SDK。要升级成 Agent Prompt 中台,我会增加几类能力:工具绑定、知识库绑定、模型参数配置、评估集绑定、灰度实验和执行链路回放。

这样一个 Agent 场景不只是一个 Prompt,而是一组 Prompt、工具、知识库、模型配置和评估规则。业务方可以像发布配置一样发布 Agent 能力,平台侧负责稳定性和质量。

Q79: 如果面试官追问 Prompt 模板的三步渲染管线,怎么展开?

答案

我会解释成:第一步处理条件块,比如不同用户状态、语言、场景下是否展示某段 Prompt;第二步处理循环块,比如把候选角色、历史事件、商品列表展开成模型可读的上下文;第三步做变量插值,把业务传入的变量填进模板。

这三步拆开后,调试会清晰很多。Playground 可以展示每一步中间结果,业务同学能知道是条件没命中、循环数据为空,还是变量没有传对。

Q80: 如果面试官追问“Prompt 迭代周期从 2-3 天到分钟级”是怎么做到的?

答案

以前 Prompt 分散在代码里,改一次要找研发、改代码、发布、验证,所以周期很长。我做的系统把 Prompt 从代码里抽出来,变成后台可编辑、可预览、可审批、可发布的资产。

业务可以在 Playground 里直接调变量和模型参数,验证效果后走审批发布。线上 SDK 通过模板 key 拉取最新版本,并通过多级缓存保证性能。这样大多数 Prompt 调整不需要重新发版,迭代自然从天级变成分钟级。

Q81: 如果面试官追问事件埋点系统的“代码自动生成”,你怎么讲?

答案

我会说,事件管理后台里每个事件都有事件名、触发时机、属性定义、枚举值和说明。基于这些结构化定义,可以生成前端调用代码、TypeScript 类型和接入示例。

这样业务研发不用手写字符串,也能减少事件名拼错、属性漏传、枚举不一致的问题。这个经验可以直接迁移到 Agent 场景:Agent 读取事件定义和页面代码,自动推荐埋点位置并生成调用代码,再通过类型和 Schema 校验保证正确性。

Q82: 如果面试官追问埋点 SDK 为什么要 sendBeacon 降级,你怎么答?

答案

sendBeacon 适合页面卸载时发送少量数据,浏览器会尽量保证请求发出,而且不会阻塞页面跳转。但它也有大小限制和兼容性问题,所以不能只依赖它。

我的设计是优先 sendBeacon,失败时降级到 fetch,再降级到 XHR。配合批量缓冲和页面生命周期事件,可以在不影响用户体验的前提下提高上报成功率。

Q83: 如果面试官追问 PostgreSQL JSONB + GIN 的收益,你怎么讲?

答案

事件埋点的属性是半结构化的,不同事件属性差异很大。如果每个属性都拆成固定列,表结构会频繁变更,也不适合快速迭代。JSONB 可以把事件属性作为结构化 JSON 存下来,GIN 索引可以提升按属性查询的效率。

当然,核心公共字段,比如事件名、用户、时间、业务线,还是应该作为普通列存储并建立索引。JSONB 适合扩展属性,不适合替代所有结构化设计。

Q84: 如果面试官追问 Swee AI 对话的多类型内容混排,怎么实现?

答案

我会把消息设计成统一消息模型,消息内容不是单纯字符串,而是一个 block 列表。每个 block 有类型,比如 text、image、audio、video、option、business-card,再有对应的数据结构。

流式返回时,服务端可以按事件类型推送增量内容,前端根据 block 类型选择渲染组件。这样后续新增业务卡片,不需要重写整个聊天框,只需要扩展一种 block 类型和渲染器。

Q85: 如果面试官追问 IndexedDB 在 AI 聊天里的作用,你怎么讲?

答案

AI 聊天历史数据量可能比较大,而且包含多媒体和结构化卡片,放在 localStorage 不合适。IndexedDB 更适合存结构化、大容量、异步访问的数据。

我用它做历史消息持久化,用户重新打开页面时可以先从本地展示最近消息,再向服务端同步最新状态。这样首屏更快,弱网下也能查看历史内容。

Q86: 如果面试官追问虎牙 SSR 的 Hydration 怎么保证一致性,你怎么答?

答案

SSR 一致性的关键是服务端和客户端使用同一份初始数据和同一套路由组件。服务端渲染时完成数据预取,把 Redux Store 注入到 HTML,客户端启动时用这份 Store 做 Hydration,避免客户端再生成一份不同初始状态。

同时要避免在首屏渲染阶段直接依赖浏览器专属状态,比如 window 尺寸、localStorage 或随机数。如果必须依赖,要放到客户端 effect 里处理。

Q87: 如果面试官追问虎牙 SSR 渐进式迁移怎么做,你怎么讲?

答案

我会说我们不是一次性替换所有页面,而是按页面维度逐步迁移。新旧系统可以并存,通过流量分发控制某些页面或某些比例用户访问新 SSR 链路。

每次放量都观察白屏时间、错误率、接口耗时和用户行为。如果指标异常,可以快速把流量切回旧链路。这种方式适合大型线上系统,能降低重构风险。

Q88: 如果面试官追问凡科快图从 Canvas 转 SVG 的原因,你怎么答?

答案

Canvas 更适合像素级绘制和高频重绘,但编辑器里很多对象是文本、图形、图层和可交互元素,需要选择、拖拽、编辑、缩放和命中检测。SVG 天然有 DOM 结构,对矢量图形、文本编辑、事件处理和对象级操作更友好。

所以我们把编辑器从 Canvas 重构到 SVG,命中检测、变换、文本编辑、图层管理直接复用 DOM 和事件系统,不用自己维护一套对象状态机,整体开发成本减少约 40%,可维护性也明显提升。复杂计算仍然可以用 Web Worker 和 OffscreenCanvas 处理。

Q89: 如果面试官追问 Web Worker + OffscreenCanvas 解决了什么问题,你怎么讲?

答案

编辑器里有很多计算密集型任务,比如滤镜、坐标变换、碰撞检测、边界判断和复杂图形处理。如果都放在主线程,会阻塞拖拽、输入和动画,用户会感觉卡顿。

Web Worker 可以把计算移到后台线程,OffscreenCanvas 可以让部分 Canvas 绘制脱离主线程。主线程只负责 UI 交互和结果合成,整体响应会更流畅。

Q90: 如果最后让你总结自己的核心优势,你怎么说?

答案

我的核心优势是把复杂业务做成可复用平台能力。前端上,我能处理 React、Next.js、性能优化、PWA、SSR、复杂编辑器和中后台系统;全栈上,我能用 NestJS、数据库、Redis、Kafka 把接口和数据链路打通;AI 上,我做过 Prompt 模板管理、流式对话、SDK 接入,也熟悉 Agent 工具链和 AI 辅助研发流程。

所以我适合这个岗位的原因是:既能写业务和架构,也能把 AI Agent 和中台工程化结合起来,真正服务多业务线效率提升。

JD 直接对应的补充追问

Q91: JD 里要求熟悉 MongoDB,你用过吗?

答案

生产项目主要用 MySQL 和 PostgreSQL,MongoDB 我用过但不是最近主线。我理解它的核心定位:文档型数据库,Schema 灵活,适合存结构不固定、查询模式以文档为主、关系不复杂的场景,比如用户画像、评论、消息、日志、配置快照。

选型上我会看几点:是否有强事务和复杂 JOIN(有就更倾向 MySQL/PostgreSQL);属性是否高度差异化(差异大且需要查询,PostgreSQL JSONB 也是好选择);读写量级和扩展模式。如果团队主用 MongoDB,我能在一两周内补齐 schema 设计、索引、聚合管道、复制集和事务这些核心点,因为底层数据库思路是相通的。

Q92: JD 提到 Node.js 或 Go 优先,你 Go 怎么样?

答案

我后端主线是 Node.js + NestJS,Go 没有生产项目经验,只看过基础语法和并发模型(goroutine、channel、context)。我会如实说不是 Go 工程师。

但如果团队中台服务有 Go 栈,我可以从两个方向切入:一是先在 Node.js 侧承担前后端协同、Agent 中间件、SDK 这些我熟悉的部分,二是根据团队规范学习 Go,从修复 issue 和写小工具开始。我做过 Node.js、PHP、NestJS、Next.js 这些不同后端栈的切换,对我来说语言不是最难的部分,难的是工程规范、性能模型和领域知识。

Q93: JD 写"深入 Vue3",能讲讲你对 Composition API 的理解吗?

答案

Composition API 解决的是 Options API 在复杂组件里逻辑碎片化的问题。Options API 把同一个功能分散到 data、methods、computed、watch、生命周期里,逻辑越多越难维护;Composition API 用 setup<script setup> 把同一逻辑聚合到一起,可以提取成 composable(类似 React 自定义 hook)跨组件复用。

核心 API 我理解:ref 是包装值的响应式引用,访问要 .valuereactive 是对象的代理响应式,深层响应;computed 是缓存的派生值;watch 显式监听特定源,watchEffect 自动追踪依赖。底层是 Proxy + 依赖收集,相比 Vue2 的 Object.defineProperty 能监听属性新增删除和数组下标。

如果项目用 Vue3,我会按 React Hooks 的经验组织 composable:每个 composable 单一职责、避免循环依赖、显式返回响应式值。Pinia 替代 Vuex 我也清楚思路。

Q94: LangChain、Semantic Kernel、Dify 你会怎么选?

答案

我会按团队定位和场景选。Dify 偏低代码 BaaS,适合非研发也要快速搭 AI 应用、做内部工具或 PoC 验证,但深度定制和工程集成会受平台约束。LangChain 是开发框架,生态最大、Tools/Agents/RAG 抽象完整,适合 Python/Node 团队做有定制需求的 Agent,缺点是抽象层多、性能和调试成本要注意。Semantic Kernel 是微软出的,Plugin/Planner 设计干净,在 .NET 体系下更顺,前端为主的团队选它的不多。

我的实际取向:业务线快速验证用 Dify;研发链路深度集成(脚手架、接口联调、组件推荐)我倾向基于 LangChain.js 或 Vercel AI SDK 自建轻量 Runtime,把工具协议、权限、日志、评估握在自己手里。框架是脚手架,平台能力(工具市场、Prompt 资产、评估、监控)才是中台的核心。

Q95: ReAct 循环代码层面怎么实现?

答案

核心是一个 while 循环:每一步把"系统指令 + 历史步骤 + 当前观察"喂给模型,模型返回"思考 + 下一步动作",如果是工具调用就执行工具拿到结果,作为新 observation 加入历史,进入下一轮;如果是 final answer 就退出。退出条件还要加最大步数、超时、token 上限和异常熔断。

async function runReAct(input: string, ctx: Ctx) {
const history: Step[] = [];
for (let i = 0; i < ctx.maxSteps; i++) {
const resp = await llm.chat({
messages: buildMessages(ctx.systemPrompt, history, input),
tools: ctx.tools.map(t => t.schema), // 工具 Schema 直接喂给模型
});
if (resp.toolCalls?.length) {
// 并行或串行执行,失败要结构化返回让模型自我修复
const obs = await Promise.all(resp.toolCalls.map(c => ctx.invoke(c)));
history.push({ thought: resp.content, calls: resp.toolCalls, obs });
} else {
return { answer: resp.content, history }; // 终态
}
}
throw new MaxStepError(history);
}

关键工程细节:工具结果必须结构化(status/data/error),失败要让模型能"读懂并修正";history 要做压缩,避免上下文爆炸;每一步都要写日志(输入、输出、耗时、token),方便评估和回放。

Q96: 接口联调 Agent 具体怎么读 OpenAPI 并生成代码?

答案

我会拆成"读 → 生成 → 验证 → 反馈"四步。:通过 MCP 或后端接口拿到 OpenAPI/Apifox 的 JSON,解析出 paths、parameters、requestBody、responses 的 schema。生成:用模板(不是让模型纯生成)渲染出 TS 类型、请求函数和 mock 数据;模型只负责选择业务命名、补注释、生成边界 case 的 mock。验证:生成后立即跑 tsc --noEmit 和 Zod/Joi schema 校验,类型错就回退给模型修。反馈:调用真实接口或 MSW mock,对比返回字段和 schema,如果后端实际返回多/少字段或类型对不上,输出明确的 diff 让前后端确认。

为什么"模板 + 模型混合"而不是纯模型:纯模型生成接口代码容易胡编字段、用错版本 API;模板保证骨架正确,模型只负责需要语义判断的部分,能让一次通过率从六七成提到九成以上。

Q97: JD 里的"组件推荐"你会怎么实现?

答案

我会做成"基于向量检索的组件推荐 Agent"。索引侧:把组件库里每个组件的名称、描述、Props、示例代码、典型场景做成文档,用 embedding 入向量库,metadata 带组件版本、稳定度、适用范围。召回侧:用户描述需求("想要一个支持搜索和多选的下拉")→ embedding 检索 Top K 候选 → 按使用频次、稳定度、版本做 rerank。生成侧:把候选组件的 Props 和示例喂给模型,让它生成可直接复制的代码片段,标注为什么选这个组件(命中了哪些需求)。

延伸:如果用户已经写了一段代码,可以做"组件替换推荐",检测代码里手写的逻辑和组件库里成熟组件的语义相似度,提示"你这段可以用 <XTable> 替代"。这个能力还能反向驱动组件库治理 —— 看哪些组件被频繁推荐、哪些从来不被推荐,决定优化和废弃。

Q98: AI 辅助测试 Agent 你会怎么设计?

答案

分三层。用例生成:Agent 读取被测函数/组件、相关类型、最近的 PR diff、历史 bug,生成 happy path、边界、异常分支的 Vitest/Jest 用例骨架,结构化输出 describe/it 名称和断言。用例补全:基于代码 AST 找出未覆盖分支、未触达的 props 组合,针对性补用例,而不是堆覆盖率数字。回归判断:CI 跑完后,Agent 分析失败用例和代码 diff,判断是"代码出错"还是"用例需要更新",给出建议而不是直接改。

底线是 Agent 只生成和建议,不直接 merge 测试代码,必须人审。否则容易产生"测试通过但什么都没测"的情况(比如断言写成 expect(x).toBeDefined() 这种没意义的语句)。评估指标看:用例首次通过率、人工修改量、新引入 bug 漏测率。

Q99: 可视化编排 Agent 节点和数据流怎么设计?

答案

节点分五类:输入节点(用户输入、表单、文件、API 响应)、模型节点(LLM 调用,配置模型/温度/Prompt 模板)、工具节点(调内部 API、调 MCP、查 RAG)、控制节点(条件分支、循环、并行、人工确认)、输出节点(返回前端、写入存储、发通知)。

数据流用"端口 + Schema"约束:每个节点声明输入端口和输出端口的 Schema,连线时编辑器自动校验类型是否匹配;运行时每个节点产出的数据进入上下文,下游节点通过表达式(${nodeA.output.userId})引用。执行引擎在后端,用 DAG 调度,支持串行、并行、重试、超时、断点续跑。前端只负责画布编辑、参数配置、运行状态和日志回放。

工程要点:节点和工具同源(编排里的工具节点就是 Function Calling 工具,统一注册中心);执行有版本快照,回滚和复现不靠人工;提供"调试模式"逐节点单步执行,每步看输入输出。

Q100: 多业务线 SDK 怎么治理版本和升级?

答案

我做 Prompt SDK 和埋点 SDK 时形成了一套规则。版本:严格 SemVer,breaking change 必须 major,每次发布生成 changelog 和迁移指南。发布:用 Changesets 管理变更日志,CI 自动发包到私有 npm,灰度版本走 next tag。接入约束:Monorepo 里强制 peerDependencies 对齐,业务包不能锁死小版本;SDK 自身要做"运行时兼容检测",发现服务端协议升级时给出明确报错而不是静默失败。

升级推动:旧版本设过期时间(比如 6 个月),过期前邮件 + 仓库 issue 提醒;提供 codemod 自动迁移;CI 加规则扫到旧版本就 warning,过期就 error。观测:服务端按 SDK 版本统计调用量、错误率、性能,看清升级渗透率。核心是给业务一条清晰的升级路径,而不是让他们自己摸索。

Q101: Agent 离线评估怎么接入 CI?

答案

评估集存到仓库或对象存储,每条样本包括"输入、上下文、期望输出(或期望工具调用序列)、断言规则"。CI 流程:PR 触发 → 跑评估集 → 对比上次基线 → 生成对比报告(任务完成率、工具成功率、首次通过率、平均 token、耗时、幻觉率)→ 关键指标回退超阈值就阻塞合并。

实现上有几个细节:降本:用小评估集(50-200 条)做 PR 检查,大评估集(千级)走每日定时;复现:固定 seed、温度调到 0.1、记录模型版本,避免随机性干扰判断;LLM-as-Judge:用强模型做评分要校准,定期人工抽样对齐评分一致性。指标不能只看通过率,还要看回归(之前能做对现在做错的样本)和成本曲线。

Q102: Function Calling 和 MCP 在中台里怎么搭配?

答案

简单说,Function Calling 是"模型调用工具的协议",MCP 是"工具暴露能力的协议",两者不冲突,是一个体系里的不同层。

实际架构:内部所有工具(接口查询、文件读写、知识库检索、组件推荐)都按 MCP 规范暴露,这样 Claude Code、Cursor 这类 IDE 客户端可以直接复用同一份工具;Agent Runtime 拿到 MCP 工具列表后,转换成 Function Calling 的 JSON Schema 喂给模型,让模型决定调谁。MCP 解决"工具能被多客户端复用"的问题,Function Calling 解决"模型怎么决定调用"的问题。

收益是工具只写一次:研发自己用的 IDE Agent、给业务用的中台 Agent、给运营用的可视化编排,背后是同一套 MCP 工具。这也是 JD 里"为多业务线提供低门槛 AI 能力接入"的关键。

Q103: 你心目中的中台前端整体分层是怎样的?

答案

我会分五层。基础设施层:脚手架、CI/CD、Monorepo、构建工具、Docker 镜像、监控 SDK。通用能力层:组件库、设计系统、请求层、错误处理、权限、国际化、埋点 SDK、文件 SDK。业务中台层:配置中心、Prompt 中台、事件埋点平台、多语言平台、工作流引擎、Agent 中间件。应用层:各业务线的 Web 应用、管理后台、移动 H5。接入与协同层:API 文档、Mock 平台、组件市场、知识库、Code Review 流程。

每一层只依赖更底层,不反向依赖。中台真正的价值不是组件多,而是上层应用能用最少的代码描述业务,不重复造轮子。AI Agent 中间件我会放在业务中台层,让它能调用通用能力层的工具,也能被应用层各自配置。

Q104: Agent 资产库具体存什么、怎么组织?

答案

资产分五类。Prompt 资产:模板、变量、版本、评估集,存在 Prompt 中台。工具资产:MCP 工具 manifest、参数 Schema、权限级别、调用示例,存在工具注册中心。知识资产:RAG 用的文档片段、向量、元数据、来源、过期策略,存在向量库和元数据库。Agent 配置:场景定义(用哪些 Prompt + 哪些工具 + 哪些知识库 + 哪个模型 + 哪份评估集),存在 Agent 中间件。最佳实践:Skills、Slash Commands、Rules、Hooks、踩坑案例,存在团队仓库或 wiki,配合 MCP 让 IDE 直接拉取。

组织上按"业务线 + 场景 + 版本"维度切,每类资产都有 owner、审批流和评估指标。没有资产化的 Agent 就是个人 demo,不是中台能力。

Q105: 你怎么在团队推广 Agent 工作流?

答案

不堆概念,按"先 ROI 后规模化"做。第一步选锚点:挑一个最高频、最痛、可量化的场景,比如接口类型生成或埋点代码生成。第二步做出可见效果:自己跑通,记录"用前 vs 用后"的时间差和 diff 质量,在周会上演示真实场景而不是 PPT。第三步降低使用门槛:把流程封装成 Slash Command 或脚手架命令,新人不用学复杂 Prompt 就能用。第四步沉淀文化:在 Code Review、技术分享、新人 onboarding 里固定环节讲 Agent 用法,把"用 AI 解决"变成默认选项之一。

避免两个反模式:一是搞 KPI 强推("必须每个 PR 用 AI"),会导致水任务;二是只让某几个人玩,团队其他人觉得是黑科技。健康状态是大家自然用、自然吐槽、自然贡献 Skills 和规则。

Q106: JD 说"评估 Agent 方案的成本与效果",你具体怎么衡量?

答案

成本和效果都要量化,缺一不可。成本:单位任务的 token 成本(区分输入/输出/缓存命中)、模型调用次数、平均耗时、人工干预次数、维护投入(工具、Prompt、知识库的更新成本)。效果:业务侧看任务完成率、人工修改率、用户采纳率、节省工时;技术侧看工具调用成功率、Schema 错误率、幻觉率、回归率。

决策模型:把效果折算成"节省的人力成本 / 提升的业务指标",对比 Agent 自身成本(token + 维护 + 基础设施),算 ROI。如果 ROI < 1 且短期看不到拐点,要么换更便宜的模型/方案,要么停掉。这个评估每个季度做一次,避免某个 Agent"曾经有效但现在已经不值得维护"。

Q107: IDE 内的 Agent 和平台型 Agent 你会怎么选?

答案

我把它们看成互补,不是二选一。IDE Agent(Cursor、Claude Code、Copilot 类)适合个人研发场景:代码补全、PR 摘要、调试、文档查询,强项是上下文紧贴当前代码,低延迟、低门槛。平台型 Agent(中台 Web 应用)适合跨人跨业务线场景:组件推荐、接口联调审核、批量代码迁移、运营/产品也要用的能力,强项是数据沉淀、权限管控、可追溯。

底层共享一套 MCP 工具和资产库,前端形态不同。落地节奏上,团队从 IDE Agent 切入门槛最低(人手一份配置就能用),平台型 Agent 需要中台投入,适合等 IDE Agent 跑出效果后做下沉。

Q108: 怎么让前端 Agent 也能被运营/产品用?

答案

研发用 IDE 形态,非研发要 Web 表单形态。我会做一层"业务模板":把研发抽象的"Prompt + 工具 + 知识库"打包成"运营能看懂的任务",比如"生成活动页文案"、"分析这批埋点数据"、"按这份需求文档生成原型描述"。运营看到的是简单的输入框 + 几个下拉,不需要懂 Prompt。

关键设计:输入做 Schema 校验避免乱传;输出结构化,能直接复制到他们的工作流(Notion、飞书、PRD 工具);调用历史保留,方便复用上次结果;高消耗任务有审批或额度。这才是"低门槛 AI 能力接入"的真实形态。

Q109: Agent 多轮对话的上下文怎么管理,避免爆窗口?

答案

几种策略组合用。滑动窗口:保留最近 N 轮原文,更早的丢掉,适合短任务。摘要压缩:超过阈值时让模型把早期对话压成摘要,保留关键决策和事实,适合长对话。结构化记忆:抽取关键实体(用户偏好、已确认的需求、已调用的工具结果)存到 KV,每轮按需注入,而不是把全部历史喂回去。分段记忆:长任务拆成子任务,每个子任务独立上下文,结束时把结论汇总到主上下文。

工程上还要做"上下文预算":每轮调用前算系统提示 + 历史 + 工具结果的 token 数,超阈值触发压缩。监控记录每次上下文大小,发现某场景频繁逼近窗口要么换长上下文模型,要么优化记忆策略。

Q110: 如果让你入职后做的第一个 Agent,你会选什么场景?

答案

我会选"接口联调 Agent"作为第一个。理由:痛点最普遍,前端等接口、字段对不上、mock 和真实不一致是日常痛点;收益可量化,能直接对比"用前接口联调耗时 vs 用后";风险可控,输出是代码和报告,不直接改线上;能复用现有资产,OpenAPI 已经有,请求层和类型生成是熟领域;能带出一整套基建,做下来必然要建立工具注册、Prompt 模板、评估集、监控、SDK 这些底层能力,第二个 Agent(比如组件推荐或测试 Agent)就能快速复用。

第一个月做 PoC、跑通一两条产线、收 10-20 个真实反馈;第二个月稳定指标、出最佳实践;第三个月再上第二个场景。一个有效的小 Agent 比一个大而空的 Agent 平台更能赢得团队信任。