AI前端开发面试题分享

在这里插入图片描述

一面:技术基础

1. Promise 状态流转与 async/await 底层原理

Promise 状态流转

  • Promise 有三种状态:pending(待定)、fulfilled(已成功)、rejected(已失败)。
  • 状态只能从 pending 转变为 fulfilledrejected,且不可逆
  • 转变时机:调用 resolve(value)fulfilled;调用 reject(reason) 或抛出异常 → rejected
  • .then/.catch 会返回新的 Promise,从而实现链式调用,值也会沿着链传递、转换。

async/await 底层原理

  • async 函数本质是返回 Promise 的函数,内部返回值会被 Promise.resolve 包裹,异常会被捕获并转为 rejected
  • await 会暂停当前 async 函数的执行,等待右侧 Promise 落定,然后恢复执行并返回其值。
  • 底层是 Generator + 自动执行器(co 库模式)。Babel / TypeScript 编译后会将 async 函数转为 Generator,await 变成 yield,外部通过递归调用 next() 并处理 Promise 实现自动流转。
  • 暂停/恢复可理解为每个 await 处将后续代码包装成一个微任务回调,注册到当前 Promise 的 .then 中,从而不阻塞主线程。

2. 手写防抖函数 & AI 输入框应用

function debounce(fn, delay) {
  let timer = null;
  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}

在 AI 对话输入框中的应用

  • 用户输入提示词(prompt)时,通常需要提供联想建议、校验或预处理。直接在每次 onChange 触发请求会造成性能浪费和闪烁。
  • 使用防抖后,在用户连续输入时只执行一次回调(例如 300ms 后),可用于:
    • 发送提示词联想请求;
    • 实时统计输入 tokens 长度并给出提示;
    • 更新预览区域的占位符渲染。
  • 同时配合立即执行选项(leading: true)可让首次输入即时反馈,后续连续输入等待停顿时再更新。

3. 事件循环:宏任务与微任务执行顺序

  • 每次执行栈清空后,事件循环会先清空微任务队列(Promise.then、MutationObserver、queueMicrotask),然后再取一个宏任务(setTimeout、setInterval、I/O、UI render)。
  • 执行完该宏任务后,再次清空所有微任务,如此循环。
  • 示例顺序:
    1. 执行全局同步代码。
    2. 清空当前微任务(比如 Promise 回调)。
    3. 执行一个宏任务(setTimeout 回调)。
    4. 再次清空微任务…
  • 浏览器可能在两轮宏任务之间插入渲染(requestAnimationFrame 在渲染前执行)。

对 AI 应用的影响:流式数据到达时,若批量更新 DOM 可以合并到微任务,避免多次渲染阻塞,也可利用 requestAnimationFrame 做节流。


4. CSS 垂直居中布局(三种方式)

  1. Flexbox(推荐)
.parent { display: flex; align-items: center; justify-content: center; }
  1. Grid
.parent { display: grid; place-items: center; }
  1. 定位 + transform(适用于未知尺寸)
.parent { position: relative; }
.child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }

其他还有 table-cell + vertical-align、行高等于高度(单行文本)等。


5. 原型链与继承

  • 每个 JS 对象都有一个内部属性 [[Prototype]](可通过 __proto__Object.getPrototypeOf 访问),指向其构造函数的 prototype 对象。
  • 当访问对象的属性时,若自身没有,会沿着原型链向上查找,直到 null(终点)。
  • prototype 是函数才有的属性,用于构造函数生成的实例共享方法和属性。

实现继承的几种方式

  • 原型链继承Child.prototype = new Parent(),但引用值会共享。
  • 构造函数继承Parent.call(this),解决引用共享,但不能继承原型方法。
  • 组合继承:两者结合,但会调用两次父类构造函数。
  • 寄生组合式继承(最理想):Child.prototype = Object.create(Parent.prototype),然后修复 constructor。
  • ES6 class extends + super 本质上是寄生组合式继承的语法糖,同时支持内置类继承。

6. 手写深拷贝(支持循环引用)

function deepClone(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (map.has(obj)) return map.get(obj); // 处理循环引用

  const clone = Array.isArray(obj) ? [] : {};
  map.set(obj, clone);

  // 可继续处理 Date、RegExp、Set、Map 等特殊对象
  for (const key of Object.keys(obj)) {
    clone[key] = deepClone(obj[key], map);
  }
  return clone;
}

利用 WeakMap 跟踪已拷贝对象,键是原始对象,值是克隆对象;遇到重复引用直接返回,避免无限递归。


二面:深入原理与项目

1. AI 应用中流式输出(Streaming)的 UI 渲染

  • 后端通过 SSE(Server-Sent Events)或 HTTP 长连接(ReadableStream)逐步返回 tokens。
  • 前端使用 EventSourcefetch + ReadableStream 逐步解析 data: 行。
  • UI 方案:
    • 维护一个响应式字符串状态,每次收到新 token 就追加并更新。
    • 为避免频繁渲染,可使用 requestAnimationFrame 节流,或利用 React 的自动批处理(React 18+)。
    • 使用虚拟列表,当对话条数极多时只渲染可见区域,防止卡顿。
    • 对 Markdown/代码块做增量解析(如基于 stream 的解析器),避免每次重新解析整段文字。
    • 光标闪烁效果和“正在输入”动画提升体验。

2. React Fiber 如何优化渲染性能

  • Fiber 是 React 16 引入的可中断的调和引擎,把渲染工作拆成小单元(fiber 节点),可以暂停、恢复、丢弃。
  • 利用 时间切片(Time Slicing)requestIdleCallback 思想,在浏览器空闲时执行工作,不阻塞主线程。
  • 将调和分为 render 阶段(可中断)和 commit 阶段(不可中断,更新 DOM)。
  • 引入了优先级调度(Lane 模型),高优先级更新(如用户输入)能打断低优先级渲染,让页面保持响应。
  • 在 AI 应用中,流式内容频繁更新,Fiber 能避免每次 token 到达导致的完整重排,只做增量标记和异步渲染。

3. RAG(检索增强生成)及前端的角色

  • RAG 在生成回答前,先用用户问题检索知识库,将相关文档片段拼入 prompt,提升回答准确性。
  • 前端角色:
    • 提供可搜索的知识源选择(文件上传、URL 抓取、知识库选择)。
    • 构建 RAG 工作流界面:文档管理、切片预览、检索测试。
    • 展示引用来源:在生成结果中高亮引用,点击可查看原文上下文。
    • 实时反馈检索质量:展示相似度得分、检索耗时,支持调整参数(topK、相似度阈值)。
    • 处理长上下文拼装,前端可预估算 tokens,提示用户分段上传。

4. 优化大模型首字响应时间(TTFT)

TTFT 是从请求发出到收到第一个生成 token 的时间。

  • 网络与连接优化:预连接、CDN、就近接入;使用 HTTP/2 或 WebSocket 复用连接。
  • 请求体精减:压缩 prompt、用更少的 tokens 做系统指令。
  • 流式传输优先:服务端立即返回第一个 token,减少等待感。
  • 前端预加载:用户输入时预检 prompt 合法性,提前发起“空”请求进行模型预热(需后端支持)。
  • 预取上下文:对于常见问题缓存 prompt embedding,避免重复计算。
  • 骨架屏/乐观更新:在等待首个 token 前展示占位动画,降低感知延迟。

5. 前端工程 CI/CD 理解(AI 项目特性)

  • CI(持续集成):代码提交后自动触发构建、lint、单元测试、类型检查、安全扫描。AI 项目还需:
    • 验证提示词模板完整性;
    • 执行 E2E 测试时 mock 模型输出,保证流式渲染正常;
    • 检查模型接口 schema 变更的影响。
  • CD(持续交付/部署):构建产物自动部署到测试/生产环境。AI 前端特有:
    • 特征开关(Feature Flag)控制模型版本、prompt 策略灰度;
    • 与后端模型版本联动发布;
    • 静态资源托管与边缘函数结合,实现 prompt 预处理。
  • 流程:Git push → CI 校验 → 构建 → 通知 → 手动/自动部署 → 监控回滚。

6. 虚拟列表及其在 AI 对话中的重要性

  • 虚拟列表只渲染可视区域内的节点,用占位元素撑开总高度,减少 DOM 节点数量,极大提升长列表滚动性能。
  • AI 对话记录会快速积累大量消息,每条消息可能包含 Markdown、代码块、图片等复杂渲染,全部渲染会卡顿。
  • 方案:
    • 使用 react-window@tanstack/virtual
    • 动态高度需测量并缓存消息高度。
    • 流式输出时当前消息高度持续变化,需要实时更新尺寸并修正滚动位置。
    • 结合自动跟随滚动(当用户在最底部时自动滚到底)。

7. 前端安全防范(针对 AI 应用)

  • XSS 防范:AI 输出可能是 Markdown/HTML,需经过安全消毒(DOMPurify),禁止执行内联脚本和危险标签。
  • Prompt 注入/越狱:前端可进行输入过滤(虽然有限),但更实际的是展示安全警告、限制特殊字符、控制输入长度。
  • CSRF/认证:使用 HttpOnly Cookie + 同源策略,或 Token 认证;AI API 访问需加权限校验。
  • 敏感信息泄露:避免将用户输入打到 console;暂存历史记录加密或脱敏;提供删除对话功能。
  • 内容安全策略(CSP):限制脚本来源,防止意外加载恶意资源。
  • 数据投毒风险:对于上传文件,限制类型、大小,并在前端预览时进行内容安全扫描(集成第三方扫描)。

8. 项目中最复杂的技术难点及解决

(以“流式对话中支持停止生成并编辑重新发送”为例)

  • 难点:
    • 流式进行中用户点击“停止”,需中断请求并保留已生成内容。
    • 用户编辑已生成部分或中间某条消息后重新发送,需保持上下文连续。
  • 解决:
    • 使用 AbortController 中断 fetch 流。
    • 停止时冻结当前消息状态,将其存入对话历史数组。
    • 编辑时找到该消息,标记后续消息为“失效/裁剪”,构造新的请求上下文(包含编辑前所有历史+编辑后消息)。
    • 重新生成时,采用新的对话分支,类似 Git 分支管理,可向前端展示“此消息之后的内容已重新生成”。

三面:架构与综合能力

1. 设计支持多模型切换的 AI 对话组件

核心思路:适配器模式 + 策略模式 + 依赖注入

  • 模型适配器层:定义统一接口 sendMessage(prompt, history, options) => Stream,每个模型(GPT、Claude、Gemini 等)实现一个适配器,负责转换请求格式、解析流式响应。
  • 组件设计
    • ChatContainer:管理状态、协调。
    • ModelSelector:切换模型,通过 Context 传递当前适配器实例。
    • MessageList:虚拟列表渲染,支持 Markdown/代码块。
    • InputArea:支持文件上传、停止生成、重新生成。
  • 参数配置化:每个模型的 max_tokens、temperature 等可由用户调整,UI 动态生成配置面板(Schema 驱动)。
  • 流式输出统一抽象:所有适配器返回 ReadableStream 或 AsyncIterator,组件消费时统一处理。
  • 扩展性:新增模型只需添加一个适配器文件并注册,核心组件零改动。

2. 快速迭代的 AI 业务下保障前端代码可维护性

  • 目录结构分层:按功能域(chat, knowledge, settings)划分,每个域内分层(components, hooks, services, types)。
  • 抽象核心逻辑:将与模型交互、流式处理、token 计算等封装为自定义 Hooks 和工具函数,避免业务组件分散实现。
  • 测试先行/保障:关键逻辑(prompt 构建、历史裁剪)编写单元测试;核心流程用 E2E mock 覆盖。
  • 特性开关(Feature Flag):控制新功能的灰度发布,未准备好的代码合并后隐藏,避免长分支。
  • 统一类型定义:使用 TypeScript 严格模式,API 响应类型、模型参数类型集中管理,一有修改编译报错。
  • 文档与注释:对复杂流程(如流式解析)写清流程图,记录设计决策。
  • Code Review 规范:关注抽象合理性、重复代码、性能影响。

3. 构建前端 AI 性能监控系统

  • 指标收集
    • 响应时间:TTFT(首 token 时间)、总生成时长、每 token 间隔。
    • 渲染性能:FPS 下降、长任务(Long Task)次数、虚拟列表滚动帧率。
    • 错误信息:API 错误码、流中断次数、解析异常。
  • 采集方式
    • 包装 fetch/SSE 客户端,埋点记录各阶段耗时。
    • 利用 PerformanceObserver 监控长任务、资源加载。
    • 用户操作(发送、停止)打点。
  • 上报策略:抽样上报,使用 Navigator.sendBeacon 保证页面关闭时仍可发送;聚合计算平均值、P95。
  • 可视化大盘:展示实时 QPS、TTFT 分布、错误率;可按模型、地域、版本下钻。
  • 告警:设定阈值(如 TTFT > 3s 占比突增),触发企业微信/邮件通知。
  • 关联后端:与后端 trace id 打通,联合排查全链路。

4. 对未来前端在 AI 领域发展的看法

  • AI 原生组件库:将流式渲染、提示词管理、模型切换等封装成标准化组件,大幅降低开发成本。
  • 边缘 AI + 前端推理:WebGPU 和 ONNX Runtime Web 发展,小模型可在浏览器本地执行,实现即时响应和隐私保护。
  • 智能前端工具链:AI 辅助生成组件代码、自动写测试、设计稿转代码,前端工程师更多负责校验、组合和创意。
  • 多模态交互:前端需要处理图像、语音、视频等更多类型流的实时渲染和同步,催生新的框架能力。
  • 个性化与自适应用户界面:根据用户行为和上下文动态调整 UI,每个用户看到的前端都可能是生成式的。
  • 前端角色升级:不再是单纯实现界面,而是 AI 系统的体验架构师,关注意图识别、对话设计、安全伦理等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值