Резюме предварительных интервью Shanghai Lilith, Mihayou, Bilibili, Xiaohongshu, Dewu и других интернет-компаний

интервью
Резюме предварительных интервью Shanghai Lilith, Mihayou, Bilibili, Xiaohongshu, Dewu и других интернет-компаний

Резюме интервью

1. Добавлено 9 декабря 2020 г.:

Мы подготовили интеллект-карты высокой четкости и более удобные PDF-документы для всех. Все агрегированные интеллект-карты и 17 классифицированных интеллект-карт, охватывающих все аспекты разработки интерфейса, основы JS, проектирования, оптимизации производительности, безопасности, фреймворка и т. д. Если вы готовитесь к собеседованию или любите расширять знания о фронтенде, рекомендуется собирать и изучать.17 ментальных карт, которые нужно освоить фронтенд-разработчику в 2021 году. Справочная схема материалов обзора фронтенд-интервью

заполнить яму

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

2. Добавлено 23 ноября 2020 г.:2020 Обзор безопасности Front-End - заполнение ямы

предисловие

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

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

опрошенная компания

Lilith, Mihayou, Bilibili, Xiaohongshu, Weimeng, Dewu и т. д. В этой статье в основном представлены интернет-компании второго уровня, с которыми я беседовал, и, конечно же, я также брал интервью у таких компаний, как Ali, Meituan и Pinduoduo. линейный лагерь, здесь нет записи. Подробности смотрите в следующей статье!

Понимание вопросов и ответов

1. Идея реализации ленивой загрузки картинок

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

  1. offsetTop < clientHeight + scrollTop
  2. element.getBoundingClientRect().top < clientHeight
  3. IntersectionObserver
2. Как обращаться с междоменными

Решений по кроссдоменной обработке слишком много.Наша компания в основном пересылает через nginx.Адрес фронтенда совпадает с адресом страницы,поэтому междоменной нет,и nginx пересылает запрос на правильный сервис. Адрес страницы: web.taobao.com, адрес интерфейса запроса web.taobao.com/api.taobao.com/***

3. Может ли форма быть междоменной?

Отправка формы может быть междоменной и не ограничена политикой браузера в отношении одного и того же источника. Считается, что это наследие истории. Также может быть, что результат отправки формы недоступен в js, поэтому он не большая проблема, если он не ограничен. Но есть проблема, то есть атака csrf, которая не расширяется, потому что файл cookie может быть автоматически введен для обеспечения успеха атаки, а новый атрибут файла cookie, SameSite, может использоваться для ограничения этой ситуации. .

4. Почему вы говорите, что js — это однопоточность, а не многопоточность?

Единый поток JavaScript в соответствии с его назначением. В качестве языка сценариев браузера JavaScript в основном используется для взаимодействия с пользователем и управления DOM. Это определяет, что это может быть только один поток, иначе возникнут сложные проблемы с синхронизацией. Например, если предположить, что в JavaScript есть два потока одновременно, один поток добавляет содержимое в узел DOM, а другой поток удаляет этот узел, какой поток должен выбрать браузер?

5. Почему typeof может определить тип и есть ли лучший способ

typeof обычно используется для оценки типа переменной. Мы можем использовать typeof для оценки семи типов числа, строки, объекта, логического значения, функции, неопределенного значения, символа. Это суждение может помочь нам решить некоторые проблемы. js хранит переменные в Внизу Когда машинный код переменной хранится в младших 1-3 битах информации о ее типе (000: объект, 010: число с плавающей запятой, 100: строка, 110: логическое значение, 1: целое число), но все машинные коды null являются 0 , рассматривается непосредственно как объект. Итак, есть ли лучший способ различать типы? Как правило, используется Object.prototype.toString.call(). Подробнее см. в этой статье:zhuanlan.zhihu.com/p/118793721

6. Расскажите о своем понимании GraphQL

GraphQL предоставляет полное и простое для понимания описание данных в вашем API, позволяя клиентам получать именно те данные, которые им нужны, без какой-либо избыточности, упрощая развитие API с течением времени, и может использоваться для создания мощных инструментов разработчика. .

  1. С появлением нескольких терминалов APP, апплет и ПК нуждаются в одном и том же интерфейсе, но есть небольшие различия.Необходимо предоставить несколько наборов обычных интерфейсов.Для GraphQL вам нужно только написать оператор запроса.
  2. Естественный интерфейс агрегации. Раньше странице приходилось запрашивать разные данные. Мы можем запрашивать несколько интерфейсов. Мы можем позволить серверу выполнять агрегацию. С помощью GraphQL мы можем агрегировать нужные данные самостоятельно.
  3. Версия, не будучи беспокоиться, прежде чем писать интерфейс для совместимости со старыми временными элементами обычно можно получить доступ, особенно приложение для проекта, онлайн, и мы, безусловно, не можем повлиять на интерфейсную линию, поэтому существует относительно большое время для изменения, может только обновить Версия, без заботы о версии с GraphQL после проблемы, интерфейс или интерфейсы, которые выглядят как измененный запрос
  4. Миграция очень проста, сторона сервера может быть немного модифицирована на предыдущем интерфейсе, а передний конец записывает оператор запроса

7. Что такое делегирование событий? Для чего это?

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

8. Как изменить url с помощью js, а страница не обновляется?

Цель изменения URL - позволить js получать разные параметры и отображать разные страницы, что на самом деле является принципом vue-router.

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

Другим методом является использование метода history.pushState(), который также может изменить URL-адрес без обновления страницы, но этот метод не может инициировать событие popstate, но pushState позволяет нам инициировать его вручную, так что вы знаете, если URL-адрес На самом деле, в настоящее время нам не нужно отслеживать popstate, мы можем знать, что URL-адрес изменился, чтобы получить параметры и отобразить страницу.

9. Что лучше для непрерывной анимации js?

использовать запросAnimationFrame

10. Каковы преимущества использования анимации CSS3 вместо анимации js?

Анимации CSS и JS имеют свои плюсы и минусы.

  1. Не занимает основной поток JS

  2. Может использовать аппаратное ускорение

  3. Браузеры могут оптимизировать анимацию (отсутствие анимации, когда элементы не видны, что снижает влияние на FPS)

Пользовательские события 11.js с использованием триггера
var event = new Event('build');

// Listen for the event.
elem.addEventListener('build', function (e) { ... }, false);

// Dispatch the event.
elem.dispatchEvent(event);
12. Если бы вас попросили выбрать один из vue/react/angularjs, какой бы вы выбрали? скажи свои причины

Посмотрите на команду, все могут это принять, а я относительно знаком с vue и реагировать

13. Зачем использовать разработку jsx, разве vue не использует шаблон?

jsx более гибкий, и эффективнее писать html с идеей написания js

14. Пожалуйста, объясните, как работает JSONP

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

15. Как создать рабочий поток в JavaScript?

Просто посмотрите на документацию, на самом деле я использовал его только один раз в проекте, и он не используется повсеместно.

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

варьируется от человека к человеку

17. Как вы выполняли отладку при разработке мобильных приложений?

Наиболее часто используемыми из них являются charles и chrome://inspect/#devices для отладки.Конечно, в реальной разработке по-прежнему используется инструмент разработки chrome.Когда используется реальная машина, прокси-сервер charles или chrome:// используется прокси-сервер inspect/#devices.Для ios используется отладка реальной машины сафари, конечно, также используются vconsole, weinre и т. д. для отладки

18. Как реализовать адаптацию мобильного терминала H5?

Гибкая + REM адаптация

19. Как решить проблему 1px на мобильном терминале?

Масштабирование псевдоэлементов

20. Блочная модель css

Блочная модель IE, обычная блочная модель и другие производные проблемы

21. Как реализовать функцию скиннинга

Я никогда не делал этого раньше, я проверил, и некоторые студенты дали более подробный план:nuggets.capable/post/684490…

22. Как гибрид общается?
  1. Внедрение API, принцип на самом деле заключается в том, что Native получает контекст среды JavaScript и напрямую монтирует в него объекты или методы, так что js можно вызывать напрямую.Android и IOS имеют соответствующие методы монтирования соответственно.
  2. Перехват подсказки/консоли/предупреждения в WebView, обычно используется подсказка, потому что этот метод используется нечасто во внешнем интерфейсе, и нет конфликта
  3. Перехват перехода схемы URL-адреса WebView

23. Можете ли вы кратко описать weex?

На Zhihu есть статья, в которой очень ясно сказано:zhuanlan.zhihu.com/p/71064826

24. Пожалуйста, опишите, как улучшить производительность страницы и как оптимизировать загрузку главной страницы?

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

25. Как оптимизировать производительность?

То же

26. Расскажите о решениях для оптимизации производительности, которые вы знаете?

То же

27. Можете ли вы рассказать о кэшировании страниц?

Cache Cache строгое соглашение специально не разработано запущено

28. В чем разница между анимацией js и анимацией css?

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

29. Скажите, в чем разница между синхронным и асинхронным вы понимаете?

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

30. Какие есть способы реализации асинхронного программирования? Что рекомендуется?

Функция обратного вызова, Генератор, Обещание, асинхронность/ожидание

31. Расскажите о характеристиках, преимуществах и недостатках обещаний и о том, как они реализуются внутри компании?

Promise — это асинхронное решение. Объект Promise принимает функцию обратного вызова в качестве параметра. Функция обратного вызова принимает два параметра, а именно разрешение обратного вызова в случае успеха и отклонение обратного вызова в случае неудачи. be является экземпляром объекта Promise; аргумент для отклонения обычно является экземпляром объекта Error.

  1. Преимущество — лучшее асинхронное решение
  2. Недостатком является то, что Promise нельзя отменить, после того как он будет создан, он будет выполнен немедленно и не может быть отменен на полпути.

32. Можно ли перехватывать https-запросы и как?

Вполне возможно, иначе как charles перехватывает пакеты, конечно, предпосылка в том, что на клиенте установлен соответствующий сертификат

33. Как https обеспечивает безопасность передачи данных?

Шифрование передачи, конкретный процесс сложнее, вы можете начать статью об этом

34. Объясните симметричное шифрование https и асимметричное шифрование?

Эффективность шифрования и дешифрования асимметричного шифрования очень низкая, оно работает только на этапе проверки сертификата, а симметричное шифрование — на этапе передачи данных.

35. Расскажите, с какими проблемами безопасности вы столкнулись в своем проекте и как они обычно решаются?

Подробности смотрите в этой статьеОбзор безопасности переднего плана на 2020 год — наполнение ямы

Проблемы безопасности, такие как xss, csrf, рептилии и шерсть

Шифрование передачи, подпись интерфейса, переменные среды, токен, проверка ввода и т. д.

36. Расскажите о своем понимании XSS и CSRF, в чем между ними разница?

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

Внешний интерфейс xss в основном предназначен для управления вводом, а файл cookie настроен только на http.

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

37. Считаете ли вы, что параметры внешнего процесса передачи должны быть зашифрованы? Зачем? Как зашифровать более безопасно?

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

38. Что такое атака «человек посередине»?

Атака «человек посередине» означает, что злоумышленник создает независимые соединения с обоими концами связи и обменивается полученными данными, так что два конца связи думают, что они общаются напрямую друг с другом через частное соединение. но на самом деле весь сеанс полностью контролируется злоумышленником.

39. Что делать, если скорость упаковки webpack слишком низкая?

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

40. В чем разница между загрузчиком и плагином?

загрузчик, это конвертер, который компилирует файл A в файл B, например: преобразование A.less в A.css, простой процесс преобразования файлов.

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

41. В проекте написан какой-нибудь плагин?

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

42. Использовали ли вы другие инструменты для упаковки, кроме webpack?

свертывание и т. д.

43. Знаете ли вы npm ci? В чем разница между npm install и npm install?

npm install читает package.json, чтобы создать список зависимостей, и использует package-lock.json, чтобы указать, какие версии этих зависимостей установить. Если зависимости нет в package-lock.json, она будет добавлена ​​при установке npm.

npm ci (названный в честь непрерывной интеграции) устанавливает зависимости непосредственно из package-lock.json и использует package.json только для проверки отсутствия несоответствующих версий. Ошибка будет выдана, если какие-либо зависимости отсутствуют или версия несовместима.

С точки зрения скорости, ci явно быстрее, чем install.Лучше использовать ci, чем install при публикации и упаковке в Интернете.

44. Можете ли вы кратко описать принцип отзывчивости vue?

Есть много вещей, которые можно сказать об этой теме. Каждый пункт может быть расширен. В основном это зависит от того, насколько вы знакомы с исходным кодом. Вы можете сказать Object.defineProperty, вы можете сказать Watcher. реальный дом, чтобы объяснить этот процесс, хорошо иметь возможность объяснить это ясно

45. Расскажите мне о своем понимании vue3.0?

Прокси, CompositionAPI, TypeScript и т. д.

46. ​​Почему vue3.0 представляет CompositionAPI?
  1. Лучшая организация кода, опции API заставляют код прыгать
  2. Логическое повторное использование более удобно.Хотя миксины тоже могут хорошо переиспользовать код, когда миксинов больше, вы не будете знать, откуда берутся переменные, и это также вызовет конфликты имен.
  3. Это неуловимо
47. Конфликтует ли двусторонняя привязка с vuex?

Есть конфликт, собственно есть объяснение на официальном сайтеv u ex.v UE JS.org/this/expensive/fo...v-model изменит значение состояния, но модификация данных vuex должна пройти через мутацию, которая будет конфликтовать Простой способ - не использовать v-модель, просто сделать привязку данных самостоятельно.

48. Как решить проблему потери данных состояния vuex после обновления страницы?

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

49. Зачем вам vuex и можно ли использовать localStorage для локального хранилища?

Vuex — это шаблон управления состоянием, специально разработанный для приложений Vue.js. Хранилище состояния Vuex является реактивным. Когда компонент Vue считывает состояние из хранилища, если состояние в хранилище изменяется, соответствующий компонент будет эффективно обновлен соответствующим образом. Когда несколько компонентов имеют одинаковое состояние, vuex может помочь нам справиться с этим очень хорошо. Вы можете использовать инструменты разработчика vue для отладки состояния vuex. Эти преимущества плохо эмулируются localStorage.

50. Нативные addEventListeners, написанные в компоненте vue, прослушивают события, нужно ли их вручную уничтожать? Зачем?

Уничтожать вручную перед уничтожением, в противном случае, если вы используете addEventListeners в смонтированном, вы можете повторить регистрацию несколько раз и вызвать утечку памяти.

51. Можете ли вы кратко описать, как организован код вашего проекта?

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

52. Что вы думаете о сверхурочной работе?

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

53. Какие трудности в проекте и как их решить?

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

54. Как управлять собственными проектами?

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

55. Как вы обычно пишете техническую документацию проекта и как вы проводите обзор проекта?

Обычно технические документы пишутся на основе знакомства с документами требований, бизнес-процессом, выбором технологии, определением интерфейса (некоторые фиксированные интерфейсы, некоторые фиксированные серверные части, у нас нет слишком строгой атрибуции), а затем интерфейс с обратной стороной. -end, Разработать после установки интерактивного режима Обзор проекта в основном основан на проблемах, возникших в проекте, ситуации с данными и т. Д., И я много сказал.

56. Какова интерфейсная инфраструктура компании? Вы сами участвовали в его разработке?

Объясните на примере своей ситуации, написали ли вы библиотеку компонентов, участвовали ли вы в разработке системы, и вашу роль

57. Командная работа, предыдущий процесс разработки?

Открытые вопросы, описывающие реальную ситуацию

вопросы по программированию

1. Познакомить с принципом, отличием и применением антитряски и троттлинга и реализовать их с помощью JavaScript.

Anti-shake Непрерывный запуск в течение определенного периода времени не будет вызываться повторно. Когда он превышает определенный период времени, он будет выполняться снова. Он в основном используется в таких местах, как поля ввода. Когда вам нужно что-то запросить, непрерывный ввод не будет запрашивать интерфейс.

function debounce(fn, delay) {
    let timer = null
    return function (...args) {
        clearTimeout(timer)
        timer = setTimeout(() => {
            fn.apply(this, args)
        }, delay)
    }
}

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

function throttle(fn, delay) {
    let start = +Date.now()
    let timer = null
    return function(...args) {
        const now = +Date.now()
        if (now - start >= delay) {
            clearTimeout(timer)
            timer = null
            fn.apply(this, args)
            start = now
        } else if (!timer){
            timer = setTimeout(() => {
                fn.apply(this, args)
            }, delay)
        }
    }
}
2. Реализовать простой EventEmiter, включая привязку событий, запуск и удаление событий.
class EventEmiter {
    constructor() {
        this.events = {}
    }
    emit(event, ...args) {
        this.events[event].forEach(fn => {
            fn.apply(this, args)
        })
    }
    on(event, fn) {
        if (this.events[event]) {
            this.events[event].push(fn)
        } else {
            this.events[event] = [fn]
        }
    }
    remove(event) {
        delete this.events[event]
    }
}

const eventHub = new EventEmiter()

eventHub.on('test', data => {
    console.log(data)
})

eventHub.emit('test', 1)
console.log(2)
3. Объединить два отсортированных массива

Лико Вопрос 88:Lee TCO's-talent.com/problems/why…

function merge(left, right) {
    let i = 0
    let j = 0
    const temp = []
    while(i < left.length && j < right.length) {
        if (left[i] < right[j]) {
            temp.push(left[i])
            i++
        } else {
            temp.push(right[j])
            j++
        }
    }
    while(i < left.length) {
        temp.push(left[i])
        i++
    }
    while(j < right.length) {
        temp.push(right[j])
        j++
    }
    return temp
}
4. Подъем по лестнице

Лико Вопрос 70:Lee TCO's-talent.com/problems/ кроме…

var climbStairs = function(n) {
    if (n <= 2) return n
    let n1 = 1
    let n2 = 2
    let nn = 0
    for (let i = 3; i <= n; i++) {
        nn = n1 + n2
        n1 = n2
        n2 = nn
    }
    return nn
};
5. Обезьяны едят бананы

Ликоу Вопрос 875:Ли ТСО's-talent.com/problems/KO…

function minEatingSpeed(piles, H) {
    let left = 1;
    let right = Math.max(...piles);
    const canEat = (piles, speed, H) => {
        let sumTime = 0;
        for (let pile of piles) {
            sumTime += Math.ceil(pile / speed);
        }
        return sumTime <= H;
    };
    while (left < right) {
        let mid = Math.floor((right + left) / 2);
        if (canEat(piles, mid, H)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return right;
};
6.лру алгоритм

Ликоу № 146 Вопрос:Lee TCO's-talent.com/problems/ Например…

class LRU {
    constructor(max) {
        this.max = max
        this.cache = new Map()
    }
    get(key) {
        const { cache } = this
        const value = cache.get(key)
        if (!value) return -1
        cache.delete(key)
        cache.set(key, value)
        return value
    }
    set(key, value) {
        const { cache, max } = this
        if (cache.has(key)) {
            cache.delete(key)
        }
        if (cache.size === max) {
            cache.delete(cache.keys().next().value)
        }
        cache.set(key, value)
    }
}
7. Обход бинарного дерева

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

// 前序遍历
function preorderTraversal(root) {
    const result = []
    function preOrderTraverseNode(node) {
        if (node) {
            result.push(node.val)
            preOrderTraverseNode(node.left)
            preOrderTraverseNode(node.right)
        }
    }

    preOrderTraverseNode(root)

    return result
};
// 层次遍历
function levelOrder(root) {
    const res = []
    function dfs(node, step) {
        if (node) {
            if (res[step]) {
                res[step].push(node.val)
            } else {
                res[step] = [node.val]
            }
            dfs(node.left, step + 1)
            dfs(node.right, step + 1)
        }
    }
    dfs(root, 0)
    return res
}

8. Палиндромная подстрока

Ликоу № 647:Lee TCO's-talent.com/problems/afraid…

function countSubstrings(s) {
    const n = s.length;
    let ans = 0;
    for (let i = 0; i < 2 * n - 1; ++i) {
        let l = i / 2, r = i / 2 + i % 2;
        while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) {
            --l;
            ++r;
            ++ans;
        }
    }
    return ans;
};
9. Лучшее время для покупки и продажи акций

Ликоу Вопрос 121:Lee TCO's-talent.com/problems/не голоден…

function maxProfit(prices) {
    const len = prices.length
    if (len < 2) return 0
    let min = prices[0]

    let dis = 0
    for (let i = 1; i < len; i++) {
        if (prices[i] < min) {
            min = prices[i]
        }
        const disc = prices[i] - min
        if (disc > dis) {
            dis = disc
        }
    }
    return dis
};
10. обещаниеВсе и всеВыбрано
Promise.all = function(promises) {
    const values = []
    let count = 0
    return new Promise((resolve, reject) => {
        promises.forEach((promise, index) => {
            Promise.resolve(promise).then(res => {
                count++
                values[index] = res
                if (count === promises.length) {
                    resolve(values)
                }
            }, err => {
                reject(err)
            })
        })
    })
}

Promise.allSeleted = function(promises) {
    let count = 0
    let result = []
    return new Promise((resolve, reject) => {
        promises.forEach((promise, index) => {
            Promise.resolve(promise).then(res => {
                result[index] = {
                    value: res,
                    reason: null,
                }
            }, err => {
                result[index] = {
                    value: null,
                    reason: err,
                }
            }).finally(() => {
                count++
                if (count === promises.length) {
                    resolve(result)
                }
            })
        })
    })
}
11. Реализуйте maxRequest, определяйте результат после успеха, повторяйте попытку после неудачи и отклоняйте только после определенного количества попыток.
function maxRequest(fn, maxNum) {
    return new Promise((resolve, reject) => {
        function help(index) {
            Promise.resolve(fn()).then(value => {
                resolve(value)
            }).catch(error => {
                if (index - 1 > 0) {
                    help(index - 1)
                } else {
                    reject(error)
                }
            })
        }
        help(maxNum)
    })
}