backup

backup


Java Backend Roadmap 2024

Abdurakhmon BainazarovFebruary 19, 2024

За 1.5 года обучения и работы, я собрал большое количество материалов и практик, исходя из этого был составлен данный roadmap. Тут я хочу сделать выжимку, при котором можно быстро и качественно получить работу Junior(а в некоторых местах и Middle) Java разработчиком. Так как акцент на получении работы, что то я буду пропускать, большинство материалов в данной статье бесплатные.


Немного обо мне

Меня зовут Abdurakhmon, мне 23 года, с ноября 2023 года работаю Java разработчиком. До разработки 3 года работал поваром в ресторанах Крыма, Сочи и Москвы. В 2023 году я поставил себе цель стать Java разработчиком и в первый же день начал вести свой БЛОГ, там вы можете прочитать, как проходила моя стажировка, опыт прохождения собеседований, о моем первом проекте и развитие как разработчика.


Java Core


Предлагаю начать с JavaRush - пока лучший сайт для начинающих, там много теории и практики, 20 уровней более чем хватает, т.к дальше уже идет повторение некоторых тем, и уже мало смысла оставаться там. Сайт не бесплатный подписка 30$(~2500 руб.) в месяц, но это того стоит. Карты РФ не принимает, но вы можете воспользоваться сервисами, например Oplatym.ru.

Параллельно на выбор можно смотреть видеокурсы по данным темам:

Дополнительная практика:

Что вы должны знать на выходе:

Loops, Collections, Stream API, Exceptions, Generics, Date and Time, OOP(basics), Lamda, Objects.


Сборка проекта + Git


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

Идем дальше Git - как система контроля версий с распределенной архитектурой. Проще говоря мы можем отправлять/копировать проекты на удаленный репозиторий. На выбор можете посмотреть это видео ТЫК либо это ТЫК.

Поиграться с командами и ветками git, можно здесь.

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


База данных, JDBC и Hibernate


Тут мы начнем изучать новый язык SQL - для общения с реляционными базами данных. Для начала предлагаю ознакомиться и попрактиковаться с СУБД PostgreSql тут. Также будет полезно прочитать статью о разнице SQL vs NoSQL.

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

Работать с JDBC, чаще всего неудобно(много кода, кэширование, управление транзакциями), поэтому на помощь пришли ORM(Object Relational Mapping) - преобразование объектно-ориентированной модели в реляционную и наоборот. То есть нам больше не нужно писать эти громоздкие запросы, а можем работать с нашими объектами, если точнее будем знакомиться с конкретной ее реализацией Hibernate.

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

*В разделе Java core у нас была практика ATM simulator, предлагаю переписать хранилище с использованием JDBC либо Hibernate.


Spring Framework

  • Spring Core

Spring это основной энтерпрайз фреймворк для Java на котором пишут RESTfull API и backend в целом.

По сути spring'ом называют не один конкретный фреймворк, а семейство разных фреймворков (Spring Core, Spting MVC, Spring Web, Spring Data JPA, Spring Security, Spring Boot и т.д.), которые построены на одной архитектуре главного фреймворка Spring Core.

У спринга есть своя уникальная архитектура проекта которая связана с двумя важными принципами - "Dependency Injection" и "Inversion Of Control"

Для начала предлагаю вот такую задачу: 

1. Изучить концепт этих двух принципов и как они реализованы в спринге.

2. Что такое bean

3. Что такое spring context

4. Что такое spring container

5. Жизненный цикл бина

6. Написать небольшую программу с использованием этих принципов

!!!Важно: Не уделяйте много времени на xml конфигурацию спринга, только исключительно java конфигурацию и аннотации

Можете пойти по Алишеву(до 13 урока достаточно) либо по JavaGuru(с 23-24 урока).

  • Spring Boot - если нам до этого приходился писать бесконечные конфигурации, то Spring boot облегчает нам эту задачу тем, что предоставляет автоконфигурацию для наших модулей. Также он имеет встроенный http-сервер(Диспетчер сервлетов) который помогает развернуть RESTful API очень быстро.

Перед тем как создать первый проект на start.spring.io посмотрите это видео.

  • Spring Data JPA - еще одна абстракция теперь для нашего Hibernate, предоставляет нам из коробки методы для работы с нашей БД, реализацию TransactionManager и автоконфигурацию, теория + практика.

*Практика cоздайте CRUD приложение для магазина:

1) Сущность товары: Название, описание, категории, цена, количество, артикул, дата и время последнего изменения количества, дата создания. В качестве БД использовать PostgreSQL.

2) UUID в качестве первичного ключа, почитать/использовать @Lombok и @Builder .

3) Разделение приложения на слои: веб -> сервис -> репозиторий , использование Spring ConversionService для конвертации entity -> dto -> request/response.

4)Поиграйся с ручками на создание/удаление/обновление/получения.

Пример реализации: github.com/bainazarov


Пишем свой первый проект

Теперь начинается самое интересно, мы будем писать свой первый проект и он будет максимально приближен к боевому, какую выберите тему неважно, самое главное это потрогать технологии, за основу возьмем наш CRUD магазин, который делали в разделе Spring. Все эти реализации есть в моем проекте github.com/bainazarov, который я писал в рамках стажировки:


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


  • Liquibase - упрощает отслеживание/управление в базе данных, помогает вести версионность БД и упрощает тестирование(если поднимать другую базу данных для тестов), видео для ознакомления.
Задача: Написать скрипты миграции для вашей базы, добавьте валидацию для входных полей(NotEmpty, NotNull и т.д)


  • @Profile и Пагинация - @Profile служит для управления конфигурацией и активацией компонентов в зависимости от профиля. Пагинация - это процесс при котором мы разделяем большое количество набор данных на небольшие фрагменты(например страницы).
Задача: добавьте возможность запускать с профилем спринга "local", при котором в качестве БД подключается H2DB, а не PostgreSQL. Добавить ручку findAll, которая должна быть с пагинацией.


  • GlobalExceptionHandler - является глобальным компонентом который будет отлавливать наши исключения.
Задача:  Написать GlobalExceptionHanlder, перехватывающей все ошибки приложения. Создать ErrorDetails (содержит название класса исключение, сообщение и штамп времени), который возвращается хендлером. Больше никаких RuntimeException пишите свои кастомные исключения и отлавливайте из сервиса хендлером.


  • Job Sheduler - это некий планировщик задач, который выполняется на фоне работы нашего основного приложения.
Задача: добавить job sheduler, который каждые 30 секунд увеличивает цену товара на 10%. Время конфигурируется через параметр app.scheduling.period. Должна быть возможность отключения фичи через параметр app.scheduling.enabled. По дефолту false.


  • Spring AOP - статья для понимая что такое AOP. Это некие сквозные операции которые позволяют внедрить дополнительное поведение без изменение целевого объекта(Например кэширование, логирование и т.д).
Задача: Сделать свою аннотацию, которая замеряет время выполнения метода. Использовать аспект с joinpoint @Around. Повесить аннотацию на методы сервиса.


  • JUnit, Jupiter, Mockito - это библиотеки, которые используются для тестирования, здесь пример реализации.
Задача: Написать юнит-тесты на методы сервиса. Применить Junit, Jupiter и Mockito. Пример теста: Если jpa-репозиторий вернул пустой Optional, то будет ProductNotFoundException. Второй тест – если репозиторий вернул ProductEntity, то метод вернет ProductDto с полями, которые совпадают с ProductEntity. Не spring boot тест, репозиторий надо будет замокать @Mock


  • RestAssured - это библиотека для тестирования RESTful API в Java. Она предоставляет удобные и выразительные способы отправки HTTP-запросов к API, проверки ответов и проверки состояния системы, статья для первого ознакомления.
Задача: Написать тесты на методы контроллера, используя библиотеку RestAssured. Это будет SpringBootTest, тест проверяет валидацию NotNull NotBlank полей, коды ответов.


  • JPA Specification
Задача: Сделать новый эндпоинт /products/search, который принимает объект – фильтр. Поля: имя, количество, цена, доступность. Из полей собирается спецификация. Name сравнить по like, количество по нижней границе, цену по верхней, доступность по eq. Если во входящем запросе какой-либо параметр = null, то на фильтрацию не должно влиять, отображаются все товары по этому критерию. Добавить новое boolean поле скриптами миграции isAvailable оно не может быть Null, по дефолту true.


  • Работа с @Transactional
Задача: В шедулер добавить sleep на 30 сек и @Transactional. Попробовать изменить, извлечь товары в процессе работы шедулера. Посмотреть, что будет. Попробовать все блокировки optimistic locking, pessimistic locking, pessimistic writing и попробовать починить.


  • Рассчитываем курс из файла
Задача: Добавить файл формата .json. {“exchangeRate”:65.0}. Сделать так, чтобы цена переводилась в курс из этого файла. (используй RestControllerAdvice " implements ResponseBodyAdvice<GetProductResponse>"). Создать класс ExchangeRateProvider с одним методом getExchangeRate.


  • CaffeineCache, Docker и настройка общения через RestTemplate
Задача: 1)Сделать второй сервис, который возвращает курс (json аналогичный как в предыдущем задании). Сделать, чтобы значение курса бралось из этого сервиса, кэшировалось на 1 минуту. Если сервис не доступен, бралось из локального файла. Для практики с docker, написать для нашего второго сервиса dockerfile.yml и попробовать покидать запросы.

*То есть в exchange сделать 2 приватных метода, один получает значение курса из этого json файла, а второй получает значение курс из второго сервиса. И публичный метод, он как раз будет решать откуда брать курс.

*Полезно:

сначала mvn clean --> mvn .jar (собрать jar-ник)

docker build -t my-app3 .  ---> (пробел после my-app3) -- тут собираем образ

docker run -d -p 8080:8082 -e spring.profiles.active=local my-app -- запускаем контейнер с профилем local 

host.docker.internal --> у докера свое окружение


  • Stub для вызываемого сервиса - stub'ом у нас будет класс/заглушка, обычно так делают если нам неважна реализация, а только ответ от какого-то сервиса.
Задача: Сделать stub для вызываемого сервиса (отдельная реализация бина клиента сервиса). Активируется параметром interaction.rate.stub=true. Использовать @ConditionalOnProperty делаем через интерфейс.


  • Используем OncePerRequestFilet и SessionScope
Задача: Сделать чтобы было 3 курса валюты, расширить имеющийся json, поправить второй сервис с курсом валют. Клиент в хедере передает USD или EUR или RUB. Значение из хедера устанавливает валюту для клиента на время сессии клиентских запросов. Если хедер пустой или не мапится, то установленная валюта не меняется. По дефолту сервис выдает цену в RUB. Используй OncePerRequestFilter и SessionScope сделать отдельный класс фильтр который перехватывает запрос и установил его для текущей валюты сессии.


  • @OneToMany, @OneToOne и @ManyToMany - это отношения между таблицами в базе данных в контексте реляционных баз данных.
Задача: Сделать сущность заказа, сущность юзера. Когда заказ создан, количество товаров уменьшается. На заказе есть общая стоимость товаров. При заказе цена фиксируется. У заказа есть поле статус. При создании заказа автоматически проставляется статус – CREATED. Еще статусы CANCELLED, COMPLETED. Привязать сущность юзера к заказам. Реализовать эндпоинт создание/удаление заказа, по ID продукта получить заказы в котором он есть, изменение статуса заказа, добавление продуктов в существующий заказ(можете свои добавить поиграться). Посмотреть какие sql отправляются, посмотреть на N+1 и починить. OrderedProduct составной первичный ключ, поля id товара и заказа, количество и цена.


  • Ходим за ИНН в другой сервис
Задача: Написать другой сервис, который по имейлам юзеров одним запросом возвращает данные (например возвращает список ИНН по списку email).
В основном сервисе сделать ручку, которая группирует товары по заказам. У каждого заказа получить данные о юзере из другого сервиса. Формат ответа примерно такой: товар -> список заказов в которых он присутствует, а у каждого заказа инфа по юзеру с ИНН.


  • Каркас общения через события EventSource(будет основой для нашей кафки)
Задача: Сделать эндпоинт для обработки событий с общим полем event и абсолютно разным набором остальных полей. Принимает интерфейс EventSource, сделать через JsonSubtype, сделать хендлеры для событий. Ввиды эвентов: CREATE_ORDER, CHANGE_ADDRESS, CANCELLED_ORDER, COMPLETED_ORDER.
  • Kafka producer/consumer - это некая разветвленная система труб, в которую с одного конца можно бросить, например, контейнер с сообщениями, а с другого конца его кто-то получит и прочитает. К таким системам относят и Apache Kafka, немного теории.
Задача: в основном сервисе сделать consumer, которыпй ринимает события из топика "events". Данные передавать как объект, сериализованный в json строку. События должны обрабатываться теми же хендлерами. Почитать что означает groupId, зачем ключ передается в топик вместе с сообщением.
Сообщения в топик отправлять либо вручную (через плагин идеи), либо через другой сервис, в котором настроить producer.
Как только все заработает, запусти 2 экземпляра своего основного сервиса на разных портах. И покидай сообщения в топик. Нужно посмотреть какой именно запущенный экземпляр обрабатывает сообщения.
2 экземпляра нужно запустить двумя вариантами: 1) с одинаковыми groupId 2) с разными groupId.


  • Redis noSQL хранилище - это опенсорсный сервер баз данных типа ключ-значение. Хранит все данные в RAM, в отличии от традиционных БД, которые хранятся в жестком диске, что и делает его быстрее.
Задача: Подключить нереляционную БД - Redis. Хранить там ключ идемпотентности. Если запрос на создание происходит с одним и тем же ключом, то заказ не создается, возвращается id уже созданного заказа. Для профиля local – ключ хранится в inmemory.


Также если хотите улучшить написание кода, предлагаю вам лучшие практики by dmdev.



Подготовка к собеседованию

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

Дополнительные материалы/шпаргалки для подготовки:

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

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


Как лучше начать поиск работы?

Поставьте минимум 1 год опыта, т.к часто у hr стоит фильтр на кандидатов с опытом меньше 1 года. Я знаю как тяжело найти первую работу, по своему опыту кроме hh, habr и linkedIn ищите местные IT компании и пишите их hr'ам в телеграмм, у них даже может вакансии не быть, но все равно есть шанс, что позовут на собеседование(так я нашел свою первую работу).


А как же алгоритмы и книги? - Чаще всего у вас не будет секции с алгоритмами, а книги уже на ваше усмотрение, технологии с каждым днем обновляются и многое просто устарело. Мы делаем акцент на получении работы, а это у нас заберет приличное время.


Советы по ускорению твоей учебы

В этом блоке я расскажу вам фичи/лайфхаки, которые облегчит/ускорит ваше обучение:

  • Сообщество наше все - вступай в чаты/группы знакомься с другими разработчиками, ходи на митапы, максимально окружи себя всей этой айтишной тематикой. Не зря есть поговорка "Если вы общаетесь с пятью Java разработчиками, то станете шестым".
  • Дисциплина превыше всего - мало смысла от учебы, если ты не уделяешь ей время регулярно, старайся учиться каждый день по часу, чем ты раз в неделю сядешь на 10 часов. В идеале я бы уделял по 4-5 часа в день, а в выходные разбавлять это чем то другим.
  • ChatGPT ускорение - используй GPT для ускорения своей работы правильно, не стоит злоупотреблять и самому ничего не писать, толком не поняв, что ты делаешь. В идеале сначала разобраться самому -> Далее написать GPT спросить как можно решить тут -> Если и так не получилось, то запросить решение и разобраться в нем.
  • Будь самостоятельным - старайся прививать себе это качество с самого начала, большее количество работы программиста это поиск решения определенной проблемы.
  • Не понимать чего-то это нормально - часто когда люди только начинают учиться, могут столкнуться с первыми трудностями и появляются мысли ''А может это не мое'', "Я слишком глуп для этого". Расслабьтесь это чувство у вас будет всегда) Например я никак не мог понять тему массивов, особенно двухмерные, я просто взял и пропустил его, чем сидеть над ним неделями, позже я все таки вернулся и закрыл для себя эту тему.
  • Коворкинги/кафе - мне часто было тяжело заниматься дома, т.к было много отвлекающих факторов. Тогда я брал ноутбук и садился в какое-нибудь заведение. Какое то время меня спасал трекинг обучение, смотреть сколько реально ты сидел над задачей.


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






Report Page