Node.js 前端面试题及详细答案(实战向)_第1页
Node.js 前端面试题及详细答案(实战向)_第2页
Node.js 前端面试题及详细答案(实战向)_第3页
Node.js 前端面试题及详细答案(实战向)_第4页
Node.js 前端面试题及详细答案(实战向)_第5页
已阅读5页,还剩3页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Node.js前端面试题及详细答案(实战向)一、Node.js基础核心题1.说说你对Node.js的理解,它和浏览器JS有什么区别?参考答案:Node.js是一个基于ChromeV8引擎的服务端JavaScript运行环境,采用事件驱动、非阻塞I/O模型,适合开发高并发、轻量级的后端服务、接口、工具脚本等。它和浏览器JS核心区别主要有三点:1.运行环境不同:浏览器是前端运行环境,提供DOM、BOMAPI;Node.js是服务端环境,没有DOM/BOM,提供文件操作、网络、进程、流等服务端API。2.模块体系不同:浏览器以ES6Module为主;Node.js同时支持CommonJS和ESModule,默认老旧版本以CommonJS为主。3.应用场景不同:浏览器JS主要做页面交互、DOM操作;Node.js用于服务端接口、中间层、打包构建、脚本自动化、服务器部署等。2.Node.js中的CommonJS和ESModule有什么区别?参考答案:1.语法差异:CommonJS使用require()引入、module.exports/exports导出;ESModule使用import/export语法。2.加载机制:CommonJS是运行时同步加载,加载时会完整执行模块代码,缓存模块结果;ESModule是编译时静态解析,可以做树摇优化,加载为异步机制。3.值的特性:CommonJS导出的是值的拷贝,原模块值修改后,引入方不会更新;ESModule导出的是值的引用,原模块值变化,引入方同步更新。4.文件后缀:CommonJS可省略后缀、默认找index文件;ESModule必须写完整文件后缀。5.顶层变量:CommonJS有module、exports、__dirname、__filename顶层变量;ESModule没有这些变量,需要手动引入模块实现。3.解释一下Node.js的单线程模型,它是如何实现高并发的?参考答案:Node.js主线程是单线程的,所有JS代码、事件回调都在主线程执行,不会开启多线程处理业务逻辑。它能实现高并发,核心靠非阻塞I/O+事件循环+线程池:1.遇到文件读写、网络请求、数据库查询等I/O操作时,主线程不会阻塞等待,而是将任务交给系统底层或libuv线程池处理,主线程继续执行后续代码。2.当I/O任务完成后,回调函数会被推入事件队列,等待主线程空闲时执行。3.这种模型避开了线程创建、销毁、切换的开销,擅长处理大量I/O密集型请求,所以高并发性能优异。注意:单线程不适合CPU密集型任务,大量计算会阻塞主线程,导致服务卡顿。二、事件循环与异步核心(高频必考)4.详细说一下Node.js事件循环的执行顺序参考答案:Node.js事件循环分为6个阶段,会按顺序循环执行,每一轮循环称为一次tick,完整顺序如下:1.timers阶段:执行setTimeout、setInterval到期的回调2.pendingcallbacks阶段:执行延迟的I/O回调(绝大多数系统错误回调)3.idle、prepare阶段:系统内部调用,业务代码基本接触不到4.poll阶段:核心阶段,获取新的I/O事件,执行I/O回调,空闲时会阻塞等待新事件5.check阶段:专门执行setImmediate回调6.closecallbacks阶段:执行关闭回调,比如socket、文件关闭事件微任务优先级:每执行完一个事件循环阶段,都会先清空所有微任务,再进入下一个阶段。微任务优先级:process.nextTick>Promise.then/catch/finally5.setTimeout、setImmediate、process.nextTick执行顺序区别?参考答案:1.process.nextTick:优先级最高,属于微任务,每一轮事件循环的各个阶段切换间隙,都会优先执行完它的所有回调。2.setTimeout:属于宏任务,在timers阶段执行,最小延迟默认1ms,代码首次执行时定时器可能存在延迟偏差。3.setImmediate:属于宏任务,在check阶段执行,专门用于当前poll阶段结束后立即执行。固定执行优先级:process.nextTick>Promise微任务>setTimeout/setImmediate特殊场景:全局直接写setTimeout和setImmediate,执行顺序不确定;如果在I/O回调内部,一定是setImmediate先执行。6.什么是事件冒泡?Node.js事件发射器EventEmitter怎么用?参考答案:EventEmitter是Node.js内置的事件驱动核心类,所有事件模块(流、HTTP、文件)都基于它实现,核心是发布订阅模式。常用API:-on():绑定事件监听,可多次触发-once():绑定一次性监听,触发一次后自动销毁-emit():触发自定义事件,可传参-off():移除指定事件监听-error事件:必须手动监听,否则程序直接崩溃退出事件冒泡主要体现在继承链上,子实例触发事件会向上传递,日常开发中多用于解耦异步逻辑、拆分复杂业务。三、文件与流操作(实战常用)7.Node.js中fs模块同步、异步、Promise版本的区别?参考答案:1.同步fs:方法名带Sync,比如readFileSync,会阻塞主线程,执行完才会走下一步,适合启动初始化、配置读取等一次性操作,不适合接口请求中使用。2.异步回调fs:原生异步方法,通过回调函数获取结果,不会阻塞主线程,但多层文件操作容易出现回调地狱,代码可读性差。3.fs/promises:Node.js官方封装的Promise版本,无需手动封装,支持async/await,代码扁平化,是目前业务开发首选。8.什么是流(Stream)?有哪几种流?解决了什么问题?参考答案:流是Node.js处理大文件、大数据的核心机制,核心思想是分段读取、分段写入,不用一次性把所有数据加载到内存中。四种基础流:1.可读流Readable:读取数据(读文件、读接口响应)2.可写流Writable:写入数据(写文件、推送数据)3.双工流Duplex:既可读又可写(TCP套接字)4.转换流Transform:读写过程中可修改数据(压缩、解压、编码转换)解决的核心问题:大文件内存溢出,一次性读取大文件会占用大量内存,流可以边读边写,内存占用极低。日常文件上传、下载、压缩、日志打印都依赖流实现。四、网络与HTTP模块9.用原生http模块简单实现一个接口服务参考答案:javascript

consthttp=require('http')

constserver=http.createServer((req,res)=>{

//设置响应头

res.setHeader('Content-Type','application/json')

//处理路由

if(req.url==='/api/getList'&&req.method==='GET'){

res.end(JSON.stringify({code:200,data:[1,2,3]}))

}else{

res.end(JSON.stringify({code:404,msg:'接口不存在'}))

}

})

server.listen(3000,()=>{

console.log('服务启动在3000端口')

})核心知识点:req是请求对象,包含请求头、请求地址、请求方法、请求体;res是响应对象,用于设置响应头、返回数据、结束请求。10.说说Node.js中的跨域问题及解决方案参考答案:跨域是浏览器同源策略限制,前端域名、端口、协议与后端不一致时就会触发跨域,Node.js服务端本身不存在跨域。常用解决方案:1.后端设置CORS响应头(最常用):在响应头中允许前端域名、允许请求方法、允许请求头。2.使用cors中间件:Express/Koa项目直接引入cors包,一行代码解决跨域。3.前端代理:开发环境通过vite、webpack代理转发请求,规避跨域。4.Nginx反向代理:线上部署通过Nginx统一域名端口,彻底解决跨域。五、异常与进程管理11.Node.js如何捕获全局异常?防止服务崩溃?参考答案:Node.js默认遇到未捕获异常会直接退出进程,线上服务必须做异常捕获保活:1.同步异常:使用try/catch捕获2.Promise异常:通过catch捕获,全局可监听unhandledRejection3.全局同步异常:监听uncaughtException4.事件错误:所有EventEmitter实例必须监听error事件线上进阶方案:通过PM2守护进程,进程崩溃后自动重启,保证服务可用。12.process进程常用API有哪些?参考答案:-process.argv:获取命令行启动参数,用于脚本传参-process.env:获取系统环境变量,区分开发、测试、生产环境-process.cwd():获取当前项目运行目录-process.exit():手动退出进程-process.on('exit'):进程退出监听,用于收尾日志、资源释放六、性能优化与面试手写题13.Node.js服务性能优化方案有哪些?参考答案:1.规避阻塞:禁止在主线程写大量同步代码、复杂循环、CPU密集计算,耗时计算可拆分或用子进程。2.合理使用缓存:接口数据、静态资源做内存缓存或Redis缓存,减少重复查询。3.流处理大数据:文件上传下载、日志处理全部使用流,避免内存溢出。4.开启多进程:利用cluster模块多核部署,充分利用服务器CPU核心。5.异常与监控:全局异常捕获、日志记录、接口耗时监控,及时定位卡顿问题。6.静态资源优化:开启gzip压缩、设置缓存过期时间,减轻服务压力。14.手写简单的发布订阅(EventEmitter核心逻辑)参考答案:javascript

classEventEmitter{

constructor(){

//存储事件:key事件名,value回调数组

this.events=Object.create(null)

}

//绑定事件

on(eventName,fn){

if(!this.events[eventName]){

this.events[eventName]=[]

}

this.events[eventName].push(fn)

}

//触发事件

emit(eventName,...args){

constfns=this.events[eventName]||[]

fns.forEach(fn=>fn(...args))

}

//一次性监听

once(eventName,fn){

constwrap=(...args)=>{

fn(...args)

this.off(eventName,wrap)

}

this.on(eventName,wrap)

}

//移除监听

off(eventName,fn){

if(!this.events[eventName])return

this.events[eventName]=this.events[eventName].filter(item=>item!==fn)

}

}

//使用示例

conste=newEventEmitter()

e.on('say',(msg)=>console.log(msg))

e.emit('say','hellonode')七、易错面试真题(含解析)15.为什么Node.js不适合CPU密集型任务?怎么解决?参考答案:Node.js主线程单线程,CPU密集型任务会一直占用主线程,导致事件循环阻塞,所有异步回调、接口请求都会停滞,服务直接卡顿、超

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论