C++ Academy


Гео и язык канала: Россия, Русский
Категория: Технологии



Гео и язык канала
Россия, Русский
Категория
Технологии
Статистика

💡 Clang умеет показывать AST, и это один из лучших способов реально понять, что компилятор видит в вашем C/C++ коде.
AST — это Abstract Syntax Tree, внутреннее представление программы после парсинга.
Например, простой код:
int x = a + b * 2;
для компилятора — не просто строка текста, а дерево примерно такого смысла:
VarDecl
└── BinaryOperator +
├── a
└── BinaryOperator *
├── b
└── 2
Именно через такое представление компилятор понимает структуру выражений, типы, области видимости и то, какие преобразования можно выполнить дальше.
У Clang AST можно получить напрямую:
clang++ -Xclang -ast-dump -fsyntax-only main.cpp
А в Compiler Explorer / Godbolt есть отдельный режим просмотра AST, поэтому можно менять код и сразу видеть, как перестраивается дерево.
Особенно полезно разбирать так:
шаблоны;
перегрузку функций;
implicit conversions;
auto;
лямбды;
range-based for;
временные объекты;
разные формы инициализации.
Если регулярно смотреть AST, C++ постепенно перестаёт выглядеть как набор «магических правил».
Начинаешь видеть код примерно так, как его видит компилятор.
🔗 https://godbolt.org/z/cfc7h41bT
#Cpp #Clang #Compiler #Programming
Compiler Explorer - C++ (x86-64 clang (trunk))
static int foo(int a, int b) { return a % 2 == 0 ? a + b : 2 * a + b; } int main() { return foo(3, 4); }


Алгоритм сортировочной станции Дейкстры получил название в честь железнодорожной сортировочной станции - и работает очень похоже.

Он преобразует обычную инфиксную запись:

3 + 4 * 2

в постфиксную:

3 4 2 * +

После этого калькулятору уже не нужно каждый раз разбираться с приоритетами операторов и строить полноценное AST.

Как работает идея:

- один стек хранит операторы;
- второй поток формирует результат;
- операторы с более высоким приоритетом выходят раньше;
- скобки и ассоциативность обрабатываются по правилам стека.

В итоге выражение можно вычислять последовательно и без рекурсивного спуска.

Простой, старый и до сих пор очень красивый алгоритм для парсеров, калькуляторов и компиляторов.

#Algorithms #C #Programming #Compilers #ComputerScience


🔥 Quickselect быстрый, пока не выберет плохой pivot

Обычный Quickselect в среднем работает за O(n), но неудачный выбор опорного элемента может превратить поиск k-го элемента в O(n²).

В 1973 году Блум, Флойд, Пратт, Ривест и Тарьян предложили алгоритм median of medians, который гарантирует линейное время даже в худшем случае.

Идея:

1. Разделить массив на группы по 5 элементов.
2. Найти медиану каждой группы.
3. Рекурсивно найти медиану полученных медиан.
4. Использовать её как pivot для Quickselect.
int mom_pivot(int *arr, int n)
{
    if (n <= 5) {
        sort(arr, n);
        return arr[n / 2];
    }

    int medians[(n + 4) / 5];

    for (int i = 0; i < n; i += 5) {
        int len = (n - i < 5) ? n - i : 5;

        sort(arr + i, len);
        medians[i / 5] = arr[i + len / 2];
    }

    return mom_pivot(medians, (n + 4) / 5);
}
Такой pivot не обязательно будет настоящей медианой массива, но он гарантированно не окажется слишком близко к краю. После разбиения отбрасывается достаточно большая часть элементов, поэтому рекурсия не деградирует.

Итоговая сложность поиска:
Средний случай: O(n)
Худший случай: O(n)
Дополнительная память: зависит от реализации
На практике randomized Quickselect часто быстрее из-за меньших констант. Median of medians нужен там, где важна строгая гарантия времени: real-time системы, adversarial input и библиотеки с предсказуемой производительностью.


Как Linux увеличивает счётчик без lock на SMP-системах

В ядре Linux есть трюк, который выглядит почти слишком просто: не заставлять все CPU драться за одну переменную.

Вместо общего счётчика используется per-CPU переменная - у каждого ядра своя копия данных.

На x86 макрос this_cpu_inc(var) превращается в одну инструкцию incl, которая работает с областью данных текущего CPU через GS.

Что это даёт:

* нет общего lock
* нет постоянной конкуренции между ядрами
* инкремент выполняется локально для текущего CPU
* операция получается быстрой и дешёвой

Идея мощная: если данные можно разделить по CPU, не нужно синхронизировать каждый маленький апдейт между всеми ядрами.

Так ядро экономит огромное количество лишней блокировки там, где код выполняется постоянно.


🔥 Хочешь быстрее расти в 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: https://t.me/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: https://t.me/addlist/2Ls-snqEeytkMDgy
Папка Frontend: https://t.me/addlist/mzMMG3RPZhY2M2Iy

Полезное
сверху:

ИТ-мемы: t.me/memes_prog
Английский для программистов: t.me/english_forprogrammers
ИИ и технологии: t.me/vistehno
954 ГБ open-source курсов: @courses
ИТ-книги бесплатно: https://t.me/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

Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.

Пока кто-то листает шум, ты будешь видеть инструменты, задачи и идеи, которые помогают расти в профессии.


NVIDIA выкатили Nemotron 3 Embed — семейство open-моделей для RAG, agentic retrieval, code retrieval и памяти агентов.

Флагман Nemotron-3-Embed-8B-BF16 заявлен как SOTA на multilingual RTEB на 16 июля 2026 года. Это retrieval-бенчмарк: он показывает, насколько хорошо embedding-модель находит нужный контекст для RAG.

Почему это важно для агентов?

Когда retrieval промахивается, агент получает мусорный контекст. Дальше начинаются лишние поиски, длиннее reasoning, больше токенов и выше счёт за inference.

В линейке три модели:

* 8B
-BF16 — максимум качества
* 1B
-BF16 — дешевле и быстрее для продакшена
* 1B-
NVFP4 — версия под Blackwell/vLLM, квантованная через NVIDIA Model Optimizer

Все модели работают с входом до 32K токенов, то есть могут индексировать длинные документы, код и agent history без слишком агрессивной нарезки.

У 1B-NVFP4 на RTEB почти тот же результат, что у BF16: 72.00 против 72.38, при этом модель остаётся совместимой по embedding-space с 1B-BF16.

https://huggingface.co/blog/nvidia/nemotron-3-embed-wins-rteb


Репост из: Kali Linux
TIME_WAIT в Linux годами объясняют неправильно
Я полез в исходники Linux TCP и снова наткнулся на старый сетевой миф.

В коде TIME_WAIT фактически зафиксирован на 60 секунд:
#define TCP_TIMEWAIT_LEN (60 * HZ)
Его нельзя настроить отдельно для сокета.

И да, tcp_fin_timeout, который часто советуют крутить в блогах, не управляет TIME_WAIT.
Он относится к состоянию FIN_WAIT2.

TIME_WAIT задан в исходниках ядра и не вынесен в отдельный sysctl.
Вот так появляются мифы: один параметр звучит похоже, его копируют из статьи в статью, а потом годами лечат не то состояние TCP.


🗺️ Полный роадмап C++ 2026 — от нуля до профессионала

Это не просто список тем, а пошаговый маршрут превращения новичка в профессионального C++-разработчика. Каждый уровень даёт не только перечень концепций, но и рабочие примеры кода с пояснениями «как правильно» и «как неправильно», чтобы вы сразу видели идиоматичный современный C++, а не устаревшие практики из учебников 2000-х годов.

Роадмап построен по принципу «теория рядом с практикой»: сначала вы изучаете концепцию на коде из соответствующего уровня, а затем углубляете понимание в разделе.
 📚 Теория C++, где каждая тема разобрана от базовой интуиции до тонкостей, важных на собеседованиях и в продакшене. Такой подход экономит месяцы: вы не зубрите оторванные факты, а понимаете, почему язык устроен именно так.
Как пользоваться: идите по уровням сверху вниз, не перепрыгивая. Пишите каждый пример руками, ломайте его, смотрите на ошибки компилятора — именно так формируется интуиция. Параллельно решайте задачи на платформах из раздела ресурсов и читайте теорию по мере появления вопросов.

https://github.com/justxor/cpproadmap2026/tree/main


C++23 добавил `std::expected`, и это одна из самых практичных вещей в языке за последние годы.

Идея простая: функция возвращает либо нормальный результат, либо ошибку. Без исключений, без output-параметров и без неявного control flow, который потом сложно отследить.
Например, парсер заголовка может вернуть uint32_t, если всё хорошо, или std::error_code, если буфер слишком короткий. Вызывающая сторона сразу видит: здесь результат может быть ошибкой, её нельзя «случайно забыть» так же легко, как при старом стиле с кодами возврата.

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

std::expected не делает обработку ошибок магической. Он просто заставляет контракт функции быть честным: успешный результат и возможная ошибка описаны прямо в типе.


Видео недоступно для предпросмотра
Смотреть в Max
🖥 Создатель C++ разнёс вайбкодинг: “сеньоры не хотят разгребать этот мусор”

Бьёрн Страуструп, легендарный создатель C++, в новом двухчасовом интервью резко прошёлся по вайбкодингу.
Главная претензия простая: сгенерированный код пока слишком часто выглядит красиво только на демке. В реальном проекте он приносит баги, раздувает кодовую базу, плодит уязвимости и плохо поддаётся нормальной проверке.
Особенно больно это бьёт по опытным разработчикам. Им потом приходится не “магически ускоряться с ИИ”, а читать, чинить и переписывать слоп, который кто-то нагенерировал за пять минут.
Похожая история уже достала и Линуса Торвальдса. Его буквально завалили кривыми AI-отчётами по ядру Linux: вроде бы люди “помогают”, а на практике создают шум, который мешает настоящей разработке.
И вот тут неприятный вывод для рынка:
ИИ не отменяет инженерное мышление.
Он просто делает слабого разработчика быстрее.

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

Сеньоры не боятся ИИ.
Они просто не хотят провести остаток карьеры, разгребая чужой промптованный мусор.


⚡️ C тоже умеет автоматическую очистку ресурсов. Просто почти никто об этом не знает

В C нет RAII как в C++ и нет defer как в Go. Поэтому код с ресурсами часто превращается в набор goto cleanup, ручных free() и риска забыть освободить память на одной из веток.
Но у GCC и Clang есть полезное расширение - __attribute__((cleanup)).
Оно позволяет повесить cleanup-функцию на локальную переменную. Когда переменная выходит из scope, компилятор сам вызывает эту функцию.
Пример:
void autofree(void *p) {
    free(*(void **)p);
}
#define auto __attribute__((cleanup(autofree)))
int main() {
    auto char *buf = malloc(1024);
    // buf будет автоматически освобождён
    // при выходе из scope
    return 0;
}
Это просто автоматический вызов cleanup-функции в конце области видимости.
Почему это удобно:
• меньше ручных free()
• меньше утечек на early return
• чище код с несколькими ресурсами
• проще писать функции без огромного cleanup: блока

Но есть важный нюанс: это не стандартный C, а расширение компилятора. В portable-коде так лучше не делать, а вот в системном коде под GCC/Clang - вполне рабочий инструмент.

C не стал безопасным языком от одной такой фичи. Но иногда он умеет больше, чем от него ожидают.


Репост из: Kali Linux
В C код может выполниться ещё до `main()`

В Linux и GCC есть constructor-функции - они запускаются автоматически до входа в main().

Выглядит почти как магия:

__attribute__((constructor))

Такую функцию не нужно вызывать вручную. Компилятор сам пометит её как код, который должен выполниться при старте программы.

Где это используется:
- инициализация глобального состояния
- подготовка shared libraries
- регистрация плагинов
- настройка runtime-окружения
- выполнение служебного кода до основной логики

Именно поэтому в C-программе не всегда всё начинается с main().
Иногда до него уже кто-то успел поработать.


✔️ Одно слово в C, которое может ускорить ваш цикл

В C есть ключевое слово restrict.
Оно говорит компилятору простую, но очень важную вещь:
«Эти указатели не пересекаются в памяти».
Без restrict компилятор обязан быть осторожным. Он не знает, могут ли a, b и result указывать на один и тот же участок памяти. Поэтому он не всегда может агрессивно оптимизировать код.
С restrict ситуация меняется:
- компилятор уверен, что указатели не alias друг друга
- цикл можно безопаснее векторизовать
- загрузки и записи можно переупорядочивать
- проще включать SIMD-инструкции
- GCC и Clang получают больше свободы для оптимизаций
Пример:
void add_arrays(int *restrict a,
                int *restrict b,
                int *restrict result,
                int n)
{
    for (int i = 0; i < n; i++)
        result[i] = a[i] + b[i];
}
Но есть важный момент.

restrict - это обещание программиста компилятору. Если вы соврали и передали пересекающиеся массивы, поведение может стать неопределённым.

Именно поэтому restrict полезен в участках кода, где вы точно контролируете память: численные вычисления, обработка массивов, графика, DSP, low-level performance-код.

Иногда одно слово даёт компилятору больше информации, чем десяток ручных микрооптимизаций.


Самый знаменитый комментарий в истории C.
Его оставил разработчик id Software в 1999 году в коде Quake III Arena.
Одна строка с приведением указателя, один битовый сдвиг, одно вычитание - и на выходе получается приближение к 1/√x.
Просто битовые трюки, магическая константа и финальный шаг уточнения методом Ньютона.
А комментарий в коде был максимально честный:
what the f***?


Своя виртуальная машина на C за 200 строк⁠⁠
Каждый раз, когда мы запускаем inference LLM, мы на самом деле гоняем программу в виртуальной машине. PyTorch крутит граф вычислений, llama.cpp интерпретирует GGUF, vLLM гоняет свой движок поверх CUDA. Мы живём в мире абстракций настолько глубоких, что уже забыли, как это всё работает на уровне байтов.
Ребята, рекомендую статью от Scarlett. Она показывает, как написать полноценную виртуальную машину на чистом C меньше чем за 200 строк. Без фреймворков, без зависимостей, без магии. Только память, регистры и опкоды. И это самая освежающая вещь, которую я читал на этой неделе.
Почему AI-специалисту стоит уделить этому вечер. Мы постоянно работаем с абстракциями поверх абстракций. Python вызывает CUDA-ядра, которые транслируются в PTX, который превращается в SASS, который исполняется на SM. Когда что-то падает с out of memory или внезапно становится в десять раз медленнее, мы открываем Nsight и видим непонятные буквы. Понимание того, как вообще работает машина, отдельная суперсила, которая окупается на каждом продакшен-инциденте.
Если кратко, что там внутри. Автор строит VM по образу LC-3, это учебная архитектура фон-Неймана. 65 536 ячеек памяти по 16 бит, 10 регистров, включая программный счётчик и регистр условных флагов. Вся инструкция это 16 бит, где первые 4 бита опкод, остальные параметры. Поддерживается 14 команд: арифметика, загрузка и сохранение памяти, переходы, вызовы подпрограмм и trap для ввода-вывода.
Самое интересное это цикл fetch decode execute. Три строки кода. Читаем инструкцию по адресу из RPC, увеличиваем RPC, вызываем обработчик по индексу опкода из таблицы указателей на функции. Всё. Вот так работает любой процессор в мире, только сложнее и с миллиардами транзисторов. Когда вы понимаете это на уровне C, архитектурные особенности Transformer runtime перестают казаться чёрной магией.
Ещё из приятного. Есть подробный разбор битовых полей инструкций, объяснение sign extension, работа с условными флагами N, Z, P и аккуратная реализация trap-таблицы через массив указателей на функции вместо гигантского switch. Этот приём напрямую переиспользуется, когда вы пишете свой интерпретатор графа или custom kernel dispatcher.
Что из этого вытаскивает AI-инженер. Во-первых, интуицию по поводу того, как устроен любой runtime, от TensorRT до ONNX. Во-вторых, понимание, почему arena-аллокаторы и заранее выделенная память бьют malloc в цикле. В-третьих, это лучший антидот от выученной беспомощности на фоне LLM-ассистентов. Пока Cursor пишет вам код на TypeScript, вы садитесь и руками собираете VM на C, которая исполняет машинный код. Мозг перезагружается, руки помнят, что такое настоящая инженерия.
Совет. Не просто читайте. Откройте файл, начните с main memory и регистров, добавляйте по одной инструкции. Сверяйтесь с постом, когда застряли. К концу вечера у вас будет рабочая VM, в которую можно загрузить свой собственный hex-файл и выполнить сложение двух чисел с клавиатуры. Это тот самый момент, ради которого мы когда-то пошли в инженерию. Источник и полный разбор: https://x.com/Zyara_1ot/status/2045916052559900725


🔥 Linux 7.0 - вычистили десятилетия легаси и стало реально быстрее
Линус Торвальдс наконец пошёл на радикальный шаг и начал массовую зачистку старого кода. То, что копилось годами, просто выкинули. Итог - система стала заметно проще, чище и быстрее.
Что изменилось по факту:
XFS сильно прокачали - файловая система стала надёжнее, меньше рисков потери данных и лучше ведёт себя под нагрузкой
Работа с памятью ускорилась примерно на 20%, плюс подтянули сетевой стек - соединения стабильнее при высоких нагрузках
Контейнеры теперь стартуют быстрее за счёт улучшений в open_tree - меньше оверхеда при разворачивании
В Kconfig наконец дали больше свободы кастомизации - можно заменить Tux на свой логотип
Поддержка железа тоже прокачана - AMD и Intel работают эффективнее без ручных оптимизаций
Главное здесь не список фич, а тренд. Ядро постепенно избавляется от исторического балласта и становится более предсказуемым и удобным для современных нагрузок.
https://github.com/torvalds/linux/releases/tag/v7.0


🧩 C++ обертка для PCRE2
pcre2cpp — это объектно-ориентированная обертка для библиотеки PCRE2, обеспечивающая удобный интерфейс для работы с регулярными выражениями. Поддерживает C++17 и C++20, упрощая процесс сопоставления и захвата результатов.
🚀 Основные моменты:
- Объектно-ориентированный интерфейс для PCRE2 10.47
- Совместимость с C++17 и C++20
- Удобное сопоставление регулярных выражений
- Встроенное захватывание результатов
📌 GitHub: https://github.com/MAIPA01/pcre2cpp
#cpp
GitHub - MAIPA01/pcre2cpp: A C++ wrapper around the PCRE2 library to provide a more user-friendly and object-oriented interface for using regular expressions, while retaining the performance and flexibility of the original library.
A C++ wrapper around ...
GitHub


🎲 Высокопроизводительная генерация случайных чисел с Zorro
Zorro - это библиотека для генерации случайных чисел на основе xoshiro256++, поддерживающая автоматическую SIMD-диспетчеризацию. Просто добавьте один заголовочный файл в проект и получите доступ к высокопроизводительным генераторам для различных распределений.
🚀Основные моменты:
- Поддержка uniform, normal, exponential и Bernoulli распределений.
- Автоматический выбор SIMD на этапе компиляции.
- Высокая производительность: до 3900 M/s для uniform генерации.
- Легкая интеграция с существующими проектами через один заголовок.
📌 GitHub: https://github.com/bobjansen/Zorro


🖥 SQL-концепции, которые реально нужно знать: https://www.youtube.com/shorts/p1czMvSxCmo
• CRUD → SELECT, INSERT, UPDATE, DELETE  
• Ключи → PRIMARY KEY, FOREIGN KEY  
• Ограничения → NOT NULL, UNIQUE, CHECK, DEFAULT  
• JOIN’ы → INNER JOIN, LEFT JOIN, RIGHT JOIN  
• Агрегации → COUNT, SUM, AVG, MIN, MAX  
• Группировка → GROUP BY, HAVING  
• Фильтрация → WHERE, BETWEEN, IN, LIKE  
• Сортировка → ORDER BY  
• Подзапросы → SELECT (SELECT …)  
• Индексы → CREATE INDEX  
• Представления → CREATE VIEW  
• Транзакции → BEGIN, COMMIT, ROLLBACK  
• Пагинация → LIMIT, OFFSET  
• Оптимизация → EXPLAIN


libPhenom

libPhenom — это фреймворк событий, разработанный Facebook для создания высокопроизводительных и масштабируемых систем на C++. Он обеспечивает простой и эффективный способ публикации и подписки на события, а также маршрутизации событий между различными компонентами системы.

#для_продвинутых

Показано 20 последних публикаций.