Atlassian Previous Year Coding Questions

Atlassian (makers of Jira, Confluence, Trello, Bitbucket, OpsGenie) is known for one of the most engineer-friendly interview processes in the industry. Headquartered in Sydney with major campuses in Austin, New York, and Amsterdam, Atlassian's engineering culture centres on clean code, collaborative problem-solving, and its "Open Company, No Bullshit" values. The interview process is notably different from FAANG: there is a dedicated Values Interview round, and coding rounds reward readable, well-structured code over brute-force speed. Graph problems appear in almost every loop — this makes sense given that Jira's issue dependency system is fundamentally a directed graph. Tree traversals, string manipulation, and linked list problems round out the DSA focus. For LLD, Jira Issue Tracker and Rate Limiter are canonical problems. For HLD, expect Jira at scale, Confluence's real-time collaborative editing, and Atlassian's notification pipeline.


Hiring Process

Step 1: Resume Screening Atlassian values strong fundamentals, open-source contributions, and side projects. A GitHub profile with real commits matters here more than at many other companies.

Step 2: Online Assessment (HackerRank) Duration: 90 minutes. 2–3 coding problems. Focus on graphs, trees, and string manipulation. Problems are medium difficulty but expect clean code — partial credit for readable incomplete solutions over ugly complete ones.

Step 3: Technical Phone Screen 60 minutes. One medium-to-hard DSA problem. Interviewers care about your thought process: talk through your approach before coding, name variables well, and discuss edge cases proactively.

Step 4: Onsite Loop (4 rounds)

  • Coding Round 1: Graph or tree problem. Expect BFS/DFS on a graph that models a Jira-like structure (dependencies, blocking relationships, notification cascades).
  • Coding Round 2: String/array problem or a design-coding hybrid (e.g., implement a simplified LRU cache from scratch).
  • System Design Round: HLD — design Jira, Confluence, or the Atlassian notification service.
  • Values Interview: No code. Behavioural questions mapped to Atlassian's five values. Prepare STAR stories for each.

Step 5: Hiring Committee Review All four interviewers submit written feedback. The Values Interview carries equal weight to the coding rounds — a strong technical score with a poor values score results in rejection.

Tips: The single most impactful preparation is practising graph problems where nodes have domain meaning (users, issues, projects, teams). Atlassian interviewers often modify standard problems to have a Jira-flavoured framing — "given a project dependency graph, find all blocking issues for a given release." For the Values round, prepare 2–3 real stories for each value. For LLD, Jira Issue Tracker is asked in almost every loop — know it deeply.


Preparation Resources

Part 1 — OA Questions

1. Number of Islands Medium

OAGraph · BFS/DFS · GridLeetCode: #200

Count the number of islands in a binary grid. An island is surrounded by water and formed by connecting adjacent 1s horizontally or vertically. Atlassian frames this as counting disconnected project clusters in a dependency graph.

Input: grid=[["1","1","0","0"],["1","1","0","0"],["0","0","1","0"],["0","0","0","1"]]
Output: 3

Input: grid=[["1","1","1"],["0","1","0"],["1","1","1"]]
Output: 1

Approach: DFS/BFS from each unvisited '1'. Mark all reachable connected cells as visited ('0' or a visited marker). Increment island count each time you start a new DFS. Complexity: Time O(m*n) · Space O(m*n) Follow-up: Number of Distinct Islands (LC #694) — count unique island shapes by normalising DFS paths.


2. Clone Graph Medium

OAGraph · BFS · HashingLeetCode: #133

Return a deep copy of an undirected graph. Each node has a value and a list of neighbours.

Input: adjList = [[2,4],[1,3],[2,4],[1,3]]
Output: [[2,4],[1,3],[2,4],[1,3]]  (deep copy, different node objects)

Approach: BFS with a hash map (originalNode → clonedNode). For each node popped from the queue, iterate its neighbours: if the neighbour has no clone yet, create one and enqueue it. Add the cloned neighbour to the cloned node's neighbour list. Complexity: Time O(V+E) · Space O(V) Follow-up: Atlassian variant — clone a Jira project dependency graph where each issue node has a priority, status, and list of blocking issues.


3. Decode String Medium

OAStack · Strings · RecursionLeetCode: #394

Decode an encoded string. The encoding rule is k[encoded_string] meaning repeat encoded_string k times. Brackets can be nested.

Input: s = "3[a]2[bc]"
Output: "aaabcbc"

Input: s = "3[a2[c]]"
Output: "accaccacc"

Input: s = "2[abc]3[cd]ef"
Output: "abcabccdcdcdef"

Approach: Stack-based. Push (current_string, repeat_count) onto the stack when '[' is encountered. On ']', pop the pair and append current string repeated by count to the previous string. Complexity: Time O(output length) · Space O(nesting depth) Follow-up: What if k can be a multi-digit number? Parse digits greedily before '['.


4. Meeting Rooms II Medium

OAHeap · Greedy · IntervalsLeetCode: #253

Find the minimum number of conference rooms required to schedule all meetings (intervals).

Input: intervals = [[0,30],[5,10],[15,20]]
Output: 2

Input: intervals = [[7,10],[2,4]]
Output: 1

Approach: Sort by start time. Min-heap of end times. For each meeting, if the earliest-ending room finishes before this meeting starts, reuse it (pop and push new end time). Otherwise, add a new room (push end time). Answer = heap size. Complexity: Time O(n log n) · Space O(n) Follow-up: Employee Free Time (LC #759) — merge all employees' schedules and find gaps.


5. Top K Frequent Elements Medium

OAHeap · Bucket Sort · HashingLeetCode: #347

Return the k most frequent elements. Atlassian phrases this as: given Jira activity logs, return the k most active users.

Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]

Input: nums = [1], k = 1
Output: [1]

Approach: Frequency map + min-heap of size k. Push each (freq, element); if heap exceeds k, pop the minimum. Remaining heap contains the top-k. Complexity: Time O(n log k) · Space O(n) Follow-up: Bucket sort approach — O(n) using frequency array indexed by count. Explain the trade-offs.


6. Insert Interval Medium

OAArrays · IntervalsLeetCode: #57

Insert a new interval into a sorted list of non-overlapping intervals, merging as necessary.

Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]

Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]

Approach: Three phases: (1) add all intervals that end before newInterval starts, (2) merge all overlapping intervals with newInterval (update newInterval's end to the max end seen), (3) add all remaining intervals. Complexity: Time O(n) · Space O(n) Follow-up: Merge Intervals (LC #56) — sort then merge; same merging logic but needs sorting first.


Part 2 — Phone Screen Questions

7. Word Ladder Hard

Phone ScreenGraph · BFS · HashingLeetCode: #127

Find the shortest transformation sequence from beginWord to endWord, changing one letter at a time, where each intermediate word must exist in the dictionary.

Input: beginWord="hit", endWord="cog", wordList=["hot","dot","dog","lot","log","cog"]
Output: 5
Explanation: hit→hot→dot→dog→cog

Input: beginWord="hit", endWord="cog", wordList=["hot","dot","dog","lot","log"]
Output: 0  (endWord not in list)

Approach: BFS from beginWord. For each word, generate all one-letter-change neighbours by replacing each position with 'a'-'z' and checking the dictionary. BFS level = transformation length. Use a hash set for O(1) lookup and mark visited by removing from set. Complexity: Time O(n * L * 26) where L = word length · Space O(n) Follow-up: Word Ladder II (LC #126) — return all shortest paths. Requires BFS for levels + DFS/backtracking for path reconstruction.


8. Group Anagrams Medium

Phone ScreenHashing · Sorting · StringsLeetCode: #49

Group strings that are anagrams of each other.

Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]

Approach: Hash map keyed by the sorted string (canonical anagram form). Sorting each word costs O(L log L) per word; a 26-element character count array as key is O(L) and faster. Complexity: Time O(n * L log L) or O(n * L) with count key · Space O(n) Follow-up: Valid Anagram (LC #242) — single pair check. Find All Anagrams in a String (LC #438) — sliding window.


9. Flatten Nested List Iterator Medium

Phone ScreenStack · Iterator · DesignLeetCode: #341

Implement an iterator that flattens a nested list of integers on-demand. Atlassian asks this because Confluence page hierarchies are nested structures.

NestedIterator([[1,1],2,[1,1]])
next()→1, next()→1, next()→2, next()→1, next()→1

NestedIterator([1,[4,[6]]])
next()→1, next()→4, next()→6

Approach: Stack of iterators. Constructor pushes the top-level iterator. hasNext() peeks at the front of the current iterator: if it's a NestedInteger that is a list, pop it and push its iterator; if it's an integer, return true; if the current iterator is exhausted, pop it. Complexity: Time O(1) amortised per next() · Space O(depth) Follow-up: Flatten 2D Vector (LC #251) — simpler version with a fixed 2D structure.


10. Longest Substring Without Repeating Characters Medium

Phone ScreenSliding Window · HashingLeetCode: #3

Find the length of the longest substring without repeating characters.

Input: s = "abcabcbb"
Output: 3  ("abc")

Input: s = "bbbbb"
Output: 1  ("b")

Input: s = "pwwkew"
Output: 3  ("wke")

Approach: Sliding window with a hash map storing the last seen index of each character. When a repeated character is found, move the window's left pointer to max(left, lastSeen[char] + 1). Track maximum window size. Complexity: Time O(n) · Space O(min(n, charset)) Follow-up: Longest Substring with At Most K Distinct Characters (LC #340) — same sliding window, shrink when distinct count exceeds k.


11. Course Schedule Medium

Phone ScreenGraph · Topological Sort · Cycle DetectionLeetCode: #207

Determine if it is possible to finish all courses given prerequisites. Atlassian frames this as: can a Jira sprint be completed given issue blocking dependencies?

Input: numCourses=2, prerequisites=[[1,0]]
Output: true

Input: numCourses=2, prerequisites=[[1,0],[0,1]]
Output: false  (cycle: 0 requires 1 requires 0)

Approach: DFS cycle detection with three states per node: unvisited, in-progress, done. If you reach an in-progress node during DFS, a cycle exists → return false. Kahn's BFS topological sort also works: if the sorted result has fewer nodes than total, there's a cycle. Complexity: Time O(V+E) · Space O(V+E) Follow-up: Course Schedule II (LC #210) — return the actual topological order.


12. LRU Cache Medium

Phone ScreenDesign · HashMap · Doubly Linked ListLeetCode: #146

Design a data structure with O(1) get(key) and put(key, value) that evicts the least recently used item when capacity is exceeded.

LRUCache(2)
put(1,1), put(2,2), get(1)→1, put(3,3) [evicts 2], get(2)→-1, get(3)→3

Approach: HashMap (key → DLL node) + doubly linked list (MRU at head, LRU at tail). get: move the accessed node to the head, return value. put: if key exists, update and move to head; else create a new head node; if over capacity, remove the tail node and its map entry. Complexity: Time O(1) both operations · Space O(capacity) Follow-up: LFU Cache (LC #460) — evict the least frequently used; same idea but with a frequency map and per-frequency DLLs.


13. All Nodes Distance K in Binary Tree Medium

Phone ScreenTrees · BFS · Graph ConversionLeetCode: #863

Find all nodes exactly distance k from a target node in a binary tree. Atlassian frames this as: find all Jira issues exactly k hops away from a given issue in the dependency graph.

Input: root=[3,5,1,6,2,0,8,null,null,7,4], target=5, k=2
Output: [7,4,1]

Approach: Convert the tree to an undirected graph (add parent pointers via DFS). Then BFS from the target node for exactly k levels, tracking visited nodes. Complexity: Time O(n) · Space O(n) Follow-up: Amount of Time for Binary Tree to Be Infected (LC #2385) — same graph-conversion + BFS pattern.


Part 3 — Onsite Questions

14. Employee Importance Medium

OnsiteGraph · BFS/DFS · HashingLeetCode: #690

Given a list of employees with id, importance, and subordinates list, return the total importance of an employee and all their subordinates.

Input: employees=[[1,5,[2,3]],[2,3,[]],[3,3,[]]], id=1
Output: 11
Explanation: Employee 1 has importance 5 + Employee 2 (3) + Employee 3 (3) = 11

Approach: Build a hash map from id to Employee. BFS/DFS from the target employee. Sum importance values of all reachable nodes in the subordinate tree. Complexity: Time O(n) · Space O(n) Follow-up: Atlassian variant — given a project hierarchy in Jira, find the total story points assigned under a given epic (including all sub-tasks recursively).


15. Binary Tree Right Side View Medium

OnsiteTrees · BFS · Level OrderLeetCode: #199

Return the value of the rightmost node at each level of a binary tree (what you'd see from the right side).

Input: root = [1,2,3,null,5,null,4]
Output: [1,3,4]

Input: root = [1,null,3]
Output: [1,3]

Approach: BFS level order traversal. At each level, record the last node's value. Alternatively, DFS visiting right subtree before left, recording the first value seen at each depth. Complexity: Time O(n) · Space O(n) Follow-up: Left side view — same BFS, record first node per level instead of last.


16. Lowest Common Ancestor of a Binary Tree Medium

OnsiteTrees · DFSLeetCode: #236

Find the lowest common ancestor (LCA) of two nodes in a binary tree (not necessarily a BST).

Input: root=[3,5,1,6,2,0,8,null,null,7,4], p=5, q=1
Output: 3

Input: p=5, q=4
Output: 5

Approach: DFS returning whether p or q was found in each subtree. If both left and right subtrees return true, the current node is the LCA. If only one side returns true and the current node is p or q, the current node is the LCA. Complexity: Time O(n) · Space O(h) Follow-up: LCA of Deepest Leaves (LC #1123). LCA in a BST (LC #235) is simpler — use BST ordering to direct the traversal.


17. Construct Binary Tree from Preorder and Inorder Traversal Medium

OnsiteTrees · Divide & Conquer · HashingLeetCode: #105

Reconstruct a binary tree from its preorder and inorder traversal arrays.

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

Approach: preorder[0] is always the root. Find its position in inorder (use a hash map for O(1) lookup) to split left/right subtrees. Recurse with the corresponding sub-arrays. Complexity: Time O(n) with hash map · Space O(n) Follow-up: Construct from Postorder and Inorder (LC #106) — postorder's last element is the root; same logic mirrored.


18. Flatten Binary Tree to Linked List Medium

OnsiteTrees · DFS · In-placeLeetCode: #114

Flatten a binary tree into a linked list in-place using preorder traversal order (right pointers as next, left pointers as null).

Input: root = [1,2,5,3,4,null,6]
Output: [1,null,2,null,3,null,4,null,5,null,6]

Approach: Morris traversal style: for each node with a left child, find the rightmost node of the left subtree and set its right to the current node's right. Then move the left subtree to the right and null the left. Complexity: Time O(n) · Space O(1) Follow-up: The recursive DFS approach (post-order, track the previous node) is cleaner — when would you use it vs. the O(1) space Morris approach?


19. Path Sum II Medium

OnsiteTrees · Backtracking · DFSLeetCode: #113

Find all root-to-leaf paths where the sum of node values equals targetSum.

Input: root=[5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum=22
Output: [[5,4,11,2],[5,8,4,5]]

Approach: DFS with a running path list. Add the current node to the path. If it's a leaf and the remaining sum equals 0, record the path (copy it). Backtrack by removing the last node on return. Complexity: Time O(n * h) · Space O(h) Follow-up: Path Sum III (LC #437) — any path (not just root-to-leaf) using prefix sums.


20. Copy List with Random Pointer Medium

OnsiteLinked List · HashingLeetCode: #138

Deep copy a linked list where each node has a next and a random pointer that can point to any node or null.

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]  (deep copy)

Approach: Two-pass with a hash map (original → clone). First pass: create all clone nodes. Second pass: assign next and random pointers using the map. Complexity: Time O(n) · Space O(n) Follow-up: O(1) space approach — interleave cloned nodes with originals (A→A'→B→B'→...), set random pointers, then split the two lists.


21. Reorder List Medium

OnsiteLinked List · Two PointersLeetCode: #143

Reorder a linked list L0→L1→...→Ln to L0→Ln→L1→Ln-1→L2→Ln-2→...

Input: head = [1,2,3,4]
Output: [1,4,2,3]

Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]

Approach: Three steps — (1) find the middle using slow/fast pointers, (2) reverse the second half, (3) merge the two halves by interleaving. Complexity: Time O(n) · Space O(1) Follow-up: Odd Even Linked List (LC #328) — group all odd-indexed nodes before even-indexed nodes.


22. Find the Duplicate Number Medium

OnsiteFloyd's Cycle Detection · ArraysLeetCode: #287

Given n+1 integers in range [1,n], find the one duplicate without modifying the array and using only O(1) extra space.

Input: nums = [1,3,4,2,2]
Output: 2

Input: nums = [3,1,3,4,2]
Output: 3

Approach: Floyd's Cycle Detection. Treat nums as a linked list where nums[i] points to node nums[i]. The duplicate creates a cycle. Phase 1: find the intersection. Phase 2: find the cycle entrance (move one pointer from head, one from intersection — they meet at the duplicate). Complexity: Time O(n) · Space O(1) Follow-up: Why does this work? Prove that the cycle entrance corresponds to the duplicate value.


23. Search in Rotated Sorted Array Medium

OnsiteBinary SearchLeetCode: #33

Search for a target in a rotated sorted array in O(log n).

Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4

Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1

Approach: Binary search with two cases. At mid, check which half is sorted (nums[lo] ≤ nums[mid] means left half is sorted). Determine if target lies in the sorted half; if yes, search there, else search the other half. Complexity: Time O(log n) · Space O(1) Follow-up: Search in Rotated Sorted Array II (LC #81) — with duplicates. Worst case O(n) because you can't determine which half is sorted when nums[lo]nums[mid]nums[hi].


24. Three Sum Medium

OnsiteTwo Pointers · SortingLeetCode: #15

Find all unique triplets in an array that sum to zero.

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]

Input: nums = [0,0,0]
Output: [[0,0,0]]

Approach: Sort. For each index i, use two pointers (lo=i+1, hi=end) to find pairs summing to -nums[i]. Skip duplicates by advancing past equal values after finding a match or moving past a fixed element. Complexity: Time O(n²) · Space O(1) Follow-up: 3Sum Closest (LC #16), 4Sum (LC #18). Why does sorting + two pointers eliminate duplicates correctly?


25. Spiral Matrix Medium

OnsiteMatrix · SimulationLeetCode: #54

Return all elements of an m×n matrix in spiral order.

Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]

Input: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]

Approach: Maintain four boundaries (top, bottom, left, right). Traverse right along top, down along right, left along bottom, up along left. Shrink boundaries after each pass. Stop when boundaries cross. Complexity: Time O(m*n) · Space O(1) Follow-up: Spiral Matrix II (LC #59) — fill a matrix in spiral order with numbers 1 to n².


26. Rotate Image Medium

OnsiteMatrix · Math · In-placeLeetCode: #48

Rotate an n×n matrix 90 degrees clockwise in-place.

Input: [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]

Approach: Two steps — (1) transpose the matrix (swap matrix[i][j] with matrix[j][i]), (2) reverse each row. Complexity: Time O(n²) · Space O(1) Follow-up: Rotate 90° counter-clockwise — reverse each row first, then transpose. 180° — transpose then reverse columns, or just reverse the whole matrix.


27. Set Matrix Zeroes Medium

OnsiteMatrix · In-placeLeetCode: #73

If a matrix element is 0, set its entire row and column to 0, in-place.

Input: [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]

Input: [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]

Approach: O(1) space — use the first row and first column as markers. Scan the matrix; for each zero, mark its row's first element and column's first element as zero. Apply the markers. Handle the first row and first column separately with boolean flags. Complexity: Time O(m*n) · Space O(1) Follow-up: Game of Life (LC #289) — same "in-place state transition" pattern using bit encoding to store old and new state simultaneously.


28. Product of Array Except Self Medium

OnsiteArrays · Prefix ProductLeetCode: #238

Return an array where each element is the product of all other elements. No division allowed.

Input: nums = [1,2,3,4]
Output: [24,12,8,6]

Input: nums = [-1,1,0,-3,3]
Output: [0,0,9,0,0]

Approach: Left pass — result[i] = product of all elements to the left of i. Right pass — multiply result[i] by the running product of all elements to the right. One output array + one running variable = O(1) extra space. Complexity: Time O(n) · Space O(1) Follow-up: What if the array contains zeros — can there be two zeros, and how does that affect the result?


29. Sort Colors (Dutch National Flag) Medium

OnsiteTwo Pointers · In-placeLeetCode: #75

Sort an array of 0s, 1s, and 2s in-place (one pass, O(1) space).

Input: nums = [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]

Input: nums = [2,0,1]
Output: [0,1,2]

Approach: Dutch National Flag algorithm. Three pointers: lo (next 0 position), mid (current), hi (next 2 position). If nums[mid]0, swap with lo, advance both. If nums[mid]2, swap with hi, decrement hi only. If 1, advance mid. Complexity: Time O(n) · Space O(1) Follow-up: This is Dijkstra's 3-way partition — how does it generalise to k-way partitioning (e.g., sort by k distinct priorities)?


30. Generate Parentheses Medium

OnsiteBacktracking · StringsLeetCode: #22

Generate all valid combinations of n pairs of parentheses.

Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]

Input: n = 1
Output: ["()"]

Approach: Backtracking. Track open and close counts. Add '(' if open < n; add ')' if close < open. When the string length is 2n, record it. *Complexity: Time O(4^n / sqrt(n)) (Catalan number) · Space O(n) Follow-up: Valid Parentheses (LC &#35;20) — validate a string. Remove Invalid Parentheses (LC &#35;301) — remove minimum to make valid.


31. Simplify Path Medium

OnsiteStack · StringsLeetCode: &#35;71

Convert a Unix-style absolute path to its canonical form.

Input: path = "/home//foo/"
Output: "/home/foo"

Input: path = "/home/user/Documents/../Pictures"
Output: "/home/user/Pictures"

Input: path = "/../"
Output: "/"

Approach: Split by '/'. For each component: skip '' and '.'; for '..', pop the stack if non-empty; otherwise push the component. Join the stack with '/' and prepend '/'. Complexity: Time O(n) · Space O(n) Follow-up: Atlassian frames this as normalising a Confluence page path with relative navigation links.


32. Partition Equal Subset Sum Medium

OnsiteDynamic Programming · 0/1 KnapsackLeetCode: &#35;416

Determine if a set of integers can be partitioned into two subsets with equal sum.

Input: nums = [1,5,11,5]
Output: true
Explanation: [1,5,5] and [11]

Input: nums = [1,2,3,5]
Output: false

Approach: Target = totalSum / 2 (if odd, return false). dp[j] = true if a subset with sum j is achievable. For each number, update dp right to left: dp[j] |= dp[j - num]. Complexity: Time O(n * sum) · Space O(sum) Follow-up: Subset Sum Count (LC &#35;494 Target Sum) — count the number of ways instead of just feasibility.


33. Unique Paths Medium

OnsiteDynamic Programming · CombinatoricsLeetCode: &#35;62

Count the number of unique paths from the top-left to the bottom-right of an m×n grid, moving only right or down.

Input: m=3, n=7
Output: 28

Input: m=3, n=2
Output: 3

Approach: dp[i][j] = dp[i-1][j] + dp[i][j-1]. First row and column are all 1s. Optimise to O(n) space by maintaining a single row. Complexity: Time O(m*n) · Space O(n) Follow-up: Unique Paths II (LC &#35;63) — with obstacles. Mathematical solution: C(m+n-2, m-1) using combinatorics.


34. Maximum Subarray (Kadane's) Medium

OnsiteDynamic Programming · GreedyLeetCode: &#35;53

Find the subarray with the largest sum.

Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1]

Input: nums = [1]
Output: 1

Approach: Kadane's algorithm. currentMax = max(nums[i], currentMax + nums[i]). globalMax = max(globalMax, currentMax). Reset the running sum when adding the current element alone is better. Complexity: Time O(n) · Space O(1) Follow-up: Return the actual subarray indices. Maximum Sum Circular Subarray (LC &#35;918) — total sum minus the minimum subarray sum.


35. Zigzag Level Order Traversal Medium

OnsiteTrees · BFSLeetCode: &#35;103

Return level order traversal where alternate levels are reversed (zigzag pattern).

Input: root = [3,9,20,null,null,15,7]
Output: [[3],[20,9],[15,7]]

Approach: BFS level order. For each level, collect values; if the level index is odd, reverse the list before appending to results. Or use a deque and alternate between appendLeft and appendRight. Complexity: Time O(n) · Space O(n) Follow-up: Maximum Level Sum of a Binary Tree (LC &#35;1161) — same BFS, track which level has the max sum.


36. Count Good Nodes in Binary Tree Medium

OnsiteTrees · DFSLeetCode: &#35;1448

A node is "good" if no node on the path from root to that node has a value greater than the node's value. Count all good nodes.

Input: root = [3,1,4,3,null,1,5]
Output: 4

Input: root = [3,3,null,4,2]
Output: 3

Approach: DFS passing the maximum value seen so far on the current path. A node is good if node.val >= maxSoFar. Recurse with max(maxSoFar, node.val). Complexity: Time O(n) · Space O(h) Follow-up: Path In Zigzag Labelled Binary Tree (LC &#35;1104) — uses path properties in a labelled complete binary tree.


37. Letter Case Permutation Medium

OnsiteBacktracking · Strings · BFSLeetCode: &#35;784

Given a string, generate all permutations by changing the case of letters (digits stay fixed).

Input: s = "a1b2"
Output: ["a1b2","a1B2","A1b2","A1B2"]

Input: s = "3z4"
Output: ["3z4","3Z4"]

Approach: Backtracking. For each character: if digit, recurse to the next position; if letter, recurse with lowercase and with uppercase. Complexity: Time O(2^L * n) where L = number of letters · Space O(L) Follow-up: Subsets (LC &#35;78) — same backtracking template; letter case permutation is a variant with a fixed-structure decision tree.


38. Design Jira Issue Tracker (LLD) Hard

Onsite · LLDOOP · Design · Graph

Design Jira's issue tracker. Support creating issues, assigning them to users, setting priorities, tracking status transitions (To Do → In Progress → Done), adding comments, and querying all issues blocking a given issue.

IssueTracker.createIssue(title, description, priority, assignee) → Issue
IssueTracker.updateStatus(issueId, status)
IssueTracker.addBlocker(issueId, blockedById)
IssueTracker.getBlockedBy(issueId) → [Issue]
IssueTracker.addComment(issueId, author, text)
IssueTracker.getIssuesByAssignee(userId) → [Issue]

Approach: Classes: Issue (id, title, description, priority, status, assignee, comments, blockers), User (id, name, email), Comment (id, author, text, timestamp), IssueTracker (issues map, users map). Status as an enum with a valid-transitions map (state machine). addBlocker creates a directed edge in a dependency graph (Issue → blocks Issue). getBlockedBy does a DFS/BFS on the blocker graph. Priority as enum (CRITICAL, HIGH, MEDIUM, LOW). IssueTracker also has getIssuesByFilter(status, priority, assignee) using a stream/filter pattern. Key Design Principles: State machine for status transitions, directed graph for blocking relationships, Strategy pattern for different query filters Follow-up: How would you detect a circular blocking dependency (Issue A blocks B which blocks A) and prevent it?


39. Design Rate Limiter (LLD) Medium

Onsite · LLDOOP · Design · Concurrency

Design a rate limiter that allows at most N requests per user per time window. Support multiple algorithms: Fixed Window, Sliding Window Log, and Token Bucket.

RateLimiter.isAllowed(userId) → boolean
RateLimiter.setLimit(userId, maxRequests, windowSeconds)

Approach: RateLimiter interface with isAllowed(userId). FixedWindowRateLimiter: map of (userId → {count, windowStart}); reset count when current time > windowStart + windowSize. SlidingWindowLogRateLimiter: map of (userId → sorted timestamp queue); remove expired entries older than window, allow if queue size < limit. TokenBucketRateLimiter: map of (userId → {tokens, lastRefill}); refill tokens since last call at rate = maxTokens/windowSeconds; allow if tokens > 0. All implementations must be thread-safe — use synchronized blocks or ReentrantLock per userId. Key Design Principles: Strategy pattern for algorithm interchangeability, per-user locking for concurrency, clean separation between rate limit logic and storage Follow-up: Token Bucket allows bursts; Fixed Window has a boundary problem (2× requests at the window edge). Which does Atlassian's API gateway use and why?


40. Design Atlassian Audit Log System (LLD) Medium

Onsite · LLDOOP · Design · Observer

Design Atlassian's audit log system. Every action on a Jira issue, Confluence page, or Bitbucket repository must be logged with actor, action, resource, timestamp, and metadata. Logs must be queryable by resource, actor, time range, and action type.

AuditLogger.log(actor, action, resource, metadata)
AuditLogger.query(filters: {actor?, resource?, actionType?, from?, to?}) → [AuditEntry]

Approach: AuditEntry (id, actor, action, resourceType, resourceId, timestamp, metadata map). AuditLogger wraps an AuditStore. AuditStore has two implementations: InMemoryAuditStore (sorted list + indexed maps for O(1) lookup by actor/resource) and DatabaseAuditStore (delegates to a repository). Observer pattern: any Jira/Confluence service publishes events to an EventBus; AuditLogger subscribes and records. query() combines filters with AND logic, applies time range first (most selective), then narrows by actor/resource/action. Key Design Principles: Observer for decoupled log collection, immutable AuditEntry, pluggable store backend, composite filter pattern for queries Follow-up: How would you guarantee exactly-once audit logging even if the service crashes mid-write?


41. Design Jira at Scale (HLD) Hard

Onsite · HLDSystem Design

Design Jira — a project tracking system used by 300,000 companies with 10M+ daily users. Support creating/updating/searching issues, sprint planning, backlog management, and real-time notifications when issues are updated.

Functional: createIssue, updateIssue, searchIssues(JQL), getSprintBoard, assignIssue, addComment
Non-functional: 10M DAU, <200ms search, multi-tenant (each company is isolated), real-time updates

Approach: Multi-tenancy: each Jira workspace (company) is a tenant with data isolated by workspaceId. Issue storage: PostgreSQL with workspaceId as a sharding key — all queries are scoped to one workspace, so cross-shard joins are rare. Search: Jira Query Language (JQL) is parsed by a Query Parser into a structured query → Elasticsearch for full-text + faceted search (indexed by workspaceId). Real-time: issue updates published to Kafka → Notification Service fans out to WebSocket connections for active users on the board (via a WebSocket Gateway with user-session routing). Caching: Sprint boards cached in Redis (TTL 30s, invalidated on issue update). Attachments: S3 with pre-signed URLs. Workflow engine: issue status transitions validated against a per-project workflow graph stored in PostgreSQL. Key Concepts: Multi-tenancy with workspace sharding, Elasticsearch for JQL, Kafka + WebSocket for real-time, Redis board cache, workflow state machine Follow-up: A customer's workspace has 5M issues. How do you handle a JQL query that returns 500,000 results — pagination, cursors, or streaming?


42. Design Confluence Real-time Collaborative Editing (HLD) Hard

Onsite · HLDSystem Design

Design Confluence's real-time collaborative editing feature — multiple users editing the same page simultaneously, seeing each other's changes in real time (similar to Google Docs).

Functional: openPage(pageId), applyEdit(pageId, delta), getPageHistory(pageId), resolveMergeConflict(pageId)
Non-functional: <100ms latency for edits to propagate, consistent final state across all clients, offline support

Approach: Operational Transformation (OT) or CRDT for conflict-free merging of concurrent edits. Architecture: Client sends an operation (delta) with its local version number to a Collaboration Service. Collaboration Service transforms the incoming operation against all concurrent operations (OT) → applies to the document state → broadcasts the transformed operation to all other WebSocket-connected clients on that page. Document state is stored as a sequence of operations (operation log) in Redis (fast) + persisted to PostgreSQL asynchronously. Page snapshots created every N operations for faster load. Conflict resolution: OT guarantees all clients converge to the same final state without manual merge. Presence: each client sends a cursor position heartbeat; Collaboration Service broadcasts to other clients for live cursor display. Key Concepts: Operational Transformation for conflict-free concurrent edits, operation log as source of truth, WebSocket for real-time propagation, periodic snapshots for performance Follow-up: What are the trade-offs between OT (used by Google Docs) and CRDT (used by Figma/Notion) for this use case?


43. Design Atlassian Notification Service (HLD) Hard

Onsite · HLDSystem Design

Design Atlassian's cross-product notification service. When a Jira issue is assigned to you, a Confluence page is edited, or a Bitbucket PR is approved, you get notified via in-app notification, email, and Slack. 10M users, 50M events/day.

Functional: sendNotification(event), getUserNotifications(userId, filters), markAsRead(notificationId), updatePreferences(userId, preferences)
Non-functional: <5s delivery for in-app, at-least-once delivery, user preferences respected, no spam

Approach: Event pipeline: Jira/Confluence/Bitbucket publish events to Kafka (topic per product). Notification Service consumes events → applies fan-out: for each event, determine affected users (e.g., all watchers of the issue) → look up their channel preferences (DB + Redis cache) → enqueue delivery jobs per channel. Channel workers: InAppWorker (writes to notifications table in Postgres, pushes via WebSocket), EmailWorker (SES/SendGrid), SlackWorker (Slack Webhooks). Preference engine: per user per product per event-type toggle. Deduplication: within a 5-minute window, batch similar events (e.g., 10 comments on the same issue = one digest email). Unread count: Redis counter per user, invalidated on markAsRead. Key Concepts: Kafka fan-out, per-channel delivery workers, preference engine, digest batching, Redis for unread counts Follow-up: How do you handle a user who has 50,000 watchers on a popular Confluence page — fan-out at write vs. fan-out at read?


44. Maximum Width of Binary Tree Medium

OnsiteTrees · BFSLeetCode: &#35;662

Find the maximum width of a binary tree where width is the number of nodes between the leftmost and rightmost non-null nodes at any level (including null nodes in between).

Input: root = [1,3,2,5,3,null,9]
Output: 4

Input: root = [1,3,2,5,null,null,9,6,null,7]
Output: 7

Approach: BFS with position indices. Left child of position i has index 2i, right child has 2i+1. At each level, width = rightmost index - leftmost index + 1. Normalise indices by subtracting the leftmost index at each level to prevent integer overflow. **Complexity: Time O(n) · Space O(n) Follow-up: Why is normalisation at each level required? What is the maximum possible index value without it?


45. Jump Game Medium

OnsiteGreedyLeetCode: &#35;55

Determine if you can reach the last index from the first index. nums[i] is the maximum jump length from index i.

Input: nums = [2,3,1,1,4]
Output: true

Input: nums = [3,2,1,0,4]
Output: false

Approach: Track the maximum reachable index. For each position i ≤ maxReach, update maxReach = max(maxReach, i + nums[i]). If maxReach ever falls below i, return false. If maxReach ≥ last index, return true. Complexity: Time O(n) · Space O(1) Follow-up: Jump Game II (LC &#35;45) — minimum jumps. Jump Game VII (LC &#35;1871) — jump from intervals.


46. Minimum Path Sum Medium

OnsiteDynamic ProgrammingLeetCode: &#35;64

Find the path from the top-left to the bottom-right of a grid with the minimum sum of numbers along the path (only right or down moves).

Input: grid = [[1,3,1],[1,5,1],[4,2,1]]
Output: 7
Explanation: 1→3→1→1→1

Input: grid = [[1,2,3],[4,5,6]]
Output: 12

Approach: dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]. Can be done in-place by modifying the grid. Optimise to O(n) space with a rolling 1D array. Complexity: Time O(m*n) · Space O(n) Follow-up: Triangle (LC &#35;120) — minimum path sum from top to bottom in a triangle; same bottom-up DP.


47. Intersection of Two Linked Lists Easy

OnsiteLinked List · Two PointersLeetCode: &#35;160

Find the node where two singly linked lists intersect. Return null if no intersection.

listA: a1→a2→c1→c2→c3
listB: b1→b2→b3→c1→c2→c3
Output: c1

Approach: Two pointers. When pointer A reaches the end of list A, redirect it to the head of list B (and vice versa). They traverse an equal total distance (lenA + lenB) and meet at the intersection node (or both reach null simultaneously if no intersection). Complexity: Time O(m+n) · Space O(1) Follow-up: Linked List Cycle II (LC &#35;142) — same two-pointer technique to find cycle entry point.


48. Find Minimum in Rotated Sorted Array Medium

OnsiteBinary SearchLeetCode: &#35;153

Find the minimum element in a rotated sorted array (no duplicates) in O(log n).

Input: nums = [3,4,5,1,2]
Output: 1

Input: nums = [4,5,6,7,0,1,2]
Output: 0

Approach: Binary search. If nums[mid] > nums[hi], the minimum is in the right half. Otherwise it's in the left half (including mid). When lo==hi, the minimum is found. Complexity: Time O(log n) · Space O(1) Follow-up: Find Minimum in Rotated Sorted Array II (LC &#35;154) — with duplicates; worst case O(n).


49. Design Twitter / Social Feed (LLD) Medium

Onsite · LLDOOP · Design · HeapLeetCode: &#35;355

Design a simplified Twitter. Support postTweet, getNewsFeed (most recent 10 tweets from self and followed users), follow, and unfollow.

Twitter.postTweet(userId, tweetId)
Twitter.getNewsFeed(userId) → [tweetId] (most recent 10)
Twitter.follow(followerId, followeeId)
Twitter.unfollow(followerId, followeeId)

Approach: User map (userId → set of followeeIds). Tweet map (userId → list of (timestamp, tweetId) in insertion order). getNewsFeed: collect iterators for the user's own tweets and all followees' tweets. Use a max-heap of (timestamp, tweetId, iterator, nextIndex) to merge-sort up to 10 tweets. Complexity: Time O(k log n) for getNewsFeed where k=10, n=followees · Space O(users + tweets) Follow-up: Atlassian frames this as: given activity streams from multiple Jira projects a user follows, return the 10 most recent events across all of them.


50. Merge Intervals Medium

OnsiteSorting · IntervalsLeetCode: &#35;56

Merge all overlapping intervals and return the merged list.

Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]

Input: intervals = [[1,4],[4,5]]
Output: [[1,5]]

Approach: Sort by start time. Iterate: if the current interval overlaps with the last merged interval (current.start ≤ last.end), extend last.end = max(last.end, current.end). Otherwise, push the current interval as a new merged interval. Complexity: Time O(n log n) · Space O(n) Follow-up: Non-Overlapping Intervals (LC &#35;435) — minimum removals to make intervals non-overlapping. Both are classic Atlassian sprint planning problems.


Preparation Tips

Atlassian interviewers are known for caring as much about how you think as what you produce. Talk through your approach before writing any code, name your variables well, and discuss time/space complexity without being asked. For DSA, graphs and trees dominate — practise them until every traversal variation (BFS, DFS, level-order, zigzag, right-side view, LCA, distance-k) is second nature. For the Values Interview, prepare two real stories for each of Atlassian's five values — vague answers are rejected outright. For LLD, practise Jira Issue Tracker and Rate Limiter until you can implement them cleanly in 90 minutes. For HLD, know the real-time collaboration architecture (OT vs CRDT) — Confluence's collaborative editor comes up in almost every senior loop.

Join Telegram group to get the latest Atlassian OA questions and connect with candidates currently in the Atlassian interview process.

Useful Resources