+7 (495) 859-21-36
Предоставляемые услуги
  1. Сайты
  2. Порталы
  3. Интернет-магазины
  4. Мобильные приложения
  5. Лендинги
  6. Брендинг
  7. Нейминг
  8. Продвижение
  9. Дизайн сайта
  10. Личные кабинеты
  11. Аудит сайта
  12. Образовательные платформы
  13. Сайты на Тильде
  14. Комплексный интернет маркетинг
  15. Техническая поддержка
  16. Коммерческие фотосессии
Вакансия

Мобильный разработчик Kotlin Multiplatform, C++

Мы рады, что вы выбрали нашу команду чтобы развиваться в направлении Kotlin Multiplatform, C++. Перед собеседованием мы просим вас выполнить тестовое задание

Подробнее о вакансии
Тестовое задание:
Задание для вакансии Мобильный разработчик Kotlin Multiplatform, C++
Важное условие:

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

У вас 3 устройства:

Устройство "А" — смартфон на Android выполняет роль клиента.
Устройство "Б" — рутированный смартфон на Android выполняет роль сервера.
Устройство "В" — любое устройство на Linux (например, обычный ПК) выполняет роль сервера мониторинга.

Все три устройства находятся в локальной сети, то есть имеют статические ip.
Серверное приложение получает root права от Magisk.


Простейший UI на Compose у каждого:

Клиент: кнопка "Настройки" и кнопка "Старт/Стоп".
В настройках указываем:
— ip:порт Сервера Б;
— ip:порт Сервера мониторинга В;
— Частоту X;
Есть кнопки "Сохранить" и "Редактировать".

Сервер: кнопка "Настройка", кнопка "Включить/Выключить", кнопка "Трек".
В настройках указываем:
— порт для прослушивания запросов от клиента;
— значение смещения в пикселях Dx и Dy;
— ip:порт Сервера мониторинга В;

Сервер мониторинга: кнопка "Настройки", кнопка "Треки", панель "Потребление ресурсов".
В настройках указываем:
— порт для получения данных от Клиента;
— порт для получения данных от Сервера.


Логика клиента и сервера:

1. Поведение клиента:
Включаем сервер кнопкой "Включить".
Нажимаем "Старт" на клиенте, устанавливается соединение клиент-сервер по протоколу websocket c Сервером и Сервером мониторинга.

С этого момента Клиент начинает считывать треки свайпов пользователя с частотой X раз в секунду (по умолчанию X = 50). При считывании учитываются:
— координаты соприкосновения пальца с экраном;
— оба радиуса эллипса соприкосновения пальца с экраном;
— угол поворота эллипса;
— сила давления пальца на экран.

Клиент в режиме реального времени отправляет эти данные по протоколу websocket одновременно Серверу и Серверу мониторинга.
Клиент работает таким образом пока не будет нажата кнопка "Стоп".

2. Поведение и архитектура сервера:
Серверная часть для устойчивости разделена на три изолированных процесса: Alfa, Beta, Gamma и Omega. То есть каждый из них является независимым приложением.

Alfa — имеет статус системного сервиса. Отвечает за получения данных от клиента, их преобразование на лету и передачу обработанных данных сервису Beta. Преобразование данных простейшее: для каждой передаваемой точки значение x и y смещается на Dx и Dy.
Alfa передаёт преобразованные данные в Beta с помощью IPC механизма SharedMemory.

Beta — имеет статус системного сервиса. Отвечает за воспроизведение движений, полученных от Alfa.
Воспроизведение движений осуществляется не через adb и не через какие либо верхнеуровневые библиотеки, а через события ввода операционной системы, при этом воспроизводит все доступные характеристики касания пальцем экрана (радиусы, угол, давление).
Важно, что Beta является системным сервисом, и осуществляет воспроизведение движений на любом экране, где бы вы ни находились, а не только в экране приложения, и это происходит всегда, пока на сервере не будет нажата кнопка "Выключить".

Gamma — тоже имеет статус системного сервиса. Этот сервис, по аналогии с Клиентом, считываем фактические треки свайпов (которые воспроизводятся пользователем или сервисом Beta) с учётом всех доступных характеристик (радиусы, угол, давление) и отправляет их по протоколу websocket Серверу мониторинга.
Важно, что Gamma никак не связан с Beta. Он именно считываем фактические свайпы независимо от того, воспроизводит ли их Beta или делает сам пользователь. То есть Gamma не должен просто копировать набор данных от Beta.

Omega — является обычным пользовательским приложением с root-правами (то есть, не системный сервис) и своим UI. При нажатии кнопки "Включить" он активирует функционал системных сервисов Alfa, Beta и Gamma, а при нажатии "Выключить" деактивирует его.

При нажатии на кнопку "Трек" мы попадаем на белый экран. На этом экране движения, воспроизводимые сервисом Beta графически визуализируются: каждая точка визуализируется соответствующим ей эллипсом с учётом радиусов и углов поворота, а сила давления обозначается цветом (0 - чёрный, 1 - ярко голубой, промежуточные значения - оттенками между ними).

Логика сервера мониторинга

При запуске сервер мониторинга разворачивает пользовательское приложение с UI мониторинга и два LXC-контейнера с сервисами для получения данных.
В каждом контейнере:
1. Сервис, который получает данные о движениях и записывает их в базу данных, добавляя к каждой точке значение времени получения данных. Также в БД записывается время активации и деактивации функционала Клиента (при нажатии кнопки "Старт" и "Стоп") и время активации и деактивации функционала Сервера (при нажатии кнопки "Включить" и "Выключить").
2. Сервер СУБД Postgresql. То есть, у каждого контейнера своя независимая СУБД.

Сервис в первом контейнере получает данные от Клиента, включая данные о времени нажатия "Старт" и "Стоп".
Сервис во втором контейнере получает данные от Сервера, включая данные о времени нажатия "Включить" и "Выключить".

Пользовательское приложение:
В панели "Мониторинг ресурсов" мы видим потребление ресурсов RAM и CPU, а также использования постоянной памяти базой данных для каждого из двух контейнеров отдельно в режиме реального времени с частотой обновления 1 раз в секунду.
При нажатии на кнопку "Треки" мы переходим на белый экран.
Элементы UI на экране: кнопка "Назад" для возврата на главный экран и рычаг переключения режимов между "Realtime" и "Record". Панель "Мониторинг ресурсов" остаётся везде.
По умолчанию мы находимся в режиме "Realtime".
На экране режиме реального времени отображаются свайпы от Клиента и свайпы от Сервера. Способ графической визуализации свайпов точно такой же, как на Сервере (использовать тот же код на KMP), только для клиента вместо ярко голубого использовать ярко оранжевый цвет.
Обратите внимание, что если , например, на Сервере экран не позволяет считывать радиусы, а на Клиенте экран позволяет, то графический трек от Клиента будет иметь переменную толщину, а трек от Сервера будет тонкой линией.
Если мы переключаемся в режим "Record", то графические треки начинают выстраиваться на основании данных из БД, причём с левого края экрана отображаются в столбик значения времени, координат, радиусов, угла и давления для треков от Клиента. А с правого края экрана отображается аналогично столбец значений от Сервера.
Воспроизведение начинается с момента последнего нажатия кнопки "Старт" и до момента последнего нажатия кнопки "Стоп" (если "Стоп" ещё не нажималось, то получится, воспроизведение из базы будет идти непрерывно с фиксированным отставанием от реального времени). Если воспроизведение закончилось, то оно повторяется в цикле.
При возвращении в режим Realtime мы опять отображаем данные, поступающие в реальном времени.

Некоторые требования к использованию технологий:

— Для сетевого взаимодействия использовать Ktor.
— Для решения низкоуровневых задач использовать C++.
— При наличии нескольких вариантов решения предпочтение отдавать root-командам, а не пользовательским библиотекам.

Что хочется увидеть в проекте?
  1. Понимание модульности в проекте (в нашем случае это несколько приложений в рамках единого проекта).
  2. Применение шаблона проектирования Singleton.
  3. Умение рефакторить собственный код (покажите оптимальные чисты решения без мусора).
  4. Использование DI решений.
  5. Отсутствие закомментированного кода (в смысле мусора).
  6. Наличие кратких содержательных комментариев к коду (защита кода будет на собеседовании)
  7. Разделение сервисов на слои.
Форма обратной связи