Сохранёнки программиста
6.61K subscribers
1.14K photos
59 videos
10 files
1.75K links
Заметки и ссылки на будущее, чтобы изучить когда будет время.

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Другие наши проекты: https://tprg.ru/med
Download Telegram
CSS: какие части языка неустранимо плохие и как с ними жить

Разбор от Алекса Кладова (matklad, автор rust-analyzer) — взгляд бэкендера, которому пришлось стилизовать свой блог. Он разложил CSS на части, которые работают предсказуемо, и части, которые подведут в самый неожиданный момент, и для каждой плохой нашёл обходной путь.

Главные практические выводы:

🔘первая строка любого CSS-файла — * { box-sizing: border-box; }, иначе padding ломает размеры элементов;
🔘вместо обёрток и div-супа — семантические теги main, article, nav, details: с ними простой classless CSS работает сам;
🔘отступы между детьми удобно задавать через owl-селектор section > *+* { margin-top: 1rem; } — родитель контролирует расстояния, дети ни о чём не знают;
🔘явные media-запросы для простых страниц не нужны: flexbox и max-width на главной колонке дают отзывчивость бесплатно;
🔘браузерные дефолты — ловушка: проблема не в правиле, которое вы написали, а в правиле, на которое вы полагаетесь, не написав его;
🔘font-size задаёт размер виртуальной коробки вокруг глифа, а не сам глиф — выровнять два шрифта помогает font-size-adjust.

Для блога автору хватило примерно 200 строк читаемого CSS без фреймворков.

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

Полная статья: https://matklad.github.io/2026/06/04/css-unavoidable-bad-parts.html

@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
Как мы проскочили путь от первого iPhone и сложной разработки под мобильные устройства до эпохи ИИ? Что случилось и к чему это привело — в третьей части цикла об истории российского IT.

Мобильный бум застал индустрию врасплох: было непонятно, как адаптировать сайты под маленькие экраны и что делать со слабой связью. Решением стали нативные приложения — их начали разрабатывать многие компании. Так мы пришли к эпохе супераппов, где собрано всё и сразу.

Приложений, проектов и стартапов становилось больше — начался расцвет российского IT. Но разработчиков не хватало, и на сцену вышли курсы, школы и онлайн-уроки. Желающих войти в профессию оказалось огромное количество, и рынок быстро перегрелся. Теперь новичков заменяет ИИ, а найти работу — задача со звёздочкой. Сегодня гонка за лучшими программистами превратилась в гонку ИИ-инфраструктур.

Так решения порождали новые проблемы, а российская IT-индустрия вышла на новый уровень сложности. Подробнее — в материале на Tproger.
🤗2
Algorithm Visualizer — сайт, где 30+ алгоритмов разобраны пошаговой анимацией

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

Что внутри:

🔘поиск пути и обходы графов: BFS, DFS, Dijkstra, Bellman-Ford;
🔘остовные деревья Краскала и Прима, компоненты связности, потоки в сетях (Edmonds-Karp, Ford-Fulkerson);
🔘сортировки, бинарное дерево поиска, связные списки, дерево рекурсии;
🔘классика собеседований и олимпиад: N-Queens, выпуклая оболочка, машина Тьюринга.

Июньское обновление добавило визуализатор связных списков, рабочее пространство для обходов графа, кратчайшие пути с остовными деревьями и переиспользуемый 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Forwarded from Типичный программист
Разработчик заменил 3 ГБ SQLite на десяток мегабайт FST и не потерял в скорости

У финнов есть слово opiskelijassammekin, и если вы не носитель, разобрать его вручную — то ещё удовольствие. Проект Taskusanakirja как раз помогает: вводишь приставку, а словарь ищет финско-английские пары на лету. Раньше под это дело автор держал 3 ГБ SQLite и упирался в размер.

В итоге он перешёл на FST (finite state transducer), статичную структуру данных для префиксного поиска. Бинарник сжался до десятка мегабайт, а отклик остался таким, что глаз не заметит.

Цепляет не столько цифрой, сколько подходом: вместо универсальной базы используется узкая структура, которая делает ровно то, что нужно, и не жрёт лишнего. Хороший напоминание, что иногда оптимизация заключается не в ускорении запросов, а в отказе от лишнего инструмента.
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
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
Please open Telegram to view this post
VIEW IN TELEGRAM
3❤‍🔥1👍1
Похвала memcached: зачем намеренно держать кеш простым

Автор объясняет, почему в новых проектах снова берёт memcached вместо Redis. Redis он плохим не называет. Просто напоминает, что у простого инструмента есть свои сильные стороны, про которые многие забыли.

Главные мысли разбора:
🔘Redis легко перерастает из кеша в самодельную базу: положить данные через SET проще, чем сделать INSERT, и команда постепенно перестаёт относиться к нему как к временному кешу;
🔘у memcached нет персистентности на диск, и это сделано намеренно: его можно гонять как нагрузку без состояния и не думать о сохранности;
🔘клиентские библиотеки memcached прощают сбои: если сервер упал, get возвращает пустоту, и приложение просто идёт в основной источник данных;
🔘кластеризация живёт на стороне клиента через хеширование ключей по нескольким адресам, упавшая нода выводится из ротации;
🔘автор спокойно поднимает десятки инстансов по 64 МБ почти без накладных расходов.

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

Полная статья: https://jchri.st/blog/in-praise-of-memcached/

@prog_stuff
Please open Telegram to view this post
VIEW IN TELEGRAM
MinIO на staging: собственное S3-хранилище вместо облачного счёта

Казалось бы, облачное 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
VPS vs VDS vs виртуальный хостинг: что выбрать в 2026

Часто сервер выбирают по цене, а потом упираются в нехватку ресурсов, гибкости или поддержки. И почти никто не знает главного: VPS и VDS — это в большинстве случаев одно и то же, разница только в названии. Реально выбор идёт между хостингом (провайдер всё настроил, но конфигурация ограничена) и изолированным сервером с root-доступом.

В подборке 6 провайдеров под разные сценарии: от старта на виртуальном хостинге за ~123 рубля в месяц до VPS с зарубежными локациями. Внутри реальные цены, лимиты, условия по бэкапам, тестовым периодам и подсказки как сделать правильный выбор для своего случая.