Библиотека собеса по Java | вопросы с собеседований
6.36K subscribers
441 photos
12 videos
760 links
Вопросы с собеседований по Java и ответы на них.

По рекламе: @tproger_sales_bot

Учиться у нас: clc.to/3wECtA

Для обратной связи: @proglibrary_feeedback_bot
Download Telegram
❓ Чем List.copyOf отличается от Collections.unmodifiableList?

Ответ: Collections.unmodifiableList(source) создаёт представление исходного списка, запрещающее изменения через это представление. Если исходный список изменить напрямую, изменения будут видны и через обёртку.

List.copyOf(source) возвращает список, который нельзя изменить и чьё содержимое не зависит от последующих изменений исходной коллекции. При этом метод не обязан физически создавать новый объект: подходящий неизменяемый список может быть переиспользован.

Например, после добавления элемента в source обёртка unmodifiableList увидит новый элемент, а результат copyOf — нет.

Есть ещё два нюанса. List.copyOf не допускает null-элементы. И ни один из этих способов не делает глубокую копию объектов внутри списка: если элемент изменяемый, его состояние всё ещё можно изменить.

List.copyOf доступен с Java 10.

Документация Java · Дополнение 1

🐸 Библиотека собеса по Java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
📌 Один курс — хорошее вложение в себя. Два по той же цене — ещё лучше.

В Proglib Academy действует акция: покупаешь один курс, а второй получаешь в подарок.

Например, можно совместить два направления по работе с ИИ:

💥 ИИ для разработчиков — применение нейросетей в повседневной разработке: работа с кодом, тестирование и ревью.

💥 Разработка ИИ-агентов — архитектура агентов и создание собственных AI-решений.


📍 Разница в цене — почти 50 тысяч рублей. Можно освоить больше, не выходя за рамки запланированного бюджета.

А если тебе интереснее Python, алгоритмы, backend или DevOps — выбирай другую пару курсов из каталога.

Акция действует до 31 октября включительно ⏳

⏮️ Пора прокачать свой стек
Please open Telegram to view this post
VIEW IN TELEGRAM
❓ Почему orElse может вызвать функцию, даже если Optional не пуст?

Ответ: Потому что аргументы метода вычисляются до его вызова.

В выражении optional.orElse(loadDefault()) функция loadDefault() выполнится даже тогда, когда Optional уже содержит значение. Её результат будет вычислен, а затем окажется не нужен.

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

Для отложенного вычисления используют optional.orElseGet(() -> loadDefault()). Переданная функция будет вызвана только при пустом Optional.

При этом лень относится именно к вызову Supplier.get(). Само выражение, создающее поставщика, всё равно вычисляется заранее. Например, в orElseGet(createSupplier()) вызов createSupplier() произойдёт до входа в orElseGet.

Если значение по умолчанию уже готово и его получение не требует работы, orElse остаётся подходящим вариантом.

Документация Java

🐸 Библиотека собеса по Java
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍1
❓ Можно ли заменить collect(Collectors.toList()) на Stream.toList() без изменения поведения?

Ответ: Не всегда. Главное различие — в гарантиях для полученного списка.

Stream.toList(), появившийся в Java 16, возвращает список, который нельзя изменить: add, remove и другие операции изменения выбросят UnsupportedOperationException.

У Collectors.toList() контракт не гарантирует ни конкретный тип списка, ни возможность его изменять. Поэтому утверждение «он всегда возвращает изменяемый ArrayList» тоже неверно, даже если вы наблюдали такое поведение в используемой реализации.

Если код после сбора элементов добавляет новые значения или сортирует список на месте, механическая замена на Stream.toList() может его сломать.

Когда нужен именно изменяемый ArrayList, это стоит выразить явно: collect(Collectors.toCollection(ArrayList::new)).

И в обоих случаях сам сбор в список не создаёт глубокие копии элементов.

Документация Java · Дополнение 1

🐸 Библиотека собеса по Java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Приглашаем на Java Jam — бесплатный митап ЮMoney для бэкенд-разработчиков 🔥

✅ 29 октября, четверг, 19:00 МСК — приходите на митап в Санкт-Петербурге или смотрите трансляцию. 

Спикеры из ЮMoney и Сбера выступят с докладами:

🟣 Один апгрейд — больше сотни сервисов: как мы обновляем Java-стек в компании
Обсудим, как обновить Gradle, Spring Boot и Java в 120+ компонентах, не останавливая разработку. Расскажем, как выстраивали процессы на протяжении этого времени: от порядка действий и массовых патчей до взаимодействия с командами и решения трудностей, с которыми столкнулись во время последнего обновления.

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

🟣 Откатить нельзя оставить: мониторинг выкладки релиза на основе Sentry
Ошибки случаются. Узнаем, какие из них появляются или возникают чаще после последнего релиза — и достаточно ли этого, чтобы принять решение об откате.

Зарегистрируйтесь, чтобы принять участие. Все подробности — на сайте митапа Java Jam👈
Please open Telegram to view this post
VIEW IN TELEGRAM
Делает ли final объект неизменяемым?

Ответ: Нет. Для переменной ссылочного типа final запрещает присвоить другую ссылку. Состояние самого объекта при этом может меняться. Например, в final List<String> items можно добавлять элементы, если реализация списка это разрешает. Чтобы объект был неизменяемым, нужно отдельно продумать его поля, методы и доступ к вложенным объектам. Одного модификатора final недостаточно.

Документация: final-переменные

Основа вопроса: Подборка по публичным Java-собеседованиям, темы final и immutable objects.

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Гарантирует ли Future.cancel(true), что задача остановилась?

Ответ: Нет. Если задача уже выполняется и реализация поддерживает прерывание, cancel(true) пытается прервать выполняющий её поток. Но прерывание — сигнал, а не принудительная остановка. Код должен на него реагировать: проверять флаг или корректно обрабатывать InterruptedException. Успешная отмена Future не доказывает, что работа уже прекратилась. У CompletableFuture параметр mayInterruptIfRunning вообще не управляет прерыванием выполнения.

Документация: Future.cancel • Документация: CompletableFuture.cancel

Основа вопроса: Подборка по публичным Java-собеседованиям, темы Future и остановки потоков.

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Запомнит ли HashMap.computeIfAbsent результат null?

Ответ: Нет. Если функция вычисления вернула null, новая запись не добавляется. При следующем вызове для того же отсутствующего ключа функция может выполниться снова. Поэтому возвращать null как признак «проверили, ничего не нашли» недостаточно для кэширования отрицательного результата. Для него нужен отдельный маркер или другой способ хранения. Если ключ уже связан со значением null, computeIfAbsent тоже пытается вычислить значение.

Документация: HashMap.computeIfAbsent

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
Почему TreeSet может не добавить объект, который не равен существующему по equals?

Ответ: Для TreeSet совпадение определяется результатом compareTo или переданного Comparator. Если сравнение возвращает ноль, коллекция считает элементы одинаковыми. Например, компаратор только по возрасту не позволит сохранить двух разных людей одного возраста. Чтобы коллекция соблюдала обычный контракт Set, порядок сравнения должен быть согласован с equals. Если это не так, поведение остаётся определённым, но может удивить вызывающий код.

Документация: TreeSet

Основа вопроса: Подборка по публичным Java-собеседованиям, темы TreeSet и сравнения объектов.

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
Чем thenApply отличается от thenCompose?

Ответ: thenApply преобразует полученное значение. Если функция вернула ещё один CompletableFuture, результатом будет вложенная конструкция — future внутри future. thenCompose нужен, когда следующий шаг сам возвращает CompletionStage. Он связывает этапы и возвращает одну общую стадию с конечным результатом. Выбирайте thenApply для обычного преобразования, а thenCompose — для последовательности зависимых асинхронных операций.

Документация: CompletableFuture

Основа вопроса: Подборка по публичным Java-собеседованиям, тема CompletableFuture.

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
Блокируют ли друг друга static synchronized и synchronized-метод экземпляра?

Ответ: Сами по себе — нет. Статический метод захватывает монитор объекта Class, а метод экземпляра — монитор this. Это разные блокировки, поэтому два метода могут выполняться одновременно. Если они работают с одними данными, наличие слова synchronized в обоих ещё не обеспечивает защиту. Для согласованного доступа все участники должны использовать одну и ту же блокировку.

Документация: мониторы и синхронизация

Основа вопроса: Подборка по публичным Java-собеседованиям, тема static synchronized.

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Может ли return в finally скрыть исключение из try?

Ответ: Да. Если try выбросил исключение, а finally завершился через return, метод вернёт значение из finally. Исходное исключение не продолжит распространяться. Аналогично новый throw в finally может заменить прежнюю ошибку. Поэтому в finally лучше оставлять очистку ресурсов и избегать команд, которые меняют способ завершения метода. Для закрываемых ресурсов обычно удобнее try-with-resources.

Документация: выполнение try-finally

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Почему в List<? extends Number> нельзя добавить Integer?

Ответ: Точный тип элементов неизвестен. За такой ссылкой может находиться, например, List<Double>. Если разрешить добавить Integer, типобезопасность нарушится. Читать элементы можно как Number, потому что верхняя граница известна. Для коллекции, в которую нужно добавлять целые числа, часто подходит List<? super Integer>. Отдельный случай — null: система типов его допускает, но сама реализация списка может запрещать вставку.

Документация: wildcard с верхней границей

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
👀 Освобождает ли Thread.sleep монитор и чем он отличается от Object.wait?

Ответ: Thread.sleep приостанавливает текущий поток и сохраняет захваченные им мониторы. Другие потоки продолжат ждать, если им нужен тот же монитор.

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

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

Документация

Вопрос из подборки для собеседований

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
👀 Почему ThreadLocal нужно очищать после задачи в пуле потоков?

Ответ: ThreadLocal связывает значение с потоком. Рабочий поток пула может пережить множество задач, поэтому данные одного запроса способны остаться до следующего запуска на том же потоке.

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

Контекст задачи очищают через remove() в finally. Если внутри временно подменяется уже существующий контекст, после работы восстанавливают прежнее значение.

Документация

Вопрос из подборки для собеседований

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
👀 Чем Thread.interrupted() отличается от isInterrupted()?

Ответ: Thread.interrupted() — статический метод. Он проверяет флаг прерывания текущего потока и сбрасывает его. При двух вызовах подряд второй обычно вернёт false, если за это время не поступило новое прерывание.

thread.isInterrupted() проверяет флаг указанного потока и сохраняет его состояние.

Эта разница важна в циклах обработки отмены: проверка через interrupted() расходует сигнал. Если InterruptedException перехвачен, а передать его выше нельзя, часто нужно восстановить флаг через Thread.currentThread().interrupt().

Документация

Вопрос из подборки для собеседований

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👀 Куда попадёт исключение из задачи, переданной через execute и submit?

Ответ: В обычном ThreadPoolExecutor неперехваченное исключение из Runnable, переданного через execute, выходит из задачи. Рабочий поток завершается, а ошибка попадает в механизм обработки неперехваченных исключений, включая UncaughtExceptionHandler.

submit оборачивает задачу в Future. Исключение сохраняется в ней, а вызов get() выбрасывает ExecutionException с исходной ошибкой в cause.

Если результат submit никто не проверяет, ошибка может остаться незамеченной. Для фоновых задач заранее определите, кто получает результат и где регистрируются сбои.

Документация

Вопрос из подборки для собеседований

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
👀 Чем CountDownLatch отличается от CyclicBarrier и что можно использовать повторно?

Ответ: CountDownLatch ждёт, пока счётчик событий дойдёт до нуля. Рабочие задачи вызывают countDown(), а ожидающий поток — await(). После достижения нуля этот latch остаётся открытым: сбросить счётчик нельзя.

CyclicBarrier собирает заданное количество участников в одной точке. Каждый вызывает await(), а когда приходят все, они продолжают работу. Затем барьер можно использовать для следующего этапа.

Latch удобен для ожидания завершения набора работ. Barrier — для алгоритма, в котором несколько потоков многократно встречаются между этапами.

Документация

Вопрос из подборки для собеседований

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
👀 Почему при переопределении equals нужно переопределять hashCode?

Ответ: Контракт Java требует: если два объекта равны по equals, их hashCode должен совпадать.

HashMap и HashSet используют хеш, чтобы выбрать область поиска, а затем проверяют равенство объектов. Если equals переопределён, а hashCode остался несовместимым, коллекция может не найти равный ключ или сохранить несколько равных элементов.

Обычно оба метода строят на одном наборе значимых полей. Совпадение хешей у неравных объектов допустимо: это коллизия. Результат hashCode должен сохраняться, пока поля, участвующие в equals, не меняются.

Документация

Вопрос из подборки для собеседований

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👀 Какое исключение сохранит try-with-resources, если ошиблись и try, и close?

Ответ: Если исключение возникло в теле try и затем при закрытии ресурса, основным останется исключение из try. Ошибка из close попадёт в список подавленных исключений — её можно получить через getSuppressed().

Ресурсы закрываются в обратном порядке объявления. Если тело try завершилось нормально, а close выбросил исключение, оно само станет основным. Это помогает сохранить причину сбоя и ошибки освобождения ресурсов.

Документация.

Источник вопроса

➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2