Design a duplicate-file removal algorithm
Company: Abnormal Security
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: Design a duplicate-file removal algorithm evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Part 1: Single-Machine Verified Duplicate-File Removal
Constraints
- 0 <= len(files) <= 100000
- Each path is unique.
- path, content, permissions, and timestamp are strings.
- content may be an empty string, representing a zero-byte file.
- Duplicate detection is based only on exact content equality.
- Target complexity: O(total_bytes + n log n) time including output sorting.
Examples
Input: ([],)
Expected Output: []
Explanation: No files means there is nothing to delete.
Input: ([['/a.jpg', 'abc', 'rw', '10']],)
Expected Output: []
Explanation: A single file has no duplicate.
Hints
- For each exact content value, track the canonical path seen so far.
- If a later duplicate has a smaller path than the current canonical path, the old canonical becomes deletable.
Part 2: External-Merge Duplicate Detection for Too-Large Input
Constraints
- 0 <= number of runs <= 10000
- 0 <= total number of records <= 100000
- Each run is sorted by numeric size, then digest, then path.
- Each path is unique.
- If two files have identical content, their size and digest fields are identical.
- Different contents may have the same digest, so exact content comparison is still required.
Examples
Input: ([],)
Expected Output: []
Explanation: No runs means there are no records.
Input: ([[], [['3', 'h1', '/a', 'abc']]],)
Expected Output: []
Explanation: Empty runs are ignored, and the single file has no duplicate.
Hints
- Use a min-heap to k-way merge the already sorted runs.
- You only need to keep the current equal (size, digest) group in memory before verifying exact contents.
Part 3: Validate Production Invariants for a Duplicate-Deletion Plan
Constraints
- 0 <= len(files) <= 100000
- 0 <= len(delete_paths) <= 100000
- path and content are strings.
- content may be an empty string.
- When duplicate file paths exist, report DUPLICATE_FILE_PATH; other checks should still be computed using the first occurrence of each path.
Examples
Input: ([['/b', 'cat'], ['/a', 'cat'], ['/u', 'dog']], ['/b'])
Expected Output: []
Explanation: /b has a kept identical copy at /a, and the canonical /a is not deleted.
Input: ([], [])
Expected Output: []
Explanation: An empty scan with an empty deletion plan violates no invariant.
Hints
- Build counts for scanned paths and delete paths before validating content-based safety.
- For each content group, compare the delete set against the kept paths and the lexicographically smallest canonical path.
Part 4: Select Tests Covering Deduplication Bug Categories
Constraints
- 0 <= len(candidates) <= 100000
- Each candidate name is unique.
- tags may contain off_by_one, duplicate, tie_breaking, unknown tags, spaces, or be empty.
- Unknown tags should be ignored.
- The returned list must be sorted lexicographically.
Examples
Input: ([['two_equal_files', 'off_by_one,duplicate'], ['reverse_order_names', 'tie_breaking'], ['single_file', 'off_by_one']],)
Expected Output: ['reverse_order_names', 'two_equal_files']
Explanation: The first and second tests together cover all three required categories.
Input: ([],)
Expected Output: []
Explanation: No candidates means full coverage is impossible.
Hints
- There are only three required categories, so represent coverage as a 3-bit mask.
- Dynamic programming over masks can track the best chosen name list for each coverage state.