👍12🔥2🌚2
Forwarded from Java библиотека
ConcurrentHashMap – это высокопроизводительная реализация Map, специально разработанная для многопоточной среды. Она гарантирует безопасность данных при одновременном доступе и минимизирует использование блокировок.
- Compare-And-Swap используется для операций записи, что позволяет избегать блокировок для большинства операций. Операции с разными бакетами могут выполняться параллельно, поскольку локальная блокировка применяется только к отдельному узлу или бакету.
- Fine-Grained Locking минимизирует область блокировок. Например, если требуется масштабирование (resize) или обработка коллизий, потоки могут продолжать работу с другими бакетами, даже если один из них временно заблокирован.
- synchronized применяется только для случаев, когда CAS не справляется (например, при реорганизации данных или сложных операциях). Это помогает поддерживать баланс между безопасностью и производительностью.
📚 Основные методы:
Легковесная операция, не требует блокировок. Ключ хэшируется, затем вычисляется индекс сегмента. Если в сегменте есть соответствующий узел, он возвращается.
- Сначала используется CAS для вставки нового элемента.
- Если CAS не срабатывает (например, при наличии коллизии), включается локальная блокировка на соответствующей корзине.
Более сложные операции, которые комбинируют вычисления с модификацией. Используются короткие локи для минимизации блокировки других потоков.
- ConcurrentHashMap не допускает хранения null для ключей и значений. Это связано с невозможностью различать отсутствие значения и реальное хранение null.
- Итерации по карте предоставляют "слабо согласованные" данные, что означает, что изменения, происходящие параллельно, могут быть частично видны.
Документация
@javalib #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4❤1
Builder — это порождающий паттерн, который позволяет пошагово создавать сложные объекты. Вместо того чтобы создавать объект одним большим конструктором с множеством параметров, Builder организует процесс создания по частям, обеспечивая гибкость и читаемость кода.
Использование:
Преимущества:
Недостатки:
@javatasks #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥6🥰3⚡2
Что выведет код?
Anonymous Quiz
66%
1 2 3 4 5 6 7 8 9 10
7%
1 3 2 4 5 6 7 8 9 10
9%
1 2 3 4 3 6 5 7 8 9 10
17%
1 2 3 4 5 1 2 3 4 5 6
👍14
В обычном Java приложении всегда должен быть main class, содержащий метод main. С него начинается исполнение всей программы. Main class-ом может быть не только класс, но и интерфейс или енам. Для JavaFX приложения главный класс должен реализовывать javafx.application.Application.
main обязательно public static. Дополнительно, методу разрешено иметь модификатор strictfp. На аннотации и список исключений ограничений не накладывается.
В главном методе должен быть объявлен единственный аргумент – массив строк. Обе конструкции String[] и String... компилируются в один и тот же байт-код, так что приемлемы оба варианта. Название массива может быть любым, а значение будет содержать аргументы командной строки.
Когда приложение запускается как classpath, главный класс передается параметром командной строки. Если выполняется единственный исходник, он и описывает main class.
Для исполняемого jar-файла (java -jar MyJar.jar), его главный класс должен быть указан в манифесте. Внутри архива, в файл META-INF/MANIFEST.MF добавляется строчка вида Main-Class: ru.itsobes.MyClass. Иначе запуск завершается ошибкой «no main manifest attribute».
В случае, когда в указанном главном классе не оказывается метода, который бы удовлетворял всем критериям главного метода, программа падает с ошибкой «Main method not found».
В апплетах вместо main входной точкой служат методы init и start. Начиная с версии Java 9 технология апплетов объявлена устаревшей, а с 11 – совсем удалена. Не будем останавливаться на них подробнее.
@javatasks #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥4❤3
Что такое функциональный интерфейс?
Так называется специальная разновидность интерфейса, который определяет тип-функцию, коллбэк.
Чтобы компилятор считал интерфейс функциональным, этот интерфейс должен добавлять единственный абстрактный метод. Вдобавок он может содержать любое количество дефолтных методов с телом. Переобъявление методов класса Object также игнорируется.
Никаких других ограничений на метод не накладывается: он не ограничен в типах аргументов и возвращаемого значения, может иметь любое название и список выбрасываемых исключений (checked и unchecked).
Даже при выполнении всех этих условий, никакие другие разновидности типов кроме interface не могут считаться функциональными интерфейсами.
Дополнительно функциональный интерфейс принято помечать аннотацией @FunctionalInterface. Наличие этой аннотации не необходимо, но оно даёт дополнительную валидацию: её присутствие на нефункциональном типе спровоцирует ошибку компиляции.
Типичные примеры функциональных интерфейсов: Callable, Supplier, Comparable.
@javatasks #java
Так называется специальная разновидность интерфейса, который определяет тип-функцию, коллбэк.
Чтобы компилятор считал интерфейс функциональным, этот интерфейс должен добавлять единственный абстрактный метод. Вдобавок он может содержать любое количество дефолтных методов с телом. Переобъявление методов класса Object также игнорируется.
Никаких других ограничений на метод не накладывается: он не ограничен в типах аргументов и возвращаемого значения, может иметь любое название и список выбрасываемых исключений (checked и unchecked).
Даже при выполнении всех этих условий, никакие другие разновидности типов кроме interface не могут считаться функциональными интерфейсами.
Дополнительно функциональный интерфейс принято помечать аннотацией @FunctionalInterface. Наличие этой аннотации не необходимо, но оно даёт дополнительную валидацию: её присутствие на нефункциональном типе спровоцирует ошибку компиляции.
Типичные примеры функциональных интерфейсов: Callable, Supplier, Comparable.
@javatasks #java
❤11👍5🔥3
Что будет результатом кода?
Anonymous Quiz
12%
Final counter value: 1000
48%
Final counter value: 2000
11%
Final counter value: *любое число*
16%
Final counter value: *число менее 2000, но более 1000*
14%
Ошибка компиляции
👍7🔥5❤2
Как инициализировать переменную функционального интерфейса?
Функциональный интерфейс – всё ещё интерфейс, поэтому остаются доступными стандартные способы. Интерфейс можно реализовать обычным классом, и затем создать его экземпляр оператором new. Можно совместить эти два действия, и создать экземпляр анонимного класса.
Основное преимущество, которое дает функциональный интерфейс – два дополнительных способа инициализации параметров и переменных.
1. Лямбда-выражение: (x, y) -> x * y
2. Ссылка на метод: Math::sqrt
На эти способы накладывается небольшое ограничение: тип функционального параметра/переменной должен быть указан явно. Это значит, что лямбдой или метод-референсом нельзя инициализировать переменную, объявленную ключевым словом var. Также, чтобы передать лямбду или референс в параметр generic-типа, этот тип должен быть ограничен функциональным интерфейсом (должен стираться в него).
@javatasks #java
Функциональный интерфейс – всё ещё интерфейс, поэтому остаются доступными стандартные способы. Интерфейс можно реализовать обычным классом, и затем создать его экземпляр оператором new. Можно совместить эти два действия, и создать экземпляр анонимного класса.
Основное преимущество, которое дает функциональный интерфейс – два дополнительных способа инициализации параметров и переменных.
1. Лямбда-выражение: (x, y) -> x * y
2. Ссылка на метод: Math::sqrt
На эти способы накладывается небольшое ограничение: тип функционального параметра/переменной должен быть указан явно. Это значит, что лямбдой или метод-референсом нельзя инициализировать переменную, объявленную ключевым словом var. Также, чтобы передать лямбду или референс в параметр generic-типа, этот тип должен быть ограничен функциональным интерфейсом (должен стираться в него).
@javatasks #java
🔥11🎉3❤2
Задачи с собеседований: Проверка, является ли бинарное дерево деревом поиска (middle)
— Как определить, является ли заданное бинарное дерево деревом поиска (BST)?
📌 Ключевые моменты:
- Бинарное дерево поиска (BST) — это бинарное дерево, в котором для каждого узла все значения в левом поддереве меньше значения узла, а все значения в правом поддереве больше.
- Для проверки можно использовать рекурсивный подход с отслеживанием допустимых диапазонов значений для каждого узла.
- Как изменить реализацию для работы с любыми типами данных в узлах дерева?
Реализация с числами в узлах на картинке👆
@javatasks #java
— Как определить, является ли заданное бинарное дерево деревом поиска (BST)?
- Бинарное дерево поиска (BST) — это бинарное дерево, в котором для каждого узла все значения в левом поддереве меньше значения узла, а все значения в правом поддереве больше.
- Для проверки можно использовать рекурсивный подход с отслеживанием допустимых диапазонов значений для каждого узла.
- Как изменить реализацию для работы с любыми типами данных в узлах дерева?
Реализация с числами в узлах на картинке
@javatasks #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥5❤3
Какой компонент в Аpache Kafka отвечает за сохранение сообщений в топиках?
Anonymous Quiz
10%
Consumer
20%
Producer
47%
Broker
17%
Zookeeper
6%
Controller
🔥10👍5🌚2😐2
Forwarded from Java библиотека
Фасад — это структурный паттерн, который предоставляет унифицированный интерфейс для работы с набором сложных подсистем. Он скрывает сложность системы и упрощает взаимодействие с ней, предоставляя более простой и понятный API для клиента.
Использование:
Преимущества:
Недостатки:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤3🔥2
Что можно импортировать статически?
Обычный импорт избавляет от необходимости писать полное имя классов: при использовании можно не указывать пакет. Статические импорты делает то же самое, но для статических членов класса.
Самое распространенное применение статического импорта – включение констант из константных интерфейсов и статических методов из утилитарных классов. Но также можно включать и изменяемые статические поля других классов.
Отдельно интересен случай nested-класса. Он одновременно является и классом, и статическим членом другого класса. Поэтому для него работает как обычный, так и статический импорт.
Языковая конструкция static import обязана располагаться там же, где и обычные импорты – обязательно между package и объявлением основного класса файла.
Java Guru🤓 #java
Обычный импорт избавляет от необходимости писать полное имя классов: при использовании можно не указывать пакет. Статические импорты делает то же самое, но для статических членов класса.
Самое распространенное применение статического импорта – включение констант из константных интерфейсов и статических методов из утилитарных классов. Но также можно включать и изменяемые статические поля других классов.
Отдельно интересен случай nested-класса. Он одновременно является и классом, и статическим членом другого класса. Поэтому для него работает как обычный, так и статический импорт.
Языковая конструкция static import обязана располагаться там же, где и обычные импорты – обязательно между package и объявлением основного класса файла.
Java Guru🤓 #java
🔥9👍5❤4
Что будет результатом кода?
Anonymous Quiz
24%
Ошибка компиляции
4%
RuntimeException
59%
1 2 3 4
3%
1| 2| 3| 4|
10%
ClassCastException
👍14🔥2❤1
Для чего нужно ключевое слово super?
Как и многие другие ключевые слова, super имеет несколько разных значений в зависимости от контекста:
1. Задать нижнюю границу generic-типа: Consumer<? super Number>
2. Обратиться к члену класса-родителя, который перекрыт (shadowed) членами наследника или локальными переменными: int foo = super.foo
3. Вызвать в конструкторе конструктор родителя: SubClass() { super("subclass param"); }
4. В случае неопределенности, уточнить родительский тип (на картинке)
Java Guru🤓 #java
Как и многие другие ключевые слова, super имеет несколько разных значений в зависимости от контекста:
1. Задать нижнюю границу generic-типа: Consumer<? super Number>
2. Обратиться к члену класса-родителя, который перекрыт (shadowed) членами наследника или локальными переменными: int foo = super.foo
3. Вызвать в конструкторе конструктор родителя: SubClass() { super("subclass param"); }
4. В случае неопределенности, уточнить родительский тип (на картинке)
Java Guru🤓 #java
👍14❤4🔥3
Что будет результатом кода?
Anonymous Quiz
35%
Ошибка компиляции
5%
Java Top!
42%
Jao
8%
Jv T!
11%
RuntimeException
🔥12👍6
Можно ли переопределить статический метод?
Отвечая на этот вопрос, необходимо аккуратно обращаться с терминологией перегрузки и переопределения.
На перегрузку (overload) статического метода не накладывается никаких ограничений. С точки зрения компилятора, методы с разным списком аргументов – разные методы. Но это не переопределение.
Метод с модификатором static относится к классу, а не к его объектам. Для него работает статическое связывание, поэтому именно переопределение (override) в дочернем классе не работает.
Несмотря на это, в дочернем классе можно объявить static метод с такой же сигнатурой, как в родительском. В этом случае произойдет не перегрузка и не переопределение, а перекрытие (shadowing). К такому методу нельзя применить аннотацию @Override, в нём нельзя использовать ключевое слово super.
Если вы вызываете статический метод от переменной, а не типа, перекрытие таит в себе опасность. Без динамического связывания компилятор знает только о типе переменной, но не о типе ее значения. Если объявленный тип переменной – базовый класс, то метод-перекрытие никогда не вызовется. Поэтому при попытке такого вызова в IDE мы видим предупреждение.
Java Guru🤓 #java
Отвечая на этот вопрос, необходимо аккуратно обращаться с терминологией перегрузки и переопределения.
На перегрузку (overload) статического метода не накладывается никаких ограничений. С точки зрения компилятора, методы с разным списком аргументов – разные методы. Но это не переопределение.
Метод с модификатором static относится к классу, а не к его объектам. Для него работает статическое связывание, поэтому именно переопределение (override) в дочернем классе не работает.
Несмотря на это, в дочернем классе можно объявить static метод с такой же сигнатурой, как в родительском. В этом случае произойдет не перегрузка и не переопределение, а перекрытие (shadowing). К такому методу нельзя применить аннотацию @Override, в нём нельзя использовать ключевое слово super.
Если вы вызываете статический метод от переменной, а не типа, перекрытие таит в себе опасность. Без динамического связывания компилятор знает только о типе переменной, но не о типе ее значения. Если объявленный тип переменной – базовый класс, то метод-перекрытие никогда не вызовется. Поэтому при попытке такого вызова в IDE мы видим предупреждение.
Java Guru🤓 #java
👍19🔥4❤2