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 (результат воспроизводим и объяснён). Если обязательный сценарий не работает, вернитесь к нему независимо от общей суммы. Это рубрика самопроверки: сайт не исполняет присланный код и не выдаёт автоматическую оценку проекта.