Java Learning
18.7K subscribers
1.62K photos
1 video
3 files
998 links
№ 5079899194

Обучающий канал по Java

Ссылка для друга - https://t.iss.one/+ZEYYht6-46w5MDM6

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

Реклама на бирже - https://telega.in/c/Java_per_month
Download Telegram
#Вопросы_с_собеседования
🚩 Можете ли вы объяснить, как работает механизм 'Double Brace Initialization' в Java и в каких случаях его использование может быть неэффективным?

Механизм "Double Brace Initialization" в Java - это способ инициализации объектов, основанный на анонимных внутренних классах, где первые фигурные скобки создают анонимный подкласс, а вторые - блок инициализации. Этот подход может быть неэффективным из-за создания дополнительного класса для каждого использования, что увеличивает использование памяти и может затруднить чтение кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Конвертируем массив в список

Arrays.asList() — это статический метод класса Arrays, который позволяет конвертировать обычный массив в список List.

— Принимает массив в качестве аргумента и возвращает объект типа List с элементами этого массива.

— Возвращаемый список имеет фиксированный размер, равный длине исходного массива. Добавлять/удалять элементы в него нельзя.

— Изменения в возвращаемом списке будут вноситься в исходный массив, т. к. список работает как "представление" массива. Метод работает для массивов примитивных и ссылочных типов.

Arrays.asList хорош для чтения элементов массива, но не для записи из-за неизменяемого размера.
👍10🎄1
Micronaut

Micronaut — это современный фреймворк для создания микросервисных приложений на языке Java, Kotlin и Groovy. Он разрабатывался с учетом требований эффективности, производительности и легковесности.

— Легковесность: Micronaut предлагает низкоресурсное потребление благодаря тому, что многие операции выполняются во время компиляции, а не во время выполнения. Это позволяет создавать быстрые и эффективные приложения.
— Инъекция зависимостей во время компиляции: В отличие от многих других фреймворков, которые используют внедрение зависимостей во время выполнения, Micronaut выполняет внедрение зависимостей во время компиляции, что повышает производительность.
— Встроенная поддержка для микросервисной архитектуры: Micronaut предоставляет инструменты и функциональность для создания микросервисов, включая обработку HTTP-запросов, масштабирование и управление конфигурацией.
— Поддержка различных протоколов: Micronaut поддерживает различные протоколы взаимодействия, такие как HTTP, WebSocket, gRPC, RMI и многие другие.
— Встроенная поддержка тестирования: Фреймворк обеспечивает инструменты для написания и запуска тестов, что упрощает разработку надежных приложений.

Для подробной информации о Micronaut и примеров использования рекомендуется обратиться к официальной документации Micronaut.

#для_продвинутых
👍12🤔1
Вложенные классы

Вложенные классы (nested classes) представляют собой классы, объявленные внутри других классов. Вложенные классы могут быть статическими или нестатическими, и они могут использоваться для логической организации кода, повышения инкапсуляции и улучшения читаемости.

Статические вложенные классы (Static Nested Classes):

— Статический вложенный класс объявляется с использованием ключевого слова static.
— Он имеет доступ только к статическим членам внешнего класса и не имеет доступа к нестатическим членам.
— Статические вложенные классы используются, когда внутренний класс не зависит от экземпляра внешнего класса.

Внутренние классы (Inner Classes):

— Внутренние классы не объявляются с использованием ключевого слова static.
— Они имеют доступ ко всем членам внешнего класса, включая нестатические поля и методы.
— Внутренние классы могут быть обычными (обычные вложенные классы), анонимными или локальными.

#для_начинающих
👍8
#Вопросы_с_собеседования

🎙️ Какие два класса не наследуются от Object?

Ответ:
Не ведитесь на провокации, нет таких классов: все классы прямо или через предков наследуются от класса Object!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍49😁11🤔1
#Вопросы_с_собеседования
Реализуйте простой кэш на Java. Класс должен поддерживать операции добавления значения по ключу, получения значения по ключу и удаления значения по ключу. Кэш должен иметь фиксированный размер, и при превышении этого размера он должен удалять самый старый элемент. Как вы обеспечите оптимальную производительность операций?


Решение:

Кэш будет представлять собой обобщенный класс
SimpleCache, который может хранить пары ключ-значение. Размер кэша будет ограничен, чтобы избежать переполнения. В случае превышения размера, самый старый элемент будет удаляться.
Для хранения данных будем использовать
HashMap (cache), так как это обеспечит эффективный доступ к значениям по ключу. Для отслеживания порядка ключей (чтобы определить самый старый элемент) будем использовать Queue (keyQueue), в данном случае LinkedList.

Инициализируем кэш. Конструктор
SimpleCache принимает максимальный размер кэша и инициализирует cache и keyQueue. Добавляем элемент в кэш и при добавлении элемента проверяем, не превышен ли максимальный размер. Если превышен, вызываем метод evictOldest для удаления самого старого элемента.
Добавляем новый элемент в
cache и помещаем ключ в keyQueue. Получаем элемент по ключу. Если элемент существует в кэше, перемещаем соответствующий ключ в конец keyQueue (чтобы отметить последнее использование) и возвращаем значение. Удаляем элемент из cache и соответствующий ключ из keyQueue. Получаем самый старый ключ из начала keyQueue, удаляем соответствующий элемент из cache.
👍124
Есть ли смысл использовать лямбды в Java в целях оптимизации, или это только для улучшения читабельности кода?
Anonymous Quiz
35%
Только улучшение читабельности
40%
Есть смысл использовать всегда, так как это более оптимально
25%
Есть смысл использовать только в циклах вместо анонимных классов
👍6
Класс ZonedDateTime

Класс ZonedDateTime предоставляет функциональность для представления даты и времени с учетом временной зоны. Этот класс входит в пакет java.time, который был представлен в Java 8 в рамках нового API времени и даты.

Как видно из примера, ZonedDateTime учитывает временную зону (в данном случае, ZoneId.of("Europe/Paris")). Вы также можете использовать другие методы для манипуляций с датой и временем, такие как plusDays, minusHours, и т. д.

Класс ZonedDateTime особенно полезен, когда вам нужно учитывать временные зоны при работе с датой и временем в приложении.

#для_начинающих
👍10
#Вопросы_с_собеседования
Расскажите о принципе работы алгоритма сортировки QuickSort. Напишите Java-код для реализации этого алгоритма и объясните его эффективность. Также, укажите, какие могут быть проблемы с производительностью в некоторых случаях и как можно их решить.


Алгоритм QuickSort относится к семейству алгоритмов быстрой сортировки. Он использует подход "разделяй и властвуй", разбивая массив на подмассивы, сортируя их и затем объединяя весь массив.
quickSort: Рекурсивная функция, которая разделяет массив и вызывает сама себя для подмассивов.
partition: Функция, которая определяет местоположение опорного элемента (pivot) и переставляет элементы так, чтобы элементы меньше pivot находились слева, а больше — справа.

QuickSort в среднем случае имеет сложность O(n log n), что делает его одним из самых эффективных алгоритмов сортировки. QuickSort может показывать плохую производительность в случае уже отсортированных или почти отсортированных данных. Это может быть улучшено, выбирая разумные опорные элементы или переходя к другому алгоритму, например, Insertion Sort, для небольших подмассивов.
👍14
#Вопросы_с_собеседования
Реализуйте в Java класс, представляющий стек (stack), который поддерживает операции push, pop и получение минимального элемента (getMin) — все операции должны выполняться за константное время (O(1)). Напишите код и объясните, как вы решите эту задачу.


Объяснение:

В этом коде используется два стека: stack для хранения элементов стека и minStack для хранения минимальных элементов.
В методе push, при добавлении нового элемента в стек проверяется, является ли он минимальным. Если да, то он также добавляется в minStack.
В методе pop, при извлечении элемента из стека проверяется, является ли этот элемент минимальным. Если да, то он также удаляется из minStack.
Методы top и getMin просто возвращают верхний элемент стека и минимальный элемент соответственно.

Сложность:
Временная сложность для всех операций: O(1). Все операции выполняются за константное время, так как мы используем два стека и не производим поиск по всему стеку для поиска минимального элемента.

Пространственная сложность: O(n). Где n — количество элементов в стеке. Мы используем два стека, но их размер ограничен размером стека.
👍14
#Вопросы_с_собеседования
Как в Java реализуется принцип "Double-Checked Locking" в контексте создания экземпляров синглтонов и какие особенности данного подхода нужно учитывать, чтобы избежать проблем с многопоточностью?

В Java, "Double-Checked Locking" используется для минимизации затрат на синхронизацию при создании экземпляров синглтонов в многопоточных средах. Этот подход включает двойную проверку: сначала проверяется, был ли уже создан экземпляр без блокировки, а затем, если экземпляр не создан, происходит блокировка и повторная проверка. Важно использовать ключевое слово volatile для переменной экземпляра синглтона, чтобы обеспечить корректную работу в многопоточной среде из-за проблем с упорядоченностью чтения/записи в Java Memory Model.
👍19
Почему Map не наследуется от Collection?

Это связано с различиями в их целях и использовании. Интерфейс Collection представляет собой общие методы для работы с группой объектов, таких как добавление, удаление и проверка наличия элемента. Он ориентирован на работу с коллекциями объектов, где каждый объект является элементом коллекции.

Интерфейс Map, с другой стороны, представляет собой отображение ключей на значения. Он не рассматривает элементы коллекции как отдельные объекты, а предоставляет доступ к значению, связанному с определенным ключом. Это более общий и мощный подход, который не сводится к работе с отдельными элементами коллекции.

Интерфейс Map включает в себя методы для управления парами ключ-значение и обеспечивает эффективный доступ к значениям по ключу. По этим причинам он не является подтипом Collection. Однако, классы, реализующие интерфейс Map, часто предоставляют методы, которые позволяют работать с элементами коллекции или возвращают представление коллекции ключей, значений или записей (ключ-значение).

Таким образом, хотя Map и Collection предоставляют абстракции для работы с группой объектов, они решают разные задачи, и поэтому не существует иерархического отношения наследования между ними.

#для_продвинутых
👍18
#Вопросы_с_собеседования
Расскажите о принципе Dependency Injection (внедрение зависимостей) в Java. Приведите пример кода, демонстрирующий использование Dependency Injection, и объясните, как его.


Объяснение:

Dependency Injection (внедрение зависимостей) — это паттерн проектирования, который заключается в том, что объект получает все свои зависимости извне, а не создает их сам. Это делает классы более независимыми, повышает их переиспользуемость и упрощает тестирование.

1. Интерфейс Engine: Определяет контракт для всех типов двигателей.
2. Реализация GasolineEngine: Конкретная реализация интерфейса Engine.
3. Класс Car: Класс автомобиля, зависящий от интерфейса Engine. Зависимость внедряется через конструктор. Мы можем легко заменить GasolineEngine другой реализацией Engine без изменения кода класса Car.
👍193
#Вопросы_с_собеседования
Объясните принципы работы Java Garbage Collection. Какие виды сборщиков мусора существуют в Java? Напишите код с утечкой памяти и объясните, как ее можно обнаружить и предотвратить.


Ответ:

В Java, управление памятью осуществляется автоматически с помощью механизма сборки мусора. Основные принципы работы:

— JVM отслеживает все активные ссылки на объекты в программе.
— Определение мертвых объектов: Объект считается мертвым (готовым к удалению), если на него нет активных ссылок.
— JVM автоматически освобождает память, занятую мертвыми объектами.

Виды сборщиков мусора в Java:

Serial Collector (Serial GC): Однопоточный, используется в небольших приложениях или на однопроцессорных системах.
Parallel Collector (Parallel GC): Многопоточный, предназначен для многопроцессорных систем.
Concurrent Mark-Sweep (CMS) Collector: Позволяет сократить время простоя приложения, так как многие его этапы выполняются параллельно с работой приложения.
G1 (Garbage-First) Collector: Пытается сбалансировать время простоя приложения и эффективность сборки.

Обнаружение и предотвращение утечек памяти:

— Инструменты профилирования, такие как VisualVM или YourKit, могут помочь обнаружить утечки памяти.
— Внимательный анализ кода с использованием статических анализаторов, таких как FindBugs или SonarQube, может выявить потенциальные проблемы.
— Для ресурсов, реализующих интерфейс AutoCloseable (например, InputStream), следует использовать try-with-resources для автоматического освобождения ресурсов.
— Важно убедиться, что ресурсы (файлы, сетевые соединения и т. д.) освобождаются явным образом, например, в блоке finally.
— Если объект может быть удален, даже если на него есть ссылки, рассмотрите использование weak-ссылок, таких как WeakReference или SoftReference.
— Объединение жизненных циклов объектов помогает предотвратить утечки памяти. Например, закрывайте ресурсы вместе с объектом, который их использует.
👍222
#Вопросы_с_собеседования
Расскажите о принципах работы и применении ExecutorService в Java для управления потоками. Приведите пример использования ExecutorService.


Ответ:

ExecutorService — это фреймворк в Java для управления выполнением потоков. Он предоставляет высокоуровневый интерфейс для управления потоками, скрывая детали создания, управления и завершения потоков.

Преимущества:

— Управление пулом потоков.
— Переиспользование потоков.
— Управление жизненным циклом потоков.

Объяснение:

Executors.newFixedThreadPool(2): Создание пула потоков с фиксированным числом (в данном случае, 2) потоков.
executorService.execute(...): Подача задач на выполнение. ExecutorService автоматически управляет потоками из пула для выполнения этих задач.
shutdown(): Вызывается для завершения работы ExecutorService после завершения всех задач. После вызова shutdown, ExecutorService больше не принимает новые задачи, но выполняет ранее добавленные.

Примечание:

ExecutorService предоставляет также методы для выполнения задач с возвращаемым значением, планирования задач на определенное время и другие возможности управления потоками. Он является частью более общего фреймворка управления выполнением (Executor framework) в Java.
👍163
#Вопросы_с_собеседования
Объясните принципы работы и применение «стримов» (streams) в Java. Какие операции можно выполнять с использованием стримов? Приведите пример кода с использованием стримов.


Ответ:

Стримы представляют собой последовательность элементов, которую можно обрабатывать функциональными операциями. Стримы применяют в фильтрации для выборки элементов, для отображения (Mapping), сортировки и свертки (Reduction).

Объяснение кода:


words.stream(): Создание стрима из списка слов.
.filter(word -> word.length() > 5): Фильтрация слов, оставляя только те, у которых длина больше 5 символов.
.map(String::toUpperCase): Преобразование каждого слова в верхний регистр.
.sorted(): Сортировка слов.
.collect(Collectors.toList()): Сбор результатов в список.
Результат выводится на экран: [BANANA, ORANGE].
👍20
TimeUnit

TimeUnit — этоперечисление (enum), которое предоставляет удобные константы для работы с временем. Этот класс обычно используется вместе с классом ExecutorService из пакета java.util.concurrent для управления временем ожидания выполнения задач.

TimeUnit содержит константы для различных временных единиц, таких как наносекунды, микросекунды, миллисекунды, секунды, минуты и часы. Он предоставляет методы для конвертации времени из одной единицы в другую.

#для_продвинутых
👍18
#Вопросы_с_собеседования
Объясните процесс загрузки, инициализации, выполнения и выгрузки класса в Java Virtual Machine (JVM). Какие шаги выполняются на каждом этапе?


Ответ:

Загрузка (Loading):
— Нахождение и загрузка класс-файла: Class Loader ищет и загружает байт-код класса из файловой системы, JAR-архива, сети или другого источника.
— Создание структур данных: Создаются структуры данных для представления класса в памяти JVM, такие как Class объект.

Подготовка (Preparation):
— Выделение памяти для статических переменных: Выделяется память для статических переменных, инициализированных значением по умолчанию.

Инициализация (Initialization):
— Инициализация статических переменных и выполнение статических блоков: Статические переменные получают значения из кода инициализации, выполняются статические блоки.

Выполнение (Execution):
— Вызов метода main(): Если класс содержит метод public static void main(String[] args), JVM вызывает этот метод для выполнения программы.
— Вызов других методов: JVM вызывает другие методы по мере необходимости.

Выгрузка (Unloading):
— Освобождение памяти: Если класс больше не используется и нет активных ссылок на его объекты, JVM может выгрузить класс и освободить память.
👍21
RejectedExecutionHandler

RejectedExecutionHandler — это интерфейс, используемый для определения стратегии обработки задач, когда они не могут быть приняты для выполнения в пуле потоков. Этот интерфейс содержит единственный метод rejectedExecution, который вызывается, когда пул потоков не может принять задачу. Разработчики могут предоставить свою реализацию RejectedExecutionHandler для определения способа обработки отклоненных задач.

#для_продвинутых
👍10
RecursiveTask<V>

RecursiveTask<V> является частью фреймворка Fork/Join в Java, введенного в Java 7. Этот фреймворк предоставляет удобный способ распараллеливания выполнения задач.

RecursiveTask<V> является подклассом ForkJoinTask<V>. Он предназначен для использования вместе с пулом Fork/Join (ForkJoinPool) и предоставляет специальные методы для разделения задачи на подзадачи и объединения результатов.

#для_продвинутых
👍9