🚀 Как ядро Linux создаёт пакеты переменной длины без лишних копирований
В C есть мощный паттерн — flexible array member.
Вместо хранения заголовка и данных отдельно:
можно сделать один непрерывный блок памяти:
Код:
Один
Почему это любят в системном коде:
✅ меньше аллокаций
✅ лучше работа с CPU cache
✅ проще сериализация
✅ нет лишних указателей и разрозненных данных
Такой подход используется в низкоуровневом коде: ядрах, драйверах, сетевых стеках.
До C99 часто писали:
и вручную обходили ограничения языка.
Теперь
«После структуры здесь будет динамический массив данных».
Маленькая особенность C, которая помогает писать быстрый код на уровне ядра.
В C есть мощный паттерн — flexible array member.
Вместо хранения заголовка и данных отдельно:
header → отдельно
payload → отдельно
можно сделать один непрерывный блок памяти:
+----------------+
| struct msg |
| len |
+----------------+
| payload data[] |
+----------------+
Код:
struct msg {
uint32_t len;
uint8_t data[];
};
struct msg *m = malloc(sizeof(*m) + n);
Один
malloc() → один блок памяти → один free().Почему это любят в системном коде:
✅ меньше аллокаций
✅ лучше работа с CPU cache
✅ проще сериализация
✅ нет лишних указателей и разрозненных данных
Такой подход используется в низкоуровневом коде: ядрах, драйверах, сетевых стеках.
До C99 часто писали:
uint8_t data[1];
и вручную обходили ограничения языка.
Теперь
data[] — официальный способ сказать:«После структуры здесь будет динамический массив данных».
Маленькая особенность C, которая помогает писать быстрый код на уровне ядра.
❤11🫡6👍5🥰1
🐢 Все пытаются ускорить процессоры. А этот проект делает наоборот.
Новый проект CPU deoptimization ищет самые медленные инструкции, которые когда-либо выполнялись на x86.
Идея простая:
Не «как заставить CPU работать быстрее», а:
«Какую самую ужасную инструкцию можно заставить выполнить процессор?»
Результат уже впечатляет:
💀 Рекорд x86:
198 002 498 236 тактов CPU
≈ 62 секунды на выполнение одной инструкции
Это целая «галерея позора» для ассемблера:
- странные инструкции;
- неожиданные микроархитектурные эффекты;
- случаи, когда одна команда превращается в вечность.
Иногда лучший способ понять процессор — не ускорять его, а найти его слабые места.
Assembly Hall of Shame:
https://github.com/xoreaxeaxeax/asm-hall-of-shame
Новый проект CPU deoptimization ищет самые медленные инструкции, которые когда-либо выполнялись на x86.
Идея простая:
Не «как заставить CPU работать быстрее», а:
«Какую самую ужасную инструкцию можно заставить выполнить процессор?»
Результат уже впечатляет:
💀 Рекорд x86:
198 002 498 236 тактов CPU
≈ 62 секунды на выполнение одной инструкции
Это целая «галерея позора» для ассемблера:
- странные инструкции;
- неожиданные микроархитектурные эффекты;
- случаи, когда одна команда превращается в вечность.
Иногда лучший способ понять процессор — не ускорять его, а найти его слабые места.
Assembly Hall of Shame:
https://github.com/xoreaxeaxeax/asm-hall-of-shame
❤16👍9🔥4
🛠 Как автоматически закрывать файлы из C-библиотеки в C++
Использование внутри функции:
Когда
Так устроен RAII: время жизни ресурса связано со временем жизни объекта. Если
FILE* можно обернуть в std::unique_ptr с собственным обработчиком освобождения:
#include <cstdio>
#include <memory>
struct FileCloser {
void operator()(std::FILE* file) const noexcept {
std::fclose(file);
}
};
using File = std::unique_ptr<std::FILE, FileCloser>;
Использование внутри функции:
File file{std::fopen("data.txt", "r")};
if (!file) {
return;
}
// Передаём FILE* в функции C-библиотеки
int ch = std::fgetc(file.get());
Когда
file выйдет из области видимости, unique_ptr вызовет fclose. Это работает при обычном завершении функции, раннем return и раскрутке стека при исключении.Так устроен RAII: время жизни ресурса связано со временем жизни объекта. Если
fopen вернул nullptr, обработчик освобождения вызван не будет.🔥10❤6👍4
📚 Отличная подборка материалов по современному C++
На Modernes C++ собрали большой структурированный каталог статей по языку - от базовых концепций до сложных тем из современного стандарта.
Что есть внутри:
- templates и metaprogramming;
- concurrency и multithreading;
- smart pointers и управление ресурсами;
- ranges, concepts и coroutines;
- STL и алгоритмы;
- memory model;
- best practices и типичные ошибки;
- новые возможности C++20/23 и дальше.
Удобно, что это не набор случайных постов, а фактически большая карта тем по современному C++.
Хороший ресурс, если хочется системно закрыть пробелы и глубже понять, как язык работает под капотом.
https://modernescpp.com/index.php/table-of-content/
#Cpp #CPlusPlus #Programming #STL #ModernCpp
На Modernes C++ собрали большой структурированный каталог статей по языку - от базовых концепций до сложных тем из современного стандарта.
Что есть внутри:
- templates и metaprogramming;
- concurrency и multithreading;
- smart pointers и управление ресурсами;
- ranges, concepts и coroutines;
- STL и алгоритмы;
- memory model;
- best practices и типичные ошибки;
- новые возможности C++20/23 и дальше.
Удобно, что это не набор случайных постов, а фактически большая карта тем по современному C++.
Хороший ресурс, если хочется системно закрыть пробелы и глубже понять, как язык работает под капотом.
https://modernescpp.com/index.php/table-of-content/
#Cpp #CPlusPlus #Programming #STL #ModernCpp
👍12❤3🔥2🎉1
🔥 Хочешь расти в 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: https://t.me/+90Z5TAyfuNU5YmRi
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_ci
Java: t.me/javatg
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 курсов: https://t.me/+rKBQEMccAA01MTcy
ИТ-книги бесплатно: 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
Подпишись и сохрани, здесь регулярно появляются новые подборки, инструменты и материалы, которые реально помогают расти быстрее.
Можно годами смотреть курсы, читать документацию и всё равно топтаться на месте.
А можно попасть в правильное окружение, где каждый день обсуждают новые инструменты, вакансии, реальные кейсы, ошибки и то, что уже завтра станет стандартом.
Здесь собраны папки и каналы по разным направлениям IT, чтобы ты быстрее находил нужных людей, идеи и полезный контент - без бесконечного поиска.
AI: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Хакинг: t.me/linuxkalii
DevOps: t.me/DevOPSitsec
Docker: https://t.me/+90Z5TAyfuNU5YmRi
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_ci
Java: t.me/javatg
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 курсов: https://t.me/+rKBQEMccAA01MTcy
ИТ-книги бесплатно: 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
Подпишись и сохрани, здесь регулярно появляются новые подборки, инструменты и материалы, которые реально помогают расти быстрее.
❤1👍1🕊1
💡 C++:
Если ключ уже приходит как
std::map<std::string, ...> не обязан создавать временный std::string при каждом поискеЕсли ключ уже приходит как
std::string_view, можно использовать transparent comparator:
std::map<std::string, int, std::less<>> status_codes{
{"not_found", 404},
{"timeout", 504}
};
std::string_view key = "timeout";
auto match = status_codes.find(key);
❤6👍5
🔥 Почему в Redis Cluster именно 16 384 hash slot и при чём тут `{}`
Redis Cluster распределяет ключи не напрямую по нодам, а сначала по 16 384 hash slots.
Формула по сути такая:
Но есть важный трюк — hash tags.
Если ключ содержит часть в фигурных скобках, Redis хеширует только содержимое внутри
Оба ключа будут вычислены по
Это нужно для multi-key операций в cluster mode.
Именно поэтому такие конструкции позволяют нормально использовать:
-
-
- транзакции
- Lua-скрипты с несколькими ключами
На уровне кода Redis сначала ищет
Небольшая деталь синтаксиса, которая на самом деле решает важную проблему распределённых операций в Redis Cluster.
Redis Cluster распределяет ключи не напрямую по нодам, а сначала по 16 384 hash slots.
Формула по сути такая:
CRC16(key) % 16384Но есть важный трюк — hash tags.
Если ключ содержит часть в фигурных скобках, Redis хеширует только содержимое внутри
{}:{user100}:cart {user100}:ordersОба ключа будут вычислены по
user100, поэтому попадут в один и тот же hash slot и, соответственно, на одну ноду.Это нужно для multi-key операций в cluster mode.
Именно поэтому такие конструкции позволяют нормально использовать:
-
MGET-
MSET- транзакции
- Lua-скрипты с несколькими ключами
На уровне кода Redis сначала ищет
{, затем }, и если внутри есть непустая строка — хеширует только её.Небольшая деталь синтаксиса, которая на самом деле решает важную проблему распределённых операций в Redis Cluster.
👍5❤2
Например:
SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count)После препроцессора это превращается сразу в несколько функций:
-
sys_write-
__se_sys_write-
__do_sys_writeОдна строка описывает системный вызов, а C-препроцессор через макросы и token pasting собирает остальную обвязку автоматически.
Именно поэтому код ядра Linux часто выглядит коротко, пока не начнёшь разворачивать макросы.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍3🔥2
🔥 Приглашаем на бесплатный открытый вебинар курса «Программист С»: «Указатели в Си — от адреса к управлению памятью»
🗓 Когда: 24 сентября, 20:00 (мск)
Указатели — это не просто синтаксис, а ключ к пониманию того, как Си общается с памятью. Без них невозможно осознанно работать с массивами, строками, структурами и динамическими данными. На вебинаре разберём указатели от самого основания — адресов и операторов — до передачи параметров по ссылке, чтобы вы перестали бояться звёздочек и начали управлять памятью уверенно.
Что будет на вебинаре:
• Разбор ключевых понятий: адрес переменной, операторы & и *, объявление и разыменовывание указателей — разберём, как Си работает с памятью напрямую;
• Пошаговый анализ связи указателей, массивов и функций — выясним, как передавать параметры по ссылке и заставлять функции изменять переменные вызывающего кода.
👉 Зарегистрируйтесь https://otus.pw/BLgM/?erid=2W5zFHuFYrV
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
🗓 Когда: 24 сентября, 20:00 (мск)
Указатели — это не просто синтаксис, а ключ к пониманию того, как Си общается с памятью. Без них невозможно осознанно работать с массивами, строками, структурами и динамическими данными. На вебинаре разберём указатели от самого основания — адресов и операторов — до передачи параметров по ссылке, чтобы вы перестали бояться звёздочек и начали управлять памятью уверенно.
Что будет на вебинаре:
• Разбор ключевых понятий: адрес переменной, операторы & и *, объявление и разыменовывание указателей — разберём, как Си работает с памятью напрямую;
• Пошаговый анализ связи указателей, массивов и функций — выясним, как передавать параметры по ссылке и заставлять функции изменять переменные вызывающего кода.
👉 Зарегистрируйтесь https://otus.pw/BLgM/?erid=2W5zFHuFYrV
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
👍2
💡 Алгоритм Флойда находит цикл в связном списке всего с двумя указателями и `O(1)` дополнительной памяти.
Идея простая:
Если цикл есть, они обязательно встретятся.
После встречи один указатель возвращаем в
Сложность:
Один из самых красивых примеров того, как простая математика по модулю превращается в очень практичный алгоритм.
Идея простая:
slow двигается на 1 узел fast — на 2Если цикл есть, они обязательно встретятся.
После встречи один указатель возвращаем в
head, а дальше оба двигаем по одному узлу. Следующая точка встречи — точное начало цикла.
Node *detect_cycle(Node *head) {
Node *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
}
return NULL;
}
Сложность:
O(n) по времени
O(1) по памяти
Один из самых красивых примеров того, как простая математика по модулю превращается в очень практичный алгоритм.
❤8👍3