Тестовое задание на стажировку в Контур 2019
Разработать приложение для архивации логов в заданном формате (см. конец этого документа). Это должно быть консольное приложение, имеющее два режима работы: сжатие и разжатие.
При запуске с двумя аргументами приложение должно запускаться в режиме сжатия:
dotnet Kontur.LogPacker.dll <input_file> <output_file>
Первый аргумент задает путь до исходного лог-файла. Второй аргумент задает путь до файла, куда вы запишете сжатые данные.
При запуске с тремя аргументами, где первый равен -d, приложение должно запускаться в режиме разжатия:
dotnet Kontur.LogPacker.dll -d <input_file> <output_file>
Здесь второй аргумент задает путь до сжатого файла, сформированного вашим приложением, а третий аргумент — путь до разжатого файла.
- После цикла сжатие-разжатие файл должен быть побайтово равен исходному.
- Алгоритм должен корректно работать на логах, где строки имеют другой формат, а также на данных, вообще не являющихся логами (в общем случае это просто случайные бинарные данные). Требований по качеству сжатия в таком случае нет, но требования по скорости сжатия сохраняются.
- Качество сжатия: на произвольных лог-файлах заданного формата размер сжатых данных должен быть меньше, чем при использовании gzip (здесь и далее имеется в виду стандартная реализация из .NET Core: GZipStream с CompressionLevel.Optimal).
- Ваш архиватор должен выигрывать хотя бы 1 процентный пункт (если gzip сжимает файл до 25% исходного размера, у вас должно получаться 24% или ещё меньше).
- Скорость сжатия: на любых данных время работы вашего алгоритма не должно превышать время работы gzip более чем в два раза. Аналогично со скоростью разжатия.
- Потребление оперативной памяти: объем потребляемой оперативной памяти не должен зависеть от размера входных данных и на любых входных данных не должен выходить за разумные пределы (100-200 МБ).
- Загрузка процессора: архивация логов не должна мешать другим работающим на машине приложениям. Поэтому ваш архиватор должен работать в один поток.
- Решение может создавать временные файлы, но их суммарный размер не должен превышать размер входного файла, и они должны удаляться до завершения процесса архиватора.
- Все временные файлы должны находиться в рабочей директории приложения (т. е. если вы будете указывать только имя файла, без директории, всё сработает как надо).
- Решение должно представлять собой консольное приложение на .NET Core 2.1.
- Нельзя использовать внешние библиотеки и приложения, как из nuget, так и подключаемые вручную.
Вот маленький фрагмент лог-файла в нужном формате:
2018-11-13 00:02:40,574 76 INFO Configured ThreadPool: 1024/32767 workers, 1024/32767 IOCP (min/max).
2018-11-13 00:02:41,315 816 INFO [BackgroundDaemon] Starting iteration #15434.
2018-11-13 00:02:41,330 831 INFO [0de1db] Started processing user request. Id = 0de1dbfb-fddb-40b5-b34b-7a7beb43a33f. Size = 2.83 KB.
2018-11-13 00:02:41,344 845 INFO [0de1db] Doing some complicated stuff.. Random numbers are: 1192743271, 187325574, 168764164.
2018-11-13 00:02:41,345 846 INFO [3a61cc] Started processing user request. Id = 3a61cc3f-2ee9-4738-8283-efc073235ec8. Size = 67.46 KB.
2018-11-13 00:02:41,354 855 INFO [3a61cc] Doing some complicated stuff.. Random numbers are: 905206199, 2002603058, 533352593.
2018-11-13 00:02:41,373 875 INFO [0de1db] Finished processing user request with id = 0de1dbfb-fddb-40b5-b34b-7a7beb43a33f in 00:00:00.0442952.
Формальное описание формата корректной строки лога:
[дата в формате 'yyyy-MM-dd HH:mm:ss,fff'][пробел][число из полуинтервала [0, ulong.MaxValue), дополненное пробелами справа до 6 символов][пробел][строка, дополненная пробелами справа до 5 символов][пробел][строка]
* дополнение пробелами справа работает аналогично методу string.PadRight()