Вопросы на собеседовании Go junior
Как устроены срезы и мапы, чем интерфейсы Go отличаются от привычных, почему ошибки — это значения, как работают горутины, каналы, select и context — то, о чём спрашивают начинающих Go-разработчиков.
- 01Что такое any, type assertion и type switch?
any (= interface{}) — интерфейс без методов, ему удовлетворяет любой тип. Достать конкретный тип — type assertion v, ok := x.(string) (без ok при несовпадении — panic) или type…
Junior - 02Почему изменение одного среза неожиданно меняет другой?
Срезы, полученные друг из друга, делят базовый массив, пока append не перевыделил его. Если у исходного среза есть свободная ёмкость, append к подсрезу перезапишет элементы…
Junior - 03Чем массив отличается от среза в Go?
Массив [5]int — значение фиксированного размера, размер — часть типа ([3]int и [4]int — разные типы); присваивание и передача копируют все элементы. Срез []int — дескриптор над…
Junior - 04Чем буферизованный канал отличается от небуферизованного и что происходит при закрытии канала?
Небуферизованный канал — отправка блокируется, пока получатель не заберёт значение: синхронная встреча. Буферизованный (make(chan T, n)) — отправка блокируется только при полном…
Junior - 05Зачем нужен context.Context?
Context переносит отмену, дедлайн и значения запроса через цепочку вызовов и горутин. Создают от входящего запроса, передают первым аргументом во все функции с вводом-выводом…
Junior - 06Как работает defer и в каком порядке выполняются отложенные вызовы?
defer откладывает вызов до выхода из функции — при обычном return и при panic. Отложенные вызовы выполняются в порядке LIFO (последний — первым). Аргументы вычисляются сразу в…
Junior - 07Как в Go обрабатывают ошибки и зачем нужны errors.Is, errors.As и %w?
Ошибка — обычное значение типа error, которое функция возвращает последним: if err != nil { return ... }. Оборачивают с контекстом через fmt.Errorf("...: %w", err). Проверяют…
Junior - 08Как в Go устроены сборка мусора и размещение на стеке или в куче?
GC в Go — конкурентный mark-and-sweep без поколений и без перемещения объектов, с паузами в доли миллисекунды. Где разместить значение, решает escape analysis компилятора: не…
Middle - 09Как устроены дженерики в Go и когда их использовать?
С Go 1.18 функции и типы принимают параметры типов с ограничениями — интерфейсами, которые могут перечислять допустимые типы: func Max[T cmp.Ordered](a, b T) T. Применение …
Middle - 10Как создавать свои ошибки в Go — сигнальные ошибки и типы ошибок?
Сигнальная ошибка — переменная пакета var ErrNotFound = errors.New("not found"): вызывающий проверяет её через errors.Is. Тип ошибки — структура с методом Error() string, когда…
Junior - 11Как настроить таймауты и корректную остановку HTTP-сервера в Go?
http.ListenAndServe по умолчанию без таймаутов: медленные клиенты держат соединения и горутины бесконечно. Нужен свой http.Server с ReadHeaderTimeout, ReadTimeout, WriteTimeout…
Middle - 12Как написать HTTP-сервис на стандартной библиотеке Go?
Обработчик — всё, что реализует http.Handler (метод ServeHTTP(w, r)), чаще — функция func(w http.ResponseWriter, r http.Request). Маршруты регистрируют в http.ServeMux; с Go 1.22…
Junior - 13Как найти, что тормозит или ест память в Go-сервисе, — pprof?
pprof — встроенный профилировщик. В сервис подключают import _ "net/http/pprof" (на внутреннем порту), затем go tool pprof http://host:6060/debug/pprof/profile?seconds=30 …
Middle - 14Что такое утечка горутин и как её избежать?
Горутина, навсегда заблокированная на канале, мьютексе или вводе-выводе, никогда не завершится и держит стек и всё, на что ссылается. Типичные причины: отправка в канал, который…
Middle - 15Что такое горутина и чем она отличается от потока ОС?
Горутина — лёгкий поток, управляемый рантаймом Go: стартовый стек ~2 КБ (растёт по необходимости), создание и переключение в разы дешевле потока ОС — можно держать сотни тысяч…
Junior - 16Как работают интерфейсы в Go и что значит неявная реализация?
Тип удовлетворяет интерфейсу автоматически, если у него есть все методы интерфейса — без слова implements. Поэтому интерфейсы объявляют у потребителя и делают маленькими…
Junior - 17Что изменилось с переменной цикла в Go 1.22?
До Go 1.22 переменная цикла for i := ... была одна на весь цикл: замыкания и горутины, захватившие её, видели последнее значение. С Go 1.22 каждая итерация получает свою копию …
Junior - 18Чем make отличается от new в Go?
new(T) выделяет нулевое значение любого типа и возвращает указатель T. make — только для срезов, мап и каналов: инициализирует их внутреннюю структуру и возвращает само значение…
Junior - 19Как устроена map в Go и какие у неё особенности?
map — хеш-таблица: вставка, поиск и удаление в среднем O(1). Порядок обхода случаен и намеренно перемешивается от запуска к запуску. Конкурентная запись из нескольких горутин …
Junior - 20Как устроены модули Go — go.mod, go.sum, версии?
go.mod объявляет путь модуля, версию Go и зависимости с версиями (семантическое версионирование). go.sum хранит хеши — гарантия, что скачан тот же код. Версии выбирает MVS…
Junior - 21Когда использовать каналы, а когда sync.Mutex и WaitGroup?
Каналы — для передачи данных и владения ими между горутинами (конвейеры, очереди задач). Mutex — для защиты общего состояния (кэш, счётчик). WaitGroup — дождаться группы горутин…
Junior - 22Почему интерфейс с nil-указателем внутри не равен nil?
Интерфейсное значение — пара (тип, значение). Оно равно nil, только когда обе части nil. Если положить в интерфейс nil-указатель конкретного типа, тип уже заполнен — интерфейс не…
Middle - 23Чем nil-срез отличается от пустого и почему запись в nil-map вызывает panic?
nil-срез (var s []int) и пустой ([]int{}) оба имеют len 0, с обоими работают range и append. Различие — только s == nil и JSON: nil кодируется как null, пустой — как []. nil-map…
Junior - 24Когда в Go используют panic и как работает recover?
panic — для невозможных ситуаций и ошибок программиста (выход за границы, nil-указатель, нарушенный инвариант), а не для ожидаемых ошибок. Panic раскручивает стек, выполняя defer…
Junior - 25Как в Go передаются аргументы и зачем нужны указатели?
Всё передаётся по значению — копируется само значение: структура целиком, массив целиком. Чтобы функция изменила объект вызывающего, передают указатель (T, взять адрес — &x)…
Junior - 26Что такое гонка данных в Go и как её найти?
Гонка данных — две горутины обращаются к одной переменной одновременно, и хотя бы одна пишет, без синхронизации. Результат непредсказуем, а для мап и срезов возможна порча…
Junior - 27Как работает select в Go?
select ждёт сразу несколько операций с каналами и выполняет ту, что готова первой; если готовы несколько — случайную. Ветка default делает select неблокирующим. Таймаут — ветка…
Junior - 28Чем := отличается от var и что такое затенение переменных?
:= — короткое объявление с выводом типа, только внутри функций; объявляет хотя бы одну новую переменную слева. var — работает и на уровне пакета, позволяет указать тип без…
Junior - 29Как устроен срез (slice) в Go?
Срез — дескриптор из трёх полей: указатель на базовый массив, длина (len — сколько элементов доступно) и ёмкость (cap — сколько поместится до конца массива). append пишет в тот же…
Junior - 30Как в Go устроены строки, байты и руны?
Строка — неизменяемая последовательность байт, обычно в UTF-8. len возвращает число байт, а не символов: кириллица занимает 2 байта, поэтому len("привет") == 12. Руна (rune =…
Junior - 31Как в Go обходятся без наследования — что такое встраивание (embedding)?
Наследования нет. Встраивание — поле без имени: методы и поля встроенного типа продвигаются во внешний и вызываются напрямую. Это композиция, а не наследование: нет…
Junior - 32Как пишут тесты в Go — табличные тесты, моки, бенчмарки?
Тесты — функции TestXxx(t testing.T) в файлах _test.go, запуск go test ./.... Идиома — табличные тесты: срез случаев и t.Run для каждого. Зависимости подменяют через маленькие…
Junior - 33Когда метод должен иметь получатель-указатель, а когда — значение?
Указатель func (s Svc) — если метод меняет получателя, структура большая или содержит то, что нельзя копировать (sync.Mutex). Значение func (p Point) — для маленьких неизменяемых…
Junior - 34Чем Go отличается от других языков и почему его выбирают для бэкенда?
Go — компилируемый статически типизированный язык с простым синтаксисом, сборщиком мусора и встроенной конкурентностью (горутины и каналы). Компилируется в один статический…
Junior - 35Что такое нулевые значения в Go?
Любая переменная без явной инициализации получает нулевое значение своего типа: 0 для чисел, "" для строк, false для bool, nil для указателей, срезов, мап, каналов, функций и…
Junior
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.