Enterprise Java Backend Technical Interview Reference

Microservices Architecture Stack

Modern distributed systems leverage Spring Cloud Alibaba ecosystem combined with containerized deployement. Core infrastructure components include Nginx for edge traffic management, Spring Cloud Gateway for centralized authentication and routing, Nacos for service discovery and dynamic configuration, Sentinel for circuit breaking and traffic shaping, Seata for distributed transaction coordination, and Canal with Kafka for data synchronization pipelines.

Nginx Load Balancing and Reverse Proxy Configuration

Reverse proxy configuration directs client requests to upstream server pools while masking backend topology. The proxy_pass directive forwards requests to defined upstream groups.

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://application_cluster;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_connect_timeout 30s;
        proxy_read_timeout 30s;
    }
}

Load balancing distributes traffic across multiple backend instances using various algorithms. Configuration defines separate upstream pools for different service tiers:

http {
    upstream application_cluster {
        least_conn;
        server app01.internal:8080 weight=5;
        server app02.internal:8080 weight=5;
        server app03.internal:8080 backup;
    }

    upstream api_services {
        server api01.internal:9090;
        server api02.internal:9090;
    }

    upstream database_read_pool {
        server db-read01.internal:3306;
        server db-read02.internal:3306;
    }

    server {
        listen 80;
        server_name app.example.com;
        location / {
            proxy_pass http://application_cluster;
        }
    }

    server {
        listen 8080;
        server_name api.example.com;
        location / {
            proxy_pass http://api_services;
        }
    }

    server {
        listen 3307;
        server_name db-proxy.example.com;
        location /read {
            proxy_pass http://database_read_pool;
        }
    }
}

Gateway Authentication Implementation

Spring Cloud Gateway implements security through custom filter chains operating on the reactive web stack. The architecture employs Global Filters for cross-cutting concerns like JWT validation and route-specific filters for granular access control.

Implementation Mechanism:

  1. Filter Chain Architecture: Requests traverse ordered filters implementing GatewayFilter interface, enabling pre-processing (authentication) and post-processing (logging) operations.

  2. Token Validation Logic: Custom filters extract credentials from headers or query parameters, verify signatures against authorization servers, and inject security context into request attributes.

@Component
public class JwtValidationFilter extends AbstractGatewayFilterFactory<JwtValidationFilter.Config> {

    public static class Config {
        private String headerName = "Authorization";
        private String prefix = "Bearer ";
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String authHeader = request.getHeaders().getFirst(config.headerName);
            
            if (authHeader == null || !authHeader.startsWith(config.prefix)) {
                return unauthorizedResponse(exchange);
            }
            
            String token = authHeader.substring(config.prefix.length());
            if (!validateTokenSignature(token)) {
                return unauthorizedResponse(exchange);
            }
            
            ServerHttpRequest mutatedRequest = exchange.getRequest()
                .mutate()
                .header("X-User-Id", extractUserId(token))
                .build();
                
            return chain.filter(exchange.mutate().request(mutatedRequest).build());
        };
    }

    private Mono<Void> unauthorizedResponse(ServerWebExchange exchange) {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }
}

Sentinel Rate Limiting Principles

Sentinel implements flow control through sliding window counting algorithms and dynamic rule management. The architecture separates statistics collection from decision logic through slot chain processing.

Core Mechanisms:

  • Sliding Window Algorithm: Time windows divide into granular buckets tracking request counts. Sentinel aggregates statistics across recent buckets to determine threshold violations, preventing sudden traffic spikes.

  • Slot Chain Processing: Requests pass through processor slots including NodeSelectorSlot (building invocation trees), ClusterBuilderSlot (cluster node aggregation), StatisticSlot (metrics recording), and FlowSlot (rule enforcement).

  • Adaptive Strategies: When thresholds breach, Sentinel executes configured control behaviors including immediate rejection, warm-up pacing (gradual traffic acceptance), uniform rate spacing (queuing), or system adaptive protection (load-based throttling).

Dynamic Configuration with Nacos

Nacos Configuration Center enables externalized configuration management with real-time push capabilities. Services subscribe to configuration changes through long polling mechanisms, receiving immediate updates when administrators modify properties through the console.

Integration patterns include:

  • Shared Configurations: Common properties across microservices (database connection pools, logging levels)
  • Extension Configs: Environment-specific overrides (dev/staging/production)
  • Namespace Isolation: Logical grouping preventing configuration leakage between tenants

Configuration changes propagate through Spring Cloud's @RefreshScope mechanism, reloading beans without service restarts.

Production Issue Resolution Case Studies

High CPU Utilization Investigation System monitoring revealed sustained 100% CPU consumption correlating with 75-second database query latency. Root cause analysis identified missing indexes on high-cardinality columns. Resolution involved index optimization, query restructuring, and implementing read replicas to distribute analytical workloads.

Database Deadlock Resolution MySQL error logs exposed lock timeout exceptions during batch heart rate data ingestion. Original implementation validated duplicates by querying existing records (1440 daily entries per user), creating prolonged lock retention during bulk uploads. Solution redesigned the deduplication logic to operate on daily aggregation units rather than individual records, reducing lock granularity.

Network Protocol Fragmentation IoT device communication exhibited packet fragmentation during ECG data transmission. Implementation of custom Netty ByteToMessageDecoder with delimiter-based frame resolution ensured complete message reconstruction before business logic processing.

Read-Write Separation Architecture

Database traffic splitting leverages Canal binlog parsing, Kafka streaming, and Redis caching layers. Canal monitors MySQL transaction logs, publishing row changes to Kafka topics. Consumer applications transform and persist data to Redis, serving as the primary query interface.

Advantages over Native Replication:

  1. Data Transformation: Heterogeneous wearable devices (varying protocols and data formats) normalize during the Canal-to-Kafka pipeline, standardizing heart rate as integers and blood oxygen as floats before storage.

  2. Unified Query Interface: Applications retrieve standardized data from Redis regardless of originating device type, eliminating device-specific database routing logic.

  3. Stream Processing: Kafka enables real-time data cleansing and enrichment during replication, unlike passive database replication.

Redis Caching Anomalies and Mitigation

Cache Penetration Occurs when queries target non-existent keys, bypassing cache to bombard databases. Mitigation strategies include:

  • Bloom filters pre-validating key existence
  • Null value caching with short TTL
  • API authentication preventing malicious enumeration

Cache Breakdown High-traffic keys expiring simultaneously causes database stampede. Solutions implement:

  • Distributed locks (Redisson) ensuring single database query during reconstruction
  • Logical expiration with background refresh threads
  • Randomized TTL preventing synchronized expiry

Cache Avalanche Mass simultaneous expiration across keyspace. Prevention includes:

  • Staggered expiration timestamps
  • Cache warming during low-traffic periods
  • Circuit breakers temporarily rejecting excess load
  • Redis Cluster deployment eliminating single points of failure

JVM Object Promotion and Memory Management

Minor GC Promotion Criteria Objects surviving Eden space scavenging migrate to Survivor regions. Promotion to Tenured generation depends on:

  • Age Thresholding: Default MaxTenuringThreshold (15) defines Minor GC survival iterations before old generation promotion. Dynamic age adjustment occurs based on survivor space occupancy.

  • Size-Based Promotion: Objects exceeding PretenureSizeThreshold (default disabled) bypass young generation, allocating directly in old space when larger then survivor regions.

  • Survivor Space Exhaustion: When To-Survivor cannot accommodate live objects from From-Survivor and Eden, objects promote prematurely regardless of age.

Configuration parameters:

-XX:MaxTenuringThreshold=15
-XX:PretenureSizeThreshold=1048576  # 1MB threshold
-XX:SurvivorRatio=8  # Eden:Survivor ratio

JVM Runtime Data Areas

Program Counter Register: Thread-isolated pointer tracking current bytecode execution address. Critical for context switching and native method differentiation.

Java Virtual Machine Stack: Thread-private frames containing local variables, operand stacks, and dynamic links. Method invocations push frames; returns pop them.

Native Method Stack: Analogous to JVM stacks but serving native method executions (C/C++ implementations).

Heap: Shared runtime data area hosting object instances and arrays. Partitioned into:

  • Young Generation (Eden + Survivor0 + Survivor1): Copying algorithm collection
  • Old Generation: Mark-Compact or Mark-Sweep algorithms

Metaspace (Java 8+): Stores class metadata, constants, and static variables. Replaces Permanent Generation with native memory allocation, eliminating OutOfMemoryError: PermGen.

Garbage Collection Algorithms

Mark-Sweep: Identifies live objects through GC Root reachability (stack references, static fields, native handles), clearing unreachable memory. Produces fragmentation requiring compaction.

Copying: Divides space into equal semispaces. Live objects copy to empty space during collection, clearing source space. Eliminates fragmentation at 50% capacity cost.

Mark-Compact: Marking phase identifies survivors; compacting phase shifts live objects to memory region boundaries, creating contiguous free blocks. Suitable for old generation stability.

Generational Collection: Exploits weak generational hypothesis (most objects die young). Young generation uses copying; old generation uses mark-sweep-compact or concurrent mark-sweep (CMS).

G1 Garbage Collector: Regions-based heap organization. Prioritizes collection of regions with highest garbage ratios, achieving predictable pause times through incremental evacuation.

Spring Framework Architecture

Inversion of Control (IoC): Container-managed lifecycle decouples object creation from usage. Dependency Injection (constructor, setter, or field injection) provides collaborators without direct instantiation.

Aspect-Oriented Programming (AOP): Cross-cutting concerns (transaction management, auditing, security) modularize through advisors and pointcuts. JDK dynamic proxies (interface-based) or CGLIB subclassing (concrete classes) implement method interception.

Template Pattern: JdbcTemplate, JmsTemplate abstract boilerplate resource management (connection acquisition, exception translation), allowing business logic focus.

Observer Pattern: ApplicationEvent multicasters notify registered listeners of state changes, enabling decoupled component interaction.

Spring Boot vs. Spring Framwork

Spring Boot accelerates Spring application development through:

  • Auto-configuration: Classpath inspection automatically configures beans (DataSource, EntityManagerFactory) based on detected libraries.
  • Embedded Containers: Integrated Tomcat/Jetty/Undertow eliminates WAR deployment requirements.
  • Starter Dependencies: Aggregated POMs (spring-boot-starter-web) resolve transitive dependency compatibility.
  • Production Features: Actuator endpoints expose health metrics, configuration properties, and runtime environment details.

Traditional Spring requires explicit XML or Java configuration for component wiring, while Spring Boot favors convention over configuration with @SpringBootApplication enabling component scanning and auto-configuration.

Spring MVC Request Processing Flow

  1. DispatcherServlet receives HTTP requests via front controller pattern
  2. HandlerMapping resolves URL patterns to controller methods via @RequestMapping metadata
  3. HandlerAdapter invokes controller methods, converting request parameters to method arguments through HttpMessageConverters
  4. Controller executes business logic, returning ModelAndView or ResponseEntity
  5. ViewResolver maps logical view names to template engines (Thymeleaf, FreeMarker) or JSON serialization
  6. View renders response content with model data

Exception handling occurs through @ControllerAdvice annotated classes with @ExceptionHandler methods intercepting thrown exceptions before view resolution.

Spring Cloud Microservices Toolkit

Service Discovery: Nacos or Eureka maintains service registries enabling client-side load balancing.

Circuit Breaking: Sentinel or Resilience4j isolates failing dependencies, preventing cascade failures through fallback methods.

API Gateway: Spring Cloud Gateway (reactive) or Zuul (servlet-based) handles cross-cutting concerns (authentication, rate limiting, request transformation) at edge layer.

Distributed Tracing: Sleuth injects trace IDs into logging context; Zipkin aggregates span data visualizing request latencies across service boundaries.

Config Server: Centralized external configuration with Git or Nacos backends, supporting dynamic property refresh via Spring Cloud Bus.

Circular Dependency Resolution

Spring resolves field/setter injection circularities through three-tier caching:

  1. singletonObjects: Completed bean instances ready for use
  2. earlySingletonObjects: Instantiated but uninitialized beans (exposed for reference resolution)
  3. singletonFactories: Object factories generating early references

When creating Bean A requiring Bean B, while Bean B requires Bean A:

  • Bean A instantiates and enters earlySingletonObjects
  • Bean B instantiation retrieves Bean A from earlySingletonObjects
  • Bean B completes initialization; Bean A finishes wiring

Limitation: Constructor injection circular dependencies remain unsolvable because instantiation requires all dependencies present, creating unresolvable deadlock. Spring throws BeanCurrentlyInCreationException for constructor wiring cycles.

Seata Distributed Transaction Protocol

Seata implements AT (Automatic Transaction) mode providing ACID guarantees across microservices.

Architecture Components:

  • Transaction Coordinator (TC): Global transaction state manager, driving commit/rollback decisions
  • Transaction Manager (TM): Application-embedded component defining global transaction boundaries via @GlobalTransactional
  • Resource Manager (RM): Branch transaction handler coordinating local resources with TC

Two-Phase Commit Process:

Phase One: RM intercepts SQL execution via JDBC proxy, parsing statements to generate before/after image snapshots (undo logs). Local transaction commits immediately while reporting status to TC.

Phase Two:

  • Success: TC releases global locks asynchronously, scheduling RM undo log cleanup
  • Failure: TC triggers compensation, applying undo logs to restore pre-transaction states

Common Memory Leak Sources

Static Collection Accumulation: Class-level collections (static List, static Map) retain references indefinitely, preventing garbage collection of added objects despite method scope completion.

Singleton External References: Singleton pattern objects holding references to short-lived instances (contexts, request-scoped data) prevent those instances' collection throughout application lifecycle.

Unclosed Resources: Database connections, file streams, or socket channels remaining open after use exhaust native and heap memory. Always employ try-with-resources or explicit close() in finally blocks.

Mutable HashCodes: Objects used as HashMap keys modifying fields affecting hashCode() calculation become unreachable for removal. String immutability prevents this issue.

ThreadLocal Abandonment: ThreadLocal variables without remove() calls persist across thread pool reuse (thread recycling in pools), causing value accumulation. Explicit cleanup in finally blocks essential.

Tags: java Spring Cloud microservices JVM Redis

Posted on Tue, 19 May 2026 01:38:50 +0000 by cody44