👩💻🎯 Открытый урок «Основы многопоточности в Java».
🗓 7 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».
Приглашаем вас на бесплатный вебинар, посвященный основам многопоточности в Java. Абсолютное большинство коммерческих Java-приложений работает в многопоточном режиме, и понимание принципов многопоточной обработки позволяет писать более эффективные программы, избегая распространенных ошибок. На занятии мы разберем ключевые подходы к многопоточности, изучим используемые классы, а также рассмотрим типовые проблемы и их решения.
Программа урока:
✔️ Введение в многопоточность: что это и зачем это нужно.
✔️ Изучение базовых классов для работы с потоками.
✔️ Разбор типовых проблем многопоточности и подходов к их решению.
Урок будет полезен тем, кто хочет:
- Разобраться в основах многопоточности в Java.
- Понять, как писать многопоточные программы.
- Узнать, какие классы используются для работы с потоками в Java.
В результате урока вы:
- Поймете подходы к многопоточности в Java.
- Изучите базовые классы и синтаксис многопоточной обработки.
- Сможете применять полученные знания для создания более эффективных Java-приложений.
🔗 Ссылка на регистрацию: https://vk.cc/cNjooh
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🗓 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
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1
2 июля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqxP5g9d
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
🔥 Пройдите тест! 💻 Ответьте на 22 вопроса и узнайте, достаточно ли у вас знаний, для обучения на онлайн-курсе «Java Developer. Advanced» от OTUS.
На курсе вы изучите:
Вас ждут живые вебинары, общение с преподавателями и вашей группой в Telegram, сдача домашних работ и получение обратной связи от преподавателя..
🦾 Пора стать тем самым разработчиком, которого компании хантят друг у друга. Нужно только перейти на принципиально новый уровень.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
10 полезных функций, которые часто пригождаются продвинутым Java-разработчикам
1. Safe Cast с Optional
2. Таймер производительности (Stopwatch)
3. Deep Copy через сериализацию
4. Рекурсивный поиск файлов с фильтром
5. Универсальный Retry Wrapper
6. Сериализация Map в query string
7. Группировка по произвольному ключу
8. Метод ожидания условия с таймаутом
9. Поиск первого ненулевого значения
10. Конвертация Enum в Map
👉@BookJava
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)
Класс должен иметь только одну причину для изменения.
📌 O — Open/Closed Principle (OCP)
Классы открыты для расширения, но закрыты для изменения.
📌 L — Liskov Substitution Principle (LSP)
Объекты подклассов должны заменять объекты суперклассов без ошибок.
⚠️ Нарушение LSP вызывает баги, когда подкласс меняет поведение базового класса.
✅ Решение — выносить общее поведение в интерфейсы по возможностям, а не по наследованию.
📌 I — Interface Segregation Principle (ISP)
Лучше несколько маленьких интерфейсов, чем один жирный.
📌 D — Dependency Inversion Principle (DIP)
Модули верхнего уровня не должны зависеть от низкоуровневых. Зависимость — от абстракций.
💡 Spring идеально подходит для соблюдения DIP — внедрение зависимостей через
Если вы соблюдаете SOLID — ваш код легче тестировать, расширять и поддерживать. Но без фанатизма: балансируйте с принципами KISS и YAGNI.
👉@BookJava
📌 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
👍7❤3
🧑🏻💻Хотите научиться создавать приложения на Android?
9 июля в 20:00 МСК мы разберёмся, как создать простое приложение «Фото дня». На открытом вебинаре вы научитесь работать с API, скачивать данные с сервера, отображать фотографии и их описания в приложении, а также писать бизнес-логику для загрузки и отображения информации.
Вы освоите ключевые навыки, необходимые начинающему разработчику Android-приложений: подключение к серверу, взаимодействие с API, отображение данных и создание интерфейса. Этот опыт станет основой для вашего пути в мобильной разработке.
⚡️Открытый урок проходит в преддверии старта курса «Android Developer». Все участники получат скидку на обучение. Регистрация открыта: https://vk.cc/cNsUdo
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
9 июля в 20:00 МСК мы разберёмся, как создать простое приложение «Фото дня». На открытом вебинаре вы научитесь работать с API, скачивать данные с сервера, отображать фотографии и их описания в приложении, а также писать бизнес-логику для загрузки и отображения информации.
Вы освоите ключевые навыки, необходимые начинающему разработчику Android-приложений: подключение к серверу, взаимодействие с API, отображение данных и создание интерфейса. Этот опыт станет основой для вашего пути в мобильной разработке.
⚡️Открытый урок проходит в преддверии старта курса «Android Developer». Все участники получат скидку на обучение. Регистрация открыта: https://vk.cc/cNsUdo
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Media is too big
VIEW IN TELEGRAM
Абстрактные классы и методы в Java: объяснение за 7 минут
Что такое абстрактные классы и методы в Java, как и зачем их использовать?
Также — в чём разница между абстрактным классом и интерфейсом?
Абстрактные классы могут показаться странной и сложной концепцией в Java, но на самом деле всё довольно просто. Мы объясним их всего за несколько минут в этом видеоуроке для начинающих по Java.
Как создать абстрактный класс или абстрактный метод? Почему вообще стоит использовать абстрактный класс в Java? Чем абстрактный класс отличается от интерфейса?
Улучшайте свои знания Java, наблюдая за живым написанием кода!
Привет, меня зовут Джон! Я ведущий инженер-программист Java с более чем десятилетним опытом работы в индустрии. Мне нравится делиться тем, что я узнал за эти годы, понятным языком — для программистов любого уровня.
👉@BookJava
Что такое абстрактные классы и методы в Java, как и зачем их использовать?
Также — в чём разница между абстрактным классом и интерфейсом?
Абстрактные классы могут показаться странной и сложной концепцией в Java, но на самом деле всё довольно просто. Мы объясним их всего за несколько минут в этом видеоуроке для начинающих по Java.
Как создать абстрактный класс или абстрактный метод? Почему вообще стоит использовать абстрактный класс в Java? Чем абстрактный класс отличается от интерфейса?
Улучшайте свои знания Java, наблюдая за живым написанием кода!
Привет, меня зовут Джон! Я ведущий инженер-программист Java с более чем десятилетним опытом работы в индустрии. Мне нравится делиться тем, что я узнал за эти годы, понятным языком — для программистов любого уровня.
👉@BookJava
👍2
🗓 17 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».
Ошибки в кодировках ломают приложения, превращая текст в «абракадабру». Понимание таблиц кодировок — must-have навык для работы с данными, файлами и международными проектами.
О чём поговорим:
Кому будет интересно:
Начинающим Java-разработчикам и тестировщикам, сталкивающимся с международными данными и проблемами кодировки.
В результате вебинара вы:
Научитесь контролировать кодировки в своих приложениях, исправлять «кракозябры» и работать с любыми текстовыми данными без страха.
🔗 Ссылка на регистрацию: https://vk.cc/cNvkAu
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🧠 Stream API vs. for-loop: когда лучше не использовать Stream
Всё чаще вижу, как даже простые циклы заменяют на Stream API "для красоты". Но в ряде случаев это бьёт по производительности и читаемости.
📌 Пример:
💡 Выглядит элегантно, но…
⚠️ Проблема:
📊 Бенчмарк (JMH):
*
* На больших коллекциях разница сокращается, но
📌 Когда лучше использовать
* Нужно выйти из цикла при первом совпадении.
* Важна максимальная производительность.
* Код должен быть суперчитаемым и без лишних аллокаций.
📌 Когда можно Stream:
* Фильтрации, маппинги, группировки — когда логика сложнее.
* Обработка больших потоков с
* Когда читаемость выигрывает из-за декларативности.
✅ Вывод: Stream API — мощный инструмент, но не замена всему подряд. Иногда простой
👉@BookJava
Всё чаще вижу, как даже простые циклы заменяют на Stream API "для красоты". Но в ряде случаев это бьёт по производительности и читаемости.
📌 Пример:
// Было
for (User user : users) {
if (user.isActive()) {
return user;
}
}
// Стало
return users.stream()
.filter(User::isActive)
.findFirst()
.orElse(null);
💡 Выглядит элегантно, но…
⚠️ Проблема:
stream()
создает итератор, лямбду, объект Optional
, плюс возможен autoboxing. А обычный for
— просто цикл.📊 Бенчмарк (JMH):
*
for-loop
быстрее на ~30-50% на коротких коллекциях (до 1000 элементов).* На больших коллекциях разница сокращается, но
for
всё равно стабильнее.📌 Когда лучше использовать
for
:* Нужно выйти из цикла при первом совпадении.
* Важна максимальная производительность.
* Код должен быть суперчитаемым и без лишних аллокаций.
📌 Когда можно Stream:
* Фильтрации, маппинги, группировки — когда логика сложнее.
* Обработка больших потоков с
parallelStream()
(осторожно!).* Когда читаемость выигрывает из-за декларативности.
✅ Вывод: Stream API — мощный инструмент, но не замена всему подряд. Иногда простой
for
— это и быстрее, и понятнее.👉@BookJava
👍7💩7❤1
🚀 Совет по Java API
Периоды дня в форматах java.time
Если вы хотите указать период дня, например «утром», «днем» или «ночью», используйте шаблон форматирования с символом B. 🔥
👉@BookJava
Периоды дня в форматах java.time
Если вы хотите указать период дня, например «утром», «днем» или «ночью», используйте шаблон форматирования с символом B. 🔥
👉@BookJava
👍6❤1
15 июля в 20:00 МСК OTUS проведёт открытый урок «Нормальная денормализация» — ключевой приём для оптимизации доступа к данным в NoSQL.
На примере Spring Data MongoDB разберём, как настраивать связи между сущностями: когда выбрать вложенные документы, а когда — ссылочные связи. Вы поймёте, как денормализация влияет на производительность запросов, расходы на память и сложность поддержки.
Урок будет полезен Java-разработчикам, backend-инженерам и архитекторам, работающим с MongoDB. Вы получите готовые шаблоны организации данных в Spring-приложениях, избежите типичных ошибок при проектировании схемы и сможете принимать обоснованные архитектурные решения.
Присоединяйтесь к уроку и получите скидку на полный курс «Разработчик на Spring Framework».
Регистрируйтесь прямо сейчас: https://vk.cc/cNzDh0
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
На примере Spring Data MongoDB разберём, как настраивать связи между сущностями: когда выбрать вложенные документы, а когда — ссылочные связи. Вы поймёте, как денормализация влияет на производительность запросов, расходы на память и сложность поддержки.
Урок будет полезен Java-разработчикам, backend-инженерам и архитекторам, работающим с MongoDB. Вы получите готовые шаблоны организации данных в Spring-приложениях, избежите типичных ошибок при проектировании схемы и сможете принимать обоснованные архитектурные решения.
Присоединяйтесь к уроку и получите скидку на полный курс «Разработчик на Spring Framework».
Регистрируйтесь прямо сейчас: https://vk.cc/cNzDh0
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576