Amazon Interview Question for Software Engineer / Developers






Comment hidden because of low score. Click to expand.
4
of 6 vote

I have tried to build a more complete system, but it has flaws.
Here is my design:
System class: handles the elevator calling algorithm, which request to send to which elevator, etc.
Elevator class: models an elevator
Request class: Models a request

--------------
System
--------------
PendingReq: Request[*]
EmergencyReq: Request[*]

--------------
serviceNextReq()
stopSystem()
addRequest()
groundElevator(Elevator)
groundAllElevators()
----------------------

--------------
Elevator
--------------
currentRequest: Request

--------------
getCurrReq()
setCurrReq()
processReq()
--------------

----------------
Request
----------------
SrcFloorNo.
-----------------
-----------------

Derived classes of Request: FloorRequest, ElevatorRequest

FloorRequest: Requests sent from a floor
ElevatorRequest: Requests sent from the elevator

-----------------
FloorRequest
-----------------
Direction: bool
-----------------
setDirection()
getDirection()
-----------------

-----------------
ElevatorRequest
-----------------

-----------------

Derived classes of ElevatorRequest: EmergencyRequest and ServiceRequest

----------------------
EmergencyRequest
----------------------
enum emergency    (malfunction, fire, earthquake)

-----------------------


----------------------
ServiceRequest
----------------------
destFloorNo: int

-----------------------

---------------------


Here are the flaws:

Not close enough to real-world? Elevators have buttons, Elevator-has-buttons also makes sense

- Anonymous April 19, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

ggg.. what if an emergency happens which has no an appropriate EmergencyRequest type ?
e.g., biohazard ?;))

and who's gonna instantiate this EmergencyRequest
when it happens ? personnel ? )) everyone dive into panic gg
furthermore: you are nto allowed to use elevator when fire alarm

- Anonymous February 06, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

There should be a method in the elevator class to know that whether the weight of people inside the elevator has crossed its capacity or not!!

- Psycho February 11, 2012 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

public class Elevator {
	private float location = 0;
	private Direction direction = Direction.UP;
	private State state = State.STOPPED;
	private Door door = Door.CLOSED;
	private Thread processingThread;
	private Thread listeningThread;

	public class Request {
		public long time;
		public Integer floor;
		public Direction direction;

		public Request(long time, Integer floor, Direction direction) {
			this.time = time;
			this.floor = floor;
			this.direction = direction;
		}
	}

	public enum Direction {
		UP, DOWN
	}

	public enum State {
		MOVING, STOPPED
	}

	public enum Door {
		OPEN, CLOSED
	}

	public Comparator<Request> upComparator = new Comparator<Request>() {
		public int compare(Request u1, Request u2) {
			return u1.floor.compareTo(u2.floor);
		}
	};

	public Comparator<Request> downComparator = upComparator.reversed();

	private Queue<Request> upQueue = new PriorityQueue<>(upComparator);
	private Queue<Request> currentQueue = upQueue;
	private Queue<Request> downQueue = new PriorityQueue<>(downComparator);

	public void call(int floor, Direction direction) {
		if (direction == Direction.UP) {
			if (floor >= location) {
				currentQueue.add(new Request(System.currentTimeMillis(), floor,
						direction));
			} else {
				upQueue.add(new Request(System.currentTimeMillis(), floor,
						direction));
			}
		} else {
			if (floor <= location) {
				currentQueue.add(new Request(System.currentTimeMillis(), floor,
						direction));
			} else {
				downQueue.add(new Request(System.currentTimeMillis(), floor,
						direction));
			}
		}
	}

	public void go(int floor) {
		call(floor, direction);
	}

	public void process() {
		while (true) {
			if (!upQueue.isEmpty() && !downQueue.isEmpty()) {
				Request r = currentQueue.poll();
				if (r != null) {
					goToFloor(r.floor);
				} else {
					preProcessNextQueue();
				}
			}
		}
	}

	public void goToFloor(int floor) {
		state = State.MOVING;
		for (float i = location; i <= floor; i = (float) (i + 0.1)) {
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		location = floor;
		door = Door.OPEN;
		state = State.STOPPED;
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		door = Door.CLOSED;
	}

	private void preProcessNextQueue() {
		if (getLowestTimeUpQueue() > getLowestTimeDownQueue()) {
			this.direction = Direction.UP;
			currentQueue = upQueue;
			upQueue = new PriorityQueue<>(upComparator);
		} else {
			this.direction = Direction.DOWN;
			currentQueue = downQueue;
			downQueue = new PriorityQueue<>(downComparator);
		}
	}

	private long getLowestTimeUpQueue() {
		long lowest = Long.MAX_VALUE;
		for (Request r : upQueue) {
			if (r.time < lowest)
				lowest = r.time;
		}
		return lowest;
	}

	private long getLowestTimeDownQueue() {
		long lowest = Long.MAX_VALUE;
		for (Request r : downQueue) {
			if (r.time < lowest)
				lowest = r.time;
		}
		return lowest;
	}

	public class Process implements Runnable {
		@Override
		public void run() {
			process();
		}
	}

	public class Listen implements Runnable {
		@Override
		public void run() {
			try {
				ServerSocket serverSocket = new ServerSocket(90000);
				while (true) {
					Socket socket = serverSocket.accept();
					Thread thread = new Thread(new Worker(socket));
					thread.start();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	public class Worker implements Runnable {
		private Socket s;

		public Worker(Socket s) {
			this.s = s;
		}

		@Override
		public void run() {
			try {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(s.getInputStream()));
				String line;
				while (true) {
					if ((line = reader.readLine()) != null) {
						String[] tokens = line.split(" ");
						if(tokens.length == 3 && tokens[0].equals("call")){
							call(Integer.parseInt(tokens[1]), tokens[2].equals("up")?Direction.UP:Direction.DOWN);
						}else if(tokens.length == 2 && tokens[0].equals("go")){
							go(Integer.parseInt(tokens[1]));
						}else{
							s.getOutputStream().write("Wrong input".getBytes());
						}
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		Elevator elevator = new Elevator();
		elevator.listeningThread = new Thread(elevator.new Listen());
		elevator.listeningThread.start();
		elevator.processingThread = new Thread(elevator.new Process());
		elevator.processingThread.start();
		try {
			Thread.currentThread().join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

- Anonymous June 01, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Classes : Elevator, Floor

Floor -> Press Elevator Button.
Elevator -> Go up, Go down, serviceUser, stopElevator.

ElevatorManager has a boolean array of floors, and by walking through the array, elevator can decide whether to go up or down.

- Messi April 13, 2010 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

OMG...Floor is not an Object. You are using the Process Oriented way but not Object Oriented way to handle this question.

The answer is you just need an elevator class. The elevator will save the floor information and current floor number. Then judge the current floor number and the number which it will go (from the user operation), and choose to go up or go down. very simple

- Anonymous April 25, 2010 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Elevator
Floor/Location Identifier
Number of steps
Rotation speed
Daterange
InstallationDate
MaintainenceDate
Department Identifier
AllowedWeight
Detail / Description

Start
Stop
SetDirection
SetRotationSpeed
EmergencyStop = Stop + Alert
EmergencyAccidentSenser Handler

- ankushbindlish May 01, 2010 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 4 vote

I think its a typical example of command pattern. Elevator system will have set of slots where each buttons (commands) can be executed.

This way we can extend the elevator system by adding new buttons very easily and each button can test individually.

- Anonymous August 29, 2010 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 votes

LOL.

- Anonymous February 11, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

LOL

- Anonymous July 29, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

it would be nice to add these two variables
numOfStopsAhead
numOfStopsBehind

according to the direction and requested floor you can increment either
every stop decrements the first one
if the first one becomes 0, it is time to change direction and swap these 2 variables as well.
stop if both is 0
a floor request would increment the ahead one and set the direction and call start

- dantepy May 01, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I was asked the same question, the main issue that you need to worry about is how would you notify the elevator that it needs to move up or down. and also if you are going to have a centralized class to control this behavior and how could you distribute the control.

- Anonymous May 28, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

--You can't design everything during the system. You need to show all operation and implement one. For example

/*
------------------------
Elevator System
------------------------

Use Cases :

1. Passanger/User wants to go to the different floor.
2. He request the floor number in the elevator system
3. Elevator picks the person
4. Elevator delivers the person to the floor.

-----------------
What if elevator is running ?

-> If it is going to the same direction, it will pick the person on its way
-> If it is open state, it will wait to get it running state
-> If elevator is in halt/maintainance state, it will not respond
-> If it is waiting state, it will start moving.

------------------ Alternate usecases----
-> Elevator has a maximum number of floor.
-> A user can request for call, alarm, stop, keep door open/close such commands
-> Elevator has preferrences like door will keep open for 5 seconds for loading or unloading.

------------------
Let's find out the classes, attribute and datastructure by doing language analysis
---------------------------------------------------------------------------------
1. Passanger
-> srcFloor
-> destinationFloor
*issueRequest(int dest)
*issueAlarm()
*issueStop()

2. Elevator
-> state
-> direction
-> speed
-> targetted Floors
*openDoor()
*moveUp()
*moveDown()
*stop()
*startAlarm()

3. State (Enum)
-> Running, Open, Idle, Stopped, Alarmed

4. Floor
-> number
-> isServiced

--------------------------------------------------------------------------------------
Command Pattern ( How Elevator will listen to request )
--------------------------------------------------------------------------------------
/*
/

class Elevator{
State currState;
int directon;
int speed;
Floor[] targettedFloors;

void openDoor()
{
//Implementation of open door
}

void closeDoor()
{
//Implementation of closing door
}
}

interface Request
{
boolean execute(Elevator e);
}

class DoorOpenRequest implements Request{
public boolean execute(Elevator e)
{
e.openDoor();
}
}

class CloseDoorRequest implements Request{
public boolean execute(Elevator e)
{
e.closecloseDoor();
}
}

--- If passanger wants to issue request

Command odCommand = new OpenDoorCommand(Elevator.getInstance());
odCommand.execute();

- Paras Dattani August 10, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class Elevator {
	private float location = 0;
	private Direction direction = Direction.UP;
	private State state = State.STOPPED;
	private Door door = Door.CLOSED;
	private Thread processingThread;
	private Thread listeningThread;

	public class Request {
		public long time;
		public Integer floor;
		public Direction direction;

		public Request(long time, Integer floor, Direction direction) {
			this.time = time;
			this.floor = floor;
			this.direction = direction;
		}
	}

	public enum Direction {
		UP, DOWN
	}

	public enum State {
		MOVING, STOPPED
	}

	public enum Door {
		OPEN, CLOSED
	}

	public Comparator<Request> upComparator = new Comparator<Request>() {
		public int compare(Request u1, Request u2) {
			return u1.floor.compareTo(u2.floor);
		}
	};

	public Comparator<Request> downComparator = upComparator.reversed();

	private Queue<Request> upQueue = new PriorityQueue<>(upComparator);
	private Queue<Request> currentQueue = upQueue;
	private Queue<Request> downQueue = new PriorityQueue<>(downComparator);

	public void call(int floor, Direction direction) {
		if (direction == Direction.UP) {
			if (floor >= location) {
				currentQueue.add(new Request(System.currentTimeMillis(), floor,
						direction));
			} else {
				upQueue.add(new Request(System.currentTimeMillis(), floor,
						direction));
			}
		} else {
			if (floor <= location) {
				currentQueue.add(new Request(System.currentTimeMillis(), floor,
						direction));
			} else {
				downQueue.add(new Request(System.currentTimeMillis(), floor,
						direction));
			}
		}
	}

	public void go(int floor) {
		call(floor, direction);
	}

	public void process() {
		while (true) {
			if (!upQueue.isEmpty() && !downQueue.isEmpty()) {
				Request r = currentQueue.poll();
				if (r != null) {
					goToFloor(r.floor);
				} else {
					preProcessNextQueue();
				}
			}
		}
	}

	public void goToFloor(int floor) {
		state = State.MOVING;
		for (float i = location; i <= floor; i = (float) (i + 0.1)) {
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		location = floor;
		door = Door.OPEN;
		state = State.STOPPED;
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		door = Door.CLOSED;
	}

	private void preProcessNextQueue() {
		if (getLowestTimeUpQueue() > getLowestTimeDownQueue()) {
			this.direction = Direction.UP;
			currentQueue = upQueue;
			upQueue = new PriorityQueue<>(upComparator);
		} else {
			this.direction = Direction.DOWN;
			currentQueue = downQueue;
			downQueue = new PriorityQueue<>(downComparator);
		}
	}

	private long getLowestTimeUpQueue() {
		long lowest = Long.MAX_VALUE;
		for (Request r : upQueue) {
			if (r.time < lowest)
				lowest = r.time;
		}
		return lowest;
	}

	private long getLowestTimeDownQueue() {
		long lowest = Long.MAX_VALUE;
		for (Request r : downQueue) {
			if (r.time < lowest)
				lowest = r.time;
		}
		return lowest;
	}

	public class Process implements Runnable {
		@Override
		public void run() {
			process();
		}
	}

	public class Listen implements Runnable {
		@Override
		public void run() {
			try {
				ServerSocket serverSocket = new ServerSocket(90000);
				while (true) {
					Socket socket = serverSocket.accept();
					Thread thread = new Thread(new Worker(socket));
					thread.start();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	public class Worker implements Runnable {
		private Socket s;

		public Worker(Socket s) {
			this.s = s;
		}

		@Override
		public void run() {
			try {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(s.getInputStream()));
				String line;
				while (true) {
					if ((line = reader.readLine()) != null) {
						String[] tokens = line.split(" ");
						if(tokens.length == 3 && tokens[0].equals("call")){
							call(Integer.parseInt(tokens[1]), tokens[2].equals("up")?Direction.UP:Direction.DOWN);
						}else if(tokens.length == 2 && tokens[0].equals("go")){
							go(Integer.parseInt(tokens[1]));
						}else{
							s.getOutputStream().write("Wrong input".getBytes());
						}
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		Elevator elevator = new Elevator();
		elevator.listeningThread = new Thread(elevator.new Listen());
		elevator.listeningThread.start();
		elevator.processingThread = new Thread(elevator.new Process());
		elevator.processingThread.start();
		try {
			Thread.currentThread().join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

- ketul June 01, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class Elevator {
private float location = 0;
private Direction direction = Direction.UP;
private State state = State.STOPPED;
private Door door = Door.CLOSED;
private Thread processingThread;
private Thread listeningThread;

public class Request {
public long time;
public Integer floor;
public Direction direction;

public Request(long time, Integer floor, Direction direction) {
this.time = time;
this.floor = floor;
this.direction = direction;
}
}

public enum Direction {
UP, DOWN
}

public enum State {
MOVING, STOPPED
}

public enum Door {
OPEN, CLOSED
}

public Comparator<Request> upComparator = new Comparator<Request>() {
public int compare(Request u1, Request u2) {
return u1.floor.compareTo(u2.floor);
}
};

public Comparator<Request> downComparator = upComparator.reversed();

private Queue<Request> upQueue = new PriorityQueue<>(upComparator);
private Queue<Request> currentQueue = upQueue;
private Queue<Request> downQueue = new PriorityQueue<>(downComparator);

public void call(int floor, Direction direction) {
if (direction == Direction.UP) {
if (floor >= location) {
currentQueue.add(new Request(System.currentTimeMillis(), floor,
direction));
} else {
upQueue.add(new Request(System.currentTimeMillis(), floor,
direction));
}
} else {
if (floor <= location) {
currentQueue.add(new Request(System.currentTimeMillis(), floor,
direction));
} else {
downQueue.add(new Request(System.currentTimeMillis(), floor,
direction));
}
}
}

public void go(int floor) {
call(floor, direction);
}

public void process() {
while (true) {
if (!upQueue.isEmpty() && !downQueue.isEmpty()) {
Request r = currentQueue.poll();
if (r != null) {
goToFloor(r.floor);
} else {
preProcessNextQueue();
}
}
}
}

public void goToFloor(int floor) {
state = State.MOVING;
for (float i = location; i <= floor; i = (float) (i + 0.1)) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
location = floor;
door = Door.OPEN;
state = State.STOPPED;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
door = Door.CLOSED;
}

private void preProcessNextQueue() {
if (getLowestTimeUpQueue() > getLowestTimeDownQueue()) {
this.direction = Direction.UP;
currentQueue = upQueue;
upQueue = new PriorityQueue<>(upComparator);
} else {
this.direction = Direction.DOWN;
currentQueue = downQueue;
downQueue = new PriorityQueue<>(downComparator);
}
}

private long getLowestTimeUpQueue() {
long lowest = Long.MAX_VALUE;
for (Request r : upQueue) {
if (r.time < lowest)
lowest = r.time;
}
return lowest;
}

private long getLowestTimeDownQueue() {
long lowest = Long.MAX_VALUE;
for (Request r : downQueue) {
if (r.time < lowest)
lowest = r.time;
}
return lowest;
}

public class Process implements Runnable {
@Override
public void run() {
process();
}
}

public class Listen implements Runnable {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(90000);
while (true) {
Socket socket = serverSocket.accept();
Thread thread = new Thread(new Worker(socket));
thread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

public class Worker implements Runnable {
private Socket s;

public Worker(Socket s) {
this.s = s;
}

@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String line;
while (true) {
if ((line = reader.readLine()) != null) {
String[] tokens = line.split(" ");
if(tokens.length == 3 && tokens[0].equals("call")){
call(Integer.parseInt(tokens[1]), tokens[2].equals("up")?Direction.UP:Direction.DOWN);
}else if(tokens.length == 2 && tokens[0].equals("go")){
go(Integer.parseInt(tokens[1]));
}else{
s.getOutputStream().write("Wrong input".getBytes());
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public static void main(String[] args) {
Elevator elevator = new Elevator();
elevator.listeningThread = new Thread(elevator.new Listen());
elevator.listeningThread.start();
elevator.processingThread = new Thread(elevator.new Process());
elevator.processingThread.start();
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

- Anonymous June 01, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

what is the diff btw go() and call() ??

- Anonymous January 01, 2019 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

what is the diff btw go() and call() ??

- Nouman January 01, 2019 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

{}

- Anonymous December 20, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

“Design a Elevator System” on medium page of @nishantnitb
I have added all possible detail to crack design interview

- Nishant Sharma June 09, 2018 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

There is Video available that will demonstrate how to model elevator, youtube .com watch?v=fITuhLSwbt8

- palak pal July 21, 2013 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More