Задача с собеседования Java

98
07 августа 2019, 08:30

Есть вот такое задание:

Даны несколько файлов логов в директории. За минимальное время необходимо вычислить распределение возникновения ошибок (ERROR) за каждый час/минуту/

Как я понял необходимо всё вычислять в параллельных стримах. Меня хватило на следующее - я открываю директорию и ищу в ней все файлы с расширением .log, далее параллельно читаю файлы построчно и ищу в строках слово ERROR и считаю их количество и ... тупик, не знаю, что делать дальше

public void findErrors() throws IOException {
    Path dir = Paths.get("D:/Logs");
    long x = Files.walk(dir)
            .filter(file -> file.toString().endsWith(".log"))
//          .peek(System.out::println)  
            .parallel()
            .flatMap((p) -> {
                try {
                    return Files.lines(p);
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            }).filter(s -> s.contains("ERROR"))
//            .peek(System.out::println)
            .count();
    System.out.println(x);
}

Строчка логов выглядит вот так:

15:35:36,374 ERROR [ru.company.idocs_storage._stdimpl.dao.IDocsStorageApplicationImpl] (longRunTasksThreadPoll-4) Error in iDocs process
15:35:36,374 ERROR [ru.company.idocs_storage._stdimpl.dao.IDocsStorageApplicationImpl] (longRunTasksThreadPoll-4) User: Êóíöåâ Ä.È.
Answer 1

Прошу прощения, не буду писать код, так как не гуру в Java, но выскажу общие соображения. Задача идеально ложится на парадигму MapReduce. При этом шагом Map является составление отображения (Map в терминах Java): час/минута возникновения ошибки - количество ошибок в данный интервал времени, а шагом Reduce - агрегирование данных, полученных на предыдущем шаге, уже по всем файлам.

необходимо всё вычислять в параллельных стримах

И если уж вы заговорили про много-поточность, то я бы предложил такую идею. Несколько потоков открывают файлы (каждый поток по 1 файлу) и создают на основании него Map, где ключем является час/минута возникновения ошибки, а значением - количество ошибок в этот интервал времени. После обработки файла они передают полученный Map основному потоку, координатору, который занимается их агрегированием.

Отдельно можно обсудить:

  • Количество потоков, обрабатывающих файлы. Наверное их количество должно совпадать с количеством ядер системы (или количеством ядер, выделенных JVM).
  • Поговорить о том, что шаг Map может выполняться параллельно на нескольких машинах. То есть, если у нас есть несколько машин, то обработку файлов можно разнести сразу на несколько машин (при условии, что логи лежат на общем файловом хранилище). Главное, чтобы они результаты обработки отдавали одной машине-координатору.
  • Развить предыдущий пример и рассказать, что есть готовые системы, которые облегчают создание таких систем - например, Spark.
READ ALSO
Потокобезопасность Collections.synchronizedList

Потокобезопасность Collections.synchronizedList

Какой смысл потокобезопасности CollectionssynchronizedList если ее все равно нужно синхронизировать при итерации

109
Не может найти и загрузить main class. Win10

Не может найти и загрузить main class. Win10

Полагаю, что это один из самых распространенных вопросов от начинающихЯ учусь по учебнику с сайта ProgLang

129
Не вызывается onActivityResult()

Не вызывается onActivityResult()

Во время закрытия активити не выполняется onActivityResult()

114
Зачем нужны препроцессоры? [закрыт]

Зачем нужны препроцессоры? [закрыт]

Скажите, в каких ситуациях используют к примеру less если есть postcss с кучей полезных плагинов? например nextCss

128