> Что происходит при выполнении функции 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 с мьютексами или структурированное логирование.

Пример кода

GO
package main
import "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 добавляет пробелы между аргументами и перевод строки в конце.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью