(乾貨)記前端工程師面試題,一塊兒帶你們理一理

此文是上篇 如何拿到大廠offer面試題|技術徵文 下,更新下剩下題目及答題思路javascript

1.請簡單描述http協議的請求報文和響應報文的組成格式?

HTTP請求報文css

一個HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求數據4個部分組成,下圖給出了請求報文的通常格式。html

英文:前端

<request-line>

<headers>

<blank line>

<request-body>
java

1.請求頭ios

請求行由請求方法字段、URL字段和HTTP協議版本字段3個字段組成,它們用空格分隔。例如,GET /index.html HTTP/1.1。程序員

HTTP協議的請求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。web

2.請求頭部面試

請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號「:」分隔。請求頭部通知服務器有關於客戶端請求的信息,典型的請求頭有:數據庫

User-Agent:產生請求的瀏覽器類型。

Accept:客戶端可識別的內容類型列表。

Host:請求的主機名,容許多個域名同處一個IP地址,即虛擬主機。

3.空行

最後一個請求頭以後是一個空行,發送回車符和換行符,通知服務器如下再也不有請求頭。

4.請求數據

請求數據不在GET方法中使用,而是在POST方法中使用。POST方法適用於須要客戶填寫表單的場合。與請求數據相關的最常使用的請求頭是Content-Type和Content-Length。

HTTP報文

HTTP響應也由三個部分組成,分別是:狀態行、消息報頭、響應正文。

以下所示,HTTP響應的格式與請求的格式十分相似:

英文:

<status-line>

<headers>

<blank line>

<response-body>

正如你所見,在響應中惟一真正的區別在於第一行中用狀態信息代替了請求信息。狀態行(status line)經過提供一個狀態碼來講明所請求的資源狀況。

狀態行格式以下:

HTTP-Version Status-Code Reason-Phrase CRLF

其中,HTTP-Version表示服務器HTTP協議的版本;Status-Code表示服務器發回的響應狀態代碼;Reason-Phrase表示狀態代碼的文本描述。狀態代碼由三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。

  • 1xx:指示信息--表示請求已接收,繼續處理。
  • 2xx:成功--表示請求已被成功接收、理解、接受。
  • 3xx:重定向--要完成請求必須進行更進一步的操做。
  • 4xx:客戶端錯誤--請求有語法錯誤或請求沒法實現。
  • 5xx:服務器端錯誤--服務器未能實現合法的請求。

常見狀態代碼、狀態描述的說明以下。

  • 200 OK:客戶端請求成功。
  • 400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解。
  • 401 Unauthorized:請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用。
  • 403 Forbidden:服務器收到請求,可是拒絕提供服務。
  • 404 Not Found:請求資源不存在,舉個例子:輸入了錯誤的URL。
  • 500 Internal Server  Error:服務器發生不可預期的錯誤。
  • 503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間後可能恢復正常,舉個例子:HTTP/1.1 200 OK(CRLF)。

詳情能夠參考該博客

2.用三種方式實現塊框的垂直劇中效果,假設框的高度根據內容自適應

注意兼容性,autoprefixer能夠處理前綴的兼容而已,對於不支持transform和flex的瀏覽器,若是要兼容該部分瀏覽器,請選擇其餘方式(筆者作的大可能是移動端,如下三種,除安卓4.3如下原生內核不支持外,並外見兼容性的bug,flex在X5內核,ios低版本內核中有些兼容性(如flex-wrap),需注意)。

第一種:flex

父元素設置如下屬性
display:flex;
flex-direction:row //web 默認的值,rn默認column
align-items:center複製代碼

第二種:absolute

父元素設置
position:relative
本元素
position:absolute;
top:50%;
transform:translateY(-50%);
複製代碼

第三種:利用display:table-cell屬性

display:table-cell;
vertical-alian:middle;複製代碼

。。。還有不少

3.http中的狀態碼302表明的是什麼意思

302重定向表示臨時性轉移(Temporarily Moved ),當一個網頁URL須要短時間變化時使用。

順便提一嘴301

301重定向/跳轉通常,表示本網頁永久性轉移到另外一個地址。

301是永久性轉移(Permanently Moved),SEO經常使用的招式,會把舊頁面的PR等信息轉移到新頁面

301重定向與302重定向的區別

301重定向是永久的重定向,搜索引擎在抓取新內容的同時也將舊的網址替換爲重定向以後的網址。

302重定向是臨時的重定向,搜索引擎會抓取新的內容而保留舊的網址。由於服務器返回302代碼,搜索引擎認爲新的網址只是暫時的。

4.cookie是什麼,和session有什麼區別

1,session 在服務器端,cookie 在客戶端(瀏覽器)

2,session 默認被存在在服務器的一個文件裏(不是內存)

3,session 的運行依賴 session id,而 session id 是存在 cookie 中的,也就是說,若是瀏覽

器禁用了 cookie ,同時 session 也會失效(可是能夠經過其它方式實現,好比在 url 中傳遞 

session_id)

4,session 能夠放在 文件、數據庫、或內存中均可以。

5,用戶驗證這種場合通常會用 session

所以,維持一個會話的核心就是客戶端的惟一標識,即 session id

5.有那些dom接口能夠獲取一個元素的尺寸(寬度和高度)

假設該元素id爲box

1.第一種經過內聯樣式(注意:css聲明中沒有設置hieght和width的話是獲取不到的,並且也不會根據box-sizing的值而返回不一樣盒子模型的寬高)

var box = document.getElementById('box');
    var w = box.style.width;
    var h = box.style.height;複製代碼

2.經過計算元素的大小(可是在ie狀況下有一個問題,那就沒寫widht和height的css就返回auto,getComputedStyle在IE下若是設置了寬高爲em這種單位,返回來的值依然是em,而不會是px);

var style = window.getComputedStyle ? window.getComputedStyle(box,null) : null || box.currentStyle;
    var w = style.width;
    var h = style.height;複製代碼


3.offsetHeight和offsetHeight

4.getBoundingClientRect(IE67的left、top會少2px,而且沒有width、height屬性,需兼容該部分瀏覽器的,那就不得不選擇放棄了)DOMRect 對象包含了一組用於描述邊框的只讀屬性——left、top、right和bottom,單位爲像素。除了 width 和 height 外的屬性都是相對於視口的左上角位置而言的

。。。

6.請描述dom事件的流程,即從觸發到結束的整個過程

事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。首先發生的是事件捕獲,

爲截獲事件提供了機會。而後是實際的目標接收到事件。最後一個階段是冒泡階 段,能夠在這

個階段對事件作出響應。 單擊<div>元素會按照以下圖:

DOM 事件流中,實際的目標(<div>元素)在捕獲階段不會接收到事件。這意味着在捕獲階段, 

12 事件從 document 到<html>再到<body>後就中止了。下一個階段是「處於目標」階段,因而

事件在<div> 上發生,並在事件處理(後面將會討論這個概念)中被當作冒泡階段的一部分。然

後,冒泡階段發生, 事件又傳播迴文檔。 

多數支持 DOM 事件流的瀏覽器都實現了一種特定的行爲;即便「DOM2 級事件」規範明確要求

捕獲階段不會涉及事件目標,但 IE九、Safari、Chrome、Firefox 和 Opera 9.5 及更高版本都

會在捕獲階段觸 發事件對象上的事件。結果,就是有兩個機會在目標對象上面操做事件。 

以上是高程的內容。

7.請描述utf-8和unicode的區別

  • Unicode 是「字符集」
  • UTF-8 是「編碼規則」

Unicode是一套複雜的字符編碼標準,簡單來講就是將人類使用的每一個所謂字符與一個非負整數對應,而且保證不一樣的字符對應的整數必定不一樣。UTF-8是這個整數的編碼方式,用1到4字節來表達一個整數。

關係:UTF-8是Unicode的實現方式之一,它規定了字符如何在計算機中存儲、傳輸等。

8.講一講你在平常web開發中加載和交互體驗上經常使用的優化策略

1. 減小HTTP請求數

這條策略基本上全部前端人都知道,並且也是最重要最有效的。都說要減小HTTP請求,那請求多了到底會怎麼樣呢?首先,每一個請求都是有成本的,既包 含時間成本也包含資源成本。一個完整的請求都須要通過DNS尋址、與服務器創建鏈接、發送數據、等待服務器響應、接收數據這樣一個「漫長」而複雜的過程。 時間成本就是用戶須要看到或者「感覺」到這個資源是必需要等待這個過程結束的,資源上因爲每一個請求都須要攜帶數據,所以每一個請求都須要佔用帶寬。

另外,因爲瀏覽器進行併發請求的請求數是有上限的,所以請求數多了之後,瀏覽器須要分批進行請求,所以會增長用戶的等待時間,會給 用戶形成站點速度慢這樣一個印象,即便可能用戶能看到的第一屏的資源都已經請求完了,可是瀏覽器的進度條會一直存在。減小HTTP請求數的主要途徑包括:

(1). 從設計實現層面簡化頁面

若是你的頁面像百度首頁同樣簡單,那麼接下來的規則基本上都用不着了。保持頁面簡潔、減小資源的使用時最直接的。若是不是這樣,你的頁面須要華麗的皮膚,則繼續閱讀下面的內容。

(2). 合理設置HTTP緩存

緩存的力量是強大的,恰當的緩存設置能夠大大的減小HTTP請求。以有啊首頁爲例,當瀏覽器沒有緩存的時候訪問一共會發出78個請求,共600多K 數據(如圖1.1),而當第二次訪問即瀏覽器已緩存以後訪問則僅有10個請求,共20多K數據(如圖1.2)。(這裏須要說明的是,若是直接F5刷新頁面 的話效果是不同的,這種狀況下請求數仍是同樣,不過被緩存資源的請求服務器是304響應,只有Header沒有Body,能夠節省帶寬)

怎樣纔算合理設置?原則很簡單,能緩存越多越好,能緩存越久越好。例如,不多變化的圖片資源能夠直接經過HTTP Header中的Expires設置一個很長的過時頭;變化不頻繁而又可能會變的資源可使用Last-Modifed來作請求驗證。儘量的讓資源可以 在緩存中待得更久。

(3). 資源合併與壓縮

若是能夠的話,儘量的將外部的腳本、樣式進行合併,多個合爲一個。另外,CSS、Javascript、Image均可以用相應的工具進行壓縮,壓縮後每每能省下很多空間。

(4). CSS Sprites

合併CSS圖片,減小請求數的又一個好辦法。

(5). Inline Images

使用data: URL scheme的方式將圖片嵌入到頁面或CSS中,若是不考慮資源管理上的問題的話,不失爲一個好辦法。若是是嵌入頁面的話換來的是增大了頁面的體積,並且沒法利用瀏覽器緩存。使用在CSS中的圖片則更爲理想一些。

(6). Lazy Load Images

這條策略實際上並不必定能減小HTTP請求數,可是卻能在某些條件下或者頁面剛加載時減小HTTP請求數。對於圖片而言,在頁面剛加載的時候能夠只 加載第一屏,當用戶繼續日後滾屏的時候才加載後續的圖片。這樣一來,假如用戶只對第一屏的內容感興趣時,那剩餘的圖片請求就都節省了。有啊首頁曾經的作法 是在加載的時候把第一屏以後的圖片地址緩存在Textarea標籤中,待用戶往下滾屏的時候才「惰性」加載。

2. 將外部腳本置底

前文有談到,瀏覽器是能夠併發請求的,這一特色使得其可以更快的加載資源,然而外鏈腳本在加載時卻會阻塞其餘資源,例如在腳本加載完成以前,它後面 的圖片、樣式以及其餘腳本都處於阻塞狀態,直到腳本加載完成後纔會開始加載。若是將腳本放在比較靠前的位置,則會影響整個頁面的加載速度從而影響用戶體 驗。解決這一問題的方法有不少,而最簡單可依賴的方法就是將腳本儘量的日後挪,減小對併發下載的 影響。

3. 異步執行inline腳本

inline腳本對性能的影響與外部腳本相比,是有過之而無不及。首頁,與外部腳本同樣,inline腳本在執行的時候同樣會阻塞併發請求,除此之 外,因爲瀏覽器在頁面處理方面是單線程的,當inline腳本在頁面渲染以前執行時,頁面的渲染工做則會被推遲。簡而言之,inline腳本在執行的時 候,頁面處於空白狀態。鑑於以上兩點緣由,建議將執行時間較長的inline腳本異步執行,異步的方式有不少種,例如使用script元素的defer屬 性(存在兼容性問題和其餘一些問題,例如不能使用document.write)、使用setTimeout,此外,在HTML5中引入了Web Workers的機制,偏偏能夠解決此類問題。

4. Lazy Load Javascript

隨着Javascript框架的流行,愈來愈多的站點也使用起了框架。不過,一個框架每每包括了不少的功能實現,這些功能並非每個頁面都須要 的,若是下載了不須要的腳本則算得上是一種資源浪費-既浪費了帶寬又浪費了執行花費的時間。目前的作法大概有兩種,一種是爲那些流量特別大的頁面專門定製 一個專用的mini版框架,另外一種則是Lazy Load。YUI則使用了第二種方式,在YUI的實現中,最初只加載核心模塊,其餘模塊能夠等到須要使用的時候才加載。

5. 將CSS放在HEAD中

若是將CSS放在其餘地方好比BODY中,則瀏覽器有可能還未下載和解析到CSS就已經開始渲染頁面了,這就致使頁面由無CSS狀態跳轉到CSS狀 態,用戶體驗比較糟糕。除此以外,有些瀏覽器會在CSS下載完成後纔開始渲染頁面,若是CSS放在靠下的位置則會致使瀏覽器將渲染時間推遲。

6. 減小沒必要要的HTTP跳轉

對於以目錄形式訪問的HTTP連接,不少人都會忽略連接最後是否帶’/',假如你的服務器對此是區別對待的話,那麼你也須要注意,這其中極可能隱藏了301跳轉,增長了多餘請求。具體參見下圖,其中第一個連接是以無’/'結尾的方式訪問的,因而服務器有了一次跳轉。

7. 避免重複的資源請求

這種狀況主要是因爲疏忽或頁面由多個模塊拼接而成,而後每一個模塊中請求了一樣的資源時,會致使資源的重複請求。出現的概率不大,可是仍是要注意排查。

。。。

9.什麼是CSRF攻擊,如何預防

CSRF全程 Cross Site Request Forgery, 跨站域請求僞造.CSRF是一種夾持用戶在已經登錄的web應用程序上執行非本意的操做的攻擊方式。相比於XSS,CSRF是利用了系統對頁面瀏覽器的信任,XSS則利用了系統對用戶的信任。

防護CSRF攻擊:

目前防護 CSRF 攻擊主要有三種策略:驗證 HTTP Referer 字段;在請求地址中添加 token 並驗證;在 HTTP 頭中自定義屬性並驗證。

(1)驗證 HTTP Referer 字段

根據 HTTP 協議,在 HTTP 頭中有一個字段叫 Referer,它記錄了該 HTTP 請求的來源地址。在一般狀況下,訪問一個安全受限頁面的請求來自於同一個網站,好比須要訪問 http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory,用戶必須先登錄 bank.example,而後經過點擊頁面上的按鈕來觸發轉帳事件。這時,該轉賬請求的 Referer 值就會是轉帳按鈕所在的頁面的 URL,一般是以 bank.example 域名開頭的地址。而若是黑客要對銀行網站實施 CSRF 攻擊,他只能在他本身的網站構造請求,當用戶經過黑客的網站發送請求到銀行時,該請求的 Referer 是指向黑客本身的網站。所以,要防護 CSRF 攻擊,銀行網站只須要對於每個轉帳請求驗證其 Referer 值,若是是以 bank.example 開頭的域名,則說明該請求是來自銀行網站本身的請求,是合法的。若是 Referer 是其餘網站的話,則有多是黑客的 CSRF 攻擊,拒絕該請求。

這種方法的顯而易見的好處就是簡單易行,網站的普通開發人員不須要操心 CSRF 的漏洞,只須要在最後給全部安全敏感的請求統一增長一個攔截器來檢查 Referer 的值就能夠。特別是對於當前現有的系統,不須要改變當前系統的任何已有代碼和邏輯,沒有風險,很是便捷。

然而,這種方法並不是萬無一失。Referer 的值是由瀏覽器提供的,雖然 HTTP 協議上有明確的要求,可是每一個瀏覽器對於 Referer 的具體實現可能有差異,並不能保證瀏覽器自身沒有安全漏洞。使用驗證 Referer 值的方法,就是把安全性都依賴於第三方(即瀏覽器)來保障,從理論上來說,這樣並不安全。事實上,對於某些瀏覽器,好比 IE6 或 FF2,目前已經有一些方法能夠篡改 Referer 值。若是 bank.example 網站支持 IE6 瀏覽器,黑客徹底能夠把用戶瀏覽器的 Referer 值設爲以 bank.example 域名開頭的地址,這樣就能夠經過驗證,從而進行 CSRF 攻擊。

即使是使用最新的瀏覽器,黑客沒法篡改 Referer 值,這種方法仍然有問題。由於 Referer 值會記錄下用戶的訪問來源,有些用戶認爲這樣會侵犯到他們本身的隱私權,特別是有些組織擔憂 Referer 值會把組織內網中的某些信息泄露到外網中。所以,用戶本身能夠設置瀏覽器使其在發送請求時再也不提供 Referer。當他們正常訪問銀行網站時,網站會由於請求沒有 Referer 值而認爲是 CSRF 攻擊,拒絕合法用戶的訪問。

(2)在請求地址中添加 token 並驗證

CSRF 攻擊之因此可以成功,是由於黑客能夠徹底僞造用戶的請求,該請求中全部的用戶驗證信息都是存在於 cookie 中,所以黑客能夠在不知道這些驗證信息的狀況下直接利用用戶本身的 cookie 來經過安全驗證。要抵禦 CSRF,關鍵在於在請求中放入黑客所不能僞造的信息,而且該信息不存在於 cookie 之中。能夠在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端創建一個攔截器來驗證這個 token,若是請求中沒有 token 或者 token 內容不正確,則認爲多是 CSRF 攻擊而拒絕該請求。

這種方法要比檢查 Referer 要安全一些,token 能夠在用戶登錄後產生並放於 session 之中,而後在每次請求時把 token 從 session 中拿出,與請求中的 token 進行比對,但這種方法的難點在於如何把 token 以參數的形式加入請求。對於 GET 請求,token 將附在請求地址以後,這樣 URL 就變成 http://url?csrftoken=tokenvalue。 而對於 POST 請求來講,要在 form 的最後加上 <input type=」hidden」 name=」csrftoken」 value=」tokenvalue」/>,這樣就把 token 以參數的形式加入請求了。可是,在一個網站中,能夠接受請求的地方很是多,要對於每個請求都加上 token 是很麻煩的,而且很容易漏掉,一般使用的方法就是在每次頁面加載時,使用 javascript 遍歷整個 dom 樹,對於 dom 中全部的 a 和 form 標籤後加入 token。這樣能夠解決大部分的請求,可是對於在頁面加載以後動態生成的 html 代碼,這種方法就沒有做用,還須要程序員在編碼時手動添加 token。

該方法還有一個缺點是難以保證 token 自己的安全。特別是在一些論壇之類支持用戶本身發表內容的網站,黑客能夠在上面發佈本身我的網站的地址。因爲系統也會在這個地址後面加上 token,黑客能夠在本身的網站上獲得這個 token,並立刻就能夠發動 CSRF 攻擊。爲了不這一點,系統能夠在添加 token 的時候增長一個判斷,若是這個連接是鏈到本身本站的,就在後面添加 token,若是是通向外網則不加。不過,即便這個 csrftoken 不以參數的形式附加在請求之中,黑客的網站也一樣能夠經過 Referer 來獲得這個 token 值以發動 CSRF 攻擊。這也是一些用戶喜歡手動關閉瀏覽器 Referer 功能的緣由。

(3)在 HTTP 頭中自定義屬性並驗證

這種方法也是使用 token 並進行驗證,和上一種方法不一樣的是,這裏並非把 token 以參數的形式置於 HTTP 請求之中,而是把它放到 HTTP 頭中自定義的屬性裏。經過 XMLHttpRequest 這個類,能夠一次性給全部該類請求加上 csrftoken 這個 HTTP 頭屬性,並把 token 值放入其中。這樣解決了上種方法在請求中加入 token 的不便,同時,經過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄,也不用擔憂 token 會透過 Referer 泄露到其餘網站中去。

然而這種方法的侷限性很是大。XMLHttpRequest 請求一般用於 Ajax 方法中對於頁面局部的異步刷新,並不是全部的請求都適合用這個類來發起,並且經過該類請求獲得的頁面不能被瀏覽器所記錄下,從而進行前進,後退,刷新,收藏等操做,給用戶帶來不便。另外,對於沒有進行 CSRF 防禦的遺留系統來講,要採用這種方法來進行防禦,要把全部請求都改成 XMLHttpRequest 請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的。

10.script標籤到defer和async屬性有什麼做用和區別

async屬性,表示後續文檔的加載和渲染與js腳本的加載和執行是並行進行的,即異步執行。

defer屬性,加載後續文檔的過程和js腳本的加載(此時僅加載不執行)是並行進行的(異步),js腳本的執行須要等到文檔全部元素解析完成以後,DOMContentLoaded事件觸發執行以前。

區別

  1.defer和async在網絡加載過程是一致的,都是異步執行的;

  2.二者的區別在於腳本加載完成以後什麼時候執行,defer更符合大多數場景對應用腳本加載和執行的要求;

  3.若是存在多個有defer屬性的腳本,那麼它們是按照加載順序執行腳本的;而對於async,它的加載和執行是牢牢挨着的,不管聲明順序如何,只要加載完成就馬上執行,它對於應用腳本用處不大,由於它徹底不考慮依賴。

相關文章
相關標籤/搜索