Как проверить указатель
Что проверяют
Судя по контексту, речь о Go: автоматизатор должен понимать, когда указатель равен nil, чем это грозит и как это правильно проверить в тесте. Следом почти всегда спрашивают про интерфейс, внутри которого лежит nil-указатель.
Как отвечать
Базовая проверка простая: if p != nil перед разыменованием. Разыменование nil даёт панику invalid memory address or nil pointer dereference, а паника в горутине без recover роняет весь процесс.
Дальше то, что отличает сильный ответ:
- типизированный nil в интерфейсе: если функция возвращает
error, а внутриvar e *MyErr = nil; return e, тоerr != nilбудетtrue. Интерфейс хранит тип и значение и считается пустым, только когда пусты оба; - testify:
assert.Nilпроверяет через рефлексию и такой интерфейс считает nil, хотя в кодеerr != nilсработает. Для ошибок надёжнееassert.NoError, он повторяет логику кода; - сравнение:
p1 == p2сравнивает адреса, а не значения.assert.Equalсравнивает значения, на которые указывают указатели, аassert.Sameпроверяет, что это один и тот же объект; - необязательные поля: в DTO поле
*intразличает «поле не пришло илиnull» и «пришёл ноль». Для тестировщика API это отдельные кейсы: отправить0,nullи не отправить поле вовсе; - статический анализ: staticcheck ловит часть возможных разыменований
nilправилом SA5011.
Если вопрос про C или C++, ответ меняется: проверка на NULL не спасает от висячего указателя, и нужны инструменты вроде AddressSanitizer.
Где спотыкаются
Отвечают «сравню с nil» и останавливаются. Интервьюер ждёт как раз ловушку с интерфейсом.
Сравнивают две структуры по указателям через == и получают false для одинаковых данных.
Не знают, что в Go до 1.22 переменная цикла range была одна на весь цикл, и &v в срезе указателей давал много ссылок на последний элемент. С 1.22 (для модулей с этой версией в go.mod) переменная своя на каждой итерации, но в старом коде ловушка осталась.