10个常见的Node.js面试题

摘自:http://www.admin10000.com/document/6715.html

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

错误优先的回调函数用于传递错误和数据。第一个参数始终应该是一个错误对象, 用于检查程序是否发生了错误。其余的参数用于传递数据。

s.readFile(filePath, function(err, data) {  
    if (err) {
        //handle the error
    }
    // use the data object
});

解析:这个题目的主要作用在于检查被面试者对于Node中异步操作的一些基本知识的掌握。

2、如何避免回调地狱

引用:http://www.cnblogs.com/greatluoluo/p/6288931.html

为了解决这个阻塞问题,JavaScript严重依赖于回调,这是在长时间运行的进程(IO,定时器等)完成后运行的函数,因此允许代码执行经过长时间运行的任务。

downloadFile('example.com/weather.json', function(err, data) {  
    console.log('Got weather data:', data);
});

但是,问题来了,回调地狱

虽然回调的概念在理论上是巨大的,但它可能导致一些真正令人困惑和难以阅读的代码。 想象一下,如果你需要在回调后进行回调

这种层层嵌套的代码给开发带来了很多问题,主要体现在:

1.代码可能性变差
2.调试困难
3.出现异常后难以排查
  • Use modules

在几乎每种编程语言中,降低复杂性的最好方法之一是模块化。 JavaScript也不例外。 每当你编写代码时,花一些时间来回顾一下你是否经常遇到一个常见的模式。

你在不同的地方多次写相同的代码吗? 你的代码的不同部分是否遵循一个共同的主题? 如果是这样,你有机会清理东西,抽象和重用代码。

有数千个模块,你可以看看供参考,但这里有几个要考虑。 它们处理常见的,但非常具体的任务,否则会扰乱你的代码并降低可读性:Pluralize,csv,qs,clone。

Here is a new file called formuploader.js that contains our two functions from before:

module.exports.submit = formSubmit

function formSubmit (submitEvent) {
  var name = document.querySelector('input').value
  request({
    uri: "http://example.com/upload",
    body: name,
    method: "POST"
  }, postResponse)
}

function postResponse (err, response, body) {
  var statusMessage = document.querySelector('.status')
  if (err) return statusMessage.value = err
  statusMessage.value = body
}

Now that we have formuploader.js (and it is loaded in the page as a script tag after being browserified) we just need to require it and use it! Here is how our application specific code looks now:

var formUploader = require('formuploader')
document.querySelector('form').onsubmit = formUploader.submit
  • Promises

虽然Promises可以花费一些时间来掌握,但在我看来,它们是您可以在JavaScript中学习的更重要的概念之一。 它不仅大大减少了代码行数,而且使代码的逻辑流程更容易遵循。

这里是一个使用非常快,非常受欢迎的Promise库,Bluebird的例子:

var Promise = require('bluebird');  
var fs = require('fs');  
Promise.promisifyAll(fs);

var myFile = '/tmp/test';  
fs.readFileAsync(myFile, 'utf8').then(function(txt) {  
    txt = txt + '\nAppended something!';
    fs.writeFile(myFile, txt);
}).then(function() {
    console.log('Appended text!');
}).catch(function(err) {
    console.log(err);
});

请注意,这个解决方案不仅比以前的解决方案更短,而且更容易阅读(尽管,诚然,Promise风格的代码可能需要一些习惯)。 花时间学习和理解承诺,这将是值得你的时间。 但是,Promise绝对不是解决我们在异步编程中的所有问题,所以不要假设通过使用它们,你会有一个快速,干净,无bug的应用程序。 关键是知道什么时候对你有用。

一些Promise库你应该检查是Q,bluebird,或内置Promises如果你使用ES6的话。

  • Async/Await

注意:这是一个ES7功能,目前不支持Node或io.js。 但是,你现在可以使用它像Babel一样的转换器。

清除代码的另一个选项是我最近喜欢的(当它有更广泛的支持时),它使用异步函数。 这将允许你编写看起来更像同步代码,但仍然是异步的代码。

async function getUser(id) {  
    if (id) {
        return await db.user.byId(id);
    } else {
        throw 'Invalid ID!';
    }
}

try {  
    let user = await getUser(123);
} catch(err) {
    console.error(err);
}

The db.user.byId(id) call returns a Promise , which we'd normally have to use with .then() , but with await we can return the resolved value directly. Notice that the function containing the await call is prefixed with async , which tells us that it contains asynchronous code and must also be called with await. Another big advantage to this method is we can now use try/catch, for, and while with our asynchronous functions,which is much more intuitive than chaining promises together.Aside from using transpilers like Babel and Traceur, you can also get functionality like this in Node with the asyncawait package.

async/await 语法到底好在哪里?一图胜千言


1.png

2.png

3.png

3、如何用Node监听80端口

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

4.png

方向代理指的是以代理服务器来接收Internet上的连接请求,然后将请求转发给内部网络上的服务器, 并且将服务器返回的结果发送给客户端。
关于反向代理的更多内容,建议你阅读这篇文章

解释:这个问题用于检查被面试者是否有实际运行Node应用的经验。

4.什么是事件循环

Node采用的是单线程的处理机制(所有的I/O请求都采用非阻塞的工作方式),至少从Node.js开发者的角度是这样的。 而在底层,Node.js借助libuv来作为抽象封装层, 从而屏蔽不同操作系统的差异,Node可以借助livuv来来实现多线程。下图表示了Node和libuv的关系。

5.png

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

6.png

每一个I/O都需要一个回调函数——一旦执行完便推到事件循环上用于执行。 如果你需要更多详细的解释,可以参考这个视频。 你也可以参考这篇文章
  解释:这用于检查Node.js的底层知识,例如什么是libuv,它的作用是什么。

Event Loop:  http://www.ruanyifeng.com/blog/2014/10/event-loop.html

5、哪些工具可以用来保证一致性的代码风格

你可以选择如下的工具:

JSLint
JSHint
ESLint
JSCS - 推荐

在团队开发中,这些工具对于编写代码非常的有帮助,能够帮助团队开发者强制执行规定的风格指南, 还能够通过静态分析捕获常见的错误。
  解析:用于检查被面试者是否有大型项目开发经验。

6、运算错误与程序员错误的区别

运算错误并不是bug,这是和系统相关的问题,例如请求超时或者硬件故障。而程序员错误就是所谓的bug。
解析:这个题目和Node关系并不大,用于考察面试者的基础知识。

7、使用NPM有哪些好处?

通过NPM,你可以安装和管理项目的依赖,并且能够指明依赖项的具体版本号。 对于Node应用开发而言,你可以通过package.json文件来管理项目信息,配置脚本, 以及指明项目依赖的具体版本。
  关于NPM的更多信息,你可以参考官方文档
  解析:它能考察面试者使用npm命令的基础知识和Node.js开发的实际经验。

8、什么是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.restore(); 

在单元测试中:Stub是完全模拟一个外部依赖,而Mock常用来判断测试通过还是失败。
有关Node.js的单元测试小结,你可以参考这个链接

解析:用于测试被面试者是否有测试的经验。如果被面试者知道什么是Stub, 那么可以继续问他是如何做单元测试的。

8、什么是测试金字塔?

测试金字塔指的是: 当我们在编写测试用例时,底层的单元测试应该远比上层的端到端测试要多。

7.png

当我们谈到HTTP API时,我们可能会涉及到:

有很多针对模型的底层单元测试
但你需要测试模型间如何交互时,需要减少集成测试

解析:本文主要考察被面试者的在测试方面的经验。

9、你最喜欢的HTTP框架以及原因

这题没有唯一的答案。本题主要考察被面试者对于他所使用的Node框架的理解程度, 考察他是否能够给出选择该框架的理由,优缺点等。常用的HTTP框架你可以参考这个网站

Statement
原文地址:https://blog.risingstack.com/node-js-interview-questions

References
http://zyzhang.github.io/blog/2013/04/28/test-pyramid/
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
http://segmentfault.com/a/1190000002921481

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容