Штош, шутки шутками, но настало время более серьезно поговорить про вайбкодинг, а точнее, про влияние вайбкодинга на разработчика. Так получилось, что сам я не выйбкодю. И далее по тексту вы увидите мои оправдашки, почему так.
В качестве поддержки своего мнения, я бы хотел обратиться к офигенной статье Why I stopped using AI code editors. На момент написания поста оригинал статьи почему-то недоступен, но есть копия в вебархиве. Я советую прочитать, очень отрезвляюще. Особенно прикольна аналогия с теслой, когда долгое использование автопилота привело к деградации навыка вождения у автора.
Почему же я не вайбкодю? Я отвечаю себе на этот вопрос так: прекращение работы над простыми вещами делает сложные вещи еще сложнее. В статье об этом говорится в части про Fingerspitzengefühl.
Приведу свою налогию. Какое-то время назад я занимался единоборствами. Одним из ключевых упражнений в тренировках было бить по мешку один и тот же удар определенное количество раз. Ну например, надо 100 раз ударить прямым ударом руки по мешку. Затем поменять руку и стойку и также 100 раз ударить. Потом тоже самое с другими видами ударов руками и ногами. Скучно кабзда! Но мне кажется, мало кто сомневается в полезности таких упражнений. Тренер всегда объяснял нам, зачем это делать. Нужно довести наши удары до автоматизма в "тепличных" условиях. В спаринге не будет таких условий. В спаринге часто оказываешься в неудобной позиции, тебя бьют, ты устаешь. Но ключ к победе в том, чтоб "прошел" один единственный удар, который ты наносишь, находясь в супер неудобных условиях. Вот для этого ты и долбишь часами один и тот же удар. И даже самые опытные бойцы продолжают бить эти самые удары и связки ударов. Потому что это важно.
Теперь представьте, что у вас появляется ИИ в тренировке. И он добавляет "множитель" к вашим ударам. Например, множитель 5: теперь вместо 100 ударов, надо сделать всего 20. Формально ты выполнишь тренировку, нанеся всего 20 ударов. Сделает ли это твою жизнь проще? Конечно сделает! Но в спарринге, человек, который честно набил 100 ударов будет иметь преимущество. У него и удары техничнее, и руки "набиты" лучше.
Любая аналогия ложна, в том числе и эта. Все таки тренировка не работа разработчиком, а спаринг не построение архитектуры ПО. Но я все равно считаю, что каким бы ремеслом ты не занимался (а программирование - это ремесло), важно продолжать делать "простые" вещи, если хочешь оставаться в этом ремесле и не терять квалификацию. При этом эти самые простые вещи можно делать с помощью современного инструментария: крутой IDE, фреймворка или даже ИИ. Но главное, делать.
Проблема вайбкодинга в том, что он отобирает возможность делать простые вещи. Это особенно черевато для джунов и тех, кто только хочет вкатиться в IT. Обманчивая иллюзия скорости и эффективности, которая по итогу приводит к отсуствию навыка у джунов и потере навыка у более опытных разработчиков. Кроме того, согласно недавнему исследованию Microsoft, само по себе использование ИИ оказывает негативное влияние на способность человека мыслить критически и к чрезмерной зависимости от этого самого ИИ.
Я непротив использования ИИ в целом. Я считаю, что ИИ пришел всерьез и надого, и сам активно использую его в работе. Оно очень помогает погрузиться в какую-то тему максимально быстро, получить ответ на вопрос, накинуть множество вариантов решения для выбора, объяснить что-то. Глупо спорить, что с ИИ продуктивность разработчиков сильно выросла по сравнению с традицонным гуглом + стэковефлоу.
Но на мой взгляд, вайбкодинг - это когда ИИ переступает уже черту крутого инструмента, забирая локус контроля у разработчика. Сам я боюсь потери навыка. Поэтому пока без него.
В завершении отмечу, что я тут не говорю о влиянии на бизнес, о корректности работы самого ИИ, о влиянии ИИ на код и индустрию. Я думаю, никто не сможет сказать, как это будет через год, два или пять лет. Но в одном я уверен: пока ИИ оперирует обычными ЯП, пока валидация решения остается на уровне обычного кода, никуда программистские навыки не денутся, кто бы там что не говорил.
В качестве поддержки своего мнения, я бы хотел обратиться к офигенной статье Why I stopped using AI code editors. На момент написания поста оригинал статьи почему-то недоступен, но есть копия в вебархиве. Я советую прочитать, очень отрезвляюще. Особенно прикольна аналогия с теслой, когда долгое использование автопилота привело к деградации навыка вождения у автора.
Почему же я не вайбкодю? Я отвечаю себе на этот вопрос так: прекращение работы над простыми вещами делает сложные вещи еще сложнее. В статье об этом говорится в части про Fingerspitzengefühl.
Приведу свою налогию. Какое-то время назад я занимался единоборствами. Одним из ключевых упражнений в тренировках было бить по мешку один и тот же удар определенное количество раз. Ну например, надо 100 раз ударить прямым ударом руки по мешку. Затем поменять руку и стойку и также 100 раз ударить. Потом тоже самое с другими видами ударов руками и ногами. Скучно кабзда! Но мне кажется, мало кто сомневается в полезности таких упражнений. Тренер всегда объяснял нам, зачем это делать. Нужно довести наши удары до автоматизма в "тепличных" условиях. В спаринге не будет таких условий. В спаринге часто оказываешься в неудобной позиции, тебя бьют, ты устаешь. Но ключ к победе в том, чтоб "прошел" один единственный удар, который ты наносишь, находясь в супер неудобных условиях. Вот для этого ты и долбишь часами один и тот же удар. И даже самые опытные бойцы продолжают бить эти самые удары и связки ударов. Потому что это важно.
Теперь представьте, что у вас появляется ИИ в тренировке. И он добавляет "множитель" к вашим ударам. Например, множитель 5: теперь вместо 100 ударов, надо сделать всего 20. Формально ты выполнишь тренировку, нанеся всего 20 ударов. Сделает ли это твою жизнь проще? Конечно сделает! Но в спарринге, человек, который честно набил 100 ударов будет иметь преимущество. У него и удары техничнее, и руки "набиты" лучше.
Любая аналогия ложна, в том числе и эта. Все таки тренировка не работа разработчиком, а спаринг не построение архитектуры ПО. Но я все равно считаю, что каким бы ремеслом ты не занимался (а программирование - это ремесло), важно продолжать делать "простые" вещи, если хочешь оставаться в этом ремесле и не терять квалификацию. При этом эти самые простые вещи можно делать с помощью современного инструментария: крутой IDE, фреймворка или даже ИИ. Но главное, делать.
Проблема вайбкодинга в том, что он отобирает возможность делать простые вещи. Это особенно черевато для джунов и тех, кто только хочет вкатиться в IT. Обманчивая иллюзия скорости и эффективности, которая по итогу приводит к отсуствию навыка у джунов и потере навыка у более опытных разработчиков. Кроме того, согласно недавнему исследованию Microsoft, само по себе использование ИИ оказывает негативное влияние на способность человека мыслить критически и к чрезмерной зависимости от этого самого ИИ.
Я непротив использования ИИ в целом. Я считаю, что ИИ пришел всерьез и надого, и сам активно использую его в работе. Оно очень помогает погрузиться в какую-то тему максимально быстро, получить ответ на вопрос, накинуть множество вариантов решения для выбора, объяснить что-то. Глупо спорить, что с ИИ продуктивность разработчиков сильно выросла по сравнению с традицонным гуглом + стэковефлоу.
Но на мой взгляд, вайбкодинг - это когда ИИ переступает уже черту крутого инструмента, забирая локус контроля у разработчика. Сам я боюсь потери навыка. Поэтому пока без него.
В завершении отмечу, что я тут не говорю о влиянии на бизнес, о корректности работы самого ИИ, о влиянии ИИ на код и индустрию. Я думаю, никто не сможет сказать, как это будет через год, два или пять лет. Но в одном я уверен: пока ИИ оперирует обычными ЯП, пока валидация решения остается на уровне обычного кода, никуда программистские навыки не денутся, кто бы там что не говорил.
web.archive.org
Why I stopped using AI code editors ·
Luciano Nooijen
Luciano Nooijen
In the past I used AI code editors for all of my programming, but I stopped using it and recommend others to consider this as well
❤5🔥4👍1
Корочи, на работе продолжаем пилить жесткую тему связанную с ИИ🤖Для этого у нас в команде есть специально обученный (нет) человек, чтоб заниматься непотребствами с llm и всячески их тюнить. Ибо тема эта новая, и, кажется, человечество создало нечто такое, в чем само поитогу разобраться не может. Требуются бесконечные эксперименты с промптами и всякими агентами.
Разумеется, то тут, то там, начали вылезать фреймворки для разработки "expressive, customizable agent workflows". Суть их в том, чтоб ускорить накидывание говна в llm, в надежде получить че-то хорошее на выходе. По сути - ускорить обратную связь. Одним из таких фреймворков является набирающий популярность сейчас langgraph. Решили попробовать часть функционала переписать с помощью него. Потому что на бумаге все звучит очень круто🤩
Основная идея, на которой построен langgraph - представление логики обработки запроса пользователя в виде графа. В этом графе каждый узел - это какая-то функция, которая может сходить в llm или вызвать локальный инструмент (tool) или запросить помощь от пользователя. Можно определить условия перехода в тот или иной узел. А еще langgraph позволяет работать с состоянием. Каждая нода ведет себя каксучька редьюсер в react redux - принимает на вход старое состояние и возвращает новое. Ну не красота ли!
Но по факту опыт получился смешанный. Потому что нахуевертили!
Если вы начнете погружаться в langgraph, то обнаружите, что там довольно много документации. Ситуация осложняется еще и тем, что разработчики предоставили миллиард способов сделать одну и ту же херню. Да там даже 2 разных независимых API существует зачем-то! Короче, готовьтесь пару дней тратить только на чтение буков🤓
Ну это ладно. Самая большая проблема для нас оказалась в персистентности. Ведь логично предположить, что агент, который забывает предыдущий ответ пользователя - это как дед с деменцией - вроде парень неплохой, только ссытся и глухой. Поэтому разработчики добавили "память" в langgraph. Но сделали это через жепу.
Вам предлагается модель чекпоинтеров, когда переход через каждый узел сохраняется в хранилище. Поэтому всегда можно восстановить состояние и продолжить.
Проблема в том, что я могу НЕ хотеть сохранять промежуточный мусор пока запрос не выполнился полностью. Потому что если на середине пути у меня вывалилась ошибка, то я хочу просто начать сначала без предыдущих потуг. И langgraph не особо дает это сделать. Более того, разработчики, видимо поняв, что идея с чекпоинтерами не слишком гибкая, добавили еще один вид памяти long term. И это какая то невнятная дичь. Вдовесок ко всему, модель хранения langgraph по сути скрыта. Например, захотите вы проанализировать транскрипт пользователя - ну удачи вам.
В итоге, мы решили использовать langgraph только как способ организовать код в виде графа. Это реально облегчило прототипирование, поскольку позволило отвязать весь наш остальной код от логики работы агента. Мы сами храним и состояние, и транскрипт, и общую память о пользователе, а в langgraph бегаем просто как в black box. На вход ему подаем наши загруженные данные + запрос пользователя. После обработки запроса графом, мы используем результат для обновления состояний, метрик, транскрипта и т.п.
Я считаю, что в этом и состоялась основная польза от использования langgraph. Именно отделение кода логики агента от остального кода - основная ценность. Поскольку этими двумя частями заведуют разные люди в команде.
А сам по себе langgraph на 5.5 из 10. Много что есть сразу, но не гибко, сложно, потно!😰Будем надеяться, что это просто первые попытки человечества создать фреймворк под написание агентов, и дальше будет лучше.
Разумеется, то тут, то там, начали вылезать фреймворки для разработки "expressive, customizable agent workflows". Суть их в том, чтоб ускорить накидывание говна в llm, в надежде получить че-то хорошее на выходе. По сути - ускорить обратную связь. Одним из таких фреймворков является набирающий популярность сейчас langgraph. Решили попробовать часть функционала переписать с помощью него. Потому что на бумаге все звучит очень круто🤩
Основная идея, на которой построен langgraph - представление логики обработки запроса пользователя в виде графа. В этом графе каждый узел - это какая-то функция, которая может сходить в llm или вызвать локальный инструмент (tool) или запросить помощь от пользователя. Можно определить условия перехода в тот или иной узел. А еще langgraph позволяет работать с состоянием. Каждая нода ведет себя как
Но по факту опыт получился смешанный. Потому что нахуевертили!
Если вы начнете погружаться в langgraph, то обнаружите, что там довольно много документации. Ситуация осложняется еще и тем, что разработчики предоставили миллиард способов сделать одну и ту же херню. Да там даже 2 разных независимых API существует зачем-то! Короче, готовьтесь пару дней тратить только на чтение буков🤓
Ну это ладно. Самая большая проблема для нас оказалась в персистентности. Ведь логично предположить, что агент, который забывает предыдущий ответ пользователя - это как дед с деменцией - вроде парень неплохой, только ссытся и глухой. Поэтому разработчики добавили "память" в langgraph. Но сделали это через жепу.
Вам предлагается модель чекпоинтеров, когда переход через каждый узел сохраняется в хранилище. Поэтому всегда можно восстановить состояние и продолжить.
Проблема в том, что я могу НЕ хотеть сохранять промежуточный мусор пока запрос не выполнился полностью. Потому что если на середине пути у меня вывалилась ошибка, то я хочу просто начать сначала без предыдущих потуг. И langgraph не особо дает это сделать. Более того, разработчики, видимо поняв, что идея с чекпоинтерами не слишком гибкая, добавили еще один вид памяти long term. И это какая то невнятная дичь. Вдовесок ко всему, модель хранения langgraph по сути скрыта. Например, захотите вы проанализировать транскрипт пользователя - ну удачи вам.
В итоге, мы решили использовать langgraph только как способ организовать код в виде графа. Это реально облегчило прототипирование, поскольку позволило отвязать весь наш остальной код от логики работы агента. Мы сами храним и состояние, и транскрипт, и общую память о пользователе, а в langgraph бегаем просто как в black box. На вход ему подаем наши загруженные данные + запрос пользователя. После обработки запроса графом, мы используем результат для обновления состояний, метрик, транскрипта и т.п.
Я считаю, что в этом и состоялась основная польза от использования langgraph. Именно отделение кода логики агента от остального кода - основная ценность. Поскольку этими двумя частями заведуют разные люди в команде.
А сам по себе langgraph на 5.5 из 10. Много что есть сразу, но не гибко, сложно, потно!😰Будем надеяться, что это просто первые попытки человечества создать фреймворк под написание агентов, и дальше будет лучше.
langchain-ai.github.io
Overview
Build reliable, stateful AI systems, without giving up control
❤5👍2
В прошлый раз рассказывал про langgraph. а сегодня расскажу о том, почему у меня сгорела дыра из-за него🌚
Дело в том, что langgraph пытается казаться на столько удобным решением, что они даже запилили собственную IDE, и назвали ее langgraph studio (далее lgs). Очень блять оригинально.
Как же выглядит IDE для разработки агентов? Нужно ли там писать код? Можно ли там вайбкодить с помощью агента, которого сам же пишешь? 🤔 Все эти вопросы сразу остро встают на повестке дня.
Но все гораздо прозаичнее (см. картинку). Эта присрачка позволяет запускать каждый узел в графе (функцию) отдельно, мейнтейнить стейт, менять входные параметры. Короче говоря, позволяет всячески эксперементировать с узлами без необходимости работать с полным циклом запрос-ответ. Удобно? Не то слово! Идея просто бомбическая.
Разумеется, наш специально обученный человек сразу захотел lgs использовать. И тут его трудно осуждать.
Сначала все было хорошо. Сплошные востороженные возгласы. Но внезапно мне прилетает тревожное сообщение "В lgs не работает подключение к бд"😱
Начал разбираться в проблеме. Как вы можете помнить, коннекшн к бд я храню в contextvars. Подробнее об этом я писал тут. Когда lgs запускает отдельно ноду, то contextvars пустые. Поэтому и подключения нет. Надо как-то подключиться к бд и положить коннекшн в переменную перед запуском каждой ноды. Изи!
И вот тут меня настигло абсолютное разочарование. Потому что никакого способа это сделать разработчики не предоставили. Ни хуков, ни api для плагинов, вообще ни-ху-я. Просто нет возможности выполнить код в этой IDE помимо кода узла😔
ТО ЕСТЬ, разрабы lgs дали способ работать с каждым узлом изолированно от всего остального кода, но не подумали, что может потребоваться ЧТО-ТО от этого остального кода. Гении ебать!
В общем ключе задача формулируется так: "У библиотеки или тулзы отсутствует нужный api для взаимодействия, а вам позарез надо вмешаться в ее модель выполнения". Звучит конечно так себе. Поэтому добавим "...для разработки или тестирования"😏
Это был пост-затравка. В следующем посте я расскажу, как решал эту проблему в python. Но подобный метод может применяться практически в любых интерпретируемых ЯП. В комментах пишите, как бы вы решали подобную проблему👇
Дело в том, что langgraph пытается казаться на столько удобным решением, что они даже запилили собственную IDE, и назвали ее langgraph studio (далее lgs). Очень блять оригинально.
Как же выглядит IDE для разработки агентов? Нужно ли там писать код? Можно ли там вайбкодить с помощью агента, которого сам же пишешь? 🤔 Все эти вопросы сразу остро встают на повестке дня.
Но все гораздо прозаичнее (см. картинку). Эта присрачка позволяет запускать каждый узел в графе (функцию) отдельно, мейнтейнить стейт, менять входные параметры. Короче говоря, позволяет всячески эксперементировать с узлами без необходимости работать с полным циклом запрос-ответ. Удобно? Не то слово! Идея просто бомбическая.
Разумеется, наш специально обученный человек сразу захотел lgs использовать. И тут его трудно осуждать.
Сначала все было хорошо. Сплошные востороженные возгласы. Но внезапно мне прилетает тревожное сообщение "В lgs не работает подключение к бд"😱
Начал разбираться в проблеме. Как вы можете помнить, коннекшн к бд я храню в contextvars. Подробнее об этом я писал тут. Когда lgs запускает отдельно ноду, то contextvars пустые. Поэтому и подключения нет. Надо как-то подключиться к бд и положить коннекшн в переменную перед запуском каждой ноды. Изи!
И вот тут меня настигло абсолютное разочарование. Потому что никакого способа это сделать разработчики не предоставили. Ни хуков, ни api для плагинов, вообще ни-ху-я. Просто нет возможности выполнить код в этой IDE помимо кода узла😔
ТО ЕСТЬ, разрабы lgs дали способ работать с каждым узлом изолированно от всего остального кода, но не подумали, что может потребоваться ЧТО-ТО от этого остального кода. Гении ебать!
В общем ключе задача формулируется так: "У библиотеки или тулзы отсутствует нужный api для взаимодействия, а вам позарез надо вмешаться в ее модель выполнения". Звучит конечно так себе. Поэтому добавим "...для разработки или тестирования"😏
Это был пост-затравка. В следующем посте я расскажу, как решал эту проблему в python. Но подобный метод может применяться практически в любых интерпретируемых ЯП. В комментах пишите, как бы вы решали подобную проблему👇
❤5
Итак, я обозначил проблему. Вкратце: у нас библиотека или тулза, которая настолько говяная, что к ней не подступиться через публичный api, но недостаточно говяная, чтоб от нее отказываться. А нам позарез надо что-то поменять в ее поведении.
В комментах никто не написал, как бы это делал (эх 😔), поэтому дам ответ сам: monkey patch - это возможность менять код в рантайме.
Как же это выглядит в моем случае. У меня тулза - это вонючий langgraph studio (lgs), и мне надо, чтоб во всем коде, при запуске через lgs было доступно подключение к бд.
Напоминаю, что все питонисты обмазываются декораторами. Я решил не отставать. Написал декоратор db_aware такой, что
Пусть точка входа в наш граф находится в файлике my_agent/graph.py, его мы подаем на вход lgs. В файлике my_agent/nodes.py находится код всех нод графа. Напоминаю, что ноды - это просто функции. Тогда можно написать новую точку входа только для lgs
Выглядит потно, согласен. Но на самом деле, главное здесь - это подход. Ведь он применим ко всем популярным интерпертируемым языкам программирования: python, php, ruby, js.
Например, в php можно тупо перегрузить stream для чтения файлов, и менять код прямо во время чтения интерпретатором исходников. Именно так работает пакет dg/bypass-finals, позволяющий мокать final классы.
Самое главное, помните, что monkey patch следует использовать только при разработке! В продакшне использовать подобное - это надо быть очень смелым, либо очень тупым. Лучше не надо.
В комментах никто не написал, как бы это делал (эх 😔), поэтому дам ответ сам: monkey patch - это возможность менять код в рантайме.
Как же это выглядит в моем случае. У меня тулза - это вонючий langgraph studio (lgs), и мне надо, чтоб во всем коде, при запуске через lgs было доступно подключение к бд.
Напоминаю, что все питонисты обмазываются декораторами. Я решил не отставать. Написал декоратор db_aware такой, что
@db_aware
async def some_func():
# db стопроц будет тут
db = get_db()
# далее в коде юзаем db в хвост и гриву
Пусть точка входа в наш граф находится в файлике my_agent/graph.py, его мы подаем на вход lgs. В файлике my_agent/nodes.py находится код всех нод графа. Напоминаю, что ноды - это просто функции. Тогда можно написать новую точку входа только для lgs
# Исходный пакет с нодами
NODES_MODULE: Final[str] = "my_agent.nodes"
class DbAwareNodes(ModuleType):
def __init__(self, module: str):
super().__init__(module)
# Сохраняем исходные функции
self._original_nodes = importlib.import_module(NODES_MODULE)
# __getattr__ вызывается когда интерпретатор импортирует имя из модуля
def __getattr__(self, name):
# Находим исходную функцию
node = getattr(self._original_nodes, name)
# Декоратор работает только с корутинами
if iscoroutinefunction(node):
# Декорируем исходную функцию
return db_aware(node)
return node
# Здесь подменяем дефолтный модуль на наш пропатченный
sys.modules[NODES_MODULE] = DbAwareNodes(NODES_MODULE)
# Экспортируем наш граф, будто это точка входа.
from pain_agent.graph import graph
__all__ = ["graph"]
Выглядит потно, согласен. Но на самом деле, главное здесь - это подход. Ведь он применим ко всем популярным интерпертируемым языкам программирования: python, php, ruby, js.
Например, в php можно тупо перегрузить stream для чтения файлов, и менять код прямо во время чтения интерпретатором исходников. Именно так работает пакет dg/bypass-finals, позволяющий мокать final классы.
Самое главное, помните, что monkey patch следует использовать только при разработке! В продакшне использовать подобное - это надо быть очень смелым, либо очень тупым. Лучше не надо.
❤3👍3🙈2
Вышло очередное обновление индекса языков программирование TIOBE. Меня прикалывает, как создатели TIOBE продолжают срать себе в штаны, делая вид, что все в порядке👌
"У нас Ada обогнал PHP и Kotlin, а Visual Basic будет попизже Golang. Perl попал в 10ку, а Ruby, даже в 20ке не видно. Typescript мы поместили на 35е место. Вас что-то смущает?.. Нам поебать!" - так прокомментировал свежие данные рейтинга глава TIOBE Вротстислав Хуепутолов.
Ну а если серьезно, когда видишь в одном рейтинге matlab и php, то сразу же вопрос возникает, а для кого это составляется вообще? в чем польза?
The index can be used to check whether your programming skills are still up to date or to make a strategic decision about what programming language should be adopted when starting to build a new software system.
Я считаю, что индекс можно использовать для проверки того, на сколько челики в TIOBE ебнулись в своих метриках, который нахер никому кроме них самих не нужны. Тупее было бы только составить рейтинг по количеству букв в названии языка. Хотя нет, даже это имело бы больше смысла😡
Единственное, что могло бы оправдать этот рейтинг из жопы, это если бы TIOBE просто бабок занесли. Но мы об этом никогда не узнаем.
"У нас Ada обогнал PHP и Kotlin, а Visual Basic будет попизже Golang. Perl попал в 10ку, а Ruby, даже в 20ке не видно. Typescript мы поместили на 35е место. Вас что-то смущает?.. Нам поебать!" - так прокомментировал свежие данные рейтинга глава TIOBE Вротстислав Хуепутолов.
Ну а если серьезно, когда видишь в одном рейтинге matlab и php, то сразу же вопрос возникает, а для кого это составляется вообще? в чем польза?
The index can be used to check whether your programming skills are still up to date or to make a strategic decision about what programming language should be adopted when starting to build a new software system.
Я считаю, что индекс можно использовать для проверки того, на сколько челики в TIOBE ебнулись в своих метриках, который нахер никому кроме них самих не нужны. Тупее было бы только составить рейтинг по количеству букв в названии языка. Хотя нет, даже это имело бы больше смысла😡
Единственное, что могло бы оправдать этот рейтинг из жопы, это если бы TIOBE просто бабок занесли. Но мы об этом никогда не узнаем.
Че-то в последнее время тяжеловато идет написание постов. Много работы и уходящее лето, когда надо успеть чуток почиллить, - делают свое дело!
Контент план есть, тем много. Темы появляются быстрее, чем успевается о них писать. Но я тот еще писака, поэтому на написание одного поста у меня уходит от 2х часов 😔 Сами понимаете, как с такими таймингами тяжело вписаться в текущую жизнь.
Тем не менее, будем надеяться, что с приходом осени все стабилизируется. На улице будет нечего делать, и придется заниматься эскопизмом в канале 😊
Контент план есть, тем много. Темы появляются быстрее, чем успевается о них писать. Но я тот еще писака, поэтому на написание одного поста у меня уходит от 2х часов 😔 Сами понимаете, как с такими таймингами тяжело вписаться в текущую жизнь.
Тем не менее, будем надеяться, что с приходом осени все стабилизируется. На улице будет нечего делать, и придется заниматься эскопизмом в канале 😊
❤2🤯2
Но чтобы перерывы в постах о программировании не были такими уж длинными, я воспользуюсь читерной рубрикой "подписчики набрасывают на вентилятор".
Мне тут скинули старую, но презабавнейшую статью What is {} + {} in JavaScript?. В статье автор задается вопросом, а что будет при выполнении следующих операций в js
Спойлер:будут приколы.
Для []+{} ответ '[object Object]'. []+[] - это ''. И наконец, два моих "любимых": {} + [] дает 0, а {} + {} вернет NaN.
Для "любимых" объяснение такое, что первый {} js интерпретирует как пустой блок кода 🤡, а дальше уже приводит второй аргумент к числу в соответствии с действием унарного оператора +. Ну не красота ли! Об остальных можно прочесть в статье.
Может показаться, что всем результатам есть логичное объяснение. И в статье это объяснение дается. Но по факту, это просто торчащие уши плохого дизайна js, с которым приходится мириться и по сей день, используя костыли в виде ts. Запоминать такое поведение категорически противопоказанно для сохранения рассудка! 👆
А если на собеседованиях вас спрашивают про подобные особенности, то можете смело проваливать это интервью, потому что тех. лид долбаеб, и делать в такой компании нечего. Ну либо можете зазубрить кучу таких кейсов и задоминировать! Но будьте осторожны, ведь тогда можно самому ебнуться наглухо и стать вонючим душнилой🤓 Смотрите сами короче
Мне тут скинули старую, но презабавнейшую статью What is {} + {} in JavaScript?. В статье автор задается вопросом, а что будет при выполнении следующих операций в js
[]+{}
[]+[]
{}+[]
{}+{}
Спойлер:
Для []+{} ответ '[object Object]'. []+[] - это ''. И наконец, два моих "любимых": {} + [] дает 0, а {} + {} вернет NaN.
Для "любимых" объяснение такое, что первый {} js интерпретирует как пустой блок кода 🤡, а дальше уже приводит второй аргумент к числу в соответствии с действием унарного оператора +. Ну не красота ли! Об остальных можно прочесть в статье.
Может показаться, что всем результатам есть логичное объяснение. И в статье это объяснение дается. Но по факту, это просто торчащие уши плохого дизайна js, с которым приходится мириться и по сей день, используя костыли в виде ts. Запоминать такое поведение категорически противопоказанно для сохранения рассудка! 👆
А если на собеседованиях вас спрашивают про подобные особенности, то можете смело проваливать это интервью, потому что тех. лид долбаеб, и делать в такой компании нечего. Ну либо можете зазубрить кучу таких кейсов и задоминировать! Но будьте осторожны, ведь тогда можно самому ебнуться наглухо и стать вонючим душнилой🤓 Смотрите сами короче
2Ality
What is {} + {} in JavaScript?
Recently, the lightning talk “Wat” by Gary Bernhardt pointed out an interesting JavaScript quirk: You get unexpected results when you add objects and/or arrays. This post explains those results.
😁5💯2❤1
Прикол. У меня прям сейчас таск по обновлению пакетов. Обновляю-обновляю, и вдруг перестает все собираться. И ошибка такая интересная
Захожу на гитхаб, а тут issue час назад была создана Version 4.4.2 published to npm is compromised.
С одной стороны, как бы круто что в npm так быстро сработали. С другой стороны, че то я себя не очень безопасно щас почувствовал, даже несмотря на то, что этой версии уже нет в npm. Какое-то время эта херабора запускалась у меня локально, пусть и в контейнере.
Вообщем в мире js все как всегда 😔
npm error 404 Not Found - GET https://registry.npmjs.org/debug/-/debug-4.4.2.tgz - Not found
Захожу на гитхаб, а тут issue час назад была создана Version 4.4.2 published to npm is compromised.
С одной стороны, как бы круто что в npm так быстро сработали. С другой стороны, че то я себя не очень безопасно щас почувствовал, даже несмотря на то, что этой версии уже нет в npm. Какое-то время эта херабора запускалась у меня локально, пусть и в контейнере.
Вообщем в мире js все как всегда 😔
GitHub
(RESOLVED) Version 4.4.2 published to npm is compromised · Issue #1005 · debug-js/debug
MESSAGE FROM @Qix- : PLEASE SEE #1005 (comment) FOR LATEST UPDATES. Version not present in this repo has been pushed out to npm. https://www.npmjs.com/package/debug/v/4.4.2?activeTab=code src/index...
👍1😱1
А я отвечу постом на комментарий выше про то, что это касается не только js.
Да, безусловно, такое может произойти в любой экосистеме, не только в js. Везде есть уязвимости!
Но js отличает то, что здесь какое-то неадекватное количество peer dependencies. Авторы пакетов на каждый чих используют другой сторонний пакет. Мемный пакет is-odd все еще с нами, и у него ебейшее количество скачиваний в неделю. А истории про то, что папка node_modules занимает гигабайты - это вообще-то норма, а не исключение.
Именно потому что в папке node_modules лежат миллиарды пакетов, вероятность получить уязвимость кратно возрастает!
У меня 3 экосистемы на поддержке: js, php и python. И раз в полгода мне надо обновлять пакеты для аудита. И я хочу сказать, что если у вас более менее серьезный проект, то довести количество уязвимостей до 0 в js нереально. Мне ни разу не удавалось это даже для внутренних простеньких проектов. В то же время для php и python отсутствие уязвимостей - это скорее норма.
Конкретно в случае с пакетом debug это зависимость express
А самое смешное то, что я вот откатил этот злоебучий пакет до предыдущей версии, а в нем 7 критических уязвимостей 🤡
Поэтому нет, я не соглашусь, что оно везде все так. В js количество уже перетекло в качество. Точнее в его отсутствие.
Да, безусловно, такое может произойти в любой экосистеме, не только в js. Везде есть уязвимости!
Но js отличает то, что здесь какое-то неадекватное количество peer dependencies. Авторы пакетов на каждый чих используют другой сторонний пакет. Мемный пакет is-odd все еще с нами, и у него ебейшее количество скачиваний в неделю. А истории про то, что папка node_modules занимает гигабайты - это вообще-то норма, а не исключение.
Именно потому что в папке node_modules лежат миллиарды пакетов, вероятность получить уязвимость кратно возрастает!
У меня 3 экосистемы на поддержке: js, php и python. И раз в полгода мне надо обновлять пакеты для аудита. И я хочу сказать, что если у вас более менее серьезный проект, то довести количество уязвимостей до 0 в js нереально. Мне ни разу не удавалось это даже для внутренних простеньких проектов. В то же время для php и python отсутствие уязвимостей - это скорее норма.
Конкретно в случае с пакетом debug это зависимость express
+-- debug@4.4.1
`-- express@5.1.0
+-- body-parser@2.2.0
| `-- debug@4.4.1 deduped
+-- debug@4.4.1 deduped
+-- finalhandler@2.1.0
| `-- debug@4.4.1 deduped
+-- router@2.2.0
| `-- debug@4.4.1 deduped
`-- send@1.2.0
`-- debug@4.4.1 deduped
А самое смешное то, что я вот откатил этот злоебучий пакет до предыдущей версии, а в нем 7 критических уязвимостей 🤡
Поэтому нет, я не соглашусь, что оно везде все так. В js количество уже перетекло в качество. Точнее в его отсутствие.
👍2☃1
Я уже 5 лет плотничком работаю с Doctrine ORM. Работа у меня разнообразная. Пишем мы и новый код, с новыми таблицами в бд. Но также имеется большая легаси база говна данных, на которую мы старательно натягиваем Doctrine. Короче, всякое повидал за эти годы, в том числе даже поконтрибьютил в саму Doctrine.
Несмотря на то, что в целом впечатления от Doctrine благостное (по сравнению с тем же Eloquent хех), эта ORM может вставить палки в колеса. Как и любой инструмент. Об этом я написал свой очередной лонгрид Как Doctrine ORM ломает вашу архитектуру.
Я постарался рассказать об основных принципах работы этой ORM так, чтоб было понятно даже тем, кто никогда не работал с Doctrine. А по скольку Doctrine - это классический пример Data Mapper, все эти принципы могут быть применены к другим Data Mapper ORM, например Hibernate и SQLAlchemy.
А от тех, кто тоже успел поработать с Doctrine, жду накидывания на меня какашек о том, что я просто все неправильно понял 😘
Несмотря на то, что в целом впечатления от Doctrine благостное (по сравнению с тем же Eloquent хех), эта ORM может вставить палки в колеса. Как и любой инструмент. Об этом я написал свой очередной лонгрид Как Doctrine ORM ломает вашу архитектуру.
Я постарался рассказать об основных принципах работы этой ORM так, чтоб было понятно даже тем, кто никогда не работал с Doctrine. А по скольку Doctrine - это классический пример Data Mapper, все эти принципы могут быть применены к другим Data Mapper ORM, например Hibernate и SQLAlchemy.
А от тех, кто тоже успел поработать с Doctrine, жду накидывания на меня какашек о том, что я просто все неправильно понял 😘
👍7