Приведите примеры использования fork/join framework
Как следует из названий связанных классов, ForkJoinPool используется для рекурсивных задач. Это такие задачи, которые можно делить на порции, подзадачи. Отделение подзадачи — это операция fork, финальная агрегация результатов подзадач — join.
Реализация fork/join для самых популярных общих случаев уже есть в стандартной библиотеке, работать непосредственно с классом ForkJoinPool не потребуется. Метод parallelSetAll из класса Arrays применяет fork/join для генерации элементов массива; parallelPrefix для модификации; parallelSort для сортировки.
Фреймворк неявно работает и в параллельных стримах. В этом случае логику fork определяет его сплитератор, а join выполняют потоковые операции. Классический пример:
Arrays.stream(new int[]{1, 2, 3, 4}).parallel().sum();
Существуют целые категории частных задач, решения которых хорошо параллелизуются: векторные операции, работа с графами, поиск данных. Для специфичных задач придется реализовывать собственные RecursiveTask, RecursiveAction или Spliterator.
Как следует из названий связанных классов, ForkJoinPool используется для рекурсивных задач. Это такие задачи, которые можно делить на порции, подзадачи. Отделение подзадачи — это операция fork, финальная агрегация результатов подзадач — join.
Реализация fork/join для самых популярных общих случаев уже есть в стандартной библиотеке, работать непосредственно с классом ForkJoinPool не потребуется. Метод parallelSetAll из класса Arrays применяет fork/join для генерации элементов массива; parallelPrefix для модификации; parallelSort для сортировки.
Фреймворк неявно работает и в параллельных стримах. В этом случае логику fork определяет его сплитератор, а join выполняют потоковые операции. Классический пример:
Arrays.stream(new int[]{1, 2, 3, 4}).parallel().sum();
Существуют целые категории частных задач, решения которых хорошо параллелизуются: векторные операции, работа с графами, поиск данных. Для специфичных задач придется реализовывать собственные RecursiveTask, RecursiveAction или Spliterator.
Сколько объектов станут доступны для сборщика мусора после выполнения строки 1?
Anonymous Quiz
32%
1
31%
5
32%
6
6%
11
Что вы знаете о функции main()?
Метод main() — точка входа в программу. В приложении может быть несколько таких методов. Если метод отсутствует, то компиляция возможна, но при запуске будет получена ошибка Error: Main method not found.
Метод main() — точка входа в программу. В приложении может быть несколько таких методов. Если метод отсутствует, то компиляция возможна, но при запуске будет получена ошибка Error: Main method not found.
🧑💻 Статьи для IT: как объяснять и распространять значимые идеи
Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.
Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.
Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.
👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.
Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.
Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.
👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
Способы передачи параметров
В языках программирования существует два основных способа передачи параметров в методы (или функции) — «по значению» и «по ссылке». Эти методы определяют, каким образом изменения, внесенные в параметр внутри метода, влияют на исходное значение аргумента, переданного методу. Рассмотрим оба способа более подробно.
📌 Передача параметра «по значению» (pass-by-value):
В этом способе исходное значение параметра не изменяется внутри метода. Метод работает с копией значения параметра. Это означает, что любые изменения, внесенные в параметр внутри метода, не отразятся на исходном значении, переданном методу. Параметры передаются «по значению» в большинстве простых типов данных.
📌 Передача параметра «по ссылке» (pass-by-reference):
В этом случае метод получает не копию значения параметра, а ссылку на сам объект или переменную. Если метод изменяет значение параметра, это изменение отразится на исходном объекте или переменной, переданной методу. Параметры передаются «по ссылке» в языках программирования, поддерживающих ссылки на объекты, как например в языке C++ с использованием указателей.
Понимание разницы между передачей параметра «по значению» и «по ссылке» важно для правильной работы и отладки программ. В разных языках программирования могут быть разные правила для передачи параметров, поэтому важно знать, какой механизм используется в конкретном языке.
В Java передача всегда происходит «по значению», то есть содержимое переменной копируется при передаче в метод. Но важно понимать, что при передаче переменной ссылочного типа (любой не примитивный тип), скопируется именно ссылка на объект (а не сам объект) и соответственно в методе можно поменять сам исходный (переданный) объект.
В языках программирования существует два основных способа передачи параметров в методы (или функции) — «по значению» и «по ссылке». Эти методы определяют, каким образом изменения, внесенные в параметр внутри метода, влияют на исходное значение аргумента, переданного методу. Рассмотрим оба способа более подробно.
📌 Передача параметра «по значению» (pass-by-value):
В этом способе исходное значение параметра не изменяется внутри метода. Метод работает с копией значения параметра. Это означает, что любые изменения, внесенные в параметр внутри метода, не отразятся на исходном значении, переданном методу. Параметры передаются «по значению» в большинстве простых типов данных.
📌 Передача параметра «по ссылке» (pass-by-reference):
В этом случае метод получает не копию значения параметра, а ссылку на сам объект или переменную. Если метод изменяет значение параметра, это изменение отразится на исходном объекте или переменной, переданной методу. Параметры передаются «по ссылке» в языках программирования, поддерживающих ссылки на объекты, как например в языке C++ с использованием указателей.
Понимание разницы между передачей параметра «по значению» и «по ссылке» важно для правильной работы и отладки программ. В разных языках программирования могут быть разные правила для передачи параметров, поэтому важно знать, какой механизм используется в конкретном языке.
В Java передача всегда происходит «по значению», то есть содержимое переменной копируется при передаче в метод. Но важно понимать, что при передаче переменной ссылочного типа (любой не примитивный тип), скопируется именно ссылка на объект (а не сам объект) и соответственно в методе можно поменять сам исходный (переданный) объект.
Что выведет код? public static void main(String[] args) { int a = 5; System.out.println(a % 2); }
Anonymous Quiz
64%
1
27%
2
6%
2,5
3%
unhandled exception
Immutable Classes (неизменяемые классы)
Неизменяемость — это характеристика объектов Java, которая делает их неизменными для будущих изменений после их инициализации. Его внутреннее состояние невозможно никак изменить. Чтобы изменить состояние, мы должны создать новую копию такого объекта с предполагаемыми изменениями.
Рассмотрим класс java.lang.String, который является неизменяемым классом. После создания строки мы не сможем изменить содержимое этой строки. Каждый общедоступный API в классе String возвращает новую строку с измененным содержимым. Исходная строка всегда остается неизменной.
Рекомендации по созданию неизменяемых классов:
🧠 Не определять сеттеров. Сеттеры предназначены для изменения состояния объекта, которое мы здесь хотим предотвратить.
🧠 Сделайте все поля final и private. Поля, объявленные private, не будут доступны за пределами класса, и если сделать их final, мы не сможем изменить их даже случайно.
🧠 Не позволяйте подклассам переопределять методы. Самый простой способ — объявить класс как final. final классы не могут быть расширены.
🧠 Особое внимание «неизменяемым классам с изменяемыми полями». Всегда помните, что поля-члены могут быть либо изменяемыми, либо неизменяемыми. Значения неизменяемых членов (примитивы, классы-обёртки, строки и т. д.) могут быть безопасно возвращены из геттеров. Для изменяемых членов (POJO, коллекций и т. д.) мы должны скопировать содержимое в новый объект перед возвратом из геттера.
Некоторые неизменяемые классы из JDK:
👉 String
👉 Integer, Long, Double и другие обёртки
👉 BigInteger, BigDecimal
👉 enum
👉 record
👉 LocalDate, LocalTime и другие классы Java 8 Date Time API
Неизменяемость — это характеристика объектов Java, которая делает их неизменными для будущих изменений после их инициализации. Его внутреннее состояние невозможно никак изменить. Чтобы изменить состояние, мы должны создать новую копию такого объекта с предполагаемыми изменениями.
Рассмотрим класс java.lang.String, который является неизменяемым классом. После создания строки мы не сможем изменить содержимое этой строки. Каждый общедоступный API в классе String возвращает новую строку с измененным содержимым. Исходная строка всегда остается неизменной.
Рекомендации по созданию неизменяемых классов:
🧠 Не определять сеттеров. Сеттеры предназначены для изменения состояния объекта, которое мы здесь хотим предотвратить.
🧠 Сделайте все поля final и private. Поля, объявленные private, не будут доступны за пределами класса, и если сделать их final, мы не сможем изменить их даже случайно.
🧠 Не позволяйте подклассам переопределять методы. Самый простой способ — объявить класс как final. final классы не могут быть расширены.
🧠 Особое внимание «неизменяемым классам с изменяемыми полями». Всегда помните, что поля-члены могут быть либо изменяемыми, либо неизменяемыми. Значения неизменяемых членов (примитивы, классы-обёртки, строки и т. д.) могут быть безопасно возвращены из геттеров. Для изменяемых членов (POJO, коллекций и т. д.) мы должны скопировать содержимое в новый объект перед возвратом из геттера.
Некоторые неизменяемые классы из JDK:
👉 String
👉 Integer, Long, Double и другие обёртки
👉 BigInteger, BigDecimal
👉 enum
👉 record
👉 LocalDate, LocalTime и другие классы Java 8 Date Time API
Анонимные классы
Система, которая позволяет создавать объекты «без название». Мы создаём экземпляр, передаём его в метод и всё.
В примере мы могли бы создать три отдельных класса, наследуемых от MonitoringSystem, но ради чего? Они используются только один раз.
Анонимные классы — элегантное решение данной проблемы, но во всём надо знать меру.
Система, которая позволяет создавать объекты «без название». Мы создаём экземпляр, передаём его в метод и всё.
В примере мы могли бы создать три отдельных класса, наследуемых от MonitoringSystem, но ради чего? Они используются только один раз.
Анонимные классы — элегантное решение данной проблемы, но во всём надо знать меру.
Arrays.toString() и Arrays.deepToString()
В Java массивы не переопределяют toString(), поэтому, если вы попытаетесь напечатать его напрямую, вы получите имя класса + '@' + шестнадцатеричный хеш-код массива, как определено в Object.toString().
Но обычно нам на самом деле нужно что бы напечаталось содержимое массива. Самый простой способ это сделать, это воспользоваться методом Arrays.toString(). А если массив содержит другие массивы, то Arrays.deepToString().
Внутри этих методов на каждом элементе массива вызывается метод toString() для получения строкового представления.
В Java массивы не переопределяют toString(), поэтому, если вы попытаетесь напечатать его напрямую, вы получите имя класса + '@' + шестнадцатеричный хеш-код массива, как определено в Object.toString().
Но обычно нам на самом деле нужно что бы напечаталось содержимое массива. Самый простой способ это сделать, это воспользоваться методом Arrays.toString(). А если массив содержит другие массивы, то Arrays.deepToString().
Внутри этих методов на каждом элементе массива вызывается метод toString() для получения строкового представления.
Класс Scanner — инструмент (часть пакета java.util) для считывания данных из различных источников: стандартный ввод, файлы и строки.
Основные методы и возможности класса Scanner включают:
🔻 nextInt(), nextLong(), nextDouble() считывают числа, а next() и nextLine() считывают строки.
🔻 Управление разделителями: метод useDelimiter(String pattern) позволяет настроить пользовательский разделитель для ввода, по умолчанию Scanner использует пробелы как разделители.
🔻 Проверка наличия данных: методы hasNextInt(), hasNextDouble(), hasNext() позволяют проверить наличие следующего значения определенного типа во входных данных.
🔻 Обработка исключений: методы nextInt(), nextDouble() и другие могут вызвать исключения типа InputMismatchException, если ввод не соответствует ожидаемому типу данных.
Класс Scanner позволяет удобно считывать и обрабатывать ввод от пользователя или из файлов, что делает его полезным инструментом при создании интерактивных приложений и обработке входных данных.
Основные методы и возможности класса Scanner включают:
🔻 nextInt(), nextLong(), nextDouble() считывают числа, а next() и nextLine() считывают строки.
🔻 Управление разделителями: метод useDelimiter(String pattern) позволяет настроить пользовательский разделитель для ввода, по умолчанию Scanner использует пробелы как разделители.
🔻 Проверка наличия данных: методы hasNextInt(), hasNextDouble(), hasNext() позволяют проверить наличие следующего значения определенного типа во входных данных.
🔻 Обработка исключений: методы nextInt(), nextDouble() и другие могут вызвать исключения типа InputMismatchException, если ввод не соответствует ожидаемому типу данных.
Класс Scanner позволяет удобно считывать и обрабатывать ввод от пользователя или из файлов, что делает его полезным инструментом при создании интерактивных приложений и обработке входных данных.
Какой класс лучше всего использовать для реализации кеша или для хранения метаданных об объектах?
Anonymous Quiz
46%
HashMap
15%
LinkedHashMap
14%
IdentityHashMap
25%
WeakHashMap
Как принудительно запустить поток?
Ответ:
Никак. В Java не существует абсолютно никакого способа принудительного запуска потока. Это контролируется JVM и Java не предоставляет никакого API для управления этим процессом.
Ответ:
Чем является ключевое слово «private»?
Anonymous Quiz
1%
Типом данных
2%
Оператором
1%
Литералом
97%
Модификатором доступа
Что такое сигнатура метода?
Сигнатура метода — это уникальная комбинация имени метода и списка его параметров. Сигнатура метода определяет, какие аргументы должны быть переданы методу при его вызове.
Сигнатура метода используется для определения перегрузки методов. Два или более метода считаются перегруженными, если они имеют одинаковое имя, но разные сигнатуры. То есть они принимают разные наборы параметров.
Важно отметить, что сигнатура метода не включает в себя возвращаемый тип и модификаторы доступа.
Сигнатура метода — это уникальная комбинация имени метода и списка его параметров. Сигнатура метода определяет, какие аргументы должны быть переданы методу при его вызове.
Сигнатура метода используется для определения перегрузки методов. Два или более метода считаются перегруженными, если они имеют одинаковое имя, но разные сигнатуры. То есть они принимают разные наборы параметров.
Важно отметить, что сигнатура метода не включает в себя возвращаемый тип и модификаторы доступа.
В каком классе или интерфейсе реализованы (объявлены) методы wait(), notify(), notifyAll()?
Anonymous Quiz
18%
Runnable
32%
Thread
5%
Callable
45%
Object
Какие из следующих списков примитивных типов представлены в порядке от меньшего к большему?
Anonymous Quiz
67%
byte, char, float, double
16%
byte, char, double, float
12%
char, byte, float, double
4%
char, double, float, bigint