Библиотека Java разработчика
10.8K subscribers
1.14K photos
563 videos
58 files
1.44K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Download Telegram
Чем отличается Comparator от Comparable?

Интерфейс Comparable определяет естественный порядок среди объектов. Java Collections Framework активно использует этот порядок. По нему упорядочены элементы SortedSet/SortedMap, им упорядочиваются элементы списков и массивов в методе sort().

Порядок определяется единственным методом compareTo. Отрицательный результат означает что текущий объект «меньше» чем переданный параметром, 0 – равен, положительный – больше. Рекомендуется чтобы равные с точки зрения equals объекты всегда были равны с точки зрения compareTo.

С математической точки зрения это должен быть линейный порядок. Он требует выполнения четырех свойств:
1. Антирефлексивность: x.compareTo(x) всегда 0;
2. Антисимметричность: если x.compareTo(y) > 0, то y.compareTo(x) < 0;
3. Транзитивность: если x.compareTo(y) > 0 и y.compareTo(z) > 0, то x.compareTo(z) > 0;
4. Полнота: отношение определено для любых объектов класса (кроме null).


Интерфейс Comparator – это логика Comparable, вынесенная в отдельный объект. Компаратор реализует паттерн Стратегия. Большинство платформенных методов, использующих Comparable имеют перегруженный вариант с не-comparable объектом и внешним компаратором.

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

Кроме основного метода compare(), в компараторе есть набор утилитарных методов для комбинирования и модификации компараторов. Все они возвращают новый компаратор, позволяя сделать его иммутабельным.

#Классы

👉@BookJava
👍3
Почему 90% Java-разработчиков не могут вырасти из джунов долгое время  
Большинство специалистов еще на старте начинают совершать критические ошибки, и даже не замечают этого. 

На бесплатном вебинаре 9 августа разберем основные 7 ошибок, которые встречаются на пути к карьере backend java разработчика с основателем международной IT-компании.

А также узнаем:
✔️ Почему backend-разработчики являются наиболее востребованными;
✔️ Вилки зарплат у java-разработчиков на российском и зарубежном рынках;
✔️ Как освоить профессию максимально быстро и избежать примитивных ошибок; 

Участники вебинара получат бонус 🎁

Регистрация доступна по ссылке: https://clck.ru/sVjuW
👍1
Сколько необходимо дополнительной памяти при вызове ArrayList.add()?

Если в массиве достаточно места для размещения нового элемента, то дополнительной памяти не требуется. Иначе происходит создание нового массива размером в 1,5 раза превышающим существующий (это верно для JDK выше 1.7, в более ранних версиях размер увеличения иной).

👉@BookJava
👍8
Thymeleaf + Spring WebFlux + Spring Security

Thymeleaf появился довольно давно, как минимум 10 лет назад, но он до сих пор весьма популярен и активно поддерживается. Шаблоны Thymeleaf удобны тем, что при простом открытии в браузере они выглядят как обычные HTML-страницы и их можно использовать как статический прототип приложения.

В этой статье рассмотрим, как создать простое приложение Spring WebFlux с Thymeleaf, аутентификацией Okta OIDC, защитой от CSRF-атак и контролем полномочий.

👉@BookJava
👍5
Как Java выбирает перегруженный метод? (1/2)

Метод может быть перегружен различными параметрами – в классе могут существовать несколько разных методов с одинаковым названием. При вызове такого метода выбор конкретного варианта происходит на этапе компиляции (раннее связывание). В деталях алгоритм выбора перегруженного метода описан в спецификации.

Выбор происходит в два шага. На первом выбирается одна из трех фаз – множество подходящих методов.

1. Методы, в которые переданные параметры подходят по типу либо как есть, либо с применением расширения (upcasting) примитивов или ссылочных типов, исключая vararg-параметры.

2. Если в фазе 1 подходящих методов не нашлось, к ее условиям добавляются возможность боксинга/анбоксинга параметров. Обратите внимание, в комбинации работает только боксинг+расширение, но не наоборот.

3. Если и для фазы 2 нет удовлетворительных сигнатур, к условиям поиска подключаются vararg-параметры.

В случае, когда ни один метод не нашелся ни в одной фазе, компиляция завершается ошибкой.

Когда в фазе имеется несколько подходящих методов, используется наиболее специфичный среди них (но только в рамках данной фазы!).

Метод A считается более специфичным чем B, когда типы параметров одного метода – подтипы типов параметров другого. То есть любые возможные значения аргументов A подошли бы и для B, но не наоборот.

В условии специфичности говорится о типах параметров метода, а не о типах передаваемых значений. Так что боксинг/анбоксинг не учитывается, и метод с параметром int не считается более специфичным, чем с параметром Object (в отличие от Integer). Хотя, целое число можно передавать и как Object, и как Integer. Подробное объяснение.

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

#Язык

👉@BookJava
👍5
Бесплатный онлайн-митап для Java-разработчиков от IT_One при поддержке JUG Ru Group.

IT_One Java Meetup — 18 августа, 18:00, онлайн

Доклады в программе:
✔️Роман Тищенко — «Гайд: что нужно начинающему Java-разработчику»
Из этого доклада вы узнаете об основных технологиях при разработке ПО и путях развития начинающего специалиста.
✔️Андрей Дудин, Константин Харитонов — «OPENTRACING: как перестать искать иголку в стоге сена»
Сотни микросервисов оставляют миллионы строк логов, а среди них нужно найти лишь одну. Спикеры расскажут, как OpenTracing может решить эту проблему. В конце доклада вас ждет бонус — лайфхаки, которые помогут сэкономить нервы и время при расследовании инцидентов.

Вы также сможете поучаствовать в дискуссиях и задать вопросы спикерам.
Автор лучшего вопроса получит крутую толстовку 🎁

Участие бесплатное, нужно только зарегистрироваться: https://bit.ly/3JNPHL6
👍3
Подборка каналов для IT специалистов 🎯

https://t.me/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/React_lib Подборки по React js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
https://t.me/frontend_sovet Frontend советы, примеры и практика!


Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++

Программирование Python 📌
https://t.me/pythonofff Python академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus

Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus

GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub

CodePen 📌
https://t.me/codepen_1 Сообщество пользователей CodePen

Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных

Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка

Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков

Разработка игр 📌
https://t.me/game_devv Все о разработке игр

Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT

Чат программистов📌
https://t.me/developers_ru

Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов

БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning

Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию

QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика

Шутки программистов 📌
https://t.me/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности

Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
https://t.me/arhitekturamira World Architecture

Системное администрирование 📌
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux

Английский 📌
https://t.me/UchuEnglish Английский с нуля

Математика 📌
https://t.me/Pomatematike Канал по математике

Арбитраж трафика 📌
https://t.me/partnerochkin CPA и арбитраж трафика

Крипта 📌
https://t.me/bitkoinoff Новости криптовалют

Метавселенная, GameFi, Crypto 📌
https://t.me/metaverse360

DeepFake 📌
https://t.me/deepfakenow Публикуем deepfake видео

Мир технологий 📌
https://t.me/mir_teh Видео из мира технологий

Excel лайфхак📌
https://t.me/Excel_lifehack
👍1💩1
Атака на String.hashCode: прообразы и коллизии

Как-то раз мне понадобилось несколько наборов строк с коллизией по хеш-коду. То есть таких, чтобы значение String::hashCode() совпадало для всех строк в наборе.

Блуждание по интернету не дало результатов, примеров было мало и все они довольно однообразны. Поиск по словарям подарил забавную пару "javascript's".hashCode() == "monocle".hashCode(), но практической пользы не принёс. Полный перебор не рассматривался в виду скорой тепловой смерти вселенной.

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

👉@BookJava
👍1😁1
Для чего используются аннотации?

Удобно рассмотреть случаи применения аннотаций с точки зрения возможных значений их свойства RetentionPolicy:

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

Первая – аннотации для программиста, а не для программы. Это всевозможные маркеры. Они добавляют аннотируемым элементам некоторую специальную семантику. Более формализованный вариант документации. Примеры – @Immutable и @ThreadSafe из Hibernate.

Вторая категория – инструкции для инструментов разработки. Примеры этой категории, @SuppressWarnings и @Override могут влиять на предупреждения и ошибки компиляции. IntelliJ IDEA умеет понимать @Nullable и @NonNull из Spring Framework, и предупреждать о возможных NullPointerException.

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

RUNTIME – самое ходовое значение. Цель снабжается метаинформацией, доступной во время выполнения программы. Сама по себе аннотация всё так же не добавляет нового поведения. Для практической пользы runtime-аннотации в программе должен быть исполнен некоторый код процессинга, который прочитает метаинформацию инструментами Reflection API. Такой механизм широко используется во множестве популярных фреймворков: Spring, Hibernate, Jackson.

#Язык #Аннотации

👉@BookJava
👍6
Большой гайд. Пишем микросервисы на Java и Spring Boot, заворачиваем в Docker, запускаем на EKS, мониторим на Grafana

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

К какой из двух категорий относится эта статья — решать вам.

В этой статье вы увидите пошаговое создание cloud-native микросервиса на Amazon AWS, пригодное для "чтения с листа". Чтобы понять, что здесь происходит, не нужно разворачивать проект - достаточно обладать живым воображением и прочитать текст по диагонали. Если же вы всё-таки захотите повторить шаги, вам будут жизненно нужны знания вида, как создавать классы в IDE и что такое Spring.

👉@BookJava
👍101
Как сделать хеширование паролей в Java-приложениях правильным способом!

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

👉@BookJava
👍3
⬆️ На курсе «Профессия Архитектор ПО» вы вырастете как разработчик и повысите свой доход. Разберёте реальные кейсы от ведущих разработчиков «Альфа-Банка» и сможете проектировать масштабируемые и отказоустойчивые приложения.

За 5 месяцев вы научитесь:

применять архитектурные стили и паттерны проектирования — API Gateway, CQRS и «Сага»;
выявлять и проверять нефункциональные требования и характеристики систем;
строить распределённые системы на основе микросервисов и создавать cloud-native-приложения;
принимать архитектурные решения исходя из контекста;
учитывать вопросы кибербезопасности при проектировании.

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

Спешите приобрести курс со скидкой!

🔥 Также для IT-специалистов действуют специальные плюшки от государства!
Узнать больше: https://clc.to/lUFx_g
Можно ли наследовать аннотацию?

Можно понять этот вопрос по-разному. Если имеется в виду, передается ли аннотация класса-родителя классу-наследнику, ответ – по умолчанию нет. Но наследование можно включить, если на объявлении аннотации поставить мета-аннотацию @Inherited. Это работает только для классов, переопределенные методы нужно аннотировать заново.

Другой возможный смысл вопроса – наследование самих типов-аннотаций. Аннотация, как класс или интерфейс представляется в системе ссылочным типом, она тоже компилируется в .class-файл. Вы можете создать переменную с типом, скажем, java.lang.Override.

Но в отличие от других ссылочных типов, объявление аннотации (@interface) не может иметь секций extends или implements. Это ограничение добавлено просто чтобы не усложнять систему типов. В скомпилированном коде все типы-аннотации – это интерфейсы, унаследованные от Annotation.

#Классы #Аннотации

👉@BookJava
👍2
Почему важен graceful shutdown в облачной среде (на примере Kubernetes + Spring Boot)

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

👉@BookJava
👍5
Можно ли добавить одному элементу несколько одинаковых аннотаций?

По умолчанию нельзя. До Java 8 нужно было создавать дополнительную аннотацию-контейнер, в ней в виде проперти объявлять массив интересующих аннотаций. При применении набор аннотаций нужно было оборачивать в этот контейнер (см. на картинке).

Начиная с Java 8 в стандартную библиотеку добавлена мета-аннотация @Repeatable.
Механизм ее действия такой же, как раньше: помечая ей интересующую аннотацию, необходимо указать параметром @Repeatable аннотацию-контейнер. Нововведение заключается в синтаксисе использования: теперь набор аннотаций оборачивается в контейнер неявно.

Со стороны Reflection при чтении мета-информации тоже появилась возможность не оперировать контейнером явно – метод getAnnotationsByType при необходимости найдет и развернет этот контейнер.

#Аннотации

👉@BookJava
👍4