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

(последнее обновление от )

Senior Go-разработчик отвечает за подсистему или сервис целиком: проектирует, поддерживает, развивает. Влияет на решения за пределами своих задач, помогает расти коллегам. Таких людей на рынке мало, а ошибка при найме обходится дорого — Senior принимает решения, которые живут в системе годами после его ухода.

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

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

Зона ответственности

Middle отвечает за реализацию задачи, Senior — за подсистему или сервис целиком: API, схему данных, эксплуатацию, ресурсы, план развития на 6-12 месяцев вперёд. Senior не ждёт, когда ему принесут задачу. Он сам ищет узкие места, в которые подсистема может упереться по производительности, формализует техдолг и берётся за устранение.

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

Middle способен спроектировать микросервис с нуля. Senior сначала спрашивает, а нужен ли вообще отдельный сервис, или это модуль в монолите (монолит vs микросервисы). Он мыслит на уровне границ сервисов, контрактов, отказоустойчивости и стоимости владения — а не на уровне пакетов и функций.

Технические компромиссы и принятие решений

Senior формулирует выбор как trade-off с обоснованием через бизнес-метрики, нагрузку и операционные риски. Умеет составить ADR (Architecture Decision Record). Не исходит из позиции «мне кажется, так будет лучше».

Глубина в Go

Senior знает, как Go устроен внутри, а не только как им пользоваться: модель памяти, планировщик, сборщик мусора, escape analysis. Он читал исходники стандартной библиотеки и может объяснить, почему sync.Map быстрее в одном паттерне доступа и медленнее в другом — без подглядывания в документацию.

Лидерство и развитие людей

В роль Senior’а входит и техническое лидерство. Он менторит джунов и миддлов, делает ревью кода так, чтобы команда писала лучше, умеет давать обратную связь — в том числе негативную. Без этих навыков получается не Senior, а «Middle с десятилетним опытом».

Почему собеседование делят на два этапа

С Junior и Middle хватает одного интервью: вы проверяете язык, базовые паттерны и софт-скиллы. С Senior так не сработает по двум причинам.

Разный фокус навыков. Глубокое знание Go и умение проектировать распределённую систему — это разные вещи. Сильный разработчик может слабо ориентироваться в архитектуре сервисов под нагрузкой. Сильный архитектор — писать посредственный Go-код. На Senior-позиции нужно и то и другое, и проверять эти навыки приходится отдельно: иначе вы либо переоцените язык, либо переоцените архитектуру.

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

Итоговая схема оценки навыков получается примерно такая:

ЭтапДлительностьФорматЧто проверяем
1. Технический (Go)60-75 минВопросы + 1-2 небольшие задачиГлубина языка, рантайма, экосистемы
2. Архитектурный60-90 минОткрытый дизайн системы по кейсуПроектирование, компромиссы, операционная зрелость

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

Этап 1. Технический (Go)

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

  1. Рантайм и модель памяти — планировщик горутин, GMP-модель, GC, escape analysis, модель памяти Go (happens-before, синхронизация).
  2. Конкурентность на уровне дизайна — паттерны (pipeline, fan-in/fan-out, worker pool, semaphore), управление backpressure, отмена через context, утечки горутин.
  3. Производительность и низкий уровень — pprof CPU/mem/goroutine/block/mutex, чтение flamegraph, бенчмарки и benchstat, sync.Pool, аллокации, зачем нужен unsafe.
  4. Стандартная библиотека и внутренности — что внутри net/http, database/sql, encoding/json, как работают sync.Mutex и sync.WaitGroup, дженерики.
  5. Дизайн API и библиотек — обратная совместимость, semver, идиоматичные интерфейсы (принимаем интерфейс, возвращаем структуру), функциональные опции, godoc.
  6. Обработка ошибок и устойчивость — кастомные типы ошибок, errors.Is/errors.As, context.Cause, retry с jitter, circuit breaker, идемпотентность, graceful degradation.
  7. Тестирование сложных систем — табличные тесты, моки vs стабы vs фейки, интеграционные тесты через testcontainers, тестирование контрактов пакета, fuzzing.
  8. Безопасность и supply chaingovulncheck, политика обновлений зависимостей, секреты и их ротация, TLS/mTLS, защита от типовых уязвимостей в HTTP-сервисах (инъекции, CSRF, IDOR и т.п.).

1.1 Рантайм и модель памяти

Что проверяем: Как Go работает под капотом: планировщик, переключения, сборка мусора, escape analysis, модель памяти. Senior должен уметь объяснить наблюдаемое поведение (рост latency, p99, всплески CPU) через свойства рантайма.

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

УровеньОжидания
Не прошёлНе отличает горутину от потока, не слышал про GC tuning
Проходной минимумПонимает GMP-модель в общих чертах, знает, что есть escape analysis
Хороший seniorОбъясняет, что происходит при блокирующем системном вызове, как работают preemption и GOMAXPROCS, читал статью про GC
Сильный seniorСвязывает рантайм с наблюдаемыми метриками, диагностировал реальные инциденты с применением runtime/* пакетов, понимает компромиссы GOGC/GOMEMLIMIT

Примеры вопросов:

  1. Опишите GMP-модель. Что произойдёт, если горутина уйдёт в долгий блокирующий syscall? А если в долгий CPU-bound цикл без точек preemption? Что изменилось с Go 1.14 (asynchronous preemption)?

  2. Что такое модель памяти Go? Когда нужно явно синхронизировать доступ, а когда хватает канала или happens-before-гарантий стартующей горутины? Приведите пример кода, который «вроде работает», но фактически содержит data race.

  3. Как сборщик мусора Go (трёхцветный, конкурентный, неперемещающий) влияет на p99 задержки? Когда имеет смысл крутить GOGC, а когда — GOMEMLIMIT (Go 1.19+)?

  4. Что такое escape analysis? Приведите пример кода, где значение «убегает» на кучу — например через interface{}, замыкание или возврат указателя. Как это проверить (go build -gcflags="-m")?

  5. У сервиса периодически растёт CPU на 30% без роста нагрузки. С чего начнёте диагностику? (pprof, runtime/trace, метрики GC через GODEBUG=gctrace=1).

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


1.2 Конкурентность на уровне дизайна

Что проверяем: Не «знает каналы», а умеет выбрать паттерн под задачу: pipeline для потоковой обработки, fan-out для распараллеливания, worker pool для ограничения ресурсов, семафор через буферизованный канал. Понимает backpressure и graceful shutdown.

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

УровеньОжидания
Не прошёлКаналы и мьютексы как «взаимозаменяемые», игнорирует утечки горутин
Проходной минимумЗнает базовые паттерны, использует context для отмены
Хороший seniorВыбирает паттерн осознанно, обоснованно использует errgroup, понимает backpressure
Сильный seniorПроектирует pipeline под нагрузку, учитывает кардинальность очередей, fairness, диагностирует через runtime/pprof goroutine и runtime/trace

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

  1. Дизайн: Пишете сервис, который читает события из Kafka, обогащает их вызовом внешнего API (медленный, ~200мс) и пишет в БД. Опишите конкурентную схему. Где здесь backpressure? Что произойдёт, если внешний API лёг?

  2. Worker pool: Реализуйте worker pool с ограничением N горутин, отменой через context и сбором ошибок. Какие компромиссы между передачей задач через канал и через semaphore + WaitGroup?

  3. Утечки: Покажите три способа «утечь» горутиной. Как их находить в проде? (pprof goroutine, метрика go_goroutines, alerting на рост).

  4. Тонкое: Чем errgroup отличается от ручной координации через канал ошибок? Что нового в Go 1.25 WaitGroup.Go?

  5. Подвох: Дан код с select из трёх каналов в цикле. При закрытии одного из каналов цикл крутит CPU на 100%. Почему? Как исправить?

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


1.3 Производительность и низкий уровень

Что проверяем: Умение оптимизировать с измерениями. Senior не «оптимизирует на глаз»: профилирует, формулирует гипотезу, измеряет до и после через benchstat. И знает, когда оптимизация принесёт пользу, а когда это over-engineering.

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

УровеньОжидания
Не прошёл«Оптимизирую на глаз», не знает pprof
Проходной минимумПрофилирует CPU и память через pprof, пишет бенчмарки
Хороший seniorЧитает flamegraph, использует benchstat, понимает аллокации, применял sync.Pool
Сильный seniorПрофилировал прод-сервисы под нагрузкой, делал escape-аналитический рефакторинг, знает runtime/metrics, понимает компромиссы unsafe

Примеры вопросов:

  1. Сервис тратит 20% CPU на JSON-сериализацию. Ваши шаги? (профилирование → подтверждение → варианты: encoding/json v2, easyjson, code-gen, переход на protobuf; обязательное измерение с benchstat).

  2. Когда sync.Pool помогает, а когда вредит? Приведите конкретный сценарий, где sync.Pool ухудшил производительность.

  3. Покажите бенчмарк, в котором компилятор выкинет вашу горячую функцию (dead code elimination). Как защититься? (b.Loop() с Go 1.24, присвоение результата runtime.KeepAlive или глобальной var sink).

  4. Что такое false sharing в Go? Когда вы реально с этим сталкивались?

  5. unsafe: приведите случай, когда он оправдан, и случай, когда это плохая идея. Какие риски?

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


1.4 Стандартная библиотека и внутренности

Что проверяем: Знание стандартной библиотеки на уровне «как это сделано», а не «как этим пользоваться». Senior спокойно ориентируется в net/http, database/sql, encoding/json, sync. Идеально — читал исходники.

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

УровеньОжидания
Не прошёлЗнает только сигнатуры функций
Проходной минимумПонимает поведение основных пакетов, читает godoc
Хороший seniorЗаглядывал в исходники, объясняет неочевидные особенности
Сильный seniorМожет объяснить дизайн-решения авторов, знает историю эволюции пакетов

Примеры вопросов:

  1. Как net/http.Server обрабатывает соединения? Что такое http.Transport и почему важно переиспользование соединений? Что произойдёт, если не читать body ответа?

  2. database/sql: как устроен пул соединений? Чем pgx отличается от lib/pq (драйверы PostgreSQL)? Что значит ConnMaxLifetime и зачем оно нужно при работе через pgbouncer?

  3. encoding/json: что внутри? Почему он медленный, и какие альтернативы (json/v2, easyjson, sonic)? Какие подводные камни у sonic (случай с багом)?

  4. Generics с Go 1.18+: когда они уместны, а когда лучше остаться на интерфейсах? Почему slices.Sort быстрее, чем sort.Slice?

  5. Что нового в стандартной библиотеке между Go 1.21 и Go 1.25, что вы реально используете? (slog, cmp, maps/slices, unique, WaitGroup.Go).

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


1.5 Дизайн API и библиотек

Что проверяем: Умение проектировать публичные API: пакеты, интерфейсы, опции, расширяемость, обратная совместимость. Плохо спроектированный публичный API нельзя «откатить» — он застрянет в кодовой базе на годы, и Senior это понимает.

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

УровеньОжидания
Не прошёл«Какая разница, как назвать функцию»
Проходной минимумЗнает «принимаем интерфейс, возвращаем структуру»
Хороший seniorИспользует функциональные опции, продумывает обратную совместимость
Сильный seniorПроектирует API под эволюцию, понимает semver на уровне Go-модулей, документирует через примеры

Примеры вопросов:

  1. Проектируете клиент к внешнему сервису как библиотеку для коллег. Какой будет публичный API? Где интерфейсы, где структуры? Как передать таймауты, retry, метрики? (функциональные опции vs config struct).

  2. Семвер в Go-модулях: что значит v2, как его правильно выпускать, и почему мажорная версия попадает в путь импорта?

  3. Какие изменения в публичном API считаются ломающими в Go? (добавление метода в интерфейс — да, поля в публичную структуру — нет, при условии что её не создают литералом без имён полей).

  4. Когда оправдан паттерн «context.Context первым аргументом», а когда нет?

  5. Дан godoc плохой библиотеки — что бы вы исправили? (примеры, doc.go, идиоматичные имена, отсутствие глобального состояния).

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


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

Что проверяем: Идиоматичная обработка ошибок на уровне дизайна сервиса: классификация (retryable/non-retryable), wrapping, sentinel’ы vs типы, паттерны устойчивости (retry с jitter, circuit breaker, идемпотентность).

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

УровеньОжидания
Не прошёлif err != nil { return err } без контекста
Проходной минимумИспользует %w, errors.Is/errors.As
Хороший seniorКлассифицирует ошибки, реализовал retry с backoff и jitter
Сильный seniorПроектирует error-таксономию, понимает идемпотентность на уровне системы, реализовал circuit breaker и graceful degradation

Примеры вопросов:

  1. Сервис вызывает 5 внешних API. Как спроектируете обработку ошибок? Что считать retryable, что нет? Где границы транзакции?

  2. Retry: почему нужен jitter? Что произойдёт без него при отказе downstream-сервиса? (thundering herd, синхронизация retry, повторный обвал).

  3. Идемпотентность: как реализуете идемпотентный POST? (ключ идемпотентности, дедупликация, окно хранения).

  4. Когда оправдан circuit breaker, когда — bulkhead, когда достаточно таймаута? (три разных паттерна, разные цели).

  5. context.Cause с Go 1.20: зачем добавили, какие проблемы он решает?

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


1.7 Тестирование сложных систем

Что проверяем: Отношение к тестам: не «100% покрытия любой ценой», а понимание, где какой тест уместен. Senior умеет писать integration-тесты с testcontainers, contract-тесты для межсервисных API, fuzzing для парсеров.

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

УровеньОжидания
Не прошёл«Тесты пишет QA»
Проходной минимумЮнит-тесты, табличные тесты, моки
Хороший seniorIntegration через testcontainers, понимает пирамиду тестирования
Сильный seniorContract testing, fuzzing критичных мест, осознанный выбор «когда не тестировать»

Примеры вопросов:

  1. У вас 3 микросервиса: A → B → C. Какие тесты на каких границах? (юнит внутри, contract на границах, e2e только для критичных сценариев).

  2. Когда мок вреден? (когда тест становится тестом мока, а не кода; когда мок расходится с реальным поведением — классический «прод сломался, тесты зелёные»).

  3. Fuzzing: какие места в коде стоит фаззить? Покажите пример находки фаззингом (реальный случай с sonic).

  4. Как тестировать код с временем? (clock интерфейс, фейковые часы, не использовать time.Sleep в тестах).

  5. Flaky-тест в CI. Стратегия? (не «retry в CI», а найти причину: гонка, зависимость от порядка, внешний ресурс).

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


1.8 Безопасность и supply chain

Что проверяем: Senior отвечает за безопасность своего кода и зависимостей. «Security — это другая команда» — не позиция Senior’а. Базовое понимание угроз обязательно: уязвимости в зависимостях, секреты, TLS, классические дыры в HTTP-сервисах.

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

УровеньОжидания
Не прошёл«За безопасность отвечает security-команда»
Проходной минимумЗнает про SQL injection, параметризованные запросы, секреты не в git
Хороший seniorИспользует govulncheck, понимает supply chain risk, настраивает TLS
Сильный seniorПонимает OWASP, проводит threat modeling, ротирует секреты, ограничивает blast radius

Примеры вопросов:

  1. Стратегия обновления зависимостей: dependabot/renovate, политика мажорных обновлений, go.sum и проверка checksum. Что делать с CVE в транзитивной зависимости?

  2. govulncheck: чем отличается от обычного сканера CVE? (анализирует, реально ли вызывается уязвимый код, а не «есть ли он в go.sum»).

  3. Хранение секретов: что плохого в .env? Как ротировать? Где хранить (Vault, secrets manager облака)?

  4. TLS в Go: верифицируете ли цепочку, что такое pinning, когда нужна mTLS?

  5. HTTP-сервис: SSRF, открытые редиректы, CSRF — что из этого относится к API на Go и как защищаться?

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


Этап 2. Архитектурный

Это открытое интервью на 60-90 минут вокруг одного кейса. Я не использую заготовленный список вопросов: даю задачу и веду диалог. Проверяю не «знает ли он Kafka», а как он думает. Задаёт ли уточняющие вопросы. Формулирует ли требования. Рассматривает ли альтернативы. Обосновывает ли выбор.

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

  1. Сбор требований — функциональные и нефункциональные, нагрузка, SLA, бюджет, ограничения.

  2. Декомпозиция системы — границы сервисов, ownership данных, контракты, синхронные vs асинхронные взаимодействия.

  3. Хранилища данных — SQL vs NoSQL, репликация, шардирование, кэширование, выбор по требованиям.

  4. Распределённые свойства — consistency, CAP, exactly-once vs at-least-once, sagas, идемпотентность на уровне системы.

  5. Очереди и event-driven — Kafka vs RabbitMQ vs NATS, ordering, partitioning, ретраи и dead letter.

  6. Надёжность и операционная зрелость — SLO/SLI, observability (logs/metrics/traces), incident response, deploy-стратегии.

  7. Безопасность и compliance — авторизация, аудит, персональные данные, защита границы сети, мульти-тенант изоляция.

  8. Эволюция и стоимость — план миграции, обратная совместимость, capacity planning, cost-aware design.

2.1 Сбор требований

Что проверяем: Может ли кандидат не бросаться рисовать диаграмму по первой формулировке, а сначала выяснить, что на самом деле нужно. Применяет ли «5 почему», различает ли функциональные и нефункциональные требования.

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

УровеньОжидания
Не прошёлСразу начинает рисовать диаграмму
Проходной минимумУточняет, что должна делать система
Хороший seniorСпрашивает про нагрузку, SLA, бюджет, команду
Сильный seniorВыясняет реальную проблему за постановкой, проверяет ограничения, обсуждает что не нужно делать

Пример кейса:

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

Сильный senior за первые 10 минут задаст вопросы вроде:

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


2.2 Декомпозиция системы

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

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

УровеньОжидания
Не прошёл«Микросервисы потому что модно» или «всё в монолите потому что просто»
Проходной минимумРазделяет по функциональным областям
Хороший seniorАргументирует границы через ownership данных и autonomy команд
Сильный seniorПрименяет DDD-bounded contexts, обсуждает компромисс монолит/микросервисы через размер команды и cognitive load

Вопросы в дискуссии:

  1. Почему именно эти границы? Что произойдёт, если объединить сервисы A и B?

  2. Где у вас синхронные вызовы, где асинхронные? Что произойдёт, если очередь упадёт?

  3. Кто владеет данными о пользователе? Что делать, если две команды хотят добавить поле?

  4. Как менять контракт между сервисами без downtime?

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


2.3 Хранилища данных

Что проверяем: Выбор хранилища под требования, а не «потому что мы любим Postgres». Понимание репликации, шардирования, индексов, паттернов доступа, бэкапов и восстановления.

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

УровеньОжидания
Не прошёл«PostgreSQL подходит для всего» или «NoSQL быстрее»
Проходной минимумРазличает SQL и NoSQL, базово понимает индексы
Хороший seniorВыбирает под паттерн доступа, понимает репликацию, шардирование
Сильный seniorПроектирует с учётом точки роста, делал миграции хранилищ под нагрузкой, понимает RPO/RTO

Вопросы:

  1. Как выбираете между PostgreSQL, ClickHouse, ScyllaDB/Cassandra, S3 для разных частей системы?

  2. Когда нужно шардирование? Какие стратегии шардирования и компромиссы (consistent hashing, range, hash, geo)?

  3. Чтение из реплики: какие гарантии вы теряете? Как с этим жить (read-your-writes consistency)?

  4. Что такое RPO и RTO? Как они влияют на стратегию бэкапов?

  5. Кэширование: write-through, write-back, write-around, look-aside. Где какая стратегия и какие проблемы (thundering herd при инвалидации, stampede)?

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


2.4 Распределённые свойства

Что проверяем: Понимание сложности распределённых систем: consistency, ordering, exactly-once как иллюзия, сетевые партиции, частичные отказы. Где система реально гарантирует то, что обещает, а где гарантии — на бумаге.

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

УровеньОжидания
Не прошёл«Сеть надёжна», «exactly-once есть»
Проходной минимумЗнает CAP, понимает at-least-once
Хороший seniorПроектирует идемпотентность, понимает разницу strong/eventual consistency
Сильный seniorПрименяет saga, outbox, change data capture, понимает компромисс consistency и latency

Вопросы:

  1. Транзакция «перевести деньги между двумя сервисами»: как? (saga, two-phase commit и его проблемы, outbox).

  2. Гарантии Kafka: что значит «at-least-once», что нужно от потребителя для идемпотентности?

  3. Если в очереди порядок важен — как обеспечить? Что с этим теряете?

  4. Distributed transactions vs eventual consistency vs orchestration vs choreography — компромиссы.

  5. Сетевая партиция между датацентрами на 5 минут. Что произойдёт с вашей системой? Что вы выбираете — доступность или консистентность — и для какой части системы?

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


2.5 Очереди и event-driven

Что проверяем: Выбор брокера под задачу, проектирование топологии, обработка отказов: ретраи, DLQ, ordering. Подход не «возьмём Kafka», а «вот требования, поэтому Kafka, и вот цена этого выбора».

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

УровеньОжидания
Не прошёл«Берём Kafka» без обоснования
Проходной минимумВыбирает между Kafka и RabbitMQ по задаче
Хороший seniorПроектирует партиционирование, DLQ, ретраи, exactly-once-обработку через идемпотентность
Сильный seniorУчитывает hot partitions, ребалансировку, схему эволюции событий, backfill

Вопросы:

  1. Kafka vs RabbitMQ vs NATS — для каких задач каждый?

  2. Партиционирование: как выбрать ключ? Что произойдёт, если один ключ начнёт давать 50% трафика (hot partition)?

  3. Эволюция схемы событий: добавление поля, удаление, переименование. Как? (schema registry, обратная совместимость на 2 версии).

  4. Потребитель упал, обработав сообщение, но не закоммитив offset. Что произойдёт? Как защититься?

  5. DLQ: когда отправлять, как разбирать, кто отвечает?

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


2.6 Надёжность и операционная зрелость

Что проверяем: Системное мышление об операциях: SLO/SLI, observability, deploy-стратегии, incident response, on-call. Senior проектирует систему вместе с её эксплуатацией, а не отдельно от неё.

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

УровеньОжидания
Не прошёл«Передадим в эксплуатацию»
Проходной минимумЗнает про логи и метрики
Хороший seniorФормулирует SLO, проектирует observability, разбирал реальные инциденты
Сильный seniorПрименяет error budgets, проводит post-mortems, проектирует под graceful degradation и blast radius

Вопросы:

  1. Сформулируйте 3 ключевых SLI для вашей системы. Какие SLO? Что делать при превышении error budget?

  2. Observability: какие метрики, логи, трейсы вы соберёте на старте? Какие добавите после первого инцидента?

  3. Deploy-стратегии: rolling, blue-green, canary. Когда какая? Как откатиться?

  4. Кейс: 3 часа ночи, p99 latency вырос с 100мс до 5с. Ваши действия? (триаж, runbook, постановка бекапа, не «давайте сразу деплоить фикс»).

  5. Что такое blameless post-mortem? Зачем он?

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


2.7 Безопасность и compliance

Что проверяем: В дизайне сразу заложены аутентификация, авторизация, аудит, изоляция данных. Senior понимает compliance-ограничения (152-ФЗ, GDPR, PCI DSS, если применимо), даже если их реализуют не он.

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

УровеньОжидания
Не прошёл«За это отвечает другая команда»
Проходной минимумПонимает аутентификацию и авторизацию
Хороший seniorПроектирует с учётом RBAC/ABAC, аудита, изоляции tenant’ов
Сильный seniorПрименяет threat modeling, понимает 152-ФЗ/GDPR-ограничения, защищает по принципу defense in depth

Вопросы:

  1. Авторизация в мульти-тенантной системе: где проверка, как избежать «забыл проверить tenant_id»?

  2. Аудит: что логируем, как защищаем логи от изменения, сколько храним?

  3. Персональные данные: как хранить, как удалять (right to be forgotten), как анонимизировать для аналитики?

  4. Если один из ваших сервисов скомпрометирован, что получит атакующий? Как ограничить blast radius?

  5. Threat modeling: проведите для одной из подсистем. Что считаете рисками, что митигациями?

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


2.8 Эволюция и стоимость

Что проверяем: Система живёт годами: миграции, обратная совместимость, capacity planning, cost-aware design. Senior умеет оценить TCO решения и спланировать эволюцию — не только «сделать работающее на старте».

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

УровеньОжидания
Не прошёл«Главное чтобы запустилось»
Проходной минимумДумает про обратную совместимость API
Хороший seniorПланирует миграции, понимает стоимость инфраструктуры
Сильный seniorПроектирует под 10x роста, делал реальные миграции на проде, считает unit economics

Вопросы:

  1. Как мигрировать схему БД на 1 Тб без downtime? (expand-contract, обратная совместимость кода и схемы, фоновая миграция данных).

  2. Сейчас 1000 RPS, через год прогноз 10000. Что вы спроектируете иначе?

  3. Стоимость: сколько стоит ваша система в облаке в месяц? Где основные статьи (compute, storage, egress)? Где можно оптимизировать?

  4. Когда переписывание оправдано, а когда — это «второй системный синдром»? Стратегия рефакторинга legacy без остановки фич.

  5. Sunset плана: как закрыть сервис, который больше не нужен?

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


Что проверяем поверх двух этапов: лидерство

Эту тему я не выношу в отдельный этап: её сигналы проступают сквозь оба интервью и через несколько дополнительных вопросов в конце:

Senior, который силён технически, но не работает с людьми, на команду из 5+ человек не подойдёт. Он станет узким горлом: вместо того чтобы развивать команду, будет всё делать сам.

Итог

Senior Go-разработчик — это глубина в языке плюс широта в системном мышлении. Поэтому я делю собеседование на два этапа: технический (рантайм, конкурентность, производительность, экосистема) и архитектурный (требования, декомпозиция, хранилища, распределённые свойства, эксплуатация, стоимость). Между этапами сверяюсь с командой. Если технический прошёл с натяжкой, на архитектурный звать не стоит — без глубины в Go позицию не закрыть.

Главное на обоих этапах — слушать, как кандидат думает, а не только что отвечает. Задаёт ли уточняющие вопросы. Формулирует ли компромиссы. Ссылается ли на собственный опыт. Готов ли сказать «не знаю». Senior с честным «не знаю, но вот как бы я подходил» сильнее Senior с уверенным неправильным ответом.


Теги: