Обновление: Спасибо за вашу поддержку. Недавно я бросил сводку данных для всех, чтобы прочитать систему. В будущем будет больше контента и больше оптимизации.Нажмите здесь, чтобы просмотреть
------ Далее идет текст ------
введение
Второй выпуск журнала, выходящего два раза в месяц, здесь. За это время Daily-Interview-Question добавил 10 новых высокочастотных вопросов для интервью. Сегодня я пришлю вам вопросы для интервью и некоторые ответы, собранные за последние полмесяца. чтобы помочь вам проверить и заполнить вакансии.
Добро пожаловать в PR вопросы интервью, которые вы считаете хорошими, можете оставлять свои ответы в разделе «Проблема проекта» и приглашаем обсудить, если у вас есть какие-либо вопросы.
Адрес проекта:Daily-Interview-Question
Вопрос 15: Краткое объяснение мультиплексирования HTTP2
В HTTP/1 для каждого запроса устанавливается TCP-соединение, это то, что мы часто называем 3 рукопожатиями и 4 волнами, что занимает много времени в процессе запроса, даже если включен Keep-Alive, это решает проблему. Проблема множественных подключений, но есть еще две проблемы с эффективностью:
- Первый: последовательная передача файлов. Когда файл запрашивается, файл b может только ждать, ожидая, пока a подключится к серверу, сервер обработает файл и сервер вернет файл, эти три шага. Мы предполагаем, что эти три шага занимают 1 секунду, затем файл a занимает 3 секунды, передача файла b занимает 6 секунд и так далее. (Примечание: для этого расчета есть обязательное условие, то есть браузер и сервер имеют одноканальную передачу)
- Второе: слишком много связей. Мы предполагаем, что Apache устанавливает максимальное количество параллелизма равным 300. Из-за ограничений браузера максимальное количество запросов, инициируемых браузером, равно 6 (Chrome), то есть максимальное количество одновременных запросов, которые может выполнять сервер, равно 50. При посещении 51-го человека нужно подождать, предыдущий запрос обработан.
HTTP2 передается в двоичном формате, заменяя текстовый формат HTTP1.x, а анализ двоичного формата более эффективен. Мультиплексирование заменяет механизм последовательности и блокировки HTTP1.x, и все запросы на одно и то же доменное имя выполняются одновременно через одно и то же соединение TCP. В HTTP1.x для нескольких одновременных запросов требуется несколько TCP-подключений, а браузеры ограничены 6-8 TCP-подключениями для управления ресурсами. HTTP2
- Вся связь под одним и тем же доменным именем осуществляется в одном соединении, что устраняет задержки и потребление памяти, вызванные несколькими TCP-соединениями.
- Запросы и ответы, которые могут чередоваться параллельно в одном соединении, не мешая друг другу
Больше анализа:GitHub.com/advanced-fr…
Вопрос 16. Расскажите о своем понимании трехэтапного рукопожатия TCP и четырехэтапной волны.
Больше анализа:GitHub.com/advanced-fr…
Вопрос 17: После того, как машины A и B нормально подключены, машина B внезапно перезагружается и спрашивает, в каком состоянии TCP находится A в это время.
Если A и B установили нормальное соединение, они никогда не отправляли данные друг другу.В это время B внезапно перезагружает машину и спрашивает, в каком состоянии TCP находится A в это время? Как избавиться от этого состояния в серверной программе? (Превышение контура, вы можете понять это)
Поскольку B войдет в состояние прослушивания конечного автомата tcp после перезапуска, до тех пор, пока a повторно отправляет пакет данных (будь то пакет синхронизации или данные приложения), сторона b должна активно отправлять пакет сброса с первым битом для подключения . reset, поэтому a должен находиться в состоянии syn_sent.
Больше анализа:GitHub.com/advanced-fr…
Вопрос 18: Когда setState в React синхронный, а когда асинхронный?
В React, если обработка событий инициируется React (например, обработка событий, инициируемая onClick), вызов setState не будет синхронно обновлять this.state, а другие вызовы setState будут выполнять this.state синхронно. Так называемое «в дополнение к этому» относится к обработчикам событий, напрямую добавляемым addEventListener в обход React, а также к асинхронным вызовам, генерируемым setTimeout/setInterval.
**Причина:** В реализации функции React setState она будет основана на переменнойisBatchingUpdatesОпределите, обновлять ли это состояние напрямую или поместить его в очередь, а затем вернуться, а isBatchingUpdates по умолчанию имеет значение false, что означает, что setState будет обновлять это состояние синхронно, но есть функция batchedUpdates, которая изменит isBatchingUpdates на true , и когда React вызывает этот batchedUpdates перед вызовом обработчика событий, следствием этого является то, что обработчик события setState, управляемый React, не будет синхронно обновлять this.state.
Больше анализа:GitHub.com/advanced-fr…
Вопрос 19: Письменный тестовый вопрос React setState, что выводит следующий код?
class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}
componentDidMount() {
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 1 次 log
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 2 次 log
setTimeout(() => {
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 3 次 log
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 4 次 log
}, 0);
}
render() {
return null;
}
};
Разобрать:
1. Первый и второй раз находятся в жизненном цикле самого react.При срабатывании isBatchingUpdates имеет значение true, поэтому состояние обновления не выполняется напрямую, а добавляется dirtyComponents, поэтому при печати получается состояние до обновления.0.
2. Когда setState используется дважды, this.state.val получается как 0, поэтому 0 устанавливается в 1 во время выполнения, которое будет объединено внутри реакции и выполнено только один раз. Значение state.val равно 1 после завершения настройки.
3. Код в setTimeout, isBatchingUpdates имеет значение false при запуске, поэтому его можно обновить напрямую, поэтому 2 и 3 выводятся вместе.
Выход: 0 0 2 3
Больше анализа:GitHub.com/advanced-fr…
Вопрос 20: Представьте механизм установки модуля npm, зачем вводить npm install для автоматической установки соответствующего модуля?
Разобрать:
1. Механизм установки модуля npm:
- проблема
npm install
Заказ - Запросить, существует ли уже указанный модуль в каталоге node_modules.
- Если он существует, не переустанавливайте
- если не существует
- npm запрашивает в реестре URL-адрес сжатого пакета модуля.
- Загрузите сжатый пакет и сохраните его в корневом каталоге.
.npm
в каталоге - Разархивируйте архив в папку текущего проекта
node_modules
содержание
2. Принцип реализации npm
После ввода команды npm install и нажатия Enter он пройдет следующие этапы (в качестве примера возьмем npm 5.5.1):
- Выполнить сам проект предустановить
Если текущий проект npm определяет хук предварительной установки, он будет выполнен в это время.
- Определить модуль зависимости первого уровня
Первое, что нужно сделать, это определить зависимости первого уровня в проекте, то есть модули, прямо указанные в свойствах dependencies и devDependencies (при условии, что параметр npm install в это время не добавлен).
Сам проект является корневым узлом всего дерева зависимостей. Каждый модуль зависимостей первого уровня представляет собой поддерево под корневым узлом. npm запустит несколько процессов, чтобы постепенно найти более глубокие узлы из каждого модуля зависимостей первого уровня.
- получить модуль
Получение модуля — это рекурсивный процесс, который делится на следующие этапы:
- Получить информацию о модуле. Перед загрузкой модуля необходимо сначала определить его версию, потому что package.json часто является семантической версией (semver, семантическая версия). На данный момент, если в файле описания версии (npm-shrinkwrap.json или package-lock.json) есть информация о модуле, вы можете получить ее напрямую, если нет — получить со склада. Если версия пакета в packageaeg.json ^1.1.0, npm отправится в репозиторий, чтобы получить последнюю версию в виде 1.x.x.
- Получите сущность модуля. На предыдущем шаге будет получен адрес сжатого пакета (resolved field) модуля, и npm будет использовать этот адрес для проверки локального кеша, если он есть в кеше, то он будет взят напрямую, если нет, то он будут загружены со склада.
- Найдите зависимость модуля, если есть зависимость, вернитесь к шагу 1, если нет, остановитесь.
- Сведение модулей (дедупликация)
На предыдущем шаге вы получаете полное дерево зависимостей, которое может содержать множество повторяющихся модулей. Например, модуль A зависит от lodash, а модуль B также зависит от lodash. До npm3 он будет устанавливаться строго по структуре дерева зависимостей, поэтому вызовет избыточность модулей.
Процесс дедупликации был добавлен по умолчанию, начиная с npm3. Он проходит через все узлы и помещает модули один за другим под корневым узлом, который является первым уровнем узлов-модулей. когда нашлиповторный модульотбрасывается.
нужно быть здесьповторный модульдать определение, к которому относитсято же имя модуляа такженесколько совместимы. Каждому семверу соответствует диапазон допустимых версий.Если допустимые диапазоны версий двух модулей перекрываются, то можно получить совместимую версию.version без необходимости сопоставлять номера версий, что позволяет удалить больше избыточных модулей в процессе дедупликации.
- Установите модуль
Этот шаг обновит node_modules в проекте и выполнит функции жизненного цикла в модуле (в порядке предварительной установки, установки, постустановки).
- Выполнение собственного жизненного цикла проекта
Если текущий проект npm определяет хуки, он будет выполнен в это время (в порядке установки, постустановки, предварительной публикации, подготовки).
Последним шагом является создание или обновление файла описания версии, и процесс установки npm завершен.
Больше анализа:GitHub.com/advanced-fr…
Вопрос 21: Существуют следующие 3 метода оценки массивов, укажите их различия, преимущества и недостатки соответственно.
Object.prototype.toString.call(), instanceof и Array.isArray()
Разобрать:
1. Object.prototype.toString.call()
Каждый объект, который наследует Object, имеетtoString
метод, еслиtoString
Если метод не переопределен, он вернет[Object type]
, где тип — это тип объекта. Но когда помимо объектов типа Object используются непосредственно другие типыtoString
метод, он будет напрямую возвращать строку содержимого, поэтому нам нужно использовать метод call или apply, чтобы изменить контекст выполнения метода toString.
const an = ['Hello','An'];
an.toString(); // "Hello,An"
Object.prototype.toString.call(an); // "[object Array]"
Этот метод работает для всех основных типов данных, даже для null и undefined.
Object.prototype.toString.call('An') // "[object String]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call({name: 'An'}) // "[object Object]"
Object.prototype.toString.call()
Обычно используется для определения встроенных объектов браузера.
2. instanceof
instanceof
Внутренний механизм заключается в том, чтобы определить, можно ли найти тип в цепочке прототипов объекта.prototype
.
использоватьinstanceof
Определить, является ли объект массивом,instanceof
Он определит, будет ли найден соответствующий объект в цепочке прототипов этого объекта.Array
Прототип , найти возвращаетtrue
, иначе возвратfalse
.
[] instanceof Array; // true
ноinstanceof
Его можно использовать только для определения типа объекта, а не исходного типа. И все типы объектов instanceof Object имеют значение true.
[] instanceof Object; // true
3. Array.isArray()
-
Функция: используется для определения того, является ли объект массивом.
-
instanceof и isArray
При обнаружении экземпляров массива
Array.isArray
лучше чемinstanceof
,потому чтоArray.isArray
может быть обнаруженiframes
var iframe = document.createElement('iframe'); document.body.appendChild(iframe); xArray = window.frames[window.frames.length-1].Array; var arr = new xArray(1,2,3); // [1,2,3] // Correctly checking for Array Array.isArray(arr); // true Object.prototype.toString.call(arr); // true // Considered harmful, because doesn't work though iframes arr instanceof Array; // false
-
Array.isArray()
а такжеObject.prototype.toString.call()
Array.isArray()
Новый метод в ES5, когда его не существуетArray.isArray()
,Можно использоватьObject.prototype.toString.call()
выполнить.if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; }
Больше анализа:GitHub.com/advanced-fr…
Вопрос 22: Представляем Repaint & Reflow и как его оптимизировать
Разобрать:
1. Механизм рендеринга браузера
- Браузер использует модель гибкой компоновки (
Flow Based Layout
) - Браузер будет
HTML
анализируется вDOM
,ПучокCSS
анализируется вCSSOM
,DOM
а такжеCSSOM
Слияние создает дерево рендеринга (Render Tree
). - имеют
RenderTree
, мы знаем стили всех узлов, затем вычисляем их размер и положение на странице и, наконец, рисуем узлы на странице. - Поскольку браузеры используют плавные макеты,
Render Tree
Вычисление , как правило, нужно пройти только один раз,За исключением таблиц и их внутренних элементов, для них может потребоваться несколько вычислений, обычно в 3 раза больше, чем для эквивалентных элементов, что является одной из причин, по которой избегают макетов таблиц..
2. Перерисовать
Макет не затрагивается из-за изменения геометрических свойств узла или из-за изменения стиля, называемого перерисовкой, напримерoutline
, visibility
, color
,background-color
и т. д., перерисовка стоит дорого, потому что браузер должен проверять видимость других элементов узла в дереве DOM.
3. Перекомпоновка
Перекомпоновка — это когда необходимо изменить макет или геометрические свойства, и это называется перекомпоновкой. Перекомпоновка — это ключевой фактор, влияющий на производительность браузера, поскольку его изменения связаны с обновлением макета для частей страницы (или всей страницы). Перекомпоновка элемента может привести к последующей перекомпоновке всех его дочерних элементов, а также непосредственно следующих узлов и элементов-предков в DOM.
<body>
<div class="error">
<h4>我的组件</h4>
<p><strong>错误:</strong>错误的描述…</p>
<h5>错误纠正</h5>
<ol>
<li>第一步</li>
<li>第二步</li>
</ol>
</div>
</body>
Во фрагменте HTML выше абзац (<p>
тег) перекомпоновка вызовет сильную перекомпоновку, потому что это дочерний узел. Это тоже приводит к обратному потоку предков (div.error
а такжеbody
– в зависимости от браузера). также,<h5>
а также<ol>
Также будут простые перекомпоновки, так как эти узлы появляются после перекомпоновки элементов в DOM.Большинство перекомпоновок приводят к повторному рендерингу страницы.
Перекомпоновка должна происходить при перерисовке, а перерисовка не обязательно приводит к перерисовке.
4. Оптимизация браузера
Большинство современных браузеров обновляют макет пакетами с помощью механизма очереди.Браузер поставит операцию модификации в очередь, и по крайней мере одно обновление браузера (т.е. 16,6 мс) очистит очередь, но когда выПри получении информации о макете в очереди могут быть операции, влияющие на возвращаемое значение этих свойств или методов. Даже если нет, браузер принудительно очистит очередь, запустив перекомпоновку и перерисовку, чтобы гарантировать, что возвращается правильное значение..
В основном он включает следующие свойства или методы:
-
offsetTop
,offsetLeft
,offsetWidth
,offsetHeight
-
scrollTop
,scrollLeft
,scrollWidth
,scrollHeight
-
clientTop
,clientLeft
,clientWidth
,clientHeight
-
width
,height
getComputedStyle()
getBoundingClientRect()
Поэтому нам следует избегать частого использования вышеуказанных свойств, все они заставляют рендеринг обновлять очередь.
5. Уменьшите перерисовку и перекомпоновку
- CSS
- Используйте преобразование вместо верха
- Заменить дисплей: нет с видимостью, потому что первое вызовет только перерисовку, второе вызовет перекомпоновку
-
Избегайте использования макета таблицы, небольшое изменение может привести к полной
table
перестановка. - Измените классы, насколько это возможно, в конце дерева DOM., рефлюкс неизбежен, но его эффект можно уменьшить. Изменение класса, насколько это возможно, в самом конце дерева DOM ограничивает область перекомпоновки, чтобы затронуть как можно меньше узлов.
- Избегайте установки нескольких слоев встроенных стилей., CSS-селекторсправа налевоПоиск соответствий, чтобы избежать слишком большого количества уровней узлов.
<div>
<a> <span></span> </a>
</div>
<style>
span {
color: red;
}
div > a > span {
color: red;
}
</style>
Для первой настройки стиля браузеру просто нужно найти всеspan
метку, а затем установить цвет, но для второго способа установки стиля браузеру сначала нужно найти всеspan
метка, затем найтиspan
на этикеткеa
метка и, наконец, найтиdiv
ярлык, а затем дайтеspan
Метка задает цвет, поэтому рекурсивный процесс очень сложен. Поэтому мы должны избегать написания как можно большеслишком конкретныйселекторы CSS, а затем добавьте в HTML как можно меньше бессмысленных тегов, чтобы убедиться, чтоИерархия квартира.
-
Примените эффект анимации к элементу, свойство position которого является абсолютным или фиксированным., чтобы не влиять на компоновку других элементов, это просто перерисовка, а не перекомпоновка, при этом скорость анимации управления можно выбирать
requestAnimationFrame
, видетьИсследуйте запросAnimationFrame. - Избегайте использования выражений CSS, может вызвать обратный поток.
-
Установите часто перерисовываемые или перекомпоновываемые узлы в качестве слоев, слой может предотвратить влияние рендеринга этого узла на другие узлы, например
will-change
,video
,iframe
и другие теги, браузер автоматически превратит узел в слой. -
Аппаратное ускорение CSS3 (ускорение GPU), с помощью аппаратного ускорения css3 можно сделать
transform
,opacity
,filters
Эти анимации не вызывают перерисовки перерисовки. Но для других свойств анимации, таких какbackground-color
Они по-прежнему будут вызывать перекомпоновку и перерисовку, но все же могут повысить производительность этих анимаций.
-
JavaScript
-
Избегайте частых стилей манипулирования, желательно разовую перезапись
style
или определите список стилей какclass
и поменять все сразуclass
Атрибуты. -
Избегайте частых манипуляций с DOM,Создавать
documentFragment
, на него распространяются всеDOM操作
и, наконец, добавьте его в документ. -
Избегайте частого чтения свойств, которые вызывают перекомпоновку/перерисовку, если вам действительно нужно использовать его несколько раз, используйте переменную для его кэширования.
-
Используйте абсолютное позиционирование для элементов со сложной анимацией, вынося его из потока документа, иначе это вызовет частую перекомпоновку родительского элемента и последующих элементов.
-
Больше анализа:GitHub.com/advanced-fr…
Вопрос 23. Опишите разницу между режимом наблюдателя и режимом подписки-публикации и в каких сценариях они применимы?
Разобрать:
соединять
Шаблон публикации-подписки является вариантом шаблона наблюдателя. Публикация-подписка просто абстрагирует часть функциональности в независимый менеджер изменений.
намерение
Это изменение объекта (субъекта, издателя) с уведомлением нескольких объектов (наблюдателей, подписчиков), которые от него зависят.
Различия и применимые сценарии
В целом модель публикации-подписки подходит для более сложных сценариев.
В сценарии «один ко многим» обновление издателя хочет уведомить только некоторых своих подписчиков?
В сценарии «многие к одному» или «многие ко многим». Подписчик зависит от нескольких издателей. Нужно ли уведомлять подписчиков после обновления издателя? Или дождаться обновления всех издателей, прежде чем уведомлять подписчиков?
Эта логика может быть размещена в ChangeManager.
Больше анализа:GitHub.com/advanced-fr…
Вопрос 24: Расскажите о дизайнерском мышлении Redux и Vuex.
Вы можете оставить свой ответ в разделе Проблема.