談談前端面試中遇到的問題(一)

前言

歇了一個多月,終因而拿了駕照,也算是完成了人生計劃中的其中一個,沒有過去2019年。css

2019年的所有計劃估計是完不成了,想要完成多少,仍是要看接下來的努力。react

歇息了一個月,最近剛剛開始面試,前兩個面試是一點準備都沒有,去面試也僅僅是考慮一下本身如今的狀況,有目的的去準備面試。面試

一個多月,感受忘記了不少,在此記下面試中遇到的問題,以來自勉。redux

題目

一、React context是如何工做的?數組

更多的時候,咱們在組件層級間進行數據傳遞,都會用到props,可是若是須要傳遞的子屬性太多,個人組件屬性就有可能會寫得很長。而這時候,context或許是個解決方案。promise

context做用是爲了不在組件間層層傳遞變量。咱們能夠經過createContext(null)來建立一個新的context,新建立的context包含一個Provider以及一個Consumer。瀏覽器

若是咱們想要在組件間層層傳遞變量,則須要用Provider來包裹父組件,在Provider包裹下的層層組件,均可以經過Consumer包裹子組件來讀取傳遞的變量。緩存

二、react兄弟組件間通訊方式服務器

第一種笨方法,子組件1傳遞給父組件,接着傳遞給子組件2.app

第二種利用事件的發佈訂閱。

第三種你們都知道,用redux管理數據。原理和第一種+第二種差很少,不過是更規範的數據管理和數據流傳遞和事件發佈訂閱方式。

三、setState原理

先說明,setState既能夠同步也能夠異步。好比在setTimeout的包裹中setState會當即執行。咱們正常方式下的setState是異步狀態,由於React中的狀態合併,使得屢次操做,在最終的一次時間點作數據更新,避免每次都執行DOM操做耗費性能。

那麼setState的原理大體能夠描述爲:設置新的state會將這個新的state存儲在一個狀態隊列,若是達到批量更新的節點,則進行狀態合併,更新成組件最終的state或者props。

而setState就是將新的狀態放置在狀態隊列中的操做函數,由此也能夠知道,若是直接更改state,如this.state = 1這樣的操做,並不會直接更新狀態隊列的,因此這個操做是無效的。

這個只是簡單的回答,若是要從源碼上回答,還得知道setState的事務機制。

四、PureComponent和Component的區別

PureComponent會幫助咱們在shouldComponentUpdate生命週期中進行一次淺比較。

淺比較只檢查值類型的值和引用類型的引用是否相等,若是要作比較深刻的判斷,仍是應該在shouldComponentUpdate生命週期自行判斷。

五、如何避免重複渲染。

這個問題,其實也至關因而React性能問題的一個。

首先,不要在render中爲函數綁定參數,每次參數更改都會建立新的函數,則會刷新組件或者子組件。

其次,儘可能不要使用派生數據綁定到組件屬性,每次傳遞props都會生成新的數據,即便數據同樣,也會致使重複渲染。

還有,組件設定的key值要和裏和固定,這樣當數據一致和key一致的時候,組件也不會從新渲染。

最終,你還能夠修改shouldComponentUpdate生命週期返回值來手動達到不重複渲染的目的。

六、getDerivedStateFromProps幹了什麼?

getDerivedStateFromProps是React16.3中新增的一個靜態的生命週期函數,將來即將移除的神明週期有三個:componentWillMount `,componentWillReceiveProps ,componentWillUpdate

這個生命週期是映射props到state上,至關因而執行setState操做。因此,每次父組件發生props變化,都會執行setState操做。這也可能致使重複渲染,感受盡可能也減小使用吧。

getDerivedStateFromProps 是一個靜態方法, 是一個和組件自身"不相關"的角色. 在這個靜態方法中, 除了兩個默認的位置參數 nextProps 和 currentState 之外, 你沒法訪問任何組件上的數據.

七、解析HTTP 304 狀態碼

數據請求的時候,若是服務器發現客戶端有緩存,而且時間沒過時,則返回304狀態。

請求頭中的Last Modified和f Modified Since來進行比較判斷是否須要返回304,或者更新數據返回200.

八、什麼是高階組件?

咱們知道函數的參數是函數,返回的是新的函數,則稱爲高階函數。

高階組件是返回組件的組件,也就是傳遞參數是組件,對這個組件進行加工成爲一個新的組件並返回。

他用來幹什麼?通常用來屬性代理,也就是把本來的props和新的props組合成一個新的組件的屬性。因此,咱們若是要建立一個loading效果組件,或者是成功失敗等狀態組件,能夠用高階組件來實現。

九、for...of能遍歷什麼?

可迭代對象。如Arrays(數組), Strings(字符串), Maps(映射), Sets(集合)等。

十、如何避免遍歷到原型上的屬性?

第1、for..in + hasOwnProperty方法

第2、Object.keys()

十一、事件循環。

JavaScript是單線程執行模型,執行的時候將會區分爲主線程和任務隊列。主線程執行完畢,會從任務隊列中讀取新的任務放入主線程進行執行,這個讀取過程是循環讀取,因此也叫事件循環。

任務隊列分爲宏任務和微任務,同層次,先執行微任務,再執行宏任務。

微任務:promise.then()、process.nextTick()

宏任務:setTimeOut()、setInterval()

十二、瀏覽器的渲染流程

這個問題應該就是輸入url到頁面呈現問題的變種,只不過此時的側重點是獲取完數據以後進行的渲染流程。

根據李兵老師的瀏覽器工做原理一節作以下回答:

第一步,HTML轉換成DOM

第二步,CSS轉換成瀏覽器可理解的styleSheets,而後計算DOM節點的樣式

第三步,建立布居樹,計算元素的佈局信息

第四步,對布居樹進行分層,構建分層樹

第五步,爲每一個圖層生產繪製列表,並將其提交到合成線程

第六步,合成線程將圖層轉化爲圖塊,進而將圖塊轉化成位圖

第七步,合成線程發送繪製命令給瀏覽器

第八步,瀏覽器根據繪製命令生成頁面,並顯示到顯示器上。

1三、deffer和async的區別

瀏覽器腳本,在普通的狀況下,是會依次執行。可是咱們能夠用deffer和async關鍵字來讓腳本異步執行。

可是,deffer是按照加載順序執行DOMContentLoaded以前執行,可是async則是腳本加載完畢以後當即執行(不考慮依賴以及DOM的加載狀態),通常來講,deffer要比async好一點。

1四、DOM選擇器中,querySelectorAll和getElementByClass的區別?

querySelectorAll 返回的是一個 Static Node List,而 getElementsBy 系列的返回的是一個 Live Node List。

因此靜態節點列表至關因而快照,不影響文檔操做,因此咱們能夠遍歷循環querySelectorAll生產的數據。

可是動態節點列表,若是咱們的一些查詢和操做就會變成死循環。

從性能上來說,getElementByClass要更快。

1五、map和forEach的區別

forEach返回undefined,map會返回新的數組。

forEach沒辦法停止循環,可是map能夠經過返回false或者出錯來停止。

1六、call、apply以及bind的區別。

三者都是改變this執行,不一樣的是,call和apply是直接生成了函數調用,而bind則是返回了一個函數,你須要再次執行纔會達到相同的效果。

call和apply又是由於參數的傳遞方式不同,apply傳遞的是數組,call傳遞的單個參數的陳列。

bind則是以函數調用參數的方式傳遞參數。

1七、css中的box-sizing

懵逼了,不知道是啥,以前根本沒用過。

查了下,box-sizing 屬性容許你以某種方式定義某些元素,以適應指定區域。例如,假如您須要並排放置兩個帶邊框的框,可經過將 box-sizing 設置爲 "border-box"。這可令瀏覽器呈現出帶有指定寬度和高度的框,並把邊框和內邊距放入框中。

box-sizing的值有三個,content-box:只有內容、border-box:包括邊框、inherit:繼承自父元素。

總結

剛開始面試,有些生疏,而且有時候明明記得,卻死活想不起來,大概是太長時間沒有思考技術的緣由。過後仔細思考,以爲這些問題都是很基礎,很簡單的題目,只要好好準備一下,應該仍是慢慢會好起來的。

個人博客:http://www.gaoyunjiao.fun/?p=163

相關文章
相關標籤/搜索