Євгеній Гизила
189 subscribers
21 photos
1 file
46 links
Якщо що, то пишіть @hyzyla
Download Telegram
Для Python проєктів наразі немає жодного де-факто стандартного інструменту, яким можна створювати та запускати команди для локальної роботи з проєктом. Чогось по типу npm run … як в екосистемі JS. Бачив як колеги використовують для цього make, docker-compose чи самописні bash скрипти. Проблема з цими інструментами, що частина з них створювалася для інших цілей. Для прикладу make це інструмент для збірки та компіляції програм, а docker-compose для запуску Docker контейнерів.

Як альтернативу недавно знайшов just — інструмент для запуску команд (command runner). Команди описуються у justfile, який за синтаксисом схожий на Makefile, і запускаються так: just <command>.  Основні можливості: простий формат, є підтримка .env файлів, можна передати аргументи у команду, можна написати команду на bash, js, python чи ruby 😱  і багато іншого. В readme проєкту автори заявляють, що прямою альтернативою make, тільки орієнтованою на запуск команд, а не збірку проєкту.

Мій вердикт: перейти з makefile можна за 5 хвилин, працює інтуїтивно і надійно як швейцарський годинник
prefetch_related в Django

Недавно займався код-ревю Django проєктів і постійно бачив одну й ту ж проблему — N+1 запит. Для прикладу, ви робите один запит, щоб дістати 100 оголошень у вашому маркетплейсі, а потім ще 100 додаткових запитів, щоб дістати дані про магазин по кожному оголошенню. Сумарно у вас виходить 101 запит 😨: ваша база навантажена, клієнти довго очікують відповідь від сервера і ви прогріваєте повітря марною роботою.

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

products = Product.objects.all()
for product in products:
print(product.shop.name)


Але є місця, де цикли заховані в самому Django і в такому випадку приходиться уважно передивлятися як отриманий список об’єктів обробляється до самого кінця запиту. На прикріпленому фото канонічний приклад такого захованого циклу.

Найлегше вирішити цю проблему, додавши .prefetch_related до запиту, який дістає список чогось (або .select_related, якщо ви розумієте різницю між цими методами). Метод .prefetch_related зробить додатковий запит і дістане всі підв’язані моделі одним запитом і покладе у внутрішній кеш. Унаслідок чого Django зробить два запити: один, щоб дістати оголошення, а один, щоб дістати магазини :

Products.objects \
.prefetch_related('shop') \
.all()

Щоб уникнути N+1 запиту в майбутньому, треба, в першу чергу, знати про таку проблему, можна спробувати тестувати кількість запитів або, найпростіше, при локальній розробці запускати базу в режимі логування всіх запитів і уважно слідкувати, щоб там не було сотні однотипних запитів.
Please open Telegram to view this post
VIEW IN TELEGRAM
Монгольське письмо

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

Для таких мов не достатньо просто розвернути текст дзеркально, ще треба розвернути всі елементи інтерфейсу. Але зробити це треба теж розумно, бо число записане як “54321” в арабській мові, не повинно стати “12345”, латинський текст посеред такого письма теж не потрібно розвертати, але вирівняти треба вже по іншу сторону. Ну і зображення не треба відзеркалювати, але частина іконок все ж таки має бути на новий лад, і т.д.. Дуже добре про ці нюанси описано в настановах від Apple і Google для їхніх дизайн-систем.

Так-от недавно дізнався факт, що Монголія на офіційному рівні поступово відмовляється від кириличного письма і переходить до традиційного монгольського, яке записується з верху до низу, зліва на право 😱. При чому текст виглядає, ніби його перевернули на 90°, а не вишикували літери зверху донизу, саме тому весь інтерфейс теж має виглядати, ніби його повернули на 90°. Для прикладу вебсайт президента Монголії має горизонтальну прокрутку сторінки, заголовок зліва і підвал з правого кінця. Звісно ж UI фреймворки таке письмо не підтримують, тому монгольським розробникам хіба можу побажати терпіння і наполегливості. Мрію колись побачити як має виглядати монгольський варіант телеграму і інстарграму.
Please open Telegram to view this post
VIEW IN TELEGRAM
Інструменти для Кафки

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

🚀 provectus/kafka-ui — вебінтерфейс для брокера. Сервіс вміє працювати з декількома кластерами одночасно, можна переглядати та створювати повідомлення 🔥, редагувати топіки та інше. Дуже зручно, якщо цей сервіс піднятий для Кафки на рівні компанії для тестового чи продуктового середовища (якщо безпека дозволяє) і з доступом через LDAP чи GoogleAuth. В такому випадку можна не налаштовувати авторизацію в самій Кафці для різних користувачів, особливо якщо у вас не налаштована взагалі (100% не налаштовано). Також розробникам чи тестувальникам не потрібно буде налаштовувати ніяких додаткових інструментів.

✈️ deviceinsight/kafkactl — консольна програма, щоб працювати з Кафкою. Вміє все що й очікувалося від такого інструменту: переглядати/створювати/редагувати топіки, зчитувати чи публікувати повідомлення, автодоповнення і т.д. Для мене особисто, зручним відкриттям став файл конфігурації, в який можна додати декілька кластерів з різними налаштуваннями та перемикатися між ними командою:

kafkactl config use-context <context>
Please open Telegram to view this post
VIEW IN TELEGRAM
strace

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

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

access("/var/config.yalm", R_OK) = -1
ENOENT (No such file or directory)

Бібліотека не змогла зчитати файл з налаштуваннями, бо я зробив помилку, вказавши не правильну назву файлу 😂. Помилку виправив і все запрацювало
Please open Telegram to view this post
VIEW IN TELEGRAM
Про карти

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

- Falsehoods programmers believe about maps
- Falsehoods programmers believe about geography
- False Assumptions Programmers Make

Декілька цікавих фактів з цих публікацій, щоб зацікавити та переконати, що таємний світовий уряд навіть не зміг Землю поділити:

🌍 У світі існують нічийні території, які називають terra nullius. Найвідомішою такою територією є Антарктида. Але terra nullius є навіть в Європі між Сербією і Хорватією — кордон між цими країнами пролягає по річці Дунаю майже з 17 століття і саме річкою кордон і визначався в міжнародних умовах з тих часів. Час йде і річки змінюють свою форму і разом з тим і повинні були б змінюватися й кордони країн. Чи не повинні? Саме через розбіжності в поглядах на це питання на хорватській стороні Дунаю з’явилася ніким не визнана земля. Навіть декілька чехів у 2015 році спробували створити власну державу Liberland на цій території.

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

🏔 Про всі нюанси спірних кордонів між країнами взагалі й мови не йде, оскільки навіть Італія і Франція не можуть поділити територію на веришині гори Монблан.
Зсув часового поясу

Додатково до попереднього допису про карти, а також в честь переходу годинників на зимовий час розкажу один цікавий факт з категорії хибних упереджень розробників про час. Якщо у вас є задача обрати в якому форматі зберегти зсув часового поясу відносно UTC +0, то можна легко помилитися, припустивши, що для цього можна використати ціле число в якому буде зберігатися лише годину зсуву: +2, -8. Проте світ наскільки не очевидний, близько 1.4 мільярди людей з Індії 🇮🇳 і Шрі-Ланки 🇱🇰використовую часовий пояс з сувом +5:30, що робить його другим у світі за кількістю людей, які користуються ним (після +8, який використовується у Китаї). Тому краще зберегти зсув у хвилинах як ціле число 330 хв, або як пара цілих чисел (5, 30), або як дивне ціле число 530 🤔.

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

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

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

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

Не розводьте бюрократію у ваших бірюзових компаніях і буде вам щастя 👨‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
Europe/Kyiv not Europe/Kiev

Часові пояси дуже мінлива і політична тема, де майже кожен місяць відбуваються якісь зміни. Для прикладу країни відмовляються від переходу на зимовий час, перейменовують міста, об’єднують регіони і тд. Саме тому в розробці майже ніхто не намагається самостійно підтримувати список часових поясів і орієнтуються на відкриту базу часових поясів tz database, яку підтримує американська організація IANA.

В цій базі Київський часовий пояс весь час був записаний як Europe/Kiev і довгий час аргументом, чому саме використовується назва Kiev, була теза, що так заведено називати Київ англійською. Але я недавно розбирався з часовими поясами на проєкті і наткнувся на новину за 10 серпня, що часовий пояс Europe/Kiev був перейменований у Europe/Kyiv:

Release 2022b - 2022-08-10 15:38:32 -0700

Briefly:
...
Rename Europe/Kiev to Europe/Kyiv.
...


Тому очікую оновлення операційних систем і пакетів, і можна буде змінювати тайзону на Europe/Kyiv 🎉
git includeIf

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

Недавно вирішив пошукати як розв'язувати цю проблему і знайшов, що в git є можливість налаштувати окремі налаштування для всіх репозиторіїв у каталозі. Запхав усі робочі проєкти в одну каталог ~/work/evo.company/, створив .gitconfig і вже декілька місяців й не згадую про цю проблему
Емейл чи імейл

Коли писав минулий допис, стало цікаво дізнатися як правильно писати слово email українською. Пам’ять підказує, що це слово залишають в тексті чи інтерфейсі без перекладу або ж перекладають як емейл. Але всі посилання, які знайшов у ґуґлі, говорять, що правильно писати імейл і ніяк інакше. Всі ці посилання посилаються на норми правопису, які я звісно ж не перевіряв, але яким я більше довіряю, ніж своїй інтуїції.

Також на сайті проєкту «Словотвір» знайшов голосування за український відповідник цьому запозиченому слову і там зараз лідирує е-пошта і е-скринька.

Тому для себе вирішив так:
⁃ email – ні ⛔️
⁃ емейл – ні 🤔
⁃ імейл – топ 😌
⁃ е-пошта – для патріотів 🇺🇦🫡

*картинку взяв з проєкту «Мова – ДНК нації»
Please open Telegram to view this post
VIEW IN TELEGRAM
~* "postgre"

Коли я щось шукаю в базі даних, то часто використовую ILIKE, якщо знаю лише частину рядка. Для прикладу так:

companies.name ILIKE "%розетка%"

Але недавно відкрив для себе оператор ~* в PostgreSQL, який перевіряє текст по реглярці. Я регулярки люблю і мені їх писати легше і швидше, ніж ILIKE вирази. Тому мій приклад вище з оператором ~* буде виглядати так:

companies.name ~* "розетка"

Звісно ж для продакшену рекомендують використовувати LIKE чи ILIKE на противагу регулярним виразам, але для одноразового запиту те що треба 🤌
Адмінки

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

Майже завжди байдуже як ця адмінка буде виглядати, бо її будуть бачити лише співробітники компанії. І гарантовано на цю адмінку найменший пріоритет на розробку, бо між оптимізувати операційку і зробити нову фічу, продакт менеджер обере ймовірніше друге.

В цей момент, коли бізнес вирішує робити адмінку, я агітую за low-code/no-code конструктори адмінок. За останні два роки з‘явилося десяток рішення з відкритим кодом: appsmith, ToolJet, Budibase та інші. Також є Retool, який зараз де-факто стандарт серед комерційних рішень.

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

Поки я ще в жодному продукті не зміг продати ідею, щоб ми не кодили адмінку вручну. Але це тільки поки! 👨‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Fig

Вже пройшло майже пів року як я відкрив для себе інструмент Fig для macOS. Він додає підказки в термінал, які схожі на підказки в сучасних IDE-шках, де набираєш текст, а тобі за курсом випадає попапчик з варіантами як доповнити текст. В терміналі ж Fig показує параметри і аргументи для CLI інструментів, які він підтримує. Інструмент безплатний, має підтримку купи CLI програм, інтегрується з нативним терміналом, працює швидко і надійно.

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

На вихідних повільно читаю книгу про комп’ютерні мережі «Computer Networking: A Top-Down Approach» і в ній знайшов потішний для себе факт, що абревіатура LTE означає Long-Term Evolution, що, по суті, є просто маркетинговий вислів, який без приставки 4G не має ніякого значення. Але ця абревіатура настільки прижилася в народі, що стала самодостатньою й у всіх асоціюється з мобільним інтернетом. І саме тому в мене айфон зверху екрану, замість бездуховного 4G, пише народне LTE і всім ОК з цим. Так і живемо 📶
EXISTS в SQL

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

Для прикладу, в мене є таблиця «shops», пов‘язана таблиця «products» і я хочу знайти всі магазини у яких продається риба 🐟. Раніше мій запит виглядав би так:

SELECT shops.*
FROM shops
JOIN shops.id = products.shop_id
WHERE product.type = “fish”
GROUP shops.id


А тепер я напишу такий запит:

SELECT shops.*
FROM shops
WHERE EXISTS (
SELECT 1
FROM products
WHERE products.shop_id = shops.id
AND product.type = “fish”
)

І це так само працює й для протилежної умови, де треба знайти магазини у яких не продається риба 🐟🙅‍♂️. Раніше я б використав OUTER JOIN і умову products.id IS NULL, а зараз лише добавлю у запит вище оператор NOT перед EXISTS без будь-якого додаткового JOIN з основною таблицею.
імейл+1@gmail.com

Gmail має корисну приховану можливість, про яку мені розповіли колеги на початку моєї кар’єри і якою я тепер сам ділюся з новими колегами. Беремо, будь-яку Gmail адресу, для прикладу hyzyla@gmail.com. Додаємо символ "+" після імені, та будь-який рядок опісля цього символу, нехай наша нова адреса буде виглядати так: hyzyla+test1@gmail.com. Пробуємо відправити лист на цю нову адресу, заходимо в Gmail і бачимо, що в скриньці hyzyla@gmail.com є лист відправлений на hyzyla+test1@gmail.com.

Це працює так, тому що Google автоматично перенаправляє всі листи, відправлені на адресу з таким суфіксом, на основну адресу. Для цього не треба реєструвати новий профіль у Gmail чи взагалі щось додатково робити. Часто використовую цей лайфхак, щоб зареєструвати декілька користувачів для тестування сервісу, використовуючи один і той самий профіль у Gmail.
Контекст в контексті

На код рев’ю час від часу зустрічаю колег, які намагаються впихнути у назву локальної змінної весь контекст у якому вона використовується. В найкращих випадках змінна буде складатися з трьох-п’яти слів, а код буде виглядати наче його написала людина в офісному кубіклі двадцятиповерхової корпорації 🏢

Я маю суб’єктивне переконання, що в більшості випадків контекст можна пропустити і назвати змінну одним-двома словами. Поки ще не зустрів жодного розробника, який би від цього постраждав, тому раджу й вам спробувати: у вас покращиться кровообіг, відновиться здоровий сон і налагодяться стосунки з рідними 💆‍♀️
Captive portal

Помітив, що за кордоном, коли підключаєшся до публічного WiFi, то майже завжди відкривається сторінка на якій треба ввести свій імейл чи погодитися з правилами користування. Ці сторінки ще відомі як “captive portal” і щоб автоматично така сторінка відкривалася, роутер перехоплює HTTP запити та перенаправляє користувача на потрібну йому сторінку, якщо це потрібно.

Але по суті таке перехоплення нічим не відрізняється від men-in-the-middle атаки,  де роутери, що передають ваш запит, можуть підслуховувати чи підміняти вміст сторінки. Щоб захиститися від цієї атаки, свого часу й придумали захищений HTTPS на заміну HTTP.

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

Так от недавно відкрив для себе сайт, який завжди працює лише через HTTP http://neverssl.com. І тепер, коли я бачу помилку сертифікату при підключенні до публічного Wifi, то ввожу цю адресу у браузері, далі роутер робить свою зловмисну роботу, перенаправляє мене на свою сторінку входу, я підписуюся на всю рекламу, яку мені пропонують, і отримую свою порцію безкоштовного інтернету на 30 хвилин.📶
Please open Telegram to view this post
VIEW IN TELEGRAM