Безопасные часовые пояса в Go благодаря типам
Matthew Halpern показал интересный подход к работе со временем в Go: библиотека Meridian делает часовой пояс частью *типа*. Это решает давнюю боль - потерю таймзоны при передаче time.Time между функциями, БД и сервисами.
Зачем это нужно: стандартный time.Time не хранит исходный часовой пояс. Из-за этого легко получить баги: некорректные дедлайны, неверные расчёты, ошибки в биллинге. Meridian решает проблему через generics:
Time[TZ] — это время, привязанное к конкретной зоне.
Например: et.Time (America/New_York), pt.Time (America/Los_Angeles), utc.Time и т.д.
Что это даёт:
- компилятор не позволит смешать ET и PT случайно
- подпись функции сама объясняет, в каком поясе она работает
- преобразования зон делаются явно: pt.FromMoment(etTime)
- внутреннее хранение остаётся в UTC, но тип всегда «знает», какая зона ему принадлежит
Операции между разными зонами запрещены — если нужно сравнение, используется общий интерфейс Moment с получением UTC().
Итог: Meridian превращает таймзоны из хаоса в строгую систему типов. Ошибки ловятся на этапе компиляции, а код становится самодокументируемым.
Источник: matthewhalpern.com/posts/golang-type-safe-timezones
Matthew Halpern показал интересный подход к работе со временем в Go: библиотека Meridian делает часовой пояс частью *типа*. Это решает давнюю боль - потерю таймзоны при передаче time.Time между функциями, БД и сервисами.
Зачем это нужно: стандартный time.Time не хранит исходный часовой пояс. Из-за этого легко получить баги: некорректные дедлайны, неверные расчёты, ошибки в биллинге. Meridian решает проблему через generics:
Time[TZ] — это время, привязанное к конкретной зоне.
Например: et.Time (America/New_York), pt.Time (America/Los_Angeles), utc.Time и т.д.
Что это даёт:
- компилятор не позволит смешать ET и PT случайно
- подпись функции сама объясняет, в каком поясе она работает
- преобразования зон делаются явно: pt.FromMoment(etTime)
- внутреннее хранение остаётся в UTC, но тип всегда «знает», какая зона ему принадлежит
Операции между разными зонами запрещены — если нужно сравнение, используется общий интерфейс Moment с получением UTC().
Итог: Meridian превращает таймзоны из хаоса в строгую систему типов. Ошибки ловятся на этапе компиляции, а код становится самодокументируемым.
Источник: matthewhalpern.com/posts/golang-type-safe-timezones
👍15❤1🌚1
Долгое время он был «уверенным мидлом».
Умел писать фичи, работал с Go, microservices, немного разбирался в распределённых системах.
Но каждый раз, когда он пытался выйти на senior-позицию, всё заканчивалось одинаково:
Он умел делать, но не умел объяснять.
- System design?
- Trade-off'ы?
- Архитектура распределённых систем?
- Конкурентность?
- Сетевые протоколы?
На собеседованиях он будто терял почву под ногами.
Знания были, но целостной картины - нет.
В какой-то момент он решил изменить ситуацию.
И вот путь, который реально сработал — и привёл его к первому офферу Senior Backend Engineer (Go).
Что стало переломным моментом
Он не хотел буткемпов, марафонов и длинных лекций.
Ему нужны были:
- чёткие, короткие объяснения
- визуализации
- практика
- реальные архитектурные примеры
И именно там у него впервые сложилась цельная картина системной архитектуры.
Ниже - точная последовательность курсов, которые он прошёл.
1. Grokking the System Design Interview
Этот курс дал ему главное — структуру мыслей.
До: он уходил в детали и путался.
После: действовал по чёткому фреймворку:
1. Уточнение требований
2. Компоненты
3. Масштабирование
4. Trade-off’ы
В интервью ему особенно помогли примеры из курса:
- rate limiting
- sharding
- caching
- consistent hashing
- message queues
- fan-out patterns
Это был фундамент, который дал более половины успеха.
2. Grokking Modern System Design
Этот курс научил его думать как инженер распределённых систем.
Он разобрал:
- push vs pull модели
- когда выбирать gRPC или REST
- backpressure
- идемпотентные консьюмеры
- стратегии retry и DLQ
- eventual vs strong consistency
Для Go-разработчика это оказалось очень ценным.
3. System Design: Scalability & Distributed Systems Guide
Курс поднял его "архитектурный словарь" на новый уровень.
Он научился говорить как сеньор:
Не только *что* сделать, но *почему*.
Интервьюеры особенно впечатлялись фразами вроде:
> «Здесь нужен write-ahead log для гарантий durability.»
> «Это thundering herd, понадобится request coalescing.»
Именно такие ответы добавляют вес.
4. Concurrency in Go
Поскольку позиция была Go-ориентированной, ему нужно было подтянуть конкурентность.
Курс дал ему:
- worker pools
- пайплайны
- управление context
- каналы vs мьютексы
- deadlocks, races
- архитектуру rate limiters
На интервью ему встретился вопрос:
> «Спроектируй rate limiter в Go.»
Он ответил спокойно — потому что уже делал это в курсе.
5. Grokking the Behavioral Interview
Он думал, что поведенческие вопросы — вторичны.
Оказалось — нет.
Этот курс помог ему собрать истории про:
- конфликты
- провалы
- лидерство
- сложные решения
- ответственность
- коммуникацию
Он подготовил несколько универсальных историй и использовал их в разных компаниях.
Его стратегия подготовки
1) Один system design в день
Тренировал структуру, а не заучивал решения.
2) Один backend-топик в день
Например:
- circuit breaker
- sharding
- replication
- load balancing
- consensus
3) Go: конкуренция, профилирование, память
Углубление того, что отличает senior Go engineer.
4) Поведенческие ответы
Отточенные истории.
5) Мок-интервью
Чтобы снять стресс и уверенно излагать мысли.
На финальном интервью его попросили:
> «Спроектируй систему реальной-временной доставки событий (похожа на pub/sub).
> Нужны масштабируемость и надёжность.»
Несколько месяцев назад он бы провалился.
А теперь спокойно разобрал:
- partitions
- consumer groups
- горизонтальное масштабирование
- backpressure
- retry logic
- идемпотентность
- мониторинг
Итог
Он наконец выучил то, что обычно знают senior-инженеры:
- системное мышление
- понимание распределённых систем
- объяснение архитектурных решений
- trade-off’ы
- чёткая коммуникация
Если кто-то застрял между middle и senior — его опыт показывает, что выбраться можно. Точно так же.
Читать
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🤣5❤4🔥2🥴1
🚀 Portal - open-source хостинговая сеть без разрешений, которая превращает локальный проект в публичный веб-эндпоинт
Portal - это интересный инструментарий на Go, который позволяет развернуть ваш локальный сервис в интернет без сложных настроек.
По сути, это сеть открытого хостинга, где вы можете:
- поднять любой локальный проект и сразу получить публичный URL
- делиться API, микросервисами или демо без деплоя
- проксировать запросы с минимальной задержкой
- использовать современный p2p-подход без централизованного контроля
Идеально для быстрого прототипирования, демонстраций, внутренних сервисов, интеграций и тестирования.
Открыть локалхост в интернет стало ещё проще.
Если вы работаете с Go или часто делаете демо — попробуйте Portal.
https://github.com/gosuda/portal
#golang
Portal - это интересный инструментарий на Go, который позволяет развернуть ваш локальный сервис в интернет без сложных настроек.
По сути, это сеть открытого хостинга, где вы можете:
- поднять любой локальный проект и сразу получить публичный URL
- делиться API, микросервисами или демо без деплоя
- проксировать запросы с минимальной задержкой
- использовать современный p2p-подход без централизованного контроля
Идеально для быстрого прототипирования, демонстраций, внутренних сервисов, интеграций и тестирования.
Открыть локалхост в интернет стало ещё проще.
Если вы работаете с Go или часто делаете демо — попробуйте Portal.
https://github.com/gosuda/portal
#golang
🤔4❤1👍1
This media is not supported in your browser
VIEW IN TELEGRAM
В Go все циклы строятся через одно ключевое слово - for.
Чтобы пройтись по слайсу, используй конструкцию for range, она сразу даёт доступ к элементам без лишнего шума.
Просто, читаемо и удобно для повседневных задач.
В Go все циклы строятся через одно ключевое слово - for:
Циклы в Go через for и range
names := []string{"Alice", "Bob"}
for _, name := range names {
fmt.Println(name)
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣22👍10❤3🥴2👏1
Предлагаем размяться и проверить свои навыки. Ответы есть, но подглядывать во время решения — неспортивно ⬇️
Подписывайтесь:
Please open Telegram to view this post
VIEW IN TELEGRAM
🥴4👍1🔥1
Инструмент betteralign анализирует ваш Go-код и автоматически определяет структуры, которые занимают больше памяти из-за неэффективного порядка полей. Он показывает, сколько памяти можно сэкономить, и может сам отсортировать поля в оптимальном порядке.
Что умеет betteralign
- Находит структуры, где изменение порядка полей уменьшит память и уберёт паддинги
- Показывает размер структуры и количество pointer bytes (важно для работы GC)
- Может автоматически отсортировать поля (`-apply`), сохраняя комментарии
- Пропускает автогенерируемые файлы, тесты и структуры с пометкой
betteralign:ignore Почему это полезно
- Экономит память при работе с большим количеством структур
- Улучшает эффективность кода без ручного анализа
- Подходит для высоконагруженных и производительных Go-приложений
Как использовать
go install github.com/dkorunic/betteralign/cmd/betteralign@latest
betteralign ./...
# автоматическое исправление:
betteralign -apply ./...
github.com/dkorunic/betteralign
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥3❤2🤔2
🌀 Vuego - шаблонизатор для Go, основанный на модели документа (DOM).
Вдохновлён синтаксисом и поддерживает подмножество его возможностей.
👉 GitHub-репозиторий: https://github.com/titpetric/vuego
#golang
Вдохновлён синтаксисом и поддерживает подмножество его возможностей.
👉 GitHub-репозиторий: https://github.com/titpetric/vuego
#golang
🔥3👍1🥰1
Настройка
git config --global user.name "Name" — задать имя git config --global user.email "email" — задать почту git config --list — показать настройки Старт
git init — создать репозиторий git clone url — клонировать репо Стейджинг и коммиты
git status — статус git add . — добавить все изменения git reset file — убрать из стейджа git commit -m "msg" — коммит git commit --amend — исправить последний коммит Ветки
git branch — список git branch name — создать git checkout -b name — создать и перейти git branch -d name — удалить Merge и Rebase
git merge branch — слить ветку git merge --abort — отменить git rebase branch — перебазирование История
git log --oneline — компактная история git log --graph --all — граф git diff — показать изменения Откат
git restore file — вернуть файл git reset --soft HEAD~1 — откатить коммит, сохранить изменения git reset --hard HEAD~1 — откатить и удалить изменения git clean -f — удалить лишние файлы Удалённые репозитории
git remote -v — список git push origin branch — запушить git pull — получить изменения git fetch — только забрать Теги
git tag — список git tag name — создать git push origin --tags — отправить теги Stash
git stash — сохранить изменения git stash list — список git stash apply — применить Поиск и анализ
git blame file — кто менял строки git grep "text" — поиск git bisect — бинарный поиск бага Продвинутое
git cherry-pick commit — взять коммит git revert commit — отменить коммит через новый git submodule add url — добавить сабмодуль Полезно сохранить под рукой.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤4🔥3
Docker поддерживает несколько сетевых моделей - от полной изоляции до работы напрямую с сетью хоста. Выбор нужного варианта влияет на безопасность, производительность и масштабируемость приложения.
1) Bridge (по умолчанию)
→ Docker создаёт виртуальный мост docker0.
→ Контейнеры общаются друг с другом по внутренним IP.
→ Чтобы получить доступ извне, нужно пробрасывать порты (-p 8080:80).
→ Идеально для локальной разработки и одиночных хостов.
2) Host
→ Контейнер использует сетевой стек хоста напрямую.
→ Нет виртуальной сети и NAT - максимум производительности.
→ Минимальная изоляция.
→ Применяется для мониторинга, логгинга, высокоскоростных сервисов.
3) None
→ У контейнера вообще нет сети.
→ Нет доступа ни к интернету, ни к другим контейнерам.
→ Используется для задач, где требуется полная изоляция.
4) Overlay
→ Сеть, работающая поверх нескольких хостов или в Docker Swarm.
→ Контейнеры на разных серверах могут общаться как будто они в одной сети.
→ Основа для распределённых микросервисных систем.
5) Macvlan
→ Каждый контейнер получает свой MAC-адрес и «видится» как отдельная машина.
→ Контейнеры становятся полноценными участниками вашей физической сети.
→ Полезно, когда контейнеры должны быть напрямую доступны по LAN.
6) IPvlan
→ Похоже на Macvlan, но проще управляет IP-адресами на уровне L3.
→ Хорошо подходит для масштабных систем с жёсткими требованиями к маршрутизации.
Дополнительно:
Сервис-дискавери
→ Внутри Docker работает собственный DNS - контейнеры могут общаться по имени сервиса, а не по IP.
Проброс портов
→ Стандартный вариант доступа извне:
-p 8080:80
Драйверы сетей
→ bridge
→ host
→ overlay
→ macvlan
→ ipvlan
Как выбрать модель?
→ Bridge — одиночный хост, локалка.
→ Host — максимум скорости, минимум изоляции.
→ Overlay — распределённые микросервисы.
→ Macvlan — нужны «настоящие» сетевые адреса.
→ None — полная изоляция без сети.
Правильный выбор сетевой модели Docker напрямую влияет на безопасность, структуру архитектуры и производительность. Чтобы уверенно работать с контейнерами и микросервисами - эти модели нужно знать.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍5
Как создать эффективное REST API или оптимизировать его? Что сделать для ускорения Redis? Какие секреты скрываются под капотом Android? Что делать при конфликте стилей в микрофронтендах? Что поможет провести продуктивное кросс-ревью в команде?
Своим опытом в самых разных сферах делятся frontend-разработчики, системные аналитики, разработчики под Android и iOS из команды ПСБ.
Читайте в блоге ПСБ на Хабре, делитесь в комментариях своим мнением и опытом!
Своим опытом в самых разных сферах делятся frontend-разработчики, системные аналитики, разработчики под Android и iOS из команды ПСБ.
Читайте в блоге ПСБ на Хабре, делитесь в комментариях своим мнением и опытом!
В Go, чтобы проверить тип ошибки, обычно используют
errors.As, но это требует заводить временные переменные и делает код громоздким. В статье предлагается более удобный подход - обёртка AsType, которая сразу возвращает ошибку нужного типа.Зачем это нужно:
• Код становится короче: никаких
var e *MyError заранее. • Проверка выглядит чище:
if e := errors.AsType[*MyError](err); e != nil { … } • Удобно, когда нужно последовательно обработать несколько типов ошибок.
Идея не ломает существующий подход, а делает его проще и безопаснее - меньше шаблонного кода, больше читаемости.
Кому полезно: всем, кто пишет стабильный продакшн-код на Go и работает с elaborate-ошибками.
https://antonz.org/accepted/errors-astype/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥23❤1🥰1👏1
This media is not supported in your browser
VIEW IN TELEGRAM
Вот хитрая задача по Go - идеально, чтобы проверить, насколько хорошо ты понимаешь устройство слайсов, capacity и поведение append.
Подумай, что именно выведет программа и почему.
package main
import "fmt"
func main() {
a := []int{10, 20, 30, 40}
b := a[:2] // [10 20]
c := append(b, 99) // что происходит с a?
a[1] = 777 // влияет ли это на b и c?
c = append(c, 555) // а теперь?
fmt.Println("a:", a)
fmt.Println("b:", b)
fmt.Println("c:", c)
Please open Telegram to view this post
VIEW IN TELEGRAM