面試必備良藥之前端Q本周N題匯總

  • 2019 年 12 月 21 日
  • 筆記

背景

最近起了一個新項目,叫每周N題,N<=5。前端面試題雖然五花八門,但是我們也確實可以從中學到知識。所以我覺得應該有個地方收錄一下,每周做幾題,既可以考驗自己知識的廣度又可以挖掘深度,挺好的。

github地址:https://github.com/LuckyWinty/fe-weekly-questions,點擊即可到達題庫哦~

參與步驟:

  1. 打開地址,點 star
  2. watch 項目,及時收到題目的更新及答案消息
  3. 有自己會的題目 ,點comment,留下答案,大家交流學習

本周題目匯總

1. 如何判斷左右小括號是否全部匹配。如 ( ( ))()((((()))))

思路:利用棧,先進後出的特性

參考答案(答案不嚴謹,請到GitHub參考):

const judgeBracketsMatch = (s)=> {        const result = [];        for(let i = 0;i < s.length;i++){            if(s[i] === '('){                result.push(s[i])            }            if(s[i] === ')'){                result.pop()            }        }        if(result.length){            return false        }else{            return true        }    }

2. 下面代碼中的 a 在什麼情況下會打印1?

var a = ?if(a == 1 && a == 2 && a == 3){console.log(1)}

思路:重寫 valueOf 方法 參考答案:

var a = { value: 0, valueOf(){  return ++this.value }}  if (a == 1 && a == 2 && a == 3) { console.log(1);}

3. 如何理解迴流和重繪

迴流:當我們對 DOM 的修改引發了 DOM 幾何尺寸的變化(比如修改元素的寬、高或隱藏元素等)時,瀏覽器需要重新計算元素的幾何屬性(其他元素的幾何屬性和位置也會因此受到影響),然後再將計算的結果繪製出來。這個過程就是迴流(也叫重排)。

重繪:當我們對 DOM 的修改導致了樣式的變化、卻並未影響其幾何屬性(比如修改了顏色或背景色)時,瀏覽器不需重新計算元素的幾何屬性、直接為該元素繪製新的樣式(跳過了上圖所示的迴流環節)。這個過程叫做重繪。由此我們可以看出,重繪不一定導致迴流,迴流一定會導致重繪。

常見的會導致迴流的元素:
  • 常見的幾何屬性有 width、height、padding、margin、left、top、border 等等。
  • 最容易被忽略的操作:獲取一些需要通過即時計算得到的屬性,當你要用到像這樣的屬性:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight 時,瀏覽器為了獲取這些值,也會進行迴流。
  • 當我們調用了 getComputedStyle 方法,或者 IE 里的 currentStyle 時,也會觸發迴流。原理是一樣的,都為求一個「即時性」和「準確性」。
避免方式:
  1. 避免逐條改變樣式,使用類名去合併樣式
  2. 將 DOM 「離線」,使用DocumentFragment
  3. 提升為合成層,如使用will-change
#divId {  will-change: transform;}

優點

  • 合成層的位圖,會交由 GPU 合成,比 CPU 處理要快
  • 當需要 repaint 時,只需要 repaint 本身,不會影響到其他的層
  • 對於 transform 和 opacity 效果,不會觸發 layout 和 paint

注意:

部分瀏覽器緩存了一個 flush 隊列,把我們觸發的迴流與重繪任務都塞進去,待到隊列里的任務多起來、或者達到了一定的時間間隔,或者「不得已」的時候,再將這些任務一口氣出隊。但是當我們訪問一些即使屬性時,瀏覽器會為了獲得此時此刻的、最準確的屬性值,而提前將 flush 隊列的任務出隊。

4. UDP和TCP有什麼區別?

  • TCP協議在傳送數據段的時候要給段標號;UDP協議不
  • TCP協議可靠;UDP協議不可靠
  • TCP協議是面向連接;UDP協議採用無連接
  • TCP協議負載較高,採用虛電路;UDP採用無連接
  • TCP協議的發送方要確認接收方是否收到數據段(3次握手協議)
  • TCP協議採用窗口技術和流控制

特性

TCP

UDP

是否連接

面向連接

面向非連接

傳輸可靠性

可靠

不可靠

應用場合

傳輸大量數據

傳輸少量數據

速度

5. 實現一個LazyMan,可以按照以下方式調用

實現一個LazyMan,可以按照以下方式調用:LazyMan('Hank')輸出:Hi! This is Hank!LazyMan('Hank').sleep(10).eat('dinner')輸出Hi! This is Hank!//等待10秒..Wake up after 10Eat dinner~LazyMan('Hank').sleep(10).eat('dinner').eat('supper')輸出Hi This is Hank!Eat dinner~Eat supper~LazyMan('Hank').sleepFirst(5).eat('supper')輸出//等待5秒Wake up after 5Hi This is Hank!Eat supper~以此類推。

思路:參考Generator實現,可以控制執行和停止 參考答案:

function LazyMan(name) {    if(!(this instanceof LazyMan)){        return new LazyMan(name)    }  const cb = (next)=>{      console.log(`Hi This is ${name}!`)      next()  }  this.cbs = [cb];  setTimeout(()=>{    this.next()  },0)}LazyMan.prototype.eat = function (food){    const cb = (next)=>{        console.log(`Eat ${food}~`)        next()    }     this.cbs.push(cb);    return this}LazyMan.prototype.sleepFirst = function (time){    const cb = (next)=>{        setTimeout(()=>{            next()        },time*1000)     }     this.cbs.unshift(cb);    return this}LazyMan.prototype.sleep = function(time){    const cb = (next)=>{        setTimeout(()=>{            next()        },time*1000)     }     this.cbs.push(cb);    return this}LazyMan.prototype.next = function(){    if(this.cbs.length <= 0)return    const first = this.cbs.shift()    first(this.next.bind(this))}

小結

本周題目,還是比較考驗深度的,建議大家都動手做一下。更多題目查看這裡:

github地址:https://github.com/LuckyWinty/fe-weekly-questions,點擊即可到達題庫哦~