PracHub
QuestionsLearningGuidesInterview Prep

Quick Overview

This question evaluates knowledge of designing stateful in-memory services, efficient data structures and algorithms for scheduled task execution and top‑K outgoing aggregation, and correctness in handling cancellation, failure semantics, and related edge cases.

  • medium
  • Circle
  • Coding & Algorithms
  • Software Engineer

Design payment scheduler with cancel and top-K outgoing

Company: Circle

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Take-home Project

Design and implement an in-memory banking payment component with the following APIs: ( 1) schedulePayment(payerId, payeeId, amount, executeAt) -> paymentId: create a pending outgoing payment scheduled for executeAt. ( 2) cancelPayment(paymentId) -> boolean: cancel only if still pending. ( 3) removePayment(paymentId) -> boolean: allow deletion only if the payment is CANCELED or FAILED; successful payments cannot be removed. ( 4) processDuePayments(now): execute all pending payments with executeAt <= now; mark each as SUCCESS if funds are sufficient, otherwise FAILED; only successful payments contribute to outgoing totals. ( 5) getTopKByOutgoingTotal(k) -> list<accountId>: return accountIds sorted by descending total outgoing amount from successful payments only; break ties by smaller accountId. Requirements: support only outgoing flow tracking (no incoming totals). Define the data structures to support efficient scheduling, cancellation, removal, and top-k queries; provide the time and space complexity of each API. Describe how you handle edge cases such as canceling an already executed payment, repeated cancellations, removing non-existent or ineligible payments, and ensuring that canceled payments are not executed.

Quick Answer: This question evaluates knowledge of designing stateful in-memory services, efficient data structures and algorithms for scheduled task execution and top‑K outgoing aggregation, and correctness in handling cancellation, failure semantics, and related edge cases.

Implement an in-memory payment scheduler. The function receives initial account balances and a list of operations, and it must return the result of every operation in order. Rules: - Payment IDs are assigned sequentially starting from 1 in the order payments are scheduled. - A scheduled payment starts in status PENDING. - cancelPayment(paymentId) succeeds only if the payment still exists and is PENDING. It changes the status to CANCELED. - removePayment(paymentId) succeeds only if the payment still exists and its status is CANCELED or FAILED. It deletes the payment record completely. - processDuePayments(now) processes every PENDING payment with executeAt <= now, in ascending order of (executeAt, paymentId). This tie-breaker is required for deterministic behavior. - When a due payment is processed: - if the payer has enough balance at that moment, transfer the amount from payer to payee, mark the payment SUCCESS, and add the amount to the payer's outgoing total; - otherwise mark it FAILED. - CANCELED payments must never execute. - getTopKByOutgoingTotal(k) returns up to k account IDs that have a positive outgoing total from SUCCESS payments only, sorted by descending outgoing total, and by smaller account ID when totals tie. - If an account appears for the first time in a scheduled payment, its starting balance is 0. You must support these operations efficiently using appropriate data structures.

Constraints

  • 0 <= len(balances) <= 2 * 10^5
  • 0 <= len(operations) <= 2 * 10^5
  • Account IDs are positive integers
  • Initial balances are non-negative integers
  • 1 <= amount <= 10^9
  • 0 <= executeAt, now <= 10^9
  • 0 <= k <= 2 * 10^5

Examples

Input: ({1: 100, 2: 50, 3: 0}, [('schedule', 1, 2, 70, 10), ('schedule', 1, 3, 40, 5), ('schedule', 2, 3, 60, 5), ('cancel', 1), ('process', 5), ('topk', 2), ('remove', 3), ('process', 10), ('cancel', 1), ('topk', 3)])

Expected Output: [1, 2, 3, True, 2, [1], True, 0, False, [1]]

Explanation: Payment 1 is canceled before execution. At time 5, payment 2 succeeds and payment 3 fails due to insufficient funds. Only account 1 has successful outgoing total, failed payment 3 can be removed, and the canceled payment is skipped later.

Input: ({1: 100, 2: 0, 3: 0, 4: 0}, [('schedule', 1, 2, 50, 7), ('schedule', 1, 3, 50, 7), ('schedule', 1, 4, 10, 7), ('process', 7), ('topk', 3), ('cancel', 2), ('remove', 2)])

Expected Output: [1, 2, 3, 3, [1], False, False]

Explanation: All three payments are due at the same time, so they are processed by paymentId order: 1, 2, then 3. The first two succeed and use up all funds; the third fails. A successful payment cannot be canceled or removed.

Hints

  1. Store each payment by paymentId in a hash map so cancel, remove, and status checks are O(1).
  2. A min-heap ordered by (executeAt, paymentId) is useful for due payments. For top-k outgoing totals, consider a max-heap with lazy deletion because totals only increase after successful payments.
Last updated: May 20, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Implement Recipe Storage CRUD - Circle (hard)
  • Implement a simplified multi-level banking system - Circle (medium)
  • Implement cheapest itinerary with date filters - Circle (medium)