VMWare Inc Interview Question
Quality Assurance EngineersTeam: QATeam
Country: India
Interview Type: In-Person
Probably following data structure could help
struct Data{
private:
vector<Range> ranges;
public:
void addToCollection(Range rangObj);
//Intelligently add rangeobj to 'ranges'. Overlapping sections of multiple ranges would
//be made part of only one range as ConcreteSubRange and other ranges would just point at that through VirtualSubrange.
vector<Range> getCollection(); //Returns the net collection generated.
};
struct Range{
int start, end;
vector<SubRange> subranges;
};
struct Subrange : public Range
{};
struct ConcreteSubrange: public SubRange
{
int start, end;
int sum;
bool calculated; //needs to be thread safe
};
struct VirtualSubrange: public SubRange{
ConcreteSubrange *subrange;
};
Before begining calculations, 'Data' would be filled with Range(s) through addToCollection.
'addToCollection' would insure that no two ranges contains redundant data for calculation
and any overlapping part between two ranges is calculated only be one thread.
Each thread would be assigned a range object from Data Collection
and the thread would first work on 'ConcreteSubRange'(s)
and then would wait for completion of calculation of 'VirtualSubRange'(s) by other threads.
package com.thread.ex;
public class SeriesAdder implements Runnable {
private int start;
private int to;
private int finalValue = 0;
public SeriesAdder(int start, int to) {
super();
this.start = start;
this.to = to;
}
@Override
public void run() {
for (int i = start; i <= to; i++) {
finalValue = finalValue + i;
}
System.out.println("Final Value -:"+finalValue);
}
public static void main(String args[]) {
SeriesAdder runnerAdder = new SeriesAdder(0, 12);
Thread tr = new Thread(runnerAdder);
tr.start();
new Thread(new SeriesAdder(0, 10)).start();
new Thread(new SeriesAdder(1, 50)).start();
new Thread(new SeriesAdder(5, 15)).start();
new Thread(new SeriesAdder(10, 20)).start();
new Thread(new SeriesAdder(15, 20)).start();
}
}
Better way to use AtomicInteger like
public AtomicInteger addNumbers(int s, int e)
{
AtomicInteger number = new AtomicInteger(0);
for(int i=s; i <= e; i++)
{
number.addAndGet(i);
}
return number;
}
where s and e are the parameters like 1&10,5&15. Then invoke this method from callable threads and hold the result in FutureObjects
Callable:
@Override
public AtomicInteger call() throws Exception
{
return this.numbers.addNumbers(this.s, this.e);
}
and invoke threads
Callable<AtomicInteger> callable1 = new CallableThread(addNumbers, 1, 10);
Future<AtomicInteger> future1 = executor.submit(callable1);
list.add(future1);
Thanks
How about the following, there is no lock used.
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
std::vector<int> rslt(5, 0);
void myadd(const int s, const int e, const int id) {
int r = 0;
for (int i = s; i <= e; ++i) {
r += i;
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
rslt[id] = r;
}
int main() {
std::thread t1(myadd, 1, 5, 0);
std::thread t2(myadd, 1, 50, 1);
std::thread t3(myadd, 5, 15, 2);
std::thread t4(myadd, 10, 20, 3);
std::thread t5(myadd, 15, 20, 4);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
for (size_t i = 0; i < rslt.size(); ++i) std::cout << rslt[i] << std::endl;
std::cout << "Press enter to continue ..." << std::endl;
std::cin.get();
return 0;
}
I guess interviewer doesn't want addition of same numbers more than once so caching should be done in this case, here is the solution for same.
package threads;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import javafx.util.Pair;
/**
*
* I have to create 5 threads where each thread has to perform the addition operation.
* Thread1 - Add 1 to 10
* Thread2 - Add 1 to 50
* Thread3 - Add 5 to 15
* Thread4 - Add 10 to 20
* Thread5 - Add 15 to 20
* What is the best way to accomplish this? Also, I need 1 sec time delay between each addition operation.
* @author Ramesh BG
*
*/
public class MultiThreadAddition {
private ConcurrentHashMap<Pair<Integer, Integer>, Future<Integer>> sharedConcurrentHashMap = new ConcurrentHashMap<>();
private Thread firstThread;
private Thread secondThread;
private Thread thirdThread;
private Thread fourthThread;
private Thread fifthThread;
private Object sharedLock = new Object();
/**
* @author Ramesh BG
*
*/
private final class ExtendedCallable implements Callable<Integer> {
/**
* @param pair
*/
Pair<Integer, Integer> pair;
public ExtendedCallable(Pair<Integer, Integer> pair) {
this.pair = pair;
}
@Override
public Integer call() throws Exception {
int result = 0;
synchronized (sharedLock) {
Thread.sleep(1000);
}
result = pair.getKey() + pair.getValue();
System.out.println("Thread: "+Thread.currentThread().getName()+" sum of pair "+pair+" is "+result);
return result;
}
}
/**
* @param args
*/
public static void main(String[] args) {
new MultiThreadAddition().createThreads();
}
public void createThreads() {
firstThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(1, 10).add();
}
});
firstThread.start();
secondThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(1, 50).add();
}
});
secondThread.start();
thirdThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(5, 15).add();
}
});
thirdThread.start();
fourthThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(10, 20).add();
}
});
fourthThread.start();
fifthThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(15, 20).add();
}
});
fifthThread.start();
}
private class Addition {
private int lowerRange;
private int upperRange;
public Addition(int lowerRange, int upperRange) {
this.lowerRange = lowerRange;
this.upperRange = upperRange;
}
public int add() {
int result = 0;
int firstNumber = 0;
int secondNumber = 0;
for (int i = this.lowerRange; i <= this.upperRange; i = i + 2) {
if ((i & 1) == 1) {
firstNumber = i;
/*
* if upperRange is oddNumber
*/
if (i + 1 <= this.upperRange) {
secondNumber = i + 1;
}
} else {
result = result + i;
firstNumber = i + 1;
secondNumber = i + 2;
i = i + 1;
}
Pair<Integer, Integer> pair = new Pair<>(firstNumber,
secondNumber);
Future<Integer> future = sharedConcurrentHashMap.get(pair);
if (future == null) {
FutureTask<Integer> futureTask = new FutureTask<Integer>(
new ExtendedCallable(pair));
future = futureTask;
sharedConcurrentHashMap.putIfAbsent(pair, futureTask);
futureTask.run();
} else {
try {
System.out.println("Thread: "+Thread.currentThread().getName()+" uses CACHED VALUE for pair "+pair+" result is "+future.get());
} catch (Exception e) {
e.printStackTrace();
}
}
try {
Integer integer = future.get();
result = result + integer;
} catch (Exception e) {
e.printStackTrace();
}
/*
* reset number, do not want to use same numbers in next
* iteration.
*/
firstNumber = 0;
secondNumber = 0;
}
System.out.println("THREAD: " + Thread.currentThread().getName()
+ " SUM FROM " + this.lowerRange + " TO " + this.upperRange
+ " IS " + result);
return result;
}
}
}
I guess interviewer doesn't want addition of same numbers more than once so caching should be done in this case, here is the solution for same.
{package threads;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import javafx.util.Pair;
/**
*
* I have to create 5 threads where each thread has to perform the addition operation.
* Thread1 - Add 1 to 10
* Thread2 - Add 1 to 50
* Thread3 - Add 5 to 15
* Thread4 - Add 10 to 20
* Thread5 - Add 15 to 20
* What is the best way to accomplish this? Also, I need 1 sec time delay between each addition operation.
* @author Ramesh BG
*
*/
public class MultiThreadAddition {
private ConcurrentHashMap<Pair<Integer, Integer>, Future<Integer>> sharedConcurrentHashMap = new ConcurrentHashMap<>();
private Thread firstThread;
private Thread secondThread;
private Thread thirdThread;
private Thread fourthThread;
private Thread fifthThread;
private Object sharedLock = new Object();
/**
* @author Ramesh BG
*
*/
private final class ExtendedCallable implements Callable<Integer> {
/**
* @param pair
*/
Pair<Integer, Integer> pair;
public ExtendedCallable(Pair<Integer, Integer> pair) {
this.pair = pair;
}
@Override
public Integer call() throws Exception {
int result = 0;
synchronized (sharedLock) {
Thread.sleep(1000);
}
result = pair.getKey() + pair.getValue();
System.out.println("Thread: "+Thread.currentThread().getName()+" sum of pair "+pair+" is "+result);
return result;
}
}
/**
* @param args
*/
public static void main(String[] args) {
new MultiThreadAddition().createThreads();
}
public void createThreads() {
firstThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(1, 10).add();
}
});
firstThread.start();
secondThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(1, 50).add();
}
});
secondThread.start();
thirdThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(5, 15).add();
}
});
thirdThread.start();
fourthThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(10, 20).add();
}
});
fourthThread.start();
fifthThread = new Thread(new Runnable() {
@Override
public void run() {
new Addition(15, 20).add();
}
});
fifthThread.start();
}
private class Addition {
private int lowerRange;
private int upperRange;
public Addition(int lowerRange, int upperRange) {
this.lowerRange = lowerRange;
this.upperRange = upperRange;
}
public int add() {
int result = 0;
int firstNumber = 0;
int secondNumber = 0;
for (int i = this.lowerRange; i <= this.upperRange; i = i + 2) {
if ((i & 1) == 1) {
firstNumber = i;
/*
* if upperRange is oddNumber
*/
if (i + 1 <= this.upperRange) {
secondNumber = i + 1;
}
} else {
result = result + i;
firstNumber = i + 1;
secondNumber = i + 2;
i = i + 1;
}
Pair<Integer, Integer> pair = new Pair<>(firstNumber,
secondNumber);
Future<Integer> future = sharedConcurrentHashMap.get(pair);
if (future == null) {
FutureTask<Integer> futureTask = new FutureTask<Integer>(
new ExtendedCallable(pair));
future = futureTask;
sharedConcurrentHashMap.putIfAbsent(pair, futureTask);
futureTask.run();
} else {
try {
System.out.println("Thread: "+Thread.currentThread().getName()+" uses CACHED VALUE for pair "+pair+" result is "+future.get());
} catch (Exception e) {
e.printStackTrace();
}
}
try {
Integer integer = future.get();
result = result + integer;
} catch (Exception e) {
e.printStackTrace();
}
/*
* reset number, do not want to use same numbers in next
* iteration.
*/
firstNumber = 0;
secondNumber = 0;
}
System.out.println("THREAD: " + Thread.currentThread().getName()
+ " SUM FROM " + this.lowerRange + " TO " + this.upperRange
+ " IS " + result);
return result;
}
}
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadingPoolingVMWareQuestion {
ExecutorService exe = Executors.newFixedThreadPool(5);
List<Callable<Integer>> callableList = new ArrayList<Callable<Integer>>();
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 0; i < 10; i++)
resultOfSum += i;
System.out.println("Finding the result of 1 to 10 : "
+ resultOfSum);
return resultOfSum;
}
});
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 5; i < 50; i++)
resultOfSum += i;
System.out.println("Finding the result of 1 to 50 :"
+ resultOfSum);
return resultOfSum;
}
});
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 5; i < 15; i++)
resultOfSum += i;
System.out.println("Finding the result of 5 to 15 :"
+ resultOfSum);
return resultOfSum;
}
});
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 10; i < 20; i++)
resultOfSum += i;
System.out.println("Finding the result of 10 to 20 : "
+ resultOfSum);
return resultOfSum;
}
});
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 15; i < 20; i++)
resultOfSum += i;
System.out.println("Finding the result of 15 to 20 : "
+ resultOfSum);
return resultOfSum;
}
});
List<Future<Integer>> result = exe.invokeAll(callableList);
for (Future<Integer> ft : result) {
System.out.println(ft.get());
Thread.sleep(1000);
}
}
package com.src.nirakar.thread.programming;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadingPooling{
public static void main(String[] args) throws InterruptedException,
ExecutionException {
ExecutorService exe = Executors.newFixedThreadPool(5);
List<Callable<Integer>> callableList = new ArrayList<Callable<Integer>>();
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 0; i < 10; i++)
resultOfSum += i;
System.out.println("Finding the result of 1 to 10 : "
+ resultOfSum);
return resultOfSum;
}
});
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 5; i < 50; i++)
resultOfSum += i;
System.out.println("Finding the result of 1 to 50 :"
+ resultOfSum);
return resultOfSum;
}
});
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 5; i < 15; i++)
resultOfSum += i;
System.out.println("Finding the result of 5 to 15 :"
+ resultOfSum);
return resultOfSum;
}
});
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 10; i < 20; i++)
resultOfSum += i;
System.out.println("Finding the result of 10 to 20 : "
+ resultOfSum);
return resultOfSum;
}
});
callableList.add(new Callable<Integer>() {
public Integer call() throws Exception {
int resultOfSum = 0;
for (int i = 15; i < 20; i++)
resultOfSum += i;
System.out.println("Finding the result of 15 to 20 : "
+ resultOfSum);
return resultOfSum;
}
});
List<Future<Integer>> result = exe.invokeAll(callableList);
// System.out.println(result.get(0).get() + " " + result.get(1).get()
// );
for (Future<Integer> ft : result) {
System.out.println(ft.get());
Thread.sleep(1000);
}
}
}
Use CountDownlatch.
public class ThreadEx {
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
CountDownLatch latch3 = new CountDownLatch(1);
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ThreadEx ex = new ThreadEx();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
ex.latch1.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ex.method1();
}
});
t.start();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
ex.latch2.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ex.method2();
}
});
t1.start();
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
ex.latch3.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ex.method3();
}
});
t3.start();
ex.latch1.countDown();
Thread.sleep(1000);
ex.latch2.countDown();
Thread.sleep(1000);
ex.latch3.countDown();
}
public void method1() {
System.out.println("1");
}
public void method2() {
System.out.println("2");
}
public void method3() {
System.out.println("3");
}
}
public class ThreadEx {
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
CountDownLatch latch3 = new CountDownLatch(1);
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ThreadEx ex = new ThreadEx();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
ex.latch1.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ex.method1();
}
});
t.start();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
ex.latch2.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ex.method2();
}
});
t1.start();
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
ex.latch3.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ex.method3();
}
});
t3.start();
ex.latch1.countDown();
Thread.sleep(1000);
ex.latch2.countDown();
Thread.sleep(1000);
ex.latch3.countDown();
}
public void method1() {
System.out.println("1");
}
public void method2() {
System.out.println("2");
}
public void method3() {
System.out.println("3");
}
}
import java.io.*;
class Mythread extends Thread
{
public int i;
public int sum =0;
public int j =0;
public int sum1 =0;
public int k;
public int sum2 =0;
public int p;
public int sum3 =0;
public int q;
public int sum4=0;
public void run()
{
task1();
try
{
Thread.sleep(150);
}
catch(InterruptedException ie){ }
task2();
try
{
Thread.sleep(200);
}
catch(InterruptedException ie){ }
task3();
try
{
Thread.sleep(250);
}
catch(InterruptedException ie){ }
task4();
try
{
Thread.sleep(300);
}
catch(InterruptedException ie){ }
task5();
}
void task1()
{
for(i =0;i<10;i++)
{
System.out.println(i);
sum = sum+i;
}
System.out.print("\n sum is "+sum);
}
void task2()
{
for(j =1;j<50;j++)
{
System.out.print("\n"+j);
sum1 = sum1+j;
}
System.out.print("\n sum is "+sum1);
}
void task3()
{
for(k =5;k<15;k++)
{
System.out.print("\n"+k);
sum2 = sum2+k;
}
System.out.print("\n sum is "+sum2);
}
void task4()
{
for(p =10;p<20;p++)
{
System.out.print("\n"+p);
sum3 = sum3+p;
}
System.out.print("\n sum is "+sum3);
}
void task5()
{
for(q =15;q<20;q++)
{
System.out.print("\n"+q);
sum4 = sum4+q;
}
System.out.print("\n sum is "+sum4);
}
}
class My1
{
public static void main(String s[ ])throws IOException
{
Mythread m = new Mythread();
Thread t = new Thread(m);
t.start();
}
}
Maybe you should use some synchronization primitives from java.util.concurrent for example CyclicBarrier? Actually i can't get the purpose of solving this problem well.
- glebstepanov1992 August 07, 2013