Где в памяти располагаются локальные переменные: стек или куча
Что проверяют
Для QA-автоматизатора этот вопрос не про теорию компиляторов, а про то, понимаете ли вы, откуда берутся утечки памяти и переполнение стека, которые вы ловите в тестах. Если автотесты пишутся на Go, следом спросят про escape analysis и про то, как посмотреть аллокации.
Как отвечать
Правильный ответ: зависит от языка. Дальше конкретика:
- Go: место выбирает компилятор с помощью escape analysis. Если переменная не переживает функцию, она живёт на стеке горутины. Если на неё возвращают указатель, её захватывает замыкание, её кладут в интерфейс или размер неизвестен при компиляции, она уходит в кучу, и потом её освобождает GC. Вернуть указатель на локальную переменную в Go законно;
- Java: локальные примитивы и ссылки лежат в кадре стека, а сами объекты в куче. JIT может убрать аллокацию объекта, который не выходит за метод, но это оптимизация, а не правило;
- Python: все объекты в куче, в кадре функции только имена, которые на них ссылаются.
Про стек в Go полезно знать, что у горутины он стартует с нескольких килобайт и растёт по мере нужды, а на 64-битных системах по умолчанию ограничен 1 ГБ. Бесконечная рекурсия заканчивается ошибкой goroutine stack exceeds ... limit.
Как это пригодится в тестировании:
go build -gcflags=-m: печатает решения компилятора, строки «moved to heap» и «escapes to heap»;- бенчмарки:
go test -bench . -benchmemпоказываетallocs/op, и рост этой цифры между версиями хороший повод завести баг; - pprof: профиль кучи через
/debug/pprof/heapпомогает найти утечку на нагрузочном прогоне.
Где спотыкаются
Отвечают «локальные переменные всегда на стеке». Для Go это неверно, и интервьюер сразу попросит разобрать пример с возвратом указателя.
Считают, что указатель означает кучу. Указатель на переменную, которая не покидает функцию, спокойно остаётся на стеке.
Путают переполнение стека с нехваткой памяти в куче. Первое почти всегда рекурсия без выхода, второе это утечка или слишком большие данные, и искать причину нужно в разных местах.