Search
Write a publication
Pull to refresh
22
11
Григорий Мясоедов @grisha9

Java Developer, Open Source Contributor

Send message

а как добавить туда свой плагин?

Спасибо за замечание - линк добавил.
Потомучто в настоящий момент поддержка Quarkus является частью Explyt Spring Plugin.
Почему так - мы постарались объяснить в самом первом абзаце.
И далее тоже - что это позволяет переиспользовать многие из наших "фич" также и для Quarkus

В большинстве моих проектов коллекции лежали в БД, 

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

Самое смешное мой первый друг также сказал что у него все БД и он все делает на ее стороне. На что я ему пошутил, что теперь придется добавлять базу в каждый проект, чтобы туда выгружать данные и на стороне бд решать проблему filter/map/reduce. Да и есть кейсы когда проще что то вычислить уже по имеющимся данным, чем делать второй запрос или делать страшные вещи проде union или outer join натягивая сову на глобус.

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

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

Так я поэтому и задал вопрос, про создание массивов после каждой операции, и те библиотеки что вы показали, именно так и делают - грузят память. А в c#/java/kotlin такой проблемы нет по дефолту в sdk! Все уже давно как я писал отлажено и оптимизировано. Java вообще всегда создает stream и не создает лишних списков там где это не надо, в котлин можно управлять этим поведением. И основная область применения у jvm стека также как и у го это бэкэнд, и она тоже хорошо с этим справляется, большинство банков используют этот стек.

Даже не знаю, что на это ответить. В теории - да, это звучит логично. На практике - нет, не сталкивался. 

Вот честно, не знаю даже что опять и думать) Вот взять мой реальный случай с двумя друзьями описанный выше, первый показал мне свои утилитные файлы хелперы, которые копирует из проекта в проект (все по канонам го), другой реализовал “ручками” с мапой и проходом по циклу. Даже тут мимо… Я не первый день живу и вижу как пишут код, чем больше свободы, тем больше проблем. А го как раз из за своей “бедноты” дает больше возможностей написать код по разному. 

Это как пример - заставить разные бригады собирать каркасные дома, или вывалить перед ними кучу кирпичей и сказать стройте. Ну очевидно же те кто будет строить из более крупных и готовых блоков, построят +- одинаковые и проверенные временем решения, где во втором случае каждый сам себе художник. (Понятное дело, тут тоже надо знать меру (в разнообразии элементов) и не “свалиться” в kotlin, о чем я также писал выше)

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

P.S. Вот лично я не ничего против не имею про исключения в го, ну есть у них такой подход - ок. Обработка исключений как по мне это всегда более бизнес специфичный кейс.

С интерфейсами мне тоже все понятно, что есть метод куда нужно передать разные объекты, по месту создается нужный интерфейс который покрывает все возможные вариации входных типов и вуаля “утиная” типизация в действии.

В целом мне достаточно того что я у Вас услышал вскользь “грустные нотки” и про тернарные операторы и про конвейерные операции, но лично я не хочу писать на “Pascal” и иметь проблемы о которых писал выше. Но в любом случае спасибо Вам за дискуссию. я все)

Заранее извиняюсь, но продолжим душную дискуссию)

Не спрашивали знакомых гоферов? Неужели все гоферы мазохисты и любят писать кучу лишнего кода?

Не поверите, спрашивал. Добавлю контекста - это два моих давнишних институтских друга с которыми вместе закончили вуз в 2008г. Сейчас они оба работают го-девелоперами, в достаточно крупных компаниях. Мнения разделились - один ничего не хочет слышать и го просто самый лучший язык, и рассказывает и показывает ихние утилитные файлы которые они копируют из проекта в проект, что у меня кроме смеха ничего не вызывает. Второй признает проблему, мы кстати с ним вместе ранее работали в одном из цветных банков на jvm стеке. Так вот он признает проблему и говорит, что ему этого не хватает, но го ему все равно очень нравится) И также обронил фразу что простота го обманчива (об этом я далее напишу) Когда я попросил его написать пример из моего первого поста, он сделал простой цикл с мапой) ну это так к слову…
Также сошлюсь еще на видео с Кириллом Макевниным (создателем Хекслет, кстати его видео про ментальное программирование сильно на меня повлияли как мне думается в лучшую сторону) где он задает похожие вопросы гоферу и получает похожие ответы, что так принято, а толком почему не говорит. Но гофер в видео также отмечает что ему всеже не хватает стандартной библиотеки. (Видео давнишнее и смотрел я его давно, а не искал специально чтобы Вам ответить, там они затрагивают еще момент с дженериками, но сейчас это уже не так актуально)

И таких случаев на практике оказывается достаточно мало (ну, по крайней мере в типовых Go-шных проектах вроде утилит и бэкенда)

Я вот в бытность бэкендером регулярно использовю Stream API java/kotlin и почти любая операция с коллекциями это обращение к ним, хотя может быть проблема во мне) Да и весь код который я вижу по работе и не только - аналогично.

Нет, сильная сторона - это как раз ясность и читабельность кода.

Опять же, я не был бы столь категоричен, т.к. на многих докладах/конференциях отмечается, что реализация многопоточности в го из коробки на “зеленых” тредах, да к тому же еще в 2010 году, является во многом эталонной и не приводит к “раскраске” кода async/await и как следствие хорошо утилизирует ресурсы. В идеале конечно хотелось бы увидеть статью от кого то из крупных маркетплейсов или соц.сетей почему они выбрали го, и мне кажется не в последнюю очередь из за ресурсов, купить 1000 или 1100 серверов, как по мне большая разница в текущих реалиях.

Я не против синтаксического сахара. Я очень даже "за". И мне его в Go не хватает. НО. У него есть цена, и я не уверен, что готов её заплатить в Go

Я же не призываю сделать из go kotlin) Я и сам считаю что kotlin даже в чем то переборщил, вот например в данный момент я переписываю kotlin код за молодыми и дерзкими, где использовано все что только можно из языка и лямбда в лямбде и лямбдой погоняет) И для командной разработки backend если бы я сейчас выбирал язык то остановился бы на java, как нечто среднем. 

Но конструкции типа filter/map/reduce уже настолько прочно вошли в текущую жизнь, и уже так хорошо изучены и отлажены, что даже в java(которую часто ругают за медленное развитие) уже существуют более 10 лет, то странно ждать там подвоха. Тот же underscore помню использовали на фронте еще в 2010, когда в JS еще не завезли этих операций. А го получается вообще как будто голый язык, где грубо говоря нет ничего кроме циклов, условий и структур. Поэтому я и сравнил его с Pascal и го-код мне очень напоминает институтские лабы на Pascal) Я не говорю что надо добавить все, но такие базовые вещи очень напрашиваются. И основная стезя го это всеже не геймдев/железо/операционки где производительность особенно важна.

Go прекрасен по синтаксису! То качество, которое Вы подразумеваете, не находится в категориях хорош/плох

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

Про простоту го, которая обманчива, как выразился мой второй друг. Получается что го очень простой, но простой с точки зрения компилятора, т.к. мало ключевых слов и конструкций по сравнению с другими языками (и по моему тернарного оператора там тоже нет… ), из за этого каждый будет “рисовать так как он видит” и мы увидим больше разнообразие решений, одних и тех же типовых задач - что на мой взгляд не есть хорошо. И когда я вижу типовой код на стримах я сразу улавливаю суть, в то время как с го приходить больше вчитываться в код. Те же исходники kubernetes уже давно стали притчей во языцех.

Хорошо, что в Golang есть библиотеки которые решают данные проблемы.
Но перед тем как постить свой пост, я интереса ради поинтересовался у знакомых гофферов... и ответ был одинаков - у нас так не принято, все пишем руками или создаем утилитные функции.
И убедился что в стандартном golang sdk таких функций нет.
Вообще такую фразу "у нас так в го не принято" я слышал много где) да и видел код реальных проектов Golang на гитхабе, которые пестрят разными утилитными файлами и хелперами, которые как я понимаю кочуют из проекта в проект копипастой и код похож на старый добрый Pascal.

Я конечно могу ошибаться, поправте меня если я не прав, но те примеры которые вы скинули, они создают после каждой операции новый массив, и как я понял такого понятия как стримминг элементов коллекции в go нет, в отличии от скажем c#/java/kotlin, что сильно нагружает GC.

Но я не хочу сказать что go плохой, каждый язык призван для решения своей задачи, как я написал выше сильная сторона go это хорошая утилизация ресурсов, иначе его бы не выбирали скажем крупные маркетплейсы. И в место того чтобы появлялись статьи которые рассказывали про то как мы после перехода на go сэкномили на железе и прочих ресурсов в датацентрах например, регулярно появляются статься как я перешел на go c c#/java/kotlin и пр. и мне нравится набирать "километры" кода и читать их. Извините, но я не могу в это поверить, по синтаксису он не так хорош как языки что я привел выше и на которых я имею опыт.

Выскажу свое мнение про Go...
Для начала скажу что писать на языке в 2025 году, где нет типовых операция типа filter/map/reduce и прочее это очень больно. Возьмем простой пример где у нас есть коллекция юзеров и нам над отфильтровать их например по росту, а потом сгруппировать по нему же. Как это будет выглядеть примерно выглядеть на JS/C#/Java/Kotlin/Rust и пр.:

users.filter { it.height > 100 }.groupBy { it.height }

А как это будет выглядеть на Go?
Я не готов набирать столько текста и тем более читать на экране столько портянок с кастомной фильтрацией и группировкой. По моему это никак не вяжется с вашим первым принципом наглядностью. Где каждый будет реализовывать эти операции по своему, а джуны еще наверняка и сделают типовые ошибки для новичков при группировке, забыв проинициализировать маппу для группировки пустой коллекцией и словят NPE.

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

Но опять же в 2025 году, это уже не является чем то уникальным, в отличии от 2015 года)

Почему вы реализуете quicksort по разному? Если сделать аналогичную реализацию на Java, то все будет примерно также как и на Python

public static List<Integer> quicksort(List<Integer> arr) {
      if (arr.size() <= 1) {
          return arr;
      }
      var pivot = arr.get(arr.size() / 2);
      var left = arr.stream().filter(x -> x < pivot).toList();
      var middle = arr.stream().filter(x -> x.equals(pivot)).toList();
      var right = arr.stream().filter(x -> x > pivot).toList();
      var result = new ArrayList<>(quicksort(left));
      result.addAll(middle);
      result.addAll(quicksort(right));
      return result;
}

  public static void main(String[] args) {
      System.out.println(quicksort(List.of(3, 6, 8, 10, 1, 2, 1)));
  }

Почему для Python вы не делаете обработку ошибок, но делаете ее для Java хотя могли бы просто добавить ошибку в сигнатуру Java метода, что сильно уменьшило объем кода?

И как правильно вам уже указали в комментариях, такой код в продакшен никто не пишет, а для объективнсости надо сравнивать именно продакшен код.

Имея опыт работы на трех языках Java/Kotlin/Python, могу сказать что сильнее всего объем кода сокращает Kotlin, благодаря null safety и оператору elvis (?:), а также богатой библиотеки встроенных функций для работы с коллекциями и для трансформации значений. И работая на Python мне больше всего не хватало того что перечислил выше, особенно elvis.

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

По итогу статья содержит ложные посылы и содержит ссылки на неактуальные материалы, когда еще в Java даже Stream API не было. И несет больше вреда чем пользы, особенно для неокрепших умов, начинающих разработчиков.

Спасибо за статью и доклад на Joker 2024 - было интересно.
Хотел воспользоваться вашей библиотекой для патчинга байт кода, но нашел ее только в вашем репозитории SPYT.
Она доступна в каком либо общедоступном репозитории чтобы ее можно подключить как зависимость в билд тулзе? (Maven/Gradle)
Есть ли какие то готовые примеры по ее использованию помимо доклада?

Вопрос не ко мне, но попробую ответить)
Подобная "кастомизация" это обычная практика чтобы повлияеть на процесс сборки. Собственно для этого maven plugins и extensions и предназначены. И это не вина Maven, а проблема конкретной IDE. Сообсвенно это и побудило меня написать свой плагин. Переезд на Gradle это уж очень радикальное решение. Кстати Gradle IDEA plugin также использует Gradle таск для получения модели, как и я в своем плагине)

Да и для меня лично Maven намного проще и легковеснее и как ни странно работает быстрее для моих проектов. Так синк проекта на 100 модулей занимает 4сек. Тогда как Gradle на скрине выше 4 модуля синхронизировал 2 сек, а мой другой проект, где всего то около 20 модулей, он синхронизирует за 10 сек.

И как это решает проблему синхронизации доступа к данным?

В данной реализации volatile не нужен и в нем нет никакого смысла. Код и так корректно синхронизирован и все изменения переменной происходят под локами.

Интересная проблема. Мавен плагин, отработал как надо и вернул все зависимости что есть. Проблема была в интеграции с IDEA. Т.к. она не зависит от билд тулзов и может работать вообще без них, то надо было настроить определенные "политики" для работы с зависимостями. Я про это не знал, но благодаря вашему issue настроил как в bundled Maven plugin. Мавен возращает для каждого модуля все зависимости полностью с учетом транзитивных, а IDEA по умолчанию "докидывает" зависимости от дочерних модулей - и для мавен это не надо и приводило к jar hell в вашем примере. После фикса ваш пример у меня успешно отработал.

Поправил пока в beta канале https://plugins.jetbrains.com/plugin/22370-easy-maven/versions/beta

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

Здравствуйте. Спасибо за обратную связь. Буду признателен если сможете найти время и завести issue по проблеме с опциональными зависимостями.
Я правильно понимаю, что это связано с параметром <optional> у dependency?

"Может так оказаться", "совсем небезосновательная стратегия", "из теории", "может в другой момент"... все ежели да кабы.
Вы можете мне не поверить, но я сам за мир во всем мире, но к сожалению, не из теории, а из практики я такого, да и не только я, пока не встречал. И как уже писал в самом начале, вся тысячилетняя история челеовечества говорит об этом: покорение Америки европейцами, Индии, Китая - опиумные войны, а теперь и покорение Европы США.

Если весь смысл "прогресса" у вас сводиться к поглощению и порабощению других

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

Давайте для начала добавлю контекста:
Автор говорит, о разрушении образования в РФ, что его превращают в тест(ЕГЭ), в ущерб "инновационной" деятельности мозга, что из за этого люди становятся менее способными к созданию нового. Далее идет приведенный вами фрагмент.
Из которого по моему мнению также, логично следует, что отвечать этому вмешательству в образование извне, проще с более образованными людьми. Но из за разрушения образования, его общий уровень у людей упал. О чем и говорит автор.
Или вас смущает только фраза о человеческом материале? Или вы будете спорить с тем что люди по своим способностям не равны? Т.е. по вашему любой кто захочет как то воспитать людей, автоматически будет записан в "ругаемый запад"? Т.к. в процессе воспитания так или иначе приходится иметь дело с человеческим материалом, т.е. исходными данными. Не вижу тут никаких оскорблений и противоречий.


Давайте теперь представим ситуацию о которой говорите вы:

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

Допустим на какой то территории N, люди решили жить по принципу за все хорошее, против всего плохого, каждый занимается тем что ему по душе, без всякой указки извне. По моему совершенно очевидно и вся тысячелетняя история человечества это доказывает, что найдется другая группа людей M, которые объединены конкретной идеологией (не важно со знаком + или -) и как следствие добились большего прогресса в "инновационной деятельности", и поэтому им не составит труда поглотить группу N и навязать им свой образ мыслей и заставить делать то что нужно доминирующей группе.
Для тех кто выбрал такой путь развития "что "материалу" возможно уже поперек горла стоит эта инновационная деятельность" история придумала и доказала на практике ряд афоризмов: "Если ты выглядишь как еда, то тебя обязательно съедят" и "Удел тех, у кого нет идеологии — пикник на обочине Истории"

Совершенно случайно, никак не связано с данной публикацией, читал на днях статью Ильинского И.М. (на данный момент президент МГУ) "Образование в целях оглупления". Оставлю на всякий случай ссылку тут, может кому то еще будет интеренсо - читать

как только вы хотите ходить в read replic для всех readOnly транзакций то без неё уже никак

Сильное утверждение... что без нее никак. Это лишь деталь вашей реализации роутинга. В обмен на простую реализацию, вы получаете лишний запрос. Но можно сделать свою имплеменатцию на основе ThreadLocal, да так будет больше кода, но перфоманс будет выше. Быстрый поиск показал что люди в целом там и делают (там правда не совсем про это). Да и обычный Spring Transaction также реализован через ThreadLocal, подробнее тут.

Как следует из названия плагина - "Explyt Spring" он добавляет поддержку Spring. В статье про это подробно описано. Разве в community есть поддержка данного фрейморка? можете дать ссылку на плагин который за это отвечает?

Information

Rating
1,272-nd
Location
Рязань, Рязанская обл., Россия
Date of birth
Registered
Activity

Specialization

Specialist
Lead
Java
SQL
Database
Android development