Тру-Джава
137 subscribers
31 photos
79 links
блог начинающего Java-программиста

Чат: https://t.me/trujavachat
Download Telegram
Всем привет!

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

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

В процессе он показал мне суперкласс при составлении спецификации (Specification) для динамического поиска в базе данных. Такое я ни за что бы не написала без гугла, а он сориентировался очень быстро, со словами: "хм, как интересно они придумали".

Я только после созвона разобрала со скрина, что делает код, но до сих пор не совсем осознала, как это вкупе с другим работает)

Ещё 2 месяца назад не знала, что можно искать в базе данных парами в условии, например, так:

Select u.* from users u where (u.name, u.email) in (("name", "email" ), ("name2", "email2"));

Это убирает ненастоящие совпадения и оптимизирует запрос, в сравнении, например, со сгенерированным запросом по названию метода, который мог бы называться по этому примеру как-нибудь в стиле findAllByNameInAndEmailIn. Запрос во втором случае выглядел бы примерно так:

Select u.* from users u where u.name in :names and u.email in :emails;

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

Потом он ещё меня озадачил на рефакторинг моего подхода в более общем плане, сегодня просидела над этим до 9 вечера, только уже домашние напомнили, что вообще-то уже пора отдыхать) Очень хочется эту задачу поскорее закрыть))
🔥10👍6❤‍🔥1👏1
Всем привет!

С последнего поста сделала несколько интересных экспериментов - развернула локально ИИ, обращалась к нему по API и развернула небольшой пет-проект в кубернетес.

Про локальный ИИ ещё увидела на одной конференции месяц назад, спикера тогда немного подвел заряд ноутбука, но в целом идея понятна. (Кстати, следующий после этого доклад про ИИ был просто огонь.)

Кубернетес разворачивала локально с помощью Minikube, если интересно здесь есть файлы с прописанными настройками для базы данных и приложения. Единственное, не написала пока Readme с командами для запуска. Это в моем todo листе))

Планирую потом, в рамках бесплатного пользования на какой-то ограниченный срок, попробовать развернуть приложение в настоящем kubernetes кластере через яндекс cloud. Как-то попалось, что там есть такая возможность.

А завтра я, внезапно, собираюсь на оффлайн конференцию для питонистов. Потом поделюсь впечатлениями👩‍💻
🔥12
Всем привет!

Сегодня была на Pytup конференции. Очень понравилось, была классная атмосфера, общение с интересными людьми.

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

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

Трансляция в общем доступе по ссылке, хоть и не совсем на тему джавы, но доклад на тему CI/CD мне показался очень полезным, и также доклад с практической частью и подключением к яндекс cloud тоже понравился, планирую воспроизвести на джаве что-нибудь похожее.

P. S. На трансляции я даже иногда попадала в кадр, но фото с конференции обещают через неделю 😊
🔥9👍2🎉1
Всем привет!

На днях наткнулась на интересное решение и хочу им поделиться.

Например, мы имеем список объектов, условно счетов (InvoiceDto), собранных из разных таблиц базы данных.

Поэтому это Дто имеет у нас 15 полей - наименование, номер счета, дату выставления, дату оплаты, сумму и т.п.

Мы этот список счетов хотим выгрузить в Excel, но особенность в том, что фронт-енд нам присылает названия колонок, которые пользователь выбрал и хочет выгрузить. Ему нужны может 3 поля из дто, а не все 15.

Проблема:

В каждой колонке свои данные, как узнать, какие колонки к нам пришли и какое значение нужно заполнить?

Первая моя мысль: switch case. Типа, идем по колонкам и смотрим, если это наименование - записываем invoice.getName, если сумма - записываем invoice.getAmount, и так 15 кейсов.

Минусы: решение громоздкое, плохо поддерживаемое, напрашивается на баги, плюс многие чекстайл проверки даже не пропустят больше 7 кейсов в одном switch.

Вторая мысль: написать интерфейс с одним методом и как-то определить в зависимости от колонки нужное действие.

Такого типа решение я и нашла: написать мапу, ключом которой будет название колонки, а значением функциональный интерфейс Function, принимающий один объект и возвращающий другой.

Map<String, Function<InvoiceDto, Object>> map = new HashMap<>();

Заполняется:

map.put("nameColumn", InvoiceDto::getName());

В коде это выглядит примерно так:

for (String column : columns) {

Function<InvoiceDto, Object> function = map.get(column)

if (function != null) {

Object value = function.apply(dto);
//далее записываем в ячейки и т.д.

Таким образом, мы избавляемся от проверок, какая колонка к нам пришла и сразу записываем именно то поле, которое требуется.
👍9🔥5
Всем привет!

Не прошло и 2 месяца (позавчера прошло), как я, наконец, прошла видео-курс по Кубернетесу, который длился целых 3 часа 36 минут. 😁

На степике курс тоже почти прошла (осталась одна тема), он в плане объяснения теории очень слабый. Скорее ходила туда закрепить тему с отрывка видео. Отдельно его будет мало, мне кажется. Ссылки на эти курсы оставляла ранее.

Теперь можно смело сказать, что я знаю некоторые определения что есть что в кубернетес и некоторые команды, скрипты настроек. Думаю, как закончу курс со степика, не буду глубже погружаться в K8s пока.

В процессе изучения / чтения у меня сейчас идет книга с паттернами и "кабанчик" ( Kleppmann "Designing Data-Intensive Applications"), его начала читать, чтобы потом просмотреть серию выпусков на ютюбе "Читаем кабанчика".

С моей скоростью просмотра видео, я вряд ли успею просмотреть к 18 июня предыдущие обсуждения (18 июня будет обсуждение 7 главы), но может к июлю что-то и изменится :)
🔥7😁3
Всем привет!

Недавно видела пост про различие между мидлом и сеньором, джуном и мидлом. Мне очень понравились мысли автора.

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

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

А причина в том, что инструменты осваиваются быстрее, чем растет уверенность, самостоятельность, качество кода и умение справляться с неопределённостью в задачах.

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

Вспомнила, что хотела недавно пройти курс на сеньора, там было в программе за пару месяцев осваиваешь Kubernetes, CI/CD и что-то ещё и вот ты сеньор. Но на самом деле, не все так просто)

На самом деле, и чтобы стать мидлом нужно сначала пару лет поработать, учась у старших коллег.
🔥10💯32
Всем привет!

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

Одними из таких видео, меня ждет курс по Котлин на Степике. Возможно он был у меня в рекомендованных, от этого автора я проходила в том году курс для джавистов - "подготовка к собеседованиям".

Его объяснения у меня хорошо откладываются и курс по котлину тоже шёл бодро, но с мобильным интернетом приходится временно его поставить на паузу.

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

Во вторник у нас на проекте будет переход на джаву 21 и последнюю версию Spring Boot. Это хотели сделать ещё весной, но по разным обстоятельствам, пришлось отложить.

У нас в пятницу была презентация по этому поводу, обсуждали виртуальные потоки и разные фишки, относящиеся к синтаксическому сахару, 21 джавы. В общем, очень жду, а то у нас пока ещё 11 версия.
🔥10👍2
Всем привет!

Мы на проекте успешно перешли на 21 джаву. Правда день перехода вызывал нервный смех над количеством отвалившегося функционала😅

Но всё достаточно быстро починили, правда заметили, что Hibernate 6 версии по-другому генерирует запросы и разные тяжелые запросы стали работать ещё медленнее.

Пример поинтереснее потом поищу, но пока могу сказать, что многие запросы перестали работать, падая с разными ошибками синтаксиса.

Например, раньше byte[] отлично получался из селекта без указания аннотации @Lob над полем, но теперь эту аннотацию надо обязательно указывать. Также, до этого работавший запрос с LISTAGG функцией, стал падать с ошибкой синтаксиса.

Этой проблемой занимаются более старшие, а я в пятницу делала динамический импорт из файла, в котором порядок колонок и их количество может отличаться. Применила похожую вещь из этого поста, только плюсом ещё использовала мапу с заголовками по индексу.

Поэтому идя по ячейкам, смотрела по индексу что за заголовок и по заголовку-ключу получала действие - присвоение нужному полю значения.

Это решение я ещё не успела отправить на проверку, но думаю, что оно будет одобрено, потому что кажется достаточно гибким, if I do say so myself, как говорится 🤭
🔥8👍3
Всем привет!

Позавчера была борьба с забавным багом, такой эпик фейл с моей стороны. Пришлось мне работать с сущностью, у которой было поле-объект, помеченное @EmbeddedId, а у самого этого поля-объекта была аннотация @Embeddable.

Я до этого знала, что @Embeddable в принципе означает вложенный и, что все перечисленные поля вложенного класса, будут в виде этого класса присутствовать в классе верхнего уровня.

Что я не до конца понимала — это почему использовался именно @EmbeddedId, а не просто @Embedded, и по лени не перепроверив, решила, что это примерно одно и то же, а значит я спокойно могу добавить два нужных мне поля из таблицы во вложенный класс и по данным из этого вложенного класса найти потом запись в таблице.

В общем, ждал меня сюрприз. В базе данных запись я видела, но при дебаге с теми же данными запись в таблице мне не выдавалась. Что я только не перепробовала, и меняла запросы со сгенерированного, на кастомный на JHQL, потом на native SQL. Игралась с equals и hashCode. Через пару часов спросила у одного из старших коллег, он говорит, может ты не в той базе смотришь, на другом стенде? Но нет, база данных была та же. Профиль спринга был нужный.

Еще через полчаса-час я начала, наконец, читать подробнее про @EmbeddedId и параллельно спросила самого нашего гениального разработчика. Он сначала подумал, что у меня кривой запрос, созвонились, проверили, запрос не кривой и в принципе по нему в консоли я находила запись со входными данными.

Потом он попросил показать тот @Embeddable класс и увидел, что я туда добавила два поля. В этом, говорит, и была моя ошибка. Так я узнала, что @EmbeddedId означает составной первичный ключ в таблице и нельзя просто так бездумно добавлять дополнительные колонки к этому ключу.

Вот такой вот эпик фейл, но на ошибках учимся)))
🔥7👍6
Всем привет!

Вчера у меня начался отпуск. 🥳 Много нацелилась успеть сделать, но без жестких требований к себе, все-таки нужно и отдыхать))

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

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

Я думаю, что не пройду и первый этап с решением задач за ограниченное время, но собираюсь попробовать.

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

Котлин пока откладываю в дальний ящик, до востребования. После перехода на 21 джаву на проекте, синтаксис котлина так не привлекает, потому что многие интересные конструкции теперь доступны и в джаве.

Но появился интерес к питону, решила с ним познакомиться поближе. В первую мою попытку лет ~10 назад, он меня очень быстро победил. Хочется взять реванш, плюс многие алгоритмы объясняют с псевдокодом, либо на питон, и возможно более хорошее понимание питона мне поможет и с алгоритмами.
🔥7👍6
Всем привет!)

Продолжаю подтягивать алгоритмы и готовлюсь потихоньку к решению задач на время (диагностика из предыдущего поста).

Сначала даже чуть было не записалась на курсы по алгоритмам за >80 тыс 😱 Но меня вовремя отговорили)) Поэтому пошла на степик и нашла там java - тренажёр. Там от совсем простых задач начинается, думаю раз уж повторять надо с самого начала))

Ещё ездили тут в Москву на выходных и в поезде слушала Clean Code, так сказать, познакомиться с классикой)

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

Ещё продолжаю читать про паттерны, уже с января никак не дочитаю книгу Head First, последний паттерн, про который читала дался особенно тяжело - паттерн Команда/Command. Сложность для меня понять отличие от Стратегии и применение на практике. Думаю ещё поизучаю эти моменты)
🔥7👍2
Всем привет!

С понедельника участвую в небольшом челлендже 💪 на несколько человек. У меня две цели на месяц - дочитать "Чистый код" и по максимуму дорешать тренажёр из предыдущего поста.

Тренажер нравится, там есть задачки на 2 / 3 звезды и над ними приходится подумать. Одну так решила, зная, что неправильно, но после решения открывается доступ к решениям остальных студентов и увидела, как правильно сделать)

Потом попробовала повторить по памяти и всяко-разно потренироваться, понравилось) Там часто в решениях методы используют нестандартные, пометила себе несколько таких, чтобы знать)
🔥10
Всем привет!

Я продолжаю участие в челлендже, осталось 2 недели. Заодно решила побить свой рекорд непрерывной серии решения задач на степике. Там рекорд у меня 20 дней, сейчас пока 13, но проблема в том, что я дошла до более сложных задач, поэтому не знаю получится или нет.

По этому поводу в пятницу получилось довольно забавно. Часов в 8 вечера думаю, что-то я сегодня устала, дай-ка решу одну задачку, чисто для непрерывной серии. А задача под 2мя звездами на списки / массивы. В общем решала ее 3 часа, но все-таки решила)) Причем процент решения у нее был высокий и ни одной подсказки / вопроса в комментариях.

Но это не самый смешной случай с задачами, поэтому расскажу про другую задачу.

Решаю вчера задачи, и попалась мне задача — дан список с числами, расположенными по возрастанию, например [1, 2, 3] и нужно отдать на выходе сумму пропущенных чисел, в данном случае 2 и 4, т. е. вернуть 6. Осложнялась она тем, что на вход приходили числа класса Number и их сначала нужно было перевести в Integer.

Не то чтобы я долго над ней сидела, но мое решение, с ошибочно-ненужными 2мя условиями заняло 22 строки (со всем форматом и скобками), захожу в решения других людей. И что я вижу! Эта задача, оказывается, решается в 2 строки, чисто с математической стороны. 😁 Да еще и стримами) Там, конечно, гении стримов сидят, почти все задачи кто-нибудь решает используя только стримы.

Но еще активно пользуются методами из стандартной библиотеки. Например, я до этого не знала про метод Collections.reverse() — развернуть порядок списка на обратный, и про метод set() в интерфейсе List, он заменяет по индексу элемент на другой. Я делала это в несколько операций, сначала удалить старое значение по индексу из копии листа (чтобы не было ConcurrentModificationException), а потом добавить новое значение по индексу. А есть специальный метод🙈
🔥5👍41
Всем привет!

Продолжаю активно прокачивать алгоритмы. В задачнике дошла до 47%. Осталось несколько задач до 3х-звездных на списки. Лучшую свою серию на степике не улучшила, может быть как-нибудь в другой раз:)

Дочитала «Чистый код», книжка очень понравилась. Открыла для себя новый способ чтения — читать под аудиокнигу. Следующая моя цель на прочтение — «Гроккаем алгоритмы», нашла последнее издание от 2024 года, купила ее еще в варианте аудиокниги и начала читать.

На работе практически закончили переход на Domain Driven Design, перевели все микросервисы. Теперь у меня задача написать архюнит тест проверку, на то, чтобы этот дизайн не нарушался. Короткое видео о том, что такое DDD в общих чертах тут. Если кто-то еще не работал с архюнитами, то вот статьи с примерами на baeldung и хабре.
🔥81👏1
Всем привет!

Сегодня напишу про patch, о котором нам рассказывали ещё в Практикуме, но я никогда не пользовалась им до пары недель назад. Оказалось, что это очень удобная вещь.

У меня была ситуация, что не получалось сгенерировать правильный для меня объект через open api генератор. Я обратилась к техлиду, он сказал, что попробует и вернется.

Через какое-то время, он показал, как сделал и я попросила его прислать мне его вариант. Так, он научил меня использовать патч. Он создал его в идее и отправил мне в мессенджере, я выбрала в меню apply patch и у меня применились все изменения, которые я сразу закоммитила и отправила.

После этого, стала использовать этот способ в качестве быстрого бэкапа, потому что в merge реквесты обычно отправляю 1 коммит.

И эта привычка не коммитить и не работать в отдельной ветке сразу меня в пятницу чуть жестко не наказала😅 У меня была относительно большая задача на рефакторинг, я его делала дня два, у меня было 87 изменений и перед отправкой, я как обычно нажала обновить dev, чтобы из последней версии создать ветку, закоммитить и отправить.

Но обновления не подтянулись. Конфликт в измененном файле🙈 Мне вышло сообщение, что все мои изменения были положены на полку (shelve). Про нее я только знала, что один из преподавателей на стажировке потерял один раз все свои изменения, положив на полку свои изменения и как-то неправильно их пытаясь достать, удалил.

Седея по волосу в секунду, я открыла этот shelve, сначала выбрала silently unshelve, ничего не произошло)) В итоге выделила и нажала unshelve, мысленно формулируя, как я на дейлике в понедельник буду рассказывать, что все свои изменения эпично удалила.

Но всё досталось с полки успешно, закоммитила, отправила на проверку и потом несколько раз проверила, точно ли всё досталось правильно) несколько раз прогнав всевозможные тесты) Даже сегодня утром потратила часа полтора всё перепроверяя))

А здесь есть ещё классная статья про фишки идеи, здесь есть и про shelve и patch.
👍15🔥42👏1😁1
Всем привет!

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

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

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

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

Настолько я соскучилась по активному движению тасок, что даже в прошлые выходные заводила себе в пет-проекте issue и закрывала их пулл-реквестами) Подправила свои github actions, подключила еще одну ИИ проверку, которая ищет различные уязвимости.

Так, у меня не пропустился последний мой ПР, нашлась уязвимость в html (игралась с фронтом через thymeleaf и ИИ). Но возвращение html также и мои постман тесты поломало, поэтому, наверное, попробую пощупать другие инструменты для фронта, если не получится с html.

А в эти выходные делала игру - кликер в unity 🙈 Ребенок ждет обещанной игры уже 3й год 😁
🔥132😁2
Всем привет!

Вчера читала один дайджест с последними новостями в мире IT и интересными новыми статьями по Java.

Привлекло название одной статьи - Паттерны применения многопоточности на коммерческом проекте. Решила тоже ссылку на нее здесь оставить, потому что очень крутая статья)

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

У меня сохранено с десяток задач с разных отборов на стажировку в Яндекс и Тинькофф, в которых я участвовала года полтора-два назад. Собираюсь вернуться к ним и решить, как закончу книжку, потому что тогда у меня не было даже идей как их решать.
🔥12👍2
Всем привет!

Вчера дочитала "Гроккаем алгоритмы", появилось понимание некоторых алгоритмов и появилось понимание, что нужно ещё много много тренировок))

Поэтому на днях было несколько решений, во-первых, заменить прохождение задачника на решение задач на leetcode. Потому что 3х звездные задачи оказались скорее муторные на выведение ответа в определенном формате, чем сложные и хитрые на логику. В общем, проще говоря пока стало скучно их решать, где-то на 60 с небольшим процентах решила пока остановиться. Возможно потом вернусь, чтобы добить.

Во-вторых, записалась на очередной поток тренировок по алгоритмам в Яндексе. Набор всё ещё открыт, начало 24 октября.

Следующую книжку выбрала "Java Concurrency and Parallelism" (Jay Wang), издание тоже 24 года. Буду углубляться в тему многопоточности. В первой же главе написано, что есть разница между выполнением задач параллельно и в режиме многопоточности. Буду узнавать какая🤓

Пока идея с чтением книг последовательно для меня работает, а то перескакивание с книги на книгу часто отбивало желание читать вообще)) Ещё достаточно весело читать одновременно с аудиокнигой, но книги, где много кода, конечно, не очень подходят для аудиокниг, даже удивительно, что была версия аудиокниги для алгоритмов, в конце концов стало неудобно ее слушать и постоянно ставить на паузу, чтобы разобраться в коде и схемах, в итоге перестала)
👍8🔥4
Всем привет!

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

Ощущение как будто читаешь какую-то рекламную брошюру по джаве😅 К концу первой главы, фразы в стиле, "но ничего, джава и об этом позаботилась" начали вызывать отторжение))) Это всё ещё совмещается с примерами танцев и получается, что "потоки движутся в ритме танго/вальса на переполненном облачном танцполе".

В итоге глаза стали стараться пропустить такие сравнения и "рекламу" джавы и осталось не так много и читать, только примеры кода. Так что, наверное, лучше посмотрю примеры кода в приложенном к книге проекте на гитхабе и переключусь на что-то другое. Может дальше стиль написания и меняется, но пока не зашёл совсем)
😁8🔥1
Всем привет!

С прошлой недели меня поставили помогать разгрузить техлида и одного сеньора и теперь я gateway по багам. Приходится разбираться, где проблема на бэке или фронте (иногда это не очевидно для меня) и переназначать, или брать в работу.

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

А из таких задач у меня были задачи на добавление второго профиля в микросервисы, как подготовка к миграции на другую базу данных. Один микросервис только успела перевести) Но надо сказать, что это достаточно монотонное дело. В этом плане поиск и исправление багов поинтереснее, но есть какое-то напряжение с ними)
🔥16👍3