Java Interview Tasks
4.83K subscribers
212 photos
1 video
1 file
140 links
Реальные вопросы и задачи с собеседований.
Оригинальный авторский контент.
Актуальный материал.
Уровень вопросов от junior до supersenior.

Автор канала - @alexzelentsov

По рекламе: @alexzelentsov
Download Telegram
🔍 Ответ на задачу про String: replace vs replaceAll 🧐

- replace(CharSequence target, CharSequence replacement) заменяет литеральные строки. Точка воспринимается просто как символ.
- replaceAll(String regex, String replacement) принимает регулярное выражение. В регулярках точка . означает "любой символ". Поэтому replaceAll заменит абсолютно все символы в строке на слэш.

Вывод:
Первая строка выведет java/is/fun, а вторая — ///////////.

⚡️ Не перепутайте:
Если вам не нужны регулярные выражения, всегда используйте replace(). Он быстрее и безопаснее.

#java #string #regex #basics #интервью #java_interview_tasks
👍10🔥6❤1
🔍 Ответ на задачу про List.remove(): Индекс или Объект? 🔢

Удаление из списка List<Integer> — классическая ловушка из-за перегрузки метода remove().

У List есть два метода: remove(int index) и remove(Object o). Если в списке лежат Integer, то при вызове remove(1) Java выберет версию с примитивом int (по индексу), так как это точное совпадение. В итоге удалится элемент под индексом 1 (это число 2).

Вывод:
Список станет [1, 3]. Чтобы удалить именно число 1, нужно вызвать list.remove(Integer.valueOf(1)).

⚡️ Не перепутайте:
Будьте осторожны с коллекциями чисел! Всегда проверяйте, удаляете вы по индексу или по значению.

#java #collections #arraylist #list #интервью #java_interview_tasks
1👍8❤2🔥1
🔍 Ответ на задачу про BigDecimal: equals vs compareTo ⚖️

- equals() у BigDecimal сравнивает не только значение, но и scale (точность/количество знаков после запятой). Так как у "1.0" scale=1, а у "1.00" scale=2, они не равны.
- compareTo() сравнивает только математические значения. 1.0 и 1.00 математически равны.

Вывод:
equals вернет false, а compareTo вернет true.

⚡️ Не перепутайте:
Для проверки равенства денежных сумм почти всегда нужно использовать compareTo() == 0.

#java #bigdecimal #math #finance #интервью #java_interview_tasks
👍6🔥3👏1
🔍 Ответ на задачу про String.contains: Ловушка экранирования 🪤

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

Многие методы в Java (например, split, replaceAll) принимают регулярные выражения. В regex символ | (pipe) является специальным (логическое ИЛИ) и требует экранирования — \|.

Однако метод String.contains(CharSequence s) ищет буквальное совпадение подстроки.

В данном примере:
- MULTIPLE_VALUES_SPLITTER инициализируется строкой \| (обратный слеш и вертикальная черта).
- Метод contains честно ищет эти два символа подряд.
- В строке "apple|orange|banana" есть только символ |, но нет символа \.

Вывод:
Результат будет false. Для корректной проверки наличия разделителя в данном случае нужно использовать val.contains("|").

⚡️ Не перепутайте:
- Методы contains, indexOf, replace работают с литералами.
- Методы split, replaceAll, matches работают с регулярными выражениями.

#java #string #contains #regex #backslash #интервью #java_interview_tasks
👍8❤1🔥1
🔍 Ответ на задачу про Double.NaN: 👻

- Согласно стандарту IEEE 754, NaN не равен самому себе. Поэтому x == y всегда false.
- Однако Double.equals() реализован так, что он считает два NaN равными. Это сделано для того, чтобы NaN можно было использовать в коллекциях (например, как ключ в HashMap).

Вывод:
Сравнение примитивов даст false, а объектов — true.

⚡️ Не перепутайте:
Для проверки на NaN у примитивов используйте Double.isNaN(x).

#java #double #nan #floatingpoint #интервью #java_interview_tasks
👍7🔥1
🔍 Ответ на задачу про HashSet: Опасность мутабельных объектов 🧩

Когда мы положили p в сет, он попал в "корзину" (bucket), соответствующую hashCode = 1. После изменения p.x = 2, hashCode объекта тоже стал равен 2. Когда мы вызываем contains(p), сет ищет объект в корзине №2, но наш объект всё еще лежит в корзине №1! Сет его не найдет.

Вывод:
contains вернет false, но размер сета по-прежнему 1. Объект "застрял" в неправильной корзине.

⚡️ Не перепутайте:
Никогда не используйте изменяемые (mutable) поля в hashCode и equals, если объекты будут храниться в сетах или мапах.

#java #collections #hashset #hashcode #bug #интервью #java_interview_tasks
👍6🔥2👏1
🔍 Ответ на задачу про Integer.MIN_VALUE: Математические странности 🧮
Диапазон int в Java — от -2,147,483,648 до 2,147,483,647. Заметьте, что отрицательных чисел на одно больше. При попытке вычислить -Integer.MIN_VALUE происходит переполнение, и число превращается... снова в Integer.MIN_VALUE!

Вывод:
Оба условия выведут true. Отрицание минимального значения int дает то же самое отрицательное число.

⚡️ Не перепутайте:
Всегда помните об асимметрии диапазона целых чисел в Java. Это частый источник багов при использовании Math.abs().

#java #int #overflow #math #basics #интервью #java_interview_tasks
❤7🔥2💯1👀1
🔍 Ответ на задачу про IdentityHashMap: Когда ссылки важнее значений 🔗

- HashMap использует equals() и hashCode() для сравнения ключей. Для "Java" и new String("Java") equals вернет true, поэтому в HashMap была бы 1 запись.

- IdentityHashMap использует оператор ==. Так как s1 и s2 — это разные объекты в памяти, мапа считает их разными ключами.

Вывод:
Размер мапы будет 2.

⚡️ Не перепутайте:
IdentityHashMap — редкий зверь. Она полезна, например, при сериализации графа объектов, чтобы не зациклиться, если два узла имеют одинаковое содержимое, но являются разными объектами.

#java #collections #hashmap #identityhashmap #internals #интервью #java_interview_tasks
🔥6👏2👍1
🔍 Ответ на задачу про Enum.values(): Скрытые аллокации 📦
Спецификация Java требует, чтобы массив, возвращаемый values(), был изменяемым (вы можете заменить в нем элементы, хотя это и плохая практика). Чтобы пользователи не могли испортить внутреннее состояние перечисления, компилятор генерирует код, который создает копию массива при каждом вызове values().

Вывод:
Каждый вызов values() — это новая аллокация памяти. В высокопроизводительном коде лучше кешировать этот массив: private static final Color[] VALUES = Color.values().

⚡️ Не перепутайте:
Если вам нужно просто получить количество элементов, используйте кешированное значение или Java 21 Enum.entries.

#java #enum #performance #jvm #memory #интервью #java_interview_tasks
👍7🔥1
🔍 Ответ на задачу про Iterator.remove(): Чистим коллекцию правильно 🧹
- Вариант A (for-each) использует итератор неявно. Если мы вызываем list.remove() напрямую, итератор об этом не знает и при следующей проверке modCount выбросит ConcurrentModificationException.
- Вариант B использует iterator.remove(). Этот метод специально спроектирован для безопасного удаления текущего элемента во время итерации.

Вывод:
Верный вариант — B. (Хотя есть исключение: в ArrayList удаление предпоследнего элемента через list.remove() в for-each может не вызвать ошибку из-за бага/особенности проверки hasNext(), но полагаться на это нельзя).

⚡️ Не перепутайте:
В Java 8+ самый простой и безопасный способ: list.removeIf(s -> s.equals("A")).

#java #collections #iterator #bug #clean_code #интервью #java_interview_tasks
👏5❤1🍌1
🔍 Ответ на задачу про LinkedHashMap: Порядок имеет значение 🔄
У LinkedHashMap есть специальный конструктор, где третий аргумент accessOrder включает режим "порядка доступа". Если он равен true, то при каждом get() или put() элемент перемещается в конец списка. Это идеальная основа для реализации LRU-кеша (Least Recently Used).

Вывод:
Так как мы обратились к ключу 2, он переместился в конец. Порядок станет: 1, 3, 2.

⚡️ Не перепутайте:
По умолчанию LinkedHashMap сохраняет порядок вставки (accessOrder = false).

#java #collections #linkedhashmap #lru #cache #интервью #java_interview_tasks
🔥8👍2👏1
🔍 Ответ на задачу про Наследование: Приватные методы не переопределяются 🛡
Приватные методы в Java не участвуют в полиморфизме. Они принадлежат только тому классу, в котором объявлены, и не могут быть переопределены (override). Когда метод test() вызывается у объекта Child, он ищется в Parent. Внутри test() вызывается print(), который в Parent помечен как private. Java связывает этот вызов статически именно с методом в Parent.

Вывод:
Напечатается "Parent". Метод print() в Child — это просто новый метод, который никак не связан с приватным методом родителя.

⚡️ Не перепутайте:
Если вы хотите, чтобы метод переопределялся, он должен быть как минимум protected.

#java #oop #inheritance #polymorphism #basics #интервью #java_interview_tasks
❤5👍3
🔍 Ответ на задачу про Static:

Статические методы привязаны к классу, а не к объекту. В Java нет полиморфизма для статики. Это называется method hiding. Какой метод вызовется, определяется типом переменной во время компиляции, а не типом объекта во время выполнения.

Вывод:
Так как переменная obj имеет тип A, вызовется A.staticMethod(). Результат: "A".

⚡️ Не перепутайте:
Никогда не вызывайте статические методы через экземпляры объектов (obj.method()). Всегда пишите ClassName.method(), чтобы не вводить в заблуждение.

#java #static #inheritance #basics #clean_code #интервью #java_interview_tasks
🔥6👍2🤔1
🔍 Ответ на задачу про Final поля: Безопасная публикация 🏗

Согласно JMM, поля final обеспечивают "гарантию заморозки". Если объект был правильно сконструирован (ссылка this не утекла во время работы конструктора), то любой поток, увидевший ссылку на этот объект, гарантированно увидит корректные значения всех его final полей.

Вывод:
При условии отсутствия "утечки" this в конструкторе , после создания объекта другой тред увидеть не может ничего кроме 5. Это одна из основ создания Immutable объектов в Java.

⚡️ Не перепутайте:
Обычные (не final) поля без синхронизации могут быть видны другим потокам в их дефолтном состоянии (например, 0 или null), даже если конструктор уже отработал.

#java #concurrency #jmm #final #multithreading #интервью #java_interview_tasks
🔥4
🔍 Ответ на задачу про Generics: Стирание типов (Type Erasure) 🧼
В Java дженерики реализованы через стирание типов. Это сделано для обратной совместимости с кодом до Java 5. Во время компиляции проверки проводятся, но в байт-коде вся информация о типах <String> и <Integer> удаляется, и оба списка превращаются в просто ArrayList (работающий с Object).

Вывод:
Оба списка принадлежат одному и тому же классу java.util.ArrayList. Результат: true.

⚡️ Не перепутайте:
Из-за стирания типов вы не можете сделать instanceof List<String> или создать массив дженериков new T[10].

#java #generics #jvm #internals #basics #интервью #java_interview_tasks
👌5👍1👏1
🔍 Ответ на задачу про Wildcards: List<Object> vs List<?> ❓
1. List<Object> не является родителем для List<String>. Несмотря на то, что String — это Object, сами коллекции инвариантны. Иначе мы могли бы положить Integer в список строк через ссылку на List<Object>.
2. List<?> (wildcard) — это родитель для любого List. Строка 2 верна.
3. В List<?> нельзя ничего добавлять (кроме null), так как мы не знаем, список какого типа там на самом деле.

Вывод:
Не скомпилируются строки 1 и 3.

⚡️ Не перепутайте:
List<Object> — это список, в который можно класть любые объекты.
List<?> — это список какого-то неизвестного типа, из него можно только читать.

#java #generics #wildcards #basics #интервью #java_interview_tasks
✍6👍4👏1
🔍 Ответ на задачу про PECS: Producer Extends, Consumer Super 🦆
Это правило PECS:
- Producer Extends: Если коллекция "производит" данные (мы из нее читаем), используйте extends. Мы гарантируем, что там лежат объекты типа T или его наследники, поэтому их безопасно приводить к T.
- Consumer Super: Если коллекция "потребляет" данные (мы в нее пишем), используйте super. Мы можем безопасно положить туда T. Но при чтении мы получим только Object, так как не знаем реального типа.

Вывод:
Верна только строка A.

⚡️ Не перепутайте:
List<? extends T> — только для чтения.
List<? super T> — в основном для записи.

#java #generics #pecs #clean_code #интервью #java_interview_tasks
🔥5
### 🧮 Задача: (7x−y)(7y−z)(7z−x) = 11, где x, y, z — целые числа

### Решение: 🚫

Ключевое наблюдение — посмотрим на чётность произведения (7x−y)(7y−z)(7z−x).

Сложим все три множителя:

(7x − y) + (7y − z) + (7z − x) = 6x + 6y + 6z = 6(x + y + z)

Сумма трёх множителей всегда чётна (кратна 6). Если сумма трёх целых чисел чётна, то среди них либо все три чётные, либо ровно два нечётных и одно чётное. В обоих случаях хотя бы один множитель — чётный. А значит, произведение (7x−y)(7y−z)(7z−x) всегда чётно при любых целых x, y, z.

Но 11 — нечётное число.

### Вывод:
Уравнение не имеет решений в целых числах.

#math #numbertheory #diophantine #интервью #java_interview_tasks
🤔6👍3🔥2