Skip to content

Instantly share code, notes, and snippets.

@MasterAler
Last active October 30, 2019 12:55
Show Gist options
  • Save MasterAler/547d5fe9f6b0cad92b9cbb7cfccdab4d to your computer and use it in GitHub Desktop.
Save MasterAler/547d5fe9f6b0cad92b9cbb7cfccdab4d to your computer and use it in GitHub Desktop.
Тестовое задание на позицию разработчика C++/Qt

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

Описанное ниже предлагается выполнить на C++ без использования сторонних библиотек, оформив в виде компилирующегося и запускающегося проекта для QMake/CMake на выбор. Использование Qt в основной части задания допускается, но не рекомендуется ограничиваться встроенными классами (очевидно, что тестовое окошко делать лучше именно на Qt, но свести всю многопоточность к вызову QtConcurrent::run было бы неправильно, что станет ясно из последующих уточнений). Проект должен быть совместим с компилятором, поддерживающим С++11, а также Qt 5.

Суть

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

Назовём классThreadPool, он должен уметь следующее:

  • Обладать методом для добавления задачи. Задачей считаются любые свободные функции и лямбда-выражения (ну, точнее, замыкания). Поддерживать методы произвольных классов в этом качестве не обязательно, на усмотрение реализующего.
  • Уметь быть запущенным и остановленным после запуска в произвольный момент времени. Запуск стартует потоки, которые (очевидно) начинают выполнять задачи. Остановка удаляет те задачи, выполнение которых ещё не началось, но не тормозит те, которые выполняются на момент остановки (потоки завершатся после того, как доделают свою текущую задачу).
  • Уметь управлять количеством потоков, которое задаётся до запуска пула. Предположим для простоты, что это число от 1 до 30. Задач может быть больше, чем рабочих потоков, те задачи, что ещё не обрабатываются, добавляются в очередь. Порядок получения задач рабочими потоками тот же, в котором задачи были добавлены.
  • Рабочие потоки после запуска циклично получают задачу из списка добавленных, после этого выполняют её, после этого берут следующую. Если задачи закончились -- спят, либо завершаются, на усмотрение реализующего. Главное то, что если количество добавленных к выполнению задач превышает максимальное количество потоков, все потоки должны делать что-то полезное.
  • Иметь возможность удалить ("отменить") конкретную задачу до того, как она начала выполняться. Удалить выполняющуюся задачу нельзя (для простоты).
  • В случае, если задача предполагает получение результата, должен присутствовать способ (сюрприз!) этот результат получить

Интерфейс

Дабы продемонстрировать, что пул потоков работает, предлагается реализовать окошко со следующими возможностями:

  • Пусть будет 3 типа задач, выполнение которых достаточно длительно, чтобы это заметить, а реализация не слишком трудоёмка. Предлагается выбрать вычисление факториала числа; вычисление N-ого числа Фибоначчи; вычисление двойного факториала числа
  • Должны быть кнопки "старт", "стоп", которые запускают и останавливают пул потоков
  • Должен быть способ задавать количество рабочих потоков
  • Должны быть способы ввести входные данные для задачи
  • Должен быть способ увидеть результат вычисления каждой задачи
  • Должна быть кнопка "добавить" и список/таблица/что-угодно-вообще для отображения статуса задач. Следует предусмотреть какой-то очевидный способ удалять любые стоящие в очереди задачи на своё усмотрение.
  • Для каждой задачи должны быть статусы "В очереди"/"Выполняется"/"Завершена", отражающие реальное состояние каждой задачи
  • Было бы неплохо, если бы где-то отражалось, что пул выполнил все задачи

Критерии качества реализации

Всё просто, код пула потоков должен быть неплох, а окошко ни в коем случае не должно ломаться. Сомнения на тему деталей реализации следует трактовать в свою пользу == в пользу минимальных усилий по реализации (надёжность важнее, чем изощрённость). Основное и очевидное:

  • Valgrind не должен находить утечек памяти
  • Никакое, даже самое внезапное, неожиданное и бессмысленное взаимодействие с окошком не должно приводить к его краху. Можно упростить для себя интерфейс с этой целью, но им всё равно должно быть возможно воспользоваться по назначению (пункт ниже).
  • Хочется, чтобы можно было выбрать количество потоков, создать мышкой 40-50-60 заданий, нажать "старт" и смотреть как что-то происходит. Потом нажать "стоп".
  • Стоит понимать, что задачи для выполнения потоками выбраны произвольны, не стоит привязывать реализацию пула потоков к их смыслу, на их месте могло быть что угодно.
  • Оформление (внешний вид) интерфейса принципиально никак не важно, но окошко с хаотично накиданными компонентами будет говорить о том, что автор не в состоянии нормально сделать даже такой простой концепт.
  • Ну и, конечно же, потоки в пуле должны корректно работать

На любые уточняющие вопросы можно получить ответ. GL;HF

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment