16151
По всем вопросам- @haarrp @itchannels_telegram - 🔥 best it channels РКН: clck.ru/3FmxJF
Кто-то под именем Сатоши Накамото в 2008 году опубликовал идею, из которой выросла целая индустрия майнинга с огромным энергопотреблением.
И до сих пор никто достоверно не знает, кто скрывается за этим именем.
При этом сама базовая идея Proof of Work выглядит почти примитивно: берём число nonce, меняем его снова и снова, каждый раз считаем хэш и проверяем, попал ли результат ниже нужного target.
Условно это выглядит так:
uint32_t nonce = 0;
while (1) {
header.nonce = nonce;
hash = sha256(sha256(header));
if (hash < target)
break;
nonce++;
}
⚡️ Linux может освободить RAM, не уничтожая сам диапазон виртуальной памяти процесса.
Это как раз то, что делает madvise(MADV_DONTNEED) для anonymous mappings.
Сценарий такой:
char *region = mmap(NULL, GB,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
// потрогали часть страниц
madvise(region, GB, MADV_DONTNEED);
madvise виртуальные адреса остаются валидными. Процесс всё ещё «видит» тот же диапазон памяти.munmap и нового mmapMADV_DONTNEED не означает «удали адреса». Это скорее сигнал ядру: «эти страницы мне сейчас не нужны, можешь забрать физическую память».
⚡️ Fenwick Tree держится на одном битовом трюке
Fenwick Tree, или Binary Indexed Tree, считает prefix sums за O(log n).
Вся магия в операции:
i & -i
-i получается как инверсия битов i плюс 1.i & -i, остаётся только самый правый бит, равный 1.
i = 12 // 1100
-i // 0100 в нужной маске
i & -i = 4
for (; i < MAXN; i += i & -i)
tree[i] += v;
for (; i > 0; i -= i & -i)
s += tree[i];
i += i & -i — перейти к следующему ответственному узлуi -= i & -i — убрать последний блок из prefix sum
💡 Clang умеет показывать AST, и это один из лучших способов реально понять, что компилятор видит в вашем C/C++ коде.
AST — это Abstract Syntax Tree, внутреннее представление программы после парсинга.
Например, простой код:
int x = a + b * 2;
VarDecl
└── BinaryOperator +
├── a
└── BinaryOperator *
├── b
└── 2
clang++ -Xclang -ast-dump -fsyntax-only main.cpp
auto;for;https://godbolt.org/z/cfc7h41bT
⚡️ Один `static` - три разных смысла. Добро пожаловать в C.
В C ключевое слово static меняет поведение в зависимости от того, где именно оно написано.
### 1. static у глобальной переменной
static int global;
.c файла.static внутри функции
void foo(void) {
static int count;
count++;
}
count не создаётся заново при каждом вызове.
foo(); // count = 1
foo(); // count = 2
foo(); // count = 3
static у функции
static void bar(void) {
}
.c файл вызвать bar() напрямую уже не сможет.
static global variable -> скрыть символ внутри файла
static local variable -> сохранить состояние между вызовами
static function -> скрыть функцию внутри файла
static в C полезнее воспринимать не как одно конкретное поведение, а как подсказку проверить две вещи:
Keylogger в несколько строк C? Почти.
На самом деле это не «магия взлома», а raw mode в терминале.
Обычно терминал ждёт Enter и сам обрабатывает ввод.
А здесь программа отключает echo и canonical mode, поэтому видит каждое нажатие сразу.
Именно так работают редакторы, TUI-приложения и терминальные игры.
Важно: использовать только на своём вводе и в учебных целях. Перехват чужих клавиш - уже не программирование, а нарушение безопасности.
Четыре строки делают сложение `float` заметно точнее
При последовательном сложении чисел с плавающей точкой часть младших битов теряется из-за округления. На больших массивах эта ошибка постепенно накапливается.
Алгоритм Кэхэна хранит потерянную часть в отдельной переменной и компенсирует её на следующем шаге:
float kahanSum(const float *nums, int count)
{
float sum = 0.0f;
float correction = 0.0f;
for (int i = 0; i < count; ++i)
{
float adjusted = nums[i] - correction;
float next = sum + adjusted;
correction = (next - sum) - adjusted;
sum = next;
}
return sum;
}
correction запоминает ошибку округления, которая потерялась при предыдущем сложении.
LEA в x86 выглядит как инструкция для адресов, но компиляторы часто используют её как скрытый калькулятор.
Формально LEA считает адрес без обращения к памяти:
lea eax, [rdi + 3]
return x + 3;
lea eax, [rdi + rdi*4]
return x * 5;
base + index * scale + offset, а LEA позволяет использовать эту механику без чтения памяти.LEA не трогает флаги процессора, в отличие от add.x * 5 может стоять не mul, а маленький трюк архитектуры.
Читать полностью…
Doom в 1993 работал на 486 и 4 МБ RAM. А современные игры почему едят 16 ГБ?
Секрет был в BSP-дереве: уровень заранее делился на области, а движок во время рендера просто обходил дерево в нужном порядке. Без z-buffer, без лишней магии, без пересчёта видимости с нуля каждый кадр.
Кармак буквально заставил геометрию работать вместо железа.
Подписывайся, тут ещё много таких историй про код, который унижает современные «оптимизации».
🛠️ Cup: C-Based Build System
Cup — это система сборки, написанная на C, позволяющая использовать C в качестве языка сценариев. Она поддерживает сложную логику сборки и интеграцию с инструментами разработки, такими как LSP и отладчики.
🚀Основные моменты:
- Полная поддержка C без использования DSL.
- Автоматическое обновление и кэширование сборок.
- Поддержка Windows, Linux и macOS.
- Генерация файлов конфигурации для популярных IDE.
- Легковесные сборки и параллельные команды.
📌 GitHub: https://github.com/howaajin/cup
#c
✔️ std::exchange: правильный move-конструктор без double free
Move-конструктор через ручное копирование полей это ловушка. Скопировал указатель, забыл занулить источник, и оба объекта в деструкторе зовут delete по одному адресу. Double free: иногда падает сразу, иногда через неделю в проде.
std::exchange закрывает вопрос одним вызовом. Он забирает ресурс и кладёт в источник безопасное значение:
Handle(Handle&& other)
: ptr(std::exchange(other.ptr, nullptr)) {}
⚡️ C++26: прямой доступ к типу внутри parameter pack
В C++26 появился pack indexing. Теперь тип по индексу можно получить напрямую из набора параметров:
template<std::size_t I, typename... Ts>
using nth_t = Ts...[I];
using Second = nth_t<1, int, double, std::string>;
// Second = double
std::tuple_element_t, вспомогательные шаблоны или рекурсию:
template<std::size_t I, typename... Ts>
using old_nth_t = std::tuple_element_t<I, std::tuple<Ts...>>;
Ts...[I]
✔️ Furtex: исследовательский набор для Linux post-exploitation и обхода EDR
В open source вышел Furtex - низкоуровневый toolkit для изучения техник post-exploitation и evasion в Linux.
Проект построен вокруг io_uring, BPF и eBPF. Автор намеренно отказался от liburing и готовых фреймворков: взаимодействие с ядром реализовано через raw syscalls.
В репозитории собраны эксперименты для:
- анализа возможностей io_uring
- исследования BPF-карт и программ
- тестирования Linux EDR
- изучения видимости событий для средств мониторинга
- проверки защитных правил Falco
- исследования сетевых и процессных механизмов ядра
Furtex интересен специалистам по Linux security, разработчикам EDR и red team-инженерам, которым важно понимать, какие действия могут проходить мимо привычных точек наблюдения.
Автор отдельно подчёркивает: проект предназначен только для разрешённых исследований и тестирования собственной инфраструктуры.
https://github.com/MatheuZSecurity/Furtex
#linux #cybersecurity #ebpf #io_uring #research
🔥 Хочешь быстрее расти в IT? Хватит учиться в одиночку
В IT прокачивается тот, кто каждый день видит сильные идеи, новые инструменты, реальные задачи, вакансии и разборы.
Окружение решает больше, чем кажется.
Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.
AI: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Хакинг: t.me/linuxkalii
DevOps: t.me/DevOPSitsec
Docker: t.me/DevopsDocker
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_1001_notes
Java: t.me/java_library
JavaScript: t.me/javascriptv
React: t.me/react_tg
Frontend: t.me/front
PHP: t.me/phpshka
Android: t.me/android_its
Мобильная разработка: t.me/mobdevelop
Базы данных: t.me/sqlhub
Data Science: t.me/data_analysis_ml
Big Data: t.me/bigdatai
Математика: t.me/data_math
Физика: t.me/fizmat
Kubernetes: t.me/kubernetc
GameDev: /channel/gamedev
Haskell: t.me/haskell_tg
Собеседования и карьера:
DS собеседования: t.me/machinelearning_interview
Python собеседования: t.me/python_job_interview
Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: /channel/addlist/2Ls-snqEeytkMDgy
Папка Frontend: /channel/addlist/mzMMG3RPZhY2M2Iy
Полезное сверху:
ИТ-мемы: t.me/memes_prog
Английский для программистов: t.me/english_forprogrammers
ИИ и технологии: t.me/vistehno
954 ГБ open-source курсов: @courses
ИТ-книги бесплатно: /channel/addlist/BkskQciUW_FhNjEy
Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg
Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.
Пока кто-то листает шум, ты будешь видеть инструменты, задачи и идеи, которые помогают расти в профессии.
⁉️ malloc — кто же ты на самом деле?
Приглашаем на открытый урок.
🗓 23 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Системное программирование».
Программа урока:
✔️ Как работает malloc и какую роль он играет в управлении памятью в системном программировании;
✔️ Что происходит при выделении памяти: от вызова функции до взаимодействия с ОС и аллокатором;
✔️ Какие типичные ошибки возникают при работе с динамической памятью и к каким последствиям они приводят;
✔️ Как понимать поведение программ на уровне памяти и писать более надежный и предсказуемый код.
После занятия вы будете знать:
• Как устроено динамическое выделение памяти в программах на низком уровне;
• Что именно делает malloc и почему его работа не сводится к "просто выделить память";
• Как более осознанно использовать механизмы управления памятью в системной разработке.
🔗 Ссылка на регистрацию: https://otus.pw/qQjk/?erid=2W5zFG1oCNd
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
🖥 C++26 закрывает одну из самых больных тем lock-free кода - безопасное удаление памяти.
Проблема не в atomics.
Проблема в том, что один поток уже убрал узел из структуры, а другой всё ещё может его читать.
Удалишь слишком рано, получишь use-after-free.
Поэтому в C++26 стандартизируют Hazard Pointers.
Идея простая:
поток заранее помечает объект как “я сейчас его читаю”.
Пока хотя бы один reader держит такой hazard pointer, объект нельзя удалять.
Удаление откладывается до момента, когда все читатели закончат работу.
Это делает lock-free структуры вроде стеков, очередей и списков намного безопаснее.
Lock-free программирование становится не магией, а чуть более нормальным инженерным инструментом.
⚙️ Обычный strcat() в цикле может незаметно превратить простую склейку строк в O(n²).
Причина в том, что strcat() при каждом вызове сначала ищет конец уже собранной строки.
Чем длиннее буфер, тем больше данных приходится повторно проходить.
Например:
for (int i = 0; i < 100000; i++)
strcat(buf, "chunk");
char *p = buf;
for (int i = 0; i < 100000; i++) {
memcpy(p, "chunk", 5);
p += 5;
}
📚 Библиотека для работы с SQLite в C++26 с использованием рефлексии
Reflite — это библиотека на C++26, которая упрощает взаимодействие с SQLite, позволяя использовать обычные структуры как основу для выполнения запросов. Она поддерживает основные операции: вставка, удаление, выборка и обновление, избавляя от лишнего шаблона кода.
🚀 Основные моменты:
- Легковесная библиотека в одном файле
- Поддержка операций INSERT, DELETE, SELECT, UPDATE
- Использует рефлексию для работы с типами структур
- Не требует полной реализации SQL, фокус на простоте
- Совместима с современными компиляторами C++26
📌 GitHub: https://github.com/KaruroChori/reflite
#cpp
🎶 Оптимизированный аудиовизуализатор для Windows
Spectrum — это легковесный аудиовизуализатор на C++, который обрабатывает звук в реальном времени и выводит его в консоль без разрывов экрана. Он использует FFTW3 для анализа аудиосигналов и обеспечивает точное визуальное представление частот.
🚀 Основные моменты:
- Реализация на C++17 для Windows.
- Низкое использование CPU и памяти.
- Поддержка WASAPI для захвата системного звука.
- Отображение в виде ASCII-графиков.
- Легкий в использовании и установке.
📌 GitHub: https://github.com/majockbim/spectrum
#cpp
⚡️ Генератор случайных чисел всего из трёх XOR и сдвигов
В 2003 году Джордж Марсалья представил xorshift - один из самых простых и быстрых генераторов псевдослучайных чисел.
Классический xorshift32:
uint32_t xorshift32(void)
{
state ^= state << 13;
state ^= state >> 17;
state ^= state << 5;
return state;
}
shift → XOR
shift → XOR
shift → XOR
state период может достигать:
2³² - 1
Лето, ИТ-Пикник и музыка известных артистов уже через несколько дней!
8 августа в Коломенском пройдет ИТ-Пикник.
В программе — выступления проекта LAB Антона Беляева, IOWA, Cream Soda, Pompeya, мартина и Совы.
А днем — научпоп-лекции, дискуссии об ИИ и больших языковых моделях, мастер-классы и интерактивы. Полезные знакомства и развлечения тоже будут.
Зарегистрироваться и узнать подробности можно на сайте мероприятия.
В билет входит +1 — можно позвать близких и друзей.
До встречи в месте притяжения ИТ.
Оператор # в препроцессоре C превращает токены в строковые литералы ещё на этапе компиляции.
Никакого преобразования во время выполнения не происходит.
Ядро Linux использует этот трюк в макросах вроде WARN_ON(), чтобы вывести точное условие, которое не прошло проверку.
Вы пишете выражение один раз, а препроцессор автоматически генерирует соответствующую строку.
Один оператор - и ваши debug-сообщения остаются идеально синхронизированы с кодом.
C++ enum class: безопасно, но местами раздражаетenum class даёт строгую типизацию и не позволяет случайно смешивать значения с обычными числами.
Но есть нюанс: даже если enum используется как набор флагов,
Flags::Read | Flags::Write
|, &, ^, ~ придётся вручную определить операторы и приводить значения к базовому типу.enum внутри namespace: меньше защиты, зато код значительно проще.
Читать полностью…
🔥 Как найти младший установленный бит без цикла
Этот трюк возвращает позицию самого правого бита 1 в 32-битном числе:
static const int table[32] = {
0, 1, 28, 2, 29, 14, 24, 3,
30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7,
26, 12, 18, 6, 11, 5, 10, 9
};
int lowest_set_bit(uint32_t v)
{
return table[((v & -v) * 0x077CB531U) >> 27];
}
v & -v изолирует младший установленный бит.0x077CB531 из последовательности де Брёйна. Для каждой из 32 возможных позиций старшие 5 бит произведения образуют уникальный индекс.v != 0.std::countr_zero() или __builtin_ctz() - компилятор часто превращает их в одну инструкцию процессора.
Читать полностью…
🌍🚀 Pointerverse: Версионный контроль для ветвящихся миров
Pointerverse — это детерминированный движок для создания проверяемых миров. Вы описываете мир как программу, создаете контент-адресованные коммиты и проверяете каждое изменение по заданным законам. Это позволяет воспроизводить историю и анализировать последствия изменений.
🚀Основные моменты:
- Детерминированное управление историей с проверкой на соответствие законам.
- Возможность ветвления и сравнения различных сценариев.
- Полная воспроизводимость и защита от подделок с помощью Merkle DAG.
- Поддержка написания собственных миров с использованием языка .pv.
📌 GitHub: https://github.com/farukalpay/Pointerverse
Даже формально верифицированный компилятор может ошибаться
В 2011 году исследователи тестировали CompCert случайно сгенерированными C-программами и нашли wrong-code баг в таком выражении:
return -1 <= (1 && x);
Правильный результат — 1, но CompCert 1.6 для PowerPC возвращал 0.
Ошибка оказалась не в доказанно корректном оптимизаторе, а в неверифицированном фронтенде.
Формальная верификация защищает только те части системы, для которых действительно построено доказательство.
От инженеров для инженеров: 1 августа в Москве, Белграде и Ереване пройдет бэкенд-конференция Яндекса — Back to Back
Старый добрый C++ Zero Cost Conf расширил формат и добавил новые бэкенд-направления — от низкоуровневой эффективности и производительности до архитектуры и надёжности продакшен-систем. Всего доступно два трека: C++ Zero Cost (Москва/Белград) и Architecture & Performance (Москва/Ереван).
— В Москве Антон Полухин, руководитель РГ21 C++, обсудит главные новости со встречи Международного комитета по стандартизации C++, ответит на вопросы о развитии C++26 и планах на C++29.
— Там же Константин Владимиров и Елизавета Носкова из Syntacore, разберут, что C++ программист должен знать про ABI. А Антон Пионтковский, разработчик YDB, расскажет, как мы считаем range-предикаты с помощью битовых масок и как комбинировать их между колонками.
Три города — три программы: Москва, Белград и Ереван.
Если планируете посетить конференцию в Москве, вас ждут экспертные сессии 1:1 с разбором карьерных запросов и выступление группы «Научно-технический рэп».
Конференции во всех городах пройдут и офлайн, и онлайн.
Зарегистрироваться можно здесь.
🤖 RSA почти никогда не делит числа по модулю напрямую
Операции с огромными числами слишком дорогие, поэтому реализации RSA используют редукцию Монтгомери.
Идея Питера Монтгомери из 1985 года:
выбирается R = 2^k
деление на R заменяется битовым сдвигом
модульные вычисления выполняются через умножения, сложения и сдвиги
За счёт этого быстрее считается:a^e mod N
Это критично для:
шифрования и расшифровки
цифровых подписей
TLS-соединений
банковских операций
Редукция Монтгомери десятилетиями работает внутри криптографических библиотек, хотя большинство пользователей даже не знает о её существовании.
Cuckoo hashing даёт O(1) lookup в худшем случае
Не амортизированно.
Не «в среднем».
А именно worst case.
Идея красивая: у каждого ключа есть ровно две возможные позиции в таблице.
Поэтому поиск тупо проверяет оба места и заканчивается.
return table1[h1(key)] == key
|| table2[h2(key)] == key;
C++23 добавил `std::expected`, и это одна из самых практичных вещей в языке за последние годы.
Идея простая: функция возвращает либо нормальный результат, либо ошибку. Без исключений, без output-параметров и без неявного control flow, который потом сложно отследить.
Например, парсер заголовка может вернуть uint32_t, если всё хорошо, или std::error_code, если буфер слишком короткий. Вызывающая сторона сразу видит: здесь результат может быть ошибкой, её нельзя «случайно забыть» так же легко, как при старом стиле с кодами возврата.
Это особенно удобно для системного кода, сетевых протоколов, парсеров, embedded и всего, где исключения либо запрещены, либо нежелательны.std::expected не делает обработку ошибок магической. Он просто заставляет контракт функции быть честным: успешный результат и возможная ошибка описаны прямо в типе.