[Fortnightly 3] Резюме вопросов и ответов на высокочастотных собеседованиях перед началом работы

внешний интерфейс JavaScript

Обновление: Спасибо за вашу поддержку.Недавно официальный сайт блога был выкинут, чтобы каждый мог его систематически читать.В будущем будет больше контента и больше оптимизации.Нажмите здесь, чтобы просмотреть

------ Далее идет текст ------

введение

Приближается третий номер журнала, выходящего два раза в месяц.За это время в Daily-Interview-Question добавлено 15 новых высокочастотных вопросов для интервью.Сегодня я пришлю вам вопросы для интервью и некоторые ответы, собранные за последние полмесяца. чтобы помочь вам проверить и заполнить вакансии.

Все больше и больше полных вопросов интервью и ответов находятся в адресе проекта ниже, нажмите, чтобы посмотреть.

адрес проекта:Daily-Interview-Question

Вопрос 25: Расскажите о разнице между браузером и циклом событий Node.

браузер

Порядок выполнения микрозадач и макрозадач в браузере следующий:

  • Выполнение задачи (макрозадача)
  • Завершить выполнение очереди микрозадач (микрозадачи)

этот цикл продолжается и продолжается

Порядок выполнения задачи браузера (макроса) находится вhtml#event-loopsВ нем говорится, и он не будет переведен Общие задачи (макрозащитные задачи), такие как: SettimeOut, Setinterval, Script (общий код), операции ввода / вывода, рендеринг пользовательского интерфейса и т. Д. Общие микрозаправки, такие как: новое обещание (). Затем (обратный вызов), MutationObserver (HTML5 новые функции) и т. Д.

Node

Цикл событий Node реализован в libuv, ссылка на официальный сайт Fig:

default

Общий порядок выполнения задачи (макроса задачи) следующий:

  • таймеры: на этом этапе выполняются запланированные функции обратного вызова setTimeout() и setInterval().
  • ожидающие обратные вызовы: обратные вызовы ввода-вывода, выполнение которых отложено до следующей итерации цикла.
  • бездействие, подготовка: используется только внутри системы.
  • опрос опроса: получение новых событий ввода-вывода; выполнение обратных вызовов, связанных с вводом-выводом (почти во всех случаях, за исключением обратных вызовов выключения, которые запланированы таймерами и setImmediate()), в остальных узлах блокируется здесь.
  • проверка обнаружения: здесь выполняется функция обратного вызова setImmediate().
  • Обратные вызовы закрытия закрывают функцию обратного вызова: некоторые функции обратного вызова, готовые к закрытию, например Socket.on('close',...).

Порядок выполнения микрозадач и макрозадач в Node

До узла 10:

  • Выполнить все задачи на этапе
  • После выполнения содержимого очереди nextTick
  • Затем выполните содержимое очереди микрозадач

После узла 11: Он унифицирован с поведением браузера, то есть каждый раз, когда выполняется задача макроса, выполняется очередь микрозадачи.

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 25: Различия между циклами событий браузера и узла

Вопрос 26: Знакомство с историей модульной разработки

Доступно в IIFE, AMD, CMD, CommonJS, UMD, webpack (require.ensure), модуле ES,<script type="module">Рассмотрим эти углы.

отвечать:

Модульность в основном используется для извлечения общего кода, изоляции области действия и предотвращения конфликтов переменных.

IIFE: Используйте самореализацию функций для записи модульности, функций:Выполнять код в отдельной области действия, избегая конфликтов переменных..

(function(){
  return {
	data:[]
  }
})()

AMD: Используйте requireJS для написания модульности, функции:Зависимости должны быть объявлены заранее.

define('./index.js',function(code){
	// code 就是index.js 返回的内容
})

CMD: Используйте seaJS для написания модульности, возможности:Поддержка динамического импорта файлов зависимостей.

define(function(require, exports, module) {  
  var indexCode = require('./index.js');
});

CommonJS: Модульность, которая приходит с nodejs.

var fs = require('fs');

UMD: Совместимость с модульным синтаксисом AMD, CommonJS.

webpack(require.ensure): Разделение кода в версиях webpack 2.x.

ES Modules: Модульность, представленная ES6, поддерживает импорт для введения другого js.

import a from 'a';

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 26: Модульная разработка во внешнем интерфейсе

Вопрос 27: Переменные, объявленные с помощью const и let, не находятся в окне глобальной области видимости, где они? Как получить его? .

В ES5 свойства объекта верхнего уровня эквивалентны глобальным переменным, а глобальные переменные, объявленные командой var и командой function, естественно являются объектами верхнего уровня.

var a = 12;
function f(){};

console.log(window.a); // 12
console.log(window.f); // f(){}

Однако ES6 предусматривает, что глобальные переменные, объявленные командой var и командой function, по-прежнему являются свойствами объекта верхнего уровня, но глобальные переменные, объявленные командой let, командой const и командой class, не являются свойствами объекта верхнего уровня. объект уровня.

let aa = 1;
const bb = 2;

console.log(window.aa); // undefined
console.log(window.bb); // undefined

Где? Как получить его? Посмотрите, как браузер обрабатывает это, устанавливая точки останова:

letandconst

Как также видно из приведенного выше рисунка, в глобальной области видимости глобальные переменные, объявленные с помощью let и const, находятся не в глобальном объекте, а только в области блочного уровня (сценарии).

Как получить его? Его можно получить в блочной области видимости, где определена переменная, так как она не принадлежит объекту верхнего уровня, то окно (глобальное) не добавляется.

let aa = 1;
const bb = 2;

console.log(aa); // 1
console.log(bb); // 2

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 27: Переменные, объявленные в const и let, не находятся в окне

28 Вопросов: Печенье и токен хранятся в заголовке, токен угона, почему нет?

1. Во-первых, токен не для предотвращения XSS, а для предотвращения CSRF; 2. Причина CSRF-атаки в том, что браузер автоматически доставит куки, но не токен автоматически.

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 28: И куки, и токены хранятся в заголовке, почему бы не захватить токен?

Вопрос 29. Расскажите о двусторонней привязке данных Vue, о том, как модель меняет представление и как представление меняет модель.

img

VM в основном сделал две второстепенные вещи:

  • Сопоставление от M к V (привязка данных), что может сэкономить вам много кода для обновления View
  • Слушатели событий от V до M (DOM Listeners), так что ваша модель будет меняться, когда представление запускает событие

1. Реализация M-V

Первым шагом в этом является формирование чего-то вроде:

// template
var tpl = '<p>{{ text }}</p>';
// data
var data = {
text: 'This is some text'
};
// magic process
template(tpl, data); // '<p>This is some text</p>'

Волшебный процесс посередине — это то, что делает механизм шаблонов, и уже существует множество механизмов шаблонов на выбор.

Конечно, если вы предпочитаете строить колеса, вы также можете изготовить их самостоятельно.

Будь то $scope в Angular, состояние React или данные Vue, все они предоставляют базовый объект модели для сохранения состояния модели; их механизмы шаблонов немного отличаются, но общая идея схожа; после получения отрендеренной строки подключите ее. самоочевидно, что делать дальше (в середине еще много обработки, например, использование diff модели для минимального обновления представления).

Но этого недостаточно, нам нужно знать, когда обновлять представление (т.е. рендеринг) Вообще говоря, основная виртуальная машина делает следующий выбор:

  • Когда экземпляр виртуальной машины инициализирован
  • Модель

Про инициализацию для получения объекта модели и потом рендеринга и говорить нечего, как следить за изменением атрибутов при модификации модели - проблема, на данный момент есть следующие идеи:

  • С помощью метода наблюдения объекта
  • Инициируйте событие изменения в общих операциях набора и массива самостоятельно
  • Вручную setState(), затем вызовите событие изменения внутри

Зная, когда запускать рендеринг и как рендерить, реализовано простое отображение M в V.

2. Реализация от V до M

От V до M в основном состоят из двух типов (хотя они, по сути, прослушивают DOM), один из которых является прослушивателем, определяемым пользователем, а другой — прослушивателем, который автоматически обрабатывается виртуальной машиной с элементами атрибута значения.

Первый тип похож на то, что вы привязываете, когда используете v-on в Vue.При создании экземпляра виртуальная машина может одновременно проксировать все пользовательские слушатели к корневому элементу, и эти слушатели могут получить доступ к вашему объекту модели. можно изменить модель в слушателе

Вторая категория похожа на автоматическую обработку элементов, содержащих v-model и value , что мы ожидаем, например, внутри поля ввода.

<input type="text" v-model="message" />

Введите значение, тогда мое соответствующее сообщение атрибута модели также изменится, что эквивалентно тому, что виртуальная машина создаст прослушиватель по умолчанию, который будет прослушивать изменения этих элементов и автоматически изменять модель. Я думаю, вы можете понять, как это реализовать.

Справочный адрес:Как создать модель представления в mvvm?

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 29

Вопрос 30: объединить два массива в один массив

Поместите два массива ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2'] и ['A', 'B', 'C' , 'D'], объединенные в ['A1', 'A2', 'A', 'B1', 'B2', 'B', 'C1', 'C2', 'C', 'D1', ' Д2", "Д"].

решение:

let a1 =  ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2']
let a2 = ['A', 'B', 'C', 'D'].map((item) => {
  return item + 3
})

let a3 = [...a1, ...a2].sort().map((item) => {
  if(item.includes('3')){
    return item.split('')[0]
  }
  return item
})

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 30

Вопрос 31: Измените приведенный ниже код так, чтобы он выдавал от 0 до 9, и напишите любое решение, которое придет вам в голову.

for (var i = 0; i< 10; i++){
	setTimeout(() => {
		console.log(i);
    }, 1000)
}

Решение 1:

for (var i = 0; i< 10; i++){
   setTimeout((i) => {
   	  console.log(i);
   }, 1000,i)
}

Решение 2:

for (var i = 0; i< 10; i++){
  ((i) => {
    setTimeout(() => {
      console.log(i);
    }, 1000)
 })(i)
}

Решение 3:

for (let i = 0; i< 10; i++){
  setTimeout(() => {
    console.log(i);
  }, 1000)
}

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 31

Вопрос 32: Действительно ли виртуальный DOM быстрее, чем манипулирование родным DOM? Говорите о своих мыслях.

Используя ответ Юды:

1. Нативные манипуляции с DOM по сравнению с манипуляциями, инкапсулированными в Framework.

Это компромисс между производительностью и ремонтопригодностью. Смысл фреймворка в том, чтобы замаскировать для вас базовые манипуляции с DOM, позволяя вам описать свою цель более декларативным способом, тем самым упрощая поддержку вашего кода. Ни один фреймворк не может оптимизировать операции DOM быстрее, чем чисто ручные операции, потому что уровень манипулирования DOM фреймворка должен иметь дело с любыми операциями, которые могут быть сгенерированы API верхнего уровня, и его реализация должна быть универсальной. Я могу написать ручную оптимизацию быстрее, чем любой фреймворк для любого бенчмарка, но какой в ​​этом смысл? При создании реального приложения вы все оптимизируете вручную? По соображениям ремонтопригодности это, очевидно, невозможно. Гарантия, которую дает фреймворк, заключается в том, что я могу обеспечить достойную производительность без ручной оптимизации.

2. Непонимание виртуального DOM React.

React никогда не говорил, что «React быстрее, чем манипулирование DOM изначально». Основной образ мышления React заключается в том, чтобы перерисовывать все приложение каждый раз, когда в него вносятся изменения. Если Virtual DOM отсутствует, простой идеей является прямой сброс innerHTML. Многие люди не понимают, что сброс innerHTML на самом деле является разумным, когда все данные в большом списке изменились... Настоящая проблема заключается в менталитете «перерисовать все», даже если изменилась только одна строка данных. , а также необходимо сбросить весь innerHTML, что, очевидно, является большой тратой времени.

Мы можем сравнить стоимость перерисовки innerHTML и Virtual DOM:

  • innerHTML: отображать строку html O (размер шаблона) + воссоздавать все элементы DOM O (размер DOM)
  • Виртуальный DOM: рендеринг Virtual DOM + diff O (размер шаблона) + необходимое обновление DOM O (изменение DOM)

Виртуальный рендеринг DOM + diff явно медленнее, чем рендеринг html-строк, но! Это по-прежнему чистые вычисления на уровне js, которые все еще намного дешевле, чем последующие операции DOM. Видно, что общий объем вычислений innerHTML, будь то расчет js или операция DOM, связан с размером всего интерфейса, но в объеме вычислений Virtual DOM только расчет js связан с размером интерфейса, и операция DOM связана с объемом изменения данных. Как упоминалось ранее, вычисления js чрезвычайно дешевы по сравнению с манипулированием DOM. Вот почему существует виртуальный DOM: он гарантирует, что 1) независимо от того, насколько сильно меняются ваши данные, производительность каждой перерисовки является приемлемой; 2) вы все равно можете написать свое приложение аналогично innerHTML.

3. Сравнение производительности также зависит от случая

При сравнении производительности вы должны очистить начальную рендеринг, небольшое количество обновлений данных и большие данные обновляют эти разные случаи. Виртуальный дом, грязная проверка MVVM, сбор данных MVVM имеет разные характеристики и различные потребности оптимизации в разных случаях. Виртуальный DOM также требует целевой оптимизации, такую ​​как необходимые для необходимости необходимых или неизменных данных.

  • Небольшой объем обновления данных: зависит от коллекции >> Virtual DOM + оптимизация> грязная проверка (не оптимизирована)> Virtual DOM без оптимизации
  • Массовое обновление данных: грязная проверка + оптимизация >= сбор зависимостей + оптимизация > Virtual DOM (оптимизация не требуется) >> MVVM без оптимизации

Не будьте наивны, думая, что Virtual DOM работает быстро, diff не бесплатен, пакетная обработка или MVVM могут это сделать, а окончательный патч не использует собственный API. На мой взгляд, реальная ценность Virtual DOM никогда не заключалась в производительности, а в том, что он 1) открывает дверь для функционального программирования пользовательского интерфейса и 2) может отображать бэкэнды за пределами DOM, такие как ReactNative.

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 32

Вопрос 33: Что печатает приведенный ниже код и почему?

var b = 10;
(function b(){
    b = 20;
    console.log(b); 
})();

отвечать:

  1. Выражение функции отличается от объявления функции, имя функции допустимо только внутри функции, а привязка является привязкой константы.
  2. Присвоение константе сообщит об ошибке в строгом режиме и автоматически завершится ошибкой в ​​нестрогом режиме.
  3. Функции в IIFE являются функциональными выражениями, а не объявлениями функций.

На самом деле он немного похож на следующий код, но не совсем такой же, потому что использование const приведет к ошибке типа TypeError независимо от того, в каком режиме он находится.

const foo = function () {
  foo = 10;
  console.log(foo)
}
(foo)() // Uncaught TypeError: Assignment to constant variable.

Функция b является константой, эквивалентной константе, определенной const, и не может быть переназначена внутри. Если она находится в строгом режиме, будет сообщено об ошибке «Uncaught TypeError: Assignment to Constant Variable». Например следующее:

var b = 10;
(function b() {
  'use strict'
  b = 20;
  console.log(b)
})() // "Uncaught TypeError: Assignment to constant variable."

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 33

Вопрос 34: Просто измените приведенный ниже код, чтобы он печатал 10 и 20 соответственно.

var b = 10;
(function b(){
    b = 20;
    console.log(b); 
})();

решение:

分åˆ"打印出 10 和 20

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 34

Вопрос 35: Правила чтения кэша браузера

Его можно разделить на Service Worker, кэш-память, кэш-память и кэш-память.Что является основой для кэш-памяти и кэш-памяти при запросе, и когда данные хранятся в кэш-памяти и дисковом кэше?

отвечать:

В основном:

  1. Если Service Worker включен, он сначала будет взят из Service Worker
  2. Если вы открываете новую страницу, которая была открыта ранее, кеш будет взят из кеша диска (при условии, что сильный кеш попал)
  3. При обновлении текущей страницы браузер будет решать, брать ли ее из кэша памяти или из кэша диска в соответствии с памятью текущей операционной среды (вы можете видеть, что последние несколько файлов на рисунке ниже иногда берутся из Кэш памяти и иногда берется из Кэш диска. )这是我的实验过程

Уведомление: Все приведенные выше ответы основаны на браузере Chrome.

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 35.

Резюме: Используйте итерацию для реализации функции Flatten.

Итеративная реализация:

let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]

const flatten = function (arr) {
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr)
    }
    return arr
}

console.log(flatten(arr))

Рекурсивная реализация (сокращение ES6):

const flatten = array => array.reduce((acc, cur) => (Array.isArray(cur) ? [...acc, ...flatten(cur)] : [...acc, cur]), [])

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 36

Вопрос 37: Почему мутации Vuex и редукторы Redux не могут выполнять асинхронные операции?

Вы можете оставить свой ответ в разделе Проблема.

Вопрос 38: При каких обстоятельствах находится печать 1 в коде ниже?

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

Решение 1. Используйте toString

let a = {
  i: 1,
  toString () {
    return a.i++
  }
}

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

Решение 2. Используйте значениеOf

let a = {
  i: 1,
  valueOf () {
    return a.i++
  }
}

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

Решение 3. Массивы немного демоничны

var a = [1,2,3];
a.join = a.shift;
if(a == 1 && a == 2 && a == 3) {
  console.log(1);
}

Решение 4: символы ES6

let a = {
    [Symbol.toPrimitive]: (i => () => ++i) (0)
};
if(a == 1 && a == 2 && a == 3) {
  console.log(1);
}

Решение 5: Object.defineProperty

Object.defineProperty(window, 'a', {
    get: function() {
          return this.value = this.value ? (this.value += 1) : 1;
    }
});
if(a == 1 && a == 2 && a == 3) {
  console.log(1);
}

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:№ 38.

Вопрос 39: Расскажите о BFC и его приложениях.

BFC — это концепция макета CSS, это независимая область рендеринга и среда, элементы внутри которой не будут влиять на элементы снаружи.

  • Как сгенерировать BFC: (т.е. из документооборота)

    • 1. Корневой элемент, который является элементом HTML (самый большой BFC).
    • 2. Значение float не равно none
    • 3. Значение позиции абсолютное или фиксированное
    • 4. Значение переполнения не отображается (значение по умолчанию. Содержимое не будет обрезано и будет отображаться за пределами поля элемента)
    • 5. Значение display: inline-block, table-cell, table-caption
  • Правила компоновки BFC:

    • 1. Внутренние ящики будут размещены один за другим в вертикальном направлении.

    • 2. Поля двух соседних блоков, принадлежащих одному BFC, будут перекрываться.

    • 3.BFC — это изолированный и независимый контейнер на странице, и дочерние элементы внутри контейнера не будут влиять на внешние элементы. И наоборот, эффект переноса текста, установить float

    • 4. Область BFC не будет перекрываться с поплавком.

    • 5. Рассчитать высоту БТЭ, в расчете также участвуют плавучие элементы

  • Роль БФК:

    • 1. Адаптивная двухколоночная верстка

    • 2. Может предотвратить закрытие элементов плавающими элементами.

    • 3. Может содержать плавающие элементы --- очистить внутренний плавающий принцип: активировать свойство BFC родительского div, чтобы все следующие дочерние div находились в одной и той же области BFC родительского div

    • 4. При принадлежности к разным BFC это может предотвратить наложение полей.

Чтобы продолжить, нажмите, чтобы просмотреть более подробную информацию:Вопрос 39

общаться с

Продвинутая серия статей резюмируется следующим образом. В ней есть качественная фронтенд-информация. Если вы считаете, что это хорошо, нажмите звездочку.

GitHub.com/100 миллионов акционеров/Нет...

Я Му Иян, автор официального аккаунта Advanced Front-end Advancement, подписывайтесь на меняСосредоточьтесь на преодолении сложного фронтенд-собеседования каждую неделю. Далее, позвольте мне познакомить вас с миром продвинутого интерфейса и подбодрить друг друга на пути к продвинутому!