Java собеседования
664 subscribers
106 photos
224 links
Подготовка к собеседованиям на позицию Java-разработчик

Еще больше на сайте https://frontview-it.ru

Backend собеседования - @frontview_backend
Java работа - @frontview_java_vacancies
Все IT вакансии - @frontview_all_vacancies
Download Telegram
🔥 Объясни концепцию неизменяемости (immutability)

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

Преимущества неизменяемых объектов:
- Упрощают понимание и сопровождение кода.
- Повышают безопасность данных.
- Улучшают производительность за счёт кеширования и оптимизаций компилятора.

Создание неизменяемого класса:
1. Класс объявляется как final, чтобы предотвратить наследование.
2. Все поля класса приватны и объявлены как final.
3. Нет сеттеров; значения устанавливаются только через конструктор.
4. Если поля содержат ссылки на изменяемые объекты, создаются их копии (глубокая копия).

Пример:

public final class User {
private final String name;
private final int age;

public User(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}

В данном примере класс User неизменяемый: после создания объекта нельзя изменить его name или age.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🔥 В чем разница между CI и CD?

Непрерывная интеграция (CI) и непрерывная доставка (CD) являются важными практиками DevOps, способствующими эффективной разработке программного обеспечения.

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

Непрерывная доставка (CD) расширяет возможности CI, автоматизируя процесс развертывания приложения на различных средах — от тестовой до продакшен. Это гарантирует, что обновления могут быть доставлены пользователям быстро и без сбоев, минимизируя риски при выпуске новых версий.

Таким образом, CI улучшает процесс интеграции кода и обеспечивает его качество, а CD автоматизирует доставку и развёртывание приложения, обеспечивая непрерывность и надежность обновлений.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🔥 Как защищаться от SQL-инъекций?

SQL-инъекции представляют серьёзную угрозу безопасности приложений. Для защиты от них применяются следующие методы:

Параметризованные запросы: Использование PreparedStatement в Java предотвращает внедрение вредоносного кода, гарантируя, что вводимые данные обрабатываются как параметры, а не как часть SQL-запроса.

ORM-фреймворки: Инструменты, такие как Hibernate, автоматически обрабатывают параметры запросов, снижая риск инъекций.

Валидация и фильтрация ввода: Проверка и ограничение вводимых пользователем данных на стороне сервера помогает предотвратить внедрение нежелательных символов.

Использование хранимых процедур: Хранимые процедуры могут ограничить прямой доступ к базе данных и контролировать выполняемые операции.

Минимизация привилегий: Предоставление минимальных необходимых прав доступа к базе данных уменьшает потенциальный ущерб от успешной атаки.

Применение этих практик обеспечивает надёжную защиту приложения от SQL-инъекций.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Как работать с JSON в Java с помощью библиотек Gson и Jackson?

Работа с JSON в Java может осуществляться с помощью библиотек Gson и Jackson, каждая из которых имеет свои особенности.

Gson

Библиотека от Google, удобна для простого преобразования между JSON и Java объектами.

Пример сериализации:

Gson gson = new Gson();
String json = gson.toJson(объект);


Пример десериализации:

MyClass obj = gson.fromJson(jsonString, MyClass.class);


Jackson

Более мощная и настраиваемая библиотека, поддерживает потоковую обработку JSON.

Пример сериализации:

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(объект);


Пример десериализации:

MyClass obj = mapper.readValue(jsonString, MyClass.class);


Выбор библиотеки зависит от требований проекта: для простоты использования подходит Gson, для более сложных задач – Jackson.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🔥 Объясни паттерн Prototype

Паттерн Prototype относится к порождающим и позволяет создавать новые объекты путем копирования существующих экземпляров.

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

- Быстрота создания: Клонирование объектов зачастую быстрее, чем их создание с нуля.
- Гибкость: Обеспечивает создание объектов разных типов без привязки к конкретным классам.
- Избежание дублирования кода: Упрощает создание сложных объектов путем копирования прототипов.

Реализация в Java:

Класс должен реализовывать интерфейс Cloneable и переопределять метод clone().


public class Prototype implements Cloneable {
private int field;

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}


Использование паттерна Prototype повышает гибкость системы и упрощает создание новых объектов, особенно когда инициализация объектов сложна или ресурсоемка.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🔥 Что такое полиморфизм?

Полиморфизм в Java позволяет объектам принимать множество форм, что является одной из фундаментальных концепций объектно-ориентированного программирования.

Виды полиморфизма:

1. Компиляционный (переопределение методов): Позволяет подклассам предоставлять специфическую реализацию методов, объявленных в базовом классе.
2. Перегрузка методов (overloading): Наличие нескольких методов с одинаковым именем, но разными параметрами в одном классе.

Преимущества полиморфизма:
- Упрощение кода и повышение его гибкости.
- Позволяет писать более абстрактный и расширяемый код.
- Улучшает поддержку и масштабируемость приложений.

Пример:


class Animal {
void makeSound() {
System.out.println("Animal sound");
}
}

class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Bark");
}
}

public class TestPolymorphism {
public static void main(String[] args) {
Animal animal = new Dog();
animal.makeSound(); // Вывод: Bark
}
}


В этом примере объект Dog представлен как Animal, что демонстрирует полиморфизм при вызове метода makeSound(). Это позволяет использовать объекты различных классов через единый интерфейс, упрощая архитектуру приложения.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Что такое ConcurrentHashMap и когда его использовать?

ConcurrentHashMap в Java представляет собой потокобезопасную реализацию интерфейса Map, обеспечивающую высокую производительность при одновременном доступе нескольких потоков.

Особенности:
- Разделение карты на сегменты для минимизации блокировок.
- Поддержка полной итерации без блокировки всей карты.
- Высокая масштабируемость в многопоточной среде.

Когда использовать:
- В приложениях с интенсивным параллельным доступом к данным.
- Когда необходима быстрая и безопасная модификация коллекции из нескольких потоков.
- В ситуациях, требующих высокой производительности при одновременной работе многих потоков.

Пример использования:

import java.util.concurrent.ConcurrentHashMap;

public class Example {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("один", 1);
map.put("два", 2);

map.forEach((key, value) -> {
System.out.println(key + " = " + value);
});
}
}


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🔥 В чем разница между FileInputStream и FileReader?

FileInputStream и FileReader в Java используются для чтения данных из файлов, но предназначены для разных типов данных.

FileInputStream:
- Предназначен для чтения двоичных данных (байтов).
- Используется для работы с любыми файлами, такими как изображения, аудио, видео и другие бинарные форматы.
- Читает данные в виде массива байтов, что делает его подходящим для обработки несоответствующих тексту данных.

Пример использования FileInputStream:

import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("example.bin")) {
int byteData;
while ((byteData = fis.read()) != -1) {
// Обработка байта
System.out.print(byteData + " ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}


FileReader:
- Предназначен для чтения символьных данных (текстовых).
- Использует кодировку символов для преобразования байтов в символы.
- Упрощает работу с текстовыми файлами, такими как .txt, .csv и другие.

Пример использования FileReader:

import java.io.FileReader;
import java.io.IOException;

public class FileReaderExample {
public static void main(String[] args) {
try (FileReader fr = new FileReader("example.txt")) {
int charData;
while ((charData = fr.read()) != -1) {
// Обработка символа
System.out.print((char) charData);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}


Основные отличия:
- FileInputStream работает с байтами, подходит для бинарных файлов.
- FileReader работает с символами, оптимален для текстовых данных.
Выбор между ними зависит от типа обрабатываемого файла.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔥 В чем разница между wait() и sleep()?

В Java методы wait() и sleep() используются для приостановки выполнения потоков, но имеют ключевые отличия.

wait():
- Определен в классе Object.
- Используется в синхронизированных блоках для взаимодействия между потоками.
- Освобождает монитор (блокировку) объекта при вызове.
- Поток возобновляется после вызова notify() или notifyAll().

Пример использования wait():

synchronized (obj) {
while (условие) {
obj.wait();
}
// Действия после ожидания
}


sleep():
- Определен в классе Thread.
- Приостанавливает выполнение потока на заданное время.
- Не требует синхронизации и не освобождает блокировки.
- Поток автоматически возобновляется после истечения времени.

Пример использования sleep():

try {
Thread.sleep(1000); // Пауза 1 секунда
} catch (InterruptedException e) {
e.printStackTrace();
}


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🔥 Что такое default и static методы в интерфейсах?

Default и static методы в интерфейсах Java появились с версии Java 8, расширив возможности интерфейсов.

Default методы:
- Позволяют добавлять реализацию методов в интерфейс.
- Реализующие классы могут использовать их без необходимости переопределения.
- Обеспечивают обратную совместимость при добавлении новых методов в интерфейсы.

Пример default метода:

public interface MyInterface {
default void defaultMethod() {
System.out.println("Это default метод");
}
}


Static методы:
- Определяются как статические внутри интерфейса.
- Вызываются через имя интерфейса, а не через экземпляр класса.
- Не могут быть переопределены в реализующих классах.
- Используются для утилитарных функций, связанных с интерфейсом.

Пример static метода:

public interface MyInterface {
static void staticMethod() {
System.out.println("Это static метод");
}
}

// Вызов:
MyInterface.staticMethod();


Основные отличия:
- Default методы предоставляют возможность наследования реализации и могут быть переопределены.
- Static методы принадлежат самому интерфейсу и не могут быть изменены в реализующих классах.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🔥 Объясни основные аннотации JPA (@ Entity, @ Table, @ Id)

В Java Persistence API (JPA) аннотации используются для сопоставления классов Java с таблицами базы данных.

@ Entity
- Помечает класс как сущность, которая будет отображаться на таблицу в базе данных.
- Каждый экземпляр класса соответствует строке в таблице.
- Обязательная аннотация для JPA сущностей.

@ Table
- Определяет имя таблицы в базе данных, с которой связана сущность.
- Если не указана, по умолчанию используется имя класса.
- Позволяет задать схему и другие параметры таблицы.

@ Id
- Указывает поле, являющееся первичным ключом таблицы.
- Обязательное для каждой сущности.
- Часто используется вместе с генераторами значений, например, @ GeneratedValue.

Пример использования:

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

@Entity
@Table(name = "users")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

// Геттеры и сеттеры
}


В данном примере класс User является JPA сущностью, отображающейся на таблицу users. Поле id служит первичным ключом и автоматически генерируется базой данных.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🔥 В чем разница между JUnit 4 и JUnit 5?

JUnit 5 представляет значительное обновление по сравнению с JUnit 4, предлагая более гибкую и расширяемую платформу для тестирования в Java.

Основные отличия:

Архитектура:
- JUnit 4: Монолитная структура.
- JUnit 5: Состоит из трёх модулей – JUnit Platform, JUnit Jupiter и JUnit Vintage, что обеспечивает поддержку как новых, так и старых тестов.

Аннотации:
- JUnit 4: Использует аннотации вроде @ Before, @ After, @ Test.
- JUnit 5: Вводит новые аннотации, такие как @ BeforeEach, @ AfterEach, @ DisplayName, улучшая читаемость и функциональность тестов.

Модель расширений:
- JUnit 4: Применяет правила (@ Rule) и раннеры (@ RunWith), что ограничивает гибкость.
- JUnit 5: Внедряет расширения через @ ExtendWith, позволяя создавать более мощные и настраиваемые расширения.

Поддержка Java 8 и выше:
- JUnit 5: Полностью поддерживает лямбда-выражения и другие возможности Java 8+, упрощая написание тестов.

Параллельное выполнение:
- JUnit 5: Предоставляет встроенную поддержку параллельного запуска тестов, что ускоряет процесс тестирования.

Обратная совместимость:
- JUnit 5: С помощью модуля JUnit Vintage позволяет запускать тесты, написанные для JUnit 4, обеспечивая плавный переход.

JUnit 5 улучшает процесс тестирования, делая его более модульным, гибким и совместимым с современными стандартами разработки.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🔥 Как использовать лямбда-выражения в Java?

Лямбда-выражения были введены в Java 8 и позволяют писать компактный и понятный код для реализации функциональных интерфейсов.

Синтаксис:

(parameters) -> expression

или

(parameters) -> { statements; }


Преимущества:
- Упрощение кода: Сокращают объем кода, делая его более читаемым.
- Функциональный стиль программирования: Позволяют легко работать с коллекциями и потоками данных.
- Ленивая оценка: Поддерживают эффективное выполнение операций.

Пример использования:


import java.util.Arrays;
import java.util.List;

public class LambdaExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Anna", "Boris", "Victor");

// Использование лямбда-выражения для перебора списка
names.forEach(name -> System.out.println(name));

// Лямбда для сортировки
names.sort((a, b) -> a.compareTo(b));
}
}


Функциональные интерфейсы:
Лямбда-выражения реализуют интерфейсы с единственным абстрактным методом, такие как Runnable, Callable, Comparator, и интерфейсы из пакета java.util.function (например, Predicate, Function).

Пример функционального интерфейса:

@FunctionalInterface
interface MathOperation {
int operate(int a, int b);
}

public class LambdaTest {
public static void main(String[] args) {
MathOperation add = (a, b) -> a + b;
System.out.println(add.operate(5, 3)); // Вывод: 8
}
}


Лямбда-выражения делают код более гибким и выразительным, облегчая реализацию функций обратного вызова и работу с потоками.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
🔥 Что такое паттерн Builder и когда его применять?

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

Применяется, когда необходимо создать объект с множеством опциональных параметров или когда требуется избежать конструктора с длинным списком параметров. Builder позволяет создавать объект в несколько этапов, добавляя параметры по мере необходимости.

Пример использования в Java:


public class Car {
private final String engine;
private final int wheels;
private final String color;

private Car(Builder builder) {
this.engine = builder.engine;
this.wheels = builder.wheels;
this.color = builder.color;
}

public static class Builder {
private String engine;
private int wheels;
private String color;

public Builder setEngine(String engine) {
this.engine = engine;
return this;
}

public Builder setWheels(int wheels) {
this.wheels = wheels;
return this;
}

public Builder setColor(String color) {
this.color = color;
return this;
}

public Car build() {
return new Car(this);
}
}
}


Этот паттерн улучшает читаемость кода и упрощает процесс создания объектов.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🔥 Объясни сборку мусора по поколениям

Сборка мусора по поколениям — это стратегия управления памятью в Java, основанная на наблюдении, что большинство объектов "живут" недолго. Память делится на три поколения: Young Generation, Old Generation и Permanent Generation (в современных JVM заменена на Metaspace).

Young Generation — здесь создаются новые объекты. Состоит из Eden и двух Survivor областей. Когда Eden заполняется, происходит Minor GC, перемещающий выжившие объекты в Survivor.

Old Generation — сюда перемещаются объекты, пережившие несколько сборок в Young Generation. Когда Old Generation заполняется, запускается Major GC, который освобождает больше памяти, но работает медленнее.

Permanent Generation/Metaspace — хранит метаданные классов и методы. Metaspace использует память вне кучи, что решает проблемы с OutOfMemoryError в Permanent Generation.

Сборка мусора по поколениям оптимизирует производительность, минимизируя паузы и улучшая использование памяти.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤔3
🔥 Объясни работу с файловыми атрибутами

Работа с файловыми атрибутами в Java осуществляется с помощью класса Files и интерфейсов из пакета java.nio.file.attribute. Эти инструменты позволяют читать и изменять метаданные файлов, такие как время создания, последнего доступа, изменения, а также права доступа.

Для получения атрибутов используется метод readAttributes. Например, чтобы получить базовые атрибуты файла:


Path path = Paths.get("example.txt");
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Creation Time: " + attrs.creationTime());
System.out.println("Last Modified Time: " + attrs.lastModifiedTime());


Для изменения атрибутов, например, времени последнего изменения, используется метод setLastModifiedTime:


FileTime newTime = FileTime.fromMillis(System.currentTimeMillis());
Files.setLastModifiedTime(path, newTime);


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Расскажи про работу с сокетами

Работа с сокетами в Java позволяет создавать сетевые приложения, которые могут обмениваться данными через TCP/IP. Основные классы для работы с сокетами — это Socket и ServerSocket.

ServerSocket используется для создания серверного приложения, которое ожидает входящих соединений. Пример создания сервера:


ServerSocket serverSocket = new ServerSocket(8080);
Socket clientSocket = serverSocket.accept();


Socket используется для создания клиентского приложения, которое подключается к серверу. Пример создания клиента:


Socket socket = new Socket("localhost", 8080);


После установления соединения можно использовать потоки ввода-вывода для обмена данными:


OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
out.write("Hello".getBytes());
byte[] buffer = new byte[1024];
int bytesRead = in.read(buffer);


Работа с сокетами позволяет реализовывать клиент-серверные приложения, обеспечивая двустороннюю связь между узлами сети.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Что такое пакет (package) и почему он важен?

Пакет (package) в Java — это механизм, позволяющий организовать классы и интерфейсы в логические группы. Он помогает структурировать код, предотвращает конфликты имен и упрощает управление доступом.

Пакеты важны для:

1. Организации кода: Позволяют группировать связанные классы, что делает проект более понятным и поддерживаемым.

2. Избежания конфликтов имен: Разные разработчики могут использовать одинаковые имена классов, но благодаря пакетам они не конфликтуют.

3. Управления доступом: Пакеты позволяют контролировать видимость классов и методов, используя модификаторы доступа.

Пример объявления пакета:


package com.example.project;

public class MyClass {
// class implementation
}


Пакеты способствуют созданию чистой архитектуры и упрощают навигацию по коду, особенно в крупных проектах.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🔥 Что такое реактивное программирование?

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

В Java реактивное программирование часто реализуется с помощью библиотек, таких как Project Reactor или RxJava. Эти библиотеки предоставляют API для работы с потоками данных и позволяют обрабатывать их асинхронно.

Пример использования Project Reactor:


Flux<String> flux = Flux.just("Hello", "World")
.map(String::toUpperCase)
.filter(s -> s.startsWith("H"));

flux.subscribe(System.out::println);


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🔥 Как реализовать цепочки CompletableFuture?

Цепочки CompletableFuture в Java позволяют выполнять асинхронные задачи последовательно или параллельно, упрощая обработку результатов и ошибок. Это достигается с помощью методов, таких как thenApply, thenCompose, thenAccept, и exceptionally.

Пример создания цепочки:


CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(String::toUpperCase)
.thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"))
.thenAccept(System.out::println)
.exceptionally(ex -> {
System.out.println("Error: " + ex.getMessage());
return null;
});


В этом примере сначала выполняется асинхронная задача, возвращающая строку "Hello". Затем строка преобразуется в верхний регистр, объединяется с "World" и выводится на экран. В случае ошибки используется метод exceptionally для обработки исключений.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7