如下答案僅供參考,大部分題目都是考察靈活應用某些概念,不是生記硬背的javascript
QA:咱們都知道nodejs是單線程的,可是若是仔細看過Nodejs啓動的進程,你仍是會發現實際上是有7個線程的。那麼請問這7個線程都是負責哪些工做的?java
單線程只是由於執行js代碼的只有一個,這個也叫做主線程。可是像GC這些事情是不會主線程上執行的,所以7個線程包括了:node
QA:瞭解過v8嗎?v8裏面也有一個叫作context的東西,每當咱們須要切換上下文的時候都會切換這個context,好比一個worker到另一個worker。可是切換上下文涉及到堆棧以及一些別的操做,能夠說是比較費時的。那麼v8裏面是用了什麼技術來優化這個上下文的切換?react
該題目考查對v8的基本瞭解程度,若是有看過v8的基本官方文檔介紹的話,都知道V8利用大量緩存
來提升context切換的成本。正則表達式
參考:[譯文]V8學習的高級進階express
QA:作過Nodejs的進程狀態信息監控嗎?除了通常監控的CPU、內存以外,可能還須要監控event loop的平均調度時間,那麼請問有什麼辦法能夠統計到event loop的延遲時間呢?api
該題目考察對event loop的瞭解,若是知道event loop的原理,那麼咱們能夠主動加入一個定時器,而後就能夠計算加入定時器的時間和回調函數被調用的時間差與定時器設置的超時時間之差,兩者即是event loop的延遲時間。數組
僞代碼實現:promise
const now = Date.now() // 若是須要精度更加精確,可使用process.hrtime.bigint()
setTimeout(() => {
const cost = Date.now() - now
const eventloopDelay = cost - 100 // 這個時間即是eventloop的延遲時間
}, 100)
複製代碼
QA:說一下下面代碼的打印結果:瀏覽器
const EventEmitter = require('events')
class EE extends EventEmitter {}
const yy = new EE()
console.log('測試開始')
yy.on('event', () => console.log('我是EventEmitter觸發的事件回調'))
setTimeout(() => {
console.log('0 毫秒後到期的定時器回調1')
process.nextTick(() => console.log('我是0毫秒定時器1加塞的一個微任務'))
}, 0)
setTimeout(() => {
console.log('0 毫秒後到期的定時器回調2')
process.nextTick(() => console.log('我是0毫秒定時器2加塞的一個微任務'))
}, 0)
setImmediate(() => console.log('immediate 當即回調'))
process.nextTick(() => console.log('process.nextTick 的第一次回調'))
new Promise((resolve) => {
console.log('我是promise')
}).then(() => {
yy.emit('event')
process.nextTick(() => console.log('process.nextTick 的第二次回調'))
console.log('promise 第一次回調')
})
.then(() => console.log('promise 第二次回調'))
console.log('測試結束?')
複製代碼
該題的解析參考:js語言中那些讓你抓狂又容易混淆的概念(建議收藏)
QA:說一下當請求:curl 127.0.0.1:3000/api/test1
的時候下面代碼的打印結果:
const express = require('express')
const app = express()
const sleep = (mseconds) => new Promise((resolve) => setTimeout(() => {
console.log('sleep timeout...')
resolve()
}, mseconds))
app.use(async (req, res, next) => {
console.log('I am the first middleware')
const startTime = Date.now()
console.log(`================ start ${req.method} ${req.url}`, { query: req.query, body: req.body });
next()
const cost = Date.now() - startTime
console.log(`================ end ${req.method} ${req.url} ${res.statusCode} - ${cost} ms`)
})
app.use((req, res, next) => {
console.log('I am the second middleware')
next()
console.log('second middleware end calling')
})
app.get('/api/test1', async(req, res, next) => {
console.log('I am the router middleware => /api/test1')
await sleep(2000)
res.status(200).send('hello')
})
app.listen(3000)
console.log('server listening at port 3000')
複製代碼
該題的解析參考:js語言中那些讓你抓狂又容易混淆的概念(建議收藏)
QA:請將下面代碼使用修飾器的功能,將全部公共部分抽象出一個修飾函數,以即可以簡單使用在各個請求之中
class allApisClass {
async fetchGoods(params) {
Toast.loading('請稍候...')
try {
const info = await fetchHandle(fetchGoods, params)
Toast.close()
return info
} catch (err) {
Toast.close()
Toast.error(err.msg)
}
}
}
複製代碼
好比抽象後的修飾器是:decorator,那麼我能夠這麼簡單地使用:
class allApisClass {
@decortor()
async fetchGoods(params){
const info = await fetchHandle(fetchGoods, params)
return info
}
}
複製代碼
請實現對應的修飾器函數:
function decorator(target, propertyKey, descriptor) {
}
複製代碼
該題目的解析參考:你覺得裝飾器那麼容易學嗎?
QA:你以爲使用react框架的時候,用componentWillUnMount來統計訪問時間靠譜嗎?爲何?若是是你作,你會怎麼實現?
統計頁面訪問時間是從頁面渲染完成開始計時到頁面關閉,若是使用componentWillUnMount來統計頁面關閉的時間是統計不到的,由於當頁面關閉時並不會觸發這個事件,該事件可以被觸發存在的前提是頁面仍然在瀏覽器中顯示,因此是不靠譜的。監聽頁面關閉的只能使用原生的unload
事件。
QA:如何快速統計字符串某個字符出現的次數?如何使用正則表達式快速計算出現次數最多的字符?
第一個問題的答案是利用split
:
str.split('a').length - 1
複製代碼
第二個問題的答案是利用正則表達式的捕捉組概念:/(\w)\1+/g
const str = 'fhsdfhdsofsifjisffs'
const arr = str.split(''); //把字符串轉換爲數組
//首先進行排序,這樣結果會把相同的字符放在一塊兒,而後再轉換爲字符串
const str = arr.sort().join('')
const value = ''
const index = 0
//匹配字符,且重複這個字符,重複次數至少一次
const re = /(\w)\1+/g
str.replace(re, function ($0, $1) {
console.log($0, $1)
//若是index保存的值小於$0的長度就進行下面的操做
if (index < $0.length) {
index = $0.length;
value = $1;
}
})
複製代碼