Полтора года опыта, резюме интервью Baidu, Youzan, Ali.

внешний интерфейс JavaScript React.js Canvas

предисловие

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

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

исходный адрес

Baidu WEB front-end инженер, пять сессий подряд, весь процесс занимает около 3 часов

одна сторона

Сначала выполните письменный тест

  1. Реализуйте функцию, которая определяет, являются ли входные данные палиндромом.
function run(input) {
  if (typeof input !== 'string') return false;
  return input.split('').reverse().join('') === input;
}
  1. Два или более способов достижения вертикального и горизонтального центрирования известной или неизвестной ширины.

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

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

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

// 4
.wrapper {
  display: table;
  .box {
    display: table-cell;
    vertical-align: middle;
  }
}

  1. Чтобы добиться эффекта, щелкните значок в контейнере, граница значка станет сплошной красной рамкой толщиной 1 пиксель, и щелкните пустое место для сброса.
const box = document.getElementById('box');
function isIcon(target) {
  return target.className.includes('icon');
}

box.onclick = function(e) {
  e.stopPropagation();
  const target = e.target;
  if (isIcon(target)) {
    target.style.border = '1px solid red';
  }
}
const doc = document;
doc.onclick = function(e) {
  const children = box.children;
  for(let i; i < children.length; i++) {
    if (isIcon(children[i])) {
      children[i].style.border = 'none';
    }
  }
}
  1. Пожалуйста, просто реализуйте двустороннюю привязку данных mvvm.
<input id="input"/>
const data = {};
const input = document.getElementById('input');
Object.defineProperty(data, 'text', {
  set(value) {
    input.value = value;
    this.value = value;
  }
});
input.onchange = function(e) {
  data.text = e.target.value;
}
  1. Реализовать Storage, сделать объект одноэлементным и инкапсулировать localStorage для установки значений setItem(key,value) и getItem(key)
var instance = null;
class Storage {
  static getInstance() {
    if (!instance) {
      instance = new Storage();
    }
    return instance;
  }
  setItem = (key, value) => localStorage.setItem(key, value),
  getItem = key => localStorage.getItem(key)
}

Q1 Ваш технологический стек в основном состоит из реакции, так каковы подводные камни при использовании реакции?

1. Когда JSX оценивает выражение, его необходимо преобразовать в логический тип, например:

render() {
  const b = 0;
  return <div>
    {
      !!b && <div>这是一段文本</div>
    }
  </div>
}

Если вы не используете !!b для приведения типа данных, на странице будет выведено 0.

2. Старайтесь не использовать setState в componentWillReviceProps.Если вы должны использовать его, вам нужно судить о конечном условии, иначе будет бесконечный повторный рендеринг и страница вылетит. (Дело не в том, что componentWillReviceProps будет перерисовываться бесконечно, а в componentDidUpdate)

3. При добавлении ref к компоненту старайтесь не использовать анонимные функции, потому что при обновлении компонента анонимная функция будет рассматриваться как новая проп.Когда атрибут ref получит новую функцию, реакция сначала очистит ref , то есть реквизиты ref будут выполняться один раз с null в качестве параметра обратного вызова, а затем ref будет выполняться один раз с экземпляром компонента, поэтому при использовании анонимной функции в качестве ref иногда свойство после присвоения значения ref получит нуль.Подробнее см.

4. При обходе дочерних узлов не используйте индекс в качестве ключа компонента для передачи.

Q2 Теперь у меня есть кнопка, и я хочу привязать к ней событие click с помощью реакции, что мне делать?

class Demo {
  render() {
    return <button onClick={(e) => {
      alert('我点击了按钮')
    }}>
      按钮
    </button>
  }
}

Q3 Продолжая вопрос, как вы думаете, будут ли какие-либо проблемы с настройкой события клика таким образом?

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

Исправлять

class Demo {

  onClick = (e) => {
    alert('我点击了按钮')
  }

  render() {
    return <button onClick={this.onClick}>
      按钮
    </button>
  }
}

Конечно, вы не объявляете стрелочные функции внутри, и тогда вам может понадобиться использовать bind для привязки контекста при настройке onClick.Этот эффект похож на предыдущее использование анонимных функций, потому что bind вернет новую функцию, которая также будет рассматриваться реакцией как новая опора.

Q4 Можете ли вы рассказать о цикле событий?

Прежде всего, js является однопоточным. Основная задача — обрабатывать взаимодействие с пользователем, а взаимодействие с пользователем — это не что иное, как реагирование на добавления, удаления и изменения DOM. Используя форму очередей событий, цикл обработки событий обрабатывает только одно событие. ответ, что делает выполнение скрипта относительно непрерывным Итак, с очередью событий, которая используется для хранения событий, которые должны быть выполнены, откуда берутся события очереди событий? Это то, что делает другой поток, называемый потоком триггера события.Его функция в основном состоит в том, чтобы поместить функцию обратного вызова в очередь событий, когда поток триггера синхронизации и поток асинхронного HTTP-запроса удовлетворяют определенным условиям, и выполнить его, когда движок js idle., разумеется, есть приоритеты в процессе выполнения js движка.Сначала js движок выполнит основную задачу js потока в цикле событий, а потом проверит есть ли микрозадача (promise), и если да, то она будет выполнена первой.Микрозадача, если нет, то перейти к макрозадаче найти макрозадачу (setTimeout, setInterval) для выполнения.

Q5 Расскажите о потоке событий

Существует два типа потоков событий: потоки захвата событий и потоки всплывающих событий.

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

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

Поток событий DOM разделен на три этапа: один — узел захвата, другой — этап целевого узла, а третий — этап всплытия.

Q6 Теперь у меня есть индикатор выполнения, и в середине индикатора выполнения есть строка текста. Когда мой индикатор выполнения закрывает текст, текст должен быть обратным индикатору выполнения. Как этого добиться?

. . . В то время я дал решение js.При изменении ширины индикатора выполнения расчет покрывает 50% каждого текста.Если превышает, устанавливайте противоположный цвет текста.

Конечно, в CSS тоже есть соответствующее решение, то есть Mix-Blend-Mode, я его не понял.

Для html тоже есть соответствующая схема, то есть две DOM-структуры с одинаковым положением, но противоположными цветами настроены на перекрытие, верхний слой закрывает нижний слой, а индикатор выполнения верхнего уровня принимает переполнение как скрытое, а его ширина это прогресс.

две стороны

Q1 Почему вы покинули свою последнюю компанию?

-

Q2 Какая, по вашему мнению, идеальная передняя позиция?

-

Q3 Тогда вы понимаете проблему, вы пытались решить ее снова?

-

Три стороны

Q1 Расскажите мне об общем процессе развития вашей последней компании

-

Как реализован виртуальный дом реакции Q2?

Прежде всего, давайте поговорим о том, почему вы должны использовать Virturl DOM. Поскольку затраты производительности на работу с реальным DOM слишком высоки, поэтому React использует js для реализации набора структур DOM. Перед каждой операцией и реальным DOM хорошо используется реализованный алгоритм diff.Сравните виртуальный DOM, рекурсивно найдите изменившийся узел DOM, а затем обновите его. Чтобы реализовать виртуальный DOM, нам нужно абстрагировать каждый тип узла в объект.Каждый тип узла имеет свои собственные свойства, то есть свойство.Каждый раз, когда выполняется сравнение, реакция сначала сравнивает тип узла.Если тип узла отличается Если узел тот же, то реакция удалит узел напрямую, а затем напрямую создаст новый узел и вставит его в него.Если тип узла тот же, он сравнит, была ли обновлена ​​опора.Если prop отличается, тогда реакция определит, что узел был обновлен.Визуализируйте узел, затем сравните его дочерние элементы, слой за слоем, пока не останется дочерних элементов.

Q3 Как обрабатываются одноуровневые узлы в процессе рендеринга React? То есть когда значения ключей разные.

Обычно, когда мы выводим узлы, мы сопоставляем массив, а затем возвращаем ReactNode. Чтобы облегчить внутреннюю оптимизацию реакции, мы должны добавить ключ к каждому reactNode. Эта ключевая опора не используется разработчиками в расчетном значении, но для реагировать. Он используется, и общая функция состоит в том, чтобы добавить идентификатор к каждому reactNode, что удобно для реакции, чтобы идентифицировать. Во время процесса повторного рендеринга, если ключ тот же, если свойства компонента меняются, реакция будет только обновить соответствующие свойства компонента, если нет изменений, то Не обновлять, если ключ другой, react сначала уничтожает компонент, а потом пересоздает компонент.

Q4 У меня сейчас есть массив [1, 2, 3, 4], пожалуйста, реализуйте алгоритм, чтобы получить полноразрученный массив этого массива, например [2, 1, 3, 4], [2, 1, 4, 3]. . . . Сколько стоит ваш алгоритм?

这个我没写出来,大概给了个思路,将每一个数组拆除俩个小数组进行求它的全排列,然后得到的结果互相之间又进行全排列,然后把最后的结果连接起来。 . .

Заинтересованные студенты видят васмассив полный массив

Q5 Теперь у меня есть рюкзак вместимостью m, а затем есть n грузов весом w1, w2, w3...wn, и стоимость каждого груза равна v1, v2, v3...vn, w и v не имеет отношения Any, запросите максимальное значение, которое может вместить рюкзак.

Я этого не записывал, но также дал идею: сначала методом Q4 получить полную комбинацию массива веса груза (включая полную комбинацию, разбитую на маленькие массивы), затем вычислить значение каждой комбинации , отсортируйте его, а затем пройдитесь по массиву, чтобы найти комбинацию более высокого значения и достаточного количества, чтобы поместиться в рюкзак m.

этот вопрос动态规划面试题, Заинтересованные студенты, пожалуйста, Baidu или Google.

четыре стороны

Q1 Пожалуйста, расскажите нам о процессе выпуска R&D вашей последней компании.

-

Q2 Расскажите мне о некоторых плагинах веб-пакета и о том, как использовать веб-пакет для оптимизации проекта.

Недавно я занимался оптимизацией сборки веб-пакета и оптимизацией производительности. В то время это занимало около 15-20 минут. Пожалуйста, посмотрите плагин.Сводка плагинов webpack.

Оптимизация сборки

1, уменьшение объема компилятора ContextreplacePugin, IgnorePlugin, Babel-Plugin-Import, Babel-Plugin-Transfrance-Runtime.

2. Параллельная компиляция happypack, thread-loader, uglifyjsWebpackPlugin open parallel

3. Cache cache-loader, hard-source-webpack-plugin, uglifyjsWebpackPlugin включает кеширование, babel-loader включает кеширование

4. Прекомпилировать dllWebpackPlugin && DllReferencePlugin, auto-dll-webapck-plugin

оптимизация производительности

1. Уменьшите объем компиляции Tree-shaking, Scope Hosites.

2, хэш-кэш WebPack-MD5-PLUGIN

3. Распаковка splitChunksPlugin, import(), require.ensure

Q3 В чем разница между новым экземпляром класса es6 и новым экземпляром es5

Я думаю, что это то же самое (потому что я редко смотрел на результаты после компиляции babel), интервьюер сказал, что это другое. . . Позже я посмотрел на результаты компиляции babel и обнаружил, что процесс объявления метода класса был другим, а конечный результат new был таким же. . . Я пока не знаю точного ответа. . .

Q4 Увидев, что холст написан в вашем резюме, скажите, пожалуйста, почему изображение холста имеет междоменные проблемы.

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

Q5 Теперь у меня есть холст, на котором случайным образом размещено несколько черных блоков. Пожалуйста, реализуйте метод для подсчета количества черных блоков на холсте.

Используйте Getimagedata, чтобы получить массив пикселя, а затем перейти к массиву. В процессе прохождения узла проверьте, будет ли цвет пикселя верхнего, нижнего, влево и справа от узла. Если оно совсем Затем установите логотип и, наконец, Groupby все пиксели. (Это мой план в то время)

другие лучшие ответысм. адрес

Q6 Пожалуйста, выполните обещание вручную

Об этом не будет написано, подробности см.Принцип выполнения обещания

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

пять сторон

Q1 Каковы характеристики вашей технологии?

-

Q2 Расскажите мне о проекте, которым, по вашему мнению, вы больше всего гордитесь? Есть ли недостатки в вашем проекте?

-

Q3 Теперь есть такая команда, если бы вас попросили заняться технической архитектурой, что бы вы сделали?

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

Q4 Расскажите об основном бизнес-процессе вашей прошлой компании, участвовали ли вы в нем?

-

Ханчжоу Юдзан

One side WEB front-end инженер Телефонное интервью 43 минуты

Q1 Самостоятельное введение

-

Q2 Расскажите обо всем процессе от ввода URL до просмотра того, что происходит на странице. Чем подробнее, тем лучше.

  1. Сначала основной процесс браузера вступает во владение и открывает поток загрузки.
  2. Затем сделать HTTP-запрос (DNS-запрос, IP-адресация и т. д.), и будет три руки, прикрывающие середину, ожидающие ответа и начинающие загружать ответное сообщение.
  3. Передайте загруженный контент в управление процессами рендерера.
  4. Процесс Renderer начинает парсить дерево правил css и дерево dom.Эти два процесса идут параллельно, поэтому я обычно ставлю тег ссылки вверху страницы.
  5. В процессе парсинга и отрисовки, когда браузер встречает тег link, script, img и другие теги, браузер загружает контент, при его обнаружении используется кеш, а кешированные ресурсы не загружаются повторно.
  6. После дерева правила CSS и генерирование дерева DOM, синтезированное начальное дерево рендер, на этот раз будет макет браузера, начальная позиция каждого узла рассчитана, затем нанесена.
  7. После окончания розыгрыша закрываем TCP-соединение, и процесс проходит четыре взмаха рук.

Q3 Вы только что сказали три рукопожатия и четыре взмаха руками, как бы вы это описали?

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

Q4 Позиция CSS и JS, упомянутая в Q2, повлияет на эффективность страницы, почему?

CSS не повлияет на генерацию DOM-дерева в процессе загрузки, но повлияет на генерацию Render-дерева, что в свою очередь влияет на верстку, поэтому в целом тег link style нужно разместить в шапке максимально, т. к. при парсинге DOM-дерева Time идет сверху вниз, а CSS-стили загружаются асинхронно, в этом случае парсинг узла body под DOM-деревом и загрузка CSS-стилей могут быть максимально распараллелены, что ускоряет Генерация дерева рендеринга.

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

Q5 Теперь есть функция A и функция B, пожалуйста, реализуйте B, чтобы наследовать A

// 方式1
function B(){}
function A(){}
B.prototype = new A();

// 方式2
function A(){}
function B(){
  A.call(this);
}

// 方式3
function B(){}
function A(){}
B.prototype = new A();

function B(){
  A.call(this);
}

Q6 Только что вы упомянули несколько методов наследования в Q5 и рассказали об их преимуществах и недостатках соответственно.

Метод 1: простой и понятный, но не может обеспечить множественное наследование, родительский класс добавляет методы прототипа/свойства прототипа, и подкласс может получить к нему доступ

Режим 2: может быть достигнуто множественное наследование, но могут наследоваться только свойства и методы экземпляра родительского класса, а не свойства/методы прототипа.

Режим 3: свойства/методы экземпляра могут быть унаследованы, и свойства/методы прототипа также могут быть унаследованы, но в качестве примеров приведены два конструктора A.

Q7 Расскажите о нескольких методах вертикального и горизонтального центрирования в CSS.

Обратитесь к предыдущему вопросу одностороннего письменного теста Baidu Q2.

Q8 В гибком макете, упомянутом в Q7, вертикальное и горизонтальное центрирование должно знать ширину?

Да, вы должны знать высоту

Q9 Опишите это

this, контекст, в котором выполняется функция, вы можете изменить точку this с помощью применения, вызова и привязки. Для анонимных функций или функций, вызываемых напрямую, this указывает на глобальный контекст (window для браузеров, global для nodejs), а для остальных вызовов функций, кто бы их ни вызывал, this указывает на. Конечно, есть и стрелочная функция es6.Указатель стрелочной функции зависит от позиции, где объявлена ​​стрелочная функция.Где бы она ни была объявлена, это указывает на то, куда.

Q10 Расскажите мне о механизме кэширования браузера

Существует два механизма кэширования браузера: один — строгое кэширование, а другой — согласованное кэширование.

Для сильного кэширования браузер будет непосредственно загружать ресурс, когда он запрашивается в первый раз, то кэшируйте его локально и использовать кэш непосредственно, когда он запрашивается во второй раз.

Для согласованного кеша кеш запрашивается в первый раз, а идентификатор кеша и время сохраняются.Повторные запросы отправляют идентификатор кеша и время последнего кеша на сервер, и сервер проверяет его.Если это не удается, кеш использовал.

Сильная схема кэширования

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

Cache-control: max-age, который указывает, через сколько истечет срок действия ресурса, что решает проблему, связанную с тем, что время клиента и сервера должно быть синхронизировано.

Согласовать схему кэширования

If-None-Match/ETag: идентификатор кеша, используйте его для идентификации кеша при сравнении кешей, сервер вернет идентификатор клиенту при первом запросе, а клиент принесет его со вторым запросом.Этот флаг сравнивается с сервером и возвращает, указывает ли флаг If-None-Match на совпадение.

Last-modified/If-Modified-Since: сервер возвращает Last-modified, чтобы указать время последней модификации запрошенного ресурса при первом запросе.Когда сделан второй запрос, клиент приносит заголовок запроса If-Modified- Т.к. указывает время последней модификации ресурса, и сервер получает эти два поля для сравнения.

Q11 Как ETag генерируется этой строкой?

Я не ответил, я догадался, что это алгоритм шифрования, основанный на содержимом файла или времени последней модификации. На самом деле официальный не указывает явно метод генерации значения ETag.

Как правило, используйте хэш содержимого, хэш метки времени последней модификации или просто номер версии.

Q12 Теперь я хочу, чтобы вы завершили компонент Dialog, расскажите мне о ваших дизайнерских идеях? Какую функцию он должен иметь?

  1. Компонент должен предоставить хук для указания позиции рендеринга, которая по умолчанию рендерится под телом.
  2. Затем измените компонент, чтобы указать внешний стиль, например ширину и т. д.
  3. Внешний слой компонента также нуждается в слое маски, чтобы покрыть нижележащее содержимое.Щелкните маску, чтобы выполнить входящую функцию onCancel, чтобы закрыть диалоговое окно.
  4. Кроме того, компонент является управляемым, и внешний слой должен пройти в качестве видимого, чтобы указать, является ли он видимым.
  5. Затем диалоговому окну может потребоваться настроить верхний и нижний колонтитулы, верхний и нижний колонтитулы по умолчанию, а также кнопку подтверждения и кнопку отмены внизу, кнопка подтверждения выполнит событие onOk, переданное извне, а затем кнопка отмены будет выполнить переданное извне событие onCancel.
  6. Если для компонента значение visible равно true, установите для переполнения тела значение hidden, скройте полосу прокрутки тела и вместо этого отобразите полосу прокрутки.
  7. Высота компонента может быть больше высоты страницы, а внутри компонента требуются полосы прокрутки.
  8. Все содержимое в компоненте перерисовывается только тогда, когда видимость компонента изменяется и становится истинной.

Q13 Какой проект вы считаете самым достойным?

Ant Financial-Experience Technology Department Старший инженер по исследованиям и разработкам в области визуализации данных

Одна сторона Телефонная сторона 1 час 24 минуты

Q1 Опишите свой последний проект визуализации

Q2 Java-вызов js только что сказал создать отчет о данных в автономном режиме? Как java вызывает обещание js асинхронно возвращать результат?

Используя js движок java Nashorn, Nashorn не поддерживает очереди событий, необходимо вводить полифилл, затем java вызывает метод js для получения объекта обещания java, а затем вызывает метод then объекта, а функция обратного вызова — некая тип метода java., то пока переменная, которая указывает, был ли выполнен обратный вызов, если нет, пусть основной поток java спит, если он был выполнен, то выпрыгивает из цикла, указывая, была ли переменная обратного вызова выполнена выполнено устанавливается и изменяется в функции обратного вызова входящего промиса. код деталисм. адрес

Q3 Расскажите мне о преимуществах и недостатках svg и canvas?

То, что они имеют общего: оба являются эффективными графическими инструментами, оба являются высокопроизводительными для небольших данных, оба используют JavaScript и HTML; все они соответствуют стандартам World Web Consortium (W3C).

Преимущества svg:

Векторная графика, независимая от пикселей, не будет искажаться после бесконечного увеличения.

В форме DOM привязки событий распространяются браузером непосредственно на узлы.

Недостатки svg:

В виде dom, dom нужно обновлять, когда задействована анимация, а производительность низкая.

Преимущества холста:

Настройка сильнее, и вы можете рисовать то, что хотите.

Структура без DOM рисуется с помощью JavaScript, что требует высокой производительности анимации.

Недостатки холста:

Распределение событий обрабатывается холстом, а события отрисовываемого содержимого необходимо обрабатывать самостоятельно.

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

Q4 Холст, о котором вы только что сказали, будет иметь более низкую производительность при рендеринге большого холста? Почему?

Поскольку холст зависит от пикселей, он рисуется пиксель за пикселем в процессе рисования.Когда холст достаточно большой, будет достаточно пикселей, поэтому энергия будет достаточно низкой.

Q6 Предположим, у меня сейчас 5000 кругов, которые полностью нарисованы, кликните по кругу, круг будет выделен, а остальные 4999 кругов настроены полупрозрачными.Подскажите, как использовать svg и canvas соответственно?

Прежде всего, начиная с данных, каждый из наших кругов является частью данных.Эти данные имеют x, y, радиус и isHighlight круга.Если это svg, вы можете напрямую отобразить узел, а затем привязать Щелкните событие на узле и щелкните, чтобы изменить все свойства выделения данных (что должно быть выполнено синхронно), а затем позволить браузеру нарисовать его. Если это холст, нам нужно привязать событие к тегу холста самостоятельно, а затем определить, находится ли позиция щелчка внутри круга при щелчке.Если он находится внутри круга, обновите атрибут выделения всех данных, а затем выполните разовый рисунок..

Q7 Как реализовать только что упомянутое событие щелчка холста? Если это не круг, эти фигуры являются квадратами, прямоугольниками, правильными фигурами и неправильными фигурами.

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

В8 Что делать, если мою графику нужно деформировать, увеличить, сместить и повернуть? Как вы справляетесь с этим isPointInSide?

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

Q9 Для события щелчка этого холста, как вы быстро находите круг, на который вы нажали, из 5000 кругов при нажатии (не полностью пересекая 5000 узлов)?

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

Q10 Тогда вы использовали @antv/g6, в нем есть дерево, расскажите мне, как была реализована структура данных дерева, с которым вы столкнулись, когда учились в колледже?

Проучившись больше года, я, наверное, забыл структуру дерева и ответил так:

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

Q11 Помните бинарное дерево? Опишите несколько способов обхода бинарного дерева?

Обход в предварительном порядке: если двоичное дерево не пусто, посетите корневой узел, обойдите левое поддерево и обойдите правое поддерево.

Обход по порядку: если бинарное дерево не пусто, обходим левое поддерево, посещаем корневой узел, обходим правое поддерево.

Обход в обратном порядке: если бинарное дерево не пусто, пройти по левому поддереву, пройти по правому поддереву, посетить корневой узел.

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

Q12 Расскажите обо всех сортировках, которые вы помните, каков их принцип?

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

Быстрая сортировка: перейдите к числу в середине массива, затем просмотрите все числа, поместите число меньше этого числа в один массив, поместите число больше этого числа в другой массив, затем рекурсивно отсортируйте два массива и наконец соедините все результаты.

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

Q13 скажите, что, по вашему мнению, вы сделали самые сложные проекты? Трудности, возникающие в середине, и как вы решаете?

-


Интервьюер: Я почти закончил со своими вопросами, какие вопросы у вас есть?

Я: Я удивлен, что сегодня все они про визуализацию, а не про js, css и html.

Интервьюер: Тогда продолжим

Я:. . .


Q14 Тогда расскажите мне о реакции (интервьюер занимается визуальной разработкой и совсем не понимает реакцию)

Когда у нас не было jquery в прошлом, наш общий процесс заключался в том, чтобы получать данные из серверной части через ajax, а затем использовать jquery для генерации результатов dom и обновления их на странице.Однако по мере развития бизнеса наши проекты могут стать более и более сложные.Когда данные запрашиваются в первый раз или когда данные изменяются, нам нужно снова собрать структуру DOM, а затем обновить страницу, так что стоимость ручной синхронизации DOM и данных становится выше и выше, да и частая работа ДОМ тоже заставляет меня медленно деградировать производительность нашей страницы.

В это время появился mvvm.Двусторонняя привязка данных mvvm позволяет нам синхронизировать обновление dom во время изменения данных.Обновление dom также может напрямую синхронизировать изменения наших данных, что может значительно уменьшить стоимость ручного обслуживания обновления dom. , mvvm — одна из особенностей реакции, хотя реакция относится к одному потоку данных, нам нужно вручную реализовать двустороннюю привязку данных.

Недостаточно иметь mvvm, потому что если каждый раз происходит изменение данных, а потом мы обновляем структуру dom в полном объеме, то никак не решить проблему нашей частой работы структуры dom (снижение производительности страницы). чтобы решить эту проблему, реагируйте внутренне.Реализован набор виртуальной структуры DOM, то есть набор структуры DOM, реализованный js.Его функция состоит в том, чтобы сделать набор кеша в js для реального DOM.Каждый раз, когда происходит изменение данных , сначала используется внутренний алгоритм реакции, то есть известный алгоритм diff сравнивает структуру DOM, находит те узлы DOM, которые нам нужно добавить, обновить и удалить, а затем за один раз обновить реальный DOM, что значительно уменьшает количество операций DOM.

Так как же работает алгоритм diff?Во-первых, для узлов разных типов diff будет напрямую определять местоположение исходного узла, который нужно выгрузить, и использовать новый узел для загрузки выгруженного узла; для узлов одного типа узла, он будет сравнивать узел.Если все атрибуты узла одинаковы, то определяется, что узел не нуждается в обновлении.Если атрибуты узла не совпадают, будет определено, что узел должен быть обновлен обновлен, и реакция обновит и повторно отобразит узел.

В начале разработки React он в основном отвечал за отрисовку слоя пользовательского интерфейса.Хотя каждый компонент имеет свое собственное состояние, состояние представляет собой состояние компонента.Когда состояние необходимо изменить, нам нужно использовать setState для обновления наших компонентов.Однако мы хотим использовать компонент для сброса. Чтобы визуализировать его одноуровневые компоненты, нам нужно повысить состояние компонента до родительского компонента и позволить состоянию родительского компонента управлять повторным рендерингом этих компонентов. два компонента.Когда уровень наших компонентов становится все глубже и глубже, состояние должно перейти к Загрузка, несомненно, увеличит сложность нашего кода.Нам нужен центр управления состоянием, который поможет нам управлять нашим состоянием.

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

Позже в сообществе появился еще один набор решений, то есть mobx, который выступает за простой и понятный код, в нем нужно только определить наблюдаемый объект, а затем какой компонент использует этот наблюдаемый объект, и данные этого объект имеет Change, то этот компонент будет перерендерен, а также mobx хорошо поработал над перерендерингом жизненного цикла компонента shouldUpdateComponent, разработчикам не рекомендуется вносить изменения, что позволяет нам использовать mobx для разрабатывать проекты.Многие функции выполняются легко и быстро.Даже автор редукса рекомендует использовать mobx для разработки проектов. Однако, по мере того, как проект продолжает расти, mobx продолжает выявлять свои недостатки, то есть поток данных слишком случайный, и трудно отследить поток данных после возникновения ошибки, этот недостаток как раз и отражает преимущества редукса, поэтому для небольших проектов сообщество рекомендует mobx, а для крупных проектов рекомендуется redux.

В15. Если у меня есть компонент со счетчиком состояний, равным 1, я дважды выполняю this.setState({count: ++this.state.count}) в componentDidMount(), а затем выполняю setTimeout(( ) => { this. setState({count: ++this.state.count}) }, 0), каков окончательный счет? Почему?

count равен 4, так как при повторном выполнении setState результат this.state.count++ в первый раз получить невозможно.React обновит внутреннее состояние после окончания одного жизненного цикла.Если их больше одного жизненный цикл в одном цикле. Когда setState используется во второй раз, в реакции будет поле isBatchUpdate, чтобы идентифицировать это обновление как пакетное обновление, а затем отправить все результаты setState в состояние в финальном рендеринге, обновить его в один раз и установите для поля isBatchUpdate значение false.

Для двух setTimeout движок js бросит эти два setStates в очередь событий, ожидая, пока js будет простаивать для выполнения, и наша функция рендеринга рендеринга выполняется синхронно (версия react16 не включает асинхронный рендеринг по умолчанию), так что подождите для нас выполнение рендера завершено, то есть после того, как наше состояние синхронизировано, на выполнение берется setState в очереди событий, а второй setState у setTimeout такой же, поэтому итоговый результат равен 4.

Примечания: Ответ на этот счет кажется сомнительным, я написал демо, ответ не 4, адрес демоJS fiddle.net/Asian отключен 8/5 высокого уровня…

В16 Скажите, что вы считаете самым полезным из того, что вы сделали?

-

наконец

Интервьюеры в этих раундах интервью все очень дружелюбны и общительны. Я не знаю, прошли ли пять раундов интервью Baidu. Я просто помню, что интервьюер на пяти сторонах сказал: подождите, я спрошу, что другие люди Я спросил, и через некоторое время HR сказал мне вернуться первым, и сказал мне ждать новостей от HR. Если я не пройду, они не свяжутся со мной. Прошло четыре дня, я надеюсь есть новости позже. Потом я сдал и Zan, и Ant Financial, потому что интервьюер спрашивал меня, есть ли у меня вопросы после каждого собеседования? Я всегда буду спрашивать, что интервьюер сказал обо мне в этом интервью.

Последующая дверь доставки ->Помните весь процесс интерфейсного интервью