38 Common Backend Interview Questions, Organized

 ・ 21 min

photo by Matthew Smith(https://unsplash.com/@whale?utm_source=templater_proxy&utm_medium=referral) on Unsplash

If you've sat through enough interviews, you'll notice the same topics keep coming up. I've gathered 38 questions I've actually been asked in Java/Spring backend interviews and grouped them by theme. Let's walk through how to answer each one.

Java Fundamentals#

Features of Java#

Three OOP pillars are the safe answer.

  1. Encapsulation — Bundle data and behavior together, expose only what's needed.
  2. Inheritance — Child classes inherit attributes and behavior from parent classes.
  3. Polymorphism — The same interface can call different implementations.

Some include abstraction to make it four. It also helps to mention that Java runs on the JVM (Write Once, Run Anywhere) and uses garbage collection for automatic memory management.

Interviewers also ask about modern Java features these days. Knowing the highlights from Java 21 (LTS) onward goes a long way.

  • Record (Java 16+) — Declare immutable data classes in one line
  • Sealed Class (Java 17+) — Explicitly restrict which classes can extend a parent
  • Pattern Matching (Java 21+) — Pattern matching for switch and instanceof
  • Virtual Threads (Java 21+) — The result of Project Loom; lightweight threads for concurrency

Class vs. Object#

  • Class — A blueprint for creating objects. Defines attributes (fields) and behavior (methods).
  • Object — An actual instance in memory, created from a class.

If a fish-shaped bread mold is the class, each bread that comes out of it is an object.

Data Types (Primitive vs. Reference)#

Primitive — The value itself sits on the stack. The eight types: byte, short, int, long, float, double, char, boolean.

Reference — Holds the address of an object on the heap. Classes, arrays, and interfaces are all reference types.

int a = 10;              // Primitive: stores the value 10 directly
String s = "hello";      // Reference: stores the heap address

Instantiation#

The act of creating an object in memory from a class blueprint. You use the new keyword.

User user = new User();  // Instantiating the User class

The resulting user is called an instance of the class. It's nearly synonymous with "object," but you use "instance" when you want to emphasize which class it came from.

Interface vs. Abstract Class#

Aspect Interface Abstract Class
Purpose Enforce contract Shared logic + partial enforcement
Multiple inheritance Yes No (single inheritance)
Fields Only public static final Any kind
Methods abstract + default + static abstract + concrete
When to use "What it can do" "What it is (is-a)"

An interface is a contract — "this class can do these things." An abstract class lets you share common implementation while forcing subclasses to implement specific methods.

Why Use Generics?#

The one-line answer: type safety + code reuse.

// Without generics
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);  // Cast required, runtime risk
 
// With generics
List<String> list = new ArrayList<>();
list.add("hello");
String s = list.get(0);  // No cast, type-checked at compile time

The biggest win is catching ClassCastException at compile time instead of letting it explode at runtime.

Collections Framework#

The Big Picture#

Three main interfaces to know.

  • List — Ordered, allows duplicates (ArrayList, LinkedList)
  • Set — Unordered, no duplicates (HashSet, TreeSet, LinkedHashSet)
  • MapKey-value pairs (HashMap, TreeMap, LinkedHashMap)

Map doesn't extend Collection, but it's still part of the framework.

Java 21 added Sequenced Collections. The SequencedCollection, SequencedSet, and SequencedMap interfaces give you a consistent API for the first/last element (getFirst(), getLast(), addFirst(), addLast(), reversed()). Before this, every LinkedList, LinkedHashSet, and LinkedHashMap had its own way to access the ends.

Array vs. ArrayList#

Item Array ArrayList
Size Fixed Dynamic
Type Both primitive and reference Reference only (generics)
Performance Fast (lightweight) Slight overhead
Features Minimal Rich (add, remove, contains, ...)

Internally, ArrayList is also backed by an array. When capacity runs out, it creates a larger array and copies everything over to fake dynamic sizing.

Key-Value / Deduplication#

  • Key-value: Map family → HashMap, TreeMap, LinkedHashMap
  • Deduplication: Set family → HashSet, TreeSet, LinkedHashSet

What Works in for-each#

Anything that implements the Iterable interface, plus arrays.

public interface Iterable<T> {
    Iterator<T> iterator();
}

Collection extends Iterable, so List and Set work directly. Map doesn't work directly — you need to convert it via entrySet(), keySet(), or values().

Spring & DI/IoC#

DI and IoC#

  • IoC (Inversion of Control) — Object creation and lifecycle are managed by the framework (container), not the developer.
  • DI (Dependency Injection) — Objects don't create their dependencies themselves; they receive them from outside. DI is one way to implement IoC.
// Without DI
public class OrderService {
    private UserRepository repo = new UserRepository();  // Tight coupling
}
 
// With DI
public class OrderService {
    private final UserRepository repo;
 
    public OrderService(UserRepository repo) {  // Injected from outside
        this.repo = repo;
    }
}

The benefits: lower coupling, easier testing, better reusability.

Spring Bean Scope#

  • singleton (default) — One instance per container
  • prototype — A new instance per request
  • request — One per HTTP request (web only)
  • session — One per HTTP session (web only)
  • application — One per ServletContext (web only)

Most service beans are stateless, so singleton is enough.

Spring Version#

As of 2026, the practical standard is Spring Boot 3.x / Spring Framework 6.x. The key changes:

  • Java 17+ required (Spring Boot 3.2 added official Java 21 support, enabling Virtual Threads)
  • javax.*jakarta.* package migration (Jakarta EE 9 transition). The biggest migration headache.
  • GraalVM Native Image officially supported
  • Observability standardized (Micrometer + OpenTelemetry)

Projects still on Spring Boot 2.x face this migration, which is why interviewers love asking about it.

REST Standard Annotations (HATEOAS / OpenAPI)#

When an interviewer asks "Spring's API annotations don't conform to the standard — which library makes them standard-compliant?", they're usually pointing at one of two things:

  1. HATEOAS (Hypermedia As The Engine Of Application State) — The final stage of true REST as defined by Roy Fielding. Spring offers the Spring HATEOAS library.
  2. OpenAPI 3 / Swagger — The standard for API specs. In Spring, springdoc-openapi is the de facto choice (the older SpringFox is deprecated).

HATEOAS embeds links (href) to next actions in responses, getting closer to true REST.

{
  "id": 1,
  "name": "User",
  "_links": {
    "self": { "href": "/users/1" },
    "orders": { "href": "/users/1/orders" }
  }
}

Full HATEOAS adoption is rare in practice — standardizing API specs with OpenAPI is far more common.

HTTP & REST#

HTTP#

  • HyperText Transfer Protocol — The protocol clients and servers use on the web
  • Stateless — Each request is independent; the server doesn't remember prior requests
  • Request-response structure: method, URL, headers, body
  • Default port 80, HTTPS uses 443

It also helps to know the version differences.

Version Features Transport
HTTP/1.1 Text-based, Keep-Alive TCP
HTTP/2 Binary, multiplexing, header compression (HPACK), server push TCP + TLS
HTTP/3 Runs on QUIC, 0-RTT, solves TCP head-of-line blocking UDP + TLS 1.3

As of 2026, most major CDNs and large services have HTTP/3 enabled.

HTTP Methods: Safety and Idempotency#

Method Safe Idempotent Use
GET Yes Yes Read
HEAD Yes Yes Headers only
OPTIONS Yes Yes Check supported methods
PUT No Yes Full update/create
DELETE No Yes Delete
POST No No Create
PATCH No No Partial update
  • Safe — Doesn't change server state (read-only)
  • Idempotent — Multiple identical requests produce the same result

HTTPS#

HTTP plus TLS/SSL encryption. The three guarantees to remember:

  1. Confidentiality — Encrypts data in transit
  2. Integrity — Ensures data isn't tampered with along the way
  3. Authentication — Verifies the server is who it claims to be, via certificates

The handshake works like this: exchange a session key safely with asymmetric crypto, then switch to fast symmetric crypto for the rest.

TLS 1.3 is the standard now. Faster 1-RTT handshake, and weak algorithms (RSA key exchange, CBC, SHA-1) are gone. TLS 1.0/1.1 have been deprecated for years, and TLS 1.2 is being phased out as well.

RESTful API#

REST stands for REpresentational State Transfer. Core principles:

  • Identify resources by URL/users/1
  • Express actions with HTTP methods — GET, POST, PUT, DELETE
  • Stateless — The server doesn't store client state
  • Representation — Resource state is conveyed via JSON, XML, etc.

URLs hold nouns; actions go in HTTP methods.

Bad:  GET  /getUser/1
Good: GET  /users/1
 
Bad:  POST   /deleteUser/1
Good: DELETE /users/1

OSI Layers and HTTP#

Layer Name Examples
7 Application HTTP, FTP, SMTP, DNS
6 Presentation SSL/TLS, JPEG, ASCII
5 Session NetBIOS, RPC
4 Transport TCP, UDP
3 Network IP, ICMP
2 Data Link Ethernet, MAC
1 Physical Cables, signals

HTTP lives at layer 7 (Application), TCP at layer 4, IP at layer 3. TLS in HTTPS is usually classified at layer 6 (Presentation).

Web Server & Servlet#

Web Server vs. WAS#

  • Web Server — Serves static content (HTML, CSS, images). Nginx, Apache HTTPD.
  • WAS (Web Application Server) — Handles dynamic content and business logic. Tomcat, Jetty.

A common production setup is Nginx in front + Tomcat behind. The web server handles static assets, the WAS handles dynamic processing — splitting the load.

How a Servlet Works#

  1. A client request arrives
  2. The servlet container (Tomcat etc.) receives it
  3. URL mapping locates the right servlet (instantiating it if needed)
  4. A thread is allocated to call service()doGet() / doPost()
  5. The response goes back to the client

A servlet is a singleton, so multiple requests share the same instance. That means storing state in instance variables is dangerous.

Since Jakarta EE 9, the package is javax.servletjakarta.servlet, and Spring Boot 3.x follows. From Spring Boot 3.2 onward, enabling Virtual Threads drastically lowers the cost of the thread-per-request model. If you need non-blocking, Spring WebFlux (reactive) is also an option.

Servlet Filter#

A component that intercepts requests and responses in front of the servlet. Useful for authentication, logging, encoding conversion, CORS, and more.

Client → Filter 1 → Filter 2 → Servlet → Filter 2 → Filter 1 → Client

Spring's Interceptor is similar but kicks in at a different point. Filter runs before DispatcherServlet, Interceptor runs after DispatcherServlet but before the controller.

Item Cookie Session
Stored at Client (browser) Server
Security Relatively weak Stronger
Size 4KB limit Server memory
Expiry Set duration Browser close (or timeout)

Common rule of thumb: sensitive data goes in the session, simple identifiers and remember-me tokens go in cookies. Remember-me lives in cookies because it must survive a browser restart — sessions disappear on close or timeout.

It's worth knowing the cookie security flags:

  • HttpOnly — Inaccessible from JavaScript (XSS defense)
  • Secure — Sent only over HTTPS
  • SameSiteStrict / Lax / None. CSRF defense. Chrome's default is Lax now.
  • Partitioned (CHIPS) — Isolates third-party cookies, prevents cross-site tracking

These days, stateless token authentication with JWT (JSON Web Token) is also widespread. It avoids server memory and scales horizontally well, but token revocation is hard. The usual workaround: short access tokens + longer refresh tokens.

Security#

Defending Against SQL Injection#

The most reliable defense is PreparedStatement (parameter binding).

// Dangerous: string concatenation
String sql = "SELECT * FROM users WHERE id = '" + userId + "'";
 
// Safe: parameter binding
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, userId);

"Doesn't MyBatis or JPA block this automatically?" — Partly, but not entirely.

  • MyBatis #{} becomes a PreparedStatement and is safe; ${} is string substitution and unsafe
  • JPA's JPQL is safe, but concatenating strings into a Native Query is just as risky

Bottom line: even with an ORM, be careful whenever you build SQL fragments dynamically from strings.

Proxy vs. Gateway#

  • Proxy — A middleman between client and server. Forwards requests within the same protocol.
    • Forward Proxy — Client-side (corporate network → external)
    • Reverse Proxy — Server-side (external → distributed internal servers, e.g., Nginx)
  • Gateway — Adds protocol translation, routing, auth, logging, and other value-add features. API Gateway is the canonical example.

In short: proxy = simple forwarding, gateway = entry point that applies policies.

In the MSA era, Service Mesh (Istio, Linkerd) often comes up. A sidecar proxy (like Envoy) handles service-to-service communication at the infrastructure layer — pulling cross-cutting concerns like mTLS, traffic shaping, and observability out of application code.

Message Queues & Caches#

RabbitMQ Features#

  • Built on AMQP (Advanced Message Queuing Protocol)
  • Producer → Exchange → Queue → Consumer flow
  • Supports message persistence (disk-backed)
  • Flexible routing via Exchange types
  • Wide language client support

RabbitMQ Exchange Types (Beyond Just Queueing)#

You don't push directly into a queue — the Exchange routes messages to queues based on rules.

Exchange Type Behavior
Direct To the queue whose routing key matches exactly
Topic Routing key pattern matching (*, #)
Fanout Broadcast to all bound queues
Headers Routing based on message headers

The Topic Exchange is what people mean by "publishing to a topic." It's great for patterns like order.created, order.cancelled.

For reference, RabbitMQ 4.x added Streams, a new persistent log structure for Kafka-like replay and long retention scenarios. Heavy event streaming is still Kafka territory, while RabbitMQ shines as a reliable work queue.

Caches Other Than Redis (In-Memory)#

If they ask about "RAM caches," they mean local in-memory caches.

  • Caffeine — The most popular high-performance in-memory cache for Java
  • Ehcache — A Java-world veteran; supports distributed caching too
  • Guava Cache — Predecessor of Caffeine; Caffeine is now recommended
  • Memcached — Distributed in-memory cache (simpler than Redis)

Redis is a separate server over the network; Caffeine runs inside the JVM. For fast in-process caching, go Caffeine. For sharing across servers, go Redis.

JavaScript#

Why Minify?#

  • Smaller files → faster downloads
  • Lower bandwidth costs
  • Faster parsing

Minifiers strip whitespace, line breaks, and comments, and shorten variable names. It's not about security (obfuscation is a different thing).

These days, builds are mostly handled by Go/Rust-based tools like esbuild, swc, Rolldown. They're tens of times faster than Webpack/Babel, which is why they power next-gen bundlers like Vite and Turbopack.

Inline vs. External#

Item Inline (<script>...</script>) External (<script src="...">)
HTTP requests None extra Extra request
Caching Not cacheable Browser-cacheable
Reuse Duplicated per page Shared across pages
Maintainability Hard Easy
Initial render Can be faster First request is slower

In the HTTP/1.1 era, the cost of an extra external request was painful. With HTTP/2 multiplexing, fetching multiple external files no longer hurts much. The recommended approach is to split modules into external files, and inline only the critical CSS/JS needed for the first paint.

Where to Place Inline Scripts#

  • In <head> — Runs before the page renders, can't access the DOM
  • At the end of <body> — Runs after DOM load; the common recommendation
  • In <head> with defer/async — Parallel download with controlled execution timing

If your code touches the DOM, just before </body> is safe. Or use the DOMContentLoaded event.

The modern best practice is to put scripts in <head> with defer or type="module". Both don't block HTML parsing and execute in order after the DOM is ready.

<!-- Modern recommended pattern -->
<script type="module" src="/app.js"></script>
<script defer src="/legacy.js"></script>

Collaboration & Communication#

How Do You Handle Disagreements?#

This question is really about attitude and reasoning process. The model answer follows this flow:

  1. Hear them out fully — Understand their intent and reasoning
  2. Confirm a shared goal — "We both want X, right?"
  3. Argue from data and evidence — Objective grounds, not emotion
  4. Disagree and Commit — Once a decision is made, support it 100%

The core mindset: "It's not about winning; it's about reaching a better outcome."

Wrapping Up#

Each interview question is really a tool to gauge how solidly you grasp the fundamentals. Don't just rattle off keywords — practice articulating why something works the way it does and how it's used in practice.

When you don't know an answer, it's better to say "I'm not sure exactly, but I've encountered this in such-and-such context." Pretending to know is the most dangerous move.


People take different roads seeking fulfilment and happiness. Just because theyre not on your road doesn't mean they've gotten lost.

— Dalai Lama


Other posts
25 Backend Interview Questions Revisiting Java Server Fundamentals 커버 이미지
 ・ 14 min

25 Backend Interview Questions Revisiting Java Server Fundamentals

Government Grants and Investment — What Every Founder Should Know 커버 이미지
 ・ 5 min

Government Grants and Investment — What Every Founder Should Know

Core Backend Concepts for Interview Preparation 커버 이미지
 ・ 11 min

Core Backend Concepts for Interview Preparation