Java coding interview questions and answers



These Java coding questions and answers are extracted from the book " Core Java Career Essentials. Good interviewers are more interested in your ability to code rather than knowing the flavor of the month framework.


Q. Can you write an algorithm to swap two variables?
A.

package algorithms;

public class Swap {

public static void main(String[ ] args) {
int x = 5;
int y = 6;

//store x in a temp variable
int temp = x;
x = y;
y = temp;

System.out.println("x=" + x + ",y=" + y);
}
}


Q. Can you write  code to bubble sort { 30, 12, 18, 0, -5, 72, 424 }?
A.

package algorithms;
import java.util.Arrays;

public class BubbleSort {

public static void main(String[ ] args) {
Integer[ ] values = { 30, 12, 18, 0, -5, 72, 424 };
int size = values.length;
System.out.println("Before:" + Arrays.deepToString(values));

for (int pass = 0; pass < size - 1; pass++) {
for (int i = 0; i < size - pass - 1; i++) {
// swap if i > i+1
if (values[i] > values[i + 1])
swap(values, i, i + 1);
}
}

System.out.println("After:" + Arrays.deepToString(values));
}

private static void swap(Integer[ ] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}


Q. Is there a more efficient sorting algorithm?
A. Although bubble-sort is one of the simplest sorting algorithms, its also one of the slowest. It has the O(n^2) time complexity. Faster algorithms include quick-sort and heap-sort. The Arrays.sort( ) method uses the quick-sort algorithm, which on average has O(n * log n) but can go up to O(n^2) in a worst case scenario, and this happens especially with already sorted sequences.

Q. Write a program that will return whichever value is nearest to the value of 100 from two given int numbers?
A. You can firstly write the pseudo code as follows:

  • Compute the difference to 100.
  • Find out the absolute difference as negative numbers are valid.
  • Compare the differences to find out the nearest number to 100.
  • Write test cases for +ve, -ve, equal to, > than and < than values.
package chapter2.com;



public class CloseTo100 {



public static int calculate(int input1, int input2) {

//compute the difference. Negative values are allowed as well

int iput1Diff = Math.abs(100 - input1);

int iput2Diff = Math.abs(100 - input2);



//compare the difference

if (iput1Diff < iput2Diff) return input1;
else if (iput2Diff < iput1Diff) return input2;
else return input1; //if tie, just return one
}

public static void main(String[ ] args) {
//+ve numbers
System.out.println("+ve numbers=" + calculate(50,90));

//-ve numbers
System.out.println("-ve numbers=" + calculate(-50,-90));

//equal numbers
System.out.println("equal numbers=" + calculate(50,50));

//greater than 100
System.out.println(">100 numbers=" + calculate(85,105));

System.out.println("<100 numbers=" + calculate(95,110));
}
}



Output:

+ve numbers=90
-ve numbers=-50
equal numbers=50
>100 numbers=105
<100 numbers=95


Q. Can you write a method that reverses a given String?
A.
public class ReverseString {



public static void main(String[ ] args) {

System.out.println(reverse("big brown fox"));

System.out.println(reverse(""));

}



public static String reverse(String input) {

if(input == null || input.length( ) == 0){

return input;

}



return new StringBuilder(input).reverse( ).toString( );

}

}


It is always a best practice to reuse the API methods as shown above with the StringBuilder(input).reverse( ) method as it is fast, efficient (uses bitwise operations) and knows how to handle Unicode surrogate pairs, which most other solutions ignore. The above code handles null and empty strings, and a StringBuilder is used as opposed to a thread-safe StringBuffer, as the StringBuilder is locally defined, and local variables are implicitly thread-safe.

Some interviewers might probe you to write other lesser elegant code using either recursion or iterative swapping. Some developers find it very difficult to handle recursion, especially to work out the termination condition. All recursive methods need to have a condition to terminate the recursion.


public class ReverseString2 {

public String reverse(String str) {
// exit or termination condition
if ((null == str) || (str.length( ) <= 1)) {
return str;
}

// put the first character (i.e. charAt(0)) to the end. String indices are 0 based.
// and recurse with 2nd character (i.e. substring(1)) onwards
return reverse(str.substring(1)) + str.charAt(0);
}
}

There are other solutions like
public class ReverseString3 {

public String reverse(String str) {
// validate
if ((null == str) || (str.length( ) <= 1)) {
return str;
}

char[ ] chars = str.toCharArray( );
int rhsIdx = chars.length - 1;

//iteratively swap until exit condition lhsIdx < rhsIdx is reached
for (int lhsIdx = 0; lhsIdx < rhsIdx; lhsIdx++) {
char temp = chars[lhsIdx];
chars[lhsIdx] = chars[rhsIdx];
chars[rhsIdx--] = temp;
}

return new String(chars);
}
}



Or
 
public class ReverseString4 {

public String reverse(String str) {
// validate
if ((null == str) || (str.length( ) <= 1)) {
return str;
}


char[ ] chars = str.toCharArray( );
int length = chars.length;
int last = length - 1;

//iteratively swap until reached the middle
for (int i = 0; i < length/2; i++) {
char temp = chars[i];
chars[i] = chars[last - i];
chars[last - i] = temp;
}

return new String(chars);
}


public static void main(String[] args) {
String result = new ReverseString4().reverse("Madam, Im Adam");
System.out.println(result);
}
}

Relevant must get it right coding questions and answers



Read More..

Java ExecutorService for multi threading coding question and tutorial

Q. Can you code in Java for the following scenario?

Write a multi-threaded SumEngine, which takes  SumRequest with 2 operands (or input numbers to add) as shown below:

package com.mycompany.metrics;

import java.util.UUID;

public class SumRequest {

private String id = UUID.randomUUID().toString();
private int operand1;
private int operand2;

protected int getOperand1() {
return operand1;
}
protected void setOperand1(int operand1) {
this.operand1 = operand1;
}
protected int getOperand2() {
return operand2;
}
protected void setOperand2(int operand2) {
this.operand2 = operand2;
}
protected String getId() {
return id;
}

@Override
public String toString() {
return "SumRequest [id=" + id + ", operand1=" + operand1 + ", operand2=" + operand2 + "]";
}
}

and returns a  SumResponse with a result.

package com.mycompany.metrics;

public class SumResponse {

private String requestId;
private int result;

protected String getRequestId() {
return requestId;
}
protected void setRequestId(String requestId) {
this.requestId = requestId;
}
protected int getResult() {
return result;
}
protected void setResult(int result) {
this.result = result;
}

@Override
public String toString() {
return "SumResponse [requestId=" + requestId + ", result=" + result + "]";
}
}

A. Processing a request and returning a response is a very common programming task. Here is a basic sample code to get started.This interface can take any type of object as request and response.

package com.mycompany.metrics;

/**
* R -- Generic request type, S -- Generic response type
*/
public interface SumProcessor<R,S> {

abstract S sum(R request);
}

Step 1: Define the interface that performs the sum operation. Take note that generics is used .

package com.mycompany.metrics;

/**
* R -- Generic request type, S -- Generic response type
*/
public interface SumProcessor<R,S> {

abstract S sum(R request);
}

Step 2: Define the implementation for the above interface. Takes SumRequest and returns SumResponse. 

package com.mycompany.metrics;

public class SumProcessorImpl<R,S> implements SumProcessor<SumRequest, SumResponse> {

@Override
public SumResponse sum(SumRequest request) {
System.out.println(Thread.currentThread().getName() + " processing request .... " + request);
SumResponse resp= new SumResponse();
resp.setRequestId(request.getId());
resp.setResult(request.getOperand1() + request.getOperand2());
return resp;
}
}

Step 3: Write the multi-threaded  SumEngine. The entry point is the public method execute(SumRequest... request ) that takes 1 or more SumRequest as input via varargs. ExecutorService is the thread pool and closure of Callable interface is the executable task that can be submitted to the pool to be executed by the available thread.


package com.mycompany.metrics;

import java.util.LinkedList;
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;
import java.util.concurrent.atomic.AtomicInteger;

public class SumEngine {

private final AtomicInteger requestsCount = new AtomicInteger();

ExecutorService executionService = null;

//executes requests to sum
public void execute(SumRequest... request) {
executionService = Executors.newFixedThreadPool(5); //create a thread pool
List<Callable<SumResponse>> tasks = createExecuteTasks(request);
List<Future<SumResponse>> results = execute(tasks);
for (Future<SumResponse> result : results) {

try {
System.out.println(Thread.currentThread().getName() + ": Response = " + result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}

//initiates an orderly shutdown of thread pool
executionService.shutdown();
}

//create tasks
private List<Callable<SumResponse>> createExecuteTasks(SumRequest[] requests) {
List<Callable<SumResponse>> tasks = new LinkedList<Callable<SumResponse>>();
executingRequests(requests.length);
for (SumRequest req : requests) {
Callable<SumResponse> task = createTask(req);
tasks.add(task);
}

return tasks;
}

//increment the requests counter
private void executingRequests(int count) {
requestsCount.addAndGet(count);
}

//creates callable (i.e executable or runnable tasks)
private Callable<SumResponse> createTask(final SumRequest request) {
// anonymous implementation of Callable.
// Pre Java 8s way of creating closures
Callable<SumResponse> task = new Callable<SumResponse>() {

@Override
public SumResponse call() throws Exception {
System.out.println(Thread.currentThread().getName() + ": Request = " + request);
SumProcessor<SumRequest, SumResponse> processor = new SumProcessorImpl<>();
SumResponse result = processor.sum(request);
return result;
}

};

return task;
}

//executes the tasks
private <T> List<Future<T>> execute(List<Callable<T>> tasks) {

List<Future<T>> result = null;
try {
//invokes the sum(sumRequest) method by executing the closure call() inside createTask
result = executionService.invokeAll(tasks);
} catch (InterruptedException e) {
e.printStackTrace();
}

return result;

}

public int getRequestsCount(){
return requestsCount.get();
}
}

Step 4: Write the SumEngineTest to run the engine with the main method. Loops through numbers 1 to 5 and adds each consecutive numbers like 1+2=3, 2+3=5, 3+4=7, 4+5=9, and 5+6 = 11.

package com.mycompany.metrics;

import java.util.ArrayList;
import java.util.List;

public class SumEngineTest {

public static void main(String[] args) throws Exception {

SumEngine se = new SumEngine();

List<SumRequest> list = new ArrayList<>();

// sums 1+2, 2+3, 3+4, etc
for (int i = 1; i <= 5; i++) {
SumRequest req = new SumRequest();
req.setOperand1(i);
req.setOperand2(i + 1);
list.add(req);
}

SumRequest[] req = new SumRequest[list.size()];
se.execute((SumRequest[]) list.toArray(req));

}
}

The output is:

pool-1-thread-2: Request = SumRequest [id=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, operand1=2, operand2=3]
pool-1-thread-4: Request = SumRequest [id=36d95b35-09f0-4e93-99e4-715ea7cb33c9, operand1=4, operand2=5]
pool-1-thread-3: Request = SumRequest [id=31ccd137-349a-4b7a-93b1-e51f62c11ba9, operand1=3, operand2=4]
pool-1-thread-1: Request = SumRequest [id=4bfa782a-c695-4de6-9593-cbfd357c3535, operand1=1, operand2=2]
pool-1-thread-5: Request = SumRequest [id=c653f469-6a6f-45b6-99f2-ed58620fd144, operand1=5, operand2=6]
pool-1-thread-4 processing request .... SumRequest [id=36d95b35-09f0-4e93-99e4-715ea7cb33c9, operand1=4, operand2=5]
pool-1-thread-2 processing request .... SumRequest [id=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, operand1=2, operand2=3]
pool-1-thread-1 processing request .... SumRequest [id=4bfa782a-c695-4de6-9593-cbfd357c3535, operand1=1, operand2=2]
pool-1-thread-3 processing request .... SumRequest [id=31ccd137-349a-4b7a-93b1-e51f62c11ba9, operand1=3, operand2=4]
pool-1-thread-5 processing request .... SumRequest [id=c653f469-6a6f-45b6-99f2-ed58620fd144, operand1=5, operand2=6]
main: Response = SumResponse [requestId=4bfa782a-c695-4de6-9593-cbfd357c3535, result=3]
main: Response = SumResponse [requestId=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, result=5]
main: Response = SumResponse [requestId=31ccd137-349a-4b7a-93b1-e51f62c11ba9, result=7]
main: Response = SumResponse [requestId=36d95b35-09f0-4e93-99e4-715ea7cb33c9, result=9]
main: Response = SumResponse [requestId=c653f469-6a6f-45b6-99f2-ed58620fd144, result=11]

Read More..

Blog Archive

Powered by Blogger.