After 1st telephonic technical round, I got the call to come to BoA office in Hyderabad for technical discussion of 2nd round.
That interviewer was good & patient enough to listen the ideas/answers. He even helped with hints when getting stuck.
Below are the coding questions asked apart from some theoretical questions, though I was not able to write the complete code except to reverse the String in simple way. But below I have mentioned one more way to reverse the String plus I have added the code for other 2 problems -
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BoA1 {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException,
IllegalAccessException {
String str = "123456789";
System.out.println("Converted to integer : " + integerAns(str));
reverseString(str);
System.out.println("Reversed the string : " + str);
BlockingQueue<String> bq = new ArrayBlockingQueue<>(20);
BlockingQueue1<String> bq1 = new BlockingQueue1<>(20, 1000, 100);
Producer prod = new Producer(bq1, 30);
Consumer consumer = new Consumer(bq1);
Thread t1 = new Thread(prod);
Thread t2 = new Thread(consumer);
t1.start();
t2.start();
}
// Question 1: Parse the string containing integers only, without using any Java API.
private static int integerAns(String str) {
int len = str.length();
int ans = 0;
for(int i = 0 ; i < len; i++) {
char ch = str.charAt(i);
int n = ch-48;
int k = len-i;
while(k > 1) {
n = n*10;
k--;
}
ans+=n;
}
return ans;
}
A bit simplified way with examples, here the assumption is that string gis having only integer & no negative sign, so number will be positive if within Integer range.
That interviewer was good & patient enough to listen the ideas/answers. He even helped with hints when getting stuck.
Below are the coding questions asked apart from some theoretical questions, though I was not able to write the complete code except to reverse the String in simple way. But below I have mentioned one more way to reverse the String plus I have added the code for other 2 problems -
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BoA1 {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException,
IllegalAccessException {
String str = "123456789";
System.out.println("Converted to integer : " + integerAns(str));
reverseString(str);
System.out.println("Reversed the string : " + str);
BlockingQueue<String> bq = new ArrayBlockingQueue<>(20);
BlockingQueue1<String> bq1 = new BlockingQueue1<>(20, 1000, 100);
Producer prod = new Producer(bq1, 30);
Consumer consumer = new Consumer(bq1);
Thread t1 = new Thread(prod);
Thread t2 = new Thread(consumer);
t1.start();
t2.start();
}
// Question 1: Parse the string containing integers only, without using any Java API.
private static int integerAns(String str) {
int len = str.length();
int ans = 0;
for(int i = 0 ; i < len; i++) {
char ch = str.charAt(i);
int n = ch-48;
int k = len-i;
while(k > 1) {
n = n*10;
k--;
}
ans+=n;
}
return ans;
}
A bit simplified way with examples, here the assumption is that string gis having only integer & no negative sign, so number will be positive if within Integer range.
StringToInteger
// Question 2: Reverse the given String. Below way can be used to reverse the String.
// It reverses the provided string, if dont want to reverse the original String then skip
// Reflection part.
private static void reverseString(String str) {
try {
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char[] chars = (char[])field.get(str);
int len = str.length();
int last = len-1;
int i = 0;
while(last > i) {
char temp = chars[last];
chars[last] = chars[i];
chars[i] = temp;
i++;
last--;
}
field.set(str, chars);
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
// Question 3: Create the custom BlockingQueue to write the Producer/Consumer scenario.
// It took me 90 mins to write the below code about the idea I had.
// One can change the producer/consumer threads wait as per the requirements.
// It is just to represent the idea & not tested properly.
class BlockingQueue1<T> implements Queue<T> {
private int defaultSize = 10;
private int size = defaultSize;
private T[] queue;
private int push = 0;
private int pull = 0;
private int prodWait = 500;
private int consWait = 500;
@SuppressWarnings("unchecked")
public BlockingQueue1() {
queue = (T[])new Object[size];
}
@SuppressWarnings("unchecked")
public BlockingQueue1(int size) {
queue = (T[])new Object[size];
this.size = size;
}
@SuppressWarnings("unchecked")
public BlockingQueue1(int size, int prodWait, int consWait) {
queue = (T[])new Object[size];
this.prodWait = prodWait;
this.consWait = consWait;
this.size = size;
}
@Override
public int size() {
return Math.abs(push-pull);
}
@Override
public boolean isEmpty() {
return push == pull;
}
@Override
public boolean contains(Object o) {
return false;
}
@Override
public Iterator<T> iterator() {
return null;
}
@Override
public T[] toArray() {
return queue;
}
@Override
public Object[] toArray(Object[] a) {
return null;
}
@Override
public boolean remove(Object o) {
return false;
}
@Override
public boolean containsAll(Collection c) {
return false;
}
@Override
public boolean addAll(Collection c) {
return false;
}
@Override
public boolean removeAll(Collection c) {
return false;
}
@Override
public boolean retainAll(Collection c) {
return false;
}
@Override
public void clear() {
}
@Override
public boolean add(T e) {
// System.out.println("Got : " + e);
synchronized(this) {
while(queue[push] != null) {
try {
System.out.println("Waiting for Queue to have space....");
wait(consWait);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
System.out.println("Got : " + e);
queue[push] = e;
push++;
if(push == size) {
push = 0;
}
notifyAll();
}
return true;
}
@Override
public boolean offer(T e) {
return add(e);
}
@Override
public T remove() {
T ans = null;
synchronized(this) {
while(queue[pull] == null)
try {
System.out.println("Waiting for Queue to have data....");
wait(prodWait);
} catch (InterruptedException e) {
e.printStackTrace();
}
ans = queue[pull];
queue[pull] = null;
System.out.println("Removed : " + ans);
pull++;
if(pull == size) {
pull = 0;
}
notifyAll();
}
return ans;
}
@Override
public T poll() {
return remove();
}
@Override
public T element() {
return null;
}
@Override
public T peek() {
return queue[pull];
}
}
class Producer implements Runnable {
private BlockingQueue1<String> bq;
private int range;
public Producer(BlockingQueue1<String> bq, int range) {
this.bq = bq;
this.range = range;
}
public void run() {
System.out.println("Producer started.....");
while(range > 0) {
bq.offer(""+range);
range--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bq.offer("End");
}
}
class Consumer implements Runnable {
private BlockingQueue1<String> bq;
public Consumer(BlockingQueue1<String> bq) {
this.bq = bq;
}
public void run() {
System.out.println("Consumer started.....");
while(true) {
String ans = bq.poll();
if(ans != null && ans.equals("End"))
System.exit(0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// It reverses the provided string, if dont want to reverse the original String then skip
// Reflection part.
private static void reverseString(String str) {
try {
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char[] chars = (char[])field.get(str);
int len = str.length();
int last = len-1;
int i = 0;
while(last > i) {
char temp = chars[last];
chars[last] = chars[i];
chars[i] = temp;
i++;
last--;
}
field.set(str, chars);
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
// Question 3: Create the custom BlockingQueue to write the Producer/Consumer scenario.
// It took me 90 mins to write the below code about the idea I had.
// One can change the producer/consumer threads wait as per the requirements.
// It is just to represent the idea & not tested properly.
class BlockingQueue1<T> implements Queue<T> {
private int defaultSize = 10;
private int size = defaultSize;
private T[] queue;
private int push = 0;
private int pull = 0;
private int prodWait = 500;
private int consWait = 500;
@SuppressWarnings("unchecked")
public BlockingQueue1() {
queue = (T[])new Object[size];
}
@SuppressWarnings("unchecked")
public BlockingQueue1(int size) {
queue = (T[])new Object[size];
this.size = size;
}
@SuppressWarnings("unchecked")
public BlockingQueue1(int size, int prodWait, int consWait) {
queue = (T[])new Object[size];
this.prodWait = prodWait;
this.consWait = consWait;
this.size = size;
}
@Override
public int size() {
return Math.abs(push-pull);
}
@Override
public boolean isEmpty() {
return push == pull;
}
@Override
public boolean contains(Object o) {
return false;
}
@Override
public Iterator<T> iterator() {
return null;
}
@Override
public T[] toArray() {
return queue;
}
@Override
public Object[] toArray(Object[] a) {
return null;
}
@Override
public boolean remove(Object o) {
return false;
}
@Override
public boolean containsAll(Collection c) {
return false;
}
@Override
public boolean addAll(Collection c) {
return false;
}
@Override
public boolean removeAll(Collection c) {
return false;
}
@Override
public boolean retainAll(Collection c) {
return false;
}
@Override
public void clear() {
}
@Override
public boolean add(T e) {
// System.out.println("Got : " + e);
synchronized(this) {
while(queue[push] != null) {
try {
System.out.println("Waiting for Queue to have space....");
wait(consWait);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
System.out.println("Got : " + e);
queue[push] = e;
push++;
if(push == size) {
push = 0;
}
notifyAll();
}
return true;
}
@Override
public boolean offer(T e) {
return add(e);
}
@Override
public T remove() {
T ans = null;
synchronized(this) {
while(queue[pull] == null)
try {
System.out.println("Waiting for Queue to have data....");
wait(prodWait);
} catch (InterruptedException e) {
e.printStackTrace();
}
ans = queue[pull];
queue[pull] = null;
System.out.println("Removed : " + ans);
pull++;
if(pull == size) {
pull = 0;
}
notifyAll();
}
return ans;
}
@Override
public T poll() {
return remove();
}
@Override
public T element() {
return null;
}
@Override
public T peek() {
return queue[pull];
}
}
class Producer implements Runnable {
private BlockingQueue1<String> bq;
private int range;
public Producer(BlockingQueue1<String> bq, int range) {
this.bq = bq;
this.range = range;
}
public void run() {
System.out.println("Producer started.....");
while(range > 0) {
bq.offer(""+range);
range--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bq.offer("End");
}
}
class Consumer implements Runnable {
private BlockingQueue1<String> bq;
public Consumer(BlockingQueue1<String> bq) {
this.bq = bq;
}
public void run() {
System.out.println("Consumer started.....");
while(true) {
String ans = bq.poll();
if(ans != null && ans.equals("End"))
System.exit(0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}