Для більшості це ім’я асоціюється з quicksort, але його внесок набагато ширший: quickselect, Hoare logic, CSP, вплив на дизайн мов і взагалі на те, як ми думаємо про correctness та concurrency.
Про quicksort цікаво не лише те, що він швидкий. Там сильна сама ідея partition. Із неї природно виростає quickselect: median, p95, k-й елемент, top-k cutoff - без повного сортування. У багатьох таких задачах інженери автоматично беруть heap, але для одноразового selection на статичному масиві partition-підхід часто простіший і дешевший: in-place, без зайвих структур, із середнім O(n). Саме тому ця ідея досі живе в алгоритмах на кшталт nth_element в C++.
Ще важливіше для мене - CSP, Communicating Sequential Processes. У своїй роботі Хоар запропонував дивитися на concurrent system як на композицію незалежних sequential processes, які взаємодіють через явну комунікацію. Ключовий момент тут у тому, що send/receive - це не просто передача даних, а синхронізація: подія відбувається лише коли обидві сторони ready. Це rendezvous-модель. Плюс guarded choice: процес може чекати на кілька можливих communication events і продовжити виконання по тому, який став доступним. Дуже багато того, що сьогодні здається “природним” у Go - channels, select, і сама ідея share memory by communicating - росте саме звідси, офіційні матеріали Go і Rob Pike прямо відсилають до CSP. Хоча Go, звісно, не є буквальним CSP.
І окремо - Hoare logic. Трійки {P} C {Q} дали просту, але дуже сильну рамку: код треба не лише тестувати, а й уміти пояснити, за яких передумов він коректний і що гарантує після виконання.
Майже точно я згадав не все. Але, мабуть, це і є найкращий показник масштабу людини: коли навіть короткий список її ідей уже змінив цілу індустрію. Дякую вам, сер Ентоні 🫡
Про quicksort цікаво не лише те, що він швидкий. Там сильна сама ідея partition. Із неї природно виростає quickselect: median, p95, k-й елемент, top-k cutoff - без повного сортування. У багатьох таких задачах інженери автоматично беруть heap, але для одноразового selection на статичному масиві partition-підхід часто простіший і дешевший: in-place, без зайвих структур, із середнім O(n). Саме тому ця ідея досі живе в алгоритмах на кшталт nth_element в C++.
Ще важливіше для мене - CSP, Communicating Sequential Processes. У своїй роботі Хоар запропонував дивитися на concurrent system як на композицію незалежних sequential processes, які взаємодіють через явну комунікацію. Ключовий момент тут у тому, що send/receive - це не просто передача даних, а синхронізація: подія відбувається лише коли обидві сторони ready. Це rendezvous-модель. Плюс guarded choice: процес може чекати на кілька можливих communication events і продовжити виконання по тому, який став доступним. Дуже багато того, що сьогодні здається “природним” у Go - channels, select, і сама ідея share memory by communicating - росте саме звідси, офіційні матеріали Go і Rob Pike прямо відсилають до CSP. Хоча Go, звісно, не є буквальним CSP.
І окремо - Hoare logic. Трійки {P} C {Q} дали просту, але дуже сильну рамку: код треба не лише тестувати, а й уміти пояснити, за яких передумов він коректний і що гарантує після виконання.
Майже точно я згадав не все. Але, мабуть, це і є найкращий показник масштабу людини: коли навіть короткий список її ідей уже змінив цілу індустрію. Дякую вам, сер Ентоні 🫡
👍25🫡17❤8
Хотів поділитися корисною штукою - почав користуватися додатком Opal.
Він блокує сповіщення та доступ до вибраних апок у ті години, коли хочеться нормально попрацювати без постійних відволікань. І це блокування складно обійти (навіть не знаю як). Як результат, це поступово відбило звичку зранку одразу хапатися за телефон і читати новини. Через це ранок став значно спокійнішим. Загалом, дуже рекомендую тим, хто хоче трохи краще контролювати свою увагу.
Ну і приємний бонус: для України річна підписка на PRO у мене показує $0.49.
А які у вас є свої маленькі хаки чи біохаки, які реально покращили фокус, ранок або загальний стан? Буде цікаво зібрати мікропоради в коментарях.
Він блокує сповіщення та доступ до вибраних апок у ті години, коли хочеться нормально попрацювати без постійних відволікань. І це блокування складно обійти (навіть не знаю як). Як результат, це поступово відбило звичку зранку одразу хапатися за телефон і читати новини. Через це ранок став значно спокійнішим. Загалом, дуже рекомендую тим, хто хоче трохи краще контролювати свою увагу.
Ну і приємний бонус: для України річна підписка на PRO у мене показує $0.49.
А які у вас є свої маленькі хаки чи біохаки, які реально покращили фокус, ранок або загальний стан? Буде цікаво зібрати мікропоради в коментарях.
👍28❤10🤔8😁1
Тому вирішив подивитися на цифри:
у Citadel Securities вийшов репорт із графіком, де видно, що загальна кількість вакансій на Indeed падає ще з січня 2024 року. Але вакансії саме для software engineers, навпаки, ростуть з червня 2025. Схожу картину показує і Pragmatic Engineer на основі даних TrueUp: з 2023 року кількість інженерних вакансій у tech-компаніях теж йде вгору.
І тут цікаво не лише саме зростання, а й контраст. Паралельно ми постійно читаємо, що "код скоро писатиме AI", "вхід у професію закривається". Але якщо подивитися на дії, а не на заголовки, то AI-компанії, big tech і сильні продуктові гравці чомусь не припиняють найм. Навпаки.
Для мене з цього висновок доволі простий. Зараз хороший час, щоб вчитись програмуванню. І хороший час, щоб бути сильним інженером.
Так, просто “знати синтаксис” уже недостатньо. Так, конкуренція вища, і планка теж вища. Але потреба в людях, які вміють думати, будувати системи, розбиратися у нюансах/компромісах, читати чужий код, дебажити прод, працювати з невизначеністю й доводити рішення до результату - нікуди не зникла.
Мені навіть здається, що зараз цінність хорошого інженера стала більш видимою. Бо коли рутинні шматки роботи спрощуються, ще краще видно, хто просто щось кодив, а хто реально вміє вирішувати задачі.
Тому я б точно не вівся на наратив "все, розробка закінчилась". Скоріше навпаки: професія змінюється, інструменти змінюються, але сильні інженери все ще дуже потрібні.
у Citadel Securities вийшов репорт із графіком, де видно, що загальна кількість вакансій на Indeed падає ще з січня 2024 року. Але вакансії саме для software engineers, навпаки, ростуть з червня 2025. Схожу картину показує і Pragmatic Engineer на основі даних TrueUp: з 2023 року кількість інженерних вакансій у tech-компаніях теж йде вгору.
І тут цікаво не лише саме зростання, а й контраст. Паралельно ми постійно читаємо, що "код скоро писатиме AI", "вхід у професію закривається". Але якщо подивитися на дії, а не на заголовки, то AI-компанії, big tech і сильні продуктові гравці чомусь не припиняють найм. Навпаки.
Для мене з цього висновок доволі простий. Зараз хороший час, щоб вчитись програмуванню. І хороший час, щоб бути сильним інженером.
Так, просто “знати синтаксис” уже недостатньо. Так, конкуренція вища, і планка теж вища. Але потреба в людях, які вміють думати, будувати системи, розбиратися у нюансах/компромісах, читати чужий код, дебажити прод, працювати з невизначеністю й доводити рішення до результату - нікуди не зникла.
Мені навіть здається, що зараз цінність хорошого інженера стала більш видимою. Бо коли рутинні шматки роботи спрощуються, ще краще видно, хто просто щось кодив, а хто реально вміє вирішувати задачі.
Тому я б точно не вівся на наратив "все, розробка закінчилась". Скоріше навпаки: професія змінюється, інструменти змінюються, але сильні інженери все ще дуже потрібні.
❤41🔥10💯8👍3
🐍 Колись у нас в команді виникла дискусія в одному з піарів — як правильно перевіряти список на порожність: if not mylist чи len(mylist) == 0. Частина наполягала, що len() — читабельніше. Інша казала, що перший варіант більш пітонячий. Кожен при своїй думці. Я вирішив розібратися до кінця, бо ця перевірка виконувалася в гарячому циклі.
Спойлер: пітон-лайк варіант швидший майже вдвічі. І причини цього глибоко всередині CPython VM. Дивимося на заміри:
Майже 2x різниця для операції. Чому так?
У CPython всі об'єкти мають спільну ієрархію. PyObject — базовий хедер для кожного типу:
PyVarObject — розширює PyObject для sequence-типів:
PyListObject — власне list, наслідує PyVarObject:
PyObject → PyVarObject → PyListObject
Поле ob_size завжди лежить прямо в хедері. Але щоб дістатись до нього через ob_type, потрібно пройти ланцюжок: ob_type → tp_as_sequence → sq_length → list_length → ob_size. 5 рівнів pointer indirection — і кожен з них потенційний cache miss.
⚡️ if not mylist — що відбувається під капотом
Компілятор генерує лише 2 VM-інструкції: LOAD_FAST + TO_BOOL. TO_BOOL — інструкція, яка не знає тип об'єкта наперед. При першому виконанні йде через ті самі 5 рівнів indirection.
Але починаючи з CPython 3.12, після першого виклику спрацьовує instruction specialization — VM замінює TO_BOOL на TO_BOOL_LIST. Ця спеціалізована інструкція читає ob_size напряму, одним memory access, без зайвих dereference'ів. Фактично — inline-функція без overhead'у виклику. Результат: в hot loop-і перевірка зводиться до одного читання з пам'яті.
🐢 len(mylist) == 0 — де губиться час
VM генерує 5 інструкцій: LOAD_GLOBAL, LOAD_FAST, CALL, LOAD_CONST, COMPARE_OP.
1. Function call overhead — CALL це не безкоштовно. Stack frame setup, register spills, jump до C-коду. В tight loop'і накопичується.
2. len() теж не знає тип наперед — всередині йде через ob_type → tp_as_sequence → sq_length, ті самі 5 рівнів indirection. І на відміну від TO_BOOL_LIST — не отримує спеціалізації.
3. Порівняння з нулем — після повернення з len() VM ще виконує LOAD_CONST 0 і COMPARE_OP. Дві зайві операції на кожну ітерацію.
🔬 Чому переходи за вказівниками — це погано?
L1 cache access — ~4 такти
Cache miss → main memory — 100–200 тактів. Чим глибший ланцюжок dereference'ів, тим вища ймовірність вийти за межі кешу. 5 рівнів замість одного — це потенційно на порядок дорожче при cold cache. Особливо помітно в будь-якому performance-critical коді, де перевірка на порожність стоїть у циклі.
Спойлер: пітон-лайк варіант швидший майже вдвічі. І причини цього глибоко всередині CPython VM. Дивимося на заміри:
timeit.timeit(
"not mylist",
number=100_000_000,
globals={"mylist": list()}
)
# 0.869 сек
timeit.timeit(
"len(mylist) == 0",
number=100_000_000,
globals={"mylist": list()}
)
# 1.939 сек
Майже 2x різниця для операції. Чому так?
У CPython всі об'єкти мають спільну ієрархію. PyObject — базовий хедер для кожного типу:
struct _object {
Py_ssize_t ob_refcnt; // reference count
PyTypeObject *ob_type; // тип + function pointers
};
PyVarObject — розширює PyObject для sequence-типів:
typedef struct {
PyObject ob_base;
Py_ssize_t ob_size; // кількість елементів
} PyVarObject;
PyListObject — власне list, наслідує PyVarObject:
typedef struct {
PyObject_VAR_HEAD
PyObject **ob_item; // масив елементів
Py_ssize_t allocated; // скільки пам'яті виділено
} PyListObject;
PyObject → PyVarObject → PyListObject
Поле ob_size завжди лежить прямо в хедері. Але щоб дістатись до нього через ob_type, потрібно пройти ланцюжок: ob_type → tp_as_sequence → sq_length → list_length → ob_size. 5 рівнів pointer indirection — і кожен з них потенційний cache miss.
⚡️ if not mylist — що відбувається під капотом
Компілятор генерує лише 2 VM-інструкції: LOAD_FAST + TO_BOOL. TO_BOOL — інструкція, яка не знає тип об'єкта наперед. При першому виконанні йде через ті самі 5 рівнів indirection.
Але починаючи з CPython 3.12, після першого виклику спрацьовує instruction specialization — VM замінює TO_BOOL на TO_BOOL_LIST. Ця спеціалізована інструкція читає ob_size напряму, одним memory access, без зайвих dereference'ів. Фактично — inline-функція без overhead'у виклику. Результат: в hot loop-і перевірка зводиться до одного читання з пам'яті.
🐢 len(mylist) == 0 — де губиться час
VM генерує 5 інструкцій: LOAD_GLOBAL, LOAD_FAST, CALL, LOAD_CONST, COMPARE_OP.
1. Function call overhead — CALL це не безкоштовно. Stack frame setup, register spills, jump до C-коду. В tight loop'і накопичується.
2. len() теж не знає тип наперед — всередині йде через ob_type → tp_as_sequence → sq_length, ті самі 5 рівнів indirection. І на відміну від TO_BOOL_LIST — не отримує спеціалізації.
3. Порівняння з нулем — після повернення з len() VM ще виконує LOAD_CONST 0 і COMPARE_OP. Дві зайві операції на кожну ітерацію.
🔬 Чому переходи за вказівниками — це погано?
L1 cache access — ~4 такти
Cache miss → main memory — 100–200 тактів. Чим глибший ланцюжок dereference'ів, тим вища ймовірність вийти за межі кешу. 5 рівнів замість одного — це потенційно на порядок дорожче при cold cache. Особливо помітно в будь-якому performance-critical коді, де перевірка на порожність стоїть у циклі.
🔥38👍11❤7🤯2
Як ми пришвидшили запит до БД в 100 разів 🐘
Писали Python-сервіс, який за набором device ID-шників витягував дані з таблиці на кілька мільйонів рядків. Логіка проста — є список девайсів, які нас цікавлять, йдемо в базу:
Виглядає невинно. І працювало нормально — поки кількість девайсів була маленькою.
Але коли девайсів стало ~15к, запит почав виконуватися 20+ секунд. Полізли в EXPLAIN ANALYZE і побачили Bitmap Heap Scan з ручним перебором рядків.
Проблема в тому, що Postgres бачить ARRAY[...] як один суцільний параметр і не розкладає його на окремі значення на етапі планування. Тому він не може сказати “ось 15к конкретних ключів, піду за кожним в індекс”. Натомість робить навпаки: спочатку сканує таблицю за умовою region_id, збирає всі кандидати — а потім фільтрує кожен рядок вручну, перевіряючи, чи є його id в масиві.
Із 15к девайсів це десятки тисяч зайвих перевірок. І це при тому, що таблиця частково була закешована в RAM — тобто Postgres навіть не йшов на диск. Просто сам факт ручної перевірки кожного рядка вже коштував 20+ секунд. Замість “знайди мені ось ці конкретні рядки” виходить “знайди багато рядків, а потім я сам розберуся, які потрібні”.
Фікс виявився абсурдно простим — замінити ARRAY на VALUES:
VALUES (...) — це підзапит із тимчасовою таблицею. Optimizer бачить конкретні рядки, хешує їх і робить точковий Index Scan по кожному device ID. Тобто саме те, що й очікувалося від початку.
20 000 мс → 200 мс. В 100 разів швидше.
Ця історія про те, що проблеми з продуктивністю живуть на різних рівнях. Минулого разу ми говорили про Python. Тут — один рядок SQL, який ламав весь запит. Щоб бачити такі речі одразу, треба розуміти, що відбувається під капотом — і в Python, і в базах даних. Саме для цього ми запустили два курси:
🐍 Python Advanced — модель пам'яті CPython, GIL, multiprocessing, async, zero-copy підходи. Читає Senior Python Engineer з N-iX, яка проєктує high-load системи. Старт сьогодні.
🗄️ Database Internals — як написати свою БД і по ходу розібратися, як насправді працюють індекси, join, order by, як дані зберігаються на диску, query optimizer, транзакції та MVCC. Читає інженер Embucket, ex-SingleStore, ex-Microsoft. Старт 31 березня.
Як би я хотів аби такі курси були в моєму універі :)
Писали Python-сервіс, який за набором device ID-шників витягував дані з таблиці на кілька мільйонів рядків. Логіка проста — є список девайсів, які нас цікавлять, йдемо в базу:
device_ids = [123, ...] # ~15к девайсів
cursor.execute("""
SELECT d.id, d.meta, r.region_name
FROM devices d
JOIN regions r ON d.region_id = r.id
WHERE d.id = ANY (ARRAY[%s])
AND d.region_id = 1
""", (device_ids,))
Виглядає невинно. І працювало нормально — поки кількість девайсів була маленькою.
Але коли девайсів стало ~15к, запит почав виконуватися 20+ секунд. Полізли в EXPLAIN ANALYZE і побачили Bitmap Heap Scan з ручним перебором рядків.
Проблема в тому, що Postgres бачить ARRAY[...] як один суцільний параметр і не розкладає його на окремі значення на етапі планування. Тому він не може сказати “ось 15к конкретних ключів, піду за кожним в індекс”. Натомість робить навпаки: спочатку сканує таблицю за умовою region_id, збирає всі кандидати — а потім фільтрує кожен рядок вручну, перевіряючи, чи є його id в масиві.
Із 15к девайсів це десятки тисяч зайвих перевірок. І це при тому, що таблиця частково була закешована в RAM — тобто Postgres навіть не йшов на диск. Просто сам факт ручної перевірки кожного рядка вже коштував 20+ секунд. Замість “знайди мені ось ці конкретні рядки” виходить “знайди багато рядків, а потім я сам розберуся, які потрібні”.
Фікс виявився абсурдно простим — замінити ARRAY на VALUES:
values = ",".join(f"({id})" for id in device_ids)
cursor.execute(f"""
SELECT d.id, d.meta, r.region_name
FROM devices d
JOIN regions r ON d.region_id = r.id
WHERE d.id = ANY (VALUES {values})
AND d.region_id = 1
""")
VALUES (...) — це підзапит із тимчасовою таблицею. Optimizer бачить конкретні рядки, хешує їх і робить точковий Index Scan по кожному device ID. Тобто саме те, що й очікувалося від початку.
20 000 мс → 200 мс. В 100 разів швидше.
Ця історія про те, що проблеми з продуктивністю живуть на різних рівнях. Минулого разу ми говорили про Python. Тут — один рядок SQL, який ламав весь запит. Щоб бачити такі речі одразу, треба розуміти, що відбувається під капотом — і в Python, і в базах даних. Саме для цього ми запустили два курси:
🐍 Python Advanced — модель пам'яті CPython, GIL, multiprocessing, async, zero-copy підходи. Читає Senior Python Engineer з N-iX, яка проєктує high-load системи. Старт сьогодні.
🗄️ Database Internals — як написати свою БД і по ходу розібратися, як насправді працюють індекси, join, order by, як дані зберігаються на диску, query optimizer, транзакції та MVCC. Читає інженер Embucket, ex-SingleStore, ex-Microsoft. Старт 31 березня.
Як би я хотів аби такі курси були в моєму універі :)
🔥40👍9❤3😱1
Parameter Golf від OpenAI
OpenAI нещодавно запустила цікавий контест — потрібно натренувати максимально якісну модель фіксованого розміру (до 16 MB) на заданому датасеті.
Лідерборд і код сабмітів відкриті, тому вже зараз можна подивитися, які оптимізації реально працюють.
Що особливо круто: розміри задачі невеликі, тобто не потрібна велика інфраструктура, але при цьому це все ще реальна ML-інженерія, а не іграшка. Так, GPU потрібні, але OpenAI дає кредити для експериментів, якщо хочете взяти участь.
💡 І цікавий момент. Потрапити на співбесіду в OpenAI - складно, навіть якщо ти сильний інженер. І цей контест - це один зі способів знайти крутих людей серед великої кількості резюме.
OpenAI нещодавно запустила цікавий контест — потрібно натренувати максимально якісну модель фіксованого розміру (до 16 MB) на заданому датасеті.
Лідерборд і код сабмітів відкриті, тому вже зараз можна подивитися, які оптимізації реально працюють.
Що особливо круто: розміри задачі невеликі, тобто не потрібна велика інфраструктура, але при цьому це все ще реальна ML-інженерія, а не іграшка. Так, GPU потрібні, але OpenAI дає кредити для експериментів, якщо хочете взяти участь.
💡 І цікавий момент. Потрапити на співбесіду в OpenAI - складно, навіть якщо ти сильний інженер. І цей контест - це один зі способів знайти крутих людей серед великої кількості резюме.
GitHub
GitHub - openai/parameter-golf: Train the smallest LM you can that fits in 16MB. Best model wins!
Train the smallest LM you can that fits in 16MB. Best model wins! - openai/parameter-golf
👍8🔥7❤2
Якщо вам здається, що більше потоків = швидше — дуже раджу подивитися це відео від відомої HFT компанії: про реальну вартість concurrency на рівні CPU cache lines, синхронізації і того, чому іноді багатопоточність робить систему повільнішою. Якщо вам зайде лектор Jon Gjengset - він також викладає курс MIT https://missing.csail.mit.edu/ Курс про речі, які майже не вчать в університеті: shell, git, debugging, profiling, tooling і вчать інтернів на стажуванні.
❤26👍10🔥6🤔1
https://bytebytego.com/
Дає безкоштовний доступ до матеріалів на місяць
Дає безкоштовний доступ до матеріалів на місяць
ByteByteGo
System Design · Coding · Behavioral · Machine Learning Interviews
Ace Every Stage of Your Next Technical Interview
🔥38❤2❤🔥1
Зміна місця, роботи чи друзів може допомогти покращити твоє життя, але ніщо не зрівняється зі зміною твого мислення. Стан твого розуму впливає на все, що ти сприймаєш.
❤56💯9👍5✍3🎉1💊1
CS 153: Frontier Systems | Stanford University
https://cs153.stanford.edu/
Прикольний тим, що це спроба пояснити, як виглядає вся АІ система загалом. Бо зазвичай ми бачимо тільки верхівку — ChatGPT, Copilot, Midjourney. А під цим — величезний стек: датацентри, GPU, distributed systems, тренування моделей, і тільки потім вже продукт.
І от весь цей стек вони проходять шар за шаром. Причому через людей, які це реально будують прямо зараз.
Типу:
Jensen Huang розповідає про залізо,
Andrej Karpathy — про моделі,
Sam Altman — про продукт і майбутнє,
Satya Nadella — як це все впливає на великі компанії.
По суті це такий system design для AI епохи. І головна думка AI — це вже давно не “модель”, це інфраструктура. Якщо ти бачиш тільки модель — ти бачиш десь 10% картини.
Перша лекція
https://cs153.stanford.edu/
Прикольний тим, що це спроба пояснити, як виглядає вся АІ система загалом. Бо зазвичай ми бачимо тільки верхівку — ChatGPT, Copilot, Midjourney. А під цим — величезний стек: датацентри, GPU, distributed systems, тренування моделей, і тільки потім вже продукт.
І от весь цей стек вони проходять шар за шаром. Причому через людей, які це реально будують прямо зараз.
Типу:
Jensen Huang розповідає про залізо,
Andrej Karpathy — про моделі,
Sam Altman — про продукт і майбутнє,
Satya Nadella — як це все впливає на великі компанії.
По суті це такий system design для AI епохи. І головна думка AI — це вже давно не “модель”, це інфраструктура. Якщо ти бачиш тільки модель — ти бачиш десь 10% картини.
Перша лекція
cs153.stanford.edu
CS 153: Frontier Systems | Stanford University
From energy, silicon and models to applications, security and deployment policy, the infrastructure stack is undergoing a generational rewrite. Each week, this course puts you in the room with the global leaders solving the biggest bottlenecks on frontier…
❤31🔥17👍9
Зранку трохи пустив сльозу.
Почав викладати в ліцеї інформатику, перша пара і раптом о 9:00 всі ліцеїсти просто встали, щоб вшанувати память загиблих. Причому, що жодного сигналу не було — оповіщувач зламався, то я спочатку навіть трохи розгубився і не одразу зрозумів, що відбувається.
А потім в ліцеї лунає гімн, а вони стоять, приклавши руку до серця.
У такі секунди просто відчуваєш, які хороші діти у нас ростуть.
Почав викладати в ліцеї інформатику, перша пара і раптом о 9:00 всі ліцеїсти просто встали, щоб вшанувати память загиблих. Причому, що жодного сигналу не було — оповіщувач зламався, то я спочатку навіть трохи розгубився і не одразу зрозумів, що відбувається.
А потім в ліцеї лунає гімн, а вони стоять, приклавши руку до серця.
У такі секунди просто відчуваєш, які хороші діти у нас ростуть.
💔113❤32🫡7
4 роки тому одне інтерв’ю змінило моє життя.
Березень 2022-го. Війну я зустрів за кордоном. Постійно "на трубі" з друзями. Наш чат на трьох, де раніше були лише меми, перетворився на нескінченне "як ви?".
Одного вечора, коли «Азов» уже був у повному оточенні, у чат прилетіло посилання. Інтерв’ю з Денисом Прокопенком. Відкрив автоматично, щоб відволіктися. І залип. Він говорив чітко, виважено, предметно. Про цивільних, про ситуацію в місті, про полк, що стримує навалу ворога. Сказати, що я був вражений, — це нічого не сказати.
Я така людина, що завжди шукає коріння. Мені цікаво, як людина зростала, що на неї впливало. Тоді я ще не знав, хто такий Редіс. Тому почав вивчати. Ось просто сухі факти з мережі: ультрас «Динамо» та викладач англійської й німецької за освітою. 2014-й — доброволець, солдат. У 26 років — командир «Азову». Герой України. Сьогодні — бригадний генерал.
Але якщо подивитися інтерв'ю про нього від людей, що з ним перетиналися, то всі як один пишуть про фанатичну працездатність. Він — приклад того, як гострий розум множиться на трудоголізм. Один епізод, який пояснює все: Неділя. 04:00 ранку. Єдиний вихідний за тиждень. Дзвінок: «Вибач, що розбудив. Є термінова задача». Це і є Редіс. "Моє серце, моя душа, моє тіло належать Азову". Це і є Редіс.
До чого я це пишу? Після того інтерв’ю я невдовзі повернувся до Києва. Пройшло 4 роки. Сьогодні мені не соромно повідомити, що наша школа csosvita.com перетнула рубіж у 3 000 000 гривень допомоги Силам оборони. Безкоштовне навчання для військових. Понад 1 000 000 гривень ми спрямували саме на «Азов». І від сьогодні ми — їхні офіційні партнери.
Так, я не військовий. Але це мій спосіб бути корисним у цій війні, поки без зброї в руках. Просто робити максимум там, де я є. Просто робити якісну Computer Science освіту.
Дякую за приклад, командире.
"Без бою немає слави" (с) Редіс.
Березень 2022-го. Війну я зустрів за кордоном. Постійно "на трубі" з друзями. Наш чат на трьох, де раніше були лише меми, перетворився на нескінченне "як ви?".
Одного вечора, коли «Азов» уже був у повному оточенні, у чат прилетіло посилання. Інтерв’ю з Денисом Прокопенком. Відкрив автоматично, щоб відволіктися. І залип. Він говорив чітко, виважено, предметно. Про цивільних, про ситуацію в місті, про полк, що стримує навалу ворога. Сказати, що я був вражений, — це нічого не сказати.
Я така людина, що завжди шукає коріння. Мені цікаво, як людина зростала, що на неї впливало. Тоді я ще не знав, хто такий Редіс. Тому почав вивчати. Ось просто сухі факти з мережі: ультрас «Динамо» та викладач англійської й німецької за освітою. 2014-й — доброволець, солдат. У 26 років — командир «Азову». Герой України. Сьогодні — бригадний генерал.
Але якщо подивитися інтерв'ю про нього від людей, що з ним перетиналися, то всі як один пишуть про фанатичну працездатність. Він — приклад того, як гострий розум множиться на трудоголізм. Один епізод, який пояснює все: Неділя. 04:00 ранку. Єдиний вихідний за тиждень. Дзвінок: «Вибач, що розбудив. Є термінова задача». Це і є Редіс. "Моє серце, моя душа, моє тіло належать Азову". Це і є Редіс.
До чого я це пишу? Після того інтерв’ю я невдовзі повернувся до Києва. Пройшло 4 роки. Сьогодні мені не соромно повідомити, що наша школа csosvita.com перетнула рубіж у 3 000 000 гривень допомоги Силам оборони. Безкоштовне навчання для військових. Понад 1 000 000 гривень ми спрямували саме на «Азов». І від сьогодні ми — їхні офіційні партнери.
Так, я не військовий. Але це мій спосіб бути корисним у цій війні, поки без зброї в руках. Просто робити максимум там, де я є. Просто робити якісну Computer Science освіту.
Дякую за приклад, командире.
"Без бою немає слави" (с) Редіс.
👍82❤🔥46🔥10❤9👏6
Branch Predictor: скільки if-ів — це забагато?
Нещодавно копався в hot path нашого коду і натрапив на класику:
І задумався: ми ніколи не запускаємо з debug = true. Чи є якась ціна у цього if, який ніколи не спрацьовує? А якщо таких if-ів буде 10? 100? 1000? Старе правило каже: повністю передбачуваний branch — це ~0 тактів CPU. Але наскільки це правда? Почав розбиратися.
Чому взагалі існує branch prediction? Сучасний CPU — це конвеєр. Поки одна інструкція виконується, наступна вже декодується, а та, що після — вже завантажується з пам'яті. Все летить паралельно. Але що відбувається, коли CPU натикається на jmp або if?
CPU ще не знає, куди стрибати — інструкція ще навіть не декодована. Але fetch unit вже хоче наступну! Якщо він вгадає неправильно — марно витрачені такти. Це називається frontend bubble.
Саме тому існує Branch Predictor Unit (BPU) — спеціальний блок CPU, який намагається вгадати адресу наступної інструкції ще до того, як branch буде декодовано. У нього мінімум інформації: лише адреса поточної інструкції та історія попередніх переходів. І він вгадує з дуже високою точністю.
Ключова структура всередині BPU — Branch Target Buffer (BTB). Це, по суті, кеш, де CPU запам'ятовує: "минулого разу ця інструкція стрибнула ось сюди".
Далі вирішив провести експеримент: скільки branchів витримує BTB? І натрапив на такий блог пост від https://blog.cloudflare.com/branch-predictor/
Дуже раджу почитати.
Практичні поради (TL;DR)
1. Never-taken branch — безкоштовний. Той if (debug) нічого не коштує, якщо він ніколи не true. Можете сміливо залишати — BTB про нього навіть не знає.
2. Always-taken branch коштує BTB-слот. Кожен jmp, кожен taken if, кожен call + ret — це запис у BTB. На x86 у вас є бюджет ~4096 слотів.
3. Hot loop краще тримати < 4096 taken branches. Інакше BTB переповнюється, і кожен branch стає у 3–7 разів дорожчим.
4. Функцій у hot path — менше ніж 2000. Бо call + ret = 2 BTB-записи.
5. На x86 тримайте hot code < 16 KB. На M1 — ідеально < 4 KB.
6. На Intel не вирівнюйте branch-і по 64 байти. Associativity BTB зіграє проти вас.
Якщо пишете performance-critical код — рахуйте свої branch-і. CPU не всемогутній, навіть якщо дуже старається.
Нещодавно копався в hot path нашого коду і натрапив на класику:
if (debug) {
log("...");
}
І задумався: ми ніколи не запускаємо з debug = true. Чи є якась ціна у цього if, який ніколи не спрацьовує? А якщо таких if-ів буде 10? 100? 1000? Старе правило каже: повністю передбачуваний branch — це ~0 тактів CPU. Але наскільки це правда? Почав розбиратися.
Чому взагалі існує branch prediction? Сучасний CPU — це конвеєр. Поки одна інструкція виконується, наступна вже декодується, а та, що після — вже завантажується з пам'яті. Все летить паралельно. Але що відбувається, коли CPU натикається на jmp або if?
BR label_a;
X1 ; <- CPU може завантажити цю інструкцію "про всяк"
...
label_a:
Y1 ; <- а виконувати треба ось цю
CPU ще не знає, куди стрибати — інструкція ще навіть не декодована. Але fetch unit вже хоче наступну! Якщо він вгадає неправильно — марно витрачені такти. Це називається frontend bubble.
Саме тому існує Branch Predictor Unit (BPU) — спеціальний блок CPU, який намагається вгадати адресу наступної інструкції ще до того, як branch буде декодовано. У нього мінімум інформації: лише адреса поточної інструкції та історія попередніх переходів. І він вгадує з дуже високою точністю.
Ключова структура всередині BPU — Branch Target Buffer (BTB). Це, по суті, кеш, де CPU запам'ятовує: "минулого разу ця інструкція стрибнула ось сюди".
Далі вирішив провести експеримент: скільки branchів витримує BTB? І натрапив на такий блог пост від https://blog.cloudflare.com/branch-predictor/
Дуже раджу почитати.
Практичні поради (TL;DR)
1. Never-taken branch — безкоштовний. Той if (debug) нічого не коштує, якщо він ніколи не true. Можете сміливо залишати — BTB про нього навіть не знає.
2. Always-taken branch коштує BTB-слот. Кожен jmp, кожен taken if, кожен call + ret — це запис у BTB. На x86 у вас є бюджет ~4096 слотів.
3. Hot loop краще тримати < 4096 taken branches. Інакше BTB переповнюється, і кожен branch стає у 3–7 разів дорожчим.
4. Функцій у hot path — менше ніж 2000. Бо call + ret = 2 BTB-записи.
5. На x86 тримайте hot code < 16 KB. На M1 — ідеально < 4 KB.
6. На Intel не вирівнюйте branch-і по 64 байти. Associativity BTB зіграє проти вас.
Якщо пишете performance-critical код — рахуйте свої branch-і. CPU не всемогутній, навіть якщо дуже старається.
The Cloudflare Blog
Branch predictor: How many "if"s are too many? Including x86 and M1 benchmarks!
Is it ok to have if clauses that will basically never be run? Surely, there must be some performance cost to that...
🔥28❤2❤🔥1
Midnight Code Cup 2026 — як AI змінив змагання
Пройшов кваліфікаційний раунд MCC https://midnightcodecup.org/. Задачі можна подивитись на Codeforces (на жаль, мають відношення до русні 🤮), і вони справді цікаві. Але найцікавіше — спостерігати за роллю AI у змаганнях.
Ще минулого літа на фіналі MCC команди вже використовували AI, але ближче до кінця контесту на топових місцях були ті, хто писав код руками — бо AI-код було складно підтримувати. Зараз ситуація кардинально змінилась: майже всі топові команди працювали через агентів, по суті кажучи їм, що робити, а не вирішуючи задачі самостійно. Ті, хто намагався все робити по-старому, витратили купу часу на бойлерплейт і не встигли реалізувати щось серйозне. Нагадує ситуацію в індустрії загалом: AI вже зараз дає величезне прискорення, але багато хто ігнорує це — і ризикує опинитися в програшній позиції.
Окремо цікаве спостереження про оптимізаційну задачу C: більшість топових рішень набрали приблизно 70k балів, але одна команда отримала 90k. Вони використали принципово інший підхід. І це добре ілюструє обмеження сучасних агентів — вони схильні мікрооптимізувати поточне рішення, але їм важко зробити крок назад і знайти глобально кращу стратегію.
Загалом, якщо ви ще не пробували розв'язувати задачі разом з AI-агентами — дуже раджу спробувати. Це незвичний процес, який потребує окремого навчання: треба розуміти, де агент допоможе, а де зашкодить, і як організувати роботу так, щоб легко знаходити баги, які він вносить у код.
Пройшов кваліфікаційний раунд MCC https://midnightcodecup.org/. Задачі можна подивитись на Codeforces (на жаль, мають відношення до русні 🤮), і вони справді цікаві. Але найцікавіше — спостерігати за роллю AI у змаганнях.
Ще минулого літа на фіналі MCC команди вже використовували AI, але ближче до кінця контесту на топових місцях були ті, хто писав код руками — бо AI-код було складно підтримувати. Зараз ситуація кардинально змінилась: майже всі топові команди працювали через агентів, по суті кажучи їм, що робити, а не вирішуючи задачі самостійно. Ті, хто намагався все робити по-старому, витратили купу часу на бойлерплейт і не встигли реалізувати щось серйозне. Нагадує ситуацію в індустрії загалом: AI вже зараз дає величезне прискорення, але багато хто ігнорує це — і ризикує опинитися в програшній позиції.
Окремо цікаве спостереження про оптимізаційну задачу C: більшість топових рішень набрали приблизно 70k балів, але одна команда отримала 90k. Вони використали принципово інший підхід. І це добре ілюструє обмеження сучасних агентів — вони схильні мікрооптимізувати поточне рішення, але їм важко зробити крок назад і знайти глобально кращу стратегію.
Загалом, якщо ви ще не пробували розв'язувати задачі разом з AI-агентами — дуже раджу спробувати. Це незвичний процес, який потребує окремого навчання: треба розуміти, де агент допоможе, а де зашкодить, і як організувати роботу так, щоб легко знаходити баги, які він вносить у код.
👍21❤7🔥4🤡1
Що питають на інтерв'ю у FAANG/HFT прямо зараз - дайджест за останні 2 місяці з реальних співбесід від випускників CS Osvita:
HFT (High-frequency trading) - багато задач з математики, є класична зелена книга (про яку писав вище) для повторення цього; кодінг задачі на перформенс оптимізацію можна потренувати ось тут, і дуже багато питають теорію - все що є на сайті варто пройти (від пейдж таблиць та віртуальної памяті до потоків і роботи cpu)
Стосовно кодінгу, то помітний тренд — розмиті умови, як новий стандарт: дають навмисно нечіткі задачі, щоб не можна було просто закинути в ai чи нагуглити. Під капотом це класичний алгоритм, але спочатку треба самому дійти до суті і саме так перевіряють, як ти уточнюєш, комунікуєш, думаєш вголос.
наприклад, були такі питання, що зводилися до
1. https://leetcode.com/problems/swap-adjacent-in-lr-string/description/
2. задизайнити snake game: які класи, структури даних, як би організував архітектуру
3. набір ренджів + запит "чи потрапляє число хоча б в один діапазон?", потім ускладнили - треба ще й вставку нових ренджів підтримувати. потім дійшли до цього: https://leetcode.com/problems/range-module/description/
4. є n ядер, кожне тягне одну задачу. нова задача → вибираєш вільне ядро з найменшим сумарним навантаженням. задача завершилась → оновлюєш навантаження, звільняєш ядро. треба зробити це ефективно (так, хіп 😄)
5. chemical formula decomposition — дано рядок formula та масив хімічних елементів. визначити, чи можна розбити formula на послідовність елементів з масиву. під капотом це word break: https://leetcode.com/problems/word-break/description/ — dp знизу вгору або dfs з мемоізацією по індексу
6. дві задачі в одній:
а) isValidId(str, alphabet, L, K) — перевірити, що рядок складається тільки з символів alphabet, має довжину рівно L, і жоден символ не повторюється більше K разів підряд.
б) generateStrings(alphabet, L, K) — згенерувати всі рядки довжиною L з alphabet, де жоден символ не йде підряд більше K разів.
HFT (High-frequency trading) - багато задач з математики, є класична зелена книга (про яку писав вище) для повторення цього; кодінг задачі на перформенс оптимізацію можна потренувати ось тут, і дуже багато питають теорію - все що є на сайті варто пройти (від пейдж таблиць та віртуальної памяті до потоків і роботи cpu)
Стосовно кодінгу, то помітний тренд — розмиті умови, як новий стандарт: дають навмисно нечіткі задачі, щоб не можна було просто закинути в ai чи нагуглити. Під капотом це класичний алгоритм, але спочатку треба самому дійти до суті і саме так перевіряють, як ти уточнюєш, комунікуєш, думаєш вголос.
наприклад, були такі питання, що зводилися до
1. https://leetcode.com/problems/swap-adjacent-in-lr-string/description/
2. задизайнити snake game: які класи, структури даних, як би організував архітектуру
3. набір ренджів + запит "чи потрапляє число хоча б в один діапазон?", потім ускладнили - треба ще й вставку нових ренджів підтримувати. потім дійшли до цього: https://leetcode.com/problems/range-module/description/
4. є n ядер, кожне тягне одну задачу. нова задача → вибираєш вільне ядро з найменшим сумарним навантаженням. задача завершилась → оновлюєш навантаження, звільняєш ядро. треба зробити це ефективно (так, хіп 😄)
5. chemical formula decomposition — дано рядок formula та масив хімічних елементів. визначити, чи можна розбити formula на послідовність елементів з масиву. під капотом це word break: https://leetcode.com/problems/word-break/description/ — dp знизу вгору або dfs з мемоізацією по індексу
6. дві задачі в одній:
а) isValidId(str, alphabet, L, K) — перевірити, що рядок складається тільки з символів alphabet, має довжину рівно L, і жоден символ не повторюється більше K разів підряд.
б) generateStrings(alphabet, L, K) — згенерувати всі рядки довжиною L з alphabet, де жоден символ не йде підряд більше K разів.
👍19🔥8❤7
Чому O(n) іноді програє O(n²)? Чому HashMap на мільйон записів може бути повільнішим за sorted array + binary search? Чому два потоки інколи працюють повільніше за один? Як працюють корутини? Як написати власний GC та malloc? І до чого тут ядро ОС?
Для middle/senior, без води. Cache, CPU pipeline, SIMD, branch predictor, memory layout, scheduling.
Завтра стартує курс Performance Engineering від CS Osvita — саме про це.
👉 csosvita.com/courses/performance-engineering
Для middle/senior, без води. Cache, CPU pipeline, SIMD, branch predictor, memory layout, scheduling.
Завтра стартує курс Performance Engineering від CS Osvita — саме про це.
👉 csosvita.com/courses/performance-engineering
CS Osvita
Performance Engineering
Practice writing fast software. Learn to do it right.
🔥24❤1🎉1
Класна штука — DeepWiki (https://deepwiki.com/)
Сайт, де лежить код популярних опенсорс-проєктів, і про нього можна питати AI. Наче чат з кодом, тільки він реально розуміє, що де лежить і як він працює.
Два режими:
— deep — показує конкретні шматки коду з поясненнями
— codemap — візуалізує структуру всього проєкту
Наприклад, можна подивитись як імплементований binary search у різних мовах і порівняти підходи:
chat → https://deepwiki.com/search/find-and-explain-binary-search_50038924-10a3-4609-a931-dfc83e469357?mode=deep
codemap → https://deepwiki.com/search/show-me-binarysearch-implement_e7948a6c-a72f-4748-a53f-a8c1b48135d3?mode=codemap
Або копнути як у LLVM зроблений Registry Pattern для реєстрації таргетів:
https://deepwiki.com/search/llvm-uses-a-registrar-the-targ_20014273-830e-4623-b832-24edd0fe6420?mode=fast
Рекомендую затестити не тільки для алгоритмів, а взагалі для вивчення дизайн-патернів, архітектури, будь-якого коду, який хочеться зрозуміти глибше.
Сайт, де лежить код популярних опенсорс-проєктів, і про нього можна питати AI. Наче чат з кодом, тільки він реально розуміє, що де лежить і як він працює.
Два режими:
— deep — показує конкретні шматки коду з поясненнями
— codemap — візуалізує структуру всього проєкту
Наприклад, можна подивитись як імплементований binary search у різних мовах і порівняти підходи:
chat → https://deepwiki.com/search/find-and-explain-binary-search_50038924-10a3-4609-a931-dfc83e469357?mode=deep
codemap → https://deepwiki.com/search/show-me-binarysearch-implement_e7948a6c-a72f-4748-a53f-a8c1b48135d3?mode=codemap
Або копнути як у LLVM зроблений Registry Pattern для реєстрації таргетів:
https://deepwiki.com/search/llvm-uses-a-registrar-the-targ_20014273-830e-4623-b832-24edd0fe6420?mode=fast
Рекомендую затестити не тільки для алгоритмів, а взагалі для вивчення дизайн-патернів, архітектури, будь-якого коду, який хочеться зрозуміти глибше.
DeepWiki
DeepWiki | AI documentation you can talk to, for every repo
DeepWiki provides up-to-date documentation you can talk to, for every repo in the world. Think Deep Research for GitHub - powered by Devin.
❤36🔥10👍3😱2🤯1
MIT кілька годин тому виклав всі лекції нового курсу 6.566: Computer Systems Security, Spring 2026.
https://css.csail.mit.edu/6.566/2026/
Курс виглядає як крутий матеріал для тих, хто хоче глибше розібратися в computer systems security: як будуються захищені системи і де вони ламаються
https://css.csail.mit.edu/6.566/2026/
Курс виглядає як крутий матеріал для тих, хто хоче глибше розібратися в computer systems security: як будуються захищені системи і де вони ламаються
YouTube
6.566 Spring 2026 Lecture 1: Introduction
MIT 6.566: Computer Systems Security
https://css.csail.mit.edu/6.566/2026/
Information about accessibility can be found at https://accessibility.mit.edu/
https://css.csail.mit.edu/6.566/2026/
Information about accessibility can be found at https://accessibility.mit.edu/
🔥51👍15❤9🤯1
Andrej Karpathy доєднується до Anthropic:
https://x.com/karpathy/status/2056753169888334312
А хто не знав: у Karpathy є легендарний курс CS231n: Deep Learning for Computer Vision від Stanford. Лекції доступні на YouTube, а на сайті Stanford можна знайти матеріали курсу та лабораторні роботи.
https://x.com/karpathy/status/2056753169888334312
А хто не знав: у Karpathy є легендарний курс CS231n: Deep Learning for Computer Vision від Stanford. Лекції доступні на YouTube, а на сайті Stanford можна знайти матеріали курсу та лабораторні роботи.
X (formerly Twitter)
Andrej Karpathy (@karpathy) on X
Personal update: I've joined Anthropic. I think the next few years at the frontier of LLMs will be especially formative. I am very excited to join the team here and get back to R&D. I remain deeply passionate about education and plan to resume my work on…
🔥34👍6❤🔥1😢1