Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
07.07.2023
Зони відповідальності, другий рівень
Ділюся останніми міркуваннями з самоорганізації. Минулого разу я розповідав про модель зон відповідальності. Хоч вона й дозволяла робити вичерпний огляд життя, але для пріоритизації підходила погано. А саме, зон знаходиться багато, та якщо намагатися робити щось в кожній з них, то починається перевантаження, яке вбиває кожну мою систему продуктивності. А з іншого боку, з деякими зонами пріоритизація взагалі не працює — наприклад, роботу потрібно робити щодня, навіть коли на роботі все супер.
Тому я прийшов до моделі з двома рівнями зон. За основу береться той самий список зон відповідальності, але вони групуються в три-пʼять зон верхнього рівня. Для кожної з цих зон визначається поточний проєкт. Тобто виходить загалом три-пʼять поточних проєктів. Всі інші проєкти йдуть в беклог відповідної зони. По завершенню поточного проєкту обирається наступний — з тієї самої зони верхнього рівня. Тут вже набирає чинності пріоритизація між зонами другого рівня.
Таким чином, кожна з зон верхнього рівня отримує увагу постійно — щодня або майже щодня. А зони другого рівня змагаються за увагу відповідно до стану та цілей. Групування визначає, як ми хочемо витрачати свій час. Тут можуть бути різні підходи — наприклад, я зараз створив зону “своє” з усього, що роблю на самоті, щоб балансувати це зі спільними заняттями. Можна було розділити “робота”/“побут”/“розваги”. Або “навчання”/“піклування про себе”/“суспільна діяльність”. Одним словом, це ще одна корисна модель, щоб зважити свої життєві цінності.
Як ілюстрація, я взяв пару вихідних (зона “робота”), щоб зробити дещо по ремонту (зона “дім”). Коли в ремонті вийшла пауза, то я взявся за поточний проєкт з зони “своє” - а саме, за розділ “Цілі” для Сінтри — та зробив гарний прогрес. Якби в мене був не список з чотирьох проєктів, а з тридцяти, або ста, то скоріше за все я б зробив гірший вибір. Навіть не тому, що складно їх пріоритизувати, а просто чим більше проєктів, тим легше втекти від відповідальності до чогось простішого.
Цікаво, що схожа система вже існує — це Intend.do, який раніше називався Complice. В мене навіть наліпка їхня є. Схожого тут те, що увага фокусується на невеликій кількості цілей.
06.07.2023
Парадигми текстових редакторів для коду
Хоча код, майже завжди, є звичайним текстом, його редагування ставить особливі вимоги до редактора. На відміну від “просто тексту” код має взаємоповʼязані частини, які треба редагувати разом — тобто займатися рефакторингом. Є декілька підходів до того, як це робити, хочу їх розглянути. Далі номенклатура моя, може хтось по-іншому ділить.
-
Звичайні текстові редактори. Окрім Ctrl+C/Ctrl+V, будь-який редактор, що себе поважає, вміє робити масовий пошук та заміну. Візьмемо це за основу. Цього достатньо для базових операцій, таких як перейменування змінної, але якщо треба, наприклад, перетворити перелік атрибутів на набір функцій, які їх повертають, то це доведеться робити вручну.
-
Редактори з підтримкою рефакторингу Спеціалізовані редактори (або спеціалізовані доповнення для них) розуміють структуру коду та пропонують команди для виконання обмеженого переліку операцій рефакторингу. Тут може бути й перейменування функції по всьому проєкту, й винос коду в нові функції, і так далі. Все це дуже круто, але не гнучко. Наприклад, знайти в журналі всі згадки деякого атрибута та перетворити їх на масив — такої функції в IDE не знайдеш, бо вона надто специфічна.
-
Командний режим (Vim). Вся сіль Vim в тому, що все що в ньому робиться, можна записати та відтворити. Замість того, щоб робити редагування “в реальному часі”, можна підготувати макрос, а потім запустити стільки разів, скільки це потрібно. (Це підкріплено системою стислих команд для переміщень.) Командна мова дозволяє робити мультиплікативно більше дій за менше натискань клавіш, що робить Vim дуже потужним редактором в жанрі tactical turn-based code golf.
-
Редагування декількома курсорами — нарешті, мій улюблений. Ідея проста — курсор (а точніше, виділення) в такому редакторі можна поставити багато разів. Тоді всі команди редактора застосовуються до кожного курсора. Зазвичай курсор ставиться не вручну, а командою “виділити всі випадки” (перед чим маємо виділити один з потрібних шматків тексту), або командою “поставити курсор в кінець кожного рядка” (теж перед цим виділивши потрібні рядки). Далі звичайними командами можна робити те ж саме, що й командний режим, але в реальному часі, що дозволяє швидко ітерувати зміни (не спрацювало один раз — скасовуємо, пробуємо щось інше.) Можу навести реальний приклад, як воно розвʼязує задачу замість непрямого підходу. Вся похвала багатокурсорності в один пост не влізе, тож продовжу завтра.
05.07.2023
Чому я користуюсь VSCode
Я десь з 2016 року користуюся редактором Visual Studio Code. В ньому я пишу майже все (включаючи цей пост.) Це свідомий вибір; час від часу я дивлюся на інші редактори, особливо такі, що нативні для macOS (наприклад, BBEdit, але нічого вартого не бачив.)
-
Я працюю з чисельними оточеннями та мовами програмування. Мені потрібний редактор, який може все — щоб не звикати до різних. VSCode підходить, завдяки розширенням на будь-який (ну, майже) випадок. Чесно кажучи, навіть зі Swift в мене не виходить подружитися, бо для цього потрібно перейти на XCode. Я не виключаю, що XCode - хороше оточення розробки, але воно не універсальне, тому завжди буде тільки “оточенням №2”, та я не зможу опанувати його парадигми.
-
VSCode - редактор з парадигмою декількох курсорів. Це важливо розуміти для ефективної роботи — так само як команди переміщення та макроси у Vim. Власне, колись давно саме багатокурсорність переконала мене піти з Vim на Sublime Text. На мою думку, вона потужніша та інтуїтивніша за командний режим Vim. Хоча, “думати багатьма курсорами” теж треба звикнути.
-
Sublime Text - теж чудовий редактор, але більш обмежений. Як приклад, для зручного пошуку по файлах мені довелося писати плагін Search in Project. А у VSCode така функція вбудована. І так багато чого. Єдине, в чому Sublime Text безумовно виграє — це у швидкодії.
-
Швидкодія редактора для мене це найголовніший його атрибут. Якщо я відчуваю затримку при вводі, то все інше вже не має значення. Так я ніколи не зміг випробувати Atom, та ніколи (ніколи) не зможу перейти на редактор, написаний на Java (в першу чергу, IDEA/RubyMine.) А VSCode якимсь дивом (для платформи Electron) не гальмує. (Насправді, не дивом, а прямими руками, але про це іншим разом.) Це дозволило мені зістрибнути з Sublime Text на VSCode, коли стало ясно, що темпи розробки Sublime Text не можуть зрівнятися з командою Microsoft (хоч в мене і є ліцензія на ST). Навіть коли я перейшов до використання вбудованого у VSCode терміналу, то швидкодії вистачило й на нього.
-
У Microsoft насправді величезний досвід побудови крутих редакторів, я ще з Visual Studio 6.0 задоволений користувач. Intellisense для C++ вже тоді був неперевершений. А зараз VSCode активно розробляється, щомісячні release notes завжди цікаво почитати. Тож я впевнений, що мій редактор в правильних руках з надійною фінансовою підтримкою.
04.07.2023
Підбірка доповнень для VSCode
Вчора колега поділився доповненням Error Lens, яке виводить повідомлення про помилки безпосередньо в кінці рядка. Захотілося теж поділитися цікавими доповненнями, якими я користуюсь.
-
change-case - дозволяє змінити регістр виділеного тексту (або навіть декількох виділених фрагментів.) Підтримує купу різних форм. Зручно при переході з мови на мову (наприклад, snake_case в Ruby та camelCase в JavaScript.)
-
File Utils - це доповнення я знайшов, коли переїжджав з Sublime Text, бо там це вбудовано. Воно додає до меню команди для файлових операцій — я постійно користуюсь Duplicate та Move. Робимо більше без миші.
-JSON Tools - просто форматує блок JSON. Напевно, є багато альтернатив, але в мене давно прижилась ця (це точно було ще до Prettier.)
-
Sort JSON Objects - так само інколи дуже корисно просто впорядкувати JSON. Витратив трохи часу, щоб знайти саме це доповнення.
-
Rainbow CSV - розфарбовує стовпчики CSV в різний колір. Так можна у редакторі передивитись та відредагувати CSV файли середньої складності.
-
vscode-gemfile - додає посилання на сторінку гему до рядків у
Gemfile
. Дрібниця, але зручна. (Не впевнений, звідки беруться такі самі посилання вpackage.json
- чи то доповнення, чи то вбудоване.) -
Тема 8-Bit - в кожного є улюблена схема, але ця — одна з висококонтрастних. Я перемикаюся на неї, коли доводиться працювати на сонці.
Ще більше виявилося таких доповнень, якими я не користуюсь та пора їх видаляти. А у вас які є цікаві доповнення?
03.07.2023
Враження від Kafka
Минув місяць моїх випробувань Кафки. Швидкість, з якою вона здатна приймати дані, реально вражає. Мільйон записів на секунду — цілком реальна цифра. Так, звісно, сама Kafka нічого з ними не зробить — ані індексації, ані агрегації. Проте цінність її не в тому. Кафку ставлять тому, що вона здатна розділити навантаження виробника та споживача подій. Та, навіть якщо мільйон на секунду вам не потрібний постійно, таке навантаження може виникнути, наприклад, на піці попиту, та Кафка спокійно його проковтне.
Так само Кафка розділяє й ризики виробника та споживача. Споживач подій — напевно, складна система, з внутрішньою логікою. Якщо виробник пише прямо в неї, то треба піклуватися й про високу надійність споживача — а чим більше логіки, тим це важче. Тому знову Кафка приходить на допомогу та підхопить всі дані, що були видобуті виробником, навіть якщо споживач зараз не може їх прийняти. (При цьому сама Кафка — досить проста та надійна система, з можливістю високого ступеня надмірності.)
Що мені не подобається — то, безумовно, складнощі в налаштуванні та інтеграції. Ну, з налаштуванням можна взяти керований сервіс, такий як Confluent. Але ще доведеться нормально розбиратись, як же з нею читати та писати. Та які саме компоненти потрібні. От є такі речі, як Zookeeper - сервіс керування кластером — який вже типу не потрібний, бо Кафка вміє й без нього. А ще є Schema Registry - вона для початку теж, це тільки для зрілих систем. А ще є Kafka Connect, який дуже боляче налаштовувати, але насправді вимоги такої немає, можна й без нього.
Поруч з Кафкою, AWS Kinesis Firehose вже не виглядає таким незамінним сервісом. Бо Кафка точно розвʼязує задачу “безрозмірного збору подій.” Тільки Firehose - сервіс вищого рівня, хоч і заточений під одну задачу. Його точно простіше налаштовувати та інтегрувати. З боку запису, Firehose надає простий API, а з боку збереження даних, він доставить їх туди, куди потрібно (до речі, перелік призначень нещодавно розширився.) Плюс, Firehose коштуватиме дешевше, до деякого обсягу. Тільки треба чітко розуміти, що Firehose зробить те, що вам від нього потрібно.
02.07.2023
Реверс-інжинірінг формату тепловізора, ч. 2
… Після вимірів зображення в файлі розташовувалась матриця з двобайтових значень. А далі — сюрприз — ще одна матриця, але вже з однобайтових значень. Тож отримав одну матрицю 16-бітних чисел, іншу - 8-бітних, а також 112 байтів додаткової інформації, такої, як відбиток часу та інше. Двох матриць я не очікував.
(Як взагалі здогадатись, що то матриця та який розмір її елемента? Бо послідовні елементи мають близькі значення. Тож повторюватись буде або кожний байт, або кожний другий байт. Також на початку кожного рядка значення теж близькі до попереднього. Все це легко побачити в hex-редакторі.)
Що робити з матрицями чисел? Спробував записати в CSV, але він погано сприймається. Краще перетворити на зображення. Тож відкрив для себе вбудований в Go пакет image. Він не дуже багато вміє, але дозволяє створити зображення, встановити в ньому значення пікселів, а потім зберегти у формат PNG. Саме так я й зробив (результат — вище.)
Після наочного перегляду 8-бітна матриця виявилася, напевно, сирим змістом сенсора. Її пікселі мали весь діапазон значень від 0 від 255 (Хоча цікаво, що не на кожній світлині — при малій розбіжності температур значення були більш обмежені. Тож можу зробити висновок, що вона не нормалізована, а саме сира.)
А от з 16-бітною не так все зрозуміло, бо у графічному поданні вона мала рівномірно сірий вигляд. Тоді знайшов мінімальне та максимальне значення, та стало зрозуміло, що це температура, але помножена на 10. (Ще одна сфера застосування цілочисельних дробів.) Ці значення відповідали тим, що показує сам пристрій.
На цьому питання не закінчуються. Можна було б очікувати, що температура є лінійною функцією від показників сенсора. Проте ні — як тепловізор її обчислює, я поки не зрозумів. Але я точно знаю, що одному значенню сенсора відповідають різні значення температури (в межах однієї світлини, звісно.)
P.S. Сподіваюся, зроблю пізніше повноцінну статтю з ілюстраціями та кодом, бо у формат Телеграму та щоденних постів воно ніяк не влазить.
01.07.2023
Реверс-інжинірінг формату файлів тепловізора
Мав нагоду випробувати індустріальний тепловізор. Окрім всього іншого, цікаво, що ті світлини, що він зберігає, хоч і мають формат .jpg
, але за допомогою супутнього програмного забезпечення дозволяють працювати, фактично, з RAW-даними. Захотілося дізнатись, як же ж воно влаштоване. З першого погляду, ці JPEG-файли 240x320 займають близько 300 Кб, що відразу викликає підозру: навіть нестиснутий файл BMP з такою роздільною здатністю займав би не більш ніж 240 Кб. Проте звичайні переглядачі світлин нічого цікавого в файлі не знаходили.
Тому в першу чергу звернувся до HEX-редактора. Останній раз я таким займався ще на Windows та років 15 тому, отже, для macOS довелося шукати. Є з чого обрати, насправді; я зупинився на редакторі ImHex. Він відразу сподобався тим, що наочно показує значення в різних представленнях, а також підтримує структурні дані. Причому структуру JPEG він вже знає. Але тут теж файл розкусити не вдалося.
Файл JPEG, як я дізнався, складається з сегментів. Сегмент заголовка, метаданих, і так далі. Останній сегмент містить дані світлини та зазвичай продовжується до кінця файлу. Тому наївні програми-читачі — в їхньому числі й ImHex - просто ігнорують те, що може йти після нього. Втім, кінець сегмента з зображенням (Entropy Coded Segment) можна знайти (за послідовністю байт FFxx
, де xx
- не 0).
Перейшов до написання утиліти на Go, яка біжить по JPEG файлу та перебирає сегменти аж до логічного кінця. Таким чином вдалося знайти не тільки кінець того JPEG, який видно “ззовні”, але й друге зображення JPEG - це була світлина, яку тепловізор робить звичайною фотокамерою.
Зображення просто знаходилися в файлі одне за одним. Але після них залишилося ще багацька даних — близько 250 Кб. Відкрив залишок в ImHex. Помітив, по-перше, що файл починається з ширини та висоти зображення, а далі — повторювану послідовність двобайтових значень, яка, як нетрудно здогадатись, містила якусь матрицю. Але про це, напевно, завтра.
30.06.2023
Робота з великими вихідними файлами на ECS
Сьогодні продовжував роботу з ECS, генерацією даних, тестами та так далі. Додатковий нюанс — застосування великих вихідних файлів.
-
Якщо в тесті потрібний великий файл (типу, 1 Гб), то через безплатний ngrok його не завантажити. Також не хотілося додавати файл у Git, бо видалити його буде складніше, ніж додати. Тоді можна відвантажити файл на S3 або інше сховище з можливістю публічного доступу. А мій улюблений спосіб простого тимчасового захисту — файл з випадковим імʼям.
-
Є інший варіант — пакувати файл в образ Docker. Щоб уникнути Git, його доведеться пакувати локально, але з ECS для цього немає перешкод — після авторизації в ECR можна відправляти образи прямо зі своєї машини. Проте ECR коштує в 5 разів більше за S3 (зараз $0.10 за Гб/місяць).
-
А якщо файл — це 5 гігабайтів JSONу, то його має сенс стиснути. Тут варто знати, що формат gzip - потоковий формат стискання. Та файл, що був стиснутий у gzip, можна відкрити та читати послідовно, без того, щоб розтискати та займати зайве місце. Наприклад, в Go стиснутий файл відкривається функцією gzip.NewReader.
29.06.2023
Запуск локальних скриптів на ECS за допомогою ngrok
В продовження теми з запуском скриптів на ECS, сьогодні винайшов ще більш зручний спосіб. Задача була схожа: зробити бенчмарк, який можливо запустити тільки з середовища ECS. Проблема така сама: на ECS можна запускати тільки готові контейнери Docker. Бенчмарк потребує послідовного налагодження та експериментування. Якщо підходити до цього нормальним шляхом — тобто комітити код, запускати скрипт деплою та очікувати, доки GitHub Actions та AWS CodeDeploy зроблять своє діло — то власне запустити скрипт вдасться раз хвилин в десять. Всякий фокус втрачається.
Тепер в мене є кращий спосіб: скрипт завантажується в контейнер ECS з локального компʼютера. Ніякої попередньої підготовки сервісу для цього не потрібно.
-
На своїй машині запускаємо HTTP сервер з теки:
python -m http.server 7777
. Цю команду взагалі варто запамʼятати, бо це найпростіший спосіб роздати файли за HTTP. -
В іншому терміналі запускаємо ngrok:
ngrok http 7777
. Таким чином отримуємо доступ до нашого сервісу з інтернету. Ngrok теж треба знати, зазвичай він використовується для отримання тестових вебхуків на локальний додаток. Або ж можна подивитись свій вебдодаток з телефону, наприклад. -
Тепер я можу запускати свіжий скрипт на ECS, замінив команду запуску одним рядком
wget -O benchmark https://ab-cd-ef.ngrok-free.app/benchmark && chmod +x benchmark && ./benchmark
. Для цього у нас є утиліта ecs_run. -
Коли закінчив роботу, просто зупиняю сервер та ngrok та жодного “хвосту” в публічному доступі не залишається.
Найкраще це працює з Go, оскільки там все компілюється в єдиний файл, та не треба окремо завантажувати залежності. Проте й в інтерпретованих мовах залежності змінюються не так часто, тому підхід працює.
28.06.2023
Кілька порад з мого повсякденного Git
-
Rebase - чудова команда, бо дозволяє відокремити збереження коду (коміт) від створення документації (підпису до коміту). А саме: оскільки всі зміни можна будь-коли відребейзати, розділити по логічних комітах, та красиво підписати, то попередні коміти можна робити будь-коли — наприклад, перед кожною ризиковою зміною. А не чекати, поки набереться набір змін, вартий коміту. А ще, коли PR виявиться несподівано довгим, або міститиме побічні зміни, можна спокійно їх відрізати, навіть якщо ми цього не планували. Взагалі, поки коміт не покинув твоєї машини, з ним можна робити все що завгодно.
-
Blame - одна з найважливіших функцій Git, бо робить корисним все ведення історії змін. Перша функція Git - поєднання змін від різних людей. Як людина, яка встигла покористуватись SourceSafe, скажу, що ця можливість змінила життя. Але друга функція - це відстеження історії змін. Та з нею можна роздивлятись будь-який баг як не просто комбінацію обставин, але і як подію в історії проєкту. Завдяки команді
git blame
можна знайти, де ж баг виник, та які зміни його супроводжували. Часто виявляється, що, наприклад, автор не володів всім контекстом, тоді легше зрозуміти, що треба виправити. Я взагалі постійно дивлюся на вік коду, який редагую, тому в мене blame зʼявляться біля кожного рядка редактора. -
Посилання на Pull Request є в коментарі до кожного merge commit, який робить Гітхаб. Тому я не бачу багато сенсу у вкладанні коду задачі на назву гілки — завжди можна знайти відповідний пул-реквест, та в мене цим часто закінчується пошук причини помилки через
git blame
.