Top 20 HCLTech Full Stack Java Developer (Node.js) Interview Questions & Answers

Preparing for a full-stack technical interview at HCLTech requires a strong grasp of both core Java/Spring Boot enterprise concepts and lightweight Node.js/JavaScript asynchronous architectures.

Below is a complete collection of 20 high-frequency questions, technical answers, and scenario-based code concepts used during HCLTech hiring rounds.

Part 1: Core Java & Spring Boot (Questions 1–6)

Q1: How does HashMap work internally in Java 8, and how are hash collisions handled?

  • Answer: Java 8 HashMap relies on an array of buckets containing nodes. When put(key, value) is called, Java computes the key’s hash code to locate the bucket index. If two keys collide at the same bucket, they are stored in a singly linked list. When a bucket’s linked list grows beyond TREEIFY_THRESHOLD = 8 nodes and table capacity reaches 64, Java converts the list into a Red-Black Tree, reducing lookup time complexity from $O(n)$ to $O(\log n)$.

Q2: What is the difference between @Controller and @RestController in Spring Boot?

  • Answer: @Controller is designed for traditional web applications returning view templates (e.g., Thymeleaf or HTML). @RestController is a composite annotation combining @Controller and @ResponseBody. It automatically serializes returned Java objects directly into JSON or XML HTTP responses for RESTful web services.

Q3: What is the difference between Fail-Fast and Fail-Safe iterators?

  • Answer: Fail-Fast iterators (e.g., ArrayList, HashMap) throw a ConcurrentModificationException immediately if the collection is structurally modified while iterating. Fail-Safe iterators (e.g., ConcurrentHashMap, CopyOnWriteArrayList) operate on a clone or concurrent snapshot of the collection, allowing modifications during iteration without throwing runtime exceptions.

Q4: How do you handle database transaction management in Spring Boot using @Transactional?

  • Answer: @Transactional uses Spring AOP proxies to manage database boundaries automatically. It begins a transaction before method execution and commits it upon success. If a RuntimeException or Error occurs, Spring triggers an automatic rollback. Custom rollback rules can be configured using @Transactional(rollbackFor = Exception.class).

Q5: What are the primary Bean Scopes available in Spring Framework?

  • Answer:
    1. Singleton (Default): Creates a single shared instance per Spring IoC container.
    2. Prototype: Creates a brand-new bean instance every time it is requested.
    3. Request: Creates a single instance per HTTP request (Web context only).
    4. Session: Creates a single instance per HTTP session lifecycle.
    5. Application: Scoped to the lifecycle of a ServletContext.

Q6: How does Dependency Injection work in Spring, and why is Constructor Injection preferred over Field Injection?

  • Answer: Dependency Injection (DI) allows the Spring IoC container to inject dependent objects into a class rather than having the class instantiate them directly. Constructor injection is preferred over @Autowired field injection because it enforces immutability (final fields), allows unit testing without starting a full Spring context, and prevents circular dependency runtime issues.

Part 2: Node.js & Asynchronous JavaScript (Questions 7–12)

Q7: How does the Node.js Event Loop work?

  • Answer: Node.js runs single-threaded using the libuv library to manage non-blocking I/O. The Event Loop executes synchronous tasks on the Call Stack. Asynchronous tasks (like file I/O or network calls) are offloaded to system kernels or libuv worker threads. Once complete, their callbacks enter the Microtask or Macrotask queues and execute on the Call Stack when it becomes empty.

Q8: What is the difference between process.nextTick() and setImmediate() in Node.js?

  • Answer: process.nextTick() executes callbacks immediately after the current operation finishes, before the Event Loop proceeds to its next phase. setImmediate() schedules callbacks to execute during the Check phase of the Event Loop, running after I/O callbacks are processed.

Q9: How do you handle CPU-intensive or blocking tasks in a Node.js application?

  • Answer: Since long-running CPU calculations block the single-threaded Event Loop, you can delegate heavy workloads using the built-in worker_threads module or child processes (child_process.fork()). Alternatively, offload intensive processing to dedicated background microservices written in Java.

Q10: What are Streams in Node.js, and why are they useful?

  • Answer: Streams are objects that read or write data continuously in chunks rather than buffering entire files into memory. Types include Readable, Writable, Duplex, and Transform streams. They significantly improve memory efficiency and performance when processing large logs, uploads, or datasets.

Q11: What is the difference between Promises and Async/Await in JavaScript?

  • Answer: Promises handle asynchronous operations using chainable .then() and .catch() blocks. Async/Await is syntactic sugar built on top of Promises, allowing asynchronous code to be written in a clean, synchronous-looking style using standard try/catch blocks for error handling.

Q12: How do you prevent and detect memory leaks in Node.js applications?

  • Answer: Memory leaks occur due to global variables, unclosed database connections, or uncleared setInterval() timers. They are detected using memory profiling tools like Chrome DevTools (Heap Snapshots), process.memoryUsage(), or APM monitoring tools like New Relic or Dynatrace.

Part 3: Architecture, Integration & Security (Questions 13–16)

Q13: How do you handle Cross-Origin Resource Sharing (CORS) between a Node.js/React frontend and a Spring Boot backend?

  • Answer: CORS can be configured on the backend to permit requests from the frontend domain. In Spring Boot, apply @CrossOrigin(origins = "[https://bytetocareer.com](https://bytetocareer.com)") on controller classes or define a global WebMvcConfigurer. In Node.js Express, utilize the cors() middleware package.

Q14: How do you secure REST APIs when combining Node.js microservices with a Java backend?

  • Answer:
    1. Stateless JWT: Authenticate users and pass JSON Web Tokens in the Authorization: Bearer <token> header across services.
    2. API Gateways: Route traffic through a gateway (e.g., Spring Cloud Gateway or Kong) for centralized authentication.
    3. HTTPS/TLS: Encrypt data in transit between microservices.
    4. Role-Based Access Control (RBAC): Enforce scope checks using Spring Security or Express authorization middleware.

Q15: When should you use a SQL database vs. a NoSQL database in a full-stack project?

  • Answer: Choose SQL (PostgreSQL, MySQL) for structured data requiring strict ACID compliance, complex relational queries, and transactional integrity (e.g., payments, user accounts). Choose NoSQL (MongoDB, Redis) for unstructured data, high-throughput caching, dynamic schemas, or real-time event logging.

Q16: How do you implement the Circuit Breaker pattern in Java microservices?

  • Answer: Circuit Breakers prevent cascading system failures when a downstream service becomes unresponsive. Using libraries like Resilience4j in Spring Boot, the circuit stays Closed during normal operation, switches to Open to block requests immediately when failures breach a threshold, and transitions to Half-Open to test if the dependent service has recovered.

Part 4: Practical Coding & Real-World Scenarios (Questions 17–20)

Q17: Write a Java 8 Stream pipeline to filter employees earning > ₹50,000 and collect their names in uppercase.

  • Answer:

Java

List<String> highEarners = employees.stream()
.filter(emp -> emp.getSalary() > 50000)
.map(emp -> emp.getName().toUpperCase())
.collect(Collectors.toList());

Q18: Write an Express.js middleware in Node.js to log request details and validate a Bearer token.

  • Answer:

JavaScript

const authMiddleware = (req, res, next) => {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
const authHeader = req.headers['authorization'];
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Unauthorized: Missing or invalid token' });
}
const token = authHeader.split(' ')[1];
// Verify token logic here...
next();
};

Q19: How do you handle global exception management in a Spring Boot application?

  • Answer: Use @RestControllerAdvice along with @ExceptionHandler methods. This captures exceptions thrown across all controllers centrally and returns standardized JSON error responses.

Java

@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
}

Q20: How do you optimize REST API response times when serving high-traffic requests?

  • Answer:
    1. Caching: Implement Redis or HTTP caching headers for static/frequently accessed data.
    2. Database Indexing: Ensure queries utilize proper indexing on foreign keys and search columns.
    3. Pagination: Avoid returning full datasets by using Spring Data Pageable or Mongo limit/offset parameters.
    4. Asynchronous Execution: Offload background tasks (email sending, logs) using Java @Async or Node queues like Bull/BullMQ.

👉 Applying for HCL Tech? Check out the latest [HCL Tech Off Campus Drive Listing]

More Articles & Posts