OOD and Machine Coding
- Run Workday's object-oriented and machine-coding round in order: clarify, name classes, fix signatures, extend, test
- Build an in-memory, tenant-scoped key-value store as clean Java classes
- Solve two medium Workday problems: minimum swaps to sort, and a bracket validator
Workday builds enterprise software on Java and Spring, and its most consistently reported technical round reflects that. You get a domain, model it as objects, then make those objects run. The prompt is a small system, such as a ride-hailing app, a payments-and-cards model, an inventory manager, or the multi-tenant storage that a SaaS platform lives on. You clarify what it has to do, draw the classes, and define the methods. You write enough code to make it work. Then the interviewer changes the requirement to see whether your model bends or breaks. This lesson runs that round in order and works three problems from inside it. One is a tenant-scoped key-value store built as a class. The other two are medium algorithm problems that match Workday's easy-to-medium coding bar.
How Workday runs the OOD and machine-coding round
The round moves through five beats. Do them in order, and don't start typing the moment you hear the domain. First, clarify. Restate what the system must do and pin down the operations and their contracts. What does a read return when the key is absent? Does a delete report whether it removed anything? Does an update replace or append? A minute of clarifying questions reads as senior signal. Nobody takes it as stalling. Second, name the classes and interfaces. Identify the entities: the one that owns state and the ones that model records. Say the relationships and cardinality out loud. One tenant owns many keys. One customer owns many cards.
Third, fix the method signatures before the bodies. Decide the public surface, the arguments, the return types, and what each method promises, because the signatures are the contract the interviewer will push on. Fourth, build extensibility in from the start by keeping responsibilities separate and state private, so that when the requirement changes you add a class or a field rather than rewrite the core. Fifth, back it with tests, or at minimum narrate the cases you would write: the empty read, the overwrite, the double delete, the isolation boundary. Workday's interviewers reward a small system you can defend as it changes far more than a clever one-shot answer.
A machine-coding answer at Workday looks like Java that would survive code review. Pseudocode falls short. The first problem below takes this shape as a Java class: state kept private, a nested map for per-tenant isolation, and methods whose contracts are obvious from their signatures.
final class TenantStore { // tenant id -> that tenant's own isolated key/value bucket private final Map<String, Map<String, String>> data = new HashMap<>(); void put(String tenant, String key, String value) { data.computeIfAbsent(tenant, t -> new HashMap<>()).put(key, value); } String get(String tenant, String key) { Map<String, String> bucket = data.get(tenant); return bucket == null ? null : bucket.get(key); } boolean delete(String tenant, String key) { Map<String, String> bucket = data.get(tenant); return bucket != null && bucket.remove(key) != null; } List<String> keys(String tenant) { Map<String, String> bucket = data.get(tenant); if (bucket == null) return List.of(); List<String> out = new ArrayList<>(bucket.keySet()); Collections.sort(out); return out; }}The through-line of this round is one question: does your design absorb the next requirement. Keep state private, keep each class doing one job, and name the contract of every method. Then, when the interviewer bounds the history or adds a concurrent writer, you extend the model instead of tearing it down.
Machine coding: a tenant-scoped key-value store
The cleanest way to feel the machine-coding round is to build the thing Workday's own product is made of: isolated storage per tenant. Many customers share one running system, and no customer may ever see another's data. The same key can hold different values under different tenants. A read for one tenant must be blind to the rest. Stripped of the SaaS framing, this is a map of maps behind a small class, with put, get, delete, and keys as its public surface. What the interviewer watches is whether you keep the isolation airtight and the method contracts honest.
Tenant-Scoped Key-Value Store
Problem
TenantStore that isolates every tenant's data. Implement four methods:-
put(tenant, key, value) stores value under key for that tenant, overwriting any existing value. It returns nothing.-
get(tenant, key) returns the stored value, or null if that tenant has no such key.-
delete(tenant, key) removes the key for that tenant and returns true, or returns false if the key was not there.-
keys(tenant) returns that tenant's keys as a list sorted ascending, or an empty list if the tenant is unknown.The same key may exist under different tenants with different values, and no operation for one tenant may ever read or change another tenant's data.
Input: put("acme","currency","USD"); put("hooli","currency","EUR"); get("acme","currency"); get("hooli","currency")
Output: "USD", then "EUR"
Both tenants store the key "currency", but each read sees only its own tenant’s value, so the buckets never bleed into each other.
Input: put("acme","locale","en_US"); delete("acme","locale"); delete("acme","locale")
Output: true, then false
The first delete removes the key and reports true. The second finds nothing to remove and reports false.
Keep a map from tenant id to that tenant’s own map of key to value. Every method looks up the tenant bucket first, so isolation falls out for free: a missing tenant is simply an absent outer entry. Sort the keys only at read time in keys(), and skip sorting on every write.
Tenant-Scoped Key-Value Store
Click "Run" to execute your code
Test Cases
[["TenantStore",[]],["put",["acme","currency","USD"]],["put",["acme","locale","en_US"]],["put",["hooli","currency","EUR"]],["get",["acme","currency"]],["get",["hooli","currency"]],["get",["acme","timezone"]],["keys",["acme"]],["delete",["acme","locale"]],["delete",["acme","locale"]],["keys",["acme"]]]Expected: [null,null,null,null,"USD","EUR",null,["currency","locale"],true,false,["currency"]][["TenantStore",[]],["get",["ghost","x"]],["keys",["ghost"]],["delete",["ghost","x"]]]Expected: [null,null,[],false][["TenantStore",[]],["put",["t","k","v1"]],["put",["t","k","v2"]],["get",["t","k"]]]Expected: [null,null,null,"v2"][["TenantStore",[]],["put",["a","role","admin"]],["put",["b","role","viewer"]],["get",["a","role"]],["get",["b","role"]],["delete",["a","role"]],["get",["a","role"]],["get",["b","role"]]]Expected: [null,null,null,"admin","viewer",true,null,"viewer"][["TenantStore",[]],["put",["z","gamma","3"]],["put",["z","alpha","1"]],["put",["z","beta","2"]],["keys",["z"]]]Expected: [null,null,null,null,["alpha","beta","gamma"]][["TenantStore",[]],["put",["one","only","1"]],["keys",["one"]],["get",["one","only"]]]Expected: [null,null,["only"],"1"]Minimum swaps to sort an array
Beside the design round sits Workday's straight algorithm bar. It's easy to medium, and graded on a correct, clean solution more than raw speed. A reported phone-screen prompt is the minimum number of moves to sort an array, and the sharpest version asks for the fewest swaps of any two elements. The brute force keeps swapping the smallest misplaced element home, and it happens to be optimal. The elegant answer reads the count off the permutation directly. An array is a set of cycles, and each cycle of length k costs exactly k minus one swaps.
Minimum Swaps to Sort an Array
Problem
arr of distinct integers. In one move you may swap the elements at any two positions. Return the minimum number of swaps needed to sort the array into ascending order.Because every element is distinct, there is exactly one sorted arrangement, and the question is how few swaps reach it.
Input: arr = [4,3,2,1]
Output: 2
Swap 4 and 1, then swap 3 and 2, and the array is sorted. No single swap and no zero-swap arrangement can do it, so two is minimal.
Input: arr = [2,3,1]
Output: 2
The three elements form one cycle, and a cycle of length three costs two swaps.
Map each element to the position it must end up in, which turns the array into a permutation. Decompose that permutation into cycles: elements already in place are cycles of length one and cost nothing, and a cycle of length k needs exactly k minus one swaps to resolve.
Minimum Swaps to Sort an Array
Click "Run" to execute your code
Test Cases
[[4,3,2,1]]Expected: 2[[1,2,3]]Expected: 0[[2,3,1]]Expected: 2[[5]]Expected: 0[[2,1]]Expected: 1[[1,5,4,3,2]]Expected: 2A bracket validator that reports where it fails
The valid-parentheses validator is a reported Workday coding prompt, and interviewers rarely leave it at a plain true or false. A sharper version also asks where the string first goes wrong. That turns the classic stack into one that carries indices. The structure is the same push-openers, match-closers scan, and the twist is deciding, precisely, which position to blame when a closer has no partner or an opener is never closed.
Bracket Validator: First Failing Index
Problem
s made only of the six bracket characters ()[]{}. Return -1 if the string is balanced. Otherwise return the 0-based index of the first character where validation fails, defined as:- a closing bracket that has no matching open bracket, or whose most recent unmatched opener is the wrong type, fails at its own index, or
- if the scan finishes with unmatched openers left over, the failure is the index of the earliest such opener.
An empty string is balanced, so it returns
-1.Input: s = "([)]"
Output: 2
At index 2 the closer ) meets a most-recent opener of [, which is the wrong type, so validation fails there.
Input: s = "(()"
Output: 0
The scan ends with the opener at index 0 still unmatched, so its index is the reported failure.
Push each opener with its index onto a stack. On a closer, if the stack is empty or its top is the wrong type, that closer’s index is the answer. If the scan completes with the stack non-empty, the answer is the index stored at the bottom of the stack, the earliest opener that never closed.
Bracket Validator: First Failing Index
Click "Run" to execute your code
Test Cases
["([])"]Expected: -1["([)]"]Expected: 2["(()"]Expected: 0["))"]Expected: 0[""]Expected: -1["()]"]Expected: 2Common questions
What does Workday's machine-coding round test?
It tests whether you can turn a domain into clean objects and then defend them when the requirement moves. You clarify the operations and their contracts, name the classes and their relationships, fix the method signatures, keep state private so the model extends cleanly, and back it with the cases you would test. The tenant-store problem above is the shape it takes: a small system where the interviewer will press on isolation, idempotent deletes, and concurrency, so a design that answers those cleanly is the signal.
How hard is the algorithm bar next to the design round?
Easy to medium. It's graded on correctness, clean code, and edge cases you name yourself. Minimum swaps to sort rewards seeing the cycle structure and stating why a k-cycle costs k minus one. The bracket validator rewards a careful stack that carries indices, plus a sensible answer to the memory follow-up. Both reward clear reasoning about the invariant and the resource behavior over raw speed.
Should I write these in Java?
Yes, by default. Workday is a Java and Spring shop, the machine-coding round expects idiomatic Java, and the follow-ups lean on language internals like how a HashMap behaves and how you keep returned objects immutable. Interviewing in Java lets you answer those follow-ups fluently instead of translating them, which is why the static example above is Java even though the runnable solutions here are language-agnostic.
Key Takeaways
- ✓Workday’s signature round runs in five beats: clarify the operations and contracts, name the classes and interfaces, fix the method signatures, keep state private so the model extends, and back it with tests. The grade is whether your design absorbs the next requirement. A first answer that works is only the start.
- ✓The tenant-scoped key-value store is the machine-coding round in miniature. A map from tenant to that tenant’s own map makes isolation correct by construction, and the outer key carries the guarantee. The concurrency follow-up (ConcurrentHashMap, atomic bucket creation) is the load pressure Workday always applies.
- ✓Minimum swaps to sort is a permutation split into cycles, where a cycle of length k costs exactly k minus one swaps. Counting cycles in one pass gives both the optimal answer and the one-line proof of optimality, which Workday grades above a fast brute force.
- ✓The bracket validator is a stack that carries indices. A closer that cannot match fails at its own index, and leftover openers fail at the earliest one. The huge-input heap-overflow follow-up is the memory-awareness test Workday is known for.
Workday interview guideKnow what Workday asks before you walk in.
10 coding · 3 system design · 15 behavioral questions
Get their questions first.
InterviewLegend is independent and not affiliated with or endorsed by any company it covers.