A few months ago I got rejected at the technical interview for a position.
The problem that they gave me is the following:
From a binary file, parse two shorts, x and y and build a Point object with these coordinates.
Repeat the process until there is no more shorts to parse. From all those points, return the 10 closest points to the point -200,300 and the furthest points from the point 1000,25.
Could you help me to identify what I can do different to increase the performance of my program?
Also, please give me any general suggestions or pointers to improve my code.
public class Main {
private static final Point closest = new Point(-200, 300);
private static final Point furthest = new Point(1000, 25);
private static final int POINTS_IN_FILE = 10000000;
private static final Comparator<Point> closestComparator = new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
Double firstDistance = o1.distance(closest);
Double secondDistance = o2.distance(closest);
return - firstDistance.compareTo(secondDistance);
}
};
private static final Comparator<Point> furthestComparator = new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
Double firstDistance = o1.distance(furthest);
Double secondDistance = o2.distance(furthest);
return firstDistance.compareTo(secondDistance);
}
};
public static void main(String[] args) throws IOException {
String pathToFile;
for (String arg : args) {
pathToFile = arg;
try (DataInputStream stream = new DataInputStream(
new BufferedInputStream(new FileInputStream(new File(pathToFile))))) {
Point[] pointArray = new Point[POINTS_IN_FILE];
readPointsIntoArray(pointArray, stream);
calculateFirstPoints(pointArray, false, 10);
calculateFirstPoints(pointArray, true, 20);
}
}
}
private static void calculateFirstPoints(Point[] pointArray, boolean furthest, int size) {
Comparator<Point> pointComparator = furthest? furthestComparator : closestComparator;
LimitedPriorityQueueWrapper<Point> pointWrapper = new LimitedPriorityQueueWrapper<>(size, pointComparator);
pointWrapper.bulkInsertToQueue(pointArray);
List<Point> resultList = pointWrapper.getElements();
printPoints(resultList);
}
private static void readPointsIntoArray(Point[] points, DataInputStream stream) {
int index = 0;
while (true) {
try {
Point currentPoint = new Point(stream.readShort(), stream.readShort());
points[index] = currentPoint;
index++;
} catch (Exception e) {
break;
}
}
}
private static void printPoints(List<Point> points) {
for (Point point : points) {
System.out.println(point.toString());
}
}
}
This is a helper class that I created with an inner priority queue. Its purpose is to insert the points in the correct order so I don't have to sort the collection later.
public class LimitedPriorityQueueWrapper<T> {
private PriorityQueue<T> queue;
private int size;
private boolean sizeReached = false;
public LimitedPriorityQueueWrapper(int size, Comparator<T> comparator) {
this.queue = new PriorityQueue<T>(comparator);
this.size = size;
}
public void insertIntoQueue(T t) {
queue.add(t);
if (sizeReached) {
queue.poll();
return;
}
if (queue.size() >= size) {
sizeReached = true;
}
}
public void bulkInsertToQueue(T[] array) {
for (int i=0; i<array.length; i++) {
insertIntoQueue(array[i]);
}
}
public List<T> getElements() {
return new ArrayList<T>(queue);
}
}
All the advice that you can give me will be very appreciated.