I bought the cheapest EV, a used Nissan Leaf 🔥 Горячее 💬 Длинная дискуссия
Купил подержанный Nissan Leaf 2023 года — первую «новую» машину за 15 лет. Езжу мало (пара миль в день), поэтому нужен был компактный и экономичный городской автомобиль.
Дополнительное оборудование
- Зарядка Grizzl-E Level 2 в гараже
- Переносная Lectron L1
- Адаптеры NACS→J1772 и CCS1→CHAdeMO
- CarlinKit 5.0 для беспроводного CarPlay
- Видеорегистратор VIOFO A119 Mini
Мониторинг батареи
- Адаптер LeLink 2 + приложение LeafSpy Pro
- SOH (состояние) аккумулятора — 93,16 %
- Стараюсь: реже быстрые зарядки, держать заряд 50–80 %, раз в месяц доводить до 100 % и выдерживать для балансировки.
Почему электромобиль?
Анализировал покупку десятилетие. Для ежедневных поездок идеально; раз-два в год беру в аренду бензиновую машину на дальние поездки, пока зарядная инфраструктура не дотягивает до уровня АЗС.
Почему Leaf?
Цена. Плюс неплохой опыт с Nissan на прокате.
Комментарии (620)
- Кто-то купил Nissan Leaf 2012 за $400 (≈1 тыс. с доставкой) и заменил им все городские поездки.
- Другие находят 2019–2020 Bolt/Zoe/Ioniq за $10–16 тыс. после субсидий/пробега Hertz; считают их идеальными «коммьютерами».
- Старые Leaf без активного охлаждения быстро теряют ёмкость; новые с CCS2/NACS заряжаются быстрее и охлаждаются лучше.
- Главная боль: разрозненные сети зарядок, куча приложений, часто 1–2 поста CHAdeMO по станции.
- Вывод: для коротких дистанций и зарядки дома/на работе любой дешёвый подержанный EV окупается за пару лет.
SQL needed structure
- Данные на странице IMDB иерархические: фильм → режиссёр, жанры, актёры → персонажи.
- Иерархия двунаправленная: фильм→актеры и актер→фильмы.
- Реляционная БД хранит всё в плоских таблицах; при выводе строим нужную иерархию.
- Ручная сборка — утомительна, это «объектно-реляционное несоответствие».
SQL не умеет выдавать структуру
Цель: JSON вида
{"title":"Baby Driver","director":["Edgar Wright"],"writer":["Edgar Wright"],
"genres":["Action","Crime","Drama"],
"actors":[{"name":"Ansel Elgort","characters":["Baby"]}, …]}
Пошаговые запросы:
-- название
SELECT primaryTitle FROM title WHERE tconst='tt3890160';
-- режиссёры
SELECT p.primaryName
FROM title t
JOIN principal pr ON t.tconst=pr.tconst
JOIN person p ON pr.nconst=p.nconst
WHERE t.tconst='tt3890160' AND pr.category='director';
-- сценаристы
... AND pr.category='writer';
-- актёры
SELECT p.nconst, p.primaryName
FROM title t
JOIN principal pr ON t.tconst=pr.tconst
JOIN person p ON pr.nconst=p.nconst
WHERE t.tconst='tt3890160' AND pr.category='actor';
-- персонажи
SELECT pc.nconst, pc.character
FROM title t
JOIN principal pr ON t.tconst=pr.tconst
JOIN principal_character pc ON pr.nconst=pc.nconst
WHERE t.tconst='tt3890160';
Попытка объединить всё в один запрос даёт декартово произведение (режиссёры×сценаристы) и пропуск записей при отсутствии одной из ролей. Поэтому приходится делать множество отдельных запросов и собирать итоговую структуру на клиенте.
Комментарии (100)
- Обсуждение крутится вокруг «объектно-реляционного несоответствия»: SQL хорошо хранит нормализованные данные, но плохо отдаёт их иерархически.
- Многие считают, что виноват сам язык: нет встроенных вложенных отношений, агрегация в JSON делается громоздко, JOIN-ы приходится «переделывать» в коде.
- Часть участников предлагает решать задачу внутри СУБД: Postgres-функции json_agg, LATERAL-подзапросы, денормализованные VIEW и «JSON-проекции».
- Другие уверены, что проблема надумана: деревья в SQL вполне строятся (adjacency list, nested sets, closure table), просто нужно знать приёмы; ORM и NoSQL лишь откладывают боль.
- Упоминаются альтернативные пути: GraphQL-слой поверх SQL, графовые СУБД, документные хранилища (MongoDB), event-sourcing с CQRS, но каждый имеет свои trade-off.
Contracts for C
Контракты для C
C++ почти утвердила контракты (P2900); я попробовал адаптировать идеи для C.
Пока это черновик, без реализации в компиляторах.
Главное:
- `pre`/`post` — проверяемые условия на входе/выходе функции.
- Не ломают ABI.
- Компонуются и позволяют оптимизатору выкинуть лишние проверки.
- Если условие — константа, оно как `static_assert`: ошибка компиляции.
Базовые примитивы
```c
contract_assert(условие, "текст"); // всегда проверяется, при лжи — abort
contract_assume(условие, "текст"); // компилятор верит, иначе UB
Пример функции
// заголовок
void *my_malloc(size_t s) pre(s) post(r: r);
// реализация
inline void *my_malloc(size_t s) {
contract_assert(s, "size != 0");
defer { contract_assert(defer_return_value, "ok"); };
return malloc(s);
}
defer выполняет post-проверку при любом выходе.
Инлайн даёт компилятору видеть контракт; внешняя декларация сохраняет привычное разделение .h/.c.
Польза: читаемость, статический анализ, оптимизация.
Комментарии (82)
- Участники спорят, что считать «контрактом»: от assert до полноценных спецификаций, проверяемых компилятором.
- Проблема С/С++: нет единого стандарта, каждый реализует по-своему (Digital Mars — с 90-х, Frama-C, C23 unreachable()).
- Часть сообщества считает контракты костылем для слабой типизации: «если типы не выражают инварианты, добавь ещё один слой».
- Критика С23: макрос contract_assume вызывает UB через unreachable(), что делает поведение непредсказуемым и оптимизацию агрессивной.
- Альтернативы: переходить на Ada/SPARK, Rust, OCaml — там контракты либо встроены, либо доказываются статически.
Show HN: Swimming in Tech Debt
Погружён в технический долг
Книга-манифест о том, как разработчики и компании увязают в «техдолге» и выбираются из него.
-
Что такое техдолг?
Упрощения в коде, которые экономят время сейчас, но замедляют работу потом. -
Почему он растёт?
Жёсткие дедлайны, отсутствие тестов, «потом поправим». -
Как измерить?
Метрики времени на исправление багов, частота откатов, удовлетворённость команды. -
Как уменьшить?
- Выделять 20 % времени на рефакторинг.
- Писать тесты до кода (TDD).
- Проводить ревью каждого PR.
- Удалять мёртвый код.
-
Культура
Признайте проблему публично, отпразднуйте первый «день выплаты долга».
Комментарии (62)
- Читатели спорят: кто-то хвалит тему и пользу книги, кто-то ругает «воду», анекдотичность и сомневается в ИИ-авторстве.
- Критикуют метафору «плавание против течения» и длинные главы; просят внятную структуру и кликабельное оглавление.
- Автор (loumf): 18 месяцев писал без ИИ, 4 раунда редакторов, половина текста за 1 $ – чтобы покупали только заинтересованные.
- Печать через месяц; Show HN подача съехала в обычную.
- Вывод: тема ценна, но подача и навигация пока спорны – автор собирает конструктив и правит.
Fil's Unbelievable Garbage Collector 🔥 Горячее 💬 Длинная дискуссия
Fil-C — это C/C++-совместимый язык с безопасной памятью и современным инструментарием. Его сердце — FUGC, параллельный, конкурентный, точный, неперемещающий сборщик мусора.
Ключевые черты FUGC
- Параллельность: маркировка и очистка выполняются на всех ядрах.
- Конкурентность: потоки-мутаторы не останавливаются; блокировки только на медленных путях аллокации.
- On-the-fly: нет глобальной паузы; «мягкие рукопожатия» просят потоки асинхронно сканировать стек.
- Grey-stack: повторное сканирование стеков до фикс-поинта; барьер только при записи, быстрая сходимость.
- Dijkstra-barrier: при записи указателя объект помечается CAS-relaxed.
- Точность: LLVM-плагин
FilPizlonatorточно знает, где все указатели. - Неперемещаемость: объекты не двигаются; освобождённые блоки «перенаправляются» через InvisiCap.
Safepoint-механизм
- Компилятор вставляет
pollcheck: быстрая проверка или колбэк для GC. - «Мягкое рукопожатие» запускает колбэк на всех потоках.
- Состояния enter/exit позволяют блокироваться в syscall без pollcheck’ов; GC сам выполняет колбэк для «exited» потоков.
- Safepoint защищает от гонок: загруженный указатель будет жив до следующего safepoint’а.
По желанию можно включить полный stop-the-world (FUGC_STW=1) для fork(2) или отладки.
Комментарии (247)
- Fil-C — это С-компилятор с точным параллельным GC (FUGC) и capability-указателями, позволяющий запускать «как есть» CPython, SQLite, OpenSSH и др., теряя в худшем случае 4× производительности.
- Вместо ручного free и UB-оптимизаций LLVM код живёт под барьером Дейкстры и soft-handshake safepoint’ами; указатели превращаются в «InvisiCap» (base+offset), теряющие силу при приведении к integer.
- Проект исследовательский, но уже промышленно полезен: нет сборок под 32-бит, Windows и embedded без MMU, нет пока поколенческого GC и ARM/RISC-V.
- Споры: «lock-and-key» предсказуемее RAM, но требует атомиков; GC = «мусор потом» vs compile-time проверки; можно ли дождаться AI-стат-анализа вместо Rust-переписей.
Forking Chrome to render in a terminal (2023)
-
Рисование
Терминал умеет только моноширинные символы и escape-последовательности. Используем нижний полублок▄, задавая цвет фона (верхний пиксель) и символа (нижний).fn print_pixels_pair(top, bottom, (x, y)) { println!("\x1b[{};{}H\x1b[48;2;{t}m\x1b[38;2;{b}m▄", y+1, x+1, t=top, b=bottom); } -
Текст
СоздаёмTextCaptureDeviceв Skia: перехватываемonDrawGlyphRunList, преобразуем glyph → Unicode, вызываем Rust-функциюdraw_text.
Добавляем очистку текста при заливке прямоугольников:if (paint.getStyle() == kFill_Style && paint.getAlphaf() == 1.0) clear_text(rect); -
Ввод
Читаем stdin, парсим escape-коды клавиш/мыши, передаём их в Chromium через DOM-события. -
Pipe-режим
carbonyl --pipeрисует в stdout, позволяя встраивать браузер в скрипты. -
Mojo
Заменяем GPU-процесс на заглушку, отключая лишние сервисы. -
Layout
Подгоняемdevice_scale_factorиviewportпод размер терминала, чтобы 1 px = ½ клетки. -
LoDPI
На 1×-экранах включаем сглаживание, чтобы символы не «дребезжали». -
Цвет
Палитра 6×6×6 или 24-бит truecolor; приводим цвета к ближайшему доступному. -
Заголовок
ESC-операторы меняют заголовок окна и вкладки tmux. -
Итог
Carbonyl запускает весь веб в терминале без X11/Wayland:cargo install carbonyl.
Комментарии (17)
- Carbonyl — терминальный браузер на движке Chrome, удивительно шустрый и юзабельный, особенно с --zoom=300 --bitmap.
- Пользователи просят добавить Kitty Graphics Protocol, sixel/chafa для нормального вывода картинок без ASCII-арта.
- Проект вдохновлён browsh, но работает быстрее; автору даже помог получить работу.
- Запускается в podman, показывает YouTube «кубиками» и почти справляется с капчей (могут помочь мультимодальные LLM).
- Под капотом — Skia и Mojo из Chromium, что позволяет рендерить всё, включая PDF.
Evolving the OCaml Programming Language (2025) [pdf]
- Эволюция OCaml – Ashoka Univ, сент 2025 [pdf][key]
- Авто-проверка реплиц. типов – NUS, авг 2025 [pdf][key]
- AI-инструменты для исследований – IIT Madras, июль 2025 [pdf][key]
- Параллельный рантайм OCaml – Chalmers, май 2025 [pdf][key]
- Авто-проверка реплиц. типов – WG 2.8, май 2025 [pdf][key]
- Параллельный OCaml 5 – Bloomberg, мар 2025 [pdf][key]
- Параллельный OCaml 5 – IIT Gandhinagar, мар 2025 [pdf][key]
- Параллельный OCaml 5 (ч.1) – PACE Lab, фев 2025 [pdf][key]
- Безопасность памяти и ЯП – Schaeffler @ IITM, фев 2025 [pdf][key]
- Мини-ОС через Unikernels – Daekin–IITM, янв 2025 [pdf][key]
- Безопасные Unikernels с аппаратной поддержкой – CAIR DRDO, ноя 2024 [pdf][key]
- Параллельный OCaml 5 – Meta London, сен 2024 [pdf][key]
- Зачем OCaml? – Rezilyens, авг 2024 [pdf][key]
- Эффекты и конкурентность – Chalmers, май 2024 [pdf][key]
- Безопасность функциональных программ – WG 2.8, апр 2024 [pdf][key]
- Композиция библиотек конкурентности – EHOP, июл 2023 [pdf][key]
- Сливаемые реплиц. типы – Collège de France, апр 2023 [pdf][key][видео]
- OCaml 5.0 – OCaml Workshop, сен 2022 [pdf][key]
- Ретрофит конкурентности – ICFP keynote, сен 2022 [pdf][key][видео]
- Сертифицированные сливаемые типы – PLDI, июн 2022 [pdf][key][видео]
- Сертифицированные сливаемые типы – Nomadic Labs, апр 2022 [pdf][key][видео]
- Параллелизм в OCaml – Marigold, дек 2021
- Эффекты в OCaml 5 – Huawei STW, окт 2021 [pdf][key]
- Эффекты в OCaml – SimCorp, сен 2021 [pdf][key]
- Параллелизм в OCaml – SimCorp, сен 2021 [pdf][key]
- ParaFuzz: фаззинг многопоточных программ – Dagstuhl, 2021
Комментарии (30)
- Доклад — субъективный взгляд на 10-летнюю эволюцию OCaml; цель — убрать мистику вокруг разработки компилятора и заманить новых контрибьюторов.
- Главный бытовой pain-point: в стандартной библиотеке исключения — часть API, и они не типизированы, что подрывает «безопасность» языка.
- Выход — использовать Jane Street Core/Base (функции либо возвращают Result, либо помечены _exn), но большинство проектов всё ещё живёт на обычной Stdlib.
- «Большие» альтернативы Stdlib (Core, Base) существуют, но их значение часто преувеличено; официальная библиотека за последние годы всё-таки подросла полезными функциями.
- Новичкам в компиляторщине советуют начинать с мелких багов и мини-Pull Request’ов, а не пытаться сразу «съесть слона».
I ditched Spotify and set up my own music stack 💬 Длинная дискуссия
-
Причины ухода: Spotify платит артистам копейки, плодит фейковых исполнителей и треки, навязывает AI-музыку и сканирование лица для возраста. Платя ежемесячно, ты ничего не владеешь.
-
Ядро стека
- Navidrome – самописный стриминг-сервер. Доступ через Cloudflare Tunnel без открытия портов.
- Клиенты: браузер, iOS (Play:Sub), Android (Symfonium), десктоп (Feishin).
- Всё скробблится в Last.fm.
-
Управление библиотекой
- Lidarr следит за новинками любимых артистов и организует коллекцию.
- Загрузки через sabnzbd только легально: покупки, CD-рипы, CC-лицензии. Контейнеры не выходят в интернет.
-
Синхронные тексты
- lrcget-kasm массово скачивает LRC-файлы. GUI-версия запускается в контейнере Kasm.
-
Итог: полный контроль, качество, поддержка артистов без посредников.
Комментарии (169)
- Участники обсуждают, что Spotify платит артистам ~$0,005 за стрим и спорят, какая компенсация была бы «справедливой»: кто-то считает, что платформа забирает слишком много, кто-то — что рынок перенасыщен треками и цена на запись стремится к нулю.
- Почти все сошлись: чтобы «поддерживать артистов», нужно покупать у них напрямую (Bandcamp, концерты, Patreon), а не полагаться на стриминг.
- Одновременно многие признают, что самоуправляемые стеки (Navidrome, Jellyfin, Plex, Lyrion LMS) — это хобби для тех, кто готов тратить время и деньги на «сервер + хранилище + поддержку».
- Часть комментаторов прямо указывает на иронию: автор жалуется на мизерные выплаты артистам, но описывает систему, где музыка по сути скачивается из Usenet/торрентов, и артисты не получают ничего.
What Is the Fourier Transform? 🔥 Горячее 💬 Длинная дискуссия
Фурье-преобразование — это способ разложить любую функцию на сумму простых волн.
Идея родилась в 1807 г., когда Жан Батист Жозеф Фурье искал закон теплопроводности. Он показал: любая периодическая кривая — это набор синусов и косинусов с разными частотами и амплитудами.
Современная формула
$$ \hat f(\xi)=\int_{-\infty}^{\infty} f(x),e^{-2\pi i x\xi},dx $$
переводит сигнал из «временной» области в «частотную».
Как работает
- Сложный звук → набор чистых тонов.
- Изображение → сетка синусоидальных полос разной плотности.
- Удалив высокие частоты, получаем сжатие JPEG; убрав низкие — оставляем контуры.
Применения
- МРТ и рентген: преобразование Радона + обратное Фурье.
- Сотовая связь, радары, шумоподавление.
- Решение дифференциальных уравнений и квантовая механика.
Интуиция
Фурье-анализ — это «математический слух»: он выделяет, какие «ноты» содержатся в любом сигнале.
Комментарии (179)
- В треде делятся ссылками на яркие визуализации: Captain Disillusion, 3Blue1Brown, MIT-лекция Фримена, интерактивы injuly.in и jezzamon.
- Кто-то предупреждает: «простые» объяснения могут дать иллюзию понимания, лучше сразу смотреть на математику.
- Появляются любители Лапласа/z-преобразования, жалуются, что о них почти нет популярных видео.
- Обсуждают практику: JPEG, OFDM, сжатие манги, анти-муар, фильтры в е-ink, а также «почему это работает» — спarsity, смена базиса в бесконечномерном пространстве.
- Интересуются деталями: как выбрать частоты, как считать преобразование на потоке, почему убрать высокие частоты = размытие.
io_uring is faster than mmap 🔥 Горячее
TL;DR
Чтение напрямую с диска быстрее, чем из кеша в памяти: пропускная способность SSD растёт, а латентность памяти стоит на месте. Нужны новые инструменты.
Эксперимент
- Задача: подсчитать количество десяток в 50 ГБ псевдослучайных
int. - Железо: AMD EPYC 7551P, 96 ГБ DDR4-2133, два Samsung PM983a PCIe 3.0 SSD (3,1 ГБ/с каждый) в RAID-0.
- Ограничения:
- Память: 13 ГБ/с на поток (3 канала × 2133 МТ/с × 8 Б / 4 NUMA-домена).
- Диски: 6,2 ГБ/с суммарно.
Код
int* data = mmap(..., size, PROT_READ, MAP_SHARED, fd, 0);
for (...) if (data[i] == 10) count++;
Результаты
- Первый запуск (с диска): 0,61 ГБ/с — ограничение диск.
- Второй запуск (из кеша): 3,71 ГБ/с — всё ещё ниже пропускной способности памяти.
- Бутылочное горлышко: не векторизованный цикл, ~3–4,5 млрд инструкций/с.
Комментарии (120)
- mmap тормозит из-за последовательных page-fault и 4 Кб страниц; io_uring на 6 потоках читает буферы заранее и просто отдаёт готовые.
- Пропущены MAP_POPULATE / MADV_SEQUENTIAL / hugepages — без них сравнение «mmap vs io_uring» нечестое.
- Автор признаёт кликбейтное название «Memory is slow, Disk is fast»; суть: «RAID-0 NVMe даёт больше пропускной канала, чем DDR5-каналов на тестовой машине».
- Под капотом io_uring + O_DIRECT сам управляет кэшем, mmap же полагается на page-cache ядра.
- PCIe-5 ×128 линий серверных CPU уже >1 ТБ/с, что выше DDR5-6400 12-канального узла (~600 ГБ/с), но данные всё равно идут в RAM перед CPU.