Sunday, 1 November 2015

Design a Task Executor for a Car Workshop


Interview question asked in Triple Point Technology Company.

The Car workshop has following Employees on the payroll:
Employee Name
Designation
Joe
Trainee
Smith
Expert
Walker
Employee

Following tasks/duties are performed in the workshop:
Task Name
Service Fee($)
Time Taken(Hours)
Car-Wash
100
2
Car-Repair
1000
5
Car-Paint
1100
4

On any given day, a schedule is created in the morning, in which task/tasks are assigned to each Employee. Example, schedule of 2-Jan-2015:
Employee Name
Task Name
Joe
Car-Wash
Car-Repair
Car-Paint
Smith
Car-Repair
Walker
Car-Paint
Car-Repair

Assignment:  
1.  Design and implement Task, Employee and Schedule classes.
2.  Design and Implement Executor which will schedule and execute tasks of all employees 
3.  All Employees will start their work in Parallel (multi-threaded). 
4.  There can be 2 strategies of Task Prioritization –
       Tasks can be prioritized based on the time taken. More time consuming task should be executed prior to other lesser time-consuming tasks assigned to that employee.
Expected output
Employee Name
Task Name
Time taken
Fee
Joe
Car-Repair
5
1000
Car-Paint
4
1100
Car-Wash
2
100
Smith
Car-Repair
5
1000
Walker
Car-Repair
5
1000
Car-Paint
4
1100

       Tasks can be prioritized based on Service Fee. A Task which charges more service fee should be executed first. Expected output
Employee Name
Task Name
Time taken
Fee
Joe
Car-Paint 
4
1100
Car-Repair
5
1000
Car-Wash
2
100
Smith
Car-Repair
5
1000
Walker
Car-Paint
4
1100
Car-Repair
5
1000

Solution:-
First create bean class for Employee which consist of two variable name and designation.

 /**  
  * @author Dixit  
  *  
  */  
 public class Employee {  
      private String name;  
      private String designation;  
      public Employee(String name,String designation) {  
           this.name=name;  
           this.designation=designation;  
      }  
      /**  
       * @return the name  
       */  
      public String getName() {  
           return name;  
      }  
      /**  
       * @param name the name to set  
       */  
      public void setName(String name) {  
           this.name = name;  
      }  
      /**  
       * @return the designation  
       */  
      public String getDesignation() {  
           return designation;  
      }  
      /**  
       * @param designation the designation to set  
       */  
      public void setDesignation(String designation) {  
           this.designation = designation;  
      }  
 }  


then create bean class for Task consisting of 3 fields taskName,fees,timeTaken.

 /**  
  * @author Dixit  
  *   
  */  
 public class Task {  
      private String taskName;  
      private int fees;  
      private int timeTaken;  
      public Task(String taskName, int fees, int timeTaken) {  
           this.taskName = taskName;  
           this.fees = fees;  
           this.timeTaken = timeTaken;  
      }  
      /**  
       * @return the taskName  
       */  
      public String getTaskName() {  
           return taskName;  
      }  
      /**  
       * @param taskName  
       *      the taskName to set  
       */  
      public void setTaskName(String taskName) {  
           this.taskName = taskName;  
      }  
      /**  
       * @return the fees  
       */  
      public int getFees() {  
           return fees;  
      }  
      /**  
       * @param fees  
       *      the fees to set  
       */  
      public void setFees(int fees) {  
           this.fees = fees;  
      }  
      /**  
       * @return the timeTaken  
       */  
      public int getTimeTaken() {  
           return timeTaken;  
      }  
      /**  
       * @param timeTaken  
       *      the timeTaken to set  
       */  
      public void setTimeTaken(int timeTaken) {  
           this.timeTaken = timeTaken;  
      }  
 }  

create a ScheduleTask class consisting of Employee object and List of Task objects.ScheduleTask implements runnable interface to perform multi threading operation.

 import java.util.List;  
 /**  
  * @author Dixit  
  *   
  */  
 public class ScheduleTask implements Runnable {  
      private Employee e;  
      private List<Task> t;  
      /**  
       * @param e  
       * @param t  
       */  
      public ScheduleTask(Employee e, List<Task> t) {  
           super();  
           this.e = e;  
           this.t = t;  
      }  
      /**  
       * @return the e  
       */  
      public Employee getE() {  
           return e;  
      }  
      /**  
       * @param e  
       *      the e to set  
       */  
      public void setE(Employee e) {  
           this.e = e;  
      }  
      /**  
       * @return the t  
       */  
      public List<Task> getT() {  
           return t;  
      }  
      /**  
       * @param t  
       *      the t to set  
       */  
      public void setT(List<Task> t) {  
           this.t = t;  
      }  
      @Override  
      public void run() {  
           for(Task task:t)  
           {  
                System.out.println("Employee Name: "+e.getName()+" ,Task name: "+task.getTaskName()+" ,Time Taken: "+task.getTimeTaken()+" ,Fee: "+task.getFees());  
           }  
      }   
 }


As we have to prioritize the task based on Time Taken and Service fees.Create a comparator class for each type.

Comparator class for Time Taken by the task:-

 import java.util.Comparator;  
 /**  
  *   
  */  
 /**  
  * Compares the tasks and return task with high value of time taken.  
  * @author Dixit  
  *   
  */  
 public class TaskTimeComparator implements Comparator<Task> {  
      @Override  
      public int compare(Task o1, Task o2) {  
           return o2.getTimeTaken() - o1.getTimeTaken();  
      }  
 }  

Comparator class for Time Taken by the task:-

 import java.util.Comparator;  
 /**  
  * Compares the tasks and return task with high fees.  
  * @author Dixit  
  *  
  */  
 public class TaskFeeComparator implements Comparator<Task> {  
      @Override  
      public int compare(Task o1, Task o2) {  
           return o2.getFees() - o1.getFees();  
      }  
 }  

Now Create a main class which uses executor service framework to start the work in parallel(multi-threading)

 import java.util.ArrayList;  
 import java.util.Collections;  
 import java.util.List;  
 import java.util.concurrent.ExecutorService;  
 import java.util.concurrent.Executors;  
 /**  
  * @author Dixit  
  *   
  */  
 public class ExecutorServiceExample {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           // creating Employee Object  
           Employee e1 = new Employee("Joe", "Trainee");  
           Employee e2 = new Employee("Smith", "Expert");  
           Employee e3 = new Employee("Walker", "Employee");  
           // Creating Task Object  
           Task t1 = new Task("Car-Wash", 100, 2);  
           Task t2 = new Task("Car-Repair", 1000, 5);  
           Task t3 = new Task("Car-Paint", 1100, 4);  
           //Creating list of task for employee Joe ie e1 object  
           List<Task> l1 = new ArrayList<Task>();  
           l1.add(t1);  
           l1.add(t2);  
           l1.add(t3);  
           //Creating list of task for employee Smith ie e2 object  
           List<Task> l2 = new ArrayList<Task>();  
           l2.add(t2);  
           //Creating list of task for employee Walker ie e3 object  
           List<Task> l3 = new ArrayList<Task>();  
           l3.add(t3);  
           l3.add(t2);  
           System.out.println("Task Prioritization based on time taken:-");  
           // sort the list of task based on time taken  
           Collections.sort(l1, new TaskTimeComparator());  
           Collections.sort(l2, new TaskTimeComparator());  
           Collections.sort(l3, new TaskTimeComparator());  
           // create scheduleTask objects  
           ScheduleTask s1 = new ScheduleTask(e1, l1);  
           ScheduleTask s2 = new ScheduleTask(e2, l2);  
           ScheduleTask s3 = new ScheduleTask(e3, l3);  
     //creating executor service of 3 threads to execute 3 tasks simultaneously  
           ExecutorService executorService = executorService = Executors.newFixedThreadPool(3);  
           // submit the scheduleTask  
           executorService.submit(s1);  
           executorService.submit(s2);  
           executorService.submit(s3);  
           try {  
                Thread.sleep(1000);  
           } catch (InterruptedException e) {  
                System.out.println("Exception:"+e.getMessage());  
           }  
           System.out.println("\nTask Prioritization based on Service Fees:-");  
           // sort the list of task based on fees  
           Collections.sort(l1, new TaskFeeComparator());  
           Collections.sort(l2, new TaskFeeComparator());  
           Collections.sort(l3, new TaskFeeComparator());  
           // create scheduleTask objects  
           ScheduleTask s4 = new ScheduleTask(e1, l1);  
           ScheduleTask s5 = new ScheduleTask(e2, l2);  
           ScheduleTask s6 = new ScheduleTask(e3, l3);  
           // submit the scheduleTask  
           executorService.submit(s4);  
           executorService.submit(s5);  
           executorService.submit(s6);  
           //shutdown executor service  
           while (!executorService.isTerminated()) {  
                executorService.shutdown();  
           }  
      }  
 }  


 Output  
 Task Prioritization based on time taken:-  
 Employee Name: Joe ,Task name: Car-Repair ,Time Taken: 5 ,Fee: 1000  
 Employee Name: Smith ,Task name: Car-Repair ,Time Taken: 5 ,Fee: 1000  
 Employee Name: Walker ,Task name: Car-Repair ,Time Taken: 5 ,Fee: 1000  
 Employee Name: Joe ,Task name: Car-Paint ,Time Taken: 4 ,Fee: 1100  
 Employee Name: Joe ,Task name: Car-Wash ,Time Taken: 2 ,Fee: 100  
 Employee Name: Walker ,Task name: Car-Paint ,Time Taken: 4 ,Fee: 1100  
 Task Prioritization based on Service Fees:-  
 Employee Name: Joe ,Task name: Car-Paint ,Time Taken: 4 ,Fee: 1100  
 Employee Name: Joe ,Task name: Car-Repair ,Time Taken: 5 ,Fee: 1000  
 Employee Name: Joe ,Task name: Car-Wash ,Time Taken: 2 ,Fee: 100  
 Employee Name: Smith ,Task name: Car-Repair ,Time Taken: 5 ,Fee: 1000  
 Employee Name: Walker ,Task name: Car-Paint ,Time Taken: 4 ,Fee: 1100  
 Employee Name: Walker ,Task name: Car-Repair ,Time Taken: 5 ,Fee: 1000  

All the Best :)
In case of any doubt,please post in comment.

4 comments:

  1. I did not go thru your solution in its entirety. How about using PriorityBlockingQueue in the Executor service? Sorting could take place while insertion.

    ReplyDelete
    Replies
    1. Yes. we can solve this using PriorityBlockingQueue as well.

      Delete
  2. Very informative and unique tips dear. Thanks for sharing

    Car Scanner & Car Scanners in India

    ReplyDelete