面試官:你能回答這兩個簡單的問題嗎

前端小智發表於2022-05-24
本文首發於微信公眾號:大遷世界, 我的微信:qq449245884,我會第一時間和你分享前端行業趨勢,學習途徑等等。
更多開源作品請看 GitHub https://github.com/qq449245884/xiaozhi ,包含一線大廠面試完整考點、資料以及我的系列文章。

背景

這是我的朋友在最近一次面試中被問到的兩個問題,來一起學習一下。

1. 如何防止重複傳送多個請求?

問題:

在我們的工作中,經常需要只傳送一次請求,以防止使用者重複點選。

請編寫請求方法(執行後返回 promise)並返回一個新方法。當連續觸發時,將只傳送一個請求。

事例

function firstPromise () {
  // ...Please fill in here
}
let count = 1;
let promiseFunction = () =>
  new Promise(rs =>
    window.setTimeout(() => {
      rs(count++)
    })
  )
let firstFn = firstPromise(promiseFunction)
firstFn().then(console.log) // 1
firstFn().then(console.log) // 1
firstFn().then(console.log) // 1

問題分析

與演算法問題相比,這個問題相對簡單,我們只需要使用閉包和Promise的特徵就可以完成。

function firstPromise(promiseFunction) {
  // Cache request instance
  let p = null
  return function (...args) {
    // 如果請求的例項已經存在,說明請求正在進行中,
    // 直接返回該例項,而不觸發新的請求。
    return p
      ? p
      // 否則就傳送該請求,並在Promise結束時將p設定為null,然後可以重新傳送下一個請求
      : (p = promiseFunction.apply(this, args).finally(() => (p = null)))
  }
}

測試

let count = 1
let promiseFunction = () =>
  new Promise((rs) =>
    setTimeout(() => {
      rs(count++)
    }, 1000)
  )
let firstFn = firstPromise(promiseFunction)
firstFn().then(console.log) // 1
firstFn().then(console.log) // 1
firstFn().then(console.log) // 1
setTimeout(() => {
  firstFn().then(console.log) // 2
  firstFn().then(console.log) // 2
  firstFn().then(console.log) // 2
}, 3000)

2. 兩數之和

這是力扣的第1題,請看這裡:https://leetcode.cn/problems/...

給定一個整數陣列 nums 和一個整數目標值 target,請你在該陣列中找出 和為目標值 target  的那 兩個 整數,並返回它們的陣列下標。

你可以假設每種輸入只會對應一個答案。但是,陣列中同一個元素在答案裡不能重複出現。

你可以按任意順序返回答案。

 
示例 1:

輸入:nums = [2,7,11,15], target = 9
輸出:[0,1]
解釋:因為 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

輸入:nums = [3,2,4], target = 6
輸出:[1,2]

示例 3:

輸入:nums = [3,3], target = 6
輸出:[0,1]

方法一:使用兩層 for 迴圈

我們最快想到的方式就是暴力破解,直接用 for 魯,如下:

const twoSum = (nums, target) => {
  const len = nums.length
  for (let i = 0; i < len; i++) {
    for (let j = i + 1; j < len ; j++) {
      // find the answer, return
      if (nums[ i] + nums[ j ] === target) {
        return [ i, j ]
      }
    }
  }
}

面試官表揚了她的快速回答,但他對結果並不滿意,他認為有進一步最佳化的可能。

image.png

方法2:使用 Map

通常,當使用兩個for迴圈來求解一個問題時,我們需要意識到演算法的時間複雜度(o(n2))是可以最佳化的。

事實上,我們可以用一個 "for"迴圈來做,只要把加法變成減法,並且把遍歷的值儲存在一個物件sumCache中。

例如:

輸入: [2,7,11,15]

步驟1:

  1. 讀取 2, 此時 sumCache 為空。
  2. sumCache 中儲存 2 作為鍵,索引 0 作為值。

image.png

步驟2:

  1. 7,發現目標值是 9-7 = 2。
  2. 2 存在於 sumCache中,0 和 1 的索引將被直接返回。

image.png

你認為使用 Map 的方法是否簡單明瞭,比for迴圈容易得多?

這很好。我們得到了更好的結果。我們只多用了1.5M的空間,時間減少了近一半。

image.png

作者:fatfish 譯者:前端小智 來源:medium

原文:https://javascript.plainengli...

編輯中可能存在的bug沒法實時知道,事後為了解決這些bug,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug

交流

有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章