Java: fill the gaps
前往频道在 Telegram
Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк 🔥Тот самый курс по многопочке🔥 https://fillthegaps.ru/mt Комплименты, вопросы, предложения: @utki_letyat
显示更多📈 Telegram 频道 Java: fill the gaps 的分析概览
频道 Java: fill the gaps (@java_fillthegaps) 俄语 语言赛道中的 是活跃参与者。目前社区聚集了 12 396 名订阅者,在 技术与应用 类别中位列第 9 830,并在 俄罗斯 地区排名第 51 978 位。
📊 受众指标与增长动态
自 невідомо 创建以来,项目保持高速增长,吸引了 12 396 名订阅者。
根据 27 八月, 2026 的最新数据,频道保持稳定运转。过去 30 天订阅人数变化为 -61,过去 24 小时变化为 -4,整体触达仍然可观。
- 认证状态: 未认证
- 互动率 (ER): 平均受众互动率为 0%。内容发布后 24 小时内通常能获得 N/A% 的反应,占订阅者总量。
- 帖子覆盖: 每篇帖子平均可获得 0 次浏览,首日通常累积 0 次浏览。
- 互动与反馈: 受众积极参与,单帖平均反应数为 0。
- 主题关注点: 内容集中在 redis, hashmap, linkedhashmap, индекс, фича 等核心主题上。
📝 描述与内容策略
作者将该频道定位为表达主观观点的平台:
“Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк
🔥Тот самый курс по многопочке🔥
https://fillthegaps.ru/mt
Комплименты, вопросы, предложения: @utki_letyat”
凭借高频更新(最新数据采集于 28 八月, 2026),频道始终保持新鲜度与高覆盖。分析显示受众积极互动,使其成为 技术与应用 类别中的关键影响点。
12 396
订阅者
-424 小时
-157 天
-6130 天
帖子存档
12 396
Понятия в БД, часть 3. CAP, BASE, PACELC
Аббревиатура ACID появилась в 1983 году и относилась тогда к реляционным БД небольшого размера. В 2021 БД уже большие и распределённые. С ними связаны три понятия - CAP теорема, BASE и PACELC теорема. С ними и разберёмся в этом посте.
CAP теорема говорит, что распределённая система может обеспечить не больше двух гарантий из трёх:
🔸 Consistency. Эта целостность отличается от понятия в ACID и означает, что при каждом чтении
читается последнее значение. Неважно, один сервер в системе или тысяча.
🔸 Availability - каждый запрос возвращает ответ.
🔸 Partition tolerance - система продолжает работать несмотря на задержки в связи серверов и отказ некоторых из них.
Речь идёт о распределённых системах, так что без Partition tolerance никак. Если во время запроса пропала связь между серверами, придётся делать выбор:
🤔 Отменить запрос. Упор на консистенси - доступность снижается, зато ответ будет точным. Такие системы условно называют CP системами, к ним относятся Redis и Mongo.
🤔 Выполнить запрос, но не будут учитываться данные с опоздавших серверов. Это AP системы, среди них Apache Cassandra, Riak, Hazelcast
У целостности и доступности тоже есть градации:
▫️Доступность считается высокой от 90% до 99.999999%
▫️У целостности 15+ различных моделей
100% гарантий никто не даёт, и деление систем на СР и АР довольно условное. У большинства БД и месседж-брокеров можно настроить баланс между доступностью и целостностью для разных ситуаций.
Расширение CAP теоремы - теорема PACELC:
🔹 Если связь между серверами нарушается, придётся выбирать между целостностью данных и доступностью. Об этом говорится в CAP.
🔹 При нормальной работе встаёт выбор между низкими задержками(latency) и целостностью(consistency). Чем чаще синхронизируются сервера, тем выше задержки и целостность данных.
И ACID, и CAP теорема обещают больше, чем есть на деле. Более честен акроним BASE:
▪️ Basically Available - некоторые сервера могут быть недоступны, но в целом система работает.
▪️ Soft state - некоторые данные могут не сразу попасть на другие сервера.
▪️ Eventual consistency - но однажды точно попадут.
Неопределённость и слабые гарантий, но это реалии разработки распределённых систем.
🟥 Теперь ответ на вопрос перед постом. Термин "целостность" по-разному трактуется в ACID и CAP теореме. Грубо говоря:
▫️ ACID consistency - в данных нет аномалий
▫️ CAP consistency - данные на всех серверах одинаковые
Может быть ситуация, когда в БД выставлен уровень Serialazable и отличная целостность по ACID, но так себе целостность по CAP, и сервера синхронизируются раз в час. Может быть и наоборот, и в разных сочетаниях.
12 396
Понятия в БД, часть 2. Уровни изоляции
Изоляция в ACID говорит: транзакция должна выполняется так, как будто других транзакций нет.
Единственный надёжный способ - запускать транзакции последовательно. Это медленно, поэтому БД поддерживает менее строгие модели изоляции. База работает быстрее, но возможны аномалии данных.
В этом посте углубимся в детали - что за аномалии, что за уровни изоляции, и какие проблемы они решают.
Все проблемы транзакций давно изучены: dirty reads, write skews и т.д. Чем больше проблем решает БД, тем сложнее код и тем медленнее работает БД. Уровни изоляции позволяют найти баланс между скоростью и корректностью.
В SQL стандарте их 4:
▫️ READ_UNCOMMITED ▫️ READ_COMMITED ▫️ REPEATABLE_READ ▫️ SERIALIZABLEКаждый уровень гарантирует решение чёткого списка проблем. Для остальных нужно либо писать код, либо забить на возможные неточности. В стандарте SQL описаны три проблемы: 🔸 Dirty reads - грязные чтения Транзакция 1 обновляет поле Х. Другие транзакции видят новое значения Х до того, как транзакция 1 завершится. В вопросе с переводом денег как раз возникла такая ситуация. Транзакция перевода ещё не завершилась, а другая транзакция прочитала промежуточные значения. Где возникает проблема: только на уровне READ_UNCOMMITED. 🔸 Nonrepeatable reads - неповторяющиеся чтения Транзакция 2 читает поле X и работает с ним. В это время транзакция 3 обновляет поле Х. В итоге транзакция 2 работает с устаревшим значением. Более формально, "неповторяющееся чтение" - когда чтение одного поля в начале и конце транзакции даёт разные результаты. Но редко кто читает одно поле дважды, на практике получается либо бесполезная транзакция с устаревшими данными, либо несогласованные данные внутри транзакции. Проблема остро проявляется для долгих запросов - бэкапов или аналитики. Решается на уровне REPEATABLE_READ и выше. 🔸 Фантомные чтения Транзакция 3 проверяет условие по большому количеству записей. Транзакция 4 меняет выборку, например, добавляет новую запись. Если условие в транзакции 3 перестанет выполнятся, транзакция 3 этого не заметит. Важно, что условие касается не одного поля, а многих. В этом разница с неповторяющимся чтением - там меняется одно конкретное поле, а в фантомном чтении меняется вся выборка, по которому проверяется условие. Проблема решается на уровне SERIALIZABLE. Подробные примеры и схемы аномалий есть в Википедии. Я перечислила основные, но у многих проблем есть разновидности, поэтому аномалий получается больше, чем уровней изоляции. Каждая БД сама решает, какие проблемы решать на конкретных уровнях. У MS SQL Server - 5 уровней, у Oracle - 3. Большинство NoSQL баз не поддерживают транзакции, поэтому для них указывать тип изоляции бессмысленно. В универсальных адаптерах типа JDBC, Hibernate и Spring Data уровней столько, сколько в стандарте - 4. Ещё одна проблема, которой нет в SQL стандарте, но встречается на практике: 🔸 Потерянный апдейт Транзакции работают с одними данными и не учитывают друг друга. Пример: транзакция 5 и транзакция 6 одновременно прочитали значение счётчика. Каждая транзакция прибавила к значению единицу и обновила поле счётчика. Вначале они прочитали одно значение, и получается, что один инкремент потерялся. Проблема решается не только уровнями изоляции, но и SQL конструкциями: 🔹 Атомарный апдейт:
UPDATE test SET x=x-1 where id=1;🔹 Блокировка строки:
SELECT * FROM test WHERE id = 1 FOR UPDATE;Итог. Как учитывать внутрянку БД в написании кода: 1️⃣ Выбирать уровень изоляции с учётом вероятности и критичности проблем 2️⃣ Уточнить в документации БД, какие проблемы решает выбранный уровень 3️⃣ Писать код с учётом возможных аномалий 4️⃣ Помнить о потерянных апдейтах
12 396
Петя и Катя - брат и сестра, у каждого на счету 500р. Петя перевёл Кате 100р. Банк делает это в рамках одной транзакции. Мама смотрит в приложении балансы и видит 400 и 500 рублей. Обновляет данные и видит 400 и 600. На каком уровне изоляции это возможно?
12 396
Пара слов о гарантиях и Consistency в ACID.
Нужно чётко понимать разницу:
🔸 Заданные внутри БД ограничения, constraints, выполняются всегда.
Пример: в таблице хранится цена товара и скидочная цена:
price numeric, sale_price numeric CHECK(price>sale_price)Условие "обычная цена выше скидочной" задано в пределах ОДНОЙ записи. БД контролирует это условие и выдаст ошибку при несоблюдении. 🔸 Другое дело - транзакция, в которой меняются РАЗНЫЕ записи. Нельзя атомарно перевести 100 рублей с одного аккаунта на другой. Будет момент, когда с одного аккаунта уже сняли 100 рублей, а на другой ещё не перевели. Целостность данных ненадолго нарушится. От уровня изоляции зависит, заметят ли несоответствие другие транзакции. Эту тему обсудим сегодня.
12 396
Понятия в БД, часть 1. ACID
Какими свойствами обладает БД - популярный вопроc на собеседовании. Предполагается, что кандидат назовёт аббревиатуру ACID и cкажет 4 главных слова - Atomicity, Consistency, Isolation, Durability. На этих нехитрых знаниях можно дорасти до позиции сеньор, но дальше этого будет недостаточно.
Этот пост о том, зачем нужен ACID, какую задачу решает и как влияет на разработку.
ACID - это набор гарантий. Подразумевается, что если БД обозначена как ACID-compliant, можно ожидать следующее:
🔸 A - Atomicity
Можно объединить несколько операций в одну транзакцию. Если произойдёт ошибка, уже сделанные операции в группе отменятся. Всё или ничего.
Благодаря этому свойству можно не держать в коде несколько версий данных "на всякий случай" и восстанавливаться после ошибок гораздо проще.
🔸 C - Consistency
Целостность - широкий термин и его значения отличаются в ACID и CAP теореме. Что это значит в ACID: если для данных в БД заданы ограничения(constaints), то гарантируется их соблюдение всегда и везде. Если две транзакции захотят записать одинаковые значения в колонку с UNIQUE, то одна транзакция завершится с ошибкой.
Пользы от этого свойства мало. Обычно все проверки находятся в коде, поэтому у базы здесь немного работы.
🔸 I - Isolation
Каждая транзакция выполняется так, как будто других транзакций не существует.
На практике внутри БД происходит лютая многопоточка, с одними структурами одновременно работают десятки и сотни транзакций. Единственный способ надёжно изолировать их друг от друга - запускать транзакции последовательно.
Такая схема работает медленно, поэтому у БД есть менее строгие уровни изоляции. База работает быстрее, но возможны аномалии в данных. Подробно поговорим о них в части 2.
🔸 D - Durability
Если данные записаны в БД, они не потеряются. Даже если выключится свет во всём районе.
Достигается двумя способами:
▫️ Запись на носитель, например, жёсткий диск или SSD
▫️ Отправка копий на другие сервера
100% надёжности на тысячи лет не будет, но сохранность данных - наименее проблемный пункт из всех остальных.
Подведём итог. ACID не даёт гарантий на уровне "записал и забыл". Целостность данных лежит на бизнес-логике, а в коде учитываются возможные ошибки неполной изоляции.
Поэтому ACID чаще встречается не в техническом описании, а в маркетинговых текстах рядом с цифровой трансформацией и дизайн-мышлением. Новые БД не берут на себя грех называться ACID-compliant, а используют более мягкую аббревиатуру BASE. Она не даёт чувства стабильности, но лучше отражает реальность.
12 396
Когда я была беспечным джуниором, я представляла базу данных как всемогущий цилиндр, в который записываешь что угодно, а потом читаешь.
С годами стало понятно, что это обычная программа со своими сложностями и гарантиями. В цикле из трёх статей расскажу о принципах работы БД, которые пригодятся на практике. Они не относятся к конкретным БД, но помогают понять, где на БД можно положиться, а где надо подстраховаться и написать дополнительный код.
План такой:
Часть 1 - ACID
Часть 2 - Уровни изоляции транзакций
Часть 3 - CAP теорема и BASE
12 396
Intellij IDEA: как выучить шорткаты
В IDEA сотни горячих клавиш. С ними удобно работать, не надо тащить курсор через 2 монитора и бродить по контекстному меню. Есть только одна проблема - шорткаты сложно запомнить сразу.
Видела, как люди распечатывают огромный список горячих клавиш и вешают рядом с монитором. Поделюсь более прогрессивными методами:
1️⃣ Выучить топ-15
Статистика использования IDE находится в Help → Productivity Guide. Сортируем по колонке Used, получаем часто используемые команды. В описании указаны шорткаты. Запоминаем горячие клавиши для 10-15 действий, и продуктивность заметно растёт.
2️⃣ Плагин Key Promoter X
Установка: File → Settings → Plugins → Key Promoter X.
При действиях с мышкой в углу всплывает подсказка-шорткат.
Здесь работает правило 80/20: шорткаты для навигации, поиска и рефакторинга покрывают большинство ежедневных задач. Их легко выучить с помощью этих двух инструментов.
12 396
Как считается хэшкод по умолчанию?
На собеседованиях часто обсуждают методы equals и hashcode. За что отвечают, как соотносятся между собой, когда переопределять, а когда не стоит.
В этом посте разберём, как считается хэшкод под умолчанию. Практической пользы у него, конечно, нет🙂. Цель вопроса - проверить, понимает ли человек внутреннюю работу JVM. Бывает, что ответы на стандартные вопросы знает, а как всё связано вместе - нет. Возможен такой диалог:
- Как считается хэшкод по умолчанию?
- Это адрес объекта в памяти.
- А почему так?
- Адрес каждого объекта уникален, то что надо для хэшкода.
- Сборщик мусора перемещает объекты внутри памяти. Как это влияет на значения хэшей?
- Ээээ...
Разберём вычисление хэшкода от и до. Сигнатура метода в классе Object выглядит так:
public native int hashCode();В разных JVM реализации могут отличаться. Рассмотрим исходный код hashcode() в OpenJDK. Там 6(!) стратегий вычисления хэшкода. Стратегия задаётся опциями VM:
-XX:+UnlockExperimentalVMOptions -XX:hashCode={число}
При первом вызове результат сохраняется внутри объекта. Хэшкод для Object считается один раз и не меняется, даже если объект перемещается в памяти. Посмотрим все возможные варианты:
🔸 Стратегия по умолчанию.
Случайное число по алгоритму Xorshift RNG. Следующее значение вычисляется на основе предыдущего. Значения равномерно распределены. У каждого потока свой генератор. Синхронизации между потоками нет, поэтому алгоритм работает быстро.
🔸-XX:hashCode=0
Случайное число по алгоритму Lehmer RNG. Генератор один на все потоки, поэтому работает медленно.
🔸-XX:hashCode=1
Адрес объекта в памяти и немного манипуляций с битами. Работает быстро, но не даёт равномерного распределения хэш кодов.
🔸-XX:hashCode=2
Чемпион по скорости, возвращает 1 для всех объектов:
java.lang.Object@1Используется как отправная точка для тестов остальных стратегий. 🔸
-XX:hashCode=3
Обычная возрастающая последовательность:
java.lang.Object@a4 java.lang.Object@a5 java.lang.Object@a6🔸
-XX:hashCode=4
Текущий адрес в памяти. Популярный, но неправильный ответ на собеседованиях. Отчасти в этом виновата документация: там адрес приводится как пример реализации.
Рейтинг стратегий по скорости:
🏆 Вернуть единицу: 184 операций за микросекунду
🥈 Вариант по умолчанию: 176 оп/мск
🥉 Адрес в памяти-1: 175 оп/мск
4️⃣ Адрес в памяти-2: 160 оп/мск
5️⃣ Растущая последовательность: 14 оп/мск
6️⃣ Случайное число и глобальная переменная: 10 оп/мск
Интересно, что до java 8 самая медленная опция была вариантом по умолчанию.
Резюме:
✅ Реализация хэшкода зависит от JVM и VM-флажков.
✅ Расчёт на основе адреса памяти не даёт равномерного распределения.
✅ Общие переменные в маленьких методах снижают производительность в 10 раз.
✅ В OpenJDK 6 стратегий вычисления хэшкода. По умолчанию используется генератор случайных чисел в рамках одного потока.12 396
Stream API: новые методы в Java 16
16 марта вышла java 16. Новые фичи входят во вторую превью стадию перед главным релизом 2021 - java 17 LTS.
Существующие классы тоже развиваются. В java 16 в Stream API появилось 4 новых метода, которые мы и рассмотрим в этом посте.
1️⃣
toList()
С 25 по 27 ноября была серия постов о коллекторах (часть 1, часть 2, часть 3). Там я писала, что вместо
collect(Collectors.toList())было бы удобно писать просто
toList()30 ноября разработчик Oracle добавил метод toList() в класс Stream. Вряд ли он читает этот канал, но совпадение интересное🙂 Новый метод не совсем равнозначный: ▫️Collectors.toList() возвращает экземпляр ArrayList. ▫️Новый метод toList() возвращает неизменяемый список. 2️⃣ mapMulti Это оптизированный flatMap. Объясню суть на примере. Заказ - класс Order, товар - класс Item. Заказ состоит из нескольких товаров. Из списка заказов хотим получить список всех товаров.
orders.stream() .flatMap(order->order.getItems().stream()) .toList();flatMap переводит "список списков" в один список. Товары для каждого заказа превращаются в Stream, а метод flatMap объединяет эти стримы в один. Минус: объект стрима создаётся всегда, даже для пустых списков. mapMulti устраняет этот недостаток:
orders.stream() .<Item>mapMulti((order, consumer) -> order.getItems().forEach(item -> consumer.accept(item)) ).toList();Что происходит: mapMulti принимает на вход (order, consumer): ▪️order - элемент стрима, в нашем случае - заказ ▪️consumer - следующий этап в стриме. Наша задача - передать этому этапу все будущие элементы. Берём у заказа товары и для каждого вызываем consumer.accept(item). Мультимэп не знает, для каких объектов будет вызван accept, и не может вывести тип выходных элементов. Поэтому для нормальной работы тип надо указать явно:
<Item>mapMulti(…)Когда использовать mapMulti? ✅ Небольшое количество элементов в списках. Например, много заказов с 1-2 товарами ✅ Элементы легко получить без Stream API Основная фишка mapMulti - нет промежуточных стримов. Если внутри метода создаётся стрим, то вся выгода сходит на нет. ❌ order.getItems().stream()… Есть три вариации метода: 🔸IntStream mapMultiToInt 🔸LongStream mapMultiToLong 🔸DoubleStream mapMultiToDouble Для них выходной тип не указывается.
12 396
Аннотации, часть 2: как использовать
Продолжим вчерашнюю тему. Рассмотрим Retention, и когда пригодится самодельная аннотация.
@Retention определяет, на каком этапе доступна аннотация:
🔹 SOURCE - аннотация видна только во время компиляции
🔹 CLASS - доступна также в байт-коде
🔹 RUNTIME - видна всегда, даже во время работы программы
Доступность выбирается исходя из цели. Поэтому перейдём к кейсам.
Что можно сделать через аннотации?
1️⃣ Объединить уже существующие.
Самый популярный и простой случай. Если в проекте несколько аннотаций часто идут вместе, объедините их в одну. Если у всех компонентов есть обработчики, то больше ничего делать не надо, всё заработает само.
Пример: @SpringBootApplication - это комбинация @Configuration, @EnableAutoConfiguration и @ComponentScan.
2️⃣ Генерация кода и файлов.
Происходит на этапе компиляции:
🔸 Отмечаем код аннотацией
🔸 Создаём класс-наследник от AbstractProcessor. Определяем, на какие аннотации реагировать
🔸 Вытаскиваем дополнительную информацию через
.class
Deprecated d = Account.class. getAnnotation(Deprecated.class)🔸 Делаем что-то полезное 🔸 Включаем процессор в компиляцию. В maven-compiler-plugin это секция annotationProcessors. Для обработки подойдут аннотации с любой RetentionPolicy. Что получаем: ❌ Долгая компиляция ❌ Специфичное тестирование. Пример 😐 Сложный и запутанный код ✅ Не тратится время на старте приложений Этот подход используется в библиотеке Lombok, микрофреймворках Quarkus и Micronaut, в Android фреймворке Dagger. Библиотека Dekorate на основе аннотаций создаёт манифесты для Kubernetes и OpenShift. 3️⃣ Статический анализ. Алгоритм такой же - создать наследник от AbstractProcessor, добавить в процесс компиляции. Примеры: библиотека Google Error Prone ищет в коде ошибки, Hibernate Validator проверяет, что аннотации Hibernate корректно расставлены. 4️⃣ Работа с байт-кодом. Редкий случай. В байт-коде остаются аннотации с RetentionPolicy.CLASS или RUNTIME. 5️⃣ Создать объекты и прокси-классы. Доступно для аннотаций с RetentionPolicy.RUNTIME. Основа работы многих фреймворков: Spring, Hibernate, Java EE. Под работу с аннотациями в рантайме заточены многие библиотеки: Reflections, Spring. Работать с ними удобно и приятно. Обработка рантайм-аннотаций обычно происходит на старте приложения, поэтому запуск сервиса может занимать несколько минут. ❌Теперь рассмотрим анти-кейсы, для чего аннотации НЕ нужны: 1️⃣ Отметить код для себя или команды. Поставить аннотацию @RefactorASAP легко, но без дальнейших действий это бесполезно. Аннотации нужно обрабатывать, и делать это автоматически. Чтобы запомнить место в коде, используйте TODO комментарии в Intellij IDEA. 2️⃣ Для бизнес-логики. Аннотации легко добавить в обход ООП и основной логики. Так можно быстро решить проблему, но долгосрочно это неудачный вариант: ❌ Нельзя контролировать процесс целиком ❌ Сложно писать тесты ❌ Сложно дебажить ❌ Внезапные сайд-эффекты Частая ситуация на Spring проектах: на старте запускаются десятки @PostConstruct. Если в процессе возникает ошибка, то найти и исправить её непросто. Но вообще, чем меньше вы полагаетесь на аннотации, тем лучше.
12 396
Аннотации, часть 1: обзор
Аннотации - дополнительная информация к исходному коду.
@Override, @Deprecated, @SuppressWarnings - вот это всё.
Первая часть будет о том, как сделать свою аннотацию, а во второй расскажу, когда и зачем это нужно.
Создать аннотацию легко:
public @interface MyAnnotation {}
❓Почему ключевое слово @интерфейс, а не @аннотейшн?
Во времена java 4 аннотаций не было и для дополнительной информации классу добавляли интерфейс-маркер. В интерфейсах Cloneable, Serializable, Remote нет методов, они используются только как дополнительный признак класса.
Подход рабочий, но похож на костыль. Цель интерфейса - показать контракт класса, поэтому для маркировки кода в java 5 ввели аннотации.
Вернёмся в наши дни. Посмотрим исходный код @Deprecated:
@Retention(RUNTIME)
@Target(value={FIELD,…})
public @interface Deprecated {
String since() default "";
boolean forRemoval() default false;
}
На этом примере видно, из чего состоит аннотация:
🔸Поля
Содержат доп. информацию. Если указать значение по умолчанию, поле становится необязательным:
@Deprecated(since="14")// forRemoval по умолчанию false 🔸Список внутри @Target показывает элементы, для которых работает аннотация. В java 7 аннотации доступны для классов, методов, параметров, полей и переменных. В java 8 аннотации действуют везде, где указан тип. Можно писать даже такое:
▫️new @Test Account() ▫️throws @Test IOException ▫️implements @Test Comparable<@Test
T>
Такие аннотации называются type annotations и используются в IDE и компиляторах для анализа и строгого контроля типов.
Аннотации нельзя ставить для имён переменных. Правильный ответ на вопрос перед постом - ошибка в 5 строке:
✅ @Test String doubled
❌ String @Test out
🔸@Retention определяет, когда доступна аннотация и как её можно использовать. Все виды подробно рассмотрим во второй части.
@Target и @Retention- это мета аннотации, то есть аннотации для аннотаций.
Какие ещё бывают мета-аннотации:
🔸@Documented - аннотация появится в JavaDoc
🔸@Inherited - наследуется подклассами
🔸@Repeatable (Java 8) - можно использовать несколько раз для одного элемента. Иногда такое приятнее читать, чем один массив:
@Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23")Создать аннотацию легко, правильно применить - уже сложнее. С этим вопросом разберёмся во второй части.
12 396
У аннотации Test определены все возможные Target. В какой строке будет ошибка компиляции (если будет)?
12 396
Гороскоп на 2021
Всем известно, что астрология играет важную роль в IT. Двухнедельный спринт - это ровно половина лунного цикла. Идеальный размер команды равен количеству планет солнечной системы. Премии рассчитываются по астральным коэффициентам.
Вот что говорят звёзды про 2021 год:
♈️ Овен
Металлический Бык симпатизирует Овнам, поэтому все инициативы будут удачны, особенно зимой, весной, летом и осенью. Будьте активны на ретро, предлагайте новые фичи и подходы, возьмите под наставничество стажёров. В сентябре ожидайте наплыв писем от HR.
♉️ Телец
В год Быка Тельцы нацелены на быстрый карьерный взлёт. Подтяните пробелы и обсудите с тимлидом возможности роста. В этом году звёзды раскрутили ваш потенциал до максимума. В августе будьте осторожнее с
git push --force.
♊️ Близнецы
Год будет спокойным и приятным. В прошлом году вы много работали, в 2021 выделяйте больше времени на отдых. Качество жизни и работы только улучшится. Самое время взяться за большие и фундаментальные книги, которые вы долго откладывали.
♋️ Рак
Откажитесь от лишней эмоциональности, она может помешать вашему развитию. Подтяните DevOps, в этом году он вам пригодится. Сложные задачи ждут вас в середине лета, но они дадут нужный стимул для дальнейшего роста.
♌️ Лев
В этом году удача не на вашей стороне, придётся много работать. Хотите успеха — начните сейчас, чтобы уже весной видеть первые результаты. Смотрите на вещи шире. Почитайте книжки по архитектуре, посмотрите видео с конференций HighLoad и ArchDays. В апреле высокий риск простудиться, одевайтесь теплее.
♍️ Дева
Год будет богат на свежие идеи и начинания. Начните то, что давно откладывали. Интересные идеи, вопросы и решения придут в самый неожиданный момент. Сохраняйте их сразу - запишите в блокнот, голосовое сообщение, как угодно, а то улетят. Обязательно делайте бэкапы и резервные копии.
♎️ Весы
В этом году у Весов будет шанс попробовать себя в руководящей роли. Готовьтесь заранее - почитайте статьи по управлению людьми и проектами. Подтяните тайм-менеджмент, иначе времени на хобби и внерабочие активности совсем не останется.
♏️ Скорпион
В этом году вы будете на переднем фронте. Вас ждут горячие фиксы и спасение команды перед дедлайном. Будет сложно, но Сатурн вам поможет. Помните об отдыхе и набирайтесь сил в спокойное время.
♐️ Стрелец
Пересмотрите приоритеты в жизни, попробуйте смежные IT направления. Возможно позиция тимлида, менеджера или аналитика раскроют вас с новой стороны. В этом году особую важность приобретут межличностные отношения. Октябрь станет самым прибыльным месяцем в году.
♑️ Козерог
Для вас 2021 год — это борьба со своими слабостями. Уделяйте больше внимания тестированию и самопроверке. Разберитесь с NoSQL: книга для начинающих, для продолжающих. Хорошей идеей будет сходить на каток и покататься на ватрушках.
♒️ Водолей
Лучшее время для решительных шагов — начало весны. Много возможностей принесёт нетворкинг - поддерживайте тёплые отношения с коллегами, участвуйте в конференциях, митапах и корпоративных мероприятиях. Идите в ногу со временем - освойте Kotlin и Cloud computing.
♓️ Рыбы
Наступает период, когда пора применить все накопленные знания. А возможности для этого обязательно будут. Меркурий помешает сделать важные задачи в срок, поэтому закладывайте на выполнение в 2 раза больше времени. Лето подкинет массу интересных вариантов для отдыха.
Дружите со звёздами, они плохого не посоветуют💫12 396
Спасибо за этот год!
Завтра новый год, это отличный повод сказать нечто важное.
Ребята, вы супер! Спасибо, что читаете мои нудные посты без картинок, помогаете найти ошибки и задаёте интересные вопросы. Благодаря вам блог ещё жив❤️
В 2020 году на канале вышло 85 постов, которые в сумме набрали 475к просмотров! Я в шоке и постараюсь в 2021 не сбавлять обороты.
Желаю всем в следующем году +1 грейд, интересные проекты и яркую жизнь вне работы🔥
12 396
Switch: успеть до 30-ти
Сегодняшняя тема - история успеха оператора switch. Он появился в java 1.0, и с тех пор оставался в неизменном виде. В 2018 разработчики JDK смахнули пыль с кодовой базы switch, и теперь над ним идёт активная работа.
Почему о нём вспомнили, и как меняется switch? Рассмотрим по порядку.
1️⃣ Часть 1. Эпоха ООП
Java работает с объектами уже 25 лет. В этих условиях switch редко встречается в коде и часто считается плохой практикой.
Почему? Всё дело в сценарии использования:
switch (user.getState()) {
case NEW: …
case CONFIRMED: …
case BANNED: … }
Switch - это не просто набор нескольких if. У объекта user 3 статуса. Список чётко определен, статусы не пересекаются между собой.
Почему switch так себе вариант?
❌Сложный код. Работа со всеми состояниями в одной куче.
❌Дублирование кода. Если поле проверяется несколько раз, то менять такой код неудобно и легко ошибиться.
Для объекта с понятным набором состояний switch лучше заменить на полиморфные методы. Это несложный рефакторинг - пример1, пример2.
Цель ООП - смоделировать реальный мир через объекты. Главное здесь - объекты взаимодействуют и меняют состояние друг друга. В таких условиях switch проигрывает полиморфным методам и редко используется.
2️⃣ Часть 2. Эра функциональности
Сегодня для бизнеса недостаточно простой автоматизации. Основной задачей становится работа с данными.
Они не меняются, приходят из разных источников в разных форматах. Потоки данных идут через множество сервисов. Каждый сервис берёт данные, которые понимает, а остальные игнорирует. Строить иерархии классов для такой задачи кажется лишним и сложным.
Поэтому внедряются подходы из фунциональных языков. Один из них - pattern matching, а switch идеально подходит для его реализации. Паттерн - некоторое условие для переменной:
▫️Равна заданной константе
▫️Имеет определённый тип
▫️Подходит под регулярное выражение
Если произошёл мэтч, то для переменной сразу доступна доп.информация. Например, она приводится к нужному типу:
switch (animal) {
case Cat c → c.putToBox();
case Dog d → d.train(); }
Итак, в чём разница между switch в 2000 и switch в 2021?
Switch 2000 работает с объектами, у которых меняется состояние. Вокруг этого строится бизнес-логика.
Switch 2021 работает с неизменными данными и помогает найти среди них подходящие. В следующем году выйдет java 17, и switch будет появляться в коде чаще.
Вот так один непопулярный оператор в JDK нашёл своё место в мире спустя 23 года⭐️