Библиотека Go-разработчика | Golang

Библиотека Go-разработчика | Golang

@goproglib

Все самое полезное для Go-разработчика в одном канале.Учиться у нас: clc.to/qaSdwwПо рекламе: @proglib_advДля обратной связи: @proglibrary_feeedback_botРКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0#WXSSA

23 943подписчиков
Ежедневно🇷🇺

Похожие каналы

Все →

Последние посты

Библиотека Go-разработчика | Golang — пост в ТГ канале

🎉 Первый релиз кандидат Go 1.27Вышел релиз-кандидат Go 1.27, финал ждут в августе 2026. Команда просит прогнать на нём свои тесты и нагрузку, пока есть время поймать регрессии. Что в нём интересного.➡️ Дженерик-методыГлавная новость, которую ждали годами. Теперь метод может объявлять собственные параметры типа, а не только функция уровня пакета. Раньше дженерик-функцию, привязанную к типу, приходилось выносить в область видимости всего пакета. Теперь так:type Box[T any] struct{ v T }func (b Box[T]) Map[U any](f func(T) U) Box[U] { return Box[U]{f(b.v)}}Методы интерфейсов параметры типа объявлять не могут, и дженерик-методом интерфейс не реализуешь.➡️ JSON переписалиПоявились пакеты encoding/json/v2 и encoding/json/jsontext. Старый encoding/json теперь работает поверх v2. Поведение сохранили, но разбор JSON стал заметно быстрее, а кодирование осталось примерно на том же уровне. v2 строже по умолчанию, отвергает битый UTF-8 и дублирующиеся ключи в объекте. Если что-то сломалось, есть аварийный тормоз GOEXPERIMENT=nojsonv2.➡️ UUID в стандартной библиотекеНовый пакет uuid генерирует и парсит UUID. Можно выкинуть одну внешнюю зависимость из проекта.➡️ Что ещёМелкие аллокации до 80 байт стали дешевле примерно на 30 процентов за счёт специализированных по размеру функций выделения памяти. Профиль утечек горутин goroutineleak доехал из эксперимента в стабильную версию и ловит горутины, навсегда заблокированные на канале или мьютексе. Добавили экспериментальный пакет simd для портируемых векторных операций, включается через GOEXPERIMENT=simd. Завезли постквантовые подписи crypto/mldsa по FIPS 204 и поддержку их в crypto/tls и crypto/x509. В strings и bytes появилась CutLast, в net/url методы Clone. Каналы из пакета time теперь всегда небуферизованные, настройку asynctimerchan убрали навсегда. И минимум для macOS поднялся до Ventura 13.Поставить и попробовать.go install golang.org/dl/go1.27rc1@latestgo1.27rc1 download➡️ Источник📍 Навигация: Вакансии • Задачи • Собесы🐸 Б

19 июн. 2026 г.1 960В Telegram

😁 Интерфейс ради мока проверяет ваш мок, а не кодСообщество Go любит интерфейсы, и они правда мощные. Но в какой-то момент «пиши тестируемый код» превратилось в «оборачивай в интерфейс вообще всё»:type UserRepository interface { GetByID(ctx context.Context, id string) (*User, error) Create(ctx context.Context, u *User) error Update(ctx context.Context, u *User) error Delete(ctx context.Context, id string) error}// и мок на 120 строк, который расходится с реальной// реализацией в тот же миг, когда кто-то добавил методМок становится грузом в поддержке. Он не говорит, корректен ли ваш SQL запрос. Он не ловит разницу в поведении pgx между pgx.ErrNoRows и реальной ошибкой скана. И он даёт ложную уверенность, тесты зелёные, а боевые запросы кривые.➡️ Что делать вместоТестировать код базы против настоящей базы. testcontainers-go поднимает реальный Postgres прямо в CI. Код, сгенерированный sqlc, типизирован и корректен по построению. Интерфейсы остаются там, где они нужны по делу, то есть на границах сервисов, где вы реально подменяете реализацию:func TestCreateMember(t *testing.T) { ctx := context.Background() db := testutil.NewPostgresContainer(t) // реальный postgres, реальная схема q := db_gen.New(db) member, err := q.CreateMember(ctx, db_gen.CreateMemberParams{ FullName: "Witty", Phone: "+254700000000", }) require.NoError(t, err) require.Equal(t, "Witty", member.FullName)}Интерфейс под каждый репозиторий часто тестирует сам себя, а не вашу логику работы с данными. Базу проверяйте на реальной базе, а интерфейсы держите на стыках сервисов, где подмена реализации нужна по делу.📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoToProduction

19 июн. 2026 г.2 300В Telegram

🔍 Почему у горутин нет IDРазработчики, пришедшие из Java или Python удивляются: горутина запущена, но получить её идентификатор нельзя. Нет метода, нет структуры, нет ничего, что можно было бы сохранить и использовать потом. В Go это сделано намеренно.❓ Как это устроеноГорутина — анонимный воркер. Она не имеет имени, не возвращает дескриптор при запуске, не регистрируется нигде в рантайме с точки зрения программиста.Это не техническое ограничение. Рантайм Go знает о каждой горутине всё что нужно — стек, статус, планировщик. Но эта информация намеренно скрыта от прикладного кода.Причина в том, что именованные горутины провоцируют плохой дизайн. Когда у потока есть ID, программисты начинают привязывать к нему состояние — «этот поток обрабатывает этот запрос, значит туда и кладём контекст». Именно так работает thread-local storage, и именно это создаёт проблемы в конкурентных системах.Пример из реальной жизни: если бы net/http хранил состояние запроса в горутине по ID, сервер не мог бы распараллелить обработку одного запроса между несколькими горутинами. Вся архитектура стала бы жёстче.➡️ Подводные камниОпыт с графическими системами, где весь рендеринг должен идти через «главный поток», хорошо показывает, к чему ведёт именование. Программисты вынуждены постоянно маршрутизировать работу в конкретный поток, обходить ограничения, добавлять костыли. В конкурентном языке это особенно болезненно.Похожая история возникает с goroutine-local storage — его периодически пытаются реализовать через runtime.Stack и парсинг вывода. Это работает, но Go-команда считает такой подход антипаттерном: он хрупкий, медленный и ломается при изменении формата стека.➡️ Пример кодаПравильный способ передать состояние между горутинами — канал или context.Context:func worker(ctx context.Context, jobs <-chan int, results chan<- int) { for { select { case j, ok := <-jobs: if !ok { return } results <- process(ctx, j) case <-ctx.D

18 июн. 2026 г.2 660В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

🚀 Java догнала Go, а на больших запросах обогналаВ 2020 Марк Нельсон проверял, может ли Java-микросервис держать скорость как у Go. Тогда для маленького сервиса вышла ничья. В июне 2026 замер повторился на свежих рантаймах, и расклад поменялся.Оба сервиса гоняли по очереди на одной машине, без конкуренции за CPU. Go на стандартном net/http, без фреймворка. Java на Helidon SE с виртуальными потоками, в двух вариантах. Обычный JVM от Oracle JDK 26 и тот же JDK с AOT-кэшем Leyden. Сервис делал немного работы на запрос. Регистр, разворот строки, CRC32 и JSON в ответ.❓ Что показали цифрыНа одном воркере и 7 байтах все шли рядом. Go около 3 200 запросов в секунду, JVM около 2 722, Leyden около 3 561. Классическая картинка из старых споров, где Go стартует резво.А потом подняли конкуренцию до 192 воркеров, и кривая разъехалась. На 7 байтах Go выдал около 59 тысяч запросов в секунду, JVM около 74 тысяч, Leyden около 99 тысяч. На 2 КБ пик Go около 17 тысяч против 40 с лишним тысяч у обоих вариантов Java. На 8 КБ Go около 6,8 тысячи, Java около 15 тысяч. Отказов не было нигде. В финальной матрице Go не выиграл ни одной ячейки.❓Какие выводыСтарый тезис «Java тяжёлая, для мелких сервисов берите Go» этот прогон не подтверждает. Go по-прежнему хорош, компактный код и поставка одним бинарником никуда не делись. Но виртуальные потоки и зрелый JVM делают блокирующий код Java дешёвым, а Helidon SE держит сервис маленьким, так что сравнение не «Go против монстра-фреймворка».Делать из этого корпоративную политику по языкам не нужно. Полезнее помнить, что рантайм, прогрев, опции сокетов и дизайн замера часто значат больше, чем сам язык. ➡️ Код и сырые результаты📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoLive

18 июн. 2026 г.2 780В Telegram

🤨 Не прокидывайте context в чистые функции. Он стоит дороже, чем кажетсяПроброс контекста штука верная и важная. Но совет «всегда прокидывай context» превращается в карго культ, когда ctx добавляют в сигнатуру каждой функции, включая чистые функции без всякого ввода вывода, просто потому что так сказал линтер или комментарий в PR:// Этой функции context не нуженfunc calculateInstallments(principal float64, rate float64, months int) []Installment { // чистая математика, нет I/O, нет горутин}У контекста есть цена. Это аргумент, который приходится тянуть повсюду, он зашумляет сигнатуры и провоцирует пихать зависимости через context.WithValue, чего делать не стоит.➡️ Где он нуженПрокидывайте контекст туда, где он реально используется. Это вызовы базы, HTTP клиенты, gRPC стабы, всё, что блокируется на I/O или нуждается в отмене. Не прокидывайте его в чистые функции, доменную логику и всё, что возвращается за микросекунды независимо от отмены.Контекст нужен там, где есть что отменять или ждать. В остальных местах он только зашумляет код и создаёт соблазн использовать его не по назначению. Доверяйте языку и добавляйте структуру там, где она окупается.📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoToProduction

18 июн. 2026 г.2 830В Telegram

⏰ Уже сегодня в 19:00 (МСК) стартует открытый урок!Тема:«Мультиагентные системы: почему большинство архитектур переусложнены»🔥 За 90 минут разберёмся, когда действительно стоит строить мультиагентную систему, а когда она только добавляет сложность, расходы и новые точки отказа.Поговорим о критериях выбора архитектуры, типичных ошибках и ограничениях современных ИИ-агентов, которые важно учитывать ещё до внедрения в продукт.🎙️ Спикер — Дмитрий Юдин, руководитель AI/ML-направления в Сloud․ru.🎁 Для всех участников подготовили промокод на скидку 10 000 ₽ на курс «Разработка ИИ-агентов».👉 Успей присоединиться к уроку

18 июн. 2026 г.2 770В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoGiggle

17 июн. 2026 г.2 830В Telegram

☕️ Топ-вакансий для Go-разработчиков за неделю Go-разработчик — от 100 до 350 тысяч рублей в зависимости от нагрузкиДжун+ в МосквуGo разработчик — 320 тысяч рублей и гибрид в Москве➡️ Еще больше топовых вакансий — в нашем канале Go jobs🐸Библиотека Go-разработчика#GoWork

17 июн. 2026 г.2 880В Telegram

🖥 Монолитные тесты Go API: cлой логики, слой HTTP и трейдоффыМы вынесли моки в mock.go и наметили разбиение тестов на слои. Теперь покажем сами тесты двух слоёв и честно разберём, чем платим за такую структуру.🛠 Бизнес логика (`*_service_test.go`)Этот файл проверяет только доменную логику. Слой репозитория замокан через mock.go, поэтому тесты гоняются целиком в памяти и работают очень быстро. Здесь проверяют правила валидации, обработку кривых данных, доменные ошибки и переходы состояний:func TestAuthServiceLogin(t *testing.T) { t.Run("login credentials", func(t *testing.T) { testAuthRepo.GetUsernameOrEmailFunc = func(ctx context.Context, username string) (*models.Users, error) { hash, _ := bcrypt.GenerateFromPassword([]byte("!Abc1234"), bcrypt.DefaultCost) return &models.Users{ID: 1, Username: "test_account", Password: string(hash)}, nil } req := auth.LoginRequest{Username: "rdev", Password: "!Abc1234"} _, err := testAuthSvc.Login(context.Background(), req) if err != nil { t.Errorf("Expected no error, got %v", err) } })}🛠 HTTP слой (`*_handler_test.go`)Этот файл проверяет, как API общается с внешним миром. Он поднимает запросы через net/http/httptest и использует моки сервиса, чтобы не дёргать реальную логику. Под проверкой статус коды, сериализация JSON, параметры запроса, заголовки, работа мидлварей вроде rate limiter. Табличный тест гоняет несколько кейсов входа сразу:func TestAuthHandlerLogin(t *testing.T) { tests := []struct { name string requestBody any expectedStatus int }{ {"complete credentials", loginRequest{"rdev", "!Abc1234"}, http.StatusOK}, {"no password", loginRequest{"rdev", ""}, http.StatusBadRequest}, {"password too short", loginRequest{"rdev", "1234"}, http.StatusBadRequest}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctx, w := helpers.SetupJSONTestContext(t,

17 июн. 2026 г.2 670В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

⚡️ Быстрый бэкап с шифрованием и дедупликацией из коробкиrestic — это открытая программа бэкапа на Go, которая работает на Linux, macOS, Windows, а также FreeBSD и OpenBSD. На GitHub у проекта около 34 тысяч звёзд.Что делаетСнимает инкрементальные снапшоты ваших файлов, шифрует их, дедуплицирует и складывает в хранилище, которому не обязательно доверять. Каждый новый снапшот занимает место только под реальный прирост данных, а дубликаты убираются ещё до записи в бэкенд.➡️ Принципы, на которых построенПросто. Бэкап и восстановление не должны быть сложными, иначе их пропускают. Быстро. Скорость упирается только в сеть или диск, при восстановлении переносятся лишь те данные, что нужны для нужных файлов. Проверяемо. Восстановление важнее самого бэкапа, поэтому restic даёт легко убедиться, что данные реально восстановимы. Безопасно. Шифрование гарантирует конфиденциальность и целостность, а место хранения считается недоверенным, то есть защита рассчитана даже на админа с доступом к вашим бэкапам. Эффективно. Рост данных не означает рост хранилища в разы за счёт дедупликации.➡️ Как пользоватьсяСначала создаёте репозиторий под бэкапы. Пароль обязателен, без него данные не восстановить:restic init --repo /tmp/backupЗатем кладёте данные. restic сам сканирует и показывает прогресс со скоростью и ETA:restic --repo /tmp/backup backup ~/workВосстановить можно командой restic restore, либо смонтировать репозиторий через fuse командой restic mount и ходить по файлам прошлых снапшотов как по обычной папке.➡️ Куда складывать бэкапыХранить копию на той же машине это не стратегия. restic нативно поддерживает локальную папку, sftp по SSH, собственный REST сервер, Amazon S3 и совместимый Minio, OpenStack Swift, Backblaze B2, Azure Blob Storage, Google Cloud Storage. Через rclone подключается ещё множество сервисов.Приятная детальБинарники начиная с версии 0.6.1 собираются воспроизводимо. Из исходников релиза вы можете получить байт в байт идентичную сборку и убедиться, что в бинаре нет

16 июн. 2026 г.2 360В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

📹 Монтаж видео на Go без ручного ffmpegMovieGo это библиотека на Go для монтажа видео. Под капотом она работает поверх пакета ffmpeg-go и даёт API с цепочками методов. Вы пишете обычный Go код, а команду для ffmpeg библиотека собирает сама. Через неё можно нарезать ролик, склеить несколько в один, поменять размер, добавить плавное появление и затухание или снять кадр. Сам ffmpeg должен стоять в системе отдельно.РазмерResizeByWidth задаёт ширину, ResizeByHeight высоту, Resize сразу оба значения:first, _ := moviego.Load("forest.mp4")first.Resize(1000, 500).Output("resized.mp4").Run()НарезкаSubClip обрезает ролик по началу и концу отрезка в секундах. Тут кусок с третьей по пятую секунду:first.SubClip(3, 5).Output("final.mp4").Run()СклейкаConcat собирает слайс Video в один ролик, прямо в слайсе можно применять эффекты к отдельным кускам:finalVideo, _ := moviego.Concat([]moviego.Video{ first, second.SubClip(5.3, 10.5), first.FadeIn(0, 5).FadeOut(5),})finalVideo.Output("final.mp4").Run()Появление и затуханиеFadeIn и FadeOut работают с картинкой, AudioFadeIn и AudioFadeOut со звуком. Методы складываются в цепочку:first.FadeIn(0, 3).FadeOut(5).Output("fade.mp4").Run()first.FadeOut(5).AudioFadeOut(5).Output("fade-out.mp4").Run()СкриншотScreenshot сохраняет кадр по указанной секунде, в том числе после эффектов:first.Screenshot(5, "simple-screen.png")MovieGo снимает рутину по сборке команд ffmpeg руками и переводит монтаж на понятные методы. Подойдёт, чтобы автоматизировать обработку видео в Go сервисе, например генерировать превью или собирать ролики из частей.➡️ Репозиторий📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max🐸 Библиотека Go-разработчика#GoToProduction

11 июн. 2026 г.2 100В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

👋 Привет, гоферы!Канал работает стабильно, без паник и утечек. Но мы нашли такую строку в коде:if boosts < needed { return fmt.Errorf("не хватает буста для крутых фич: %w", ErrSadAdmin)}Без бустов канал живёт, но с ними — раскрывает все горутины на полную. Один клик, и вы в списке тех, кто помог проекту.➡️ Бустануть канал📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max🐸 Библиотека Go-разработчика

11 июн. 2026 г.2 350В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max🐸 Библиотека Go-разработчика#GoGiggle

11 июн. 2026 г.2 660В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

🔄 pgCenter 0.10.0, поддержка Postgres 15–18 и переход на pgx/v5Вышел релиз v0.10.0 консольной утилиты pgcenter для наблюдения за Postgres. Это в основном обновление совместимости и безопасности, новых экранов в интерфейсе не добавили.Главное изменение это поддержка Postgres от 15 до 18. Запросы статистики обновили под формат версии 17, прогон тестов идёт на ветках с 14 по 18. Под капотом утилита перешла на драйвер pgx/v5, обновилась до Go 1.25.10 и закрыла накопившиеся уязвимости в зависимостях.Часть правок касается устойчивости и вывода:• Теперь pgcenter проверяет, включён ли pg_stat_statements в shared_preload_libraries, и больше не зависает, если расширение установлено в базе, но не активировано в конфигурации.• Длинные значения application_name из pg_stat_activity перестали обрезаться. • Адрес клиента в pg_stat_activity и pg_stat_replication теперь оборачивается в функцию host(), поэтому в выводе нет лишней маски подсети.Если вы уже пользуетесь pgcenter на свежих версиях Postgres, обновление снимает проблемы совместимости и убирает известные CVE. ➡️ Репозиторий📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max🐸 Библиотека Go-разработчика#GoLive

10 июн. 2026 г.2 690В Telegram

🥺 Big money вакансии для Go-разработчиков за неделю Middle / Senior Бэкенд разработчик — до 405 000 $ (в год) — удаленно по Сан-ФранцискоGolang-разработчик — до 400 000 ₽ в офис или удаленно (Москва)➡️ Еще больше топовых вакансий — в нашем канале Go jobs🐸 Библиотека Go-разработчика#GoWork

10 июн. 2026 г.2 780В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

📎 Почему цепочка middleware ломает безопасность, даже когда каждый обработчик корректенСтек middleware разрастается до десятка с лишним обработчиков. Каждый написан осознанно и протестирован, а ревью всё равно находит обход аутентификации. Дыра не внутри обработчика, а в порядке их выполнения.👉 Почему так происходитПорядок обычно складывается стихийно. Обработчики добавляют по мере задач, и очерёдность повторяет хронологию, а не смысл. Кто добавлен раньше, тот снаружи. При этом влияние нового обработчика на безопасность всей цепочки никто не проверяет.В итоге порядок принимает решения, которые никто явно не принимал. Когда срабатывает аутентификация, может ли запрос получить ответ до неё, кто видит личность в контексте. Эта политика нигде не записана и меняется при каждой перестановке.👉 Как этого избежатьРазбейте цепочку на слои доверия и зафиксируйте, что внутри блока безопасности порядок обязателен:// Слой безопасности, порядок обязателен// авторизации нужна личность из контекста// аутентификации нужен резолв тенанта из контекстаhandler = authorizationMiddleware(handler)handler = authenticationMiddleware(handler)handler = tenantMiddleware(handler)Запретите ранний выход до аутентификации. Ни один обработчик выше блока безопасности не должен сам возвращать неошибочный ответ. Быстрый ответ на health check выносите на отдельный неаутентифицированный маршрут.Сделайте порядок проверяемым в CI. Пусть пайплайн отклоняет PR, который переставляет обработчики внутри блока безопасности без явного ревью. Тогда комментарии о порядке работают как ограничение, а не пожелание.Тестируйте цепочку целиком. Юнит тесты не ловят такие дыры, потому что баг живёт во взаимодействии. Нужны сквозные тесты на враждебные комбинации заголовков, путей и параметров.Полезнее спрашивать не про то, корректен ли каждый middleware, а про то, что цепочка считает истинным к моменту запуска каждого обработчика. Держите порядок явным, проверяемым и покрытым тестами на всю цепочку сразу.📍 Навигация: Ва

10 июн. 2026 г.2 720В Telegram

💻 top для Postgres прямо в терминалеPostgres отдаёт массу статистики о своей работе. Активные сессии, запросы, репликация, блокировки, обращения к таблицам и индексам, прогресс вакуума. Всё это лежит в системных представлениях вроде pg_stat_activity и pg_stat_statements. Беда в том, что родного инструмента для удобной работы с этой статистикой у Postgres нет. Приходится держать в голове десятки запросов и руками дёргать представления через psql. Написанный на Go, pgCenter показывает статистику в живом интерфейсе, похожем на top.🖇 Что он умеетОсновная команда pgcenter top обновляет метрики в реальном времени и переключается между экранами по горячим клавишам. Видно сводку по базе, активность клиентов из pg_stat_activity, тяжёлые запросы из pg_stat_statements, состояние репликации, обращения к таблицам и индексам, прогресс операций вроде VACUUM, CREATE INDEX и COPY. Рядом идёт системная статистика, собранная из procfs. Это load average, загрузка CPU, память и swap, нагрузка на диски и сеть.Отдельно полезен экран по процессам, он открывается по Shift+S. Там pgcenter склеивает данные из pg_stat_activity с метриками каждого бэкенда из /proc/[pid]/stat и /proc/[pid]/io. Сразу видно, во что упёрся медленный запрос, в процессор или в диск, без выхода из утилиты. Экран работает только в локальном режиме.🖇Как запуститьПроще всего через Docker:docker pull lesovsky/pgcenter:latestdocker run -it --rm lesovsky/pgcenter:latest pgcenter top -h 1.2.3.4 -U user -d dbnameЕсли ставите пакетом, под DEB, RPM и APK есть готовые сборки на странице релизов. После установки запуск выглядит так:pgcenter top -h 127.0.0.1 -U postgres -d mydbКроме живого режима есть запись статистики на будущее. Команда pgcenter record складывает метрики в файлы, а pgcenter report строит из них отчёты для разбора уже после инцидента. Метрики по процессам тоже пишутся, и их можно проиграть через pgcenter report -N. Ещё внутри есть профайлер событий ожидания, просмотр и правка конфигов с перезагрузкой сервиса,

9 июн. 2026 г.2 490В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

🔥 Приглашаем на бесплатный открытый вебинар курса «Высоконагруженные системы: архитектура и масштабирование»:«Асинхронная обработка данных в высоконагруженных системах»🗓 Когда: 16 июня, 20:00 (мск)На вебинаре разберём, как грамотно внедрять асинхронность и строить по-настоящему производительные системы.Что будет на вебинаре:— Зачем и когда переходить на асинхронную обработку данных в высоконагруженных проектах— Очереди сообщений, веб-сокеты и другие инструменты асинхронного взаимодействия— Реальный архитектурный кейс: от веб-сервера до брокера сообщений и базы данных— Типичные узкие места асинхронных систем и проверенные способы их устранения👉 Зарегистрироваться: https://clc.to/ziti4AБесплатное занятие приурочено к курсу «Высоконагруженные системы: архитектура и масштабирование», где вы научитесь проектировать высоконагруженные системы, способные выдерживать экстремальные нагрузки и работать стабильно в любых условиях.🎁При покупке курса вы получите в подарок мини-курс по Kafka, который поможет подготовиться к собеседованию в бигтехРеклама. ООО «Отус онлайн-образование», ОГРН 1177746618576 Erid 2VtzqvCg3jn

9 июн. 2026 г.2 430В Telegram
Библиотека Go-разработчика | Golang — пост в ТГ канале

🧑‍💻 Зачем мьютекс в uuid, если UUID не хранят состояниеВ исходниках пакета uuid рядом с генерацией UUIDv7 лежит мьютекс уровня пакета и переменная с временем последнего вызова. UUID считаются значениями без состояния, поэтому блокировка выглядит лишней. Разберём, зачем она там.Первые 48 бит UUIDv7 это метка времени в миллисекундах. Поэтому такие значения сортируются по времени создания и удобны как ключи в базе. Но внутри одной миллисекунды программа создаёт тысячи идентификаторов с одинаковой меткой, и без счётчика их порядок стал бы случайным.Пакет хранит последнее выданное время вместе со счётчиком в lastV7time и проверяет, что новое значение строго больше прошлого:func getV7Time() (milli, seq int64) { timeMu.Lock() defer timeMu.Unlock() nano := timeNow().UnixNano() milli = nano / nanoPerMilli seq = (nano - milli*nanoPerMilli) >> 8 now := milli<<12 + seq if now <= lastV7time { now = lastV7time + 1 milli = now >> 12 seq = now & 0xfff } lastV7time = now return milli, seq}Если посчитанное время не больше прошлого, функция берёт lastV7time + 1. Так порядок держится даже при переводе часов назад, просто встроенная метка ненадолго разойдётся с реальной.Мьютекс нужен потому, что NewV7 зовут из разных горутин, а lastV7time одна на весь пакет. Используется общий timeMu, тот же, что защищает время старых версий UUID.Состояние живёт в одном процессе. Между несколькими машинами строгий порядок внутри миллисекунды не гарантирован, хотя сортировка по времени всё равно работает.📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max🐸 Библиотека Go-разработчика#GoDeep

9 июн. 2026 г.2 370В Telegram

🌴 Деревья поиска на Go: вставка, поиск, удалениеBST — двоичное дерево поиска. Простая идея: левый потомок всегда меньше родителя, правый — больше. Это даёт поиск за O(log n), но только если дерево сбалансировано. Об этом — в конце поста.Структура узлаtype Node struct { Val int Left *Node Right *Node}type BST struct { Root *Node}ВставкаИдём по дереву вниз: если значение меньше текущего узла — налево, больше — направо. Когда упёрлись в nil — вставляем:func (t *BST) Insert(val int) { t.Root = insert(t.Root, val)}func insert(node *Node, val int) *Node { if node == nil { return &Node{Val: val} } if val < node.Val { node.Left = insert(node.Left, val) } else if val > node.Val { node.Right = insert(node.Right, val) } return node}Дубликаты здесь просто игнорируются. Можно добавить счётчик в узел, если нужно их хранить.ПоискТа же логика, что и вставка, но вместо создания узла возвращаем результат:func (t *BST) Search(val int) bool { return search(t.Root, val)}func search(node *Node, val int) bool { if node == nil { return false } if val == node.Val { return true } if val < node.Val { return search(node.Left, val) } return search(node.Right, val)}УдалениеТри случая:- узел без потомков — просто удаляем- узел с одним потомком — заменяем им- узел с двумя потомками — находим минимальный элемент правого поддерева (in-order successor), ставим его на место удалённогоfunc (t *BST) Delete(val int) { t.Root = deleteNode(t.Root, val)}func deleteNode(node *Node, val int) *Node { if node == nil { return nil } if val < node.Val { node.Left = deleteNode(node.Left, val) } else if val > node.Val { node.Right = deleteNode(node.Right, val) } else { if node.Left == nil { return node.Right } if node.Right == nil { return node.Left } // Находим минимум в правом поддереве min := findMin(node.Right

9 июн. 2026 г.2 280В Telegram