EXPLORE THE LIBRARY
全部题目与资料
找到 359 项内容
请介绍一个你最熟悉的项目
按“业务目标 → 用户和流程 → 技术栈 → 个人负责范围 → 难点 → 结果”回答。先讲全貌,再挑一个能展开的重点。团队成果和个人贡献要分清。
项目里最难的问题是什么
准备两个真实案例,每个按“现象 → 影响 → 定位证据 → 根因 → 修改 → 验证 → 防复发”讲。性能、请求竞争、复杂表单、SSR 登录态、线上兼容问题都可以。 别只说“查资料解决了”。说明看了什么日志、怎么排除其他原因、为什么这个修改能解决问题。
列表查询、分页和筛选怎么设计
区分编辑中的筛选项与已提交条件;条件变化时回到第一页;明确 loading、空数据、失败重试。连续查询要处理响应乱序,避免旧结果覆盖新结果。
请求封装和登录过期怎么处理
说明基础请求层、业务 API 层和页面的职责;统一处理认证、超时、取消、公共错误,页面决定业务反馈。刷新 token 时考虑并发请求只触发一次刷新,以及刷新失败后的退出流程。
权限系统怎么做
区分菜单、路由、按钮和数据权限。前端负责展示和导航,后端校验真实权限;隐藏按钮不构成安全边界。考虑刷新恢复、直接访问地址、角色切换及无权限页面。
怎么封装组件,怎么判断有没有必要
举表单、弹窗、上传或业务选择器的真实例子:哪些配置稳定、哪些通过事件或插槽扩展,数据由谁持有。通用组件处理展示与交互,页面组合业务流程。
闭包是什么,有什么用途和风险
函数保留对其词法环境的访问能力,可用于私有状态、工厂函数、防抖等。闭包本身不是内存泄漏;重点是长期存活的监听器、定时器等是否持有不再需要的对象。
this、箭头函数、call / apply / bind 有什么区别
普通函数的 this 与调用方式有关;箭头函数使用外层词法 this。call / apply 立即调用,bind 返回绑定后的函数。准备解释方法被单独取出、回调传递、new 调用时的差异。
原型链和 class 怎么理解
属性查找先看对象自身,再沿原型链查找。区分实例、构造函数的 prototype 和对象的内部原型;class 建立在原型机制上,同时有自己的语法语义。能解释 new 的主要步骤。
事件循环、Promise、async / await 怎么执行
浏览器中先执行当前同步任务,在微任务检查点处理微任务;渲染还取决于浏览器的渲染机会,不是每个任务结束都重绘。await 之后的继续执行具有异步调度行为,Promise 构造器执行器本身同步执行。 不要把浏览器和 Node 的调度规则混用;微任务不断追加也可能阻塞渲染。 MDN:J…
Promise.all、allSettled、race、any 怎么选
all:全部成功才成功,结果保持输入顺序,任一拒绝会使聚合结果拒绝。 allSettled:等待全部结束,分别拿成功或失败状态。 race:采用最先敲定的结果;any:采用最先兑现的结果,全部拒绝时拒绝。 聚合 Promise 失败不会自动取消其他任务;并行请求也不等于具备并发数…
深拷贝和浅拷贝有什么区别
展开运算符、Object.assign 只复制一层。JSON 序列化会丢失或改变部分类型,不能处理循环引用。structuredClone 支持循环引用及多种内建类型,但不能当成可复制函数、DOM 节点和任意类语义的万能工具。 先说明要支持哪些数据,再选择方案。 MDN:stru…
防抖和节流怎么实现
防抖用于一段时间内频繁触发后只处理一次,例如搜索;节流限制连续触发频率,例如滚动处理。编码时要保留 this 和参数,并说清首触发、尾触发、取消和组件销毁清理。
ES Module 和 CommonJS 有什么区别
从语法、加载与执行、依赖分析、导出绑定和运行环境回答。不要简单背“一个同步、一个异步”;浏览器、Node 和打包产物的行为需要分别看。 **追加检查:**let / const / var、暂时性死区、类型判断、引用相等、Map / Set、可选链、空值合并、浮点精度。
let / const / var 与暂时性死区
块作用域;初始化前不可访问;const 不冻结对象。
怎么判断类型和引用相等
typeof 的边界;Array.isArray;引用与 Object.is。
Map / Set 与对象有什么区别
键类型;去重规则;迭代与原型。
可选链、空值合并与浮点精度
只对 null/undefined 短路;0 和空串;十进制精度。
盒模型、BFC、外边距折叠怎么解释
说明 content-box 与 border-box 的尺寸计算;理解 BFC 与浮动、布局隔离的关系。不要只背触发方式,要能用具体布局解释问题;overflow 方案还可能带来裁切或滚动副作用。
Flex / Grid 怎么做常见布局
能写居中、两栏、三栏、等分、自适应布局。重点解释 flex-grow / shrink / basis;子项无法收缩时检查默认最小尺寸,按需要设置 min-width: 0。
定位、层叠上下文、z-index 怎么排查
先确认定位参照和滚动容器,再看层叠上下文。z-index 大不保证跨上下文覆盖;transform 等属性可能影响定位或层叠。弹窗被遮挡还要检查祖先裁切。
移动端适配和可访问性怎么做
说明 viewport、弹性布局、媒体查询、rem / vw 的取舍,覆盖安全区、软键盘、长文案和横屏。语义化标签、表单 label、键盘操作、焦点和错误提示也要能解释。
从输入 URL 到页面显示经历什么
按 URL 解析、缓存 / Service Worker 等拦截、名称解析、连接、请求响应、HTML 解析、资源加载、样式和布局、绘制合成说明。连接复用、缓存命中会改变链路;HTTP/3 使用 QUIC,不要把所有情况都说成 TCP。
强缓存、协商缓存怎么区分
新鲜缓存可直接复用;过期或要求校验时,可用 ETag / If-None-Match、Last-Modified / If-Modified-Since 做条件请求。304 不携带完整资源正文。 no-cache 表示复用前需校验,不等于不存储;no-store 才要求不存储。带…
跨域是什么,CORS 和开发代理怎么工作
浏览器依据同源策略限制脚本跨源读取响应。CORS 由服务端通过响应头授权,部分请求会先发预检;开发代理通过同源服务转发。跨域不等于所有请求都发不出去。 携带凭证时不能把允许来源简单设为通配符;还需考虑 Cookie 策略。 MDN:CORS
Cookie、localStorage、sessionStorage 怎么选
Cookie 可按规则随请求发送,HttpOnly Cookie 不能由 JS 读取;localStorage 按源持久化,sessionStorage 按源及页面会话隔离。结合容量、生命周期、SSR、XSS 和 CSRF 风险回答,不要说“token 放哪里绝对安全”。
XSS 和 CSRF 分别怎么防
XSS 关注不可信内容被当作脚本执行:正确转义、可信净化、减少危险 HTML 注入、配合 CSP。CSRF 关注浏览器自动附带凭证的伪造请求:结合 SameSite、CSRF token、来源检查等防护。
重排、重绘、事件委托和内存泄漏怎么理解
布局变化可能引发布局计算,视觉变化可能涉及绘制,部分动画可走合成,但要实测。避免循环中交错读写布局。事件委托依赖冒泡;检查 target、currentTarget 和动态节点。 内存问题重点排查未移除监听、未清理定时器、全局引用及脱离文档但仍被引用的 DOM。
Vue2 响应式原理是什么
Object.defineProperty 将已有属性转换为 getter / setter;读取时收集依赖,写入时通知更新。数组依赖变更方法的处理。要能从“改数据”讲到“组件重新渲染”。
为什么新增属性、数组下标赋值有时不更新
Vue2 对未声明属性新增 / 删除、直接写数组索引或 length 有检测限制。优先预声明字段;已有响应式嵌套对象可用 this.$set,数组可用 splice 或替换为新数组。根级字段不能靠事后随意添加解决。
computed、watch、methods 怎么选
computed 表达派生值并按响应式依赖缓存;watch 处理变化引发的副作用;methods 用于显式调用。深度监听有遍历成本,嵌套对象原地修改时新旧引用可能相同;computed 通常应保持无副作用。
nextTick 解决什么问题
Vue 会对更新排队和去重,数据变化后 DOM 不一定立即更新。nextTick 用于等待本轮相关 DOM 更新完成,再做测量等操作;不等于图片加载完成,也不是所有时序问题的通用补丁。 25~28 的响应式限制、依赖跟踪与异步更新机制可对照 Vue2 官方响应式说明 。
生命周期、keep-alive、路由复用怎么配合
讲清创建、挂载、更新和销毁阶段各适合做什么。keep-alive 还要处理 activated / deactivated;路由参数改变可能复用实例,不会按预想重新 mounted。按业务选择参数监听或路由更新守卫,并清理资源。
组件通信和 Vuex 怎么设计
父子优先 props / events,跨层按场景选 provide / inject,跨页面共享用 Vuex。actions 组织异步流程,mutations 同步修改状态。Vue2 的 provide / inject 不能一概当作自动响应式,取决于提供值是否已被观察等条件。…
key、v-if / v-show、自定义 v-model 有什么作用
key 标识节点身份,动态增删排序用稳定业务 ID;索引容易使输入状态错位。v-if 控制创建销毁,v-show 主要控制显示。Vue2 组件默认 v-model 对应 value / input,也能通过 model 配置调整。
Vue2 和 Vue3 的区别,迁移怎么做
至少理解:Vue3 对象响应式使用 Proxy,ref 的值访问通过 getter / setter;ref / reactive 的使用边界、解构丢失响应性、组合式逻辑复用。Proxy 仍不能追踪绕过代理的原对象修改。 迁移先盘点组件库、插件、浏览器与构建环境,再小范围验证;O…
CSR、SSR、SSG 各适合什么
CSR 主要在客户端生成界面;SSR 按请求在服务端生成 HTML;SSG 在构建等阶段预生成。比较首屏、SEO、内容实时性、服务成本和缓存。SSR 仍需要客户端 JS 水合,不会自动消除慢接口和重脚本。
asyncData、fetch、mounted 有什么区别
asyncData 用于页面,无 this,通过返回值合并数据;Nuxt 2.12+ 新 fetch 可用于组件并访问实例,有 $fetchState;mounted 只在客户端运行,不能为服务端首屏提供数据。旧版 fetch(context) 语义不同,回答前先说清版本。
SSR 为什么会报 window is not defined
服务端没有浏览器对象。浏览器操作放到合适的客户端生命周期,或用 process.client 判断;依赖导入本身若就访问 window,需要客户端插件或客户端动态导入。仅包住页面渲染未必能解决模块导入时的报错。
SSR 登录态和 Vuex 怎么防止用户串数据
每个请求创建独立状态,不把用户信息放在可变模块单例中;按请求传递必要 Cookie / headers。localStorage 无法在服务端读取;用户相关响应不能误用公共缓存,敏感信息不能随意注入客户端状态。
水合不一致、SEO 和 SSR 首屏慢怎么排查
比较服务端 HTML 与客户端首轮渲染,排查随机值、时间、时区、非法 HTML、客户端独有状态。SEO 还看 head、状态码和可索引链接。首屏慢按服务端耗时、接口、HTML、静态资源与水合成本拆分。
any、unknown、never 有什么区别
any 跳过大量类型检查;unknown 要先缩小类型再使用;never 表示不应出现的值或不正常结束的路径,可用于穷尽检查。用接口结果、异常对象、状态分支举例。
type、interface、泛型怎么用
能给对象、函数、组件参数和接口响应定义类型。type 可表达联合等类型,interface 可声明合并;二者不是绝对优劣。泛型用于保留输入与输出类型的关系,别只把 any 换成 T。
联合类型和类型收窄解决什么问题
用带 status / type 字段的可辨识联合表达加载、成功、失败等状态,通过 typeof、in 或类型守卫收窄。少用断言强行绕过检查;as 不会在运行时验证接口数据。 TypeScript 官方类型收窄文档
常见工具类型、可选值和接口类型怎么处理
理解 Partial、Required、Pick、Omit、Record、ReturnType 的实际用途。区分可选字段与明确允许 null。TS 类型在运行时被擦除,关键外部数据仍要校验;Partial 也不等于递归地全部可选。
Webpack 和 Vite 有什么区别
从开发启动、模块转换、依赖处理、HMR、生产构建和插件生态解释,别只说“Vite 快”。经典 Vite 开发流程利用浏览器 ESM 按需提供源码;生产构建与底层工具随版本演进,不能把旧版本的 esbuild / Rollup 组合说成永久事实。 回答时先说项目版本、规模和瓶颈,再…
分包、Tree Shaking、Babel 和 polyfill 分别解决什么
按路由和使用时机分包,控制首屏体积;Tree Shaking 依赖静态分析并受副作用影响,不是写了 import 就一定能移除。Babel 处理语法转换,API 兼容还可能需要 polyfill;目标浏览器决定具体配置。
Git 冲突和线上发布异常怎么处理
讲清 merge / rebase 的影响,先确认分支状态再解决冲突;了解中止操作。发布重点准备资源 hash、入口缓存、CDN、旧页面引用旧 chunk、灰度与回滚,不把“重新发布”当作全部方案。
怎么保证代码质量,老项目怎么改
区分 lint、类型检查、单元测试、集成测试、端到端测试的作用。根据风险验证关键流程。旧项目先定位问题、加必要保护、做最小修改,再考虑分阶段治理;依赖升级先核对 Node、框架、打包器和插件兼容。
你做过哪些性能优化,怎么证明有效
按“用户问题 → 基线指标 → 工具定位 → 根因 → 改动 → 同条件对比 → 回归”讲。区分实验室数据和真实用户数据,明确设备、网络、缓存状态、样本和分位数,不能只报 Lighthouse 分数。 Core Web Vitals 当前包括 LCP、INP、CLS;良好阈值分别…
首屏慢、大列表卡、图片多分别怎么优化
首屏慢:拆解服务端响应、关键请求、资源体积、主线程与渲染,优先处理真正的瓶颈。 大列表:先考虑分页,再评估虚拟列表;处理动态行高、滚动定位、选择状态和可访问性。 图片多:合适尺寸和格式、缓存、非首屏懒加载;关键首屏图片不应机械懒加载,预留尺寸减少跳动。
线上白屏、接口失败、页面越用越卡怎么查
先界定用户、机型、时间和版本范围,再看 JS 错误、资源加载、网络、路由和发布变更。用 source map、日志和性能记录关联证据;内存问题结合快照与引用链。先止损,再修复和补监控。
平时怎么用 AI 写代码,怎么保证结果可用
准备一个真实例子:输入了哪些上下文和限制、AI 完成了什么、哪里出错、你如何检查和验证。重点讲业务理解、接口真实性、依赖兼容、异常和回归,不能把“生成完成”当成“交付完成”。 这是部分岗位可能追问的方向;公开个人面经中已出现 AI 工具和排障相关问题,但不能推断每个岗位都会考。 …
如果做 AI 聊天页面,需要考虑什么
按 JD 选学:流式响应消费、停止与取消、增量解析、状态机、消息顺序、断线和重试、历史记录、长列表、Markdown 安全渲染。传输分块不一定等于一条完整消息;前端取消连接也不必然终止服务端任务。 不做 AI 产品的岗位可后置,不必为了面试先背完整模型理论。
搜索结果被旧响应覆盖
防抖限制触发;请求身份保证正确性;取消与结果隔离。
连续提交导致重复订单
前端状态锁;服务端幂等;超时结果不确定。
大文件上传与断点续传
切片标识;限流重试;已上传查询;服务端验证和合并。
多个接口同时返回 401
single-flight 刷新;有限重放;统一退出;写操作语义。
弹窗重开数据不对
草稿归属;初值工厂;回填身份;清校验。
移动端返回后页面没刷新
区分路由、缓存和 WebView;显式失效策略。
发布后部分用户打不开页面
旧页面引用旧资源;缓存策略;资源保留;有限恢复。
规划技术升级
明确收益;兼容盘点;试点;回归与回退。
为什么不能直接改 state,为什么 setter 后读到旧值
只读快照;新引用;当前闭包不会被改写。
连续更新为什么用函数式 updater
更新队列;闭包所属渲染。
Effect 什么时候需要,依赖与清理怎么写
外部同步;真实响应式依赖;对称 cleanup。
key、表单与共享状态如何选择
组件身份;受控契约;状态靠近使用者。
useMemo、useCallback、memo 是否都要加
缓存结果、引用、组件;收益必须大于维护成本。
Next.js / React 的服务端与客户端边界
SSR 不等于 Server Components;水合一致;缓存按版本明确。
与产品、后端、测试有分歧时怎么协作
明确共同目标、用契约和证据讨论、记录决定、验证闭环。
为什么离职或换工作
真实动机、客观表达、与目标岗位匹配,不编造经历。
对下份工作或岗位有什么期待
具体职责、能力匹配、可交付贡献、合理成长目标。
Vue2 响应式原理是什么?
对被观察对象的已有属性使用 Object.defineProperty 定义 getter / setter。读取时收集依赖,写入时通知相关 watcher,再经调度更新组件。数组通过对变更方法的处理触发通知,不是所有索引都被逐一拦截。
新增对象属性、数组索引赋值为什么可能不更新?
Vue2 无法自动侦测所有新增 / 删除属性和数组索引、length 的直接修改。预声明状态;对已响应式的嵌套对象可用 $set / $delete;数组可用 splice 或替换。不要事后随意给实例追加根级状态。
computed、watch、methods 怎么选?
computed 适合由依赖推导的结果,并按响应式依赖缓存;watch 适合变化触发请求等副作用;methods 是显式调用。计算属性通常保持纯计算,不在其中写状态或发请求。
nextTick 的原理和使用场景是什么?
响应式数据更新会排队、去重,DOM 更新不与每次赋值同步发生。nextTick 用于等待相关更新完成后测量 DOM、聚焦等。Vue2 具体调度实现与环境有关,不要将其永远说成 setTimeout。
生命周期和父子组件执行顺序怎么讲?
说明创建、挂载、更新、销毁阶段分别适合做什么。普通同步首次挂载中,父组件先创建、子组件先 mounted;异步组件、条件分支、SSR 等需要另行考虑。SSR 不运行 mounted 和销毁阶段等客户端钩子。
组件的 data 为什么通常是函数?
同一个组件定义会被创建为多个实例,每次返回新对象可以隔离状态。若每次返回的对象内部仍引用同一个外部对象,这部分依然可能共享。SSR 的状态还要按请求隔离。
组件通信有哪些方式,怎么选?
父子优先 props / events,内容定制用插槽,跨层可用 provide / inject,跨页面共享状态用 Vuex。$refs 属于命令式调用,应有明确边界;事件总线要考虑依赖隐蔽、解绑和调试成本。
为什么不能直接修改 props?编辑表单怎么做?
props 表达父到子的输入,直接修改会破坏数据归属并可能被父更新覆盖。简单字段通过事件请求更新;编辑草稿用本地副本,并明确初始化、取消、提交和外部更新时的行为。
Vue2 的 v-model、.sync、自定义事件有什么关系?
组件默认 v-model 对应 value prop 和 input 事件,可通过 model 配置调整;.sync 对应 update:属性名 事件。它们都是输入加更新通知的约定,不意味着子组件能随意修改父状态。
普通插槽和作用域插槽有什么区别?
父级提供内容;作用域插槽由子级把行数据、状态等暴露给父级的插槽内容。模板表达式仍遵守定义处的作用域规则。适合表格单元格、选择器选项和可定制空状态。
key 为什么重要,为什么不推荐用 index?
key 辅助节点身份识别与复用。列表插入、删除、排序时,索引可能让不同业务数据复用同一组件实例,造成输入或选中状态错位。使用稳定、同级唯一的业务标识。
v-if 和 v-show 怎么选?能和 v-for 一起用吗?
v-if 创建 / 销毁分支,v-show 保留节点并通过显示样式切换。频繁切换与初始成本要权衡。同节点混用 v-if / v-for 不利于理解,Vue2 与 Vue3 的优先级也不同;用计算属性预筛选或外层分组。
keep-alive 缓存什么,怎么刷新和清理?
缓存组件实例并涉及 activated / deactivated。结合 include / exclude、key、容量和业务过期策略处理;失活不等于销毁,计时器、订阅和请求要按需要管理。
Vue Router 的模式、守卫和路由复用怎么处理?
hash 使用 URL 片段,history 模式要配合服务端回退,同时避免错误吞掉静态资源和接口 404。动态参数变化可能复用组件;通过参数监听或更新守卫处理数据。Router 3 中使用 next 时确保每条路径只完成一次。
Vuex 的 state、getters、mutations、actions 怎么分工?
state 存状态,getters 派生数据,mutations 同步改状态,actions 编排异步及提交 mutation。组件临时交互状态不用全部放 Vuex。模块化、命名空间和退出清理要有边界。
mixin 有什么问题,如何避免复杂度失控?
mixin 可复用选项,但可能产生命名冲突、依赖来源不清、隐式耦合。先评估纯函数、组件组合、显式工具模块;在已有 Vue2 项目中按成本选择,不为消除一个 mixin 大改架构。
scoped 样式是什么,为什么覆盖不到组件内部?
scoped 通常通过编译增加属性选择器限制样式范围,不是浏览器 Shadow DOM。样式影响与 DOM 结构、子组件根节点等相关;深度选择器语法要按 vue-loader / 编译器版本确认。
模板到页面经历什么?Vue2 diff 怎么理解?
模板编译为渲染函数,执行后产生虚拟节点;更新时比较并应用到真实 DOM。能说明同类型复用、子节点比较、key 和组件状态的联系。虚拟 DOM 不是永远比手工 DOM 快。
Proxy 相比 Object.defineProperty 解决什么?
Proxy 可以拦截对象多种操作,使对象属性新增、删除等更容易纳入响应式。读取代理时收集依赖,写入时触发更新;直接修改原始对象绕过代理仍可能不触发。
ref 和 reactive 怎么选?为什么需要 .value?
ref 用包装对象的 value 访问承载值,可用于基本类型和对象;reactive 返回对象代理。脚本中通常通过 .value 访问 ref,模板存在解包规则。ref 包装的对象默认也可深层响应。
解构为什么可能丢失响应式?toRef / toRefs 有什么作用?
解构出基本值后,后续访问不再经过原对象属性;toRef / toRefs 保持与源属性的关联。解构出响应式嵌套对象的行为又不同,不能一概说所有解构都完全失效。
shallowRef、shallowReactive、markRaw 什么时候用?
用于按需限制深层转换或保留第三方实例等原始对象。shallowRef 的内部对象修改通常不会触发依赖其 value 的更新,要替换 value 或使用明确的触发方式。先测成本,再决定是否采用。
Vue3 computed 和普通函数有什么区别?
computed 根据响应式依赖追踪和缓存派生值;普通函数被调用时执行。getter 保持无副作用;可写 computed 通过 setter 明确将更新映射到源状态,不是额外复制一个状态。
watch 和 watchEffect 有什么区别?
watch 显式指定源,通常在源变化时运行;watchEffect 立即执行并自动追踪同步执行期间读取的依赖。异步函数在首次 await 之后读取的值不会因此被自动追踪。
watcher 怎么清理,flush 配置有什么用?
副作用失效时取消旧请求或忽略旧结果。默认 watcher 回调与组件 DOM 更新有调度先后,访问自身更新后 DOM 可按需用 flush: 'post'。同步 flush 不做常规批量处理,要谨慎。 Vue3.5+ 的 onWatcherCleanup 要在同步执行阶段注册;回…
Composition API 相比 Options API 解决什么?
可按业务功能组织状态、派生值和副作用,便于组合、复用与类型推导;并非自动让代码更快或更简单。Options API 仍可用,函数拆分也要保持职责和依赖清晰。
setup、script setup 和编译宏是什么关系?
setup 是组合式 API 的入口;script setup 是单文件组件的编译时语法简化,顶层绑定可供模板使用。defineProps、defineEmits、defineExpose 等是编译器宏,不是通用运行时函数。
Vue3 组件 v-model 与 Vue2 有何变化?
默认约定为 modelValue / update:modelValue,支持带参数的多个模型绑定。Vue3.4+ 可用 defineModel 简化声明;底层仍是 prop 和更新事件,需明确默认值与父级状态同步。
props、emits、attrs、插槽如何设计组件接口?
明确输入、事件和内容定制边界;声明 props / emits,按需要透传 attrs。多根节点等情况下不能依赖隐式透传。组件实例对外暴露的方法应少且稳定。
生命周期、模板 ref 与 nextTick 怎么配合?
在正确阶段访问 DOM / 实例,条件渲染或列表变化后等待相关更新。模板 ref 可能为空,异步组件尚未就绪时也不能假定存在。组件停止使用时清理定时器、监听和外部实例。
provide / inject 可以代替状态管理吗?
适合组件树范围内共享依赖。提供 ref / reactive 才能保留相应响应能力,建议把修改入口集中在提供方,必要时暴露 readonly 状态和显式操作。跨页面复杂状态还要考虑调试和生命周期。
Teleport、KeepAlive 分别解决什么?
Teleport 调整实际 DOM 挂载位置,保留逻辑组件关系;KeepAlive 缓存组件实例。弹窗挂到 body 后,布局、样式、焦点和滚动锁定仍需处理;缓存页面的订阅也不会凭空失效。
异步组件、Suspense、错误状态怎么配合?
异步组件用于延后加载;Suspense 用于协调特定异步依赖并展示 fallback,不能把任意请求都自动变成其依赖。异步加载失败、超时、重试与业务错误要分别设计。
Pinia 和 Vuex 有何差异?
Pinia 通过 store 组织 state、getters、actions,不要求 Vuex 式 mutations 层;可使用 Options Store 或 Setup Store。state / getter 解构通常通过 storeToRefs 保留响应式,actio…
Vue3 路由守卫、参数与异步请求怎么协调?
区分进入前鉴权、组件复用后的参数变化与数据获取;监听需要的参数,避免监听整个路由导致重复请求。守卫的放行、重定向、取消与错误处理要覆盖所有分支。
Vue3 渲染性能优化有哪些?
理解编译器如何利用静态内容、Patch Flags、Block 等信息减少更新工作;运行时 keyed diff 会复用节点,并在特定路径用最长递增子序列减少移动。业务优化还包括稳定输入、拆分组件和列表虚拟化。
怎么封装一个可靠的 composable?
先定义输入是否响应式、返回值与更新入口、状态是每次调用独立还是共享、清理和 SSR 行为。请求函数还要明确并发、取消、错误与 loading 的归属,别把所有业务揉成一个万能 useRequest。
Vue2 升级 Vue3 怎么规划?
盘点组件库、插件、Router / Vuex、构建和 Node 版本,以及 filters、事件、插槽、v-model 等兼容差异。先试点并跑关键流程,再分阶段推进;迁移不强制把所有 Options API 改为组合式写法。
React 的 render 和 commit 有什么区别?
render 根据 props / state 计算 UI;commit 应用必要的 DOM 变化。组件重新执行不等于 DOM 必然改变。渲染逻辑应保持纯净,因为渲染可能重复、暂停或被放弃。
为什么 setState 后读到的还是旧值?
函数组件每次渲染拿到一份状态快照,setter 请求下一次更新,不会改写当前闭包里的变量。依赖前值更新时使用函数式 updater,而不是把 setter 简单理解为“立即赋值”。
连续调用三次 setCount,为什么有时只加一?
同一处理函数里的三次 setCount(count + 1) 使用相同快照,重复请求同一个结果;三次 setCount(c => c + 1) 则按更新队列逐次计算。批处理范围与 React 版本和 root 模式有关。
为什么不能直接修改 state 对象或数组?
把已有状态当作只读快照,通过新对象表达变更;共享对象被原地修改会破坏旧快照,也可能因引用不变导致预期更新被跳过。嵌套更新要复制受影响路径,或采用项目已使用的不可变更新工具。
Hooks 为什么通常不能放进条件或循环?
React 依赖稳定调用顺序关联多数 Hook 的状态,应在函数组件或自定义 Hook 的顶层调用。把条件放在 Hook 内部的合适位置。React 的 use API 有特殊规则,不能机械套用所有 Hook 的限制。
什么是闭包旧值,怎么解决?
回调捕获的是定义时所在渲染的值,定时器、订阅和异步回调里尤其常见。按业务选择正确依赖、函数式更新、ref 或适用的新 API;先明确要“当时值”还是“最新值”。
useEffect 应该用来做什么?
Effect 主要把组件与外部系统同步,例如订阅或外部实例。派生数据通常直接在渲染中计算;明确的按钮提交行为放在事件处理函数中。不要用 Effect 把所有 props 都复制一份到 state。
Effect 依赖和清理函数什么时候执行?
依赖变化的提交后,先清理旧同步,再执行新同步;卸载时也清理。依赖逐项按 Object.is 比较,应包含 Effect 使用的相关响应式值。无依赖数组与空数组含义不同。
StrictMode 下为什么看到多次渲染或重复请求?
开发期 StrictMode 可额外调用渲染相关逻辑,并对适用的 Effect 执行额外 setup / cleanup 检查,以暴露不纯与清理缺陷。具体行为与版本及启用位置有关,不是生产环境固定重复请求两次。
useEffect 与 useLayoutEffect 有什么区别?
useLayoutEffect 在相关 DOM 提交后、浏览器绘制前执行,可用于需要避免闪烁的布局测量,但会阻塞绘制。useEffect 的绘制先后还受触发场景影响,不能保证永远在屏幕绘制后执行。
useRef 和 useState 有什么区别?
ref 在重渲染间保留可变容器,改 current 不触发渲染,适合 DOM、计时器或命令式对象;界面依赖的状态通常用 state。不要在渲染期间任意读写 ref 以规避状态机制。
memo、useMemo、useCallback 分别缓存什么?
memo 可按 props 比较跳过部分父级引发的重渲染;useMemo 缓存计算结果,useCallback 缓存函数引用。自身 state 或使用的 Context 改变仍可能触发更新。先测量,避免增加无效缓存与依赖维护成本。
受控和非受控表单怎么选?
受控表单由 value / checked 与更新处理驱动;非受控由 DOM 保存当前值,defaultValue 只提供初始值。避免组件生命周期内无意切换两种模式;按复杂度和现有表单方案选择。
props、Context、useReducer、外部 store 怎么选?
局部状态靠近使用者;兄弟共享可提升状态,跨层依赖可用 Context;复杂状态转移可用 reducer。跨页面复杂状态再按项目选外部 store。Context 是传播机制,不自动提供细粒度订阅和持久化。
自定义 Hook 复用的是逻辑还是状态?
通常复用逻辑,每次调用有独立 Hook 状态;只有显式使用共享外部存储等方案才共享数据。封装时明确输入、依赖、返回值和清理,不隐藏调用者必须理解的副作用。
key 怎样影响状态保留和重置?
状态归属于渲染树中的位置与组件身份;同位置、同类型、同 key 通常保留状态,改变 key 可有意重置。列表 key 只需同级唯一,不能用随机 key 强迫所有组件每次重建。
React 事件处理与原生事件有什么不同?
理解事件对象、冒泡、默认行为和处理函数引用;阻止冒泡与阻止默认动作是不同操作。事件委托实现与版本有关,不要把旧版本的事件池结论套到现代 React DOM。
Error Boundary 能捕获哪些错误?
为子树渲染等 React 错误提供降级 UI;通常不捕获事件处理器、任意异步回调和边界自身错误,SSR 也有不同机制。请求失败需业务处理,不能指望一个边界包住所有错误。
useTransition、useDeferredValue 解决什么?
区分紧急与可延后的更新,减轻昂贵渲染对交互的影响。transition 不会把同步计算自动丢到后台线程;受控输入的直接更新不能当作 transition。deferred value 也不是带固定等待时间的防抖。
lazy、Suspense 与数据请求是什么关系?
lazy 延后加载组件代码,Suspense 对支持挂起的依赖显示 fallback;普通 useEffect 请求不会自动激活 Suspense。采用框架或支持的集成,分别处理加载中、请求失败和代码加载失败。
Fiber、协调和并发渲染怎么理解?
Fiber 是 React 组织组件工作、状态及关联关系的内部结构;协调计算前后树差异,并发能力允许部分渲染工作被调度、中断和重做。不是所有阶段都可中断,也不意味着组件 JS 自动多线程执行。
SSR、Hydration、Server Components、React 19 新能力怎么区分?
SSR 生成 HTML,水合使交互组件接管已有结构;Server Components 在独立服务端环境执行并产生可供客户端组合的输出,可与 SSR 配合,不能简单等同。客户端组件也可能参与服务端预渲染。 React 19 方向可按 JD 补 use、Actions、useAct…
请求乱序怎么在 Vue / React 中处理
请求身份;取消;最新结果所有权。
编辑弹窗如何避免残留数据
初值工厂;草稿;明确重置。
排序后输入内容为什么串到别行
同级稳定 key;业务身份。
离开页面后还在请求怎么办
卸载不等于失活;清理全部资源。
大表格卡顿怎么排查
测量瓶颈;缩小更新;减少节点。
多组件共享状态互相覆盖
独立与共享显式定义;按业务 key 分区。
父组件拿不到子组件方法
实例就绪;受限公开接口;版本差异。
SSR 报错或内容跳变怎么处理
环境隔离;初始一致;用户状态隔离。
平时怎么用 AI 写代码?
回答具体流程:理解需求 → 提供相关代码和约束 → 拆任务 → 生成或修改 → 人工审查 → 局部验证 → 页面验收。 举例时讲清 AI 做了什么、自己判断了什么。Vue2 项目可说明如何限制框架版本、复用请求封装、避免 SSR 直接访问浏览器对象。只列工具名字不够。
Prompt 怎么写,怎么让 AI 按项目规范做?
至少提供:任务目标、相关上下文、技术栈和版本、真实接口、边界、输出形式、验收标准。不必把整个仓库塞进去,优先提供相关文件和一个现有实现。 示例:“给现有 Vue2 查询页接入这个真实接口,沿用现有请求层,处理分页、请求乱序和错误提示,只修改相关文件,并说明验证结果。”
AI 一直改不对怎么办?
先复现和缩小问题,检查接口响应、控制台、网络及调用链,提出可验证的假设。把具体错误、预期与实际差异补给 AI,逐步验证。必要时自己定位根因,避免让它无依据地反复重写。
怎么判断 AI 生成的代码能上线?
检查接口和字段是否真实、依赖与版本是否兼容、状态和异步逻辑是否正确、权限边界是否合理;验证成功、失败、空数据及关键交互。编译通过不能证明业务正确。 准备一个“AI 生成了错误实现,我如何发现并修正”的真实例子。
都有 AI 了,你的价值是什么?怎么证明提效?
围绕需求澄清、方案取舍、复杂问题定位、验收和交付负责来回答。收益可以比较同类任务的交付时间、返工、缺陷或审查成本,说明样本和统计方式。 没测过就说“主要节省样板代码时间,整体收益尚未统计”,不要编造提效百分比。
AI 回答为什么能一个字一个字显示?
通常是服务端把生成结果增量传给客户端,前端逐步合并并渲染;一次传输可能包含多个 token,也可能拆在任意位置。它和前端拿完整文本再播放打字动画不是同一机制。
SSE、WebSocket、fetch 流怎么选?
SSE 是服务端向客户端推送事件的一种格式与机制;WebSocket 支持双向通信。fetch 可读取响应流,也能消费 SSE 格式;这三者不是完全并列的互斥选项。 原生 EventSource 通常用于 GET,不能直接设置任意请求头或 POST body;需要 POST 提交…
流式响应怎么解析?半截 JSON、中文被拆开怎么办?
字节块先用支持流式解码的 TextDecoder 等机制处理,保留尚未完整的事件片段,按照实际协议划分消息后再解析。不能每次 reader.read() 都直接 JSON.parse。 SSE 还涉及空行分隔、多个 data 行、换行形式和结束事件约定;流结束不等于业务成功,要按…
“停止生成”和“重新生成”怎么做?
前端通过 AbortController 取消 fetch 或关闭连接,并把消息标记为已停止;旧请求的迟到回调不能继续修改新消息。服务端是否停止生成和计费,取决于其取消机制,不能由前端单方面保证。 重新生成应有独立请求标识,明确是替换答案还是保留多个版本;网络失败、用户停止和模型…
聊天页面的数据和状态怎么设计?
区分 conversationId、messageId、requestId;分开管理会话和消息。消息至少区分等待、生成中、完成、失败、已停止,工具执行还应有独立状态。 考虑重复发送、切换会话后旧流返回、分页历史、重试、刷新恢复和乐观更新。不要用一个全局 loading 表示所有消…
Markdown、代码块、长会话怎么保证体验?
流式 Markdown 会出现未闭合代码块等中间状态,要容错,避免每个字符都重解析整段历史。按需要批量更新和缓存已完成内容;长记录采用分页或虚拟列表。 自动滚动应尊重用户向上阅读;提供“回到最新”。渲染不可信 HTML、链接和代码时做安全处理,不能直接信任模型输出。
API Key 放哪里?怎么防滥用?
长期模型密钥保存在服务端;前端调用自己的受控接口,由服务端做鉴权、额度、限流、超时和日志。客户端短期凭证只有在相应服务明确支持时才考虑。 模型输出和工具参数都是待验证输入。前端隐藏按钮不构成权限控制,工具执行前后仍要在可信服务端校验。
Token、上下文窗口、temperature 是什么?
Token 是模型处理文本等内容的单位,不等于固定字数。上下文容量有限,通常要考虑输入和输出预算,具体以模型接口为准。多轮历史、检索材料和工具结果都会占预算。 temperature 是部分模型支持的采样参数,不能把调低它当成事实正确性的保证。不同模型的参数支持和含义需查实际文档…
幻觉是什么,怎么减少?
指模型生成看似合理但不符合事实或证据的内容,原因不只“缺上下文”。可通过可靠检索、工具查询、约束输出、来源引用、拒答与人工复核降低风险,不能保证彻底消除。
RAG 是什么?Embedding 有什么用?
RAG 的核心是先检索相关材料,再将材料作为上下文供模型生成;Embedding 将内容映射成向量,可用于相似性检索,但 RAG 也可以使用关键词和混合检索。 前端关注文件处理状态、检索引用、原文定位、权限和无结果反馈;召回相关材料不代表最终答案一定正确。 Microsoft:R…
Prompt、RAG、微调有什么区别?
Prompt 在请求中提供指令和上下文;RAG 在生成时引入检索信息;微调通过训练调整模型权重。三者可以组合,选择要看知识更新频率、目标行为、数据量、成本和评测结果。 企业知识经常更新时,可优先评估检索;不要把微调当成随时更新数据库,也不要把 RAG 当成天然正确的答案系统。
Tool Calling 是什么?Agent 和固定工作流有什么区别?
Tool Calling 中,模型提出结构化工具调用,应用或平台验证参数、执行工具,再把结果反馈给模型;模型本身不是直接任意执行数据库操作。 固定工作流主要由预设逻辑安排步骤,Agent 通常允许模型在约束内动态决定下一步或工具。两者可组合,定义也有差异;回答时描述实际控制流程、…
MCP 是什么,和普通 API 有什么关系?
MCP 是 AI 应用与工具、资源等能力交换的协议,涉及 Host、Client、Server;它可以把已有 API 等能力提供给 AI 应用使用,本身不替代业务 API,也不负责保证模型回答正确。
Prompt、Rules、Skills、MCP 怎么区分?
概念 主要回答什么 例子 Prompt 这次任务要做什么 给当前列表页接真实查询接口 Rules 项目或会话应遵守什么约定,具体生效机制依工具而异 使用 Vue2、沿用请求层、控制修改范围 Skills 一类任务按什么可复用方法完成,可附脚本与参考材料 Vue2 接口页面处理流程…
Agent 怎么防止乱操作,怎么评估做得好不好?
把外部文档、网页和工具结果当作不可信数据,不能让其中的指令擅自改变任务或权限。使用最小权限、参数校验、必要确认、审计、超时、步骤和费用上限;只写“不要乱操作”的提示词不够。 用固定任务集和回归样本看任务成功率、工具错误率、引用准确性、延迟和成本;评估权限误用及失败后是否能恢复。展…
设计一个公司知识库问答页面
文档处理与检索链路、会话状态、流式与取消、引用、权限、失败与验证。
防抖与节流
触发频率、this 与参数、首尾调用、取消与刷新。
Promise / async 输出题
同步执行器、微任务入队、await 续体、定时器。
数组去重、分组、扁平化
相等规则、业务主键、Map 安全分组、深度与循环。
列表转树与 DFS / BFS
先建索引再连接;检测重复、孤儿和环;避免 O(n²) 查找。
简化 Promise.all
接受可迭代对象;吸收普通值和 thenable;保序;空输入;拒绝传播。
并发限制调度器
输入任务函数;固定 worker 数;同步异常与异步拒绝;保序与失败策略。
基础算法:Map、双指针、栈、二分
输入前提、复杂度、重复值、空结果;DFS/BFS 已在第 4 题给出。
深拷贝
支持范围、循环、共享引用、特殊对象、属性描述符。
发布订阅
订阅、精确取消、once、触发时增删、异常策略。
call / apply / bind / new
调用与绑定、参数合并、构造调用、返回值、实现边界。
TTL 缓存与 LRU
容量、最近访问顺序、过期、时钟、未命中语义。
响应式:已有对象属性的依赖收集
getter 收集、setter 触发、分支依赖清理、停止订阅。
Promise:三态、链式调用与 thenable 采纳
执行器同步、状态只确定一次、回调异步、返回值透传、错误传播、链式循环。
执行上下文、词法作用域和调用栈是什么关系?
作用域由定义位置决定;执行上下文承载一次执行的环境;调用栈组织同步调用;闭包延长词法环境中所需绑定的生命周期。
隐式类型转换和 ==、=== 的常见陷阱怎么解释?
先判断类型;对象参与转换先 ToPrimitive;+ 可能连接字符串;== 按类型组合转换;NaN、正负零分别理解。
大整数为什么丢失精度?MAX_SAFE_INTEGER、MAX_VALUE 与 BigInt 怎么选?
安全整数上限为 2^53−1;有限量级上限与精度无关;ID 用字符串;整数运算用 BigInt;JSON 序列化显式约定。
for…in、Object.keys、Reflect.ownKeys、in 和自有属性判断有什么区别?
区分自有/继承、可枚举/不可枚举、字符串/Symbol;不要用值是否 undefined 判断存在;数组遍历要区分索引和值。
map、forEach、reduce 遇到稀疏数组和回调参数会怎样?
回调收到 value/index/array;map 产生新数组,forEach 返回 undefined;空位不等于值 undefined;reduce 初始值决定空数组行为。
Object.create、寄生组合继承和 class extends 分别做了什么?
实例自有字段与原型方法分开;子原型用 Object.create;父构造函数只初始化一次;class 是原型机制上的语法且有额外语义。
高阶函数、柯里化、compose、pipe 与纯函数有什么联系?
高阶函数接收或返回函数;柯里化拆分参数;组合传递结果;纯函数同输入同输出且没有可观察副作用;异步组合需另定协议。
记忆化缓存怎么设计?为什么给递归函数包一层不一定加速递归?
缓存所有参数及必要的 this;对象按身份或显式业务键;区分缺失与缓存 undefined;有失效和容量策略;递归需要经过缓存入口。
setTimeout、setInterval 的延迟为什么不准确?如何避免任务堆积?
延迟是调度门槛而非执行承诺;主线程、后台限速和嵌套最小间隔影响时间;异步轮询可重叠;根据时间戳校正。
Map 与 WeakMap 怎么选?弱引用是否代表一定不会泄漏?
Map 可遍历、有 size;WeakMap 不可枚举,键弱引用;垃圾回收时机不可控;闭包和其他强引用仍可能保活;注意运行时版本。
CSS 层叠和选择器优先级怎么比较?:is、:where 有什么特殊之处?
先看来源、重要性与层,再比较 specificity;ID/类/元素分列比较;行内样式单独理解;:is 取参数最大值,:where 为零。
display:none、visibility:hidden、opacity:0 有哪些实际差别?
分别比较布局、绘制、命中测试、焦点与无障碍;透明不等于不可交互;aria-hidden 不会自动禁用键盘操作。
普通 script、async、defer 和 type=module 的加载执行顺序是什么?
经典脚本默认阻塞解析;async 下载后尽快执行且不保证顺序;defer 保序并在 DOM 解析后执行;模块默认延后且有依赖图。
px、em、rem、vw、vh、dvh 与设备像素比怎么理解?
CSS 像素与物理像素不同;em 看使用属性,rem 看根字体;移动视口高度会变化;高清屏细线与 Canvas 分辨率分开处理。
Canvas 与 SVG 如何选择?
Canvas 位图即时绘制;SVG 矢量元素树;缩放、命中、节点数、可访问性与更新频率共同决定方案。
GET、POST、PUT、PATCH、DELETE 的安全性与幂等性如何区分?
safe 指预期不改变服务器业务状态;幂等指重复请求预期效果相同;与响应是否相同无关;接口仍需正确实现。
常见 HTTP 状态码和重定向有哪些容易混淆的地方?
204/304 无响应内容;401 与 403 区分认证和拒绝;301/302 与 307/308 的方法保留不同;429 尊重 Retry-After。
HTTP/1.1、HTTP/2、HTTP/3 的队头阻塞分别发生在哪里?
HTTP/1.1 连接复用但流水线有响应顺序限制;HTTP/2 多流帧复用仍受 TCP 丢包影响;HTTP/3 基于 QUIC 分流恢复。
HTTPS 的 TLS 握手解决什么问题?证书和会话密钥是什么关系?
机密性、完整性、服务端身份认证;验证证书链和域名;协商临时密钥;应用数据用对称加密;TLS 版本决定细节。
TCP 和 UDP 的区别是什么?三次握手、四次挥手为什么不能只背次数?
TCP 有序可靠字节流;UDP 数据报且不保证交付顺序;可靠性有代价;握手确认双方收发与序列号;关闭两个方向可合并报文。
DNS 与 CDN 在一次资源访问中如何协作?更新不生效怎么排查?
DNS 解析可能经过多级缓存和 CNAME;CDN 选边缘节点;DNS 缓存和 HTTP 缓存不同;逐层确认命中的主机与内容版本。
Web Worker、SharedWorker 与 Service Worker 有什么区别?
都不能直接操作页面 DOM;专用 Worker 处理后台计算;SharedWorker 可共享;Service Worker 是事件驱动的网络代理与离线基础。
IndexedDB、CacheStorage 与 localStorage 如何选择?浏览器容量是多少?
localStorage 同步字符串;IndexedDB 异步结构化事务存储;CacheStorage 保存请求响应;容量因环境变化;处理配额与驱逐。
CSP 怎么配置才能产生实际价值?nonce、hash 与 Report-Only 分别是什么?
CSP 限制资源与执行来源;从报告模式验证;nonce 每次响应随机生成;hash 对内容匹配;不能替代转义与鉴权。
postMessage 跨窗口通信如何防止消息伪造和数据泄露?
指定精确 targetOrigin;接收端校验 origin、source 和消息结构;使用请求 ID;不把消息当代码执行;与 CORS 分工不同。
Webpack Loader、Plugin 与 Babel 的处理阶段怎么区分?
Loader 转换模块内容;Plugin 监听构建生命周期;Babel 解析、转换 AST、生成代码;转语法不等于补运行时 API。
HMR 为什么能保留状态?什么时候仍然需要整页刷新?
模块图定位更新;accept 边界接纳变更;dispose 清理旧副作用;框架决定组件状态是否保留;不保证所有修改都热替换。
hash、chunkhash、contenthash 与长期缓存有什么关系?
区分整体构建、chunk、内容粒度;运行时代码影响引用;稳定模块标识;HTML 与指纹资源采用不同缓存策略。
Source Map 如何帮助线上排障?怎么兼顾定位与源码暴露?
映射生成代码到源位置;版本与构建必须匹配;可私有上传监控平台;hidden/nosources 各有边界;敏感信息不能打进客户端。
构建慢、包体大和页面运行慢,应该分别怎么优化?
三类指标分开测;先 profile 再改;构建缓存与处理范围;产物分析与按需拆分;运行时看主线程和网络。
大量计算或 DOM 更新怎样拆分?rAF、requestIdleCallback 能解决什么?
主线程长任务影响输入和绘制;rAF 在绘制前执行但不转移线程;idle 有预算且可能延迟;按时间片让出,CPU 计算可放 Worker。
虚拟列表的可视范围如何计算?变高内容和滚动跳动怎么处理?
固定高度按 scrollTop/itemHeight 定位;上下占位和 overscan;可变高度用测量与前缀和;稳定 key、滚动锚点、数据范围与无障碍。
如何设计前端监控 SDK?sendBeacon 能保证日志不丢吗?
分错误类型捕获;版本与上下文关联;采样、批量、去重、脱敏;生命周期触发上报;Beacon 入队不等于服务端确认。
图片懒加载、预加载、预连接和 fetchpriority 怎么配合?
首屏关键图不懒加载;屏外图延迟;明确尺寸与合适资源;提示有成本且不是强制;以 LCP 与网络实测验收。
前端怎样实现网页截图?为什么不能直接 drawImage(documentElement)?
CanvasImageSource 不包含任意 DOM;DOM 渲染库存在样式兼容边界;真实浏览器截图可服务端完成;跨域资源与隐私必须处理。
接口超时与自动重试怎么设计,才不会重复下单或产生僵尸请求?
单次超时与总截止时间分开;AbortController 真正发出取消信号;重试条件受幂等性约束;指数退避加抖动;区分取消原因。
深色主题如何避免首屏闪烁?SSR 项目如何保存选择?
CSS 变量统一设计令牌;用户偏好优先于系统偏好;服务端 Cookie 决定首屏;首屏前设置主题;监听和清理系统变化。
不同域名的系统怎样实现 SSO?为什么不能直接共享 localStorage?
同源存储不能跨任意域共享;中央身份提供方;一次性授权码/票据与回调校验;state、PKCE、服务端会话;控制重定向地址。
手写 curry、compose 与 memoize,并说明实现边界。
curry 累积参数并明确 arity;compose 从右往左传单值;memoize 使用参数元组和 this 索引;正确缓存 undefined、区分正负零;说明同步、占位符与容量边界。
手写 map 与 reduce,如何保留空位并处理未提供初始值?
固定初始长度;用 in 检查属性存在;回调签名正确;reduce 根据 arguments.length 判断初始值;不修改内置原型。
Node.js 事件循环和浏览器有什么不同?nextTick、Promise、setImmediate 如何排序?
libuv 阶段;nextTick 队列与 Promise 微任务;timer 与 check;说明版本和执行位置,不背全局固定顺序。
Node.js 是单线程吗?CPU 密集任务与 I/O 密集任务怎样处理?
一个执行环境的 JS 主线程;系统异步 I/O、线程池与 Worker;线程与进程隔离;任务池与传输成本。
Express 与 Koa 的中间件如何执行?洋葱模型有什么要求?
注册顺序;继续执行条件;Koa await next 前后嵌套;Express4 异步错误显式 next;只响应一次。
Stream 与背压是什么?为什么不能把大文件全部读进内存?
分块消费;Readable/Writable/Transform;速度差导致缓冲;write false 等 drain;pipeline 统一错误与关闭。
Buffer、ArrayBuffer、Blob 和 Base64 怎么区分?中文分块怎么解码?
Buffer 是字节视图;ArrayBuffer 是内存容器;Blob 是不可变原始数据对象;Base64 是编码且增大体积;增量解码保留尾字节。
Node 文件操作怎样避免阻塞、路径穿越和竞态?
fs/promises;路径白名单与边界校验;权限与符号链接;避免先 exists 再操作;原子替换按平台处理。
Node 服务怎样优雅退出?PM2 重启能解决什么,不能解决什么?
停止接新请求;等待进行中工作;关闭连接与资源;总超时;进程守护与业务正确性分开。
Node 的 require 与 import 如何解析模块?为什么 ESM 常要求扩展名?
路径、包名、内置模块;CJS 历史补全;ESM 按 URL 与包 exports;package type;版本互操作。
EventEmitter 的监听是同步还是异步?如何避免泄漏?
emit 通常同步按监听顺序调用;async listener 不等于 emit 等待;error 特殊;off/once;监听数量告警不是根因修复。
Node 服务 CPU 高、内存涨、接口慢怎么定位?
分 CPU、heap/RSS、事件循环延迟、I/O 和下游;CPU profile、heap snapshot、请求时序;保留现场与脱敏。
dependencies、devDependencies、peerDependencies 和锁文件分别管什么?
运行依赖、开发工具、宿主兼容;安装模式不等于打包结果;npm ci 与锁文件;构建阶段和运行阶段区分。
前端 CI/CD 应有哪些阶段?如何设计可回滚发布?
可重复安装、相关检查、单次构建、制品版本、灰度与观测、回滚兼容;CI 不等于自动上线所有提交。
Webpack 的 module、chunk、bundle 分别是什么?
源码依赖单元、构建组织单元、输出产物;入口、动态导入和拆分;不保证一一对应。
BFF 与开发代理有什么区别?SSR 项目怎样聚合接口?
开发便利与生产业务层分开;聚合、裁剪、认证与超时;请求隔离;下游失败策略和安全目标。
tsconfig 的 target、module、lib 与 strict 分别影响什么?
输出语法、模块形式、可见 API 类型、检查强度;编译与运行支持分开;解析模式适配工具链。
is 类型守卫与断言有什么区别?怎样安全处理 unknown?
运行时验证与编译期承诺;谓词必须真实;null 与数组;边界数据先验证后使用。
keyof、映射类型、条件类型与 infer 怎么配合?
键集合与索引访问;逐键转换;按类型条件选择;infer 提取局部类型;分布式条件边界。
函数重载什么时候比联合参数合适?实现签名是什么?
多种调用关系;重载对外、实现承载联合;能用泛型/联合表达就避免过度重载;运行时仍要判断。
declare、.d.ts 与 @types 是什么?声明能创造运行时对象吗?
描述已存在能力;类型声明不产对应实现;模块声明与全局扩展;依赖版本与发布;不要用声明掩盖缺包。
namespace、ES Module、enum 与字面量联合怎么选择?
组织代码与组织类型;模块化优先适配工具链;enum 可能产运行时代码;联合通常被擦除;const enum 兼容边界。
DOM、BOM、Node、Element 与语义标签是什么关系?
文档树与浏览器宿主;元素是节点子类;语义与样式分开;原生交互和可访问性。
输入框限制长度、中文输入法与表单提交怎么处理?
原生约束与业务校验;composition;字符计数口径;粘贴和程序写入;服务端校验。
图片上传前怎样预览?Object URL、Data URL 如何释放和控制?
File/Blob;createObjectURL 与 revokeObjectURL;FileReader Data URL;类型、尺寸与解码;前端检查不是安全边界。
transform、transition、animation 的区别和动画性能如何解释?
变换值、状态过渡、关键帧序列;布局/绘制/合成;不是所有变换都零成本;减少动态偏好。
单行、多行省略为什么有时不生效?Flex 子项如何防撑宽?
有可约束尺寸才有溢出;nowrap/overflow/ellipsis 配合;Flex 自动最小尺寸;多行方案与兼容;可访问完整内容。
哪些事件不冒泡?mouseenter、mouseover 与事件委托有什么区别?
捕获、目标、冒泡;focus/blur 与 focusin/out;enter/leave 与 over/out;target/currentTarget/relatedTarget;原生与框架事件区分。
MessageChannel、BroadcastChannel、storage 与 postMessage 如何选择?
成对端口、同源广播、存储事件、指定窗口;结构化消息;来源权限、关闭与恢复;不把通信当持久化。
SRI、iframe sandbox 与防点击劫持分别解决什么?
资源完整性、嵌入权限、限制谁嵌入当前页;CORS 与 CSP 配合;校验摘要及最小权限。
小程序为什么没有普通 DOM?逻辑层、渲染层与 setData 如何协作?
宿主能力与 JS 引擎分开;逻辑/渲染隔离;序列化通信;局部更新、频率与数据量;渲染引擎版本边界。
小程序页面通信、bindtap/catchtap 与页面清理怎样处理?
URL 小参数、EventChannel、共享状态与存储;事件传播;onShow/onHide/onUnload;验证参数与取消请求。
观察者、发布订阅、策略、工厂和单例在前端怎么用?
按耦合关系与变化点选择;主题直接通知与事件中心;替换算法、创建实例、作用域唯一;SSR 不共享用户单例。
手写支持异步的 Koa 洋葱模型 compose,并防止多次 next。
递归 dispatch;Promise 采纳;每次请求独立游标;同步异常转拒绝;next 只前进一次;中间件要 await/return。
手写 Fisher–Yates 洗牌,为什么 sort(() => Math.random()-0.5) 不可靠?
剩余区间均匀选择;每步缩小区间;O(n);随机源假设;原数组不变;统计检验不同于证明。
手写稳定的归并排序,并分析复杂度与重复项顺序。
分治、合并有序序列;相等先取左侧;O(n log n);辅助空间与递归栈;比较器一致性。
删除字符串中出现次数最少的字符,怎样保持原顺序?
两遍计数与筛选;删除所有并列最少字符;码点与字形;O(n);空输入。
用 Promise 实现可取消的红绿灯循环,怎样避免递归和定时器泄漏?
等待包装 Promise;for/await 顺序;AbortSignal;取消清定时器与监听;有限轮测试;显示与停留语义明确。
CommonJS、AMD、CMD、UMD 与 ES Module 是怎样演进的?今天还要关心哪些差异?
CommonJS 服务端同步加载;AMD 依赖前置、CMD 就近依赖,解决浏览器异步加载;UMD 是兼容包装;ESM 是语言标准,静态结构、活绑定、可 Tree Shaking。今天主要关心 ESM 与 CommonJS 互操作。
迭代器协议和 Generator 是什么?怎样让普通对象支持 for...of?
可迭代对象有 Symbol.iterator 方法,返回带 next() 的迭代器;for...of、展开、解构、 Array.from 都依赖它。Generator 用 function* 和 yield 暂停与恢复,自动实现迭代器协议。普通对象默认不可迭代。
V8 怎样执行和回收 JavaScript?JIT、隐藏类、新生代与老生代分别是什么?
源码解析为 AST,Ignition 生成并解释字节码,收集类型反馈后由 Sparkplug、Maglev、TurboFan 分层编译成机器码,假设失效会去优化。隐藏类加内联缓存加速属性访问。分代回收:新生代 Scavenge 复制,老生代标记清除与整理,并通过增量、并发与并行减…
try...catch 能捕获哪些异步错误?forEach 里 await 为什么不按顺序等待?
try...catch 只捕获 try 块同步执行期间抛出的错误;稍后在定时器、事件回调中抛错捕获不到;Promise 必须在 async 函数中 await 后才能被 catch。forEach 不等待回调返回的 Promise,应改用 for...of 串行或 Promise…
怎样排查“到底是谁改了这个对象”?
开发环境用 Proxy 拦截 set/deleteProperty 打印调用栈;单个属性可用访问器设置断点;Object.freeze 让严格模式下的修改直接抛错;DOM 用“属性修改时中断”;框架用 Vue 的 onTrigger 或 Redux DevTools 看是谁触发了…
水平垂直居中有哪些写法?圣杯、双飞翼和 sticky footer 现在怎么实现?
首选 Flex 或 Grid;绝对定位配合 transform 适合覆盖层;单行文本可用 line-height。圣杯和双飞翼是早期用浮动加负边距实现“两侧定宽、中间自适应且主内容先加载”的方案,今天用 Grid 或 Flex 即可。sticky footer 用列方向 Flex…
浮动为什么会造成高度塌陷?清除浮动有哪些方式,和 BFC 有什么关系?
浮动元素脱离常规流参与布局,父元素计算高度时不包含它,于是塌陷。解决方式:后面元素 clear 、伪元素 clearfix、让父元素形成 BFC(首选 display: flow-root )。今天布局用 Flex/Grid,浮动主要用于文字环绕。
怎样用 CSS 画三角形?如何显示小于 12px 的文字和真正的 1px 细线?
三角形可用零宽高元素的透明边框,或 clip-path: polygon() 。部分浏览器设置有最小字号,小于 12px 可用 transform 缩放,但要兼顾可读性。高 DPR 屏幕的 1px 细线可用 0.5px 边框、伪元素 scale 或 box-shadow。
link 与 @import、src 与 href、label、data-* 属性分别有什么区别和用途?
link 是 HTML 元素,能被预加载扫描器提前发现并行下载;@import 在 CSS 下载解析后才发现,形成串行瀑布。src 嵌入并使用资源,href 建立到资源的关联。label 关联表单控件,扩大点击区域并提供可访问名称。data-* 存放自定义数据,通过 datase…
Sass/Less、BEM、CSS Modules、Scoped 与 CSS-in-JS 分别解决什么?怎样治理样式冲突?
预处理器提供变量、嵌套、混入等编译期能力;BEM 用命名约定降低冲突与优先级混乱;CSS Modules 和 Vue scoped 在构建时生成唯一类名或属性选择器实现作用域;CSS-in-JS 让样式与组件逻辑共存。全局治理还要靠设计令牌、Cascade Layers 和 St…
渐进增强和优雅降级是什么?browserslist、Autoprefixer 与 polyfill 如何配合处理兼容?
渐进增强先保证基础功能可用,再为能力强的浏览器叠加体验;优雅降级先按现代浏览器实现,再给旧环境可接受的回退。工程上用 browserslist 统一目标环境,Autoprefixer 补 CSS 前缀,Babel 转语法,core-js 等补运行时 API,再用特性检测兜底。
浏览器为什么采用多进程架构?一个标签页卡死为什么不一定拖垮整个浏览器?
现代 Chrome 分为浏览器主进程、渲染进程、GPU 进程、网络服务等进程。多进程带来稳定性(单个渲染进程崩溃不影响其他)、安全性(渲染进程运行在沙箱中,站点隔离防止跨站读取内存)和并行性。同站页面可能共享渲染进程,所以并不是完全隔离。
前端路由的 hash 与 history 模式怎样实现?刷新 404 如何配置?Link 和 a 有什么区别?
hash 模式改变 # 后的片段,不请求服务器,监听 hashchange ;history 模式用 pushState / replaceState 修改路径,监听 popstate 处理前进后退,但刷新时服务器会收到真实路径,必须回退到 index.html。路由库的 Lin…
手写一个 XMLHttpRequest 请求;XHR、fetch 与 axios 在进度、取消、错误判断上有什么区别?
XHR 通过 open、setRequestHeader、send 发请求,onload 判断状态码,onerror 处理网络错误,支持上传进度。fetch 基于 Promise,只有网络失败才拒绝,HTTP 404/500 仍然 resolve,需要检查 response.ok…
axios 的拦截器、适配器和取消请求是怎样工作的?
配置按默认值、实例、单次调用合并;请求拦截器后注册先执行,响应拦截器按注册顺序执行,中间是真正发请求的 dispatchRequest; use 返回 id,用 eject(id) 注销。适配器在浏览器用 XHR(新版也可选 fetch),在 Node 用 http 模块。取消用…
对称加密、非对称加密、哈希和数字签名分别解决什么问题?
对称加密(AES-GCM)同一密钥加解密,速度快,难点是密钥分发;非对称加密用公钥和私钥,适合密钥交换和签名;哈希(SHA-256)生成不可逆摘要,用于完整性校验;数字签名用私钥对摘要签名、公钥验证,证明来源且未被篡改。HTTPS 组合使用它们。
Cookie、Session、Token、JWT 怎样区分?JWT 泄露或需要立即失效怎么办?
Cookie 是浏览器保存并自动携带的机制;Session 是服务端保存的登录状态,通常用 Cookie 里的 session id 关联;Token 是放在请求头或 Cookie 中的凭证字符串;JWT 是一种自包含、带签名的 Token,服务端无需查库即可验证,但签发后难以提…
OAuth 2.0 授权码流程是什么?扫码登录如何设计?
OAuth 2.0 是授权协议:客户端带 client_id、redirect_uri、scope、state 和 PKCE 的 code_challenge 跳到授权服务器,用户同意后回调带 code,后端用 code 加凭证换取 access token。state 防 CS…
OSI 七层与 TCP/IP 四层模型分别是什么?前端常见协议在哪一层?
OSI 七层:物理、数据链路、网络、传输、会话、表示、应用;TCP/IP 四层:网络接口(链路)、网际(IP)、传输(TCP/UDP)、应用。HTTP、DNS、WebSocket 属于应用层;TLS 位于 TCP 与 HTTP 之间;QUIC 运行在 UDP 上,自己实现可靠传输…
浏览器为什么限制同源并发连接?域名分片在 HTTP/2 下还有用吗?
HTTP/1.1 下浏览器对同一主机的并发 TCP 连接有上限(Chrome 常见为 6),以保护服务器、让 TCP 拥塞控制公平运作并节约客户端资源。域名分片能在 HTTP/1.1 下绕过限制,但增加 DNS、TCP、TLS 开销;HTTP/2 多路复用单连接,分片反而破坏复用…
PWA 由哪些部分组成?怎样把传统网站改造成可安装、可离线的应用?
核心是 HTTPS、Web App Manifest 和 Service Worker。Manifest 描述名称、图标、启动地址和显示方式;Service Worker 拦截请求,实现离线缓存、后台同步和推送。改造时为不同资源选择缓存策略,设计更新提示,避免旧缓存困住用户。
GraphQL 与 REST 有什么区别?什么时候值得引入?
REST 按资源设计多个端点,响应结构由服务端决定;GraphQL 通常一个端点,基于强类型 Schema,由客户端声明需要的字段,减少过度获取和多次往返。代价是 HTTP 缓存更难、需要处理 N+1 查询、查询复杂度限制和字段级权限。多端需求差异大、需要聚合多个服务时更值得引入…
Vue 有哪些常用修饰符?Vue3 中 .native 和 .sync 去哪了?
事件修饰符 .stop .prevent .self .once .capture .passive ;按键与鼠标修饰符 .enter .esc .ctrl .exact .left ;v-model 修饰符 .lazy .number .trim 。Vue3 移除了 .nati…
怎样写 Vue 自定义指令?用 v-permission 做按钮权限有什么局限?
指令适合封装直接的 DOM 操作,Vue3 钩子为 created、beforeMount、mounted、beforeUpdate、updated、beforeUnmount、unmounted,参数为 el、binding、vnode。v-permission 在 mount…
Vue 插件是什么?和组件有什么区别?全局方法应该挂 globalProperties 还是 provide?
插件是带 install(app, options) 的对象或函数,用 app.use 安装,可注册全局组件、指令、provide 和全局属性;组件是可复用的 UI 单元。Vue3 的 app.config.globalProperties 只能在模板和 Options API …
父组件怎样监听子组件的生命周期?
最清晰的是子组件主动 emit 事件;Vue2 可用 @hook:mounted 监听任意子组件的生命周期钩子;Vue3 改为 @vue:mounted 这类 vnode 生命周期事件。需要拿到实例时用 ref 配合父组件 onMounted,父组件的 mounted 在子组件之…
Vue 应用中错误怎样分层捕获?errorHandler 和 errorCaptured 能捕获什么?
app.config.errorHandler 是应用级兜底,能捕获组件渲染、生命周期、侦听器、事件处理函数以及 setup 中返回的 Promise 拒绝; onErrorCaptured 捕获后代组件错误,可实现局部错误边界,返回 false 阻止继续向上传播。不在 Vue …
computed 的缓存是怎么实现的?和 methods、watch 有什么区别?
computed 是带脏标记的惰性副作用:首次读取时执行 getter 并收集依赖,依赖变化只把它标记为脏并通知订阅者,下次读取才重新计算,依赖不变就返回缓存。methods 每次调用都执行;watch 用于数据变化后执行副作用。Vue 3.4 起,computed 重新计算后值…
React 为什么需要 Fiber 和时间切片,Vue 却没有引入同样的机制?
React 更新默认从触发组件开始自顶向下重新执行组件并 diff,组件树大时一次更新可能很重,所以需要 Fiber 把渲染拆成可中断的单元并按优先级调度。Vue 通过响应式系统精确知道哪个组件依赖了哪个数据,更新粒度是组件级,再配合编译期优化减少 diff,单次更新通常足够小,…
JSX 本质是什么?为什么 React 17 以后不用再手动 import React?
JSX 是语法扩展,编译后成为创建 React 元素的函数调用:旧转换为 React.createElement(type, props, ...children) ,React 17 起的新转换为 jsx() / jsxs() ,由编译器自动从 react/jsx-runtim…
React 类组件的生命周期有哪些?PureComponent 与 Hooks 怎样对应?
挂载:constructor → getDerivedStateFromProps → render → componentDidMount;更新:getDerivedStateFromProps → shouldComponentUpdate → render → getSna…
Redux 的数据流和中间件原理是什么?redux-thunk 和 redux-saga 有什么区别?
单向数据流:dispatch(action) → reducer(state, action) 纯函数返回新状态 → store 通知订阅者。中间件是包装 dispatch 的柯里化函数 store => next => action ,可在 action 到达 reducer …
Redux、MobX、Zustand、Vuex、Pinia 应该怎样选?
先区分状态类型:服务端数据交给 React Query、SWR 或 RTK Query;局部 UI 状态放组件内;真正跨页面共享的客户端状态才用全局 store。Redux(RTK)流程显式、生态和调试最完善;MobX 基于可观察对象自动追踪,代码量少;Zustand 轻量、基于…
HOC、Render Props 和自定义 Hooks 有什么区别?逻辑复用该怎么选?
HOC 是接收组件、返回增强组件的函数;Render Props 通过函数 prop 把数据交给调用方渲染;自定义 Hook 在函数组件中直接复用有状态逻辑。HOC 和 Render Props 会带来嵌套地狱、props 命名冲突和来源不清,新代码优先用自定义 Hooks;HO…
React Scheduler 怎样实现时间切片和优先级调度?
Scheduler 维护按过期时间排序的任务小顶堆,用 MessageChannel 在宏任务中执行工作循环,每个时间片约 5ms,超时就让出主线程,下一个宏任务继续。React 用 Lane 位掩码表示更新优先级,用户输入为同步或高优先级,Transition 为低优先级,高优…
React 怎样实现类似 Vue keep-alive 的组件缓存?
React 卸载组件就会丢失状态,没有内置 keep-alive。常见方案:用 CSS 隐藏而不是卸载;把需要保留的状态提升到父组件、全局 store 或 URL;React 19.2 起使用官方 <Activity mode="hidden"> ,隐藏时保留状态与 DOM 并卸…
Webpack 的构建流程是什么?怎样写一个 Plugin?
初始化合并配置并创建 Compiler,注册插件 → run 后从 entry 开始,每个模块经 loader 转换、解析 AST 收集依赖,递归构建依赖图 → seal 阶段按入口和动态导入划分 chunk,优化、生成代码与哈希 → emit 写出文件。Plugin 是带 ap…
git 的 merge、rebase、squash、revert、cherry-pick 分别在什么场景使用?
merge 保留分支历史并生成合并提交;rebase 把提交重放到新基底上,历史线性,但会改写提交,不能对已共享的分支随意使用;squash 把多个提交压成一个;revert 生成反向提交来撤销,适合已推送的公共分支;reset 移动分支指针,适合本地;cherry-pick 把…
ESLint 是怎样工作的?husky、lint-staged、commitlint 如何组成提交前检查?
ESLint 用解析器把代码转成 AST,规则在遍历 AST 时订阅节点类型并报告问题,可附带自动修复。ESLint 9 默认使用扁平配置 eslint.config.js 。husky 管理 Git 钩子,lint-staged 只检查暂存的文件,commitlint 校验提交…
怎样从零写一个前端脚手架 CLI?
在 package.json 中用 bin 声明命令,入口文件首行加 #!/usr/bin/env node ;用 commander 等解析参数,用 prompts 等交互收集选项;从本地模板目录或远程仓库拉取模板,替换变量后写入目标目录;最后可选安装依赖、初始化 git,并输…
前端测试怎样分层?Jest、Vitest、Testing Library、Playwright 各负责什么?
单元测试验证纯函数和独立模块;组件测试用 Testing Library 从用户视角查询元素、触发交互;集成测试用 MSW 等模拟接口验证模块协作;端到端测试用 Playwright 或 Cypress 在真实浏览器跑关键流程。Jest 与 Vitest 是测试运行器,Vite …
前端项目怎样用 Docker 和 Nginx 部署?缓存头应该怎么配?
多阶段构建:第一阶段用 Node 镜像安装依赖并构建,第二阶段只把产物复制进 Nginx 镜像,镜像小、无源码与 node_modules。Nginx 配置:带哈希的静态资源长期缓存加 immutable,index.html 使用 no-cache 每次协商,history 路…
新版本发布后,怎样提示正在使用旧页面的用户刷新?
构建时生成版本号写入 version.json 与页面;前端在页面重新可见、路由切换或定时轮询时请求 version.json?t=时间戳 (或配置 no-cache),版本不同则提示刷新。动态导入 chunk 失败时,捕获错误后提示或自动刷新一次。使用 Service Work…
微前端解决什么问题?qiankun 的 JS 沙箱和样式隔离怎样实现?为什么不直接用 iframe?
微前端让多个团队独立开发、部署不同技术栈的子应用,并组合成一个产品,适合大型后台和遗留系统渐进迁移。qiankun 基于 single-spa,用 HTML Entry 加载子应用,通过 Proxy 沙箱隔离全局变量,通过 Shadow DOM 或选择器前缀隔离样式。iframe…
怎样搭建和发布一个公司内部组件库?
用 Vite 库模式或 Rollup 构建 ESM 与类型声明,组件按目录组织、支持按需引入; package.json 配置 exports 、 types 、 sideEffects 标记样式文件,把 Vue、React 放在 peerDependencies ;样式基于 C…
Node 如何利用多核?cluster、worker_threads 与 PM2 集群模式有什么区别?
Node 的 JS 主要运行在单个线程,但 I/O 由 libuv 线程池和系统异步接口处理。利用多核有两类:cluster 或 PM2 cluster 模式创建多个进程共享同一端口,适合 HTTP 服务横向扩展;worker_threads 在同一进程内开线程,适合 CPU 密…
Node 服务怎样安全地接收文件上传?
上传使用 multipart/form-data,服务端用 multer、busboy、formidable 或 koa-body 流式解析,限制文件大小、数量和字段长度;用文件内容的魔数判断真实类型,而不是只信扩展名和 Content-Type;文件名由服务端生成,存储在 We…
TypeScript 装饰器怎样使用?标准装饰器和 experimentalDecorators 有什么区别?
装饰器是在类及其成员定义时运行的函数,用于附加元数据或包装行为,常见于 NestJS、TypeORM、Angular。TypeScript 5.0 起支持 TC39 标准装饰器,签名是 (value, context) ;旧版 experimentalDecorators 签名是…
TypeScript 中的协变、逆变、双变和不变是什么?strictFunctionTypes 改变了什么?
设 Dog 是 Animal 的子类型:协变指 T<Dog> 可赋给 T<Animal> ,如数组、返回值;逆变方向相反,函数参数位置是逆变的;双变两个方向都允许;不变两个方向都不允许。开启 strictFunctionTypes 后,函数类型属性的参数按逆变检查,但方法简写语法…
TypeScript 的 public、private、protected、#private、readonly 和抽象类有什么区别?
public 默认可访问;protected 只能在类及子类内部访问;private 只能在声明它的类内访问;这三者只在编译期检查,运行时仍可访问。 #field 是 JavaScript 原生私有字段,运行时真正不可访问。readonly 只禁止重新赋值。abstract 类不…
uni-app 是怎样实现一套代码多端运行的?条件编译、生命周期和分包要注意什么?
uni-app 基于 Vue 语法,编译期把代码转换为各平台产物:小程序端编译为 WXML/WXSS 和对应 JS,H5 端是普通 Vue 应用,App 端由 WebView 或原生渲染(nvue、uvue)承载。平台差异用 #ifdef / #ifndef 条件编译处理。生命周…
JSBridge 的原理是什么?H5 与原生 App 怎样双向通信?
H5 调原生:原生向 WebView 注入对象(Android addJavascriptInterface 、iOS WKScriptMessageHandler 的 window.webkit.messageHandlers ),或拦截自定义 URL Scheme。原生调 H…
微信小程序的登录和支付流程是什么?
登录:小程序调用 wx.login 拿到一次性 code,发给自己的服务端;服务端用 appid、secret 和 code 调用 code2Session 换取 openid 与 session_key,生成自己的登录态返回。session_key 不能下发给前端。支付:服务端…
低代码平台或表单生成器应该怎样设计?
核心是 Schema 驱动:用 JSON 描述组件类型、属性、校验、布局与联动规则;设计器负责拖拽编辑并产出 Schema;渲染器根据组件注册表把 Schema 渲染为页面。联动用声明式表达式或规则引擎,撤销重做基于命令或快照历史,Schema 需要版本号和迁移脚本,自定义能力通…
前端埋点有哪几种方式?曝光、停留时长和上报可靠性怎样处理?
代码埋点在业务代码中手动调用,数据精确但成本高;可视化埋点在圈选工具中配置元素与事件;无埋点(全埋点)自动采集点击和页面浏览,后期再筛选。曝光用 IntersectionObserver 判断元素可见比例和持续时间;停留时长结合 visibilitychange 计算;上报优先 …
前端国际化需要考虑哪些问题?
文案抽离为语言包并按需懒加载;用 vue-i18n、react-i18next 等处理插值与复数;日期、数字、货币、相对时间用 Intl API 按地区格式化;时间统一以 UTC 存储、按用户时区展示;支持阿拉伯语等从右到左布局;语言选择根据 URL、用户设置和 Accept-L…
数据大屏怎样做多分辨率适配?图表组件如何封装和避免内存泄漏?
大屏通常按设计稿尺寸(如 1920×1080)开发,再用 transform scale 等比缩放,保持比例并处理留白;也可用 vw/vh 或 rem 方案。图表监听容器尺寸用 ResizeObserver,组件卸载时调用 chart.dispose() 。实时数据更新用 set…
超大文件下载怎样设计?
优先让浏览器原生下载:服务端设置 Content-Disposition: attachment 与正确的文件名,前端用 a 链接或预签名 URL 直连对象存储/CDN,不经过 JS 内存。支持 Range 实现断点续传和多线程下载。前端需要处理进度或加工数据时,用 fetch …
怎样实现复制到剪贴板、禁止复制和粘贴时清洗内容?
复制用异步剪贴板 API navigator.clipboard.writeText ,需要安全上下文和用户手势,失败时回退到 textarea 加 document.execCommand('copy') (已废弃但仍广泛可用)。禁止复制可用 user-select: none…
移动端的点击延迟、点击穿透和滚动性能问题怎样处理?
300ms 延迟来自浏览器等待判断是否双击缩放,设置 width=device-width 的 viewport 或 touch-action: manipulation 后现代浏览器已取消,FastClick 不再需要。点击穿透是 touchstart 关闭遮罩后,延迟派发的 …
页面水印怎样实现?怎样防止被轻易删除?
明水印:用 Canvas 或 SVG 绘制包含用户名、时间的旋转文字,转成图片作为全屏覆盖层的重复背景,设置 pointer-events: none 不影响操作。防删除:MutationObserver 监听水印节点被删除或样式被修改时重新生成。前端水印只能增加删除成本,追溯泄…
前端有哪些反爬和防调试手段?它们的边界在哪里?
反爬主要在服务端:频率限制、行为风控、验证码、登录与签名校验、设备指纹;前端可做接口参数签名、代码混淆、字体映射混淆数字、蜜罐链接。防调试常见手段是无限 debugger、检测开发者工具、禁用右键与快捷键。这些都只能提高成本,所有运行在用户浏览器中的代码和数据最终都可以被获取。
手写 Generator 自动执行器,说明它和 async/await 的关系。
执行器调用 Generator 得到迭代器,每次 next(value) 拿到 yield 出的值,用 Promise.resolve 包装后等待:成功则把结果 next 回去,失败则 throw 回 Generator,使其内部 try...catch 能捕获; done 为 …
实现可取消的 sleep,并按顺序每隔一段时间打印 1、2、3。
sleep 返回在 ms 毫秒后 resolve 的 Promise;支持 AbortSignal 时,开始前已取消直接拒绝,取消时清除定时器并拒绝,完成时移除监听。顺序打印用 for...of 加 await sleep 串行;如果题意是“在第 1、2、3 秒分别打印”,也可以…
手写链表的反转、合并两个有序链表和查找中间节点。
反转用 prev、cur 两个指针逐个调转 next,先保存后继;合并用哨兵节点 dummy 简化头节点处理,比较两表头较小者接到尾部,最后接上剩余部分;中间节点用快慢指针,快指针每次两步、慢指针一步,偶数长度时返回第二个中间节点。均为 O(n) 时间、O(1) 额外空间。
手写快速排序,并说明 JavaScript 的 sort 是否稳定。
选择基准,把数组分为小于、等于、大于三部分,递归排序两侧。随机选择基准避免有序数组退化为 O(n²);三路划分处理大量重复元素;先递归较短的一侧、循环处理较长一侧,把递归深度控制在 O(log n)。快速排序不稳定。ES2019 起 Array.prototype.sort 要求…
实现括号匹配校验和滑动窗口最大值。
括号匹配用栈:左括号入栈,右括号时弹出栈顶并检查是否配对,遍历结束栈必须为空。滑动窗口最大值用单调递减双端队列保存下标:新元素入队前弹出所有不大于它的队尾,队头下标滑出窗口时移除,队头即当前窗口最大值,整体 O(n)。
用动态规划解决爬楼梯、最大子数组和与最长递增子序列。
动态规划先定义状态、写出转移方程、确定初始值,再考虑压缩空间。爬楼梯 f(n) = f(n-1) + f(n-2) ,只需两个变量;最大子数组和(Kadane):以 i 结尾的最大和等于 max(nums[i], 前一个 + nums[i]) ;最长递增子序列用“各长度子序列的最…
实现千分位格式化、模板字符串渲染和 Cookie 解析。
千分位:先用正则拆出符号、整数与小数部分,只对整数部分用 \B(?=(\d{3})+(?!\d)) 插入逗号;业务中优先 Intl.NumberFormat 。模板渲染:正则匹配 {{ path }} ,按点路径从数据中取值,只读取自有属性,缺失时保留占位符,null 渲染为空字…
怎样避免深递归导致栈溢出?实现蹦床函数、大数阶乘和迭代版数组扁平化。
规范中的尾调用优化只有 Safari 实现,不能依赖。可行办法:改写为循环;用蹦床函数让递归返回“下一步”的函数,由外层循环执行;用显式栈模拟递归。阶乘结果很快超出 Number.MAX_SAFE_INTEGER ,需要 BigInt。扁平化用栈迭代,跳过数组空位并检测循环引用。…
实现一个与服务器时间校准、不会越走越慢的倒计时。
不要用 setInterval 每次减一秒,定时器会延迟、页面后台会被节流,误差不断累积。正确做法:记录服务器时间与本地单调时钟的偏移,每次根据“结束时间 − 当前校准时间”重新计算剩余毫秒;下一次定时只等到下一个整秒边界;页面回到前台或重新联网时重新校准;剩余时间按向上取整秒展…
new 做了什么?instanceof 为什么有时会误判?
new 创建对象、把原型指到构造函数的 prototype 、用该对象作为 this 调用构造函数;构造函数返回对象时, new 的结果是这个返回值,返回原始值则仍用新建对象。 instanceof 沿实例的原型链查找构造函数的 prototype ,可以被 Symbol.has…
属性描述符、访问器,以及 freeze、seal、preventExtensions 有什么区别?
数据属性有 value、writable、enumerable、configurable;访问器属性用 get 和 set 代替 value 和 writable。普通赋值创建的属性默认可写、可枚举、可配置。 defineProperty 省略的标志默认为 false。 prev…
原型污染是怎么发生的?怎样防护?
危险来自把外部键写进对象,尤其是递归合并时读到 __proto__ 或 constructor.prototype ,从而修改 Object.prototype 。 JSON.parse 本身用的是定义自有属性,解析出 __proto__ 键不会立刻污染全局。防护是拒绝这几个键、…
await、queueMicrotask、Promise.then 和 setTimeout 的执行顺序怎么推?
同步代码先走完,调用栈清空后才清空微任务;微任务里新排入的微任务仍在本轮清空。 await 即使等的是已完成的值,恢复也要排一次微任务。 setTimeout 是宏任务,要等当前轮微任务全部结束。顺序由“谁先登记”决定,不是由写在源码更下面决定。
Promise 的 then、catch、finally 怎样传递值和错误?
then 成功回调的返回值成为下一个 Promise 的成功值;返回 thenable 会采纳它;抛错或返回拒绝的 Promise 会拒绝。 catch 是只处理拒绝的 then 。 finally 不改成功值,回调抛错或返回拒绝时才会把链变成拒绝。非函数的处理函数会把状态原样往…
async 函数一定返回 Promise 吗?await 后面不是 Promise 会怎样?
async 函数的返回值一定是 Promise。函数里 return 普通值 等价于这个 Promise 兑现为该值; return thenable 会再解包一层;抛错则拒绝。 await 对非 Promise 也会先 Promise.resolve ,恢复至少延后一个微任务。…
arguments、默认参数、剩余参数和箭头函数有什么差异?
普通函数有 arguments ,它是类数组。严格模式下它和具名参数不再互相同步。默认值从左到右计算,可以引用前面的参数,后面的参数还在暂时性死区。剩余参数是真正的数组,不包含已具名的参数。箭头函数没有自己的 this 、 arguments 、 new.target ,也不能 …
解构和展开做的是浅拷贝吗?structuredClone 能替代手写深拷贝吗?
对象展开、数组展开、 Object.assign 和解构只复制一层,嵌套对象仍是同一引用。 structuredClone 能克隆多数内置结构、循环引用和 Map / Set ,不能克隆函数、DOM 节点、类实例的方法,也不会走访问器以外的自定义克隆协议。深拷贝方案要按数据种类选…
哪些数组方法会改原数组?类数组怎样转成真正的数组?
push 、 pop 、 shift 、 unshift 、 splice 、 sort 、 reverse 、 fill 、 copyWithin 修改原数组。 map 、 filter 、 slice 、 concat 返回新数组。ES2023 的 toSorted 、 to…
JavaScript 字符串为什么按码元计数?正则的 lastIndex 为什么会串结果?
字符串按 UTF-16 码元存储,补充平面的字符(例如多数 emoji)占两个码元, length 和 charAt 数的是码元。码点要用 for...of 、展开、 codePointAt 和 Array.from 。带 g 或 y 的正则会更新 lastIndex ,同一个正…
Symbol 解决什么问题?常见内置 Symbol 有什么用?
Symbol() 每次创建唯一值,适合做不会冲突的属性键。 Symbol.for 按字符串在全局注册表复用。Symbol 不能被隐式转成字符串。内置 Symbol 用来定制语言协议,例如 iterator 、 toPrimitive 、 hasInstance 、 toStrin…
怎样做可靠的深比较?JSON.stringify 为什么不行?
先用 Object.is 处理同一引用、 NaN 和正负零。再按类型比较:日期比时间,正则比 source 和 flags,数组要区分空位,普通对象比原型和全部自有键,包括 Symbol。循环引用用 WeakMap 记住“正在比较的一对”。 JSON.stringify 会受键顺…
严格模式改变了哪些行为?
严格模式禁止静默失败:未声明赋值、删除变量、重复参数、 with 、八进制字面量都会报错。函数里的 this 不再自动变成全局对象, arguments 不再和参数别名。ES Module、class 体默认是严格模式。
ES Module 循环依赖时,为什么会读到未初始化的值?
ESM 的导入是活绑定,模块实例只执行一次。循环依赖时,后开始执行的模块会先执行;此时先开始的模块已经有绑定,但 const 可能还在暂时性死区,顶层读取会抛 ReferenceError。把读取放进函数,等两边都执行完再调用,就能读到最终值。
对象的键会怎样转换?属性顺序和 delete 有什么规则?
普通对象的键只有字符串和 Symbol。数字、对象作键时会先转成字符串,所以 1 和 '1' 是同一个键,两个不同对象经常都变成 [object Object] 。现代引擎枚举自有属性时,先按升序给出整数索引,再按插入顺序给出其他字符串,最后是 Symbol。 delete 删除…
通用前端
详细阅读顺序:回答要点 → 原理拆解 → 示例与推演 → 易错点 → 参考回答;已有追问继续附完整解答。结合两份飞书资料整理的来源、合并位置和纠错见 专题深化与资料整理说明 。 整理日期:2026-11-04。适用方向:通用 Web 前端,重点照顾 Vue2 / Nuxt2 开发…
现在面试通常怎么问
常见考察方式是沿着一个主题不断追问: 是什么 → 为什么 → 项目里怎么用 → 出问题怎么查 → 有什么边界和取舍。 环节 常见问题 准备到什么程度 自我介绍 做过什么业务?主要负责什么? 1~2 分钟讲清经历、技术栈、个人贡献 项目深挖 最难的功能?为什么这样设计?怎么证明有效…
手写和输出题:按这个顺序练
以下所有手写题的回答要点、完整代码、示例、复杂度与边界说明已放在 手写题参考答案 。代码以明确支持范围的面试实现为目标,不冒充完整原生规范实现。 优先级 题型 重点边界 P0 防抖、节流 this、参数、连续调用、取消、首尾触发 P0 Promise / async 输出题 执行…
场景题:重点练“方案 + 异常 + 验证”
面试问题 回答要覆盖 搜索输入很快,结果偶尔回到旧内容 防抖、取消请求或请求序号、旧响应隔离、loading 的归属 用户连续点提交,怎么防重复订单 前端禁用与状态反馈;后端幂等键和唯一约束,失败重试语义 大文件上传与断点续传怎么做 切片、标识、并发、重试、服务端校验、合并、进度…
如果投 React 岗,额外准备什么
Vue 背景可以先掌握这些题目的逻辑;如果 JD 明确要求 React,需要真实编码练习支撑。 state 为什么不能直接改?为什么 setState 后当前回调里读到的值没变?理解每次渲染的状态快照。 为什么连续更新常需要函数式 updater?闭包读取的是哪次渲染的值? us…
项目回答模板:提前填两份
复制下面的模板,用自己的真实经历填写。没有统计的数据要说明,别编造“提升 80%”。 项目 / 功能: 用户与业务目标: 我的负责范围: 技术栈及相关版本: 具体问题与影响: 定位过程和证据: 考虑过的方案: 最终方案及取舍: 关键实现: 异常与边界: 如何验证: 结果及统计口径…
7 天复习安排
按每天约 2~3 小时制定;时间少就先做 P0。每次复习至少包含口述和编码,不要只看答案。 时间 重点 当天产出 第 1 天 简历、自我介绍、两个项目案例 每个案例能连续回答“为什么、怎么做、怎么验证” 第 2 天 JS、事件循环、Promise 解释几道输出题,写防抖 / 节流…
面试前自检
[ ] 自我介绍在 1~2 分钟内,和简历一致。 [ ] 两个项目案例分清个人贡献,有定位证据和验证方法。 [ ] 能讲 Vue2 响应式限制、computed / watch、nextTick、key。 [ ] 能解释事件循环和 Promise,并处理请求乱序。 [ ] 能讲清…
框架专题
详细阅读顺序:回答要点 → 原理拆解 → 示例与推演 → 易错点 → 参考回答;已有追问继续附完整解答。结合两份飞书资料整理的来源、合并位置和纠错见 专题深化与资料整理说明 。 整理日期:2026-11-04。共 60 题:Vue2 18 题、Vue3 20 题、React 22…
阅读顺序与版本边界
**主要做 Vue2:**先看 1~18,再看 Vue3 响应式、组合式逻辑与迁移,最后补 React 的状态和 Hooks。 **投 Vue3 岗:**重点看 19~38,同时能解释 Vue2 与 Vue3 的差异。 **投 React 岗:**重点看 39~60,配合编码练习…
四、跨框架对比:不要机械对应
主题 Vue2 Vue3 React 组件内状态 data 中可观察的属性 ref / reactive 等 useState / useReducer 等快照 更新方式 响应式 setter、数组方法等通知 代理或 ref 访问触发依赖更新 setter / dispatch …
五、框架场景题:把知识落到代码
场景题 Vue 侧重点 React 侧重点 搜索结果被旧响应覆盖 watcher / 请求清理,请求标识,状态归属 Effect 清理或事件请求控制,闭包与请求标识 编辑弹窗关闭重开仍是旧数据 props 草稿、重置时机、实例复用 状态初始化只执行一次、key、受控表单 列表排序…
六、容易失分的回答
“Vue3 只有 Proxy。”——还需要解释 ref、依赖追踪、调度与编译优化各自负责什么。 “Vue2 的数组不响应式。”——数组变更方法能触发更新,限制在特定操作。 “Vue3 解构一定失去响应式。”——值的类型、原对象及编译场景都要区分。 “React state 就是异…
七、复习完成标准
[ ] 主技术栈的 P0 题能不看资料讲清,并给出一个真实例子。 [ ] 能解释“为什么这样写”,也能回答改变条件后的取舍。 [ ] 能复现并修复一次请求乱序、状态残留或清理缺失问题。 [ ] 能独立封装一个输入 / 弹窗组件,说明状态和事件契约。 [ ] 能区分响应式依赖追踪与…
AI 专题
详细阅读顺序:回答要点 → 原理拆解 → 示例与推演 → 易错点 → 参考回答;已有追问继续附完整解答。结合两份飞书资料整理的来源、合并位置和纠错见 专题深化与资料整理说明 。 整理日期:2026-11-04。面向前端岗位,重点是使用 AI 完成交付、开发 AI 产品和理解应用原…
六、没做过 AI 项目时怎么回答
可以如实说:“我主要做 Vue2 / Nuxt2 业务开发,目前用 AI 辅助定位和实现,尚未上线完整 AI 产品。我了解流式聊天、RAG 和工具调用的基本链路;实际使用案例是……,我的验证方式是……。” 不要把教程复现说成线上经验。建议复习顺序: 一个真实 AI 辅助开发案例 …
手写题答案
详细阅读顺序:回答要点 → 原理拆解 → 示例与推演 → 易错点 → 参考回答;已有追问继续附完整解答。结合两份飞书资料整理的来源、合并位置和纠错见 专题深化与资料整理说明 。 本文补齐总清单里的全部 12 类手写题。每题给出回答要点、口述答案、完整代码、示例与边界;不需要再查资…
进阶补充
详细阅读顺序:回答要点 → 原理拆解 → 示例与推演 → 易错点 → 参考回答;已有追问继续附完整解答。结合两份飞书资料整理的来源、合并位置和纠错见 专题深化与资料整理说明 。 从 files/ 中分享的面试资料筛选题目,按现有题库去重后补充 40 道。每题提供回答要点与可以直接…
资料筛选与纠错
采用与去重结果 方向 处理结果 补充题号 JS 基础与函数 补齐隐式转换、精度、遍历、稀疏数组、函数组合等边界 1~10 HTML/CSS 补齐层叠、可见性、脚本顺序、尺寸单位、图形方案 11~15 网络与安全 补齐协议演进、状态码、Worker、存储、CSP、跨窗口通信 16~…
专题深化
这份文档配合原五份题库,新增 36 道目前较薄弱的专题题。所有题目按“回答要点 → 原理拆解 → 示例与推演 → 易错点 → 参考回答”组织,原有 213 道题也采用同样的详细阅读层次。参考回答用于口述,原理和示例用于理解,不需要靠外部链接才能补齐基本答案。 参考入口: 史上最全…
资料合并与纠错说明
新版分享目录包含 16 个专题,目录标称合计 945 题。目录数量包含重复与交叉分类,并非去重后的独立题数。这里按专题目录和代表题对照现有题库,保留原稳定题号,扩写原答案,新增缺少的主题;不宣称已逐字转存 945 题。原 PDF 保留用于溯源。 资料方向 合并位置与本轮处理 Ja…
宝典补充
这份文档对照 files/面试宝典/ 中新增的面试资料,与现有六份题库逐题去重后,补充 86 道此前缺少或只被顺带提到的题目。每题按“回答要点 → 原理拆解 → 示例与推演 → 易错点 → 参考回答”组织;本文的“宝典 1~86”对应网站稳定题号 baodian-1 ~ baod…
资料整理与纠错说明
files/面试宝典/ 共 249 个文件。真实简历 138 份含个人信息,训练营项目介绍 5 份属于课程宣传,均不作为题源; 2025学习资料(1).zip 与同名目录内容重复,课程大纲图片不含题目。其余 104 个 PDF 按文件内容哈希去重后剩 101 份,其中 5 份为纯…
JavaScript 语言深化
这一组补的是 JavaScript 分类里原先没有独立成题、面试又会单独追问的语言机制。闭包看 通用题 7 ,作用域与暂时性死区看 补充题 1 , == 与类型转换看 补充题 2 ,事件循环的总体模型看 通用题 10 ,模块格式差异看 宝典 1 ,V8 执行与回收看 宝典 3 。…