Senior Backend Developer (Golang, Java)

Зарплата

от 3500 €

Местоположение и тип занятости

Москва, Санкт-Петербург, Аликанте (Испания)Полный рабочий деньМожно удаленно

Компания

Разработка ПО для автоматизации ресторанов

Описание вакансии

Условия работы

Привет!

Меня зовут Максим, я руковожу разработкой ПО в компании unTill, мои статьи на habr см. тут.

У нас есть вакансия Senior Developer Golang. Что нужно делать?  Изменить мир, и это не шутка, см. детали ниже.

Изменять мир можно работая в Санкт-Петербурге,  удалённо из Москвы или иного места, а можно непосредственно в Эльче - это Испания, там находится один из наших офисов и часть команды. Релокацию поддержим, аренду жилья на 6 месяцев оплатим.

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

О проекте

Облачную версию (unTill Air) нашей продуктовой линейки по автоматизации ресторанов мы изначально разрабатывали с учётом "отстрела"  ядра в отдельный коммерческий продукт  - платформы для быстрой разработки распределённых облачных приложений (на данный момент называется Heeus). Сейчас unTill Air стабилизировался и пришло время этого самого "отстрела". Heeus - это стартап на стадии pre-seed, MVP хотим получить к будущему лету.  Стартап "пилится" совместно с еще одной компанией, директор которой - в борде достаточно крупного венчурного фонда, при условии наличия MVP и положительного отклика от клиентов проблем с финансированием SEED-раунда не должно быть. Если даже идея со стартапом провалится, проект будет использован для внутренних нужд, так что в этом смысле всё надёжно.

Сценарий использования MVP:

  • Заказываем чистые серверы с Ubuntu 18.04+ (предусмотрена опция FreeBSD 13.1+ - для фанатов) у любого провайдера (возможно, в разных ДЦ, т.е. stretched cluster)
  • Качаем установщик, сообщаем ему IP адреса узлов
  • Установщик объединяет узлы в кластер, накатывает на узлы Scylla/Cassandra, агенты и сервера приложений Heeus (никаких docker, k8s)
  • На этом с установкой платформы приложения всё
  • Хотя нет - можно сделать ещё один кластер в другом географическом месте и объединить кластеры в федерацию. Кластеры будут бесшовно работать совместно, в частности, профили пользователей будут создаваться в соответствии с требованиями национальных регуляторов

Далее на SQL-подобном языке (весьма расширенном) описываем базовую функциональность приложения типа Slack, полученные скрипты развёртываем в платформе и получаем работающий и масштабируемый горизонтально backend для Slack-подобного приложения. Для такой демки должно хватать NoCode описания - т.е. только SQL-подобный текст (без "хранимок").

Наши рестораны (unTil Air), естественно, тоже будут переведёны в такой вид, однако, ввиду сложности логики проекта, понадобится расширить ядро небольшими вставками на WASM - так сказать, LowCode здорового человека.

Как нетрудно заметить, для некоторого класса задач Heeus заменяет весь современный стек и может быть поставлен везде, в том числе и на своём железе. ok, не весь стек, на первых порах только его OLTP часть. OLAP некоторое время будет в урезанном виде, так что продукты типа Apache Storm пока выживут.

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

Статус проекта

Текущая версия разрабатывается с сентября прошлого года, до этого более года разрабатывался прототип. Проект существует в виде набора библиотек, который используется монолитом unTill Air. В таком виде (три сервера БД Scylla + один сервер приложений) вполне потянет non-functional requirements по производительности и задержке (10.000 ресторанов на кластер, ~ 1K RPS по вставкам заказов, 100 ms на ответ). Сервер  приложений может "упасть",  для этого редкого случая задержки в обслуживании на перезапуск средствами swarm считаются приемлемыми. Не айс (хотя в значительной степени смягчается толстым клиентом), к следующему лету это надо улучшить.

DevOps проекта

GitHub, GitHub Actions, CI, CD

Стек проекта

  • Golang, Bash
  • Scylla/Cassandra/bbolt/FoundationDB
  • Swarm
  • Grafana, Prometheus

Рабочий процесс

Scrum, epics, backlog. Двухнедельные спринты, ежедневная летучка, до двух раз в неделю - архитектурные совещания.

Команда проекта

На проекте есть DevOps-инженер, системный администратор (без бороды), несколько backend-разработчиков и я. Еще один backend-разработчик завершает свои проекты и вот-вот вольется в процесс, планируем привлечь еще двоих со стороны, динамика положительная, заинтересованные стороны верят в успех.

Чем предстоит заниматься

  • Участие в разработке архитектуры
  • Разработка кода
  • На каждом спринте design/code review по двум другим разработчикам

Требования

  • Желание
  • Опыт разработки проектов с высокой нагрузкой и высокой доступностью
  • Знания именно Golang/Scylla/Cassandra не требуется, например, опыт ведения highload проектов на Java/PostgreSQL вполне подойдёт, возможны и другие варианты

Бонусы

Оплата и поддержка релокации в Испанию и аренды жилья на 6 месяцев.

Дополнительные инструкции

Тестовое задание

Предложить архитектуру решения для обработки упрощенных (JOIN - одноуровневый) SQL запросов путем их разбора и перенаправления к NoSQL базе (нам нужна Scylla/Cassandra но это не имеет принципиального значения). 

Пример запроса:

SELECT is_channel_message
,(SELECT kind, COUNT() FROM reactions GROUP BY kind) AS reactions
,(SELECT FIRST(10) author DISTINCT(author) FROM reactions) AS firstReactors
,(SELECT COUNT() FROM threads) AS replies
,(SELECT LAST(3) author DISTINCT(author) FROM messages) AS lastRepliers
FROM messages
WHERE messages.is_channel_message = true
ORDER BY messages.id

Здесь подразумевается, что ядро "знает", как соединять messages, reactions, threads и т.д., таким образом информация о том, по каким колонкам происходит соединение, в запросе отсутствует.

Этот запрос надо каким-то образом "понять" и выполнить, имея лишь драйвер к KV-хранилищу.  Интерфейс к драйверу выглядит так:

type IKeyValueReader interface {
    Get(tableNo int, key []byte) (values [][]byte, err error)
}

Get() работает по полному или частичному ключу.