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

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

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

18.02.2025

Три речі, яким я приділяю увагу під час перегляду ПРів

🧩 “Цікавий” код. Більшість коду є нудною та передбачуваною. Я довіряю колегам в тому, що він робить те, що потрібно. Але… інколи дивишся на єдиний змінений рядок (або навіть переставлений місцями з іншим) та підіймаєш брови… що це?

В таких випадках обовʼязково зʼясую, чи зміна навмисна (бо інколи залишається якесь сміття від розробки, або масова заміна не спрацьовує, або ще щось.) Або, може, навмисна, але неправильна. Чи я чогось не розумію. Що веде до наступного пункту…

💬 Коментарі до кожної незрозумілої ділянки. Я прихильник того, що код повинен бути зрозумілим. Проте завжди будуть місця, де наміри не вгадати тільки з коду. Їх, на мою думку, потрібно розʼяснити не тільки рецензентам ПРу, але й кожному майбутньому читачу. Тому там, де не виходить зробити код очевидним, допоможуть коментарі.

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


17.02.2025

Забиратися на гору

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

Власне, головна теза така, що прогрес через повторення має межу. Якщо кожен день робити фічі на React, то можна набити руку, досконало вивчити весь синтаксис та бібліотеку, але залишитися на тому ж рівні майстерності.

Ця модель “забирання на гору сходами” дає раду: розрізняти практику заради можливостей (знань) та практику заради навичок. Потрібні обидві.

Щоб отримати знання, потрібно вийти з зони комфорту, зробити щось нове (або новим чином.) Це не буде ефективна робота, бо навичок ще немає. Мета — набути нову можливість.

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

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

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


16.02.2025

LLM, Obsidian та Windows - щось таке

Вчора спало на думку / згадали в коментарях, що можна було б використовувати базу знань з Obsidian як вхідні дані для чат-моделі, та таким чином отримати пошук з кращим розумінням понять, ніж в прямого порівняння рядків.

Про цю ідею взагалі багато всього зроблено, бо на базовому рівні тут наче типова для LLM задача. З серйозних проєктів знайшов Khoj - в нього є плагін для Obsidian, можливість запускати сервер локально та використовувати локальні моделі. Але сьогодні так і не вдалося запустити його для Obsidian; тільки в режимі дослідження вебу.

Багато часу відняло поєднання Khoj на макбуці з Ollama на Windows; через такі базові речі, як вибір у Windows режиму “приватна мережа” та відкриття фаєрволу для Ollama - бо без того він не був видимий назовні. Також потрібно вказати OLLAMA_HOST=0.0.0.0; для мене найпростіший спосіб це зробити — це з NSSM зробити з Ollama сервіс, а заодно й змінну оточення вказати.

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

Тепер застряг на тому, що документи з Obsidian ніяк не зʼявляються в Khoj.

А ще, найлегший спосіб погратися з локальними LLM - це LM Studio. Бо це кросплатформенний графічний застосунок, готовий до роботи без всяких налаштувань. Тут можна: спробувати різні моделі, а також їхні параметри; побачити та порівняти швидкодію різних машин; та й просто користуватися чатом.


15.02.2025

Як я користуюся Obsidian

Як подивишся на приклади баз Obsidian - наприклад, в топі /r/obsidianmd - то будеш бачити складні, витончені, застилізовані системи. Тут, я гадаю, доцільна аналогія з автомобілями: ті, хто ними діляться — зазвичай ентузіасти, а у більшості власників машини звичайні нудні, втім — незамінні та люблені.

В мене вже бозна скільки років є особиста база знань, що складається з текстових файлів. Для роботи такої бази потрібна програма зі зручним пошуком. Колись це був Bear, а до того - nvALT, а ще раніше — здається, Vimwiki. Ключовою ідеєю для мене завжди була можливість знайти нотатку через пошук. (Що звучить тривіально, але, наприклад, у VSCode такого пошуку немає: наприклад, коли потрібно знайти два слова, що не стоять поруч.)

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

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

Останній рік також багато користуюся канвою (Obsidian Canvas) для планування та зберігання ідей. Як я вже не раз писав, мені легше сприймати таку інформацію, коли вона викладена на канву. До речі, також в Obsidian можна додавати й зображення. Та й взагалі будь-що — бо нотатки це файли в директорії. Але я обмежуюсь ілюстраціями.

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

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


14.02.2025

Obsidian Canvas та Excalidraw

Obsidian Canvas - найбільш успішний з інструментів, що я спробував у 2024. Але в цього доповнення є суттєві недоліки. Головний з них — навіть не брак функціональності (хоча в порівнянні з іншими програмами тут сміховинні можливості стилізації.) А те, що Obsidian Canvas не має відкритих точок розширення. Дарма що це офіційний плагін, документовані тільки його CSS-стилі.

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

Отже, нещодавно я подивився на доповнення Excalidraw. Взагалі Excalidraw це векторний редактор для вебу, а це доповнення інтегрує його в Obsidian (де редактор працює вже з файлами з Obsidian, без жодної привʼязки до якогось сервера). Документи Excalidraw виглядають (примруживши очі) так само як і Canvas. Зате в Excalidraw багатші образотворчі можливості: не тільки вбудована стилізація, а й бібліотека фігур тощо.

Але можливо, головне це те, що в доповнення Excalidraw є відкритий API. Причому, як я розумію, зроблений конкретно для Obsidian.

Також документи Excalidraw зберігаються так, що їхній зміст видно в пошуку Obsidian (а документи Canvas - ні або неповноцінно.) Структура канви й там, і там знаходиться у JSON, з тою різницею, що в Excalidraw він містить більше атрибутів стилю, тому є більшим за розміром.

Я поки не вирішив, чи переїду на Excalidraw. З недоліків: тут немає форматування Markdown прямо на канві та не так зручно робити стрілочки (доводиться кожну створювати окремо, тоді як в Canvas можна одним рухом миші створити вузол, привʼязаний до поточного.)


13.02.2025

Історія однієї пакетної оптимізації

В тій історії про повільний API є нюанс. Це був внутрішній API між двома тісно повʼязаними сервісами — фактично, RPC, віддалений виклик процедури, бо один з сервісів був витягнутий з іншого (та переписаний на Go.)

Після цього в коді залишилися ще тисячі звернень до функцій, які стали тепер зовнішніми. Функції стосувалися обчислення метрик та раніше були суворо закешовані. Але нові вимоги додавали більше фільтрів та закешувати всі комбінації стало неможливим. Переписування на Go, те ще й зі станом в памʼяті робили обчислення швидкими, втім API накладав вагому ціну.

Перше та критичне покращення в таких обставинах — це впровадити стале підключення замість щоразового. Головне, що це уникає вище загаданого рукостискання TLS. Коли у вас швидкий API, то це реально може бути найдорожчою частиною. (Взагалі цікаво, що головні витрати на шифрування в інтернеті відбуваються в момент підключення.)

Друге — як не крути, тисяча запитів у 10 мс це вже 10 секунд. Звісно, з боку Go я міг робити їх паралельно, тому впровадив пакетні запити та переробив декілька місць. Це досить легко, поки запити відбуваються в циклі — наприклад, будується якийсь графік. Але ж як я казав, застосунок писався із вільним доступом до тих функцій…

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

Тоді я зробив хитрість. Спочатку запускав звіт із фальшивим джерелом даних, яке повертало нульові результати та запамʼятовувало кожний виклик. Потім — викликав справжній сервіс із пакетом викликів, які назбирав. Та нарешті — другий раз запускав той самий звіт, але тепер із підготованим набором даних. Звіт став швидким, а головне — я не перетворив розробку звітів у складну інженерну задачу. It just works!


12.02.2025

Оптимізація: треба йти глибше!

Далі, коли шукаєш причини уповільнення, мусиш ставити під сумнів кожний свій висновок та знаходити для нього обʼєктивні обґрунтування.

Вчора хотів написати пост “чому OpenSearch повільний, коли у вас надто багато шардів?” (Шард — це неподільний блок даних, як партиція; індекс — тобто колекція — складається з фіксованого набору шардів.) Всі радять робити шарди розміром у 10-50 Гб… але чи значить це, що робити їх меншими обовʼязково погано?

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

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

Легко вказати на неприємну частину проєкту та сказати: проблема тут! (Мені, наприклад, доводилося витрачати час на алгоритмічну оптимізацію “некрасивого коду” там, де можна було обійтися як максимум кешем.) Але взагалі шукати причини — це ціле мистецтво. Треба знати, що важливо, що не важливо, та параноїдально собі не довіряти (що, до речі, називається науковим методом.)

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


11.02.2025

Причина уповільнення вебзастосунка майже завжди в базі

Можу згадати тільки один випадок, де повільні запити до вебзастосунка були спричинені процесорним часом самого застосунку. Це коли я оптимізував css_parser. А в типових ситуаціях завжди потрібно зрозуміти, що робиться з базою.

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

Або це багато запитів в циклі — це вже хиба логіки застосунку, та потрібно шукати, як ті запити обʼєднати. Робити запити у циклі майже завжди погана ідея — але зазвичай це не так очевидно, бо процес прихований в шарах логіки. Тут, як і в першому випадку, допоможе логування запитів. (А ще — інструмент на кшталт New Relic, Sentry, Scout тощо, який автоматично збиратиме статистику по запитах.)

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

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


10.02.2025

Де знайти час на власні проєкти?

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

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

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

🦉 Чому це краще, ніж після роботи? Бо робота більше виснажує, ніж годинка програмування для себе. Тому легше з проєкту перемикнутися на роботу, ніж навпаки. (Ну, принаймні це пояснює, чому містер Андерсон ставав Нео вночі, а не о шостій, після роботи.)

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


09.02.2025

Планування роботи, оцінка часу виконання задач тощо

Не виходить з Omniwope сьогодні — наче довів до робочого стану, але для деяких постів нова контрольна сума розбігається з попередньою, зі старого скрипту. Тож треба спочатку зрозуміти, чому так.

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

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

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

💀 А тепер постмортем: варто було б виробити звичку ніколи не ставити мету “зробити” багатокрокові та незрозумілі задачі. Зробити можна тільки кроки до такої задачі. Якщо з кроками нічого не ясно, першим можна попланувати — тільки не в голові!

⏱️ Та другий трюк/підхід: оскільки навіть з одним кроком не завжди ясно, скільки часу він займе (от в мене багато пішло на звірку нового та старого рушія) - то щоб цілий день не пручатись, можна спробувати ставити мету попрацювати над цим 20 хвилин. Чи три рази по 20 хвилин. Бо це вже гарантовано реальна мета, чи не так?