noah的前端面試題(一)|掘金技術徵文

麻醬愛我發表於2018-04-05

這段時間面試了一些公司然後我也整理一些面試題目供給大家參考一下,一些基本的題目就不分享出來了,還有一些手寫的題目,另加一些我附加連結防止我表達的不夠清晰詳細。 

下一篇 前端面試題(二)

1. 談一下css盒模型 如何觸發 他是解決什麼樣子的問題

這個是老生常談的題目了

1)BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此 2) 內部的Box會在垂直方向,一個接一個地放置 3)屬於同一個BFC的兩個相鄰Box的 margin會發生重疊  4)BFC的區域不會與float box重疊 主要是這四個也沒比較每個都說的很清晰 最主要的是第一個 

那些元素生成BFC

  1. 根元素
  2. float屬性不為none
  3. position為absolute或fixed
  4. display為inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不為visible

主要的解決是一些圖形文字環繞效果和避免子元素的浮動脫離文件流而造成的高度坍塌的問題


2. 說一下你瞭解的彈性FLEX佈局

各種概念和屬效能想到大家都可以說一下,也扯到了Grid佈局,基本這個也沒啥問題。

分享一篇flex佈局很詳細的 Flex 佈局教程


3. css前處理器有哪些 你用了那個 可以詳細說一下其中特性嗎

平時我在開發中主要使用的是 Less,所以可能對 Sass 和 Stylus 的熟悉程度稍差一些

可以 基本語法 巢狀語法 變數 @import 混入 繼承 函式 邏輯控制 這些來說說 同時我給大家分享一篇文章 再談 CSS 前處理器


4. 談一談移動端適配的問題

之前的公司是用rem佈局 同時我也談到淘寶的flexible.js用來適配的,vh佈局一些東西。被問到用rem佈局有什麼缺點時候 我想了想說 我覺得很完美


5. 談談你們用的ui庫和一些css類庫


6. js中call apply bind的用法和其中之間的區別

他們三個都是為了動態改變某個函式執行時的上下文(context)或者是為了改變函式體內部this的指向  

apply()與call()作用沒有區別,用法與call()方法稍有區別,就是call()的第二個引數(呼叫函式使用的引數),是一個一個傳入的

bind()的作用其實與call()以及apply()都是一樣的,都是為了改變函式執行時的上下文,bind()與後面兩者的區別是,call()和apply()在呼叫函式之後會立即執行,而bind()方法呼叫並改變函式執行時的上下文的之後,返回一個新的函式,在我們需要呼叫的地方去呼叫他。

如果大家能夠理解這個題目那麼這三個用法也會了解很清晰了 cat.call(dog, a, b) = cat.apply(dog, [a, b]) = (cat.bind(dog, a, b))() = dog.cat(a, b)


7. 談一談你對this的理解 箭頭函式內部的this是指向哪裡的

this的指向在函式定義的時候是確定不了的,只有函式執行的時候才能確定this到底指向誰,實際上this的最終指向的是那個呼叫它的物件,也就是說 this是和上下文有關係,誰呼叫了他,他就指向誰。

箭頭函式內部的this是詞法作用域應該繼承的是父執行上下文裡面的this,切忌是父執行上下文 這樣就很多箭頭函式中的指向不明確就迎刃而解了。注意:簡單物件(非函式)是沒有執行上下文的 還有箭頭函式call apply等方法會失效 也不能使用 let that = this 的hack寫法


8. es6一些新的語法 

大家可以看一看阮一峰老師的 ECMAScript 6 入門 隨便抽幾點來說


9. 如何用es6進行陣列的複製

擴充套件運算子提供了複製陣列的簡便寫法 

const a1 = [1, 2]; const a2 = [...a1]; const [...a2] = a1;


10. 如何用es6進行陣列去重,然後用es5實現的幾種方法 談談你的思路

es6 陣列 set可以用來實現陣列去重

es5 裡面可以用物件key值唯一的方式來實現 和 陣列indexof方式 


11.  es6 es7有哪些方法實現函式的非同步操作 es6之前呢是如何實現的

promise, async await , generator。

es6之前通過回撥函式來實現的


12. 手寫原聲ajax get請求程式碼 ,在裡面設定同步非同步是在那個方法裡面 ,get 和 post 區別

function get(){  
    var req = createXMLHTTPRequest();  
    if(req){  
        req.open("GET", url , true);  
        req.onreadystatechange = function(){  
            if(req.readyState == 4){  
                if(req.status == 200){  
                    alert("success");  
                }else{  
                    alert("error");  
                }  
            }  
        }  
        req.send(null);  
    }  
}  複製程式碼


XMLHttpRequest.open(method, url, async);一個可選的布林引數,預設為true,表示要不要非同步執行操作。如果值為falsesend()方法直到收到答覆前不會返回。如果true,已完成事務的通知可供事件監聽器使用。如果multipart屬性為true則這個必須為true,否則將引發異常。

HTTP POST GET 本質區別詳解

13. HTTP請求報文和HTTP響應報文  

1.請求行
請求行由請求方法欄位、URL欄位和HTTP協議版本欄位3個欄位組成,它們用空格分隔。例如,GET /index.html HTTP/1.1。
HTTP協議的請求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
HEAD就像GET,只不過服務端接受到HEAD請求後只返回響應頭,而不會傳送響應內容。當我們只需要檢視某個頁面的狀態的時候,使用HEAD是非常高效的,因為在傳輸的過程中省去了頁面內容。
列子:
Request URL:https://www.baidu.com/
Request Method:GET
Status Code:200 OK
Remote Address:172.31.1.246:8080
2.請求頭部
請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知伺服器有關於客戶端請求的資訊,典型的請求頭有:
User-Agent:產生請求的瀏覽器型別。
Accept:客戶端可識別的內容型別列表。
Host:請求的主機名,允許多個域名同處一個IP地址,即虛擬主機。
列子:
Cache-Control:private, max-age=10
Connection:Keep-Alive
Content-Encoding:gzip
Content-Type:text/html; charset=utf-8
Date:Tue, 21 Feb 2017 03:05:37 GMT
Expires:Tue, 21 Feb 2017 03:05:47 GMT
Last-Modified:Tue, 21 Feb 2017 03:05:37 GMT
Proxy-Connection:Keep-Alive
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-UA-Compatible:IE=10
3.空行
最後一個請求頭之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有請求頭。
4.請求資料

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


HTTP響應也由三個部分組成,分別是:狀態行、訊息報頭、響應正文 在響應中唯一真正的區別在於第一行中用狀態資訊代替了請求資訊。狀態行通過提供一個狀態碼來說明所請求的資源情況。


13. http狀態碼 說一下200和304的理解和區別

協商快取和強制快取的區別,流程,還有一些細節,提到了expires,Cache-Control,If-none-match,Etag,last-Modified的匹配和特徵 還有同時有Etag,last-Modified同時出現的時候 etag(包括檔案修改時間 檔案大小 檔案內容等資訊)優先順序高  瀏覽器快取詳解:expires,cache-control,last-modified,etag詳細說明


14. websocket理解 websocket產生原因 瞭解http2嘛

在以前 HTTP 協議中所謂的 keep-alive connection 是指在一次 TCP 連線中完成多個 HTTP 請求,但是對每個請求仍然要單獨發 header;所謂的 polling 是指從客戶端(一般就是瀏覽器)不斷主動的向伺服器發 HTTP 請求查詢是否有新資料。這兩種模式有一個共同的缺點,就是除了真正的資料部分外,伺服器和客戶端還要大量交換 HTTP header,資訊交換效率很低。它們建立的“長連線”都是偽.長連線,只不過好處是不需要對現有的 HTTP server 和瀏覽器架構做修改就能實現。

WebSocket 解決的第一個問題是,通過第一個 HTTP request 建立了 TCP 連線之後,之後的交換資料都不需要再發 HTTP request了,使得這個長連線變成了一個真.長連線。但是不需要傳送 HTTP header就能交換資料顯然和原有的 HTTP 協議是有區別的,所以它需要對伺服器和客戶端都進行升級才能實現。在此基礎上 WebSocket 還是一個雙通道的連線,在同一個 TCP 連線上既可以發也可以收資訊。此外還有 multiplexing 功能,幾個不同的 URI 可以複用同一個 WebSocket 連線。這些都是原來的 HTTP 不能做到的。

http2它常被提起的特性有: 

多路複用 : 多個HTTP請求可以放在同一個連線中進行。且自有資料流能並行傳輸 以後不必在使用雪碧圖來

HEAD 壓縮:HTTP1中每次HTTP請求,都是必須要帶上HTTP頭的.而HTTP/2則在建立連線後,把頭欄位作為鍵值對,在兩邊維護一份字典,相同的就不用再傳了,如有新增或變更,則再在傳輸時帶上。減少HTTP頭的傳輸,互動密集時,其實能省不少流量 伺服器推送

優先順序請求:比如說你滾動條滑倒底部 底部圖片的圖片就會優先載入出來

伺服器推送:就是服務端能主動推東西過去,以前只能是被動的。在我的印象中,很多年前“Comet"這門技術曾經在淘寶大放光彩過。

即當客戶端發一個請求過來時,服務端能依據這個請求,推斷出你後續還要什麼,主動給推過去。大大減少了請求數,加快了反應時間.


15. 說一下為什麼會有跨域問題 你平時怎麼解決跨域的。以及後續JSONP的原理和實現以及cors怎麼設定。

瀏覽器的同源策略 同源是指,域名,協議,埠相同,三者有一個不同,則為跨域

 node代理,具體自己起個node服務,在node中轉發來自瀏覽器的請求,node服務和瀏覽器請求要同源,然後轉發攜帶具體引數,cookie...,轉發到後端的跨域介面,轉發庫可以用axios,支援在node,和瀏覽器都可以使用。

nginx配置代理

在react,vue中可以用webpack-dev-server配置代理

跨域資源共享cors,後端設定Access-Control-Allow-Origin:*

jsonp利用script標籤支援跨域 並在其中加入回撥函式 jsonp只支援get請求

iframe+script 等現實開發中,並不是很實用

16.如何設定cookie的跨域請求

Access-Control-Allow-Credentials設定為true

17. 從輸入連結到前端渲染出頁面經過什麼步驟

從輸入URL到頁面載入的過程?如何由一道題完善自己的前端知識體系!內容有很多大家可以按到自己的理解說一下其實沒必要那麼詳細

瀏覽器解析->查詢快取->dns查詢->建立連結->伺服器處理請求->伺服器傳送響應->客戶端收到頁面->解析HTML->構建渲染樹->開始顯示內容(白屏時間)->首屏內容載入完成(首屏時間)->使用者可互動(DOMContentLoaded)->載入完成(load)

18. js繼承可以說一下哪幾種和其中的優缺點

我說了原型和建構函式相結合的組合繼承方法 又談了寄生組合繼承

19. 談一談淺拷貝和深拷貝區別

object是JavaScript引用型別物件只會被克隆最外部的一層,至於更深層的物件,則依然是通過引用指向同一塊堆記憶體.

noah的前端面試題(一)|掘金技術徵文

我說了用JSON物件parse方法可以將JSON字串反序列化成JS物件,stringify方法可以將JS物件序列化成JSON字串,這兩個方法結合起來就能產生一個便捷的深克隆.

還有Object.assign() 只是一級屬性複製,比淺拷貝多深拷貝了一層而已。

noah的前端面試題(一)|掘金技術徵文

20. 尾遞迴來實現斐波那契

function fibonacci(n, n1, n2) {
    if(n <= 1) {
        return n2
    }
    return fibonacci(n - 1, n2, n1 + n2)
}複製程式碼

21. 用proxy實現string repeat方法

22. vue資料雙向繫結 

資料雙向繫結是通過oject.defineProerty進行資料劫持和訂閱者觀察者模式相結合

1.實現一個監聽器Observer,用來劫持並監聽所有屬性,如果有變動的,就通知訂閱者。

2.實現一個訂閱者Watcher,可以收到屬性的變化通知並執行相應的函式,從而更新檢視。

3.實現一個解析器Compile,可以掃描和解析每個節點的相關指令,並根據初始化模板資料以及初始化相應的訂閱器

23. vue的生命週期 

beforecreated create  mounted updated destory等

有分別說了created和mounted區別 created 初始化完成時的事件寫在這裡,如在這結束loading事件,非同步請求也適宜在這裡呼叫

mounted 掛載元素,獲取到DOM節點

destory可以做一些記憶體洩漏的東西

24. vue router模式和懶載入

vue-router 預設 hash 模式 使用 URL 的 hash 來模擬一個完整的 URL,於是當 URL 改變時,頁面不會重新載入。
如果不想要很醜的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新載入頁面。
不過這種模式要玩好,還需要後臺配置支援。因為我們的應用是個單頁客戶端應用,如果後臺沒有正確的配置,當使用者在瀏覽器直接訪問 oursite.com/user/id 就會返回 404,這就不好看了。
所以呢,你要在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面

懶載入:當打包構建應用時,Javascript 包會變得非常大,影響頁面載入。如果我們能把不同路由對應的元件分割成不同的程式碼塊,然後當路由被訪問的時候才載入對應元件,這樣就更加高效了。

結合 Vue 的非同步元件和 Webpack 的程式碼分割功能,輕鬆實現路由元件的懶載入。

25. 怎麼管理vuex的state

用module

26. 服務端渲染的優點

1. 伺服器端渲染固然耗CPU,但可以使用伺服器端快取的方式解決,並不是每個使用者訪問都需要重新渲染一遍。而且伺服器端渲染甚至可以潛在地增加伺服器效率(這點在參考資料第二個裡有提到,不過是純英文的,我有空會翻譯下)。

2. 伺服器端和客戶端可以共享某些程式碼,避免重複定義。這樣可以使結構更清晰,增加可維護性

3. 首次載入頁面的速度加快。客戶端渲染的一個缺點是,當使用者第一次進入站點,此時瀏覽器中沒有快取,需要下載程式碼後在本地渲染,時間較長。而伺服器渲染則是,使用者在下載的已經是渲染好的頁面了,開啟速度比本地渲染快。

4. SEO。伺服器端渲染可以讓搜尋引擎更容易讀取頁面的meta資訊以及其他SEO相關資訊,大大增加網站在搜尋引擎中的可見度。

27. 如果有個圖片特別大展示出來 如何優化;如果有大量圖片想相簿要展示如何處理

可以把圖片轉化base64的格式的非高清圖片用來展示,等圖片顯示完了以後再通過js進行圖片src替換;

先給每個圖片src附上通用loading圖片 通過滾輪觸發事件把想要的圖片替換loading圖片

28.前端效能優化

https://www.jianshu.com/p/ead7dab72cd6


相關文章