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


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

РКН clck.ru/3KoGeP
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Как скомпилировать исходники java вручную

В повседневной работе никто из нас не компилирует исходники Java вручную. За нас это делают такие инструменты как maven, gradle или интегрированная среда разработки типа Idea.

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

https://devmark.ru/article/manual-java-compiling

👉@BookJava
👍5
Как обобрать дерево в несколько потоков?

Всем привет, меня зовут Антон, я Java‑разработчик в Сбере, подразделение SberWorks. Я разрабатываю Giga IDE — новую IDE на основе IntelliJ IDEA. В ходе работы столкнулся с тем, что при открытии проектов происходит сканирование всех папок для поиска тех или иных файлов. Если обобщить, то задача сводится к обходу дерева. Я решил подробнее рассмотреть эту тему, причём с прицелом на многопоточность.

Задача обхода деревьев далеко не нова, существуют два основных подхода: обход в ширину и глубину. В первом случае удобно применять рекурсивный алгоритм, а во втором — понадобится дополнительная коллекция, в которую будут складываться узлы дерева, но всё это в один поток, а я решил рассмотреть эту задачу в многопоточной интерпретации.

https://habr.com/ru/companies/sberbank/articles/921528/

👉@BookJava
👍6🤔1
🔔 Прокачайте системный подход + скидка 🎁 10% на курс до 30 июня

Системный дизайн — для тех, кто отвечает за стратегическое мышление и принятие архитектурных решений

Хотите глубже понимать, как проектируются масштабируемые и устойчивые системы?

Курс «System Design» от OTUS — это:

— Не просто паттерны, а практика проектирования сложных систем,
— Подготовка к архитектурным интервью,
— Реальные кейсы из крупных компаний,
— Финальный проект, который можно показать в портфолио.

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

🚀Успейте воспользоваться 🏷10% скидкой на курс. Выгодные условия действуют до 30 июня включительно!

🔗 Получить скидку и оставить заявку: https://vk.cc/cNfrd0

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопрос с собеседования: Опишите жизненный цикл 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
👍8🔥31
🚀 Java Streams: Основные методы для чистого и эффективного кода!

Java Streams предлагают множество методов для упрощения манипуляций с данными и повышения читаемости кода.
Вот краткое руководство с примерами:

Освойте эти методы, чтобы писать более чистый и эффективный код на Java! 💡

👉@BookJava
👍4
👩‍💻🎯 Открытый урок «Основы многопоточности в Java».

🗓 7 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».

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

Программа урока:
✔️ Введение в многопоточность: что это и зачем это нужно.
✔️ Изучение базовых классов для работы с потоками.
✔️ Разбор типовых проблем многопоточности и подходов к их решению.

Урок будет полезен тем, кто хочет:
- Разобраться в основах многопоточности в Java.
- Понять, как писать многопоточные программы.
- Узнать, какие классы используются для работы с потоками в Java.

В результате урока вы:
- Поймете подходы к многопоточности в Java.
- Изучите базовые классы и синтаксис многопоточной обработки.
- Сможете применять полученные знания для создания более эффективных Java-приложений.

🔗 Ссылка на регистрацию: https://vk.cc/cNjooh

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1👎1👏1
JEP 511 расширяет язык программирования Java, добавляя возможность кратко импортировать все пакеты, экспортируемые модулем — это упрощает повторное использование модульных библиотек, но при этом не требует, чтобы код, осуществляющий импорт, сам находился в модуле.

➡️Подробнее: https://openjdk.org/jeps/511

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
Media is too big
VIEW IN TELEGRAM
Что такое Java?

Разбираем собеседование по Java-кодингу.

👉@BookJava
👍7
🔍 Завтра тестовое собеседование с Java-разработчиком

2 июля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot

Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqxP5g9d
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Media is too big
VIEW IN TELEGRAM
Что такое класс Object?

Разбираем Java-собеседование по кодингу.

👉@BookJava
👍5🔥2😐1
Media is too big
VIEW IN TELEGRAM
Можете ли вы назвать методы класса Object?

👉@BookJava
👍5🔥3💩2
🤝 Тормозит карьерный рост? Упираетесь в потолок с текущими навыками на Java? Новые проекты ускользают, а вы застряли на одном уровне?

🔥 Пройдите тест! 💻 Ответьте на 22 вопроса и узнайте, достаточно ли у вас знаний, для обучения на онлайн-курсе «Java Developer. Advanced» от OTUS.

На курсе вы изучите:

✔️ Принципы профилирования JVM и оптимизации приложений.
✔️ Выбор и настройку сборщика мусора (GC).
✔️ Использование фреймворков для неблокирующих IO.
✔️ Интеграцию с Prometheus и Grafana для мониторинга.
✔️ Разработку микросервисов и деплой в Kubernetes.

Вас ждут живые вебинары, общение с преподавателями и вашей группой в Telegram, сдача домашних работ и получение обратной связи от преподавателя..

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

➡️ Пройдите короткий тест и присоединяйтесь к группе: https://vk.cc/cNmWNd

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
В чем различия между String и char[]?

👉@BookJava
👍4💩31
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();
}



2. Таймер производительности (Stopwatch)


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;
}



3. Deep Copy через сериализацию


@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);
}
}



4. Рекурсивный поиск файлов с фильтром


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());
}
}



5. Универсальный Retry Wrapper


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");
}



6. Сериализация Map в query string


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("&"));
}



7. Группировка по произвольному ключу


public static <T, K> Map<K, List<T>> groupBy(Collection<T> items, Function<T, K> classifier) {
return items.stream().collect(Collectors.groupingBy(classifier));
}



8. Метод ожидания условия с таймаутом


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;
}



9. Поиск первого ненулевого значения


@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();
}



10. Конвертация Enum в Map


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()));
}


👉@BookJava
👍7🤡4🔥1👏1🤔1
🧠Принципы 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);
}
}



📌 O — Open/Closed Principle (OCP)

Классы открыты для расширения, но закрыты для изменения.


// Используем 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);
}
}



📌 L — Liskov Substitution Principle (LSP)

Объекты подклассов должны заменять объекты суперклассов без ошибок.

⚠️ Нарушение LSP вызывает баги, когда подкласс меняет поведение базового класса.


class Bird {
void fly() { /*...*/ }
}
class Ostrich extends Bird {
void fly() { throw new UnsupportedOperationException(); } // нарушает LSP
}


Решение — выносить общее поведение в интерфейсы по возможностям, а не по наследованию.


📌 I — Interface Segregation Principle (ISP)

Лучше несколько маленьких интерфейсов, чем один жирный.


// Плохо: интерфейс заставляет имплементировать ненужное
interface Machine {
void print(); void scan(); void fax();
}

// Хорошо: разделение по возможностям
interface Printer { void print(); }
interface Scanner { void scan(); }



📌 D — Dependency Inversion Principle (DIP)

Модули верхнего уровня не должны зависеть от низкоуровневых. Зависимость — от абстракций.


// Вместо прямой зависимости от класса — интерфейс
interface NotificationSender {
void send(String message);
}
class EmailSender implements NotificationSender { /*...*/ }
class UserNotifier {
private final NotificationSender sender;
public UserNotifier(NotificationSender sender) {
this.sender = sender;
}
}


💡 Spring идеально подходит для соблюдения DIP — внедрение зависимостей через @Autowired или @Bean.


Если вы соблюдаете SOLID — ваш код легче тестировать, расширять и поддерживать. Но без фанатизма: балансируйте с принципами KISS и YAGNI.

👉@BookJava
👍73
🧑🏻‍💻Хотите научиться создавать приложения на Android?

9 июля в 20:00 МСК мы разберёмся, как создать простое приложение «Фото дня». На открытом вебинаре вы научитесь работать с API, скачивать данные с сервера, отображать фотографии и их описания в приложении, а также писать бизнес-логику для загрузки и отображения информации.

Вы освоите ключевые навыки, необходимые начинающему разработчику Android-приложений: подключение к серверу, взаимодействие с API, отображение данных и создание интерфейса. Этот опыт станет основой для вашего пути в мобильной разработке.

⚡️Открытый урок проходит в преддверии старта курса «Android Developer». Все участники получат скидку на обучение. Регистрация открыта: https://vk.cc/cNsUdo

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Совет по Spring Boot 🚀

Еесли вы хотите узнать, когда начинается и заканчивается транзакция #JPA, как повторно использовать существующую транзакцию в @Transactional или шаблоне TransactionTemplate, включите логирование DEBUG для `org.springframework.orm.jpa`.

👉@BookJava
👍52
Media is too big
VIEW IN TELEGRAM
Абстрактные классы и методы в Java: объяснение за 7 минут

Что такое абстрактные классы и методы в Java, как и зачем их использовать?
Также — в чём разница между абстрактным классом и интерфейсом?

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

Как создать абстрактный класс или абстрактный метод? Почему вообще стоит использовать абстрактный класс в Java? Чем абстрактный класс отличается от интерфейса?

Улучшайте свои знания Java, наблюдая за живым написанием кода!

Привет, меня зовут Джон! Я ведущий инженер-программист Java с более чем десятилетним опытом работы в индустрии. Мне нравится делиться тем, что я узнал за эти годы, понятным языком — для программистов любого уровня.

👉@BookJava
👍2