【面試總結】記一次失敗的 bilibili 面試總結(1)
前幾日去B站面試了一次前端,不算資深B站使用者,平常也蠻喜歡在B站觀看視訊的,能獲得這樣的面試機會,實在是受寵若驚。但無奈實力有限加上瑣事纏身,並沒有做好充足的準備,導致面試失敗。
(ps:屬實還是有點緊張,發揮也受到影響)
這次面試過程我思前想後覺得有必要總結一下,希望自己下次再有這樣的機會的時候能夠把握的更好。
因內容比較多,所以準備可能分多篇部落格更新內容,這裡給出傳送門
- HTML佈局、CSS選擇器及JS基礎綜合能力知識點
- 演算法基礎:陣列降維、去重及排序
- react vue 理解及基礎知識
- 跨域問題解決方案
- http協議狀態碼
- 快取及更新問題
- webview與原生應用互動
- 伺服器端知識
ps:這是大綱,後續可能有變化。比如伺服器端知識,我沒有接觸過,面試官就沒問,但確實是面試過程中的一個大類的問題。
面試感受
面試過程整體感覺很舒服,面試官很有耐心,面試題由淺入深,面試打分的話,我會給5顆星。
HTML佈局、CSS選擇器及JS基礎綜合能力知識點
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { margin: 0; padding: 0; } html, body, #app { margin: 0; padding: 0; height: 100%; } #header, #footer { height: 50px; line-height: 50px; text-align: center; background: #555; color: #fff; } #side { width: 200px; background: #eee; } /* css here */ </style> </head> <body> <div id="app"> <header id="header">header</header> <aside id="side">side</aside> <div id="main"> <ul> <li><a href="https://www.bilibili.com/1">Link1</a></li> <li><a href="https://www.bilibili.com/1">Link2</a></li> <li><a href="https://www.bilibili.com/1">Link3</a></li> <br> <li><a href="https://www.bilibili.com/1">Link4</a></li> <li><a href="https://www.bilibili.com/1">Link5</a></li> </ul> </div> <footer id="footer">footer</footer> </div> <script> // JS here </script> </body> </html> 複製程式碼
不考慮相容性且不能更改dom結構,需求如下:
- 完成經典的上 header ,下 footer ,左邊是側邊欄,右邊是內容。
- 去掉列表前面的 · ,列表項水平排列,注意裡面的br標籤需要換行,同時每兩個li後有一條豎線。
- 點選列表項不跳轉,彈出href內的內容。
ANSWER 1:
時光回溯:
這道面試題是基礎題,我應該要多向面試官展示一下我的基本功,同時也要告訴面試官,我是有關注前端最新的動態的,既然不考慮相容性,我得先用 Grid 的方案實現一遍,然後在告訴面試官我大概還有108種不同的解法,:smiley:哈哈哈...。然後 Grid 除了 display: grid 外,好久沒有寫了,我都忘記的差不多了吧。在思考 Grid 的時候,時間浪費了太久,我得趕緊找個簡單的寫法先提交,不然基礎題都得做這麼久,印象肯定不行。
浮動解決方案:
/** * calc 是 css的一個函式 * 不明白的同學我附上鍊接 * https://developer.mozilla.org/zh-CN/docs/Web/CSS/calc */ #side { /* 設定 側邊欄 左浮動 */ float: left; height: calc(100% - 100px); } #main { height: calc(100% - 100px); } 複製程式碼
position 解決方案:
#app { /* 父級元素 設定 相對定位 */ position: relative; } #side { /* 左邊欄 設定 絕對定位 */ position: absolute; top: 50px; bottom: 50px; left: 0; } #main { /* 內容區 設定 絕對定位 */ position: absolute; top: 50px; right: 0; bottom: 50px; left: 200px; #footer { /* footer 設定 絕對定位 */ position: absolute; bottom: 0; width: 100%; /* 設定浮動後,補上寬度 */ } 複製程式碼
Flex 解決方案:
:x:受限於無法更改 DOM 結構,我覺得難以使用 Flex 去實現這個需求。或者請求高人指點一二。
Grid 解決方案:
參考資料
本文不贅述Grid的所有內容,有需要的朋友可以傳送門詳細瞭解。下面我會介紹我用到的部分。
#app { /* app 為 grid 佈局的容器,所以在此處建立 grid 佈局 */ display: grid; /** 這是一種縮略的寫法 等價於 grid-template-rows: 50px auto 50px; grid-template-columns: 200px auto; 建立了一個 3 * 2 的格子 高度是 50px 自動 50px 寬度是 200px 自動 */ grid: 50px auto 50px / 200px auto; } /* 這個時候其實開啟頁面看著很奇怪,header 縮在角落,等等 */ #header, #footer { /** -*- 重要 -*- 下面的寫法 等價於 grid-column-star: 1; grid-column-end: 3; 該 grid 的子項 開始與 第一根 column 線 結束與 第三根 column 線 */ grid-column: 1 / 3; } 複製程式碼
#app { display: grid; /** 等價於 grid-template-rows: 50px auto 50px; grid-template-columns: 200px auto; grid-template-areas: "header header" "side main" "footer footer"; 注意: 每一 row 只是一個字串 */ grid: "header header" 50px "side main" auto "footer footer" 50px / 200px auto; } #header { /* 注意: header 沒有雙引號 */ grid-area: header; } #footer { grid-area: footer; } 複製程式碼
ANSWER 2:
時間回溯:
取消 · 沒有難度。這個題目的難點就在這個 br 標籤,本來可以直接使用 flex 佈局,現在的話看情況應該只能使用 inline 或者 inline-block 的方式進行水平排列了。加豎線可以用偽類選擇器和偽類元素選擇器組合實現,但是我忘記了 :nth-of-type 偽類選擇器。
ul { /* 去掉 · */ list-style: none; } ul li { /* 水平排列,兩個都行*/ display: inline; /*display: inline-block; */ } 複製程式碼
當時最後一個加豎線的需求,我是這樣寫的。
/* 偽類選擇器 + 偽類元素選擇器 */ ul li:nth-child(2n)::after { content: '|'; } 複製程式碼
但是隻有 Link2 Link5 後面會出現 "|",因為 br 標籤的緣故,失敗。
但只需要稍加修改就可以完成,但面試的時候沒有完成。
/* 偽類選擇器 + 偽類元素選擇器 */ ul li:nth-of-type(2n)::after { content: '|'; } 複製程式碼
後來詢問了面試官這個應該如何解決,得知可以考慮兄弟選擇器試試。
TODO: 我目前還沒有想出來如何處理。Help!
ANSWER 3:
沒啥好說的。把事件繫結在父元素上,節約記憶體。考察點就是原生dom的一些操作吧。
document.querySelectorAll('ul')[0].addEventListener('click',event => { if(event.target.tagName === 'A') { event.preventDefault(); // 阻止預設行為 alert(event.target.getAttribute('href')); } }); 複製程式碼
總結:
- 前三種方式都是比較傳統的佈局方式,確實能解決問題,但是比較抽象。
- Grid 的佈局方式是一個二維的基於網格的佈局系統,它的目標是完全改變我們基於網格的使用者介面的佈局方式。當使用這種佈局方式的時候,在chrome中開啟除錯,能很清晰的看見網格的存在。相對於前三種,直觀方便快捷。
- 偽類選擇器這種日常可能不常用的東西可能就是面試的盲點。
- javascript 工程化之後,輪子用的多了,但是也得了解底層才行啊。