Node.js几道面试题

874829624 3年前
   <h2>一些声明</h2>    <p>通过这些问题就来判断一个人的Node.js水平是不太严谨的,但是 它能让你对面试者在Node.js上的经验如何有个大概的了解。</p>    <p>但是显然,这些问题并不会告诉你面试者思考问题的方式。</p>    <p>Show me the code. 结合一些编程题来考察面试者吧</p>    <p>大家都是人,不要做一个死板不近人情的面试官哦。</p>    <p>什么是error-first的回调方式</p>    <p>Error-first回调方式用来同时传递error和data。将错误作为第一个参数,它就必须先检查看看有没有错误先。另外的参数就用来传递data了。</p>    <pre>  <code class="language-javascript">fs.readFile(filePath, function(err, data) {    if(err) {      //处理错误,这里的return很重要,如果发生错误,在此处就会停止了。      return console.log(err);    }    //传递data    console.log(data);  })</code></pre>    <p>你是如何避免回调地狱的?</p>    <ul>     <li> <p>模块化把回调函数分割成独立的函数</p> </li>     <li> <p>使用 <strong>控制流的库</strong> ,比如 <a href="/misc/goto?guid=4958977547967818500" rel="nofollow,noindex">async</a></p> </li>     <li> <p>generators结合Promise</p> </li>     <li> <p>async/await</p> </li>    </ul>    <p>Promise是什么?</p>    <p>概念不多说了,简单来说就是帮助你更好地处理异步操作的东西。</p>    <pre>  <code class="language-javascript">new Promise((resolve, reject) => {    setTimeout(() => {      resolve('result');    }, 100)  })    .then(console.log)    .catch(console.error)</code></pre>    <p>stub是什么? 举个例子?</p>    <p>stub是用来模拟组件/模块行为的东西,它在测试阶段为函数调用提供内部响应。</p>    <p>例子是写文件,但实际上并没有这么做</p>    <pre>  <code class="language-javascript">var fs = require('fs');    var writeFileStub = sinon.stub(fs, 'writeFile', function(path, data, cb) {    return cb(null)  })    expect(writeFileStub).to.be.called  writeFileStub.restore();</code></pre>    <p>如何保证你的HTTP cookies安全不受XSS攻击</p>    <p>在 set-cookie HTTP头部加上这几个信息:</p>    <ul>     <li> <p>HttpOnly-这个属性用来防止跨站脚本攻击,它不允许cookie被JavaScript代码获取。</p> </li>     <li> <p>secure-这个属性告诉浏览器只有在HTTPS连接时才发送cookie</p> </li>    </ul>    <p>像这样: Set-Cookit: sid=<cookit-value>; HttpOnly</p>    <p>下面这段代码有什么问题</p>    <pre>  <code class="language-javascript">new Promise((resolve, reject) => {    throw new Error('error')  }).then(console.log)</code></pre>    <p>then 后面没有跟上 catch ,这样的话如果出错的这段代码还是默默地运行,并不会告诉你哪里出错了。</p>    <p>修改后:</p>    <pre>  <code class="language-javascript">new Promise((resolve, reject) => {    throw new Error('error')  }).then(console.log).catch(console.error)</code></pre>    <p>如果你正在调试一个大型项目,你不知道哪个Promise可能会有问题,可以使用 unhandledRejection 。它会打印出所有未经处理的Promise异常</p>    <pre>  <code class="language-javascript">process.on('unhandledRejection', (err) => {    console.log(err)  })</code></pre>    <p>下面的代码有什么问题?</p>    <pre>  <code class="language-javascript">function checkApiKey(apiKeyFromDb, apiKeyReceived) {    if (apiKeyFromDb === apiKeyReceived) {      return true    }    return false  }</code></pre>    <p>说实话我刚看到的时候也是一脸懵逼,这有啥问题?不是很正常的一个if else代码吗。</p>    <p>不过这不是普通的if else代码,这是用来比较安全证书的代码,这个时候你不能泄露一丁点的信息,所以确保他们在一定的时间内进行比较。否则的你的应用就可能受到时序攻击了。</p>    <p>什么是时序攻击( <a href="/misc/goto?guid=4959733684171611189" rel="nofollow,noindex">timing attacks</a> )?Node.js使用的V8引擎试图从表示层面上优化代码。它一个字符一个字符地比较,一旦找到不符合它就停止比较。</p>    <p>你可以使用 <a href="/misc/goto?guid=4959733684254368288" rel="nofollow,noindex">cryptiles</a> 这个npm模块来解决这个问题</p>    <pre>  <code class="language-javascript">function checkApiKey(apiKeyFromDb, apiKeyReceived) {    return cryptiles.fixedTimeCimparison(apiKeyFromDb, apiKeyReceived)  }</code></pre>    <p>某乎上有个解释地挺好的 <a href="/misc/goto?guid=4959733684342626304" rel="nofollow,noindex">如何通俗地解释时序攻击(timing attack)?</a></p>    <p>下面的代码会输出什么</p>    <pre>  <code class="language-javascript">Promise.reso(1)    .then((x) => x + 1)    .then((x) => {throw new Error('My Error')})    .catch(() => 1)    .then((x) => x + 1)    .then((x) => console.log(x))    .catch(console.error)</code></pre>    <ol>     <li> <p>一个新的Promise被创造出来,它会解析参数1</p> </li>     <li> <p>解析后的值会被加上1(现在是2),并立即返回了这个2</p> </li>     <li> <p>解析的值被丢弃,抛出一个异常</p> </li>     <li> <p>异常被丢弃,新的值1被返回</p> </li>     <li> <p>catch后运行不会停止,在异常处理之前,它继续运行,一个新的,增加了1后的值2被返回</p> </li>     <li> <p>返回值被打印出来</p> </li>     <li> <p>这一行不会运行,因为没有异常</p> </li>    </ol>    <p> </p>    <p>来自:https://segmentfault.com/a/1190000008037987</p>    <p> </p>