- Создайте приложение TextStatistics, анализирующее тексты на различных языках.
- Аргументы командной строки:
TextStatistics <локаль текста> <локаль вывода> <файл с текстом> <файл отчета>
- Поддерживаемые локали текста: все локали, имеющиеся в системе.
- Поддерживаемые локали вывода: русская и английская.
- Файлы имеют кодировку UTF-8.
- Подсчет статистики должен вестись по следующим категориям:
- предложения
- строки
- слова
- числа
- деньги
- даты
- Для каждой категории должна собираться следующая статистика:
- число вхождений
- число различных значений
- минимальное значение
- максимальное значение
- минимальная длина
- максимальная длина
- среднее значение/длина
- Отчет должен выводиться в формате HTML.
- Пример отчета:
- Аргументы командной строки:
Анализируемый файл: input.txt
Сводная статистика
Число предложений: 38
Число строк: 41
…
Статистика по словам
Число слов: 153 (95 уникальных)
Минимальное слово: HTML
Максимальное слово: языках
Минимальная длина слова: 1 (и)
Максимальная длина слова: 14 (Поддерживаемые)
Средняя длина слова: 10
Статистика по …
- При выполнении задания следует обратить внимание на:
- Декомпозицию сообщений для локализации
- Согласование предложений
- Добавьте к банковскому приложению возможность работы с физическими лицами.
- У физического лица (
Person
) можно запросить имя, фамилию и номер паспорта. - Локальные физические лица (
LocalPerson
) должны передаваться при помощи механизма сериализации. - Удаленные физические лица (
RemotePerson
) должны передаваться при помощи удаленных объектов. - Должна быть возможность поиска физического лица по номеру паспорта, с выбором типа возвращаемого лица.
- Должна быть возможность создания записи о физическом лице по его данным.
- У физического лица может быть несколько счетов, к которым должен предоставляться доступ.
- Счету физического лица с идентификатором subId должен соответствовать банковский счет с id вида passport:subId.
- Изменения, производимые со счетом в банке (создание и изменение баланса), должны быть видны всем соответствующим RemotePerson, и только тем LocalPerson, которые были созданы после этого изменения.
- Изменения в счетах, производимые через
RemotePerson
должны сразу применяться глобально, а призводимые черезLocalPerson
– только локально для этого конкретногоLocalPerson
.
- У физического лица (
- Напишите тесты, проверяющее вышеуказанное поведение.
- Реализуйте приложение, демонстрирующее работу с физическим лицами.
- Аргументы командной строки: имя, фамилия, номер паспорта физического лица, номер счета, изменение суммы счета.
- Если информация об указанном физическом лице отсутствует, то оно должно быть добавлено. В противном случае – должны быть проверены его данные.
- Если у физического лица отсутствует счет с указанным номером, то он создается с нулевым балансом.
- После обновления суммы счета, новый баланс должен выводиться на консоль.
-
Реализуйте клиент и сервер, взаимодействующие по UDP.
-
Класс
HelloUDPClient
должен отправлять запросы на сервер, принимать результаты и выводить их на консоль.- Аргументы командной строки:
- имя или ip-адрес компьютера, на котором запущен сервер;
- номер порта, на который отсылать запросы;
- префикс запросов (строка);
- число параллельных потоков запросов;
- число запросов в каждом потоке.
- Запросы должны одновременно отсылаться в указанном числе потоков. Каждый поток должен ожидать обработки своего запроса и выводить сам запрос и результат его обработки на консоль. Если запрос не был обработан, требуется послать его заного.
- Запросы должны формироваться по схеме
<префикс запросов><номер потока>_<номер запроса в потоке>
.
- Аргументы командной строки:
-
Класс
HelloUDPServer
должен принимать задания, отсылаемые классомHelloUDPClient
и отвечать на них.- Аргументы командной строки:
- номер порта, по которому будут приниматься запросы;
- число рабочих потоков, которые будут обрабатывать запросы.
- Ответом на запрос должно быть
Hello, <текст запроса>
. - Если сервер не успевает обрабатывать запросы, прием запросов может быть временно приостановлен.
- Аргументы командной строки:
-
Бонусный вариант. Реализация должна быть полностью неблокирующей.
- Клиент не должен создавать потоков.
- В реализации не должно быть активных ожиданий, в том числе через
Selector
.
Тестирование
- простой вариант:
- клиент:
info.kgeorgiy.java.advanced.hello client <полное имя класса>
- сервер:
info.kgeorgiy.java.advanced.hello server <полное имя класса>
- клиент:
- сложный вариант:
- клиент:
info.kgeorgiy.java.advanced.hello client-i18n <полное имя класса>
- сервер:
info.kgeorgiy.java.advanced.hello server-i18n <полное имя класса>
- клиент:
1. Напишите потокобезопасный класс WebCrawler
, который будет рекурсивно обходить сайты.
- Класс WebCrawler должен иметь конструктор:
public WebCrawler(Downloader downloader, int downloaders, int extractors, int perHost)
-
downloader
позволяет скачивать страницы и извлекать из них ссылки;downloaders
— максимальное число одновременно загружаемых страниц;extractors
— максимальное число страниц, из которых извлекаются ссылки;perHost
— максимальное число страниц, одновременно загружаемых c одного хоста. Для опредения хоста следует использовать методgetHost
классаURLUtils
из тестов.
- Класс
WebCrawler
должен реализовывать интерфейсCrawler
:
public interface Crawler extends AutoCloseable {
List<String> download(String url, int depth) throws IOException;
void close();
}
-
- Метод
download
должен рекурсивно обходить страницы, начиная с указанного URL на указанную глубину и возвращать список загруженных страниц и файлов. Например, если глубина равна 1, то должна быть загружена только указанная страница. Если глубина равна 2, то указанная страница и те страницы и файлы, на которые она ссылается и так далее. Этот метод может вызываться параллельно в нескольких потоках. - Загрузка и обработка страниц (извлечение ссылок) должна выполняться максимально параллельно, с учетом ограничений на число одновременно загружаемых страниц (в том числе с одного хоста) и страниц, с которых загружаются ссылки.
- Для распараллеливания разрешается создать до downloaders + extractors вспомогательных потоков.
- Загружать и/или извлекать ссылки из одной и той же страницы в рамках одного обхода (download) запрещается.
- Метод
close
должен завершать все вспомогательные потоки.
- Метод
- Для загрузки страниц должен применяться
Downloader
, передаваемый первым аргументом конструктора.
public interface Downloader {
public Document download(final String url) throws IOException;
}
-
- Метод
download
загружает документ по его адресу URL. - Документ позволяет получить ссылки по загруженной странице:
- Метод
public interface Document {
List<String> extractLinks() throws IOException;
}
-
- Ссылки, возвращаемые документом являются абсолютными и имеют схему
http
илиhttps
.
- Ссылки, возвращаемые документом являются абсолютными и имеют схему
- Должен быть реализован метод
main
, позволяющий запустить обход из командной строки- Командная строка:
WebCrawler url [depth [downloads [extractors [perHost]]]]
-
- Для загрузки страниц требуется использовать реализацию
CachingDownloader
из тестов.
- Для загрузки страниц требуется использовать реализацию
2. Версии задания
- Простая — можно не учитывать ограничения на число одновременных закачек с одного хоста (
perHost >= downloaders
). - Полная — требуется учитывать все ограничения.
- Бонусная — сделать параллельный обод в ширину.
Тестирование:
- простой вариант:
info.kgeorgiy.java.advanced.crawler easy <полное имя класса>
- сложный вариант:
info.kgeorgiy.java.advanced.crawler hard <полное имя класса>
- Напишите класс
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
могут одновременно обращаться несколько клиентов. - Задания на исполнение должны накапливаться в очереди и обрабатываться в порядке поступления.
- В реализации не должно быть активных ожиданий.
- Метод
- Модифицируйте класс
IterativeParallelism
так, чтобы он мог использоватьParallelMapper
.- Добавьте конструктор
IterativeParallelism(ParallelMapper)
- Методы класса должны делить работу на
threads
фрагментов и исполнять их при помощиParallelMapper
. - Должна быть возможность одновременного запуска и работы нескольких клиентов, использующих один
ParallelMapper
. - При наличии
ParallelMapper
самIterativeParallelism
новые потоки создавать не должен.
- Добавьте конструктор
Тестирование
- простой вариант:
info.kgeorgiy.java.advanced.mapper scalar <ParallelMapperImpl>,<IterativeParallelism>
- сложный вариант:
info.kgeorgiy.java.advanced.mapper list <ParallelMapperImpl>,<IterativeParallelism>
Внимание! Между полными именами классов ParallelMapperImpl
и IterativeParallelism
должна быть запятая и не должно быть пробелов.
- Реализуйте класс
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.
- Рекомендуется подумать, какое отношение к заданию имеют моноиды.
Тестирование
- простой вариант:
info.kgeorgiy.java.advanced.concurrent scalar <полное имя класса>
- сложный вариант:
info.kgeorgiy.java.advanced.concurrent list <полное имя класса>
- Создайте
.jar-файл
, содержащий скомпилированныйImplementor
и сопутствующие классы.
- Созданный
.jar-файл
должен запускаться командойjava -jar
. - Запускаемый
.jar-файл
должен принимать те же аргументы командной строки, что и классImplementor
.
- Модифицируйте
Implemetor
так, что бы при запуске с аргументами-jar имя-класса файл.jar
он генерировал.jar-файл
с реализацией соответствующего класса (интерфейса). - Для проверки, кроме исходного кода так же должны быть предъявлены:
скрипт для создания запускаемого
.jar-файла
, в том числе, исходный код манифеста; запускаемый .jar-файл. - Данное домашнее задание сдается только вместе с предыдущим. Предыдущее домашнее задание отдельно сдать будет нельзя.
- Сложная версия. Решение должно быть модуляризовано.
Класс должен реализовывать интерфейс
JarImpler
- Документируйте класс
Implementor
и сопутствующие классы с применениемJavadoc
.
- Должны быть документированы все классы и все члены классов, в том числе закрытые (
private
). - Документация должна генерироваться без предупреждений.
- Сгенерированная документация должна содержать корректные ссылки на классы стандартной библиотеки.
- Для проверки, кроме исходного кода так же должны быть предъявлены:
- скрипт для генерации документации;
- сгенерированная документация.
- Данное домашнее задание сдается только вместе с предыдущим. Предыдущее домашнее задание отдельно сдать будет нельзя.
Тестирование
- простой вариант:
info.kgeorgiy.java.advanced.implementor jar-interface <полное имя класса>
- сложный вариант:
info.kgeorgiy.java.advanced.implementor jar-class <полное имя класса>
- Реализуйте класс
Implementor
, который будет генерировать реализации классов и интерфейсов.
- Аргументы командной строки: полное имя класса/интерфейса, для которого требуется сгенерировать реализацию.
- В результате работы должен быть сгенерирован java-код класса с суффиксом
Impl
, расширяющий (реализующий) указанный класс (интерфейс). - Сгенерированный класс должен компилироваться без ошибок.
- Сгенерированный класс не должен быть абстрактным.
- Методы сгенерированного класса должны игнорировать свои аргументы и возвращать значения по умолчанию.
- В задании выделяются три уровня сложности:
- Простой —
Implementor
должен уметь реализовывать только интерфейсы (но не классы). Поддержка generics не требуется. - Сложный —
Implementor
должен уметь реализовывать и классы и интерфейсы. Поддержка generics не требуется. - Бонусный —
Implementor
должен уметь реализовывать generic-классы и интерфейсы. Сгенерированный код должен иметь корректные параметры типов и не порождатьUncheckedWarning
.
Класс должен реализовывать интерфейс
Impler
Тестирование
- простой вариант:
info.kgeorgiy.java.advanced.implementor interface <полное имя класса>
- сложный вариант:
info.kgeorgiy.java.advanced.implementor class <полное имя класса>
- Разработайте класс
StudentDB
, осуществляющий поиск по базе данных студентов.
- Класс
StudentDB
должен реализовывать интерфейсStudentQuery
(простая версия) илиStudentGroupQuery
(сложная версия). - Каждый метод должен состоять из ровно одного оператора. При этом длинные операторы надо разбивать на несколько строк.
- При выполнении задания следует обратить внимание на:
- Применение лямбда-выражений и потоков.
- Избавление от повторяющегося кода.
Тестирование
- простой вариант:
info.kgeorgiy.java.advanced.student StudentQuery <полное имя класса>
- сложный вариант:
info.kgeorgiy.java.advanced.student StudentGroupQuery <полное имя класса>
- Разработайте класс ArraySet, реализующие неизменяемое упорядоченное множество.
- Класс
ArraySet
должен реализовывать интерфейсSortedSet
(упрощенная версия) илиNavigableSet
(усложненная версия). - Все операции над множествами должны производиться с максимально возможной асимптотической эффективностью.
- При выполнении задания следует обратить внимание на:
- Применение стандартных коллекций.
- Избавление от повторяющегося кода.
Тестирование
- простой вариант:
info.kgeorgiy.java.advanced.arrayset SortedSet <полное имя класса>
- сложный вариант:
info.kgeorgiy.java.advanced.arrayset NavigableSet <полное имя класса>
-
Разработайте класс Walk, осуществляющий подсчет хеш-сумм файлов.
-
Формат запуска
java Walk <входной файл> <выходной файл>
-
Входной файл содержит список файлов, которые требуется обойти.
-
Выходной файл должен содержать по одной строке для каждого файла. Формат строки:
<шестнадцатеричная хеш-сумма> <путь к файлу>
-
Для подсчета хеш-суммы используйте алгоритм FNV.
-
Если при чтении файла возникают ошибки, укажите в качестве его хеш-суммы 00000000.
-
Кодировка входного и выходного файлов —
UTF-8
. -
Если родительская директория выходного файла не существует, то соответствующий путь надо создать.
-
Размеры файлов могут превышать размер оперативной памяти.
-
Пример
Входной файл
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
-
-
Усложненная версия:
-
Разработайте класс
RecursiveWalk
, осуществляющий подсчет хеш-сумм файлов в директориях -
Входной файл содержит список файлов и директорий, которые требуется обойти. Обход директорий осуществляется рекурсивно.
-
Пример
Входной файл
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
-
-
При выполнении задания следует обратить внимание на:
- Дизайн и обработку исключений, диагностику ошибок.
- Программа должна корректно завершаться даже в случае ошибки.
- Корректная работа с вводом-выводом.
- Отсутствие утечки ресурсов.
-
Требования к оформлению задания.
- Проверяется исходный код задания.
- Весь код должен находиться в пакете
ru.ifmo.rain.фамилия.walk
.
Для того, чтобы протестировать программу:
- Скачайте
- тесты
- и библиотеки к ним:
- Откомпилируйте решение домашнего задания
- Протестируйте домашнее задание
- Текущая директория должна:
- содержать все скачанные
.jar
файлы; - содержать скомпилированное решение;
- не содержать скомпилированные самостоятельно тесты.
- содержать все скачанные
- простой вариант:
java -cp . -p . -m info.kgeorgiy.java.advanced.walk Walk <полное имя класса>
- сложный вариант:
java -cp . -p . -m info.kgeorgiy.java.advanced.walk RecursiveWalk <полное имя класса>
- Текущая директория должна: