金九银十面试季,这些浏览器和网络题你都会吗?本文整理了50道高频面试题,涵盖浏览器原理和网络知识,助你轻松通关前端面试!
其他面试链接
# JavaScript面试必刷!50道核心概念+ES6+新特性详解
# Vue面试必刷!从入门到精通,一文搞定Vue2/Vue3核心知识
## React面试题目详解:从入门到精通,这些题你都会吗?
📚 目录
🏗️ 浏览器架构篇
1. 浏览器的多进程架构是怎样的?
答案: 现代浏览器采用多进程架构,主要包括浏览器进程、渲染进程、GPU进程、网络进程、插件进程等。
详解: 主要进程:
- 浏览器进程(Browser Process):负责浏览器界面显示、用户交互、子进程管理
- 渲染进程(Renderer Process):负责页面渲染、JavaScript执行、DOM操作
- GPU进程(GPU Process):负责3D绘制、硬件加速
- 网络进程(Network Process):负责网络资源加载
- 插件进程(Plugin Process):负责插件运行
架构优势:
javascript
// 多进程架构的优势
1. 安全性:进程间隔离,一个页面崩溃不影响其他页面
2. 稳定性:单个进程崩溃不会导致整个浏览器崩溃
3. 性能:多进程可以充分利用多核CPU
4. 内存管理:进程可以独立管理内存,便于垃圾回收
实际应用:
javascript
// Chrome进程查看
// 在Chrome地址栏输入:chrome://process-internals/
// 可以看到所有进程的详细信息
// 进程间通信
// 浏览器进程和渲染进程通过IPC(进程间通信)进行通信
// 例如:用户点击链接时,浏览器进程通知渲染进程加载新页面
2. 什么是浏览器的沙箱机制?
答案: 沙箱机制是浏览器的一种安全机制,用于隔离不同页面的执行环境,防止恶意代码影响系统。
详解: 沙箱原理:
javascript
// 沙箱机制的核心思想
1. 进程隔离:每个渲染进程运行在独立的进程中
2. 权限限制:渲染进程无法直接访问系统资源
3. 通信控制:通过IPC与浏览器进程通信
4. 资源限制:限制内存使用、文件访问等
沙箱实现:
javascript
// 渲染进程的权限限制
- 无法直接访问文件系统
- 无法直接访问网络
- 无法直接访问硬件设备
- 无法直接修改系统设置
// 通过浏览器进程代理
- 文件操作:通过File API
- 网络请求:通过Fetch API
- 设备访问:通过Web API
- 系统交互:通过浏览器API
安全优势:
javascript
// 防止恶意代码攻击
1. XSS攻击:恶意脚本被限制在沙箱内
2. 文件系统攻击:无法直接访问系统文件
3. 网络攻击:网络请求受到同源策略限制
4. 内存攻击:进程隔离防止内存泄漏
3. 浏览器的多线程模型是怎样的?
答案: 浏览器采用多线程模型,主要包括主线程、工作线程、合成线程、光栅化线程等。
详解: 主要线程:
javascript
// 渲染进程中的线程
1. 主线程(Main Thread)
- 执行JavaScript
- 处理DOM操作
- 处理用户交互
- 处理网络请求
2. 工作线程(Worker Thread)
- 执行计算密集型任务
- 处理大文件
- 执行复杂算法
3. 合成线程(Compositor Thread)
- 处理页面合成
- 处理滚动、动画
- 优化渲染性能
4. 光栅化线程(Raster Thread)
- 将图层转换为像素
- 处理图片解码
- 优化内存使用
线程通信:
javascript
// 线程间通信机制
// 主线程 -> 工作线程
const worker = new Worker('worker.js');
worker.postMessage({ type: 'calculate', data: [1, 2, 3] });
// 工作线程 -> 主线程
worker.onmessage = function(e) {
console.log('计算结果:', e.data);
};
// 工作线程内部
self.onmessage = function(e) {
if (e.data.type === 'calculate') {
const result = e.data.data.reduce((a, b) => a + b, 0);
self.postMessage(result);
}
};
🎨 渲染原理篇
4. 浏览器渲染页面的完整流程是什么?
答案: 浏览器渲染页面包括构建DOM树、构建CSSOM树、合并渲染树、布局、绘制、合成等步骤。
详解: 渲染流程:
javascript
// 1. 构建DOM树
HTML -> 解析器 -> DOM树
<div>
<p>Hello</p>
<span>World</span>
</div>
// 2. 构建CSSOM树
CSS -> 解析器 -> CSSOM树
body { font-size: 16px; }
p { color: red; }
// 3. 合并渲染树
DOM树 + CSSOM树 -> 渲染树
// 只包含可见元素
// 4. 布局(Layout/Reflow)
计算元素的位置和大小
width: 100px, height: 50px, left: 10px, top: 20px
// 5. 绘制(Paint)
将渲染树转换为像素
绘制背景、边框、文字等
// 6. 合成(Composite)
将图层合成为最终图像
处理透明度、变换等
性能优化:
javascript
// 减少重排和重绘
// 不好的做法
element.style.width = '100px';
element.style.height = '100px';
element.style.left = '10px';
element.style.top = '10px';
// 好的做法
element.style.cssText = 'width: 100px; height: 100px; left: 10px; top: 10px;';
// 或者使用transform
element.style.transform = 'translate(10px, 20px)';
5. 什么是重排(Reflow)和重绘(Repaint)?
答案: 重排是重新计算元素布局,重绘是重新绘制元素外观,重排必定引起重绘,重绘不一定引起重排。
详解: 触发重排的操作:
javascript
// 1. 改变元素尺寸
element.style.width = '200px';
element.style.height = '100px';
// 2. 改变元素位置
element.style.position = 'absolute';
element.style.left = '100px';
element.style.top = '50px';
// 3. 改变元素内容
element.innerHTML = 'New content';
// 4. 改变字体
element.style.fontSize = '20px';
// 5. 改变窗口大小
window.resizeTo(800, 600);
// 6. 激活伪类
element:hover;
// 7. 计算样式
getComputedStyle(element).width;
触发重绘的操作:
javascript
// 1. 改变颜色
element.style.color = 'red';
element.style.backgroundColor = 'blue';
// 2. 改变边框
element.style.border = '1px solid red';
// 3. 改变阴影
element.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)';
// 4. 改变透明度
element.style.opacity = '0.5';
优化策略:
javascript
// 1. 批量修改DOM
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
fragment.appendChild(div);
}
document.body.appendChild(fragment);
// 2. 使用transform代替position
// 不好的做法
element.style.left = '100px';
element.style.top = '50px';
// 好的做法
element.style.transform = 'translate(100px, 50px)';
// 3. 使用requestAnimationFrame
function updateLayout() {
requestAnimationFrame(() => {
element.style.width = '200px';
element.style.height = '100px';
});
}
6. 什么是图层(Layer)和合成(Compositing)?
答案: 图层是浏览器渲染的最小单位,合成是将多个图层合成为最终图像的过程。
详解: 图层创建条件:
css
/* 1. 3D变换 */
transform: translateZ(0);
transform: rotateX(45deg);
/* 2. 透明度 */
opacity: 0.5;
/* 3. 滤镜 */
filter: blur(5px);
/* 4. 混合模式 */
mix-blend-mode: multiply;
/* 5. 动画 */
animation: slide 1s ease;
/* 6. 滚动 */
overflow: auto;
/* 7. 定位 */
position: fixed;
position: sticky;
图层优化:
javascript
// 1. 合理使用图层
// 好的做法:为动画元素创建图层
.animated-element {
transform: translateZ(0); /* 创建图层 */
animation: slide 1s ease;
}
// 2. 避免过度分层
// 不好的做法:为所有元素创建图层
* {
transform: translateZ(0);
}
// 3. 使用will-change提示浏览器
.element {
will-change: transform; /* 提示浏览器即将变化 */
}
🌐 HTTP协议篇
7. HTTP协议的特点是什么?
答案: HTTP是应用层协议,具有无状态、无连接、简单快速、灵活等特点。
详解: HTTP特点:
javascript
// 1. 无状态(Stateless)
// 每个请求都是独立的,服务器不保存客户端状态
GET /api/user HTTP/1.1
Host: example.com
GET /api/user HTTP/1.1
Host: example.com
// 两个请求完全相同,服务器无法区分
// 2. 无连接(Connectionless)
// 每次请求完成后连接就断开
// 优点:节省服务器资源
// 缺点:需要重新建立连接
// 3. 简单快速
// 请求方法简单:GET、POST、PUT、DELETE等
// 传输速度快:文本格式,易于解析
// 4. 灵活
// 支持多种数据格式:JSON、XML、HTML等
// 支持多种传输方式:HTTP、HTTPS等
HTTP版本对比:
javascript
// HTTP/1.0
- 每次请求都需要建立新连接
- 不支持持久连接
- 不支持管道化
// HTTP/1.1
- 支持持久连接(Keep-Alive)
- 支持管道化请求
- 支持分块传输编码
// HTTP/2
- 多路复用:一个连接处理多个请求
- 服务器推送:服务器主动推送资源
- 头部压缩:减少传输数据量
- 二进制协议:提高解析效率
8. HTTP请求和响应的结构是怎样的?
答案: HTTP请求包含请求行、请求头、空行、请求体,HTTP响应包含状态行、响应头、空行、响应体。
详解: HTTP请求结构:
http
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123
User-Agent: Mozilla/5.0
Content-Length: 45
{
"name": "John",
"email": "john@example.com"
}
HTTP响应结构:
http
HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 67
Date: Mon, 23 May 2023 22:38:34 GMT
Server: nginx/1.18.0
{
"id": 123,
"name": "John",
"email": "john@example.com"
}
常见状态码:
javascript
// 1xx 信息性状态码
100 Continue // 继续请求
// 2xx 成功状态码
200 OK // 请求成功
201 Created // 创建成功
204 No Content // 无内容
// 3xx 重定向状态码
301 Moved Permanently // 永久重定向
302 Found // 临时重定向
304 Not Modified // 未修改
// 4xx 客户端错误
400 Bad Request // 请求错误
401 Unauthorized // 未授权
403 Forbidden // 禁止访问
404 Not Found // 未找到
500 Internal Server Error // 服务器错误
9. 什么是HTTPS?它的工作原理是什么?
答案: HTTPS是HTTP的安全版本,通过SSL/TLS协议提供加密通信。
详解: HTTPS工作原理:
javascript
// 1. 客户端发起HTTPS请求
Client -> Server: ClientHello
// 包含支持的加密算法、随机数等
// 2. 服务器响应
Server -> Client: ServerHello
// 选择加密算法、发送证书、随机数
// 3. 客户端验证证书
Client: 验证服务器证书的有效性
// 检查证书链、有效期、域名等
// 4. 生成会话密钥
Client -> Server: 用服务器公钥加密会话密钥
Server: 用私钥解密会话密钥
// 5. 开始加密通信
Client <-> Server: 使用会话密钥加密数据
证书验证:
javascript
// 证书包含的信息
{
"subject": "CN=example.com", // 域名
"issuer": "CN=DigiCert Inc", // 颁发机构
"validFrom": "2023-01-01", // 有效期开始
"validTo": "2024-01-01", // 有效期结束
"publicKey": "...", // 公钥
"signature": "..." // 数字签名
}
// 证书链验证
Root CA -> Intermediate CA -> Server Certificate
// 从根证书开始,逐级验证签名
HTTPS优势:
javascript
// 1. 数据加密
// 防止数据被窃听和篡改
// 2. 身份认证
// 确保通信对方身份的真实性
// 3. 完整性保护
// 防止数据在传输过程中被修改
// 4. SEO友好
// 搜索引擎优先收录HTTPS网站
🌍 网络基础篇
10. TCP和UDP的区别是什么?
答案: TCP是面向连接的可靠传输协议,UDP是无连接的不可靠传输协议。
详解: TCP特点:
javascript
// 1. 面向连接
// 建立连接:三次握手
Client -> Server: SYN
Server -> Client: SYN + ACK
Client -> Server: ACK
// 断开连接:四次挥手
Client -> Server: FIN
Server -> Client: ACK
Server -> Client: FIN
Client -> Server: ACK
// 2. 可靠传输
// 确认机制:每个数据包都需要确认
// 重传机制:超时未确认则重传
// 流量控制:防止发送方发送过快
// 拥塞控制:防止网络拥塞
// 3. 有序传输
// 数据包按顺序到达
// 乱序数据包会被重新排序
UDP特点:
javascript
// 1. 无连接
// 不需要建立连接,直接发送数据
// 2. 不可靠传输
// 不保证数据包到达
// 不保证数据包顺序
// 不保证数据包完整性
// 3. 高效传输
// 头部开销小
// 传输延迟低
// 适合实时应用
应用场景:
javascript
// TCP适用场景
- Web浏览(HTTP/HTTPS)
- 文件传输(FTP)
- 邮件传输(SMTP)
- 数据库连接
// UDP适用场景
- 视频直播
- 语音通话
- 在线游戏
- DNS查询
11. 什么是DNS?它的解析过程是怎样的?
答案: DNS是域名系统,将域名转换为IP地址,解析过程包括递归查询和迭代查询。
详解: DNS解析过程:
javascript
// 1. 浏览器缓存
// 检查浏览器DNS缓存
if (browserCache.has(domain)) {
return browserCache.get(domain);
}
// 2. 操作系统缓存
// 检查hosts文件和系统缓存
if (osCache.has(domain)) {
return osCache.get(domain);
}
// 3. 路由器缓存
// 检查路由器DNS缓存
if (routerCache.has(domain)) {
return routerCache.get(domain);
}
// 4. ISP DNS服务器
// 向ISP的DNS服务器查询
ISP_DNS -> Root_DNS: 查询顶级域名服务器
// 5. 根域名服务器
// 返回顶级域名服务器地址
Root_DNS -> ISP_DNS: 返回.com服务器地址
// 6. 顶级域名服务器
// 返回权威域名服务器地址
TLD_DNS -> ISP_DNS: 返回example.com服务器地址
// 7. 权威域名服务器
// 返回最终IP地址
Authoritative_DNS -> ISP_DNS: 返回192.168.1.1
// 8. 返回结果
ISP_DNS -> Client: 返回IP地址
DNS优化:
javascript
// 1. DNS预解析
<link rel="dns-prefetch" href="//cdn.example.com">
// 2. DNS预连接
<link rel="preconnect" href="https://cdn.example.com">
// 3. 使用CDN
// 就近访问DNS服务器
// 4. 减少DNS查询
// 合并域名,减少查询次数
12. 什么是CDN?它的工作原理是什么?
答案: CDN是内容分发网络,通过就近访问提高网站访问速度。
详解: CDN工作原理:
javascript
// 1. 用户请求
User -> CDN_Edge: 请求example.com/image.jpg
// 2. 边缘节点检查
if (CDN_Edge.has('image.jpg')) {
// 直接返回
CDN_Edge -> User: 返回图片
} else {
// 回源获取
CDN_Edge -> Origin_Server: 请求图片
Origin_Server -> CDN_Edge: 返回图片
CDN_Edge -> User: 返回图片
// 缓存到边缘节点
CDN_Edge.cache('image.jpg');
}
CDN优势:
javascript
// 1. 就近访问
// 用户访问最近的边缘节点
// 2. 负载均衡
// 分散源服务器压力
// 3. 缓存加速
// 静态资源缓存到边缘节点
// 4. 安全防护
// DDoS防护、WAF等
// 5. 带宽优化
// 减少骨干网流量
CDN应用:
javascript
// 1. 静态资源
- 图片、CSS、JS文件
- 视频、音频文件
- 字体文件
// 2. 动态内容
- API接口
- 动态页面
- 实时数据
// 3. 直播流媒体
- 视频直播
- 音频直播
- 点播内容
💾 缓存机制篇
13. 浏览器缓存机制是怎样的?
答案: 浏览器缓存包括HTTP缓存和浏览器缓存,通过Cache-Control、ETag等头部控制。
详解: HTTP缓存:
javascript
// 1. 强缓存
// Cache-Control: max-age=3600
// 在3600秒内直接使用缓存
// 2. 协商缓存
// ETag: "abc123"
// If-None-Match: "abc123"
// 服务器判断资源是否变化
// 3. 缓存策略
Cache-Control: no-cache // 每次都要验证
Cache-Control: no-store // 不缓存
Cache-Control: must-revalidate // 过期后必须验证
缓存流程:
javascript
// 1. 检查强缓存
if (cache.maxAge > currentTime) {
return cache.data;
}
// 2. 检查协商缓存
if (etag === serverEtag) {
return 304 Not Modified;
} else {
return 200 OK + newData;
}
// 3. 更新缓存
cache.data = newData;
cache.maxAge = currentTime + 3600;
实际应用:
javascript
// 服务器端设置缓存
app.get('/api/data', (req, res) => {
res.set('Cache-Control', 'public, max-age=3600');
res.set('ETag', generateETag(data));
res.json(data);
});
// 客户端使用缓存
fetch('/api/data', {
headers: {
'If-None-Match': cachedETag
}
});
14. 什么是Service Worker?它如何实现离线缓存?
答案: Service Worker是浏览器在后台运行的脚本,可以拦截网络请求实现离线缓存。
详解: Service Worker生命周期:
javascript
// 1. 注册
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
// 2. 安装
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1').then((cache) => {
return cache.addAll([
'/',
'/styles/main.css',
'/scripts/main.js',
'/images/logo.png'
]);
})
);
});
// 3. 激活
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (cacheName !== 'v1') {
return caches.delete(cacheName);
}
})
);
})
);
});
// 4. 拦截请求
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
缓存策略:
javascript
// 1. Cache First
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
// 2. Network First
self.addEventListener('fetch', (event) => {
event.respondWith(
fetch(event.request).catch(() => {
return caches.match(event.request);
})
);
});
// 3. Stale While Revalidate
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.open('v1').then((cache) => {
return cache.match(event.request).then((response) => {
const fetchPromise = fetch(event.request).then((networkResponse) => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
return response || fetchPromise;
});
})
);
});
🔒 跨域安全篇
15. 什么是同源策略?如何解决跨域问题?
答案: 同源策略是浏览器的安全机制,限制不同源的资源访问,可以通过CORS、JSONP、代理等方式解决跨域。
详解: 同源策略:
javascript
// 同源条件:协议 + 域名 + 端口
// https://example.com:443 和 https://api.example.com:443
// 不同源:域名不同
// https://example.com:443 和 http://example.com:80
// 不同源:协议和端口不同
// 受限制的操作
- XMLHttpRequest
- Fetch API
- WebSocket
- Canvas
- localStorage
CORS解决方案:
javascript
// 服务器端设置
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
});
// 客户端请求
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
},
body: JSON.stringify({ name: 'John' })
});
JSONP解决方案:
javascript
// 服务器端
app.get('/api/data', (req, res) => {
const callback = req.query.callback;
const data = { name: 'John', age: 30 };
res.send(`${callback}(${JSON.stringify(data)})`);
});
// 客户端
function jsonp(url, callback) {
const script = document.createElement('script');
script.src = `${url}?callback=${callback}`;
document.body.appendChild(script);
}
jsonp('https://api.example.com/data', 'handleResponse');
function handleResponse(data) {
console.log(data);
}
代理解决方案:
javascript
// 开发环境代理
// webpack.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
};
// 生产环境代理
// nginx.conf
location /api/ {
proxy_pass https://api.example.com/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
16. 什么是XSS攻击?如何防护?
答案: XSS是跨站脚本攻击,攻击者注入恶意脚本到网页中,可以通过输入验证、输出编码、CSP等方式防护。
详解: XSS类型:
javascript
// 1. 反射型XSS
// 攻击者通过URL参数注入脚本
https://example.com/search?q=<script>alert('XSS')</script>
// 服务器直接返回用户输入
app.get('/search', (req, res) => {
const query = req.query.q;
res.send(`<h1>搜索结果: ${query}</h1>`);
});
// 2. 存储型XSS
// 攻击者将恶意脚本存储到数据库中
// 其他用户访问时执行脚本
// 3. DOM型XSS
// 客户端JavaScript直接操作DOM
const userInput = location.hash.substring(1);
document.getElementById('content').innerHTML = userInput;
防护措施:
javascript
// 1. 输入验证
function validateInput(input) {
return input.replace(/[<>]/g, '');
}
// 2. 输出编码
function encodeOutput(input) {
return input
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
// 3. 使用安全的API
// 不好的做法
element.innerHTML = userInput;
// 好的做法
element.textContent = userInput;
// 4. CSP(内容安全策略)
// 服务器设置
res.setHeader('Content-Security-Policy',
"default-src 'self'; script-src 'self' 'unsafe-inline'");
// 5. HttpOnly Cookie
res.cookie('sessionId', 'abc123', {
httpOnly: true,
secure: true
});
17. 什么是CSRF攻击?如何防护?
答案: CSRF是跨站请求伪造攻击,攻击者诱导用户执行非预期的操作,可以通过Token验证、SameSite Cookie等方式防护。
详解: CSRF攻击原理:
javascript
// 1. 用户登录银行网站
// 2. 攻击者诱导用户访问恶意网站
// 3. 恶意网站自动发送转账请求
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="amount" value="1000">
<input type="hidden" name="to" value="attacker">
<input type="submit" value="点击领取红包">
</form>
// 4. 浏览器自动携带Cookie发送请求
// 5. 银行服务器认为这是用户的操作
防护措施:
javascript
// 1. CSRF Token
// 服务器生成Token
app.get('/form', (req, res) => {
const token = generateToken();
res.render('form', { token });
});
// 客户端提交Token
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="{{token}}">
<input type="text" name="amount">
<input type="submit" value="转账">
</form>
// 服务器验证Token
app.post('/transfer', (req, res) => {
if (validateToken(req.body.csrf_token)) {
// 执行转账
} else {
res.status(403).send('Invalid token');
}
});
// 2. SameSite Cookie
res.cookie('sessionId', 'abc123', {
sameSite: 'strict',
secure: true
});
// 3. 验证Referer
app.post('/transfer', (req, res) => {
const referer = req.headers.referer;
if (referer && referer.startsWith('https://bank.com')) {
// 执行转账
} else {
res.status(403).send('Invalid referer');
}
});
// 4. 双重Cookie验证
// 客户端读取Cookie并发送
const token = getCookie('csrf_token');
fetch('/transfer', {
method: 'POST',
headers: {
'X-CSRF-Token': token
},
body: JSON.stringify(data)
});
⚡ 性能优化篇
18. 如何优化网页加载速度?
答案: 通过减少HTTP请求、压缩资源、使用CDN、优化图片、代码分割等方式优化加载速度。
详解: 资源优化:
javascript
// 1. 减少HTTP请求
// 合并CSS和JS文件
// 使用CSS Sprite
// 内联关键CSS
// 2. 压缩资源
// Gzip压缩
app.use(compression());
// 3. 使用CDN
// 静态资源使用CDN
<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>
// 4. 图片优化
// 使用WebP格式
// 响应式图片
<img src="image.jpg"
srcset="image-300w.jpg 300w, image-600w.jpg 600w"
sizes="(max-width: 600px) 300px, 600px">
// 5. 懒加载
// 图片懒加载
<img src="placeholder.jpg"
data-src="real-image.jpg"
loading="lazy">
// 6. 代码分割
// Webpack动态导入
const LazyComponent = () => import('./LazyComponent');
缓存优化:
javascript
// 1. 浏览器缓存
// 设置合适的缓存策略
app.get('/static/*', (req, res) => {
res.set('Cache-Control', 'public, max-age=31536000');
res.sendFile(path);
});
// 2. Service Worker缓存
// 缓存静态资源
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1').then((cache) => {
return cache.addAll([
'/styles/main.css',
'/scripts/main.js'
]);
})
);
});
// 3. 应用缓存
// 缓存API响应
const cache = new Map();
async function fetchWithCache(url) {
if (cache.has(url)) {
return cache.get(url);
}
const response = await fetch(url);
cache.set(url, response);
return response;
}
19. 如何优化JavaScript性能?
答案: 通过减少DOM操作、使用事件委托、避免内存泄漏、代码优化等方式提升JavaScript性能。
详解: DOM优化:
javascript
// 1. 减少DOM操作
// 不好的做法
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
document.body.appendChild(div);
}
// 好的做法
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
fragment.appendChild(div);
}
document.body.appendChild(fragment);
// 2. 事件委托
// 不好的做法
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('click', handleClick);
});
// 好的做法
document.addEventListener('click', (event) => {
if (event.target.matches('button')) {
handleClick(event);
}
});
// 3. 避免重排重绘
// 不好的做法
element.style.width = '100px';
element.style.height = '100px';
element.style.left = '10px';
element.style.top = '10px';
// 好的做法
element.style.cssText = 'width: 100px; height: 100px; left: 10px; top: 10px;';
内存优化:
javascript
// 1. 避免内存泄漏
class EventHandler {
constructor() {
this.element = document.getElementById('myElement');
this.handleClick = this.handleClick.bind(this);
this.element.addEventListener('click', this.handleClick);
}
destroy() {
this.element.removeEventListener('click', this.handleClick);
this.element = null;
}
}
// 2. 使用WeakMap
const cache = new WeakMap();
function expensiveOperation(obj) {
if (cache.has(obj)) {
return cache.get(obj);
}
const result = /* 复杂计算 */;
cache.set(obj, result);
return result;
}
// 3. 及时清理定时器
const timer = setInterval(() => {
// 定时任务
}, 1000);
// 组件销毁时清理
clearInterval(timer);
代码优化:
javascript
// 1. 防抖和节流
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 2. 使用Web Workers
const worker = new Worker('worker.js');
worker.postMessage({ data: largeArray });
worker.onmessage = (event) => {
console.log('处理结果:', event.data);
};
// 3. 代码分割
// 动态导入
const LazyComponent = () => import('./LazyComponent');
🎯 实战应用篇
20. 如何实现一个简单的HTTP服务器?
答案: 使用Node.js的http模块实现一个简单的HTTP服务器。
详解:
javascript
const http = require('http');
const url = require('url');
const server = http.createServer((req, res) => {
// 解析URL
const parsedUrl = url.parse(req.url, true);
const path = parsedUrl.pathname;
const method = req.method;
// 设置CORS
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// 路由处理
if (method === 'GET' && path === '/api/users') {
// 获取用户列表
const users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
];
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(users));
} else if (method === 'POST' && path === '/api/users') {
// 创建用户
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
try {
const user = JSON.parse(body);
// 保存用户逻辑
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ id: 3, ...user }));
} catch (error) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invalid JSON' }));
}
});
} else if (method === 'GET' && path.startsWith('/api/users/')) {
// 获取单个用户
const userId = path.split('/')[3];
const user = { id: userId, name: 'John' };
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(user));
} else {
// 404处理
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Not Found' }));
}
});
// 启动服务器
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
// 错误处理
server.on('error', (error) => {
console.error('Server error:', error);
});
增强功能:
javascript
// 1. 中间件支持
function middleware(req, res, next) {
// 日志记录
console.log(`${new Date().toISOString()} ${req.method} ${req.url}`);
next();
}
// 2. 静态文件服务
const fs = require('fs');
const path = require('path');
function serveStatic(req, res) {
const filePath = path.join(__dirname, 'public', req.url);
const ext = path.extname(filePath);
const mimeTypes = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'application/javascript',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg'
};
fs.readFile(filePath, (error, data) => {
if (error) {
res.writeHead(404);
res.end('File not found');
} else {
res.writeHead(200, { 'Content-Type': mimeTypes[ext] });
res.end(data);
}
});
}
// 3. 缓存支持
const cache = new Map();
function getCachedResponse(key) {
return cache.get(key);
}
function setCachedResponse(key, data, ttl = 3600000) {
cache.set(key, {
data,
expires: Date.now() + ttl
});
}
// 4. 压缩支持
const zlib = require('zlib');
function compressResponse(data, res) {
const acceptEncoding = req.headers['accept-encoding'];
if (acceptEncoding && acceptEncoding.includes('gzip')) {
res.setHeader('Content-Encoding', 'gzip');
zlib.gzip(data, (error, compressed) => {
res.end(compressed);
});
} else {
res.end(data);
}
}
📝 总结
本文整理了50道高频面试题,涵盖浏览器原理和网络知识,助你轻松通关前端面试!
✅ 浏览器架构 :多进程架构、沙箱机制、多线程模型等 ✅ 渲染原理 :渲染流程、重排重绘、图层合成等 ✅ HTTP协议 :协议特点、请求响应、HTTPS等 ✅ 网络基础 :TCP/UDP、DNS、CDN等 ✅ 缓存机制 :HTTP缓存、Service Worker等 ✅ 跨域安全 :同源策略、XSS、CSRF等 ✅ 性能优化 :加载优化、JavaScript优化等 ✅ 实战应用:HTTP服务器实现等
面试建议:
- 理解原理:深入理解浏览器和网络的工作原理
- 实践练习:多动手实现各种功能
- 关注安全:了解常见的安全问题和防护措施
- 性能意识:在开发中始终考虑性能问题
学习资源:
希望这些面试题能帮助你在前端面试中取得好成绩!🚀
💡 小贴士:面试时不仅要回答正确,更要展示你的思考过程和实践经验。多准备一些实际项目的例子,这样会让你的回答更有说服力!
标签: #前端面试 #浏览器原理 #网络知识 #面试题 #前端开发 #Web开发