最近在找工作,面試了好多家公司,結果都不怎么理想。要么公司環境氛圍不行,要么工資達不到理想的薪資。大部分公司對程序員的面試流程幾乎都一樣,來了先填一份登記表,寫一套面試題,然后技術面,人事面。至於有的大牛說,四面web前端,拿到10K+的工資,反正我這個渣渣程序員是沒有碰到。
現在來整理一下這幾天我所碰到的面試題。
html、css相關
如何垂直居中一個浮動元素
- 父盒子有寬高
父元素相對定位,子元素絕對定位,top:50%;left:50%。margin負的左右二分之一的height,width
.content{ position: absolute; top: 50%; left: 50%; width: 100px; float: left; height: 100px; background-color: #ff6700; margin-top: -50px; margin-left: -50px; }
- 父盒子沒有高寬
父盒子相對定位,子盒子決定定位,上下左右都為0,margin:auto;
.content{ width: 200px; height: 200px; background-color: #ff6700; float: left; margin: auto; position: absolute; left: 0; top: 0; bottom: 0; right: 0; }
說一下css的三大特性以及選擇器的優先級
css三大特性:繼承、優先級、層疊
選擇器優先級:!important > 行內樣式 > ID選擇器 > 類選擇器 > 標簽 > 通配符 > 繼承
簡單說一下盒模型
盒模型: 內容 + padding + border + margin
有用過less這種預編譯嗎?用過它的那些方法
less是對css進行一個預編譯,它重新定義了css樣式的書寫,樣式可以嵌套,同時還定義了變量和函數
<!--定義變量--> @color: #ccc; .content{ background-color:@color; } <!--定義函數--> .textCenter(@marginT: 10px){ text-align:center; margin-top:@marginT; }
Css3顏色漸變有那兩種
線性漸變所用的屬性是
linear-gradien
徑向漸變用到的屬性是radial-gradient
說說H5和C3新增了那些特性
H5主要新增了一些語義化標簽,比如
header
,nav
,main
等等,還有音頻視頻,本地存儲等技術。
Css3新增了一些屬性選擇器,偽類選擇器,過度transition
,2D3D旋轉transform
,動畫animation
等
實現頁面間通信有那些方法,他們有什么區別
可以使用H5新增的本地存儲技術
localstorage
, 將數據存儲到本地硬盤
使用cookie
存儲,sessitionStorage
區別:cookie
兼容性較好,但是存儲體積小只有時4kb,生命周期短,會話結束數據就消失,而且不安全容易被劫持。而其他兩者不一樣,存儲體積大,存儲時間長,除非手動刪除否則不會消失。
說一下rem和em的區別
在css中的單位主要有px,em,rem
px單位是固定的像素,一但設置就無法適應頁面大小而改變
em和rem相對於px更具有靈活性,他們是相對長度單位,意思是長度不是定死了的,更適用於響應式布局。
em相對於父元素,rem相對於根元素(參照的是html)
說一下flex彈性布局的屬性
justify-content: //子元素水平排列的方式 center //居中 space-between //兩端對齊 space-around // 子元素拉手分布 flex-start // 居左 flex-end //居右 align-items : // 子元素的垂直居中的排列方式 enter // 居中 flex-end //底部 flex-start //開始 align-content : //多行的時候,子元素的垂直排列方式 center //居中 flex-end //底部 flex-start //開始 flx-direction: // 排列方式row 橫向排列 row-reverse //橫向反向排列 flex-wrap : //子元素是否在一行顯示 no-wrap //不換行 wrap //換行
控制元素顯示隱藏有那些方式,有什么區別
display:none
和visibility:hidden
display:none
控制隱藏的元素不占位置
visibility:hidden
隱藏元素,但保留元素空間
js相關
怎樣添加、移除、移動、復制、創建和查找節點
1)創建新節點 createDocumentFragment() //創建一個DOM片段 createElement() //創建一個具體的元素 createTextNode() //創建一個文本節點 (2)添加、移除、替換、插入 appendChild() removeChild() replaceChild() insertBefore() (3)查找 getElementsByTagName() //通過標簽名稱 getElementsByName() //通過元素的Name屬性的值 getElementById() //通過元素Id,唯一性
說說js中操作數組字符串的方法
這個我在之前的文章也有總結過
談談你對閉包的理解
之所以有閉包是因為js存在一個變量作用域,變量的作用域分為局部全局作變量和局部變量,在js函數中,可以訪問到外部定義的全局變量,但在函數外面卻無法訪問函數內部定義的局部變量。所以閉包就是用來解決函數外部無法訪問函數內部的局部變量。
閉包是在一個函數內部,return一個子函數,在子函數中可以訪問到父函數定義的局部變量。它可以讀取函數內部的變量,讓這些變量的值始終保持在內存中,避免變量全局污染。所以導致它不能被瀏覽器垃圾回收機制回收,容易造成頁面性能問題,內存泄漏
垃圾回收機制
JS的垃圾回收機制是為了以防內存泄漏,內存泄漏的含義就是當已經不需要某塊內存時這塊內存還存在着,垃圾回收機制就是間歇的不定期的尋找到不再使用的變量,並釋放掉它們所指向的內存。
當一個變量的生命周期結束之后它所指向的內存就應該被釋放。JS有兩種變量,全局變量和在函數中產生的局部變量。局部變量的生命周期在函數執行過后就結束了,此時便可將它引用的內存釋放(即垃圾回收),但全局變量生命周期會持續到瀏覽器關閉頁面。
說一下原型和原型鏈
- 原型
JavaScript 規定,每一個構造函數都有一個 prototype 屬性,指向另一個對象。我們可以把所有對象實例需要共享的屬性和方法直接定義在 prototype 對象上。這個對象的所有屬性和方法,都會被構造函數的所擁有。
Prototype
作為對象的內部屬性,是不能被直接訪問的,我們一般通過__proto__
這個屬性進行訪問。
在原型對象中還有一個屬性constructor
,這個屬性對應創建所有指向該原型的實例的構造函數
原型對象就相當於一個公共的區域,所有同一個類的實例都可以訪問到這個原型對象,我們可以將對象中共有的內容,統一設置到原型對象中。

- 原型鏈
在JavaScript中萬物都是對象,對象和對象之間也有關系,並不是孤立存在的。對象之間的繼承關系,在JavaScript中是通過prototype對象指向父類對象,直到指向Object對象為止,這樣就形成了一個原型指向的鏈條
當我們訪問對象的一個屬性或方法時,它會先在對象自身中尋找,如果有則直接使用,如果沒有則會去原型對象中尋找,如果找到則直接使用。如果沒有則去原型的原型中尋找,直到找到Object對象的原型,Object對象的原型沒有原型,如果在Object原型中依然沒有找到,則返回undefined。

事件機制和事件委托
事件流的三個階段:
事件捕獲
處於目標階段
事件冒泡
事件委托:
事件委托是利用了事件的冒泡原理實現的,子元素的事件通過冒泡形式委托父元素執行
說一下JS面對對象有那些特性,怎樣實現
-
對象三大特性:封裝,繼承,多態
-
封裝:將面向過程每一步進行推進:對同種對象的屬性和方法進行抽象,成為一個類(js中沒有類的概念,實際上也是一個對象),然后通過類的方法和屬性來訪問類
-
繼承:在封裝的基礎上,將同類事物繼續抽象,繼承時,子類擁有父類的屬性和方法,同時擁有自己特有的屬性和方法
js的繼承實現方法:
1.屬性拷貝(淺拷貝)
2.屬性拷貝(深拷貝)
3.原型式繼承
4.原型鏈繼承
5.借用構造函數
6.組合繼承
- 多態:不同對象對同一事物做出不同的回應,通常出現在繼承后對方法的重寫
特點:對於同一個操作(指令),不同的對象表現出不同的反應 隱藏不同
談談你對同步異步的理解
-
同步:在執行完一個函數或方法之后,一直等待系統返回值或消息,這時程序是出於阻塞的,只有接收到返回的值或消息后才往下執行其他的命令。
-
異步:執行完函數或方法后,不必阻塞性地等待返回值或消息
-
區別:同步會阻塞程序的執行,效率低。異步可以同時執行多個程序,效率高
一次完整的HTTP請求是怎樣一個過程
域名解析 --> 發起TCP的3次握手 --> 建立TCP連接后發起http請求 --> 服務器響應http請求,瀏覽器得到html代碼 --> 瀏覽器解析html代碼,並請求html代碼中的資源(如js、css、圖片等) --> 瀏覽器對頁面進行渲染呈現給用戶
Ajax原理
ajax是用來實現頁面異步加載,同步刷新。
Ajax的原理簡單來說通過XmlHttpRequest
對象來向服務器發異步請求,從服務器獲得數據,然后用javascript來操作DOM而更新頁面。
XMLHttpRequest
對象的屬性:
open
准備發送請求的數據
send
發送請求
onreadystatechange
每次狀態改變所觸發事件的事件處理程序。
responseText
從服務器進程返回數據的字符串形式。
responseXML
從服務器進程返回的DOM兼容的文檔數據對象。
status
從服務器返回的數字代碼,比如常見的404(未找到)和200(已就緒)
status Text
伴隨狀態碼的字符串信息
readyState
對象狀態值
Ajax中get請求和post有什么區別
GET和POST請求方式的差異
GET請求沒沒有請求體,請求的數據在xhr.open()里面拼接,xhr.send(null)
POST請求數據在xhr.send()里面,在設置請求體之前需要設置請求頭
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
解決跨域
產生跨域是因為瀏覽器的同源策略:域名 協議 端口必須保持一致
- CORS
在服務器端設置響應頭
header("Access-Control-Allow-Origin:*")
這種方式需要前后台的一個配后,而且相對而言不安全
- JSONP
利用script標簽src天然支持跨域的特征,將請求的地址寫在src,在script里面定義一個處理函數,並把函數名傳遞給后台,后台接收並返回這個函數的調用,將傳遞的參數以函數形參的方式傳遞給前端
這種通過src放送的是一個同步請求,而且只能發送get請求,和ajax不一樣
- 方向代理
通過訪問第三方服務器,讓第三方服務器幫我們發送請求.
es6你知道多少
-
字符串擴展
includes
斷字符串中是否包含子字符串,第一個參數表示要測試的子字符串,第二個參數表示從那個位置開始查找,不傳默認從索引0開始。
startsWith
判斷字符串是否以特定的字符串開始
endsWith
判斷字符串是否以特定的字符串結束
字符串填充:padStart()
和padEnd()
可以對字符串進行填充 -
解構賦值
數組的結構賦值
// 解構 let [a,b,c] = [1,2,3]; console.log(a,b,c); // 1 2 3 // 解構時設置默認值 let [a = 1,b,c] = [,5,6]; console.log(a,b,c); // 1 5 6 // 解構時沒有的數據為undefined let [a = 1,b,c] = [4,5,]; console.log(a,b,c); // 4 5 undefined
對象的解構賦值
let {name,age} = {name:'zxx',age:18} console.log(name,age); // zxx 18 // 順序無關 let {name,age} = {age:18,name:'zxx'} console.log(name,age); // zxx 18 // 屬性別名,一旦設置了別名,原來的名字就無效了 let {name:tag,age} = {age:18,name:'zxx'} console.log(name,age); // ReferenceError: name is not defined console.log(tag,age); // zxx 18
// 解構賦值時設置默認值 let {name:tag='zxx',age} = {age:18} console.log(tag,age); // zxx 18
字符串的解構賦值
let [a,b,c,d] = 'zxx'; console.log(a,b,c,d); // z x x undefined let [a,b,c,d] = 'zxx'; console.log(a,b); z x // 得到字符串長度 let { length } = 'zxx'; console.log(length); // 3
- 擴展運算符
合並數組
let arr2 = [4,5,6]; let arr3 = [...arr1,...arr2]; console.log(arr3); // [1,2,3,4,5,6]
- 箭頭函數
let f = function(v) { return v; }; let f = v => v;
- Promise
Promise 是異步編程的一種解決方案.簡單說就是一個容器,里面保存着某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說,Promise 是一個對象,可以從改對象獲取異步操作的消息。
// 1. 創建promise實例,在實例中執行異步操作(比如發送網絡請求) // 2. 異步操作成功時,調用reslove函數傳遞數據 // 3. 異步操作失敗時,調用reject函數傳遞錯誤信息 const promise = new Promise(function(resolve, reject) { // 異步操作 if (/* 異步操作成功 */){ resolve(value); } else { reject(error); } }); // 使用promise實例then方法接收reslove或reject返回的數據 promise.then(function(value) { // 此處數據即為reslove回來的數據 // success }, function(error) { // 此處數據即為reject回來的數據 // failure });
VUE相關
vue有那些指令
v-text
v-bind
v-for
v-if
v-on
談談MVVM
MVVM是一種分層次開發思想,它是CommonJS規范的實現
M代表module模型層
V代碼view視圖層
VM模型層和視圖層之間沒有任何的聯系,而VM會充當一個調度者,將他們聯系起來,實現雙向數據綁定
組件化
從頁面視圖的角度出發,對頁面功能的封裝,實現項目可獨立維護,可復用性大大提高
什么是Vue雙向數據綁定?原理?
v-model指令、數據視圖同步更新、使用的是ES5提供的Object.defineProperty()這個方法實現數據劫持
數據如何從模型同步到視圖?當模型中數據發生變化時會觸發Object.defineProperty的set方法,在這個方法內部能夠劫持到數據的改變,然后就可以在該方法內部通知視圖更新
視圖中的數據如何同步到模型中?(v-model指令是怎么實現改變了元素中的數據同步到模型中)監聽表單元素的change事件,在change事件中可以拿到用戶輸入的數據,然后給模型中的數據賦值
v-if和v-show的區別
v-if和v-show都是用來控制元素的顯示和隱藏,當值是true,元素顯示,值為false,元素隱藏
區別: v-if當切換布爾值時,會創建/刪除元素;v-show當切換布爾值時,會改變元素的樣式,display:block
Vue生命周期函數的理解?
生命周期就是在vue實例執行過程中會觸發的一批函數,這些函數可以幫助我們處理不同時間段的業務邏輯
- 創建階段
-
beforeCreate
vue實例被創建出來,此時僅僅只是分配了內存,屬性和方法都還沒有掛載到vue實例上 -
created
此時vue實例已經創建完畢,data中的屬性和methods中的方法都已經掛載到vue實例上
-
- 渲染階段
-
beforeMount
vue實例中的數據被解析渲染到內存中的虛擬DOM上,真實中的DOM指令還沒有被解析 -
mounted
vue實例中的數據已經完全被渲染到了真實DOM中
-更新階段 -
beforeUpdate
模型中的數據已經改變,但視圖中的數據還沒有同步更新 -
updated
此時模型中的數據改變,視圖層數據已經同步更新
-
- 銷毀階段
-beforeDestroy
vue中的數據和方法還能繼續使用,但是指令不能再被vue解析-
destroyed
vue中的數據和方法都已經被銷毀
-
說一下單向數據流
組件之間的傳值,數據從父級組件傳遞給子組件,只能單向綁定。
- 父組件向子組件傳值
在父組件中定義數據,通過屬性綁定的形式綁定到子組件上,在子組件中定義props接收傳遞過來的變量
- 子組件向父組件傳值
在子組件中使用this.$emit觸發一個自定義的方法名,然后傳遞數據第一個參數就是自定義的方法名,第二個參數就是需要傳遞給父組件的數據
this.$emit('func',this.msg)
在父組件中使用子組件時,綁定一個事件,事件名稱和子組件觸發的方法名同名
<div id='app'> <son @func = 'getmsg'></son> </div>
vue-router路由模式有幾種,原理分別是什么?
vue-router路由庫是用哪種技術實現的,總共有兩種,分別叫hash模式和history模式,默認是hash模式
-
hash模式:地址上帶有#號;url地址可以放在任意標簽中打開;可以兼容低版本的瀏覽器
hash模式原理:監聽hashchange事件,可以調用window.location.hash獲取到錨點值,和路由規則進行匹配,匹配到之后將路由規則中定義的組件渲染到頁面
history模式:地址上沒有#號,更加符合URL形式;url地址不能重復打開; -
history模式原理:利用HTML5新提供的history.pushState API 來完成 URL 跳轉而無須重新加載頁面
history模式需要后台進行相關配置:要在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面
Vuex怎么用,它相對與localstorage有什么優點和缺點
vuex的核心是:state,getter,actions,mutations
state
用來定義存放公共數據this.$store.state.msg
mutations
定義方法this.$store.commit('change','我是被修改的數據')
getters
用於獲取數據 進行一些操作 類似於Vue實例中的過濾器和計算屬性this.$store.getters.fixmsg
action
actions和mutations都是定義對數據進行操作的方法,mutations中都是同步方法,mutations中定義異步方法this.$store.dispatch('asyncchange','我是被異步修改的數據')
區別
localstorage無法實現雙向數據綁定,模型層的數據改變視圖中數據不會發生改變,vuex數據不能持久化,需要結合localstorage使用,比較臃腫,小型項目不建議使用
總結
以上就是我最近面試遇到的面試題,希望對各位有所幫助,后期我也會持續更新,有遇到新的問題會及時更新。如果有什么錯誤,還請各位大佬指出在評論留言,小子會更改。最后希望大家能順利的找到自己滿意的工作,喜歡的可以支持一下,畢竟座在床上寫了一下午(別問我為什么還在床上)也蠻辛苦的。
小禮物走一走
鏈接:https://www.jianshu.com/p/605a6f60ca92