10986
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP
Что происходит внутри HashMap.put()?
1. Вычисляется хэш ключа. Если ключ null, хэш считается равным 0. Чтобы достичь лучшего распределения, результат вызова hashCode() «перемешивается»: его старшие биты XOR-ятся на младшие.
2. Значения внутри хэш-таблицы хранятся в специальных структурах данных – нодах, в массиве. Из хэша высчитывается номер бакета – индекс для значения в этом массиве. Полученный хэш обрезается по текущей длине массива. Длина – всегда степень двойки, так что для скорости используется битовая операция &.
3. В бакете ищется нода. В ячейке массива лежит не просто одна нода, а связка всех нод, которые туда попали. Исполнение проходит по этой связке (цепочке или дереву), и ищет ноду с таким же ключом. Ключ сравнивается с имеющимися сначала на ==, затем на equals.
4. Если нода найдена – её значение просто заменяется новым. Работа метода на этом завершается.
5. Если ноды с таким же ключом в бакете пока нет – добавляемая пара ключ-значение запаковывается в новый объект типа Node, и прикрепляется к структуре существующих нод бакета. Ноды составляют структуру за счет того, что в ноде хранится ссылка на следующий элемент (для дерева – следующие элементы). Кроме самой пары и ссылок, чтобы потом не считать заново, записывается и хэш ключа.
6. В случае, когда структурой была цепочка а не дерево, и длина цепочки превысила 7 элементов – происходит процедура treeification – превращение списка в самобалансирующееся дерево. В случае коллизии это ускоряет доступ к элементам на чтение с O(n) до O(log(n)). У comparable-ключей для балансировки используется их естественный порядок. Другие ключи балансируются по порядку имен их классов и значениям identityHashCode-ов. Для маленьких хэш-таблиц (< 64 бакетов) «одеревенение» заменяется увеличением (см. п.8).
7. Если новая нода попала в пустую ячейку, заняла новый бакет – увеличивается счетчик структурных модификаций. Изменение этого счетчика сообщит всем итераторам контейнера, что при следующем обращении они должны выбросить ConcurrentModificationException.
8. Когда количество занятых бакетов массива превысило пороговое (capacity * load factor), внутренний массив увеличивается вдвое, а для всего содержимого выполняется рехэш – все имеющиеся ноды перераспределяются по бакетам по тем же правилам, но уже с учетом нового размера.
👉@BookJava
👩💻 Как изменилась Java и зачем разработчику Stream API?
Узнайте на открытом практическом уроке от OTUS, где вы:
— увидите, как создаются программы на Java с использованием Stream API;
— разберетесь, как легко перевести ваш старый код на Stream API;
— сможете попробовать создать похожие приложения и даже улучшить их.
Спикер Роман Вороновский — опытный разработчик и ментор.
Встречаемся 5 июня в 20:00 мск в рамках курса «Специализация Java-разработчик». Все участники вебинара получат специальную цену на обучение!
➡️ Регистрируйтесь прямо сейчас, чтобы не пропустить бесплатный урок: https://vk.cc/cxgDAKРеклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🚀Java с JMH для бенчмаркинга 🚀
Создайте класс бенчмарка для измерения производительности конкретного кода. 🔥
https://github.com/openjdk/jmh
👉@BookJava
Что такое функциональный интерфейс?
Так называется специальная разновидность интерфейса, который определяет тип-функцию, коллбэк.
Чтобы компилятор считал интерфейс функциональным, этот интерфейс должен добавлять единственный абстрактный метод. Вдобавок он может содержать любое количество дефолтных методов с телом. Переобъявление методов класса Object также игнорируется.
Никаких других ограничений на метод не накладывается: он не ограничен в типах аргументов и возвращаемого значения, может иметь любое название и список выбрасываемых исключений (checked и unchecked).
Даже при выполнении всех этих условий, никакие другие разновидности типов кроме interface не могут считаться функциональными интерфейсами.
Дополнительно функциональный интерфейс принято помечать аннотацией @FunctionalInterface. Наличие этой аннотации не необходимо, но оно даёт дополнительную валидацию: её присутствие на нефункциональном типе спровоцирует ошибку компиляции.
Типичные примеры функциональных интерфейсов: Callable, Supplier, Comparable.
👉@BookJava
Углубленному изучению Java – быть!🤝✨
По многочисленным просьбам мы все-таки запускаем новый поток курса «Углубленное изучение языка Java»!
Курс отличается тем, что рассказывает не только как писать код, используя популярные среды, как IDEA, а позволяет узнать, как именно устроен язык. Вы сможете эффективнее использовать ядро и тонкости языка.
Это авторский курс от Дмитрия Когана, который позволяет подготовиться к сертификации Oracle.
Автор курса прошел сертификацию Oracle, и на основе своего опыта, сделал курс, который позволит вам подготовиться к сертификации без штудирования огромной разрозненной литературы.
На курсе мы будем решать практические задачи, которые будут на экзамене.
📢 Стартуем уже 31 мая!
Оставляйте заявку и присоединяйтесь, пока не началось самое интересное и сложное!👉🏻 https://vk.cc/cx5uvn
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Совет
Если вы хотите узнать, когда произойдет совпадение заданного выражения cron, вы можете использовать класс Spring CronExpression.
Он принимает выражение cron expr и с помощью метода next() определяет следующее совпадение после заданного момента времени.
👉@BookJava
Внутри JVM: Массивы и их отличие от других объектов
Массивы являются уникальными объектами в JVM, и понимание их структуры позволяет лучше писать код.
Самый простой способ классификации элементов данных Java - это разделение их на примитивы и объекты. К примитивам, как известно большинству разработчиков Java, относятся булевы числа, байты, символы, варианты целых чисел (short, int и long), а также варианты чисел с плавающей точкой (floats и doubles). Внутри JVM эти примитивы инстанцируются в "сыром" виде. Объявление int создает для JVM 32-разрядное знаковое целое поле, с которым она может работать. Чаще всего эти примитивы создаются в стеке операндов, который строится при каждом вызове метода. (Заметным исключением являются статические примитивы, которые создаются в куче).
https://blogs.oracle.com/javamagazine/post/java-array-objects
👉@BookJava
👩💻 Хотите стать Java-разработчиком, но думайте, что изучение основ программирования — это скучно?
Только не в нашем формате!
Ждём вас на открытом практическом уроке от OTUS, где мы:
- установим все, что необходимо для программирования на языке Java;
- изучим несколько базовых блоков, из которых строятся любые приложения;
- на практике посмотрим, как создаются программы на языке Java на примере простой консольной игры.
📌После вебинара вы сможете самостоятельно написать похожее приложение и даже улучшить его!
Спикер Александр Фисунов — Senior Kotlin Developer в SSP Software на проекте ВТБ, опытный ментор, кандидат технических наук.
Встречаемся 29 мая в 20:00 мск в рамках курса «Специализация Java-разработчик».
Все участники вебинара получат специальную цену на обучение!
➡️ Регистрируйтесь прямо сейчас, чтобы не пропустить бесплатный урок: https://vk.cc/cx3JsJРеклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Как инициализировать переменную функционального интерфейса?
Функциональный интерфейс – всё ещё интерфейс, поэтому остаются доступными стандартные способы. Интерфейс можно реализовать обычным классом, и затем создать его экземпляр оператором new. Можно совместить эти два действия, и создать экземпляр анонимного класса.
Основное преимущество, которое дает функциональный интерфейс – два дополнительных способа инициализации параметров и переменных.
1. Лямбда-выражение: (x, y) -> x * y
2. Ссылка на метод: Math::sqrt
На эти способы накладывается небольшое ограничение: тип функционального параметра/переменной должен быть указан явно. Это значит, что лямбдой или метод-референсом нельзя инициализировать переменную, объявленную ключевым словом var. Также, чтобы передать лямбду или референс в параметр generic-типа, этот тип должен быть ограничен функциональным интерфейсом (должен стираться в него).
👉@BookJava
new Integer(128) == 128?
Для всех классов-оберток над примитивами кроме Float и Double работает механизм кэширования. Некоторые значения создаются на этапе инициализации класса, и переиспользуются когда объект создается не оператором new (например с помощью valueOf).
Кэшируемые значения – оба возможных Boolean, Character до '\u007f' (127) и все целые числа от -128 до 127 включительно. С Java 7 верхнюю границу для Integer можно увеличить параметром java.lang.Integer.IntegerCache.high.
Значения кэшируются и во многих других встроенных классах: BigDecimal, Currency, пустые коллекции. Детали можно узнавать из исходников и документаций, так как эти кэши реализованы не на уровне JVM а в коде классов.
В конкретно этом примере скрыт еще один подвох: объект класса-обертки сравнивается с примитивом. Это приводит к анбоксингу и сравнению значений. И ответ на вопрос – да.
👉@BookJava
Что можно импортировать статически?
Обычный импорт избавляет от необходимости писать полное имя классов: при использовании можно не указывать пакет. Статические импорты делает то же самое, но для статических членов класса.
Самое распространенное применение статического импорта – включение констант из константных интерфейсов и статических методов из утилитарных классов. Но также можно включать и изменяемые статические поля других классов.
Отдельно интересен случай nested-класса. Он одновременно является и классом, и статическим членом другого класса. Поэтому для него работает как обычный, так и статический импорт.
Языковая конструкция static import обязана располагаться там же, где и обычные импорты – обязательно между package и объявлением основного класса файла.
👉@BookJava
👩💻 Тест по Java от OTUS
Проверь насколько хорошо ты знаешь Java и готов освоить Spring!
Ответишь — пройдешь на продвинутый курс "Разработчик на Spring Framework" от OTUS по специальной цене.
➡️ ПРОЙТИ ТЕСТ: https://vk.cc/cx1G3c
🎫 Курс можно приобрести в рассрочкуРеклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Совет по Spring Boot 🍃💡
Если вы используете Docker Compose или Testcontainers и хотите узнать ConnectionDetails, которые мы используем под капотом, просто выведите их 🤩
👉@BookJava
Совет по Spring Boot 🍃💡
Если вы перешли на Java 21 и используете Spring Boot 3.1 или ниже, вам необходимо обновить билдер Paketo, чтобы избежать ошибки: «Builder lifecycle „creator“ failed with status code 51» во время `mvn spring-boot:build-image`.
👉@BookJava
Совет по Spring Boot 💡
Вы думаете о замене 🍃`RestTemplate` на новый Spring RestClient? Конфигурация SSL очень проста благодаря поддержке 🔐`SslBundles` через интерфейс RestClientSsl 👆
👉@BookJava
Совет по Java 💡
Занимаетесь ли вы версионированием REST API в своих приложениях? Micronaut🚀 - единственный популярный фреймворк Java☕️, который предоставляет очень удобный встроенный механизм для этого 👆
#java #restapi #versioning #micronaut
👉@BookJava
Какой у Spring бинов скоуп по умолчанию?
В Spring Framework во всех определениях бизнес-сущностей (bean) явно или неявно присутствует атрибут scope. В Java-конфигурации он передается в аннотации @Scope, в xml – в атрибуте scope тега <bean>.
Атрибут scope – это строка-идентификатор, которая ставит бину в соответствие экземпляр класса org.springframework.beans.factory.config.Scope. Скоуп – реализация паттерна «стратегия» для фабрик бинов, инструкция по созданию бизнес-объектов.
В простейшем Spring-приложении всегда существует два сокоупа:
• singleton – объект создается однажды, при последующих внедрениях переиспользуется. Полезен для большинства случаев: различные сервисы, объекты без состояния, неизменяемые объекты. Стоит заметить, это не класс-синглтон: при объявлении двух бинов одного класса их экземпляров будет два. Это скоуп по умолчанию.
• prototype – при каждом внедрении фабрика бинов создает новый объект. Нужен для изменяемых бинов с состоянием.
Spring Web добавляет 4 дополнительных скоупа, которые делают бин синглтоном в пределах обработки одного сетевого запроса (request), клиентской сессии (session), контекста сервлета (application) и вебсокет-сессии (websocket).
Разработчик может добавлять собственные скоупы. Пример реализации одного можно найти в самих исходниках Spring: SimpleThreadScope, который делает бин тред-локальным. Для использования его, как и пользовательские скоупы, нужно сначала зарегистрировать в BeanFactory.
👉@BookJava
👩💻 Обучение для тех, кто хочет освоить Java на профессиональном уровне — актуальный стек, 88 часов практической работы, детальный разбор технологий изнутри
Пройди тест по Java и проверь свои знания, готов ли ты к обучению на курсе.
Ответишь — пройдешь на продвинутый курс "Java Developer. Professional" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса курса
👉 ПРОЙТИ ТЕСТ: https://vk.cc/cxdeYxРеклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Совет 🚀 Spring Retry 🚀
Spring Retry предлагает возможность автоматического повторного выполнения неудачной операции. 🔥
https://github.com/spring-projects/spring-retry
👉@BookJava
👩💻 Пройди тест по Java и проверь свои знания.
Ответишь — пройдешь на продвинутый курс "Java Developer. Professional" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса курса
👉 ПРОЙТИ ТЕСТ: https://vk.cc/cx5tGbРеклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🚀 Spring Boot с DevTools для Live Reload🚀
Ускорьте разработку с помощью DevTools! 🔥
https://docs.spring.io/spring-boot/reference/using/devtools.html
👉@BookJava
Совет по Java 💡☕️
Чтобы получить все дни месяца, вы можете начать с объекта YearMonth, получить его первый день, а затем использовать функцию datesUntil(), которая возвращает Stream всех дней до указанной даты.
👉@BookJava
Почему интерактивная разработка на Clojure — это круто?
В Clojure ты можешь запустить программу всего один раз и взаимодействовать с ней на протяжении всего процесса разработки в реальном времени. Хочешь разобраться? Тогда ждем тебя на открытом практическом уроке от OTUS, где мы разберем:
▫️как добавлять новые функции или менять состояние программы;
▫️как «прощупывать» любые данные и пошагово отлаживать код;
▫️как запускать тесты и подключаться к внешним системам.
И всё это не выходя из интерактивной среды разработки REPL!
Встречаемся 30 мая в 20:00 мск в рамках курса «Clojure Developer». Все участники вебинара получат специальную цену на обучение!
➡️ Регистрируйся прямо сейчас, чтобы не пропустить бесплатный урок: https://vk.cc/cx3CGN
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Мечтаешь об успешной карьере в Java-разработке, но не знаешь, с чего начать ❓
Прокачайся бесплатно в ИТ-лагере T1.Дебют!
🌟 Приглашаем студентов и выпускников всей страны в ИТ-лагерь — это новый образовательный интенсив для Java-разработчиков от Холдинга Т1 — крупнейшей ИКТ-компании в России по версии RAEX 2023.
ИТ-лагерь проходит в два этапа: 1 месяц онлайн-обучения и неделя летнего атмосферного офлайн-буткемпа! ☀️
Гибкий формат позволяет совмещать обучение в ИТ-лагере со сдачей сессии или работой.
Финалисты получат сертификат на оплачиваемую стажировку, а лучших выпускников с опытом сразу пригласят в команду Т1.
🗓 Подай заявку до 31 мая
Реклама. ООО "Т1". ИНН 7720484492.
🚀Совет по использованию Spring Boot API🚀SpringApplicationBuilder
Мастер настройки приложений Spring Boot. Настройте поведение вашего приложения при запуске.
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/builder/SpringApplicationBuilder.html
👉@BookJava
Совет по Spring Boot💡
Используйте SpringApplicationBuilder для настройки запуска, свойств и профилей приложения.
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/builder/SpringApplicationBuilder.html
👉@BookJava
AnyLogic — почему это ПО используют современные компании и зачем вам его осваивать?
Узнайте на открытом практическом уроке от OTUS, где мы разберем:
- что может AnyLogic, что не могут решатели дифференциальных уравнений, Excel и здравый смысл;
- основные возможности AnyLogic;
- основные логические блоки;
- начальную настройку любой модели;
- начальную настройку исходных чертежей.
Спикер — опытный разработчик, веб-дизайнер и преподаватель.
Встречаемся 23 мая в 20:00 мск в преддверии старта курса «Имитационное моделирование на базе AnyLogic». Все участники вебинара получат специальную цену на обучение и консультацию от менеджеров OTUS!
➡️ Регистрируйтесь прямо сейчас, чтобы не пропустить бесплатный урок: https://vk.cc/cx02fN
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Совет по Spring Boot 💡
Если вы используете DTO в Spring Data/JPA, вы можете автоматизировать отображение между сущностями и DTO с помощью библиотеки Blaze Persistence (https://persistence.blazebit.com). Тогда вы сможете воспользоваться преимуществами, например, паттерна Spring repository.
👉@BookJava
Совет по Spring Boot 💡
Аннотация с возможностью кэширования
Обеспечьте быстрый доступ к данным и уменьшите нагрузку на базу данных. 🔥
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/annotation/Cacheable.html
👉@BookJava