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

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

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

Мы на бирже: telega.in/channels/javatasks/card?r=lcDuijdm
Download Telegram
Когда нужно использовать raw types?

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

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

Есть всего три случая, когда использовать обобщенный тип без параметра правильно:
• Целевая версия Java < 5.0 (2002 год и ранее – вряд ли это ваш случай);
• В литерале класса. List<String>.class не сработает, нужно писать List.class;
• В операторе instanceof. Вместо instanceof Set<Integer> должно быть instanceof Set.
👍82🔥2
Переверни игру за день в офисе Финтеха и Фантеха Яндекса 🙃

Зовём бэкенд-разработчиков на вечеринку JavaKotDay, чтобы поменяться ролями и почувствовать себя яндексоидом ещё до того, как примешь оффер.

Приходи к нам в гости 14 июля, чтобы порулить на встречах по планированию, поважничать в переговорке и приложить руку к сервисам, которыми пользуются миллионы!

А между делом вкусно поедим, посплетничаем у кулера и обсудим планы с нашими CTO. Кто мы? 😜 Фантех — это Кинопоиск, Плюс, Музыка, Афиша и Букмейт. 🤑 Финтех — Пэй, Сплит, Сейвы, ID.

Хочешь на JavaKotDay? Подтверди свои скиллы и реши задачку на сайте →
🔥5👍2
Что будет со ссылкой на метод, если заменить объект-владельца?

Ответ на этот вопрос будет очевиден, если вы уверенно понимаете, что скрывается за терминами ссылки вообще и ссылки на метод.

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

Факт позднего связывания в этом вопросе может ввести в заблуждение. Связывание случается в момент обращения, а не вызова. В результате в переменной хранится неизменяемая копия ссылки на метод. Она ведет на метод объекта, а не хранящей его переменной. Поэтому переприсвоение переменной позже не окажет на ссылку никакого эффекта.

Для достижения реального связывания в момент вызова в байткоде существует инструкция invokedynamic. Однако гораздо проще добиться того же результата, если использовать поведенческий паттерн ООП, например, посетителя.
👍172🔥2
🔥 Время прокачивать навыки в проектировании и расти!

💥 Проверь себя – пройди тест по архитектуре и шаблонам проектирования!

Ответишь успешно — пройдешь на курс «Архитектура и шаблоны проектирования» от OTUS по специальной цене со скидкой.

❗️На курсе ты научишься применять шаблоны проектирования и SOLID в разработке всего за 4 месяца под руководством опытных экспертов.

Именно эти навыки дадут мощное конкурентное преимущество IT-специалистам и повысят твою востребованность и доход!

➡️ ПРОЙТИ ТЕСТ:

https://vk.cc/cy3cLJ

💥 Пройдете тест и бонусом получишь:

– Доступ к записям лучших вебинаров курса

– Скидку на онлайн-курс «Архитектура и шаблоны проектирования»

🎁 А при покупке курса индивидуальную консультацию с преподавателем!
👍52🔥2👏1
Как обойти коллекцию?

for/while. Классический способ: целочисленная переменная-индекс, которая увеличивается от 0 до size(). Можно использовать для неполного обхода, с нестандартным шагом. Плата за это – возможность ошибиться в индексах и менее читабельный код.

Iterator. ООП-способ: методом iterator() получить объект-итератор, и вызывать у него next() пока hasNext() возвращает true. В реализации может быть дополнительная логика, такая как потокобезопасность. Такой «объект-итерацию» коллекции можно передать в сторонний код, не отдавая саму коллекцию. Всё еще требует слишком много кода.

for Iterable. Синтаксический сахар для обхода итератором. Простейший синтаксис когда нужен просто обход. В отличие от явного использования итератора не дает возможности модифицировать элементы в процессе.

Стримы. Создать от коллекции стрим и работать с элементами в нём. Кроме простого forEach(), можно воспользоваться всей мощью Java Steam API – фильтровать, преобразовывать и агрегировать элементы. За это создаются лишние объекты, а синтаксис гораздо более развесистый.

Функции Java 8. С этой версии появились удобные средства для обхода не только строк. У коллекций и хэш-таблиц добавились методы forEach для обхода и replaceAll для модификации. Как со стримами, они дают функциональный стиль, но без избыточного создания стримов. Внутри используются простые итераторы и циклы for.
👍18🔥31
Привет! Рекомендую подписаться на канал Java: fill the gaps, полезно для разработчиков любого уровня🔥

Для продолжающих:

🔹 Как реализованы лямбда выражения внутри JVM
🔹 Библиотеки работы с данными: от JDBC до Spring Data
🔹 3 способа подружить Postgres и Kafka

Для начинающих:

🔸 5 ошибок при использовании Optional
🔸 Fluent API: что такое и зачем нужен
🔸 Как освоить многопоточку

Подписывайся👉 Java: fill the gaps
👍8
Может ли имя класса не совпадать с именем файла?

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

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

Так что ответ – может.
👍18🔥53
Как сравнивать элементы перечисления?

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

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

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

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

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

3. == быстрее. Скорее всего разница в производительности будет незаметной, но тем не менее, оператор не требует лишнего вызова метода.
👍202🔥2🌚1
👩‍💻 Тест по Java от OTUS

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

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

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

🎫 Курс можно приобрести в рассрочку

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

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

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

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

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

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

Решение: неожиданное исключение обычно указывает на логическую ошибку. Лучший способ предотвратить логические ошибки – покрыть код Unit-тестами.
👍12🔥32
This media is not supported in your browser
VIEW IN TELEGRAM
Cамый простой способ изучить Java — залезть в голову профи

Один из лучших айтишников России учит базе кодинга в Telegram. Даже гуманитарий поймёт, как создавать приложения, сайты, игры и чат-боты.

Достаточно подписаться на «Секреты Java», где каждый день появляются гайды, готовые примеры кода и лучших практик.

И всё это бесплатно — вместо сотен тысяч рублей за курсы. Стартовать в прибыльной профессии с нуля вы сможете гораздо проще!

Теперь обучиться Java может каждый: @java_secrets
👍3
Отличаются ли сокращенные и обычные операторы?

Java предлагает программисту сокращенную запись для применения операции с сохранением ответа в операнд. Это например +=, &=, и другие. Их правильное название – операторы сложного присваивания (compound assignment). Сокращенные версии есть для всех арифметических и битовых операторов.

У таких сокращений есть одно неочевидное отличие от полных версий. Если прочитать спецификацию, там сказано, что x += y – это на самом деле сокращение от x = (XType)(x + y). То есть, кроме самой операции происходит приведение результата к типу левого операнда.

Незнание этой особенности может привести к ошибочно успешной компиляции, и неожиданным результатам работы кода (как в примере на изображении).
🔥27👍102🎉1
Лишает ли var строгой типизации?

Ключевое слово var появилось в Java 10. Указание var вместо типа локальной переменной применяет к ней механизм вывода типов (type inference). Тип будет вычислен на этапе компиляции из того, чем переменная инициализируется.

Отсюда несколько выводов. Во-первых, нельзя использовать var в полях класса, параметрах метода, и где-либо еще кроме локальных переменных. Во-вторых, обязана быть инициализация с понятным типом – варианты var x; или var x = null; не скомпилируются.

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

Ответ: нет, выводимый тип – строгий. Более того, типизация остается статической.

Главное упущение – в инициализации разрешено использовать diamond operator. В обычных обстоятельствах в нём выведется правильный generic-тип, но в случае var информации недостаточно, и типом-параметром будет Object.
🔥17👍4
Что лучше, ArrayList или LinkedList?

Самый избитый вопрос. Проверяет знание особенностей реализации (кишки ArrayList, кишки LinkedList) и эффективности операций в этих разных реализациях. В вопрос иногда добавляют Vector – пересинхронизированный и устаревший вариант ArrayList, который лучше заменить Collections.synchronizedList().

ArrayList хранит данные в массиве, LinkedList в двусвязном списке. Из этого вытекает разница в эффективности разных операций: ArrayList лучше справляется с изменениями в середине и ростом в пределах capacity, LinkedList – на краях. В целом обычно ArrayList лучше.

Стоит добавить, что для работы на краях лучше использовать реализации специально для этого спроектированного интерфейса Deque: например реализующую кольцевой буфер ArrayDeque.
👍15🔥7
👩‍💻 Интеграционные тесты контроллеров, интеграций с внешними API и безопасности.

Ждём вас на третьем занятии серии открытых практических уроков по тестированию Spring-приложений от OTUS, где мы:

- рассмотрим специфику тестирования классических и REST-контроллеров и интеграций с внешними API;
- уделим внимание тому, как проверить, что все конечные точки нашего приложения действительно защищены;
- ответим на все возникающие вопросы.

Спикер — Senior Software Engineer, опытный преподаватель и руководитель курса.

Встречаемся 16 июля в 20:00 мск в преддверии старта курса «Разработчик на Spring Framework».
Все участники вебинара получат специальную цену на обучение!

➡️ Регистрируйтесь прямо сейчас, чтобы не пропустить бесплатный урок и получить записи предыдущих вебинаров серии: https://vk.cc/cyfvVS

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

Обычно формулируется в виде задачи на внимательность «что здесь не так», например

for (String item : arrayList)
if (item.length() > 2)
arrayList.remove(item);

Подвох в том, что итератор ArrayList, который используется в таком варианте цикла for, является fail-fast, то есть не поддерживает итерацию с параллельной модификацией. А параллельная модификация случается даже в одном потоке, что демонстрирует этот пример. Следующий шаг итератора после удаления элемента выбросит ConcurrentModificationException.

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

Единственный способ удалить элемент из коллекции при обходе, не получив при этом ConcurrentModificationException или неопределенное поведение – удалить с помощью remove() того же инстанса итератора. Вариант ListIterator поможет, если в теле цикла требуется и работа с индексами.

Некоторые коллекции, такие как CopyOnWriteArrayList и ConcurrentHashMap адаптированные под многопоточную среду и имеют fail-safe итераторы.
👍11🔥2
Какова структура Java Collections Framework? Почему Map не Collection?

Collection – хранилище отдельных значений, Map – хранилище ключ-значение. Отсюда разные методы этих интерфейсов. Если проще, разные сигнатуры методов put и add.

Collection в свою очередь делится на три основных группы, и соответствующих им интерфейса:
🔘 List – упорядоченные списки с возможностью содержания дубликатов и доступа по индексу (random access);
🔘 Queue – обычно FIFO-коллекции, предполагает добавление/удаление элементов с края. Интерфейс-наследник Deque – двусвязная очередь;
🔘 Set – не обязательно упорядоченный набор уникальных (с точки зрения equals) значений;

HashMap можно привести к виду Collection вызвав например keySet(), entrySet() или values().
👍223🔥2
♨️ Хотите добиться максимальной производительности от своих Java-проектов?

Научитесь искусству измерения производительности и оптимизации кода на нашем увлекательном онлайн-уроке.

Забудьте о гадании и предположениях!
На этом вебинаре мы расскажем вам о мощном инструменте Java Microbenchmark Harness (JMH) и его области применения. Вместе мы разберем работу с производительными тестами и сравнением различных алгоритмов.

Вебинар будет полезен как Java-разработчикам, которые ищут лучшие практики для оптимизации кода, так и тестировщикам, специализирующимся на нагрузочном тестировании.

Спикер — Tech Lead в одном из крупнейших российских банков и кандидат технических наук.

Готовы стать мастером производительности в Java?

➡️ Регистрируйтесь прямо сейчас и откройте новый уровень эффективности в своих проектах: https://vk.cc/cykUlW

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

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

Нюансы которые стоит повторить и запомнить:
🔘 Общий принцип: внутренний массив table, содержащий бакеты (корзины) – списки элементов с одинаковыми пересчитанными хэш-суммами;
🔘 Пересчет хэш-суммы для умещения int индексов в capacity ячейках table;
🔘 rehash – удвоение размера table при достижении threshold (capacity*loadFactor) занятых бакетов;
🔘 Невозможность сжать однажды раздувшийся table;
🔘 Два способа разрешения коллизий: используемый в HashMap метод цепочек и альтернатива – открытая адресация;
🔘 Варианты для многопоточного использования: пересинхронизированная Hashtable и умная ConcurrentHashMap;
🔘 Оптимизация Java 8: превращение списка в бакете в дерево при достижении 8 элементов – при большом количестве коллизий скорость доступа растет с O(n) до O(log(n));
🔘 Явное использование бакета 0 для ключа null;
🔘 Связь с HashSet – HashMap, в котором используются только ключи;
🔘 Нет гарантий порядка элементов;

Обсуждая этот вопрос на интервью вы обязательно затронете особенности методов equals/hashCode. Возможно придется поговорить об альтернативных хранилищах ключ-значение – TreeMap, LinkedHashMap.
👍145🔥3
🤝 Не дай себя завязнуть в рутинных задачах!

🦾 Осваивай Spring и выходи на новый профессиональный уровень

Пройди тест по Java от OTUS

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

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

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

🎫 Начни обучение со скидкой в 10%, действует до конца июля.

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

Для Map можно привести ключи/значения к виду Collection, переложить в новый List и отсортировать с помощью Collections.sort. То же делается с Set. Этот метод конечно же неэффективный, так как потребует полного копирования содержимого.

Эффективный способ – хранить данные уже отсортированными. Для таких реализаций созданы интерфейсы-наследники SortedSet и SortedMap.

Реализации SortedSet дают линейный порядок множества. Элементы упорядочены по возрастанию. Порядок либо натуральный (элементы реализуют интерфейс Comparable), либо его определяет переданный в конструктор Comparator.
Этот интерфейс добавляет методы получения подмножества от указанного элемента (tailSet), до элемента (headSet), и между двумя (subSet). Подмножество включает нижнюю границу, не включает верхнюю.

SortedSet расширяется интерфейсом NavigableSet для итерации по порядку, получения ближайшего снизу (floor), сверху (ceiling), большего (higher) и меньшего (lower) заданному элемента.

Все те же правила применяются к элементам SortedMap/NavigableMap относительно их ключей.

Основными реализациями являются TreeSet и TreeMap. Внутри это самобалансирующиеся красно-чёрные деревья. Их структура и способ балансировки – вопрос достойный отдельного поста. Другая любопытная реализация из java.util.concurrent – ConcurrentSkipListMap.
🔥19👍63