Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
- ActiveRecord
- AmazonRedshift
- API
- AppleScript
- AWS
- AWSLambda
- CGO
- Chezmoi
- CI
- Clojure
- Cloudflare
- CloudflarePages
- CssParser
- CтохастичнийТаймтрекер
- DNS
- Docker
- Dotfiles
- Fly.io
- GCP
- Git
- GitHub
- GitHubActions
- Go
- Golang
- GTD
- HomeAssistant
- Hugo
- I18next
- JavaScript
- JSON
- Kafka
- MacMiniВДорозі
- MacOS
- Markdown
- Mastodon
- Obsidian
- ObsidianCanvas
- OmniWOPE
- OpenSearch
- Oura
- Ping
- Plausible
- ReactNative
- Redis
- RSS
- Ruby
- RubyOnRails
- Sintra
- SMTP
- SQL
- SQLite
- Svelte
- Swift
- SwiftData
- SwiftUI
- Telegram
- Terraform
- TLS
- TypeScript
- Vercel
- VPN
- WeightPlot
- WordPress
- XCode
- Адвент2024
- Бази Даних
- БДС
- Безпека
- Блокнот
- Вебтехнології
- ВолюІнформації
- Гаджети
- ДизайнМовПрограмування
- Ігри
- Інструменти
- ІнтеграційніТести
- Кава
- КеруваннняЗадачами
- Кодогенерація
- Криптографія
- Локалізація
- Маркетинг
- МетаПост
- МоїПроєкти
- Навігація
- Оптимізація
- ОсновиІнтернетБезпеки
- Помічник ШІ
- ПомічникШІ
- ПостПроПохід
- Програмування
- Продуктивність
- Проєкти
- Проза
- РДУГ
- Рівночасність
- РобочийКомп
- Розробка
- РозумнийБудинок
- СинПопросивПриготувати
- Сон
- СтохастичнийТаймтрекер
- ХмарніТехнології
18.09.2025
Зони відповідальностей
Раджу провести таку вправу: перелічити власні зони відповідальностей. Зона відповідальності — не обовʼязково значить, що ти єдина особа, відповідальна за цю зону. Таке визначення більш корисно для менеджменту. А для мене (та за GTD) ці зони ділять не підприємство, а твої власні турботи та прагнення. Тобто зони відповідальності — це вичерпний перелік всіх сфер життя (в даному разі — робочого), де можуть виникати нові справи (проєкти).
Ось (неповний) перелік моїх зон з роботи:
-
Розробка нового функціоналу. Це як найбільш очевидне та те, на що формально мене наймали.
-
Третя лінія підтримки. Дослідження проблем клієнтів, які виявилися достатньо складними та ймовірно викликані помилками. А може, браком можливостей, про що теж треба зробити опосередкований висновок.
-
Інструменти та середовище розробників. Швидкість та стабільність CI, зручність та повнота локального запуску. Розгортування. Всілякі лінтери-шмінтери.
-
Якість коду. Оновлення залежностей. Впровадження логування та метрик. Безпека коду. Спостереження та оптимізація.
-
Виправлення технічного боргу. Широка категорія, куди я відношу задачі типу “воно повинно бути так, але поки є сяк.” Не обовʼязково це щось свідомо “недороблене” - часто вже після розробки виявляється, що можна було зробити краще. Для кожного підпроєкту власний список.
-
Лідерство. Підтримка роботи інших розробників, перегляд планів та коду, консультації. Розшук та впровадження нових підходів та технологій.
Аксіомою роботи є те, що тебе наймають робити одне, але зрештою перелік обовʼязків розширяється. Тому корисно інколи робити такий “аудит”.
17.09.2025
Коли не треба очікувати впорядкованості
Є такий момент у програмуванні, що оскільки ми можемо перелічити колекцію, то це натякає на наявність порядку. Бо перелік завжди відбувається в якомусь порядку! Важливо памʼятати, що не всяка колекція має порядок, та знати, які приклади з твого середовища його не мають (або навпаки, мають.)
Проблема ускладнюється тим, що рідко яка колекція повертає елементи у випадковому порядку. Навпаки, більшу частину часу ми будемо бачити саме той порядок, який очікуємо. Наприклад, порядок, в якому ми додавали елементи. Аж поки у підступний момент не випаде інший та не зіпсує нам всю логіку.
Наприклад: структура даних словник (вона ж hash
) наче зазвичай не є впорядкованою. Але в ній можна перебрати елементи. Та скоріше за все, вони повернуться в порядку додавання. Тільки покладатися на це не можна. Чи можна? В Ruby та Python цей порядок гарантований мовою! А в JavaScript чи Go - ні. Ото й кажу — знай своє оточення.
Також реляційні бази даних не мають ніякого “порядку за замовчуванням”, а вертають результат запиту в довільному, зручному для бази порядку. Може це в порядку за ключем. А може, це лише збіг, бо насправді — в порядку додавання. А взагалі не варто відгадувати, треба явно задавати порядок командою ORDER BY
, якщо він тобі потрібний.
Коли архітектор серйозно ставиться до цієї проблеми, то порядок перебору буде дійсно випадковий, щоб на нього ніколи не можна було покластися. Мені відомо, що саме так робить Go - ось живий приклад, де кожен запуск дасть інший порядок ключів.
16.09.2025
Модуль encoding/json/v2 в Go
…А головне що мені, щоб читати довільні атрибути JSON, довелося ще й використати новинку.
Місяць тому вийшов Go 1.25. Проміж іншим, там зʼявився новий модуль для роботи з JSON - encoding/json/v2
. За домовленостями Go це як той самий модуль, тільки другої версії — але технічно як раз ця версійність і дозволяє повністю змінити не тільки реалізацію, а й інтерфейси. (Та, по-правильному, поки не впровадиш нову версію, модуль мусить зберігати повну сумісність, хоча на практиці це постійно порушують.)
Я вже до того спробував замінити json
на json/v2
в іншому проєкті, але як раз зіткнувся з несумісністю деяких інтерфейсів та відклав, бо великої потреби в оновленні не було. Та й модуль поки експериментальний та потребує особливих параметрів компіляції.
А тут раптом виявляється потреба прочитати невідомі атрибути. Звісно, це легко зробити, якщо прочитати JSON у map[string]interface{}
. Проте потім доведеться вручну зчитувати відомі атрибути. Ну або можна власний UnmarshalJSON()
реалізувати — теж вручну. Це мені не до вподоби. Я хотів би все, що знаю, прочитати у типізовану структуру, а потім решту вже в map
.
Та, виявляється, це одна з можливостей нового пакета. Якщо в структурі присутній атрибут з потрібною анотацією json:",unknown"
- він й отримає всі невідомі значення. Ото й все, що треба було зробити!
Цікаво, що я не бачу такої можливості в жодному сторонньому модулі. Хіба що є відомий підхід з іншого боку — модуль mapstructure, яким можна з нетипізованого map
утворити структуру.
А ще важлива причина чекати json/v2
- там зʼявилося справжнє читання та запис потоком. Бо як я дізнався, стандартний модуль json
завжди буферизує весь текст об’єкта — тут можна почитати. Це, прямо кажучи, бентежить. Хоча, звісно, є багато інших модулів, які це вирішують. Мені, поки що, завжди вистачало стандартного.
15.09.2025
JCT 0.1.0 - краще перетворення JSON Canvas на Markdown
На вихідних розширив можливості JSON Canvas Tools… бо мені було треба. А саме, почав перекладати власні канви на списки, та виявилося, що наївного перетворення замало.
Взагалі воно й так не було зовсім наївним — я принаймні знаходив кластери вузлів зі звʼязками та перетворював їх у вкладені списки. Але того мало.
По-перше, хоч всіх нюансів розташування в просторі не передати, є один зрозумілий: групи.
В JSON Canvas група — це лише спеціальний тип вузла group
, явної вкладеності немає. Зате цю вкладеність легко обчислити за координатами вузлів — що, я гадаю, й робить Obsidian, коли ти перетягаєш всі вузли в групі разом із самою групою. А в мене тепер кожна група стає заголовком в Markdown.
Друге, та досить просто, на канві можуть бути зображення. Для них немає особливої розмітки — лише вузли типу file
- для локальних зображень, або link
- для URL. Можна, звісно, залишити їх в Markdown посиланнями, але щоб було зручніше, я перевіряю розширення посилання, та виводжу з відповідною розміткою.
Нарешті, багато в кого канва доповнена нестандартними атрибутами — в мене ось такі. Щоб їх не загубити, я виводжу всі нестандартні атрибути у Markdown. Спочатку хотів показати їх просто JSONом, але не так зручно мати JSON всередині тексту. Тому натомість виводжу у вигляді key=value
. Потім я можу звичайною заміною тексту перекласти їх в щось красиве.
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 теж.)
Все це не так легко та швидко налаштувати, як воно мені здавалося. Одна справа — вирішити підняти Патреон, зовсім інша — все в ньому наповнити та продумати.
Такий поки проєкт на вихідний день. :) А тут побачимось в понеділок.