Экзамен

Вопросы к экзамену

Задача с экзамена в прошлом году

Задача экзамена 2018

В прошлогодней задаче используются CSV файлы, вы можете представить, что вместо них я прошу пользоваться json файлом с данными.

Многопоточное программирование

  1. Используйте AtomicInteger вместо synchronized блока для решения задачи про бананы и мартышек.
  2. Многопоточный фрактал
    1. Добавьте в задачу с фракталом ProgressBar внизу окна.
    2. Пусть каждое вычиление фрактала производится в отдельном Task.
    3. Пусть во время вычисления фрактала обновляется ProgressBar.
    4. Если начал работать Task для вычисления фрактала, при этом аналогичный Task уже работает, предудущий нужно отменить. Используйте метод cancel() для отмены, и внутри Task завершите вычисления, если isCancelled() возвращает true.
    5. Пусть после вычисления очередной строки (столбца) фрактала Task обновляет вычисленное значение методом updateValue, и программа сразу показывает обновленное значение. В этом случае рисование фрактала на экране будет происходить постепенно, а не скачком.

JSON

  1. Создайте класс Author с полями name и surname. Пусть теперь в Book поле author имеет тип Author. Измените json, чтобы программа могла правильно прочитать книги.
  2. Дано слово String word = "..." и два языка: String from = "..." и String to = "...". Переведите с слово с одного языка на другой с помощью glosbe.com. Выведите в консоль исходное слово, все переводы, для каждого первода — все смыслы. После этого для каждого перевода укажите источник.

Jar файлы

  1. Создайте запускаемый jar файл из своей задачи про фракталы.
  2. Необязательно: добавьте в задачу про фракталы иконку в виде ресурса.

Потоки (Streams)

  1. Создайте метод getTokenStream, который для заданного файла возвращает поток слов в этом файле.
    1. Простой способ: прочитайте весь файл в память в виде одной строки (используйте вспомогательные функции из класса Files), и вызовите для полученной строки метод split().
    2. Сложнее. Создайте Scanner и воспользуйтесь методом Stream.generate() для создания потока.

    Начинайте решение каждой следующей задачи с вызова метода getTokenStream.

  2. Посчитайте количество слов в потоке.
  3. Сколько в тексте слов, начинающихся с заглавной буквы?
  4. Посчитайте количество слов в потоке без учета стоп-слов. Приводите слова к нижнему регистру для сравнения со стоп словами.

    Подсказка: создайте Set для списка стоп-слов.

  5. Какая средняя длина слова в вашем тексте?
  6. Посчитайте сразу и среднюю длину слова, и максимальная длину, и минимальную. Подсказка: для вычисления сразу всех статистик есть соответствующий Collector.
  7. Каких слов больше, с четной длиной или с нечетной длиной? Попробуйте сделать только один проход по потоку для получения ответа.
  8. Распечатайте «табличку», сколько раз встретилась каждая длина слова. Например, слов длины 1: 10 штук, слов длины 2: 40 штук и т.п.
  9. Аналогично предыдущей задаче, но должно быть две таблички. С учетом одинаковых слов или без учета одинаковых слов. Т.е. Если некоторое слово встретилось дважды, его нужно считать дваждый в первой таблице, и один раз во второй таблице.
  10. Посчитайте частоты всех слов файла. Верните Map<String, Integer>, сопоставляющий каждому слову количество раз, которое оно встретилось в файле. Приводите слова к нижнему регистру.
  11. Получите частоты всех слов в файле с помощью предыдущей задачи и выведите слова в порядке убывания частот. Подсказка. У Map есть метод entrySet который возвращает множество (Set) записей, содержащих пару из ключа и значения. С этим множеством тоже можно работать с помощью потоков, и сортировать его.
  12. Пусть S = количество стоп-слов. Если взять первые S самых частотных слов вашего текста, сколько совпадений будет со словами стоп-листа?
  13. Сложно. Определите имена в тексте. Имена — это слова, начинающиеся с заглавной буквы, перед которыми не было конца предложения, т.е. точки, восклицательного знака, вопросительного знака.
  14. Сложно. Создайте класс Context. Он содержит String word — слово и Set<String> — несколько соседних слов, пять до и пять после. (5 — это константа, которую можно менять при создании класса). Превратите поток слов в поток их контекстов.

Сбор данных

  1. Выберите русскоязычного автора на сайте http://lib.ru, откройте список его произведений и запустите библиотеку crawler4j для сбора текстов всех произведений. Сохраните все тексты на диск в папку с именем этого автора.
  2. Повторите это же действие для другого русскоязычного автора.

Определение автора

В этой задаче необходимо написать классификатор, который по предложению определяет его автора. Мы будем определять одного из двух авторов, тексты которых собирали в предыдущем задании.

  1. У каждого автора прочитайте все его тексты из соответствующей папки и разбейте их на предложения. Используйте split для разделения по точкам, вопросительным и восклицательным знакам.
  2. Каждое предложение разбейте на слова, опять используя split. Приведите слова к нижнему регистру и избавьтесь от всех других знаков препинания. Создайте множество Set allWords для хранения вобще всех слов, встречающихся в текстах, и заполните его словами всех предложений обоих авторов.
  3. Создайте Instances allSentences для хранения всех предложений. Создайте по одному атрибуту для каждого слова из allWords с двумя значениями no и yes. И создайте атрибут author с двумя значениями, соответствуюищими именам двух авторов.
  4. Для каждого предложения создайте свой SparseInstance. Для тех слов, которые встрчаются в предложении, установите значение соответствующих атрибутов в yes, остальные атрибуты заполните no. Поместите готовый Sparsenstance в allSentences.
  5. Разбейте allSentences на два набора предложений: trainingSentences для обучения и testSentences для проверки. (см. пример в файле MLExample).
  6. Обучите модель и проверьте ее точность.