Разработайте класс Walk, осуществляющий подсчет хеш-сумм файлов.
- Формат запуска java Walk <входной файл> <выходной файл>
- Входной файл содержит список файлов, которые требуется обойти.
- Выходной файл должен содержать по одной строке для каждого файла. Формат строки: <шестнадцатеричная хеш-сумма> <путь к файлу>
- Для подсчета хеш-суммы используйте 64-битную версию алгоритма PJW.
- Если при чтении файла возникают ошибки, укажите в качестве его хеш-суммы 0000000000000000.
- Кодировка входного и выходного файлов — UTF-8.
- Если родительская директория выходного файла не существует, то соответствующий путь надо создать.
- Размеры файлов могут превышать размер оперативной памяти. Пример
Входной файл
samples/1
samples/12
samples/123
samples/1234
samples/1
samples/binary
samples/no-such-file
Выходной файл
0000000000000031 samples/1
0000000000003132 samples/12
0000000000313233 samples/123
0000000031323334 samples/1234
0000000000000031 samples/1
005501015554abff samples/binary
0000000000000000 samples/no-such-file
Разработайте класс RecursiveWalk, осуществляющий подсчет хеш-сумм файлов в директориях
- Входной файл содержит список файлов и директорий, которые требуется обойти.
- Обход директорий осуществляется рекурсивно. Пример
Входной файл
samples/binary
samples
samples/no-such-file
Выходной файл
005501015554abff samples/binary
0000000000000031 samples/1
0000000000003132 samples/12
0000000000313233 samples/123
0000000031323334 samples/1234
005501015554abff samples/binary
0000000000000000 samples/no-such-file
- Дизайн и обработку исключений, диагностику ошибок.
- Программа должна корректно завершаться даже в случае ошибки.
- Корректная работа с вводом-выводом.
- Отсутствие утечки ресурсов.
Разработайте класс ArraySet, реализующие неизменяемое упорядоченное множество.
- Класс ArraySet должен реализовывать интерфейс SortedSet (простой вариант) или NavigableSet (сложный вариант).
- Все операции над множествами должны производиться с максимально возможной асимптотической эффективностью.
- Применение стандартных коллекций.
- Избавление от повторяющегося кода.
Разработайте класс StudentDB, осуществляющий поиск по базе данных студентов.
- Класс StudentDB должен реализовывать интерфейс StudentQuery (простой вариант) или GroupQuery (сложный вариант).
- Каждый метод должен состоять из ровно одного оператора. При этом длинные операторы надо разбивать на несколько строк.
- Применение лямбда-выражений и потоков;
- Избавление от повторяющегося кода.
Реализуйте класс Implementor, который будет генерировать реализации классов и интерфейсов.
- Аргумент командной строки: полное имя класса/интерфейса, для которого требуется сгенерировать реализацию.
- В результате работы должен быть сгенерирован java-код класса с суффиксом Impl, расширяющий (реализующий) указанный класс (интерфейс).
- Сгенерированный класс должен компилироваться без ошибок.
- Сгенерированный класс не должен быть абстрактным.
- Методы сгенерированного класса должны игнорировать свои аргументы и возвращать значения по умолчанию.
- Простой — Implementor должен уметь реализовывать только интерфейсы (но не классы). Поддержка generics не требуется.
- Сложный — Implementor должен уметь реализовывать и классы, и интерфейсы. Поддержка generics не требуется.
- Бонусный — Implementor должен уметь реализовывать generic-классы и интерфейсы. Сгенерированный код должен иметь корректные параметры типов и не порождать UncheckedWarning.
Создайте .jar-файл, содержащий скомпилированный Implementor и сопутствующие классы.
- Созданный .jar-файл должен запускаться командой java -jar.
- Запускаемый .jar-файл должен принимать те же аргументы командной строки, что и класс Implementor.
- Модифицируйте Implemetor так, чтобы при запуске с аргументами -jar имя-класса файл.jar он генерировал .jar-файл с реализацией соответствующего класса (интерфейса).
- Cкрипт для создания запускаемого .jar-файла, в том числе, исходный код манифеста.
- Pапускаемый .jar-файл.
- Данное домашнее задание сдается только вместе с предыдущим. Предыдущее домашнее задание отдельно сдать будет нельзя.
Документируйте класс Implementor и сопутствующие классы с применением Javadoc.
- Должны быть документированы все классы и все члены классов, в том числе private.
- Документация должна генерироваться без предупреждений.
- Сгенерированная документация должна содержать корректные ссылки на классы стандартной библиотеки.
- Cкрипт для генерации документации;
- Cгенерированная документация.
- Данное домашнее задание сдается только вместе с предыдущим. Предыдущее домашнее задание отдельно сдать будет нельзя.
Реализуйте класс IterativeParallelism, который будет обрабатывать списки в несколько потоков.
- minimum(threads, list, comparator) — первый минимум;
- maximum(threads, list, comparator) — первый максимум;
- all(threads, list, predicate) — проверка, что все элементы списка удовлетворяют предикату;
- any(threads, list, predicate) — проверка, что существует элемент списка, удовлетворяющий предикату.
- filter(threads, list, predicate) — вернуть список, содержащий элементы удовлетворяющие предикату;
- map(threads, list, function) — вернуть список, содержащий результаты применения функции;
- join(threads, list) — конкатенация строковых представлений элементов списка.
Во все функции передается параметр threads — сколько потоков надо использовать при вычислении. Вы можете рассчитывать, что число потоков не велико. Не следует рассчитывать на то, что переданные компараторы, предикаты и функции работают быстро. При выполнении задания нельзя использовать Concurrency Utilities. Рекомендуется подумать, какое отношение к заданию имеют моноиды.
public interface ParallelMapper extends AutoCloseable {
<T, R> List<R> map(
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 могут одновременно обращаться несколько клиентов.
- Задания на исполнение должны накапливаться в очереди и обрабатываться в порядке поступления.
- В реализации не должно быть активных ожиданий.
- Добавьте конструктор IterativeParallelism(ParallelMapper)
- Методы класса должны делить работу на threads фрагментов и исполнять их при помощи ParallelMapper.
- При наличии ParallelMapper сам IterativeParallelism новые потоки создавать не должен.
- Должна быть возможность одновременного запуска и работы нескольких клиентов, использующих один ParallelMapper.
public WebCrawler(Downloader downloader, int downloaders, int extractors, int perHost)- downloader позволяет скачивать страницы и извлекать из них ссылки;
- downloaders — максимальное число одновременно загружаемых страниц;
- extractors — максимальное число страниц, из которых одновременно извлекаются ссылки;
- perHost — максимальное число страниц, одновременно загружаемых c одного хоста. Для определения хоста следует использовать метод getHost класса URLUtils из тестов.
public interface Crawler extends AutoCloseable {
Result download(String url, int depth);
void close();
}- Метод download должен рекурсивно обходить страницы, начиная с указанного URL на указанную глубину и возвращать список загруженных страниц и файлов. Например, если глубина равна 1, то должна быть загружена только указанная страница. Если глубина равна 2, то указанная страница и те страницы и файлы, на которые она ссылается и так далее. Этот метод может вызываться параллельно в нескольких потоках.
- Загрузка и обработка страниц (извлечение ссылок) должна выполняться максимально параллельно, с учетом ограничений на число одновременно загружаемых страниц (в том числе с одного хоста) и страниц, с которых загружаются ссылки.
- Для распараллеливания разрешается создать до downloaders + extractors вспомогательных потоков.
- Загружать и/или извлекать ссылки из одной и той же страницы в рамках одного обхода (download) запрещается.
- Метод close должен завершать все вспомогательные потоки.
public interface Downloader {
public Document download(final String url) throws IOException;
}- Метод download загружает документ по его адресу (URL).
- Документ позволяет получить ссылки по загруженной странице:
public interface Document {
List<String> extractLinks() throws IOException;
}Ссылки, возвращаемые документом, являются абсолютными и имеют схему http или https.
- Командная строка
WebCrawler url [depth [downloads [extractors [perHost]]]]
- Для загрузки страниц требуется использовать реализацию CachingDownloader из тестов.
- Простая — не требуется учитывать ограничения на число одновременных закачек с одного хоста (perHost >= downloaders).
- Полная — требуется учитывать все ограничения.
- Бонусная — сделать параллельный обод в ширину.
Класс HelloUDPClient должен отправлять запросы на сервер, принимать результаты и выводить их на консоль.
- имя или ip-адрес компьютера, на котором запущен сервер;
- номер порта, на который отсылать запросы;
- префикс запросов (строка);
- число параллельных потоков запросов;
- число запросов в каждом потоке.
Запросы должны одновременно отсылаться в указанном числе потоков. Каждый поток должен ожидать обработки своего запроса и выводить сам запрос и результат его обработки на консоль. Если запрос не был обработан, требуется послать его заново.
- Запросы должны формироваться по схеме <префикс запросов><номер потока>_<номер запроса в потоке>.
- Класс HelloUDPServer должен принимать задания, отсылаемые классом HelloUDPClient и отвечать на них.
- номер порта, по которому будут приниматься запросы;
- число рабочих потоков, которые будут обрабатывать запросы.
Ответом на запрос должно быть Hello, <текст запроса>. Если сервер не успевает обрабатывать запросы, прием запросов может быть временно приостановлен.
- У физического лица (Person) можно запросить имя, фамилию и номер паспорта.
- Локальные физические лица (LocalPerson) должны передаваться при помощи механизма сериализации.
- Удалённые физические лица (RemotePerson) должны передаваться при помощи удалённых объектов.
- Должна быть возможность поиска физического лица по номеру паспорта, с выбором типа возвращаемого лица.
- Должна быть возможность создания записи о физическом лице по его данным.
- У физического лица может быть несколько счетов, к которым должен предоставляться доступ.
- Счету физического лица с идентификатором subId должен соответствовать банковский счет с id вида passport:subId.
- Изменения, производимые со счетом в банке (создание и изменение баланса), должны быть видны всем соответствующим RemotePerson, и только тем LocalPerson, которые были созданы после этого изменения.
- Изменения в счетах, производимые через RemotePerson, должны сразу применяться глобально, а производимые через LocalPerson – только локально для этого конкретного LocalPerson.
- Аргументы командной строки: имя, фамилия, номер паспорта физического лица, номер счета, изменение суммы счета.
- Если информация об указанном физическом лице отсутствует, то оно должно быть добавлено. В противном случае – должны быть проверены его данные.
- Если у физического лица отсутствует счет с указанным номером, то он создается с нулевым балансом.
- После обновления суммы счета новый баланс должен выводиться на консоль.
- Для реализации тестов рекомендуется использовать JUnit (Tutorial). Множество примеров использования можно найти в тестах.
- Если вы знакомы с другим тестовым фреймворком (например, TestNG), то можете использовать его.
- Jar-файлы используемых библиотек надо класть в каталог lib вашего репозитория.
- Использовать самописные фреймворки и тесты запускаемые через main нельзя.
- Тесты не должны рассчитывать на наличие запущенного RMI Registry.
- Создайте класс BankTests, запускающий тесты.
- Создайте скрипт, запускающий BankTests и возвращающий код (статус) 0 в случае успеха и 1 в случае неудачи.
- Создайте скрипт, запускающий тесты с использованием стандартного подхода для вашего тестового фреймворка. Код возврата должен быть как в предыдущем пункте.
- Реализуйте клиент и сервер, взаимодействующие по UDP, используя только неблокирующий ввод-вывод.
- Класс HelloUDPNonblockingClient должен иметь функциональность аналогичную HelloUDPClient, но без создания новых потоков.
- Класс HelloUDPNonblockingServer должен иметь функциональность аналогичную HelloUDPServer, но все операции с сокетом должны производиться в одном потоке.
- В реализации не должно быть активных ожиданий, в том числе через Selector.
- Обратите внимание на выделение общего кода старой и новой реализации.
- Клиент и сервер могут перед началом работы выделить O(число потоков) памяти. Выделять дополнительную память во время работы запрещено.
- Аргументы командной строки:
- локаль текста,
- локаль вывода,
- файл с текстом,
- файл отчета.
- Поддерживаемые локали текста: все локали, имеющиеся в системе.
- Поддерживаемые локали вывода: русская и английская.
- Файлы имеют кодировку UTF-8.
- Подсчет статистики должен вестись по следующим категориям:
- предложения
- слова
- числа
- деньги
- даты
- Для каждой категории должна собираться следующая статистика:
- число вхождений
- число различных значений
- минимальное значение
- максимальное значение
- минимальная длина
- максимальная длина
- среднее значение/длина
Пример отчета:
Анализируемый файл "input.txt"
Сводная статистика
Число предложений: 43.
Число слов: 275.
Число чисел: 40.
Число сумм: 3.
Число дат: 3.
Статистика по предложениям
Число предложений: 43 (43 различных).
Минимальное предложение: "Аргументы командной строки: локаль текста, локаль вывода, файл с текстом, файл отчета.".
Максимальное предложение: "Число чисел: 40.".
Минимальная длина предложения: 13 ("Число дат: 3.").
Максимальная длина предложения: 211 ("GK: если сюда поставить реальное предложение, то процесс не сойдётся").
Средняя длина предложения: 55,465.
Статистика по словам
Число слов: 275 (157 различных).
Минимальное слово: "GK".
Максимальное слово: "языках".
Минимальная длина слова: 1 ("с").
Максимальная длина слова: 14 ("TextStatistics").
Средняя длина слова: 6,72.
Статистика по числам
Число чисел: 40 (24 различных).
Минимальное число: -12345,0.
Максимальное число: 12345,67.
Среднее число: 207,676.
Статистика по суммам денег
Число сумм: 3 (3 различных).
Минимальная сумма: 100,00 ₽.
Максимальная сумма: 345,67 ₽.
Средняя сумма: 222,83 ₽.
Статистика по датам
Число дат: 3 (3 различных).
Минимальная дата: 22 мая 2021 г..
Максимальная дата: 8 июн. 2021 г..
Средняя дата: 30 мая 2021 г..
- Вы можете рассчитывать на то, что весь текст помещается в память.
- При выполнении задания следует обратить внимание на:
- Декомпозицию сообщений для локализации
- Согласование сообщений по роду и числу
- Напишите тесты, проверяющее вышеуказанное поведение приложения.
- Для реализации тестов рекомендуется использовать JUnit (Tutorial). Множество примеров использования можно найти в тестах.
- Если вы знакомы с другим тестовым фреймворком (например, TestNG), то можете использовать его.
- Использовать самописные фреймворки и тесты запускаемые через main нельзя.