Собеседование Middle Golang: вопросы, темы и критерии оценки

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

Чем Middle отличается от Junior

Самостоятельность

Middle берет задачу в формате user story и доводит до продакшена. Он сам разбирается в требованиях, проектирует решение, реализует, покрывает тестами и раскатывает в production. Вам не нужно расписывать каждый шаг — достаточно обозначить цель и ожидаемый результат.

Архитектурное мышление

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

Понимание бизнес-контекста

Middle спросит: «Зачем нужна эта фича? Как она влияет на метрики продукта? Может, есть альтернативное решение, которое быстрее доставит ценность?» Он понимает, что код — это средство доставки бизнес-ценности, а не самоцель.

Техническая глубина

Middle понимает, КАК работают горутины, планировщик, сборщик мусора. Он может профилировать производительность приложения, находить узкие места и оптимизировать их с измерениями до и после. Он не угадывает, а измеряет и принимает решения на основе данных.

Коммуникация

Middle проактивно коммуницирует: сообщает о блокерах, рисках, предлагает альтернативные решения. Он может объяснить техническое решение нетехническому человеку — PM, заказчику, руководителю — на понятном языке без избыточного жаргона.

На что обращать внимание при найме Middle

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

Middle — это будущий Senior или Tech Lead. Вложения времени и денег в правильного Middle’а окупается кратно, потому что через год-два он способен стать опорой команды.

Темы (кратко)

Технические темы (8 штук)

  1. Конкурентность и синхронизация — горутины, каналы, select, context, race conditions, deadlock, примитивы синхронизации. Ожидается понимание модели конкурентности Go, и умение применять правильные инструменты для решения задач.

  2. Управление памятью и производительность — стек против кучи, escape analysis, профилирование (через pprof), бенчмаркинг, оптимизация аллокаций, понимание работы сборщика мусора.

  3. Работа с базами данных — database/sql, lib/pq, pgx, sqlx, транзакции, пулы соединений, миграции, понимание ACID и уровней изоляции.

  4. Паттерны проектирования и архитектура — чистая архитектура, DDD основы, SOLID принципы в Go, инъекция зависимостей, интерфейсы как контракты, разделение на слои (handlers, services, repositories).

  5. Протоколы и API дизайн — лучшие практики REST и GRPC, middleware, context propagation, graceful shutdown, rate limiting, аутентификация и авторизация, идемпотентность.

  6. Тестирование в Go — табличные тесты, моки (testify, gomock), покрытие тестами, интеграционное тестирование, бенчмарки.

  7. Обработка ошибок и устойчивость — оборачивание ошибок (errors.Is, errors.As), retry паттерны, экспоненциальный backoff, circuit breaker, graceful degradation.

  8. Observability и диагностика — структурированные логи (slog), метрики (Prometheus), трейсинг (OpenTelemetry), health проверки, readiness пробы, мониторинг производительности.

Soft skills и бизнес-ориентация (4 темы)

  1. Декомпозиция задач и оценка сроков — умение разбить фичу на подзадачи, реалистичная оценка с учетом рисков, понимание треугольника scope-time-quality, коммуникация при сдвиге сроков.

  2. Коммуникация с заказчиком — выявление реальных требований и проблем (техника «5 почему»), управление ожиданиями, объяснение технических ограничений нетехническому человеку, проактивность в коммуникации.

  3. Приоритизация и фокус на ценности — понимание MVP vs полнофункциональная версия, умение отказаться от over-engineering, выбор решения исходя из бизнес-целей, time-to-market против совершенства кода.

  4. Код ревью и командная работа — опыт ревью кода (как автор и ревьювер), конструктивная критика кода, менторинг джуниоров, работа в распределенной команде, линтеры.

Темы (подробно)

1. Конкурентность и синхронизация

Что проверяем: Понимание модели конкурентности Go, умение выбрать правильный примитив синхронизации для конкретной задачи, знание типичных проблем (race conditions, deadlocks, утечка рутин), практический опыт с отмены context’а операций.

Критерии оценки:

УровеньОжидания
Не прошелПутает горутины и потоки ОС, не знает про гонку данных
Проходной минимумОбъясняет горутины и каналы, знает sync.Mutex, sync.RWMutex, sync.WaitGroup, пакет errgroup
Хороший middleЗнает select, context, может выбрать между каналом и мьютексом
Сильный middleПонимает планировщик, знает про GOMAXPROCS, умеет диагностировать deadlock, объясняет паттерн «worker pool»

Примеры вопросов/задач:

  1. Теория: Чем отличается горутина от потока ОС? Что произойдет, если создать миллион горутин?

  2. Практика: Напишите worker pool, который обрабатывает задачи из канала с ограничением количества воркеров. Как корректно завершить все воркеры при получении сигнала остановки?

  3. Диагностика: Дан код с race condition — найдите и исправьте:

    var counter int
    for i := 0; i < 100; i++ {
        go func() {
            counter++ // race!
        }()
    }
    
  4. Пакет context: Как использовать context.Context для отмены долгих операций? Когда использовать WithTimeout vs WithDeadline vs WithCancel? Приведите пример HTTP-хендлера, который прерывается при отмене запроса от клиента.

  5. Продвинутое: Что такое deadlock? Приведите пример кода, который гарантированно приведет к deadlock. Как диагностировать deadlock в production?

На что обращать внимание:

Полезные ссылки и материалы (Go 1.23-1.25):


2. Управление памятью и производительность

Что проверяем: Понимание модели памяти Go: стек, куча, сборщик мусора, escape analysis. Что это, зачем, как влияет на производительность, умение бенчить, профилировать и оптимизировать код.

Критерии оценки:

УровеньОжидания
Не прошелНе знает про GC, не слышал про pprof
Проходной минимумПонимает базово GC, знает что аллокации на куче медленнее стека
Хороший middleУмеет пользоваться pprof, понимает escape analysis, писал бенчмарки
Сильный middleЧитает assembly вывод, оптимизировал реальный код с измерениями до/после, понимает компромиссы оптимизаций

Примеры вопросов/задач:

  1. Теория: Когда переменная попадает на стек, а когда на кучу? Что такое escape analysis? Как компилятор принимает решение?

  2. Практика: Даны два варианта функции — какой быстрее и почему?

    // Вариант 1
    func process1() *Result {
        r := Result{}
        return &r  // escapes to heap
    }
    
    // Вариант 2
    func process2() Result {
        r := Result{}
        return r  // может остаться на стеке
    }
    
  3. Профилирование: Как найти, какая функция в вашем сервисе потребляет больше всего CPU/RAM? Опишите шаги использования pprof.

  4. Бенчмарки: Напишите бенчмарк для функции конкатенации строк. Как убедиться, что компилятор не оптимизировал код (dead code elimination)? Что такое b.N/b.Loop() и как Go подбирает это значение?

  5. Тонкая настройка GC: В каких случаях имеет смысл настраивать GOGC? Приведите пример сценария. Какие есть альтернативы настройке GC?

На что обращать внимание:

Полезные ссылки и материалы (Go 1.24-1.25):


3. Работа с базами данных

Что проверяем: Практический опыт с PostgreSQL/MySQL из Go, понимание database/sql, lib/pq, pgx, sqlx — когда что использовать, знание про транзакции, уровни изоляции, пуллинг соединений, умение избежать типичных проблем (SQL инъекции, утечка соединений).

Критерии оценки:

УровеньОжидания
Не прошелНе работал с БД из Go, не знает database/sql
Проходной минимумИспользовал database/sql или GORM, понимает базовые запросы и транзакции
Хороший middleЗнает pgx, понимает транзакции, connection pooling, миграции
Сильный middleОптимизировал запросы, использовал prepared statements, знает уровни изоляции ACID, понимает в чём PostgreSQL измеряет дороговизну запроса

Примеры вопросов/задач:

  1. Теория: В чем разница между database/sql, pgx и sqlx? Когда что использовать? Какие преимущества дает pgx над pq?

  2. Транзакции: Как правильно обернуть несколько операций в транзакцию в Go? Что делать при ошибке в середине транзакции? Покажите пример с rollback и commit.

  3. Connection pooling: Как настроить размер пула соединений? Что такое MaxOpenConns, MaxIdleConns и ConnMaxLifetime? Как выбрать правильные значения для высоко-нагруженного сервиса?

  4. Миграции: Какие инструменты для миграций знаете (например goose)? Как откатывать миграции? Как организовать миграции в production с минимальным простоем?

На что обращать внимание:

Полезные ссылки и материалы:


4. Паттерны проектирования и архитектура

Что проверяем: Знание базовых паттернов (репозиторий, инъекция зависимостей, фабрика), понимание SOLID принципов применительно к Go, умение структурировать код (слоистая архитектура и чистая архитектура), опыт рефакторинга.

Критерии оценки:

УровеньОжидания
Не прошелВесь код в одном файле/пакете, нет структуры
Проходной минимумРазделяет handlers/services/repositories, знает интерфейсы
Хороший middleПонимает инъекцию зависимостей, использует паттерны осознанно, может обосновать выбор
Сильный middleМожет спроектировать микросервис с нуля, понимает разницу для применения паттернов, объясняет выбор архитектуры через бизнес-требования

Примеры вопросов/задач:

  1. SOLID: Объясните принцип единственной ответственности. Приведите пример нарушения в Go-коде. Как его исправить?

  2. Инъекция зависимостей: Как внедрять зависимости в Go, где располагать интерфейсы? Покажите на примере структуры с несколькими зависимостями.

  3. Паттерн репозиторий: Зачем нужен? Как выглядит интерфейс репозитория для User? Какие методы должны быть? Что должно возвращаться при ошибках?

  4. Архитектура: Как бы вы структурировали REST API сервис на Go? (handlers, services, repositories, models). Какие слои и зачем? Как будут зависеть друг от друга?

  5. Рефакторинг: Даётся «God Object» (1000+ строк, 20+ методов, все в одном файле) — как разбить на модули? С чего начать? Какие метрики использовать для оценки качества рефакторинга?

На что обращать внимание:

Полезные ссылки и материалы:


5. HTTP и API дизайн

Что проверяем: Опыт построения REST API или gRPC сервисов, знание middleware, понимание graceful shutdown, rate limiting, аутентификация, авторизация, HTTP/2 особенности.

Критерии оценки:

УровеньОжидания
Не прошелНе писал HTTP сервисы в Go
Проходной минимумИспользовал net/http или gin/echo, знает handlers и routing
Хороший middleПонимает middleware, context propagation, graceful shutdown, знает REST
Сильный middleПроектировал API с версионированием, rate limiting, observability, понимает идемпотентность

Примеры вопросов/задач:

  1. Лучшие практики REST: Как бы вы спроектировали CRUD API для блога? (ручки, HTTP методы, статус-коды). Какой метод будем использовать для получения списка постов? Для создания? Для обновления?

  2. Middleware: Напишите middleware для логирования всех HTTP запросов (метод, URL, продолжительность, статус). Как передать ID запроса через цепочку middleware?

  3. Graceful shutdown: Как корректно остановить HTTP сервер при получении SIGINT или SIGTERM, не оборвав существующие запросы?

  4. Rate limiting: Как реализовать простой rate limiter на уровне приложения? (token bucket, sliding window). Где хранить состояние? Что возвращать клиенту при превышении лимита?

  5. Аутентификация: JWT или сессии — плюсы и минусы каждого подхода? Где хранить JWT на клиенте? Как обрабатывать refresh tokens?

На что обращать внимание:

Полезные ссылки и материалы:


6. Тестирование в Go

Что проверяем: Практика написания юнит-тестов, табличные тесты (идиома Go), использование моков (testify/mock, gomock), интеграционные тесты, понимание покрытия тестами и ограничений.

Критерии оценки:

УровеньОжидания
Не прошелНе пишет тесты, не знает testing пакет
Проходной минимумПишет базовые unit tests, знает t.Run для вложенных тестов
Хороший middleИспользует табличные тесты, использует моки, анализирует покрытие, понимает разницу юнит-тестом и интеграционным
Сильный middleПокрывает интеграционные сценарии, знает testcontainers, пишет бенчмакри

Примеры вопросов/задач:

  1. Табличные тесты: Напишите табличные тесты для функции, которая валидирует email адреса. Как организовать тестовые случаи? Что делать с негативными кейсами?

  2. Моки: Как протестировать сервис, который ходит в БД и внешний API, не поднимая реальные зависимости? (интерфейсы + моки). Покажите пример с testify/mock.

  3. Покрытие: Как измерить покрытие тестами? Какой процент покрытия считается хорошим? Почему 100% покрытия не гарантирует отсутствие багов?

  4. Интеграционные тесты: Как бы вы тестировали HTTP сервер с реальной БД? Когда имеет смысл писать интеграционные тесты, а когда достаточно юнит-теста?

На что обращать внимание:

Полезные ссылки и материалы:


7. Обработка ошибок и устойчивость

Что проверяем: Понимание обработки ошибок в Go (error как значение, не исключение), error wrapping (errors.Is, errors.As) с Go 1.13+, retry patterns, exponential backoff, circuit breaker, graceful degradation и fallback механизмы.

Критерии оценки:

УровеньОжидания
Не прошелИгнорирует ошибки (_ = err) или всегда паникует
Проходной минимумПроверяет ошибки, использует fmt.Errorf
Хороший middleИспользует error wrapping (%w), понимает ситуации когда приемлемо использовать panic
Сильный middleРеализовал retry, circuit breaker, понимает fault tolerance паттерны, может объяснить fail-fast vs fault-tolerant

Примеры вопросов/задач:

  1. Error wrapping: В чем разница между fmt.Errorf("%w", err) и fmt.Errorf("%v", err)? Когда использовать каждый вариант?

  2. Sentinel errors: Что это? Приведите пример из стандартной библиотеки (io.EOF, sql.ErrNoRows).

  3. Retry pattern: Реализуйте функцию retry с экспоненциальным backoff и максимальным количеством попыток. Как обрабатывать context cancellation во время retry?

  4. Circuit breaker: Что это и когда применять? Приведите пример сценария (внешний API недоступен). Какие состояния у circuit breaker?

  5. Паника или ошикба: Когда в Go использовать panic, а когда возвращать error? Что делать с panic из сторонних библиотек?

На что обращать внимание:

Полезные ссылки и материалы:


8. Observability и диагностика

Что проверяем: Структурированные логи (slog в Go 1.21+), метрики (Prometheus), трейсинг (OpenTelemetry), health checks, readiness probes (для Kubernetes), понимание трёх столпов наблюдаемости.

Критерии оценки:

УровеньОжидания
Не прошелИспользует fmt.Println для логирования в проде
Проходной минимумИспользует logrus или zap, логирует ошибки и важные события
Хороший middleИспользует structured logging (slog), экспортирует метрики (Prometheus)
Сильный middleНастраивал трейсинг, понимает пользу распределенного трейсинга, понимает зачем требуется сэмплирование

Примеры вопросов/задач:

  1. Структурированные логи: Чем отличается от обычного текстового? Покажите пример с slog. Какие уровни логирования использовать и для чего?

  2. Метрики: Какие метрики вы бы собирали для HTTP сервиса? (latency, throughput, errors). В чем разница между counter, gauge, histogram, summary?

  3. Health checks: Как реализовать /health (liveness) и /ready (readiness) endpoints для Kubernetes? В чем разница? Что проверять в каждом?

  4. Трейсинг: Что такое trace, span, trace ID? Зачем нужно распределенный трейсинг? Как передавать trace context между сервисами?

  5. Уровни логов: Когда использовать DEBUG vs INFO vs WARN vs ERROR? Что логировать в production, а что только в dev/stage среде?

На что обращать внимание:

Полезные ссылки и материалы:


9. Декомпозиция задач и оценка сроков

Что проверяем: Умение разбить задачу на подзадачи, реалистичная оценка с учетом рисков, понимание что «быстро» не равно «хорошо», коммуникация при сдвиге сроков, понимание треугольника scope-time-quality.

Критерии оценки:

УровеньОжидания
Не прошелНе может разбить задачу, оценки всегда оптимистичны («сделаю за день»)
Проходной минимумРазбивает на шаги, даёт оценку с запасом
Хороший middleУчитывает тестирование, код-ревью, документацию в оценке, задает уточняющие вопросы
Сильный middleВыделяет риски, предлагает инкременты ценности (MVP → v2 → v3)

Примеры вопросов/задач:

  1. Практика: Задача — «Добавить фильтрацию пользователей по ролям в REST API». Разбейте на подзадачи и оцените время на каждую. Что может пойти не так?

  2. Риски: Какие риски вы учитываете при оценке задачи? (неопределенность, зависимости от других команд, технический долг, незнакомые технологии)

  3. Неопределенность: Как оценивать задачу, если не знаете технологию или предметную область? (spike, time-boxing, исследование, proof of concept)

  4. MVP мышление: Как бы вы приоритизировали функции для MVP версии продукта? Что включить в первую итерацию, что отложить на v1, что на v2?

  5. Задержка: Понимаете, что не успеваете в срок. Что делаете? (сообщить заранее, предложить урезать объём, перенести дедлайн, обосновать решение)

На что обращать внимание:


10. Коммуникация с заказчиком

Что проверяем: Умение выявлять реальные требования (не принимать постановку на веру), управление ожиданиями, объяснение технических ограничений нетехническому человеку, проактивность в коммуникации, техника «5 почему».

Критерии оценки:

УровеньОжидания
Не прошелИзбегает общения с заказчиком, только пишет код
Проходной минимумОтвечает на вопросы, может показать демо, реагирует на обратную связь
Хороший middleЗадает уточняющие вопросы, предлагает альтернативы, управляет ожиданиями
Сильный middleВыявляет скрытые требования («5 почему»), управляет ожиданиями проактивно, предлагает поэтапную доставку

Примеры вопросов/ситуаций:

  1. Выявление требований: Заказчик говорит «Мне нужна быстрая система». Какие вопросы зададите? (быстрая — это сколько мс? для какого сценария? сколько пользователей? что критичнее — задержка или пропускная способность?)

  2. Объяснение ограничений: Как объясните, что «добавить эту кнопку» займет неделю? (рефакторинг, тесты, интеграции, ревью безопасности, деплой)

  3. Альтернативы: Заказчик хочет фичу за 2 дня, но это нереалистично. Ваши действия? (предложить упрощенную версию, фича-тогглы, инкременты ценности)

  4. Демо: Как проводите демонстрацию новой фичи? (готовите сценарий, подготовленные данные, фокус на ценности, а не на технических деталях)

  5. Обратная связь: Заказчик недоволен результатом. Как реагируете? (слушаем, уточняем ожидания, предлагаем улучшения, не защищаемся)

На что обращать внимание:


11. Приоритизация и фокус на ценности

Что проверяем: Понимание разницы MVP и полнофункциональной версии, умение отказаться от over-engineering, выбор решения исходя из бизнес-целей, понимание компромисса time-to-market и совершенства кода, YAGNI принцип.

Критерии оценки:

УровеньОжидания
Не прошел«Код должен быть идеальным» — перфекционизм без учета контекста
Проходной минимумПонимает, что иногда «работает» важнее чем «красиво»
Хороший middleВыбирает уровень качества исходя из важности фичи, понимает техдолг
Сильный middleАргументирует решения через бизнес-метрики (выручка, DAU/MAU, engagement)

Примеры вопросов/ситуаций:

  1. MVP: Что вы включите в MVP для интернет-магазина? Что отложите на v2? (каталог, корзина, оплата — обязательно; избранное, отзывы, рекомендации — v2)

  2. Техдолг: Когда можно взять задачи на техдолг (быстрая доставка критична, конкурентное преимущество), а когда нельзя (платежная система, безопасность, комплаенс)?

  3. Over-engineering: Приведите пример, когда вы отказались от «красивого» решения в пользу простого. Почему? Какие были компромиссы?

  4. Компромиссы: Микросервисы или монолит — как принять решение для стартапа из 5 человек? (монолит проще, быстрее MVP, меньше операционных издержек)

  5. Бизнес-ценность: Как оценить, принесет ли оптимизация (ускорение на 100ms) бизнес-ценность? (зависит от сценария: страница оплаты — критично, админ-панель — не важно)

На что обращать внимание:


12. Ревью кода и командная работа

Что проверяем: Опыт ревью кода (как автор и как ревьювер), конструктивная критика кода, менторинг джуниоров, работа в распределенной команде и CI/CD интеграции.

Критерии оценки:

УровеньОжидания
Не прошелНе понимает зачем нужно ревью кода, воспринимает критику лично
Проходной минимумУчаствует в ревью, исправляет замечания, оставляет комментарии
Хороший middleДает конструктивные комментарии, менторит джуниоров, понимает баланс улучшений стиля и критических проблем
Сильный middleСоздает культуру качества в команде, автоматизирует проверки в CI пайплайнах, асинхронная коммуникация

Примеры вопросов/ситуаций:

  1. Процесс кодревью: Как вы проводите ревью? На что обращаете внимание? (логика, тесты, читаемость, безопасность, производительность)

  2. Конструктивная критика: Что скажете на плохой код, не демотивируя автора? (фокус на код, не на человека; объяснить почему; предложить альтернативы)

  3. Менторинг: Джуниор написал код с проблемами. Как поступите? (объясняете почему проблема, даете ссылки на лучшие практики, примеры)

  4. Конфликт: Коллега не согласен с вашим комментарием в ревью. Ваши действия? (обсуждаем, приводим аргументы, идем на компромисс, эскалируем если нужно)

  5. Лучшие практики: Какие практики ревью вы считаете обязательными? (автоматизация, чек-листы, фокус на важное, асинхронность)

На что обращать внимание:


Теги: