Загрузка…
Загрузка…
backend / middle / tech_deep
Формат
online
Стадия
tech_deep
Когда
within_quarter
Длительность
60 мин
01
Код
Дан код на Go: скажите, что выведет программа (структура передаётся в функцию, принимающую указатель, внутри присваивается новый объект).
Задача 1 лайвкодинга: предсказать вывод программы (Bob/Alice).
02
Теория
Почему программа выведет Bob, а не Alice? Что происходит при передаче указателя в функцию (копирование указателя, присваивание нового объекта внутри функции)?
Follow-up к задаче 1.
03
Код
Поправь код так, чтобы программа выводила Alice (чтобы изменение объекта внутри функции было видно снаружи).
Follow-up к задаче 1: live-фикс кода.
04
Теория
Какие ещё варианты знаешь, как можно было бы изменить объект через функцию (например, передать указатель на указатель)?
Заметки
Транскрипт технического собеседования по Go в Авито (компания упомянута в конце: вопросы кандидата «по поводу работы Авито»). Формат: 1 час, 3 задачи лайвкодинга (вывод программы с указателями; счётчик ошибок/запросов с выводом rate раз в секунду; обёртка predict с таймаутом через context и select) + теоретический блок по внутренностям Go: горутины, планировщик GMP, runtime, каналы, примитивы синхронизации, интерфейсы, слайсы/мапы, GC, тестирование, профилирование. Результат собеседования в транскрипте не упомянут.
Стиль интервьюера
Общение на «ты», доброжелательное. Интервьюер активно задаёт уточняющие follow-up'ы по ходу решения («почему так?», «какие ещё варианты?», «что происходит на этой строке?»), подсказывает и направляет (например, разрешает опустить контекст, помогает с условием), просит дорабатывать решение итеративно. Пропускает вопрос, если кандидат не помнит. В конце оставляет время на вопросы кандидата.
Follow-up к задаче 1.
05
Код
Реализуйте подсчёт количества ошибок и общего количества запросов HTTP-ручки и раз в секунду выводите их отношение (error rate).
Задача 2 лайвкодинга. Кандидат использовал atomic-счётчики и отдельную горутину с тикером.
06
Теория
Для чего ты здесь используешь atomic — что будет, если ручки запустятся параллельно (гонка данных)?
Follow-up к задаче 2.
07
Код
Как организовать вывод метрики раз в секунду — откуда и как запускать отдельную горутину, не внутри обработчика (структура со счётчиками, метод-handler и метод с фоновой горутиной)?
Follow-up к задаче 2: интервьюер попросил вынести периодический вывод из ручки.
08
Теория
Для чего ты хотел передать контекст в фоновую горутину?
Follow-up к задаче 2: чтобы горутина не работала бесконечно и не утекла.
09
Теория
Расскажи, что происходит на строке с ожиданием канала тикера (time.Tick) — как работает ожидание в цикле for?
Follow-up к задаче 2: интервьюер указал на конкретную строку (50-я) в коде кандидата.
10
Теория
Почему ты использовал atomic, а не другой примитив синхронизации (например, mutex)? Чем atomic отличается от mutex?
Follow-up к задаче 2. Обсудили, что mutex внутри сам использует atomic как счётчик занятости.
11
Теория
Что такое горутина и в чём её легковесность по сравнению с потоком операционной системы?
Начало теоретического блока.
12
Теория
За счёт чего достигается быстрое переключение контекста между горутинами по сравнению с потоками ОС?
Follow-up: размер стека, отсутствие регистров/данных уровня ОС, планировщик Go.
13
Теория
Расскажи подробнее про планировщик Go: как он работает (модель GMP, локальные и глобальная очереди, work stealing, netpoller)?
Интервьюер уточнял: куда идёт процессор P, когда заканчивается локальная очередь (глобальная очередь, воровство из других очередей, netpoller).
14
Теория
Чем занимается рантайм Go? Какие ещё функции у него есть, кроме планировщика и сборщика мусора?
15
Теория
За счёт чего Go позволяет работать с большим количеством сетевых соединений?
Обсуждали обработку каждого соединения в отдельной горутине и очередь ожидания сетевых вызовов (netpoller).
16
Теория
Что такое каналы в Go и для чего они нужны (буферизированные и небуферизированные, закрытие канала, запись/чтение из закрытого канала)?
17
Теория
Что будет, если записать в nil-канал?
Follow-up к вопросу про каналы.
18
Теория
Что будет, если прочитать из nil-канала?
Follow-up к вопросу про каналы.
19
Теория
Как выполняется передача значений из одной горутины в другую через канал — как канал устроен внутри (мьютекс, копирование из стека отправителя, оптимизации)?
20
Теория
Как реализован буфер канала внутри (кольцевая очередь)?
Follow-up к вопросу об устройстве канала.
21
Поведенческий
Приходилось ли на практике использовать nil-каналы (например, в select)?
22
Теория
Какие примитивы синхронизации в Go знаешь, кроме atomic и mutex (RWMutex, WaitGroup, каналы)?
23
Теория
Что такое интерфейс в Go и из чего он состоит внутри (информация о типе и значение, утиная типизация)?
Интервьюер попросил ещё раз подробнее рассказать, из чего состоит интерфейс внутри.
24
Код
Оберните функцию predict в управляемую функцию с таймаутом: запустить вызов в горутине, через select ждать либо отмены контекста, либо результата из буферизированного канала.
Задача 3 лайвкодинга. Обсудили, зачем нужен буферизированный канал ёмкости 1 (чтобы горутина не зависла на записи после таймаута).
25
Теория
А контекст у нас завершится когда-нибудь? Что будет, если контекст никогда не отменят — как ограничить ожидание (контекст с таймаутом)?
Follow-up к задаче 3.
26
Код
Измерьте, сколько времени выполнялся именно вызов predict внутри обёртки.
Follow-up к задаче 3.
27
Код
Доработайте обёртку так, чтобы оборачиваемая функция predict возвращала ещё и ошибку, и обработайте её.
Follow-up к задаче 3.
28
Теория
Мы закрываем канал в этом коде — а можно ли его вообще не закрывать? Нужно ли это здесь?
Follow-up к задаче 3.
29
Теория
Чем слайс отличается от мапы? Зачем нужна мапа и какие типы могут быть её ключом (comparable-типы)?
Блок про использование памяти в Go.
30
Теория
Чем длина слайса (len) отличается от его ёмкости (cap)?
31
Теория
Что происходит, когда нужно добавить элементы в слайс, а capacity уже исчерпан (как растёт слайс, что происходит со старым массивом)?
Обсудили удвоение до ~1024 элементов и дальнейший рост по формуле, копирование в новый массив.
32
Теория
Что происходит в мапе при заполнении (рост, бакеты по 8 элементов, инкрементальная эвакуация данных)?
33
Теория
Как происходит сборка мусора в Go (трёхцветная маркировка mark-and-sweep, барьер записи, stop the world)?
34
Поведенческий
Приходилось ли тебе писать тесты? Какие виды тестов знаешь (unit, функциональные, интеграционные, e2e)?
35
Теория
Какие полезные аргументы/флаги команды go test знаешь?
Follow-up к вопросу про тесты.
36
Теория
Что такое мок (mock) и для чего он используется в тестах?
37
Поведенческий
Сталкивался ли ты с профилированием программ (pprof)?
38
Теория
Для чего нужно профилирование программ?
Follow-up: выявление аномального поведения, утечек горутин, медленных функций.
39
Теория
Какие параметры можно посмотреть при профилировании, кроме процента выполнения по CPU и памяти?
Кандидат не вспомнил, вопрос пропустили.