Домашнее задание 1. Обход файлов

  1. Разработайте класс Walk, осуществляющий подсчет хеш-сумм файлов.
    1. Формат запуска
      java Walk <входной файл> <выходной файл>
    2. Входной файл содержит список файлов, которые требуется обойти.
    3. Выходной файл должен содержать по одной строке для каждого файла. Формат строки:
      <шестнадцатеричная хеш-сумма> <путь к файлу>
    4. Для подсчета хеш-суммы используйте алгоритм FNV.
    5. Если при чтении файла возникают ошибки, укажите в качестве его хеш-суммы 00000000.
    6. Кодировка входного и выходного файлов — UTF-8.
    7. Если родительская директория выходного файла не существует, то соответствующий путь надо создать.
    8. Размеры файлов могут превышать размер оперативной памяти.
    9. Пример

      Входной файл

                              java/info/kgeorgiy/java/advanced/walk/samples/1
                              java/info/kgeorgiy/java/advanced/walk/samples/12
                              java/info/kgeorgiy/java/advanced/walk/samples/123
                              java/info/kgeorgiy/java/advanced/walk/samples/1234
                              java/info/kgeorgiy/java/advanced/walk/samples/1
                              java/info/kgeorgiy/java/advanced/walk/samples/binary
                              java/info/kgeorgiy/java/advanced/walk/samples/no-such-file
                          

      Выходной файл

                              050c5d2e java/info/kgeorgiy/java/advanced/walk/samples/1
                              2076af58 java/info/kgeorgiy/java/advanced/walk/samples/12
                              72d607bb java/info/kgeorgiy/java/advanced/walk/samples/123
                              81ee2b55 java/info/kgeorgiy/java/advanced/walk/samples/1234
                              050c5d2e java/info/kgeorgiy/java/advanced/walk/samples/1
                              8e8881c5 java/info/kgeorgiy/java/advanced/walk/samples/binary
                              00000000 java/info/kgeorgiy/java/advanced/walk/samples/no-such-file
                          
  2. Усложненная версия:
    1. Разработайте класс RecursiveWalk, осуществляющий подсчет хеш-сумм файлов в директориях
    2. Входной файл содержит список файлов и директорий, которые требуется обойти. Обход директорий осуществляется рекурсивно.
    3. Пример

      Входной файл

                              java/info/kgeorgiy/java/advanced/walk/samples/binary
                              java/info/kgeorgiy/java/advanced/walk/samples
                          

      Выходной файл

                              8e8881c5 java/info/kgeorgiy/java/advanced/walk/samples/binary
                              050c5d2e java/info/kgeorgiy/java/advanced/walk/samples/1
                              2076af58 java/info/kgeorgiy/java/advanced/walk/samples/12
                              72d607bb java/info/kgeorgiy/java/advanced/walk/samples/123
                              81ee2b55 java/info/kgeorgiy/java/advanced/walk/samples/1234
                              8e8881c5 java/info/kgeorgiy/java/advanced/walk/samples/binary
                          
  3. При выполнении задания следует обратить внимание на:
    • Дизайн и обработку исключений, диагностику ошибок.
    • Программа должна корректно завершаться даже в случае ошибки.
    • Корректная работа с вводом-выводом.
    • Отсутствие утечки ресурсов.
  4. Требования к оформлению задания.
    • Проверяется исходный код задания.
    • Весь код должен находиться в пакете ru.ifmo.rain.фамилия.walk.

Тесты к домашним заданиям

Домашнее задание 2. Множество на массиве

  1. Разработайте класс ArraySet, реализующие неизменяемое упорядоченное множество.
    • Класс ArraySet должен реализовывать интерфейс SortedSet (упрощенная версия) или NavigableSet (усложненная версия).
    • Все операции над множествами должны производиться с максимально возможной асимптотической эффективностью.
  2. При выполнении задания следует обратить внимание на:
    • Применение стандартных коллекций.
    • Избавление от повторяющегося кода.

Домашнее задание 3. Студенты

  1. Разработайте класс StudentDB, осуществляющий поиск по базе данных студентов.
    • Класс StudentDB должен реализовывать интерфейс StudentQuery (простая версия) или StudentGroupQuery (сложная версия).
    • Каждый метод должен состоять из ровно одного оператора. При этом длинные операторы надо разбивать на несколько строк.
  2. При выполнении задания следует обратить внимание на:
    • Применение лямбда-выражений и потоков.
    • Избавление от повторяющегося кода.

Домашнее задание 4. Implementor

  1. Реализуйте класс Implementor, который будет генерировать реализации классов и интерфейсов.
    • Аргументы командной строки: полное имя класса/интерфейса, для которого требуется сгенерировать реализацию.
    • В результате работы должен быть сгенерирован java-код класса с суффиксом Impl, расширяющий (реализующий) указанный класс (интерфейс).
    • Сгенерированный класс должен компилироваться без ошибок.
    • Сгенерированный класс не должен быть абстрактным.
    • Методы сгенерированного класса должны игнорировать свои аргументы и возвращать значения по умолчанию.
  2. В задании выделяются три уровня сложности:
    • ПростойImplementor должен уметь реализовывать только интерфейсы (но не классы). Поддержка generics не требуется.
    • СложныйImplementor должен уметь реализовывать и классы и интерфейсы. Поддержка generics не требуется.
    • БонусныйImplementor должен уметь реализовывать generic-классы и интерфейсы. Сгенерированный код должен иметь корректные параметры типов и не порождать UncheckedWarning.

Домашнее задание 5. Jar Implementor

  1. Создайте .jar-файл, содержащий скомпилированный Implementor и сопутствующие классы.
    • Созданный .jar-файл должен запускаться командой java -jar.
    • Запускаемый .jar-файл должен принимать те же аргументы командной строки, что и класс Implementor.
  2. Модифицируйте Implemetor так, что бы при запуске с аргументами -jar имя-класса файл.jar он генерировал .jar-файл с реализацией соответствующего класса (интерфейса).
  3. Для проверки, кроме исходного кода так же должны быть предъявлены:
    • скрипт для создания запускаемого .jar-файла, в том числе, исходный код манифеста;
    • запускаемый .jar-файл.
  4. Данное домашнее задание сдается только вместе с предыдущим. Предыдущее домашнее задание отдельно сдать будет нельзя.
  5. Сложная версия. Решение должно быть модуляризовано.

Домашнее задание 6. Javadoc

  1. Документируйте класс Implementor и сопутствующие классы с применением Javadoc.
    • Должны быть документированы все классы и все члены классов, в том числе закрытые (private).
    • Документация должна генерироваться без предупреждений.
    • Сгенерированная документация должна содержать корректные ссылки на классы стандартной библиотеки.
  2. Для проверки, кроме исходного кода так же должны быть предъявлены:
    • скрипт для генерации документации;
    • сгенерированная документация.
  3. Данное домашнее задание сдается только вместе с предыдущим. Предыдущее домашнее задание отдельно сдать будет нельзя.

Домашнее задание 7. Итеративный параллелизм

  1. Реализуйте класс IterativeParallelism, который будет обрабатывать списки в несколько потоков.
  2. В простом варианте должны быть реализованы следующие методы:
    • minimum(threads, list, comparator) — первый минимум;
    • maximum(threads, list, comparator) — первый максимум;
    • all(threads, list, predicate) — проверка, что все элементы списка удовлетворяют предикату;
    • any(threads, list, predicate) — проверка, что существует элемент списка, удовлетворяющий предикату.
  3. В сложном варианте должны быть дополнительно реализованы следующие методы:
    • filter(threads, list, predicate) — вернуть список, содержащий элементы удовлетворяющие предикату;
    • map(threads, list, function) — вернуть список, содержащий результаты применения функции;
    • join(threads, list) — конкатенация строковых представлений элементов списка.
  4. Во все функции передается параметр threads — сколько потоков надо использовать при вычислении. Вы можете рассчитывать, что число потоков не велико.
  5. Не следует рассчитывать на то, что переданные компараторы, предикаты и функции работают быстро.
  6. При выполнении задания нельзя использовать Concurrency Utilities.
  7. Рекомендуется подумать, какое отношение к заданию имеют моноиды.

Домашнее задание 8. Параллельный запуск

  1. Напишите класс ParallelMapperImpl, реализующий интерфейс ParallelMapper.
    public interface ParallelMapper extends AutoCloseable {
        <T, R> List<R> run(
            Function<? super T, ? extends R> f, 
            List<? extends T> args
        ) throws InterruptedException;
    
        @Override
        void close() throws InterruptedException;
    }
    
    • Метод run должен параллельно вычислять функцию f на каждом из указанных аргументов (args).
    • Метод close должен останавливать все рабочие потоки.
    • Конструктор ParallelMapperImpl(int threads) создает threads рабочих потоков, которые могут быть использованы для распараллеливания.
    • К одному ParallelMapperImpl могут одновременно обращаться несколько клиентов.
    • Задания на исполнение должны накапливаться в очереди и обрабатываться в порядке поступления.
    • В реализации не должно быть активных ожиданий.
  2. Модифицируйте касс IterativeParallelism так, чтобы он мог использовать ParallelMapper.
    • Добавьте конструктор IterativeParallelism(ParallelMapper)
    • Методы класса должны делить работу на threads фрагментов и исполнять их при помощи ParallelMapper.
    • Должна быть возможность одновременного запуска и работы нескольких клиентов, использующих один ParallelMapper.
    • При наличии ParallelMapper сам IterativeParallelism новые потоки создавать не должен.