面試分享:兩年工做經驗成功面試阿里P6總結

前言

本文主要給你們帶來一些我面試的經歷和經驗,但願對正在求職的同窗有所幫助。我先大體說下面試以前的我的狀況:2017年7月正式入職海康威視數字技術股份有限公司,使用Vue.js技術棧。javascript

我寫的篇幅可能有點長,若是隻想當作功的面試請直接從阿里企業智能事業部(一面)開始,你們見諒哈。css

這裏推薦閱讀以前寫的文章(前面兩篇實用型,後面兩篇對面試應該會有幫助):html

關於阿里

Hi,你們好,咱們是阿里巴巴新成立的BU,目前還有大量的Web前端職位空缺,機會可貴,但願正在找工做的同窗們能夠來試試:前端

  • 目前Web前端急缺P6和P7(阿里的不少BU都只招P7了)
  • 新的BU你進來便是元老😂😂😂
  • 前端技術體系大部分須要一塊兒從新開拓,能夠學習到更多的新內容
  • 主要負責PC端、客戶端、釘釘E應用以及支付寶小程序的開發(我本人徹底不會小程序,不用擔憂😂😂😂)
  • 技術棧是React(若是你是Vue技術棧徹底不用擔憂,由於我也是😂😂😂)
  • 其餘BU面試可能有五輪,咱們這邊只有4輪面試

真的機會可貴哦,若是想更多瞭解咱們BU以及找我內推的同事加我釘釘或者微信(純粹找我瞭解或者溝通技術也行,啊哈哈):18768107826vue

簡歷

個人簡歷只是簡單的用MD作了一份,大體包含了如下幾個部分:java

  • 基本資料
  • 專業技能
  • 工做經歷
  • 實習經歷(可選)
  • 項目經歷

小提示:在基本資料裏必定要填寫正確的郵箱地址,我在前期面試的時候都沒有打開郵箱查看面試狀況,致使一些面試的時間點和麪試結果都不清楚(一直覺得會發短信通知)。react

若是去現場面試,必定要記得帶上筆和簡歷。一方面你給面試官的簡歷一定是最新的(在不斷面試的過程當中你一定會修改簡歷),另外一方面這也會給面試官一種很是舒心的感受。css3

對於簡歷這裏提一點,在寫本身的專業技能項目經歷時儘可能不要給本身挖坑,這裏展現一下個人專業技能(我會的很少):git

  • 熟悉嵌入式C、JavaScript、Node.js
  • 熟悉Vue.js框架

切忌寫一大堆讓人感受花裏胡哨的技能,尤爲是一些很淺顯的技能(基本技能除外)。若是你有一些別人很難替代的技能,那這些技能就是亮點了,我這裏就沒什麼亮點技能。有些技能你會可是不熟練,你能夠適當的在你的項目經歷中體現出來。對於項目經歷儘可能挑本身以爲很是有技術含量的項目進行說明(寧缺毋濫),對於本身參加過但不是特別熟悉的項目儘可能不要填寫,防止給本身挖坑。github

小提示:這裏附上的個人面試簡歷供你們參考。感謝jsliang的文章2019 面試系列 - 簡歷,你們製做簡歷時也能夠參考這篇文章。

在投遞簡歷時你們千萬不要被招聘信息中的要求嚇到,記得有一次投遞簡歷時我對招聘者說自身不太符合要求,招聘者當時說要求都是唬人的,以爲有興趣就投,有些招聘要求可能正是你將來學習或者深刻的領域。

面試

簡歷製做完後我大概投了四家公司:有贊、滴滴、51信用卡和阿里。其中有贊掛在二面,滴滴掛在一面,51信用卡掛在一面,阿里兩個部門掛在一面,一個部門面試成功。不少面試者的經歷可能都是像我這樣,在一次次的面試失敗中不斷的總結進步,最終拿到理想的Offer。

小提示:建議你們在投遞簡歷時能夠先投遞一些試水的小公司,先檢驗一下本身是否是能夠勝任這些公司的面試。同時在每一次面試完後記得把面試官提問的問題記錄下來,對於沒有答上來的問題仍是要好好搞懂或者實踐一下,由於頗有可能下一家的面試官會問一樣的問題。

在面試的過程當中,這裏我給出幾點意見:

  • 心態放平穩,假設第一題你答不上來很正常,面試官不會由於第一題你不會就PASS你
  • 不會的題目必定不要瞎猜,每每面試官給你挖的坑就是但願你往錯的方向猜,必定要答不知道
  • 不要說太多跟當前面試題無關的內容,問你什麼問題儘可能就答什麼問題,除非面試官指定你發散一下思惟
  • 若是沒有聽懂面試題能夠試着詢問面試官,您要問的是關於xxx的問題麼
  • 對於某些問題必定要本身先提早精煉一下(例如做用域鏈、繼承以及原型鏈等問題)
  • 若是面試官問的某項技術本身在某些場景使用過或看到別的場景有使用,可結合這些場景進行講解(讓面試官知道你不只僅理解它,你還會很好的使用它)
  • 若是是Vue技術棧但願能夠深刻源碼或者至少理解一些別人的源碼分析
  • 若是面試阿里那麼面試以前必定要好好準備這樣一個問題:你以爲你最擅長什麼
  • 面試必定要真誠,切勿投機取巧
  • 面試態度必定要謙虛

接下來我會按照面試順序給出面試題以及本身理解的一些答案:

  • 大部分答案都是借鑑別人的博客
  • 有些答案不必定合理
  • 有些答案寫的很零散
  • 有些答案會觸類旁通
  • 有些題目太基礎或者重複了就沒有寫答案
  • 有些題目太宏觀或者不知道怎麼回答合理,但願你們能夠在評論中補充答案供更多的人受益

有贊(一面)

說說CSS選擇器以及這些選擇器的優先級

  • !important
  • 內聯樣式(1000)
  • ID選擇器(0100)
  • 類選擇器/屬性選擇器/僞類選擇器(0010)
  • 元素選擇器/關係選擇器/僞元素選擇器(0001)
  • 通配符選擇器(0000)

你知道什麼是BFC麼

小提示:這個問題重點是BFC是什麼,BFC觸發的條件有哪些,BFC能夠幹什麼。這裏我試着講解了一下Boostrap的清除浮動(display:table建立匿名table-cell間接觸發BFC),若是有看到別的場景使用或者自身有使用的場景能夠嘗試講解一下使用技巧。這樣可讓面試官以爲你不只僅知道他問的東西是什麼,你還能很好的使用它。

什麼是BFC

BFC 全稱爲塊級格式化上下文 (Block Formatting Context) 。BFC是 W3C CSS 2.1 規範中的一個概念,它決定了元素如何對其內容進行定位以及與其餘元素的關係和相互做用,當涉及到可視化佈局的時候,Block Formatting Context提供了一個環境,HTML元素在這個環境中按照必定規則進行佈局。一個環境中的元素不會影響到其它環境中的佈局。好比浮動元素會造成BFC,浮動元素內部子元素的主要受該浮動元素影響,兩個浮動元素之間是互不影響的。這裏有點相似一個BFC就是一個獨立的行政單位的意思。能夠說BFC就是一個做用範圍,把它理解成是一個獨立的容器,而且這個容器裏box的佈局與這個容器外的box絕不相干。

觸發BFC的條件

  • 根元素或其它包含它的元素
  • 浮動元素 (元素的 float 不是 none)
  • 絕對定位元素 (元素具備 positionabsolutefixed)
  • 內聯塊 (元素具備 display: inline-block)
  • 表格單元格 (元素具備 display: table-cell,HTML表格單元格默認屬性)
  • 表格標題 (元素具備 display: table-caption, HTML表格標題默認屬性)
  • 具備overflow 且值不是 visible 的塊元素
  • 彈性盒(flexinline-flex
  • display: flow-root
  • column-span: all

BFC的約束規則

  • 內部的盒會在垂直方向一個接一個排列(能夠看做BFC中有一個的常規流)
  • 處於同一個BFC中的元素相互影響,可能會發生外邊距重疊
  • 每一個元素的margin box的左邊,與容器塊border box的左邊相接觸(對於從左往右的格式化,不然相反),即便存在浮動也是如此
  • BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之亦然
  • 計算BFC的高度時,考慮BFC所包含的全部元素,連浮動元素也參與計算
  • 浮動盒區域不疊加到BFC上

BFC能夠解決的問題

  • 垂直外邊距重疊問題
  • 去除浮動
  • 自適用兩列布局(float + overflow

瞭解盒模型麼

包括內容區域內邊距區域邊框區域外邊距區域

enter image description here

box-sizing: content-box(W3C盒子模型):元素的寬高大小表現爲內容的大小。 box-sizing: border-box(IE盒子模型):元素的寬高表現爲內容 + 內邊距 + 邊框的大小。背景會延伸到邊框的外沿。

IE5.x和IE6在怪異模式中使用非標準的盒子模型,這些瀏覽器的width屬性不是內容的寬度,而是內容內邊距邊框的寬度的總和。

如何實現左側寬度固定,右側寬度自適應的佈局

小提示:這個問題面試官會要求說出幾種解決方法。

DOM結構

<div class="box">
  <div class="box-left"></div>
  <div class="box-right"></div>
</div>
複製代碼

利用float + margin實現

.box {
 height: 200px;
}

.box > div {
  height: 100%;
}

.box-left {
  width: 200px;
  float: left;
  background-color: blue;
}

.box-right {
  margin-left: 200px;
  background-color: red;
}
複製代碼

利用calc計算寬度

.box {
 height: 200px;
}

.box > div {
  height: 100%;
}

.box-left {
  width: 200px;
  float: left;
  background-color: blue;
}

.box-right {
  width: calc(100% - 200px);
  float: right;
  background-color: red;
}
複製代碼

利用float + overflow實現

.box {
 height: 200px;
}

.box > div {
  height: 100%;
}

.box-left {
  width: 200px;
  float: left;
  background-color: blue;
}

.box-right {
  overflow: hidden;
  background-color: red;
}
複製代碼

利用flex實現

這裏不是最佳答案,應該是使用flex-basis實現更合理

.box {
  height: 200px;
  display: flex;
}

.box > div {
  height: 100%;
}

.box-left {
  width: 200px;
  background-color: blue;
}

.box-right {
  flex: 1; // 設置flex-grow屬性爲1,默認爲0
  overflow: hidden;
  background-color: red;
}
複製代碼

瞭解跨域嗎,通常什麼狀況下會致使跨域

小提示: 若是日常自身有使用場景可結合使用場景進行講解,好比我在這裏使用過的場景是CORS和Nginx反向代理。

跨域行爲

  • 同源策略限制、安全性考慮
  • 協議、IP和端口不一致都是跨域行爲

JSONP

小提示:若是你提到JSONP,面試官確定會問你整個詳細的實現過程,因此必定要搞懂JSONP的實現原理,若是不是很理解能夠本身起一個Express服務實踐一下。

Web前端事先定義一個用於獲取跨域響應數據的回調函數,並經過沒有同源策略限制的script標籤發起一個請求(將回調函數的名稱放到這個請求的query參數裏),而後服務端返回這個回調函數的執行,並將須要響應的數據放到回調函數的參數裏,前端的script標籤請求到這個執行的回調函數後會立馬執行,因而就拿到了執行的響應數據。

缺點: JSONP只能發起GET請求

如何實現一個JSONP

這裏給出幾個連接:

segmentfault.com/a/119000001… zhangguixu.github.io/2016/12/02/… www.cnblogs.com/iovec/p/531…

JSONP安全性問題

CSRF攻擊

前端構造一個惡意頁面,請求JSONP接口,收集服務端的敏感信息。若是JSONP接口還涉及一些敏感操做或信息(好比登陸、刪除等操做),那就更不安全了。

解決方法:驗證JSONP的調用來源(Referer),服務端判斷Referer是不是白名單,或者部署隨機Token來防護。

XSS漏洞

不嚴謹的 content-type致使的 XSS 漏洞,想象一下 JSONP 就是你請求 http://youdomain.com?callback=douniwan, 而後返回 douniwan({ data }),那假如請求 http://youdomain.com?callback=<script>alert(1)</script> 不就返回 <script>alert(1)</script>({ data })了嗎,若是沒有嚴格定義好 Content-Type( Content-Type: application/json ),再加上沒有過濾 callback 參數,直接當 html 解析了,就是一個赤裸裸的 XSS 了。

解決方法:嚴格定義 Content-Type: application/json,而後嚴格過濾 callback 後的參數而且限制長度(進行字符轉義,例如<換成&lt,>換成&gt)等,這樣返回的腳本內容會變成文本格式,腳本將不會執行。

服務器被黑,返回一串惡意執行的代碼

能夠將執行的代碼轉發到服務端進行校驗JSONP內容校驗,再返回校驗結果。

CORS(跨域資款共享)

小提示:若是你回答跨域解決方案CORS,那麼面試官必定會問你實現CORS的響應頭信息Access-Control-Allow-Origin。

什麼是CORS

CORS(跨域資源共享 Cross-origin resource sharing)容許瀏覽器向跨域服務器發出XMLHttpRequest請求,從而克服跨域問題,它須要瀏覽器和服務器的同時支持。

  • 瀏覽器端會自動向請求頭添加origin字段,代表當前請求來源。
  • 服務器端須要設置響應頭的Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin等字段,指定容許的方法,頭部,源等信息。
  • 請求分爲簡單請求和非簡單請求,非簡單請求會先進行一次OPTION方法進行預檢,看是否容許當前跨域請求。
簡單請求

請求方法是如下三種方法之一:

  • HEAD
  • GET
  • POST

HTTP的請求頭信息不超出如下幾種字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain

後端的響應頭信息:

  • Access-Control-Allow-Origin:該字段是必須的。它的值要麼是請求時Origin字段的值,要麼是一個*,表示接受任意域名的請求。
  • Access-Control-Allow-Credentials:該字段可選。它的值是一個布爾值,表示是否容許發送Cookie。
  • Access-Control-Expose-Headers:該字段可選。CORS請求時,XMLHttpRequest對象的getResponseHeader()方法只能拿到6個基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。若是想拿到其餘字段,就必須在Access-Control-Expose-Headers裏面指定。
非簡單請求

非簡單請求是那種對服務器有特殊要求的請求,好比請求方法是PUT或DELETE,或者Content-Type字段的類型是application/json。非簡單請求的CORS請求,會在正式通訊以前,增長一次HTTP查詢請求,稱爲"預檢"請求(preflight)。

  • Access-Control-Request-Method:該字段是必須的,用來列出瀏覽器的CORS請求會用到哪些HTTP方法,上例是PUT。

  • Access-Control-Request-Headers:該字段是一個逗號分隔的字符串,指定瀏覽器CORS請求會額外發送的頭信息字段,上例是X-Custom-Header。

若是瀏覽器否認了"預檢"請求,會返回一個正常的HTTP迴應,可是沒有任何CORS相關的頭信息字段。這時,瀏覽器就會認定,服務器不一樣意預檢請求,所以觸發一個錯誤,被XMLHttpRequest對象的onerror回調函數捕獲。

JSONP和CORS的對比

  • JSONP只支持GET請求,CORS支持全部類型的HTTP請求
  • JSONP的優點在於支持老式瀏覽器,以及能夠向不支持CORS的網站請求數據

其餘跨域解決方案

  • Nginx反向代理
  • postMessage
  • document.domain

HTTP2和HTTP1有什麼區別

相對於HTTP1.0,HTTP1.1的優化:

  • 緩存處理:多了Entity tag,If-Unmodified-Since, If-Match, If-None-Match等緩存信息(HTTTP1.0 If-Modified-Since,Expires)
  • 帶寬優化及網絡鏈接的使用
  • 錯誤通知的管理
  • Host頭處理
  • 長鏈接: HTTP1.1中默認開啓Connection: keep-alive,必定程度上彌補了HTTP1.0每次請求都要建立鏈接的缺點。

相對於HTTP1.1,HTTP2的優化:

  • HTTP2支持二進制傳送(實現方便且健壯),HTTP1.x是字符串傳送
  • HTTP2支持多路複用
  • HTTP2採用HPACK壓縮算法壓縮頭部,減少了傳輸的體積
  • HTTP2支持服務端推送

你能說說緩存麼

小提示:若是日常有遇到過緩存的坑或者很好的利用緩存,能夠講解一下本身的使用場景。若是沒有使用注意過緩存問題你也能夠嘗試講解一下和咱們息息相關的Webpack構建(每一次構建靜態資源名稱的hash值都會變化),它其實就跟緩存相關。有興趣的同窗能夠查看張雲龍的博客大公司裏怎樣開發和部署前端代碼?

緩存分爲強緩存和協商緩存。強緩存不過服務器,協商緩存須要過服務器,協商緩存返回的狀態碼是304。兩類緩存機制能夠同時存在,強緩存的優先級高於協商緩存。當執行強緩存時,如若緩存命中,則直接使用緩存數據庫中的數據,再也不進行緩存協商。

強緩存

Expires(HTTP1.0):Exprires的值爲服務端返回的數據到期時間。當再次請求時的請求時間小於返回的此時間,則直接使用緩存數據。但因爲服務端時間和客戶端時間可能有偏差,這也將致使緩存命中的偏差。另外一方面,Expires是HTTP1.0的產物,故如今大多數使用Cache-Control替代。

缺點:使用的是絕對時間,若是服務端和客戶端的時間產生誤差,那麼會致使命中緩存產生誤差。

Pragma(HTTP1.0):HTTP1.0時的遺留字段,當值爲"no-cache"時強制驗證緩存,Pragma禁用緩存,若是又給Expires定義一個還未到期的時間,那麼Pragma字段的優先級會更高。服務端響應添加'Pragma': 'no-cache',瀏覽器表現行爲和刷新(F5)相似。

Cache-Control(HTTP1.1):有不少屬性,不一樣的屬性表明的意義也不一樣:

  • private:客戶端能夠緩存
  • public:客戶端和代理服務器均可以緩存
  • max-age=t:緩存內容將在t秒後失效
  • no-cache:須要使用協商緩存來驗證緩存數據
  • no-store:全部內容都不會緩存

請注意no-cache指令不少人誤覺得是不緩存,這是不許確的,no-cache的意思是能夠緩存,但每次用應該去想服務器驗證緩存是否可用。no-store纔是不緩存內容。當在首部字段Cache-Control 有指定 max-age 指令時,比起首部字段 Expires,會優先處理 max-age 指令。命中強緩存的表現形式:Firefox瀏覽器表現爲一個灰色的200狀態碼。Chrome瀏覽器狀態碼錶現爲200 (from disk cache)或是200 OK (from memory cache)。

協商緩存

協商緩存須要進行對比判斷是否能夠使用緩存。瀏覽器第一次請求數據時,服務器會將緩存標識與數據一塊兒響應給客戶端,客戶端將它們備份至緩存中。再次請求時,客戶端會將緩存中的標識發送給服務器,服務器根據此標識判斷。若未失效,返回304狀態碼,瀏覽器拿到此狀態碼就能夠直接使用緩存數據了。

Last-Modified:服務器在響應請求時,會告訴瀏覽器資源的最後修改時間。

if-Modified-Since:瀏覽器再次請求服務器的時候,請求頭會包含此字段,後面跟着在緩存中得到的最後修改時間。服務端收到此請求頭髮現有if-Modified-Since,則與被請求資源的最後修改時間進行對比,若是一致則返回304和響應報文頭,瀏覽器只須要從緩存中獲取信息便可。

  • 若是真的被修改:那麼開始傳輸響應一個總體,服務器返回:200 OK
  • 若是沒有被修改:那麼只需傳輸響應header,服務器返回:304 Not Modified

if-Unmodified-Since: 從某個時間點算起, 是否文件沒有被修改,使用的是相對時間,不須要關心客戶端和服務端的時間誤差。

  • 若是沒有被修改:則開始`繼續'傳送文件,服務器返回: 200 OK
  • 若是文件被修改:則不傳輸,服務器返回: 412 Precondition failed (預處理錯誤)

這兩個的區別是一個是修改了才下載一個是沒修改才下載。若是在服務器上,一個資源被修改了,但其實際內容根本沒發生改變,會由於Last-Modified時間匹配不上而返回了整個實體給客戶端(即便客戶端緩存裏有個如出一轍的資源)。爲了解決這個問題,HTTP1.1推出了Etag。

Etag:服務器響應請求時,經過此字段告訴瀏覽器當前資源在服務器生成的惟一標識(生成規則由服務器決定)

If-Match:條件請求,攜帶上一次請求中資源的ETag,服務器根據這個字段判斷文件是否有新的修改

If-None-Match: 再次請求服務器時,瀏覽器的請求報文頭部會包含此字段,後面的值爲在緩存中獲取的標識。服務器接收到次報文後發現If-None-Match則與被請求資源的惟一標識進行對比。

  • 不一樣,說明資源被改動過,則響應整個資源內容,返回狀態碼200。
  • 相同,說明資源無意修改,則響應header,瀏覽器直接從緩存中獲取數據信息。返回狀態碼304.

可是實際應用中因爲Etag的計算是使用算法來得出的,而算法會佔用服務端計算的資源,全部服務端的資源都是寶貴的,因此就不多使用Etag了。

  • 瀏覽器地址欄中寫入URL,回車瀏覽器發現緩存中有這個文件了,不用繼續請求了,直接去緩存拿(最快)
  • F5就是告訴瀏覽器,別偷懶,好歹去服務器看看這個文件是否有過時了。因而瀏覽器就膽膽襟襟的發送一個請求帶上If-Modify-since
  • Ctrl+F5告訴瀏覽器,你先把你緩存中的這個文件給我刪了,而後再去服務器請求個完整的資源文件下來。因而客戶端就完成了強行更新的操做

緩存場景

對於大部分的場景均可以使用強緩存配合協商緩存解決,可是在一些特殊的地方可能須要選擇特殊的緩存策略

  • 對於某些不須要緩存的資源,能夠使用 Cache-control: no-store ,表示該資源不須要緩存
  • 對於頻繁變更的資源,能夠使用 Cache-Control: no-cache 並配合 ETag 使用,表示該資源已被緩存,可是每次都會發送請求詢問資源是否更新
  • 對於代碼文件來講,一般使用 Cache-Control: max-age=31536000 並配合策略緩存使用,而後對文件進行指紋處理,一旦文件名變更就會馬上下載新的文件

能說說首屏加載優化有哪些方案麼

小提示:若是作過相似優化的同窗,可能就比較好回答,沒有作過相似優化的同窗能夠重點講解一下懶加載(固然我這裏被面試官追問過懶加載的Webpack配置問題)。同時不知道使用Vue技術棧的同窗們有沒有仔細觀察過Vue CLI 3構建的html文件中的link標籤的rel屬性。

  • Vue-Router路由懶加載(利用Webpack的代碼切割)
  • 使用CDN加速,將通用的庫從vendor進行抽離
  • Nginx的gzip壓縮
  • Vue異步組件
  • 服務端渲染SSR
  • 若是使用了一些UI庫,採用按需加載
  • Webpack開啓gzip壓縮
  • 若是首屏爲登陸頁,能夠作成多入口
  • Service Worker緩存文件處理
  • 使用link標籤的rel屬性設置 prefetch(這段資源將會在將來某個導航或者功能要用到,可是本資源的下載順序權重比較低,prefetch一般用於加速下一次導航)、preload(preload將會把資源得下載順序權重提升,使得關鍵數據提早下載好,優化頁面打開速度)

如何在Node端配置路徑別名(相似於Webpack中的alias配置)

  • 全局變量
  • 環境變量
  • 本身HACK一個@符號,指向特定的路徑
  • HACK require方法

參考

這種問題仍是附上參考連接

segmentfault.com/a/119000001… chashaobao.net/2017/09/03/… www.zhihu.com/question/26…

談談你對做用域鏈的理解

小提示:同類型的問題還能夠是原型鏈、繼承、閉包等,這種概念性的問題你確定不是一句兩句能說清楚的,建議在理解以後本身嘗試總結一下,如何把重要的知識點用簡短的話語說明白。

瞭解做用域鏈以前咱們要知道一下幾個概念:

  • 函數的生命週期
  • 變量和函數的聲明
  • Activetion Object(AO)、Variable Object(VO)

函數的生命週期:

  • 建立:JS解析引擎進行預解析,會將函數聲明提早,同時將該函數放到全局做用域中或當前函數的上一級函數的局部做用域中。

  • 執行:JS引擎會將當前函數的局部變量和內部函數進行聲明提早,而後再執行業務代碼,當函數執行完退出時,釋放該函數的執行上下文,並註銷該函數的局部變量。

變量和函數的聲明:若是變量名和函數名聲明時相同,函數優先聲明。

Activetion Object(AO)、Variable Object(VO):

  • AO:Activetion Object(活動對象)
  • VO:Variable Object(變量對象)

VO對應的是函數建立階段,JS解析引擎進行預解析時,全部的變量和函數的聲明,統稱爲Variable Object。該變量與執行上下文相關,知道本身的數據存儲在哪裏,而且知道如何訪問。VO是一個與執行上下文相關的特殊對象,它存儲着在上下文中聲明的如下內容:

  • 變量 (var, 變量聲明);
  • 函數聲明 (FunctionDeclaration, 縮寫爲FD);
  • 函數的形參

AO對應的是函數執行階段,當函數被調用執行時,會創建一個執行上下文,該執行上下文包含了函數所需的全部變量,該變量共同組成了一個新的對象就是Activetion Object。該對象包含了:

  • 函數的全部局部變量
  • 函數的全部命名參數
  • 函數的參數集合
  • 函數的this指向

做用域鏈:

當代碼在一個環境中建立時,會建立變量對象的一個做用域鏈(scope chain)來保證對執行環境有權訪問的變量和函數。做用域第一個對象始終是當前執行代碼所在環境的變量對象(VO)。若是是函數執行階段,那麼將其activation object(AO)做爲做用域鏈第一個對象,第二個對象是上級函數的執行上下文AO,下一個對象依次類推。

在《JavaScript深刻之變量對象》中講到,當查找變量的時候,會先從當前上下文的變量對象中查找,若是沒有找到,就會從父級(詞法層面上的父級)執行上下文的變量對象中查找,一直找到全局上下文的變量對象,也就是全局對象。這樣由多個執行上下文的變量對象構成的鏈表就叫作做用域鏈。

你知道nullundefined有什麼區別麼

閉包有什麼做用

Vue響應式原理

小提示:若是面試者使用的是Vue技術棧,那麼響應式原理是一個必問的問題,同時面試官常常也會問Vue 3.0在響應式原理上的優化方案。

若是對於響應式原理不是很清楚能夠查看我以前寫的文章基於Vue實現一個簡易MVVM/數據劫持的實現

瞭解Event Loop麼

小提示:這個題目問到的機率仍是蠻大的,這裏面試官詢問了我瀏覽器端和Node端的Event Loop有什麼不一樣點。若是想要知道更多瀏覽器端的Event Loop機制能夠查看我以前寫的文章你真的理解$nextTick麼/JS引擎線程和事件觸發線程/事件循環機制

事件觸發線程管理的任務隊列是如何產生的呢?事實上這些任務就是從JS引擎線程自己產生的,主線程在運行時會產生執行棧,棧中的代碼調用某些異步API時會在任務隊列中添加事件,棧中的代碼執行完畢後,就會讀取任務隊列中的事件,去執行事件對應的回調函數,如此循環往復,造成事件循環機制。JS中有兩種任務類型:微任務(microtask)和宏任務(macrotask),在ES6中,microtask稱爲 jobs,macrotask稱爲 task:

  • 宏任務: script (主代碼塊)、setTimeoutsetIntervalsetImmediate 、I/O 、UI rendering
  • 微任務:process.nextTick(Nodejs) 、PromiseObject.observeMutationObserver

Node.js中Event Loop和瀏覽器中Event Loop有什麼區別

┌───────────────────────┐
┌─>│        timers         │<————— 執行 setTimeout()、setInterval() 的回調
│  └──────────┬────────────┘
|             |<-- 執行全部 Next Tick Queue 以及 MicroTask Queue 的回調 │ ┌──────────┴────────────┐ │ │ pending callbacks │<————— 執行由上一個 Tick 延遲下來的 I/O 回調(待完善,可忽略) │ └──────────┬────────────┘ | |<-- 執行全部 Next Tick Queue 以及 MicroTask Queue 的回調 │ ┌──────────┴────────────┐ │ │ idle, prepare │<————— 內部調用(可忽略) │ └──────────┬────────────┘ | |<-- 執行全部 Next Tick Queue 以及 MicroTask Queue 的回調 | | ┌───────────────┐ │ ┌──────────┴────────────┐ │ incoming:- (執行幾乎全部的回調,除了 close callbackstimerssetImmediate) │ │ poll │<─────┤ connections, │ │ └──────────┬────────────┘ │ data, etc. │ │ | | | | | └───────────────┘ | |<-- 執行全部 Next Tick Queue 以及 MicroTask Queue 的回調 | ┌──────────┴────────────┐ │ │ check │<————— setImmediate() 的回調將會在這個階段執行 │ └──────────┬────────────┘ | |<-- 執行全部 Next Tick Queue 以及 MicroTask Queue 的回調 │ ┌──────────┴────────────┐ └──┤ close callbacks │<————— socket.on('close', ...) └───────────────────────┘ 複製代碼

Node.js中宏任務分紅了幾種類型,而且放在了不一樣的task queue裏。不一樣的task queue在執行順序上也有區別,微任務放在了每一個task queue的末尾:

  • setTimeout/setInterval 屬於 timers 類型;
  • setImmediate 屬於 check 類型;
  • socket 的 close 事件屬於 close callbacks 類型;
  • 其餘 MacroTask 都屬於 poll 類型。
  • process.nextTick 本質上屬於 MicroTask,可是它先於全部其餘 MicroTask 執行;
  • 全部 MicroTask 的執行時機在不一樣類型的 MacroTask 切換後。
  • idle/prepare 僅供內部調用,咱們能夠忽略。
  • pending callbacks 不太常見,咱們也能夠忽略。

如何避免迴流和重繪

瀏覽器渲染過程

enter image description here

  • 瀏覽器使用流式佈局模型 (Flow Based Layout)
  • 瀏覽器會把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合併就產生了Render Tree
  • 有了RenderTree就能知道全部節點的樣式,計算節點在頁面上的大小和位置,把節點繪製到頁面上
  • 因爲瀏覽器使用流式佈局,對Render Tree的計算一般只須要遍歷一次就能夠完成,但table及其內部元素除外,一般須要屢次計算且要花費3倍於同等元素的時間,這也是爲何要避免使用table佈局的緣由之一

瀏覽器渲染過程以下:

  • 解析HTML,生成DOM樹
  • 解析CSS,生成CSSOM樹
  • 將DOM樹和CSSOM樹結合,生成渲染樹(Render Tree)
  • Layout(迴流):根據生成的渲染樹,進行迴流(Layout),獲得節點的幾何信息(位置,大小)
  • Painting(重繪):根據渲染樹以及迴流獲得的幾何信息,獲得節點的絕對像素
  • Display:將像素髮送給GPU,展現在頁面上。(這一步其實還有不少內容,好比會在GPU將多個合成層合併爲同一個層,並展現在頁面中。而css3硬件加速的原理則是新建合成層,這裏咱們不展開,以後有機會會寫一篇博客)

什麼時候觸發迴流和重繪

什麼時候發生迴流:

  • 添加或刪除可見的DOM元素
  • 元素的位置發生變化
  • 元素的尺寸發生變化(包括外邊距、內邊框、邊框大小、高度和寬度等)
  • 內容發生變化,好比文本變化或圖片被另外一個不一樣尺寸的圖片所替代。
  • 頁面一開始渲染的時候(這確定避免不了)
  • 瀏覽器的窗口尺寸變化(由於迴流是根據視口的大小來計算元素的位置和大小的)

什麼時候發生重繪(迴流必定會觸發重繪):

當頁面中元素樣式的改變並不影響它在文檔流中的位置時(例如:color、background-color、visibility等),瀏覽器會將新樣式賦予給元素並從新繪製它,這個過程稱爲重繪。

有時即便僅僅迴流一個單一的元素,它的父元素以及任何跟隨它的元素也會產生迴流。現代瀏覽器會對頻繁的迴流或重繪操做進行優化,瀏覽器會維護一個隊列,把全部引發迴流和重繪的操做放入隊列中,若是隊列中的任務數量或者時間間隔達到一個閾值的,瀏覽器就會將隊列清空,進行一次批處理,這樣能夠把屢次迴流和重繪變成一次。你訪問如下屬性或方法時,瀏覽器會馬上清空隊列:

  • clientWidthclientHeightclientTopclientLeft
  • offsetWidthoffsetHeightoffsetTopoffsetLeft
  • scrollWidthscrollHeightscrollTopscrollLeft
  • widthheight
  • getComputedStyle()
  • getBoundingClientRect()

以上屬性和方法都須要返回最新的佈局信息,所以瀏覽器不得不清空隊列,觸發迴流重繪來返回正確的值。所以,咱們在修改樣式的時候,**最好避免使用上面列出的屬性,他們都會刷新渲染隊列。**若是要使用它們,最好將值緩存起來。

如何避免觸發迴流和重繪

CSS:

  • 避免使用table佈局。
  • 儘量在DOM樹的最末端改變class。
  • 避免設置多層內聯樣式。
  • 將動畫效果應用到position屬性爲absolutefixed的元素上
  • 避免使用CSS表達式(例如:calc()
  • CSS3硬件加速(GPU加速)

JavaScript:

  • 避免頻繁操做樣式,最好一次性重寫style屬性,或者將樣式列表定義爲class並一次性更改class屬性
  • 避免頻繁操做DOM,建立一個documentFragment,在它上面應用全部DOM操做,最後再把它添加到文檔中
  • 也能夠先爲元素設置display: none,操做結束後再把它顯示出來。由於在display屬性爲none的元素上進行的DOM操做不會引起迴流和重繪
  • 避免頻繁讀取會引起迴流/重繪的屬性,若是確實須要屢次使用,就用一個變量緩存起來
  • 對具備複雜動畫的元素使用絕對定位,使它脫離文檔流,不然會引發父元素及後續元素頻繁迴流

有贊(二面)

小提示:進入現場面試須要注意好好準備本身的簡歷,面試官通常會根據項目進行問答。

筆試題環節

一開始面試官就發了兩張筆試題試卷,總共四道題目,大體考了如下知識點:

  • 做用域
  • 原型鏈(例如實例屬性和原型屬性同樣,刪除實例屬性後能夠繼續訪問原型屬性問題)
  • 宏任務和微任務的打印順序
  • Array.prototype.map的第二個參數

項目問答環節

答完試卷面試官就開始問簡歷上的一些項目,我記得其中幾個問題以下(事實上他問的一些問題和簡歷不是很相關):

  • 大家產品的服務器部署在哪裏
  • 你是如何實現一個Tooltip組件的,能寫一下怎麼使用這個組件麼(這算什麼問題...)
  • 我認識大家海康的一些開發,我知道大家的產品按套數賣的...

我當場就感覺到了面試官問的問題很敷衍,可能他以爲個人簡歷不夠好,又或者以爲我能力不行,接下來面試官又讓我作了一道算法題...

算法題環節

  • 1塊、4塊、5塊,求總數n塊的最小硬幣數

當時沒作出來,非科班出身可能作這些確實有些困難,也沒有系統的學習,面試官看我很困難的樣子,就換了一道題。

  • 一、一、二、三、五、8...計算第n個數的值(斐波那契數列)

這道題仍是作出來了,畢竟比較簡單,而後面試官說今天先到這裏,面試結果會在一星期內通知,而後回來的那天晚上就收到了面試沒過的通知。

小結

仍是蠻感謝此次現場面試的經歷,讓我知道若是自身不夠硬,到哪裏都會很被動。面試的好處不只僅在於檢驗本身到底有多少能力,更應該發現自身的不足,同時不斷的去彌補這些不足。因而我再次捧起以前擱置的《算法導論》,而且建立了一個算法學習演示文檔I-Algorithms,但願能夠簡化《算法導論》的一些理論知識,使你們對於算法的學習能夠變得更加系統全面和簡單,也但願經過這個學習使得算法面試會變得更加駕輕就熟,但願感興趣的同窗能夠star一下。

enter image description here

滴滴(一面)

你知道哪些安全問題,如何避免

小提示:這裏我簡單講解了一下Vue中的v-html防範XSS攻擊。

XSS(跨站腳本攻擊)

XSS,即 Cross Site Script,中譯是跨站腳本攻擊;其本來縮寫是 CSS,但爲了和層疊樣式表(Cascading Style Sheet)有所區分,於是在安全領域叫作 XSS。

XSS 攻擊是指攻擊者在網站上注入惡意的客戶端代碼,經過惡意腳本對客戶端網頁進行篡改,從而在用戶瀏覽網頁時,對用戶瀏覽器進行控制或者獲取用戶隱私數據的一種攻擊方式。

攻擊者對客戶端網頁注入的惡意腳本通常包括 JavaScript,有時也會包含 HTML 和 Flash。有不少種方式進行 XSS 攻擊,但它們的共同點爲:將一些隱私數據像 cookie、session 發送給攻擊者,將受害者重定向到一個由攻擊者控制的網站,在受害者的機器上進行一些惡意操做。

XSS攻擊能夠分爲3類:反射型(非持久型)、存儲型(持久型)、基於DOM。

反射型

反射型 XSS 只是簡單地把用戶輸入的數據 「反射」 給瀏覽器,這種攻擊方式每每須要攻擊者誘使用戶點擊一個惡意連接(攻擊者能夠將惡意連接直接發送給受信任用戶,發送的方式有不少種,好比 email, 網站的私信、評論等,攻擊者能夠購買存在漏洞網站的廣告,將惡意連接插入在廣告的連接中),或者提交一個表單,或者進入一個惡意網站時,注入腳本進入被攻擊者的網站。最簡單的示例是訪問一個連接,服務端返回一個可執行腳本:

const http = require('http');
function handleReequest(req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'});
    res.write('<script>alert("反射型 XSS 攻擊")</script>');
    res.end();
}

const server = new http.Server();
server.listen(8001, '127.0.0.1');
server.on('request', handleReequest);
複製代碼
存儲型

存儲型 XSS 會把用戶輸入的數據 "存儲" 在服務器端,當瀏覽器請求數據時,腳本從服務器上傳回並執行。這種 XSS 攻擊具備很強的穩定性。比較常見的一個場景是攻擊者在社區或論壇上寫下一篇包含惡意 JavaScript 代碼的文章或評論,文章或評論發表後,全部訪問該文章或評論的用戶,都會在他們的瀏覽器中執行這段惡意的 JavaScript 代碼:

// 例如在評論中輸入如下留言
// 若是請求這段留言的時候服務端不作轉義處理,請求以後頁面會執行這段惡意代碼
<script>alert('xss 攻擊')</script>
複製代碼
基於DOM

基於 DOM 的 XSS 攻擊是指經過惡意腳本修改頁面的 DOM 結構,是純粹發生在客戶端的攻擊:

<h2>XSS: </h2>
<input type="text" id="input">
<button id="btn">Submit</button>
<div id="div"></div>
<script>
    const input = document.getElementById('input');
    const btn = document.getElementById('btn');
    const div = document.getElementById('div');

    let val;
     
    input.addEventListener('change', (e) => {
        val = e.target.value;
    }, false);

    btn.addEventListener('click', () => {
        div.innerHTML = `<a href=${val}>testLink</a>`
    }, false);
</script>
複製代碼

點擊 Submit 按鈕後,會在當前頁面插入一個連接,其地址爲用戶的輸入內容。若是用戶在輸入時構造了以下內容:

'' onclick=alert(/xss/)
複製代碼

用戶提交以後,頁面代碼就變成了:

<a href onlick="alert(/xss/)">testLink</a>
複製代碼

此時,用戶點擊生成的連接,就會執行對應的腳本。

XSS攻擊防範

HttpOnly 防止劫取 Cookie:HttpOnly 最先由微軟提出,至今已經成爲一個標準。瀏覽器將禁止頁面的Javascript 訪問帶有 HttpOnly 屬性的Cookie。上文有說到,攻擊者能夠經過注入惡意腳本獲取用戶的 Cookie 信息。一般 Cookie 中都包含了用戶的登陸憑證信息,攻擊者在獲取到 Cookie 以後,則能夠發起 Cookie 劫持攻擊。因此,嚴格來講,HttpOnly 並不是阻止 XSS 攻擊,而是能阻止 XSS 攻擊後的 Cookie 劫持攻擊。

輸入檢查:不要相信用戶的任何輸入。 對於用戶的任何輸入要進行檢查、過濾和轉義。創建可信任的字符和 HTML 標籤白名單,對於不在白名單之列的字符或者標籤進行過濾或編碼。在 XSS 防護中,輸入檢查通常是檢查用戶輸入的數據中是否包含 <,> 等特殊字符,若是存在,則對特殊字符進行過濾或編碼,這種方式也稱爲 XSS Filter。而在一些前端框架中,都會有一份 decodingMap, 用於對用戶輸入所包含的特殊字符或標籤進行編碼或過濾,如 <,>,script,防止 XSS 攻擊:

// vuejs 中的 decodingMap
// 在 vuejs 中,若是輸入帶 script 標籤的內容,會直接過濾掉
const decodingMap = {
  '&lt;': '<',
  '&gt;': '>',
  '&quot;': '"',
  '&amp;': '&',
  '&#10;': '\n'
}
複製代碼

輸出檢查:用戶的輸入會存在問題,服務端的輸出也會存在問題。通常來講,除富文本的輸出外,在變量輸出到 HTML 頁面時,能夠使用編碼或轉義的方式來防護 XSS 攻擊。例如利用 sanitize-html 對輸出內容進行有規則的過濾以後再輸出到頁面中。

CSRF/XSRF(跨站請求僞造)

CSRF,即 Cross Site Request Forgery,中譯是跨站請求僞造,是一種劫持受信任用戶向服務器發送非預期請求的攻擊方式。一般狀況下,CSRF 攻擊是攻擊者藉助受害者的 Cookie 騙取服務器的信任,能夠在受害者絕不知情的狀況下以受害者名義僞造請求發送給受攻擊服務器,從而在並未受權的狀況下執行在權限保護之下的操做。

Cookie

Cookie 是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶併發送到服務器上。Cookie 主要用於如下三個方面:

  • 會話狀態管理(如用戶登陸狀態、購物車、遊戲分數或其它須要記錄的信息)
  • 個性化設置(如用戶自定義設置、主題等)
  • 瀏覽器行爲跟蹤(如跟蹤分析用戶行爲等)

而瀏覽器所持有的 Cookie 分爲兩種:

  • Session Cookie(會話期 Cookie):會話期 Cookie 是最簡單的Cookie,它不須要指定過時時間(Expires)或者有效期(Max-Age),它僅在會話期內有效,瀏覽器關閉以後它會被自動刪除。
  • Permanent Cookie(持久性 Cookie):與會話期 Cookie 不一樣的是,持久性 Cookie 能夠指定一個特定的過時時間(Expires)或有效期(Max-Age)。
res.setHeader('Set-Cookie', ['mycookie=222', 'test=3333; expires=Sat, 21 Jul 2018 00:00:00 GMT;']);
複製代碼

上述代碼建立了兩個 Cookie:mycookie 和 test,前者屬於會話期 Cookie,後者則屬於持久性 Cookie。

CSRF攻擊

使登陸用戶訪問攻擊者的網站,發起一個請求,因爲 Cookie 中包含了用戶的認證信息,當用戶訪問攻擊者準備的攻擊環境時,攻擊者就能夠對服務器發起 CSRF 攻擊。

在這個攻擊過程當中,攻擊者藉助受害者的 Cookie 騙取服務器的信任,但並不能拿到 Cookie,也看不到 Cookie 的內容。而對於服務器返回的結果,因爲瀏覽器同源策略的限制,攻擊者也沒法進行解析。(攻擊者的網站雖然是跨域的,可是他構造的連接是源網站的,跟源網站是同源的,因此可以攜帶cookie發起訪問)。

可是攻擊者沒法從返回的結果中獲得任何東西,他所能作的就是給服務器發送請求,以執行請求中所描述的命令,在服務器端直接改變數據的值,而非竊取服務器中的數據。例如刪除數據、修改數據,新增數據等,沒法獲取數據。

CSRF攻擊防範

驗證碼:驗證碼被認爲是對抗 CSRF 攻擊最簡潔而有效的防護方法。從上述示例中能夠看出,CSRF 攻擊每每是在用戶不知情的狀況下構造了網絡請求。而驗證碼會強制用戶必須與應用進行交互,才能完成最終請求。由於一般狀況下,驗證碼可以很好地遏制 CSRF 攻擊。但驗證碼並非萬能的,由於出於用戶考慮,不能給網站全部的操做都加上驗證碼。所以,驗證碼只能做爲防護 CSRF 的一種輔助手段,而不能做爲最主要的解決方案。

Referer Check:根據 HTTP 協議,在 HTTP 頭中有一個字段叫 Referer,它記錄了該 HTTP 請求的來源地址。經過 Referer Check,能夠檢查請求是否來自合法的"源"。

添加token驗證:要抵禦 CSRF,關鍵在於在請求中放入攻擊者所不能僞造的信息,而且該信息不存在於 Cookie 之中。能夠在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端創建一個攔截器來驗證這個 token,若是請求中沒有 token 或者 token 內容不正確,則認爲多是 CSRF 攻擊而拒絕該請求。

介紹一下Graphql

小提示:這道題是給本身挖了一個坑,抱着學習的心態嘗試使用Graphql技術,卻沒有好好理解是在什麼場景下爲了解決什麼問題才應該使用,也沒有好好準備如何描述新技術,每每這種不熟悉的技術本身在簡歷中應該留存一些心眼,儘可能不要提,不然答不上來會很尷尬,讓面試官懷疑你的項目成分。

什麼是Graphql

GraphQL是一種API查詢語言。API接口的返回值能夠從靜態變爲動態,即調用者來聲明接口返回什麼數據,能夠進一步解耦先後端。在Graphal中,預先定義Schema和聲明Type來達到動態獲取接口數據的目的:

  • 對於數據模型的抽象是經過Type來描述的
  • 對於接口獲取數據的邏輯是經過Schema來描述的

爲何要使用Graphql:

  • 接口數量衆多維護成本高
  • 接口擴展成本高
  • 接口響應的數據格式沒法預知
  • 減小無用數據的請求, 按需獲取
  • 強類型約束(API的數據格式讓前端來定義,而不是後端定義)

Type(數據模型的抽象)

Type簡單能夠分爲兩種,一種叫作Scalar Type(標量類型),另外一種叫作Object Type(對象類型):

  • Scalar Type(標量類型):內建的標量包含,String、Int、Float、Boolean、Enum

  • Object Type(對象類型):感受相似於TypeScript的接口類型

  • Type Modifier(類型修飾符):用於代表是否必填等

Schema(模式)

定義了字段的類型、數據的結構,描述了接口數據請求的規則

Query(查詢、操做類型)

查詢類型: query(查詢)、mutation(更改)和subscription(訂閱)

  • query(查詢):當獲取數據時,應當選取Query類型
  • mutation(更改):當嘗試修改數據時,應當使用mutation類型
  • subscription(訂閱):當但願數據更改時,能夠進行消息推送,使用subscription類型
Resolver(解析函數)

提供相關Query所返回數據的邏輯。Query和與之對應的Resolver是同名的,這樣在GraphQL才能把它們對應起來。解析的過程多是遞歸的,只要遇到非標量類型,會嘗試繼續解析,若是遇到標量類型,那麼解析完成,這個過程叫作解析鏈。

說說Vue中$nextTick的實現原理

小提示:若是面試者使用的是Vue技術棧,那麼$nextTick的原理是一個高頻問題,面試者藉此能夠追問的東西較多,例如瀏覽器的Event Loop、微任務和宏任務、Node.js的Event Loop、異步更新DOM(響應式的數據for循環改變了1000次爲何視圖只更新了一次)、$nextTick歷史版本問題等等。

這個若是不是很清楚的具體可查看我以前寫的文章你真的理解$nextTick麼

Vue響應式原理

談談對閉包的理解

JSONP的實現原理

CSS中的BFC

如何實現居中

水平居中

  • 如果行內元素,給其父元素設置text-align:center便可實現行內元素水平居中
  • 如果塊級元素,該元素設置margin:0 auto便可(元素須要定寬)
  • 如果塊級元素,設置父元素爲flex佈局,子元素設置margin:0 auto便可(子元素不須要定寬)
  • 使用flex 2012年版本佈局,能夠輕鬆的實現水平居中,子元素設置以下:
// flex容器
<div class="box"> 
 // flex項目
 <div class="box-center">
 </div>
</div>


.box {
  width: 200px;
  height: 200px;
  display: flex;
  // 使內部的flex項目水平居中
  justify-content: center;
  background-color: pink;
}

/* .box-center {
  width: 50%;
  background-color: greenyellow;
} */


複製代碼
  • 使用絕對定位和CSS3新增的屬性transform(這個屬性還和GPU硬件加速、固定定位相關)
.box {
  width: 200px;
  height: 200px;
  position: relative;
  background-color: pink;
}

.box-center {
  position: absolute;
  left:50%;
  // width: 50%;
  height: 100%;
  // 經過 translate() 方法,元素從其當前位置移動,根據給定的 left(x 座標) 和 top(y 座標) 位置參數:
  // translate(x,y)	定義 2D 轉換。
  // translateX(x)	定義轉換,只是用 X 軸的值。
  // translateY(y)	定義轉換,只是用 Y 軸的值。
  // left: 50% 先總體向父容器的左側偏移50%,此時是不能居中的,由於元素自己有大小
  // 接着使用transform使用百分比向左偏移自己的寬度的一半實現水平居中(這裏的百分比以元素自己的寬高爲基準)
  transform:translate(-50%,0);
  background-color: greenyellow;
}
複製代碼
  • 使用絕對定位和margin-left(元素定寬)
.box {
  width: 200px;
  height: 200px;
  position: relative;
  background-color: pink;
}

.box-center {
  position: absolute;
  left:50%;
  height: 100%;
  // 相似於transform
  // width: 50%;
  // margin-left: -25%;
  width: 100px;
  margin-left: -50px;
  background-color: greenyellow;
}
複製代碼

垂直居中

  • 若元素是單行文本, 則可設置line-height等於父元素高度
  • 如果塊級元素,設置父元素爲flex佈局,子元素設置margin: auto 0便可(子元素不須要定寬)
  • 若元素是行內塊級元素,基本思想是使用display: inline-block, vertical-align: middle和一個僞元素讓內容塊處於容器中央:
.box {
  height: 100px;
}

.box::after, .box-center{
  display:inline-block;
  vertical-align:middle;
}
.box::after{
  content:'';
  height:100%;
}
複製代碼
居中元素高度不定
  • 可用 vertical-align 屬性(vertical-align只有在父層爲 td 或者 th 時纔會生效,,對於其餘塊級元素,例如 div、p 等,默認狀況是不支持的),爲了使用vertical-align,咱們須要設置父元素display:table, 子元素 display:table-cell;vertical-align:middle
.box {
  height: 100px;
  display: table;
}

 .box-center{
    display: table-cell;
    vertical-align:middle;
}
複製代碼
  • 可用 Flex 2012版, 這是CSS佈局將來的趨勢。Flexbox是CSS3新增屬性,設計初衷是爲了解決像垂直居中這樣的常見佈局問題:
.box {
  height: 100px;
  display: flex;
  align-items: center;
}
複製代碼

優勢:內容塊的寬高任意, 優雅的溢出. 可用於更復雜高級的佈局技術中. 缺點:IE8/IE9不支持、須要瀏覽器廠商前綴、渲染上可能會有一些問題。

  • 可用 transform ,設置父元素相對定位:
.box {
  height: 100px;
  position: relative;
  background-color: pink;
}

.box-center {
  position: absolute;
  top: 50%;
  transform: translate(0, -50%);
  background-color: greenyellow;
}
複製代碼

缺點:IE8不支持, 屬性須要追加瀏覽器廠商前綴,可能干擾其餘 transform 效果,某些情形下會出現文本或元素邊界渲染模糊的現象。

居中元素高度固定
  • 設置父元素相對定位,子元素以下css樣式:
.box {
  position:relative;
  height: 100px;
  background-color: pink;
}

.box-center{
  position:absolute;
  top:50%;
  // 注意不能使用百分比
  // margin的百分比計算是相對於父容器的width來計算的,甚至包括margin-top和margin-bottom
  height: 50px;
  margin-top: -25px;
}
複製代碼
  • 設置父元素相對定位, 子元素以下css樣式:
.box {
  position:relative;
  width: 200px;
  height: 200px;
  background-color: pink;
}

.box-center{
  position:absolute;
  top: 0;
  bottom: 0;
  margin: auto 0;
  height: 100px;
  background-color: greenyellow;
}
複製代碼

水平垂直居中

  • Flex佈局(子元素是塊級元素)
.box {
  display: flex;
  width: 100px;
  height: 100px;
  background-color: pink;
}

.box-center{
  margin: auto;
  background-color: greenyellow;
}
複製代碼
  • Flex佈局
.box {
  display: flex;
  width: 100px;
  height: 100px;
  background-color: pink;
  justify-content: center;
  align-items: center;
}

.box-center{
  background-color: greenyellow;
}
複製代碼
  • 絕對定位實現(定位元素定寬定高)
.box {
  position: relative;
  height: 100px;
  width: 100px;
  background-color: pink;
}

.box-center{
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
  width: 50px;
  height: 50px;
  background-color: greenyellow;
}
複製代碼

用過Flex麼,能簡單介紹一下麼

小提示:若是在項目中使用過,可簡單介紹一下本身使用Flex解決過什麼問題,這裏我在項目中印象比較深入的是使用Flex解決上面內容高度不固定,下面內容高度自動撐滿父容器剩餘高度的問題。

若是不是很清楚Flex,能夠查看阮一峯的文章Flex 佈局教程:語法篇。面試官追問,那麼除了Flex,你還知道Grid麼?這個因爲兼容性問題,我一直沒有好好研究過,這裏可查看阮一峯的文章CSS Grid網格佈局教程

bind的源碼實現

小提示:這裏我回答使用函數柯里化加上apply或者call可實現bind,面試官追問了一些具體的實現細節。

後來我本身粗糙的實現了一下,僅供參考:

Function.prototype.myCall = function (obj) {
  obj.fn = this
  let args = [...arguments].splice(1)
  let result = obj.fn(...args)
  delete obj.fn
  return result
}

Function.prototype.myApply = function (obj) {
  obj.fn = this
  let args = arguments[1]
  let result
  if (args) {
    result = obj.fn(...args)
  } else {
    result = obj.fn()
  }

  delete obj.fn

  return result
}

Function.prototype.myBind = function (obj) {
  let context = obj || window
  let _this = this
  let _args = [...arguments].splice(1)

  return function () {
    let args = arguments
    // 產生反作用
    // return obj.fn(..._args, ...args)
    return _this.apply(context, [..._args, ...args])
  }
}

function myFun (argumentA, argumentB) {
  console.log(this.value)
  console.log(argumentA)
  console.log(argumentB)
  return this.value
}

let obj = {
  value: 'ziyi2'
}
console.log(myFun.myCall(obj, 11, 22))
console.log(myFun.myApply(obj, [11, 22]))
console.log(myFun.myBind(obj, 33)(11, 22))
複製代碼

僞類和僞元素的區別

小提示:這個問題我當時懵了一下,一會兒沒反應過來面試官想要問什麼,就答了這二者在CSS優先級上有區別,而後因爲遇到不會的問題有些緊張就多說了一些廢話,但顯然這不是面試官想要的答案而且消耗了面試官面試的耐心,說他問的不是這個。這裏再次提示你們,若是你感受你說不清楚,可是你又知道一點,我建議你說不知道,不要糾結,面試官不會由於你不知道一個問題就PASS你,相反你說了一些可有可無的廢話,反而在消耗面試官的耐性,增長負面印象。

僞類和僞元素是用來修飾不在文檔樹中的部分,好比,一句話中的第一個字母,或者是列表中的第一個元素。下面分別對僞類和僞元素進行解釋:

僞類用於當已有元素處於的某個狀態時,爲其添加對應的樣式,這個狀態是根據用戶行爲而動態變化的。好比說,當用戶懸停在指定的元素時,咱們能夠經過:hover來描述這個元素的狀態。雖然它和普通的css類類似,能夠爲已有的元素添加樣式,可是它只有處於dom樹沒法描述的狀態下才能爲元素添加樣式,因此將其稱爲僞類。

僞元素用於建立一些不在文檔樹中的元素,併爲其添加樣式。好比說,咱們能夠經過:before來在一個元素前增長一些文本,併爲這些文本添加樣式。雖然用戶能夠看到這些文本,可是這些文本實際上不在文檔樹中。

區別

僞類的操做對象是文檔樹中已有的元素,而僞元素則建立了一個文檔樹外的元素。所以,僞類與僞元素的區別在於:有沒有建立一個文檔樹以外的元素。

CSS3規範中的要求使用雙冒號(::)表示僞元素,以此來區分僞元素和僞類,好比::before和::after等僞元素使用雙冒號(::),:hover和:active等僞類使用單冒號(:)。除了一些低於IE8版本的瀏覽器外,大部分瀏覽器都支持僞元素的雙冒號(::)表示方法。

小結

對於滴滴的此次面試,我感受到本身準備的不是很充分,尤爲是本身簡歷上的項目技術Graphql。同時對於本身不會的題目強行作了一些解釋說明,其實應該簡潔明瞭的告訴面試官不會。

51信用卡(一面)

說說DOM事件流

在ES5中如何實現繼承

小提示:這裏我說了不少,從借用構造函數到組合繼承到寄生組合繼承,但面試官其實最想聽到的是寄生組合繼承。面試官還追問我具體要如何實現寄生組合繼承。固然這裏其實問的問題還能夠不少,好比ES6的類繼承和ES5中的繼承有什麼區別。

若是對於繼承以及繼承的區別不是很清楚的,能夠隨便看看我以前寫的大筆記js類和繼承

絕對定位

小提示:這個建議你們好好回憶一下,例如子元素是相對父元素的padding、border仍是content進行定位之類的,當時面試官問的就這麼細。

消抖和節流

小提示:面試官只是問了一下具體的使用場景,沒有問實現原理。

簡單消抖

function debounce (fn, wait = 1000) {
  let timeOutId

  return function () {
    let context = this

    if (timeOutId) {
      clearTimeout(timeOutId)
    }

    timeOutId = setTimeout(() => {
      fn.apply(context, arguments)
    }, wait)
  }
}
複製代碼

帶當即執行參數的消抖

function debounceImmediate (fn, wait = 1000, immediate) {
  let timeOutId, context, args

  const later = (immediate) => setTimeout(() => {
    if (!immediate) {
      fn.apply(context, args)
      timeOutId = context = args = null
    }
  }, wait)

  return function () {
    if (!timeOutId) {
      timeOutId = later(true)

      if (immediate) {
        fn.apply(this, arguments)
      }

      context = this
      args = arguments
    } else {
      clearTimeout(timeOutId)
      timeOutId = later(false)
    }
  }
}
複製代碼

節流

function throttle (fn, wait) {
  let timeoutId = null
  return function () {
    let context = this
    if (!timeoutId) {
      timeoutId = setTimeout(() => {
        fn.apply(context, arguments)
        timeoutId = null
      }, wait)
    }
  }
}
複製代碼

Vue中的computed實現原理

小提示:這個問題面試官問的很細,絕對是想問你是否閱讀過源碼。他首先問computed的實現原理,其次問了這樣一個問題:如今有兩個computed計算值,其中一個computed計算值爲何能夠依賴另一個computed計算值。這裏順便將watch的實現原理也貼上。

watch的實現原理

watch的分類:

  • deep watch(深層次監聽)
  • user watch(用戶監聽)
  • computed watcher(計算屬性)
  • sync watcher(同步監聽)

watch實現過程:

  • watch的初始化在data初始化以後(此時的data已經經過Object.defineProperty的設置成響應式)
  • watch的key會在Watcher裏進行值的讀取,也就是立馬執行get獲取value(從而實現data對應的key執行getter實現對於watch的依賴收集),此時若是有immediate屬性那麼立馬執行watch對應的回調函數
  • 當data對應的key發生變化時,觸發user watch實現watch回調函數的執行

computed運行原理

  • computed的屬性是動態掛載到vm實例上的,和普通的響應式數據在data裏聲明不一樣
  • 設置computed的getter,若是執行了computed對應的函數,因爲函數會讀取data屬性值,所以又會觸發data屬性值的getter函數,在這個執行過程當中就能夠處理computed相對於data的依賴收集關係了
  • 首次計算computed的值時,會執行vm.computed屬性對應的getter函數(用戶指定的computed函數,若是沒有設置getter,那麼將當前指定的函數賦值computed屬性的getter),進行上述的依賴收集
  • 若是computed的屬性值又依賴了其餘computed計算屬性值,那麼會將當前target暫存到棧中,先進行其餘computed計算屬性值的依賴收集,等其餘計算屬性依賴收集完成後,在從棧中pop出來,繼續進行當前computed的依賴收集
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})
複製代碼

因爲 this.firstNamethis.lastName (上面是Vue官方示例)都是響應式變量,所以會觸發它們的 getter,根據咱們以前的分析,它們會把自身持有的 dep 添加到當前正在計算的 watcher 中,這個時候Dep.target就是這個 computed watcher,具體步驟以下:

  • data 屬性初始化 getter setter
  • computed 計算屬性初始化,提供的函數將用做屬性 vm.fullName 的 getter
  • 當首次獲取 fullName 計算屬性的值時,Dep 開始依賴收集
  • 在執行 message getter 方法時,若是 Dep 處於依賴收集狀態,則斷定firstNamelastNamefullName 的依賴,並創建依賴關係
  • firstNamelastName 發生變化時,根據依賴關係,觸發 fullName 的從新計算
  • 若是計算值沒有發生變化,不會觸發視圖更新

經過以上的分析,咱們知道計算屬性本質上就是一個 computed watcher,也瞭解了它的建立過程和被訪問觸發 getter 以及依賴更新的過程,其實這是最新的計算屬性的實現,之因此這麼設計是由於 Vue 想確保不只僅是計算屬性依賴的值發生變化,而是當計算屬性最終計算的值發生變化纔會觸發渲染 watcher 從新渲染,本質上是一種優化。

computed計算值爲何還能夠依賴另一個computed計算值

小提示:這個問題當時徹底不知道,哎,官方源碼的套路太深了......

這裏但願有大神能夠補充說明一下。

周期函數有哪些(beforeCreatedcreated中間都作了什麼

初始化 datapropscomputedwatcherprovide。官方源碼具體位置src/core/instance/init.js

callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
複製代碼

小結

51信用卡的此次面試其實面試官考察的點仍是蠻深刻的,問了一些Vue底層源碼的實現,整體感受本身回答的還能夠,可是面試官說:你應該去阿里...

阿里部門未知(一面)

說說Webpack的實現原理

小提示:這個直接回答不知道,問題較大,我這裏猜想一下是相似Babel和AST抽象語法樹相關,有空去看下源碼。

這個問題但願同窗能夠補充一下。

首屏優化有哪些解決方案

小提示:這個問題在回答懶加載的過程當中,面試官追問懶加載的Webpack配置,我說了和代碼切割相關。

關於懶加載,這裏推薦一篇很是好的文章:Webpack 大法之 Code Splitting

Node.js的加載機制(requiremodule.exports

小提示:這個問題實際上是很是常見的問題,建議你們閱讀一下源碼,有些也可能會問一下比較簡單的問題,例如module.exportsexports的區別,或者也可能問CommonJS引入和ES6引入的區別。

你以爲你最擅長什麼

小提示:這個問題是個大坑阿,我這裏直接回答我什麼都不擅長,這樣回答顯然面試官是不會不滿意的,建議你們在面試前好好想一想本身到底擅長啥。

React和Vue的區別

小提示:這裏React真的很久沒用了,幾乎忘記了,大體說了下單向數據流、雙向數據綁定、數據監聽方式、JSX以及Vue的單文件組件、函數式編程、Vue的指令之類的。

這個問題但願同時熟悉React和Vue的同窗能夠補充一下。

React、Vue和JQuery在什麼場景下怎麼選型

這個問題但願同窗能夠補充一下。

Vue的響應式原理

什麼狀況下會阻塞DOM渲染

小提示:面試官這裏應該想問DOM渲染的過程當中可能有哪些狀況會阻塞渲染。我當時回答不知道。

這個問題但願同窗能夠補充一下。

有哪些異步函數

小提示:回答了宏任務和微任務。

講講MVVM,說說與MVC有什麼區別

小提示:這個問題我專門發了一篇掘金文章,可是不少人好像都不是很感興趣的樣子,可是面試官真的就問了這樣一個問題。

這裏推薦我以前寫的掘金文章基於Vue實現一個簡易MVVM/MV*設計模式的演變歷史,一開始重點講解了MVC、MVP以及MVVM的演變過程和區別。

阿里CBU技術部(一面)

說說z-index有什麼須要注意的地方

小提示:真的忘記的差很少了,就簡單說了只能在同一層疊上下文中進行z-index值比較、和絕對定位的關係,z-index值不須要設置過大,只須要理清楚層級關係便可。面試官追問了z-index值和background的覆蓋關係,還追問了絕對定位元素以及後來居上的準則。面試官還問了z-index默認值是什麼,0auto有沒有區別?真的對於CSS可能日常就用的很少,因此這個問題答的不是很好。

可能面試官最想知道的是下面這張圖:

enter image description here

這裏附上張鑫旭的文章深刻理解CSS中的層疊上下文和層疊順序

這裏因爲回答了定位,面試官追問固定定位的元素是相對於什麼進行定位?相對定位會脫離正常文檔流麼?絕對定位是相對於什麼元素進行定位?

熟悉CSS3動畫麼

小提示:CSS3動畫硬件加速?CSS3動畫的性能問題(重繪和重流,是否須要脫離正常文檔流)?這個我當時答不知道,確實日常用的不多,若是熟悉Vue過渡動畫的同窗能夠講講過渡動畫?

有沒有作過什麼可視化的項目

小提示:個人回答:地圖算麼?基於OpenLayers設計過地圖的Vue組件庫。

對於可視化但願同窗能夠補充一下。

你以爲你最擅長的是什麼

小提示:這個問題簡直就是給人挖坑。

Flex實現兩列布局

這裏簡單實現一下(其實應該使用flex-basis屬性):

<div class="box">
  <div class="box-left"></div>
  <div class="box-right"></div>
</div>
複製代碼
.box {
  height: 200px;
  display: flex;
}

.box > div {
  height: 100%;
}

.box-left {
  width: 200px;
  background-color: blue;
}

.box-right {
  flex: 1; // 設置flex-grow屬性爲1,默認爲0
  overflow: hidden;
  background-color: red;
}
複製代碼

ES6/ES7/ES8的特性

說說DOM事件流

小提示:面試官追問事件委託有什麼優勢(起碼兩個以上)、target/currentTarget/relateTarget具體指向什麼目標。

你以爲你有作過推進流程或者改善流程的事件麼,舉例說明

小提示:這個若是作過什麼規範或者開發工具之類的,應該比較好回答。

小結

整體來講此次面試面得很細,有些知識點已經忘記,建議你們面試前把一些感受不是很熟悉的原生知識點回憶起來,尤爲是在開發中都不怎麼會使用一些CSS樣式設計的童鞋(如今不少都是組件庫的設計方案,樣式早已經封裝掉了)。

阿里企業智能事業部(一面)

Event Loop

Webpack的loader和plugins的區別

小提示:當時直接回答不知道,確實Webpack我只會用,還沒了解過內部的實現原理和構成。這個後續不管如何都要好好理解一下原理。

這個問題但願同窗能夠補充一下。

HTTP狀態碼206是幹什麼的

小提示:工做中沒有遇到過須要上傳下載大型文件,因此這個問題當時老老實實回答不知道。具體應該和斷點續傳相關,可能也須要回答一些range的頭部信息等。

React高階組件的做用有哪些

小提示:很久沒用過React了,大體只知道Racct是單向數據流的,利用高階組件能夠實現相似於Vue的雙向數據綁定。

這個問題但願同窗能夠補充一下。

React和Vue的區別

Service Worker有哪些做用

小提示:當時怕說錯,老老實實回答不知道。後來查了一下應該和緩存以及HTTP請求攔截相關。

這個問題但願同窗能夠補充一下。

跨域

文件上傳的二進制具體是怎麼處理的

小提示:只知道上傳的頭信息是application/x-www-form-urlencoded,也能夠對上傳的文件的數據進行攔截處理,例如對上傳文件的信息進行加密處理。

這個問題但願同窗能夠補充一下。

Vue響應式原理

首屏加載性能優化

小結

其實這一次面試本身感受面試的不是很好(儘管面試官問的確實比我上面列出的問題多),由於有好幾個問題本身確實不清楚。這裏再次建議你們不知道就是回答不知道,這樣不會對面試官形成一些負面印象。這一次面試可以經過運氣佔了很大一部分。

阿里企業智能事業部(二面)

computed的實現原理

Vue的整個實現原理

小提示:當時面試官問的蠻好玩的,他問從開始寫一個.vue文件開始到DOM渲染到頁面上,Vue作了哪些工做。而後我當時沒理解面試官是要問vue-loader?DOM樹的渲染過程?來來回回試探性的問了面試官幾回,才理解原來面試官想知道Vue源碼的整個實現過程。

你們若是想了解Vue源碼實現的整個粗略過程,能夠看下以前寫的文章基於Vue實現一個簡易MVVM/Vue的運行機制簡述

通信

小提示:因爲這邊涉及到一些海康的設備(上下位機通訊),面試官問我如何知道上位機軟件給下位機設備發送了5次信息。這個其實大部分Web前端開發在工做上很難遇到相似的問題,辛虧我之前畢業設計中作過上下位機的TCP通信。後來我從Leader面那裏瞭解到二面面試官應該是作iot物聯網開發這一塊的。

請求幀數據結構以下:

幀頭 幀序號 幀負載 幀校驗 幀尾
2 Byte 1 Byte N Byte 1 Byte 1 Byte

這裏幀頭使用2字節識別,校驗能夠採用CRC校驗,幀序號用來識別發送了幾回信息。

Chrome插件如何屏蔽廣告

小提示:這個問題當時回答不知道,其實後面想一想最簡單的辦法是先找出廣告元素的一些通用特性,而後在Chrome插件中經過注入腳本的形式將這些廣告元素隱藏掉。

這裏不知道有沒有更好的其餘方式,例如不知道Service Work對請求攔截處理是否能夠有效屏蔽廣告等,這個問題但願同窗能夠補充一下。

如何判斷兩個變量相等

小提示:這裏須要分基本類型和引用類型,面試官在這裏具體想問的是Object.is的實現原理。這是面試官問個人第一個問題,當時直接回答不知道,心裏都以爲接下來要涼涼了。

Watch的運行原理

Vue的數據爲何頻繁變化但只會更新一次

小提示:這裏問的是Vue源碼對於視圖更新的優化。我這裏的回答是亂糟糟的,但願有同窗可以給出一個精準而且簡短的回答。

Vue 異步執行 DOM 更新。只要觀察到數據變化,Vue 將開啓一個隊列,並緩衝在同一事件循環中發生的全部數據改變。若是同一個 watcher 被屢次觸發,只會被推入到隊列中一次。這種在緩衝時去除重複數據對於避免沒必要要的計算和 DOM 操做上很是重要。而後,在下一個的事件循環「tick」中,Vue 刷新隊列並執行實際 (已去重的) 工做。Vue 在內部嘗試對異步隊列使用原生的 Promise.thenMessageChannel,若是執行環境不支持,會採用 setTimeout(fn, 0) 代替。

另外,關於waiting變量,這是很重要的一個標誌位,它保證flushSchedulerQueue回調($nextTick中執行)容許被置入callbacks一次。

由於Vue的事件機制是經過事件隊列來調度執行,會等主進程執行空閒後進行調度,因此先會去等待全部的同步代碼執行完成以後再去一次更新。這樣的性能優點很明顯,好比:

如今有這樣的一種狀況,mounted的時候test的值會被循環執行++1000次。 每次++時,都會根據響應式觸發setter->Dep->Watcher->update->run。 若是這時候沒有異步更新視圖,那麼每次++都會直接操做DOM更新視圖,這是很是消耗性能的。 因此Vue實現了一個queue隊列,在下一個tick(或者是當前tick的微任務階段)統一執行queue中Watcher的run。同時,擁有相同id的Watcher不會被重複加入到該queue中去,因此不會執行1000次Watcher的run。最終更新視圖只會直接將test對的DOM的0變成1000。 保證更新視圖操做DOM的動做是在當前棧執行完之後下一個tick(或者是當前tick的微任務階段)的時候調用,大大優化了性能。

執行順序update -> queueWatcher -> 維護觀察者隊列(重複id的Watcher處理) -> waiting標誌位處理(保證須要更新DOM或者Watcher視圖更新的方法flushSchedulerQueue只會被推入異步執行的$nextTick回調數組一次) -> 處理$nextTick(在爲微任務或者宏任務中異步更新DOM)->

  • Vue是異步更新Dom的,Dom的更新放在下一個宏任務或者當前宏任務的末尾(微任務)中進行執行

因爲VUE的數據驅動視圖更新是異步的,即修改數據的當下,視圖不會馬上更新,而是等同一事件循環中的全部數據變化完成以後,再統一進行視圖更新。在同一事件循環中的數據變化後,DOM完成更新,當即執行nextTick(callback)內的回調。

vue和react同樣,對dom的修改都是異步的。它會在隊列裏記錄你對dom的操做並進行diff操做,後一個操做會覆蓋前一個,而後更新dom。

Event Loop

除了Flex還能夠用什麼進行佈局

小提示:我猜這裏面試官想問的是Grid,當時說不知道。

絕對定位、固定定位和z-index

小提示:感謝CBU技術部的面試官。

絕對定位

  • 一旦給元素加上absolutefloat就至關於給元素加上了display:block
  • absolute元素覆蓋正常文檔流內元素(不用設z-index,天然覆蓋)
  • 能夠減小重繪和迴流的開銷(如absolute+ top:-9999em,或absolute + visibility:hidden,將動畫效果放到absolute元素中)

屬性介紹

  • static,默認值。位置設置爲static的元素,它始終會處於文檔流給予的位置。
  • inherit,規定應該從父元素繼承 position 屬性的值。可是任何的版本的 Internet Explorer (包括 IE8)都不支持屬性值 「inherit」。
  • fixed,生成絕對定位的元素。默認狀況下,可定位於相對於瀏覽器窗口的指定座標。元素的位置經過 「left」, 「top」, 「right」 以及 「bottom」 屬性進行規定。不論窗口滾動與否,元素都會留在那個位置。但當祖先元素具備transform屬性且不爲none時,就會相對於祖先元素指定座標,而不是瀏覽器窗口。
  • absolute,生成絕對定位的元素,相對於距該元素最近的已定位的祖先元素進行定位。此元素的位置可經過 「left」、」top」、」right」 以及 「bottom」 屬性來規定。
  • relative,生成相對定位的元素,相對於該元素在文檔中的初始位置進行定位。經過 「left」、」top」、」right」 以及 「bottom」 屬性來設置此元素相對於自身位置的偏移。

浮動、絕對定位和固定定位會脫離文檔流,相對定位不會脫離文檔流,絕對定位相對於該元素最近的已定位的祖先元素,若是沒有一個祖先元素設置定位,那麼參照物是body層。

絕對定位相對於包含塊的起始位置:

  • 若是祖先元素是塊級元素,包含塊則設置爲該元素的內邊距邊界。
  • 若是祖先元素是行內元素,包含塊則設置爲該祖先元素的內容邊界。

問答題:

  • 定位的元素的起始位置爲父包含塊的內邊距(不會在border裏,除非使用負值,會在padding裏)
  • 定位的元素的margin仍是能起做用的
  • background屬性是會顯示在border裏的
  • z-index是有層疊層級的,須要考慮同一個層疊上下文的層疊優先級
  • z-index是負值不會覆蓋包含塊的背景色(可是若是有內容,會被包含塊的內容覆蓋)
  • z-index的值影響的元素是定位元素以及flex盒子
  • 上面一個定位元素,下面一個正常流的元素,定位元素會覆蓋在正常流元素之上,除非給z-index是負值
  • 頁面根元素html天生具備層疊上下文,稱之爲「根層疊上下文」

小結

這一次面試官問個人第一個問題Object.is就沒答上來,不過面試官顯然沒有由於開頭答的很差就否認面試者。你們若是在面試時第一個問題就答不上來,不要慌,要保持良好的心態,把接下來能答的問題好好答上來。可能不少同窗會疑問,好像還有好幾個問題感受沒答上來,可是可能只要有一個問題答的很是出彩,仍然能夠彌補那些沒答上來的問題(這裏面試官當時說Vue源碼的實現過程我說的比較清楚,尚未一個面試者答的比我更清楚的)。

阿里企業智能事業部(Leader面)

三面是Leader現場面,我當時特別擔憂有贊二面的狀況發生,冷不丁又給你來一道算法題,這些真是我最不擅長的點。由於有點心虛我就問了下在阿里的師兄(師兄可能也作招聘工做,當時還怪我沒有找他內推...),他說現場面其實最主要的是好好準備簡歷上的內容,面試官通常都會根據簡歷進行問答,還說他當時面試阿里時會讓他畫一些框架層次圖(這個我當時沒在乎,結果面試官確實讓我根據其中某個項目畫一個框架層次圖)。Leader面的時候在場的有兩個面試官和一個HR。

Leader(一)面試

先是進來一個氣場很足的Leader,看起來很權威,可是問問題還蠻隨意的,就簡單的讓我介紹一下本身作的項目,而後翻看了我作的一些東西。感受他好像有點心不在焉,翻看的很隨意,我在回答問題的時候用餘光關注了一下大佬的表情,感受他在我項目經歷那一塊停留了很是長的時間。

Leader(二)面試

我正回答着本身的項目經歷,Leader二和HR進來了,等我回答完Leader一就讓Leader二開始面我。Leader二就問了我其中的兩個項目。問個人第一個項目是本身作的公司內部的工具,他問這個平臺有什麼能夠衡量的數據代表公司內部人員的使用狀況。我回答當時由於領導以爲不必作,就沒有作數據統計這一塊,告訴了他數據庫裏的一些真實數據狀況。而後他問PV、UV應該怎麼統計(我當時還厚臉皮的問他PV和UV是什麼)?若是訪問的頁面出不來PV怎麼統計?頁面有沒有作什麼行爲監測?頁面訪問量過大怎麼處理?我大體講了一些個人思路。

接着問我第二個項目(Low Code相關),我就回答了這個項目的技術體系,從之前作了什麼到如今作到什麼程度,到將來須要作成什麼樣,通通仔細的說了一遍。Leader二就問我將來作成什麼樣能不能思考一下怎麼作,給了我5分鐘的時間(這期間他一直反覆的在翻閱個人簡歷)。而後我就僞裝思考了5分鐘左右,其實腦子裏一片空白,當時對於將來要作成什麼樣還只是個構思。而後Leader二仍是很體貼的,他說你能夠在牆上畫一畫(牆上能夠寫字),我就大體畫了畫,Leader二問我能不能畫一畫這個項目的框架層次圖,我就簡單的畫了畫...最後Leader二直接說大家作的太Low了,這個(Low Code)在咱們這裏已是兩年前的技術了...(這個我仍是要解釋下,我所在的部門從開始用Vue到目前只有短短的兩年時間,在這兩年時間裏技術體系仍是飛速的在沉澱和發展,我離開以前已經構思並實現了部分Vue技術棧的Low Code解決方案,若是這方面感興趣的同窗也能夠找我溝通)。

Leader二還蠻好玩的,他說Low Code若是真的作出來了,都沒前端什麼事情了,那你幹嗎去?順着這個問題他還問我將來的前端應該怎麼發展?將來前端有哪些能夠挖掘的點?我回答了一些Graphql、可視化等,我還說了一個特別搞笑的回答,我說從以往的發展來看,前端應該搶佔後端的資源,把後端限制咱們的事情讓前端也能作,讓前端更加解放。Leader二當場就進行了反駁,說是要有價值才作,而不是爲了能作而作,嚇得我不輕...而後Leader二還詳細的跟我解釋了將來發展這個問題他但願獲得什麼回答,當時仍是以爲Leader二蠻親切的。

HR面試

Leader二問完之後HR就接着問我瞭如下幾個問題:

  • 爲何要離開如今的公司
  • 之前公司的崗位制度是什麼樣
  • 你是校招進去的麼
  • 你如今的崗位等級狀況
  • 你的績效狀況
  • 你領導對你的評價是怎麼樣的
  • 領導是否是常常找你溝通

而後Leader一順着HR問了一個小問題:

  • 你將來對於你的職業有什麼規劃

最後問我還有什麼想問的,我當時已經被三我的問的有點迷迷糊糊了,而後想了想說沒有。

小結

此次現場面其實我感受本身面得不是很好,總感受本身要掛了。總共面了將近1個半小時左右,尤爲是Leader二的問題不少不是他想要的答案,可是最終竟然過了。

阿里企業智能事業部(HR面)

企業智能事業部Leader面後又收到了HR面的面試通知,這一輪面試大體問了如下問題:

  • 你爲何要離開如今的公司
  • 大家公司的崗位等級是怎麼評定的,你如今是什麼崗位等級
  • 談談你在公司的績效狀況
  • 你以爲你作的最有成就感的一件事
  • 你通常解決問題的方法有哪些
  • 你是由於什麼契機選擇作前端
  • 你有對你所在的公司作過什麼流程或制度規範上的改進麼
  • 你最近在看什麼書,和工做相關麼,你爲何要看這些書
  • 看到你以前還面試了其餘兩個部門都掛在了一面,你感受是什麼緣由
  • 你指望的薪資待遇是多少

小提示:這裏HR會問的其實不止這些問題,例如你爲何喜歡Web前端這個崗位、你將來的職業規劃、你以爲你的優勢和缺點有哪些、爲何選擇阿里巴巴、對以前幾個面試官作下評價、你用過阿里的哪些產品順便談談這些產品的優缺點、你對於互聯網是怎麼理解的...

小結

對於HR面仍是要好好準備的,尤爲是有些問題仍是很容易挖坑的,例如你爲何離開如今的公司(你固然不該該抱怨如今的公司有哪些很差的地方,更多的應該代表本身想要尋找更好的發展機會,本身的一些現實因素,好比對於我而言是如今應聘的公司離本身的家更近,又或者是本身工做到達了迷茫期,想跳出迷茫期等等),你以爲你作的最有成就感的一件事(你要是說個簡單的,HR會以爲你工做能力不強),你通常解決問題的方法有哪些(HR固然也想考察你解決問題的能力,你要是說什麼百度啊之類的HR固然會以爲你解決問題的能力不強),你指望的薪資待遇是多少(你要是不喜歡這家公司,能夠指望高一些,你要是很喜歡這家公司面試過程很愉快上浮個30%左右,面試過程通常上浮個20%左右)。

相關文章
相關標籤/搜索