22 вопросов
Богатая стандартная библиотека Go: net/http для веб-серверов, encoding/json для JSON, fmt для форматирования, io для потоков, time для работы с временем.
net/http - мощный пакет для HTTP-клиента и сервера. http.ListenAndServe(":8080", handler) запускает сервер. Многие Go-фреймворки (gin, chi, echo) построены поверх net/http.
Подробнее →encoding/json - пакет для сериализации (Marshal) и десериализации (Unmarshal) JSON. Работает через рефлексию и теги структур (json:"name").
Подробнее →json.Marshal(v)? 🟢 Лёгкий
▶
json.Marshal принимает любое значение и возвращает ([]byte, error) - JSON-представление. Экспортированные поля структур попадают в JSON, приватные - нет.
Подробнее →fmt - форматированный ввод/вывод. Println, Printf, Sprintf, Fprintf. Поддерживает глаголы: %v (значение), %T (тип), %d (число), %s (строка).
Подробнее →Пакет time предоставляет Time, Duration, Timer, Ticker. time.Now(), time.Since(), time.Sleep(). Формат даты: t.Format("2006-01-02") - Go использует эталонную дату.
Подробнее →log/slog - стандартный пакет для структурированного логирования. slog.Info("запрос", "method", "GET", "path", "/api") выводит ключ-значение пары. Поддерживает JSON и текстовый формат, уровни логирования. Заменяет сторонние логгеры (zap, zerolog) для большинства задач.
Подробнее →http.DefaultClient не имеет Timeout. В production зависший сервер заблокирует горутину навсегда. Всегда создавайте клиент с Timeout.
Подробнее →Reference time: месяц=1 (January), день=2, час=15 (3 PM), минута=04, секунда=05, год=2006, смещение=-0700. Каждое число уникально, поэтому Go точно понимает что есть что.
Подробнее →time.NewTicker(d) отправляет в канал каждые d. time.NewTimer(d) отправляет один раз через d. Оба нужно останавливать через Stop().
Подробнее →sort.Interface требует три метода: Len (длина коллекции), Less (сравнение двух элементов по индексам), Swap (обмен двух элементов). sort.Sort(data) сортирует in-place.
Подробнее →strconv.Atoi("42") -> 42, err. strconv.Itoa(42) -> "42". ParseInt/ParseFloat для других оснований и типов. Приведение int("42") не компилируется.
Подробнее →io.Copy(dst, src)? 🟡 Средний
▶
io.Copy читает из io.Reader и пишет в io.Writer, пока не встретит io.EOF или ошибку. Работает с любыми потоками: файлы, сеть, буферы.
Подробнее →http.Client{Timeout: 5*time.Second} - таймаут на весь запрос. context.WithTimeout - более гибкий, можно задать для отдельных запросов. На практике используют оба подхода.
Подробнее →log.Fatal("error") отличается от panic("error")? 🟡 Средний
▶
log.Fatal пишет сообщение в лог и вызывает os.Exit(1) - deferred функции не выполняются, recover не поможет. panic запускает раскрутку стека, deferred функции выполняются, и panic можно перехватить через recover. log.Fatal - для фатальных ошибок при старте.
Подробнее →http.HandleFunc("GET /users/{id}", handler) в Go 1.22+? 🟡 Средний
▶
Go 1.22 добавил HTTP-метод и path-параметры в стандартный ServeMux. "GET /users/{id}" обрабатывает только GET. Параметр доступен через r.PathValue("id"). Раньше для этого нужны были внешние роутеры (chi, gorilla).
Подробнее →var s []int от s := []int{}? 🟡 Средний
▶
json.Marshal(nil-слайса) возвращает null, а json.Marshal(пустого слайса) - []. Критично для API: фронтенд обрабатывает null и [] по-разному. Для гарантии [] инициализируйте слайс: s := []int{} или s := make([]int, 0).
Подробнее →Middleware в Go - функция, принимающая http.Handler и возвращающая http.Handler. Пример: func Log(next http.Handler) http.Handler { return http.HandlerFunc(func(w, r) { log(r); next.ServeHTTP(w, r) }) }. Middleware оборачивают друг друга: Log(Auth(handler)).
Подробнее →slices.SortFunc (Go 1.21+) лучше sort.Slice? 🟡 Средний
▶
slices.SortFunc использует generics - нет приведения типов и интерфейсных вызовов. sort.Slice работает через interface{} и рефлексию. slices.SortFunc инлайнит функцию сравнения. slices.SortStableFunc - для стабильной сортировки.
Подробнее →http.Client переиспользует TCP-соединения (keep-alive). Если Body не прочитан и не закрыт, соединение не возвращается в пул.
Подробнее →http.DefaultTransport поддерживает пул keep-alive соединений. MaxIdleConnsPerHost=2 по умолчанию - при нагрузке на один хост стоит увеличить.
Подробнее →strings.Clone(s) (Go 1.20+), если строки неизменяемы? 🔴 Сложный
▶
Подстрока s[i:j] может ссылаться на большой базовый массив оригинальной строки, не давая GC его собрать. strings.Clone создаёт копию с новым массивом. Это важно при чтении маленьких подстрок из больших данных (парсинг файлов, HTTP-заголовки).
Подробнее →time.After(d) создает Timer при каждом вызове. В цикле select каждая итерация создает новый Timer, который живет до истечения d. При высокой частоте это тысячи таймеров в памяти.
Подробнее →