Implement simple VM manager with CRUD operations
Company: NVIDIA
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates a candidate's ability to design and implement in-memory data models and CRUD APIs with unique-identifier management and consistent error signaling, testing skills in data structures, API/interface design, and algorithmic complexity.
Constraints
- 0 <= len(operations) <= 10^4
- All VM ids are integers
- Each create operation provides all required fields: id, name, cpu_cores, memory_gb, status
- For this problem, `updated_fields` will not contain the `id` key
- All operations are one of: create, list, update, delete
Examples
Input: [('create', {'id': 2, 'name': 'db', 'cpu_cores': 4, 'memory_gb': 16, 'status': 'running'}), ('create', {'id': 1, 'name': 'web', 'cpu_cores': 2, 'memory_gb': 8, 'status': 'stopped'}), ('list',), ('update', 1, {'status': 'running', 'memory_gb': 12}), ('list',), ('delete', 2), ('list',)]
Expected Output: ['created', 'created', [{'id': 1, 'name': 'web', 'cpu_cores': 2, 'memory_gb': 8, 'status': 'stopped'}, {'id': 2, 'name': 'db', 'cpu_cores': 4, 'memory_gb': 16, 'status': 'running'}], 'updated', [{'id': 1, 'name': 'web', 'cpu_cores': 2, 'memory_gb': 12, 'status': 'running'}, {'id': 2, 'name': 'db', 'cpu_cores': 4, 'memory_gb': 16, 'status': 'running'}], 'deleted', [{'id': 1, 'name': 'web', 'cpu_cores': 2, 'memory_gb': 12, 'status': 'running'}]]
Explanation: The manager stores VMs by id. Listing is sorted by id, so VM 1 appears before VM 2 even though VM 2 was created first.
Input: [('create', {'id': 1, 'name': 'vm1', 'cpu_cores': 1, 'memory_gb': 2, 'status': 'running'}), ('create', {'id': 1, 'name': 'dup', 'cpu_cores': 2, 'memory_gb': 4, 'status': 'stopped'}), ('update', 3, {'status': 'stopped'}), ('delete', 2), ('list',)]
Expected Output: ['created', 'error: duplicate id', 'error: not found', 'error: not found', [{'id': 1, 'name': 'vm1', 'cpu_cores': 1, 'memory_gb': 2, 'status': 'running'}]]
Explanation: Creating a VM with an existing id fails. Updating or deleting a missing id also fails.
Input: []
Expected Output: []
Explanation: No operations means no results.
Input: [('list',), ('create', {'id': 10, 'name': 'cache', 'cpu_cores': 1, 'memory_gb': 2, 'status': 'stopped'}), ('delete', 10), ('create', {'id': 10, 'name': 'cache-new', 'cpu_cores': 2, 'memory_gb': 4, 'status': 'running'}), ('list',), ('update', 10, {'cpu_cores': 4, 'status': 'stopped'}), ('list',)]
Expected Output: [[], 'created', 'deleted', 'created', [{'id': 10, 'name': 'cache-new', 'cpu_cores': 2, 'memory_gb': 4, 'status': 'running'}], 'updated', [{'id': 10, 'name': 'cache-new', 'cpu_cores': 4, 'memory_gb': 4, 'status': 'stopped'}]]
Explanation: Listing an empty manager returns an empty list. After deletion, the same id can be reused by a new VM.
Solution
def solution(operations):
# Use a dictionary keyed by VM id so lookup, update, and delete are O(1) on average.
# For 'list', return a sorted snapshot so the output order is deterministic.
vms = {}
results = []
for op in operations:
action = op[0]
if action == 'create':
vm = dict(op[1])
vm_id = vm['id']
if vm_id in vms:
results.append('error: duplicate id')
else:
vms[vm_id] = vm
results.append('created')
elif action == 'list':
# Copy each VM so earlier snapshots are not affected by later updates.
snapshot = [vms[vm_id].copy() for vm_id in sorted(vms)]
results.append(snapshot)
elif action == 'update':
vm_id, updated_fields = op[1], op[2]
if vm_id not in vms:
results.append('error: not found')
else:
vms[vm_id].update(updated_fields)
results.append('updated')
elif action == 'delete':
vm_id = op[1]
if vm_id not in vms:
results.append('error: not found')
else:
del vms[vm_id]
results.append('deleted')
return resultsTime complexity: Average O(1) for each create, update, and delete. Each list operation is O(n log n) because VMs are sorted by id before returning.. Space complexity: O(n), where n is the number of VMs currently stored..
Hints
- A hash map / dictionary keyed by VM id gives efficient average-time create, update, and delete.
- For deterministic `list` output, think about returning VMs in a fixed order rather than relying on hash map iteration order.