• Typescript Daily
  • Posts
  • Frontend system design interview - Actual interactions between interviewer and candidate

Frontend system design interview - Actual interactions between interviewer and candidate

How do you implement Spotify's search feature?

📢 Special Note to Our Readers

Happy weekend everyone!

Relax, enjoy the weekend, and at the same time have some typescript fun 😉

Last week's edition of the TypescriptDaily newsletter article went viral. It gathered close to 100 upvotes on Reddit. Check for yourself here. If you have not already read that article, I highly recommend you read that!

If your friends have sent you this newsletter over email, please consider subscribing here so that you get every day’s content direct to your inbox.

In continuation to our previous week, let’s look into another front-end design problem today and understand how the ideal conversations happen between the interviewer and the candidate during the front-end system design round. This is going to be interesting so stick around!

🎯 TypeScript Daily Digest! (Special Edition)

For this weekly special edition, we will cover typical candidate-interviewer interactions that happen during a front-end-system design round. Again, this is mainly for educational purposes as different companies differ in the interview styles. Regardless, this article should give you a high-level perspective of how to approach a “Frontend System design interview” if you are applying for roles like “Senior frontend Engineer”, “Frontend architect”, and similar ones.

Before we read further into this article, let’s establish some context:

  1. Interviewer - is the one who is interviewing

  2. Candidate - is the one who is attending the interview (specifically the frontend system design round)

Since it is a system design interview round, it is the candidate who should be leading the round and not the interviewer. Imagine this way before you attempt any system design round. The aim of this round is not to implement the flawless solution but to demonstrate the considerations that are taken in order to arrive at some solution. Of course, the implementation is important as well but the primary motive is to brainstorm on the design.

Based on my experience interviewing over 200 people in various companies, this is the place where I find most of the candidates lacking experience. Even the candidates who perform remarkably well in the other rounds (like problem-solving, domain rounds, …) fail to switch their mindsets to view this round from a different angle.

As a candidate, you should understand the difference between problem-solving rounds and design rounds.

“Imagine in your day-to-day work, if you are asked to design an “XYZ” feature and nobody is there to guide/review you, how will you design the feature making sure that that is usable, scalable, performant, secure, extensible, fault-tolerant, modern, …”

Overall, the intention of the design round is to understand the design thinking skills more than your problem-solving skills. Sometimes both go hand-in-hand, but you understand the gist.

Okay, with this in mind, let’s cover a mock-styled interview and see how that works out.

(I’m keeping some of the styles from the last article to maintain consistency)

Interviewer: Your task today is to design and implement a simplified version of Spotify’s search functionality.

More often than not, interviewer will not say anything more than this in the beginning.

This is intentionally done to ensure that the candidate spends good amount of time thinking through and asking the clarifying questions before going further deep into the solution.

Candidate: Based on the mock gif provided, I am assuming the following things:

  1. We are focusing only on the Search feature similar to Spotify’s search.

  2. As user types, the interface has to change to display the relevant results for the current search term.

    1. There is an Artist display section

    2. There is a Songs display section

    3. You have Artists at the bottom as well.

  3. We don’t have to worry about the other parts of the interface namely, left bar, bottom bar, and anything that doesn’t involve search.

  4. For the sake of time, I am avoiding tags that are displayed below the search bar.

Interviewer: Those are fair assumptions to move forward. We don’t have to worry about the rest of the sections.

Candidate: Do I need to support mobile and other devices (TVs, Car displays, …)?

Interviewer: For the sake of this interview, let’s keep it simple and support only desktop versions.

Candidate: That narrows down things a bit. I will need to still handle responsiveness in order to support multiple layouts for the desktop versions. (Eg. For smaller desktop layout, maybe I can show Artist, Songs one below another, For the larger layouts I can have them as seen in the mock)

Interviewer: That works. How will you decide on the layouts?

Candidate: I shall use media queries to have various breakpoints for the layouts.

These early interactions are very crucial in any tech interview. This sets the baseline for the rest of the interview to follow on. Mainly for the design interviews such as this one, it is highly critical to clarify the requirements.

You can equate this process to that of Requirements Gathering and Clarification that happens between the teams and the Product managers before the start of any product/software life-cycle.

The intention of having this in both the above instances is to make sure we are building the right product and for the right set of users.

For instance, if the candidate hadn’t clarified whether this needs a mobile support and went straight to implement for mobile which was never a use case, then everything becomes a wasted effort. The same can be said in the real software life-cycle as well.

Candidate: I’m now clear with the requirements. Let me first start by drafting a high level design for this implementation.

Candidate: I’ve considered 3 parts at a very high-level. Actor/User who visits the Spotify’s Search page and queries for a term. For each character, we get the relevant data. For simplicity and since it is focused heavily on frontend, I have simplified the service layer as just “Backend”. Ideally there will be indexes to support the read heavy operations, load balancers, …

Interviewer: This high-level works and we can keep the focus only specific to frontend. How’re you going to interact with the backend services? How often are you going to make the requests? Let’s talk more about the data-retrieval part.

Coming up with some kind of high-level diagram helps you talk specifically on those sections and that easily enables the interviewer to follow you along. This also helps you think from a broader perspective on how this use case is impacting.

Candidate: Sure, for these use cases, GraphQL seems to be favourable option as based on the mock, we will need to fetch Artist information, Songs information and related Artists information. In real-world, all these would be handled by different microservices (artist-details service, songs-service, …). Using GraphQL lets you query multiple data sources and return with a focused and the only required data to the client. This saves in payload size, avoids multiple requests, scales the design well to plugin and play this wherever required.

For the number of requests, as per our requirement, we will have to ensure that we refresh the interface based on each of the query term. But, if the user keeps typing continuously, it doesn’t make sense to hit the service for every key-stroke. We can debounce and hit the servers only when there is a delay in typing. This reduces the number of hits to the servers while still ensuring the interface stays updated to the latest. As another improvement, we can wait until user enters 2 or more characters in the search box but based on this mock gif, we are required to start even from the first character type. That optimization may not help here. Also, we can cancel out the previous in-progress requests as the new requests come in. This ensures we don’t rely on the old requests anymore which otherwise would result in the data being out of sync.

Debouncing is a great concept which helps reduce the unwanted calls to server or anything in general. Whenever it comes to user interactions such as searching (typing), scrolling, clicking through a slideshow, resizing the browser window it’s worth considering Debouncing. The other related concept is Throttling. Both helps depending on use cases.

It’s very important to cancel out the previous stale requests. Otherwise, it will result in data out-of-sync issues.

Imagine user types “bohe”, let’s say we triggered request for “boh” and now we trigger a new request for “bohe”.

If we don’t cancel the previous request, there is a chance that “bohe” request’s response can arrive to the client first and “boh” request’s response arriving later. This causes inconsistency.

Interviewer: Let’s talk about the response structure. How do you want to design the structure and how are you handling the large number of results per section?

Candidate: To make it simple and scalable, I will fetch the top result for the artist, and top 5 results for the songs, and top 10 results for the related artists. This ensures that the response is faster enough to handle the searching behaviour and interactions. I will start with a response structure similar to the one below:

GET /search/:term
{
    "data": {
        "artists": [
            {
                "name": "top artist",
                "imgUrl": ""
            },
            {
                "name": "",
                "imgUrl": ""
            }
        ],
        "songs": [
            {
                "title": "",
                "band": "",
                "cover": "",
                "durationInMs": 1234
            }
        ]
    }
}

I have artists and songs array. The first index of the artists array will be displayed for the top artist. The rest will be used for the related artists.

Interviewer: Okay. Would you consider anything else as a part of API interactions?

Candidate: Yes. I will consider API security. I will use OAuth for api authentication. It passes a token on every request and the backend validates if the request has the authentication to invoke this api. I’m assuming the login/signup is already taken care.

Interviewer: Great, now let’s think about the client side.

Subscribe to keep reading

This content is free, but you must be subscribed to Typescript Daily to continue reading.

Already a subscriber?Sign In.Not now

Reply

or to participate.