Интервью, чтобы построить ракету, посмотрите на оригинальные вопросы этих крупных производителей

внешний интерфейс опрос

Спрос изменился, а объем работы увеличился, работать сверхурочно всю ночь, чтобы наблюдать за восходом солнца. В итоге запуск отложили, а исправить баг до сих пор не могут.

На собеседовании строить ракету, и работать, чтобы закрутить шуруп.Хотя я хочу только шуруп, но мне нужно использовать технологию строительства ракеты, чтобы найти работу по закручиванию шурупа.Как я могу сделать себя непобедимым во время Процесс собеседования?Чистка вопросов — это сравнение Хороший ярлык, сегодня я обобщу некоторые из наиболее классических вопросов интервью и поделюсь ими с вами.

Все темы в этой статье впервые появились на публике, чтобы сыграть в какой-то интерфейс [№], Сяо Бянь организует двухдневное интервью, а затем расскажет всем вашим друзьям, обеспокоенным небольшим сериалом, чтобы вы почистили лицо вопросы каждый день, не хотите соленую рыбу , вы хотите сменить работу, все еще колеблясь, обеспокоен === производители предлагают.

Тема 1

Введение в тему

Ниже приведен фрагмент кода, пожалуйста, улучшите функцию суммы, чтобы возвращаемое значение функции суммы (1,2,3,4,5,6) было равно 21 , вам нужно вызвать функцию asyncAdd в функции суммы, чтобы выполнять числовые операции, и функция asyncAdd не может быть изменена

/**
 * 请在 sum函数中调用此函数,完成数值计算
 * @param {*} a 要相加的第一个值
 * @param {*} b 要相加的第二个值
 * @param {*} callback 相加之后的回调函数
 */
function asyncAdd(a,b,callback) {
  setTimeout(function(){
   callback(null, a+b)
  },1000)
}

/**
 * 请在此方法中调用asyncAdd方法,完成数值计算
 * @param  {...any} rest 传入的参数
 */
async function sum(...rest) {
  // 请在此处完善代码
}

let start = window.performance.now()
sum(1, 2, 3, 4, 5, 6).then(res => {
  // 请保证在调用sum方法之后,返回结果21
  console.log(res)
  console.log(`程序执行共耗时: ${window.performance.now() - start}`)
})

Этот вопрос можно разделить на три уровня сложности в зависимости от разного времени вывода программы.

  1. Бронзовая сложность, время выхода более 6 секунд
  2. Серебряная сложность, время выхода больше 3 секунд
  3. Король сложности, время выхода более 1 секунды

Отвечать

  1. Бронзовая сложность
async function sum(...rest) {
  // 取出来第一个作为初始值
  let result = rest.shift()
  // 通过for of 遍历 rest, 依次相加
  for(let num of rest) {
    // 使用promise 获取相加结果
    result = await new Promise(resolve => {
      asyncAdd(result, num, (_,res) => {
        resolve(res)
      })
    })
  }
  // 返回执行结果
  return result
}

// 执行成功,执行时长大于6秒
sum1(1, 2, 3, 4, 5,6).then(res => {
  console.log(`计算结果为:${res}`)
})

  1. Серебряная сложность

На уровне сложности «Бронза» мы добавляем каждый элемент массива по очереди. Однако также можно выполнить некоторые оптимизации и одновременно выполнять несколько операций, например:sum(1,2,3,4,5,6), который может выполняться одновременно1+2,3+4,5+6, что может повысить эффективность выполнения

async function sum(...rest) {
  // 如果传的值少于2个,则直接返回
  if (rest.length <= 1) {
    return rest[0] || 0
  }
  const promises = []
  // 遍历将数组里面的值两个两个的执行
  for (let i = 0; i < rest.length; i += 2) {
    promises.push(
      new Promise(resolve => {
        // 如果 rest[i+1] 是 undefined, 说明数组长度是奇数,这个是最后一个
        if (rest[i + 1] === undefined) {
          resolve(rest[i])
        } else {
          // 调用asyncAdd 进行计算
          asyncAdd(rest[i], rest[i + 1], (_, result) => {
            resolve(result)
          })
        }
      })
    )
  }
  // 获取第一次计算结果
  const result = await Promise.all(promises)
  // 然后将第一次获取到的结果即 [3,7,11] 再次调用 sum执行
  return await sum(...result)
}

// 执行成功,执行时长大于3秒小于4秒
sum1(1, 2, 3, 4, 5,6).then(res => {
  console.log(`计算结果为:${res}`)
})
  1. Король сложности
async function sum(...rest) {
  let result = 0
  // 隐氏类型转换, 对象 + 数字,会先调用对象的toString 方法
  const obj = {}
  obj.toString = function() {
    return result
  }
  const promises = []
  for(let num of rest) {
    promises.push(new Promise((resolve) => {
      asyncAdd(obj, num, (_, res) => {
        resolve(res)
      })
    }).then(res => {
      // 在这里将 result的值改变之后,obj.toString 的返回值就变了,这时候下一个setTimeout调用时就使用了新值
      result = res
    }))
  }
  await Promise.all(promises)
  return result
}

// 执行成功,执行时长大于1秒小于2秒
sum1(1, 2, 3, 4, 5,6).then(res => {
  console.log(`计算结果为:${res}`)
})

потому чтоjsОн выполняется в одном потоке, поэтому приведенный выше код находится вfor ofввести все расчетыpromisesвнутри массива, а затем передатьPromise.allДля выполнения одноразового исполнения в это время не нужно учитывать, какие два числа добавляются первыми. Из-за однопоточных причин мы можем гарантировать, что этиPromiseвыполняется последовательно, в это времяobj.toStringВозвращаемое значение является предыдущимPromiseВозвращаемое значение, запустите код несколько раз, и вы поймете

тема вторая

Введение в тему

Пожалуйста, объясните, что выводит каждый из следующих кодов?

console.log(typeof (() => {}))

console.log(typeof ['前端有的玩','公众号'])

console.log(typeof null)

console.log(typeof undefined)

console.log(typeof Function.prototype)

console.log('子君' instanceof String)

console.log(new Date() instanceof Date)

Отвечать

// 输出 function
console.log(typeof (() => {}))

// 输出 object
console.log(typeof ['前端有的玩','公众号'])

// 输出 object
console.log(typeof null)

// 输出 undefined
console.log(typeof undefined)

// 输出 function 
console.log(typeof Function.prototype)

// 输出 false
console.log('子君' instanceof String)

// 输出 true
console.log(new Date() instanceof Date)

Следует отметить, что дляtypeof, можно правильно судить, что помимоnullВсе базовые типы, кроме ссылочных, кроме функций, будут оцениваться какobject.

дляinstanceof, не может судить об основном типе, но может правильно судить об эталонном типе

тема три

Введение в тему

пожалуйста, реализуйтеinstanceof, чтобы следующий код мог работать нормально

/**
 自定义instanceof 
*/
function instanceOf(left, right) {
    // 请完善以下代码,不能使用原生instanceof
}

class A{}
class B extends A {}
class C{}

const b = new B()
// 输出 true
console.log(instanceOf(b,B))
// 输出 true
console.log(instanceOf(b,A))
// 输出 false
console.log(instanceOf(b,C))

Отвечать

Основное исследование этой темыinstanceofпринцип суждения,instanceofОсновной принцип реализации заключается в том, что пока правильная переменнаяprototypeНа цепочке прототипов переменная слева. следовательно,instanceofВ процессе поиска будет проходиться цепочка прототипов левой переменной до тех пор, пока не будет найдена правая переменная.prototype, который вернется, если поиск завершится ошибкойfalse.

/**
  自定义instanceof 
*/
function instanceOf(left, right) {
  let proto = left.__proto__
  while(proto){
    if(proto === right.prototype){
       return true
    }
    proto = proto.__proto__
  }  
  return false
}

class A{}
class B extends A {}
class C{}

const b = new B()
// 输出 true
console.log(instanceOf(b,B))
// 输出 true
console.log(instanceOf(b,A))
// 输出 false
console.log(instanceOf(b,C))

тема четвертая

Введение в тему

Пожалуйста, смоделируйтеnewоператор, чтобы следующий код работал правильно

function myNew(constructor, ...rest) {
 // 请在此处完善代码,不能直接使用 new 操作符
}
function Fun(name,sex) {
  this.name = name
  this.sex = sex
}
Fun.prototype.getUserInfo = function() {
  return `我的姓名${this.name},我的性别${this.sex}`
}

const fun = myNew(Fun,'子君','男')
// 我的姓名子君,我的性别男
console.log(fun.getUserInfo())

Отвечать

Этот вопрос исследует использованиеnew操作符Этапы, через которые вызывается конструктор:

  1. создать новый объект;
  2. присвойте области конструктора новому объекту;
  3. выполнить код в конструкторе;
  4. вернуть новый объект;
function myNew(constructor, ...rest) {
  if (typeof constructor !== 'function') {
        return constructor;
    }
    //创建新的对象,关联构造函数的原型对象
    const _constructor = Object.create(constructor.prototype);
    //执行构造函数
    const obj = constructor.apply(_constructor, rest);
    //如果构造函数执行结果是对象则返回执行结果
    if (typeof obj === 'object') {
        return obj;
    } else {
        return _constructor;
    }
}
function Fun(name,sex) {
  this.name = name
  this.sex = sex
}
Fun.prototype.getUserInfo = function() {
  return `我的姓名${this.name},我的性别${this.sex}`
}

const fun = myNew(Fun,'子君','男')
// 我的姓名子君,我的性别男
console.log(fun.getUserInfo())

пятая тема

Введение в тему

Скажите, что выводит следующий код

const a = {}
const b = Symbol('1')
const c = Symbol('1')
a[b] = '子君'
a[c] = '君子'

// 我是子君还是君子呢
console.log(a[b])

const d = {}
const e = {key: '1'}
const f = {key: '2'}
d[e] = '子君'
d[f] = '君子'

// 我是子君还是君子呢
console.log(d[e])

Отвечать

const a = {}
const b = Symbol('1')
const c = Symbol('1')
a[b] = '子君'
a[c] = '君子'

// 输出子君
console.log(a[b])

const d = {}
const e = {key: '1'}
const f = {key: '2'}
d[e] = '子君'
d[f] = '君子'

// 输出君子
console.log(d[e])

Для первого выходаSymbol()Функция возвращает значение типа **"символ"**, иSymbolПараметры, передаваемые в функцию, используются только для идентификации и не влияют на уникальность значения.

Для второго выхода, потому чтоeа такжеfявляются объектами, а объектыkeyЭто может быть только числовое значение или символ, поэтому объект будет преобразован в символ,toStringметод возвращает[object Object], все выходы джентльменские

тема шесть

Введение в тему

Скажите, что выводит следующий код

console.log([] + [])
console.log({} + [])
console.log([] == ![])
console.log(true + false)

Отвечать

  1. первая строка кода
// 输出 "" 空字符串
console.log([] + [])

Эта строка кода выводит пустую строку"", когда тип оболочки работает, он сначала вызоветvalueOfметод, еслиvalueOfВозврат по-прежнему является типом оболочки, затем снова вызовитеtoStringметод

// 还是 数组
const val = [].valueOf()
// 数组 toString 默认会将数组各项使用逗号 "," 隔开, 比如 [1,2,3].toSting 变成了"1,2,3",空数组 toString 就是空字符串
const val1 = val.toString() // val1 是空字符串

Так что вышеуказанный код эквивалентен

console.log("" + "")
  1. вторая строка кода

    // 输出 "[object Object]"
    console.log({} + [])
    

    Как и в случае с первым вопросом, объект{}неявно преобразуется в[object Object], а потом с""добавить

  2. третья строка кода

    // 输出 true
    console.log([] == ![])
    

    для===, будет строго сравнивать два значения, но для==это не одно и то же

    Итак, для приведенного выше кода посмотрите на следующий пошаговый анализ.

    // 这个输出 false
    console.log(![])
    // 套用上面第三条 将 false 转换为 数值
    // 这个输出 0
    console.log(Number(false))
    // 包装类型与 基本类型 == 先将包装类型通过 valueOf toString 转换为基本类型 
    // 输出 ""
    console.log([].toString())
    // 套用第2条, 将空字符串转换为数值、
    // 输出 0
    console.log(Number(""))
    // 所以
    console.log(0 == 0)
    
    1. Напримерnull == undefined
    2. если неnumberа такжеnumberсравнения, он будет преобразован вnumber
    3. Если одна из двух сторон сравненияboolean, то первыйbooleanПеревести вnumber
  3. четвертая строка кода

    // 输出 1
    console.log(true + false)
    

    Добавьте два базовых типа, если один из них является символом, другой преобразуйте в символьное сложение, в противном случае преобразуйте тип вNumber, а затем сложить,Number(true)да1, Number(false)да0, так что результат1

Все вопросы в этой статье были впервые опубликованы на официальном аккаунте [Некоторые играют на фронтенде]. Редактор будет организовывать один или два вопроса для интервью каждый день, а затем рассылать их всем друзьям. Следуйте за редактором и отведите вас на чистку интервью вопросы каждый день Я не хочу быть соленой рыбой. , Хотите сменить работу, что вы все еще колеблетесь, обратите внимание на === большое заводское предложение.

Эпилог

Не истощайте свое вдохновение и воображение, не будьте рабом своих моделей. - Винсент Ван Гог