前言:
2020年是多災多難的一年民泵,疫情持續(xù)至今癣丧,到目前,全世界的經(jīng)濟都受到不同程序的影響栈妆,各大公司裁員胁编,在這樣一片嚴峻的形式下厢钧,找工作更是難上加難。
企業(yè)的門檻提高嬉橙,第一早直,對于學歷的要求,必須學信網(wǎng)可查的統(tǒng)招本科市框;第二霞扬,對于技術(shù)的掌握程序,更多的是底層原理拾给,項目經(jīng)驗祥得,等等。
下面是面試幾周以來蒋得,總結(jié)的一些面試中常被問到的題目级及,還有吸取的一些前輩們分享的貼子,全部系統(tǒng)的羅列出來额衙,希望能夠幫到正在面試的人饮焦。
React.js
1. React生命周期
單個組件的生命周期
1.componentwillMount
(React17廢棄)
2.componentDidMount
3.componentWillReceiveProps
(React17替換成getDerivedStateFromProps
)
4.shouldComponentUpdate
5.componentWillUpdate
(React17替換成getSnapshotBeforeUpdate
)
6.componentDidUpdate
7.componentWillUnmount
父子組件的生命周期
大致和Vue相同,不同的是窍侧,react沒有局部更新县踢,更新父組件的同時也會更新子組件。
1.掛載:父componentWillMount -> 子componentWillMount -> 子componentDidMount -> 父componentDidMount
2.銷毀:父componentWillUnmount -> 子componentWillUnmount
3.更新
(1)只更新子:子shouldComponentUpdate -> 子componentWillUpdate -> 子componentDidUpdate
(2)更新父或同時更新:父shouldComponentUpdate -> 父componentWillUpdate -> 子componentWillReceiveProps-> 子shouldComponentUpdate -> 子componentWillUpdate -> 子componentDidUpdate -> 父componentDidUpdate
2. React17 生命周期改動
componentWillMount
componentWillRecieveProps
componentWIllUpdate
簡單來說就是這三個生命周期函數(shù)容易被誤解并濫用伟件,可能會對異步渲染造成潛在的問題硼啤。可用UNSAFE_xxx
來取消eslint
的報錯斧账。
- 新增三個生命周期
1.getDerivedStateFromProps(nextProps, prevState)
靜態(tài)方法谴返,所以不能使用this.setState。 用于替換componentWillReceiveProps
咧织,可以用來控制props
更新state
的過程嗓袱;它返回一個對象表示新的state
;如果不需要更新习绢,返回null
即可
2.getSnapshotBeforeUpdate(nextProps, prevState) 渠抹。用于替換componentWillUpdate
3.componendDidCatch(error, info)。新增闪萄,用于捕捉錯誤
3. React的通信方式
props
context梧却。可跨級通信桃煎,但不知道來源哪里不推薦使用篮幢。基于生產(chǎn)者消費者模式
redux和react-redux
用js實現(xiàn)發(fā)布訂閱模式
React17 會廢棄childContext 使用新API - createContext()为迈,并提供Provider和consumer組件三椿,類似Vue
4. setState
setState
是React
組件中用于更新數(shù)據(jù)和觸發(fā)渲染的函數(shù)缺菌,他的用法如下
this.setState(newState:object | updater: Function, callback?)
updater = (state, prop) => {}
同步和異步
setState
,何時同步搜锰,何時異步伴郁?
1.在react的生命周期勾子或react事件監(jiān)聽回調(diào)中使用
2.其他情況,如定時器回調(diào)蛋叼,原生事件監(jiān)聽回調(diào)焊傅,promise回調(diào)為什么setState是異步的?
-
setState
出發(fā)React
的更新生命周期函數(shù)4個函數(shù):shouldComponentUpdate
狈涮,componentWillUpdate
狐胎,render
,componentDidUpdate
歌馍。如果每一次setState
調(diào)用都走一圈生命周期握巢,并拿render
函數(shù)返回的結(jié)果會拿去做Virtual DOM比較和更新DOM樹,這個就比較費時間松却。 - 目前
React
會將setState
的效果放在隊列中暴浦,積攢著一次引發(fā)更新過程。為的就是把 Virtual DOM 和 DOM 樹操作降到最小晓锻,用于提高性能歌焦。
- setState如何實現(xiàn)
ReactComponent.prototype.setState = function (partialState, callback) {
// 更新的操作會放在數(shù)組里
this.updater.enqueueSetState(this, partialState);
if (callback) {
this.updater.enqueueCallback(this, callback, 'setState');
}};
- 總體流程如下:
1.將state
放入enqueueSetState
隊列中,并調(diào)用enqueueUpdate
處理要更新的Component
2.如果組件當前正處于update
中(isBatchingUpdates
)砚哆,則先將Component
存入dirtyComponent
中独撇。否則調(diào)用batchedUpdates
處理。
3.batchedUpdates
發(fā)起一次transaction.perform()
事務(wù)
4.事務(wù)會更新isBatchingUpdates
為false
躁锁,循環(huán)遍歷所有的dirtyComponents
券勺,調(diào)用updateComponent
刷新組件,并執(zhí)行它的pendingCallbacks
, 也就是setState
中設(shè)置的callback
灿里。
5. React的事件機制
合成事件
1.在react
中使用jsx語法綁定的事件并不是原生事件,而是一種合成事件SyntheticEvent
程腹。例如SyntheticEvent
,SyntheticKeyboardEvent
,SyntheticFocusEvent
等匣吊。他有以下特點:
2.默認的事件流是冒泡,如果以捕獲的方式來觸發(fā)事件的話寸潦,事件類型后面加一個后綴Capture
幾乎所有的事件代理(delegate
)到document
色鸳,達到性能優(yōu)化的目的,例如對于audio
见转、video
標簽命雀,存在一些媒體事件(例如onplay
、onpause
)斩箫,只能在這些標簽上進行事件綁定吏砂,綁定一個入口分發(fā)函數(shù)(dispatchEvent
)
3.對于每種類型的事件撵儿,擁有統(tǒng)一的分發(fā)函數(shù)dispatchEvent
4.事件對象(event
)是合成對象(SyntheticEvent
),不是原生的狐血。所以e.stopPropagation()
方法阻止的知識合成事件流的傳播淀歇。如何實現(xiàn)
React 事件機制分為事件注冊,和事件分發(fā)匈织,兩個部分浪默。
1.組件加載 (mountComponent
)、更新 (updateComponent
) 的時候缀匕,調(diào)用_updateDOMProperties
方法對props
進行處理纳决,將事件綁定在document
上,并存儲在EventPluginHub
中(訂閱發(fā)布中心)
2.回調(diào)統(tǒng)一是ReactEventListener
的dispatch
方法乡小。通過_dispatchListeners
里得到所有綁定的回調(diào)函數(shù)阔加,然后循環(huán)執(zhí)行里面的所有的回調(diào)函數(shù)
6. React16
- 新的核心算法 Fiber
-
render
可以返回數(shù)組,字符串 - 錯誤處理機制
-
Portals
組件 渲染外部的dom節(jié)點.createPortal API
- 更好 更快的服務(wù)端渲染
rendertoNodeStream
返回node
的流 - 體積更小 MIT協(xié)議
7. Fiber
Fiber
可以提升復雜React
應用的可響應性和性能劲件。Fiber
即是React
新的調(diào)度算法掸哑。每次有
state
的變化React
重新計算,如果計算量過大零远,瀏覽器主線程來不及做其他的事情苗分,比如rerender
或者layout
,那例如動畫就會出現(xiàn)卡頓現(xiàn)象牵辣。React
制定了一種名為Fiber
的數(shù)據(jù)結(jié)構(gòu)摔癣,加上新的算法,使得大量的計算可以被拆解纬向,異步化择浊,瀏覽器主線程得以釋放,保證了渲染的幀率逾条。從而提高響應性琢岩。React
將更新分為了兩個時期:
1.render/reconciliation
: 可打斷,React
在workingProgressTree
上復用current
上的Fiber
數(shù)據(jù)結(jié)構(gòu)來一步地(通過requestIdleCallback
)來構(gòu)建新的tree
师脂,標記處需要更新的節(jié)點担孔,放入隊列中。
2.commit
: 不可打斷吃警。在第二階段糕篇,React
將其所有的變更一次性更新到DOM上。
8. 函數(shù)式組件酌心,class組件拌消,受控組件,高級組件的概念
-
class
組件:類組件不僅允許你使用更多額外的功能安券,如組件自身的狀態(tài)和生命周期鉤子墩崩,也能使組件直接訪問store
并維持狀態(tài) - 函數(shù)式組件:當組件僅是接收
props
氓英,并將組件自身渲染到頁面時,該組件就是一個 '無狀態(tài)組件(stateless component
)'泰鸡,可以使用一個純函數(shù)來創(chuàng)建這樣的組件,即函數(shù)式組件 - 受控組件:在 HTML 中债蓝,類似
input, textarea
和select
這樣的表單元素會維護自身的狀態(tài),并基于用戶的輸入來更新盛龄。一個輸入表單元素饰迹,它的值通過React
的這種方式來控制,這樣的元素就被稱為"受控元素"余舶。 - 高級組件HOC:高階組件是一個以組件為參數(shù)并返回一個新組件的函數(shù)啊鸭,例如:
redux的connect函數(shù)
9. React-router
- BrowserHistory:h5歷史模式
- HashHistory:h5 hash模式
- MemoryHistory:和abstract模式類似
- StaticRouter:一個永遠不會改變位置的<Router>。這在服務(wù)器端渲染場景中非常有用
- NativeRouter:RN使用
10. Redux
-
state
: 數(shù)據(jù)匿值,即狀態(tài) -
Action
: 一個純對象赠制,攜帶這個操作的類型和數(shù)據(jù)信息 -
Action Creater
: 一個函數(shù),根據(jù)指定參數(shù)挟憔,來生成一個Action
钟些,目的是減少代碼量 -
Reducer
: 一個純函數(shù),用來修改應用的狀態(tài)绊谭,接收當前State
和Action
政恍,返回一個新的State
。
1.不得改寫參數(shù)
2.不得調(diào)用系統(tǒng)的I/O的API
3.不得調(diào)用Date.now()
或者Math.random()
等不純的方法达传,因為每次得到的結(jié)果會不一樣
4.不能改變State
篙耗,必須返回一個新的對象,具體可以使用{...obj}
運算符或者Object.assign()
來操作 -
combineReducers
: 一個函數(shù)宪赶,將多個小的Reducer
合并成一個大的Reducer
-
Store
: 數(shù)據(jù)存儲中心
1.Store.getState()
獲取Store
當前的狀態(tài)
2.Store.dispatch()
分派一個Action
宗弯,用來修改Store
的狀態(tài),從View中發(fā)出Action的唯一方法
3.Store.subscribe()
訂閱一個監(jiān)聽器搂妻,當Store
的狀態(tài)發(fā)生改變的時候蒙保,執(zhí)行函數(shù) -
Middlewares
: 中間件, 中間件實際上就是一個攔截器,本質(zhì)是一個函數(shù)欲主,攔截所有的Action追他,并執(zhí)行特定的操作
compose
函數(shù),將[f1, f2, f3] => f1(f2(f3(x)))
11. Redux數(shù)據(jù)流
- Redux 應用中數(shù)據(jù)的生命周期遵循下面 4 個步驟:
調(diào)用 store.dispatch(action)岛蚤。
Redux store 調(diào)用傳入的 reducer 函數(shù)。
根 reducer 應該把多個子 reducer 輸出合并成一個單一的 state 樹懈糯。
Redux store 保存了根 reducer 返回的完整 state 樹涤妒。
# Node.js
1. eventloop
基本流程
1.timers:執(zhí)行滿足條件的setTimeout、setInterval回調(diào)赚哗。[uv__run_timers函數(shù)]
2.I/O callbacks:是否有已完成的I/O操作的回調(diào)函數(shù)她紫,來自上一輪的poll殘留硅堆。[uv__run_pending函數(shù)]
3.idle,prepare:node內(nèi)部特定的階段贿讹,在I/O輪詢開始前做一些特定的回調(diào)渐逃,可忽略 [uv__run_idle, uv__run_prepare函數(shù)]
4.poll:輪詢,等待還沒完成的I/O事件民褂,會因timers和超時時間等結(jié)束等待茄菊。[uv__io_poll(loop, timeout)函數(shù)]
5.check:執(zhí)行setImmediate的回調(diào)。[uv__run_check函數(shù)]
6.close callbacks:關(guān)閉所有的closing handles赊堪,一些onclose事件面殖,例如7.socket.on("close",func)。[ uv__run_closing_handles(loop)函數(shù)]
重復以上步驟哭廉。經(jīng)典例子
瀏覽器環(huán)境:time1脊僚,promise1,time2遵绰,promise2
node11以下:time1辽幌,time2,promise1椿访,promise2
node11及以上:time1乌企,promise1,time2赎离,promise2
在 node 11 版本中逛犹,node 下 Event Loop 已經(jīng)與瀏覽器趨于相同。我們可以用瀏覽器的微任務(wù)和宏任務(wù)解釋梁剔,11版本前的timer虽画,由于到期時間相近,會在timer階段合并執(zhí)行荣病。所以打出time1后码撰,打印time2。
2. koa 洋蔥模型
koa洋蔥式模型: koa各個中間件合并執(zhí)行个盆,結(jié)合next()形成一種串行機制脖岛,并且是支持異步。如請求順序進入1颊亮,2柴梆,3,4终惑,響應順序從4绍在,3,2,1出來
1.compose函數(shù)支持中間件和next
2.async/await支持異步洋蔥模式實現(xiàn)了:
1.context的保存和傳遞
2.中間件的管理和next的實現(xiàn)