Java Guru 🤓
13.4K subscribers
933 photos
15 videos
788 links
Канал с вопросами и задачами с собеседований!

По сотрудничеству и рекламе: @NadikaKir

Канал в перечне РКН: https://vk.cc/cJrSQZ

Мы на бирже: telega.in/channels/javatasks/card?r=lcDuijdm
Download Telegram
🏓 Знакомимся с Java на примере пинг-понга

Хотите узнать, как создавать программы на Java, даже если никогда не программировали?

Ждем вас на открытом вебинаре 24 сентября в 20:00 мск, где мы разберем:

- что такое программирование и язык Java;
- как создать игру пинг-понг с нуля на Java;
- как работать с двумерной графикой в Java.

Урок полезен для тех, кто хочет начать изучать Java с нуля и увидеть на практике, как создаются приложения.

Спикер Александр Фисунов — Senior Kotlin Developer в SSP Software на проекте ВТБ, опытный Java-разработчик и кандидат технических наук.

Встречаемся в преддверии старта курса «Специализация Java-разработчик».
Все участники вебинара получат специальную цену на обучение!

👉 Регистрируйтесь прямо сейчас, чтобы не пропустить мероприятие: https://vk.cc/cASVPo

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42🔥2
new String("Hello_42") == "Hello_" + 42?

Такие вопросы о сравнении строковых и числовых констант проверяют знания о понятии пулов литералов (literal pool). Не следует путать с пулом констант класса. Виртуальная машина переиспользует один и тот же объект для строкового литерала при загрузке класса, если такой уже выделен в куче. Вот почему "Hello" == "Hello" истинно, не смотря на то что String – ссылочный тип. Такая оптимизация возможна благодаря свойству неизменяемости (immutable) класса String, и называется интернирование строк.

Кроме самих литералов, интернирование применяется ко всем константным выражениям. К таким выражениям в этом примере относятся неявное приведение числа 42 к строке и конкатенация констант. Это делает истинным "Hello_42" == "Hello_" + 42.

Пул литералов не работает, когда явно используется оператор new. Это причина, по которой выражение new String("Hello_42") == "Hello_" + 42 ложно.
13👍5🔥3
Как сделать Android-приложение быстрее и эффективнее?

Узнайте на открытом вебинаре 18 сентября в 20:00 мск, где мы разберем:

- как ProGuard/R8 минимизируют, оптимизируют и убирают неиспользуемый код;
- сравнение эффективности ProGuard и R8;
- как внедрять ProGuard/R8 в существующий проект.

Урок особенно полезен для Android-разработчиков с опытом работы от 1 года.

Встречаемся в преддверии старта курса «Специализация Android Developer». Все участники вебинара получат специальную цену на обучение!

Регистрируйтесь прямо сейчас, чтобы не пропустить мероприятие.
👍42🔥2
Параметры в Java передаются по ссылке или по значению?

Этот вопрос уходит корнями в C++ прошлое (скорее всего интервьюера), это терминология из C++. Для начала нужно разобраться в этой терминологии.

В C++ ссылка – это переменная-псевдоним для другой переменной. Меняя значение ссылки, поменяется и оригинал. В Java такого нет, легко понять это подумав например о ссылке на int.

Ссылка в Java – это нечто похожее на адрес объекта в памяти. Похожая сущность в C++ называется указатель.

Передача параметра по значению – это копирование значения в переменную-параметр метода. По ссылке – передача ссылки, то есть по сути использование той же самой переменной.

В Java параметр метода – всегда копия. Значит параметры передаются всегда по значению, просто это значение может быть ссылкой на объект. Код выше это демонстрирует.
👍17🔥3
Какие в Java бывают виды ссылок?

Кроме обычной жесткой ссылки на объект существуют варианты ссылок, которые обрабатываются сборщиком мусора особым образом. Это наследники класса java.lang.ref.Reference. Все они реализуют разного рода слабые ссылки. Технически это обертки над объектом, который доступен по методу get(), и может быть удален сборщиком мусора пока объект-обертка еще не удален. Используются они для экономии памяти, для реализации кэшей, для финализации внешних ресурсов. Например в Android слабые ссылки иногда используются для борьбы с утечкой Activity.

Виды ссылок в порядке убывания «жесткости»:

Обычная жесткая ссылка – любая переменная ссылочного типа. Очистится сборщиком мусора не раньше, чем станет неиспользуемой (перестанет быть доступной из GC roots, подробнее в следующих постах).
SoftReference – мягкая ссылка. Объект не станет причиной израсходования всей памяти – гарантированно будет удален до возникновения OutOfMemoryError. Может быть раньше, зависит от реализации сборщика мусора.
WeakReference – слабая ссылка. Слабее мягкой. Не препятствует утилизации объекта, сборщик мусора игнорирует такие ссылки.
PhantomReference – фантомная ссылка. Используется для «предсмертной» обработки объекта: объект доступен после финализации, пока не очищен сборщиком мусора.
👍154🔥3
Сколько памяти занимает объект?

Размер экземпляров ссылочных типов, как и примитивов, зависит от конкретной реализации JVM и параметров ее запуска. Обычно в вопросе подразумевается самая популярная машина – HotSpot от Oracle.

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

Как говорилось ранее, ссылка в Java – не то же самое что указатель в C++, это не адрес в памяти. Из-за этого размер поля-ссылки может не совпадать с размером машинного слова, например когда HotSpot использует оптимизацию «сжатие ссылок» (Compressed OOP).

Кроме полей и промежутков, каждый объект в HotSpot начинается с заголовка – runtime-метаинформации. Заголовок занимает от 8 до 16 байт.

В общем можно только сказать, что размер объекта строго больше суммы размеров его полей. Примерный размер конкретного объекта измеряется средствами инструментации.
👍154🔥4
На какие области делится память JVM?

Следует помнить, что это внутренние особенности HotSpot (и её opensource-версии OpenJDK). В других виртуальных машинах (например в Android) всё может быть абсолютно по-другому. Области-поколения кучи вообще зависят от используемого алгоритма сборки мусора, и могут отличаться в рамках одной и той же реализации виртуальной машины.

Stack – место под примитивы и ссылки на объекты (но не сами объекты). Хранит локальные переменные и возвращаемые значения функций. Здесь же хранятся ссылки на объекты пока те конструируются. Все данные в стеке – GC roots. Освобождается сразу на выходе из функции. Принадлежит потоку, размер по-умолчанию указывается параметром виртуальной машины -Xss, но при создании потока программно можно указать отличное значение. Подробнее.
PermGen – В этой области хранятся загруженные классы (экземпляры класса Class<T>). Здесь же с Java 7 хранится пул строк. Изначально размера -XX:PermSize, растет динамически до -XX:MaxPermSize. Не считается частью кучи.
Metaspace – с Java 8 заменяет permanent generation. Отличие в том, что по умолчанию metaspace ограничен только размерами доступной на машине памяти, но так же как PermGen может быть ограничен, параметром -XX:MaxMetaspaceSize.
Heap – куча, вся managed-память, в которой хранятся все пользовательские объекты. Все следующие разделы – части кучи. Параметры -Xms, -Xmn и -Xmx устанавливают начальный, минимальный и максимальный размеры хипа соответственно.
Eden, New Generation, Old Generation и другие – специфичные для сборщика мусора части кучи, поколения. Могут быть разные, но общий подход сохраняется: долго живущий объект постепенно двигается во всё более старое поколение; сборка мусора в разных поколениях происходит раздельно; чем поколение старше, тем сборка в нём реже, но и дороже.

Хотя устройство памяти – это детали реализации виртуальной машины, для Java-разработчика знания о них несут практическую пользу. Эти знания необходимы для передачи правильных значений параметров JVM, что в свою очередь спасает от просадок производительности GC и остановок с OutOfMemoryError.
👍173
Вакансия:Java Developer
Грейд: Miiddle+/Senior/Lead


Компания BSS — российский разработчик ДБО и решений в сфере голосовых технологий, а также провайдер услуг по привлечению специалистов на IT проекты.
Сейчас мы в поиске опытных Java разработчиков для нашего заказчика - международной продуктовой компании, специализирующейся на разработке решений для операторов мобильной связи. Сотрудник требуется на проект по созданию современной биллинговой системы одного из российских операторов связи.

Тех.стек:
Управление процессом разработки:
- Jira
- Confluence
Технологии разработки:
Java 11+, , Spring (web, data jpa, security, boot 2.5), Oracle 19, PostgreSQL, SQL, Camunda, Kafka, RabbitMQ, Gradle, Maven

Обязанности:
• Разработка на Java;
• Оценка и декомпозиция задач;
• Умение четко формулировать задачи/проблематику/ технические детали для взаимодействия между командами и заказчиком;
• Умение работать как самостоятельно, так и в составе команды;
• Багфикс, написание unit-tests;
• Следовать жизненному циклу ПО, поддерживать статус и описание задач в баг-трекинговых системах в актуальном состоянии;
• Своевременно отчитываться о временных затратах в разрезе задач.

Требования:
• Опыт работы 3+ года;
• Умение ставить задачи другим разработчикам
• Четкое понимание жизненного цикла ПО;
• Уверенное владение Java 8; Java 11
• Понимание архитектуры Spring и SpringBoot;
• Опыт работы с крупными многомодульными проектами;
• Работа с микросервисной архитектурой;
• Опыт работы с message brokers (RabbitMQ, Kafka);
• Опыт разработки интеграционных и Unit-тестов;
• ! Обязателен военный билет или приписное свидетельство (для военнообязанных)
• Опыт работы с API (REST, SOAP - Желательно);
• Умение заниматься debug’ом (в том числе удаленным);
• Опыт работы с Jira Atlassian;

Будет плюсом:
• Умение проводить Code Review;
• Опыт с JPA Specification;
• Профилирование SQL-запросов (Oracle);
• Опыт подготовки и развёртывания приложения в Docker-контейнер;
• Опыт работы с Linux (CLI).
• Работа с GitLab, следование git-flow.

Условия:
• Удалённый формат работы по РФ, гибридный формат в Москве/Пензе обязателен (1-2 раза в неделю в офисе);
• Работа на крупном проекте с современными технологиями в аккредитованной IT-компании;
• Полное соблюдение ТК РФ и своевременная выплата заработной платы;
• ДМС для вас и семьи;
• Страхование жизни;
• Предоставляем технику для работы;
• Проведение Performance Review.

Контакты:
@olga_sourcer
👍63🔥1
Что произойдет при выполнении такого кода?
👍8🔥2🤯1
Расширьте свой стек и апнитесь в зарплате!

👉Начните на бесплатном вебинаре онлайн-курса «Greenplum для разработчиков и аналитиков» - «Введение в Greenplum и её архитектуру»: регистрация

На вебинаре вы узнаете о структуре системы, параллелизме и масштабируемости. В практической части будут продемонстрированы примеры работы с запросами и оптимизации производительности.

Цели вебинара:
1. Основы: Познакомить участников с архитектурой Greenplum и её концепциями.
2. Распределенная обработка: Объяснить преимущества MPP (Massively Parallel Processing).
3. Практика: Показать, как разрабатывать и оптимизировать запросы.
4. Сравнение: Рассмотреть отличия от других СУБД, таких как PostgreSQL.

🤝Понравится урок — продолжите обучение на курсе по спеццене и даже в рассрочку!

erid: LjN8K1J6X
👍4🔥3
Как объявить переменное количество аргументов метода?

Для этого используется аргумент-массив. В нем может находиться любое количество элементов. Еще с Java 5 для этого случая добавился синтаксический сахар: Variable-length argument (vararg). Три точки ... ставятся между типом и именем переменной, и становится можно передать любое количество аргументов, не упаковывая их в массив.

На уровне байткода применение массива и варарга не отличаются: vararg-параметр Foo... превращается в параметр-массив Foo[], на этапе вызова подставляется неявное инстанцирование и заполнение массива.

Чтобы избежать неоднозначностей, на vararg наложено ограничение: им может быть только один последний аргумент.

Vararg, как массив, может быть пустым. Иногда это приводит к неочевидному поведению. Допустим, имеем две перегрузки метода с аргументами int... и float.... Вызов такого метода без параметров попадает в вариант с int, как с более специфичным типом. Наличие же перегрузки с несовместимыми типами, например int... и boolean..., приводит при вызове к ошибке компиляции «Ambiguous method call».

Когда типом варарга используется generic-параметр, возникает warning «Possible heap pollution from parameterized vararg type». Вам нужно убедиться, что вы понимаете в чем этот риск, что ваш код не приводит к heap pollution, и уведомить об этом компилятор аннотацией
@SafeVarargs.
👍11🔥5
👩‍💻 Курс для Java-разработчиков, которые хотят профессионального роста.

Пройди тест по Java и проверь свои знания, готов ли ты к обучению на курсе.

Ответишь — пройдешь на продвинутый курс "Java Developer. Professional" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса курса

➡️ ПРОЙТИ ТЕСТ: https://vk.cc/cBhLkN

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3🔥2🎉1
Как в лямбде изменить внешнюю локальную переменную?

Это нельзя сделать в лоб. Такой код не скомпилируется, потому что захваченная локальная переменная обязана быть effectively final. Такое требование исходит из следующих причин.

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

Эта проблема решается тем, что в лямбду копируется значение локальной переменной. Такая копия живет независимо, возможно дольше оригинала. Но это решение приведет к сложному поведению из-за возможности работы с неактуальным значением – копия и оригинал станут двумя разными переменными. Поэтому значение должно быть вечно актуально – неизменяемо.

Поля экземпляра менять можно, потому что захваченной переменной в этом случае выступает effectively final значение this.

Если локальную переменную всё же хочется изменить, решение очевидно – поместить её в кучу. Для этого нужно использовать любого рода обертку: одноэлементный массив, объект-atomic, специально созданный класс с этой переменной как полем.

Хак с оберткой решает проблему времени жизни и даёт коду скомпилироваться, но возвращает проблему сложности поведения. Если среда многопоточная, то вероятно порядок операций с этой переменной придется синхронизировать вручную.
👍19🔥52
👩‍💻 Пройди тест по Java

Проверь насколько хорошо ты знаешь Java и готов освоить 👩‍💻 Spring!

Ответишь — пройдешь на продвинутый курс "Разработчик на Spring Framework" от OTUS по специальной цене.

👉 ПРОЙТИ ТЕСТ: https://vk.cc/cBlkgF

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥2👍1
Как получить гарантированный дедлок?

Сначала поговорим о том, что это такое. Deadlock – это взаимная блокировка, ситуация, когда два или более потока «наступают друг-другу на хвост» – зависают в вечном ожидании ресурсов, захваченных друг другом.

Livelock – похожая проблема, с тем лишь отличием, что потоки не останавливаются, а вместо этого зацикливаются, выполняя одни и те же бесполезные действия, ходят по кругу.

Стандартный подход к обеспечению гарантии защиты от дедлока – установка строгого порядка взятия блокировок. Если для мониторов A и B соблюдается всеобщий порядок захвата AB (и соответственно отпускания BA), то ни с одним потоком не случится попасть на ожидание B, успешно при этом захватив A.

Из этого можно догадаться, простой способ гарантировать возможность дедлока – явно нарушить это условие.

Нарушение условия даст дедлок «скорее всего когда-нибудь». Чтобы получить его точно и с первого раза, нужно гарантировать, что оба потока окажутся на этапе между захватами одного и другого ресурса в одно время. Это можно сделать множеством способов, в примере ниже использован CyclicBarrier.
👍9🔥21
Тестовое собеседование на Middle Java-разработчика завтра

Уже завтра, 25 сентября в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

Как это будет:
1. Мария Ядерцова ведущий Java-разработчик в МТС Диджитал и ex. Сбербанк-Технологии будет задавать реальные вопросы и задачи разработчику-добровольцу
2. Мария будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
3. В конце можно будет задать любой вопрос Марии

Что узнаешь на прямом эфире от ШОРТКАТ:

· Чего ждут от кандидатов на Middle позиции в Java-разработке
· Какие вопросы задают на интервью и зачем
· Как подготовиться к собесу, чтобы получить оффер

Это бесплатно? Бесплатно

Переходи в нашего бота, чтобы получить ссылку на эфир@shortcut_sh_bot

Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqvMv5C4
🔥4👍32
Как устроены атомики?

Начнем с того, что такое атомики и зачем нужны. Atomic* – семейство классов из java.util.concurrent. Они предоставляют набор атомарных операций для соответствующих типов. Например с помощью методов getAndIncrement/incrementAndGet класса AtomicInteger можно делать неатомарный в обычных условиях инкремент (i++).

Условно можно разделить подходы реализации большинства atomic-методов на две группы: compare-and-set и set-and-get.

Методы категории compare-and-set принимают старое значение и новое. Если переданное старое значение совпало с текущим, устанавливается новое. Обычно делегируют вызов в методы класса Unsafe, которые заменяются нативными реализациями виртуальной машины. Виртуальная машина в большинстве случаев использует атомарную операцию процессора compare-and-swap (CAS). Поэтому атомики обычно более эффективны чем стандартная дорогостоящая блокировка.

В случае set-and-get старое значение неизвестно. Поэтому нужен небольшой трюк: программа сначала считывает текущее значение, а затем записывает новое, тоже с помощью CAS, потому что запись могла успеть поменяться даже за этот шаг. Эта попытка чтения+записи повторяется в цикле, пока старое значение не совпадет и переменная не будет успешно записана.

Этот трюк называется double-checked или optimistic locking, и может быть использован и в пользовательском коде с любым способом синхронизации. Оптимистичность заключается в том, что мы надеемся что состояния гонки нет, прибегая к синхронизации только если гонка всё же случилась. Реализация оптимистичной блокировки может быть дана как отдельная задача.
👍165🔥2
🏓 Знакомимся с Java на примере пинг-понга

Хотите узнать, как создавать программы на Java, даже если никогда не программировали?

Ждем вас на открытом вебинаре 26 сентября в 20:00 мск,

где мы разберем:

➡️ что такое программирование и язык Java;
➡️ как создать игру пинг-понг с нуля на Java;
➡️ как работать с двумерной графикой в Java.

Урок полезен для тех, кто хочет начать изучать Java с нуля и увидеть на практике, как создаются приложения.

🎙 Спикер Александр Фисунов — Senior Kotlin Developer в SSP Software на проекте ВТБ, опытный Java-разработчик и кандидат технических наук.

Встречаемся в преддверии старта курса «Специализация Java-разработчик».
Все участники вебинара получат специальную цену на обучение!

➡️ Регистрируйтесь прямо сейчас, чтобы не пропустить мероприятие: https://vk.cc/cBpkfQ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4🥰3👍21🥴1
Что выведет код сверху?

Ответ: Not equal. Переменная real не равна самой себе. Арифметика с плавающей запятой реализована в соответствии со стандартом IEEE 754, который требует возвращения специального значения «NaN» (от английского «Not a Number» — не число), когда ноль делится на ноль. В спецификации также указано, что NaN не равно никакому значению с плавающей запятой, включая само себя.

@javalib #java
👍313🔥3😐3