Секреты Java
前往频道在 Telegram
Обсуждаем Java, архитектуру, фреймворки и всё, о чем должны говорить разработчики. Владелец: @Alexey_Morl Реклама на бирже: https://telega.in/c/java_secrets
显示更多7 991
订阅者
无数据24 小时
无数据7 天
无数据30 天
帖子存档
7 991
🔥 Это база 1700 вопросов с собеседований на Java разработчика. Фишка в том, что просчитана вероятность с которой вопрос буден задан и есть примеры ответов. Теперь можно легко получить оффер, подготовившись к самым популярным вопросам 😏
7 991
✅ Функциональные интерфейсы
Функциональные интерфейсы являются одним из ключевых элементов функционального программирования в Java, особенно с появлением лямбда-выражений в Java 8. Функциональный интерфейс — это интерфейс, содержащий ровно один абстрактный метод*, который можно реализовать с использованием лямбда-выражений, ссылок на методы (Method reference) или анонимных классов.
Функциональные интерфейсы в Java обозначаются аннотацией
@FunctionalInterface, которая указывает на то, что интерфейс предназначен для использования в функциональном стиле. Однако эта аннотация не обязательна, но она помогает разработчикам - компилятор начнет ругаться, если интерфейс перестанет быть функциональным.
Пример:
@FunctionalInterface
public interface MyFunctionalInterface {
void execute();
}
Этот интерфейс содержит единственный абстрактный метод execute(), что делает его функциональным интерфейсом.
Пример использования лямбда-выражения с нашим интерфейсом:
MyFunctionalInterface myFunction = () -> System.out.println("Hello, Lambda!");
myFunction.execute();
В этом примере лямбда-выражение (то что начинается с () -> ) реализует метод execute() нашего функционального интерфейса.
Функциональные интерфейсы могут иметь любое кол-во статических и дефолтных методов и они все равно остануться функциональными:
@FunctionalInterface
interface MyFunctionalInterface {
void execute();
static <T> boolean check(T t) {
return t == null;
}
default String name() {
return "Barsik";
}
}
В данном примере все хорошо скомпилируется.
И если заметили звездочку в начале поста, то вот уточнение к ней - ровно один абстрактный метод, НЕ совпадающий сигнатурой с каким-либо методом класса Object:
@FunctionalInterface
interface MyFunctionalInterface {
void execute();
boolean equals(Object obj);
}
Такой интерфейс так же будет функциональным! Но если мы уберем метод execute() и оставим equals(), то компилятор скажет нам - no abstract method found.
🫡 Секреты Java
#java #java8 #interface7 991
✅ Daemon Thread
В Java поток (thread) может быть либо пользовательским (user), либо демоном (daemon). Демон-потоки — это потоки, которые работают в фоновом режиме и в отличие от user-потоков, демон-потоки имеют низкий приоритет и не препятствуют завершению работы JVM; JVM завершает работу тогда, когда завершены все user-потоки, независимо от состояния демон-потоков.
Основные моменты:
▫️Демон-потоки предназначены для выполнения фоновых служебных задач, таких как сборка мусора, очистка кеша, мониторинг и т.п.
▫️JVM завершает работу, когда все user-потоки завершены, даже если существуют активные демон-потоки.
▫️Демон-потоки создаются и управляются так же, как и обычные потоки, но их статус можно изменить с помощью метода setDaemon(boolean).
Как создать демон-поток?
Нужно вызвать метод
setDaemon(true) перед запуском потока.
Рассмотрим пример:
Thread daemonThread = new Thread(() -> {
// какая то логика
});
daemonThread.setDaemon(true); // Устанавливаем поток как демон
daemonThread.start();
Метод setDaemon() может быть вызван только перед start(), иначе получите исключение IllegalThreadStateException.
Любой поток порожденный демон-потоком по умолчанию так же будет демон-потоком!
Можно так же проверить является ли поток демоном. Если у объекта с примера выше вызвать
daemonThread.isDaemon()
то этот метод вернет true.
Демо-поток следует использовать исключительно для фоновых задач. Если он занимается важной задачей, такой как запись данных, и основной поток завершится раньше, данные могут быть потеряны. Так же демон-потоки не могут не выполнить блоки finally если user-потоки завершатся раньше.
Демон-потоки в Java — это полезный инструмент для выполнения фоновых задач, которые не должны блокировать завершение программы. Они просты в использовании и обеспечивают эффективное выполнение служебных задач. Однако важно использовать их с осторожностью, чтобы избежать потенциальных проблем, таких как потеря данных или некорректное завершение работы задач.
🫡 Секреты Java
#thread #multithreading7 991
✅ Метод Arrays.parallelPrefix()
В Java 8 у утильного класса
Arrays повился достаточно интересный метод parallelPrefix() — инструмент для выполнения параллельных операций над массивами. Он применяет заданную бинарную операцию (BinaryOperator<T>) к каждому элементу массива кумулятивно, используя возможности параллельных вычислений для повышения производительности.
Как работает parallelPrefix(), рассмотрим на примере:
int[] array = {1, 2, 3, 4};
Arrays.parallelPrefix(array, Integer::sum);
System.out.println(Arrays.toString(array));
// Вывод: [1, 3, 6, 10]
В этом примере Integer::sum используется в качестве бинарной операции.
Метод обрабатывает массив, выполняя операцию кумулятивно (т.е. последовательно, накапливая результат от предыдущих вычислений). Например, для примера выше, метод вычислит:
▫️На первом шаге: [1, 3, 3, 4] (накопленный результат после второго элемента — 1+2=3)
▫️На втором шаге: [1, 3, 6, 4] (накопленный результат после третьего элемента — 3+3=6)
▫️На третьем шаге: [1, 3, 6, 10] (накопленный результат после четвертого элемента — 6+4=10)
Подобные операции можно делать и со строками и любыми другими объектами, а так же задавать диапазон элементов в массиве для обработки:
String[] array = {"a", "b", "c", "d", "f"};
Arrays.parallelPrefix(array, 1, 4, (first, second) -> first.toUpperCase().concat(second));
System.out.println(Arrays.toString(array));
// Вывод: [a, Ab, ABc, ABCd]
Метод parallelPrefix() использует преимущества многопоточности для обработки больших массивов более эффективно. Он разбивает задачу на подзадачи, которые могут выполняться параллельно, и объединяет результаты. Это особенно полезно при работе с большими объемами данных, где последовательная обработка может быть слишком медленной.7 991
❓Что нужно вставить на место //insert code here, чтобы гарантировать вывод "123"
7 991
Java используют Сбербанк, «Яндекс Маркет», «Госуслуги». На нём создают приложения для банков, IT-корпораций и стриминговых сервисов, разрабатывают интернет-магазины, игры и облачные решения. Попробуйте себя в роли Java-разработчика, напишите несколько программ и решите, нравится ли вам эта профессия, на бесплатном мини-курсе Skillbox.
Сразу после регистрации дарим гайд по профессии Java-разработчика: 👉 https://epic.st/1kkiZi?erid=2VtzqxFNKRj
Мини-курс подойдёт новичкам разного возраста, а также:
📌 Тем, кто хочет оценить сферу IT
📌 Тем, кто стремится зарабатывать на удалёнке
📌 Разработчикам с небольшим опытом
В программе:
— Основы профессии и языка Java
— Telegram-бот на Java. Запускаем готового бота
— Программа для обработки файлов
— Живой эфир с экспертом по Java
Успейте записаться бесплатно!
Реклама. ЧОУ ДПО «Образовательные технологии «Скилбокс (Коробка навыков)», ИНН: 9704088880
7 991
Настоящий айтишник в отпуск не ходит.
Code Review – кладезь отборных IT-мемасов. Внутри вся будничная жиза: джуна, мидла, сеньора и всех, кто так или иначе связан с айтишкой.
⚠️ Колкий юмор для тех, кто в теме.
Подпишись: @coode_review
7 991
✅ Паттерн Builder или Строитель
Этот паттерн является порождающим и используется для создания объектов с большим количеством необязательных полей.
Паттерн Строитель инкапсулирует конструирование продукта и позволяет разделить его на этапы"Паттерны проектирования" Э. Фриман Давайте на примере: У нас есть класс
Person с обязательным полем name и необязательными полями age и address.
public class Person {
private final String name; // Обязательное
private int age; // Необязательное
private String address; // Необязательное
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.address = builder.address;
}
// Геттеры
public static class Builder {
private final String name;
private int age;
private String address;
public Builder(String name) {
this.name = name;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Person build() {
return new Person(this);
}
}
}
Вложенный класс Builder используется для "поэтапного и инкапсулированного" конструирования объекта Person. Мы можем установить необходимые поля с помощью методов age() и address(), а затем создать объект Person с помощью метода build():
var person = new Person.Builder("John")
.age(30)
.address("My Street")
.build();
Без паттерна Builder нам бы пришлось делать 4 конструктора для двух необязательных полей, чтобы покрыть возможные варианты создания объекта!
Таким образом, шаблон Builder обеспечивает удобный способ создания объектов с различными составом полей, делая код более читаемым и гибким, но будет плохим решением если все поля обязательные.
Кстати, библиотека lombok предлагает очень удобную аннотацию @Builder.
🫡 Секреты Java
#pattern7 991
+6
☄️ Горячая акция для IT-специалистов на дизайн и ремонт квартиры!
RE Design Buro создаем дизайн-проекты и реализуем их в жизнь более 15 лет ⭐️
За это время сделали уже 450+ проектов и ремонтов в Москве и области 🏆
Коротко о компании:
⭐️ работают не бригады, а узкие специалисты: плиточники, электрики, сантехники т.д.
⭐️ 6 месяцев средний срок ремонта.
⭐️ рейтинг выполненных ремонтов - 4.9.
⭐️ все цены и сроки фиксируем в договоре.
⭐️ оплата разбивается частями по факту сдачи работ.
💥 Только для специалистов IT-индустрии - скидка 10% на дизайн и ремонт от компании RE Design Buro
‼️ Важное условие — вы работаете в IT-компании, которая получила аккредитацию Минцифры РФ
👉 Наши работы
👉 Мы в Телеграм
👉 Связаться с нами
👉 Консультация дизайнера БЕСПЛАТНО
👉 Получить сметный расчёт стоимости ремонта
7 991
✅ Кто такой этот ваш classpath?
Classpath является одним из основных параметров в Java, однако его довольно легко понять неправильно. Если говорить простыми словами, то classpath - это набор путей к директориям и JAR-файлам, где компилятор и JVM будут искать классы и ресурсы, необходимые для компиляции/выполнения программы (не по всей же файловой системе они будут это делать, верно?).
Пример:
У нас есть класс
com.demo.Main по пути:
demo\src\com\demo\Main.java
и содержанием:
package com.demo;
import com.orange.Orange;
public class Main {
public static void main(String[] args) {
var orange = new Orange();
System.out.println("Hello world!");
}
}
и класс com.orange.Orange по пути:
lib\com\orange\Orange.java
Что внутри него неважно (коммерческая тайна).
И вот мы хотим запустить нашу программу, т.к. бизнес уже давно этого ждет.
Взволнованные, мы приступаем к компиляции проекта:
javac demo/src/com/demo/Main.java
И тут получаем первую ошибку - компилятор ругается на класс Orange, он о нем ничего не знает.
Окей, говорим ему где искать подключаемые "библиотеки" (предварительно скомпилированный Orange) и указываем компилятору параметр -cp (-classpath):
javac -cp lib/ demo/src/com/demo/Main.java
Ура! Мы успешно скомпилировали наш проект и после этого бежим его запускать:
java -cp demo/src com.demo.Main
И бац! Ошибка выполнения -
Exception in thread "main" java.lang.NoClassDefFoundError: com/orange/Orange
at com.demo.Main.main(Main.java:8)
Caused by: java.lang.ClassNotFoundException: com.orange.Orange
JVM также не может найти класс Orange по classpath (потому что мы его не указали, а указали только путь к Main).
Вообще одна из наиболее частых причин NoClassDefFoundError и ClassNotFoundException - это неверно указанный (или не указанный) classpath.
Не будем мучать JVM и в classpath зададим два пути: для Main и для Orange (список указывается через ";" для Windows/ ":" для Linux):
java -cp demo/src;lib com.demo.Main
И получаем долгожданный вывод:
Hello world!
🫡 Секреты Java
#classpath7 991
Как стать востребованным DevOps-специалистом всего за полгода и увеличить свой доход минимум в 3 раза?
Самое перспективное направление в IT сейчас – DevOps. И пока одни его боятся и обходят стороной, другие снимают все сливки.
Реальный пример – автор канала «Devops за полгода» Марсель Ибраев, Senior system engineer в Core42 Cloud и спикер учебного центра Слёрм.
Совместно с ребятами из Честного Знака, Лаборатории Касперского, VK и Jetty Cloud, они запускают новый крутой проект для всех начинающих DevOps-специалистов.
В канале собраны все фишки о том, как:
– Начать свой путь в DevOps
– Освоить базовые компетенции DevOps-специалиста
– Стать Junior DevOps и повысить свою стоимость на рынке труда в 3 раза
Переходи и забирай бесплатную карту по базовым и основным компетенциям для всех, кто собирается в DevOps 👉 @devopsupgrade
Реклама. ИП Аердинов Никита Вадимович ИНН 638103515932 erid: LjN8K7zVy
