JavaWhiteBook
77 subscribers
135 photos
1 video
70 links
Привет!
Меня зовут Алексей. Мне 49.
Я второй год работаю java-разработчиком.
В этом канале я рассказываю про трудности-печали, с которыми сталкиваюсь, а также радости-победы, которые случаются.
Только практика, никакой теории, и очень простыми словами.
Download Telegram
🎆 Открыл для себя GitHub Gist

И так для тех кто не знает
gist [ʤɪst] сущ
1️⃣ суть ж, сущность ж, смысл м
essence,meaning
2️⃣ суть того
3️⃣ ГГИП м (что это??? 🤯 )
4️⃣ истинный смысл
true meaning

В ключе GitHub'а - это такая его фича, которая позволяет хранить кусочки кода совершенно отдельно, не привязанными ни к чему и даже не рабочими.
Т.е. если грубо блокнот с набросками кода. Кроме того они могут быть доступными для всех и приватными. И на них можно ссылаться. 🤓

Что это такое я знаю в принципе давно, но никогда особо этим не пользовался. Знаю что гисты можно создавать непосредственно из идеи - стандартная фича, но достаточно бессмысленная (как мне казалось, пока я не понял как это можно использовать тут же в идее). 😅

Последнее время при решении задачек и эвента приходится писать маленькие кусочки одинакового кода. Это происходит достаточно часто и занимает определенное время, так вот мне очень захотелось освободить это время. 🧐

Для использования я установил плагин Gist Snippet 👍
И получил в меню - Insert Gist, при нажатии на который влазить окно со всеми моими гистами.
Если все хорошо описать то достаточно простой и быстрый поиск.

Список моих гистов стал резко увеличиваться 😇

А вы пользуетесь GitHub Gist?

#github
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Прошло чуть больше половины эдвента
Пока хорошо - нет совсем не решенных задач. 🤘

Но есть сложные.
В трех задачах не решены вторые части (серые звезды). 😦

В двух из-за недостатка времени или кривых ручек.
Кривые ручки нескольких первых задачах стоили мне достаточно много нервов и времени.
Помогало только одно - сносить все решение и писать заново.
И потом, уже сравнивая варианты, сразу были видны ошибки. 🤦‍♂️

А одна на комбинаторику.
Посчитать перестановки в лоб с небольшой оптимизацией получилось, при увеличении количества точек для перестановок в 5 раз все работает очень долго. 😡

Очень надеюсь что в этот раз получится дойти до конца 😈
Please open Telegram to view this post
VIEW IN TELEGRAM
🎓 Развитие

Получил сертификат о прохождении тренинга. 🏆

В этот раз без приключений. 😜

Общаясь с некоторыми ребятами из чата тренинга, понял что обязательно надо пройти все круги ада и посмотреть+порешать первые две тренировки.
Видимо это пойдет в план обучения на следующий год. 😇

А сейчас по все свободное время занимает эдвент 🎭👿🤦‍♂️
Please open Telegram to view this post
VIEW IN TELEGRAM
Из последних сил пытаюсь помогать эльфам. ⭐️

Чем дальше тем веселее и сложнее.
Бог с ним что формулировки задач становится жутко длинными.
Парсинг входных данных превращается в простыню.
Так это все еще и не работает при решениях в лоб. 👿😈

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

Речь об "шнуровке Гауса".
Алгоритм позволяет найти площадь выпуклого многоугольника зная только координаты его вершин.
Я не буду рассказывать как это работает, но тем кто не знает настоятельно рекомендую посмотреть это замечательное видео, в котором, с моей точки зрения, все объясняется предельно просто и с картинками.

Простой код реализации (не судите строго) приведу в комментах. 😇

А вам когда нибудь приходилось шнуровать по Гаусу в реальной жизни⁉️

🚩🚩
Кроме этого на том же канале есть еще пара замечательных видео:
Красивые теоремы с необычными названиями
Почему геометрия — это красиво?
Please open Telegram to view this post
VIEW IN TELEGRAM
🎓 Развитие

Ранее в сериале


На контроле знаний есть такой вопрос:
Перечислите побитовые логические операции, которые Вы знаете? Расскажите, как они работают.
Было приятно осознать, что я уже это значительно лучше понимаю и более осознано использую.
И так кратенько и смаленькими примерчиками
(в примерах r=a<операция>b):

🔸 Побитовое И (&)
Используется для выключения битов.
Любой бит, установленный в 0, вызывает установку соответствующего бита результата также в 0.
&
a: 11001010
b: 11100010
r: 11000010


🔸 Побитовое ИЛИ (|)
Используется для включения битов.
Любой бит, установленный в 1, вызывает установку соответствующего бита результата также в 1
|
a: 11001010
b: 11100010
r: 11101010


🔸 Побитовое НЕ (~)
Инвертирует состояние каждого бита исходной переменной.
~ (r = ~a)
a: 11001010
r: 00110101

🔸 Побитовое исключающее ИЛИ (^)
Устанавливает значение бита результата в 1, если значения в соответствующих битах исходных переменных различны.
^
a: 11001010
b: 11100010
r: 00101000


А еще есть
Побитовые сдвиги!!!

🔹 Операторы сдвига << и >>
Сдвигают биты в переменной влево или вправо на указанное число.

⚠️ При этом на освободившиеся позиции устанавливаются нули (кроме сдвига вправо отрицательного числа, в этом случае на свободные позиции устанавливаются единицы, так как числа представляются в двоичном дополнительном коде и необходимо поддерживать знаковый бит).

Сдвиг влево может применяться для умножения числа на два, сдвиг вправо — для деления.
x = 7         // 00000111 (7)
x = x >> 1 // 00000011 (3)
x = x << 1 // 00000110 (6)
x = x << 5 // 11000000 (-64)
x = x >> 2 // 11110000 (-16)


В JAVA еще еще есть беззнаковый сдвиг вправо.
Обозначается >>>. В отличии от предыдущих, а освободившиеся позиции всегда устанавливаются нули.
Ни разу им не пользовался. Если кто может привести пример для чего он его использует - буду очень признателен.
Please open Telegram to view this post
VIEW IN TELEGRAM
🎓 Развитие

Опять про битики

Сравнивая свои решения на литкоде с другими, я натолкнулся на один класс, про который хочу рассказать.

⭐️ Класс BitSet
представляет собой класс, который реализует динамический битовый массив.
Он предоставляет методы для работы с отдельными битами и выполнения различных операций над множествами битов.

1️⃣ Принцип работы:
🔸 BitSet внутренне представляет собой массив отдельных битов.
🔸 Каждый бит в BitSet может иметь два значения: 0 или 1.
🔸 По умолчанию, все биты инициализированы значением 0.
🔸 При изменении состояния бита, BitSet автоматически расширяет свой размер, чтобы вместить новые биты.

2️⃣ Основные методы:
🔸 void set(int index)
Устанавливает значение бита с указанным индексом равным 1.
🔸 void clear(int index)
Устанавливает значение бита с указанным индексом равным 0.
🔸 boolean get(int index)
Возвращает значение бита с указанным индексом.
🔸 int length()
Возвращает количество битов в BitSet.
🔸 void and(BitSet set)
Выполняет побитовое "И" (and) с другим BitSet.
🔸 void or(BitSet set)
Выполняет побитовое "ИЛИ" (or) с другим BitSet.
🔸 void xor(BitSet set)
Выполняет побитовое "исключающее ИЛИ" (xor) с другим BitSet.
🔸 void flip(int index)
Инвертирует значение бита с указанным индексом.

3️⃣ Где можно использовать:
🔸 Работа с большими объемами данных, где каждый бит отражает состояние или наличие конкретного элемента.
🔸 Кодирование и декодирование информации.
🔸 Реализация фильтра Блума для быстрого поиска элементов в больших множествах данных (даже не спрашивайте от куда я это знаю).

Решая задачки от Яндекса в одном месте городил что-то подобное самостоятельно - задача была "разрезать" множество на две части.

Надеюсь, это было полезно и когда нибудь пригодится!
А Вы знали и использовали BitSet?
Please open Telegram to view this post
VIEW IN TELEGRAM
🛠 Трудовые будни

TESTCONTAINERS ⭐️⭐️⭐️⭐️⭐️

Недавно сделал шаг в омут интеграционных тестов.
В текущем проекте используется голое JDBC и мне подсознательно казалось что в апдейтах данных есть "что-то не то". От этого чувства в бизнес части помогли избавится юнит-тесты и TDD, потому что при "нестабильном" ТЗ посчитал это оптимальным путем.

Так вот, было желание протестировать репозиторий.
И т.к. время и возможность позволяли решил изучить testcontainers.
Посмотрев несколько видео сложилось впечатление что из подключение и использование это реально не сложно.
Есть официальный сайт - на нем тоже есть много полезного для тех кто умеет читать.

Сначала попробовал на "котиках" - на одном из своих пет-проектов. Все завелось и протестировалось. ☺️

Но на рабочем возникли сложности.
При тестах поднималось все приложение, а значит пришлось настраивать все что есть тестовыми пропертями. Плюс ко всему запуск просто происходил достаточно долго.
Тесты конечно заработали, но зачем запускать все приложение если надо протестировать только репозиторий, вопрос оставался открытым. 🧐

Нашел способ указывать загружать и настраивать в контекст только то что нужно, и тесты побежали значительно быстрее.
@SpringBootTest(classes = {
MyHistoryRepositoryImpl.class,
})
@ImportAutoConfiguration(classes = {
MyPersistenceConfiguration.class
})

В итоге после 2х дней "мучений" тест-контейнерс больше мне не страшен. 🥂

P.S: Самое веселое, что в итоге я нашел в нашей модульной библиотеке готовую аннотацию.
Т.е. в моем случае было достаточно добавить только ее, что бы подключить все что нужно. 💥

А вы используете testcontainers в своих тестах⁉️
Please open Telegram to view this post
VIEW IN TELEGRAM
🎓 Развитие

JUnit 5

Сегодня наконец-то появилось время для себя, точнее "для поучиться". 🧑‍💻

Начал смотреть небольшой курс по тестированию. 👩‍💻

Из плюсов - видосики короткие и очень понятные. 👍
Так же есть на чем сразу пробовать - на работе сейчас тема тестирования становится очень актуальной. 🔥

Посмотрел пока не много, но как обычно сделал заметки в книжечке.

А как у вас с тестами ⁉️
Please open Telegram to view this post
VIEW IN TELEGRAM
💥 ВНЕЗАПНО

Сегодня внезапно узнал что у дяди Яши начались тренировки.
Записался. 🆒

Если кому интересно присоединяйтесь!‼️
Please open Telegram to view this post
VIEW IN TELEGRAM
🛠 Трудовые будни

В одном из последних ревью (задача по рефакторингу) было предложено использовать аннотацию @UtilityClass

До этого я ни разу ее не использовал. 😇

Для начала я решил проверить, а правильно ли я понимаю понятие утилитный класс.

🔸Утилитный класс
- класс-помощник, содержащий статические переменные и статические методы, которые выполняют определенный перечень задач, объединённых одним смыслом.

В Java нет встроенной поддержки для создания утилитных классов напрямую. Поэтому используют @UtilityClass в Lombok.

Пошел к известной нейросетке и спросил о плюсах-минусах.

Плюсы использования @UtilityClass в Lombok (кратко):
1. Меньше шаблонного кода
2. Неявный private конструктор
3. Предотвращение наследования
4. Повышение читаемости

Минусы использования @UtilityClass (кратко):
1. Зависимость от Lombok
2. Необходимость плагина
3. Понимание магии Lombok
4. Ограничения при сериализации
5. Ограниченная поддержка в инструментарии рефакторинга

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

A вы используете утилитные классы ⁉️
В каких случаях и для чего ⁉️
Please open Telegram to view this post
VIEW IN TELEGRAM
🎓 Развитие

Завершился очередной тренинг по алгоритмам.
Прислали сертификат.

Типа ура!

И вот в тот единственный раз, когда решил не все задачи, эти собаки сутулые решили написать количество решенных задач.
28/40 - в целом тоже не плохо, надо будет все таки дорешать, потому что последние задачи были самые интересные.
🎓 Транзакции

Вчера повторял про транзакции в БД.

Тезисно, что бы закрепить

Аномалии:
🔸 Потерянное обновление
🔸 Грязное чтение
🔸 Неповторяющееся чтение
🔸 Фантомное чтение

Свойства ACID:
🔸 Атомарность (atomicity)
🔸 Согласованность (consistency)
🔸 Изоляция (isolation)
🔸 Устойчивость (durability)

Уровни изоляции в SQL:
🔸 Read uncommitted (чтение незафиксированных данных).
🔸 Read committed (чтение фиксированных данных).
🔸 Repeatable read (повторяющееся чтение).
🔸 Serializable (упорядочиваемость).

⚠️ А еще надо не забывать что СУБД не обязательно поддерживает все эти уровни.

💥 Например, Postgres поддерживает только последние 3ри, а oracle и того меньше - Read committed и Serializable

А вы когда-нибудь наступали на грабли транзакционности ⁉️

#interview
Please open Telegram to view this post
VIEW IN TELEGRAM
🔈 А поговорить?!

Я очень люблю идею.
На данном этапе мой жизни это единственно ПО за которое не жалко денег.

Это очень мощный инструмент и что бы использовать его эффективно посмотрите видосик.

Пишите кто что новое узнал или что есть добавить...
Please open Telegram to view this post
VIEW IN TELEGRAM
🔈 А поговорить?!

И опять про идею.

Не знаю у кого, где и когда я это увидел, но очень хотел видеть прямо в среде разработки комменты которые оставляют ревьюверы на нашем GitLab 🥕🥕🥕

Оказалось что это предельно просто!!! 🤘
Есть плагин GitLab, в нем создаем соединение, указываем адрес репы, генерируем токен доступа и все!!! 🤦‍♂️

Теперь прямо в коде видно кто и что тебе прокомментировал, тут же можно ответить или зарезолвить проблему. 😇

И не надо лазить в почту, потом идти в репу и там смотреть, потом, если сложный вопрос опять возвращаться в IDE и смотреть код.... 🔥

Короче мне это очень понравилось❗️
А вы таким пользуетесь⁉️
Please open Telegram to view this post
VIEW IN TELEGRAM
🔈 А поговорить?!

И опять-опять про идею.

На работе закончилась лафа с лицензией - продлил свою.
Перерыв два года - никаких скидок нет.
Плюс небольшая комиссия за перевод, что минус.

Кто какими лицензиями пользуется и пользуется ли вообще?
Please open Telegram to view this post
VIEW IN TELEGRAM
🛠 Трудовые будни

Стояла задача в сервисе принимать команды, которые имеют разную структуру.
Т.е. в одном месте из json получить разные объекты

Я конечно сделал и оно конечно работает, но...
но на ревью меня завернули и отправили читать про полиморфный json 😮

Очень интересный зверь 🤓

Настраивается очень просто:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = AddCommand.class, name = "AddCommand"),
@JsonSubTypes.Type(value = DeleteCommand.class, name = "DeleteFortsLimitsCommand")
})
public interface Command {
EventType getType();
}

public abstract class BaseCommand implements Command {...}

public class AddCommand extends BaseCommand {...}


т.е. в полученном json ищем поле (в моем случае type) и по его значению выбираем класс в который будет произведена десереализация. 🔥

Почитать можно тут

А вы сталкивались с таким зверем ⁉️
Please open Telegram to view this post
VIEW IN TELEGRAM
🎓 CodeReview

На собесах иногда просят сделать код-ревью.

Набросал себе схему, как проводить это самое ревью.

1️⃣ Корректность работы
(т.е. что делаем, что ожидаем, проверяем, что закрыли ресурсы, и т.п.)

2️⃣ Обработка ошибок
(все ли обработаны и в нужном ли месте)

3️⃣ Алгоритмы и перфоманс
(можно ли сделать лучше)

4️⃣ Read-n-Code Quality
(кривые имена, дублирование кода, и т.д)

Ничего не забыл ⁉️

Если есть примеры кода, которые вам давали или вы давали на собесе, бросьте в коменты посмотреть

#interview
Please open Telegram to view this post
VIEW IN TELEGRAM