前端面试复习|03项目篇
前端面试复习项目篇涵盖实时通信 / ECharts / 地图 SDK / 工程化 / 项目难点话术 / 简历项目 QA复习时长建议1 周 目录实时通信WebSocket / WebRTC / MQTTECharts 数据可视化地图 SDK 与电子围栏前端工程化低代码 / 中后台脚手架Node.js / BFF项目难点话术STAR简历项目延伸 QA一、实时通信1.1 WebSocket为什么需要HTTP 是请求-响应模式服务器无法主动推送。WebSocket 是全双工长连接。constwsnewWebSocket(wss://api.com);ws.onopen()ws.send(hello);ws.onmessage(e)console.log(e.data);ws.onclose()reconnect();ws.onerror(){};生产级要点心跳定时发 ping30s 没收到 pong 就重连断线重连指数退避1s、2s、4s、8s…消息队列断线期间消息暂存重连后补发鉴权URL 带 token 或第一条消息发 auth完整封装classSocketClient{constructor(url){this.urlurl;this.reconnectTimes0;this.heartTimernull;this.connect();}connect(){this.wsnewWebSocket(this.url);this.ws.onopen(){this.reconnectTimes0;this.startHeartbeat();};this.ws.onclose()this.reconnect();}startHeartbeat(){this.heartTimersetInterval((){this.ws.send(JSON.stringify({type:ping}));},30000);}reconnect(){clearInterval(this.heartTimer);constdelayMath.min(1000*2**this.reconnectTimes,30000);setTimeout((){this.reconnectTimes;this.connect();},delay);}}1.2 WebRTC用途浏览器间 P2P 音视频传输1V1 通话、屏幕共享、实时直播。三大核心 APIAPI作用getUserMedia()获取摄像头/麦克风流RTCPeerConnection建立 P2P 连接RTCDataChannel任意数据通道信令流程A → 创建 Offer → 信令服务器 → B B → 创建 Answer → 信令服务器 → A A、B 互换 ICE Candidate → P2P 通道建立多路视频卡顿优化SFU 架构服务器转发不合流自适应码率关键帧请求PLI硬件解码1.3 MQTT为什么用 MQTT 而不用 WebSocket极轻量最小 2 字节头发布订阅模型适合海量设备支持 QoS0/1/2 三级遗嘱消息核心概念概念解释Broker消息中转服务器EMQX、MosquittoTopic主题如farm/cow1/temperatureQoS 0最多一次可能丢QoS 1至少一次可能重复QoS 2仅一次最可靠最慢importmqttfrommqtt;constclientmqtt.connect(wss://broker.com);client.subscribe(farm//temperature);// 单层通配client.on(message,(topic,payload){});client.publish(farm/cow1/cmd,feed);二、ECharts 数据可视化2.1 基础使用import*asechartsfromecharts;constchartecharts.init(document.getElementById(main));chart.setOption({xAxis:{type:category,data:[周一,周二]},yAxis:{type:value},series:[{type:bar,data:[120,200]}],});2.2 性能优化场景方案大数据1万appendData增量加载多图表共享主题 懒加载体积大按需引入resize 不灵监听 resize chart.resize()按需引入import*asechartsfromecharts/core;import{BarChart}fromecharts/charts;import{GridComponent,TooltipComponent}fromecharts/components;import{CanvasRenderer}fromecharts/renderers;echarts.use([BarChart,GridComponent,TooltipComponent,CanvasRenderer]);体积从 ~1MB 降到 ~200KB。2.3 常踩坑setOption默认合并要清空用chart.clear()数据切换时 series 数量变化要setOption(option, true)v-if 销毁后要重新 init容器宽高为 0 时初始化失败2.4 Vue3 封装template div refchartRef :style{ width, height }/div /template script setup import { ref, onMounted, onBeforeUnmount, watch } from vue; import * as echarts from echarts; const props defineProps([option, width, height]); const chartRef ref(); let chart null; onMounted(() { chart echarts.init(chartRef.value); chart.setOption(props.option); window.addEventListener(resize, () chart.resize()); }); watch(() props.option, (val) chart?.setOption(val), { deep: true }); onBeforeUnmount(() { chart?.dispose(); }); /script2.5 大屏适配.bigscreen{width:1920px;height:1080px;transform:scale(var(--scale));transform-origin:left top;}functionsetScale(){constscaleMath.min(window.innerWidth/1920,window.innerHeight/1080);document.documentElement.style.setProperty(--scale,scale);}window.addEventListener(resize,setScale);2.6 主题定制echarts.registerTheme(myDark,{color:[#5470c6,#91cc75],backgroundColor:#1a1a2e,textStyle:{color:#fff},});echarts.init(dom,myDark);三、地图 SDK 与电子围栏3.1 高德 vs 腾讯高德腾讯国内数据★★★★★★★★★海外★★★文档优秀一般3.2 核心能力constmapnewAMap.Map(container,{zoom:11,center:[116.4,39.9]});// 标记newAMap.Marker({position:[lng,lat],map});// 路径规划newAMap.Driving().search([from,to],(status,result){});// 地理编码newAMap.Geocoder().getLocation(address,callback);// 电子围栏判定AMap.GeometryUtil.isPointInRing([lng,lat],polygonPath);3.3 电子围栏是什么在地图上画一个虚拟圈判断设备/用户进入或离开 → 触发动作。业务流程商家用MouseTool.polygon()绘制多边形后端持久化围栏数据用户下单 → 取地址坐标 → 用isPointInRing判断完整代码// 1. 商家绘制constmouseToolnewAMap.MouseTool(map);mouseTool.polygon({fillColor:#1791fc,strokeColor:#1791fc,});mouseTool.on(draw,(event){constpathevent.obj.getPath();constcoordspath.map(p[p.lng,p.lat]);saveToBackend(coords);});// 2. 用户下单判定constisInsideAMap.GeometryUtil.isPointInRing([userLng,userLat],polygonPath);if(!isInside)alert(超出服务范围);坐标系坑坐标系用于WGS84GPS 原始GCJ02高德、腾讯火星坐标BD09百度后端拿到 GPS 坐标要先转 GCJ02 再画到高德地图否则偏移几百米。应用场景外卖配送范围共享单车运营区/禁停区门店服务范围上门取件车辆调度儿童老人定位手表四、前端工程化4.1 模块化历史CommonJSNode→ AMD/CMD已弃→ ES Module// CommonJSconstfsrequire(fs);module.exports{};// ESMimportfsfromfs;exportdefault{};4.2 代码规范# ESLint代码错误# Prettier代码格式# HuskyGit hooks# lint-staged只检查暂存区# Commitlintcommit 规范.husky/pre-commitnpx lint-staged4.3 Git 协作命令用途git rebase -i合并/修改历史 commitgit cherry-pick挑某个 commitgit stash暂存当前修改git reset --soft/--hard软/硬重置git revert反向 commitGit Flowmaster ←─ release ←─ develop ←─ feature/xxx ←─ hotfix/xxx4.4 Monorepo工具pnpm workspace、Turborepo、Nx、Lerna好处多包共享依赖、统一版本、原子提交4.5 CI/CD 流程name:Deployon:push:branches:[main]jobs:build:runs-on:ubuntu-lateststeps:-uses:actions/checkoutv3-uses:actions/setup-nodev3with:node-version:18-run:pnpm install-run:pnpm lint-run:pnpm test-run:pnpm build-name:Deployrun:rsync-avz dist/ userserver:/var/www/五、低代码 / 中后台脚手架5.1 表单生成器Schema 驱动constschema[{type:input,field:username,label:用户名,rules:[{required:true,message:必填}],},{type:select,field:role,label:角色,options:[{label:管理员,value:admin}],},];functionrenderForm(schema){returnschema.map(item{switch(item.type){caseinput:returnh(ElInput,{...});caseselect:returnh(ElSelect,{...});}});}5.2 RBAC 权限设计用户 ─── 多对多 ─── 角色 ─── 多对多 ─── 权限前端三层权限路由级动态注册可访问路由菜单级根据权限渲染菜单按钮级自定义指令v-permissionuser:deleteconstpermission{mounted(el,binding){const{value}binding;constuserPermsuseUserStore().perms;if(!userPerms.includes(value)){el.parentNode?.removeChild(el);}},};5.3 多租户模式隔离复杂度独立数据库完全高共享库独立 schema中中共享库共享表tenant_id低低前端要点登录确定租户 请求带X-Tenant-Id头 子域名区分。六、Node.js / BFF6.1 事件循环与浏览器差异Node.js Event Loop 6 个阶段 timers → pending → idle → poll → check → close与浏览器差异Node 11.x 微任务穿插在每个阶段和浏览器一致多了setImmediate、process.nextTickprocess.nextTick优先级最高6.2 Buffer / StreamconstbufBuffer.from(hello);console.log(buf.toString(hex));fs.createReadStream(big.txt).pipe(fs.createWriteStream(copy.txt));4 种流Readable / Writable / Duplex / Transform6.3 Express 中间件constappexpress();app.use((req,res,next){console.log(日志);next();});app.get(/users,(req,res)res.json([]));app.listen(3000);Koa 洋葱模型请求 → mw1 前 → mw2 前 → 处理 → mw2 后 → mw1 后 → 响应6.4 BFFBackend For Frontendapp.get(/api/dashboard,async(req,res){const[user,orders,stats]awaitPromise.all([fetch(/user-service/info).then(rr.json()),fetch(/order-service/recent).then(rr.json()),fetch(/stat-service/today).then(rr.json()),]);res.json({user,orders,stats});});6.5 npm 包发布npminitnpmloginnpmpublishnpmversion patch# 1.0.0 → 1.0.1npmversion minor# 1.0.0 → 1.1.0npmversion major# 1.0.0 → 2.0.0七、项目难点话术STAR7.1 STAR 法则SSituation业务背景TTask你要解决什么AAction你做了什么技术细节RResult结果有数字7.2 难点 1多端架构统一场景云护项目要同时支持 Web 后台 小程序 公众号 H5问题三端代码大量重复方案抽象业务层API、Store、工具函数成 npm 包UI 层用 uni-app 条件编译适配差异结果跨端复用率 70%新功能开发效率提升 40%7.3 难点 2长列表性能优化场景监控页面要展示 1000 设备实时状态问题直接渲染浏览器卡死方案虚拟滚动el-table-v2 requestAnimationFrame 节流 Web Worker 处理数据结果FPS 从 25 提升到稳定 60内存占用降低 60%7.4 难点 3首屏加载优化场景长慈系统首屏 4.2s 用户投诉排查Lighthouse Performance 面板定位发现 ECharts 全量引入 图表组件同步加载方案路由懒加载 ECharts 按需引入 Gzip 关键 CSS 内联结果首屏 4.2s → 1.3sLighthouse 58 → 927.5 难点 4WebRTC 多路视频卡顿场景云护值守端要同屏看 16 路 1080P 视频问题客户端 CPU 跑满方案协商时降低非焦点画面分辨率动态码率 启用硬件解码 滚动可视区外暂停解码结果CPU 占用降低 50%16 路同屏稳定运行7.6 难点 5MQTT 长连接稳定性场景牛轻松 App 在弱网环境下 MQTT 频繁断连方案心跳间隔动态调整弱网延长 指数退避重连 断线期间消息本地暂存 QoS 1结果弱网下指令到达率从 78% 提升到 99.5%八、简历项目延伸 QA8.1 通用追问 10 个角度每个项目准备这 10 个角度业务背景to B 还是 to C多少用户你的角色独立做的团队几个人技术选型理由为什么用 Vue3 不用 React架构设计项目目录结构模块划分难点最大技术挑战数据提升数据怎么测的工具协作和后端/UI 怎么协作上线怎么发布灰度回滚复盘如果重做你会怎么改延伸最自豪的一行代码/设计8.2 高频问题Q为什么用 Vue3 不用 React三个角度团队成本团队 Vue 经验更多React Hooks 学习曲线对部分成员陡峭生态匹配项目用了大量 Element-Plus 组件Vue 生态更顺维护成本Vue 双向绑定和模板语法对业务开发者更直观高交互复杂应用Figma 这种React 类型系统可能更适合。Q为什么用 uni-app 不用 Taro团队是 Vue 技术栈uni-app 0 学习成本。Taro 虽然 React 写法更现代但需要培训。项目主要面向小程序和 Appuni-app 微信生态适配更成熟。QWebRTC 你做到什么深度业务层完整对接信令、SDP 协商、ICE 流程优化层处理过多路视频卡顿底层原理理解 STUN/TURN/ICE不擅长底层协议修改、自研信令服务器团队有专人诚实地标记自己的边界。Q项目的并发上限前端1000 表格行 10 路视频流 实时数据推送时仍能保持 60FPS后端单接口 QPS 在 2000 左右团队压测报告Q项目的代码量我主导的项目代码量约 X 万行cloc 统计X 个核心模块X 个通用组件我个人贡献者占 70%本篇完。下一篇04-软实力篇