Golang "Что выведет код?" задачи для собеседования.
Проходя собеседование на позицию Golang разработчика мы часто сталкиваемся с задачами по типу “что выведет код на экране?”. Цель подобных задач – определить насколько хорошо кандидат понимает синтаксис своего языка и основы работы с базовыми типами и функциями. Ниже я набросал несколько, которые чаще всего попадались мне на собеседованиях. Эти задачи затрагивают темы: slice, map, struct, goroutine и их синхронизации. Так же в конце я добавил одно бонусное задание, которое давали мне на собеседование в один небезызвестный маркетплейс.
Что выведет данный код?
1. Слайсы – определение, аллокации и указатели.
Ответ:
[9 8 3] [1 2] 8
2. Map – определение, перебор.
Ответ:
[9 2 7]
[9 4 7]
3. Struct – встраивание и receiver method.
Ответ:
child
4. Goroutine – гонка данных.
Ответ:
Код не имеет детерминированного результата, это data race, поэтому программа может зависнуть навсегда или напечатать finished.
5. Goroutine – deadlock?
Ответ:
Вывод у этой программы никогда не дойдёт до done. Она зависнет после получения первого значения и дальше будет печатать точки.
6. Goroutine – интересное поведение.
Ответ:
У данного кода существует 3 варианта поведения:
1. программа выведет только done;
2. программа успеет вывести от одной до трех цифр в случайном порядке;
3. программа завершится с паникой sync: WaitGroup misuse: Add called concurrently with Wait. Из за того что Add(1) находится внутри горутины а Wait() вызывается снаружи сразу после запуска эти функции могут выполняться параллельно.
Бонус
Дополнительная задача о которой упоминал вначале. К “что выведет” она не относится, но я все равно решил включить её в статью, потому что она интересная и мне встречалась в части секции с устными задачами. Суть задачи – проверить, понимает ли кандидат интерфейсы в Go.
Надо реализовать функцию getError, которая выбрасывает ошибку без сторонних импортов (в тч. без пакета fmt).
Решение:
Пояснение:
error – это интерфейс
У error внутри две части:
- тип (dynamic type);
- значение (dynamic value).
Интерфейс считается nil только если обе части nil: нет типа и нет значения.
Что возвращает getError.
e – это nil-указатель типа *myErr.
Когда программа возвращает e как error, Go упаковывает это в интерфейс:
dynamic type = *myErr (НЕ nil)
dynamic value = nil
То есть интерфейс не nil, потому что у него есть тип.
Надеюсь мне удалось подкинуть интересных задач программисту который готовится к собеседованию. Подробно пояснять поведение кода я не стал чтобы не перегружать статью, но если для вас не очевиден вывод представленных программ, то настоятельно рекомендую устранить непонимание, дабы избежать казусов на собеседовании и в работе.
Спасибо за внимание!