LogIn
I don't have account.

My Adobe SDE Interview Experience (Aug 2026) 5 Rounds, Selected

Tanvi Deshmukh
423 Views

I want to share my Adobe interview story. I will tell you what happened in each round, what I got right, where I got stuck and what the interviewer said to help me when I was stuck. I will also show the code for every DSA question, starting from my first (slow) idea and ending with the best idea. I hope this helps you if you have an Adobe interview coming up.

Result: Selected.

Detail Info
Company Adobe
Role SDE (Backend Developer)
Total rounds 5
Coding problems 4
Overall Difficulty ⭐⭐⭐☆☆ (3/5)
Result Selected

Round 1: Aptitude Test and Technical MCQs (60–90 minutes)

This round had two parts and no live interviewer. It was more like a test.

The first part was an aptitude test. It had logical reasoning questions, basic math and pattern recognition questions. Nothing about coding here, just general thinking speed.

The second part had 20 technical MCQs (multiple choice questions). These covered DSA basics, Operating Systems (things like processes, threads and memory), DBMS (normalization, joins, indexing) and SQL optimization.

What I'd Tell Someone Before This Round

I did not treat this round as "just an MCQ test," and I am glad I didn't. A few of the OS and DBMS questions were tricky in a quiet way they looked simple, but one wrong word in the question could flip the answer. For example, a question about "which type of join returns all rows from both tables even when there is no match" is easy if you know the difference between an inner join and a full outer join, but easy to get wrong if you're rushing.

My tip: don't rush through MCQs just because there is no coding. Read each question twice before picking an answer, especially on OS and DBMS topics.

Round 2: DSA Coding Round (60 minutes, 2 problems)

This round had two coding problems. Both were based on arrays and trees.

Problem 1: Rotate Array

You get an array of numbers. You need to rotate it to the right by k steps. For example, [1,2,3,4,5,6,7] rotated right by 3 steps becomes [5,6,7,1,2,3,4].

My first idea (brute force): I said, "I can just rotate the array one step at a time and do this k times." One rotation means: take the last number and put it at the front, then shift everything else one place to the right.

static void bruteForce(int[] nums, int k) {
    int n = nums.length;
    k = k % n;
    for (int t = 0; t < k; t++) {
        int last = nums[n - 1];
        for (int i = n - 1; i > 0; i--) {
            nums[i] = nums[i - 1];
        }
        nums[0] = last;
    }
}

I said out loud that this works, but it is slow. Doing one rotation takes O(n) time and I am doing it k times, so the total time is O(n × k). If k is close to n, this becomes close to O(n²), which is not great for a large array.

The interviewer just asked, "Can you do this faster, maybe without doing it step by step?" That question pushed me to think of a smarter way.

A better idea (using extra space): I can build a brand new array. Every number moves to its new correct position in one pass. This is O(n) time, but it uses O(n) extra space, since I need a second array.

static void extraArray(int[] nums, int k) {
    int n = nums.length;
    k = k % n;
    int[] result = new int[n];
    for (int i = 0; i < n; i++) {
        result[(i + k) % n] = nums[i];
    }
    System.arraycopy(result, 0, nums, 0, n);
}

The best idea (reverse trick, no extra space): This is the one I actually used in the interview and it is a nice trick once you see it. You reverse the whole array first. Then you reverse the first k numbers. Then you reverse the rest. That's it.

static void optimalReverseTrick(int[] nums, int k) {
    int n = nums.length;
    k = k % n;
    reverse(nums, 0, n - 1);   // reverse everything
    reverse(nums, 0, k - 1);   // reverse the first k numbers
    reverse(nums, k, n - 1);   // reverse the rest
}

static void reverse(int[] nums, int left, int right) {
    while (left < right) {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
        left++;
        right--;
    }
}

This is O(n) time and O(1) extra space meaning it does not need any second array at all. It rotates the array in place. I tested it with [1,2,3,4,5,6,7] and k=3 and it gave [5,6,7,1,2,3,4], which is correct. I also checked what happens if k is bigger than the array size like k=5 on a 3-number array and the trick still works because I take k % n first.

I explained to the interviewer why the reverse trick works: rotating right by k means the last k numbers move to the front and the first n-k numbers move to the back, but their own order inside each group does not change. Reversing everything once flips both groups, then reversing each group again inside itself puts each group back in the right order, but now they are in the right spots too.

Follow-Up Questions

1. What if k is 0, does your rotate function still work?

Yes, I said if k is 0, none of the reverse calls actually move anything meaningful in a way that changes the final order, since reversing the "first 0 elements" and reversing "elements from index 0 to n-1" (the whole array again) still lands back on the same array after the full reverse and the two half reverses cancel out correctly. I mentioned I'd still want to test this edge case directly instead of just assuming it.

Problem 2: All Elements in Two Binary Search Trees

Leetcode Link: All Elements in Two BSTs

You get two Binary Search Trees (BSTs). You need to return all the numbers from both trees, combined into one single sorted list.

For this one, I knew the right idea quickly, because I remembered an important fact about BSTs: if you do an in-order traversal of a BST (visit left side, then the node, then right side), you always get the numbers in sorted order for free. No extra sorting needed.

So my plan was: do an in-order traversal of tree 1 to get a sorted list. Do an in-order traversal of tree 2 to get another sorted list. Then merge these two sorted lists into one, the same way you merge two lists in merge sort.

static void inorder(TreeNode node, List<Integer> out) {
    if (node == null) return;
    inorder(node.left, out);
    out.add(node.val);
    inorder(node.right, out);
}

static List<Integer> optimal(TreeNode root1, TreeNode root2) {
    List<Integer> list1 = new ArrayList<>();
    List<Integer> list2 = new ArrayList<>();
    inorder(root1, list1);
    inorder(root2, list2);

    List<Integer> merged = new ArrayList<>();
    int i = 0, j = 0;
    while (i < list1.size() && j < list2.size()) {
        if (list1.get(i) <= list2.get(j)) merged.add(list1.get(i++));
        else merged.add(list2.get(j++));
    }
    while (i < list1.size()) merged.add(list1.get(i++));
    while (j < list2.size()) merged.add(list2.get(j++));
    return merged;
}

I did point out the slower way too, just to show I understood why my way was better: you could throw every number from both trees into one big list and then sort that list at the end. That works, but sorting takes O((m+n) log(m+n)) time. My way skips the sorting step completely and just merges, which is O(m+n) time faster and it uses the special sorted property of a BST instead of ignoring it.

I tested this on two small trees and got the correct merged, sorted list both ways, so I was confident the faster method was right, not just faster.

Follow-Up Questions

1. For the two-BST problem, does it matter if the trees are not balanced?

No I said in-order traversal visits every node no matter how the tree is shaped, so it still gives a sorted list even for a very lopsided tree. The time complexity is still based on the number of nodes, not the shape.

2. Could you solve the two-BST problem without collecting the full list into memory first?

I said you could use two iterators (using an explicit stack for each tree's in-order traversal) and pull one value at a time from whichever tree has the smaller "next" value, similar to how you would merge two linked lists lazily. I said this would help if the final merged list needs to be streamed instead of stored fully in memory, but for this problem, since we need to return the whole list anyway, the simpler two-list-then-merge approach is easier to write correctly under interview time pressure.

Round 3: Mixed Round One Coding Problem Plus a Personal Conversation (60 minutes)

This round started with a short coding problem. I honestly don't remember the exact question anymore it was somewhere between easy and medium and I was able to solve it, but the details did not stay in my memory the way the other two problems did.

After the coding part, the conversation became more personal and relaxed. The interviewer asked about my hobbies. I told them I like open-source work, blogging and photography. Then they asked how I keep up with new tech trends. I said I follow tech blogs, go to meetups, try out new frameworks on my own time and do coding challenges on sites like LeetCode and Codewars. They also asked how I balance my job and learning new things. I said I make time for side projects, go to conferences when I can and learn a lot just from talking to other people on my team.

This round felt less like a test and more like a normal conversation between two people who both like building things. I think being honest and specific here mattered more than giving a "perfect" answer.

Round 4: DSA Plus Code Review (60 minutes, 1 problem)

After a quick introduction, I was given one coding problem directly.

The Problem: Kth Smallest Element in a Sorted Matrix

Leetcode Link: Kth Smallest Element in a Sorted Matrix

You get a square matrix (grid of numbers) where every row is sorted left to right and every column is sorted top to bottom. You need to find the k-th smallest number in the whole matrix.

My first idea (using a heap): I said I could use a min-heap (a small-number-comes-out-first structure). I put the first number of every row into the heap, since the first number of a sorted row is always the smallest in that row. Then I pop the smallest number from the heap and every time I pop a number from some row, I push the next number from that same row into the heap. I do this k times and the last number I pop is the answer.

static int heapApproach(int[][] matrix, int k) {
    int n = matrix.length;
    PriorityQueue<int[]> minHeap = new PriorityQueue<>((a, b) -> a[0] - b[0]);
    for (int row = 0; row < n; row++) {
        minHeap.offer(new int[]{matrix[row][0], row, 0});
    }
    int result = -1;
    for (int i = 0; i < k; i++) {
        int[] top = minHeap.poll();
        result = top[0];
        int row = top[1], col = top[2];
        if (col + 1 < n) {
            minHeap.offer(new int[]{matrix[row][col + 1], row, col + 1});
        }
    }
    return result;
}

This works and it is faster than just flattening the whole matrix into one list and sorting it (which would be the true brute force way, at O(n² log n²) time). The heap way is around O(k log n) time.

The interviewer then asked me if I could make it even faster. That question is what pushed me toward binary search.

My best idea (binary search on the answer): Instead of searching through positions in the matrix, I searched through possible values. I know the smallest possible answer is the top-left number and the largest possible answer is the bottom-right number. I picked the middle value between these two and counted how many numbers in the matrix are less than or equal to that middle value. If that count is smaller than k, the real answer must be bigger than my middle guess, so I search the upper half of the value range next. Otherwise, I search the lower half (including the middle value itself).

Counting how many numbers are less than or equal to a guess can be done in O(n) time using a neat "staircase" walk: start at the bottom-left corner of the matrix and move up or right depending on whether the current number is too big or small enough.

static int optimalBinarySearch(int[][] matrix, int k) {
    int n = matrix.length;
    int lo = matrix[0][0], hi = matrix[n - 1][n - 1];
    while (lo < hi) {
        int mid = lo + (hi - lo) / 2;
        int count = countLessOrEqual(matrix, mid);
        if (count < k) lo = mid + 1;
        else hi = mid;
    }
    return lo;
}

static int countLessOrEqual(int[][] matrix, int target) {
    int n = matrix.length;
    int count = 0, row = n - 1, col = 0; // start bottom-left
    while (row >= 0 && col < n) {
        if (matrix[row][col] <= target) {
            count += row + 1; // everything above this cell in the same column is also <= target
            col++;
        } else {
            row--;
        }
    }
    return count;
}

This runs in about O(n log(max - min)) time, where max - min is the range between the smallest and largest number in the matrix. It does not depend on k at all, which makes it a nice improvement when k is large.

I tested my binary search answer against both the brute-force sort and the heap approach, on the classic example matrix [[1,5,9],[10,11,13],[12,13,15]] with k=8 and all three gave the same answer: 13.

The Dry Run

The interviewer asked me to do a dry run using a sample matrix, going through my binary search step by step on paper showing the lo, hi, mid and the count at each step, until the two pointers met. This part was actually good practice for me, because saying each step out loud forced me to make sure I really understood my own code, not just that it happened to work.

The Code Review Part

After the coding problem, I was shown a few small code snippets and asked to point out bugs, bad habits or ways to improve them. Here are the kinds of things I was looking for, with real examples:

Comparing objects with == instead of .equals(). In Java, comparing two Integer objects with == compares whether they are the exact same object in memory, not whether they hold the same value. For small numbers (between -128 and 127), Java happens to reuse the same cached objects, so == can look like it works until you try it with bigger numbers.

Integer a = 200;
Integer b = 200;
System.out.println(a == b);       // false! surprising if you expect true
System.out.println(a.equals(b));  // true, correct way to compare values

Off-by-one errors in loops. A loop like for (int i = 0; i <= arr.length; i++) will try to read one position past the end of the array, causing a crash.

for (int i = 0; i <= arr.length; i++) { // should be < not <=
    sum += arr[i]; // crashes on the last loop with ArrayIndexOutOfBoundsException
}

Building strings with += inside a loop. Every time you use += on a String inside a loop, Java creates a brand new String and copies everything so far into it. For a small loop this doesn't matter, but for a big loop it gets very slow, very fast. I actually timed this difference: building a string of 60,000 numbers using += took about 3.2 seconds, while doing the exact same thing with a StringBuilder took about 2 milliseconds over a thousand times faster.

// Slow
String result = "";
for (int i = 0; i < n; i++) result += i;

// Fast
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) sb.append(i);
String result = sb.toString();

Pointing out real, specific problems like these, instead of just saying "this looks fine," is what I think this part of the round was really checking for.

Round 5: Behavioral Round (60 minutes)

This last round had no coding at all. The interviewer asked about my past work experience, why I wanted to join Adobe and some general behavioral questions about how I work and think. It felt more like a friendly conversation than a test and it was a nice, calm way to end the whole process.

Biggest Learnings

Looking back at all five rounds, I noticed one pattern in myself: almost every time, my first idea worked, but it was not the fastest idea. The rotate array problem, the kth-smallest-in-matrix problem both times, I started with something simple and correct and only got to the best version after the interviewer gently asked, "Can you do better?" That question was never mean or tricky. It was just a normal, expected part of the round. Getting comfortable hearing that question, instead of feeling like it means you did something wrong, made a big difference in how calm I felt.

Preparation Tips

  • Practice explaining your first idea out loud, even if it is slow, before jumping to the best idea. Interviewers want to see how you think, not just the final fast answer appearing out of nowhere.

  • For array problems, learn the reverse trick and similar in-place tricks. They come up more than once and they show you can think about memory, not just correctness.

  • For anything involving a Binary Search Tree, always remember: in-order traversal gives you sorted order for free. This one fact solves a surprising number of BST questions quickly.

  • For matrix or search-space problems, if a heap solution works but feels slow, ask yourself if you can binary search over the answer instead of the position. This pattern shows up a lot in "kth smallest/largest" style questions.

  • Practice reading small code snippets and looking for common mistakes: wrong object comparisons, off-by-one loop bounds and slow string building in loops. These are simple to fix once you know to look for them, but easy to miss if you are not specifically checking.

  • Do not skip the "soft" rounds. Be ready to talk honestly about your hobbies, how you learn new things and why you want the job. These rounds are shorter to prepare for, but they are still real rounds that count.

  • Practice DSA problems regularly and consistently, on any platform you like. Being comfortable with common patterns (sliding window, two pointers, in-order traversal, binary search on the answer) matters more than memorizing exact problems.

Interview Preparation Resources

FAQs

1. How many rounds does the Adobe SDE interview have?

In my case, 5 rounds: an aptitude and MCQ test, a DSA coding round, a mixed coding-and-personal round, a DSA-plus-code-review round and a final behavioral round.

2. What kind of coding questions does Adobe ask for SDE roles?

I was asked Rotate Array, All Elements in Two Binary Search Trees and Kth Smallest Element in a Sorted Matrix. The topics covered arrays, BSTs, heaps and binary search.

3. Does Adobe ask about Operating Systems and DBMS?

Yes, in the very first round. It was all multiple choice questions, covering processes, threads, memory, normalization, joins, indexing and SQL optimization.

4. Does Adobe include a code review round?

In my loop, yes. After solving a coding problem in Round 4, I was shown small code snippets and asked to spot bugs and bad practices, not just write new code.

5. Is the Adobe SDE interview very hard?

I would call it a solid 3 out of 5. None of the problems were extremely hard on their own, but almost every round expected me to go from a simple first answer to a better, faster one and to clearly explain my thinking the whole way.

Conclusion

Five rounds, four coding problems and a lot of "can you do better than that?" questions along the way. If you take one thing from my experience, let it be this: it is completely fine to start with a slow, simple idea. What matters is that you can explain why it is slow and then work your way to something better, out loud, step by step.

Responses (0)

Write a response

CommentHide Comments

No Comments yet.