1. HTTP 和 WebSocket 的区别与适用场景
核心区别:
HTTP:基于请求-响应模式,无状态协议,每次请求都要建立新连接(HTTP/1.1有keep-alive但本质仍是请求-响应)
适用场景:
网页浏览、资源加载
RESTful API调用
文件上传下载
WebSocket:全双工通信协议,建立连接后双方可随时主动发送数据
适用场景:
实时聊天应用
在线协作编辑
股票行情实时推送
多人在线游戏
简单比喻:HTTP像是打电话,每次说完挂断;WebSocket像是微信语音通话,接通后随时可以说话。
可引申:TCP和UDP区别?TCP挥手为什么要四次?TCP的拥塞避免算法是什么?http2.0和http3.0特点?https加密流程是什么?(内容较多,后续单独梳理)
2. SSE(Server-Sent Events)及其特点
SSE允许服务器主动向客户端推送数据,基于HTTP协议实现。
核心特点:
单向通信(服务器→客户端)
基于HTTP,兼容性好
自动重连机制
轻量级,使用简单
3. 选择SSE而非WebSocket的场景
适合SSE的场景:
4. 常见HTTP状态码有哪些
2xx 成功:
200 OK:请求成功
201 Created:创建成功(如新建资源)
204 No Content:成功但无返回内容
3xx 重定向:
4xx 客户端错误:
400 Bad Request:请求格式错误
401 Unauthorized:需要身份验证
404 Not Found:资源不存在
5xx 服务器错误:
5. 强缓存与协商缓存
强缓存:
直接从本地缓存读取,不向服务器发送请求
通过响应头实现:
优点:
缺点:
协商缓存:
每次请求都向服务器验证资源是否过期
通过请求头/响应头实现:
优点:
缺点:
6. Vue3 和 React 组件通信方式有哪些
Vue3 常用方式:
React 常用方式:
7. SSR 与 SSG 的区别
SSR(服务端渲染):
每次请求时在服务器生成HTML
适合:动态内容、SEO要求高、个性化页面
缺点:服务器压力大,TTFB时间可能较长
SSG(静态站点生成):
构建时生成静态HTML文件
适合:博客、文档、营销页面
优点:访问速度快,部署简单
缺点:不适合频繁更新的内容
现代方案:Next.js、Nuxt.js支持混合渲染,不同页面可采用不同策略。
8. 浏览器存储三剑客对比
9. localStorage 存 Token 的风险与解决方案
风险:
XSS攻击可直接读取localStorage
Token泄露等于账户被盗
无法设置HttpOnly保护
更安全方案:
1. HttpOnly Cookie(推荐)
// 服务器设置Set-Cookie: token=xxx; HttpOnly; Secure; SameSite=Strict
2. 内存存储 + 短期Token
Token只在内存中存在
配合refresh token机制
3. 浏览器安全存储API
10. 移动端适配方案对比
1. rem方案(已逐渐淘汰)
原理:根据根元素font-size动态计算
优点:兼容性好
缺点:需要JS计算,不如CSS方案纯粹
2. vw/vh方案(当前主流)
优点:纯CSS实现,性能好
缺点:低版本浏览器兼容问题
3. 响应式布局
使用媒体查询
适合:官网、管理后台
不适合:复杂移动端H5
4. 混合方案
// 实际项目中常用混合方案@functionvw($px) { @return($px / 375) * 100vw;}.container { padding: vw(15); @media (max-width: 768px) { // 移动端特殊样式 }}
11. 跨域问题与解决方案
什么是跨域?浏览器同源策略限制:协议、域名、端口任一不同即跨域。
常见解决方案:
1. CORS(推荐)
// 服务器设置响应头Access-Control-Allow-Origin: 'https://yourdomain.com'Access-Control-Allow-Credentials: true
2. 开发环境代理
// webpack配置devServer: { proxy: { '/api': { target: 'http://backend:3000', changeOrigin: true } }}
3. JSONP(仅限GET)
function handleResponse(data) { console.log(data);}// 动态创建script标签const script = document.createElement('script');script.src = 'http://api.com/data?callback=handleResponse';
4. Nginx反向代理
// nginxlocation /api/ { proxy_pass http://backend-server/; proxy_set_header Host $host;}
算法题:爬楼梯问题
解题思路:
到达第n阶,只能从第n-1阶或第n-2阶过来
所以动态转移方程:dp[n] = dp[n-1] + dp[n-2]
方法一:动态规划 + 斐波那契数列
// 斐波那契数列思想function climbStairs(n) { if (n <= 2) return n; // dp[i]表示爬到第i阶的方法数 const dp = new Array(n + 1); dp[1] = 1; // 1阶:1种方法 dp[2] = 2; // 2阶:2种方法(1+1或2) for (let i = 3; i <= n; i++) { // 状态转移方程 dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n];}
方法二:动态规划 + 滚动数组
// 滚动数组,空间优化function climbStairsOptimized(n) { if (n <= 2) return n; let prev1 = 1; // dp[i-1] let prev2 = 2; // dp[i-2] for (let i = 3; i <= n; i++) { const current = prev1 + prev2; prev1 = prev2; prev2 = current; } return prev2;}