当前位置: 首页 > 后端技术 > Node.js

Node.js面试题2017

时间:2023-04-03 13:31:16 Node.js

译者注:从ECMAScript标准、Node.js语法和NPM模块来看,Node.js的发展让人眼花缭乱,所以面试题也要与时俱进。原文:Node.js面试问答(2017版)译者:Fundebug为了保证可读性,本文采用意译而非直译。问题什么是错误优先回调函数?如何避免回调地狱?什么是承诺?使用什么工具来确保一致的编码风格?为什么?什么是存根?举个例子什么是测试金字塔?举个例子,你最喜欢哪个HTTP框架?为什么?cookies如何防止XSS攻击?如何保证依赖的安全性?回答1.什么是错误优先回调函数?错误优先回调函数(Error-FirstCallback)用于同时返回错误和数据。第一个参数返回错误,并验证错误;其他参数用于返回数据。fs.readFile(filePath,function(err,data){if(err){//处理错误returnconsole.log(err);}console.log(data);});2.如何避免回调地狱?可以通过以下方式避免回调地狱:模块化:将回调函数转换为独立的函数使用流控库,例如aync使用Promise使用aync/await(参考Async/Await替代Promise的6个原因)3.什么是Promise?Promise可以帮助我们更好的处理异步操作。在下面的示例中,结果字符串将在100毫秒后打印。catch用于错误处理。可以链接多个Promise。newPromise((resolve,reject)=>{setTimeout(()=>{resolve('result');},100)}).then(console.log).catch(console.error);4.使用什么工具保证代码风格一致?为什么?在与团队合作时,确保代码风格一致非常重要,这样团队成员可以更快地修改代码,而不必每次都去适应新的风格。这些工具可以帮助我们:如果你对ESLintStandard感兴趣,可以参考JavaScriptCleanCoding5。存根是什么?Stub如何用于模拟模块行为的示例。测试时,存根可以返回函数调用的模拟结果。例如,当我们写入文件时,我们实际上并不需要实际写入。varfs=require('fs');varwriteFileStub=sinon.stub(fs,'writeFile',function(path,data,cb){returncb(null);});期望(writeFileStub).to.be。调用;writeFileStub.restore();6。什么是测试金字塔?举个例子说明,测试金字塔反映了需要编写的单元测试、集成测试和端到端测试的比例:在测试HTTP接口时,应该是这样的:很多单元测试,分别测试每个模块的集成测试(需要存根)较少,测试各个模块之间的交互(依赖不能存根)少量端到端测试调用真正的接口(依赖不能存根)7.哪个HTTP框架做你最喜欢?为什么?这个问题的标准答案。需要描述框架的优缺点,可以体现开发者对框架的熟悉程度。8、cookies如何防止XSS攻击?XSS(Cross-SiteScripting,跨站脚本攻击)是指攻击者在返回的HTML中插入JavaScript脚本。为了减轻这些攻击,有必要在HTTP标头中配置set-cookie:HttpOnly-这个属性可以防止跨站点脚本,因为它会阻止Javascript脚本访问cookie。secure-此属性告诉浏览器仅在请求为HTTPS时发送cookie。结果应该是这样的:Set-Cookie:sid=;仅限HTTP。如果使用Express,则默认配置cookie-session。9、如何保证依赖的安全?在编写Node.js应用程序时,它很可能依赖于数百或数千个模块。比如直接使用Express依赖27个模块。因此,手动检查所有依赖项是不切实际的。唯一的方法是自动对依赖项进行安全检查,有以下工具可供选择:RisingStack的npmoutdatedTraceNSPGreenKeeperSnyk其他问题1.这段代码有什么问题?newPromise((resolve,reject)=>{thrownewError('error')}).then(console.log)then之后没有捕获。在这种情况下,错误将被忽略。你可以这样解决问题:newPromise((resolve,reject)=>{thrownewError('error')}).then(console.log).catch(console.error)在调试大型项目时,你可以使用监控unhandledRejection事件来捕获所有未处理的Promise错误:process.on('unhandledRejection',(err)=>{console.log(err)})2.这段代码有什么问题?functioncheckApiKey(apiKeyFromDb,apiKeyReceived){if(apiKeyFromDb===apiKeyReceived){returntrue}returnfalse}比对密码时,不能泄露任何信息,所以比对必须在固定时间内完成。否则,您可以使用定时攻击来攻击您的应用程序。为什么会这样?Node.js使用V8引擎,从性能角度优化代码。它逐个字母地比较字符串,并在发现不匹配时停止。当攻击者的密码更准确时,比较需要更长的时间。因此,攻击者可以通过比较时间长短来判断密码的正确性。使用cryptiles可以解决这个问题:functioncheckApiKey(apiKeyFromDb,apiKeyReceived){returncryptiles.fixedTimeComparison(apiKeyFromDb,apiKeyReceived)}3.这段代码的输出是什么?Promise.resolve(1).then((x)=>x+1).then((x)=>{thrownewError('MyError')}).catch(()=>1).then((x)=>x+1).then((x)=>console.log(x)).catch(console.error)答案是2,逐行解释如下:CreateanewPromisewitharesolve1.x的值为1,加上1.x后返回2,但没有使用。抛出错误。错误被捕获,但不被处理。返回1。x为1,加上1后返回2。x为2,打印2。不会执行,因为没有抛出错误。参考链接Node.js10道常见面试题XSS-窃取Cookies101关于FundebugFundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、ReactNative、Node.js和Java实时BUG监控。自2016年双十一正式上线以来,Fundebug累计处理了7亿+错误事件,得到了谷歌、360、金山词霸、人民网等众多知名用户的认可。欢迎免费试用!转载版权声明请注明作者Fundebug及本文地址:https://blog.fundebug.com/2017/04/10/nodejs-interview-2017/