自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

TikTok 面試:四個(gè)你可能感興趣的前端題

開發(fā) 前端
最近,我的好朋友正在換工作,在網(wǎng)上收到了很多offer。其中之一就有來自一家名為 TikTok 公司的Offer,你可能非常熟悉該公司,也有可能不是很熟悉它。

最近,我的好朋友正在換工作,在網(wǎng)上收到了很多offer。

其中之一就有來自一家名為 TikTok 公司的Offer,你可能非常熟悉該公司,也有可能不是很熟悉它。

朋友在面試的時(shí)候,他們讓我的朋友當(dāng)場(chǎng)寫代碼來實(shí)現(xiàn)4個(gè)復(fù)雜方法的功能。

1. 嘗試實(shí)現(xiàn)Promise.all API

Promise.all() 方法將可迭代的 Promise 作為輸入,并返回單個(gè) Promise,該 Promise 解析為輸入 Promise 結(jié)果的數(shù)組。

當(dāng)所有輸入的 Promise 都已解決,或者輸入的可迭代對(duì)象不包含 Promise 時(shí),返回的 Promise 將得到解決。

它會(huì)在任何輸入Promise拒絕或非承諾拋出錯(cuò)誤時(shí)立即拒絕,并將拒絕第一個(gè)拒絕消息/錯(cuò)誤。

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

現(xiàn)在,自己實(shí)現(xiàn)了一個(gè)

Promise.myAll = (promises) => {
  return new Promise((rs, rj) => {
    // counter
    let count = 0
    // Storage results
    let result = []
    const len = promises.length


    if (len === 0) {
      return rs([])
    }


    promises.forEach((p, i) => {
      // Some array items may not be Promise and need to be converted manually
      Promise.resolve(p).then((res) => {
        count += 1
        // Collect the return value of each Promise 
        result[ i ] = res
        // Set the value of Promise to result, when all Promises are successful
        if (count === len) {
          rs(result)
        }
        // As long as one promise fails, the result is failure
      }).catch(rj)
    })
  })
}

進(jìn)行測(cè)試如下:

const p1 = Promise.resolve(1)
const p2 = new Promise((resolve) => {
  setTimeout(() => resolve(2), 1000)
})
const p3 = new Promise((resolve) => {
  setTimeout(() => resolve(3), 3000)
})
const p4 = Promise.reject('err4')
const p5 = Promise.reject('err5')
// 1. All promise succeeded
const p11 = Promise.myAll([ p1, p2, p3 ])
  .then(console.log) // [ 1, 2, 3 ]
      .catch(console.log)


// 2. One promise failed
const p12 = Promise.myAll([ p1, p2, p4 ])
  .then(console.log)
      .catch(console.log) // err4


// 3. Two promises failed. The final output is err4. The return value of the first failure
const p13 = Promise.myAll([ p1, p4, p5 ])
  .then(console.log)
      .catch(console.log) // err4

2.設(shè)計(jì)一個(gè)可以設(shè)置過期日期的localstorage API

localstorage不會(huì)像cookie一樣自動(dòng)過期,所以過期時(shí)間需要自己維護(hù)。

我的思路是:

使用setItem時(shí),保存過期時(shí)間。使用getItem時(shí),將時(shí)間與當(dāng)前時(shí)間進(jìn)行比較,如果大于當(dāng)前時(shí)間,則返回該值,否則,需要通過removeItem移除該值,并返回null。

const storage = {
  prefix: 'fatFish',
  timeSign: '|fatFish|',
  setItem (key, value, time) {
    // Protect the key from being overwritten
    key = `${this.prefix}${key}`
    // There is no incoming time, the default expiration time is one month, of course, it can be other times or not set
    time = time ? new Date(time).getTime() : Date.now() + 24 * 60 * 60 * 31 * 1000
    // Constructs a string of the form 1646094676134|fatFish|"Front-end Fat Fish"
    window.localStorage.setItem(key, `${time}${this.timeSign}${JSON.stringify(value)}`)
  },
  getItem (key) {
    key = `${this.prefix}${key}`
    let value = window.localStorage.getItem(key)
    if (value) {
      let index = value.indexOf(this.timeSign)
      let time = +value.slice(0, index)
      // Determine if time has expired
      if (time > Date.now()) {
        value = JSON.parse(value.slice(index + this.timeSign.length))
      } else {
        value = null
        window.localStorage.removeItem(key)
      }
    }
    return value
  }
}

現(xiàn)在,進(jìn)行測(cè)試

storage.setItem('name', 'front-end-fat-head', Date.now() + 100 * 1000) // fatFishname  1646095230191|fatFish|"front-end-fat-head"
storage.getItem('name') // front-end-fat-head
// 100s later
storage.getItem('name') // null
storage.setItem('obj', { name: 'front-end-fat-head', age: 100 }, Date.now() + 100 * 1000) // fatFishobj  1646095311366|fatFish|{"name":"front-end-fat-head","age":100}
storage.getItem('obj') // {name: 'front-end-fat-head', age: 100}

基本上符合題主的要求。當(dāng)然,我們也可以處理異常情況,比如空間已滿、設(shè)置錯(cuò)誤等。

3.找到兩個(gè)節(jié)點(diǎn)最近的公共父節(jié)點(diǎn),包括節(jié)點(diǎn)本身

介紹:

oNode1 和 oNode2 位于同一文檔中,并且不會(huì)是同一節(jié)點(diǎn)。

function findCommonParent(oNode1, oNode2) {
  // fill here
}

相信看到這道題你一定會(huì)用遞歸,但是沒有明確的思路。

這個(gè)時(shí)候不要緊張。從問題中找出更有效的信息,盡量用更多的筆來畫(如果是現(xiàn)場(chǎng)面試,記得只帶一支鉛筆,有時(shí)候畫多了想法就出來了)。

1.1 兩個(gè)節(jié)點(diǎn)處于同一級(jí)別

讓我們嘗試畫出這兩個(gè)節(jié)點(diǎn)之間可能的關(guān)系。如下圖所示,它們的直接父節(jié)點(diǎn)就是答案。

1.2 兩個(gè)節(jié)點(diǎn)互為祖先

oNode1 是目標(biāo)節(jié)點(diǎn)。當(dāng)然,反過來也是一樣的。oNode2 也可以是 oNode1 的祖先。

1.3 兩個(gè)節(jié)點(diǎn)之間沒有關(guān)系

如下圖所示,兩個(gè)節(jié)點(diǎn)之間的距離很遠(yuǎn),看似沒有任何關(guān)系,但從其中任意一個(gè)向上查找,肯定能找到包含oNode1或oNode2的點(diǎn)。

1.4 遞歸實(shí)現(xiàn)版本

根據(jù)上面的分析,相信你很快就能寫出下面的代碼。

function findCommonParent(oNode1, oNode2) {
  // Cases 1 and 2
  if (oNode1.contains(oNode2)) {
    return oNode1
    // Cases 1 and 2
  } else if (oNode2.contains(oNode1)) {
    return oNode2
  } else {
    // Case 3, if you look up one of the nodes, you will find a common ancestor node
    return findCommonParent(oNode1.parentNode, oNode2)
  }
}

1.5 遍歷實(shí)現(xiàn)版本

遞歸很好理解,僅僅通過遍歷就可以實(shí)現(xiàn)嗎?事實(shí)上,遞歸問題往往可以通過遍歷來解決。

function findCommonParent (oNode1, oNode2) {
  // Using oNode2 here is the same
  // If a node contains another node, return directly, otherwise keep looking up
  while (!oNode1.contains(oNode2)) {
    oNode1 = oNode1.parentNode 
  }
  return oNode1
}

4.使用reduce實(shí)現(xiàn)map功能

這個(gè)問題會(huì)比較簡(jiǎn)單,我們直接寫代碼吧。

Input: [1, 2, 3]
Output: [2, 4, 6]
Array.prototype.map2 = function (callback, ctx = null) {
  if (typeof callback !== 'function') {
    throw('callback must be a function')
  }
  return this.reduce((result, cur, index, array) => {
    return  result.concat(callback.call(ctx, cur, index, array))
  }, [])
}
let arr = [ 1, 2 ]
let arr2 = arr.map2(function (it, i, array) {
  console.log(it, i, array, this)
  return it * 2
}, { name: 'fatfish' })
console.log(arr2)

最后

看到這里,我想你已經(jīng)明白了,如果還不明白的話,那就是我還沒有說清楚,下次,我爭(zhēng)取說的更加清楚一些。當(dāng)然,如果你覺得這個(gè)內(nèi)容對(duì)你有幫助的話,請(qǐng)記得點(diǎn)贊我,關(guān)注我,以便學(xué)習(xí)能夠內(nèi)容,同時(shí),也不會(huì)錯(cuò)過我們的優(yōu)質(zhì)內(nèi)容。

責(zé)任編輯:華軒 來源: web前端開發(fā)
相關(guān)推薦

2012-07-09 11:20:59

2009-07-27 17:59:27

博科資訊物流管理

2009-03-20 08:34:11

2018-10-19 10:43:13

營(yíng)銷物聯(lián)網(wǎng)IOT

2015-02-10 10:08:59

JavaScript

2009-07-17 11:28:07

TwitterGoogle

2012-10-17 13:28:59

Windows 8

2009-06-25 09:11:58

鮑爾默雅虎搜索

2017-09-05 13:55:07

windowsHTML5Chrome

2017-03-16 22:22:26

2011-03-28 19:18:00

手機(jī)輻射iPhone應(yīng)用

2010-09-17 10:31:14

VMworld 201

2015-03-18 10:33:27

2025-02-27 08:33:13

2021-05-10 14:50:03

.NETRust語言

2021-09-26 22:23:45

iPhone 13安卓手機(jī)

2011-01-27 11:48:44

職場(chǎng)

2024-05-23 17:16:36

2012-03-26 21:56:58

WP

2024-11-20 12:21:37

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)