Java guru
4.36K subscribers
1 photo
1 video
1 file
266 links
Новости из мира Java, обзоры интересных библиотек и фреймворков, обучающие статьи. Онлайн обсуждения актуальных тем и обмен опытом. Для связи @RodmanDV
Download Telegram
JetBrains планирует полностью поменять интерфейс IntelliJ IDEA и других своих IDE. Как утверждается в блоге JetBrains, "тренды графического интерфейса эволюционировали, и многие из наших пользователей говорят нам, что текущий интерфейс кажется тяжеловесным и устаревшим". Поэтому в компании было принято решение разработать абсолютно новый look-and-feel, который будет чистым, современным и мощным.

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

В современном языке Java паттерн Посетитель (Visitor) уже не нужен. Он отлично компенсируется использованием запечатанных типов и переключателей, использующих сопоставление с шаблоном – в таком случае те же цели достигаются проще и меньшим объемом кода.

https://habr.com/ru/company/piter/blog/668646/
Сравнение объектов в Java

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

В этой статье еще не затронута тема сравнения Enum. Возможно автор исходит из соображений, что все знают как это работает.

В моей практике меня больше всего поразил код одного джуна. Он повторял как мантру, что все нужно сравнивать через equals и как следствие даже приводил int к Integer для того чтобы сравнивать через equals (((

Статья интересна еще и тем, что там дают обзор по функционалу в разных библиотеках.

https://habr.com/ru/company/otus/blog/670630/
👍1
Вопросы для собеседования на Java Developer

Многие часто сталкиваются либо с задачей подготовки к собеседованиям либо самостоятельно проводят собеседования. Хочу поделиться с вами неплохой подборкой вопросов для собеседования.

Можно и самому пробежаться по ним и освежить знания ))

https://github.com/enhorse/java-interview
Micronaut. Краткое руководство о том, как создавать микросервисы с помощью этого JVM-фреймворка

Работа многих JVM-фреймворков с инверсией управления (IoC frameworks) базируется на применении рефлексии (reflection-based). Это означает, что, для функционирования, таким фреймворкам требуется загружать и кэшировать данные рефлексии для каждого бина (bean) внутри контекста приложения.

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

https://www.tune-it.ru/web/romo/blog/-/blogs/micronaut-microservices-part1
Зачем нужен Thread.UncaughtExceptionHandler?
Ваше приложение выполняется в потоках. При необходимости можно создавать дополнительные потоки. Поток, в котором было выброшено и не обработано исключение, остановится, и распечатает стектрейс в вывод System.err. Если это был последний пользовательский поток, приложение начнет завершение работы.

Для изменения логики обработки непойманных исключений в Java существует функциональный интерфейс Thread.UncaughtExceptionHandler.

Обработчик упущенных исключений может быть установлен (в порядке возрастания приоритета):
• глобально на всё приложение, статическим методом Thread.setDefaultUncaughtExceptionHandler();
• для группы потоков, переопределением метода uncaughtException() в реализации объекта подкласса ThreadGroup (т.к. ThreadGroup сам является наследником UncaughtExceptionHandler);
• для отдельного потока, методом setUncaughtExceptionHandler().

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

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

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

Когда код с исключением выполняет ExecutorService, мы не имеем прямого доступа к объектам потока. Но в этом случае результатом выполнения будет объект типа Future. Такой отложенный объект при попытке прочитать значение перевыбросит полученное исключение, завернув его в ExecutionException. Новое исключение-обертка уже пойдет по обычному пути обработки текущего потока. Исключение как бы перекочует из внутреннего потока пулла во внешний, который использует этот пулл.

Если же пользовательский код не станет дожидаться результатов, исключение будет потеряно, не оставив даже стектрейса в потоке вывода. Для предотвращения такой ситуации стоит снабдить поток обработчиком сразу после создания, определив для сервиса собственную ThreadFactory.

Обычно, если фреймворк скрывает от пользователя детали работы с потоками, он также скрывает и детали работы с исключениями, оставляя свой специальный способ назначить обработчик. И этот специальный обработчик – более специфичный, а значит более правильный подход, чем стандартная глобальная обработка исключений Java. Так, например, в Spring MVC применяется аннотация @ExceptionHandler.
👍1
Организация SFC призвала открытые проекты прекратить использовать GitHub

Правозащитная организация Software Freedom Conservancy (SFC), предоставляющая юридическую защиту свободным проектам и отстаивающая необходимость соблюдения лицензии GPL, объявила о прекращении любого использования платформы для совместной разработки кода GitHub и призвала разработчиков других открытых проектов последовать своему примеру. Организация также запустила инициативу, нацеленную на упрощение миграции проектов с GitHub на более открытые альтернативы, например, CodeBerg (на базе Gitea) и SourceHut, или внедрение на своих серверах собственных сервисов разработки, основанных на открытых платформах, таких как Gitea или GitLab Community Edition.

К созданию инициативы организацию SFC подтолкнуло нежелание GitHub и Microsoft разбираться в этических и юридических тонкостях использование исходных текстов свободного ПО в качестве основы для построения модели машинного обучения в коммерческом сервисе GitHub Copilot. Представители SFC попытались разобраться в том, является ли созданная модель машинного обучения объектом авторских прав и если да, то кому принадлежат эти права и как они соотносятся с правами на код, на основе которого построена модель. Также пока непонятно, может ли считаться производной работой блок кода, сгенерированный в GitHub Copilot и повторяющий код из используемых при построении модели проектов, и может ли рассматриваться включение таких блоков в проприетарное ПО как нарушение копилефт лицензий.

https://sfconservancy.org/blog/2022/jun/30/give-up-github-launch/
Сравнение производительности ввода/вывода: C, C++, Rust, Golang, Java и Python

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

Это сподвигло автора выяснить настоящую стоимость затрат ресурсов, необходимых для “голого” ввода/вывода на различных платформах. Измерение прокси TCP, кажется, дается проще всего. Он включает только обработку входящих и исходящих соединений, а также передачу необработанных байтовых данных.

https://nuancesprog.ru/p/14464/
👍3
AssertJ как способ значительно улучшить код ваших тестов

Недавно я открыл для себя прекрасный инструмент AssertJ. Его API гораздо лаконичнее чем стандартные assert-ы JUnit + Hamcrest. Код тестов читается проще. Он позволяет также тестировать базу.

AssertJ предоставляет абстрактный базовый класс AbstractAssert<>, расширяя который, вы можете добавить поддержку своих собственных типов и методов для проверки. В некоторых случаях это позволяет заметно сократить количество тестового кода и повысить его выразительность. Пример:

assertThat(check)
.hasType(Column.class)
.hasDiagnostic(Diagnostic.COLUMNS_WITHOUT_DESCRIPTION)
.hasHost(PgHostImpl.ofPrimary())
.executing()
.isEmpty();

https://habr.com/ru/post/675778/
https://assertj.github.io/doc/
👍1
Robocode

Достаточно давно я играл в такую старую, но замечательную игру Robocode. Это прям классика. Недавно я опять на нее набрел и хочу с вами ей поделиться.

Суть в том, что вы пишите алгоритм на Java и потом ваша стратегия сражается с другими стратегиями. Прелесть в том, что этот батл визуализируется.

Есть современный аналог от mail_ru и я там даже участвовал. Было прикольно. https://cups.online/ru/contests/?category=ai&utm_campaign=to-allcups&utm_medium=referral&utm_source=raic

https://robocode.sourceforge.io
Как правильно писать сообщения коммитов в GIT, чтобы всем было хорошо

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

https://proglib.io/p/kak-pravilno-pisat-soobshcheniya-kommitov-v-git-chtoby-vsem-bylo-horosho-2022-08-11
Атака на String.hashCode: прообразы и коллизии

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

https://habr.com/ru/post/674816/
Свой Spliterator

Многие из вас активно пользуются Stream API из Java 8, но не всем приходилось создавать свои Spliterator-ы. В статье очень хорошо разбирается процесс написания своего Spliterator-а. Мне особенно понравился пример создания для любой нестандартной коллекции (ещё пример — org.json.JSONArray), которая умеет быстро вернуть длину и элемент по порядковому номеру.

public class XmlStream {
static Stream<Node> of(NodeList list) {
return IntStream.range(0, list.getLength()).mapToObj(list::item);
}
}


https://habr.com/ru/post/256905/
👍2
Выпуск стандартной Си-библиотеки Cosmopolitan 2.0, развиваемой для переносимых исполняемых файлов

Этот пост не про Java. Извините, но я просто не удержался. Для меня она настоящее открытие.

Если вы думали, что только в Java возможна переносимость между разными операционными системами, то вы ошибались. Your build-once run-anywhere c library!!!
https://justine.lol/cosmopolitan/

Опубликован выпуск проекта Cosmopolitan 2.0, развивающего стандартную Си-библиотеку и универсальный формат исполняемых файлов, который можно использовать для распространения программ для разных операционных систем без использования интерпретаторов и виртуальных машин. Получаемый при помощи компиляции в GCC и Clang результат компонуется в статически связываемый универсальный исполняемый файл, который пригоден для запуска в любом дистрибутиве Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD и даже вызова из BIOS. Код проекта распространяется под лицензией ISC (упрощённый вариант MIT/BSD).

Контейнер для формирования универсальных исполняемых файлов основан на совмещении специфичных для разных операционных систем сегментов и заголовков (PE, ELF, MACHO, OPENBSD) в одном файле, комбинируя в нем несколько разных форматов, используемых в Unix, Windows и macOS. Для обеспечения запуска одного исполняемого файла в Windows и Unix-системах применяется трюк, связанный с кодированием файлов Windows PE в виде shell-скрипта, пользуясь тем, что Thompson Shell не использует маркер скриптов "#!". Для создания программ, включающих несколько файлов (компоновки всех ресурсов в один файл), поддерживается формирование исполняемого файла в виде специально оформленного ZIP-архива.

https://github.com/jart/cosmopolitan/releases/tag/2.0
👍5
Статический анализ кода в современной Java-разработке

Многостраничные гайды по оформлению кода, правильных инструментах и библиотеках по факту не работают. Люди в принципе не любят читать документацию. Автор статьи выражается более радикально по поводу таких гайдов ))

Выход из ситуации использовать различные автоматизированные средства валидация. В статье собрана неплохая подборка, которую однозначно стоит попробовать. Подключать ли все сложный вопрос. С одной стороны больше мнений по качеству кода, а с другой стороны замедление (доп. время на проверки). Нужно искать золотую середину. Я думаю, что если на одной чаше качество кода, а на другой скорость, то я скорее отдам большее предпочтение качеству, но возможно не каждый заказчик со мной согласится. Им нужно как всегда быстро и качественно )))
https://habr.com/ru/post/680018/
JUnit расширение DbChange

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

Если вы пишите тесты с использованием JUnit, то стоит обратить внимание на замечательное расширение DbChange. При помощи него вы можете декларативно описать шаги взаимодействия с базой. Мне очень понравился такой подход. Рекомендую попробовать.

https://habr.com/ru/post/684692
👍5
Обобщенное программирование – обзор реализаций

В статье дается довольно занимательное сравнение поддержки обобщенного программирования в C++, Java, C#(.Net). Наилучшего подхода не существует, любой подход – это всегда компромисс, при котором одними преимуществами жертвуют ради других.

https://habr.com/ru/company/piter/blog/656377/
Better Java logging, inspired by Clojure and Rust

Недавно наткнулся на интересную статью про логирование. Там сравниваются подходы к логированию в Clojure, Rust и Java. Самое вкусное в этой статье - это попытка автора реализовать в Java более лучший способ логирования. Он в реализации использует новые фичи из последних версий Java и интересно проследить ход его мысли. Он по шагам добавляет новый функционал.

С практической точки зрения я не во всем согласен с автором. Особого профита от namespace-ов я особо не вижу. В моем представлении реализация получилась достаточно перегруженной и самое главное нет возможности отключить не нужные фичи. Возможно стоит доработать решение. Не нужно забывать еще и про GG. В частности в том же log4j есть режим "garbage free".

Про log4j есть режим "garbage free" - https://logging.apache.org/log4j/2.x/manual/garbagefree.html

https://mccue.dev/pages/9-25-22-better-java-logging
👍1
Shift Left Approach for API Standardization

Как я уже писал в одном из прошлых постов разработчики не любят читать "длинных инструкций" и нужны автоматизированные средства проверки. С разработкой API тоже беда. Вы можете разработать стандарты и взять за основу Microsoft REST API Guidelines https://github.com/Microsoft/api-guidelines или Google API design guide https://cloud.google.com/apis/design/ или посмотреть примеры на API Stylebook http://apistylebook.com/ но чем больше мануал тем меньше вероятность что прочтут до конца и самое главное правильно поймут.

Решение: воспользоваться автоматизацией. Если разговор про OpenAPI, то есть целый класс инструментов линтеров https://nordicapis.com/8-openapi-linters/

В статье приводится пример для Zally. У данного инструмента есть также Gradle plugin. https://github.com/thiyagu06/zally-gradle-plugin

https://www.infoq.com/articles/shift-left-api/
👍1