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

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

По рекламе: @alexzelentsov и https://telega.in/c/java_interview_tasks
Download Telegram
Какие пары (x, y) могут напечататься после того, как отработают thread1 и thread2?
👍7
Какие пары (x, y) могут напечататься после того как отработают thread1 и thread2?
Anonymous Quiz
27%
(0, 0), (1, 1), (2, 1), (1, 2), (2, 2)
23%
(1, 1), (2, 1), (1, 2), (2, 2)
8%
(2, 1), (1, 2), (2, 2)
17%
(1, 2), (2, 2)
25%
(2, 2)
👍10🔥4
Java Interview Tasks
Какие пары (x, y) могут напечататься после того, как отработают thread1 и thread2?
Ответ к последнему вопросу:
Проблема тут в том, что происходит инкремент полей под гонкой и операция i++ не атомарна. По факту это две операции: чтение и запись. Может случиться так, что первый поток прочитал значение поля, потом второй поток увеличил значение, а после этого первый поток перетер его, сделав инкремент значения, которое он прочитал в самом начале.
Volatile тут значения не имеет.
Что бы решить проблему, можно использовать AtomicInteger и атомарные операции, например, incrementAndGet()
Следующий вопрос: почему нельзя увидеть x = 0?
Видимость всех переменных гарантируется тем, что перед чтением переменных делается join на тредах, в спеке по этому поводу написано следующее: All actions in a thread happen-before any other thread successfully returns from a join() on that thread.
Прочитать про это можно тут - https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html (17.4.5. Happens-before Order)
Похожая проблема с неатомарностью инкрементов рассмотрена здесь - https://github.com/openjdk/jcstress/blob/master/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/api/API_02_Arbiters.java
👍9🔥5
Что напечатает код?
🔥9🤩2
Java Interview Tasks
Что напечатает код?
Ответ к задаче про сравнение строк:

Первое, что нужно отметить, что тут сравниваются не значения строк, а ссылки на строки. Поэтому ide подчёркивает все равенства и предлагает правильный вариант сравнения значений строк через “equals”

s1 и s2 это один и тот же объект, так как в java есть пул строк, и для s2 не создается новый объект, так как в пуле уже есть строка с таким же значением.
А вот s3 создается через new и в пул строк не попадает. Поэтому s1 и s3 это разные объекты, поэтому сравнение вернёт false
s4 будет гарантированно из пула, так как вызван метод intern.
s5 работает аналогично s2

Выводы:
1) сравнивая объекты через == , можно не всегда получить то, что ожидаешь, поэтому лучше этого не делать и использовать метод equals. Сравнивая через == вы должны знать что делаете.
2) Если ide подчёркивает код, стоит обратить на это внимание, скорее всего у вас проблемы в коде
3) Метод intern перед созданием объекта String смотрит, есть ли этот объект в пуле стрингов и возвращает его. Иначе создается новый объект в пуле.

Статья на эту тему: https://habr.com/ru/post/79913/

Видео, которое рекомендую посмотреть, про intern там тоже идёт речь: https://youtu.be/SZFe3m1DV1A
👍24🔥52🎉1🤩1
Какие тут есть проблемы в коде?
#spring
👍9💩6🔥2
Ответ к последнему вопросу про спринг контроллер (https://t.me/java_interview_tasks/101):
1. Надо сделать поле starterService final. Аннотация @RequiredArgsConstructor добавляет конструктор со всеми final полями, поэтому при создании бина поле starterService не проинициализируется.
2. Не хватает аннотации @PathVariable. Иначе будет всегда collector = null и NPE в collector.toString()

Также был вопрос про @Autowired над полем и над конструктором: https://t.me/java_interview_tasks/62
👍7🔥21
Java Interview Tasks
Что больше занимает места List<Integer> или int[] с 10 элементами каждый?
# openjdk-17.0.1
# Running 64-bit HotSpot VM. # Using compressed oop with 3-bit shift. # Using compressed klass with 3-bit shift. # Objects are 8bytes aligned.
Разъяснение к вопросу про int[] и ArrayList<Integer>:

Пустой массив весит 16 байт , учитывая выравнивание на 8
(про подсчет байтов для конкретного класса был вопрос с более детальным объяснением - https://t.me/java_interview_tasks/56)

[I object internals:
OFF SZ TYPE DESCRIPTION
0 8 (object header: mark)
8 4 (object header: class)
12 4 (array length)
12 4 (alignment/padding gap)
16 0 int [I.<elements>
Instance size: 16 bytes

Массив с 10-ю элементами весит 56 (16 + 10 * 4 (4 - размер int в массиве))
int[]:
[I@2328c243d object externals:
SIZE TYPE VALUE
56. [I [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Total size: 56


ArrayList из 10-ти элементов выглядит по памяти как показано ниже:
ArrayList<Integer>:
java.util.ArrayList@281e3708d object externals:
SIZE TYPE PATH VALUE
24 java.util.ArrayList (object)
56 [LObject; .elementData [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
16 Integer .elementData[0] 0
16 Integer .elementData[1] 1
16 Integer .elementData[2] 2
16 Integer .elementData[3] 3
16 Integer .elementData[4] 4
16 Integer .elementData[5] 5
16 Integer .elementData[6] 6
16 Integer .elementData[7] 7
16 Integer .elementData[8] 8
16 Integer .elementData[9] 9

Total size: 240

Получается 240 байт против 56 -> разница чуть больше чем в 4 раза между массивом и списком

Разница большая из-за того, что в листе элементы не примитивы, как в массиве, а объекты
Есть библиотеки, которые позволяют хранить примитивы, их довольно много:
например trove4j или fastutil

Для сравнения it.unimi.dsi.fastutil.ints.IntArrayList с 10-ю элементами:

it.unimi.dsi.fastutil.ints.IntArrayList@17695df3d object externals:

ADDRESS SIZE TYPE PATH VALUE
6233247b0 24 IntArrayList (object)
623357278 56 [I .a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Total size: 80

Про сравнение производительности можно почитать здесь - https://www.baeldung.com/java-list-primitive-performance

Вопрос к читателям:
Благодаря чему достигается прирост производительности в коллекциях с примитивами, кроме экономии памяти?
👍13🔥5👏1
Что напечатает код?
👍11👏3🔥2
Что напечатает код ?
Anonymous Quiz
8%
1
43%
2
33%
3
5%
Что-то ещё
11%
Узнать результаты
👍20🔥12👏3🎉1
Java Interview Tasks
Что напечатает код?
Ответ на задачу про instance of:
Если значение, переданное в оператор instance of == null, тогда результат будет false.

Ссылка на спеку: https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.20.2 (If the value of the RelationalExpression is the null reference (§4.1), then the result is false.)

В jdk 14 появились новые возможности, связанные с instance of.
Главная вещь это то, что теперь не надо делать cast внутри оператора, то есть можно так:
if (obj instanceof String obj) {
System.out.println(obj.toLowerCase());
}
(подробнее тут: https://habr.com/ru/post/477654/)
👍14🔥31
Известно, что x++ над volitile полем x не атомарен (https://t.me/java_interview_tasks/94), давайте посмотрим насколько серьезными могут быть потери данных в случае гонки:

Вопрос:
Что может напечатать код?

(Варианты ответов в следующем опросе, в каждом варианте перечислены списки значений которые могут быть выведены на экран)

#concurrency
👍6🔥5
🤯14👍7😱6🔥5
Java Interview Tasks
Известно, что x++ над volitile полем x не атомарен (https://t.me/java_interview_tasks/94), давайте посмотрим насколько серьезными могут быть потери данных в случае гонки: Вопрос: Что может напечатать код? (Варианты ответов в следующем опросе, в каждом варианте…
Ответ к вопросу про инкремент под гонкой:
Рассуждения аналогичные как и тут:
https://t.me/java_interview_tasks/96
Для примера, посмотрим, как может получится 2 - это самый интересный случай (см. картинку к посту)
Остальные варианты (больше 2) возможно получить аналогичными рассуждениями.

Выводы: этот простой пример показывает, что не синхронизированный счётчик может терять много данных.
Если вам нужно использовать счётчик под гонкой, то надо синхронизировать инкремент или использовать уже синхронизированные счётчики, например, AtomicInteger

Упражнение для читателей:
Доказать, что 0 и 1 напечататься не могут
👍18🔥3
Какие проблемы есть в этом коде ?
👍9🔥5👏1
Java Interview Tasks
Какие проблемы есть в этом коде ?
Проблемы в коде:
1) notify нельзя переопределять, потому что он final
2) Если вызывать notify, то нужно это делать внутри synchronized блока
3) lock не инициализируется и будет npe
👍31🔥5
Что напечатает код?
👍7🤔5💩5🔥2
🤔11🔥7👍4🤯2