Простір для вивчення нової професії, зростання в кар’єрі або розвитку бізнесу👇🏻
Наша команда пише для вас найкращі та найцікавіші матеріали, які обов’язково допоможуть у вашому навчанні: https://genius.space/lab/
Last updated 2 months, 3 weeks ago
Дауншифтери
Є категорія людей які не мають бажання працювати або ефективно використовувати свої навички, натомість обмежуюсь роботою явно нижче їх ~~потужностей~~ можливостей.
Я знаю як мінімум чотирьох програмістів, троє з яких принципово хотіли в піхотний двіж (і один з яких вийшов живим з дуже ризикованої операції про яку ше кіно знімуть), а четвертий — займається сумнівною паперовою роботою. Я б дуже хотів бачити їх у більш хай-тековій суєті, бо в армії небагато людей які легко роздупляться з радіотехнікою, більшість все-таки вимагають навчання, яке часто йде важко. Все-таки технар є технар, навіть якщо людина мала чисто софтверний бекграунд.
Може воно й на краще коли людина хоче займатися чим хоче і не займатися тим чим не хоче, та й командир не відпустить бійця просто так, навіть якщо навести всі аргументи що він буде більш ефективним.
Якщо у цивільній роботі уникати відповідальності та «підвищення» у менеджмент середньої ланки це правильна стратегія яка мінімізує ризики та максимізує прибуток, то на війні від цього залежить боєздатність.
Навіщо працювати СТО на 8к якщо можна працювати за ті ж в 8к сенйором помідором? Отож. Навіщо отримувати більше відповідальності та напрягатися, якщо гз таке ж?
P.S.: Ну гаразд, я теж принципово не хотів йти на ЗСУшні ІТ-галери, але то окрема історія.
#армія
permalink | @full_of_hatred
👇Щоденні донати💰на ЗСУ🪖
🫡@Donate1024Bot
Agency
Є такий термін в англійській який я не знаю як нормально перекласти («суб'єктність» — шляпа). Зазвичай під цим мається на увазі здатність людини активно діяти та змінювати світ довкола себе.
Це людина якій треба більше всіх. Яка тягне проєкти та двіжухи за собою, на якій все тримається.
Зазвичай ці люди роблять щось своє, але якщо вони достатньо clueless, то можуть робити й ваше. Такі люди — на вагу золота. Бо тих, хто буде робити через підсрачники — багато, тих — хто буде робити без підсрачників — теж багато, але тих, хто буде рухатися сам та брати на себе відповідальність, щоб роздати підсрачників першим та розписати таски другим, а крім того придумувати ще й щось нове і робити це проактивно, а не чекати на команду зверху — одиниці.
Отримати в команду тіпа який буде сам шось робити — це неймовірна вдача. На цивільній роботі я був наполовину таким тіпом, бо друга половина — то ріжок-антикапіталіст який постійно ригав від необхідності працювати на дядю (та й працювати в принципі). Оцієї половини якраз і не вистачило, щоб стати VPoE або повноцінним CTO у великій конторі, а не залишитися hands-on-architect.
Будь-який бос шукає саме таку людину, але небагато таких людей зацікавлені в тому щоб за так батрачити на чуже. Зазвичай це або вже підприємці, або люди які мають солідний овнершип у своїй конторі й не рипаються.
Ну а в армії? В армії таких людей як ви розумієте небагато, і на них все й тримається.
За можливості, будьте саме такою людиною. Якій треба більше інших, яка наводить двіж, суєту, мутиться.
За можливості, тримайтеся таких людей. Отримаєте частку від успіху, а як не будете тупити то й самі підтягнетесь.
#робота
permalink | @full_of_hatred
👇Щоденні донати💰на ЗСУ🪖
🫡@Donate1024Bot
Local-first dev environments
Найбільше мене харить коли код проєкту неможливо запустити локально.
Коли є мільйон залежностей, кафки-хуяфки, редіси-хуєдіси, бридка трійця S3/SQS/SNS, мерзенний OAuth 2.0 та інша шляпа яка не запускається або складно запускається на вашому комп'ютері.
Коли для підйому адмінки проєкту над яким ти працюєщ тобі пропонують докер композ на більше рядків ніж сорци кожного мікросервісу, з яких він складається.
Коли їхав мікросервіс через стаб і моком поганяв, а половина тестових даних складені в YAML файли які останній раз оновлювалися за першого коміта у той мікросервіс.
Коли на старті проєкту лід видає тобі вагон кредів та інструкцій де отримати ще вагон кредів щоб потім захардкодити їх в дотенв-файлі.
Коли тобі пропонується піднімати на ноуті, прости Г-ди, кубернетіс🤮
∈)☼(∋. Очко.
Найцікавіше, що для спрощення розробки міленіали придумали мейнфрейми з тонкими клієнтами — ваш код запуститься на потужному кластері десь в клауді, а ви зі свого IDE будете давати команди. Дуже круто, дякую. Один з найабсурдніших стартапів минулих років це Mightyapp — «Mighty makes Google Chrome faster & use 10x less memory. Mighty speeds up Chrome on your laptop by streaming it from a more powerful computer in the cloud—that makes your browser & other apps run significantly faster.» Просто вдумайтесь, браузер(!) в клауді(!!!)! Ідея звісно не полетіла і фаундер запівотився (хоча це не назвеш півотом) в AI-генерацію логотипів та дизайнів.
Зважаючи на те, що лептопи та десктопи розробників зараз набагато потужніші ніж ті крихти vCPU які нам відсипає гіпервізор за вказівкою Безоса, склалась просто ганебна ситуація. І ми самі себе в неї загнали.
E2E тести які проганяються по ночам тому що «тест suite займає 2 години» забивають ще один цвях у труну продуктивності. Як щодо того, що запустити їх локально? Ой, не можна? А як мені тоді продебажити тест що падає?
Проєкт має збиратися та запускатися локально без усіх цих хоботів. Цикл read-evaluate-print має бути настільки коротким, наскільки це можливо.
Зовнішні залежності мають бути мінімізовані. Звісно за роки роботи працьовиті міленіали навигадували різних стабів для хмарних сервісів типу DynamoDB Local. Але менше ж з ним — відсутня залежність ліпша за стаб.
Хотів би вам дати пораду сьогодні подивитися на свій стек та викинути щось, але я знаю що ви з більшим задоволенням додасте ще один мікросервіс та ще одну клаудну шляпу від амазону. Тому насолоджуйтесь роздуванням complexity. Ми, ~~інженери~~ кодери, це любимо.
Без порад.
#робота
permalink | @full_of_hatred
👇Щоденні донати💰на ЗСУ🪖
🫡@Donate1024Bot
Performance by design
В попередньому дописі я зробив маленький сервіс який скриншотить твітер.
Зазвичай все що я пишу на Java то роблю на Spring Boot, через багату та зрозумілу екосистему та відносну швидкість розробки.
Цього разу для загального розвитку взяв vert.x, який заявлений найшвидшим Java-фреймворком згідно з результатами Ultimate Web Frameworks Benchmark.
Мій проєкт складається лише з двох ендпоїнтів — /health
для перевірки чи все ок та /api/screenshots
власне для скриншотів, тому бойлерплейту було мінімум.
Але що мене відразу вразило, так це те що фреймворк за замовчуванням виставляє таймаути на обробку HTTP-запитів. Якщо час виконання перевищує софт-ліміт, то в лог пишеться повідомлення:
Thread Thread[vert.x\-eventloop\-thread\-0,5,main] has been blocked for 2031 ms, time limit is 2000 ms
Якщо ж час обробки перевищує хард-ліміт, то ліба викидає експешн:
io.vertx.core.VertxException: Thread blocked
at java.base/java.lang.Thread.sleepNanos0(Native Method)
at java.base/java.lang.Thread.sleepNanos(Thread.java:491)
at java.base/java.lang.Thread.sleep(Thread.java:559)
at java.base/java.util.concurrent.TimeUnit.sleep(TimeUnit.java:446)
at me.rozhkov.snapshottr.App.handleScreenshotRequest(App.java:79)
При цьому код продовжує працювати, але експешн буде в логах.
Це чудовий приклад коли швидкодія закладається самим фреймворком та спонукає розробника думати як організувати обробку, щоб вкладатися в ліміти.
Я завжди виступаю за sane defaults, бо в сучасному світі занадто багато опцій, варіантів, прапорців, та перемикачів, щоб конфігурувати то все кожного разу.
Можливо у Spring Boot теж є таке налаштування, але його треба додатково увімкнути. Розробники роблять все на своїх машинах та не задумуються про швидкодію, поки не прийде час стрес-тесту, але тоді вже може бути запізно.
Раніше я вже згадував про автоматичне логування реквестів, SQL-запитів та часу їх виконання у Rails. Вважаю що це має стати стандартом усіх таких бібліотек. Чим прозоріше для нас, розробників, те, що виконується на сервері та скільки часу воно займає, тим більше можливостей писати відразу нормально, а не як-небудь.
Уявіть проходити мільйон співбесід по алгоритмах та системному дизайну, щоб потім влаштуватися у твітер та писати неймовірно тормозний сервіс, який віддає вам твіт цілу вічність, не може відразу завантажити тред, а глибина дом-дерева може позмагатися з глибиною node_modules того недолугого фронтенду який змогли написати олімпіадники. Це абсолютна ганьба та дискредитація інженерного ремесла від тих, хто заявляє найвищі вимоги до наших вмінь. Пруф що твітер можна зробити швидким та нормальним я вже давав — це Nitter.
Пишуть що Premature Optimization is the Root of all Evil, але я з цим не погоджуюсь. Нормально роби — нормально буде, і для цього не треба витрачати надмірно багато часу та зусиль. Просто з початку задайте собі адекватні обмеження та дотримуйтесь їх.
☝️Практична порада
?Подивіться чи підтримує ваш фреймворк схожу функціональність та увімкніть її.
#інструменти
permalink | @full_of_hatred
?Щоденні донати?на ЗСУ?
?@Donate1024Bot
Телеграм-бот для скриншотів твітера
У нас в телеграм-чаті каналу часто приносять посилання на твітер. Дивитися їх незручно, бо ти тикаєш посилання, щоб почитати коротенький текст. Логічно було б цей текст вставляти в прев'ю лінка, але твітер так робити не буде, бо їм потрібен енгейжмент.
Якось прочитав у блозі Swizec Teller пост про те як він зробив скріншотилку інстаграма на лямбді. Згадав про це і подумав — давай і собі зроблю! Впевнений що таких проєктів є ціла купа, але я хотів отримати задоволення від розробки, бо люблю робити продукти та програмувати?.
Колись давно я хотів зробити бота який буде автоматично банити за матюки, проєкт провалився і зараз цей бот просто рахує статистику повідомлень (хто більше написав) та робить ще деяку дрібну роботу. Вирішив його розширити.
ШІ швидко підказав потрібний код:
def screenshot(link)
browser = Ferrum::Browser.new({browser\_options: {'no\-sandbox': nil}})
begin
browser.go\_to(link)
browser.network.wait\_for\_idle(duration: 2, timeout: 30)
path = "tmp/tweet\_\#{Time.now.to\_i}.jpeg"
browser.screenshot(path: path, selector: 'article[data\-testid="tweet"]', quality: 95, format: "jpeg")
path
rescue StandardError => e
Rails.logger.error("Error capturing screenshot: \#{e.message}")
nil
ensure
browser.reset
browser.quit
end
end
За 5 хв протестив локально — все працює як треба! Заливаю, не працює. WTF?
Починаю розбиратися. Спочатку думав що проблема в alpine на якому зібраний базовий образ. Потім думав що проблема у твітері який блокує запити. Потім в, тому що недостатньо пам'яті. Потім в, тому що браузер закривається. Перевів з альпіну на дебіан, переконався що курли на твітер з хоста проходять, додав пам'яті, зробив браузер перзистентним.
Але все одно скриншоти робились через раз. Я витратив ще купу часу на різних форумах у спробах розібратися що ж не так, адже все було максимально просто — бібліотека то тонкий врапер над процесом хроміума, там нічому було ламатися.
Врешті я здався і вирішив переписати все на Java. ШІ швидко підказав потрібний код на Selenium:
driver.get(url);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
WebElement element = driver.findElement(By.cssSelector(cssSelector));
File screenshotFile = element.getScreenshotAs(OutputType.FILE);
Я нашкрябав вебсервіс який би виставив ендпоїнт до інтернету. З минулого разу я згадав про Ulitimate Web Frameworks Benchmark, і такий думаю, давай не буду брати Spring Boot, а візьму vert.x. Сказано—зроблено—задеплоєно. Запускаю — не працює?
Хром видає якісь крипто помилки, нічого не гуглиться. Заходжу на хост, запускаю хроміум вручну, той пише OOM. Фух, ясно, даю машині більше пам'яті, вуаля — все працює.
❓Наступна проблема—браузер не встигає завантажити прев'ю картинки або відео, які є у твіті. На жаль, я не знайшов як це нормально вирішити, тому просто додав 5 секунд очікування після відкриття сторінки. Можливо читачки та читачі підкажуть як більш елегантно це розв'язати?
Ну все, чатботи крутяться, скриншоти мутяться. Додав туди ще код який буде відповідати в телеграм, бо не хотілося робити муторну інтеграцію з основним сервісом.
Потім подивився що скриншоти треба в рамку, бо телеграм їх обрізає по висоті. Додав паддінгу 50px та й вспокоївся.
Три доби — жодної помилки, пам'ять не протікає, в середньому скриншот робиться за 7 секунд. Як на мене, це дуже багато, але вище написав що не знаю як виправити таймаут.
Бот — @chat_keeper_bot. Ви можете додати собі його в будь-який чат, і він теж буде працювати.
#проєкти
permalink | @full_of_hatred
?Щоденні донати?на ЗСУ?
?@Donate1024Bot
Ruby on Snails: 1 req/sec
Нещодавно один відомий консультант по перформенсу рельс написав твіт, де стверджував що більшість Rails апок тримають 1.5 req/sec на одному ядрі й тому треба мільйони vCPU, пам'яті та серверів, щоб воно хоч якось працювало.
Надзвичайно контроверсійна заява яка породила відповідну реакцію спільноти, де різні люди заявляли що в них все працює як мінімум в 10 разів швидше.
Згодом по треду виявилося, що 1.5 req/sec це те що автор бачить на своїх консалтингових проєктах. Тобто не всі проєкти, а ті, куди його запрошують (очевидно, з перформенс проблемами). І не нормально написані проєкти, а нездало написані. І основна проблема не в повільному Ruby, а в I/O до бази. Короче як в тому анекдоті, «— Чули Рабінович виграв мільйон у лотерею? — Все так, тільки не Рабінович, а Петренко, не мільйон, а тисячу, не в лотерею, а в карти, і не виграв, а програв».
Я звичайно крінжанув з поста, потім крінжанув що люди ганьблять Ruby, потім пішов дивитися скільки ж тримає сайт https://donate1024.org/
Поставив модну зараз програму oha, запустив у 20 потоків на 30 секунд: oha \-c 20 \-z 30s \-m GET \-\-latency\-correction \-\-disable\-keepalive \-\-redirect 0
https://donate1024.org/
і отримав наступний результат:
```
Summary:
Success rate: 100.00%
Total: 30.0017 secs
Slowest: 18.8368 secs
Fastest: 0.2681 secs
Average: 1.1295 secs
Requests/sec: 9.7328
Total data: 2.68 MiB
Size/request: 10.11 KiB
Size/sec: 91.64 KiB
Response time distribution:
10.00% in 0.4612 secs
25.00% in 0.5410 secs
50.00% in 0.6348 secs
75.00% in 1.0161 secs
90.00% in 1.9351 secs
95.00% in 2.4722 secs
99.00% in 16.0569 secs
99.90% in 18.8368 secs
99.99% in 18.8368 secs
```
~10 req/sec на одному ядрі з ±нормальним p95, бо сервер в мене найдешевший: shared\-cpu\-1x@512MB
Ця сторінка звісно не рендерить нічого такого, але десяток запитів в базу і яка-не яка логіка присутня. Звісно всі запити оптимізовані по максимуму, але все ж.
Маю гіпотезу, що більшість часу що витрачається, це не Ruby, а I/O в базу. Тобто якби сюди запулити джаву, то результат був би не набагато кращим, бо код аплікейшена це десятки мілісекунд, стислися б вони у два рази, в загальній частці це не дало б суттєвого прискорення. Щоб перевірити, може знайду час написати два ідентичних сервери на Ruby та Java і порівняти.
І це я просто написав нормальний код. Простору для оптимізацій ще багато: додати кешування, оптимізувати рендерінг HTML (замінити стандартний шаблонізатор ERB на Phlex). Якщо запаритися, то гадаю, що вдалося б покращити результат вдвічі.
Я ж зупинився на тому, що в мене сторінка віддається за 300 мс.
Тому сміливо пишемо на тому, що подобається, оптимізуємо дані та SQL запити, а всім хейтерам які заявляють про тормознутість вашого рантайму у порівнянні з джавою/растом/го сміливо ~~плюємо в обличчя~~ ставимо реакцію клоуна.
P.S.: я звичайно не метр перформенсу, але ще 4 роки тому писав про те що корені всіх проблем веб апок — це запити в базу даних.
P.P.S.: особливо прискіпливі можуть сходити на TechEmpower Web Framework Benchmarks та подивитися, що Spring не набагато швидший ніж Rails, Laravel та Django повільніші, а виграють не фреймворки, а голі бібліотеки вебсерверів.
#робота
permalink | @full_of_hatred
?Щоденні донати?на ЗСУ?
?@Donate1024Bot
Олімпіадники strikes back
Щодня @Donate1024Bot надсилає своїм підписникам звіти по завершених зборах. Це посилання на соцмедіа, відео з фото та супровідний текст.
Деколи ті звіти не відправляються через костурбатість Telegram Bot API:
- Текст до картинок не може бути довшим ніж 1024 символи. Щоб запобігти цьому обмеженню я додав у себе в адмінці валідацію на розмір тексту
- Файлів з медіа не може бути більше ніж 10. Щоб уникнути цієї помилки я просто брав перших 10 файлів, якщо випадково в адмінці додавав більше при створенні звіту
І найнапряжніше це document can't be mixed with other media types
. Олімпіадники Дурова не змогли зробити одночасну відправку різних типів файлів. Найчастіше у мене ця помилка падає коли випадково разом з JPEG файлами додав PNG. Також неможливо відправити PDF або щось інше разом з картинками.
В чому проблема це зробити для мене загадка. Хоче користувач додати одним повідомленням кілька картинок різних форматів, відео, та бінарний файл — ну покажи замість прев'юшки іконку файлу і все.
?А найцікавіше що джипег та відео можна відправити одним повідомленням! Чому не можна одночасно відправити PNG та JPEG?
Signal до речі, теж цим страждає. Тупе обмеження яке програмісти придумали напевне щоб спростити собі життя.
Рік я ігнорував цю проблему і коли телеграм не хотів відправляти мій звіт користувачам, то це попадало в Sentry, а далі я вже вручну дивився що не так і переробляв звіт.
Але врешті мені воно надоїло і я додав «тестування» звіту: при його створенні відразу відправляти у приватний чат. Таким чином я точно знатиму що звіт валідний та буде належним чином доставлений користувачам.
Інтеграційне тестування на продакшені?
#проєкти
permalink | @full_of_hatred
?Щоденні донати?на ЗСУ?
?@Donate1024Bot
Збір на абонплату старлінків
upd: збір завершено, всім дякую!
Вітаю шановне товариство!
?Шо ви там, оновили дані? Вже думаєте куди податися чи обираєте гідрокостюм?
?Працюю над тим щоб запропонувати вам дещо цікаве?
??Ну а поки що прошу допомогти моїм друзям з проплатою старлінків.
Зараз на балансі маю 4 старлінки: 3×95$ та 1×59€
На перших трьох вже борг 190$? Не хотілося б щоб кенти випадково залишилися на позиціях без зв'язку.
Щоб два рази не вставати пропоную зібрати 30000₴ — на кілька місяців вперед.
Банка: https://send.monobank.ua/jar/A9WetxuXih
Приват: 4627055113374002
PayPal: [email protected]
Чеки — в коментах до цього посту.
Дякую всім за допомогу!
P.S.: генератор, старлінк та щогла з попереднього збору успішно пережили дуже близьку роботу 120, 122, 152 та ще бозна чого і продовжують допомагати ✊
Простір для вивчення нової професії, зростання в кар’єрі або розвитку бізнесу👇🏻
Наша команда пише для вас найкращі та найцікавіші матеріали, які обов’язково допоможуть у вашому навчанні: https://genius.space/lab/
Last updated 2 months, 3 weeks ago