Atlassian - Senior Software Engineer | Rejected
Summary
I was rejected for the Senior Software Engineer (P50) role at Atlassian after two downleveling verdicts. I am sharing my detailed experience across multiple rounds, including System Design, Low-Level Design, and Data Structures problems, hoping it helps others.
Full Experience
Hey guys,
This was my experience with Atlassian. Hoping this helps others in the same boat.
1st Round (Karat) (Verdict - pass)
System Design Question -
you have 2 client applications
- delivery executive can mark a delivery as complete, he can also add locker number, in case delivered to a locker.
- User can view the status from his application for a given package.
each load balancer has 3 servers.
first load balancer handles delivery executive related things
second load balancer handles users related things.
there 3 servers on both loadbalancers write to a single DB, read from the same DB.
server 3 on load balancer 2 is used for logging all the logs across all the servers and sending it into a third party application
Round robin routes requests to applications.
Auth is managed independently by the servers.
A load balancer A is 90 % available only, in such cases WAF or lb2 can send the request.
There's a rabbit mq queue which is taking up events that need to be called later on like calling the sms gateway or the locker service that sits as a 3rd party tool.
the rabbit mq related data is consumed by an API service which makes call to the sms gateway eventually and the locker if needed.
Check if there are any flaws in the architecture.
DS Problems <> Karat Round
1. Given a list of words and a note, check if an anagram of a word in words array can be found in note.
The anagram can appear shuffled up in characters, so the ordering doesn't matter.
Additionally, the anagram letters need not be together. it is true as long as all the characters occur in the notes string.
2. Word search to find word in a given grid. Give result as a array of coordinates of the characters in string.
---
2nd Round (LLD - CodeDesign) (Verdict - Pass)
Problem Statement -
We have a cinema hall where movies are scheduled.
Constraints -
Cinema hall has only 1 screen.
Starts around 10 am, and last show can run upto 11 pm.
If a movie ends at 12 pm, next movie can start exactly at 12 pm.
Input will be provided as screenings.
Screening represents, movie schedule. movie will have name, start time (in the screening)
and duration.
Expectation - create a function canSchedule(Movie movie, CurretnMovieScheudle), that can
return a boolean that checks whether it can be put into the current movie schedule with no overlaps.
start time cannot be before 10 am and after 11 pm.
movieName, duration, startTime
movie name & duration
one movie name to movie.
screen scheudle List<Schedule> movieName, duration, startTime
Follow ups -
we want to replace a movie in the schedule
Each movie is associated with a revenue.
---
3rd Round (LLD - Datastructures) - (Verdict - Downlevelled to P40)
I felt this round was unfair. I was able to provide both optimal approaches (Heap and TreeMap). Derived time complexity. Coded the solution for treemap and coded the follow ups as well. Added interface for extension and threw appropriate exceptions. Not sure what else they were expecting here.
Problem Statment
We have a bunch of commoddity prices.
We get a stream of events.
We can either update or add a timestamp and a price against it.
interface RunningCommodityPrice {
void upsertCommodityPrice(int timestamp, int commodityPrice);
int getMaxCommodityPrice();
}
RunningCommodityPrice r = new RunningCommodityPrice();
r.upsertCommodityPrice(4, 27);
r.upsertCommodityPrice(6, 26);
r.upsertCommodityPrice(9, 25);
r.getMaxCommodityPrice(); // output should be 27 which is at timestamp 4
r.upsertCommodityPrice(4, 28); // timestamps can come out of order and there can be duplicates
// the commodity price at timestamp 4 got updated to 28, so the max commodity price is 28
r.getMaxCommodityPrice(); // output should be 28 from timestamp 4
My Solution -
<br>package main.com.commodity_prices;<br><br>import java.util.HashMap;<br>import java.util.Map;<br>import java.util.TreeMap;<br><br>public class CommodityPrices implements CommodityPricesInterface {<br><br> // tracking timestam to price<br> private Map<Integer, Integer> timestampToPrice = new HashMap<>();<br><br> // Tracking price to frequency of occurence of that price<br> private TreeMap<Integer, Integer> priceToFrequency = new TreeMap<>();<br><br> int maxValue;<br><br><br> // Check if timestamp exists in the source of truth map.<br> // if it doesn't exist, then go ahead and make a new entry<br> // We will chekc if the prcie is existing in price to frequency map.<br> // if it exists, we will go ahwad and increment it.<br><br> // if timestamp already exists.<br> // We will first get the old price.<br> // We will update the frequency map to reduce the old price frequency -> 0 then we will r3emove out of tree map<br> // whatever is the new value in both the datastrcutures<br><br> @Override<br> public void upsertCommodityPrice(int timestamp, int commodityPrice) {<br><br> if(maxValue < commodityPrice) {<br> maxValue = commodityPrice;<br> }<br><br> if(timestamp < 0 || commodityPrice < 0) {<br> throw new IllegalArgumentException("Invalid parameters provided");<br> }<br><br> if(!timestampToPrice.containsKey(timestamp)) {<br> this.timestampToPrice.put(timestamp, commodityPrice);<br><br> this.priceToFrequency.put(commodityPrice, this.priceToFrequency.getOrDefault(commodityPrice, 0) + 1);<br> } else {<br><br> int oldPrice = this.timestampToPrice.get(timestamp);<br><br> this.priceToFrequency.put(oldPrice, this.priceToFrequency.get(oldPrice) - 1);<br><br> if(this.priceToFrequency.get(oldPrice) == 0) {<br> this.priceToFrequency.remove(oldPrice);<br> }<br><br> this.timestampToPrice.put(timestamp, commodityPrice);<br> this.priceToFrequency.put(commodityPrice, this.priceToFrequency.getOrDefault(commodityPrice, 0) + 1);<br> }<br><br> }<br><br> @Override<br> public int getMaxCommodityPrice() {<br> return this.maxValue;<br>// return priceToFrequency.lastKey();<br> }<br>}<br>---
4th Round - System Design (Verdict - Downlevel to P40)
Same as the previous round, Interviewer seemed immature.
I was able to provide Functional Requirements, Non Functional Requirements, API design, DB choice, Queries (and how they can be optimized) and a valid HLD.
The interviewer barely asked for any followups. I scaled a basic system to be able to accommodate the scale and showed the DB queries that can be executed along with indices and reasoning for choosing every component. The interviewer
stayed silent for the most part of it and it was difficult to understand the direction he wanted me to go into.
Problem Statement
Design the popular feed on a content authoring platform such as Confluence. If they have never used Confluence, there are parallels like popular feeds that can be used instead. Most candidates have seen a version of
popularity feed in another scenario like YouTube, Twitter, Facebook. However that will limit some of the areas of deeper dive that are listed below.
There are three aspects to this system:
Gathering the popularity indicators, content views, likes and shares.
Calculating the top-n popular content
Providing real time updates to the client
---
Result -
Rejected as I received 2 downlevelling and was not allowed to continue with P50 role interviews.
Interview Questions (6)
Delivery Management System Design
Design a system for delivery management with two client applications: one for delivery executives to mark deliveries complete (with optional locker numbers) and one for users to view package status. The architecture includes a WAF, two load balancers (one for executives, one for users), multiple servers under each, a single shared DB, a dedicated logging server, round-robin routing, independent authentication, and a RabbitMQ queue for deferred events (SMS gateway, locker service). Identify flaws in this architecture.
Details:
- 2 client applications: delivery executive (mark complete, add locker number), user (view status).
- WAF -> 2 Load Balancers.
- Each LB has 3 servers.
- LB1 for delivery executive, LB2 for users.
- All servers write/read from a single DB.
- Server 3 on LB2 for logging to a third-party application.
- Round robin routing.
- Auth managed independently by servers.
- LB A (one of the LBs) is 90% available; WAF or LB2 can send requests in such cases.
- RabbitMQ queue for deferred events (SMS gateway, locker service) consumed by an API service.
Task: Check for flaws in the architecture.
Anagram of Word in Note
Given a list of words and a note, check if an anagram of a word in the words array can be found in note. The anagram can appear shuffled, meaning character order doesn't matter. Additionally, the anagram letters need not be contiguous in the note; it's true as long as all the characters of an anagram are present in the note string.
Word Search (Grid Coordinates)
Word search to find a word in a given grid. Give the result as an array of coordinates of the characters in the string.
Cinema Hall Movie Scheduler
Design a system for scheduling movies in a cinema hall.
Constraints:
- Cinema hall has only 1 screen.
- Movies run from 10 am to 11 pm (last show can run up to 11 pm).
- If a movie ends at 12 pm, the next movie can start exactly at 12 pm.
Input: Screenings (movie schedule), where each screening includes movieName, startTime, and duration.
Expectation: Create a function canSchedule(Movie movie, CurrentMovieSchedule) that returns a boolean, checking if a given movie can be put into the CurrentMovieSchedule without overlaps. The movie's start time cannot be before 10 am and after 11 pm.
Follow-ups:
- Replace a movie in the schedule.
- Each movie is associated with a revenue.
Running Commodity Price Tracker
We have a bunch of commodity prices and get a stream of events. We can either update or add a timestamp and a price against it.
Interface: java <br>interface RunningCommodityPrice { <br> void upsertCommodityPrice(int timestamp, int commodityPrice); <br> int getMaxCommodityPrice(); <br>} <br>
Example: java <br>RunningCommodityPrice r = new RunningCommodityPrice(); <br>r.upsertCommodityPrice(4, 27); <br>r.upsertCommodityPrice(6, 26); <br>r.upsertCommodityPrice(9, 25); <br>r.getMaxCommodityPrice(); // output should be 27 which is at timestamp 4 <br>r.upsertCommodityPrice(4, 28); // timestamps can come out of order and there can be duplicates <br>// the commodity price at timestamp 4 got updated to 28, so the max commodity price is 28 <br>r.getMaxCommodityPrice(); // output should be 28 from timestamp 4 <br>
Design Popular Feed (Confluence/YouTube/Twitter)
Design the popular feed on a content authoring platform such as Confluence. If they have never used Confluence, parallels like popular feeds on YouTube, Twitter, or Facebook can be used instead. The system has three main aspects:
1. Gathering popularity indicators (content views, likes, shares).
2. Calculating the top-n popular content.
3. Providing real-time updates to the client.