Обложка: Как я со своей командой победил в хакатоне DEVHack

Как я со своей командой победил в хакатоне DEVHack

Привет! Я открыл для себя нечто новое — хакатоны.

Для тех, кто не в теме, в двух словах объясню. Хакатон — это марафон для разработчиков. Вы собираете команду или работаете один (если правилами это разрешено). У вас есть 48 часов на решение задачи. О ходе работы отчитываетесь на чекпоинтах. Они нужны для того, чтобы помочь участникам и отсеять тех, кто идёт совсем не в том направлении. До дедлайна вы показываете своё решение жюри, которое его оценивает.

Я случайно наткнулся на объявление о том, что «Промсвязьбанк» организует хакатон. Целевая аудитория — frontend/backend/mobile-разработчики, бизнес-аналитики и дизайнеры. Было несколько задач, мне показалась интересной первая: разработать механизм исполнения операций для розничного банка в рамках микросервисной архитектуры. Рекомендуемый стек: kafka/kafka streaming, .NET, Java.

За решение задачи дают 375 000 рублей, что очень неплохо за 48 часов работы. Глаза загорелись: банковская задача, нормальные деньги и опыт нон-стоп работы в выходные — что может быть лучше?

Для участия в хакатоне по правилам была нужна команда минимум из 3 человек. Я зарегистрировался, добавился в чат в Telegram, написал, что ищу команду, и забыл.

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

Подробности в видео, ниже — текстовая расшифровка.

Суть задачи, которую мы решали

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

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

Презентация не очень понятная, деталей мало, объяснения абстрактные. В общем, всё, что нужно, чтобы включить голову. После объяснения задачи была Q/A-сессия, в рамках которой мы задавали экспертам вопросы в чате. Поскольку непонятно было примерно ничего, вопросы тоже были слабыми. Уточнили стек, узнали, что нужен движок дистанционного банковского обслуживания, а не информационная система процессинга, и разошлись.

День первый: проектирование решения

Хакатон начался. Итак, наша команда: продакт-менеджер, архитектор, софтверный инженер и я бездельник. Продакт пошел писать рыбы документов и накидывать схемы операций, а мы стали брейнштормить. На самом деле, был один главный вопрос: надо сделать именно движок без реализации сервисов процессинга или же надо реализовать/придумать сервисы процессинга вместе с движком? Обсуждение этого вопроса заняло около 6 часов. Только в час ночи мы решили, что будем делать движок и сосредоточимся на описании операции. Ещё нужно не забыть про возможность указывать в операции для каждого шага доменный сервис, который и делает этот шаг. Да, и про формы тоже нужно не забыть.

Общая архитектура стала понятна сразу. Есть Kafka — брокер. Вокруг него микросервисы. Микросервисы пишем, используя Java-фреймворк Quarkus, пакуем в Docker-контейнеры, образы собираем и деплоим при помощи GitLab CI. Событийно-ориентированная архитектура — сервисы генерируют события и реагируют на них. Для поддержки транзакционности возьмём за основу хореографическую сагу. Осталось только понять, как наложить её на пайплайны операций, сделать rollback и компенсацию операций. Откат в том числе нужен и для успешно завершённых операций.

Основная идея зародилась в первые же часы проектирования и не изменилась до сдачи решения. Мы берем JSON, берём паттерн DSL (Domain Specific Language), описываем пайплайн в виде JSON.

Почему JSON? Он быстрый, его все знают и умеют готовить, как люди, так и сервисы.

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

День второй: выживают сильнейшие

В субботу мы занимались CI/CD, рисовали схемы в Miro, составляли документ, описывающий архитектурное решение (High Level Design). В 11:00 я прошёл первый чекпоинт. Рассказал про JSON, DSL и Quarkus. Этого хватило: эксперты поняли идею, им понравилось наше решение.

Затем мы продолжили работу. Начали реализовывать микросервисы и билдить нативные бинарники (представляете, GraalVM такое умеет!), чтобы не париться с Java в контейнере. Следующий чекпоинт был в 15:00. Я выкатил HLD, подробно описал механизм работы движка. Этого опять же хватило для попадания на следующий этап.

Последние 9 часов были самыми тяжёлыми. С архитектурной точки зрения всё было почти идеально. HLD готов, архитектура понятная и рабочая. Были даже 2 сервиса, которые получали пайплайн, генерировали события и отправляли в Kafka. Но других сервисов не было. Нужно было ещё сделать презентацию, оформить решение, записать видео с рассказом про решение, реализовать 3 сервиса и сделать фронтенд. А время уже 2 часа ночи.

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

В 3 часа ночи меня вырубило на пару часов прямо в кресле. Софтовик вообще не спал, остальные поспали от 2 до 4 часов.

День третий: подготовка презентации и защита проекта

Продакт сделал черновик презентации, я завернул его в мой любимый шаблон и добавил «мяса», софтовик набросал общую архитектуру для презентации. Затем я за 15 минут сделал index.html, в котором при помощи хардкода на JavaScript DSL-форма была отрисована в виде HTML-страницы. Архитектор в это время дописывал код сервисов и сшивал решение. На Java он писал в третий или четвёрый раз в жизни, но это неважно.

За 5 минут до дедлайна по загрузке решений я заливаю ролик на YouTube, высылаю презентацию, докидываю документ HLD + файлы Miro. За минуту до дедлайна делаем последний коммит в репозиторий, высылаем ссылки, выдыхаем.

Через 3 часа стало известно, что мы прошли в финал, в котором нужно будет защитить свой проект. Я успешно объяснил решение, а на закрытии мы узнали, что наша команда SchrodingersSingleton заняла первое место в первом треке!

Впечатления от участия в хакатоне

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

Хинт для программистов: если зарегистрируетесь на соревнования Huawei Cup, то бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.

Перейти к регистрации

Что думаете?