---
title: Runtime
seo:
  title: Runtime — Go Developer
  description: Тема «Runtime» для собеседования Go Developer. Как устроен планировщик горутин в Go runtime? Что такое горутина (goroutine)?
---

[Все темы Go Developer](/go-developer)

## Как устроен планировщик горутин в Go runtime? [#q-14bee738d69b817a8334ff34bee68037]

<strong>Планировщик (</strong>
<code>Scheduler</code>
<strong>)</strong> в Go — это часть среды выполнения (<code>runtime</code>),
которая управляет выполнением горутин, распределяя их на потоки ОС.

#### Основные характеристики&#58;

{/* prettier-ignore */}
1. <strong>Модель планировщика</strong>&#58;

    - Go использует модель M&#58;N, где M горутин выполняются на N потоках ОС.

    - Позволяет эффективно использовать системные ресурсы, выполняя множество горутин на ограниченном количестве потоков.

1. <strong>Компоненты</strong>&#58;

    - <strong>Goroutine (G)</strong>&#58; Легковесная единица выполнения, представляющая собой функцию, запускаемую параллельно.

    - <strong>Processor (P)</strong>&#58; Логический процессор, который выполняет горутины, управляет очередью готовых к выполнению горутин.

    - <strong>Machine (M)</strong>&#58; Операционный системный поток, который выполняет горутины.

1. <strong>Работа планировщика</strong>&#58;

    - <strong>Создание</strong>&#58; Новая горутина создается и помещается в очередь готовых горутин.

    - <strong>Выбор</strong>&#58; Логический процессор (P) выбирает горутину из своей очереди для выполнения.

    - <strong>Исполнение</strong>&#58; Поток ОС (M) выполняет выбранную горутину.

    - <strong>Блокировка</strong>&#58; Если горутина блокируется, поток ОС (M) может взять другую горутину из очереди.

#### Пример&#58;

```go
package main

import (
    "fmt"
    "runtime"
    "time"
)

func main() {
    runtime.GOMAXPROCS(2) // Установка числа логических процессоров

    go func() {
        for i := 0; i < 5; i++ {
            fmt.Println("Goroutine 1:", i)
            time.Sleep(100 * time.Millisecond)
        }
    }()

    go func() {
        for i := 0; i < 5; i++ {
            fmt.Println("Goroutine 2:", i)
            time.Sleep(100 * time.Millisecond)
        }
    }()

    time.Sleep(1 * time.Second)
}
```

Планировщик в Go обеспечивает эффективное выполнение множества горутин на ограниченном количестве потоков ОС, используя модель M&#58;N и логические процессоры для управления очередями горутин.

:::note[Ссылки для изучения]

1. [Runtime в Go](https://habr.com/ru/companies/timeweb/articles/589167/)
   :::

---

## Что такое горутина (goroutine)? [#q-14bee738d69b811f95f1ece5b262e4e9]

<strong>Горутина</strong> — это легковесная единица выполнения, аналогичная
потоку, но гораздо более дешёвая в создании и управлении.

#### Основные характеристики&#58;

{/* prettier-ignore */}
1. <strong>Легковесность</strong>&#58;

    - Горутины имеют меньший накладной расход по сравнению с потоками ОС, позволяя создавать тысячи горутин одновременно.

1. <strong>Создание</strong>&#58;

    - Горутина создается с помощью ключевого слова <code>go</code>, перед которым указывается вызов функции.

    - Пример&#58;

        ```go
        go func() {
            fmt.Println("Hello from goroutine")
        }()
        ```

1. <strong>Параллелизм и конкурентность</strong>&#58;

    - Горутины могут выполняться параллельно на нескольких процессорах или конкурентно на одном.

#### Пример&#58;

```go
package main

import (
    "fmt"
    "time"
)

func main() {
    go func() {
        fmt.Println("Hello from goroutine")
    }()
    time.Sleep(1 * time.Second)  // Даем время горутине завершить выполнение
    fmt.Println("Hello from main")
}
```

:::note[Ссылки для изучения]

1. [Runtime в Go](https://habr.com/ru/companies/timeweb/articles/589167/)
   :::

---

## <strong>В чем отличие горутины от потока?</strong> [#q-14bee738d69b8158ae4ff70b5ec377ad]

Отличие горутины от потока&#58;

{/* prettier-ignore */}
1. <strong>Легковесность</strong>&#58;

    - <strong>Горутины</strong>&#58; Горутины потребляют меньше ресурсов и быстрее создаются.

    - <strong>Потоки</strong>&#58; Потоки ОС тяжелее, требуют больше памяти и времени на создание и переключение.

1. <strong>Управление</strong>&#58;

    - <strong>Горутины</strong>&#58; Управляются планировщиком Go на уровне пользовательского пространства.

    - <strong>Потоки</strong>&#58; Управляются ядром операционной системы.

1. <strong>Модель выполнения</strong>&#58;

    - <strong>Горутины</strong>&#58; Используют модель M&#58;N, где множество горутин выполняются на ограниченном числе потоков ОС.

    - <strong>Потоки</strong>&#58; Каждый поток ОС является отдельной единицей выполнения на уровне ядра.

1. <strong>Память</strong>&#58;

    - <strong>Горутины</strong>&#58; Начальный стек горутины очень мал (~2 KB) и может динамически расти.

    - <strong>Потоки</strong>&#58; Начальный стек потока ОС значительно больше (обычно несколько МБ).

:::note[Ссылки для изучения]

1. [Runtime в Go](https://habr.com/ru/companies/timeweb/articles/589167/)
   :::

---

## <strong>Как устроены горутины, сколько памяти они занимают в стеке?</strong> [#q-14bee738d69b81978b0bd3c131f5f07f]

<strong>Горутины</strong> — легковесные единицы выполнения, управляемые
планировщиком Go.

#### Основные характеристики&#58;

{/* prettier-ignore */}
1. <strong>Легковесность</strong>&#58;

    - Горутины потребляют меньше ресурсов по сравнению с потоками ОС.

1. <strong>Память</strong>&#58;

    - <strong>Начальный стек</strong>&#58; Горутины начинаются с очень малого начального стека, примерно 2 KB.

    - <strong>Динамическое расширение</strong>&#58; Стек горутины может динамически расти и уменьшаться по мере необходимости.

1. <strong>Планировщик</strong>&#58;

    - Планировщик Go использует модель M&#58;N, где множество горутин (M) выполняются на ограниченном числе потоков ОС (N).

#### Пример&#58;

```go
package main

import (
    "fmt"
    "time"
)

func main() {
    go func() {
        fmt.Println("Hello from goroutine")
    }()
    time.Sleep(1 * time.Second)
    fmt.Println("Hello from main")
}
```

Горутины в Go занимают около 2 KB начального стека и могут динамически расширяться, что делает их легковесными и эффективными для выполнения параллельных задач.

:::note[Ссылки для изучения]

1. [Runtime в Go](https://habr.com/ru/companies/timeweb/articles/589167/)
   :::

---

## Как планировщик Go управляет горутинами и вытесняет их? [#q-14bee738d69b81c38048dae132a0625f]

Управление горутинами в Go&#58;

{/* prettier-ignore */}
- <strong>Планировщик Go (</strong><code>Scheduler</code><strong>)</strong>&#58; Управляет выполнением горутин.

- <strong>Тип многозадачности</strong>&#58;

    - До Go 1.14 вытеснение в основном зависело от безопасных точек, например проверок при вызове функций.

    - В Go 1.14 добавлено асинхронное вытеснение горутин на поддерживаемых платформах, в том числе циклов без вызовов функций.

:::note[Ссылки для изучения]

1. [Runtime в Go](https://habr.com/ru/companies/timeweb/articles/589167/)
   :::

---

## Что такое сборщик мусора (GC)? [#q-14bee738d69b81d9aaeacde676a440a6]

Сборщик мусора освобождает память недостижимых объектов. Если программа сохраняет ненужные ссылки, GC не устранит такую утечку; освобождение файлов и соединений тоже требует явного управления ресурсами.

#### Основные характеристики&#58;

{/* prettier-ignore */}
1. <strong>Автоматическое управление памятью</strong>&#58;

    - Освобождает память объектов, недостижимых от корней графа ссылок.

1. <strong>Периодическая работа</strong>&#58;

    - Запускается периодически во время выполнения программы.

1. <strong>Минимизация пауз</strong>&#58;

    - Стремится минимизировать паузы в работе приложения для улучшения производительности.

:::note[Ссылки для изучения]

1. [Runtime в Go](https://habr.com/ru/companies/timeweb/articles/589167/)
   :::

---

## <strong>Как работает сборщик мусора в Go?</strong> [#q-14bee738d69b8100bdabf7cd590cf6b6]

Как работает сборщик мусора в Go&#58;

{/* prettier-ignore */}
1. <strong>Трассировка</strong>&#58;

    - <strong>Mark Phase</strong>&#58; Определяет все достижимые объекты, начиная с корневых ссылок (стек, глобальные переменные).

    - <strong>Sweep Phase</strong>&#58; Освобождает память, занятую недостижимыми объектами.

1. <strong>Преэмптивная многозадачность</strong>&#58;

    - В Go 1.5 появился конкурентный сборщик мусора. Это изменение GC, а не версия введения асинхронного вытеснения горутин (Go 1.14).

1. <strong>Постепенная (Incremental) работа</strong>&#58;

    - Разделяет работу на маленькие части, чтобы избежать длительных пауз в работе приложения.

1. <strong>Конкурентная работа</strong>&#58;

    - Сборщик мусора работает одновременно с приложением, минимизируя время пауз и обеспечивая плавную работу.

Сборщик мусора в Go работает путем трассировки и освобождения памяти, используя конкурентные и постепенные методы для минимизации пауз и обеспечения высокой производительности.

:::note[Ссылки для изучения]

1. [Runtime в Go](https://habr.com/ru/companies/timeweb/articles/589167/)
   :::
