Стендап Сьогодні

Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті

Підписатись на RSS
📢 Канал в Telegram @stendap_sogodni
🦣 @stendap_sogodni@shevtsov.me в Федиверсі

12.09.2025

Мій місяць з монітором глюкози

Десь із місяць тому сестра нахвалила мені монітор глюкози FreeStyle Libre 3 Plus. Це, звісно, в першу чергу рішення для хворих на діабет. Але для здорової людини монітор відкриває цікавий погляд на один з важливіших біохімічних процесів в нашому тілі. Сьогодні — розповідь про технічну сторону.

Що з себе складає монітор глюкози? Це розміром з монету біла шайбочка, яка наклеюється на задню поверхню плеча. Від неї під шкіру йде волосина міліметрів пʼять — вона й “бачить” рівні глюкози. Монітор живе два тижні, потім ставиш новий. Ніякого іншого обслуговування не потребує. Ніяких обмежень не накладає, я, наприклад, спокійно собі плавав.

Наліпити його дуже просто. Для того монітор продається вже в спеціальній касеті. Притискаєш її до чистої шкіри, всередині відстрілює за долі секунди голка, вживляє датчик та наліпляє сам пристрій. Процедура буквально моментальна та не потребує ніякого досвіду. Після вживлення може кілька хвилин трохи поболіти та й усе. Коли знімаєш, сліду практично не залишається, хіба що від клею.

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

Для перегляду інформації сучасні датчики підʼєднуються просто до телефону. І тут виявляється, що в Україні офіційно вони недоступні, бо застосунку в нашому App Store немає. Де ж я брав датчик? А на Промі — їх прямо багато. Тож очевидно, що люди користуються. Як вони знають, що треба звернути увагу на країну походження датчика та встановити застосунок з App Store тільки цієї країни? (Наприклад — Німеччини.) Перед цим зареєструвати окремий обліковий запис Apple? Вийти зі свого запису тільки для App Store, зайти в новий, встановити застосунок та повернутися назад? Я чесно не уявляю.

Із застосунку створюєш обліковий запис, підносиш телефон до вже вживленого монітору, він його підʼєднує та за годину починає видавати показники в реальному часі. А про те, що там він показує - вже наступного разу.

PS. Виправив підписку на Патреоні - як виявилося, щомісячна підписка там можливість відносно нова.


11.09.2025

Оптичне вирівнювання

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

Виявляється, що гармонійний дизайн не завжди є математично “ідеальним”. Та навпаки — розташовані “точно” предмети доводиться посунути, щоб вони ще й мали гарний приклад. Цей спосіб називається оптичне вирівнювання.

Мабуть, найпоширеніший приклад — це центрування тексту кнопки за вертикаллю. Розмір тексту враховує й великі літери, але буде гармонійніше, якщо вирівняти центр саме малих літер. Бо головна “маса” підпису складається саме з них.

Або ще приклад: якщо поруч стоять квадрат та коло “однакового розміру”, то діаметр кола повинен бути трохи більшим за сторону квадрата. Тут легше зрозуміти, бо фактично повинна збігатися площа фігур.

Але то все дрібниці. Колись я робив собі значок для проєкту та намалював оцей цікавий трилисник. Він, взагалі-то, має центральну симетрію. Математичну, без жодних трюків. Проти коли я захотів розмістити його в колі, то з центральним розміщенням значок був незбалансованим, наче “задраним нагору”. Тоді я просто вручну підібрав зсув вниз, та дуже бентежився “неідеальністю” рішення. А тепер дізнаюся, що так всі роблять! І це абсолютно нормально.

Як дуже схожий поширений приклад: трикутна кнопка “Play” теж не відцентрована!

Такий він, дизайн — не про цифри, а про відчуття.


10.09.2025

Питання для продумування проєктів

Продумати справи до кінця звучить красиво, але як це зробити? На практиці часто опиняєшся в стані, коли в голову нічого не йде. Особливо із тими проєктами, які вже застрягли та не рухаються. Але і з новими теж буває що думці нема за що зачепитися. Власне, так потім і опиняєшся з задачами, які наче потрібні, але навідсіч непідступні.

Отже, я для себе збираю потроху список питань, які освітлюють той чи інший аспект справи. Це не анкета — не потрібно відповідати на всі з них. Достатньо знайти ту відповідь, яка зсуне справу з місця. Ну або переконає відмовитися чи пересунути на пізніше — це теж гарний результат.

Ось поточний список. Ставиш перед очима назву наступної справи та медитуєш на нього. Сподіваюся, можна не казати, що всі відповіді треба записувати, щоб наступного разу не починати все наново.


09.09.2025

Різниця між навігаторами та що це значить

Згадали історію про навігацію в лісі. Йшлося тоді про ліси на Самарі, що поблизу міста Самара. Хто там був, знає, що цей ліс є суцільним лабіринтом водойм, ґрунтових доріг та баз відпочинку. Нагадаю, що мене Waze завів на протилежний бік річки, в той час, як Google Maps показав шлях до дальшої дороги, але без перетину річок — як видно на ілюстрації.

Можна було прийняти безперечну перевагу Google - і це нескладно раціоналізувати. Але я спочатку вирішив перевірити далі. Спробував побудувати той самий маршрут в OpenStreetMaps, Apple Maps, Here Maps, навіть Mapy.cz… вони всі роблять однакову помилку. Тільки Google будував “вірний” маршрут.

Тепер вже точно пора було погодитися із домінуванням Google. Тільки мені спала на думку інша перевірка: а що, якщо Google дати точку на іншому боці тієї самої річки? Та тут виявилося, що він робить таку саме помилку, тільки навпаки! Ба більше, навіть якщо дати точку на дорозі з протилежного боку чи поза нею, він так само вперто веде на ту ж саму дорогу, що й вперше. Яка, якщо чесно, навіть не є правильною дорогою для початкового маршруту. Правильної на карті взагалі не відмічено, а це — дорога на сусідню базу.

Так що виходить: Google, так само як і всі інші навігатори, не знається на водоймах та інших перешкодах. Він дивиться на граф доріг. Цей граф доріг у кожного навігатора свій, а ще й алгоритм пошуку маршруту — теж. Як я гадаю, в цьому випадку Google обирає той маршрут, в якого менше лісової ґрунтовки. При цьому навігатору в принципі байдуже на розташування тих доріг. Йому достатньо знати, що, умовно, від цієї дороги до точки йти 10 хвилин, а від тієї - 5. А їхати до першої 30 хвилин, а до другої - 40. Далі — проста математика.

Зате щоб побачити, що між точкою та дорогою є водна перешкода, доведеться робити складніші обчислення, для початку — пошук ймовірних перешкод. При цьому потрібно це тільки на такі крайові випадки. До речі, схожі проблеми виникають в промзонах, де навігатор може не знати, де вʼїзд у двір, а де — паркан.

🗺️ Висновок на всі схожі випадки єдиний: завжди перевіряй маршрут навігатора перед тим, як їхати у незнайоме місце. Та особливо — якщо це місце десь на природі, де покриття не таке ретельне.


08.09.2025

Магія та абстракції

У продовження теми Low Magic vs High Magic.

Хороша абстракція — це коли сутності, з якими ти працюєш, виглядають цілісними та складаються в систему з міцною логікою. В цілому, у світі безліч хороших абстракцій, які вірно нам служать, та й у програмуванні теж. Зокрема, рідко хто замислюється, як там працює процесор — а при тому кожна програма втілюється через внутрішню архітектуру процесора. Та ще глибше, електричні потенціали та струм.

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

На “допомогу” тут приходить магія (“it just works”). Магія просто приховує всі подробиці “за лаштунки”, де ми їх не можемо побачити. До певної міри це допомагає, бо поки ти працюєш в дозволених межах, “магічна” абстракція може бути дуже красивою. Але як тільки потрібно робити щось незвичне, магія розходиться по швах і доведеться вчити, як воно там всередині влаштоване.

Різниця між магією та абстракцією в тому, що хороша абстракція робить заглиблення в подробиці не потрібним, а магія робить його прихованим та складним. В цілому, одне не виключає іншого, але я завжди прагну першого варіанту — коли подробиці легко доступні. Наприклад, в Go завжди можна відстежити весь шлях виконання, це просто антимагічна мова.

З пришестям мовних машин зʼявився ще третій варіант — найпростіший — це замість абстракції плюватися кодом нижчого рівня. Аби працювало. Перевага очевидна — це швидко. Як я казав, від гарних абстракцій вигода зʼявляється значно пізніше. Оце й бентежить, бо я не хочу увʼязати в коді.

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


06.09.2025

Turning Pro

Сьогодні в мене для вас новини про канал. Нарешті починаю ставитися більш серйозно. Бо, розумієте, до написання статей я завжди ставився серйозно, а до публікації та маркетингу — ні. Через цей дисонанс багато стресу та менше натхнення. Так що, оскільки писати статті гірше я не збираюся, доведеться дотягнути продуктову сторону до відповідного рівня.

Публікувати в цей канал я тепер буду 5 днів на тиждень. Та, скоріше, тематика звужується до більш (чи лише) професійної. Над цим поки думаю.

В мене зʼявляється підписка через Patreon та закритий сервер Discord. Туди переноситься публікація на вихідних. Також планую замість постів робити щось цікавіше як для мене, так і для вас.

(Чому Patreon та Discord? Це доволі типова комбінація, тож довго над цим не думав. Я хотів МоноБазу, але вона змушує привʼязати публікацію до одного з кількох соціальних майданчиків, чого я робити не хочу. Та й інтеграції з Discord там немає. Та й API теж.)

Все це не так легко та швидко налаштувати, як воно мені здавалося. Одна справа — вирішити підняти Патреон, зовсім інша — все в ньому наповнити та продумати.

Такий поки проєкт на вихідний день. :) А тут побачимось в понеділок.


05.09.2025

Світ на тобі не закінчується

Значить, є проблема. З якоїсь причини пару годин був суттєво уповільнений один HTTP сервіс. Треба знайти, чому.

Ускладнення в тому, що це уповільнення ні з чим більше не корелює. Запитів більше не стало. Кількість оброблених байтів теж. Процесор в нормі. Памʼять в нормі. Але щось змусило сервіс відповідати повільно.

Єдине, що хоч трохи вказувало на причину - Sentry підказав, що час витрачається на читання запитів від клієнта. Цікаво! (Інструментація дала дивіденди.) За моїм досвідом, повільне читання завжди пояснюється повільним клієнтом. Може, в нього погане підключення. А може, це цілеспрямована атака.

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

Поки шукав правду в статистиці, спала на думку інша ідея. Вхідні запити до нас обслуговуються ще й сервісом переднього краю, та власне, інфраструктурою провайдера. Тож, думаю, перевірю, чи не було у них інцидентів. Так, про всяк випадок.

Та яке ж було моє здивування, що інцидент був! Та рівно на той час, який ми бачили в метриці. Та складався рівно з того, що мережа була перенавантажена. А значить, запити йшли до нас надто повільно. А ми вже обробляли їх як тільки, так відразу.

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

Гарних вам вихідних без інцидентів!


04.09.2025

Продумай до кінця (чи до початку?)

Одна з цікавих ідей GTD: будь-яка справа ділиться на два етапи: думати та робити. Робити, коли все ясно — достатньо просто (може, не легко.) Мабуть, кожний може згадати час, коли нехай важка, але абсолютно визначена робота була навіть в задоволення. Але в нормі не все ясно. Та ми, замість того, щоб подумати та прояснити, думаємо про справи, та ухиляємося від невизначеності.

Щоб полегшити собі життя, можна продумати справи, а не думати про справи. Це значить — поставити та знайти відповіді на всі запитання потрібні… уважно: для того, щоб зробити наступну дію. Продумати все до кінця під час не те що непрактично, а взагалі неможливо.

Питань виникає багато, деякі очевидні, деякі несподівані. Наприклад: щоб “шукати нові шини” треба хоча б знайти потрібний розмір. А може поговорити з дружиною про бюджет. А може взагалі вони ще не потрібні? Як це перевірити? А який виробник гарний? І так далі. Поки не будеш точно знати — що далі робити.

(До речі, це відчуття оманливе, та його в собі ще потрібно виплекати. Як легкий показник — якщо щось не робиться певний час — спитай себе: чи є обʼєктивні причини відкладати, або “руки не доходять”? В другому разі шукай невизначеність.)

(Ще один гарний критерій - чи можу я доручити цю дію комусь іншому? Якщо ні - значить, не все ще вирішено.)

Звісно, щоб не ходити по колу, всі ці відповіді варто записувати хоч кудись. Тоді буде зʼявлятися визначеність та впевненість. Навіть без всякого GTD можна завести звичку брати аркуш (чи текстовий документ) та проводити інтервʼю сам з собою. А ще й заготувати список питань заздалегідь.

В програмуванні такий підхід особливо потрібний, бо в нас “думати” та “робити” тісно повʼязані. Можна сказати, що на кожному рядку доводиться щось вирішувати. Але в таких дрібних рішеннях немає проблеми. Зате варто продумати: спочатку перелік вимог, потім з нього — загальну архітектуру, потім — план виконання. І на кожному з цих етапів будуть виникати питання, які здатні повністю загальмувати наївну розробку в лоб без продумування. Без цього сидиш тиждень, дивишся в порожній екран та не можеш написати ані рядка. Проблема не в натхненні — а в невизначеності на одному з рівнів. Знайомо?


03.09.2025

Помічник ШІ для прорізного аналізу проєкту

Знайшов вигідну галузь використання агентів (в моєму випадку це все ще Cursor.) Стосується це в першу чергу вебпроєктів, в яких, як знаємо, використовується цілий ворох технологій та мов: Ruby для бекенду, JS для фронтенду, CSS для оформлення, SQL для запитів. Поясню на прикладах.

Є інтеграційний тест — мені не знайомий. Він валиться на натисканні такої-то кнопки. Чому? Зазвичай тут доведеться майстерно грепати, та ще й знати звʼязки між шарами. Натомість виділяю рядок, тисну Cmd+L та задаю запит: describe code flows that are triggered by this action. Cursor знаходить в коді React цю кнопку — навіть якщо вона називається “Continue”, то він бачить її в контексті всього тесту. Сила LLM - в розумінні синонімів. Навіть коли тест називається “Profile”, а компонент - Account, LLM знайде його проміж інших. Звідти описує, що саме робить ця кнопка, які запити на бекенд, і далі розкладає по шарах бекенду, навіть до асинхронних задач. Це надзвичайно потужна можливість для такої доступності.

Або, бачу по CSS що ми використовуємо шрифт, але не можу зрозуміти, де саме. Замість того щоб відстежувати по кроках від CSS - до компонента, від компонента - до ієрархії, і так далі, питаю: which feature spec would load a page that uses the FooBar font? І так само отримую опис сценаріїв, де шрифт може бути залучений, та навіть конкретний приклад з тестів. Знову, це заміняє пів години ретельного пошуку та відкидання зайвого.

Так само можна робити з попередженнями в JS, які незрозуміло звідки зʼявляються в консолі. Або й в журналі з бекенду. І зовсім не обовʼязково для LLM потрібний прямий збіг за текстом.

Я взагалі завжди пишався своєю власною здатністю відстежити такі звʼязки, але ось в чому різниця. Коли я вручну за годину чи пів знаходжу причину помилки, то зможу виправити тільки найбільш гострі з них. А тепер вистачає можливостей ще й на деякі неприємні, але терпимі ситуації - як-от випадково невдалі тести.


02.09.2025

Легкий спосіб пришвидшити збірку у 2 рази

Взагалі знаєте, що є неформальне правило, що збірка коду на CI повинна тривати менше за 10 хвилин? Тоді в розробника менше шансів втратити контекст, поки тести йдуть.

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

Є й інший шлях: виправляти випадково невдалі тести. Бо дійсно, якщо збірка впала через випадкову невдачу — доведеться запускати її двічі та витрачати у два рази більше часу. А якщо друга спроба теж невдала — то й третій і четвертий раз. Виходить, випадково невдалі тести бʼють по продуктивності значно більше, ніж просто повільна збірка, особливо якщо збірку доводиться перезапускати вручну.

Я тієї думки, що випадково невдалі тести — як і помилки, завжди зʼявляються. Тому й боротьба з ними має системний, а не разовий характер. Як перший крок, почни записувати ті тести, що не вдалися з першої спроби. Тут доведеться відстежувати історію збірок. А можна поступити простіше та записувати всі тести, що не вдалися в головній гілці, бо там вже не повинно бути недоробок. (Правда?)

Є також рішення типу rspec-retry - перезапускати невдалі тести відразу один по одному, на випадок що вони пройдуть. Так, це певна поступка чистоті підходів, але я гадаю, варта того. Заодно можна відразу збирати список тестів, які пройшли з другої спроби.