From a9155f52f8303c6936e2443210b228141216ddc6 Mon Sep 17 00:00:00 2001 From: Aleksandr Kormushin Date: Tue, 14 Oct 2014 12:56:06 +0400 Subject: [PATCH] Merged common files from master --- .gitignore | 5 +- .travis.yml | 4 + README.md | 11 +- build.xml | 5 +- github-workflow.md | 2 +- src/ru/fizteh/fivt/storage/strings/Table.java | 75 +++++++++++ .../fivt/storage/strings/TableProvider.java | 35 +++++ .../storage/strings/TableProviderFactory.java | 20 +++ tasks/01-Calculator.md | 21 +++ tasks/02-ExternalListRank.md | 28 ++++ tasks/02-FileMap.md | 120 ++++++++++++++++++ tasks/03-MultiFileHashMap.md | 105 +++++++++++++++ tasks/04-JUnit.md | 62 +++++++++ 13 files changed, 487 insertions(+), 6 deletions(-) create mode 100644 .travis.yml create mode 100644 src/ru/fizteh/fivt/storage/strings/Table.java create mode 100644 src/ru/fizteh/fivt/storage/strings/TableProvider.java create mode 100644 src/ru/fizteh/fivt/storage/strings/TableProviderFactory.java create mode 100644 tasks/01-Calculator.md create mode 100644 tasks/02-ExternalListRank.md create mode 100644 tasks/02-FileMap.md create mode 100644 tasks/03-MultiFileHashMap.md create mode 100644 tasks/04-JUnit.md diff --git a/.gitignore b/.gitignore index b84864001..779ffad30 100644 --- a/.gitignore +++ b/.gitignore @@ -4,11 +4,9 @@ .mtj.tmp/ # Package Files # -*.jar *.war *.ear -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* .idea @@ -19,3 +17,6 @@ jars .classpath .project + +.settings +.checkstyle diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..2b7b2ff42 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: java +jdk: + - oraclejdk8 +script: ant checkstyle \ No newline at end of file diff --git a/README.md b/README.md index 718085524..46bc67a28 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## Семинары В папке [tasks](tasks) находятся описания заданий на семинары. Для написания программ необходимо руководствоваться [соглашениями -по оформлению кода](http://www.oracle.com/technetwork/java/codeconv-138413.html) +по оформлению кода](http://www.oracle.com/technetwork/java/codeconvtoc-136057.html) от Oracle (Code Conventions). В документе [github-workflow](github-workflow.md) описаны @@ -14,9 +14,18 @@ [checkstyle](http://checkstyle.sourceforge.net/), которая проверяет код на соответствие Code Conventions. +## Лекции +1. [Java, JVM, примитивные типы](https://yadi.sk/d/_ZgbGf9NbXraZ) +2. [Object, String, исключения](https://yadi.sk/d/MCu6krbtbXrgZ) +3. [IO Stream, инициализация объектов, enum](https://yadi.sk/d/MinWJhG0bteEr) +4. [Лямбды, аннотации, обобщения, коллекции](https://yadi.sk/d/hxkoP81rbteTp) + ## Список литературы * Брюс Эккель — Философия Java (Thinking in Java) * Brian Goetz — Java Concurrency in Practive (продвинутая книжка по многопоточности в Java) * [Спецификации по JVM и JLS](http://docs.oracle.com/javase/specs/index.html) * [Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html) + +## Успеваемость +[Таблица на Google Docs](https://docs.google.com/spreadsheet/ccc?key=0Ag7dwrMmZBKedGk1Q1RfSXh1RzZyeEJhaE94dW1CaGc&usp=sharing) diff --git a/build.xml b/build.xml index 867e507fd..f5898b1a7 100644 --- a/build.xml +++ b/build.xml @@ -34,13 +34,14 @@ - + + diff --git a/github-workflow.md b/github-workflow.md index e1ae4cab3..41a464c2c 100644 --- a/github-workflow.md +++ b/github-workflow.md @@ -13,4 +13,4 @@ Чтобы сократить количество итераций на проверку задания, полезно самостоятельно удостовериться, что Code Conventions соблюдены. Для этого нужно запустить сборку проекта с помощью ```ant checkstyle```. Вместо этого можно поставить -соответствующий плагин в IDE и настроить этот плагин на конфигурационный файл ```bin/checkstyle-rules.xml```. +соответствующий плагин в IDE и настроить этот плагин на конфигурационный файл ```lib/checkstyle-rules.xml```. diff --git a/src/ru/fizteh/fivt/storage/strings/Table.java b/src/ru/fizteh/fivt/storage/strings/Table.java new file mode 100644 index 000000000..dd0fb75cb --- /dev/null +++ b/src/ru/fizteh/fivt/storage/strings/Table.java @@ -0,0 +1,75 @@ +package ru.fizteh.fivt.storage.strings; + +import java.util.List; + +/** + * @author Fedor Lavrentyev + * @author Dmitriy Komanov + */ +public interface Table { + + /** + * Возвращает название базы данных. + */ + String getName(); + + /** + * Получает значение по указанному ключу. + * + * @param key Ключ. + * @return Значение. Если не найдено, возвращает null. + * + * @throws IllegalArgumentException Если значение параметра key является null. + */ + String get(String key); + + /** + * Устанавливает значение по указанному ключу. + * + * @param key Ключ. + * @param value Значение. + * @return Значение, которое было записано по этому ключу ранее. Если ранее значения не было записано, + * возвращает null. + * + * @throws IllegalArgumentException Если значение параметров key или value является null. + */ + String put(String key, String value); + + /** + * Удаляет значение по указанному ключу. + * + * @param key Ключ. + * @return Значение. Если не найдено, возвращает null. + * + * @throws IllegalArgumentException Если значение параметра key является null. + */ + String remove(String key); + + /** + * Возвращает количество ключей в таблице. + * + * @return Количество ключей в таблице. + */ + int size(); + + /** + * Выполняет фиксацию изменений. + * + * @return Количество сохранённых ключей. + */ + int commit(); + + /** + * Выполняет откат изменений с момента последней фиксации. + * + * @return Количество отменённых ключей. + */ + int rollback(); + + /** + * Выводит список ключей таблицы + * + * @return Список ключей. + */ + List list(); +} diff --git a/src/ru/fizteh/fivt/storage/strings/TableProvider.java b/src/ru/fizteh/fivt/storage/strings/TableProvider.java new file mode 100644 index 000000000..17d92d9b1 --- /dev/null +++ b/src/ru/fizteh/fivt/storage/strings/TableProvider.java @@ -0,0 +1,35 @@ +package ru.fizteh.fivt.storage.strings; + +/** + * @author Fedor Lavrentyev + * @author Dmitriy Komanov + */ +public interface TableProvider { + + /** + * Возвращает таблицу с указанным названием. + * + * @param name Название таблицы. + * @return Объект, представляющий таблицу. Если таблицы с указанным именем не существует, возвращает null. + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. + */ + Table getTable(String name); + + /** + * Создаёт таблицу с указанным названием. + * + * @param name Название таблицы. + * @return Объект, представляющий таблицу. Если таблица уже существует, возвращает null. + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. + */ + Table createTable(String name); + + /** + * Удаляет таблицу с указанным названием. + * + * @param name Название таблицы. + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. + * @throws IllegalStateException Если таблицы с указанным названием не существует. + */ + void removeTable(String name); +} diff --git a/src/ru/fizteh/fivt/storage/strings/TableProviderFactory.java b/src/ru/fizteh/fivt/storage/strings/TableProviderFactory.java new file mode 100644 index 000000000..c4a8fdc11 --- /dev/null +++ b/src/ru/fizteh/fivt/storage/strings/TableProviderFactory.java @@ -0,0 +1,20 @@ +package ru.fizteh.fivt.storage.strings; + +/** + * Представляет интерфейс для создание экземпляров {@link TableProvider}. Предполагается, что реализация интерфейса + * фабрики будет иметь публичный конструктор без параметров. + * + * @author Fedor Lavrentyev + * @author Dmitriy Komanov + */ +public interface TableProviderFactory { + + /** + * Возвращает объект для работы с базой данных. + * + * @param dir Директория с файлами базы данных. + * @return Объект для работы с базой данных. + * @throws IllegalArgumentException Если значение директории null или имеет недопустимое значение. + */ + TableProvider create(String dir); +} diff --git a/tasks/01-Calculator.md b/tasks/01-Calculator.md new file mode 100644 index 000000000..ab10812a9 --- /dev/null +++ b/tasks/01-Calculator.md @@ -0,0 +1,21 @@ +## Калькулятор +Задание - альтернатива Shell. Не нужно делать оба. Только для группы 394. + +Консольное приложение, на вход принимает выражение как параметр : +```bash +java Calculator "-(3 + 5.5) * 2 - 20/(15 - 5)" +``` + +Результат работы приложения -- результат выражения: +``` +-19 +``` + +Поддерживаемые операции: ```+ - * /```. Приоритет операций -- математический +(скобки, потом унарное отрицание, потом умножение/деление, потом сложение/вычитание). + +В случае неправильных входных данных приложение должно вывести понятное описание +ошибки. + +Ограничения: не использовать встроенные скриптовые движки и кодо- или байткод генерацию. +Одним словом, парсить вручную. diff --git a/tasks/02-ExternalListRank.md b/tasks/02-ExternalListRank.md new file mode 100644 index 000000000..a3a250d9a --- /dev/null +++ b/tasks/02-ExternalListRank.md @@ -0,0 +1,28 @@ +## Внешняя сортировка связанного списка +Задание - альтернатива FileMap. Не нужно делать оба. Только для группы 394. + +Консольное приложение, на вход принимает имя входного и выходного файлов: +```bash +java ExternalListRank +``` + +На входе файл с заданным односвязным списком. Все вершины пронумерованы от 1 до n. Каждая строчка имеет формат: вершина<пробел>следующая вершина. Последняя вершина имеет вид <номер вершины><пробел>0. +Например: +``` +1 5 +2 3 +5 0 +4 1 +3 4 +``` + +На выходе должен быть файл, в котором вершины идут в порядке следования в списке: +``` +2 3 +3 4 +4 1 +1 5 +5 0 +``` + +Ограничения: программа должна работать с памятью -Xmx64M и уметь сортировать файлы до 1Гб. Должна делать O(nlogn) операций ввода/вывода во внешнюю память. diff --git a/tasks/02-FileMap.md b/tasks/02-FileMap.md new file mode 100644 index 000000000..a03be34f1 --- /dev/null +++ b/tasks/02-FileMap.md @@ -0,0 +1,120 @@ +## FileMap + +Консольное приложение, которое работает с файлом-БД. Путь к файлу задаётся системным свойством ```System.getProperty("db.file")```. Из командной строки надо запускать приложение так: ```java -Ddb.file=/home/student/db.dat ru.fizteh.fivt.students.test.DbMain```. + +Приложение должно работать как в интерактивном режиме, так и в пакетном (см. задание Shell). + +Приложение должно поддерживать следующие команды с фиксированным выводом: + +### put +``` +put key value +``` + +Если значение новое, то вывод: +``` +new +``` + +Если значение затирает существующее: +``` +overwrite +old value +``` + +### get +``` +get key +``` + +Если значение есть: +``` +found +value +``` + +Если значения нет: +``` +not found +``` + +### remove +``` +remove key +``` + +Если значение удалено: +``` +removed +``` + +Если значения нет: +``` +not found +``` + +### list +``` +list +``` + +Выводит список всех ключей или пустую строку, если ничего нет: +``` +key1, key2, kеy3 +``` + +### exit +``` +exit +``` + +### Вариант 1 +Данные лежат в бинарном файле следующего формата: +``` +Длина ключа 1, ключ 1, длина значения 1, значение 1, +Длина ключа 2, ключ 2, длина значения 2, значение 2, +... +``` + +Форматы длин - целые числа в машинном представлении, 4 байта. +Формат ключа и значения - байты, полученные из строки в кодировке UTF-8. + +#### Пример +``` +add key value +add ключ значение +``` + +В файле должно оказаться (в бинарном виде): +``` +00000008 d0bad0bb d18ed187 00000010 +d0b7d0bd d0b0d187 d0b5d0bd d0b8d0b5 +00000003 6b657900 00000576 616c7565 +``` + +### Вариант 2 +Данные лежат в бинарном файле следующего формата: +``` +Ключ 1, \0, смещение значения 1, +Ключ 2, \0, смещение значения 2, +... +Ключ N, \0, смещение значения N, +значение 1, значение 2, ... +``` + +Форматы смещений - целые числа в машинном представлении, 4 байта. +Формат ключа - байты, полученные из строки в кодировке UTF-8. Оканчивается ключ нулевым символом (\0). +Между списком смещений и первым значением нет разрыва. + +#### Пример +``` +add key value +add ключ значение +``` + +В файле должно оказаться (в бинарном виде): +``` +d0bad0bb d18ed187 00000000 156b6579 +00000000 25d0b7d0 bdd0b0d1 87d0b5d0 +bdd0b8d0 b576616c 7565 +``` diff --git a/tasks/03-MultiFileHashMap.md b/tasks/03-MultiFileHashMap.md new file mode 100644 index 000000000..19b9acb6d --- /dev/null +++ b/tasks/03-MultiFileHashMap.md @@ -0,0 +1,105 @@ +## MultiFileHashMap + +Поддержка в БД нескольких таблиц и распределение данных таблицы. + +Корневая директория для данных получается из property ```System.getProperty("fizteh.db.dir")```. В корневой директории +располагаются поддиректории, чьи имена соответствуют именам таблиц. Директория таблицы может содержать до 16 +директорий: ```0.dir, 1.dir, 2.dir, ..., 15.dir```. Внутри каждой директории может быть до 16 файлов с именами: +```0.dat, 1.dat, 2.dat, ..., 15.dat```. Данные распределяются по файлам строго оговоренным ниже образом. +Файлы и директории должны быть непустыми. Если файл или директория опустели, они удаляются. + +Кроме того, приложение должно поддерживать дополнительные команды для работы с таблицами. + +### create +``` +create +``` + +Создать новую таблицу. Создается соответствующая директория. Если успешно: +``` +created +``` + +Если такая таблица уже существует: +``` +tablename exists +``` + +### drop +``` +drop tablename +``` + +Удалить таблицу. Директория таблицы удаляется с диска. Если успешно: +``` +dropped +``` + +Если такой таблицы не существует: +``` +tablename not exists +``` + +### use +``` +use tablename +``` + +Использовать указанную таблицу для последующих операций работы с данными. + +Если таблицы не существует: +``` +tablename not exists +``` + +Если переключение прошло успешно: +``` +using tablename +``` + +Если пользователь пытается провести операции с данными, когда база еще не выбрана: +``` +no table +``` + +### show tables +``` +show tables +``` + +Выводит список таблиц с количеством записей (через пробел). +``` +table_name row_count +table1 10 +table2 123 +table3 45 +… +``` + +### Вариант 1 +Пара ключ-значение записывается в соответствующий файл по следующему правилу: +``` +hashcode = key.hashCode() +ndirectory = hashcode % 16 +nfile = hashcode / 16 % 16 +``` + +### Вариант 2 +Пара ключ-значение записывается в соответствующий файл по следующему правилу: +``` +byte = key.bytes[0] +ndirectory = byte % 16 +nfile = byte / 16 % 16 +``` + +### Подводные камни + +* При запуске приложения нужно убедиться, что директория, в которой предлагается работать, существует. +* Также следует проверить, что корневая директория и поддиректории действительно директории, а не файлы. +* При чтении из файлов нужно проверять их валидность, избегать слишком больших и маленьких значений буферов. +* При чтении из файла можно проверять, что читаемые ключи действительно должны принадлежать именно к этому файлу. +* Бинарный формат и соотношение ключ-файл должны быть строго соблюдены. +* Протокол интерактивной работы должен быть строго соблюден. +* Приложение должно поддерживать русские буковки. +* Неразумно на каждый запрос писать в файл и читать из файла. + diff --git a/tasks/04-JUnit.md b/tasks/04-JUnit.md new file mode 100644 index 000000000..db7192458 --- /dev/null +++ b/tasks/04-JUnit.md @@ -0,0 +1,62 @@ +## JUnit + +В базу данных добавляется механизм транзакций. Изменения не записываются на диск до выполнения команды commit. +Если пользователь хочет отменить изменения, сделанные с момента последнего вызова команды commit (например, если +пользователь ошибся во вводе), то должна быть возможность откатить все эти изменения с помощью команды rollback. + +Теперь приложение, помимо возможности запуска из командной строки, может быть запущено в рамках другого приложения +(как библиотека). Библиотека должна реализовывать соответствующие интерфейсы, объявленные в пакете +[ru.fizteh.fivt.storage.strings](../src/ru/fizteh/fivt/storage/strings) (Table, TableProvider, TableProviderFactory). + +Каждый метод каждого интерфейса должен быть покрыт модульными тестами (с помощью [JUnit](http://junit.org/)). +Для классов-реализаций интерфейсов, где это разумно, также должны быть написаны тесты. + +### Предполагаемое использование. + +Контракт превращает ваше приложение в стороннюю библиотеку. Пользователь создает экземпляр вашей реализации +```TableProviderFactory``` конструктором по умолчанию. Эта фабрика нужна для того, чтобы создать экземпляр +```TableProvider``` с указанием пути до корня хранилища. Пользуясь экземпляром ```TableProvider```, пользователь может +создать или открыть одну или несколько таблиц. Получив экземпляр таблицы, пользователь вызывает нужные ему методы для +работы с данными. + +### Добавляются следующие команды + +#### size +``` +size +``` + +Вывести число хранимых пар ключ-значение: +``` +6 +``` + +#### commit +``` +commit +``` + +Записать изменения на диск. +Вывод - число измененных значений: +``` +int +``` + +#### rollback +``` +rollback +``` + +Откатить все изменения до предыдущего коммита (или до состояния на момент начала программы). +Вывод - число откаченных изменений: +``` +int +``` + +### Изменения в командах: + +#### use +Если есть незакоммиченные изменения, команда должна выдавать сообщение об ошибке: +``` +5 unsaved changes +```