Компилируем Go в TypeScript 😂
Этот тул работает на уровне AST-дерева, позволяя переиспользовать бизнес-логику, алгоритмы и структуры данных между бэкендом и фронтом без переписывания руками
Исходный код этого чуда
👉 @BackendPortal
Этот тул работает на уровне AST-дерева, позволяя переиспользовать бизнес-логику, алгоритмы и структуры данных между бэкендом и фронтом без переписывания руками
Исходный код этого чуда
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
This media is not supported in your browser
VIEW IN TELEGRAM
Минималистичный клиент для SQL-баз данных
Называется Outerbase Studio:
✓ Совместим с MySQL, Postgres, SQLite и MongoDB
✓ Поддерживает сервисы вроде Turso и Cloudflare D1
✓ Доступен для Web, macOS и Windows
✓ Бесплатный и open source
→ [http://github.com/outerbase/studio]
👉 @BackendPortal
Называется Outerbase Studio:
✓ Совместим с MySQL, Postgres, SQLite и MongoDB
✓ Поддерживает сервисы вроде Turso и Cloudflare D1
✓ Доступен для Web, macOS и Windows
✓ Бесплатный и open source
→ [http://github.com/outerbase/studio]
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11
7 обязательных сложностей по времени для собесов:
1. O(1) - константное время
* Время не меняется независимо от размера входа.
* Пример: доступ к элементу массива по индексу.
2. O(log n) - логарифмическое время
* Растет медленно по мере увеличения входа. Обычно в алгоритмах, которые на каждом шаге делят задачу пополам.
* Пример: бинарный поиск в отсортированном массиве.
3. O(n) - линейное время
* Растет линейно вместе с размером входа.
* Пример: поиск элемента в массиве перебором.
4. O(n log n) - линеарифмическое время
* Растет чуть быстрее, чем линейное. Для каждого элемента входа делается логарифмическое число операций.
* Пример: сортировка массива quick sort или merge sort.
5. O(n^2) - квадратичное время
* Растет пропорционально квадрату размера входа.
* Пример: bubble sort, который сравнивает и при необходимости меняет местами каждую пару элементов.
6. O(2^n) - экспоненциальное время
* Время удваивается при добавлении каждого элемента во вход. Для больших n становится непрактично.
* Пример: генерация всех подмножеств множества.
7. O(n!) - факториальное время
* Время пропорционально факториалу размера входа.
* Пример: генерация всех перестановок множества.
👉 @BackendPortal
1. O(1) - константное время
* Время не меняется независимо от размера входа.
* Пример: доступ к элементу массива по индексу.
2. O(log n) - логарифмическое время
* Растет медленно по мере увеличения входа. Обычно в алгоритмах, которые на каждом шаге делят задачу пополам.
* Пример: бинарный поиск в отсортированном массиве.
3. O(n) - линейное время
* Растет линейно вместе с размером входа.
* Пример: поиск элемента в массиве перебором.
4. O(n log n) - линеарифмическое время
* Растет чуть быстрее, чем линейное. Для каждого элемента входа делается логарифмическое число операций.
* Пример: сортировка массива quick sort или merge sort.
5. O(n^2) - квадратичное время
* Растет пропорционально квадрату размера входа.
* Пример: bubble sort, который сравнивает и при необходимости меняет местами каждую пару элементов.
6. O(2^n) - экспоненциальное время
* Время удваивается при добавлении каждого элемента во вход. Для больших n становится непрактично.
* Пример: генерация всех подмножеств множества.
7. O(n!) - факториальное время
* Время пропорционально факториалу размера входа.
* Пример: генерация всех перестановок множества.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤2
Если protobuf уже компактный бинарный формат, есть ли вообще смысл дополнительно жать его Snappy? Вот что на самом деле делает Uber M3...
Uber M3 принимает больше миллиарда датапоинтов в секунду (масштаб реально дикий) и при этом принимает данные по HTTP/1.1 в виде Snappy-сжатого protobuf.
Protobuf сам по себе эффективный, да. Но у телеметрии есть особенность: она очень повторяющаяся. Одни и те же имена метрик, похожие наборы тегов, повторяющиеся hostnames, одинаковая структура полей в тысячах точек. Из-за этой избыточности такие данные отлично сжимаются даже быстрым алгоритмом вроде Snappy.
M3 использует Snappy-сжатый protobuf поверх HTTP для своего Prometheus remote write endpoint. Причина простая: на огромном масштабе тебе нужна компрессия, которая не станет узким местом.
* Snappy очень быстро сжимает и разжимает
* он ставит скорость выше коэффициента сжатия
* CPU-оверхед и на клиенте, и на коллекторе остается минимальным
* клиентам телеметрии не стоит жечь CPU на компрессию, когда они должны заниматься реальной работой
Забавный факт: на масштабе бутылочным горлышком становится вообще все. Ты пытаешься экономить каждый бит и каждый CPU-цикл. Нужно просто хорошо понимать кейс, замечать паттерны и выбирать то, что подходит именно тебе.
👉 @BackendPortal
Uber M3 принимает больше миллиарда датапоинтов в секунду (масштаб реально дикий) и при этом принимает данные по HTTP/1.1 в виде Snappy-сжатого protobuf.
Protobuf сам по себе эффективный, да. Но у телеметрии есть особенность: она очень повторяющаяся. Одни и те же имена метрик, похожие наборы тегов, повторяющиеся hostnames, одинаковая структура полей в тысячах точек. Из-за этой избыточности такие данные отлично сжимаются даже быстрым алгоритмом вроде Snappy.
M3 использует Snappy-сжатый protobuf поверх HTTP для своего Prometheus remote write endpoint. Причина простая: на огромном масштабе тебе нужна компрессия, которая не станет узким местом.
* Snappy очень быстро сжимает и разжимает
* он ставит скорость выше коэффициента сжатия
* CPU-оверхед и на клиенте, и на коллекторе остается минимальным
* клиентам телеметрии не стоит жечь CPU на компрессию, когда они должны заниматься реальной работой
Забавный факт: на масштабе бутылочным горлышком становится вообще все. Ты пытаешься экономить каждый бит и каждый CPU-цикл. Нужно просто хорошо понимать кейс, замечать паттерны и выбирать то, что подходит именно тебе.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍2
Uber выложили в опенсорс свою платформу метрик M3, и пока я бегло смотрел, как она устроена, наткнулся на подход под названием LTTB downsampling. Вот о чём речь...
LTTB расшифровывается как Largest Triangle Three Buckets. Это алгоритм даунсэмплинга, который помогает эффективно запрашивать и визуализировать миллионы точек таймсерий. Идея в том, чтобы сохранить визуальную форму графика, но сильно сократить число точек, которые нужно рендерить.
За счёт этого фронтенду легче: меньше точек для отрисовки и меньше данных надо гонять по сети.
Работает так: временной ряд делится на “бакеты”, и из них выбираются точки, которые сохраняют максимальную “визуальную площадь”. То есть вместо случайной выборки или простого усреднения, LTTB оставляет точки так, чтобы на графике не потерялись пики, провалы и общий тренд.
Механика простая: берутся три точки за раз (предыдущая, текущая, следующая) и считается площадь треугольника, который они образуют. Выбирается та точка, которая даёт самый большой треугольник. В итоге важные визуальные особенности переживают даунсэмплинг.
С таким подходом можно ужать 10 000 точек до 500 и всё равно получить график, который выглядит почти так же, как исходный. Помимо M3, системы вроде Grafana, InfluxDB и Prometheus тоже взяли LTTB или похожие техники даунсэмплинга.
Забавно, что такая, казалось бы, простая штука как “какие точки оставить?” внезапно превращается в реально интересную задачу.
👉 @BackendPortal
LTTB расшифровывается как Largest Triangle Three Buckets. Это алгоритм даунсэмплинга, который помогает эффективно запрашивать и визуализировать миллионы точек таймсерий. Идея в том, чтобы сохранить визуальную форму графика, но сильно сократить число точек, которые нужно рендерить.
За счёт этого фронтенду легче: меньше точек для отрисовки и меньше данных надо гонять по сети.
Работает так: временной ряд делится на “бакеты”, и из них выбираются точки, которые сохраняют максимальную “визуальную площадь”. То есть вместо случайной выборки или простого усреднения, LTTB оставляет точки так, чтобы на графике не потерялись пики, провалы и общий тренд.
Механика простая: берутся три точки за раз (предыдущая, текущая, следующая) и считается площадь треугольника, который они образуют. Выбирается та точка, которая даёт самый большой треугольник. В итоге важные визуальные особенности переживают даунсэмплинг.
С таким подходом можно ужать 10 000 точек до 500 и всё равно получить график, который выглядит почти так же, как исходный. Помимо M3, системы вроде Grafana, InfluxDB и Prometheus тоже взяли LTTB или похожие техники даунсэмплинга.
Забавно, что такая, казалось бы, простая штука как “какие точки оставить?” внезапно превращается в реально интересную задачу.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍2🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Познакомься с Devin Review: это переосмысленный интерфейс для понимания сложных PR.
Современные инструменты для код-ревью на деле не делают чтение кода проще. Devin Review прокачивает понимание и помогает перестать пропускать слоп.
Вместо алфавитного списка файлов он группирует связанные изменения и раскладывает их в логическом порядке, плюс дает короткое описание каждой группы. Отдельно умеет находить перемещенный и скопированный код, отделяя сигнал от шума.
Еще внутри есть агент, который ловит потенциальные баги и помечает их по уверенности и критичности. Причем он подсвечивает не только прямые баги, но и спорные решения/паттерны, которые потом превращаются в техдолг. Маркировка простая: красный срочно смотреть, оранжевый стоит глянуть, серый просто к сведению.
Плюс можно обсудить PR в чате с Devin, с контекстом всего репо.⌨️
Как зайти:
- прямо на devinreview.com (можно без аккаунта)
- или заменить
- или дернуть из репы:
👉 @BackendPortal
Современные инструменты для код-ревью на деле не делают чтение кода проще. Devin Review прокачивает понимание и помогает перестать пропускать слоп.
Вместо алфавитного списка файлов он группирует связанные изменения и раскладывает их в логическом порядке, плюс дает короткое описание каждой группы. Отдельно умеет находить перемещенный и скопированный код, отделяя сигнал от шума.
Еще внутри есть агент, который ловит потенциальные баги и помечает их по уверенности и критичности. Причем он подсвечивает не только прямые баги, но и спорные решения/паттерны, которые потом превращаются в техдолг. Маркировка простая: красный срочно смотреть, оранжевый стоит глянуть, серый просто к сведению.
Плюс можно обсудить PR в чате с Devin, с контекстом всего репо.
Как зайти:
- прямо на devinreview.com (можно без аккаунта)
- или заменить
github на devinreview в ссылке PR- или дернуть из репы:
npx devin-review {pr-link}Please open Telegram to view this post
VIEW IN TELEGRAM
Фан-факт: OpenAI тянет 800 млн пользователей в ChatGPT всего на одном primary PostgreSQL и 50 read-репликах 🤯
Сегодня OpenAI выкатили инженерный пост о том, как они масштабировали Postgres, чтобы обслуживать эти 800 млн пользователей: один primary и 50 мульти-региональных реплик.
Внутри разбирают свой подход к масштабированию, прокси PgBouncer, локи вокруг кэша и каскадные read-реплики. Реально выглядит аккуратно и впечатляюще.
ВОТ короткое видео на YouTube, где разбирают этот пост и раскладывают нюансы по полочкам.
Зацени, видос короткий
👉 @BackendPortal
Сегодня OpenAI выкатили инженерный пост о том, как они масштабировали Postgres, чтобы обслуживать эти 800 млн пользователей: один primary и 50 мульти-региональных реплик.
Внутри разбирают свой подход к масштабированию, прокси PgBouncer, локи вокруг кэша и каскадные read-реплики. Реально выглядит аккуратно и впечатляюще.
ВОТ короткое видео на YouTube, где разбирают этот пост и раскладывают нюансы по полочкам.
Зацени, видос короткий
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9
This media is not supported in your browser
VIEW IN TELEGRAM
Учись программированию, Cloud и DevOps через практику
Бесплатные серверы и реальные задания.
✓ Практикуй Git и Linux-серверы
✓ Создавай и тестируй ресурсы AWS без страха
✓ Kubernetes, Docker, Terraform и другое
Регистрация не нужна: вперёд
👉 @BackendPortal
Бесплатные серверы и реальные задания.
✓ Практикуй Git и Linux-серверы
✓ Создавай и тестируй ресурсы AWS без страха
✓ Kubernetes, Docker, Terraform и другое
Регистрация не нужна: вперёд
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
Если я говорю “горизонтальное масштабирование”, ты, скорее всего, автоматически думаешь про load balancer.
Вот 2 способа масштабироваться дальше, чем просто балансировщик.
При горизонтальном дублировании ты копируешь часть системы, чтобы переваривать больше нагрузки, и распределяешь работу между этими копиями.
Самый очевидный вариант горизонтального дублирования это как раз load balancer. Он:
• распределяет запросы
• видит, когда нода умерла, и убирает ее из пула
1. Competing Consumer Pattern
Суть паттерна в том, чтобы раскидать нагрузку и поднять throughput.
Идеально, когда у тебя есть обработчики задач. Например, система должна давать пользователям импортировать и обрабатывать большие файлы.
Ты кладешь каждый загруженный файл в очередь, и много консьюмеров “соревнуются” за то, кто заберет задачу и обработает ее.
2. Read Replicas для read-нагрузки
Чтобы разгрузить primary базу по чтениям, ты поднимаешь read replicas.
Работает отлично, если основная нагрузка на систему в основном чтение.
Пример: e-commerce. Primary база принимает все записи, а реплики обслуживают тяжелые чтения, типа карточек товара или истории заказов пользователя.
Горизонтальное дублирование обычно довольно прямолинейное.
Если вертикально масштабироваться уже нельзя, это обычно следующее, куда я бы смотрел.
Если ты можешь нормально “разрезать” работу между копиями, это очень элегантный способ разнести нагрузку и снизить конкуренцию за ресурсы.
Но есть нюанс: нужно больше инфраструктуры, и это, конечно, дороже.
Ты делал что-то из этого?
👉 @BackendPortal
Вот 2 способа масштабироваться дальше, чем просто балансировщик.
При горизонтальном дублировании ты копируешь часть системы, чтобы переваривать больше нагрузки, и распределяешь работу между этими копиями.
Самый очевидный вариант горизонтального дублирования это как раз load balancer. Он:
• распределяет запросы
• видит, когда нода умерла, и убирает ее из пула
1. Competing Consumer Pattern
Суть паттерна в том, чтобы раскидать нагрузку и поднять throughput.
Идеально, когда у тебя есть обработчики задач. Например, система должна давать пользователям импортировать и обрабатывать большие файлы.
Ты кладешь каждый загруженный файл в очередь, и много консьюмеров “соревнуются” за то, кто заберет задачу и обработает ее.
2. Read Replicas для read-нагрузки
Чтобы разгрузить primary базу по чтениям, ты поднимаешь read replicas.
Работает отлично, если основная нагрузка на систему в основном чтение.
Пример: e-commerce. Primary база принимает все записи, а реплики обслуживают тяжелые чтения, типа карточек товара или истории заказов пользователя.
Горизонтальное дублирование обычно довольно прямолинейное.
Если вертикально масштабироваться уже нельзя, это обычно следующее, куда я бы смотрел.
Если ты можешь нормально “разрезать” работу между копиями, это очень элегантный способ разнести нагрузку и снизить конкуренцию за ресурсы.
Но есть нюанс: нужно больше инфраструктуры, и это, конечно, дороже.
Ты делал что-то из этого?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍1🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
Колонарное хранилище vs построчное (row store) наглядно
Берем простую агрегацию и сравниваем, как она выполняется в row store и columnar store.
В row store данные лежат строками, поэтому движку приходится читать каждую строку целиком, чтобы из нее вытащить значение колонки age.
В columnar store данные лежат по колонкам, поэтому он читает сразу только значения колонки age, без трогания остальных полей и без лишнего I/O.
👉 @BackendPortal
Берем простую агрегацию и сравниваем, как она выполняется в row store и columnar store.
В row store данные лежат строками, поэтому движку приходится читать каждую строку целиком, чтобы из нее вытащить значение колонки age.
В columnar store данные лежат по колонкам, поэтому он читает сразу только значения колонки age, без трогания остальных полей и без лишнего I/O.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍2
Вот 14 авторских обучающих IT каналов по самым востребованным областям программирования:
Выбирай своё направление:
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
JavaScript, Ruby и Go используют сборщик мусора для управления памятью.
Но ты знал, что у SSD тоже есть свой GC?
SSD с большим количеством записей и удалений постоянно “перекладывает” данные, и этим занимается сборщик мусора, встроенный прямо в прошивку, которая крутится на контроллере SSD.
Из-за этого последовательная запись до сих пор предпочтительнее случайной, даже если у тебя не HDD.
👉 @BackendPortal
Но ты знал, что у SSD тоже есть свой GC?
SSD с большим количеством записей и удалений постоянно “перекладывает” данные, и этим занимается сборщик мусора, встроенный прямо в прошивку, которая крутится на контроллере SSD.
Из-за этого последовательная запись до сих пор предпочтительнее случайной, даже если у тебя не HDD.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
JSON и JSONB колонки удобны тем, что туда можно просто закинуть любые “безсхемные” данные, но иногда хочется хоть немного это зажать правилами.
Для этого можно использовать расширение
👉 @BackendPortal
Для этого можно использовать расширение
pg_jsonschema: задаешь JSON Schema и получаешь больше контроля над тем, какой формы данные вообще имеют в этих колонках.Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
SYN Flood это одна из самых старых DoS-атак, и она до сих пор работает. Вот что происходит под капотом.
TCP-соединение поднимается через three-way handshake: клиент шлет SYN, сервер отвечает SYN-ACK, клиент завершает ACK.
Фишка в том, что на этом этапе сервер держит состояние для каждой “полуоткрытой” сессии в очереди backlog и под это выделяются ресурсы.
В SYN Flood атакующий шлет тысячи SYN-пакетов, но рукопожатие не завершает. Сервер продолжает ждать ACK, backlog забивается, и когда очередь переполнена, легитимные клиенты уже не могут подключиться. Получается DoS.
Почему атака такая живучая: из-за асимметрии. Нападающий кидает крошечные пакеты почти бесплатно, а серверу на каждый приходится тратить ресурсы. Даже слабая машина может уложить куда более мощный сервер.
Факт: SYN-флуды в прошлом валили GitHub, Cloudflare и разные базы. Защита обычно такая:
1. лимитить SYN от одного IP
2. дропать пакеты от известных плохих источников
3. и самое эффективное: SYN cookies
С SYN cookies сервер вообще ничего не хранит на этапе “полуоткрыто”. Он кодирует нужную инфу (IP клиента, порт, таймстамп и т.д.) в initial sequence number у SYN-ACK, который отправляет в ответ. Номер генерируется криптографически, подделать его сложно.
В итоге handshake становится по сути stateless со стороны сервера, пока клиент не докажет, что он реальный. Ресурсы резервируются только после верификации.
Кстати, в большинстве современных ОС поддержка SYN cookies уже встроена. В Linux это включается так:
Если хочется копнуть глубже, статьи в Wikipedia по теме реально норм, плюс можно добить деталями через любимую LLM.
👉 @BackendPortal
TCP-соединение поднимается через three-way handshake: клиент шлет SYN, сервер отвечает SYN-ACK, клиент завершает ACK.
Фишка в том, что на этом этапе сервер держит состояние для каждой “полуоткрытой” сессии в очереди backlog и под это выделяются ресурсы.
В SYN Flood атакующий шлет тысячи SYN-пакетов, но рукопожатие не завершает. Сервер продолжает ждать ACK, backlog забивается, и когда очередь переполнена, легитимные клиенты уже не могут подключиться. Получается DoS.
Почему атака такая живучая: из-за асимметрии. Нападающий кидает крошечные пакеты почти бесплатно, а серверу на каждый приходится тратить ресурсы. Даже слабая машина может уложить куда более мощный сервер.
Факт: SYN-флуды в прошлом валили GitHub, Cloudflare и разные базы. Защита обычно такая:
1. лимитить SYN от одного IP
2. дропать пакеты от известных плохих источников
3. и самое эффективное: SYN cookies
С SYN cookies сервер вообще ничего не хранит на этапе “полуоткрыто”. Он кодирует нужную инфу (IP клиента, порт, таймстамп и т.д.) в initial sequence number у SYN-ACK, который отправляет в ответ. Номер генерируется криптографически, подделать его сложно.
В итоге handshake становится по сути stateless со стороны сервера, пока клиент не докажет, что он реальный. Ресурсы резервируются только после верификации.
Кстати, в большинстве современных ОС поддержка SYN cookies уже встроена. В Linux это включается так:
net.ipv4.tcp_syncookies = 1.Если хочется копнуть глубже, статьи в Wikipedia по теме реально норм, плюс можно добить деталями через любимую LLM.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2