Спят усталые игрушки, книжки спят… А вот Хабр не дремлет. Уже целый год прошёл с прошлого сезона Java. Стал ли за это время язык менее актуальным? Его всё ещё путают с JavaScript? Помогла ли Java 20 поставить новый рекорд длины Hello World? Чтобы ответить на эти и другие вопросы, мы запускаем новый сезон Java.
Программирование — это про целесообразность. Для многих простых задач достаточно подружиться со слонёнком. Однако когда хочешь сотворить настоящее, крупномасштабное чудо вроде национальной платёжной системы, без jar-птицы никак не обойтись — можете поверить опыту НСПК, партнёра этого сезона.
С 31 июля по 19 сентября мы будем говорить о чудесах больших и поменьше, о кровавых ритуалах энтерпрайза и защитных пентаклях тестовых окружений. Лучший кудесник, избранный народным голосованием, получит в награду Apple MacBook Air 13, а его имя навсегда останется на страницах нашей сказки.
Java и энтерпрайз
Наверное, Java на сегодня — самый «энтерпрайзный» из языков программирования. Обычно именно на нём реализуются большие сложные системы с высокими требованиями к надёжности. Многим нравится гибкость Python и простота JavaScript, другие хотят хайповать на Go или писать высоколобый функциональный код на Scala — и всё же кровавый энтерпрайз держится на (или за?) Java. Почему всё обстоит именно так?
Антон Будкевич
глава разработки IT-решений Мир Plat.Form aka @Wanderrer
Вопрос многогранный. Можно выделить несколько ключевых моментов:
1. Высокая производительность Java-платформы в принципе. Если сравнивать с другими распространёнными языками, такими как Python или PHP, — они проигрывают в производительности в десятки-сотни раз.
2. Большое сообщество. Многие вопросы, которые встают перед разработчиком, уже так или иначе в Java-сообществе кто-то решал.
3. Большая экосистема. Есть не только ответы на вопросы, как разработать что-то, но и готовые реализации. Экосистема библиотек, пакетов для реализации бизнес-задач.
4. Кадры. Разработчиков-джавистов объективно больше, чем программистов на других языках. На двух гошников, например, приходится 10 джавистов.
Сергей Петрелевич
ведущий разработчик Мир Plat.Form aka @Petrelevich
Один из ключевых факторов — обратная совместимость. Ни один из популярных языков и платформ не обладает таким свойством. Java появилась в 90-е годы, и до сих пор код, написанный в 90-е годы, функционирует. В банке, где я работал лет 6 назад, была система, написанная на первой версии Java, — и она до сих пор в деле. Причём это крупная система, тысячи серверов по всему миру, за 20 лет разработки над ней успели потрудиться порядка 100 человек со всех континентов.
В других языках бывает, что выходит третья версия — и объявляют, что вторая была сделана по ошибке, и теперь всё будет не так. Для системы, где срок разработки измеряется десятками лет, это была бы катастрофа. А когда есть гарантированная обратная совместимость, можно смело вкладывать сотни миллионов долларов в разработку, и система будет работать годами, столько, сколько надо.
Java и разработчик
Джависты любят делать всё обстоятельно. Говорят, если за столом попросить джависта передать хлеб — он начнёт строить хлебозавод. Врут, конечно, — он просто загрузит его с Maven Central. Пока другие холиварят по поводу того, чей язык лучше, джависты тихо и скромно пилят мегапроекты на своём любимом языке.
Сергей Петрелевич
ведущий разработчик Мир Plat.Form aka @Petrelevich
В Java ничего не устаревает — просто появляются новые инструменты, позволяющие решать новые задачи или старые, но по-другому.
Допустим, раньше все приложения были монолитными. Их масштабирование достигалось за счёт многопоточности и увеличения количества потоков. С появлением «двенадцати факторов» от Heroku и моды на микросервисную архитектуру масштабирование стало делаться не за счёт потоков, а за счёт процессов. Мы запускаем кучу реплик нашего процесса и достигаем тех же целей. Появился Kubernetes, появилась новая идеология, под это подстраивается в том числе и Java. Например, все мы ждём virtual threads в Java 21. Но старые подходы при этом никто не отменял, и у них по-прежнему есть своя область применимости.
Конечно, есть определённая инерционность, запаздывание. Вспомнить хотя бы, когда в других языках появились лямбды и когда они приехали в Java. Но это плата за обратную совместимость, ничего не поделаешь.
Антон Будкевич
глава разработки IT-решений Мир Plat.Form aka @Wanderrer
На любом языке можно решить любую задачу, хоть на Visual Basic. Вопрос не столько в скорости обработки транзакций, сколько в стоимости разработки. В изменчивости бизнес-функциональности. Мы много дорабатываем наши системы, и скорость, надёжность, стоимость этих доработок для нас критичны.
Важен не столько сам язык, сколько его экосистема, инструменты, комьюнити. Больше разработчиков на языке — больше комьюнити — больше мощных инструментов. Например, в Go нет аналога Spring. И, допустим, веб-клиент на Go написать посложнее, потребуется больше кода. Грубо говоря, у нас это одна строчка, а в Go понадобилось бы пять.
Впрочем, джависты сами про себя всё знают. А читателю, возможно, интересно, насколько сложно стать Java-разработчиком в 2023 году.
Александр Ланцов
ведущий разработчик Мир Plat.Form
Сейчас на джуновские позиции очень большой конкурс. Молодые и перспективные специалисты, по большому счёту, все одинаково умные. И конкурировать им приходится через время, которое они готовы потратить на подготовку.
С другой стороны, именно в Java, возможно, это несколько проще, чем в других языках. Java сейчас не такая «модная» среди молодёжи, и за счёт этого порог входа в профессию может быть чуть-чуть пониже.
Владимир Петров
aka @vvpetrov91
Java — как швейцарский нож: на ней можно разрабатывать Android, десктопные приложения, веб, программировать микроконтроллеры и т. п. Однако основная фишка джавы — это универсальность («написал однажды — работает везде») и возможность работы в многопоточной среде. Большая доля рынка джавы — это крупные предприятия, высоконагруженный бизнес-бэкенд, куча интеграций.
Важное качество для wannabe-джависта — усидчивость и стремление к результату в долгосрочной перспективе. Быстренько наклепать сайтик можно на питоне. То же самое можно сделать и на джаве, — работать это скорее всего будет даже лучше, но время, затраченное на разработку, будет больше.
Вторым качеством можно выделить стремление к совершенству. Джава очень многогранна, и код, написанный на ней, можно улучшать бесконечно. Написать простой алгоритм, потом можно переписать его на более низком уровне, потом прикрутить асинхронность и многопоточность — можно даже JVM затюнить.
Java и евангелист
Некоторые люди не просто используют Java, но и хотят обратить в свою веру других. А тех, кто уже обращён, — мотивировать к росту в этой области. Победитель прошлого сезона Java расскажет, почему в 2023 году этот язык особенно хорош (и в каких областях — не очень).
Олег Чирухин
победитель прошлого сезона Java aka @olegchir
У Java поменялся релизный цикл, и теперь новые версии выходят дважды в год. Это позволило выпустить множество новой функциональности, в том числе той, которую ждали годами. Например, в Java 21 у нас появятся Virtal Threads, которые позволят улучшить эффективность использования оборудования. Сегодня Java — это крутой, современный, динамично развивающийся язык, выгодным преимуществом которого является то, что он не оторвался от своих изначальных ценностей: совместимости между версиями, фокусом на производительность и безопасность, использование строго типизированного языка с поддержкой IDE и так далее. Безусловно, далеко не всем системам нужна безопасность или необходимо думать о производительности. Например, у браузерного фронтенда совершенно другие ценности. Но если вы совпадаете по ценностям с Java, то это идеальный выбор.
Есть ряд областей, в которых Java уже нормально можно использовать, но уровень применения не очень большой. Например, инфраструктура для создания умных домов, в том же Eclipse IOT есть много готовых наработок. На Java можно работать с машинным обучением и большими данными: в качестве примера — Apache Spark MLlib, предназначенный для сборки пайплайнов машинного обучения с использованием навыков работы со Spark, которые уже имеются у data-инженеров.
Если говорить о потерянных областях, то это мобильная разработка. На Android стали повсеместно использовать Kotlin. Строго говоря, на Android никогда и не было «настоящей» Java — там всегда был компилятор, который собирал код на Java во что-то своё, что живёт по своим правилам и необязательно регулируется спецификацией языка и виртуальной машины, как в OpenJDK. Но теперь это вообще свой отдельный мир. В какой-то другой параллельной реальности, Android бы перешёл с «не совсем настоящей Java» на «полностью настоящую Java», но в нашей версии мультивселенной этого не случилось. У нас случился Kotlin. Может быть, и к лучшему.
Когда Java только появлялась, была большая ставка на использование в браузере через апплеты. Сейчас же, многие Java-разработчики никогда и не видели никаких апплетов. Современный браузерный фронтенд делается на чем-то с условным названием JavaScript (в реальности это множество технологий — от TypeScript с миллионом фреймворков на клиенте, до Node.js и Deno на бэкенде). Всё это заворачивается в «рамочки» от Electron или его мобильных аналогов и получаются «почти нативные» приложения.
Java-интерфейсы всё ещё используются там, где они жизненно необходимы, где важна максимальная переносимость и сопровождение на протяжении десятилетий — IDE, торговые терминалы и так далее. Swing, SWT, JavaFX никуда не делись и продолжают развиваться в рамках крупных и общественно-важных продуктов. Тем не менее в ближайшие пять лет мы вряд ли увидим Java в роли основной технологии разработки веб-сайтов. Возможно, с развитием Web Assembly что-то изменится, но пока воз и ныне там.
Java и авторы Хабра
Наверное, некоторые читатели уже задумались — о чём бы таком написать на этот сезон, чтобы собрать много лайков и забрать суперприз… Вряд ли это хорошая постановка вопроса. Писать надо о том, что хорошо знаешь, что интересно самому, — тогда выйдет хорошая статья. Зайдёт ли она аудитории лучше, чем все остальные, — на то уже воля случая. Впрочем, некоторыми идеями наши спикеры всё же хотят поделиться.
Антон Будкевич
глава разработки IT-решений Мир Plat.Form aka @Wanderrer
Мне было бы интересно почитать о том, как Java со своими фреймворками взаимодействует с другими компонентами. Kafka, Kubernetes, Cassandra, ClickHouse, PostgreSQL — мне интересно было бы почитать, как всё это работает как единое целое, и как бизнес-логика абстрагирована от инфраструктурных компонентов. Как можно наладить взаимодействие одним импортом правильной библиотеки — или, наоборот, как кто-нибудь написал свой велосипед для работы с Kafka, который лучше, чем что-то.
Правила сезона
Сезон Java будет проходить с 31 июля по 15 сентября.
К участию допускаются статьи, опубликованные с 24 июля в хабе Java, у которых выставлен тег «Сезон Java one love».
Побеждает статья с наивысшим рейтингом. Голосование идёт в течении всего сезона, результаты фиксируются по его завершению.
Допускается несколько статей от одного автора.
Участвовать могут даже авторы из «Песочницы».
Требования к статьям
В сезоне участвуют статьи, посвящённые языку программирования Java, его применению в различных задачах, неочевидным нюансам и подводным граблям.
Приветствуются технохардкорные статьи, основанные на личном опыте и собственной экспертизе. Рерайты, дайджесты и другие вторичные тексты к участию не допускаются.
Статьи должны быть полезны Java-разработчику, помогать ему в решении конкретных задач или давать ему более глубокое понимание фундаментальных особенностей языка. Абстрактно-философские рассуждения в сезоне участвовать не будут.
Реклама и антиреклама запрещены. Уместные упоминания продуктов и брендов допустимы, но если статья целиком посвящена пиару — она не будет допущена к участию в конкурсе.
Автору самой заплюсованной статьи достанется Apple MacBook Air 13, а также грант в 30 000 ₽ на подготовку следующего крутого поста.
Статьи-участники
FizzBuzz и искусство фильтрации
В этой статье мы рассмотрим особенности создания и применения предикатов на примере задач, вдохновленных классической проблемой FizzBuzz. С помощью Java Stream API мы изучим различные методы фильтрации, объединения и инвертирования предикатов для решения четырех простых задач и одной более сложной. Данная статья поможет вам понять, насколько мощными и гибкими могут быть предикаты при работе со Stream API, а также улучшит ваши навыки построения и применения предикатов в программах на Java.
Перестаём бояться генерировать байт-код
Многие, возможно, думают, что работа с байт-кодом Java (будь то чтение или, тем более, генерация) — это какая-то особенная магия, доступная только продвинутым разработчикам с особенно крутым опытом. На самом деле, я считаю такую точку зрения ошибочной. JVM устроена гораздо проще, чем CPU; она оперирует такими высокоуровневыми понятиями как классы, интерфейсы, методы, а не просто лопатит байты в памяти. В отличие от CPU, который легко уронить криво сгенерированным машинным кодом, JVM заботливо отверифицирует любой байт-код и в общем не даст выстрелить в ногу.
Но с чего начать погружение в байт-кодную магию? В сети есть некоторое количество туториалов по этому вопросу. Как мне кажется, они либо показывают слишком простые случаи, от которых непонятно, как перейти к чему-то более интересному, либо очень основательные и требуют вникать в теорию, собирать целиком картину в голове по кусочкам. Я хотел бы попробовать внести свой вклад в эту тему — надеюсь, у меня получится показать, как можно побороть первый страх и написать что-то похожее на реалистичный сценарий без особого вникания в теорию на первом этапе.
Весь приведённый код доступен в моём репозитории.
Создание приложения для распознавания текста с изображений и аудиофайлов
Запись текста с фотографии листа или из аудиозаписи в текстовый файл, доступный для редактирования – довольно часто встречающаяся задача при работе в офисах или учёбы. Для распознавания текстов и аудио в платных сервисах и программах сегодня используются такие подходы, как машинное зрение и распознавание речи с использованием глубоких нейронных сетей.
Детектирование (обнаружение) и классификация символов на изображении осуществляется с использованием различных архитектур свёрточных нейронных сетей. Обработка естественного языка основана на использовании глубоких рекуррентных нейронных сетей, состоящих из ячеек долгой краткосрочной памяти LSTM. При создании соответствующих приложений для работы с текстами, этап реализации нейронных сетей можно пропустить, используя соответствующие свободно распространяемые библиотеки.
В данной статье я хочу поделиться реализацией приложения, позволяющего пользователю преобразовать и сохранить текстовую информацию из изображения листа или аудио-файла.
Высокие технологии или дешевые фокусы с двойным дном
Отлаживал я как-то тесты и параллельно размышлял о null-safety. Звезды сошлись и родилась довольно странная идея - замокать null.
Параллельность в Java на практике
Как следует из названия, здесь будет только про параллельное выполнение (не путать с конкурентностью). Так же я не буду затрагивать проект Loom, который «должен убить» все остальные подходы написания параллельного кода. Надеюсь изложенное ниже позволит начинающим java программистам разобраться с разными подходами и структурировать имеющиеся знания.
Начинающие java программисты, разрабатывая новые сервиса, сталкиваются с задачей выбора технологий, фреймворков и т. д. При написании параллельного кода так же есть множество различных вариантов. Вряд ли кто‑то будет создавать и запускать треды вручную, но можно использовать старый добрый ExecutorService. Можно выбрать Stream API или Reactor с его реализацией параллельной обработки. Есть ещё Akka и куча других экзотических фреймворков. Некоторые из них разработаны под набор конкретных задач, другие же вроде подходят для любых. И как оценить производительность того же Reactor против ExecutorService, или же, например, используя Stream API. Попробуем разобраться.
Динамическое создание слушателей в Kafka
Эта статья обьясняет, как создать слушатель в Kafka на лету в процессе работы приложения. В процессе разработки решение использовался язык программирования Java.
Байки джависта
Привет, Habr! Я конечно не Джеймс Гослинг, но за долгое время работы с Java у меня накопилась масса мыслей. Мысли по написанию кода, о подводных камнях типа Null safety
, советы для любителей усложнять, байки бывалого погромиста про 0-day в Spring, экзистенциальные переживания при работе с мегабайтами легаси, очевидные советы, которые так сложно даются сеньорам — и ещё масса полезных размышлений в связке с примерами кода.
Релиз Jmix 2.0 — новой версии платформы для быстрой разработки бизнес-приложений на Java
Выпуск Jmix 2.0 — важная веха в развитии платформы. В первую очередь мы провели глобальное обновление технологического стека, что гарантирует актуальность в долгосрочной перспективе.
Ускоряем java-рефлексию в 2023
Привет, Хабр. С момента выхода в свет предыдущей статьи прошёл год с хвостиком, и у меня наконец-то дошли руки до написания исправленной версии, учитывающей предыдущие косяки с замером времени вызова и несправедливо забытую тему доступа к полям классов. Ну что же, поехали!
Нагрузочное тестирование API без использования UI
В этой статье поговорим о Нагрузочном тестировании при помощи JMeter-Java-Dsl и реализуем наш первый нагрузочный тест для API с генерацией динамических значений.
Почему WebAssembly плохо годится для Java
Как разработчик TeaVM, компилятора байт-кода JVM в JavaScript и WebAssembly, я часто рекомендую пользователям, почему-то жаждущим сгенерировать WebAssembly, начать с JavaScript. Если честно, бэкэнд WebAssembly я очень давно не развиваю, не реализую в нём недостающих фич и не фикшу баги. Меня спрашивают: а почему так? Обычно, я просто игнорирую подобные вопросы, потому что в двух предложениях ответить на них невозможно, а для того, чтобы писать больше предложений, у меня нет времени. Обычно если я встречаю чьи‑то попытки объяснить, чем WebAssembly плох для реализации JVM (а так же, CLR, JavaScript и прочих динамических сред), то они сводятся к следующему: «Java (.NET, JavaScript, ваш вариант) — это управляемый язык со сборкой мусора и исключениями, так что приходится тащить с собой гигантский рантайм». Что же, на самом деле, ситуация несколько сложнее, а размер рантайма вовсе не такой страшный и не является основным источником бед.
Как скомпилировать Spring Boot приложение в native image с помощью GraalVm и развернуть его с помощью Docker
До недавнего времени мой опыт работы с бекенд-приложениями ограничивался созданием приложения на базе Spring Boot различных версий с использованием реляционных баз данных, ликвибейза, брокеров сообщений и т.д. Приложения в большинстве своем были легковесными, быстро запускались и не требовали большого количества ресурсов. Пока на работе мы с командой не столкнулись с проектом, который мало того, что запускался мучительно долго, так ещё и работал с большим количеством сервисов, постоянно то отдавая, то обрабатывая различные данные. Всё это, конечно же, приводило к медленной работе в продакшене, частым зависанием или вообще поломкой сервиса.
Это стало одной из причин интереса к GraalVm - виртуальной машине, написанной на Java, помогающая делать программы быстрее с помощью JIT компилятора. GraalVm помогает скомпилировать java код в так называемый native image. Это исполняемый файл приложения, который мгновенно запускается без старта JVM.
Эта статья - туториал, как подружить между собой Spring Boot, GraalVm, Liquibase и Docker, какие могут возникнуть подводные камни и как их можно обойти.
Фундаментальное руководство по пакетам в Java
Пакеты в Java появились с самого начала, во времена, когда язык еще назывался Oak. Их описание уже присутствует в его ранних спецификациях. Java-пакеты реализуют так называемое пространство имен (namespace), позволяющее использовать в проекте файлы с одинаковыми именами. Такой подход существует с давних времен во многих языках.
Также с помощью пакетов разработчики структурируют файлы удобным и понятным для себя способом, т. к. чем их больше используется в программе, тем в них сложнее становится ориентироваться. Если они будут размещаться бессистемно, то это рано или поздно приведет к полному запутыванию кодовой базы и дезориентации программистов. И наконец, с помощью пакетов можно ограничивать доступ (из других пакетов) как целиком к классам, так и к их отдельным элементам.
Об этом и многом другом и пойдет речь в данной статье.
Авторизация в Spring Boot приложении с Spring Security 3.1.0 и PostgreSQL
На данный момент являюсь Junior Java разработчиком, поэтому в этой
статье не будет сложной аналитики и глубокого погружения в тему, но я покажу
свой опыт изучения и реализации приложений с использованием Spring
Security. Возможно, кому-то это поможет справиться с теми трудностями, с
которыми встретился я.
Недавно мне пришлось подключать и настраивать авторизацию через Spring Security версии 3.1.0. В процессе разработки и решения сложностей, которых было не мало, я заметил, что информации по версии 3.1.0 довольно мало, если не считать документацию.
Использование Kotlin и WebFlux для выполнения задач ML в Apache Spark на GPU
В предыдущей статье для создания Spark Driver приложения использовался сервлетный стек Spring (Boot 2.7.11) и JDK 8.
На дворе вторая половина 2023 года, у многих в проде уже используется Boot 3+ (а то и 3.1+), совсем скоро должна выйти новая LTS версия Java, и, мягко говоря, Boot 2+ и JDK8 устарели. Использовались они намеренно, так как для задач тренировки моделей машинного обучения на GPU в среде Spark частью системы является ускоритель вычислений на GPU NVidia Rapids. Поддержка JDK 17 появилась только в релизе v23.06.0 от 27.06.23, с ее выходом появилась возможность перейти на актуальную LTS версию Java, а с ней - на Spring Boot 3+.
В данной статье описывается миграция с Boot 2 и JDK 8 До Boot 3 и JDK 17, со Spring Web на Spring WebFlux, в конце сравниваются Web и WebFlux версии по потреблению аппаратных ресурсов и скорости выполнения.
Поднимаем кластер PostgreSQL в Docker и Testcontainers
Ранее я рассказывал о том, как запустить PostgreSQL в Docker. Тогда речь шла об использовании «ванильных» образов Postgres и поднятии одного хоста. В большинстве случаев этого достаточно как для тестов, так и для экспериментов, но нужно понимать, что в промышленной эксплуатации чаще всего используются высокодоступные (отказоустойчивые, кластеризованные) конфигурации PostgreSQL.
Сегодня я покажу, как запустить уже целый кластер PostgreSQL в Docker, а также в тестах через Testcontainers, и как вручную инициировать смену мастер-хоста.
Новый взгляд на Maven-plugin для IDEA — GMaven
Привет, меня зовут Григорий Мясоедов, ранее я имел опыт работы в JetBrains в команде build tools, а конкретно занимался Maven-plugin. В этой статье я хочу поговорить о том как устроен плагин под капотом, его сильных и слабых местах, и о том что я в итоге со всем этим сделал.
Одна из самых частых проблем, которыми я занимался в JetBrains, звучала так - “через командную строку Maven проект собирает, но в IDEA он не импортируется (импортируется с ошибками)”. Как будет показано ниже большинство этих проблем связаны с архитектурой JB Maven плагина.
Исчерпывающее руководство по одномерным массивам в Java
Для хранения данных, используемых при работе программы, применяются переменные того или иного типа. Например, если требуется сохранить имя игрока, то создается переменная String name, если целочисленное значение, то int number и т. д. Когда таких значений немного или их количество заранее известно, то для них приемлемо использовать отдельные переменные. Но что делать, когда в программе задействовано не одно, а 10 чисел, или их количество становится известно только на этапе запуска приложения, когда пользователь вводит его с клавиатуры?
Магия Spring Framework своими руками
Прокси объекты являются основой "магии" Spring Framework. В качестве демонстрации реализована @JmxExporter аннотация, которая позволяет превратить любой Spring Bean в JMX MBean.
Одна из возможных версий переезда с MySQL на PostgreSQL
Всем привет! Меня зовут Станислав, я Java-разработчик в Rocket Science, outsource-компании, специализирующейся преимущественно на финтех-проектах. С 2019 года я веду проект бэкенда для внутренних мобильных приложений (которыми пользуются сотрудники) одного крупного банка. Когда мы начинали проект, у DBA были компетенции только в Oracle и MySQL, а в последние пару лет, наоборот, фокус в организации сместился в сторону PostgreSQL и появилась тенденция по переезду в него разных внутренних сервисов. Нашей команде было вполне комфортно на MySQL, но мы прикинули, что переезд в PostgreSQL позволит нам решить ряд попутных технических вопросов, и ввязались в эту авантюру. В этой статье я расскажу, какие подводные камни ждали нас на этом пути
Разница между загрузкой и инициализацией классов в Java на любопытном примере
Привет, сегодняшняя статья будет о некоторых тонкостях загрузки и инициализации классов и немного о производительности (совсем чуть-чуть и в самом конце). Поводом для написания статьи стал вопрос на StackOverflow. Откройте, но не торопитесь читать ответ ;)