Загрузка…
Загрузка…
frontend / middle / tech_screening
Формат
online
Стадия
tech_screening
Когда
within_quarter
Длительность
90 мин
01
Код
Напишите функцию, которая проверяет, является ли строка палиндромом, с учётом того, что в строке могут быть строчные и заглавные буквы (регистр не учитывается) и нужно игнорировать все небуквенные символы (пробелы, знаки препинания). Решение должно быть максимально эффективным по памяти — O(1).
Первая задача (попроще). Решается методом двух указателей без создания промежуточных структур.
02
Теория
Что такое алгоритмическая сложность по времени и по памяти, что означает O(1) и O(n), какие алгоритмы линейные, а какие нелинейные?
Базовое фундаментальное знание, которое проверяется на секции.
03
Теория
Как определить, является ли символ буквой, не используя регулярное выражение? (приведение символа к нижнему и верхнему регистру и сравнение)
Хак: буква меняется при смене регистра, спецсимвол — нет. Обсуждалась невозможность regex/Set под все европейские алфавиты.
Заметки
Это не реальное собеседование, а записанное мок-интервью (формат Weekend offer) от компании Яндекс, снятое как обучающий/демонстрационный материал. Ведущий — Сергей Бережной (директор по взаимодействию с разработчиками); собеседующие — Лёша и Слава; в роли подопытного кандидата — YouTube-блогер Тимур (автор канала). Секция называется «проверка базовых технических навыков» (часто такие называют алгоритмическими). На секции обычно решают две задачи разных калибров: одну попроще, одну посложнее. Задачи решаются в редакторе без возможности запуска кода (хотя упомянуты эксперименты с запуском). Для тренировки упомянут сайт contest/кудранинг на yandex (включая фронтендерские задачи на CSS).
Подготовка
Освежить в памяти понимание алгоритмической сложности по времени и по памяти (O(1), O(n), линейность/квадратичность) — это главное фундаментальное знание для секции. Прорешать хотя бы десяток пробных задач под таймер (или с наблюдателем), чтобы снять физический стресс и привыкнуть к формату. Психологически подготовиться к незнакомым задачам — тупить и пользоваться подсказками нормально. Тренироваться на задачах с yandex contest. Проговаривать вслух общее направление решения (но не избыточно детально), чтобы интервьюер мог вовремя помочь и уберечь от лишнего кода. Внимательно следить, нужно ли мутировать массив (push) или нет (spread). Не рефакторить и не выносить в функции раньше времени.
Стиль интервьюера
Интервьюер не топит кандидата, а поддерживает его на плаву; цель — выявить максимально сильные стороны при минимальном количестве подсказок. Помощь идёт по нарастающей: сначала наводящие вопросы, затем небольшие подсказки и только в крайнем случае — разбор решения. Интервьюер ведёт заметки в отдельном поле (тайминги, варианты решений), которые потом проверяются другими собеседующими. Опечатки прощаются (поправляются молча/намёком), но логические ошибки кандидат ищет сам с подсказками. Чем больше подсказок потребовалось, тем ниже балл, но дожатое наводящими вопросами решение всё равно засчитывается. Если кандидат нервничает, могут убрать таймер. Баг, пропущенный собеседующим, не засчитывается кандидату.
04
Теория
Почему в цикле условие на указатели start строго меньше end, а не start <= end? Что будет, если они равны друг другу?
Серединный символ по определению не учитывается.
05
Теория
Сравните расход памяти решения с двумя указателями и однострочника через replace/reverse (toLowerCase + разворот строки). Какой расход памяти у каждого — константный или линейный?
Создание приведённой/развёрнутой строки даёт линейный расход памяти.
06
Код
Напишите асинхронную функцию findPath(from, to, getFlights), где getFlights — асинхронная функция, принимающая город и возвращающая массив городов, куда можно из него долететь. Функция должна вернуть отклонённый промис, если пути нет, либо resolved-промис с маршрутом от начальной до конечной точки. Известно, что маршрут единственный, без петель.
Вторая задача (посложнее), про асинхронность и обход графа. Решается BFS с очередью.
07
Теория
Какой обход графа использовать для поиска пути — в ширину (BFS) или в глубину (DFS), и почему?
Обсуждалось, что в общем случае искомая точка может быть неглубоко, поэтому равномерный обход в ширину предпочтительнее.
08
Теория
Оцените сложность вашего решения задачи findPath по памяти.
В исходном решении хранятся полные маршруты для каждой точки, что даёт квадратичную память O(n^2).
09
Кейс
Предложите входные данные (худший случай), которые убьют это решение по памяти — так чтобы на сервере не хватило памяти.
Худший случай — цепочка из точек, где конечная точка требует максимально длинного пути.
10
Теория
Верно ли утверждение, что если решение требует квадратичного количества памяти, то оно требует не менее квадратичного количества CPU?
11
Код
Предложите более оптимальное решение задачи findPath: как избавиться от хранения полных маршрутов для каждой точки? (хранить для каждой точки только предка — откуда пришли)
Подсказка интервьюера: для восстановления маршрута достаточно знать для каждой точки, откуда в неё пришли.
12
Код
Восстановите маршрут из словаря предков (для каждой точки известно, откуда пришли), пройдя от конечной точки к начальной.
13
Кейс
В каких крайних случаях ваше решение восстановления маршрута не будет работать?
Случай маршрута из одной точки (когда start === to и предка нет).
14
Теория
Как избавиться от квадратичной сложности при восстановлении маршрута, если вы вставляете элементы в начало массива (spread/unshift)? (формировать массив в обратном порядке и развернуть его в конце)
Вставка в начало массива требует копирования всех элементов; reverse в конце даёт линейную сложность.
15
Теория
Какова сложность операции shift у массива, используемого как очередь, и как обрабатывать очередь, чтобы избежать копирования всех элементов при извлечении из начала?
Для данной задачи порядок обработки очереди неважен, поэтому менять код фактически не пришлось.