Аллокатор памяти в NGINX по сути представляет собой указатель, который движется только вперёд.
В нём нет free list-ов, он избегает фрагментации и сохраняет минимальные накладные расходы на каждое выделение памяти.
Память выделяется из одного большого блока по мере поступления запросов.
Когда обработка запроса завершается, весь пул памяти освобождается целиком за один раз.
Именно этот аллокатор используется в
👉 @Cpportal
В нём нет free list-ов, он избегает фрагментации и сохраняет минимальные накладные расходы на каждое выделение памяти.
Память выделяется из одного большого блока по мере поступления запросов.
Когда обработка запроса завершается, весь пул памяти освобождается целиком за один раз.
Именно этот аллокатор используется в
nginx/src/core/ngx_palloc.cPlease open Telegram to view this post
VIEW IN TELEGRAM
❤10👍2
Я читал исходники SQLite и нашёл интересную вещь.
DELETE на самом деле не уменьшает размер файла базы данных.
Удалённые страницы попадают во внутренний freelist прямо внутри файла.
Новые INSERT сначала переиспользуют эти свободные страницы, а уже потом снова увеличивают базу.
Сам файл уменьшается только после VACUUM.
Можно удалить всё из базы на 1 ГБ, а файл всё равно останется 1 ГБ, пока вы его не сожмёте.
👉 @Cpportal
DELETE на самом деле не уменьшает размер файла базы данных.
Удалённые страницы попадают во внутренний freelist прямо внутри файла.
Новые INSERT сначала переиспользуют эти свободные страницы, а уже потом снова увеличивают базу.
Сам файл уменьшается только после VACUUM.
Можно удалить всё из базы на 1 ГБ, а файл всё равно останется 1 ГБ, пока вы его не сожмёте.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍6🤔4
Этот алгоритм подсчёта установленных битов был опубликован ещё в 1957 году.
Он считает все 64 бита параллельно с помощью арифметики над битовыми масками, вместо того чтобы проходить по каждому биту в цикле.
Когда инструкция POPCNT недоступна, ядро Linux использует ту же идею в функции __sw_hweight64.
👉 @Cpportal
Он считает все 64 бита параллельно с помощью арифметики над битовыми масками, вместо того чтобы проходить по каждому биту в цикле.
Когда инструкция POPCNT недоступна, ядро Linux использует ту же идею в функции __sw_hweight64.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14🤯5❤3🤔1🤣1
Только что наткнулся на довольно безумную штуку — Linux прямо в браузере.
✓ Без установки и настройки, всё работает через WebAssembly
✓ Из коробки доступны Python, C, C++, Vim, cURL и другие инструменты
✓ Есть доступ в интернет, так что можно ставить дополнительные пакеты
Потыкать можно здесь: webvm.io
Честно, не ожидал, что это будет работать настолько хорошо.
👉 @Cpportal
✓ Без установки и настройки, всё работает через WebAssembly
✓ Из коробки доступны Python, C, C++, Vim, cURL и другие инструменты
✓ Есть доступ в интернет, так что можно ставить дополнительные пакеты
Потыкать можно здесь: webvm.io
Честно, не ожидал, что это будет работать настолько хорошо.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🔥6👎2
Забавный факт: решето Эратосфена позволяет найти все простые числа примерно до 8 миллионов, используя всего около 1 МБ памяти.
Один бит хранит информацию об одном числе, а внутренний цикл помечает составные числа с помощью битовых операций.
Этот же подход используется в генераторах простых чисел и при выборе размеров хеш-таблиц.
Если пост был полезен как и всегда - ставь like🫢
👉 @Cpportal
Один бит хранит информацию об одном числе, а внутренний цикл помечает составные числа с помощью битовых операций.
Этот же подход используется в генераторах простых чисел и при выборе размеров хеш-таблиц.
Если пост был полезен как и всегда - ставь like
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤39🔥7😁3
Одна из самых недооценённых анонсированных на WWDC фич — Container Machines. Она позволяет запускать на Mac лёгкое и постоянное Linux-окружение, в котором домашний каталог пользователя и репозитории автоматически монтируются внутрь контейнера.
По сути, разработчики получают Linux-среду, тесно интегрированную с macOS, без необходимости вручную настраивать виртуальные машины или сложную инфраструктуру контейнеров.🍎 🐧
https://github.com/apple/container/blob/main/docs/container-machine.md
👉 @Cpportal
По сути, разработчики получают Linux-среду, тесно интегрированную с macOS, без необходимости вручную настраивать виртуальные машины или сложную инфраструктуру контейнеров.
https://github.com/apple/container/blob/main/docs/container-machine.md
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
container/docs/container-machine.md at main · apple/container
A tool for creating and running Linux containers using lightweight virtual machines on a Mac. It is written in Swift, and optimized for Apple silicon. - apple/container
❤6
Вышел бесплатный гайд по Vim.
Внутри:
→ история Vim
→ настройка и кастомизация
→ плагины
→ основные команды для повседневной работы
https://freecodecamp.org/news/mastering-vim-your-guide-to-efficient-text-editing/
👉 @Cpportal
Внутри:
→ история Vim
→ настройка и кастомизация
→ плагины
→ основные команды для повседневной работы
https://freecodecamp.org/news/mastering-vim-your-guide-to-efficient-text-editing/
Please open Telegram to view this post
VIEW IN TELEGRAM
freeCodeCamp.org
Mastering VIM: Your Guide to Efficient Text Editing
VIM is a highly configurable text editor that enables efficient text editing. It's favored by many developers and system administrators for its powerful capabilities and extensive customization options. We just published a course on the freeCodeCamp....
🔥8❤3👍3
Бинарный поиск, который вы заучили, скорее всего реализован с ошибкой.
Джон Бентли опубликовал реализацию бинарного поиска в Programming Pearls после того, как доказал её корректность и протестировал.
Ошибка оставалась незамеченной почти 20 лет.
Позже Джошуа Блох обнаружил ту же самую ошибку в реализации бинарного поиска, которую написал для JDK.
Исследование 1988 года показало, что корректная реализация бинарного поиска была только в 5 из 20 учебников.
Ошибка проявляется только на массивах размером 2³⁰ элементов и больше.
Проблема возникает при вычислении середины диапазона.
На очень больших массивах такое выражение может вызвать переполнение.
Исправление простое:
В C переполнение приводит к выходу за границы массива с непредсказуемыми последствиями.
В Java это заканчивается исключением
Та же ошибка затронула Merge Sort и множество других алгоритмов класса «разделяй и властвуй».
Эта ошибка была и в ядре Linux — в
Вегард Носсум исправил её, а Линус Торвальдс одобрил патч.
Исправление сводилось к замене:
на:
Джошуа Блох завершил свою статью фразой, которая остаётся актуальной и сегодня:
👉 @Cpportal
Джон Бентли опубликовал реализацию бинарного поиска в Programming Pearls после того, как доказал её корректность и протестировал.
Ошибка оставалась незамеченной почти 20 лет.
Позже Джошуа Блох обнаружил ту же самую ошибку в реализации бинарного поиска, которую написал для JDK.
Исследование 1988 года показало, что корректная реализация бинарного поиска была только в 5 из 20 учебников.
Ошибка проявляется только на массивах размером 2³⁰ элементов и больше.
Проблема возникает при вычислении середины диапазона.
mid = (low + high) / 2
На очень больших массивах такое выражение может вызвать переполнение.
Исправление простое:
mid = low + (high - low) / 2
В C переполнение приводит к выходу за границы массива с непредсказуемыми последствиями.
В Java это заканчивается исключением
ArrayIndexOutOfBoundsException.Та же ошибка затронула Merge Sort и множество других алгоритмов класса «разделяй и властвуй».
Эта ошибка была и в ядре Linux — в
kallsyms.c.Вегард Носсум исправил её, а Линус Торвальдс одобрил патч.
Исправление сводилось к замене:
mid = (low + high) / 2;
на:
mid = low + (high - low) / 2;
Джошуа Блох завершил свою статью фразой, которая остаётся актуальной и сегодня:
«Трудно правильно написать даже самый маленький фрагмент кода, а весь наш мир работает на больших и сложных программных системах».
Please open Telegram to view this post
VIEW IN TELEGRAM
❤20🥱1
Этот обычный на вид C-код содержит серьёзную уязвимость: она может повредить память и привести к эксплуатации.
Такой паттерн находили в OpenSSH в 2002 году, libtiff и куче других проектов.
Сможете сказать, в чём проблема, если код запускается на 32-битной системе?
Именно этот кусок кода стал причиной уязвимости OpenSSH (CVE-2002-0640).
nresp = packet_get_int();
if (nresp > 0) {
response = xmalloc(nresp * sizeof(char *));
for (i = 0; i < nresp; i++)
response[i] = packet_get_string(NULL);
}
Через неё атакующие могли ломать кучу, выполнять свой код на сервере и получать над ним контроль.
👉 @Cpportal
Такой паттерн находили в OpenSSH в 2002 году, libtiff и куче других проектов.
Сможете сказать, в чём проблема, если код запускается на 32-битной системе?
nresp = packet_get_int();
if (nresp > 0) {
response = xmalloc(nresp * sizeof(char *));
for (i = 0; i < nresp; i++)
response[i] = packet_get_string(NULL);
}
Через неё атакующие могли ломать кучу, выполнять свой код на сервере и получать над ним контроль.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤5👀2
PID'ы переиспользуются. pidfd — нет.
Если вызвать
Одна из тех фич Linux, после знакомства с которыми возникает только один вопрос: почему я не знал об этом раньше?
👉 @Cpportal
Если вызвать
kill() для PID, который ты сохранил 20 минут назад, есть шанс отправить сигнал уже совершенно другому процессу.pidfd — это стабильный дескриптор конкретного процесса. Он остаётся привязанным именно к нему, даже если его PID позже будет переиспользован системой.Одна из тех фич Linux, после знакомства с которыми возникает только один вопрос: почему я не знал об этом раньше?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11🔥4
В исходниках Nginx HTTP-парсер реализован как ручная конечная машина с примерно 25 состояниями.
Каждый байт запроса обрабатывается по одному, с одной трансформацией состояния за символ.
Весь HTTP/1.1 request line проходит через этот парсер в один проход, без промежуточных буферизаций или повторного анализа.
Это классический подход для высокопроизводительных C-серверов: минимальные аллокации, предсказуемое поведение и высокая скорость.
👉 @Cpportal
Каждый байт запроса обрабатывается по одному, с одной трансформацией состояния за символ.
Весь HTTP/1.1 request line проходит через этот парсер в один проход, без промежуточных буферизаций или повторного анализа.
Это классический подход для высокопроизводительных C-серверов: минимальные аллокации, предсказуемое поведение и высокая скорость.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍3🔥3
Один геймер превратил GTA Online с 6-минутной загрузкой в игру с секундной загрузкой за один уикенд.
Rockstar терпел эту проблему почти 7 лет.
t0st разобрал игру на уровне реверса и выявил два узких места:
Один парсер каждый шаг вызывал
Другая функция делала почти 2 миллиарда проверок дубликатов на 63 000 уникальных предметов, хотя в этом не было необходимости.
То же самое игра, те же данные — всего несколько строк кода решают разницу между минутами и секундами.
t0st решил проблему максимально просто:
Для парсера JSON он не переписывал весь движок, а просто «повесил» хук на
В итоге загрузка GTA Online упала с ~6 минут до менее чем 2 минут.
t0st позже сказал, что исправление выглядело как задача, которую один разработчик мог бы сделать меньше чем за день.
Rockstar выплатили ему $10,000 через программу bug bounty.
👉 @Cpportal
Rockstar терпел эту проблему почти 7 лет.
t0st разобрал игру на уровне реверса и выявил два узких места:
Один парсер каждый шаг вызывал
strlen() на оставшихся 10 МБ JSON, повторяя лишнюю работу.Другая функция делала почти 2 миллиарда проверок дубликатов на 63 000 уникальных предметов, хотя в этом не было необходимости.
// bug 1 - ChakraCore sscanf implementation
// github.com/chakra-core/ChakraCore/blob/master/pal/src/safecrt/sscanf.c
int sscanf(const char *string, const char *format, ...) {
size_t count = strlen(string); // scans the whole string before parsing starts
return input_s_l(..., string, count, ...);
}
// bug 2 - from t0st's decompilation notes
char __fastcall netcat_insert_dedupe(
uint64_t catalog,
uint64_t *key,
uint64_t *item
) {
uint64_t not_a_hashmap = catalog + 88;
if (!(*(uint8_t(__fastcall**)(uint64_t*))(item + 48))(item))
return 0;
array_find_and_insert(not_a_hashmap, key, &item); // linear search on every insert
}
То же самое игра, те же данные — всего несколько строк кода решают разницу между минутами и секундами.
t0st решил проблему максимально просто:
Для парсера JSON он не переписывал весь движок, а просто «повесил» хук на
strlen() и кешировал результат, чтобы не пересчитывать его каждый раз. Для проверки дубликатов он заметил, что элементы уже уникальные, и пропустил проверку полностью.// fix 1 - cache strlen results for very large strings
size_t strlen_cacher(char *str) {
static char *start, *end;
if (start && str >= start && str <= end)
return end - str;
size_t len = __builtin_strlen(str);
if (len > 20000) {
start = str;
end = str + len;
}
return len;
}
// fix 2 - skip the duplicate lookup entirely
char __fastcall netcat_insert_dedupe_hooked(
uint64_t catalog,
uint64_t *key,
uint64_t *item
) {
uint64_t not_a_hashmap = catalog + 88;
if (!(*(uint8_t(__fastcall**)(uint64_t*))(item + 48))(item))
return 0;
netcat_insert_direct(not_a_hashmap, key, &item); // bypass the scan
}
В итоге загрузка GTA Online упала с ~6 минут до менее чем 2 минут.
t0st позже сказал, что исправление выглядело как задача, которую один разработчик мог бы сделать меньше чем за день.
Rockstar выплатили ему $10,000 через программу bug bounty.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤33🔥6👍5😁1
В C есть оператор «идёт к», которого так и не добавили в стандарт.
Выглядит как оператор, но на самом деле им не является.
Компилятор интерпретирует его как:
Сначала выполняется постдекремент, затем результат сравнивается с нулём.
👉 @Cpportal
Выглядит как оператор, но на самом деле им не является.
Компилятор интерпретирует его как:
(x--) > 0
Сначала выполняется постдекремент, затем результат сравнивается с нулём.
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱19👍12❤5👎4🤔1
Стандартный макрос
Во время сравнения оба значения приводятся к
В ядре Linux макрос
👉 @Cpportal
min(a, b) может вернуть неверный результат, если один аргумент знаковый (signed), а другой беззнаковый (unsigned).Во время сравнения оба значения приводятся к
unsigned, поэтому отрицательные числа превращаются в огромные положительные значения.В ядре Linux макрос
min() защищает от такой ошибки: он выполняет проверку типов и превращает подобные случаи в ошибку компиляции.Please open Telegram to view this post
VIEW IN TELEGRAM
😁10❤8👍2
std::expected из C++23 может оказаться одним из самых практичных нововведений в языке за последние годы.Он даёт структурированный способ обработки ошибок без использования исключений и выходных параметров.
Вызывающий код не может случайно проигнорировать возможность ошибки, при этом здесь нет управления потоком выполнения через исключения.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19❤3👍2👀1
Ещё одно распространённое заблуждение о C — многие думают, что строки обязательно нужно писать в кавычках. https://godbolt.org/z/qcWc4j3q3
👉 @Cpportal
#include <stdio.h>
#define puts(x...) puts(%:x)
int main() {
puts(Hello, world!);
}
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🤔7👍2👀1
Предсказание ветвлений, переименование регистров, спекулятивное выполнение, буферы записи, трансляция μops.
Огромная часть сложности современных процессоров нужна для поддержки простой иллюзии: будто инструкции выполняются строго по порядку, по одной за раз, именно так, как это описывает ISA.
Ты пишешь код под x86. Процессор переводит его во что-то другое и дальше работает уже с этим.
👉 @Cpportal
Огромная часть сложности современных процессоров нужна для поддержки простой иллюзии: будто инструкции выполняются строго по порядку, по одной за раз, именно так, как это описывает ISA.
Ты пишешь код под x86. Процессор переводит его во что-то другое и дальше работает уже с этим.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👎2🥱1💊1
В C++ появился новый оператор:
В комитете его называют cat-ears operator («оператор кошачьих ушек»).
Именно через него в язык приходит рефлексия — одно из крупнейших изменений в C++ со времён появления шаблонов.
C++26 приносит в язык compile-time reflection (P2996).
Оператор
JSON-сериализация? Без макросов, генераторов кода и километров шаблонов.
Автор предложения — Barry Revzin и ещё шесть соавторов.
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2996r13.html
https://wg21.org/
👉 @Cpportal
^^
В комитете его называют cat-ears operator («оператор кошачьих ушек»).
Именно через него в язык приходит рефлексия — одно из крупнейших изменений в C++ со времён появления шаблонов.
C++26 приносит в язык compile-time reflection (P2996).
Оператор
^^ позволяет превратить любую сущность — тип, функцию или элемент перечисления — в compile-time представление (mirror), которое можно анализировать и преобразовывать во время компиляции.enum → строка? Одна функция.JSON-сериализация? Без макросов, генераторов кода и километров шаблонов.
Автор предложения — Barry Revzin и ещё шесть соавторов.
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2996r13.html
https://wg21.org/
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍6🤣4🥱1👀1
Если вы ещё не знакомы с этим, обязательно загляните в техническую и архитектурную документацию SQLite — там разобрано огромное количество впечатляющих инженерных деталей. Достаточно просто посмотреть на список тем, которые она охватывает.
[https://sqlite.org/docs.html]
👉 @Cpportal
[https://sqlite.org/docs.html]
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1