Recently, this Config Diff System question has been frequently appearing in Google VO. What seems like a simple dictionary comparison is actually a progressively challenging engineering design problem.
Many candidates breathe a sigh of relief after finishing the first version, only to be caught off guard by 3 rounds of Followups. Today, oavoservice breaks down this problem completely, from basic to production-level implementation.
๐ Problem Description
Given two nested dictionaries left and right, compare them and output a result dictionary with three sections:
- added โ Keys that exist in right but not in left
- deleted โ Keys that exist in left but not in right
- edited โ Keys that exist in both but have different values
๐ฏ Interview Flow Breakdown
Step 1: Clarify (Critical!)
The interviewer will first ask you to clarify. Make sure to ask:
- Q: Can values be nested dictionaries?
- A: Initially no need to consider nested, all values are primitive types
- Q: Can values be list/array?
- A: No need to consider
๐ก oavoservice Tip: The clarification phase determines your first version's complexity. Start simple and leave room for Followups.
โ Basic Version: Flat Dictionary Comparison
Approach
Three passes:
- Iterate through
leftkeys to find deleted and edited - Iterate through
rightkeys to find added
oavoservice Perfect Solution
def config_diff(left: dict, right: dict) -> dict:
result = {
"added": {},
"deleted": {},
"edited": {}
}
# Find deleted and edited
for key in left:
if key not in right:
result["deleted"][key] = left[key]
elif left[key] != right[key]:
result["edited"][key] = {"old": left[key], "new": right[key]}
# Find added
for key in right:
if key not in left:
result["added"][key] = right[key]
return result
Example
left = {"a": 1, "b": 2, "c": 3}
right = {"a": 1, "b": 5, "d": 4}
# Output:
{
"added": {"d": 4},
"deleted": {"c": 3},
"edited": {"b": {"old": 2, "new": 5}}
}
Complexity Analysis
- Time: O(n + m), where n and m are the number of keys in left and right
- Space: O(n + m) for storing results
Test Case Design
The interviewer will ask how you would design test cases:
- Empty dicts โ
{}, {}โ all empty - Identical โ
{"a": 1}, {"a": 1}โ all empty - Completely different โ
{"a": 1}, {"b": 2}โ deleted + added - Only edited โ
{"a": 1}, {"a": 2} - Mixed cases โ added + deleted + edited all present
๐ Followup 1: Support Nested Dictionary
Problem Change
Now values can be nested dictionaries, requiring recursive comparison.
Core Approach
- If both sides are dict โ recursive comparison
- If one side is dict and other is not โ treat as edited
- Other cases โ basic comparison logic
oavoservice Perfect Solution
def config_diff_nested(left: dict, right: dict) -> dict:
result = {
"added": {},
"deleted": {},
"edited": {}
}
all_keys = set(left.keys()) | set(right.keys())
for key in all_keys:
left_val = left.get(key)
right_val = right.get(key)
if key not in left:
# Added
result["added"][key] = right_val
elif key not in right:
# Deleted
result["deleted"][key] = left_val
elif isinstance(left_val, dict) and isinstance(right_val, dict):
# Recursively compare nested dicts
nested_diff = config_diff_nested(left_val, right_val)
# Only add non-empty results
if any(nested_diff.values()):
result["edited"][key] = nested_diff
elif left_val != right_val:
# Values differ (including type mismatch)
result["edited"][key] = {"old": left_val, "new": right_val}
return result
Example
left = {
"db": {"host": "localhost", "port": 3306},
"cache": {"enabled": True}
}
right = {
"db": {"host": "prod.db.com", "port": 3306},
"cache": {"enabled": True, "ttl": 300}
}
# Output:
{
"added": {},
"deleted": {},
"edited": {
"db": {
"added": {},
"deleted": {},
"edited": {"host": {"old": "localhost", "new": "prod.db.com"}}
},
"cache": {
"added": {"ttl": 300},
"deleted": {},
"edited": {}
}
}
}
๐ Followup 2: Support List as Value
Problem Change
Now values can be lists. How do you handle this?
Discussion Points (What the Interviewer Wants to Hear)
The interviewer may not require implementation, but wants to hear your design thinking:
Simple Approach: Whole List Comparison
- Compare two lists directly with
== - If different, mark as edited with old/new
- Compare two lists directly with
Complex Approach: Element-Level Comparison
- Need to define what "same element" means
- If list elements are dicts, may need an ID field for matching
- Similar to React's key concept
Order Sensitive vs Order Insensitive
- Are
[1, 2, 3]and[3, 2, 1]the same?
- Are
oavoservice Recommended Implementation (Whole Comparison)
def config_diff_with_list(left: dict, right: dict) -> dict:
result = {"added": {}, "deleted": {}, "edited": {}}
all_keys = set(left.keys()) | set(right.keys())
for key in all_keys:
left_val = left.get(key)
right_val = right.get(key)
if key not in left:
result["added"][key] = right_val
elif key not in right:
result["deleted"][key] = left_val
elif isinstance(left_val, dict) and isinstance(right_val, dict):
nested_diff = config_diff_with_list(left_val, right_val)
if any(nested_diff.values()):
result["edited"][key] = nested_diff
elif isinstance(left_val, list) and isinstance(right_val, list):
# Whole list comparison
if left_val != right_val:
result["edited"][key] = {"old": left_val, "new": right_val}
elif left_val != right_val:
result["edited"][key] = {"old": left_val, "new": right_val}
return result
๐ Followup 3: Alternative Output Structure
Problem Change
The interviewer may request a different output format, such as:
Flat Path Format:
{
"added": ["cache.ttl"],
"deleted": ["old_key"],
"edited": ["db.host"]
}
Or Detailed Format with Paths:
[
{"path": "db.host", "type": "edited", "old": "localhost", "new": "prod.db.com"},
{"path": "cache.ttl", "type": "added", "value": 300}
]
oavoservice Perfect Solution (Flat Path Version)
def config_diff_flat(left: dict, right: dict, prefix: str = "") -> dict:
result = {"added": [], "deleted": [], "edited": []}
all_keys = set(left.keys()) | set(right.keys())
for key in all_keys:
path = f"{prefix}.{key}" if prefix else key
left_val = left.get(key)
right_val = right.get(key)
if key not in left:
result["added"].append(path)
elif key not in right:
result["deleted"].append(path)
elif isinstance(left_val, dict) and isinstance(right_val, dict):
nested = config_diff_flat(left_val, right_val, path)
result["added"].extend(nested["added"])
result["deleted"].extend(nested["deleted"])
result["edited"].extend(nested["edited"])
elif left_val != right_val:
result["edited"].append(path)
return result
๐ก What the Interviewer is Really Testing
This problem tests more than algorithms:
- Clarification Skills โ Ask before you code
- Recursive Thinking โ Handling nested structures
- Edge Cases โ Type mismatches, null handling
- Engineering Mindset โ Output format design, extensibility
- Trade-off Discussion โ Multiple approaches for List comparison
๐คฏ Common Pitfalls
- First version too complex โ Considering nested from the start wastes time
- Recursive return value issues โ Handling empty nested results
- Missing type checks โ One side is dict, other is not
- Shallow Followup discussion โ Only mentioning one approach for List comparison
๐ oavoservice: Your Google VO Full Support
Google interviews are characterized by layered Followups โ one problem can be explored for 30-45 minutes. Many candidates do well on the basic version but get stumped during Followups.
oavoservice's Real-time VO Assistance helps you:
โ Real-time strategy hints โ Anticipate Followup directions
โ Edge case reminders โ Don't miss critical cases
โ Discussion point preparation โ Trade-off analysis support
โ Non-intrusive โ Compatible with Google Meet / Zoom
Don't let a Followup cost you your Google offer.
We consistently provide professional interview assistance services for major tech companies like Google, Meta, Amazon, and TikTok. Feel free to contact us if you're interested.
๐ Add WeChat now: Coding0201
Secure your Google interview opportunity!