Домашние задания
- Разработайте класс
Grep, осуществляющий поиск подстрок к файлах. - Класс
Grepдолжен поддерживать следующую функциональность: 1. При запуске
java Grep строка1 строка2 ... строкаN
ищет в файлах указанные N подстрок.
2. При запуске
java Grep -
список искомых подстрок читается со стандартного ввода.
3. Поиск строк осуществляется во всех файлах текущей директории и всех поддиректориях (рекурсивно). Порядок, в котором обрабатываются файлы не важен.
4. Если строка файла содержит хотя бы одну из искомых подстрок, то на стандартный вывод должно быть выдано сообщение в формате:
относительный-путь-к-файлу: строка-файла
Например, если ищется подстрока hello и файл qqq/HelloWorld.java содержит
строку
System.out.println("hello, world!")
, то вывод должен содержать строку
qqq/HelloWorld.java: System.out.println("hello, world!")
5. Каждый файл читается не более одного раза.
6. Размеры файлов и строк в них могут превышать размер оперативной памяти.
7. Консольный ввод-вывод и поиск осуществляется в кодировке UTF-8.
8. Осущетсвляется поиск не более чем 1000 подстрок длиной до 1000 символов каждая.
- Усложненная версия: 1. Поиск строк должен осуществляться в кодировках UTF-8, KOI8-R, CP1251, CP866. 2. Должен поддерживаться поиск в бинарных файлах и файлах, содержащих фрагменты в разных кодировках. 3. Каждый файл читается не более одного раза.
- При выполнении задания следует обратить внимание на: * Дизайн и обработку исключений, диагностику ошибок. * Программа должна корректно завершаться даже в случае ошибки. * Корректная работа с вводом-выводом. * Отсутствие утечки ресурсов. * Отсутствие дублирования кода.
- Требования к оформлению задания.
* Проверяется исходный код задания.
* Весь код должен находиться в пакете
ru.ifmo.ctddev.фамилия.task1.
- Разработайте класс
ArraySet, реализующие неизменяемое упорядоченное множество. * КлассArraySetдолжен реализовывать интерфейсSortedSet(упрощенная версия) илиNavigableSet(усложненная версия). * Все операции над множествами должны производиться с максимально возможной асимптотической эффективностью. - При выполнении задания следует обратить внимание на: * Применение стандартных коллекций. * Избавления от boilerplate кода.
- Реализуйте класс
Implementor, который будет генерировать реализации классов и интерфейсов. * Аргументы командной строки: полное имя класса/интерфейса, для которого требуется сгенерировать реализацию. * В результате работы должен быть сгенерирован java-код класса с суффиксомImpl, расширяющий (реализующий) указанный класс (интерфейс). * Сгенерированный класс должен компилироваться без ошибок. * Сгенерированный класс не должен быть абстрактным. * Методы сгенерированного класса должны игнорировать свои аргументы и возвращать значения по-умолчанию. - В задании выделяются три уровня сложности:
* Простой --
Implementorдолжен уметь реализовывать только интерфейсы (но не классы). Поддержка Generics не требуется. * Сложный --Implementorдолжен уметь реализовывать и классы и интерфейсы. Поддержка Generics не требуется. * Бонусный --Implementorдолжен уметь реализовывать и Generic-классы и интерфейсы. Сгенерированный код должен иметь корректные параметры типов.
- Создайте
.jar-файл, содержащий скомпилированныйImplementorи сопутствующие классы. * Созданный.jar-файл должен запускаться командойjava -jar. * Запускаемый.jar-файл должен принимать те же аргументы командной строки, что и классImplementor. - Модифицируйте
Implemetorтак, что бы при запуске с аргументами-jar имя-класса файл.jarон генерировал.jar-файл с реализацией соответствующего класса (интерфейса). - Для проверки, кроме исходного кода так же должны быть предъявлены:
* скрипт для создания запускаемого
.jar-файла, в том числе, исходный код манифеста; * запускаемый.jar-файл.
- Документируйте класс
Implementorи сопутствующие классы с применением Javadoc. * Должны быть документированы все классы и все члены классов, в том числе закрытые (private). * Документация должна генерироваться без предупреждений. * Сгенерированная документация должна содержать корректные ссылки на классы стандартной библиотеки. - Для проверки, кроме исходного кода так же должны быть предъявлены: * скрипт для генерации документации; * сгенерированная документация.
- Реализуйте класс
Client, который будет генерировать задачи и исполнять их с применениемTaskRunner. * Клиент в бесконечном цикле должен генерировать задание, исполнять его при помощиTaskRunner, печатать результат исполнения на экран. * Разные клиенты должны иметь возможность использовать разныеTaskRunner'ы. * Должна быть возможность одновременного запуска и работы нескольких клиентов, использующих одинTaskRunner. - Реализуйте класс
TaskRunnerImpl, реализующий интерфейсTaskRunnerи исполняющий задачи в заданном числе потоков. * К одномуTaskRunnerImplмогут одновременно обращаться несколько клиентов. * Задания на исполнение должны накапливаться в очереди и обрабатываться в порядке поступления. * В реализации не должно быть активных ожиданий. - Общие интерфейсы: * Задача:
public interface Task<X, Y> {
X run(Y value);
}
* Исполнитель задач:
public interface TaskRunner {
<X, Y> X run(Task<X, Y>, Y value);
}
- Реализуйте цепочку генерации и исполнения заданий.
* Класс
Producerгенерирует задания и передает их на исполнение. * КлассWorkerисполняет задания и передает их на публикацию. * КлассPublisherпубликует результаты исполнения заданий. - Одновременно должны работать по 10
Producer'ов,Worker'ов иPublisher'ов. - Если
Worker'ы илиPublisher'ы не успевают обрабатывать задания, то генерация заданий должна приостанавливаться. - Пример задания для исполнения выбрать самостоятельно.