当前位置: 首页 > news >正文

Node.js面试题及详细答案120题(93-100) -- 错误处理与调试篇

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 93. Node.js中的错误类型有哪些?如何捕获全局错误?
        • 常见错误类型
        • 捕获全局错误
      • 94. 如何使用`try/catch`处理异步错误?它能捕获哪些错误?
        • 处理异步错误的方式
        • `try/catch` 能捕获的错误
      • 95. 什么是未捕获异常(Uncaught Exception)?如何处理?
        • 示例:未捕获异常
        • 处理方式
      • 96. 什么是未处理的Promise拒绝(Unhandled Rejection)?如何处理?
        • 示例:未处理的Promise拒绝
        • 处理方式
      • 97. Node.js的调试工具有哪些?如何使用`--inspect`参数调试?
        • 常用调试工具
        • 使用`--inspect`参数调试
      • 98. 如何使用VS Code调试Node.js程序?
        • 步骤1:创建调试配置
        • 步骤2:配置`launch.json`
        • 步骤3:开始调试
      • 99. 什么是日志?在Node.js中如何记录和管理日志?
        • 日志的作用
        • 记录和管理日志的方式
      • 100. 常用的Node.js日志库有哪些?请举例说明。
        • 1. `winston`
        • 2. `pino`
        • 3. `morgan`
  • 二、120道Node.js面试题目录列表

一、本文面试题目录

93. Node.js中的错误类型有哪些?如何捕获全局错误?

Node.js 中的错误可分为多种类型,不同类型对应不同的场景,捕获全局错误能避免程序意外崩溃。

常见错误类型
  1. Error:所有错误的基类,包含错误消息(message)和堆栈跟踪(stack)。
  2. SyntaxError:语法错误(如代码拼写错误),通常在程序启动时抛出。
    // 示例:缺少括号导致语法错误
    function test() { console.log('test') // 缺少 }
    
  3. TypeError:类型错误(如调用非函数对象)。
    const num = 123;
    num(); // TypeError: num is not a function
    
  4. ReferenceError:引用错误(如使用未定义的变量)。
    console.log(undefinedVar); // ReferenceError: undefinedVar is not defined
    
  5. RangeError:范围错误(如数组长度为负数)。
    const arr = new Array(-1); // RangeError: Invalid array length
    
  6. 自定义错误:通过继承 Error 实现特定业务错误。
    class ValidationError extends Error {constructor(message) {super(message);this.name = 'ValidationError';}
    }
    
捕获全局错误

全局错误指未被局部 try/catch 捕获的错误,需通过事件监听处理:

// 1. 捕获未捕获的同步异常
process.on('uncaughtException', (err) => {console.error('未捕获的同步异常:', err);// 必要时进行资源清理后退出进程process.exit(1);
});// 2. 捕获未处理的Promise拒绝
process.on('unhandledRejection', (reason, promise) => {console.error('未处理的Promise拒绝:', reason);// 可在此处记录日志或进行补救
});// 3. 捕获警告(非致命错误)
process.on('warning', (warning) => {console.warn('警告:', warning.message);
});

注意uncaughtException 发生后,进程可能处于不稳定状态,建议记录日志后重启进程。

94. 如何使用try/catch处理异步错误?它能捕获哪些错误?

try/catch 是 JavaScript 处理异常的标准方式,在 Node.js 中可结合 async/await 处理异步错误,但需注意其适用范围。

处理异步错误的方式
  1. async/await + try/catch(推荐):

    const fs = require('fs/promises');async function readFile() {try {// 异步操作:读取文件const data = await fs.readFile('nonexistent.txt', 'utf8');console.log(data);} catch (err) {// 捕获异步操作中的错误(如文件不存在)console.error('读取失败:', err.message);}
    }readFile();
    
  2. Promise链式调用 + catch()

    fs.readFile('nonexistent.txt', 'utf8').then(data => console.log(data)).catch(err => console.error('读取失败:', err.message));
    
try/catch 能捕获的错误
  • 同步错误:如 TypeErrorReferenceError 等。

  • await 后的异步错误:通过 async/await 包装的 Promise 拒绝。

  • 异步回调中的错误(不能直接捕获):需在回调内部处理。

    // 错误示例:try/catch 无法捕获回调中的异步错误
    try {fs.readFile('file.txt', (err, data) => {if (err) throw err; // 此处错误不会被外部 try/catch 捕获});
    } catch (err) {console.error('无法捕获此处错误');
    }// 正确处理:在回调内部捕获
    fs.readFile('file.txt', (err, data) => {try {if (err) throw err;console.log(data);} catch (err) {console.error('处理错误:', err);}
    });
    

95. 什么是未捕获异常(Uncaught Exception)?如何处理?

未捕获异常(Uncaught Exception) 指同步代码中抛出的错误未被 try/catch 捕获,导致错误冒泡到事件循环顶层,可能导致程序崩溃。

示例:未捕获异常
// 同步代码抛出错误但未捕获
function throwError() {throw new Error('致命错误');
}throwError(); // 未被捕获,触发 uncaughtException 事件
console.log('此处不会执行');
处理方式

通过监听 process 对象的 uncaughtException 事件捕获:

// 注册全局未捕获异常处理器
process.on('uncaughtException', (err) => {// 1. 记录详细错误日志(包含堆栈)console.error('未捕获异常:', err.stack);// 2. 清理资源(如关闭数据库连接、释放文件句柄)const cleanup = async () => {try {await db.disconnect(); // 假设 db 是数据库连接对象console.log('资源清理完成');} catch (cleanupErr) {console.error('清理失败:', cleanupErr);}};// 3. 清理后退出进程(避免不稳定状态)cleanup().then(() => {process.exit(1); // 非0退出码表示异常终止});
});

最佳实践

  • 仅用 uncaughtException 作为最后的安全网,优先通过 try/catch 局部处理。
  • 发生未捕获异常后,进程状态可能不可靠,应重启进程(可配合进程管理工具如 PM2 自动重启)。

96. 什么是未处理的Promise拒绝(Unhandled Rejection)?如何处理?

未处理的Promise拒绝(Unhandled Rejection) 指Promise被拒绝(reject)后,未通过 catch()try/catch 处理,导致错误未被捕获。

示例:未处理的Promise拒绝
// 情况1:Promise链式调用未加 catch()
Promise.reject(new Error('操作失败')).then(() => console.log('成功')); // 未处理拒绝// 情况2:async/await 未用 try/catch
async function test() {await Promise.reject(new Error('异步失败')); // 未捕获
}
test();
处理方式
  1. 局部处理:为每个Promise添加 catch() 或用 try/catch

    // 方式1:使用 catch()
    Promise.reject(new Error('失败')).catch(err => console.error('处理拒绝:', err));// 方式2:使用 try/catch
    async function safeTest() {try {await Promise.reject(new Error('失败'));} catch (err) {console.error('处理拒绝:', err);}
    }
    safeTest();
    
  2. 全局处理:监听 unhandledRejection 事件(作为兜底)。

    process.on('unhandledRejection', (reason, promise) => {console.error('未处理的Promise拒绝:', reason);// 可选:给未处理的Promise添加catch(避免多次触发)promise.catch(err => console.error('补捕获:', err));
    });
    

注意:Node.js 15+ 中,未处理的Promise拒绝会导致进程退出(类似未捕获异常),因此必须处理。

97. Node.js的调试工具有哪些?如何使用--inspect参数调试?

Node.js 提供多种调试工具,用于定位代码错误和性能问题,--inspect 参数是官方推荐的调试方式。

常用调试工具
  1. Chrome DevTools:通过 --inspect 连接,支持断点、变量监视等。
  2. VS Code 内置调试器:集成IDE,操作便捷。
  3. WebStorm:专业JavaScript IDE,调试功能强大。
  4. node-inspect:命令行调试工具(需单独安装)。
  5. ndb:改进的命令行调试工具(来自Google)。
使用--inspect参数调试
  1. 启动调试模式

    # 基础用法:启动程序并开启调试
    node --inspect app.js# 可选:指定端口(默认9229)
    node --inspect=3000 app.js# 可选:程序启动时暂停(等待调试器连接)
    node --inspect-brk app.js
    
  2. 连接调试器

    • 打开 Chrome 浏览器,访问 chrome://inspect
    • 在“Remote Target”中找到目标程序,点击“inspect”打开调试面板。
  3. 调试操作

    • 设置断点:在代码行号处点击添加断点。
    • 监视变量:在“Watch”面板输入变量名。
    • 控制流程:使用“继续”“单步执行”“步入”“步出”按钮控制代码执行。

示例:调试 app.js

// app.js
function add(a, b) {return a + b; // 在该行设置断点
}const result = add(2, 3);
console.log(result);

启动命令:node --inspect app.js,在 Chrome DevTools 中观察变量 ab 的值。

98. 如何使用VS Code调试Node.js程序?

VS Code 内置Node.js调试器,支持断点调试、变量监视等功能,操作步骤如下:

步骤1:创建调试配置
  1. 打开项目文件夹,点击左侧“运行和调试”图标(或按 Ctrl+Shift+D)。
  2. 点击“创建 launch.json 文件”,选择“Node.js”环境,自动生成配置文件。
步骤2:配置launch.json

基础配置示例:

{"version": "0.2.0","configurations": [{"type": "node","request": "launch","name": "启动程序","program": "${workspaceFolder}/app.js" // 入口文件路径},{"type": "node","request": "attach","name": "附加到进程","port": 9229 // 对应 --inspect 端口}]
}
  • launch:直接启动程序并调试。
  • attach:附加到已运行的 --inspect 进程。
步骤3:开始调试
  1. 在代码行号左侧点击设置断点(出现红色圆点)。
  2. 点击调试面板的“启动调试”按钮(或按 F5)。
  3. 使用调试控制栏操作:
    • 继续(F5):执行到下一个断点。
    • 单步跳过(F10):执行当前行,不进入函数。
    • 单步调试(F11):进入当前函数内部。
    • 步出(Shift+F11):从当前函数退出。
  4. 在“变量”面板查看当前作用域的变量,在“监视”面板添加自定义监视表达式。

示例:调试HTTP服务器

// app.js
const http = require('http');
const server = http.createServer((req, res) => {const url = req.url; // 设置断点res.end(`Hello ${url}`);
});
server.listen(3000);

启动调试后,访问 http://localhost:3000/test,程序会在断点处暂停,可查看 req.url 的值。

99. 什么是日志?在Node.js中如何记录和管理日志?

日志是程序运行过程中产生的记录,用于跟踪流程、排查错误、分析性能。在Node.js中,日志管理需考虑分级、格式、存储和轮转。

日志的作用
  • 错误排查:记录异常堆栈和上下文。
  • 行为跟踪:记录用户操作、系统事件。
  • 性能分析:记录耗时操作的执行时间。
  • 安全审计:记录敏感操作(如登录、权限变更)。
记录和管理日志的方式
  1. 基础日志记录:使用 console 方法(简单但功能有限)。

    console.log('信息日志:用户登录'); // 普通信息
    console.warn('警告日志:磁盘空间不足'); // 警告
    console.error('错误日志:数据库连接失败'); // 错误
    
  2. 使用日志库:如 winstonpino,支持分级、格式化和输出到文件。

    const winston = require('winston');
    const logger = winston.createLogger({level: 'info', // 日志级别(info及以上会被记录)format: winston.format.combine(winston.format.timestamp(), // 添加时间戳winston.format.json() // JSON格式),transports: [new winston.transports.Console(), // 输出到控制台new winston.transports.File({ filename: 'error.log', level: 'error' }), // 错误日志到文件new winston.transports.File({ filename: 'combined.log' }) // 所有日志到文件]
    });// 使用日志
    logger.info('用户登录', { userId: 1, ip: '192.168.1.1' });
    logger.error('支付失败', { orderId: 100, error: '余额不足' });
    
  3. 日志轮转:防止日志文件过大,使用 winston-daily-rotate-file 按时间分割日志。

    npm install winston-daily-rotate-file
    
    const DailyRotateFile = require('winston-daily-rotate-file');
    logger.add(new DailyRotateFile({filename: 'app-%DATE%.log',datePattern: 'YYYY-MM-DD',maxSize: '20m', // 单个文件最大20MBmaxFiles: '14d' // 保留14天日志
    }));
    
  4. 日志级别:按重要性从低到高为 sillydebugverboseinfowarnerror,可通过配置控制输出粒度。

100. 常用的Node.js日志库有哪些?请举例说明。

Node.js 生态中有多个成熟的日志库,各有特点,适用于不同场景:

1. winston
  • 特点:功能全面、可扩展、支持多传输目标(控制台、文件、数据库等)。
  • 示例
    const winston = require('winston');const logger = winston.createLogger({level: 'debug', // 记录debug及以上级别format: winston.format.combine(winston.format.colorize(), // 控制台彩色输出winston.format.simple() // 简化格式),transports: [new winston.transports.Console(),new winston.transports.File({ filename: 'app.log' })]
    });logger.debug('调试信息:变量x的值为10');
    logger.info('用户注册成功');
    logger.warn('API响应缓慢');
    logger.error('数据库连接失败', { error: '连接超时' });
    
2. pino
  • 特点:高性能(速度比 winston 快5-10倍)、默认JSON格式、适合生产环境。
  • 示例
    const pino = require('pino');
    const logger = pino({level: 'info',timestamp: pino.stdTimeFunctions.isoTime // ISO格式时间戳
    });// 输出到文件(需配合重定向)
    // const logger = pino(pino.destination('app.log'));logger.info({ userId: 1 }, '用户登录');
    logger.error({ err: new Error('失败') }, '操作出错');
    
3. morgan
  • 特点:专为HTTP请求日志设计,常与Express/Koa配合使用。
  • 示例
    const express = require('express');
    const morgan = require('morgan');
    const app = express();// 输出到控制台(combined格式包含详细信息)
    app.use(morgan('combined'));// 输出到文件
    const fs = require('fs');
    const accessLogStream = fs.createWriteStream('access.log', { flags: 'a' });
    app.use(morgan('combined', { stream: accessLogStream }));app.get('/',
    

二、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.dtcms.com/a/426785.html

相关文章:

  • pc端js动态调用提示音音频报错的问题解决
  • 网站的建设特色网站开发培训哪家好
  • C# 中的 简单工厂模式 (Simple Factory)
  • Docker linux 离线部署springcloud
  • 第 2 天:搭建 C 语言开发环境 ——VS Code/Dev-C++/Code::Blocks 安装与配置全指南
  • 基于 Celery 的分布式文件监控系统
  • CATIA二次开发(2)C#启用AOT
  • Linux 驱动开发与内核通信机制——超详细教程
  • 【langgraph】本地部署方法及实例分析
  • Linux入门指南:从零掌握基础指令
  • 做笔记的网站源码江永网站建设
  • 是时候重启了:AIGC将如何重构UI设计师的学习路径与知识体系?
  • uniapp 请求接口封装和使用
  • AIGC重构数据可视化:你是进化中的“驯兽师”还是被替代的“画图工”?
  • Apache Doris 内部数据裁剪与过滤机制的实现原理
  • 专业做网站流程小程序开发步骤大全
  • C语言基础之指针2
  • 淘客网站怎么做 知乎wordpress淘宝联盟插件
  • flink工作流程
  • openHarmony之storage_daemon:分区挂载与设备节点管理机制讲解
  • 建站怎么赚钱个人官方网站怎么建设
  • 学习笔记093——Windows系统如何定时备份远程服务器的mysql文件到本地?
  • 操作系统内核架构深度解析:从单内核、微内核到鸿蒙分布式设计
  • MySQL 架构全景解析
  • .NET MVC中实现后台商品列表功能
  • oracle logwr,ckpt,dbwn 如何协同工作的
  • C# 网络通讯核心知识点笔记
  • Ubuntu之apt安装ClickHouse数据库
  • 在线音乐网站开发现状网站全屏弹出窗口
  • 泛型在Java集合框架中的应用有哪些?