Advance Java MCQ Questions and Answers

81. What is the concept of Eager vs Lazy fetching in Hibernate/JPA?

  1. Eager loading is only for collections; lazy loading is only for single entity references
  2. Eager fetching loads the associated entities immediately when the parent is loaded; Lazy fetching delays loading until the association is actually accessed — reducing unnecessary database queries
  3. Eager fetching is always faster and should always be used for better performance
  4. Lazy loading requires a special @LazyLoad annotation on every field that uses it

Answer : B
Explanation: FetchType controls when related entities are loaded from the database. FetchType.EAGER: associated data loaded immediately with the parent in the same query (or additional query). Default for: @ManyToOne, @OneToOne. @ManyToOne(fetch=FetchType.EAGER) — fetching User also fetches their Department immediately. Risk: causes performance problems when you have multiple EAGER associations. FetchType.LAZY: associated data loaded only when you access it (first access triggers a query). Default for: @OneToMany, @ManyToMany. @OneToMany(fetch=FetchType.LAZY) — fetching Order does NOT load OrderItems until you call order.getItems(). Must still have an open Session when accessing lazy collections. LazyInitializationException: accessing a lazy collection after the Session is closed causes this exception. Solutions: Open Session in View pattern (not recommended — keeps session open for the entire request), @Transactional on service method ensures session stays open, JOIN FETCH in JPQL eagerly loads for specific queries, @EntityGraph for query-level eager loading. Best practice: keep all associations LAZY by default. Use JOIN FETCH or @EntityGraph in specific queries where you know you need the data. This gives maximum control and avoids N+1 problems and unnecessary data loading.

82. What is the difference between @OneToMany and @ManyToMany in JPA?

  1. @OneToMany is for parent-child relationships within the same Java class
  2. @OneToMany maps a one-to-many relationship (one Order has many OrderItems) stored as a foreign key in the child table; @ManyToMany maps a many-to-many relationship (many Students have many Courses) requiring a join table with foreign keys to both entities
  3. @ManyToMany can only be used with List; @OneToMany can only be used with Set
  4. Both annotations are identical — the difference is only in naming convention

Answer : B
Explanation: JPA relationship annotations map object associations to database table relationships: @OneToMany: one entity (parent) has a collection of another entity (child). Database: child table has a foreign key column pointing to parent. Example: @OneToMany(mappedBy=”order”, cascade=CascadeType.ALL, fetch=FetchType.LAZY) private List<OrderItem> items. mappedBy: specifies which field in the child owns the relationship (child has @ManyToOne). The “owning” side (where the foreign key lives) is usually the @ManyToOne side. @ManyToMany: both entities can have collections of each other. Database: requires a join table (student_course) with foreign keys to both student and course tables. Example: @ManyToMany(fetch=FetchType.LAZY) @JoinTable(name=”student_course”, joinColumns=@JoinColumn(name=”student_id”), inverseJoinColumns=@JoinColumn(name=”course_id”)) private Set<Course> courses. One side is the owner (has @JoinTable), other side has mappedBy. Cascade types: CascadeType.ALL — all operations cascade. CascadeType.PERSIST — save parent also saves children. CascadeType.REMOVE — delete parent also deletes children (use carefully with @ManyToMany). Best practices: prefer Set over List for @ManyToMany (avoids duplicate join rows). For @ManyToMany with extra attributes on the join table: create a separate entity for the join table (Student, Enrollment, Course) with two @ManyToOne relationships.

83. What is Spring Security’s authentication flow for a JWT-based REST API?

  1. JWT authentication in Spring means storing the token in a server-side session for lookup
  2. JWT authentication: client sends credentials → server validates and returns a signed JWT → client includes JWT in Authorization header of subsequent requests → Spring Security filter validates the token on each request without any server-side session state
  3. JWT tokens are only valid for a single request and must be refreshed for every API call
  4. Spring Security handles JWT automatically with no custom code when spring-security is included

Answer : B
Explanation: JWT (JSON Web Token) enables stateless authentication for REST APIs. JWT structure: Header.Payload.Signature (Base64 encoded, signed with secret or RSA key). Contains: userId, roles, expiration — verifiable without server-side storage. Spring Security JWT flow: Login endpoint (/api/auth/login): receives username/password. AuthenticationManager validates credentials against UserDetailsService. On success: generate JWT (using jjwt or java-jwt library). Return JWT to client. Client stores JWT (localStorage, memory). Subsequent requests: client includes: Authorization: Bearer <jwt-token>. Custom JwtAuthenticationFilter (extends OncePerRequestFilter): extracts token from Authorization header. Validates signature, checks expiry. Extracts user details from token. Sets Authentication in SecurityContextHolder. SecurityContextHolder.getContext().setAuthentication(authToken). Spring Security allows the request to proceed. Stateless: disable session management: http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS). Disable CSRF: http.csrf().disable() — JWT tokens are CSRF-safe (not sent automatically by browsers). Refresh tokens: short-lived access token (15 min) + long-lived refresh token (7 days). OAuth2/OpenID Connect: production apps often use Keycloak, Auth0, Okta instead of rolling custom JWT auth — Spring Security has built-in OAuth2 resource server support.

84. What is the role of @RequestBody and content negotiation in Spring REST?

  1. @RequestBody is used to send responses — it is equivalent to @ResponseBody in Spring
  2. @RequestBody deserializes the HTTP request body (JSON/XML) into a Java object; content negotiation determines the format for responses based on the Accept header — Spring’s HttpMessageConverters handle the conversion automatically
  3. @RequestBody only works with String type and cannot deserialize into complex Java objects
  4. Content negotiation requires manual format detection code in every controller method

Answer : B
Explanation: @RequestBody deserializes HTTP request body into Java objects: @PostMapping(“/users”) public ResponseEntity<User> createUser(@RequestBody User user) { … }. Spring uses Jackson to parse the incoming JSON into a User object automatically. @Valid or @Validated can be added for Bean Validation: @PostMapping(“/users”) public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request). Bean Validation annotations: @NotNull, @NotBlank, @Email, @Size(min=3, max=50), @Min(0), @Max(150) on fields. @ExceptionHandler(MethodArgumentNotValidException.class) handles validation errors globally. Content Negotiation: determines format of response based on client preferences. Accept: application/json — client wants JSON (default in most APIs). Accept: application/xml — client wants XML. Produces: @GetMapping(value=”/users”, produces={“application/json”,”application/xml”}) — server declares what it can produce. HttpMessageConverters: Jackson (for JSON), JAXB2 (for XML if on classpath). Spring Boot auto-configures both. ContentNegotiationManager: resolves which format to use based on: Accept header (most common), URL extension (/users.json vs /users.xml), Query parameter (?format=json). Best practice: for REST APIs, accept and return JSON only — simplifies things. Use @RequestBody for incoming data, ResponseEntity for outgoing data.

85. What is the purpose of the @SpringBootTest annotation in testing?

  1. @SpringBootTest is used to deploy a Spring Boot application to a test cloud environment
  2. @SpringBootTest loads the complete Spring ApplicationContext for integration testing — starting the actual application (including embedded server and all beans) so tests run against the full application stack
  3. @SpringBootTest replaces JUnit 5 and provides a completely separate testing framework
  4. @SpringBootTest only tests Spring Boot auto-configuration and ignores application code

Answer : B
Explanation: @SpringBootTest is the foundation for Spring Boot integration tests. Full context loading: @SpringBootTest loads ALL Spring beans (real application context). @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) — starts the embedded Tomcat on a random port. For testing REST controllers end-to-end. @SpringBootTest(webEnvironment = WebEnvironment.MOCK) — default. Mocked servlet environment, no real HTTP. Used with MockMvc. Testing REST APIs: MockMvc (without actual server): @AutoConfigureMockMvc — injects MockMvc. mockMvc.perform(get(“/users”)).andExpect(status().isOk()).andExpect(jsonPath(“$.name”).value(“John”)). TestRestTemplate (with real server): @Autowired TestRestTemplate restTemplate; restTemplate.getForObject(“http://localhost:”+port+”/users”, String.class). Slicing annotations (faster — only load relevant parts): @WebMvcTest — only web layer (controllers). No database, no service layer. Use @MockBean for dependencies. @DataJpaTest — only JPA layer (repositories). Uses in-memory H2 database. No web layer. @JsonTest — only Jackson serialization. @WebFluxTest — reactive web layer. Mocking: @MockBean — Spring-managed mock (Mockito under the hood). Replaces real bean in ApplicationContext. @Mock (Mockito) — used without Spring context. Best practice: unit tests with mocks (fast), integration tests with @SpringBootTest for key flows (slower).

86. What is the Java Reflection API and how is it used in frameworks?

  1. Java Reflection is a mirror-like debugging tool that reflects code back to developers for review
  2. Java Reflection API allows programs to inspect and manipulate the structure of classes, methods, fields, and annotations at runtime — used by Spring, Hibernate, JUnit, and other frameworks to implement DI, ORM, and testing without modifying application code
  3. Java Reflection is a compile-time feature that only works during the build process
  4. Reflection only works on public classes and cannot access private fields or methods

Answer : B
Explanation: Java Reflection (java.lang.reflect) enables runtime introspection and manipulation of classes. Key operations: Get Class object: MyClass.class, obj.getClass(), Class.forName(“com.example.MyClass”). Inspect: clazz.getDeclaredFields() — all fields (including private). clazz.getDeclaredMethods() — all methods. clazz.getDeclaredAnnotations() — annotations. clazz.getDeclaredConstructors(). Manipulate: field.setAccessible(true) — bypass private access. field.set(obj, value) — set field value. method.invoke(obj, args) — call method. constructor.newInstance(args) — create instance. Read annotations: method.isAnnotationPresent(MyAnnotation.class), method.getAnnotation(Transactional.class). How frameworks use reflection: Spring DI: scans for @Component classes via reflection, creates instances, injects @Autowired fields (even private). Hibernate ORM: reads @Entity, @Column, @Id annotations to map Java classes to database tables without you writing the mapping code. JUnit: finds @Test, @BeforeEach methods and calls them via reflection. Jackson: reads field names and values via reflection to serialize/deserialize JSON. Performance note: reflection is slower than direct Java calls — frameworks cache reflection results. Modern alternative: annotation processors (compile-time code generation) — Lombok uses this to avoid runtime reflection overhead.

87. What is the difference between JDK, JRE, and JVM?

  1. JDK, JRE, and JVM are three different Java programming languages for different use cases
  2. JVM (Java Virtual Machine) executes bytecode; JRE (Java Runtime Environment) = JVM + standard libraries needed to run Java programs; JDK (Java Development Kit) = JRE + development tools (compiler javac, debugger, javadoc, jar)
  3. JDK is only needed for Java 8 — modern Java versions only require JRE
  4. JVM is a physical chip installed on the computer specifically for running Java programs

Answer : B
Explanation: Understanding JVM/JRE/JDK is a fundamental Java question: JVM (Java Virtual Machine): the runtime engine that executes Java bytecode. Platform-specific implementation (JVM for Windows differs from JVM for Linux). Provides: memory management, garbage collection, JIT compilation, bytecode verification. Enables Java’s “Write Once, Run Anywhere” portability — bytecode runs on any JVM. JRE (Java Runtime Environment): JVM + the Java Class Library (standard library classes — java.lang, java.util, java.io etc.). Everything needed to RUN Java applications. End users who just run Java apps need JRE. JDK (Java Development Kit): JRE + development tools. javac — Java compiler (compiles .java to .class bytecode). java — JVM launcher. javadoc — documentation generator. jar — archive tool. jdb — debugger. jshell (Java 9+) — interactive REPL. Developers need JDK. JDK relationship: JDK ⊃ JRE ⊃ JVM (each is a superset of the next). Modern note: since Java 11, Oracle no longer distributes a separate JRE — only JDK. Distributions: Oracle JDK (commercial for production use in recent versions), OpenJDK (free, open-source — most common), Amazon Corretto, Eclipse Temurin (Adoptium), GraalVM (with native compilation). Spring Boot applications: need JDK to build, JRE/JDK to run. Docker containers typically use OpenJDK-based images.

88. What is Hibernate’s Second Level Cache and how is it configured?

  1. Second Level Cache in Hibernate refers to the L2 processor cache of the CPU
  2. Hibernate’s Second Level Cache is an optional, session-factory-scoped cache that stores entities across multiple sessions — reducing database hits for frequently accessed data — configured using providers like EHCache or Redis
  3. The second level cache stores only SQL query results and not entity objects
  4. Second Level Cache is automatically enabled in all Hibernate configurations with no setup needed

Answer : B
Explanation: Hibernate has two cache levels: First Level Cache (Session Cache): always enabled, automatic. Scoped to a Session (single transaction). Entities fetched within the same session are cached — second fetch doesn’t hit DB. session.get(User.class, 1) twice in same session → only one DB query. Cleared when session closes. Second Level Cache (SessionFactory Cache): optional, shared across all Sessions. Must be explicitly configured. Entities that are @Cacheable are stored here. Second session.get(User.class, 1) → hits second-level cache, not DB. Persists until cache expires or invalidated. Configuration: Add EHCache dependency: spring-boot-starter-cache + ehcache. application.properties: spring.jpa.properties.hibernate.cache.use_second_level_cache=true, spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory. Annotate entity: @Entity @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) public class User { … }. Cache concurrency strategies: READ_ONLY — immutable data. NONSTRICT_READ_WRITE — rarely updated. READ_WRITE — frequently updated (uses soft locks). TRANSACTIONAL — JTA environments. Query Cache: spring.jpa.properties.hibernate.cache.use_query_cache=true. @QueryHints({@QueryHint(name=HINT_CACHEABLE, value=”true”)}) — cache query results. Redis as second-level cache provider: used in distributed environments where multiple JVM instances share cache.

89. What are Java Design Patterns most commonly used in Spring applications?

  1. Spring applications only use the Singleton pattern — all other patterns are irrelevant
  2. Spring applications heavily use Singleton (bean scope), Factory (ApplicationContext creating beans), Proxy (AOP, @Transactional), Template (JdbcTemplate, RestTemplate), Observer (ApplicationEvents), and Front Controller (DispatcherServlet) patterns
  3. Design patterns are only for academic study and are not used in real Spring applications
  4. Spring replaces all design patterns with its own proprietary Spring-specific coding patterns

Answer : B
Explanation: Spring is built on design patterns — recognizing them deepens your understanding: Singleton Pattern: Spring beans are singleton by default — one instance per ApplicationContext. @Scope(“singleton”) is the default scope. Factory Pattern: ApplicationContext (BeanFactory) creates beans based on configuration. @Bean methods are factory methods. The container is the factory. Proxy Pattern: Spring AOP creates proxies for @Transactional, @Cacheable, @Async beans. The proxy intercepts method calls, applies advice, delegates to the real object. Template Method Pattern: JdbcTemplate, RestTemplate, HibernateTemplate — template defines algorithm skeleton, subclasses (or lambda callbacks) fill in specific steps. Eliminates boilerplate while maintaining control. Observer Pattern: ApplicationEventPublisher / @EventListener. @Component publishes events, other @Components listen. Loose coupling between components. Front Controller Pattern: DispatcherServlet is the single front controller for all Spring MVC requests. Routes to specific handlers based on URL mapping. Decorator Pattern: @Cacheable wraps methods with caching behavior. Security proxy wraps beans. Strategy Pattern: different AuthenticationProvider implementations. Different DataSource configurations for different environments. Dependency Injection itself: enables Strategy, Decorator, and Observer patterns cleanly by injecting different implementations.

90. What is Apache Tomcat’s connection between Spring Boot and deployment?

  1. Spring Boot applications cannot use Tomcat — they must use Jetty or Undertow instead
  2. Spring Boot embeds Tomcat inside the application JAR — the application starts its own server with a simple java -jar command, eliminating the need for an external application server deployment and making the application fully self-contained
  3. Apache Tomcat must always be installed separately even when using Spring Boot applications
  4. Spring Boot’s embedded Tomcat only works in development — production requires external Tomcat

Answer : B
Explanation: Traditional vs Spring Boot Deployment: Traditional WAR deployment: develop app → build WAR file → install Tomcat separately → copy WAR to webapps/ → start Tomcat → app is running. Multiple apps can share one Tomcat. Complex deployment process. Spring Boot embedded server: spring-boot-starter-web includes embedded Tomcat. Build: mvn package → creates executable JAR (fat JAR) containing application classes + all dependencies including Tomcat. Run: java -jar myapp-1.0.jar → Tomcat starts, app deploys automatically. Port: default 8080, change with server.port in application.properties. This is the recommended Spring Boot deployment model. Changing the embedded server: exclude Tomcat: <exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions>. Add Jetty: spring-boot-starter-jetty. Add Undertow: spring-boot-starter-undertow. Deploying to external Tomcat (traditional WAR): extend SpringBootServletInitializer, change packaging to WAR. Needed when organization mandates a shared app server. Docker deployment (modern standard): FROM openjdk:17-jre-slim, COPY target/app.jar app.jar, ENTRYPOINT [“java”,”-jar”,”/app.jar”]. Each Spring Boot JAR runs in its own Docker container — self-contained, portable, independently scalable.