Adobe Interview Experience: MTS-2 Android
Years of Experience: 2 YOE
Current Role: Android Engineer, Startup (SDE-III)
Result: Offer Received
Round 1: Android Basics Deep Dive
Format: Online (MS Teams) · Duration: 1 hour
Introduction
The round started with a brief introduction — my career journey so far and my open-source contribution. We then went deeper into my work at my organization: the overall team structure, the size of the Android team, and what a typical day looks like for me.
Singleton Pattern
-
What is a singleton class? Followed by implementing a basic singleton in Java.
-
Thread safety of the implementation — how do we ensure the singleton is thread-safe?
-
Singletons in Kotlin — different approaches:
-
objectdeclaration -
Java-style singleton
-
synchronizedblock — we discussed that this is JVM-specific, and since Kotlin is multiplatform, platform-specific locking mechanisms would be needed for KMP targets.
class Database {
private static Database INSTANCE;
private Database() {}
static Database getInstance() {
if (INSTANCE == null) INSTANCE = new Database();
return INSTANCE;
}
}
object Database
App Performance
How do we measure the performance of an Android app (or any app in general)?
-
Memory leaks
-
UI jank
-
ANR — main thread blocked for more than 5 seconds
-
Crashes
-
UX degradation from long-running work — slow DB queries, IO, heavy computation
How do we measure and diagnose these? Using tools like Crashlytics and App Inspection in Android Studio.
Memory Leaks
-
What is a memory leak? Detailed discussion with Android-specific examples.
-
Scenarios that commonly cause leaks, and coding patterns that lead to them.
-
How to prevent leaks in practice.
-
AndroidViewModelvsViewModel— differences and when to use which.
Coroutines
-
What is a coroutine, and why do we need it? Brief discussion of threads vs coroutines.
-
Ways of launching a coroutine:
runBlocking,launch,async— when to use which. -
Scopes: What is a
CoroutineScope? What areviewModelScopeandlifecycleScope? Within these, we discussed coroutine cancellation, lifecycle awareness, and job cancellation. -
asyncandDeferred: What does deferred mean? When does suspension happen, and when does the deferred block actually start executing? -
A few more conceptual questions around coroutines to close out.
suspend fun init() {
val val1 = async { /* ... */ }
val val2 = async { /* ... */ }
// initialize something
val1.await()
val2.await()
}
Round 2: DSA Round
Format: Offline (Adobe Office) · Platform: HackerRank live session
Introduction
The round started with brief introductions — myself and the interviewer — along with some small talk about weather and general well-being. I was then asked to take out my laptop, and the interviewer shared a HackerRank live session link.
Format
There were two DSA questions. I was asked to look at Problem 1 first and decide whether I wanted to attempt it or look at Problem 2 and start there. I looked at Problem 1 and decided to attempt it first.
The interviewer set an expectation upfront: brute force approaches would only be discussed, not coded, to save time. Once we arrived at the optimal solution, I could code it up.
Problem 1: Nice Array
Statement: A Nice Array is an array in which removing exactly one element makes the array strictly increasing. You are given a list of positive integers — find the number of elements that need to be removed to make the array a Nice Array.
-
I first discussed the brute force approach, followed by its time and space complexity.
-
We then discussed that we could do better, and I proposed the optimal solution.
-
I wrote pseudo-code on paper and did a dry run on the example input.
-
The interviewer was satisfied with the approach. We then discussed a few edge cases and follow-ups:
-
Duplicates — how would my approach change if duplicates were allowed (i.e., strictly increasing vs non-decreasing)?
-
Already sorted array — the trivial case.
I was then given a choice: code this problem now, or move to the next one and code later. I decided to move to the next question.
Problem 2: Shops on a Street
Statement: You are given a list of integers representing shops on a street. Each number is the amount I must spend at that shop before moving to the next. You are given n queries of the form [Sᵢ, Capᵢ], where Sᵢ is the starting shop and Capᵢ is the amount I have. For each query, return the farthest shop I can reach.
-
I initially proposed the brute force approach using linear search per query.
-
I then arrived at the optimal solution: cummulative sums + binary search per query.
-
The interviewer was okay with the approach and asked me to code either of the two problems.
Coding & Wrap-up
I chose to code Problem 2. A few test cases failed — I walked the interviewer through the edge cases where my solution was failing and how I would fix them, but we ran out of time.
Round 3 - System Design
Format: Offline (Adobe Office) · Duration: 1 hour
Introduction & Expectations
The round started with a basic introduction, after which the interviewer set expectations for the interview. He said he would throw very broad, open questions at me and we'd discuss around them. He expected a certain depth in each concept — once he found the depth he was looking for, we'd immediately move to the next topic. My goal should be to state the facts I know immediately, so he could extract as much information from me as possible.
Dependency Injection
-
Started with what is dependency injection and the need for it.
-
Began with the basic motivation for DI, then circled to the Android-specific need — activities and other components are instantiated by the system, not by constructor calls.
-
Discussed Dagger and Hilt — how Hilt simplifies things, whether we can use Dagger without Hilt, and what the challenges are.
-
Discussed scoping of objects — what "scope" means in the context of Hilt.
LLD Problem 1: Search Bar with Suggestions
Problem: Implement a search bar that provides suggestions, with the data sitting on the backend and search firing a network call.
Follow-up discussion:
-
Caching vs no caching - we steered towards caching.
-
Debouncing the search input.
-
Data sources and mediation between the two sources (local cache and backend).
-
Prefix search - and the data structures suited for it.
LLD Problem 2: Infinite Scroll
Problem: Implement an infinite scroll.
Follow-up discussion:
-
When to fetch the next page.
-
Handling dynamic data — e.g., new rows inserted into an already-fetched page.
-
Fetching approach — page numbers vs cursors.
-
Storage and mediation — how I would store the data and mediate it to the upper layers.
App Architecture & Performance
-
How I would layer/structure the app — what logic lives where.
-
Ensuring performance checks and good practices — e.g., network calls on the IO dispatcher.
-
Repository vs use cases — when to use what.
-
ViewModel and coroutines — what is
viewModelScope, then what is aCoroutineScope. The interviewer expected depth around lifecycle management here; once I answered that, we moved to UI. -
LazyColumnvs a normalColumn— how performance is affected in each. I discussed recomposition, disposing of composables, and related behavior.
Wrap-up
The interview ended a bit earlier than expected. The interviewer said he was done and I could ask anything I wanted. I was a bit confused, since I expected more questions — and I told him so. He said, "let's keep going for a few more minutes," and we discussed some challenging work I've done in my career before ending the interview.
Round 4: Hiring Manager Round
Format: Offline (Adobe Office) · Duration: 1–1.5 hours
Introduction
This was the final round, with the hiring manager. The interview started with basic introductions — the interviewer introduced himself and asked me to introduce myself and walk through my career experience. During the walkthrough, he asked questions in between — less technical, more around how I approach problems in general and how I manage a team.
Cultural Fit Questions
Once I was done with my walkthrough, he said we'd do some basic cultural fit questions and then move to open discussion. These were standard hiring manager questions, such as:
-
Why do you want to join Adobe?
-
What's the most challenging thing you've done in your career?
-
As a team lead, how do you ensure alignment when some team members are misaligned?
-
Describe a scenario where you overcame a hurdle.
-
Describe a scenario where you solved a really challenging task.
-
Describe a scenario where you demonstrated teamwork.
-
Describe a scenario where you demonstrated leadership spirit.
Overall there were 12–15 cultural fit questions along these lines.
Design Problem: Promo Processor
I was then given a problem statement to design a "Promo Processor" (my name for it — the interviewer just described the problem).
Context: Multiple promos/dialogs currently appear in the Acrobat Reader app — banners, dialogs, ads, feature promotions. Users complain a lot about this. The idea is to design a promotion processor infrastructure that handles when a promotion should be displayed. Its only job is to tell the UI layer when to display which promotion.
My approach:
-
Discussed the problem with the interviewer and listed down all the required features.
-
Discussed the high-level design in brief.
-
Moved into low-level design and discussed around that.
Wrap-up
This round ran over its allocated time. It ended with my questions about the org structure, the project, and when I would be staffed.


