> Что происходит при выполнении функции main с набором принтов и что выводится в консоли (Go)
Уровень: middle · Роль: backend · Категория: Технические вопросы
Компании: Яндекс
Стек: Go
> Пример ответа
Короткий ответ
При выполнении main с набором принтов Go выполняет код последовательно сверху вниз, если нет горутин или отложенных вызовов. Каждый fmt.Println выводит переданные аргументы в стандартный поток вывода, добавляя перевод строки. Порядок вывода строго соответствует порядку вызовов в коде. Если используются defer, вывод отложенных вызовов происходит после завершения main, в обратном порядке их объявления.
Подробное объяснение
Функция main - точка входа в Go-программе. Выполнение идёт синхронно: каждый принт блокирует выполнение до завершения записи в stdout. fmt.Println форматирует аргументы с пробелами между ними и добавляет \n в конец. Если аргументы - разные типы, они приводятся к строковому представлению через fmt.Sprint.
При наличии defer вызовы помещаются в стек и выполняются после всех остальных операций в main, но до возврата из функции. Порядок выполнения отложенных вызовов - LIFO (последний объявленный выполняется первым).
Если в main запускаются горутины, порядок вывода становится недетерминированным: планировщик Go решает, когда переключать контекст. Без синхронизации (например, sync.WaitGroup или каналов) вывод горутин может перемешиваться с выводом main или вообще не успеть выполниться до завершения программы.
На практике
Для предсказуемого вывода в конкурентном коде используйте синхронизацию. Для простых программ порядок принтов очевиден. Важно помнить: fmt.Println не гарантирует атомарность при параллельной записи из нескольких горутин - строки могут перемешиваться. Для логов в production используйте log с мьютексами или структурированное логирование.
Пример кода
GOpackage mainimport "fmt"func main() {fmt.Println("первый")defer fmt.Println("отложенный 1")defer fmt.Println("отложенный 2")fmt.Println("второй")}
Вывод:
первый второй отложенный 2 отложенный 1
Как отвечать на собеседовании
Начните с базового: последовательное выполнение, порядок вывода совпадает с порядком вызовов. Затем упомяните defer и LIFO-порядок. Если в вопросе есть намёк на горутины, объясните недетерминизм и необходимость синхронизации. Приведите пример с defer, чтобы показать понимание. Не углубляйтесь в детали реализации fmt - достаточно знать про буферизацию и перевод строки.
Что проверяет интервьюер
Проверяется понимание модели выполнения Go: синхронность по умолчанию, механизм defer, особенности конкурентного вывода. Также оценивается умение предсказывать поведение программы без запуска. Для middle-уровня важно показать знание планировщика и проблем гонок при выводе из нескольких горутин.
Типичные ошибки
- Утверждение, что
deferвыполняется в порядке объявления - на самом деле в обратном. - Игнорирование того, что горутины могут не завершиться до выхода из
main. - Ожидание атомарности
fmt.Printlnпри параллельном выводе - на самом деле возможны перемешивания. - Забывание, что
fmt.Printlnдобавляет пробелы между аргументами и перевод строки в конце.
> Похожие задачи по backend
Как запустить две задачи параллельно и дождаться их результата
Вычистит ли сборщик мусора объекты, если они ссылаются друг на друга, но не имеют ссылок из корня
Что может выступать корневым элементом для сборщика мусора
Что такое Dependency Injection (DI)
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью