摘要:組件化編碼的一切都是基于組件的。屬性返回目標(biāo)節(jié)點的前一個兄弟節(jié)點。如果目標(biāo)節(jié)點前面沒有同屬于一個父節(jié)點的節(jié)點,將返回屬性是一個只讀屬性。而當(dāng)變量離開環(huán)境時,則將其標(biāo)記為離開環(huán)境。
第一次寫面試經(jīng)歷,雖然之前有過一些電話面試經(jīng)歷,但相對而言感覺此次的經(jīng)歷對自己收獲還是比較大,這里留下面經(jīng)當(dāng)作日記吧?。嬖嚂r間:2018-6-12 下午2:10;時長:50min;公司:*)1、說說React,為什么選擇React
(一)、React特點
高效、虛擬DOM,最大限度地減少與DOM的交互:
瀏覽器在渲染網(wǎng)頁時,會先將HTML文檔解析并構(gòu)建DOM樹,然后與CSSOM樹生成RenderObject樹,最后渲染成頁面。瀏覽器中渲染引擎和JavaScript引擎是分離的,渲染引擎會提供一些接口給JavaScript調(diào)用,它們二者通信是通過橋接的,性能其實是很差的。
以往,為了優(yōu)化性能通常采用的辦法是減少DOM操作次數(shù)。而React提出了一個新的思路就是虛擬DOM:組件的HTML結(jié)構(gòu)不再是直接生成DOM,而是映射生成虛擬的JavaScript DOM結(jié)構(gòu),React通過diff算法將最小變更寫入DOM中,從而減少DOM的實際次數(shù),提升性能。
服務(wù)器端渲染
React提供開箱即用的服務(wù)器端渲染,服務(wù)器端渲染解除了服務(wù)器端對瀏覽器的依賴,它會將“可視”部分先渲染,然后再交給客戶端做渲染。
組件化編碼
React 的一切都是基于組件的。可以通過定義一個組件,然后在其他的組件中,可以像HTML標(biāo)簽一樣引用它。說得通俗點,組件其實就是自定義的標(biāo)簽;通過 React 構(gòu)建組件,使得代碼更加容易得到復(fù)用,能夠很好的應(yīng)用在大項目的開發(fā)中。
聲明式設(shè)計
React采用聲明范式,函數(shù)式編程,可以輕松描述應(yīng)用。
靈活
React可以與已知的庫或框架很好地配合。
JSX
JSX 是 JavaScript 語法的擴展。React開發(fā)不一定使用 JSX ,但我們建議使用它。
單向響應(yīng)的數(shù)據(jù)流
React 實現(xiàn)了單向響應(yīng)的數(shù)據(jù)流,數(shù)據(jù)是自頂向下單向流動的,即從父組件到子組件,這種原則讓組件之間的關(guān)系變得簡單可預(yù)測;props作為外部接口、state作為內(nèi)部狀態(tài)。
(二)、為什么選擇React
相比其他如Vue、angular的雙向數(shù)據(jù)綁定的框架,個人比較喜歡這種比較流程化的單向數(shù)據(jù)流形式,因為可以更好的預(yù)測數(shù)據(jù)的變化;
當(dāng)然最主要的原因是學(xué)校圖書館,對于React的書籍資料更豐富(。。。。道出了真相、尷尬)
2、剛剛你說到了虛擬DOM的Diff算法,談?wù)勀銓λ睦斫?/b>因為當(dāng)時沒有怎么看這個算法,所以只是憑借之前的知識點簡單的說了下;
這里在具體的回顧下:
React的Diff算法巧妙的使用了試探法將復(fù)雜度為O(n^3)的數(shù)差異比較算法轉(zhuǎn)換成O(n)復(fù)雜度的問題;
該算法基于兩個假定:
相同類的兩個組件將會生成相似的樹形結(jié)構(gòu),而不同類的兩個組件將會生成不同的樹形結(jié)構(gòu);
可以為元素提供唯一的標(biāo)識,確保該元素在不同的渲染過程中保持不變。
具體實現(xiàn)細(xì)節(jié):
(樹形結(jié)構(gòu)的比較)即首先檢查兩個節(jié)點的差異
節(jié)點類型不同時
React會把它們當(dāng)做兩個不同的字樹,導(dǎo)致直接移除之前的那顆子樹,然后創(chuàng)建并插入之前的那顆子樹
優(yōu)點:巧妙的避開了對樹形結(jié)構(gòu)的大量差異檢測,然后關(guān)注與相同的部分,實現(xiàn)了快速而又精確的差異檢測邏輯;
缺陷:如果兩個子樹具有相似的結(jié)構(gòu),即頂節(jié)點不同,子節(jié)點結(jié)構(gòu)相同,這時本來只需要對不同的頂節(jié)點進(jìn)行刪除插入操作,但是React會將整個子樹都刪除然后從新構(gòu)建插入
3、對React生命周期了解嗎(1)、裝載過程
當(dāng)組件第一次被渲染時,依次調(diào)用的函數(shù):
construction
getInitalState
getDefaultProps
componentWillMount
render
componentDidMount
(2)、更新過程
更新過程會依次調(diào)用以下生命周期函數(shù),其中render函數(shù)和“裝載”過程一樣:
?- componentWillReceiveProps
?- shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
并不是所有的更新過程都會執(zhí)行全部函數(shù)。
(3)、React組件的卸載過程只涉及一個函數(shù)componentWillUnmount
具體詳情介紹可以看React生命周期詳解
4、說到shouldComponentUpdate,你是如何使用的、如何判斷是否更新在生命周期中render函數(shù)決定了該渲染什么,而shouldComponentUpdate決定了一個組件什么時候不需要渲染;
shouldComponentUpdate(nextProps,nextState)接收兩個參數(shù),即此次渲染的props和state對象,返回一個布爾,默認(rèn)返回true,表示進(jìn)行更新;返回false表示此次更新不需要到此終止;
通過比較此次props、state和上次是否相同決定是否需要進(jìn)行更新可以很好的避免不必要的更新操作,提升性能;
因為props和state的是對象,平時使用的一般都淺層比較,如果需要對兩個對象進(jìn)行深度全面比較,我考慮的是使用JSON.stringify()
5、如果在React中我需要獲取DOM節(jié)點、應(yīng)該在什么階段獲取、如何獲取要獲取DOM節(jié)點的話,需要在componentDidMount或者componentDidUpdata中獲取,因為只有在這個階段真實DOM節(jié)點才構(gòu)建完成了
獲取DOM節(jié)點可以使用ref屬性
6、如果我又需要通過原生js獲取這個節(jié)點的父節(jié)點呢可能只是作為一個過渡,比較簡單、直接回答了使用DOM節(jié)點的parentNode屬性獲取;不過這里還是補充一點。
nextSibling 屬性 :
返回目標(biāo)節(jié)點的下一個兄弟節(jié)點。
如果目標(biāo)節(jié)點后面沒有同屬于一個父節(jié)點的節(jié)點,nextSibling 將返回null ;
nextSibling 屬性是一個只讀屬性。
previousSibling屬性 :
返回目標(biāo)節(jié)點的前一個兄弟節(jié)點。
如果目標(biāo)節(jié)點前面沒有同屬于一個父節(jié)點的節(jié)點,previousSibling 將返回null ;
previousSibling 屬性是一個只讀屬性。
parentNode 屬性 :
注:parentNode屬性返回的節(jié)點永遠(yuǎn)是一個元素節(jié)點,因為只有元素節(jié)點才有可能有子節(jié)點。
當(dāng)然有個例外:
document節(jié)點,他沒有父節(jié)點。所以document節(jié)點的parentNode屬性將返回null;
parentNode 屬性是一個只讀屬性。
7、現(xiàn)在我又需要以類名獲取DOM當(dāng)時直接說的是:可以使用document.getElementsByClassName()、document.querySelector()、document.querySelectorAll();
然后又引出了區(qū)別問題~
8、說說以上三種方法的區(qū)別回答:
getElementsByClassName()、和querySelectorAll()返回的是一個DOM列表,雖然可以用循環(huán)遍歷,但是它們只是偽數(shù)組,不能使用數(shù)組的方法;
getElementsByClassName()只能通過類名獲取,而和querySelectorAll、querySelector是使用CSS選擇器獲取的,
當(dāng)時只說了querySelector是返回一個DOM節(jié)點,有點錯誤吧;querySelector是返回文檔中匹配指定的CSS選擇器的第一元素
9、剛剛你說到偽數(shù)組,那么如何區(qū)分一個對象是數(shù)組呢回答:
obj instanceof Array如果返回true或者false;
Object.prototype.toString.call(obj) === "[object Array]";
還有一個當(dāng)時沒有說道:
obj.constructor == Array為true或false
當(dāng)時還補充了Array.isArray(obj),用于確定傳遞的值是否是一個 Array,如果對象是 Array,則為true; 否則為false。
10、談到ES6,說說你對ES6的了解回答:
ES6主要增加了一些新的特效,如:
const定義常量,但是const定義的常量只是值不可變,即基本數(shù)據(jù)類型不可變,對于引用類型,因為它建立的是引用,所以即使使用const定義的對象,其屬性還是可變的;
let定義變量,相對于var,它修復(fù)了一些問題,比如變量提升、重復(fù)定義等問題,并且const和let的定義具有塊級作用域;
對于字符串?dāng)U展有:字符串模板、還有一些方法(忘了,趕緊跳過);
還有就是:剩余參數(shù)、函數(shù)默認(rèn)參數(shù)、模塊化、Promise、裝飾器、Symbol、set和map等;
剛學(xué)習(xí)不久,大概就說了這些;最近也在更新ES6的筆記深入理解ES6
對ES6并沒有深入的問,直接從let和const的塊級作用域引到了閉包11、剛剛說到塊級作用域,談?wù)勊烷]包的區(qū)別,就是說一般什么時候使用閉包?
回答:
閉包使用的作用的話主要是為了獲取函數(shù)內(nèi)部的變量和將變量保存下來,使其不被垃圾回收器回收,供給之后使用;
使用的話一般是為了封裝作用域,即代替全局變量,避免全局變量污染;
因為使用閉包,會將變量保存不被回收器回收,所以應(yīng)該盡量避免使用,防止造成內(nèi)存泄漏
答的不是太全面,這里補充:
閉包的應(yīng)用場景
使用閉包代替全局變量
函數(shù)外或在其他函數(shù)中訪問某一函數(shù)內(nèi)部的參數(shù)
在函數(shù)執(zhí)行之前為要執(zhí)行的函數(shù)提供具體參數(shù)
在函數(shù)執(zhí)行之前為函數(shù)提供只有在函數(shù)執(zhí)行或引用時才能知道的具體參數(shù)
為節(jié)點循環(huán)綁定click事件,在事件函數(shù)中使用當(dāng)次循環(huán)的值或節(jié)點,而不是最后一次循環(huán)的值或節(jié)點
暫停執(zhí)行
包裝相關(guān)功能
12、說到回收器,說說如何判斷一個變量可回收,如果我需要使用閉包,該如何避免你所說的內(nèi)存泄漏?感覺有點給自己挖坑了,(回收機制、內(nèi)存泄漏不是太懂啊~~)
回答:
一個變量的可回收性,一般需要根據(jù)瀏覽器js引擎的回收器機制判斷,大概有兩種方式(當(dāng)時只說到了一種);
即引用計數(shù):引用計數(shù)的含義是跟蹤記錄每個變量被引用的次數(shù),當(dāng)期的引用次數(shù)為0時表回收
一般手動清除是將它賦值為null
科普:
引用計數(shù):
當(dāng)聲明一個變量并將一個引用類型值賦給該變量時,則這個值的引用次數(shù)便是1,如果同一個值又被賦給另一個變量,則該值的引用次數(shù)加1,相反,如果包含對這個值引用的變量又取得了另一個值,則這個值的引用次數(shù)減1。當(dāng)這個值的引用次數(shù)為0時,說明沒有辦法訪問到它了,因而可以將其占用的內(nèi)存空間回收
標(biāo)記清除:
當(dāng)變量進(jìn)入環(huán)境時,例如,在函數(shù)中聲明一個變量,就將這個變量標(biāo)記為“進(jìn)入環(huán)境”。從邏輯上講,永遠(yuǎn)不能釋放進(jìn)入環(huán)境的變量所占用的內(nèi)存,因為只要執(zhí)行流進(jìn)入相應(yīng)的環(huán)境,就可能會用到它們。而當(dāng)變量離開環(huán)境時,則將其標(biāo)記為“離開環(huán)境”。
13、HTML5了解嗎?談一談HTML5 主要增加了一些語義化標(biāo)簽和一些API、刪除了一些元素
繪畫 canvas
用于媒介回放的 video 和 audio 元素
本地離線存儲 localStorage 長期存儲數(shù)據(jù),瀏覽器關(guān)閉后數(shù)據(jù)不丟失
sessionStorage 的數(shù)據(jù)在瀏覽器關(guān)閉后自動刪除
語意化更好的內(nèi)容元素,比如 article、footer、header、nav、section
表單控件,calendar、date、time、email、url、search
新的技術(shù)webworker, websocket, Geolocation
移除的元素:
純表現(xiàn)的元素:basefont,big,center,font, s,strike,tt,u
對可用性產(chǎn)生負(fù)面影響的元素:frame,frameset,noframes
沒有到這么詳細(xì),以上回顧14、說到localStorage和sessionStorage還有cookie談?wù)勊麄兊膮^(qū)別?
相同點:都可以作為瀏覽器存儲,且都不能進(jìn)行跨域訪問;
不同點:
cookie始終會在同源 http 請求頭中攜帶(即使不需要),在瀏覽器和服務(wù)器間來回傳遞
sessionStorage 和 localStorage 不會自動把數(shù)據(jù)發(fā)給服務(wù)器,僅在本地保存;
sessionStorage 和 localStorage 存儲大小比cookie大得多,可以達(dá)到5M或更大;
localStorage 存儲持久數(shù)據(jù),瀏覽器關(guān)閉后數(shù)據(jù)不丟失除非主動刪除數(shù)據(jù);
sessionStorage 數(shù)據(jù)在當(dāng)前瀏覽器窗口關(guān)閉后自動刪除;
cookie 設(shè)置的cookie過期時間之前一直有效,與瀏覽器是否關(guān)閉無關(guān)。
15、簡歷上看你上過《計算機網(wǎng)絡(luò)》?談一談ISO七層,按順序說說應(yīng)用層、表示層、會話層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層、物理層
16、說說http和ftp協(xié)議分別在哪一層都處于應(yīng)用層(現(xiàn)在回顧好像錯了一個~~~~)
科普:
應(yīng)用層:允許訪問OSI環(huán)境的手段(應(yīng)用協(xié)議數(shù)據(jù)單元APDU)(HTTP、FTP、SMTP、DNS)
表示層:對數(shù)據(jù)進(jìn)行翻譯、加密和壓縮(表示協(xié)議數(shù)據(jù)單元PPDU)
會話層:建立、管理和終止會話(會話協(xié)議數(shù)據(jù)單元SPDU);
傳輸層:提供端到端的可靠報文傳遞和錯誤恢復(fù)(段Segment)(TCP和UDP);
網(wǎng)絡(luò)層:負(fù)責(zé)數(shù)據(jù)包從源到宿的傳遞和網(wǎng)際互連(包PackeT)IP尋址;
數(shù)據(jù)鏈路層:將比特組裝成幀和點到點的傳遞(幀F(xiàn)rame)
物理層:通過媒介傳輸比特,確定機械及電氣規(guī)范(比特Bit)
17、說說你對http的了解,就說狀態(tài)碼吧,你常用的狀態(tài)碼及其含義HTTP超文本傳輸協(xié)議,基于請求/響應(yīng)模式。
HTTP是無狀態(tài)協(xié)議,F(xiàn)TP是有狀態(tài)
狀態(tài)碼:
100:post請求第一次發(fā)送頭信息后服務(wù)器返回100,表示請求繼續(xù);
200: 表示請求正常,請求成功;
301:永久重定向;
302: 臨時重定向;
304: 用于協(xié)商緩存,表示瀏覽器緩存資源未改變,任然可用
400:請求語法或參數(shù)錯誤;
401:認(rèn)證未通過,如跨域未通過;
403:請求未授權(quán);
404:找不到相應(yīng)資源的位置;
500:服務(wù)器內(nèi)部出錯;
502: 錯誤網(wǎng)關(guān)
18、聽你談到瀏覽器緩存,說說你所知道的緩存方式緩存類型有兩種,強緩存和協(xié)商緩存
強緩存:不會向服務(wù)器發(fā)送請求,直接從緩存中讀取資源(Expires、cache-control);
協(xié)商緩存:向服務(wù)器發(fā)送請求,服務(wù)器會根據(jù)這個請求的request header的一些參數(shù)來判斷是否命中協(xié)商緩存,如果命中,則返回304狀態(tài)碼并帶上新的response header通知瀏覽器從緩存中讀取資源;
科普更多瀏覽器緩存細(xì)節(jié):深入瀏覽器緩存19、那接下來我們談?wù)凜SS,兩個div垂直布局,上面的設(shè)置margin—bottom:50px;下面的margin-top:100px;此時兩個div相距多少
100px,因為垂直方向的margin會存在重疊現(xiàn)象
深入了解可閱讀CSS可格式化模型
20、如果我需要消除這種情況,如何處理
因為是消除兩個兄弟div間的margin重疊問題:
兩個兄弟div設(shè)置為float:left(或display:inline-block);width:100%;
科普更多(父子間的margin重疊消除)
外層元素padding代替
內(nèi)層元素透明邊框 border:1px solid transparent;
內(nèi)層元素絕對定位 postion:absolute:
外層元素 overflow:hidden;
內(nèi)層元素 加float:left;或display:inline-block;
內(nèi)層元素padding:1px;
21、現(xiàn)在我需要實現(xiàn)兩個div水平布局使用flex布局:父元素設(shè)置display;flex
使用float布局(或者display:inline-block)
//html22、現(xiàn)在我改變需求,左邊固定寬度,右邊自適應(yīng)//CSS .item1 { float: left; //display:inline-block } .item2 { overflow: hidden; //display:inline-block }floatoverflow:hidden
左邊定寬width:200px;設(shè)置浮動float:left;右邊overflow:hidden(或者margin-left:左邊寬度);
父元素display:flex;左邊定寬width:200px;;右邊設(shè)置項伸展屬性flex-grow: 1;
父元素position:relative;左邊定寬width:200px;position:absolute;右邊margin-left:左邊寬度;
父元素display:table;左邊定寬width:200px;右邊width:100%;display:tabel-cell;。
23、現(xiàn)在我需要,兩個div進(jìn)行兩列布局,要求高度不定(父元素也是),我需要兩個div實時等高,即左邊div高度被其內(nèi)子元素?fù)胃邥r,右邊的div高度和左邊同步父元素display:table;左邊定寬width:200px;display:tabel-cell;右邊width:100%。
父元素display:flex;align-items:stretch;左邊定寬width:200px;;右邊設(shè)置項伸展屬性flex-grow: 1;
24、突然又有新的需求,實現(xiàn)左右兩邊固定寬度,中間自適應(yīng)使用flex布局:父元素display:flex;左邊定寬width:200px;右邊定寬width:200px;中間flex-grow:1;
使用浮動布局:父元素overflow:hidden;左邊定寬width:200px;float:left;右邊定寬width:200px;float:right;中間margin:0 200px;
這里有個坑,那就是HTML結(jié)構(gòu)必須得變換,即中和右要調(diào)換位置(當(dāng)時沒想到,一直被問你確定就這樣可以?短路短路~)
細(xì)想因為center的div在正常文檔流中,且占據(jù)全屏寬度,自然之后的浮動元素會被放置下一行
// Html結(jié)構(gòu)// CSS樣式布局 .left { width: 200px; background: bisque; float: left; } .center{ background: red; margin: 0 200px; } .right { background: rgba(22,220,22,0.5); float: right; width: 200px; }leftrightcenter
使用絕對定位布局:
絕對定位法原理是將左右兩邊使用absolute定位,因為絕對定位使其脫離文檔流,后面的center會自然流動到他們上面,然后使用margin屬性,留出左右元素的寬度,既可以使中間元素自適應(yīng)屏幕寬度。(這種方式)
// CSS樣式布局 .left { width: 200px; background: bisque; position: absolute; } .center{ background: red; margin: 0 200px; } .right { background: rgba(22,220,22,0.5); position: absolute; right: 0; width: 200px; }
圣杯布局(不是太理解)
圣杯布局的原理是margin負(fù)值法。使用圣杯布局首先需要在center元素外部包含一個div,包含div需要設(shè)置float屬性使其形成一個BFC,并設(shè)置寬度,并且這個寬度要和left塊的margin負(fù)值進(jìn)行配合:
// html結(jié)構(gòu)// CSS 樣式 .left { width: 200px; background: bisque; float: left; margin-left: -100%; } .wrap { float: left; width: 100%; } .center{ background: red; margin: 0 200px; } .right { background: rgba(22,220,22,0.5); float: left; margin-left: -200px; width: 200px; }centerleftright
整個過程歷時1個小時左右,感覺還好吧,怎么說不管過沒過,起碼知道自己還有哪些方面不足,可以針對性的深入學(xué)習(xí)。
最后附上此次面試涉及的一些知識點
React知識冊;
瀏覽器緩存詳解;
ES6知識總結(jié);
最后加上前端面試題JavaScript
持續(xù)跟進(jìn)中,喜歡可以留下個贊哦~~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/113488.html
摘要:組件化編碼的一切都是基于組件的。屬性返回目標(biāo)節(jié)點的前一個兄弟節(jié)點。如果目標(biāo)節(jié)點前面沒有同屬于一個父節(jié)點的節(jié)點,將返回屬性是一個只讀屬性。而當(dāng)變量離開環(huán)境時,則將其標(biāo)記為離開環(huán)境。 第一次寫面試經(jīng)歷,雖然之前有過一些電話面試經(jīng)歷,但相對而言感覺此次的經(jīng)歷對自己收獲還是比較大,這里留下面經(jīng)當(dāng)作日記吧!(面試時間:2018-6-12 下午2:10;時長:50min;公司:*) 1、說說Rea...
摘要:是模板方法,他封裝了子類中算法框架,它作為一個算法的模板,去指導(dǎo)子類以什么樣的順序去執(zhí)行代碼。制定算法骨架,讓子類具體實現(xiàn),這大概就是模板方法模式了吧 模板方法模式: 把相似的流程抽象出來作為一個父類,來封裝好子類的算法框架,然后子類繼承這個父類,并且可以重寫非公有的方法,來實現(xiàn)自己的業(yè)務(wù)邏輯。 聚個栗子 泡茶泡咖啡是很好的例子,不同企業(yè)的面試流程也是一個很好的例子對于很多大型公司,...
摘要:面試時間晚上時長小時分鐘公司,一面一簡單的介紹下自己介紹的真的很簡單。。。。。。二平時都是怎么學(xué)習(xí)前端的學(xué)習(xí)前端的話,我主要是以書籍為主然后是網(wǎng)站視頻博客文檔等學(xué)習(xí)理論,之后再通過代碼實踐。。。 大概是在6月11號在Boss直聘投的簡歷,6月12號中午收到電話約的面試時間,剛開始說是13號晚上7點;后面可能時間有變,中午來了個電話說改到9-10點;怎么說算是第一次面試自己目標(biāo)公司之一吧...
閱讀 2679·2021-11-25 09:43
閱讀 2484·2021-09-22 15:29
閱讀 1001·2021-09-22 15:17
閱讀 3643·2021-09-03 10:36
閱讀 2239·2019-08-30 13:54
閱讀 1759·2019-08-30 11:23
閱讀 1173·2019-08-29 16:58
閱讀 1303·2019-08-29 16:14