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

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

По рекламе: @alexzelentsov и https://telega.in/c/java_interview_tasks
Download Telegram
Что напечатает код?
Anonymous Quiz
65%
1
30%
2
5%
узнать
🔥5👍21
🔍 Ответ на задачу про логические операторы

Давайте разберем работу логических операторов в данном коде на Java. У нас есть три логические переменные: a, b, и c, со значениями true, false, и false соответственно. В условии if используется комбинация операторов (логическое "ИЛИ") и && (логическое "И").

Стоит помнить, что оператор && имеет более высокий приоритет, чем оператор . Поэтому выражение b && c будет вычислено первым. Но поскольку b равно false, а c также false, это выражение дает в результате false.

Далее, выражение a false будет всегда истинным, так как a равно true. Следовательно, полное условие в if равно true, и будет выполнена первая ветка блока:

1

Когда дело касается вложенных логических операторов в условных выражениях, расстановка скобок может значительно упростить понимание кода и избежать путаницы. В данном случае, добавим скобки для ясности:
boolean a = true;
boolean b = false;
boolean c = false;

if (a || (b && c)) {
System.out.println("1");
} else {
System.out.println("2");
}

Скобки вокруг выражения (b && c) четко определяют, что это будет вычислено в первую очередь. Это не только делает код более понятным, но и исключает возможность неправильной интерпретации, особенно если у вас большой и сложный условный оператор.

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

✍️ Научитесь писать чистый и понятный код! Поддержите эту идею, поставив лайк, подписывайтесь на канал и оставляйте комментарии с вашими мыслями об использовании скобок в коде.

#java #logicaloperators #boolean #clean_code #java_interview_tasks
🔥8👍52
Как вам такое?)
1😁17💩4😭2🐳1
Вот такую задачу с собеседования нашел:
Что думаете?)
🔥1
Наверняка эта задачка входит в число хрестоматийных и встречается на собеседованиях по #Java, но поскольку я по ним не хожу, пришлось убить часок на разбирательство с ней. Поделюсь с вами; вдруг кто-то тоже встретит.

🎓 Дано
Ванильный пул потоков на голом JDK (аналоги из класса Executors не подходят):
var threadPool = new ThreadPoolExecutor(
corePoolSize, // 3
maxPoolSize, // 30
keepAliveTime, // 60
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(maxQueueLength), // 100
Executors.defaultThreadFactory(),
new DiscardPolicy()); // could also be a logging implementation


И некий метод, который сначала просто напихивает задачки в этот пул:
List<Future> futures = new ArrayList<>();
futures.add(threadPool.submit(task));


, потом идёт по своим делам, а когда заканчивает с ними, проверяет готовность задачек и, если надо, дожидается завершения каждой, чтобы продолжить работу дальше:
for (Future future : futures) {
try {
future.get();
}
catch (Exception e) {
log.error("Failed to get task result from future", e);
}
}


🔍 Найти
Какого _🙊_ в некоторых случаях метод намертво зависает на вызове future.get()?
При этом в дампе потоков нет никаких следов задач, которые бы зависли/зациклились/заблокированы.

🔑 Решение
Вариант 1. Добавить таймаут в метод future.get(). Да, это решит проблему, но не даст понять, почему она появилась.

Вариант 2. Извернуться как-нибудь так, чтобы прийти к вызову вида CompletableFuture.allOf(c1, c2, c3).join(). Наверняка так можно (не проверял), но выглядит избыточно сложно, должно же работать и так.

Вариант 3. Обернуть вызов future.get() вот в такое условие:
    if (future.isDone()) {
future.get();
}

Казалось бы, смысла в нём нет, ведь если задача не завершена (isDone() == false), то мы просто дождёмся её завершения при вызове get(). Но нет. Когда мы имеем дело с ThreadPoolExecutor, то при вызове submit() он в качестве имплементации Future возвращает экземпляр FutureTask, у которого метод isDone() выглядит так:
    public boolean isDone() {
return state != NEW;
}

, то есть "сделанной" считается любая не новая задача (в том числе когда она ещё в работе).

А метод FutureTask.get() устроен так:
    public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}

, то есть ожидание наступит для любого состояния, предшествующего завершению, в том числе для вышеупомянутого NEW (на самом деле только для NEW и COMPLETING).

Но если бы задача, на которой завис наш поток, была в состоянии COMPLETING, мы наверняка увидели бы соответствующий ей поток в дампе, а раз его нет, значит, она в NEW.
А как она могла оказаться NEW, если все задачи вроде как были переданы пулу на исполнение? Видимо, он её не взял. А почему не взял? Правильно — из-за переполнения очереди, ведь она ограничена (new LinkedBlockingQueue<>(maxQueueLength)). А почему тогда это не привело к ошибкам и прерыванию всего процесса? Верно, из-за с виду безобидной new DiscardPolicy(), которая просто дропает не влезшие задачки (и логирует их, как было в нашем случае).

Вся цепочка кратко:
— не влезающие в очередь задачи молча отбрасываются политикой пула, оставляя им статус NEW;
— видя этот статус, метод future.get() впадает в бесконечное ожидание;
— исключить ожидание можно добавлением проверки на NEW в виде вызова future.isDone().
⚠️ Если очередь будет большой, а задачи — долгоиграющими, можно нарваться на случай, когда задача уже в очереди и имеет шанс быть выполненной, но цикл с вызовом get() её не подождёт. В этом случае решение должно быть другим.

Мораль: пишите однопоточные приложения🤪
🔥133👍3😁2
Что напечатает код?
🔥3👍1💩1👌1
Друзья, нужна ваша поддержка! 🙌

Если контент вам нравится, проголосуйте за канал! Ваш голос очень важен, и он поможет каналу расти и продолжать делиться интересными задачами и полезными материалами.

Пройдите по ссылке и отдайте свой голос за канал: https://t.me/boost/java_interview_tasks 🌟🌟🌟

Ваша поддержка — это мой самый сильный стимул становиться лучше. Большое спасибо каждому, кто уже подписался и активно участвует в жизни нашего канала! 💪❤️
4
🔍 Ответ на задачу про сравнение строк в Java

Давайте разберемся, что напечатает приведённый код! 🚀
String a = "ab";
String b = "a" + "b";
String c = "a";
String d = c + "b";

System.out.println(a == b);
System.out.println(a == d);
System.out.println(a.equals(d));

Этот код выводит на экран:

true — В первом сравнении (a == b), оба операнда являются строковыми литералами, и компилятор оптимизирует их, так что они указывают на один и тот же объект в строковом пуле.
false — Во втором сравнении (a == d), d создается путем конкатенации на этапе выполнения, из-за чего она не будет указывать на тот же объект в строковом пуле, что и a.
true — В третьем сравнении (a.equals(d)), метод equals сравнивает содержимое строк, а не их ссылки, потому этот результат будет true, так как содержимое одинаково.
Интересно, правда? 😄 Не забудьте, что использование оператора == для сравнения строк может привести к неожиданным результатам. Для проверки эквивалентности строк на уровне содержимого всегда используйте equals.

Ставьте лайк, подписывайтесь на канал и оставляйте комментарии! 💬👉

#Java #StringComparison #ИзучаемJava #java_interview_tasks
👍102🔥2
Оцените код по 10-ти бальной системе (10 - наилучший код в истории человечества)
Anonymous Poll
17%
1
7%
2
7%
3
3%
4
15%
5
5%
6
10%
7
4%
8
2%
9
28%
10
🤣5👍3🔥2
Что произойдет при выполнении следующего кода на Java?
🔥3👍1
Что произойдет при выполнении следующего кода на Java?
Anonymous Quiz
4%
A, B, C, D, E
73%
A, C, D, E
5%
A, D
1%
A, C, E
4%
узнать ответ
13%
делить на ноль нельзя
🔥4👍1
🔍 Ответ на задачу про исключения в Java

Давайте разберемся, что произойдет при выполнении представленного кода! ⬇️
public class ExceptionTest {
public static void main(String[] args) {
try {
System.out.println("A");
int result = 10 / 0; // Здесь возникнет ArithmeticException
System.out.println("B"); // Эта строка не будет выполнена
} catch (ArithmeticException e) {
System.out.println("C");
} finally {
System.out.println("D");
}
System.out.println("E");
}
}

Рассмотрим выполнение программы по шагам:

"A" будет напечатано, так как это первое действие в блоке try.
Далее происходит деление на ноль (10 / 0), что вызывает ArithmeticException.
Блок catch перехватывает исключение, и "C" выводится на экран.
Блок finally выполняется всегда, независимо от того, поймано ли исключение, таким образом, "D" будет напечатано.
После выполнения всех блоков try-catch-finally программа продолжает выполнение, поэтому "E" также будет напечатано.
Итак, правильная последовательность вывода: A, C, D, E. 🎉

Не забудьте поставить лайк, подписаться на наш канал и оставляйте комментарии! 💬👉

#Java #Исключения #ОбработкаИсключений #java_interview_tasks
👍10🔥2🙏1
Что произойдет при запуске следующего кода?
🔥4
Что произойдет при запуске следующего кода?
Anonymous Quiz
8%
Код скомпилируется и выполнится, одновременно будут запущены два потока.
56%
Код скомпилируется и выполнится, но "thread.run()" будет выполняться в основном потоке.
15%
Код скомпилируется, но вызовет исключение во время выполнения.
8%
Код не скомпилируется.
14%
Узнать что произойдет
🔥4👍1
🔍 Ответ на задачу про работу с многопоточностью в Java

Давайте разберёмся, что происходит при запуске данного кода! 🔍
public class ThreadTest {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
}
});

thread.start();
thread.run();
}
}

Объяснение:

thread::start — запускает новый поток, который выполняет переданное лямбда-выражение. В отдельном потоке выводятся значения от 0 до 4. Поток выполняет метод run, и будет выполняться параллельно с основным потоком.

thread::run — здесь метод run вызывается в основном потоке так, как если это был обычный метод, а не в отдельном потоке. Это означает, что в основном потоке без создания нового потока пойдет выполнение того же самого кода ещё раз, так как метод run просто выполняется в потоке, из которого он был вызван.

Следовательно, программа завершится успешным выполнением, и будут выведены две последовательности от 0 до 4. Таким образом, правильный ответ — Код скомпилируется и выполнится, но "thread::run()" будет выполняться в основном потоке.

Эта ситуация — прекрасный пример, демонстрирующий разницу между методами start() и run() в многопоточности. 🌟

Не забудьте поставить лайк, подписаться на канал и оставлять комментарии с вашими идеями и вопросами! 💬👉

#Java #Многопоточность #Concurrency #java_interview_tasks
🔥7👍43
#реклама

Секретное оружие против ИИ-шума 🔥🔥🔥


Вы ведь тоже устали от тонн бесполезности в ленте?

Я с коллегами собрал свой лист экспертов в одну папку

Только те, кто:
→ Копает глубже хайтек-новостей,
→ Делится кодом/архитектурами,
→ Бьет в точку.

Просто твой личный фильтр
Подруби себе: все здесь
P.S. Я тоже там есть😁
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Что напечатает код?
🔥3👍2
🔥6👍2😢1