Mobile System Design

By the author of the Mobile System Design and Swift in Depth books

Interview Preparation Resources

Welcome to this resource hub dedicated to helping you prepare for and ace your Mobile System Design interviews!

You can consider this page a cheat sheet where you will find useful links to resources, such as detailed videos, insightful articles, practical tips, and valuable links to resources on this website.

Each resource is curated carefully to help you understand key concepts, tackle complex system design problems, and confidently navigate your interviews.

Note that this is a living page. It will grow with more resources as soon as they become available.

Whether you're an aspiring mobile app developer or an experienced engineer aiming to enhance your skills, this page contains will help you by offering both free content and references to the Mobile System Design book to guide you through the interview process.

Dive into these materials, practice diligently, and get ready to impress your interviewers with your mobile system design expertise. Let's get started on your path to success!

The process

The total time of an interview is usually around 45 minutes to an hour. The beginning and end are formalities, the actual design session takes approximately 30 to 40 minutes.

Intro (5- 10 mins)

The interview starts with introductions, where the interviewers will introduce themselves and ask you to do the same. This segment lasts about 5 to 10 minutes.

  • Preparation: Ensure your microphone and camera are working properly if you are interviewing remotely. You don't want technical issues to take up your time.
  • Keep it brief: This time should be used efficiently to maximize the time available for the actual design session.

Designing a system (30 - 40 mins)

Following the introductions, you will be given specifications and requirements for a feature or functionality. This could range from implementing a UI screen to designing model-layer functionality. Perhaps you're asked to create an analytics library that needs to support an entire app. Or maybe you're asked how you would implement a feature flag system from scratch. It could be anything.

Often, this functionality needs to communicate with a hypothetical backend server. Since that's a common requirement for mobile features.

What the interviewers are looking for is your thought process. What types would you come up with for an implementation? How would these types work together? What about backend communication? Does anything need to be stored locally? How would you decide what to store and how often? What about performance bottlenecks? Any weird edge-cases you can find? And how would you make sure this functionality doesn't break over time?

  • Understand Requirements: The requirements provided will be intentionally vague. Your goal is to uncover all necessary requirements, including hidden and edge cases, and to understand non-functional requirements.
  • Deliver from Scratch:You are not expected to memorize all frameworks and functionalities. Instead, focus on delivering something concrete from abstract requirements, often from scratch.
  • Offer an implementation: Communicate your ideas clearly using diagrams, code, or mock implementations. It’s important to articulate your thought process, including types of implementations, backend communication, performance bottlenecks, edge cases, and long-term functionality stability.
  • Think out Loud: Constantly verbalize your thoughts. Explain what you are considering, why certain ideas might work, and why others might not. This helps interviewers understand your approach and problem-solving skills. Note that you might (sub)consciously be graded on communication skills, too.

Updated requirements

After presenting your initial design, the interviewer will likely increase the complexity of the requirements. This tests your ability to handle new situations and complex problems. Similar to real-world scenarios where requirements often change.

Increased complexity can come from any angle. For example, maybe the interviewers will ask how versioning with the backend would work.

Alternatively, maybe you were tasked to design a solution to upload videos to the backend. Now, the interviewer might ask how you could upload videos if the app gets killed or suspended midway. How would you update your design, so that you can continue uploading videos in a new session?

Now suddenly you need to support offline storage for videos, which touches a lot more topics. Such as: What if there isn't enough disk space? What about compression? When would the app upload? How would you resume uploads? and so forth.

Outro (5 - 10 mins)

The session concludes with an opportunity for you to ask questions. This final segment also lasts about 5 to 10 minutes.

Overall, the key to a successful mobile system design interview is effective communication, a solid understanding of abstract requirements, adaptability to changing scenarios, and a collaborative approach with the interviewers.

Unlike other interview sessions, a good system design interview can actually be quite fun. Because you are teaming up with the interviewers to come up with a design together. You take the lead, and the interviewer might throw in some more ideas and alternative requirements. A good session almost feels like pair-programming where you work together.

To better prepare, check out the resources below.

Being Briefed

First, I recommend you become great at handling briefings.

During an interview, you'll be getting (intentionally vague) requirements of something to make. The goal would be to come up with a design to solve the problem.

To achieve this, you'll need to find hidden requirements, non-functional requirements, find hidden edge cases, discover the highest priorities, show that you understand the question on a deep level, define the scope, and so forth.

If you only want to focus on one thing, I recommend you become great at this skill.

Ultimately, you will want to come up with a strong technical design that will (hopefully) signal to the interviewer that you know what you're doing.

But, there is a pitfall: If you "just start implementing" without considering the entire situation, you are setting yourself up for failure.

Getting the most out of a briefing is key. Without understanding requirements, everything else fails. That's why getting the most out of a briefing is more important than knowing about the latest design patterns or being able to articulate the best way to store data.

For that reason, I recommend you check out the free resources below.

Be sure to check out Chapter 2 in the free book sample, because it shows you how to turn requirements into a graph. Which is a great approach to effectively communicate your design to the interviewer.

Delivering an implementation

Depending on the type of interview, you might need to write a crude implementation for the feature you're asked to build. You may write this in the programming language of your field (e.g. Kotlin, Swift, Java, Objective-C, or Dart). In some interviews, it's more about the concepts, and you may even write code in a fake pseudo-language.

Often it's not the key priority to have the code in a perfectly working compiling state. It's more important you show what to build, which types to introduce, their API design and the trade-offs you make.

Pro tip: If during this stage your code isn't compiling and you're stressing out; Just say it's intentional and that you want to focus on the design, not waste time finding the missing curly brace.

What is more important is that you show the interviewer that you are designing the types and their API's, or interfaces. The key here is to give signals you take all (hidden) requirements into consideration and come up with a strong design.

Online editor

An interview will most-likely happen on-site, or remote in a browser with a code editor, such as CodeSignal or HackerRank.

A browser with a code editor might be an unfamiliar environment since it's not your default IDE, and you will not have frameworks ready. You may not always have auto-complete or the latest version of your programming language, either.

That means you need to be comfortable to make something from scratch.

Tip: I recommend practicing building a feature from scratch, from memory, to get comfortable.

To translate requirements into code is one skill, but to do it efficiently and quickly is going to be essential.

To know how to do this, I strongly recommend you check out Chapter 3. Holistic-Driven Development; Turning a plan into code from the Mobile System Design book. Because it teaches you how to get a feature up and running quickly while keeping a strong focus on priorities and API design.

I'd say it's a must-read.

Delivering Reusable Components

After delivering a feature or piece of functionality, you will most-likely receive more difficult requirements that will disrupt your design.

This will be intentional, because it helps the interviewer to see how you can handle new ideas, and how to adjust your design. It will also be a way to show how to handle more difficult requirements.

To handle these new complexities, you will iterate on your current design.

One aspect of this is making components more generic or reusable, so they can be used more broadly. This way you can not only support your feature but also other features, or even entirely different teams in your company.

For this reason, it's worthwhile to be strong in abstractions and generalizing your code.

However, there is the trap that you might be over-engineering your code by doing so.

It's an art to create reusable components, without wasting time or introducing complexity for little benefit.

Check out these resources to get well-versed in finding the right balance between reusability and over-engineering.

Architectures and Design Patterns

Depending on your level, you may be asked how you would scale up the feature of your briefing.

For example, the interviewer might be interested in hearing how you can make a feature work across various navigation flows, or even multiple platforms and targets.

That means that eventually, you'll be covering application-wide architectures and Design Patterns.

Architectures can be tricky, since most developers have their preferences and favorite architectures.

It's good to familiarize yourself with them and know the pros and cons. Be sure to show an open attitude and willingness to work with architectures that you aren't familiar with.

Unfortunately, architectures and patterns are highly susceptible to trends and debates. Which is why I try to not focus on them too much.

That's why we'll take a more timeless approach where the architecture plays a smaller role.

Instead, one constant that is always valuable is to make features self-sufficient and portable. This way, they can support and outlive most patterns and architectures.

The focus would be to make it easy to "cut and paste" features so that you can move them around in your app without difficulty.

On top of that, you can learn how to make features portable, so that you can easily support multiple platforms and targets.

We can achieve this without relying too much on the trending architecture of the day.

Luckily, there are plenty of resources available to achieve this. Check them out below.

Testing

After coming up with a design for your feature, chances are, that you will be asked how to make your implementation testable.

That doesn't mean you have to write tests during an interview. But it is an opportunity to show your way of thinking; What would you test, what would you avoid testing, and where would you insert testing points like interfaces?

The world of testing is a complex and a highly opinionated field and I assume you have your own methods, too. Entire books, papers, and case-studies have been written about testing. There are no silver bullets.

However, the complexity of modern apps benefit from a more holistic approach. System-wide testing evaluates the entire system as a whole, ensuring that all components interact seamlessly under real-world conditions. This form of testing uncovers issues that might not be apparent in isolated unit tests, such as performance bottlenecks and failing integrations.

For that reason, I recommend you not only become aware of unit testing small pieces of a program. But also system-wide testing, of which you can find resources here.

Dependency Injection

Dependency injection (DI) is a ubiquitous and essential concept in modern software development.

At its core, Dependency Injection involves supplying a type with its dependencies from an external source rather than creating them internally. This decouples implementations from their dependencies, promoting a more modular and maintainable codebase.

It's crucial to understand not only how to implement DI effectively but also when to use or avoid singletons, how to navigate third-party frameworks, and strategies to overcome typical dependency management challenges.

Traditional resources often discuss DI in the context of individual components, with a heavy reliance on interfaces. However, in these resources, you may find to handle DI on a more system-wide level, which requires fewer interfaces altogether.

To learn how, check out the following resources.

Good luck!

These resources should help you prepare to ace any upcoming Mobile System Design interview.

Remember, practice is key, and the more you immerse yourself in these materials, the more confident you will become.

Since this is a living page, be sure to keep coming back to find new resources to help you get that job you want.

Note that passing an interview is only the beginning of your system design journey. For the long term, becoming great at Mobile System Design is not a "quick and easy" preparation. It is a craft that you can hone over years.

If you're interested in improving your Mobile System Design skills, both in general and for interviews, then I strongly recommend getting the Mobile System Design book. This will help you save time to improve your Mobile System Design skill set on a fundamental level.

Good luck!

- Tjeerd