Node.js面試題之2017

譯者按:ECMAScript標準Node.js語法以及NPM模塊角度來看,Node.js的發展讓人應接不暇,那麼面試題也得與時俱進。javascript

原文: Node.js Interview Questions and Answers (2017 Edition)html

譯者: Fundebugjava

爲了保證可讀性,本文采用意譯而非直譯。

問題node

- 什麼是錯誤優先的回調函數?
- 如何避免回調地獄?
- 什麼是Promise?
- 用什麼工具保證一致的代碼風格?爲何要這樣?
- 什麼是Stub?舉例說明
- 什麼是測試金字塔?舉例說明
- 最喜歡哪一個HTTP框架?爲何?
- Cookies如何防範XSS攻擊?
- 如何保證依賴的安全性?git

答案github

1. 什麼是錯誤優先的回調函數?面試

錯誤優先的回調函數(Error-First Callback)用於同時返回錯誤和數據。第一個參數返回錯誤,而且驗證它是否出錯;其餘參數用於返回數據。express

 

fs.readFile(filePath, function(err, data)
{
if (err)
{
// 處理錯誤
return console.log(err);
}
console.log(data);
});

  

2. 如何避免回調地獄?npm

如下方式能夠避免回調地獄:json

- 模塊化: 將回調函數轉換爲獨立的函數
- 使用流程控制庫,例如[aync](https://www.npmjs.com/package/async)
- 使用Promise
- 使用aync/await(參考[Async/Await替代Promise的6個理由](https://blog.fundebug.com/2017/04/04/nodejs-async-await/))

3. 什麼是Promise?

Promise能夠幫助咱們更好地處理異步操做。下面的示例中,100ms後會打印result字符串。catch用於錯誤處理。多個Promise能夠連接起來。

 

new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('result');
}, 100)
})
.then(console.log)
.catch(console.error);

 

4. 用什麼工具保證一致的代碼風格?爲何要這樣?

團隊協做時,保證一致的代碼風格是很是重要的,這樣團隊成員才能夠更快地修改代碼,而不須要每次去適應新的風格。這些工具能夠幫助咱們:

- [ESLint](http://eslint.org/)
- [Standard](https://standardjs.com/)

感興趣的話,能夠參考JavaScript Clean Coding

5. 什麼是Stub?舉例說明

Stub用於模擬模塊的行爲。測試時,Stub能夠爲函數調用返回模擬的結果。好比說,當咱們寫文件時,實際上並不須要真正去寫。

 

var fs = require('fs');

var writeFileStub = sinon.stub(fs, 'writeFile', function(path, data, cb)
{
return cb(null);
});

expect(writeFileStub).to.be.called;
writeFileStub.restore();

 

6. 什麼是測試金字塔?舉例說明

測試金字塔反映了須要寫的單元測試集成測試以及端到端測試的比例:

測試HTTP接口時應該是這樣的:

- 不少單元測試,分別測試各個模塊(依賴須要stub)
- 較少的集成測試,測試各個模塊之間的交互(依賴不能stub)
- 少許端到端測試,去調用真正地接口(依賴不能stub)

7. 最喜歡哪一個HTTP框架?爲何?

這個問題標準答案。須要描述框架的優缺點,這樣能夠反映開發者對框架的熟悉程度。

8. Cookies如何防範XSS攻擊?

XSS(Cross-Site Scripting,跨站腳本攻擊)是指攻擊者在返回的HTML中插入JavaScript腳本。爲了減輕這些攻擊,須要在HTTP頭部配置set-cookie:

- HttpOnly - 這個屬性能夠防止cross-site scripting,由於它會禁止Javascript腳本訪問cookie。
- secure - 這個屬性告訴瀏覽器僅在請求爲HTTPS時發送cookie。

結果應該是這樣的: Set-Cookie: sid=<cookie-value>; HttpOnly. 使用Express的話,cookie-session默認配置好了。

9. 如何保證依賴的安全性?

編寫Node.js應用時,極可能依賴成百上千的模塊。例如,使用了Express的話,會直接依賴27個模塊。所以,手動檢查全部依賴是不現實的。惟一的辦法是對依賴進行自動化的安全檢查,有這些工具可供選擇:

- npm outdated
- [Trace by RisingStack](https://trace.risingstack.com/)
- [NSP](https://nodesecurity.io/)
- [GreenKeeper](https://greenkeeper.io/)
- [Snyk](https://snyk.io/)

附加題

1. 這段代碼有什麼問題?

 

new Promise((resolve, reject) =>
{
throw new Error('error')
})
.then(console.log)

 

then以後沒有catch。這樣的話,錯誤會被忽略。能夠這樣解決問題:

 

new Promise((resolve, reject) =>
{
throw new Error('error')
})
.then(console.log).catch(console.error)

 

調試一個大型的項目時,可使用監控unhandledRejection事件來捕獲全部未處理的Promise錯誤:

 

process.on('unhandledRejection', (err) =>
{
console.log(err)
})

 

------

2. 這段代碼有什麼問題?

 

function checkApiKey(apiKeyFromDb, apiKeyReceived)
{
if (apiKeyFromDb === apiKeyReceived)
{
return true
}
return false
}

 

比較密碼時,不能泄露任何信息,所以比較必須在固定時間完成。不然,可使用timing attacks來攻擊你的應用。爲何會這樣呢?Node.js使用V8引擎,它會從性能角度優化代碼。它會逐個比較字符串的字母,一旦發現不匹配時就中止比較。當攻擊者的密碼更準確時,比較的時間越長。所以,攻擊者能夠經過比較的時間長短來判斷密碼的正確性。使用[cryptiles](https://www.npmjs.com/package/cryptiles)能夠解決這個問題:

 

function checkApiKey(apiKeyFromDb, apiKeyReceived)
{
return cryptiles.fixedTimeComparison(apiKeyFromDb, apiKeyReceived)
}

 

3. 這段代碼的輸出是什麼?

 

Promise.resolve(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)

 

答案是2,逐行解釋以下:

1. 建立新的Promise,resolve值爲1。
2. x爲1,加1以後返回2。
3. x爲2,可是沒有用到。拋出一個錯誤。
4. 捕獲錯誤,可是沒有處理。返回1。
5. x爲1,加1以後返回2。
6. x爲2,打印2。
7. 不會執行,由於沒有錯誤拋出。

關於Fundebug:

Fundebug專一於JavaScript、微信小程序、微信小遊戲、支付寶小程序、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了7億+錯誤事件,獲得了Google、360、金山軟件、百姓網等衆多知名用戶的承認。歡迎免費試用!

 

 

參考連接:

- 10個常見的Node.js面試題
- XSS - Stealing Cookies 101

版權聲明:

轉載時請註明做者Fundebug

以及本文地址:https://blog.fundebug.com/2017/04/10/nodejs-interview-2017/

相關文章
相關標籤/搜索