記一次今日頭條前端面試

最近公司部門被裁了,讓我這個剛剛畢業(yè)一年不到的人情何以堪啊。硬著頭皮出去面試吧!
在此記錄一下今日頭條面試中印象比較深刻的問題,問題順序已打亂。

一、實現(xiàn)Bind函數(shù)

其實本來不是考查這個的,僅僅是考查bind的用法。后來題目做出來面試官又繼續(xù)問如何實現(xiàn)bind。下面是參考MDN的polyfill寫出來的代碼:

if(!Function.prototype.bind){
  Function.prototype.bind = function(context){
    // 首先判斷this是不是function
    if(typeof this !== 'function'){
      // 拋出錯誤
    }
    var _this = this,
          fNOP = function(){},    // 用于后面維護原型關系
          args = Array.prototype.slice.call(arguments, 1),    // 取出bind收到的參數(shù),除去第一個作為上下文的參數(shù)并保存
          fBound = function(){
            _this.call(context, args.concat(Array.prototype.slice.call(arguments)))   // 將bind接收的的參數(shù)和實際接收到的參數(shù)相連接
          };
    // 維護原型關系
    if(this.prototype){
        fNOP.prototype = this.prototype;
        fBound.prototype = new fNOP;
    }
    return fBound;
  }
}

二、實現(xiàn)節(jié)流函數(shù)

有一個高頻操作會讓函數(shù)迅速執(zhí)行很多次,需要按照下面的時間線圖來實現(xiàn)一個節(jié)流函數(shù)。


節(jié)流函數(shù)示意圖

圖是word畫的,微信截的圖,湊合看吧...圖中每一個斷點都代碼觸發(fā)了一次函數(shù),但是觸發(fā)函數(shù)時只在奇數(shù)時執(zhí)行,偶數(shù)時不執(zhí)行,斷點間的時間間隔為50ms。
根據(jù)題意需要的是一個節(jié)流函數(shù)。剛開始時我是這么實現(xiàn)的:

var throttle = function(fn){
  var timer = null;
  return function(){
    var args = arguments, context = this;
    clearTimeout(timer);
    timer = setTimeout(function(){
      fn.call(context, args)
    }, 100)
  }
}
這跟javascript高級程序設計中的實現(xiàn)方式差不多,其實嚴格來說這種實現(xiàn)方式并不叫節(jié)流函數(shù),而是防抖函數(shù):短時間內(nèi)多次調(diào)用同一函數(shù),只執(zhí)行最后一次調(diào)用。
下面是改進:
var throttle = function(fn){
  var timer = null;
  return function(){
    var args = arguments, context = this;
    if(!timer){
      timer = setTimeout(function(){
        timer = null;
        fn.call(context, args)
      }, 100);
    }
  }
}
如此一來這個功能基本上就可以實現(xiàn)了,但是仍有一個問題,第一次調(diào)用的時候函數(shù)并沒有執(zhí)行,而是直接從第三次調(diào)用開始執(zhí)行的,那么我們再改進一下,加一個第一次調(diào)用時的哨兵即可:
var throttle = function(fn){
  var timer = null, first = true;
  return function(){
    var args = arguments, context = this;
    if(first){
      first = false;
      fn.call(context, args)
    }
    if(!timer){
      timer = setTimeout(function(){
        timer = null;
        fn.call(context, args)
      }, 100);
    }
  }
}

三、窮舉組合

實現(xiàn)一個函數(shù),給三個參數(shù),data是整形數(shù)組,m和sum都是一個整數(shù),從data中取出n個整數(shù),使它們的和為sum,求出一種組合即可。
我的思路是窮舉data中的n個key的組合,假設data有6(n)個元素,從中取出3(m)個數(shù),那么它key的組合就有:[0,1,2]、[0,1,3]、[0,1,4]、[0,1,5]、[0,2,3]、[0,2,4]、[0,2,5]、...、[3,4,5]
列出它的所有組合就好辦了,直接用這些key去data里面取數(shù),如果找到答案就退出程序。
下面僅給出窮舉組合的算法,為了簡單,相關參數(shù)寫死并忽略全局污染:

// 數(shù)組a用于存放key的組合,data并沒有出現(xiàn),只給出data元素個數(shù)n
var a=[0,1,2], oldA = [],n = 6, len = a.length;
function listArr(key){
    let same = true
    for(let i = 0 ; i < len ; i++){
        if(a[i] !== oldA[i]){
            same = false
            break
        }
    }
    if(!same){
        console.log(a)
        oldA = Array.prototype.slice.call(a)
    }
}
function list(currentKey, initValue){
    if(currentKey >= len || initValue >= n){
        return
    }
    for(let v = initValue ; v <= n + currentKey - len ; v++){
        a[currentKey] = v
        arguments.callee(currentKey+1, v+1)
        listArr(currentKey);
    }
}
list(0,0)

當然不止這些題目,我這里只是列出了一些我答得不好和根本沒有答出來的題目(逃),面試的結(jié)果應該是黃了。今天回頭一想其實都還是可以做出來的,只是平時練得太少,心態(tài)也有點問題。多多復習,希望接下來的面試順利吧!

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,734評論 18 399
  • 大年初二下午,我們?nèi)ヌ铱赐〉奶?,順便在那里吃晚飯? 太婆發(fā)了高燒,姨丈送她去醫(yī)院。誰知看了醫(yī)...
    潘儀宸閱讀 346評論 0 0
  • 19 98年,米雪13歲,讀初二。 如平時一樣,米雪要凌晨五點起床,要到5公里外的學校讀書,如果晚了,...
    米夜雪閱讀 466評論 0 0
  • 是不輕易受一些東西誘惑了
    三自先生閱讀 162評論 0 0

友情鏈接更多精彩內(nèi)容