Skip to content

nikita-mamro/SPBU_Homework_Sem3

Repository files navigation

  • Домашняя работа 1. 06.09.19

    • Реализовать следующий интерфейс, представляющий ленивое вычисление:

         public interface ILazy<T> 
         {
              T Get();  
         }

      Объект Lazy создаётся на основе вычисления (представляемого объектом Func)

      • Первый вызов Get() вызывает вычисление и возвращает результат
      • Повторные вызовы Get() возвращают тот же объект, что и первый вызов
      • Вычисление должно запускаться не более одного раза

      Создавать объекты надо не вручную, а с помощью класса LazyFactory, который должен иметь два метода с сигнатурами наподобие

      public static Lazy<T> Create...Lazy<T>(Func<T> supplier)

      возвращающих две разные реализации ILazy:

      • Простая версия с гарантией корректной работы в однопоточном режиме (без синхронизации)

      • Гарантия корректной работы в многопоточном режиме

        • При этом она должна по возможности минимизировать число необходимых синхронизаций (если значение уже вычислено, не должно быть блокировок) supplier вправе вернуть null
      • Библиотечным Lazy пользоваться, естественно, нельзя Нужно:

      • CI, на котором проходят ваши тесты

      • Тесты

        • Однопоточные, на разные хорошие и плохие случаи
        • Многопоточные, на наличие гонок

      Lazy

  • Домашняя работа 2. 20.09.19

    • Реализовать простой пул задач (наподобие https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool?view=netframework-4.8 + https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskfactory?view=netframework-4.8) с фиксированным числом потоков (число задается в конструкторе))

      • При создании объекта MyThreadPool в нем должно начать работу n потоков

      • У каждого потока есть два состояния: ожидание задачи / выполнение задачи

      • Задача — вычисление некоторого значения, описывается в виде Func

      • При добавлении задачи, если в пуле есть ожидающий поток, то он должен приступить к ее исполнению. Иначе задача будет ожидать исполнения, пока не освободится какой-нибудь поток

      • Задачи, принятые к исполнению, представлены в виде объектов интерфейса IMyTask

      • Метод Shutdown должен завершить работу потоков. Завершение работы коллаборативное, с использованием CancellationToken — уже запущенные задачи не прерываются, но новые задачи не принимаются на исполнение потоками из пула.

        • Возможны два варианта решения --- дать всем задачам, которые уже попали в очередь, досчитаться, либо выбросить исключение во все ожидающие завершения задачи потоки
      • IMyTask

        • Свойство IsCompleted возвращает true, если задача выполнена
        • Свойство Result возвращает результат выполнения задачи
        • В случае, если соответствующая задаче функция завершилась с исключением, этот метод должен завершиться с исключением AggregateException, содержащим внутри себя исключение, вызвавшее проблему
        • Если результат еще не вычислен, метод ожидает его и возвращает полученное значение, блокируя вызвавший его поток
        • Метод ContinueWith — принимает объект типа Func<TResult, TNewResult>, который может быть применен к результату данной задачи X и возвращает новую задачу Y, принятую к исполнению
        • Новая задача будет исполнена не ранее, чем завершится исходная
        • В качестве аргумента объекту Func будет передан результат исходной задачи, и все Y должны исполняться на общих основаниях (т.е. должны разделяться между потоками пула)
        • Метод ContinueWith может быть вызван несколько раз
        • Метод ContinueWith не должен блокировать работу потока, если результат задачи X ещё не вычислен
        • ContinueWith должен быть согласован с Shutdown --- принятая как ContinueWith задача должна либо досчитаться, либо бросить исключение ожидающему её потоку.
      • При этом:

        • В данной работе запрещено использование TPL, PLINQ и библиотечных классов Task и ThreadPool.
        • Все интерфейсные методы должны быть потокобезопасны
        • Для каждого базового сценария использования должен быть написан несложный тест
        • Также должен быть написан тест, проверяющий, что в пуле действительно не менее n потоков

      Подсказка: задачи могут быть разных типов (например, можно var myTask = myThreadPool.Submit(() => 2 * 2).ContinueWith(x => x.ToString());). Хранить такие задачи в очереди можно, обернув их в Action.

      MyThreadPool

  • Домашняя работа 3. 04.10.19

    • Требуется реализовать сервер, обрабатывающий два запроса.

      • List — листинг файлов в директории на сервере
      • Get — скачивание файла с сервера

      И клиент, позволяющий исполнять указанные запросы.

      • List, формат запроса:

        • <1: Int> <path: String>
        • path — путь к директории относительно того места, где запущен сервер Например, "1 ./Test/Files".
      • Формат ответа:

        • <size: Int> (<name: String> <isDir: Boolean>)*,
        • size — количество файлов и папок в директории
        • name — название файла или папки
        • isDir — флаг, принимающий значение True для директорий Например, "2 ./Test/files/file1.txt false ./Test/files/directory true"

        Если директории не существует, сервер посылает ответ с size = -1

      • Get, формат запроса:

        • <2: Int> <path: String>
        • path — путь к файлу
      • Формат ответа:

        • <size: Long> <content: Bytes>,
        • size — размер файла,
        • content — его содержимое

        Если файла не существует, сервер посылает ответ с size = -1

      Обратите внимание на строгое следование протоколу. Сервер любого правильного решения должен уметь взаимодействовать с клиентом любого другого правильного решения.

      SimpleFTP

  • Домашняя работа 4. 25.10.19

    • Реализовать command-line приложение, принимающее на вход путь и выполняющее запуск тестов, находящихся во всех сборках, расположенных по этому пути:

      • тестом считается метод, помеченный аннотацией Test
        • у аннотации может быть два аргумента -- Expected для исключения, Ignore (со строковым параметром) -- для отмены запуска и указания причины
      • перед и после запуска каждого теста в классе должны запускаться методы, помеченные аннотациями Before и After
      • перед и после запуска тестов в классе должны запускаться методы, помеченные аннотациями BeforeClass и AfterClass
        • BeforeClass и AfterClass должны быть статическими методами, при их запуске объект создаваться не должен

      Тесты должны запускаться возможно более параллельно.

      Приложение должно выводить в стандартный поток вывода отчет:

      • о результате и времени выполнения прошедших и упавших тестов
      • о причине отключенных тестов

      Юнит-тесты на систему тестирования обязательны (при этом они должны быть написаны не на ней самой, а на чём-то более отлаженном, типа NUnit).

      MyNUnit

  • Домашняя работа 5. 22.11.19

    • Сделать на WPF GUI для FTP-клиента из домашней работы 5.

      Нужно:

      • иметь возможность задать адрес и порт сервера;

      • при подключении получить список файлов и подпапок папки, на которую "смотрит" сервер;

      • иметь возможность перемещаться по папкам (переходить в подпапки и возвращаться на уровень выше, если он есть --- выходить выше "корневой" папки нельзя);

      • иметь возможность указать папку в файловой системе клиента для скачивания файлов;

      • иметь возможность скачать один файл или все файлы в текущей папке сразу;

        • при этом скачивание нескольких файлов должно происходить параллельно, в клиенте должен как-нибудь отображаться статус файла --- скачивается или уже скачан. При этом:
      • надо активно пользоваться Data Binding и паттерном Model-View-ViewModel;

      • юнит-тесты на GUI можно не писать, но вся нетривиальная функциональность "бэкенда" должна быть протестирована.

      GUIforFTP

About

Зомашнее дазание на 3-ий семестр

Topics

Resources

License

Stars

Watchers

Forks

Languages