项目难点及解决方案
难点一:内网摄像头 RTSP 视频流 → 公网网页播放(MMMP 项目)
基础认知(先讲背景):工地的摄像头输出的是 RTSP 协议(类似原始视频流快递),但网页浏览器只认识 WebRTC 或 HLS(类似京东/顺丰快递)。RTSP 没法被网页直接
video标签播放。而且摄像头都在内网(没有公网IP),外网根本访问不到。技术痛点(难在哪):
- 协议转换:怎么把 RTSP “翻译” 成 WebRTC?
- 网络穿透:没有公网IP,怎么让外网的电脑看到内网的摄像头画面?
- 延迟要求:工地监控要求延迟低于 1 秒,不能卡顿。
你的解决方案(全面拆解):
- 协议转换层:后端部署
mediamtx(以前叫 RTSPtoWebRTC)服务,把 RTSP 流转成 WebRTC 流,前端直接用video标签配合RTCPeerConnection拉流。 - 内网穿透核心:采用 STUN + TURN 双打洞策略。优先让浏览器通过 STUN 服务器尝试“打洞”建立 P2P 直连(零成本、低延迟);如果遇到对称型 NAT(打不通),自动降级走 TURN 服务器转发流量(相当于架了个桥梁)。同时,配合 frp(内网穿透工具) 将内网的信令服务映射到公网。
- 前端优雅降级:封装一层
WebRTCPlayer,如果检测到 WebRTC 连接失败,自动切换为 HLS(http-flv)备选方案(牺牲 2-3 秒延迟保证画面可用)。
- 协议转换层:后端部署
量化结果:打洞成功率达 92%,端到端延迟控制在 300ms-500ms。工地远程监管从“跑现场看”变成“看大屏管”,异常响应从小时级缩短至秒级。
面试现场话术(直接背):
“这个项目最大的坑是网络环境不可控。工地内网防火墙策略五花八门。我没有死磕 WebRTC,而是设计了‘双轨制’:优先 STUN 打洞追求低延迟,失败立刻切 TURN 中转保底。前端通过
RTCPeerConnection的oniceconnectionstatechange事件监听连接状态,一旦掉线立即重连。这让我们的监控平台在全国 50 多个工地稳定运行。”
难点二:华为 WeLink 百万日活 IM —— 消息列表渲染卡顿(WeLink 项目)
基础认知(先讲背景):WeLink 类似企业微信,一个群聊可能有上万条消息。React 每次收到新消息都要重新渲染整个列表,如果全量渲染,页面直接卡死。
技术痛点(难在哪):
- 海量 DOM 节点:即使只显示最近的 100 条,DOM 节点数也很多。
- 高频更新:百万日活下,消息每秒几十条涌入,频繁
setState会导致 React 不断协调(Reconciliation)。 - Electron 内存敏感:桌面端内存不如浏览器充裕,闭包和事件监听稍有不慎就内存泄漏导致闪退。
你的解决方案(全面拆解):
- 虚拟滚动(核心武器):引入
react-window或react-virtualized,只渲染视口能看到的 10-15 条消息,上下滚动时动态替换,DOM 数量始终恒定。 - 状态管理优化(Redux 精髓):使用
reselect(记忆化选择器),对消息列表做filter或sort前,先判断数据引用是否变化。只有新消息的messageId真正插入时,才返回新数组;否则直接返回旧数组,阻止 React 重新渲染。 - 消息合并更新(防抖):利用
setTimeout或requestIdleCallback做写合并——收到消息先塞入缓冲区,每 100ms 批量更新一次 Redux(而非来一条更新一次)。 - 内存释放(针对 Electron):监听 React 组件的
componentWillUnmount,主动将监听事件removeListener,并将大图片src置空,配合global.gc()(开发环境验证)确保回收。
- 虚拟滚动(核心武器):引入
量化结果:长列表滚动帧率从 35fps 提升至 58fps,内存占用稳定在 150MB 以内,支撑 500 人超大群聊无卡顿。
面试现场话术(直接背):
“我在 WeLink 做消息模块时,性能是头号难题。我用了‘虚拟列表 + 数据不可变 + 批量更新’三把斧。特别是 Redux 的
reselect极其关键——它能缓存计算结果,哪怕几百条消息轮询更新,只要 IDs 没变,组件就不重绘。配合React.memo包裹单条消息,将重绘粒度细化到‘只重绘刚发的那一条’。”
难点三:IAMP 隧道检测 —— 百万级激光雷达点云在浏览器流畅渲染(IAMP 项目)
基础认知(先讲背景):隧道检测车用激光雷达扫描隧道内壁,生成上百万个带有 XYZ 坐标和反射强度的点。要在 Web 端把隧道病害(裂缝、掉块)精准显示出来。
技术痛点(难在哪):
- 显卡(GPU)内存瓶颈:一百万个点直接扔给 Three.js,显存瞬间爆炸,浏览器直接崩溃。
- 主线程阻塞:解析二进制的点云数据(.las/.pcd 格式)如果用 JS 在主线程解析,页面会卡死 5-6 秒。
- 渲染开销大:即使渲染出来,鼠标拖拽旋转时,CPU 要重新计算所有点的位置,极易掉帧。
你的解决方案(全面拆解):
- 分块加载(Chunked Loading):不一次性加载全部点云。将隧道按里程桩号切分成 10 米一段,默认只加载当前视口所在的 3 段。滚动时采用 “预加载 + 销毁” 策略(提前加载下一段,远离的立即
dispose释放显存)。 - Web Worker 异步解析:点云二进制数据解析放在 Worker 线程。Worker 解析完生成
Float32Array传给主线程,主线程直接塞进BufferAttribute,完全不影响 UI 交互。 - LOD(层次细节)技术:根据相机距离动态控制点的密度——离得近显示全部点(厘米级精度),离得远自动抽稀(每 5 个点取 1 个),用
three.js的PointsMaterial配合size attenuation(尺寸衰减)。 - 自定义着色器优化:弃用标准的
PointsMaterial,手写 Shader 只传位置和颜色,用gl_PointSize在顶点着色器里控制点大小,大幅减少 CPU 计算。
- 分块加载(Chunked Loading):不一次性加载全部点云。将隧道按里程桩号切分成 10 米一段,默认只加载当前视口所在的 3 段。滚动时采用 “预加载 + 销毁” 策略(提前加载下一段,远离的立即
量化结果:支持 120 万 个点流畅渲染(60fps),内存占用降低 60%,病害定位精度达 厘米级。
面试现场话术(直接背):
“Three.js 渲染点云,核心痛点是显卡扛不住。我的解法是‘分而治之’:把 120 万点按空间切成小块,只让显卡渲染眼前的那部分。同时把最耗时的数据解析扔给 Worker 线程,主线程只管渲染。这就好比看地图——你不可能一次性加载整个世界,而是随着缩放动态加载瓦片。”
难点四:IRMP 报告生成 —— 大文件 PDF 生成与幂等防重提交(IRMP 项目)
基础认知(先讲背景):检测完隧道,系统要自动生成一份 50-100 页的 PDF 检测报告(含图表、病害列表、曲线图)。原来人工整理要 2-3 周。
技术痛点(难在哪):
- 生成耗时长:后端合成 PDF 可能需要 20-30 秒,HTTP 请求极易超时断开。
- 重复提交风暴:用户等了 10 秒没反应,疯狂点“生成”按钮,后端瞬间收到 20 个请求,服务器 CPU 飙满,生成出 20 份一模一样无效报告。
- 用户等待体验差:界面一直转圈,用户不知道进度。
你的解决方案(全面拆解):
- 幂等键(Idempotent-Key)设计(核心技术):前端每次点击生成时,根据
任务ID + 时间戳生成唯一字符串,存入请求头Idempotent-Key。后端维护 Redis 缓存,如果 5 秒内收到相同 Key,直接返回“处理中”,拒绝重复执行。 - 异步任务队列 + WebSocket 进度推送:点击生成后,后端立即返回
taskId,状态为PENDING。前端用 WebSocket 或轮询监听进度(processing... 30%)。PDF 生成完毕,后端把文件上传 OSS 并推送给前端 URL。 - 前端兜底策略(防抖 + 状态锁):虽然后端有幂等,前端依然做防抖(
debounce 500ms)。点击后按钮置灰,文案变为“生成中,预计 20s...”,配合进度条,彻底杜绝重复点击。 - PDF 模板前后端协作:不把大量数据传给后端,而是前端用
html2canvas+jspdf先在浏览器生成基础图表,压缩成 Base64 传给后端填入模板,减轻后端渲染压力。
- 幂等键(Idempotent-Key)设计(核心技术):前端每次点击生成时,根据
量化结果:重复报告提交率降为 0,报告交付周期从 2-3 周 降至 1-2 天。
面试现场话术(直接背):
“PDF 生成的痛点不是‘能不能生成’,而是‘在高并发下怎么稳定生成且不重复’。我从阿里云的 API 设计得到启发,引入了‘幂等键’机制。前端生成唯一的
Idempotent-Key,后端以此做天然屏障——哪怕用户把鼠标点烂,后端也只处理一次。同时用 WebSocket 实时推送进度,用户不用干等,体验非常好。”
面试时回答“难点”的万能公式(务必按这个结构说)
- 背景(1句话):在 IAMP 项目中,我需要处理百万级点云渲染。
- 难点(2-3句话):主要瓶颈在于浏览器 GPU 显存有限,且数据解析耗时久,直接加载会导致页面卡死或崩溃。
- 行动(核心、分点说):我采取了三个措施,第一,Web Worker 异步解析;第二,分块加载 + LOD 控制渲染数量;第三,自定义 Shader 减少 CPU 开销。
- 结果(数据量化):最终做到了 120 万点 60fps 流畅渲染,病害定位精度达厘米级。