02.27 前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer

小編在之前的文章中分享了PHP、Java等面試題以及答案,許多人就給小編留言,希望分享前端、大數據、軟件測試等面試題,小編已經拿小本本記下來了,在接來的文章中會相繼分享給大家,而今天我們就一起來看看前端的一些面試題吧~

談談對MVVM開發模式的理解

MVVM分為Model、View、ViewModel三者。

  • Model:代表數據模型,數據和業務邏輯都在Model層中定義;
  • View:代表UI視圖,負責數據的展示;
  • ViewModel:負責監聽Model中數據的改變並且控制視圖的更新,處理用戶交互操作;

Model和View並無直接關聯,而是通過ViewModel來進行聯繫的,Model和ViewModel之間有著雙向數據綁定的聯繫。因此當Model中的數據改變時會觸發View層的刷新,View中由於用戶交互操作而改變的數據也會在Model中同步。

這種模式實現了Model和View的數據自動同步,因此開發者只需要專注對數據的維護操作即可,而不需要自己操作dom。

Vue 有哪些指令?( )

v-html、v-show、v-if、v-for等等。

v-if 和 v-show 有什麼區別?

v-show 僅僅控制元素的顯示方式,將 display 屬性在 block 和 none 來回切換;而v-if會控制這個 DOM 節點的存在與否。當我們需要經常切換某個元素的顯示/隱藏時,使用v-show會更加節省性能上的開銷;當只需要一次顯示或隱藏時,使用v-if更加合理。

簡述Vue的響應式原理

當一個Vue實例創建時,vue會遍歷data選項的屬性,用 Object.defineProperty將它們轉為getter/setter並且在內部追蹤相關依賴,在屬性被訪問和修改時通知變化。每個組件實例都有相應的watcher程序實例,它會在組件渲染的過程中把屬性記錄為依賴,之後當依賴項的setter被調用時,會通知watcher重新計算,從而致使它關聯的組件得以更新。


前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer


Vue中如何在組件內部實現一個雙向數據綁定?

假設有一個輸入框組件,用戶輸入時,同步父組件頁面中的數據。

具體思路:父組件通過props傳值給子組件,子組件通過 $emit 來通知父組件修改相應的props值,具體實現如下:

import

Vue
from
'vue'
const
component = {
props: [
'value'
],
template: `

"text"

@input
=
"handleInput"
:value=
"value"
>

`,
data () {

return
{

}
},
methods: {
handleInput (e) {

this
.$emit(
'input'
, e.target.value)
}
}
}
new

Vue
({
components: {

CompOne
: component
},
el:
'#root'
,
template: `

<comp-one>"value"

@input
=
"value = arguments[0]"
>/<comp-one>

`,
data () {

return
{
value:
'123'
}
}
})

可以看到,當輸入數據時,父子組件中的數據是同步改變的:

前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer


前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer


我們在父組件中做了兩件事,一是給子組件傳入props,二是監聽input事件並同步自己的value屬性。那麼這兩步操作能否再精簡一下呢?答案是可以的,你只需要修改父組件:

template: `


<comp-one>"value"
>/<comp-one>

`

v-model 實際上會幫我們完成上面的兩步操作。

Vue中如何監控某個屬性值的變化?

比如現在需要監控data中, obj.a 的變化。Vue中監控對象屬性的變化你可以這樣:

watch: {
obj: {
handler (newValue, oldValue) {
console.log(
'obj changed'
)
},
deep:
true
}
}

deep屬性表示深層遍歷,但是這麼寫會監控obj的所有屬性變化,並不是我們想要的效果,所以做點修改:

watch: {

'obj.a'
: {
handler (newName, oldName) {
console.log(
'obj.a changed'
)
}
}
}

還有一種方法,可以通過computed 來實現,只需要:

computed: {
a1 () {

return

this
.obj.a
}
}

利用計算屬性的特性來實現,當依賴改變時,便會重新計算一個新值。

Vue中給data中的對象屬性添加一個新的屬性時會發生什麼,如何解決?

示例:

<template>






  • v-for
    =
    "value in obj"
    :
    key
    =
    "value"
    >
    {{value}}





<button> @
click
=
"addObjB"
>
添加obj.b
/<button>


/<template>

<style>

點擊button會發現, obj.b 已經成功添加,但是視圖並未刷新:


前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer


前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer

原因在於在Vue實例創建時, obj.b 並未聲明,因此就沒有被Vue轉換為響應式的屬性,自然就不會觸發視圖的更新,這時就需要使用Vue的全局api—— $set():

addObjB () {

// this.obj.b = 'obj.b'

this
.$set(

this
.obj,
'b'
,
'obj.b'
)
console.log(
this
.obj)
}

$set() 方法相當於手動的去把 obj.b 處理成一個響應式的屬性,此時視圖也會跟著改變了:


前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer


delete和Vue.delete刪除數組的區別

delete只是被刪除的元素變成了 empty/undefined 其他的元素的鍵值還是不變。

Vue.delete 直接刪除了數組 改變了數組的鍵值。

 
var
a=[
1
,
2
,
3
,
4
]

var
b=[
1
,
2
,
3
,
4
]

delete
a[
1
]
console.log(a)

this
.$delete(b,
1
)

console.log(b)


前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer


前端程序員心心念唸的面試題精選(全都有答案)助你拿心儀offer


如何優化SPA應用的首屏加載速度慢的問題?

  • 將公用的JS庫通過script標籤外部引入,減小 app.bundel 的大小,讓瀏覽器並行下載資源文件,提高下載速度;
  • 在配置 路由時,頁面和組件使用懶加載的方式引入,進一步縮小 app.bundel 的體積,在調用某個組件時再加載對應的js文件;
  • 加一個首屏loading圖,提升用戶體驗;

前端如何優化網站性能?

1、減少 HTTP 請求數量

在瀏覽器與服務器進行通信時,主要是通過 HTTP 進行通信。瀏覽器與服務器需要經過三次握手,每次握手需要花費大量時間。而且不同瀏覽器對資源文件併發請求數量有限(不同瀏覽器允許併發數),一旦 HTTP 請求數量達到一定數量,資源請求就存在等待狀態,這是很致命的,因此減少 HTTP 的請求數量可以很大程度上對網站性能進行優化。

CSS Sprites

國內俗稱CSS精靈,這是將多張圖片合併成一張圖片達到減少HTTP請求的一種解決方案,可以通過CSS的background屬性來訪問圖片內容。這種方案同時還可以減少圖片總字節數。

合併 CSS 和 JS 文件

現在前端有很多工程化打包工具,如:grunt、gulp、webpack等。為了減少 HTTP 請求數量,可以通過這些工具再發布前將多個CSS或者多個JS合併成一個文件。

採用 lazyLoad

俗稱懶加載,可以控制網頁上的內容在一開始無需加載,不需要發請求,等到用戶操作真正需要的時候立即加載出內容。這樣就控制了網頁資源一次性請求數量。

2、控制資源文件加載優先級

瀏覽器在加載HTML內容時,是將HTML內容從上至下依次解析,解析到link或者script標籤就會加載href或者src對應鏈接內容,為了第一時間展示頁面給用戶,就需要將CSS提前加載,不要受 JS 加載影響。

一般情況下都是CSS在頭部,JS在底部。

3、利用瀏覽器緩存

瀏覽器緩存是將網絡資源存儲在本地,等待下次請求該資源時,如果資源已經存在就不需要到服務器重新請求該資源,直接在本地讀取該資源。

4、減少重排(Reflow)

基本原理:重排是DOM的變化影響到了元素的幾何屬性(寬和高),瀏覽器會重新計算元素的幾何屬性,會使渲染樹中受到影響的部分失效,瀏覽器會驗證 DOM 樹上的所有其它結點的visibility屬性,這也是Reflow低效的原因。如果Reflow的過於頻繁,CPU使用率就會急劇上升。

減少Reflow,如果需要在DOM操作時添加樣式,儘量使用 增加class屬性,而不是通過style操作樣式。

5、減少 DOM 操作

6、圖標使用 IconFont 替換

網頁從輸入網址到渲染完成經歷了哪些過程?

大致可以分為如下7步:

  1. 輸入網址;
  2. 發送到DNS服務器,並獲取域名對應的web服務器對應的ip地址;
  3. 與web服務器建立TCP連接;
  4. 瀏覽器向web服務器發送http請求;
  5. web服務器響應請求,並返回指定url的數據(或錯誤信息,或重定向的新的url地址);
  6. 瀏覽器下載web服務器返回的數據及解析html源文件;
  7. 生成DOM樹,解析css和js,渲染頁面,直至顯示完成;

jQuery獲取的dom對象和原生的dom對象有何區別?

js原生獲取的dom是一個對象,jQuery對象就是一個數組對象,其實就是選擇出來的元素的數組集合,所以說他們兩者是不同的對象類型不等價。

原生DOM對象轉jQuery對象:

var
box = document.getElementById(
'box'
);
var
$box = $(box);

jQuery對象轉原生DOM對象:

var
$box = $(
'#box'
);
var
box = $box[
0
];

jQuery如何擴展自定義方法

(jQuery.fn.myMethod=
function
() {
alert(
'myMethod'
);
})
// 或者:
(
function
($) {
$.fn.extend({
myMethod :
function
() {
alert(
'myMethod'
);
}
})
})(jQuery)

使用:

$(

"#div"

).myMethod();

CSS,JS代碼壓縮,以及代碼CDN託管,圖片整合。

(1)CSS,JS 代碼壓縮:

可以應用gulp的gulp-uglify,gulp-minify-css模塊完成;可以應用Webpack的 UglifyJsPlugin壓縮插件完成。

(2)CDN:

內容分發網絡(CDN)是一個經策略性部署的整體系統,包括分佈式存儲、負載均衡、網絡請求的重定向和內容管理4個要件。主要特點有:本地Cache加速,鏡像服務,遠程加速,帶寬優化。關鍵技術有:內容發佈,內容路由,內容交換,性能管理。CDN網站加速適合以諮詢為主的網站。CDN是對域名加速不是對網站服務器加速。CDN和鏡像站比較不需要訪客手動選擇要訪問的鏡像站。CDN使用後網站無需任何修改即可使用CDN獲得加速效果。如果通過CDN後看到的網頁還是舊網頁,可以通過URL推送服務解決,新增的網頁和圖片不需要URL推送。使用動態網頁可以不緩存即時性要求很高的網頁和圖片。CDN可以通過git或SVN來管理。

(3)圖片整合

減少網站加載時間的最有效的方式之一就是減少網站的HTTP請求數。實現這一目標的一個有效的方法就是通過CSS Sprites——將多個圖片整合到一個圖片中,然後再用CSS來定位。缺點是可維護性差。可以使用百度的fis/Webpack來自動化管理sprite。

如何利用Webpack把代碼上傳服務器以及轉碼測試?

(1)代碼上傳:

可以使用sftp-Webpack-plugin,但是會把子文件夾給提取出來,不優雅。可以使用gulp+Webpack來實現。

(2)轉碼測試

Webpack應用babel來對ES6轉碼,開啟devtool: “source-map" 來進行瀏覽器測試。應用karma或mocha來做單元測試。

項目上線流程是怎樣的?

(1)流程建議

- 模擬線上的開發環境

本地反向代理線上真實環境開發即可。(apache,nginx,nodejs均可實現)

- 模擬線上的測試環境

模擬線上的測試環境,其實是需要一臺有真實數據的測試機,建議沒條件搭daily的,就直接用線上數據測好了,只不過程序部分走你們的測試環境而已,有條件搭daily最好。

- 可連調的測試環境

可連調的測試環境,分為2種。一種是開發測試都在一個局域網段,直接綁hosts即可,不在一個網段,就每人分配一臺虛擬的測試機,放在大家都可以訪問到的公司內網,代碼直接往上布即可。

- 自動化的上線系統

自動化的上線系統,可以採用Jenkins。如果沒有,可以自行搭建一個簡易的上線系統,原理是每次上線時都抽取最新的trunk或master,做一個tag,再打一個時間戳的標記,然後分發到cdn就行了。界面裡就2個功能,打tag,回滾到某tag,部署。

- 適合前後端的開發流程

開發流程依據公司所用到的工具,構建,框架。原則就是分散獨立開發,互相不干擾,連調時有hosts可綁即可。

(2)簡單的可操作流程

- 代碼通過git管理,新需求創建新分支,分支開發,主幹發佈

- 上線走簡易上線系統,參見上一節

- 通過gulp+Webpack連到發佈系統,一鍵集成,本地只關心原碼開發

- 本地環境通過Webpack反向代理的server

- 搭建基於linux的本地測試機,自動完成build+push功能

工程化怎麼管理的?

gulp和Webpack

git常用命令

Workspace:工作區

Index / Stage:暫存區

Repository:倉庫區(或本地倉庫)

Remote:遠程倉庫

Webpack 和 gulp對比

Gulp 就是為了規範前端開發流程,實現前後端分離、模塊化開發、版本控制、文件合併與壓縮、mock數據等功能的一個前端自動化構建工具。說的形象點,“Gulp就像是一個產品的流水線,整個產品從無到有,都要受流水線的控制,在流水線上我們可以對產品進行管理。” 另外,Gulp是通過task對整個開發過程進行構建。

Webpack 是當下最熱門的前端資源模塊化管理和打包工具。它可以將許多鬆散的模塊按照依賴和規則打包成符合生產環境部署的前端資源。還可以將按需加載的模塊進行代碼分隔,等到實際需要的時候再異步加載。通過 loader的轉換,任何形式的資源都可以視作模塊,比如 CommonJs 模塊、AMD 模塊、ES6 模塊、CSS、圖片、JSON、Coffeescript、LESS 等。

Gulp和Webpack功能實現對比:從基本概念、啟動本地Server、sass/less預編譯、模塊化開發、文件合併與壓縮、mock數據、版本控制、組件控制八個方面對Gulp和Webpack進行對比。

Webpack打包文件太大怎麼辦?

Webpack 把我們所有的文件都打包成一個 JS 文件,這樣即使你是小項目,打包後的文件也會非常大。可以從去除不必要的插件,提取第三方庫,代碼壓縮,代碼分割,設置緩存幾個方面著手優化。

不想讓別人盜用你的圖片,訪問你的服務器資源該怎麼處理?

目前常用的防盜鏈方法主要有兩種:

(1)設置Referer:適合不想寫代碼的用戶,也適合喜歡開發的用戶

(2)簽名URL:適合喜歡開發的用戶

精靈圖和base64如何選擇?

css精靈,用於一些小的圖標不是特別多,一個的體積也稍大,比如大於10K(這個沒有嚴格的界定)。

base64,用於小圖標體積較小(相對於css精靈),多少都無所謂。字體圖標,用於一些別人做好的圖標庫(也有少數自己去做的)用起來比較方便,他的圖標只能用於單色,圖標用只能於一種顏色。

Webpack怎麼引入第三方的庫?

拿jQuery為例:

entry: {

page: 'path/to/page.js',

jquery: 'node_modules/jquery/dist/jquery.min.js'

}

new HtmlWebpackPlugin({

filename: 'index.html',

template: 'index.html',

inject: true,

chunks: ['jquery', 'page'] // 按照先後順序插入script標籤

})

希望大家不僅要追求學習的廣度,更要追求深度。願你能早日拿到心儀的offer。


分享到:


相關文章: