https://github.com/haizlin/fe-interview
2、http緩存
-
強緩存
強緩存就是給資源設置個過期時間,客戶端每次請求資源時都會看是否過期;只有在過期才會去詢問服務器。
不會向服務器發(fā)送請求,直接從緩存中讀取資源 -
協(xié)商緩存
請求資源時,服務端和最新資源做對比。
如果資源沒更改,返回304,瀏覽器讀取本地緩存。
如果資源有更改,返回200,返回最新的資源。
協(xié)商緩存和強緩存使用場景:服務器上的資源會更新,這個時候如果我們還訪問本地緩存,那么對用戶來說,那就相當于資源沒有更新,用戶看到的還是舊的資源;所以我們希望服務器上的資源更新了瀏覽器就請求新的資源,沒有更新就使用本地的緩存,以最大程度的減少因網(wǎng)絡請求而產(chǎn)生的資源浪費。所以一般會使用協(xié)商緩存 -
本地存儲
本地存儲主要有以下幾種,localStorage、sessionStorage、cookie、websql、indexDB.
localStorage
在前端設置,可以減少數(shù)據(jù)請求,長期存儲。
sessionStorage
在前端設置,只存在當前會話中即重新打開瀏覽器則數(shù)據(jù)消失
cookie
在后端設置,保存在客戶端本地文件,通過set-cookie設置且Cookie的內(nèi)容自動在請求的時候被傳遞到服務器
3、nginx負載均衡
使用upstream設置不同的服務器,以便每次訪問的時候,都會訪問到不同的服務器

5、key使用index會有什么問題
key是這條數(shù)據(jù)唯一的標識,用來追蹤列表中哪條元素進行變動了。如果數(shù)組某項數(shù)據(jù)刪除,以前的數(shù)據(jù)和重新渲染后的數(shù)據(jù)隨著 key 值的變化從而沒法建立關聯(lián)關系. 這就失去了 key 值存在的意義,可能就會導致數(shù)據(jù)錯亂。一般都會使用每條數(shù)據(jù)的id,因為id是唯一的
6、css優(yōu)先級
內(nèi)聯(lián)樣式>ID選擇器>類選擇器(Class)
8、絕對定位和相對定位的區(qū)別
絕對定位:是相對于元素最近的已定位的祖先元素,如果元素沒有已定位的祖先元素,那么它的位置則是相對于body
相對定位:相對于元素在文檔中的初始位置
9、let、const、var的區(qū)別
const一般用于聲明常量,var和let一般用于聲明變量
const和let不能重復定義屬性名,而var可以,并且var存在變量提升的現(xiàn)象
var可以跨快訪問
10、get和post的區(qū)別
get返回時,不會重新請求,而post返回時,會重新提交表單
get沒有post安全,因為get請求參數(shù)直接暴露在url上
get參數(shù)通過url傳遞,post放在body中
get請求參數(shù)長度有限制,post沒有
get請求參數(shù)會被保存在瀏覽器歷史中,而post不會
11、常用狀態(tài)碼
200 - 成功
301 - 重定向
304 - 一般用于協(xié)商緩存,向后臺發(fā)請求讀取資源,如果本地有緩存,則返回304讀取本地緩存
400 - 前臺數(shù)據(jù)格式有錯誤
401 - 權(quán)限不足
403 - 服務器拒絕請求
500 - 服務器內(nèi)部錯誤
503 - 服務器維護
12、react調(diào)用setState后發(fā)生了什么
react會觸發(fā)調(diào)和過程,react會以相對高效的方式根據(jù)新的狀態(tài)構(gòu)建react元素樹并且重新渲染界面,react會自動計算新數(shù)樹與舊樹的差異,然后根據(jù)差異來渲染。
14、react為什么虛擬 dom 會提高性能?
虛擬 dom 相當于在 js 和真實 dom 中間加了一個緩存,利用 dom diff 算法避免了沒有必要的 dom 操作,從而提高性能。傳統(tǒng)diff算法復雜度達到 O(n^3) ,n是樹的節(jié)點數(shù),而虛擬dom中的Diff算法復雜度只需要O(n)復雜度
15、了解redux嗎?
redux是公共管理狀態(tài)的,主要有三個核心方法,action,reducer,store,工作流程就是view調(diào)用dispatch觸發(fā)action,action可以寫異步操作,然后分發(fā)dispatch,reducer會根據(jù)action分發(fā)的dispatch中的type和state來更新狀態(tài)。當我們在組件中使用則需要使用connect將組件與store連接起來。
16、JS事件循環(huán)
首先JS是單線程的,一般的代碼都會按順序執(zhí)行,如果遇到異步代碼,會將異步代碼放到另一個線程,這個線程我們叫工作線程,主線程繼續(xù)執(zhí)行剩余的代碼,當工作線程異步代碼執(zhí)行完成過后,比如setTimeout時間到了或者axios得到了數(shù)據(jù),該線程就會將回調(diào)函數(shù)放到消息隊列里面去,當主線程代碼執(zhí)行完過后,會檢查任務隊列是否有任務要執(zhí)行,如果有,則會執(zhí)行,如果沒有,則會一直循環(huán)等待任務到來。
17、什么是閉包和內(nèi)存泄漏
閉包通俗來講,就是a函數(shù)里面還有b函數(shù),而b函數(shù)可以訪問a函數(shù)里面的變量。
因為閉包會攜帶它的函數(shù)的作用域,這樣會導致多余的內(nèi)存被占用,這就是內(nèi)存泄漏
在推出函數(shù)之前,將變量賦值為null,就可解決內(nèi)存泄漏
18、async和await的原理和使用
在異步代碼的函數(shù)上加上async,在異步代碼前加上await,這樣使用的話,我們即使調(diào)用的異步代碼,也會變成類似于同步,只有讓這個異步代碼執(zhí)行完過后,才會執(zhí)行下面的代碼,好處就是promise一般會通過then方法來獲取異步數(shù)據(jù),如果過多的話,就會造成回調(diào)地獄,代碼可讀性差,使用async/await可以使代碼很簡潔。
19、MVVM是什么?
MVVM即Model-View-ViewModel的簡寫。模型(Model)指的是后端傳遞的數(shù)據(jù)。視圖(View)指的是所看到的頁面。視圖模型(ViewModel)是mvvm模式的核心,它是連接view和model的橋梁。例如react的state和vue的data里面,然后頁面數(shù)據(jù)是從這個state或data里面取到的
20、css和less區(qū)別
less是css預處理語言,擴展了css。
- less可以聲明變量,@color: #4D926F;
- less可以混合,即b樣式可以直接調(diào)用a樣式
21、form表單提交和ajax提交表單區(qū)別
- ajax是異步的,網(wǎng)頁不需要刷新,form表單提交則需要刷新
- ajax提交是在后臺新建請求,form表單則是趨勢放棄本頁面,再申請
22、Promise是什么?
promise是一個對象,內(nèi)部有三個狀態(tài),resolved,rejected,pending。當我們new一個promise對象的時候,會傳入一個回調(diào)函數(shù),這回調(diào)函數(shù)有resolve和reject兩個方法。想改變狀態(tài)只能調(diào)用resolve()或者reject()這兩個方法,并且resolve可以將異步數(shù)據(jù)存儲在內(nèi)部data里面,然后他們通過.then方法來獲取數(shù)據(jù),then方法可以接受兩個參數(shù),一個成功的回調(diào),一個失敗的回調(diào)。但是我們獲取數(shù)據(jù)一般是通過async/await來獲取數(shù)據(jù)。這樣可以避免回調(diào)地獄。
23、高階函數(shù)是什么?
高階函數(shù)就是指函數(shù)作為可以作為另外一個函數(shù)的參數(shù)
24、組件化開發(fā)有什么好處?
- 可組合:便于將復雜的UI拆分成多個簡單的UI組件
- 可復用:每個組件都具有獨立功能,可使用在多個場景
- 便于維護:每個組件都有自己的功能,便于開發(fā)者維護
25、什么是跨域?
當一個url的協(xié)議、域名、端口三者之間任意一個與當前url不同即為跨域,跨域則是因為受到瀏覽器同源策略的限制,同源就是指兩個頁面具有相同的協(xié)議、域名、端口號。
26、怎么解決跨域?
- 1、nginx反向代理
- 2、jsonp請求,但是只能處理get請求
-
3、CORS跨域
cors全稱是跨域資源共享,cors需要瀏覽器和服務器同時支持,瀏覽器會將請求分為兩大類,一類是簡單請求,一類是復雜請求. - 簡單請求一般就是get,post,并且頭部信息也不能帶多余的參數(shù),當瀏覽器發(fā)現(xiàn)是簡單請求時,請求頭會多一個字段origin,origin會指出當前請求屬于哪個域,服務器會根據(jù)這個值決定是否允許跨域。
- 特殊請求,例如put,delete等,則會在發(fā)送請求之前先發(fā)送一個預檢測請求,服務器收到預檢測請求,如果允許跨域,客戶端則能成功發(fā)送請求
27、react框架的優(yōu)點
1、react速度快,因為含有虛擬dom
2、組件化,便于維護
3、單向數(shù)據(jù)流,便于閱讀代碼
4、純粹的javaScript語法,沒有任何專有的react語法
28、vue框架和react框架的區(qū)別
- vue使用html模板進行渲染,只是在html上多了一些特有的屬性,例如v-for,v-if等,而react則是使用jsx語法,jsx語法則是可以再javaScript中寫html
29、什么是回調(diào)函數(shù)?
回調(diào)函數(shù)則是函數(shù)作為參數(shù)傳入另外一個函數(shù),這個作為參數(shù)的函數(shù)會在某個時機被調(diào)用,這就是回調(diào)函數(shù)
30、xss跨站腳本如何進行?防御手段?
如何進行:xss是指惡意攻擊者利用網(wǎng)站沒有對用戶提交的數(shù)據(jù)進行過濾處理,進而添加一些惡意代碼,嵌入到Web頁面,從而利用用戶的身份進行某種動作
防御手段:不信任客戶端提交的任何數(shù)據(jù),只要是客戶端提交的就應該先進行對應的過濾處理。
31、CSRF跨站請求偽造如何進行?防御手段?
如何進行:當用戶在某網(wǎng)頁登錄后,在沒有關閉網(wǎng)頁的情況下,收到惡意鏈接,點擊鏈接,則會利用瀏覽器的cookie把密碼改掉。
防御手段:后端使用jwt技術(shù)驗證token,使用axios請求
32、web上傳漏洞如何進行?防御手段?
如何進行:用戶上傳了一個可執(zhí)行的腳本文件,并通過腳本文件獲得了執(zhí)行服務器端命令的能力
防御手段:1、前后端都對文件后綴名進行限制
2、吧文件上傳目錄的權(quán)限設置為只讀
33、什么是盒子模型?
盒子模型從外到內(nèi)由margin、border、padding、content組成
34、簡要說一下css的元素分類
塊級元素:div,p,h1,form,ul,li;
行內(nèi)元素 : span,a,label,input,img,strong,em;
35、axios有什么好處?
- 支持promise語法
- 攔截請求頭和響應
- 自動轉(zhuǎn)換json數(shù)據(jù)
- 客戶端支持防止csrf
36、冒泡排序
比較相鄰的元素,如果前者比后者大,則交換,大的在右邊,雙重循環(huán),最外層循環(huán)arr.length - 1,內(nèi)層循環(huán)比較相鄰兩個數(shù)的大小,直到吧最大的數(shù)放在最右邊,外層循環(huán)arr.length-1次,然后數(shù)組就會從小到大排列。
37、快排排序
一個數(shù)組里面尋找中間的值作為基準,然后創(chuàng)建兩個空數(shù)組,循環(huán)原數(shù)組,將數(shù)組的每個值跟基準比較,比基準小的存在一個數(shù)組,比基準大的存在一個數(shù)組,然后遞歸執(zhí)行以上操作,最后將兩個數(shù)組合并。
38、為什么要清楚浮動,如何清除?
當給元素設置了浮動float過后,就會產(chǎn)生高度塌陷的情況,就是如果子元素高度大于父元素時,父元素就包含不住子元素了。
- 給父元素添加偽元素清楚浮動
.clear-float:after{
display:block;
content : "";
clear:both;
height:0
}
- 父級盒子觸發(fā)BFC
39、實現(xiàn)數(shù)組去重
- 使用indexOf()去重,首先創(chuàng)建一個空數(shù)組,然后原數(shù)組循環(huán)遍歷,然后判斷如果當前的這個值在創(chuàng)建的新數(shù)組里面沒有,也就是等于-1,那么就添加,如果有,則不添加。
let res = []
for (let i = 0; i < arr.length; i++) {
if (res.indexOf(arr[i]) === -1) {
res.push(arr[i])
}
}
- 使用ES6,Set去重
const arr = [1,2,2,3,4,5,3]
console.log(new Set(arr))
40、談一談箭頭函數(shù)
- 箭頭函數(shù)可以更改this的指向,使this指向上下文
- 箭頭函數(shù)后面只要一條語句時,可以直接寫在后面
- 箭頭函數(shù)需要返回一個對象時,則需要使用({})
41、談一談ES6中的模塊化
ES6的模塊化分為導出(export)與導入(import)兩個模塊。如果希望外部能讀取模塊當中的內(nèi)容,就必須使用export暴露出去,然后在另外一個文件中用Import引入該模塊,一個模塊如果只有一個默認導出的話,就使用export default,引入的時候也可使用as進行重命名。
42、JS原型鏈和原型
- prototype是函數(shù)才有的屬性
- __proto __是每個對象都有的屬性
當我們定義一個函數(shù)的時候,就會產(chǎn)生一個原型對象,當我們使用這個函數(shù)構(gòu)造對象,該對象都會從原型對象中繼承屬性、方法。
當JS尋找該對象的屬性時,先會查找對象本身是否存在該屬性,如果不存在,則會在原型鏈上查找。
因為任何對象都有proto,所以會形成一個鏈條,當我們到頂點的時候,就會發(fā)現(xiàn)proto里面只有object了,因為JS中任何對象都是Object的實例。
43、使用原型鏈實現(xiàn)js繼承
- 思路就是讓子類的原型等于父類的實例,因為父類的實例,就繼承了父類的屬性和方法,然后父類的屬性和方法就定義在子類的原型對象上,這樣子類就實現(xiàn)了繼承父類
//父方法
function SupperFunction(flag1){
this.flag1 = flag1;
}
//子方法
function SubFunction(flag2){
this.flag2 = flag2;
}
//父實例
var superInstance = new SupperFunction(true);
//子繼承父
SubFunction.prototype = superInstance;
//子實例
var subInstance = new SubFunction(false);
//子調(diào)用自己和父的屬性
console.log(subInstance.flag1);
console.log(subInstance.flag2);
44、Vue組件間的通信
- 通常父組件傳遞給子組件使用props
- 子組件傳遞給父組件,使用ref屬性,獲取真實dom
- 子組件使用emit方法
- 使用vux
45、介紹Vuex
vuex能對vue項目進行狀態(tài)管理,主要一般通過state,mutations,action這三個模塊構(gòu)造,state是保存所有數(shù)據(jù),mutations用來保存所有方法,用來改變state的數(shù)據(jù),action一般暴露給用戶使用,可執(zhí)行異步操作,用來觸發(fā)mutatios的方法,用來改變數(shù)據(jù)。一般在頁面中通過mapState來讀取數(shù)據(jù),通過mapActions來操作action。面對復雜的應用我們還需要創(chuàng)建modules,將vuex的store對象拆分成模塊來寫。
46、vuex的優(yōu)缺點
優(yōu)點首先是
- 代碼看得更簡潔了,我們閱讀代碼時,不需要去看組件之間如何傳遞數(shù)據(jù)的,特別是非父子組件傳遞
- 減少了ajax請求,可以從store里面直接取
缺點: - 每次刷新vuex也就會刷新,但是我一般需要長久存儲的數(shù)據(jù),我會存儲在localStorage里面,然后vuex再讀取。
47、vue雙向數(shù)據(jù)綁定原理
實現(xiàn)雙向數(shù)據(jù)綁定主要是結(jié)合發(fā)布者-訂閱者的模式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在數(shù)據(jù)變動時發(fā)給訂閱者,觸發(fā)相應的監(jiān)聽回調(diào),當把一個普通的對象作為data選項時,vue將遍歷它的屬性并且轉(zhuǎn)換為getter/setter。
48、sum求和,可以傳入多個參數(shù)
使用arguments這個API,arguments為函數(shù)傳入的實參,并且會轉(zhuǎn)換為數(shù)組形式,這樣的話就好做了,遍歷實參,相加,最后返回。
49、多維數(shù)組降為一維數(shù)組
將數(shù)組轉(zhuǎn)換為字符串,再切割字符串
let arr = [1, 2, 3, 4, 5, [6, 7, 8, [9, 10, 11, 12, [13, 14, 15, 16]]]]
console.log(arr.toString())
let newArr = arr.toString().split(',')
console.log(newArr)
50、什么是TCP
OSI一共有7層網(wǎng)絡模型,應用層、表示層、會話層、傳輸層、網(wǎng)絡層、數(shù)據(jù)鏈路層、物理層,TCP和UDP是傳輸層的協(xié)議。
TCP無論哪一方向另一方發(fā)送數(shù)據(jù)之前,都會在雙方之間建立一條連接。連接是通過“三次握手”進行初始化的。三次握手的目的是建立可靠的通信連接,確認雙方的發(fā)送與接收是否正常。完成了三次握手,客戶端和服務端就可以開始傳送數(shù)據(jù)了。
三次握手的步驟
- 第一次握手,客戶端發(fā)送請求建立連接,請求報文段
- 第二次握手,服務器收到請求,發(fā)送同意并請求與客戶端建立連接
- 第三次握手,客戶端收到請求,發(fā)送同意與服務器建立連接
當客戶端與服務器通過三次握手建立了TCP連接過后,當數(shù)據(jù)傳送完畢,相應的就要斷開TCP連接了,于是就有了四次分手的步驟。
四次分手的步驟 - 第一次分手,客戶端發(fā)送斷開請求
- 第二次分手,服務器收到斷開請求,發(fā)送同意斷開連接的請求
- 第三次分手,服務器發(fā)送請求斷開連接
- 第四次分手,客戶端收到,發(fā)送同意斷開連接
51、為什么TCP是三次握手,而不是兩次
可能會形成死鎖。假設客戶端給服務器發(fā)送了一個連接請求報文,服務端成功接收并給客戶端發(fā)送了確認應答報文,此時服務端并不能確認該應答報文是否成功到了客戶端,但因為兩次握手,所以這時候服務端就處于成功連接的狀態(tài)了,并給客戶端發(fā)送數(shù)據(jù)。如果客戶端未收到服務端的應答報文,則不知道服務器是否確認好建立連接,甚至不知道自己發(fā)送給服務器的報文是否成功抵達,此時客戶端會認為連接并未成功建立,會忽略服務端發(fā)送過來的任何數(shù)據(jù)。而服務端發(fā)送的數(shù)據(jù)未得到相應超時時,會重復發(fā)送同樣的數(shù)據(jù),這樣就形成了死鎖。
52、TCP和UDP的區(qū)別
TCP是一種面向連接,可靠穩(wěn)定的傳輸協(xié)議,建立連接需要經(jīng)歷三次握手,握手成功才可通信,但是速度比較慢,效率比較低,容易被DOS,DDOS攻擊。
UDP是一種面向無連接,不可靠的傳輸協(xié)議,會直接建立連接,速度快,沒有三次握手的機制,所以會相對安全,但是UDP還是可能會被flood攻擊,在網(wǎng)絡不好的情況,容易發(fā)生丟包。
- 當對網(wǎng)絡通信質(zhì)量有要求時,比如:整個數(shù)據(jù)要準確無誤的傳遞給對方,這往往對于一些要求可靠的應用,比如HTTP,HTTPS,FTP等傳輸文件的協(xié)議,POP,SMTP等郵件的傳輸協(xié)議。常見使用TCP協(xié)議的應用:
1.瀏覽器使用的:HTTP
2.FlashFXP:FTP
3.Outlook:POP,SMTP
4.QQ文件傳輸
UDP 文件傳輸協(xié)議 - 對當前網(wǎng)絡通訊質(zhì)量要求不高的時候,要求網(wǎng)絡通訊速度盡量的快,這時就使用UDP
日常生活中常見使用UDP協(xié)議:
1.QQ語音
2.QQ視頻
HTTP請求報文
HTTP的請求報文包括:請求行(request line)、請求頭部(header)、空行 和 請求數(shù)據(jù)(request data) 四個部分組成。
- 請求行包括: 請求方法,URL(包括參數(shù)信息),協(xié)議版本這些信息
- 請求頭部(Header)
- 空行(CR+LF):請求報文用空行表示header和請求數(shù)據(jù)的分隔
- 請求數(shù)據(jù):GET方法沒有攜帶數(shù)據(jù), POST方法會攜帶一個body
瀏覽器渲染的步驟
- 處理HTML標記并構(gòu)建DOM樹
- 處理CSS標記并構(gòu)建CSSOM樹
- 將DOM與CSSOM合并成一個渲染樹
- 根據(jù)渲染樹來布局,計算每個節(jié)點的布局信息
- 將各個節(jié)點繪制到屏幕上
53、輸入url后發(fā)生了什么
- 用戶輸入url通過DNS解析為對應的IP地址
- TCP連接
- 發(fā)送http請求
- 返回http響應
- 瀏覽器解析渲染頁面
- 斷開TCP連接
54、重繪和重排的區(qū)別
重繪不一定重排,重排必定導致重繪
- 重繪:指一個元素外觀被改變,瀏覽器會根據(jù)元素新屬性重新繪制,使元素呈現(xiàn)新的外觀,比如改變某個元素的背景色、文字顏色、邊框顏色等
- 重排 :當渲染樹的一部分更新并且節(jié)點的尺寸發(fā)生了變化,瀏覽器會使渲染樹種受到影響的部分失效,并且重新構(gòu)造渲染樹。
引發(fā)重排:
1、添加、刪除可見的dom
2、元素的位置改變
3、元素的尺寸改變
4、頁面渲染初始化
5、瀏覽器窗口尺寸改變
優(yōu)化
瀏覽器會維護一個隊列,把所有引起重拍、重繪的操作放入這個隊列,等隊列到了一定的數(shù)量或者到了一定的時間間隔,瀏覽器就會進行處理,這樣多次重排重繪就會進行成一次重排重繪 - 不要一條一條修改dom樣式,寫在定義好css的class中
- 為動畫元件使用絕對定位,修改樣式就不會進行重繪
54、HTML行內(nèi)元素、塊狀元素、行內(nèi)塊狀元素的區(qū)別
使用display可以將三者任意轉(zhuǎn)換,
-
行內(nèi)元素,最常用的就是span
(1)、設置寬高無效
(2)、margin僅左右有效
(3)、不會自動換行 -
塊狀元素,具有代表性的就是div
(1)、能夠識別寬高
(2)、margin和padding均有效
(3)、可以自動換行 -
行內(nèi)塊狀元素,
(1)、能夠識別寬高
(2)、不會自動換行
(3)、默認排列方式從左到右
55、http和https的區(qū)別
https的ssl加密是在傳輸層實現(xiàn)的
- http傳輸?shù)臄?shù)據(jù)都是未加密的,而https是通過ssl協(xié)議對數(shù)據(jù)進行加密處理
- https協(xié)議需要ca證書,費用較高
- http協(xié)議的端口為80,而https協(xié)議端口為443
56、移動端怎么做適配的
- 使用viewport,隨著屏幕寬度變化,頁面也會跟著變化
<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
width設置成了設備的寬度,initial-scale控制了頁面加載時候的縮放等級,maximum-scale為用戶最大縮放值,user-scalabel是否允許用戶進行縮放
57、box-sizing屬性
box-sizing是更改盒子模型基準,有兩個選項,一個是content-box,一個是border-box。還有一個是inherit默認的是content-box。
其實兩者的區(qū)別也就是盒子的寬高是否包含border和padding,如果是content-box那么寬高就是固定的,如果是border-box,那么寬高就是設定的寬高再減去border和padding,就是這個盒子的寬高。
inherit是繼承父元素的box-sizing。
58、宏任務與微任務
宏任務例如,script,setTimeout,setInterval
微任務例如Promise.then
執(zhí)行一個宏任務,執(zhí)行過程中如果遇到微任務,就會將微任務添加到微任務的隊列,宏任務執(zhí)行完畢過后,會立即按順序執(zhí)行微任務,當這個宏任務執(zhí)行完畢后,開始進行渲染,渲染完畢后,開始下一個宏任務。
59、BFC是什么?
BFC是塊級格式化上下文,是用于布局塊級盒子的一塊渲染區(qū)域。
一般觸發(fā)BFC的條件
- 根元素,即html元素
- float的值不為none
- overflow的值為hideen
- display的值為inline-block
- position的值為absolute或者fixed
作用 - 可以阻止元素被浮動的元素覆蓋
- 清除浮動
- 解決同一個BFC區(qū)域的垂直方向margin塌陷的問題
屬于同一個BFC的兩個相鄰的box的margin會重疊,以大的為主。要想解決這個問題,可以將兩個盒子分為不同的BFC中。
60、AST抽象語法樹
抽象語法樹,是源代碼的抽象語法結(jié)構(gòu)的樹狀表現(xiàn)形式,一般指編程語言的源代碼
61、put、post、patch的區(qū)別
post用來創(chuàng)建資源,多次執(zhí)行,會導致多條資源重復創(chuàng)建
put一般用來更新已知資源
patch對已知資源進行局部更新
62、vue-router原理
vue-router是應用在單頁面應用中。
單頁面:第一次進入頁面的時候會請求一個html文件,當url變化時,js會感知到,js會將當前的頁面清除掉,判斷當前url需要顯示哪個組件,清除不需要的,顯示需要的組件。
實現(xiàn)原理:更新視圖但不重新請求頁面
前端路由主要有兩種模式,hash模式和history模式,hash會在域名后面加一個#號,hash雖然會出現(xiàn)在url中,但不會包括在http請求中而history則不存在,沒有#號,這種模式需要服務端支持。服務端接收到請求后,都指向同一個html文件。
vue-router也是利用了這兩個特性來實現(xiàn)前端路由
63、Node.js中間件
中間件主要是指封裝所有http請求細節(jié)處理的方法,比如記錄日志、權(quán)限驗證、異常處理等。
中間件是從http請求發(fā)起到響應結(jié)束過程中的處理方法,通常需要對請求和響應進行處理。
64、什么是DNS、FTP,基于什么協(xié)議?
DNS(Domain Name System):域名解析協(xié)議,端口號:53;通過域名解析獲得域名所對應的IP
FTP(File Transfer Protocol):文件傳輸協(xié)議,端口號:21;用戶可通過客戶機程序向遠程主機上傳文件;或從遠程主機上下載文件。
- FTP用的TCP協(xié)議。
- DNS域名解析時用的UDP協(xié)議,DNS區(qū)域傳輸?shù)臅r候使用的TCP協(xié)議。
輔域名服務器會定時(一般3小時)向主域名服務器進行查詢以便了解數(shù)據(jù)是否有變動,這就是區(qū)域傳輸。
65、Vue生命周期
beforeCreate : 組件創(chuàng)建之前
created:組件創(chuàng)建后
beforeMount:組件掛載之前
mounted:掛載完成
beforeUpdate:數(shù)據(jù)更新前
updated:數(shù)據(jù)更新后
beforeDestory:實例銷毀之前
destored:實例銷毀后
65、防抖和節(jié)流
防抖:讓某個時間期限內(nèi),事件處理函數(shù)只執(zhí)行一次,例如獲取滾動條位置,就要每3S執(zhí)行一次,可以使用定時器來實現(xiàn),我們可以在一個方法里面使用閉包來存儲一個狀態(tài),定時器每次執(zhí)行,都會返回一個類似于ID,ID是用來關閉定時器的,每次執(zhí)行該方法,如果有ID就清除該ID的定時器,并且創(chuàng)建一個新的定時器。
function dbbounce(fn,delay){
let timer = null
return function(){
//setTimeout每次執(zhí)行,會返回給我一個特殊的值,這個值是用來關閉定時器的,每次執(zhí)行該方法時,如果有timer就清楚上個定時器
//如果沒有就執(zhí)行定時器
if(timer){
clearTimeout(timer)
}
timer = setTimeout(fn,delay)
}
}
function showTop (){
var scrollTop = document.documentElement.scrollTop
console.log('滾動距離',scrollTop)
}
window.onscroll = dbbounce(showTop,3000)
節(jié)流:函數(shù)執(zhí)行一次后,在某個時間段內(nèi)暫時失效,過段時間再重新激活,使用閉包存儲一個布爾類型的狀態(tài),每次執(zhí)行該方法時,如果狀態(tài)為false則不執(zhí)行,如果狀態(tài)為true,則會使狀態(tài)先等于false,達到冷卻的效果,再調(diào)用定時器,定時器完成過后,會將狀態(tài)改為true。
function throttle(fn, delay) {
let valid = true
return function () {
//類似于技能能卻,執(zhí)行完一次,有間隔時間,時間走完了,才能再執(zhí)行
//滾動時,如果狀態(tài)為false就不執(zhí)行,如果狀態(tài)為true,在間隔期間設置狀態(tài)為false,然后在執(zhí)行定時器,定時器執(zhí)行完,將狀態(tài)改為true
if (!valid) {
return false
}
valid = false
setTimeout(() => {
fn()
valid = true
}, delay)
}
}
function showTop() {
var scrollTop = document.documentElement.scrollTop
console.log('滾動距離', scrollTop)
}
window.onscroll = throttle(showTop, 2000)
66、ajax,axios和fetch有什么區(qū)別
ajax
- 本身針對MVC的編程,不符合現(xiàn)在MVVM的框架
- JQuery整個項目太大,單純使用ajax卻要引入整個JQuery
axios - 支持Promise語法
- 客戶端支持防止CSRF
- 攔截請求頭和響應
- 自動轉(zhuǎn)換json數(shù)據(jù)
fetch - fetch只對網(wǎng)絡請求報錯,對400,500都當做成功的請求,需要封裝去處理。
67、為什么JS是單線程的?
JS作為瀏覽器腳本語言,JS的主要用途是與用戶互動,以及操作DOM。這決定了只能是單線程,否則會帶來復雜的同步問題,比如,假如JS有兩個線程,一個線程在某個DOM節(jié)點上添加內(nèi)容,另一個線程刪除了這個節(jié)點,這時候瀏覽器就不知道應該以哪個為準。
68、路由懶加載
路由懶加載也叫按需加載,即在需要的時候進行加載,單頁應用,利用webpack打包后的文件會非常大,造成進入首頁時,需要加載的內(nèi)容過多,時間過長,會出現(xiàn)長時間白屏,而運用懶加載可以將頁面進行劃分,需要的時候加載頁面,減少首頁加載用時。
routes: [
{
path: "/",
name: "home",
component: Home
},
{
path: "/about",
name: "about",
component: () => import(/* webpackChunkName: "about" */ "./views/About.vue")
}
]
69、前端項目優(yōu)化
- 路由懶加載
- 開啟nginx的gzip壓縮
- 抽取公用組件和方法,清除冗余代碼
- 使用壓縮工具壓縮圖片,例如tinypng
72、水平垂直居中
flex布局, justify-content: center; align-items: center;
給父元素設置相對定位,給子元素設置絕對定位
#father {
width: 500px;
height: 300px;
background-color: skyblue;
position: relative;
}
#son {
background-color: green;
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
}
73、兩個等號和三個等號的區(qū)別
- 三個等號稱為等同符,當兩邊值類型相同時,直接比較值,若類型不相同,直接返回false
- 兩個等號稱為等值符,當?shù)忍杻蛇咁愋拖嗤瑫r,直接比較值,若不相同,則先轉(zhuǎn)化為類型相同的值,在進行比較。
類型轉(zhuǎn)換規(guī)則:
(1)如果等號兩邊是boolean、string、number三者中任意兩者進行比較時,優(yōu)先轉(zhuǎn)換為數(shù)字進行比較。
(2)如果等號兩邊出現(xiàn)了null或undefined,null和undefined除了和自己相等,就彼此相等
74、常用操作字符串方法
- split(sep,limit):將字符串分割為字符數(shù)組,limit為從頭開始執(zhí)行分割的最大數(shù)量
- slice(start,end):返回字符索引在start和end(不含)之間的子串
- substr(start,length):從字符索引start的位置開始,返回長度為length的子串
- substring(from,to):返回字符索引在from和to(不含)之間的子串
- charAt(index):返回指定索引處的字符串
- charCodeAt(index):返回指定索引處的字符的Unicode的值
- lastIndexOf(str):返回str在父串中最后一次出現(xiàn)的位置,若沒有則返回-1
- indexOf(str):返回str在父串中第一次出現(xiàn)的位置,若沒有則返回-1
75、常用操作數(shù)組方法
- push(),向數(shù)組的末尾添加元素
- pop(),刪除數(shù)組中最后一個元素
- unshift(),向數(shù)組開頭添加元素
- shift(),刪除數(shù)組第一個元素
- splice(index,howmany,item1....):添加/刪除數(shù)組元素,index規(guī)定位置,howmany為刪除的數(shù)量,item1......可選向數(shù)組添加的新項目
- sort(),對數(shù)組元素進行排序,并返回這個數(shù)組,sort的比較函數(shù)有兩個參數(shù),返回a-b則使升序,返回b-a則是降序
- slice(start,end):返回數(shù)組下標在start和end(不含)之間的值
- indexOf() 查找數(shù)組是否存在某個元素,返回下標
- lastIndexOf() 查找指定元素在數(shù)組中的最后一個位置
- includes() 查找數(shù)組是否包含某個元素 返回布爾
- filter(function) 過濾原始數(shù)組,返回新數(shù)組
function(currentValue,index,arr): 數(shù)組中每個元素需要調(diào)用的函數(shù)。
// 回調(diào)函數(shù)的參數(shù)
- currentValue(必須),數(shù)組當前元素的值
- index(可選), 當前元素的索引值
- arr(可選),數(shù)組對象本身
76、什么是事件委托
事件委托就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件。
當我們有很多dom需要添加處理事件,比如ul下面有很多l(xiāng)i,我們給每個li都要添加相同的點擊事件,通常會用for循環(huán),給它們添加點擊事件,這有很大的性能弊端
77、call、bind、apply的區(qū)別?
- bind 返回一個函數(shù), 第一個參數(shù)是改變this指向的對象 直接傳參
- apply 對函數(shù)的直接調(diào)用, 第一個參數(shù)是改變this指向的對象 參數(shù)用數(shù)組包裹
- call 對函數(shù)直接調(diào)用,第一個參數(shù)是改變this指向的對象 直接傳參
78、深拷貝和淺拷貝的區(qū)別
它們最根本的區(qū)別在于是否真正獲取了一個對象的復制實體,而不是引用
淺拷貝現(xiàn)在可以使用Object.assign快速實現(xiàn)
Object.assign()只有源對象,沒有目標對象時為淺拷貝
JSON.parse(JSON.stringify())可以實現(xiàn)深拷貝
79、JSON.parse和JSON.stringify的區(qū)別
- JSON.parse()【從一個字符串中解析出json對象】
- JSON.stringify()【從一個對象中解析出字符串】
80、JS動畫和CSS3動畫差異性
css3后來添加了transform動畫函數(shù)
css3動畫與js動畫的區(qū)別:
js功能涵蓋面比css3廣
css3比js更易實現(xiàn)
css3存在兼容問題 js不存在兼容問題
81、join("")和toString()的區(qū)別
join(“”)轉(zhuǎn)換為字符串時,會將逗號去掉
82、JS基本數(shù)據(jù)類型
基礎類型:Undefined,Null,Boolean,Number,String,Symbol
引用類型:Object,Array
symbol生成的是一個全局唯一的值,Symbol(1) === Symbol(1)是為false的。
83、ES6新特性
- promise
- async/await
- class
- 箭頭函數(shù)
- 擴展運算符
84、談談ES6中的class
首先class是用來創(chuàng)建類的,在傳統(tǒng)的js中,沒有類的概念。class的作用讓原型對象的寫法更加清晰
- 首先我們在類里面寫方法時,方法時直接定義在原型對象上面
- constructor就相當于構(gòu)造函數(shù),接受參數(shù)
- 類必須使用new調(diào)用
85、擴展運算符
擴展運算符就是遍歷目標對象,拷貝到當前對象中
擴展運算符如果目標對象中含有引用數(shù)據(jù)類型,則使用擴展運算符拷貝出來的則是淺拷貝。
86、vue和react的事件綁定對比
首先vue的特色是雙向綁定,而react是單向綁定,其實vue的雙向綁定也可以使用單向綁定加上onChange事件監(jiān)聽來實現(xiàn)。
87、Hooks是什么
原來我們寫一個組件需要去聲明一個類,但是使用了hooks就不需要了,就直接使用function創(chuàng)建一個函數(shù),然后使用useState來管理狀態(tài),然后在返回html模板就可以成功創(chuàng)建一個組件了
88、webpack是什么,loader是什么?
webpack是前端構(gòu)建的一個工具,loader其實就是提供了打包方案,就比如webpack不知道怎么打包圖片模塊、css模塊、js模塊時,就會使用各種loader來幫助Webpack打包
比如:
image-loader:加載并且壓縮圖片文件
babel-loader:把 ES6 轉(zhuǎn)換成 ES5
css-loader:加載 CSS,支持模塊化、壓縮、文件導入等特性
eslint-loader:通過 ESLint 檢查 JavaScript 代碼
plugin其實主要是監(jiān)聽一些webpack事件的,然后做優(yōu)化
89、CSS可繼承的屬性
1、字體系列屬性,例如字體粗細,風格,大小
2、文本系列屬性,例如行高,文本顏色
無繼承的屬性:display,背景屬性,盒子模型的屬性,定位屬性
談一談RCM自動升級這個項目?
公司每次有升級包,就需要在這創(chuàng)建任務,上傳升級包,然后對任務可視化操作,顯示進度和狀態(tài)信息等,可以編輯,可以查看詳情,可以下載對比文件等,除此之外還有一些基準文件配置、郵箱配置、常用工具等功能。
1、表單聯(lián)動太多,開始想著用change方法來監(jiān)聽數(shù)據(jù),最后編輯的時候,因為需要初始化數(shù)據(jù),最后才采用的watch的深度監(jiān)聽
2、formdata傳遞數(shù)組,當時后端需求就是我需要傳一個數(shù)組,這個數(shù)組每一個對象里面都包含的有文件,所以我選擇采
用Formdata形式傳遞數(shù)據(jù)給后臺,而formdata添加數(shù)據(jù)又是key,value的形式,所以我添加時key就是將數(shù)組轉(zhuǎn)為語義化來命名。
3、下載瀏覽器默認打開的文件。
談一談你做項目遇到的困難
1、最開始做項目的時候,跨域問題以及服務器配置
2、前期對數(shù)據(jù)的處理,例如數(shù)組,或者對象類型的方法了解的太少