Algorithm Visualizer — сайт, где 30+ алгоритмов разобраны пошаговой анимацией
Открытый React-проект, который превращает сухие учебники по алгоритмам в живые картинки: на каждом шаге видно состояние структуры данных, активную строку кода и пояснение, что сейчас происходит. Проект живой, в июне завезли крупное обновление.
Что внутри:
🔘 поиск пути и обходы графов: BFS, DFS, Dijkstra, Bellman-Ford;
🔘 остовные деревья Краскала и Прима, компоненты связности, потоки в сетях (Edmonds-Karp, Ford-Fulkerson);
🔘 сортировки, бинарное дерево поиска, связные списки, дерево рекурсии;
🔘 классика собеседований и олимпиад: N-Queens, выпуклая оболочка, машина Тьюринга.
Июньское обновление добавило визуализатор связных списков, рабочее пространство для обходов графа, кратчайшие пути с остовными деревьями и переиспользуемый SVG-компонент дерева с BST.
Работает прямо в браузере, ничего ставить не нужно. Сохранять студентам перед сессией, всем, кто готовится к алгоритмическим секциям собеседований, и менторам — объяснять джуну Дейкстру по анимации сильно проще, чем по псевдокоду.
Полная ссылка: https://tamimehsan.github.io/AlgorithmVisualizer/
@prog_stuff
Открытый React-проект, который превращает сухие учебники по алгоритмам в живые картинки: на каждом шаге видно состояние структуры данных, активную строку кода и пояснение, что сейчас происходит. Проект живой, в июне завезли крупное обновление.
Что внутри:
Июньское обновление добавило визуализатор связных списков, рабочее пространство для обходов графа, кратчайшие пути с остовными деревьями и переиспользуемый SVG-компонент дерева с BST.
Работает прямо в браузере, ничего ставить не нужно. Сохранять студентам перед сессией, всем, кто готовится к алгоритмическим секциям собеседований, и менторам — объяснять джуну Дейкстру по анимации сильно проще, чем по псевдокоду.
Полная ссылка: https://tamimehsan.github.io/AlgorithmVisualizer/
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
Сжать баг до минимального примера автоматически: про недооценённые test-case reducers
Когда баг воспроизводится на огромном входе — файле, программе, последовательности действий — стандартный совет «сделайте минимальный пример» звучит легко, а руками делается мучительно. Лори Тратт напоминает про инструменты, которые делают это сами: test-case reducers берут падающий вход и ужимают его, часто на 95-99%, до состояния, где удалить уже нечего.
Ключевая идея — reducer ничего не знает про ваш язык и формат. Ему нужен только оракул: функция, которая отвечает «да, этот вход всё ещё интересен», то есть баг по-прежнему воспроизводится. Всё остальное — перебор и выбрасывание кусков.
Что полезно знать:
🔘 reducer языконезависим: тот же инструмент сжимает и C-программу, и JSON, и лог действий, лишь бы был тест на «интересность»;
🔘 написать хороший тест на интересность сложнее, чем кажется: легко получить переусушку, когда вход схлопывается в другой баг, не тот, что вы ловите;
🔘 скорость этого теста решает всё: reducer вызывает его тысячи раз, поэтому его выгодно делать максимально дешёвым;
🔘 сжимать можно не только по длине входа, но и по другим метрикам — длине трейса, числу инструкций, частоте срабатывания ошибки;
🔘 есть приёмы и для недетерминированных багов, которые воспроизводятся через раз.
Сохранять всем, кто хоть раз убил полдня на ручное вырезание строк из репродукции. Навык языконезависимый и не устаревает: дешёвый минимальный пример экономит часы на каждом нетривиальном баге.
Полная статья: https://tratt.net/laurie/blog/2026/test_case_reducers_are_underappreciated_debugging_tools.html
@prog_stuff
Когда баг воспроизводится на огромном входе — файле, программе, последовательности действий — стандартный совет «сделайте минимальный пример» звучит легко, а руками делается мучительно. Лори Тратт напоминает про инструменты, которые делают это сами: test-case reducers берут падающий вход и ужимают его, часто на 95-99%, до состояния, где удалить уже нечего.
Ключевая идея — reducer ничего не знает про ваш язык и формат. Ему нужен только оракул: функция, которая отвечает «да, этот вход всё ещё интересен», то есть баг по-прежнему воспроизводится. Всё остальное — перебор и выбрасывание кусков.
Что полезно знать:
Сохранять всем, кто хоть раз убил полдня на ручное вырезание строк из репродукции. Навык языконезависимый и не устаревает: дешёвый минимальный пример экономит часы на каждом нетривиальном баге.
Полная статья: https://tratt.net/laurie/blog/2026/test_case_reducers_are_underappreciated_debugging_tools.html
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Forwarded from Типичный программист
Разработчик заменил 3 ГБ SQLite на десяток мегабайт FST и не потерял в скорости
У финнов есть слово opiskelijassammekin, и если вы не носитель, разобрать его вручную — то ещё удовольствие. Проект Taskusanakirja как раз помогает: вводишь приставку, а словарь ищет финско-английские пары на лету. Раньше под это дело автор держал 3 ГБ SQLite и упирался в размер.
В итоге он перешёл на FST (finite state transducer), статичную структуру данных для префиксного поиска. Бинарник сжался до десятка мегабайт, а отклик остался таким, что глаз не заметит.
Цепляет не столько цифрой, сколько подходом: вместо универсальной базы используется узкая структура, которая делает ровно то, что нужно, и не жрёт лишнего. Хороший напоминание, что иногда оптимизация заключается не в ускорении запросов, а в отказе от лишнего инструмента.
У финнов есть слово opiskelijassammekin, и если вы не носитель, разобрать его вручную — то ещё удовольствие. Проект Taskusanakirja как раз помогает: вводишь приставку, а словарь ищет финско-английские пары на лету. Раньше под это дело автор держал 3 ГБ SQLite и упирался в размер.
В итоге он перешёл на FST (finite state transducer), статичную структуру данных для префиксного поиска. Бинарник сжался до десятка мегабайт, а отклик остался таким, что глаз не заметит.
Цепляет не столько цифрой, сколько подходом: вместо универсальной базы используется узкая структура, которая делает ровно то, что нужно, и не жрёт лишнего. Хороший напоминание, что иногда оптимизация заключается не в ускорении запросов, а в отказе от лишнего инструмента.
til.andrew-quinn.me
Replacing a 3 GB SQLite database with a 10 MB FST (finite state transducer) binary
Note for
numberphiles:
all numbers have been rounded to their first significant
digit, because I’m a fan of Rob Eastaway’s
“zequals” method
of getting to the point when it comes to estimation. It’s much
more valuable to walk away with the heuristic “some…
numberphiles:
all numbers have been rounded to their first significant
digit, because I’m a fan of Rob Eastaway’s
“zequals” method
of getting to the point when it comes to estimation. It’s much
more valuable to walk away with the heuristic “some…
❤1👍1
p99 0 мс на автодополнение 240 миллионов доменов
Автор поставил себе дерзкую цель: показывать подсказки раньше, чем пользователь успеет отпустить клавишу. Задержку он меряет от момента keyUp до готового результата и закладывает бюджет p99 в 121 мс на два нажатия с паузой между ними. Чтобы в него уложиться, выдача должна быть готова почти мгновенно.
Архитектура делится на две части по распределению запросов:
🔘 голова, миллион самых частых доменов из списка Tranco, лежит в памяти как символьный trie с заранее посчитанным топ-8 для каждого префикса;
🔘 хвост, все 240 миллионов доменов из CZDS, лежит на SSD как memory-mapped блочный индекс с дельта-сжатием: 27 МБ оглавления в памяти и 2,5 ГБ на диске;
🔘 большинство запросов к API отвечают за 2 мс, на нагрузке 1600 запросов в секунду p99 связки nginx и API держится около 15 мс;
🔘 оставшаяся задержка упирается в сетевой путь через Cloudflare, поэтому для дальних регионов нужна геобалансировка.
По дороге видно, как требование «мгновенно» раскладывается на конкретные структуры данных и бюджеты по миллисекундам.
Сохранять тем, кто проектирует поиск и автодополнение под нагрузкой и любит, когда задержку считают по слоям.
Полная статья: https://ruurtjan.com/articles/p99-0ms-autocomplete-for-240-million-domain-names
@prog_stuff
Автор поставил себе дерзкую цель: показывать подсказки раньше, чем пользователь успеет отпустить клавишу. Задержку он меряет от момента keyUp до готового результата и закладывает бюджет p99 в 121 мс на два нажатия с паузой между ними. Чтобы в него уложиться, выдача должна быть готова почти мгновенно.
Архитектура делится на две части по распределению запросов:
По дороге видно, как требование «мгновенно» раскладывается на конкретные структуры данных и бюджеты по миллисекундам.
Сохранять тем, кто проектирует поиск и автодополнение под нагрузкой и любит, когда задержку считают по слоям.
Полная статья: https://ruurtjan.com/articles/p99-0ms-autocomplete-for-240-million-domain-names
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
Сжать GIF без потерь полным перебором: история ZGIF
GIF внутри использует LZW, а не DEFLATE, и это влияет на то, как его сжимать. Существующий flexiGIF уже умеет гибкий разбор с заглядыванием вперёд, но иногда делает хуже: занятый слот в словаре потом аукается. Автор задался вопросом, какой LZW-поток для картинки минимален в принципе, и написал ZGIF, который ищет этот минимум полным перебором. По духу это Zopfli, только для LZW.
Путь к рабочей версии занял несколько подходов, от поиска A* через динамическое программирование к гибриду с отсечением:
🔘 первая реализация на Python сжимала картинку 16 на 16 пикселей, всего 256 байт, за 30 минут;
🔘 после оптимизаций то же самое стало занимать 4 минуты;
🔘 с отсечением и заглядыванием на один шаг скорость упала до 4 секунд;
🔘 результат при этом всё равно плотнее, чем у существующих инструментов.
Сохранять тем, кто любит алгоритмы сжатия и истории про то, как наивная идея «давайте переберём всё» доводится до практичной скорости.
Полная статья: https://blog.arusekk.pl/posts/lossless-gif-recompression/
@prog_stuff
GIF внутри использует LZW, а не DEFLATE, и это влияет на то, как его сжимать. Существующий flexiGIF уже умеет гибкий разбор с заглядыванием вперёд, но иногда делает хуже: занятый слот в словаре потом аукается. Автор задался вопросом, какой LZW-поток для картинки минимален в принципе, и написал ZGIF, который ищет этот минимум полным перебором. По духу это Zopfli, только для LZW.
Путь к рабочей версии занял несколько подходов, от поиска A* через динамическое программирование к гибриду с отсечением:
Сохранять тем, кто любит алгоритмы сжатия и истории про то, как наивная идея «давайте переберём всё» доводится до практичной скорости.
Полная статья: https://blog.arusekk.pl/posts/lossless-gif-recompression/
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3❤🔥1👍1
Похвала memcached: зачем намеренно держать кеш простым
Автор объясняет, почему в новых проектах снова берёт memcached вместо Redis. Redis он плохим не называет. Просто напоминает, что у простого инструмента есть свои сильные стороны, про которые многие забыли.
Главные мысли разбора:
🔘 Redis легко перерастает из кеша в самодельную базу: положить данные через
🔘 у memcached нет персистентности на диск, и это сделано намеренно: его можно гонять как нагрузку без состояния и не думать о сохранности;
🔘 клиентские библиотеки memcached прощают сбои: если сервер упал,
🔘 кластеризация живёт на стороне клиента через хеширование ключей по нескольким адресам, упавшая нода выводится из ротации;
🔘 автор спокойно поднимает десятки инстансов по 64 МБ почти без накладных расходов.
Сохранять тем, кто выбирает кеш для веба и заодно хочет перечитать аргумент против того, чтобы кеш медленно превращался в критичное хранилище состояния.
Полная статья: https://jchri.st/blog/in-praise-of-memcached/
@prog_stuff
Автор объясняет, почему в новых проектах снова берёт memcached вместо Redis. Redis он плохим не называет. Просто напоминает, что у простого инструмента есть свои сильные стороны, про которые многие забыли.
Главные мысли разбора:
SET проще, чем сделать INSERT, и команда постепенно перестаёт относиться к нему как к временному кешу;get возвращает пустоту, и приложение просто идёт в основной источник данных;Сохранять тем, кто выбирает кеш для веба и заодно хочет перечитать аргумент против того, чтобы кеш медленно превращался в критичное хранилище состояния.
Полная статья: https://jchri.st/blog/in-praise-of-memcached/
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1
MinIO на staging: собственное S3-хранилище вместо облачного счёта
Казалось бы, облачное S3-хранилище на staging — очевидный выбор. Но аватары, документы, отчёты и записи звонков там не удаляют, SLA не нужен, а счёт растёт за хранение и трафик. В гайде разбирают, как поднять MinIO на том же VPS, где крутится staging.
MinIO реализует API Amazon S3 и понимает те же SDK и presigned URL, но стоит ровно столько, сколько диск сервера. Код клиента не меняется: меняются только эндпоинт, регион, ключи и флаг
Сохраните, если устали платить за тестовые артефакты или заметили, что staging тестирует не тот путь загрузки, что прод.
Казалось бы, облачное S3-хранилище на staging — очевидный выбор. Но аватары, документы, отчёты и записи звонков там не удаляют, SLA не нужен, а счёт растёт за хранение и трафик. В гайде разбирают, как поднять MinIO на том же VPS, где крутится staging.
MinIO реализует API Amazon S3 и понимает те же SDK и presigned URL, но стоит ровно столько, сколько диск сервера. Код клиента не меняется: меняются только эндпоинт, регион, ключи и флаг
forcePathStyle. Контейнер поднимается за 10–15 минут, HTTPS отдаётся обратному прокси с Let’s Encrypt, а приложение получает отдельного пользователя с политикой только на нужный бакет.Сохраните, если устали платить за тестовые артефакты или заметили, что staging тестирует не тот путь загрузки, что прод.
Git-сервер без диска: как объектное хранилище научили говорить по git
Git-репозиторий под капотом это объектное хранилище: коммиты, деревья и сами файлы лежат как сжатые объекты с адресацией по содержимому, а ветки и теги это крошечные изменяемые указатели на них. Обычно git-сервер держит всё это на локальной файловой системе одной машины, и она становится единой точкой отказа. Автор решил проверить, что будет, если направить git-сервер прямо в бакет объектного хранилища, без диска, без бинарника git и без базы данных.
Получился objgit, один бинарник, который хранит репозитории в облачном бакете и говорит по трём транспортам: HTTP, классический git:// и SSH. Внутри он опирается на go-git, чистую реализацию протоколов git на Go, и на billy, файловую абстракцию, которую автор натянул на объектное хранилище, чтобы go-git не заметил подмены.
Самое предметное в статье это грабли латентности, разобранные по числу запросов:
🔘 push пакета из 100 тысяч объектов разворачивался в 200 тысяч обращений к хранилищу, по одному stat и write на каждый объект, и при задержке около 10 мс это полчаса ожидания;
🔘 клон простого репозитория из 318 объектов с пакетом в 200 КиБ до починки кеша делал больше 8500 вызовов GetObject;
🔘 поиск объектов по двухсимвольным префиксам каталога давал до 256 вызовов листинга бакета за один клон;
🔘 ошибка в кеше приводила к тысячам фоновых листингов каждые 30 секунд в течение 10 минут;
🔘 pack-файлы неизменны и адресуются по содержимому, поэтому их можно держать в локальном кеше без инвалидации: первый запрос медленный, дальше скорость файловой системы;
🔘 атомарное обновление веток автор делает через расширение RenameObject, переименование объекта за один запрос к хранилищу.
Сохранять тем, кто строит поверх объектных хранилищ или любит истории про то, как привычный инструмент ведёт себя на непривычном бэкенде и во что упирается по числу запросов.
Полная статья: https://www.tigrisdata.com/blog/objgit/
@prog_stuff
Git-репозиторий под капотом это объектное хранилище: коммиты, деревья и сами файлы лежат как сжатые объекты с адресацией по содержимому, а ветки и теги это крошечные изменяемые указатели на них. Обычно git-сервер держит всё это на локальной файловой системе одной машины, и она становится единой точкой отказа. Автор решил проверить, что будет, если направить git-сервер прямо в бакет объектного хранилища, без диска, без бинарника git и без базы данных.
Получился objgit, один бинарник, который хранит репозитории в облачном бакете и говорит по трём транспортам: HTTP, классический git:// и SSH. Внутри он опирается на go-git, чистую реализацию протоколов git на Go, и на billy, файловую абстракцию, которую автор натянул на объектное хранилище, чтобы go-git не заметил подмены.
Самое предметное в статье это грабли латентности, разобранные по числу запросов:
Сохранять тем, кто строит поверх объектных хранилищ или любит истории про то, как привычный инструмент ведёт себя на непривычном бэкенде и во что упирается по числу запросов.
Полная статья: https://www.tigrisdata.com/blog/objgit/
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
VPS vs VDS vs виртуальный хостинг: что выбрать в 2026
Часто сервер выбирают по цене, а потом упираются в нехватку ресурсов, гибкости или поддержки. И почти никто не знает главного: VPS и VDS — это в большинстве случаев одно и то же, разница только в названии. Реально выбор идёт между хостингом (провайдер всё настроил, но конфигурация ограничена) и изолированным сервером с root-доступом.
В подборке 6 провайдеров под разные сценарии: от старта на виртуальном хостинге за ~123 рубля в месяц до VPS с зарубежными локациями. Внутри реальные цены, лимиты, условия по бэкапам, тестовым периодам и подсказки как сделать правильный выбор для своего случая.
Часто сервер выбирают по цене, а потом упираются в нехватку ресурсов, гибкости или поддержки. И почти никто не знает главного: VPS и VDS — это в большинстве случаев одно и то же, разница только в названии. Реально выбор идёт между хостингом (провайдер всё настроил, но конфигурация ограничена) и изолированным сервером с root-доступом.
В подборке 6 провайдеров под разные сценарии: от старта на виртуальном хостинге за ~123 рубля в месяц до VPS с зарубежными локациями. Внутри реальные цены, лимиты, условия по бэкапам, тестовым периодам и подсказки как сделать правильный выбор для своего случая.
Tproger
VPS vs VDS vs виртуальный хостинг: что выбрать в 2026
Сравнили VPS, VDS и виртуальный хостинг: чем отличаются, кому что подходит и сколько стоит. Подборка провайдеров с ценами и условиями.
Пассивный Ethernet-tap на бредборде за 15 евро
Чтобы посмотреть трафик в домашней сети, обычно нужен управляемый свитч с port mirroring или отдельный TAP-девайс за сотни долларов. Ata Kuyumcu собрал пассивный вариант на минибредборде: без чипов, без питания и без активной обработки пакетов.
🔘 четыре разъёма RJ45: два в разрыв рабочего кабеля, два мониторных для утекающей копии;
🔘 два конденсатора по 220 пФ на линиях мониторных портов сбрасывают Gigabit-автосогласование до 100 Mbps, чтобы приёмник видел только нужные пары;
🔘 рабочие пары идут напрямую через плату, поэтому отключение или поломка тапа не рвёт основной линк;
🔘 вся сборка обошлась примерно в 15 евро;
🔘 в тесте с телевизором за 7,5 минуты плата поймала 2769 пакетов и 877 SSDP-анонсов без единой CRC-ошибки.
Сохранять тем, кто хочет заглянуть в свою сеть, но не готов городить управляемый свитч ради разового дебага.
Полная статья: https://blog.lvmbdv.dev/posts/building-a-passive-ethernet-tap/
@prog_stuff
Чтобы посмотреть трафик в домашней сети, обычно нужен управляемый свитч с port mirroring или отдельный TAP-девайс за сотни долларов. Ata Kuyumcu собрал пассивный вариант на минибредборде: без чипов, без питания и без активной обработки пакетов.
Сохранять тем, кто хочет заглянуть в свою сеть, но не готов городить управляемый свитч ради разового дебага.
Полная статья: https://blog.lvmbdv.dev/posts/building-a-passive-ethernet-tap/
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
👌1
Что на самом деле такое database cluster в PostgreSQL
В PostgreSQL кластером баз данных называют набор баз, которыми управляет один инстанс сервера. Burak Sen прошёлся по внутренностям этого механизма и записал по шагам, из чего он реально состоит на диске.
Каждая база сама является объектом со своим OID. У встроенных баз он захардкожен: 1 у template1, 4 у template0, 5 у postgres. Пользовательские объекты стартуют с 16384. Все объекты и связи между ними хранятся в системных каталогах вроде pg_class и pg_database, устроенных как обычные таблицы.
🔘 tablespace физически реализован через symlink, поэтому файлы базы можно раскидать по разным дискам, не трогая логику выше;
🔘 heap-страница весит ровно 8192 байта, и модуль pageinspect позволяет заглянуть внутрь неё вручную;
🔘 значения длиннее 2 КиБ Postgres выносит во внешнее хранилище TOAST вместо того, чтобы впихивать их в страницу целиком;
🔘 VACUUM FULL переписывает файл и меняет relfilenode, а OID самой таблицы при этом остаётся прежним.
Сохранять тем, кто работает с Postgres каждый день и ни разу не заглядывал, что происходит на файловой системе под капотом.
Полная статья: https://www.buraksen.dev/articles/internals-of-postgresql-db-cluster-and-tables
@prog_stuff
В PostgreSQL кластером баз данных называют набор баз, которыми управляет один инстанс сервера. Burak Sen прошёлся по внутренностям этого механизма и записал по шагам, из чего он реально состоит на диске.
Каждая база сама является объектом со своим OID. У встроенных баз он захардкожен: 1 у template1, 4 у template0, 5 у postgres. Пользовательские объекты стартуют с 16384. Все объекты и связи между ними хранятся в системных каталогах вроде pg_class и pg_database, устроенных как обычные таблицы.
Сохранять тем, кто работает с Postgres каждый день и ни разу не заглядывал, что происходит на файловой системе под капотом.
Полная статья: https://www.buraksen.dev/articles/internals-of-postgresql-db-cluster-and-tables
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
Zig вынес пакетный менеджер из компилятора в систему сборки
Andrew Kelley описал редизайн Zig: вся логика пакетного менеджера переехала из компилятора в отдельный процесс сборки maker. Раньше компилятор сам тянул зависимости, теперь этим занимается build-система, а компилятор остался компилятором.
🔘 из бинарника zig вынесены fetching пакетов, HTTP-клиент, TLS/crypto, Git-протокол, распаковка xz/gzip/zstd/flate/zip и парсер build.zig.zon;
🔘 сам бинарник похудел на 4%: с 14,1 МиБ до 13,5 МиБ на сборке без LLVM в режиме ReleaseSmall;
🔘 пакетный менеджер теперь собирается в ReleaseSafe, то есть все сетевые операции работают с включёнными проверками безопасности;
🔘 crypto и хеширование файлов могут использовать редкие инструкции конкретного CPU, потому что maker компилируется прямо на машине пользователя, а не распространяется готовым бинарником;
🔘 флаг --maker-opt заменили на переменную окружения ZIG_DEBUG_MAKER, а --zig-lib-dir — на ZIG_LIB_DIR.
Это промежуточный шаг к протоколу build server, который нужен языковому серверу ZLS.
Сохранять тем, кто интересуется архитектурой компиляторов и тем, как языки постепенно выносят периферийную логику из ядра.
@prog_stuff
Andrew Kelley описал редизайн Zig: вся логика пакетного менеджера переехала из компилятора в отдельный процесс сборки maker. Раньше компилятор сам тянул зависимости, теперь этим занимается build-система, а компилятор остался компилятором.
Это промежуточный шаг к протоколу build server, который нужен языковому серверу ZLS.
Сохранять тем, кто интересуется архитектурой компиляторов и тем, как языки постепенно выносят периферийную логику из ядра.
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1
Как эмулировать inline-ассемблер в Haskell, которого там нет
Задача простая на словах: перемножить два Word64 и получить обе половины 128-битного результата через одну машинную инструкцию mulq. В GHC нет inline assembly, и разработчик под ником minoki перебрал все возможные обходные пути, от честного FFI до чёрной магии на уровне calling convention.
🔘 unsafe FFI с указателем через alloca работает, но тянет за собой IO и лишнюю память;
🔘 unsafe FFI в два вызова, отдельно для старшей и младшей половины, укладывает всё в регистры без указателей;
🔘 unsafe FFI через XMM-регистры возвращает обе половины сразу, но требует
🔘 foreign import prim позволяет написать собственный PrimOp прямо на ассемблере, с ручным учётом регистров STG (%rbx, %r14, jmp *(%rbp)) и макросов LEADING_UNDERSCORE и TABLES_NEXT_TO_CODE;
🔘 отдельная ассемблерная обёртка переводит между C calling convention и GHC calling convention, чтобы дёргать C-функцию, которая возвращает
На Zen4 в WSL2 встроенный timesWord2# отработал за 4 нс, foreign import prim на чистом ассемблере уложился в 4,5 нс, а unsafe FFI с указателем скатился до 19 нс. Safe FFI для такого короткого вызова вышел медленнее 60 нс, то есть медленнее чистого Haskell на Integer.
Сохранять тем, кто когда-нибудь спорил, действительно ли safe FFI в GHC настолько накладен, как все говорят.
@prog_stuff
Задача простая на словах: перемножить два Word64 и получить обе половины 128-битного результата через одну машинную инструкцию mulq. В GHC нет inline assembly, и разработчик под ником minoki перебрал все возможные обходные пути, от честного FFI до чёрной магии на уровне calling convention.
__m128i на стороне C;unsigned __int128 структурой по значению.На Zen4 в WSL2 встроенный timesWord2# отработал за 4 нс, foreign import prim на чистом ассемблере уложился в 4,5 нс, а unsafe FFI с указателем скатился до 19 нс. Safe FFI для такого короткого вызова вышел медленнее 60 нс, то есть медленнее чистого Haskell на Integer.
Сохранять тем, кто когда-нибудь спорил, действительно ли safe FFI в GHC настолько накладен, как все говорят.
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👏1
Rust-компилятор, переписанный в 46 миллионов строк C
Rustc — самокомпилирующийся компилятор Rust — переведён в 46 миллионов строк C и собирается обычным GCC и make, без единой строчки cargo или rustc в цепочке сборки. Автор — разработчик бэкенда cilly, который компилирует Rust в C.
🔘 это уже 14-я попытка автора скомпилировать Rust в C — до этого были публичные и приватные проекты вроде rustc_codegen_clr;
🔘 бэкенд генерирует «witness»-программы, которые прощупывают, что поддерживает целевой C-компилятор и платформа, и подстраивает вывод под них;
🔘 получившийся код собирает core, alloc и std и способен пересобрать сам себя;
🔘 практической пользы для повседневной разработки в этом немного — это демонстрация переносимости, а не замена rustc.
Сохранять тем, кто интересуется внутренностями компиляторов и любит истории про перенос целого тулчейна на неожиданный бэкенд.
Полная статья: https://github.com/FractalFir/crustc
@prog_stuff
Rustc — самокомпилирующийся компилятор Rust — переведён в 46 миллионов строк C и собирается обычным GCC и make, без единой строчки cargo или rustc в цепочке сборки. Автор — разработчик бэкенда cilly, который компилирует Rust в C.
Сохранять тем, кто интересуется внутренностями компиляторов и любит истории про перенос целого тулчейна на неожиданный бэкенд.
Полная статья: https://github.com/FractalFir/crustc
@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Почему ваш пет-проект ещё не бизнес, а вы — не предприниматель
У каждого второго разработчика в столе лежит проект, который «вот-вот станет бизнесом». Осталось дописать пару фич — и дальше всё поедет само. Спойлер: не поедет. Разбираемся, где заканчивается код и начинается бизнес: почему всё стартует не с технологии, а с чужой проблемы, чем фаундер отличается от тимлида и почему рабочий сервис с первыми пользователями и MRR — это не бизнес, а промежуточный результат.
Простой тест: уйдите в отпуск на две недели, и если без вас всё встало — поздравляем, у вас пока не бизнес, а вы сами и есть главный «производственный ресурс».
Внутри ещё и про AR-очки на трамвайном заводе, которые зарубили сами рабочие: история о том, как ценность решения определяете не вы.
У каждого второго разработчика в столе лежит проект, который «вот-вот станет бизнесом». Осталось дописать пару фич — и дальше всё поедет само. Спойлер: не поедет. Разбираемся, где заканчивается код и начинается бизнес: почему всё стартует не с технологии, а с чужой проблемы, чем фаундер отличается от тимлида и почему рабочий сервис с первыми пользователями и MRR — это не бизнес, а промежуточный результат.
Простой тест: уйдите в отпуск на две недели, и если без вас всё встало — поздравляем, у вас пока не бизнес, а вы сами и есть главный «производственный ресурс».
Внутри ещё и про AR-очки на трамвайном заводе, которые зарубили сами рабочие: история о том, как ценность решения определяете не вы.
Марцин Вихари, автор большого интерактивного эссе про кнопки, разобрал свежий пример того, как одна и та же кнопка поворота фото ведёт себя по-разному. Тапаешь «повернуть на 90°» восемь раз подряд: iPhone буферизует нажатия и честно доводит все повороты до конца, а Nothing Phone даёт вибрацию-подтверждение и молча съедает тап, если анимация предыдущего поворота ещё не закончилась.
Отсюда правило: никогда не заставлять пользователя ждать конца анимации. Буферизовать нажатия при этом не единственный выход, можно ускорять или обрывать анимацию по следующему тапу.
Вторая мысль, ради которой стоит читать целиком, — «ситуативная продвинутость». Любой казуальный интерфейс при достаточно большой аудитории встретит человека, которому придётся пользоваться им всерьёз: например, поворачивать десятки отсканированных документов подряд. И тогда блокирующая анимация из милой детали превращается в стену.
Полная статья: https://unsung.aresluna.org/if-youre-a-button-you-have-one-job/
Сохранять тем, кто делает интерфейсы.
@prog_stuff
Отсюда правило: никогда не заставлять пользователя ждать конца анимации. Буферизовать нажатия при этом не единственный выход, можно ускорять или обрывать анимацию по следующему тапу.
Вторая мысль, ради которой стоит читать целиком, — «ситуативная продвинутость». Любой казуальный интерфейс при достаточно большой аудитории встретит человека, которому придётся пользоваться им всерьёз: например, поворачивать десятки отсканированных документов подряд. И тогда блокирующая анимация из милой детали превращается в стену.
Полная статья: https://unsung.aresluna.org/if-youre-a-button-you-have-one-job/
Сохранять тем, кто делает интерфейсы.
@prog_stuff
👍2
Майк Боулер, консультант по инженерным командам, измерил уровень CO2 в переговорках портативным датчиком: на улице около 400 ppm, а в закрытой комнате с несколькими людьми показатель за первый час переваливает за 1000. Его личный рекорд на фото в статье — 2143.
Дальше цифры из исследований. В эксперименте Лаборатории Беркли при 1000 ppm результаты испытуемых упали на шести из девяти показателей качества принятия решений, при 2500 ppm — на семи, причём часть до уровня, который исследователи назвали дисфункциональным. Гарвардское исследование показало, что сильнее всего страдают стратегия, планирование и работа с информацией под давлением — ровно то, ради чего людей и собирают в переговорку.
Изнутри это не ощущается: туман в голове списывают на длину встречи или недосып, и воздух остаётся единственной переменной, которую никто не проверяет. То же относится к домашнему кабинету с закрытой дверью: прежде чем объяснять послеобеденный спад мотивацией, автор предлагает исключить комнату, которая не проветривалась с утра. Датчик CO2 стоит дешевле часа рабочего времени, открыть окно — бесплатно.
Полная статья: https://blog.mikebowler.ca/2026/07/03/co2-and-decision-making/
Сохранять тем, кто проводит долгие встречи и планирования в переговорках.
@prog_stuff
Дальше цифры из исследований. В эксперименте Лаборатории Беркли при 1000 ppm результаты испытуемых упали на шести из девяти показателей качества принятия решений, при 2500 ppm — на семи, причём часть до уровня, который исследователи назвали дисфункциональным. Гарвардское исследование показало, что сильнее всего страдают стратегия, планирование и работа с информацией под давлением — ровно то, ради чего людей и собирают в переговорку.
Изнутри это не ощущается: туман в голове списывают на длину встречи или недосып, и воздух остаётся единственной переменной, которую никто не проверяет. То же относится к домашнему кабинету с закрытой дверью: прежде чем объяснять послеобеденный спад мотивацией, автор предлагает исключить комнату, которая не проветривалась с утра. Датчик CO2 стоит дешевле часа рабочего времени, открыть окно — бесплатно.
Полная статья: https://blog.mikebowler.ca/2026/07/03/co2-and-decision-making/
Сохранять тем, кто проводит долгие встречи и планирования в переговорках.
@prog_stuff
❤🔥2
Почему банки теряют клиентов на вводе паспорта
В расчётно-кассовом обслуживании паспорт требуется почти для каждой операции: открытие счёта, обмен валюты, подтверждение личности. Пара минут на ручной перенос данных в масштабе банка превращается в очереди, ошибки операторов к вечеру и рост операционных расходов.
Авторы разбирают, как ИИ убирает это узкое место: документ распознаётся, поля заполняются автоматически, без ручного перепечатывания. Итог: быстрее обслуживание, меньше ошибок и предсказуемая нагрузка на отделение.
Автоматизация РКО влияет не только на внутреннюю эффективность, но и на лояльность клиентов. Если вы работаете с финтехом, интерфейсами крупных систем или высоконагруженными сервисами, где маленькая операция влияет на метрики, стоит сохранить.
В расчётно-кассовом обслуживании паспорт требуется почти для каждой операции: открытие счёта, обмен валюты, подтверждение личности. Пара минут на ручной перенос данных в масштабе банка превращается в очереди, ошибки операторов к вечеру и рост операционных расходов.
Авторы разбирают, как ИИ убирает это узкое место: документ распознаётся, поля заполняются автоматически, без ручного перепечатывания. Итог: быстрее обслуживание, меньше ошибок и предсказуемая нагрузка на отделение.
Автоматизация РКО влияет не только на внутреннюю эффективность, но и на лояльность клиентов. Если вы работаете с финтехом, интерфейсами крупных систем или высоконагруженными сервисами, где маленькая операция влияет на метрики, стоит сохранить.
Каждый, кто работал с легаси, знает это чувство: код вроде бы живой, но каждая фича даётся всё тяжелее, а на вопрос «почему так долго?» хочется ответить «потому что там всё сложно». Вот только бизнесу это ничего не объясняет — «плохой код» звучит как внутренняя боль разработчиков, а не как аргумент.
Аргументировать необходимость рефакторинга на самом деле можно. Оказывается, надо просто перевести техдолг в деньги: сколько теряется каждый месяц из-за замедлившейся разработки и багов и за какой срок рефакторинг окупится. В новом материале разбираемся, как посчитать ROI рефакторинга и с какими аргументами идти к менеджменту.
Аргументировать необходимость рефакторинга на самом деле можно. Оказывается, надо просто перевести техдолг в деньги: сколько теряется каждый месяц из-за замедлившейся разработки и багов и за какой срок рефакторинг окупится. В новом материале разбираемся, как посчитать ROI рефакторинга и с какими аргументами идти к менеджменту.
Tproger
Технический долг в деньгах: как считать ROI рефакторинга легаси-системы
Как перевести техдолг в деньги: отделяем от багов и новых требований, считаем текущие потери и обосновываем рефакторинг бизнесу через скорость, предсказуемость и риски.
Баг, который семь лет видели только левши
Читатель пожаловался Теренсу Идену: скроллишь его блог с телефона, и вдруг посреди прокрутки открывается форма ответа на комментарий. Иден скроллит собственный сайт постоянно и ничего такого не встречал. Разгадка в пальцах: он листает правым большим пальцем, а читатель — левым. Ссылка «ответить» стоит у левого края страницы, ровно там, где ложится левый палец при прокрутке.
Причина оказалась археологической. В 2017 году в WordPress добавили обработчик touchstart на клики по ссылкам — когда-то так обходили задержку в 300 мс, которую мобильные браузеры выдерживали между тапом и кликом, чтобы отличить его от двойного тапа для зума. Браузеры избавились от этой задержки ещё к 2015-му, то есть код был бесполезен уже в момент добавления. А побочный эффект остался: касание ссылки при скролле срабатывало как клик.
Баг зарепортили семь лет назад. В итоге Иден сам закоммитил фикс — удалил пару строк, переживших свою причину на десятилетие. А в WHATWG он в шутку предложил тег meta handed="right", чтобы левши на праведные сайты вообще не заходили.
Полная статья: https://shkspr.mobi/blog/2026/07/a-bug-which-only-affected-left-handed-users/
Сохранять тем, кто подозревает, что в их проекте тоже живут обходные пути, чью причину уже никто не помнит.
@prog_stuff
Читатель пожаловался Теренсу Идену: скроллишь его блог с телефона, и вдруг посреди прокрутки открывается форма ответа на комментарий. Иден скроллит собственный сайт постоянно и ничего такого не встречал. Разгадка в пальцах: он листает правым большим пальцем, а читатель — левым. Ссылка «ответить» стоит у левого края страницы, ровно там, где ложится левый палец при прокрутке.
Причина оказалась археологической. В 2017 году в WordPress добавили обработчик touchstart на клики по ссылкам — когда-то так обходили задержку в 300 мс, которую мобильные браузеры выдерживали между тапом и кликом, чтобы отличить его от двойного тапа для зума. Браузеры избавились от этой задержки ещё к 2015-му, то есть код был бесполезен уже в момент добавления. А побочный эффект остался: касание ссылки при скролле срабатывало как клик.
Баг зарепортили семь лет назад. В итоге Иден сам закоммитил фикс — удалил пару строк, переживших свою причину на десятилетие. А в WHATWG он в шутку предложил тег meta handed="right", чтобы левши на праведные сайты вообще не заходили.
Полная статья: https://shkspr.mobi/blog/2026/07/a-bug-which-only-affected-left-handed-users/
Сохранять тем, кто подозревает, что в их проекте тоже живут обходные пути, чью причину уже никто не помнит.
@prog_stuff
Rust, Go или Zig: как не ошибиться с языком для нагруженного бэкенда
Обстоятельный разбор того, как выбирать язык для высоконагруженного бэкенда в 2026 году. Не сравнение синтаксиса, а реальные сервисы: API, шлюзы, обработка событий, парсинг под нагрузкой.
Автор разбирает три языка: Go (стандарт для микросервисов), Rust (для предельной задержки и контроля памяти, но с borrow checker и долгими сборками), Zig (для узких критичных участков и интеграции с C-кодом). У каждого своя цена, скорость разработки и сценарии, где он выигрывает.
Главный вывод — не искать победителя, а смешивать: Go для скорости разработки, Rust или Zig для горячих путей. Мигрировать стоит только после профилирования, иначе оптимизация обойдётся дороже выгоды.
Сохранить тем, кто выбирает стек для нового сервиса или думает, почему в их системе растёт задержка.
Обстоятельный разбор того, как выбирать язык для высоконагруженного бэкенда в 2026 году. Не сравнение синтаксиса, а реальные сервисы: API, шлюзы, обработка событий, парсинг под нагрузкой.
Автор разбирает три языка: Go (стандарт для микросервисов), Rust (для предельной задержки и контроля памяти, но с borrow checker и долгими сборками), Zig (для узких критичных участков и интеграции с C-кодом). У каждого своя цена, скорость разработки и сценарии, где он выигрывает.
Главный вывод — не искать победителя, а смешивать: Go для скорости разработки, Rust или Zig для горячих путей. Мигрировать стоит только после профилирования, иначе оптимизация обойдётся дороже выгоды.
Сохранить тем, кто выбирает стек для нового сервиса или думает, почему в их системе растёт задержка.
👍2