> Как запустить профилировщик в Go (Go)
Уровень: senior · Роль: backend · Категория: Технические вопросы
Компании: Wildberries
Стек: Go
> Пример ответа
Короткий ответ
Профилировщик в Go запускается через пакет runtime/pprof для приложений с явным жизненным циклом или через net/http/pprof для HTTP-сервисов. Основные профили - CPU, heap, goroutine, block, mutex. Для CPU-профиля нужно явно вызвать pprof.StartCPUProfile и pprof.StopCPUProfile, для heap - достаточно снять snapshot через pprof.Lookup("heap").WriteTo. Данные анализируются командой go tool pprof или визуально через go tool pprof -http.
Подробное объяснение
В Go профилирование встроено в рантайм. Есть два основных способа запуска:
- Императивный - используете
runtime/pprofнапрямую, когда сами контролируете жизненный цикл приложения (CLI-утилиты, batch-задачи, тесты). - HTTP-режим - подключаете
net/http/pprofкак blank import, и рантайм сам раздаёт профили по эндпоинтам/debug/pprof/. Это стандарт для long-running сервисов.
Ключевые профили:
- CPU - показывает, где процессорное время. Запускается на фиксированный интервал (обычно 30 секунд), семплирование по умолчанию 100 Hz.
- Heap - snapshot аллокаций в памяти. Показывает, сколько памяти удерживается и где она была выделена.
- Goroutine - стек-трейсы всех горутин. Полезен для поиска утечек горутин и deadlock-подобных состояний.
- Block - где горутины блокируются на каналах, мьютексах, sleep.
- Mutex - contention на мьютексах.
Важный момент: CPU-профиль требует явного StartCPUProfile и StopCPUProfile, потому что семплирование активно только между этими вызовами. Остальные профили - это snapshot, их можно снять в любой момент.
Для анализа используется go tool pprof. Он умеет работать с файлом профиля или напрямую с HTTP-эндпоинтом. Интерактивный режим даёт команды top, list, web. Современный режим -http открывает веб-интерфейс с flame graph и иерархическим деревом.
На практике
Для HTTP-сервиса достаточно добавить в main:
GOimport _ "net/http/pprof"
И убедиться, что у вас есть HTTP-сервер (обычно на отдельном порту, например :6060, чтобы не светить в production). После этого:
curl http://localhost:6060/debug/pprof/profile?seconds=30- снимет CPU-профиль за 30 секунд.curl http://localhost:6060/debug/pprof/heap- снимет heap snapshot.curl http://localhost:6060/debug/pprof/goroutine?debug=1- покажет все горутины текстом.
Для CLI-приложения:
GOf, _ := os.Create("cpu.prof")pprof.StartCPUProfile(f)defer pprof.StopCPUProfile()// ... основной код
Для тестов: go test -cpuprofile cpu.prof -memprofile mem.prof -bench . - это самый простой способ, не требует кода.
Анализ: go tool pprof -http :8081 cpu.prof - откроет браузер с интерактивным интерфейсом.
Пример кода
GOpackage mainimport ("net/http"_ "net/http/pprof""time")func main() {// pprof-эндпоинты будут доступны на :6060go func() {http.ListenAndServe("localhost:6060", nil)}()// основная логикаfor {time.Sleep(time.Second)}}
Императивный вариант для CLI:
GOpackage mainimport ("os""runtime/pprof")func main() {f, _ := os.Create("cpu.prof")pprof.StartCPUProfile(f)defer pprof.StopCPUProfile()// ваш код}
Как отвечать на собеседовании
Начните с двух способов запуска: runtime/pprof и net/http/pprof. Уточните, что для HTTP-сервисов стандарт - blank import. Затем перечислите основные типы профилей и их назначение. Обязательно упомяните, что CPU-профиль требует явного старта и остановки, а heap - snapshot. Покажите понимание анализа через go tool pprof, включая интерактивный режим и -http. Если спросят про production - скажите, что pprof-эндпоинты обычно не выставляют наружу, а слушают на localhost или внутреннем порту, и что есть библиотеки типа github.com/google/pprof для расширенного анализа.
Что проверяет интервьюер
- Понимание разницы между CPU и heap профилями.
- Знание, что CPU-профиль - это семплирование, а не трассировка.
- Умение выбрать правильный инструмент для конкретной проблемы (утечка памяти vs высокая нагрузка на CPU).
- Понимание, как профилировать в production без деградации (снижение частоты семплирования, отдельный порт).
- Знание
go tool pprofи его возможностей (top, list, web, -http).
Типичные ошибки
- Забывают остановить CPU-профиль - файл остаётся пустым или битым.
- Снимают CPU-профиль слишком короткое время (меньше 5-10 секунд) - статистика недостоверна.
- Пытаются профилировать heap через
StartCPUProfile- это не работает, heap снимается отдельно. - Не используют
-httpрежим и пытаются анализировать профиль текстом, что неэффективно для больших данных. - В production оставляют pprof-эндпоинты открытыми на публичном порту - это утечка информации и DoS-вектор.
- Путают
goroutineпрофиль сthreadпрофилем - в Go горутины не равны потокам ОС.
> Похожие задачи по backend
Писали ли интеграционные тесты или моки для сервисов с Dependency Injection
Что лучше использовать в Go: int8, int32, int64 или просто int
Какая команда помогает понять, что происходит при запросе к базе данных для поиска узких мест по производительности
Сколько потоков запускается в runtime приложении Go по умолчанию
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью