13 New Java Developer Interview Question Series-6 (Microservices and Java Coding)

These are actual interview questions asked in recent times in Java Developer interviews. Please go through it to clear your technical round. Have added coding questions as well.

Ajay Rathod
Javarevisited
12 min readMay 10, 2022

--

(A bit of context: I’ve conducted numerous interviews for software engineering positions in most of the MNCs. Additionally, there have been instances where I faced challenges during coding interviews due to lack of preparation.)

Are you preparing for a job interview as a Java developer?

Find my book Guide To Clear Java Developer Interview here Gumroad (PDF Format) and Amazon (Kindle eBook).

Guide To Clear Spring-Boot Microservice Interview here Gumroad (PDF Format) and Amazon (Kindle eBook).

Download the sample copy here: Guide To Clear Java Developer Interview[Free Sample Copy]

Guide To Clear Spring-Boot Microservice Interview[Free Sample Copy]

Security in Microservices

How is rest API secured?

There are several ways to secure a REST API:

Use HTTPS: This ensures that all data transferred between the client and the server is encrypted.

Use OAuth: OAuth is an authorization framework that allows a user to grant a third-party application access to their resources without sharing their passwords.

Use JSON Web Tokens (JWT): A JWT is a JSON object that is used to securely transmit information between parties. The information can be verified and trusted, because it is digitally signed.

Use API keys: An API key is a unique string that is used to authenticate API requests. The key is usually passed in the HTTP header of an API request.

Use basic authentication: In this method, the client sends an HTTP request with a username and password for authentication.

Use multi-factor authentication: This method combines two or more authentication methods for added security.

It is important to choose an appropriate security measure based on the sensitivity of the data being transferred and the level of trust between the client and the server.

How JWT token works internally? (you should know the flow of it, and how the token is used internally).

A JSON Web Token (JWT) is a compact, URL-safe means of representing claims that can be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.

Here’s how JWT works internally:

  1. The client sends a request to the server to authenticate a user.
  2. The server verifies the user’s credentials and generates a JWT if the user is authenticated.
  3. The server sends the JWT back to the client.
  4. The client stores the JWT and includes it in the header of subsequent requests to protected routes on the server.
  5. The server verifies the JWT and processes the request if the token is valid.

A JWT consists of three parts: a header, a payload, and a signature.

  1. The header typically consists of two parts: the type of the token, which is JWT, and the signing algorithm being used, such as HMAC SHA256 or RSA.
  2. The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.
  3. The third part of the token is the signature, which is used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn’t changed along the way.

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that. For example, if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:

HMACSHA256( base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)

The complete JWT is then composed by concatenating the encoded header, the encoded payload, and the signature, with periods (.) separating them. For example:

xxxxx.yyyyy.zzzzz

How does Transaction work in Spring boot microservice, How to achieve that? (basically, microservices are mostly stateless and they don’t maintain the state that is required for transactions.

In Spring Boot, a transaction is a unit of work that is executed against a database. Transactions in Spring Boot are managed by the Spring Framework’s transaction management infrastructure, which is based on the Java Transaction API (JTA).

Here’s how transactions work in Spring Boot:

  1. A client initiates a transaction by calling a method on a transactional service bean.
  2. The transactional service bean’s method executes one or more database operations using a DAO (data access object).
  3. If the database operations are successful and no exceptions are thrown, the transaction is committed and the changes are persisted in the database.
  4. If an exception is thrown during the execution of the database operations, the transaction is rolled back and the changes are not persisted in the database.

To use transactions in your Spring Boot application, you will need to:

  1. Enable transaction management in your Spring configuration.
  2. Annotate your transactional service beans and methods with the @Transactional annotation.
  3. Configure a DataSource and a transaction manager bean in your Spring configuration.
  4. Use DAOs (data access objects) to execute database operations within the scope of a transaction.

For more information on transactions in Spring Boot, you can refer to the Spring documentation: https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction

What are Composition and Aggregation with examples?

A composition is a strong form of association that represents a “has-a” relationship between two objects. It is used to represent a part-whole or whole-part relationship, where the whole object contains the part object and has sole responsibility for its lifetime.

For example, a Car class might be composed of a Wheel class, where a car "has-a" set of wheels. If the car is destroyed, the wheels are also destroyed, because they cannot exist independently of the car.

class Wheel {
// ...
}

class Car {
private final List<Wheel> wheels = new ArrayList<>();

// ...
}

Aggregation is a weaker form of association that represents a “has-a” relationship between two objects. It is used to represent a loose coupling between two objects, where the lifetime of the contained object is not directly tied to the lifecycle of the containing object. For example, a Department class might be aggregated by a Employee class, where an employee "has-a" a department. If the employee leaves the company, the department still exists and can have other employees.

class Department {
// ...
}

class Employee {
private Department department;

// ...
}

Both composition and aggregation can be represented using UML class diagrams, where the association is shown as a line connecting the two classes, and the multiplicity is shown using an arrowhead on the end of the line. In the case of composition, the arrowhead is filled in, indicating that the contained object cannot exist independently of the containing object. In the case of aggregation, the arrowhead is open, indicating that the contained object can exist independently of the containing object.

What is a Concurrent Modification exception, and how to prevent that?

A ConcurrentModificationException is a runtime exception that occurs when an application concurrently modifies an object in a way that violates the object’s concurrent modification rules.

This exception can occur when multiple threads are attempting to modify an object concurrently, and the object is not designed to be modified concurrently. It can also occur when a single thread is iterating over a collection and modifies the collection in some way, such as by adding or removing an element, while the iteration is in progress.

Here is an example of how a ConcurrentModificationException might be thrown:

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (s.equals("a")) {
list.remove(s); // This will throw a ConcurrentModificationException
}
}

To avoid ConcurrentModificationExceptions, you can:

  1. Use thread-safe collections such as Vector or CopyOnWriteArrayList instead of non-thread-safe collections like ArrayList.
  2. Use synchronization to ensure that only one thread can modify the collection at a time.
  3. Use an iterator that supports the remove() method and call that method instead of modifying the collection directly.

For more information, you can refer to the Java documentation: https://docs.oracle.com/javase/8/docs/api/java/util/ConcurrentModificationException.html

Cohesion vs Coupling, Explain that?

Cohesion and coupling are two measures of the design quality of a software system.

Cohesion refers to the degree to which the elements within a single module or component work together to achieve a single, well-defined purpose. A highly cohesive system is one in which all the elements within a module are strongly related and work together towards a common goal. High cohesion is generally seen as a desirable characteristic of a software system, as it makes the system easier to understand and maintain.

Coupling, on the other hand, refers to the degree to which one module or component depends

Do you know Distributed tracing? what is the use of it?

Distributed tracing is a technique used to track the progress of a request as it travels through a distributed system. It allows you to see how different components of the system interact with each other and can help you identify bottlenecks and other issues that may be affecting the performance of your application.

In Spring Boot, you can use the Spring Cloud Sleuth library to add distributed tracing to your application. Sleuth integrates with popular tracing systems such as Zipkin, Jaeger, and Elastic APM to collect and display trace data.

To use Sleuth in your Spring Boot application, you will need to:

  1. Add the Spring Cloud Sleuth starter dependency to your project.
  2. Configure your tracing system of choice (e.g. Zipkin, Jaeger, etc.).
  3. Annotate your service beans with the @Trace annotation to enable tracing for individual methods.

Sleuth will automatically add trace information to your application logs, which can then be collected and displayed by your tracing system. You can also use the Sleuth API to manually add trace information to your application code.

For more information on using Sleuth for distributed tracing in Spring Boot, you can refer to the Spring Cloud Sleuth documentation: https://spring.io/projects/spring-cloud-sleuth

Do you follow any standards to build a rest service?

There are several standards that you should follow when building a RESTful service:

  1. Use HTTP methods (e.g. GET, POST, PUT, DELETE) appropriately:
  • GET should be used to retrieve data.
  • POST should be used to create new data.
  • PUT should be used to update existing data.
  • DELETE should be used to delete data.

Use HTTP status codes correctly:

  • 2xx status codes (e.g. 200, 201) should be used to indicate success.
  • 4xx status codes (e.g. 400, 401) should be used to indicate an error that occurred due to the client.
  • 5xx status codes (e.g. 500, 501) should be used to indicate an error that occurred on the server.

2. Use a consistent and logical URL structure.

Use appropriate HTTP headers (e.g. Content-Type, Authorization).

  1. Allow for flexible content negotiation (e.g. support different formats such as JSON and XML).
  2. Follow the principles of REST (e.g. use hypermedia, cache resources, and design for visibility and reliability).

It’s also a good idea to design your RESTful service in a way that is easy for developers to use and understand and follows common conventions for building APIs.

Do you know the 12-factor methodology to build a microservice?

The 12-factor methodology is a set of best practices for building software-as-a-service (SaaS) applications that are:

  1. Build for scale from the start
  2. Use the declarative format for setup and deploy
  3. Strictly separate build and run stages
  4. Export services via port binding
  5. Use a dependency injection
  6. Store config in the environment
  7. Treat logs as event streams
  8. Run as a single process
  9. Disposability
  10. Maximize robustness with fast startup and graceful shutdown
  11. Keep development, staging, and production as similar as possible
  12. Treat backing services as attached resources

The goal of the 12-factor methodology is to provide a set of guidelines for building software that is easy to scale, maintain, and deploy. It is particularly well-suited for building microservices, which are modular, independently deployable units of software that work together to form a larger application.

What is a pod in Kubernetes?

In Kubernetes, a pod is the basic unit of deployment. It is the smallest deployable unit in the Kubernetes object model.

A pod consists of one or more containers, such as Docker containers, and is used to host the containers that make up an application. The containers in a pod share the same network namespace and can communicate with each other using localhost. Pods are also co-located and co-scheduled, which means that they are scheduled to run on the same node and they share the same resources (e.g. CPU, memory).

Pods are intended to be ephemeral, meaning that they are expected to be terminated and replaced over time. This allows for easy scaling and rolling updates of applications.

Pods are created and managed by the Kubernetes control plane, which is responsible for ensuring that the desired number of replicas of a pod are running at any given time.

Java Coding Questions asked in Interview

Write a Program to print only numbers from alphanumeric char array using stream API in java-8.

char[] alphanumericArray = {'a', '1', 'b', '2', 'c', '3', 'd', '4', 'e', '5'};

Arrays.stream(alphanumericArray)
.filter(Character::isDigit)
.forEach(System.out::print);
Arrays.stream(alphanumericArray)
.mapToInt(Character::getNumericValue)
.filter(i -> i != -1)
.forEach(System.out::print);

Write a program to convert string to integer in java without any API?

public class StringToInt {
public static void main(String[] args) {
String str = "12345";

int result = 0;
for (int i = 0; i < str.length(); i++) {
result = result * 10 + str.charAt(i) - '0';
}

System.out.println(result);
}
}

This code will print the integer 12345 to the console.

The algorithm works by iterating through each character in the string, starting from the leftmost character. For each character, it multiplies the current result by 10 and adds the numeric value of the character. The numeric value of a character is obtained by subtracting the ASCII value of the character ‘0’ from the ASCII value of the character. This is equivalent to calling the Character.getNumericValue() method, which returns the integer value of a digit character.

For example, if the string is “12345”, the first iteration will calculate result = 0 * 10 + 1, the second iteration will calculate result = 1 * 10 + 2, and so on. After all iterations are complete, the final value of result will be 12345.

Write a program to find the first occurrence of a character in a string in java.

public class FindFirstOccurrence {
public static void main(String[] args) {
String str = "Hello, world!";
char c = 'l';

int index = -1;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == c) {
index = i;
break;
}
}

if (index != -1) {
System.out.println("Character '" + c + "' found at index " + index);
} else {
System.out.println("Character '" + c + "' not found in string");
}
}
}

This code will find the first occurrence of the character ‘l’ in the string “Hello, world!” and print the message “Character ‘l’ found at index 2” to the console.

The algorithm works by iterating through each character in the string and checking if it is equal to the target character. If it is, the index is stored and the loop is terminated. If the character is not found, the index is set to -1. The final value of the index is then used to determine whether the character was found in the string.

int index = str.indexOf(c);
if (index != -1) {
System.out.println("Character '" + c + "' found at index " + index);
} else {
System.out.println("Character '" + c + "' not found in string");
}

Looking for more interview questions and answers? Here are some recommended books I have used for my preparation.

You can get your copy here — Grokking the Spring Boot Interview:

Grokking the Spring Boot Interview [Free Sample Copy]: click here

You can get your copy here: Grokking the Java Interview

Grokking the Java Interview [Free Sample Copy]: click here

Looking for more advanced topics

1. String

2. Abstract class and Interface

3. Inheritance

4. ClassLoaders

5. Enum

6. ArrayList

7. HashMap

8. ConcurrentHashMap

9. Date, Time, and Calendar

10. Equals and HashCode

11. NIO and Socket Programming

12. Web Services

13. Error, Exception, and Troubleshooting

14. Tricky Questions

15. Technical Core Java Questions

I will highly recommend the below book for advanced topics.

Get this book here: Grokking the Java interview volume-2

Thanks for reading

  • 👏 Please clap for the story and follow me 👉
  • 📰 Read more content on my Medium (21 stories on Java Developer interview)

Find my books here:

--

--

Ajay Rathod
Javarevisited

Java Programmer | AWS Certified | Writer | Find My Books on Java Interview here - https://rathodajay10.gumroad.com | YouTube - https://www.youtube.com/@ajtheory