Node.js
Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行時,廣泛用于構建高性能的網絡應用。以下是一些常見的 Node.js 面試題及其解答,幫助你準備面試:
1. 什么是 Node.js?
Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行時,允許開發者使用 JavaScript 編寫服務器端代碼。它采用事件驅動、非阻塞 I/O 模型,適合構建高性能、可擴展的網絡應用。
2. Node.js 的特點是什么?
非阻塞 I/O:Node.js 使用非阻塞 I/O 模型,能夠處理大量并發請求。
事件驅動:基于事件循環機制,適合處理實時應用。
單線程:Node.js 是單線程的,但通過事件循環和異步操作可以高效處理并發。
跨平臺:Node.js 可以在多種操作系統上運行,如 Windows、Linux、macOS 等。
3. Node.js 的事件循環是什么?
事件循環是 Node.js 處理異步操作的核心機制。它允許 Node.js 執行非阻塞 I/O 操作,盡管 JavaScript 是單線程的。事件循環不斷地檢查事件隊列,執行回調函數,處理異步任務。
4. 什么是回調函數?
回調函數是作為參數傳遞給另一個函數的函數,通常用于處理異步操作的結果。例如,在讀取文件時,可以傳遞一個回調函數來處理文件讀取完成后的操作。
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {if (err) throw err;console.log(data);
});
5. 什么是 Promise?
Promise 是用于處理異步操作的對象,表示一個可能現在、將來或永遠都不會完成的操作。它有三種狀態:pending(進行中)、fulfilled(已成功)和 rejected(已失敗)。
const promise = new Promise((resolve, reject) => {setTimeout(() => {resolve('Success!');}, 1000);
});promise.then((result) => {console.log(result); // 輸出: Success!
});
6. 什么是 async/await?
async/await 是 ES2017 引入的語法糖,用于簡化異步代碼的編寫。async 函數返回一個 Promise,await 用于等待 Promise 的解決。
async function fetchData() {const response = await fetch('https://api.example.com/data');const data = await response.json();console.log(data);
}
7. Node.js 中的模塊系統是什么?
Node.js 使用 CommonJS 模塊系統,允許開發者將代碼分割成多個模塊。每個模塊可以通過 require 導入,通過 module.exports 導出。
// math.js
module.exports = {add: (a, b) => a + b,subtract: (a, b) => a - b
};// app.js
const math = require('./math');
console.log(math.add(2, 3)); // 輸出: 5
8. 什么是事件發射器(Event Emitter)?
事件發射器是 Node.js 中用于處理事件的核心類。它允許對象觸發和監聽事件。EventEmitter 類是 events 模塊的一部分。
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}const myEmitter = new MyEmitter();
myEmitter.on('event', () => {console.log('An event occurred!');
});myEmitter.emit('event'); // 輸出: An event occurred!
9. Node.js 中的流(Stream)是什么?
流是用于處理讀寫數據的抽象接口,特別適合處理大文件或實時數據。Node.js 中有四種類型的流:可讀流、可寫流、雙工流和轉換流。
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt');readStream.pipe(writeStream);
10. 如何處理 Node.js 中的錯誤?
在 Node.js 中,錯誤通常通過回調函數的第一個參數傳遞,或者通過 Promise 的 catch 方法捕獲。還可以使用 try/catch 塊來處理 async/await 中的錯誤。
// 回調函數中的錯誤處理
fs.readFile('file.txt', 'utf8', (err, data) => {if (err) {console.error('Error reading file:', err);return;}console.log(data);
});// Promise 中的錯誤處理
promise.then((result) => console.log(result)).catch((err) => console.error('Error:', err));// async/await 中的錯誤處理
async function fetchData() {try {const response = await fetch('https://api.example.com/data');const data = await response.json();console.log(data);} catch (err) {console.error('Error:', err);}
}
11. 什么是中間件(Middleware)?
中間件是 Express.js 中的一個概念,指的是在請求和響應之間執行的函數。中間件可以執行各種任務,如日志記錄、身份驗證、數據解析等。
const express = require('express');
const app = express();app.use((req, res, next) => {console.log('Request URL:', req.url);next();
});app.get('/', (req, res) => {res.send('Hello World!');
});app.listen(3000);
12. 如何調試 Node.js 應用?
可以使用 node inspect 命令啟動調試器,或者使用 Chrome DevTools 進行調試。還可以使用 console.log 或 debugger 語句進行簡單的調試。
node inspect app.js
13. Node.js 中的集群(Cluster)是什么?
Node.js 的集群模塊允許創建多個子進程(worker)來處理請求,充分利用多核 CPU 的性能。每個子進程都有自己的事件循環和內存空間。
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;if (cluster.isMaster) {for (let i = 0; i < numCPUs; i++) {cluster.fork();}
} else {http.createServer((req, res) => {res.writeHead(200);res.end('Hello World\n');}).listen(8000);
}
14. Node.js 中的 Buffer 是什么?
Buffer 是用于處理二進制數據的類。它表示固定長度的字節序列,通常用于處理文件、網絡流等。
const buf = Buffer.from('Hello World', 'utf8');
console.log(buf.toString('hex')); // 輸出: 48656c6c6f20576f726c64
15. Node.js 中的全局對象有哪些?
Node.js 中的全局對象包括 global、process、console、Buffer、setTimeout、setInterval 等。
16. Node.js 中的 process 對象是什么?
process 對象提供了與當前 Node.js 進程相關的信息和控制。它可以用于獲取環境變量、命令行參數、退出進程等。
console.log(process.env.NODE_ENV); // 輸出當前環境
process.exit(0); // 退出進程
17. Node.js 中的 require 是如何工作的?
require 是 Node.js 中用于加載模塊的函數。它首先查找核心模塊,然后查找 node_modules 目錄中的模塊,最后查找本地文件模塊。
const fs = require('fs'); // 核心模塊
const express = require('express'); // node_modules 中的模塊
const myModule = require('./myModule'); // 本地文件模塊
18. Node.js 中的 __dirname 和 __filename 是什么?
__dirname 表示當前模塊文件所在的目錄路徑,__filename 表示當前模塊文件的完整路徑。
javascript
復制
console.log(__dirname); // 輸出當前目錄路徑
console.log(__filename); // 輸出當前文件路徑
19. Node.js 中的 setImmediate 和 setTimeout 有什么區別?
setImmediate 和 setTimeout 都用于調度回調函數的執行,但 setImmediate 會在當前事件循環的末尾執行,而 setTimeout 會在指定的延遲后執行。
setImmediate(() => {console.log('setImmediate');
});setTimeout(() => {console.log('setTimeout');
}, 0);
20. Node.js 中的 child_process 模塊是什么?
child_process 模塊允許創建子進程,執行系統命令或其他 Node.js 腳本。常用的方法有 spawn、exec、execFile 和 fork。
const { exec } = require('child_process');
exec('ls -l', (err, stdout, stderr) => {if (err) {console.error('Error:', err);return;}console.log(stdout);
});
21. Node.js 中的 util 模塊是什么?
util 模塊提供了一些實用函數,如 util.promisify 用于將回調風格的函數轉換為返回 Promise 的函數。
const util = require('util');
const fs = require('fs');
const readFile = util.promisify(fs.readFile);readFile('file.txt', 'utf8').then(data => console.log(data)).catch(err => console.error(err));
22. Node.js 中的 path 模塊是什么?
path 模塊提供了一些用于處理文件路徑的工具函數,如 path.join、path.resolve、path.basename 等。
const path = require('path');
const filePath = path.join(__dirname, 'file.txt');
console.log(filePath); // 輸出當前目錄下的 file.txt 路徑
23. Node.js 中的 os 模塊是什么?
os 模塊提供了一些與操作系統相關的工具函數,如獲取 CPU 信息、內存信息、網絡接口等。
const os = require('os');
console.log(os.platform()); // 輸出操作系統平臺
console.log(os.cpus()); // 輸出 CPU 信息
24. Node.js 中的 crypto 模塊是什么?
crypto 模塊提供了加密功能,如哈希、HMAC、加密、解密等。
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update('Hello World');
console.log(hash.digest('hex')); // 輸出哈希值
25. Node.js 中的 net 模塊是什么?
net 模塊提供了創建 TCP 服務器和客戶端的功能,用于處理網絡通信。
const net = require('net');
const server = net.createServer((socket) => {socket.write('Hello World\n');socket.end();
});server.listen(8000, () => {console.log('Server listening on port 8000');
});
26. Node.js 中的 dns 模塊是什么?
dns 模塊提供了域名解析功能,如將域名解析為 IP 地址。
const dns = require('dns');
dns.lookup('example.com', (err, address) => {if (err) throw err;console.log(address); // 輸出 IP 地址
});
27. Node.js 中的 http 模塊是什么?
http 模塊提供了創建 HTTP 服務器和客戶端的功能,用于處理 HTTP 請求和響應。
const http = require('http');
const server = http.createServer((req, res) => {res.writeHead(200, { 'Content-Type': 'text/plain' });res.end('Hello World\n');
});server.listen(3000, () => {console.log('Server listening on port 3000');
});
28. Node.js 中的 https 模塊是什么?
https 模塊提供了創建 HTTPS 服務器和客戶端的功能,用于處理加密的 HTTP 請求和響應。
const https = require('https');
const fs = require('fs');const options = {key: fs.readFileSync('key.pem'),cert: fs.readFileSync('cert.pem')
};https.createServer(options, (req, res) => {res.writeHead(200);res.end('Hello World\n');
}).listen(443);
29. Node.js 中的 fs 模塊是什么?
fs 模塊提供了文件系統操作的功能,如讀取文件、寫入文件、刪除文件等。
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {if (err) throw err;console.log(data);
});
30. Node.js 中的 zlib 模塊是什么?
zlib 模塊提供了壓縮和解壓縮功能,如 Gzip、Deflate 等。
const zlib = require('zlib');
const fs = require('fs');const gzip = zlib.createGzip();
const input = fs.createReadStream('file.txt');
const output = fs.createWriteStream('file.txt.gz');input.pipe(gzip).pipe(output);
31. Node.js 中的 readline 模塊是什么?
readline 模塊提供了逐行讀取輸入流的功能,通常用于處理命令行輸入。
const readline = require('readline');
const rl = readline.createInterface({input: process.stdin,output: process.stdout
});rl.question('What is your name? ', (name) => {console.log(`Hello, ${name}!`);rl.close();
});
32. Node.js 中的 vm 模塊是什么?
vm 模塊提供了在 V8 虛擬機中運行 JavaScript 代碼的功能,通常用于沙箱環境。
const vm = require('vm');
const script = new vm.Script('x += 1;');const context = { x: 1 };
script.runInNewContext(context);
console.log(context.x); // 輸出: 2
33. Node.js 中的 assert 模塊是什么?
assert 模塊提供了斷言功能,用于測試代碼的正確性。
const assert = require('assert');
assert.strictEqual(1, 1); // 通過
assert.strictEqual(1, 2); // 拋出 AssertionError
34. Node.js 中的 events 模塊是什么?
events 模塊提供了事件驅動的功能,允許對象觸發和監聽事件。
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}const myEmitter = new MyEmitter();
myEmitter.on('event', () => {console.log('An event occurred!');
});myEmitter.emit('event'); // 輸出: An event occurred!
35. Node.js 中的 stream 模塊是什么?
stream 模塊提供了流處理的功能,如可讀流、可寫流、雙工流和轉換流。
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt');readStream.pipe(writeStream);
36. Node.js 中的 timers 模塊是什么?
timers 模塊提供了定時器功能,如 setTimeout、setInterval 和 setImmediate。
setTimeout(() => {console.log('Timeout');
}, 1000);setInterval(() => {console.log('Interval');
}, 1000);setImmediate(() => {console.log('Immediate');
});
37. Node.js 中的 querystring 模塊是什么?
querystring 模塊提供了處理 URL 查詢字符串的功能,如解析和序列化。
const querystring = require('querystring');
const query = querystring.parse('name=John&age=30');
console.log(query); // 輸出: { name: 'John', age: '30' }
38. Node.js 中的 url 模塊是什么?
url 模塊提供了處理 URL 的功能,如解析和格式化。
const url = require('url');
const parsedUrl = url.parse('https://example.com/path?name=John');
console.log(parsedUrl.host); // 輸出: example.com
39. Node.js 中的 util 模塊是什么?
util 模塊提供了一些實用函數,如 util.promisify 用于將回調風格的函數轉換為返回 Promise 的函數。
const util = require('util');
const fs = require('fs');
const readFile = util.promisify(fs.readFile);readFile('file.txt', 'utf8').then(data => console.log(data)).catch(err => console.error(err));
40. Node.js 中的 worker_threads 模塊是什么?
worker_threads 模塊提供了多線程支持,允許在 Node.js 中創建和管理工作線程。
const { Worker, isMainThread, parentPort } = require('worker_threads');if (isMainThread) {const worker = new Worker(__filename);worker.on('message', (message) => {console.log(message); // 輸出: Hello from worker});
} else {parentPort.postMessage('Hello from worker');
}
41. Node.js 中的 cluster 模塊是什么?
cluster 模塊允許創建多個子進程來處理請求,充分利用多核 CPU 的性能。
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;if (cluster.isMaster) {for (let i = 0; i < numCPUs; i++) {cluster.fork();}
} else {http.createServer((req, res) => {res.writeHead(200);res.end('Hello World\n');}).listen(8000);
}
42. Node.js 中的 buffer 模塊是什么?
buffer 模塊提供了處理二進制數據的功能,表示固定長度的字節序列。
const buf
性能優化
1. 明確優化目標與量化指標
首先說明優化的核心目標,并強調數據驅動:
-
目標:提升用戶體驗(如加載速度、交互流暢度)、降低資源消耗(如代碼體積、請求數)、提高可維護性(如代碼規范、架構設計)。
-
量化指標:
-
首屏加載時間(FCP, LCP)降低至 1s 以內
-
頁面完全加載時間(Load)減少 30%
-
代碼體積(Bundle Size)壓縮 40%
-
關鍵接口響應時間縮短 50%
-
Lighthouse 評分提升至 90+
-
示例回答:
“在最近一個電商項目中,我們通過性能監控發現首屏加載時間超過 3 秒,Lighthouse 性能評分僅 45 分。目標是將首屏時間壓縮到 1 秒內,并提升評分至 90+。最終通過靜態資源優化、接口緩存和代碼分割等手段,首屏時間降至 0.8 秒,Lighthouse 評分達到 92。”
2. 分層優化策略(技術細節)
從多維度展開優化方案,體現技術深度:
① 靜態資源優化
-
壓縮與 CDN:
-
使用 Webpack + TerserPlugin 壓縮 JS/CSS,啟用 Brotli/Gzip 壓縮;
-
圖片使用 WebP/AVIF 格式,配合 image-webpack-loader 自動壓縮;
-
靜態資源上傳 CDN,通過 HTTP/2 多路復用提升加載效率。
-
-
按需加載:
-
路由級懶加載(React.lazy + Suspense / Vue 異步組件);
-
非關鍵資源(如埋點、非首屏圖片)延遲加載(IntersectionObserver);
-
第三方庫按需引入(如 lodash-es、antd 的 tree-shaking)。
-
② 代碼與構建優化
-
Bundle 分析:
-
使用 webpack-bundle-analyzer 分析依賴體積,拆分重復代碼(SplitChunksPlugin);
-
動態導入(Dynamic Import)分割業務代碼與第三方庫;
-
升級至 Webpack 5,利用持久化緩存(cache.filesystem)減少構建時間。
-
-
現代語法與工具鏈:
-
使用 ES Module 替代 CommonJS,利用 Vite/Snowpack 提升開發構建速度;
-
通過 Babel 按需編譯,避免全量 Polyfill(@babel/preset-env + useBuiltIns: ‘usage’)。
-
③ 運行時性能優化
-
渲染優化:
-
避免強制同步布局(如減少 offsetWidth 讀取,使用 FastDom 庫);
-
高頻操作防抖/節流(如滾動事件、ResizeObserver);
-
復雜列表使用虛擬滾動(react-window / vue-virtual-scroller)。
-
-
內存管理:
-
及時銷毀全局事件監聽、定時器;
-
使用 Chrome DevTools Memory 面板分析內存泄漏;
-
大數據列表采用分頁或增量渲染。
-
④ 網絡層優化
-
接口聚合與緩存:
-
GraphQL/BFF 層聚合分散接口,減少 HTTP 請求;
-
瀏覽器緩存(Cache-Control, ETag)與 Service Worker 離線緩存(Workbox);
-
預加載關鍵資源()。
-
-
協議升級:
-
升級至 HTTP/2 + TLS 1.3,啟用 QUIC(如 Cloudflare 支持);
-
使用 Server Push 推送關鍵資源。
-
⑤ 用戶體驗增強
-
加載態優化:
-
骨架屏(Skeleton Screen)占位,避免布局抖動;
-
關鍵數據優先渲染(如先展示文字,圖片懶加載 + 漸進式加載)。
-
-
交互反饋:
-
長任務使用 Web Worker 分解(如大數據計算);
-
點擊/滾動添加微交互動畫(CSS Transition,避免 JS 動畫)。
-
- 工具鏈與監控
-
性能監控:
-
接入 Sentry 監控異常,Google Analytics 統計性能數據;
-
使用 Performance API 自定義指標(如 FCP、FID);
-
定時跑 Lighthouse CI,集成到 Jenkins/GitHub Actions。
-
-
自動化優化:
-
通過 Critical CSS 工具提取首屏關鍵樣式內聯;
-
使用 Preact 替代 React 輕量化(針對低端設備場景)。
-
4. 實際案例與難點突破
結合具體項目,突出技術決策和問題解決能力:
案例:
“在某個中后臺項目中,首屏加載慢的原因是全量引入了 Moment.js 和 Antd。優化措施包括:
-
用 day.js 替代 Moment.js,減少 200KB;
-
配置 Antd 按需加載 + babel-plugin-import;
-
將非首屏組件拆分為獨立 Chunk;
-
啟用 Brotli 壓縮后,主 Bundle 從 1.8MB 降至 600KB。首屏時間從 2.5s 優化至 0.9s。”
難點與解決:
“曾遇到 Webpack 編譯慢的問題,通過分析發現是 Sass 嵌套過深導致。解決方案:
-
使用 dart-sass 替代 node-sass;
-
拆分全局 Sass 變量與混合器,避免重復編譯;
-
開啟 thread-loader 并行處理,構建時間減少 60%。”
5. 總結與未來規劃
-
成果總結:用數據量化結果(如“PV 跳出率降低 20%”);
-
持續優化:關注 Web Vitals 指標、探索 WASM/Edge Computing 等新技術;
-
團隊協作:推動 Code Review 中添加性能檢查項,制定性能基線。
回答示例:
“在前端優化中,我會先通過 Lighthouse 和 Web Vitals 定位瓶頸,分優先級制定方案。例如,針對首屏加載,我會優先優化關鍵資源(如內聯 CSS、預加載字體),用代碼分割減少主包體積;針對運行時性能,通過虛擬列表和防抖優化長列表滾動。在最近的項目中,通過 Service Worker 緩存接口數據,接口平均響應時間從 800ms 降至 200ms。未來計劃引入 RUM(Real User Monitoring)更精準監控性能瓶頸。”