← Все проекты уровня 5
Уровень 5 · Обработка большого числа файловВариант A

Поиск дубликатов

Найдите одинаковое содержимое в дереве файлов, безопасно ограничивая память и параллелизм.

Техническое задание

Поиск и безопасность

Реализуйте CLI для обнаружения файлов с одинаковым содержимым. Обязателен корневой путь; параметры --workers, --max-files и --max-file-size задают положительное число рабочих горутин, жёсткий предел числа обрабатываемых файлов и верхний предел размера одного файла. Используйте SHA-256 и сравнивайте полное содержимое, а не только имена или размеры. Группируйте файлы только если совпадают и размер в байтах, и хеш. Для каждой группы выводите размер, хеш и отсортированные относительные пути; группы сортируйте по первому пути. Относительные пути строятся от корня, чтобы отчёт был переносимым.

Обходите обычные файлы рекурсивно, но не переходите по символическим ссылкам и не включайте сами ссылки в хеширование. Ограничьте очередь путей каналом ёмкостью не более workers; не собирайте все пути дерева в памяти. Если обнаружен ещё один подходящий файл после обработки --max-files файлов, остановите обход, выведите найденные группы с пометкой о неполноте и завершитесь с ненулевым кодом. Каталоги, недоступные для чтения файлы и файлы сверх лимита диагностируются; ошибки отдельных файлов не прекращают поиск. Пользователь явно задаёт ограничение параллелизма; одновременно открытых файлов и буферов чтения не должно быть больше числа workers. Не загружайте файлы целиком: считайте потоковыми блоками фиксированного размера и проверяйте context.Context перед получением задания и во время чтения. При отмене прекратите выдачу новых заданий, закройте открытые файлы, дождитесь всех рабочих горутин и верните ошибку отмены вместе с диагностированными находками.

Результат частичный при ошибках отдельных файлов или отмене: выведите завершённые группы и диагностики, отдельно обозначьте, что поиск неполный; код завершения ненулевой. Ошибка корневого каталога фатальна и результата не даёт. Поведение должно предусматривать только чтение. Потоки задач и результатов обязаны завершаться без утечки при ошибке и отмене; общие структуры защищайте синхронизацией. README описывает политику ссылок, ограничения размера, частичный результат и отмену. Проверьте потоковую обработку, отмену и конкурентную безопасность локальными тестами и race-проверкой.

Структура программы

Разделите internal/files, который обходит дерево, открывает потоки и вычисляет SHA-256, и internal/duplicates, который группирует проверенные метаданные и сортирует результат. main.go создаёт контекст, отменяемый сигналом, ограничивает workers, связывает каналы и решает судьбу частичного результата. Направьте зависимости к типам результата и правилам, без циклов; workers и context не прячьте в пакетах правил.

Критерии готовности

Ожидаемый результат

Сдайте запускаемый Go-модуль и CLI с ограниченным числом работников, потоковым SHA-256, обходом только для чтения, README и офлайн-тестами. В отчёте различаются полные результаты и неполный поиск; ошибки файлов можно локализовать по относительному пути. Тесты и код должны подтверждать закрытие файлов и завершение работников при отмене.

Критерии приёмки:

  • README описывает границы файлового обхода и группировки; race-тест проверяет workers.
  • два файла одинакового содержимого попадают в одну группу;
  • одинаковый размер при разных байтах не даёт дубликат;
  • ссылка на файл не обходится;
  • файл выше лимита диагностируется;
  • одновременно работающих обработчиков не больше workers;
  • отмена контекста возвращает неполный результат, закрывает ресурсы и завершает горутины. Ошибка одного файла не скрывает другие группы. Повторный запуск даёт тот же порядок, исходные файлы не изменяются, а go test -race ./... завершается чисто.

Для ориентира

Примеры входа и результата

В дереве есть a.txt и sub/b.txt с байтами «hello», а c.txt содержит «world». Отчёт объединяет только a.txt и sub/b.txt. Файл больше --max-file-size диагностируется и пропускается; итог помечается неполным, если это повлияло на поиск.