Capital One Interview (Full Virtual onsite) for Technical Lead Software Engineer
Anonymous User
2587

'''

Round 1:

Your task is to implement a simplified version of a banking system.

Initially, the banking system does not contain any accounts, so implement operations to allow accounts creation as well as making deposits.

Operations:

CREATE_ACCOUNT

Should create a new account with the given identifier if it doesn't already exist.
Returns "true" if an account was successfully created,
Returns "false" if an account with accountId already exists.

DEPOSIT

Should deposit the given amount of money to the specified account accountId
Returns the total amount of money in the account after the query has been processed.
If the specified account doesn't exist, it should return -1.

TRANSFER

This should transfer the given amount of money from account with fromId to account with toId.

Returns the balance of fromId if the transfer was successful, or -1 otherwise.
Returns -1 if fromId or toId doesn't exist.
Returns -1 if fromId and toId are the same.
Returns -1 if funds on the account fromId are insufficient to perform the transfer.

TOP_ACTIVITY

This should return the identifiers of n most active accounts in descending order of financial activity indicator, In case of a tie, sorted alphabetically by accountId in ascending order.

The returned value should be an array of identifiers in the format
<accountId_1>(<activity_indicator_1>),
<accountId_2>(<activity_indicator_2>),
...,
<accoundId_n>(<activity_indicator_n>)

Financial activity indicator is defined as the sum of all transactions for an account including the money deposited and/or successfully transferred. Unsuccessful transactions are not included.

If less than n accounts exist in the system, then return all their identifiers (in the described format).

operations = [
["CREATE_ACCOUNT", "account1"], # true
["CREATE_ACCOUNT", "account1"], # false
["CREATE_ACCOUNT", "account2"], # true
["DEPOSIT", "non-existing", "2700"], # -1
["DEPOSIT", "account1", "2700"], # 2700
["TRANSFER", "account1", "account2", "2701"], # -1
["TRANSFER", "account1", "account2", "200"], # 2500
["TRANSFER", "account1", "account2", "2500"], # 0
["DEPOSIT", "account2", "300"], #3000
["CREATE_ACCOUNT", "account3"], # true
["DEPOSIT", "account3", "4000"], #4000
["TOP_ACTIVITY", "3"], #[account1(5400), account3(4000), account2(3000)]
["DEPOSIT", "account2", "1000"], # 4000
["TOP_ACTIVITY", "2"], #[account1(5400), account2(4000)]
["TOP_ACTIVITY", "5"] #[account1(5400), account2(4000), account3(4000)]
]
'''

class BankingSystem:
def init(self):
self.accounts = {} # dictionary to store account balances
self.activity = {} # dictionary to store financial activity

def create_account(self, accountId):
    # if account already exists (edge case)
    if accountId in self.accounts: 
        return False
        
    # otherwise create account with 0 balance
    self.accounts[accountId] = 0
    self.activity[accountId] = 0 # initialize financial activity to 0
    return True
    
def deposit(self, accountId, amount):
    # if account does not exist, return -1
    if accountId not in self.accounts:
        return -1
    # add the amount, if it exists:
    self.accounts[accountId] += int(amount)
    self.activity[accountId] += int(amount)
    # Return the output balance
    return self.accounts[accountId]

def transfer(self, fromId, toId, amount):
    # check if both account exist
    if fromId not in self.accounts or toId not in self.accounts:
        return -1
    
    # check if fromId and toId are the same
    if fromId == toId:
        return -1
        
    # check if funds on the account fromId are insufficient
    if self.accounts[fromId] < int(amount):
        return -1
        
    # Do the tranfer operation
    self.accounts[fromId] -= int(amount)
    self.accounts[toId] += int(amount)
    
    # adding the financial activity for both accounts
    self.activity[fromId] += int(amount)
    self.activity[toId] += int(amount)
    
    return self.accounts[fromId]
    
def top_activity(self,n):
    # sorting in descending order the activity indicator, then by accountId in acscendting order
    sorted_accounts = sorted(
        self.activity.items(),
        key=lambda x: (-x[1], x[0]) # sorts the activity by desc, then accountId by ascending asc
    )
    
    # format the result
    result = [f"{accountId}({activity})" for accountId, activity in sorted_accounts[:n]]
    return result
        

Operations input

operations = [
["CREATE_ACCOUNT", "account1"], # true
["CREATE_ACCOUNT", "account1"], # false
["CREATE_ACCOUNT", "account2"], # true
["DEPOSIT", "non-existing", "2700"], # -1
["DEPOSIT", "account1", "2700"], # 2700
["TRANSFER", "account1", "account2", "2701"], # -1
["TRANSFER", "account1", "account2", "200"], # 2500
["TRANSFER", "account1", "account2", "2500"], # 0
["DEPOSIT", "account2", "300"], #3000
["CREATE_ACCOUNT", "account3"], # true
["DEPOSIT", "account3", "4000"], #4000
["TOP_ACTIVITY", "3"], #[account1(5400), account3(4000), account2(3000)]
["DEPOSIT", "account2", "1000"], # 4000
["TOP_ACTIVITY", "2"], #[account1(5400), account2(4000)]
["TOP_ACTIVITY", "5"] #[account1(5400), account2(4000), account3(4000)]
]

banking_system = BankingSystem()

for op in operations:
if op[0] == "CREATE_ACCOUNT":
print(banking_system.create_account(op[1]))
elif op[0] == "DEPOSIT":
print(banking_system.deposit(op[1], op[2]))
elif op[0] == "TRANSFER":
print(banking_system.transfer(op[1],op[2], op[3]))
elif op[0] == "TOP_ACTIVITY":
print(banking_system.top_activity(int(op[1])))
# -----

    # # Modifications
    # self.acccounts = {
    #     "accountId": {
    #         "balance" : 0,
    #         "activity" : 0
    #     }
        
    # }

#------
"""

Round 2: System Design

Design a credit card account management application.
The application should represent a bank with the opportunity to apply for credit cards,
manage credit cards, manage payments, and report usages.

Features that need to be supported:

  • Process a credit card application

  • Create a credit card online account / access online portal

Provide API to authorize credit card transactions

  • Support calculating daily, weekly and monthly statistics

Pay credit card balance using a third-party payment service

Round 3: Behavioral Interview

The st*pid interviewer thought I was interviewing
for a managerial positiion and started asking me all the
management based questions .. What a bummer !!

Round 4:
Asked me what quick replying model.
Capital One has a model "Eeno", which is a quick replying model.
Told me about it and asked my suggestions on how to improve it:

Q- what types of data will be useful for this kind (Eeno) of model

Then asked me to tweak the following code:

import calendar
import time

class RetrieverQ:
def init(self, store):
self.store = store

def retrieve_recent(self, customer_id, curr_time):
    result = []
    # Retrieve data for the last 5 minutes including the current minute
    for index in range(0, 5):
        val = self.store.retrieve(customer_id, curr_time - 5 + index)
        if val is not None:
            result.append(val)
    return result

Create retrievers for each store

clk_retriever = RetrieverQ(clk_store)
trx_retriever = RetrieverQ(trx_store)

Current time in minutes since epoch

cid = 1
curr_time = int(calendar.timegm(time.gmtime()) / 60) # minutes

Retrieve recent activity

clk_recent = clk_retriever.retrieve_recent(cid, curr_time)
trx_recent = trx_retriever.retrieve_recent(cid, curr_time)

--- Data -----

#NOTE: Minute is sequential number of minutes since the Epoch (1/1/1970)

NOTE: Minute is sequential number of minutes since the Epoch (1/1/1970)

--- Clickstream Data ---

#CID - MINUTE - CLICK EVENT
#1 - 25853654 - Confirm
#1 - 25853653 - Schedule Payment
#1 - 25853652 - View recent
#1 - 25853651 - Login
#1 - 25853650 - Enter password
#1 - 25853649 - Enter user name
#1 - 25853648 - Login
#1 - 25853649 - Login
#1 - 25853650 - Recover Login

--- Transactions Data ---

#CID - MINUTE - TRANSACTION
#1 - 25853652 - Krogers 5
#1 - 25853653 - Geddy's Music 45
#1 - 25853598 - Starbucks 45.00
#2 - 25851945 - OSU Bookstore 222
#2 - 25851002 - Neil's Drums $1340

Questions Asked:

  • Explain the code
  • Given: cid = 1, curr_time = 25853655, What rows come back retrieve_recent fucntion
    -Output be like: clk_recent : ["Login", "Enter user name"]
    trx_recent : ["Krogers 8.00"]
  • now the requirement is : retrieve_recent Be able to retrieve a window of Time T minutes and not hard core 5.
    modify the retrieve recent function.
    - output ( my answer):
    def retrieve_recent(self, customer_id, curr_time, time_window):
    # Remove default value, require explicit time_window
    result = []
    for index in range(time_window): # Use time_window directly in the loop
    val = self.store.retrieve(customer_id, curr_time - time_window + index + 1)
    if val is not None:
    result.append(val)
    return result

"""

Comments (1)