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

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

На этой неделе интересовалась Spring MVC, что это такое и чем отличается от Spring Boot. Во-первых, потому что часто встречала требование в вакансиях знать Spring MVC, а во-вторых, потому что узнала, что мы не будем подробно этим заниматься в Практикуме. Начала смотреть курс по нему на youtube, прочитала короткую статью об основных принципах на хабре. Почитала другие статьи на английском. Итак, что могу сказать пока после короткого знакомства со Spring MVC:

MVC – описывает паттерн Model (сущности), View (отображение/ фронт-энд) и Controller (контроллеры). То есть, на первый взгляд, всё как мы и делаем в наших приложениях на Spring Boot, за исключением того, что мы не делаем фронт-энд.

Когда стала смотреть курс на ютюбе, увидела, что view оказывается здесь играет ключевую роль. Например, когда мы пишем REST API в Spring Boot, мы можем вернуть созданный объект в теле ответа, либо просто статус ОК. Здесь же, каждый метод контроллера возвращает String – название html страницы, которую нужно отобразить пользователю. Для каждого эндпоинта, по которому мы будем создавать какой-либо объект, в mvc существует и GetMapping и PostMapping. То есть мы сначала получаем страницу, на которой будем что-то создавать, а потом только можем это создать.

Стала смотреть еще на разницу между Spring Boot и Spring MVC, оказалось что есть отличия и в настройках — в mvc нужно прописывать настройки (configuration) вручную, в boot этого не требуется. Есть еще отличия, связанные с тем, что я пока еще не делала (например, deployment – развертывание и запуск веб-приложения на сервере), поэтому пока не буду о них писать.

Также, в этом курсе подтвердили слова нашего наставника с вебинара, что действительно не делают 1 класс для одной сущности и перегружают ее всякими аннотациями. Например, один класс User для обозначения полей, какие у него будут, и связывания с базой данных. А другой класс, UserDto (dto - data transfer object, или объект передачи данных), где можно добавить аннотации по валидации или дополнительные поля, которые в связи с безопасностью не нужно раздавать при любом запросе. И иметь два маппера, один из которых будет собирать более общий объект userDto, а другой обычного юзера. Наставник также говорил, что может быть и третий класс, который будет дополнительно иметь какую-нибудь логику.
👍6🔥1
Всем привет!

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

Обсуждали ООП, HTTP, SOLID, алгоритмы и сложности, циклы разработки, монолит против микросервисной архитектуры, тесты, а также, рассказывала о проектах, которые писала (учебные и свой пет-проект).

Из забавного — забыла, что такое логарифм)) Когда «раскладывала» сложности по О-большое в порядке возрастания.

Вспомнила только два принципа SOLID, поэтому сейчас их здесь пропишу, чтобы лучше запомнить:

S – Single Responsibility – Принцип единственной ответственности. Каждый класс должен иметь только одну зону ответственности. Из жизни — курьер только доставляет, а не чинит нам технику.

O – Open / Closed — Принцип открытости-закрытости. Классы должны быть открыты для расширения, но закрыты для изменения. Например, хотим мы класс, отправляющий оповещения по электронной почте, научить отправлять оповещения по смс. Если мы изменим его метод sendNotification – это будет противоречить принципу закрытости для изменения. Как тогда лучше это сделать? Например, создать интерфейс с методом sendNotification, в этом случае класс, который будет оповещать по смс, просто переопределит этот метод, реализуя этот интерфейс. А класс, оповещающий по электронной почте, не потерял свой функционал.

L – Liskov Substitution — Принцип подстановки Барбары Лисков. Можно пояснить так, если класс A является подтипом класса B (наследуется от него), мы должны иметь возможность заменить B на A, не нарушая поведения нашей программы. Другими словами наследники должны уметь делать все то же, что и родители. Пример на машинах — есть класс Car, в котором прописаны методы завестись (turnOnEngine()) и ускориться (accelerate()). Подтип машин, электромашины. Он сможет также заводиться и ускоряться.

I – Interface Segregation — Принцип разделения интерфейсов. Большие интерфейсы должны быть разделены на более мелкие. Таким образом, классы будут реализовывать только те интерфейсы, которые имеют к ним отношение. Другими словами, нельзя заставлять класс переопределять все методы интерфейсов, которые они не используют.

D – Dependecy InversionПринцип инверсии зависимостей. Он относится к разделению программных модулей. Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те, и другие должны зависеть от абстракции. Звучит сложно, но по сути это классический полиморфизм, когда мы одинаково можем работать с классами, реализующими один интерфейс. То есть, вместо того, чтобы прописать конкретную реализацию (условный userServiceImpl), мы прописываем интерфейс, который этот класс реализует (userService).
🔥6👍1
Всем привет!

Небольшой пятничный апдейт. С понедельника у нас начался новый модуль, начали углубляться в то, как работает Spring Boot под капотом. Начали новый проект, в этом спринте в основном задание было сделать каркас-подготовку, в следующем спринте будем подключать базу данных с помощью JPA. Мне задание уже зачли, поэтому я пока буду отдыхать до открытия следующей теории, до среды.

Вчера порекомендовали одного преподавателя/ментора по Java, у него есть свой YouTube канал — dmdev. Заинтересовали его видео по сервлетам. После теории этого спринта, захотелось углубиться в эту тему, потому что представление о том, как они работают пока очень поверхностное. Возможно после этих видео, сделаю короткий пост о том, что это такое. Присмотрела, что у него есть и по docker и по spring видео, думаю начать смотреть его канал.

Также, думаю доделать подключение пользователей через Spring Security у себя в пет-проекте. Я пока security подробно не касалась, но зато пригодятся знания, полученные в результате работы над ТЗ. Теперь есть лучше представление, как организовать работу с DTO объектами и где хранить пароль юзера, хотя на счет пароля еще есть сомнения с точки зрения безопасности. Скорее всего изучение Spring Security подскажет точно как это нужно правильно сделать.
👍41🔥1
Всем привет!

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

Когда браузер отправляет HTTP запрос, этот запрос направляется в контейнер, который обычно называется web container (web application container полностью). Внутри этого контейнера есть один или несколько сервлетов, которые обрабатывают отправляемые ему HTTP-запросы. Запрос приходит в веб-контейнер, а затем перенаправляется одному из многих отдельных сервлетов.

Что такое сервлет? Это просто класс Java, который имеет специальные методы для обработки входящих HTTP-запросов, а ключевые методы сервлета — это doGet(), doPost(), и так далее, на каждый HTTP-метод.

Один из ключевых вопросов: если у нас есть несколько сервлетов, как нам решить, какой сервлет должен обрабатывать конкретный HTTP-запрос?

Внутри большинства веб-контейнеров есть то, что называется функцией маршрутизации или неким маршрутизатором, с помощью которого решается на основе поступающего запроса, какой сервлет должен его обработать. В Java способ обработки и маршрутизации сервлета определяется через файл web.xml. Это специальный файл, сообщающий веб-контейнеру о поступлении определенного запроса.

Допустим, у нас есть новый запрос для /bar, и это POST. С помощью файла web.xml, находится сервлет, к которому этот запрос должен перейти, а затем он направляется к соответствующему сервлету.

Так что этот файл — это по сути маршрутизация запросов. Веб-контейнер обеспечивает жизненный цикл и использует эту таблицу маршрутизации для определения какой сервлет должен получать запросы, а затем эти запросы обрабатываются отдельными сервлетами.
👍6
Всем привет!

Сегодня хочу рассказать о паре забавных случаев, связанных со Spring Security (один напрямую связан, второй не очень). В начале недели делала свой проект, разобралась, как хранить пароли пользователей в зашифрованном виде, начала настраивать SecurityConfig, чтобы это все дело протестировать. Даже сделала пару простеньких html страниц для отображения страниц регистрации и логина, для зарегистрированных пользователей.

Делала я по курсу Spring MVC Security, который был выложен 6 месяцев назад. Оказалось, что методы, которые там применялись для настройки SecurityConfig уже устарели. Попробовала сделать сама по неглубокому погружению в документацию — дошла до того, что мне стал запрещен доступ на localhost 😅

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

А второй забавный случай произошел вчера. Делала я учебный проект, немного зайдя вперед теории настроила связь таблиц по аннотации OneToMany. Запускаю проект — ошибка выходит “Unable to acquire JDBC Connection”, стала гуглить — никакие варианты не работали. Отложила теорию, пошла смотреть более новое видео по Spring Security, оно начинается с настройки связей ManyToMany по аннотации и тут я замечаю свою ошибку в учебном проекте. Надо указывать сначала в JoinColumn ссылку на класс, в котором есть поле, ссылающееся на другую сущность/таблицу, а потом уже указывать ссылку на второй класс. Поменяла в учебном проекте — запустила, вышла ошибка с наименованием колонки, поправила и все заработало. Так неожиданно, но интересно и забавно вышло.
🔥3😁2👍1
Всем привет!

Может кому-то скучно и будет интересно решить алгоритмическую задачку?)) Эта задачка со степика из курса "Алгоритмы", которую я решала на прошлой неделе.

"Официальное" задание:
По данным n отрезкам необходимо найти множество точек минимального размера, для которого каждый из отрезков содержит хотя бы одну из точек.

В первой строке дано число 1 ≤ n ≤ 100 отрезков. Каждая из последующих n строк содержит по два числа 0 ≤ l ≤ r ≤10 , задающих начало и конец отрезка. Выведите оптимальное число m точек и сами m точек. Если таких множеств точек несколько, выведите любое из них.

Пример ввода №1:

3
1 3
2 5
3 6

Вывод:

1
3

Пример ввода №2:

4
4 7
1 3
2 5
5 6

Вывод:

2
3 6

Перевод с учебного на русский: "есть несколько дощечек разной длины (это наши отрезки n). Нужно прибить их к полу так, чтобы если комната перевернулась они не попадали. Вот минимальное количество гвоздей в этой задаче и точки куда они прибиты и будет решением"

(позже в комментариях скину свое решение)
👍3👏21
Всем привет!

Захотелось рассказать про интересный инструмент, о котором узнала вчера. Мне пришло тестовое задание на отклик на вакансию. Задание было — «Добавить кнопку и текстовое поле на страницу. По нажатию на кнопку - значение в поле увеличивается на 1. Значение поля можно изменить руками, вписав нужное значение. Изменения должны сохранятся в БД автоматически при каждом изменении.» Одним из требований было сделать это используя Vaadin 24. Я с ним не была до этого знакома, пошла изучать и мне очень понравились его возможности.

Это такой фреймворк, на котором можно удобно создавать фронт на Java. Я стала с ним знакомиться по этой статье с spring.io, есть очень похожая статья на русском языке с хабра. Идеальная вещь для создания симпатичного внешнего вида для своих пет-проектов. Этим я с удовольствием скоро займусь, как закончу делать ТЗ этого спринта (вчера только начала).

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

Так что кому хочется симпатичного фронта для своего веб-приложения, но не хочется сильно углубляться в JavaScript, HTML, CSS и так далее, советую посмотреть в сторону Vaadin (прочитав про его минусы из последней ссылки).
🔥3👍2👏21
Всем привет!

На этой неделе плотно занималась учебным проектом. В этот раз к нашему проекту шеринга нужно было подключить базу данных через JPA и внести новые фичи. Нам дали ~700 тестов, на которых наш проект должен был успешно отработать. Из новых фич: добавили возможность бронировать вещи и оставлять комментарии после аренды.

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

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

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

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

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

Вчера пока ждала проверки, стала потихоньку возвращаться к своим вопросам по другим темам, начала смотреть курс по докеру, потом по кафке. Ещё вчера "разговорилась" с chat gpt часа на полтора, просила его сравнивать разные инструменты, применять их на примерах с кодом. Очень понравилось)
👏6🔥1
Всем привет!

Вчера целый день изучала Docker. Хочу сегодня здесь немного коротко структурировать основные понятия:

Что такое докер?

Docker – это программная платформа для быстрой разработки, тестирования и развертывания приложений. Docker упаковывает ПО в стандартизованные блоки, которые называются контейнерами.

Что такое Docker контейнер?

Это такой блок, который включает все необходимое для работы приложения: библиотеки, системные инструменты, код и среду исполнения.

Что такое Docker-образ? (на английском Docker Image)

Docker-образ — шаблон для создания Docker-контейнеров. Представляет собой исполняемый пакет, содержащий все необходимое для запуска приложения: код, среду выполнения, библиотеки, переменные окружения и файлы конфигурации.

Казалось бы, определения для контейнера и образа очень похожи. Чем же отличается докер контейнер от докер образа? Docker контейнер – это рабочая среда для образа. А докер-образ — это неизменяемый образ, из которого разворачивается контейнер.

Зачем нам может понадобиться Docker?

Когда разработка ведется разными людьми, на разных компьютерах, для того, чтобы запустить приложение, использующее, например, Java и PostgreSQL, нужно установить на каждый компьютер и java и postgresql. Когда мы хотим продемонстрировать работу нашего приложения, нам нужно установить java и postgresql на ту машину, на которой будет демо, либо привезти свой ноутбук. Если добавить удаленных тестировщиков, которые будут тестировать наше приложение, им также нужно будет установить и java и postgresql на их компьютерах. В зависимости от операционной системы на разных компьютерах, установка может отличаться, что может привести к сложностям.

Захотим мы протестировать наше приложение с работой с другой базой данных, MongoDb или MySQL, нам нужно будет установить все три базы данных на каждый компьютер.

Так вот докер позволяет запустить наше приложение не устанавливая никаких дополнительных инструментов на наш компьютер напрямую. Потому что контейнер — это своя собственная изолированная среда, включающая все необходимые настройки и инструменты для запуска и работы нашего приложения. И загрузить и запустить такой контейнер можно одной командой — docker run my-app:1.0, где my-app будет именем нашего образа, а 1.0 версией (тегом) нашего образа.
👍6
Всем привет!

Небольшой пятничный апдейт 👨‍💻

После того, как познакомилась с Docker, захотелось применить его на своем пет-проекте. Но для этого захотелось его сначала доделать.

Поэтому начала с настройки Spring Security. Наконец, это у меня получилось, пароли стали сохраняться в зашифрованном виде. После этого, подключила Json Web Token, который теперь может выдаваться юзеру на короткое время действия, и с которым юзер может заходить в защищенные эндпоинты.

Теперь хочу подключить простой фронт. Сомневаюсь, стоит ли делать через модель Spring MVC или через Vaadin... 🤔 C одной стороны, мне интереснее Vaadin, потому что он на Java, а MVC предполагает знание, как минимум, HTML. Но оба варианта предполагают изменение существующей логики — у меня сейчас реализованы REST контроллеры.

Буду рада, если кто-нибудь из читающих посоветует, что лучше выбрать (или свой вариант) ☺️
👏2👍1
Всем привет!

Сегодня прочитала про одну, относительно древнюю, мудрость в современном контексте — «Лучшее — враг хорошего».

Мы часто много времени тратим на поиск лучшего — лучшей работы, лучших курсов, лучшего фреймворка, лучшего инструмента. С одной стороны, это логично и всем бы этого, наверное, хотелось.

Но из такого подхода могут выйти некоторые скрытые недостатки, например:

Мы не всегда знаем, что что-то перед нами уже и есть лучшее. Часто мы делаем выбор, основываясь на неидеальной информации: советам друзей, оценкам ревьюеров. Приобретая это что-то мы можем увидеть, что получили не «лучшее», а что-то, что занимает второе место по эффективности. Это может привезти к разочарованию и долгому сравнению фич одной вещи и другой. Такой подход может привезти к тревоге пропустить «лучшее».

Зачастую наш курс «Java-разработчика» на Яндекс.Практикум критикуют более опытные учащиеся, кто-то кто уже работает, например. Говорят, что теория подана плохо, тема раскрыта не полностью, другие говорят, что слишком много ссылок на сторонние ресурсы. Один из моих сокурсников ушел на другие курсы, потому что там ему показалось, что преподавание поставлено лучше и более эффективно.

Идея звучит в том, чтобы принимать то, что «достаточно хорошо». Когда мы перестаем стремиться к идеалу каждую минуту, мы не только становимся счастливее, но и развиваемся.
👍7🔥3
Всем привет!

Сегодня хочу рассказать про свое мок-собеседование, которое у меня прошло в понедельник. Оно было посвящено уже больше java, ООП не обсуждали, хотя немного поговорили о SOLID (и как я нем опять ошиблась? 🤦)

Собеседование проходило в интересном формате, я расшарила свой экран, открыла блокнот и писала в нем код. Кстати, кто вдруг не использует, рекомендую Notepad++ вместо стандартного блокнота. Он удобнее для того, чтобы писать код.

Первая задача была написать алгоритм для расчёта факториала. Не с первого раза вспомнила как он рассчитывается, но потом написала.

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

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

Так что на следующей неделе сделаю здесь подробный разбор как устроены HashMap и HashSet.😊

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

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

В общем, очень интересный и полезный опыт - перед реальным собеседованием нужно научиться говорить о технических вещах и, главное, научиться правильно выражать свои мысли. 💪
🔥8👏3
Всем привет!

Сегодня будет пост, посвященный HashMap и HashSet.

Итак, что такое HashMap?

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

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

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

Как выбирается корзина, в которую попадет наш элемент?

Путем следующего вычисления: берется hashcode нашего ключа (хэшкод - это численное представление объекта в java) и берется остаток от деления на количество наших корзин. Например, пусть хэшкод нашего ключа 245345, тогда остаток от деления на 16 будет 1. Это будет индекс нашей ячейки куда поместится элемент, который мы хотим сохранить в хэшмапе.

В случае, когда в качестве ключа у нас кастомный класс, необходимо переопределить equals и hashcode для правильного расчета хэшкода для нашего класса. Ведь если всем элементам будет выдаваться одинаковый хэшкод и мы захотим положить в хэшмапу такие ключи, они все будут попадать в одну и ту же ячейку. Каждый элемент в такой ячейке будет ссылаться на следующий, подобно Linkedlist. Что увеличит сложность для получения значения по ключу от мгновенной О(1) до О(n).

Как правильно отметил Руслан в комментариях, начиная с Java 8, структура данных, в которой хранятся значения внутри одной корзины, изменяется со списка на сбалансированное дерево, если корзина содержит 8 или более значений, и обратно возвращается в список, если в какой-то момент в корзине осталось только 6 значений. Это повышает производительность до O(log n).

HashSet в свою очередь основан на хэшмапе, только в ключ попадает наш элемент, что позволяет хранить уникальные элементы, а в качестве значения кладется пустой объект заглушка (new Object()).

Таким образом, с правильно определенным equals и hashcode для кастомных классов, узнать есть ли в множестве (hashset) наш элемент можно мгновенно, так как в методе contains у хэшсета вызывается метод хэшмапы containsKey, который работает за О(1).

Стоит иметь в виду, что хэшсет не имеет метода get() для получения конкретного значения, поэтому найти нужный элемент мы можем за О(n).
👍71
Всем привет!

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

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

Начала с подготовки к настройке Spring Security, завела базу пользователей, базу ролей, которые могут быть у этих пользователей.

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

Тут я вспомнила, что давно не практиковалась с Docker, поэтому подумала: "А почему бы не попробовать запустить кафка через докер?" Подумано - сделано, и теперь у меня подключена Kafka к проекту, которую запускала вчера через докер😁

Пока я не знаю, как именно ее буду использовать, потому что только только начала читать книгу "Kafka в действии" и находить более-менее понятные туториалы. Может мне в проекте Kafka, как акуле ноги, но посмотрю, что из этого получится 😊
🔥5👍1
Всем привет!

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

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

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

Это мне потом, возможно, пригодится для своего блог-проекта. Одно применение Кафки в нем, кстати, нашла - буду использовать при подсчете количества просмотров поста. (пока не знаю как, но как сделаю учебное ТЗ начну разбираться 😊)

Вот такие новости. Это ТЗ, кстати, будет последним перед дипломом. Диплом начнётся 4 сентября.
👍6🔥3
Всем привет!

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

Что нужно было сделать:
1. Подключить Spring Security + JWT токены для авторизации и аутентификации. (это не вызвало сложностей)

2. Сделать, чтобы пользователи могли публиковать посты с заголовками, описанием и фото/jpg файлом. Jpg файлы до этого я ещё не подключала/не хранила в базе данных, поэтому получилось не сразу. Но теперь я знаю, как это нужно делать 🥳

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

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

4. Добавить ленту событий. Это тоже не сложно.

5. Добавить документацию API с помощью OpenAPI, этого никогда до этого не делала, но, оказалось, что это делается очень просто и быстро.

6. Покрыть тестами. Пока я на этом этапе. Думала вчера, что за вечер всё протестирую, а в результате просидела до 2х часов ночи, разбираясь с тестами контроллеров и неправильно работающим моком Spring Security 😅 Он сначала ни в какую не давал мне прав создавать/изменять данные, давал права только на get методы.

В итоге, попробовав 5 разных вариантов, я смогла правильно сформулировать вопрос в гугле и нашла на stackoverflow ответ. Теперь, осталось применить во всех контроллерах, протестировать сервисы, и можно отправлять. 💪

(это тестовое - скрининг, так что не факт, что его будут проверять - при такой большой конкуренции начинающих специалистов на рынке, высока вероятность, что таких проектов им пришлют много на проверку, но я всё равно попробую 😊)
🔥6👍2👏2
Всем привет!

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

Его мне прислали также на прошлой неделе, но со словами: "не пугайтесь, если вакансия уйдёт в архив, выполнение тестового задания всегда актуально". Я подумала, что раз "всегда", значит выполню сначала то, которое со сроком (из прошлого поста).

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

Нужна была такая функциональность:

1. регистрация почтового отправления,
2. его прибытие в промежуточное почтовое отделение,
3. его отправление из почтового отделения,
4. его получение адресатом,
5. просмотр статуса и полной истории движения почтового отправления
6. покрытие тестами 70% и документация API.

Самое сложное было выцепить эти требования из самого задания и разложить по полочкам😁

Завтра вернусь к своим экспериментам с Кафка, потом расскажу, что из этого выйдет 😊
👍8👏1
Всем привет!

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

Десятилетиями мы хранили информацию, как некие 'данные' в базе данных. Это могут быть какие-то сущности, такие как пользователь, или что-то другое. Сейчас, многие стали думать о том, что хранить только данные недостаточно. Нужно хранить события (логи) - что-то случилось тогда-то в этом-то месте, например, такой-то пользователь обновил свой пост.

Кафка - это система, которая помогает управлять этими событиями. Эти события кафка называет топиками (topic с английского означает тема).

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

Топики могут быть маленькие, могут быть огромные, храниться могут несколько секунд или бесрочно.

Кафка мотивирует разработчиков думать о событиях сначала и 'данных' потом.

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

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

Это базовое представление о том, что такое кафка и что она из себя представляет.

Определение с официального сайта:
Kafka - это распределенная потоковая платформа, предлагающая три основные возможности:
1. чтение сообщений из очереди и запись их в очередь;
2 надежное хранение сообщений;
3 обработку потоков данных по мере их появления.
👍8🔥2
Всем привет!

Расскажу свои последние новости. После тестового задания по соцсети, меня пригласили к ним на собеседование, правда назначили мне его на 4 сентября. Сказали, что будет разговор о Spring и Spring Security.

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

Вчера ещё в одной организации начался java интенсив, на который я попала в группу из 22 человек. Было первое занятие, позиционировалось, как лекция, но на деле было знакомство. Так что потренировалась делать краткую самопрезентацию.

Потом лектор стал каждому задавать по два вопроса по Java Core и многие на них споткнулись. Вопросы в принципе были не сложные, но человека без подготовки могут застать врасплох.

Поэтому напишу некоторые вопросы здесь:
1. Отличие Comparable от Comparator.
2. Что такое блоки инициализации. Какие бывают и в каком порядке запускаются, если есть наследники.
3. Что такое дженерики (мне достался вопрос)
4. К какому типу данных относятся массивы, можно ли хранить примитивные типы данных в коллекциях.
5. Разница между final, finally и finalize.

Есть репозиторий с ответами на эти и похожие вопросы, здесь.
🔥2👏2
С Днем Знаний! 😁

У нас сегодня открылось задание на диплом. Будем реализовывать огромный, судя по всему, проект с несколькими микросервисами. Нужно выбрать дополнительную функциональность для него из нескольких на выбор. Я пока не определилась, но склоняюсь к функциональности «рейтинги». Там будет проект на тему событий, которые можно было бы оценивать, или, наоборот, хейтить :) В зависимости от рейтинга потом сортировать при выдаче.

Пока закрыт был доступ к диплому делала свой проект-блог. Настроила Spring Security, JWT, сделала, чтобы подсчет просмотров постов велся с помощью Kafka. Пока у меня есть два топика, один больше для логов, в качестве практики. А второй вот для подсчетов просмотров постов.

На интенсиве вчера был созвон с обсуждением Git, SOLID, задавались нам опять вопросы, только на этот раз не только по Java Core, но и по алгоритмам. На следующий созвон планируется подробная проверка наших знаний, как устроены коллекции.

Вчера отвлекалась от мыслей о сегодняшней линейке как могла: посмотрела видео Евгения Борисова о Spring (его видео - просто огонь, всем советую, кто еще не смотрел), читала Spring Security в действии, потом захотелось переключиться от Spring и стала читать MongoDB for Jobseekers (тоже интересная книжка).
👍6🔥1
Всем привет!

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

Все вопросы касались Spring, за редким исключением, всего длилось 1.5 часа.

Много говорили о бинах, сервлетах, подробно говорили о самом Hibernate, этапах жизни сущности, proxy.

Узнала много нового, например, что можно использовать environment переменные в пропертиз файле. Выписала себе много новых аннотаций.

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

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

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

Думаю всё дело в том, что тема задач была не какая-то там абстрактная, про каких-нибудь Вовочек-маминых хакеров, а более реалистичная. Можно даже сказать брутальная и жизненная. Во всех задачах герой был Ковбой Джо, не сопереживать которому было просто невозможно 😁
🔥7👍1