Elevator design (interview)
up vote
2
down vote
favorite
I believe interviews (~1 hour) commonly ask to code an elevator system, so this is my attempt.
I made some requirements/assumptions:
- support one or more elevators
- accept pickup requests (think of up/down buttons outside each floor) that is served by the entire elevator pool
- each elevator individually accepts destination requests (think of floor buttons in each elevator)
My code is below, I didn't include my Exception class code, as they are just bare bones. I appreciate any feedback!
Elevator interface
public interface Elevator {
int getMinFloor();
int getMaxFloor();
int getCurrentFloor();
Deque<Integer> getDestinationQueue();
void moveUp();
void moveDown();
void moveNext();
void prependDestination(int floor);
void queueDestination(int floor);
boolean isInPath(int floor);
boolean isFull();
boolean isIdle(); }
Elevator
public class ElevatorImpl implements Elevator {
private final int minFloor;
private final int maxFloor;
private final int maxCapacity;
private int currentFloor;
private Deque<Integer> destinationQueue;
public ElevatorImpl(int minFloor, int maxFloor, int maxCapacity) {
this.minFloor = minFloor;
this.maxFloor = maxFloor;
this.maxCapacity = maxCapacity;
currentFloor = 0;
destinationQueue = new LinkedList<>();
}
@Override
public int getMinFloor() {
return minFloor;
}
@Override
public int getMaxFloor() {
return maxFloor;
}
@Override
public int getCurrentFloor() {
return currentFloor;
}
@Override
public Deque<Integer> getDestinationQueue() {
return destinationQueue;
}
@Override
public void queueDestination(int floor) {
//O(N)
if (!destinationQueue.contains(floor)) {
destinationQueue.add(floor);
}
}
@Override
public void prependDestination(int floor) {
destinationQueue.addFirst(floor);
}
@Override
public void moveNext() {
if (destinationQueue.isEmpty()) {
return;
}
int destination = destinationQueue.peek();
if (currentFloor < destination) {
moveUp();
} else if (currentFloor > destination) {
moveDown();
}
if (currentFloor == destination) {
destinationQueue.poll();
}
}
@Override
public void moveUp() {
if (currentFloor == maxFloor) {
throw new MoveFailureException("cannot move above max currentFloor");
}
// if full, then takes up a tick and must check again next tick
if (!isFull()) {
currentFloor++;
}
}
@Override
public void moveDown() {
if (currentFloor == minFloor) {
throw new MoveFailureException("cannot move below minimum currentFloor");
}
if (!isFull()) {
currentFloor--;
}
}
@Override
public boolean isInPath(int floor) {
if (destinationQueue.isEmpty()) {
return false;
}
int destination = destinationQueue.peek();
return (floor >= currentFloor && floor <= destination) || (floor <= currentFloor && floor >= destination);
}
@Override
public boolean isFull() {
//would use maxCapacity here
return false;
}
@Override
public boolean isIdle() {
return destinationQueue.isEmpty();
}
}
Controller interface
public interface ElevatorController {
void addPickup(int floor);
void step() throws RunException;
}
Controller
public class GlobalElevatorController implements ElevatorController {
private List<Elevator> elevators;
// mainly used if no elevators are available, then need to queue into controller
private Queue<Integer> pickupQueue;
public GlobalElevatorController(List<Elevator> elevators) {
this.elevators = elevators;
pickupQueue = new LinkedList<>();
}
/**
* Represents pick up (origin floor). Attempt to delegate request immediately, but if no elevators presently
* available, then add to controller's queue, and attempt again during step().
*
* @param floor assumption: the same pickup floor will not be requested while it's being processed. Logic should
* be handled by hypothetical button class.
*/
@Override
public void addPickup(int floor) {
if (!pickupQueue.isEmpty()) {
pickupQueue.add(floor);
} else {
// immediately put into idle or in-path elevators
for (Elevator elevator : elevators) {
if (elevator.isIdle()) {
elevator.queueDestination(floor);
return;
} else if (elevator.isInPath(floor)) {
elevator.queueDestination(floor);
}
}
}
}
/**
* Move elevators.
*
* TODO: extend Thread, so this runs autonomously. For now, call step() manually.
*/
@Override
public void step() {
for (Elevator elevator : elevators) {
if (elevator.isIdle()) {
if (!pickupQueue.isEmpty()) {
elevator.queueDestination(pickupQueue.poll());
}
} else {
elevator.moveNext();
}
}
} }
java object-oriented interview-questions
add a comment |
up vote
2
down vote
favorite
I believe interviews (~1 hour) commonly ask to code an elevator system, so this is my attempt.
I made some requirements/assumptions:
- support one or more elevators
- accept pickup requests (think of up/down buttons outside each floor) that is served by the entire elevator pool
- each elevator individually accepts destination requests (think of floor buttons in each elevator)
My code is below, I didn't include my Exception class code, as they are just bare bones. I appreciate any feedback!
Elevator interface
public interface Elevator {
int getMinFloor();
int getMaxFloor();
int getCurrentFloor();
Deque<Integer> getDestinationQueue();
void moveUp();
void moveDown();
void moveNext();
void prependDestination(int floor);
void queueDestination(int floor);
boolean isInPath(int floor);
boolean isFull();
boolean isIdle(); }
Elevator
public class ElevatorImpl implements Elevator {
private final int minFloor;
private final int maxFloor;
private final int maxCapacity;
private int currentFloor;
private Deque<Integer> destinationQueue;
public ElevatorImpl(int minFloor, int maxFloor, int maxCapacity) {
this.minFloor = minFloor;
this.maxFloor = maxFloor;
this.maxCapacity = maxCapacity;
currentFloor = 0;
destinationQueue = new LinkedList<>();
}
@Override
public int getMinFloor() {
return minFloor;
}
@Override
public int getMaxFloor() {
return maxFloor;
}
@Override
public int getCurrentFloor() {
return currentFloor;
}
@Override
public Deque<Integer> getDestinationQueue() {
return destinationQueue;
}
@Override
public void queueDestination(int floor) {
//O(N)
if (!destinationQueue.contains(floor)) {
destinationQueue.add(floor);
}
}
@Override
public void prependDestination(int floor) {
destinationQueue.addFirst(floor);
}
@Override
public void moveNext() {
if (destinationQueue.isEmpty()) {
return;
}
int destination = destinationQueue.peek();
if (currentFloor < destination) {
moveUp();
} else if (currentFloor > destination) {
moveDown();
}
if (currentFloor == destination) {
destinationQueue.poll();
}
}
@Override
public void moveUp() {
if (currentFloor == maxFloor) {
throw new MoveFailureException("cannot move above max currentFloor");
}
// if full, then takes up a tick and must check again next tick
if (!isFull()) {
currentFloor++;
}
}
@Override
public void moveDown() {
if (currentFloor == minFloor) {
throw new MoveFailureException("cannot move below minimum currentFloor");
}
if (!isFull()) {
currentFloor--;
}
}
@Override
public boolean isInPath(int floor) {
if (destinationQueue.isEmpty()) {
return false;
}
int destination = destinationQueue.peek();
return (floor >= currentFloor && floor <= destination) || (floor <= currentFloor && floor >= destination);
}
@Override
public boolean isFull() {
//would use maxCapacity here
return false;
}
@Override
public boolean isIdle() {
return destinationQueue.isEmpty();
}
}
Controller interface
public interface ElevatorController {
void addPickup(int floor);
void step() throws RunException;
}
Controller
public class GlobalElevatorController implements ElevatorController {
private List<Elevator> elevators;
// mainly used if no elevators are available, then need to queue into controller
private Queue<Integer> pickupQueue;
public GlobalElevatorController(List<Elevator> elevators) {
this.elevators = elevators;
pickupQueue = new LinkedList<>();
}
/**
* Represents pick up (origin floor). Attempt to delegate request immediately, but if no elevators presently
* available, then add to controller's queue, and attempt again during step().
*
* @param floor assumption: the same pickup floor will not be requested while it's being processed. Logic should
* be handled by hypothetical button class.
*/
@Override
public void addPickup(int floor) {
if (!pickupQueue.isEmpty()) {
pickupQueue.add(floor);
} else {
// immediately put into idle or in-path elevators
for (Elevator elevator : elevators) {
if (elevator.isIdle()) {
elevator.queueDestination(floor);
return;
} else if (elevator.isInPath(floor)) {
elevator.queueDestination(floor);
}
}
}
}
/**
* Move elevators.
*
* TODO: extend Thread, so this runs autonomously. For now, call step() manually.
*/
@Override
public void step() {
for (Elevator elevator : elevators) {
if (elevator.isIdle()) {
if (!pickupQueue.isEmpty()) {
elevator.queueDestination(pickupQueue.poll());
}
} else {
elevator.moveNext();
}
}
} }
java object-oriented interview-questions
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I believe interviews (~1 hour) commonly ask to code an elevator system, so this is my attempt.
I made some requirements/assumptions:
- support one or more elevators
- accept pickup requests (think of up/down buttons outside each floor) that is served by the entire elevator pool
- each elevator individually accepts destination requests (think of floor buttons in each elevator)
My code is below, I didn't include my Exception class code, as they are just bare bones. I appreciate any feedback!
Elevator interface
public interface Elevator {
int getMinFloor();
int getMaxFloor();
int getCurrentFloor();
Deque<Integer> getDestinationQueue();
void moveUp();
void moveDown();
void moveNext();
void prependDestination(int floor);
void queueDestination(int floor);
boolean isInPath(int floor);
boolean isFull();
boolean isIdle(); }
Elevator
public class ElevatorImpl implements Elevator {
private final int minFloor;
private final int maxFloor;
private final int maxCapacity;
private int currentFloor;
private Deque<Integer> destinationQueue;
public ElevatorImpl(int minFloor, int maxFloor, int maxCapacity) {
this.minFloor = minFloor;
this.maxFloor = maxFloor;
this.maxCapacity = maxCapacity;
currentFloor = 0;
destinationQueue = new LinkedList<>();
}
@Override
public int getMinFloor() {
return minFloor;
}
@Override
public int getMaxFloor() {
return maxFloor;
}
@Override
public int getCurrentFloor() {
return currentFloor;
}
@Override
public Deque<Integer> getDestinationQueue() {
return destinationQueue;
}
@Override
public void queueDestination(int floor) {
//O(N)
if (!destinationQueue.contains(floor)) {
destinationQueue.add(floor);
}
}
@Override
public void prependDestination(int floor) {
destinationQueue.addFirst(floor);
}
@Override
public void moveNext() {
if (destinationQueue.isEmpty()) {
return;
}
int destination = destinationQueue.peek();
if (currentFloor < destination) {
moveUp();
} else if (currentFloor > destination) {
moveDown();
}
if (currentFloor == destination) {
destinationQueue.poll();
}
}
@Override
public void moveUp() {
if (currentFloor == maxFloor) {
throw new MoveFailureException("cannot move above max currentFloor");
}
// if full, then takes up a tick and must check again next tick
if (!isFull()) {
currentFloor++;
}
}
@Override
public void moveDown() {
if (currentFloor == minFloor) {
throw new MoveFailureException("cannot move below minimum currentFloor");
}
if (!isFull()) {
currentFloor--;
}
}
@Override
public boolean isInPath(int floor) {
if (destinationQueue.isEmpty()) {
return false;
}
int destination = destinationQueue.peek();
return (floor >= currentFloor && floor <= destination) || (floor <= currentFloor && floor >= destination);
}
@Override
public boolean isFull() {
//would use maxCapacity here
return false;
}
@Override
public boolean isIdle() {
return destinationQueue.isEmpty();
}
}
Controller interface
public interface ElevatorController {
void addPickup(int floor);
void step() throws RunException;
}
Controller
public class GlobalElevatorController implements ElevatorController {
private List<Elevator> elevators;
// mainly used if no elevators are available, then need to queue into controller
private Queue<Integer> pickupQueue;
public GlobalElevatorController(List<Elevator> elevators) {
this.elevators = elevators;
pickupQueue = new LinkedList<>();
}
/**
* Represents pick up (origin floor). Attempt to delegate request immediately, but if no elevators presently
* available, then add to controller's queue, and attempt again during step().
*
* @param floor assumption: the same pickup floor will not be requested while it's being processed. Logic should
* be handled by hypothetical button class.
*/
@Override
public void addPickup(int floor) {
if (!pickupQueue.isEmpty()) {
pickupQueue.add(floor);
} else {
// immediately put into idle or in-path elevators
for (Elevator elevator : elevators) {
if (elevator.isIdle()) {
elevator.queueDestination(floor);
return;
} else if (elevator.isInPath(floor)) {
elevator.queueDestination(floor);
}
}
}
}
/**
* Move elevators.
*
* TODO: extend Thread, so this runs autonomously. For now, call step() manually.
*/
@Override
public void step() {
for (Elevator elevator : elevators) {
if (elevator.isIdle()) {
if (!pickupQueue.isEmpty()) {
elevator.queueDestination(pickupQueue.poll());
}
} else {
elevator.moveNext();
}
}
} }
java object-oriented interview-questions
I believe interviews (~1 hour) commonly ask to code an elevator system, so this is my attempt.
I made some requirements/assumptions:
- support one or more elevators
- accept pickup requests (think of up/down buttons outside each floor) that is served by the entire elevator pool
- each elevator individually accepts destination requests (think of floor buttons in each elevator)
My code is below, I didn't include my Exception class code, as they are just bare bones. I appreciate any feedback!
Elevator interface
public interface Elevator {
int getMinFloor();
int getMaxFloor();
int getCurrentFloor();
Deque<Integer> getDestinationQueue();
void moveUp();
void moveDown();
void moveNext();
void prependDestination(int floor);
void queueDestination(int floor);
boolean isInPath(int floor);
boolean isFull();
boolean isIdle(); }
Elevator
public class ElevatorImpl implements Elevator {
private final int minFloor;
private final int maxFloor;
private final int maxCapacity;
private int currentFloor;
private Deque<Integer> destinationQueue;
public ElevatorImpl(int minFloor, int maxFloor, int maxCapacity) {
this.minFloor = minFloor;
this.maxFloor = maxFloor;
this.maxCapacity = maxCapacity;
currentFloor = 0;
destinationQueue = new LinkedList<>();
}
@Override
public int getMinFloor() {
return minFloor;
}
@Override
public int getMaxFloor() {
return maxFloor;
}
@Override
public int getCurrentFloor() {
return currentFloor;
}
@Override
public Deque<Integer> getDestinationQueue() {
return destinationQueue;
}
@Override
public void queueDestination(int floor) {
//O(N)
if (!destinationQueue.contains(floor)) {
destinationQueue.add(floor);
}
}
@Override
public void prependDestination(int floor) {
destinationQueue.addFirst(floor);
}
@Override
public void moveNext() {
if (destinationQueue.isEmpty()) {
return;
}
int destination = destinationQueue.peek();
if (currentFloor < destination) {
moveUp();
} else if (currentFloor > destination) {
moveDown();
}
if (currentFloor == destination) {
destinationQueue.poll();
}
}
@Override
public void moveUp() {
if (currentFloor == maxFloor) {
throw new MoveFailureException("cannot move above max currentFloor");
}
// if full, then takes up a tick and must check again next tick
if (!isFull()) {
currentFloor++;
}
}
@Override
public void moveDown() {
if (currentFloor == minFloor) {
throw new MoveFailureException("cannot move below minimum currentFloor");
}
if (!isFull()) {
currentFloor--;
}
}
@Override
public boolean isInPath(int floor) {
if (destinationQueue.isEmpty()) {
return false;
}
int destination = destinationQueue.peek();
return (floor >= currentFloor && floor <= destination) || (floor <= currentFloor && floor >= destination);
}
@Override
public boolean isFull() {
//would use maxCapacity here
return false;
}
@Override
public boolean isIdle() {
return destinationQueue.isEmpty();
}
}
Controller interface
public interface ElevatorController {
void addPickup(int floor);
void step() throws RunException;
}
Controller
public class GlobalElevatorController implements ElevatorController {
private List<Elevator> elevators;
// mainly used if no elevators are available, then need to queue into controller
private Queue<Integer> pickupQueue;
public GlobalElevatorController(List<Elevator> elevators) {
this.elevators = elevators;
pickupQueue = new LinkedList<>();
}
/**
* Represents pick up (origin floor). Attempt to delegate request immediately, but if no elevators presently
* available, then add to controller's queue, and attempt again during step().
*
* @param floor assumption: the same pickup floor will not be requested while it's being processed. Logic should
* be handled by hypothetical button class.
*/
@Override
public void addPickup(int floor) {
if (!pickupQueue.isEmpty()) {
pickupQueue.add(floor);
} else {
// immediately put into idle or in-path elevators
for (Elevator elevator : elevators) {
if (elevator.isIdle()) {
elevator.queueDestination(floor);
return;
} else if (elevator.isInPath(floor)) {
elevator.queueDestination(floor);
}
}
}
}
/**
* Move elevators.
*
* TODO: extend Thread, so this runs autonomously. For now, call step() manually.
*/
@Override
public void step() {
for (Elevator elevator : elevators) {
if (elevator.isIdle()) {
if (!pickupQueue.isEmpty()) {
elevator.queueDestination(pickupQueue.poll());
}
} else {
elevator.moveNext();
}
}
} }
java object-oriented interview-questions
java object-oriented interview-questions
edited Nov 5 '17 at 5:43
asked Nov 5 '17 at 1:32
onepiece
11114
11114
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
4
down vote
As an interviewer, I would consider this to be a failed attempt. Simply put, it's conceptually wrong. No elevator that I have ever encountered acts as a queue. In a single-elevator system, it should go up, stopping at all requested floors on the way, until there are no more pending requests for higher floors, then it should service all of the down requests in descending order. The order in which the requests are submitted does not matter; the timing does matter, though.
In an interview, you should usually submit the simplest solution that works (then ask for feedback, and refine the solution as necessary). I see that you wrote an interface and an implementation, so I would challenge you to explain why you felt that an interface was needed. Are you anticipating the need for multiple implementations? One such justification might be to implement a multi-elevator system in the future. But in that case, your interface would not be sophisticated enough. With multiple elevators, you would need to distinguish between external and internal requests: external requests (consisting of a floor and desired direction) may be served by any elevator, but internal requests (consisting of a destination) must be served by a specific elevator. Furthermore, you would probably want to model the system using a controller that directs the elevators' movements. With multiple elevators, the algorithms for deciding which elevator to dispatch to handle an external request could get quite sophisticated. If you are planning for growth (which doesn't look like the case here), a // TODO
comment would be helpful.
One minor observation: you have a maxCapacity
field. What is it for? "Max" capacity sounds redundant — why not just "capacity"? Are you talking about limiting the load that the elevator is carrying (which you haven't modeled), or limiting the number of requests (which makes no sense)? In any case, I'd avoid leaving unexplained dead code when submitting a solution.
Thanks for the feedback! My response to your paragraph #1: The elevator uses a Deque. If a request is in the path that the elevator is going, the controller puts the request to the front of the Deque, which makes it not strictly queue behavior, and resembles your description. If no elevators are available, the controller stores the request to its own Queue, since it should wait to see which elevators are available.
– onepiece
Nov 5 '17 at 7:18
Paragraph #2: I created an interface to allow for hypothetical multiple implementations. For example, different buildings may require different implementations. I didn't make request classes for simplicity's sake. Internal request is already represented by Elevator'squeueDestination(int floor)
. External request is somewhat represented by GlobalElevatorController's addPickup(int floor), though it's missing your described direction. What would be the usage of the direction? I'm not sure what you mean by "model the system using a controller", as I do have a controller class.
– onepiece
Nov 5 '17 at 7:22
p#2 continued: The controller logic searches for the first idle (no requests and not full) or in path (between curr floor and destination) elevator. If none found, then controller queues the request itself. I think it's reasonably functional, but would like ideas on how to improve it
– onepiece
Nov 5 '17 at 7:24
Paragraph #3: maxCapacity is for the weight limit of the elevator, and yes it can be better named. I stubbed the isFull() method for simplicity sake. Thanks for all your comments, and I would appreciate if you could re-respond
– onepiece
Nov 5 '17 at 7:28
Nice explanation, I would consider finding all the relevantobjects
needed to complete the task, probably asking interviewer to describe in detail what the elevator should do? Few questions from my side, can we leaveuser
since we are consideringElevator
as a system here? I would have chosenElevator
,Door
,Button
,Direction,
Floor` as one on the classes, any thought?
– CodeYogi
Nov 7 '17 at 12:26
add a comment |
up vote
0
down vote
plz add the main method code too
New contributor
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f179645%2felevator-design-interview%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
As an interviewer, I would consider this to be a failed attempt. Simply put, it's conceptually wrong. No elevator that I have ever encountered acts as a queue. In a single-elevator system, it should go up, stopping at all requested floors on the way, until there are no more pending requests for higher floors, then it should service all of the down requests in descending order. The order in which the requests are submitted does not matter; the timing does matter, though.
In an interview, you should usually submit the simplest solution that works (then ask for feedback, and refine the solution as necessary). I see that you wrote an interface and an implementation, so I would challenge you to explain why you felt that an interface was needed. Are you anticipating the need for multiple implementations? One such justification might be to implement a multi-elevator system in the future. But in that case, your interface would not be sophisticated enough. With multiple elevators, you would need to distinguish between external and internal requests: external requests (consisting of a floor and desired direction) may be served by any elevator, but internal requests (consisting of a destination) must be served by a specific elevator. Furthermore, you would probably want to model the system using a controller that directs the elevators' movements. With multiple elevators, the algorithms for deciding which elevator to dispatch to handle an external request could get quite sophisticated. If you are planning for growth (which doesn't look like the case here), a // TODO
comment would be helpful.
One minor observation: you have a maxCapacity
field. What is it for? "Max" capacity sounds redundant — why not just "capacity"? Are you talking about limiting the load that the elevator is carrying (which you haven't modeled), or limiting the number of requests (which makes no sense)? In any case, I'd avoid leaving unexplained dead code when submitting a solution.
Thanks for the feedback! My response to your paragraph #1: The elevator uses a Deque. If a request is in the path that the elevator is going, the controller puts the request to the front of the Deque, which makes it not strictly queue behavior, and resembles your description. If no elevators are available, the controller stores the request to its own Queue, since it should wait to see which elevators are available.
– onepiece
Nov 5 '17 at 7:18
Paragraph #2: I created an interface to allow for hypothetical multiple implementations. For example, different buildings may require different implementations. I didn't make request classes for simplicity's sake. Internal request is already represented by Elevator'squeueDestination(int floor)
. External request is somewhat represented by GlobalElevatorController's addPickup(int floor), though it's missing your described direction. What would be the usage of the direction? I'm not sure what you mean by "model the system using a controller", as I do have a controller class.
– onepiece
Nov 5 '17 at 7:22
p#2 continued: The controller logic searches for the first idle (no requests and not full) or in path (between curr floor and destination) elevator. If none found, then controller queues the request itself. I think it's reasonably functional, but would like ideas on how to improve it
– onepiece
Nov 5 '17 at 7:24
Paragraph #3: maxCapacity is for the weight limit of the elevator, and yes it can be better named. I stubbed the isFull() method for simplicity sake. Thanks for all your comments, and I would appreciate if you could re-respond
– onepiece
Nov 5 '17 at 7:28
Nice explanation, I would consider finding all the relevantobjects
needed to complete the task, probably asking interviewer to describe in detail what the elevator should do? Few questions from my side, can we leaveuser
since we are consideringElevator
as a system here? I would have chosenElevator
,Door
,Button
,Direction,
Floor` as one on the classes, any thought?
– CodeYogi
Nov 7 '17 at 12:26
add a comment |
up vote
4
down vote
As an interviewer, I would consider this to be a failed attempt. Simply put, it's conceptually wrong. No elevator that I have ever encountered acts as a queue. In a single-elevator system, it should go up, stopping at all requested floors on the way, until there are no more pending requests for higher floors, then it should service all of the down requests in descending order. The order in which the requests are submitted does not matter; the timing does matter, though.
In an interview, you should usually submit the simplest solution that works (then ask for feedback, and refine the solution as necessary). I see that you wrote an interface and an implementation, so I would challenge you to explain why you felt that an interface was needed. Are you anticipating the need for multiple implementations? One such justification might be to implement a multi-elevator system in the future. But in that case, your interface would not be sophisticated enough. With multiple elevators, you would need to distinguish between external and internal requests: external requests (consisting of a floor and desired direction) may be served by any elevator, but internal requests (consisting of a destination) must be served by a specific elevator. Furthermore, you would probably want to model the system using a controller that directs the elevators' movements. With multiple elevators, the algorithms for deciding which elevator to dispatch to handle an external request could get quite sophisticated. If you are planning for growth (which doesn't look like the case here), a // TODO
comment would be helpful.
One minor observation: you have a maxCapacity
field. What is it for? "Max" capacity sounds redundant — why not just "capacity"? Are you talking about limiting the load that the elevator is carrying (which you haven't modeled), or limiting the number of requests (which makes no sense)? In any case, I'd avoid leaving unexplained dead code when submitting a solution.
Thanks for the feedback! My response to your paragraph #1: The elevator uses a Deque. If a request is in the path that the elevator is going, the controller puts the request to the front of the Deque, which makes it not strictly queue behavior, and resembles your description. If no elevators are available, the controller stores the request to its own Queue, since it should wait to see which elevators are available.
– onepiece
Nov 5 '17 at 7:18
Paragraph #2: I created an interface to allow for hypothetical multiple implementations. For example, different buildings may require different implementations. I didn't make request classes for simplicity's sake. Internal request is already represented by Elevator'squeueDestination(int floor)
. External request is somewhat represented by GlobalElevatorController's addPickup(int floor), though it's missing your described direction. What would be the usage of the direction? I'm not sure what you mean by "model the system using a controller", as I do have a controller class.
– onepiece
Nov 5 '17 at 7:22
p#2 continued: The controller logic searches for the first idle (no requests and not full) or in path (between curr floor and destination) elevator. If none found, then controller queues the request itself. I think it's reasonably functional, but would like ideas on how to improve it
– onepiece
Nov 5 '17 at 7:24
Paragraph #3: maxCapacity is for the weight limit of the elevator, and yes it can be better named. I stubbed the isFull() method for simplicity sake. Thanks for all your comments, and I would appreciate if you could re-respond
– onepiece
Nov 5 '17 at 7:28
Nice explanation, I would consider finding all the relevantobjects
needed to complete the task, probably asking interviewer to describe in detail what the elevator should do? Few questions from my side, can we leaveuser
since we are consideringElevator
as a system here? I would have chosenElevator
,Door
,Button
,Direction,
Floor` as one on the classes, any thought?
– CodeYogi
Nov 7 '17 at 12:26
add a comment |
up vote
4
down vote
up vote
4
down vote
As an interviewer, I would consider this to be a failed attempt. Simply put, it's conceptually wrong. No elevator that I have ever encountered acts as a queue. In a single-elevator system, it should go up, stopping at all requested floors on the way, until there are no more pending requests for higher floors, then it should service all of the down requests in descending order. The order in which the requests are submitted does not matter; the timing does matter, though.
In an interview, you should usually submit the simplest solution that works (then ask for feedback, and refine the solution as necessary). I see that you wrote an interface and an implementation, so I would challenge you to explain why you felt that an interface was needed. Are you anticipating the need for multiple implementations? One such justification might be to implement a multi-elevator system in the future. But in that case, your interface would not be sophisticated enough. With multiple elevators, you would need to distinguish between external and internal requests: external requests (consisting of a floor and desired direction) may be served by any elevator, but internal requests (consisting of a destination) must be served by a specific elevator. Furthermore, you would probably want to model the system using a controller that directs the elevators' movements. With multiple elevators, the algorithms for deciding which elevator to dispatch to handle an external request could get quite sophisticated. If you are planning for growth (which doesn't look like the case here), a // TODO
comment would be helpful.
One minor observation: you have a maxCapacity
field. What is it for? "Max" capacity sounds redundant — why not just "capacity"? Are you talking about limiting the load that the elevator is carrying (which you haven't modeled), or limiting the number of requests (which makes no sense)? In any case, I'd avoid leaving unexplained dead code when submitting a solution.
As an interviewer, I would consider this to be a failed attempt. Simply put, it's conceptually wrong. No elevator that I have ever encountered acts as a queue. In a single-elevator system, it should go up, stopping at all requested floors on the way, until there are no more pending requests for higher floors, then it should service all of the down requests in descending order. The order in which the requests are submitted does not matter; the timing does matter, though.
In an interview, you should usually submit the simplest solution that works (then ask for feedback, and refine the solution as necessary). I see that you wrote an interface and an implementation, so I would challenge you to explain why you felt that an interface was needed. Are you anticipating the need for multiple implementations? One such justification might be to implement a multi-elevator system in the future. But in that case, your interface would not be sophisticated enough. With multiple elevators, you would need to distinguish between external and internal requests: external requests (consisting of a floor and desired direction) may be served by any elevator, but internal requests (consisting of a destination) must be served by a specific elevator. Furthermore, you would probably want to model the system using a controller that directs the elevators' movements. With multiple elevators, the algorithms for deciding which elevator to dispatch to handle an external request could get quite sophisticated. If you are planning for growth (which doesn't look like the case here), a // TODO
comment would be helpful.
One minor observation: you have a maxCapacity
field. What is it for? "Max" capacity sounds redundant — why not just "capacity"? Are you talking about limiting the load that the elevator is carrying (which you haven't modeled), or limiting the number of requests (which makes no sense)? In any case, I'd avoid leaving unexplained dead code when submitting a solution.
edited Nov 5 '17 at 6:47
answered Nov 5 '17 at 6:38
200_success
128k15149412
128k15149412
Thanks for the feedback! My response to your paragraph #1: The elevator uses a Deque. If a request is in the path that the elevator is going, the controller puts the request to the front of the Deque, which makes it not strictly queue behavior, and resembles your description. If no elevators are available, the controller stores the request to its own Queue, since it should wait to see which elevators are available.
– onepiece
Nov 5 '17 at 7:18
Paragraph #2: I created an interface to allow for hypothetical multiple implementations. For example, different buildings may require different implementations. I didn't make request classes for simplicity's sake. Internal request is already represented by Elevator'squeueDestination(int floor)
. External request is somewhat represented by GlobalElevatorController's addPickup(int floor), though it's missing your described direction. What would be the usage of the direction? I'm not sure what you mean by "model the system using a controller", as I do have a controller class.
– onepiece
Nov 5 '17 at 7:22
p#2 continued: The controller logic searches for the first idle (no requests and not full) or in path (between curr floor and destination) elevator. If none found, then controller queues the request itself. I think it's reasonably functional, but would like ideas on how to improve it
– onepiece
Nov 5 '17 at 7:24
Paragraph #3: maxCapacity is for the weight limit of the elevator, and yes it can be better named. I stubbed the isFull() method for simplicity sake. Thanks for all your comments, and I would appreciate if you could re-respond
– onepiece
Nov 5 '17 at 7:28
Nice explanation, I would consider finding all the relevantobjects
needed to complete the task, probably asking interviewer to describe in detail what the elevator should do? Few questions from my side, can we leaveuser
since we are consideringElevator
as a system here? I would have chosenElevator
,Door
,Button
,Direction,
Floor` as one on the classes, any thought?
– CodeYogi
Nov 7 '17 at 12:26
add a comment |
Thanks for the feedback! My response to your paragraph #1: The elevator uses a Deque. If a request is in the path that the elevator is going, the controller puts the request to the front of the Deque, which makes it not strictly queue behavior, and resembles your description. If no elevators are available, the controller stores the request to its own Queue, since it should wait to see which elevators are available.
– onepiece
Nov 5 '17 at 7:18
Paragraph #2: I created an interface to allow for hypothetical multiple implementations. For example, different buildings may require different implementations. I didn't make request classes for simplicity's sake. Internal request is already represented by Elevator'squeueDestination(int floor)
. External request is somewhat represented by GlobalElevatorController's addPickup(int floor), though it's missing your described direction. What would be the usage of the direction? I'm not sure what you mean by "model the system using a controller", as I do have a controller class.
– onepiece
Nov 5 '17 at 7:22
p#2 continued: The controller logic searches for the first idle (no requests and not full) or in path (between curr floor and destination) elevator. If none found, then controller queues the request itself. I think it's reasonably functional, but would like ideas on how to improve it
– onepiece
Nov 5 '17 at 7:24
Paragraph #3: maxCapacity is for the weight limit of the elevator, and yes it can be better named. I stubbed the isFull() method for simplicity sake. Thanks for all your comments, and I would appreciate if you could re-respond
– onepiece
Nov 5 '17 at 7:28
Nice explanation, I would consider finding all the relevantobjects
needed to complete the task, probably asking interviewer to describe in detail what the elevator should do? Few questions from my side, can we leaveuser
since we are consideringElevator
as a system here? I would have chosenElevator
,Door
,Button
,Direction,
Floor` as one on the classes, any thought?
– CodeYogi
Nov 7 '17 at 12:26
Thanks for the feedback! My response to your paragraph #1: The elevator uses a Deque. If a request is in the path that the elevator is going, the controller puts the request to the front of the Deque, which makes it not strictly queue behavior, and resembles your description. If no elevators are available, the controller stores the request to its own Queue, since it should wait to see which elevators are available.
– onepiece
Nov 5 '17 at 7:18
Thanks for the feedback! My response to your paragraph #1: The elevator uses a Deque. If a request is in the path that the elevator is going, the controller puts the request to the front of the Deque, which makes it not strictly queue behavior, and resembles your description. If no elevators are available, the controller stores the request to its own Queue, since it should wait to see which elevators are available.
– onepiece
Nov 5 '17 at 7:18
Paragraph #2: I created an interface to allow for hypothetical multiple implementations. For example, different buildings may require different implementations. I didn't make request classes for simplicity's sake. Internal request is already represented by Elevator's
queueDestination(int floor)
. External request is somewhat represented by GlobalElevatorController's addPickup(int floor), though it's missing your described direction. What would be the usage of the direction? I'm not sure what you mean by "model the system using a controller", as I do have a controller class.– onepiece
Nov 5 '17 at 7:22
Paragraph #2: I created an interface to allow for hypothetical multiple implementations. For example, different buildings may require different implementations. I didn't make request classes for simplicity's sake. Internal request is already represented by Elevator's
queueDestination(int floor)
. External request is somewhat represented by GlobalElevatorController's addPickup(int floor), though it's missing your described direction. What would be the usage of the direction? I'm not sure what you mean by "model the system using a controller", as I do have a controller class.– onepiece
Nov 5 '17 at 7:22
p#2 continued: The controller logic searches for the first idle (no requests and not full) or in path (between curr floor and destination) elevator. If none found, then controller queues the request itself. I think it's reasonably functional, but would like ideas on how to improve it
– onepiece
Nov 5 '17 at 7:24
p#2 continued: The controller logic searches for the first idle (no requests and not full) or in path (between curr floor and destination) elevator. If none found, then controller queues the request itself. I think it's reasonably functional, but would like ideas on how to improve it
– onepiece
Nov 5 '17 at 7:24
Paragraph #3: maxCapacity is for the weight limit of the elevator, and yes it can be better named. I stubbed the isFull() method for simplicity sake. Thanks for all your comments, and I would appreciate if you could re-respond
– onepiece
Nov 5 '17 at 7:28
Paragraph #3: maxCapacity is for the weight limit of the elevator, and yes it can be better named. I stubbed the isFull() method for simplicity sake. Thanks for all your comments, and I would appreciate if you could re-respond
– onepiece
Nov 5 '17 at 7:28
Nice explanation, I would consider finding all the relevant
objects
needed to complete the task, probably asking interviewer to describe in detail what the elevator should do? Few questions from my side, can we leave user
since we are considering Elevator
as a system here? I would have chosen Elevator
, Door
, Button
, Direction,
Floor` as one on the classes, any thought?– CodeYogi
Nov 7 '17 at 12:26
Nice explanation, I would consider finding all the relevant
objects
needed to complete the task, probably asking interviewer to describe in detail what the elevator should do? Few questions from my side, can we leave user
since we are considering Elevator
as a system here? I would have chosen Elevator
, Door
, Button
, Direction,
Floor` as one on the classes, any thought?– CodeYogi
Nov 7 '17 at 12:26
add a comment |
up vote
0
down vote
plz add the main method code too
New contributor
add a comment |
up vote
0
down vote
plz add the main method code too
New contributor
add a comment |
up vote
0
down vote
up vote
0
down vote
plz add the main method code too
New contributor
plz add the main method code too
New contributor
New contributor
answered 9 mins ago
wayn
1
1
New contributor
New contributor
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f179645%2felevator-design-interview%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown