Quick Overview

This question evaluates proficiency in debugging and maintaining a Java codebase with failing unit tests, testing competencies in unit testing, fault isolation, reading test assertions and stack traces, and verifying regression-free fixes.

Debug and Fix Failing Unit Tests in Java

Company: Bilt Rewards

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

You receive a small Java project for a credit-card rewards service with three failing unit tests: calculatesTriplePointsForRestaurants, returnsUnknownWhenMerchantCodeMissing, and aggregatesDailyPointsCorrectly. Without adding new tests, make minimal, well-justified code changes in up to three files so that all tests pass. Walk through your debugging process: reproducing failures, reading assertions and stack traces, isolating defects, and verifying no regressions. Then implement fixes such as correcting a category check for 'Restaurant', handling null/empty merchantCode safely, and resolving an off-by-one error in daily aggregation. Finally, explain how you would prevent future regressions (e.g., edge-case tests, input validation, and code review checklist).

Overview: This question evaluates proficiency in debugging and maintaining a Java codebase with failing unit tests, testing competencies in unit testing, fault isolation, reading test assertions and stack traces, and verifying regression-free fixes.

Read the full Bilt Rewards Software Engineer interview experience this question came from

You are given a list of credit-card transactions. Implement process_rewards(transactions) that returns a pair: (normalized_merchant_codes, daily_points). For each transaction, normalize merchantCode by replacing any null, empty, or whitespace-only value with "UNKNOWN" (trimming other codes). Compute daily_points by aggregating reward points per UTC calendar date derived from the transaction timestamp. Points are amount * 3 if category equals "Restaurant" (case-insensitive, after trimming), otherwise amount * 1. The timestamp is an ISO 8601 string with timezone (e.g., Z or offsets), and aggregation must be done by UTC day (YYYY-MM-DD). Preserve the order of normalized merchant codes to match the input transaction order.

Constraints

  • 0 <= len(transactions) <= 100000
  • Each transaction is a dict with keys: amount (int, 0 <= amount <= 10^6), category (string), merchantCode (string or null), timestamp (ISO 8601 string with timezone, e.g., 'Z' or '+02:00')
  • Compare category to 'Restaurant' case-insensitively after trimming whitespace
  • Normalize merchantCode: if null, empty, or whitespace-only, use 'UNKNOWN'; otherwise trim surrounding whitespace
  • Aggregate points by UTC date (YYYY-MM-DD) derived from timestamp
  • Return value: (normalized_merchant_codes: list[str], daily_points: dict[str, int])

Hints

  1. Parse ISO 8601 timestamps and convert to UTC before taking the date.
  2. Consider replacing a trailing 'Z' with '+00:00' for Python's fromisoformat.
  3. Use a dictionary or defaultdict(int) to accumulate points by date.
  4. Trim strings before checking emptiness or comparing to 'Restaurant'.

Loading coding console...

Show the approach

Approach

Iterate once over the transactions. Normalize merchant codes by trimming whitespace and replacing null/empty values with 'UNKNOWN'. Determine the points multiplier by comparing the trimmed, lowercased category to 'restaurant'. Parse each ISO 8601 timestamp and convert it to UTC before taking the calendar date to prevent off-by-one day errors from timezones. Use a dictionary to accumulate points per date. Return the normalized merchant codes (in input order) and the per-day totals.

Time complexity:
O(n)
Space complexity:
O(n)