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

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

Ir al canal en Telegram

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

Mostrar más
2 064
Suscriptores
Sin datos24 horas
-77 días
-1930 días
Archivo de publicaciones
Пять стадий написания LayoutManager 1. 😨 Быть такого не может, чтобы ранее такую штуку никто не делал! 2. 😡 Нет, ну почему никто не запилил?! 3. 🤬 Может, как-нибудь попроще, без менеджера? 4. 😢 *гуглинг в гитхабе* 5. 😌 Ладно-ладно, пойду писать. Итого: Flow (раскладывает в строчку, переносит на новую при необходимости) с возможностью ограничить количество строк и показать специальную вьюшку «ещё 100500». https://github.com/Miha-x64/FlowLayoutManager/

Сегодня в IT идут все, кто мечтает о работе в международной компании с хорошей зарплатой. Но правда в том, что на рынке по-пр
Сегодня в IT идут все, кто мечтает о работе в международной компании с хорошей зарплатой. Но правда в том, что на рынке по-прежнему наблюдается дефицит квалифицированных кадров. Бизнесу нужны люди, которые могут прийти и сразу решать их задачи. Те, кто обладает практическими знаниями и может переводить любую бизнес задачу на язык кода. Именно на глубокую и постоянную практику нацелен курс «Java-разработчик» от Хекслета. Вы начнете писать код с первого дня обучения, выполните сотни практических упражнений, напишете 5 полноценных проектов, поучаствуете в Open Source и подготовитесь к собеседованиям с помощью тестовых от компаний партнеров. 🎁 Вы можете начать учиться уже сегодня! Пройдите 5 бесплатных уроков, получите скидку 10% на курс и решите, подойдёт вам профессия или нет. Будьте уверены — вы получите именно те инструменты и навыки, которые позволят вам найти работу!

Hashcode для Hibernate сущностей Год новый, а темы всё те же. В декабрьском адвенте разгорелась горячая дискуссия на тему hashcode. Встал такой вопрос: Как определить hashcode для сущностей Hibernate? Что делать, если объект пока не сохранён в БД и у него нет id? В этом вопросе часто упоминается статья Thorben Janssen Ultimate Guide to Implementing equals() and hashCode() with Hibernate В самом конце там вывод: если для сущности id генерируется в БД, то hashcode должен возвращать константу. Почему это не лучший вариант? Контракт соблюдается, всё работает корректно. Но задача хэша — быстрая проверка схожести объектов. Мы теряем преимущество быстрого поиска, и хэшсет будет работать как список. Так будет и для новых объектов, и для уже сохранённых (у которых id есть). Другие авторы рекомендуют считать хэш Hibernate сущностей на основе всех полей кроме id. В чём недостатки такого решения: ❌ Если поля изменяемые, есть шанс потерять объект внутри HashSet ❌ Цель хэша — быстрая проверка. Если считать хэш всех полей, с тем же успехом можно использовать списки и сравнение через equals Что же делать? 1️⃣ Использовать для хэша любое неизменяемое поле Даже если поле не уникальное, распределение хэшей будет лучше, чем у константы 2️⃣ Не использовать хэш-структуры для новых объектов Новые объекты собирать в список:
List users = …
users.forEach(u -> session.save(u));

Тогда в хэшкоде можно спокойно использовать id и для уже сохранённых объектов хэшсет будет работать как надо:
Set users = …
if (!users.contains(…)) {…}

Итого: 🔸 Hashcode нужен только, когда структура используется в hash-based структурах. Если новые объекты не складываются в HashSet или HashMap, то проблемы вообще нет 🔸 Если вы хотите возвращать в хэшкод константу, рассмотрите вариант хранения сущностей в ArrayList или TreeSet Ответ на вопрос перед постом: зависит от сценариев использования. Если новые объекты User собираются в коллекцию, я бы складывала в список, а hashcode реализовала как return id; Но ситуации бывают разные, решение не универсально. И более глобальные выводы: Хороших материалов по разработке мало. Но даже в хороших легко свернуть не туда. Статья Thorben Janssen в целом ок, но итог немного сбивает с толку. Сравните: 💁🏼‍♂️ "Если для сущности id генерируется в БД, hashcode должен возвращать константу" 💁🏼 "Если новые Hibernate сущности складываются в hash структуры, и у них нет final полей, то для соблюдения контракта можно использовать в hashcode константу" Второй вариант корректнее, но первый проще и лучше запоминается. Не попадайте в эту ловушку. Задача разработчика — разобраться в сценариях, оценить варианты и найти подходящий😌

🤔Как написать игру «Game Of Life» на Clojure? Узнайте на бесплатном вебинаре в OTUS: https://otus.pw/D7TF/ ✅Занятие приуроче
🤔Как написать игру «Game Of Life» на Clojure? Узнайте на бесплатном вебинаре в OTUS: https://otus.pw/D7TF/ ✅Занятие приурочено к старту онлайн-курса «Clojure Developer». На вебинаре мы: — Узнаем, как реализовать на Clojure классическую задачу Computer Science — Game of Life. — Обсудим разные способы визуализации работы алгоритма. — Рассмотрим, как представить состояние игры с помощью персистентных структур данных и вести разработку интерактивно через REPL. 👍Продолжить обучение на курсе возможно в рассрочку. Курс ориентирован на разработчиков с опытом работы от года. 👉Пройдите тест на сайте, узнайте, осилите ли вы обучение, и запишитесь на бесплатный вебинар: https://otus.pw/Mvip/

Какими свойствами обладает порождаемое equals() отношение эквивалентности? ☕️ Рефлексивность: для любой ссылки на значение x, x.equals(x) вернет true; ☕️ Симметричность: для любых ссылок на значения x и y, x.equals(y) должно вернуть true, тогда и только тогда, когда y.equals(x) возвращает true. ☕️ Транзитивность: для любых ссылок на значения x, y и z, если x.equals(y) и y.equals(z) возвращают true, тогда и x.equals(z) вернёт true; ☕️ Непротиворечивость: для любых ссылок на значения х и у, если несколько раз вызвать х.equals(y), постоянно будет возвращаться значение true либо постоянно будет возвращаться значение false при условии, что никакая информация, используемая при сравнении объектов, не поменялась. Для любой ненулевой ссылки на значение х выражение х.equals(null) должно возвращать false. #вопросы_с_собеседований

🔥Старт в Java-разработке с нуля и до Middle+ возможен! Полное погружение в программирование на одном из самых популярных язы
🔥Старт в Java-разработке с нуля и до Middle+ возможен! Полное погружение в программирование на одном из самых популярных языков ждет вас на специализации «Java-разработчик» в OTUS. ⚡️Преподаватели-эксперты будут делиться уникальным опытом и трендами, а также разбирать кейсы на живых вебинарах. Вы будете учиться решать реальные задачи разработки и получать фидбек в формате полноценных код-ревью. Практический опыт 15 месяцев обучения вы закрепите на двух проектных работах, которые дополнят ваше портфолио и повысят уверенность в новых скиллах. Оставляйте заявку, чтобы присоединиться к группе по спец. цене и получить чек-лист "10 распространенных ошибок, которые делают новички в Java" 👇Оплата возможна в рассрочку. https://otus.pw/4rnN/ Реклама. Информация о рекламодателе на сайте www.otus.ru

Сравните Iterator и ListIterator. ☕️ ListIterator расширяет интерфейс Iterator; ☕️ ListIterator может быть использован только для перебора элементов коллекции List; ☕️ Iterator позволяет перебирать элементы только в одном направлении при помощи метода next(). Тогда как ListIterator позволяет перебирать список в обоих направлениях, при помощи методов next() и previous(); ☕️ ListIterator не указывает на конкретный элемент: его текущая позиция располагается между элементами, которые возвращают методы previous() и next(). ☕️ При помощи ListIterator вы можете модифицировать список, добавляя/удаляя элементы с помощью методов add() и remove(). Iterator не поддерживает данного функционала. #вопросы_с_собеседований

Мы создали практическую онлайн-программу «Java-разработчик», которая позволит за 10 месяцев плотной практики стать высокоопла
Мы создали практическую онлайн-программу «Java-разработчик», которая позволит за 10 месяцев плотной практики стать высокооплачиваемым специалистом. Учиться на Хекслете удобно: ✔️Все лекции доступны 24/7 на платформе — занимайтесь в удобное время ✔️ Практика прямо в браузере ✔️Наставники, которые помогут в процессе обучения, и кураторы, контролирующие прогресс Вы также сможете принять участие в открытых проектах Хекслета на GitHub. Научитесь работать с реальными приложениями и закреплять навыки, полученные на курсе, прямо в браузере. А самое главное — вы станете участником Карьерного трека уже во время обучения. Пройдете вебинары, которые охватывают все темы по трудоустройству: от составления резюме и рабочих профилей до психологических аспектов собеседования и адаптации на рабочем месте. Получите рекомендации по своему первому резюме от HR-специалистов и более опытных разработчиков. Мы заинтересованы, чтобы вы нашли первую работу. Получите полную консультацию по профессии и карьере в IT!

Оптимизация запросов В этом посте хочу рассказать основы оптимизации запросов в БД. Буду говорить на примере Postgre, но в других БД процесс похож. Шаг 0. Вспоминаем основы При выполнении запроса участвуют два процесса: ▪️ Планировщик — составляет план выполнения запроса. Какие таблицы обойти, что проверить и в какой последовательности ▪️ Исполнитель — извлекает данные по заданному плану Разработчик может создать дополнительные структуры данных — индексы. Индексы помогают быстрее выполнять запросы, но занимают много места. Если данные в таблице занимают 1 ГБ, то индекс с id займёт 250 МБ. Шаг 1. Ищем, что оптимизировать Смотрим таблицу pg_stat_statements — там собирается статистика по запросам. Чтобы получить достоверные данные, берём статистику с продакшн базы. Ищем запросы, которые выполняются часто или долго. Шаг 2. Работаем с конкретным запросом Для экспериментов берём тестовую базу с большим количеством данных. Минимум миллион записей, иначе эффект оптимизаций не будет заметен. Прогоняем запрос через EXPLAIN ANALYZE:
EXPLAIN ANALYZE SELECT * FROM users where name = ’K’;

EXPLAIN пишет только план выполнения запроса. EXPLAIN ANALYZE выполняет запрос и показывает ▪️ planning time — время планирования запроса ▪️ execution time — время выполнения запроса. Работаем с этим значением Можно поиграть с условиями, порядком соединения таблиц и разными функциями. Обратите внимание на способ обхода таблицы: Index Scan using name_index on — при выполнении запроса используется индекс, и это отлично Seq Scan on означает, что происходит долгий последовательный обход таблицы. Причиной может быть 🔸 поиск по условию (where name = …) 🔸 проверка уникальности поля 🔸 проверка внешнего ключа (foreign key) Решение здесь простое — добавить индекс по проблемному полю. Базовый вариант выглядит так:
CREATE INDEX index_name ON users(name);

Дальше всё просто: ▫️ Запустить EXPLAIN ANALYZE ▫️ Увидеть в плане выполнения новый индекс ▫️ Порадоваться снижению execution time Для оптимизаций популярных и тяжёлых запросов добавление индекса оправдано. Разумеется, не нужно добавлять индексы для всех запросов и всех условий. Индексы занимают много места и замедляют запись в базу. В оптимизации запросов огромное количество нюансов, но большинство проблем решается кэшем и добавлением индекса. Более сложные случаи лучше обсуждать с коллегами DBA😌

Академия Яндекса продолжает набор в Летние школы для джунов и других спецов с опытом работы. Они пройдут в 3 странах — Россия
Академия Яндекса продолжает набор в Летние школы для джунов и других спецов с опытом работы. Они пройдут в 3 странах — Россия, Сербия и Казахстан. — Школа фронтенда; — Школа мобильной разработки (iOS, Android, Flutter); — Школа бэкенд-разработки (Python, Java, C++, Go) — Школа менеджеров (управление проектами и продуктами, маркетинг, продуктовая аналитика) Сначала пройдут лекции в онлайне, а затем практика в офисах Яндекса в Москве, Белграде и Алматы. Участники будут работать над реальными проектами в фулстек-группах с опытным экспертом-наставником. Лучшие студенты смогут получить оффер в штат или приглашение на стажировку – по внутренней статистике Яндекса, 50% выпускников с каждого потока становятся стажерами или сотрудниками. Если вы из другого города, но успешно закончите онлайн-этап, Яндекс оплатит билеты и проживание на период практики. Чтобы попасть в интересующую вас Школу, нужно отправить заявку и пройти конкурсный отбор на основе тестового задания, опубликованного на странице Школ.

Приведите пример, когда какая-либо коллекция выбрасывает UnsupportedOperationException. public static void main(String[] args) { List<Integer> list = Collections.emptyList(); list.add(0); } #вопросы_с_собеседований

Где и как вы можете использовать приватный конструктор? Приватный (помеченный ключевым словом private, скрытый) конструктор может использоваться публичным статическим методом генерации объектов данного класса. Также доступ к нему разрешён вложенным классам и может использоваться для их нужд. #вопросы_с_собеседований

🔥 Как создать простой чат с помощью Firebase и Kotlin? Узнайте и попробуйте 24 марта в 20:00 мск на бесплатном вебинаре онла
🔥 Как создать простой чат с помощью Firebase и Kotlin? Узнайте и попробуйте 24 марта в 20:00 мск на бесплатном вебинаре онлайн-курса «Kotlin Backend Developer. Professional» в OTUS. 📚Что будет на занятии? - Посмотрим в структуру firebase, создание и подключение аккаунта - Разберем и продумаем архитектуру чата - Реализуем клиента для чат приложения, используя Realtime Database В результате вебинара у вас будет базовое умение работы с Firebase, знание, как работает realtime база данных и онлайн-чат, полностью написанный на Kotlin.   👉 Регистрация на вебинар:  https://otus.pw/QB5X/   Не упустите возможность протестировать обучение, а продолжить вы сможете уже на курсе, доступном в рассрочку.   Реклама. Информация о рекламодателе на сайте www.otus.ru

Назовите основные свойства транзакции. Атомарность (atomicity) гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной. Согласованность (consistency). Транзакция, достигающая своего нормального завершения и, тем самым, фиксирующая свои результаты, сохраняет согласованность базы данных. Изолированность (isolation). Во время выполнения транзакции параллельные транзакции не должны оказывать влияние на её результат. Долговечность (durability). Независимо от проблем на нижних уровнях (к примеру, обесточивание системы или сбои в оборудовании) изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу. #вопросы_с_собеседований

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

Типы кэшей Если спросить разработчика, что такое кэш, он скорее всего ответит: — Кэш — хранилище типа ключ-значение. Позволяет снизить количество запросов к БД, другому сервису или не выполнять повторно сложные вычисления Это, безусловно, правда, но не вся. В этом посте кратко опишу, что ещё умеют делать кэши и какие они бывают. 1️⃣ Кэш внутри сервиса Хранится только в оперативной памяти. При выключении сервиса кэш пропадает. При включении — заполняется. Популярны два варианта: 🔸 ConcurrentHashMap: полностью ручное управление. Разработчик пишет код по наполнению кэша, обновлению и удалению значений 🔸 Google Guava Cache: более продвинутый вариант. Очищает кэш, уведомляет об удалении, предоставляет статистику 2️⃣ Удалённый кэш Не связан с конкретным сервисом и запущен в отдельном процессе ✅ Доступен для нескольких сервисов ✅ Хранит данные на нескольких уровнях — в оперативной памяти и на диске 3️⃣ Распределённый кэш Данные хранятся в нескольких процессах. Один экземпляр обычно называют нодой ✅ Шардирование. Распределяем данные по разным нодам и в итоге храним больше данных ✅ Репликация. Дублируем данные на разные ноды и повышаем доступность Уровни 2-3 это скорее ступени эволюции кэшей. Большинство реализаций находятся на уровне 4: 4️⃣ In-memory data grid (IMDG) Распределённый кэш с дополнительными фичами. Например: ▫️ Атомарный апдейт (вместо чтения и перезаписи) ▫️ Подписка на изменения в кэше ▫️ Поддержка транзакций ▫️ SQL-like запросы ▫️ Средства синхронизации (распределённый lock, очередь) ▫️ Продвинутый мониторинг ▫️ Выполнение скриптов У многих кэшей есть платная и бесплатная версии. Многие фичи из списка выше доступны только платно. В вакансиях чаще всего встречается Redis, чуть отстаёт Hazelcast. Также видела в проектах Memcached, Ehcache, Aerospike, Ignite/GridGain, Coherence. В их описании нет слова "кэш", как минимум distributed real-time in-memory streaming data platform🙂 Рекомендую погулять по документации того же Redis или Hazelcast, может для вашего проекта найдётся что-то полезное.

🔴 «Кто прод ронял, тот в цирке не смеется» Если вам знаком термин SDLC (жизненный цикл разработки ИТ-продукта), вы знаете, ч
🔴 «Кто прод ронял, тот в цирке не смеется» Если вам знаком термин SDLC (жизненный цикл разработки ИТ-продукта), вы знаете, что эксплуатация — важнейший этап для команды. А одним из критических свойств системы является сопровождаемость. 📢📢 Подключайтесь в понедельник 13 марта в 20:00 мск к отрытому уроку онлайн-курса «Software Architect» в OTUS. На занятии мы рассмотрим архитектурное свойство “сопровождаемость” на примере соответствующих сервисов k8s: Pod, Deployment, ReplicaSet. 🎓 Занятие проведет Анатолий Бурнашев, эксперт центра практик обеспечения надёжности в MTS.Digital. ❗️ Не упустите возможность познакомиться с преподавателем и форматом обучения! Продолжить обучение можно в рассрочку. ➡️ Для участия пройдите вступительный тест: https://otus.pw/2OXl/ Реклама. Информация о рекламодателе на сайте otus.ru

Асинхронность, параллельность, многопоточность Опишу простыми словами разницу между этими и близкими терминами. Многоядерный Относится к процессору. У процессора 4-16 ядер, каждое работает независимо от других. Если ядер 8, то в каждый момент процессор работает над 8 задачами. Во многих процессорах есть технология hyper-threading, когда на 1 ядре выполняются 2 задачи. Тогда на 8 ядрах могут одновременно выполняться 16 задач. Многопоточный Относится к языку программирования. Это возможность изолировать задачи в разных потоках. У каждого потока свои локальные переменные, область видимости и исполняемый код. Очень удобно:) Если у процессора 8 ядер, в java приложении в каждый момент выполняются не больше 8 потоков (= не больше 8 задач). В других языках дело обстоит по-другому, подробнее в этом посте. Многопоточность — свойство языка, но в жизни часто упоминают "многопоточный код". Это код, в котором задачи из разных потоков взаимодействуют между собой. Например, запросы увеличивают общую переменную — счётчик запросов. Или задача делится на подзадачи, и они выполняются в разных потоках. Когда в вакансии пишут про знания многопоточки, то имеют в виду мастерское владение java.util.concurrent, знание возможных многопоточных проблем и лучших практик. Concurrency Относится к системе в целом. Система называется concurrent, если в ней выполняются несколько задач и актуальны проблемы: 🔹 как поделить системные ресурсы между задачами 🔹 как координировать задачи между собой 🔹 как корректно работать с общими ресурсами 🔹 как сделать так, чтобы ничего не сломалось при увеличении нагрузки В наши дни сложно найти что-то НЕ concurrent, все веб-сервисы попадают в эту категорию. На практике под concurrent кодом подразумевается, что проблемы выше решает не только фреймворк, но и разработчик. Параллельный Относится к задачам. Параллельно = одновременно. Процессор с 8 ядрами выполняет в каждый момент времени 8 задач = процессор параллельно выполняет 8 задач. В жизни термин употребляется не так строго. Допустим, нужно обработать 10 млн элементов. Если делать это последовательно, то будет работать одно ядро процессора, а остальные 7 (если ядер 8) — простаивать. При параллельной обработке задача разбивается на 10 частей по 1 млн, и каждая подзадача отправляется в отдельный поток. Вычислениями занимаются больше ядер, и общий результат посчитается быстрее. Значит ли это, что все 10 задач выполняются одновременно? Нет. Если у процессора 8 ядер, то в один момент выполняется максимум 8 задач. Но подобную схему всё равно называют параллельной обработкой Асинхронный Относится к общению между потоками, классами или сервисами. Синхронный означает, что участник 1 останавливает свою работу и ждёт результата от участника 2: ▫️ поток отправил запрос в БД и ждёт ответ ▫️ сервис отправил HTTP-запрос в другой сервис и ждёт ответ ▫️ поток отправил задачу в executor и ждёт результат через join Часто используют слово "блокирующий" как синоним синхронного запроса Асинхронный — когда участник 1 отправил запрос и НЕ ждёт ответ. Результат либо не нужен, либо участник 2 сам инициирует общение, когда результат готов: ▫️ поток отправил задачу в executor и не вызывает у задачи join ▫️ сервис отправляет сообщение в месседж брокер Многие инструменты выглядят как синхронные, но под капотом работают асинхронно. Например, метод sendAsync в HttpCLient или реактивные драйвера БД. 🎁 Бонус — чтобы понять, что могут спросить на собесах, воспользуйтесь формулой: Может ли (термин 1) быть/не быть (термин 2)? Например, ❓ Возможна ли многопоточная программа без параллельности? да ❓ А параллельная без многопоточности? нет ❓ Может ли однопоточная программа быть асинхронной? да ❓ Возможны ли многопоточные проблемы в программе, запущенной на одноядерном процессоре? да

В чем заключается особенность работы метода clone () с полями объекта типа ссылки? При клонировании объектов копируются только примитивные значения и значение ссылок на объекты. Это значит, что если объект имеет во внутреннем поле ссылку на другой объект, то будет клонирована только эта ссылка, сам же этот другой объект клонирован не будет. Собственно, это и называют — поверхностным клонированием. Ну а что, если вам нужно полноценное клонирование с клонированием всех вложенных объектов? Как сделать, чтобы это были не копии ссылок, а полноценные клоны объекты с другими занимаемыми ячейками памяти в куче? На самом деле все довольно просто — для этого вам нужно в каждом классе этих внутренних объектов также переопределить метод clone() и добавить интерфейс маркер — Cloneable. Тогда будут скопированные не ссылки на объекты, а сами объекты, ведь теперь они тоже имеют возможность копировать себя. #вопросы_с_собеседований

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