IT Academy
Справочник курса

Go для сетевых сервисов

Все объяснения, задачи и лабораторная в одном месте.

Можно сохранить страницу в PDF через печать браузера. Для печати разборы ответов раскрываются автоматически.

1. Пакеты, интерфейсы и обработка ошибок

Объяснение

Интерфейс Go описывает методы и реализуется неявно. Ошибка — значение, которое вызывающий код должен обработать. Оборачивание ошибки сохраняет контекст, а errors.Is позволяет проверить исходную причину.

Задача для самостоятельного решения

Почему сравнение текста ошибки ненадёжно?

Показать разбор ответа

Сообщение меняется при добавлении контекста. Используйте sentinel, тип ошибки или errors.Is/As, а текст оставляйте для диагностики человека.

2. Slices, maps и управление памятью

Объяснение

Slice содержит указатель, длину и ёмкость. Несколько slices могут разделять массив. append при нехватке ёмкости создаёт новое хранилище, поэтому совместное владение может измениться после добавления.

Задача для самостоятельного решения

Почему изменение b[0] меняет a[0], если b=a[:2]?

Показать разбор ответа

Оба среза указывают на один массив. Для независимой копии выделите новый slice и выполните copy; присваивание заголовка slice данные не копирует.

3. Goroutines, channels и context

Объяснение

Goroutine не завершится автоматически вместе с HTTP-запросом. Context передаёт отмену и deadline. Отправка в канал блокируется, если нет получателя или свободного буфера.

Задача для самостоятельного решения

Как не оставить worker навсегда на отправке результата?

Показать разбор ответа

Выполнить select между отправкой и ctx.Done(). Владелец жизненного цикла также должен отменять context и дожидаться завершения workers.

4. HTTP, middleware и gRPC

Объяснение

HTTP-handler должен ограничивать размер входа, проверять метод и возвращать определённые статусы. Тело ответа и соединения требуют закрытия. Timeout клиента должен учитывать весь сценарий запроса.

Задача для самостоятельного решения

Почему бесконечный HTTP timeout опасен?

Показать разбор ответа

Недоступный upstream удерживает goroutine и соединение. Установите deadline, ограничьте конкуренцию и проверяйте отмену при обращении к зависимостям.

5. Тесты, race detector и benchmarks

Объяснение

Table-driven тесты перечисляют входы и ожидаемые результаты. Race detector обнаруживает гонки только на реально выполненных путях. Бенчмарк должен учитывать выделения памяти, а не только наносекунды.

Задача для самостоятельного решения

Тест с race detector прошёл. Доказана ли потокобезопасность?

Показать разбор ответа

Нет: проверена конкретная история исполнения. Нужны конкурентные сценарии и анализ синхронизации; отсутствие отчёта — полезное наблюдение, не доказательство.

6. Профилирование, сборка и эксплуатация

Объяснение

Graceful shutdown прекращает приём новых запросов и даёт текущим ограниченное время завершиться. Профиль CPU показывает активные вычисления, heap — удержание или выделение памяти в зависимости от вида профиля.

Задача для самостоятельного решения

В каком порядке останавливать HTTP и БД?

Показать разбор ответа

Сначала снять readiness и остановить приём HTTP, дождаться текущих запросов с deadline, затем закрыть БД. Закрытие БД первым ломает ещё работающие запросы.

Практика

Лабораторная работа

Подготовка

Go. Сохраните main.go и выполните go run main.go.

Учебный пример

package main
import "fmt"
func sum(values []int) int {
    total := 0
    for _, value := range values { total += value }
    return total
}
func main() {
    values := []int{1,2,3}
    fmt.Println(sum(values))
}

Как работает пример и что ожидать

Вывод 6. Range возвращает индекс и значение; подчёркивание игнорирует индекс. Функция не изменяет slice. Однако отсутствие изменения в этой реализации — свойство кода, а не автоматическая глубокая неизменяемость slices.

Итоговая работа

Создайте HTTP API с context deadlines, обработкой ошибок и graceful shutdown. Добавьте table-driven тесты, конкурентный сценарий для race detector и benchmark. Докажите, что отменённый запрос не оставляет goroutine.

Проверка результата

1. Опишите исходные данные и условия запуска, чтобы другой человек мог повторить работу.
2. Приложите результат обычного сценария и сравните его с ожидаемым.
3. Проверьте неверный вход, граничный случай и отказ зависимости, если она есть.
4. Объясните выбранное решение и известное ограничение.
5. Сохраните исправления после самопроверки вместе с примером, который раньше не работал.

Как оценить работу

По каждому пункту поставьте 0 (не выполнено), 1 (выполнено с пробелами) или 2 (результат воспроизводим и объяснён). Если обязательный сценарий не работает, вернитесь к нему независимо от общей суммы. Это рубрика самопроверки: сайт не исполняет присланный код и не выдаёт автоматическую оценку проекта.