Node 面試題整理

1:簡述require()模塊加載機制

答:在node中文件即模塊,分為原生模塊和3種文件模塊。

具體加載順序如下圖

2:node導出模塊有哪2種方式贾虽,說說它們的區(qū)別?

答:真正的接口是module.exports, 初始值為{}熙侍。exports是對module.exports的引用榄鉴,指向module.exports。在require()的時候蛉抓,返回的是module.exports而不是exports庆尘。

3:請簡述下Node事件循環(huán)機制

答:Node采用的是單線程異步非阻塞I/O模式。

主線程執(zhí)行同步任務巷送,異步I/O交給libuv處理驶忌。

libuv將建立的所有I/O操作內(nèi)容綁定到單個線程上。只要每個事件循環(huán)在不同的線程中笑跛,就可以運行多個事件循環(huán)付魔。

libuv將不同的任務交給不同的線程來處理。處理完成后會將對應事件的狀態(tài)轉(zhuǎn)為pending飞蹂。

然后在下一次事件循環(huán)的時候按順序取來執(zhí)行几苍。每一次事件循環(huán)都只會執(zhí)行一個回調(diào),從而避免了競爭的發(fā)生陈哑。

libuv解釋:libuv是一個多平臺支持庫妻坝,主要關注異步I/O伸眶。它主要為node.js的使用而開發(fā),同時也被Luvit刽宪、Julia厘贼、pyuv等使用。libuv為Node.js提供了跨平臺圣拄、線程池嘴秸、事件池、異步I/O等能力庇谆,是Node.js如此強大的關鍵岳掐。

每個事件循環(huán)包含的7階段(每個階段結束后都會執(zhí)行所有的微任務):

1:run due timers 執(zhí)行到期的計時器,如:setTimeout族铆、setInterval等岩四。

2:call pending callbacks 執(zhí)行轉(zhuǎn)入pending狀態(tài)的觀察者的回調(diào)函數(shù)。大多數(shù)情況下哥攘,在輪詢I/O之后立即調(diào)用所有I/O回調(diào)剖煌。但是在某些情況下,調(diào)用此類回調(diào)會被推遲到下一個循環(huán)迭代去逝淹。如果先前的迭代推遲了任何I/O回調(diào)耕姊,它在將在此時運行。

3:run idle handles 如果idle句柄是活躍的栅葡,每一次迭代循環(huán)都會執(zhí)行茉兰。

4:run prepare handles 執(zhí)行prepare句柄的回調(diào)。在循環(huán)阻止I/O前執(zhí)行prepare 句柄的回調(diào)函數(shù)欣簇。

5:poll for I/O 計算出輪詢超時時間规脸,并以此時間作為阻塞I/O的持續(xù)時間,等待還未返回的I/O回調(diào)熊咽。

6:run check handles 執(zhí)行check handles的回調(diào)函數(shù)莫鸭。check handles本質(zhì)上是prepare的對應物。

7:call close callbacks 執(zhí)行關閉回調(diào)函數(shù)横殴。如果一個句柄被uv_close關閉將執(zhí)行關閉回調(diào)函數(shù)被因。

注意:node事件循環(huán)比js事件循環(huán)多了兩個異步,setImmediate(宏任務)衫仑、process.nextTick(微任務)梨与。process.nextTick的優(yōu)先級高于promise().then()。


3:談談V8的垃圾回收機制

答:V8是由google公司開發(fā)的javascript和webAssembly引擎文狱,用c++編寫粥鞋。它被用在了Chrome瀏覽器和Node中。它實現(xiàn)了ECMAScript和WebAssembly, 可以運行在Win7+(含Win7)瞄崇、macOS10.12+陷虎、Linux等系統(tǒng)上到踏。V8也可以三都運行,或者被嵌入到任何由C++編寫的程序中尚猿。

內(nèi)存限制:

V8只能使用部分內(nèi)存,默認大小為64位系統(tǒng)1.4G楣富,32位系統(tǒng)為0.7G凿掂。當然你也可以自定義大小。建議是不要超過1.5G纹蝴。因為垃圾回收1.5G的堆內(nèi)存V8需要花費50毫秒以上庄萎,做一次非增量式的垃圾回收甚至需要1秒以上,性能響應明顯下降塘安。

內(nèi)存分類:

1:新生代內(nèi)存空間 (主要用來存放存活時間較短的對象)

2:老生代內(nèi)存空間 (主要用來存放存活時間較長的對象)

新生代垃圾回收:

主要通過Scavenge算法進行糠涛,主要通過停止-復制的方式實現(xiàn)垃圾回收,具體采用了Cheney算法兼犯。

Cheney將內(nèi)存空間一分為二忍捡,被分出來的空間叫做semi-space(半空間),一個半空間處于使用中叫做From切黔,一個半空間處于閑置狀態(tài)叫做To砸脊。

垃圾回收在運行時,會檢查From空間的存活對象纬霞,將存活對象復制到To中凌埂,而死亡對象占用的空間就會被釋放。然后交換From和To角色繼續(xù)重復上邊的操作诗芜。當一個對象經(jīng)過多次復制后依然存活瞳抓,我們就認為該對象生命周期較長,會被移到老生代內(nèi)存中去伏恐。

老生代垃圾回收:

老生代垃圾回收分為Mark Sweep(標記清除)和 Mark Compact(標記合并)兩種方式孩哑。

Mark Sweep:標記需要回收的對象,然后在垃圾回收的時直接清除釋放空間脐湾。這個有個問題就是臭笆,釋放后的空閑時間是碎片化的,再次分配的時候可能因為單個碎片塊大小小于需要分配的空間大小而造成無法再次分配內(nèi)存秤掌。

Mark Compact:標記存活的對象統(tǒng)一移到一邊愁铺,死亡對象移動到另外一邊,然后垃圾回收清除死亡對象釋放空間闻鉴。

以上三種垃圾回收算法比較:

在 Mark-Sweep 和 Mark-Compact 之間茵乱,由于 Mark-Compact 需要移動對象,所以它的執(zhí)行速度不可能很快孟岛,所以在取舍上瓶竭,V8 主要使用 Mark-Sweep督勺,在空間不足以從新生代中晉升過來的對象進行分配時才使用 Mark-Compact 。為了避免出現(xiàn) JavaScript應用邏輯與垃圾回收器看到的不一致的情況斤贰,垃圾回收的3種算法都需要將應用邏輯暫停下來智哀,這種行為稱為“全停頓” (stop-the-world)。由于新生代配置的空間較小荧恍,存活對象較少瓷叫,全停頓對新生代影響不大。但老生代通常配置的空間較大送巡,且存活對象較多摹菠,全堆垃圾回收(full垃圾回收)的標記、清除骗爆、整理等動作造成的停頓就會比較可怕次氨。

增量標記:

為了降低全堆垃圾回收帶來的停頓時間,V8先從標記階段入手摘投,將原本要一口氣停頓完成的動作改成增量標記(Incremental Marking)煮寡,也就是拆分為許多小“步進”,每做完一“步進”就讓JavaScript應用邏輯執(zhí)行一小會兒谷朝,垃圾回收和應用邏輯交替執(zhí)行直到標記階段完成洲押。

增量標記允許堆的標記發(fā)生在幾次5-10毫秒(移動設備)的小停頓中。

增量標記在堆的大小達到一定的閾值時啟用圆凰,啟用之后每當一定量的內(nèi)存分配后杈帐,腳本的執(zhí)行就會停頓并進行一次增量標記。就像普通的標記一樣专钉,增量標記也是一個深度優(yōu)先搜索挑童,并同樣采用白灰黑機制來分類對象。但增量標記和普通標記不同的是跃须,對象的圖譜關系可能發(fā)生變化站叼!

查看V8內(nèi)存使用情況:

查看內(nèi)存使用情況:process.memoryUsage()

查看操作系統(tǒng)總內(nèi)存:os.totalmem()

查看操作系統(tǒng)總空閑內(nèi)存:os.freemem()

4:說說排查內(nèi)存泄露的方法

答:內(nèi)存泄露通常有兩種情況,一種是容易復現(xiàn)的菇民,一種是不容易復現(xiàn)的尽楔。

對于容易復現(xiàn)的我們在測試環(huán)境中模擬排查即可。

對于不容易復現(xiàn)的我們就要借助內(nèi)存快照第练,可以使用devtool查看內(nèi)存快照阔馋,heapdump保存內(nèi)存快照。heapdump保存的內(nèi)存快照只會有Node環(huán)境中的對象娇掏,如果使用node-inspector快照中就會包含前端變量呕寝,容易造成干擾。

推薦使用:npm install heapdump -target=Node.js 進行安裝婴梧。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末下梢,一起剝皮案震驚了整個濱河市客蹋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌孽江,老刑警劉巖档玻,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爱态,死亡現(xiàn)場離奇詭異鸟缕,居然都是意外死亡目代,警方通過查閱死者的電腦和手機琉预,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門尿褪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來壤巷,“玉大人明也,你說我怎么就攤上這事洼冻≌钙纾” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵撞牢,是天一觀的道長率碾。 經(jīng)常有香客問我,道長屋彪,這世上最難降的妖魔是什么所宰? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮畜挥,結果婚禮上仔粥,老公的妹妹穿的比我還像新娘。我一直安慰自己蟹但,他們只是感情好躯泰,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著华糖,像睡著了一般麦向。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上客叉,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天诵竭,我揣著相機與錄音,去河邊找鬼兼搏。 笑死卵慰,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的向族。 我是一名探鬼主播呵燕,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼件相!你這毒婦竟也來了再扭?” 一聲冷哼從身側(cè)響起氧苍,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泛范,沒想到半個月后让虐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡罢荡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年赡突,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片区赵。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡惭缰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出笼才,到底是詐尸還是另有隱情漱受,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布骡送,位于F島的核電站昂羡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏摔踱。R本人自食惡果不足惜虐先,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望派敷。 院中可真熱鬧蛹批,春花似錦、人聲如沸膀息。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潜支。三九已至甸赃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冗酿,已是汗流浹背埠对。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留裁替,地道東北人项玛。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像弱判,于是被迫代替她去往敵國和親襟沮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容