We helped write the sequel to "Cracking the Coding Interview". Read 9 chapters for free

Photo Sharing Service

Watch someone solve the photo sharing service problem in an interview with a FAANG engineer and see the feedback their interviewer left them. Explore this problem and others in our library of interview replays.

Interview Summary

Problem type

Photo sharing service

Interview question

Design a photo-sharing service which allows users to: 1. Upload a photo on their profile. 2. See photos uploaded by other users the user follows.

Interview Feedback

Feedback about Orthogonal Warrior (the interviewee)

Advance this person to the next round?
Thumbs upYes
How were their technical skills?
4/4
How was their problem solving ability?
4/4
What about their communication ability?
4/4
What went well: • Good question to confirm whether follow requests are auto-accepted or not • Great question asking whether anonymous users are something we should support in the system or if all users are already verified/authenticated. • Good questions asking what metadata I care about seeing associated with the photo. Great point about talking about the delete case. • Solid job probing the functional requirements -- photo resolution, what limitations for read/write are on the system. • Solid RESTful API design • Good clarifying the need to come back to certain items -- such as the queue • Explained rationale for the architectural components which were introduced -- LB, API GW for supporting indirection and horizontal scaling. • Great call-outs on the why behind using NoSQL databases for supporting horizontal scaling along with call-outs for a specific technology. Areas for improvement: • Improve -- did not clarify what non-functional requirements I care about. • Improve -- take your time to talk through request/response payloads and status codes • Improve -- should have clariifed if I need to see a newsfeed of all photos uploaded by users the user follows • Nit -- call out the need for versioning

Feedback about Platinum Lambda (the interviewer)

Would you want to work with this person?
Thumbs upYes
How excited would you be to work with them?
4/4
How good were the questions?
4/4
How helpful was your interviewer in guiding you to the solution(s)?
4/4
Great interviewer. Great questions, was very happy with the feedback and hopefully things end up well!

Interview Transcript

Platinum Lambda: Excellent. How's it going?
Orthogonal Warrior: Oh, you know, it's preparing for interviews, so as good as you can be while handling the stress. Gotcha.
Platinum Lambda: When is your upcoming interview? How far out?
Orthogonal Warrior: It's actually tomorrow and it's the round of five over at Facebook. This is, I think, my fifth one of these mocks that I'm doing. I'm just trying to really make sure that I'm taking and getting feedback and getting used to that. I've, I haven't interviewed for a FAANG company in a number of years, so trying to brush off some of those skills.
Platinum Lambda: Gotcha. And then what level are you applying for?
Orthogonal Warrior: I'm going for a l six over at meta.
Platinum Lambda: Okay, perfect. All right. I hope this will get you more ready. Tomorrow's interview, we'll get started. I'm going to paste a question here. Sure. If you've seen this question before, let me know.
Orthogonal Warrior: Let's see. Design a photo sharing service which allows users to upload a photo on their profile and see photos uploaded. But I haven't, I mean, this sounds like Instagram. I know that Instagram is a common design problem. I have not actually done this problem personally.
Platinum Lambda: Okay, sounds good. All right, we'll get started then. Cool. But yeah, have a look and then let me know if you have any questions on the requirements.
Orthogonal Warrior: Yeah, if you don't mind, I'm actually going to just jump over, I'm going to copy this and jump over to the whiteboard. I'll probably be doing most of our discussion, driving most of our discussion there, if that's all right.
Platinum Lambda: Sure.
Orthogonal Warrior: So we'll drop those in there. All right, so design a photo sharing service which allows users to upload a photo on their profile and see photos uploaded by other users. The user follows. Okay, so I guess we'll just start talking about functional and non functional requirements and we'll kind of go from there. So from this, these two pieces really become our functional requirements. Uploading a photo on the profile and so see photos uploaded by other users, the user follows. So I'm assuming that there needs to be some sort of, some sort of like pre profile viewing. Again, I'm going to use the Instagram analogy just because it's similar here, but like a visibility restricted version of the profile so they can opt to follow somebody or how do you want to go from, from non followed to follow? How would you like that flow to work?
Platinum Lambda: Yeah. So I think you have it correct. So assume that if a user is not following the user, the visibility is restricted. Once the user follows the user, they can see all the photos that user uploads.
Orthogonal Warrior: Okay, so it's in that sense again, kind of allah Instagram, it's going to be the same page, just visibility restricted. And then follow unfollow toggles there.
Platinum Lambda: That's correct. Yep.
Orthogonal Warrior: Okay, so follow a user via navigating to a visibility restricted version of profile and then see photos uploaded by other users to user follow. And just so, just making sure that I understand this, like, if user a, if I'm user a and I follow user b, is the visibility case here that a can't see b's photos until a follows b, whereas a can't see b's photos until b follows a. Yeah.
Platinum Lambda: So a can't see B's photos until a follows b. And the same thing applies to b. So a might follow b and a can see the photos, but if b isn't following a, then b can't see the photos of a.
Orthogonal Warrior: Okay, and for these follows, are these like follow, is this like a follow request? Like is it something that like the user would have to accept or can I just follow somebody and then immediately I'm granted that access?
Platinum Lambda: Yeah. For the sake of this design, let's assume that the access is granted immediately.
Orthogonal Warrior: Okay. So we don't need to design any sort of acceptance thing. It's purely the visibility, the restricting the restricted visibility. And then once they've kind of gone through that follow or once they've gone through that follow flow, they get that visibility unrestricted. Okay. And then let's see here other things that I'm thinking of. I mean, for the scope of this, can a user that is not authenticated. So I, well, no, I guess that kind of, this also kind of implies that you need to be authenticated. I'm assuming that we aren't going to support like anonymous. Do you want to support anonymous sessions or something of the like? Or does the user need to have a, have a known, verified user in order to be able to subsequently follow somebody?
Platinum Lambda: Yeah, let's assume that all users are authenticated in this flow.
Orthogonal Warrior: Okay. Okay. So we'll just assume that, I'll just document the assumptions here. Assume all users are verified, authenticated. Okay. And then, cool. And then I guess, I think, and then, do you want to, I guess, I mean, again, thinking instagram, do you want to do anything beyond just the seeing and viewing of photos, any comments, anything of the life? Or is this kind of as deep as you'd like to dive on this.
Platinum Lambda: For photos uploaded, I want to see some metadata. So starting with caption each photo that's associated with the photo.
Orthogonal Warrior: Okay, so you do want some user or some uploader provided metadata. So captions, locations, time of upload, things of that nature.
Platinum Lambda: Yeah. Let's start with three pieces of data. The caption underneath the photo, location where the actual photo was taken and then the time of upload, five minute date.
Orthogonal Warrior: And date timestamp of upload. Okay. And is this, okay, and then is the photo, I guess I'm assuming that a user can upload. And do you want to go through the delete case in the scope of this design or should we just, do you want to just handle the creation and the visibility case?
Platinum Lambda: Let's treat the delete case as a bonus. Okay. So we can start with the initial ones here.
Orthogonal Warrior: Okay, cool. And then just talking kind of in terms of like scale and things like that. What type of, what type of scale do you want to design this for? Are we talking like what, what amount of users? Kind of. Where's, where are we looking for the design?
Platinum Lambda: Yeah, let's assume we have about 500 million daily active users.
Orthogonal Warrior: And you said 500 million?
Platinum Lambda: Yep.
Orthogonal Warrior: 500. 500 million daily active users. And then are there any limitations in terms of uploads or views of other user's photos? Is there any restrictions in either of those cases?
Platinum Lambda: No restrictions.
Orthogonal Warrior: No restrictions? No. Okay, and then do we have, I mean, I guess this is probably still in the no restrictions, but I'll ask anyway. Is there like an upper bound in terms of like the size of photos that we're processing or anything of that nature or.
Platinum Lambda: Yeah, so let's assume that a user can upload as many photos as they want and, you know, they can read as much as they want. But to support the stability of a system, the max size of a photo upload will be capped to ten megabytes.
Orthogonal Warrior: Ten megabytes. Okay, max photo size is ten megabytes. And then max photo size. Max photo limit, unlimited. And then for this, do we want to support for these uploads any sort of post processing, all off filters or anything like that? Or for this, we just assume that that's out of scope.
Platinum Lambda: Assume it's out of scope. Assume we can assume that every photo is uploaded at the same resolution.
Orthogonal Warrior: Okay.
Platinum Lambda: So you can assume maybe 1080p or something like that.
Orthogonal Warrior: Okay. Assume all photos are uploaded. Okay, cool. Cool. So I'm happy to dive in and do some rough capacity estimates if that would be beneficial. To you, 500 million daily active users is a lot. And so I'm immediately going to probably be biasing my design towards horizontally scalable system. Would you like to see those calculations in terms of like average rec?
Platinum Lambda: Yeah, but I think before we get there, I want you to, we haven't really, we have talked a little bit about the expected scale. We haven't actually talked about the non functional requirements. Right. So, so the two things I'm looking for in this design are low latency.
Orthogonal Warrior: Okay.
Platinum Lambda: And high availability. So just, just as a tidbit here, I'll mention at the input, you definitely want to ask interviewer what they care about because I may have said I care about consistency. Some might say latency, low latency. And that will explain to you, right.
Orthogonal Warrior: The whole cap theorem trade off or whatever. Yeah. Okay, cool. So low latency and high availability. Okay. Okay. So then, yeah, so then, I mean, I guess just some rough nap and math. It's 500 million daily active users divided by, you know, so. Well, I guess. Okay, so let me, before I go and do that because it really, it will be determined by how, by like this is going to be driven because there's no reader write restrictions estimating capacity estimates. It's going to be hard. So let's go ahead and I'm going to hold off on doing any sort of capacity estimates actually until it's maybe required a little later and just jump into kind of identifying some entities. So we have here we have the actual photo blob itself. We have users, we have photo metadata. And I don't think I see any. I mean, I guess depending on how it's structured follows. But follows could just be a sub characteristic of users. So we'll see how I end up breaking this out. That may end up being an entity unto itself. Probably not, though, now that I'm saying this out loud. So in terms of like a rough API for accomplishing the functional requirements, before I jump into some high level design, we'll probably have a post to photos that's going to take and I. Okay, so when you upload a photo, I guess this is maybe just a refining of this functional requirement. The photo metadata itself. When you upload a photo, should this photo metadata be something that you specify or should this be something that we infer based on the photo that we upload?
Platinum Lambda: Yeah, so a few things here. When a user would upload a photo, they're going to have some kind of blob data, right. The location you can assume is inferred from the photo, right? Where that is. Okay, but the caption is something the user should be explicitly inputting as part of that request.
Orthogonal Warrior: Okay, so the location and the date timestamp will get from the actual photo metadata of the blob itself. But the caption is a user provided thing in addition to that. Okay, so then, so we'll have a post to photos and this is probably going to be our, we'll probably do a photo upload and this is going to be the upload, the upload photo. We'll have like a slash photos slash id caption. I'm going to default to rest here and we're going to photosid caption. This is going to be set caption and I'm going to explicitly not enumerate every single crud thing here. But it would be assumed that if you can edit a caption or if you can post a caption that you can then also edit and get and all those other things as needed. But I'm not going to explicitly enumerate all of those. We'll need to so upload a photo. So for the user stuff we can assume that all users are authenticated. Is it all right with you if I just go ahead and assume that the user service exists something op zero, some firebase authentication type entity that provides those authenticated users and I don't need to provide APIs for that.
Platinum Lambda: Sure, yeah, that sounds good.
Orthogonal Warrior: Okay, so I'm going to go ahead and make that assumption and handled by external service. So then we need to be able to upload photos. We need to upload photo. So we need to upload the photo. We need to set a caption and then we need to be able to follow a user by navigating. So we need to be able to follow a user. So we're going to go ahead here and we're going to have users id, follow id. And then after we do that, so that should be the totality of the API. And then we obviously if we get to delete we'll expand this a little bit. But that's really all of the stuff that we kind of need at the outset. So I'm going to go ahead and jump into a little bit of high.
Platinum Lambda: Level design real quick before you jump in. So I'd like for you to expand a little bit on the request and response payload structure. So the request payload. Response payload.
Orthogonal Warrior: Ah, yes, sorry, my apologies. The schemas. The schema is the schemas. The schemas. Right. So the photos upload. So for photos upload, this is going to be a standard or what's it called, a file upload URL. So the intention of this thing is going to be that it's going to accept a multi part file and it's going to stream from the user's machine into wherever we choose to receive it. And we'll discuss that more a little later. And what this should return, I guess, is going to be our photo object. Which photo object is going to have a couple things. We're going to have photo so we're going to have the URL and this is going to be some string here, some sort of id that is also going to be some sort of a string. We're going to get some sort of metadata associated with this. And this is going to be the caption, this is going to be the location, which we can do this as a lat long and we'll do a, let's see, the three things that you had said were the caption, the location and then the date, timestamp, those were the three. And then we'll also create a created at Timestamp and an updated, well, I guess I don't really need, I kind of have these by default, these updated apps, but that will be what it returns by default. This metadata object is obviously going to be optional at the outset, but we'll go and we'll parse. So yeah, and then I guess for this upload and this will kind of, this will have the potential to change. But like given how we choose to handle the uploads, if the upload, like the upload flow is inherently serial, as in like a user is going, they make a request and we do the processing. Before we actually return to the call point, which would limit scale, we may choose to return some sort of queue identifier that says, hey, your photo is in this part of the processing queue. If we're doing any sort of thumbnail reprocessing or things of that nature. So we may return a different object, but this is kind of the. Oh, and the visibility is the other thing here that we're missing.
Platinum Lambda: Go ahead, go ahead, finish your channel.
Orthogonal Warrior: Oh, I was just going to say the visibility is really dependent on the user's photo and so we need to say the owner, which is also going to be a user id here. And this is what's going to be the thing that we, that we're going to need to do some lookups based on to actually see if we can fetch. But. Sorry, I interrupted you. What was your question?
Platinum Lambda: Yeah, so I think you hinted at you know, so just to clarify, so if a user uploads a photo, I think, are you mentioning there's two possible responses. One is photo gets done and you get the response back, which is metadata. Correct. Or photo might take longer to process, which results in some qid.
Orthogonal Warrior: Right.
Platinum Lambda: That gets correct. Okay. Okay, got it.
Orthogonal Warrior: Yeah.
Platinum Lambda: Let's, let's call that a. Hear the details here, that the other response payload could be the QID. Okay. And I think that that makes sense. I think that maybe, assuming you're thinking here, that if there's probably high traffic to our system or delays, correct.
Orthogonal Warrior: Yeah. If you're feeling like I write volume, that it probably isn't pertinent for you to go and block the user escaping that flow, as in the user has uploaded all of the bytes and there's no further action that the user actually needs to take. It's just a system thing. And so we would show like, I mean, I'm imagining like some interface where we go and we show something with like some sort of a spinner type of a doohickey here while this to showcase like processing or something like this. Right. To be able to indicate that, hey, you've got a photo here that is of this id. And the URL is this dummy URL and it's still in process until we can fully populate the totality of the actual image itself.
Platinum Lambda: Okay, sounds good.
Orthogonal Warrior: And so, yeah, so I guess I'll just kind of, I'll put that in for right now because we'll. So the URL here is going to be optional and it may instead be a queue id that also ends up being a. A string where I use. So, and this kind of has implications that there's going to be a queue in some part of this that is going to have a data store associated with it that is going to. That you'll be able to go and actually look these photos up by id. So maybe we'll augment this thing and we'll go, we'll get huid status. We'll just kind of walk down this path because it will scale higher in terms of writes if we do something like this. So get status of Q.
Platinum Lambda: We'll go ahead.
Orthogonal Warrior: And so that's kind of our photos object, our users object here like this. Call this photos. And then we've got our users object or our follows object. And this is, again, it's going to have an id. And actually, now that I'm thinking about this, because our users are external, I actually don't think that users is a concept, never mind, ignore me. But what we're going to do is we're going to create an, I think that we are going to have follow as a bespoke entity unto itself. And we're going to have the iD, which is just a unique id, the user, the owner of the follow, which is this is who actually created the follow itself. And then we're going to have a target. This is, hey, who am I actually following? And this is going to be something.
Platinum Lambda: Okay, so this is the response payload for the follow API.
Orthogonal Warrior: Yes, this would be for the follow API. And this is going to be, you're actually, this is going to be. We're going to create a. Because we aren't going to actually expose, because most of this user's API is going to be a thing unto itself. We're going to, we're going to create follows as a construct unto itself and store using a follow service. And we may come back and iterate on some of these a little bit. For at the outset, I think it's going to end up looking something like this where we have an id, an owner, a target, and then some timestamps associated with it. And then the other thing that we're going to need is we're going to need to get a list of photos or get a list of users photos. And this is going to need to be a paginated. I'm going to put this in here because these are the things that we typically do on paginated endpoints. We didn't explicitly call out that you're going to be able to, you know, sort or filter the photos in any way, shape or form, but I'm going to assume that that exists. That may exist in some capacity at some point.
Platinum Lambda: So, yeah, a quick question on this. So get users. Okay, so this gets the list of photos for a given user, right?
Orthogonal Warrior: Correct.
Platinum Lambda: But a user might be following many users. So I'm guessing, just to understand the flow here, if I'm following 20 people, 100 people list, for example, in our feed. Sure. I'm guessing the flow is we pull the list of followers. Where is the list of followers, actually? Where would I see that?
Orthogonal Warrior: The list of followers? So you would go. That's where. Well, okay, so my thought is that the list of followers is just in, the date is in the database and that's not exactly something. Well, I guess, I mean, it's not technically part of the functional requirements to be able to view your followers, but we could very easily create a, you know, a get users and get users followers or something like this.
Platinum Lambda: I see. Yeah. So I'm thinking here more. So this might, you probably might cover this in design, but as a user, I want to see everything my user has uploaded. It's requiring one is the API call you have there. Forget users id photos, but it also requires knowledge of the followers. So. Okay, that sounds good. I think you'll probably cover the design. We just want to make sure that because there's two data sets we need to return and pull together to return that feed.
Orthogonal Warrior: Right? Yeah. So kind of based on how I'm kind of approaching this, I'm envisioning that this is probably going to be like a SQL API of some nature that is going to have rich relations of photos and followers. And that will go, and it will be the join of these two fields that inherently solves this. And then we'll propagate the joined data via caching to solve for the low latency requirements for the various sets of users. So have our data sets be inherently relational, but solve for the latency with caching? It's kind of what I'm envisioning. Sounds good. Jumping in then to some high level design. I may, and I guess technically we didn't talk about the return of this queue, this queue status thing. I'm going to put a pin in that. We will come back to that if we dive into it a little bit more. For the time being, though, I want to jump into the design because I think that there will be some other things that we can discuss as a result of the design as well. We're going to, so we have here our clients, and I'm going to go ahead and make the assumption that all our clients are going to come from a variety of different, or a variety of different types. So I'm assuming that we'll probably have a web client, we'll probably have an iOS, a native mobile client, things like this. And I'm just going to bulk all of those in client, we'll interface with all of them in the same way. Then I'm envisioning that there's probably going to be, there's going to need to be a load balancer and an API gateway, because to handle the load of what we're going to be doing, we're going to need some indirection and some horizontal scaling.
Platinum Lambda: So.
Orthogonal Warrior: And then from the API gateway, so we have our, we also are going to need the messaging queue. So we're going to put this up here. And for this, looking at this, my initial thought is not that there is anything like that, probably a Kafka is going to be just fine. The number of topics that it seems like we're going to have is pretty narrow. And the ability to, the way that Kafka stores topics with the ability to replay and all that stuff will offer very nice integrity of actual processing. So I'm thinking that we would probably use something like a Kafka as opposed to a high performance stream based queue think rabbit or something of that nature. So kind of what I'm thinking is if a user comes in and they want to upload a photo, because that's kind of our first case, so they're going to come in here to our load balancer or they're going to come in, they're going to upload. So we're also going to need, we're also going to need a CDN because we're not going to. There we go. We're not going to be storing these bytes in one place. In order to solve for the high availability, for both the availability and the latency requirements, the CDN is going to be required something like s three. Both of these are going to be required to be. Yeah, so both of those will be required to kind of meet the non functional requirements. So when a user goes to upload, they're going to go and they will post to the photos service and the photo service is going to go ahead and it's going to, they're going to post the upload to the photo service. And what the upload to the photo service is actually going to do is it's going to, geez, I hate that it's doing this. It keeps disconnecting me from the thing. But it's going to generate a CDN URL and then it is going to allow the user to directly upload the bytes to that CDN URL. And that will be something that we can just take care of underneath the hood in those APIs. But effectively we're going to be a direct s three upload to the cdns for these things to ensure that we're not like middleman ing any of that traffic and encumbering this service unnecessarily. The photo service is also going to need to go. And when a file has been uploaded from the photo service. So we're going to go and we're going to put one of these here. When an upload comes in, it's going to go into the photo service which is going to dump it into the CDN. Once it has been dumped into the CDN the photo service is then going to push from the photo service onto the messaging queue. And then I'm going to drag. Yes, I can drag that. Cool. I'm going to push the raw CDN URL and end that onto the messaging queue. Messaging queue is then going to be listened to by a number of processing bots that are going to be back here. Can I make this come to the front? We're going to have photo processors and so this is for downresing. I'm assuming that to. Well, to solve for the latency requirements, if I can upload a ten megabyte image, it's going to be unsustainable to try and load the entire ten megabyte image. There are more. What's it called? And so that's actually going to need to change our photo schema a little bit. We'll come down to that in just a second. But there are more effective formats for storing data than just what we're getting uploaded. And so we're going to downres it to what's going to be on these or on the, in the, in a thumbnails type of a page and work from there. So the photos processor is then going to jump back into the CDN. Ooh, I. Oh, there it went. I accidentally minimized. We're going to. The photos processing workers are going to push all of their photos also into the CDN as well as pushing into a. We need a database here for the photos as well as the photo metadata. We need a metadata. And this is going to push into, into the photos Db and the photo service is going to read this. So it's going to look something kind of like this for the uploads where an upload is going to come into the photo service. The photo service is going to facilitate the upload of that thing directly to the CDN URL to reduce load. It's going to, once that CDN URL or once that CDN upload has been confirmed, it's going to then blast off a message onto the messaging queue. Those messages will be picked up by the photo processing units which will then eventually dump those images back into the photosynth or dump the images back onto the CDN. With the actual image URL's going into the photosDb itself. So with that we actually need to come in here and refine our URL's. These URL's is going to be a list of all of the different supported or processed resolutions by string. And so basically for, let's say that we want to load like a thumbnail version. So like a 320 pixel by 320 pixel version of this thing that will be there. And then if we have like a iOS version of this processing, whatever we, based on the requirements we would need, we would have all of those resolutions stored in the CDN and that would be something that would be created as a function of photo processing service itself. Yeah, that seems about right to me. And then, okay, so that's uploading a.
Platinum Lambda: Photo.
Orthogonal Warrior: And we'll, okay, and then we also need to upload the captions. So that's probably also just going to be a post to the photo service and that's just going to be simply a data write to the metadata of a given photo. So I don't think that we need to do anything, anything specific there for that one. Yeah. Okay, so then moving forward then, so let's look at following a user via navigating to a restricted version of the profile. So if I am a user and I navigate to somebody's profile, so I go and I get the user whose id that I am looking to go to, I call photos, that returns me a list of these objects or no, it doesn't do that first. The first thing that it does is it needs to go and it needs to say, hey, am I a follower of this person? In order to do that, we need a follower service. I'm going to put this here.
Platinum Lambda: Wait, sorry. I want to talk a little bit about the follow use case. First of all, when a user goes to a restricted version of profile, can you talk to that use case here? So I want to understand the API call path and that, yeah, so kind.
Orthogonal Warrior: Of what I'm thinking is a user goes and they navigate to the user's page and really there would need to be a, yeah, actually now that you're saying that, I think that you're raising a good point. So when I go to the user's page, technically speaking, I could just call for all the photos. But any sort of basic authorization flow on this data would, I mean, specifically if we're doing joins on the data checking. If I have follows and then if I have follows, which querying for the photos, that just wouldn't work. So I need to query first to say, hey, do I follow this person? Which implies that I need just to get the status of a given user. I can get a user's followers, but I need to see, I really just need to get a user. When I get the user, then I should. Yeah, because I mean, I guess I'm kind of envisioning like again, if I think in terms of a UI, if I did that, like I have John Doe here and it would be like John Doe and a follow button. Right. And so you do kind of need some information about the user in addition to whether or not you've actually followed the person. So with that. So yeah, so we need to be able to get a user. So I'm going to go ahead and make the assumption that this is, well, that I can get the user's data from this other API. But specifically we need to get the user and we need to get the user, we need to get the status of the followers. So we, so we're going to post a user id. Followers. We're going to get a user's followers. And, and I guess like this is where like rest is kind of weird. In this, in this specific case, I probably like this would be an API that would probably be more action oriented.
Platinum Lambda: Yes, I think this could be simplified a little bit. So essentially what you're doing is.
Orthogonal Warrior: You.
Platinum Lambda: Have some user context to log, then assume they have some authentication context and it's a metadata associated with the login user like the list of followers. And so I think what you have there to simplify this, getusers Id followers, that gives you the list of followers for user, right? So if you go to, I guess.
Orthogonal Warrior: You can just iterate that strictly and say, hey, do you have this user in your list of followers? Or if that's provided in your authentication context. But that kind of becomes a weird thing to have. And if you get into like, I mean if you have 500 million daily active users and you as a user are following all 500 million users for whatever reason, then all of a sudden that like fetching that list of followers becomes untenable. And so it would be nice to be able to say like, hey, do I follow this specific user? And having a request to fetch. Exactly. To check exactly one user.
Platinum Lambda: Yeah, that could be fine as well. Yeah. So it looks like that's such a major issue you find you're trying to determine is if you go to restricted profile, does it allow me to click the button or is it that you're already following?
Orthogonal Warrior: Exactly, exactly. And so it's probably, it's probably like a user's action.
Platinum Lambda: Oh, you know what you could probably do is you could simplify this and just be on demand. So the minute you click on the profile at that runtime, you basically look up the user id in your followers list. The API you have right there or whatever API, maybe get user by id and just check if the users in the follow ups. If so, then it's grayed out. There's nothing with a follow up. Not then you just follow.
Orthogonal Warrior: Yeah, that, that probably also works, but yeah, so we'll, we'll, I'll just, I'll just slam like a getusers Id followers like an, I like an id here that gets a follower status if available for us. Let's go to civic user, something like this. Well that way I can query for Ace. If me as a user follows a specific user, then yeah. Okay, so now I can go to a user's page, I can say hey, do I, and I can get the user, we're going to assume that this already exists or is provided. So that gets me my name and then I can say hey, do I follow that user with those APIs? And then if I follow that user then I can go and I can request their photos which gets me this list here. And so for this really I just need this user service. Well, I need this. It is a follower service because it's the follower. This service kind of works in conjunction with our auths or our auth service. And these two things are kind of, they are indirect but we don't own this one. This is somebody else, this is auth zero or something like that. And this is our interface onto that. And this has a followers DB that allows me to fetch everything off of that. So if I come in from the API gateway to get any of those things, I go to the follower service for all of these requests. I go to the photos service by owner id for all of them for this request. And then, yeah, so what that does is that gives me those things. So then I guess we need to talk about caching because what we have here is that mostly, yeah, that mostly solves for our functional requirements, but it does not solve for, given my assertion that this is going to be inherently relational, it does not solve for the case or for the latency case. When this gets to scale and gets to 500 million users, even that single join is going to be a pain. So let's see here. So for the follower service, looking at this, the follower service, I guess it's high availability, low latency. So ultimately when I follow somebody, kind of the assumption is that within a short amount of time, that is a couple seconds, I'm then able to see that user's stuff. So when a user interacts with the follower service, so ultimately, well, okay, so this is where now I'm maybe rethinking a little bit what I had originally said, because maybe this isn't relational, maybe this because of that assertion. For the follower service, it actually makes pretty good sense for the followers DB to be something that is probably nosql in some capacity, that it is high, write high, read overwhelmingly, people are probably going to be viewing photos overwhelmingly more than they are going to be uploading photos. And so the frequency of people going to the follower service, reading or posting writing to the follower service so that they can then query the photos DB is going to be high. So it may actually make more sense now that I'm thinking about this, to throw a higher availability, higher write throughput database that doesn't give as strong guarantees on consistency at those specific pieces so that I can throw. So I think this followers DB is probably something like a dynamoDB or something of that nature, which makes it so that this follower service actually doesn't need the cache because the dynamoDB outscales and performs that use case. I'm trying to think if for the photosdb we need something different. I don't know that I do. I think that it may, given that what's being stored in this is also metadata, this may also be able to be a dynamodB. Now that I'm thinking about this and storing all this JSON in there as blobs does also have benefits. So we're just leveraging a document store inherently does also have its own benefits. So yeah, actually, yeah, I think that that's what I'm going to run with. So I think that we're going to just run with some NoSQL databases that we can scale horizontally and then it becomes a question of, okay, so is the latency low enough? Dynamodb is going to be fine for returning JSON objects. It's going to have the right and the read throughput to be able to handle our follower service. And the relations are not such that we need, that we have anything that blocks there. The one thing that we do probably need, however, is the photos service. When I call user id photos, it needs to run a check on the follower service before it goes to the photo service because we shouldn't be returning stuff for which I don't have access. So if I scoot these over specifically for that one case where we kind of merge these domains, we'll call this a user photos service that is going to facilitate going to the followers service and then going to the photo service for that specific case so that we don't actually ever run into a case where we get out of sync because we've, in invalidating, in invalidating the assumption that we're going to have a single relational database that manages these things and instead doing multiple nosqls. We need to make that validity check across these now isolated domains before we make that, before we return that data.
Platinum Lambda: So just to go through, so we talked about the photo upload, we talked about the followers case. I want to just recap my understanding of the getting all the list of photos of people I follow. So I'm guessing here the flow path is that there's an API, I guess on the client there's some request that's initiated that goes to user photo service that first gets all the followers for the given user, which is using the API. The fourth, I guess the fourth, 5th API there in that list. Now with the list of each follower I have a list of followers, I have people I follow. I'm calling that second to last API passing in user id. Is that correct?
Orthogonal Warrior: Okay, so in terms of, so, yes, but also that's not optimal. And I'm understanding now that you meant something different by this than what I had interpreted. So when you say see upload uploaded by other users, the user follows, you're talking in bulk. So if I follow, if John Doe follows A, B and C, you want a page where he can see all of A, B and C's photos. Is that correct? Yep. Okay then. So yeah, so I've solved for the case where a user can see a single users, but I don't think that these would be ideal for the case. For that case specifically, because that case is kind like how you would handle that would be a little, a little different. So I think that it probably would be, it probably would be similar. I think that it does go to the user's iD followers endpoint and gets a list of the user's followers. But I think that it's actually probably a different API. I think that it's probably because like the question then becomes like, if I see the photos uploaded by other users, the user follows, is this, like, what is the criteria for that? So, like, if I'm, if I'm here on this page and I, you know, am I looking, am I seeing, you know, the most recent uploads by all users? Like what? Like what is the, like, what is the criteria of what I'm seeing on that page where I'm seeing all of those things? It just, the most recent uploads or what is that criteria in your mind?
Platinum Lambda: Yeah. So assuming on a mobile device or webpage there's a limited number of items user can see at any time. Assume that what happens is I see 50 uploads on the page and these are the 50 most, let's assume 25 uploads on the page. These are the most recently uploaded 25 photos. So it could be the same user who's uploaded two things or it could be different users each uploading a photo.
Orthogonal Warrior: But it's the most recent 25.
Platinum Lambda: The most recent 25. Net out of the system.
Orthogonal Warrior: Scoped ultimately to who the user follows.
Platinum Lambda: That's right.
Orthogonal Warrior: Okay, so then, yeah, so we would need probably one more API that is going to be a. Here. Oh, come on. Did all my stuff just. Okay. I was going to be really upset. I thought it just disconnected me again. Okay, so we're going to jump in here. We're going to not a post, we're going to get a get photos recent. And actually I don't even, well, we can, we'll call it recents because maybe you create multiple different viewing organizations, but this is going to fetch most recent 25 uploads across all followers. And this photos recents is going to be, would be run by the user photos service. It would go and it would get the list of all of their followers. And then for the list of all of the followers it would need to get the photos, the most recent 25 photos from all of the followers. That's pretty inefficient now that I'm thinking about that. Because if you have a lot of followers and you're fetching 25 from each, that gets really efficient. Is there a way that you can do that better? Yes, you can probably. I guess if this is, if this is sorted and filterable, then maybe you can filter it based on owner ids and then you can sort it based on. So yeah, so the user photos service, the photos recents would be a single endpoint in the user photos service that a user would call. It would go down into the user id, it would get all the users followers with that list of followers. It would then call into the photos service. And I'm just going to document or just throw this together real quick in the thing.
Platinum Lambda: I do have about 1 minute remaining to give that I get some arts and feedback. Okay.
Orthogonal Warrior: Yeah, I'll try and go quick and then. Yeah, I'd love to hear your thoughts. So, you know, user photo service goes to followers service for list of followers. User photos service goes to users id photos with list of followers. It reset me again. Of course it did. And then user photos service goes to users id photos with list and sort by upload date and then return paginated timestamp or return paginated or return result set 25. So it kind of be some flow, something like this, where you would go through that.
Platinum Lambda: Yeah, makes sense. Okay, I have some other questions, but I want to summarize even time. Sure. One moment here. Right?
Orthogonal Warrior: Yeah.
Platinum Lambda: So overall you did a great job on this. It's clear that you've went through this many times and you're very thoughtful and you're very coherent in terms of your communication. The first off I want to talk to is that you did a very good job on the functional requirements. You asked a lot of really good questions. You talked about the need for anonymous users or if we should assume the users are already authenticated. You talked about what metadata I care about seeing. So we came up with the caption location timestamp. You also confirmed whether follow requests are auto accepted or not. Right. Where some verification has to be done. So you did a really, really solid job of probing these functional requirements. And I was impressed out of some of the interviews people I've seen doing. And you did a thorough job. The only thing here is that you did get into capacity estimation and you asked all the right questions. Just keep in mind that when you are done with functional requirements, be sure to ask your interviewer, what non functional requirements do you care about in the design? And I had to obviously stop you and mention that. So before we get too far into it. But that's an important part of it. Your API design is solid. It shows that you clearly understand rustle API design. It's very clean, very concise, very understandable. But do take your time to talk to the request response payloads status codes. Where do the API synchronous asynchronous? I think you did talk to one of the APIs that had the queue. Now that API in and of itself more likely has to be async, right? It cannot be. Right. So if it's returning queue information. So since this is a senior level interview, be sure to call out synchronous asynchronous. The behavior of the API minor net is versioning. So be sure to call out Vivon.
Orthogonal Warrior: Whatever on the API. Right, right.
Platinum Lambda: It shows that you are, you are developing in a way where you can support future contract changes without breaking changes. A good move you made is you talked about the queue initially and you mentioned, hey, I'm talking about here, here's this. But I'll come back to it really good, because showing that to the interviewer, you're not forgetting about something, you will come back to it. So you're explaining you're very diligent in your design. And then as we got into the architecture design, you did a great job of explaining the rationale for architecture components. Right. Why use a load balancer? Why is the eight bit gateway? Well, you need support in direction, horizontal scaling. Continue explaining directional behind certain technologies, that's always a plus. And then you did especially good when you talked about the NoSQL databases and the call outs for Dynamodb. And not just DynamodB because it's a buzzword but why it has read write throughput configurations. Right. Continue where you understand technologies, call it out and explain the rationale for that.
Orthogonal Warrior: Continue.
Platinum Lambda: That's good. And then the one final item I have feedback is when we talked about the initial use case for viewing, seeing photos uploaded by other users. User follows. You did cover the use case where someone searches a user and they can see the photos, they found them. But that's the time and the functional requirement level to say, hey, well, do you also need a news feed list of all the photos?
Orthogonal Warrior: Right, right.
Platinum Lambda: But overall you consistently communicated throughout design. Your technical skills are solid. The other question I was going to ask you if we had more time is how do you, so if you have this queue inserted here and if there are situations where let's, so let's say that certain items were processed out of the queue or certain items in the queue fail to be processed, how do you support troubleshooting issues in the queue?
Orthogonal Warrior: Right.
Platinum Lambda: And then I would have asked you questions. Ron scale. Okay, well, if this runs as a geographical service, what happens here? So be prepared to answer questions without default tolerance and scale and really get into details for senior load, especially one at Facebook. So yes, good. Great job overall.
Orthogonal Warrior: Okay, like, I mean like on the back of this interview, would you be like, yes, he knows this stuff. Like this is, this is a l six level higher or is it like you're left wanting in your opinion?
Platinum Lambda: I think you just get five l six.
Orthogonal Warrior: Okay.
Platinum Lambda: But I think if you want more assurance, you can follow feedback. I mentioned where you go into extreme detail on the API synchronous asynchronous. You continue doubling down on the rationale, the technology choices, not just saying ids, CBN, but what even if you even know, like hey, well, s three, right, or gcs, the more you can talk about technologies, you know, that's all it.
Orthogonal Warrior: And then so, so go really intentionally deep everywhere that I can.
Platinum Lambda: Yeah, well you can, I mean like you have to spend a lot of time on it. But if you're gonna to do this to CDN and you have experience working with CDN, talk a little bit about why and your interviewer will understand. Oh, this guy knows what he's talking about. He's quite experienced because with single engineer, you're expected to know about cues and cdns and these types of things. And the more you can show that off, the better it is. So.
Orthogonal Warrior: Okay. Yeah, I think the hardest thing in these questions is it's like you've never seen it before and it's just like you just have to, you've got 45 minutes to just spit it all out and it's just like.
Platinum Lambda: One final tip on that is so with these interviews, if you don't get a chance to complete it, that's fine. But the main thing they're looking for is someone I can work with in the future. Are they deliberate and how they think? Like the way you. If you had finished just at the API design, I still would have probably been okay with it because you did a great job covering this. Well and with that AP design, you could give it to somebody, they could help build the system because you did a great job covering it. So don't feel pressured to have to get through every little thing.
Orthogonal Warrior: But, yeah.
Platinum Lambda: Okay.
Orthogonal Warrior: Alrighty. Well, thank you so much. Like, I feeling I. It's the practice that helps. Right. So thank you for. For taking me through this and for challenging me and for helping me to think through this. And, yeah, I will try and apply some of your feedback and hopefully tomorrow goes well.
Platinum Lambda: Excellent. Yeah, no worries. And best of luck in your interview.
Orthogonal Warrior: Thank you, man. Have a good one.
Platinum Lambda: You too.
Orthogonal Warrior: Thanks. Bye.
Platinum Lambda: Oh, yeah.

We know exactly what to do and say to get the company, title, and salary you want.

Interview prep and job hunting are chaos and pain. We can help. Really.