Petrushenko
1.04K subscribers
20 photos
3 videos
1 file
53 links
Founder CS Osvita, Engineering Lead.
Все про програмування, освіту та науку.

https://www.csosvita.com/
https://www.linkedin.com/in/ivanpetrushenko
Download Telegram
Хотів поділитися корисною штукою - почав користуватися додатком Opal.

Він блокує сповіщення та доступ до вибраних апок у ті години, коли хочеться нормально попрацювати без постійних відволікань. І це блокування складно обійти (навіть не знаю як). Як результат, це поступово відбило звичку зранку одразу хапатися за телефон і читати новини. Через це ранок став значно спокійнішим. Загалом, дуже рекомендую тим, хто хоче трохи краще контролювати свою увагу.

Ну і приємний бонус: для України річна підписка на PRO у мене показує $0.49.

А які у вас є свої маленькі хаки чи біохаки, які реально покращили фокус, ранок або загальний стан? Буде цікаво зібрати мікропоради в коментарях.
👍2810🤔8😁1
Останнім часом часто бачу дві крайності.

З одного боку - розмови в стилі "ринок помер", "джуніори більше не потрібні", "AI скоро всіх замінить". З іншого - реальність, у якій великі компанії продовжують наймати інженерів сотнями й тисячами. У нас, наприклад, зараз активний найм.
13👍4💯2❤‍🔥1🔥1
Тому вирішив подивитися на цифри:

у 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. Дивимося на заміри:

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👍117🤯2
Як ми пришвидшили запит до БД в 100 разів 🐘

Писали 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👍93😱1
Parameter Golf від OpenAI

OpenAI нещодавно запустила цікавий контест — потрібно натренувати максимально якісну модель фіксованого розміру (до 16 MB) на заданому датасеті.

Лідерборд і код сабмітів відкриті, тому вже зараз можна подивитися, які оптимізації реально працюють.

Що особливо круто: розміри задачі невеликі, тобто не потрібна велика інфраструктура, але при цьому це все ще реальна ML-інженерія, а не іграшка. Так, GPU потрібні, але OpenAI дає кредити для експериментів, якщо хочете взяти участь.

💡 І цікавий момент. Потрапити на співбесіду в OpenAI - складно, навіть якщо ти сильний інженер. І цей контест - це один зі способів знайти крутих людей серед великої кількості резюме.
👍8🔥72
Якщо вам здається, що більше потоків = швидше — дуже раджу подивитися це відео від відомої 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/
Дає безкоштовний доступ до матеріалів на місяць
🔥382❤‍🔥1
Зміна місця, роботи чи друзів може допомогти покращити твоє життя, але ніщо не зрівняється зі зміною твого мислення. Стан твого розуму впливає на все, що ти сприймаєш.
56💯9👍53🎉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% картини.

Перша лекція
31🔥17👍9
Зранку трохи пустив сльозу.

Почав викладати в ліцеї інформатику, перша пара і раптом о 9:00 всі ліцеїсти просто встали, щоб вшанувати память загиблих. Причому, що жодного сигналу не було — оповіщувач зламався, то я спочатку навіть трохи розгубився і не одразу зрозумів, що відбувається.

А потім в ліцеї лунає гімн, а вони стоять, приклавши руку до серця.

У такі секунди просто відчуваєш, які хороші діти у нас ростуть.
💔11332🫡7
20🔥6❤‍🔥1
4 роки тому одне інтерв’ю змінило моє життя.

Березень 2022-го. Війну я зустрів за кордоном. Постійно "на трубі" з друзями. Наш чат на трьох, де раніше були лише меми, перетворився на нескінченне "як ви?".

Одного вечора, коли «Азов» уже був у повному оточенні, у чат прилетіло посилання. Інтерв’ю з Денисом Прокопенком. Відкрив автоматично, щоб відволіктися. І залип. Він говорив чітко, виважено, предметно. Про цивільних, про ситуацію в місті, про полк, що стримує навалу ворога. Сказати, що я був вражений, — це нічого не сказати.

Я така людина, що завжди шукає коріння. Мені цікаво, як людина зростала, що на неї впливало. Тоді я ще не знав, хто такий Редіс. Тому почав вивчати. Ось просто сухі факти з мережі: ультрас «Динамо» та викладач англійської й німецької за освітою. 2014-й — доброволець, солдат. У 26 років — командир «Азову». Герой України. Сьогодні — бригадний генерал.

Але якщо подивитися інтерв'ю про нього від людей, що з ним перетиналися, то всі як один пишуть про фанатичну працездатність. Він — приклад того, як гострий розум множиться на трудоголізм. Один епізод, який пояснює все: Неділя. 04:00 ранку. Єдиний вихідний за тиждень. Дзвінок: «Вибач, що розбудив. Є термінова задача». Це і є Редіс. "Моє серце, моя душа, моє тіло належать Азову". Це і є Редіс.

До чого я це пишу? Після того інтерв’ю я невдовзі повернувся до Києва. Пройшло 4 роки. Сьогодні мені не соромно повідомити, що наша школа csosvita.com перетнула рубіж у 3 000 000 гривень допомоги Силам оборони. Безкоштовне навчання для військових. Понад 1 000 000 гривень ми спрямували саме на «Азов». І від сьогодні ми — їхні офіційні партнери.

Так, я не військовий. Але це мій спосіб бути корисним у цій війні, поки без зброї в руках. Просто робити максимум там, де я є. Просто робити якісну Computer Science освіту.

Дякую за приклад, командире.
"Без бою немає слави" (с) Редіс.
👍82❤‍🔥46🔥109👏6
Branch Predictor: скільки if-ів — це забагато?

Нещодавно копався в 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 не всемогутній, навіть якщо дуже старається.
🔥282❤‍🔥1
Midnight Code Cup 2026 — як AI змінив змагання

Пройшов кваліфікаційний раунд MCC https://midnightcodecup.org/. Задачі можна подивитись на Codeforces (на жаль, мають відношення до русні 🤮), і вони справді цікаві. Але найцікавіше — спостерігати за роллю AI у змаганнях.

Ще минулого літа на фіналі MCC команди вже використовували AI, але ближче до кінця контесту на топових місцях були ті, хто писав код руками — бо AI-код було складно підтримувати. Зараз ситуація кардинально змінилась: майже всі топові команди працювали через агентів, по суті кажучи їм, що робити, а не вирішуючи задачі самостійно. Ті, хто намагався все робити по-старому, витратили купу часу на бойлерплейт і не встигли реалізувати щось серйозне. Нагадує ситуацію в індустрії загалом: AI вже зараз дає величезне прискорення, але багато хто ігнорує це — і ризикує опинитися в програшній позиції.

Окремо цікаве спостереження про оптимізаційну задачу C: більшість топових рішень набрали приблизно 70k балів, але одна команда отримала 90k. Вони використали принципово інший підхід. І це добре ілюструє обмеження сучасних агентів — вони схильні мікрооптимізувати поточне рішення, але їм важко зробити крок назад і знайти глобально кращу стратегію.

Загалом, якщо ви ще не пробували розв'язувати задачі разом з AI-агентами — дуже раджу спробувати. Це незвичний процес, який потребує окремого навчання: треба розуміти, де агент допоможе, а де зашкодить, і як організувати роботу так, щоб легко знаходити баги, які він вносить у код.
👍217🔥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 разів.
👍19🔥87
Чому 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
🔥241🎉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

Рекомендую затестити не тільки для алгоритмів, а взагалі для вивчення дизайн-патернів, архітектури, будь-якого коду, який хочеться зрозуміти глибше.
36🔥10👍3😱2🤯1
MIT кілька годин тому виклав всі лекції нового курсу 6.566: Computer Systems Security, Spring 2026.
https://css.csail.mit.edu/6.566/2026/

Курс виглядає як крутий матеріал для тих, хто хоче глибше розібратися в computer systems security: як будуються захищені системи і де вони ламаються
🔥51👍159🤯1
Andrej Karpathy доєднується до Anthropic:
https://x.com/karpathy/status/2056753169888334312

А хто не знав: у Karpathy є легендарний курс CS231n: Deep Learning for Computer Vision від Stanford. Лекції доступні на YouTube, а на сайті Stanford можна знайти матеріали курсу та лабораторні роботи.
🔥34👍6❤‍🔥1😢1