Что такое стек и куча в контексте памяти
Что проверяют
Не путаете ли вы место хранения с категорией типа. Для C# это главный водораздел: кандидат, уверенный что структуры всегда на стеке, а классы всегда в куче, ошибается на первом же нетривиальном случае, и вопрос обычно задают именно ради этого.
Как отвечать
Стек хранит кадры вызовов: параметры, локальные переменные и ссылки. Выделение и освобождение это сдвиг указателя, время жизни жёстко привязано к методу, размер ограничен и задаётся для потока. Куча хранит данные, которые должны пережить вызов. Память возвращает сборщик мусора по поколениям, а крупные объекты попадают в отдельную область, где возможна фрагментация.
Дальше главное правило: значимые типы хранятся там, где объявлены. Локальная структура лежит в кадре, поле-структура внутри класса лежит в куче вместе с объектом, элемент массива структур лежит в куче. Ссылочные типы всегда в куче, а переменная хранит ссылку на объект.
Отдельно назовите случаи, когда локальная переменная уезжает в кучу: захват замыканием, использование в итераторе или асинхронном методе, упаковка значимого типа в object или интерфейс. Компилятор строит объект состояния, и локальные становятся его полями.
Для тонкой работы со стеком есть stackalloc, Span<T> для доступа к такой памяти без копирования и ref struct для типов, которым в кучу попадать запрещено.
Где спотыкаются
Повторяют, что куча требует ручного управления. Память освобождает сборщик, руками управляют только неуправляемыми ресурсами через освобождающий интерфейс и конструкцию с автоматическим вызовом. Ручного освобождения памяти в этой среде нет вовсе.
Объявляют большую структуру ради скорости, раз уж она на стеке. Значимый тип копируется при каждой передаче, и на крупном размере копирование перевешивает выигрыш от отсутствия выделения. Порог измеряют, а не угадывают, и для больших данных берут класс или передачу по ссылке.
Не замечают упаковку. Присваивание структуры переменной интерфейсного типа, добавление в нетипизированную коллекцию, неудачно написанное сравнение создают объект в куче на каждой операции. В цикле получается ровный поток мусора, заметный только профилировщиком, а по коду он выглядит работой со значениями.