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
Когда стоит выбрать char[] вместо String?

Первая, очевидная причина – оптимизация. Если вам заранее известен размер строки, и он фиксирован, может быть полезно выбрать массив. Если программа работает с неизменяемыми подстроками, удобно представить их в виде offset-ов общего массива (как это было сделано раньше в самом String).

Следует помнить, что оптимизировать нужно осознанно и своевременно. JVM тоже прикладывает усилия по оптимизации строк (вроде интернирования), которые могут оказаться эффективнее ваших.

Вторая, менее очевидная причина – безопасность. Строки в Java иммутабельны. Это значит, что когда вы сохраняете пароль в объекте типа String, физически уничтожить его из памяти может только сборщик мусора.

Существует способ алгоритмической атаки на систему, когда хакер своими действиями вызывает переполнение памяти, и конфиденциальная информация попадает в heap dump.

Если пароль хранится в массиве, программист может самостоятельно «занулить» значение после использования.
👍13🔥5
Хотите узнать, как использовать Kafka Streams для эффективной работы с данными?

Всего за пару часов вы научитесь уверенно создавать топологии с помощью DSL, запускать обработку данных и использовать основные процессоры для преобразования, фильтрации, логирования и разделения данных. Вы узнаете, как работать с состоянием и разберете нюансы работы с несколькими партициями.

Присоединяйтесь к открытому вебинару 19 сентября в 20:00 мск!

Урок будет полезен разработчикам, которым интересно узнать про потоковую обработку данных из Kafka с использованием kafka-streams.

Спикер Евгений Непомнящий — опытный разработчик и преподаватель.

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

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

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
5👍2🔥2
Под каким типом хранить период времени?

В стандартной библиотеке современных версий Java для этих целей есть два класса:

Period – календарный период. Количество дней, месяцев и лет. Одним днем здесь считается день в терминах ZonedDateTime.

Duration – длительность времени. Количество наносекунд, секунд, минут, часов, и тоже дней. Здесь один день – ровно 24 часа.

Оба класса реализуют общий интерфейс TemporalAmount – период времени вообще. Оба иммутабельны, и как следствие, потокобезопасны. Любая модифицирующая операция вроде plusX() возвращает новый экземпляр с измененным значением.

Экземпляры обоих классов могут быть созданы из значений отдельных компонентов, из двух моментов времени методом between, или из строки. Строковое представление Duration: "P2DT3H4M", Period: "P1Y2M3D".

До Java 8 основным способом хранения периода были числовые примитивы. В этом подходе есть много недостатков, среди которых в первую очередь неограниченность значений и ненаглядность. Чтобы в Java 8+ получить период числом, используется метод between() нужного элемента енама ChronoUnit.
👍11🔥2
Если JAVA, SPRING, API для тебя не просто набор сектантских аббревиатур, ждём тебя на нашем JAVA митапе!
27 сентября Axenix проведет открытый митап для всех java-разработчиков и не только.
📅 Дата: 27 сентября, 18:30
📍 Место проведения: г. Санкт-Петербург, Аптекарский проспект д. 4, к.2, стр. 1, (Амфитеатр Ленполиграфмаша).

Программа: 

🔶Валерий Торопов, «Что за фокусник такой Spring-Data-Redis».  
🔶Михаил Бондаренко, «Оптимизация логирования и маскирования». 
🔶Антон Богун, «Prometheus: как Бог огня стал Богом мониторинга». 

🔥Для всех гостей митапа будет проведена пивная дегустация и кейтеринг! 
Зови друзей и приходи сам, количество мест ограничено! Успей зарегистрироваться!
👍3🔥2😁2
Что напечатает следующий код?
🔥8👍2
🏓 Знакомимся с 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