Меню


Site Logo

Тестовое задание для младшего разработчика С++

Постановка задачи

Необходимо разработать модуль, реализующий логику переключения светодиодного светофора для автомобилей (рис. 1). При выполнении задания считать, что светофор один, установлен на однополосной дороге и закреплен на столбе так, чтобы быть видным водителям транспортных средств.

trafficlight

Рис.1. Внешний вид светофора

Логика должна обеспечивать следующий цикл переключений сигналов:

  • 40 секунд зеленый;
  • 4 секунды желтый;
  • 30 секунд красный.

Управляющая логика, которую следует разработать, должна взаимодействовать с исполнительным модулем, умеющим взаимодействовать с контроллером светофора, и контролирующей логикой. Модуль-исполнитель умеет устанавливать на светофоре нужный сигнал — зеленый, красный, желтый. Он не умеет организовывать ожиданий. Т.е., нельзя сказать ему: «показывай зеленый сигнал 40 секунд». Время должна контролировать управляющая логика. Контролирующая логика решает задачу включения цикла работы управляющей логики и получает от нее сообщения о проблемах.

При выполнении задания следует считать, что аппаратура светофора обеспечивает:

  • мигающий желтый сигнал при включении;
  • мигающий желтый сигнал в случае аварии контроллера (автоматически включается, когда не поступают воздействия от контроллера).

Модуль-исполнитель пассивен по своей природе и обеспечивает реакцию на команды, никогда не начиная обмены по своей инициативе. Управляющая логика должна в нужные моменты передавать через коммуникационную среду сообщения-команды исполнительному модулю и ожидать от него ответа об исполнении. Для установки сигнала нужного света нужно отправить исполнительному модулю сообщение SetLight. Ниже приведен протокол модуля-исполнителя:

Enumerations ; Перечислимые типы
  ColorType                | Цвет светофора
    1 : 3
      Red    : 1           |- Красный цвет
      Yellow : 2           |- Желтый цвет
      Green  : 3           |- Зеленый цвет
Messages ; Сообщения
  SetLight : 1             | Установить новый сигнал
    1 : 1
      Color : ColorType    |- Требуемый цвет сигнала
  Success : 2              | Команда контроллеру отработана
    1 : 0
  Fail : 3                 | Ошибка в работе контроллера (авария)
    1 : 0 

После отправки исполнителю команды (сообщения SetLight) следует учесть три возможных варианта дальнейшего развития событий:

  • исполнитель успешно отрабатывает запрос и светофор показывает нужный сигнал — ситуация, в которой получено ответное сообщение Success;
  • исполнитель обнаружил, что не может обработать запрос и сообщает об аварии контроллера — ситуация, в которой получено ответное сообщение Fail;
  • управляющая логика отправила запрос, но ничего не получила в ответ — ситуация, которую можно «поймать» с помощью тайм-аута нахождения в состоянии ожидания ответа от модуля-исполнителя.

Варианты 2 и 3 при выполнении задания считать аварийными. Обрабатывая эту ситуацию, следует остановить работу управляющей логики на паузу, отправив вышестоящему уровню (контролирующей логике) оповещение ProblemDetected. В состоянии паузы управляющая логика должна уметь воспринимать команды «выгрузиться» (сообщение Shutdown) и «возобновить работу» (сообщение Start). Изначально управляющая логика должна находиться в состоянии паузы.

Ниже приводится протокол управляющей логики:

Enumerations ; Перечислимые типы
Messages ; Сообщения
  Start : 1           | Включить цикл работы светофора
    1 : 0
  Shutdown : 2        | Выгрузить управляющую логику
    1 : 0
  ProblemDetected : 3 | Проблема в работе светофора
    1 : 0

При реализации модуля следует также использовать системные сообщения среды исполнения, определенные протоколом обмена ядра (Kernel).

Messages ; Сообщения
  TimeOut : 1                                 | Сообщение TimeOut. Рассылается машинами состояний в случае превышения допустимого интервала нахождения в определенном состоянии.
    1 : 0 ; Поколение 1, число аргументов 0
  ModuleFailedOnEvent : 2                     | Модуль не смог обработать сообщение
    1 : 3 ; Поколение 1, число аргументов 3
      EventKind : int                         | - Тип, события, при реакции на которое произошла ошибка
      ExceptionKind : string                  | - Тип ошибки (исключения)
      ExceptionMessage : string               | - Сообщение об ошибке
  Start : 3                                   | Команда инициализации
    1 : 0 ; Поколение 1, число аргументов 0
  Stop : 4                                    | Команда остановки
    1 : 0 ; Поколение 1, число аргументов 0
  StateChanged : 5                            | Событие, присылаемое в момент изменения состояния конечного автомата
    1 : 4 ; Поколение 1, число аргументов 4
      MachineName : string                    | - Имя конечного автомата, перешедшего в новое состояние
      OldState : string                       | - Старое состояние машины
      NewState : string                       | - Новое состояние машины
      Event : int                             | - Событие, активировавшее переход

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

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

Сообщение Kernel.Stop используется для оповещения модуля о выгрузке. Обычно получив такое сообщение модуль переходит в конечное состояние.

Сообщение Kernel.TimeOut может быть прислано ядром, если модуль находится в состоянии, отмеченном пометкой TimeOut=Значение (в миллисекундах). Если модуль находится в таком состоянии без переходов время, большее чем указанное значение, то он получит сообщение Kernel.TimeOut.

Сообщение Kernel.StateChanged отладочное информационное сообщение. В режиме отладки модуль рассылает такое сообщение при каждом изменении состояния конечного автомата. В сообщении зафиксированы старое и новое состояние, а также код события, активировавшего переход.

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

Модуль Адрес
Контролирующая логика "ControlLogic"
Модуль-исполнитель "LedDriver"

Требования к решению

Для успешного прохождения тестирования кандидат должен предоставить комплект материалов:

  • сценарии работы модуля управляющей логики;
  • чек-лист;
  • модель конечного автомата;
  • код;
  • автоматические тесты.

Комплект предоставляется в форме zip-архива с именем в формате <ФамилияИО>.zip (например: SukhoiDA.zip).

Задание можно выполнять как с применением Microsoft Visual C++ (под управлением ОС Windows), так и с применением компилятора gcc (под управлением ОС Linux CentOS 7 или ОС Ubuntu Linux).

Внимание!

Резюме и выполненное тестовое задание присылайте на электронный адрес n.prosalkova@uniteller.ru

Рекомендуемый порядок выполнения задания

  1. Изучить материалы тренинга (как минимум нужно понять конструкцию программных решений, что такое протокол и зачем он нужен, что такое конечный автомат и как он функционирует, как он изображается). Не прочитав эти материалы правильно задание сделать будет тяжело.
  2. Скачать материал для загрузки под нужную платформу (ссылки ниже);
  3. Изучить руководство состав пакета для загрузки (если у вас платформа Windows);
  4. Разработать сценарии использования и интерфейс модуля (протокол обмена);
  5. Разработать модель поведения модуля (конечный автомат);
  6. Разработать чек-лист (перечень аспектов, которые необходимо контролировать);
  7. Разработать скрипты автоматического тестирования;
  8. Разработать программный код;
  9. Собрать модуль и разместить его и его протокол в папке release для тестирования;
  10. Запустить автоматические тесты и убедиться, что модуль работает.

Критерий успеха

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

Появились вопросы, на которые нет ответа в материалах?

Если у кандидата появились какие-то вопросы, на которые не обнаружился ответ в материалах их можно задать через электронную почту n.prosalkova@uniteller.ru.