10986
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP
15 июля в 20:00 МСК OTUS проведёт открытый урок «Нормальная денормализация» — ключевой приём для оптимизации доступа к данным в NoSQL.
На примере Spring Data MongoDB разберём, как настраивать связи между сущностями: когда выбрать вложенные документы, а когда — ссылочные связи. Вы поймёте, как денормализация влияет на производительность запросов, расходы на память и сложность поддержки.
Урок будет полезен Java-разработчикам, backend-инженерам и архитекторам, работающим с MongoDB. Вы получите готовые шаблоны организации данных в Spring-приложениях, избежите типичных ошибок при проектировании схемы и сможете принимать обоснованные архитектурные решения.
Присоединяйтесь к уроку и получите скидку на полный курс «Разработчик на Spring Framework».
Регистрируйтесь прямо сейчас: https://vk.cc/cNzDh0
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🧠 Stream API vs. for-loop: когда лучше не использовать Stream
Всё чаще вижу, как даже простые циклы заменяют на Stream API "для красоты". Но в ряде случаев это бьёт по производительности и читаемости.
📌 Пример:
// Было
for (User user : users) {
if (user.isActive()) {
return user;
}
}
// Стало
return users.stream()
.filter(User::isActive)
.findFirst()
.orElse(null);
stream() создает итератор, лямбду, объект Optional, плюс возможен autoboxing. А обычный for — просто цикл.for-loop быстрее на ~30-50% на коротких коллекциях (до 1000 элементов).for всё равно стабильнее.for:parallelStream() (осторожно!).for — это и быстрее, и понятнее.
Абстрактные классы и методы в Java: объяснение за 7 минут
Что такое абстрактные классы и методы в Java, как и зачем их использовать?
Также — в чём разница между абстрактным классом и интерфейсом?
Абстрактные классы могут показаться странной и сложной концепцией в Java, но на самом деле всё довольно просто. Мы объясним их всего за несколько минут в этом видеоуроке для начинающих по Java.
Как создать абстрактный класс или абстрактный метод? Почему вообще стоит использовать абстрактный класс в Java? Чем абстрактный класс отличается от интерфейса?
Улучшайте свои знания Java, наблюдая за живым написанием кода!
Привет, меня зовут Джон! Я ведущий инженер-программист Java с более чем десятилетним опытом работы в индустрии. Мне нравится делиться тем, что я узнал за эти годы, понятным языком — для программистов любого уровня.
👉@BookJava
VK приглашает на Java AI meetup 9 июля. Обещают доклады топовых спикеров из AI-департамента, тематическую дискуссию и много полезных знакомств в индустрии.
Подробнее — здесь.
🧑🏻💻Хотите научиться создавать приложения на Android?
9 июля в 20:00 МСК мы разберёмся, как создать простое приложение «Фото дня». На открытом вебинаре вы научитесь работать с API, скачивать данные с сервера, отображать фотографии и их описания в приложении, а также писать бизнес-логику для загрузки и отображения информации.
Вы освоите ключевые навыки, необходимые начинающему разработчику Android-приложений: подключение к серверу, взаимодействие с API, отображение данных и создание интерфейса. Этот опыт станет основой для вашего пути в мобильной разработке.
⚡️Открытый урок проходит в преддверии старта курса «Android Developer». Все участники получат скидку на обучение. Регистрация открыта: https://vk.cc/cNsUdo
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
10 полезных функций, которые часто пригождаются продвинутым Java-разработчикам
1. Safe Cast с Optional
public static <T> Optional<T> safeCast(Object obj, Class<T> clazz) {
return clazz.isInstance(obj) ? Optional.of(clazz.cast(obj)) : Optional.empty();
}
public static <T> T measureTime(String label, Supplier<T> supplier) {
long start = System.nanoTime();
T result = supplier.get();
long duration = System.nanoTime() - start;
System.out.printf("[%s] Duration: %d ms%n", label, duration / 1_000_000);
return result;
}
@SuppressWarnings("unchecked")
public static <T extends Serializable> T deepCopy(T object) {
try (
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)
) {
oos.writeObject(object);
try (
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais)
) {
return (T) ois.readObject();
}
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("Deep copy failed", e);
}
}
public static List<Path> findFiles(Path root, Predicate<Path> filter) throws IOException {
try (Stream<Path> stream = Files.walk(root)) {
return stream.filter(Files::isRegularFile).filter(filter).collect(Collectors.toList());
}
}
public static <T> T retry(int attempts, Duration delay, Supplier<T> task) {
for (int i = 1; i <= attempts; i++) {
try {
return task.get();
} catch (Exception e) {
if (i == attempts) throw e;
try { Thread.sleep(delay.toMillis()); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }
}
}
throw new RuntimeException("Retry failed");
}
public static String toQueryString(Map<String, String> params) {
return params.entrySet().stream()
.map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8) + "=" +
URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
}
public static <T, K> Map<K, List<T>> groupBy(Collection<T> items, Function<T, K> classifier) {
return items.stream().collect(Collectors.groupingBy(classifier));
}
public static boolean waitFor(Predicate<Void> condition, Duration timeout, Duration interval) {
long deadline = System.currentTimeMillis() + timeout.toMillis();
while (System.currentTimeMillis() < deadline) {
if (condition.test(null)) return true;
try { Thread.sleep(interval.toMillis()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
}
return false;
}
@SafeVarargs
public static <T> Optional<T> firstNonNull(Supplier<T>... suppliers) {
for (Supplier<T> supplier : suppliers) {
T value = supplier.get();
if (value != null) return Optional.of(value);
}
return Optional.empty();
}
public static <E extends Enum<E>> Map<String, E> enumMap(Class<E> enumClass) {
return Arrays.stream(enumClass.getEnumConstants())
.collect(Collectors.toMap(Enum::name, Function.identity()));
}
🤝 Тормозит карьерный рост? Упираетесь в потолок с текущими навыками на Java? Новые проекты ускользают, а вы застряли на одном уровне?
🔥 Пройдите тест! 💻 Ответьте на 22 вопроса и узнайте, достаточно ли у вас знаний, для обучения на онлайн-курсе «Java Developer. Advanced» от OTUS.
На курсе вы изучите:
✔️ Принципы профилирования JVM и оптимизации приложений.
✔️ Выбор и настройку сборщика мусора (GC).
✔️ Использование фреймворков для неблокирующих IO.
✔️ Интеграцию с Prometheus и Grafana для мониторинга.
✔️ Разработку микросервисов и деплой в Kubernetes.
Вас ждут живые вебинары, общение с преподавателями и вашей группой в Telegram, сдача домашних работ и получение обратной связи от преподавателя..
🦾 Пора стать тем самым разработчиком, которого компании хантят друг у друга. Нужно только перейти на принципиально новый уровень.
➡️ Пройдите короткий тест и присоединяйтесь к группе: https://vk.cc/cNmWNd
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Что такое класс Object?
Разбираем Java-собеседование по кодингу.
👉@BookJava
Что такое Java?
Разбираем собеседование по Java-кодингу.
👉@BookJava
👩💻🎯 Открытый урок «Основы многопоточности в Java».
🗓 7 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».
Приглашаем вас на бесплатный вебинар, посвященный основам многопоточности в Java. Абсолютное большинство коммерческих Java-приложений работает в многопоточном режиме, и понимание принципов многопоточной обработки позволяет писать более эффективные программы, избегая распространенных ошибок. На занятии мы разберем ключевые подходы к многопоточности, изучим используемые классы, а также рассмотрим типовые проблемы и их решения.
Программа урока:
✔️ Введение в многопоточность: что это и зачем это нужно.
✔️ Изучение базовых классов для работы с потоками.
✔️ Разбор типовых проблем многопоточности и подходов к их решению.
Урок будет полезен тем, кто хочет:
- Разобраться в основах многопоточности в Java.
- Понять, как писать многопоточные программы.
- Узнать, какие классы используются для работы с потоками в Java.
В результате урока вы:
- Поймете подходы к многопоточности в Java.
- Изучите базовые классы и синтаксис многопоточной обработки.
- Сможете применять полученные знания для создания более эффективных Java-приложений.
🔗 Ссылка на регистрацию: https://vk.cc/cNjooh
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Вопрос с собеседования: Опишите жизненный цикл Spring Bean
Beans – центральный объект заботы Spring Framework. За кулисами фреймворка с ними происходит множество процессов. Во многие из них можно вмешаться, добавив собственную логику в разные этапы жизненного цикла. Через следующие этапы проходит каждый отдельно взятый бин:
1. Инстанцирование объекта. Техническое начало жизни бина, работа конструктора его класса;
2. Установка свойств из конфигурации бина, внедрение зависимостей;
3. Нотификация aware-интерфейсов. BeanNameAware, BeanFactoryAware и другие. Мы уже писали о таких интерфейсах ранее. Технически, выполняется системными подтипами BeanPostProcessor, и совпадает с шагом 4;
4. Пре-инициализация – метод postProcessBeforeInitialization() интерфейса BeanPostProcessor;
5. Инициализация. Разные способы применяются в таком порядке:
• Метод бина с аннотацией @PostConstruct из стандарта JSR-250 (рекомендуемый способ);
• Метод afterPropertiesSet() бина под интерфейсом InitializingBean;
• Init-метод. Для отдельного бина его имя устанавливается в параметре определения initMethod. В xml-конфигурации можно установить для всех бинов сразу, с помощью default-init-method;
6. Пост-инициализация – метод postProcessAfterInitialization() интерфейса BeanPostProcessor.
Когда IoC-контейнер завершает свою работу, мы можем кастомизировать этап штатного уничтожения бина. Как со всеми способами финализации в Java, при жестком выключении (kill -9) гарантии вызова этого этапа нет. Три альтернативных способа «деинициализации» вызываются в том же порядке, что симметричные им методы инициализации:
1. Метод с аннотацией @PreDestroy;
2. Метод с именем, которое указано в свойстве destroyMethod определния бина (или в глобальном default-destroy-method);
3. Метод destroy() интерфейса DisposableBean.
Не следует путать жизненный цикл отдельного бина с жизненным циклом контекста и этапами подготовки фабрик бинов. О них мы поговорим в будущих публикациях.
👉@BookJava
Как обобрать дерево в несколько потоков?
Всем привет, меня зовут Антон, я Java‑разработчик в Сбере, подразделение SberWorks. Я разрабатываю Giga IDE — новую IDE на основе IntelliJ IDEA. В ходе работы столкнулся с тем, что при открытии проектов происходит сканирование всех папок для поиска тех или иных файлов. Если обобщить, то задача сводится к обходу дерева. Я решил подробнее рассмотреть эту тему, причём с прицелом на многопоточность.
Задача обхода деревьев далеко не нова, существуют два основных подхода: обход в ширину и глубину. В первом случае удобно применять рекурсивный алгоритм, а во втором — понадобится дополнительная коллекция, в которую будут складываться узлы дерева, но всё это в один поток, а я решил рассмотреть эту задачу в многопоточной интерпретации.
https://habr.com/ru/companies/sberbank/articles/921528/
👉@BookJava
🦾👩💻 Вы опытный Java-разработчик и хотите углубить свои знания? Понимание JVM, профилирование и оптимизация приложений под нагрузкой — это ключевые навыки для карьерного роста.
⚡️ Курс «Java Developer. Advanced» от OTUS даст вам все необходимые знания для оптимизации приложений в облачной инфраструктуре.
На курсе вы изучите:
✔️ Принципы профилирования JVM и оптимизации приложений.
✔️ Выбор и настройку сборщика мусора (GC).
✔️ Использование фреймворков для неблокирующих IO.
✔️ Интеграцию с Prometheus и Grafana для мониторинга.
✔️ Разработку микросервисов и деплой в Kubernetes.
Вы сможете протестировать и профилировать приложения под нагрузкой, устранять утечки памяти и оптимизировать их производительность.
➡️ Пройдите короткий тест и присоединяйтесь к группе: https://vk.cc/cNbBBv
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Java. Представление отрицательных чисел. Преобразование цветной фотографии в черно-белую.
В этом видео я рассказываю о представлении в отрицательных чисел в компьютере на примере типа byte. Показываю, что можно получить, если забыть, что все целочисленные типы в языке программирования Java знаковые. В качестве практической части, пишем алгоритм для преобразования цветной фотографии в черно-белую.
👉@BookJava
Kafka Cluster в Docker
Настроим docker-compose.yml для кафка кластера и запустим наше приложение с кафкой из докера
00:00 Intro
00:30 Конфигурация одного сервера
10:23 Запуск и проверка работы
15:15 Конфигурация кластера
18:05 Запуск кластера и проверка работы
19:30 environment.env
21:30 environment.env
22:56 Итог
источник
👉@BookJava
🚀 Совет по Java API
Периоды дня в форматах java.time
Если вы хотите указать период дня, например «утром», «днем» или «ночью», используйте шаблон форматирования с символом B. 🔥
👉@BookJava
👩💻🎯 Открытый урок «Кракозябры vs Java: как победить кодировки и стать Гуру Unicode?».
🗓 17 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».
Ошибки в кодировках ломают приложения, превращая текст в «абракадабру». Понимание таблиц кодировок — must-have навык для работы с данными, файлами и международными проектами.
О чём поговорим:
✔️ ASCII, UTF-8, Unicode — WTF? Разберём, как Java хранит и обрабатывает текст.
✔️ Почему файлы «ломаются»? Как избежать ошибок при чтении/записи данных.
✔️ Лайфхаки для юникода: работа с иероглифами и русским языком.
✔️ Секреты JVM: как настроить кодировку в проекте.
Кому будет интересно:
Начинающим Java-разработчикам и тестировщикам, сталкивающимся с международными данными и проблемами кодировки.
В результате вебинара вы:
Научитесь контролировать кодировки в своих приложениях, исправлять «кракозябры» и работать с любыми текстовыми данными без страха.
🔗 Ссылка на регистрацию: https://vk.cc/cNvkAu
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Roadmap for Java Developers
👉@BookJava
Совет по Spring Boot 🚀
Еесли вы хотите узнать, когда начинается и заканчивается транзакция #JPA, как повторно использовать существующую транзакцию в @Transactional или шаблоне TransactionTemplate, включите логирование DEBUG для `org.springframework.orm.jpa`.
👉@BookJava
🧠Принципы SOLID
📌 S — Single Responsibility Principle (SRP)
Класс должен иметь только одну причину для изменения.
// ❌ Плохо: один класс делает и валидацию, и сохранение
class UserService {
void register(User user) {
if (user.email().isBlank()) throw new IllegalArgumentException();
userRepository.save(user);
}
}
// ✅ Хорошо: разбили ответственности
class UserValidator {
void validate(User user) { /*...*/ }
}
class UserService {
void register(User user) {
validator.validate(user);
userRepository.save(user);
}
}
// ✅ Используем Strategy вместо if-else
interface DiscountStrategy {
BigDecimal apply(BigDecimal price);
}
class BlackFridayDiscount implements DiscountStrategy {
public BigDecimal apply(BigDecimal price) { return price.multiply(new BigDecimal("0.8")); }
}
class CheckoutService {
BigDecimal checkout(BigDecimal price, DiscountStrategy strategy) {
return strategy.apply(price);
}
}
class Bird {
void fly() { /*...*/ }
}
class Ostrich extends Bird {
void fly() { throw new UnsupportedOperationException(); } // ❌ нарушает LSP
}
// ❌ Плохо: интерфейс заставляет имплементировать ненужное
interface Machine {
void print(); void scan(); void fax();
}
// ✅ Хорошо: разделение по возможностям
interface Printer { void print(); }
interface Scanner { void scan(); }
// ✅ Вместо прямой зависимости от класса — интерфейс
interface NotificationSender {
void send(String message);
}
class EmailSender implements NotificationSender { /*...*/ }
class UserNotifier {
private final NotificationSender sender;
public UserNotifier(NotificationSender sender) {
this.sender = sender;
}
}
@Autowired или @Bean.
В чем различия между String и char[]?
👉@BookJava
Можете ли вы назвать методы класса Object?
👉@BookJava
🔍 Завтра тестовое собеседование с Java-разработчиком
2 июля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqxP5g9d
JEP 511 расширяет язык программирования Java, добавляя возможность кратко импортировать все пакеты, экспортируемые модулем — это упрощает повторное использование модульных библиотек, но при этом не требует, чтобы код, осуществляющий импорт, сам находился в модуле.
➡️Подробнее: https://openjdk.org/jeps/511
👉@BookJava
🚀 Java Streams: Основные методы для чистого и эффективного кода!
Java Streams предлагают множество методов для упрощения манипуляций с данными и повышения читаемости кода.
Вот краткое руководство с примерами:
Освойте эти методы, чтобы писать более чистый и эффективный код на Java! 💡
👉@BookJava
🔔 Прокачайте системный подход + скидка 🎁 10% на курс до 30 июня
Системный дизайн — для тех, кто отвечает за стратегическое мышление и принятие архитектурных решений
Хотите глубже понимать, как проектируются масштабируемые и устойчивые системы?
Курс «System Design» от OTUS — это:
— Не просто паттерны, а практика проектирования сложных систем,
— Подготовка к архитектурным интервью,
— Реальные кейсы из крупных компаний,
— Финальный проект, который можно показать в портфолио.
Курс подойдёт разработчикам, архитекторам, техническим лидам и DevOps-инженерам, которые хотят повысить квалификацию и системно мыслить при проектировании.
🚀Успейте воспользоваться 🏷10% скидкой на курс. Выгодные условия действуют до 30 июня включительно!
🔗 Получить скидку и оставить заявку: https://vk.cc/cNfrd0
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Как скомпилировать исходники java вручную
В повседневной работе никто из нас не компилирует исходники Java вручную. За нас это делают такие инструменты как maven, gradle или интегрированная среда разработки типа Idea.
Но для понимания процессов, которые происходят при каждом тестовом запуске вашего приложения, имеет смысл хотя бы один попробовать это сделать самостоятельно прямо из консоли.
https://devmark.ru/article/manual-java-compiling
👉@BookJava
📌Примеры базовых алгоритмов
➡️ 1. Сортировка пузырьком (Bubble Sort)
public class BubbleSort {
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// обмен
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
public class BinarySearch {
public static int binarySearch(int[] arr, int target) {
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1; // элемент не найден
}
}
public class MaxInArray {
public static int findMax(int[] arr) {
int max = arr[0];
for (int num : arr) {
if (num > max) max = num;
}
return max;
}
}
public class Factorial {
public static long factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
}
public class PalindromeCheck {
public static boolean isPalindrome(String str) {
int left = 0, right = str.length() - 1;
while (left < right) {
if (str.charAt(left++) != str.charAt(right--)) {
return false;
}
}
return true;
}
}
👩💻 Разработка на Java требует глубокого понимания не только языка, но и принципов работы JVM, многопоточности и современных фреймворков.
🎯 Курс «Java Developer. Professional» — это структурированное обучение для разработчиков, которые хотят выйти на новый уровень, освоить актуальный стек технологий и уверенно претендовать на позиции уровня Middle+.
Вы получите 96 часов практической работы, на живых вебинарах разберете ключевые аспекты работы JVM, научитесь строить эффективные многопоточные приложения, освоите Spring WebFlux, Kafka, реактивный Postgres и Kubernetes.
📚Программа OTUS постоянно обновляется, соответствуя требованиям рынка, а диплом ценится работодателями.
➡️ Пройдите вступительное тестирование и присоединяйтесь к группе: https://vk.cc/cN9CYN
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🧠 Быстрый способ найти performance-проблемы в Spring Boot-приложении
Сейчас покажу, как быстро узнать, какие бины подгружаются дольше всего при старте Spring Boot-приложения.
📌 Добавь в application.yml:
spring:
application:
name: demo
main:
log-startup-info: true
boot:
startup:
logging:
enabled: true
Startup completed in 3.567 seconds
Application started in 3.789 seconds (JVM running for 4.112)
Bean instantiation and initialization:
145 ms -> com.example.HeavyBean
95 ms -> com.example.AnotherBean