myStack
878 subscribers
754 photos
15 videos
24 files
304 links
Меня зовут Ростислав и я разработчик.

Это мой личный блог.

Я пишу на Go, читаю книги про технологии и пишу об этих и других вещах сюда.


Книги:
https://bit.ly/rostislav-books

Личка:
https://t.me/Rostislaved

Сайт:
Rostislav.me
Download Telegram
Чистка ноута

Во второй раз поставил:
node_exporter
prometheus
grafana

чтобы посмотреть, как поможет чистка ноута и замена термопасты.

Судя по графику разница где-то 7 градусов. Хотя, возможно, еще повлияла сама перезагрузка: я редко перезагружаю, может какие процессы фоновые вносили свой вклад. Поэтому построил дополнительную метрику T/cpu. Возможно странная, но вроде логичная. Разница получилась 9%.

Грустно всё не у apple.
👀4🔥111
Потребление памяти при декодинге json стандартной либой

Создал два файла с json'ами по 65 МБ каждый
В первом слайс сложной структуры (~ 70полей разных типов)
Во втором слайс структуры из одного интового поля

Парсил их в коде и смотрел потребление памяти.

- Значения для второго файла - в скобках
- Alloc - размер всех объектов в памяти программы
- Sys - память зарезервированная у ОС

1. json.NewDecoder
Alloc х4.6 (x3) от размера файла
func func1() {
printMemStats() // Alloc/Sys: 0/7 MiB (0/7 MiB)

f, err := os.Open("file.json")
if err != nil {
panic(err)
}

printMemStats() // Alloc/Sys: 0/7 MiB (0/7 MiB)

var dto Dto

err = json.NewDecoder(f).Decode(&dto)
if err != nil {
panic(err)
}

printMemStats() // Alloc/Sys: 304/317 MiB (197/401 MiB)
}


2. json.Unmarshal
Alloc x2.2 (x2) от размера файла
func func2() {
printMemStats() // Alloc/Sys: 0/7 MiB (0/7 MiB)

b, err := os.ReadFile("file.json")
if err != nil {
panic(err)
}

printMemStats() // Alloc/Sys: 65/75 MiB (65/76 MiB)

var dto Dto

err = json.Unmarshal(b, &dto)
if err != nil {
panic(err)
}

printMemStats() // Alloc/Sys: 145/191 MiB (134/232 MiB)
}


3. json.Unmarshal + runtime.GC()
Alloc x2.2 (x2) от размера файла
func func3() {
printMemStats() // Alloc/Sys: 0/7 MiB (0/7 MiB)

b, err := os.ReadFile("file.json")
if err != nil {
panic(err)
}

printMemStats() // Alloc/Sys: 65/76 MiB (65/76 MiB)

var dto Dto

err = json.Unmarshal(b, &dto)
if err != nil {
panic(err)
}

printMemStats() // Alloc/Sys: 145/190 MiB (145/190 MiB)

b = nil
runtime.GC()

printMemStats() // Alloc/Sys: 47/191 MiB (38/232 MiB)

fmt.Println(dto.Objects[0].Field)
}


go1.25.3

Без вывода, просто значения для понимания порядка величин
3
Мой любимый линтер - это wsl, который заставляет вставлять пустые строки между разными логическими блоками. Но теперь у него появился конкурент😈

noinlineerr

Disallows inline error handling:
if err := ...; err != nil {
54😁4
Месяц как я слез с иглы подписки на телеграм премиум и обнаружил, что вот это - максимальный размер поста с картинкой.

А как постить?

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc et enim luctus, condimentum arcu ut, volutpat neque. Donec et metus ante. Integer ipsum elit, ultrices et dignissim non, posuere at quam. In auctor ipsum eu eros fringilla, quis fringilla enim fringilla. Suspendisse eget lectus sed nibh cursus commodo non in odio. Etiam urna ligula, luctus eget est quis, vehicula pharetra lectus. Sed dictum elit massa. Integer gravida fringilla dolor, vel feugiat nunc congue fringilla. Suspendisse varius odio eu pellentesque euismod. Nam vel mauris vel urna egestas pellentesque eget vitae lacus. Phasellus fermentum lacinia est non vestibulum. Donec id ornare lectus. Integer purus orci, eleifend a mi commodo, blandit ultrices odio. Sed pretium tortor dui, a auctor enim pellentesque nec. Nunc nulla felis, mollis sit amet convallis eu, dignissim est. Pellentesque hendrerit eleifend.
2
#книги
Chris Sanders - Practical Packet Analysis
18.08.2025 - 31.10.2025

Первое, что хочу сказать, что у этой книги название вводящее в заблуждение. Может показаться, что книга по каким-то глубоким исследованиям пакетов, но фактически это книга по сетям с акцентом на то, чтобы руками в wireshark'е смотреть, как происходят различные процессы вроде tcp handshak'ов, retransmission'ов, запросов http, ответов итд итп.

Это прекраснейшная книга и на данный момент это мой топ 1 кандидат в "первую книгу по сетям". Мой опыт довольно травмирующий, начинал с ютуба с курса Созыкина (для меня сложно представить более бесполезный способ получения информации), потом Таненбаум (не начинайте изучать что-либо с больших книг), потом Michael W. Lucas - Networking for Systems Administrators (в целом норм, но не как первая) и вот сейчас эта книга. Ну и конечно параллельно с работой все происходило, хотя я всё же разработчик, а не сетевой инженер. А еще заглядывал в "сети для самых маленьких" и не понял, кто подразумевается по маленьким.. Но явно не новичок в сетях

По главам так:
1-2: вводные про то, как и где эти пакеты получать - какой-то закос под хакерство что ли или попытка оправдать название
3-5: wireshark
6: command line: tcpdump, tshark
7-9: tcp\ip стек - заголовки и основные механизмы их работы все с примерами в wireshark'е как все происходит. Отличные главы и максимально полезные.
10-12: Всякие кейсы в wiresharke: почему не открывается сайт, почему медленный интернет итд. Тоже отличные главы. По сути практика знаний из глав 7-9

Из минусов:
- Книга 2017 года. В целом это практически не чувствуется: пару ссылок устарело, устройство в примере wifi адаптера старенькое, поколения wifi перечислены до 802.11n (wifi 4, а сейчас уже 7 начинает продаваться). Но это не влияет ни на что
- Книга с акцентом на windows. Тоже особо ни на что не влияет, но некоторый софт, который упоминается - для винды.

В остальном отличная книга! Рекомендую
👍4🔥2111
hyperfine

https://github.com/sharkdp/hyperfine

Нашел приятную утилиту - hyperfine (rust). Она нужна чтобы бенчмаркать разные команды в терминале.

Измерим, сколько выполняется sleep 0.1:
 > hyperfine "sleep 0.1"                         
Benchmark 1: sleep 0.1
Time (mean ± σ): 102.0 ms ± 1.1 ms [User: 0.6 ms, System: 1.4 ms]
Range (min … max): 100.5 ms … 104.3 ms 29 runs

Выполняется 100 мс (кто бы мог подумать).

Также можно запустить несколько команд и тогда hyperfine еще покажет насколько самая быстрая была быстрее других:
 > hyperfine "sleep 0.1" "sleep 1.1" "sleep 1.2" 
Benchmark 1: sleep 0.1
Time (mean ± σ): 101.9 ms ± 1.1 ms [User: 0.5 ms, System: 1.4 ms]
Range (min … max): 100.2 ms … 103.4 ms 29 runs

Benchmark 2: sleep 1.1
Time (mean ± σ): 1.102 s ± 0.001 s [User: 0.001 s, System: 0.001 s]
Range (min … max): 1.100 s … 1.103 s 10 runs

Benchmark 3: sleep 1.2
Time (mean ± σ): 1.201 s ± 0.001 s [User: 0.001 s, System: 0.001 s]
Range (min … max): 1.200 s … 1.203 s 10 runs

Summary
sleep 0.1 ran
10.81 ± 0.12 times faster than sleep 1.1
11.79 ± 0.13 times faster than sleep 1.2
5👍32
golangci-lint config v1.1.0 (for golangci-lint v2.6.0)


https://github.com/rostislaved/golangci-lint-config

Конфигурация golangci-lint, в которой включено как можно больше проверок.

Зачем?
- В репозитории golangci-lint нет конфига с максимальным числом включенных линтеров, а включение всех линтеров не включает все правила внутри каждого линтера (например gocritic и revive).
- Более того, каждый линтер кроме отдельно включаемых правил имеет "настройки", которые тоже по умолчанию могут быть выключены.

Что в конфиге
- В этом конфиге по возможности включено максимальное число линтеров и правил линтеров
- Для некоторых линтеров включены дополнительные настройки, например:
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`.
# Such cases aren't reported by default.
# Default: false
check-blank: true

- всё же это opinionated конфиг и некоторые линтеры в нем отключены. Там где это сделано есть комментарий о причине отключения и можно легко его включить.

P.S.
К сожалению мейнтейнер golangci-lint не хочет добавлять пример конфига со всеми дефолтными настройками и предлагает самостоятельно следить за changlog'ом, чтобы не пропустить новые правила и настройки
541
OpenAPI 101

https://github.com/rostislaved/open-api-101

Репозиторий с примерами кода на основе трёх самых популярных библиотек для работы с OpenAPI:
- go-swagger
- oapi-codegen
- ogen

Зачем?
Документация у разных библиотек разная и часто довольно неочевидная, из-за чего сложно сделать даже самый базовый пример, который работает. В этом репозитории представлены как раз такие примеры.
18👍31
Купил эту мышку

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

А в целом мышка понравилась. Из побочных плюсов type-c коннектора - его можно вставлять в разъем для зарядки мышки, чтобы не терялся при переноске. Удобно т.к. специального отсека для него никогда не было.

Ну и материал выглядит более живучим, чем резина в прошлой модели
13
Либа конфига

При организации пакета конфига часто используют следующий вариант:
package config

type Config struct {
Database DatabaseConfig
Kafka KafkaConfig
}

type DatabaseConfig struct { /// }

type KafkaConfig struct { /// }

Пакет config, который содержит главную структуру конфига, а также все подструктуры.

Минус этого варианта в том, что пакет, например, бд будет делать импорт DatabaseConfig из пакета общего конфига, пакет кафки - KafkaConfig итд.

Гораздо более логичен вариант, когда каждая подструктура конфига лежит в своем пакете, а в пакет общего конфига всё это импортируется:
package config

type Config struct {
Database database.Config
Kafka kafka.Config
}


Однако, тогда в подструктурах могут быть теги от либы, считывания конфига, что делает хоть и неявную, но все же зависимость от либы конфига:
package database

type Config struct {
User string `yaml:"user"`
Password string `env:"password"`
}


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

Из-за отсутствия этой возможности и некоторых других я написал свою либу для конфига. Она по большей части основывается на koanf - имхо лучшей либе для конфига в go (у нее прекрасный интерфейс, намного более красивый, чем у viper) и добавляет некоторые фичи.

Чего не хватало в существующих:
- Возможности задать название env'а не в тегах структуры, а в самом файле конфига {"env": "DB_PASSWORD"}
- Ошибки, если поле в структуре есть, а в ямле отсутствует (чтобы забытое значение не превратилось в zero-value)
- Ошибки, если поле в ямле есть, а в структуре отсутствует (чтобы мусора в ямле не было)
- Опционального считывания. Если поле в структуре - указатель, то ошибки не будет при отсутствии его в ямле

Также либа поддерживает всё, что поддерживает сам koanf

https://github.com/rostislaved/cleanconfig
👍42
Go Clean Architecture Template v0.0.4 (15.12.2025)

https://github.com/rostislaved/go-clean-architecture


- Сборка и запуск приложения теперь не в main, а в app.New() и app.Start()
- Файл конфига toml -> yaml
- Структуры конфигов находятся каждая в своем пакете, а не все в общем (стало возможно полностью, благодаря новой либе конфига)
- Обновлен конфиг линтеров до 2.6.0 (https://github.com/rostislaved/golangci-lint-config)
😁6👍1
Telegram Export Parser

Написал небольшой скрипт, который парсит экспорт чата телеграма

https://github.com/rostislaved/telegram-export-parser

Основная ценность скрипта в структуре, в которую парсится экспорт чата, она нетривиальная. Кроме нее там просто json.Unmarshal

- Запись только текста сообщений в файл (converted.txt).
- Печать сообщений в stdout в немного отформатированном виде
- Можно задать дату, сообщения до которой игнорируются
- Можно задать число сообщений, которое будет обрабатываться

Я это написал, чтобы в Gemini загружать экспорт чата и задавать по нему вопросы
1👍13😨2
vscode

сегодня я узнал, что режим сравнения в VS code можно запустить из терминала вот так:
code --diff ./config ./config_bak 


что конкретно мне намного приятнее, чем через UI натыкивать:
Select for Compare и Compare with Selected
👍54😁31
#книги
How To DeFi: Begginer
31.10.2025 - 30.12.2025

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

В целом неплохо.

Из минусов:
- не нужны скрины создания аккаунта
- некоторые DeFi apps скорее всего уже устарели и лучше бы рассматривались концепции, а конкретные DeFi apps просто перечислялись
- возможно выбор DeFi apps был не случаен и как-то связан с авторами книги
- Не первое, что можно читать в крипте. Лучше уже понимать, хотя бы примерно, как работает биткойн\эфир\смартконтракты

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

Чем больше читаю, тем больше ценю не огромные книги, а именно короткие с поверхностным обзором темы. После таких можно точечно почитать нужное уже в больших или загуглить. То есть сперва строится верхнеуровневая картина в голове, в потом детализируются нужные моменты.
👍32
Почти конец года. Первую книгу в этом году я начал читать 2го января, а последнюю закончил 30го декабря. Всего 7 книг. Немало вроде как, но и немного. Когда-то было даже 15 штук. Но в 24м было всего 3. Вот такая статистика.
👍1241
slice-analyzer

Написал крошечный пакет для печати внутренней структуры слайса

https://github.com/rostislaved/slice-analyzer

package main

import (
sliceanalyzer "github.com/rostislaved/slice-analyzer"
)

func main() {
s1 := []int{1, 2, 3}
sliceanalyzer.Print(s1, "s1")

s2 := append(s1, 4, 5)
sliceanalyzer.Print(s2, "s2")

s3 := s2[1:4]
sliceanalyzer.Print(s3, "s3")
}


[s1]
┌───────┬───┬───┬───┐
│ slice │ 1 │ 2 │ 3 │
│ array │ 1 │ 2 │ 3 │
│ index │ 0 │ 1 │ 2 │
└───────┴───┴───┴───┘
┌─────────────┬──────────────┐
│ pointer │ 0xc00001a108 │
│ pointer dec │ 824633827592 │
│ len │ 3 │
│ cap │ 3 │
└─────────────┴──────────────┘

[s2]
┌───────┬───┬───┬───┬───┬───┬───┐
│ slice │ 1 │ 2 │ 3 │ 4 │ 5 │ ▒ │
│ array │ 1 │ 2 │ 3 │ 4 │ 5 │ 0 │
│ index │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │
└───────┴───┴───┴───┴───┴───┴───┘
┌─────────────┬──────────────┐
│ pointer │ 0xc0000221b0 │
│ pointer dec │ 824633860528 │
│ len │ 5 │
│ cap │ 6 │
└─────────────┴──────────────┘

[s3]
┌───────┬───┬───┬───┬───┬───┐
│ slice │ 2 │ 3 │ 4 │ ▒ │ ▒ │
│ array │ 2 │ 3 │ 4 │ 5 │ 0 │
│ index │ 0 │ 1 │ 2 │ 3 │ 4 │
└───────┴───┴───┴───┴───┴───┘
┌─────────────┬──────────────┐
│ pointer │ 0xc0000221b8 │
│ pointer dec │ 824633860536 │
│ len │ 3 │
│ cap │ 5 │
└─────────────┴──────────────┘
🔥2361🤩1
придумал, как понять, один и тот же ли underlying array за слайсами - по адресу последнего элемента массива под слайсами!

У двух разных слайсов, которые имеют один и тот же underlying array он будет одинаковым.

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

UPD: заявление я сделал сильное) Данный подход не сработет для слайсов созданных через full slice expression ( s[low:high:max] )
🔥10
Лучшие актуальные книги по Golang

📦 База

- Jon Bodner - Learning Go (2024)
- Teiva Harsanyi - 100 Go Mistakes and How to Avoid Them (2022)

🌐 Веб-разработка
- Alex Edwards - Let's Go (2025)
- Alex Edwards - Let's Go Further (2025)
- Hüseyin Babal - gRPC Microservices in Go (2023)

🚀 Advanced topics
- James Cutajar - Learn Concurrent Programming with Go (2024)

- Thorsten Ball - 1. Writing an Interpreter in Go (2020)
- Thorsten Ball - 2. Writing A Compiler In Go (2020)

- Adam Woodbeck - Network Programming with Go (2021)

🗂 Чуть менее актуальные:
- Alan A. A. Donovan, Brian W. Kernighan - The Go Programming Language (2015)
Классика. Хорошая книга, но уже не такая актуальная. Можно дополнительно смотреть в ней интересующие главы.

- McGavren Jay - Head First Go (2019)
Не самая актуальная, но может быть полезной из-за акцента этой серии книг на простоту
16🔥33💩1
Clean Code 2nd Edition

Оказывается, 18.10.2025 вышло второе издание Чистого кода.

Вот как описаны изменения в предисловии:
Примечание о более ранних главах

Я позволил себе значительную свободу в отношении более ранних глав, единственным автором которых был я сам. Во многих случаях они были полностью переписаны или весьма существенно отредактированы. Большинство авторов глав, которые писал не я, представили для этой работы вторые издания своих глав.

Структура этой книги

Пожалуй, самым большим изменением между первым и вторым изданиями является структура материала. Я разделил книгу на четыре части: Код, Проектирование, Архитектура и Мастерство.
Эти части не являются независимыми друг от друга.

Часть I: Код в значительной степени зависит от Части II: Проектирование. Читая Часть I, вы встретите множество ссылок на принципы и стратегии проектирования, которые описаны в Части II. Я рекомендую использовать Часть II как справочник, к которому можно обращаться во время чтения Части I. Затем, закончив с Частью I, вам следует прочитать Часть II целиком.

Часть III: Архитектура представляет собой тщательно отредактированный и сокращённый набор фрагментов из моей книги Clean Architecture. И снова, рассматривайте её как справочный материал, помогающий лучше понять Часть I. Однако она также может использоваться самостоятельно — как простое введение в архитектурные принципы более высокого уровня.

Часть IV: Мастерство — это, в свою очередь, тщательно отредактированный и сокращённый набор фрагментов из моей книги Clean Craftsmanship — в частности, главы, посвящённые этике разработки программного обеспечения. Она включена для того, чтобы подчеркнуть: написание чистого кода является этическим императивом.
1🔥6🤯2💩2🙏1
Reading queue

У меня большая база книг, разделенная по темам. Она обладает следующими свойствами:
- Книги скорее всего хорошие (я определяю это по рейтингу амазона и goodreads). Хотя часть книг есть и плохих, но это, если мне все равно надо зачем-то в них смотреть
- Файлы книг там в лучшем качестве, что я смог найти. И мне не надо опять проделывать эту работу
- Книги в быстром доступе для меня, если надо что-то вспомнить

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

А вторая существовала до текущего момента. Я забываю, какие книги я сохраняю в эту базу и какие из них я хотел бы прочитать.

Много раз было такое, что я находил потенциально интересную книгу и думал, что надо обязательно ее прочитать, но потом понимал, что я не помню ни одного названия такой книги. Поэтому решил создать Reading queue книг, которые хочу прочитать. Идея - располагать книги отсортированными по приоритету, так я и не забуду ни о чем и в порядке не запутаюсь.

Пока составлял список, понял, что в нем определенно есть книги, до которых я все же не доберусь, но они важны, как напоминание об определенной теме, а может и доберусь когда-то. Пока только первые книги в списке имеют порядок актуальный, после первых 10 порядок случайный т.к. до них еще далеко. Порядок этот будет постепенно корректироваться.
1👍42
Chris Richardson - Microservices Patterns

Chris Richardson пишет второе издание своей книги. По планам релиз весной 2027

Ниже - что будет нового во втором издании.
tldr (полная версия в комментариях):
- Книга сильно обновлена на основе практики последних лет.

- Главный акцент - fast flow: быстрые мелкие изменения + быстрый feedback.

- Fast flow держится на трех вещах: Team Topologies, DevOps, подходящая architecture.

- Больше внимания архитектурным основам: coupling, quality attributes, устройство architecture.

- Расширен раздел про принятие решений: как выбирать между monolith и microservices, 10 сил для оценки решений, пошаговый процесс проектирования.


Особо ничего непонятно конечно, но будем думать, что там что-то нормальное
3🤣11