Java Guru 🤓

Description
Канал с вопросами и задачами с собеседований!

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

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

Мы на бирже: telega.in/channels/javatasks/card?r=lcDuijdm
Advertising
We recommend to visit
HAYZON
HAYZON
5,777,024 @hayzonn

👤 𝐅𝐨𝐮𝐧𝐝𝐞𝐫: @Tg_Syprion
🗓 ᴀᴅᴠᴇʀᴛɪsɪɴɢ: @SEO_Fam
Мои каналы: @mazzafam

Last updated 1 month, 1 week ago

Architec.Ton is a ecosystem on the TON chain with non-custodial wallet, swap, apps catalog and launchpad.

Main app: @architec_ton_bot
Our Chat: @architec_ton
EU Channel: @architecton_eu
Twitter: x.com/architec_ton
Support: @architecton_support

Last updated 1 month ago

Канал для поиска исполнителей для разных задач и организации мини конкурсов

Last updated 1 month, 3 weeks ago

3 недели, 1 день назад
**Как работает вывод типов?

**Как работает вывод типов?

Для* начала разберемся, что такое вывод типов. Type inference – это способность компилятора догадаться, какой тип нужно подставить, и сделать это за вас. На обычном интервью никто не спросит детали алгоритма вывода типов, достаточно будет сказать, что вывод происходит статически, только на основании типов аргументов и ожидаемого типа результата. По сути, вопрос заключается не в «как работает?», а «что это и когда возникает?».

Первое, что многим приходит в голову при фразе «вывод типов» – diamond operator <>. Он появился в Java с версии 7. Его применяют к конструкторам дженерик классов, чтобы отличать требование автоматического вывода типа от raw type.

С Java 9 diamond operator заработал и для анонимных классов.

Для дженерик методов можно указывать параметр явно, но diamond синтаксически недопустим – вывод и так сработает по умолчанию.

В Java 10 для вывода типа локальной переменной добавлено ключевое слово var. Работает это так же, как в большинстве современных языков – ключевое слово ставится вместо типа при объявлении.

Типы выводимых параметров лямбда-выражения также можно не указывать. С Java 11 вместо типа указывается ключевое слово var. Такой синтаксис дает возможность добавлять параметру модификаторы и аннотации.*

3 недели, 2 дня назад
3 недели, 4 дня назад

Перечислите целочисленные битовые операторы

*Во-первых, стоит освежить знания о бинарном представлении целых знаковых чисел. В Java используется подход two's complement – для значения 0 все биты нули, при переполнении максимального значения на 1 получается минимальное.

Бинарные битовые операторы &, | и ^ действуют очевидным образом: выполняют побитовые «И», «ИЛИ» и «исключающее ИЛИ» (XOR) соответственно. Здесь особенно интересен XOR:

Применение к значению «исключающего или» с одним и тем же параметром два раза дает то же значение. За счет этого его можно использовать как простейшее шифрование, аргумент выступит ключом;
С помощью XOR реализуется XOR-обмен – алгоритм обмена значениями переменных без дополнительной памяти и без риска переполнения. Это также один из популярных вопросов для собеседования.

Унарный оператор битового отрицания (дополнения) ~. Эквивалентен «исключающему или» с самим собой – все биты инвертируются. ~x эквивалентно -x-1. ~0 == -1.
Битовые сдвиги: левый << правый знаковый >> и правый беззнаковый >>>. Левый операнд – что сдвигать, правый – на сколько битов.

Второй параметр, дистанция сдвига, должен быть не больше доступных разрядов – 31 для int и 63 для long. Если передано значение больше – используются младшие 5 и 7 битов соответственно. То есть для int переменной x << 33 эквивалентно x << 2.

a << b эквивалентно умножению a на 2 в степени b.
a >> b совпадает с делением на 2 в степени b, с округлением вниз. Для положительных a то же что a/pow(2,b). Для не делящихся нацело на pow(2,b) отрицательных это a/pow(2,b)-1.

Беззнаковый сдвиг вправо трактует число не как two's complement, а как беззнаковое. То есть Integer.MIN_VALUE будет сдвинут так, как будто это сдвигается число на 1 большее чем Integer.MAX_VALUE.

Беззнакового сдвига влево не существует, потому что он совпадал бы со знаковым сдвигом, и был бы избыточным.*

@javatasks#java

3 месяца, 2 недели назад

Как объявить переменное количество аргументов метода?

*Для этого используется аргумент-массив. В нем может находиться любое количество элементов. Еще с 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.*

3 месяца, 3 недели назад
3 месяца, 3 недели назад

На какие области делится память JVM?

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

Stack – место под примитивы и ссылки на объекты (но не сами объекты). Хранит локальные переменные и возвращаемые значения функций. Здесь же хранятся ссылки на объекты пока те конструируются. Все данные в стеке – GC roots. Освобождается сразу на выходе из функции. Принадлежит потоку, размер по-умолчанию указывается параметром виртуальной машины -Xss, но при создании потока программно можно указать отличное значение. Подробнее.
PermGen – В этой области хранятся загруженные классы (экземпляры класса Class). Здесь же с 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.*

6 месяцев, 1 неделя назад

**Какие бывают проблемы с арифметикой в Java?

Переполнения.***Числа примитивных типов в Java хранятся в дискретной оперативной памяти компьютера и занимают фиксированный объем. Из этого вытекает ограничение диапазона возможных значений. Когда результат арифметической операции выпадает из диапазона, значение идет по кругу – максимальное становится минимальным, либо наоборот. Такая ситуация называется переполнение (underflow/overflow).

Решение: если опасность переполнения значима, помогут методы с суффиксом *Exact из классе Math. Это безопасные аналоги арифметических операций, которые бросают исключение в случае переполнения.

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

Решение: модификатор strictfp в объявлении класса или метода приводит точность вычислений к единой спецификации IEEE 754. За это может ухудшиться производительность и уменьшиться точность значений.

ArithmeticException.Операторы могут выбрасывать исключение. Это происходит, например, при делении на ноль. Это же исключение бросают безопасные методы из Math.

Решение: неожиданное исключение обычно указывает на логическую ошибку. Лучший способ предотвратить логические ошибки – покрыть код Unit-тестами.*

6 месяцев, 1 неделя назад

Как сравнивать элементы перечисления?*Элементы enum-а компилируются в статические константы-экземпляры его класса. Экземпляры гарантированно синглтоны. Это значит, для их сравнения безопасно использовать ==, даже после десериализации и в многопоточной среде.

Скомпилированный класс неявно наследуется от java.lang.Enum, в котором все методы из Object кроме toString объявлены финальными. В частности, невозможно изменить поведение метода equals – он сравнивает enum-ы с помощью ==. Так что equals тоже можно использовать без опаски.

Но помимо этого есть несколько отличий в пользу ==:

  1. == не выбросит NullPointerException. Прежде чем вызывать equals у переменной, придется удостовериться что она не null.

  2. == не позволит сравнить объекты разных типов. Оператор еще на этапе компиляции подскажет, что такое сравнение не имеет смысла. equals же будет принимать аргумент под типом Object, и всегда возвращать false уже в рантайме.

  3. == быстрее. Скорее всего разница в производительности будет незаметной, но тем не менее, оператор не требует лишнего вызова метода.*

6 месяцев, 2 недели назад

Может ли имя класса не совпадать с именем файла?*Компилятор требует, чтобы в .java файле был не больше чем один публичный класс верхнего уровня, и чтобы его название совпадало с названием файла. Все специальные символы также должны быть в имени файла.

Protected и private классов верхнего уровня не бывает в принципе, а вот на package-protected это ограничение не распространяется. Это значит, что класс без модификатора доступа может иметь любое имя. Также это значит, что рядом с основным публичным классом файла (или вместо него) можно объявить любое количество других классов без модификатора доступа, с произвольными именами. Они будут доступны внутри всего пакета.

Так что ответ – может.*

6 месяцев, 2 недели назад

Когда нужно использовать raw types?*Сначала вспомним, что такое raw type. В Java так называют generic-типы без указания типа-параметра. Такая языковая конструкция валидна, но в большинстве случаев приводит к предупреждению компилятора.

Предупреждение связано с риском получения проблемы heap pollution. Ей мы уже посвящали публикации ранее. Использование raw types никогда не оправдано – спецификация языка явно говорит: их поддержка остается только для обратной совместимости.

Есть всего три случая, когда использовать обобщенный тип без параметра правильно:
• Целевая версия Java < 5.0 (2002 год и ранее – вряд ли это ваш случай);
• В литерале класса. List.class не сработает, нужно писать List.class;
• В операторе instanceof. Вместо instanceof Set должно быть instanceof Set.*

We recommend to visit
HAYZON
HAYZON
5,777,024 @hayzonn

👤 𝐅𝐨𝐮𝐧𝐝𝐞𝐫: @Tg_Syprion
🗓 ᴀᴅᴠᴇʀᴛɪsɪɴɢ: @SEO_Fam
Мои каналы: @mazzafam

Last updated 1 month, 1 week ago

Architec.Ton is a ecosystem on the TON chain with non-custodial wallet, swap, apps catalog and launchpad.

Main app: @architec_ton_bot
Our Chat: @architec_ton
EU Channel: @architecton_eu
Twitter: x.com/architec_ton
Support: @architecton_support

Last updated 1 month ago

Канал для поиска исполнителей для разных задач и организации мини конкурсов

Last updated 1 month, 3 weeks ago