👍7❤2🔥2😁1
Ответ на задачи про DoubleRead и BenignRace:
Устоявшиеся семантики при доступе к совместно используемым данным с возможными конфликтами позволяют создавать примеры, где объекты публикуются без проблем через гонку. Это состояние известно как "безопасная гонка" ("benign race"). Оно обычно выглядит следующим образом:
T get() {
T t = instance; // 1: ОДНО неоднозначное чтение
if (t == null) {
t = new T(...); // 2: БЕЗОПАСНОЕ, ИДЕМПОТЕНТНОЕ создание
instance = t; // запись с гонкой
}
return t;
}
Механизм этой безопасной гонки понятен: если мы что-то читаем, мы читаем это полностью, потому что семантика финальных полей защищает нас (смотри вопросы про TestFinalConcurrency и TestFinalConcurrency2 ). Если мы читаем null, то можем это исправить, создавая экземпляр самостоятельно и сохраняя его для будущих вызовов. Поскольку может произойти гонка записи, важно, чтобы создание объекта было идемпотентным, то есть независимо от того, сколько потоков инициализируют объект, все они сохранят семантически идентичный объект.
Дополнительная сложность, предписанная моделью памяти Java (JMM), заключается в необходимости одноразового чтения. Если мы прочитаем поле instance один раз, выясним, что оно не равно null, а затем прочитаем его снова, мы можем получить null при втором чтении!
Устоявшиеся семантики при доступе к совместно используемым данным с возможными конфликтами позволяют создавать примеры, где объекты публикуются без проблем через гонку. Это состояние известно как "безопасная гонка" ("benign race"). Оно обычно выглядит следующим образом:
T get() {
T t = instance; // 1: ОДНО неоднозначное чтение
if (t == null) {
t = new T(...); // 2: БЕЗОПАСНОЕ, ИДЕМПОТЕНТНОЕ создание
instance = t; // запись с гонкой
}
return t;
}
Механизм этой безопасной гонки понятен: если мы что-то читаем, мы читаем это полностью, потому что семантика финальных полей защищает нас (смотри вопросы про TestFinalConcurrency и TestFinalConcurrency2 ). Если мы читаем null, то можем это исправить, создавая экземпляр самостоятельно и сохраняя его для будущих вызовов. Поскольку может произойти гонка записи, важно, чтобы создание объекта было идемпотентным, то есть независимо от того, сколько потоков инициализируют объект, все они сохранят семантически идентичный объект.
Дополнительная сложность, предписанная моделью памяти Java (JMM), заключается в необходимости одноразового чтения. Если мы прочитаем поле instance один раз, выясним, что оно не равно null, а затем прочитаем его снова, мы можем получить null при втором чтении!
Telegram
Java Interview Tasks
Что может напечатать код?
Методы actor1, actor2 и eraser вызываются одновременно в параллельных потоках
Методы actor1, actor2 и eraser вызываются одновременно в параллельных потоках
👍7🔥3🤔2
#реклама
Привет, коллеги! А вы знаете, что митапы в IT — это не просто тусовка, а мощный рывок для роста?
Здесь можно:
— Найти работу — HRы и тимлиды ищут таланты прямо в кулуарах.
— Прокачать скиллы — доклады от практиков, а не теория из учебников.
— Завести полезные знакомства — нетворкинг круче, чем LinkedIn
— Вдохновиться — после митапа хочется кодить, а не залипать в Netflix.
В нашем tg канале Митапочная:
— Только соль: анонсы ближайших митапов без воды
— Четко, коротко, по делу: тема + дата + ссылка на регистрацию
— Никакого спама — только то, что действительно стоит твоего времени
Главное в IT — не только код, но и люди вокруг. Присоединяйся! 🚀
Привет, коллеги! А вы знаете, что митапы в IT — это не просто тусовка, а мощный рывок для роста?
Здесь можно:
— Найти работу — HRы и тимлиды ищут таланты прямо в кулуарах.
— Прокачать скиллы — доклады от практиков, а не теория из учебников.
— Завести полезные знакомства — нетворкинг круче, чем LinkedIn
— Вдохновиться — после митапа хочется кодить, а не залипать в Netflix.
В нашем tg канале Митапочная:
— Только соль: анонсы ближайших митапов без воды
— Четко, коротко, по делу: тема + дата + ссылка на регистрацию
— Никакого спама — только то, что действительно стоит твоего времени
Главное в IT — не только код, но и люди вокруг. Присоединяйся! 🚀
👍7🔥1
Полезный доклад про рекурсию:
https://youtu.be/VAUQVmPMiYw?si=2l0A071vhTnFjWQN
https://youtu.be/VAUQVmPMiYw?si=2l0A071vhTnFjWQN
YouTube
Максим Сидоров — Как избавиться от рекурсии и исправить глупую ошибку в Google
Подробнее о Java-конференциях:
— весной — JPoint: https://jrg.su/gTrwHx
— осенью — Joker: https://jrg.su/h7yvG4
— —
Скачать презентацию с сайта JPoint — https://jrg.su/SbBUTL
Спикер рассказал про исследование различных подходов к оптимизации рекурсии. Рассмотрел…
— весной — JPoint: https://jrg.su/gTrwHx
— осенью — Joker: https://jrg.su/h7yvG4
— —
Скачать презентацию с сайта JPoint — https://jrg.su/SbBUTL
Спикер рассказал про исследование различных подходов к оптимизации рекурсии. Рассмотрел…
👍3🔥2❤1
Что напечатает код?
Anonymous Quiz
31%
"123"
31%
"456"
3%
"123456"
4%
будет exception
28%
будет ошибка компиляции
4%
узнать ответ
🔥6👍2😁1😱1
Ответ на вопрос про нестатический блок инициализации: здесь пример неочевидной опережающей инициализации поля, такой синтаксис в джаве разрешен, внутри блока инициализации s будет равно "456", но значение поля будет переопределено в строке 15, поэтому ответ "123".
Telegram
Java Interview Tasks
Что напечатает код?
👍10❤1🔥1
Что напечатает код?
Anonymous Quiz
5%
true, true, true
33%
false, true, true
10%
false, false, true
43%
false, false, false
4%
другой вариант
5%
узнать результаты
👍7🔥2😁1
#реклама
📂 Папка, которую вы бы хотели найти полгода назад
https://t.me/addlist/xjhUe5s57kg4NWNi
📈 Развиваешь экспертный канал в IT, AI или маркетинге?
В подборке собрали только практиков: специалисты и команды, которые действительно работают с ИИ и IT-продуктами.
Никакой теории ради охватов, репостов с трендами и «обёрток» без содержания.
Без марафонов, геймификации и чат-ботов для вовлечённости. Только прикладной опыт, который помогает расти бизнесу.
Что в папке:
— Маркетинг ИИ-продуктов: без буллшита и по шагам
— Опыт запуска и масштабирования IT-продуктов
— Контент, который действительно читает ЦА
— Настоящие кейсы. Настоящие люди.
https://t.me/addlist/xjhUe5s57kg4NWNi
📂 Папка, которую вы бы хотели найти полгода назад
https://t.me/addlist/xjhUe5s57kg4NWNi
📈 Развиваешь экспертный канал в IT, AI или маркетинге?
В подборке собрали только практиков: специалисты и команды, которые действительно работают с ИИ и IT-продуктами.
Никакой теории ради охватов, репостов с трендами и «обёрток» без содержания.
Без марафонов, геймификации и чат-ботов для вовлечённости. Только прикладной опыт, который помогает расти бизнесу.
Что в папке:
— Маркетинг ИИ-продуктов: без буллшита и по шагам
— Опыт запуска и масштабирования IT-продуктов
— Контент, который действительно читает ЦА
— Настоящие кейсы. Настоящие люди.
https://t.me/addlist/xjhUe5s57kg4NWNi
❤4👍1
🔍 Ответ на вопрос про сравнение объектов в Java:
Разберемся, как Java сравнивает объекты и что скрывается за методами equals() и hashCode().
У нас есть два объекта:
Object o1 = new Object();
Object o2 = new Object();
Теперь давайте посмотрим, что произойдет, если мы их сравним:
1️⃣ Сравнение ссылок (оператор ==):
System.out.println((o1 == o2)); // Выводит: false
🔸 Оператор == сравнивает адреса в памяти. Поскольку o1 и o2 — разные объекты, они находятся по разным адресам, что возвращает false.
2️⃣ Сравнение методом equals():
System.out.println(o1.equals(o2)); // Выводит: false
🔸 Метод equals() по умолчанию в классе Object работает как ==, сравнивая ссылки. Без переопределения возвращает false.
3️⃣ Сравнение значений hashCode():
System.out.println(o1.hashCode() == o2.hashCode()); // Выводит: false
🔸 Метод hashCode() вычисляет уникальное значение на основе текущего объекта (реализация может быть различна и может зависеть от платформы). Обычно для двух разных объектов значения будут уникальными.
Почитать подробнее можно тут.
💡 Итак, вывод программы:
false
false
false
➖➖➖➖➖
✍️ В реальной практике нужно переопределять equals() и hashCode(), чтобы они отражали бизнес-логику ваших объектов.
Будьте внимательны и прописывайте правильные сравнения! 🤓
➖➖➖➖➖
🎓 Надеюсь, это было полезно! Оставьте свои вопросы и комментарии ниже. 👇
#java #программирование #equals #hashcode #разработка
Разберемся, как Java сравнивает объекты и что скрывается за методами equals() и hashCode().
У нас есть два объекта:
Object o1 = new Object();
Object o2 = new Object();
Теперь давайте посмотрим, что произойдет, если мы их сравним:
1️⃣ Сравнение ссылок (оператор ==):
System.out.println((o1 == o2)); // Выводит: false
🔸 Оператор == сравнивает адреса в памяти. Поскольку o1 и o2 — разные объекты, они находятся по разным адресам, что возвращает false.
2️⃣ Сравнение методом equals():
System.out.println(o1.equals(o2)); // Выводит: false
🔸 Метод equals() по умолчанию в классе Object работает как ==, сравнивая ссылки. Без переопределения возвращает false.
3️⃣ Сравнение значений hashCode():
System.out.println(o1.hashCode() == o2.hashCode()); // Выводит: false
🔸 Метод hashCode() вычисляет уникальное значение на основе текущего объекта (реализация может быть различна и может зависеть от платформы). Обычно для двух разных объектов значения будут уникальными.
Почитать подробнее можно тут.
💡 Итак, вывод программы:
false
false
false
➖➖➖➖➖
✍️ В реальной практике нужно переопределять equals() и hashCode(), чтобы они отражали бизнес-логику ваших объектов.
Будьте внимательны и прописывайте правильные сравнения! 🤓
➖➖➖➖➖
🎓 Надеюсь, это было полезно! Оставьте свои вопросы и комментарии ниже. 👇
#java #программирование #equals #hashcode #разработка
Telegram
Java Interview Tasks
Что напечатает код? (Супермаловероятными событиями тут пренебрегаем)
👍15🔥5🙏2
Что произойдет при запуске кода?
Anonymous Quiz
15%
напечатается null
30%
ничего не напечатается
48%
напечатается эксепшен в лог в каком-то виде
7%
узнать ответ
👍5👌2🔥1
🔍 Ответ на вопрос про пропавший эксепшен:
Привет, друзья! Сегодня обсудим скрытую проблему с логированием исключений, которая часто возникает в многопоточной среде.
На первый взгляд все кажется довольно обычным: мы отправляем задачу на выполнение, которая вызывает метод logString с null значением. Это должно вызвать NullPointerException.
❓ Где же исключение? Вы могли заметить, что исключение не будет напечатано в логи, даже если оно происходит. Почему?
🔎 Объяснение:
Исключения в Java, возникающие в потоке, обрабатываются контекстом этого потока.
В случае использования ExecutorService.submit(...), если задача выбрасывает исключение, оно остается незамеченным, потому что submit возвращает Future, который просто тихо удаляет это исключение.
Если вы не вызываете методы get() у Future и не обрабатываете возможное исключение, вы его просто не увидите.
💡 Как это исправить? Чтобы исключение стало видимым, можно сделать следующее:
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(() -> logString(null));
try {
future.get(); // Обрабатываем возможное исключение
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); // Выводим исключение в логи
} finally {
executorService.shutdown();
}
}
📌 В этом изменении future.get() либо вернёт результат, либо выбросит ExecutionException, если что-то пошло не так, позволяя вам логировать и обрабатывать ситуацию корректно.
👨💻 Вывод: Будьте внимательны при работе с многопоточностью. Убедитесь, что вы корректно обрабатываете возможные исключения, особенно при использовании ExecutorService.
➖➖➖➖➖
🎓 Надеюсь, это было полезно! Оставьте свои вопросы и комментарии ниже. 👇
Подписывайтесь, чтобы не пропустить важные советы и приемы! 🔥
#java #многопоточность #исключения #программирование #лучшиепрактики
Привет, друзья! Сегодня обсудим скрытую проблему с логированием исключений, которая часто возникает в многопоточной среде.
На первый взгляд все кажется довольно обычным: мы отправляем задачу на выполнение, которая вызывает метод logString с null значением. Это должно вызвать NullPointerException.
❓ Где же исключение? Вы могли заметить, что исключение не будет напечатано в логи, даже если оно происходит. Почему?
🔎 Объяснение:
Исключения в Java, возникающие в потоке, обрабатываются контекстом этого потока.
В случае использования ExecutorService.submit(...), если задача выбрасывает исключение, оно остается незамеченным, потому что submit возвращает Future, который просто тихо удаляет это исключение.
Если вы не вызываете методы get() у Future и не обрабатываете возможное исключение, вы его просто не увидите.
💡 Как это исправить? Чтобы исключение стало видимым, можно сделать следующее:
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(() -> logString(null));
try {
future.get(); // Обрабатываем возможное исключение
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); // Выводим исключение в логи
} finally {
executorService.shutdown();
}
}
📌 В этом изменении future.get() либо вернёт результат, либо выбросит ExecutionException, если что-то пошло не так, позволяя вам логировать и обрабатывать ситуацию корректно.
👨💻 Вывод: Будьте внимательны при работе с многопоточностью. Убедитесь, что вы корректно обрабатываете возможные исключения, особенно при использовании ExecutorService.
➖➖➖➖➖
🎓 Надеюсь, это было полезно! Оставьте свои вопросы и комментарии ниже. 👇
Подписывайтесь, чтобы не пропустить важные советы и приемы! 🔥
#java #многопоточность #исключения #программирование #лучшиепрактики
🔥15❤4👍4🙏1
Какие значения могут напечататься? (thread1 и thread2 запускаются одновременно в разных потоках)
Anonymous Quiz
17%
"0, 0", "1, 1"
8%
"0, 0", "1, 1", "0, 1"
59%
"0, 0", "1, 1", "0, 1", "1, 0"
4%
свой вариант хочу предложить
12%
узнать ответ
🔥7👍2🐳2
🔍 Ответ на вопрос про volatile и массивы в Java:
📌 Многие разработчики могут ошибочно полагать, что при объявлении массива volatile все его элементы также будут обладать свойствами volatile. Однако это не так!
Пример выше как раз демонстрирует эту особенность.
🔎 Объяснение:
volatile int[] arr делает переменную arr ссылкой volatile. Это означает, что любые изменения ссылки на массив будут видны другим потокам.
Однако элементы массива не наследуют volatile-свойство. Таким образом, arr[0] и arr[1] не имеют гарантий видимости друг для друга.
➖➖➖➖➖
Ставьте лайк , если нашли это полезным и задавайте свои вопросы и комментарии ниже для получения дополнительных знаний! 🚀
#java #многопоточность #volatile #программирование
📌 Многие разработчики могут ошибочно полагать, что при объявлении массива volatile все его элементы также будут обладать свойствами volatile. Однако это не так!
Пример выше как раз демонстрирует эту особенность.
🔎 Объяснение:
volatile int[] arr делает переменную arr ссылкой volatile. Это означает, что любые изменения ссылки на массив будут видны другим потокам.
Однако элементы массива не наследуют volatile-свойство. Таким образом, arr[0] и arr[1] не имеют гарантий видимости друг для друга.
➖➖➖➖➖
Ставьте лайк , если нашли это полезным и задавайте свои вопросы и комментарии ниже для получения дополнительных знаний! 🚀
#java #многопоточность #volatile #программирование
Telegram
Java Interview Tasks
Какие значения могут напечататься? (thread1 и thread2 запускаются одновременно в разных потоках)
🔥9👍4❤3👎1👏1🙏1🐳1
Что напечатает код?
Anonymous Quiz
31%
Integer
2%
Long
12%
long
26%
int...
4%
Integer...
8%
Object
9%
ничего
8%
узнать ответ
👍8🤨7🔥2
🔍 Ответ на задачу про то, как Java выбирает перегрузку метода?
🚀🚀🚀Когда вы вызываете метод в Java, который имеет несколько перегруженных вариантов, компилятор должен решить, какой из них использовать. Давайте разберёмся, как он это делает на примере вызова метода printFor(42).
Вот правила, которыми руководствуется компилятор:
🚀 Точный тип: Ищет метод с точным совпадением типа аргумента. У нас его нет для int, так как метода printFor(int) нет.
🚀 Примитивное расширение (widening): Далее проверяется, можно ли расширить примитивный тип. 42 (int) может быть преобразован в long, и метод printFor(long) подходит.
🚀 Автоупаковка (boxing): Если расширение невозможно, оценивается автоупаковка. int может стать Integer, что делает метод printFor(Integer) возможным, но менее предпочтительным, чем printFor(long).
🚀 Varargs (массив произвольной длины): Как запасной вариант, компилятор рассматривает использование varargs. Метод printFor(int...) подходит, но также менее предпочтителен.
🚀 Автоупаковка в Object: Ещё менее специфичный вариант — преобразование в Integer и затем в Object для printFor(Object).
🔗🔗 🔗 В итоге, компилятор выбирает printFor(long), потому что расширение примитивного типа более предпочтительно, чем автоупаковка и varargs. Это позволяет Java эффективно и предсказуемо обрабатывать вызовы методов!
🎓 Надеюсь, это было полезно! Оставьте свои вопросы, лайки и комментарии ниже. 👇
#Java #Программирование #CodingTips #JavaTips #java_interview_tasks
🚀🚀🚀Когда вы вызываете метод в Java, который имеет несколько перегруженных вариантов, компилятор должен решить, какой из них использовать. Давайте разберёмся, как он это делает на примере вызова метода printFor(42).
Вот правила, которыми руководствуется компилятор:
🚀 Точный тип: Ищет метод с точным совпадением типа аргумента. У нас его нет для int, так как метода printFor(int) нет.
🚀 Примитивное расширение (widening): Далее проверяется, можно ли расширить примитивный тип. 42 (int) может быть преобразован в long, и метод printFor(long) подходит.
🚀 Автоупаковка (boxing): Если расширение невозможно, оценивается автоупаковка. int может стать Integer, что делает метод printFor(Integer) возможным, но менее предпочтительным, чем printFor(long).
🚀 Varargs (массив произвольной длины): Как запасной вариант, компилятор рассматривает использование varargs. Метод printFor(int...) подходит, но также менее предпочтителен.
🚀 Автоупаковка в Object: Ещё менее специфичный вариант — преобразование в Integer и затем в Object для printFor(Object).
🔗🔗 🔗 В итоге, компилятор выбирает printFor(long), потому что расширение примитивного типа более предпочтительно, чем автоупаковка и varargs. Это позволяет Java эффективно и предсказуемо обрабатывать вызовы методов!
🎓 Надеюсь, это было полезно! Оставьте свои вопросы, лайки и комментарии ниже. 👇
#Java #Программирование #CodingTips #JavaTips #java_interview_tasks
1👍23🔥5❤3