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 было бы неправильно, что станет ясно из последующих уточнений). Проект должен быть совместим с MSVC 2015+/GCC 5.4.x+/Qt 5.6+

Суть

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

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

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

Интерфейс

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

  • Пусть будет 3 типа задач, выполнение которых достаточно длительно, чтобы это заметить, а реализация не слишком трудоёмка. Предлагается выбрать копирование файла из одного места в другое (файлы могут быть 300 - 1000Мб); вычисление 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