Резюме более десятка вопросов интервью с ответами

внешний интерфейс опрос
Резюме более десятка вопросов интервью с ответами

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

1. Какие существуют методы асинхронного программирования в JavaScript?

1. Функция обратного вызова

f1(f2);

Функция обратного вызова — это основной метод асинхронного программирования. Преимущества в том, что его легко написать, понять и развернуть; недостаток в том, что он не способствует чтению и сопровождению кода, высокая связанность (Coupling) между различными частями, процесс относительно хаотичен, и только один обратный вызов функция может быть указана для каждой задачи.

2. Мониторинг событий

f1.on('done',f2);

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

3. Опубликовать/подписаться

f1: jQuery.publish("done");
f2: jQuery.subscribe("done", f2);

Предполагая, что существует «центр сигналов», когда задача будет завершена, она «опубликует» сигнал в центре сигналов, и другие задачи могут «подписаться» на центр сигналов, чтобы знать, когда они могут начать выполняться. называется «шаблон публикации/подписки» (шаблон публикации-подписки), также известный как «шаблон наблюдателя» (шаблон наблюдателя). Сущность этого метода аналогична «отслеживанию событий», но у него есть то преимущество, что вы можете отслеживать работу программы, просматривая «центр сообщений», чтобы увидеть, сколько существует сигналов и сколько подписчиков у каждого сигнала.

4. Объект обещания

f1().then(f2);

Объект Promises — это спецификация, предложенная рабочей группой CommonJS для предоставления унифицированного интерфейса для асинхронного программирования; идея состоит в том, что каждая асинхронная задача возвращает объект Promise, у которого есть метод then, позволяющий указать функцию обратного вызова. Преимущество состоит в том, что функция обратного вызова записывается в цепочке, поток программы очень ясен и имеется полный набор вспомогательных методов, которые могут реализовать множество мощных функций, таких как указание нескольких функций обратного вызова, указание функции обратного вызова, когда возникает ошибка, и если задача была завершена, а затем добавить функцию обратного вызова, функция обратного вызова будет выполнена немедленно, поэтому не беспокойтесь о пропущенном событии или сигнале; недостатком является то, что ее относительно сложно написать и понимать.

2. Какие существуют методы мониторинга зависаний веб-страницы?

Катон

FPS веб-страницы

Содержимое веб-страницы постоянно меняется, и FPS веб-страницы — это только частота кадров, с которой браузер отображает эти изменения. Чем выше частота кадров, тем более гладкой выглядит веб-страница для пользователя, и наоборот.

Мониторинг метода Катона

Рассчитайте значение FPS веб-страницы каждую секунду, получите столбец данных, а затем проанализируйте его. Популярное объяснение состоит в том, что некоторый код JS регулярно выполняется через API requestAnimationFrame. Если браузер завис, частота рендеринга не может быть надежно гарантирована. Если кадр не может достигать 60 кадров за 1 с, это может косвенно отражать частоту кадров рендеринга браузер.

var lastTime = performance.now();
var frame = 0;
var lastFameTime = performance.now();
var loop = function(time) {
    var now =  performance.now();
    var fs = (now - lastFameTime);
    lastFameTime = now;
    var fps = Math.round(1000/fs);
    frame++;
    if (now > 1000 + lastTime) {
        var fps = Math.round( ( frame * 1000 ) / ( now - lastTime ) );
        frame = 0;    
        lastTime = now;    
    };           
    window.requestAnimationFrame(loop);   
}

Мы можем определить некоторые граничные значения, такие как 3 последовательных FPS ниже 20, можно считать, что веб-страница зависла.

3. Расскажите о сходствах и различиях между defer и async в теге script?

defer

Назначение этого свойства — указать, что скрипт не повлияет на построение страницы при выполнении. То есть сценарий задерживается до тех пор, пока вся страница не будет проанализирована перед запуском. Таким образом, установка атрибута defer для элемента скрипта эквивалентна указанию браузеру на немедленную загрузку, но с задержкой выполнения.

Спецификация HTML5 требует, чтобы сценарии выполнялись в том порядке, в котором они появляются, поэтому первый отложенный сценарий выполняется до второго отложенного сценария, а оба сценария выполняются до события DOMContentLoaded. На самом деле отложенные сценарии не обязательно будут выполняться по порядку и не будут выполняться до времени DOMContentLoad, поэтому лучше включать только один отложенный сценарий.

Для неподдерживаемых браузеров, таких как Safari, это не задержит выполнение или заблокирует рендеринг браузера.

async

Как и defer, этот атрибут используется для изменения поведения скрипта обработки. Как и в случае с defer, async работает только с внешними файлами сценариев и указывает браузеру немедленно загрузить файл. Но, в отличие от defer, сценарии, помеченные как async, не гарантируют, что они будут выполняться в том порядке, в котором они были заданы.

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

Суммировать

Хотя и async, и defer являются асинхронными, есть некоторые отличия: после загрузки файла сценария, отмеченного async, он будет выполнен немедленно, а файл сценария, отмеченный defer, необходимо выполнить до события DOMContentLoaded.

Его можно расширить: предварительная загрузка ссылок также может использоваться для ранней загрузки js, в чем разница между двумя вышеперечисленными? Также есть предложения по сценариям применения

4. Почему margin:auto обеспечивает центрирование по вертикали?

Концепция маржи:

Свойство поля задает свойства поля для всех четырех направлений (вверх, вниз, влево и вправо) для данного элемента. Это сокращение для четырех параметров свойства поля. Четыре параметра свойства поля: margin-top, margin-right, margin-bottom и margin-left. Указанный запас может быть отрицательным.

Верхние и нижние свойства поля не влияют на незаменяемые встроенные элементы, такие какspanа такжеcode.

добиться вертикального центрирования

Чтобы добиться вертикального центрирования, используйте абсолютное позиционирование:

div  {
        width: 20px;
        height: 20px;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
     }

Почему можно добиться вертикального центрирования

Блочные горизонтальные элементы, такие как элементы div (то же самое ниже), по умолчанию (не плавающие, абсолютное позиционирование и т. д.), горизонтальное направление автоматически заполняет внешний контейнер; если есть поле-лево / поле-право, отступы -left/padding-right, border-left-width/border-right-width и т. д., фактическая область содержимого будет сужена в ответ.

Однако свойства жидкости возникают, когда абсолютно позиционированный элемент имеет определенное значение позиционирования для свойства противоположного направления позиционирования. Абсолютно позиционированные элементы с плавающими свойствами имеют те же правила заполнения для margin:auto, что и обычные плавающие элементы, со следующими свойствами:

  • Если одна сторона фиксирована, одна сторона имеет значение auto, а auto — размер оставшегося пространства;

  • Если обе стороны автоматические, разделите оставшееся пространство поровну

5. Какие методы есть у CDN для оптимизации скорости загрузки статических ресурсов?

Вы можете обратиться к команде Alibaba Cloud«Мой взгляд на CDN». Обобщенно следующим образом:

Планирование ресурсов: CDN найдет сервер с оптимальным путем от пользователя в соответствии с IP-адресом пользователя, подключающегося к сети. Методы планирования в основном включают планирование DNS, планирование http 302 и планирование DNS с использованием HTTP (в основном используется для мобильных терминалов); Стратегия кэширования и извлечение данных: серверы CDN используют эффективные алгоритмы и структуры данных для быстрого извлечения ресурсов и обновления кэшей чтения; Оптимизация сети: оптимизируйте семиуровневую модель OSI для достижения цели оптимизации сети. Физический уровень L1: обновление оборудования повышает скорость Уровень канала передачи данных L2: найдите более быстрые сетевые узлы, сделайте Lastmile как можно короче. Уровень маршрутизации L3: оптимизация пути, поиск оптимального пути между двумя точками Транспортный уровень L4: оптимизация протокола TCP, сохранение длительного соединения, быстрое открытие TCP Прикладной уровень L7: статическое сжатие ресурсов, слияние запросов

6. В чем разница между выборкой и ajax?

Ядром технологии Ajax является объект XMLHttpRequest (сокращенно XHR). XHR предоставляет удобный интерфейс для отправки запросов и анализа ответов сервера. Возможность асинхронного получения дополнительной информации с сервера означает, что при нажатии пользователем новые данные могут быть получены без необходимости обновления страницы. См. пример вызова:

var xhr = createXHR();
xhr.onreadystatechange = function(){
    if (xhr.readyState == 4){
       if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
          alert(xhr.responseText);
          } else {
          alert("Request was unsuccessful: " + xhr.status);
        }
    }
};
xhr.open("get", "example.txt", true);
xhr.send(null);

Fetch утверждает, что является альтернативой ajax. Его API разработан на основе Promise. Старые браузеры не поддерживают Promise и должны использовать polyfill es6-promise. Например:

// 原生XHR
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(xhr.responseText)   // 从服务器获取数据
    }
}
xhr.send()
// fetch
fetch(url)
    .then(response => {
        if (response.ok) {
            return response.json();
        }
    })
    .then(data => console.log(data))
    .catch(err => console.log(err))

Похоже на удобство, цепочка then похожа на знакомый обратный вызов. В MDN, когда дело доходит до разницы между ним и jquery ajax, выборка очень странная:

Когда получен код состояния HTTP, представляющий ошибку, обещание, возвращенное из fetch(), не будет помечено как отклоненное, даже если код состояния ответа HTTP равен 404 или 500. Вместо этого он пометит статус обещания как разрешение (но установит для свойства ok возвращаемого значения разрешения значение false ) и пометит его как отклонение только в случае сбоя сети или блокировки запроса. По умолчанию fetch не отправляет и не получает файлы cookie с сервера, что может привести к запросам без проверки подлинности, если сайт использует сеансы пользователей (для отправки файлов cookie необходимо установить параметр учетных данных).

7. Найдите выходное значение кода (функция/прототип указывает на проблему)?

2

Функция также является объектом, который может иметь свойства и методы, Foo.getName назначена функция, которая выводит 2, поэтому вывод равен 2

Foo.getName = function () { console.log(2) }
Foo.getName() // 输出 2

4

Родительской областью действия getName() является окно, что эквивалентно вызову window.getName(), Foo() еще не выполнялась, вам не нужно учитывать влияние тела функции Foo на getName, последние два осталось

var getName = function () { console.log(4) } // 函数表达式
function getName() { // 函数声明
  console.log(5)
}

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

getName() // 输出 5
function getName() { // 函数声明
  console.log(5)
}

Но выражение функции в вопросе переопределит объявление функции, см. следующий абзац:

getName() // 输出 5, 函数声明提升的结果
var getName = function () { console.log(4) } // 函数表达式
getName() // 输出 4, 函数声明提升后, 又被函数表达式覆盖了
function getName() { // 函数声明
  console.log(5)
}
getName() // 还是输出 4, 覆盖的结果, 函数声明提升了, 不按照文本的顺序重新声明的, 你可以想象它被移到了最前边

1

Foo().getName()

Разбираем пошагово, приведенное выше утверждение эквивалентно

var context = Foo();
context.getName();

Посмотрите на объявление Foo:

function Foo() {
  // 下边这句没有 var, let 或 const, 相当于 window.getName = xxx
  getName = function () { console.log(1) }
  return this // 这里的 this 要看调用方式, 直接调用 Foo() 则 this 指向 window, new 调用, this 指向 new 出来的实例
}

Посмотрите внимательно на комментарии выше, window.getName был переписан в теле функции Foo, что является ключом к следующему выводу

1

Как проанализировано выше, выполнение функции Foo() перезаписывает window.getName, и теперь window.getName становитсяfunction () { console.log(1) }

2

new Foo.getName()

Оператор сначала выполняет Foo.getName, что согласуется с первым выводом, и выводит 2, но new вернет объект, который указывает на экземпляр, созданный new, но этот экземпляр здесь не используется, поэтому дальше не будет проанализировано.

3

new Foo().getName()

Разобрать следующим образом

var foo = new Foo()
foo.getName()

Если вы посмотрите и проанализируете его полностью, вы поймете, что экземпляр foo находится в теле функции Foo.Из знания прототипов мы можем знать, что если метод экземпляра вызывается и не может быть найден в методе экземпляра, то он будет найден в прототипе экземпляра.

То есть будет найден и выполнен следующий метод:

Foo.prototype.getName = function() { console.log(3) }

3

new new Foo().getName()

Разобрать следующим образом

var foo = new Foo();
var bar = new foo.getName();

сверхуnew Foo().getName()Из анализа вы можете узнать, что foo.getName() находится в прототипе foo.Здесь функция в прототипе новая, что эквивалентно ее выполнению сначала, а затем возвращению нового экземпляра.Выполнение здесь — это выполнение следующего таким образом:

Foo.prototype.getName = function() { console.log(3) }

Просто new возвращает дополнительный экземпляр, экземпляр не используется, ничего особенного.

Если вы все еще что-то не понимаете, рекомендуется прочитать главу 4 «Сущность языка JavaScript» (я читаю исправленную версию) о вызовах функций. конец Q официальной учетной записи на WeChat и ответ на электронную книгу для чтения, Кроме того, рекомендуется купить оригинальную версию.

8. Как определить, совпадают ли все левые и правые скобки. Такие как ( ( ​​))()((((()))))?

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    var stack = []
    var map = { 
        '(' : ')',
        '[': ']',
        '{': '}'
    }
    
    for (var char of s) {
        if(char in map) {
            stack.push(char)
        } else {
            if( !stack.length || char != map[stack.pop()]) {
                return false
            }
        }
    }
    
    // 如果最后stack 里没有元素了, 就一定是匹配的
    return !stack.length
};

9. Нарисовать сектор с помощью css?

width: 0;
height: 0;
border: solid 100px red;
border-color: red transparent transparent transparent;
border-radius: 100px;

10. Использовать css для вертикального и горизонтального центрирования известной или неизвестной ширины?

/
/ 1
.wraper {
position: relative;
.box {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
margin: -50px 0 0 -50px;
}
}


// 2
.wraper {
position: relative;
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}


// 3
.wraper {
.box {
display: flex;
justify-content:center;
align-items: center;
height: 100px;
}
}


// 4
.wraper {
display: table;
.box {
display: table-cell;
vertical-align: middle;
}
}
//5
.container {
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 200px;
background: #eee;
}
.parent {
background: grey;
justify-self: center;
align-self: center;
}
.child {
font-size: 30px;
}
//6、块级元素:calc()
.parent {
width: 300px;
height: 300px;
border: 1px solid red;
position: relative;
}
.child {
width: 100px;
height: 100px;
background: blue;
padding: -webkit-calc((100% - 100px) / 2);
padding: -moz-calc((100% - 100px) / 2);
padding: -ms-calc((100% - 100px) / 2);
padding: calc((100% - 100px) / 2);
background-clip: content-box;
}
//7、margin:auto实现绝对定位元素的居中
.element {
width: 600px; height: 400px;
position: absolute; left: 0; top: 0; right: 0; bottom: 0;
margin: auto; /* 有了这个就自动居中了 */
}
//8、
.parent{
display: flex;
}
.parent{
display: flex;
width: 500px;
height: 500px;
background-color: pink;
}
.child{
flex: 0 0 auto;
margin: auto;
width: 100px;
height: 100px;
background-color: red;

11. Как понимать перекомпоновку и перерисовку? ?

回流:Когда наша модификация DOM вызывает изменение геометрического размера DOM (например, изменение ширины, высоты элемента или скрытие элемента и т. д.), браузеру необходимо пересчитать геометрические свойства элемента (т. также будут затронуты геометрические свойства и положения других элементов. ), а затем нанесите на график расчетные результаты. Этот процесс называется перекомпоновкой (также называемой перестановкой).

重绘:Когда наша модификация DOM приводит к изменению стиля без изменения его геометрических свойств (например, изменение цвета или цвета фона), браузеру не нужно пересчитывать геометрические свойства элемента и напрямую рисовать новый стиль для элемента (пропускает этап оплавления, показанный выше). Этот процесс называется перекрашиванием. Отсюда видно, что перерисовка не обязательно приводит к перерисовке, а перерисовка точно приведет к перерисовке.

Общие элементы, вызывающие перекомпоновку:
  • Общие геометрические свойства: ширина, высота, отступ, поле, левое, верхнее, граница и т. д.
  • Самая упускаемая из виду операция: получить некоторые свойства, которые нужно вычислять на лету, когда вы используете такие свойства, как это: offsetTop, offsetLeft, offsetWidth, offsetHeight, scrollTop, scrollLeft, scrollWidth, scrollHeight, clientTop, clientLeft, clientWidth, clientHeight, браузер также будет перекомпонован, чтобы получить эти значения.
  • Перекомпоновка также запускается, когда мы вызываем метод getComputedStyle или currentStyle в IE. Принцип тот же, как для «непосредственности», так и для «точности».
Способы избежать:
  1. Избегайте изменения стилей один за другим, используйте имена классов для комбинирования стилей.
  2. Чтобы перевести DOM в автономный режим, используйте DocumentFragment.
  3. Повышение до составного слоя, например с использованиемwill-change
#divId {
  will-change: transform;
}

优点

  • Растровое изображение составного слоя будет составлено графическим процессором, который быстрее, чем обработка процессором.
  • Когда вам нужно перекрасить, вам нужно перекрасить только себя, это не повлияет на другие слои
  • Для эффектов преобразования и непрозрачности компоновка и рисование не запускаются.

Уведомление:

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

12. Написать обещание от руки?

Ответ слишком длинный, вы можете обратиться к этим вопросам:GitHub.com/счастливая победа TY/…

13. Расскажите о проблемах веб-безопасности и решениях

Ответ слишком длинный, вы можете обратиться к этим вопросам:GitHub.com/счастливая победа TY/…

14. В чем разница между HTTPS и HTTP?

Ответ слишком длинный, вы можете обратиться к этим вопросам:GitHub.com/счастливая победа TY/…

15. Что вы знаете об оптимизации производительности Webpack?

Ответ слишком длинный, вы можете обратиться к этим вопросам:GitHub.com/счастливая победа TY/…

Более

Резюме этой проблемы временно находится здесь.Для получения дополнительных тем вы можете обратить внимание на:GitHub.com/счастливая победа TY/…

Блог Подписаться:GitHub.com/счастливая победа TY/…

наконец

  • Добро пожаловать, чтобы отсканировать код плюс я, втянуть вас в технологическую группу, долгосрочный обмен знаниями ...
  • Добро пожаловать, чтобы обратить внимание на «Front-end Q», серьезно изучить интерфейс и быть профессиональным техническим специалистом...

GitHub