Pull to refresh

Comments 45

Извинте, я тут из мира .NET мимо проходил.
Я Redis не только как кэш использую, но и как хранилище фоновых задач. Ну я читал, что его можно задействовать как Message Queue https://dev.to/lazypro/message-queue-in-redis-38dm.
Наблюдаю с интересом за Kotlin. Смущает то, что он всё же в экосистеме Java, которая постепенно будет сходить на нет на андроиде. Да жалуются, что Java отстает в развитии от других языков. Как вам Kotlin, насколько удобна на нём разработка?

Redis как кэш - само собой.

Вы вероятно невнимательно прочитали, в статье для транспорта сообщений я писал про rabbitMQ, это совсем другая вещь :)
https://www.rabbitmq.com/

Ключевое слово "можно". Это не отменаяет использования rabbitMQ.

Что касается сравнения Kotlin и Java для бэкенд разработки. Если коротко, то могу сказать, что java живее всех живых и от нее никто не отказывается и врядли откажется в ближайшее время. Новые версии добавляют фичи, которые делают написание кода более приятным.


Kotlin для бэкенда сильно более приятен, это факт

Если будет интересно мое чуть более развернутое мнение, то вот моя статья на эту тему: https://tproger.ru/articles/sravnenie-kotlin-i-java-pri-napisanija-backend-prilozhenij/


Бонусом вопрос - насколько я изучал, в .NET мире довольно приятно выглядит синтаксис и работа с библиотеками. Насколько это приятно и удобно на самом деле?

Максимально удобно и приятно.

Одной командой/кнопкой добавляется nuget пакет и все.
Rider/Resharper все зависимости (в случае, если в соседнем проекте в том же решении есть нужная либа) и директивы using подтягивает по одному нажатию хоткея.
Если либы нет в nuget, то парой кликов добавляется ссылка на dll.

Как тот кто пришел в жаву после дотнетов, могу сказать что намного приятнее. Во первых система сборки понятная и единая, пакеты тоже максимально понятны. Ну и язык конечно намного более богатый и развитый. Жава жива, да, но скорее вопреки чем благодаря. Фактически это тот же кобол - язык не лучший, но решения поддерживать же кому-то надо. Вот и раздули персонал, а теперь раз персонал у нас умеет только в жаву, будем и новые проекты пилить на этом недоязыке. А персонал он нового ничего не любит и даже противится, вот и останемся на жаве.
Тут вот еще JPA упоминается - так вот ормка в дотнете тоже намного лучше и приятнее. Элементарно сортировка будет `.OrderBy(x -> x.Field)`, а не по рандомной строке как в жаве `Sort.by(ASC, "Field")`.

История из личного опыта... Устраивался на работу в крупный банк и одним из вопросов было "что нового появилось в 8-й версии". Более-менее ответил, т.к. уже давно 11+ использовал, ждал выхода 17-й, поэтому многие возможности языка воспринимал как само собой разумеющиеся. И лишь в первый день работы понял истинный смысл: половина сервисов на 1.7 и переводит выше никто не собирается - "работает? не трогаем."

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

Прилично много энтерпрайз кода на 5 версии еще работает. Кодовую базу в пару десятков миллионов строк перевести одним махом не просто. Плюс, надо понимать, что может потребоваться сначала например с 5й мигрироваться на 7ю (ну может на 8ю) и только потом дальше. Энтерпрайз неохотно подписывается на самые свежие версии.

Как профит, недавняя история с log4j обошла стороной тех, кто на старых версиях 1.х.х сидел.

Это собственно то за что Enterprise ценит Java и не откажется от нее никогда.

Вот свежий личный опыт:
огромная система из 10-ков приложений которая пишется и поддерживается 15+ лет.
Полный набор (все на Java): консольные утилиты, десктоп приложения(огромного размера), JEE в изобилии, Web интерфесы и даже кое что на Spring(версия 3 :) )
Используется огромное количество внешних библиотек(сотни. буквально), некоторые из которых уже не поддерживаются и не развиваются лет 10.

Cамые старые куски кода, определенно, писаны еще до Java 5.

Все это работало на Java 7 и сервера: Power и AIX O_o

Переписать это всё с нуля, в соответствии с модными трендами - просто не реально: работа на годы для не маленькой команды. Оценить объем работ невозможно.

Однако, за 4 месяца(причем половина времени потрачено на тестирование) все это мигрировали на Java 11, Intel + RedHat и новый Application server. Силами 2-х людей.

Менять код почти не пришлось(было несколько случаев связанных с необходимостью обновить некоторые библиотеки, там где выбора другого не было)

И все работает.

Я честно сам не очень верил в успех, особенно в отношении десктоп приложений(в коде AД и пепел), но... работает.

Проделывал аналогичное на проекте корнями уходящим в 2003 год, с 1,4 версии на 6-ю, потом на 7-ю версию. А уже на 8-ю переехали практически сразу. Работоспособность полная. Рефакторинг можно делать не торопясь.

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

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

По поводу kotlin для бекенда. Как вы его используете для jpa сущностей? Я лично устал страдать от того что не удается все not null поля объявлять not nullable в классе сущностей.

Да, котлин для jpa сущностей это полное несоответствие реализации jpa и логики котлина. Мы используем jdbcTemplate с самописными конверторами и аннотациями для маппинга в sql и обратно. На каждый чих приходится писать sql, зато все максимально прозрачно.

А для пет проектов да, забавляюсь с nullable полями со значениями по умолчанию. Пока не нашел чего-то проще и лучше

Kotlin для бекенда идея крайне спорная и я бы сказал умирающая.

Лично сталкивался с тремя проектами за последние годы. Все успешно справились. Но. Два из трех прожект менеджеров сказали мне в кулуарах: больше никогда.

Проблема собственно конечно не в языке. А в экосистеме вокруг.

И учитывая что разрыв между Java и Кotlin сокращается все больше... (Java таки уже умеет в lambda, и в текстовые блоки :), да и Loom уже не за горами) то и смысла все меньше.

IMHO: если бы не Google был бы Kotlin примерно там же где Groovy. При всех, бесспорных, достоинствах.

Kotlin для бекенда идея крайне спорная и я бы сказал умирающая.

Глупость какая-то.

Два из трех прожект менеджеров сказали мне в кулуарах: больше никогда.

Я могу найти людей, которые и про джаву скажут то же самое, и вообще про любой другой язык. Проблема или в ПМах, или в команде, или в подходах, редко в инструментах. :)

Хотя я не знаю, насколько некомпетентен или архаичен должен быть джавист, чтобы через неделю не мочь выдать на котлине продакшн-реди код.

Проблема собственно конечно не в языке. А в экосистеме вокруг.

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

разрыв между Java и Кotlin сокращается все больше

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

java таки уже умеет в lambda

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

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

Это, конечно, мой субъективный опыт. Но чтобы вы понимали бэкграунд: я работаю на очень большой, европейской, галере: тысячи разработчиков и сотни проектов во всех сферах бизнеса.
Я сталкиваюсь прямо или косвенно со множеством проектов каждый год и я не вижу Kotlin в бэке практически совсем. Андроид разработка - да. там оно уже доминирует (хотя и на Java там проекты есть до сих пор, и не сказать что это редкость)

А бэкенд это Java и C# в подавляющем большинстве случаев.
Причем, по моим ощущениям, именно С# потихоньку откусывает у Java. Но не Kotlin.

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

Ну, одна галера, ну, бывает. Я в галере с тысячами разработчиков тоже работал. :)

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

Причем, по моим ощущениям, именно С# потихоньку откусывает у Java

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

Работаю на "галерах" почти во всех государственных компаниях Норвегии... Везде последние 2 года основными проектами является переезд с java/.netь на kotlin...

также существует реализация ORM работы с бд - Spring Data JPA. Она работает быстрее, конфигурируется удобнее, чем hibernate

Какая ересь. Spring Data JPA - это ни что иное, как обёртка над JPA-провайдером, коим является Hibernate, т.е. она тупо не будет работать без настроенных Hibernate/EclipseLink/OpenJPA.

Согласен, можно сформулировать иначе. Более правильно будет сказать, что Spring Data JPA - следующий уровень абстракции над hibernate и более удобная в конфигурации обертка.

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

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

Если коротко, то dependency injection это про то, что вы написали отдельный кирпичик кода - класс и используете его в тех местах, где требуется логика этого кирпичика вместо написания новой. 

Такое описание DI вызвало некоторую боль, если честно.

Также мы не забыли, что стандартом индустрии является Spring Boot, для него также существует реализация ORM работы с бд - Spring Data JPA. Она работает быстрее, конфигурируется удобнее, чем hibernate и даже позволяет писать запросы без sql вообще. 

Spring Data JPA - всего лишь обёртка (плюс пачка адаптеров) над непосредственно библиотеками/фреймворками для работы с БД, и чаще всего под капотом у неё - да, вы угадали, Hibernate. Расскажете, как обёртка над Hibernate будет работать быстрее, чем Hibernate? :)

Ну то есть как перечисление терминов с их неглубоким объяснением + чеклист полезных для ознакомления инструментов статья работает сносно, а как что-то большее её рассматривать - вредно.

Скажите, а если мне не нравится Hibernate, люблю простой JDBC, что тогда делать?

Для этого есть весьма гибкий JdbcTemplate, который интегрирован со спринговым менеджером транзакций.

Ну и JPA тоже прекрасно поддерживает нативный SQL и хранимые процедуры, и можно поекрасно обойтись без ORM.

За первый абзац - плюс, а вот второй - очередная ересь. Для чего заморачиваться с настройкой JPA, чтобы потом пользоваться исключительно нативными запросами? Чтобы что?

JdbcTemplate - хорошее решение, если спринг всё равно используется.

Хотя нет ничего сложного в том, чтобы написать простейший UnitOfWork на 2 метода (один просто что-то делает, второй - возвращает какой-то результат), принимающих лямбды с полезной работой. В них реализовать работу с транзакцией. И пользоваться им, работая с jdbc напрямую. Через некоторое время это всё выльется в какое-то подобие JdbcTemplate-а, но попроще, сугубо под решаемые задачи.

В простых приложениях на Spring Boot типа микросервисов, с единственным дата-сорсом и одним менеджером транзакций, модуль "Spring Data JPA" фактически не требует вообще никакой настройки. В более сложных случаях это тоже делается довольно просто, всего-то несколько бинов объявить в конфиге и добавить квалифаеры для контроля транзакций.

Да, JPA/Hibernate при неумелом обращении может принести много вреда. Я неоднократно видел проекты которые буквально загибались под нагрузкой из-за этого. Причём, как правило, проблема была в том что тимлид говорил "а вдруг придётся переходить на другую СУБД?", и потому отказывался от native SQL.

Но если понимать что происходит под капотом, то есть и плюсы. Лично я сторонник строгих нативных запросов (и никакого JPQL) с чётко предсказуемыми эффективными планами и индексами, а также функций/процедур СУБД в чуть более сложных случаях, или если размер запроса превышает некоторый порог. Потому что негоже мешать в кучу SQL и Java. К тому же как DBA я всегда могу оптимизнуть соранённый запрос прямо внутри СУБД без редеплоя апликухи и лишней бюрократии.

Но для простейших вещей типа findByName() или existsByProductId() можно спокойно положиться на способность JpaRepository генерировать код автоматически по названию метода в интерфейсе. Это позволяет избавиться от бойлерплейта и это здорово. Ещё мне нравится объявлять отдельные @Repository для разных классов объектов, тем самым чётко разделяя их по зонам ответственности.

Если же вам совершенно ненавистен Hibernate (понимаю!) то есть "Spring Data JDBC". Это очень крутая штука, если вы ещё не успели познакомиться. Это почти такие же CrudRepository как в JPA только очень лёгкие, на чистом JDBC, но правда с небольшими ограничениями. Разработка команды Спринга. И там точно так же можно декларативно объявлять простые методы без написания кода.

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

Все так. Интересно посмотреть, как одними только средствами jpa будут доставать записи по внутренним полям jsonb

С точки зрения JDBC (а всё в конечном счёте сводится к нему), тип jsonb мапируется на java.sql.Types.OTHER и прилетает на клиента как строка. Вы можете либо получить эту строку целиком и превратить в Java объект самостоятельно, либо выбрать нужные атрибуты в native SQL запросе и вернуть их в отдельных полях кортежа. Решайте сами что вам удобнее в вашем конуретном случае.

Для первого варианта в JPA есть поддержка кастомных типов данных. Можете сами имплементировать интерфейс org.hibernate.usertype.UserType. Есть готовая библиотека от Vlad Mihalcea которая поддерживает всевозможные типы. Вот тут почитайте к примеру: https://vladmihalcea.com/how-to-map-json-objects-using-generic-hibernate-types/

Кстати таким же образом происходит мапирование enum типов Postgres и Java.

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

Это точно! Плюсую.

Но всё таки использование одинаковых enum типов в Java и в Postgres это супер фича, которая повышает чисту и безопасность кода, и уберегает от ошибок.

Нет в этом ничего плохого, без хибера, по моему скромному мнению, вообще живётся лучше, чем с ним. Но то, конечно, мнение. :)

Я бы предложил ещё посмотреть на такие инструменты, как querydsl, jooq, jdbi - авось приглянутся.

Ну автор же предложил прямо в статье JdbcTemplate

Я тоже не люблю ORM в любых проявления и, поверьте, таких как я МНОГО. Поэтому есть как минимум две популярных и активных альтернативы: http://jdbi.org и https://www.jooq.org. Посмотрите. Попробуйте. И то и другое прекрасно применимо в проектах любых размеров, кто бы чтобы там не говорил.

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

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

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

Суть статического анализа кода - в проверке кода без его исполнения. По определению. Что является предметом проверки - вопрос вторичный. У вас перечислены одни линтеры, но есть еще направление SAST, представленное продуктами вроде Checkmarx, Solar AppScreener, Fortify

Я за последние 5 лет работал в 3х разных крупных компаниях (2 из них топ банки), и даже в них не встречал широкого использования SAST.

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

Процессы до этого не успевали дорасти. Сейчас уже активно используется в одном из топ.

MongoDB (очень удобная для стартовой разработки ввиду нереляционности

Тут что-то смешалось теплое с мягким, не?

Эта статья будет особенно интересна для тех, кто собирается входить в "IT" - чтобы они примерно представили себе, чем придется заниматься на первой работе.

Не "особенно", а "исключительно", остальным тут хватать нечего.

Как большинство Java проектов выглядят изнутри

Разница между статьей и реальностью примерно как между школьным описанием размножения и тяжелой порнухой.

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

Корпоративные репы... Как это знакомо...

хорошая статья, только про секьюрность и spring ws ничего не написал - это огромный пласт иных задач в современной java

Добавлю от себя что мне понравилось для работы с БД - так это MyBatis, очень здорово sql запросы мапить через xml конфигурацию.

Sign up to leave a comment.

Articles