“Hello folks, I am jotting down the full tech interview round for a Java developer position at Cisco. All these Q&A are actual questions and will immensely help you if you are looking to enter Cisco Systems. Let’s get started.”
Are you preparing for a job interview as a Java developer?
Find my book Guide To Clear Java Developer Interview here Gumroad (PDFFormat) and Amazon (Kindle eBook).
Guide To Clear Spring-Boot Microservice Interview here Gumroad (PDFFormat) 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]
In this interview transcript, first round was with two senior engineer, they were evaluating me for Java,Spring-boot,microservice,Database,hibernate,kafka so on and so forth.
Pro Tip:
“In one hour of interview, only important questions are always asked, and they tend to get repeated all the time. Preparing them is the key to success.”
Spring Framework and Spring Boot
What is Response Entity in Spring-Boot?
In Spring Boot, a ResponseEntity is a class used to represent the entire HTTP response sent back to a client. It goes beyond just the data itself and encapsulates three key aspects:
Status Code: This indicates the outcome of the request, like success (200 OK), not found (404), or internal server error (500).
Headers: These are optional key-value pairs that provide additional information about the response, such as content type, cache control, or authentication details.
Body: This is the actual data being sent back to the client. It can be anything from JSON or XML to plain text, depending on your API design.
By using ResponseEntity, you gain fine-grained control over how Spring Boot constructs the response. You can set the appropriate status code, add custom headers, and include the response data in the body. This allows you to build more informative and flexible APIs.
@RestController
public class ProductController {
@GetMapping("/products/{id}")
public ResponseEntity<Product> getProduct(@PathVariable Long id) {
// Simulate product retrieval logic
Product product = getProductFromDatabase(id);
// Check if product exists
if (product == null) {
return ResponseEntity.notFound().build(); // 404 Not Found
}
// Return product with OK status (200)
return ResponseEntity.ok(product);
}
// Simulate product retrieval from database (replace with your actual logic)
private Product getProductFromDatabase(Long id) {
// ... (implementation details)
return new Product(id, "Sample Product", 10.0);
}
}
How to configure multiple databases in spring-boot application?
This is very interesting question and gets repeated all the time in an interview.
Spring Boot offers a convenient way to configure multiple databases in your application. Here’s a breakdown of the steps involved:
- Define Data Source Properties:
Spring Boot uses properties to configure data sources. You can define them in your application.yml or application.properties file.
Each data source needs its own set of properties, prefixed with a unique identifier. Common properties include:
url: Database connection URL.
username: Database username.
password: Database password.
driverClassName: JDBC driver class name for the database.
Here’s an example configuration for two databases named users and orders:
spring: datasource: users: url: jdbc:mysql://localhost:3306/users username: user password: password driverClassName: com.mysql.cj.jdbc.Driver orders: url: jdbc:postgresql://localhost:5432/orders username: orders_user password: orders_password driverClassName: org.postgresql.Driver
- Create DataSource Beans: Spring Boot provides annotations and utilities to create DataSource beans. You can use @ConfigurationProperties to map the data source properties defined earlier to a bean. Here’s an example configuration class with DataSourceBuilder to create beans for each data source: `@Configuration public class DataSourceConfig {
@bean
@ConfigurationProperties(prefix = "spring.datasource.users")
public DataSource usersDataSource() {
return DataSourceBuilder.create().build();
}
@bean
@ConfigurationProperties(prefix = "spring.datasource.orders")
public DataSource ordersDataSource() {
return DataSourceBuilder.create().build();
}
}`
Configure Entity Manager and Transaction Manager (Optional):
If you’re using Spring Data JPA, you’ll need to configure separate Entity Managers and Transaction Managers for each data source.
These can be created similarly to DataSource beans, specifying the entities associated with each data source.
- Injecting the Correct DataSource: By default, Spring Boot auto-configures a single DataSource. To use specific data sources: You can inject @Qualifier("usersDataSource") or @Qualifier("ordersDataSource") for specific repositories or services. JPA repositories can also use @Entity annotation with a entityManagerFactoryRef attribute to specify the EntityManager. Remember to adapt the configuration details (database type, connection details) to your specific databases. How to declare Global Exceptions in Springboot application?[imp question] Spring Boot offers two main approaches to declare Global Exceptions:
- Using @ControllerAdvice: This is the recommended approach for centralized exception handling. Here’s how it works: Create a class annotated with @ControllerAdvice. Define methods annotated with @ExceptionHandler to handle specific exceptions. These methods can: Return a custom error response object containing details about the exception. Set a specific HTTP status code using ResponseEntity. Log the exception for further analysis.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse("Resource not found");
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse);
}
// Define methods for other exceptions you want to handle globally
}
What is Spring Bean LifeCycle?
What is IOC Containers?
An IoC Container is a software framework component that manages the objects (beans) in your application. It takes over the responsibility of creating, configuring, and assembling these objects and their dependencies.
How Does it Work?
Object Creation: Traditionally, you’d manually create objects in your code. With an IoC container, you define the objects (beans) you need in your application using configuration files (XML or annotations) or Java classes. The container then takes care of instantiating these objects.
Dependency Injection: Objects often rely on other objects to function properly (dependencies). Instead of manually creating and passing these dependencies around, you declare them in your object definitions. The IoC container injects (provides) the required dependencies to the objects it creates. This creates a loose coupling between objects, making your code more modular and easier to test.
Object Lifecycle Management: The IoC container also manages the lifecycle of objects, including initialization and destruction. This frees you from writing boilerplate code for these tasks.
What is Dependency Injections?
In software development, dependency injection (DI) is a technique for providing an object with the objects (dependencies) it needs to function. Here’s a breakdown of the key concepts:
What are Dependencies?
Dependencies are other objects that a class or function relies on to perform its work effectively.
Examples:
A car depends on an engine, wheels, and other parts to function.
A database access class depends on a database connection object to interact with the database.
What is Application Context & its's use?
In Spring Boot applications, the ApplicationContext is a central interface that plays a critical role in managing the objects (beans) used throughout your application. It’s essentially a container that provides the following functionalities:
- Bean Management: The core responsibility of the ApplicationContext is to manage the objects (beans) that make up your application. These beans are typically defined using annotations or XML configuration files. The ApplicationContext takes care of creating, configuring, and assembling these beans according to the specified configuration.
- Dependency Injection: Beans often rely on other beans to function properly. These are called dependencies. The ApplicationContext facilitates dependency injection by automatically providing the required dependencies to the beans it creates. This eliminates the need for manual dependency creation and management, leading to loosely coupled and more maintainable code.
- Resource Access: The ApplicationContext provides access to various resources your application might need, such as property files, configuration files, and message bundles. This simplifies resource retrieval and ensures consistent access throughout your code. How to Enable multiple Eureka Servers? This article deals with this question https://medium.com/become-developer/how-to-work-with-multiple-instances-of-eureka-naming-server-to-avoid-a-single-point-of-failure-d953544281d0?source=post_page-----34ed516ae32d--------------------------------
What is the difference between Spring Filter and Spring Interceptors?(This is good question to check your Spring MVC framework related concepts)
HandlerInterceptor is basically similar to a Servlet Filter, but in contrast to the latter it just allows custom pre-processing with the option of prohibiting the execution of the handler itself, and custom post-processing. Filters are more powerful, for example they allow for exchanging the request and response objects that are handed down the chain. Note that a filter gets configured in web.xml, a HandlerInterceptor in the application context.
As a basic guideline, fine-grained handler-related pre-processing tasks are candidates for HandlerInterceptor implementations, especially factored-out common handler code and authorization checks. On the other hand, a Filter is well-suited for request content and view content handling, like multipart forms and GZIP compression. This typically shows when one needs to map the filter to certain content types (e.g. images), or to all requests.
So where is the difference between Interceptor#postHandle() and Filter#doFilter()?
postHandle will be called after handler method invocation but before the view being rendered. So, you can add more model objects to the view but you can not change the HttpServletResponse since it's already committed.
doFilter is much more versatile than the postHandle. You can change the request or response and pass it to the chain or even block the request processing.
Also, in preHandle and postHandle methods, you have access to the HandlerMethod that processed the request. So, you can add pre/post-processing logic based on the handler itself. For example, you can add a logic for handler methods that have some annotations.
As the doc said, fine-grained handler-related pre-processing tasks are candidates for HandlerInterceptor implementations, especially factored-out common handler code and authorization checks. On the other hand, a Filter is well-suited for request content and view content handling, like multipart forms and GZIP compression. This typically shows when one needs to map the filter to certain content types (e.g. images), or to all requests.
Why to use @Transactional annotation what's the benefit?(In spring interview @Transactional annotation is always asked)
@Transactional is a Spring annotation that can be applied to methods or classes to indicate that the annotated code should be executed within a transaction. When Spring encounters the @Transactional annotation, it automatically creates a transaction around the annotated code and manages the transaction lifecycle.
By default, @Transactional creates a transaction with the default isolation level (usually READ_COMMITTED) and the default propagation behavior (REQUIRED). However, you can customize these settings by passing parameters to the annotation.
Here’s an example of using @Transactional in a Spring service class:
`@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public void createUser(String name, String email) {
User user = new User(name, email);
userRepository.save(user);
}
}`
In this example, the createUser() method is annotated with @Transactional, which means that the save() method of the UserRepository will be executed within a transaction.
Advantages of @Transactional:
The @Transactional annotation provides several benefits:
Simplifies transaction management: By using @Transactional, you can avoid writing boilerplate code to create and manage transactions manually. Spring takes care of transaction management for you, so you can focus on writing business logic.
Promotes consistency and integrity: Transactions ensure that multiple database operations are executed atomically, which helps to maintain data consistency and integrity.
Improves performance: Transactions can improve database performance by reducing the number of round trips between the application and the database.
Supports declarative programming: With @Transactional, you can use declarative programming to specify transaction management rules. This makes your code more concise and easier to read.
If there is Memory Leak in your application how will you find it?
Symptoms of a Memory Leak
Severe performance degradation when the application is continuously running for a long time.
OutOfMemoryError heap error in the application.
Spontaneous and strange application crashes.
The application is occasionally running out of connection objects.
What is the use of Stringtokenizer?
The string tokenizer class allows an application to break a string into tokens. The tokenization method is much simpler than the one used by the StreamTokenizer class. The StringTokenizer methods do not distinguish among identifiers, numbers, and quoted strings, nor do they recognize and skip comments.
The set of delimiters (the characters that separate tokens) may be specified either at creation time or on a per-token basis.
An instance of StringTokenizer behaves in one of two ways, depending on whether it was created with the returnDelims flag having the value true or false:
If the flag is false, delimiter characters serve to separate tokens. A token is a maximal sequence of consecutive characters that are not delimiters.
If the flag is true, delimiter characters are themselves considered to be tokens. A token is thus either one delimiter character, or a maximal sequence of consecutive characters that are not delimiters.
A StringTokenizer object internally maintains a current position within the string to be tokenized. Some operations advance this current position past the characters processed.
A token is returned by taking a substring of the string that was used to create the StringTokenizer object.
The following is one example of the use of the tokenizer. The code:
StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
What is Spring Security Context?
SecurityContext — is obtained from the SecurityContextHolder and contains the Authentication of the currently authenticated user. Authentication — Can be the input to AuthenticationManager to provide the credentials a user has provided to authenticate or the current user from the SecurityContext .
Thanks for reading folks
full article on medium - https://medium.com/@rathod-ajay/cisco-java-developer-interview-transcript-2024-java-spring-boot-hibernate-34ed516ae32d
Top comments (0)