🔍 Ответ на вопрос про использование var в Java:
Все больше и больше в коде начали использовать var .
🤔 Давайте разберем плюсы и минусы его использования.
📌 Плюсы var:
✔️ Меньше "визуального шума": избавляет от длинных и громоздких объявлений.
✔️ Удобно при работе с дженериками и вложенными типами: никакого лишнего написания.
✔️ Код читается проще, когда тип очевиден из правой части.
Примеры, когда var выглядит отлично:
var map = new HashMap<String, List<Long>>();
var name = "LinkedIn";
var count = 42;
⚠️ Минусы var:
❌ Иногда теряется читаемость: особенно, когда возвращаемый тип не очевиден.
❌ Может прятать неожиданные типы, что усложняет отладку.
❌ Не подходит для публичных API / сигнатур, где тип данных должен быть явно указан.
Когда var может стать врагом:
var data = process(); // Непонятно, что за тип возвращается.
var a = someObj.getValue().getAnother().resolve(); // Много уровней вложенности.
📌 Мой вывод: var — это отличный инструмент, но важно знать, когда и как его использовать. Лично я применяю var, когда тип очевиден без догадок. Если нужно вчитываться или полагаться на IDE, лучше указать тип явно. Помните, что читаемость важнее краткости! 💡
Согласны с таким подходом? Или у вас есть свои мысли? Делитесь в комментариях, подписывайтесь и ставьте лайк! 🤗
#Java #var #кодстайл #java10 #java_interview_tasks
Все больше и больше в коде начали использовать var .
🤔 Давайте разберем плюсы и минусы его использования.
📌 Плюсы var:
✔️ Меньше "визуального шума": избавляет от длинных и громоздких объявлений.
✔️ Удобно при работе с дженериками и вложенными типами: никакого лишнего написания.
✔️ Код читается проще, когда тип очевиден из правой части.
Примеры, когда var выглядит отлично:
var map = new HashMap<String, List<Long>>();
var name = "LinkedIn";
var count = 42;
⚠️ Минусы var:
❌ Иногда теряется читаемость: особенно, когда возвращаемый тип не очевиден.
❌ Может прятать неожиданные типы, что усложняет отладку.
❌ Не подходит для публичных API / сигнатур, где тип данных должен быть явно указан.
Когда var может стать врагом:
var data = process(); // Непонятно, что за тип возвращается.
var a = someObj.getValue().getAnother().resolve(); // Много уровней вложенности.
📌 Мой вывод: var — это отличный инструмент, но важно знать, когда и как его использовать. Лично я применяю var, когда тип очевиден без догадок. Если нужно вчитываться или полагаться на IDE, лучше указать тип явно. Помните, что читаемость важнее краткости! 💡
Согласны с таким подходом? Или у вас есть свои мысли? Делитесь в комментариях, подписывайтесь и ставьте лайк! 🤗
#Java #var #кодстайл #java10 #java_interview_tasks
👍13❤3❤🔥1👎1🔥1🙏1
Что напечатает код?
Anonymous Quiz
21%
1236
33%
1237
6%
1239
0%
2319
23%
2317
7%
узнать ответ
10%
другой овтет
🔥10🤔4👍1
🔍 Ответ на задачу про порядок выполнения операций в Java:
Давайте посмотрим, что напечатает следующий код:
❓Что произойдёт при выполнении этого кода?
🧐 Важный момент — это порядок выполнения операций и вычислений.
Вначале вызывается int1(), который печатает 1 и возвращает 1.
Затем в правой части выполняется int2() * int3().
int2() печатает 2 и возвращает 2.
int3() печатает 3 и возвращает 3.
Происходит умножение (2 * 3 = 6).
Наконец, результат сложения: 1 + 6 = 7.
Итак, итоговый вывод будет:
1237
Первые три цифры — это значения, возвращаемые методами, а 7 — результат вычисления выражения. 🔢
Если вам интересны подобные разборы, ставьте лайк, не забывайте подписаться и оставлять свои комментарии! 🤗
#Java #порядок_выполнения #вычисления #java_interview_tasks
Давайте посмотрим, что напечатает следующий код:
public static void main(String[] args) {
System.out.print(int1() + int2() * int3());
}
private static int int1() {
System.out.print(1);
return 1;
}
private static int int2() {
System.out.print(2);
return 2;
}
private static int int3() {
System.out.print(3);
return 3;
}
❓Что произойдёт при выполнении этого кода?
🧐 Важный момент — это порядок выполнения операций и вычислений.
Вначале вызывается int1(), который печатает 1 и возвращает 1.
Затем в правой части выполняется int2() * int3().
int2() печатает 2 и возвращает 2.
int3() печатает 3 и возвращает 3.
Происходит умножение (2 * 3 = 6).
Наконец, результат сложения: 1 + 6 = 7.
Итак, итоговый вывод будет:
1237
Первые три цифры — это значения, возвращаемые методами, а 7 — результат вычисления выражения. 🔢
Если вам интересны подобные разборы, ставьте лайк, не забывайте подписаться и оставлять свои комментарии! 🤗
#Java #порядок_выполнения #вычисления #java_interview_tasks
👍26🔥3❤2🙏2
🔥4
🔥5😁1
🔍 Ответ на задачу про передачу примитивов в методы в Java
Давайте рассмотрим, что произойдёт при выполнении этого кода:
❓Чего ожидать от вывода?
🔎 В Java при передаче примитивных типов (таких как int) в методы используется передача по значению. Это означает, что в метод inc передаётся копия значения count, а не сама переменная. Таким образом, любые изменения над параметром count в методе inc не влияют на переменную count в методе main.
🌟 Вот шаги выполнения:
В main у нас переменная count равна 123.
Мы вызываем метод inc(count), передавая копию значения count.
В методе inc эта копия увеличивается на 1, но никак не затрагивает оригинальную переменную в main.
Поэтому System.out.println(count); выведет оригинальное значение: 123
🔗 Это пример важной концепции в Java — примитивы передаются по значению, и изменения не сохраняются вне метода. Помните об этом при проектировании ваших программ!
⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️
🔍 Ответ на задачу про неизменяемость объектов в Java
Здесь у нас код, который работает с неизменяемостью объектов в Java:
❓Что выведет этот код?
🤔 Давайте разберёмся. На первый взгляд могло бы показаться, что после вызова метода inc count увеличится. Но это не так.
🔸 Тип Integer — это неизменяемый объект в Java. Кроме того, при передаче в метод inc, создаётся копия ссылки, а не передача по ссылке, как в некоторых других языках.
🔸 Метод count++ использует count локально, создавая новый объект Integer, но не изменяет оригинальный объект count в main.
Таким образом, System.out.println(count); напечатает: 123
😯 Не забывайте об этих особенностях при работе с объектами! Если у вас есть мысли или вопросы, делитесь ими в комментариях! Подписывайтесь и ставьте лайк, чтобы не пропустить новые посты! 🤗
#Java #неизменяемость #Integer #java_interview_tasks
Давайте рассмотрим, что произойдёт при выполнении этого кода:
public static void main(String[] args) {
int count = 123;
inc(count);
System.out.println(count);
}
private static void inc(int count) {
count++;
}
❓Чего ожидать от вывода?
🔎 В Java при передаче примитивных типов (таких как int) в методы используется передача по значению. Это означает, что в метод inc передаётся копия значения count, а не сама переменная. Таким образом, любые изменения над параметром count в методе inc не влияют на переменную count в методе main.
🌟 Вот шаги выполнения:
В main у нас переменная count равна 123.
Мы вызываем метод inc(count), передавая копию значения count.
В методе inc эта копия увеличивается на 1, но никак не затрагивает оригинальную переменную в main.
Поэтому System.out.println(count); выведет оригинальное значение: 123
🔗 Это пример важной концепции в Java — примитивы передаются по значению, и изменения не сохраняются вне метода. Помните об этом при проектировании ваших программ!
⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️
🔍 Ответ на задачу про неизменяемость объектов в Java
Здесь у нас код, который работает с неизменяемостью объектов в Java:
public static void main(String[] args) {
Integer count = 123;
inc(count);
System.out.println(count);
}
private static void inc(Integer count) {
count++;
}
❓Что выведет этот код?
🤔 Давайте разберёмся. На первый взгляд могло бы показаться, что после вызова метода inc count увеличится. Но это не так.
🔸 Тип Integer — это неизменяемый объект в Java. Кроме того, при передаче в метод inc, создаётся копия ссылки, а не передача по ссылке, как в некоторых других языках.
🔸 Метод count++ использует count локально, создавая новый объект Integer, но не изменяет оригинальный объект count в main.
Таким образом, System.out.println(count); напечатает: 123
😯 Не забывайте об этих особенностях при работе с объектами! Если у вас есть мысли или вопросы, делитесь ими в комментариях! Подписывайтесь и ставьте лайк, чтобы не пропустить новые посты! 🤗
#Java #неизменяемость #Integer #java_interview_tasks
🔥10👍3😨2❤1🐳1
Сколько существует 6-значных чисел, в записи которых есть хотя бы одна чётная цифра?
👍5🥱4🤔2🔥1
🔍 Ответ на задачу про 6-значные числа и четные цифры:
Вместо подсчёта количества шестизначных чисел, в записи которых есть хотя бы одна чётная цифра, можно посчитать количество шестизначных чисел не обладающих данным свойством, то есть тех, в записи которых встречаются только нечётные цифры. Таких чисел:
5⁶ = (5³)² = 125² =
12·13·100 + 25 =
15625.
Всего же шестизначных чисел:
999 999 - 99 999 =
900 000.
Значит количество шестизначных чисел, обладающих указанным свойством, ровно:
900 000 - 15 625 =
884 375.
🚀Если вам понравилось это объяснение, ставьте лайк, подписывайтесь на канал и делитесь своими мыслями в комментариях!
🚀🚀 Если хотите больше таких задач ставьте 🔥 к этому посту.
#MathChallenge #Combinatorics #java_interview_tasks
Вместо подсчёта количества шестизначных чисел, в записи которых есть хотя бы одна чётная цифра, можно посчитать количество шестизначных чисел не обладающих данным свойством, то есть тех, в записи которых встречаются только нечётные цифры. Таких чисел:
5⁶ = (5³)² = 125² =
12·13·100 + 25 =
15625.
Всего же шестизначных чисел:
999 999 - 99 999 =
900 000.
Значит количество шестизначных чисел, обладающих указанным свойством, ровно:
900 000 - 15 625 =
884 375.
🚀Если вам понравилось это объяснение, ставьте лайк, подписывайтесь на канал и делитесь своими мыслями в комментариях!
🚀🚀 Если хотите больше таких задач ставьте 🔥 к этому посту.
#MathChallenge #Combinatorics #java_interview_tasks
🔥10👍4⚡2🤮2🐳1
Что напечатает код?
Anonymous Quiz
11%
"Аня", "Боря", "Вова"
2%
"Боря", "Вова", "Аня"
29%
"Боря", "Вова"
48%
"Боря", "Вова" и ексепшн
6%
не скомпилируется
3%
узнать ответ
👍14🔥2💩1🌚1
🔍 Ответ на задачу про вывод элементов списка
Тут есть одна особенность: индекс увеличивается до получения элемента из списка благодаря ++index.
При таком подходе, цикл начинает с индексом 1, а значит будет выбирать имена начиная с "Боря", а "Аня" будет пропущена. Значение index будет увеличено на 1, после чего произойдет проверка условия index < names.size(), и условие будет истинным до тех пор, пока индекс не станет равен размеру списка.
Таким образом, в результате выполнение кода мы увидим такой вывод на консоли:
Боря
Вова
А дальше будет эксепшен, так как следующего индекса в массиве уже нет.
🥳 Надеюсь, этот разбор был полезен! Не забудьте лайкнуть пост, подписаться на канал и оставить комментарий, если у вас есть вопросы или дополнения!
#java #coding #++i #java_interview_tasks
Тут есть одна особенность: индекс увеличивается до получения элемента из списка благодаря ++index.
При таком подходе, цикл начинает с индексом 1, а значит будет выбирать имена начиная с "Боря", а "Аня" будет пропущена. Значение index будет увеличено на 1, после чего произойдет проверка условия index < names.size(), и условие будет истинным до тех пор, пока индекс не станет равен размеру списка.
Таким образом, в результате выполнение кода мы увидим такой вывод на консоли:
Боря
Вова
А дальше будет эксепшен, так как следующего индекса в массиве уже нет.
🥳 Надеюсь, этот разбор был полезен! Не забудьте лайкнуть пост, подписаться на канал и оставить комментарий, если у вас есть вопросы или дополнения!
#java #coding #++i #java_interview_tasks
👍13🔥2🐳2❤1
🔥5👍2❤1
🔍 Ответ на задачу про логические операторы
Давайте разберем работу логических операторов в данном коде на Java. У нас есть три логические переменные: a, b, и c, со значениями true, false, и false соответственно. В условии if используется комбинация операторов (логическое "ИЛИ") и && (логическое "И").
Стоит помнить, что оператор && имеет более высокий приоритет, чем оператор . Поэтому выражение b && c будет вычислено первым. Но поскольку b равно false, а c также false, это выражение дает в результате false.
Далее, выражение a false будет всегда истинным, так как a равно true. Следовательно, полное условие в if равно true, и будет выполнена первая ветка блока:
1
Когда дело касается вложенных логических операторов в условных выражениях, расстановка скобок может значительно упростить понимание кода и избежать путаницы. В данном случае, добавим скобки для ясности:
Скобки вокруг выражения (b && c) четко определяют, что это будет вычислено в первую очередь. Это не только делает код более понятным, но и исключает возможность неправильной интерпретации, особенно если у вас большой и сложный условный оператор.
Используйте скобки в логических выражениях, чтобы код был читаемым как для вас, так и для вашей команды! Рекомендуется всегда группировать логические операции скобками, если существует вероятность появления неоднозначности.
✍️ Научитесь писать чистый и понятный код! Поддержите эту идею, поставив лайк, подписывайтесь на канал и оставляйте комментарии с вашими мыслями об использовании скобок в коде.
#java #logicaloperators #boolean #clean_code #java_interview_tasks
Давайте разберем работу логических операторов в данном коде на 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
🔥7👍5❤1
Вот такую задачу с собеседования нашел:
Что думаете?)
Что думаете?)
Forwarded from Верхняя полка📝
Наверняка эта задачка входит в число хрестоматийных и встречается на собеседованиях по #Java, но поскольку я по ним не хожу, пришлось убить часок на разбирательство с ней. Поделюсь с вами; вдруг кто-то тоже встретит.
🎓 Дано
Ванильный пул потоков на голом JDK (аналоги из класса
И некий метод, который сначала просто напихивает задачки в этот пул:
, потом идёт по своим делам, а когда заканчивает с ними, проверяет готовность задачек и, если надо, дожидается завершения каждой, чтобы продолжить работу дальше:
🔍 Найти
Какого _🙊_ в некоторых случаях метод намертво зависает на вызове
При этом в дампе потоков нет никаких следов задач, которые бы зависли/зациклились/заблокированы.
🔑 Решение
Вариант 1. Добавить таймаут в метод
Вариант 2. Извернуться как-нибудь так, чтобы прийти к вызову вида
Вариант 3. Обернуть вызов
Казалось бы, смысла в нём нет, ведь если задача не завершена (
, то есть "сделанной" считается любая не новая задача (в том числе когда она ещё в работе).
А метод
, то есть ожидание наступит для любого состояния, предшествующего завершению, в том числе для вышеупомянутого
Но если бы задача, на которой завис наш поток, была в состоянии
А как она могла оказаться
✅ Вся цепочка кратко:
— не влезающие в очередь задачи молча отбрасываются политикой пула, оставляя им статус
— видя этот статус, метод
— исключить ожидание можно добавлением проверки на
⚠️ Если очередь будет большой, а задачи — долгоиграющими, можно нарваться на случай, когда задача уже в очереди и имеет шанс быть выполненной, но цикл с вызовом
Мораль: пишите однопоточные приложения🤪
🎓 Дано
Ванильный пул потоков на голом 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()
её не подождёт. В этом случае решение должно быть другим.Мораль: пишите однопоточные приложения🤪
🔥8👍2😁2