uk
Feedback
Уютное сообщество джавистов

Уютное сообщество джавистов

Відкрити в Telegram

Уютное сообщество джавистов - это хорошие материалы,задачки, туториалы для проверки знаний и обратная связь от соратников по изучению. @viktorreh

Показати більше
2 064
Підписники
Немає даних24 години
-77 днів
-1930 день
Архів дописів
🔥 Хардкорный тест для разработчиков, тимлидов и архитекторов! ➡️ Ответьте на 11 вопросов и узнайте, достаточно ли у вас знан
🔥 Хардкорный тест для разработчиков, тимлидов и архитекторов! ➡️ Ответьте на 11 вопросов и узнайте, достаточно ли у вас знаний, чтобы пройти онлайн-курс «Software Architect» в OTUS по спец.цене. 🦾 Курс поможет прокачать весь арсенал навыков, необходимых архитектору ПО. Возможна рассрочка. 💣 Успешное прохождение теста откроет доступ к 2 урокам курса: — Модели межсервисного взаимодействияАрхитектурное свойство "Сопровождаемость" на примере сервисов k8s ➡️ Пройти тест: https://otus.pw/ovR0/ Реклама. Информация о рекламодателе на сайте www.otus.ru

Что такое effectively final и что с ним делать Начну с правильного ответа на вопрос выше. В точке Б мы получим предупреждение компилятора: local variables referenced from a lambda expression must be final or effectively final В этом посте обсудим, что означает effectively final, о чём молчит спецификация и как менять переменные внутри лямбд. Про модификатор final всё понятно — он запрещает изменение переменной
final int count = 100;

count всегда будет равен 100. Каждый, кто напишет
count = 200;

будет осуждён компилятором. Для ссылок схема такая же:
final User admin = User.createAdmin();

Ссылка admin всегда будет указывать на объект User с параметрами админа. Никто не может её переприсвоить:
❌ admin = new User(…)

Effectively final называется переменная, значение которой не меняется после инициализации. По сути это тот же final, но без ключевого слова. Чтобы компилятор не ругался, надо выполнить два условия: 1️⃣ Локальная переменная однозначно определена до начала лямбда-выражения Так не скомпилируется:
int x;
if (…) х = 10

Вот так норм:
int x;
if (…) х = 10; else х = 15;

2️⃣ Переменная не меняется внутри лямбды и после неё
int х = 10;
…лямбда…
❌ х = 15

User user = …
…лямбда…
❌ user = userRepository.findByName(…)
✅ user.setTIN(…)

❓ Зачем нужно такое ограничение? JLS 15.27.2 говорит, что ограничение помогает избежать многопоточных проблем: The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems С первого взгляда звучит разумно. Основное применение лямбд — в рамках Stream API. В Stream API есть опция parallel(), которая запускает выполнение в разных потоках. Там и возникнут concurrency problems. Но я не принимаю это объяснение, потому что: 🤔 С каких пор компилятор волнуют многопоточные проблемы? Вся многопоточка отдана под контроль разработчика с начала времён 🤔 Если локальная переменная станет полем класса, то компилятор перестанет ругаться. При этом вероятность concurrency problems увеличится в разы Моя гипотеза: требование final/effectively final связано с особенностями реализации лямбд и ограничением модели памяти. Это технические сложности в JVM и ничего больше. Отсутствие многопоточных проблем, о которых говорится в JLS, это всего лишь следствие, а не причина. ❓ Как же менять переменные внутри лямбд? 1️⃣ Сделать переменную полем класса:
int count;
public void m() {
   list.forEach(v -> count++);
}

Не лучший вариант, переменная доступна теперь другим потокам. Concurrency problems! 2️⃣ Использовать Atomic обёртку Для примитивов:
AtomicInteger count = new AtomicInteger(0);
list.forEach(v -> count.incrementAndGet())

Для ссылок:
AtomicReference<User> user = new AtomicReference<>();
…map(i -> user.set(…))

3️⃣ Использовать массив с одним элементом
int[] res = new int[] {0};
list.forEach(v -> res[0]++);

Популярный вариант, который подходит и для примитивов, и для ссылок. Но мне больше нравится вариант с Atomic:)

Почему нельзя использовать byte[] в качестве ключа в HashMap? Хэш-код массива не зависит от хранимых в нем элементов, а присваивается при создании массива (метод вычисления хэш-кода массива не переопределен и вычисляется по стандартному Object.hashCode() на основании адреса массива). Так же у массивов не переопределен equals и выполняется сравнение указателей. Это приводит к тому, что обратиться к сохраненному с ключом-массивом элементу не получится при использовании другого массива такого же размера и с такими же элементами, доступ можно осуществить лишь в одном случае — при использовании той же самой ссылки на массив, что использовалась для сохранения элемента. #вопросы_с_собеседований

Просто ли стать Java-разработчиком? Нет. Всем ли подойдет IT? Тоже нет. Стоит ли попробовать? Да. Если вы хотите стать востре
Просто ли стать Java-разработчиком? Нет. Всем ли подойдет IT? Тоже нет. Стоит ли попробовать? Да. Если вы хотите стать востребованным разработчиком, вам нужно не просто научиться писать код. А в первую очередь сформировать инженерное мышление. На этом построен процесс обучения на Хекслете. На профессии «Java-разработчик» вас ждет не только теория, но и много практики: ✔️ Сотни упражнений в браузере. ✔️ 5 проектов для портфолио на GitHub. ✔️ 150 тестовых заданий от наших партнёров. ✔️ Вебинары, сессии лайвкодинга с наставником 1-2 раза в неделю. Сделайте шаг в карьере в IT-специалиста прямо сейчас! Переходите по ссылке выше и начните обучение! 🎁 Пройдите первые 10 бесплатных уроков из профессии и получите дополнительно скидку 10%

IDEA: замена кода и сто шагов назад (тихо на пальцах) Недавно посмотрела доклад с конференции Devoxx и узнала две полезные штуки для дебага. О них и расскажу в посте. 1️⃣ Откат на предыдущий фрейм У каждого потока есть стек вызовов. Оказывается, по нему можно перемещаться! Чтобы сделать шаг назад, щёлкните в дебаггере область слева от метода. Внизу поста скриншот — рядом с методом должна появиться стрелка 2️⃣ Замена исполняемого кода В дебаге нажать Shift-Shift и ввести Reload Changed Classes или Run → Debugging Actions → Reload Changed Classes Нельзя заменять код в том методе, где остановился дебаггер. В любом другом — можно Фичи отлично работают вместе для простых правок, которые сложно воспроизвести. Например, ошибка воспроизводится редко, на специфичном стенде или при участии других компонентов. План действий такой: 🔸 Зайти в удалённый дебаг, найти ошибку 🔸 Вернуться на пару фреймов назад 🔸 Поправить ошибку, сделать замену класса 🔸 Проверить, что всё ок При этом сервис продолжит работать с исправленным классом, ну разве не красота🥰

Друзья, какие каналы и сайты по Java вы читаете для обучения? Напишите в комментах под постом ☕️

Что такое Optional? Опциональное значение Optional — это контейнер для объекта, который может содержать или не содержать значение null. Такая обёртка является удобным средством предотвращения NullPointerException, т.к. имеет некоторые функции высшего порядка, избавляющие от добавления повторяющихся if null/notNull проверок:
Optional<String> optional = Optional.of("hello");

optional.isPresent(); // true
optional.ifPresent(s -> System.out.println(s.length())); // 5
optional.get(); // "hello"
optional.orElse("ops..."); // "hello"

#вопросы_с_собеседований

Что такое «конструктор по умолчанию»? Если у какого-либо класса не определить конструктор, то компилятор сгенерирует конструктор без аргументов - так называемый «конструктор по умолчанию». public class ClassName() {} Если у класса уже определен какой-либо конструктор, то конструктор по умолчанию создан не будет и, если он необходим, его нужно описывать явно. #вопросы_с_собеседований

правильный ответ 1, сори

Что такое FutureTask?
Anonymous voting

Разбираемся, что не так с кодом в новой рубрике⬇️ Вопрос: Почему код не скомпилируется? Ответ: В цикле while нет условия типа
Разбираемся, что не так с кодом в новой рубрике⬇️ Вопрос: Почему код не скомпилируется? Ответ: В цикле while нет условия типа Boolean

Что такое аннотации в Java?
Anonymous voting

Друзья, мы создали канал с вакансиями по Java. В чем там фишка? — В каждой вакансии есть ссылка на телеграм аккаунт HR-менеджера или технического специалиста этой вакансии. Вы сразу же можете заслать в телеге ваше резюме или задать вопрос по вакансии. Подписывайтесь и ищите работу: @javaoffers

Для чего используются ключевые слова volatile, synchronized, transient, native? volatile вынуждает потоки отключить оптимизацию доступа и использовать единственный экземпляр переменной. Если переменная примитивного типа – этого будет достаточно для обеспечения потокобезопасности. Если же переменная является ссылкой на объект – синхронизировано будет исключительно значение этой ссылки. Все данные, содержащиеся в объекте, синхронизированы не будут! synchronized — это зарезервированное слово позволяет добиваться синхронизации в помеченных им методах или блоках кода. Ключевые слова transient и native к многопоточности никакого отношения не имеют, первое используется для указания полей класса, которые не нужно сериализовать, а второе сигнализирует о том, что метод реализован в платформо-зависимом коде. #вопросы_с_собеседований

Ссылки на методы в Java Лямбды в Java полезны во многих направлениях. Лямбда-выражения можно использовать для более простых задач, а лямбда-утверждения — для более сложных. Лямбды могут вызывать другие методы для текущего объекта (this) и объектов, которые находятся в области видимости, таких как текущий элемент итерации и конечная локальная переменная за пределами лямбды. Лямбду всегда можно упростить, поместив код в другой метод. Читать статью

Effective Java Автор: Joshua Bloch Год издания: 2018 #java #english Скачать книгу
Effective Java Автор: Joshua Bloch Год издания: 2018 #java #english Скачать книгу

#вопросы_с_собеседований Как можно вывести на экран уникальные квадраты чисел используя метод map()? Для этого можно использо
#вопросы_с_собеседований Как можно вывести на экран уникальные квадраты чисел используя метод map()? Для этого можно использовать Stream. Ответ на картинке.

Полраза в жизни встречал ViewModel + MutableStateFlow. Попросили объяснить, как использовать. Чем дальше в лес, тем меньше понимания, как и зачем этим вообще пользоваться и под какими веществами это придумали 🤦 Ожидание: val vm by viewModels(factory = { MyCoolViewModel(args) }) Реальность:
val vm: MyCoolViewModel by viewModels(factoryProducer = {
    object : ViewModelProvider.Factory {
        override fun <T : ViewModel> create(...): T =
            MyCoolViewModel(args) as T
    }
})


Ожидание: val stateSmth = savedStateHandle.getMutableStateFlow("smth", defaultSmth) Реальность: отрицание, гнев, торг, пост в канал, кастомный флоу.

fun factorial(n: Int): Long =
    (2..n).fold(1L, Long::times)