Обновить
128.4

Go *

Компилируемый, многопоточный язык программирования

Сначала показывать
Порог рейтинга

2ГИС зовёт на хакатон: https://hackathon.2gis.ru

4–5 октября, офлайн, Москва. Два дня, чтобы общаться, фигачить, вдохновляться и повлиять на городские сервисы!

Три трека: городские данные с ЦОДД, инклюзия с фондами «Антон тут рядом», «Продвижение», «ЛизаАлерт» и носимые устройства — часы, браслеты, AR и другие гаджеты. Будут онлайн-встречи, чтобы больше узнать про реальные задачи.

Призовой фонд: 1 000 000 рублей и шанс, что проект попадёт прямо в 2ГИС🔥

Регистрироваться можно с командой от 3 до 6 человек или самостоятельно — поможем найти команду в чате!

Теги:
Рейтинг0
Комментарии0

Вышел Gonzo 0.1.6 - терминальный UI для анализа журналов в реальном времени. Написал на Go, вдохновлён k9s. Позволяет анализировать потоки журналов с помощью красивых диаграмм, аналитики и расширенной фильтрации — всё прямо в терминале.

ChangeLog: https://github.com/control-theory/gonzo/releases/tag/v0.1.6

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Мое решение для Нерешаемой Проблемы

Все дети знают, что много мусора создает большие проблемы для Garbage Collector. Ну а взрослые видели и НЕРЕШАЕМЫЕ! Причем, мусора было немного:

We kept digging and learned the spikes were huge not because of a massive amount of ready-to-free memory, but because the garbage collector needed to scan the entire LRU cache in order to determine if the memory was truly free from references.

Что в этом случае делают взрослые? Правильно! Взрослые в ужасе убегают...

У меня есть решение для тех, кто устал убегать: mdb.BlobMap. Это быстрая хеш-таблица, не создающая проблем сборщику мусора:

ОК, что значит "не создающая проблем"? В данном случае это значит, что весь mdb.BlobMap -- это просто массив uint64...

Так НЕ БЫВАЕТ?!

Бывает, чо https://ders.by/go/blobmap/blobmap.html

Теги:
Всего голосов 5: ↑0 и ↓5-5
Комментарии0

В прошлую субботу я подал заявку на участие в митапе GoSharp Weekend, который проводит компания Ozon Tech. Все заявки на этот митап проходят модерацию, т.к. к участию допускаются только C#- и Go-разработчики уровня middle+.

Вчера я получил письмо с отказом:

Сначала я подумал, что просто закончились свободные места. Но сегодня я, как постоянный участник мероприятий Ozon Tech, получил письмо с рекламой данного мероприятия. Получается, что свободные места все еще есть, а моя заявку отклонили, потому что она не прошла модерацию. Вполне возможно, что из-за всей этой охоты на волков организаторы не поняли, что означает фраза «опенсорс-мейнтейнер», и приняли меня за накрутчика опыта.

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии1

Вышел NATS.go 1.45 - Go-клиент для системы обмена сообщениями NATS.

Ключевые изменения:

  • В Core NATS добавлена обработка превышения максимального количества активных подключений к учетной записи

  • В JetStream добавлена опция WithExpectLastSequenceForSubject для логики публикации

  • Добавили тесты на проверку обновлений KV TTL watcher

  • Исправлено несколько ошибок

GitHub: https://github.com/nats-io/nats.go

ChangeLog: https://github.com/nats-io/nats.go/releases/tag/v1.45.0

Теги:
Рейтинг0
Комментарии0

Вышел Statsviz 0.7.0- визуализатор работы Golang программы в реальном времени.

В число показателей входят данные о куче, переменных, горутинах, паузах работы сборщика мусора, планировщика. Данные выводятся в браузере.

GitHub: https://github.com/arl/statsviz

ChangeLog: https://github.com/arl/statsviz/blob/main/CHANGELOG.md

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Ко мне в телеграм канал заглянул один из разработчиков Графини (убийцы Grafana), с пояснением, зачем они её родили, и что писали полностью с нуля.

Я верю.

Теги:
Всего голосов 12: ↑4 и ↓8-4
Комментарии2

Многие крупные компании применяют Go, а спрос на опытных инженеров, владеющих Go, высок как никогда. Онбординг проходит действительно быстро, и у нас есть успешные тому примеры. Все благодаря общей простоте языка и отсутствию function coloring. В карточках рассказываем, как это получилось у Кирилла в 2ГИС↓

Теги:
Всего голосов 6: ↑3 и ↓30
Комментарии4

Хотите подтянуть свои знания Go?

Тогда новый бесплатный курс для вас!

Язык Go называют одним из самых удобных для бэкенда. Дело тут не в примитивности: его специально стремились сделать простым и лаконичным, чтобы пользователям было легко работать с синтаксисом и понимать чужой код.

Если вы уже знакомы с Go, но не хватает практики, приглашаем пройти новый курс в Академии Selectel. С ним вы научитесь писать простые сервисы на Go и использовать его в некоторых рабочих задачах, а еще получите большую подборку ресурсов для погружения в этот язык. 

Несколько материалов для старта.

Открыть курс →

Теги:
Всего голосов 6: ↑6 и ↓0+9
Комментарии1

Бесплатные курсы Route 256 от Ozon Tech для Go-инженеров уровня middle

Route 256 — это эффективная прокачка знаний и навыков работы с микросервисами. Программа курса составлена ведущими экспертами Ozon Tech — командой, которая разрабатывает сервисы, выдерживающие экстремальные нагрузки до 382 000 RPS.

Программа состоит из вебинаров, воркшопов, домашних заданий и их детальных разборов. Причём каждый из этих элементов основан на реальных задачах Ozon. Никаких заданий ради заданий — только действительно актуальные знания и проекты.

Как минимум, они бустанут ваше портфолио. Как максимум, вы получите оффер в команду. Заходите на сайт Route 256, изучайте требования и подавайте заявку.

Отборочный контест уже 3 августа!

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Эффективные хеш-таблицы на Go

В Go нет недостатка хеш-таблиц. Вы всегда можете использовать встроенную map[Key]Val, с ошеломительной скоростью обладающую непревзойденным удобством! А изобилие типов Keyразрешенных к использованию, способно довести до изумления!

Вот только ни указатель, ни слайс не подходят... Невозможно подсунуть свои операции (равенства и хеширования). Но хоть со скоростью все хорошо! (извините, не удержался)

Итого, мне пришлось написать HashMap[K, V any], закрывающую проблемы.

------------------8<------------------

В это трудно поверить, но:

  • Без резервирования памяти (конфигурация R0), map[uint64]uint64 работает в 1.93 раза медленнее UintMap! И производит в 5.64 раза больше мусора!!

  • А с полным резервированием (R1), в 1.72 раза медленнее! И аж в 16.5 раз больше мусора!!!

Вдумайтесь! На коленке написанная хеш-таблица для целых чисел UintMap почти в два раза обгоняет ЖУТКО оптимизированную нативную map[uint64]uint64!! И существенно менее мусорит!!!

Но раз трудно поверить, то давайте проверим:

func MyUintMap() {
    const N = umN

//R0|    um := lib.NewUintMap(0)
    um := lib.NewUintMap(N) //R1|

    for i := uint64(0); i < N; i++ {
        um.Findsert(i, i+N)
    }
    lib.Assert(um.Size() == N)

    cnt := 0
    for i := uint64(0); i < N; i++ {
        if *um.Val(um.Find(i)) == i+N {
            cnt++
        }

        if um.Find(i+N) == -1 {
            cnt++
        }
    }
    lib.Assert(cnt == N*2)

    for i := uint64(0); i < N; i++ {
        um.Delete(i)
    }
    lib.Assert(um.Size() == 0)
}

func GoUintMap() {
    const N = umN

//R0|    m := make(map[uint64]uint64)
    m := make(map[uint64]uint64, N) //R1|

    for i := uint64(0); i < N; i++ {
        m[i] = i + N
    }
    lib.Assert(len(m) == N)

    cnt := 0
    for i := uint64(0); i < N; i++ {
        if m[i] == i+N {
            cnt++
        }

        if _, ok := m[i+N]; !ok {
            cnt++
        }
    }
    lib.Assert(cnt == N*2)

    for i := uint64(0); i < N; i++ {
        delete(m, i)
    }
    lib.Assert(len(m) == 0)
}

Здесь всего-то лишь вставка, два поиска и удаление. Запустите go test -bench=UintMap -benchmem и увидите сами. Вот только можно ли ругать Google за неэффективный map[uint64]uint64?

------------------8<------------------

Итоги?

  1. Смело берите HashMap[K, V any] для слайсов и указателей!

  2. Немного оптимизированная BytesMap -- лучший выбор для []byte.

  3. Интересно оптимизированная UintMap -- это выбор для целых чисел. Разберитесь, что там "не так", и используйте за основу.

И как всегда, исходный код, подробности и пару неудачных шуток вы можете найти в моей статье https://ders.by/go/hashmap/hashmap.html

Теги:
Всего голосов 1: ↑1 и ↓0+2
Комментарии0

NotCVE-2025-0003 и NotCVE-2025-0004

Продолжаю по мере сил пополнять базу проекта NotCVE информацией о проблемах безопасности, которым разработчики не желают присваивать CVE (делал заметку об этом проекте). В этот раз одна проблема в компиляторе Go привела к регистрации сразу 2-х записей:

Т.к. помимо самого компилятора Go, пострадал и Kubernetes:

The Go team has released a fix in Go versions 1.21.11 and 1.22.4 addressing a symlink race condition when using os.RemoveAll. The Kubernetes Security Response Committee received a report that this issue could be abused in Kubernetes to delete arbitrary directories on a Node with root permissions by a local non-root user with the same UID as the user in a Pod.


Из сообщения в гитхабе Kubernetes видно насколько заразительна тенденция вместо регистрации CVE называть фикс проблемы безопасности хардерингом:

The Go team has not issued a CVE for this, as it is considered a hardening issue, and the SRC is following that decision as well.

Собственно, в случае с Docker в этом году было то же самое, для них это тоже хардеринг (моё обращение в MITRE так и не привело к появлению CVE, поэтому я зарегистрировал NotCVE-2025-001).

Как видно, ситуации, когда проблемы безопасности не приводят к появлению CVE случаются не редко. А некоторые разработчики даже пытаются оспаривать назначение CVE.

Теги:
Всего голосов 2: ↑2 и ↓0+3
Комментарии0

Привет Хабр! Это мой первый пост, и я просто хотелось спросить, стоит ли уходить в Go? У меня есть небольшая база в программировании, делал сайты на реакт и ларавел, реализовывал бэкенд с Солид и паттернами, писал на нативном пхп файловые обменники и апи. Не много знаю базы данных соответственно, гит, докер. Сейчас засматриваюсь на Go, где то вычитал что мол крутая штука для бигтехов в России, а сам я студент и пока сижу на шее у родителей, но в следующем году я окончу к курс, и хочу где то месяца за 4-5 изучить все нужное в го и во всех других сопутствующих технологиях для разработки высоконагруженных приложений и микросервисов и всякого подобного. Стоит ли сворачивать на этот путь, или добить стек ларавел плюс вью? Немного боюсь, так как слышал что в го нужны уже 25 летние синьоры со стажем работы минимум в 20 лет, но и не хочется проторчать всю жизнь в челябинской галере на фуллстеке за 70 деревянных на руки.

Теги:
Всего голосов 7: ↑1 и ↓6-4
Комментарии20

Ближайшие события

Хочу поделиться с вами видением хорошей архитектуры Go проекта, к которой я пришёл на данный момент и также интересно послушать ваши варианты и мнения по данному поводу.

Моё видение:

У нас ядро приложения это сервисный слой (юзкейсы), именно ядро самая основная часть приложения, которая взаимодействует с какой‑то логикой.

Если логика основана на внешних компонентах, то для связи ядра с компонентом(адаптер) и обратно используются абстракции в виде интерфейса(порт). При этом неважно какая связь (от ядра к компоненту или наоборот), внешние компоненты реализуют интерфейсы ядра и не содержат бизнес‑логики, они лишь преобразуют данные к форматам, понятным ядру (интерфейсы также основаны на моделях ядра).

Так как мы не хотим, чтобы логика из ядра уходила во внешние компоненты (по моему мнению, это повлечет переплетение зависимостей и нарушение принципов разделения ответственности), то вся логика должна выполняться на уровне ядра (например, вместо default значений полей в базе, мы создаём модель на уровне ядра, а база служит лишь в качестве хранилища, не выполняя какой‑либо бизнес логики). То есть бизнес‑валидация (инварианты агрегатов) остаётся в ядре, а адаптеры проводят schema‑валидацию (обязательные поля и форматы) до передачи в юзкейсы, тем самым мы избегаем лишних вызовов ядра (при некорректных данных), и не засоряя само ядро валидацией (отличным примером служит то, когда HTTP адаптер валидирует модель до передачи её в юзкейсы).

При этом всё, самое лучше место для интерфейсов (портов) будет отдельный пакет в ядре, к которому могут иметь доступ адаптеры, чтобы проверить реализации контракта (при это адаптеры будут "знать" лишь интерфейсы, а не весь сервисный слой, если бы порты хранились бы в месте использования), а также сами сервисы могут спокойно ссылаться на данные интерфейсы, не подтягивая их с адаптеров (в том случае, если бы мы хранили интерфейсы по месту имплементации).

То есть я считаю идеальной архитектурой для большинства Go проектов, работающих на основании адаптеров (к примеру, REST или gRPC сервис) гексагональную архитектуру с включением подхода DDD.

У меня остались также холиварные вопросы к вам. Как считаете:

  • Передавать в юзкейсы структуру или поля по отдельности?

  • Должно ли хранилище, в виде БД например, иметь валидацию данных? Операции по крону? Дефолтные значения полей?

  • Транзакции: где их начинать/заканчивать?

  • Когда и где вводить versioning: в HTTP‑уровне, в домене (разные агрегаты) или в репозиториях (Multi‑tenant)?

  • Должны ли доменные ошибки возвращать rich‑error (с кодом/контекстом) или достаточно обычных error с текстом?

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии3

Мои коллеги по ИТ-компании "Криптонит" пишут на Go. Я попросила их придумать ошибку — сможете её найти? Ждём в комментариях ваши варианты.

package main

import "fmt"

type User struct {
 name string
 meta map[string]string
 }

func (u *User) SetMeta(key, value string) {
 u.meta[key] = value
 }

func main() {
 u := &User{name: "Alice"}
 u.SetMeta("role", "admin")
 fmt.Println("Meta:", u.meta)
 }

.

.

.

ОСТОРОЖНО! ДАЛЬШЕ СПОЙЛЕР

В main() мы создаём указатель на User, но не инициализируем вложенную map[string]string (Meta)

Присвоение значения через u.Meta[key] = value, вызовет панику (panic: assignment to entry in nil map), потому что u.Meta всё ещё nil, и в Go нельзя присваивать значения в nil-мапу.

Одним из вариантов было бы добавить функцию NewUser(), создавать пользователя через нее, и сразу инициализировать мапу:

 func NewUser(name string) *User {
 return &User{
 name: name,
 meta: make(map[string]string),
 }
 }

func main() {
 u := NewUser("Alice")
 u.SetMeta("role", "admin")
 fmt.Println("Meta:", u.meta)
 }

Второй вариант решения изменить SetMeta что бы инициализировать мапу, если она равна nil

 func (u *User) SetMeta(key, value string) {
 if u.meta == nil {
 u.meta = make(map[string]string)
 }
 u.meta[key] = value

Ошибку и решение нам помог составить Алексей Косов, системный инженер департамента инфраструктуры в «Криптоните». Его материал про особенности, применение, плюсы и минусы Golang можно прочитать в этой статье.

Теги:
Всего голосов 4: ↑4 и ↓0+4
Комментарии4

Всем привет. В свободное время создаю игру, хотел привлечь студентов для реальной практики, которую студенту без опыта получить практически нереально (опробовал на себе лет 10 назад), знал что есть такое место как GB, но и тут облом, оказывается раздел уже не актуален, где можно было бы разместить информацию о своем проекте, и привлечь молодую кровь, жаждущих практики на реальных проектах.

Но где сейчас обитает студент? Где можно рассказать о себе, и закинуть удочку для поиска интернов? Хотелось бы и собрать команду, и дать молодым специалистам возможность пополнить свое портфолио реальным кейсом. Заранее спасибо.

Теги:
Всего голосов 3: ↑1 и ↓2+1
Комментарии1

Поддержка должна быть бесплатной. Всегда!

Последнее время замечаю тенденцию, что многие хостинги и публичные облака вводят платную поддержку. 

Позиционируется поддержка как дополнительная опция и гарантия времени ответа. Но на мой взгляд это выглядит как вымогательство денег, когда компания может оказывать качественную поддержку, но если вы их не “подкупите” дополнительно, не будет.

Я основатель облака для простого деплоя проектов через Git push – Amvera Cloud. И вижу, что пользователи пишут нам в поддержку. И говоря честно – люди пишут только тогда, когда другие способы не помогли и они не знают, как решить их насущную проблему. А это значит мы не доработали и сделали что-то непонятно или неудобно. И это наша обязанность постараться им помочь. И я не вижу морального права просить за это с них деньги.

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

И главное, я не верю, что на платной поддержке можно сильно заработать. Это просто предлог, чтобы работать хуже, чем может компания.

Поддержка должна быть бесплатной, всегда, и без всяких но! 

Теги:
Всего голосов 8: ↑7 и ↓1+6
Комментарии3

Оплачиваемая стажировка Cloud.ru Camp — успей подать заявку до 12 мая 📢

Присоединяйся к Cloud.ru Camp — оплачиваемой стажерской программе, которая поможет студентам и начинающим специалистам прокачать скиллы и с головой погрузиться в IT-сферу. 

Ты можешь выбрать направления:

  • Продуктовая разработка: DevOps или Golang.

  • Кибербезопасность: мониторинг событий и автоматизация или сертификация программных продуктов.

  • Команда внедрения: QA.

  • Технические продажи: технический менеджер клиентов.

Что тебя ждет:

  • оплачиваемая стажировка,

  • работа в реальных проектах,

  • поддержка наставников и экспертов,

  • регулярная обратная связь.

А у лучших стажеров будет возможность попасть в штат Cloud․ru.

Прием заявок открыт до 16 мая включительно, а для прошедших все этапы отбора стажировка начнется 16 июня. Пройти стажировку можно очно в офисе Cloud.ru в Москве, а также удаленно из любой точки РФ. График гибкий — от 20 часов в неделю.

📬 Подать заявку на Cloud.ru Camp

Используйте шанс погрузиться в реальные проекты, обучиться актуальным технологиям и продолжить работу в крутой компании. А о результатах и впечатлениях участников предыдущих стажировок можно почитать в статье.

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0

Есть такая мантра в гошке - "всегда обрабатывать ошибки"

А ведь так хочется чтобы они сами наверх прокидывались...

Недавно работал с либой валидатора, и нашел функцию у которой можно не проверять ошибку так как если она не отработает то приложение не запустится в любом случае

То есть ошибка равна панике

validator.Register("", func any)
if err := validator.Register("", func(
  
); err != nil {
  return err
}

Первый вариант выглядит гораздо чище, результат одинаковый, проверка идёт на старте, ошибку можно не обрабатывать

Теги:
Всего голосов 5: ↑3 и ↓2+3
Комментарии2

В 2ГИС мы пишем на Go и помогаем инженерам перейти на него с других языков. Знакомство с Go открывает возможность контрибьютить в одну из самых востребованных технологий современности. На Go написаны проекты, без которых сложно представить мир распределённых систем: K8s, CockroachDB, Badger, Prometheus, VictoriaMetrics, Jaeger, NATS, Temporal. 

Переход на Go — реальность! В карточках рассказываем, как это получилось у Саши

Хочешь так же? Прямо сейчас ищем ребят с Java и C#.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии8