Нервный программист
176 subscribers
87 photos
2 videos
1 file
50 links
Эмоционально об айти и программировании
Download Telegram
Знаете, что общего между Егором Бугаенко и Артемием Лебедевым? И тот и другой много чего рассказывает. И у того, и у другого 50% это база, но другие 50% это откровенная дичарня.

Ладно, на самом деле я со всем уважением к Егору. У чувака опыта больше в 2 раза, его производительность видна на гитхабе, он пишет книги, читает лекции и его слушают. Так шо аргумент "сначала добейся" кажется мне уместным здесь. Но, думаю, я имею право не согласиться с ним в чем-то.

Около полугода назад попался мне ролик, где Егор отвечает на вопросы. И его там спросили, как он относится к DI - контейнерам. И он сослался на свою старую статью, и отметил, что его позиция с тех пор не изменилась. Штош, вот она эта статья под громким названием Dependency Injection Containers are Code Polluters. Она довольно старая. Но раз Егор по-прежнему ссылается на нее, то и мы скидок делать не будем. Давайте ознакомимся.

В статье Егор сначала приводит пример DI через конструктор, рассказывает на сколько это полезно по сравнению с инстанцированием зависимостей внутри класса. Ну допустим, тут мы верим, хотя Егор заканчивает объяснение фразой No need to discuss why. It’s obvious. Причем obvious - это ссылка stackexchange 😂 Так бы и написал "мне лень объяснять, давайте там сами, заебали".

"So far so good, but here comes the dark side—a dependency injection container" -- говорит нам Егор далее. Ну надеюсь щас нам расскажут про темную сторону.

После этого он вводит понятие DI-контейнера на примере старой библиотеки Google Guice, которая в данный момент не поддерживается. Удивительно, но оказывается, что если у тебя в приложении всего 2 класса, один из которых - это зависимость другого, то написать new A(new B()) окажется короче, чем конфигурировать контейнер! Вы знали об этом? Я ахуэл!

Кроме того, Егор отмечает, что существуют еще сценарии неправильного использования DI-контейнера такие как
* Field injection
* Setter injection
* Passing injector as dependency
* Making injector a global singlton (чем это плохо, кстати?)
И далее Егор заключает "If we put all of them aside, all we have left is the constructor injection explained above. And how does that help us? Why do we need it? Why can’t we use plain old new in the main class of the application? ... The container we created simply adds more lines to the code base, or even more files, if we use XML. And it doesn’t add anything, except an additional complexity."

Ну собственно все! Вот и вся аргументация! спасибо за внимание, нахуй!

Вот вам рецепт, как писать статьи: просто накидывайте обесценивающих вопросов и добивочка "про дополнительную сложность". Какие-то примеры, раскрытие тезисов, попытка разобраться в вопросах -- это для хабра 😂 в личном блоге можно просто надменно нести хуйню. Я, собственно, поэтому его и завел 🤫

Лан, на самом деле это еще не все. В конце Егор нам приводит пример Right way. Там гигантская портянка кода, которая не влезет никуда, поэтому ее кусок я ввиде скриншота приложил. Знаете, программирование - это в каком-то смысле квинтэссенция принципа "красота в глазах смотрящего". Егор смотрит на этот код и видит Right way, я смотрю на этот код и вижу клубень говна. Какие-то блять волшебные константы, ни одной повторяющейся зависимости. Где логер, Егор? В любом приложении он есть. Как ты его со своим right way собираешься вкорячивать?

О, я кстати придумал аргумент. "Егор, ну и чем твой код лучше XML? А?" Раунд!

Ладно, если по серьезке, то статья просто гавно! не потому что Егор там глобально неправ (хотя и это тоже), а потому что он свою позицию никак не раскрыл. Даже если бы он просто взял свой right way и переделал с использованием DI-контейнера, и вот там уже указал на additional complexity, и где конкретно она появляется -- в этом уже был бы толк и предмет для дискуссии. А так ну это просто наброс.

Хотел свое мнение написать про di-контейнеры, но че то разбобмбился знатно, пока пост писал. Да и так про них много написано. Ну может потом. "мне лень объяснять, давайте там сами, заебали"

А вы как, согласны с Егором, что di-контейнеры - это зло?
👍81🤗1
Решил вчера вернуться на десктопный линукс после 5 лет перерыва. Поставил кубунту. Перезагрузился 2 раза - все ок. На 3й раз увидел вот это.

Годы идут, а к десктопному линуксу как нельзя было без вазилина прикасаться лет 10 назад, так и до сих пор нельзя. Оплот стабильности😊 зато будет, чем заняться в это воскресенье.

PS. Да, я подозреваю, что это какая-то проблема с grub, secure boot и тем, что это вторая система. Но все равно прикольно, что на ровном месте приключения. Винда кстати норм грузится🤷
👍32
Карочи, опять про питоновский линтер pylint. Не буду повторять (хотя повторю), что в наше время, если линтер не умеет сам ошибки исправлять, то это немношк кринге. Ну да ладно😔

Седня хотел поговорить про конкретное правило линтера, а именно про порядок импортов. У нас есть стандарт PEP8, который декларирует следующие группы импортов:
1. Импорты стандартной библиотеки
2. Импорты сторонних либ
3. Локальные импорты
Группы импортов должны размещаться в начале каждого файла именно в таком порядке. Они должны быть разделены пустой строкой. Код должен идти после. И pylint по дефолту требует выполнения этого условия. Вроде норм, но! Импорты не реордятся автоматически 😡

Есть такая функция из модуля dotenv, называется load_dotenv(). Любой сеньор догадается, что эта функция занимается тем, что загружает переменные окружения. Поэтому, мы ее где нить в начале скрипта вызываем, и дальше у нас все окружение доступно.

Поскольку я парень пидаристичный педантичный, я хочу, шоб мое приложение даже не запускалось, если какие-то переменные окружения отсутвуют, и сразу падало с ошибкой. Для этого в начале своего модуля, который, например, отвечает за интеграцию с каким-то сервисом я воткну что-то вроде

SERVICE_HOST: Final[str | None] = os.getenv("SERVICE_HOST")
if SERVICE_HOST is None:
raise RuntimeError("SERVICE_PORT is not set далбаеб")


Вроде нойм. Но вопрос, а куда воткнуть load_dotenv()? Вы можете подумать, что load_dotenv надо воткнуть сразу после импортов в рутовом файле приложения. Ну типа, это начало "как бы" кода. Но в таком случае, мы сразу получаем ошибку, потому что наш import service окажется до load_dotenv() и переменные не будут загружены на момент выполнения импорта. Ведь питон просто исполняет код внутри файлов по мере поступления импортов.

И тут получается 2 стула:
* Либо мы вызываем load_dotenv() в каждом таком файле с env переменными после импортов, и pylint счастлив
* Либо мы втыкаем его между импортами прямо перед группой локальных импортов в рутовом файле

Во втором случае у pylint сгорает срака. Потушить ее можно поместив все локальные импорты между дtрективами # pylint: disable=wrong-import-position и # pylint: enable=wrong-import-position (см. скриншот кода из прода 😱).

Я че то думал-думал, и решил, что load_dotenv() в каждом файле это какая-то параша. Хоть вызов load_dotenv() несколько раз на корректность не влияет, вроде как оно замедляет старт скрипта. Но я не бенчмаркал🤷 Поэтому выбрал второй варик.

И тут многие проженные питонисты скажут "Ррряяя, ты туповатый. Надо делать отдельный класс-хранилище переменных, который ты будешь инициализировать на старте. У тебя опять skill issues!". Не кипятитись мои горячие питонячие пирожочки. Тут важно еще раз обратиться к цели: скрипт не должен даже стартануть, если какой-то конфиг пропущен. Я не должен узнать об этом в рантайме. И все должно быть типизированно. Никакое класс-хранилище эту проблему не решит.

Или я неправ? Делитесь в комментах, как у вас дела обстоят с енв переменными. Или напихайте мне за высосанную из пальца проблему! 😘
4
Блин, такая вообще обида у меня щас конечно😢 аж до слез!

На прошлой неделе тюнил потребление памяти в нашем монололитном макросервисе на symfony. Че то оно было подозрительно высокое. И обнаружил, что в какой-то момент бэкграунд джоба загружает из базы массив на 200 000 интов. Чтобы подсчитать их количество🤡 Ну это ладно. Думаю, все так делают.

Чтоб достать это все из базы, используется доктриновский getSingleColumnResult(), который возвращает лист со значениями одного столбца. И в этот момент потребление памяти подскакивает до 60 мб, шо как бы нихуясебе. Ну и вы можете сказать "а че ты хотел. 200 000 интов в массиве на пхп, это тебе не шутки!"

А давайте все таки прикинем писю к носу потребление памяти для такого списка. Любой скаляр в пхп занимает 16 байт, потому что именно столько занимает zval. И тут, как математик, я вам могу сказать что, (16 х 200 000) / 1024 / 1024 = 3мб. И с этим уже можно жить. И если, как физик, я создам такой лист с нуля, то примерно такое потребление памяти я и увижу. Но откуда 60 мб? Стало быть, какое-то непотребство происходит внутри доктрины.

Стал разбираться и быстро выяснил, что под капотом у getSingleColumnResult() используется PDOStatement::fetchAll c флагом PDO::FETCH_NUM. Этот флаг возвращает результат в виде списка списков с одним элементом. Таким образом, доктрина была поймана за руку, как дешевка! Ведь у каждого массива в пхп есть оверхед в пару сотен байт. Вот оно и вылазиет.

Тут же созрел хитрый план, что на выхах я буду врываться в опен сурс со своим классным пулл реквестом, где заменю флаг на PDO::FETCH_COLUMN. И меня тут же все полюбят, и я стану красавчиком, наконец😌

Начал еще раз все перепроверять на новой версии доктрины, а оно сука работает как надо! Оказывается, на прошлой неделе они выпустили фикс, где эта проблема была закрыта😔 а соответствующему пру уже 5 месяцев.

Вот так провалилась очередная попытка стать классным😢

Выводы:
* Жизнь - жестокая штука
* Своевременность - это очень важно
* За любым массивом кроется память

Спасибо, что выслушали ❤️
👏12😁64👍3
Сорри за прошлонедельный боян, но я не мог пройти мимо этого.

Наконец-то кто-то сможет положить конец этой бездушной корпорации!
😁52🤯1
Ну что, мои дорогие бомбята! Вот и наступил 2026. Я не очень люблю итоги года, поэтому всех просто поздравляю. Надеюсь все выжили и готовы активничать дальше. Может не прям сегодня конечно😊

Думаю 2026 год даст не меньше поводов побомбить, чем 2025. А это значит, будет о чем написать, и что обсудить. Я, в свою очередь, обещаю, что контент, как и прежде, останется человеко-генерированным, но не всегда полезным) Но я щитаю, что польза - это про другие каналы. Здесь я скорее про фан и эмоции вокруг нашего любимого программирования. Ну и всегда рад показать, что обосраться - это не зазорно, а иногда и очень здорово 😀

Всех с новым годом! 🥳 Хорошо отдохните, шоб сделать врыв в следующий год максимально мощным!

P.S. Праздничный кот Кристофер передает всем привет
14🎉10💯1
Литералли каждый коммент, когда вайбкодю:
😁4🤔1
Уууу сукаа. Выбесился с двух вещей вчера.😡
1. Claude Sonnet 4.5 (потому что пиздабол)
2. github (потому что майкрософт нихера там не улучшает и всем поебать на запросы пользователей)

В чем суть. Пытался задеплоить пет проект. Шоб вы понимали, это просто старый добрый static веб сайт из трех файликов: html, js, css. Никаких фреймворков, баз данных и прочего бэкендского говнишка. Всякие либы гружу с CDN. Полный минимализм. Боже, как я по этому скучаю на работе😔

А в другом репозитории у меня находится то, что представляет определенную ценность прелессть, точнее ее исходники. И статичный сайт просто дает удобный доступ к этой прелести.

И я спрашиваю у клода "а могу я в github actions просто собрать свою прелессть во время публикации релиза и просто запихать ее как ассет, а потом на своем сайте просто грузить этот ассет по прямой ссылке?"

И клод мне отвечает: "Отличная идея! Ты такой умный и красивый! Кстати, github releases поддерживает CORS, так что проблем не будет!" Я его про CORS даже не спрашивал, но он вообще красавчик, и сам мне написал про это👍

Для тех кто не в курсе, что такое CORS (Cross-Origin Resource Sharing). Это такая штука, которая позволяет бровзеру загружать ресурсы с другого домена. В данном случае, мне нужно грузить ассеты с гитхаба, и это другой домен. Поэтому поддержка CORS с их стороны будет как нельзя кстати.

Проблема в том, что у гитхаба нет поддержки CORS для ассетов релизов 🤡 Зато есть тикет, которому 3 года, с просьбой добавить эту самую поддержку. И я узнаю об этом в тот момент, когда уже все нахуячил и пытаюсь задеплоить. Всякие штуки вроде raw.githubusercontent.com позволяют загружать только контент репозиториев, но не ассеты релизов.

У этой проблемы существует 2 решения:
* Использовать прокси
* Добавить стадию билда, где перед публикацией загружать ассет и класть его рядом с другими файлами

Я выбрал второй варик, потому что первый - это какое-то нереальное дрочево, если делать свой прокси, и суперненадежно, если использовать публичные. Благо, что мой хостинг провайдер netlify позволяет изи сделать билд😍 Вообще про netlify можно отдельно написать, потому что прям очень понравилось. Если вам надо захостить простой сайт БЕСПЛАТНО, то netlify - это прям мой рекомендасьон!

Выводы:
1. github не поддерживает CORS. Говорят, даже их api не поддерживает CORS, хотя в доке написано обратное, но тут я не проверял 🤷
2. llm врали, врут и будут врать. Причем делают они это так убедительно, что каким бы подозревакой ты не был, разок-другой тебя все равно наебунькают. К сожалению или счастью, общая производительность благодаря им все равно гораздо выше. Поэтому придется принять эту реальность. Кожанный мешок может лишь научиться вычленять критичные факты, и вовремя их проверять (используя те же llm для скорости проверки), прежде чем начинать реализовывать предложенный план.

Пока что с пунктом 2 у меня проблемы. Нейронки нахлабучивают меня регулярно, а я им даже в чан не могу прописать 😢
😢5👍2👏21
⚠️Итак, про пет проект и небольшой анонс! Если вы php разработчик, то это может быть вам интересно!⚠️

Те, кто ковыряются с пыхой знают, насколько важен стат анализ в их коде. В наши дни наличие phpstan или psalm в дев пайплайне уже вариант нормы. Ну это, если вы не wordpress разработчик — вам, ребята, мои искренние соболезнования и обнимашки🙆‍♂️

Тем не менее, существует огромное количество легаси проектов, в которых вместо современных DTO с readonly классами, все еще повсеместно используются наши любимые array. Но даже в современных проектах, внешний json незамедлительно декодится во что? Правильно, в std объект или массив! В этих ситуациях разработчик может почувствовать недостаток типизации в крови.

При этом, и phpstan, и psalm поддерживают array и object shapes в аннотациях типов, что позволяет добавить типизацию для массивов и объектов. Но аннотировать такое ручками часто больно и лениво😔

Поэтому мне пришла в голову идея "а что если бы можно было сделать дамп переменной, закинуть ее куда-то и на выходе получить аннотации типов?" Я не очень хорош в гуглеже, но ничего готового или похожего найти не получилось. Ну и будем честными, это отличная задачка на тему "напиши парсер с нуля", которую стоит попробовать сделать любому разработчику. Правда в моем случае, писал парсер я руками клода, хых.

Короче, в итоге родилась cli утилита hell2shape (https://github.com/Feolius/hell2shape)🤩

Но! я прекрасно понимаю вас, мои ленивые пирожочки, что вы даже исполняемый файл заленитесь скачать, и уж тем более не будете ставить это через композер. Поэтому специально для вас я сделал веб версию, чтоб вам вообще можно было не напрягаться https://hell2shape.netlify.app/, а сразу попробовать! Из прекрасного здесь то, что это все работает локально в браузере через php-wasm😍 Как следствие, я не парюсь насчет сервера, а вы не паритесь насчет ваших данных!

Теперь немного оправдашек:
1. Сразу скажу, что я не ставил задачу сгенерировать все типы абсолютно правильно. Это и невозможно! Тут скорее смысл в том, чтоб у разработчика появился некий бейзлайн, который он скопировал в ide, а дальше уже допиливал сам.
2. Генератор тупой как пробка. Это означает, что если вы ему дали на вход лист, в котором каждый элемент уникальный — на выходе вы получите лист, у которого элемент это юнион из кучи типов. Никакого лимита на количество типов в юнионе пока что нет.
3. Ну и в целом тема то сложная, обосраться можно много где. Так что не судите строго. Просто шлите баг репорты 😊

Пожалуйста пробуйте. И пишите, че думаете. Говно, не говно? На сколько полезно вам будет?
Please open Telegram to view this post
VIEW IN TELEGRAM
7🔥6🤝5
Вы не просили, но я все равно принес вам обзор на книгу. В этот раз отзыв будет о труде под названием "Распределенные данные" за авторством Алекса Петрова☝️Про себя я ее называю "недокабанчик".

Мы с Маськой изучили книгу и ставим ей четкие 5.5 из 10. Маська попросила накинуть 0.5 за рыбу на обложке😊Данную оценку можно интерпретировать как "Книга не полное говно, но и настоятельно рекомендовать ее не буду".

Это книга о базах данных в разрезе подсистем хранения. И название здесь совершенно сбивает с толку. Можно подумать, что она про базы данных исключительно в распределенных системах. Но это не так. Книга состоит из двух частей, и первая из них (бОльшая) посвящена исключительно одноузловым системам. И только вторая часть про алгоритмы распределенных СУБД.

В этой книге рассматриваются следующие темы:
* B-деревья
* Очень много разных B-деревьев
* Больше-больше B-деревьев
* LSM - деревья
* Важные слова про распределенные системы, куча бессмысленных описаний алгоритмов распределенных транзакций и выбора лидера, CAP - теорема.

Впринципи, больше ничего нет. Да, в книге про распределенные данные не написано толком ничего про репликацию и шардирование. Так бывает.

Тут есть две большие проблемы, которые и делают книгу "недокабанчиком". Первая заключается в том, что вы с книгой находитесь в противофазе. Это означает, что книга берет какой-то относительно простой факт, и начинает его разжевывать с помощью полотна текста и кучи рисунков. И ты такой думаешь "да заебал ты, давай дальше". Но зато, если какой-то хардкорный алгоритм рассматривается, то там автор уж как следует поскупится на объяснения. И ты перечитываешь это все раз за разом, а понимания не приходит😪

Второй момент связан с тем, что как учебник она так себе. Это легко можно понять по тому, что в книге очень много ссылок на БУДУЩИЕ главы. Я считаю, такое допустимо, только когда книга - справочник. Кстати, вы можете легко это исправить, если будете читать книгу задом наперед🤡

Но не только в организации дело. Пока читаешь книгу, то создается впечатление, что автор не поработал над материалом. Он просто брал научные статьи и пересказывал их общими словами, в надежде, что так оно лучше поймется. Не поймется. Оно как зашло, так и вылетело тут же.

Еще хуже обстоит дело, если есть возможность сравнить материал с кабанчиком. Например, можно взять LSM-деревья. Кабанчик шикарен. Он начинает от простой идеи хранения упорядоченных списков и постепенно расширяет ее, при этом избегая лишних сложностей. Тут же тебе сначала предстоит прочитать 5 страниц какой-то пежни ни о чем, а потом начинается жестб. Мне кажется, я бы нихера не понял без кабанчика.

В паре мест автор вообще прикололся. Нахуя-то вставил в книгу описание жестких вещей, над которыми ты прям пыжишься, чтоб понять. А в конце добавляет "мне неизвестны примеры практического использования этого алгоритма"🤡

Книга будет полезна, если вы хотите разобраться в
* B-деревьях (круто описаны)
* общих вещах и проблемах, связанных с распределенными системами

Она неплохо дополняет кабанчика в каких-то темах. Например, термин "линеаризуемость" может быть лучше понят с помощью этой книги. Но все равно пользы мало.

Вердикт: могло бы быть и лучше!

Кто найдет ошибку на второй фотке?
👏7❤‍🔥4🔥2
Карочи, попробовал использовать свой hell2shape в работе. Оказалось неюзабельное говно😀

Обнаружил две проблемы
* сам по себе результат var_dump неудобно получать, ибо все это по умолчанию в буфер вывода сыпется
* при вставке типов сучий phpstorm распепеживает форматирование вложенных структур в одну большую колбасу, все отступы исчезают, выглядит как кловн в смокинге 🤡 (см. картинку)

Первая проблема была ожидаема. Я предполагал, что var_dump не очень удобен в использовании. Но его универсальность как инструмента отладки подкупила. Вторая же проблема оказалась неожиданностью, потому что я вроде бы тестировал сохранение форматирования при вставке до этого, и все работало🤔 Но возможно мне показалось, и я в очередной раз обосрался.

Немного погрустил. Но на энергии грусти решил запилить фиксы в эти выходные. И мне кажется, получилось 🤩 Встречайте версию 0.4.2!

Первую проблему решил тем, что добавил фасад Hell2Shape, у которого всего один статик метод generate. В итоге можно прям в коде написать

$types = Hell2Shape::generate($var);

и получить типизацию в $types. А дальше уже вопрос, как ее скопировать. Можно, например, var_dump'ом 🤡 Но я обычно просто из дебаггера копирую. В любом случае, это уже не мои проблемы так гораздо проще😊

Вторую проблему удалось победить тем, что теперь hell2shape по-умолчанию генерирует PSR-5 DocComment. При вставке комментом все форматирование сохраняется (слава богу). А дальше его уже можно допиливать в редакторе, добавляя всякие @var и прочее. Появилась опция и в cli, и в gui, чтоб можно было отключить комменты, и вернуться к старому варианту.

Вот такие пирожочки, пирожочки!

Спасибо, что накидали (накидали же?🤨) звезд на гитхабе, даже несмотря на неюзабельное говно 😘

UPD. Чуть не забыл. Внутри Hell2Shape есть хелпер VarDumper, который позволяет сохранить var_dump переменной в переменную

$dump = VarDumper::dump($var);

Тоже должно помочь поидее
😁4👍31
В сеть утекли требования на джуна в 2026 году
🤣8🔥2😁2👍1😭1
Ну так что там у нас с десктопным линуксом? На сколько это все дружелюбно для рядового пользователя?

Как некоторые из вас могут помнить, перед новым годом я ставил кубунту. Ну как ставил. По сути это она ставила меня на место. Но в итоге все таки проблемы запуска удалось победить, и я даже как-то смог там обжиться😊

Ну как обжиться. Через включений 10 она просто начала зависать в рандомный момент или падать с какими-то ошибками😡

Давайте сразу объясню ситуацию, чтоб не началось вот это вот "рряяяя, нахера ты взял кубунту, надо было взять монжаро, арч, элементариос или астралинукс".

Линукс мне потребовался для дела. Не просто поразвлекаться и вспомнить молодость. Мне надо, чтоб все работало с минимальным количеством затрат. И даже если бы что-то не работало, я мог бы изи это все починить по гайдам в интернете. Некада мне тут экспериментировать. Поэтому и выбор в пользу самого попсового дистрибутива. Понятно так?

Поскольку kde че то подвели, было принято волевое решение поставить обычную убунту с гномом. Хотя сам гном мне никогда не нравился.

Первая проблема, которая бросилась в глаза: если комп засыпает, то после пробуждения монитор не включается, нет видеосигнала 🤡 Я решил, что если не замечать проблему, то она исчезнет, поэтому просто перестал пользоваться фичей "сон".

Ну это ладно. Начал ставить всякие приложухи. И само по себе это удовольствие ниже среднего, если ваши приложения не deb пакеты. Ну, например, если вам поставляют AppImage на электроне, то надо создать конфиг для apparmorа, иначе ничо не запустится. Представляете, как классно быть обычным пользователем самого дружелюбного дистрибутива?

Самый прикол не в этом. Понаставил я приложений, следуя всем инструкциям от разрабов. И в какой-то момент замечаю, что большинство из них просто отсутствуют в списке приложений! И они никак не ищутся.

Я пошел в интернет, и охуел, что эта проблема на столько распространена: раз, два, три. А решения то нет. Никакие советы мне не помогли.

И вот смотрите. Я хочу быть обычным пользователем. Я рот топтал эти ковыряния в настройках. Я даже задумываться не хотел, как там у гнома этот список приложений формируется. Но че то вот не получается оно никак.

Значится, для тех, кто как и я, последние N лет сидит на маке или винде, рассказываю, че там в убунте. Приложение появляется в меню, благодаря специальному файлику .desktop, который должен располагаться в одной из специальных директорий. Там всякая метаинформация, нужная для запуска, путь к иконке и тд.

Так вот, 2 часа ковыряний, и экспериментально выяснил, что если .desktop файл в имени содержит дефис, то приложение не появляется в списке🤡 А при этом разработчики, поставляют этот файлик с дефисом, например jetbrains-pycharm.desktop.

Вот и сиди, обычный пользователь, думай, че у тебя нет приложения в списке, лох!

Короче, вывод. Как бы кто не хейтил винду или мак, у обычных пользователей по факту нет альтернатив. Сорри. 6 лет не касался десктопного линукса, но он как был говном для специалистов, так и остается. Поэтому, если ты своей маме решил поставить убунту, ведь там все НЕХУЖЕ, будь готов выделить пару выходных в месяц и банку смазки (себе, не маме), чтоб решить ее проблемы.
4💯4👍2👨‍💻2🔥1
Полюбас у каждого разработчика есть нелюбимый тип тасков. У меня, как у бэкенд трудяги, в топе этого списка всегда находится интеграция с third-party api. Потому что
* это всегда куча неопределенности, которую невозможно оценить
* в 90 процентах случаев дока говно
* это всегда жопа с тестированием

Однако даже среди таких задач, оказывается, существует подвид задач, которые абсолютно прокляты. Я сейчас говорю про интеграцию с платежным api google и apple. Я бы даже расширил это до "интеграции с appstore и google play api".

Третьего дня свалилась задачка, что пора бы обновить интеграцию на сервере с apple app store api, потому что текущий способ устарел. Вот такое конечно особенно ценишь, когда все работает, но блять устарело. В итоге ценности для бизнеса ноль, для разработчика удвольствия ноль, а пердолинга по самые помидоры. Штош.

Карочи, почитал доку, и флоу в целом то понятен. Но проблема в том, что я php разработчик у меня нет айфона. И выясняется, что ты ну никак вот не можешь протестировать платежку без физического девайса. И даже, если ты сидишь на маке, и собрал приложение, запустил его на эмуляторе — все равно ты не сможешь ничо сделать.

Тоже самое с гуглом. Если хочешь тестировать платежки в google play, нужен девайс с андроидом🤷

Почему так? ну потому что якобы только на девайсах есть интеграция с эпп сторами. Но я считаю, что это просто высосано из пальца Тима Кака😡

Есть консоль разработчика, есть сэндбокс аккаунты. Какие проблемы встроить прогон тестовых сценариев прямо в консоли разработчика для сэндбокс аккаунтов? Вот мне, как бэкендщику, нахера вот это все связанное с девайсами? мне надо просто, чтоб данные появились на сервере у них. Неужели я так много прошу😢

еще и sdk под пхп не завезли 😔
👍3💯31🤝1
Вчера Валентин Удальцов с канала @phpyh разобрал код hell2shape на стриме, за что ему огромное человеческое спасибо. По итогу даже отправил pr с небольшим фиксом😍В конце выяснилось, что код hell2shape был написан с использованием llm 😀

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

Знаете, что общего между мной и Меркурием? Мы оба бываем очень ретроградными

Короче говоря, в своей работе я все еще не вайбкожу использую ллм только в чатике. Но надо как-то развиваться, чтоб не деграднуть совсем. Проект hell2shape я начал исходно с прицелом на попробовать вайбкодинг.

Сама по себе задача очень простая и прямолинейная. Есть понятные ввод и вывод. Есть понятные стадии обработки: лексер, парсер, генератор. Мне показалось, что это будет идеально для проверки возможностей ллм. В качестве агента решил использовать Cline + claude sonnet 4.5 (ебать это дорого оказалось)

По итогу llm бустанул меня так, шо я охерел. Учитывая, что писал я это вечерами после работы, будучи уже очень усталым, польза от ллм становится х2. Более конкретно, ллм помогла в следующем:
* создание каркаса приложения (генерация файлов с классами, структура папок и накидывание сигнатур методов)
* написание тестов
* написание документации (это вообще просто бомба)
* создание UI (ненавижу фронтенд)

НО!

Как только начиналась конкретная реализация, там в 80% случаев просто херня какая-то. Причем на всех уровнях. И если на макро уровне ты сразу видишь, что ллм неправильно использует паттерн visitor, то на микро уровне нейробред заметить гораздо тяжелее. Он часто выглядит ничошно так, уверенно. Но по факту, например, больше половины регулярок лексера были абсолютно неправильными.

Или вот решил я возвращать phpdoc вместо типов, о чем писал до этого. Понятное изменение. Сказал клоду, шоб делал. В итоге клод просто взял результат, разделил строку по \n, добавил префиксы пхпдоков и собрал обратно. Вроде валидно, но по факту ведь говно. Если бы у меня был заказчик, который торопил меня, я бы даже принял такое и поставил тудуху на фикс)

Поэтому я ему сказал "братиш, давай-ка ты все же генератор переделаешь". Клод кивнул, и ушел в бесконечный безуспешный цикл говна и палок. В итоге, все равно пришлось руками писать🤷

Мне кажется, что до сих пор не существует какой-то выверенной стратегии правильной работы с ллм. Тут все еще развивается и постоянно че то новое появляется. И то, как человек использует ллм зависит от
* персоналий
* проекта

Первый пункт очень важен. Вот мне очень тяжело ревьюить код, я это ненавижу просто. Это с одной стороны. А с другой стороны, я тот еще контрол фрик. Тяжело отпустить вожжи и просто принять говнокод в каком нить маловажном месте. Поэтому моя работа с ллм — это итеративные маленькие изменения, с мануальным апрувом каждого из них. И это гораздо медленнее "классического" вайбкодинга.

В этом смысле меня хорошо понимает зарубежный блогер ThePrimeagen. Он недавно зарелизил тулзу 99. В своей демке он показывал, как он пишет код с ней. И это просто моя мечта. Он пишет "заготовку" для метода с типами, выделяет ее, а затем просит ллм написать код внутри этой заготовки, который выполняет конкретную задачу. И это то, что мне откликается.

Много где слышал мнение, что нельзя отдавать тесты на откуп ллм. Но в моем случае специфика проекта такова, что тесты ллм как раз таки доверять можно и нужно. Потому что я имею дело с чистыми функциями, а готовить тестовые вардампы — это прям максимально неприятно. ллм это изи сделает.

Также специфика проекта это еще и об изолированности области, в которой вы вайбкодите. UI hell2shape — отличный пример. Я туда смотреть вообще не собираюсь. Мне этот html и css абсолютно не интересен. Более того, я еще и на компромиссы готов тут пойти, как единственный стейкхолдер. Поэтому здесь ускорение даже не в дестяки раз, а в сотни.

Кароче, тема пока что неясная для меня. Чувствую себя динозавром😢 Но польза от этого всего колоссальная.

Если не лень, пишите в комментах про ваши стратегии вайбкодинга🙏
5🔥4👍3
Давненько не было лонгридов. Решил это исправить.

Сегодня у меня жесткий наброс на mypy с точки зрения пхп разработчика. Возможно у кого-то из питонистов сгорит срака. Но у меня она, знаете ли, тоже горит, когда я на питон переключаюсь😡

Mypy vs Phpstan: битва стат анализаторов

Ну и как всегда, feel free to написать коммент, и сказать, где я обосрался и неправ😚
8🔥2👍1