面试题手册

梳理高频技术问题,帮助你按主题复习和查漏补缺。

服务端阅读 05月29日 22:54

WebRTC 如何控制音视频质量?码率/分辨率/帧率的动态调节策略是什么?

WebRTC 如何控制音视频质量?码率/分辨率/帧率的动态调节策略是什么?WebRTC 通过 GCC(Google Congest Control) 算法自动估算带宽,动态调节编码参数,核心机制:自动调节:带宽探测:发送端逐步增加码率,检测丢包率上升则回退(AIMD 策略)编码器适配:VP8/VP9/H264 编码器根据目标码率自动调整量化参数帧率调节:带宽不足时降低帧率优先保分辨率,极低带宽才降分辨率手动控制 API:const sender = pc.getSenders()[0];const params = sender.getParameters();params.encodings[0].maxBitrate = 500000; // 500kbpsparams.encodings[0].maxFramerate = 15;params.encodings[0].scaleResolutionDownBy = 2; // 分辨率减半sender.setParameters(params);音频处理:NetEQ:抖动缓冲 + PLC(丢包隐藏),平滑播放AEC:回声消除,防止扬声器声音被麦克风拾取NS/ANR:噪声抑制,过滤背景噪声AGC:自动增益控制,稳定音量视频处理:关键帧请求(PLI/FIR)应对丢包,Simulcast 发多路流供 SFU 选择。追问Simulcast 是什么?如何工作? — 同时发送多分辨率/码率流,SFU 按接收端带宽转发对应路如何检测网络质量变差? — 监听 getStats 的 packetsLost、jitterBufferDelay、availableOutgoingBitrateAEC 在什么场景下效果差? — 延迟超过 200ms、非线性失真严重、多声源场景setParameters 和 replaceTrack 有什么区别? — setParameters 调编码参数不变轨道,replaceTrack 换整个轨道(如切换摄像头)
服务端阅读 05月29日 22:54

WebRTC 安全吗?DTLS/SRTP 加密原理和常见风险有哪些?

WebRTC 安全吗?DTLS/SRTP 加密原理和常见风险有哪些?WebRTC 强制加密:所有媒体流走 SRTP,数据通道走 DTLS,密钥通过 DTLS 握手在 ICE 连接建立后协商,默认端到端加密。加密链路:信令:HTTPS/WSS 传输 SDP,信令服务器可看明文(所以选可信信令服务)媒体:DTLS 握手协商密钥 → SRTP 加密音视频包 → 中间人无法解密数据通道:DTLS 直接加密,SCTP 传输潜在安全风险:信令劫持:SDP 明文经信令服务器,恶意服务器可篡改 SDP 注入攻击者 ICE Candidate(MITM)IP 泄露:ICE Candidate 包含本地/公网 IP,即使经过 VPN 也会泄露真实 IPTURN 中继窃听:TURN 服务器可解密中继流量,需选择可信 TURN 提供商屏幕共享滥用:getDisplayMedia 无限制可能泄露敏感信息,应约束分享区域DDoS 利用:WebRTC 可被用来发起 UDP 泛洪攻击防护措施:验证远端指纹(remoteDescription.fingerprint)、限制 ICE Candidate 类型隐藏 IP、信令用 Token 鉴权。追问DTLS 和 TLS 有什么区别? — DTLS 基于 UDP,增加重传和乱序处理,握手流程类似但容忍丢包如何防止 IP 通过 ICE 泄露? — 设置 iceTransportPolicy 为 relay 仅用 TURN,或 filter 掉 host CandidateWebRTC 能做到零信任吗? — 需要 Insertable Streams 在应用层再做一层端到端加密TURN 服务器如何选择才安全? — 自建优于第三方,审计日志,限制中继流量配额
服务端阅读 05月29日 22:54

WebRTC 如何与 Socket.io 和 Node.js 后端集成?信令服务怎么设计?

WebRTC 如何与 Socket.io 和 Node.js 后端集成?信令服务怎么设计?WebRTC 本身只解决 P2P 媒体传输,信令交换(SDP Offer/Answer、ICE Candidate)必须通过独立信令通道完成,Socket.io + Node.js 是最常见组合。架构:浏览器 A 通过 Socket.io 将 SDP Offer 发给 Node.js 信令服务器 → 服务器转发给浏览器 B → B 回传 Answer → 双方交换 ICE Candidate → P2P 连接建立。核心集成点:Socket.io 信令:事件驱动,房间模型天然适合多方通话。emit/offer、on/answer、ice-candidate 三组事件即可完成信令Node.js TURN 服务:P2P 穿透失败时需中继,Node.js 可管理 TURN 服务器分配录制集成:Node.js + FFmpeg 接收 WebRTC 流转码存储,或用 MediaRecorder API 浏览器端录制权限控制:Node.js 中间件校验房间 Token,防止未授权加入典型信令流程:join room → emit('offer') → broadcast → emit('answer') → exchange ICE → RTCPeerConnection connected注意事项:Socket.io 不保证消息顺序,ICE Candidate 可能乱序到达,但 WebRTC 内部会缓存排序;大规模房间需改用 SFU(如 mediasoup)代替 Mesh。追问信令服务器能用 HTTP 代替 WebSocket 吗? — 可以但延迟高,HTTP 轮询不适合实时 ICE 交换多人通话信令如何设计? — 每对用户建立 PeerConnection,新用户加入时向房间内所有人发 Offer如何集成 mediasoup 做 SFU? — Node.js worker 管理 Router/Transport,WebRTC 端通过 produce/consume 订阅流Socket.io 和原生 WebSocket 怎么选? — Socket.io 自带房间/重连/命名空间,开发效率高;原生 WebSocket 更轻量性能更好
服务端阅读 05月29日 22:54

WebView 如何与原生应用交互?JS Bridge 原理是什么?

WebView 如何与原生应用交互?JS Bridge 原理是什么?WebView 与原生交互本质是JS 和 Native 之间的双向通信,核心方案:Native → JS:Android:evaluateJavascript(script, callback)(API 19+)iOS:evaluateJavaScript(script, completionHandler)JS → Native:URL Scheme 拦截:JS 修改 window.location = "scheme://action?params",Native 拦截 shouldOverrideUrlLoading 解析执行。兼容性最好,但 URL 长度受限prompt/alert 拦截:JS 调 prompt(),Native 在 onJsPrompt 中拦截。支持大参数,但会阻塞 JS 线程JS Bridge 注入:Native 通过 addJavascriptInterface(Android)/ WKScriptMessageHandler(iOS)向 JS 上下文注入对象,JS 直接调用原生方法。最主流的方案通信协议设计:请求:{ method: "getUserInfo", params: {}, callbackId: "cb_123" }响应:Native 执行 JS 回调函数 Bridge.callbacks["cb_123"](result)关键注意事项:安全:Android addJavascriptInterface 在 API < 17 有反射漏洞,需校验调用来源线程:Native 回调在非 UI 线程,操作 UI 需切换到主线程生命周期:页面销毁后 JS 回调可能崩溃,需清空回调队列追问三种 JS→Native 方案怎么选? — URL Scheme 兼容性好,prompt 支持大数据,注入对象最优雅,实际项目通常组合使用如何设计通用的 Bridge 协议? — 统一 method/params/callbackId,Native 端注册 Handler 映射表Bridge 通信有性能瓶颈吗? — 高频调用(如滚动事件)会有延迟,需节流或改用批量传递iOS WKWebView 和 UIWebView 交互有什么区别? — UIWebView 用 JSContext 注入,WKWebView 只能用 messageHandler + evaluateJavaScript
服务端阅读 05月29日 22:54

WebView、React Native 和 Flutter 怎么选?跨平台方案核心差异是什么?

WebView、React Native 和 Flutter 怎么选?跨平台方案核心差异是什么?| 维度 | WebView | React Native | Flutter ||------|---------|-------------|---------|| 渲染 | 系统 WebView | 原生组件 | 自绘引擎(Skia) || 语言 | HTML/JS/CSS | JavaScript | Dart || 性能 | 中低 | 中高 | 高 || 一致性 | 依赖系统内核 | 接近原生 | 像素级一致 || 生态 | Web 生态复用 | npm 生态 | Pub 生态(快速成长) || 热更新 | 天然支持 | CodePush 支持 | 需自建方案 |选择建议:内容型/运营驱动 → WebView:发版快、Web 人才多、适合高频变动的营销页交互型/团队 JS 为主 → RN:接近原生体验,复用 React 生态,适合中等复杂度应用高性能/一致性要求 → Flutter:60fps 自绘,UI 高度定制,适合动画密集或双端一致性要求高的应用注意:没有银弹,混合方案(部分 Flutter + 部分 WebView)也是常见选择。团队技术栈和招聘成本往往比技术指标更决定性。追问Flutter 自绘引擎为什么性能好? — 直接操作 Canvas 绘制,不经过原生组件树,减少桥接开销RN 的新架构有什么改进? — JSI 同步调用替代异步 Bridge,Fabric 新渲染器,TurboModule 懒加载WebView 方案最大的瓶颈是什么? — 渲染性能和交互一致性,复杂列表和手势场景体验差混合栈如何实现? — FlutterBoost / RN 容器化,原生管理页面栈,跨方案页面共存三者动态化能力如何? — WebView 最强(发版即更新),RN 支持 CodePush,Flutter 需自建 DSL 下发
服务端阅读 05月29日 22:54

WebView 能跑 PWA 吗?离线应用和 Service Worker 支持情况如何?

WebView 能跑 PWA 吗?离线应用和 Service Worker 支持情况如何?WebView 对 PWA 的支持严重受限,不能直接当作浏览器使用 PWA。Service Worker:Android WebView 从 Chrome 40+ 支持注册,但需手动启用 setJavaScriptEnabled + setDomStorageEnabled。iOS WKWebView 自 iOS 11.3 支持 Service Worker,但有限制——默认不共享浏览器 SW 缓存。离线应用核心障碍:Manifest 注册:WebView 不支持 Web App Manifest,无法安装到桌面缓存隔离:WebView 的 Service Worker 缓存与浏览器独立,不能复用后台同步:Background Sync API 在 WebView 中不可用推送通知:Push API 依赖浏览器推送通道,WebView 无法使用可行替代方案:离线包:Native 层下载资源包,WebView 拦截请求从本地返回LocalStorage / IndexedDB:可正常使用,做数据层离线App Shell 模型:首屏 HTML/CSS/JS 内置到 App,接口数据走缓存策略追问WebView 中 Service Worker 注册失败怎么排查? — 检查 HTTPS、scope 路径、SW 文件 MIME 类型是否为 application/javascript离线包如何更新? — Native 层检查版本号 diff 更新,或全量替换 zipIndexedDB 在 WebView 中有限制吗? — 存储配额因系统而异,iOS 可能低至 5MB 无提示清理如何模拟 PWA 的添加到桌面? — Native 提供 Shortcut API,结合 Deep Link 实现类似效果
服务端阅读 05月29日 22:54

WebView 中视频播放有哪些坑?如何处理全屏和自动播放?

WebView 中视频播放有哪些坑?如何处理全屏和自动播放?WebView 内嵌视频的核心问题集中在全屏切换、自动播放限制、硬件加速三方面。自动播放:多数浏览器禁止带声音自动播放。Android 需设置 mediaPlaybackRequiresUserGesture = false(API 17+),iOS WKWebView 设置 mediaTypesRequiringUserActionForPlayback = []。静音视频自动播放限制更宽松。全屏播放:HTML5 video 全屏时 Android 需实现 onShowCustomView / onHideCustomView 回调,将视频 SurfaceView 提升到原生层展示。iOS 的 video 默认支持内联全屏,playsinline 属性控制是否内联。硬件加速:Android 必须在 Manifest 中开启 hardwareAccelerated,否则视频黑屏有声音无画面。关键注意事项:同层渲染:视频层级高于 WebView,会遮挡其他 HTML 元素,需同层渲染方案(腾讯 X5 内核支持)内存释放:页面销毁前必须调用 video.pause() 释放解码器Cookie 传递:视频 CDN 鉴权 Cookie 可能未同步到 MediaPlayer画中画:Android 8+ 支持 PiP,需在 onUserLeaveHint 中 enterPictureInPictureMode追问视频黑屏有声音怎么排查? — 检查硬件加速是否开启,SurfaceView 层级是否被覆盖如何实现视频内联播放? — iOS 加 playsinline 属性,Android 设置 setMediaPlaybackRequiresUserGesture同层渲染原理是什么? — X5 内核将视频帧绘制到 WebView 纹理上,统一渲染层级视频 Cookie 鉴权失败怎么办? — 从 WebView CookieManager 读取,通过 Header 传给 MediaPlayer
服务端阅读 05月29日 22:54

WebView 如何拦截和修改网络请求?shouldInterceptRequest 能做什么?

WebView 如何拦截和修改网络请求?shouldInterceptRequest 能做什么?Android 用 shouldInterceptRequest(WebViewClient),iOS 用 WKURLSchemeHandler(WKWebView)拦截请求,可读取 URL/Headers 并返回自定义响应。Android shouldInterceptRequest:非 UI 线程回调,不可操作 View返回 WebResourceResponse 即替换原始响应,返回 null 走默认逻辑仅拦截 GET/POST 等 HTTP 请求,不拦截 XHR fetch(部分版本)iOS WKURLSchemeHandler:需注册自定义 Scheme(如 custom://),https scheme 无法拦截实现 startURLSchemeTask / stopURLSchemeTask返回数据通过 didReceiveResponse + didReceiveData 回调核心用途:本地缓存替换、请求头注入(Token)、CDN 域名替换、离线包加载。注意事项:性能:拦截所有请求会拖慢页面,需按 URL 前缀过滤线程安全:Android 回调在非 UI 线程,不能直接操作 UIHTTPS 限制:iOS 不允许拦截 https,必须用自定义 Scheme缓存一致:替换响应后需正确设置 mimeType 和 encoding追问如何只拦截特定域名请求? — URL 前缀判断,命中才处理,其余返回 null拦截后如何修改请求头? — Android 无法直接修改请求头,需重新发 HttpURLConnection 并附带头信息离线包方案如何实现? — 拦截请求后从本地 Zip 读取文件返回,版本号控制更新iOS 为什么不能拦截 https? — Apple 安全策略限制,需改用自定义 Scheme 或 ATS 例外
服务端阅读 05月29日 22:54

WebView 如何与原生页面混合使用?混合栈有哪些坑?

WebView 如何与原生页面混合使用?混合栈有哪些坑?WebView 与原生页面混合使用指在同一 App 中交替展示 H5 页面和原生页面,形成混合导航栈。核心方案:容器模式:Native 提供 WebView 容器 Activity/ViewController,H5 页面作为容器内容路由分发:URL Scheme 或 JS Bridge 指令决定跳转原生还是 WebView栈管理:统一路由层维护混合栈,处理前进/后退的页面类型判断关键注意事项:回退逻辑:WebView 内部有历史栈,按返回键需先回退 WebView 历史,空了再 pop 原生栈生命周期:WebView 页面切后台后 JS 定时器/回调可能丢失,需 visibilitychange 监听内存泄漏:WebView 引用未及时销毁,Android 需在 onDestroy 中移除并置空状态同步:登录态、用户信息需在原生和 H5 间实时同步,避免态不一致转场体验:Native↔H5 切换易出现白屏闪烁,可用预加载 + 转场动画缓解追问混合栈如何统一管理路由? — 封装 Router 中间层,registerNativeRoute / registerWebViewRoute,跳转时根据类型分发WebView 页面如何感知原生返回事件? — 注入 JS Bridge 的 onBackPress 回调,返回 true 拦截默认行为如何避免 WebView 重复创建? — 复用 WebView 池,页面切换时 loadUrl 替换内容而非新建实例混合栈的埋点如何统一? — 定义统一事件协议,Native 和 H5 各自上报到同一埋点通道
服务端阅读 05月29日 22:54

Canvas fillText 和 strokeText 有什么区别?如何实现高级文本效果?

Canvas fillText 和 strokeText 有什么区别?如何实现高级文本效果?fillText 绘制实心文字,strokeText 绘制文字轮廓(空心),两者共用 font、textAlign、textBaseline 属性。调用签名:fillText(text, x, y [, maxWidth]),maxWidth 超出时自动压缩。关键要点:同时使用:先 strokeText 再 fillText,可做出描边+填充效果,避免填充被描边覆盖measureText:获取文本宽度做布局计算,返回 TextMetrics 对象maxWidth:文本超宽时等比缩放,不截断多行文本:Canvas 不支持自动换行,需手动按 \n 分割后逐行 fillText中文渲染:指定支持中文的字体族,否则可能回退为系统默认ctx.font = 'bold 24px sans-serif';ctx.strokeStyle = '#333';ctx.lineWidth = 2;ctx.strokeText('描边文字', 50, 50);ctx.fillStyle = '#e74c3c';ctx.fillText('填充文字', 50, 80);追问如何实现文本自动换行? — 按字符逐个累加 measureText 宽度,超过容器宽度时截断换行strokeText 描边模糊怎么办? — 设置 lineJoin 为 round,或在 fillText 之前 strokeText 避免叠加伪影如何绘制竖排文字? — 逐字绘制并递增 y 坐标,或使用 CSS WritingMode 配合 OffscreenCanvasmeasureText 能获取高度吗? — 标准 TextMetrics 已支持 actualBoundingBoxAscent/Descent,兼容性需注意高 DPI 屏幕文字模糊如何解决? — Canvas 尺寸乘 devicePixelRatio,CSS 尺寸不变,scale 后绘制