nodejs面试题及答案

更新日期: 2021-07-24阅读: 1.6k标签: 面试题

为什么用Nodejs,它有哪些缺点?

  • 事件驱动,通过闭包很容易实现客户端的生命活期。
  • 不用担心多线程,锁,并行计算的问题
  • V8引擎速度非常快
  • 对于游戏来说,写一遍游戏逻辑代码前端后端通用

当然Nodejs也有一些缺点:

  • nodejs更新很快,可能会出现版本兼容
  • nodejs还不算成熟,还没有大制作
  • nodejs不像其他的服务器,对于不同的链接,不支持进程和线程操作


nodejs有哪些特点

它是一个Javascript运行环境
依赖于Chrome V8引擎进行代码解释
事件驱动
非阻塞I/O
轻量、可伸缩,适于实时数据交互应用
单进程,单线程 (一个应用程序对应一个进程, 一个进程下面会有多个线程, 每个线程用于处理任务..)


路由是什么?

后端路由, 其实就是提前规定好的一串url路径, 当前端访问不同的路径, 后端做出不同的处理


node主要模块及api

http模块http.Agent 类http.ClientRequest 类http.Server 类http.ServerResponse 类 
events模块异步 VS 同步EventEmitter    
module模块commonjs模块化规范,一个module就是一个文件    
fs模块fs.ReadStream类fs.FSWatcher类 fs.WriteStream类 fs.Stats() fs的Promise API
process模块

process.stdin

process.stdout

process.on

process.env

process.nextTick

方法将 callback 

添加到下一个时间点的队列(事件循环)

process.mainModule
querystring模块

querystring.parse

querystring.stringify   
path模块

path.join([...paths])

path.parse(path)

path.resolve([...paths])

path.join([...paths])

path.dirname(path)

debuger模块run - 运行脚本(在调试器启动时自动运行)restart - 重启脚本scripts - 列出所有已加载的脚本  

如何避免回调地狱

你可以有如下几个方法:

  • 模块化:将回调函数分割为独立的函数
  • 使用Promises
  • 使用yield来计算生成器或Promise

解析:这个问题有很多种答案,取决你使用的场景,例如ES6, ES7,或者一些控制流库。


如何用Node监听80端口

在类Unix系统中你不应该尝试去监听80端口,因为这需要超级用户权限。 因此不推荐让你的应用直接监听这个端口。
目前,如果你一定要让你的应用监听80端口的话,你可以有通过在Node应用的前方再增加一层反向代理 (例如nginx)来实现,如下图所示。否则,建议你直接监听大于1024的端口。


方向代理指的是以代理服务器来接收Internet上的连接请求,然后将请求转发给内部网络上的服务器, 并且将服务器返回的结果发送给客户端。


什么是同步, 异步?

同步操作, 当代码运行到同步操作的代码时, 所在线程等待结果返回, 而异步操作, 则是不会耽误代码继续执行, 当异步操作成功,
一般使用回调函数来处理异步成功的动作(常用在ajax/定时器/计时器等)


 node的构架是什么样子的?

主要分为三层,应用app >> V8及node内置架构 >> 操作系统. V8是node运行的环境,可以理解为node虚拟机.node内置架构又可分为三层: 核心模块(javascript实现) >> c++绑定 >> libuv + CAes + http



node有哪些核心模块?

一、HTTP模块
作用:处理网络客户端的请求
二、URL模块
作用:处理客户端请求过来的url
三、Query Strings模块
作用:处理客户端通过get/post请求传递过来的参数
四、File System模块
作用:在服务端操作文件,可能是需要将浏览器上传的图片保存到服务器,也可能是需要将服务器的资源读取之后返回给浏览器。
五、Path模块
作用:操作文件的路径,为文件操作服务
常用的几个函数: path.join(第一个路径,第二个路径) : 拼接路径
六、Global模块
作用:全局共享的,不需要导入模块即可以使用,常用的属性:

__dirname : 文件所在的文件夹路径
__filename : 文件所在的路径
require() : 导入需要的模块
module : 自定义模块时用到
exports : 自定义模块时用到

什么是事件循环

Node采用的是单线程的处理机制(所有的I/O请求都采用非阻塞的工作方式),Node.js 在主线程里维护了一个事件队列,当接到请求后,就将该请求作为一个事件放入这个队列中,然后继续接收其他请求。
而在底层,Node.js借助libuv来作为抽象封装层, 从而屏蔽不同操作系统的差异,Node可以借助livuv来来实现多线程。下图表示了Node和libuv的关系。


Libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个事件循环, 以异步的方式将任务的执行结果返回给V8引擎。可以简单用下面这张图来表示。



使用npm有哪些好处?

通过NPM,你可以安装和管理项目的依赖,并且能够指明依赖项的具体版本号。 对于Node应用开发而言,你可以通过package.json文件来管理项目信息,配置脚本, 以及指明项目依赖的具体版本。


常用的npm指令有哪些?

npm init 
npm search 
npm install 
npm remove 
npm uninstall  
npm config set


什么是错误优先的回调函数

NodeJS 通常使用回调模式,如果在执行期间发生错误,会把错误作为回调的第一个参数传递到回调函数中。


http工作原理

  • 客户端连接到Web服务器 2、发送HTTP请求

  • 释放连接TCP连接

  • 客户端浏览器解析html内容

  • 服务器接受请求并返回HTTP响应


node的常用工具util

util是一个Node.js核心模块,提供常用函数的集合,用于弥补核心js的功能过于精简的不足。

util.inherits实现对象间原型继承的函数。js面向对象特性是基于原型的。

util.inspect将任意对象转换为字符串的方法。

util.isArray(), util.isRegExp(), util.isDate(), util.isError(), util.format(), util.debug()等


node的网络模块架构是什么样子的?

node全面支持各种网络服务器和客户端,包括tcp, http/https, tcp, udp, dns, tls/ssl等.


node是怎样支持https,tls的?

主要实现以下几个步骤即可: 1) openssl生成公钥私钥 2) 服务器或客户端使用https替代http 3) 服务器或客户端加载公钥私钥证书


实现一个简单的http服务器?

思路是加载http模块,创建服务器,监听端口

var http = require('http'); // 加载http模块
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'}); // 200代表状态成功, 文档类型是给浏览器识别用的
res.write('<meta charset="UTF-8"> <h1>我是标题啊!</h1> <font color="red">这么原生,初级的服务器</font>'); // 返回给客户端的html数据
res.end(); // 结束输出流
}).listen(3000); // 绑定3ooo, 查看效果请访问 http://localhost:3000


内置的fs模块架构是什么样子的?

fs模块主要由下面几部分组成: 1) POSIX文件Wrapper,对应于操作系统的原生文件操作 2) 文件流 fs.createReadStream和fs.createWriteStream 3) 同步文件读写,fs.readFileSync和fs.writeFileSync 4) 异步文件读写, fs.readFile和fs.writeFile


读写一个文件有多少种方法?

总体来说有四种: 1) POSIX式低层读写 2) 流式读写 3) 同步文件读写 4) 异步文件读写


怎么读取json配置文件?

参考答案: 主要有两种方式,第一种是利用node内置的require('data.json')机制,直接得到js对象; 第二种是读入文件入内容,然后用JSON.parse(content)转换成js对象.二者的区别是require机制情况下,如果多个模块都加载了同一个json文件,那么其中一个改变了js对象,其它跟着改变,这是由node模块的缓存机制造成的,只有一个js模块对象; 第二种方式则可以随意改变加载后的js变量,而且各模块互不影响,因为他们都是独立的,是多个js对象.


fs.watch和fs.watchFile有什么区别,怎么应用?

二者主要用来监听文件变动.fs.watch利用操作系统原生机制来监听,可能不适用网络文件系统; fs.watchFile则是定期检查文件状态变更,适用于网络文件系统,但是相比fs.watch有些慢,因为不是实时机制.


fs模块能否删除一个, 非空的文件夹, 如果不能应该怎么做?

首先封装函数, 用于读取目标路径下所有文件/文件夹的名字
开始遍历每个相对路径, 判断是文件夹, 就递归调用次函数
如果是文件, 则删除此文件
当上面循环结束以后, 则删除当前所在的文件夹即可


node有哪些全局对象?

process, console, Buffer和exports


process有哪些常用方法?

process.stdin, process.stdout, process.stderr, process.on, process.env, process.argv, process.arch, process.platform, process.exit


console有哪些常用方法?

参考答案: console.log/console.info, console.error/console.warning, console.time/console.timeEnd, console.trace, console.table


node有哪些定时功能?

setTimeout/clearTimeout, setInterval/clearInterval, setImmediate/clearImmediate, process.nextTick


node中的事件循环是什么样子的?

event loop其实就是一个事件队列,先加入先执行,执行完一次队列,再次循环遍历看有没有新事件加入队列.执行中的叫IO events, setImmediate是在当前队列立即执行,setTimout/setInterval是把执行定时到下一个队列,process.nextTick是在当前执行完,下次遍历前执行.所以总体顺序是: IO events >> setImmediate >> setTimeout/setInterval >> process.nextTick


node中的Buffer如何应用?

Buffer是用来处理二进制数据的,比如图片,mp3,数据库文件等.Buffer支持各种编码解码,二进制字符串互转.


Buffer基本操作

Buffer对象是node处理二进制数据的一个接口。它是node原生提供的全局对象,可以直接使用,不需要require('Buffer')。
实例化
Buffer from(array)
Buffer alloc(size)
功能方法
Buffer isEncodeing() 判断是否支持编码
Buffer isBuffer() 判断是否为Buffer
Buffer byteLength() 返回指定编码的字节长度,默认为utf8
Buffer concat() 将一组Buffer对象合并为一个Buffer对象
实例方法
write() 向Buffer对象中写入内容
slice() 截取新的Buffer对象
toString() 把Buffer对象转成字符串
toJson() 把Buffer对象转成json形式的字符串

什么是EventEmitter?

EventEmitter是node中一个实现观察者模式的类,主要功能是监听和发射消息,用于处理多模块交互问题.


如何实现一个EventEmitter?

主要分三步:定义一个子类,调用构造函数,继承EventEmitter

代码演示

var util = require('util');
var EventEmitter = require('events').EventEmitter;
function MyEmitter() {
EventEmitter.call(this);
} // 构造函数

util.inherits(MyEmitter, EventEmitter); // 继承

var em = new MyEmitter();
em.on('hello', function(data) {
console.log('收到事件hello的数据:', data);
}); // 接收事件,并打印到控制台
em.emit('hello', 'EventEmitter传递消息真方便!');


 EventEmitter有哪些典型应用?

1) 模块间传递消息 2) 回调函数内外传递消息 3) 处理流数据,因为流是在EventEmitter基础上实现的. 4) 观察者模式发射触发机制相关应用


怎么捕获EventEmitter的错误事件?

监听error事件即可.如果有多个EventEmitter,也可以用domain来统一处理错误事件.

代码演示

var domain = require('domain');
var myDomain = domain.create();
myDomain.on('error', function(err){
console.log('domain接收到的错误事件:', err);
}); // 接收事件并打印
myDomain.run(function(){
var emitter1 = new MyEmitter();
emitter1.emit('error', '错误事件来自emitter1');
emitter2 = new MyEmitter();
emitter2.emit('error', '错误事件来自emitter2');
});


EventEmitter中的newListenser事件有什么用处?

newListener可以用来做事件机制的反射,特殊应用,事件管理等.当任何on事件添加到EventEmitter时,就会触发newListener事件,基于这种模式,我们可以做很多自定义处理.

代码演示

var emitter3 = new MyEmitter();
emitter3.on('newListener', function(name, listener) {
console.log("新事件的名字:", name);
console.log("新事件的代码:", listener);
setTimeout(function(){ console.log("我是自定义延时处理机制"); }, 1000);
});
emitter3.on('hello', function(){
console.log('hello node');
});


什么是Stream?

stream是基于事件EventEmitter的数据管理模式.由各种不同的抽象接口组成,主要包括可写,可读,可读写,可转换等几种类型.


Stream有什么好处?

非阻塞式数据处理提升效率,片断处理节省内存,管道处理方便可扩展等.


Stream有哪些典型应用?

文件,网络,数据转换,音频视频等.


怎么捕获Stream的错误事件?

监听error事件,方法同EventEmitter.


有哪些常用Stream,分别什么时候使用?

参考答案: Readable为可被读流,在作为输入数据源时使用;Writable为可被写流,在作为输出源时使用;Duplex为可读写流,它作为输出源接受被写入,同时又作为输入源被后面的流读出.Transform机制和Duplex一样,都是双向流,区别时Transfrom只需要实现一个函数_transfrom(chunk, encoding, callback);而Duplex需要分别实现_read(size)函数和_write(chunk, encoding, callback)函数.


实现一个Writable Stream?

三步走:1)构造函数call Writable 2) 继承Writable 3) 实现_write(chunk, encoding, callback)函数

代码演示

var Writable = require('stream').Writable;
var util = require('util');

function MyWritable(options) {
Writable.call(this, options);
} // 构造函数
util.inherits(MyWritable, Writable); // 继承自Writable
MyWritable.prototype._write = function(chunk, encoding, callback) {
console.log("被写入的数据是:", chunk.toString()); // 此处可对写入的数据进行处理
callback();
};

process.stdin.pipe(new MyWritable()); // stdin作为输入源,MyWritable作为输出源


为什么需要child-process?

node是异步非阻塞的,这对高并发非常有效.可是我们还有其它一些常用需求,比如和操作系统shell命令交互,调用可执行文件,创建子进程进行阻塞式访问或高CPU计算等,child-process就是为满足这些需求而生的.child-process顾名思义,就是把node阻塞的工作交给子进程去做.


exec,execFile,spawn和fork都是做什么用的?

exec可以用操作系统原生的方式执行各种命令,如管道 cat ab.txt | grep hello; execFile是执行一个文件; spawn是流式和操作系统进行交互; fork是两个node程序(javascript)之间时行交互.


实现一个简单的命令行交互程序?

那就用spawn吧.

代码演示

var cp = require('child_process');
var child = cp.spawn('echo', ['你好', "钩子"]); // 执行命令
child.stdout.pipe(process.stdout); // child.stdout是输入流,process.stdout是输出流
// 这句的意思是将子进程的输出作为当前程序的输入流,然后重定向到当前程序的标准输出,即控制台


两个node程序之间怎样交互?

用fork嘛,上面讲过了.原理是子程序用process.on, process.send,父程序里用child.on,child.send进行交互.
代码演示

1) fork-parent.js
var cp = require('child_process');
var child = cp.fork('./fork-child.js');
child.on('message', function(msg){
console.log('老爸从儿子接受到数据:', msg);
});
child.send('我是你爸爸,送关怀来了!');

2) fork-child.js
process.on('message', function(msg){
console.log("儿子从老爸接收到的数据:", msg);
process.send("我不要关怀,我要银民币!");
});


怎样让一个js文件变得像linux命令一样可执行?

1) 在myCommand.js文件头部加入 #!/usr/bin/env node 2) chmod命令把js文件改为可执行即可 3) 进入文件目录,命令行输入myComand就是相当于node myComand.js了


child-process和process的stdin,stdout,stderror是一样的吗?

概念都是一样的,输入,输出,错误,都是流.区别是在父程序眼里,子程序的stdout是输入流,stdin是输出流.


node中的异步和同步怎么理解

node是单线程的,异步是通过一次次的循环事件队列来实现的.同步则是说阻塞式的IO,这在高并发环境会是一个很大的性能问题,所以同步一般只在基础框架的启动时使用,用来加载配置文件,初始化程序什么的.


有哪些方法可以进行异步流程的控制?

 1) 多层嵌套回调 2) 为每一个回调写单独的函数,函数里边再回调 3) 用第三方框架比方async, q, promise等


 怎样绑定node程序到80端口?

多种方式 1) sudo 2) apache/nginx代理 3) 用操作系统的firewall iptables进行端口重定向


有哪些方法可以让node程序遇到错误后自动重启?

参考答案: 1) runit 2) forever 3) nohup npm start &


怎样充分利用多个CPU?

一个CPU运行一个node实例


怎样调节node执行单元的内存大小?

用--max-old-space-size 和 --max-new-space-size 来设置 v8 使用内存的上限


程序总是崩溃,怎样找出问题在哪里?

1) node --prof 查看哪些函数调用次数多 2) memwatch和heapdump获得内存快照进行对比,查找内存溢出


有哪些常用方法可以防止程序崩溃?

1) try-catch-finally 2) EventEmitter/Stream error事件处理 3) domain统一控制 4) jshint静态检查 5) jasmine/mocha进行单元测试


 怎样调试node程序?

node --debug app.js 和node-inspector


什么是Stub?举个使用场景

Stub是用于模拟一个组件或模块的函数或程序。在测试用例中, 简单的说,你可以用Stub去模拟一个方法,从而避免调用真实的方法, 使用Stub你还可以返回虚构的结果。你可以配合断言使用Stub。
举个例子,在一个读取文件的场景中,当你不想读取一个真正的文件时:

var fs = require('fs');

var readFileStub = sinon.stub(fs, 'readFile', function (path, cb) {
return cb(null, 'filecontent');
});

expect(readFileStub).to.be.called;
readFileStub.

在单元测试中:Stub是完全模拟一个外部依赖,而Mock常用来判断测试通过还是失败。


express优点是什么?

Express 的优点是线性逻辑:路由和中间件完美融合,通过中间件形式把业务逻辑细分,简化,一个请求进来经过一系列中间件
处理后再响应给用户,再复杂的业务也是线性了,清晰明了。


express缺点是什么?

Express 是基于 callback 来组合业务逻辑。Callback 有两大硬伤,一是不可组合,二是异常不可捕获。


express常用函数

express.Router路由组件,app.get路由定向,app.configure配置,app.set设定参数,app.use使用中间件


express中如何获取路由的参数

参考答案: /users/:name使用req.params.name来获取; req.body.username则是获得表单传入参数username; express路由支持常用通配符 ?, +, *, and ()


express response有哪些常用方法

res.download() 弹出文件下载
res.end() 结束response
res.json() 返回json
res.jsonp() 返回jsonp
res.redirect() 重定向请求
res.render() 渲染模板
res.send() 返回多种形式数据
res.sendFile 返回文件
res.sendStatus() 返回状态


session和cookie的作用, 以及区别是什么?

session是区别于数据库存在的一种服务器临时存储技术, 它主要存储一些无需持久化的数据, 比如临时的登录状态信息等
cookie是存在于浏览器上的一种浏览器本地存储的方式, 同域名下的cookie不同标签页可以共享, 默认过期时间是浏览器关闭时,而且在进行http请求时, 会自动带上浏览器全部的cookie发给后台, 后台也可以获取cookie, 设置可以在响应时, 想浏览器中设置cookie。


ejs的作用是什么?

EJS是一个JavaScript模板库, 用来从JSON数据中生成HTML文件


pug的作用是什么?

Pug是一款健壮、灵活、功能丰富的HTML模板引擎,专门为 Node.js 平台开发。Pug是由Jade 改名而来。是一种通过缩进(表示标签间的嵌套关系)的方式来编写代码的过程,在编译的过程中,不需要考虑标签是否闭合的问题。可以加快写代码速度,也为代码复用提供了便捷。

什么是中间件?

中间件其实就是一个个的函数, 当调用next时, 才会执行下一个中间件函数Express是一个自身功能极简,完全是路由和中间件
构成一个web开发框架:从本质上来说,一个Express应用就是在调用各种中间件函数。封装了一些或许复杂但肯定是通用的功能,
非内置的中间件需要通过安装后,require到文件就可以运行


mongodb有哪些常用优化措施

类似传统数据库,索引和分区.


redis支持哪些功能

set/get, hset/hget, publish/subscribe, expire


redis最简单的应用

参考答案:

var redis = require("redis"),
client = redis.createClient();

client.set("foo_rand000000000000", "some fantastic value");
client.get("foo_rand000000000000", function (err, reply) {
console.log(reply.toString());
});
client.end();


apache,nginx有什么区别?

二者都是代理服务器,功能类似.apache应用简单,相当广泛.nginx在分布式,静态转发方面比较有优势.


关系和非关系型数据库的区别?

存储方式
传统的关系型数据库采用表格的储存方式, 数据以行和列的方式进行存储,要读取和查询都十分方便。而
非关系型数据库通常以数据集的方式,大量的数据集中存储在一起,类似于键值对、图结构或者文档。
存储结构
关系型数据库按照结构化的方法存储数据, 每个数据表都必须对各个字段定义好(也就是先定义好表的结
构),再根据表的结构存入数据。NoSQL 数据库采用的是动态结构,对于数据类型和结构的改变非常的适应,
可以根据数据存储的需要灵活的改变数据库的结构。
存储规范
关系型数据库为了避免重复、规范化数据以及充分利用好存储空间,把数据按照最小关系表的形式进行存
储。而 NoSQL 数据库的数据存储方式是用平面数据集的方式集中存放。
扩展方式
关系型数据库只具备纵向扩展能力。非关系型数据库还可以采用横向的方式来扩展。
查询方式
关系型数据库采用结构化查询语言(即 SQL)来对数据库进行查询,NoSQL 中的文档 Id 与关系型表中
主键的概念类似,NoSQL 数据库采用的数据访问模式相对 SQL 更简单而精确。


链接: https://fly63.com/article/detial/10584

史上最全的Javascript面试题总结(内附答案)

近年来,从事JavaScript的程序员越来越多,JavaScript的曝光率也越来越高,如果你想转行试试JavaScript,不妨收下这份面试题及答案,没准用得上。当然,如果针对这些问题,你有更棒的答案,欢迎移步至评论区。

高级前端面试题汇总

面试的公司分别是:阿里、网易、滴滴、今日头条、有赞、挖财、沪江、饿了么、携程、喜马拉雅、兑吧、微医、寺库、宝宝树、海康威视、蘑菇街、酷家乐、百分点和海风教育。以下是面试题汇总

web前端常见的面试题,基础知识点

web前端常见的面试题:包括:HTML 常见题目、CSS类的题目、JavaScript类的题目、面试官爱问的问题。原来公司工作流程是怎么样的,如何与其他人协作的?如何夸部门合作的?你遇到过比较难的技术问题是?你是如何解决的?

前端面试题汇总(主要为Vue)

毕业之后就在一直合肥小公司工作,没有老司机、没有技术氛围,在技术的道路上我只能独自摸索。老板也只会画饼充饥,前途一片迷茫看不到任何希望。于是乎,我果断辞职,在新年开工之际来到杭州,这里的互联网公司应该是合肥的几十倍吧。。。。

js常见面试题

javascript的typeof返回哪些数据类型;例举3种强制类型转换和2种隐式类型转换?split() join() 的区别; 数组方法pop() push() unshift() shift();IE和标准下有哪些兼容性的写法

Js字符串类面试题

解析 URL Params 为对象;模板引擎实现;转化为驼峰命名;查找字符串中出现最多的字符和个数;字符串查找请使用最基本的遍历来实现判断字符串 a 是否被包含在字符串 b 中

35道必须要清楚的 React面试题

虚拟 DOM (VDOM)是真实 DOM 在内存中的表示。UI 的表示形式保存在内存中,并与实际的 DOM 同步。这是一个发生在渲染函数被调用和元素在屏幕上显示之间的步骤,整个过程被称为调和。函数组件和类组件当然是有区别的

23 个 Vue.js 初级面试题

使用渐进式框架的代价很小,从而使现有项目(使用其他技术构建的项目)更容易采用并迁移到新框架。 Vue.js 是一个渐进式框架,因为你可以逐步将其引入现有应用,而不必从头开始重写整个程序。

AJAX原理及常见面试题

AJAX 即 Asynchronous Javascript And XML(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。AJAX 是一种用于创建快速动态网页的技术。它可以令开发者只向服务器获取数据(而不是图片,HTML文档等资源)

12道vue高频原理面试题,你能答出几道?

本文分享 12 道 vue 高频原理面试题,覆盖了 vue 核心实现原理,其实一个框架的实现原理一篇文章是不可能说完的,希望通过这 12 道问题,让读者对自己的 Vue 掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握 Vue

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!