Node.js面試題及詳細答案120題(16-30) -- 核心模塊篇

前后端面試題》專欄集合了前后端各個知識模塊的面試題,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。

前后端面試題-專欄總目錄

在這里插入圖片描述

文章目錄

  • 一、本文面試題目錄
      • 16. Node.js的核心模塊有哪些?請舉例說明其用途。
      • 17. `fs`模塊的作用是什么?它的同步和異步方法有什么區別?
      • 18. 如何使用`fs`模塊讀取大文件?為什么不推薦用同步方法讀取大文件?
      • 19. `path`模塊的常用方法有哪些?它們的作用是什么?
      • 20. `http`模塊如何創建一個簡單的Web服務器?
      • 21. 如何處理`http`請求中的GET和POST參數?
        • 處理GET參數
        • 處理POST參數
      • 22. `url`模塊的作用是什么?如何解析URL字符串?
      • 23. `querystring`模塊如何解析查詢字符串?
      • 24. `events`模塊的作用是什么?如何自定義事件?
      • 25. 什么是EventEmitter?它的常用方法有哪些?
      • 26. `stream`模塊的作用是什么?它有哪幾種類型?
      • 27. 為什么說流(Stream)適合處理大文件?請舉例說明流的使用場景。
      • 28. `buffer`模塊的作用是什么?它和字符串有什么區別?
      • 29. 如何在Node.js中操作Buffer?請舉例說明常用方法。
        • 1. 創建Buffer
        • 2. 讀寫Buffer
        • 3. 復制Buffer
        • 4. 切片Buffer
        • 5. 拼接Buffer
        • 6. 比較Buffer
      • 30. `util`模塊的`util.promisify`方法有什么作用?
  • 二、120道Node.js面試題目錄列表

一、本文面試題目錄

16. Node.js的核心模塊有哪些?請舉例說明其用途。

Node.js 提供了眾多核心模塊,這些模塊由 Node.js 官方開發,無需額外安裝即可使用,主要用于處理文件、網絡、事件等基礎功能。以下是常用核心模塊及其用途:

  • fs:文件系統模塊,用于讀寫文件、操作目錄等(如 fs.readFile 讀取文件,fs.writeFile 寫入文件)。
  • path:路徑處理模塊,用于解析和拼接文件路徑(如 path.join 拼接路徑,path.resolve 獲取絕對路徑)。
  • http:HTTP 協議模塊,用于創建 Web 服務器和客戶端(如 http.createServer 創建服務器)。
  • https:HTTPS 協議模塊,功能類似 http,但支持加密傳輸。
  • url:URL 解析模塊,用于解析 URL 字符串(如 url.parse 解析 URL 為對象)。
  • querystring:查詢字符串模塊,用于解析和序列化 URL 中的查詢參數(如 querystring.parse 解析查詢字符串)。
  • events:事件處理模塊,提供事件觸發和監聽機制(核心是 EventEmitter 類)。
  • stream:流模塊,用于處理流式數據(如文件流、網絡流),適合大文件處理。
  • buffer:緩沖區模塊,用于處理二進制數據(如網絡傳輸、文件讀寫中的二進制數據)。
  • util:工具模塊,提供實用工具函數(如 util.promisify 將回調函數轉為 Promise)。
  • os:操作系統模塊,用于獲取系統信息(如 os.cpus 獲取 CPU 信息,os.totalmem 獲取總內存)。
  • process:進程模塊,提供當前 Node.js 進程的信息和控制方法(如 process.env 環境變量,process.exit 退出進程)。

示例:使用多個核心模塊

const fs = require('fs');
const path = require('path');
const os = require('os');// 讀取當前目錄下的文件
const filePath = path.join(__dirname, 'example.txt');
fs.readFile(filePath, 'utf8', (err, data) => {if (err) throw err;console.log('文件內容:', data);
});// 輸出系統信息
console.log('CPU 核心數:', os.cpus().length);
console.log('總內存(GB):', os.totalmem() / (1024 **3).toFixed(2));

17. fs模塊的作用是什么?它的同步和異步方法有什么區別?

fs(File System)模塊是 Node.js 用于與文件系統交互的核心模塊,提供了文件讀寫、目錄操作、權限管理等功能。它的方法分為同步異步兩種形式。

同步方法與異步方法的區別

區別同步方法異步方法
執行方式阻塞主線程,需等待操作完成后才繼續執行非阻塞主線程,操作在后臺執行,完成后通過回調通知
命名規則方法名末尾加 Sync(如 readFileSync方法名無特殊后綴(如 readFile
錯誤處理通過 try/catch 捕獲錯誤通過回調函數的第一個參數返回錯誤
返回值直接返回操作結果結果通過回調函數的參數返回
適用場景簡單腳本、初始化操作(不影響并發的場景)服務器環境、高并發場景(避免阻塞主線程)

示例:同步與異步讀取文件

const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, 'test.txt');// 同步讀取
try {const data = fs.readFileSync(filePath, 'utf8');console.log('同步讀取結果:', data);
} catch (err) {console.error('同步讀取錯誤:', err);
}// 異步讀取
fs.readFile(filePath, 'utf8', (err, data) => {if (err) {console.error('異步讀取錯誤:', err);return;}console.log('異步讀取結果:', data);
});

18. 如何使用fs模塊讀取大文件?為什么不推薦用同步方法讀取大文件?

讀取大文件(如幾個 GB 的文件)時,不適合一次性將文件內容加載到內存中,而應使用流(Stream) 進行分塊讀取,以降低內存占用。

使用流讀取大文件的示例

const fs = require('fs');
const path = require('path');const largeFilePath = path.join(__dirname, 'large-file.txt');// 創建可讀流
const readStream = fs.createReadStream(largeFilePath, {encoding: 'utf8',  // 編碼格式highWaterMark: 64 * 1024  // 每次讀取的緩沖區大小(默認64KB)
});// 監聽數據事件(每讀取一塊數據觸發)
readStream.on('data', (chunk) => {console.log(`讀取到 ${chunk.length} 字節的數據`);// 處理數據(如解析、過濾等)
});// 監聽結束事件
readStream.on('end', () => {console.log('文件讀取完成');
});// 監聽錯誤事件
readStream.on('error', (err) => {console.error('讀取錯誤:', err);
});

不推薦用同步方法讀取大文件的原因
1.** 阻塞主線程 :同步方法(如 readFileSync)會阻塞 Node.js 主線程,直到文件讀取完成,期間無法處理其他請求,嚴重影響應用的并發能力。
2.
內存占用過高 :同步方法會將整個文件內容加載到內存中,大文件可能導致內存溢出(OOM),使應用崩潰。
3.
性能低下**:一次性讀取大文件需要分配大量內存,且數據處理效率低,而流的分塊處理更輕量、高效。

19. path模塊的常用方法有哪些?它們的作用是什么?

path 模塊用于處理文件路徑,解決不同操作系統(如 Windows 和 Linux)路徑分隔符差異(\/)的問題,提供了跨平臺的路徑處理能力。

常用方法及作用

  1. path.join([...paths])

    • 拼接多個路徑片段,自動處理分隔符,返回規范化的路徑。
    path.join('/a', 'b', 'c'); // 輸出:'/a/b/c'
    path.join('/a', '../b');   // 輸出:'/b'(解析上層目錄)
    
  2. path.resolve([...paths])

    • 將路徑片段解析為絕對路徑,以當前工作目錄為基準。
    path.resolve('file.txt');        // 輸出:'/當前工作目錄/file.txt'
    path.resolve('/a', 'b', '../c'); // 輸出:'/a/c'
    
  3. path.basename(path[, ext])

    • 返回路徑中的文件名(包含擴展名),可選參數 ext 可去除擴展名。
    path.basename('/a/b/c.txt');   // 輸出:'c.txt'
    path.basename('/a/b/c.txt', '.txt'); // 輸出:'c'
    
  4. path.dirname(path)

    • 返回路徑中的目錄部分。
    path.dirname('/a/b/c.txt'); // 輸出:'/a/b'
    
  5. path.extname(path)

    • 返回路徑中的文件擴展名(包含 .),無擴展名則返回空字符串。
    path.extname('file.txt');   // 輸出:'.txt'
    path.extname('file');       // 輸出:''
    path.extname('file.md.txt');// 輸出:'.txt'
    
  6. path.parse(path)

    • 將路徑解析為包含 rootdirbasenameext 的對象。
    path.parse('/a/b/c.txt');
    // 輸出:
    // {
    //   root: '/',
    //   dir: '/a/b',
    //   base: 'c.txt',
    //   name: 'c',
    //   ext: '.txt'
    // }
    
  7. path.format(pathObject)

    • path.parse 生成的對象轉換為路徑字符串。
    path.format({ dir: '/a/b', base: 'c.txt' }); // 輸出:'/a/b/c.txt'
    

示例:綜合使用 path 模塊

const path = require('path');const filePath = '/user/docs/report.pdf';console.log('文件名:', path.basename(filePath)); // 'report.pdf'
console.log('目錄:', path.dirname(filePath));   // '/user/docs'
console.log('擴展名:', path.extname(filePath)); // '.pdf'
console.log('拼接路徑:', path.join(path.dirname(filePath), 'archive', 'old.pdf')); 
// '/user/docs/archive/old.pdf'

20. http模塊如何創建一個簡單的Web服務器?

http 模塊是 Node.js 用于構建 HTTP 服務器和客戶端的核心模塊,通過 http.createServer() 方法可快速創建 Web 服務器。

創建簡單Web服務器的步驟

  1. 引入 http 模塊。
  2. 使用 http.createServer() 創建服務器實例,傳入請求處理函數(接收 req 請求對象和 res 響應對象)。
  3. 調用 server.listen() 方法指定端口和主機,啟動服務器。

示例

const http = require('http');// 創建服務器
const server = http.createServer((req, res) => {// 設置響應頭(狀態碼 200,內容類型為文本)res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });// 根據 URL 路徑返回不同內容if (req.url === '/') {res.end('歡迎訪問首頁!\n');} else if (req.url === '/about') {res.end('關于我們\n');} else {res.writeHead(404, { 'Content-Type': 'text/plain' });res.end('404 頁面未找到\n');}
});// 啟動服務器,監聽 3000 端口
const PORT = 3000;
server.listen(PORT, 'localhost', () => {console.log(`服務器運行在 http://localhost:${PORT}`);
});

關鍵對象說明

  • req(IncomingMessage):請求對象,包含請求方法、URL、頭信息等(如 req.methodreq.url)。
  • res(ServerResponse):響應對象,用于發送響應(如 res.writeHead() 設置響應頭,res.end() 發送響應體并結束響應)。

運行上述代碼后,訪問 http://localhost:3000 可看到首頁內容,訪問 http://localhost:3000/about 可看到關于頁面。

21. 如何處理http請求中的GET和POST參數?

在 Node.js 的 http 模塊中,GET 和 POST 參數的處理方式不同:GET 參數位于 URL 中,POST 參數位于請求體中。

處理GET參數

GET 參數通過 URL 的查詢字符串(?key=value&key2=value2)傳遞,可使用 url 模塊或 querystring 模塊解析。

示例

const http = require('http');
const url = require('url');
const querystring = require('querystring');const server = http.createServer((req, res) => {if (req.method === 'GET') {// 解析 URL(第二個參數為 true 時自動解析 query 為對象)const parsedUrl = url.parse(req.url, true);const query = parsedUrl.query; // 獲取 GET 參數對象res.writeHead(200, { 'Content-Type': 'application/json' });res.end(JSON.stringify({message: 'GET 請求參數',params: query}));}
});server.listen(3000, () => {console.log('服務器運行在 http://localhost:3000');
});

訪問 http://localhost:3000?name=Alice&age=20,將返回解析后的 GET 參數。

處理POST參數

POST 參數位于請求體中,需通過監聽 req 對象的 data 事件(接收數據塊)和 end 事件(數據接收完成)來獲取,再用 querystring 解析。

示例

const http = require('http');
const querystring = require('querystring');const server = http.createServer((req, res) => {if (req.method === 'POST') {let body = '';// 接收數據塊req.on('data', (chunk) => {body += chunk;});// 數據接收完成req.on('end', () => {// 解析 POST 參數(默認解析 form-data 格式)const postData = querystring.parse(body);res.writeHead(200, { 'Content-Type': 'application/json' });res.end(JSON.stringify({message: 'POST 請求參數',params: postData}));});}
});server.listen(3000, () => {console.log('服務器運行在 http://localhost:3000');
});

可通過 POST 工具(如 Postman)發送 name=Bob&age=25 表單數據,服務器將返回解析結果。

注意:對于 JSON 格式的 POST 數據(如 {"name":"Bob"}),需手動解析:

// 在 end 事件中
const postData = JSON.parse(body); // 適用于 Content-Type: application/json

22. url模塊的作用是什么?如何解析URL字符串?

url 模塊用于處理 URL 字符串,提供了解析 URL、格式化 URL 等功能,可將 URL 字符串轉換為對象(便于獲取各部分信息),或反之。

主要作用

  • 解析 URL 字符串為對象,提取協議、主機、路徑、查詢參數等部分。
  • 將 URL 對象格式化為 URL 字符串。
  • 處理不同格式的 URL(如絕對 URL、相對 URL)。

解析URL字符串的方法
使用 url.parse(urlString[, parseQueryString[, slashesDenoteHost]]) 方法:

  • urlString:要解析的 URL 字符串。
  • parseQueryString:可選,默認為 false,若為 true,則將查詢字符串解析為對象。
  • slashesDenoteHost:可選,默認為 false,用于處理無協議的 URL。

示例

const url = require('url');const urlString = 'https://user:pass@example.com:8080/path?name=Alice&age=20#hash';// 解析 URL(parseQueryString 設為 true,自動解析查詢參數)
const parsedUrl = url.parse(urlString, true);console.log('解析結果:', parsedUrl);
/* 輸出主要屬性:
{protocol: 'https:',        // 協議auth: 'user:pass',         // 用戶名:密碼host: 'example.com:8080',  // 主機名:端口hostname: 'example.com',   // 主機名port: '8080',              // 端口pathname: '/path',         // 路徑search: '?name=Alice&age=20', // 查詢字符串(含?)query: { name: 'Alice', age: '20' }, // 解析后的查詢參數對象hash: '#hash'              // 哈希(含#)
}
*/// 將 URL 對象轉換為字符串
const formattedUrl = url.format(parsedUrl);
console.log('格式化結果:', formattedUrl); // 輸出原始 URL 字符串

注意:Node.js v11.0.0 后推薦使用 WHATWG URL 標準 API(new URL(urlString)),功能更完善:

const myUrl = new URL('https://example.com/path?name=Alice');
console.log(myUrl.searchParams.get('name')); // 'Alice'(獲取查詢參數)

23. querystring模塊如何解析查詢字符串?

querystring 模塊用于處理 URL 中的查詢字符串(如 name=Alice&age=20),提供了解析(字符串轉對象)和序列化(對象轉字符串)功能。

常用方法

  1. querystring.parse(str[, sep[, eq[, options]]])

    • 解析查詢字符串為對象。
    • str:要解析的查詢字符串。
    • sep:分隔符,默認為 &
    • eq:鍵值分隔符,默認為 =
    • options:可選配置(如 maxKeys 限制解析的鍵數量)。

    示例

    const querystring = require('querystring');const str = 'name=Alice&age=20&hobby=reading&hobby=sports';
    const obj = querystring.parse(str);
    console.log(obj);
    // 輸出:{ name: 'Alice', age: '20', hobby: [ 'reading', 'sports' ] }
    
  2. querystring.stringify(obj[, sep[, eq[, options]]])

    • 將對象序列化為查詢字符串。
    • obj:要序列化的對象。
    • sep:分隔符,默認為 &
    • eq:鍵值分隔符,默認為 =

    示例

    const querystring = require('querystring');const obj = { name: 'Bob', age: 25, hobby: ['music', 'games'] };
    const str = querystring.stringify(obj);
    console.log(str);
    // 輸出:'name=Bob&age=25&hobby=music&hobby=games'
    
  3. querystring.escape(str)

    • 對字符串進行 URL 編碼(將特殊字符轉換為 %xx 格式)。
    querystring.escape('a b=c'); // 輸出:'a%20b%3Dc'
    
  4. querystring.unescape(str)

    • 對 URL 編碼的字符串進行解碼。
    querystring.unescape('a%20b%3Dc'); // 輸出:'a b=c'
    

注意querystring 適合解析簡單的查詢字符串,對于復雜場景(如嵌套對象),建議使用 qs 等第三方庫。

24. events模塊的作用是什么?如何自定義事件?

events 模塊是 Node.js 實現事件驅動架構的核心,提供了事件的觸發、監聽、移除等功能,其核心是 EventEmitter 類。

主要作用

  • 實現對象間的事件通信(發布-訂閱模式)。
  • 支持自定義事件,通過觸發事件執行回調函數。
  • 是許多 Node.js 核心模塊(如 fshttp)的基礎(這些模塊的對象繼承自 EventEmitter)。

自定義事件的步驟

  1. 引入 events 模塊,創建 EventEmitter 實例。
  2. 使用 on()addListener() 方法監聽事件。
  3. 使用 emit() 方法觸發事件,可傳遞參數。

示例

const EventEmitter = require('events');// 創建 EventEmitter 實例
const myEmitter = new EventEmitter();// 監聽 'greet' 事件(第一個參數為事件名,第二個為回調函數)
myEmitter.on('greet', (name) => {console.log(`Hello, ${name}!`);
});// 監聽 'sum' 事件,處理數字相加
myEmitter.on('sum', (a, b) => {console.log(`${a} + ${b} = ${a + b}`);
});// 觸發事件(第一個參數為事件名,后續為傳遞給回調的參數)
myEmitter.emit('greet', 'Alice'); // 輸出:Hello, Alice!
myEmitter.emit('sum', 3, 5);      // 輸出:3 + 5 = 8// 一次性事件(觸發后自動移除)
myEmitter.once('single', () => {console.log('這個事件只會觸發一次');
});
myEmitter.emit('single'); // 輸出:這個事件只會觸發一次
myEmitter.emit('single'); // 無輸出(事件已移除)

注意EventEmitter 有默認的事件監聽器數量限制(默認 10 個),超過時會觸發警告,可通過 setMaxListeners(n) 調整。

25. 什么是EventEmitter?它的常用方法有哪些?

EventEmitterevents 模塊提供的一個類,是 Node.js 事件驅動模型的核心,用于實現事件的發布(觸發)和訂閱(監聽)。Node.js 中的許多核心對象(如 http.Serverfs.ReadStream)都繼承自 EventEmitter

常用方法

  1. on(eventName, listener)

    • 為指定事件注冊一個監聽器(回調函數),可多次調用注冊多個監聽器。
    emitter.on('data', (chunk) => { console.log(chunk); });
    
  2. emit(eventName[, ...args])

    • 觸發指定事件,可傳遞多個參數給監聽器。返回 true 表示事件有監聽器,否則為 false
    emitter.emit('data', 'hello'); // 觸發 'data' 事件,傳遞 'hello'
    
  3. once(eventName, listener)

    • 為指定事件注冊一個一次性監聽器,觸發一次后自動移除。
    emitter.once('init', () => { console.log('初始化完成'); });
    
  4. off(eventName, listener)(或 removeListener):

    • 移除指定事件的某個監聽器(需傳入監聽器的引用)。
    const listener = () => { console.log('監聽'); };
    emitter.on('event', listener);
    emitter.off('event', listener); // 移除監聽器
    
  5. removeAllListeners([eventName])

    • 移除指定事件的所有監聽器,若未指定事件名,則移除所有事件的監聽器。
    emitter.removeAllListeners('data'); // 移除 'data' 事件的所有監聽器
    
  6. setMaxListeners(n)

    • 設置事件監聽器的最大數量(默認 10 個),超過時的警告可通過此方法關閉(設為 Infinity)。
    emitter.setMaxListeners(20); // 允許最多 20 個監聽器
    
  7. listeners(eventName)

    • 返回指定事件的所有監聽器數組。
    console.log(emitter.listeners('data')); // 輸出 'data' 事件的監聽器數組
    

示例:綜合使用 EventEmitter 方法

const EventEmitter = require('events');
const emitter = new EventEmitter();// 定義監聽器函數
const logMessage = (msg) => {console.log('收到消息:', msg);
};// 注冊監聽器
emitter.on('message', logMessage);
emitter.on('message', (msg) => {console.log('消息長度:', msg.length);
});// 觸發事件
emitter.emit('message', 'Hello EventEmitter');
// 輸出:
// 收到消息: Hello EventEmitter
// 消息長度: 18// 移除監聽器
emitter.off('message', logMessage);
emitter.emit('message', '再次發送');
// 輸出:
// 消息長度: 4

26. stream模塊的作用是什么?它有哪幾種類型?

stream(流)模塊是 Node.js 用于處理流式數據的核心模塊,通過分塊讀取/寫入數據,降低內存占用,提高處理效率,尤其適合大文件或持續的數據流(如網絡傳輸)。

主要作用

  • 分塊處理數據,避免一次性加載大量數據到內存。
  • 支持管道(pipe)操作,可將一個流的輸出直接作為另一個流的輸入(如文件壓縮、網絡傳輸)。
  • 提供統一的接口處理不同類型的數據流(文件、網絡、內存等)。

流的四種類型

  1. Readable(可讀流)

    • 用于讀取數據的流(如 fs.createReadStream 讀取文件)。
    • 狀態:paused(暫停)和 flowing(流動),數據通過 data 事件傳遞。
  2. Writable(可寫流)

    • 用于寫入數據的流(如 fs.createWriteStream 寫入文件)。
    • 通過 write() 方法寫入數據,end() 方法結束寫入。
  3. Duplex(雙工流)

    • 同時具備可讀和可寫能力的流(如 TCP 套接字 net.Socket)。
    • 可讀和可寫部分相互獨立,分別遵循各自的接口。
  4. Transform(轉換流)

    • 一種特殊的雙工流,用于修改或轉換數據(如 zlib.createGzip 壓縮數據)。
    • 讀取數據后進行處理,再輸出處理后的結果。

示例:使用可讀流和可寫流復制文件

const fs = require('fs');
const path = require('path');// 創建可讀流(源文件)
const readStream = fs.createReadStream(path.join(__dirname, 'source.txt'));
// 創建可寫流(目標文件)
const writeStream = fs.createWriteStream(path.join(__dirname, 'copy.txt'));// 監聽數據事件,將讀取的塊寫入可寫流
readStream.on('data', (chunk) => {writeStream.write(chunk);
});// 讀取完成后結束寫入
readStream.on('end', () => {writeStream.end();console.log('文件復制完成');
});// 簡化寫法:使用 pipe 自動處理數據傳遞
// readStream.pipe(writeStream);

27. 為什么說流(Stream)適合處理大文件?請舉例說明流的使用場景。

流(Stream)適合處理大文件的核心原因是其分塊處理數據的特性,無需將整個文件加載到內存中,而是逐塊讀取、處理和寫入,顯著降低內存占用并提高效率。

流適合處理大文件的原因

  1. 低內存占用:大文件(如 10GB)無法一次性加載到內存,流通過每次讀取一小塊數據(默認 64KB),內存占用保持穩定。
  2. 高效處理:數據可邊讀取邊處理(如解析、過濾),無需等待整個文件加載完成,減少處理延遲。
  3. 管道操作:支持 pipe() 方法將多個流串聯(如讀取 → 壓縮 → 寫入),簡化大文件處理流程。

流的典型使用場景

1.** 大文件復制 **:

const fs = require('fs');
// 使用 pipe 快速復制大文件
fs.createReadStream('large-file.iso').pipe(fs.createWriteStream('copy-large-file.iso'));

2.** 日志實時處理 **:
監聽日志文件的新增內容并實時分析(如監控系統)。

const fs = require('fs');
const readStream = fs.createReadStream('app.log', { tail: true }); // 模擬尾行監聽
readStream.on('data', (chunk) => {console.log('新日志:', chunk.toString());// 實時分析邏輯(如錯誤檢測)
});

3.** 數據壓縮/解壓 **:
結合 zlib 模塊對流數據進行壓縮(無需加載整個文件到內存)。

const fs = require('fs');
const zlib = require('zlib');
// 讀取文件 → 壓縮 → 寫入壓縮文件
fs.createReadStream('large-file.txt').pipe(zlib.createGzip()).pipe(fs.createWriteStream('large-file.txt.gz'));

4.** 網絡數據傳輸 **:
HTTP 服務器中通過流發送大文件(如視頻、下載資源)。

const http = require('http');
const fs = require('fs');
http.createServer((req, res) => {if (req.url === '/video') {res.writeHead(200, { 'Content-Type': 'video/mp4' });// 以流的形式發送視頻文件fs.createReadStream('large-video.mp4').pipe(res);}
}).listen(3000);

5.** 數據轉換 **:
處理 CSV 大文件并轉換為 JSON 格式。

const fs = require('fs');
const readline = require('readline'); // 逐行讀取流
const rl = readline.createInterface({input: fs.createReadStream('large-data.csv'),crlfDelay: Infinity
});
rl.on('line', (line) => {// 每行轉換為 JSON 并處理const json = convertCsvToJson(line);console.log(json);
});

28. buffer模塊的作用是什么?它和字符串有什么區別?

buffer 模塊是 Node.js 用于處理二進制數據的核心模塊,提供了 Buffer 類(無需 require 即可使用),用于存儲和操作二進制數據。在處理文件、網絡傳輸、加密等場景中,二進制數據是基礎,Buffer 解決了 JavaScript 原生不支持二進制數據的問題。

Buffer 與字符串的區別

區別Buffer字符串(String)
數據類型二進制數據(字節序列)Unicode 字符序列(文本數據)
編碼方式可通過編碼(如 utf8base64)轉換為字符串本質是 Unicode 編碼,可通過 Buffer.from() 轉為 Buffer
長度計算length 屬性返回字節數length 屬性返回字符數(可能與字節數不同)
不可變性長度固定,內容可修改(內存分配后大小不變)不可變,修改會創建新字符串
適用場景二進制數據(文件、網絡、加密)文本數據(用戶輸入、顯示內容)

示例:Buffer 與字符串的轉換

// 字符串轉 Buffer(默認 utf8 編碼)
const str = 'Hello 世界';
const buf = Buffer.from(str);
console.log('Buffer 內容:', buf); // <Buffer 48 65 6c 6c 6f 20 e4 b8 96 e7 95 8c>
console.log('Buffer 字節數:', buf.length); // 11('Hello ' 占 6 字節,'世界' 占 6 字節?此處實際為11字節,因UTF8編碼中漢字占3字節)// Buffer 轉字符串
const str2 = buf.toString('utf8');
console.log('轉換后的字符串:', str2); // 'Hello 世界'// 不同編碼的轉換
const base64Str = buf.toString('base64');
console.log('Base64 編碼:', base64Str); // 'SGVsbG8g5LiW55WM'
const buf2 = Buffer.from(base64Str, 'base64');
console.log(buf2.toString('utf8')); // 'Hello 世界'

注意:字符串的 length 可能與對應的 Buffer 字節數不同(如中文在 UTF8 中占 3 字節),例如 '世界'.length 為 2,而 Buffer.from('世界').length 為 6。

29. 如何在Node.js中操作Buffer?請舉例說明常用方法。

Buffer 是 Node.js 中處理二進制數據的核心類,提供了豐富的方法用于創建、讀寫、轉換 Buffer。以下是常用操作及示例:

1. 創建Buffer
  • Buffer.alloc(size):創建指定大小的空 Buffer(已初始化,默認填充 0)。
  • Buffer.allocUnsafe(size):創建指定大小的 Buffer(未初始化,可能包含舊數據,速度更快)。
  • Buffer.from(data):從數據(字符串、數組、Buffer 等)創建 Buffer。
// 創建 10 字節的空 Buffer
const buf1 = Buffer.alloc(10);
console.log(buf1); // <Buffer 00 00 00 00 00 00 00 00 00 00>// 從字符串創建 Buffer
const buf2 = Buffer.from('hello');
console.log(buf2); // <Buffer 68 65 6c 6c 6f>// 從數組創建 Buffer(數組元素為 0-255 的整數)
const buf3 = Buffer.from([0x68, 0x65, 0x6c]); // 對應 'hel'
console.log(buf3.toString()); // 'hel'
2. 讀寫Buffer

Buffer 可通過索引讀寫字節(0-255 的整數)。

const buf = Buffer.alloc(4);// 寫入字節
buf[0] = 0x48; // 'H' 的 ASCII 碼
buf[1] = 0x65; // 'e'
buf[2] = 0x6c; // 'l'
buf[3] = 0x6c; // 'l'console.log(buf.toString()); // 'Hell'// 讀取字節
console.log(buf[0]); // 72(0x48 的十進制)
console.log(String.fromCharCode(buf[0])); // 'H'
3. 復制Buffer

buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]]):復制一個 Buffer 的內容到另一個 Buffer。

const srcBuf = Buffer.from('hello');
const destBuf = Buffer.alloc(5);srcBuf.copy(destBuf); // 復制整個 srcBuf 到 destBuf
console.log(destBuf.toString()); // 'hello'// 部分復制(復制 'llo' 到 destBuf 的起始位置 2)
const destBuf2 = Buffer.alloc(5, 'he'); // 初始化為 'he'
srcBuf.copy(destBuf2, 2, 2, 5); // targetStart=2, sourceStart=2, sourceEnd=5
console.log(destBuf2.toString()); // 'hello'
4. 切片Buffer

buf.slice([start[, end]]):返回 Buffer 的一部分(與原 Buffer 共享內存,修改會影響原 Buffer)。

const buf = Buffer.from('hello world');
const slice = buf.slice(6, 11); // 從索引 6 到 10(不包含11)
console.log(slice.toString()); // 'world'// 修改切片會影響原 Buffer
slice[0] = 0x57; // 'W' 的 ASCII 碼
console.log(buf.toString()); // 'hello World'
5. 拼接Buffer

Buffer.concat(list[, totalLength]):拼接多個 Buffer 為一個新 Buffer。

const buf1 = Buffer.from('Hello ');
const buf2 = Buffer.from('World');
const combined = Buffer.concat([buf1, buf2]);
console.log(combined.toString()); // 'Hello World'
6. 比較Buffer

buf.compare(otherBuffer):比較兩個 Buffer,返回數值(-1:當前小,0:相等,1:當前大)。

const buf1 = Buffer.from('abc');
const buf2 = Buffer.from('abd');
console.log(buf1.compare(buf2)); // -1('abc' < 'abd')

30. util模塊的util.promisify方法有什么作用?

util.promisify 是 Node.js util 模塊提供的工具函數,用于將遵循 Node.js 回調風格(即最后一個參數為回調函數,且回調的第一個參數為錯誤對象)的函數轉換為返回 Promise 的函數,便于使用 async/await 語法處理異步操作。

作用

  • 簡化異步代碼,將回調地獄(Callback Hell)轉換為更易讀的 async/await 形式。
  • 統一異步編程風格,兼容 Promise 生態。

使用條件
被轉換的函數必須符合 Node.js 回調規范:

  • 函數的最后一個參數是回調函數。
  • 回調函數的第一個參數是錯誤對象(err),后續參數是結果。

示例:將回調風格的函數轉為 Promise

const util = require('util');
const fs = require('fs');// 回調風格的函數(fs.readFile)
fs.readFile('example.txt', 'utf8', (err, data) => {if (err) throw err;console.log('回調方式讀取:', data);
});// 使用 util.promisify 轉換為 Promise 風格
const readFileAsync = util.promisify(fs.readFile);// 使用 Promise.then()
readFileAsync('example.txt', 'utf8').then(data => console.log('Promise 方式讀取:', data)).catch(err => console.error('錯誤:', err));// 使用 async/await(更簡潔)
async function readFile() {try {const data = await readFileAsync('example.txt', 'utf8');console.log('async/await 方式讀取:', data);} catch (err) {console.error('錯誤:', err);}
}
readFile();

自定義回調函數的轉換

const util = require('util');// 自定義回調風格函數(符合規范)
function fetchData(callback) {setTimeout(() => {const err = null;const data = '模擬數據';callback(err, data); // 第一個參數為 err,第二個為結果}, 1000);
}// 轉換為 Promise 函數
const fetchDataAsync = util.promisify(fetchData);// 使用 async/await
async function main() {const data = await fetchDataAsync();console.log(data); // '模擬數據'
}
main();

注意:Node.js v10.0.0 后,許多核心模塊提供了內置的 Promise 版本(如 fs.promises),可直接使用,無需手動轉換。

二、120道Node.js面試題目錄列表

文章序號Node.js面試題120道
1Node.js面試題及詳細答案120道(01-15)
2Node.js面試題及詳細答案120道(16-30)
3Node.js面試題及詳細答案120道(31-42)
4Node.js面試題及詳細答案120道(43-55)
5Node.js面試題及詳細答案120道(56-68)
6Node.js面試題及詳細答案120道(69-80)
7Node.js面試題及詳細答案120道(81-92)
8Node.js面試題及詳細答案120道(93-100)
9Node.js面試題及詳細答案120道(101-110)
10Node.js面試題及詳細答案120道(111-120)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918988.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918988.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918988.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RabbitMQ:Windows版本安裝部署

目錄一、概述二、OPT三、安裝RabbitMQ四、登錄測試一、概述 什么是MQ&#xff0c;有什么做作用&#xff1f; MQ即MessageQueue&#xff0c;消息隊列。可以分為兩部分理解&#xff1a;消息Message用于在不同的應用程序中傳遞數據。隊列Queue&#xff0c;一種FIFO先進先出的數據…

酒店行業安全體系構建與優化策略

酒店行業安全體系構建與優化策略為確保酒店行業領導及賓客的安全&#xff0c;構建全面的治安聯防體系及事故處理預案至關重要。某招待所通過設立保衛部&#xff0c;細化內保、治安、防火及交通管理職能&#xff0c;并下設警衛班、監控中心和電瓶車班&#xff0c;以全方位保障安…

python30-正則表達式

在Python中需要通過正則表達式對字符串進?匹配的時候&#xff0c;可以使??個python自帶的模塊&#xff0c;名字為re。 re模塊的使用&#xff1a;import re 一、匹配函數 1-1、re.match函數&#xff1a;返回匹配對象 match函數實現的是精準匹配&#xff0c;嘗試從字符串的…

EP1C12F324I7N Altera Cyclone FPGA

EP1C12F324I7N 是 阿爾特拉 Altera Cyclone 系列中的一款 SRAM-based FPGA&#xff0c;定位為低成本、低功耗、面向嵌入式與消費/工業類量產應用的器件。該器件提供約 12,060 個邏輯單元&#xff08;Logic Elements&#xff09;&#xff0c;片上嵌入式存儲約 234 kbit&#xff…

html5語義元素

1、參考&#xff1a;HTML5 語義元素 | 菜鳥教程 2、實戰 HTML5 <section> 元素 <section> 標簽定義文檔中的節&#xff08;section、區段&#xff09;。比如章節、頁眉、頁腳或文檔中的其他部分。 根據W3C HTML5文檔: section 包含了一組內容及其標題。 <!D…

java調用PyTorch 訓練模型實現神經網絡全流程

以下是完整的操作流程:用 PyTorch 訓練模型 → 導出為 ONNX 格式 → 用 Java 加載并推理,兼顧開發效率(PyTorch 快速訓練)和生產部署(Java 穩定運行)。 一、PyTorch 訓練模型并導出為 ONNX 1. 安裝依賴 bash pip install torch onnx # PyTorch 和 ONNX 庫2. 訓練一個…

Maven - Spring Boot 項目打包本地 jar 的 3 種方法

文章目錄Pre概述方案思路構建流程圖工作機制說明目錄結構示例POM 配置模板構建與驗證注意事項方案優缺點Pre Maven - Manual Maven JAR Installation&#xff1a;用 mvn install:install-file 安裝本地 JAR 的實用指南 概述 在 Spring Boot 項目中&#xff0c;通常依賴包會從…

平替 Claude Code,API接入 GPT-5,Codex CLI 國內直接使用教程

最新升級接入GPT-5的 Codex 擁有可以媲美 Claude Code 的AI編碼能力&#xff0c;本文將指導你在 Windows系統上部署原生的 Codex CLI程序&#xff0c;并且接入超低價中轉API&#xff0c;讓你在國內直接用上超高性價比的 OpenAI Codex CLI 應用。關于 CodexCodex 是 OpenAI 開發…

kubernertes (K8S)部署

參考&#xff1a; https://blog.csdn.net/yu33575/article/details/135387548 二進制安裝k8s&#xff1a; https://blog.csdn.net/qq_73990369/article/details/143217084 K8S二進制安裝與部署 &#xff1a;https://blog.csdn.net/fantuan_sss/article/details/139073366 k8s…

LeetCode 簡單JS刷題

目錄 返回數組最后一個元素 2787.將一個數字表示成冪的和的方案數 326.3的冪 1780.判斷一個數字是否可以表示成三的冪的和 342.4的冪 返回數組最后一個元素 1.請你編寫一段代碼實現一個數組方法&#xff0c;使任何數組都可以調用 array.last() 方法&#xff0c;這個方法將…

七大排序算法全解析:從入門到精通

目錄 一.排序的概念 二.常見排序算法的實現 2.1 插入排序 &#xff08;1&#xff09;直接插入排序&#xff1a; 當插入第i(i>1)個元素時&#xff0c;前面的array[0],array[1],…,array[i-1]已經排好序&#xff0c;此時用array[i]的排序碼與array[i-1],array[i-2],…的排序…

20250814在榮品RD-RK3588開發板的Android13下解決卡迪的LCD屏在開機的時候brightness最暗【背光的pwm信號的極性反了】

20250814在榮品RD-RK3588開發板的Android13下解決卡迪的LCD屏在開機的時候brightness最暗【背光的pwm信號的極性反了】 2025/8/14 11:33緣起&#xff1a;在榮品RD-RK3588開發板的Android13下&#xff0c;卡迪的LCD屏在開機的時候很暗&#xff0c;幾乎看不見。 在命令行查看亮度…

Flink的狀態管理

一、狀態的概念Flink的狀態其實你就可以將其想象為中間結果就可以了。在Flink中&#xff0c;算子的任務可以分為無狀態和有狀態兩種情況。無狀態算子任務在計算過程中是不依賴于其他數據的&#xff0c;只根據當前的輸入數據就可以得到結果輸出。比如之前講到的Map、FlatMap、Fi…

GoLand 項目從 0 到 1:第八天 ——GORM 命名策略陷阱與 Go 項目啟動慢問題攻堅

第八天核心任務&#xff1a;解決開發中的兩大技術卡點今天的開發不僅聚焦于代碼層面的數據庫字段映射問題&#xff0c;還遭遇了一個困擾團隊許久的環境難題 ——Go 項目啟動異常緩慢。經過多維度排查&#xff0c;我們不僅理清了 GORM 命名策略的設計邏輯&#xff0c;還找到了影…

在Ubuntu上安裝Google Chrome的詳細教程

步驟 1&#xff1a;下載 Google Chrome 安裝包 打開瀏覽器輸入https://www.google.cn/chrome/&#xff0c;然后進入Chrome瀏覽器官方網站 點擊下載選擇Debian/Ubuntu版本 google-chrome-stable_current_amd64.deb步驟 2&#xff1a;安裝下載的.deb 包 sudo dpkg -i google-chro…

el-table合并相同名稱的行

el-table合并相同名稱的行 <template><el-table:data"tableData":span-method"objectSpanMethod"border><el-table-columnprop"name"label"名稱"width"180"></el-table-column><el-table-column…

解決 VSCode 無法從右鍵菜單“通過 Code 打開”文件夾的問題

&#x1f9e9; 一、問題現象 VSCode 已安裝&#xff0c;但右鍵文件夾/桌面空白處無“通過 Code 打開在 VSCode 中執行 Shell Command: Install ‘Open with Code’ 無反應手動添加后菜單顯示亂碼&#xff08;如 €?? Code ‰“€&#xff09;點擊右鍵菜單無響應或提示“找不到…

服務器數據恢復—服務器硬盤狀態燈變紅,分區數據恢復過程

服務器數據恢復環境&故障&#xff1a; 某公司服務器上有一組由3塊硬盤組建的raid5磁盤陣列。 服務器上1塊硬盤的狀態燈變為紅色&#xff0c;磁盤陣列出現故障&#xff0c;分區無法識別。服務器數據恢復過程&#xff1a; 1、將故障服務器上所有磁盤編號后取出。經過初檢&…

MySQL → SQL → DDL → 表操作 → 數據類型 知識鏈整理成一份系統的內容

1. 知識結構MySQL└── SQL&#xff08;結構化查詢語言&#xff09;├── DDL&#xff08;數據定義語言&#xff09; → 定義結構│ ├── 表操作&#xff08;創建/修改/刪除表&#xff09;│ └── 數據類型&#xff08;列字段類型定義&#xff09;├── DML&…

基于 gRPC 的接口設計、性能優化與生產實踐

gRPC 是一種高性能、跨語言的遠程過程調用&#xff08;RPC&#xff09;框架&#xff0c;由 Google 開發&#xff0c;基于 HTTP/2 協議和 Protocol Buffers&#xff08;Protobuf&#xff09;序列化機制&#xff0c;廣泛應用于微服務架構和分布式系統中。本文將深入解析 gRPC 的底…