某银行前端面试题整理
第一批(第 1–17 题)
1. axios 如何区分 Node 环境和浏览器环境?
axios 采用“适配器”模式:请求时检测环境选择适配器,浏览器检测 XMLHttpRequest/fetch,Node 检测 http/https,常见写法是 typeof XMLHttpRequest !== 'undefined' 或 process?.versions?.node,也支持手动传 adapter。
2. 浏览器的存储有哪些?
Cookie、localStorage、sessionStorage、IndexedDB、Cache Storage、WebSQL(废弃)、File System Access API 等。小数据用 storage,大结构数据用 IndexedDB,认证用 Cookie,离线资源用 Cache Storage。
3. 常见登录鉴权方式有哪些?
Session-Cookie、JWT/Token、OAuth 2.0/OIDC、SSO(CAS/SAML)、短信/邮箱验证码(OTP)、扫码登录、Magic Link 等。前端常用 Token + 刷新令牌 + 路由守卫 + 请求拦截器。
4. Git 仓库迁移怎么操作?
git clone --bare 旧仓库 → 在新平台建空仓库 → git push --mirror 新地址 推送所有分支标签 → 更新本地 remote set-url origin → 迁移 CI/CD、Webhook、分支保护、权限配置,最后验证 clone 和构建。
5. ESLint 代码检查的过程是什么?
读取配置 → 解析器把源码解析成 AST → 按规则遍历 AST 静态检查 → 收集违规项,可自动修复的修复 → 按 formatter 输出报告。整个过程不执行代码。
6. 应用上线后如何通知用户刷新页面?
版本轮询:请求 version.json 或读取打包 buildId,不一致时弹“有新版本,点击刷新”;或用 WebSocket/SSE 推送;PWA 场景监听 updatefound/controllerchange 提示刷新。
7. 你用过哪些 TS 特性?
类型注解与接口、泛型及约束、联合/交叉类型、字面量类型、类型收窄、as const、工具类型(Partial/Pick/Omit/Record/ReturnType)、枚举、type guard、可选链、模块化类型导入等。
8. 如何一次性渲染十万条数据不卡顿?
首选虚拟滚动,只渲染可视区域;再配合分页、requestIdleCallback 分批渲染、documentFragment 批量插入、Canvas 绘制、Web Worker 处理数据。
9. git pull 和 git fetch 的区别?
git fetch 只下载远程提交和引用,不改工作区;git pull = fetch + merge/rebase,会直接更新工作区。
10. 用户访问白屏的原因和排查方法?
原因:JS 报错、入口资源 404、路由没匹配、chunk 加载失败、CSP/跨域拦截、302 跳转、浏览器兼容等。排查:Network 看状态码、Console 看报错、Elements 看根节点、Source 断点定位、配合 sourcemap 和 performance 分析。
11. 前端有哪些跨页面通信方式?
postMessage、BroadcastChannel、localStorage/sessionStorage 事件、SharedWorker、IndexedDB、WebSocket/SSE、window.opener、MessageChannel。
12. 你用过哪些 Webpack Plugin?
HtmlWebpackPlugin 生成 HTML 注入 bundle;MiniCssExtractPlugin 提取 CSS;CleanWebpackPlugin 清空 dist;DefinePlugin 注入环境变量;CopyWebpackPlugin 复制静态资源;TerserPlugin 压缩 JS;CompressionPlugin 生成 gzip;BundleAnalyzerPlugin 分析体积;ESLintPlugin/ForkTsCheckerWebpackPlugin 检查代码;HotModuleReplacementPlugin 热更新。
13. 组件封装的基本准则是什么?
单一职责、props 少而稳定、默认值合理、支持受控/非受控、事件向上抛、用插槽/组合代替堆配置、状态最小化、避免过度封装、可测试可访问、有文档。
14. 常见登录鉴权方式?
同上第 3 题。
15. 为什么 Vite 比 Webpack 快?
Vite 开发时基于原生 ESM,启动几乎不打包、按需编译单个文件;依赖用 esbuild 预构建(Go 编写);文件改动只重编当前模块,配合强缓存,冷启动和热更新都快。生产构建 Vite 用 Rollup。
16. 十万条数据渲染?
同上第 8 题。
17. V8 里面的 JT 是什么?
指 JIT,Just-In-Time 即时编译。V8 先用解释器 Ignition 快速执行并收集运行信息,热点函数再由 TurboFan 编译成优化机器码;假设不成立会反优化回解释器。
第二批(第 18–32 题)
18. 介绍 requestIdleCallback API?
浏览器在空闲时段调用回调,适合低优先级任务(上报、分片处理)。用 deadline.timeRemaining() 判断剩余时间,可传 timeout 兜底;不兼容时用 setTimeout/rAF 回退,任务要做切片避免一次执行过久。
19. 电梯导航(滚动跟随导航)如何实现?
侧边固定目录点击锚点 scrollIntoView/scrollTo 滚动;滚动时用 getBoundingClientRect() 或 IntersectionObserver 判断当前区块,高亮对应项;注意节流、顶部 header 偏移、平滑滚动。
20. 移动端下拉滚动加载(顶部加载)如何实现?
监听 touchstart/touchmove/touchend,页面在顶部且下拉超过阈值时显示“下拉/释放刷新”,松手后重新请求并插入顶部数据;也可用 pulltorefresh.js、better-scroll、Vant PullRefresh。请求期间锁定状态,完成后再收起。
21. 页面关闭时如何执行方法?
优先 pagehide,兼容用 beforeunload;要可靠上报用 navigator.sendBeacon() 或 fetch(..., {keepalive: true}),普通 XHR 可能被中断;移动端后台切换用 visibilitychange 判断。
22. 如何还原用户操作流程?
埋点记录点击、输入、路由、滚动、请求并按时间轴存储;用 rrweb 做 DOM 快照 + 增量录制回放;保存请求参数和响应做请求重放;撤销/恢复用命令模式或事件溯源压栈。
23. 如何把请求的调用源码地址和行号上报?
在请求封装处捕获 new Error().stack 或 Error.captureStackTrace;生产环境上传 sourcemap,用 source-map 库还原压缩代码到源码位置;Sentry 等平台原生支持,注意限制 stack 层数。
24. 批量请求失败如何只弹一个 Toast?
在统一请求封装里做聚合去重:按错误消息维护 Map,相同消息在时间窗口内只弹一次;或对一批并发请求做 debounce,结束后汇总成“N 个请求失败”;用单例 Toast 管理器替换而不是堆叠。
25. 如何减少项目里的 if-else?
提前 return、用 Map/对象表替代分支、策略模式、多态、配置化/规则引擎、空对象模式、可选链 ?. 和空值合并 ??。核心是把分支变成数据或对象。
26. babel-runtime 的作用?
提供 Babel 转换产物的公共辅助函数(_extends、regenerator runtime 等)和部分 core-js polyfill,配合 @babel/plugin-transform-runtime 按需引入,避免每个文件重复内联辅助代码、不污染全局,减小体积。
27. 如何实现 PDF 预览?
简单场景用 <iframe>/<embed>/<object> 或 window.open();自定义场景用 PDF.js(pdfjs-dist)渲染到 canvas,生态库有 vue-pdf、react-pdf;跨域文件先转 Blob,大文件只渲染当前页。
28. 如何在划词选择的文本上添加右键菜单?
监听 mouseup/selectionchange 获取 window.getSelection(),用 range.getBoundingClientRect() 定位;监听 contextmenu 阻止默认菜单并渲染自定义菜单;点击其他区域或滚动时隐藏。
29. 富文本里如何实现划词?
和普通页面一样用 window.getSelection() 拿 Range,在 contenteditable 里保存选区;高亮/标注用 document.execCommand() 或包裹 <span>/<mark>;持久化用字符偏移或 DOM 序列化,编辑后重算位置。
30. px 如何转 rem?
rem = px / html 根字号。移动端用 postcss-pxtorem 自动转换,根字号由 amfe-flexible 按 clientWidth 动态设置,如 html { font-size: clientWidth / 10 };1px 边框等可保留 px。
31. 如何做好前端监控方案?
稳定性:window.onerror、unhandledrejection、资源错误 + sourcemap;性能:Web Vitals + Performance API;行为:PV/UV、路由、点击、业务漏斗;网络:成功率、耗时、错误码;批量 + sendBeacon 上报,配套告警和大盘,可直接用 Sentry/ARMS 或自建。
32. 如何标准化处理线上用户反馈?
统一反馈入口(应用内/工单/IM)→ 结构化模板(版本、设备、浏览器、时间、路由、复现步骤、截图、日志)→ 去重聚合 → 严重级别分级 → 复现定位 → 修复发布 → 反馈用户 → 沉淀知识库,联动监控和发布变更记录。
第三批(第 1–19 题)
1. 性能指标 FCP/LCP/FP 的 Chrome 标准?
FCP ≤ 1.8s,LCP ≤ 2.5s,CLS ≤ 0.1,INP ≤ 200ms;FP 没有硬性标准,尽量接近 FCP;另可看 TTFB ≤ 0.8s。
2. Lighthouse 怎么打分?
满分 100,性能权重:LCP 25%、TBT 30%、CLS 25%、FCP 10%、Speed Index 10%。绿色 ≥ 90,橙色 50–89,红色 < 50。
3. Sentry 怎么上传 sourcemap?
用 @sentry/webpack-plugin 配置 authToken/org/project/release/include;或用 sentry-cli sourcemaps upload;SDK 里 release 必须一致;上线后不要把 sourcemap 公开,避免源码泄露。
4. 性能具体优化了哪些?
构建层:代码分割、tree-shaking、压缩、CDN;网络层:缓存、gzip/brotli、preload/prefetch、懒加载;资源层:图片压缩/WebP/懒加载;运行层:虚拟滚动、防抖节流、减少重排、Web Worker、SSR/骨架屏。
5. Web Worker 的使用场景?
CPU 密集计算(图片处理、加密、哈希、排序过滤)、大文件分片 hash 计算、OffscreenCanvas 渲染、代码解析/编译、实时数据处理。不能操作 DOM。
6. WebP 跨端兼容怎么处理?
用 <picture> + <source type="image/webp"> 和 <img> 回退;运行时用 canvas.toDataURL('image/webp') 检测支持;CDN 按 Accept 头切图;不支持的环境降级 PNG/JPEG。
7. Jenkins 切换分支怎么配置?
安装 Git Parameter 插件,流水线参数化 BRANCH,用 checkout([$class: 'GitSCM', branches: [[name: "${params.BRANCH}"]]]);或 Git SCM 配 “Branches to build” 为 ${BRANCH},配合分支 webhook;构建前 clean workspace。
8. SSO 跳转流程?Cookie 可以跨域吗?
子系统未登录 → 跳 SSO 登录页带 service/callback → SSO 登录写统一域 Cookie → 用 ticket/code 跳回子系统 → 子系统校验后建本地会话。Cookie 默认不能跨域名,跨域靠统一认证 + ticket/redirect,或 token + iframe/postMessage/网关同域方案。
9. Canvas 渲染 10 万数据?Canvas 和 SVG 区别?
Canvas 是位图、只有画布一个 DOM,适合海量数据,配合可视区裁剪和滚动重绘;SVG 每个元素都是 DOM,适合几千以内、需要缩放和事件交互的场景。海量选 Canvas,交互精细选 SVG。
10. pnpm 对比 npm 的优势?公共组件更新怎么做?
pnpm 用全局内容寻址存储 + 硬链接,安装快、省磁盘、多项目共享;符号链接式 node_modules 避免幽灵依赖。公共组件用语义化版本 + changelog,monorepo 用 workspace:* 本地联调,changesets 统一发版,升级大版本看 breaking changes。
11. qiankun 的 JS 和 CSS 隔离原理?
JS:现代浏览器用 Proxy 给子应用创建 window 沙箱,读写隔离;旧浏览器用快照 diff 后还原。CSS:默认动态插入/卸载样式,切换应用时清理;严格模式用 Shadow DOM,或构建时给选择器加应用前缀。
12. 改变主题色功能的思路和持久化?
用 CSS 变量 --primary,切换时 document.documentElement.style.setProperty() 或改 data-theme;组件库 token 映射到变量;持久化存 localStorage,storage 事件跨标签页同步,首次进入读取存储或系统主题。
13. 浏览器缓存的区别?IndexedDB 缓存?
memory cache 会话内最快;disk cache 持久,受 Cache-Control/ETag 控制;Service Worker Cache Storage 是应用可控的 HTTP 缓存;IndexedDB 是浏览器数据库,适合大量结构化数据、离线数据、大文件分片,不是 HTTP 缓存。
14. 浏览器缓存了 JS/包产物怎么解决?
文件名加 contenthash,HTML 用新引用;index.html 设 Cache-Control: no-cache;CDN 静态资源按版本目录发布;Service Worker 版本化并清理旧缓存;必要时版本轮询提示用户刷新。
15. SharedWorker 和 postMessage 的区别?
postMessage 是页面间直接通信,消息结构化克隆,简单、支持跨源指定 targetOrigin,但无共享状态;SharedWorker 是所有标签页共享的后台线程,可维护公共状态和统一分发,但兼容性和生命周期管理更复杂。
16. 大文件上传的并发、切片、缓存、断网续传、进度条?
File.slice 切分片 → 计算文件 hash → 控制 3–5 个并发 → 上传前询问服务端已有分片并跳过 → 分片状态和进度存 IndexedDB/localStorage 实现续传 → 进度 = 已传字节/总字节 → 失败重试,全部完成后服务端合并。
17. 可视区渲染逻辑?
根据 scrollTop 和行高算出 startIndex,只渲染 start ~ start + 可视行数 + buffer;外层用总高度占位保持滚动条;滚动用 rAF/节流重算;动态高度要缓存每项真实高度并用累计偏移定位。
18. 怎么请求 10 万数据?
不要一次拉全量:分页/游标 + 无限滚动;确实需要全量时分片并发请求或流式响应边收边处理;数据处理放 Worker,渲染用虚拟滚动,避免主线程阻塞。
19. 算法:队列方式将树表平铺?
BFS 层序遍历:根节点入队,弹出即加入结果,再把 children 入队;表格用 parentId/level/expanded 标记层级并缩进展示。
function flattenTree(root) {
const result = [], queue = [...root];
while (queue.length) {
const node = queue.shift();
result.push(node);
if (node.children?.length) queue.push(...node.children);}
return result;}
第四批(第 1–17 题,与上一条相同,并入合集)
1. 怎么在前端页面中添加水印?
canvas 绘制含用户信息的重复水印转 dataURL,作为 position: fixed、pointer-events: none、高 z-index 覆盖层的背景;也可用 repeating-linear-gradient 实现简单水印。
2. 如何封装请求,多次调用只发起一次并返回同一份结果?
单飞模式:以 url + 参数 为 key 缓存 Promise,相同请求返回同一个 Promise,完成后删除:
const pending = new Map();
function request(key, fn) {
if (!pending.has(key)) {
pending.set(key, fn().finally(() => pending.delete(key)));}
return pending.get(key);} 3. 如何禁止别人移除水印?
无法绝对禁止。用 MutationObserver 监听删除/修改后自动重建、高 z-index 覆盖、水印带用户标识可溯源、图片视频服务端加水印。任何纯前端方案都能被绕过。
4. React 下拉菜单点击区域外关闭?
ref 包住组件,document 监听 mousedown,目标不在 ref 内就关闭;同时支持 Escape;下拉用 Portal 避免被裁剪。
5. 如何搭建灰度系统?
网关/LB 按 Header、Cookie、参数、用户分组或百分比切流量;前端 Feature Flag 控制功能;用户按 user_id % 100 或白名单稳定分流;配指标对比、自动回滚、逐步放量。
6. React 如何实现 keep-alive?
没有内置方案:用 react-activation;或组件不卸载、切换时 display: none 保留 state;或状态提升到 Redux/Zustand 持久化。
7. 如何监控页面崩溃?
页面定时更新心跳时间戳,另一个标签页/SharedWorker 检测心跳超时且没触发 pagehide/beforeunload 即判定崩溃,用 sendBeacon 上报;配合 onerror/unhandledrejection 区分错误类型。
8. 如何快速落地代码规范?
共享 ESLint/Prettier/Stylelint/commitlint + husky,CI 卡 lint,脚手架一键生成合规项目,存量代码增量迁移,配文档和评审 checklist,骨干试点再推广。
9. 前端如何实现即时通讯?
主用 WebSocket,服务端单向推送用 SSE,兜底轮询/长轮询;处理心跳、断线重连、消息确认重发、离线消息、消息顺序、未读数和文件上传;可自研或接入 Socket.io、腾讯云 IM 等。
10. 白屏原因与排查?
同第一批第 10 题。
11. 大型项目单元测试怎么设计?
测试金字塔:纯逻辑/工具/状态做单测,组件用 Testing Library 测行为,核心链路用 Playwright/Cypress 做 E2E;优先覆盖高风险公共模块;测试数据用工厂函数、不依赖网络;CI 并行,关键模块定覆盖率,快照少用。
12. 前端自动化部署的规范和流程?
lint/test → build → 不可变版本产物 → 测试环境 → 验收 → 灰度 → 生产 → 健康检查 → 告警。配套分支保护、语义化版本、配置与代码分离、密钥放 Secrets、产物可回滚、发布通知。
13. 你参与过哪些前端基建?
脚手架与统一构建、规范包、组件库/设计系统、请求层与错误上报 SDK、Mock 平台、CI/CD、监控告警、微前端落地、开发体验优化、统一文档站等,按实际经历说明内容和产出。
14. 商城商品点击量如何设计?
前端 SDK 采集 productId/userId/sessionId/时间/来源/渠道,sendBeacon 或批量上报;服务端进消息队列削峰,实时算 PV/UV 去重,离线算趋势,结果存 Redis/ClickHouse;加频率限制和设备指纹防刷。
15. 前端怎么做错误监控?
捕获 window.onerror、unhandledrejection、资源 error;React ErrorBoundary、Vue errorHandler;带上堆栈、版本、浏览器、用户信息,sourcemap 还原,批量 + sendBeacon 上报,可直接用 Sentry。
16. Token 过期如何无感刷新?
401 时把请求放进待重试队列,用 refresh_token 单飞刷新一次,成功后更新 token 并重放队列;刷新失败才跳登录;多标签页用 storage 事件同步 token。
17. 如何解决接口大规模并发?
并发池控制同时请求数;相同请求缓存/去重;高频接口批量合并;AbortController 取消过期请求;按优先级排队;服务端分页、限流、CDN 缓存兜底。
