Какие способы отладки кода используются?
Что проверяют
Какой у вас набор инструментов кроме fmt.Println и умеете ли вы выбрать нужный под тип бага: логика, гонка, утечка горутин, зависание в проде. Следом часто спрашивают, как отлаживать сервис, который уже крутится в контейнере.
Как отвечать
- Delve:
dlv debug,dlv testдля отдельного теста,dlv attachк работающему процессу,dlv coreдля дампа. В контейнере запуск в headless-режиме с--listen=:2345и подключение из GoLand или VS Code. Собирать с-gcflags="all=-N -l", иначе оптимизации и инлайнинг прячут переменные; - детектор гонок:
go test -raceиgo run -race. Ловит гонки только на тех путях, которые реально выполнились, и заметно замедляет программу, поэтому живёт в CI, а не в проде; - дамп горутин:
SIGQUITпечатает стеки всех горутин, в сервисе удобнееnet/http/pprofи/debug/pprof/goroutine?debug=2. Так ищут дедлоки и горутины, навсегда повисшие на канале; - профилирование:
pprofдля CPU, памяти и блокировок,go tool traceдля планировщика и задержек; - логи:
log/slogиз стандартной библиотеки (с Go 1.21) с уровнями, JSON-выводом и полями вродеrequest_id. У старого пакетаlogуровней нет; - тесты как инструмент отладки: воспроизвести баг табличным тестом, запускать
go test -run TestName -count=1 -v, для граничных входов фаззинг черезgo test -fuzz; - статический анализ:
go vet,staticcheck, агрегаторgolangci-lint.
В проде к этому добавляется трассировка через OpenTelemetry: она показывает, в каком сервисе и на каком вызове потерялось время.
Где спотыкаются
Отлаживают оптимизированный бинарник и удивляются, что Delve пишет «optimized away» вместо значения переменной и прыгает по строкам не по порядку.
Ищут гонку через Println. Вывод меняет тайминги, и баг прячется, а -race находит его за один прогон теста. Обратная ошибка: считать, что зелёный прогон с -race доказывает отсутствие гонок.
Называют golint основным линтером. Он давно заброшен и помечен устаревшим, его место заняли staticcheck и golangci-lint.