背景
我18年本科畢業(yè)裙秋,年前已有換工作想法,一直沒(méi)有付諸行動(dòng)缨伊,疫情爆發(fā)后回到老家摘刑,年后開(kāi)始找工作,對(duì)于自己水平不是很清楚刻坊,之前找工作一直都挺順利的枷恕。大學(xué)畢業(yè)沒(méi)有留在實(shí)習(xí)單位繼續(xù)做前端開(kāi)發(fā),那時(shí)候三大框架已經(jīng)開(kāi)始流行了谭胚,實(shí)習(xí)公司用的還是jquery徐块。回老家學(xué)了一個(gè)月的車(chē)和vue灾而、小程序后胡控,憑著自學(xué)做的項(xiàng)目找了一周工作入職第一家公司。面試經(jīng)驗(yàn)比較少旁趟,想著多面面看看對(duì)方公司的反饋昼激。年前還沒(méi)開(kāi)始準(zhǔn)備就面了騰訊,終止于二面锡搜,所以說(shuō)還是要好好復(fù)習(xí)再面大廠(chǎng)橙困。
面的崗位以?xún)扇隇橹鳎m然我是1.5年經(jīng)驗(yàn)耕餐,但有的崗位年限要求沒(méi)那么嚴(yán)格也可以試試纷宇,尤其寫(xiě)的優(yōu)秀者可放寬年限要求。面了四五家蛾方,有上市公司像捶,也有小公司,都是遠(yuǎn)程面試桩砰。
html拓春、css部分
如何理解html語(yǔ)義化
html語(yǔ)義化是指從代碼上展示頁(yè)面的結(jié)構(gòu),而不是從最終視覺(jué)上來(lái)表現(xiàn)結(jié)構(gòu)亚隅。
- 表現(xiàn)形式
html5新標(biāo)簽:
header-頁(yè)眉硼莽、footer-頁(yè)腳、aside-附屬信息、nav-導(dǎo)航鏈接懂鸵、section偏螺、article,
caption-表格標(biāo)題匆光、thead-表頭套像、tbody-表格內(nèi)容、tfoot-表尾
h1~h6终息,作為標(biāo)題使用夺巩,且重要性遞減
- 作用
有利于構(gòu)建良好的html架構(gòu),有利于搜索引擎建立索引和抓取
頁(yè)面結(jié)構(gòu)清晰周崭,有利于代碼的維護(hù)和管理
有利于不同設(shè)備(盲人閱讀器柳譬、屏幕閱讀器)的解析
- px,em续镇,rem區(qū)別
px 相對(duì)長(zhǎng)度單位美澳,是相當(dāng)于顯示器的分辨率而言的
em 相對(duì)長(zhǎng)度單位,相對(duì)父元素的字體大小而言的
rem 相對(duì)長(zhǎng)度單位摸航,相對(duì)html根元素的字體大小而言的制跟,css3新增元素
- 盒子模型
IE盒子模型 寬度=內(nèi)容寬度+padding *2+border *2
w3c盒子模型 寬度=內(nèi)容寬度
通過(guò)box-sizing切換,默認(rèn)為content-box(w3c盒子模型)忙厌,border-box時(shí)為IE盒子模型
- BFC
塊級(jí)格式化上下文,讓BFC里面的元素與外面元素隔離江咳,使里外元素的定位不會(huì)相互影響逢净。觸發(fā)條件:
根元素
overflow不為visible
float
position:absolute或fixed
display:inline-block或table
應(yīng)用:
防止垂直方向margin重疊
不和浮動(dòng)元素重疊
清除元素內(nèi)部浮動(dòng)
- target和currentTarget區(qū)別
target是事件的真正目標(biāo)
currentTarget是事件處理程序注冊(cè)的元素
- document.ready和window.onload區(qū)別
document.ready是dom樹(shù)加載后執(zhí)行,而window.onload是整個(gè)頁(yè)面資源加載完后執(zhí)行歼指,所以document.ready比window.onload先執(zhí)行
- 事件流
DOM2事件流分為三個(gè)部分:事件捕獲爹土、處于目標(biāo)、事件冒泡踩身。
事件冒泡是指事件從執(zhí)行的元素開(kāi)始往上層遍歷執(zhí)行
事件捕獲是指事件從根元素開(kāi)始從外向里執(zhí)行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn">click Me</button>
<script>
let btn=document.getElementById('btn');
btn.onclick=fucntion(e){
console.log(e)
}
</script>
</body>
</html>
點(diǎn)擊按鈕后胀茵,事件冒泡的執(zhí)行順序是:button->body->html->document
事件捕獲的執(zhí)行順序則相反:document->html->body->button
- doctype作用,嚴(yán)格模式和混合模式的區(qū)別
<!doctype>聲明位于文檔的最前面挟阻,在html之前顯示琼娘。用于告訴瀏覽器的解析器,用什么文檔類(lèi)型規(guī)范來(lái)解析文檔附鸽。嚴(yán)格模式默認(rèn)用瀏覽器支持的最高版本解析脱拼,混合模式以寬松的向后兼容的方式解析,doctype不存在或格式不正確時(shí)會(huì)讓文檔以混雜模式呈現(xiàn)
水平垂直居中
//方法一
display:flex;
justify-content:center;
align-items:center;
//方法二
display:table;
vertical-align:center;
//方法三:適用于已知寬高且父元素定位不為static
postion:absolute;
width:100px;
height:100px;
top:50%;
left:50%;
margin:-50px 0 0 -50px;
//方法四
position:absolute;
top:50%;
left:50%;
transform:translateY(-50%) translateX(-50%);
//方法五:適用于行內(nèi)元素
display:inline-block;
width:100px;
height:100px;
text-align:center;
line-height:100px;
//方法六:適用于塊級(jí)元素
display:block;
height:100px;
margin:0 auto;
line-height:100px;
回流和重繪區(qū)別
回流:當(dāng)渲染樹(shù)中元素尺寸坷备、結(jié)構(gòu)或者某些屬性發(fā)生變化時(shí)熄浓,瀏覽器重新渲染部分或全部頁(yè)面的情況叫回流。下列元素改變引發(fā)回流:
getBoundingClientRect()
scrollTo()
scrollIntoView()或者scrollIntoViewIfneeded
clientTop省撑、clientLeft赌蔑、clientWidth俯在、clientHeight
offsetTop、offsetLeft娃惯、offsetWidth跷乐、offsetHeight
scrollTop、scrollLeft石景、scrollWidth劈猿、scrollHeight
getComputedStyle()
重繪:當(dāng)頁(yè)面中元素樣式變化不會(huì)改變它在文檔流中的位置時(shí),即不會(huì)使元素的幾何屬性發(fā)生變化潮孽,瀏覽器會(huì)將新樣式賦給它并重新繪制頁(yè)面(比如color揪荣、backgroundColor)
頻繁回流和重繪會(huì)引起性能問(wèn)題
避免方法:
減少table布局使用
減少css表達(dá)式的使用(如calc())
減少DOM操作,用documentFragment代替
將元素設(shè)為display:none;操作結(jié)束后把它顯示回來(lái)往史,因?yàn)閐isplay:none不會(huì)引發(fā)回流重繪
避免頻繁讀取會(huì)引發(fā)回流重繪的元素仗颈,如果需要最好是緩存起來(lái)
對(duì)復(fù)雜動(dòng)畫(huà)元素使用絕對(duì)定位,使它脫離文檔流
減少使用行內(nèi)樣式
js部分
- setTimeout椎例、setInterval區(qū)別
兩者都是定時(shí)器挨决,設(shè)定一個(gè)150ms后執(zhí)行的定時(shí)器不代表150ms后定時(shí)器會(huì)執(zhí)行,它表示代碼在150ms內(nèi)會(huì)被加入隊(duì)列订歪,如果這個(gè)時(shí)間點(diǎn)隊(duì)列沒(méi)有其他邏輯在執(zhí)行脖祈,表面上看代碼在精確時(shí)間執(zhí)行了。在隊(duì)列中有其他邏輯時(shí)刷晋,代碼等待時(shí)間會(huì)超過(guò)150ms
setTimeout 只執(zhí)行一次
setInterval 執(zhí)行多次盖高,屬于重復(fù)定時(shí)器
- 防抖節(jié)流
節(jié)流:多次觸發(fā)事件時(shí),一段時(shí)間內(nèi)保證只調(diào)用一次眼虱。以動(dòng)畫(huà)為例喻奥,人眼中一秒播放超過(guò)24張圖片就會(huì)形成動(dòng)畫(huà),假設(shè)有100張圖片捏悬,我們一秒播放100張過(guò)于浪費(fèi)撞蚕,一秒播放24張就夠了。
防抖:持續(xù)觸發(fā)事件后过牙,時(shí)間段內(nèi)沒(méi)有再觸發(fā)事件甥厦,才調(diào)用一次。以坐電梯為例寇钉,電梯10s運(yùn)行一次矫渔。如果快要運(yùn)行時(shí)進(jìn)來(lái)一個(gè)人,則重新計(jì)時(shí)摧莽。
//節(jié)流
function throttle(fn,delay) {
let timer=null
return function () {
if(!timer){
timer=setTimeout(()=>{
fn.call(this,arguments)
timer=null
},delay)
}
}
}
//防抖
function debounce(fn,delay) {
let timer=null
return function () {
if(timer){
clearTimeout(timer)
}
timer=setTimeout(()=>{
fn.call(this,arguments)
},delay)
}
}
深淺拷貝
淺拷貝:
concat()
Object.assign()
slice()
手寫(xiě)
function shallowCopy(obj){
if(typeof obj==='function'&& obj!==null){
let cloneObj=Array.isArray(obj)?[]:{}
for(let prop in obj){
if(obj.hasOwnProperty(prop)){
cloneObj[prop]=obj[prop]
}
}
return cloneObj
}
else{
return obj
}
}
深```貝:
JSON.stringfy(JSON.parse())
上面的方法不能解決循環(huán)引用庙洼,也不能顯示函數(shù)或undefined
手寫(xiě)深拷貝
var deepClone=(obj,map=new WeakMap())=>{
if(map.get(obj)){
return obj
}
let newObj;
if(typeof obj==='object'&& obj!==null){
map.set(obj,true)
newObj=Array.isArray(obj)?[]:{};
for(let item in obj){
if(obj.hasOwnProperty(item)){
newObj[item]=deepClone(obj[item])
}
}
return newObj;
}
else {
return obj;
}
};
繼承
我覺(jué)得沒(méi)啥好說(shuō)的,紅寶書(shū)里介紹的挺詳細(xì)了,不過(guò)es6的class多了個(gè)extends
//原型鏈繼承
function Parent(){
this.property=true;
}
Parent.prototype.getValue=function(){
return this.property;
}
function Son(){
this.subProperty=false;
}
Son.prototype=new Parent();
let instance=new Son();
原型鏈繼承繼承了原型的屬性和方法油够,但是有幾個(gè)缺點(diǎn):
原型鏈中包括引用類(lèi)型的值時(shí)蚁袭,會(huì)被所有實(shí)例共享
不能實(shí)現(xiàn)子類(lèi)向超類(lèi)的構(gòu)造函數(shù)中添加屬性
由此產(chǎn)生了借用構(gòu)造函數(shù)繼承,解決了原型鏈繼承的缺點(diǎn),它自身又有缺點(diǎn):不能實(shí)現(xiàn)函數(shù)復(fù)用
//借用構(gòu)造函數(shù)繼承
function Parent(){
this.property=true;
}
function Son(){
Parent.call(this);
}
復(fù)制代碼//組合繼承
function Parent(){
this.property=true;
this.colors=['red','purple','orange']
}
Parent.prototype.getPro=function(){
return this.property;
}
function Son(property,name){
Parent.call(this,property);
this.name=name;
}
Son.prototype=new Parent()
組合繼承避免了原型鏈和借用構(gòu)造函數(shù)的缺陷,是最常用的繼承之一
//原型繼承
var a = {
friends : ["yuki","sakura"]
};
var b = Object.create(a);
b.friends.push("ruby");
var c = Object.create(a);
c.friends.push("lemon");
alert(a.friends);//"yuki,sakura,ruby,lemon"
原型繼承缺點(diǎn)跟原型鏈繼承一樣石咬,也是引用類(lèi)型的屬性會(huì)被所有實(shí)例共享
//寄生式繼承,可以類(lèi)比設(shè)計(jì)模式的工廠(chǎng)模式
function createAnother(obj){
var clone = object(obj);
clone.sayHi = function(){
console.log("hello");
};
return clone;
}
寄生式繼承不能做到函數(shù)復(fù)用
//寄生組合式繼承
function Parent(name){
this.name=name;
this.colors=['red','white','gray']
}
Parent.prototype.getName=function(name){
this.name=name
}
function Son(name,age){
Parent.call(this,name);//第二次調(diào)用Parent()
this.age=age;
}
Son.prototype=new Parent()//第一次調(diào)用Parent()
Son.prototype.constructor=Son;
Son.prototype.getAge=function(){
return this.age;
}
寄生組合式繼承避免了在子實(shí)例上創(chuàng)建多余的屬性揩悄,又能保持原型鏈不變,還能正常使用instanceof()和isPrototypeOf()鬼悠,是最理想的繼承方式删性。
es6方法的繼承:通過(guò)extends實(shí)現(xiàn)
class Parent(){
constructor(){}
}
class Son extends Parent(){
constructor(){
super()
}
}
了解的es6新特性
說(shuō)的越多越好,比如Promise焕窝,箭頭函數(shù)蹬挺、數(shù)組擴(kuò)展:includes()、find()它掂、findIndex()...,Symbol巴帮、Map、Set... 我就不羅嗦了虐秋,看阮一峰的ES6就好了es6的class的es5的類(lèi)有什么區(qū)別
1.es6 class內(nèi)部定義的方法都是不可枚舉的
2.es6 class必須用new調(diào)用
3.es6 class不存在變量提升
4.es6 class默認(rèn)使用嚴(yán)格模式
5.es6 class子類(lèi)必須在父類(lèi)的構(gòu)造函數(shù)中調(diào)用super(),才有this對(duì)象榕茧;而es5是先有子類(lèi)的this,再調(diào)用父類(lèi)的方法應(yīng)用再在this上面
數(shù)組去重
//方法一 使用ES6的Set
function filterArr(arr) {
return new Set(arr)
}
//方法二:filter+indexOf()判斷客给,如果數(shù)字不是第一次出現(xiàn)則被過(guò)濾
function filterArr2(arr){
let newArr=arr.filter((item,index)=>{
return arr.indexOf(item)===index
})
console.log(newArr)
}
//方法三:雙重for循環(huán)
function filterArr3(arr){
let isRepeat,newArr=[];
for(let i=0;i<arr.length;i++){
isRepeat=false
for(let j=i+1;j<arr.length;j++){
if(arr[i]===arr[j]){
isRepeat=true
break
}
}
if(!isRepeat){
newArr.push(arr[i])
}
}
return newArr
}
//方法四:哈希表
function filterArr4(arr){
let seen={}
return arr.filter(function (item) {
return seen.hasOwnProperty(item)?false:(seen[item]=true)
});
}
//方法五:sort排序用押,相同的數(shù)字會(huì)排在相鄰n個(gè)位置
function filterArr5(arr){
let lastArr=[]
const newArr=arr.sort((a,b)=>{
return a-b
})
for(let i=0;i<newArr.length;i++){
if(newArr[i]!==newArr[i+1]){
lastArr.push(newArr[i])
}
}
return lastArr
}
this
this綁定函數(shù)的執(zhí)行上下文,誰(shuí)調(diào)用它靶剑,它就指向誰(shuí)蜻拨。分為默認(rèn)綁定、顯式綁定抬虽、隱式綁定官觅、apply/call/bind綁定纵菌、new綁定和箭頭函數(shù)綁定
默認(rèn)綁定:嚴(yán)格模式下this指向undefined阐污,非嚴(yán)格模式this指向window
call、apply咱圆、bind都可以改變this的指向笛辟,但是apply接收參數(shù)數(shù)組,call接收的是參數(shù)列表 bind接收的是參數(shù)列表序苏,但是apply和call調(diào)用就執(zhí)行手幢,bind需要手動(dòng)執(zhí)行
箭頭函數(shù)綁定:箭頭函數(shù)的this是父作用域的this,不是調(diào)用時(shí)的this,其他方法的this是動(dòng)態(tài)的忱详,而箭頭函數(shù)的this是靜態(tài)的
window.name='a'
const obj={
name:'b',
age:22,
getName:()=>{
console.log(this)
console.log(this.name)
},
getAge:function(){
setTimeout(()=>{
console.log(this.age)
})
}
}
obj.getName();//window a
obj.getAge();//22
優(yōu)先級(jí):箭頭函數(shù)>new綁定>顯示綁定/apply/bind/call>隱式綁定>默認(rèn)綁定
箭頭函數(shù)和普通函數(shù)區(qū)別
箭頭函數(shù)沒(méi)有prototype围来,所以箭頭函數(shù)本身沒(méi)有this
箭頭函數(shù)的this指向在定義的時(shí)候繼承自外層第一個(gè)普通函數(shù)的this
箭頭函數(shù)沒(méi)有arguments,普通函數(shù)有
使用new調(diào)用箭頭函數(shù)會(huì)報(bào)錯(cuò)
不可以使用yield命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)监透。
new的原理
var obj={};
obj._proto_=F.prototype;
F.call(obj);
創(chuàng)建一個(gè)空對(duì)象
this變量引用該對(duì)象桶错,同時(shí)還繼承了這個(gè)函數(shù)的原型
屬性和方法被加入到引用的對(duì)象里
新創(chuàng)建的對(duì)象由this引用,最后隱式返回this
瀏覽器事件循環(huán)和node事件循環(huán)
瀏覽器事件循環(huán):
同步任務(wù)在主線(xiàn)程執(zhí)行胀蛮,在主線(xiàn)程外還有個(gè)任務(wù)隊(duì)列用于存放異步任務(wù)
主線(xiàn)程的同步任務(wù)執(zhí)行完畢院刁,異步任務(wù)入棧,進(jìn)入主線(xiàn)程執(zhí)行
上述的兩個(gè)步驟循環(huán)粪狼,形成eventloop事件循環(huán) 瀏覽器的事件循環(huán)又跟宏任務(wù)和微任務(wù)有關(guān)退腥,兩者都屬于異步任務(wù)。
js異步有一個(gè)機(jī)制再榄,就是遇到宏任務(wù)狡刘,先執(zhí)行宏任務(wù),將宏任務(wù)放入任務(wù)隊(duì)列不跟,再執(zhí)行微任務(wù)颓帝,將微任務(wù)放入任務(wù)隊(duì)列,他倆進(jìn)入的不是同一個(gè)任務(wù)隊(duì)列窝革。往外讀取的時(shí)候先從微任務(wù)里拿這個(gè)回調(diào)函數(shù)购城,然后再?gòu)暮耆蝿?wù)的任務(wù)隊(duì)列上拿宏任務(wù)的回調(diào)函數(shù)
宏任務(wù):
script
定時(shí)器 setTimeout setInterval setImmediate
微任務(wù):
promise
process.nextTick()
MutationObserver
node事件循環(huán):
timer階段
I/O 異常回調(diào)階段
空閑預(yù)備階段
poll階段
check階段
關(guān)閉事件的回調(diào)階段
手寫(xiě)系列
遠(yuǎn)程面試沒(méi)考手寫(xiě)虐译,但我覺(jué)得還是要會(huì)手寫(xiě)promise
我的是簡(jiǎn)易版本
function myPromise(executor) {
let self=this;
self.status='pending';
self.value=undefined;
self.reason=undefined;
function resolve(value) {
if(self.status==='pending'){
self.value=value
self.status="resolved"
}
}
function reject(reason) {
if(self.status==='pending'){
self.reason=reason
self.status=status
}
}
try{
executor(resolve,reject)
}
catch (e) {
reject(e)
}
}
手寫(xiě)bind
Function.prototype.myBind=function(context,...args){
const fn=this
args=args?args:[]
return function newFn(...newFnArgs) {
if(this instanceof newFn){
return new fn(...args,...newFnArgs)
}
return fn.apply(context,[...args,...newFnArgs])
}
}
手寫(xiě)call瘪板、apply
Function.prototype.myCall=function(context,...args){
context=context||window
args=args?args:[]
const key=Symbol()
context[key]=this
const result=context[key](...args)//通過(guò)隱式綁定的方式調(diào)用函數(shù)
delete context[key]//刪除添加的屬性
return result//返回函數(shù)調(diào)用的返回值
}
Function.prototype.myApply=function(context,args){
context=context||window
args=args||[]
const key=Symbol()
context[key]=this
const result=context[key](...args)
delete context[key]
return result
}
- vue部分
vue的雙向綁定原理
vue的雙向綁定是通過(guò)數(shù)據(jù)劫持和發(fā)布者-訂閱者模式實(shí)現(xiàn)的,數(shù)據(jù)劫持又是通過(guò)Object.defineProperty()實(shí)現(xiàn)的
Object.defineProperty(data,'a',{
enumerable:true,//是否可枚舉
writable:true,//是否可寫(xiě)
configurable:true,//是否可配置
get(){
return this.a//讀取data對(duì)象的a屬性時(shí)漆诽,觸發(fā)get方法
},
set(val){
this.a=val;//修改data對(duì)象的a屬性時(shí)侮攀,觸發(fā)set方法
}
})
mvvm的數(shù)據(jù)變化更新視圖,是通過(guò)Object.defineProperty()實(shí)現(xiàn)的厢拭;視圖更新變化數(shù)據(jù)兰英,是通過(guò)事件監(jiān)聽(tīng)實(shí)現(xiàn)的。
發(fā)布者-訂閱者的實(shí)現(xiàn)過(guò)程:
- 實(shí)現(xiàn)一個(gè)監(jiān)聽(tīng)器Observer供鸠,劫持并監(jiān)聽(tīng)所有屬性畦贸,如果有變化,就通知訂閱者
- 實(shí)現(xiàn)一個(gè)訂閱者Watcher,收到屬性的變化通知并執(zhí)行響應(yīng)的函數(shù),從而更新視圖
- 實(shí)現(xiàn)一個(gè)解析器Compiler侵浸,可以?huà)呙璨⒔馕雒總€(gè)節(jié)點(diǎn)的相關(guān)指令,初始化模板數(shù)據(jù)和對(duì)應(yīng)的訂閱器
vue的指令有哪些
v-if 用于條件渲染
v-show 用于條件渲染胶坠,兩者的區(qū)別請(qǐng)參考下一個(gè)問(wèn)題
v-for 用于列表渲染
v-on 監(jiān)聽(tīng)事件
v-bind 動(dòng)態(tài)綁定
v-html 渲染html元素
v-model 數(shù)據(jù)雙向綁定
v-if和v-show區(qū)別
v-if 是惰性的,只有條件為真時(shí)才會(huì)切換繁堡,為假時(shí)什么也不做沈善。確保切換過(guò)程中的事件監(jiān)聽(tīng)器和子組件適當(dāng)?shù)谋讳N(xiāo)毀和重建乡数,適用于運(yùn)行條件很少改變的場(chǎng)景。v-show 不管條件是否為真闻牡,總是會(huì)被渲染瞳脓,適用于頻繁切換的場(chǎng)景
v-for和v-if為什么不能放于同一級(jí)
v-for優(yōu)先級(jí)高于v-if,放于同級(jí)可能會(huì)重復(fù)渲染兩次v-if澈侠,建議把v-for放于v-if所在的外層元素
nextTick
原理:eventloop事件循環(huán)
在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)劫侧。在修改數(shù)據(jù)之后立即使用這個(gè)方法,獲取更新后的 DOM哨啃。
v-for中key的原理
key 主要用在 Vue 的虛擬 DOM 算法烧栋,在新舊 nodes 對(duì)比時(shí)辨識(shí) VNodes。不指定key時(shí)拳球,Vue 會(huì)使用一種最大限度減少動(dòng)態(tài)元素并且盡可能的嘗試
就地修改/復(fù)用相同類(lèi)型元素的算法审姓。而使用 key 時(shí),它會(huì)基于 key 的變化重新排列元素順序祝峻,并且會(huì)移除 key 不存在的元素魔吐。
有相同父元素的子元素必須有獨(dú)特的 key。重復(fù)的 key 會(huì)造成渲染錯(cuò)誤莱找。
vue的生命周期
1.beforeCreate
初始化界面前
2.created
初始化界面后酬姆,拿到data,props奥溺,methods辞色、computed和watch
3.beforeMount
渲染dom前
4.mounted
渲染dom后,拿到$el
5.beforeUpdate
更新前
6.updated
更新后浮定,拿到更新后的dom
7.beforeDestroy
卸載組件前
8.destroyed
卸載組件后
9.activated
被 keep-alive 緩存的組件激活時(shí)調(diào)用
10.deactivated
被 keep-alive 緩存的組件停用時(shí)調(diào)用
- errorCaptured
當(dāng)捕獲一個(gè)來(lái)自子孫組件的錯(cuò)誤時(shí)被調(diào)用相满。此鉤子會(huì)收到三個(gè)參數(shù):錯(cuò)誤對(duì)象、發(fā)生錯(cuò)誤的組件實(shí)例
以及一個(gè)包含錯(cuò)誤來(lái)源信息的字符串桦卒。此鉤子可以返回 false 以阻止該錯(cuò)誤繼續(xù)向上傳播立美。
父子組件通信
父?jìng)髯?prop
子傳父:$emit
父子通信:
- eventbus
- vuex
- ref結(jié)合children
跨層級(jí)較多:provide/inject
computed和watch區(qū)別
computed用于計(jì)算屬性,只有它依賴(lài)的值改變才會(huì)觸發(fā)方灾,且這個(gè)值有緩存
watch用于監(jiān)聽(tīng)一個(gè)屬性的變化建蹄,屬性變化就會(huì)觸發(fā)
vnode的diff算法原理
虛擬dom是對(duì)真實(shí)dom的一種映射,新舊Vnode比較同層級(jí)的節(jié)點(diǎn)迎吵,然后根據(jù)兩者的差異只更新有差異的部分躲撰,生成新的視圖针贬,而不是對(duì)樹(shù)進(jìn)行逐層搜素遍歷击费,因此時(shí)間復(fù)雜度是O(n)。虛擬dom可以減少頁(yè)面的回流和重繪桦他,提升性能
webpack相關(guān)
webpack運(yùn)行流程
分為初始化蔫巩、編譯谆棱、輸出三個(gè)階段.
- 初始化:
從配置文件和shell文件讀取、合并參數(shù)圆仔;
加載plugin
實(shí)例化compiler
- 編譯
從entry發(fā)出垃瞧,針對(duì)每個(gè)module串行調(diào)用對(duì)應(yīng)loader翻譯文件內(nèi)容
找到module依賴(lài)的module,遞歸進(jìn)行編譯處理
- 輸出:
把編譯后module組合成chunk
把chunk轉(zhuǎn)換成文件坪郭,輸出到文件系統(tǒng)
webpack性能優(yōu)化
優(yōu)化可以從兩個(gè)方面考慮个从,一個(gè)是優(yōu)化開(kāi)發(fā)體驗(yàn),一個(gè)是優(yōu)化輸出質(zhì)量歪沃。優(yōu)化開(kāi)發(fā)體驗(yàn)
縮小文件搜索范圍嗦锐。涉及到webpack如何處理導(dǎo)入文件,不再贅述沪曙,不會(huì)的可以自行搜索奕污。由于loader對(duì)文件轉(zhuǎn)換操作很耗時(shí),應(yīng)該盡量減少loader處理的文件液走,可以使用include命中需要處理的文件碳默,縮小命中范圍。
使用DllPlugin缘眶,提升構(gòu)建速度
使用happyPack開(kāi)啟多線(xiàn)程
使用UglifyJs壓縮代碼(只支持es5)嘱根,uglifyes支持es6,兩個(gè)插件不能同時(shí)開(kāi)啟巷懈。使用ParalellUgifyPlugin開(kāi)啟多個(gè)子進(jìn)程壓縮儿子,既支持UglifyJs又支持uglifyes
使用自動(dòng)刷新:監(jiān)聽(tīng)到代碼改變后,自動(dòng)編譯構(gòu)建可運(yùn)行代碼并刷新頁(yè)面
開(kāi)啟模塊熱替換:在不刷新網(wǎng)頁(yè)的同時(shí)實(shí)現(xiàn)實(shí)時(shí)預(yù)覽
優(yōu)化輸出質(zhì)量減少首屏加載時(shí)間
區(qū)分環(huán)境
壓縮代碼
CDN加速
使用Tree shaking
提取公共代碼
按需加載
提升流暢度砸喻,即代碼性能:
使用PrePack優(yōu)化代碼運(yùn)行時(shí)的效率
開(kāi)啟Scope Hoisting柔逼,讓webpack打包出來(lái)的代碼更小、運(yùn)行更快
- loader的原理
loader能把源文件翻譯成新的結(jié)果割岛,一個(gè)文件可以鏈?zhǔn)浇?jīng)過(guò)多個(gè)loader編譯愉适。以處理scss文件為例:
sass-loader把scss轉(zhuǎn)成css
css-loader找出css中的依賴(lài),壓縮資源
style-loader把css轉(zhuǎn)換成腳本加載的JavaScript代碼
plugin原理
plugin用于擴(kuò)展webpack功能癣漆。
webpack啟動(dòng)后维咸,在讀取配置時(shí)會(huì)先執(zhí)行new BasicPlugin(options)初始化一個(gè)BasicPlugin獲得它的實(shí)例
調(diào)用BasicPlugin.apply(compiler)給插件實(shí)例傳遞compiler對(duì)象
插件實(shí)例獲取compiler對(duì)象后,通過(guò)compiler.plugin(事件名惠爽,回調(diào)函數(shù))監(jiān)聽(tīng)webpack廣播出的事例
http相關(guān)
url從輸入到輸出的過(guò)程1. 構(gòu)建請(qǐng)求
構(gòu)建請(qǐng)求行癌蓖,請(qǐng)求行包括請(qǐng)求方法、請(qǐng)求http版本婚肆、URI
Get/Http/1.0
- 查找強(qiáng)緩存
檢查強(qiáng)緩存租副,命中則直接使用,否則檢查協(xié)商緩存 - DNS解析
域名與IP地址映射
4.建立tcp連接
chrome限制同一域名下最多6個(gè)tcp連接
- 通過(guò)三次握手建立連接
三次握手過(guò)程:
1.客戶(hù)端向服務(wù)器發(fā)送連接請(qǐng)求较性,傳遞一個(gè)數(shù)據(jù)包syn用僧,此時(shí)客戶(hù)端處于SYN_SEND狀態(tài)
2.服務(wù)器接收syn報(bào)文后结胀,會(huì)以自己的syn報(bào)文作為應(yīng)答,傳遞數(shù)據(jù)包syn+ack,此時(shí)服務(wù)器處于SYN-REVD狀態(tài)
3.客戶(hù)端接收syn報(bào)文后责循,發(fā)送一個(gè)數(shù)據(jù)包ack糟港,此時(shí)客戶(hù)端處于ESTABLISHED狀態(tài),雙方已建立連接 - 進(jìn)行數(shù)據(jù)傳輸
- 通過(guò)四次揮手?jǐn)嚅_(kāi)連接
四次揮手過(guò)程:
- 客戶(hù)端發(fā)送一個(gè)FIN報(bào)文院仿,報(bào)文中指定一個(gè)序列號(hào)秸抚,此時(shí)客戶(hù)端處于FIN_WAIT1狀態(tài),等待服務(wù)器確認(rèn)
- 服務(wù)器接收到FIN后歹垫,會(huì)發(fā)送ACK確認(rèn)報(bào)文耸别,表明已經(jīng)收到客戶(hù)端報(bào)文,此時(shí)服務(wù)端處于CLOSE_WAIT2狀態(tài)
- 服務(wù)器發(fā)送FIN县钥,告訴客戶(hù)端想斷開(kāi)連接秀姐,此時(shí)服務(wù)端處于LAST_CHECK階段
- 客戶(hù)端收到FIN后,一樣發(fā)送一個(gè)ACK作為應(yīng)答若贮,此時(shí)客戶(hù)端處于TIME_WAIT階段省有。需要過(guò)一段時(shí)間確認(rèn)服務(wù)端收到自己的ACK報(bào)文
后才會(huì)進(jìn)入CLOSED狀態(tài)
5.發(fā)送http請(qǐng)求
6.網(wǎng)絡(luò)響應(yīng)
7.瀏覽器解析和渲染
分為構(gòu)建dom樹(shù)、樣式計(jì)算谴麦、生成布局樹(shù)蠢沿。
8.生成布局
觸發(fā)回流和重繪
介紹下半連接隊(duì)列
服務(wù)器第一次接收到客戶(hù)端的SYN后,會(huì)處于SYN-REVD階段匾效,此時(shí)雙方還沒(méi)有建立完全的連接舷蟀,
服務(wù)器會(huì)把此種狀態(tài)下請(qǐng)求連接放在一個(gè)隊(duì)列里,我們把這種隊(duì)列稱(chēng)為半連接隊(duì)列
已經(jīng)完成三次握手并建立連接面哼,就叫全連接隊(duì)列
http和https區(qū)別
http基于TCP/IP協(xié)議野宜,https基于SSL/TLS協(xié)議
http默認(rèn)端口號(hào)為80,https默認(rèn)端口號(hào)為443
https安全性更強(qiáng)魔策,需要CA證書(shū)
https可以防止運(yùn)營(yíng)商劫持
可以介紹https的通信過(guò)程匈子,涉及對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密
tcp和udp區(qū)別
tcp只能一對(duì)一通信,udp可以一對(duì)一闯袒、一對(duì)多虎敦、多對(duì)多通信,即支持多播和廣播
tcp首部開(kāi)銷(xiāo)消耗32字節(jié)政敢,udp僅消耗8個(gè)字節(jié)
tcp適合對(duì)數(shù)據(jù)安全性要求高的場(chǎng)景其徙,比如文件傳輸,udp適合對(duì)數(shù)據(jù)實(shí)時(shí)性要求高的場(chǎng)景喷户,比如視頻通話(huà)唾那、語(yǔ)音通話(huà)
tcp是有狀態(tài)連接,udp是無(wú)狀態(tài)的連接
tcp-可靠傳輸 udp-不可靠傳輸
tcp-面向字節(jié)流 udp-面向報(bào)文
tcp怎么保證可靠性
- 超時(shí)重傳機(jī)制
- 對(duì)失序數(shù)據(jù)進(jìn)行重排序
- 應(yīng)答機(jī)制
- 滑動(dòng)窗口
- 擁塞控制
http請(qǐng)求有哪幾種
http1.0:get摩骨、post通贞、head
http1.1:put、delete恼五、connect昌罩、trace、options
簡(jiǎn)單請(qǐng)求:
請(qǐng)求method只能是get灾馒、post茎用、head
請(qǐng)求頭只能是accept/accept-language/content-language/content-Type
content-Type只能是text/plain、multipart/form-data睬罗、application/x-www-form-urlencoded
介紹http1.0|http1.1|http2.0
http1.0:
完成連接即斷開(kāi)轨功,導(dǎo)致重新慢啟動(dòng)和三次握手
線(xiàn)頭阻塞,導(dǎo)致請(qǐng)求間相互影響
http1.1:
用keep-alive支持長(zhǎng)連接
用host字段指定對(duì)應(yīng)的虛擬站點(diǎn)
新增功能: 斷點(diǎn)續(xù)傳容达、身份認(rèn)證古涧、狀態(tài)管理、cache緩存->cache-control花盐、expires羡滑、last-modified、etag
http2.0:
二進(jìn)制分幀層:應(yīng)用層和傳輸層
header頭部壓縮
服務(wù)端推送
多路復(fù)用
二進(jìn)制分幀層可以擴(kuò)展到計(jì)算機(jī)網(wǎng)絡(luò)的OSI參考模型
客戶(hù)端緩存
客戶(hù)端緩存分為cookie算芯、localStorage柒昏、sessionStorage、indexedDB熙揍,網(wǎng)上有關(guān)的文章很多职祷,就不詳細(xì)說(shuō)了
瀏覽器緩存
強(qiáng)緩存
不向http發(fā)送請(qǐng)求,返回狀態(tài)碼304.
檢查強(qiáng)緩存有兩個(gè)字段: http1.0使用expires届囚,代表過(guò)期時(shí)間有梆,但是服務(wù)器時(shí)間和客戶(hù)端時(shí)間可能不一致。為了彌補(bǔ)這個(gè)缺點(diǎn)意系,http1.1使用cache-control的max-age字段淳梦,cache-control有多個(gè)指令
public 允許客戶(hù)端和代理服務(wù)器緩存
private 允許客戶(hù)端緩存
no-store 不使用緩存
no-cache 使用協(xié)商緩存 兩個(gè)字段都存在,cache-control優(yōu)先級(jí)高于expires
協(xié)商緩存向http發(fā)送請(qǐng)求昔字,返回狀態(tài)碼200
檢查協(xié)商緩存有兩個(gè)字段: http1.0使用last-modified爆袍,即最后修改時(shí)間。
在瀏覽器向服務(wù)器發(fā)送請(qǐng)求后作郭,服務(wù)器會(huì)在響應(yīng)頭上加上這個(gè)字段
瀏覽器接收后陨囊,如果再次請(qǐng)求,會(huì)在請(qǐng)求頭上攜帶If-Modified-Since
服務(wù)器拿到If-Modified-Since字段后夹攒,會(huì)和服務(wù)器中該資源的最后修改時(shí)間對(duì)比,如果請(qǐng)求頭中這個(gè)值小于最后修改時(shí)間蜘醋,更新資源;否則返回304咏尝,告訴瀏覽器直接使用緩存
http1.1使用etag压语,etag是服務(wù)器根據(jù)當(dāng)前文件內(nèi)容啸罢,給文件生成的唯一標(biāo)識(shí),只要內(nèi)容改變胎食,這個(gè)值就會(huì)變扰才。etag優(yōu)先級(jí)高于last-modifed
緩存位置,按優(yōu)先級(jí)從高到低分別是:
service worker
memory cache
disk cache
push cache
http狀態(tài)碼
列舉一些常見(jiàn)狀態(tài)碼即可
200-請(qǐng)求成功
301-永久重定向
302和307-臨時(shí)重定向
400-當(dāng)前請(qǐng)求不能被服務(wù)器理解或請(qǐng)求參數(shù)有誤
401-請(qǐng)求需要認(rèn)證或認(rèn)證失敗
403-服務(wù)器禁止訪(fǎng)問(wèn)
404-資源未找到
405-方法未允許
500-內(nèi)部服務(wù)器錯(cuò)誤
502-網(wǎng)關(guān)錯(cuò)誤
503-服務(wù)器處于超負(fù)載或停機(jī)維護(hù)
了解nginx嗎
ngnix是個(gè)高性能反向代理服務(wù)器厕怜,有以下作用:
解決跨域
請(qǐng)求過(guò)濾
配置gzip
負(fù)載均衡
靜態(tài)資源服務(wù)器
ngnix解決跨域的原理:
把后端域名設(shè)為前端服務(wù)的域名衩匣,然后設(shè)置相應(yīng)的location攔截前端需要跨域的請(qǐng)求,最后將請(qǐng)求代理回服務(wù)端的域名
ngnix實(shí)現(xiàn)負(fù)載均衡的策略:輪詢(xún)粥航、最小鏈接數(shù)琅捏、最快響應(yīng)時(shí)間
web安全
xss
跨站腳本攻擊,指攻擊者在網(wǎng)頁(yè)上注入惡意的客戶(hù)端代碼递雀,通過(guò)惡意腳本對(duì)客戶(hù)端網(wǎng)頁(yè)進(jìn)行篡改柄延,從而在用戶(hù)瀏覽網(wǎng)頁(yè)時(shí), 對(duì)客戶(hù)端瀏覽器進(jìn)行控制或獲取用戶(hù)隱私數(shù)據(jù)的方式
防范:
httpOnly防止截取cookie
用戶(hù)輸入檢查
用戶(hù)輸出檢查
利用CSP(瀏覽器的內(nèi)容安全策略)
csrf
跨站請(qǐng)求偽造缀程,劫持受信任用戶(hù)向服務(wù)器發(fā)送非預(yù)期請(qǐng)求的方式拦焚。
防范:
驗(yàn)證碼
referer check
增加token驗(yàn)證
二次封裝axios
1.新建一個(gè)axios對(duì)象,定義好字段并設(shè)置默認(rèn)值杠输,比如超時(shí)時(shí)間赎败、請(qǐng)求頭
2.定義過(guò)濾字符串方法,過(guò)濾服務(wù)端為空字符串或null的屬性
3.請(qǐng)求攔截器調(diào)用過(guò)濾字符串方法蠢甲,遍歷url上的字段僵刮,如果為數(shù)組或?qū)ο筠D(zhuǎn)為JSON對(duì)象
4.響應(yīng)攔截器捕獲錯(cuò)誤,根據(jù)http狀態(tài)碼進(jìn)行不同的處理鹦牛,比如401跳轉(zhuǎn)登陸頁(yè)面搞糕,403返回您沒(méi)有權(quán)限,502返回系統(tǒng)正在升級(jí)中曼追,請(qǐng)稍后重試窍仰,
504返回系統(tǒng)超時(shí),并彈出對(duì)應(yīng)的消息提示框礼殊。消息提示框自定義
axios調(diào)用流程
查看axios源碼驹吮,axios調(diào)用流程實(shí)質(zhì)是Axios.prototype.request的實(shí)現(xiàn),調(diào)用過(guò)程如下:
1.判斷傳入?yún)?shù)config是否是字符串晶伦,是則設(shè)置url碟狞,否則設(shè)置config為對(duì)象
2.調(diào)用mergeConfig方法,合并默認(rèn)參數(shù)和用戶(hù)傳入的參數(shù)
3.如果設(shè)置了請(qǐng)求方法婚陪,將其轉(zhuǎn)為小寫(xiě)族沃,否則設(shè)置請(qǐng)求方法為get
4.將用戶(hù)設(shè)置的請(qǐng)求和響應(yīng)攔截器、發(fā)送請(qǐng)求的dispatchRequest組成promise鏈,最后返回promise實(shí)例脆淹。
這一步保證先執(zhí)行請(qǐng)求攔截器常空,再執(zhí)行請(qǐng)求,最后執(zhí)行響應(yīng)攔截器
聊項(xiàng)目
挑一到兩個(gè)比較有代表性的項(xiàng)目講盖溺,可以用SWOT方法漓糙,簡(jiǎn)要介紹項(xiàng)目的背景,項(xiàng)目的主要的技術(shù)難點(diǎn)咐柜,如何解決的兼蜈,項(xiàng)目做完后的效果攘残。我主要講的是怎么推動(dòng)Jenkins自動(dòng)化部署在前端組里的應(yīng)用
hr面
一般都是聊規(guī)劃聊跳槽原因拙友,掌握一些常見(jiàn)聊天技巧一般來(lái)說(shuō)不會(huì)掛人,除非(薪資沒(méi)談攏)歼郭。遗契。。
后記
數(shù)據(jù)結(jié)構(gòu)和算法也有問(wèn)到了病曾,規(guī)模不大的公司一般排序問(wèn)的比較多(插冒歸基快選堆希)牍蜂,前端會(huì)這8種排序就行了。如果想面更好的公司泰涂,還得把數(shù)據(jù)結(jié)構(gòu)和算法復(fù)習(xí)好了鲫竞。