Interview questions
4 subscribers
6 files
3 links
Answers to common Java Backend questions

My Linked in: www.linkedin.com/in/axmadullo-ubaydullayev-0738a1210

Tg: @HardWorker3334
Download Telegram
What is a Bean?

Objects which created automotically by the spring container and inversioned by it

We can use Annotations like Component, or other specific annotations (Controller, Service, Repository)
Or create beans in configuration class, using @Bean over the methods, and point @Configuration in class level.
Or Use XML way to create beans

#bean #annotation #configuration
What is the difference between ApplicationContext and BeanFactory?


BeanFactory vs ApplicationContext
BeanFactory — legacy

XML based configuration
Creates beans lazily — only when requested
Basic bean management only

ApplicationContext — modern

Extends BeanFactory — has everything it has + more
Creates beans eagerly — all at startup
Supports AOP
Supports events
Recommended for all modern Spring apps

#bean #spring #application_context #bean_factory
@Qualifier What is it?

When multiple implementations of the same interface exist, @Qualifier tells Spring exactly which one to inject.

@Autowired
@Qualifier("emailNotificationService")
private NotificationService notificationService;


Without it — Spring throws:
NoUniqueBeanDefinitionException — found 2 candidates, doesn't know which to pick.

Two ways to fix:

@Qualifier("beanName") // explicitly pick one
@Primary // mark one implementation as the default choice



#qualifier
How many ways exist to create Beans?

@Repository — adds exception translation, converts raw DB exceptions into Spring's DataAccessException. The only one with real functional difference.
@Service — purely semantic, no extra functionality. Just indicates business logic layer.
@Component — generic base annotation. Use when the class doesn't fit @Service or @Repository.

#bean #repository #service #component
What does @ComponentScan do?

It shows the location of beans where compiler should search for beans to inject

#componentScan
How many Bean scopes exist?

singleton (object creates once and uses everywhere) , prototype (new object every time) , session (used rarely)

#singleton #prototype
What is @PostConstruct and @PreDestroy?

Method with @PostContruct annotation runs after injecting the bean, and @PreDestroy method runs after closing the context

@PreDestroy — closing connections, releasing resources, cleanup before the bean dies.


@PostConstruct
public void init() {
dbConnection.open(); // runs after bean created
}

@PreDestroy
public void cleanup() {
dbConnection.close(); // runs before context closes
}


#post_construct #pre_destroy
Bean Circular Dependency in Spring
What is it?

When two beans depend on each other — neither can be created first.

Bean A needs B → Bean B needs A → 💥

Spring throws: BeanCurrentlyInCreationException:

Requested bean is currently in creation:

Is there an unresolvable circular reference?

3 ways to fix:

1. @Lazy recommended

@Component
public class A {
public A(@Lazy B b) { }
}


Delays bean creation until actually needed — breaks the cycle.

2. Setter Injection

@Autowired
public void setB(B b) { this.b = b; }


Spring creates both beans first, injects after.

3. Redesign — best long term

Extract shared logic into a third bean. Circular dependency usually signals an architecture problem.


#Java #Spring #Beans #CircularDependency
1
@Value in Spring

What is it?

Injects values from properties files or expressions directly into fields at runtime.

1. From properties file ${}

application.yml
app.servers=server1,server2,server3
app.timeout=5000



@Value("${app.servers}")
private String[] servers;

@Value("${app.timeout:5000}") // default if not found
private int timeout;


2. SpEL expressions #{}

@Value("#{2 * 3}")                         // math → 6
private int result;

@Value("#{userService.getDefaultName()}") // method call on a bean
private String name;

@Value("#{T(Math).PI}") // static field
private double pi;


Key difference:
${} reads from properties files
#{} evaluates Java expressions at runtime

#Java #Spring #Value #SpEL #Properties
How JVM Works Internally?

First, we create a .java file, then compile it with javac MyApp.java, which produces a .class file containing bytecode.

After that, the ClassLoader starts working. It follows the Parent Delegation Model — so the request goes upward first, not downward. The Application ClassLoader (where our class data is located) delegates to Extension (extra libraries for helping Java), which delegates to Bootstrap (Java core libraries like java.lang, java.util). Bootstrap tries to load the class first. If it can't find it, the request falls back to Extension, and finally to Application. This prevents malicious code from replacing core Java classes.


After finishing this process, data gets stored in 5 types of memory according to their purpose: Heap (for objects, reference types), Stack (references, primitive types, method frames), Method Area (class metadata, static fields, method bytecode), Native Method Stack (for non-Java code called through JNI), and PC Register (holds the address of the current bytecode instruction for each thread — needed for thread switching).


After all that, the Execution Engine starts working. It has 2 modes working simultaneously. The Interpreter reads bytecode instruction by instruction. While it runs, the JVM counts how many times each method is called. After a method is called around 10,000 times, it becomes "hot code" and the JIT Compiler converts it into native machine code (0s and 1s). From that point, that method runs directly as compiled code, skipping the Interpreter. This is why Java gets faster over time.
Here also GC works, which manages Heap memory by removing unreachable objects. It has Young Generation — new objects come to Eden, and after surviving Minor GC cycles they get copied between Survivor1 and Survivor2 (one is always empty). After around 15 cycles they move to Old Generation, where objects are less likely to be removed and can be cleaned by Major GC or Full GC.


#JVM #heap #stack #meta_space #native #pc_register #class_loader #boostrap #extension #application #GC #minor_gc #major_gc #eden
Why the program slow down over time?

There might be several reasons why a Java application slows down over time.

1. Memory Leak — objects that are no longer needed still have references pointing to them, so GC can't remove them. For example, adding objects to a static List and never clearing it. The Heap gradually fills up, GC runs more and more frequently, recovers almost nothing, and the application slows down. In the worst case, if GC spends more than 98% of CPU time and recovers less than 2% of the Heap, the JVM throws OutOfMemoryError: GC overhead limit exceeded.



2. GC Pressure — even without a leak, if your application creates too many short-lived objects too fast, Minor GC runs constantly. And if many objects survive long enough to reach Old Generation, Full GC kicks in — which is a stop-the-world pause that freezes the entire application.


3. Thread Contention — when multiple threads compete for the same lock or synchronized block, they wait instead of working. The application has available CPU cores but threads are stuck in a queue, so throughput drops.


4. JIT Decoptimisation — the JIT Compiler makes assumptions when optimising hot code. If those assumptions become invalid later (for example, a new subclass appears), the JIT throws away the compiled code and falls back to the Interpreter. This causes temporary performance drops.

5. Resource Exhaustion — unclosed connections, streams, or file handles accumulate over time. The application starts waiting for available resources instead of processing requests.



#memory_leak #gc_pressure #thread_contention #JIT_Decomposition #Resource_Exhaustion
Why JVM Doesn't Exit After main() Finishes?

JVM exits only when all non-daemon threads finish. If main() ends but other threads are still running — JVM stays alive.

Common culprits — infinite loop in a thread, ExecutorService not shut down, Timer or ScheduledExecutorService still running, unclosed DB or socket connections holding background threads.

Fix — make background threads daemon with setDaemon(true) so they die automatically when main dies, or properly shut down ExecutorService, or interrupt threads explicitly.

#Java #JVM #Threads #Daemon
What's the key differences between Java 8 vs Java 17?


GC — Java 8 defaults to Parallel GC (rare but long pauses). Java 9+ defaults to G1 (frequent but short pauses). Both do Full GC if memory leaks exist.

Strings — Java 8 stores every character as 2 bytes. Java 9+ stores Latin characters as 1 byte, falls back to 2 bytes for Cyrillic/Chinese. Automatic memory saving, zero code changes.

PermGen → Metaspace — Java 8 removed PermGen (fixed-size box for class metadata) and replaced it with Metaspace (grows dynamically using native memory). Old -XX:MaxPermSize flags silently ignored.

Reflection locked down — Java 9+ introduced the module system and restricted access to internal JDK classes like sun.misc.Unsafe. Java 9-15 showed warnings. Java 16+ throws hard errors. This broke Hibernate, Spring, and hundreds of libraries. Main reason companies stayed on Java 8 for years.

New language features — Records (one-line DTOs), sealed classes (controlled inheritance), pattern matching (no manual casting after instanceof), text blocks (multiline strings). None exist in Java 8.

JIT — Java 8 had C1 and C2 compilers separately. Java 9+ introduced tiered compilation by default — C1 compiles quickly first, C2 recompiles hot methods with deeper optimisations. Faster warm-up.

API additions — var for local variables (Java 10), new HttpClient (Java 11), helpful NullPointerException messages showing exactly which reference was null (Java 14), Stream.toList() shortcut (Java 16).


#java8 #java9+
What Happens if main() is Not Static

When you type java MyApp, the Heap is empty — no objects exist yet. The JVM needs an entry point to start your programme.

If main() were non-static — JVM would need to create an object first. But which constructor? What arguments? What if it throws an exception? JVM has no information to decide.

With static — JVM calls MyApp.main(args) directly on the class level. No object needed, no guessing.

Without static — JVM doesn't even try. You get:

Error: Main method not found, please define as public static void main(String[] args)

Java 21 introduced a preview feature — you can write just void main() without static, without String[] args, without public. JVM handles object creation internally.

#Java #JVM #Static #Main
Memory Leaks in Java — yes, even with GC

A lot of devs think "Java has GC, so no memory leaks". I thought the same. Then I spent 3 hours debugging why our app crashed every night at 3am.
Turned out — one unclosed DB connection. That's it.

GC is smart but it's not magic. It removes objects nobody references anymore. The problem is you — you keep referencing objects you forgot about.
Classic examples from real life:
You register a listener and never unregister. You put something in ThreadLocal and move on. You cache objects in a static list and never clean it. You open a connection and "handle it later".

The app doesn't crash immediately. It slows down. Memory grows. GC works harder. Until one night — boom.
The fix isn't a library or a pattern. It's just discipline — close what you open.

#Java #Backend #RealTalk
GC Pauses Increased After a Small Code Change

A small code change caused GC pauses to spike. How?

Most developers add a log line, forget to close a connection, or switch from primitive to wrapper type. Looks innocent. But the chain reaction is brutal.
Too many objects created → Eden fills fast → Minor GC runs constantly → objects survive and get promoted to Old Generation → Old Gen fills up → Major GC kicks in → long Stop The World pause.
Minor GC pauses are short — milliseconds. Major GC pauses are long — hundreds of milliseconds or even seconds. That's the difference between a smooth app and one that freezes randomly.
The culprit is almost always objects living longer than they should — unclosed connections, unbounded caches, forgotten listeners.

#Java #JVM #GC #Performance