<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Coding Shuttle Blogs</title>
        <link>https://www.codingshuttle.com/blogs</link>
        <description>Stay up-to-date with the latest news and trends in software development and programming from Coding Shuttle.</description>
        <lastBuildDate>Fri, 08 May 2026 15:11:33 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Coding Shuttle Blogs</title>
            <url>https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/white_circle_5b59b3bf7f.png</url>
            <link>https://www.codingshuttle.com/blogs</link>
        </image>
        <copyright>All rights reserved 2026, Coding Shuttle</copyright>
        <atom:link href="https://www.codingshuttle.com/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Master Redis and Caching – A Practical Guide for Modern Backend Development]]></title>
            <link>https://www.codingshuttle.com/blogs/master-redis-and-caching-a-practical-guide-for-modern-backend-development</link>
            <guid>https://www.codingshuttle.com/blogs/master-redis-and-caching-a-practical-guide-for-modern-backend-development</guid>
            <pubDate>Tue, 31 Mar 2026 10:18:28 GMT</pubDate>
            <description><![CDATA[This Redis & Caching Cheatsheet explains how caching works and how Redis is used to build fast, scalable systems. It covers Redis fundamentals, core data structures, and commonly used commands while also exploring caching strategies, persistence, replication, and clustering. The guide is designed for backend engineers, students, and anyone who wants to learn Redis, with practical explanations and real-world system design use cases.]]></description>
            <content:encoded><![CDATA[<p>Master Redis and Caching – A Practical Guide for Modern Backend Development</p><p>Caching is one of the most important techniques used to build <strong>high-performance and scalable systems</strong>. Instead of repeatedly querying slow databases, applications store frequently accessed data in a fast in-memory store like <strong>Redis</strong>, dramatically improving response time and reducing database load.</p><p>Redis has become one of the most widely used technologies in modern backend architectures because of its <strong>speed, simplicity, and powerful data structures</strong>. From session storage and API caching to rate limiting and real-time analytics, Redis plays a key role in handling large-scale traffic efficiently.</p><p>This guide explains the <strong>core concepts of caching and Redis</strong>, including caching strategies, Redis data structures, essential commands, eviction policies, and common production patterns used in scalable systems. Whether you're learning backend engineering or preparing for system design interviews, understanding Redis and caching is a must-have skill.</p><hr><h2>1. Caching Fundamentals</h2><h3>What is Caching</h3><p>Caching is storing a copy of frequently accessed data in a faster storage layer so future requests can be served without going back to the original, slower source. The core idea is simple: if you already computed or fetched something expensive, save it temporarily so the next request gets it instantly.</p><h3>Why Caching is Needed</h3><p>Every system eventually hits a wall where the database becomes the bottleneck. When thousands of users hit the same endpoint simultaneously, querying the database for every request is wasteful and slow. Caching solves this by absorbing repeated reads.</p><p>Problems caching directly addresses:</p><ul><li><strong>Database latency</strong>: A typical PostgreSQL query takes 20-100ms. Redis responds in under 1ms. For read-heavy workloads, that difference is enormous.</li><li><strong>High traffic spikes</strong>: A viral post, a flash sale, a live event — these create sudden traffic bursts that databases struggle to handle. A cache absorbs the load.</li><li><strong>Repeated identical queries</strong>: Fetching the same product details, user profile, or config values thousands of times per second makes no sense. Cache it once, serve it many times.</li></ul><h3>Cache Hit vs Cache Miss</h3><ul><li><strong>Cache hit</strong>: The requested data exists in the cache. Serve it directly. Fast, cheap, ideal.</li><li><strong>Cache miss</strong>: The data is not in the cache. Fall through to the database, fetch it, optionally store it in the cache for next time.</li></ul><p><strong>Hit rate</strong> is the key metric. A 95% hit rate means only 5% of requests touch the database. In high-traffic systems, even a 1% improvement in hit rate can significantly reduce database load.</p><h3>Cache vs Database</h3><figure class="table"><table><thead><tr><th>Attribute</th><th>Cache (Redis)</th><th>Database (Postgres/MySQL)</th></tr></thead><tbody><tr><td>Speed</td><td>Sub-millisecond</td><td>10–100ms+</td></tr><tr><td>Storage type</td><td>In-memory</td><td>Disk-based</td></tr><tr><td>Data size</td><td>Limited by RAM</td><td>Effectively unlimited</td></tr><tr><td>Durability</td><td>Optional</td><td>Strong by default</td></tr><tr><td>Query power</td><td>Key-based lookups</td><td>Full SQL queries</td></tr><tr><td>Use case</td><td>Repeated reads</td><td>Source of truth</td></tr></tbody></table></figure><h3>Where Caching is Used in Real Systems</h3><ul><li>User session data</li><li>Product catalog and pricing</li><li>Homepage feed or trending content</li><li>Auth tokens and permissions</li><li>Rate limit counters</li><li>Search results</li><li>Computed aggregations (dashboards, leaderboards)</li></ul><hr><h2>2. Types of Caching</h2><h3>Client-Side Caching</h3><p>The browser or mobile app stores responses locally. HTTP cache headers (<code>Cache-Control</code>, <code>ETag</code>, <code>Expires</code>) control this. Good for static assets, infrequently changing API responses.</p><p><strong>Example</strong>: A user's browser caches a product image for 24 hours. No network request is made on repeated visits.</p><h3>CDN Caching</h3><p>Content Delivery Networks cache content at edge locations geographically close to users. CDNs like Cloudflare, Fastly, and AWS CloudFront cache HTML pages, images, JS/CSS bundles.</p><p><strong>Example</strong>: A news article cached at 200 edge locations globally. A user in Mumbai gets content from the nearest edge node, not from the origin server in the US.</p><h3>Application-Level Caching</h3><p>The application server maintains a cache in-process (local memory) or via an external cache like Redis. This is where most backend engineering decisions happen.</p><p><strong>Example</strong>: An Express.js or Django app caching database query results in Redis before returning them to the client.</p><h3>Database Caching</h3><p>Databases have internal caches (buffer pools, query caches). MySQL's InnoDB buffer pool caches frequently accessed pages. This is mostly automatic and not directly controlled by application engineers.</p><h3>Distributed Caching</h3><p>When you run multiple application servers, a single in-process cache does not work — each server has its own memory. A distributed cache like Redis sits outside all app servers as a shared cache that every server reads from and writes to.</p><p><strong>Example</strong>: A fleet of 20 API servers all reading from the same Redis cluster. Consistent cache state across all nodes.</p><hr><h2>3. Introduction to Redis</h2><h3>What Redis Is</h3><p>Redis (Remote Dictionary Server) is an open-source, in-memory data structure store. It functions as a cache, database, and message broker. Unlike a simple key-value store, Redis supports rich data structures: strings, hashes, lists, sets, sorted sets, streams, and more.</p><p>Created by Salvatore Sanfilippo in 2009, Redis became the default caching layer for production systems at companies like Twitter, GitHub, Stack Overflow, and Airbnb.</p><h3>Why Redis Became the Industry Standard</h3><ul><li>Extremely fast: sub-millisecond response times at scale</li><li>Simple mental model: keys map to values, values can be complex structures</li><li>Atomic operations: counters, queues, leaderboards without race conditions</li><li>Built-in expiration: TTLs make cache management straightforward</li><li>Persistence options: optional durability for more than just ephemeral caching</li><li>Cluster support: horizontal scaling built into the server</li></ul><h3>Redis vs Traditional Databases</h3><figure class="table"><table><thead><tr><th>Feature</th><th>Redis</th><th>Traditional RDBMS</th></tr></thead><tbody><tr><td>Storage</td><td>In-memory (optional disk)</td><td>Disk-primary</td></tr><tr><td>Query model</td><td>Key-based</td><td>SQL with indexes</td></tr><tr><td>Speed</td><td>Sub-millisecond</td><td>10–100ms</td></tr><tr><td>Schema</td><td>Schema-less</td><td>Structured schema</td></tr><tr><td>Joins</td><td>Not supported</td><td>Full join support</td></tr><tr><td>Persistence</td><td>Optional (RDB/AOF)</td><td>Always durable</td></tr><tr><td>Best for</td><td>Caching, real-time ops</td><td>Transactional data</td></tr></tbody></table></figure><hr><h2>4. Why Redis is Fast</h2><p>Redis achieves exceptional performance through a combination of architectural decisions:</p><ul><li><strong>In-memory storage</strong>: All data lives in RAM. No disk seeks, no I/O waits. RAM access is orders of magnitude faster than disk.</li><li><strong>Single-threaded event loop</strong>: Redis processes one command at a time using a non-blocking I/O event loop (similar to Node.js). No lock contention, no thread context switching.</li><li><strong>Efficient data structures</strong>: Redis data structures are carefully optimized in C. A sorted set uses a skip list + hash map combo for O(log N) operations.</li><li><strong>Minimal network overhead</strong>: Redis uses a simple text-based protocol (RESP). Commands are compact and parsed fast.</li><li><strong>No disk I/O on reads/writes</strong>: By default, reads and writes happen entirely in memory. Persistence writes (RDB/AOF) happen asynchronously and don't block command processing.</li></ul><h3>Redis Request Processing Model</h3><pre><code class="language-ruby">Client sends command
    --&gt; Kernel receives data (TCP)
    --&gt; Redis event loop picks it up
    --&gt; Command parsed and executed in memory
    --&gt; Response written back to client
</code></pre><p>The entire cycle happens in microseconds. There is no thread pool, no connection thread per client — just a single loop handling all I/O via epoll/kqueue.</p><hr><h2>5. Redis Architecture</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Redis_architecture_682b39ab97.webp" alt="Redis architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Redis_architecture_682b39ab97.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Redis_architecture_682b39ab97.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Redis_architecture_682b39ab97.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Redis_architecture_682b39ab97.webp 1000w," sizes="100vw"><figcaption>Redis architecture</figcaption></figure><h3>Core Components</h3><ul><li><strong>Redis Server</strong>: The process that holds all data in memory and handles all commands</li><li><strong>Redis Client</strong>: Any application connecting over TCP (redis-cli, application libraries like ioredis, Jedis, redis-py)</li><li><strong>Event Loop</strong>: Single-threaded loop that handles all client connections, reads commands, executes them, sends responses</li><li><strong>In-memory store</strong>: The actual data — organized as a hash table of key-value pairs at the top level</li><li><strong>Persistence layer</strong>: Optional background processes writing RDB snapshots or AOF logs to disk</li></ul><hr><h2>6. Redis Installation and Setup</h2><h3>Installing Redis</h3><pre><code class="language-ruby"># Ubuntu/Debian
sudo apt install redis-server

# macOS
brew install redis

# Docker
docker run -d -p 6379:6379 redis
</code></pre><h3>Running and Connecting</h3><pre><code class="language-ruby"># Start Redis server
redis-server

# Connect via CLI
redis-cli

# Test connection
PING
# Returns: PONG

# Connect to remote host
redis-cli -h 127.0.0.1 -p 6379 -a yourpassword
</code></pre><h3>Basic Configuration (<code>redis.conf</code>)</h3><pre><code class="language-php">bind 127.0.0.1
port 6379
maxmemory 256mb
maxmemory-policy allkeys-lru
requirepass yourpassword
</code></pre><hr><h2>7. Redis Key Concepts</h2><h3>Keys and Values</h3><p>Every piece of data in Redis has a key (always a string) and a value (can be one of several data types). Keys are case-sensitive. There is no implicit hierarchy — namespacing is a naming convention only.</p><h3>Key Naming Conventions</h3><p>Use colon-separated namespaces. This keeps keys readable and avoids collisions across different parts of your application.</p><pre><code class="language-ruby">user:profile:123
product:price:567
order:details:9812
session:token:abc123
rate:limit:user:456
</code></pre><h3>TTL (Time to Live)</h3><p>Every key can have an expiration time. Once expired, Redis automatically deletes the key. This is how you prevent stale data from accumulating.</p><pre><code class="language-ruby">SET user:session:123 "data"
EXPIRE user:session:123 3600        # expires in 1 hour

# Or set with TTL in one command
SET user:session:123 "data" EX 3600

# Check remaining TTL
TTL user:session:123
# Returns: seconds remaining, -1 (no expiry), -2 (key doesn't exist)
</code></pre><hr><h2>8. Redis Data Structures</h2><h3>Strings</h3><p>The most basic type. Can hold text, numbers, serialized JSON, or binary data up to 512MB.</p><p><strong>When to use</strong>: Session tokens, counters, simple cached values, feature flags.</p><pre><code class="language-ruby">SET user:name "Alice"
GET user:name

# Atomic counter (no race condition)
INCR page:views
DECR inventory:item:42

# Append
APPEND log:entry "new line"
</code></pre><p><strong>Real-world example</strong>: Storing a serialized JSON object for a user profile. Fast reads, no joins needed.</p><h3>Hashes</h3><p>A hash maps field names to values inside a single key. Think of it as a row in a database table — one key, multiple attributes.</p><p><strong>When to use</strong>: Storing objects with multiple attributes. More memory-efficient than storing each field as a separate key.</p><pre><code class="language-ruby">HSET user:100 name "Alice" age 25 city "Mumbai"
HGET user:100 name
HGETALL user:100
HDEL user:100 city
HINCRBY user:100 age 1
</code></pre><p><strong>Real-world example</strong>: User profile data where you need to update individual fields without rewriting the whole object.</p><h3>Lists</h3><p>An ordered list of strings. Elements can be added or removed from both ends. Internally a linked list.</p><p><strong>When to use</strong>: Task queues, recent activity feeds, message queues, job queues.</p><pre><code class="language-ruby">LPUSH tasks "task1"         # add to front
RPUSH tasks "task2"         # add to back
LPOP tasks                  # remove from front
LRANGE tasks 0 -1           # get all elements
LLEN tasks                  # count elements
</code></pre><p><strong>Real-world example</strong>: A background job queue. Workers LPOP from the list. Producers RPUSH new jobs.</p><p><strong>Trade-off</strong>: LRANGE on large lists is O(N). Avoid storing unbounded lists without trimming via LTRIM.</p><h3>Sets</h3><p>An unordered collection of unique strings. Duplicate inserts are silently ignored.</p><p><strong>When to use</strong>: Tracking unique visitors, tags, relationships (followers/following), deduplication.</p><pre><code class="language-ruby">SADD tags "redis" "cache" "backend"
SMEMBERS tags
SISMEMBER tags "redis"      # check membership
SCARD tags                  # count members

# Set operations
SUNION tags1 tags2          # union
SINTER tags1 tags2          # intersection
SDIFF tags1 tags2           # difference
</code></pre><p><strong>Real-world example</strong>: Storing user IDs who have seen a notification. SISMEMBER in O(1) to check if a user already saw it.</p><h3>Sorted Sets</h3><p>Like sets, but every member has a score (floating point). Members are always sorted by score. Allows range queries by rank or score.</p><p><strong>When to use</strong>: Leaderboards, priority queues, rate limiting sliding windows, time-series data indexed by timestamp.</p><pre><code class="language-ruby">ZADD leaderboard 100 "player1"
ZADD leaderboard 250 "player2"
ZADD leaderboard 75  "player3"

ZRANGE leaderboard 0 -1 WITHSCORES   # ascending
ZREVRANGE leaderboard 0 2             # top 3
ZRANK leaderboard "player1"           # rank of player
ZINCRBY leaderboard 50 "player1"      # add to score
</code></pre><p><strong>Real-world example</strong>: A gaming leaderboard updated in real-time. ZREVRANGE gives you the top N players instantly.</p><h3>Bitmaps</h3><p>Not a separate type — Bitmaps are strings where individual bits are addressed. Extremely memory-efficient for binary data at scale.</p><p><strong>When to use</strong>: Tracking daily active users, feature flags per user ID, presence tracking.</p><pre><code class="language-ruby">SETBIT user:active:2024-01-15 1001 1   # user 1001 was active on Jan 15
GETBIT user:active:2024-01-15 1001
BITCOUNT user:active:2024-01-15        # count active users that day
</code></pre><p><strong>Real-world example</strong>: 100 million users tracked for daily activity costs only 12MB in bitmap form.</p><h3>HyperLogLog</h3><p>A probabilistic data structure for counting unique elements with very low memory usage. Trades a small error margin (~0.81%) for massive memory savings.</p><p><strong>When to use</strong>: Counting unique visitors, unique search queries, approximate cardinality at scale.</p><pre><code class="language-ruby">PFADD unique:visitors "user1" "user2" "user3"
PFCOUNT unique:visitors      # approximate unique count
PFMERGE combined key1 key2   # merge two HyperLogLogs
</code></pre><p><strong>Real-world example</strong>: Counting unique page views. Storing 1 billion unique IDs exactly would take gigabytes. HyperLogLog does it in 12KB.</p><h3>Streams</h3><p>An append-only log data structure. Supports consumer groups for distributed message processing.</p><p><strong>When to use</strong>: Event sourcing, message queues, activity logs, real-time data pipelines.</p><pre><code class="language-ruby">XADD mystream * event "order_created" order_id "456"
XREAD STREAMS mystream 0
XLEN mystream
</code></pre><hr><h2>9. Core Redis Commands Reference</h2><h3>String Commands</h3><pre><code class="language-ruby">SET key value
SET key value EX 3600        # with expiry
GET key
MSET k1 v1 k2 v2             # multi-set
MGET k1 k2                   # multi-get
INCR counter
INCRBY counter 5
DECR counter
DEL key
EXISTS key
</code></pre><h3>Hash Commands</h3><pre><code class="language-ruby">HSET user:1 name "Alice" age 25
HGET user:1 name
HMGET user:1 name age
HGETALL user:1
HDEL user:1 age
HKEYS user:1
HVALS user:1
HINCRBY user:1 age 1
</code></pre><h3>List Commands</h3><pre><code class="language-ruby">LPUSH queue "task1"
RPUSH queue "task2"
LPOP queue
RPOP queue
LRANGE queue 0 -1
LLEN queue
LTRIM queue 0 99             # keep only first 100 elements
BLPOP queue 30               # blocking pop, wait 30 seconds
</code></pre><h3>Set Commands</h3><pre><code class="language-ruby">SADD users "user1" "user2"
SMEMBERS users
SISMEMBER users "user1"
SCARD users
SREM users "user1"
SUNION set1 set2
SINTER set1 set2
</code></pre><h3>Sorted Set Commands</h3><pre><code class="language-ruby">ZADD leaderboard 100 "player1"
ZRANGE leaderboard 0 -1
ZREVRANGE leaderboard 0 -1
ZRANK leaderboard "player1"
ZREVRANK leaderboard "player1"
ZSCORE leaderboard "player1"
ZINCRBY leaderboard 10 "player1"
ZRANGEBYSCORE leaderboard 50 200
</code></pre><hr><h2>10. Caching Strategies</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/caching_strategies_6006ad7d38.webp" alt="Four Caching Strategies" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_caching_strategies_6006ad7d38.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_caching_strategies_6006ad7d38.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_caching_strategies_6006ad7d38.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_caching_strategies_6006ad7d38.webp 1000w," sizes="100vw"><figcaption>Four Caching Strategies</figcaption></figure><h3>Cache Aside (Lazy Loading)</h3><p>The application manages the cache. On read, check cache first. On miss, fetch from DB and write to cache. On write, update the DB and invalidate or update the cache.</p><p><strong>How it works</strong>:</p><ol><li>Read request comes in</li><li>Check Redis — if hit, return data</li><li>If miss, query database</li><li>Write result to Redis with TTL</li><li>Return data to client</li></ol><pre><code class="language-php"># Pseudocode flow
value = redis.get("user:100")
if value is None:
    value = db.query("SELECT * FROM users WHERE id = 100")
    redis.set("user:100", value, ex=3600)
return value
</code></pre><p><strong>When to use</strong>: Read-heavy workloads, data that can tolerate brief staleness, general-purpose caching.</p><p><strong>Pros</strong>: Only caches what is actually requested, resilient to cache failures.</p><p><strong>Cons</strong>: First request always misses (cache cold start), potential for stale data if DB updates don't invalidate cache.</p><h3>Write Through</h3><p>On every write to the database, simultaneously write to the cache. Cache is always up to date.</p><p><strong>How it works</strong>:</p><ol><li>Application writes data</li><li>Write to Redis AND database in the same operation</li><li>Reads always hit the cache</li></ol><p><strong>When to use</strong>: Data that is written and then immediately read back, systems where stale cache is unacceptable.</p><p><strong>Pros</strong>: Cache is always fresh, no stale reads.</p><p><strong>Cons</strong>: Every write hits both systems — higher write latency, cache fills with data that may never be read.</p><h3>Write Behind (Write Back)</h3><p>Write to cache immediately. Write to database asynchronously (batched or delayed).</p><p><strong>How it works</strong>:</p><ol><li>Application writes to Redis only</li><li>Background worker flushes cache changes to DB periodically</li></ol><p><strong>When to use</strong>: Write-heavy workloads where write latency is critical (e.g., analytics counters, click tracking).</p><p><strong>Pros</strong>: Very low write latency, write batching reduces DB load.</p><p><strong>Cons</strong>: Risk of data loss if cache crashes before flush. Complex to implement correctly.</p><h3>Refresh Ahead</h3><p>Cache proactively refreshes entries before they expire, based on predicted access patterns.</p><p><strong>How it works</strong>: Before a key's TTL hits zero, a background job refetches and re-caches the value.</p><p><strong>When to use</strong>: Predictable access patterns, content that must never go stale (e.g., homepage data, config values).</p><p><strong>Pros</strong>: No cache misses for hot data.</p><p><strong>Cons</strong>: Wastes resources refreshing data that might never be requested again.</p><hr><h2>11. Cache Eviction Policies</h2><p>When Redis reaches its <code>maxmemory</code> limit, it needs to evict keys. The policy controls which keys get removed.</p><figure class="table"><table><thead><tr><th>Policy</th><th>Behavior</th><th>When to use</th></tr></thead><tbody><tr><td><code>noeviction</code></td><td>Returns error when memory is full</td><td>When you must never lose data</td></tr><tr><td><code>allkeys-lru</code></td><td>Evicts least recently used keys from all keys</td><td>General-purpose cache</td></tr><tr><td><code>volatile-lru</code></td><td>Evicts LRU keys only among keys with TTL set</td><td>Mixed cache + persistent data</td></tr><tr><td><code>allkeys-lfu</code></td><td>Evicts least frequently used keys</td><td>Skewed access patterns</td></tr><tr><td><code>volatile-lfu</code></td><td>Evicts LFU keys only among keys with TTL</td><td>Similar to volatile-lru but frequency</td></tr><tr><td><code>allkeys-random</code></td><td>Evicts random keys</td><td>Rarely useful</td></tr><tr><td><code>volatile-ttl</code></td><td>Evicts keys with the shortest TTL first</td><td>When TTL reflects priority</td></tr></tbody></table></figure><p><strong>Production recommendation</strong>: <code>allkeys-lru</code> for pure caches. <code>volatile-lru</code> when Redis serves both cache and persistent storage roles.</p><pre><code class="language-ruby"># Set in redis.conf
maxmemory 512mb
maxmemory-policy allkeys-lru
</code></pre><hr><h2>12. Redis Persistence</h2><p>Redis is in-memory, but it offers two persistence mechanisms for durability.</p><h3>RDB (Redis Database Snapshots)</h3><p>Periodic point-in-time snapshots of the entire dataset written to disk. Redis forks a child process to write the dump.</p><pre><code class="language-ruby"># In redis.conf
save 900 1       # save if at least 1 key changed in 900 seconds
save 300 10      # save if 10 keys changed in 300 seconds
save 60 10000    # save if 10000 keys changed in 60 seconds

# Manual snapshot
BGSAVE
</code></pre><h3>AOF (Append Only File)</h3><p>Logs every write command to a file. On restart, Redis replays the log to reconstruct state.</p><pre><code class="language-ruby"># In redis.conf
appendonly yes
appendfsync everysec    # flush to disk every second (balanced)
# appendfsync always    # flush every command (safest, slowest)
# appendfsync no        # let OS decide (fastest, least safe)
</code></pre><h3>RDB vs AOF</h3><figure class="table"><table><thead><tr><th>Feature</th><th>RDB</th><th>AOF</th></tr></thead><tbody><tr><td>Performance</td><td>Faster (periodic)</td><td>Slightly slower</td></tr><tr><td>Durability</td><td>Can lose minutes of data</td><td>Lose at most 1 second</td></tr><tr><td>File size</td><td>Compact binary</td><td>Larger, grows over time</td></tr><tr><td>Recovery speed</td><td>Fast (load binary snapshot)</td><td>Slower (replay commands)</td></tr><tr><td>Use case</td><td>Backups, fast restarts</td><td>Strong durability required</td></tr></tbody></table></figure><p><strong>Production recommendation</strong>: Use both. RDB for fast restarts and backups, AOF for durability.</p><hr><h2>13. Redis Replication</h2><p>Redis supports master-replica (formerly master-slave) replication. The replica receives a full copy of data from the master and then streams incremental updates.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Redis_master_replica_replication_bd6b46117d.webp" alt="Redis master-replica replication" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Redis_master_replica_replication_bd6b46117d.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Redis_master_replica_replication_bd6b46117d.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Redis_master_replica_replication_bd6b46117d.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Redis_master_replica_replication_bd6b46117d.webp 1000w," sizes="100vw"><figcaption>Redis master-replica replication</figcaption></figure><h3>How Replication Works</h3><ol><li>Replica connects to master and sends <code>REPLICAOF</code> command</li><li>Master sends full RDB snapshot to replica</li><li>Replica loads snapshot, then receives and applies ongoing write commands</li><li>Replicas serve read requests, master handles all writes</li></ol><pre><code class="language-ruby"># On replica node
REPLICAOF master-host 6379

# Check replication status
INFO replication
</code></pre><h3>When to Use Replication</h3><ul><li>Scale read traffic across multiple replicas</li><li>Provide a hot standby for failover</li><li>Offload analytics queries to replicas</li></ul><p><strong>Important</strong>: Replication is asynchronous by default. A replica may lag slightly behind the master. For critical reads, always read from the master.</p><hr><h2>14. Redis Cluster</h2><p>Redis Cluster provides horizontal scaling by sharding data across multiple nodes.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Redis_cluster_with_multiple_nodes_c201cfac60.webp" alt="Redis cluster with multiple nodes" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Redis_cluster_with_multiple_nodes_c201cfac60.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Redis_cluster_with_multiple_nodes_c201cfac60.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Redis_cluster_with_multiple_nodes_c201cfac60.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Redis_cluster_with_multiple_nodes_c201cfac60.webp 1000w," sizes="100vw"><figcaption>Redis cluster with multiple nodes</figcaption></figure><h3>How It Works</h3><ul><li>Redis divides the key space into <strong>16,384 hash slots</strong></li><li>Each master node owns a range of hash slots</li><li>A key's slot is computed as: <code>CRC16(key) % 16384</code></li><li>Clients are redirected to the correct node for each key</li></ul><pre><code class="language-ruby"># Minimal 3-master cluster
redis-cli --cluster create \\
  127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 \\
  --cluster-replicas 1

# Check cluster info
CLUSTER INFO
CLUSTER NODES
</code></pre><h3>Key Considerations</h3><ul><li>Keys that need to go to the same slot use hash tags: <code>{user:100}:profile</code> and <code>{user:100}:settings</code> land on the same node</li><li>Multi-key commands (MGET, MSET) only work if all keys hash to the same slot</li><li>Minimum recommended setup: 3 masters with 3 replicas for high availability</li></ul><hr><h2>15. Redis Pub/Sub</h2><p>Redis Pub/Sub implements the publish-subscribe messaging pattern. Publishers send messages to channels. Subscribers receive all messages on channels they are subscribed to. No message persistence — if a subscriber is offline, it misses the message.</p><pre><code class="language-ruby"># Terminal 1 - Subscriber
SUBSCRIBE notifications
SUBSCRIBE channel1 channel2   # multiple channels
PSUBSCRIBE news.*             # pattern subscription

# Terminal 2 - Publisher
PUBLISH notifications "User logged in"
PUBLISH news.sports "Match started"
</code></pre><h3>When to Use</h3><ul><li>Real-time notifications (in-app alerts, push triggers)</li><li>Live dashboard updates</li><li>Chat systems (with the understanding that messages are not persisted)</li><li>Fanout events where multiple services need to react to the same event</li></ul><h3>When Not to Use</h3><p>Pub/Sub has no message persistence and no delivery guarantees. If your subscriber process restarts, messages sent while it was down are lost. For reliable messaging, use Redis Streams instead.</p><hr><h2>16. Redis Streams</h2><p>Redis Streams is a persistent, append-only log. Unlike Pub/Sub, messages are stored and can be replayed. Supports consumer groups for distributed processing.</p><pre><code class="language-ruby"># Add to stream
XADD orders * event "order_created" order_id "789" user_id "123"

# Read from stream
XREAD COUNT 10 STREAMS orders 0

# Read only new messages
XREAD BLOCK 0 STREAMS orders $

# Consumer groups
XGROUP CREATE orders processors $ MKSTREAM
XREADGROUP GROUP processors worker1 COUNT 5 STREAMS orders &gt;
XACK orders processors &lt;message-id&gt;

# Stream info
XLEN orders
XINFO STREAM orders
</code></pre><h3>When to Use</h3><ul><li>Event-driven architectures where events need to be replayed or reprocessed</li><li>Background job queues with at-least-once delivery</li><li>Activity feeds, audit logs, order pipelines</li><li>Multiple consumers processing the same stream independently</li></ul><hr><h2>17. Rate Limiting with Redis</h2><p>Redis is the standard tool for implementing rate limiting due to its atomic operations and TTL support.</p><h3>Fixed Window</h3><p>Simplest approach. Count requests per user per time window.</p><pre><code class="language-ruby"># Increment counter for this user this minute
INCR rate:user:123:2024011510     # key includes the current minute
EXPIRE rate:user:123:2024011510 60

# Check before incrementing
GET rate:user:123:2024011510
# If count &gt;= limit, reject request
</code></pre><p><strong>Trade-off</strong>: Allows burst at window boundary. A user could make 100 requests at 11:59 and 100 at 12:00 — 200 requests in 2 seconds.</p><h3>Sliding Window (with Sorted Sets)</h3><p>More accurate. Track exact timestamps of requests using a sorted set.</p><pre><code class="language-ruby"># Add current request with timestamp as score
ZADD rate:user:123 1705312800 "request-uuid-1"

# Remove entries older than 60 seconds
ZREMRANGEBYSCORE rate:user:123 0 (now - 60)

# Count requests in window
ZCARD rate:user:123
# If count &gt;= limit, reject
</code></pre><h3>Token Bucket with Lua Script</h3><p>For production, use Lua scripts for atomic token bucket logic. This prevents race conditions between check and increment.</p><pre><code class="language-php">local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local current = redis.call('INCR', key)
if current == 1 then
    redis.call('EXPIRE', key, 60)
end
if current &gt; capacity then
    return 0
end
return 1
</code></pre><hr><h2>18. Redis in System Design</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/system_design_and_Redis_eee6a78f0d.webp" alt="Redis in System Design" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_system_design_and_Redis_eee6a78f0d.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_system_design_and_Redis_eee6a78f0d.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_system_design_and_Redis_eee6a78f0d.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_system_design_and_Redis_eee6a78f0d.webp 1000w," sizes="100vw"><figcaption>Redis in System Design</figcaption></figure><h3>Typical Caching Architecture</h3><pre><code class="language-ruby">Client Request
    --&gt; Load Balancer
    --&gt; API Server
        --&gt; Check Redis Cache
            --&gt; Cache Hit: return data immediately (&lt;1ms)
            --&gt; Cache Miss: query Database (20-100ms)
                --&gt; Store result in Redis
                --&gt; Return data to client
</code></pre><h3>Latency Impact</h3><figure class="table"><table><thead><tr><th>Layer</th><th>Typical Latency</th></tr></thead><tbody><tr><td>Redis (in-region)</td><td>0.1–1ms</td></tr><tr><td>Same-region DB</td><td>10–50ms</td></tr><tr><td>Cross-region DB</td><td>50–200ms</td></tr></tbody></table></figure><p>With a 90% cache hit rate, average response time drops from 30ms to 3ms — a 10x improvement.</p><h3>Database Load Reduction</h3><p>If 95% of reads are served from cache, the database handles 5% of the original traffic. This extends database capacity, reduces costs, and improves write throughput since fewer reads compete for DB connections.</p><hr><h2>19. Real-World Redis Use Cases</h2><h3>Session Storage</h3><p>Store authenticated user sessions in Redis with a TTL matching session timeout. Much faster than database session lookups on every request.</p><pre><code class="language-ruby">SET session:abc123 '{"user_id": 100, "role": "admin"}' EX 86400
GET session:abc123
DEL session:abc123     # on logout
</code></pre><h3>Leaderboards</h3><p>Sorted sets are purpose-built for this. Scores update atomically. Range queries return top-N players in O(log N + M).</p><pre><code class="language-ruby">ZINCRBY game:leaderboard 50 "player:999"
ZREVRANGE game:leaderboard 0 9 WITHSCORES    # top 10
</code></pre><h3>Shopping Cart</h3><p>Store cart items as a hash per user. Fast reads, partial updates without rewriting the full cart.</p><pre><code class="language-ruby">HSET cart:user:100 product:42 2 product:17 1
HGETALL cart:user:100
HDEL cart:user:100 product:17
</code></pre><h3>Real-Time Analytics</h3><p>Count events atomically. Bitmaps for unique users. HyperLogLog for approximate counts at scale.</p><pre><code class="language-ruby">INCR analytics:page:home:views
PFADD analytics:unique:visitors:today "user:100" "user:200"
PFCOUNT analytics:unique:visitors:today
</code></pre><h3>API Rate Limiting</h3><p>As described in section 16 — Redis is the standard tool across the industry.</p><h3>Message Queues</h3><p>Lists as simple queues. BLPOP for blocking consumers.</p><pre><code class="language-ruby">RPUSH email:queue '{"to":"a@example.com","subject":"Welcome"}'
BLPOP email:queue 0    # worker blocks until job arrives
</code></pre><hr><h2>20. Common Cache Problems</h2><h3>Cache Stampede (Thundering Herd)</h3><p><strong>What happens</strong>: A popular cache key expires. Hundreds of concurrent requests all miss at the same time, all query the database simultaneously, all try to write to Redis simultaneously.</p><p><strong>Real-world scenario</strong>: A trending product page expires at midnight. 10,000 users simultaneously trigger database queries.</p><p><strong>Mitigation</strong>:</p><ul><li><strong>Mutex/lock</strong>: Only one request fetches from DB. Others wait for the cache to be populated.</li><li><strong>Probabilistic early expiration</strong>: Start refreshing before TTL expires using a small random chance as TTL approaches zero.</li><li><strong>Background refresh</strong>: An async worker refreshes hot keys before they expire.</li></ul><pre><code class="language-ruby"># Mutex pattern
SET cache:lock:product:42 1 NX EX 5    # NX = only set if not exists
# If SET succeeds, this request fetches from DB and populates cache
# Others check lock, wait, then read from cache
</code></pre><h3>Cache Penetration</h3><p><strong>What happens</strong>: Requests for data that doesn't exist in the database or cache keep bypassing the cache and hitting the database. Common in scraping or malicious traffic patterns.</p><p><strong>Real-world scenario</strong>: Attacker queries <code>user:0</code>, <code>user:-1</code>, <code>user:999999999</code> — none exist in DB, cache never populates, database gets hammered.</p><p><strong>Mitigation</strong>:</p><ul><li>Cache null results with a short TTL: <code>SET user:0 "NULL" EX 60</code></li><li><strong>Bloom filter</strong>: Maintain a probabilistic set of valid keys. Reject requests for keys not in the filter before they reach the cache or database.</li></ul><h3>Cache Avalanche</h3><p><strong>What happens</strong>: A large number of cache keys expire at the same time. All traffic suddenly hits the database simultaneously.</p><p><strong>Real-world scenario</strong>: You preloaded 10,000 product cache entries at startup with the same 1-hour TTL. At exactly T+1 hour, all 10,000 keys expire simultaneously.</p><p><strong>Mitigation</strong>:</p><ul><li><strong>Jitter on TTL</strong>: Add a random offset to expiration times: <code>EX = base_ttl + random(0, 300)</code> — entries expire spread over a window, not all at once.</li><li><strong>Persistent hot keys</strong>: Never expire the most critical cache entries, refresh them via background jobs.</li><li><strong>Circuit breaker</strong>: If database error rate spikes, temporarily serve stale cache data.</li></ul><hr><h2>21. Redis vs Memcached</h2><figure class="table"><table><thead><tr><th>Feature</th><th>Redis</th><th>Memcached</th></tr></thead><tbody><tr><td>Data structures</td><td>Strings, hashes, lists, sets, sorted sets, streams</td><td>Strings only</td></tr><tr><td>Persistence</td><td>Yes (RDB + AOF)</td><td>No</td></tr><tr><td>Clustering</td><td>Built-in cluster mode</td><td>Client-side sharding only</td></tr><tr><td>Pub/Sub</td><td>Yes</td><td>No</td></tr><tr><td>Lua scripting</td><td>Yes</td><td>No</td></tr><tr><td>Multi-threading</td><td>Single-threaded (I/O)</td><td>Multi-threaded</td></tr><tr><td>Memory efficiency</td><td>Slightly higher overhead</td><td>Very lean</td></tr><tr><td>Replication</td><td>Built-in</td><td>Not native</td></tr><tr><td>Transactions</td><td>Yes (MULTI/EXEC)</td><td>No</td></tr><tr><td>Best for</td><td>Caching + queues + leaderboards + sessions</td><td>Simple high-throughput string cache</td></tr></tbody></table></figure><p><strong>When to choose Memcached</strong>: You only need simple string caching, you need raw multi-threaded throughput, and you have no need for persistence, pub/sub, or complex data structures. In practice, most teams choose Redis because its additional capabilities rarely come with a meaningful cost.</p><hr><h2>22. Redis Best Practices</h2><h3>Key Design</h3><ul><li>Always namespace keys using a predictable format like <code>service:entity:id</code></li><li>Keep keys short but descriptive — long keys waste memory</li><li>Avoid spaces and special characters in key names</li><li>Document key patterns just like database schemas</li></ul><p>Examples:</p><pre><code class="language-ruby">user:profile:123
order:details:9812
product:inventory:42
session:token:abc123
</code></pre><p>Good key design prevents collisions and makes debugging production systems easier.</p><h3>TTL Discipline</h3><ul><li>Always set a <strong>TTL for cached data</strong> when possible</li><li>Avoid storing temporary cache entries without expiration</li><li>Add small randomness to TTL values to prevent mass expiration</li></ul><p>Example:</p><pre><code class="language-plaintext">SET product:42'{
	"name":"Laptop",
	"price":1200
}' EX3600
</code></pre><p>Adding slight TTL variation helps avoid <strong>cache avalanche</strong> situations.</p><h3>Avoid Large Values</h3><p>Large values increase memory usage and network overhead.</p><p>Instead of storing one huge object:</p><pre><code class="language-ruby">user:123-&gt; large JSON object
</code></pre><p>Split the data logically:</p><pre><code class="language-ruby">user:profile:123
user:settings:123
user:preferences:123
</code></pre><p>This improves partial updates and reduces serialization overhead.</p><h3>Monitor Redis</h3><p>Always monitor Redis in production.</p><p>Important metrics include:</p><ul><li>Memory usage</li><li>Cache hit rate</li><li>Evicted keys</li><li>Connected clients</li><li>Command latency</li></ul><p>Useful commands:</p><pre><code class="language-ruby">INFO memory
INFO stats
SLOWLOG GET
MONITOR
</code></pre><p>Monitoring helps detect memory pressure, slow commands, and traffic spikes.</p><h3>Avoid Blocking Commands</h3><p>Some commands can block the Redis server if the dataset is large.</p><p>Avoid:</p><pre><code class="language-ruby">KEYS *
LRANGE huge_list0-1
SMEMBERS large_set
</code></pre><p>Prefer incremental scanning:</p><pre><code class="language-ruby">SCAN
SSCAN
HSCAN
ZSCAN
</code></pre><p>These iterate through data gradually without blocking the server.</p><hr><h2>Quick Reference</h2><figure class="table"><table><thead><tr><th>Topic</th><th>Key Idea</th><th>Important Commands / Concepts</th><th>Use Case</th></tr></thead><tbody><tr><td>Caching</td><td>Store frequently accessed data in fast storage</td><td>Cache hit, cache miss</td><td>Reduce DB load</td></tr><tr><td>Redis</td><td>In-memory key-value data store</td><td>Sub-ms latency, RAM storage</td><td>High-performance backend systems</td></tr><tr><td>Strings</td><td>Basic key-value storage</td><td><code>SET</code>, <code>GET</code>, <code>INCR</code></td><td>Counters, sessions</td></tr><tr><td>Hashes</td><td>Store objects with fields</td><td><code>HSET</code>, <code>HGET</code>, <code>HGETALL</code></td><td>User profiles</td></tr><tr><td>Lists</td><td>Ordered collection</td><td><code>LPUSH</code>, <code>RPUSH</code>, <code>LPOP</code></td><td>Queues, feeds</td></tr><tr><td>Sets</td><td>Unique unordered values</td><td><code>SADD</code>, <code>SMEMBERS</code></td><td>Tags, unique users</td></tr><tr><td>Sorted Sets</td><td>Ordered by score</td><td><code>ZADD</code>, <code>ZRANGE</code></td><td>Leaderboards</td></tr><tr><td>TTL</td><td>Auto-expire keys</td><td><code>EXPIRE</code>, <code>TTL</code></td><td>Temporary cache</td></tr><tr><td>Caching Strategies</td><td>Ways to manage cache</td><td>Cache-Aside, Write-Through</td><td>Performance optimization</td></tr><tr><td>Eviction</td><td>Remove keys when memory is full</td><td>LRU, LFU</td><td>Memory management</td></tr><tr><td>Persistence</td><td>Save Redis data to disk</td><td>RDB, AOF</td><td>Durability</td></tr><tr><td>Replication</td><td>Copy data to replicas</td><td>Master–Replica</td><td>High availability</td></tr><tr><td>Cluster</td><td>Horizontal scaling</td><td>Hash slots (0–16384)</td><td>Large distributed systems</td></tr><tr><td>Pub/Sub</td><td>Real-time messaging</td><td><code>PUBLISH</code>, <code>SUBSCRIBE</code></td><td>Notifications</td></tr><tr><td>Streams</td><td>Persistent event log</td><td><code>XADD</code>, <code>XREAD</code></td><td>Event processing</td></tr><tr><td>Common Issues</td><td>Cache pitfalls</td><td>Stampede, Penetration</td><td>Production reliability</td></tr></tbody></table></figure><hr><h2>Conclusion</h2><p>Redis is one of the most powerful tools used in modern backend systems to improve performance and scalability. By storing frequently accessed data in memory, it significantly reduces database load and improves application response times. Beyond simple caching, Redis provides rich data structures that enable features like leaderboards, rate limiting, queues, and real-time analytics.</p><p>Understanding caching strategies, eviction policies, and common cache failure scenarios is essential to use Redis effectively in production systems. When designed correctly, Redis can handle massive traffic spikes while keeping systems stable and responsive.</p><p>Mastering Redis and caching concepts is a valuable skill for backend engineers and is frequently tested in system design interviews as well as used heavily in real-world distributed systems.</p><p>If you found this cheatsheet useful, consider sharing it with your friends or colleagues who are learning backend development or preparing for system design interviews.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Redis</category>
            <category>Caching</category>
            <category>Backend Development</category>
            <category>System Design</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Caching_And_Redis_Thumbnail_7752a718ed.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[RDBMS Guide — The Only Cheat Sheet You Need for Interviews & Real-World Systems]]></title>
            <link>https://www.codingshuttle.com/blogs/rdbms-guide-the-only-cheat-sheet-you-need-for-interviews-and-real-world-systems</link>
            <guid>https://www.codingshuttle.com/blogs/rdbms-guide-the-only-cheat-sheet-you-need-for-interviews-and-real-world-systems</guid>
            <pubDate>Wed, 25 Mar 2026 06:10:09 GMT</pubDate>
            <description><![CDATA[A comprehensive RDBMS cheat sheet covering SQL queries, joins, indexing, normalization, ACID properties, transactions, and database design. Perfect for interview preparation, backend development, and mastering relational database concepts with real-world examples and practical insights.]]></description>
            <content:encoded><![CDATA[<p><strong>RDBMS Guide — The Only Cheat Sheet You Need for Interviews &amp; Real-World Systems</strong></p><p>A <strong>Relational Database Management System (RDBMS)</strong> powers modern applications by organizing data into structured tables, enforcing relationships with keys, and ensuring reliable, consistent transactions using SQL and ACID principles.</p><hr><h2>1. RDBMS Fundamentals</h2><h3>What is an RDBMS?</h3><p>A Relational Database Management System is software that stores data in structured tables and enforces relationships between them. The "relational" part comes from relational algebra — data is organized so you can query across tables using shared keys.</p><p>Examples: PostgreSQL, MySQL, Oracle, SQL Server, SQLite.</p><h3>Why RDBMS? (Real-world context)</h3><p>Most business data is naturally relational. An order belongs to a customer. A product belongs to a category. RDBMS lets you model that reality directly, enforce rules at the database level, and query across entities without duplicating data.</p><ul><li>Enforces data integrity (you can't have an order with no customer)</li><li>Supports complex queries without application-level joins</li><li>ACID compliance makes it safe for financial, medical, and transactional workloads</li><li>Decades of tooling, optimization, and community support</li></ul><h3>RDBMS vs DBMS</h3><figure class="table"><table><thead><tr><th>Feature</th><th>DBMS</th><th>RDBMS</th></tr></thead><tbody><tr><td>Data storage</td><td>Files, hierarchical</td><td>Tables with rows/columns</td></tr><tr><td>Relationships</td><td>Not enforced</td><td>Enforced via keys</td></tr><tr><td>Normalization</td><td>Not required</td><td>Supported and encouraged</td></tr><tr><td>SQL support</td><td>May not support</td><td>Full SQL support</td></tr><tr><td>ACID compliance</td><td>Not guaranteed</td><td>Core feature</td></tr><tr><td>Examples</td><td>XML stores, file systems</td><td>PostgreSQL, MySQL</td></tr></tbody></table></figure><p>Mental model: DBMS is a filing cabinet. RDBMS is a filing cabinet with enforced cross-references between folders, a query engine, and a transaction log.</p><hr><h2>2. Core Concepts</h2><h3>Tables, Rows, Columns</h3><ul><li><strong>Table</strong> — a named set of data with a fixed structure (like a spreadsheet with rules)</li><li><strong>Row (tuple/record)</strong> — one instance of data in a table</li><li><strong>Column (attribute/field)</strong> — a named property with a defined data type</li></ul><p>Every column has a data type (INT, VARCHAR, DATE, BOOLEAN, etc.). This isn't just for storage — the database uses types to validate, index, and compare data correctly.</p><h3>Schema</h3><p>A schema is the blueprint. It defines what tables exist, what columns each has, what types they are, and what constraints apply. Think of it as the contract between your application and your data.</p><pre><code class="language-php">CREATE TABLE users (
  id       INT PRIMARY KEY,
  email    VARCHAR(255) UNIQUE NOT NULL,
  name     VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);
</code></pre><h3>Primary Key</h3><ul><li>Uniquely identifies each row in a table</li><li>Cannot be NULL</li><li>Should be immutable — once set, never changed</li><li>Usually a surrogate key (auto-increment INT or UUID) rather than a natural key (email, phone)</li></ul><p>Why surrogate keys? Natural keys change. Someone's email changes. Their phone number changes. An auto-increment ID never does.</p><h3>Foreign Key</h3><ul><li>A column (or set of columns) in one table that references the primary key of another</li><li>Enforces referential integrity — you can't reference a row that doesn't exist</li></ul><pre><code class="language-php">CREATE TABLE orders (
  id         INT PRIMARY KEY,
  user_id    INT NOT NULL,
  total      DECIMAL(10,2),
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
</code></pre><p><code>ON DELETE CASCADE</code> means: if the user is deleted, delete their orders too. Alternatives: <code>SET NULL</code>, <code>RESTRICT</code> (block the delete). Choose carefully — wrong cascade behavior is a data loss nightmare.</p><h3>Constraints</h3><figure class="table"><table><thead><tr><th>Constraint</th><th>Purpose</th></tr></thead><tbody><tr><td>NOT NULL</td><td>Column must have a value</td></tr><tr><td>UNIQUE</td><td>No duplicate values in the column</td></tr><tr><td>PRIMARY KEY</td><td>NOT NULL + UNIQUE + indexed</td></tr><tr><td>FOREIGN KEY</td><td>References another table's PK</td></tr><tr><td>CHECK</td><td>Custom condition must be true</td></tr><tr><td>DEFAULT</td><td>Fallback value if none provided</td></tr></tbody></table></figure><p>Constraints live in the database, not in your application code. This is intentional — application bugs can be patched, but corrupt data is permanent.</p><hr><h2>3. Keys in Detail</h2><figure class="table"><table><thead><tr><th>Key Type</th><th>Definition</th><th>Uniqueness</th><th>NULLs</th></tr></thead><tbody><tr><td>Super Key</td><td>Any set of columns that uniquely identifies a row</td><td>Yes</td><td>Depends</td></tr><tr><td>Candidate Key</td><td>Minimal super key (no redundant columns)</td><td>Yes</td><td>No</td></tr><tr><td>Primary Key</td><td>The chosen candidate key</td><td>Yes</td><td>No</td></tr><tr><td>Alternate Key</td><td>Candidate key not chosen as PK</td><td>Yes</td><td>Depends</td></tr><tr><td>Foreign Key</td><td>References PK in another table</td><td>Not required</td><td>Allowed</td></tr><tr><td>Composite Key</td><td>PK made of two or more columns</td><td>Combined unique</td><td>No</td></tr></tbody></table></figure><p><strong>Common confusion points:</strong></p><ul><li>Every primary key is a candidate key, but not every candidate key is the primary key</li><li>A table can have multiple candidate keys (e.g., <code>id</code>, <code>email</code>, <code>phone</code>) but only one primary key</li><li>A foreign key's value doesn't have to be unique — many orders can reference the same user</li><li>Composite keys are common in junction tables (user_id + role_id together are unique)</li></ul><p><strong>Interview trap:</strong> "Can a foreign key reference a non-primary key?" Yes — it can reference any UNIQUE column, not just the PK. Most people assume it must be PK.</p><hr><h2>4. Relationships</h2><h3>One-to-One (1:1)</h3><p>A user has one profile. A country has one capital. Rare in practice. Usually signals you could merge the tables — but sometimes you split for performance (keeping heavy columns separate) or security (separating sensitive data).</p><pre><code class="language-php">CREATE TABLE user_profiles (
  user_id    INT PRIMARY KEY,
  bio        TEXT,
  avatar_url VARCHAR(500),
  FOREIGN KEY (user_id) REFERENCES users(id)
);
</code></pre><h3>One-to-Many (1:N)</h3><p>The most common relationship. One customer, many orders. One author, many posts. The foreign key lives on the "many" side.</p><pre><code class="language-ruby">-- orders.user_id references users.id
-- One user -&gt; many orders
</code></pre><h3>Many-to-Many (M:N)</h3><p>Students take many courses. Courses have many students. You can't express this with just two tables — you need a junction (bridge/associative) table.</p><pre><code class="language-php">CREATE TABLE student_courses (
  student_id INT NOT NULL,
  course_id  INT NOT NULL,
  enrolled_at DATE,
  PRIMARY KEY (student_id, course_id),
  FOREIGN KEY (student_id) REFERENCES students(id),
  FOREIGN KEY (course_id) REFERENCES courses(id)
);
</code></pre><p>The junction table's PK is composite (student_id + course_id). You can also add extra columns to it — enrollment date, grade, status.</p><p><strong>Entity Relationships:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Entity_Relationships_59e1156941.webp" alt="Entity Relationships" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Entity_Relationships_59e1156941.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Entity_Relationships_59e1156941.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Entity_Relationships_59e1156941.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Entity_Relationships_59e1156941.webp 1000w," sizes="100vw"><figcaption><strong>Entity Relationships</strong></figcaption></figure><hr><h2>5. SQL Fundamentals</h2><p>SQL has four sub-languages. Know them cold — interviewers ask this.</p><figure class="table"><table><thead><tr><th>Category</th><th>Commands</th><th>Purpose</th></tr></thead><tbody><tr><td>DDL — Data Definition</td><td>CREATE, ALTER, DROP, TRUNCATE</td><td>Define/modify schema</td></tr><tr><td>DML — Data Manipulation</td><td>INSERT, UPDATE, DELETE</td><td>Modify data</td></tr><tr><td>DQL — Data Query</td><td>SELECT</td><td>Read data</td></tr><tr><td>TCL — Transaction Control</td><td>COMMIT, ROLLBACK, SAVEPOINT</td><td>Manage transactions</td></tr><tr><td>DCL — Data Control</td><td>GRANT, REVOKE</td><td>Permissions</td></tr></tbody></table></figure><pre><code class="language-php">-- DDL
CREATE TABLE products (id INT PRIMARY KEY, name VARCHAR(100), price DECIMAL(8,2));
ALTER TABLE products ADD COLUMN stock INT DEFAULT 0;
DROP TABLE products;

-- DML
INSERT INTO products (name, price) VALUES ('Keyboard', 49.99);
UPDATE products SET price = 44.99 WHERE id = 1;
DELETE FROM products WHERE stock = 0;

-- DQL
SELECT name, price FROM products WHERE price &lt; 100 ORDER BY price DESC;

-- TCL
BEGIN;
  UPDATE accounts SET balance = balance - 500 WHERE id = 1;
  UPDATE accounts SET balance = balance + 500 WHERE id = 2;
COMMIT;
</code></pre><p><strong>TRUNCATE vs DELETE:</strong> TRUNCATE removes all rows without logging individual deletions — much faster, but cannot be rolled back in most databases and does not fire triggers. Use DELETE when you need control or auditability.</p><hr><h2>6. CRUD Operations</h2><pre><code class="language-php">-- CREATE
INSERT INTO users (name, email) VALUES ('Priya Sharma', 'priya@example.com');

-- READ with filtering, sorting, pagination
SELECT id, name, email
FROM users
WHERE created_at &gt;= '2024-01-01'
ORDER BY name ASC
LIMIT 20 OFFSET 40;

-- UPDATE (always use WHERE — a bare UPDATE touches every row)
UPDATE users SET email = 'new@example.com' WHERE id = 7;

-- DELETE
DELETE FROM users WHERE id = 7;

-- Conditional insert (upsert)
INSERT INTO users (id, name, email)
VALUES (7, 'Priya', 'priya@example.com')
ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email;
</code></pre><p><strong>Common mistake:</strong> Running <code>UPDATE</code> or <code>DELETE</code> without a WHERE clause in production. Always test with a SELECT first using the same WHERE condition.</p><hr><h2>7. Joins</h2><p>The heart of relational databases. A join combines rows from two or more tables based on a related column.</p><p><strong>Mental model:</strong> Think of two spreadsheets. A join is asking "show me rows where these two sheets have matching values in these columns."</p><figure class="table"><table><thead><tr><th>Join Type</th><th>Returns</th></tr></thead><tbody><tr><td>INNER JOIN</td><td>Only rows with a match in BOTH tables</td></tr><tr><td>LEFT JOIN</td><td>All rows from left + matched rows from right (NULLs for no match)</td></tr><tr><td>RIGHT JOIN</td><td>All rows from right + matched rows from left (NULLs for no match)</td></tr><tr><td>FULL OUTER JOIN</td><td>All rows from both, NULLs where no match</td></tr><tr><td>SELF JOIN</td><td>Table joined with itself</td></tr><tr><td>CROSS JOIN</td><td>Every combination of rows (Cartesian product)</td></tr></tbody></table></figure><pre><code class="language-php">-- INNER JOIN: orders with their customer names
SELECT o.id, u.name, o.total
FROM orders o
INNER JOIN users u ON o.user_id = u.id;

-- LEFT JOIN: all users, even those with no orders
SELECT u.name, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id;

-- SELF JOIN: employees and their managers (same table)
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
</code></pre><p><strong>Interview trap:</strong> "What's the difference between LEFT JOIN and LEFT OUTER JOIN?" They're the same thing. OUTER is optional syntax.</p><p><strong>Join Types:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Join_Types_321f6e0cc7.webp" alt="Join Types" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Join_Types_321f6e0cc7.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Join_Types_321f6e0cc7.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Join_Types_321f6e0cc7.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Join_Types_321f6e0cc7.webp 1000w," sizes="100vw"><figcaption><strong>Join Types</strong></figcaption></figure><hr><h2>8. Aggregation</h2><p>Aggregates collapse multiple rows into a single result. Used constantly in reporting.</p><pre><code class="language-php">SELECT
  category,
  COUNT(*)          AS total_products,
  AVG(price)        AS avg_price,
  MAX(price)        AS max_price,
  SUM(stock * price) AS inventory_value
FROM products
GROUP BY category
HAVING COUNT(*) &gt; 5
ORDER BY inventory_value DESC;
</code></pre><p><strong>WHERE vs HAVING:</strong></p><ul><li>WHERE filters rows before grouping</li><li>HAVING filters groups after aggregation</li><li>You cannot use aggregate functions in WHERE</li></ul><pre><code class="language-php">-- Wrong
SELECT category, COUNT(*) FROM products WHERE COUNT(*) &gt; 5 GROUP BY category;

-- Right
SELECT category, COUNT(*) FROM products GROUP BY category HAVING COUNT(*) &gt; 5;
</code></pre><hr><h2>9. Advanced Queries</h2><h3>Subqueries</h3><p>A query inside another query. Used when you need the result of one query to drive another.</p><pre><code class="language-php">-- Find users who have placed at least one order
SELECT name FROM users
WHERE id IN (SELECT DISTINCT user_id FROM orders);

-- Find products more expensive than the average
SELECT name, price FROM products
WHERE price &gt; (SELECT AVG(price) FROM products);
</code></pre><h3>Correlated Subqueries</h3><p>The inner query references the outer query. Executes once per row — can be slow on large tables.</p><pre><code class="language-php">-- For each user, find their most recent order date
SELECT u.name,
  (SELECT MAX(o.created_at) FROM orders o WHERE o.user_id = u.id) AS last_order
FROM users u;
</code></pre><p>When performance matters, rewrite correlated subqueries as JOINs or CTEs.</p><h3>Window Functions</h3><p>Window functions compute a value across a "window" of related rows without collapsing them (unlike GROUP BY).</p><pre><code class="language-php">SELECT
  name,
  department,
  salary,
  RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank_in_dept,
  AVG(salary) OVER (PARTITION BY department) AS dept_avg
FROM employees;
</code></pre><p>Common window functions: <code>RANK()</code>, <code>ROW_NUMBER()</code>, <code>DENSE_RANK()</code>, <code>LAG()</code>, <code>LEAD()</code>, <code>SUM() OVER</code>, <code>AVG() OVER</code>.</p><p>Mental model: GROUP BY collapses rows. Window functions keep all rows and add a computed column.</p><hr><h2>10. Normalization</h2><p>Normalization is the process of organizing data to reduce redundancy and improve integrity. Each normal form solves a specific class of problem.</p><h3>The Problem Without Normalization</h3><figure class="table"><table><thead><tr><th>order_id</th><th>customer_name</th><th>customer_email</th><th>product</th><th>product_price</th></tr></thead><tbody><tr><td>1</td><td>Alice</td><td><a href="mailto:alice@x.com">alice@x.com</a></td><td>Keyboard</td><td>49</td></tr><tr><td>2</td><td>Alice</td><td><a href="mailto:alice@x.com">alice@x.com</a></td><td>Mouse</td><td>29</td></tr><tr><td>3</td><td>Bob</td><td><a href="mailto:bob@x.com">bob@x.com</a></td><td>Keyboard</td><td>49</td></tr></tbody></table></figure><p>Problems: Alice's email appears twice — update one, forget the other. Product price duplicated everywhere.</p><h3>1NF — First Normal Form</h3><p><strong>Rule:</strong> Each column must hold atomic (indivisible) values. No repeating groups.</p><p>Violation: Storing <code>"Math, Science, English"</code> in a single <code>subjects</code> column.</p><p>Fix: One subject per row, or a separate subjects table.</p><h3>2NF — Second Normal Form</h3><p><strong>Rule:</strong> Must be in 1NF + no partial dependencies (non-key column depends on only part of a composite PK).</p><p>Violation: In <code>order_items(order_id, product_id, product_name)</code> — <code>product_name</code> depends only on <code>product_id</code>, not the full PK.</p><p>Fix: Move <code>product_name</code> to a <code>products</code> table.</p><h3>3NF — Third Normal Form</h3><p><strong>Rule:</strong> Must be in 2NF + no transitive dependencies (non-key column depends on another non-key column).</p><p>Violation: <code>employees(id, dept_id, dept_name)</code> — <code>dept_name</code> depends on <code>dept_id</code>, not on <code>id</code>.</p><p>Fix: Move <code>dept_name</code> to a <code>departments</code> table.</p><h3>BCNF — Boyce-Codd Normal Form</h3><p>Stricter version of 3NF. Every determinant must be a candidate key. In practice, 3NF is sufficient for most systems.</p><h3>When to Denormalize</h3><ul><li>High-read, low-write reporting tables</li><li>Data warehouses and analytics (star schema, fact tables)</li><li>When join cost exceeds storage cost at scale</li><li>Caching pre-computed aggregates for dashboards</li></ul><p>Denormalization is a deliberate performance trade-off, not laziness. The mistake is denormalizing before you've proven you need to.</p><p><strong>Normalization Flow Diagram:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Normalization_Flow_5f82e0724e.webp" alt="Normalization Flow" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Normalization_Flow_5f82e0724e.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Normalization_Flow_5f82e0724e.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Normalization_Flow_5f82e0724e.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Normalization_Flow_5f82e0724e.webp 1000w," sizes="100vw"><figcaption><strong>Normalization Flow</strong></figcaption></figure><hr><h2>11. Indexing</h2><h3>What and Why</h3><p>An index is a separate data structure that lets the database find rows without scanning every row in the table. Without an index, every query is a full table scan — O(n). With a B-tree index, lookup is O(log n).</p><p>Analogy: A database table is a book. An index is the book's index at the back — instead of reading every page, you go straight to page 247.</p><h3>How it Works (B-Tree)</h3><p>The default index type. A balanced tree where leaf nodes hold the actual row pointers (or values for covering indexes). Each lookup traverses from root to leaf — typically 3–4 levels for millions of rows.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/B_Tree_6c89cbbe15.webp" alt="B-Tree" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_B_Tree_6c89cbbe15.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_B_Tree_6c89cbbe15.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_B_Tree_6c89cbbe15.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_B_Tree_6c89cbbe15.webp 1000w," sizes="100vw"><figcaption>B-Tree</figcaption></figure><h3>Types of Indexes</h3><figure class="table"><table><thead><tr><th>Type</th><th>Use Case</th></tr></thead><tbody><tr><td>B-Tree (default)</td><td>Range queries, equality, ORDER BY</td></tr><tr><td>Hash Index</td><td>Equality only (=), not ranges</td></tr><tr><td>Composite Index</td><td>Multiple columns, follows left-prefix rule</td></tr><tr><td>Unique Index</td><td>Enforces uniqueness + fast lookup</td></tr><tr><td>Partial Index</td><td>Index only rows matching a condition</td></tr><tr><td>Full-Text Index</td><td>Text search (LIKE '%word%' won't use B-tree)</td></tr><tr><td>Covering Index</td><td>Index includes all columns the query needs</td></tr></tbody></table></figure><pre><code class="language-php">CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
CREATE UNIQUE INDEX idx_users_phone ON users(phone);
-- Partial index: only index active users
CREATE INDEX idx_active_users ON users(email) WHERE status = 'active';
</code></pre><h3>Composite Index: Left-Prefix Rule</h3><p>An index on <code>(a, b, c)</code> can serve queries filtering on <code>a</code>, <code>a+b</code>, or <code>a+b+c</code>. It cannot serve queries filtering only on <code>b</code> or <code>c</code>.</p><pre><code class="language-php">-- Index on (user_id, created_at)
SELECT * FROM orders WHERE user_id = 5 AND created_at &gt; '2024-01-01'; -- uses index
SELECT * FROM orders WHERE user_id = 5;                                -- uses index
SELECT * FROM orders WHERE created_at &gt; '2024-01-01';                  -- does NOT use index
</code></pre><h3>Trade-offs</h3><ul><li>Indexes speed up reads but slow down writes (INSERT/UPDATE/DELETE must update the index too)</li><li>Each index consumes disk space</li><li>Too many indexes on write-heavy tables is a common performance killer</li><li>Rule of thumb: index columns you frequently filter, join, or sort by</li></ul><hr><h2>12. Transactions</h2><h3>What is a Transaction?</h3><p>A transaction is a unit of work that either completes entirely or doesn't happen at all. It groups multiple operations into an all-or-nothing block.</p><pre><code class="language-php">BEGIN;
  UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
  UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;
-- If anything fails between BEGIN and COMMIT, ROLLBACK undoes both updates
</code></pre><h3>ACID Properties</h3><figure class="table"><table><thead><tr><th>Property</th><th>Meaning</th><th>Real-world guarantee</th></tr></thead><tbody><tr><td>Atomicity</td><td>All or nothing</td><td>If transfer fails mid-way, neither account is changed</td></tr><tr><td>Consistency</td><td>DB goes from one valid state to another</td><td>Account total before = account total after</td></tr><tr><td>Isolation</td><td>Concurrent transactions don't interfere</td><td>Two people withdrawing at the same time can't both see the same old balance</td></tr><tr><td>Durability</td><td>Committed data survives crashes</td><td>Once you see "Payment successful", it's on disk</td></tr></tbody></table></figure><h3>Transaction Flow Diagram:</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Transaction_Flow_a5edd48467.webp" alt="Transaction Flow" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Transaction_Flow_a5edd48467.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Transaction_Flow_a5edd48467.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Transaction_Flow_a5edd48467.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Transaction_Flow_a5edd48467.webp 1000w," sizes="100vw"><figcaption>Transaction Flow</figcaption></figure><h3>SAVEPOINT</h3><pre><code class="language-php">BEGIN;
  INSERT INTO orders ...;
  SAVEPOINT after_order;
  INSERT INTO payments ...;  -- if this fails
  ROLLBACK TO after_order;   -- undo only the payment, keep the order
COMMIT;
</code></pre><hr><h2>13. Concurrency Control</h2><h3>Why it's Needed</h3><p>Multiple users hitting the database simultaneously create race conditions. Without control, two transactions can read the same data, modify it, and overwrite each other.</p><h3>Locking</h3><ul><li><strong>Shared Lock (S):</strong> Read lock. Multiple transactions can hold it simultaneously.</li><li><strong>Exclusive Lock (X):</strong> Write lock. Only one transaction; blocks everyone else.</li><li><strong>Row-level lock:</strong> Only locks the affected row (preferred, more concurrency)</li><li><strong>Table-level lock:</strong> Locks the entire table (fast to acquire, kills concurrency)</li></ul><h3>Deadlock</h3><p>Transaction A holds lock on row 1, wants row 2.</p><p>Transaction B holds lock on row 2, wants row 1.</p><p>Both wait forever.</p><p>Databases detect deadlocks and kill one transaction (the "victim"). Your application must handle this by retrying.</p><p>Prevention: always acquire locks in the same order across transactions.</p><h3>Isolation Levels</h3><figure class="table"><table><thead><tr><th>Level</th><th>Dirty Read</th><th>Non-Repeatable Read</th><th>Phantom Read</th><th>Use Case</th></tr></thead><tbody><tr><td>READ UNCOMMITTED</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Almost never</td></tr><tr><td>READ COMMITTED</td><td>No</td><td>Yes</td><td>Yes</td><td>Default in most DBs</td></tr><tr><td>REPEATABLE READ</td><td>No</td><td>No</td><td>Yes</td><td>Consistent reports</td></tr><tr><td>SERIALIZABLE</td><td>No</td><td>No</td><td>No</td><td>Financial, critical ops</td></tr></tbody></table></figure><ul><li><strong>Dirty Read:</strong> Reading uncommitted data from another transaction</li><li><strong>Non-Repeatable Read:</strong> Re-reading a row gets different data (another tx updated it)</li><li><strong>Phantom Read:</strong> Re-running a query gets different rows (another tx inserted/deleted)</li></ul><p>Higher isolation = more safety, but more lock contention and lower throughput.</p><hr><h2>14. Database Optimization</h2><h3>Query Optimization Tips</h3><ul><li>SELECT only the columns you need — <code>SELECT *</code> forces the DB to fetch all columns</li><li>Filter early with WHERE before joining when possible</li><li>Use indexes on JOIN columns and WHERE clauses</li><li>Avoid functions on indexed columns in WHERE: <code>WHERE YEAR(created_at) = 2024</code> doesn't use the index; <code>WHERE created_at &gt;= '2024-01-01' AND created_at &lt; '2025-01-01'</code> does</li><li>Avoid <code>SELECT DISTINCT</code> unless truly needed — it adds a sort/dedup step</li><li>Use <code>EXISTS</code> instead of <code>IN</code> with large subquery results</li><li>Paginate with keyset pagination (<code>WHERE id &gt; last_seen_id LIMIT 20</code>) instead of <code>OFFSET</code> for large tables</li></ul><h3>EXPLAIN / EXPLAIN ANALYZE</h3><pre><code class="language-php">EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 5 AND created_at &gt; '2024-01-01';
</code></pre><p>Key things to look for:</p><ul><li><code>Seq Scan</code> — full table scan, usually bad on large tables</li><li><code>Index Scan</code> — using an index, good</li><li><code>Nested Loop</code> vs <code>Hash Join</code> — matters at scale</li><li><code>rows=</code> estimate vs actual rows — large mismatch means stale statistics (run ANALYZE)</li><li><code>cost=</code> — planner's estimate; focus on actual time in ANALYZE output</li></ul><h3>Common Mistakes</h3><ul><li>No index on foreign key columns (causes full scan on every JOIN)</li><li>Using <code>LIKE '%term%'</code> on large tables (can't use B-tree index)</li><li>N+1 query problem: fetching 100 posts, then 1 query per post for author</li><li>Not using connection pooling in production</li><li>Running migrations without testing on production-sized data</li></ul><hr><h2>15. Advanced Features</h2><h3>Views</h3><p>A stored query that acts like a virtual table. Doesn't store data itself.</p><pre><code class="language-php">CREATE VIEW active_users AS
SELECT id, name, email FROM users WHERE status = 'active';

SELECT * FROM active_users; -- runs the underlying query
</code></pre><p>Use views for: simplifying complex queries, hiding sensitive columns, creating stable interfaces over evolving schemas.</p><p>Don't use views for: performance optimization (a view doesn't cache data — it re-runs each time). Use materialized views for caching.</p><h3>Stored Procedures</h3><p>Precompiled SQL logic stored in the database. Can accept parameters, contain control flow, and return results.</p><pre><code class="language-php">CREATE PROCEDURE transfer_funds(from_id INT, to_id INT, amount DECIMAL)
BEGIN
  START TRANSACTION;
    UPDATE accounts SET balance = balance - amount WHERE id = from_id;
    UPDATE accounts SET balance = balance + amount WHERE id = to_id;
  COMMIT;
END;

CALL transfer_funds(1, 2, 500.00);
</code></pre><p>Trade-off: logic in the database is harder to version, test, and deploy. Prefer application-layer logic unless there's a specific reason (performance, shared logic across multiple apps).</p><h3>Triggers</h3><p>Automatically execute logic in response to INSERT, UPDATE, or DELETE.</p><pre><code class="language-php">CREATE TRIGGER log_price_change
AFTER UPDATE ON products
FOR EACH ROW
WHEN (OLD.price &lt;&gt; NEW.price)
INSERT INTO price_audit (product_id, old_price, new_price, changed_at)
VALUES (NEW.id, OLD.price, NEW.price, NOW());
</code></pre><p>Use triggers for: audit logging, denormalized counter updates.</p><p>Avoid triggers for: business logic — they're invisible, hard to debug, and cause surprises.</p><h3>Cursors</h3><p>Row-by-row processing within a stored procedure. Almost always the wrong choice — set-based SQL operations are orders of magnitude faster. Use cursors only when row-by-row processing is genuinely unavoidable (rare ETL edge cases).</p><hr><h2>16. Scaling Databases</h2><h3>Vertical vs Horizontal Scaling</h3><figure class="table"><table><thead><tr><th>&nbsp;</th><th>Vertical (Scale Up)</th><th>Horizontal (Scale Out)</th></tr></thead><tbody><tr><td>What</td><td>Bigger machine (more CPU, RAM, SSD)</td><td>More machines</td></tr><tr><td>Simplicity</td><td>Simple — no app changes</td><td>Complex — app must handle distribution</td></tr><tr><td>Limit</td><td>Hard ceiling (biggest available server)</td><td>Near-unlimited</td></tr><tr><td>Cost</td><td>Expensive at high end</td><td>Commodity hardware</td></tr><tr><td>When</td><td>First resort, up to a point</td><td>When vertical ceiling is hit</td></tr></tbody></table></figure><h3>Replication</h3><p>One primary (write) database, one or more replicas (read copies). Changes on primary are streamed to replicas.</p><ul><li>Read replicas absorb read traffic (reporting, analytics, API reads)</li><li>Replication lag is real — reads from replicas may be slightly stale</li><li>If your app reads immediately after writing, use the primary for that read</li></ul><h3>Sharding</h3><p>Splitting data across multiple database instances based on a shard key. User IDs 1–1M on shard 1, 1M–2M on shard 2.</p><p>Trade-offs:</p><ul><li>Cross-shard joins are expensive or impossible — design schemas to avoid them</li><li>Choosing the wrong shard key causes hot spots (one shard gets all the traffic)</li><li>Resharding as you grow is painful</li></ul><p>Most applications shouldn't shard until they're at massive scale. It's a last resort, not a first step.</p><p><strong>Scaling Diagram:</strong></p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Replication_7019e28b5e.webp" alt="Scaling" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Replication_7019e28b5e.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Replication_7019e28b5e.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Replication_7019e28b5e.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Replication_7019e28b5e.webp 1000w," sizes="100vw"></p><hr><h2>17. SQL vs NoSQL</h2><figure class="table"><table><thead><tr><th>Factor</th><th>SQL (RDBMS)</th><th>NoSQL</th></tr></thead><tbody><tr><td>Data model</td><td>Tables, fixed schema</td><td>Documents, KV, graphs, columns</td></tr><tr><td>Schema</td><td>Strict, defined upfront</td><td>Flexible, schema-on-read</td></tr><tr><td>Relationships</td><td>Built-in JOINs</td><td>Manual, denormalized</td></tr><tr><td>ACID</td><td>Yes, native</td><td>Depends (many offer eventual consistency)</td></tr><tr><td>Scaling</td><td>Vertical, then complex horizontal</td><td>Horizontal by design</td></tr><tr><td>Query flexibility</td><td>Rich SQL</td><td>Varies by type</td></tr><tr><td>Best for</td><td>Transactional, relational data</td><td>High-scale, flexible, or unstructured data</td></tr></tbody></table></figure><p><strong>Choose SQL when:</strong> strong consistency matters, data is relational, you need complex queries, compliance requires auditability.</p><p><strong>Choose NoSQL when:</strong> massive write throughput (Cassandra), flexible schema (MongoDB for CMS), pure key-value cache (Redis), graph relationships (Neo4j).</p><p><strong>Interview trap:</strong> "Is NoSQL always faster?" No. PostgreSQL with proper indexes beats many NoSQL solutions for typical workloads. The choice is about data model fit and scale patterns, not raw speed.</p><hr><h2>18. Real-World System Design</h2><h3>E-Commerce Database</h3><pre><code class="language-ruby">users       (id, name, email, password_hash, created_at)
addresses   (id, user_id, street, city, country, is_default)
categories  (id, name, parent_id)  -- self-referential for hierarchy
products    (id, name, description, price, stock, category_id, seller_id)
orders      (id, user_id, address_id, status, total, created_at)
order_items (id, order_id, product_id, quantity, unit_price)
payments    (id, order_id, method, status, amount, processed_at)
reviews     (id, user_id, product_id, rating, body, created_at)
</code></pre><p>Key design decisions:</p><ul><li><code>order_items.unit_price</code> stores price at time of purchase — product price can change later</li><li><code>categories.parent_id</code> self-references for nested categories (Electronics &gt; Phones &gt; Android)</li><li><code>orders.status</code> uses an ENUM or varchar with CHECK constraint (pending, paid, shipped, delivered, cancelled)</li><li>Index on <code>products(category_id)</code>, <code>orders(user_id)</code>, <code>order_items(order_id)</code></li></ul><h3>Blog System</h3><pre><code class="language-ruby">users      (id, username, email, bio, avatar_url)
posts      (id, author_id, title, slug, body, status, published_at, created_at)
tags       (id, name, slug)
post_tags  (post_id, tag_id)  -- junction table
comments   (id, post_id, user_id, parent_id, body, created_at)
</code></pre><p>Key design decisions:</p><ul><li><code>posts.slug</code> is UNIQUE and indexed — used in URLs instead of exposing numeric IDs</li><li><code>comments.parent_id</code> self-references for threaded replies</li><li><code>posts.status</code> ENUM: draft, published, archived</li><li>Full-text index on <code>posts(title, body)</code> for search</li></ul><h3>Banking System</h3><pre><code class="language-ruby">customers     (id, name, national_id, email, kyc_status)
accounts      (id, customer_id, type, balance, currency, status, created_at)
transactions  (id, from_account_id, to_account_id, amount, type, status, created_at, reference_id)
audit_log     (id, table_name, row_id, action, changed_by, changed_at, old_values, new_values)
</code></pre><p>Key design decisions:</p><ul><li><strong>Never update balance directly.</strong> Balance is derived from transactions, or updated only inside a transaction with locking</li><li><code>transactions</code> is append-only — never update or delete transaction rows</li><li><code>reference_id</code> is idempotency key — prevents duplicate charges if client retries</li><li>Use <code>SERIALIZABLE</code> isolation for transfers or optimistic locking with a version column</li><li><code>audit_log</code> uses a trigger on accounts and transactions — every change is recorded</li></ul><pre><code class="language-php">-- Safe transfer with locking
BEGIN;
  SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;  -- exclusive row lock
  SELECT balance FROM accounts WHERE id = 2 FOR UPDATE;
  UPDATE accounts SET balance = balance - 500 WHERE id = 1;
  UPDATE accounts SET balance = balance + 500 WHERE id = 2;
  INSERT INTO transactions (from_account_id, to_account_id, amount, type, status)
    VALUES (1, 2, 500, 'transfer', 'completed');
COMMIT;
</code></pre><hr><h2>19. Quick Revision Summary</h2><p><strong>Fundamentals</strong></p><ul><li>RDBMS stores data in tables with enforced relationships via keys</li><li>Primary key: unique + not null + immutable. Foreign key: references PK in another table</li><li>Constraints live in the DB, not just the app</li></ul><p><strong>SQL</strong></p><ul><li>DDL (schema), DML (data changes), DQL (queries), TCL (transactions)</li><li>WHERE filters rows, HAVING filters groups, you can't use aggregates in WHERE</li><li>Joins combine tables: INNER (matches only), LEFT (all left), FULL (all rows)</li><li>Window functions keep all rows + add computed column, unlike GROUP BY</li></ul><p><strong>Normalization</strong></p><ul><li>1NF: atomic values. 2NF: no partial deps. 3NF: no transitive deps</li><li>Denormalize for performance only after proving it's needed</li></ul><p><strong>Indexing</strong></p><ul><li>B-tree default, left-prefix rule for composite indexes</li><li>Indexes slow writes — don't over-index write-heavy tables</li><li>Covering index: query fetches everything from the index, never touches the table</li></ul><p><strong>Transactions</strong></p><ul><li>ACID: Atomicity, Consistency, Isolation, Durability</li><li>Higher isolation = safer, but more contention</li><li>Deadlocks: always acquire locks in the same order</li></ul><p><strong>Scaling</strong></p><ul><li>Vertical first, then replicas for reads, then sharding as last resort</li><li>Replication has lag — don't read from replica immediately after writing</li></ul><hr><h2>Conclusion</h2><p>This RDBMS cheatsheet covers everything from core fundamentals to real-world system design, giving you a solid foundation for interviews and practical development. Focus on understanding the concepts, not just memorizing them—because real strength comes from applying these ideas in real systems.</p><p>If you found this helpful, consider sharing it with your friends, developers, or teammates—it might help someone else prepare smarter and faster.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>RDBMS</category>
            <category>SQL</category>
            <category>Database</category>
            <category>System Design</category>
            <category>ACID</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/RDBMS_Thumbnail_e34852d32c.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Low Level Design (LLD) in One Shot – Complete Guide for Interviews & Real-World Systems]]></title>
            <link>https://www.codingshuttle.com/blogs/low-level-design-lld-in-one-shot-complete-guide-for-interviews-and-real-world-systems</link>
            <guid>https://www.codingshuttle.com/blogs/low-level-design-lld-in-one-shot-complete-guide-for-interviews-and-real-world-systems</guid>
            <pubDate>Mon, 23 Mar 2026 17:39:47 GMT</pubDate>
            <description><![CDATA[A practical cheatsheet for mastering Low Level Design (LLD), covering OOP, SOLID, design patterns, and clean code. Built for interview preparation and real-world system design.]]></description>
            <content:encoded><![CDATA[<p><strong>Low Level Design (LLD) in One Shot – Complete Guide for Interviews &amp; Real-World Systems</strong></p><p>A complete and practical guide to Low Level Design (LLD), covering OOP principles, SOLID, design patterns, class relationships, and real-world system design problems. This cheatsheet is designed to help backend developers and interview candidates build clean, scalable, and maintainable code with confidence.</p><hr><h2>1. LLD Fundamentals</h2><h3>What is LLD</h3><p>Low Level Design is the process of defining the internal structure of individual components in a system. It answers the question: <i>how</i> will each module be built, not just <i>what</i> it will do.</p><p>While High Level Design (HLD) tells you that a system has a "Notification Service," LLD tells you what classes exist inside it, how they communicate, what patterns they use, and how edge cases are handled.</p><p>In interviews, LLD tests your ability to translate requirements into clean, extensible, object-oriented code. In real systems, good LLD is what separates a codebase that survives scaling from one that collapses under its own weight.</p><h3>LLD vs HLD</h3><figure class="table"><table><thead><tr><th>Aspect</th><th>HLD (High Level Design)</th><th>LLD (Low Level Design)</th></tr></thead><tbody><tr><td>Focus</td><td>System architecture</td><td>Component internals</td></tr><tr><td>Scope</td><td>Macro (services, databases, infra)</td><td>Micro (classes, methods, patterns)</td></tr><tr><td>Audience</td><td>Architects, stakeholders</td><td>Engineers, tech leads</td></tr><tr><td>Output</td><td>Architecture diagrams, service contracts</td><td>Class diagrams, code structure</td></tr><tr><td>Tools</td><td>Block diagrams, sequence diagrams</td><td>UML class diagrams, code</td></tr><tr><td>Interview Round</td><td>System design round</td><td>Machine coding / OOP round</td></tr></tbody></table></figure><h3>Importance in Interviews and Real Systems</h3><p>In FAANG and product-based interviews, the LLD round evaluates:</p><ul><li>Whether you can identify the right abstractions</li><li>Whether your code is extensible without modification</li><li>Whether you understand design patterns and know when NOT to use them</li><li>Whether your classes have clear, single responsibilities</li></ul><p>In real systems, poor LLD leads to:</p><ul><li>God classes that nobody wants to touch</li><li>Tight coupling that makes testing a nightmare</li><li>Impossible-to-extend code whenever requirements change</li></ul><h3>Clean Code Principles</h3><p>These are not optional niceties. They are the baseline expectation.</p><ul><li><strong>Readability</strong>: Code is read far more than it is written. Name things clearly. A method called <code>processData()</code> tells you nothing. <code>calculateInvoiceTotal()</code> tells you everything.</li><li><strong>Maintainability</strong>: Can a new engineer fix a bug without understanding the entire codebase? If not, your design has failed.</li><li><strong>Extensibility</strong>: Can you add a new payment method without touching existing payment code? Good LLD makes this possible.</li></ul><hr><h2>2. Object-Oriented Programming (OOP)</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Four_pillars_of_OOP_de774cc4e8.webp" alt="Four pillars of OOP" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Four_pillars_of_OOP_de774cc4e8.webp 178w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Four_pillars_of_OOP_de774cc4e8.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Four_pillars_of_OOP_de774cc4e8.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Four_pillars_of_OOP_de774cc4e8.webp 1000w," sizes="100vw"><figcaption>Four pillars of OOP</figcaption></figure><h3>Class and Object</h3><p>A <strong>class</strong> is a blueprint. An <strong>object</strong> is a live instance of that blueprint with its own state.</p><pre><code class="language-java">public class BankAccount {
    private String accountId;
    private double balance;

    public BankAccount(String accountId, double initialBalance) {
        this.accountId = accountId;
        this.balance = initialBalance;
    }

    public double getBalance() {
        return balance;
    }
}

// Object
BankAccount account = new BankAccount("ACC001", 5000.0);
</code></pre><p><strong>Common mistake</strong>: Treating classes as data bags with no behavior. If your class only has getters/setters and no meaningful methods, it is an anemic domain model - a known anti-pattern.</p><h3>Encapsulation</h3><p>Hide internal state. Expose only what is necessary through a controlled interface.</p><p><strong>Why it matters</strong>: If <code>balance</code> is public, any part of the system can directly set it to -99999. Encapsulation prevents this.</p><pre><code class="language-java">// BAD
public class Order {
    public double total; // Anyone can mutate this
}

// GOOD
public class Order {
    private double total;

    public void addItem(double price) {
        if (price &lt;= 0) throw new IllegalArgumentException("Price must be positive");
        this.total += price;
    }

    public double getTotal() {
        return total;
    }
}
</code></pre><h3>Abstraction</h3><p>Expose <i>what</i> something does, hide <i>how</i> it does it. Achieved through interfaces and abstract classes.</p><pre><code class="language-java">public interface PaymentGateway {
    boolean processPayment(double amount, String currency);
}

public class StripeGateway implements PaymentGateway {
    @Override
    public boolean processPayment(double amount, String currency) {
        // Stripe-specific HTTP calls, token handling, etc.
        return true;
    }
}
</code></pre><p>The caller only knows about <code>PaymentGateway</code>. It does not care whether it is Stripe, Razorpay, or PayPal underneath.</p><h3>Inheritance</h3><p>A subclass inherits state and behavior from a parent class. Use it when a genuine "is-a" relationship exists.</p><pre><code class="language-java">public class Vehicle {
    protected String brand;
    protected int speed;

    public void accelerate(int amount) {
        this.speed += amount;
    }
}

public class Car extends Vehicle {
    private int numberOfDoors;

    public Car(String brand, int numberOfDoors) {
        this.brand = brand;
        this.numberOfDoors = numberOfDoors;
    }
}
</code></pre><p><strong>Trade-off</strong>: Inheritance creates tight coupling between parent and child. Prefer composition over inheritance when the relationship is behavioral, not structural. If you are inheriting just to reuse methods, use composition instead.</p><h3>Polymorphism</h3><p><strong>Compile-time (Static)</strong>: Method overloading - same method name, different parameter signatures, resolved at compile time.</p><pre><code class="language-java">public class Calculator {
    public int add(int a, int b) { return a + b; }
    public double add(double a, double b) { return a + b; }
}
</code></pre><p><strong>Runtime (Dynamic)</strong>: Method overriding - subclass provides its own implementation of a parent method, resolved at runtime.</p><pre><code class="language-java">public abstract class Notification {
    public abstract void send(String message);
}

public class EmailNotification extends Notification {
    @Override
    public void send(String message) {
        System.out.println("Sending email: " + message);
    }
}

public class SMSNotification extends Notification {
    @Override
    public void send(String message) {
        System.out.println("Sending SMS: " + message);
    }
}

// Runtime dispatch
Notification notif = new EmailNotification();
notif.send("Your order is confirmed"); // Calls EmailNotification's implementation
</code></pre><p><strong>Interview insight</strong>: When an interviewer asks you to add a new notification type, the right answer is to create a new subclass, not to add an <code>if-else</code> block. That is polymorphism at work.</p><hr><h2>3. SOLID Principles</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/SOLID_principles_1e330d4f5f.webp" alt="SOLID principles" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_SOLID_principles_1e330d4f5f.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_SOLID_principles_1e330d4f5f.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_SOLID_principles_1e330d4f5f.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_SOLID_principles_1e330d4f5f.webp 1000w," sizes="100vw"><figcaption>SOLID principles</figcaption></figure><h3>S - Single Responsibility Principle (SRP)</h3><p>A class should have one and only one reason to change.</p><pre><code class="language-java">// BAD - This class does too much
public class UserService {
    public void createUser(User user) { /* ... */ }
    public void sendWelcomeEmail(User user) { /* ... */ }
    public void generateUserReport(User user) { /* ... */ }
}

// GOOD - Separate concerns
public class UserService {
    public void createUser(User user) { /* ... */ }
}

public class EmailService {
    public void sendWelcomeEmail(User user) { /* ... */ }
}

public class ReportService {
    public void generateUserReport(User user) { /* ... */ }
}
</code></pre><p><strong>Why it matters</strong>: When email logic changes, you do not want to risk breaking user creation logic. They are separate concerns and belong in separate classes.</p><h3>O - Open/Closed Principle (OCP)</h3><p>Classes should be open for extension, closed for modification.</p><pre><code class="language-java">// BAD - Adding a new discount type means modifying this class
public class DiscountCalculator {
    public double calculate(String discountType, double price) {
        if (discountType.equals("SEASONAL")) return price * 0.9;
        if (discountType.equals("EMPLOYEE")) return price * 0.7;
        return price; // Adding new type = modifying this method
    }
}

// GOOD
public interface DiscountStrategy {
    double apply(double price);
}

public class SeasonalDiscount implements DiscountStrategy {
    public double apply(double price) { return price * 0.9; }
}

public class EmployeeDiscount implements DiscountStrategy {
    public double apply(double price) { return price * 0.7; }
}

public class DiscountCalculator {
    public double calculate(DiscountStrategy strategy, double price) {
        return strategy.apply(price);
    }
}
</code></pre><p>Adding a new discount type now means creating a new class, not touching existing code.</p><h3>L - Liskov Substitution Principle (LSP)</h3><p>If S is a subtype of T, objects of type T should be replaceable with objects of type S without breaking the program.</p><pre><code class="language-java">// BAD - Violates LSP
public class Rectangle {
    protected int width, height;
    public void setWidth(int w) { this.width = w; }
    public void setHeight(int h) { this.height = h; }
    public int area() { return width * height; }
}

public class Square extends Rectangle {
    @Override
    public void setWidth(int w) { this.width = w; this.height = w; } // Breaks contract
    @Override
    public void setHeight(int h) { this.width = h; this.height = h; }
}
// Code that sets width=5, height=10 and expects area=50 breaks when given a Square

// GOOD - Use a common interface instead
public interface Shape {
    int area();
}

public class Rectangle implements Shape {
    private int width, height;
    public Rectangle(int width, int height) { this.width = width; this.height = height; }
    public int area() { return width * height; }
}

public class Square implements Shape {
    private int side;
    public Square(int side) { this.side = side; }
    public int area() { return side * side; }
}
</code></pre><p><strong>Key test</strong>: If you have to override a method and throw an exception or change behavior in a way that breaks caller assumptions, you are violating LSP.</p><h3>I - Interface Segregation Principle (ISP)</h3><p>Clients should not be forced to depend on interfaces they do not use.</p><pre><code class="language-java">// BAD - Forced to implement irrelevant methods
public interface Worker {
    void work();
    void eat();
    void sleep();
}

public class RobotWorker implements Worker {
    public void work() { /* ... */ }
    public void eat() { throw new UnsupportedOperationException(); } // Robots don't eat
    public void sleep() { throw new UnsupportedOperationException(); }
}

// GOOD - Split into focused interfaces
public interface Workable {
    void work();
}

public interface HumanNeeds {
    void eat();
    void sleep();
}

public class HumanWorker implements Workable, HumanNeeds {
    public void work() { /* ... */ }
    public void eat() { /* ... */ }
    public void sleep() { /* ... */ }
}

public class RobotWorker implements Workable {
    public void work() { /* ... */ }
}
</code></pre><h3>D - Dependency Inversion Principle (DIP)</h3><p>High-level modules should not depend on low-level modules. Both should depend on abstractions.</p><pre><code class="language-java">// BAD - High-level class depends on a concrete low-level class
public class OrderService {
    private MySQLOrderRepository repository = new MySQLOrderRepository(); // Hardcoded dependency

    public void placeOrder(Order order) {
        repository.save(order);
    }
}

// GOOD - Depend on abstraction, inject the implementation
public interface OrderRepository {
    void save(Order order);
}

public class OrderService {
    private final OrderRepository repository;

    public OrderService(OrderRepository repository) { // Injected from outside
        this.repository = repository;
    }

    public void placeOrder(Order order) {
        repository.save(order);
    }
}
</code></pre><p>Now you can swap <code>MySQLOrderRepository</code> with <code>MongoOrderRepository</code> or a mock in tests without touching <code>OrderService</code>.</p><hr><h2>4. Design Patterns</h2><p>Design patterns are reusable solutions to common design problems. They are not copy-paste templates. They are thinking tools.</p><h3>Creational Patterns</h3><h3>Singleton</h3><p>Ensures only one instance of a class exists throughout the application lifecycle.</p><p><strong>When to use</strong>: Shared resources like configuration, connection pools, logging instances.</p><p><strong>When NOT to use</strong>: If you find yourself using Singleton everywhere, you are probably hiding poor dependency management.</p><pre><code class="language-java">public class ConfigManager {
    private static volatile ConfigManager instance;
    private final Map&lt;String, String&gt; configs = new HashMap&lt;&gt;();

    private ConfigManager() {
        // Load configs from file or env
    }

    public static ConfigManager getInstance() {
        if (instance == null) {
            synchronized (ConfigManager.class) {
                if (instance == null) {
                    instance = new ConfigManager();
                }
            }
        }
        return instance;
    }

    public String get(String key) {
        return configs.getOrDefault(key, "");
    }
}
</code></pre><p><strong>Common mistake</strong>: Not using <code>volatile</code> and double-checked locking. Without <code>volatile</code>, the JVM can reorder instructions and return a partially constructed object.</p><p><strong>Trade-off</strong>: Makes unit testing hard because you cannot easily inject a mock. Prefer dependency injection over Singleton wherever possible.</p><h3>Factory Method</h3><p>Delegates the creation of objects to subclasses or dedicated factory methods. Decouples object creation from usage.</p><p><strong>When to use</strong>: When the exact type of object to create depends on runtime conditions.</p><pre><code class="language-java">public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) { System.out.println("Email: " + message); }
}

public class PushNotification implements Notification {
    public void send(String message) { System.out.println("Push: " + message); }
}

public class NotificationFactory {
    public static Notification create(String type) {
        return switch (type) {
            case "EMAIL" -&gt; new EmailNotification();
            case "PUSH" -&gt; new PushNotification();
            default -&gt; throw new IllegalArgumentException("Unknown notification type: " + type);
        };
    }
}

// Usage
Notification notif = NotificationFactory.create("EMAIL");
notif.send("Your order shipped");
</code></pre><p><strong>Trade-off</strong>: Adding a new type means modifying the factory. Use an abstract factory or registry pattern if you have many types or need plugin-style extensibility.</p><h3>Builder</h3><p>Constructs a complex object step by step. Useful when an object has many optional fields and telescoping constructors become unreadable.</p><pre><code class="language-java">public class UserProfile {
    private final String userId;
    private final String name;
    private final String email;
    private final String phoneNumber;
    private final String address;

    private UserProfile(Builder builder) {
        this.userId = builder.userId;
        this.name = builder.name;
        this.email = builder.email;
        this.phoneNumber = builder.phoneNumber;
        this.address = builder.address;
    }

    public static class Builder {
        private final String userId; // Required
        private final String name;   // Required
        private String email;
        private String phoneNumber;
        private String address;

        public Builder(String userId, String name) {
            this.userId = userId;
            this.name = name;
        }

        public Builder email(String email) { this.email = email; return this; }
        public Builder phoneNumber(String phone) { this.phoneNumber = phone; return this; }
        public Builder address(String address) { this.address = address; return this; }

        public UserProfile build() {
            return new UserProfile(this);
        }
    }
}

// Usage - clean, readable, no positional argument confusion
UserProfile profile = new UserProfile.Builder("U001", "Alice")
    .email("alice@example.com")
    .address("Pune, India")
    .build();
</code></pre><p><strong>Trade-off</strong>: More boilerplate. In production, Lombok's <code>@Builder</code> handles this, but knowing the manual pattern is essential for interviews.</p><h3>Structural Patterns</h3><h3>Adapter</h3><p>Wraps an incompatible interface to make it compatible with what the client expects.</p><p><strong>Real-world analogy</strong>: A power plug adapter. The socket interface does not change, your device does not change, but the adapter bridges them.</p><pre><code class="language-java">// Third-party payment library we cannot modify
public class LegacyPaymentSDK {
    public String makeTransaction(String accountNo, float rupees) {
        return "SUCCESS";
    }
}

// Interface our system expects
public interface PaymentProcessor {
    boolean processPayment(String accountId, double amount);
}

// Adapter bridges the gap
public class PaymentAdapter implements PaymentProcessor {
    private final LegacyPaymentSDK legacySDK;

    public PaymentAdapter(LegacyPaymentSDK sdk) {
        this.legacySDK = sdk;
    }

    @Override
    public boolean processPayment(String accountId, double amount) {
        String result = legacySDK.makeTransaction(accountId, (float) amount);
        return "SUCCESS".equals(result);
    }
}
</code></pre><h3>Decorator</h3><p>Adds behavior to an object dynamically without modifying its class or creating subclasses for every combination.</p><p><strong>When to use</strong>: When you need to stack behaviors, like adding logging, caching, retry logic to a service.</p><pre><code class="language-java">public interface DataReader {
    String read();
}

public class FileDataReader implements DataReader {
    public String read() { return "raw file data"; }
}

public class EncryptedDataReader implements DataReader {
    private final DataReader wrapped;
    public EncryptedDataReader(DataReader reader) { this.wrapped = reader; }
    public String read() { return decrypt(wrapped.read()); }
    private String decrypt(String data) { return "decrypted: " + data; }
}

public class CachedDataReader implements DataReader {
    private final DataReader wrapped;
    private String cache;
    public CachedDataReader(DataReader reader) { this.wrapped = reader; }
    public String read() {
        if (cache == null) cache = wrapped.read();
        return cache;
    }
}

// Usage - stacking decorators
DataReader reader = new CachedDataReader(new EncryptedDataReader(new FileDataReader()));
reader.read();
</code></pre><p><strong>Trade-off</strong>: Debugging a deeply nested decorator chain can be confusing. Use clear naming and keep the chain shallow.</p><h3>Behavioral Patterns</h3><h3>Strategy</h3><p>Defines a family of algorithms, encapsulates each one, and makes them interchangeable at runtime.</p><p><strong>When to use</strong>: When you have multiple ways to do something and you want to switch between them without conditionals.</p><pre><code class="language-java">public interface SortStrategy {
    void sort(int[] data);
}

public class QuickSort implements SortStrategy {
    public void sort(int[] data) { /* quicksort impl */ }
}

public class MergeSort implements SortStrategy {
    public void sort(int[] data) { /* mergesort impl */ }
}

public class DataProcessor {
    private SortStrategy strategy;

    public DataProcessor(SortStrategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(SortStrategy strategy) {
        this.strategy = strategy;
    }

    public void process(int[] data) {
        strategy.sort(data);
    }
}
</code></pre><p><strong>Interview insight</strong>: Every time you see a chain of if-else or switch based on a "type," ask yourself if Strategy pattern cleans it up.</p><h3>Observer</h3><p>Defines a one-to-many dependency so that when one object changes state, all its dependents are notified automatically.</p><p><strong>When to use</strong>: Event systems, notification pipelines, pub-sub mechanisms.</p><pre><code class="language-java">public interface EventListener {
    void onEvent(String eventType, Object data);
}

public class EventManager {
    private final Map&lt;String, List&lt;EventListener&gt;&gt; listeners = new HashMap&lt;&gt;();

    public void subscribe(String eventType, EventListener listener) {
        listeners.computeIfAbsent(eventType, k -&gt; new ArrayList&lt;&gt;()).add(listener);
    }

    public void publish(String eventType, Object data) {
        List&lt;EventListener&gt; eventListeners = listeners.getOrDefault(eventType, Collections.emptyList());
        for (EventListener listener : eventListeners) {
            listener.onEvent(eventType, data);
        }
    }
}

public class OrderService {
    private final EventManager eventManager;

    public OrderService(EventManager eventManager) {
        this.eventManager = eventManager;
    }

    public void placeOrder(Order order) {
        // save order
        eventManager.publish("ORDER_PLACED", order);
    }
}

public class EmailService implements EventListener {
    public void onEvent(String eventType, Object data) {
        System.out.println("Sending confirmation email for: " + eventType);
    }
}
</code></pre><p><strong>Trade-off</strong>: If observers are slow or throw exceptions, they can affect the publisher. Consider async notification for production use.</p><h3>Command</h3><p>Encapsulates a request as an object, allowing you to parameterize, queue, log, or undo operations.</p><p><strong>When to use</strong>: Undo/redo functionality, job queues, audit trails.</p><pre><code class="language-java">public interface Command {
    void execute();
    void undo();
}

public class TransferMoneyCommand implements Command {
    private final BankAccount from;
    private final BankAccount to;
    private final double amount;

    public TransferMoneyCommand(BankAccount from, BankAccount to, double amount) {
        this.from = from;
        this.to = to;
        this.amount = amount;
    }

    public void execute() {
        from.debit(amount);
        to.credit(amount);
    }

    public void undo() {
        to.debit(amount);
        from.credit(amount);
    }
}

public class CommandHistory {
    private final Deque&lt;Command&gt; history = new ArrayDeque&lt;&gt;();

    public void executeCommand(Command cmd) {
        cmd.execute();
        history.push(cmd);
    }

    public void undoLast() {
        if (!history.isEmpty()) history.pop().undo();
    }
}
</code></pre><hr><h2>5. Class Design and Relationships</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/UML_class_diagrams_c2e8630d9e.webp" alt="UML class diagrams " srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_UML_class_diagrams_c2e8630d9e.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_UML_class_diagrams_c2e8630d9e.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_UML_class_diagrams_c2e8630d9e.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_UML_class_diagrams_c2e8630d9e.webp 1000w," sizes="100vw"><figcaption>UML class diagrams&nbsp;</figcaption></figure><h3>Types of Relationships</h3><figure class="table"><table><thead><tr><th>Relationship</th><th>Meaning</th><th>Lifetime Dependency</th><th>Example</th></tr></thead><tbody><tr><td>Association</td><td>Class A uses Class B</td><td>Independent</td><td>Teacher and Student</td></tr><tr><td>Aggregation</td><td>Class A has Class B (weak ownership)</td><td>B can exist without A</td><td>Department and Employee</td></tr><tr><td>Composition</td><td>Class A owns Class B (strong ownership)</td><td>B cannot exist without A</td><td>House and Room</td></tr><tr><td>Dependency</td><td>Class A temporarily uses Class B</td><td>No ownership</td><td>OrderService uses PaymentGateway</td></tr></tbody></table></figure><pre><code class="language-java">// Association - loose relationship, no ownership
public class Driver {
    private Car car; // Driver can exist without car and vice versa
}

// Aggregation - weak ownership
public class Department {
    private List&lt;Employee&gt; employees; // Employees can exist even if department is dissolved
}

// Composition - strong ownership, child cannot exist without parent
public class House {
    private final List&lt;Room&gt; rooms; // Rooms are created and destroyed with the house

    public House(int numberOfRooms) {
        this.rooms = new ArrayList&lt;&gt;();
        for (int i = 0; i &lt; numberOfRooms; i++) {
            rooms.add(new Room());
        }
    }
}

// Dependency - method-level, temporary use
public class InvoiceService {
    public void generate(PdfGenerator generator, Invoice invoice) { // Uses generator but doesn't own it
        generator.create(invoice);
    }
}
</code></pre><h3>UML Class Diagram Basics</h3><p>A class box has three sections:</p><pre><code class="language-ruby">+------------------+
|    ClassName     |
+------------------+
| - privateField   |
| + publicField    |
+------------------+
| + method(): void |
+------------------+
</code></pre><ul><li><code>-</code> = private, <code>+</code> = public, <code>#</code> = protected</li><li>Arrow with hollow triangle = Inheritance</li><li>Dashed arrow = Dependency/Implementation</li><li>Solid arrow with hollow head = inheritance</li><li>Dashed arrow = dependency or implements</li><li>Filled diamond = composition</li><li>Hollow diamond = aggregation</li></ul><p>When drawing in an interview, label your arrows. A diagram without labels communicates nothing.</p><hr><h2>6. Clean Code Practices</h2><h3>DRY, KISS, YAGNI</h3><figure class="table"><table><thead><tr><th>Principle</th><th>Full Form</th><th>What It Means</th><th>Common Violation</th></tr></thead><tbody><tr><td>DRY</td><td>Don't Repeat Yourself</td><td>Extract duplicated logic into reusable units</td><td>Copy-pasting validation logic in every method</td></tr><tr><td>KISS</td><td>Keep It Simple, Stupid</td><td>Simplest solution that works is best</td><td>Over-engineering a problem that needs 10 lines with 200 lines</td></tr><tr><td>YAGNI</td><td>You Aren't Gonna Need It</td><td>Do not build features until they are needed</td><td>Adding abstract factories for a system with one concrete type</td></tr></tbody></table></figure><h3>Naming Conventions</h3><p>Good names are the cheapest form of documentation.</p><figure class="table"><table><thead><tr><th>What</th><th>Convention</th><th>BAD Example</th><th>GOOD Example</th></tr></thead><tbody><tr><td>Class</td><td>PascalCase, noun</td><td><code>ProcessData</code></td><td><code>InvoiceProcessor</code></td></tr><tr><td>Method</td><td>camelCase, verb</td><td><code>data()</code></td><td><code>calculateTotalPrice()</code></td></tr><tr><td>Boolean variable</td><td>camelCase, is/has/can prefix</td><td><code>active</code></td><td><code>isActive</code>, <code>hasExpired</code></td></tr><tr><td>Constant</td><td>UPPER_SNAKE_CASE</td><td><code>maxRetry</code></td><td><code>MAX_RETRY_COUNT</code></td></tr><tr><td>Interface</td><td>PascalCase, noun or adjective</td><td><code>IPayable</code></td><td><code>Payable</code>, <code>PaymentProcessor</code></td></tr><tr><td>Package</td><td>lowercase, dot-separated</td><td><code>UserService</code></td><td><code>com.company.user.service</code></td></tr></tbody></table></figure><h3>Layered Architecture</h3><pre><code class="language-ruby">Controller Layer    → Handles HTTP, input parsing, response formatting
     |
Service Layer       → Business logic, orchestration, transaction management
     |
Repository Layer    → Data access, persistence, query execution
</code></pre><pre><code class="language-java">// Controller - handles request/response only
@RestController
public class OrderController {
    private final OrderService orderService;

    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping("/orders")
    public ResponseEntity&lt;OrderResponse&gt; createOrder(@Valid @RequestBody CreateOrderRequest request) {
        OrderDTO order = orderService.createOrder(request);
        return ResponseEntity.ok(new OrderResponse(order));
    }
}

// Service - owns the business logic
@Service
public class OrderService {
    private final OrderRepository orderRepository;
    private final InventoryService inventoryService;

    public OrderDTO createOrder(CreateOrderRequest request) {
        inventoryService.reserve(request.getItems());
        Order order = Order.from(request);
        Order saved = orderRepository.save(order);
        return OrderDTO.from(saved);
    }
}

// Repository - data access only
@Repository
public interface OrderRepository extends JpaRepository&lt;Order, String&gt; {
    List&lt;Order&gt; findByCustomerId(String customerId);
}
</code></pre><p><strong>Common mistake</strong>: Putting business logic in controllers or database queries in service classes. These layers exist for a reason.</p><hr><h2>7. Common LLD Problems</h2><h3>Parking Lot</h3><p><strong>Key requirement</strong>: Track available spots, support multiple vehicle types, calculate fare.</p><p><strong>Key classes</strong>:</p><pre><code class="language-java">public enum VehicleType { BIKE, CAR, TRUCK }

public class Vehicle {
    private final String licensePlate;
    private final VehicleType type;
}

public class ParkingSpot {
    private final String spotId;
    private final VehicleType allowedType;
    private boolean isOccupied;
    private Vehicle parkedVehicle;
}

public class ParkingFloor {
    private final String floorId;
    private final List&lt;ParkingSpot&gt; spots;

    public Optional&lt;ParkingSpot&gt; findAvailableSpot(VehicleType type) {
        return spots.stream()
            .filter(s -&gt; s.getAllowedType() == type &amp;&amp; !s.isOccupied())
            .findFirst();
    }
}

public class ParkingLot {
    private static ParkingLot instance; // Singleton - one lot per JVM
    private final List&lt;ParkingFloor&gt; floors;
    private final FareCalculator fareCalculator;

    public Ticket park(Vehicle vehicle) {
        for (ParkingFloor floor : floors) {
            Optional&lt;ParkingSpot&gt; spot = floor.findAvailableSpot(vehicle.getType());
            if (spot.isPresent()) {
                spot.get().park(vehicle);
                return new Ticket(vehicle, spot.get(), LocalDateTime.now());
            }
        }
        throw new ParkingLotFullException("No available spot for: " + vehicle.getType());
    }
}

public interface FareCalculator {
    double calculate(Ticket ticket);
}

public class HourlyFareCalculator implements FareCalculator {
    private final Map&lt;VehicleType, Double&gt; ratePerHour;

    public double calculate(Ticket ticket) {
        long hours = ChronoUnit.HOURS.between(ticket.getEntryTime(), LocalDateTime.now());
        return ratePerHour.get(ticket.getVehicle().getType()) * Math.max(1, hours);
    }
}
</code></pre><p><strong>Design decisions</strong>:</p><ul><li><code>ParkingLot</code> is Singleton because there is only one physical lot</li><li><code>FareCalculator</code> is an interface (Strategy pattern) so pricing logic can change without touching <code>ParkingLot</code></li><li><code>findAvailableSpot</code> returns <code>Optional</code> to force callers to handle the "no spot" case explicitly</li></ul><h3>Library Management System</h3><p><strong>Key classes</strong>: <code>Book</code>, <code>BookCopy</code>, <code>Member</code>, <code>Loan</code>, <code>LibraryCatalog</code>, <code>LoanService</code></p><pre><code class="language-java">public class Book {
    private final String isbn;
    private final String title;
    private final String author;
}

public class BookCopy {
    private final String copyId;
    private final Book book;
    private boolean isAvailable;
}

public class Member {
    private final String memberId;
    private final List&lt;Loan&gt; activeLoans;

    public boolean canBorrow() {
        return activeLoans.size() &lt; MAX_LOANS_ALLOWED;
    }
}

public class Loan {
    private final BookCopy copy;
    private final Member member;
    private final LocalDate borrowDate;
    private LocalDate returnDate;
    private LoanStatus status;
}

public class LoanService {
    private final LoanRepository loanRepository;
    private final NotificationService notificationService;

    public Loan issueBook(Member member, BookCopy copy) {
        if (!member.canBorrow()) throw new LoanLimitExceededException(member.getMemberId());
        if (!copy.isAvailable()) throw new BookNotAvailableException(copy.getCopyId());

        copy.setAvailable(false);
        Loan loan = new Loan(copy, member, LocalDate.now());
        loanRepository.save(loan);
        notificationService.sendBorrowConfirmation(member, copy.getBook());
        return loan;
    }
}
</code></pre><p><strong>Design decisions</strong>:</p><ul><li>Separate <code>Book</code> (logical entity) from <code>BookCopy</code> (physical instance). A library has one "Clean Code" book but may have 5 physical copies.</li><li><code>canBorrow()</code> is a domain method on <code>Member</code>, not a service-level check. Domain logic belongs in domain objects.</li></ul><h3>Elevator System</h3><p><strong>Key classes</strong>: <code>Elevator</code>, <code>ElevatorController</code>, <code>Request</code>, <code>ElevatorScheduler</code></p><pre><code class="language-java">public enum Direction { UP, DOWN, IDLE }

public class Elevator {
    private final int elevatorId;
    private int currentFloor;
    private Direction direction;
    private ElevatorStatus status;
    private final TreeSet&lt;Integer&gt; floorsToVisit = new TreeSet&lt;&gt;();

    public void addFloorRequest(int floor) {
        floorsToVisit.add(floor);
    }

    public void move() {
        if (floorsToVisit.isEmpty()) { direction = Direction.IDLE; return; }
        int nextFloor = direction == Direction.UP
            ? floorsToVisit.first()
            : floorsToVisit.last();
        currentFloor = nextFloor;
        floorsToVisit.remove(nextFloor);
    }
}

public interface ElevatorScheduler {
    Elevator selectElevator(List&lt;Elevator&gt; elevators, int requestedFloor, Direction direction);
}

public class NearestElevatorScheduler implements ElevatorScheduler {
    public Elevator selectElevator(List&lt;Elevator&gt; elevators, int floor, Direction direction) {
        return elevators.stream()
            .min(Comparator.comparingInt(e -&gt; Math.abs(e.getCurrentFloor() - floor)))
            .orElseThrow();
    }
}
</code></pre><p><strong>Design decisions</strong>:</p><ul><li><code>ElevatorScheduler</code> is an interface. You can swap in SCAN algorithm, LOOK algorithm, or nearest-first without changing elevator internals.</li><li><code>TreeSet</code> for floor requests because it keeps floors sorted, making directional traversal efficient.</li></ul><h3>Splitwise</h3><p><strong>Key classes</strong>: <code>User</code>, <code>Expense</code>, <code>Split</code>, <code>Balance</code>, <code>ExpenseService</code></p><pre><code class="language-java">public abstract class Split {
    protected final User user;
    protected double amount;
    public abstract void calculateAmount(double totalAmount, int numberOfPeople);
}

public class EqualSplit extends Split {
    public EqualSplit(User user) { super(user); }
    public void calculateAmount(double total, int people) { this.amount = total / people; }
}

public class PercentSplit extends Split {
    private final double percent;
    public PercentSplit(User user, double percent) { super(user); this.percent = percent; }
    public void calculateAmount(double total, int people) { this.amount = total * percent / 100; }
}

public class Expense {
    private final String expenseId;
    private final User paidBy;
    private final double totalAmount;
    private final List&lt;Split&gt; splits;
    private final String description;
}

public class BalanceService {
    // Returns simplified balances: who owes whom and how much
    public Map&lt;User, Map&lt;User, Double&gt;&gt; calculateBalances(List&lt;Expense&gt; expenses) {
        Map&lt;User, Map&lt;User, Double&gt;&gt; balances = new HashMap&lt;&gt;();
        for (Expense expense : expenses) {
            User payer = expense.getPaidBy();
            for (Split split : expense.getSplits()) {
                if (!split.getUser().equals(payer)) {
                    balances.computeIfAbsent(split.getUser(), k -&gt; new HashMap&lt;&gt;())
                        .merge(payer, split.getAmount(), Double::sum);
                }
            }
        }
        return balances;
    }
}
</code></pre><p><strong>Design decisions</strong>:</p><ul><li><code>Split</code> is abstract. Different split types (equal, percentage, exact) are subclasses. Adding a new split type does not touch existing code.</li></ul><h3>Shopping Cart</h3><p><strong>Key classes</strong>: <code>Product</code>, <code>CartItem</code>, <code>Cart</code>, <code>PricingEngine</code>, <code>OrderService</code></p><pre><code class="language-java">public class Product {
    private final String productId;
    private final String name;
    private final double basePrice;
    private final int stockCount;
}

public class CartItem {
    private final Product product;
    private int quantity;

    public double getSubtotal() {
        return product.getBasePrice() * quantity;
    }
}

public class Cart {
    private final String cartId;
    private final String userId;
    private final Map&lt;String, CartItem&gt; items = new LinkedHashMap&lt;&gt;();

    public void addItem(Product product, int quantity) {
        items.merge(product.getProductId(),
            new CartItem(product, quantity),
            (existing, newItem) -&gt; { existing.increaseQuantity(quantity); return existing; });
    }

    public double getTotal() {
        return items.values().stream().mapToDouble(CartItem::getSubtotal).sum();
    }
}

public interface PricingRule {
    double apply(Cart cart);
}

public class CouponDiscountRule implements PricingRule {
    private final String couponCode;
    private final double discountPercent;

    public double apply(Cart cart) {
        return cart.getTotal() * (1 - discountPercent / 100);
    }
}
</code></pre><hr><h2>8. Error Handling and Logging</h2><h3>Exception Handling Best Practices</h3><ul><li>Catch specific exceptions, not <code>Exception</code> or <code>Throwable</code></li><li>Never silently swallow exceptions</li><li>Clean up resources in <code>finally</code> or use try-with-resources</li><li>Fail fast: validate inputs at system boundaries</li></ul><pre><code class="language-java">// BAD
try {
    processOrder(order);
} catch (Exception e) {
    // silently ignored - debugging nightmare
}

// GOOD
try {
    processOrder(order);
} catch (InsufficientInventoryException e) {
    log.warn("Inventory check failed for order {}: {}", order.getId(), e.getMessage());
    throw new OrderCreationException("Product out of stock", e);
} catch (PaymentFailedException e) {
    log.error("Payment failed for order {}", order.getId(), e);
    notificationService.alertUser(order.getUserId(), "Payment failed");
    throw e;
}
</code></pre><h3>Custom Exceptions</h3><p>Design your exception hierarchy to mirror your domain.</p><pre><code class="language-java">// Base exception for the domain
public class ApplicationException extends RuntimeException {
    private final String errorCode;

    public ApplicationException(String message, String errorCode) {
        super(message);
        this.errorCode = errorCode;
    }

    public ApplicationException(String message, String errorCode, Throwable cause) {
        super(message, cause);
        this.errorCode = errorCode;
    }

    public String getErrorCode() { return errorCode; }
}

public class ResourceNotFoundException extends ApplicationException {
    public ResourceNotFoundException(String resource, String id) {
        super(resource + " not found with id: " + id, "RESOURCE_NOT_FOUND");
    }
}

public class ValidationException extends ApplicationException {
    private final List&lt;String&gt; violations;

    public ValidationException(List&lt;String&gt; violations) {
        super("Validation failed", "VALIDATION_ERROR");
        this.violations = violations;
    }
}
</code></pre><h3>Logging Levels</h3><figure class="table"><table><thead><tr><th>Level</th><th>When to Use</th><th>Example</th></tr></thead><tbody><tr><td>ERROR</td><td>Unexpected failure, needs immediate attention</td><td>Payment gateway down, DB unreachable</td></tr><tr><td>WARN</td><td>Something unusual happened but system is still running</td><td>Retry attempt, deprecated API used</td></tr><tr><td>INFO</td><td>Normal but significant operations</td><td>Order placed, user logged in</td></tr><tr><td>DEBUG</td><td>Detailed trace for development</td><td>Request payload, SQL query</td></tr><tr><td>TRACE</td><td>Very granular, almost never in production</td><td>Method entry/exit</td></tr></tbody></table></figure><pre><code class="language-java">// Structured logging - always include context
log.info("Order created successfully | orderId={} userId={} amount={}",
    order.getId(), order.getUserId(), order.getTotal());

log.error("Payment failed | orderId={} gateway={} errorCode={}",
    order.getId(), gateway.getName(), response.getErrorCode());

// NEVER log sensitive data
// BAD: log.info("User logged in | password={}", password);
// GOOD: log.info("User logged in | userId={}", userId);
</code></pre><hr><h2>9. Concurrency Basics</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/race_condition_53b54878b9.webp" alt="Race condition" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_race_condition_53b54878b9.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_race_condition_53b54878b9.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_race_condition_53b54878b9.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_race_condition_53b54878b9.webp 1000w," sizes="100vw"><figcaption>Race condition</figcaption></figure><h3>Threads vs Processes</h3><figure class="table"><table><thead><tr><th>Aspect</th><th>Process</th><th>Thread</th></tr></thead><tbody><tr><td>Memory</td><td>Separate memory space</td><td>Shared memory within process</td></tr><tr><td>Communication</td><td>IPC (sockets, pipes)</td><td>Shared variables, synchronized blocks</td></tr><tr><td>Creation cost</td><td>High</td><td>Low</td></tr><tr><td>Isolation</td><td>Full isolation</td><td>Shared state can cause bugs</td></tr></tbody></table></figure><h3>Race Condition</h3><p>When two threads access shared mutable state concurrently and the outcome depends on the timing of execution.</p><pre><code class="language-java">// BAD - race condition on counter
public class Counter {
    private int count = 0;

    public void increment() {
        count++; // Read-increment-write is NOT atomic
    }
}

// GOOD - use AtomicInteger for single variable
public class Counter {
    private final AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet(); // Atomic operation
    }
}
</code></pre><h3>Synchronization</h3><p>Use <code>synchronized</code> for compound operations or multi-variable state that must be consistent.</p><pre><code class="language-java">public class BankAccount {
    private double balance;
    private final Object lock = new Object();

    public void transfer(BankAccount target, double amount) {
        // Always lock in consistent order to prevent deadlock
        BankAccount first = this.hashCode() &lt; target.hashCode() ? this : target;
        BankAccount second = first == this ? target : this;

        synchronized (first.lock) {
            synchronized (second.lock) {
                if (this.balance &lt; amount) throw new InsufficientFundsException();
                this.balance -= amount;
                target.balance += amount;
            }
        }
    }
}
</code></pre><h3>Deadlock</h3><p>Occurs when two or more threads are each waiting for a lock held by the other, resulting in a permanent standstill.</p><p><strong>Four conditions required</strong> (remove any one to prevent deadlock):</p><ol><li>Mutual exclusion</li><li>Hold and wait</li><li>No preemption</li><li>Circular wait</li></ol><p><strong>Prevention</strong>: Always acquire locks in a consistent global order. The bank transfer example above uses hash code ordering to ensure <code>lock A</code> is always acquired before <code>lock B</code>.</p><h3>Thread-Safe Design</h3><pre><code class="language-java">// Prefer immutable objects - they are inherently thread-safe
public final class Money {
    private final double amount;
    private final String currency;

    public Money(double amount, String currency) {
        this.amount = amount;
        this.currency = currency;
    }

    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) throw new CurrencyMismatchException();
        return new Money(this.amount + other.amount, this.currency); // Returns new object
    }
}

// Use concurrent collections
private final Map&lt;String, Session&gt; sessions = new ConcurrentHashMap&lt;&gt;();
private final BlockingQueue&lt;Task&gt; taskQueue = new LinkedBlockingQueue&lt;&gt;();

// Use ExecutorService instead of raw threads
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -&gt; processOrder(order));
</code></pre><p><strong>Modern practices</strong>: Prefer <code>java.util.concurrent</code> over raw <code>synchronized</code>. Use <code>CompletableFuture</code> for async pipelines. Keep shared state minimal. Prefer message passing over shared mutable state.</p><hr><h2>10. API and Service Layer Design</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Layered_architecture_65c3931c56.webp" alt="Layered architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Layered_architecture_65c3931c56.webp 136w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Layered_architecture_65c3931c56.webp 437w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Layered_architecture_65c3931c56.webp 656w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Layered_architecture_65c3931c56.webp 874w," sizes="100vw"><figcaption>Layered architecture</figcaption></figure><h3>DTO vs Entity</h3><figure class="table"><table><thead><tr><th>Aspect</th><th>Entity</th><th>DTO</th></tr></thead><tbody><tr><td>Purpose</td><td>Database representation</td><td>API data transfer</td></tr><tr><td>Contains</td><td>DB annotations, relationships</td><td>Only fields needed for specific use case</td></tr><tr><td>Should expose directly?</td><td>Never</td><td>Yes</td></tr><tr><td>Serialization</td><td>No</td><td>Yes</td></tr></tbody></table></figure><pre><code class="language-java">// Entity - internal, mapped to DB table
@Entity
@Table(name = "users")
public class User {
    @Id
    private String userId;
    private String name;
    private String email;
    private String passwordHash; // Should NEVER appear in API response
    private LocalDateTime createdAt;
}

// DTO - external, safe to return from API
public class UserResponseDTO {
    private String userId;
    private String name;
    private String email;
    // No passwordHash - intentional

    public static UserResponseDTO from(User user) {
        UserResponseDTO dto = new UserResponseDTO();
        dto.userId = user.getUserId();
        dto.name = user.getName();
        dto.email = user.getEmail();
        return dto;
    }
}

// Request DTO - what the API accepts
public class CreateUserRequest {
    @NotBlank(message = "Name is required")
    private String name;

    @Email(message = "Invalid email format")
    @NotBlank
    private String email;

    @Size(min = 8, message = "Password must be at least 8 characters")
    private String password;
}
</code></pre><h3>Validation</h3><p>Validate at the boundary - controllers are the entry point. Do not let invalid data leak into service or domain layers.</p><pre><code class="language-java">@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;

    @PostMapping
    public ResponseEntity&lt;UserResponseDTO&gt; createUser(
            @Valid @RequestBody CreateUserRequest request) { // @Valid triggers Bean Validation
        UserResponseDTO user = userService.createUser(request);
        return ResponseEntity.status(HttpStatus.CREATED).body(user);
    }
}

// Global exception handler
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity&lt;ErrorResponse&gt; handleValidationErrors(MethodArgumentNotValidException ex) {
        List&lt;String&gt; errors = ex.getBindingResult().getFieldErrors().stream()
            .map(e -&gt; e.getField() + ": " + e.getDefaultMessage())
            .collect(Collectors.toList());
        return ResponseEntity.badRequest().body(new ErrorResponse("VALIDATION_ERROR", errors));
    }

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity&lt;ErrorResponse&gt; handleNotFound(ResourceNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
            .body(new ErrorResponse(ex.getErrorCode(), ex.getMessage()));
    }
}
</code></pre><h3>Dependency Injection</h3><p>Do not create dependencies inside classes. Inject them from outside.</p><pre><code class="language-java">// Constructor injection - preferred over field injection (@Autowired on field)
@Service
public class OrderService {
    private final OrderRepository orderRepository;
    private final InventoryService inventoryService;
    private final NotificationService notificationService;

    // Spring injects these at startup
    public OrderService(OrderRepository orderRepository,
                        InventoryService inventoryService,
                        NotificationService notificationService) {
        this.orderRepository = orderRepository;
        this.inventoryService = inventoryService;
        this.notificationService = notificationService;
    }
}
</code></pre><p><strong>Why constructor injection over field injection</strong>: Makes dependencies explicit, enables immutability with <code>final</code>, and makes the class testable without a Spring container.</p><hr><h2>11. Testing Basics</h2><h3>Unit Testing</h3><p>Tests a single unit of logic in isolation. Dependencies are mocked.</p><pre><code class="language-java">@ExtendWith(MockitoExtension.class)
class OrderServiceTest {

    @Mock
    private OrderRepository orderRepository;

    @Mock
    private InventoryService inventoryService;

    @InjectMocks
    private OrderService orderService;

    @Test
    void placeOrder_shouldSaveOrder_whenInventoryAvailable() {
        // Arrange
        Order order = new Order("ORD001", "USER001", List.of(new OrderItem("PROD1", 2)));
        when(inventoryService.isAvailable("PROD1", 2)).thenReturn(true);
        when(orderRepository.save(any(Order.class))).thenReturn(order);

        // Act
        Order result = orderService.placeOrder(order);

        // Assert
        assertNotNull(result);
        assertEquals("ORD001", result.getOrderId());
        verify(inventoryService).reserve("PROD1", 2);
        verify(orderRepository).save(order);
    }

    @Test
    void placeOrder_shouldThrow_whenInventoryInsufficient() {
        Order order = new Order("ORD001", "USER001", List.of(new OrderItem("PROD1", 100)));
        when(inventoryService.isAvailable("PROD1", 100)).thenReturn(false);

        assertThrows(InsufficientInventoryException.class, () -&gt; orderService.placeOrder(order));
        verify(orderRepository, never()).save(any()); // Order should not be saved
    }
}
</code></pre><h3>Writing Testable Code</h3><figure class="table"><table><thead><tr><th>Practice</th><th>Why It Helps Testing</th></tr></thead><tbody><tr><td>Constructor injection</td><td>Can pass mock implementations in tests</td></tr><tr><td>Program to interfaces</td><td>Easy to swap real with mock</td></tr><tr><td>Small, focused methods</td><td>Each method has one thing to verify</td></tr><tr><td>Avoid static calls</td><td>Static methods cannot be mocked easily</td></tr><tr><td>Avoid <code>new</code> inside business logic</td><td>Hard to control object creation in tests</td></tr></tbody></table></figure><h3>Test Structure: Arrange-Act-Assert</h3><p>Always structure tests in three clear sections:</p><pre><code class="language-java">@Test
void calculateDiscount_shouldApply10Percent_forSeasonalCoupon() {
    // Arrange - set up the state
    Cart cart = new Cart("CART001", "USER001");
    cart.addItem(new Product("PROD1", "Laptop", 50000.0), 1);
    DiscountStrategy seasonal = new SeasonalDiscount(10);

    // Act - execute the behavior being tested
    double finalPrice = seasonal.apply(cart.getTotal());

    // Assert - verify the outcome
    assertEquals(45000.0, finalPrice, 0.001);
}
</code></pre><p><strong>Common mistake</strong>: Testing implementation details instead of behavior. Your test should not care whether <code>calculateDiscount</code> used a loop or a stream internally. It should only verify the output.</p><hr><h2>Quick Reference Summary</h2><figure class="table"><table><thead><tr><th>Category</th><th>Key Takeaway</th></tr></thead><tbody><tr><td>SOLID</td><td>SRP keeps classes focused, OCP prevents modification, DIP enables testability</td></tr><tr><td>Patterns</td><td>Singleton for shared resources, Strategy for swappable algorithms, Observer for events</td></tr><tr><td>Relationships</td><td>Prefer composition over inheritance, keep dependencies explicit</td></tr><tr><td>Clean Code</td><td>Name things clearly, keep methods small, one level of abstraction per method</td></tr><tr><td>Concurrency</td><td>Prefer immutability, use AtomicInteger for counters, lock in consistent order</td></tr><tr><td>Testing</td><td>Test behavior not implementation, inject dependencies, Arrange-Act-Assert</td></tr><tr><td>Layering</td><td>Validation in controllers, logic in services, data access in repositories</td></tr><tr><td>LLD Problems</td><td>Identify entities, relationships, and patterns before writing any code</td></tr></tbody></table></figure><hr><h2>Conclusion</h2><p>Low Level Design is not about memorizing patterns or writing complex code. It is about building systems that are easy to understand, extend, and maintain over time.</p><p>If you can apply OOP principles, follow SOLID, choose the right design patterns, and think in terms of trade-offs, you are already ahead of most developers in both interviews and real-world engineering.</p><p>Use this cheatsheet as a reference, but focus on practicing real problems and writing clean designs consistently.</p><p>If you found this helpful, consider sharing it with your friends and peers who are preparing for backend and system design interviews.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>System Design</category>
            <category>Low Level Design</category>
            <category>Backend Development</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/LLD_Thumbnail_be62e4fb8d.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[High Level Design Made Simple – A Complete System Design Cheatsheet]]></title>
            <link>https://www.codingshuttle.com/blogs/high-level-design-made-simple-a-complete-system-design-cheatsheet</link>
            <guid>https://www.codingshuttle.com/blogs/high-level-design-made-simple-a-complete-system-design-cheatsheet</guid>
            <pubDate>Mon, 23 Mar 2026 08:25:13 GMT</pubDate>
            <description><![CDATA[A quick and well-structured guide to High Level Design, covering essential concepts, real-world patterns, and key trade-offs to help you design scalable, reliable systems with confidence.]]></description>
            <content:encoded><![CDATA[<p>High Level Design Made Simple – A Complete System Design Cheatsheet</p><p>Designing scalable systems can feel overwhelming with so many moving parts—caching, load balancing, databases, microservices. This cheatsheet breaks down High Level Design (HLD) into a simple, structured format you can actually understand.</p><p>Whether you're preparing for interviews or building real systems, it covers the key concepts in one place—focusing on how things work, the trade-offs involved, and how to make practical design decisions.</p><h2>1. System Design Fundamentals</h2><h3>What is High Level Design (HLD)?</h3><p>High Level Design is the bird's-eye view of a system. You're not writing code here — you're deciding what components exist, how they talk to each other, and how the system behaves under load or failure.</p><p>Think of it as the blueprint before construction. HLD answers: <i>What are we building and how does it fit together?</i></p><h3>HLD vs LLD</h3><figure class="table"><table><thead><tr><th>Aspect</th><th>High Level Design (HLD)</th><th>Low Level Design (LLD)</th></tr></thead><tbody><tr><td>Focus</td><td>System architecture</td><td>Module/class internals</td></tr><tr><td>Audience</td><td>Architects, senior engineers</td><td>Developers</td></tr><tr><td>Output</td><td>Diagrams, component map</td><td>Class diagrams, DB schemas</td></tr><tr><td>Detail level</td><td>30,000 feet</td><td>Ground level</td></tr><tr><td>Example</td><td>"We use Kafka for async events"</td><td>"KafkaConsumer class with retry logic"</td></tr></tbody></table></figure><h3>Key System Design Goals</h3><ul><li><strong>Scalability</strong> – Can the system handle 10x traffic without a rewrite?</li><li><strong>Reliability</strong> – Does it work correctly even when parts fail?</li><li><strong>Availability</strong> – Is it up when users need it? (Measured as uptime %)</li><li><strong>Consistency</strong> – Do all nodes agree on the same data at the same time?</li></ul><p>These four goals often conflict. More on that in the CAP Theorem section.</p><h3>Functional vs Non-Functional Requirements</h3><p>Always split requirements before designing anything.</p><p><strong>Functional requirements</strong> — what the system <i>does</i></p><ul><li>User can upload a photo</li><li>System sends an OTP on login</li><li>Search returns results in under 2 seconds</li></ul><p><strong>Non-functional requirements</strong> — how well it does it</p><ul><li>System must support 1 million concurrent users</li><li>99.99% uptime SLA</li><li>Data must not be lost during a crash</li></ul><p>In interviews, listing NFRs early signals maturity. It tells the interviewer you're thinking about the hard stuff.</p><h3>Latency vs Throughput</h3><ul><li><strong>Latency</strong> — time for one request to complete (e.g., 50ms per API call)</li><li><strong>Throughput</strong> — number of requests processed per second (e.g., 10,000 RPS)</li></ul><p>You often trade one for the other. Batching improves throughput but increases latency per individual item. Caching reduces latency but adds complexity.</p><blockquote><p>Rule of thumb: optimize latency for user-facing requests, throughput for background pipelines.</p></blockquote><hr><h2>2. Core Building Blocks</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/core_system_design_building_blocks_48e67d97bf.webp" alt="Core building blocks of a distributed system" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_core_system_design_building_blocks_48e67d97bf.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_core_system_design_building_blocks_48e67d97bf.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_core_system_design_building_blocks_48e67d97bf.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_core_system_design_building_blocks_48e67d97bf.webp 1000w," sizes="100vw"><figcaption>Core building blocks of a distributed system</figcaption></figure><h3>Client, Server, API</h3><ul><li><strong>Client</strong> — the consumer of data. Browser, mobile app, another service.</li><li><strong>Server</strong> — processes requests, applies business logic, returns responses.</li><li><strong>API</strong> — the contract between client and server. Defines what's available and how to call it.</li></ul><pre><code class="language-ruby">Client  --[HTTP Request]--&gt;  API Server  --[Query]--&gt;  Database
Client  &lt;--[JSON Response]--  API Server  &lt;--[Result]--  Database
</code></pre><h3>Load Balancer</h3><p>Sits between clients and servers. Distributes incoming traffic so no single server gets overwhelmed.</p><ul><li>Prevents single points of failure</li><li>Enables horizontal scaling</li><li>Handles health checks (removes dead servers from rotation)</li></ul><p>Example: Nginx, AWS ALB, HAProxy</p><h3>Database — SQL vs NoSQL</h3><figure class="table"><table><thead><tr><th>&nbsp;</th><th>SQL</th><th>NoSQL</th></tr></thead><tbody><tr><td>Structure</td><td>Fixed schema, tables</td><td>Flexible, document/key-value/graph</td></tr><tr><td>Consistency</td><td>Strong (ACID)</td><td>Eventual (BASE)</td></tr><tr><td>Scaling</td><td>Vertical (mostly)</td><td>Horizontal</td></tr><tr><td>Best for</td><td>Financial data, relations</td><td>Feeds, sessions, logs, catalogs</td></tr><tr><td>Examples</td><td>PostgreSQL, MySQL</td><td>MongoDB, Cassandra, DynamoDB</td></tr></tbody></table></figure><h3>Cache</h3><p>A fast, in-memory store that keeps frequently accessed data close to the application layer, reducing database load.</p><ul><li><strong>Redis</strong> — in-memory key-value store. Supports strings, hashes, sorted sets, pub/sub. Used for sessions, leaderboards, rate limiting.</li><li><strong>CDN (Content Delivery Network)</strong> — caches static assets (images, JS, CSS) on edge servers geographically close to users. Think Cloudflare, Akamai.</li></ul><h3>Message Queue</h3><p>Decouples producers and consumers. Producer puts a message on the queue; consumer picks it up independently.</p><ul><li><strong>Kafka</strong> — high-throughput, distributed log. Great for event streaming, audit logs.</li><li><strong>RabbitMQ</strong> — traditional message broker. Better for task queues, simpler routing.</li></ul><p>Use when: you don't need a synchronous response, you're processing in bulk, or you want to absorb traffic spikes.</p><hr><h2>3. Scalability Concepts</h2><h3>Vertical vs Horizontal Scaling</h3><figure class="table"><table><thead><tr><th>&nbsp;</th><th>Vertical Scaling</th><th>Horizontal Scaling</th></tr></thead><tbody><tr><td>What it means</td><td>Bigger machine (more CPU/RAM)</td><td>More machines</td></tr><tr><td>Limit</td><td>Hardware ceiling</td><td>Practically unlimited</td></tr><tr><td>Downtime</td><td>Usually required</td><td>Rolling deploys possible</td></tr><tr><td>Cost</td><td>Expensive at scale</td><td>Cheaper per unit</td></tr><tr><td>Best for</td><td>Databases (early stage)</td><td>Application servers, stateless services</td></tr></tbody></table></figure><h3>Stateless vs Stateful Services</h3><ul><li><strong>Stateless</strong> — each request carries all needed context. Server doesn't remember previous requests. Easy to scale horizontally. REST APIs are stateless by design.</li><li><strong>Stateful</strong> — server remembers user state (e.g., WebSocket connections, game sessions). Harder to scale, requires sticky sessions or shared state store.</li></ul><p>Design services to be stateless wherever possible. Move state to a shared store like Redis.</p><h3>Auto Scaling</h3><p>Automatically adds or removes instances based on metrics like CPU, memory, or request queue depth.</p><ul><li><strong>Scale out</strong> — add instances when load increases</li><li><strong>Scale in</strong> — remove instances when load drops</li></ul><p>Cloud providers (AWS Auto Scaling, GCP Managed Instance Groups) handle this natively. Set minimum, maximum, and target thresholds.</p><h3>CAP Theorem</h3><p>A distributed system can guarantee only two of three properties at the same time:</p><ul><li><strong>C</strong>onsistency — every read gets the most recent write</li><li><strong>A</strong>vailability — every request gets a (non-error) response</li><li><strong>P</strong>artition Tolerance — system keeps working even if nodes can't communicate</li></ul><p>In practice, network partitions happen. So you're choosing between <strong>CP</strong> or <strong>AP</strong> systems.</p><figure class="table"><table><thead><tr><th>System Type</th><th>Choice</th><th>Simple Example</th><th>Why</th></tr></thead><tbody><tr><td>Banking System</td><td>CP</td><td>Bank account balance</td><td>You cannot show wrong balance; consistency &gt; availability</td></tr><tr><td>Payment Gateway</td><td>CP</td><td>Online payment processing</td><td>No duplicate or incorrect transactions allowed</td></tr><tr><td>Social Media Feed</td><td>AP</td><td>Instagram/Twitter feed</td><td>Slight delay in updates is acceptable</td></tr><tr><td>Messaging App</td><td>AP</td><td>WhatsApp messages</td><td>Message may arrive late but system should stay available</td></tr><tr><td>E-commerce Catalog</td><td>AP</td><td>Product listings</td><td>Slightly outdated data is fine</td></tr><tr><td>Ticket Booking System</td><td>CP</td><td>Flight/train seat booking</td><td>Must avoid double booking</td></tr></tbody></table></figure><h3>Consistency Models</h3><ul><li><strong>Strong consistency</strong> — after a write, every subsequent read sees that write. Safer but slower.</li><li><strong>Eventual consistency</strong> — writes propagate eventually; reads may be stale for a short window. Faster but requires careful design.</li></ul><p>Real-world example: your Twitter follower count may be slightly off for a few seconds after someone unfollows. That's eventual consistency in action — and totally acceptable there.</p><hr><h2>4. Database Design</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Database_sharding_and_replication_e1b4776aea.webp" alt="Database sharding and replication" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Database_sharding_and_replication_e1b4776aea.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Database_sharding_and_replication_e1b4776aea.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Database_sharding_and_replication_e1b4776aea.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Database_sharding_and_replication_e1b4776aea.webp 1000w," sizes="100vw"><figcaption>Database sharding and replication</figcaption></figure><h3>SQL vs NoSQL Decision Making</h3><p>Ask these questions:</p><ul><li>Do you need complex joins or transactions? → SQL</li><li>Is your schema changing frequently? → NoSQL</li><li>Do you need horizontal scale from day one? → NoSQL</li><li>Is data relational (users, orders, products)? → SQL</li><li>Are you storing logs, events, or documents? → NoSQL</li></ul><p>There's no universal winner. Most mature systems use both.</p><h3>Indexing Basics</h3><p>An index is a data structure that speeds up reads at the cost of slower writes and extra storage.</p><ul><li>Without index: full table scan, O(n)</li><li>With index: B-tree or hash lookup, O(log n)</li></ul><pre><code class="language-php">-- Creates an index on email column for fast lookups
CREATE INDEX idx_users_email ON users(email);
</code></pre><p>Index columns used in WHERE, JOIN, and ORDER BY clauses. Avoid over-indexing — every index slows down INSERT/UPDATE.</p><h3>Sharding</h3><p>Splitting a large database into smaller pieces (shards) across multiple servers. Each shard holds a subset of data.</p><ul><li><strong>Range-based sharding</strong> — shard by ID range (1–1M on shard 1, 1M–2M on shard 2)</li><li><strong>Hash-based sharding</strong> — shard by hash of a key (user_id % N)</li><li><strong>Directory-based sharding</strong> — a lookup table maps each key to a shard</li></ul><p>Challenges: joins across shards are expensive, resharding is painful, hotspots can occur.</p><h3>Replication</h3><p>Copying data from one database node (primary) to one or more others (replicas).</p><ul><li><strong>Synchronous replication</strong> — primary waits for replica to confirm before responding. Stronger consistency, higher latency.</li><li><strong>Asynchronous replication</strong> — primary doesn't wait. Faster, but replica may lag.</li></ul><p>Used for fault tolerance, data redundancy, and geographic distribution.</p><h3>Read Replicas</h3><p>A common pattern: write to the primary, read from replicas.</p><pre><code class="language-ruby">Write Request  --&gt;  Primary DB
Read Request   --&gt;  Replica 1 / Replica 2 / Replica 3
</code></pre><p>This offloads read traffic from the primary. Works well when your read:write ratio is high (most web apps are read-heavy).</p><hr><h2>5. Caching Strategies</h2><h3>Why Caching?</h3><p>Databases are slow compared to memory. A query that takes 50ms from disk takes under 1ms from Redis. Caching reduces latency, saves DB resources, and improves throughput.</p><p>Use caching for: frequently read, rarely written data — user profiles, product listings, config values.</p><h3>Cache-Aside (Lazy Loading)</h3><p>The most common pattern. Application checks cache first; if miss, fetches from DB and populates cache.</p><pre><code class="language-ruby">1. App checks cache for key
2. If HIT → return cached value
3. If MISS → query DB
4. Store result in cache with TTL
5. Return result to caller
</code></pre><p>Good for read-heavy workloads. Cache only stores what's actually requested.</p><h3>Write-Through</h3><p>Every write goes to cache and DB simultaneously.</p><pre><code class="language-ruby">1. App writes data
2. Cache is updated
3. DB is updated
4. Acknowledge success
</code></pre><p>Keeps cache always fresh. Downside: writes are slightly slower.</p><h3>Write-Back (Write-Behind)</h3><p>App writes to cache only. Cache asynchronously flushes to DB later.</p><pre><code class="language-ruby">1. App writes to cache
2. Acknowledge success (fast)
3. Cache flushes to DB asynchronously
</code></pre><p>Very fast writes. Risk: if cache crashes before flush, data is lost. Use only when you can tolerate brief inconsistency.</p><h3>Cache Invalidation</h3><p>The hardest part. How do you know when to expire a cached value?</p><ul><li><strong>TTL (Time To Live)</strong> — set an expiry time. Simple and effective for most cases.</li><li><strong>Event-driven invalidation</strong> — when underlying data changes, explicitly delete or update the cache key.</li><li><strong>Write-through</strong> — keeps cache current by design.</li></ul><blockquote><p>"There are only two hard things in computer science: cache invalidation and naming things." — Phil Karlton</p></blockquote><hr><h2>6. Load Balancing</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Load_balancer_694c9ae8dd.webp" alt="Load balancer distributing traffic to multiple servers" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Load_balancer_694c9ae8dd.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Load_balancer_694c9ae8dd.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Load_balancer_694c9ae8dd.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Load_balancer_694c9ae8dd.webp 1000w," sizes="100vw"><figcaption>Load balancer distributing traffic to multiple servers</figcaption></figure><h3>L4 vs L7 Load Balancing</h3><figure class="table"><table><thead><tr><th>&nbsp;</th><th>Layer 4 (Transport)</th><th>Layer 7 (Application)</th></tr></thead><tbody><tr><td>Operates on</td><td>TCP/UDP packets</td><td>HTTP/HTTPS content</td></tr><tr><td>Routing basis</td><td>IP, port</td><td>URL, headers, cookies</td></tr><tr><td>Speed</td><td>Faster (less inspection)</td><td>Slightly slower</td></tr><tr><td>Features</td><td>Basic routing</td><td>URL routing, SSL termination, auth</td></tr><tr><td>Example</td><td>AWS NLB</td><td>AWS ALB, Nginx</td></tr></tbody></table></figure><p>Use L7 when you need smart routing (e.g., /api/* to one server pool, /static/* to another).</p><h3>Load Balancing Algorithms</h3><ul><li><strong>Round Robin</strong> — requests go to servers in rotation. Simple, works when servers are equal.</li><li><strong>Weighted Round Robin</strong> — servers with more capacity get proportionally more requests.</li><li><strong>Least Connections</strong> — next request goes to the server with fewest active connections. Good for long-lived connections.</li><li><strong>IP Hash / Sticky Sessions</strong> — same client always goes to same server. Useful for stateful apps.</li><li><strong>Random</strong> — randomly pick a server. Surprisingly effective at scale.</li></ul><h3>Health Checks</h3><p>Load balancers regularly ping servers to check if they're alive.</p><ul><li><strong>Active health checks</strong> — LB sends HTTP request to /health every N seconds</li><li><strong>Passive health checks</strong> — LB monitors real traffic; marks server unhealthy after N consecutive failures</li></ul><p>A dead server gets removed from rotation automatically. When it recovers, it gets added back.</p><hr><h2>7. API Design Basics</h2><h3>REST Principles</h3><p>REST (Representational State Transfer) is an architectural style, not a protocol. The six principles:</p><ul><li><strong>Stateless</strong> — no client session stored on server</li><li><strong>Client-Server</strong> — clear separation of concerns</li><li><strong>Uniform Interface</strong> — consistent, predictable URLs and methods</li><li><strong>Cacheable</strong> — responses can be cached</li><li><strong>Layered System</strong> — client doesn't know if it's hitting server directly or via proxy</li><li><strong>Code on Demand</strong> (optional) — server can send executable code</li></ul><pre><code class="language-ruby">GET    /users/123       → fetch user
POST   /users           → create user
PUT    /users/123       → replace user
PATCH  /users/123       → partial update
DELETE /users/123       → delete user
</code></pre><h3>Idempotency</h3><p>An operation is idempotent if calling it multiple times produces the same result as calling it once.</p><ul><li>GET, PUT, DELETE — idempotent</li><li>POST — not idempotent by default (creates a new resource each time)</li></ul><p>Why it matters: networks are unreliable. Clients retry requests. If your order-creation endpoint isn't idempotent, a retry creates a duplicate order. Use an idempotency key (unique request ID in header) to prevent this.</p><h3>Pagination</h3><p>Never return all records in one response. Use one of:</p><figure class="table"><table><thead><tr><th>Method</th><th>When to use</th></tr></thead><tbody><tr><td>Offset pagination</td><td>Simple, works for most cases. <code>?page=2&amp;limit=20</code></td></tr><tr><td>Cursor-based</td><td>Better for real-time feeds. <code>?cursor=&lt;last_id&gt;</code></td></tr><tr><td>Keyset pagination</td><td>Efficient for large datasets. Based on sorted column value</td></tr></tbody></table></figure><p>Offset pagination can be slow at high offsets (<code>LIMIT 20 OFFSET 100000</code> is expensive). Cursor-based is preferred at scale.</p><h3>Rate Limiting</h3><p>Protects your API from abuse and overload.</p><ul><li><strong>Token bucket</strong> — refills tokens at a fixed rate. Requests consume tokens.</li><li><strong>Fixed window</strong> — count requests per time window (e.g., 100 per minute)</li><li><strong>Sliding window</strong> — smoother than fixed window, avoids edge spikes</li></ul><p>Return <code>429 Too Many Requests</code> with a <code>Retry-After</code> header.</p><h3>API Versioning</h3><p>Plan for breaking changes from day one.</p><ul><li><strong>URL versioning</strong> — <code>/api/v1/users</code> (most common, easy to understand)</li><li><strong>Header versioning</strong> — <code>Accept: application/vnd.api.v2+json</code></li><li><strong>Query param</strong> — <code>/api/users?version=2</code></li></ul><p>Never remove a version without a deprecation period. Give consumers time to migrate.</p><hr><h2>8. Messaging and Asynchronous Systems</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Pub_Sub_and_message_queue_8b41bed8ce.webp" alt="Pub/Sub and message queue architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Pub_Sub_and_message_queue_8b41bed8ce.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Pub_Sub_and_message_queue_8b41bed8ce.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Pub_Sub_and_message_queue_8b41bed8ce.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Pub_Sub_and_message_queue_8b41bed8ce.webp 1000w," sizes="100vw"><figcaption>Pub/Sub and message queue architecture</figcaption></figure><h3>Pub/Sub Model</h3><p>Publishers emit events to a topic. Subscribers listen to topics they care about. Neither knows about the other.</p><pre><code class="language-ruby">OrderService (publisher)  →  "order.created" topic  →  EmailService (subscriber)
                                                    →  InventoryService (subscriber)
                                                    →  AnalyticsService (subscriber)
</code></pre><p>This is loosely coupled. Adding a new subscriber doesn't change the publisher at all.</p><h3>Message Queues</h3><p>Point-to-point. One producer puts a message on the queue; one consumer picks it up.</p><ul><li>Guarantees processing — message stays in queue until acknowledged</li><li>Enables backpressure — if consumers are slow, queue buffers the load</li><li>Good for task processing (image resizing, email sending, PDF generation)</li></ul><h3>Event-Driven Architecture</h3><p>System components communicate entirely through events rather than direct calls.</p><p>Benefits:</p><ul><li>Services are decoupled</li><li>Easy to add new functionality (just subscribe to existing events)</li><li>Natural audit log (event stream = history of what happened)</li></ul><p>Challenges:</p><ul><li>Harder to debug (no single call stack)</li><li>Eventual consistency by nature</li><li>Need to handle out-of-order events</li></ul><h3>Retry and Dead-Letter Queues</h3><p>When message processing fails, you don't want to lose it.</p><ul><li><strong>Retry</strong> — attempt reprocessing N times with exponential backoff</li><li><strong>Dead-Letter Queue (DLQ)</strong> — after max retries, move message here for investigation</li></ul><pre><code class="language-ruby">Queue  →  Consumer fails
       →  Retry 1 (after 1s)
       →  Retry 2 (after 2s)
       →  Retry 3 (after 4s)
       →  Move to DLQ → alert on-call engineer
</code></pre><p>Always set up a DLQ in production. Silently dropping failed messages is dangerous.</p><hr><h2>9. Microservices Architecture</h2><h3>Monolith vs Microservices</h3><figure class="table"><table><thead><tr><th>&nbsp;</th><th>Monolith</th><th>Microservices</th></tr></thead><tbody><tr><td>Deployment</td><td>Single deployable unit</td><td>Independent services</td></tr><tr><td>Development</td><td>Simpler early on</td><td>Complex but scalable</td></tr><tr><td>Team structure</td><td>Works for small teams</td><td>Enables team autonomy</td></tr><tr><td>Failure blast radius</td><td>One bug can take everything down</td><td>Isolated failures</td></tr><tr><td>Scaling</td><td>Scale everything or nothing</td><td>Scale specific services</td></tr><tr><td>When to use</td><td>Early-stage products</td><td>Mature, growing systems</td></tr></tbody></table></figure><p>Start with a monolith. Break it apart when you feel the pain — not before.</p><h3>Service Communication</h3><p><strong>Synchronous (Request/Response)</strong></p><ul><li>REST over HTTP, gRPC</li><li>Caller waits for a response</li><li>Simpler to reason about</li><li>Creates tight coupling; if downstream is slow, caller is slow</li></ul><p><strong>Asynchronous (Event/Message)</strong></p><ul><li>Kafka, RabbitMQ, SQS</li><li>Caller fires and forgets</li><li>Better resilience and decoupling</li><li>Harder to debug, eventual consistency</li></ul><p>Use sync for user-facing flows where you need an immediate answer. Use async for background processing.</p><h3>API Gateway</h3><p>A single entry point for all client requests. Routes to the appropriate downstream service.</p><p>Responsibilities:</p><ul><li>Request routing</li><li>Authentication and authorization</li><li>Rate limiting</li><li>SSL termination</li><li>Request/response transformation</li><li>Logging</li></ul><pre><code class="language-ruby">Mobile App  →  API Gateway  →  UserService
Web App     →               →  ProductService
                            →  OrderService
</code></pre><p>Examples: AWS API Gateway, Kong, Nginx</p><h3>Service Discovery</h3><p>Services need to know each other's addresses. In dynamic environments (containers, auto-scaling), IPs change constantly.</p><ul><li><strong>Client-side discovery</strong> — client queries a service registry (e.g., Consul, Eureka) and picks an instance</li><li><strong>Server-side discovery</strong> — load balancer handles it; client just calls the LB</li></ul><p>Kubernetes handles this natively via DNS-based service discovery.</p><hr><h2>10. Reliability and Fault Tolerance</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Circuit_breaker_5aec54d2a1.webp" alt="Circuit breaker pattern state diagram" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Circuit_breaker_5aec54d2a1.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Circuit_breaker_5aec54d2a1.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Circuit_breaker_5aec54d2a1.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Circuit_breaker_5aec54d2a1.webp 1000w," sizes="100vw"><figcaption>Circuit breaker pattern state diagram</figcaption></figure><h3>Redundancy</h3><p>Having more than one instance of a component so that if one fails, others take over.</p><ul><li>Active-active: multiple instances all handle traffic</li><li>Active-passive: one primary, one standby that activates on failure</li></ul><p>Apply redundancy to: servers, databases, load balancers, entire data centers.</p><h3>Failover</h3><p>The automatic (or manual) process of switching to a redundant component when the primary fails.</p><ul><li><strong>Automatic failover</strong> — system detects failure, switches within seconds (e.g., database primary/replica promotion)</li><li><strong>Manual failover</strong> — requires human intervention, acceptable for planned maintenance</li></ul><p>RTO (Recovery Time Objective) defines how quickly you need to recover. Failover speed must beat your RTO.</p><h3>Circuit Breaker</h3><p>Prevents cascading failures. When a downstream service is failing, stop sending it requests for a period.</p><p>Three states:</p><ul><li><strong>Closed</strong> — everything normal, requests pass through</li><li><strong>Open</strong> — too many failures, requests immediately rejected with an error (fast fail)</li><li><strong>Half-Open</strong> — after a timeout, allow a test request through; if it succeeds, close the circuit</li></ul><pre><code class="language-python">if circuit.state == OPEN:
    return fallback_response()  # don't even try

try:
    response = call_downstream_service()
    circuit.record_success()
except Exception:
    circuit.record_failure()
    if circuit.failure_rate &gt; threshold:
        circuit.open()
</code></pre><p>Hystrix (Java), Resilience4j, and Polly (.NET) are popular implementations.</p><h3>Retries and Timeouts</h3><ul><li><strong>Timeout</strong> — don't wait forever for a response. Set a reasonable limit (e.g., 500ms for user-facing, 5s for background).</li><li><strong>Retry</strong> — on transient failures, try again. Use exponential backoff to avoid hammering a struggling service.</li></ul><pre><code class="language-ruby">Attempt 1: fail → wait 1s
Attempt 2: fail → wait 2s
Attempt 3: fail → wait 4s
Attempt 4: give up, return error
</code></pre><p>Always combine retries with jitter (randomized delay) to avoid thundering herd.</p><hr><h2>11. Security Basics</h2><h3>Authentication vs Authorization</h3><p>These are not the same thing.</p><ul><li><strong>Authentication</strong> — who are you? (Login, verify identity)</li><li><strong>Authorization</strong> — what are you allowed to do? (Permissions, roles)</li></ul><p>Auth flow:</p><pre><code class="language-ruby">User logs in → system verifies identity (AuthN) → issues token
User requests /admin → system checks if user has admin role (AuthZ) → allow or deny
</code></pre><p>Common patterns: JWT tokens, OAuth 2.0, session cookies, API keys.</p><h3>HTTPS and Encryption</h3><ul><li><strong>HTTPS</strong> — HTTP over TLS. Encrypts data in transit. Non-negotiable for production. Get certs from Let's Encrypt (free).</li><li><strong>Encryption at rest</strong> — encrypt sensitive database fields (PII, passwords). Never store passwords in plaintext — use bcrypt or Argon2 hashing.</li><li><strong>Encryption in transit</strong> — TLS between all internal services, not just public-facing ones.</li></ul><h3>API Security</h3><ul><li>Validate all inputs — never trust client data. Prevent SQL injection, XSS.</li><li>Use HTTPS everywhere</li><li>Rotate API keys regularly</li><li>Scope tokens minimally — don't give a read-only client write permissions</li><li>Validate JWTs properly — check signature, expiry, and audience</li><li>Use CORS headers correctly — don't set <code>Access-Control-Allow-Origin: *</code> in production</li></ul><h3>Rate Limiting and Throttling</h3><p>Both protect your system from abuse, but have a subtle difference:</p><ul><li><strong>Rate limiting</strong> — hard cap on requests per time window (block after N requests)</li><li><strong>Throttling</strong> — slow down responses rather than blocking (return 429 or add delay)</li></ul><p>Apply rate limiting per IP, per user, and per API key. Different limits for different tiers (free vs paid users).</p><hr><h2>12. Monitoring and Observability</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Observability_pillars_ce57518083.webp" alt="Observability pillars — logs, metrics, traces" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Observability_pillars_ce57518083.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Observability_pillars_ce57518083.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Observability_pillars_ce57518083.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Observability_pillars_ce57518083.webp 1000w," sizes="100vw"><figcaption>Observability pillars — logs, metrics, traces</figcaption></figure><p>The goal of observability is to understand what your system is doing — especially when things go wrong. The three pillars are logs, metrics, and traces.</p><h3>Logging</h3><p>A log is a timestamped record of an event.</p><p>Best practices:</p><ul><li>Use structured logging (JSON format) — easier to parse and query</li><li>Include correlation IDs to trace a request across services</li><li>Log at appropriate levels: DEBUG, INFO, WARN, ERROR</li><li>Don't log sensitive data (passwords, PII, tokens)</li><li>Centralize logs (ELK Stack, Datadog, CloudWatch)</li></ul><pre><code class="language-javascript">{
  "timestamp": "2025-03-01T10:22:00Z",
  "level": "ERROR",
  "service": "order-service",
  "correlation_id": "abc-123",
  "message": "Payment gateway timeout",
  "user_id": "user-456"
}
</code></pre><h3>Metrics</h3><p>Numerical measurements over time. Used for dashboards and alerting.</p><p>Four golden signals (from Google SRE):</p><ul><li><strong>Latency</strong> — how long requests take</li><li><strong>Traffic</strong> — how many requests per second</li><li><strong>Errors</strong> — rate of failed requests</li><li><strong>Saturation</strong> — how "full" your system is (CPU, memory, queue depth)</li></ul><p>Tools: Prometheus + Grafana, Datadog, AWS CloudWatch.</p><h3>Distributed Tracing</h3><p>A trace follows a single request across multiple services, showing where time is spent.</p><pre><code class="language-ruby">Request enters API Gateway (0ms)
  → UserService (5ms)
  → ProductService (20ms)
	  → DB query (18ms)  ← bottleneck
  → Response (27ms total)
</code></pre><p>Tools: Jaeger, Zipkin, AWS X-Ray, Datadog APM. Every service adds a span to the trace with timing and metadata.</p><h3>Alerts</h3><p>Alerts notify on-call engineers when something needs attention.</p><p>Good alerting principles:</p><ul><li>Alert on symptoms, not causes (alert on high error rate, not "CPU is high")</li><li>Set thresholds carefully — too sensitive creates alert fatigue</li><li>Every alert should be actionable — if you can't do anything about it, don't alert on it</li><li>Use PagerDuty, OpsGenie, or similar for on-call routing</li><li>Write runbooks: for each alert, document what it means and what to do</li></ul><hr><h2>Quick Reference: Key Concepts at a Glance</h2><figure class="table"><table><thead><tr><th>Concept</th><th>One-Line Summary</th></tr></thead><tbody><tr><td>HLD</td><td>Blueprint of components and how they interact</td></tr><tr><td>CAP Theorem</td><td>Pick two: Consistency, Availability, Partition Tolerance</td></tr><tr><td>Sharding</td><td>Split data across multiple DB nodes by a key</td></tr><tr><td>Cache-Aside</td><td>Check cache, miss → fetch DB, populate cache</td></tr><tr><td>Circuit Breaker</td><td>Stop calling a failing service; fail fast</td></tr><tr><td>Idempotency</td><td>Same request, same result, no matter how many times called</td></tr><tr><td>Rate Limiting</td><td>Cap requests per user/IP per time window</td></tr><tr><td>DLQ</td><td>Parking lot for messages that failed after max retries</td></tr><tr><td>Read Replica</td><td>DB copy that handles reads, reducing primary load</td></tr><tr><td>API Gateway</td><td>Single entry point that routes, authenticates, and rate-limits</td></tr></tbody></table></figure><hr><h2>Conclusion</h2><p>High Level Design is not about memorizing patterns — it’s about understanding <strong>trade-offs, scalability, and real-world constraints</strong>. Every system you design will require balancing consistency, availability, performance, and cost based on the problem you're solving.</p><p>This cheatsheet gives you a solid foundation, but true mastery comes from <strong>thinking in systems, practicing real-world problems, and continuously learning from existing architectures</strong>.</p><p>Keep building, keep breaking things, and keep improving</p><p>If you found this helpful, feel free to share it with your friends and help them level up in System Design too</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>System Design</category>
            <category>High Level Design</category>
            <category>HLD</category>
            <category>Backend</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/HLD_Thumbnail_cd3c3f18cc.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Hibernate in One Shot - Ultimate Java ORM Cheatsheet & Guide]]></title>
            <link>https://www.codingshuttle.com/blogs/hibernate-in-one-shot-ultimate-java-orm-cheatsheet-and-guide-1</link>
            <guid>https://www.codingshuttle.com/blogs/hibernate-in-one-shot-ultimate-java-orm-cheatsheet-and-guide-1</guid>
            <pubDate>Fri, 20 Mar 2026 18:00:16 GMT</pubDate>
            <description><![CDATA[Hibernate in One Shot is a concise cheatsheet that covers everything from ORM basics and entity mapping to CRUD operations, caching, transactions, and performance optimization—perfect for quick learning and revision]]></description>
            <content:encoded><![CDATA[<p><strong>Hibernate in One Shot: Ultimate Java ORM Cheatsheet &amp; Guide</strong></p><hr><p>Hibernate is an open-source Object Relational Mapping (ORM) framework for Java that simplifies database interactions by allowing developers to work with Java objects instead of writing raw SQL queries. It handles mapping between object-oriented code and relational databases, manages connections, caching, and transactions, and is widely used in modern backend applications.</p><h2>1. Hibernate Fundamentals</h2><h3>What is Hibernate</h3><p>Hibernate is an open-source ORM (Object Relational Mapping) framework for Java. It simplifies database interaction by letting you work with Java objects instead of raw SQL. It implements the JPA specification and sits between your application and the database.</p><ul><li>Developed by Gavin King, now maintained by Red Hat</li><li>Implements JPA (Jakarta Persistence API)</li><li>Handles SQL generation, connection pooling, caching, and transactions</li></ul><h3>ORM - Object Relational Mapping</h3><p>ORM bridges the gap between object-oriented Java code and relational databases. Instead of writing INSERT or SELECT statements, you work with plain Java objects (POJOs).</p><figure class="table"><table><thead><tr><th>Object-Oriented World</th><th>Relational World</th></tr></thead><tbody><tr><td>Class</td><td>Table</td></tr><tr><td>Object</td><td>Row</td></tr><tr><td>Field / Property</td><td>Column</td></tr><tr><td>Reference</td><td>Foreign Key</td></tr><tr><td>Collection</td><td>Join Table</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Hibernate_ORM_Mapping_821b8c43a4.webp" alt="Hibernate ORM Mapping" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Hibernate_ORM_Mapping_821b8c43a4.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Hibernate_ORM_Mapping_821b8c43a4.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Hibernate_ORM_Mapping_821b8c43a4.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Hibernate_ORM_Mapping_821b8c43a4.webp 1000w," sizes="100vw"><figcaption>Hibernate ORM Mapping</figcaption></figure><h3>Why Hibernate over JDBC</h3><p>JDBC works, but it is verbose, error-prone, and forces you to manage everything manually. Hibernate abstracts all of that away.</p><figure class="table"><table><thead><tr><th>Feature</th><th>JDBC</th><th>Hibernate</th></tr></thead><tbody><tr><td>SQL writing</td><td>Manual</td><td>Auto-generated</td></tr><tr><td>Object mapping</td><td>Manual</td><td>Automatic</td></tr><tr><td>Caching</td><td>None built-in</td><td>First and second level</td></tr><tr><td>Transaction management</td><td>Manual</td><td>Declarative</td></tr><tr><td>Boilerplate code</td><td>High</td><td>Minimal</td></tr><tr><td>Portability</td><td>DB-specific SQL</td><td>Dialect-based</td></tr></tbody></table></figure><h3>Hibernate Architecture Overview</h3><pre><code class="language-ruby">Application
    |
    v
SessionFactory  &lt;--- Configuration (hibernate.cfg.xml or annotations)
    |
    v
Session  &lt;--- Wraps JDBC Connection
    |
    v
Transaction
    |
    v
Database (via JDBC Driver)
</code></pre><p>Key components:</p><ul><li><strong>Configuration</strong> - loads Hibernate settings</li><li><strong>SessionFactory</strong> - heavyweight, one per database, thread-safe</li><li><strong>Session</strong> - lightweight, one per request/transaction, not thread-safe</li><li><strong>Transaction</strong> - wraps DB operations</li><li><strong>Query / Criteria</strong> - for executing HQL or JPQL queries</li></ul><hr><h2>2. Core Concepts</h2><h3>Entity Class and POJO</h3><p>A POJO (Plain Old Java Object) becomes a Hibernate entity when you annotate it with <code>@Entity</code>. It must have a no-arg constructor and a primary key field.</p><pre><code class="language-java">@Entity
@Table(name = "employees")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String department;

    // no-arg constructor required
    public Employee() {}

    // getters and setters
}
</code></pre><p>Rules for an entity class:</p><ul><li>Must not be <code>final</code></li><li>Must have a public or protected no-arg constructor</li><li>Must have at least one <code>@Id</code> field</li><li>Fields should be private with getters/setters</li></ul><h3>Session and SessionFactory</h3><p><strong>SessionFactory</strong> is created once when the application starts. It is expensive to build but cheap to use. Think of it as a factory that produces Session objects.</p><p><strong>Session</strong> is the primary interface to interact with the database. It represents a single unit of work and wraps a JDBC connection.</p><pre><code class="language-java">// Build SessionFactory (do this once, on startup)
SessionFactory sessionFactory = new Configuration()
    .configure("hibernate.cfg.xml")
    .buildSessionFactory();

// Open a session for each unit of work
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

// ... do work ...

tx.commit();
session.close();
</code></pre><h3>Persistence Context</h3><p>The persistence context is an in-memory cache of entities that Hibernate manages during a session. Every entity loaded or saved goes into this context.</p><ul><li>Tracks changes automatically (dirty checking)</li><li>Ensures identity - same DB row returns the same Java object</li><li>Synchronizes state to DB at flush time</li></ul><p>Three entity states:</p><ul><li><strong>Transient</strong> - object created but not associated with any session</li><li><strong>Persistent</strong> - associated with an active session, tracked by Hibernate</li><li><strong>Detached</strong> - was persistent, session is now closed</li></ul><pre><code class="language-java">Employee emp = new Employee(); // Transient

session.save(emp);             // Persistent - Hibernate tracks this

session.close();               // emp becomes Detached
</code></pre><h3>First-Level Cache</h3><p>First-level cache is scoped to the Session. It is enabled by default and cannot be disabled. When you load the same entity twice in the same session, the second call hits cache, not the database.</p><pre><code class="language-java">Employee e1 = session.get(Employee.class, 1L); // hits DB
Employee e2 = session.get(Employee.class, 1L); // hits L1 cache, no DB call

System.out.println(e1 == e2); // true - same object reference
</code></pre><hr><h2>3. Configuration</h2><h3>hibernate.cfg.xml</h3><p>This is the traditional XML-based configuration file placed in <code>src/main/resources</code>.</p><pre><code class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "&lt;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&gt;"&gt;

&lt;hibernate-configuration&gt;
    &lt;session-factory&gt;

        &lt;!-- Database connection --&gt;
        &lt;property name="hibernate.connection.driver_class"&gt;com.mysql.cj.jdbc.Driver&lt;/property&gt;
        &lt;property name="hibernate.connection.url"&gt;jdbc:mysql://localhost:3306/mydb&lt;/property&gt;
        &lt;property name="hibernate.connection.username"&gt;root&lt;/property&gt;
        &lt;property name="hibernate.connection.password"&gt;password&lt;/property&gt;

        &lt;!-- Dialect --&gt;
        &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.MySQL8Dialect&lt;/property&gt;

        &lt;!-- Show SQL in console --&gt;
        &lt;property name="hibernate.show_sql"&gt;true&lt;/property&gt;
        &lt;property name="hibernate.format_sql"&gt;true&lt;/property&gt;

        &lt;!-- Schema generation --&gt;
        &lt;property name="hibernate.hbm2ddl.auto"&gt;update&lt;/property&gt;

        &lt;!-- Entity class mapping --&gt;
        &lt;mapping class="com.example.Employee"/&gt;

    &lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;
</code></pre><h3>Annotation-Based Configuration</h3><p>In modern Spring Boot projects, <code>application.properties</code> handles Hibernate config:</p><pre><code class="language-php">spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
</code></pre><h3>Key Properties Explained</h3><figure class="table"><table><thead><tr><th>Property</th><th>Values</th><th>Description</th></tr></thead><tbody><tr><td><code>hibernate.dialect</code></td><td>MySQL8Dialect, PostgreSQLDialect, etc.</td><td>Tells Hibernate which SQL dialect to use</td></tr><tr><td><code>show_sql</code></td><td>true / false</td><td>Prints generated SQL to console</td></tr><tr><td><code>format_sql</code></td><td>true / false</td><td>Pretty prints SQL output</td></tr><tr><td><code>hbm2ddl.auto</code></td><td>create, create-drop, update, validate, none</td><td>Controls schema generation</td></tr></tbody></table></figure><p><strong>hbm2ddl.auto values:</strong></p><ul><li><code>create</code> - drops and recreates schema on startup</li><li><code>create-drop</code> - drops schema on shutdown (good for tests)</li><li><code>update</code> - updates schema without dropping data</li><li><code>validate</code> - validates schema, throws error if mismatch</li><li><code>none</code> - does nothing (recommended for production)</li></ul><hr><h2>4. Mapping Annotations</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Hibernate_Mapping_Annotations_Overview_fc3a4aabce.webp" alt="Hibernate Mapping Annotations Overview" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Hibernate_Mapping_Annotations_Overview_fc3a4aabce.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Hibernate_Mapping_Annotations_Overview_fc3a4aabce.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Hibernate_Mapping_Annotations_Overview_fc3a4aabce.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Hibernate_Mapping_Annotations_Overview_fc3a4aabce.webp 1000w," sizes="100vw"><figcaption>Hibernate Mapping Annotations Overview</figcaption></figure><h3>Basic Annotations</h3><pre><code class="language-java">@Entity                         // marks this class as a Hibernate entity
@Table(name = "employees")      // maps to a specific table name
public class Employee {

    @Id                                                    // primary key
    @GeneratedValue(strategy = GenerationType.IDENTITY)    // auto-increment
    @Column(name = "emp_id")                               // maps to specific column
    private Long id;

    @Column(name = "full_name", nullable = false, length = 100)
    private String name;

    @Column(unique = true)
    private String email;

    @Transient   // this field will NOT be persisted
    private String tempToken;
}
</code></pre><p><strong>@GeneratedValue strategies:</strong></p><figure class="table"><table><thead><tr><th>Strategy</th><th>Description</th></tr></thead><tbody><tr><td><code>IDENTITY</code></td><td>DB auto-increment (MySQL, PostgreSQL)</td></tr><tr><td><code>SEQUENCE</code></td><td>Uses DB sequence object (PostgreSQL, Oracle)</td></tr><tr><td><code>TABLE</code></td><td>Uses a separate table to track keys</td></tr><tr><td><code>AUTO</code></td><td>Hibernate picks the best strategy</td></tr></tbody></table></figure><h3>Relationship Annotations</h3><h3>@OneToOne</h3><p>One entity maps to exactly one instance of another.</p><pre><code class="language-java">@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "address_id", referencedColumnName = "id")
    private Address address;
}
</code></pre><h3>@OneToMany and @ManyToOne</h3><p>One department has many employees. Each employee belongs to one department.</p><pre><code class="language-java">// Department side (One)
@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List&lt;Employee&gt; employees = new ArrayList&lt;&gt;();
}

// Employee side (Many)
@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "department_id")
    private Department department;
}
</code></pre><ul><li><code>mappedBy</code> tells Hibernate that the other side owns the relationship</li><li>The owning side (the one with <code>@JoinColumn</code>) controls the foreign key</li></ul><h3>@ManyToMany</h3><p>Students can enroll in many courses. Each course has many students.</p><pre><code class="language-java">@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private List&lt;Course&gt; courses = new ArrayList&lt;&gt;();
}

@Entity
public class Course {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToMany(mappedBy = "courses")
    private List&lt;Student&gt; students = new ArrayList&lt;&gt;();
}
</code></pre><h3>CascadeType Quick Reference</h3><figure class="table"><table><thead><tr><th>CascadeType</th><th>Effect</th></tr></thead><tbody><tr><td><code>PERSIST</code></td><td>Saves child when parent is saved</td></tr><tr><td><code>MERGE</code></td><td>Updates child when parent is merged</td></tr><tr><td><code>REMOVE</code></td><td>Deletes child when parent is deleted</td></tr><tr><td><code>REFRESH</code></td><td>Refreshes child when parent is refreshed</td></tr><tr><td><code>DETACH</code></td><td>Detaches child when parent is detached</td></tr><tr><td><code>ALL</code></td><td>All of the above</td></tr></tbody></table></figure><hr><h2>5. CRUD Operations</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Hibernate_CRUD_0dd553f808.webp" alt="Hibernate CRUD operations" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Hibernate_CRUD_0dd553f808.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Hibernate_CRUD_0dd553f808.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Hibernate_CRUD_0dd553f808.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Hibernate_CRUD_0dd553f808.webp 1000w," sizes="100vw"><figcaption>Hibernate CRUD operations</figcaption></figure><h3>Save and Persist</h3><pre><code class="language-java">Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

Employee emp = new Employee();
emp.setName("Alice");
emp.setDepartment("Engineering");

session.save(emp);      // Hibernate-specific, returns generated ID
// OR
session.persist(emp);   // JPA standard, returns void

tx.commit();
session.close();
</code></pre><ul><li><code>save()</code> returns the generated identifier immediately</li><li><code>persist()</code> is JPA-standard and does not guarantee immediate INSERT</li></ul><h3>Get and Load</h3><pre><code class="language-java">// get() - hits DB immediately, returns null if not found
Employee emp = session.get(Employee.class, 1L);

// load() - returns a proxy, hits DB only when you access fields
// throws ObjectNotFoundException if not found (not null)
Employee emp = session.load(Employee.class, 1L);
</code></pre><p>Use <code>get()</code> when you are unsure whether the record exists. Use <code>load()</code> only when you are certain the record is there.</p><h3>Update</h3><pre><code class="language-java">// For detached objects
session.update(emp);

// merge() - safer, works for both detached and transient
session.merge(emp);

// Automatic dirty checking - no explicit update needed for persistent objects
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

Employee emp = session.get(Employee.class, 1L); // persistent
emp.setName("Bob");  // just change the field

tx.commit(); // Hibernate detects the change and fires UPDATE automatically
session.close();
</code></pre><h3>Delete</h3><pre><code class="language-java">Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

Employee emp = session.get(Employee.class, 1L);
session.delete(emp); // or session.remove(emp) in JPA

tx.commit();
session.close();
</code></pre><hr><h2>6. HQL and JPQL</h2><h3>Basics of HQL</h3><p>HQL (Hibernate Query Language) is object-oriented SQL. You write queries against entity class names and field names, not table names and column names. Hibernate translates them to native SQL.</p><pre><code class="language-java">// Basic SELECT
List&lt;Employee&gt; employees = session
    .createQuery("FROM Employee", Employee.class)
    .getResultList();

// WHERE clause
List&lt;Employee&gt; result = session
    .createQuery("FROM Employee WHERE department = :dept", Employee.class)
    .setParameter("dept", "Engineering")
    .getResultList();

// SELECT specific fields
List&lt;String&gt; names = session
    .createQuery("SELECT e.name FROM Employee e", String.class)
    .getResultList();

// JOIN
List&lt;Employee&gt; result = session
    .createQuery("FROM Employee e JOIN FETCH e.department WHERE e.department.name = :deptName", Employee.class)
    .setParameter("deptName", "Engineering")
    .getResultList();
</code></pre><h3>Named Queries</h3><p>Named queries are defined once (usually on the entity) and reused by name. They are parsed and validated at startup, which catches errors early.</p><pre><code class="language-java">@Entity
@NamedQuery(
    name = "Employee.findByDepartment",
    query = "FROM Employee WHERE department.name = :deptName"
)
public class Employee {
    // ...
}

// Usage
List&lt;Employee&gt; employees = session
    .createNamedQuery("Employee.findByDepartment", Employee.class)
    .setParameter("deptName", "Engineering")
    .getResultList();
</code></pre><h3>Pagination</h3><pre><code class="language-java">List&lt;Employee&gt; page = session
    .createQuery("FROM Employee ORDER BY name", Employee.class)
    .setFirstResult(0)   // offset - starts from 0
    .setMaxResults(10)   // page size
    .getResultList();
</code></pre><hr><h2>7. Fetching Strategies</h2><h3>Lazy vs Eager Loading</h3><p>Fetching strategy decides when related entities are loaded from the database.</p><figure class="table"><table><thead><tr><th>Strategy</th><th>When data is loaded</th><th>Default for</th></tr></thead><tbody><tr><td><code>LAZY</code></td><td>Only when you access the field</td><td><code>@OneToMany</code>, <code>@ManyToMany</code></td></tr><tr><td><code>EAGER</code></td><td>Immediately with the parent</td><td><code>@ManyToOne</code>, <code>@OneToOne</code></td></tr></tbody></table></figure><pre><code class="language-java">// Lazy - employees not loaded until you call dept.getEmployees()
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
private List&lt;Employee&gt; employees;

// Eager - employees always loaded with department
@OneToMany(mappedBy = "department", fetch = FetchType.EAGER)
private List&lt;Employee&gt; employees;
</code></pre><p>General rule: prefer LAZY loading. Use EAGER only when you always need the related data.</p><h3>N+1 Problem</h3><p>The N+1 problem happens when loading N parent entities triggers N additional queries to load their children, resulting in N+1 total queries to the database.</p><pre><code class="language-java">// BAD - triggers N+1
List&lt;Department&gt; departments = session
    .createQuery("FROM Department", Department.class)
    .getResultList();

for (Department dept : departments) {
    dept.getEmployees(); // fires a separate query for EACH department
}
// Result: 1 query for departments + N queries for employees = N+1 queries
</code></pre><p><strong>Fix: use JOIN FETCH</strong></p><pre><code class="language-java">// GOOD - loads everything in one query
List&lt;Department&gt; departments = session
    .createQuery("FROM Department d JOIN FETCH d.employees", Department.class)
    .getResultList();
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/N_1_Query_Problem_vs_JOIN_FETCH_17a91b55ce.webp" alt="N+1 Query Problem vs JOIN FETCH" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_N_1_Query_Problem_vs_JOIN_FETCH_17a91b55ce.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_N_1_Query_Problem_vs_JOIN_FETCH_17a91b55ce.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_N_1_Query_Problem_vs_JOIN_FETCH_17a91b55ce.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_N_1_Query_Problem_vs_JOIN_FETCH_17a91b55ce.webp 1000w," sizes="100vw"><figcaption>N+1 Query Problem vs JOIN FETCH</figcaption></figure><hr><h2>8. Caching</h2><h3>First-Level Cache</h3><ul><li>Enabled by default, always active</li><li>Scoped to the Session - lives and dies with the session</li><li>Cannot be turned off</li><li>Automatically used when you call <code>session.get()</code> multiple times for the same entity</li></ul><h3>Second-Level Cache</h3><ul><li>Shared across sessions within the same SessionFactory</li><li>Disabled by default - you must configure it</li><li>Useful for read-heavy, rarely-changing data (like reference tables)</li><li>Common providers: Ehcache, Infinispan, Hazelcast</li></ul><pre><code class="language-xml">&lt;!-- hibernate.cfg.xml --&gt;
&lt;property name="hibernate.cache.use_second_level_cache"&gt;true&lt;/property&gt;
&lt;property name="hibernate.cache.region.factory_class"&gt;
    org.hibernate.cache.ehcache.EhCacheRegionFactory
&lt;/property&gt;
</code></pre><pre><code class="language-java">@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)  // enable L2 cache for this entity
public class Country {
    @Id
    private Long id;
    private String name;
}
</code></pre><p><strong>Cache Concurrency Strategies:</strong></p><figure class="table"><table><thead><tr><th>Strategy</th><th>Use when</th></tr></thead><tbody><tr><td><code>READ_ONLY</code></td><td>Data never changes (best performance)</td></tr><tr><td><code>READ_WRITE</code></td><td>Data changes occasionally</td></tr><tr><td><code>NONSTRICT_READ_WRITE</code></td><td>Occasional updates, stale data acceptable</td></tr><tr><td><code>TRANSACTIONAL</code></td><td>Full transactional integrity needed</td></tr></tbody></table></figure><p><strong>Query Cache</strong> - caches query result sets (not just entities). Must be explicitly enabled per query.</p><pre><code class="language-java">session.createQuery("FROM Country", Country.class)
    .setCacheable(true)
    .getResultList();
</code></pre><hr><h2>9. Transactions</h2><h3>Transaction Lifecycle</h3><p>Every database write operation must happen inside a transaction. Hibernate does not auto-commit by default.</p><pre><code class="language-java">Session session = sessionFactory.openSession();
Transaction tx = null;

try {
    tx = session.beginTransaction();

    // your database operations here
    session.save(employee);

    tx.commit();         // writes changes to DB

} catch (Exception e) {
    if (tx != null) tx.rollback();  // undo everything on error
    e.printStackTrace();
} finally {
    session.close();     // always close the session
}
</code></pre><p>With Spring's <code>@Transactional</code>:</p><pre><code class="language-java">@Service
public class EmployeeService {

    @Transactional
    public void saveEmployee(Employee emp) {
        employeeRepository.save(emp);
        // Spring manages begin, commit, and rollback automatically
    }
}
</code></pre><h3>ACID Properties</h3><figure class="table"><table><thead><tr><th>Property</th><th>Meaning</th></tr></thead><tbody><tr><td><strong>Atomicity</strong></td><td>All operations succeed or none do</td></tr><tr><td><strong>Consistency</strong></td><td>Data is always in a valid state before and after</td></tr><tr><td><strong>Isolation</strong></td><td>Concurrent transactions do not interfere with each other</td></tr><tr><td><strong>Durability</strong></td><td>Committed data survives system failure</td></tr></tbody></table></figure><p><strong>Isolation Levels:</strong></p><figure class="table"><table><thead><tr><th>Level</th><th>Dirty Read</th><th>Non-Repeatable Read</th><th>Phantom Read</th></tr></thead><tbody><tr><td>READ_UNCOMMITTED</td><td>possible</td><td>possible</td><td>possible</td></tr><tr><td>READ_COMMITTED</td><td>prevented</td><td>possible</td><td>possible</td></tr><tr><td>REPEATABLE_READ</td><td>prevented</td><td>prevented</td><td>possible</td></tr><tr><td>SERIALIZABLE</td><td>prevented</td><td>prevented</td><td>prevented</td></tr></tbody></table></figure><hr><h2>10. Schema Design and Best Practices</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Hibernate_Entity_Relationship_3078733128.webp" alt="Hibernate Entity Relationship " srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Hibernate_Entity_Relationship_3078733128.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Hibernate_Entity_Relationship_3078733128.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Hibernate_Entity_Relationship_3078733128.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Hibernate_Entity_Relationship_3078733128.webp 1000w," sizes="100vw"><figcaption>Hibernate Entity Relationship&nbsp;</figcaption></figure><h3>Normalization vs Denormalization</h3><ul><li><strong>Normalization</strong> - reduce redundancy, split data into related tables. Better for write-heavy systems. Easier to maintain.</li><li><strong>Denormalization</strong> - combine related data into fewer tables. Better for read-heavy systems. Improves query performance at the cost of redundancy.</li></ul><p>Hibernate works better with normalized schemas but can handle denormalized designs too.</p><h3>Efficient Mapping Strategies</h3><ul><li>Use <code>@ManyToOne</code> instead of <code>@OneToMany</code> as the owning side where possible</li><li>Avoid bidirectional relationships unless you genuinely need to navigate both ways</li><li>Use <code>mappedBy</code> correctly - only one side should own the relationship</li><li>Prefer <code>List</code> over <code>Set</code> for ordered collections, but <code>Set</code> for unordered to avoid duplicates</li></ul><pre><code class="language-java">// Good practice - explicit column definitions
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;

// Good practice - use @Index for frequently queried columns
@Table(name = "employees", indexes = {
    @Index(name = "idx_email", columnList = "email"),
    @Index(name = "idx_department", columnList = "department_id")
})
</code></pre><h3>Performance Considerations</h3><ul><li>Always close sessions - use try-with-resources or finally blocks</li><li>Use pagination for large result sets - never load all rows</li><li>Avoid <code>FetchType.EAGER</code> on collections</li><li>Use <code>JOIN FETCH</code> only when you need related data in the same query</li><li>Enable second-level cache for reference/static data</li><li>Use batch inserts for bulk operations</li></ul><pre><code class="language-java">// Batch inserts - configure batch size in properties
// hibernate.jdbc.batch_size=50

for (int i = 0; i &lt; 1000; i++) {
    session.save(new Employee("emp_" + i));
    if (i % 50 == 0) {
        session.flush();  // write batch to DB
        session.clear();  // clear L1 cache to avoid memory issues
    }
}
</code></pre><hr><h2>11. Common Pitfalls</h2><h3>LazyInitializationException</h3><p>This is one of the most common Hibernate errors. It happens when you try to access a lazily loaded collection or association after the session is already closed.</p><pre><code class="language-java">// BAD - session closes after this method returns
public Department findDepartment(Long id) {
    Session session = sessionFactory.openSession();
    Department dept = session.get(Department.class, id);
    session.close(); // session closed here
    return dept;
}

// Later...
dept.getEmployees().size(); // LazyInitializationException - session is gone
</code></pre><p><strong>Fixes:</strong></p><ul><li>Use <code>JOIN FETCH</code> to load required associations eagerly within the session</li><li>Use <code>@Transactional</code> to keep session open until the method returns</li><li>Use DTOs to avoid returning entities outside the session boundary</li><li>Use <code>Hibernate.initialize(dept.getEmployees())</code> explicitly before closing session</li></ul><h3>N+1 Query Issue</h3><p>Already covered in Section 7. Quick summary:</p><ul><li>Root cause: lazy loading inside a loop</li><li>Detection: enable <code>show_sql</code> and count your queries</li><li>Fix: use <code>JOIN FETCH</code> or <code>@EntityGraph</code></li></ul><pre><code class="language-java">// @EntityGraph approach (JPA standard)
@EntityGraph(attributePaths = {"employees"})
List&lt;Department&gt; findAll(); // Spring Data JPA method
</code></pre><h3>Improper Session Handling</h3><ul><li><strong>Never share a Session across threads</strong> - it is not thread-safe</li><li><strong>Never leave sessions open</strong> - causes connection pool exhaustion</li><li><strong>Always use transactions for writes</strong> - reads may work without them but writes are unreliable without explicit transaction boundaries</li></ul><pre><code class="language-java">// BAD - storing session as a field
public class EmployeeService {
    private Session session = sessionFactory.openSession(); // wrong
}

// GOOD - open and close per operation
public Employee findById(Long id) {
    try (Session session = sessionFactory.openSession()) {
        return session.get(Employee.class, id);
    }
}
</code></pre><hr><h2>12. Hibernate vs JPA</h2><h3>The Difference</h3><p>JPA (Jakarta Persistence API) is a specification - it defines a standard set of interfaces and annotations for ORM in Java. Hibernate is the most popular implementation of that specification.</p><p>Think of JPA as the interface and Hibernate as the class that implements it.</p><figure class="table"><table><thead><tr><th>Aspect</th><th>JPA</th><th>Hibernate</th></tr></thead><tbody><tr><td>Type</td><td>Specification (API)</td><td>Implementation</td></tr><tr><td>Package</td><td><code>jakarta.persistence.*</code></td><td><code>org.hibernate.*</code></td></tr><tr><td>Portability</td><td>High - works with any JPA provider</td><td>Tied to Hibernate</td></tr><tr><td>Features</td><td>Standard features only</td><td>JPA + Hibernate-specific extras</td></tr><tr><td>Query language</td><td>JPQL</td><td>HQL (superset of JPQL)</td></tr><tr><td>EntityManager</td><td><code>EntityManager</code></td><td><code>Session</code> (also implements <code>EntityManager</code>)</td></tr></tbody></table></figure><h3>Code Comparison</h3><pre><code class="language-java">// JPA style (portable, works with EclipseLink too)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-pu");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(employee);
em.getTransaction().commit();
em.close();

// Hibernate native style
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.save(employee);
session.getTransaction().commit();
session.close();
</code></pre><h3>When to Use What</h3><ul><li><strong>Use JPA</strong> when you want portability and do not need Hibernate-specific features. Standard choice for enterprise apps.</li><li><strong>Use Hibernate-specific APIs</strong> when you need features like Hibernate filters, second-level cache fine-tuning, batch processing helpers, or advanced fetch profiles.</li><li><strong>In practice</strong>: use JPA annotations and <code>EntityManager</code> for all standard operations, and reach for Hibernate-specific APIs only when JPA falls short.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/JPA_vs_Hibernate_Architecture_611e9e1ae8.webp" alt="JPA &amp; Hibernate Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_JPA_vs_Hibernate_Architecture_611e9e1ae8.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_JPA_vs_Hibernate_Architecture_611e9e1ae8.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_JPA_vs_Hibernate_Architecture_611e9e1ae8.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_JPA_vs_Hibernate_Architecture_611e9e1ae8.webp 1000w," sizes="100vw"><figcaption>JPA &amp; Hibernate Architecture</figcaption></figure><hr><h2>Quick Reference Card</h2><h3>Session Methods</h3><figure class="table"><table><thead><tr><th>Method</th><th>Description</th></tr></thead><tbody><tr><td><code>session.save(obj)</code></td><td>Persists new entity, returns ID</td></tr><tr><td><code>session.persist(obj)</code></td><td>JPA-standard persist</td></tr><tr><td><code>session.get(Class, id)</code></td><td>Loads by ID, returns null if not found</td></tr><tr><td><code>session.load(Class, id)</code></td><td>Returns proxy, throws if not found</td></tr><tr><td><code>session.update(obj)</code></td><td>Updates detached entity</td></tr><tr><td><code>session.merge(obj)</code></td><td>Merges detached or transient entity</td></tr><tr><td><code>session.delete(obj)</code></td><td>Deletes entity</td></tr><tr><td><code>session.flush()</code></td><td>Syncs session state to DB</td></tr><tr><td><code>session.clear()</code></td><td>Clears first-level cache</td></tr><tr><td><code>session.evict(obj)</code></td><td>Removes specific entity from cache</td></tr></tbody></table></figure><h3>Common Annotations Summary</h3><figure class="table"><table><thead><tr><th>Annotation</th><th>Purpose</th></tr></thead><tbody><tr><td><code>@Entity</code></td><td>Marks class as persistent entity</td></tr><tr><td><code>@Table(name="...")</code></td><td>Maps to specific table</td></tr><tr><td><code>@Id</code></td><td>Primary key field</td></tr><tr><td><code>@GeneratedValue</code></td><td>Auto-generate primary key</td></tr><tr><td><code>@Column</code></td><td>Maps field to column with constraints</td></tr><tr><td><code>@Transient</code></td><td>Field not persisted</td></tr><tr><td><code>@OneToOne</code></td><td>One-to-one relationship</td></tr><tr><td><code>@OneToMany</code></td><td>One-to-many relationship</td></tr><tr><td><code>@ManyToOne</code></td><td>Many-to-one relationship</td></tr><tr><td><code>@ManyToMany</code></td><td>Many-to-many relationship</td></tr><tr><td><code>@JoinColumn</code></td><td>Specifies foreign key column</td></tr><tr><td><code>@JoinTable</code></td><td>Specifies join table for many-to-many</td></tr><tr><td><code>@Cache</code></td><td>Enables second-level caching</td></tr><tr><td><code>@NamedQuery</code></td><td>Defines reusable named HQL query</td></tr></tbody></table></figure><h3>hbm2ddl.auto Quick Reference</h3><figure class="table"><table><thead><tr><th>Value</th><th>Creates</th><th>Drops</th><th>Use for</th></tr></thead><tbody><tr><td><code>create</code></td><td>Yes</td><td>On startup</td><td>Development only</td></tr><tr><td><code>create-drop</code></td><td>Yes</td><td>On shutdown</td><td>Unit testing</td></tr><tr><td><code>update</code></td><td>Alters if needed</td><td>Never</td><td>Dev / staging</td></tr><tr><td><code>validate</code></td><td>Never</td><td>Never</td><td>Production (safe)</td></tr><tr><td><code>none</code></td><td>Never</td><td>Never</td><td>Production (explicit SQL)</td></tr></tbody></table></figure><hr><h2>Conclusion</h2><p>Hibernate simplifies database interaction by abstracting complex SQL into clean, object-oriented code, allowing developers to focus on business logic instead of low-level data handling. With features like automatic mapping, caching, and transaction management, and its seamless use with frameworks like Spring Boot, Hibernate remains an essential tool for building scalable and maintainable Java backend applications. If you found this helpful, consider sharing it with your friends and peers.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Hibernate</category>
            <category>JPA</category>
            <category>ORM</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Hibernate_Thumbnail_2ed7e72600.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[MongoDB in One Shot - The Ultimate Cheatsheet]]></title>
            <link>https://www.codingshuttle.com/blogs/mongo-db-in-one-shot-the-ultimate-cheatsheet</link>
            <guid>https://www.codingshuttle.com/blogs/mongo-db-in-one-shot-the-ultimate-cheatsheet</guid>
            <pubDate>Tue, 17 Mar 2026 05:35:46 GMT</pubDate>
            <description><![CDATA[A concise MongoDB cheatsheet designed to help you quickly understand and revise core concepts. It covers everything from fundamentals and CRUD operations to advanced querying, indexing, aggregation, and schema design, with practical examples for real-world applications. Ideal for learning, quick revision, and interview preparation.]]></description>
            <content:encoded><![CDATA[<p>MongoDB in One Shot - The Ultimate Cheatsheet</p><p>MongoDB is a powerful NoSQL database built for modern applications that demand flexibility, speed, and scalability. Instead of rigid tables and schemas, it stores data in JSON-like documents, making it easy to model real-world data and iterate quickly as requirements evolve.</p><p>Designed for high performance and distributed systems, MongoDB enables developers to handle large-scale data with ease through features like indexing, aggregation, replication, and sharding. It is widely used in building scalable backends, real-time applications, and microservices architectures.</p><hr><h2>1. MongoDB Fundamentals</h2><h3>What is MongoDB?</h3><p>MongoDB is a NoSQL, document-oriented database that stores data as flexible, JSON-like documents instead of rows and columns. It is schema-less by default, meaning each document in a collection can have different fields.</p><p><strong>Why MongoDB over SQL?</strong></p><ul><li>Stores hierarchical/nested data naturally</li><li>Horizontally scalable</li><li>Great for unstructured or semi-structured data</li><li>Fast reads on large datasets with proper indexing</li></ul><h3>JSON vs BSON</h3><figure class="table"><table><thead><tr><th>Feature</th><th>JSON</th><th>BSON</th></tr></thead><tbody><tr><td>Format</td><td>Text-based</td><td>Binary-encoded</td></tr><tr><td>Data Types</td><td>Limited</td><td>Extended (Date, ObjectId, etc.)</td></tr><tr><td>Speed</td><td>Slower parse</td><td>Faster for MongoDB internals</td></tr><tr><td>Used For</td><td>Human-readable</td><td>MongoDB storage + wire protocol</td></tr></tbody></table></figure><p>MongoDB stores data as BSON internally but exposes it as JSON to the developer.</p><h3>Database → Collection → Document Hierarchy</h3><pre><code class="language-ruby">MongoDB Instance
  └── Database (e.g., "shopDB")
        └── Collection (e.g., "products")
              └── Document (e.g., { name: "Laptop", price: 999 })
</code></pre><ul><li><strong>Database</strong> - container for collections</li><li><strong>Collection</strong> - equivalent to a table in SQL</li><li><strong>Document</strong> - equivalent to a row; a BSON object</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Mongo_DB_Document_Structure_1f79960c02.webp" alt="MongoDB Document Structure" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Mongo_DB_Document_Structure_1f79960c02.webp 104w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Mongo_DB_Document_Structure_1f79960c02.webp 333w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Mongo_DB_Document_Structure_1f79960c02.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Mongo_DB_Document_Structure_1f79960c02.webp 667w," sizes="100vw"><figcaption>MongoDB Document Structure</figcaption></figure><h3>The <code>_id</code> Field</h3><p>Every document must have a unique <code>_id</code> field. If you don't provide one, MongoDB auto-generates an <strong>ObjectId</strong>.</p><pre><code class="language-javascript">{
  _id: ObjectId("64a3f8c2d1e2a3b4c5d6e7f8"),
  name: "Alice",
  age: 28
}
</code></pre><ul><li>ObjectId is 12 bytes: 4-byte timestamp + 5-byte random + 3-byte incrementing counter</li><li>You can use any unique value as <code>_id</code> (string, integer, etc.)</li></ul><h3>Installation Checklist</h3><ul><li><strong>MongoDB Community Server</strong> - the core database engine</li><li><strong>MongoDB Compass</strong> - GUI for exploring and querying data visually</li><li><strong>mongosh</strong> - the official MongoDB shell for terminal-based interaction</li></ul><pre><code class="language-ruby"># Start mongosh
mongosh

# Select or create a database
use shopDB

# Check current db
db

# List all databases
show dbs

# List collections
show collections
</code></pre><hr><h2>2. Core CRUD Operations</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Mongo_DB_CRUD_Operations_c395a3ab16.webp" alt="MongoDB CRUD Operations" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Mongo_DB_CRUD_Operations_c395a3ab16.webp 104w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Mongo_DB_CRUD_Operations_c395a3ab16.webp 333w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Mongo_DB_CRUD_Operations_c395a3ab16.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Mongo_DB_CRUD_Operations_c395a3ab16.webp 667w," sizes="100vw"><figcaption>MongoDB CRUD Operations</figcaption></figure><h3>Insert</h3><pre><code class="language-javascript">// Insert a single document
db.users.insertOne({
  name: "Ravi",
  email: "ravi@example.com",
  age: 25,
  city: "Mumbai"
})

// Insert multiple documents
db.users.insertMany([
  { name: "Priya", age: 22, city: "Delhi" },
  { name: "Arjun", age: 30, city: "Bangalore" }
])
</code></pre><ul><li><code>insertOne()</code> returns <code>insertedId</code></li><li><code>insertMany()</code> returns an array of <code>insertedIds</code></li></ul><h3>Read</h3><pre><code class="language-javascript">// Find all documents
db.users.find()

// Find with a filter
db.users.find({ city: "Mumbai" })

// Find one document
db.users.findOne({ name: "Ravi" })

// Pretty print in older shell
db.users.find().pretty()
</code></pre><h3>Update</h3><pre><code class="language-javascript">// Update a single document
db.users.updateOne(
  { name: "Ravi" },
  { $set: { age: 26 } }
)

// Update multiple documents
db.users.updateMany(
  { city: "Mumbai" },
  { $set: { country: "India" } }
)

// Increment a value
db.users.updateOne(
  { name: "Ravi" },
  { $inc: { age: 1 } }
)

// Push to an array
db.users.updateOne(
  { name: "Ravi" },
  { $push: { hobbies: "photography" } }
)

// Pull from an array
db.users.updateOne(
  { name: "Ravi" },
  { $pull: { hobbies: "photography" } }
)
</code></pre><h3>Delete</h3><pre><code class="language-javascript">// Delete one
db.users.deleteOne({ name: "Ravi" })

// Delete many
db.users.deleteMany({ city: "Delhi" })

// Delete all documents in a collection
db.users.deleteMany({})
</code></pre><h3>Common Update Operators</h3><figure class="table"><table><thead><tr><th>Operator</th><th>Purpose</th></tr></thead><tbody><tr><td><code>$set</code></td><td>Set or update a field value</td></tr><tr><td><code>$unset</code></td><td>Remove a field</td></tr><tr><td><code>$inc</code></td><td>Increment a numeric field</td></tr><tr><td><code>$push</code></td><td>Add an element to an array</td></tr><tr><td><code>$pull</code></td><td>Remove matching elements from array</td></tr><tr><td><code>$addToSet</code></td><td>Add to array only if not already present</td></tr><tr><td><code>$rename</code></td><td>Rename a field</td></tr></tbody></table></figure><hr><h2>3. Advanced Querying Techniques</h2><p>MongoDB provides a flexible query language to filter, combine conditions, and shape results. Queries operate on documents and can leverage indexes for efficient execution.</p><hr><h3>Comparison Operators</h3><p>Comparison operators filter documents based on field values, similar to SQL <code>WHERE</code> conditions.</p><pre><code class="language-javascript">// Greater than
db.products.find({ price: { $gt: 500 } })

// Less than or equal
db.products.find({ price: { $lte: 1000 } })

// Equal (explicit)
db.products.find({ status: { $eq: "active" } })

// Not equal
db.products.find({ status: { $ne: "inactive" } })

// In a list
db.products.find({ category: { $in: ["Electronics", "Books"] } })

// Not in a list
db.products.find({ category: { $nin: ["Clothing"] } })
</code></pre><p>These operators are evaluated per document. MongoDB can efficiently use indexes with operators like <code>$eq</code>, <code>$gt</code>, and <code>$lt</code>. The <code>$in</code> operator is useful for matching multiple values but can become slower with very large arrays.</p><figure class="table"><table><thead><tr><th>Operator</th><th>Meaning</th></tr></thead><tbody><tr><td><code>$gt</code></td><td>Greater than</td></tr><tr><td><code>$gte</code></td><td>Greater than or equal</td></tr><tr><td><code>$lt</code></td><td>Less than</td></tr><tr><td><code>$lte</code></td><td>Less than or equal</td></tr><tr><td><code>$eq</code></td><td>Equal</td></tr><tr><td><code>$ne</code></td><td>Not equal</td></tr><tr><td><code>$in</code></td><td>Matches any value in array</td></tr><tr><td><code>$nin</code></td><td>Matches none of the values</td></tr></tbody></table></figure><hr><h3>Logical Operators</h3><p>Logical operators combine multiple conditions to form complex queries.</p><pre><code class="language-javascript">// $and - both conditions must match
db.users.find({
  $and: [{ age: { $gte: 18 } }, { city: "Mumbai" }]
})

// $or - either condition matches
db.users.find({
  $or: [{ city: "Delhi" }, { city: "Mumbai" }]
})

// $not - negates a condition
db.users.find({
  age: { $not: { $gt: 30 } }
})

// $nor - none of the conditions match
db.users.find({
  $nor: [{ city: "Delhi" }, { age: { $lt: 18 } }]
})
</code></pre><p>MongoDB implicitly applies <code>$and</code> when multiple conditions are specified in a single query object. <code>$or</code> queries may require proper indexing for good performance. <code>$not</code> and <code>$nor</code> are generally less efficient and should be used carefully on large datasets.</p><hr><h3>Projection</h3><p>Projection controls which fields are returned in the result set.</p><pre><code class="language-javascript">// Return only name and city, exclude _id
db.users.find({}, { name: 1, city: 1, _id: 0 })

// Exclude a field
db.users.find({}, { password: 0 })
</code></pre><p>Projection reduces the amount of data transferred from the database and can improve performance. It also enables covered queries when all required fields are present in an index. Inclusion and exclusion cannot be mixed in the same projection, except for <code>_id</code>.</p><hr><h3>Sorting</h3><p>Sorting arranges documents based on specified fields.</p><pre><code class="language-javascript">// Ascending (1), Descending (-1)
db.products.find().sort({ price: 1 })     // cheapest first
db.products.find().sort({ price: -1 })    // most expensive first
db.products.find().sort({ name: 1, price: -1 }) // multi-sort
</code></pre><p>Sorting without an index may result in in-memory operations, which are slower. For better performance, indexes should be created on fields used in sorting. Compound indexes should match the sort order.</p><hr><h3>Limiting and Skipping</h3><p>Used to control the number of documents returned and implement pagination.</p><pre><code class="language-javascript">// Return only 5 documents
db.products.find().limit(5)

// Skip first 10, then get 5 (pagination)
db.products.find().skip(10).limit(5)
</code></pre><p>The <code>limit()</code> function reduces the number of documents returned, improving efficiency. The <code>skip()</code> function can become inefficient on large datasets because MongoDB still scans skipped documents internally.</p><p>For scalable pagination, cursor-based approaches (e.g., using <code>_id</code> or indexed fields) are preferred over large <code>skip()</code> values.</p><hr><h2>4. Indexing and Query Optimization</h2><p>Without an index, MongoDB performs a <strong>collection scan</strong> - checking every document. With an index, it jumps directly to matching documents. Think of it like a book index versus reading every page.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Mongo_DB_Indexing_b81451c5f3.webp" alt="MongoDB Indexing Concept" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Mongo_DB_Indexing_b81451c5f3.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Mongo_DB_Indexing_b81451c5f3.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Mongo_DB_Indexing_b81451c5f3.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Mongo_DB_Indexing_b81451c5f3.webp 1000w," sizes="100vw"><figcaption>MongoDB Indexing</figcaption></figure><h3>Creating Indexes</h3><pre><code class="language-javascript">// Single field index
db.users.createIndex({ email: 1 })

// Compound index (multiple fields)
db.orders.createIndex({ userId: 1, createdAt: -1 })

// Unique index
db.users.createIndex({ email: 1 }, { unique: true })

// Text index (full-text search)
db.articles.createIndex({ content: "text" })

// List all indexes on a collection
db.users.getIndexes()

// Drop an index
db.users.dropIndex("email_1")
</code></pre><h3>Text Search with Text Index</h3><pre><code class="language-javascript">db.articles.find({ $text: { $search: "mongodb tutorial" } })
</code></pre><h3>Explain - Understand Query Performance</h3><pre><code class="language-javascript">db.users.find({ email: "ravi@example.com" }).explain("executionStats")
</code></pre><p>Key fields to check in explain output:</p><ul><li><code>COLLSCAN</code> - no index used, bad for large collections</li><li><code>IXSCAN</code> - index used, efficient</li><li><code>nReturned</code> - documents returned</li><li><code>totalDocsExamined</code> - documents scanned</li></ul><h3>Indexing Best Practices</h3><ul><li>Index fields used in <code>find()</code>, <code>sort()</code>, and <code>$lookup</code></li><li>Compound indexes follow the <strong>ESR rule</strong>: Equality first, Sort next, Range last</li><li>Too many indexes slow down writes</li><li>Use <code>explain()</code> to verify your index is being used</li><li>TTL indexes can auto-expire documents (useful for sessions, logs)</li></ul><pre><code class="language-javascript">// TTL index - auto delete after 3600 seconds
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })
</code></pre><hr><h2>5. Schema Design and Data Modeling</h2><p>MongoDB is schema-flexible, but that doesn't mean you should design carelessly. The right schema design depends on your read/write patterns.</p><h3>Embedding vs Referencing</h3><p><strong>Embedding</strong> - store related data inside the same document</p><pre><code class="language-javascript">// Embedded address inside user
{
  _id: ObjectId("..."),
  name: "Priya",
  address: {
    street: "123 MG Road",
    city: "Pune",
    pincode: "411001"
  }
}
</code></pre><p><strong>Referencing</strong> - store the related document's <code>_id</code> as a foreign key</p><pre><code class="language-javascript">// User document
{ _id: ObjectId("u1"), name: "Priya" }

// Order document references user
{ _id: ObjectId("o1"), userId: ObjectId("u1"), total: 4500 }
</code></pre><h3>When to Embed vs Reference</h3><figure class="table"><table><thead><tr><th>Scenario</th><th>Recommendation</th></tr></thead><tbody><tr><td>Data always read together</td><td>Embed</td></tr><tr><td>Child data is small and bounded</td><td>Embed</td></tr><tr><td>Data grows unboundedly (e.g., comments)</td><td>Reference</td></tr><tr><td>Data is shared across many documents</td><td>Reference</td></tr><tr><td>Need to query child data independently</td><td>Reference</td></tr></tbody></table></figure><h3>Denormalization</h3><p>MongoDB often duplicates data intentionally (denormalization) to avoid expensive joins at read time. For example, storing a user's name alongside each order even though it also exists in the users collection - this way you never need a join to display order history.</p><h3>Schema Design Principles</h3><ul><li>Design your schema around <strong>how your application queries data</strong>, not how the data naturally relates</li><li>Avoid unbounded arrays inside documents (keep arrays small and finite)</li><li>A document size limit of <strong>16 MB</strong> applies in MongoDB</li><li>Use <code>ObjectId</code> references when relationships are complex or data is large</li></ul><hr><h2>6. Aggregation Framework Deep Dive</h2><p>The aggregation pipeline processes documents through a series of stages, where each stage transforms the data. Think of it as a conveyor belt - documents go in, get filtered, grouped, reshaped, and come out the other end.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Mongo_DB_Aggregation_Pipeline_5b0b8b57ab.webp" alt="MongoDB Aggregation Pipeline" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Mongo_DB_Aggregation_Pipeline_5b0b8b57ab.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Mongo_DB_Aggregation_Pipeline_5b0b8b57ab.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Mongo_DB_Aggregation_Pipeline_5b0b8b57ab.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Mongo_DB_Aggregation_Pipeline_5b0b8b57ab.webp 1000w," sizes="100vw"><figcaption>MongoDB Aggregation Pipeline</figcaption></figure><h3>Basic Pipeline Syntax</h3><pre><code class="language-javascript">db.collection.aggregate([
  { stage1 },
  { stage2 },
  { stage3 }
])
</code></pre><h3>$match - Filter Documents</h3><p>Works like <code>find()</code>. Always put <code>$match</code> first to reduce documents early.</p><pre><code class="language-javascript">db.orders.aggregate([
  { $match: { status: "delivered" } }
])
</code></pre><h3>$group - Group and Aggregate</h3><pre><code class="language-javascript">// Total revenue per city
db.orders.aggregate([
  {
    $group: {
      _id: "$city",
      totalRevenue: { $sum: "$amount" },
      orderCount: { $sum: 1 },
      avgOrder: { $avg: "$amount" }
    }
  }
])
</code></pre><p>Common <code>$group</code> accumulators:</p><figure class="table"><table><thead><tr><th>Accumulator</th><th>Purpose</th></tr></thead><tbody><tr><td><code>$sum</code></td><td>Total sum</td></tr><tr><td><code>$avg</code></td><td>Average value</td></tr><tr><td><code>$min</code></td><td>Minimum value</td></tr><tr><td><code>$max</code></td><td>Maximum value</td></tr><tr><td><code>$count</code></td><td>Count of documents</td></tr><tr><td><code>$push</code></td><td>Collect values into array</td></tr><tr><td><code>$first</code></td><td>First value in group</td></tr><tr><td><code>$last</code></td><td>Last value in group</td></tr></tbody></table></figure><h3>$project - Reshape Documents</h3><pre><code class="language-javascript">db.users.aggregate([
  {
    $project: {
      fullName: { $concat: ["$firstName", " ", "$lastName"] },
      age: 1,
      _id: 0
    }
  }
])
</code></pre><h3>$sort and $limit</h3><pre><code class="language-javascript">db.orders.aggregate([
  { $match: { status: "delivered" } },
  { $group: { _id: "$customerId", total: { $sum: "$amount" } } },
  { $sort: { total: -1 } },
  { $limit: 10 }
])
</code></pre><p>This pipeline finds the top 10 customers by total spending.</p><h3>$unwind - Flatten Arrays</h3><pre><code class="language-javascript">// Each element of the array becomes its own document
db.orders.aggregate([
  { $unwind: "$items" }
])
</code></pre><h3>$lookup - Join Collections</h3><pre><code class="language-javascript">db.orders.aggregate([
  {
    $lookup: {
      from: "users",          // collection to join
      localField: "userId",   // field in orders
      foreignField: "_id",    // field in users
      as: "userDetails"       // output array field
    }
  }
])
</code></pre><hr><h2>7. Relationships and Joins in MongoDB</h2><p>MongoDB is not a relational database, but you can model and query relationships effectively.</p><h3>One-to-One</h3><pre><code class="language-javascript">// Embedded (preferred for one-to-one)
{
  _id: ObjectId("u1"),
  name: "Arjun",
  profile: {
    bio: "Developer",
    website: "arjun.dev"
  }
}
</code></pre><h3>One-to-Many</h3><pre><code class="language-javascript">// Author has many books - reference approach
{ _id: ObjectId("a1"), name: "Chetan Bhagat" }

{ _id: ObjectId("b1"), title: "2 States", authorId: ObjectId("a1") }
{ _id: ObjectId("b2"), title: "3 Mistakes", authorId: ObjectId("a1") }

// Query using $lookup
db.books.aggregate([
  {
    $lookup: {
      from: "authors",
      localField: "authorId",
      foreignField: "_id",
      as: "author"
    }
  }
])
</code></pre><h3>Many-to-Many</h3><p>Use an intermediary collection (like a junction table in SQL) or embed an array of references.</p><pre><code class="language-javascript">// Students and courses - array of references
{ _id: ObjectId("s1"), name: "Neha", enrolledCourses: [ObjectId("c1"), ObjectId("c2")] }
{ _id: ObjectId("c1"), title: "MongoDB Basics" }

// Or a separate enrollment collection
{ studentId: ObjectId("s1"), courseId: ObjectId("c1"), enrolledAt: ISODate("2024-01-10") }
</code></pre><hr><h2>8. Transactions and Data Consistency</h2><p>By default, individual document operations in MongoDB are atomic. If you need to update multiple documents atomically, you need multi-document transactions (available from MongoDB 4.0+ with replica sets).</p><h3>ACID in MongoDB</h3><figure class="table"><table><thead><tr><th>Property</th><th>MongoDB Support</th></tr></thead><tbody><tr><td>Atomicity</td><td>Single document always; multi-doc via transactions</td></tr><tr><td>Consistency</td><td>Enforced via schema validation + transactions</td></tr><tr><td>Isolation</td><td>Snapshot isolation within transactions</td></tr><tr><td>Durability</td><td>Write concerns + journaling</td></tr></tbody></table></figure><h3>Multi-Document Transactions</h3><pre><code class="language-javascript">const session = client.startSession()

try {
  session.startTransaction()

  await db.collection("accounts").updateOne(
    { _id: "acc1" },
    { $inc: { balance: -500 } },
    { session }
  )

  await db.collection("accounts").updateOne(
    { _id: "acc2" },
    { $inc: { balance: 500 } },
    { session }
  )

  await session.commitTransaction()
} catch (err) {
  await session.abortTransaction()
} finally {
  session.endSession()
}
</code></pre><h3>Key Points About Transactions</h3><ul><li>Transactions require a <strong>replica set</strong> or <strong>sharded cluster</strong> - they don't work on standalone instances</li><li>Keep transactions short and fast to avoid lock contention</li><li>Transactions have a default timeout of 60 seconds</li><li>Use transactions only when you truly need multi-document atomicity; single-document operations are cheaper</li></ul><hr><h2>9. MongoDB Atlas (Cloud Database)</h2><p>MongoDB Atlas is the fully managed cloud version of MongoDB. It handles provisioning, backups, scaling, and security for you.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Mongo_DB_Atlas_Dashboard_e2da06f3c8.webp" alt="MongoDB Atlas Dashboard Overview" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Mongo_DB_Atlas_Dashboard_e2da06f3c8.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Mongo_DB_Atlas_Dashboard_e2da06f3c8.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Mongo_DB_Atlas_Dashboard_e2da06f3c8.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Mongo_DB_Atlas_Dashboard_e2da06f3c8.webp 1000w," sizes="100vw"><figcaption>MongoDB Atlas Dashboard Overview</figcaption></figure><h3>Setting Up a Free Cluster</h3><ol><li>Go to <a href="http://cloud.mongodb.com">cloud.mongodb.com</a> and sign up</li><li>Create a new project</li><li>Build a cluster - choose M0 (free tier) for learning</li><li>Create a database user with username and password</li><li>Whitelist your IP address under Network Access</li><li>Click Connect to get your connection string</li></ol><h3>Connection String Format</h3><pre><code class="language-ruby">mongodb+srv://&lt;username&gt;:&lt;password&gt;@cluster0.xxxxx.mongodb.net/&lt;dbname&gt;?retryWrites=true&amp;w=majority
</code></pre><h3>Atlas Features Worth Knowing</h3><ul><li><strong>Atlas Search</strong> - full-text search powered by Lucene</li><li><strong>Atlas Triggers</strong> - run serverless functions on database events</li><li><strong>Atlas Data API</strong> - access data over HTTP without a driver</li><li><strong>Backups</strong> - automated point-in-time backups</li><li><strong>Performance Advisor</strong> - suggests indexes based on slow queries</li></ul><hr><h2>10. Security and Access Control</h2><h3>Authentication</h3><p>MongoDB supports several authentication mechanisms:</p><ul><li><strong>SCRAM</strong> (default) - username/password</li><li><strong>X.509</strong> - certificate-based</li><li><strong>LDAP</strong> - enterprise only</li><li><strong>Kerberos</strong> - enterprise only</li></ul><pre><code class="language-ruby"># Connect with authentication
mongosh "mongodb://username:password@localhost:27017/dbname"
</code></pre><h3>Built-in Roles</h3><figure class="table"><table><thead><tr><th>Role</th><th>Access Level</th></tr></thead><tbody><tr><td><code>read</code></td><td>Read all collections in a DB</td></tr><tr><td><code>readWrite</code></td><td>Read and write to a DB</td></tr><tr><td><code>dbAdmin</code></td><td>Admin tasks, no user management</td></tr><tr><td><code>userAdmin</code></td><td>Manage users and roles</td></tr><tr><td><code>clusterAdmin</code></td><td>Manage the entire cluster</td></tr><tr><td><code>readAnyDatabase</code></td><td>Read across all databases</td></tr><tr><td><code>root</code></td><td>Superuser - full access</td></tr></tbody></table></figure><h3>Creating a User</h3><pre><code class="language-javascript">use admin

db.createUser({
  user: "appUser",
  pwd: "securePassword123",
  roles: [
    { role: "readWrite", db: "shopDB" }
  ]
})
</code></pre><h3>Data Protection Best Practices</h3><ul><li>Always enable <strong>authentication</strong> (disabled by default in local dev)</li><li>Use <strong>TLS/SSL</strong> for connections in production</li><li>Enable <strong>encryption at rest</strong> (Atlas does this automatically)</li><li>Never expose MongoDB port (27017) directly to the internet</li><li>Rotate credentials regularly</li><li>Use <strong>schema validation</strong> to prevent malformed data</li></ul><pre><code class="language-javascript">// Adding schema validation to a collection
db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "email"],
      properties: {
        email: { bsonType: "string" }
      }
    }
  }
})
</code></pre><hr><h2>11. Scaling and Performance Optimization</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Mongo_DB_Replication_and_Sharding_Architecture_4fab013943.webp" alt="MongoDB Replication and Sharding Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Mongo_DB_Replication_and_Sharding_Architecture_4fab013943.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Mongo_DB_Replication_and_Sharding_Architecture_4fab013943.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Mongo_DB_Replication_and_Sharding_Architecture_4fab013943.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Mongo_DB_Replication_and_Sharding_Architecture_4fab013943.webp 1000w," sizes="100vw"><figcaption>MongoDB Replication and Sharding Architecture</figcaption></figure><h3>Replication</h3><p>A <strong>replica set</strong> is a group of MongoDB instances that hold the same data. It provides high availability and data redundancy.</p><pre><code class="language-ruby">Primary Node──writes──&gt;  Secondary Node 1
                 └────&gt;  Secondary Node 2
</code></pre><ul><li>Reads go to the primary by default; can be configured to read from secondaries</li><li>If the primary goes down, an automatic election picks a new primary</li><li>Minimum recommended: 3 nodes (1 primary + 2 secondaries)</li><li>Write concern and read preference control consistency vs performance tradeoffs</li></ul><pre><code class="language-ruby">// Connect to replica set
mongosh "mongodb://host1:27017,host2:27017,host3:27017/dbname?replicaSet=myReplicaSet"
</code></pre><h3>Sharding</h3><p>Sharding distributes data horizontally across multiple machines. Use it when a single machine can no longer handle the data volume or throughput.</p><ul><li><strong>Shard</strong> - a replica set holding a subset of data</li><li><strong>Mongos</strong> - the router that directs queries to the right shard</li><li><strong>Config Servers</strong> - store cluster metadata</li><li><strong>Shard Key</strong> - the field used to distribute data across shards</li></ul><pre><code class="language-javascript">// Enable sharding on a database
sh.enableSharding("shopDB")

// Shard a collection by a key
sh.shardCollection("shopDB.orders", { customerId: "hashed" })
</code></pre><p><strong>Choosing a good shard key:</strong></p><ul><li>High cardinality (many unique values)</li><li>Even distribution of reads and writes</li><li>Avoid monotonically increasing fields like timestamps as the sole shard key (causes hotspots)</li></ul><h3>Query Optimization Checklist</h3><ul><li>Always use <code>explain("executionStats")</code> to analyze slow queries</li><li>Ensure commonly queried fields are indexed</li><li>Avoid using <code>$where</code> (executes JavaScript - very slow)</li><li>Use projections to return only needed fields</li><li>Avoid large <code>skip()</code> values on big collections; use cursor-based pagination instead</li><li>Keep documents lean - don't store fields you never query</li><li>Use covered queries (index covers all fields in query + projection - no document fetch needed)</li></ul><pre><code class="language-javascript">// Covered query example
// Index: { email: 1, name: 1 }
db.users.find(
  { email: "test@example.com" },
  { name: 1, _id: 0 }
)
// MongoDB can return the result purely from the index, without touching documents
</code></pre><hr><h2>Quick Reference Card</h2><h3>Most Used Commands</h3><pre><code class="language-javascript">// Database
use dbName
show dbs
show collections
db.dropDatabase()

// CRUD
db.col.insertOne({})
db.col.insertMany([])
db.col.find({ field: value })
db.col.findOne({ field: value })
db.col.updateOne({ filter }, { $set: {} })
db.col.updateMany({ filter }, { $set: {} })
db.col.deleteOne({ filter })
db.col.deleteMany({ filter })

// Aggregation
db.col.aggregate([ {$match:{}}, {$group:{}}, {$sort:{}} ])

// Indexes
db.col.createIndex({ field: 1 })
db.col.getIndexes()
db.col.dropIndex("indexName")

// Explain
db.col.find({}).explain("executionStats")
</code></pre><h3>Operator Quick Reference</h3><figure class="table"><table><thead><tr><th>Category</th><th>Operators</th></tr></thead><tbody><tr><td>Comparison</td><td><code>$eq $ne $gt $gte $lt $lte $in $nin</code></td></tr><tr><td>Logical</td><td><code>$and $or $not $nor</code></td></tr><tr><td>Update</td><td><code>$set $unset $inc $push $pull $addToSet $rename</code></td></tr><tr><td>Array</td><td><code>$elemMatch $size $all</code></td></tr><tr><td>Aggregation</td><td><code>$match $group $project $sort $limit $skip $lookup $unwind</code></td></tr><tr><td>Accumulators</td><td><code>$sum $avg $min $max $first $last $push $count</code></td></tr></tbody></table></figure><hr><h2>Conclusion</h2><p>MongoDB offers a flexible and powerful approach to data modeling, making it an excellent choice for modern, scalable applications. With its document-based structure, rich query capabilities, and support for indexing, aggregation, and distributed systems, it enables developers to build high-performance backends with ease.</p><p>Mastering MongoDB is not just about learning queries, but understanding how to design schemas, optimize performance, and scale systems effectively. By applying the concepts in this guide, you can confidently use MongoDB in real-world applications and production environments.</p><p>If you found this helpful, consider sharing it with your friends and peers who are learning or working with MongoDB.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>MangoDB</category>
            <category>NoSQL</category>
            <category>Database</category>
            <category>Backend</category>
            <category>CRUD</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Mongo_Db_in_one_shot_Thumbnail_ac9da9f96e.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Inside a Spring Boot Request — Threads, Security, Transactions & System Limits Explained]]></title>
            <link>https://www.codingshuttle.com/blogs/inside-a-spring-boot-request-threads-security-transactions-memory-and-system-limits</link>
            <guid>https://www.codingshuttle.com/blogs/inside-a-spring-boot-request-threads-security-transactions-memory-and-system-limits</guid>
            <pubDate>Sun, 15 Mar 2026 06:35:21 GMT</pubDate>
            <description><![CDATA[A developer-friendly reference covering the full Spring Boot request lifecycle. From client TCP connection to Tomcat thread handling, security filter chain, DispatcherServlet routing, controller-service-repository flow, transactional management, database connection pooling, and JSON response serialization. Includes thread isolation, bottlenecks, and performance considerations—ideal for debugging, tuning, and understanding internal mechanics quickly.]]></description>
            <content:encoded><![CDATA[<p>Inside a Spring Boot Request — Threads, Security, Transactions, Memory, and System Limits</p><p>Most developers interact with Spring Boot at the surface level: write a controller, add a service, annotate a method with <code>@Transactional</code>, and ship it. But understanding what happens inside the application from the moment a request arrives to the moment a response is sent back is what separates a developer who writes code from an engineer who understands systems.</p><p>This article walks through the complete internal lifecycle of a Spring Boot HTTP request. It covers how threads are assigned, how security context is established, how transactions bind to the request, how database connections are managed, and where your application breaks under load. Every section describes behavior that is actually happening inside your JVM right now — most of it invisible unless you know where to look.</p><hr><h2>Overview — The Complete Request Journey</h2><p>When a client sends an HTTP request to a Spring Boot application, it enters a well-defined pipeline. Each stage has a specific role. Nothing happens randomly.</p><p>At the highest level, the journey looks like this:</p><ol><li>The client sends a TCP connection and HTTP request to the embedded server (Tomcat by default).</li><li>The server accepts the connection and assigns a worker thread from its thread pool.</li><li>The request passes through the Servlet filter chain, which includes Spring Security filters.</li><li>The authenticated request reaches <code>DispatcherServlet</code>, which routes it to the correct controller method.</li><li>The controller delegates work to a service, which may open a database transaction and interact with a repository.</li><li>A database connection is borrowed from the connection pool, queries are executed, and the connection is returned.</li><li>The response is serialized (usually to JSON) and written back over the TCP connection.</li><li>The thread is released back to the pool, ready for the next request.</li></ol><p>Every single one of these steps has performance implications, memory implications, and failure modes. Let us go through each one carefully.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/HTTP_request_lifecycle_in_Spring_Boot_11fad3b200.webp" alt="HTTP request lifecycle in SpringBoot" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_HTTP_request_lifecycle_in_Spring_Boot_11fad3b200.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_HTTP_request_lifecycle_in_Spring_Boot_11fad3b200.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_HTTP_request_lifecycle_in_Spring_Boot_11fad3b200.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_HTTP_request_lifecycle_in_Spring_Boot_11fad3b200.webp 1000w," sizes="100vw"><figcaption>HTTP request lifecycle in SpringBoot</figcaption></figure><hr><h2>Request Entry and Thread Assignment</h2><h3>What is a Thread</h3><p>A thread is the smallest unit of execution in a Java process. When your Spring Boot application starts, it runs inside a single JVM process. That process can run many threads concurrently, each with its own execution stack, meaning each thread tracks its own method calls, local variables, and program counter independently.</p><p>Threads share heap memory, which is where objects live. But each thread has private stack memory, which is where its method call frames live. This distinction matters because it is exactly how Spring Boot isolates request state.</p><h3>How the Server Assigns a Thread</h3><p>Spring Boot ships with an embedded Tomcat server by default. When Tomcat starts, it creates a pool of worker threads. This pool sits idle, waiting for incoming connections.</p><p>When a new HTTP request arrives, Tomcat accepts the TCP connection on the acceptor thread, then hands the actual request processing off to a worker thread from the pool. From that moment forward, the entire lifecycle of that request — filters, controllers, services, database calls — happens on that one worker thread unless you explicitly change that.</p><p>This is called the thread-per-request model. It is the default behavior in Spring MVC.</p><pre><code class="language-java">// This entire method executes on one worker thread
@GetMapping("/orders/{id}")
public ResponseEntity&lt;Order&gt; getOrder(@PathVariable Long id) {
    return ResponseEntity.ok(orderService.findById(id));
}
</code></pre><p>The thread is occupied for the full duration of the request. If your method blocks on a database query for 200ms, the thread is held for those 200ms and cannot serve any other request during that time.</p><h3>Async and Reactive Exceptions</h3><p>If you introduce <code>@Async</code>, <code>CompletableFuture</code>, or Spring WebFlux, work may move to a different thread mid-request. When that happens, critical pieces of thread-local state — specifically the <code>SecurityContextHolder</code> and any active transaction — do not automatically follow. They are bound to the original thread and become invisible on the new thread.</p><pre><code class="language-java">@Async
public CompletableFuture&lt;String&gt; processAsync() {
    // This runs on a different thread
    // SecurityContextHolder.getContext() may return an empty context here
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    return CompletableFuture.completedFuture(auth.getName()); // may throw NullPointerException
}
</code></pre><p>You must explicitly propagate state when crossing thread boundaries. Spring provides <code>DelegatingSecurityContextRunnable</code> and <code>DelegatingSecurityContextCallable</code> for this. In WebFlux, use <code>ReactiveSecurityContextHolder</code>.</p><hr><h2>Thread Pool and Request Concurrency</h2><h3>How the Thread Pool Works</h3><p>Tomcat maintains a bounded thread pool. By default, it allows up to 200 worker threads. When a request arrives, a free thread is taken from the pool and assigned to that request. When the request finishes, the thread is returned to the pool and becomes available again.</p><p>You can tune this in <code>application.properties</code>:</p><pre><code class="language-php">server.tomcat.threads.max=200
server.tomcat.threads.min-spare=10
server.tomcat.accept-count=100
</code></pre><p><code>threads.max</code> defines the maximum number of concurrent requests being actively processed. <code>accept-count</code> defines how many requests can be queued waiting for a thread when the pool is full.</p><h3>Concurrent Request Processing</h3><p>Two requests arriving at the same millisecond are handled on two separate threads simultaneously. They may be executing code in the same service class and the same repository class at the same time, but each has its own stack, its own local variables, and its own thread-local state. This is how Spring achieves request isolation without any locking overhead in the typical case.</p><pre><code class="language-ruby">Thread-47: GET /orders/101 -&gt; SecurityContext(user=alice) -&gt; Transaction-A -&gt; Connection-1
Thread-52: GET /orders/202 -&gt; SecurityContext(user=bob)   -&gt; Transaction-B -&gt; Connection-2
</code></pre><p>These two requests run in complete isolation from each other, even though they are executing the same code paths.</p><h3>What Happens When the Pool is Full</h3><p>When all 200 threads are occupied with in-progress requests, new incoming requests do not get rejected immediately. They are placed in a TCP accept queue (bounded by <code>accept-count</code>). If that queue also fills up, the server stops accepting new TCP connections, and clients will see a connection timeout or connection refused error.</p><p>This is the first hard throughput ceiling your application has.</p><hr><h2>Memory Usage of Request Threads</h2><h3>Thread Stack Size</h3><p>Each thread has a dedicated stack allocated from JVM memory. In most JVMs, the default thread stack size is 512KB to 1MB. With 200 threads, that alone accounts for 100MB to 200MB of memory reserved for thread stacks, independent of heap usage.</p><p>You can tune stack size with the <code>-Xss</code> JVM flag:</p><pre><code class="language-ruby">java -Xss512k -jar myapp.jar
</code></pre><p>Reducing stack size allows more threads to exist within the same memory footprint, but too small a stack causes <code>StackOverflowError</code> for deeply recursive code.</p><h3>Request and Response Objects</h3><p>Every HTTP request creates a <code>HttpServletRequest</code> object on the heap. It holds the request headers, query parameters, path variables, and request body. The response object (<code>HttpServletResponse</code>) holds the response buffer. For large request bodies or file uploads, these objects can consume significant heap memory.</p><p>Spring also creates objects throughout the chain: filter instances (shared, not per-request), the <code>Authentication</code> object in the security context, the <code>@Transactional</code> proxy interceptor call frames, repository proxies, and finally the response DTO serialized to JSON.</p><p>All of these are garbage collected after the request completes, but during the request they all live on the heap. High-traffic applications can generate significant GC pressure if response objects are large or if many requests are running concurrently.</p><hr><h2>Security Processing and User Isolation</h2><h3>The Filter Chain</h3><p>Before a request ever reaches <code>DispatcherServlet</code>, it passes through the Servlet filter chain. Spring Security registers itself as a filter in this chain, specifically through <code>FilterChainProxy</code>. This proxy delegates to a series of security filters, each with a specific responsibility.</p><p>The most important for most applications is <code>UsernamePasswordAuthenticationFilter</code> or, in stateless APIs, a custom JWT authentication filter. This filter extracts the credentials or token from the request, validates them, and creates an <code>Authentication</code> object.</p><h3>SecurityContextHolder and ThreadLocal Isolation</h3><p>Once authenticated, Spring Security stores the <code>Authentication</code> object in the <code>SecurityContextHolder</code>. Under the hood, <code>SecurityContextHolder</code> uses a <code>ThreadLocal</code> variable to store the security context.</p><p>A <code>ThreadLocal</code> is a per-thread variable. Each thread has its own independent copy. When thread-47 sets a value in a <code>ThreadLocal</code>, thread-52 cannot read it. This is precisely what guarantees that user Alice's authentication on thread-47 is never visible on thread-52, which is serving user Bob.</p><pre><code class="language-java">// Spring does this on your behalf during the filter chain
SecurityContextHolder.getContext().setAuthentication(authentication);

// Your code can then safely read the authenticated user anywhere in the same request
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
</code></pre><p>After the request completes, the <code>SecurityContextPersistenceFilter</code> clears the security context from the thread before it returns to the pool. If this did not happen, the next request handled by the same thread would inherit the previous user's authentication — a serious security bug.</p><p>[Image Placeholder: Spring Security filter chain showing ThreadLocal security context isolation per request thread] Image Generation Prompt: "clean minimal technical diagram showing Spring Security filter chain with ThreadLocal security context isolation, two parallel request threads each having their own security context with different authenticated users, educational software architecture diagram, white background"</p><h3>Async and Reactive Exceptions</h3><p>In asynchronous processing, the thread changes. When a task is submitted to a thread pool via <code>@Async</code> or <code>CompletableFuture.supplyAsync()</code>, the new thread has no security context. <code>SecurityContextHolder.getContext().getAuthentication()</code> returns null.</p><p>To propagate the security context across threads, wrap your runnable:</p><pre><code class="language-java">// Manually propagate security context to async thread
SecurityContext context = SecurityContextHolder.getContext();
executor.submit(new DelegatingSecurityContextRunnable(() -&gt; {
    // SecurityContext is now available here
    String user = SecurityContextHolder.getContext().getAuthentication().getName();
}, context));
</code></pre><p>In Spring WebFlux (reactive), there is no thread-local model at all. Use <code>ReactiveSecurityContextHolder</code>:</p><pre><code class="language-java">return ReactiveSecurityContextHolder.getContext()
    .map(ctx -&gt; ctx.getAuthentication().getName())
    .flatMap(username -&gt; userService.findByUsername(username));
</code></pre><hr><h2>Request Routing Inside Spring MVC</h2><h3>DispatcherServlet</h3><p>After the filter chain completes, the request reaches <code>DispatcherServlet</code>. This is the central front controller in Spring MVC. There is one <code>DispatcherServlet</code> per application context, and every request passes through it.</p><p><code>DispatcherServlet</code> does not contain any business logic. Its job is routing. It consults a list of <code>HandlerMapping</code> implementations to find which controller method should handle this specific request.</p><h3>Handler Mappings</h3><p>The primary handler mapping for annotation-based controllers is <code>RequestMappingHandlerMapping</code>. During application startup, it scans all beans annotated with <code>@Controller</code> or <code>@RestController</code> and builds a map of URL patterns to method references.</p><p>When a request for <code>GET /orders/101</code> arrives, <code>RequestMappingHandlerMapping</code> looks up this URL and HTTP method combination, finds the matching <code>@GetMapping("/orders/{id}")</code> method, and returns a <code>HandlerMethod</code> object wrapping that method reference.</p><p><code>DispatcherServlet</code> then finds the appropriate <code>HandlerAdapter</code> (usually <code>RequestMappingHandlerAdapter</code>) and invokes the method. The adapter handles argument resolution (reading <code>@PathVariable</code>, <code>@RequestBody</code>, <code>@RequestParam</code>) and return value handling (writing the response).</p><pre><code class="language-java">@RestController
@RequestMapping("/orders")
public class OrderController {

    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Long id) {
        // DispatcherServlet resolved this method via RequestMappingHandlerMapping
        // RequestMappingHandlerAdapter resolved @PathVariable from the URL
        return orderService.findById(id);
    }
}
</code></pre><hr><h2>Application Layer Execution</h2><h3>The Layered Architecture</h3><p>Spring Boot applications typically follow a three-layer architecture: controller, service, and repository. This is not a framework requirement but a widely adopted convention that separates HTTP concerns from business logic from data access.</p><p>The controller receives the HTTP request and translates it into method calls. It should contain no business logic. The service layer contains the domain logic. The repository layer handles database interaction, typically through Spring Data JPA.</p><h3>How the Call Flows Through the Layers</h3><p>From the developer's perspective, this is a straightforward method call chain. But Spring wraps each layer with proxy objects that add behavior transparently.</p><p>When your controller calls <code>orderService.findById(id)</code>, it is not calling your <code>OrderServiceImpl</code> directly. It is calling a Spring-generated proxy. That proxy checks whether any AOP advice applies to this method — including <code>@Transactional</code> transaction management, caching interceptors, security authorization checks, and any custom aspects you may have defined.</p><pre><code class="language-java">@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Transactional(readOnly = true)
    public Order findById(Long id) {
        // The proxy opens a transaction before this line executes
        return orderRepository.findById(id)
            .orElseThrow(() -&gt; new OrderNotFoundException(id));
        // The proxy commits/closes the transaction after this returns
    }
}
</code></pre><p>The <code>OrderRepository</code> is itself a JPA repository proxy that translates the <code>findById</code> call into a JPQL query, manages the <code>EntityManager</code>, and handles the result mapping. All of this happens within the same worker thread.</p><hr><h2>Transaction Lifecycle</h2><h3>How Transactions Begin</h3><p>When a method annotated with <code>@Transactional</code> is called through its proxy, Spring's <code>TransactionInterceptor</code> runs before the method body executes. It checks the transaction propagation setting (default is <code>REQUIRED</code>, meaning use an existing transaction or create a new one) and, if a new transaction is needed, calls the <code>PlatformTransactionManager</code> to begin one.</p><p>For JPA with HikariCP, beginning a transaction means: obtain a database connection from the connection pool, set <code>autoCommit=false</code> on that connection, and bind both the connection and the transaction status to the current thread using <code>TransactionSynchronizationManager</code>.</p><pre><code class="language-java">// TransactionSynchronizationManager stores the connection in a ThreadLocal map
// keyed by the DataSource
resources.set(dataSource, connectionHolder); // stored in ThreadLocal
</code></pre><p>This is the key point: the transaction is thread-bound. The database connection holding the open transaction is stored in a <code>ThreadLocal</code>, which means it is only accessible from the thread that started the transaction.</p><h3>Commit and Rollback</h3><p>After your method returns normally, the <code>TransactionInterceptor</code> calls <code>commit()</code> on the transaction. The connection flushes any pending SQL, commits the transaction on the database, sets <code>autoCommit=true</code>, and returns the connection to the pool.</p><p>If your method throws an unchecked exception (a <code>RuntimeException</code> or <code>Error</code>), the interceptor calls <code>rollback()</code> instead. The in-progress transaction is rolled back on the database, and the connection is returned to the pool.</p><pre><code class="language-java">@Transactional
public void placeOrder(OrderRequest request) {
    Order order = new Order(request);
    orderRepository.save(order);       // INSERT executed but not yet committed
    inventoryService.deduct(request);  // if this throws, the INSERT is rolled back
    // commit happens here if no exception was thrown
}
</code></pre><h3>Async and Reactive Exceptions</h3><p>Transactions are bound to the current thread via <code>ThreadLocal</code>. If the thread changes mid-transaction — which happens with <code>@Async</code>, <code>CompletableFuture</code>, or reactive pipelines — the new thread has no transaction context. Any JPA operations on the new thread will either start a new transaction or run without one, depending on propagation settings.</p><p>There is no clean way to continue a JDBC transaction across thread boundaries. The recommended pattern is to complete all transactional work on a single thread, then hand off non-transactional work asynchronously.</p><p>For reactive applications, Spring provides <code>ReactiveTransactionManager</code> and <code>@Transactional</code> support in WebFlux, but this operates on a Reactor context rather than <code>ThreadLocal</code>, and requires reactive-compatible database drivers (R2DBC, not JDBC).</p><hr><h2>Database Connection Pool Usage</h2><h3>How the Pool Works</h3><p>Spring Boot auto-configures HikariCP as the default connection pool. On startup, HikariCP creates a pool of physical JDBC connections to your database server. By default, <code>maximumPoolSize</code> is 10.</p><p>When a transaction begins (as described above), the <code>TransactionInterceptor</code> asks HikariCP for a connection. HikariCP checks if any connections are idle in the pool. If one is available, it marks it as borrowed and returns it. If none are available, the calling thread waits up to <code>connectionTimeout</code> milliseconds (default 30 seconds) for a connection to become free.</p><pre><code class="language-php">spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.idle-timeout=600000
</code></pre><h3>The Connection Is Held for the Transaction Duration</h3><p>A connection is held for the entire duration of the transaction. If your transaction opens at the start of a service method and does not commit until the end, the connection is tied up for that entire period — including any time spent doing computation, calling external services, or executing slow queries.</p><p>This is the second hard throughput ceiling: with <code>maximumPoolSize=10</code>, only 10 transactions can hold active database connections at any given moment. Thread 11 through 200 will be blocked waiting for a connection if the first 10 threads are all in active transactions.</p><h3>Pool Exhaustion</h3><p>When the connection pool is exhausted and no connection becomes free within <code>connectionTimeout</code>, HikariCP throws a <code>SQLTransientConnectionException</code>. This surfaces in your application as a 500 error.</p><p>The common mistake here is setting <code>maximumPoolSize</code> too high. More connections do not mean more throughput; they mean more concurrency on the database, which eventually saturates database CPU. The right pool size depends on your database server's capacity and your query patterns.</p><hr><h2>Response Generation</h2><h3>Returning from the Controller</h3><p>Once the service method returns its result, control flows back through the proxy layers (any <code>@AfterReturning</code> advice, transaction commit) and eventually back to <code>DispatcherServlet</code>, which now has the return value from the controller method.</p><p>For <code>@RestController</code> methods, the return value needs to be serialized to an HTTP response body. <code>DispatcherServlet</code> hands this off to a <code>HandlerMethodReturnValueHandler</code>, which for <code>ResponseEntity</code> or plain objects, delegates to an <code>HttpMessageConverter</code>.</p><h3>Jackson and JSON Serialization</h3><p>Spring Boot auto-configures Jackson's <code>MappingJackson2HttpMessageConverter</code>. When the content negotiation process determines that the client expects <code>application/json</code> (typically from the <code>Accept</code> header or by default), Jackson is used to serialize the return object.</p><p>Jackson uses reflection to inspect the object's fields, calls getter methods, and writes a JSON string to the <code>HttpServletResponse</code>'s output stream.</p><pre><code class="language-java">// Your controller returns this
return new OrderResponse(order.getId(), order.getStatus(), order.getTotal());

// Jackson serializes it to:
// {"id": 101, "status": "CONFIRMED", "total": 49.99}
// and writes it to the response output buffer
</code></pre><p>The response is then flushed over the TCP connection back to the client, and the worker thread is released back to Tomcat's thread pool.</p><hr><h2>System Limits and Throughput</h2><h3>The Three Hard Limits</h3><p>Every Spring Boot application operating under the thread-per-request model has three fundamental throughput ceilings:</p><p>The first is the thread pool size. With a default of 200 threads, you can process at most 200 requests concurrently. If each request takes 100ms on average, your theoretical maximum throughput is around 2000 requests per second — and in practice, it will be lower due to overhead.</p><p>The second is the database connection pool size. With a default of 10 connections, at most 10 requests can be in an active transaction simultaneously. If your average transaction time is 20ms, that is 500 transactional operations per second before threads start queuing for connections.</p><p>The third is the database server itself — its CPU, memory, I/O, and the complexity of your queries. The connection pool is a client-side throttle that protects the database. If you bypass it by increasing pool size too aggressively, you transfer the bottleneck to the database server instead.</p><pre><code class="language-php">Max concurrent requests:        server.tomcat.threads.max = 200
Max concurrent DB transactions: spring.datasource.hikari.maximum-pool-size = 10
Queue for waiting requests:     server.tomcat.accept-count = 100
Wait for DB connection:         spring.datasource.hikari.connection-timeout = 30000ms
</code></pre><h3>Throughput Formula</h3><p>Effective throughput depends on request latency. If average request duration is <code>L</code> milliseconds and you have <code>T</code> threads, your maximum throughput is approximately <code>T / L * 1000</code> requests per second.</p><p>A 50ms average request latency with 200 threads gives roughly 4000 req/sec theoretical maximum — but that only holds if no other bottleneck intervenes, which in practice, the database connection pool usually does first.</p><hr><h2>Bottlenecks and Failure Scenarios</h2><h3>Thread Exhaustion</h3><p>Thread exhaustion occurs when all 200 worker threads are occupied and the TCP accept queue is also full. New clients receive connection refused errors. Existing requests in the accept queue receive connection timeout errors after waiting.</p><p>The most common cause is not raw traffic volume — it is slow requests. If your application normally handles requests in 50ms but a downstream service starts responding in 5 seconds, threads start piling up. With 200 threads and a 5-second average duration, the system saturates at just 40 requests per second instead of 4000.</p><p>Symptoms include rising response time metrics, thread pool exhaustion alerts, and eventually connection refused errors from the load balancer.</p><p>The solution is a combination of: timeouts on external calls, circuit breakers, and either horizontal scaling or moving to a reactive model for I/O-heavy workloads.</p><h3>Connection Pool Exhaustion</h3><p>Connection pool exhaustion happens when all 10 (or however many you configured) database connections are held and no new one becomes available within <code>connectionTimeout</code>. Threads that need a connection block, which accelerates thread exhaustion.</p><p>The common triggers are: slow database queries holding connections longer than usual, unexpectedly high traffic, a transaction that holds a connection open across a remote API call (a very common mistake), or a connection leak where connections are borrowed but never returned.</p><pre><code class="language-java">// Common mistake: transaction spans an external HTTP call
@Transactional
public OrderConfirmation checkout(CartRequest cart) {
    Order order = orderRepository.save(new Order(cart));     // borrows connection
    paymentResult = paymentGateway.charge(cart.getPayment()); // holds connection for 2-3 seconds
    order.setStatus(paymentResult.getStatus());
    return orderRepository.save(order);                      // releases connection after this
}
</code></pre><p>The fix is to restructure so that the remote call happens outside the transaction, and the transaction only wraps the actual database operations.</p><h3>Request Timeouts</h3><p>If Tomcat has no explicit request timeout configured and a slow request holds a thread for minutes, it simply occupies that thread for the full duration. You can set a read timeout:</p><pre><code class="language-php">server.tomcat.connection-timeout=20000
</code></pre><p>At the application level, setting timeouts on <code>RestTemplate</code>, <code>WebClient</code>, and database query execution limits prevents single slow operations from consuming thread resources indefinitely.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Spring_Boot_bottleneck_65946fc375.webp" alt="SpringBoot bottleneck" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Spring_Boot_bottleneck_65946fc375.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Spring_Boot_bottleneck_65946fc375.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Spring_Boot_bottleneck_65946fc375.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Spring_Boot_bottleneck_65946fc375.webp 1000w," sizes="100vw"><figcaption>SpringBoot bottleneck</figcaption></figure><hr><h2>Final Visualization — Complete Request Lifecycle</h2><p>The diagram below ties together every stage described in this article. Following the full path of a single request reveals how each component depends on the one before it, and why bottlenecks in one layer cascade into failures across the rest.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Complete_end_to_end_Spring_Boot_request_lifecycle_fa163cddc7.webp" alt="Complete end-to-end SpringBoot request lifecycle" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Complete_end_to_end_Spring_Boot_request_lifecycle_fa163cddc7.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Complete_end_to_end_Spring_Boot_request_lifecycle_fa163cddc7.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Complete_end_to_end_Spring_Boot_request_lifecycle_fa163cddc7.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Complete_end_to_end_Spring_Boot_request_lifecycle_fa163cddc7.webp 1000w," sizes="100vw"><figcaption>Complete end-to-end SpringBoot request lifecycle</figcaption></figure><p>The sequence for a single request, fully detailed:</p><p><strong>Step 1 — TCP Acceptance.</strong> The client opens a TCP connection. Tomcat's acceptor thread receives it and places it in the worker queue.</p><p><strong>Step 2 — Thread Assignment.</strong> A worker thread from the thread pool picks up the request. This thread will carry the request from this point until the response is written.</p><p><strong>Step 3 — Filter Chain.</strong> The request traverses the filter chain. Spring Security filters extract the JWT or session token, validate it, create an <code>Authentication</code> object, and store it in the <code>SecurityContextHolder</code> <code>ThreadLocal</code> on this thread.</p><p><strong>Step 4 — DispatcherServlet Routing.</strong> <code>DispatcherServlet</code> consults <code>RequestMappingHandlerMapping</code>, finds the target controller method, and invokes it via <code>RequestMappingHandlerAdapter</code>.</p><p><strong>Step 5 — Controller Proxy.</strong> The controller calls the service through a Spring AOP proxy. The proxy evaluates any applicable aspects before delegating to the actual service method.</p><p><strong>Step 6 — Transaction Begins.</strong> The <code>@Transactional</code> proxy intercepts the service method call. <code>TransactionInterceptor</code> asks HikariCP for a connection. HikariCP lends one from the pool. The connection is bound to the current thread via <code>TransactionSynchronizationManager</code>.</p><p><strong>Step 7 — Repository and Query Execution.</strong> The repository proxy translates the method call into SQL via JPA/Hibernate. The SQL is executed on the borrowed connection. Results are mapped to entity objects.</p><p><strong>Step 8 — Transaction Commits.</strong> Control returns to the <code>@Transactional</code> proxy. No exception was thrown, so the transaction is committed. The connection is returned to HikariCP's pool.</p><p><strong>Step 9 — Response Serialization.</strong> The controller returns a response object. Jackson serializes it to JSON and writes it to the <code>HttpServletResponse</code> output buffer.</p><p><strong>Step 10 — Security Context Cleared.</strong> Spring Security's <code>SecurityContextPersistenceFilter</code> clears the <code>ThreadLocal</code> context, ensuring no user data leaks to the next request.</p><p><strong>Step 11 — Thread Released.</strong> The response is flushed over TCP. The worker thread is returned to Tomcat's thread pool, ready for the next request.</p><hr><h2>Conclusion</h2><p>Understanding the internal lifecycle of a Spring Boot request is not just academic—it provides a mental model that helps you reason about performance, debug production issues, and make confident architectural decisions.</p><p>The thread-per-request model in Spring MVC ensures that every layer of your application executes on the same OS thread. This thread carries all state: security context, transaction bindings, and borrowed database connections. Any break in that continuity—through async execution, reactive pipelines, or additional thread pools—requires explicit management of this state.</p><p>Your application's throughput ceiling isn’t determined by your code alone. It’s defined by three key numbers: <code>threads.max</code>, <code>maximum-pool-size</code>, and average request latency. Measure these under realistic load and tune them for your actual workload instead of relying on defaults.</p><p>When traffic spikes, failures follow a predictable cascade: slow requests fill threads, threads waiting for connections queue up, the connection pool exhausts, and clients see 500 errors. Understanding this pattern allows you to detect issues early and respond before a full outage occurs.</p><p>If you find this guide useful, share it with your friends!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Spring Boot</category>
            <category>HTTP Request Lifecycle</category>
            <category>Performance Tuning</category>
            <category>Thread and Connection Management</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Inside_A_Springboot_Request_Thumbnail_52578e1623.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Docker Explained Simply - The Only Cheat Sheet you need]]></title>
            <link>https://www.codingshuttle.com/blogs/docker-in-one-shot-the-ultimate-cheatsheet</link>
            <guid>https://www.codingshuttle.com/blogs/docker-in-one-shot-the-ultimate-cheatsheet</guid>
            <pubDate>Wed, 11 Mar 2026 09:15:27 GMT</pubDate>
            <description><![CDATA[This Docker cheat sheet is a concise reference guide for developers, computer science students, and DevOps beginners learning containerization. It covers core Docker concepts such as images, containers, networking, volumes, and registries in a clear and structured format. The guide also includes essential Docker commands, Dockerfile examples, and docker-compose configurations for managing containerized applications. It serves as a quick reference to help developers build, run, and deploy applications efficiently using Docker.]]></description>
            <content:encoded><![CDATA[<p>Docker Explained Simply - The Only Cheat Sheet you need</p><p>Docker has revolutionized software development by enabling consistent, isolated application environments through containerization. This cheat sheet provides a concise reference for developers, students, and DevOps beginners to quickly master essential Docker concepts and commands. Use it as your go-to guide for daily Docker tasks, from building images to orchestrating multi-container applications.</p><h2>Introduction to Docker</h2><h3>What is Docker and Why Use It</h3><p>Docker is a platform that packages applications and their dependencies into lightweight containers that run consistently across any system. It eliminates the "works on my machine" problem by ensuring identical environments from development to production. Developers use Docker to simplify dependency management, streamline deployment, and improve resource utilization compared to traditional virtual machines.</p><h3>Problems Docker Solves</h3><ul><li>Environment inconsistencies between development, testing, and production</li><li>Complex dependency management and version conflicts</li><li>Inefficient resource utilization with traditional virtualization</li><li>Slow onboarding of new team members to existing projects</li><li>Difficulty scaling applications across different infrastructure</li></ul><h3>Docker vs Virtual Machines</h3><p>Containers share the host operating system kernel and run as isolated processes, while virtual machines include complete guest operating systems. This fundamental difference makes containers more lightweight, faster to start, and more resource-efficient than VMs.</p><figure class="table"><table><thead><tr><th>Aspect</th><th>Containers</th><th>Virtual Machines</th></tr></thead><tbody><tr><td>Operating System</td><td>Share host OS kernel</td><td>Each VM has its own OS</td></tr><tr><td>Resource Usage</td><td>Lightweight (MBs)</td><td>Heavy (GBs)</td></tr><tr><td>Startup Time</td><td>Seconds</td><td>Minutes</td></tr><tr><td>Isolation</td><td>Process-level</td><td>Hardware-level</td></tr><tr><td>Performance</td><td>Near-native</td><td>Some overhead</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Docker_vs_Virtual_Machine_Architecture_Comparison_2d0bacd4aa.png" alt="Docker vs Virtual Machine Architecture Comparison" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Docker_vs_Virtual_Machine_Architecture_Comparison_2d0bacd4aa.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Docker_vs_Virtual_Machine_Architecture_Comparison_2d0bacd4aa.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Docker_vs_Virtual_Machine_Architecture_Comparison_2d0bacd4aa.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Docker_vs_Virtual_Machine_Architecture_Comparison_2d0bacd4aa.png 1000w," sizes="100vw"><figcaption>Docker vs Virtual Machine Architecture Comparison</figcaption></figure><h3>What is a Container</h3><p>A container is a standard unit of software that packages code and all its dependencies so the application runs quickly and reliably across computing environments. Containers virtualize the operating system rather than hardware, making them portable and efficient. Each container runs as an isolated process in user space on the host operating system.</p><h3>Docker Architecture</h3><p>Docker uses a client-server architecture where the client communicates with a daemon that handles building, running, and distributing containers. The daemon exposes a REST API that clients use to manage containers, images, networks, and volumes.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Docker_Architecture_Diagram_93b2e88a21.png" alt="Docker Architecture Diagram" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Docker_Architecture_Diagram_93b2e88a21.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Docker_Architecture_Diagram_93b2e88a21.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Docker_Architecture_Diagram_93b2e88a21.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Docker_Architecture_Diagram_93b2e88a21.png 1000w," sizes="100vw"><figcaption>Docker Architecture Diagram</figcaption></figure><p><strong>Key Components:</strong></p><ul><li><strong>Docker Client</strong>: Command-line tool that sends commands to the daemon</li><li><strong>Docker Daemon</strong>: Background service that manages Docker objects</li><li><strong>Docker Images</strong>: Read-only templates used to create containers</li><li><strong>Docker Containers</strong>: Runnable instances of Docker images</li><li><strong>Docker Registry</strong>: Repository for storing and distributing images</li></ul><h2>Docker Installation</h2><h3>Installing Docker on Windows</h3><p>Download Docker Desktop for Windows from the official Docker Hub website and run the installer. Enable WSL 2 integration during installation for better performance and Linux compatibility. After installation, Docker Desktop runs as a system tray application.</p><h3>Installing Docker on Mac</h3><p>Download Docker Desktop for Mac from Docker Hub and drag the application to your Applications folder. The installer includes both Intel and Apple Silicon versions for compatibility. Docker Desktop runs as a menu bar application with a simple management interface.</p><h3>Installing Docker on Linux</h3><p>Use the official package manager for your distribution to install Docker Engine. Add your user to the docker group to run commands without sudo. Enable the Docker service to start automatically on system boot.</p><pre><code class="language-ruby"># Verify Docker installation
docker --version
docker run hello-world
</code></pre><h2>Docker Core Concepts</h2><h3>Docker Images</h3><p>An image is a read-only template with instructions for creating a Docker container. Images are built from Dockerfiles and consist of multiple layers that can be cached and reused. You can create custom images or use pre-built images from Docker Hub.</p><h3>Docker Containers</h3><p>A container is a runnable instance of an image that includes the application, its dependencies, and runtime configuration. Containers can be started, stopped, moved, and deleted while maintaining their state through volumes. Multiple containers can run from the same image with different configurations.</p><h3>Container Lifecycle</h3><p>Containers transition through different states during their lifetime, from creation to removal. Understanding these states helps in managing container resources and debugging issues.</p><figure class="table"><table><thead><tr><th>State</th><th>Description</th><th>Command</th></tr></thead><tbody><tr><td>Created</td><td>Container created but not started</td><td>docker create</td></tr><tr><td>Running</td><td>Container executing with active processes</td><td>docker start</td></tr><tr><td>Paused</td><td>Processes frozen, memory preserved</td><td>docker pause</td></tr><tr><td>Stopped</td><td>Main process terminated</td><td>docker stop</td></tr><tr><td>Removed</td><td>Container deleted, resources freed</td><td>docker rm</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Docker_Container_Lifecycle_States_51f63ad845.png" alt="Docker Container Lifecycle States" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Docker_Container_Lifecycle_States_51f63ad845.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Docker_Container_Lifecycle_States_51f63ad845.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Docker_Container_Lifecycle_States_51f63ad845.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Docker_Container_Lifecycle_States_51f63ad845.png 1000w," sizes="100vw"><figcaption><code>Docker Container Lifecycle States</code></figcaption></figure><h3>Dockerfile</h3><p>A Dockerfile is a text file containing instructions to build a Docker image automatically. Each instruction creates a layer in the image, with later layers building on previous ones. The Dockerfile defines the base image, application code, dependencies, and startup commands.</p><pre><code class="language-php">FROM node:18-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 3000
USER node
CMD ["node", "server.js"]
</code></pre><figure class="table"><table><thead><tr><th>Instruction</th><th>Purpose</th></tr></thead><tbody><tr><td>FROM</td><td>Base image</td></tr><tr><td>WORKDIR</td><td>Set working directory</td></tr><tr><td>COPY</td><td>Copy files into image</td></tr><tr><td>ADD</td><td>Copy with additional features</td></tr><tr><td>RUN</td><td>Execute commands during build</td></tr><tr><td>ENV</td><td>Set environment variables</td></tr><tr><td>EXPOSE</td><td>Document port usage</td></tr><tr><td>CMD</td><td>Default container command</td></tr><tr><td>ENTRYPOINT</td><td>Main executable</td></tr><tr><td>USER</td><td>Set user for container</td></tr></tbody></table></figure><h3>Docker Image Layers</h3><p>Each instruction in a Dockerfile creates a new layer in the final image, forming a stack of read-only filesystem changes. Docker caches these layers, so unchanged instructions reuse existing layers during subsequent builds. Layer caching significantly speeds up build times and reduces bandwidth when sharing images.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Docker_Image_Layers_Diagram_e95fa8733b.png" alt="Docker Image Layers Diagram" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Docker_Image_Layers_Diagram_e95fa8733b.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Docker_Image_Layers_Diagram_e95fa8733b.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Docker_Image_Layers_Diagram_e95fa8733b.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Docker_Image_Layers_Diagram_e95fa8733b.png 1000w," sizes="100vw"><figcaption><code>Docker Image Layers Diagram</code></figcaption></figure><h2>Working with Docker Images</h2><h3>Building Docker Images</h3><p>The docker build command creates images from a Dockerfile and context directory. Tags help organize and version images for easy reference and distribution. Build context includes all files sent to the daemon during image creation.</p><pre><code class="language-ruby">docker build -t my-api:latest .
docker build -t my-api:v1.0 --build-arg ENV=production .
</code></pre><h3>Managing Images</h3><p>Images require regular maintenance to remove unused ones and free disk space. Local images are stored in the Docker daemon's storage area and can be inspected for details.</p><pre><code class="language-ruby">docker images
docker image ls --filter dangling=true
docker rmi my-api:latest
docker image prune -a
docker inspect my-api
</code></pre><h2>Working with Containers</h2><h3>Running Containers</h3><p>Containers start from images and can be configured with ports, volumes, environment variables, and restart policies. Port publishing maps container ports to host ports for external access. Background mode (-d) runs containers in the background, while interactive mode (-it) provides terminal access.</p><pre><code class="language-ruby">docker run -d --name web-app -p 8080:80 nginx:alpine
docker run --rm -it -v $(pwd):/app node:18 npm init
docker run --env DB_HOST=localhost --env DB_PORT=5432 my-api
</code></pre><h3>Managing Containers</h3><p>Container management involves monitoring, stopping, starting, and removing containers as needed. Container IDs can be referenced using the first few characters of the full ID.</p><pre><code class="language-ruby">docker ps -a
docker stop web-app
docker start web-app
docker restart web-app
docker rm web-app
docker logs --tail 50 web-app
</code></pre><h3>Interactive Containers</h3><p>Interactive containers provide shell access for debugging, development, and exploration. The -it flag combines interactive mode with a pseudo-TTY for terminal support. You can execute additional commands in running containers with docker exec.</p><pre><code class="language-ruby">docker run -it --name debug ubuntu:22.04 bash
docker exec -it web-app sh
docker run -it --entrypoint sh alpine:latest
</code></pre><figure class="table"><table><thead><tr><th>State</th><th>Description</th><th>Command</th></tr></thead><tbody><tr><td>Created</td><td>Container defined</td><td><code>docker create</code></td></tr><tr><td>Running</td><td>Active container</td><td><code>docker start</code></td></tr><tr><td>Paused</td><td>Processes frozen</td><td><code>docker pause</code></td></tr><tr><td>Stopped</td><td>Execution finished</td><td><code>docker stop</code></td></tr><tr><td>Removed</td><td>Container deleted</td><td><code>docker rm</code></td></tr></tbody></table></figure><h2>Docker Volumes and Storage</h2><h3>Docker Volumes</h3><p>Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. They are completely managed by Docker and stored in the Docker storage directory. Volumes can be named for easy reference and shared between multiple containers.</p><pre><code class="language-ruby">docker volume create app-data
docker volume ls
docker run -v app-data:/var/lib/postgresql/data postgres:15
docker volume inspect app-data
</code></pre><h3>Bind Mounts</h3><p>Bind mounts map a host file or directory into a container, providing direct access to host filesystem. They are ideal for development where code changes should reflect immediately in the container. Bind mounts depend on the host filesystem structure and permissions.</p><pre><code class="language-ruby">docker run -v /host/data:/container/data nginx
docker run --mount type=bind,src=/host/config,target=/app/config nginx
</code></pre><h3>tmpfs Mounts</h3><p>tmpfs mounts store data in the host's memory only, never written to the filesystem. They provide high-performance temporary storage for sensitive data that shouldn't persist. tmpfs mounts are ideal for secrets, tokens, or cache data.</p><pre><code class="language-ruby">docker run --tmpfs /app/cache:rw,noexec,nosuid,size=64m nginx
</code></pre><h3>Storage Types Comparison</h3><figure class="table"><table><thead><tr><th>Type</th><th>Persistence</th><th>Use Case</th><th>Performance</th></tr></thead><tbody><tr><td>Volumes</td><td>Persistent, Docker-managed</td><td>Production data, databases</td><td>Native</td></tr><tr><td>Bind Mounts</td><td>Persistent, host-managed</td><td>Development, configuration files</td><td>Native</td></tr><tr><td>tmpfs</td><td>Non-persistent, in-memory</td><td>Cache, temporary files, secrets</td><td>Fastest</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Docker_Volume_Storage_Architecture_f5cc6fcd57.png" alt="Docker Volume Storage Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Docker_Volume_Storage_Architecture_f5cc6fcd57.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Docker_Volume_Storage_Architecture_f5cc6fcd57.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Docker_Volume_Storage_Architecture_f5cc6fcd57.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Docker_Volume_Storage_Architecture_f5cc6fcd57.png 1000w," sizes="100vw"><figcaption><code>Docker Volume Storage Architecture</code></figcaption></figure><h2>Docker Networking</h2><h3>Docker Networking Basics</h3><p>Networking enables containers to communicate with each other and with the outside world. Each container gets a virtual network interface with an IP address when created. Docker provides pluggable network drivers for different communication patterns.</p><pre><code class="language-ruby">docker network create --driver bridge my-network
docker network connect my-network my-container
docker network disconnect my-network my-container
docker network inspect bridge
</code></pre><h3>Network Types</h3><p>Docker supports multiple network drivers to address different communication requirements. The choice of network type affects container isolation, performance, and accessibility.</p><figure class="table"><table><thead><tr><th>Network Type</th><th>Description</th><th>When to Use</th></tr></thead><tbody><tr><td>Bridge</td><td>Default network, containers communicate via bridge</td><td>Single host, multiple containers</td></tr><tr><td>Host</td><td>Removes network isolation, uses host networking</td><td>Performance-critical apps</td></tr><tr><td>None</td><td>No network access, complete isolation</td><td>Security-sensitive containers</td></tr><tr><td>Overlay</td><td>Spans multiple Docker hosts</td><td>Swarm mode, multi-host clusters</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Docker_Network_Types_Diagram_4678b8d5eb.png" alt="Docker Network Types Diagram" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Docker_Network_Types_Diagram_4678b8d5eb.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Docker_Network_Types_Diagram_4678b8d5eb.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Docker_Network_Types_Diagram_4678b8d5eb.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Docker_Network_Types_Diagram_4678b8d5eb.png 1000w," sizes="100vw"><figcaption><code>Docker Network Types Diagram</code></figcaption></figure><h2>Docker Registry</h2><h3>Docker Hub</h3><p>Docker Hub is the default public registry where you can find thousands of official and community images. It provides automated builds, webhooks, and organization accounts for teams. Official images are maintained by Docker or the software vendor, ensuring quality and security.</p><h3>Private Registries</h3><p>Private registries store images internally for security, compliance, or performance reasons. You can run your own registry using the registry:2 image or use cloud provider solutions. Private registries require authentication and can be integrated with CI/CD pipelines.</p><h3>Pushing Images</h3><p>Pushing images makes them available to other developers and deployment environments. Images must be tagged with the registry name before pushing. Authentication is required for private registries and Docker Hub.</p><pre><code class="language-ruby">docker login -u username
docker tag my-app:latest username/my-app:latest
docker push username/my-app:latest
docker push myregistry.com:5000/my-app:latest
</code></pre><h3>Pulling Images</h3><p>Pulling downloads images from a registry to your local Docker daemon. Images are pulled by name and tag, with :latest being the default if no tag specified. Pulls only download layers not already present locally.</p><pre><code class="language-ruby">docker pull nginx:alpine
docker pull myregistry.com:5000/my-api:v2
docker pull postgres:15
</code></pre><h2>Multi Container Applications</h2><h3>Problems with Single Containers</h3><p>Single containers become complex when applications require databases, caches, or multiple services. Managing dependencies, networking, and data persistence across services becomes challenging. Scaling individual components independently is impossible with monolithic containers.</p><h3>Multi Container Architecture</h3><p>Multi-container applications separate concerns into specialized containers that communicate over networks. Each container runs a single process or service, following the Unix philosophy. This architecture enables independent scaling, updates, and maintenance of each component.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Multi_Container_Application_Architecture_ad385ea14f.png" alt="Multi-Container Application Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Multi_Container_Application_Architecture_ad385ea14f.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Multi_Container_Application_Architecture_ad385ea14f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Multi_Container_Application_Architecture_ad385ea14f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Multi_Container_Application_Architecture_ad385ea14f.png 1000w," sizes="100vw"><figcaption><code>Multi-Container Application Architecture</code></figcaption></figure><h2>Docker Compose</h2><h3>What is Docker Compose</h3><p>Docker Compose is a tool for defining and running multi-container Docker applications using YAML files. It simplifies container orchestration by managing networks, volumes, and service dependencies. One command starts all services defined in the compose file.</p><h3>docker-compose.yml Structure</h3><p>The compose file defines services, networks, and volumes for your application. Services specify container images, ports, environment variables, and dependencies. Networks enable service discovery using service names as hostnames.</p><pre><code class="language-php">version: '3.8'

services:
  web:
    build: ./web
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    depends_on:
      - api

  api:
    build: ./api
    environment:
      - DB_HOST=postgres
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:15-alpine
    volumes:
      - pg-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]

volumes:
  pg-data:
</code></pre><h3>Running Compose Applications</h3><p>Compose commands manage the entire application lifecycle from a single directory. Services start in dependency order and can be scaled for specific services. Compose projects are isolated by directory or project name.</p><pre><code class="language-ruby">docker compose up -d
docker compose down -v
docker compose logs -f
docker compose ps
docker compose exec web sh
docker compose restart api
</code></pre><h3>Compose with Networks</h3><p>Custom networks provide service isolation and controlled communication between containers. Networks can be defined with specific drivers and configurations. Services on the same network can resolve each other by service name.</p><pre><code class="language-php">version: '3.8'

services:
  frontend:
    build: ./frontend
    networks:
      - frontend
      - backend

  backend:
    build: ./backend
    networks:
      - backend
    depends_on:
      - redis

  redis:
    image: redis:alpine
    networks:
      - backend

networks:
  frontend:
  backend:
    driver: bridge
</code></pre><h3>Compose with Volumes</h3><p>Volumes in Compose persist data across container restarts and recreations. Named volumes are managed by Docker, while bind mounts map host directories. Volume configurations can include driver options and labels.</p><pre><code class="language-php">version: '3.8'

services:
  mysql:
    image: mysql:8
    volumes:
      - mysql-data:/var/lib/mysql
      - ./backup:/backup:ro
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}

  app:
    build: .
    volumes:
      - ./uploads:/app/uploads
      - ./config:/app/config:ro

volumes:
  mysql-data:
    driver: local
    driver_opts:
      type: none
      device: /data/mysql
      o: bind
</code></pre><h3>Compose with Port Binding</h3><p>Port binding exposes container ports to the host or other networks. Published ports can be mapped to specific host ports or random high ports. Port configurations support both IPv4 and IPv6 addresses.</p><pre><code class="language-php">version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
      - "127.0.0.1:8080:80"

  app:
    build: .
    ports:
      - "3000"
    expose:
      - "3000"
</code></pre><h2>Useful Docker Commands Cheat Sheet</h2><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>docker ps</td><td>List running containers</td><td>docker ps -a</td></tr><tr><td>docker images</td><td>List local images</td><td>docker images --format "table"</td></tr><tr><td>docker build</td><td>Build image from Dockerfile</td><td>docker build -t app .</td></tr><tr><td>docker run</td><td>Create and start container</td><td>docker run -d nginx</td></tr><tr><td>docker stop</td><td>Stop running container</td><td>docker stop container_id</td></tr><tr><td>docker start</td><td>Start stopped container</td><td>docker start container_id</td></tr><tr><td>docker rm</td><td>Remove container</td><td>docker rm -f container_id</td></tr><tr><td>docker rmi</td><td>Remove image</td><td>docker rmi image_name</td></tr><tr><td>docker pull</td><td>Download image</td><td>docker pull alpine:latest</td></tr><tr><td>docker push</td><td>Upload image</td><td>docker push user/app:tag</td></tr><tr><td>docker exec</td><td>Run command in container</td><td>docker exec -it cont bash</td></tr><tr><td>docker logs</td><td>View container logs</td><td>docker logs -f cont</td></tr><tr><td>docker network</td><td>Network management</td><td>docker network ls</td></tr><tr><td>docker volume</td><td>Volume management</td><td>docker volume prune</td></tr><tr><td>docker compose</td><td>Compose management</td><td>docker compose up</td></tr></tbody></table></figure><h2>Docker Best Practices</h2><p><strong>Small Images</strong></p><ul><li>Use minimal base images like alpine, slim variants, or distroless</li><li>Combine RUN commands to reduce layer count</li><li>Remove package manager caches and temporary files</li><li>Use multi-stage builds to discard build dependencies</li></ul><p><strong>Multi-Stage Builds</strong></p><ul><li>Separate build environment from runtime environment</li><li>Copy only artifacts from build stage to final stage</li><li>Reduce final image size by excluding build tools</li><li>Maintain separate stages for development and production</li></ul><pre><code class="language-php">FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
</code></pre><p><strong>.dockerignore</strong></p><ul><li>Exclude version control directories (.git, .svn)</li><li>Ignore local configuration files (.env, .local)</li><li>Skip build artifacts and dependency caches</li><li>Exclude test files and documentation</li></ul><pre><code class="language-php">.git
node_modules
.env
*.log
Dockerfile
.dockerignore
</code></pre><p><strong>Non-Root Containers</strong></p><ul><li>Create and use non-root users in containers</li><li>Set USER instruction in Dockerfile</li><li>Avoid running processes as root</li><li>Use read-only root filesystems when possible</li></ul><h2>Docker Workflow</h2><p>The Docker development workflow provides a consistent path from code to deployment. Changes are tested in containers matching production environments. Images are versioned and stored in registries for distribution.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Complete_Docker_Development_Workflow_8fcf570ccc.png" alt="Complete Docker Development Workflow" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Complete_Docker_Development_Workflow_8fcf570ccc.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Complete_Docker_Development_Workflow_8fcf570ccc.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Complete_Docker_Development_Workflow_8fcf570ccc.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Complete_Docker_Development_Workflow_8fcf570ccc.png 1000w," sizes="100vw"><figcaption><code>Complete Docker Development Workflow</code></figcaption></figure><ol><li>Write application code and create Dockerfile</li><li>Build image with docker build and tag appropriately</li><li>Test locally with docker run or docker compose</li><li>Push image to registry with docker push</li><li>Deploy to production using docker run or orchestrator</li><li>Monitor and update containers as needed</li></ol><h2>Conclusion</h2><p>Docker has become the industry standard for containerization, enabling developers to build, ship, and run applications anywhere with consistency and efficiency. By packaging applications with their dependencies, containers eliminate environment inconsistencies and streamline the development-to-production pipeline. This cheat sheet provides essential commands and concepts for daily Docker use, from basic container operations to multi-application orchestration with Compose. Keep it handy as your quick reference to master container workflows and build portable, scalable applications in any environment.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Docker</category>
            <category>Containers</category>
            <category>Devops</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Docker_In_one_shot_thumbnail_b9ab569b66.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Git & Github in One Shot - The Ultimate Cheatsheet]]></title>
            <link>https://www.codingshuttle.com/blogs/git-and-github-in-one-shot-the-ultimate-cheatsheet</link>
            <guid>https://www.codingshuttle.com/blogs/git-and-github-in-one-shot-the-ultimate-cheatsheet</guid>
            <pubDate>Wed, 11 Mar 2026 03:43:37 GMT</pubDate>
            <description><![CDATA[Git & GitHub in One Shot – The Ultimate Cheatsheet is a developer-focused quick reference that covers essential Git commands, branching strategies, workflows, and GitHub collaboration features. It helps developers track changes, manage repositories, resolve conflicts, and maintain a clean project history efficiently, making it ideal for beginners, students, and professionals alike.]]></description>
            <content:encoded><![CDATA[<p>Git &amp; Github in one Shot - The Ultimate Cheatsheet</p><p>Git is the industry-standard version control system that tracks changes in your code, enables collaboration, and protects your project history. GitHub builds on Git by providing cloud hosting, pull requests, and team collaboration tools. This cheat sheet gives you quick access to essential Git commands, workflows, and best practices without the fluff.</p><h2>Getting Started with Git</h2><h3>What is Git and Why Use It</h3><p>Git is a distributed version control system that records snapshots of your files, allowing you to revert to previous states, compare changes, and collaborate without overwriting work. Unlike centralized systems, every developer has a complete copy of the project history locally. Git was created by Linus Torvalds in 2005 to manage the Linux kernel development efficiently.</p><p><strong>Key Points</strong></p><ul><li>Git tracks content changes, not just file names</li><li>Every clone is a full backup of the entire repository</li><li>Branching in Git is lightweight and inexpensive</li><li>Changes are stored as snapshots, not file differences</li><li>Git uses cryptographic hashing (SHA-1) to ensure data integrity</li></ul><h3>Local vs Remote Repositories</h3><p>A local repository exists on your machine and contains the complete project history with all branches. A remote repository is hosted on a server like GitHub, GitLab, or Bitbucket, enabling team collaboration and backup.</p><p><strong>Key Points</strong></p><ul><li>Local repos allow offline work and fast operations</li><li>Remote repos serve as the centralized source of truth</li><li>Changes move between repos through push and pull operations</li><li>You can connect multiple remotes to a single local repo</li><li>The default remote name is typically "origin"</li></ul><h3>Git Installation and Configuration</h3><p>Install Git from <a href="http://git-scm.com/">git-scm.com</a> or using your package manager. After installation, configure your identity and preferences to ensure commits are properly attributed.</p><pre><code class="language-ruby"># Set your global username and email
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Set your default branch name (Git 2.28+)
git config --global init.defaultBranch main

# Configure line endings (Windows vs Mac/Linux)
git config --global core.autocrlf input  # Mac/Linux
git config --global core.autocrlf true   # Windows

# View all configurations
git config --list
</code></pre><h3>Initializing and Cloning Repositories</h3><p>Start version control in an existing project with <code>git init</code> or copy an existing remote repository with <code>git clone</code>. These are the entry points to any Git workflow.</p><pre><code class="language-ruby"># Initialize a new repository in current folder
git init

# Initialize in a specific directory
git init project-name

# Clone an existing repository
git clone &lt;https://github.com/user/repo.git&gt;

# Clone into a specific folder name
git clone &lt;https://github.com/user/repo.git&gt; my-folder

# Clone with SSH (recommended for frequent pushes)
git clone git@github.com:user/repo.git
</code></pre><h3>Basic Git Workflow</h3><p>The fundamental workflow moves changes from your working directory to the staging area, then commits them to the repository history. This three-step process gives you control over what gets recorded.</p><pre><code class="language-ruby"># Check status of your working directory
git status

# Add specific files to staging
git add filename.txt

# Add all changes in current directory
git add .

# Add all changes in the entire repository
git add -A

# Commit staged changes with a message
git commit -m "Descriptive commit message"

# View commit history
git log

# View condensed one-line history
git log --oneline

# See what's changed but not staged
git diff

# See staged changes
git diff --staged
</code></pre><p><strong>Key Points</strong></p><ul><li>Working directory contains files you're editing</li><li>Staging area (index) is where you prepare your next commit</li><li>Commits are permanent snapshots with unique IDs</li><li>Always write clear commit messages explaining why, not what</li></ul><h3>Ignoring Files with .gitignore</h3><p>The <code>.gitignore</code> file tells Git which files or patterns to intentionally untrack, keeping your repository clean of temporary files, build artifacts, and sensitive information.</p><p><strong>Key Points</strong></p><ul><li>Place <code>.gitignore</code> in your repository root or subdirectories</li><li>Patterns support wildcards and negation with <code>!</code></li><li>Already tracked files are not affected by ignore rules</li><li>Use global gitignore for OS-specific files</li><li>Common ignores: node_modules, .env, .DS_Store, build folders</li></ul><pre><code class="language-php"># Example .gitignore patterns
# Dependencies
node_modules/
vendor/

# Build outputs
dist/
build/
*.exe
*.dll

# Environment files
.env
.env.local

# IDE files
.vscode/
.idea/
*.swp

# OS files
.DS_Store
Thumbs.db
</code></pre><h2>Branching and Collaboration</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Branching_and_Collaboration_991acafcf6.png" alt="Branching and Collaboration" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Branching_and_Collaboration_991acafcf6.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Branching_and_Collaboration_991acafcf6.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Branching_and_Collaboration_991acafcf6.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Branching_and_Collaboration_991acafcf6.png 1000w," sizes="100vw"><figcaption>Branching and Collaboration</figcaption></figure><h3>Branching in Git</h3><p>Branches are lightweight pointers to specific commits, allowing parallel development without affecting the main codebase. Creating and switching branches is instantaneous because Git just moves a pointer.</p><pre><code class="language-ruby"># List local branches
git branch

# List all branches including remote
git branch -a

# Create a new branch
git branch feature-login

# Switch to a branch
git checkout feature-login

# Create and switch in one command
git checkout -b feature-login

# Rename a branch
git branch -m old-name new-name

# Delete a branch (fully merged)
git branch -d feature-login

# Force delete unmerged branch
git branch -D feature-login
</code></pre><p><strong>Key Points</strong></p><ul><li>Main branch is typically called <code>main</code> or <code>master</code></li><li>Keep branches focused on single features or fixes</li><li>Delete branches after merging to keep clean history</li><li>Branch names should be descriptive: <code>feature/</code>, <code>bugfix/</code>, <code>hotfix/</code></li></ul><h3>Handling Merge Conflicts</h3><p>A <strong>merge conflict</strong> occurs when Git cannot automatically reconcile differences between two branches. This usually happens when the same line of a file has been modified differently in two branches.</p><p><strong>Signs of a Conflict</strong></p><ul><li>Git shows messages like <code>CONFLICT (content): Merge conflict in &lt;file&gt;</code></li><li><code>git status</code> shows files as <code>both modified</code></li></ul><p><strong>Resolving Conflicts</strong></p><ol><li>Open the conflicted file(s). Git marks conflicts like this:</li></ol><pre><code class="language-ruby">&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
Your changes here
=======
Incoming changes here
&gt;&gt;&gt;&gt;&gt;&gt;&gt; feature-branch
</code></pre><ol><li>Edit the file to keep the correct version or combine changes.</li><li>After fixing conflicts, mark as resolved:</li></ol><pre><code class="language-ruby">git add filename.txt</code></pre><ol><li>Complete the merge:</li></ol><pre><code class="language-ruby">git commit
# Or if rebasing
git rebase--continue</code></pre><p><strong>Best Practices</strong></p><ul><li>Pull frequently to minimize conflicts</li><li>Communicate with teammates about overlapping work</li><li>Keep branches small and focused</li><li>Use tools like <code>git mergetool</code> for complex merges</li></ul><h3>Merging vs Rebasing</h3><p>Both commands integrate changes from one branch into another, but they handle history differently. Merges preserve exact chronology while rebasing creates a linear history.</p><figure class="table"><table><thead><tr><th>Aspect</th><th>Merge</th><th>Rebase</th></tr></thead><tbody><tr><td>History</td><td>Preserves exact timeline with merge commits</td><td>Creates linear, cleaner history</td></tr><tr><td>Commit IDs</td><td>Original commits keep their IDs</td><td>Commits get new SHA hashes</td></tr><tr><td>Complexity</td><td>Simple, safe for shared branches</td><td>Riskier for public branches</td></tr><tr><td>Troubleshooting</td><td>Easier to see when changes happened</td><td>Harder to trace original context</td></tr><tr><td>Use case</td><td>Integrating completed features</td><td>Updating feature branch with main</td></tr></tbody></table></figure><pre><code class="language-ruby"># Merge feature into main (stay on main branch)
git merge feature-branch

# Merge with no fast-forward (always creates merge commit)
git merge --no-ff feature-branch

# Rebase current branch onto main
git checkout feature-branch
git rebase main

# Interactive rebase (squash, edit, reorder commits)
git rebase -i HEAD~3</code></pre><p><strong>Key Points</strong></p><ul><li>Never rebase public/shared branches</li><li>Merge when preserving context matters</li><li>Rebase for clean, linear history before pull requests</li><li>Interactive rebase helps clean up local commits</li></ul><h3>Remote Repositories</h3><p>Remotes are versions of your repository hosted on servers. They enable collaboration by allowing you to share commits and pull changes from teammates.</p><pre><code class="language-ruby"># Add a remote repository
git remote add origin &lt;https://github.com/user/repo.git&gt;

# List configured remotes
git remote -v

# Fetch changes without merging
git fetch origin

# Fetch and merge (pull) from remote
git pull origin main

# Push local commits to remote
git push origin main

# Push and set upstream tracking
git push -u origin main

# Remove a remote
git remote remove origin

# Rename a remote
git remote rename origin upstream
</code></pre><p><strong>Key Points</strong></p><ul><li><code>origin</code> is the default name for your cloned remote</li><li><code>upstream</code> often refers to the original repository in forks</li><li>Fetch is safe; pull combines fetch and merge</li><li>Always pull before pushing to avoid conflicts</li></ul><h3>Collaborating with GitHub</h3><p>GitHub transforms Git from a version control system into a complete collaboration platform. It provides the interface and tools that enable teams to review code, track work, and automate workflows around your Git repositories.</p><p><strong>Key Points</strong></p><ul><li>Pull requests are the core of code review and collaboration</li><li>Issues track bugs, feature requests, and tasks</li><li>Projects visualize work using Kanban boards</li><li>GitHub Actions automate testing and deployment</li><li>Code owners can be automatically requested for reviews</li></ul><p><strong>Pull Request Workflow</strong></p><ol><li>Push your feature branch to GitHub</li><li>Open a pull request comparing your branch to main</li><li>Add a clear description and request reviewers</li><li>Discuss changes and push additional commits if needed</li><li>Merge once approved and all status checks pass</li><li>Delete the branch after merging to keep the repository clean</li></ol><h3>Forking and Syncing with Upstream</h3><p>Forking creates a personal copy of someone else's repository on GitHub. This is essential for open-source contributions where you don't have write access.</p><p><strong>Key Points</strong></p><ul><li>Forks are independent repositories under your account</li><li>Keep your fork synced to contribute clean pull requests</li><li>The original repo is typically called "upstream"</li><li>Never commit directly to upstream main</li></ul><pre><code class="language-ruby"># Add original repository as upstream remote
git remote add upstream &lt;https://github.com/original/repo.git&gt;

# Fetch upstream changes
git fetch upstream

# Checkout your local main
git checkout main

# Merge upstream changes into your main
git merge upstream/main

# Push updates to your fork
git push origin main
</code></pre><h3>Viewing Commit History</h3><p>Git's log provides powerful filtering and formatting options to navigate project history. Understanding history helps debug issues and understand code evolution.</p><pre><code class="language-ruby"># Standard log with details
git log

# One line per commit
git log --oneline

# Graph view with branches
git log --graph --oneline --all

# Show last 3 commits
git log -3

# Search commits by message
git log --grep="fix bug"

# Show commits by author
git log --author="username"

# Show files changed in each commit
git log --stat

# View specific file history
git log -p filename.txt
</code></pre><p><strong>Key Points</strong></p><ul><li>Each commit has a unique 40-character SHA hash</li><li>Use <code>-oneline</code> for the 7-character short hash</li><li>Combine flags for custom views</li><li><code>git show</code> displays a single commit's details</li></ul><h3>Undoing Changes</h3><p>Git provides multiple ways to undo changes depending on what stage they're in and whether you've shared them. Understanding the difference between reset, revert, and checkout is crucial.</p><pre><code class="language-ruby"># Unstage a file (keep changes)
git reset HEAD filename.txt

# Discard working directory changes
git checkout -- filename.txt

# Restore file to previous commit state
git restore filename.txt

# Undo last commit, keep changes staged
git reset --soft HEAD~1

# Undo last commit, unstage changes
git reset HEAD~1

# Undo last commit, discard all changes
git reset --hard HEAD~1

# Create new commit that undoes previous commit
git revert HEAD

# Revert a specific commit by hash
git revert abc123
</code></pre><p><strong>Key Points</strong></p><ul><li><code>reset</code> moves the branch pointer and optionally modifies working directory</li><li><code>revert</code> creates a new commit that undoes changes (safe for shared history)</li><li><code>checkout</code> or <code>restore</code> for working directory files</li><li>Never use <code>-hard</code> if you're unsure about losing changes</li></ul><h3>Tagging and Releases</h3><p>Tags mark specific points in history as important, typically for releases. They're like branch references that never move.</p><figure class="table"><table><thead><tr><th>Tag Type</th><th>Description</th><th>When to Use</th></tr></thead><tbody><tr><td>Lightweight</td><td>Just a pointer to a commit</td><td>Temporary labels, personal markers</td></tr><tr><td>Annotated</td><td>Full object with message, author, date</td><td>Public releases, official versions</td></tr></tbody></table></figure><pre><code class="language-ruby"># Create lightweight tag
git tag v1.0.0

# Create annotated tag
git tag -a v1.0.0 -m "Release version 1.0.0"

# List all tags
git tag

# List tags matching pattern
git tag -l "v1.*"

# Push specific tag to remote
git push origin v1.0.0

# Push all tags
git push --tags

# Delete local tag
git tag -d v1.0.0

# Delete remote tag
git push origin --delete v1.0.0

# Checkout tag (detached HEAD)
git checkout v1.0.0
</code></pre><h3>Collaboration Best Practices</h3><p>Effective collaboration requires clear conventions and communication. These practices prevent conflicts and keep history readable.</p><p><strong>Key Points</strong></p><ul><li>Write commit messages in imperative tense: "Fix login bug"</li><li>Pull before starting work to stay updated</li><li>Keep commits focused on single changes</li><li>Use feature branches for all changes</li><li>Review your own pull request before requesting reviews</li><li>Resolve conflicts locally before pushing</li><li>Communicate breaking changes in commit messages</li></ul><h3>Branching Strategies</h3><p>Different workflows suit different team sizes and release cycles. Choose the strategy that matches your deployment frequency and team structure.</p><figure class="table"><table><thead><tr><th>Strategy</th><th>Structure</th><th>Best For</th><th>Complexity</th></tr></thead><tbody><tr><td>Git Flow</td><td>main, develop, feature, release, hotfix</td><td>Large projects with scheduled releases</td><td>High</td></tr><tr><td>GitHub Flow</td><td>main + feature branches</td><td>Continuous deployment, simple projects</td><td>Low</td></tr><tr><td>Trunk-Based</td><td>short-lived feature branches off main</td><td>CI/CD, multiple daily deployments</td><td>Medium</td></tr></tbody></table></figure><p><strong>Git Flow</strong></p><ul><li><code>main</code> always reflects production-ready state</li><li><code>develop</code> integrates completed features</li><li>Release branches prepare for production</li><li>Hotfix branches patch production directly</li></ul><p><strong>GitHub Flow</strong></p><ul><li>Anything in <code>main</code> is deployable</li><li>Create branches for features/fixes</li><li>Open pull requests for discussion</li><li>Deploy immediately after merging</li></ul><p><strong>Trunk-Based Development</strong></p><ul><li>Small, frequent commits directly to main or short-lived branches</li><li>Feature flags hide incomplete work</li><li>Continuous integration runs on every commit</li><li>Releases are snapshots of main at any time</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/branching_workflows_side_by_side_e5cb291b58.png" alt="branching workflows side by side" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_branching_workflows_side_by_side_e5cb291b58.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_branching_workflows_side_by_side_e5cb291b58.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_branching_workflows_side_by_side_e5cb291b58.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_branching_workflows_side_by_side_e5cb291b58.png 1000w," sizes="100vw"><figcaption>Branching workflows side by side</figcaption></figure><h3>Stashing Changes and Applying Patches</h3><p>Stash temporarily saves uncommitted changes when you need to switch contexts. It's like a clipboard for your working directory.</p><pre><code class="language-ruby"># Save current changes to stash
git stash

# Save with a descriptive message
git stash save "WIP: login feature"

# List all stashes
git stash list

# Apply most recent stash (keep in stash)
git stash apply

# Apply and remove from stash
git stash pop

# Apply specific stash
git stash apply stash@{2}

# Create branch from stash
git stash branch new-branch

# Clear all stashes
git stash clear
</code></pre><p><strong>Key Points</strong></p><ul><li>Stashes are stack-based (last in, first out)</li><li>Untracked files aren't stashed by default (use <code>u</code>)</li><li>Stashes are local only, never pushed</li><li>Use for quick context switches, not long-term storage</li></ul><h3>Rewriting History</h3><p>Sometimes you need to clean up commits before sharing them. Amend and interactive rebase let you modify local history, but never rewrite public commits.</p><pre><code class="language-ruby"># Amend last commit (change message or add files)
git commit --amend -m "Better commit message"

# Add forgotten files to last commit
git add forgotten-file.txt
git commit --amend --no-edit

# Interactive rebase last 3 commits
git rebase -i HEAD~3

# Rebase from specific commit
git rebase -i abc123

# Squash multiple commits into one (during rebase)
# In rebase editor: change 'pick' to 'squash'
</code></pre><p><strong>Rebase Interactive Options</strong></p><ul><li><code>pick</code> - use the commit</li><li><code>reword</code> - change commit message</li><li><code>edit</code> - modify commit content</li><li><code>squash</code> - combine with previous commit</li><li><code>fixup</code> - like squash but discard message</li><li><code>drop</code> - remove commit</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/interactive_rebase_8d0785b77b.png" alt="Interactive rebase" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_interactive_rebase_8d0785b77b.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_interactive_rebase_8d0785b77b.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_interactive_rebase_8d0785b77b.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_interactive_rebase_8d0785b77b.png 1000w," sizes="100vw"><figcaption>Interactive rebase</figcaption></figure><h3>Git LFS for Large Files</h3><p>Git LFS (Large File Storage) replaces large files with text pointers while storing the actual content on a remote server. This keeps repositories fast and clones small.</p><p><strong>Key Points</strong></p><ul><li>Install LFS separately: <code>git lfs install</code></li><li>Track file types: <code>git lfs track "*.psd"</code></li><li>LFS files are downloaded only when needed</li><li>Requires server support (GitHub, GitLab support LFS)</li><li>Great for binaries, assets, datasets, and media</li></ul><pre><code class="language-ruby"># Install LFS in repository
git lfs install

# Track file patterns
git lfs track "*.zip"
git lfs track "assets/**"

# View tracked patterns
git lfs track

# List LFS files in repository
git lfs ls-files

# Migrate existing files to LFS
git lfs migrate import --include="*.psd" --everything
</code></pre><h3>Security in Git and GitHub</h3><p>Secure your code and access with proper authentication and repository protection. Never commit secrets, tokens, or passwords.</p><figure class="table"><table><thead><tr><th>Method</th><th>Setup</th><th>Use Case</th><th>Security</th></tr></thead><tbody><tr><td>HTTPS</td><td>Username + token</td><td>Simple setup, firewalls</td><td>Token-based, 2FA support</td></tr><tr><td>SSH</td><td>Generate key pair</td><td>Frequent pushes, automation</td><td>Key-based, very secure</td></tr></tbody></table></figure><pre><code class="language-ruby"># Generate SSH key
ssh-keygen -t ed25519 -C "your.email@example.com"

# Add key to ssh-agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# View public key to add to GitHub
cat ~/.ssh/id_ed25519.pub

# Test SSH connection
ssh -T git@github.com
</code></pre><p><strong>GitHub Security Features</strong></p><ul><li>Branch protection rules prevent direct pushes to main</li><li>Require pull request reviews before merging</li><li>Require status checks to pass</li><li>Dependabot alerts for vulnerable dependencies</li><li>Secret scanning detects committed credentials</li><li>Personal access tokens replace passwords for HTTPS&nbsp;</li></ul><h2>Workflow Summary</h2><p>The complete Git workflow connects local changes through staging, commits, and branches to remote collaboration and deployment.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Git_workflow_b2b9f2b522.png" alt="Git workflow" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Git_workflow_b2b9f2b522.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Git_workflow_b2b9f2b522.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Git_workflow_b2b9f2b522.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Git_workflow_b2b9f2b522.png 1000w," sizes="100vw"><figcaption>Git workflow</figcaption></figure><pre><code class="language-ruby"># Complete feature workflow example
git checkout -b feature/new-dashboard
git add .
git commit -m "Add dashboard components"
git push -u origin feature/new-dashboard
# Open pull request on GitHub
# Address review comments
git add .
git commit -m "Fix review feedback"
git push
# Merge when approved
git checkout main
git pull origin main
git branch -d feature/new-dashboard
</code></pre><h2>Conclusion</h2><p>Git and GitHub form the backbone of modern software development, enabling teams to collaborate efficiently while maintaining complete project history. This cheat sheet condenses years of best practices into a quick-reference format designed for daily use. Master these commands and workflows to work confidently whether you're solo coding or contributing to large open-source projects. Bookmark this guide, share it with your teammates, and return whenever you need to refresh your Git knowledge. If you found this useful, pass it along to fellow developers.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Git</category>
            <category>Version Control</category>
            <category>GitHub</category>
            <category>GitLab</category>
            <category>BitBucket</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Git_And_Github_In_One_S_Hot_Thumbnail_509f76e9d8.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Linux in One Shot - The Ultimate Cheat Sheet]]></title>
            <link>https://www.codingshuttle.com/blogs/linux-in-one-shot-the-ultimate-cheat-sheet</link>
            <guid>https://www.codingshuttle.com/blogs/linux-in-one-shot-the-ultimate-cheat-sheet</guid>
            <pubDate>Thu, 05 Mar 2026 18:53:59 GMT</pubDate>
            <description><![CDATA[A quick Linux cheat sheet with essential commands for files, processes, networking, and system management. Perfect for beginners and developers who need a fast reference while working in the terminal.]]></description>
            <content:encoded><![CDATA[<p>Linux in One Shot - The Ultimate Cheatsheet</p><p>Linux in One Shot – The Ultimate Cheatsheet is a compact reference guide that brings together the most important Linux concepts, commands, and tools in one place. It is designed for developers, system administrators, and students who want a quick yet practical overview of Linux without going through lengthy documentation. From basic terminal commands and file management to permissions, networking, and process control, this cheatsheet provides concise explanations and organized command tables for fast learning and easy reference.</p><h2>Introduction to Linux</h2><p>Linux is an open-source Unix-like operating system kernel first released by Linus Torvalds in 1991. It powers everything from servers and embedded systems to desktops and mobile devices. The operating system is distributed through various packages called distributions, with popular ones including Ubuntu, CentOS, Debian, and Fedora. Understanding Linux commands and concepts is essential for developers and system administrators working with servers, cloud infrastructure, or development environments.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Linux_Architecture_a0aaa68998.png" alt="Linux Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Linux_Architecture_a0aaa68998.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Linux_Architecture_a0aaa68998.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Linux_Architecture_a0aaa68998.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Linux_Architecture_a0aaa68998.png 1000w," sizes="100vw"><figcaption>Linux Architecture</figcaption></figure><h2>Linux File System Structure</h2><p>The Linux file system follows the Filesystem Hierarchy Standard (FHS), organizing all files and directories under the root directory ( / ). Everything in Linux is treated as a file, including hardware devices and system processes. Understanding this hierarchy helps you navigate and manage the system effectively.</p><figure class="table"><table><thead><tr><th>Directory</th><th>Purpose</th></tr></thead><tbody><tr><td>/bin</td><td>Essential command binaries</td></tr><tr><td>/boot</td><td>Boot loader files and kernel</td></tr><tr><td>/dev</td><td>Device files</td></tr><tr><td>/etc</td><td>System configuration files</td></tr><tr><td>/home</td><td>User home directories</td></tr><tr><td>/lib</td><td>Shared libraries and kernel modules</td></tr><tr><td>/media</td><td>Mount point for removable media</td></tr><tr><td>/mnt</td><td>Temporary mount point</td></tr><tr><td>/opt</td><td>Optional application software</td></tr><tr><td>/proc</td><td>Virtual filesystem for process information</td></tr><tr><td>/root</td><td>Root user's home directory</td></tr><tr><td>/sbin</td><td>System administration binaries</td></tr><tr><td>/tmp</td><td>Temporary files</td></tr><tr><td>/usr</td><td>User utilities and applications</td></tr><tr><td>/var</td><td>Variable data like logs</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Linux_File_System_Structure_d490da2804.png" alt="Linux File System Structure" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Linux_File_System_Structure_d490da2804.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Linux_File_System_Structure_d490da2804.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Linux_File_System_Structure_d490da2804.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Linux_File_System_Structure_d490da2804.png 1000w," sizes="100vw"><figcaption>Linux File System Structure</figcaption></figure><h2>Essential Linux Commands</h2><p>These fundamental commands form the foundation of working with Linux. Mastering them enables you to navigate the system, get help, and perform basic operations efficiently.</p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>man</td><td>Display manual pages</td><td>man ls</td></tr><tr><td>pwd</td><td>Print working directory</td><td>pwd</td></tr><tr><td>whoami</td><td>Show current username</td><td>whoami</td></tr><tr><td>date</td><td>Display system date/time</td><td>date</td></tr><tr><td>cal</td><td>Show calendar</td><td>cal 2024</td></tr><tr><td>echo</td><td>Print text to terminal</td><td>echo "Hello World"</td></tr><tr><td>clear</td><td>Clear terminal screen</td><td>clear</td></tr><tr><td>history</td><td>Show command history</td><td>history</td></tr></tbody></table></figure><pre><code class="language-ruby"># Get help with any command
man ls
ls --help

# Check system information
uname -a
hostname
</code></pre><h2>File and Directory Management</h2><p>Navigating and manipulating files and directories are daily tasks in Linux. These commands allow you to create, move, copy, delete, and search for files efficiently.</p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>ls</td><td>List directory contents</td><td>ls -la /home</td></tr><tr><td>cd</td><td>Change directory</td><td>cd /var/log</td></tr><tr><td>mkdir</td><td>Create directory</td><td>mkdir -p projects/src</td></tr><tr><td>rmdir</td><td>Remove empty directory</td><td>rmdir olddir</td></tr><tr><td>cp</td><td>Copy files/directories</td><td>cp -r source dest</td></tr><tr><td>mv</td><td>Move/rename files</td><td>mv file.txt newname.txt</td></tr><tr><td>rm</td><td>Remove files</td><td>rm -rf tempdir</td></tr><tr><td>touch</td><td>Create empty file</td><td>touch newfile.txt</td></tr><tr><td>find</td><td>Search for files</td><td>find . -name "*.conf"</td></tr><tr><td>locate</td><td>Find files by name</td><td>locate passwd</td></tr></tbody></table></figure><pre><code class="language-ruby"># Create nested directories
mkdir -p projects/website/css

# Copy with verbose output
cp -v index.html backup/

# Find files modified in last 7 days
find /home -type f -mtime -7
</code></pre><h2>File Permissions and Ownership</h2><p>Linux uses a robust permission system to control access to files and directories. Each file has three permission sets (owner, group, others) with read, write, and execute capabilities. Understanding permissions is crucial for system security and multi-user environments.</p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>chmod</td><td>Change file permissions</td><td>chmod 755 <a href="http://script.sh/">script.sh</a></td></tr><tr><td>chown</td><td>Change file owner</td><td>chown user:group file</td></tr><tr><td>chgrp</td><td>Change group ownership</td><td>chgrp developers file</td></tr><tr><td>umask</td><td>Set default permissions</td><td>umask 022</td></tr></tbody></table></figure><p>Permission values:</p><ul><li>r (read) = 4</li><li>w (write) = 2</li><li>x (execute) = 1</li></ul><pre><code class="language-ruby"># View file permissions
ls -l filename

# Make script executable for owner
chmod u+x script.sh

# Set specific permissions using octal notation
chmod 644 document.txt
chmod 755 directory/

# Change ownership recursively
chown -R www-data:www-data /var/www
</code></pre><h2>Process Management</h2><p>Processes are running instances of programs on your Linux system. Managing them effectively helps maintain system performance and troubleshoot issues. Linux provides commands to view, control, and terminate processes.</p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>ps</td><td>Show process status</td><td>ps aux</td></tr><tr><td>top</td><td>Interactive process viewer</td><td>top</td></tr><tr><td>htop</td><td>Enhanced process viewer</td><td>htop</td></tr><tr><td>kill</td><td>Terminate process</td><td>kill -9 PID</td></tr><tr><td>pkill</td><td>Kill by name</td><td>pkill firefox</td></tr><tr><td>jobs</td><td>List background jobs</td><td>jobs</td></tr><tr><td>bg</td><td>Resume in background</td><td>bg %1</td></tr><tr><td>fg</td><td>Bring to foreground</td><td>fg %1</td></tr><tr><td>nice</td><td>Set process priority</td><td>nice -n 10 command</td></tr><tr><td>renice</td><td>Change process priority</td><td>renice +5 PID</td></tr></tbody></table></figure><pre><code class="language-ruby"># Find process by name
ps aux | grep nginx

# Kill all processes matching pattern
pkill -f "python app.py"

# Run process in background
long_running_task &amp;

# View process tree
pstree -p
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Process_Management_c48bcd68e7.png" alt="Process Management" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Process_Management_c48bcd68e7.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Process_Management_c48bcd68e7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Process_Management_c48bcd68e7.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Process_Management_c48bcd68e7.png 1000w," sizes="100vw"><figcaption>Process Management</figcaption></figure><h2>Networking Commands</h2><p>Networking commands help you configure, monitor, and troubleshoot network connections. These tools are essential for server administration, debugging connectivity issues, and ensuring services are accessible.</p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>ping</td><td>Test network connectivity</td><td>ping -c 4 <a href="http://google.com/">google.com</a></td></tr><tr><td>ifconfig</td><td>Configure network interfaces</td><td>ifconfig eth0</td></tr><tr><td>ip</td><td>Show/manipulate routing</td><td>ip addr show</td></tr><tr><td>netstat</td><td>Network statistics</td><td>netstat -tulpn</td></tr><tr><td>ss</td><td>Socket statistics</td><td>ss -tulwn</td></tr><tr><td>curl</td><td>Transfer data from URLs</td><td>curl -I <a href="http://example.com/">example.com</a></td></tr><tr><td>wget</td><td>Download files</td><td>wget <a href="https://file.zip">https://file.zip</a></td></tr><tr><td>nslookup</td><td>DNS lookup</td><td>nslookup <a href="http://google.com/">google.com</a></td></tr><tr><td>dig</td><td>DNS information</td><td>dig <a href="http://example.com/">example.com</a></td></tr><tr><td>traceroute</td><td>Trace network path</td><td>traceroute <a href="http://google.com/">google.com</a></td></tr><tr><td>ssh</td><td>Secure shell connection</td><td>ssh user@hostname</td></tr></tbody></table></figure><pre><code class="language-ruby"># Check if service is listening on port
ss -tulpn | grep :80

# Download entire website
wget -r -l 3 &lt;https://example.com&gt;

# Test HTTP headers
curl -I &lt;https://api.github.com&gt;
</code></pre><h2>Package Management</h2><p>Package managers simplify software installation, updates, and removal. Different Linux distributions use different package managers, but the concepts remain similar. Understanding package management helps maintain system integrity and track installed software.</p><p><strong>Debian/Ubuntu (apt):</strong></p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th></tr></thead><tbody><tr><td>apt update</td><td>Update package list</td></tr><tr><td>apt upgrade</td><td>Upgrade all packages</td></tr><tr><td>apt install</td><td>Install package</td></tr><tr><td>apt remove</td><td>Remove package</td></tr><tr><td>apt search</td><td>Search packages</td></tr><tr><td>apt show</td><td>Show package details</td></tr></tbody></table></figure><p><strong>Red Hat/CentOS (yum/dnf):</strong></p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th></tr></thead><tbody><tr><td>yum update</td><td>Update packages</td></tr><tr><td>yum install</td><td>Install package</td></tr><tr><td>yum remove</td><td>Remove package</td></tr><tr><td>yum list installed</td><td>List installed</td></tr><tr><td>dnf groupinstall</td><td>Install package group</td></tr></tbody></table></figure><pre><code class="language-ruby"># Debian/Ubuntu examples
sudo apt update &amp;&amp; sudo apt upgrade -y
sudo apt install nginx
apt search "web server"

# Red Hat examples
sudo yum install httpd
sudo yum list installed | grep mysql

# Check installed package version
dpkg -l | grep python3
rpm -qa | grep kernel
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Package_Management_d4c972b529.png" alt="Package Management" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Package_Management_d4c972b529.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Package_Management_d4c972b529.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Package_Management_d4c972b529.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Package_Management_d4c972b529.png 1000w," sizes="100vw"><figcaption>Package Management</figcaption></figure><h2>Disk and Storage Commands</h2><p>Managing disk space, partitions, and storage devices is critical for system maintenance. These commands help you monitor usage, mount devices, and manage file systems effectively.</p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>df</td><td>Disk free space</td><td>df -h</td></tr><tr><td>du</td><td>Disk usage</td><td>du -sh /home</td></tr><tr><td>fdisk</td><td>Partition table manager</td><td>fdisk -l</td></tr><tr><td>mount</td><td>Mount file system</td><td>mount /dev/sda1 /mnt</td></tr><tr><td>umount</td><td>Unmount file system</td><td>umount /mnt</td></tr><tr><td>fsck</td><td>File system check</td><td>fsck /dev/sda1</td></tr><tr><td>dd</td><td>Convert/copy file</td><td>dd if=/dev/zero of=file</td></tr><tr><td>lsblk</td><td>List block devices</td><td>lsblk</td></tr><tr><td>blkid</td><td>Block device attributes</td><td>blkid</td></tr></tbody></table></figure><pre><code class="language-ruby"># Check disk usage in human-readable format
df -h

# Find largest files in directory
du -ah /var | sort -rh | head -10

# Create disk image
dd if=/dev/sda of=/backup/disk.img bs=4M

# Check disk I/O performance
iostat -x 1
</code></pre><h2>System Monitoring</h2><p>Proactive system monitoring helps identify issues before they become critical. These commands provide real-time and historical data about system resources, user activity, and overall system health.</p><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>uptime</td><td>System uptime</td><td>uptime</td></tr><tr><td>who</td><td>Logged in users</td><td>who -a</td></tr><tr><td>last</td><td>Last logins</td><td>last -10</td></tr><tr><td>dmesg</td><td>Kernel messages</td><td>dmesg</td></tr><tr><td>journalctl</td><td>System logs</td><td>journalctl -xe</td></tr><tr><td>vmstat</td><td>Virtual memory stats</td><td>vmstat 5</td></tr><tr><td>iostat</td><td>CPU/IO statistics</td><td>iostat -xz</td></tr><tr><td>free</td><td>Memory usage</td><td>free -h</td></tr><tr><td>watch</td><td>Run command repeatedly</td><td>watch df -h</td></tr></tbody></table></figure><pre><code class="language-ruby"># Monitor memory usage in real-time
watch -n 2 free -m

# Check systemd service logs
journalctl -u nginx.service --since "5 minutes ago"

# View last 50 kernel messages
dmesg | tail -50

# Monitor CPU temperature
watch -n 1 sensors
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/System_Monitoring_4af3debf6a.png" alt="System Monitoring" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_System_Monitoring_4af3debf6a.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_System_Monitoring_4af3debf6a.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_System_Monitoring_4af3debf6a.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_System_Monitoring_4af3debf6a.png 1000w," sizes="100vw"><figcaption>System Monitoring</figcaption></figure><h2>Bash Scripting Basics</h2><p>Shell scripting automates repetitive tasks and combines multiple commands into reusable programs. Bash is the default shell on most Linux systems and provides powerful programming constructs for system administration.</p><figure class="table"><table><thead><tr><th>Element</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>#!</td><td>Shebang interpreter</td><td>#!/bin/bash</td></tr><tr><td>$VAR</td><td>Variable reference</td><td>echo $HOME</td></tr><tr><td>$(cmd)</td><td>Command substitution</td><td>files=$(ls)</td></tr><tr><td>if/then/else</td><td>Conditional logic</td><td>if [ -f file ]; then</td></tr><tr><td>for/while</td><td>Loops</td><td>for i in {1..5}; do</td></tr><tr><td>$1,$2</td><td>Positional arguments</td><td>echo $1</td></tr><tr><td>$?</td><td>Exit status</td><td>if [ $? -eq 0 ]</td></tr></tbody></table></figure><pre><code class="language-ruby">#!/bin/bash
# Simple backup script

backup_dir="/backup/$(date +%Y%m%d)"
source_dir="/home/user/documents"

# Create backup directory
mkdir -p "$backup_dir"

# Copy and compress files
tar -czf "$backup_dir/backup.tar.gz" "$source_dir"

# Check if successful
if [ $? -eq 0 ]; then
    echo "Backup completed: $backup_dir"
    logger "Backup successful: $backup_dir"
else
    echo "Backup failed" &gt;&amp;2
    exit 1
fi
</code></pre><h2>Useful Linux Tips</h2><p>These practical tips and shortcuts improve productivity and help you work more efficiently with the Linux command line. They're gathered from years of real-world usage.</p><p><strong>Command-line shortcuts:</strong></p><ul><li>Tab: Auto-complete commands and filenames</li><li>Ctrl + C: Terminate current command</li><li>Ctrl + Z: Suspend current process</li><li>Ctrl + D: Exit current shell</li><li>Ctrl + R: Search command history</li><li>!!: Repeat last command</li><li>!$: Use last argument from previous command</li><li>Ctrl + A/E: Move to beginning/end of line</li></ul><p><strong>Redirection operators:</strong></p><pre><code class="language-ruby">command &gt; file    # Redirect stdout to file
command &gt;&gt; file   # Append stdout to file
command 2&gt; file   # Redirect stderr to file
command &amp;&gt; file   # Redirect both stdout and stderr
command1 | command2   # Pipe output to another command
</code></pre><p><strong>Quick system checks:</strong></p><pre><code class="language-ruby"># Check Linux distribution
cat /etc/os-release

# Check kernel version
uname -r

# List available shells
cat /etc/shells

# Show environment variables
env | grep PATH

# Find command location
which python3
whereis nginx
</code></pre><hr><h2><strong>Conclusion</strong></h2><p>Linux is a powerful operating system used widely in development, servers, and cloud environments. This cheatsheet brings together essential Linux commands and concepts in one place so you can quickly reference them while learning or working in the terminal. Regular practice is the best way to become comfortable with Linux and improve your command-line skills.</p><p>If you found this cheatsheet helpful, consider sharing it with your friends or colleagues who are learning Linux.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Linux</category>
            <category>devops</category>
            <category>terminal</category>
            <category>shell</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Linux_in_one_shot_thumbnail_add7bdd784.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Computer networks in one shot  - The Ultimate Cheat Sheet]]></title>
            <link>https://www.codingshuttle.com/blogs/computer-networks-in-one-shot-the-ultimate-cheat-sheet</link>
            <guid>https://www.codingshuttle.com/blogs/computer-networks-in-one-shot-the-ultimate-cheat-sheet</guid>
            <pubDate>Wed, 04 Mar 2026 15:21:48 GMT</pubDate>
            <description><![CDATA[This Computer Networks cheat sheet is designed as a quick yet complete revision guide for the most important networking concepts. It walks through the fundamentals like how devices communicate, the OSI and TCP/IP models, IP addressing, DNS, HTTP/HTTPS, routing, switching, and commonly used network protocols. The goal is to explain these ideas in a simple and practical way so you can understand how networks actually work behind the scenes. It’s a helpful one-shot resource for students preparing for interviews, exams, or anyone who wants to refresh their networking basics in one place.]]></description>
            <content:encoded><![CDATA[<p>Computer Networks in One Shot - The Ultimate Cheatsheet Cheat Sheet</p><p>A complete computer networks cheat sheet that simplifies core networking concepts including OSI layers, TCP/IP model, network topologies, IP addressing, subnetting, networking protocols, devices, and security basics. Perfect for quick revision and interview preparation.</p><h2>Introduction to Computer Networks</h2><h3>What is a Computer Network</h3><p>A computer network is a collection of interconnected devices that can communicate and share resources with each other. These devices, ranging from computers and servers to printers and smartphones, use transmission media and protocols to exchange data.</p><h3>Why Networks are Needed</h3><ul><li>Resource sharing (printers, storage, applications)</li><li>Cost reduction through hardware and software sharing</li><li>Improved communication and collaboration</li><li>Centralized data management and backup</li><li>Increased reliability through alternative paths</li></ul><h3>Types of Networks</h3><figure class="table"><table><thead><tr><th>Network Type</th><th>Coverage</th><th>Typical Use</th></tr></thead><tbody><tr><td>PAN (Personal Area Network)</td><td>Few meters</td><td>Connecting personal devices like phone, laptop, Bluetooth devices</td></tr><tr><td>LAN (Local Area Network)</td><td>Building or campus</td><td>Office networks, school computer labs, home networks</td></tr><tr><td>MAN (Metropolitan Area Network)</td><td>City-wide</td><td>Cable TV networks, city government connectivity</td></tr><tr><td>WAN (Wide Area Network)</td><td>Country or global</td><td>Internet, multinational corporate networks</td></tr></tbody></table></figure><h3>Network Topologies</h3><p><strong>Bus Topology</strong>: All devices connect to a single central cable. Simple but a break in the main cable brings down the entire network.</p><p><strong>Star Topology</strong>: All devices connect to a central hub or switch. Easy to install and manage, but central device failure affects all connected devices.</p><p><strong>Ring Topology</strong>: Each device connects to two other devices, forming a circular path. Data travels in one direction, reducing collision risk.</p><p><strong>Mesh Topology</strong>: Every device connects to every other device. Provides high redundancy and reliability but expensive to implement.</p><p><strong>Hybrid Topology</strong>: Combination of two or more different topologies. Used in larger networks to leverage benefits of multiple topologies.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Network_Topologies_4de288b08f.png" alt="Network Topologies" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Network_Topologies_4de288b08f.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Network_Topologies_4de288b08f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Network_Topologies_4de288b08f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Network_Topologies_4de288b08f.png 1000w," sizes="100vw"><figcaption>Network Topologies</figcaption></figure><h2>OSI Model</h2><p>The Open Systems Interconnection (OSI) model is a conceptual framework that standardizes networking functions into seven distinct layers.</p><h3>The Seven Layers Explained</h3><p><strong>Layer 1: Physical Layer</strong> Handles the physical connection between devices. Converts data into bits for transmission over physical media like cables or radio waves. Defines voltage levels, cable specifications, and data rates.</p><p><strong>Layer 2: Data Link Layer</strong> Provides node-to-node data transfer and handles error correction from the physical layer. Organizes bits into frames and manages MAC addresses. Switches and bridges operate at this layer.</p><p><strong>Layer 3: Network Layer</strong> Responsible for packet forwarding and routing. Determines the best path for data transmission using logical addresses (IP addresses). Routers operate at this layer.</p><p><strong>Layer 4: Transport Layer</strong> Ensures complete data transfer with error recovery and flow control. Segments and reassembles data. TCP and UDP protocols work here.</p><p><strong>Layer 5: Session Layer</strong> Manages sessions between applications. Establishes, maintains, and terminates connections. Handles authentication and reconnection after interruptions.</p><p><strong>Layer 6: Presentation Layer</strong> Translates data between application and network formats. Handles encryption, compression, and data formatting. Ensures data from sender is readable by receiver.</p><p><strong>Layer 7: Application Layer</strong> Closest to end users. Provides network services directly to applications. HTTP, FTP, SMTP protocols operate at this layer.</p><h3>OSI Layers and Functions</h3><figure class="table"><table><thead><tr><th>Layer</th><th>Name</th><th>Function</th><th>Example Devices/Protocols</th></tr></thead><tbody><tr><td>7</td><td>Application</td><td>User interface and application support</td><td>HTTP, FTP, SMTP, DNS</td></tr><tr><td>6</td><td>Presentation</td><td>Data translation, encryption, compression</td><td>SSL, TLS, JPEG, ASCII</td></tr><tr><td>5</td><td>Session</td><td>Session management and synchronization</td><td>NetBIOS, RPC, SQL</td></tr><tr><td>4</td><td>Transport</td><td>End-to-end delivery, error recovery</td><td>TCP, UDP, SPX</td></tr><tr><td>3</td><td>Network</td><td>Logical addressing, routing</td><td>IP, ICMP, ARP, Routers</td></tr><tr><td>2</td><td>Data Link</td><td>Physical addressing, error detection</td><td>Ethernet, PPP, Switches</td></tr><tr><td>1</td><td>Physical</td><td>Bit transmission, hardware specs</td><td>Cables, Hubs, Repeaters</td></tr></tbody></table></figure><h3>Mnemonic to Remember the Layers</h3><p><strong>Please Do Not Throw Sausage Pizza Away</strong> (Physical, Data Link, Network, Transport, Session, Presentation, Application)</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/OSI_Model_3080772c91.png" alt="OSI_Model" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_OSI_Model_3080772c91.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_OSI_Model_3080772c91.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_OSI_Model_3080772c91.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_OSI_Model_3080772c91.png 1000w," sizes="100vw"><figcaption>OSI Model</figcaption></figure><h2>TCP/IP Model</h2><p>The TCP/IP model is a practical, streamlined framework based on standard protocols used on the internet.</p><h3>The Four Layers</h3><p><strong>Application Layer</strong> Combines the functions of OSI's Application, Presentation, and Session layers. Handles high-level protocols, data representation, and session management. Includes HTTP, FTP, SMTP, and DNS.</p><p><strong>Transport Layer</strong> Corresponds to OSI's Transport layer. Provides reliable or unreliable delivery and error checking. Uses TCP for reliable connections and UDP for faster, connectionless communication.</p><p><strong>Internet Layer</strong> Equivalent to OSI's Network layer. Handles logical addressing and routing. The core protocol is IP, supported by ICMP and ARP.</p><p><strong>Network Access Layer</strong> Combines OSI's Data Link and Physical layers. Manages hardware addressing and physical transmission over the network medium.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/TCP_IP_Model_c103e1e067.png" alt="TCP/IP Model" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_TCP_IP_Model_c103e1e067.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_TCP_IP_Model_c103e1e067.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_TCP_IP_Model_c103e1e067.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_TCP_IP_Model_c103e1e067.png 1000w," sizes="100vw"><figcaption>TCP/IP Model</figcaption></figure><h3>Protocol Examples by Layer</h3><figure class="table"><table><thead><tr><th>Layer</th><th>Protocols</th></tr></thead><tbody><tr><td>Application</td><td>HTTP, HTTPS, FTP, SMTP, POP3, DNS, DHCP</td></tr><tr><td>Transport</td><td>TCP, UDP</td></tr><tr><td>Internet</td><td>IPv4, IPv6, ICMP</td></tr><tr><td>Network Access</td><td>Ethernet, Wi-Fi, PPP, ARP</td></tr></tbody></table></figure><h3>OSI vs TCP/IP Comparison</h3><figure class="table"><table><thead><tr><th>Aspect</th><th>OSI Model</th><th>TCP/IP Model</th></tr></thead><tbody><tr><td>Layers</td><td>7 layers</td><td>4 layers</td></tr><tr><td>Development</td><td>Theoretical standard</td><td>Practical, protocol-based</td></tr><tr><td>Approach</td><td>Layer-by-layer separation</td><td>Protocol-specific grouping</td></tr><tr><td>Usage</td><td>Reference model</td><td>Actual implementation</td></tr><tr><td>Transport</td><td>Connection-oriented and connectionless</td><td>TCP (connection-oriented), UDP (connectionless)</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr></tbody></table></figure><h2>Networking Devices</h2><h3>Device Descriptions</h3><p><strong>Hub</strong>: Basic device that connects multiple Ethernet devices. Broadcasts data to all ports regardless of destination. Operates at Physical layer.</p><p><strong>Switch</strong>: Intelligent device that forwards data only to specific destination ports using MAC addresses. Operates at Data Link layer.</p><p><strong>Router</strong>: Connects different networks and directs data packets between them using IP addresses. Operates at Network layer.</p><p><strong>Bridge</strong>: Connects two network segments and filters traffic based on MAC addresses. Reduces unnecessary traffic.</p><p><strong>Repeater</strong>: Amplifies and regenerates signals to extend network distance. Operates at Physical layer.</p><p><strong>Gateway</strong>: Translates data between different network protocols or architectures. Can operate at multiple layers.</p><p><strong>Modem</strong>: Modulates and demodulates signals for transmission over telephone or cable lines. Converts digital to analog and vice versa.</p><p><strong>Access Point</strong>: Allows wireless devices to connect to a wired network. Extends wireless coverage.</p><h3>Device Reference Table</h3><figure class="table"><table><thead><tr><th>Device</th><th>OSI Layer</th><th>Purpose</th></tr></thead><tbody><tr><td>Hub</td><td>Physical</td><td>Connects devices, broadcasts to all ports</td></tr><tr><td>Switch</td><td>Data Link</td><td>Forwards data to specific MAC addresses</td></tr><tr><td>Router</td><td>Network</td><td>Routes between networks using IP addresses</td></tr><tr><td>Bridge</td><td>Data Link</td><td>Connects and filters between network segments</td></tr><tr><td>Repeater</td><td>Physical</td><td>Extends network distance by signal amplification</td></tr><tr><td>Gateway</td><td>Multiple</td><td>Translates between different protocols</td></tr><tr><td>Modem</td><td>Physical</td><td>Converts digital/analog signals for transmission</td></tr><tr><td>Access Point</td><td>Data Link</td><td>Provides wireless connectivity to wired network</td></tr></tbody></table></figure><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Networking_Devices_b38abcaba2.png" alt="Networking Devices" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Networking_Devices_b38abcaba2.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Networking_Devices_b38abcaba2.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Networking_Devices_b38abcaba2.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Networking_Devices_b38abcaba2.png 1000w," sizes="100vw"></p><h2>IP Addressing</h2><h3>IPv4 Format</h3><p>IPv4 addresses are 32-bit numbers written as four decimal octets separated by dots. Each octet ranges from 0 to 255.</p><p>Example: 192.168.1.10</p><h3>IPv6 Basics</h3><p>IPv6 addresses are 128-bit hexadecimal numbers written as eight groups of four hexadecimal digits separated by colons. Developed to address IPv4 exhaustion.</p><p>Example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334</p><h3>Public vs Private IP Addresses</h3><figure class="table"><table><thead><tr><th>Type</th><th>Description</th><th>Example Ranges</th></tr></thead><tbody><tr><td>Public</td><td>Globally unique, routable on internet</td><td>Assigned by ISP</td></tr><tr><td>Private</td><td>Used within local networks, not routable on internet</td><td>10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16</td></tr></tbody></table></figure><h3>Static vs Dynamic IP</h3><p><strong>Static IP</strong>: Manually assigned, permanent address. Used for servers and devices needing constant access.</p><p><strong>Dynamic IP</strong>: Automatically assigned by DHCP server. Changes periodically. Common for client devices.</p><h3>Loopback Address</h3><p>127.0.0.1 (IPv4) or ::1 (IPv6) used to test network software on local machine without sending packets over network.</p><h3>Subnet Mask</h3><p>A 32-bit number that divides an IP address into network and host portions. Uses binary 1s for network bits and 0s for host bits.</p><p>Example: 255.255.255.0 indicates first 24 bits are network portion.</p><h3>CIDR Notation</h3><p>Classless Inter-Domain Routing notation specifies IP address and network prefix length.</p><p>Example: 192.168.1.0/24 indicates 24 bits for network portion, 8 bits for hosts.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Subnet_Mask_876a478b70.png" alt="Subnet Mask" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Subnet_Mask_876a478b70.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Subnet_Mask_876a478b70.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Subnet_Mask_876a478b70.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Subnet_Mask_876a478b70.png 1000w," sizes="100vw"></p><h2>Subnetting</h2><h3>Why Subnetting is Needed</h3><ul><li>Efficient IP address utilization</li><li>Improved network performance through reduced broadcast traffic</li><li>Enhanced security by isolating network segments</li><li>Simplified network management</li></ul><h3>Basic Formula</h3><p>Number of subnets = 2^n where n is number of bits borrowed from host portion Number of hosts per subnet = 2^h - 2 where h is remaining host bits</p><h3>Simple Example Calculation</h3><p>Network: 192.168.1.0/24 Requirement: Create 4 subnets</p><p>Borrow 2 bits from host portion (2^2 = 4 subnets) New subnet mask: /26 or 255.255.255.192</p><p>Resulting subnets:</p><ul><li>192.168.1.0/26 (hosts: 192.168.1.1 - 192.168.1.62)</li><li>192.168.1.64/26 (hosts: 192.168.1.65 - 192.168.1.126)</li><li>192.168.1.128/26 (hosts: 192.168.1.129 - 192.168.1.190)</li><li>192.168.1.192/26 (hosts: 192.168.1.193 - 192.168.1.254)</li></ul><h3>Host Calculation</h3><p>For /26 subnet (64 addresses total):</p><ul><li>Network address: first address</li><li>Broadcast address: last address</li><li>Usable hosts: 62 (total - 2)</li></ul><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Host_Calculation_72ea97ada5.png" alt="Host Calculation" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Host_Calculation_72ea97ada5.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Host_Calculation_72ea97ada5.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Host_Calculation_72ea97ada5.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Host_Calculation_72ea97ada5.png 1000w," sizes="100vw"></p><h2>Common Networking Protocols</h2><figure class="table"><table><thead><tr><th>Protocol</th><th>Port</th><th>Purpose</th></tr></thead><tbody><tr><td>HTTP</td><td>80</td><td>Web page transfer, unencrypted</td></tr><tr><td>HTTPS</td><td>443</td><td>Secure web page transfer with encryption</td></tr><tr><td>FTP</td><td>20, 21</td><td>File transfer between client and server</td></tr><tr><td>SSH</td><td>22</td><td>Secure remote terminal access and command execution</td></tr><tr><td>SMTP</td><td>25</td><td>Email sending and relaying between mail servers</td></tr><tr><td>POP3</td><td>110</td><td>Email retrieval from mail server to client</td></tr><tr><td>DNS</td><td>53</td><td>Domain name to IP address resolution</td></tr><tr><td>DHCP</td><td>67, 68</td><td>Automatic IP address assignment to devices</td></tr><tr><td>Telnet</td><td>23</td><td>Remote terminal access (unencrypted, insecure)</td></tr></tbody></table></figure><h2>Network Security Basics</h2><h3>Firewall</h3><p>A security system that monitors and controls incoming and outgoing network traffic based on predetermined security rules. Can be hardware-based, software-based, or both. Creates a barrier between trusted internal and untrusted external networks.</p><h3>VPN</h3><p>Virtual Private Network creates encrypted connections over public networks. Provides secure remote access to private networks, masking user location and encrypting all transmitted data.</p><h3>SSL/TLS</h3><p>Secure Socket Layer and Transport Layer Security are cryptographic protocols providing secure communication over networks. Used extensively in web browsing (HTTPS), email, and VoIP. TLS is the modern successor to SSL.</p><h3>Encryption</h3><p>Process of converting data into unreadable format using algorithms and keys. Ensures data confidentiality during transmission and storage. Common types include symmetric (same key for encryption/decryption) and asymmetric (public/private key pairs).</p><h3>Authentication</h3><p>Verification of user or device identity before granting network access. Methods include passwords, biometrics, digital certificates, and multi-factor authentication combining multiple verification methods.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Network_Security_5839b9a43a.png" alt="Network Security" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Network_Security_5839b9a43a.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Network_Security_5839b9a43a.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Network_Security_5839b9a43a.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Network_Security_5839b9a43a.png 1000w," sizes="100vw"><figcaption>Network Security</figcaption></figure><h2>Important Networking Commands</h2><figure class="table"><table><thead><tr><th>Command</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>ping</td><td>Tests connectivity to a target by sending ICMP echo requests</td><td>ping <a href="http://google.com/">google.com</a></td></tr><tr><td>tracert / traceroute</td><td>Shows the path packets take to reach destination</td><td>tracert 192.168.1.1</td></tr><tr><td>ipconfig</td><td>Displays IP configuration on Windows systems</td><td>ipconfig /all</td></tr><tr><td>ifconfig</td><td>Displays network configuration on Linux/Unix systems</td><td>ifconfig eth0</td></tr><tr><td>netstat</td><td>Shows network connections, routing tables, interface statistics</td><td>netstat -an</td></tr><tr><td>nslookup</td><td>Queries DNS to obtain domain name or IP address mapping</td><td>nslookup <a href="http://example.com/">example.com</a></td></tr></tbody></table></figure><h2>Conclusion</h2><p>This cheat sheet explains the <strong>basic networking concepts</strong> like OSI &amp; TCP/IP models, IP addressing, subnetting, common protocols, and basic security. It also includes useful command-line tools for network troubleshooting.</p><p>It’s helpful for quick learning, interview preparation, and revision of networking fundamentals.</p><p><strong>If you like it, please share it with your friends!</strong></p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Computer  networks</category>
            <category>Internet</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Computer_Networks_Thumbnail_9054a7051d.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot in One Shot – Ultimate Cheat Sheet]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-boot-in-one-shot-ultimate-cheat-sheet</link>
            <guid>https://www.codingshuttle.com/blogs/spring-boot-in-one-shot-ultimate-cheat-sheet</guid>
            <pubDate>Mon, 02 Mar 2026 14:10:28 GMT</pubDate>
            <description><![CDATA[A clear and practical revision guide covering the most important Spring Boot concepts in one place. From project setup and auto-configuration to REST APIs, JPA, security basics, and deployment — everything is explained in a simple, structured way.

Perfect for interviews, quick revision, or anyone who wants to understand how Spring Boot applications are built and run in real projects.]]></description>
            <content:encoded><![CDATA[<p>Spring Boot in One Shot — The Ultimate CheatSheet</p><p>Master Spring Boot from zero to hero with this comprehensive, no-fluff reference. Whether you're just starting out, preparing for interviews, or building a project, this cheat sheet packs&nbsp;<strong>everything you need</strong>&nbsp;— annotations, config, security, JPA, testing, deployment — with practical examples you can use immediately. No prior Spring experience required!</p><hr><h3>1. What is Spring Boot?</h3><p>Spring Boot is an extension of the Spring Framework that eliminates boilerplate configuration and setup. It provides embedded servers, auto-configuration, and production-ready features so developers can focus entirely on business logic rather than infrastructure.</p><p><strong>Key Benefits:</strong></p><ul><li>Zero XML configuration</li><li>Embedded Tomcat, Jetty, or Undertow</li><li>Auto-configures beans based on classpath</li><li>Production monitoring via Actuator</li><li>Single executable JAR deployment</li></ul><p><strong>Spring Boot vs Spring Framework:</strong></p><figure class="table"><table><thead><tr><th>Feature</th><th>Spring Framework</th><th>Spring Boot</th></tr></thead><tbody><tr><td>Configuration</td><td>Manual XML/Java</td><td>Auto-configured</td></tr><tr><td>Server</td><td>External Tomcat</td><td>Embedded</td></tr><tr><td>Setup Time</td><td>High</td><td>Very low</td></tr><tr><td>Dependencies</td><td>Manual management</td><td>Starter bundles</td></tr><tr><td>Learning Curve</td><td>Steep</td><td>Beginner friendly</td></tr></tbody></table></figure><hr><h3>2. Project Structure</h3><p>A standard Spring Boot project follows a layered package structure. Each folder represents a layer with a single responsibility, making the codebase easy to navigate and maintain.</p><pre><code class="language-plaintext">src/main/java/com/example/
├── controller/       ← HTTP request/response handling
├── service/          ← Business logic
├── repository/       ← Database access
├── model/            ← Entities and DTOs
└── Application.java  ← Main entry point

src/main/resources/
├── application.properties  ← App configuration
└── static/                 ← Static files
</code></pre><hr><h3>3. Main Application Class</h3><p><code>@SpringBootApplication</code> is a convenience annotation that combines three annotations into one. When <code>SpringApplication.run()</code> is called, it creates the ApplicationContext, triggers auto-configuration, and starts the embedded server.</p><pre><code class="language-java">@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
</code></pre><p><code>@SpringBootApplication</code> internally combines:</p><ul><li><code>@Configuration</code> — marks class as bean source</li><li><code>@EnableAutoConfiguration</code> — enables auto-config</li><li><code>@ComponentScan</code> — scans current package and sub-packages</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Spring_Boot_Application_Startup_Flow_caa0d4af01.png" alt="SpringBoot Application Startup Flow.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Spring_Boot_Application_Startup_Flow_caa0d4af01.png 104w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Spring_Boot_Application_Startup_Flow_caa0d4af01.png 333w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Spring_Boot_Application_Startup_Flow_caa0d4af01.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Spring_Boot_Application_Startup_Flow_caa0d4af01.png 667w," sizes="100vw"><figcaption>SpringBoot Application Startup Flow</figcaption></figure><hr><h3>4. Spring Starters</h3><p>Starters are pre-packaged dependency bundles for specific features. Instead of manually finding and matching compatible library versions, you add one starter and Spring Boot handles the rest.</p><figure class="table"><table><thead><tr><th>Starter</th><th>Purpose</th></tr></thead><tbody><tr><td><code>spring-boot-starter-web</code></td><td>REST APIs and web apps</td></tr><tr><td><code>spring-boot-starter-data-jpa</code></td><td>JPA and Hibernate</td></tr><tr><td><code>spring-boot-starter-security</code></td><td>Authentication and authorization</td></tr><tr><td><code>spring-boot-starter-test</code></td><td>JUnit, Mockito, MockMvc</td></tr><tr><td><code>spring-boot-starter-actuator</code></td><td>Monitoring and health checks</td></tr><tr><td><code>spring-boot-starter-validation</code></td><td>Bean validation</td></tr></tbody></table></figure><hr><h3>5. Core Spring Concepts</h3><h3>Inversion of Control (IoC)</h3><p>IoC means Spring takes control of object creation instead of you using the <code>new</code> keyword manually. The Spring IoC container creates, wires, and manages all objects (beans) throughout the application lifecycle.</p><pre><code class="language-java">// Without IoC — you manage everything
UserService service = new UserService(new UserRepository());

// With IoC — Spring manages everything
@Autowired
UserService service;
</code></pre><h3>Dependency Injection (DI)</h3><p>DI is the mechanism through which IoC is implemented. Spring injects required dependencies into a class automatically, removing tight coupling between components.</p><p><strong>Three types of DI:</strong></p><pre><code class="language-java">// 1. Constructor Injection — Recommended
@Service
public class OrderService {
    private final PaymentService paymentService;

    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
}

// 2. Setter Injection — for optional dependencies
@Service
public class NotificationService {
    private EmailService emailService;

    @Autowired
    public void setEmailService(EmailService emailService) {
        this.emailService = emailService;
    }
}

// 3. Field Injection — avoid in production
@Autowired
private UserRepository userRepository;
</code></pre><figure class="table"><table><thead><tr><th>Type</th><th>Testable</th><th>Immutable</th><th>Recommended</th></tr></thead><tbody><tr><td>Constructor</td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td>Setter</td><td>Partial</td><td>No</td><td>Optional use</td></tr><tr><td>Field</td><td>No</td><td>No</td><td>No</td></tr></tbody></table></figure><h3>Beans</h3><p>A Bean is any Java object created and managed by the Spring IoC container. You register beans using stereotype annotations or <code>@Bean</code> inside a <code>@Configuration</code> class.</p><pre><code class="language-java">// Via annotation
@Component
public class EmailValidator { }

// Via @Configuration
@Configuration
public class AppConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
</code></pre><h3>Stereotype Annotations</h3><figure class="table"><table><thead><tr><th>Annotation</th><th>Layer</th><th>Extra Behavior</th></tr></thead><tbody><tr><td><code>@Component</code></td><td>Any</td><td>Generic bean</td></tr><tr><td><code>@Service</code></td><td>Business</td><td>Semantic clarity</td></tr><tr><td><code>@Repository</code></td><td>Persistence</td><td>DB exception translation</td></tr><tr><td><code>@Controller</code></td><td>Presentation</td><td>Returns views</td></tr><tr><td><code>@RestController</code></td><td>Presentation</td><td>Returns JSON directly</td></tr></tbody></table></figure><hr><h3>6. Configuration</h3><p>Spring Boot externalizes configuration so the same JAR can run in dev, test, and production without code changes. Configuration sources follow a priority order — higher sources override lower ones.</p><p><strong>Priority order (highest to lowest):</strong></p><ol><li>Command line arguments</li><li>Java system properties</li><li>Environment variables</li><li><code>application.properties</code> or <code>application.yml</code></li><li>Default properties</li></ol><p><strong>application.properties:</strong></p><pre><code class="language-php">server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=${DB_PASSWORD}
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
logging.level.com.example=DEBUG
</code></pre><p><strong>application.yml (same config, hierarchical format):</strong></p><pre><code class="language-php">server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: ${DB_PASSWORD}
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
</code></pre><h3>Profiles</h3><p>Profiles let you define environment-specific configuration files. When a profile is active, Spring Boot loads both <code>application.properties</code> and the profile-specific file, with the profile file taking priority.</p><pre><code class="language-ruby"># Activate in application.properties
spring.profiles.active=dev

# Or at runtime
java -jar app.jar --spring.profiles.active=prod
</code></pre><p>Create separate files per environment:</p><ul><li><code>application-dev.properties</code></li><li><code>application-prod.properties</code></li><li><code>application-test.properties</code></li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Spring_Boot_Configuration_Priority_345f011775.png" alt="SpringBoot Configuration Priority" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Spring_Boot_Configuration_Priority_345f011775.png 87w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Spring_Boot_Configuration_Priority_345f011775.png 279w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Spring_Boot_Configuration_Priority_345f011775.png 419w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Spring_Boot_Configuration_Priority_345f011775.png 558w," sizes="100vw"><figcaption>Spring Boot Configuration Priority</figcaption></figure><hr><h3>7. REST API Development</h3><p>Spring Boot makes building REST APIs simple using annotation-based controllers and automatic JSON serialization via Jackson. REST follows stateless communication where each request contains all the information needed to process it.</p><p><strong>HTTP Method to Annotation mapping:</strong></p><figure class="table"><table><thead><tr><th>Annotation</th><th>HTTP Method</th><th>Use Case</th></tr></thead><tbody><tr><td><code>@GetMapping</code></td><td>GET</td><td>Fetch resource</td></tr><tr><td><code>@PostMapping</code></td><td>POST</td><td>Create resource</td></tr><tr><td><code>@PutMapping</code></td><td>PUT</td><td>Full update</td></tr><tr><td><code>@PatchMapping</code></td><td>PATCH</td><td>Partial update</td></tr><tr><td><code>@DeleteMapping</code></td><td>DELETE</td><td>Remove resource</td></tr></tbody></table></figure><p><strong>Complete CRUD Controller:</strong></p><pre><code class="language-java">@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    public List&lt;User&gt; getAll() {
        return userService.getAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity&lt;User&gt; getById(@PathVariable Long id) {
        return ResponseEntity.ok(userService.getById(id));
    }

    @PostMapping
    public ResponseEntity&lt;User&gt; create(@Valid @RequestBody UserRequest request) {
        return ResponseEntity.status(201).body(userService.create(request));
    }

    @PutMapping("/{id}")
    public ResponseEntity&lt;User&gt; update(@PathVariable Long id,
                                       @Valid @RequestBody UserRequest request) {
        return ResponseEntity.ok(userService.update(id, request));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity&lt;Void&gt; delete(@PathVariable Long id) {
        userService.delete(id);
        return ResponseEntity.noContent().build();
    }
}
</code></pre><p><strong>Request data extraction:</strong></p><pre><code class="language-java">// From URL path: /users/5
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) { }

// From query string: /users?role=admin&amp;page=0
@GetMapping
public List&lt;User&gt; getUsers(
    @RequestParam String role,
    @RequestParam(defaultValue = "0") int page) { }

// From request body (JSON → Java object)
@PostMapping
public User create(@RequestBody UserRequest request) { }
</code></pre><p><strong>HTTP Status Codes:</strong></p><figure class="table"><table><thead><tr><th>Code</th><th>Meaning</th><th>When to use</th></tr></thead><tbody><tr><td>200</td><td>OK</td><td>Successful GET, PUT</td></tr><tr><td>201</td><td>Created</td><td>Successful POST</td></tr><tr><td>204</td><td>No Content</td><td>Successful DELETE</td></tr><tr><td>400</td><td>Bad Request</td><td>Validation failed</td></tr><tr><td>401</td><td>Unauthorized</td><td>Not authenticated</td></tr><tr><td>403</td><td>Forbidden</td><td>Not authorized</td></tr><tr><td>404</td><td>Not Found</td><td>Resource missing</td></tr><tr><td>500</td><td>Server Error</td><td>Unexpected failure</td></tr></tbody></table></figure><hr><h3>8. Validation and Exception Handling</h3><p>Bean Validation API provides declarative constraints on request objects. When <code>@Valid</code> is used in a controller, Spring automatically validates the incoming data before the method executes and throws <code>MethodArgumentNotValidException</code> if it fails.</p><p><strong>Validation annotations:</strong></p><figure class="table"><table><thead><tr><th>Annotation</th><th>Purpose</th></tr></thead><tbody><tr><td><code>@NotNull</code></td><td>Field must not be null</td></tr><tr><td><code>@NotBlank</code></td><td>String must not be empty</td></tr><tr><td><code>@Email</code></td><td>Must be valid email format</td></tr><tr><td><code>@Size(min, max)</code></td><td>String length range</td></tr><tr><td><code>@Min</code> / <code>@Max</code></td><td>Numeric range</td></tr><tr><td><code>@Pattern(regexp)</code></td><td>Must match regex</td></tr></tbody></table></figure><p><strong>DTO with validation:</strong></p><pre><code class="language-java">public class UserRequest {

    @NotBlank(message = "Name is required")
    @Size(min = 2, max = 50)
    private String name;

    @NotBlank
    @Email(message = "Invalid email format")
    private String email;

    @Min(value = 18, message = "Must be at least 18")
    private Integer age;
}
</code></pre><p><strong>Global Exception Handler:</strong></p><p><code>@RestControllerAdvice</code> centralizes exception handling across all controllers. Without it, Spring returns ugly stack traces. With it, every error returns a clean, consistent JSON response.</p><pre><code class="language-java">@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity&lt;ErrorResponse&gt; handleNotFound(ResourceNotFoundException ex) {
        return ResponseEntity.status(404)
                .body(new ErrorResponse(404, ex.getMessage()));
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity&lt;Map&lt;String, String&gt;&gt; handleValidation(
            MethodArgumentNotValidException ex) {
        Map&lt;String, String&gt; errors = new HashMap&lt;&gt;();
        ex.getBindingResult().getFieldErrors()
          .forEach(e -&gt; errors.put(e.getField(), e.getDefaultMessage()));
        return ResponseEntity.badRequest().body(errors);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity&lt;ErrorResponse&gt; handleGeneric(Exception ex) {
        return ResponseEntity.status(500)
                .body(new ErrorResponse(500, "Unexpected error occurred"));
    }
}
</code></pre><hr><h3>9. Database Integration — Spring Data JPA</h3><p>Spring Data JPA sits on top of JPA (specification) and Hibernate (implementation) to eliminate manual SQL and ResultSet handling. You define an interface, and Spring generates the full implementation at runtime.</p><h3>Entity Mapping</h3><pre><code class="language-java">@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(unique = true, nullable = false)
    private String email;

    @Column(name = "created_at")
    private LocalDateTime createdAt;
}
</code></pre><p><strong>Primary Key Generation Strategies:</strong></p><figure class="table"><table><thead><tr><th>Strategy</th><th>Description</th><th>Best For</th></tr></thead><tbody><tr><td><code>IDENTITY</code></td><td>DB auto-increment</td><td>MySQL, PostgreSQL</td></tr><tr><td><code>SEQUENCE</code></td><td>DB sequence object</td><td>Oracle, PostgreSQL</td></tr><tr><td><code>AUTO</code></td><td>JPA picks strategy</td><td>Quick prototyping</td></tr><tr><td><code>TABLE</code></td><td>Separate ID table</td><td>Rarely used</td></tr></tbody></table></figure><h3>Repository Layer</h3><pre><code class="language-java">@Repository
public interface UserRepository extends JpaRepository&lt;User, Long&gt; {

    // Derived query — Spring generates SQL from method name
    Optional&lt;User&gt; findByEmail(String email);
    List&lt;User&gt; findByNameContaining(String keyword);
    List&lt;User&gt; findByAgeGreaterThanEqual(int age);

    // Custom JPQL query
    @Query("SELECT u FROM User u WHERE u.age &gt; :age ORDER BY u.name ASC")
    List&lt;User&gt; findUsersOlderThan(@Param("age") int age);

    // Native SQL query
    @Query(value = "SELECT * FROM users WHERE email LIKE %:domain%",
           nativeQuery = true)
    List&lt;User&gt; findByEmailDomain(@Param("domain") String domain);

    // Pagination
    Page&lt;User&gt; findByDepartment(String department, Pageable pageable);
}
</code></pre><p><strong>Pagination and Sorting:</strong></p><pre><code class="language-java">// Page 0, 10 items per page, sorted by name ascending
Pageable pageable = PageRequest.of(0, 10, Sort.by("name").ascending());
Page&lt;User&gt; page = userRepository.findAll(pageable);

page.getContent();       // list of users
page.getTotalPages();    // total pages
page.getTotalElements(); // total count
</code></pre><h3>Entity Relationships</h3><p><strong>One-to-One:</strong></p><pre><code class="language-java">@Entity
public class User {
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "profile_id")
    private Profile profile;
}
</code></pre><p><strong>One-to-Many / Many-to-One:</strong></p><pre><code class="language-java">@Entity
public class User {
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List&lt;Order&gt; orders = new ArrayList&lt;&gt;();
}

@Entity
public class Order {
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}
</code></pre><p><strong>Many-to-Many:</strong></p><pre><code class="language-java">@Entity
public class Student {
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private Set&lt;Course&gt; courses = new HashSet&lt;&gt;();
}
</code></pre><p><strong>Fetch Types:</strong></p><figure class="table"><table><thead><tr><th>Type</th><th>Behavior</th><th>Default for</th></tr></thead><tbody><tr><td><code>EAGER</code></td><td>Loads related data immediately</td><td><code>@OneToOne</code>, <code>@ManyToOne</code></td></tr><tr><td><code>LAZY</code></td><td>Loads related data only when accessed</td><td><code>@OneToMany</code>, <code>@ManyToMany</code></td></tr></tbody></table></figure><p>Prefer <code>LAZY</code> for collections to avoid loading unnecessary data.</p><p><strong>Avoid infinite recursion in bidirectional relationships:</strong></p><pre><code class="language-java">@OneToMany(mappedBy = "user")
@JsonManagedReference
private List&lt;Order&gt; orders;

@ManyToOne
@JsonBackReference
private User user;
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/JPA_Entity_Relationship_Mapping_72af2d1953.png" alt="JPA Entity Relationship Mapping" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_JPA_Entity_Relationship_Mapping_72af2d1953.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_JPA_Entity_Relationship_Mapping_72af2d1953.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_JPA_Entity_Relationship_Mapping_72af2d1953.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_JPA_Entity_Relationship_Mapping_72af2d1953.png 1000w," sizes="100vw"><figcaption>JPA Entity Relationship Mapping</figcaption></figure><hr><h3>10. Transaction Management</h3><p>Transactions ensure that a group of database operations either all succeed or all fail together, maintaining data integrity. Spring Boot provides declarative transaction management through the <code>@Transactional</code> annotation.</p><pre><code class="language-java">@Service
@Transactional
public class OrderService {

    @Transactional(readOnly = true)   // Optimizes read-only operations
    public Order getOrder(Long id) {
        return orderRepository.findById(id).orElseThrow();
    }

    @Transactional(rollbackFor = Exception.class)
    public Order createOrder(OrderRequest request) {
        Order order = orderRepository.save(buildOrder(request));
        inventoryService.deductStock(request.getItems());
        return order;
    }
}
</code></pre><p><strong>Propagation Types:</strong></p><figure class="table"><table><thead><tr><th>Propagation</th><th>Behavior</th></tr></thead><tbody><tr><td><code>REQUIRED</code></td><td>Join existing or create new (default)</td></tr><tr><td><code>REQUIRES_NEW</code></td><td>Always creates new, suspends existing</td></tr><tr><td><code>NESTED</code></td><td>Runs in nested transaction</td></tr><tr><td><code>MANDATORY</code></td><td>Must have existing transaction or throws</td></tr><tr><td><code>NEVER</code></td><td>Must not have transaction or throws</td></tr><tr><td><code>SUPPORTS</code></td><td>Runs in transaction if one exists</td></tr><tr><td><code>NOT_SUPPORTED</code></td><td>Suspends existing, runs non-transactionally</td></tr></tbody></table></figure><p><strong>Isolation Levels:</strong></p><figure class="table"><table><thead><tr><th>Level</th><th>Dirty Read</th><th>Non-Repeatable Read</th><th>Phantom Read</th></tr></thead><tbody><tr><td><code>READ_UNCOMMITTED</code></td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td><code>READ_COMMITTED</code></td><td>No</td><td>Yes</td><td>Yes</td></tr><tr><td><code>REPEATABLE_READ</code></td><td>No</td><td>No</td><td>Yes</td></tr><tr><td><code>SERIALIZABLE</code></td><td>No</td><td>No</td><td>No</td></tr></tbody></table></figure><hr><h3>11. Async Processing</h3><p><code>@Async</code> allows methods to run in a separate thread so the caller doesn't wait for completion. It is useful for sending emails, notifications, or any long-running task that doesn't need to block the main request.</p><pre><code class="language-java">// Enable async in config
@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        return executor;
    }
}

// Use in service
@Service
public class EmailService {

    @Async("taskExecutor")
    public CompletableFuture&lt;String&gt; sendEmail(String to, String content) {
        // runs in separate thread
        return CompletableFuture.completedFuture("Sent");
    }
}
</code></pre><hr><h3>12. Spring Security</h3><p>Spring Security intercepts every incoming request through a filter chain before it reaches your controllers. It handles authentication (who are you?) and authorization (what can you do?) in a structured, extensible way.</p><h3>Security Filter Chain</h3><pre><code class="language-java">@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -&gt; csrf.disable())
            .sessionManagement(s -&gt;
                s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -&gt; auth
                .requestMatchers("/api/auth/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .authenticationProvider(authenticationProvider())
            .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder());
        return provider;
    }
}
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Spring_Security_Filter_Chain_Flow_7611a3dc18.png" alt="Spring Security FilterChain Flow" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Spring_Security_Filter_Chain_Flow_7611a3dc18.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Spring_Security_Filter_Chain_Flow_7611a3dc18.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Spring_Security_Filter_Chain_Flow_7611a3dc18.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Spring_Security_Filter_Chain_Flow_7611a3dc18.png 1000w," sizes="100vw"><figcaption>Spring Security FilterChain Flow</figcaption></figure><hr><h3>13. JWT Authentication</h3><p>JWT (JSON Web Token) is a stateless authentication mechanism where the server issues a signed token after login. The client stores the token and sends it with every request — no session storage needed on the server.</p><p><strong>JWT Structure:</strong></p><pre><code class="language-plaintext">eyJhbGciOiJIUzI1NiJ9  ← Header (algorithm)
.eyJzdWIiOiJqb2huIn0  ← Payload (user data, expiry)
.SflKxwRJSMeKKF2QT4f  ← Signature (tamper-proof)
</code></pre><p>Never store passwords or secrets in the payload — it is Base64 encoded, not encrypted.</p><pre><code class="language-java">@Service
public class JwtService {

    @Value("${jwt.secret}")
    private String secret;

    private Key getSigningKey() {
        return Keys.hmacShaKeyFor(secret.getBytes());
    }

    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 86400000))
                .signWith(getSigningKey(), SignatureAlgorithm.HS256)
                .compact();
    }

    public String extractUsername(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSigningKey()).build()
                .parseClaimsJws(token).getBody().getSubject();
    }

    public boolean isTokenValid(String token, String username) {
        return username.equals(extractUsername(token)) &amp;&amp; !isExpired(token);
    }
}
</code></pre><p><strong>JWT Filter:</strong></p><pre><code class="language-java">@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtService jwtService;
    private final UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain)
                                    throws ServletException, IOException {

        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            chain.doFilter(request, response);
            return;
        }

        String token = authHeader.substring(7);
        String username = jwtService.extractUsername(token);

        if (username != null &amp;&amp;
            SecurityContextHolder.getContext().getAuthentication() == null) {

            UserDetails userDetails = userDetailsService.loadUserByUsername(username);

            if (jwtService.isTokenValid(token, userDetails.getUsername())) {
                UsernamePasswordAuthenticationToken authToken =
                    new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                authToken.setDetails(
                    new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }
        chain.doFilter(request, response);
    }
}
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/JWT_Token_Generation_and_Validation_Flow_17421fd812.png" alt="JWT Token Generation and Validation Flow" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_JWT_Token_Generation_and_Validation_Flow_17421fd812.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_JWT_Token_Generation_and_Validation_Flow_17421fd812.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_JWT_Token_Generation_and_Validation_Flow_17421fd812.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_JWT_Token_Generation_and_Validation_Flow_17421fd812.png 1000w," sizes="100vw"><figcaption>JWT Token Generation and Validation Flow</figcaption></figure><hr><h3>14. CORS Configuration</h3><p>CORS is a browser security restriction that blocks frontend apps on a different origin from calling your backend. The server must explicitly tell the browser which origins, methods, and headers are allowed.</p><pre><code class="language-java">@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(List.of("&lt;http://localhost:3000&gt;"));
    config.setAllowedMethods(List.of("GET","POST","PUT","DELETE","OPTIONS"));
    config.setAllowedHeaders(List.of("*"));
    config.setAllowCredentials(true);

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return source;
}

// Wire it in SecurityFilterChain
http.cors(cors -&gt; cors.configurationSource(corsConfigurationSource()))
</code></pre><hr><h3>15. Logging with @Slf4j</h3><p>Spring Boot uses SLF4J with Logback by default. The <code>@Slf4j</code> annotation from Lombok auto-generates a logger instance so you can start logging immediately without boilerplate.</p><p><strong>Log Levels (lowest to highest priority):</strong></p><figure class="table"><table><thead><tr><th>Level</th><th>Use For</th></tr></thead><tbody><tr><td><code>TRACE</code></td><td>Extremely detailed diagnostic info</td></tr><tr><td><code>DEBUG</code></td><td>Variable values, method flow</td></tr><tr><td><code>INFO</code></td><td>Business events, app startup</td></tr><tr><td><code>WARN</code></td><td>Recoverable issues, deprecated usage</td></tr><tr><td><code>ERROR</code></td><td>Failures, exceptions</td></tr></tbody></table></figure><pre><code class="language-java">@Slf4j
@Service
public class PaymentService {

    public PaymentResult process(PaymentRequest request) {
        log.info("Processing payment for order: {}", request.getOrderId());
        log.debug("Payment amount: {}", request.getAmount());

        try {
            PaymentResult result = gateway.charge(request);
            log.info("Payment successful, transaction: {}", result.getTransactionId());
            return result;
        } catch (PaymentGatewayException e) {
            log.error("Payment failed for order {}: {}", request.getOrderId(), e.getMessage(), e);
            throw e;
        }
    }
}
</code></pre><p><strong>Configuration:</strong></p><pre><code class="language-php">logging.level.root=INFO
logging.level.com.example=DEBUG
logging.level.org.hibernate.SQL=DEBUG
logging.file.name=logs/application.log
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</code></pre><p><strong>Best practices:</strong></p><ul><li>Always use parameterized logging <code>log.info("User: {}", name)</code> not string concatenation</li><li>Never log passwords, tokens, or card numbers</li><li>Always include the exception object in <code>log.error()</code> for stack trace</li><li>Use <code>DEBUG</code> and <code>TRACE</code> only — never <code>INFO</code> — for internal flow details</li></ul><hr><h3>16. Testing</h3><p>Spring Boot provides excellent testing support out of the box. Following the testing pyramid — many unit tests, some integration tests, few end-to-end tests — gives you fast feedback with reliable coverage.</p><h3>Unit Testing with Mockito</h3><p>Unit tests verify a single class in isolation. Mock all dependencies so the test only exercises the class under test.</p><pre><code class="language-java">@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @Mock
    private PasswordEncoder passwordEncoder;

    @InjectMocks
    private UserService userService;

    @Test
    void shouldCreateUserSuccessfully() {
        // Arrange
        UserRequest request = new UserRequest("john", "pass", "john@example.com");
        User saved = new User(1L, "john", "encodedPass", "john@example.com");

        when(passwordEncoder.encode("pass")).thenReturn("encodedPass");
        when(userRepository.save(any(User.class))).thenReturn(saved);

        // Act
        User result = userService.createUser(request);

        // Assert
        assertThat(result.getId()).isEqualTo(1L);
        verify(userRepository, times(1)).save(any(User.class));
    }

    @Test
    void shouldThrowWhenUserNotFound() {
        when(userRepository.findById(99L)).thenReturn(Optional.empty());

        assertThatThrownBy(() -&gt; userService.getById(99L))
            .isInstanceOf(ResourceNotFoundException.class);
    }
}
</code></pre><h3>Controller Testing with MockMvc</h3><pre><code class="language-java">@WebMvcTest(UserController.class)
class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    void shouldReturnUser() throws Exception {
        User user = new User(1L, "john", "john@example.com");
        when(userService.getById(1L)).thenReturn(user);

        mockMvc.perform(get("/api/users/1"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.name").value("john"));
    }
}
</code></pre><h3>Repository Testing with @DataJpaTest</h3><pre><code class="language-java">@DataJpaTest
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private TestEntityManager entityManager;

    @Test
    void shouldFindByEmail() {
        entityManager.persist(new User(null, "john", "john@example.com"));
        entityManager.flush();

        Optional&lt;User&gt; found = userRepository.findByEmail("john@example.com");
        assertThat(found).isPresent();
    }
}
</code></pre><p><strong>Testing annotations summary:</strong></p><figure class="table"><table><thead><tr><th>Annotation</th><th>Loads</th><th>Use For</th></tr></thead><tbody><tr><td><code>@SpringBootTest</code></td><td>Full context</td><td>Integration tests</td></tr><tr><td><code>@WebMvcTest</code></td><td>Web layer only</td><td>Controller tests</td></tr><tr><td><code>@DataJpaTest</code></td><td>JPA layer only</td><td>Repository tests</td></tr><tr><td><code>@ExtendWith(MockitoExtension.class)</code></td><td>Nothing</td><td>Pure unit tests</td></tr></tbody></table></figure><hr><h3>17. Spring Boot Actuator</h3><p>Actuator exposes production-ready endpoints for health checks, metrics, and application info. It is essential for monitoring applications in production environments and integrates easily with tools like Prometheus and Grafana.</p><pre><code class="language-php">management.endpoints.web.exposure.include=health,info,metrics,env,loggers
management.endpoint.health.show-details=always
info.app.name=My Application
info.app.version=1.0.0
</code></pre><p><strong>Common Endpoints:</strong></p><figure class="table"><table><thead><tr><th>Endpoint</th><th>Description</th></tr></thead><tbody><tr><td><code>/actuator/health</code></td><td>App and dependency health status</td></tr><tr><td><code>/actuator/info</code></td><td>App version and metadata</td></tr><tr><td><code>/actuator/metrics</code></td><td>JVM, CPU, request metrics</td></tr><tr><td><code>/actuator/env</code></td><td>All environment properties</td></tr><tr><td><code>/actuator/loggers</code></td><td>View and change log levels at runtime</td></tr><tr><td><code>/actuator/beans</code></td><td>All registered Spring beans</td></tr><tr><td><code>/actuator/mappings</code></td><td>All request mapping paths</td></tr><tr><td><code>/actuator/threaddump</code></td><td>Current thread states</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Spring_Boot_Actuator_Endpoints_52b9db9cd4.png" alt="Spring Boot Actuator Endpoints " srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Spring_Boot_Actuator_Endpoints_52b9db9cd4.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Spring_Boot_Actuator_Endpoints_52b9db9cd4.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Spring_Boot_Actuator_Endpoints_52b9db9cd4.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Spring_Boot_Actuator_Endpoints_52b9db9cd4.png 1000w," sizes="100vw"><figcaption>Spring Boot Actuator Endpoints&nbsp;</figcaption></figure><hr><h3>18. <strong>Spring Boot DevTools</strong></h3><p>Spring Boot DevTools enhances the development experience by providing automatic restarts, live reload, and development-time optimizations. It should&nbsp;<strong>never</strong>&nbsp;be used in production — it's strictly a development dependency.</p><p>xml</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
    &lt;scope&gt;runtime&lt;/scope&gt;  &lt;!-- Critical: excluded in production --&gt;
    &lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;
</code></pre><h3><strong>Key Features</strong></h3><figure class="table"><table><thead><tr><th><strong>Feature</strong></th><th><strong>What It Does</strong></th><th><strong>Developer Benefit</strong></th></tr></thead><tbody><tr><td><strong>Automatic Restart</strong></td><td>Restarts app when classpath files change</td><td>Instant feedback after code changes</td></tr><tr><td><strong>LiveReload</strong></td><td>Triggers browser refresh automatically</td><td>See UI changes immediately</td></tr><tr><td><strong>Cache Disabling</strong></td><td>Turns off template/thymeleaf caching</td><td>Templates update without restart</td></tr><tr><td><strong>Property Defaults</strong></td><td>Sets dev-friendly defaults</td><td>No manual config needed</td></tr><tr><td><strong>Remote Debugging</strong></td><td>Optional remote update support</td><td>Debug deployed apps</td></tr></tbody></table></figure><hr><h3>19. Caching</h3><p>Caching stores the result of expensive operations (database queries, API calls, computations) so repeated requests return instantly without re-executing the underlying logic. Spring Boot integrates with multiple cache providers through a unified abstraction layer.</p><p><strong>Enable caching in your main config:</strong></p><pre><code class="language-java">@Configuration
@EnableCaching
public class CacheConfig {
    // Spring Boot auto-configures a ConcurrentMapCache by default
    // For production, swap in Redis or Caffeine (see below)
}
</code></pre><p><strong>Core caching annotations:</strong></p><figure class="table"><table><thead><tr><th>Annotation</th><th>Behavior</th></tr></thead><tbody><tr><td><code>@Cacheable</code></td><td>Returns cached result if exists, otherwise executes and caches</td></tr><tr><td><code>@CachePut</code></td><td>Always executes and updates the cache</td></tr><tr><td><code>@CacheEvict</code></td><td>Removes entry (or all entries) from cache</td></tr><tr><td><code>@Caching</code></td><td>Groups multiple cache annotations on one method</td></tr></tbody></table></figure><p><strong>Practical service example:</strong></p><pre><code class="language-java">@Service
public class ProductService {

    // Cache result — skip DB call if key already exists
    @Cacheable(value = "products", key = "#id")
    public Product getById(Long id) {
        return productRepository.findById(id).orElseThrow();
    }

    // Always update cache after save
    @CachePut(value = "products", key = "#result.id")
    public Product update(Long id, ProductRequest request) {
        return productRepository.save(buildProduct(id, request));
    }

    // Remove single entry on delete
    @CacheEvict(value = "products", key = "#id")
    public void delete(Long id) {
        productRepository.deleteById(id);
    }

    // Clear entire cache — useful after bulk operations
    @CacheEvict(value = "products", allEntries = true)
    public void clearAll() { }
}
</code></pre><p><strong>Cache providers:</strong></p><figure class="table"><table><thead><tr><th>Provider</th><th>Best For</th><th>Dependency</th></tr></thead><tbody><tr><td><code>ConcurrentHashMap</code></td><td>Dev/testing only</td><td>Built-in (default)</td></tr><tr><td>Caffeine</td><td>Single-instance apps, high performance</td><td><code>spring-boot-starter-cache</code> + <code>caffeine</code></td></tr><tr><td>Redis</td><td>Distributed apps, multiple instances</td><td><code>spring-boot-starter-data-redis</code></td></tr><tr><td>EhCache</td><td>JVM-local, rich config</td><td><code>ehcache</code></td></tr></tbody></table></figure><p><strong>Redis setup :</strong></p><pre><code class="language-php">spring.cache.type=redis
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.cache.redis.time-to-live=600000
</code></pre><p><strong>Conditional caching:</strong></p><pre><code class="language-java">// Only cache if result is not null
@Cacheable(value = "users", key = "#email", unless = "#result == null")
public User findByEmail(String email) { ... }

// Only cache for admin users
@Cacheable(value = "reports", condition = "#role == 'ADMIN'")
public Report generateReport(String role) { ... }
</code></pre><p><strong>Best practices:</strong></p><ul><li>Always set a TTL (time-to-live) — unbounded caches grow until OutOfMemoryError</li><li>Use Redis in any multi-instance deployment — in-memory caches are per-JVM and go out of sync</li><li>Cache at the <strong>service layer</strong>, never the controller or repository layer</li><li>Keep cached objects serializable — required for Redis and most distributed providers</li><li>Use <code>@CacheEvict</code> on every write operation that modifies cached data, or you'll serve stale results</li></ul><hr><h3>20. API Documentation with Swagger / OpenAPI</h3><p>Springdoc OpenAPI auto-generates interactive API documentation from your existing controller annotations. It requires zero extra configuration to get started.</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springdoc&lt;/groupId&gt;
    &lt;artifactId&gt;springdoc-openapi-starter-webmvc-ui&lt;/artifactId&gt;
    &lt;version&gt;2.3.0&lt;/version&gt;
&lt;/dependency&gt;
</code></pre><p>After adding the dependency:</p><ul><li>Swagger UI: <code>http://localhost:8080/swagger-ui.html</code></li><li>OpenAPI JSON: <code>http://localhost:8080/v3/api-docs</code></li></ul><p>Allow these paths in your security config:</p><pre><code class="language-java">.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
</code></pre><hr><h3>21. Build and Deployment</h3><p>Spring Boot packages the entire application — including the embedded server — into a single executable JAR. This makes deployment simple and consistent across all environments.</p><p><strong>Build commands:</strong></p><pre><code class="language-ruby"># Maven
mvn clean package
mvn clean package -DskipTests

# Gradle
gradle clean build
gradle clean build -x test
</code></pre><p><strong>Run the JAR:</strong></p><pre><code class="language-ruby">java -jar target/app.jar
java -jar target/app.jar --spring.profiles.active=prod
java -jar target/app.jar --server.port=9090
java -Xmx512m -Xms256m -jar target/app.jar
</code></pre><p><strong>Dockerfile:</strong></p><pre><code class="language-php">FROM openjdk:17-jdk-slim
COPY target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
</code></pre><pre><code class="language-ruby">docker build -t myapp .
docker run -p 8080:8080 -e DB_PASSWORD=secret myapp
</code></pre><hr><h3>Quick Reference — Most Used Annotations</h3><figure class="table"><table><thead><tr><th>Annotation</th><th>Purpose</th></tr></thead><tbody><tr><td><code>@SpringBootApplication</code></td><td>Bootstrap the application</td></tr><tr><td><code>@RestController</code></td><td>REST controller, returns JSON</td></tr><tr><td><code>@RequestMapping</code></td><td>Base URL mapping</td></tr><tr><td><code>@GetMapping</code> / <code>@PostMapping</code> etc.</td><td>HTTP method mapping</td></tr><tr><td><code>@PathVariable</code></td><td>Extract from URL path</td></tr><tr><td><code>@RequestParam</code></td><td>Extract from query string</td></tr><tr><td><code>@RequestBody</code></td><td>Bind JSON body to object</td></tr><tr><td><code>@Valid</code></td><td>Trigger bean validation</td></tr><tr><td><code>@Service</code></td><td>Business logic bean</td></tr><tr><td><code>@Repository</code></td><td>Data access bean</td></tr><tr><td><code>@Component</code></td><td>Generic bean</td></tr><tr><td><code>@Autowired</code></td><td>Inject dependency</td></tr><tr><td><code>@Value</code></td><td>Inject config property</td></tr><tr><td><code>@Entity</code></td><td>JPA entity (maps to table)</td></tr><tr><td><code>@Transactional</code></td><td>Transaction boundary</td></tr><tr><td><code>@Async</code></td><td>Run in separate thread</td></tr><tr><td><code>@Slf4j</code></td><td>Auto-generate logger</td></tr><tr><td><code>@RestControllerAdvice</code></td><td>Global exception handler</td></tr><tr><td><code>@ExceptionHandler</code></td><td>Handle specific exception</td></tr><tr><td><code>@Configuration</code></td><td>Bean definition class</td></tr><tr><td><code>@Bean</code></td><td>Register method return as bean</td></tr><tr><td><code>@Profile</code></td><td>Activate in specific profile</td></tr><tr><td><code>@DataJpaTest</code></td><td>Slice test for JPA layer</td></tr><tr><td><code>@WebMvcTest</code></td><td>Slice test for web layer</td></tr><tr><td><code>@MockBean</code></td><td>Spring-aware mock in tests</td></tr></tbody></table></figure><hr><h2>Conclusion</h2><p>This Spring Boot cheat sheet covers everything from core concepts to production deployment in a concise, practical format. Master these fundamentals and you'll be ready to build production-ready applications with confidence.&nbsp;<strong>If you found this helpful, share it with your friends and colleagues</strong>&nbsp;— good knowledge grows when shared!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Spring Boot</category>
            <category>REST API`s</category>
            <category>Spring Security</category>
            <category>Spring Data JPA</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Spring_Boot_In_One_Shot_Thumbnail_f540ce99bc.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Spring Cloud in One Shot — The Ultimate Cheatsheet]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-cloud-explained-from-zero-to-production-microservices-cheat-sheet</link>
            <guid>https://www.codingshuttle.com/blogs/spring-cloud-explained-from-zero-to-production-microservices-cheat-sheet</guid>
            <pubDate>Mon, 02 Mar 2026 14:05:57 GMT</pubDate>
            <description><![CDATA[A simple, practical guide to understanding how Spring Cloud helps build real microservices for production. It covers the key pieces like service discovery, API Gateway, configuration management, load balancing, and fault tolerance — all explained in a clear and straightforward way.

Perfect for developers who want to move from basic Spring Boot to building scalable, production-ready microservices.]]></description>
            <content:encoded><![CDATA[<p>Spring Cloud in One Shot — The Ultimate Cheatsheet</p><p>A practical reference for Java backend developers building microservices with Spring Cloud, covering essential concepts such as service discovery, API gateways, centralized configuration, client-side load balancing, resilience patterns, event-driven communication, distributed tracing, and production-ready monitoring and observability.</p><hr><h2>1. Microservices Fundamentals</h2><h3>Monolith vs Microservices</h3><p>A monolith packages all application features — UI, business logic, data access — into a single deployable unit. Microservices split that unit into independently deployable services, each owning a single business capability.</p><figure class="table"><table><thead><tr><th>Aspect</th><th>Monolith</th><th>Microservices</th></tr></thead><tbody><tr><td>Deployment</td><td>Single artifact</td><td>Independent per service</td></tr><tr><td>Scaling</td><td>Scale entire app</td><td>Scale individual services</td></tr><tr><td>Technology</td><td>Single stack</td><td>Polyglot allowed</td></tr><tr><td>Failure impact</td><td>Entire app affected</td><td>Isolated to service</td></tr><tr><td>Team structure</td><td>One team</td><td>Autonomous teams</td></tr><tr><td>Development speed</td><td>Fast initially</td><td>Faster at scale</td></tr></tbody></table></figure><h3>Microservices Architecture Principles</h3><ul><li><strong>Single Responsibility</strong> — each service owns exactly one business domain</li><li><strong>Loose Coupling</strong> — services communicate over well-defined APIs; no shared databases</li><li><strong>High Cohesion</strong> — related logic lives together inside the same service</li><li><strong>Decentralized Data</strong> — each service manages its own datastore</li><li><strong>Design for Failure</strong> — assume any downstream call can fail; handle gracefully</li><li><strong>Automate Everything</strong> — CI/CD pipelines, containerization, and infrastructure as code</li></ul><h3>Challenges in Distributed Systems</h3><p>Distributed systems introduce problems that simply do not exist in a monolith:</p><ul><li>Network latency and partial failures</li><li>Data consistency across service boundaries</li><li>Service discovery — how does Service A find Service B?</li><li>Distributed tracing — how do you follow a request across 10 services?</li><li>Security — each service must authenticate callers</li><li>Operational complexity — many moving parts to monitor and deploy</li></ul><h3>Service-to-Service Communication</h3><p><strong>Synchronous communication</strong> — the caller waits for a response.</p><ul><li>HTTP/REST using <code>RestTemplate</code> or <code>WebClient</code></li><li>gRPC for high-performance binary protocol</li><li>OpenFeign for declarative HTTP clients</li></ul><p><strong>Asynchronous communication</strong> — the caller publishes an event and moves on.</p><ul><li>Apache Kafka for high-throughput event streaming</li><li>RabbitMQ for message queuing with routing</li><li>Event sourcing patterns</li></ul><p><strong>When to choose which:</strong></p><figure class="table"><table><thead><tr><th>Use Synchronous When</th><th>Use Asynchronous When</th></tr></thead><tbody><tr><td>Immediate response is required</td><td>Loose coupling is priority</td></tr><tr><td>Simple request-response</td><td>High throughput needed</td></tr><tr><td>Real-time validation</td><td>Services can tolerate delay</td></tr><tr><td>UI is waiting for result</td><td>Long-running processing</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Microservices_Architecture_Overview_dd81bb2687.webp" alt="Microservices Architecture Overview" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Microservices_Architecture_Overview_dd81bb2687.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Microservices_Architecture_Overview_dd81bb2687.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Microservices_Architecture_Overview_dd81bb2687.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Microservices_Architecture_Overview_dd81bb2687.webp 1000w," sizes="100vw"><figcaption>Microservices Architecture Overview</figcaption></figure><hr><h2>2. Introduction to Spring Cloud</h2><h3>What is Spring Cloud</h3><p>Spring Cloud is a collection of tools and frameworks built on top of Spring Boot that solves the common infrastructure problems in distributed systems. It is not a single library but an ecosystem of coordinated projects.</p><h3>Why Spring Cloud</h3><p>Without Spring Cloud, a team building microservices would need to integrate Eureka, Zuul, Ribbon, Hystrix, and dozens of other libraries manually, write glue code, and maintain compatibility. Spring Cloud provides opinionated, pre-integrated solutions for all of these concerns with sensible defaults.</p><h3>Spring Cloud Ecosystem</h3><figure class="table"><table><thead><tr><th>Module</th><th>Purpose</th></tr></thead><tbody><tr><td>Spring Cloud Netflix</td><td>Eureka, Ribbon, Hystrix (largely in maintenance mode)</td></tr><tr><td>Spring Cloud Gateway</td><td>API routing and filtering</td></tr><tr><td>Spring Cloud Config</td><td>Centralized configuration server</td></tr><tr><td>Spring Cloud LoadBalancer</td><td>Client-side load balancing</td></tr><tr><td>Spring Cloud OpenFeign</td><td>Declarative HTTP clients</td></tr><tr><td>Spring Cloud Stream</td><td>Event-driven messaging abstraction</td></tr><tr><td>Spring Cloud Sleuth / Micrometer</td><td>Distributed tracing</td></tr><tr><td>Spring Cloud Bus</td><td>Configuration broadcast via messaging</td></tr><tr><td>Spring Cloud Contract</td><td>Consumer-driven contract testing</td></tr><tr><td>Spring Cloud Kubernetes</td><td>Native Kubernetes integration</td></tr><tr><td>Spring Cloud Vault</td><td>Secrets management with HashiCorp Vault</td></tr></tbody></table></figure><h3>Spring Boot and Spring Cloud Relationship</h3><p>Spring Boot provides the application runtime, auto-configuration, and embedded server. Spring Cloud builds on Spring Boot's auto-configuration mechanism to wire distributed system infrastructure automatically. Every Spring Cloud service is a Spring Boot application. Spring Cloud adds the coordination layer.</p><pre><code class="language-xml">&lt;!-- pom.xml — Spring Cloud BOM manages all version compatibility --&gt;
&lt;dependencyManagement&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
      &lt;artifactId&gt;spring-cloud-dependencies&lt;/artifactId&gt;
      &lt;version&gt;2023.0.1&lt;/version&gt;
      &lt;type&gt;pom&lt;/type&gt;
      &lt;scope&gt;import&lt;/scope&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;
</code></pre><p>Always import the Spring Cloud BOM. Never manage Spring Cloud dependency versions individually — version mismatches between modules cause subtle, hard-to-debug failures.</p><hr><h2>3. Service Discovery</h2><h3>What is Service Discovery</h3><p>In a static deployment you hard-code IP addresses and ports. In a microservices deployment, services are ephemeral — they start, stop, scale up, and scale down dynamically. Service discovery solves the question: given a service name, what network address should I call right now?</p><h3>Service Registry</h3><p>The service registry is the central directory. Every service instance registers itself on startup and sends periodic heartbeats. If a heartbeat stops, the registry removes the instance.</p><h3>Client-Side vs Server-Side Discovery</h3><p><strong>Client-Side Discovery</strong> — the client queries the registry and picks an instance itself. The client holds the load-balancing logic. Spring Cloud uses this model.</p><p><strong>Server-Side Discovery</strong> — the client calls a router (load balancer), which queries the registry internally. AWS ALB and Kubernetes Services use this model.</p><h3>Netflix Eureka</h3><p>Eureka is the most widely used service registry in the Spring Cloud ecosystem. It is designed for AWS-style availability — it prefers availability over consistency (AP in CAP theorem). When the registry cannot reach enough peers, it enters self-preservation mode and stops evicting instances.</p><h3>Eureka Server Setup</h3><pre><code class="language-xml">&lt;!-- dependency --&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-netflix-eureka-server&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-java">@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
</code></pre><pre><code class="language-php"># application.yml — standalone Eureka server
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false   # this server does not register itself
    fetch-registry: false          # this server does not fetch from another registry
</code></pre><h3>Eureka Client Setup</h3><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-netflix-eureka-client&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-java">@SpringBootApplication
@EnableDiscoveryClient   // optional from Spring Cloud 2021+, auto-detected
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}
</code></pre><pre><code class="language-php"># application.yml — Eureka client
spring:
  application:
    name: order-service   # this becomes the service name in the registry

eureka:
  client:
    service-url:
      defaultZone: &lt;http://localhost:8761/eureka/&gt;
  instance:
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 30
    lease-expiration-duration-in-seconds: 90
</code></pre><h3>Service Registration and Heartbeats</h3><ul><li>On startup, the client POSTs its metadata (hostname, IP, port, health URL, status) to the registry</li><li>Every 30 seconds (default), the client sends a heartbeat PUT request</li><li>If the registry receives no heartbeat for 90 seconds, it marks the instance as DOWN</li><li>If the registry loses over 85% of expected heartbeats from all clients, it enters self-preservation mode and stops evicting any instance — this prevents mass deregistration during network partitions</li></ul><hr><h2>4. API Gateway</h2><h3>API Gateway Pattern</h3><p>An API Gateway is the single entry point for all client requests. Instead of clients calling each microservice directly, they call the gateway. The gateway handles routing, authentication, rate limiting, SSL termination, request transformation, and logging in one place.</p><p>Benefits:</p><ul><li>Clients are decoupled from internal service topology</li><li>Cross-cutting concerns are handled once, not in every service</li><li>Service URLs can change without affecting clients</li></ul><h3>Spring Cloud Gateway</h3><p>Spring Cloud Gateway is the modern, reactive replacement for Netflix Zuul. It is built on Project Reactor and Spring WebFlux, which means it is non-blocking and handles high concurrency efficiently.</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-gateway&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><h3>Routing</h3><p>A route is the fundamental unit in Spring Cloud Gateway. Each route has:</p><ul><li>An ID for identification</li><li>A URI — the downstream service address</li><li>Predicates — conditions that must match for the route to apply</li><li>Filters — transformations applied to request or response</li></ul><pre><code class="language-php">spring:
  cloud:
    gateway:
      routes:
        - id: order-service-route
          uri: lb://order-service      # lb:// triggers load-balanced discovery
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1            # removes /api before forwarding
</code></pre><h3>Predicates</h3><p>Predicates determine whether a route matches an incoming request. Multiple predicates on one route are ANDed together.</p><figure class="table"><table><thead><tr><th>Predicate</th><th>Example</th><th>Description</th></tr></thead><tbody><tr><td>Path</td><td><code>Path=/api/users/**</code></td><td>Matches URL path pattern</td></tr><tr><td>Method</td><td><code>Method=GET,POST</code></td><td>Matches HTTP method</td></tr><tr><td>Header</td><td><code>Header=X-Request-Id, \\\\d+</code></td><td>Matches header with regex</td></tr><tr><td>Query</td><td><code>Query=color, red</code></td><td>Matches query parameter</td></tr><tr><td>Host</td><td><code>Host=**.example.com</code></td><td>Matches Host header</td></tr><tr><td>After</td><td><code>After=2024-01-01T00:00:00Z</code></td><td>Matches requests after datetime</td></tr><tr><td>Weight</td><td><code>Weight=group1, 80</code></td><td>Weighted routing for canary deploys</td></tr></tbody></table></figure><h3>Filters</h3><p>Filters transform requests or responses. They run in order and fall into two categories: GatewayFilter (per route) and GlobalFilter (all routes).</p><pre><code class="language-php">filters:
  - AddRequestHeader=X-Request-Source, gateway
  - AddResponseHeader=X-Response-Time, 200ms
  - StripPrefix=2
  - RewritePath=/api/(?&lt;segment&gt;.*), /$\\\\{segment}
  - CircuitBreaker=name=orderCircuit,fallbackUri=/fallback
  - RequestRateLimiter=redis-rate-limiter
  - Retry=retries:3,statuses:BAD_GATEWAY
</code></pre><p>Custom filter with Java:</p><pre><code class="language-java">@Component
public class LoggingGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono&lt;Void&gt; filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getURI().getPath();
        System.out.println("Incoming request: " + path);
        return chain.filter(exchange)
                    .then(Mono.fromRunnable(() -&gt;
                        System.out.println("Response status: " +
                            exchange.getResponse().getStatusCode())));
    }

    @Override
    public int getOrder() { return -1; }
}
</code></pre><h3>Authentication at Gateway</h3><p>Centralize JWT validation at the gateway so individual services do not need to repeat it.</p><pre><code class="language-java">@Component
public class JwtAuthenticationFilter implements GlobalFilter {

    @Value("${jwt.secret}")
    private String secret;

    @Override
    public Mono&lt;Void&gt; filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest()
                               .getHeaders()
                               .getFirst(HttpHeaders.AUTHORIZATION);

        if (token == null || !token.startsWith("Bearer ")) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        // validate token, then pass claims downstream as header
        exchange.getRequest().mutate()
                .header("X-User-Id", extractUserId(token));
        return chain.filter(exchange);
    }
}
</code></pre><h3>Rate Limiting</h3><p>Spring Cloud Gateway integrates with Redis for distributed rate limiting using the token bucket algorithm.</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-data-redis-reactive&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-php">spring:
  cloud:
    gateway:
      routes:
        - id: rate-limited-route
          uri: lb://product-service
          predicates:
            - Path=/api/products/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10    # tokens added per second
                redis-rate-limiter.burstCapacity: 20    # max tokens in bucket
                redis-rate-limiter.requestedTokens: 1   # tokens per request
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/API_Gateway_routing_acbde9fe67.webp" alt="API Gateway routing" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_API_Gateway_routing_acbde9fe67.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_API_Gateway_routing_acbde9fe67.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_API_Gateway_routing_acbde9fe67.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_API_Gateway_routing_acbde9fe67.webp 1000w," sizes="100vw"><figcaption>API Gateway Routing Flow</figcaption></figure><hr><h2>5. Centralized Configuration</h2><h3>Externalized Configuration</h3><p>The Twelve-Factor App methodology mandates that configuration is separated from code. In microservices, this means you do not bake environment-specific properties into your JAR. You fetch them at runtime from a central source.</p><p>Benefits:</p><ul><li>One change propagates to all service instances without redeployment</li><li>Environment-specific config (dev, staging, prod) managed in one place</li><li>Secrets managed outside source code</li><li>Audit trail via Git history</li></ul><h3>Spring Cloud Config Server</h3><p>The Config Server is a standalone Spring Boot application that serves configuration over HTTP. It reads from a Git repository, local file system, HashiCorp Vault, or AWS S3.</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-config-server&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-java">@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
</code></pre><pre><code class="language-php"># application.yml — Config Server pointing to Git
server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: &lt;https://github.com/yourorg/config-repo&gt;
          default-label: main
          search-paths: '{application}'    # subfolder per service
          clone-on-start: true
</code></pre><p>Config Server URL pattern:</p><pre><code class="language-php">/{application}/{profile}[/{label}]

# Examples:
GET &lt;http://localhost:8888/order-service/prod&gt;
GET &lt;http://localhost:8888/order-service/dev/main&gt;
</code></pre><h3>Config Client</h3><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-config&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-php"># application.yml — microservice pointing to Config Server
spring:
  application:
    name: order-service         # maps to file name in config repo
  config:
    import: "configserver:&lt;http://localhost:8888&gt;"
  profiles:
    active: dev
</code></pre><p>File resolution in the Git repo follows this priority order (highest wins):</p><ol><li><code>order-service-dev.yml</code></li><li><code>order-service.yml</code></li><li><code>application-dev.yml</code></li><li><code>application.yml</code></li></ol><h3>Git-based Configuration Management</h3><p>Organize the Git repository cleanly:</p><pre><code class="language-ruby">config-repo/
├── application.yml              # shared across all services
├── application-prod.yml         # shared prod overrides
├── order-service/
│   ├── order-service.yml
│   ├── order-service-dev.yml
│   └── order-service-prod.yml
├── user-service/
│   └── user-service.yml
</code></pre><h3>Refresh Scope</h3><p>Without <code>@RefreshScope</code>, a bean reads its configuration once at startup. With <code>@RefreshScope</code>, the bean is re-initialized when a <code>/actuator/refresh</code> endpoint is called.</p><pre><code class="language-java">@RestController
@RefreshScope     // re-inject config on refresh
public class FeatureFlagController {

    @Value("${feature.new-checkout-enabled:false}")
    private boolean newCheckoutEnabled;

    @GetMapping("/feature-status")
    public String status() {
        return "New checkout: " + newCheckoutEnabled;
    }
}
</code></pre><p>Trigger a refresh on one instance:</p><pre><code class="language-php">curl -X POST &lt;http://localhost:8080/actuator/refresh&gt;</code></pre><h3>Dynamic Configuration Reload with Spring Cloud Bus</h3><p>To refresh all instances simultaneously without calling each one individually, use Spring Cloud Bus. It broadcasts the refresh event over a message broker (Kafka or RabbitMQ) to every subscribed instance.</p><pre><code class="language-xml">&lt;!-- Add to Config Server and all clients --&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-bus-kafka&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-php"># Refresh all instances in one call
curl -X POST &lt;http://localhost:8888/actuator/busrefresh&gt;
</code></pre><hr><h2>6. Client-Side Load Balancing</h2><h3>Load Balancing Concepts</h3><p>Load balancing distributes incoming requests across multiple instances of a service to avoid overloading any single instance. In the Spring Cloud model, the load balancer runs on the client side — meaning the service making the call decides which instance to call, based on a list it receives from the service registry.</p><h3>Spring Cloud LoadBalancer</h3><p>Spring Cloud LoadBalancer replaced Netflix Ribbon as the default client-side load balancer starting from Spring Cloud 2020. It is included automatically when you add the Eureka client dependency.</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-loadbalancer&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><h3>Using @LoadBalanced with RestTemplate</h3><pre><code class="language-java">@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced   // wraps RestTemplate to resolve service names via registry
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

@Service
public class OrderService {

    @Autowired
    private RestTemplate restTemplate;

    public Product getProduct(Long id) {
        // uses service name, not hardcoded URL
        return restTemplate.getForObject(
            "&lt;http://product-service/api/products/&gt;" + id,
            Product.class
        );
    }
}
</code></pre><h3>Using @LoadBalanced with WebClient (Reactive)</h3><pre><code class="language-java">@Configuration
public class WebClientConfig {

    @Bean
    @LoadBalanced
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}

@Service
public class ReactiveOrderService {

    @Autowired
    private WebClient.Builder webClientBuilder;

    public Mono&lt;Product&gt; getProduct(Long id) {
        return webClientBuilder.build()
            .get()
            .uri("&lt;http://product-service/api/products/&gt;" + id)
            .retrieve()
            .bodyToMono(Product.class);
    }
}
</code></pre><h3>Load Balancing Algorithms</h3><figure class="table"><table><thead><tr><th>Algorithm</th><th>Behavior</th><th>When to Use</th></tr></thead><tbody><tr><td>Round Robin (default)</td><td>Cycles through instances in order</td><td>Most scenarios; even distribution</td></tr><tr><td>Random</td><td>Picks a random instance</td><td>Reduces hot spots under bursty load</td></tr><tr><td>Custom</td><td>Implement <code>ReactorServiceInstanceLoadBalancer</code></td><td>Custom business logic needed</td></tr></tbody></table></figure><h3>Custom Load Balancer Configuration</h3><pre><code class="language-java">public class CustomLoadBalancerConfig {

    @Bean
    ReactorLoadBalancer&lt;ServiceInstance&gt; randomLoadBalancer(
            Environment env,
            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = env.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(
            loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),
            name
        );
    }
}

// Apply to a specific client
@LoadBalancerClient(name = "product-service", configuration = CustomLoadBalancerConfig.class)
public class ApplicationConfig { }
</code></pre><h3>Integration with Service Discovery</h3><p>The <code>ServiceInstanceListSupplier</code> fetches the instance list from Eureka (or Consul or Kubernetes). The load balancer then applies its algorithm to that list. Caching is enabled by default with a 35-second TTL to avoid hammering the registry on every request.</p><pre><code class="language-php">spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: false    # ensure Ribbon is not on classpath
      cache:
        ttl: 35s
        capacity: 256
</code></pre><hr><h2>7. Fault Tolerance and Resilience</h2><h3>Distributed System Failures</h3><p>In a distributed system with 10 services, if each has 99.9% uptime, the end-to-end availability of a chain through all 10 is approximately 99%. Without resilience patterns, a slow or failing downstream service can cascade into a full system outage through thread pool exhaustion.</p><h3>Circuit Breaker Pattern</h3><p>The circuit breaker sits around an external call. It monitors failures. When the failure rate exceeds a threshold, it opens and stops all calls to that service for a cooldown period. After the cooldown, it enters half-open state and allows a limited number of test calls through.</p><p><strong>States:</strong></p><ul><li>CLOSED — normal operation; calls pass through</li><li>OPEN — calls fail immediately without hitting the downstream service</li><li>HALF-OPEN — a limited number of probe calls are allowed to test recovery</li></ul><h3>Resilience4j</h3><p>Resilience4j is the recommended library for Spring Cloud fault tolerance. It provides circuit breaker, retry, rate limiter, bulkhead, and time limiter as individual composable decorators.</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;io.github.resilience4j&lt;/groupId&gt;
  &lt;artifactId&gt;resilience4j-spring-boot3&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-aop&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><h3>Circuit Breaker Configuration</h3><pre><code class="language-php">resilience4j:
  circuitbreaker:
    instances:
      product-service:
        sliding-window-type: COUNT_BASED
        sliding-window-size: 10               # evaluate last 10 calls
        failure-rate-threshold: 50            # open if 50%+ fail
        wait-duration-in-open-state: 10s      # stay open for 10 seconds
        permitted-number-of-calls-in-half-open-state: 3
        automatic-transition-from-open-to-half-open-enabled: true
</code></pre><pre><code class="language-java">@Service
public class ProductService {

    @CircuitBreaker(name = "product-service", fallbackMethod = "getProductFallback")
    public Product getProduct(Long id) {
        return restTemplate.getForObject("&lt;http://product-service/api/products/&gt;" + id, Product.class);
    }

    public Product getProductFallback(Long id, Exception ex) {
        return new Product(id, "Unavailable", 0.0);   // default response
    }
}
</code></pre><h3>Retry Pattern</h3><pre><code class="language-php">resilience4j:
  retry:
    instances:
      product-service:
        max-attempts: 3
        wait-duration: 500ms
        retry-exceptions:
          - java.io.IOException
          - java.util.concurrent.TimeoutException
        ignore-exceptions:
          - com.example.ProductNotFoundException
</code></pre><pre><code class="language-java">@Retry(name = "product-service", fallbackMethod = "getProductFallback")
public Product getProduct(Long id) {
    return restTemplate.getForObject("...", Product.class);
}
</code></pre><h3>Bulkhead Pattern</h3><p>A bulkhead limits the number of concurrent calls to a service, preventing one slow service from consuming all available threads.</p><pre><code class="language-php">resilience4j:
  bulkhead:
    instances:
      product-service:
        max-concurrent-calls: 10
        max-wait-duration: 100ms
</code></pre><pre><code class="language-java">@Bulkhead(name = "product-service", type = Bulkhead.Type.SEMAPHORE)
public Product getProduct(Long id) {
    return restTemplate.getForObject("...", Product.class);
}
</code></pre><h3>Rate Limiter</h3><pre><code class="language-php">resilience4j:
  ratelimiter:
    instances:
      product-service:
        limit-for-period: 100         # max 100 calls
        limit-refresh-period: 1s      # per second
        timeout-duration: 25ms        # wait up to 25ms for a slot
</code></pre><pre><code class="language-java">@RateLimiter(name = "product-service")
public Product getProduct(Long id) {
    return restTemplate.getForObject("...", Product.class);
}
</code></pre><h3>Timeout Handling</h3><pre><code class="language-php">resilience4j:
  timelimiter:
    instances:
      product-service:
        timeout-duration: 2s
        cancel-running-future: true
</code></pre><h3>Combining Multiple Resilience Patterns</h3><p>Annotations can be stacked. The execution order is: <code>TimeLimiter -&gt; CircuitBreaker -&gt; RateLimiter -&gt; Bulkhead -&gt; Retry</code>.</p><pre><code class="language-java">@CircuitBreaker(name = "product-service", fallbackMethod = "fallback")
@Retry(name = "product-service")
@Bulkhead(name = "product-service")
@TimeLimiter(name = "product-service")
public CompletableFuture&lt;Product&gt; getProduct(Long id) {
    return CompletableFuture.supplyAsync(() -&gt;
        restTemplate.getForObject("...", Product.class));
}
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Circuit_breaker_state_22ea69b442.webp" alt="Circuit breaker state" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Circuit_breaker_state_22ea69b442.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Circuit_breaker_state_22ea69b442.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Circuit_breaker_state_22ea69b442.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Circuit_breaker_state_22ea69b442.webp 1000w," sizes="100vw"><figcaption>Circuit Breaker State Machine</figcaption></figure><hr><h2>8. Distributed Tracing</h2><h3>Observability in Microservices</h3><p>A single user request in a microservices system touches multiple services. When something goes wrong or is slow, you need to reconstruct the complete journey of that request across service boundaries. Distributed tracing provides this capability.</p><h3>Trace ID and Span ID</h3><ul><li><strong>Trace ID</strong> — a single unique identifier assigned when a request first enters your system. It follows the request through every service it touches.</li><li><strong>Span ID</strong> — a unique identifier for one unit of work within a trace. Each service call creates a new span. Spans record their parent span ID to form a tree.</li><li><strong>Parent Span ID</strong> — links a child span to the span that initiated it.</li></ul><pre><code class="language-ruby">Trace: a1b2c3d4
├── Span: gateway (e5f6)                    0ms - 120ms
│   ├── Span: order-service (a7b8)          5ms - 115ms
│   │   ├── Span: product-service (c9d0)   10ms - 60ms
│   │   └── Span: inventory-service (e1f2) 65ms - 110ms
│   └── Span: auth-service (a3b4)           6ms - 20ms
</code></pre><h3>Micrometer Tracing with Zipkin</h3><p>From Spring Boot 3, Spring Cloud Sleuth is replaced by Micrometer Tracing. The concepts are identical; the library changed.</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;io.micrometer&lt;/groupId&gt;
  &lt;artifactId&gt;micrometer-tracing-bridge-brave&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;io.zipkin.reporter2&lt;/groupId&gt;
  &lt;artifactId&gt;zipkin-reporter-brave&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-php">management:
  tracing:
    sampling:
      probability: 1.0   # sample 100% in dev; use 0.1 in prod

  zipkin:
    tracing:
      endpoint: &lt;http://localhost:9411/api/v2/spans&gt;
</code></pre><p>Micrometer Tracing auto-instruments:</p><ul><li><code>RestTemplate</code></li><li><code>WebClient</code></li><li>Feign clients</li><li>Kafka producers and consumers</li><li><code>@Scheduled</code> methods</li><li><code>@Async</code> methods</li></ul><p>The trace ID and span ID are automatically injected into the MDC (Mapped Diagnostic Context), so they appear in every log line without extra code:</p><pre><code class="language-ruby">2024-01-15 10:23:45 [order-service,,a1b2c3d4e5f6,e5f6a7b8] INFO  OrderController - Processing order 1234
</code></pre><p>Log format: <code>[service-name, trace-id, span-id]</code></p><h3>Running Zipkin Locally</h3><pre><code class="language-ruby">docker run -d -p 9411:9411 openzipkin/zipkin
</code></pre><p>Access the UI at <code>http://localhost:9411</code>. You can search by trace ID, service name, and time range.</p><hr><h2>9. Event-Driven Microservices</h2><h3>Event-Driven Architecture</h3><p>In event-driven architecture, services communicate by publishing and consuming events through a message broker. The producer has no knowledge of consumers. This creates strong decoupling and allows services to evolve independently.</p><h3>Spring Cloud Stream</h3><p>Spring Cloud Stream is a framework for building event-driven microservices connected to message brokers. It abstracts the broker-specific APIs behind a uniform programming model using Java functional interfaces.</p><pre><code class="language-xml">&lt;!-- For Kafka --&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-stream-kafka&lt;/artifactId&gt;
&lt;/dependency&gt;

&lt;!-- For RabbitMQ --&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-stream-rabbit&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><h3>Producers and Consumers</h3><p>Spring Cloud Stream uses three functional interfaces:</p><figure class="table"><table><thead><tr><th>Interface</th><th>Role</th><th>Bindings Created</th></tr></thead><tbody><tr><td><code>Supplier&lt;T&gt;</code></td><td>Source / Producer</td><td>output</td></tr><tr><td><code>Consumer&lt;T&gt;</code></td><td>Sink / Consumer</td><td>input</td></tr><tr><td><code>Function&lt;T,R&gt;</code></td><td>Processor</td><td>input + output</td></tr></tbody></table></figure><pre><code class="language-java">// Producer — publishes OrderCreatedEvent every second (Supplier auto-triggered)
@Bean
public Supplier&lt;OrderCreatedEvent&gt; orderCreatedSupplier() {
    return () -&gt; new OrderCreatedEvent(UUID.randomUUID(), "PENDING");
}

// Consumer — processes incoming events
@Bean
public Consumer&lt;OrderCreatedEvent&gt; processOrder() {
    return event -&gt; {
        System.out.println("Processing order: " + event.getOrderId());
        inventoryService.reserve(event);
    };
}

// Processor — receives, transforms, and re-publishes
@Bean
public Function&lt;OrderCreatedEvent, OrderProcessedEvent&gt; processAndPublish() {
    return event -&gt; {
        inventoryService.reserve(event);
        return new OrderProcessedEvent(event.getOrderId(), "RESERVED");
    };
}
</code></pre><h3>Binding Configuration</h3><pre><code class="language-php">spring:
  cloud:
    stream:
      bindings:
        # naming convention: functionName + -in-0 (input) or -out-0 (output)
        processOrder-in-0:
          destination: orders-topic
          group: inventory-service    # consumer group for competing consumers
        orderCreatedSupplier-out-0:
          destination: orders-topic
      kafka:
        bindings:
          processOrder-in-0:
            consumer:
              startOffset: earliest
</code></pre><h3>Apache Kafka</h3><p>Kafka is a distributed, partitioned, replicated commit log. It is optimized for high-throughput, fault-tolerant event streaming.</p><p>Key concepts:</p><figure class="table"><table><thead><tr><th>Concept</th><th>Description</th></tr></thead><tbody><tr><td>Topic</td><td>Named category for messages</td></tr><tr><td>Partition</td><td>Topic split for parallelism; messages in a partition are ordered</td></tr><tr><td>Offset</td><td>Position of a message within a partition</td></tr><tr><td>Producer</td><td>Writes messages to topics</td></tr><tr><td>Consumer</td><td>Reads messages from topics</td></tr><tr><td>Consumer Group</td><td>Set of consumers that cooperate; each partition assigned to one consumer</td></tr><tr><td>Broker</td><td>Single Kafka server node</td></tr></tbody></table></figure><pre><code class="language-php"># Start Kafka with Docker Compose
version: '3'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:7.5.0
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181

  kafka:
    image: confluentinc/cp-kafka:7.5.0
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
</code></pre><h3>RabbitMQ</h3><p>RabbitMQ uses exchanges and queues. Producers publish to exchanges; exchanges route to queues based on binding rules.</p><figure class="table"><table><thead><tr><th>Exchange Type</th><th>Routing Behavior</th></tr></thead><tbody><tr><td>Direct</td><td>Routes to queue whose binding key matches the message routing key exactly</td></tr><tr><td>Topic</td><td>Matches routing key patterns with <code>*</code> and <code>#</code> wildcards</td></tr><tr><td>Fanout</td><td>Broadcasts to all bound queues; ignores routing key</td></tr><tr><td>Headers</td><td>Routes based on message header attributes</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Event_driven_microservices_651d5f071a.webp" alt="Event-driven microservices" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Event_driven_microservices_651d5f071a.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Event_driven_microservices_651d5f071a.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Event_driven_microservices_651d5f071a.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Event_driven_microservices_651d5f071a.webp 1000w," sizes="100vw"><figcaption>Event-Driven Microservices Architecture</figcaption></figure><hr><h2>10. Security in Microservices</h2><h3>Microservices Security Challenges</h3><ul><li>Each service needs to know who is calling it and whether they are authorized</li><li>Tokens need to propagate through service chains</li><li>Services must not blindly trust data from other internal services without validation</li><li>Secrets (DB passwords, API keys) cannot be stored in config files or source code</li></ul><h3>Spring Security with OAuth2</h3><p>OAuth2 is the industry-standard protocol for authorization. In a microservices context, a client authenticates with an Authorization Server (Keycloak, Okta, Auth0) and receives a JWT access token. It presents this token on every API call. Services validate the token without calling the Authorization Server on every request.</p><h3>JWT Authentication</h3><p>A JWT (JSON Web Token) has three Base64URL-encoded parts: header, payload, and signature.</p><pre><code class="language-javascript">eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZXMiOlsiUk9MRV9VU0VSIl0sImV4cCI6MTcwNTM2NTIwMH0.&lt;signature&gt;
</code></pre><p>Payload example:</p><pre><code class="language-javascript">{
  "sub": "user123",
  "roles": ["ROLE_USER"],
  "exp": 1705365200,
  "iss": "&lt;http://auth.example.com&gt;"
}
</code></pre><h3>Resource Server Configuration (Spring Boot 3)</h3><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-oauth2-resource-server&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-java">@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -&gt; auth
                .requestMatchers("/actuator/health").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -&gt; oauth2
                .jwt(jwt -&gt; jwt
                    .jwtAuthenticationConverter(jwtAuthenticationConverter())
                )
            )
            .sessionManagement(session -&gt; session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            );
        return http.build();
    }

    private JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtGrantedAuthoritiesConverter converter = new JwtGrantedAuthoritiesConverter();
        converter.setAuthoritiesClaimName("roles");
        converter.setAuthorityPrefix("ROLE_");
        JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
        jwtConverter.setJwtGrantedAuthoritiesConverter(converter);
        return jwtConverter;
    }
}
</code></pre><pre><code class="language-php">spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: &lt;http://localhost:8080/realms/myrealm&gt;   # Keycloak issuer
</code></pre><h3>Token Propagation</h3><p>When Service A calls Service B, it must forward the JWT. Use the <code>TokenRelay</code> filter in the gateway, or propagate manually with Feign.</p><pre><code class="language-php"># Gateway: forward token to downstream services automatically
spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - TokenRelay=    # forwards Authorization header downstream
</code></pre><p>For Feign clients:</p><pre><code class="language-java">@Configuration
public class FeignSecurityConfig {

    @Bean
    public RequestInterceptor requestInterceptor() {
        return template -&gt; {
            ServletRequestAttributes attributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                String token = attributes.getRequest()
                                         .getHeader(HttpHeaders.AUTHORIZATION);
                if (token != null) {
                    template.header(HttpHeaders.AUTHORIZATION, token);
                }
            }
        };
    }
}
</code></pre><hr><h2>11. Distributed Transactions</h2><h3>Transaction Problems in Microservices</h3><p>The classic database transaction (ACID) does not work across services that own separate databases. If an order service writes to its database and then calls inventory service, and inventory fails, you cannot simply roll back the order database — the transaction boundary is gone.</p><h3>Eventual Consistency</h3><p>Accept that in a distributed system, data will not always be instantly consistent across all services. Design flows so that all services will eventually reach a consistent state, even if there are brief windows of inconsistency.</p><h3>Saga Pattern</h3><p>A saga is a sequence of local transactions. Each service in the chain performs its local transaction and publishes an event (or calls the next service). If any step fails, compensating transactions undo the previous steps.</p><h3>Choreography Saga</h3><p>Each service listens for events and decides what to do next independently. There is no central coordinator.</p><pre><code class="language-ruby">OrderService         InventoryService       PaymentService
     |                       |                      |
  Create Order               |                      |
  Publish: OrderCreated      |                      |
     |          ---------&gt; Reserve Stock            |
     |                Publish: StockReserved        |
     |                      |     -----------&gt; Charge Payment
     |                      |           Publish: PaymentCompleted
  Confirm Order             |                       |
</code></pre><p>Compensating flow on failure:</p><pre><code class="language-ruby">PaymentService fails
Publish: PaymentFailed
     |
InventoryService listens → Release Stock
     |
OrderService listens → Cancel Order
</code></pre><h3>Orchestration Saga</h3><p>A central orchestrator tells each service what to do. It tracks the saga state and issues compensating commands when a failure occurs.</p><pre><code class="language-java">@SagaOrchestrationStart
public void placeOrder(PlaceOrderCommand command) {
    orderService.createOrder(command);
    sagaManager.startSaga(command.getOrderId());
}

// Using Axon Framework Saga example
@Saga
public class OrderSaga {

    @SagaEventHandler(associationProperty = "orderId")
    public void on(OrderCreatedEvent event) {
        commandGateway.send(new ReserveStockCommand(event.getOrderId(), event.getProductId()));
    }

    @SagaEventHandler(associationProperty = "orderId")
    public void on(StockReservationFailedEvent event) {
        commandGateway.send(new CancelOrderCommand(event.getOrderId()));
    }

    @EndSaga
    @SagaEventHandler(associationProperty = "orderId")
    public void on(PaymentCompletedEvent event) {
        // saga complete
    }
}
</code></pre><figure class="table"><table><thead><tr><th>&nbsp;</th><th>Choreography</th><th>Orchestration</th></tr></thead><tbody><tr><td>Coordination</td><td>Decentralized</td><td>Centralized orchestrator</td></tr><tr><td>Coupling</td><td>Loose</td><td>Tighter to orchestrator</td></tr><tr><td>Visibility</td><td>Hard to trace</td><td>Easy to trace</td></tr><tr><td>Failure handling</td><td>Complex — each service must listen for failures</td><td>Simpler — orchestrator handles rollback</td></tr><tr><td>Best for</td><td>Simple flows with few steps</td><td>Complex flows with many conditions</td></tr></tbody></table></figure><hr><h2>12. Monitoring and Observability</h2><h3>Spring Boot Actuator</h3><p>Actuator exposes operational endpoints over HTTP (or JMX). It is the foundation for all monitoring in a Spring Boot microservice.</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-actuator&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-php">management:
  endpoints:
    web:
      exposure:
        include: health, info, metrics, prometheus, env, loggers, threaddump
  endpoint:
    health:
      show-details: always
      show-components: always
</code></pre><p>Key Actuator endpoints:</p><figure class="table"><table><thead><tr><th>Endpoint</th><th>Description</th></tr></thead><tbody><tr><td><code>/actuator/health</code></td><td>Service health status including custom indicators</td></tr><tr><td><code>/actuator/metrics</code></td><td>All Micrometer metrics</td></tr><tr><td><code>/actuator/prometheus</code></td><td>Prometheus-formatted metrics</td></tr><tr><td><code>/actuator/env</code></td><td>All environment properties (sensitive — secure this)</td></tr><tr><td><code>/actuator/loggers</code></td><td>View and change log levels at runtime</td></tr><tr><td><code>/actuator/threaddump</code></td><td>Current thread state</td></tr><tr><td><code>/actuator/info</code></td><td>Application metadata</td></tr><tr><td><code>/actuator/refresh</code></td><td>Trigger config refresh (with Cloud Config)</td></tr></tbody></table></figure><h3>Custom Health Indicator</h3><pre><code class="language-java">@Component
public class DatabaseHealthIndicator implements HealthIndicator {

    @Autowired
    private DataSource dataSource;

    @Override
    public Health health() {
        try (Connection conn = dataSource.getConnection()) {
            return Health.up()
                         .withDetail("database", "PostgreSQL")
                         .withDetail("status", "connection ok")
                         .build();
        } catch (Exception e) {
            return Health.down()
                         .withDetail("error", e.getMessage())
                         .build();
        }
    }
}
</code></pre><h3>Micrometer and Prometheus</h3><p>Micrometer is the metrics facade for Spring Boot applications — analogous to SLF4J but for metrics. It supports counters, gauges, timers, and distribution summaries.</p><pre><code class="language-java">@Service
public class OrderService {

    private final Counter orderCounter;
    private final Timer orderProcessingTimer;

    public OrderService(MeterRegistry registry) {
        this.orderCounter = Counter.builder("orders.created")
                                   .description("Total orders created")
                                   .tag("region", "us-east")
                                   .register(registry);

        this.orderProcessingTimer = Timer.builder("orders.processing.time")
                                         .description("Order processing duration")
                                         .register(registry);
    }

    public Order createOrder(CreateOrderRequest request) {
        return orderProcessingTimer.record(() -&gt; {
            Order order = processOrder(request);
            orderCounter.increment();
            return order;
        });
    }
}
</code></pre><p>Prometheus scrapes the <code>/actuator/prometheus</code> endpoint. Configure the scrape job:</p><pre><code class="language-php"># prometheus.yml
scrape_configs:
  - job_name: 'spring-cloud-services'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 15s
    static_configs:
      - targets:
          - 'order-service:8080'
          - 'product-service:8081'
          - 'user-service:8082'
</code></pre><h3>Grafana</h3><p>Grafana connects to Prometheus as a data source and provides dashboards. The Spring Boot community maintains pre-built Grafana dashboards for JVM metrics, HTTP request rates, error rates, and circuit breaker states. Import dashboard ID 4701 (JVM Micrometer) from <a href="http://grafana.com/">grafana.com</a> as a starting point.</p><h3>Logging in Microservices</h3><p>Structured logging (JSON format) is essential in microservices because it allows log aggregation systems (ELK Stack, Grafana Loki) to parse, index, and query logs across all services.</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;net.logstash.logback&lt;/groupId&gt;
  &lt;artifactId&gt;logstash-logback-encoder&lt;/artifactId&gt;
  &lt;version&gt;7.4&lt;/version&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-xml">&lt;!-- logback-spring.xml --&gt;
&lt;configuration&gt;
  &lt;springProfile name="prod"&gt;
    &lt;appender name="JSON" class="ch.qos.logback.core.ConsoleAppender"&gt;
      &lt;encoder class="net.logstash.logback.encoder.LogstashEncoder"&gt;
        &lt;includeMdcKeyName&gt;traceId&lt;/includeMdcKeyName&gt;
        &lt;includeMdcKeyName&gt;spanId&lt;/includeMdcKeyName&gt;
      &lt;/encoder&gt;
    &lt;/appender&gt;
    &lt;root level="INFO"&gt;
      &lt;appender-ref ref="JSON"/&gt;
    &lt;/root&gt;
  &lt;/springProfile&gt;
&lt;/configuration&gt;
</code></pre><p>Output:</p><pre><code class="language-javascript">{
	"@timestamp":"2024-01-15T10:23:45Z",
	"level":"INFO","service":"order-service",
 	"traceId":"a1b2c3d4e5f6",
 	"spanId":"e5f6a7b8",
 	"message":"Order 1234 created"
 }
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Monitoring_stack_93eb407854.webp" alt="Monitoring stack" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Monitoring_stack_93eb407854.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Monitoring_stack_93eb407854.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Monitoring_stack_93eb407854.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Monitoring_stack_93eb407854.webp 1000w," sizes="100vw"><figcaption>Monitoring and Observability Stack</figcaption></figure><hr><h2>13. End-to-End Microservices Request Flow</h2><h3>Complete Request Trace: Place an Order</h3><p>This section traces one user request — placing an order — through every layer of a production Spring Cloud system.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Detailed_end_to_end_request_flow_142b080e55.webp" alt="End to end request flow" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Detailed_end_to_end_request_flow_142b080e55.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Detailed_end_to_end_request_flow_142b080e55.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Detailed_end_to_end_request_flow_142b080e55.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Detailed_end_to_end_request_flow_142b080e55.webp 1000w," sizes="100vw"><figcaption>End-to-End Microservices Request Flow</figcaption></figure><p><strong>Step-by-step:</strong></p><ol><li><strong>Client sends request</strong><ul><li><code>POST &lt;https://api.example.com/api/orders</code>&gt;</li><li>Bearer JWT token in Authorization header</li></ul></li><li><strong>API Gateway receives request</strong><ul><li>JWT filter validates token signature against JWKS endpoint</li><li>Rate limiter checks Redis for remaining token budget</li><li>Route predicate <code>Path=/api/orders/**</code> matches</li></ul></li><li><strong>Gateway performs service discovery</strong><ul><li>Resolves <code>lb://order-service</code> by querying Eureka registry</li><li>Receives list of available instances: <code>[192.168.1.10:8080, 192.168.1.11:8080]</code></li></ul></li><li><strong>Load balancer selects instance</strong><ul><li>Round-robin selects <code>192.168.1.10:8080</code></li><li><code>TokenRelay</code> filter copies JWT to forwarded request</li></ul></li><li><strong>Circuit breaker check</strong><ul><li>Resilience4j checks state of <code>order-service</code> circuit breaker</li><li>Circuit is CLOSED — request proceeds</li></ul></li><li><strong>Order Service processes request</strong><ul><li>Validates request body</li><li>Calls Product Service via Feign client to verify product exists</li><li>Feign call is load-balanced and has its own circuit breaker</li><li>Saves order to database with status <code>PENDING</code></li><li>Returns <code>202 Accepted</code> with order ID</li></ul></li><li><strong>Asynchronous event published</strong><ul><li>Order Service publishes <code>OrderCreatedEvent</code> to Kafka topic <code>orders</code></li><li>Event contains order ID, product ID, quantity, user ID</li></ul></li><li><strong>Downstream consumers react</strong><ul><li>Inventory Service consumes event, decrements stock</li><li>Notification Service consumes event, sends confirmation email</li><li>Payment Service consumes event, initiates charge</li><li>Each service publishes its own result events</li></ul></li><li><strong>Distributed trace recorded</strong><ul><li>All services attached the same trace ID <code>a1b2c3d4</code> to their spans</li><li>Zipkin received all spans and assembled the complete trace tree</li><li>Total request time visible in Zipkin UI</li></ul></li></ol><h3>Gateway Routing Flow (Condensed)</h3><pre><code class="language-ruby">Client
  → Gateway (authenticate, rate limit)
    → Eureka (resolve order-service instances)
      → LoadBalancer (pick instance)
        → CircuitBreaker (check state)
          → order-service:8080 (process)
            → Feign → product-service (validate)
            → Database (persist)
            → Kafka (publish event)
          ← 202 Accepted
        ← forward response
      ←
    ←
  ← 202 Accepted with order ID
</code></pre><hr><h2>14. Spring Cloud Project Structure</h2><h3>Recommended Project Layout</h3><p>A Spring Cloud system is composed of several Spring Boot applications. The cleanest approach is a Maven or Gradle multi-module project where each module is an independent microservice.</p><pre><code class="language-ruby">microservices-project/
├── pom.xml                         # parent POM with Spring Cloud BOM
│
├── config-server/                  # Spring Cloud Config Server
│   ├── src/main/java/
│   └── src/main/resources/
│       └── application.yml
│
├── eureka-server/                  # Service Registry
│   ├── src/main/java/
│   └── src/main/resources/
│       └── application.yml
│
├── api-gateway/                    # Spring Cloud Gateway
│   ├── src/main/java/
│   └── src/main/resources/
│       └── application.yml
│
├── order-service/                  # Business microservice
│   ├── src/main/java/
│   │   └── com/example/order/
│   │       ├── controller/
│   │       ├── service/
│   │       ├── repository/
│   │       ├── model/
│   │       └── client/             # Feign clients to other services
│   └── src/main/resources/
│       └── application.yml
│
├── product-service/
├── user-service/
├── notification-service/
│
├── shared-library/                 # Common DTOs, exceptions, utils
│   └── src/main/java/
│       └── com/example/shared/
│           ├── dto/
│           ├── exception/
│           └── config/
│
└── config-repo/                    # Git repo for Config Server (or separate repo)
    ├── application.yml
    ├── order-service.yml
    ├── order-service-dev.yml
    └── order-service-prod.yml
</code></pre><h3>Parent POM</h3><pre><code class="language-xml">&lt;!-- parent pom.xml --&gt;
&lt;project&gt;
  &lt;groupId&gt;com.example&lt;/groupId&gt;
  &lt;artifactId&gt;microservices-project&lt;/artifactId&gt;
  &lt;version&gt;1.0.0&lt;/version&gt;
  &lt;packaging&gt;pom&lt;/packaging&gt;

  &lt;parent&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
    &lt;version&gt;3.2.1&lt;/version&gt;
  &lt;/parent&gt;

  &lt;properties&gt;
    &lt;java.version&gt;21&lt;/java.version&gt;
    &lt;spring-cloud.version&gt;2023.0.1&lt;/spring-cloud.version&gt;
  &lt;/properties&gt;

  &lt;dependencyManagement&gt;
    &lt;dependencies&gt;
      &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
        &lt;artifactId&gt;spring-cloud-dependencies&lt;/artifactId&gt;
        &lt;version&gt;${spring-cloud.version}&lt;/version&gt;
        &lt;type&gt;pom&lt;/type&gt;
        &lt;scope&gt;import&lt;/scope&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;
  &lt;/dependencyManagement&gt;

  &lt;modules&gt;
    &lt;module&gt;config-server&lt;/module&gt;
    &lt;module&gt;eureka-server&lt;/module&gt;
    &lt;module&gt;api-gateway&lt;/module&gt;
    &lt;module&gt;order-service&lt;/module&gt;
    &lt;module&gt;product-service&lt;/module&gt;
    &lt;module&gt;shared-library&lt;/module&gt;
  &lt;/modules&gt;
&lt;/project&gt;
</code></pre><h3>Config Server — Key Files</h3><pre><code class="language-java">// ConfigServerApplication.java
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
</code></pre><pre><code class="language-php"># application.yml
server:
  port: 8888
spring:
  cloud:
    config:
      server:
        git:
          uri: ${CONFIG_REPO_URI:&lt;https://github.com/yourorg/config-repo&gt;}
          default-label: main
</code></pre><h3>Eureka Server — Key Files</h3><pre><code class="language-java">// EurekaServerApplication.java
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
</code></pre><pre><code class="language-php"># application.yml
server:
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
</code></pre><h3>API Gateway — Key Files</h3><pre><code class="language-php"># application.yml
server:
  port: 8080
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true      # auto-create routes from Eureka registry
          lower-case-service-id: true
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
        - id: product-service
          uri: lb://product-service
          predicates:
            - Path=/api/products/**
eureka:
  client:
    service-url:
      defaultZone: &lt;http://localhost:8761/eureka/&gt;
</code></pre><h3>Microservice — Standard Dependencies</h3><pre><code class="language-xml">&lt;!-- dependencies for a typical business microservice --&gt;
&lt;dependencies&gt;
  &lt;!-- Web --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
  &lt;/dependency&gt;

  &lt;!-- Config Client --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-config&lt;/artifactId&gt;
  &lt;/dependency&gt;

  &lt;!-- Service Discovery --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-netflix-eureka-client&lt;/artifactId&gt;
  &lt;/dependency&gt;

  &lt;!-- Feign HTTP client --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-openfeign&lt;/artifactId&gt;
  &lt;/dependency&gt;

  &lt;!-- Resilience4j --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;io.github.resilience4j&lt;/groupId&gt;
    &lt;artifactId&gt;resilience4j-spring-boot3&lt;/artifactId&gt;
  &lt;/dependency&gt;

  &lt;!-- Distributed Tracing --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;io.micrometer&lt;/groupId&gt;
    &lt;artifactId&gt;micrometer-tracing-bridge-brave&lt;/artifactId&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;io.zipkin.reporter2&lt;/groupId&gt;
    &lt;artifactId&gt;zipkin-reporter-brave&lt;/artifactId&gt;
  &lt;/dependency&gt;

  &lt;!-- Actuator --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-actuator&lt;/artifactId&gt;
  &lt;/dependency&gt;

  &lt;!-- Security --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-oauth2-resource-server&lt;/artifactId&gt;
  &lt;/dependency&gt;

  &lt;!-- Database --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
  &lt;/dependency&gt;
&lt;/dependencies&gt;
</code></pre><h3>Shared Library</h3><p>The shared library avoids duplicating DTO classes, exception handling, and common configuration across services.</p><pre><code class="language-ruby">shared-library/src/main/java/com/example/shared/
├── dto/
│   ├── ApiResponse.java          # standard API response wrapper
│   ├── ErrorResponse.java        # error response structure
│   └── PagedResponse.java
├── exception/
│   ├── ServiceException.java
│   ├── ResourceNotFoundException.java
│   └── GlobalExceptionHandler.java
└── config/
    └── CommonSecurityConfig.java  # shared security base configuration
</code></pre><h3>Startup Order</h3><p>Infrastructure services must start before business services can register and fetch configuration.</p><pre><code class="language-ruby">1. Config Server (port 8888)   — must start first
2. Eureka Server  (port 8761)   — registers after Config Server
3. API Gateway    (port 8080)   — registers after Eureka
4. Business microservices       — start last; fetch config, register with Eureka
</code></pre><p>Use Docker Compose <code>depends_on</code> with health checks to enforce this ordering in a containerized environment.</p><pre><code class="language-php"># docker-compose.yml (partial)
services:
  config-server:
    build: ./config-server
    ports: ["8888:8888"]
    healthcheck:
      test: ["CMD", "curl", "-f", "&lt;http://localhost:8888/actuator/health&gt;"]
      interval: 10s
      timeout: 5s
      retries: 5

  eureka-server:
    build: ./eureka-server
    ports: ["8761:8761"]
    depends_on:
      config-server:
        condition: service_healthy

  order-service:
    build: ./order-service
    depends_on:
      eureka-server:
        condition: service_healthy
      config-server:
        condition: service_healthy
</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Microservices_startup_flowchart_diagram_7869a5ef15.webp" alt="Microservices startup" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Microservices_startup_flowchart_diagram_7869a5ef15.webp 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Microservices_startup_flowchart_diagram_7869a5ef15.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Microservices_startup_flowchart_diagram_7869a5ef15.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Microservices_startup_flowchart_diagram_7869a5ef15.webp 1000w," sizes="100vw"><figcaption>Spring Cloud Service Startup Order</figcaption></figure><hr><h2>Quick Reference Card</h2><h3>Annotations Summary</h3><figure class="table"><table><thead><tr><th>Annotation</th><th>Location</th><th>Purpose</th></tr></thead><tbody><tr><td><code>@EnableEurekaServer</code></td><td>Config class</td><td>Start Eureka registry</td></tr><tr><td><code>@EnableDiscoveryClient</code></td><td>Main class</td><td>Register with discovery</td></tr><tr><td><code>@EnableConfigServer</code></td><td>Config class</td><td>Start Config Server</td></tr><tr><td><code>@EnableFeignClients</code></td><td>Config class</td><td>Activate Feign scanning</td></tr><tr><td><code>@RefreshScope</code></td><td>Bean</td><td>Re-inject on config refresh</td></tr><tr><td><code>@LoadBalanced</code></td><td>Bean method</td><td>Enable client-side LB</td></tr><tr><td><code>@CircuitBreaker</code></td><td>Method</td><td>Apply circuit breaker</td></tr><tr><td><code>@Retry</code></td><td>Method</td><td>Apply retry logic</td></tr><tr><td><code>@Bulkhead</code></td><td>Method</td><td>Apply bulkhead concurrency limit</td></tr><tr><td><code>@RateLimiter</code></td><td>Method</td><td>Apply rate limiter</td></tr><tr><td><code>@TimeLimiter</code></td><td>Method</td><td>Apply timeout</td></tr><tr><td><code>@FeignClient</code></td><td>Interface</td><td>Declare declarative HTTP client</td></tr></tbody></table></figure><h3>Default Ports Convention</h3><figure class="table"><table><thead><tr><th>Service</th><th>Default Port</th></tr></thead><tbody><tr><td>Config Server</td><td>8888</td></tr><tr><td>Eureka Server</td><td>8761</td></tr><tr><td>API Gateway</td><td>8080</td></tr><tr><td>Zipkin</td><td>9411</td></tr><tr><td>Prometheus</td><td>9090</td></tr><tr><td>Grafana</td><td>3000</td></tr><tr><td>Kafka</td><td>9092</td></tr><tr><td>RabbitMQ</td><td>5672 (AMQP), 15672 (management UI)</td></tr></tbody></table></figure><h3>Spring Cloud Version Compatibility</h3><figure class="table"><table><thead><tr><th>Spring Boot</th><th>Spring Cloud</th></tr></thead><tbody><tr><td>3.2.x</td><td>2023.0.x (Leyton)</td></tr><tr><td>3.1.x</td><td>2022.0.x (Kilburn)</td></tr><tr><td>3.0.x</td><td>2022.0.x (Kilburn)</td></tr><tr><td>2.7.x</td><td>2021.0.x (Jubilee)</td></tr></tbody></table></figure><p>Always check the Spring Cloud release train page for the exact compatible versions before starting a new project.</p><hr><h2>Conclusion</h2><p>Spring Cloud simplifies building scalable and resilient microservices by providing tools for service discovery, API gateways, configuration management, fault tolerance, tracing, and messaging. This cheatsheet aimed to give a quick overview of the key components and how they work together in a real microservices architecture.</p><p>If you found this cheatsheet helpful, feel free to <strong>share it with your friends or fellow developers</strong> who are learning Spring Cloud.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Spring Boot</category>
            <category>Spring Cloud</category>
            <category>Microservices</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Spring_Cloud_Thumbnail_54e4aa1c44.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Core Java in One Shot: The Ultimate Core Java Cheat Sheet]]></title>
            <link>https://www.codingshuttle.com/blogs/java-in-one-shot-the-ultimate-core-java-cheat-sheet</link>
            <guid>https://www.codingshuttle.com/blogs/java-in-one-shot-the-ultimate-core-java-cheat-sheet</guid>
            <pubDate>Mon, 02 Mar 2026 14:01:18 GMT</pubDate>
            <description><![CDATA[A simple and structured revision guide covering all the essential Core Java concepts in one place. From OOP principles, collections, exception handling, multithreading, and file handling to JVM basics — this cheat sheet helps you quickly revise what truly matters.]]></description>
            <content:encoded><![CDATA[<p>Core Java in One Shot – The Ultimate Cheat Sheet</p><p>Java remains one of the most powerful and widely-used programming languages in the enterprise world. Whether you are preparing for an interview, revisiting concepts, or learning it for the first time, having a structured cheat sheet can save you hours of sifting through documentation. This guide provides a fast, practical reference to the most important Core Java concepts, combining essential theory with code examples you can use immediately.</p><h2>1. Java Introduction</h2><h3>History of Java</h3><p>Java was created by James Gosling and his team at Sun Microsystems in the early 1990s. Originally named "Oak," it was designed for interactive television, but the project was ahead of its time. The team pivoted, and in 1995, Java 1.0 was officially released. Its timing coincided perfectly with the explosive growth of the World Wide Web, as Java's ability to run small programs (applets) in browsers made web pages dynamic for the first time. Sun Microsystems was later acquired by Oracle Corporation in 2010, which now maintains and develops the language.</p><h3>Features of Java</h3><p>Java's enduring popularity stems from its robust design principles. It was built from the ground up to be reliable, secure, and portable.</p><ul><li><strong>Platform Independent</strong>: Java code does not run directly on the operating system. It compiles to an intermediate form called bytecode, which runs on a virtual machine.</li><li><strong>Object-Oriented</strong>: Java embraces the object-oriented paradigm, allowing developers to model real-world entities using classes and objects. Everything except the primitive data types is an object.</li><li><strong>Robust</strong>: The language is designed for reliability. It has strong memory management, a strict type system, and comprehensive exception handling to catch and manage errors.</li><li><strong>Secure</strong>: Java runs inside a virtual machine sandbox, which isolates it from the underlying system. It also lacks explicit pointers, preventing unauthorized memory access.</li><li><strong>Multithreaded</strong>: Java has built-in support for concurrent programming, allowing developers to write applications that can perform multiple tasks simultaneously, improving performance and responsiveness.</li></ul><h3>WORA (Write Once, Run Anywhere)</h3><p>This is the cornerstone philosophy of Java. When you write and compile Java code, it generates bytecode (.class files). This bytecode is not specific to any one operating system. To run it on a particular machine, you need a Java Virtual Machine (JVM) built for that specific operating system (Windows, Linux, macOS). The JVM acts as an intermediary, interpreting the bytecode into native machine code. This means you can compile your code on a Windows machine and run it without changes on a Linux server, provided a JVM is installed there.</p><h3>JDK, JRE, JVM</h3><p>Understanding the Java ecosystem starts with these three acronyms. They are nested layers of the Java platform.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/JDK_Architecture_d5f4391d11.png" alt="JDK Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_JDK_Architecture_d5f4391d11.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_JDK_Architecture_d5f4391d11.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_JDK_Architecture_d5f4391d11.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_JDK_Architecture_d5f4391d11.png 1000w," sizes="100vw"></p><figure class="table"><table><thead><tr><th>Component</th><th>Full Form</th><th>What it Contains</th><th>Purpose</th></tr></thead><tbody><tr><td><strong>JVM</strong></td><td>Java Virtual Machine</td><td>Runtime engine, Interpreter, JIT Compiler</td><td>Executes the bytecode. It is the runtime environment's heart.</td></tr><tr><td><strong>JRE</strong></td><td>Java Runtime Environment</td><td>JVM + Java standard libraries</td><td>Provides the libraries and JVM needed to <i>run</i> Java applications. It is for end-users.</td></tr><tr><td><strong>JDK</strong></td><td>Java Development Kit</td><td>JRE + Development Tools (javac, jar, javadoc)</td><td>Provides everything needed to <i>develop</i> and run Java applications. It is for developers.</td></tr></tbody></table></figure><h3>Java Program Structure</h3><p>Every Java application has a defined structure. The JVM looks for a specific entry point to start execution.</p><pre><code class="language-java">// 1. Package declaration (optional, but good practice for organizing classes)
package com.example.myapp;

// 2. Import statements (optional, for using classes from other packages)
import java.util.Scanner;

// 3. Class declaration (mandatory - the filename must match this class name)
public class Main {

    // 4. Main method (the mandatory entry point for any Java application)
    public static void main(String[] args) {

        // 5. Statements (the actual code to be executed)
        System.out.println("Hello, World!");

    }
}
</code></pre><h2>2. Java Fundamentals</h2><h3>Data Types</h3><p>Java is a <strong>statically-typed</strong> language, meaning every variable must have a declared type. Data types are divided into two categories.</p><figure class="table"><table><thead><tr><th>Category</th><th>Type</th><th>Size/Range</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>Primitive</strong></td><td><code>byte</code></td><td>1 byte (-128 to 127)</td><td>Useful for saving memory in large arrays.</td><td><code>byte b = 100;</code></td></tr><tr><td>&nbsp;</td><td><code>short</code></td><td>2 bytes (-32,768 to 32,767)</td><td>Rarely used, mainly for specific memory constraints.</td><td><code>short s = 10000;</code></td></tr><tr><td>&nbsp;</td><td><code>int</code></td><td>4 bytes</td><td>The default integer type.</td><td><code>int i = 100000;</code></td></tr><tr><td>&nbsp;</td><td><code>long</code></td><td>8 bytes</td><td>Used when a wider range than int is needed. Suffix with <code>L</code>.</td><td><code>long l = 100000L;</code></td></tr><tr><td>&nbsp;</td><td><code>float</code></td><td>4 bytes (single precision)</td><td>For fractional numbers, less precise than double. Suffix with <code>f</code>.</td><td><code>float f = 5.75f;</code></td></tr><tr><td>&nbsp;</td><td><code>double</code></td><td>8 bytes (double precision)</td><td>The default floating-point type.</td><td><code>double d = 19.99;</code></td></tr><tr><td>&nbsp;</td><td><code>char</code></td><td>2 bytes (Unicode)</td><td>Stores a single character, using single quotes.</td><td><code>char c = 'A';</code></td></tr><tr><td>&nbsp;</td><td><code>boolean</code></td><td><p>JVM dependent</p><p>(True / False)</p></td><td>Represents logical true/false values.</td><td><code>boolean flag = true;</code></td></tr><tr><td><strong>Non-Primitive</strong></td><td>String, Arrays, Classes, Interfaces, etc.</td><td>Varies</td><td>These are reference types that refer to objects stored in heap memory.</td><td><code>String str = "Hello";</code></td></tr></tbody></table></figure><h3>Variables</h3><p>Variables are containers for storing data values. In Java, every variable has a type, a name, and a scope.</p><pre><code class="language-java">// Declaration - telling the compiler about the variable's name and type
int number;

// Initialization - assigning a value for the first time
number = 10;

// Declaration + Initialization (combining both steps)
String message = "Hello, World!";
</code></pre><p><strong>Types of Variables:</strong></p><ul><li><strong>Local Variable:</strong> Declared inside a method, constructor, or block. It is created when the method is called and destroyed when it exits. It must be initialized before use.</li><li><strong>Instance Variable (Non-static):</strong> Declared inside a class but outside any method. It belongs to a specific instance (object) of the class.</li><li><strong>Static Variable (Class Variable):</strong> Declared with the <code>static</code> keyword. There is only one copy of this variable, shared by all objects of the class.</li></ul><h3>Operators</h3><p>Operators are special symbols that perform specific operations on one, two, or three operands and return a result.</p><ul><li><strong>Arithmetic:</strong> <code>+</code> (addition), <code>-</code> (subtraction), <code>*</code>(multiplication), <code>/</code> (division), <code>%</code> (modulo/remainder)</li><li><strong>Relational:</strong> <code>==</code> (equal to), <code>!=</code> (not equal to), <code>&gt;</code> (greater than), <code>&lt;</code> (less than), <code>&gt;=</code> (greater than or equal to), <code>&lt;=</code> (less than or equal to). They return a boolean result.</li><li><strong>Logical:</strong> <code>&amp;&amp;</code> (logical AND), <code>||</code> (logical OR), <code>!</code> (logical NOT). Used to combine conditional statements.</li><li><strong>Assignment:</strong> <code>=</code> (assign), <code>+=</code> (add and assign), <code>-=</code> (subtract and assign), <code>*=</code> (multiply and assign), <code>/=</code> (divide and assign)</li><li><strong>Unary:</strong> <code>++</code> (increment by 1), <code>-</code> (decrement by 1), <code>!</code> (logical complement)</li><li><strong>Ternary:</strong> A shorthand for an if-then-else statement. <code>variable = (condition) ? expressionIfTrue : expressionIfFalse;</code></li></ul><h3>Type Casting</h3><p>Type casting is converting a value from one data type to another. Java supports two types of casting.</p><p><strong>Widening (Implicit/Automatic):</strong> Converting a smaller type to a larger type. This is safe and happens automatically because there is no risk of data loss.</p><pre><code class="language-java">int myInt = 9;
double myDouble = myInt; // Automatic casting: int to double (9.0)</code></pre><p><strong>Narrowing (Explicit/Manual):</strong> Converting a larger type to a smaller type. This can lead to data loss and must be done manually by placing the target type in parentheses.</p><pre><code class="language-java">double myDouble = 9.78;
int myInt = (int) myDouble; // Manual casting: double to int (9, data lost)</code></pre><h3>Input / Output (Scanner)</h3><p>For basic user input from the console, the <code>Scanner</code> class (from <code>java.util</code> package) is the standard tool.</p><pre><code class="language-java">import java.util.Scanner; // 1. Import the Scanner class

public class Main {
    public static void main(String[] args) {
        // 2. Create a Scanner object to read from System.in (keyboard)
        Scanner scanner = new Scanner(System.in);

        // 3. Output a prompt to the user
        System.out.print("Enter your name: ");
        // 4. Read the input as a String
        String name = scanner.nextLine();

        System.out.print("Enter your age: ");
        // 5. Read the input as an integer
        int age = scanner.nextInt();

        System.out.println("Hello, " + name + ". You are " + age + " years old.");

        // 6. Good practice to close the scanner to release resources
        scanner.close();
    }
}
</code></pre><h2>3. Control Flow</h2><p>Control flow statements determine the order in which code is executed, allowing for decision-making and repetition.</p><h3>if / else</h3><p>The most basic form of decision-making. The code inside a block executes only if the specified boolean condition is true.</p><pre><code class="language-java">int score = 85;

if (score &gt;= 90) {
    System.out.println("Grade: A");
} else if (score &gt;= 80) {
    System.out.println("Grade: B"); // This will execute
} else if (score &gt;= 70) {
    System.out.println("Grade: C");
} else {
    System.out.println("Grade: F"); // Default case
}
</code></pre><h3>switch</h3><p>The <code>switch</code> statement is useful for selecting one of many code blocks to execute based on the value of a sin gle variable (which can be <code>int</code>, <code>char</code>, <code>String</code>, or <code>enum</code>). It is often more readable than a long chain of <code>if-else if</code> statements.</p><pre><code class="language-java">int dayNumber = 3;
String dayName;

switch (dayNumber) {
    case 1:
        dayName = "Monday";
        break; // break is crucial to prevent fall-through
    case 2:
        dayName = "Tuesday";
        break;
    case 3:
        dayName = "Wednesday"; // This will be assigned
        break;
    case 4:
        dayName = "Thursday";
        break;
    // ... cases for 5, 6, 7
    default:
        dayName = "Invalid day";
        // break is optional here, as it's the last case
}
System.out.println(dayName); // Output: Wednesday
</code></pre><h3>Loops</h3><p>Loops are used to execute a block of code repeatedly.</p><p><strong>for loop:</strong> Best used when the number of iterations is known beforehand.</p><pre><code class="language-java">// Loop from i=0 to i=4, printing each value
for (int i = 0; i &lt; 5; i++) {
    System.out.println("Iteration: " + i);
}
</code></pre><p><strong>Enhanced for-each loop:</strong> A simplified syntax for iterating over arrays and collections. You don't have access to the index.</p><pre><code class="language-java">int[] numbers = {10, 20, 30, 40};
for (int num : numbers) {
    System.out.println(num);
}
</code></pre><p><strong>while loop:</strong> Best used when the number of iterations is unknown, and the loop continues as long as a condition is true. The condition is checked before the loop body executes.</p><pre><code class="language-java">int i = 0;
while (i &lt; 5) {
    System.out.println(i);
    i++;
}
</code></pre><p><strong>do-while loop:</strong> Similar to a <code>while</code> loop, but the condition is checked <i>after</i> the loop body executes. This guarantees that the loop body will run at least once.</p><pre><code class="language-java">int i = 0;
do {
    System.out.println(i);
    i++;
} while (i &lt; 5);
</code></pre><h3>break / continue</h3><p>These statements are used to alter the normal flow of a loop.</p><ul><li><strong>break:</strong> Immediately terminates the innermost loop or <code>switch</code> statement.</li><li><strong>continue:</strong> Skips the remaining code in the current iteration and jumps to the next iteration of the loop.</li></ul><h2>4. Methods</h2><p>Methods are reusable blocks of code that perform a specific task. They are fundamental to structured and modular programming.</p><h3>Method Declaration</h3><p>A method declaration provides all the information needed to call the method.</p><pre><code class="language-java">// AccessModifier Optional(static) ReturnType methodName(ParameterList) {
//     // method body
//     // return statement (if return type is not void)
// }
public static int addNumbers(int a, int b) {
    int sum = a + b;
    return sum; // The value 'sum' is sent back to the caller
}
</code></pre><h3>Parameters and Return Types</h3><ul><li><strong>Parameters:</strong> The variables listed in the method declaration inside the parentheses. They act as placeholders for the data the method will receive (<code>a</code> and <code>b</code> in the example).</li><li><strong>Arguments:</strong> The actual values passed to the method when it is called (e.g., <code>addNumbers(5, 3)</code> passes <code>5</code> and <code>3</code> as arguments).</li><li><strong>Return Type:</strong> The data type of the value the method returns. If a method does not return a value, its return type must be declared as <code>void</code>.</li></ul><h3>Method Overloading</h3><p>Method overloading allows a class to have multiple methods with the same name, as long as their parameter lists are different (different number, type, or order of parameters). This is a form of compile-time polymorphism.</p><pre><code class="language-java">public class MathUtils {
    // Method to add two integers
    public int add(int a, int b) {
        return a + b;
    }

    // Overloaded method to add three integers (different number of parameters)
    public int add(int a, int b, int c) {
        return a + b + c;
    }

    // Overloaded method to add two doubles (different parameter type)
    public double add(double a, double b) {
        return a + b;
    }
}
</code></pre><h3>Recursion</h3><p>Recursion occurs when a method calls itself. Every recursive method must have a base condition that stops the recursion; otherwise, it will lead to a <code>StackOverflowError</code>. It is often used for problems that can be broken down into smaller, similar sub-problems, like traversing tree structures or calculating factorials.</p><pre><code class="language-java">public static int factorial(int n) {
    // Base case: if n is 0, factorial is 1
    if (n == 0) {
        return 1;
    }
    // Recursive case: n! = n * (n-1)!
    else {
        return n * factorial(n - 1);
    }
}
// factorial(4) returns 4 * factorial(3) -&gt; 4 * 3 * factorial(2) -&gt; ... -&gt; 4*3*2*1 = 24
</code></pre><h2>5. Object Oriented Programming (OOP)</h2><p>OOP is a programming paradigm based on the concept of "objects," which contain data (fields) and code (methods). Java is fundamentally built around these four pillars.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Pillars_of_OOP_1142ace7dc.png" alt="Pillars of OOP" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Pillars_of_OOP_1142ace7dc.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Pillars_of_OOP_1142ace7dc.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Pillars_of_OOP_1142ace7dc.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Pillars_of_OOP_1142ace7dc.png 1000w," sizes="100vw"><figcaption>Pillars of OOP</figcaption></figure><h3>Class and Object</h3><ul><li><strong>Class:</strong> A class is a blueprint or template from which individual objects are created. It defines the state (variables) and behavior (methods) that the objects of the class will have.</li><li><strong>Object:</strong> An object is an instance of a class. When you create an object, you allocate memory to hold its state, as defined by its class.</li></ul><pre><code class="language-java">// Class definition
class Car {
    // State (instance variables)
    String model;
    int year;

    // Behavior (methods)
    void startEngine() {
        System.out.println("The " + model + " engine is starting.");
    }
}

// Creating objects (instances of the Car class)
Car myFirstCar = new Car();
myFirstCar.model = "Tesla Model 3";
myFirstCar.year = 2023;

Car mySecondCar = new Car();
mySecondCar.model = "Ford Mustang";
mySecondCar.year = 1967;

myFirstCar.startEngine(); // Output: The Tesla Model 3 engine is starting.
</code></pre><h3>Constructors</h3><p>A constructor is a special method that is automatically called when an object is instantiated using the <code>new</code> keyword. It is used to initialize the new object's state. Constructors have the same name as the class and no return type.</p><pre><code class="language-java">class Car {
    String model;
    int year;

    // Constructor
    public Car(String modelName, int manufactureYear) {
        model = modelName;
        year = manufactureYear;
    }
}

// When creating the object, we must provide the constructor arguments
Car myCar = new Car("Tesla Model 3", 2023);
</code></pre><h3>this Keyword</h3><p>Inside a class, the <code>this</code> keyword is a reference to the current object. It is most commonly used to distinguish between instance variables and parameters with the same name.</p><pre><code class="language-java">public class Person {
    private String name;

    public Person(String name) { // Parameter 'name' shadows the instance variable
        this.name = name; // 'this.name' refers to the instance variable, 'name' refers to the parameter
    }
}
</code></pre><h3>Encapsulation</h3><p>Encapsulation is the mechanism of wrapping data (variables) and code acting on the data (methods) together as a single unit. It also involves hiding the internal state of an object from the outside world and providing controlled access through public methods (getters and setters). This protects data from unauthorized access and modification.</p><pre><code class="language-java">public class BankAccount {
    private double balance; // Private variable - cannot be accessed directly

    // Public getter to read the balance (read-only access)
    public double getBalance() {
        return balance;
    }

    // Public method to deposit money (controlled modification)
    public void deposit(double amount) {
        if (amount &gt; 0) {
            balance += amount;
        }
    }
}
</code></pre><h3>Inheritance</h3><p>Inheritance is a mechanism where one class (child/subclass) acquires the properties and methods of another class (parent/superclass). It represents an "is-a" relationship. In Java, inheritance is achieved using the <code>extends</code> keyword. A class can only extend one parent class.</p><pre><code class="language-java">class Vehicle { // Parent class
    String brand = "Generic";
    public void honk() {
        System.out.println("Beep beep!");
    }
}

class Car extends Vehicle { // Child class inherits from Vehicle
    String model = "Model 3";
    public void printDetails() {
        System.out.println(brand + " " + model); // Can access 'brand' inherited from Vehicle
    }
}
</code></pre><h3>Polymorphism</h3><p>Polymorphism means "many forms." It allows objects of different classes to be treated as objects of a common superclass, and the correct method for that specific object is called at runtime. This is achieved through method overriding.</p><h3>Method Overriding</h3><p>Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. This is how runtime polymorphism is achieved. The method in the child class must have the same name, return type, and parameters as the parent method. It's good practice to use the <code>@Override</code> annotation.</p><pre><code class="language-java">class Animal {
    public void makeSound() {
        System.out.println("Some generic animal sound");
    }
}

class Dog extends Animal {
    @Override // This annotation tells the compiler we are overriding a method
    public void makeSound() {
        System.out.println("Woof woof!"); // Specific implementation for Dog
    }
}

// Polymorphism in action
Animal myAnimal = new Dog(); // Reference of type Animal, object of type Dog
myAnimal.makeSound(); // Output: Woof woof! (Dog's version is called)
</code></pre><h3>Abstraction</h3><p>Abstraction is the concept of hiding complex implementation details and showing only the essential features of an object. It helps in managing complexity by focusing on <i>what</i> an object does rather than <i>how</i> it does it. In Java, abstraction is achieved through <strong>abstract classes</strong> and <strong>interfaces</strong>.</p><h3>Abstract Classes</h3><p>An abstract class is a class that cannot be instantiated. It may contain abstract methods (methods without a body) and concrete methods (with a body). It serves as a partial blueprint for its subclasses, forcing them to implement the abstract methods.</p><pre><code class="language-java">abstract class Shape {
    // Abstract method - no body, must be implemented by subclasses
    public abstract double calculateArea();

    // Concrete method - can be used directly by subclasses
    public void display() {
        System.out.println("Displaying shape.");
    }
}

class Circle extends Shape {
    double radius;

    Circle(double r) { radius = r; }

    @Override
    public double calculateArea() { // Must implement this method
        return Math.PI * radius * radius;
    }
}
</code></pre><h3>Interfaces</h3><p>An interface is a completely abstract blueprint of a class. It only declares methods (and sometimes constants) but provides no implementation. A class can <code>implement</code> multiple interfaces, providing a way to achieve multiple inheritance in Java. Since Java 8, interfaces can also have <code>default</code> and <code>static</code> methods with implementations.</p><pre><code class="language-java">interface Drawable {
    void draw(); // public and abstract by default
}

interface Colorable {
    void setColor(String color);
}

// A class can implement multiple interfaces
class ColoredCircle implements Drawable, Colorable {
    private String color;

    @Override
    public void draw() {
        System.out.println("Drawing a circle of color: " + color);
    }

    @Override
    public void setColor(String color) {
        this.color = color;
    }
}
</code></pre><h2>6. Arrays</h2><p>Arrays are fundamental data structures that store a fixed-size sequential collection of elements of the <strong>same type</strong>.</p><h3>One-Dimensional Arrays</h3><p>An array is declared with its type, followed by square brackets. Memory is allocated using the <code>new</code> keyword, and the size is fixed at creation.</p><pre><code class="language-java">// Declaration and memory allocation
int[] numbers = new int[5]; // Creates an array of 5 integers, all initialized to 0

// Declaration, allocation, and initialization in one line
String[] names = {"Alice", "Bob", "Charlie"};

// Assigning values using index (zero-based)
numbers[0] = 10;
numbers[1] = 20;
// numbers[5] = 60; // This would throw an ArrayIndexOutOfBoundsException
</code></pre><h3>Multi-Dimensional Arrays</h3><p>Multi-dimensional arrays are arrays of arrays. The most common is the two-dimensional array, which can be visualized as a table with rows and columns.</p><pre><code class="language-java">// 2D Array: 3 rows, 2 columns
int[][] matrix = new int[3][2];

// Declaration and initialization
int[][] predefinedMatrix = {
    {1, 2},
    {3, 4},
    {5, 6}
};

int value = predefinedMatrix[1][0]; // value is 3 (second row, first column)
</code></pre><h3>Array Traversal</h3><p>To access each element of an array, you typically use a loop.</p><pre><code class="language-java">int[] scores = {85, 92, 78, 95};

// Using a standard for loop (useful when you need the index)
for (int i = 0; i &lt; scores.length; i++) {
    System.out.println("Element at index " + i + ": " + scores[i]);
}

// Using an enhanced for-each loop (simpler, no index)
for (int score : scores) {
    System.out.println("Score: " + score);
}
</code></pre><h3>Sorting and Searching</h3><p>The <code>java.util.Arrays</code> class provides useful utility methods for working with arrays.</p><pre><code class="language-java">import java.util.Arrays;

int[] numbers = {42, 17, 8, 99, 23};

// Sorting the array in ascending order (modifies the original array)
Arrays.sort(numbers); // numbers becomes [8, 17, 23, 42, 99]

// Searching for a value using binary search (array MUST be sorted first)
int index = Arrays.binarySearch(numbers, 23); // Returns the index of 23 (which is 2)
System.out.println("Found 23 at index: " + index);

// If not found, binarySearch returns a negative insertion point.
int notFoundIndex = Arrays.binarySearch(numbers, 50); // Returns -5
</code></pre><h2>7. Strings</h2><h3>String Class</h3><p>In Java, <code>String</code> is not a primitive type but a class (<code>java.lang.String</code>). It represents a sequence of characters. String objects are created either using literals or the <code>new</code> keyword.</p><pre><code class="language-java">String str1 = "Hello"; // String literal - stored in the String Pool for efficiency
String str2 = new String("World"); // Using new - creates a new object in the heap
</code></pre><h3>String Immutability</h3><p>Once a <code>String</code> object is created, its value cannot be changed. Any operation that appears to modify a string, such as <code>concat()</code> or <code>toUpperCase()</code>, actually creates and returns a <strong>new</strong> <code>String</code> object. The original string remains unchanged. This immutability is crucial for security, caching (String Pool), and thread-safety.</p><pre><code class="language-java">String s = "Hello";
s.concat(" World"); // This creates a new string "Hello World", but does not change 's'
System.out.println(s); // Output: Hello (s is unchanged)

String s2 = s.concat(" World"); // You must assign the result to a new variable
System.out.println(s2); // Output: Hello World
</code></pre><h3>Important String Methods</h3><pre><code class="language-java">String s = "  Java Programming  ";

s.length();          // Returns 20
s.charAt(2);         // Returns 'J' (index 2 is the third character)
s.substring(5);      // Returns "Programming" (from index 5 to end)
s.substring(5, 9);   // Returns "Prog" (from index 5 inclusive to 9 exclusive)
s.contains("Java");  // Returns true
s.trim();            // Returns "Java Programming" (removes leading/trailing spaces)
s.toUpperCase();     // Returns "  JAVA PROGRAMMING  " (returns new string)
s.toLowerCase();     // Returns "  java programming  "
s.replace('a', 'x'); // Returns "  Jxvx Progrmming  "
s.split(" ");        // Returns an array: ["", "", "Java", "Programming", "", ""]
</code></pre><h3>StringBuilder vs StringBuffer</h3><p>For scenarios where you need to perform many modifications (append, insert, delete) to a character sequence, using <code>String</code> would be inefficient due to the constant creation of new objects. <code>StringBuilder</code> and <code>StringBuffer</code> are mutable alternatives.</p><figure class="table"><table><thead><tr><th>Feature</th><th>StringBuffer</th><th>StringBuilder</th></tr></thead><tbody><tr><td><strong>Thread-Safety</strong></td><td>Synchronized, meaning it is thread-safe for use in multi-threaded environments.</td><td>Not synchronized, meaning it is not thread-safe.</td></tr><tr><td><strong>Performance</strong></td><td>Slower due to the overhead of synchronization.</td><td>Faster, as it has no synchronization overhead.</td></tr><tr><td><strong>Use Case</strong></td><td>Use when you need to modify strings from multiple threads concurrently.</td><td>Use in single-threaded scenarios or where thread-safety is handled externally. This is the most common choice.</td></tr></tbody></table></figure><pre><code class="language-java">// Example with StringBuilder
StringBuilder sb = new StringBuilder("Start");
sb.append("Middle");      // sb now contains "StartMiddle"
sb.insert(5, "End");      // sb now contains "StartEndMiddle" (inserts "End" at index 5)
sb.delete(5, 8);          // sb now contains "StartMiddle" (removes "End")
String finalString = sb.toString(); // Convert back to an immutable String
</code></pre><h2>8. Exception Handling</h2><p>Exception handling is a mechanism to handle runtime errors, allowing the normal flow of the application to continue. An exception is an event that disrupts the normal execution of a program.</p><h3>try / catch / finally</h3><p>This is the primary block for handling exceptions.</p><ul><li><strong>try:</strong> Contains the code that might throw an exception.</li><li><strong>catch:</strong> Handles the exception. You can have multiple catch blocks for different exception types.</li><li><strong>finally:</strong> (Optional) Contains code that will always execute, regardless of whether an exception occurred or not. It is typically used for cleanup activities like closing files or database connections.</li></ul><pre><code class="language-java">try {
    int[] numbers = {1, 2, 3};
    System.out.println(numbers[5]); // This will throw ArrayIndexOutOfBoundsException
    int result = 10 / 0;            // This line will not execute because the exception above jumps to catch
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Error: Array index is out of bounds!");
} catch (ArithmeticException e) {
    System.out.println("Error: Cannot divide by zero!");
} finally {
    System.out.println("This block always runs, performing cleanup.");
}
</code></pre><h3>throw and throws</h3><p><strong>throw:</strong> This keyword is used to explicitly throw a single exception from a method or a block of code. You can throw a newly created exception or one that was just caught.</p><pre><code class="language-java">public void checkAge(int age) {
    if (age &lt; 18) {
        // Explicitly throwing an exception
        throw new IllegalArgumentException("Age must be 18 or older.");
    }
}</code></pre><p><strong>throws:</strong> This keyword is used in a method signature to declare that the method might throw one or more exceptions. It informs the caller that they need to handle these exceptions.</p><pre><code class="language-java">// This method declares that it might throw an IOException
public void readFile(String path) throws IOException {
    // Code that might throw an IOException, like creating a FileReader
    FileReader file = new FileReader(path);
}</code></pre><h3>Custom Exceptions</h3><p>While Java provides many built-in exceptions, you can create your own for application-specific error conditions. You create a class that extends <code>Exception</code> (to create a checked exception) or <code>RuntimeException</code> (to create an unchecked exception).</p><pre><code class="language-java">// Custom checked exception
class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message); // Pass the message to the parent Exception class
    }
}

public class BankAccount {
    private double balance = 100;

    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount &gt; balance) {
            throw new InsufficientFundsException("You do not have sufficient funds.");
        }
        balance -= amount;
    }
}
</code></pre><h2>9. Collections Framework</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Collections_Framework_ea32434cb9.png" alt="Collections Framework" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Collections_Framework_ea32434cb9.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Collections_Framework_ea32434cb9.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Collections_Framework_ea32434cb9.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Collections_Framework_ea32434cb9.png 1000w," sizes="100vw"><figcaption>Collections Framework</figcaption></figure><p>The Collections Framework provides a well-designed set of interfaces and classes for storing and processing groups of data as a single unit. It replaces arrays with more flexible and powerful data structures.</p><h3>List (Ordered, Allows Duplicates)</h3><p>A <code>List</code> is an ordered collection (also known as a sequence). The user has precise control over where in the list each element is inserted and can access them by their integer index. Lists can contain duplicate elements.</p><ul><li><strong>ArrayList:</strong> A resizable-array implementation. It offers fast random access (<code>O(1)</code>) but is slower for inserting or deleting elements in the middle (<code>O(n)</code>) as it may require shifting elements.</li><li><strong>LinkedList:</strong> A doubly-linked list implementation. It offers better performance for inserting and deleting elements in the middle (<code>O(1)</code> for some operations) but is slower for random access (<code>O(n)</code>). It can also be used as a queue or deque.</li></ul><pre><code class="language-java">List&lt;String&gt; arrayList = new ArrayList&lt;&gt;();
arrayList.add("Apple");
arrayList.add("Banana");
arrayList.add(0, "Orange"); // Insert at specific index
String fruit = arrayList.get(1); // Fast access
</code></pre><h3>Set (Unordered or Sorted, No Duplicates)</h3><p>A <code>Set</code> is a collection that cannot contain duplicate elements. It models the mathematical set abstraction.</p><ul><li><strong>HashSet:</strong> Uses a hash table for storage. It offers constant-time performance (<code>O(1)</code>) for basic operations like add, remove, and contains, but it makes no guarantees about the order of elements.</li><li><strong>LinkedHashSet:</strong> Extends <code>HashSet</code> and maintains a doubly-linked list of its entries. This ensures that the iteration order is predictable—the order in which elements were inserted.</li><li><strong>TreeSet:</strong> Implements the <code>SortedSet</code> interface using a tree structure (red-black tree). It stores elements in a sorted (ascending) order. Its operations are slower (<code>O(log n)</code>) than <code>HashSet</code> but guarantee sorted order.</li></ul><pre><code class="language-java">Set&lt;Integer&gt; hashSet = new HashSet&lt;&gt;();
hashSet.add(20);
hashSet.add(10);
hashSet.add(30);
// Order is not guaranteed; might print [20, 10, 30] or similar

Set&lt;Integer&gt; treeSet = new TreeSet&lt;&gt;();
treeSet.add(20);
treeSet.add(10);
treeSet.add(30);
// Iteration will always be in sorted order: [10, 20, 30]
</code></pre><h3>Map (Key-Value Pairs)</h3><p>A <code>Map</code> is an object that maps keys to values. It cannot contain duplicate keys; each key can map to at most one value.</p><ul><li><strong>HashMap:</strong> Implements the <code>Map</code> interface using a hash table. It offers constant-time performance for <code>get</code> and <code>put</code>. It does not guarantee the order of its entries.</li><li><strong>LinkedHashMap:</strong> Extends <code>HashMap</code> and maintains a doubly-linked list of its entries, ensuring predictable iteration order—usually the order in which keys were inserted.</li><li><strong>TreeMap:</strong> Implements the <code>SortedMap</code> interface. It stores its entries in a sorted order based on the keys (natural ordering or a provided comparator). Its operations are <code>O(log n)</code>.</li></ul><pre><code class="language-java">Map&lt;String, Integer&gt; scores = new HashMap&lt;&gt;();
scores.put("Alice", 95);
scores.put("Bob", 87);
scores.put("Charlie", 92);

int aliceScore = scores.get("Alice"); // 95

// Iterating over entries
for (Map.Entry&lt;String, Integer&gt; entry : scores.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}
</code></pre><h3>Iterator</h3><p>An <code>Iterator</code> is an object that enables you to traverse through a collection and to remove elements selectively during the traversal. It provides a uniform way to access elements of any <code>Collection</code>.</p><pre><code class="language-java">List&lt;String&gt; list = new ArrayList&lt;&gt;(Arrays.asList("A", "B", "C"));
Iterator&lt;String&gt; iterator = list.iterator();

while (iterator.hasNext()) { // Check if there is another element
    String item = iterator.next(); // Get the next element
    System.out.println(item);
    if (item.equals("B")) {
        iterator.remove(); // Safely remove the current element from the list
    }
}
</code></pre><h3>Comparable vs Comparator</h3><p>Both interfaces are used to define the order of objects, especially for sorting.</p><figure class="table"><table><thead><tr><th>Feature</th><th>Comparable</th><th>Comparator</th></tr></thead><tbody><tr><td><strong>Purpose</strong></td><td>Defines the <strong>natural ordering</strong> of objects. For example, <code>Integer</code>'s natural order is numeric ascending.</td><td>Defines a <strong>custom ordering</strong>. For example, sorting <code>Person</code> objects by name length or age.</td></tr><tr><td><strong>Package</strong></td><td><code>java.lang</code></td><td><code>java.util</code></td></tr><tr><td><strong>Method</strong></td><td><code>int compareTo(T o)</code></td><td><code>int compare(T o1, T o2)</code></td></tr><tr><td><strong>Class Modification</strong></td><td>Requires the class whose objects are being compared to implement <code>Comparable</code>.</td><td>A separate class or lambda expression implements <code>Comparator</code>. The original class remains unchanged.</td></tr><tr><td><strong>Sorting Method</strong></td><td><code>Collections.sort(list)</code></td><td><code>Collections.sort(list, comparator)</code></td></tr></tbody></table></figure><pre><code class="language-java">// Comparable: Inside the class itself
class Student implements Comparable&lt;Student&gt; {
    int age;
    String name;

    Student(int age, String name) { this.age = age; this.name = name; }

    @Override
    public int compareTo(Student s) {
        return this.age - s.age; // Sort by age (natural order)
    }
}

// Comparator: External, using a lambda for custom sorting
List&lt;Student&gt; students = new ArrayList&lt;&gt;();
// ... add students

// Sort by name using a Comparator (no change to Student class)
Collections.sort(students, (s1, s2) -&gt; s1.name.compareTo(s2.name));
</code></pre><h2>10. File Handling</h2><p>File handling in Java is done through classes in the <code>java.io</code> package. It involves reading data from and writing data to files.</p><h3>File Class</h3><p>The <code>File</code> class is an abstract representation of file and directory pathnames. It is used to get information about a file (like existence, size, permissions) but not for reading/writing the file content itself.</p><pre><code class="language-java">import java.io.File;

File myFile = new File("example.txt");
if (myFile.exists()) {
    System.out.println("File name: " + myFile.getName());
    System.out.println("Absolute path: " + myFile.getAbsolutePath());
    System.out.println("Writable: " + myFile.canWrite());
    System.out.println("File size in bytes: " + myFile.length());
} else {
    System.out.println("File does not exist.");
}
</code></pre><h3>FileReader / FileWriter</h3><p>These classes are used for reading and writing character files (text files). They handle the conversion between bytes and characters using the platform's default character encoding.</p><pre><code class="language-java">// Writing to a file using FileWriter
FileWriter writer = new FileWriter("output.txt");
writer.write("Hello, this is the first line.\n");
writer.write("This is the second line.");
writer.close(); // Always close to flush and release resources

// Reading from a file using FileReader
FileReader reader = new FileReader("output.txt");
int character;
while ((character = reader.read()) != -1) { // read() returns -1 at end of file
    System.out.print((char) character);
}
reader.close();
</code></pre><h3>BufferedReader / BufferedWriter</h3><p>For better performance, especially when dealing with large files or reading line by line, it is highly recommended to wrap <code>FileReader</code> and <code>FileWriter</code> with <code>BufferedReader</code> and <code>BufferedWriter</code>. These classes use an internal buffer to reduce the number of direct read/write operations to the underlying file system.</p><pre><code class="language-java">// Efficient writing
BufferedWriter bw = new BufferedWriter(new FileWriter("data.txt"));
bw.write("Buffered Line 1");
bw.newLine(); // Writes a platform-specific line separator
bw.write("Buffered Line 2");
bw.close();

// Efficient reading line by line
BufferedReader br = new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = br.readLine()) != null) { // readLine() returns null at EOF
    System.out.println(line);
}
br.close();
</code></pre><h3>Serialization</h3><p>Serialization is the process of converting an object into a byte stream, which can then be saved to a file, sent over a network, or stored in a database. Deserialization is the reverse process. For a class to be serializable, it must implement the <code>Serializable</code> marker interface (an interface with no methods).</p><pre><code class="language-java">import java.io.*;

// The class must implement Serializable
class Person implements Serializable {
    private static final long serialVersionUID = 1L; // Recommended for version control
    String name;
    int age;

    Person(String name, int age) { this.name = name; this.age = age; }
}

public class SerializationExample {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);

        // Serialize
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
            oos.writeObject(person);
        } catch (IOException e) { e.printStackTrace(); }

        // Deserialize
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
            Person deserializedPerson = (Person) ois.readObject();
            System.out.println(deserializedPerson.name + ", " + deserializedPerson.age); // Output: Alice, 30
        } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }
    }
}
</code></pre><h2>11. Multithreading</h2><p>Multithreading is a Java feature that allows concurrent execution of two or more parts of a program to maximize CPU utilization. Each part is called a thread.</p><h3>Creating Threads</h3><p>There are two primary ways to create a thread in Java.</p><p><strong>Extending the Thread Class:</strong> Create a subclass of <code>Thread</code> and override its <code>run()</code> method. Then, create an instance of this subclass and call its <code>start()</code> method.</p><pre><code class="language-java">class MyThread extends Thread {
    public void run() {
        System.out.println("Thread running: " + Thread.currentThread().getName());
    }
}
// Usage
MyThread t1 = new MyThread();
t1.start(); // start() automatically calls run() in a new thread</code></pre><p><strong>Implementing the Runnable Interface (Preferred):</strong> Create a class that implements the <code>Runnable</code> interface and its <code>run()</code> method. Then, pass an instance of this class to a <code>Thread</code> object's constructor and call <code>start()</code>. This is preferred because Java supports single inheritance, so implementing <code>Runnable</code> allows your class to extend another class if needed.</p><pre><code class="language-java">class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable thread running: " + Thread.currentThread().getName());
    }
}
// Usage
Thread t2 = new Thread(new MyRunnable());
t2.start();


</code></pre><h3>Thread Lifecycle</h3><p>A thread can be in one of several states during its lifetime.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Thread_Life_Cycle_d732321c1f.png" alt="Thread Life Cycle" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Thread_Life_Cycle_d732321c1f.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Thread_Life_Cycle_d732321c1f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Thread_Life_Cycle_d732321c1f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Thread_Life_Cycle_d732321c1f.png 1000w," sizes="100vw"><figcaption>Thread Life Cycle</figcaption></figure><ol><li><strong>New:</strong> A thread is created but not yet started (<code>new Thread()</code>).</li><li><strong>Runnable:</strong> After calling <code>start()</code>, the thread is ready to run and waiting for CPU time.</li><li><strong>Blocked/Waiting:</strong> The thread is alive but not eligible to run. It is waiting for a monitor lock (blocked) or for another thread to perform an action (waiting).</li><li><strong>Timed Waiting:</strong> A version of waiting with a specified waiting time (e.g., <code>Thread.sleep(1000)</code>, <code>wait(5000)</code>).</li><li><strong>Terminated:</strong> The thread's <code>run()</code> method has completed, and it is no longer alive.</li></ol><h3>Synchronization</h3><p>When multiple threads access shared resources (like an object's variable), it can lead to data inconsistency. Synchronization is the mechanism that ensures that only one thread can access the resource at a time. This is achieved using the <code>synchronized</code> keyword.</p><pre><code class="language-java">public class Counter {
    private int count = 0;

    // Synchronized method - only one thread can execute this method at a time per object
    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

// In a multi-threaded scenario, this prevents race conditions
</code></pre><h3>Executor Framework</h3><p>Introduced in Java 5, the Executor Framework provides a higher-level replacement for working with threads directly. It manages a pool of threads, handles their lifecycle, and allows you to submit tasks for asynchronous execution. This is more efficient and manageable than creating new threads for every task.</p><pre><code class="language-java">import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorExample {
    public static void main(String[] args) {
        // Create a fixed thread pool with 5 threads
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // Submit tasks (Runnable) for execution
        for (int i = 0; i &lt; 10; i++) {
            Runnable task = () -&gt; {
                System.out.println("Executing task in " + Thread.currentThread().getName());
            };
            executor.submit(task);
        }

        // Important: Shut down the executor so the application can terminate
        executor.shutdown();
    }
}
</code></pre><h2>12. Java 8 Features</h2><p>Java 8 was a landmark release, introducing significant features that brought functional programming concepts to the language.</p><h3>Lambda Expressions</h3><p>A lambda expression is a short block of code that takes in parameters and returns a value. It provides a clear and concise way to represent an instance of a functional interface. It enables you to treat functionality as a method argument.</p><pre><code class="language-java">// Old way using an anonymous inner class
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Old way");
    }
};

// New way using a lambda expression
Runnable r2 = () -&gt; System.out.println("Lambda way");
</code></pre><h3>Functional Interfaces</h3><p>A functional interface is an interface that has exactly one abstract method. They can have multiple default or static methods, but only one abstract method. Lambda expressions rely on these interfaces. Common examples include <code>Runnable</code>, <code>Callable</code>, <code>Comparator</code>, and those in the <code>java.util.function</code> package like <code>Predicate</code>, <code>Function</code>, and <code>Consumer</code>. The <code>@FunctionalInterface</code> annotation is used to declare an interface as functional.</p><pre><code class="language-java">@FunctionalInterface
interface MathOperation {
    int operate(int a, int b); // Single abstract method
}

// Lambda implementing the interface
MathOperation addition = (a, b) -&gt; a + b;
int result = addition.operate(5, 3); // 8
</code></pre><h3>Streams API</h3><p>The Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. The key idea is to perform operations on data in a declarative way, similar to SQL queries. Streams do not store data; they operate on the source data structure (like a collection) and may also produce a result.</p><pre><code class="language-java">List&lt;String&gt; names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Alex");

List&lt;String&gt; result = names.stream()                // Create a stream from the list
        .filter(name -&gt; name.startsWith("A"))      // Intermediate operation: keep names starting with 'A'
        .map(String::toUpperCase)                   // Intermediate operation: convert to uppercase
        .sorted()                                    // Intermediate operation: sort
        .collect(Collectors.toList());               // Terminal operation: collect results into a list

System.out.println(result); // Output: [ALEX, ALICE]
</code></pre><h3>Method References</h3><p>Method references are shorthand for lambda expressions when you are simply calling an existing method. They make the code even more concise. They use the <code>::</code> operator.</p><ul><li><strong>Static Method:</strong> <code>ClassName::staticMethodName</code> (e.g., <code>Math::max</code>)</li><li><strong>Instance Method of a particular object:</strong> <code>instance::instanceMethodName</code> (e.g., <code>list::add</code>)</li><li><strong>Instance Method of an arbitrary object of a particular type:</strong> <code>ClassName::instanceMethodName</code> (e.g., <code>String::toUpperCase</code> used in the Streams example)</li><li><strong>Constructor:</strong> <code>ClassName::new</code></li></ul><h3>Optional</h3><p><code>Optional</code> is a container object used to represent a value that may or may not be present. It helps in avoiding <code>NullPointerException</code> by forcing the programmer to think about and handle the case of a missing value. Instead of returning <code>null</code>, a method can return an <code>Optional</code>.</p><pre><code class="language-java">public Optional&lt;String&gt; findUserNameById(int id) {
    // ... logic that might find a user
    if (found) {
        return Optional.of(userName); // Wrap the found value
    } else {
        return Optional.empty(); // Return an empty Optional
    }
}

// Using the Optional
Optional&lt;String&gt; result = findUserNameById(123);
String name = result.orElse("Default User"); // Provide a default if not found
result.ifPresent(System.out::println); // Only print if present
</code></pre><h3>Date and Time API (java.time)</h3><p>The new Date and Time API (JSR 310) in <code>java.time</code> package is a massive improvement over the old, flawed <code>java.util.Date</code> and <code>java.util.Calendar</code>. The new classes are immutable and thread-safe.</p><pre><code class="language-java">import java.time.*;
import java.time.format.DateTimeFormatter;

// Getting current date and time
LocalDate today = LocalDate.now();          // 2024-05-21 (example)
LocalTime now = LocalTime.now();            // 10:15:30.123
LocalDateTime currentDateTime = LocalDateTime.now();

// Creating specific dates
LocalDate specificDate = LocalDate.of(2025, Month.DECEMBER, 25);
LocalTime specificTime = LocalTime.of(14, 30);

// Formatting and Parsing
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String formattedDate = today.format(formatter); // "21/05/2024"
LocalDate parsedDate = LocalDate.parse("25/12/2024", formatter);

// Date arithmetic
LocalDate nextWeek = today.plusWeeks(1);
LocalDate lastMonth = today.minusMonths(1);
</code></pre><h2>13. JVM Internals</h2><p>Understanding the internals of the JVM helps in writing better-performing code and debugging issues like memory leaks and performance bottlenecks.</p><h3>ClassLoader</h3><p>The ClassLoader is a part of the JVM that loads <code>.class</code> files from the file system, network, or other sources into memory. It works on three core principles: delegation, visibility, and uniqueness. The main class loaders are:</p><ol><li><strong>Bootstrap ClassLoader:</strong> The root class loader. It loads core Java API classes from the <code>core Java modules</code>and other core jars present in the <code>JAVA_HOME/jre/lib</code> directory.</li><li><strong>Extension ClassLoader:</strong> It loads classes from the <code>jre/lib/ext</code> directory or any other directory specified by the <code>java.ext.dirs</code> system property.</li><li><strong>System/Application ClassLoader:</strong> It loads classes from the application classpath, which includes your project's classes and any JAR files you have included.</li></ol><h3>Heap vs Stack</h3><p>Memory in the JVM is divided into several areas, with the two most important being the Heap and the Stack.</p><figure class="table"><table><thead><tr><th>Feature</th><th>Stack</th><th>Heap</th></tr></thead><tbody><tr><td><strong>What it stores</strong></td><td>Primitive local variables, object references (pointers), and method calls (stack frames).</td><td>All objects and their instance variables.</td></tr><tr><td><strong>Memory Type</strong></td><td>Memory per thread. Each thread has its own private stack.</td><td>Memory shared across all threads of an application.</td></tr><tr><td><strong>Access Speed</strong></td><td>Fast access (LIFO structure).</td><td>Slower access compared to the stack.</td></tr><tr><td><strong>Lifecycle</strong></td><td>A stack frame is created when a method is called and destroyed when the method completes.</td><td>Objects live until they are no longer referenced and are garbage collected.</td></tr><tr><td><strong>Size &amp; Error</strong></td><td>Size is typically fixed per thread. A deep recursion can cause <code>StackOverflowError</code>.</td><td>Size can grow. If the heap is full, you may get <code>OutOfMemoryError</code>.</td></tr></tbody></table></figure><h3>Garbage Collection (GC)</h3><p>Garbage Collection is the automatic process of identifying and discarding objects that are no longer needed by a program (objects with no live references) to reclaim memory. This frees the developer from manual memory management.</p><ul><li><strong>How it works (basic idea):</strong> GC roots (like local variables, static variables) are identified. The garbage collector then traverses all references from these roots. Any objects reachable from a root are marked as "live." The rest are considered garbage.</li><li><strong>Generational GC:</strong> Most JVMs use a generational approach because it has been observed that most objects die young. The heap is divided into generations:<ul><li><strong>Young Generation:</strong> Where new objects are allocated. GC here (Minor GC) is fast and frequent.</li><li><strong>Old Generation:</strong> Objects that have survived several GC cycles in the young generation are promoted here. GC here (Major/Full GC) is slower and less frequent.</li><li><strong>Metaspace (replacing PermGen):</strong> Stores class metadata.</li></ul></li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Garbage_Collection_7bf736e5da.png" alt="Garbage Collection" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Garbage_Collection_7bf736e5da.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Garbage_Collection_7bf736e5da.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Garbage_Collection_7bf736e5da.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Garbage_Collection_7bf736e5da.png 1000w," sizes="100vw"><figcaption>Garbage Collection</figcaption></figure><h3>JIT (Just-In-Time) Compiler</h3><p>The JVM initially interprets the bytecode, which can be slow. To improve performance, the JIT compiler comes into play. It monitors the code being executed and identifies "hot spots"—sections of code that are run very frequently. The JIT compiler then compiles these hot spots into native machine code. This native code is cached and executed directly by the processor, bypassing the interpreter, leading to massive performance gains. This is why a Java program can become faster as it runs.</p><h2>Conclusion</h2><p>This Core Java cheat sheet provides a structured overview of the most important concepts every Java developer should understand. From the fundamentals of the language and object-oriented programming to collections, multithreading, and JVM internals, it serves as a quick reference for both beginners and experienced developers. Use it to quickly revise key topics and strengthen your Java foundation. If you found this cheat sheet helpful, consider sharing it with your friends or fellow developers who might benefit from it as well.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>Java</category>
            <category>OOP</category>
            <category>Collections Framework</category>
            <category>Exception Handling</category>
            <category>Multithreading</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Core_Java_In_One_Shot_Thumbnail_5515867eb0.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Advanced Java in One Shot – Ultimate Cheat Sheet]]></title>
            <link>https://www.codingshuttle.com/blogs/advanced-java-in-one-shot-ultimate-cheat-sheet</link>
            <guid>https://www.codingshuttle.com/blogs/advanced-java-in-one-shot-ultimate-cheat-sheet</guid>
            <pubDate>Mon, 02 Mar 2026 13:49:05 GMT</pubDate>
            <description><![CDATA[A quick and clear revision guide to how Java web applications were built before Spring — using Servlets, JSP, JDBC, and core Java EE concepts.

Perfect for interviews, exams, and strengthening your backend fundamentals.]]></description>
            <content:encoded><![CDATA[<p>Advanced Java in One Shot – The Ultimate Cheat Sheet</p><p><strong>Advanced Java in One Shot – The Ultimate Cheat Sheet</strong> is a quick reference covering key Technologies used to build Java web applications such as JDBC, Servlets, JSP, and common design patterns. It helps developers and students quickly revise how Java web applications are built and how these technologies work together in real-world projects.</p><h2>JDBC (Java Database Connectivity)</h2><h3>What is JDBC?</h3><p>JDBC is an API that enables Java applications to interact with relational databases. It provides methods for querying, updating, and managing data across different database systems.</p><h3>JDBC Architecture</h3><p>The architecture consists of:</p><ul><li><strong>Java Application</strong> – Your code using JDBC API</li><li><strong>JDBC Driver Manager</strong> – DriverManager manages registered JDBC drivers and selects the appropriate driver to establish a database connection.</li><li><strong>JDBC Driver</strong> – Database-specific implementation</li><li><strong>Database</strong> – The actual data source</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/JDBC_Architecture_60bd2056d7.png" alt="JDBC Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_JDBC_Architecture_60bd2056d7.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_JDBC_Architecture_60bd2056d7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_JDBC_Architecture_60bd2056d7.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_JDBC_Architecture_60bd2056d7.png 1000w," sizes="100vw"><figcaption>JDBC Architecture</figcaption></figure><h3>Types of JDBC Drivers</h3><figure class="table"><table><thead><tr><th>Driver Type</th><th>Description</th><th>Use Case</th></tr></thead><tbody><tr><td>Type 1: JDBC-ODBC Bridge</td><td>Converts JDBC calls to ODBC</td><td>Legacy systems, not recommended</td></tr><tr><td>Type 2: Native-API</td><td>Uses database client libraries</td><td>Performance critical apps</td></tr><tr><td>Type 3: Network Protocol</td><td>Middleware server converts calls</td><td>Multi-database environments</td></tr><tr><td>Type 4: Thin Driver</td><td>Pure Java, direct DB connection</td><td>Most common for modern apps</td></tr></tbody></table></figure><h3>Core Components</h3><p><strong>DriverManager</strong></p><ul><li>Manages list of database drivers</li><li>Establishes connection using <code>getConnection()</code></li></ul><p><strong>Connection</strong></p><ul><li>Represents session with database</li><li>Creates statements, manages transactions</li></ul><p><strong>Statement</strong></p><ul><li>Executes static SQL queries</li><li>Vulnerable to SQL injection</li></ul><p><strong>PreparedStatement</strong></p><ul><li>Precompiled SQL with parameters</li><li>Prevents SQL injection</li><li>Better performance for repeated queries</li></ul><p><strong>CallableStatement</strong></p><ul><li>Executes stored procedures</li><li>Supports IN/OUT parameters</li></ul><p><strong>ResultSet</strong></p><ul><li>Represents query results</li><li>Provides cursor to navigate data</li></ul><h3>Database Operations – CRUD Example</h3><pre><code class="language-java">// 1. Load driver (optional for modern JDBC)
Class.forName("com.mysql.cj.jdbc.Driver");

// 2. Create connection
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/mydb", "user", "password");

// 3. Create statement
PreparedStatement pstmt = conn.prepareStatement(
    "INSERT INTO users (name, email) VALUES (?, ?)");
pstmt.setString(1, "John Doe");
pstmt.setString(2, "john@example.com");

// 4. Execute
int rows = pstmt.executeUpdate();

// 5. Process results (for queries)
ResultSet rs = pstmt.executeQuery("SELECT * FROM users");
while(rs.next()) {
    System.out.println(rs.getString("name"));
}

// 6. Close resources
rs.close();
pstmt.close();
conn.close();
</code></pre><h3>Statement vs PreparedStatement</h3><figure class="table"><table><thead><tr><th>Feature</th><th>Statement</th><th>PreparedStatement</th></tr></thead><tbody><tr><td>Performance</td><td>Slower for repeated queries</td><td>Faster, precompiled</td></tr><tr><td>SQL Injection</td><td>Vulnerable</td><td>Protected</td></tr><tr><td>Parameter Handling</td><td>String concatenation</td><td>Type-safe setters</td></tr><tr><td>Binary Data</td><td>Difficult</td><td>Easy with setBinaryStream()</td></tr><tr><td>Use Case</td><td>One-time DDL queries</td><td>Repeated or user-input queries</td></tr></tbody></table></figure><h3>Batch Processing</h3><pre><code class="language-java">PreparedStatement pstmt = conn.prepareStatement(
    "INSERT INTO products VALUES (?, ?)");
for(Product p : productList) {
    pstmt.setInt(1, p.getId());
    pstmt.setString(2, p.getName());
    pstmt.addBatch();
}
int[] results = pstmt.executeBatch();
</code></pre><h3>Transaction Management</h3><pre><code class="language-java">conn.setAutoCommit(false);
try {
    // multiple operations
    pstmt1.executeUpdate();
    pstmt2.executeUpdate();
    conn.commit();
} catch(SQLException e) {
    conn.rollback();
} finally {
    conn.setAutoCommit(true);
}
</code></pre><h3>Connection Pooling</h3><ul><li>Reuses database connections to improve performance</li><li>Common libraries: HikariCP, Apache DBCP</li><li>Configure pool size, timeout, and validation</li></ul><h3>Stored Procedures with CallableStatement</h3><pre><code class="language-java">CallableStatement cstmt = conn.prepareCall(
    "{call getUserCount(?)}");
cstmt.registerOutParameter(1, Types.INTEGER);
cstmt.execute();
int count = cstmt.getInt(1);
</code></pre><h3>Metadata</h3><p><strong>DatabaseMetaData</strong> – Information about database itself</p><pre><code class="language-java">DatabaseMetaData dbmd = conn.getMetaData();
String product = dbmd.getDatabaseProductName();
</code></pre><p><strong>ResultSetMetaData</strong> – Information about result columns</p><pre><code class="language-java">ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
String colName = rsmd.getColumnName(1);
</code></pre><hr><h2>Servlets</h2><h3>What is a Servlet?</h3><p>A Java program that runs on a web server and handles client requests, generating dynamic web content.</p><h3>Servlet Architecture</h3><ol><li>Client sends HTTP request</li><li>Web container loads servlet (if needed)</li><li>The container uses a thread pool to process requests concurrently.</li><li>Servlet processes request and generates response</li><li>Response sent back to client</li></ol><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Http_Request_flow_ac4992fe7b.png" alt="Http Request flow " srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Http_Request_flow_ac4992fe7b.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Http_Request_flow_ac4992fe7b.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Http_Request_flow_ac4992fe7b.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Http_Request_flow_ac4992fe7b.png 1000w," sizes="100vw"><figcaption>Http Request flow&nbsp;</figcaption></figure><h3>Servlet Lifecycle</h3><figure class="table"><table><thead><tr><th>Stage</th><th>Method</th><th>Description</th></tr></thead><tbody><tr><td>Initialization</td><td><code>init()</code></td><td>Called once when servlet is first loaded</td></tr><tr><td>Request Handling</td><td><code>service()</code></td><td>Dispatches to doGet/doPost methods</td></tr><tr><td>Destruction</td><td><code>destroy()</code></td><td>Called once when servlet is unloaded</td></tr></tbody></table></figure><h3>Core HTTP Methods</h3><pre><code class="language-java">protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
        throws ServletException, IOException {
    // Handle GET requests
    resp.getWriter().println("Response from GET");
}

protected void doPost(HttpServletRequest req,
                     HttpServletResponse resp)
                     throws ServletException, IOException{
}

protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // Handle PUT requests
}

protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // Handle DELETE requests
}
</code></pre><h3>Handling Request Parameters</h3><pre><code class="language-java">// Single value
String name = req.getParameter("username");

// Multiple values (checkboxes)
String[] hobbies = req.getParameterValues("hobby");

// All parameters
Enumeration&lt;String&gt; params = req.getParameterNames();
</code></pre><h3>RequestDispatcher – Forward vs Include</h3><p><strong>Forward</strong>: Transfer control completely</p><pre><code class="language-java">RequestDispatcher rd = req.getRequestDispatcher("target.jsp");
rd.forward(req, resp);
</code></pre><p><strong>Include</strong>: Include content then continue</p><pre><code class="language-java">RequestDispatcher rd = req.getRequestDispatcher("header.jsp");
rd.include(req, resp);
</code></pre><h3>Session Management Techniques</h3><figure class="table"><table><thead><tr><th>Technique</th><th>How it Works</th><th>Best For</th></tr></thead><tbody><tr><td>Cookies</td><td>Small data stored on client</td><td>Remembering preferences</td></tr><tr><td>HttpSession</td><td>Server-side storage with session ID</td><td>Shopping carts, user data</td></tr><tr><td>URL Rewriting</td><td>Session ID appended to URLs</td><td>When cookies are disabled</td></tr></tbody></table></figure><p><strong>HttpSession Example</strong></p><pre><code class="language-java">// Create/get session
HttpSession session = req.getSession(true);

// Store data
session.setAttribute("user", userObject);

// Retrieve data
User user = (User) session.getAttribute("user");

// Invalidate
session.invalidate();
</code></pre><p><strong>Cookie Example</strong></p><pre><code class="language-java">// Create cookie
Cookie cookie = new Cookie("theme", "dark");
cookie.setMaxAge(3600);
resp.addCookie(cookie);

// Read cookies
Cookie[] cookies = req.getCookies();
</code></pre><h3>Servlet Configuration</h3><p><strong>web.xml approach</strong></p><pre><code class="language-xml">&lt;servlet&gt;
    &lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.example.MyServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
    &lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/myservlet&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</code></pre><p><strong>Annotation approach (Servlet 3.0+)</strong></p><pre><code class="language-java">@WebServlet(
    name = "MyServlet",
    urlPatterns = {"/myservlet", "/test/*"},
    initParams = {@WebInitParam(name="config", value="dev")}
)
public class MyServlet extends HttpServlet { }
</code></pre><h3>Servlet Filters</h3><p>Intercept requests before they reach servlet and responses before they reach client.</p><pre><code class="language-java">@WebFilter("/secure/*")
public class AuthFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse resp,
                         FilterChain chain) {
        // Pre-processing
        if(isAuthenticated) {
            chain.doFilter(req, resp); // Continue
        } else {
            // Redirect to login
        }
        // Post-processing
    }
}
</code></pre><p>Common uses: Authentication, Logging, Compression, Encryption</p><h3>Servlet Listeners</h3><p>Monitor events in servlet context, session, and requests.</p><pre><code class="language-java">@WebListener
public class AppListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        // Initialize resources when app starts
    }
    public void contextDestroyed(ServletContextEvent sce) {
        // Cleanup when app stops
    }
}
</code></pre><hr><h2>JSP (JavaServer Pages)</h2><h3>What is JSP?</h3><p>A server-side technology that allows embedding Java code directly into HTML pages. JSPs are translated into servlets during runtime.</p><h3>JSP Lifecycle</h3><ol><li>Translation – JSP converted to servlet</li><li>Compilation – Servlet compiled to class</li><li>Loading – Class loaded into container</li><li>Initialization – <code>jspInit()</code> called</li><li>Request Processing – <code>_jspService()</code> handles requests</li><li>Destruction – <code>jspDestroy()</code> called</li></ol><h3>JSP vs Servlets</h3><figure class="table"><table><thead><tr><th>Aspect</th><th>JSP</th><th>Servlet</th></tr></thead><tbody><tr><td>Primary Use</td><td>Presentation layer</td><td>Business logic layer</td></tr><tr><td>Code Focus</td><td>HTML with embedded Java</td><td>Java with embedded HTML</td></tr><tr><td>Design</td><td>Easier for UI designers</td><td>Better for developers</td></tr><tr><td>Performance</td><td>Slightly slower (translation)</td><td>Faster (direct Java)</td></tr><tr><td>Separation</td><td>Mixes logic and presentation</td><td>Can separate better with MVC</td></tr></tbody></table></figure><h3>JSP Elements</h3><p><strong>Scriptlets</strong> – Blocks of Java code</p><pre><code class="language-plaintext">&lt;%
    String name = request.getParameter("name");
    if(name != null) {
        out.println("Hello " + name);
    }
%&gt;
</code></pre><p><strong>Expressions</strong> – Output values directly</p><pre><code class="language-plaintext">&lt;%= new java.util.Date() %&gt;
&lt;%= user.getName() %&gt;
</code></pre><p><strong>Declarations</strong> – Define methods/variables</p><pre><code class="language-plaintext">&lt;%!
    private int counter = 0;
    public String getMessage() {
        return "Count: " + counter++;
    }
%&gt;
</code></pre><h3>Directives</h3><p><strong>Page directive</strong> – Configuration for JSP</p><pre><code class="language-plaintext">&lt;%@ page language="java" contentType="text/html" %&gt;
&lt;%@ page import="java.util.*, com.example.*" %&gt;
&lt;%@ page errorPage="error.jsp" %&gt;
&lt;%@ page isELIgnored="false" %&gt;
</code></pre><p><strong>Include directive</strong> – Include file at translation time</p><pre><code class="language-plaintext">&lt;%@ include file="header.html" %&gt;
</code></pre><p><strong>Taglib directive</strong> – Declare custom tag libraries</p><pre><code class="language-plaintext">&lt;%@ taglib uri="&lt;http://java.sun.com/jsp/jstl/core&gt;" prefix="c" %&gt;
</code></pre><h3>JSP Standard Actions</h3><pre><code class="language-plaintext">&lt;!-- Include content at runtime --&gt;
&lt;jsp:include page="header.jsp"&gt;
    &lt;jsp:param name="title" value="Home" /&gt;
&lt;/jsp:include&gt;

&lt;!-- Forward to another page --&gt;
&lt;jsp:forward page="login.jsp" /&gt;

&lt;!-- Use JavaBeans --&gt;
&lt;jsp:useBean id="user" class="com.example.User" scope="session" /&gt;
&lt;jsp:setProperty name="user" property="name" value="John" /&gt;
&lt;jsp:getProperty name="user" property="name" /&gt;
</code></pre><h3>JSTL (JSP Standard Tag Library)</h3><p><strong>Core tags</strong> – Flow control, loops</p><pre><code class="language-plaintext">&lt;c:if test="${not empty user}"&gt;
    Welcome ${user.name}
&lt;/c:if&gt;

&lt;c:forEach items="${products}" var="product"&gt;
    ${product.name} - ${product.price}
&lt;/c:forEach&gt;

&lt;c:choose&gt;
    &lt;c:when test="${role == 'admin'}"&gt;Admin Panel&lt;/c:when&gt;
    &lt;c:otherwise&gt;User Dashboard&lt;/c:otherwise&gt;
&lt;/c:choose&gt;
</code></pre><p><strong>Formatting tags</strong> – Dates, numbers</p><pre><code class="language-plaintext">&lt;fmt:formatDate value="${date}" pattern="yyyy-MM-dd" /&gt;
&lt;fmt:formatNumber value="${price}" type="currency" /&gt;
</code></pre><h3>Expression Language (EL)</h3><p>Simplifies data access in JSP without scriptlets.</p><pre><code class="language-plaintext">&lt;!-- Access request parameters --&gt;
${param.username}

&lt;!-- Access bean properties --&gt;
${user.address.city}

&lt;!-- Access collection elements --&gt;
${products[0].name}

&lt;!-- Arithmetic operations --&gt;
Total: ${price * quantity + tax}

&lt;!-- Conditional checks --&gt;
${empty cart ? "Cart is empty" : cart.size()}
</code></pre><hr><h2>Java Design Patterns</h2><h3>Why Design Patterns?</h3><ul><li>Provide proven solutions to common problems</li><li>Improve code reusability and maintainability</li><li>Establish common vocabulary among developers</li><li>Reduce development time and errors</li></ul><h3>Creational Patterns</h3><p><strong>Singleton Pattern</strong> Ensures only one instance of a class exists.</p><pre><code class="language-java">public class DatabaseConnection {
    private static volatile DatabaseConnection instance;

    private DatabaseConnection() { }

    public static DatabaseConnection getInstance() {
        if(instance == null) {
            synchronized(DatabaseConnection.class) {
                if(instance == null) {
                    instance = new DatabaseConnection();
                }
            }
        }
        return instance;
    }
}
</code></pre><p><strong>Used in:</strong> Connection pools, configuration managers, logging</p><p><strong>Factory Pattern</strong> Creates objects without specifying exact class.</p><pre><code class="language-java">interface Database {
    void connect();
}

class MySQLDatabase implements Database { }
class OracleDatabase implements Database { }

class DatabaseFactory {
    public static Database createDatabase(String type) {
        if(type.equals("mysql")) return new MySQLDatabase();
        if(type.equals("oracle")) return new OracleDatabase();
        return null;
    }
}
</code></pre><p><strong>Used in:</strong> Creating different database connections, UI components</p><p><strong>Builder Pattern</strong> Constructs complex objects step by step.</p><pre><code class="language-java">User user = new User.Builder()
    .setName("John")
    .setEmail("john@email.com")
    .setAge(30)
    .build();
</code></pre><p><strong>Used in:</strong> Creating objects with many optional parameters, immutable objects</p><h3>Structural Patterns</h3><p><strong>Adapter Pattern</strong> Allows incompatible interfaces to work together.</p><pre><code class="language-java">interface NewSystem {
    void process();
}

class LegacySystem {
    void oldProcess() { }
}

class Adapter implements NewSystem {
    private LegacySystem legacy;

    public void process() {
        legacy.oldProcess();
    }
}
</code></pre><p><strong>Used in:</strong> Integrating legacy code, third-party libraries</p><p><strong>Decorator Pattern</strong> Adds responsibilities to objects dynamically.</p><pre><code class="language-java">interface Coffee { double cost(); }

class SimpleCoffee implements Coffee {
    public double cost() { return 2.0; }
}

class MilkDecorator implements Coffee {
    private Coffee coffee;
    MilkDecorator(Coffee c) { coffee = c; }
    public double cost() { return coffee.cost() + 0.5; }
}
</code></pre><p><strong>Used in:</strong> Java I/O streams, GUI components</p><p><strong>Facade Pattern</strong> Provides simplified interface to complex subsystem.</p><pre><code class="language-java">class OrderFacade {
    private Inventory inv = new Inventory();
    private Payment pay = new Payment();
    private Shipping ship = new Shipping();

    public void placeOrder(Order o) {
        inv.checkStock(o);
        pay.process(o);
        ship.shipOrder(o);
    }
}
</code></pre><p><strong>Used in:</strong> Simplifying complex APIs, service layers</p><h3>Behavioral Patterns</h3><p><strong>Observer Pattern</strong> Notifies dependents when state changes.</p><pre><code class="language-java">interface Observer { void update(String data); }

class Subject {
    List&lt;Observer&gt; observers = new ArrayList&lt;&gt;();

    void addObserver(Observer o) { observers.add(o); }
    void notifyObservers(String data) {
        for(Observer o : observers) o.update(data);
    }
}
</code></pre><p><strong>Used in:</strong> Event handling, messaging systems, MVC architecture</p><p><strong>Strategy Pattern</strong> Encapsulates interchangeable algorithms.</p><pre><code class="language-java">interface PaymentStrategy {
    void pay(double amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(double amount) { /* process card */ }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(double amount) { /* process paypal */ }
}
</code></pre><p><strong>Used in:</strong> Payment processing, sorting algorithms, validation rules</p><p><strong>Command Pattern</strong> Encapsulates requests as objects.</p><pre><code class="language-java">interface Command { void execute(); }

class LightOnCommand implements Command {
    private Light light;
    public void execute() { light.turnOn(); }
}
</code></pre><p><strong>Used in:</strong> Undo/redo functionality, task queues, transaction management</p><h3>Design Patterns Summary</h3><figure class="table"><table><thead><tr><th>Pattern</th><th>Category</th><th>Purpose</th><th>Common Use</th></tr></thead><tbody><tr><td>Singleton</td><td>Creational</td><td>Single instance</td><td>Connection pools</td></tr><tr><td>Factory</td><td>Creational</td><td>Object creation abstraction</td><td>Database drivers</td></tr><tr><td>Builder</td><td>Creational</td><td>Step-by-step construction</td><td>Complex objects</td></tr><tr><td>Adapter</td><td>Structural</td><td>Interface compatibility</td><td>Legacy code integration</td></tr><tr><td>Decorator</td><td>Structural</td><td>Dynamic behavior addition</td><td>I/O streams</td></tr><tr><td>Facade</td><td>Structural</td><td>Simplified interface</td><td>Service layers</td></tr><tr><td>Observer</td><td>Behavioral</td><td>State change notification</td><td>Event handling</td></tr><tr><td>Strategy</td><td>Behavioral</td><td>Interchangeable algorithms</td><td>Payment methods</td></tr><tr><td>Command</td><td>Behavioral</td><td>Request as object</td><td>Undo operations</td></tr></tbody></table></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Design_Patterns_3614c1791f.png" alt="Design Patterns" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Design_Patterns_3614c1791f.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Design_Patterns_3614c1791f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Design_Patterns_3614c1791f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Design_Patterns_3614c1791f.png 1000w," sizes="100vw"><figcaption>Design Patterns</figcaption></figure><h2><strong>Conclusion</strong></h2><p>Advanced Java builds the foundation for Java web applications using technologies like JDBC, Servlets, and JSP, along with important design patterns for better code structure. This cheat sheet provides a quick reference to revise the key concepts in one place. If you found it useful, consider sharing it with others learning Advanced Java.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreyash Gurav)</author>
            <category>JavaEE</category>
            <category>Servlets</category>
            <category>JSP</category>
            <category>JDBC</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Java_in_one_shot_thumbnail_87bf3d0532.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[He Was Not From Tech. He Did Not Let That Stop Him.]]></title>
            <link>https://www.codingshuttle.com/blogs/he-was-not-from-tech-he-did-not-let-that-stop-him</link>
            <guid>https://www.codingshuttle.com/blogs/he-was-not-from-tech-he-did-not-let-that-stop-him</guid>
            <pubDate>Wed, 18 Feb 2026 11:16:36 GMT</pubDate>
            <description><![CDATA[No CS degree? No problem. Discover how Debjeet Roy balanced a full-time role at Genpact with rigorous DSA training to land a dream developer role at Standard Chartered.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Debjeet Roy had a stable career going for him. As a Principle Consultant at Genpact, he was doing well by most standards. But something kept pulling him toward technology, toward building things, toward the kind of work that felt like the future. He was not from an IT background. He had no computer science degree to fall back on. What he had was the willingness to start from scratch, even if that meant sitting down to learn Data Structures and Algorithms while managing a full-time consulting job.</p><p>That decision changed everything.</p><h2><br>The Point Where Things Had to Change</h2><p>Switching into tech from a non-IT background is not a weekend project. It requires months of consistent effort, and it requires doing that work while life continues around you. Debjeet enrolled in Coding Shuttle's DSA Course and committed to the process fully. Weekdays belonged to Genpact. Weekends belonged to learning. He showed up to doubt sessions, submitted assignments before deadlines, and kept pushing through the parts of DSA that most people quietly quit on.</p><p>The discipline he built during this period was not just about algorithms. It was about proving to himself that he could do it.</p><h2><br>Where Coding Shuttle Came In</h2><p>The structure of Coding Shuttle's DSA program was exactly what Debjeet needed. The deadlines were strict and intentional, pushing students to take the course seriously rather than treat it as background content they would get to someday. Weekend doubt sessions gave him a space to ask the questions he had been sitting with all week. And Anuj's way of explaining concepts made topics that looked intimidating on paper feel completely manageable in practice.</p><p>For someone coming in from outside the industry, that combination of accountability and clarity made all the difference.</p><h2><br>In Debjeet's Own Words</h2><p><i>"It was a great learning experience altogether, specially deadline part which compelled us to complete our tasks before deadline and doubt class session on weekends helped cleared lot of our doubts. I am very thankful to Anuj for explaining all the concepts in a very easy manner that anybody can understand."</i></p><h2><br>Where He Stands Today</h2><p>Debjeet Roy is now a Senior Product Developer at Standard Chartered, one of the world's most respected banking institutions. He went from being a consultant with no IT background to building products at a global bank. The career he wanted was on the other side of a difficult, intentional period of learning and he walked straight through it.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Debjeet_Roy_51fdaaed75.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Senior Engineer to Lead Developer: What Happens When You Refuse to Plateau]]></title>
            <link>https://www.codingshuttle.com/blogs/senior-engineer-to-lead-developer-what-happens-when-you-refuse-to-plateau</link>
            <guid>https://www.codingshuttle.com/blogs/senior-engineer-to-lead-developer-what-happens-when-you-refuse-to-plateau</guid>
            <pubDate>Wed, 18 Feb 2026 11:15:41 GMT</pubDate>
            <description><![CDATA[From Senior Engineer to Lead Developer at Standard Chartered: Discover how Anil Suryaprakash used Coding Shuttle’s Spring Boot course to master enterprise architecture and transition into banking tech.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Anil Suryaprakash had already made it to Senior Software Engineer. For a lot of people, that is where the ambition starts to quiet down. Not for Anil. He looked at where he was at MILVIK and decided he wanted more, not in a restless or dissatisfied way, but in the way that serious engineers think about their growth. He wanted to lead, not just contribute. And to do that, he knew his technical foundation needed to be stronger than it already was.</p><h2><br>The Point Where Things Had to Change</h2><p>Getting from Senior Engineer to Lead Developer is not just about time served. Companies like Standard Chartered do not hand out lead roles based on experience alone. They look for engineers who have a command over the frameworks that power enterprise systems. Anil identified Spring Boot as the skill that would separate him from the competition and enrolled in Coding Shuttle's Spring Boot Course while still working full-time at MILVIK.</p><p>That kind of deliberate, forward-looking decision is what distinguishes engineers who grow from those who stagnate.</p><h2><br>Where Coding Shuttle Came In</h2><p>Coding Shuttle's Spring Boot program gave Anil the structured, end-to-end coverage he was looking for. Coming from a non-IT transition background, there were gaps he needed to close before he could confidently claim deep expertise. The course bridged those gaps systematically, covering REST APIs, microservices, Spring Security, and everything a lead-level backend engineer is expected to know and use on the job.</p><h2><br>In Anil's Own Words</h2><p>“Great course. Highly recommended to anyone looking to master Spring Boot in a structured way to understand the ”WHY" behind the concepts.</p><p><br>Where He Stands Today</p><p>Anil Suryaprakash is now a Lead Developer at Standard Chartered Bank. Sometimes the most confident review is the shortest one. No complaints, no caveats, just results. His move to Standard Chartered says the rest.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Anil_Suryaprakash_9052a35a2e.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[From Intern to Airtel: How Shadab Got His Career Right From the Very Beginning]]></title>
            <link>https://www.codingshuttle.com/blogs/from-intern-to-airtel-how-shadab-got-his-career-right-from-the-very-beginning</link>
            <guid>https://www.codingshuttle.com/blogs/from-intern-to-airtel-how-shadab-got-his-career-right-from-the-very-beginning</guid>
            <pubDate>Wed, 18 Feb 2026 11:13:22 GMT</pubDate>
            <description><![CDATA[Shadab Rehan’s journey to Airtel proves that starting your Spring Boot mastery early is the fastest way to stand out in the competitive engineering landscape.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Most people in internship roles are still figuring out what they want. Shadab Rehan already knew. While working as an intern at Azure Skynet Solution, he was not waiting for opportunity to show up. He was building toward it. He enrolled in Coding Shuttle's Spring Boot Course at a stage in his career when most of his peers were still just getting comfortable with their first job. That early seriousness about learning is what set him apart.</p><h2><br>The Point Where Things Had to Change</h2><p>Going from an internship to a full-time engineering role at Airtel, one of India's largest telecom companies, is a significant leap. It does not happen by accident. Shadab knew that if he wanted to be a serious candidate for technical roles at enterprise companies, he needed more than what college had taught him. He needed industry-relevant skills and he needed to get them fast.</p><p>Learning Spring Boot while navigating the early pressures of career life takes real focus. Shadab had that focus.</p><h2><br>Where Coding Shuttle Came In</h2><p>Coding Shuttle's Spring Boot program gave Shadab something most early-career developers do not get: structured, professional-grade learning that mirrors what companies actually expect from their engineers. The course moved from fundamentals to practical application in a way that prepared him for the kind of backend work he would face in the real world, not just for interviews but for the job itself.</p><h2><br>In Shadab's Own Words</h2><p><i>"Overall Excellent Course. Highly Recommended to someone looking to master Spring boot and microservices"</i></p><h2><br>Where He Stands Today</h2><p>Shadab Rehan is now a GIS Engineer at Airtel. He started as an intern and landed at one of India's biggest companies before many of his peers had even settled into their first full-time roles. His story is a reminder that the decisions you make at the start of your career compound faster than most people realize.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Shadab_Rehan_9874313727.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Why a Senior Developer Went Back to Learning and What It Got Him]]></title>
            <link>https://www.codingshuttle.com/blogs/why-a-senior-developer-went-back-to-learning-and-what-it-got-him</link>
            <guid>https://www.codingshuttle.com/blogs/why-a-senior-developer-went-back-to-learning-and-what-it-got-him</guid>
            <pubDate>Wed, 18 Feb 2026 11:11:42 GMT</pubDate>
            <description><![CDATA[From Lead Engineer to SDE-III at Entegris: See how Omkar Gujar utilized Coding Shuttle’s Spring Boot 0-100 bundle to master advanced backend architecture and level up his career.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Omkar Gujar was already a Lead Software Engineer at Persistent Systems, a company known for demanding high technical standards from its people. He had the seniority. He had the experience. And he still chose to sit down and learn. That is the kind of mindset that separates engineers who keep growing from those who coast on their past achievements.</p><p>He was not learning because he had to. He was learning because he understood that the gap between good and great is always filled by effort, not time.</p><h2><br>The Point Where Things Had to Change</h2><p>Omkar had been a long-time viewer of Anuj Bhaiya's YouTube content and already trusted the teaching style before making any purchase. When he decided to go deep on Spring Boot, he did not look around for long. He picked up the Spring Boot 0-1 and 1-100 bundle and committed to going through it properly, all of it, from the fundamentals to the advanced concepts.</p><p>For a senior engineer, that kind of intellectual honesty, admitting there is still more to learn and doing something about it, is rare and valuable.</p><h2><br>Where Coding Shuttle Came In</h2><p>The course gave Omkar exactly what he was looking for: depth. Every concept was explained in detail with hands-on work built in throughout. It was not the kind of course where you watch videos and feel productive. It was the kind where you actually build things, make mistakes, and come out the other side with real understanding. The 0-to-100 structure meant he could move through foundational topics quickly and spend real time on the advanced material that mattered most for his goals.</p><h2><br>In Omkar's Own Words</h2><p><i>"I was searching for detailed springboot course, luckily i was a long time youtube viewer of Anuj Bhaiya, so i got ahead with purchasing the sprintboot course 0-1 and 1-100 bundle course, pretty good deal. The course is pretty detailed and also well structured and organised, and every concept is explained in very good detail along with hands on. It covers basic concepts and goes upto very advanced concepts. All in all very good course, recommended!!"</i></p><h2><br>Where He Stands Today</h2><p>Omkar Gujar is now an SDE-III at Entegris, stepping into a product-focused engineering role that matches the level of expertise he built. His journey from Lead Engineer at Persistent Systems to SDE-III at Entegris is a reminder that seniority is not a reason to stop learning. For Omkar, it was the reason to learn better.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Omkar_Gujar_c37e2e21e1.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[From IT Services to Investment Banking Tech: The Move That Required More Than Just Experience]]></title>
            <link>https://www.codingshuttle.com/blogs/from-it-services-to-investment-banking-tech-the-move-that-required-more-than-just-experience</link>
            <guid>https://www.codingshuttle.com/blogs/from-it-services-to-investment-banking-tech-the-move-that-required-more-than-just-experience</guid>
            <pubDate>Wed, 18 Feb 2026 11:10:48 GMT</pubDate>
            <description><![CDATA[Want to build high-scale financial systems? Discover how Vedant Kumbhalkar bridged the gap between consulting and Fintech at Nomura by achieving total fluency in Spring Boot, REST APIs, and Hibernate.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Vedant Kumbhalkar was working as a Software Development Consultant at HCLTech when he set his sights on something most engineers only talk about: a role at a tier-one financial institution. Nomura, one of Japan's largest and most respected investment banks, is not a company that hires on potential alone. They want engineers who have depth and can demonstrate it. Vedant knew that and prepared accordingly.</p><h2><br>The Point Where Things Had to Change</h2><p>Breaking into fintech at the level of Nomura requires backend expertise that goes well beyond what most consulting projects demand. Vedant had the Java foundation. What he needed was a mastery of Spring Boot, the framework that powers enterprise financial applications at exactly the scale and reliability that institutions like Nomura require.</p><p>He enrolled in Coding Shuttle's Spring Boot Course while working full-time at HCLTech, which meant early mornings, late evenings, and weekends given over to learning. That kind of consistent effort over months is what turns a good candidate into an exceptional one.</p><h2><br>Where Coding Shuttle Came In</h2><p>The Coding Shuttle Spring Boot program gave Vedant more than technical skills. It gave him confidence. The course covered everything from REST API design to Spring Security and Hibernate in a way that was not just educational but directly applicable to the kind of backend systems financial companies build and maintain. By the time he was done, he was not just familiar with Spring Boot. He was fluent in it.</p><h2><br>In Vedant's Own Words</h2><p><i>"Learning Spring Boot after learning Java is very important if you want to go advanced. Spring Boot is a fast and efficient framework and is used in many companies. Just take up a course (free or paid) and get started. Ensure that you are making use of it in real world projects. Course Recommendation: Coding Shuttle - Spring Boot 0-100."</i></p><h2><br>Where He Stands Today</h2><p>Vedant Kumbhalkar is now a Senior Software Engineer at Nomura in Mumbai. He did not just change companies. He changed the category of company he works for. And in his review, he turned around and pointed other developers in the same direction, recommending Coding Shuttle by name. That is what success looks like when it comes from a place of genuine gratitude.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Vedant_Kumbhalkar_09bef039cc.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Leaving the Safety of TCS for Something Bigger: Anurag's Story]]></title>
            <link>https://www.codingshuttle.com/blogs/leaving-the-safety-of-tcs-for-something-bigger-anurag-s-story</link>
            <guid>https://www.codingshuttle.com/blogs/leaving-the-safety-of-tcs-for-something-bigger-anurag-s-story</guid>
            <pubDate>Wed, 18 Feb 2026 11:09:38 GMT</pubDate>
            <description><![CDATA[From TCS IT Analyst to Senior Associate at Publicis Sapient: Discover how Anurag Malik mastered Spring Boot, Microservices, and JPA with Coding Shuttle to transition into high-level technology consulting.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>TCS is a safe place to build a career. The work is steady, the brand is strong, and the job security is real. Anurag Malik had all of that as an I.T Analyst and he chose to leave it behind for something more demanding and more rewarding. Publicis Sapient is a different kind of company, one where engineers are expected to be technically sharp, constantly growing, and capable of delivering at a consulting level that rivals the best in the industry.</p><p>To compete for that kind of role, Anurag knew he needed to be more than a generalist. He needed to be a Spring Boot specialist.</p><h2><br>The Point Where Things Had to Change</h2><p>Upskilling while working full-time at a demanding company like TCS is not easy. There are projects, deadlines, meetings, and the everyday weight of a job that does not pause because you have decided to learn something new. Anurag did it anyway. He enrolled in Coding Shuttle's Spring Boot Course and treated it with the same seriousness he brought to his professional responsibilities.</p><p>The weekly assignments kept him accountable. The doubt forums gave him a place to work through confusion. And the project-based curriculum made sure that what he was learning was not theoretical but immediately applicable.</p><h2><br>Where Coding Shuttle Came In</h2><p>What stood out to Anurag about the Coding Shuttle course was how it handled complexity. Dependency Injection, REST APIs, Spring Security, JPA, Hibernate, microservices: these are not simple topics. The course broke them down in a way that felt gradual and logical, never overwhelming, always building on what came before. For someone moving from a service-based IT role into product-level consulting, that kind of structured depth was exactly what the transition required.</p><h2><br>In Anurag's Own Words</h2><p>"Anuj Bhaiya's teaching style is often praised for breaking down complex topics like Dependency Injection, REST APIs, and Spring Security into easily digestible lessons. The course also introduces advanced topics such as JPA, Hibernate, and microservices in a gradual, well-structured way that avoids overwhelming learners. Another standout feature is the supportive doubt forum and mentor guidance, where learners can clarify their questions. The weekly homework assignments also help reinforce what has been covered during the sessions, ensuring mastery of the topics."</p><h2><br>Where He Stands Today</h2><p>Anurag Malik is now a Senior Associate Technology at Publicis Sapient in Noida. He took a stable career, decided it was not the ceiling he wanted, and put in the work to find a better one. His detailed and analytical review of the course reflects the kind of engineer he is: someone who does not just use tools but understands how and why they work.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Anurag_Malik_98231652b4.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How Gokul Switched a Comfortable Role at Infosys for an Engineering Job at General Electric]]></title>
            <link>https://www.codingshuttle.com/blogs/how-gokul-switched-a-comfortable-role-at-infosys-for-an-engineering-job-at-general-electric</link>
            <guid>https://www.codingshuttle.com/blogs/how-gokul-switched-a-comfortable-role-at-infosys-for-an-engineering-job-at-general-electric</guid>
            <pubDate>Wed, 18 Feb 2026 11:08:25 GMT</pubDate>
            <description><![CDATA[Gokul Nair’s journey to General Electric proves that active participation and project-based mastery are the keys to outperforming the competition in mid-career pivots.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Gokul Nair was a Digital Specialist Engineer at Infosys, which is not a bad place to be. But Gokul was not interested in comfortable. He was interested in capable. He wanted to be the kind of engineer who could walk into a company like General Electric and build things that actually matter. That kind of ambition requires more than seniority. It requires skill, specifically the hands-on, industry-relevant kind that most online courses fail to deliver.</p><h2><br>The Point Where Things Had to Change</h2><p>The challenge for mid-career developers is not finding content to learn from. The internet is full of it. The challenge is finding learning that actually translates to job performance, content that is not just conceptually correct but practically useful in the environments where engineers work. Gokul needed a Spring Boot course that would give him real experience, not just familiarity. He found that in Coding Shuttle.</p><p>He enrolled while still working at Infosys and committed to doing the work properly, not skimming through videos but actually building, breaking things, and learning from the process.</p><h2><br>Where Coding Shuttle Came In</h2><p>What made the difference for Gokul was the emphasis on hands-on experience. The Coding Shuttle Spring Boot course was not a passive viewing exercise. It demanded active participation. Students did not just watch someone else build things. They built things themselves, which is the only way to develop the kind of confidence that shows up in technical interviews and on the job.</p><p>Gokul summed it up in a way that only an efficiency-minded engineer would: low cost, high output. That framing says a lot about how he approached the course and how seriously he took it.</p><h2><br>In Gokul's Own Words</h2><p>"If You want a hands on experience and want to clear all the concepts on almost all the topics which current industry requires then this course is for you. I would tell its an Low cost high output course if you put your maximum efforts in completing this course."</p><h2><br>Where He Stands Today</h2><p>Gokul Nair is now a Software Engineer at General Electric in Bangalore. He left one of India's biggest IT firms for a global industrial technology company and he made that transition on the strength of skills he built deliberately and seriously. His story is proof that when you put in maximum effort, the output is exactly what you worked for.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Gokul_Nair_ec542f5022.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[The Developer Who Could Not Find a Better Course and Found a Better Job Instead]]></title>
            <link>https://www.codingshuttle.com/blogs/the-developer-who-could-not-find-a-better-course-and-found-a-better-job-instead</link>
            <guid>https://www.codingshuttle.com/blogs/the-developer-who-could-not-find-a-better-course-and-found-a-better-job-instead</guid>
            <pubDate>Wed, 18 Feb 2026 11:07:15 GMT</pubDate>
            <description><![CDATA[Amit Jha’s journey to Guardian Life proves that when it comes to Spring Boot mastery, comprehensive, deep-dive learning is the only way to bridge the gap to top-tier roles.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Amit Jha was an Associate Software Engineer at Opentext when he decided he was ready for more. Not a lateral move, not a title change at the same level, but a genuine step up at a company where the work would challenge him. Guardian Life Insurance, one of North America's most established financial services companies, was that company. Getting there required the kind of backend skills that Amit knew he needed to sharpen.</p><h2><br>The Point Where Things Had to Change</h2><p>The problem with upskilling is not motivation. Most developers want to learn. The problem is that a huge amount of the content available online is incomplete, disorganized, or stops just short of the advanced material that actually matters. Amit spent time looking for a course that would give him comprehensive coverage of Spring Boot, not a highlights reel, but the full picture from foundational concepts to the advanced features that production systems depend on.</p><p>He found that in Coding Shuttle. He enrolled, completed the course fully, and came out the other side with the skills that got him across the finish line.</p><h2><br>Where Coding Shuttle Came In</h2><p>For Amit, the defining quality of the Coding Shuttle Spring Boot course was its coverage. It did not skip the hard parts. It did not rush through topics to look impressive in a course overview. It went deep on everything, which is exactly what a developer needs when preparing to take on backend engineering responsibilities at a financial services company where reliability and correctness are not optional.</p><h2><br>In Amit's Own Words</h2><p><i>"Definitely, I have completed the course, and I would say that it's definitely a good one. Did not find any other course with such a great coverage."</i></p><h2><br>Where He Stands Today</h2><p>Amit Jha is now a Software Engineer at Guardian Life in Gurugram. He went looking for the most comprehensive Spring Boot course he could find and ended up with the most comprehensive outcome he could have hoped for. His review is blunt and honest: he looked, he compared, and Coding Shuttle was the best he found.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Amit_Jha_a9f3fc7015.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Breaking Free From the Service Based Company: Satish's Move From TCS to a Global Product Company]]></title>
            <link>https://www.codingshuttle.com/blogs/breaking-free-from-the-service-based-company-satish-s-move-from-tcs-to-a-global-product-company</link>
            <guid>https://www.codingshuttle.com/blogs/breaking-free-from-the-service-based-company-satish-s-move-from-tcs-to-a-global-product-company</guid>
            <pubDate>Wed, 18 Feb 2026 11:06:11 GMT</pubDate>
            <description><![CDATA[From TCS to HIKVISION: Learn how Satish Diwakar mastered Spring Boot, JPA, and Hibernate with Coding Shuttle to successfully transition from service-based work to a global product company.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Satish Diwakar had a solid foundation as a Java Developer at TCS. He knew the language, he understood the ecosystem, and he had the kind of hands-on experience that service-based IT work builds over years. But he also knew something that a lot of developers in service companies eventually come to terms with: knowing Java is not the same as knowing how to build products with it.</p><p>HIKVISION, the world's largest video surveillance company, was where he wanted to go. A global product company with engineering at its core. To get there, he needed Spring Boot, not just familiarity with it, but actual mastery.</p><h2><br>The Point Where Things Had to Change</h2><p>Making the service-to-product switch is one of the most common ambitions in the Indian developer community and one of the hardest to actually execute. Product companies expect a different level of technical ownership. You are not just implementing specifications handed down from a client. You are building and maintaining systems that have to work reliably at scale, often with less hand-holding and more accountability.</p><p>Satish enrolled in Coding Shuttle's Spring Boot Course while working at TCS and went through it with the seriousness the transition required. No shortcuts. Full commitment.</p><h2><br>Where Coding Shuttle Came In</h2><p>What impressed Satish about the course was its completeness. REST APIs, JPA, Hibernate, Spring Security, real-world projects baked in throughout: the curriculum did not treat any of these as optional extras. They were core to the program because they are core to the job. The hands-on projects in particular gave him the practical experience that makes the difference between a developer who understands Spring Boot conceptually and one who can actually ship with it.</p><h2><br>In Satish's Own Words</h2><p><i>"The course is perfect for both beginners and those looking to level up their skills. The instructors do a fantastic job of explaining concepts in a clear and concise manner. They break down complex topics and walk you through real-world examples, which helped me gain practical experience. I especially appreciated the hands-on projects and in-depth lessons on REST APIs, JPA, Hibernate, and Spring Security. By the end of the course, I felt confident in my ability to build and deploy Spring Boot applications."</i></p><h2><br>Where He Stands Today</h2><p>Satish Diwakar is now a Software Developer at HIKVISION in Mumbai. He made the switch from service to product and he did it the right way: by building the skills first, then making the move. His journey is the kind of story that every developer sitting in a service company and thinking about a product role needs to read.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Satish_Diwakar_54095ee766.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[A Network Engineer Who Learned DSA and Found His Place at One of India's Fastest Growing Startups]]></title>
            <link>https://www.codingshuttle.com/blogs/a-network-engineer-who-learned-dsa-and-found-his-place-at-one-of-india-s-fastest-growing-startups</link>
            <guid>https://www.codingshuttle.com/blogs/a-network-engineer-who-learned-dsa-and-found-his-place-at-one-of-india-s-fastest-growing-startups</guid>
            <pubDate>Wed, 18 Feb 2026 11:04:54 GMT</pubDate>
            <description><![CDATA[Networking meets Algorithms: Anand Vishwakarma’s journey to Shiprocket proves that mastering DSA can unlock elite roles even for professionals in non-development backgrounds.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Anand Vishwakarma spent his early career in networking, building the kind of technical understanding that most software developers never get exposure to. As a Network Engineer at Aerotech Systems, he was good at what he did. But he had bigger ambitions. He wanted to work at a company that was building something exciting, somewhere tech was at the center of everything, not just a supporting function.</p><p>Shiprocket, one of India's fastest growing e-commerce logistics platforms, was exactly that kind of company. To compete for a role there, he needed to speak the language that tech-first companies value: algorithms, data structures, computational thinking.</p><h2><br>The Point Where Things Had to Change</h2><p>Networking professionals who want to grow into roles at high-growth tech companies face a specific challenge. They often have strong infrastructure knowledge but limited exposure to the software engineering concepts that shape how modern tech companies hire and evaluate technical talent. Anand recognized this gap and did something about it. He enrolled in Coding Shuttle's DSA Course and approached it not as a checkbox but as a genuine effort to expand his technical range.</p><h2><br>Where Coding Shuttle Came In</h2><p>Anuj Bhaiya's approach to teaching DSA was what made the course work for Anand. Complex concepts were broken down in a way that made them approachable for someone whose background was in networking rather than software engineering. The course gave Anand the algorithmic foundation and the confidence that comes with actually understanding the material, not just recognizing patterns.</p><h2><br>In Anand's Own Words</h2><p><i>"Yes definitely I recommend to others to learn coding through Anuj Bhaiya."</i></p><h2><br>Where He Stands Today</h2><p>Anand Vishwakarma is now a Network Specialist at Shiprocket in Gurugram, a company that handles millions of shipments powered by sophisticated logistics technology. His recommendation is personal and direct. When learning actually changes your career, you do not talk about the curriculum or the platform. You talk about the person who made it click. For Anand, that was Anuj Bhaiya.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Anand_Vishwakarma_2c9fca87c2.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How Bhumika Got to Siemens Before Most Graduates Even Got Started]]></title>
            <link>https://www.codingshuttle.com/blogs/how-bhumika-got-to-siemens-before-most-graduates-even-got-started</link>
            <guid>https://www.codingshuttle.com/blogs/how-bhumika-got-to-siemens-before-most-graduates-even-got-started</guid>
            <pubDate>Wed, 18 Feb 2026 11:03:37 GMT</pubDate>
            <description><![CDATA[From Intern to Graduate Trainee Engineer at Siemens: Discover how Bhumika Agrawal used Coding Shuttle’s Prime Program to master Java and DSA, building the problem-solving foundation needed for elite engineering roles.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Bhumika Agrawal was still an intern at ByTive when she made the decision that would define the start of her career. She looked at where she wanted to go and figured out what she needed to get there. Siemens, one of the world's largest and most respected engineering and technology companies, was the goal. Getting there required a level of technical preparation that most interns do not bother to put in.</p><p>Bhumika bothered. She enrolled in Coding Shuttle's Prime Program and got to work.</p><h2><br>The Point Where Things Had to Change</h2><p>DSA is the language of technical interviews. It is also the language of problem-solving, the foundational thinking that separates engineers who can follow a process from engineers who can design one. For Bhumika, the challenge was not just learning algorithms but building the kind of problem-solving instinct that lets you walk into a Siemens interview and handle whatever they throw at you.</p><p>She did that while navigating the uncertainties and pressures that come with being early in your career, which takes a kind of focus and maturity that is genuinely rare.</p><h2><br>Where Coding Shuttle Came In</h2><p>The Prime Program did not just give Bhumika a list of algorithms to memorize. It built her intuition. The structured Java and DSA curriculum made the journey systematic rather than overwhelming, which is critical when you are trying to learn something as layered as data structures from the ground up. By the end of the program, she was not just solving more questions. She was understanding why the solutions worked.</p><h2><br>In Bhumika's Own Words</h2><p><i>"I had an amazing experience attending the prime program. It was so beneficial for me. I would 100% recommend it to others. This program really helped me to learn Java and made my DSA Journey easy, because of this program I was able to solve more and more questions."</i></p><h2><br>Where She Stands Today</h2><p>Bhumika Agrawal is now a Graduate Trainee Engineer at Siemens in Bangalore. She started as an intern and landed at a global engineering institution before most of her peers had even finished figuring out what they wanted. Her story is the kind that reminds you that the decisions you make early compound faster than anything else in your career.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Bhumika_Agrawal_e98cd611d9.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[He Never Thought DSA Could Be Fun. Then He Found the Right Teacher.]]></title>
            <link>https://www.codingshuttle.com/blogs/he-never-thought-dsa-could-be-fun-then-he-found-the-right-teacher</link>
            <guid>https://www.codingshuttle.com/blogs/he-never-thought-dsa-could-be-fun-then-he-found-the-right-teacher</guid>
            <pubDate>Wed, 18 Feb 2026 11:02:35 GMT</pubDate>
            <description><![CDATA[Think DSA is dry and boring? Abhinav Sharma didn't. Learn how the right teaching style transformed a "difficult" subject into an engaging experience that led to a career at ADP.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Abhinav Sharma was working as an ML Intern at JKDaily when he enrolled in Coding Shuttle's DSA Course. He was not running away from machine learning. He was building toward something broader, a technical foundation strong enough to compete for roles at companies like ADP, one of the world's largest HR and payroll technology platforms.</p><p>What he did not expect was that learning DSA would actually be enjoyable.</p><h2><br>The Point Where Things Had to Change</h2><p>Developers working in AI-adjacent roles often underestimate how much DSA matters. The logical rigor that comes from truly understanding algorithms does not just help in interviews. It shapes how you think about problems, how you break down complex systems, and how you approach the kind of engineering challenges that generative AI applications are built on.</p><p>Abhinav needed that foundation and he needed it in a form that would actually stick, not just memorized patterns but real understanding. He found both in Coding Shuttle.</p><h2><br>Where Coding Shuttle Came In</h2><p>The thing that made the difference for Abhinav was Anuj Bhaiya's teaching style. DSA has a reputation for being dry, mechanical, and painful to get through. That reputation exists because most people who teach it treat it that way. Anuj does not. The course made the material engaging in a way that kept Abhinav showing up and doing the work, which is ultimately the only thing that produces results.</p><h2><br>In Abhinav's Own Words</h2><p><i>"Had a blast doing this course, never thought DSA could be so engaging. All thanks to Anuj Bhaiya and his teaching style."</i></p><h2><br>Where He Stands Today</h2><p>Abhinav Sharma is now a GPT Intern at ADP in Hyderabad, working at the intersection of generative AI and enterprise technology. His review says something important for every developer who has been putting off DSA because it feels too hard or too boring: the right teacher changes everything. Abhinav found that teacher and it changed his career.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Abhinav_Sharma_4468dc9c36.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[He Was Already a Lead Engineer. He Still Knew He Had More to Learn.]]></title>
            <link>https://www.codingshuttle.com/blogs/he-was-already-a-lead-engineer-he-still-knew-he-had-more-to-learn</link>
            <guid>https://www.codingshuttle.com/blogs/he-was-already-a-lead-engineer-he-still-knew-he-had-more-to-learn</guid>
            <pubDate>Wed, 18 Feb 2026 11:01:04 GMT</pubDate>
            <description><![CDATA[From HCLTech to Lead Software Engineer at Persistent Systems: See how Sai Prasad Kerur mastered Microservices, Kafka, and Kubernetes with Coding Shuttle to transition into high-scale product engineering.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Sai Prasad Kerur was a Lead Engineer at HCLTech. Senior enough to have a team, experienced enough to know the industry, and smart enough to recognize that the gap between where he was and where the best engineers in the country were operating was not just seniority. It was architecture knowledge. Microservices, Kafka, Docker, Kubernetes, the things that make systems scalable at enterprise level, he needed to go deeper on all of it.</p><p>He enrolled in Coding Shuttle's Spring Boot 1-100 course and went back to learning with the same seriousness he brought to leading his team.</p><h2><br>The Point Where Things Had to Change</h2><p>For senior engineers, upskilling presents a specific kind of challenge. The content needs to be advanced enough to be worth your time, practical enough to be immediately useful, and taught by someone who actually understands how these systems work in production. A lot of advanced courses fail on at least one of those dimensions.</p><p>Sai found that Coding Shuttle's course delivered on all three. He went through it while managing his full-time responsibilities at HCLTech, which required real discipline and real time management.</p><h2><br>Where Coding Shuttle Came In</h2><p>The Spring Boot 1-100 course gave Sai a practical grasp of the distributed systems concepts that separate mid-level engineers from the ones building truly scalable applications. Anuj's emphasis on actually doing the projects, not just watching them get built, was what made the learning stick. It is easy to feel like you understand Kafka after watching someone explain it. It is a different experience entirely to build something with it yourself.</p><h2><br>In Sai Prasad's Own Words</h2><p><i>"I recently completed a course called Spring Boot 1 to 100 by Coding Shuttle. It covered Microservices, Kafka, Docker, Kubernetes, and caching. Really helped me get a practical grasp of these concepts and will recommend to do try the projects told by Anuj Sir, it can help you to understand how to start building scalable applications."</i></p><h2><br>Where He Stands Today</h2><p>Sai Prasad Kerur is now a Lead Software Engineer at Persistent Systems in Bangalore, a company known for its engineering excellence and high technical standards. He came in already experienced and left sharper. His specific recommendation to try the projects is the advice of an engineer who knows that watching and doing are not the same thing at all.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Sai_Prasad_Kerur_4afa6619a7.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[A Senior Engineer With Student Mindset: Why Satyansh Kept Upskilling When Most Would Have Stopped]]></title>
            <link>https://www.codingshuttle.com/blogs/a-senior-engineer-with-student-mindset-why-satyansh-kept-upskilling-when-most-would-have-stopped</link>
            <guid>https://www.codingshuttle.com/blogs/a-senior-engineer-with-student-mindset-why-satyansh-kept-upskilling-when-most-would-have-stopped</guid>
            <pubDate>Wed, 18 Feb 2026 10:59:45 GMT</pubDate>
            <description><![CDATA[Senior titles don't mean you stop learning. Discover how Satyansh Shukla balanced leadership responsibilities with advanced DSA prep to land a prestigious Lead Engineer role at Accolite Digital.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Satyansh Shukla had already reached a level that most developers spend years working toward. As a Lead Engineer at HCLTech, he had the title, the experience, and the credibility. He also had the self-awareness to recognize something that many senior engineers prefer not to admit: that the DSA fundamentals he had learned years ago were rusty, and that to compete for roles at companies like Accolite Digital, they needed to be sharp.</p><p>He enrolled in Coding Shuttle's DSA program not because he had to but because he understood the difference between the engineer he was and the engineer he wanted to be.</p><h2><br>The Point Where Things Had to Change</h2><p>Lead-level engineers who want to move to more demanding, product-focused companies often underestimate how seriously those companies test foundational knowledge. Accolite Digital is known for thorough technical evaluation. Showing up with years of experience but weak algorithmic thinking is not a winning formula. Satyansh knew this and prepared accordingly.</p><p>Fitting serious DSA study into a schedule that already includes leadership responsibilities is not easy. It requires the kind of prioritization and discipline that very few people actually follow through on. Satyansh did.</p><h2><br>Where Coding Shuttle Came In</h2><p>What Coding Shuttle's DSA program gave Satyansh was not just preparation for interviews. It rebuilt his conceptual foundation from the ground up, giving him the kind of solid, transferable understanding that makes a difference not just in technical rounds but in the actual work of designing and building complex systems. The course built confidence alongside competence, which is exactly what someone going into a senior engineering interview needs.</p><h2><br>In Satyansh's Own Words</h2><p><i>"The experience was really great and I would recommend others also to join the program as it will not only help in getting confidence w.r.t. solving competitive problems but also build a solid understanding of core concepts!"</i></p><h2><br>Where He Stands Today</h2><p>Satyansh Shukla is now a Lead Software Engineer at Accolite Digital in Gurugram. He is someone who had every reason to coast and chose to grow instead. His story is a reminder that the engineers who stay at the top are not the ones who stop learning once they reach a senior title. They are the ones who treat every stage of their career as a new starting point.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Satyansh_Shukla_33a7858303.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[From System Engineer to Software Engineer: The Career Switch That Got Akhil to Kyndryl]]></title>
            <link>https://www.codingshuttle.com/blogs/from-system-engineer-to-software-engineer-the-career-switch-that-got-akhil-to-kyndryl</link>
            <guid>https://www.codingshuttle.com/blogs/from-system-engineer-to-software-engineer-the-career-switch-that-got-akhil-to-kyndryl</guid>
            <pubDate>Wed, 18 Feb 2026 10:56:34 GMT</pubDate>
            <description><![CDATA[Don't just hope for a better role—study your way there. Learn how Akhil Giri identified the specific Spring Boot skills needed to transition from system engineering to a high-impact developer role at Kyndryl.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Akhil Giri was a System Engineer at TCS with a clear sense of where he wanted to go. Kyndryl, the world's largest IT infrastructure services company spun off from IBM, was building something massive and needed engineers who could operate at enterprise scale with deep technical knowledge. Moving from a System Engineer role at TCS to a Software Engineer position at Kyndryl was not just a title change. It required a different level of backend expertise.</p><p>Akhil approached the transition the way he approaches most things: analytically and methodically.</p><h2><br>The Point Where Things Had to Change</h2><p>System engineers at large IT companies often have broad exposure to enterprise environments but lack the depth in specific development frameworks that product-focused roles require. Akhil identified this gap and spent time figuring out exactly what skills would make him a strong candidate for the kind of backend-heavy roles that Kyndryl builds and maintains. Spring Boot was the answer.</p><p>He enrolled in Coding Shuttle's Spring Boot Course and went through it with the kind of careful, thorough attention that is evident in everything he writes about the experience.</p><h2><br>Where Coding Shuttle Came In</h2><p>What mattered most to Akhil was that the course was in tune with what companies actually use. A lot of courses teach Spring Boot in a bubble, divorced from the patterns and practices that real engineering teams follow. Coding Shuttle's program aligned its content with current industry standards, which meant everything Akhil learned was immediately relevant to the kind of work that Kyndryl's clients demand.</p><h2><br>In Akhil's Own Words</h2><p>"The content seems to be in tune with current industry standards, meaning the skills and technologies taught align well with what companies expect from developers. The course was high on content and covers a wide range of topics in Spring Boot, from foundational concepts to more advanced features. Anuj Bhaiya's course seems to excel at blending theory with real-world application, providing a strong foundation in Spring Boot while focusing on industry-relevant knowledge."</p><h2><br>Where He Stands Today</h2><p>Akhil Giri is now a Software Engineer at Kyndryl in Gurugram, working within the infrastructure that serves some of the most complex enterprise environments in the world. His methodical approach to learning is exactly what made his transition possible. He did not hope his way into a better role. He studied his way there.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Akhil_Giri_0676b41bf3.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[The Specialist Who Went Deep and Came Out the Other Side as a Lead SDE]]></title>
            <link>https://www.codingshuttle.com/blogs/the-specialist-who-went-deep-and-came-out-the-other-side-as-a-lead</link>
            <guid>https://www.codingshuttle.com/blogs/the-specialist-who-went-deep-and-came-out-the-other-side-as-a-lead</guid>
            <pubDate>Wed, 18 Feb 2026 10:48:30 GMT</pubDate>
            <description><![CDATA[See how Syed Rizwan transitioned from a Specialist at Bristlecone to a Lead Software Engineer at Persistent Systems. Master Spring Boot from 0 to 100 with the technical depth required for senior engineering roles.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Syed Rizwan was a Specialist at Bristlecone, a supply chain consulting firm that works with some of the world's largest companies. He had consulting experience and real-world technical exposure. But Lead Software Engineer at Persistent Systems, a company that is synonymous with product engineering excellence, was a different ask entirely. It required the kind of in-depth Spring Boot mastery that consulting work rarely demands.</p><p>Syed decided to build that mastery properly, from the ground up.</p><h2><br>The Point Where Things Had to Change</h2><p>There is a difference between using Spring Boot on a project and truly understanding it. Consultants often end up in the first category: familiar with the framework in specific contexts, able to work within existing codebases, but not fluent enough to architect systems from scratch or lead a team through complex backend challenges. Syed wanted to be in the second category.</p><p>He enrolled in Coding Shuttle's Spring Boot 0-100 program and went through the full journey, from the fundamentals all the way to the advanced distributed systems concepts that senior engineering roles at companies like Persistent Systems expect.</p><h2><br>Where Coding Shuttle Came In</h2><p>The structure of the 0-100 program was what made it valuable for Syed. It was not a collection of loosely connected topics. It was a progression that built a complete mental model of Spring Boot development, each concept reinforcing the ones before it and setting up the ones that followed. That kind of coherent structure is what allows complex ideas to actually stick rather than blur together after a few weeks.</p><h2><br>In Syed's Own Words</h2><p><i>"Spring Boot 0 to 100 is a well-structured course that delivers in-depth, practical insights into Spring Boot development, making complex concepts easy to grasp and apply."</i></p><h2><br>Where He Stands Today</h2><p>Syed Rizwan is now a Lead Software Engineer at Persistent Systems in Bangalore. He went in as a specialist in one domain and came out leading engineers in another. His review is precise and confident, which is exactly how he approached the learning itself. The result speaks for itself.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Syed_Rizwan_ef88d444aa.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[From Financial Markets to the Big Four: The Career Switch Nobody Saw Coming Except Akhilesh]]></title>
            <link>https://www.codingshuttle.com/blogs/from-financial-markets-to-the-big-four-the-career-switch-nobody-saw-coming-except-akhilesh</link>
            <guid>https://www.codingshuttle.com/blogs/from-financial-markets-to-the-big-four-the-career-switch-nobody-saw-coming-except-akhilesh</guid>
            <pubDate>Wed, 18 Feb 2026 10:38:03 GMT</pubDate>
            <description><![CDATA[From NCDEX Manager to PwC Developer: Akhilesh Bodhane’s unconventional journey proves that with the right technical foundation, a non-traditional background is your greatest competitive advantage.]]></description>
            <content:encoded><![CDATA[<h2>Before the Switch</h2><p>Akhilesh Bodhane's story is the most unconventional in this collection and possibly the most inspiring. He was working as an Assistant Manager at NCDEX e Markets Ltd., one of India's leading commodity derivatives exchanges. He had a BCA background and a career grounded in financial markets. And he decided he wanted to be a software developer.</p><p>Not just any developer. A developer at PwC, one of the Big Four professional services firms, where the technical bar is high and the expectations are higher.</p><h2><br>The Point Where Things Had to Change</h2><p>Making the move from a managerial role in financial markets to a software development position at a firm like PwC is the kind of transition that most people would look at and quietly decide is too risky. The domain knowledge does not transfer directly. The job title goes down before it goes up. The learning curve is steep.</p><p>Akhilesh made the decision anyway. He enrolled in Coding Shuttle's Spring Boot Course and approached it the way he had approached everything else in his career: seriously, consistently, and with his eye fixed on where he was going rather than where he was starting.</p><p>Learning Spring Boot while holding down a full-time managerial role in the financial sector requires a level of time management and commitment that very few people sustain. Akhilesh sustained it.</p><h2><br>Where Coding Shuttle Came In</h2><p>For someone coming into software development from a non-traditional path, the Coding Shuttle Spring Boot course provided something invaluable: a genuine love for the craft. The course did not just teach Akhilesh how to build applications. It made him genuinely excited about building them. The focus on robust, scalable Java applications gave him the technical foundation that PwC's consulting clients demand, and his financial domain background gave him a context for understanding why reliability and correctness matter so deeply in enterprise software.</p><p>That combination of technical skill plus domain insight is exactly what makes a developer exceptional rather than just competent.</p><h2><br>In Akhilesh's Own Words</h2><p><i>"I really enjoy learning Spring Boot. The course has been incredibly insightful and has deepened my understanding of building robust, scalable applications with Java."</i></p><h2><br>Where He Stands Today</h2><p>Akhilesh Bodhane is now a Software Developer at PwC in Pune, bringing together a background in financial markets and a newly built expertise in Spring Boot to deliver work that very few developers could match. His transition is proof that the most interesting careers rarely follow the obvious path. Sometimes the switch that looks the most unlikely is the one that makes the most sense once it happens.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>Job Switch</category>
            <category>From service based to product based switch</category>
            <category>success story</category>
            <category>Big 4 interview experience</category>
            <category>coding shuttle review</category>
            <category>coding shuttle student review</category>
            <category>career switch</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Akhilesh_Bodhane_9064c32a68.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Practical Guide to Building Software Engineer Resumes that Get Shortlisted]]></title>
            <link>https://www.codingshuttle.com/blogs/practical-guide-to-building-software-engineer-resumes-that-get-shortlisted</link>
            <guid>https://www.codingshuttle.com/blogs/practical-guide-to-building-software-engineer-resumes-that-get-shortlisted</guid>
            <pubDate>Tue, 10 Feb 2026 07:26:19 GMT</pubDate>
            <description><![CDATA[Ex-Amazon SDE | Reviewed 10,000+ Resumes | Software Engineer Resume Examples & Template (2026 FAANG Guide)]]></description>
            <content:encoded><![CDATA[<p>Check out this FREE AI Resume Builder Tool: <a href="https://www.codingshuttle.com/resume-builder/">AI Resume Builder</a></p><p>If you are reading this, chances are that your resume is not getting shortlisted. Don’t worry, you are not alone. I’ve helped thousands of students at Coding Shuttle fix this exact problem. &nbsp;Today, I’m sharing the <strong>exact formula</strong> that gets resumes shortlisted at FAANG and other product-based companies.</p><p>In this guide, I will be sharing what exactly what works and what doesn't - with real resume examples from students who got into Google, Amazon, and Microsoft. I've reviewed thousands of resumes and formulated a list of what works and what doesn't.&nbsp;</p><h2>What Actually Works?</h2><p>Look at these two resumes. Both are fresh graduates and look very similar, but there's a stark difference.</p><p><strong>One got interviews at Amazon, Uber, and Google. The other got zero responses after 50+ applications.</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/2_a1aa88e4a5.png" alt="resume that get shortlisted -  example of resume getting rejected" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_2_a1aa88e4a5.png 111w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_2_a1aa88e4a5.png 357w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_2_a1aa88e4a5.png 536w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_2_a1aa88e4a5.png 714w," sizes="100vw"><figcaption>Fancy resume - Getting rejected</figcaption></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/1_f1e8781919.png" alt="resume that get shortlisted - example shortlisted resume" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_1_f1e8781919.png 111w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_1_f1e8781919.png 357w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_1_f1e8781919.png 536w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_1_f1e8781919.png 714w," sizes="100vw"><figcaption>Simple resume - Getting shortlisted</figcaption></figure><h3>What's Wrong With Ravikant's Resume?</h3><ol><li><strong>Photo on resume</strong> - Photos create bias and waste precious space that should be used to highlight important skills.</li><li><strong>"About Me" section</strong> - It is too generic and doesn't specify any actual data points for recruiters to consider as soft and personal skills.</li><li><strong>No quantifiable numbers</strong> - Phrases such as "Design, implement, and maintain Java-based applications" as such do not add any value unless they are supported by quantifiable numbers to show the impact created. It can be rephrased as: “Designed, implemented and maintained Java based applications that are over 50 internal stakeholders every day and generate $100k in annual revenue”.&nbsp;</li><li><strong>Skills section is not well defined</strong> - "Strong background in computer science" specifies educational background. Skills would be things learnt while studying computer science, eg: DSA, Kafka, Springboot etc. You should specify as many as possible, but only the ones you are proficient in as this would be the base for the interviewer to ask questions.</li><li><strong>10 years of experience (Jan 2014 - Present)</strong> - Work experience should be detailed, yearwise preferably. Work experience must be in chronological order, detailing projects you have worked on and impact created. Promotions can also be mentioned. Eg: 2014-16 - SDE 1; 2016-18 - SDE 2. &nbsp;</li></ol><blockquote><p>Don't overcomplicate things. Your resume has one job: to get you an interview. Keep it clean, keep it simple, and let your skills speak for themselves.</p></blockquote><h3>What Makes Aparna's Resume Work?</h3><p>Look at her first bullet point:</p><p><i>“Architected enterprise-scale GraphRAG platform... unifying 500,000+ data entities... 40% improved retrieval accuracy”</i></p><ul><li><strong>Specific technology</strong>: GraphRAG, Neo4j, PGVector</li><li><strong>Scale (well quantified)</strong>: 500,000+ data entities</li><li><strong>Impact (well quantified)</strong>: 40% improved accuracy</li></ul><p>This is what most recruiters want to see in a resume. Your resume should showcase the impact you created in the previous roles you worked in. Here's how you can transform your weak bullet points to stronger points.</p><h2>Transform Weak Bullets Into Strong Ones</h2><p>After reviewing 10,000+ resumes, I've seen people making the same mistakes over and over &nbsp;again. So I created a simple formula that works every time:</p><p><strong>[Action Verb] + [What You Built] + [Tech Stack] + [Measurable Result]</strong></p><p>Here's a comparison table with real examples:</p><figure class="table"><table><thead><tr><th>Weak Bullet (Gets Rejected)</th><th>Strong Bullet (Gets Interviews)</th><th>Why It Works</th></tr></thead><tbody><tr><td>Worked on improving app performance</td><td>Optimized React rendering and implemented code-splitting, reducing load time from 3.2s to 890ms (72% faster)</td><td>Shows exact improvement with numbers</td></tr><tr><td>Developed features for e-commerce site</td><td>Built one-click checkout using React + Stripe API, increasing conversions by 23% and adding ₹3.5L monthly revenue</td><td>Business impact in rupees, specific tech</td></tr><tr><td>Part of backend team</td><td>Led API migration to microservices using Docker + K8s, cutting deployment time from 45min to 4min</td><td>Leadership + time savings</td></tr><tr><td>Fixed bugs and improved code</td><td>Resolved 52 bugs in Q2 2025 using automated testing (Jest + Cypress), reducing support tickets by 34%</td><td>Quantified work + downstream impact</td></tr></tbody></table></figure><h2>Software Engineer Resume For Freshers: The Projects Strategy</h2><p>"But Anuj, I'm a fresher. I don't have work experience. How do I show impact?"</p><p>For freshers, <strong>your projects and internships ARE your experience.</strong></p><p>I've seen even bootcamp grads get interviews by treating projects like professional work. Here's how:</p><h3>❌ Bad Project:</h3><pre><code class="language-plaintext">Personal Finance Tracker
• Built a web app using React and Node.js
• Used MongoDB for database
• Implemented user authentication
• Deployed on Heroku
</code></pre><p>This could be anyone's project. Zero differentiation.</p><h3>✅ Good Project (What Gets Interviews):</h3><pre><code class="language-plaintext">FinanceFlow - Budget Management Platform
• Built real-time expense tracker using React + WebSocket, serving 847 users with 99.3% uptime
• Integrated Plaid API for bank sync, auto-categorizing 10K+ transactions/month with 94% accuracy
• Optimized MongoDB aggregation pipelines, reducing dashboard load from 4.7s to 1.2s (74% faster)
• Created budget alerts using AWS Lambda + SNS, helping 230+ users save avg ₹25K/month

Tech: React, Node.js, MongoDB, AWS (Lambda, SNS), Plaid API, Docker
Live: financeflow.dev | GitHub: github.com/username/financeflow (340 stars)
</code></pre><p><strong>What makes this work:</strong></p><ul><li>It mentions real users (847)</li><li>Includes tech depth (Plaid API, Lambda, aggregation pipelines)</li><li>Metrics and numbers wherever possible (99.3% uptime, 74% faster, ₹25K saved)</li><li>Live proof (deployed app + GitHub stars)</li></ul><h2>How To Quantify Impact (Critical)</h2><p>"I'm a junior dev. I don't have access to analytics. What do I do?"</p><p>You don't need perfect data. You need <strong>smart estimates</strong>. Also, you should ask your product managers; they usually track all these metrics.</p><p>Here are 6 types of metrics that always work:</p><figure class="table"><table><thead><tr><th>Metric Type</th><th>Examples</th><th>How To Get Numbers</th></tr></thead><tbody><tr><td><strong>Performance</strong></td><td>"Reduced API time from 2.3s to 340ms"</td><td>Chrome DevTools, monitoring tools, or time it yourself</td></tr><tr><td><strong>Scale</strong></td><td>"Handling 1.2M requests/day"</td><td>Database counts, server logs, Google Analytics</td></tr><tr><td><strong>Business</strong></td><td>"Increased conversion by 3.2%"</td><td>Product dashboards, or ask your PM</td></tr><tr><td><strong>Time Savings</strong></td><td>"Cut deployment from 2hrs to 8min"</td><td>Time yourself before/after</td></tr><tr><td><strong>Quality</strong></td><td>"Reduced bugs from 47/week to 8/week"</td><td>JIRA tickets, error monitoring (Sentry)</td></tr><tr><td><strong>Volume</strong></td><td>"Resolved 52 high-priority bugs in Q2"</td><td>Count your tickets, PRs, commits</td></tr></tbody></table></figure><p><strong>My trick when I applied to Amazon:</strong></p><p>Instead of: "Improved database performance."</p><p>I wrote: "Optimised PostgreSQL with composite indexes, reducing response time from ~2.5s to ~400ms (estimated 85% improvement from local testing)."</p><blockquote><p>Nobody expects freshers to have perfect analytics. What they DO expect is that you pay attention to your impact and can talk about it.</p></blockquote><h3>✅ Do This:</h3><p><strong>Clean, single-column layout</strong> - Top to bottom flow&nbsp;</p><p><strong>Standard headers</strong> - "Work Experience," "Education," "Skills" (not “My Journey”)&nbsp;</p><p><strong>Simple formatting</strong> - Bold + regular text only <strong>Standard fonts</strong> - Arial, Calibri (10-12pt)&nbsp;</p><p><strong>Save as PDF</strong> - Unless told otherwise</p><p><strong>Example header:</strong></p><pre><code class="language-plaintext">RAHUL SHARMA
+91-98765-43210 | rahul.sharma@gmail.com
linkedin.com/in/rahulsharma | github.com/rahulsharma
</code></pre><h3>❌ Don't Do This:</h3><ul><li>Two-column layouts (breaks parsers)</li><li>Tables or text boxes (scrambles info)</li><li>Headers/footers for contact info (often skipped)</li><li>Fancy fonts or graphics</li><li>Photos (unless you're modelling)</li></ul><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Do_s_and_dont_s_for_building_a_software_engineering_resume_a3224d1255.webp" alt="Do's and dont's for building a software engineering resume" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Do_s_and_dont_s_for_building_a_software_engineering_resume_a3224d1255.webp 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Do_s_and_dont_s_for_building_a_software_engineering_resume_a3224d1255.webp 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Do_s_and_dont_s_for_building_a_software_engineering_resume_a3224d1255.webp 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Do_s_and_dont_s_for_building_a_software_engineering_resume_a3224d1255.webp 1000w," sizes="100vw"></p><h2>Section-By-Section Templates (Copy-Paste Ready)</h2><h3>Skills Section</h3><p><strong>❌ Wrong Way:</strong></p><pre><code class="language-plaintext">Skills: HTML, CSS, JavaScript, React, Angular, Vue, Node.js, Python, Java,
C++, SQL, MongoDB, AWS, Azure, Docker, Kubernetes, Git...
</code></pre><p><strong>✅ Right Way (Like Aparna's Resume):</strong></p><pre><code class="language-plaintext">TECHNICAL SKILLS

Generative AI &amp; ML: RAG, GraphRAG, LightRAG, LangChain, Claude, Gemini AI
Full Stack: Java, Python, FastAPI, TypeScript, React, Node.js, Express
Databases: Neo4j (Graph), PostgreSQL, MongoDB, Redis, Elasticsearch
DevOps: AWS, Docker, K8s, CI/CD, GitHub Actions, Jenkins
</code></pre><p><strong>Why this works:</strong></p><ul><li>Grouped by category</li><li>Specific tools mentioned (not just "AWS" but actual services)</li><li>Shows depth, not breadth</li></ul><h3>Experience Section</h3><p><strong>❌ Wrong Way (Like Ravikant's):</strong></p><pre><code class="language-plaintext">• Design, implement, and maintain Java-based applications
• Coordinate with teams to create efficient solutions
• Analyze requirements and design software
</code></pre><p>This shows zero impact and just responsibilities. You should avoid writing experience section like this.</p><p><strong>✅ Right Way (Like Aparna's):</strong></p><pre><code class="language-plaintext">• Architected GraphRAG platform with Neo4j + PGVector, unifying 500K+ data
  entities from 8 systems, improving retrieval accuracy by 40%
• Reduced LLM indexing costs by 50% through batch API + optimized embedding,
  saving $15K+ annually
• Spearheaded AI documentation automation using CrewAI + MCP, generating docs
  for 250+ integrations, cutting update latency by 99% (72h to 45m)
</code></pre><p>See the pattern? Every bullet has:</p><ol><li>Strong verb (Architected, Reduced, Spearheaded)</li><li>Specific tech (Neo4j, PGVector, CrewAI)</li><li>Numbers (500K entities, 40%, $15K, 99%)</li></ol><p>You can also use the AI tools in this <a href="https://www.codingshuttle.com/resume-builder/">Free AI Resume Builder</a> to generate strong impactful experience bullet points like these.</p><h3>Projects Section Template</h3><pre><code class="language-plaintext">[Project Name] - [One-line description]
• [Built/Engineered] [what it does] using [tech], [usage metrics]
• [Implemented] [key feature] with [approach], [measurable outcome]
• [Optimized] [what], reducing [metric] from X to Y (Z% improvement)

Tech: [List 5-7 key technologies]
Live: [URL] | GitHub: [URL] | [Optional: stars, users]
</code></pre><h2>Why We Built The Free AI Resume Builder</h2><p>After seeing the same formatting issues 10,000 times, I got frustrated. Students are spending HOURS writing bad resume with Google Docs.</p><p>So we built a free <a href="https://www.codingshuttle.com/resume-builder/">tool</a> that handles formatting automatically and helps you focus on what actually matters - showing your value.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/ai_resume_builder_and_analyser_tool_a4e15d60b3.png" alt="ai resume builder and analyser tool" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_ai_resume_builder_and_analyser_tool_a4e15d60b3.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_ai_resume_builder_and_analyser_tool_a4e15d60b3.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_ai_resume_builder_and_analyser_tool_a4e15d60b3.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_ai_resume_builder_and_analyser_tool_a4e15d60b3.png 1000w," sizes="100vw"></p><h3>What It Does:</h3><p><strong>1. AI Impact Enhancement</strong></p><p>You type: <i>"improved app performance from 3.2s to 1.1s."</i></p><p>Then the AI will automatically rewrites this as: <i>"Optimised React rendering with code-splitting, reducing load time from 3.2s to 1.1s (66% faster)"</i></p><p><strong>2. Real-Time ATS Checks</strong></p><p>It shows you:</p><ul><li>✅ Format will parse correctly</li><li>⚠️ Skills section too long</li><li>❌ Missing GitHub link</li></ul><h2>FAQ: Questions I Get Asked Frequently</h2><p><strong>1. Should I include GPA on my resume?</strong>&nbsp;</p><p>Only if you are a fresh graduate and it is exceptional (above 8.5/10 or 3.5/4.0). If you have work experience of over 4 years, then you can avoid adding it all together.</p><p><strong>2. How long should a software engineer's resume be?</strong> <strong>One page.</strong>&nbsp;</p><p>Unless you have 10+ years of experience, keep it to one page. Recruiters usually spend 20 seconds max to go through a resume.</p><p><strong>3. What font is best for tech resumes?</strong>&nbsp;</p><p>Stick to the classics: Arial, Calibri, Roboto, or Open Sans. Size 10-12pt.</p><p><strong>4. Should I put a photo on my resume?</strong>&nbsp;</p><p>For US/UK/India tech jobs: <strong>No.</strong> It introduces bias and takes up valuable space. For some European/Asian countries, it might be standard, but for FAANG and other product-based companies, you should skip it.</p><p><strong>5. How do I list "Soft Skills"?</strong>&nbsp;</p><p><i>You should not just list them, you should show</i> them. Instead of writing "Leadership," write a bullet point: "Led a team of 3 juniors to deliver X."</p><p><strong>6. Do I need a summary/objective section?</strong>&nbsp;</p><p>Generally, <strong>no</strong>. It takes up space. Unless you are making a drastic career switch (e.g., Marketing to Coding), skip it. But if you have some space left in your resume, then a good professional summary can be added to fill up the resume as well.</p><p><strong>7. Are "Interests" sections necessary?</strong>&nbsp;</p><p>Avoid stuff like “Watching movies”, “Reading Novels”, etc. "State-level Chess Player" or "Open Source Contributor" is good. But these lines should be added in the “<strong>Achievements”</strong> section instead of calling it Interests.&nbsp;</p><p><strong>8. How do I handle employment gaps?</strong>&nbsp;</p><p>Be honest. If you took a year to upskill, list it as "Career Break - Professional Development" and list the courses/projects you did.</p><p><strong>9. Should I include my address?</strong>&nbsp;</p><p>City and State/Country are enough. "Gurugram, India." Avoid adding the full street addresses.</p><p><strong>10. What if I have no experience?</strong>&nbsp;</p><p>Focus heavily on the <strong>Projects</strong> section. Treat your projects like jobs. List the tech stack, the challenges, and the outcome. Contributing to Contributing to Open Source projects is an excellent strategy for building relevant experience.</p><hr><h2>Your Checklist Before Hitting Submit</h2><ul><li>[ ] Every bullet has a strong action verb</li><li>[ ] 70%+ bullets include specific numbers</li><li>[ ] Technologies are specific (not "cloud" but "AWS Lambda, S3")</li><li>[ ] Most impressive stuff is in the first 2-3 bullets</li><li>[ ] Projects show real usage (users, stars, metrics)</li><li>[ ] One page for &lt;5 years, max 2 for seniors</li><li>[ ] Professional email (no <code><i>coolcoder123@yahoo.com</i></code>)</li><li>[ ] Zero spelling/grammar errors</li><li>[ ] Saved as PDF with good name (FirstName_LastName_Resume.pdf)</li><li>[ ] No tables, text boxes, or fancy formatting</li><li>[ ] Matches job description keywords</li></ul><p>If you checked all, you're ready to apply.</p><blockquote><p>Most rejections happen at resume stage. Not because you can't code, but because you can't communicate your value.</p></blockquote><h2>Final Thoughts</h2><p>Three things to remember:</p><ol><li><strong>Quantify everything</strong> - "Improved performance" is useless. "Reduced latency from 2.3s to 340ms" is gold.</li><li><strong>Show impact, not responsibility</strong> - Nobody cares you were "responsible for API." They care that you "optimized API, cutting costs by ₹3.5L/month."</li><li><strong>Make it scannable</strong> - Put your best work at the top.</li></ol><p><strong>Ready to build a resume that works?</strong></p><p>Use our <a href="https://www.codingshuttle.com/resume-builder/">free AI resume builder</a> and get it done in 10 minutes. Completely free.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>FAANG resume guide</category>
            <category>Software engineer resume</category>
            <category>Tech resume tips</category>
            <category>FAANG interview preparation</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/how_to_build_a_tech_resume_blog_fb1133185e.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Complete System Design Interview Preparation For 2-7 Years of Experience [2026] ]]></title>
            <link>https://www.codingshuttle.com/blogs/system-design-in-one-shot</link>
            <guid>https://www.codingshuttle.com/blogs/system-design-in-one-shot</guid>
            <pubDate>Sun, 01 Feb 2026 12:24:20 GMT</pubDate>
            <description><![CDATA[A complete system design reference for developers, covering scalability, databases, load balancers, caching, Kafka, CDN, microservices, and distributed systems. Built for engineers preparing for system design interviews or designing production-grade systems from scratch.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p>There is <strong>no prerequisite</strong> to read this one shot blog.</p><p>If you know how to build a basic backend, understand what an API is, and have used a database at least once, you are good to go.</p><p>This article is designed to be a <strong>single source of truth</strong> for system design fundamentals. You should be able to read this and then directly start attempting system design interview problems or designing real-world systems with confidence.</p><p>Most system design content online focuses heavily on theory. This cheatsheet focuses on:</p><ul><li>Practical intuition</li><li>Real-world usage</li><li>How things break at scale</li><li>Why certain design decisions exist</li></ul><p>Think of this as notes shared by a friend who has already made mistakes so you do not have to repeat all of them.</p><h2>What This One Shot Blog Covers?</h2><p>This is a long read by design. Roughly 60 minutes if read properly.</p><p>You will learn:</p><ul><li>Why system design matters</li><li>What servers actually are</li><li>Latency vs throughput</li><li>Scaling fundamentals</li><li>Auto scaling</li><li>Back-of-the-envelope estimation</li></ul><p>Later parts will go much deeper into databases, caching, distributed systems, messaging, consistency, and interview strategy.</p><hr><h2>Why Study System Design?</h2><p>Most developers start by building systems like this:</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Basic_Single_Server_Architecture_a0a59a8deb.avif" alt="Basic Single-Server Architecture.avif"></p><p>This architecture works perfectly for:</p><ul><li>College projects</li><li>Hackathons</li><li>Early MVPs</li><li>Side projects with limited users</li></ul><p>Now imagine this same system when:</p><ul><li>Thousands of users hit it simultaneously</li><li>Database queries increase massively</li><li>One server goes down</li><li>Traffic spikes unexpectedly</li></ul><p>Suddenly:</p><ul><li>APIs slow down</li><li>Requests start failing</li><li>The database becomes the bottleneck</li><li>The system crashes at the worst possible time</li></ul><p>System design is about <strong>preparing for growth and failure</strong>.</p><p>It answers questions like:</p><ul><li>How do we scale without rewriting everything?</li><li>How do we handle failures gracefully?</li><li>How do we make systems reliable under load?</li><li>How do real companies handle millions of users?</li></ul><p>If you do not design for scale early, scale will force redesign later.</p><h2>What Is a Server?</h2><p>A server is simply a <strong>computer running your application</strong>.</p><p>There is nothing special about it.</p><p>When you run a backend locally on:</p><p><a href="http://localhost:8080">http://localhost:8080</a></p><p>You are already running a server.</p><h3>Breaking it down</h3><ul><li><code>localhost</code> resolves to the IP address <code>127.0.0.1</code></li><li>This IP points to your own machine</li><li><code>8080</code> is the port number</li><li>The port tells the operating system which application should receive the request</li></ul><p>Your laptop can run multiple applications at the same time. Ports help the OS route requests to the correct application.</p><h3>What happens when you visit a website?</h3><p>When you type:</p><p><a href="https://example.com">https://example.com</a></p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/DNS_Request_Flow_440532caf0.avif" alt="DNS + Request Flow.avif"></p><p>Behind the scenes:</p><ol><li>DNS resolves <code>example.com</code> to an IP address</li><li>Your browser sends a request to that IP</li><li>The request hits a server on a specific port</li><li>The server routes it to the correct application</li><li>The application processes the request and sends a response</li></ol><p>Remembering IP addresses is hard, so humans use domain names. Machines still talk using IP addresses.</p><h2>How Do We Deploy an Application?</h2><p>Locally, your application runs on your laptop.</p><p>To make it accessible to others:</p><ul><li>You need a public IP address</li><li>You need a machine that stays online</li><li>You need to expose your application to the internet</li></ul><p>Managing physical servers is painful. That is why cloud providers exist.</p><p>Cloud providers give you:</p><ul><li>Virtual machines</li><li>Public IP addresses</li><li>Networking</li><li>Security tools</li></ul><p>In AWS, a virtual machine is called an <strong>EC2 instance</strong>.</p><p>Uploading your application code from your laptop to a cloud server is called <strong>deployment</strong>.</p><h2>Latency and Throughput</h2><p>These two terms appear everywhere in system design discussions. They measure different things and both matter.</p><h3>Latency</h3><p>Latency is the <strong>time taken for a single request</strong> to go from the client to the server and back.</p><p>It is usually measured in milliseconds.</p><p>Examples:</p><ul><li>API responds in 120 ms</li><li>Webpage loads in 300 ms</li></ul><p>Lower latency means:</p><ul><li>Faster responses</li><li>Better user experience</li></ul><p>Higher latency means:</p><ul><li>Slower apps</li><li>Frustrated users</li><li>More retries and refreshes</li></ul><h3>Round Trip Time (RTT)</h3><p>RTT is the total time taken for:</p><ul><li>Request to reach the server</li><li>Response to come back</li></ul><p>RTT is often used interchangeably with latency.</p><h3>Throughput</h3><p>Throughput is the <strong>number of requests a system can handle per second</strong>.</p><p>It is measured as:</p><ul><li>Requests per second (RPS)</li><li>Transactions per second (TPS)</li></ul><p>A system can have:</p><ul><li>Low latency but low throughput</li><li>High throughput but high latency</li></ul><p>The ideal system has:</p><ul><li>Low latency</li><li>High throughput</li></ul><p>In reality, you usually balance between the two.</p><h3>Simple Analogy</h3><figure class="table"><table><thead><tr><th>Concept</th><th>Real World Example</th></tr></thead><tbody><tr><td>Latency</td><td>Time taken by one car to travel a road</td></tr><tr><td>Throughput</td><td>Number of cars that can pass per hour</td></tr></tbody></table></figure><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Latency_vs_Throughput_6e25483303.avif" alt="Latency vs Throughput.avif"></p><h2>Scaling Basics</h2><p>Scaling means <strong>handling more load</strong>.</p><p>Load can be:</p><ul><li>More users</li><li>More requests</li><li>More data</li></ul><p>There are only two ways to scale a system.</p><h3>Vertical Scaling</h3><p>Vertical scaling means increasing the power of a single machine.</p><p>Examples:</p><ul><li>More CPU cores</li><li>More RAM</li><li>Larger disk</li></ul><h3>Pros</h3><ul><li>Simple to implement</li><li>No architectural changes required</li></ul><h3>Cons</h3><ul><li>Has a hard upper limit</li><li>Expensive</li><li>Single point of failure</li></ul><p>Vertical scaling is usually the first step because it is easy.</p><h3>Horizontal Scaling</h3><p>Horizontal scaling means adding more machines and distributing the load.</p><p>Instead of one powerful server:</p><ul><li>Use many smaller servers</li><li>Spread traffic evenly</li></ul><p>Clients cannot decide which server to talk to. That is where load balancers come in.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Horizontal_Scaling_Load_Balancer_fe3308760c.avif" alt="Horizontal Scaling + Load Balancer.avif"></p><h2>Load Balancer (High Level)</h2><p>A load balancer:</p><ul><li>Acts as a single entry point</li><li>Receives all incoming requests</li><li>Forwards them to backend servers</li></ul><p>Clients only know the load balancer. Servers can be added or removed freely.</p><p>Horizontal scaling is the most common approach in real-world systems.</p><h2>Auto Scaling</h2><p>Traffic is rarely constant.</p><p>Some days:</p><ul><li>Low usage</li></ul><p>Some days:</p><ul><li>Traffic spikes suddenly</li></ul><p>Running maximum servers all the time is expensive and wasteful.</p><p>Auto scaling solves this.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Auto_Scaling_0ed0186537.avif" alt="Auto Scaling.avif"></p><h3>How Auto Scaling Works</h3><ul><li>Monitor server metrics like CPU or memory</li><li>Define thresholds</li><li>Add servers when load increases</li><li>Remove servers when load decreases</li></ul><p>This allows:</p><ul><li>Cost efficiency</li><li>High availability</li><li>Automatic recovery</li></ul><p>Auto scaling should always be combined with monitoring and alerts.</p><h2>Back-of-the-Envelope Estimation</h2><p>In system design interviews, you are expected to estimate scale.</p><p>Exact numbers are not required. Reasonable approximations are.</p><p>Spend around 5 minutes on this in interviews.</p><h3>Memory and Storage Reference Table</h3><figure class="table"><table><thead><tr><th>Unit</th><th>Approximate Size</th><th>Power of 10</th></tr></thead><tbody><tr><td>1 KB</td><td>1,000 bytes</td><td>10³</td></tr><tr><td>1 MB</td><td>1,000,000 bytes</td><td>10⁶</td></tr><tr><td>1 GB</td><td>1,000,000,000 bytes</td><td>10⁹</td></tr><tr><td>1 TB</td><td>1,000,000,000,000 bytes</td><td>10¹²</td></tr></tbody></table></figure><p>&nbsp;</p><h3>What We Usually Estimate</h3><ol><li>Load estimation</li><li>Storage estimation</li><li>Resource estimation</li></ol><h3>Example: Load Estimation</h3><p>Assume:</p><ul><li>50 million daily active users</li><li>Each user performs 10 actions per day</li></ul><p>Total actions per day:</p><p>50,000,000 x 10 = 500,000,000 actions/day</p><p>Approximate requests per second:</p><p>500,000,000 / 86,400 ≈ 5,800 requests/sec</p><h3>Example: Storage Estimation</h3><p>Assume:</p><ul><li>Each record is 1 KB</li><li>500 million records per day</li></ul><p>Daily storage required:</p><p>500 million x 1 KB = 500 GB per day</p><p>Monthly storage:</p><p>500 GB x 30 ≈ 15 TB</p><h3>Example: Resource Estimation</h3><p>Assume:</p><ul><li>6,000 requests per second</li><li>Each request takes 10 ms of CPU time</li></ul><p>Total CPU time per second:</p><p>6,000 x 10 ms = 60,000 ms</p><p>If one CPU core handles 1,000 ms per second:</p><p>60,000 / 1,000 = 60 CPU cores</p><p>If one server has 4 cores:</p><p>60 / 4 = 15 servers</p><h2>CAP Theorem</h2><p>CAP theorem is one of the most important ideas in system design.</p><p>It explains <strong>why distributed systems are forced to make trade-offs</strong>.</p><p>CAP stands for:</p><ul><li>Consistency</li><li>Availability</li><li>Partition Tolerance</li></ul><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/CAP_Theorem_Triangle_0e865ed113.avif" alt="CAP Theorem Triangle.avif"></p><p>This discussion always assumes we are talking about <strong>distributed systems</strong>.</p><h2>What Is a Distributed System?</h2><p>A distributed system is one where:</p><ul><li>Data is stored across multiple machines</li><li>Requests are served by multiple nodes</li><li>Systems communicate over a network</li></ul><p>We use distributed systems because:</p><ul><li>One machine is not enough at scale</li><li>We want fault tolerance</li><li>We want lower latency by serving users from nearby locations</li></ul><p>Each individual machine in a distributed system is called a <strong>node</strong>.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Distributed_Nodes_6de50cb8df.avif" alt="Distributed Nodes.avif"></p><h2>The Three Properties Explained</h2><h3>Consistency</h3><p>Consistency means:</p><ul><li>Every read returns the most recent write</li><li>All nodes see the same data at the same time</li></ul><p>If data is updated on one node, that update must be reflected on all nodes before reads are allowed.</p><p>Example:</p><ul><li>User updates their profile name</li><li>Any request from any node should show the updated name immediately</li></ul><hr><h3>Availability</h3><p>Availability means:</p><ul><li>Every request receives a response</li><li>The system continues to function even if some nodes fail</li></ul><p>The response does not need to be correct or latest, but the system should not refuse requests.</p><p>Example:</p><ul><li>One database replica crashes</li><li>Other replicas continue serving traffic</li></ul><hr><h3>Partition Tolerance</h3><p>Partition tolerance means:</p><ul><li>The system continues to operate even if network communication breaks between nodes</li></ul><p>Network failures are unavoidable in real systems. Because of this, <strong>partition tolerance is mandatory</strong> in distributed systems.</p><hr><h2>The Core Idea of CAP Theorem</h2><p>In a distributed system, you can only guarantee <strong>two out of three</strong> properties at the same time.</p><p>Possible combinations:</p><ul><li>CP (Consistency + Partition Tolerance)</li><li>AP (Availability + Partition Tolerance)</li></ul><p>Impossible combination:</p><ul><li>CAP (all three at once)</li></ul><hr><h2>Why Can We Not Have All Three?</h2><p>Assume three nodes:</p><ul><li>Node A</li><li>Node B</li><li>Node C</li></ul><p>Now assume a network partition occurs:</p><ul><li>Node B loses connection with A and C</li></ul><h3>If we choose Availability:</h3><ul><li>Node B continues serving requests</li><li>Node A and C continue serving requests</li><li>Data may become inconsistent</li></ul><p>Result:</p><ul><li>Availability achieved</li><li>Consistency sacrificed</li></ul><h3>If we choose Consistency:</h3><ul><li>Stop serving requests until network is restored</li><li>Prevent inconsistent writes</li></ul><p>Result:</p><ul><li>Consistency achieved</li><li>Availability sacrificed</li></ul><p>There is no way to avoid this trade-off.</p><hr><h2>Why Not Choose CA?</h2><p>CA assumes:</p><ul><li>No network failures</li></ul><p>In real-world distributed systems:</p><ul><li>Network partitions will happen</li><li>Latency spikes will happen</li><li>Nodes will temporarily disconnect</li></ul><p>That is why real systems always choose between <strong>CP or AP</strong>.</p><hr><h2>When to Choose CP vs AP</h2><h3>Choose CP When:</h3><ul><li>Data correctness is critical</li><li>Inconsistent data is unacceptable</li></ul><p>Examples:</p><ul><li>Banking systems</li><li>Payment systems</li><li>Stock trading platforms</li><li>Account balances</li></ul><hr><h3>Choose AP When:</h3><ul><li>High availability is more important than strict consistency</li><li>Slightly stale data is acceptable</li></ul><p>Examples:</p><ul><li>Social media feeds</li><li>Like counts</li><li>Comments</li><li>View counts</li></ul><hr><h2>Database Scaling</h2><p>Initially, applications use a single database server.</p><p>As traffic increases:</p><ul><li>Queries slow down</li><li>CPU usage increases</li><li>Disk IO becomes a bottleneck</li></ul><p>We scale databases <strong>step by step</strong>, not all at once.</p><p>Over-engineering early is just as bad as under-engineering.</p><hr><h2>Indexing</h2><p>Without indexes:</p><ul><li>Database scans every row</li><li>Time complexity is O(N)</li></ul><p>With indexes:</p><ul><li>Database uses a data structure like B-trees</li><li>Time complexity becomes O(log N)</li></ul><p>Indexes are created on columns that are frequently queried.</p><h3>Key Points About Indexing</h3><ul><li>Improves read performance</li><li>Slightly slows down writes</li><li>Uses extra storage</li><li>Should be added thoughtfully</li></ul><p>You rarely regret adding the right index.</p><hr><h2>Partitioning</h2><p>Partitioning means:</p><ul><li>Breaking a large table into smaller tables</li><li>All partitions live on the same database server</li></ul><p>Each partition has:</p><ul><li>Its own index</li><li>Smaller data size</li><li>Faster queries</li></ul><p>The database engine decides which partition to query.</p><p>Partitioning improves performance without changing application logic.</p><hr><h2>Master Slave Architecture</h2><p>Used when:</p><ul><li>Reads heavily outnumber writes</li><li>One database cannot handle read traffic</li></ul><h3>How It Works</h3><ul><li>One <strong>master</strong> handles all writes</li><li>Multiple <strong>slaves</strong> handle reads</li><li>Data is replicated from master to slaves</li></ul><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Master_Slave_Database_d569ad9f45.png" alt="Master-Slave Database.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Master_Slave_Database_d569ad9f45.png 221w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Master_Slave_Database_d569ad9f45.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Master_Slave_Database_d569ad9f45.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Master_Slave_Database_d569ad9f45.png 1000w," sizes="100vw"></p><p>Reads are distributed. Writes remain centralized.</p><hr><h2>Multi-Master Architecture</h2><p>Used when:</p><ul><li>Write traffic becomes very high</li><li>One master cannot handle all writes</li></ul><p>Multiple masters:</p><ul><li>Handle writes independently</li><li>Periodically sync data</li></ul><h3>Challenges</h3><ul><li>Write conflicts</li><li>Data reconciliation</li><li>Complex business logic</li></ul><p>Multi-master setups are powerful but risky.</p><hr><h2>Database Sharding</h2><p>Sharding means:</p><ul><li>Splitting data across multiple database servers</li><li>Each server holds a subset of the data</li></ul><p>Each server is called a <strong>shard</strong>.</p><p>Sharding is done using a <strong>sharding key</strong>.</p><p>&nbsp;</p><hr><h2>Sharding Strategies</h2><h3>Range-Based Sharding</h3><p>Data split by ranges.</p><p>Example:</p><ul><li>Users 1 to 1,000 on shard 1</li><li>Users 1,001 to 2,000 on shard 2</li></ul><p>Pros:</p><ul><li>Simple logic</li></ul><p>Cons:</p><ul><li>Uneven load</li><li>Hot shards</li></ul><hr><h3>Hash-Based Sharding</h3><p>Shard determined by hash function.</p><p>Example: hash(user_id) % number_of_shards</p><p>Pros:</p><ul><li>Even data distribution</li></ul><p>Cons:</p><ul><li>Hard to rebalance</li><li>Adding shards is complex</li></ul><hr><h3>Geographic Sharding</h3><p>Data split by region.</p><p>Example:</p><ul><li>Asia users on one shard</li><li>Europe users on another shard</li></ul><p>Pros:</p><ul><li>Low latency</li></ul><p>Cons:</p><ul><li>Traffic imbalance</li></ul><hr><h3>Directory-Based Sharding</h3><p>A lookup table maps keys to shards.</p><p>Pros:</p><ul><li>Flexible</li><li>Easy to reassign shards</li></ul><p>Cons:</p><ul><li>Lookup table becomes a bottleneck</li></ul><hr><h2>Disadvantages of Sharding</h2><ul><li>Complex application logic</li><li>Expensive joins</li><li>Hard consistency guarantees</li><li>Difficult rebalancing</li></ul><p>Avoid sharding until absolutely necessary.</p><hr><h2>Summary of Database Scaling</h2><p>Follow this order:</p><ol><li>Vertical scaling</li><li>Indexing</li><li>Partitioning</li><li>Read replicas</li><li>Sharding</li></ol><p>Scale only when needed.</p><hr><h2>SQL vs NoSQL Databases</h2><p>Choosing the right database matters more than choosing the popular one.</p><hr><h2>SQL Databases</h2><p>Characteristics:</p><ul><li>Structured schema</li><li>Tables and rows</li><li>Strong consistency</li><li>ACID guarantees</li></ul><p>Examples:</p><ul><li>MySQL</li><li>PostgreSQL</li><li>Oracle</li></ul><p>Use SQL when:</p><ul><li>Data integrity matters</li><li>Complex joins are required</li><li>Transactions are critical</li></ul><hr><h2>NoSQL Databases</h2><p>Characteristics:</p><ul><li>Flexible schema</li><li>Horizontal scaling</li><li>High availability</li><li>Eventual consistency</li></ul><p>Types:</p><figure class="table"><table><thead><tr><th>Type</th><th>Example</th><th>Use Case</th></tr></thead><tbody><tr><td>Document</td><td>MongoDB</td><td>JSON-like data</td></tr><tr><td>Key-Value</td><td>Redis</td><td>Caching</td></tr><tr><td>Column</td><td>Cassandra</td><td>Large-scale writes</td></tr><tr><td>Graph</td><td>Neo4j</td><td>Relationship queries</td></tr></tbody></table></figure><hr><h2>Scaling Differences</h2><figure class="table"><table><thead><tr><th>Feature</th><th>SQL</th><th>NoSQL</th></tr></thead><tbody><tr><td>Scaling</td><td>Vertical</td><td>Horizontal</td></tr><tr><td>Schema</td><td>Fixed</td><td>Flexible</td></tr><tr><td>Consistency</td><td>Strong</td><td>Eventual</td></tr><tr><td>Joins</td><td>Supported</td><td>Limited</td></tr></tbody></table></figure><hr><h2>When to Use Which</h2><p>Use SQL when:</p><ul><li>Financial data</li><li>User accounts</li><li>Orders and payments</li></ul><p>Use NoSQL when:</p><ul><li>High traffic</li><li>Large datasets</li><li>Real-time systems</li><li>Low latency requirements</li></ul><p>Many production systems use <strong>both together</strong>.</p><hr><h2>End of Part 2</h2><p>In this part, you learned:</p><ul><li>CAP theorem</li><li>Distributed system trade-offs</li><li>Database scaling strategies</li><li>SQL vs NoSQL decision making</li></ul><p>Next part will cover:</p><ul><li>Microservices</li><li>Load balancer deep dive</li><li>Caching and Redis</li></ul><h2>Microservices</h2><p>Before microservices became popular, most applications were built as <strong>monoliths</strong>.</p><p>Understanding the difference is critical.</p><hr><h2>Monolith Architecture</h2><p>In a monolith:</p><ul><li>Entire backend is one single application</li><li>All features live in the same codebase</li><li>Deployed as one unit</li></ul><p>Example for an e-commerce app:</p><ul><li>User management</li><li>Product listing</li><li>Orders</li><li>Payments</li></ul><p>All of this exists in one backend service.</p><h3>Advantages of Monolith</h3><ul><li>Simple to build initially</li><li>Easy to debug at small scale</li><li>Faster development for small teams</li></ul><h3>Disadvantages of Monolith</h3><ul><li>Hard to scale individual features</li><li>One crash can bring down everything</li><li>Codebase becomes messy over time</li><li>Deployments become risky</li></ul><p>Most startups begin with a monolith. That is normal and often the right choice.</p><hr><h2>Microservice Architecture</h2><p>Microservices break a large application into <strong>small, independent services</strong>.</p><p>Each service:</p><ul><li>Has its own codebase</li><li>Has its own database (usually)</li><li>Can be deployed independently</li></ul><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Monolith_vs_Microservices_a5569b287a.png" alt="Monolith vs Microservices.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Monolith_vs_Microservices_a5569b287a.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Monolith_vs_Microservices_a5569b287a.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Monolith_vs_Microservices_a5569b287a.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Monolith_vs_Microservices_a5569b287a.png 1000w," sizes="100vw"></p><p>Example microservices for e-commerce:</p><ul><li>User Service</li><li>Product Service</li><li>Order Service</li><li>Payment Service</li></ul><hr><h2>Why Do We Use Microservices?</h2><h3>Independent Scaling</h3><p>If Product Service gets more traffic:</p><ul><li>Scale only Product Service</li><li>No need to scale entire system</li></ul><h3>Independent Deployments</h3><ul><li>Deploy Order Service without touching Payment Service</li><li>Fewer production risks</li></ul><h3>Fault Isolation</h3><ul><li>Payment Service crash does not kill User Service</li><li>System degrades gracefully</li></ul><h3>Technology Flexibility</h3><ul><li>One service in Node.js</li><li>Another in Go</li><li>Another in Java</li></ul><p>Each team can choose what fits best.</p><hr><h2>When Should You Use Microservices?</h2><p>Do not start with microservices blindly.</p><p>Microservices make sense when:</p><ul><li>Team size increases</li><li>Multiple teams work independently</li><li>Application grows large</li><li>Deployment frequency increases</li><li>You want to avoid single point of failure</li></ul><p>Small teams with early-stage products should usually start with a monolith.</p><hr><h2>How Clients Communicate in Microservices</h2><p>Each microservice runs on:</p><ul><li>Different machines</li><li>Different IP addresses</li><li>Different ports</li></ul><p>Clients should not manage this complexity.</p><p>So we introduce an <strong>API Gateway</strong>.</p><hr><h2>API Gateway</h2><p>API Gateway:</p><ul><li>Acts as a single entry point</li><li>Routes requests to correct microservices</li><li>Hides internal architecture from clients</li></ul><p>Client: /login /products /orders</p><p>Gateway:</p><ul><li>Sends <code>/login</code> to User Service</li><li>Sends <code>/products</code> to Product Service</li><li>Sends <code>/orders</code> to Order Service</li></ul><hr><h2>Additional Responsibilities of API Gateway</h2><ul><li>Authentication and authorization</li><li>Rate limiting</li><li>Request validation</li><li>Response aggregation</li><li>Caching</li></ul><p>API Gateway simplifies client logic and centralizes cross-cutting concerns.</p><hr><h2>Load Balancer Deep Dive</h2><p>Whenever you horizontally scale services, you need a load balancer.</p><p>Clients should not know:</p><ul><li>How many servers exist</li><li>Which server is healthy</li><li>Which server is busy</li></ul><hr><h2>Why Load Balancer Is Required</h2><p>Without a load balancer:</p><ul><li>Clients must know all server IPs</li><li>Clients must decide routing</li><li>Failures become client problems</li></ul><p>With a load balancer:</p><ul><li>Single entry point</li><li>Automatic traffic distribution</li><li>Health checks</li><li>Failover handling</li></ul><hr><h2>Load Balancer Algorithms</h2><h3>Round Robin</h3><p>Requests are sent to servers sequentially.</p><p>Example:</p><ul><li>Request 1 to Server A</li><li>Request 2 to Server B</li><li>Request 3 to Server C</li><li>Repeat</li></ul><p>Pros:</p><ul><li>Simple</li><li>Fair distribution</li></ul><p>Cons:</p><ul><li>Ignores server load</li><li>Assumes equal capacity</li></ul><hr><h3>Weighted Round Robin</h3><p>Each server has a weight.</p><p>Servers with higher weight:</p><ul><li>Receive more requests</li></ul><p>Useful when:</p><ul><li>Servers have different hardware capacity</li></ul><hr><h3>Least Connections</h3><p>Traffic is routed to:</p><ul><li>Server with fewest active connections</li></ul><p>Pros:</p><ul><li>Dynamic</li><li>Adapts to real-time load</li></ul><p>Cons:</p><ul><li>Not ideal when requests vary greatly in duration</li></ul><hr><h3>Hash-Based Routing</h3><p>Routing based on:</p><ul><li>Client IP</li><li>User ID</li><li>Session ID</li></ul><p>Ensures:</p><ul><li>Same user hits same server</li></ul><p>Useful for:</p><ul><li>Session persistence</li><li>Stateful applications</li></ul><hr><h2>Caching</h2><p>Caching is one of the highest impact optimizations in system design.</p><p>Caching stores:</p><ul><li>Frequently accessed data</li><li>In fast storage</li><li>For quick retrieval</li></ul><hr><h2>Why Caching Is Needed</h2><p>Database access is slow compared to memory.</p><p>Example:</p><ul><li>Database fetch takes 500 ms</li><li>Processing takes 100 ms</li><li>Total response time is 600 ms</li></ul><p>With caching:</p><ul><li>Cached response served in 50 ms</li></ul><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Cache_Hit_vs_Cache_Miss_3292a7b3d9.avif" alt="Cache Hit vs Cache Miss.avif"></p><p>Huge improvement with minimal effort.</p><hr><h2>Where Can We Cache?</h2><h3>Client Side Cache</h3><ul><li>Browser cache</li><li>Mobile app cache</li></ul><p>Used for:</p><ul><li>Static files</li><li>Images</li><li>Scripts</li></ul><hr><h3>Server Side Cache</h3><ul><li>Stored on backend servers</li><li>Often in memory</li></ul><p>Examples:</p><ul><li>Redis</li><li>Memcached</li></ul><hr><h3>CDN Cache</h3><ul><li>Used for static content</li><li>Geographically distributed</li></ul><p>Examples:</p><ul><li>Images</li><li>Videos</li><li>Stylesheets</li></ul><hr><h3>Application Level Cache</h3><ul><li>Inside application code</li><li>Stores computed results</li><li>Avoids repeated computation</li></ul><hr><h2>Cache Invalidation</h2><p>Caching is easy. Invalidation is hard.</p><p>Whenever data changes:</p><ul><li>Cached value must be updated or removed</li></ul><p>Common strategies:</p><ul><li>Time based expiration</li><li>Manual eviction</li><li>Write-through cache</li></ul><p>Poor invalidation leads to stale data bugs.</p><hr><h2>Redis Introduction</h2><p>Redis is an in-memory data store.</p><p>In-memory means:</p><ul><li>Data stored in RAM</li><li>Extremely fast read and write</li></ul><p>Redis is commonly used for:</p><ul><li>Caching</li><li>Rate limiting</li><li>Pub-sub</li><li>Session storage</li></ul><hr><h2>Why Not Store Everything in Redis?</h2><p>RAM is expensive and limited.</p><p>Databases:</p><ul><li>Store data on disk</li><li>Handle large volumes</li><li>Persist data reliably</li></ul><p>Redis:</p><ul><li>Fast but volatile</li><li>Data may be lost if not persisted</li></ul><p>Redis complements databases. It does not replace them.</p><hr><h2>Redis Data Model</h2><p>Redis stores data as <strong>key-value pairs</strong>.</p><p>Key naming convention: user:1 user:1:email product:45</p><p>Colon separation helps readability and grouping.</p><hr><h2>Common Redis Data Types</h2><h3>String</h3><ul><li>Simple key-value</li><li>Most commonly used</li></ul><p>Commands:</p><ul><li>SET</li><li>GET</li><li>MGET</li></ul><hr><h3>List</h3><p>Ordered collection.</p><p>Commands:</p><ul><li>LPUSH</li><li>RPUSH</li><li>LPOP</li><li>RPOP</li></ul><p>Use cases:</p><ul><li>Queues</li><li>Stacks</li></ul><hr><h3>Set</h3><ul><li>Unique values</li><li>No duplicates</li></ul><p>Use cases:</p><ul><li>Unique visitors</li><li>Tags</li></ul><hr><h3>Hash</h3><ul><li>Key-value pairs inside a key</li><li>Similar to an object</li></ul><p>Use cases:</p><ul><li>User profiles</li><li>Configurations</li></ul><hr><h2>Redis TTL (Time To Live)</h2><p>Keys can have expiration time.</p><p>Example:</p><ul><li>Cache valid for 24 hours</li><li>Automatically deleted after expiry</li></ul><p>TTL helps:</p><ul><li>Avoid stale data</li><li>Control memory usage</li></ul><hr><h2>Cache Hit and Cache Miss</h2><ul><li>Cache hit: Data found in cache</li><li>Cache miss: Data not found in cache</li></ul><p>Flow:</p><ol><li>Check cache</li><li>If hit, return data</li><li>If miss, fetch from database</li><li>Store in cache</li><li>Return response</li></ol><hr><h2>Write-Through vs Read-Through Cache</h2><h3>Read-Through</h3><ul><li>Cache populated on read</li><li>Cache miss triggers database read</li></ul><h3>Write-Through</h3><ul><li>Data written to cache and database together</li><li>Ensures cache consistency</li></ul><p>Choice depends on use case.</p><hr><h2>End of Part 3</h2><p>In this part, you learned:</p><ul><li>Monolith vs microservices</li><li>API gateway</li><li>Load balancer internals</li><li>Caching strategies</li><li>Redis fundamentals</li></ul><p>Next part will cover:</p><ul><li>Blob storage</li><li>CDN</li><li>Message brokers</li><li>Kafka</li><li>Pub-sub systems</li></ul><h2>Blob Storage</h2><p>Databases are great at storing:</p><ul><li>Text</li><li>Numbers</li><li>Structured records</li></ul><p>Databases are terrible at storing:</p><ul><li>Images</li><li>Videos</li><li>PDFs</li><li>Audio files</li></ul><p>Trying to store large binary files inside databases leads to:</p><ul><li>Slow queries</li><li>Huge backups</li><li>Scaling nightmares</li></ul><p>That is why blob storage exists.</p><hr><h2>What Is a Blob?</h2><p>Blob stands for <strong>Binary Large Object</strong>.</p><p>Any file such as:</p><ul><li>Image</li><li>Video</li><li>PDF</li><li>ZIP</li><li>Audio</li></ul><p>Can be represented as a sequence of binary data. That binary data is called a blob.</p><hr><h2>Why We Do Not Store Blobs in Databases</h2><p>Problems with storing blobs in databases:</p><ul><li>Large row sizes</li><li>Slow reads and writes</li><li>Difficult scaling</li><li>Expensive storage</li></ul><p>Databases are optimized for structured data, not large files.</p><hr><h2>Blob Storage Services</h2><p>Blob storage is usually a managed service.</p><p>Examples:</p><ul><li>AWS S3</li><li>Cloudflare R2</li><li>Google Cloud Storage</li><li>Azure Blob Storage</li></ul><p>These services handle:</p><ul><li>Scaling</li><li>Durability</li><li>Replication</li><li>Availability</li></ul><p>You treat them like a black box.</p><hr><h2>How Blob Storage Is Used</h2><p>Typical flow:</p><ol><li>Client uploads file</li><li>Backend generates upload credentials</li><li>File stored in blob storage</li><li>Database stores file URL or metadata</li><li>Client accesses file via URL</li></ol><p>Database stores references, not the file itself.</p><hr><h2>AWS S3 Basics</h2><p>You can think of S3 like Google Drive for applications.</p><p>Key properties:</p><ul><li>Extremely cheap storage</li><li>Virtually unlimited size</li><li>High durability</li><li>Global availability</li></ul><p>S3 is ideal for:</p><ul><li>Images</li><li>Videos</li><li>Static website files</li><li>Backups</li><li>Logs</li></ul><hr><h2>Important S3 Concepts</h2><figure class="table"><table><thead><tr><th>Concept</th><th>Meaning</th></tr></thead><tbody><tr><td>Bucket</td><td>Container for files</td></tr><tr><td>Object</td><td>A file stored in S3</td></tr><tr><td>Key</td><td>Path of the file</td></tr><tr><td>Region</td><td>Physical location</td></tr></tbody></table></figure><p>S3 provides durability close to 100 percent by replicating data internally.</p><hr><h2>Content Delivery Network (CDN)</h2><p>Serving files directly from blob storage works. Serving them fast worldwide does not.</p><p>CDN solves this problem.</p><hr><h2>What Is a CDN?</h2><p>A CDN is a network of servers distributed across the world.</p><p>These servers:</p><ul><li>Cache static content</li><li>Serve users from nearby locations</li><li>Reduce latency</li></ul><p>Examples:</p><ul><li>AWS CloudFront</li><li>Cloudflare CDN</li><li>Akamai</li></ul><hr><h2>Why CDN Is Needed</h2><p>Assume:</p><ul><li>Files stored in India</li><li>User requests from USA</li></ul><p>Without CDN:</p><ul><li>High latency</li><li>Slow loading</li><li>Poor experience</li></ul><p>With CDN:</p><ul><li>File cached near user</li><li>Faster response</li><li>Reduced load on origin server</li></ul><hr><h2>How CDN Works</h2><ol><li>User requests a file</li><li>Request goes to nearest edge server</li><li>If file exists in cache, return it</li><li>If not, fetch from origin</li><li>Cache it at edge</li><li>Serve future requests locally</li></ol><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/CDN_How_It_Works_25cacb90f4.avif" alt="CDN — How It Works.avif"></p><hr><h2>CDN Terminology</h2><figure class="table"><table><thead><tr><th>Term</th><th>Description</th></tr></thead><tbody><tr><td>Edge Server</td><td>CDN server near user</td></tr><tr><td>Origin Server</td><td>Original source like S3</td></tr><tr><td>TTL</td><td>Cache expiry duration</td></tr><tr><td>Cache Hit</td><td>File served from CDN</td></tr><tr><td>Cache Miss</td><td>File fetched from origin</td></tr></tbody></table></figure><hr><h2>Message Broker</h2><p>Not all tasks should be handled synchronously.</p><p>Some tasks:</p><ul><li>Take too long</li><li>Are non-critical</li><li>Should not block user response</li></ul><p>That is where message brokers are used.</p><hr><h2>Synchronous vs Asynchronous Processing</h2><h3>Synchronous</h3><ul><li>Client waits for response</li><li>Used for quick operations</li><li>Risk of timeouts for long tasks</li></ul><h3>Asynchronous</h3><ul><li>Client gets immediate acknowledgement</li><li>Task processed in background</li><li>User notified later if needed</li></ul><hr><h2>Why Message Brokers Are Used</h2><p>Message brokers help with:</p><ul><li>Decoupling services</li><li>Reliability</li><li>Retry mechanisms</li><li>Load buffering</li></ul><p>Producer and consumer do not need to know about each other.</p><hr><h2>Message Broker Components</h2><figure class="table"><table><thead><tr><th>Role</th><th>Description</th></tr></thead><tbody><tr><td>Producer</td><td>Sends messages</td></tr><tr><td>Broker</td><td>Stores messages</td></tr><tr><td>Consumer</td><td>Processes messages</td></tr></tbody></table></figure><hr><h2>Types of Message Brokers</h2><p>There are two major types:</p><ol><li>Message Queues</li><li>Message Streams</li></ol><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Message_Queue_vs_Stream_36bd8af61e.avif" alt="Message Queue vs Stream.avif"></p><p>They solve different problems.</p><hr><h2>Message Queue</h2><p>In a message queue:</p><ul><li>One message is processed by one consumer</li><li>Message is deleted after processing</li></ul><p>Examples:</p><ul><li>RabbitMQ</li><li>AWS SQS</li></ul><hr><h2>When to Use Message Queues</h2><p>Use message queues when:</p><ul><li>One consumer should handle a task</li><li>Task must not be duplicated</li><li>Order matters less</li></ul><p>Examples:</p><ul><li>Email sending</li><li>PDF generation</li><li>Image resizing</li></ul><hr><h2>Message Stream</h2><p>In a message stream:</p><ul><li>One message can be consumed by many consumers</li><li>Messages are not deleted immediately</li><li>Consumers track their own progress</li></ul><p>Examples:</p><ul><li>Apache Kafka</li><li>AWS Kinesis</li></ul><hr><h2>When to Use Message Streams</h2><p>Use message streams when:</p><ul><li>Same event must trigger multiple actions</li><li>High throughput is required</li><li>Event history is valuable</li></ul><p>Examples:</p><ul><li>Activity logs</li><li>Analytics</li><li>Event sourcing</li></ul><hr><h2>Apache Kafka Overview</h2><p>Kafka is a distributed message streaming platform.</p><p>It is designed for:</p><ul><li>High throughput</li><li>Fault tolerance</li><li>Scalability</li></ul><p>Kafka can handle millions of messages per second.</p><hr><h2>Kafka Core Concepts</h2><figure class="table"><table><thead><tr><th>Concept</th><th>Meaning</th></tr></thead><tbody><tr><td>Producer</td><td>Sends messages</td></tr><tr><td>Consumer</td><td>Reads messages</td></tr><tr><td>Broker</td><td>Kafka server</td></tr><tr><td>Topic</td><td>Message category</td></tr><tr><td>Partition</td><td>Subdivision of topic</td></tr></tbody></table></figure><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Kafka_Topics_and_Consumer_Groups_cdab8f6af9.avif" alt="Kafka Topics &amp; Consumer Groups.avif"></p><hr><h2>Kafka Topics and Partitions</h2><p>Topics are split into partitions.</p><p>Partitions allow:</p><ul><li>Parallel processing</li><li>Horizontal scaling</li></ul><p>Each partition:</p><ul><li>Is ordered</li><li>Can be processed by only one consumer per group</li></ul><hr><h2>Consumer Groups</h2><p>Consumers belong to groups.</p><p>Rules:</p><ul><li>One partition assigned to one consumer per group</li><li>Multiple groups can read same topic</li><li>Enables parallelism</li></ul><hr><h2>Kafka Rebalancing</h2><p>When:</p><ul><li>Consumer joins</li><li>Consumer leaves</li><li>Partition count changes</li></ul><p>Kafka automatically reassigns partitions. No manual intervention required.</p><hr><h2>Kafka Use Case Example</h2><p>Assume:</p><ul><li>Ride-sharing app</li><li>Driver location updated every 2 seconds</li></ul><p>Instead of writing directly to database:</p><ul><li>Write updates to Kafka</li><li>Batch write to database later</li></ul><p>This reduces database load drastically.</p><hr><h2>Realtime PubSub</h2><p>PubSub stands for Publish Subscribe.</p><p>In PubSub:</p><ul><li>Messages are pushed immediately</li><li>No storage by default</li><li>Real-time delivery</li></ul><hr><h2>PubSub vs Message Broker</h2><figure class="table"><table><thead><tr><th>Feature</th><th>Message Broker</th><th>PubSub</th></tr></thead><tbody><tr><td>Storage</td><td>Yes</td><td>No</td></tr><tr><td>Delivery</td><td>Pull based</td><td>Push based</td></tr><tr><td>Latency</td><td>Medium</td><td>Very low</td></tr><tr><td>Use Case</td><td>Background jobs</td><td>Realtime updates</td></tr></tbody></table></figure><hr><h2>Redis PubSub</h2><p>Redis supports PubSub.</p><p>Used for:</p><ul><li>Realtime chat</li><li>Notifications</li><li>Live updates</li></ul><hr><h2>PubSub Example</h2><p>In a chat application:</p><ul><li>Clients connected to different servers</li><li>Messages published to Redis channel</li><li>All subscribed servers receive message</li><li>Servers forward message to connected clients</li></ul><p>This enables realtime communication across servers.</p><hr><h2>Limitations of PubSub</h2><ul><li>No message persistence</li><li>If consumer is offline, message is lost</li><li>Not suitable for critical workflows</li></ul><p>PubSub is for speed, not reliability.</p><hr><h2>End of Part 4</h2><p>In this part, you learned:</p><ul><li>Blob storage and S3</li><li>CDN concepts</li><li>Message brokers</li><li>Message queues vs streams</li><li>Kafka internals</li><li>Realtime PubSub</li></ul><p>Next part will cover:</p><ul><li>Event-driven architecture</li><li>Distributed systems</li><li>Leader election</li><li>Consistency deep dive</li><li>Consistent hashing</li><li>Data redundancy</li><li>Proxy</li><li>How to solve any system design problem</li></ul><h2>Event-Driven Architecture (EDA)</h2><p>Event-driven architecture is a way of designing systems where:</p><ul><li>Services react to events</li><li>Components are loosely coupled</li><li>Workflows are asynchronous by default</li></ul><p>Instead of calling services directly, systems communicate by emitting events.</p><hr><h2>Why Do We Need Event-Driven Architecture?</h2><p>Consider an e-commerce application.</p><p>When an order is placed:</p><ul><li>Order service creates the order</li><li>Payment service processes payment</li><li>Inventory service updates stock</li><li>Notification service sends confirmation</li><li>Analytics service records the event</li></ul><p>If these are synchronous calls:</p><ul><li>One failure breaks everything</li><li>Latency increases</li><li>Tight coupling forms</li></ul><p>EDA solves this.</p><hr><h2>How EDA Works</h2><ol><li>An event occurs</li><li>Event is published to an event bus</li><li>Multiple consumers listen to the event</li><li>Each consumer reacts independently</li></ol><p>The producer does not know who consumes the event.</p><hr><h2>Event Notification vs Event-Carried State</h2><h3>Event Notification</h3><p>Event contains minimal information.</p><p>Example: order_created { order_id }</p><p>Consumers fetch required data separately.</p><p>Pros:</p><ul><li>Lightweight events</li></ul><p>Cons:</p><ul><li>Extra database calls</li></ul><hr><h3>Event-Carried State Transfer</h3><p>Event carries full data.</p><p>Example: order_created { order_id, user_id, amount, items }</p><p>Pros:</p><ul><li>No extra fetch required</li></ul><p>Cons:</p><ul><li>Larger events</li><li>Schema evolution complexity</li></ul><hr><h2>Distributed Systems</h2><p>A distributed system consists of:</p><ul><li>Multiple nodes</li><li>Network communication</li><li>Shared responsibility</li></ul><p>Distributed systems exist because:</p><ul><li>One machine is not enough</li><li>We need fault tolerance</li><li>We want scalability</li></ul><hr><h2>Problems in Distributed Systems</h2><p>Distributed systems introduce challenges:</p><ul><li>Partial failures</li><li>Network latency</li><li>Clock synchronization</li><li>Data consistency</li></ul><p>Designing distributed systems is about <strong>handling failures gracefully</strong>.</p><hr><h2>Leader Election</h2><p>In many distributed systems:</p><ul><li>One node must act as leader</li><li>Leader coordinates work</li><li>Followers execute tasks</li></ul><p>Leader election decides:</p><ul><li>Which node becomes leader</li><li>How leadership changes on failure</li></ul><hr><h2>Why Leader Election Is Needed</h2><p>Examples:</p><ul><li>Distributed locks</li><li>Scheduled jobs</li><li>Master coordination</li><li>Metadata management</li></ul><p>Without a leader:</p><ul><li>Duplicate work</li><li>Conflicts</li><li>Inconsistent state</li></ul><hr><h2>How Leader Election Works (High Level)</h2><p>Common approaches:</p><ul><li>Using distributed coordination systems</li><li>Heartbeats to detect failure</li><li>Automatic re-election</li></ul><p>Popular tools:</p><ul><li>ZooKeeper</li><li>etcd</li><li>Consul</li></ul><p>When leader fails:</p><ul><li>New leader is elected automatically</li><li>System recovers without downtime</li></ul><hr><h2>Consistency Deep Dive</h2><p>Consistency defines how up-to-date data appears across nodes.</p><p>There are multiple consistency models.</p><hr><h2>Strong Consistency</h2><p>Strong consistency guarantees:</p><ul><li>Reads always return latest write</li><li>No stale data</li></ul><p>Used when correctness matters.</p><p>Examples:</p><ul><li>Banking balances</li><li>Financial ledgers</li><li>Inventory counts for purchases</li></ul><p>Trade-off:</p><ul><li>Higher latency</li><li>Lower availability during failures</li></ul><hr><h2>Eventual Consistency</h2><p>Eventual consistency guarantees:</p><ul><li>Data will become consistent over time</li><li>Temporary inconsistency is allowed</li></ul><p>Used when availability matters more.</p><p>Examples:</p><ul><li>Social media likes</li><li>Feed updates</li><li>View counts</li></ul><hr><h2>When to Choose Which</h2><figure class="table"><table><thead><tr><th>Use Case</th><th>Consistency Type</th></tr></thead><tbody><tr><td>Payments</td><td>Strong</td></tr><tr><td>Orders</td><td>Strong</td></tr><tr><td>Social feeds</td><td>Eventual</td></tr><tr><td>Analytics</td><td>Eventual</td></tr></tbody></table></figure><hr><h2>Achieving Strong Consistency</h2><p>Common techniques:</p><ul><li>Distributed locks</li><li>Synchronous replication</li><li>Two-phase commit</li><li>Leader-based writes</li></ul><p>These approaches reduce availability but ensure correctness.</p><hr><h2>Achieving Eventual Consistency</h2><p>Common techniques:</p><ul><li>Asynchronous replication</li><li>Conflict resolution</li><li>Versioning</li><li>Last-write-wins strategy</li></ul><p>Eventual consistency trades accuracy for speed and availability.</p><hr><h2>Consistent Hashing</h2><p>Consistent hashing is used to:</p><ul><li>Distribute data evenly</li><li>Reduce data movement when nodes change</li></ul><p>Used in:</p><ul><li>Caching systems</li><li>Load balancers</li><li>Distributed databases</li></ul><hr><h2>Problem With Normal Hashing</h2><p>Normal hashing: hash(key) % number_of_nodes</p><p>When nodes change:</p><ul><li>Almost all keys are remapped</li><li>Cache becomes useless</li></ul><hr><h2>How Consistent Hashing Solves This</h2><ul><li>Nodes placed on a hash ring</li><li>Keys mapped to nearest node clockwise</li><li>Only a small subset of keys move when nodes change</li></ul><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Consistent_Hashing_Ring_d0d019e13b.avif" alt="Consistent Hashing Ring.avif"></p><p>This makes scaling efficient.</p><hr><h2>Virtual Nodes</h2><p>To avoid uneven distribution:</p><ul><li>Each physical node has multiple virtual nodes</li><li>Improves balance</li><li>Reduces hotspots</li></ul><p>Most real implementations use virtual nodes.</p><hr><h2>Data Redundancy and Data Recovery</h2><p>Failures are inevitable.</p><p>Disks fail. Servers crash. Regions go down.</p><p>Data redundancy protects against data loss.</p><hr><h2>Why Data Redundancy Is Needed</h2><ul><li>Hardware failure</li><li>Human error</li><li>Natural disasters</li><li>Software bugs</li></ul><p>If data exists only in one place, it will be lost eventually.</p><hr><h2>Common Redundancy Techniques</h2><h3>Replication</h3><ul><li>Multiple copies of data</li><li>Stored across nodes or regions</li></ul><h3>Backups</h3><ul><li>Periodic snapshots</li><li>Stored separately</li><li>Used for recovery</li></ul><h3>Continuous Backup</h3><ul><li>Near real-time replication</li><li>Minimal data loss</li></ul><hr><h2>Recovery Strategies</h2><figure class="table"><table><thead><tr><th>Strategy</th><th>Purpose</th></tr></thead><tbody><tr><td>Point-in-time recovery</td><td>Restore to specific moment</td></tr><tr><td>Failover</td><td>Switch to replica</td></tr><tr><td>Disaster recovery</td><td>Region-level failure</td></tr></tbody></table></figure><p>Always test backups. Untested backups do not exist.</p><hr><h2>Proxy</h2><p>A proxy acts as an intermediary between:</p><ul><li>Client and server</li><li>Server and backend services</li></ul><hr><h2>Forward Proxy</h2><p>Used on client side.</p><p>Examples:</p><ul><li>Corporate proxies</li><li>VPNs</li><li>Content filtering</li></ul><p>Client knows proxy exists.</p><hr><h2>Reverse Proxy</h2><p>Used on server side.</p><p>Examples:</p><ul><li>Nginx</li><li>HAProxy</li><li>Cloudflare</li></ul><p>Client does not know backend servers.</p><hr><h2>Why Reverse Proxies Are Used</h2><ul><li>Load balancing</li><li>Security</li><li>SSL termination</li><li>Caching</li><li>Request routing</li></ul><p>Reverse proxies are foundational in modern architectures.</p><hr><h2>How to Solve Any System Design Problem</h2><p>This is the most important section.</p><hr><h2>Step 1: Clarify Requirements</h2><p>Ask questions:</p><ul><li>Scale</li><li>Read vs write ratio</li><li>Latency expectations</li><li>Consistency needs</li></ul><p>Never assume.</p><hr><h2>Step 2: Estimate Scale</h2><ul><li>Users</li><li>Requests per second</li><li>Storage growth</li></ul><p>Use back-of-the-envelope estimation.</p><hr><h2>Step 3: High-Level Design</h2><ul><li>Clients</li><li>APIs</li><li>Databases</li><li>Caches</li><li>Message brokers</li></ul><p>Draw boxes first, not tables.</p><hr><h2>Step 4: Identify Bottlenecks</h2><p>Ask:</p><ul><li>What fails first?</li><li>What does not scale?</li><li>What is expensive?</li></ul><hr><h2>Step 5: Apply Scaling Techniques</h2><ul><li>Caching</li><li>Replication</li><li>Sharding</li><li>Load balancing</li><li>Async processing</li></ul><hr><h2>Step 6: Discuss Trade-offs</h2><p>Every design has trade-offs.</p><p>Talk about:</p><ul><li>Consistency vs availability</li><li>Cost vs performance</li><li>Simplicity vs scalability</li></ul><p>Interviewers care about reasoning, not perfection.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/System_Design_Interview_Framework_c9d8a5aa28.avif" alt="System Design Interview Framework.avif"></p><hr><h2>Final Thoughts</h2><p>System design is not about drawing fancy diagrams.</p><p>It is about:</p><ul><li>Thinking clearly</li><li>Making reasonable trade-offs</li><li>Designing for failure</li><li>Keeping systems simple</li></ul><p>Everyone learns system design by building systems that break.</p><p>Build. Observe. Fix. Repeat.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Rohan Saxena)</author>
            <category>system design</category>
            <category>system design interview</category>
            <category>distributed systems</category>
            <category>scalability</category>
            <category>microservices</category>
            <category>load balancer</category>
            <category>caching</category>
            <category>Redis</category>
            <category>Apache Kafka</category>
            <category>CAP theorem</category>
            <category>database sharding</category>
            <category>CDN</category>
            <category>API gateway</category>
            <category>horizontal scaling</category>
            <category>vertical scaling</category>
            <category>auto scaling</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/System_Design_in_One_Shot_97afc77fc6.avif" length="0" type="image/avif"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot 4 : A Complete Guide to New Features, Improvements & Why You Should Upgrade]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-boot-4-a-complete-guide-to-new-features-improvements-and-why-you-should-upgrade</link>
            <guid>https://www.codingshuttle.com/blogs/spring-boot-4-a-complete-guide-to-new-features-improvements-and-why-you-should-upgrade</guid>
            <pubDate>Sat, 22 Nov 2025 08:56:15 GMT</pubDate>
            <description><![CDATA[Spring Boot 4 is finally here, bringing major improvements like modular auto-configuration, native API versioning, JSpecify null safety, declarative HTTP clients, and advanced observability. This guide breaks down every new feature, why it matters, and how it future-proofs your Java applications.]]></description>
            <content:encoded><![CDATA[<p>Hello, Spring developers! The wait is over. <strong>Spring Boot 4</strong> (released November 2025) is here, and it isn't just a fresh coat of paint it is the start of a new generation for the framework.</p><p>If you’ve been building with Spring Boot 3, you might be wondering: <i>"Do I really need to upgrade? What’s the big deal?"</i> The short answer: <strong>Yes.</strong> Spring Boot 4 is all about <strong>modernizing your stack</strong> and <strong>trimming the fat</strong>. It shifts the baseline to the latest industry standards, making your applications lighter, faster, and easier to maintain.</p><p>Now first let see what we are going to cover in this blog and then we will deep dive in each topic to fully understand.</p><h3>What We Will Cover :</h3><ol><li>Modularity</li><li>Native API Versioning</li><li>Null Safety With <strong>JSpecify</strong></li><li>Declarative HTTP Clients</li><li>Observability</li><li>Conclusion : future-proof your stack</li></ol><p>Now once you have checklist in your mind, it’s time to deep dive…</p><h2>1. Modularity</h2><p><strong>The Problem:</strong> In Spring Boot 3, the <code>spring-boot-autoconfigure</code> JAR was like a massive suitcase packed for a 3-month vacation. Even if you were just going for a weekend trip (building a simple microservice), you had to carry that heavy suitcase containing configuration logic for things you’d never use (like LDAP, Neo4j, or Quartz).</p><p><strong>The Fix:</strong> Spring Boot 4 unpacks the suitcase.</p><ul><li><strong>What changed:</strong> The massive auto-configuration module has been split into many smaller, focused modules.</li><li><strong>The Benefit:</strong> When you add the <code>spring-boot-starter-webmvc</code>, you <i>only</i> get the configuration for WebMVC. You don't secretly inherit configuration classes for batch jobs or obscure databases.</li><li><strong>Why you care:</strong> Your application starts faster, uses less memory, and is much easier to debug because the "classpath noise" is gone.</li></ul><h2>2. Native API Versioning: No More Hacks</h2><p>Finally! One of the features developers have screamed for is now built right into the core.</p><p><strong>The Old Way (The Headache) :</strong></p><ul><li>Before Boot 4, if you wanted to version your API, you had to manually hardcode it into every single URL path:<ul><li><code>@GetMapping("/api/v1/users")</code></li><li><code>@GetMapping("/api/v2/users")</code></li></ul></li><li>If you decided to change your versioning strategy from URL paths (e.g., <code>/v1/</code>) to Headers (e.g., <code>X-API-VERSION: 1</code>), you had to rewrite <strong>every single controller</strong>. It was a nightmare.</li></ul><p><strong>The New Way (The Clean Way)</strong></p><ul><li>Spring Boot 4 introduces a <code>version</code> attribute directly in the <code>@RequestMapping</code> and <code>@GetMapping</code> annotations. You simply tag your method with a number, and Spring handles the rest.</li></ul><h3>A. The Controller Code</h3><p>Here is how clean your code looks now. You can mix and match versions easily.</p><p><strong>Scenario 1: Different versions in the same class</strong> You have a generic "Hello" endpoint, but V1 and V2 behave differently.</p><pre><code class="language-java">@RestController
@RequestMapping("/hello")
public class HelloWorldController {

    // This handles version 1 requests
    @GetMapping(version = "1", produces = MediaType.TEXT_PLAIN_VALUE)
    public String sayHelloV1() {
        return "Hello World (I am V1)";
    }
    
    // This handles version 2 requests
    @GetMapping(version = "2", produces = MediaType.TEXT_PLAIN_VALUE)
    public String sayHelloV2() {
        return "Hi World (I am V2)";
    }
}</code></pre><p>Final URLs after this change :</p><ul><li>V1 -&gt; /api/v1/hello</li><li>V2 → /api/v2/hello</li></ul><p><strong>Scenario 2: Versioning the whole class</strong> If the changes are massive, you might want a totally separate class for V3.</p><pre><code class="language-java">// Every endpoint in this class is automatically Version 3
@RestController
@RequestMapping(path = "/hello", version = "3")
public class HelloWorldV3Controller {
    
    @GetMapping(produces = MediaType.TEXT_PLAIN_VALUE)
    public String sayHello() {
        return "Hey World (I am the shiny new V3)";
    }
}</code></pre><p>Final URLs after this change :</p><ul><li>V3 → /api/v3/hello</li></ul><h3>B. The Configuration (The "Brain")</h3><p>The annotations above just say "I am version 1." They don't say <i>how</i> the user asks for version 1. You define that strategy in <strong>one single place</strong>.</p><p>This is where the magic happens. You can choose:</p><ul><li><strong>Path-based</strong> (e.g., <code>/v1/hello</code>) - <i>Most popular</i></li><li><strong>Header-based</strong> (e.g., <code>Accept-Version: 1</code>)</li><li><strong>Query Param</strong> (e.g., <code>/hello?v=1</code>)</li></ul><p>Here is the setup for the popular <strong>Path-Based</strong> strategy:</p><pre><code class="language-java">@Configuration
public class ApiConfig implements WebMvcConfigurer {

    @Override
    public void configureApiVersioning(ApiVersionConfigurer configurer) {
        // Tell Spring to look at the URL path to find the version number
        configurer.usePathSegment(1); 
    }
    
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // This is the cool part: 
        // It dynamically builds the URL structure for you.
        // "v{version}" becomes "v1", "v2", or "v3" automatically.
        
        configurer.addPathPrefix("/api/v{version}", 
            HandlerTypePredicate.forAnnotation(RestController.class));
    }
}</code></pre><p>Here we mentioned this : <code>/api/v{version}</code> so that is why our Apis’s will look like :</p><ul><li>/api/v{version}/endpoints</li><li>example : /api/v1/hello</li></ul><h2>3. Null Safety With <strong>JSpecify</strong></h2><p>This is arguably the most "under-the-hood" change, but it will save you the most headaches.</p><h3>The Old Way (The Guessing Game)</h3><p>In previous versions of Spring (and Java in general), "Null Safety" was often just a suggestion.</p><ul><li>You wrote <code>public String getUsername(Long id)</code>.</li><li>Does it return <code>null</code> if the user isn't found? Or does it throw an exception?</li><li><strong>You didn't know.</strong> You had to read the documentation or, worse, wait for a <code>NullPointerException</code> (NPE) to crash your production app at 3 AM.</li></ul><h3>The New Way (JSpecify)</h3><p>Spring Boot 4 (and Framework 7) has completely adopted <strong>JSpecify</strong>. Think of JSpecify as a standard "Traffic Light" system that the entire Java ecosystem (Google, JetBrains, Spring) has finally agreed upon.</p><ul><li><strong>@Nullable (Red Light):</strong> Stop! This value <i>might</i> be missing. Check it before you use it.</li><li><strong>@NonNull (Green Light):</strong> Go! This value is guaranteed to be there. No check needed.</li><li><strong>@NullMarked (The Zone):</strong> The most powerful feature. It sets the "default rules" for a whole package.</li></ul><h3>A. The "Package-Info" Trick (Game Changer)</h3><p>Instead of putting <code>@NonNull</code> on <i>every single method</i>, you can declare your entire package as a "Null Safe Zone". Create a file named <code>package-info.java</code> in your package folder:</p><pre><code class="language-java">// src/main/java/com/mycompany/users/package-info.java

@NullMarked // &lt;--- MAGIC HAPPENS HERE
package com.mycompany.users;

import org.jspecify.annotations.NullMarked;</code></pre><p><strong>What this does:</strong> It tells the compiler (and your IDE), "Assume EVERYTHING in this package is <strong>Non-Null</strong> unless I explicitly say otherwise."</p><h3>B. The Service Code</h3><p>Now, look how clean your service code becomes. You only tag the exceptions to the rule.</p><pre><code class="language-java">package com.mycompany.users;

import org.jspecify.annotations.Nullable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    // 1. No annotation needed! 
    // Because of @NullMarked, Spring knows this CANNOT be null.
    public String formatUsername(String rawName) {
        return rawName.trim().toUpperCase();
    }

    // 2. Explicitly allowing Nulls
    // We use @Nullable to warn the caller: "This might be empty!"
    @Nullable
    public User findUserById(String id) {
        // ... database logic that might return nothing ...
        return null; 
    }
}</code></pre><h3>CC. The "Copilot" in Your IDE</h3><p>Because Spring Boot 4 uses these standard annotations, your IDE (like IntelliJ IDEA 2025.3+) becomes your safety cop.</p><ul><li><strong>Scenario:</strong> You try to pass a <code>null</code> value to <code>formatUsername(null)</code>.</li><li><strong>Old Result:</strong> App crashes at runtime.</li><li><strong>New Result:</strong> Your IDE highlights the code in <strong>RED</strong> <i>while you are typing</i>. It won't even let you compile it without a warning.</li></ul><blockquote><p>Note: To use these annotations in your own classes, you should add the JSpecify library to your build (it's super lightweight):</p><p><strong>Maven:</strong></p></blockquote><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.jspecify&lt;/groupId&gt;
    &lt;artifactId&gt;jspecify&lt;/artifactId&gt;
    &lt;version&gt;1.0.0&lt;/version&gt;
&lt;/dependency&gt;</code></pre><h2>4. Declarative HTTP Clients: The "Feign Killer”</h2><p>This feature is the biggest "quality of life" upgrade in Spring Boot 4. It allows you to talk to other services just by writing an Interface, with <strong>zero</strong> third-party dependencies.</p><h3>The Old Way (The Heavy Way)</h3><p>For years, we had two bad choices:</p><ol><li><code><strong>RestTemplate</strong></code><strong>:</strong> You had to write verbose, ugly code for every single request (<code>restTemplate.exchange(url, HttpMethod.GET, entity, class)</code>).</li><li><strong>Spring Cloud Feign:</strong> This was cleaner, but it required adding a massive external library (<code>spring-cloud-starter-openfeign</code>) that often caused version conflicts.</li></ol><h3>The New Way (Native &amp; Clean)</h3><p>Spring Boot 4 gives you the cleanliness of Feign but uses the native <strong>Spring Framework</strong> engine underneath. No extra jars. No version conflicts.</p><h3>A. The Interface (The "Contract")</h3><p>You simply define <i>what</i> you want to call, not <i>how</i>.</p><pre><code class="language-java">package com.mycompany.clients;

import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;

// 1. Base URL logic goes here
@HttpExchange("/users") 
public interface UserClient {

    // 2. This looks just like a Controller!
    @GetExchange("/{id}")
    User getUserById(@PathVariable("id") String id);

    @PostExchange
    void createUser(@RequestBody User user);
}</code></pre><p><i>Look at that code.</i> It’s clean. It reads like English.</p><h3>B. The Setup (The "Factory")</h3><p>Since this is just an interface, Spring needs to know how to build the actual object that does the work. We use the <code>HttpServiceProxyFactory</code>.</p><p><i>Put this in your </i><code><i>AppConfig.java</i></code><i>:</i></p><pre><code class="language-java">@Bean
public UserClient userClient(RestClient.Builder builder) {
    // 1. Create the underlying engine (RestClient is the new standard)
    RestClient restClient = builder.baseUrl("&lt;https://api.example.com&gt;").build();

    // 2. Create the "Magic Factory" that turns your Interface into code
    HttpServiceProxyFactory factory = HttpServiceProxyFactory
        .builderFor(RestClientAdapter.create(restClient))
        .build();

    // 3. Spit out the actual client bean
    return factory.createClient(UserClient.class);
}</code></pre><h3>C. The Usage</h3><p>Now, inject it anywhere. It feels just like calling a local method.</p><pre><code class="language-java">@Service
public class UserService {
    
    private final UserClient userClient;

    public UserService(UserClient userClient) {
        this.userClient = userClient;
    }

    public void doSomething(String id) {
        // No URLs, no HTTP entities, just method calls
        User u = userClient.getUserById(id); 
    }
}</code></pre><h2>5. Observability : The "High-Def" Dashboard</h2><h3>The Old Way (The "Blind Spot")</h3><p>In the past, checking if your HTTPS certificate was about to expire required external tools, manual calendar reminders, or a 3 AM panic when the site went down. You also had to manually stitch together logs and metrics to figure out why a request was slow.</p><h3>The New Way (Built-in Intelligence)</h3><p>Spring Boot 4 upgrades to <strong>Micrometer 2.0</strong> and <strong>Actuator 4</strong>. The standout feature here isn't just codeit's the <strong>native SSL Health Monitoring</strong>.</p><h3>A. SSL Certificate Monitoring (The "Lifesaver")</h3><p>Spring Boot now automatically watches your SSL certificates. If a certificate is close to expiring, the application's "Health" status goes <code>DOWN</code> (or warns you), so your load balancer can react <i>before</i> users get a security warning.</p><p><strong>The Code:</strong> You don't write Java code for this. You just configure an "SSL Bundle" in your properties. Spring Actuator takes care of the rest.</p><p><code>application.properties</code>:</p><pre><code class="language-plaintext"># 1. Define the SSL Bundle
spring.ssl.bundle.jks.my-server-cert.key.alias=server
spring.ssl.bundle.jks.my-server-cert.keystore.location=classpath:server.p12
spring.ssl.bundle.jks.my-server-cert.keystore.password=secret

# 2. Enable the "Health" Watchdog
management.endpoint.health.show-details=always
management.health.ssl.enabled=true</code></pre><p><strong>The Result (JSON):</strong> When you hit <code>/actuator/health</code>, you now get this rich data automatically:</p><pre><code class="language-plaintext">"ssl": {
    "status": "UP",
    "details": {
        "validSSL": [
            {
                "bundle": "my-server-cert",
                "expiresIn": "59 days", 
                "expiryDate": "2025-12-31T12:00:00Z"
            }
        ]
    }
}</code></pre><p><i>If that </i><code><i>expiresIn</i></code><i> drops below a threshold (default is usually 14-30 days), your monitoring system gets an alert.</i></p><h3>B. The "@Observed" Annotation</h3><p>If you want to track how long a specific method takes and how often it fails, you no longer need to write complex interceptors.</p><p><strong>The Code:</strong> Just add <code>@Observed</code>.</p><pre><code class="language-java">@Service
public class PaymentService {

    // Spring creates a Timer + Counter + Trace automatically for this method
    @Observed(name = "payment.process")
    public PaymentResult processPayment(String orderId) {
        // ... complex logic ...
        return new PaymentResult("SUCCESS");
    }
}</code></pre><h2>Conclusion :</h2><p>Spring Boot 4 isn’t just an upgrade it is a <strong>mindset shift</strong> for building modern Java applications.</p><p>The Spring team didn’t just add shiny features; they <strong>redesigned the foundation</strong> so your apps can be lighter, more predictable, easier to scale, and safer by design.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot 4</category>
            <category>Spring Framework 7</category>
            <category>Spring Boot</category>
            <category>Java</category>
            <category>API Versioning</category>
            <category>Microservices</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Gemini_Generated_Image_bgsrjvbgsrjvbgsr_d1eae83fb9.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Your Simple Guide to MCP Servers: Give Your AI "Superpowers" with Spring Boot]]></title>
            <link>https://www.codingshuttle.com/blogs/your-simple-guide-to-mcp-servers-give-your-ai-superpowers-with-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/your-simple-guide-to-mcp-servers-give-your-ai-superpowers-with-spring-boot</guid>
            <pubDate>Thu, 23 Oct 2025 06:11:59 GMT</pubDate>
            <description><![CDATA[Build real-world AI tools with Spring AI using the Model Context Protocol (MCP). Expose Java methods as AI-accessible tools in minutes.]]></description>
            <content:encoded><![CDATA[<p>You've built chatbots with <code>ChatClient</code> in <a href="https://www.codingshuttle.com/your-simple-guide-to-spring-ai-build-your-first-gen-ai-app-with-spring-boot">this article</a> . But how do you connect your AI to the <i>real world</i> so it can actually <i>do things</i>?</p><p>The answer is the <strong>Model Context Protocol (MCP)</strong>.</p><p>If you've ever felt that connecting AI to external tools would mean building a dozen custom, one-off REST APIs for every single AI model, you're not alone. The industry saw this mess and created an open standard to simplify it. And, of course, the Spring team made it easy to implement.</p><p>In this guide, we'll walk you through building an <strong>MCP Server</strong>. You'll create a simple Spring Boot app that acts as a "tool" any compatible AI (like Claude or ChatGPT) can discover and use to get real-time weather data.</p><p>Let's give your AI some superpowers.</p><h3>1. What is MCP? (The 30,000-Foot View)</h3><p>The <strong>Model Context Protocol (MCP)</strong> is an open-source standard for connecting AI applications to external systems.</p><p>The best analogy? <strong>MCP is the USB-C port for AI.</strong></p><p>Before USB-C, we had a tangled mess of different chargers and connectors for every device. Today, one standard port can handle power, data, and video for your laptop, phone, and monitor.</p><p>MCP does the same for AI:</p><ul><li><strong>The AI Host (e.g., Claude, ChatGPT):</strong> This is your "laptop." It's smart, but it needs to connect to things.</li><li><strong>External Systems (Databases, APIs, Local Files):</strong> These are your "peripherals" (like a hard drive, a printer, or a 3D printer).</li><li><strong>Your MCP Server (Our Spring App):</strong> This is the "USB-C peripheral" itself. It's a self-contained tool that tells the AI, "Hi, I'm a Weather Tool, and here are the commands I understand."</li><li><strong>The MCP Standard:</strong> This is the "USB-C" specification that defines <i>how</i> the AI Host and your server talk to each other.</li></ul><p>You build one MCP server for your <code>WeatherService</code>, and <i>any</i> MCP-compatible AI can plug into it and start checking the weather.</p><h3>2. Why Build an MCP Server with Spring AI?</h3><ul><li><strong>Standardization:</strong> You're not locked in. Build your tool server once, and it can be used by Claude, ChatGPT, and any other AI that adopts the MCP standard.</li><li><strong>Simplicity (The Spring Way):</strong> This is the magic. Spring AI abstracts away all the messy protocol (JSON-RPC, service discovery, etc.). All you have to do is write a simple Java method and add a <code><strong>@Tool</strong></code> annotation. That's it.</li><li><strong>Discoverability:</strong> You don't have to manually tell the AI what your tool can do. The AI Host will <i>ask</i> your server, "What tools do you have?" and your Spring app will automatically respond with a list of all your <code>@Tool</code>annotated methods and their descriptions.</li><li><strong>Enterprise-Ready:</strong> You can create secure, robust servers that connect to your internal databases and services, safely exposing them to your organization's AI agents.</li></ul><h3>3. The Core Setup: Dependencies &amp; Configuration</h3><p>Let's build our project. First, we need to add the correct dependencies and set up our properties file.</p><h3>System Requirements</h3><ul><li><strong>Java 17+</strong></li><li><strong>Spring Boot 3.3+</strong></li></ul><h3>pom.xml Dependencies</h3><p>You need two things: the <code>spring-ai-starter-mcp-server</code> and <code>spring-web</code> (for the tool's underlying <code>RestClient</code>, though the server itself won't be an HTTP server).</p><pre><code class="language-xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
        &lt;artifactId&gt;spring-ai-starter-mcp-server&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

&lt;dependencyManagement&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
            &lt;artifactId&gt;spring-ai-bom&lt;/artifactId&gt;
            &lt;version&gt;1.0.0-M1&lt;/version&gt;
            &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;</code></pre><h3>application.properties Configuration</h3><p>This part is <strong>CRITICAL</strong>. AI Hosts like Claude for Desktop communicate with your server using <strong>STDIO</strong> (Standard Input/Output), not HTTP. This means your app <i>cannot</i> write <i>anything</i> to <code>stdout</code> (like <code>console.log</code> or <code>System.out.println</code>).</p><p>Any logging will corrupt the JSON-RPC messages and break your server. We must disable all console logging that goes to <code>stdout</code>.</p><p>Open <code>src/main/resources/application.properties</code> and add this:</p><pre><code class="language-plaintext"># 1. Turn off the Spring Boot banner. It prints to stdout.
spring.main.bannerMode=off

# 2. Set the console logging pattern to blank to prevent stdout logging.
#    (Proper logging libraries should be configured to use stderr or files).
logging.pattern.console=</code></pre><h3>4. Step 1: Create Your "Tool" (The <code>WeatherService</code>)</h3><p>Our "tool" is just a standard Spring <code>@Service</code>. The only special part is the Spring AI annotations that expose our methods to the AI.</p><p>Let's create <code>WeatherService.java</code>.</p><pre><code class="language-java">import org.springframework.ai.model.function.Tool;
import org.springframework.ai.model.function.ToolParam;
import org.springframework.stereotype.Service;

@Service
public class WeatherService {

    // In a real app, you'd autowire a RestClient
    // to call api.weather.gov
    // ...

    @Tool(description = "Get weather forecast for a specific latitude/longitude")
    public String getWeatherForecastByLocation(
        double latitude,   // Latitude coordinate
        double longitude   // Longitude coordinate
    ) {
        // Returns detailed forecast including:
        // - Temperature and unit
        // - Wind speed and direction
        // - Detailed forecast description
        
        System.err.println("LOG (to stderr): Fetching forecast for " + latitude + "," + longitude);
        
        // Dummy implementation for the blog
        return "{\\"temperature\\": 68, \\"unit\\": \\"F\\", \\"forecast\\": \\"Sunny\\"}";
    }

    @Tool(description = "Get weather alerts for a US state")
    public String getAlerts(
        @ToolParam(description = "Two-letter US state code (e.g. CA, NY)") String state
    ) {
        // Returns active alerts including:
        // - Event type
        // - Affected area
        // - Severity
        // - Description
        // - Safety instructions
        
        System.err.println("LOG (to stderr): Fetching alerts for " + state);

        // Dummy implementation
        if ("NY".equalsIgnoreCase(state)) {
            return "{\\"alert\\": \\"High-wind warning for all 5 boroughs.\\"}";
        }
        return "{\\"alert\\": \\"No active alerts.\\"}";
    }
}</code></pre><p>Look at how simple that is!</p><ul><li><code>@Service</code>: Makes it a normal Spring bean.</li><li><code>@Tool</code>: This is the magic. It tells Spring AI to expose this method as a "tool." The <code>description</code> is crucial—it's what the AI reads to understand <i>what this tool does</i>.</li><li><code>@ToolParam</code>: This gives the AI a description for each <i>parameter</i>, so it knows what kind of data to pass in.</li></ul><h3>5. Step 2: Build the MCP Server (The Main Application)</h3><p>Now we just need to tell our main Spring Boot application to find these <code>@Tool</code> methods and register them with the MCP server.</p><p>We do this by creating one simple <code>@Bean</code>.</p><pre><code class="language-java">import org.springframework.ai.model.function.MethodToolCallbackProvider;
import org.springframework.ai.model.function.ToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class McpServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(McpServerApplication.class, args);
    }

    // This bean is what finds and registers all your @Tool methods
    @Bean
    public ToolCallbackProvider weatherTools(WeatherService weatherService) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(weatherService)
                .build();
    }
}</code></pre><p>The <code>MethodToolCallbackProvider</code> bean is auto-configured by Spring AI. We just inject our <code>WeatherService</code> (and any other tool services we create) into it, and it handles the rest.</p><h3>6. Step 3: Running and "Connecting" Your Server to an AI</h3><p>This is the final, most important step. We'll run our server and tell an AI Host (Claude for Desktop) how to find it.</p><ol><li>Build the Server</li></ol><p>Run this in your terminal:</p><pre><code class="language-plaintext">./mvnw clean install</code></pre><p>This will create your server JAR file in the <code>target/</code> directory (e.g., <code>mcp-server-0.0.1-SNAPSHOT.jar</code>).</p><ol><li>Configure Your AI Host</li></ol><p>Let's use Claude for Desktop as our "laptop." We need to tell it where our new "USB-C peripheral" is.</p><ul><li>Find the Claude for Desktop config file.<ul><li><strong>macOS/Linux:</strong> <code>~/Library/Application Support/Claude/claude_desktop_config.json</code></li></ul></li><li>Open it (or create it if it doesn't exist).</li><li>Add the following JSON. <strong>You MUST use the absolute path to your JAR file.</strong></li></ul><pre><code class="language-plaintext">{
  "mcpServers": {
    "spring-ai-mcp-weather": {
      "command": "java",
      "args": [
        "-Dspring.ai.mcp.server.stdio=true",
        "-jar",
        "/ABSOLUTE/PATH/TO/YOUR/PROJECT/target/mcp-server-0.0.1-SNAPSHOT.jar"
      ]
    }
  }
}</code></pre><p>Let's break this down:</p><ul><li><code>"spring-ai-mcp-weather"</code>: This is just a name we invent for our server.</li><li><code>"command": "java"</code>: Tells Claude to use the <code>java</code> command.</li><li><code>"args"</code>:<ul><li><code>"-Dspring.ai.mcp.server.stdio=true"</code>: This flag tells our Spring AI app to run in <strong>STDIO mode</strong> (not HTTP).</li><li><code>"-jar"</code>: The standard Java command.</li><li><code>"/ABSOLUTE/PATH/TO/.../your.jar"</code>: The full, absolute path to the JAR you just built.</li></ul></li></ul><ol><li>Restart Claude for Desktop</li></ol><p>Save the file and completely restart your Claude for Desktop app.</p><p>That's it! Claude will now launch your Spring Boot app in the background. Your AI now has a "tool" for checking weather. You can ask it, <strong>"What are the weather alerts for NY?"</strong> and it will <i>call your Spring Boot server</i> to get the answer.</p><h3>Conclusion: Your AI is No Longer in a Box</h3><p>You've just built a "plug-and-play" tool for the next generation of AI. You didn't write a single line of protocol code. You just wrote a Java method.</p><ul><li>You learned that <strong>MCP</strong> is the "USB-C for AI," a standard for connecting tools.</li><li>You saw that a <strong>Spring AI MCP Server</strong> is just a Spring Boot app with a special starter.</li><li>You exposed your Java methods to the world using the <code><strong>@Tool</strong></code> annotation.</li><li>You registered your tools using a <code><strong>ToolCallbackProvider</strong></code> bean.</li><li>You connected your "tool" to an AI Host like Claude using a simple JSON config.</li></ul><p>The world of Generative AI is moving fast, but with Spring AI, you can build powerful, real-world tools using the Java skills you already have.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring AI</category>
            <category>MCP</category>
            <category>Model Context Protocol</category>
            <category>AI Tools</category>
            <category>Java AI</category>
            <category>Spring Boot</category>
            <category>Claude AI</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/mcp_ad7ece73bf.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Your Simple Guide to RAG in Spring AI: Give Your App a "Memory"]]></title>
            <link>https://www.codingshuttle.com/blogs/your-simple-guide-to-rag-in-spring-ai-give-your-app-a-memory</link>
            <guid>https://www.codingshuttle.com/blogs/your-simple-guide-to-rag-in-spring-ai-give-your-app-a-memory</guid>
            <pubDate>Thu, 23 Oct 2025 06:09:34 GMT</pubDate>
            <description><![CDATA[Build an AI with memory using Spring AI and RAG. Learn how to connect ChatClient to a Vector Database like PGVector for context-aware answers.]]></description>
            <content:encoded><![CDATA[<p>You've built your first GenAI app with Spring AI in <a href="https://www.codingshuttle.com/your-simple-guide-to-spring-ai-build-your-first-gen-ai-app-with-spring-boot">this article</a> . You're using the <code>ChatClient</code> to tell jokes and answer questions. But you quickly hit a wall: <strong>it's stateless.</strong></p><p>It knows about the world, but it knows nothing about <i>you</i>. It can't answer questions about your company's technical documents, your product catalog, or your personal notes. If you ask it a question and then ask a follow-up, it has no idea what you're talking about.</p><p>So, how do you give your AI a "memory"? How can you make it an expert on <i>your</i> specific data?</p><p>The answer is <strong>Retrieval-Augmented Generation (RAG)</strong>, powered by a <strong>Vector Database</strong>.</p><p>If you've ever felt that building AI "memory" involved complex data pipelines and Python-heavy tools, you're not alone. The Spring team saw this and, once again, they simplified it.</p><p>In this guide, we'll pick up where we left off. We'll show you how to take your simple <code>ChatClient</code> and connect it to a "memory" so it can answer questions about your own documents. No data science degree needed—just your Spring Boot app and the <code>VectorStore</code> interface.</p><p>Let's build.</p><h3>1. What is RAG? (And What's a "Vector Database"?)</h3><p>First, let's clear up the terms.</p><ul><li><strong>Vector Database (or Vector Store):</strong> Think of this as your AI's long-term memory. A normal database finds <i>exact</i> matches (like <code>WHERE name = 'John'</code>). A vector database finds <i>similar</i> ideas. It stores "embeddings"—the numerical fingerprints for text we talked about in the last guide.</li><li><strong>Retrieval-Augmented Generation (RAG):</strong> This is the <i>process</i> of giving the AI the right memories <i>before</i> it answers a question.</li></ul><p>The RAG process is a simple, three-step "cheat sheet" you give the AI:</p><ol><li><strong>Retrieve (Search):</strong> When you ask a question (e.g., "How do I configure a <code>pom.xml</code>?"), your app <i>first</i> searches the vector database. It asks, "Find me the document 'fingerprints' that are most similar to this question's 'fingerprint'."</li><li><strong>Augment (Stuff):</strong> The database returns the matching text (e.g., "A 'pom.xml' file manages a project's dependencies..."). Your app then "stuffs" this text into your prompt using a <code>PromptTemplate</code>.</li><li><strong>Generate (Answer):</strong> You send the <i>new, combined</i> prompt to the <code>ChatClient</code>: "Using this information: [A 'pom.xml' file manages...]... please answer this question: [How do I configure a <code>pom.xml</code>?]"</li></ol><p>The AI then generates an answer using the <i>exact</i> context you provided. It's no longer guessing; it's answering based on <i>your</i> data.</p><h3>2. Why Use Spring AI for This?</h3><p>You guessed it: <strong>abstraction</strong>.</p><p>Think about Spring Data. You don't write code for PostgreSQL, then different code for MySQL. You just use <code>JpaRepository</code>.</p><p>Spring AI provides the <code><strong>VectorStore</strong></code><strong> interface</strong>.</p><p>You write your code against this one interface (<code>vectorStore.add(...)</code>, <code>vectorStore.similaritySearch(...)</code>), and Spring AI handles the rest. You can start with a simple in-memory store for testing, then switch to a production-grade database like <strong>PostgreSQL/PGVector</strong>, <strong>Chroma</strong>, or <strong>Weaviate</strong> just by changing a dependency and your <code>application.properties</code>.</p><p>Your Java code <i>doesn't change</i>. That's the power of Spring.</p><h3>3. Prerequisites: What You Need</h3><p>Let's get our tools ready. This guide assumes you already have a basic Spring AI project set up with a <code>ChatClient</code> (like in the last guide).</p><ol><li><strong>Java 21+ &amp; Spring Boot 3.2+:</strong> Same as before.</li><li><strong>An AI Model API Key:</strong> You still need your OpenAI key (or Ollama setup). The <code>VectorStore</code> needs an <code>EmbeddingClient</code> to turn your documents into "fingerprints," and the <code>ChatClient</code> needs to generate the final answer.</li><li><strong>A Vector Database:</strong> You need a place to store your vectors.<ul><li><strong>For a quick start:</strong> Spring AI provides a <code>SimpleVectorStore</code> that runs in-memory. It's the "H2" of vector databases—great for tests, but it forgets everything on restart.</li><li><strong>For a real app (what we'll use):</strong> Let's use <strong>PostgreSQL with the PGVector extension</strong>. It's a robust, production-ready choice that many Java developers already use.</li></ul></li></ol><p>If you have Docker, you can run PGVector in seconds:</p><pre><code class="language-plaintext">docker run -d --name pgvector -p 5432:5432 \\
  -e POSTGRES_DB=mydb \\
  -e POSTGRES_USER=myuser \\
  -e POSTGRES_PASSWORD=mypass \\
  ankane/pgvector</code></pre><h3>4. The Core Setup: Dependencies &amp; Configuration</h3><p>Let's tell our project to use PGVector.</p><h3>pom.xml Dependencies</h3><p>You need to add the starter for the vector database you chose. We'll add <code>spring-ai-pgvector-starter</code>.</p><pre><code class="language-xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
        &lt;artifactId&gt;spring-ai-openai-starter&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
        &lt;artifactId&gt;spring-ai-pgvector-starter&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
        &lt;groupId&gt;org.postgresql&lt;/groupId&gt;
        &lt;artifactId&gt;postgresql&lt;/artifactId&gt;
        &lt;scope&gt;runtime&lt;/scope&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

&lt;dependencyManagement&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
            &lt;artifactId&gt;spring-ai-bom&lt;/artifactId&gt;
            &lt;version&gt;1.0.0-M1&lt;/version&gt;
            &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;</code></pre><h3>application.properties Configuration</h3><p>Now, open <code>src/main/resources/application.properties</code> and add the new configuration.</p><pre><code class="language-plaintext"># Your OpenAI API Key (for Chat and Embeddings)
spring.ai.openai.api-key=${OPENAI_API_KEY}

# --- This is the new part for our Vector Store ---

# 1. Standard Spring Data Source config
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=myuser
spring.datasource.password=mypass
spring.datasource.driver-class-name=org.postgresql.Driver

# 2. Tell Spring AI to use this data source for PGVector
#    The table 'vector_store' will be created automatically
spring.ai.vectorstore.pgvector.index-type=HNSW</code></pre><p>That's it! When you run your app, Spring Boot will auto-configure a <code>VectorStore</code> bean that's connected to your PostgreSQL database.</p><h3>5. Step 1: Loading Your Data (The "Store" Step)</h3><p>We have an empty "memory." Let's add some documents to it.</p><p>Spring AI provides <code>DocumentReader</code> utilities to load data from files. For this example, let's just create a <code>Document</code> object manually. We can use a <code>CommandLineRunner</code> to load our data once on application startup.</p><pre><code class="language-java">import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.List;

@Component
public class DataLoader implements CommandLineRunner {

    private final VectorStore vectorStore;

    public DataLoader(VectorStore vectorStore) {
        this.vectorStore = vectorStore;
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println("Loading documents into the vector store...");
        
        // In a real app, you'd load this from a file or S3
        List&lt;Document&gt; documents = List.of(
            new Document("Spring Boot is a Java framework for microservices."),
            new Document("The 'spring-boot-starter-web' dependency is for building REST APIs."),
            new Document("A 'pom.xml' file manages a project's dependencies using Maven."),
            new Document("To kill port 8080 on Windows, use 'netstat -aon | findstr 8080' and then 'taskkill /PID &lt;PID&gt; /F'.")
        );

        // This one call turns text into embeddings and saves them
        this.vectorStore.add(documents);

        System.out.println("Documents loaded.");
    }
}</code></pre><p>Run your app. You'll see the "Documents loaded" message. Your data is now "fingerprinted" and saved in the <code>vector_store</code> table in PostgreSQL!</p><h3>6. Step 2: Asking a "Memory-Aware" Question (The Manual RAG)</h3><p>Now let's build a controller that uses this "memory." We'll do the RAG process manually first so you can see every step.</p><pre><code class="language-java">import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
public class RagController {

    private final ChatClient chatClient;
    private final VectorStore vectorStore;

    public RagController(ChatClient.Builder chatClientBuilder, VectorStore vectorStore) {
        this.chatClient = chatClientBuilder.build();
        this.vectorStore = vectorStore;
    }

    @GetMapping("/ai/rag")
    public String ask(@RequestParam String query) {

        // 1. RETRIEVE (Search)
        //    Find documents similar to the user's query
        List&lt;Document&gt; similarDocs = vectorStore.similaritySearch(query);

        // 2. AUGMENT (Stuff)
        //    Get the text content from the documents
        String context = similarDocs.stream()
                .map(Document::getContent)
                .collect(Collectors.joining(System.lineSeparator()));

        //    Create the "cheat sheet" prompt
        String templateString = """
                Using the information provided below, please answer the user's question.
                If the information is not sufficient, say so.
                
                Information:
                {context}
                
                Question:
                {query}
                """;
        
        PromptTemplate promptTemplate = new PromptTemplate(templateString);
        Prompt prompt = promptTemplate.create(Map.of(
                "context", context,
                "query", query
        ));

        // 3. GENERATE (Answer)
        //    Send the combined prompt to the AI
        return chatClient.call(prompt).getResult().getOutput().getContent();
    }
}</code></pre><p>Now, run your app and go to <code><strong>http://localhost:8080/ai/rag?query=what is a pom.xml</strong></code>.</p><p>The AI will give you a perfect answer: "A 'pom.xml' file manages a project's dependencies using Maven." It's not guessing; it's using the <i>exact</i> document we gave it. Now try asking <code><strong>http://localhost:8080/ai/rag?query=how do I kill port 8080</strong></code>. It will give you the specific Windows commands we loaded!</p><h3>7. The <i>Real</i> Spring Way: Simplifying with <code>RetrievalAugmentor</code></h3><p>The code above works, but it's a bit verbose. We're manually wiring together the <code>VectorStore</code> and the <code>ChatClient</code>. This is Spring—there must be a simpler way.</p><p>And there is.</p><p>Spring AI provides a <code>RetrievalAugmentor</code> that can be plugged <i>directly</i> into your <code>ChatClient</code> bean. It does the RAG "Retrieve" and "Augment" steps for you automatically.</p><p>Let's refactor.</p><p><strong>1. Create a Configuration class for your </strong><code><strong>ChatClient</strong></code><strong>:</strong></p><pre><code class="language-java">import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advise.RetrievalAugmentor;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AiConfig {

    // This creates the "automatic" RAG-enabled ChatClient
    @Bean
    public ChatClient chatClient(ChatClient.Builder builder, VectorStore vectorStore) {
        
        // 1. Create the Augmentor
        var augmentor = new RetrievalAugmentor(vectorStore);

        // 2. Add it to the ChatClient's builder
        return builder
                .defaultAdvisors(augmentor) // This is the magic!
                .build();
    }
}</code></pre><p><strong>2. Now, rewrite your Controller to be </strong><i><strong>much</strong></i><strong> simpler:</strong></p><pre><code class="language-java">import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SimpleRagController {

    private final ChatClient chatClient;

    // The ChatClient bean we defined in AiConfig is injected
    // This client *already knows* how to do RAG
    public SimpleRagController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @GetMapping("/ai/simple-rag")
    public String ask(@RequestParam String query) {

        // That's it.
        // Spring AI automatically finds similar docs from the
        // VectorStore and "augments" the prompt before sending it.
        return chatClient.prompt()
                .user(query)
                .call()
                .content();
    }
}</code></pre><p>If you run this and call <code><strong>http://localhost:8080/ai/simple-rag?query=what is a pom.xml</strong></code>, you get the <i>exact same</i> context-aware answer.</p><p>We've hidden all the complexity behind Spring's auto-configuration, just as it should be.</p><h3>Conclusion: Your App Now Has a Memory</h3><p>We've come a long way. You've now gone from a simple, stateless chatbot to an intelligent assistant that can answer specific questions about <i>your</i> data.</p><ul><li>You learned that <strong>RAG</strong> is the process of retrieving data to "augment" a prompt.</li><li>You learned that a <strong>Vector Database</strong> (like PGVector) is the "memory" that stores document "fingerprints."</li><li>You used the <code><strong>VectorStore</strong></code><strong> interface</strong> to add your own documents and search them.</li><li>You saw the "manual" RAG process (Retrieve, Augment, Generate).</li><li>Finally, you used a <code><strong>RetrievalAugmentor</strong></code> to let Spring AI do all the heavy lifting for you.</li></ul><p>You can now build applications that provide real value: customer support bots that know your manuals, research assistants that know your private notes, or e-commerce bots that know your product catalog.</p><p>You're a Spring developer, and now you're building truly intelligent, context-aware applications. Go build something that <i>knows</i> things.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring AI</category>
            <category>Spring Boot</category>
            <category>RAG</category>
            <category>Vector Database</category>
            <category>PGVector</category>
            <category>Java AI</category>
            <category>Generative AI</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/rag_4647831a2d.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Your Simple Guide to Spring AI: Build Your First GenAI App with Spring Boot]]></title>
            <link>https://www.codingshuttle.com/blogs/your-simple-guide-to-spring-ai-build-your-first-gen-ai-app-with-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/your-simple-guide-to-spring-ai-build-your-first-gen-ai-app-with-spring-boot</guid>
            <pubDate>Wed, 22 Oct 2025 04:20:12 GMT</pubDate>
            <description><![CDATA[Learn how to integrate Generative AI into your Spring Boot applications using Spring AI. This guide walks Java developers through setup, chat responses, embeddings, and AI memory—all with simple Spring code.]]></description>
            <content:encoded><![CDATA[<p>Generative AI is everywhere. You've seen it write code, create images, and answer complex questions. As a Java developer, you might be wondering, "How can I get in on this? How can I build these powerful features into my Spring Boot applications?"</p><p>The answer is <strong>Spring AI</strong>.</p><p>If you've ever felt that integrating AI was a complex mess of Python scripts, new frameworks, and confusing APIs, you're not alone. The Spring team saw this and did what they do best: they simplified it.</p><p>In this guide, we'll walk you through Spring AI, step by step. We'll start from the absolute basics and build up to creating an application that can "remember" information. No complex data science degree required—just you, your Java skills, and the Spring framework you already love.</p><p>Let's get started.</p><h2>1. First, What Are the Prerequisites?</h2><p>Before we write any code, let's get our tools ready. You don't need much:</p><ol><li><strong>Java 21+:</strong> Spring AI requires a modern version of Java.</li><li><strong>A Spring Boot Project:</strong> A basic Spring Boot 3.2 (or newer) project is all you need. You can create one easily from <a href="https://start.spring.io/">start.spring.io</a>.</li><li><strong>An AI Model API Key:</strong> Spring AI connects to AI models. You'll need an API key from a provider.<ul><li><strong>For a quick start:</strong> I recommend using <strong>OpenAI</strong> (requires a paid account, but it's very cheap for testing).</li><li><strong>For a free, local option:</strong> You can run a model like Llama 3 or Mistral locally using <strong>Ollama</strong>. It's fantastic for development.</li></ul></li></ol><p>For this guide, our examples will use OpenAI, but I'll show you the config for Ollama too!</p><h2>2. What is Spring AI? (The 30,000-Foot View)</h2><p>Think about how Spring Data JPA works. You don't write specific SQL for MySQL, then different SQL for-PostgreSQL. You just use a <code>JpaRepository</code>, and Spring handles the rest.</p><p><strong>Spring AI is the exact same idea, but for AI models.</strong></p><p>It's an <strong>abstraction layer</strong>. It gives you a set of simple, standard interfaces (like <code>ChatClient</code> and <code>EmbeddingClient</code>) to perform AI tasks. You write your code against these Spring interfaces, and <i>behind the scenes</i>, Spring AI translates your request into the specific format that OpenAI, Google Gemini, Ollama, or any other model understands.</p><p>This means you can switch your AI model provider just by changing a dependency and a line in your properties file, without <i>any</i> changes to your Java code. That's the power of Spring.</p><h2>3. Why Should You Use Spring AI?</h2><ul><li><strong>Portability:</strong> As we just covered, you're not locked into one AI vendor. You can start with OpenAI and switch to a cheaper or more powerful model later.</li><li><strong>Simplicity:</strong> It hides all the messy <code>HttpClient</code> calls, JSON parsing, and error handling. You just call a method, like <code>chatClient.call("Tell me a joke")</code>.</li><li><strong>Spring Integration:</strong> It fits perfectly into your existing app. You can <code>@Autowired</code> an AI client just like any other bean. It works with configuration properties, dependency injection, and everything else you expect.</li><li><strong>Solves Common Problems:</strong> It provides ready-to-use solutions for common AI patterns, like prompt templates, memory, and retrieving data (RAG).</li></ul><h2>4. The Core Setup: Dependencies &amp; Configuration</h2><p>Okay, let's build our project. First, we need to add the correct dependencies to our <code>pom.xml</code> and set up our <code>application.properties</code>.</p><h3><code>pom.xml</code> Dependencies</h3><p>You need two things: the Spring AI "starter" and the starter for the specific model you want to use.</p><pre><code class="language-xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
        &lt;artifactId&gt;spring-ai-boot-starter&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
        &lt;artifactId&gt;spring-ai-openai-starter&lt;/artifactId&gt;
    &lt;/dependency&gt;

 &lt;/dependencies&gt;

&lt;dependencyManagement&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
            &lt;artifactId&gt;spring-ai-bom&lt;/artifactId&gt;
            &lt;version&gt;1.0.0-M1&lt;/version&gt; &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;</code></pre><h3><code>application.properties</code> Configuration</h3><p>Next, we tell Spring AI how to connect to our model. Open <code>src/main/resources/application.properties</code>.</p><p>For OpenAI:</p><p>You just need to provide your API key. (Never hard-code your key! Use an environment variable.)</p><pre><code class="language-plaintext"># Your OpenAI API Key (Best practice: set this as an environment variable)
spring.ai.openai.api-key=${OPENAI_API_KEY}</code></pre><p>For Ollama (if you're running it locally):</p><p>You need to tell Spring AI where Ollama is running and which model to use.</p><pre><code class="language-plaintext"># The default URL for Ollama
spring.ai.ollama.base-url=http://localhost:11434

# Specify the model you want to use (e.g., llama3)
spring.ai.ollama.chat.options.model=llama3</code></pre><p>That's it! Your application is now configured to talk to an AI.</p><h2>5. Your First Conversation: The <code>ChatClient</code></h2><p>The <code>ChatClient</code> is your primary tool. It's how you send a prompt and get a response. Let's create a simple REST controller to test it.</p><pre><code class="language-java">import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ChatController {

    private final ChatClient chatClient;

    // Spring Boot auto-configures the ChatClient bean for us
    public ChatController(ChatClient.Builder chatClientBuilder) {
        // We get a ChatClient.Builder to configure our client
        // For this simple case, we just build the default one
        this.chatClient = chatClientBuilder.build();
    }

    @GetMapping("/ai/simple-joke")
    public String getJoke(@RequestParam(defaultValue = "programmers") String topic) {
        
        // This is the simplest way to get a response
        // .call() sends the prompt and returns the AI's message as a String
        return chatClient.prompt()
                .user("Tell me a simple joke about " + topic)
                .call()
                .content(); // .content() extracts the String response
    }
}</code></pre><p>If you run your app and go to <code>http://localhost:8080/ai/simple-joke</code>, you'll get a joke back from the AI!</p><h3>Getting More: <code>ChatResponse</code> and Metadata</h3><p>Sometimes, you need more than just the text. You might want to know how many "tokens" (pieces of words) your request used, or if the model had any safety warnings. For this, you can get a <code>ChatResponse</code> object instead of just a <code>String</code>.</p><pre><code class="language-java">import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.model.Generation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

// ... (imports and class definition)

    @GetMapping("/ai/full-response")
    public String getFullResponse() {
        
        ChatResponse response = chatClient.prompt()
                .user("Tell me a simple joke")
                .call()
                .response(); // .response() returns the full ChatResponse

        // Get the actual message content
        Generation generation = response.getResult();
        String content = generation.getOutput().getContent();

        // Get the metadata
        String model = response.getMetadata().getModel();
        int usage = response.getMetadata().getUsage().getTotalTokens();

        System.out.println("Model used: " + model);
        System.out.println("Tokens used: " + usage);

        return content;
    }</code></pre><h2>6. Stop Copy-Pasting! Using <code>PromptTemplate</code></h2><p>In our first example, we built our prompt string using basic Java concatenation: <code>"Tell me a simple joke about " + topic</code>. This gets messy fast.</p><p>A <code>PromptTemplate</code> is like a fill-in-the-blanks letter. You define the template once, and then just pass in the variables.</p><pre><code class="language-java">import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;

// ... (imports and class definition)

    @GetMapping("/ai/template-joke")
    public String getTemplateJoke(@RequestParam String adjective, @RequestParam String topic) {
        
        // 1. Define the template with placeholders {adjective} and {topic}
        String templateString = "Tell me a {adjective} joke about {topic}.";
        PromptTemplate promptTemplate = new PromptTemplate(templateString);

        // 2. Create a map of variables to fill in the placeholders
        Map&lt;String, Object&gt; variables = Map.of(
                "adjective", adjective,
                "topic", topic
        );

        // 3. Create the final Prompt object
        Prompt prompt = promptTemplate.create(variables);
        
        // 4. Call the client with the final prompt
        return chatClient.call(prompt).getResult().getOutput().getContent();
    }</code></pre><p>Now you can call <code>http://localhost:8080/ai/template-joke?adjective=funny&amp;topic=cats</code> and it will work perfectly. This is much cleaner and safer.</p><h2>7. What Are Embeddings? (The AI's "Brain")</h2><p>This is where things get <i>really</i> cool.</p><p>Models like ChatGPT don't "read" text. They understand <strong>numbers</strong>. An <strong>embedding</strong> is the process of turning text (like "Hello, world") into a list of numbers (a "vector") that represents its meaning.</p><p>Think of it as a <strong>numerical fingerprint for an idea</strong>.</p><ul><li>The text "king" will have a numerical fingerprint.</li><li>The text "queen" will have a very <i>similar</i> fingerprint.</li><li>The text "banana" will have a very <i>different</i> fingerprint.</li></ul><p>Spring AI gives us an <code>EmbeddingClient</code> to do this easily.</p><pre><code class="language-java">import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.embedding.EmbeddingResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

// ... (imports and class definition)

    @Autowired
    private EmbeddingClient embeddingClient; // Autowire the EmbeddingClient

    @GetMapping("/ai/embed")
    public List&lt;Double&gt; embedText(@RequestParam String text) {
        
        // This one call turns your text into a list of numbers (a vector)
        EmbeddingResponse embeddingResponse = this.embeddingClient.embedForResponse(text);
        
        List&lt;Double&gt; embedding = embeddingResponse.getResult().getOutput();
        
        System.out.println("Your text was turned into " + embedding.size() + " numbers.");
        
        return embedding;
    }</code></pre><p>If you call <code>http://localhost:8080/ai/embed?text=Hello world</code>, you'll get back a long array of numbers like <code>[-0.0012, 0.0345, ..., -0.0221]</code>.</p><p>Why is this useful? It's the key to <strong>AI memory</strong>.</p><h2>8. Giving Your AI a Memory (Using a <code>VectorStore</code>)</h2><p>By default, a <code>ChatClient</code> is <strong>stateless</strong>. It has no memory. Every call is a brand new conversation.</p><p>If you want your AI to "remember" your documents, past conversations, or product info, you need to use embeddings with a <strong>Vector Store</strong> (also called a Vector Database).</p><p>Here's the (simplified) idea, known as <strong>Retrieval-Augmented Generation (RAG)</strong>:</p><ol><li><strong>Store:</strong> You take all your documents (e.g., product manuals), turn them into embeddings (fingerprints), and save them in a Vector Store.</li><li><strong>Search:</strong> When a user asks a question (e.g., "How do I reset my a-Model?"), you turn their <i>question</i> into an embedding.</li><li><strong>Find:</strong> You ask the Vector Store: "Find me the documents with fingerprints <i>most similar</i> to this question's fingerprint."</li><li><strong>Augment:</strong> The store gives you back the relevant document text (e.g., "Chapter 4: Resetting the a-Model...").</li><li><strong>Answer:</strong> You stuff that text into a <code>PromptTemplate</code> and send it to the <code>ChatClient</code>:<ul><li><code>"Using this information: [Chapter 4 text...]... please answer this question: [How do I reset my a-Model?]"</code></li></ul></li></ol><p>The AI then answers the question using the <i>exact</i> information you provided.</p><p>Spring AI makes this "search" step simple with the <code>VectorStore</code> interface. You'll need to add a dependency for a vector database (e.g., <code>spring-ai-pgvector-starter</code> for Postgres, or <code>spring-ai-chroma-starter</code>), but here is a conceptual example using a simple in-memory store.</p><pre><code class="language-java">import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

// ... (imports and class definition)

    // We'll use a simple in-memory store for this example
    // In a real app, you'd autowire a persistent VectorStore bean
    private final VectorStore vectorStore;

    public ChatController(ChatClient.Builder chatClientBuilder, EmbeddingClient embeddingClient) {
        this.chatClient = chatClientBuilder.build();
        
        // Initialize our in-memory store
        this.vectorStore = new SimpleVectorStore(embeddingClient);

        // "Feed" our store some documents (this is the "Store" step)
        List&lt;Document&gt; documents = List.of(
            new Document("Spring Boot is a Java framework for microservices."),
            new Document("The 'spring-boot-starter-web' dependency is for building REST APIs."),
            new Document("A 'pom.xml' file manages a project's dependencies.")
        );
        this.vectorStore.add(documents);
    }

    @GetMapping("/ai/rag-search")
    public List&lt;String&gt; ragSearch(@RequestParam String query) {
        
        // "Search" step: Find the most similar documents to the query
        List&lt;Document&gt; similarDocs = vectorStore.similaritySearch(query);

        // Just return the text content for this example
        return similarDocs.stream()
                .map(Document::getContent)
                .collect(Collectors.toList());
    }</code></pre><p>If you run this and call <code>http://localhost:8080/ai/rag-search?query=what is maven for?</code>, it will likely return <code>"A 'pom.xml' file manages a project's dependencies."</code> because that document's "fingerprint" is closest to your question's.</p><p>You would then take this result and pass it to your <code>ChatClient</code> to get a final, context-aware answer.</p><h2>Conclusion: Your Journey Starts Now</h2><p>We've covered a lot of ground, but you've just seen the core building blocks of any modern AI application.</p><ul><li>You learned that <strong>Spring AI</strong> is an abstraction layer, just like Spring Data.</li><li>You built your first AI-powered app using the <code><strong>ChatClient</strong></code>.</li><li>You made your code clean and reusable with <code><strong>PromptTemplate</strong></code>.</li><li>You understood that <code><strong>Embeddings</strong></code> are "numerical fingerprints" for text.</li><li>You saw how a <code><strong>VectorStore</strong></code> uses those fingerprints to give your AI a "memory."</li></ul><p>The world of Generative AI is moving incredibly fast, but with Spring AI, you don't have to be a data scientist to build powerful, intelligent applications. You're a Spring developer, and now, you're a Spring AI developer, too. Now it's your turn. Go build something amazing.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring AI</category>
            <category>Java Spring Boot</category>
            <category>Generative AI</category>
            <category>OpenAI Integration</category>
            <category>AI in Java</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Gray_Green_Illustration_Business_Blog_Banner_e1c54d03b4.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Mastering Prompt Engineering for Developers: 6 Essential Prompting Techniques (Part 2)]]></title>
            <link>https://www.codingshuttle.com/blogs/mastering-prompt-engineering-for-developers-6-essential-prompting-techniques-part-1-1</link>
            <guid>https://www.codingshuttle.com/blogs/mastering-prompt-engineering-for-developers-6-essential-prompting-techniques-part-1-1</guid>
            <pubDate>Tue, 21 Oct 2025 05:49:56 GMT</pubDate>
            <description><![CDATA[Master the art of communicating with AI! In this post, we explore six essential prompt engineering techniques every developer should know.]]></description>
            <content:encoded><![CDATA[<p>In <a href="https://www.codingshuttle.com/blogs/mastering-prompt-engineering-for-developers-6-essential-prompting-techniques-part-1">Part 1 of this series</a>, we covered the 6 foundational techniques of prompt engineering, like Zero-Shot and Chain-of-Thought. You learned how to give basic commands, provide examples, and get the AI to "show its work."</p><p>Now, you're ready to level up.</p><p>If Part 1 was about <i>giving instructions</i>, Part 2 is about <i>directing the conversation</i>. These advanced techniques will give you a new level of control, allowing you to shape the AI's personality, constrain its output, and even have it collaborate with you to solve complex problems.</p><p>Let's dive into the next 6 techniques, all with practical examples.</p><h2>7. Role-Based Prompting: The "Act As a..." Command</h2><p><strong>What is it?</strong> This is one of the most powerful and popular techniques. You instruct the AI to adopt a specific <strong>persona</strong> or <strong>role</strong>. This role (e.g., "Senior Java Developer," "Database Architect," "Code Reviewer") dramatically filters its knowledge and changes its entire response style.</p><p><strong>Why It’s Important:</strong> It's the fastest way to get a specific <i>perspective</i>. An AI acting as a "Code Reviewer" will be far more critical and detailed about code quality than one acting as a "Java Tutor," which would be more encouraging and simplistic.</p><p><strong>Real-World Java Example:</strong> You have a piece of code and you want a professional, critical review.</p><p><strong>Prompt:</strong></p><p>"Act as a Senior Java Developer specializing in performance and concurrency. Review the following Java method. Focus on:</p><ol><li>Thread-safety issues.</li><li>Potential performance bottlenecks.</li><li>Adherence to Java best practices.</li></ol><p>Here is the method:</p><pre><code class="language-java">public class Counter {
    private int count = 0;

    public void increment() {
        count++; 
    }

    public int getCount() {
        return count;
    }
}</code></pre><p><strong>Result (from the AI):</strong></p><p>"As a Senior Java Developer, I've reviewed your <code>Counter</code> class. Here is my analysis:</p><p>This class is <strong>not thread-safe</strong>.</p><p><strong>Thread-Safety Issue:</strong> The <code>increment()</code> method presents a classic race condition. If two threads call <code>increment()</code> at the same time, the <code>count++</code> operation (which is not atomic) can result in a lost update. Both threads might read the same value of <code>count</code>, increment it, and write the same value back, leading to an incorrect final count.</p><p><strong>Performance Bottleneck:</strong> For this simple case, there isn't a major performance bottleneck, but the <i>solution</i> for thread-safety could introduce one.</p><p><strong>Best Practices:</strong></p><ul><li><strong>Visibility:</strong> The <code>count</code> variable is not declared <code>volatile</code>. This means changes made by one thread might not be visible to other threads.</li><li><strong>Atomicity:</strong> To fix the race condition, you should use an <code>AtomicInteger</code> like this, which is the standard, high-performance way to handle concurrent counters:</li></ul><pre><code class="language-java"> import java.util.concurrent.atomic.AtomicInteger;
    
    public class Counter {
        private AtomicInteger count = new AtomicInteger(0);
    
        public void increment() {
            count.incrementAndGet(); 
        }
    
        public int getCount() {
            return count.get();
        }
    }</code></pre><h2>8. Instruction-Based Prompting: The "Follow These Rules" Command</h2><p><strong>What is it?</strong> Also known as "constrained prompting," this is where you give the AI a set of explicit, numbered <strong>rules</strong> or <strong>constraints</strong> that it <i>must</i> follow.</p><p><strong>Why It’s Important:</strong> This is your tool for precision. When "good enough" isn't good enough, you use instructions to force the AI to adhere to specific naming conventions, import specific libraries, avoid certain methods, or format its output in a precise way.</p><p><strong>Real-World Java Example:</strong> You need a Java class that follows your team's strict coding standards.</p><p><strong>Prompt:</strong></p><p>"Write a Java class for a <code>User</code> entity with the following strict rules:</p><ol><li>It must be a POJO (Plain Old Java Object).</li><li>It must be in the package <code>com.example.model</code>.</li><li>It must have three private fields: <code>userId</code> (long), <code>username</code> (String), <code>email</code> (String).</li><li>It must include a no-argument constructor.</li><li>It must include a constructor for all fields.</li><li>It must include standard getters and setters for all fields.</li><li>DO NOT include a <code>toString()</code>, <code>equals()</code>, or <code>hashCode()</code> method."</li></ol><p><strong>Result (from the AI):</strong></p><p>Java</p><pre><code class="language-java">package com.example.model;

public class User {

    private long userId;
    private String username;
    private String email;

    public User() {
        // No-argument constructor
    }

    public User(long userId, String username, String email) {
        this.userId = userId;
        this.username = username;
        this.email = email;
    }

    // Getters and Setters
    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}</code></pre><h2>9. Task-Based Prompting: The "Unit of Work" Command</h2><p><strong>What is it?</strong> This technique involves clearly defining a single, well-scoped, and specific <strong>task</strong> for the AI to accomplish. It's about breaking a large project (like "build an app") into its smallest logical sub-tasks (like "write a method that validates an email").</p><p><strong>Why It’s Important:</strong> It prevents the AI from guessing, over-engineering, or doing <i>too much</i>. It keeps the response focused and gives you a clean, usable "unit of work" that you can integrate into your larger project. It's the building-block approach to AI development.</p><p><strong>Real-World Java Example:</strong> You don't need a whole class, just one specific, testable piece of logic.</p><p><strong>Prompt:</strong></p><p>"Task: Write a single, static Java method named 'isValidPassword'. This method must:</p><ol><li>Accept one String argument.</li><li>Return a boolean.</li><li>The password is valid if and only if it is at least 8 characters long AND contains at least one number."</li></ol><p><strong>Result (from the AI):</strong></p><p>Java</p><pre><code class="language-java">public class PasswordValidator {

    public static boolean isValidPassword(String password) {
        if (password == null || password.length() &lt; 8) {
            return false;
        }

        boolean hasNumber = false;
        for (char c : password.toCharArray()) {
            if (Character.isDigit(c)) {
                hasNumber = true;
                break;
            }
        }

        return hasNumber;
    }
}</code></pre><h2>10. Declarative Prompting: The "What, Not How" Command</h2><p><strong>What is it?</strong> This is the opposite of instruction-based prompting. Instead of telling the AI the <i>steps to take</i>, you describe the <strong>end state</strong> or <strong>final result</strong> you want to achieve. You declare "what" you want, not "how" to do it.</p><p><strong>Why It’S Important:</strong> This gives the AI creative freedom to find the <i>most efficient</i> or <i>modern</i> solution. You might be thinking of a clunky <code>for</code> loop, but the AI might know a cleaner, one-line Stream API solution. Use this when you care more about the result than the implementation.</p><p><strong>Real-World Java Example:</strong> You need to perform a common data transformation.</p><p><strong>Prompt:</strong></p><p>"I have a <code>List&lt;Product&gt;</code> in Java. Each <code>Product</code> object has a <code>getCategory()</code> method. I need a <code>Map&lt;String, List&lt;Product&gt;&gt;</code> where each key is a category name and each value is the list of all products in that category."</p><p><strong>Result (from the AI):</strong><i>(The AI will almost certainly choose the optimal "how")</i></p><p>Java</p><pre><code class="language-java">import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ProductService {

    public Map&lt;String, List&lt;Product&gt;&gt; groupProductsByCategory(List&lt;Product&gt; products) {
        return products.stream()
                .collect(Collectors.groupingBy(Product::getCategory));
    }
}

// Assuming a Product class like this:
// public class Product {
//     private String name;
//     private String category;
//     //...
//     public String getCategory() {
//         return category;
//     }
// }</code></pre><h2>11. Feedback Loop Prompting: The "Refine This" Command</h2><p><strong>What is it?</strong> This is less a single prompt and more an interactive <i>process</i>. You get an initial response from the AI, provide corrective feedback, and ask it to regenerate or modify its answer. You repeat this loop until the result is perfect.</p><p><strong>Why It’s Important:</strong> It's the most natural way to "collaborate" with an AI. For any complex task (like writing a new algorithm or a difficult service class), the first draft is rarely perfect. This technique lets you iteratively "sculpt" the final answer.</p><p><strong>Real-World Java Example:</strong> You're building a function and refining it step-by-step.</p><p><strong>Prompt 1:</strong>"Write a Java method that reads the contents of a file at a given path and returns it as a String."</p><p><strong>Result 1 (from AI):</strong></p><p>Java</p><pre><code class="language-java">import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderUtil {
    public String readFile(String filePath) throws IOException {
        StringBuilder content = new StringBuilder();
        BufferedReader reader = new BufferedReader(new FileReader(filePath));
        String line;
        while ((line = reader.readLine()) != null) {
            content.append(line).append(System.lineSeparator());
        }
        reader.close();
        return content.toString();
    }
}</code></pre><p><strong>Prompt 2 (Your Feedback):</strong>"This is good, but it's not using modern Java. Can you rewrite it using try-with-resources and Files.readString()?"</p><p><strong>Result 2 (from AI):</strong></p><p>Java</p><pre><code class="language-java">import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class FileReaderUtil {
    public String readFile(String filePath) throws IOException {
        // This is much cleaner and ensures the file is closed.
        return Files.readString(Paths.get(filePath));
    }
}</code></pre><h2>12. Interactive Prompting: The "Ask Me Questions" Command</h2><p><strong>What is it?</strong> This technique flips the script. Instead of you giving all the information, you explicitly ask the AI to <strong>ask you clarifying questions</strong> before it starts working.</p><p><strong>Why It’s Important:</strong> Use this for large, ambiguous, or poorly defined tasks where <i>you</i> might not even know all the requirements. It forces the AI to become a requirements-gatherer, helping you think through the problem and ensuring the final result is what you <i>actually</i> need.</p><p><strong>Real-World Java Example:</strong> You need to design a new component but haven't thought through all the details.</p><p><strong>Prompt:</strong></p><p>"I need to build a 'CacheService' class in Java for my Spring Boot application. It needs to cache product information.</p><p>``Before you write any code, ask me 3 questions to help you better understand the requirements."</p><p><strong>Result (from the AI):</strong></p><p>"Great, this is a common task. To design the best solution, I need a bit more information:</p><ol><li><strong>Cache Eviction Policy:</strong> What should the cache eviction strategy be? For example, should items expire after a certain time (Time-to-Live), or should the cache be limited by size (e.g., Least Recently Used)?</li><li><strong>Cache Implementation:</strong> Are you planning to use a simple in-memory cache (like <code>ConcurrentHashMap</code>) or a distributed cache (like Redis or Ehcache)?</li><li><strong>Data Consistency:</strong> How critical is it that the cached product information is always up-to-date? Is it acceptable for data to be slightly stale, or do you need a mechanism to manually invalidate the cache when a product is updated in the database? "</li></ol><h2>Where Do You Go From Here?</h2><p>You've now learned 12 powerful prompt engineering techniques. You've graduated from simply <i>asking</i> an AI for answers to <i>architecting</i> a conversation.</p><p>By combining these techniques—like using <strong>Role-Based Prompting</strong> with <strong>Feedback Loops</strong>, or <strong>Declarative Prompting</strong> within a <strong>Task-Based</strong> command—you can achieve a level of precision and quality that's impossible with simple, one-off questions.</p><p>The real mastery comes from practice. Go try to build a small Java project using <i>only</i> the AI, but direct it with these 12 techniques. You'll be amazed at the results.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Prompt Engineering</category>
            <category>AI Prompting Techniques</category>
            <category>Generative AI for Developers</category>
            <category>AI Coding Tips</category>
            <category>Developer Productivity</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/part_2_ace68711f4.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Mastering Prompt Engineering for Developers: 6 Essential Prompting Techniques (Part 1)]]></title>
            <link>https://www.codingshuttle.com/blogs/mastering-prompt-engineering-for-developers-6-essential-prompting-techniques-part-1</link>
            <guid>https://www.codingshuttle.com/blogs/mastering-prompt-engineering-for-developers-6-essential-prompting-techniques-part-1</guid>
            <pubDate>Tue, 21 Oct 2025 05:46:02 GMT</pubDate>
            <description><![CDATA[Master the art of communicating with AI! In this post, we explore six essential prompt engineering techniques every developer should know.]]></description>
            <content:encoded><![CDATA[<p>Have you ever asked an AI to do something, and it gives you... well, something completely weird? You're not alone. Getting a Generative AI or a Large Language Model (LLM) to give you the exact, perfect answer is an art and a science.</p><p>That science is called <strong>Prompt Engineering</strong>.</p><p>If you're a developer, a writer, or just someone curious about AI, mastering this skill is like learning the "magic words" to unlock the AI's true potential. In this post (Part 1 of our series!), we're going to dive into the 6 foundational techniques that will immediately improve your results. And since many of us are developers, we'll use <strong>Java examples</strong> to make it real.</p><p>Let's get started.</p><h2>What is Prompt Engineering, Anyway?</h2><p>Think of a Generative AI as an incredibly smart, incredibly fast intern. It knows <i>everything</i>... but it has no idea what <i>you</i> specifically want.</p><p><strong>Prompt Engineering</strong> is the process of designing and refining your instructions (the "prompt") to guide the AI to a high-quality, relevant, and accurate response.</p><p>It’s the difference between saying "Write code" and "Write a thread-safe Java method that implements a singleton pattern using double-checked locking." The second prompt will always win.</p><p>Here are the first 6 techniques you need to know.</p><h2>1. Zero-Shot Prompting: The "Just Do It" Command</h2><p><strong>What is it?</strong> This is the simplest form of prompting. You give the AI a task without <i>any</i> prior examples. You are "shooting" for an answer with zero setup. The AI has to rely entirely on its vast training data to figure out what you mean.</p><p><strong>Why It’s Important:</strong> This is your baseline. It's perfect for straightforward, general knowledge tasks. It's a great way to test the AI's general capabilities and see if it can handle a request "cold."</p><p><strong>Real-World Java Example:</strong> You need a simple utility function and don't want to waste time providing examples.</p><p><strong>Prompt:</strong></p><p><code>"Write a Java method that calculates the factorial of a number."</code></p><p><strong>Result (from the AI):</strong></p><p>Java</p><pre><code class="language-java">public class MathUtil {
    public static long factorial(int n) {
        if (n &lt; 0) {
            throw new IllegalArgumentException("Factorial is not defined for negative numbers.");
        }
        if (n == 0 || n == 1) {
            return 1;
        }
        long result = 1;
        for (int i = 2; i &lt;= n; i++) {
            result *= i;
        }
        return result;
    }
}</code></pre><h2>2. One-Shot Prompting: The "Here's a Hint" Command</h2><p><strong>What is it?</strong> This time, you give the AI <strong>one single example</strong> to guide it. You show it the <i>pattern</i> or <i>format</i> you want it to follow. The AI uses your example as a reference.</p><p><strong>Why It’s Important:</strong> Use this when you have a specific format in mind. It's incredibly useful for style matching, code refactoring, or simple pattern recognition. It’s like saying, "See this? Do something just like it."</p><p><strong>Real-World Java Example:</strong> You have a utility class and want to add a new method that follows the existing style.</p><p><strong>Prompt:</strong></p><p><code>"Here’s a Java method to square a number. Write a method to cube a number:</code></p><pre><code class="language-java">public int square(int num) { 
    return num * num; 
}</code></pre><p><strong>Result (from the AI):</strong></p><p>Java</p><pre><code class="language-java">public int cube(int num) {
    return num * num * num;
}</code></pre><h2>3. Few-Shot Prompting: The "See the Pattern?" Command</h2><p><strong>What is it?</strong> If one example isn't enough, you give a <strong>small set of examples</strong> (usually 2-5). This helps the AI understand more complex patterns, nuances, or a specific way of thinking.</p><p><strong>Why It’s Important:</strong> This is your go-to when the task is more complex or ambiguous. By showing the AI a few instances of the problem and solution, you dramatically increase the chances it will "get" the logic you're aiming for.</p><p><strong>Real-World Java Example:</strong> You're building a calculator class and want the AI to understand the pattern for adding new operations.</p><p><strong>Prompt:</strong></p><p><code>"Here are a few methods in my Java utility class. Write a method to multiply two numbers:</code></p><pre><code class="language-java">public int add(int a, int b) {
    // Adds two integers
    return a + b;
}

public int subtract(int a, int b) {
    // Subtracts the second integer from the first
    return a - b;
}</code></pre><p><strong>Result (from the AI):</strong></p><p>Java</p><pre><code class="language-java">public int multiply(int a, int b) {
    // Multiplies two integers
    return a * b;
}</code></pre><p><i>Note:</i> The AI correctly inferred the pattern, including the return type, parameters, and even the style of the code comment.</p><h2>4. Chain-of-Thought (CoT) Prompting: The "Show Your Work" Command</h2><p><strong>What is it?</strong> This is a game-changer. Instead of just asking for the answer, you ask the AI to <strong>reason through the problem step-by-step</strong>. You prompt it to "think out loud" before giving the final solution.</p><p><strong>Why It’s Important:</strong> CoT prompting is essential for complex logic, math problems, or debugging. It forces the AI to slow down and analyze the problem logically, which drastically reduces errors. It also allows <i>you</i> to see its reasoning and spot any flaws.</p><p><strong>Real-World Java Example:</strong> You need to solve a logic-based coding problem, not just a simple utility.</p><p><strong>Prompt:</strong></p><p><code>"I need to write a Java method that calculates the sum of all even numbers in a List&lt;Integer&gt;. First, explain the steps you would take, and then write the Java code."</code></p><p><strong>Result (from the AI):</strong></p><p>`"Certainly. Here are the steps to solve this problem:</p><ol><li><strong>Define the Method:</strong> We'll create a public method called <code>sumOfEvens</code> that accepts a <code>List&lt;Integer&gt;</code> called <code>numbers</code>.</li><li><strong>Initialize a Sum:</strong> We need a variable, <code>sum</code>, to store the total. We'll initialize it to 0.</li><li><strong>Iterate the List:</strong> We'll loop through each <code>number</code> in the <code>numbers</code> list.</li><li><strong>Check for Even:</strong> Inside the loop, we'll use the modulo operator (<code>%</code>). If <code>number % 2 == 0</code>, it means the number is even.</li><li><strong>Add to Sum:</strong> If the number is even, we add it to our <code>sum</code> variable.</li><li><strong>Return the Sum:</strong> After the loop finishes, we return the final <code>sum</code>.</li></ol><p>Here is the Java code based on those steps:`</p><pre><code class="language-java">import java.util.List;

public class ListProcessor {
    public int sumOfEvens(List&lt;Integer&gt; numbers) {
        int sum = 0;
        for (int number : numbers) {
            if (number % 2 == 0) {
                sum += number;
            }
        }
        return sum;
    }</code></pre><h2>5. Contextual Augmentation: The "Here's the Background" Command</h2><p><strong>What is it?</strong> This technique involves providing the AI with <strong>additional background information</strong> or "context" about your project or task. You're "augmenting" (or adding to) the prompt with relevant details.</p><p><strong>Why It’s Important:</strong> The AI doesn't know your project's architecture, your coding standards, or your business goals. Use this when the AI's general-purpose answer isn't specific enough. By providing context, you get a response that fits <i>your</i> specific needs.</p><p><strong>Real-World Java Example:</strong> You're working in a Spring Boot application and need a function that uses your specific data models.</p><p><strong>Prompt:</strong></p><p><code>"I'm building a movie recommendation system in a Spring Boot application. I have a Java POJO class called 'Movie':</code></p><pre><code class="language-java">public class Movie {
    private String title;
    private String genre;
    private double rating;
    // Getters and setters omitted
    
    public String getGenre() {
        return this.genre;
    }
}</code></pre><p><code>Now, write a Java method that takes a List&lt;Movie&gt; and a String genre, and returns a new list containing only the movies that match that genre."</code></p><p><strong>Result (from the AI):</strong></p><p>Java</p><pre><code class="language-java">import java.util.List;
import java.util.stream.Collectors;

public class MovieService {
    public List&lt;Movie&gt; filterMoviesByGenre(List&lt;Movie&gt; movies, String genre) {
        if (movies == null || genre == null) {
            return List.of(); // Return an empty list
        }

        return movies.stream()
                .filter(movie -&gt; genre.equalsIgnoreCase(movie.getGenre()))
                .collect(Collectors.toList());
    }
}</code></pre><p><i>Note:</i> Because you provided the <code>Movie</code> class context, the AI knew to use <code>movie.getGenre()</code> and even used modern Java (Streams) to solve it.</p><hr><h2>6. Prompt Chaining: The "One Step at a Time" Command</h2><p><strong>What is it?</strong> Prompt Chaining is the technique of breaking a single, massive task into a <strong>series of smaller, connected prompts</strong>. The output of one prompt becomes the input or context for the next.</p><p><strong>Why It’s Important:</strong> This is the ultimate technique for complex workflows. An AI can get overwhelmed or "forget" instructions on a very large task. Chaining allows you to guide it step-by-step, review each part, and build a high-quality final product. It's how you "collaborate" with the AI.</p><p><strong>Real-World Java Example:</strong> You want to build a new feature, from the data model all the way to the service logic.</p><p><strong>Prompt 1:</strong><code>"Create a simple Java class for a 'Product' in an e-commerce system. It should include fields for id, name, and price."</code></p><p><i>(AI generates the </i><code><i>Product</i></code><i> class)</i></p><p><strong>Prompt 2 (in the same chat):</strong><code>"Great. Now, using the 'Product' class you just created, write a Java method for a 'ProductRepository' class that finds the most expensive product from a List&lt;Product&gt;."</code></p><p><strong>Result (from AI for Prompt 2):</strong></p><p>Java</p><pre><code class="language-java">import java.util.List;
import java.util.Comparator;
import java.util.Optional;

public class ProductRepository {
    public Optional&lt;Product&gt; findMostExpensiveProduct(List&lt;Product&gt; products) {
        if (products == null || products.isEmpty()) {
            return Optional.empty();
        }

        return products.stream()
                .max(Comparator.comparingDouble(Product::getPrice));
    }
}</code></pre><h2>What's Next?</h2><p>You now have 6 powerful prompt engineering techniques in your toolkit. The best way to learn is to practice. Open your IDE or a chat window and try them out! You'll be surprised how much your AI interactions improve.</p><p>In <strong>Part 2</strong> of this series, we'll explore even more advanced techniques, including <strong>Role-based Prompting</strong>, <strong>Task-Based Prompting</strong> and more.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Prompt Engineering</category>
            <category>AI Prompting Techniques</category>
            <category>Generative AI for Developers</category>
            <category>AI Coding Tips</category>
            <category>Developer Productivity</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/part_1_eabb9474df.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[The Developer's Guide to Prompt Engineering: Get Better Code from Your AI]]></title>
            <link>https://www.codingshuttle.com/blogs/the-developer-s-guide-to-prompt-engineering-get-better-code-from-your-ai</link>
            <guid>https://www.codingshuttle.com/blogs/the-developer-s-guide-to-prompt-engineering-get-better-code-from-your-ai</guid>
            <pubDate>Tue, 21 Oct 2025 04:27:05 GMT</pubDate>
            <description><![CDATA[Learn how to write powerful prompts that turn AI tools like ChatGPT into your smartest coding partner. This guide breaks down the art of prompt engineering for developers.]]></description>
            <content:encoded><![CDATA[<p>If you're a developer using Generative AI, you've probably learned this an important lesson: <strong>your output is only as good as your input.</strong></p><p>We've all been there. You ask an AI tool like ChatGPT or Copilot for a piece of code, and it gives you something vague, buggy, or just... wrong. The problem isn't always the AI. It's often the prompt.</p><p>If you give vague instructions, you'll get vague results. But if you’re specific, clear, and detailed, the AI can become the most powerful teammate you’ve ever had.</p><p>This is the art of <strong>Prompt Engineering</strong>. In this guide, we'll break down what it is, why it's a critical skill for developers, and exactly how to write prompts that give you the code and answers you actually need.</p><h2>What is Prompt Engineering, Really?</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/prompt_image_3d810ffbed.png" alt="prompt-image" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_prompt_image_3d810ffbed.png 156w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_prompt_image_3d810ffbed.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_prompt_image_3d810ffbed.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_prompt_image_3d810ffbed.png 1000w," sizes="100vw"><figcaption>prompt-image</figcaption></figure><p>In simple terms, <strong>prompt engineering is the skill of writing clear and specific instructions</strong> to get the best possible response from an AI.</p><p>Think of it like giving instructions to a new team member.</p><ul><li><strong>Bad Instruction:</strong> "Hey, make a login page."</li><li><strong>Good Instruction:</strong> "Hey, please create a Spring Boot REST endpoint for user login. It should take a JSON object with <code>email</code> and <code>password</code>. Validate the fields, and if they're good, return a JWT. If not, return a 401 Unauthorized."</li></ul><p>The clearer you are, the better the result. No one, not even an AI, can read your mind.</p><h3>The "Ah-ha!" Moment for Developers: Declarative vs. Imperative</h3><p>Here's the best way for a developer to think about it:</p><p>A <strong>bad prompt</strong> is <strong>Declarative</strong>. You just state <i>what</i> you want.</p><ul><li><code>"Sort this array in Java."</code></li><li>This is like calling <code>Collections.sort(myList)</code>. You're trusting a black box to just "do the thing."</li></ul><p>A <strong>good prompt</strong> is <strong>Imperative</strong>. You state <i>what</i> you want and <i>how</i> you want it done.</p><ul><li><code>"Sort this List&lt;Integer&gt; in Java, but do not use any built-in .sort() methods. Implement a quicksort algorithm and include comments explaining the pivot logic."</code></li><li>This is like writing the sorting algorithm yourself. You are giving clear, step-by-step instructions that define the process and the constraints.</li></ul><p>When you start treating your prompts as imperative instructions, your results will improve dramatically.</p><hr><h3>Why This is a Critical Skill for Developers</h3><p>Mastering prompt engineering isn't just a neat trick; it's a fundamental skill that directly impacts your workflow.</p><ul><li><strong>Enhanced AI Performance:</strong> Good prompts help the AI understand precisely what you want, leading to far more accurate code, bug fixes, and technical explanations.</li><li><strong>Massive Efficiency Gains:</strong> Stop wasting time going back and forth. A smart prompt gets you 90% of the way there on the first try, saving you valuable time in generating code, writing tests, or drafting documentation.</li><li><strong>Customization and Control:</strong> Prompting allows you to guide the AI to match your exact needs, from coding style and best practices to specific framework versions.</li><li><strong>Bias Mitigation:</strong> By being careful and explicit in your prompts (e.g., "write this function without using any external libraries"), you can reduce unexpected or biased outputs.</li></ul><hr><h3>How to Write a Good Prompt: The 4-Part Formula</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/4_part_formula_7491a1b98c.png" alt="4-part-formula" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_4_part_formula_7491a1b98c.png 156w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_4_part_formula_7491a1b98c.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_4_part_formula_7491a1b98c.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_4_part_formula_7491a1b98c.png 1000w," sizes="100vw"><figcaption>4-part-formula</figcaption></figure><p>A great prompt doesn't have to be complicated. Just remember this simple, four-part structure: <strong>Role, Task, Details, Format (R-T-D-F)</strong>.</p><ol><li><strong>Role:</strong> Tell the AI who it should act as. This sets the context and tone.<ul><li><i>Example: "Act as a senior Java developer and code reviewer."</i></li></ul></li><li><strong>Task:</strong> Explain exactly what you need it to do.<ul><li><i>Example: "Write a function to validate a user's password."</i></li></ul></li><li><strong>Details:</strong> This is the most important part. Add all constraints, rules, and context.<ul><li><i>Example: "The password must be at least 8 characters long, contain one uppercase letter, one lowercase letter, one number, and one special character."</i></li></ul></li><li><strong>Format:</strong> (Optional) Tell the AI <i>how</i> to present the answer.<ul><li><i>Example: "Provide only the Java method in a code block. Do not add any explanation."</i></li></ul></li></ol><h3>Example 1: Simple Java Function</h3><p>❌ <strong>Bad Prompt:</strong><code>"Write a Java function to check if a number is prime."</code></p><ul><li><i>Why it's bad:</i> It's vague. What about edge cases? What about efficiency?</li></ul><p>✅ <strong>Good Prompt (using the R-T-D-F formula):</strong><code>"Act as a Java expert. Write a public static boolean isPrime(int num) function. In the details, it must efficiently handle edge cases like 0, 1, and 2. It should return false for numbers less than 2. Use an optimized loop for checking divisors up to the square root of the number."</code></p><h3>Example 2: Java REST API (Spring Boot)</h3><p>❌ <strong>Realistic Bad Prompt:</strong><code>"Create a POST API in Spring Boot to add a new user with name and email. Return a success message."</code></p><ul><li><i>Why it's bad:</i> No mention of data format (JSON?), validation, error handling, or proper REST conventions. The AI is left to make too many assumptions.</li></ul><p>✅ <strong>Good Prompt (Structured):</strong></p><ul><li><strong>Role:</strong> "Act as a senior backend developer experienced in Java and Spring Boot."</li><li><strong>Task:</strong> "Create a REST API endpoint that handles <code>POST</code> requests to <code>/api/v1/users</code>."</li><li><strong>Details:</strong> "The endpoint should accept a JSON body for a <code>UserDTO</code> with <code>name</code> and <code>email</code> fields. Use the <code>javax.validation</code> (or <code>jakarta.validation</code>) annotations like <code>@NotBlank</code> and <code>@Email</code> on the DTO. If validation fails, Spring Boot should automatically return a 400 Bad Request. If successful, it should return a 201 Created status with the saved user object (just echo the DTO for this example)."</li><li><strong>Format:</strong> "Provide the complete <code>@RestController</code> class, including the <code>UserDTO</code> record or class. Use modern Java (Java 17+)."</li></ul><p><strong>Full Combined Prompt (Final Version):</strong><code>"Act as a senior backend developer experienced in Java and Spring Boot. Create a REST API endpoint that handles POST requests to /api/v1/users. The endpoint should accept a JSON body for a UserDTO with 'name' and 'email' fields. Use the jakarta.validation annotations like @NotBlank and @Email on the UserDTO. If validation fails, Spring Boot should automatically return a 400 Bad Request. If successful, it should return a 201 Created status with the DTO. Provide the complete @RestController class and the UserDTO record in Java 17."</code></p><hr><h3>5 Powerful Prompting Techniques to Level Up</h3><p>Once you've mastered the basics, you can use these advanced techniques.</p><ol><li><strong>Zero-Shot Prompting:</strong> This is a simple, direct request with no examples. You use this when the task is straightforward.<ul><li><i>Example:</i> <code>"Write a Java function that calculates the factorial of a number."</code></li></ul></li><li><strong>Few-Shot Prompting:</strong> You provide 1-3 examples (or "shots") to show the AI the pattern you want it to follow. This is fantastic for formatting or complex logic.<ul><li><i>Example:</i> <code>"Here's an example of a Java class: class Dog { String name; } Now, based on that example, create a class for a Cat with a 'name' and 'age' property."</code></li></ul></li><li><strong>Chain-of-Thought (CoT) Prompting:</strong> You explicitly ask the AI to "think step-by-step" before giving the final answer. This dramatically improves accuracy for complex problems.<ul><li><i>Example:</i> <code>"I need to calculate the sum of all even numbers in an array of integers in Java. First, explain the steps you will take, then write the code."</code></li></ul></li><li><strong>Prompt Chaining (Iterative Refinement):</strong> Don't try to get everything in one prompt. Break a complex task into a conversation.<ul><li><strong>Prompt 1:</strong> <code>"Write a Java function to fetch data from an API using java.net.http.HttpClient."</code></li><li><strong>Prompt 2:</strong> <code>"That's great. Now modify that function to handle potential HTTPErrors and IOExceptions with a try-catch block."</code></li><li><strong>Prompt 3:</strong> <code>"Perfect. Now, refactor it to accept a URL and a Map&lt;String, String&gt; of headers as parameters."</code></li></ul></li><li><strong>Contextual Augmentation:</strong> Give the AI all the background info it needs. Paste in your <code>pom.xml</code>, an existing class, or API documentation.<ul><li><i>Example:</i> <code>"I'm building a Spring Boot application using these dependencies in my pom.xml: [paste dependencies]. I have this</code> User <code>entity: [paste User.java class]. Write a Spring Data JPA repository interface for this User entity that includes a custom query method to find a user by their email address."</code></li></ul></li></ol><hr><h3>A Final Warning: The AI is Your Co-Pilot, Not the Pilot</h3><p>Always remember: <strong>AI is a tool, not a replacement for your brain.</strong></p><p>It's incredibly powerful for saving time, but it can and <i>does</i> make mistakes. It can generate code that is inefficient, insecure, or subtly wrong.</p><p><strong>You are always responsible for the final code.</strong> Always check, test, and understand the code the AI generates before you commit it.</p><p>Mastering prompt engineering means getting better results faster, but it doesn't remove your job as the expert developer who ensures everything works correctly.</p><h3>Conclusion</h3><p>Getting better at prompt engineering is a skill that will pay off immediately. By moving from vague, declarative requests to clear, imperative instructions, you turn the AI from a coin-flip-helper into a reliable, efficient partner.If you're a developer using Generative AI, you've probably learned this an important lesson: <strong>your output is only as good as your input.</strong></p><p>We've all been there. You ask an AI tool like ChatGPT or Copilot for a piece of code, and it gives you something vague, buggy, or just... wrong. The problem isn't always the AI. It's often the prompt.</p><p>If you give vague instructions, you'll get vague results. But if you’re specific, clear, and detailed, the AI can become the most powerful teammate you’ve ever had.</p><p>This is the art of <strong>Prompt Engineering</strong>. In this guide, we'll break down what it is, why it's a critical skill for developers, and exactly how to write prompts that give you the code and answers you actually need.</p><h2>What is Prompt Engineering, Really?</h2><p><img src="attachment:a8e58e13-0adb-4d42-b626-fabe8556446d:prompt-image-1.png" alt="prompt-image-1.png"></p><p>In simple terms, <strong>prompt engineering is the skill of writing clear and specific instructions</strong> to get the best possible response from an AI.</p><p>Think of it like giving instructions to a new team member.</p><ul><li><strong>Bad Instruction:</strong> "Hey, make a login page."</li><li><strong>Good Instruction:</strong> "Hey, please create a Spring Boot REST endpoint for user login. It should take a JSON object with <code>email</code> and <code>password</code>. Validate the fields, and if they're good, return a JWT. If not, return a 401 Unauthorized."</li></ul><p>The clearer you are, the better the result. No one, not even an AI, can read your mind.</p><h3>The "Ah-ha!" Moment for Developers: Declarative vs. Imperative</h3><p>Here's the best way for a developer to think about it:</p><p>A <strong>bad prompt</strong> is <strong>Declarative</strong>. You just state <i>what</i> you want.</p><ul><li><code>"Sort this array in Java."</code></li><li>This is like calling <code>Collections.sort(myList)</code>. You're trusting a black box to just "do the thing."</li></ul><p>A <strong>good prompt</strong> is <strong>Imperative</strong>. You state <i>what</i> you want and <i>how</i> you want it done.</p><ul><li><code>"Sort this List&lt;Integer&gt; in Java, but do not use any built-in .sort() methods. Implement a quicksort algorithm and include comments explaining the pivot logic."</code></li><li>This is like writing the sorting algorithm yourself. You are giving clear, step-by-step instructions that define the process and the constraints.</li></ul><p>When you start treating your prompts as imperative instructions, your results will improve dramatically.</p><hr><h3>Why This is a Critical Skill for Developers</h3><p>Mastering prompt engineering isn't just a neat trick; it's a fundamental skill that directly impacts your workflow.</p><ul><li><strong>Enhanced AI Performance:</strong> Good prompts help the AI understand precisely what you want, leading to far more accurate code, bug fixes, and technical explanations.</li><li><strong>Massive Efficiency Gains:</strong> Stop wasting time going back and forth. A smart prompt gets you 90% of the way there on the first try, saving you valuable time in generating code, writing tests, or drafting documentation.</li><li><strong>Customization and Control:</strong> Prompting allows you to guide the AI to match your exact needs, from coding style and best practices to specific framework versions.</li><li><strong>Bias Mitigation:</strong> By being careful and explicit in your prompts (e.g., "write this function without using any external libraries"), you can reduce unexpected or biased outputs.</li></ul><hr><h3>How to Write a Good Prompt: The 4-Part Formula</h3><p><img src="attachment:51c51c6a-07cb-4968-b3a4-4405d519b6ff:4-part-formula.png" alt="4-part-formula.png"></p><p>A great prompt doesn't have to be complicated. Just remember this simple, four-part structure: <strong>Role, Task, Details, Format (R-T-D-F)</strong>.</p><ol><li><strong>Role:</strong> Tell the AI who it should act as. This sets the context and tone.<ul><li><i>Example: "Act as a senior Java developer and code reviewer."</i></li></ul></li><li><strong>Task:</strong> Explain exactly what you need it to do.<ul><li><i>Example: "Write a function to validate a user's password."</i></li></ul></li><li><strong>Details:</strong> This is the most important part. Add all constraints, rules, and context.<ul><li><i>Example: "The password must be at least 8 characters long, contain one uppercase letter, one lowercase letter, one number, and one special character."</i></li></ul></li><li><strong>Format:</strong> (Optional) Tell the AI <i>how</i> to present the answer.<ul><li><i>Example: "Provide only the Java method in a code block. Do not add any explanation."</i></li></ul></li></ol><h3>Example 1: Simple Java Function</h3><p>❌ <strong>Bad Prompt:</strong><code>"Write a Java function to check if a number is prime."</code></p><ul><li><i>Why it's bad:</i> It's vague. What about edge cases? What about efficiency?</li></ul><p>✅ <strong>Good Prompt (using the R-T-D-F formula):</strong><code>"Act as a Java expert. Write a public static boolean isPrime(int num) function. In the details, it must efficiently handle edge cases like 0, 1, and 2. It should return false for numbers less than 2. Use an optimized loop for checking divisors up to the square root of the number."</code></p><h3>Example 2: Java REST API (Spring Boot)</h3><p>❌ <strong>Realistic Bad Prompt:</strong><code>"Create a POST API in Spring Boot to add a new user with name and email. Return a success message."</code></p><ul><li><i>Why it's bad:</i> No mention of data format (JSON?), validation, error handling, or proper REST conventions. The AI is left to make too many assumptions.</li></ul><p>✅ <strong>Good Prompt (Structured):</strong></p><ul><li><strong>Role:</strong> "Act as a senior backend developer experienced in Java and Spring Boot."</li><li><strong>Task:</strong> "Create a REST API endpoint that handles <code>POST</code> requests to <code>/api/v1/users</code>."</li><li><strong>Details:</strong> "The endpoint should accept a JSON body for a <code>UserDTO</code> with <code>name</code> and <code>email</code> fields. Use the <code>javax.validation</code> (or <code>jakarta.validation</code>) annotations like <code>@NotBlank</code> and <code>@Email</code> on the DTO. If validation fails, Spring Boot should automatically return a 400 Bad Request. If successful, it should return a 201 Created status with the saved user object (just echo the DTO for this example)."</li><li><strong>Format:</strong> "Provide the complete <code>@RestController</code> class, including the <code>UserDTO</code> record or class. Use modern Java (Java 17+)."</li></ul><p><strong>Full Combined Prompt (Final Version):</strong><code>"Act as a senior backend developer experienced in Java and Spring Boot. Create a REST API endpoint that handles POST requests to /api/v1/users. The endpoint should accept a JSON body for a UserDTO with 'name' and 'email' fields. Use the jakarta.validation annotations like @NotBlank and @Email on the UserDTO. If validation fails, Spring Boot should automatically return a 400 Bad Request. If successful, it should return a 201 Created status with the DTO. Provide the complete @RestController class and the UserDTO record in Java 17."</code></p><hr><h3>5 Powerful Prompting Techniques to Level Up</h3><p>Once you've mastered the basics, you can use these advanced techniques.</p><ol><li><strong>Zero-Shot Prompting:</strong> This is a simple, direct request with no examples. You use this when the task is straightforward.<ul><li><i>Example:</i> <code>"Write a Java function that calculates the factorial of a number."</code></li></ul></li><li><strong>Few-Shot Prompting:</strong> You provide 1-3 examples (or "shots") to show the AI the pattern you want it to follow. This is fantastic for formatting or complex logic.<ul><li><i>Example:</i> <code>"Here's an example of a Java class: class Dog { String name; } Now, based on that example, create a class for a Cat with a 'name' and 'age' property."</code></li></ul></li><li><strong>Chain-of-Thought (CoT) Prompting:</strong> You explicitly ask the AI to "think step-by-step" before giving the final answer. This dramatically improves accuracy for complex problems.<ul><li><i>Example:</i> <code>"I need to calculate the sum of all even numbers in an array of integers in Java. First, explain the steps you will take, then write the code."</code></li></ul></li><li><strong>Prompt Chaining (Iterative Refinement):</strong> Don't try to get everything in one prompt. Break a complex task into a conversation.<ul><li><strong>Prompt 1:</strong> <code>"Write a Java function to fetch data from an API using java.net.http.HttpClient."</code></li><li><strong>Prompt 2:</strong> <code>"That's great. Now modify that function to handle potential HTTPErrors and IOExceptions with a try-catch block."</code></li><li><strong>Prompt 3:</strong> <code>"Perfect. Now, refactor it to accept a URL and a Map&lt;String, String&gt; of headers as parameters."</code></li></ul></li><li><strong>Contextual Augmentation:</strong> Give the AI all the background info it needs. Paste in your <code>pom.xml</code>, an existing class, or API documentation.<ul><li><i>Example:</i> <code>"I'm building a Spring Boot application using these dependencies in my pom.xml: [paste dependencies]. I have this</code> User <code>entity: [paste User.java class]. Write a Spring Data JPA repository interface for this User entity that includes a custom query method to find a user by their email address."</code></li></ul></li></ol><hr><h3>A Final Warning: The AI is Your Co-Pilot, Not the Pilot</h3><p>Always remember: <strong>AI is a tool, not a replacement for your brain.</strong></p><p>It's incredibly powerful for saving time, but it can and <i>does</i> make mistakes. It can generate code that is inefficient, insecure, or subtly wrong.</p><p><strong>You are always responsible for the final code.</strong> Always check, test, and understand the code the AI generates before you commit it.</p><p>Mastering prompt engineering means getting better results faster, but it doesn't remove your job as the expert developer who ensures everything works correctly.</p><h3>Conclusion</h3><p>Getting better at prompt engineering is a skill that will pay off immediately. By moving from vague, declarative requests to clear, imperative instructions, you turn the AI from a coin-flip-helper into a reliable, efficient partner.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Prompt Engineering</category>
            <category>Generative AI</category>
            <category>AI for Developers</category>
            <category>Coding with ChatGPT</category>
            <category>Developer Productivity</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbainl111_5fbff36401.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Generative AI for Beginners: Your Ultimate Guide to the Terms You Need to Know]]></title>
            <link>https://www.codingshuttle.com/blogs/generative-ai-for-beginners-your-ultimate-guide-to-the-terms-you-need-to-know</link>
            <guid>https://www.codingshuttle.com/blogs/generative-ai-for-beginners-your-ultimate-guide-to-the-terms-you-need-to-know</guid>
            <pubDate>Mon, 20 Oct 2025 04:31:45 GMT</pubDate>
            <description><![CDATA[Feeling lost in the world of AI? This beginner's guide breaks down complex terms like Machine Learning, Deep Learning, and Transformers into simple, jargon-free explanations. Start your AI understanding journey here!]]></description>
            <content:encoded><![CDATA[<p>You’ve heard the buzz. You’ve probably even used it. From the mind-blowing rise of ChatGPT to AI-powered art, it feels like <strong>Generative AI</strong> is suddenly everywhere. While the term "Artificial Intelligence" has been around since 1956, its recent explosion has made it the hottest topic of conversation.</p><p>Feeling a little lost in the jargon? Don't worry! This guide is for you. We’re going to break down the most important terms in Generative AI, one simple concept at a time. No complex definitions, just easy-to-understand explanations with real-world examples.</p><p>Let's get started!</p><h2>Decoding the Jargon: 9 Key AI Terms Explained</h2><p>Think of these terms as building blocks. We'll start with the biggest, most general idea and get more specific as we go down the list.</p><h3>1. Artificial Intelligence (AI)</h3><ul><li><strong>What it is:</strong> AI is the huge, overarching field of making machines think and act in ways we consider "smart" or human-like. It's the big umbrella that covers everything else on this list.</li><li><strong>In simple terms:</strong> It’s when a computer can perform tasks that normally require human intelligence, like problem-solving, understanding language, or recognizing objects.</li><li><strong>Example:</strong> When <strong>Google Maps</strong> suggests a faster route to avoid traffic, or when <strong>Siri</strong> understands your voice command—that's AI in action!</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/ai_8438d10cab.png" alt="AI" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_ai_8438d10cab.png 125w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_ai_8438d10cab.png 400w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_ai_8438d10cab.png 600w," sizes="100vw"><figcaption>AI</figcaption></figure><h3>2. Machine Learning (ML)</h3><ul><li><strong>What it is:</strong> A major branch of AI where machines learn patterns directly from data, instead of being programmed with a long list of rules for every possible situation.</li><li><strong>In simple terms:</strong> You don't tell the machine <i>how</i> to find spam email. You just show it thousands of examples of spam and non-spam emails, and it learns the rules by itself.</li><li><strong>Example:</strong> Your <strong>email spam filter</strong> is a classic example of ML. It learned what junk mail looks like from past data.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/machine_learning_240679601b.png" alt="machine-learning" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_machine_learning_240679601b.png 189w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_machine_learning_240679601b.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_machine_learning_240679601b.png 750w," sizes="100vw"><figcaption>machine-learning</figcaption></figure><h3>3. Deep Learning (DL)</h3><ul><li><strong>What it is:</strong> A powerful subfield of Machine Learning that uses complex structures called neural networks with many layers (that's where the "deep" comes from).</li><li><strong>In simple terms:</strong> Think of it as a more advanced, layered way for a machine to learn. It stacks multiple layers of "thinking" to solve very complex problems that basic ML can't handle.</li><li><strong>Example:</strong> The technology behind <strong>facial recognition</strong> on your phone or sophisticated <strong>voice assistants</strong> like Alexa relies on Deep Learning.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/deep_learning_d4d35288a5.png" alt="deep-learning" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_deep_learning_d4d35288a5.png 235w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_deep_learning_d4d35288a5.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_deep_learning_d4d35288a5.png 750w," sizes="100vw"><figcaption>deep-learning</figcaption></figure><h3>4. Neural Network (NN)</h3><ul><li><strong>What it is:</strong> A system inspired by the connections in the human brain. It's made of interconnected nodes (or "neurons") that process and transmit information.</li><li><strong>In simple terms:</strong> Imagine information flowing through a web of tiny calculators. Each one does a small calculation and passes its result to the next, until a final answer or prediction comes out at the end.</li><li><strong>Example:</strong> A simple neural network can be trained to look at a picture and decide if it's a <strong>cat or a dog</strong> by analyzing patterns like shapes, colors, and textures.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/neural_network_d1f784cada.png" alt="neural-network" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_neural_network_d1f784cada.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_neural_network_d1f784cada.png 500w," sizes="100vw"><figcaption>neural-network</figcaption></figure><h3>5. Weights</h3><ul><li><strong>What it is:</strong> In a neural network, weights are numbers that define the strength and importance of the connection between two neurons.</li><li><strong>In simple terms:</strong> A weight is like a "volume knob" for a piece of information. A high positive weight means the input is very important. A weight near zero means it’s not important at all.</li><li><strong>Example:</strong> If you're building a model to predict a house's price, the input for "square footage" will have a very high weight, while the "front door color" will have a weight close to zero.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/weights_3a5e1eb153.png" alt="weights" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_weights_3a5e1eb153.png 208w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_weights_3a5e1eb153.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_weights_3a5e1eb153.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_weights_3a5e1eb153.png 1000w," sizes="100vw"><figcaption>weights</figcaption></figure><h3>6. Transformer Architecture</h3><ul><li><strong>What it is:</strong> A revolutionary deep learning model design that is exceptionally good at handling sequential data, like text. It uses a mechanism called "attention" to weigh the importance of different words in a sentence.</li><li><strong>In simple terms:</strong> Instead of reading a sentence one word at a time, a Transformer looks at all the words simultaneously. This allows it to understand context, grammar, and nuance much more effectively.</li><li><strong>Example:</strong> This is the magic behind modern marvels like <strong>ChatGPT</strong> and <strong>Google Translate</strong>. It's why their responses sound so natural and coherent.</li></ul><h3>7. Supervised Learning</h3><ul><li><strong>What it is:</strong> A type of machine learning where the model is trained on "labeled" data.</li><li><strong>In simple terms:</strong> It's like learning with flashcards that have the answers on the back. You show the model a picture of a cat and tell it, "This is a cat." After seeing thousands of labeled examples, it learns to identify cats on its own.</li><li><strong>Example:</strong> Training an AI to identify different types of flowers by feeding it images, each labeled with the correct flower name.</li></ul><h3>8. Unsupervised Learning</h3><ul><li><strong>What it is:</strong> A type of machine learning where the model works with "unlabeled" data and tries to find hidden patterns or structures on its own.</li><li><strong>In simple terms:</strong> This is like giving a person a big box of mixed LEGO bricks and asking them to sort them into groups. They might group them by color, size, or shape, discovering the categories without any prior instructions.</li><li><strong>Example:</strong> An e-commerce site using unsupervised learning to <strong>segment customers</strong> into different groups based on their browsing and purchasing habits, without knowing what those groups are ahead of time.</li></ul><h3>9. Transfer Learning</h3><ul><li><strong>What it is:</strong> A clever technique where a model developed for one task is reused as the starting point for a model on a second, related task.</li><li><strong>In simple terms:</strong> Don't reinvent the wheel! If a model has already learned to recognize thousands of objects from a million images, you can use that "knowledge" as a foundation to quickly teach it a new, specific task, like identifying different models of cars.</li><li><strong>Example:</strong> Using a powerful, pre-trained image recognition model (like one from Google) and fine-tuning it to build a mobile app that can identify specific plant diseases.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Transfer_Learning_cbfa7a44fa.png" alt="Transfer-Learning" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Transfer_Learning_cbfa7a44fa.png 156w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Transfer_Learning_cbfa7a44fa.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Transfer_Learning_cbfa7a44fa.png 750w," sizes="100vw"><figcaption>Transfer-Learning</figcaption></figure><h2>Conclusion: You've Got This!</h2><p>And there you have it! From the broad concept of AI to the specific architecture that powers ChatGPT, you now have a solid foundation of the key terms in the world of Generative AI.</p><p>These aren't just buzzwords; they are the fundamental ideas that are building our future. By understanding them, you've taken the first and most important step in demystifying artificial intelligence. Keep exploring, stay curious, and welcome to the conversation!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>AI</category>
            <category>Artificial Intelligence</category>
            <category>Machine Learning</category>
            <category>Generative AI</category>
            <category>Deep Learning</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Chat_GPT_Image_Oct_20_2025_09_53_34_AM_3533698ba2.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Java 25 is Released! What are the Top 7 New Features with Code!]]></title>
            <link>https://www.codingshuttle.com/blogs/what-s-new-in-java-25-top-features-examples-and-enhancements-for-beginners-and-pros</link>
            <guid>https://www.codingshuttle.com/blogs/what-s-new-in-java-25-top-features-examples-and-enhancements-for-beginners-and-pros</guid>
            <pubDate>Fri, 19 Sep 2025 13:13:20 GMT</pubDate>
            <description><![CDATA[Discover Java 25's latest features, including instance main methods, compact source files, and scoped values, designed to simplify coding for beginners and boost productivity for advanced developers. Explore practical examples and enhancements in this concise guide.]]></description>
            <content:encoded><![CDATA[<p>Java continues to evolve rapidly with its six-month release cycle, and Java 25, released on September 16, 2025, introduces numerous enhancements aimed at simplifying development, particularly for beginners.</p><p>For advanced users, Java 25 introduced powerful new tools. This version focuses on reducing boilerplate code, improving readability, and enhancing performance in concurrent scenarios.</p><p>In this blog, we'll dive into the key new features of Java 25, along with practical examples, so it makes more sense how they work. Whether you are a new programmer or an experienced developer, these updates make Java more accessible and efficient.</p><h2>1. Instance Main Methods</h2><p>One of the most beginner-friendly changes in Java 25 is the support for instance main methods. Traditionally, the entry point for Java programs required a <code>public static void main(String[] args)</code> method. Now, you can omit <code>public</code>, <code>static</code>, and even the <code>String[] args</code> parameter if they're not needed. This simplifies writing quick test programs or scripts.</p><p>The JVM follows a specific order to locate the main method:</p><ol><li>It first checks for the standard <code>public static void main(String[] args)</code>.</li><li>If not found, it looks for <code>public static void main()</code>.</li><li>If only an instance (non-static) main exists, it instantiates the class using a public no-arg constructor and calls the method.</li><li>If no valid main is found, it throws an error.</li></ol><h3>Example</h3><pre><code class="language-java">class Test {
    void main() {
        System.out.println("Hello, World!");
        System.out.println("This is Coding Shuttle");
    }
}</code></pre><p>In this case, since there's no static main, the JVM creates an instance of <code>Test</code> and invokes the instance <code>main()</code> method.</p><h2>2. Compact Source Files (Unnamed Classes)</h2><p>Java 25 introduces compact source files, where you don't need to explicitly declare a class. The compiler implicitly wraps your code in an unnamed, final class with a default no-arg constructor. This is perfect for simple scripts or learning exercises, as it lets you focus on logic without class declarations. However, a launchable <code>main</code> method is mandatory; otherwise, compilation fails.</p><p>You can define methods, fields, and use <code>this</code> within the file.</p><h3>Example: Basic Hello World</h3><pre><code class="language-java">void main() {
    System.out.println("Hello, World");
}</code></pre><h3>Example: With Fields and Methods</h3><pre><code class="language-java">String msg = "Hello, World";

void main() {
    printMsg();
}

void printMsg() {
    System.out.println(msg);
}</code></pre><p>This code runs as if it's inside an implicit class. The generated class is final and can't be extended or referenced by name.</p><h2>3. Easier Console Input/Output Using The IO Helper Utility</h2><p>Console I/O in Java has historically been verbose, requiring classes like <code>BufferedReader</code> and exception handling. Java 25 addresses this with the new <code>java.lang.IO</code> class, providing static methods for simple printing and reading. Since it's in <code>java.lang</code>, no import is needed (though static imports can be used for convenience).</p><p>Key methods:</p><ul><li><code>IO.print("text")</code>: Prints without a newline.</li><li><code>IO.println("text")</code>: Prints with a newline.</li><li><code>IO.println()</code>: Prints a blank line.</li><li><code>IO.readln()</code>: Reads a line of input.</li><li><code>IO.readln("Prompt: ")</code>: Prompts and reads input.</li></ul><h3>Example: Printing</h3><pre><code class="language-java">import static java.lang.IO.*;

void main() {
    println("Hello, Coding Shuttle!");
}</code></pre><h3>Example: Input</h3><pre><code class="language-java">import static java.lang.IO.*;

void main() {
    var name = readln("What's your name? ");
    println("My Name is, " + name);
}</code></pre><p>This eliminates boilerplate, making interactive programs easier for beginners.</p><h2>4. Automatic Imports of Common APIs</h2><p>In compact source files, Java 25 automatically makes classes from commonly used packages in <code>java.base</code> (e.g., <code>java.util</code>, <code>java.io</code>) available without explicit imports. This reduces setup time for simple programs.</p><h3>Example</h3><pre><code class="language-java">void main() {
    IO.println("Hello, World!");  // no import needed here
}</code></pre><p>Here, <code>IO</code> is accessible directly, streamlining code in unnamed classes.</p><h2>5. Flexible Constructor Bodies</h2><p>Constructors in prior Java versions required <code>super(...)</code> or <code>this(...)</code> calls as the first statement. Java 25 relaxes this, allowing statements before these calls in the "prologue" section. However, the prologue can't reference <code>this</code> or instance members (except to initialize uninitialized fields). The "epilogue" (after the call) follows normal rules.</p><h3>Example</h3><pre><code class="language-java">class Parent {
    Parent() {
        IO.println("Parent Class Constructor");
    }
}

class Child extends Parent {
    Child() {
        IO.println("Child Class Constructor");
        super();
    }

    public static void main(String[] args) {
        new Child();
    }
}</code></pre><p>Output:</p><pre><code class="language-plaintext">Child Class Constructor
Parent Class Constructor</code></pre><p>This feature enables pre-initialization logic, like logging or computations, before calling the superclass constructor.</p><h2>6. Module Import Declarations</h2><p>For modular applications, Java 25 adds <code>import module M;</code>, which imports all packages exported by module <code>M</code>. This replaces multiple per-package imports, simplifying code when using libraries like <code>java.sql</code>.</p><h3>Before</h3><pre><code class="language-java">import java.util.*;
import java.sql.*;
import java.nio.file.*;
import javax.sql.*;

public class DataProcessor {
    Path filePath = java.nio.file.Paths.get("data.txt");
    Map&lt;String, Integer&gt; dataMap = new HashMap&lt;&gt;();
    Connection dbConn = DriverManager.getConnection(...);
}</code></pre><h3>After</h3><pre><code class="language-java">import module java.base;
import module java.sql;

public class DataProcessor {
    Path filePath = Paths.get("data.txt");        // from java.base
    Map&lt;String, Integer&gt; dataMap = new HashMap&lt;&gt;(); // from java.base
    Connection dbConn = DriverManager.getConnection(...); // from java.sql
}</code></pre><p>This reduces import clutter and improves maintainability.</p><h2>7. Scoped Values</h2><p>Scoped values provide a lightweight alternative to <code>ThreadLocal</code> for sharing immutable data within a thread and its children, without explicit parameter passing. They're efficient, with a limited scope that ends when the binding block completes.</p><p>Declare a scoped value as <code>static final ScopedValue&lt;T&gt;</code>, bind it using <code>ScopedValue.where(...).run(...)</code> or <code>.call(...)</code>, and access it via <code>.get()</code> inside the scope.</p><h3>Example: Logger with Request ID</h3><pre><code class="language-java">import java.lang.ScopedValue;
import static java.lang.ScopedValue.where;

public class LoggerExample {

    // Define a ScopedValue for transaction ID
    static final ScopedValue&lt;String&gt; TRANSACTION_ID = ScopedValue.newInstance();

    public static void main(String[] args) {
        handleTransaction("TXN-001");
        handleTransaction("TXN-002");
    }

    static void handleTransaction(String id) {
        // Bind the transaction ID for this operation
        where(TRANSACTION_ID, id).run(() -&gt; {
            execute();
            log("Transaction finished!");
        });
    }

    static void execute() {
        log("Executing operation...");
        storeData();
    }

    static void storeData() {
        log("Storing to database...");
    }

    static void log(String message) {
        // Access the bound transaction ID
        System.out.println("[" + TRANSACTION_ID.get() + "] " + message);
    }
}</code></pre><p>Output:</p><pre><code class="language-plaintext">[TXN-001] Executing operation...
[TXN-001] Storing to database...
[TXN-001] Transaction finished!
[TXN-002] Executing operation...
[TXN-002] Storing to database...
[TXN-002] Transaction finished!</code></pre><p>Scoped values are ideal for contexts like logging, transactions, or security, offering better performance than <code>ThreadLocal</code> in deeply nested calls.</p><h2>Conclusion</h2><p>Java 25 builds on Java's legacy by prioritising simplicity and productivity. Also, features like instance mains, compact files, and the IO class lower the entry barrier for new developers, while scoped values and module imports empower experienced ones.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java 25</category>
            <category>Java programming</category>
            <category>Java new features</category>
            <category>Java development</category>
            <category>Java tutorials</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_09_19_184214_be59dd034e.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Mastering MongoTemplate and Criteria API  in Spring]]></title>
            <link>https://www.codingshuttle.com/blogs/mongodb-advanced-queries-criteria-api-mongotemplate</link>
            <guid>https://www.codingshuttle.com/blogs/mongodb-advanced-queries-criteria-api-mongotemplate</guid>
            <pubDate>Sat, 13 Sep 2025 18:30:42 GMT</pubDate>
            <description><![CDATA[Learn how to use the Criteria API and MongoTemplate to build advanced queries in Spring MongoDB Data.]]></description>
            <content:encoded><![CDATA[<p>We've come a long way - from basic MongoDB commands to Spring Data repositories, and then to complex relationships. Now it's time I show you how to unleash the full power of MongoDB queries. When repository methods aren't enough, the Criteria API and MongoTemplate can be very helpful.</p><blockquote><p>This article is part of our comprehensive 4-part MongoDB with Spring Boot series.</p></blockquote><p><strong>Part 1</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-basics-installation-and-commands/">Getting Started with MongoDB: Installation and Basic Commands</a></p><p><strong>Part 2</strong>: <a href="https://www.codingshuttle.com/blogs/spring-boot-mongodb-crud-operations/">MongoDB with Spring Boot using Spring-Data-MongoDB</a></p><p><strong>Part 3</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-relationships-embedding-vs-referencing/">MongoDB Relationships in Spring Boot</a></p><p><strong>Part 4 (Current)</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-advanced-queries-criteria-api-mongotemplate/">Advanced MongoDB Queries: Mastering Criteria API and MongoTemplate</a></p><p>Repository methods are great for simple queries, but real-world applications often need:</p><ul><li>Dynamic queries based on user input</li><li>Complex conditions with multiple optional parameters</li><li>Aggregations and data transformations</li><li>Bulk operations and updates</li></ul><p>This is where MongoTemplate and Criteria API shine. They give you the flexibility of MongoDB's native query language with the type safety of Java.</p><h2>Getting Started with MongoTemplate</h2><p>MongoTemplate is the core class for interacting with MongoDB. It's automatically configured by Spring Boot:</p><pre><code class="language-java">@Service
public class OrderService {
    @Autowired
    private MongoTemplate mongoTemplate;

    public List&lt;Order&gt; findOrdersWithTemplate() {
        return mongoTemplate.findAll(Order.class);
    }
}
</code></pre><p>But that's just scratching the surface. Let's dive into the powerful features.</p><h2>The Criteria API: Building Dynamic Queries</h2><p>Criteria API lets you build queries programmatically. Think of it as a query builder that adapts to your needs.</p><h3>Basic Criteria Queries</h3><p>Let's start with simple criteria:</p><pre><code class="language-java">@Test
void basicCriteriaQuery() {
    Query query = new Query();
    query.addCriteria(Criteria.where("status").is("pending"));

    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);
}
</code></pre><h3>Combining Multiple Criteria</h3><p>Real queries often have multiple conditions:</p><pre><code class="language-java">@Test
void multipleCriteria() {
    Criteria criteria = Criteria.where("status").is("delivered")
        .and("totalPrice").gte(100)
        .and("quantity").lt(5);

    Query query = new Query(criteria);
    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);
}
</code></pre><h3>Using OR Conditions</h3><p>Sometimes you need OR logic:</p><pre><code class="language-java">@Test
void orConditions() {
    Criteria criteria = new Criteria().orOperator(
        Criteria.where("status").is("pending"),
        Criteria.where("status").is("processing")
    );

    Query query = new Query(criteria);
    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);

    assertTrue(orders.stream()
        .allMatch(o -&gt; o.getStatus().equals("pending") ||
                      o.getStatus().equals("processing"))
    );
}

</code></pre><h3>Complex Nested Conditions</h3><p>For complex business logic, combine AND and OR:</p><pre><code class="language-java">@Test
void complexNestedQuery() {
    Criteria criteria = new Criteria().andOperator(
        Criteria.where("totalPrice").gte(50),
        new Criteria().orOperator(
            Criteria.where("status").is("pending"),
            Criteria.where("quantity").gt(10)
        )
    );

    Query query = new Query(criteria);
    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);

    // Orders with price &gt;= 50 AND (status = pending OR quantity &gt; 10)
}

</code></pre><h2>Dynamic Query Building</h2><p>Here's where Criteria API really shines - building queries based on user input:</p><pre><code class="language-java">@Service
public class OrderSearchService {
    @Autowired
    private MongoTemplate mongoTemplate;

    public List&lt;Order&gt; searchOrders(OrderSearchCriteria searchCriteria) {
        Query query = new Query();

        if (searchCriteria.getStatus() != null) {
            query.addCriteria(Criteria.where("status")
                .is(searchCriteria.getStatus()));
        }

        if (searchCriteria.getMinPrice() != null) {
            query.addCriteria(Criteria.where("totalPrice")
                .gte(searchCriteria.getMinPrice()));
        }

        if (searchCriteria.getMaxPrice() != null) {
            query.addCriteria(Criteria.where("totalPrice")
                .lte(searchCriteria.getMaxPrice()));
        }

        if (searchCriteria.getCity() != null) {
            query.addCriteria(Criteria.where("address.city")
                .is(searchCriteria.getCity()));
        }

        if (searchCriteria.getDateFrom() != null) {
            query.addCriteria(Criteria.where("createdAt")
                .gte(searchCriteria.getDateFrom()));
        }

        // Add sorting
        if (searchCriteria.getSortBy() != null) {
            Sort.Direction direction = searchCriteria.isAscending() ?
                Sort.Direction.ASC : Sort.Direction.DESC;
            query.with(Sort.by(direction, searchCriteria.getSortBy()));
        }

        // Add pagination
        if (searchCriteria.getPage() != null &amp;&amp; searchCriteria.getSize() != null) {
            Pageable pageable = PageRequest.of(
                searchCriteria.getPage(),
                searchCriteria.getSize()
            );
            query.with(pageable);
        }

        return mongoTemplate.find(query, Order.class);
    }
}

</code></pre><h2>Querying Embedded Documents and References</h2><h3>Querying Embedded Documents</h3><pre><code class="language-java">@Test
void queryEmbeddedDocument() {
    // Find orders in specific cities
    Query query = new Query(
        Criteria.where("address.city").in("Mumbai", "Delhi", "Bangalore")
    );

    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);

    // Find orders with specific zip code pattern
    Query zipQuery = new Query(
        Criteria.where("address.zipCode").regex("^560.*")
    );

    List&lt;Order&gt; bangaloreOrders = mongoTemplate.find(zipQuery, Order.class);
}

</code></pre><h3>Handling DBRef Queries</h3><p>Querying referenced documents requires special handling:</p><pre><code class="language-java">@Test
void queryWithDBRef() {
    // First, find the product
    Product product = mongoTemplate.findOne(
        Query.query(Criteria.where("name").is("Gaming Laptop")),
        Product.class
    );

    // Then query orders containing this product
    Query query = new Query(
        Criteria.where("products.$id").is(new ObjectId(product.getId()))
    );

    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);
}

</code></pre><h2>Text Search Capabilities</h2><p>MongoDB supports full-text search. First, create a text index:</p><pre><code class="language-java">@Document(collection = "products")
@TextIndexed
public class Product {
    @TextIndexed(weight = 2)
    private String name;

    @TextIndexed
    private String description;

    // other fields...
}

</code></pre><p>Then search using text criteria:</p><pre><code class="language-java">@Test
void textSearch() {
    TextCriteria criteria = TextCriteria
        .forDefaultLanguage()
        .matchingAny("wireless", "bluetooth");

    Query query = TextQuery.queryText(criteria)
        .sortByScore();

    List&lt;Product&gt; products = mongoTemplate.find(query, Product.class);
}

</code></pre><h2>Update Operations with MongoTemplate</h2><h3>Single Document Updates</h3><p>Update specific fields without fetching the document:</p><pre><code class="language-java">@Test
void updateSingleDocument() {
    Query query = new Query(Criteria.where("id").is(orderId));

    Update update = new Update()
        .set("status", "shipped")
        .inc("quantity", 1)
        .currentDate("updatedAt");

    UpdateResult result = mongoTemplate.updateFirst(query, update, Order.class);

    assertEquals(1, result.getModifiedCount());
}

</code></pre><h3>Bulk Updates</h3><p>Update multiple documents at once:</p><pre><code class="language-java">@Test
void bulkUpdate() {
    Query query = new Query(
        Criteria.where("status").is("pending")
            .and("createdAt").lt(LocalDateTime.now().minusDays(7))
    );

    Update update = new Update()
        .set("status", "cancelled")
        .set("cancellationReason", "Order timeout");

    UpdateResult result = mongoTemplate.updateMulti(query, update, Order.class);

    System.out.println("Updated " + result.getModifiedCount() + " orders");
}

</code></pre><h3>Upsert Operations</h3><p>Create or update in one operation:</p><pre><code class="language-java">@Test
void upsertOperation() {
    Query query = new Query(Criteria.where("id").is("special-order-123"));

    Update update = new Update()
        .set("status", "vip")
        .setOnInsert("createdAt", LocalDateTime.now())
        .inc("updateCount", 1);

    UpdateResult result = mongoTemplate.upsert(query, update, Order.class);

    if (result.getUpsertedId() != null) {
        System.out.println("Created new order");
    } else {
        System.out.println("Updated existing order");
    }
}

</code></pre><h2>Projections and Field Selection</h2><p>Optimize queries by fetching only needed fields:</p><pre><code class="language-java">@Test
void projectionExample() {
    Query query = new Query();
    query.fields()
        .include("status")
        .include("totalPrice")
        .exclude("_id");

    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);

    // Only status and totalPrice are populated
}

</code></pre><p>For nested fields:</p><pre><code class="language-java">@Test
void nestedProjection() {
    Query query = new Query();
    query.fields()
        .include("status")
        .include("address.city")
        .include("address.state");

    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);
}

</code></pre><h2>Custom Queries with Native MongoDB</h2><p>Sometimes you need the full power of native MongoDB queries:</p><pre><code class="language-java">@Test
void nativeMongoQuery() {
    String jsonQuery = "{ 'status': 'pending', " +
        "'$or': [ " +
        "{ 'totalPrice': { '$gte': 100 } }, " +
        "{ 'quantity': { '$gt': 5 } } " +
        "] }";

    BasicQuery query = new BasicQuery(jsonQuery);
    List&lt;Order&gt; orders = mongoTemplate.find(query, Order.class);
}

</code></pre><h2>Conclusion</h2><p>Congratulations! You've completed my comprehensive MongoDB with Spring Boot series.</p><p>You're no longer just a MongoDB user - you're a MongoDB developer capable of building sophisticated, performant applications. The document database that seemed foreign at first is now a powerful tool in your arsenal.</p><p>Remember, MongoDB's flexibility is both its strength and responsibility. Design your documents thoughtfully, index strategically, and always consider how your application will query the data. With the skills you've gained, you're ready to tackle real-world projects that demand the scalability and flexibility of NoSQL databases.</p><p>Happy coding!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>Spring Boot</category>
            <category>MongoDB</category>
            <category>MongoTemplate</category>
            <category>Criteria API</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/153_5dade44c60.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Mastering MongoDB Relationships in Spring Boot]]></title>
            <link>https://www.codingshuttle.com/blogs/mongodb-relationships-embedding-vs-referencing</link>
            <guid>https://www.codingshuttle.com/blogs/mongodb-relationships-embedding-vs-referencing</guid>
            <pubDate>Sat, 13 Sep 2025 18:27:14 GMT</pubDate>
            <description><![CDATA[Learn MongoDB relationships and embedding addresses for data that belongs together and referencing products for shared, independent data.]]></description>
            <content:encoded><![CDATA[<p>In the previous parts, we installed MongoDB and built a Spring Boot application with basic CRUD operations. Now it's time to tackle one of the most important aspects of document database design: relationships. If you're coming from the SQL world, prepare to think differently about how data relates to each other.</p><blockquote><p>This article is part of our comprehensive 4-part MongoDB with Spring Boot series.</p></blockquote><p><strong>Part 1</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-basics-installation-and-commands/">Getting Started with MongoDB: Installation and Basic Commands</a></p><p><strong>Part 2</strong>: <a href="https://www.codingshuttle.com/blogs/spring-boot-mongodb-crud-operations/">MongoDB with Spring Boot using Spring-Data-MongoDB</a></p><p><strong>Part 3 (Current)</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-relationships-embedding-vs-referencing/">MongoDB Relationships in Spring Boot</a></p><p><strong>Part 4</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-advanced-queries-criteria-api-mongotemplate/">Advanced MongoDB Queries: Mastering Criteria API and MongoTemplate</a></p><h2>The MongoDB Relationship Philosophy</h2><p>In traditional SQL databases, we normalize data into separate tables and use JOINs to bring them together. MongoDB takes a different approach - it encourages you to model your data based on how your application uses it. This means sometimes embedding documents within documents, and sometimes referencing them separately.</p><p>The golden rule? If data is always accessed together, store it together. If data has its own lifecycle or is shared across multiple documents, reference it.</p><h2>Embedding Documents</h2><p>Let's start with embedding. Remember our Order entity from the last post? Orders always need shipping addresses, and an address doesn't make sense without an order. This is a perfect case for embedding.</p><h3>Creating an Embedded Address</h3><p>First, let's create our Address as a nested class within Order:</p><pre><code class="language-java">@Data
@Builder
@Document(collection = "orders")
public class Order {
    @Id
    private String id;

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;

    private String status;
    private int quantity;
    private double totalPrice;

    @Indexed
    private Address address;

    @Data
    @Builder
    public static class Address {
        private String line1;
        private String city;
        private String state;
        private String zipCode;
        private String country;
    }
}

</code></pre><p>Notice how Address is a static nested class? It doesn't need <code>@Document</code> because it's not a separate collection - it's part of the Order document. The <code>@Indexed</code> annotation on the address field creates an index on the entire embedded document, making queries on address fields faster.</p><h3>Working with Embedded Documents</h3><p>Creating an order with an embedded address is intuitive:</p><pre><code class="language-java">@Test
void createOrderWithAddress() {
    Order.Address address = Order.Address.builder()
        .line1("123 Tech Street")
        .city("Bangalore")
        .state("Karnataka")
        .zipCode("560001")
        .country("India")
        .build();

    Order order = Order.builder()
        .status("pending")
        .quantity(2)
        .totalPrice(199.99)
        .address(address)
        .build();

    Order saved = orderRepository.save(order);

    assertNotNull(saved.getAddress());
    assertEquals("Bangalore", saved.getAddress().getCity());
}

</code></pre><p>In MongoDB, this creates a single document that looks like:</p><pre><code class="language-plaintext">{
    "_id": ObjectId("..."),
    "status": "pending",
    "quantity": 2,
    "totalPrice": 199.99,
    "address": {
        "line1": "123 Tech Street",
        "city": "Bangalore",
        "state": "Karnataka",
        "zipCode": "560001",
        "country": "India"
    },
    "createdAt": ISODate("..."),
    "updatedAt": ISODate("...")
}

</code></pre><h3>Querying Embedded Documents</h3><p>Spring Data MongoDB makes querying embedded documents natural:</p><pre><code class="language-java">public interface OrderRepository extends MongoRepository&lt;Order, String&gt; {
    List&lt;Order&gt; findByAddressCity(String city);

    List&lt;Order&gt; findByAddressStateAndAddressCountry(String state, String country);

    @Query("{ 'address.zipCode': ?0 }")
    List&lt;Order&gt; findByZipCode(String zipCode);
}

</code></pre><p>The dot notation (<code>address.city</code>) navigates into embedded documents. Spring automatically understands this pattern in method names.</p><h2>Document References</h2><p>Now let's look at references. Products exist independently of orders - multiple orders can reference the same product, and products have their own lifecycle. This calls for a separate collection with references.</p><h3>Creating the Product Entity</h3><pre><code class="language-java">@Data
@Document(collection = "products")
public class Product {
    @Id
    private String id;

    private String name;

    @Indexed
    private String category;

    @Indexed
    private double price;

    private List&lt;String&gt; tags;
    private int stock;
    private double reviews;
}

</code></pre><h3>Adding Product References to Order</h3><p>Now, let's update our Order to reference products:</p><pre><code class="language-java">@Data
@Builder
@Document(collection = "orders")
public class Order {
    @Id
    private String id;

    // ...

    @Indexed
    private Address address;

    @DBRef(lazy = true)
    private List&lt;Product&gt; products;

    // Address class remains the same
}

</code></pre><p>The <code>@DBRef</code> annotation tells Spring to store references to Product documents rather than embedding them. The <code>lazy = true</code> parameter means products are only loaded when accessed, improving performance.</p><h3>Working with References</h3><p>Let's see how to create and query orders with product references:</p><pre><code class="language-java">@Test
void createOrderWithProducts() {
    // First, create some products
    Product laptop = Product.builder()
        .name("Gaming Laptop")
        .category("Electronics")
        .price(1299.99)
        .stock(10)
        .build();
    laptop = productRepository.save(laptop);

    Product mouse = Product.builder()
        .name("Wireless Mouse")
        .category("Accessories")
        .price(49.99)
        .stock(50)
        .build();
    mouse = productRepository.save(mouse);

    // Create order with product references
    Order order = Order.builder()
        .status("pending")
        .quantity(2)
        .totalPrice(1349.98)
        .products(Arrays.asList(laptop, mouse))
        .build();

    Order saved = orderRepository.save(order);

    // Products are saved as references
    assertEquals(2, saved.getProducts().size());
}

</code></pre><p>In MongoDB, the order document stores product references like this:</p><pre><code class="language-plaintext">{
    "_id": ObjectId("..."),
    "status": "pending",
    "quantity": 2,
    "totalPrice": 1349.98,
    "products": [
        { "$ref": "products", "$id": ObjectId("...") },
        { "$ref": "products", "$id": ObjectId("...") }
    ]
}

</code></pre><h3>Lazy Loading in Action</h3><p>With lazy loading, products are fetched only when accessed:</p><pre><code class="language-java">@Test
void lazyLoadingExample() {
    Order order = orderRepository.findById(orderId).orElseThrow();

    // Products not loaded yet
    System.out.println("Order status: " + order.getStatus());

    // Now products are loaded
    List&lt;Product&gt; products = order.getProducts();
    products.forEach(p -&gt; System.out.println(p.getName()));
}

</code></pre><h3>Querying Embedded Documents with Complex Criteria</h3><p>For more complex queries on embedded documents, use MongoDB's query syntax:</p><pre><code class="language-java">@Query("{ 'address.city': { $in: ?0 }, 'totalPrice': { $gte: ?1 } }")
List&lt;Order&gt; findOrdersInCitiesWithMinPrice(List&lt;String&gt; cities, double minPrice);

@Query("{ $and: [ { 'address.state': ?0 }, { 'status': 'delivered' } ] }")
List&lt;Order&gt; findDeliveredOrdersInState(String state);

</code></pre><h2>Manual References Without @DBRef</h2><p>Sometimes you want more control over references. Instead of using <code>@DBRef</code>, you can store just the ID:</p><pre><code class="language-java">@Document(collection = "orders")
public class Order {
    // Other fields...

    private List&lt;String&gt; productIds;
}

</code></pre><p>Then manually fetch products when needed:</p><pre><code class="language-java">@Service
public class OrderService {
    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private ProductRepository productRepository;

    public OrderDetails getOrderWithProducts(String orderId) {
        Order order = orderRepository.findById(orderId).orElseThrow();
        List&lt;Product&gt; products = productRepository.findAllById(order.getProductIds());

        return OrderDetails.builder()
            .order(order)
            .products(products)
            .build();
    }
}

</code></pre><p>This approach gives you more flexibility but requires more code.</p><h2>When to Embed vs When to Reference</h2><h3>Embed When:</h3><ul><li>The data is always accessed together</li><li>The embedded data doesn't change independently</li><li>The relationship is one-to-few (not one-to-millions)</li><li>You want atomic updates on the entire document</li></ul><h3>Reference When:</h3><ul><li>The data has its own lifecycle</li><li>Multiple documents need to share the same data</li><li>The relationship is one-to-many or many-to-many</li><li>The referenced data changes frequently</li><li>You need to query the data independently</li></ul><h2>Performance Considerations</h2><h3>Indexing Strategies for Relationships</h3><p>Create compound indexes for frequently queried embedded fields:</p><pre><code class="language-java">@CompoundIndex(name = "city_status_idx",
               def = "{'address.city': 1, 'status': 1}")
@Document(collection = "orders")
public class Order {
    // fields...
}

</code></pre><h3>Projection to Optimize Queries</h3><p>Fetch only what you need:</p><pre><code class="language-java">@Query(value = "{ 'address.city': ?0 }",
       fields = "{ 'products': 0 }")
List&lt;Order&gt; findOrdersInCityWithoutProducts(String city);

</code></pre><p>The <code>fields</code> parameter excludes the products field, reducing data transfer.</p><h2>What's Next?</h2><p>You've now mastered relationships in MongoDB - embedding addresses for data that belongs together and referencing products for shared, independent data. You understand when to use each approach and how Spring Data MongoDB makes both patterns elegant.</p><p>But what happens when repository methods aren't enough? In our next post, we'll explore the powerful world of MongoDB queries using Criteria API and MongoTemplate. You'll learn to build dynamic queries, perform complex aggregations, and handle scenarios that go beyond simple CRUD operations.</p><p>Next part here:</p><p><strong>Part 4</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-advanced-queries-criteria-api-mongotemplate/">Advanced MongoDB Queries: Mastering Criteria API and MongoTemplate</a></p>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>Spring Boot</category>
            <category>Spring Data MongoDB</category>
            <category>Embedding</category>
            <category>MongoDB Relationships</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/152_ee7f609cd1.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[A Complete Guide to Integrating MongoDB with Spring Boot]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-boot-mongodb-crud-operations</link>
            <guid>https://www.codingshuttle.com/blogs/spring-boot-mongodb-crud-operations</guid>
            <pubDate>Sat, 13 Sep 2025 18:23:31 GMT</pubDate>
            <description><![CDATA[Learn how Spring Boot application works with MongoDB, create entities with proper annotations, Pagination and CRUD Operations.]]></description>
            <content:encoded><![CDATA[<p>Welcome back! In our previous post, we got MongoDB up and running and learned essential commands. Now it's time to put that knowledge to work by integrating MongoDB with Spring Boot. If you've been following along, you already know how to query MongoDB from the shell - now let's see how Spring Data MongoDB makes this even more elegant in Java.</p><blockquote><p>This article is part of our comprehensive 4-part MongoDB with Spring Boot series.</p></blockquote><p><strong>Part 1</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-basics-installation-and-commands/">Getting Started with MongoDB: Installation and Basic Commands</a></p><p><strong>Part 2 (Current)</strong>: <a href="https://www.codingshuttle.com/blogs/spring-boot-mongodb-crud-operations/">MongoDB with Spring Boot using Spring-Data-MongoDB</a></p><p><strong>Part 3</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-relationships-embedding-vs-referencing/">MongoDB Relationships in Spring Boot</a></p><p><strong>Part 4</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-advanced-queries-criteria-api-mongotemplate/">Advanced MongoDB Queries: Mastering Criteria API and MongoTemplate</a></p><h2>Setting Up Your Spring Boot Project</h2><p>First things first - let's create a Spring Boot project with MongoDB support. Head over to Spring Initializr or add these dependencies to your existing project:</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-data-mongodb&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
    &lt;artifactId&gt;lombok&lt;/artifactId&gt;
    &lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;

</code></pre><p>Configure your MongoDB connection in <code>application.yml</code>:</p><pre><code class="language-plaintext">spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017/ecommerce_db
      auto-index-creation: true
</code></pre><p>That <code>auto-index-creation</code> property is important - it tells Spring to automatically create indexes based on your annotations. Remember those indexes we created manually in the last post? Spring can handle that for us now.</p><h2>Understanding MongoDB Annotations</h2><p>Spring Data MongoDB provides powerful annotations that map Java objects to MongoDB documents. Let's explore the key ones you'll use constantly.</p><h3>The @Document Annotation</h3><p>The <code>@Document</code> annotation marks a class as a MongoDB document. It's like <code>@Entity</code> in JPA, but for MongoDB:</p><pre><code class="language-java">@Document(collection = "orders")
public class Order {
    // fields here
}
</code></pre><p>This tells Spring that instances of this class should be stored in the "orders" collection. If you omit the collection name, Spring uses the class name in lowercase.</p><h3>The @Id Annotation</h3><p>Every document needs a unique identifier. In MongoDB, this is typically an ObjectId, but Spring is flexible:</p><pre><code class="language-java">@Id
private String id;
</code></pre><p>Spring automatically converts between MongoDB's ObjectId and Java's String. You can also use ObjectId directly if you prefer, but String is more convenient.</p><h3>Auditing with @CreatedDate and @LastModifiedDate</h3><p>Want to track when documents are created and updated? Spring's auditing annotations have you covered:</p><pre><code class="language-java">@CreatedDate
private LocalDateTime createdAt;

@LastModifiedDate
private LocalDateTime updatedAt;
</code></pre><p>Don't forget to enable auditing in your configuration:</p><pre><code class="language-java">@Configuration
@EnableMongoAuditing
public class MongoConfig {
    // configuration here
}
</code></pre><h3>The @Indexed Annotation</h3><p>Remember creating indexes manually? With Spring, just annotate the field:</p><pre><code class="language-java">@Indexed
private String status;

@Indexed(unique = true)
private String email;
</code></pre><p>Spring creates these indexes automatically when the application starts. You can verify this in the MongoDB shell:</p><pre><code class="language-plaintext">db.orders.getIndexes()
</code></pre><h2>Creating Your First Entity</h2><p>Let's create our Order entity with all the bells and whistles:</p><pre><code class="language-java">@Data
@Builder
@Document(collection = "orders")
public class Order {
    @Id
    private String id;

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;

    private String status;
    private int quantity;
    private double totalPrice;
}
</code></pre><p>The <code>@Data</code> annotation from Lombok generates getters, setters, toString, equals, and hashCode methods. The <code>@Builder</code> annotation provides a fluent API for object creation - perfect for tests!</p><h2>Repository Pattern with Spring Data MongoDB</h2><p>Here's where Spring Data truly shines. Instead of writing boilerplate CRUD code, you declare an interface:</p><pre><code class="language-java">@Repository
public interface OrderRepository extends MongoRepository&lt;Order, String&gt; {
    // That's it! CRUD operations are automatically available
}
</code></pre><p>Just by extending <code>MongoRepository</code>, you get:</p><ul><li><code>save()</code> for creating and updating</li><li><code>findById()</code> for retrieving by ID</li><li><code>findAll()</code> for getting all documents</li><li><code>delete()</code> for removing documents</li><li><code>count()</code> for counting documents</li><li>And much more!</li></ul><h3>Custom Query Methods</h3><p>Spring Data MongoDB can derive queries from method names:</p><pre><code class="language-java">@Repository
public interface OrderRepository extends MongoRepository&lt;Order, String&gt; {
    List&lt;Order&gt; findByStatus(String status);

    List&lt;Order&gt; findByTotalPriceGreaterThan(double price);

    List&lt;Order&gt; findByStatusAndQuantityLessThan(String status, int quantity);

    Optional&lt;Order&gt; findFirstByStatusOrderByCreatedAtDesc(String status);
}
</code></pre><p>Spring automatically generates the MongoDB queries based on these method names.</p><h3>Using @Query for Complex Queries</h3><p>When method names get too long, use the <code>@Query</code> annotation:</p><pre><code class="language-java">@Query("{ 'status': ?0, 'totalPrice': { $gte: ?1 } }")
List&lt;Order&gt; findPendingOrdersAbovePrice(String status, double minPrice);

@Query("{ 'createdAt': { $gte: ?0, $lt: ?1 } }")
List&lt;Order&gt; findOrdersInDateRange(LocalDateTime start, LocalDateTime end);
</code></pre><p>The <code>?0</code>, <code>?1</code> are positional parameters. You can also use named parameters for clarity:</p><pre><code class="language-java">@Query("{ 'status': :#{#status}, 'quantity': { $gt: :#{#minQty} } }")
List&lt;Order&gt; findActiveOrders(@Param("status") String status,
                             @Param("minQty") int minQuantity);
</code></pre><h2>CRUD Operations in Action</h2><p>Let's write some tests to see our repository in action. This is where everything comes together:</p><pre><code class="language-java">@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OrderRepositoryTest {

    @Autowired
    private OrderRepository orderRepository;

    private static String orderId;

    @Test
    @Order(1)
    void createOrder() {
        Order order = Order.builder()
            .status("pending")
            .quantity(3)
            .totalPrice(299.97)
            .build();

        Order saved = orderRepository.save(order);

        assertNotNull(saved.getId());
        assertNotNull(saved.getCreatedAt());
        assertEquals("pending", saved.getStatus());

        orderId = saved.getId(); // Save for later tests
    }
}
</code></pre><h3>Reading Documents</h3><p>Finding documents is straightforward:</p><pre><code class="language-java">@Test
@Order(2)
void findOrder() {
    Optional&lt;Order&gt; found = orderRepository.findById(orderId);

    assertTrue(found.isPresent());
    assertEquals(299.97, found.get().getTotalPrice());
}

@Test
@Order(3)
void findByStatus() {
    List&lt;Order&gt; pendingOrders = orderRepository.findByStatus("pending");

    assertFalse(pendingOrders.isEmpty());
    pendingOrders.forEach(order -&gt;
        assertEquals("pending", order.getStatus())
    );
}
</code></pre><h3>Updating Documents</h3><p>Updates are as simple as saving an existing document:</p><pre><code class="language-java">@Test
@Order(4)
void updateOrder() {
    Order order = orderRepository.findById(orderId).orElseThrow();

    order.setStatus("processing");
    order.setQuantity(5);

    Order updated = orderRepository.save(order);

    assertEquals("processing", updated.getStatus());
    assertEquals(5, updated.getQuantity());
    assertNotEquals(updated.getCreatedAt(), updated.getUpdatedAt());
}
</code></pre><h3>Deleting Documents</h3><p>Removing documents is equally simple:</p><pre><code class="language-java">@Test
@Order(5)
void deleteOrder() {
    orderRepository.deleteById(orderId);

    Optional&lt;Order&gt; deleted = orderRepository.findById(orderId);
    assertTrue(deleted.isEmpty());
}
</code></pre><h2>Pagination and Sorting</h2><p>Real applications need pagination. Spring Data makes this elegant:</p><pre><code class="language-java">@Test
void paginationExample() {
    // Create some test data
    for (int i = 0; i &lt; 20; i++) {
        orderRepository.save(Order.builder()
            .status("pending")
            .quantity(i)
            .totalPrice(i * 10.0)
            .build());
    }

    // Paginate results
    Pageable pageable = PageRequest.of(0, 5, Sort.by("totalPrice").descending());
    Page&lt;Order&gt; page = orderRepository.findAll(pageable);

    assertEquals(5, page.getContent().size());
    assertEquals(20, page.getTotalElements());
    assertEquals(4, page.getTotalPages());
}
</code></pre><p>You can also add pagination to custom query methods:</p><pre><code class="language-java">Page&lt;Order&gt; findByStatus(String status, Pageable pageable);
</code></pre><h2>What's Next?</h2><p>We have now built a Spring Boot application with MongoDB, created entities with proper annotations, implemented CRUD operations, and even added pagination.</p><p>But we're just scratching the surface. In my next post, we'll explore relationships in MongoDB. We will learn when to embed documents versus when to reference them, and how Spring Data MongoDB handles these relationships elegantly.</p><p>Next Part here:</p><p><strong>Part 3</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-relationships-embedding-vs-referencing/">MongoDB Relationships in Spring Boot</a></p>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>Spring Boot</category>
            <category>Mongo DB</category>
            <category>Spring Data MongoDB</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/151_a545b1f5a7.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Getting Started with MongoDB: Installation and Basic Commands]]></title>
            <link>https://www.codingshuttle.com/blogs/mongodb-basics-installation-and-commands</link>
            <guid>https://www.codingshuttle.com/blogs/mongodb-basics-installation-and-commands</guid>
            <pubDate>Sat, 13 Sep 2025 10:23:58 GMT</pubDate>
            <description><![CDATA[In this blog, we will learn how to install MongoDB, perform basic CRUD operations, create indexes, and even write simple aggregation pipelines.]]></description>
            <content:encoded><![CDATA[<p>Welcome to the first part of my four-part series on building an e-commerce order management system with Spring Data MongoDB! If you're new to MongoDB or looking to harness its power for flexible, scalable applications, you're in the right place.</p><p>If you've been working with traditional SQL databases and hearing all the buzz about NoSQL, you're probably curious about what makes MongoDB so special. Well, you're in the right place! This is the first post in our four-part series where I will cover MongoDB basics all the way to building sophisticated Spring Boot applications with complex queries.</p><blockquote><p>This article is part of our comprehensive 4-part MongoDB with Spring Boot series.</p></blockquote><p><strong>Part 1 (Current)</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-basics-installation-and-commands/">Getting Started with MongoDB: Installation and Basic Commands</a></p><p><strong>Part 2</strong>: <a href="https://www.codingshuttle.com/blogs/spring-boot-mongodb-crud-operations/">MongoDB with Spring Boot using Spring-Data-MongoDB</a></p><p><strong>Part 3</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-relationships-embedding-vs-referencing/">MongoDB Relationships in Spring Boot</a></p><p><strong>Part 4</strong>: <a href="https://www.codingshuttle.com/blogs/mongodb-advanced-queries-criteria-api-mongotemplate/">Advanced MongoDB Queries: Mastering Criteria API and MongoTemplate</a></p><h2>Why MongoDB?</h2><p>Before we dive into installation and commands, let me ask you a simple question - why should you care about MongoDB? In today's world of microservices and cloud-native applications, MongoDB offers something that traditional databases struggle with: flexibility and scalability. Unlike rigid table structures, MongoDB stores data in flexible, <strong>JSON-like documents</strong>. This means you can store complex nested data without the headache of multiple JOIN operations.</p><blockquote><p>Real-world data is messy, hierarchical, and constantly evolving. MongoDB embraces this reality.</p></blockquote><h2>Setting Up MongoDB on Your Machine</h2><p>Let's get MongoDB up and running on your system. The installation process varies slightly depending on your operating system.</p><h3>Using Docker (Recommended for Development)</h3><p>If you don’t like Docker or you have not used it yet, let me tell you this is the best way to run services in an isolated environemnt inside your computer. You don’t need to worry about complicated setup, system permissions and configuration, and cleanup when you want to unistall it. Docker simplifies setting up MongoDB. Here's how to get started:</p><ol><li><strong>Install Docker</strong>: Ensure Docker is installed (e.g., Docker Desktop for Windows/Mac or Docker on Linux).</li><li><strong>Pull MongoDB Image</strong>: Run the following command to download MongoDB 7.0:</li></ol><pre><code class="language-plaintext">docker pull mongo:8.0
</code></pre><p><strong>Run MongoDB Container</strong>: Start a MongoDB instance with a root user for authentication:</p><p>This maps port 27017 (MongoDB's default) to your host and sets up an admin user.</p><pre><code class="language-plaintext">docker run -d --name mongodb -p 27017:27017 \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=password \
  -v mongodb_data:/data/db \
  mongo:8.0</code></pre><ol><li><strong>Verify</strong>: Check if the container is running:</li></ol><pre><code class="language-plaintext">docker ps</code></pre><p>With MongoDB running, connect using mongosh, MongoDB's shell:</p><pre><code class="language-plaintext">docker exec -it mongodb mongosh -u admin -p password</code></pre><p>This opens the MongoDB shell. If you installed directly, run mongosh locally.</p><h3>Installing on Windows</h3><p>For Windows users, head over to the <a href="https://www.mongodb.com/try/download/community-kubernetes-operator">MongoDB download center</a> and grab the MSI installer. The installation wizard will guide you through the process. Make sure to:</p><ol><li>Choose "Complete" installation</li><li>Install MongoDB as a Windows Service (this ensures MongoDB starts automatically)</li><li>Include MongoDB Compass (the GUI tool) in your installation</li></ol><h3>Installing on macOS</h3><p>Mac users have it easy with Homebrew. Simply run:</p><pre><code class="language-plaintext">brew tap mongodb/brew
brew install mongodb-community
</code></pre><p>To start MongoDB as a service:</p><pre><code class="language-plaintext">brew services start mongodb-community
</code></pre><p>To connect with your MongoDB database, open your terminal and type <code>mongosh</code> (or <code>mongo</code> for older versions) to enter the MongoDB shell. You'll see something like:</p><pre><code class="language-plaintext">Current Mongosh Log ID: 65f3d4c5...
Connecting to: mongodb://127.0.0.1:27017
Using MongoDB: 8.0.0
Using Mongosh: 2.1.5
</code></pre><p>Congratulations! You're now connected to your MongoDB instance. Let's explore some essential commands that you'll use daily.</p><h2>MongoDB Commands</h2><p>Now, let's explore MongoDB's core commands to manage databases and collections for our e-commerce system. We'll use a database named ecommerce to store our users, orders, and products.</p><h3>1. Database Operations</h3><ul><li><strong>List Databases</strong>: See all databases:</li></ul><pre><code class="language-plaintext">show dbs
</code></pre><ul><li><strong>Switch/Create Database</strong>: Use ecommerce (created on first write):</li></ul><pre><code class="language-plaintext">use ecommerce
</code></pre><h3>2. Collection Operations</h3><p>Collections are like tables but hold JSON-like documents. Let's create an orders collection.</p><p><strong>Insert a Document</strong>:</p><p>This adds a single order document.</p><pre><code class="language-plaintext">db.orders.insertOne({
  _id: "order123",
  status: "pending",
  quantity: 2,
  totalPrice: 199.98,
  address: { city: "Delhi", state: "Delhi", zipCode: "110001" }
})
</code></pre><ul><li><strong>List Collections</strong>:</li></ul><pre><code class="language-plaintext">show collections
</code></pre><h3>3. Querying Documents</h3><ul><li><strong>Find All Orders</strong>:</li></ul><pre><code class="language-plaintext">db.orders.find()
db.orders.find().pretty()
</code></pre><p><strong>Filter by City</strong>:</p><p>Queries the embedded address field.</p><pre><code class="language-plaintext">db.orders.find({ "address.city": "Delhi" })
</code></pre><ul><li><strong>Find One Document</strong>:</li></ul><pre><code class="language-plaintext">db.orders.findOne({ status: "pending" })
</code></pre><h3>4. Updating Documents</h3><ul><li><strong>Update Status</strong>:</li></ul><pre><code class="language-plaintext">db.orders.updateOne(
  { _id: "order123" },
  { $set: { status: "shipped", updatedAt: new Date() } }
)
</code></pre><ul><li><strong>Update Multiple</strong>:</li></ul><pre><code class="language-plaintext">db.orders.updateMany(
  { "address.city": "Delhi" },
  { $set: { status: "processing" } }
)
</code></pre><h3>5. Deleting Documents</h3><pre><code class="language-plaintext">db.orders.deleteOne({ _id: "order123" })
</code></pre><pre><code class="language-plaintext">db.orders.deleteMany({ status: "cancelled" })
</code></pre><h3>6. Indexing for Performance</h3><p>Indexes speed up queries, crucial for fields like address.city in our e-commerce app.</p><ul><li><strong>Create Index</strong>:</li></ul><pre><code class="language-plaintext">db.orders.createIndex({ "address.city": 1 })
</code></pre><ul><li><strong>List Indexes</strong>:</li></ul><pre><code class="language-plaintext">db.orders.getIndexes()
</code></pre><h3>7. Inserting Multiple Documents</h3><p>Add more orders to simulate real data:</p><pre><code class="language-plaintext">db.orders.insertMany([
  { _id: "order456", status: "shipped", quantity: 1, totalPrice: 999.99, address: { city: "Mumbai", state: "Maharashtra" } },
  { _id: "order789", status: "pending", quantity: 3, totalPrice: 149.97, address: { city: "Delhi", state: "Delhi" } }
])
</code></pre><h3>8. Useful Administrative Commands</h3><p>Here are some commands you'll find handy:</p><p>Check collection statistics:</p><pre><code class="language-plaintext">db.products.stats()
</code></pre><p>See the current database:</p><pre><code class="language-plaintext">db
</code></pre><p>Drop a collection (careful with this one!):</p><pre><code class="language-plaintext">db.products.drop()
</code></pre><p>Drop the entire database (even more careful!):</p><pre><code class="language-plaintext">db.dropDatabase()
</code></pre><h2>MongoDB Compass</h2><p>While the command line is powerful, sometimes you want a visual interface. MongoDB Compass (which you installed earlier) provides a GUI for:</p><ul><li>Viewing and editing documents</li><li>Building queries visually</li><li>Viewing real-time server statistics</li></ul><p>Launch Compass and connect to <code>mongodb://localhost:27017</code>. You'll see all your databases and collections in a user-friendly interface. It's particularly useful when you're exploring data structures or debugging complex queries.</p><h2>What's Next?</h2><p>You've just taken your first steps into the MongoDB world! You can now install MongoDB, perform basic CRUD operations, create indexes, and even write simple aggregation pipelines. But this is just the beginning.</p><p>In my next blog post, I’ll show you how to integrate MongoDB with Spring Boot. We'll create a proper Java application with entities, repositories, and all the Spring Data MongoDB goodness. You'll see how the <code>Order</code> and <code>Product</code> entities come to life with annotations like <code>@Document</code>, <code>@Id</code>, and <code>@Indexed</code>. We'll implement CRUD operations the Spring way and write tests to ensure everything works perfectly.</p><p>So practice these commands, experiment with different query operators, and get comfortable with the MongoDB shell. Trust me, this foundation will make your Spring MongoDB journey much smoother. See you in the next post where we'll build something real with Spring Boot and MongoDB!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>Spring Boot</category>
            <category>Mongo DB</category>
            <category>Spring Data MongoDB</category>
            <category>Mongo DB Installation</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/150_b6a9b3952c.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Mastering Optional in Java: Avoid NullPointerExceptions with Best Practices]]></title>
            <link>https://www.codingshuttle.com/blogs/mastering-optional-in-java-say-goodbye-to-null-pointer-exceptions</link>
            <guid>https://www.codingshuttle.com/blogs/mastering-optional-in-java-say-goodbye-to-null-pointer-exceptions</guid>
            <pubDate>Mon, 08 Sep 2025 05:58:20 GMT</pubDate>
            <description><![CDATA[Learn how to use Java Optional to handle null values safely and avoid NullPointerExceptions. This guide covers Optional creation, methods, practical examples, best practices, and common pitfalls every Java developer should know.]]></description>
            <content:encoded><![CDATA[<p>NullPointerExceptions are a common headache for Java developers. They often arise from unhandled <code>null</code> references, and when they occur they lead to runtime crashes. As we know, this can be very frustrating. But to avoid this frustration, Java introduced the <code>Optional</code> class in Java 8.</p><p>The <code>Optional</code> class offers a powerful way to handle <code>null</code> values gracefully. It reduces the risk of NullPointerExceptions and helps make code more robust. In this blog, we'll explore how to master <code>Optional</code> in Java with practical examples to demonstrate its power.</p><h2>What is NullPointerException?</h2><p>A <strong>NullPointerException (NPE)</strong> happens in Java when your code tries to use something that doesn’t exist in other words, when a variable points to <code>null</code> instead of a real object.</p><p>Example:</p><pre><code class="language-java">String name = null;
System.out.println(name.length()); // Boom! NullPointerException</code></pre><p>Here, <code>name</code> has no value (it’s <code>null</code>), so when we ask for <code>length()</code>, Java throws a NullPointerException.</p><h2>What is Optional?</h2><p><code>Optional&lt;T&gt;</code> is a container object that may or may not contain a non-null value. It encourages explicit handling of cases where a value might be absent, making your code more expressive and safer. Instead of returning <code>null</code>, methods can return an <code>Optional</code> to indicate that a value might not exist.</p><p>Think of <code>Optional</code> as a box: it either contains something (a value) or is empty. By forcing developers to handle both cases, <code>Optional</code> prevents accidental NPEs.</p><h2>Why Use Optional?</h2><ul><li><strong>Avoid NullPointerExceptions</strong>: <code>Optional</code> forces you to think about the absence of a value, reducing the chance of dereferencing <code>null</code>.</li><li><strong>Cleaner Code</strong>: It provides a fluent API for handling missing values, reducing boilerplate <code>if (value != null)</code> checks.</li><li><strong>Better Intent</strong>: Using <code>Optional</code> signals to other developers that a method might not return a value, improving code readability.</li></ul><h2>Creating an Optional</h2><p>You can create an <code>Optional</code> in several ways:</p><ol><li><strong>Empty Optional</strong>: Represents the absence of a value.</li></ol><pre><code class="language-java">Optional&lt;String&gt; empty = Optional.empty();</code></pre><ol><li><strong>Optional with a Non-Null Value</strong>:</li></ol><pre><code class="language-java">Optional&lt;String&gt; name = Optional.of("Alice");</code></pre><p>Note: <code>Optional.of</code> throws a <code>NullPointerException</code> if the value is <code>null</code>.</p><ol><li><strong>Optional with a Potentially Null Value</strong>:</li></ol><pre><code class="language-java">String nullableValue = null;
Optional&lt;String&gt; maybeName = Optional.ofNullable(nullableValue);</code></pre><h2>Common Optional Methods</h2><p><code>Optional</code> provides a rich API to handle values safely. Here are some key methods:</p><ul><li><code><strong>isPresent()</strong></code>: Returns <code>true</code> if a value exists.</li><li><code><strong>isEmpty()</strong></code> (Java 11+): Returns <code>true</code> if no value exists.</li><li><code><strong>orElse(T other)</strong></code>: Returns the value if present, otherwise returns <code>other</code>.</li><li><code><strong>orElseGet(Supplier&lt;? extends T&gt; supplier)</strong></code>: Returns the value if present, otherwise invokes the supplier.</li><li><code><strong>orElseThrow()</strong></code>: Throws an exception if no value is present.</li><li><code><strong>map(Function&lt;? super T, ? extends U&gt; mapper)</strong></code>: Transforms the value if present.</li><li><code><strong>flatMap(Function&lt;? super T, Optional&lt;U&gt;&gt; mapper)</strong></code>: Transforms the value into another <code>Optional</code>.</li><li><code><strong>filter(Predicate&lt;? super T&gt; predicate)</strong></code>: Keeps the value if it matches the predicate.</li></ul><h2>Practical Examples</h2><p>Let’s dive into some real-world scenarios to see <code>Optional</code> in action.</p><h3>1. Replacing Null Checks</h3><p>Without <code>Optional</code>, you might write:</p><pre><code class="language-java">String name = getUserName();
if (name != null) {
    System.out.println(name.toUpperCase());
} else {
    System.out.println("Name not found");
}</code></pre><p>With <code>Optional</code>, this becomes more concise:</p><pre><code class="language-java">Optional&lt;String&gt; name = Optional.ofNullable(getUserName());
name.map(String::toUpperCase)
    .ifPresentOrElse(
        System.out::println,
        () -&gt; System.out.println("Name not found")
    );</code></pre><p>The <code>Optional</code> version is more fluent and explicit about handling the absence of a value.</p><h3>2. Chaining Operations</h3><p>Suppose you want to get a user’s email domain from a database. Without <code>Optional</code>, you’d need multiple null checks:</p><pre><code class="language-java">User user = getUser();
if (user != null) {
    String email = user.getEmail();
    if (email != null) {
        String domain = email.split("@")[1];
        if (domain != null) {
            System.out.println(domain);
        }
    }
}</code></pre><p>With <code>Optional</code>, you can chain operations:</p><pre><code class="language-java">Optional&lt;User&gt; user = Optional.ofNullable(getUser());
user.map(User::getEmail)
    .map(email -&gt; email.split("@")[1])
    .ifPresent(System.out::println);</code></pre><p>This is more readable and avoids nested null checks.</p><h3>3. Providing Defaults</h3><p>You can provide a default value when an <code>Optional</code> is empty:</p><pre><code class="language-java">Optional&lt;String&gt; name = Optional.ofNullable(getUserName());
String result = name.orElse("Anonymous");
System.out.println(result); // Prints "Anonymous" if name is empty</code></pre><p>For expensive default operations, use <code>orElseGet</code>:</p><pre><code class="language-java">String result = name.orElseGet(() -&gt; computeExpensiveDefault());</code></pre><h3>4. Throwing Exceptions</h3><p>If a missing value is an error condition, you can throw an exception:</p><pre><code class="language-java">String name = Optional.ofNullable(getUserName())
    .orElseThrow(() -&gt; new IllegalStateException("User name is required"));</code></pre><h3>5. Filtering Values</h3><p>You can filter values based on a condition:</p><pre><code class="language-java">Optional&lt;String&gt; name = Optional.ofNullable(getUserName());
name.filter(n -&gt; n.length() &gt; 3)
    .ifPresent(System.out::println); // Prints name only if longer than 3 characters</code></pre><h2>Best Practices</h2><ol><li><strong>Don’t Use Optional as a Method Parameter</strong>: This can make APIs harder to understand. Instead, use overloading or nullable parameters.</li></ol><pre><code class="language-java">// Avoid
void process(Optional&lt;String&gt; name) { ... }

// Better
void process(String name) { ... }
void process() { ... }</code></pre><ol><li><strong>Avoid Overusing Optional</strong>: Not every method needs to return <code>Optional</code>. Use it when absence of a value is a valid case.</li><li><strong>Don’t Use Optional.get() Blindly</strong>: Calling <code>get()</code> without <code>isPresent()</code> defeats the purpose of <code>Optional</code> and can throw <code>NoSuchElementException</code>.</li><li><strong>Combine with Streams</strong>: <code>Optional</code> works well with Java Streams for elegant data processing.</li></ol><pre><code class="language-java">List&lt;Optional&lt;String&gt;&gt; names = getNames();
List&lt;String&gt; validNames = names.stream()
    .filter(Optional::isPresent)
    .map(Optional::get)
    .collect(Collectors.toList());</code></pre><ol><li><strong>Use orElseGet for Expensive Defaults</strong>: Prefer <code>orElseGet</code> over <code>orElse</code> when the default value is computationally expensive.</li></ol><h2>Conclusion</h2><p>Java’s <code>Optional</code> class is a game-changer for writing robust, null-safe code. By embracing <code>Optional</code>, you can eliminate many causes of NullPointerExceptions, make your code more expressive, and improve its readability.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java Optional Tutorial</category>
            <category>Mastering Optional in Java</category>
            <category>Java Optional Best Practices</category>
            <category>How to Avoid NullPointerException</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Optional_In_Java_6d23cf0237.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Java Records: A Modern Way to Write Immutable Data Classes]]></title>
            <link>https://www.codingshuttle.com/blogs/java-records-a-modern-way-to-write-immutable-data-classes</link>
            <guid>https://www.codingshuttle.com/blogs/java-records-a-modern-way-to-write-immutable-data-classes</guid>
            <pubDate>Mon, 08 Sep 2025 05:54:56 GMT</pubDate>
            <description><![CDATA[Learn how to use Java Records to write clean, immutable data classes with less boilerplate. Explore syntax, features, benefits, limitations, and best practices with examples.]]></description>
            <content:encoded><![CDATA[<p>In the evolving world of Java, managing data efficiently and ensuring immutability are key concerns for developers. and to solve this problem Java Introduced <strong>records.</strong> A Java records offer a modern approach to creating immutable data classes.</p><p>Unlike traditional Java classes, records are designed specifically for holding data, reducing boilerplate code and enhancing readability. And in this blog we dives into Java records, their benefits, and how they revolutionize the creation of immutable data structures.</p><h2>What Are Java Records?</h2><p>A record is a special type of class in Java that automatically provides a concise syntax for declaring immutable data carriers. It generates constructors, getters, <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code> methods based on the components defined in its declaration. This eliminates the need to write repetitive code for simple data-holding classes.</p><h3>Syntax Example</h3><pre><code class="language-java">public record Person(String name, int age) {}</code></pre><p>This single line creates a <code>Person</code> record with <code>name</code> and <code>age</code> as components, automatically providing:</p><ul><li>A canonical constructor.</li><li>Getter methods (<code>name()</code> and <code>age()</code>).</li><li>Implementations of <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code>.</li></ul><h2>Why Use Records?</h2><ol><li><strong>Immutability</strong>: Records are inherently immutable, ensuring data cannot be altered after creation, which is ideal for value-based objects.</li><li><strong>Reduced Boilerplate</strong>: No need to manually write getters, setters, or equality methods.</li><li><strong>Clarity</strong>: The intent of the class as a data holder is immediately clear, improving code maintainability.</li><li><strong>Performance</strong>: Compiled records are optimized for memory and speed compared to traditional classes with similar functionality.</li></ol><h2>Key Features</h2><ul><li><strong>Compact Constructors</strong>: Allows validation or initialization logic within a concise constructor.</li></ul><pre><code class="language-java">public record Person(String name, int age) {
    public Person {
        if (age &lt; 0) throw new IllegalArgumentException("Age cannot be negative");
        if (name == null || name.isBlank()) throw new IllegalArgumentException("Name cannot be empty");
    }
}</code></pre><ul><li><strong>Component Access</strong>: Access components using method names that match the field names (e.g., <code>person.name()</code>).</li><li><strong>No Setter Methods</strong>: Prevents modification, enforcing immutability.</li><li><strong>Custom Methods</strong>: You can add business logic or additional methods as needed.</li></ul><pre><code class="language-java">public record Person(String name, int age) {
    public boolean isAdult() {
        return age &gt;= 18;
    }
}</code></pre><h2>Creating and Using Records</h2><h3>Instantiation</h3><pre><code class="language-java">Person person = new Person("Alice", 25);
System.out.println(person); // Output: Person[name=Alice, age=25]
System.out.println(person.isAdult()); // Output: true</code></pre><h3>Immutability in Action</h3><p>Once created, the record's state cannot change:</p><pre><code class="language-java">person.name("Bob"); // Compilation error: no setter exists</code></pre><h2>Comparing with Traditional Classes</h2><p>Traditional immutable classes require more code:</p><pre><code class="language-java">public class PersonOld {
    private final String name;
    private final int age;

    public PersonOld(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }

    @Override public boolean equals(Object o) { ... }
    @Override public int hashCode() { ... }
    @Override public String toString() { ... }
}</code></pre><p>With records, the same functionality is achieved with less effort and potential for human error.</p><h2>Best Practices</h2><ul><li><strong>Use for Data Transfer Objects (DTOs)</strong>: Records are perfect for DTOs or entities that only carry data.</li><li><strong>Avoid Complex Logic</strong>: Keep records simple; move complex behavior to separate classes if needed.</li><li><strong>Validate in Constructors</strong>: Use compact constructors for input validation.</li><li><strong>Leverage with Streams</strong>: Combine records with Java Streams for elegant data processing.</li></ul><pre><code class="language-java">List&lt;Person&gt; people = List.of(new Person("Alice", 25), new Person("Bob", 17));
people.stream().filter(Person::isAdult).forEach(System.out::println);</code></pre><h2>Limitations</h2><ul><li><strong>No Inheritance</strong>: Records cannot extend other classes (though they implicitly extend <code>Record</code>).</li><li><strong>Fixed Components</strong>: You cannot add or remove fields after declaration.</li><li><strong>Serialization</strong>: Requires explicit handling if needed (e.g., implementing <code>Serializable</code>).</li></ul><h2>Conclusion</h2><p>Java records provide a modern, efficient way to create immutable data classes, significantly reducing boilerplate and enhancing code clarity. Ideal for DTOs, configuration objects, or any data-centric use case.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java Records</category>
            <category>Immutable Data Classes</category>
            <category>Java Records vs Classes</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/java_reacords_8ae5812df7.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Date and Time API in Java 8+: Best Practices & Common Mistakes]]></title>
            <link>https://www.codingshuttle.com/blogs/date-and-time-api-in-java-8-best-practices-and-common-mistakes</link>
            <guid>https://www.codingshuttle.com/blogs/date-and-time-api-in-java-8-best-practices-and-common-mistakes</guid>
            <pubDate>Mon, 08 Sep 2025 05:51:44 GMT</pubDate>
            <description><![CDATA[Learn how to use the Java 8 Date and Time API (java.time) effectively. Explore LocalDate, LocalTime, ZonedDateTime, Duration, and Period with best practices, common mistakes to avoid, and real-world examples for modern Java applications.]]></description>
            <content:encoded><![CDATA[<p>The introduction of the Java 8 Date and Time API (<code>java.time</code> package) marked a significant improvement over the legacy <code>java.util.Date</code> and <code>java.util.Calendar</code> classes. These are Designed to be immutable, thread-safe, and intuitive, this API is the go-to choice for handling dates, times, and durations in modern Java applications.</p><p>In this blog we explore explores how to use the API effectively and highlights mistakes to avoid. So let’s get started.</p><h2>Why Use the Java 8+ Date and Time API?</h2><p>The <code>java.time</code> API addresses the shortcomings of older classes, offering:</p><ul><li>Immutability to prevent unintended modifications.</li><li>Thread-safety for concurrent applications.</li><li>Clear separation of concerns (e.g., date-only, time-only, or combined types).</li><li>Support for time zones and internationalization.</li></ul><p>Key classes include <code>LocalDate</code>, <code>LocalTime</code>, <code>LocalDateTime</code>, <code>ZonedDateTime</code>, and <code>Duration</code>.</p><h2>Best Practices</h2><h3>1. Prefer Specific Types Over General Ones</h3><p>Use <code>LocalDate</code> for dates without time, <code>LocalTime</code> for times without dates, and <code>LocalDateTime</code> for combined date-time values. Avoid <code>LocalDateTime</code> when time zones are relevant; use <code>ZonedDateTime</code> or <code>OffsetDateTime</code> instead.</p><pre><code class="language-java">LocalDate date = LocalDate.of(2025, 9, 8); // 2025-09-08
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Kolkata")); // 2025-09-08T10:32+05:30[Asia/Kolkata]</code></pre><h3>2. Handle Time Zones Explicitly</h3><p>Always specify time zones when dealing with global applications to avoid ambiguity. Use <code>ZoneId</code> and <code>ZoneOffset</code> for precision.</p><pre><code class="language-java">ZonedDateTime utcTime = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(utcTime); // e.g., 2025-09-08T05:02+00:00[UTC]</code></pre><h3>3. Use Immutability to Your Advantage</h3><p>Since <code>java.time</code> objects are immutable, chain methods safely without side effects.</p><pre><code class="language-java">LocalDate nextWeek = LocalDate.now().plusWeeks(1);</code></pre><h3>4. Parse and Format with Standard Methods</h3><p>Use <code>DateTimeFormatter</code> for consistent parsing and formatting instead of manual string manipulation.</p><pre><code class="language-java">DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
String formattedDate = LocalDateTime.now().format(formatter); // e.g., 2025-09-08 10:32
LocalDateTime parsedDate = LocalDateTime.parse("2025-09-08 10:32", formatter);</code></pre><h3>5. Manage Durations and Periods</h3><p>Use <code>Duration</code> for time-based amounts (e.g., hours, minutes) and <code>Period</code> for date-based amounts (e.g., years, months).</p><pre><code class="language-java">Duration duration = Duration.ofHours(2);
Period period = Period.ofMonths(3);</code></pre><h3>6. Avoid Legacy Classes</h3><p>Minimize use of <code>Date</code> and <code>Calendar</code>. Convert them to <code>java.time</code> types when necessary using <code>Instant</code> or <code>ZonedDateTime</code>.</p><pre><code class="language-java">Instant instant = new Date().toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());</code></pre><h2>Common Mistakes to Avoid</h2><h3>1. Ignoring Time Zones</h3><p>Failing to account for time zones can lead to incorrect date-time calculations, especially in distributed systems.</p><p><strong>Mistake</strong>:</p><pre><code class="language-java">LocalDateTime now = LocalDateTime.now(); // No time zone, assumes system default</code></pre><p><strong>Fix</strong>:</p><pre><code class="language-java">ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"))</code></pre><h3>2. Mutating Objects</h3><p>Attempting to modify <code>java.time</code> objects (which are immutable) can cause confusion.</p><p><strong>Mistake</strong>:</p><pre><code class="language-java">LocalDate date = LocalDate.now();
date = date.plusDays(1); // Correct, but some expect mutation</code></pre><p><strong>Fix</strong>: Understand immutability and assign the result to a new variable.</p><h3>3. Overusing <code>now()</code> Without Context</h3><p>Calling <code>LocalDateTime.now()</code> without a <code>ZoneId</code> relies on the system’s default, which may change.</p><p><strong>Mistake</strong>:</p><pre><code class="language-java">LocalDateTime now = LocalDateTime.now(); // Depends on system time zone</code></pre><p><strong>Fix</strong>:</p><pre><code class="language-java">LocalDateTime now = LocalDateTime.now(Clock.systemUTC());</code></pre><h3>4. Manual String Parsing</h3><p>Parsing dates with <code>SimpleDateFormat</code> from the legacy API is error-prone and not thread-safe.</p><p><strong>Mistake</strong>:</p><pre><code class="language-java">SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2025-09-08"); // Not thread-safe</code></pre><p><strong>Fix</strong>:</p><pre><code class="language-java">DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse("2025-09-08", formatter);</code></pre><h3>5. Misusing <code>Instant</code> for Local Operations</h3><p><code>Instant</code> represents a point on the timeline in UTC, which may not suit local date-time needs.</p><p><strong>Mistake</strong>:</p><pre><code class="language-java">Instant instant = Instant.now();
System.out.println(instant.plusDays(1)); // UTC-based, no local adjustment</code></pre><p><strong>Fix</strong>:</p><pre><code class="language-java">ZonedDateTime zdt = ZonedDateTime.now().plusDays(1); // Zone-aware</code></pre><h2>Advanced Tips</h2><p><strong>Use </strong><code><strong>Clock</strong></code><strong> for Testing</strong>: Inject a <code>Clock</code> to mock time in unit tests.</p><p><strong>Handle Leap Years and DST</strong>: Rely on the API’s built-in logic for accurate calculations.</p><p><strong>Combine with Streams</strong>: Process date ranges efficiently.</p><h2>Conclusion</h2><p>The Java 8+ Date and Time API is a powerful tool for managing temporal data with precision and safety. By following best practices and using specific types, handling time zones, and leveraging immutability you can avoid common mistakes and build reliable applications.</p><pre><code class="language-java">LocalDate start = LocalDate.of(2025, 9, 1);
LocalDate end = LocalDate.of(2025, 9, 8);
start.datesUntil(end).forEach(System.out::println);</code></pre><pre><code class="language-java">Clock fixedClock = Clock.fixed(Instant.now(), ZoneId.of("UTC"));
LocalDateTime testTime = LocalDateTime.now(fixedClock);</code></pre>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java 8 Date And Time API</category>
            <category>Java LocalDate vs LocalDateTime</category>
            <category>Java Time Package</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Date_and_time_api_44798a47ca.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot @Scheduled Tutorial: Building Scheduled Tasks with TaskScheduler]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-boot-scheduled-tutorial-building-scheduled-tasks-with-task-scheduler</link>
            <guid>https://www.codingshuttle.com/blogs/spring-boot-scheduled-tutorial-building-scheduled-tasks-with-task-scheduler</guid>
            <pubDate>Mon, 08 Sep 2025 05:48:45 GMT</pubDate>
            <description><![CDATA[Learn how to schedule tasks in Spring Boot using the @Scheduled annotation and TaskScheduler. This guide covers fixedRate, fixedDelay, cron expressions, async scheduling with @Async, custom thread pools, and best practices for building efficient scheduled tasks.]]></description>
            <content:encoded><![CDATA[<p>Task scheduling is the process of executing methods or tasks at specified times or intervals, either once or repeatedly, without manual intervention. Spring Boot simplifies this with the <code>@Scheduled</code> annotation and the <code>TaskScheduler.</code></p><p>This enabling developers to automate tasks like logging, notifications, and data processing. This blog explores how to implement scheduled tasks in Spring Boot, including configuration, use cases, and best practices.</p><h2>What is Task Scheduling in Spring Boot?</h2><p>Spring Boot provides built-in support for scheduling through the <code>@Scheduled</code> annotation, which integrates with the <code>TaskScheduler</code> interface. By default, it uses a <code>ScheduledExecutorService</code> under the hood, leveraging a thread pool for task execution. This allows for efficient management of recurring or delayed tasks without manual thread handling.</p><h2>Common Use Cases</h2><ul><li>Logging user activity in a separate thread.</li><li>Sending emails or SMS notifications asynchronously after user actions.</li><li>Processing multiple image uploads, database queries, or API calls in parallel.</li><li>Cleaning up expired database records.</li><li>Archiving logs.</li><li>Fetching data from external APIs regularly.</li><li>Performing regular health checks on external systems or services.</li></ul><h2>Setting Up Scheduled Tasks</h2><h3>Steps to Implement</h3><ol><li><strong>Enable Scheduling</strong>: Add <code>@EnableScheduling</code> to the main application class to activate Spring’s scheduling support.</li><li><strong>Annotate the Method</strong>: Use <code>@Scheduled</code> on the method you want to schedule.</li><li><strong>Method Requirements</strong>: The method must be <code>void</code> and take no arguments.</li></ol><h3>Example Configuration</h3><pre><code class="language-java">import org.springframework.boot.SpringApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@Component
class ScheduledTasks {
    @Scheduled(fixedRate = 5000) // Runs every 5 seconds
    public void reportCurrentTime() {
        System.out.println("Current time: " + new java.util.Date());
    }
}</code></pre><h2>How @Scheduled Works</h2><p>When a method is annotated with <code>@Scheduled</code>, Spring:</p><ol><li>Registers it as a scheduled task.</li><li>Delegates execution to a <code>TaskScheduler</code> implementation.</li><li>Uses a thread pool (defaulting to <code>ScheduledExecutorService</code>) for concurrent task execution.</li><li>By default, employs a single-threaded executor, running tasks sequentially.</li></ol><h3>Customizing for Concurrency</h3><p>By default, tasks run sequentially. To enable parallel execution, configure a custom <code>TaskScheduler</code> with a thread pool:</p><pre><code class="language-java">import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
public class TaskSchedulingConfig {
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5); // Allows 5 tasks to run concurrently
        scheduler.setThreadNamePrefix("CustomTaskScheduler-"); // Optional: Custom thread name
        scheduler.initialize(); // Initialize the scheduler
        return scheduler;
    }
}</code></pre><h2>Asynchronous Task Scheduling</h2><h3>Blocking Behavior</h3><p>By default, <code>@Scheduled</code> tasks are blocking. For example, if a task takes 5 seconds and is scheduled every 2 seconds, it will only rerun after the previous execution completes. This can lead to delays.</p><h3>Enabling Async Execution</h3><p>To avoid blocking, use the <code>@Async</code> annotation:</p><ol><li>Add <code>@EnableAsync</code> to the main application class.</li><li>Annotate the scheduled method with <code>@Async</code>.</li></ol><p>Example:</p><pre><code class="language-java">import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@EnableAsync
@Component
class ScheduledTasks {
    @Scheduled(fixedRate = 2000) // Every 2 seconds
    @Async
    public void asyncTask() {
        try {
            Thread.sleep(5000); // Simulates a 5-second task
            System.out.println("Async task completed at: " + new java.util.Date());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}</code></pre><p><strong>Note</strong>: <code>@Async</code> is ignored if the method is called within the same class due to Spring’s proxy mechanism. Move the method to a separate class or use a proxy instance.</p><h3>Benefits of @Async</h3><ul><li>Frees the main thread for other operations by offloading time-consuming tasks to a new thread.</li><li>Improves responsiveness in applications with heavy scheduled workloads.</li></ul><h2>Best Practices</h2><ul><li><strong>Configure Thread Pool Size</strong>: Adjust <code>poolSize</code> based on the number of concurrent tasks to optimize performance.</li><li><strong>Handle Exceptions</strong>: Wrap task logic in try-catch blocks to prevent crashes.</li><li><strong>Use Appropriate Scheduling Types</strong>: Choose <code>fixedRate</code>, <code>fixedDelay</code>, or <code>cron</code> based on needs (e.g., <code>fixedRate</code> for regular intervals, <code>cron</code> for complex schedules).</li><li><strong>Test Scheduling</strong>: Verify task timing and concurrency in a non-production environment.</li></ul><h2>Conclusion</h2><p>Spring Boot’s <code>@Scheduled</code> annotation, combined with <code>TaskScheduler</code> and <code>@Async</code>, provides a flexible and powerful way to implement scheduled tasks. Whether you need to log activities, send notifications, or perform health checks, this framework simplifies the process.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot Scheduled Tasks</category>
            <category>Spring Boot @Scheduled</category>
            <category>Spring Boot TaskScheduler Configuration</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Scheduled_1ecb81df62.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Java Executor Framework Tutorial: Simplifying Multithreading with ExecutorService]]></title>
            <link>https://www.codingshuttle.com/blogs/java-executor-framework-tutorial-simplifying-multithreading-with-executor-service</link>
            <guid>https://www.codingshuttle.com/blogs/java-executor-framework-tutorial-simplifying-multithreading-with-executor-service</guid>
            <pubDate>Mon, 08 Sep 2025 05:46:56 GMT</pubDate>
            <description><![CDATA[Learn how the Java Executor Framework simplifies multithreading with ExecutorService, ThreadPoolExecutor, and ScheduledExecutorService. This guide covers key components and best practices for efficient multithreaded applications.]]></description>
            <content:encoded><![CDATA[<p>In Java, Managing threads manually can be a complex task because it involves thread creation, synchronization and also thread lifecycle management. to simplifying the Java Executor Framework, part of the <code>java.util.concurrent</code> package, provides a robust solution to handle these complexities with ease.</p><p>It abstracts thread management and allows developers to focus on task execution. So in this blog we explores the Executor Framework, its components, and practical usage with examples.</p><h2>What is the Executor Framework?</h2><p>The Executor Framework is a high-level API designed to manage threads and execute tasks asynchronously. Instead of directly creating and managing <code>Thread</code> objects, you can use the framework to submit tasks and let it handle the underlying thread pool. At its core, the framework revolves around the <code>Executor</code> interface, with <code>ExecutorService</code> extending it to offer advanced features.</p><h3>Key Components</h3><ul><li><code><strong>Executor</strong></code>: The base interface defining a simple task execution mechanism.</li><li><code><strong>ExecutorService</strong></code>: An extension of <code>Executor</code> that provides methods to manage task submission, shutdown, and thread pools.</li><li><code><strong>ThreadPoolExecutor</strong></code>: A concrete implementation that manages a pool of threads, configurable with core and maximum pool sizes.</li><li><code><strong>ScheduledExecutorService</strong></code>: A specialized service for scheduling tasks to run after a delay or at fixed intervals.</li><li><code><strong>ForkJoinPool</strong></code>: Optimized for tasks that can be recursively split into smaller subtasks.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/1_9b14244ec7.png" alt="Java Executor Components" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_1_9b14244ec7.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_1_9b14244ec7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_1_9b14244ec7.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_1_9b14244ec7.png 1000w," sizes="100vw"><figcaption>Java Executor Components</figcaption></figure><h2>Why Use the Executor Framework?</h2><ol><li><strong>Simplified Thread Management</strong>: No need to manually create or destroy threads.</li><li><strong>Thread Reuse</strong>: Reduces overhead by reusing threads from a pool.</li><li><strong>Flexible Task Submission</strong>: Supports <code>Runnable</code> and <code>Callable</code> tasks with <code>Future</code> results.</li><li><strong>Controlled Shutdown</strong>: Offers graceful termination with <code>shutdown()</code> and <code>shutdownNow()</code>.</li></ol><h2>How It Works</h2><p>The Executor Framework uses a thread pool to manage tasks. Submitters send tasks to the <code>ExecutorService</code>, which queues them in a task queue (e.g., <code>ArrayBlockingQueue</code> or <code>LinkedBlockingQueue</code>). A pool of threads picks tasks from the queue and executes them. This process is illustrated by the diagram showing task submission, queuing, and execution by threads.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/2_4ec1a97bbb.png" alt="Java Executor Framework Internal Working" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_2_4ec1a97bbb.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_2_4ec1a97bbb.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_2_4ec1a97bbb.png 750w," sizes="100vw"><figcaption>Java Executor Framework Internal Working</figcaption></figure><h3>Configuring a ThreadPoolExecutor</h3><p>A <code>ThreadPoolExecutor</code> can be customized with parameters:</p><ul><li><strong>Core Pool Size</strong>: Minimum number of threads kept alive (e.g., 4).</li><li><strong>Maximum Pool Size</strong>: Maximum number of threads that can be created (e.g., 7).</li><li><strong>Keep Alive Time</strong>: Idle time after which extra threads are terminated (e.g., 2 seconds).</li><li><strong>Task Queue</strong>: A queue to hold pending tasks (e.g., <code>LinkedBlockingQueue</code>).</li></ul><p>Example configuration:</p><pre><code class="language-java">ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
    4,      // corePoolSize
    7,      // maximumPoolSize
    2,      // keepAliveTime (seconds)
    TimeUnit.SECONDS,
    new LinkedBlockingQueue&lt;&gt;()
);</code></pre><h2>Submitting Tasks</h2><p>Tasks can be submitted in two main ways:</p><ul><li><code><strong>execute(Runnable)</strong></code>: Fire-and-forget execution, suitable for tasks without return values.</li><li><code><strong>submit(Runnable/Callable)</strong></code>: Returns a <code>Future</code> object to track task completion or retrieve results.</li></ul><h3>Example: Submitting a Runnable Task</h3><pre><code class="language-java">threadPoolExecutor.submit(new Runnable() {
    @Override
    public void run() {
        System.out.println("Task 1(4Seconds) Started by Thread Name : " + Thread.currentThread().getName());
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("Task 1(4Seconds) Ended by Thread Name : " + Thread.currentThread().getName());
    }
});
</code></pre><p>This code submits a task that sleeps for 4 seconds, printing the thread name before and after.</p><h2>Shutting Down the Executor</h2><p>To terminate the thread pool gracefully:</p><ul><li><code><strong>shutdown()</strong></code>: Initiates a shutdown, completing ongoing tasks but not accepting new ones.</li><li><code><strong>shutdownNow()</strong></code>: Attempts to stop all tasks immediately, interrupting active threads.</li></ul><p>Example:</p><pre><code class="language-java">threadPoolExecutor.shutdown();</code></pre><h2>Best Practices</h2><ul><li><strong>Configure Pool Size Wisely</strong>: Match core and maximum sizes to your workload to avoid resource exhaustion.</li><li><strong>Handle Exceptions</strong>: Use <code>Future.get()</code> with try-catch to handle task exceptions.</li><li><strong>Avoid Overloading</strong>: Use bounded queues to prevent task queue overflow.</li><li><strong>Shutdown Properly</strong>: Always call <code>shutdown()</code> to release resources.</li></ul><h2>Conclusion</h2><p>The Java Executor Framework is a powerful tool for managing multithreading efficiently. By leveraging <code>ExecutorService</code> and <code>ThreadPoolExecutor</code>, you can simplify task execution, improve performance with thread reuse, and ensure controlled shutdowns.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java Executor Framework</category>
            <category>ExecutorService In Java</category>
            <category>Java ThreadPoolExecutor</category>
            <category>Multi Threading In Java</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Java_Executor_Framework_69edea45b9.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 10 Spring Boot Projects To Destroy The Competition]]></title>
            <link>https://www.codingshuttle.com/blogs/top-10-spring-boot-projects-to-destroy-the-competition</link>
            <guid>https://www.codingshuttle.com/blogs/top-10-spring-boot-projects-to-destroy-the-competition</guid>
            <pubDate>Fri, 22 Aug 2025 14:13:03 GMT</pubDate>
            <description><![CDATA[In this blog, we'll dive into a curated list of Spring Boot projects tailored for different experience levels: beginners, college students (medium-level), and working professionals (advanced).]]></description>
            <content:encoded><![CDATA[<p>If you want to stand out in today’s competitive job market, small CRUD apps or basic clones won’t cut it anymore. Recruiters can instantly spot projects that were built with one or two AI prompts on Lovabale or Bolt. If you really wish to <strong>destroy the competition</strong>, you need to build <strong>big projects that solve real problems</strong>, designed as if they could be deployed at a startup level. Think beyond “just projects”—focus on building <strong>products</strong> that demonstrate mastery of <strong>Spring Boot</strong> and integration with a full industry-ready tech stack.</p><p>If you feel like you already know these concepts but are unsure about which project to build and how to approach it, you’ve come to the right place. In this blog, I’ve shared 10 backend project ideas to help you decide which one to start with. I recommend building at least one intermediate project and one advanced project to make your resume stand out.</p><h2>Beginner-Level Projects Tech-stack:</h2><figure class="table"><table><thead><tr><th>Component</th><th>Tech/Tools</th></tr></thead><tbody><tr><td><strong>Database &amp; Persistence</strong></td><td>Spring Data JPA, Hibernate JPQL, Query Hints, Indexes</td></tr><tr><td><strong>Transactions</strong></td><td><code>@Transactional</code>, Optimistic &amp; Pessimistic Locking</td></tr><tr><td><strong>Security &amp; Auth</strong></td><td>Spring Security, JWT, OAuth2 Role-Based Access Control</td></tr><tr><td><strong>API Design</strong></td><td>CRUD APIs, Pagination &amp; Sorting (<code>Pageable</code>), Validation (<code>@Valid</code>), Auditing</td></tr><tr><td><strong>Testing &amp; Quality</strong></td><td>JUnit 5, Mockito, Spring Boot Test Aim for 85%+ coverage</td></tr><tr><td><strong>Logging &amp; Monitoring</strong></td><td>SLF4J, Logback</td></tr><tr><td><strong>Deployment &amp; Cloud Basics</strong></td><td>File Uploads (AWS S3, GCP Storage) Deploy on AWS EC2/Elastic Beanstalk Intro to Docker &amp; CI/CD</td></tr></tbody></table></figure><h2>Project 1: Blog Management System</h2><p><strong>Level:</strong> Beginner</p><p>Create a simple blogging platform where users can create, read, update, and delete blog posts. Include user authentication for posting and commenting.</p><p><strong>What You Will Learn</strong>: Fundamentals of RESTful APIs, database persistence with JPA, basic authentication, and API documentation. You'll understand how to structure a monolithic application and handle data validation.</p><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Database ORM</td><td>Spring Data JPA</td><td>Simplifies database interactions by providing repository interfaces, reducing boilerplate code for CRUD operations.</td></tr><tr><td>API Documentation</td><td>Swagger UI</td><td>Automatically generates interactive API docs, making it easier for developers (and recruiters) to test and understand your endpoints.</td></tr><tr><td>Security</td><td>Spring Security</td><td>Handles authentication and authorization, teaching secure practices essential for any web app to prevent unauthorized access.</td></tr></tbody></table></figure><p><strong>Key Project Features</strong>:</p><ul><li>User registration and login.</li><li>CRUD operations for blog posts and comments.</li><li>Role-based access (e.g., admin can delete posts).</li></ul><p><strong>Project Challenges</strong>:</p><ul><li>Managing one-to-many relationships between entities (e.g., posts and comments) in JPA, which can lead to N+1 query problems if not optimized with fetch types.</li><li>Implementing secure password hashing with BCrypt and JWT tokens for stateless authentication, requiring careful handling of token expiration and refresh mechanisms.</li><li>Handling custom exceptions with <code>@ControllerAdvice</code> to provide meaningful error responses without exposing stack traces.</li></ul><blockquote><p>Similar to personal blogs or content management systems like WordPress, where users create and manage content securely.</p></blockquote><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Add email notifications for new comments using Spring Mail.</td><td>Spring Boot Mail Starter, SMTP server (e.g., Gmail).</td><td>Shows initiative in integrating external services, highlighting full-stack potential.</td></tr><tr><td>Deploy to Heroku or AWS with a simple CI/CD pipeline.</td><td>GitHub Actions, Docker.</td><td>Demonstrates deployment knowledge, making you stand out as deployment-ready.</td></tr><tr><td>Implement unit tests with JUnit and Mockito.</td><td>JUnit 5, Mockito, Spring Boot Test.</td><td>Proves testing skills, a key requirement in professional environments.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Developed a secure Blog Management System using Spring Boot, handling 500+ simulated daily posts with 99% uptime; integrated Spring Data JPA and Swagger UI for efficient CRUD and API docs, reducing development time by 30%.</li><li>Implemented role-based authentication with Spring Security and JWT, supporting 1,000 concurrent users; added email notifications via Spring Mail, enhancing user engagement by 40% in tests.</li><li>Wrote comprehensive unit tests covering 85% code, using JUnit and Mockito, ensuring robust error handling and impressing with production-ready code quality.</li></ul><h2>Project 2: Student Management System</h2><p><strong>Level:</strong> Beginner</p><p>Build an application to manage student records, including enrollment, grades, and courses.</p><p><strong>What You Will Learn</strong>: Entity mapping, query optimization with JPA, and basic API design patterns.</p><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Database ORM</td><td>Spring Data JPA</td><td>Enables efficient querying and pagination for large datasets like student lists.</td></tr><tr><td>API Documentation</td><td>Swagger UI</td><td>Provides a user-friendly interface to explore APIs, useful for educational demos.</td></tr><tr><td>Security</td><td>Spring Security</td><td>Secures sensitive data like grades, teaching role-based access control (e.g., teacher vs. student).</td></tr></tbody></table></figure><p><strong>Key Project Features</strong>:</p><ul><li>CRUD for students, courses, and enrollments.</li><li>Search functionality by name or ID.</li><li>Basic reporting (e.g., average grades).</li></ul><p><strong>Project Challenges</strong>:</p><ul><li>Handling many-to-many relationships (students to courses) with JPA's <code>@ManyToMany</code> annotation, avoiding duplicate entries and optimizing joins to prevent performance bottlenecks.</li><li>Ensuring data integrity during updates using <code>@Transactional</code> annotations and optimistic locking with <code>@Version</code> to handle concurrent modifications.</li><li>Debugging JPA lazy loading issues with Hibernate's fetch strategies, which can cause <code>LazyInitializationException</code> If not managed in service layers.</li></ul><blockquote><p>Used in educational institutions for tracking student progress, similar to university portals.</p></blockquote><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Integrate with a frontend like React or Angular</td><td>React JS, Angular</td><td>Shows ability to build end-to-end applications, appealing to full-stack roles.</td></tr><tr><td>Add file uploads for student photos using Spring Multipart.</td><td>Spring Web MultipartFile, AWS S3 (optional).</td><td>Demonstrates handling binary data, a common real-world feature.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Engineered a Student Management System in Spring Boot, managing 10,000+ records with pagination; leveraged Spring Data JPA and Swagger for optimized queries, cutting load times by 50%.</li><li>Secured sensitive data with Spring Security's role-based access, handling 500 users; incorporated file uploads via Multipart, boosting data richness and user interaction.</li><li>Applied Lombok for cleaner code, achieving 90% reduction in boilerplate; tested with JUnit, ensuring scalability and reliability for educational platforms.</li></ul><h2>Project 3: Hospital Management System</h2><p><strong>Level:</strong> Beginner</p><p>Develop a system to manage patient records, appointments, and doctor schedules.</p><p><strong>What You Will Learn</strong>: Transactional operations, validation, and integrating multiple entities.</p><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Database ORM</td><td>Spring Data JPA</td><td>Manages complex entities like patients and appointments with ease.</td></tr><tr><td>API Documentation</td><td>Swagger UI</td><td>Allows quick testing of health-related APIs in a demo.</td></tr><tr><td>Security</td><td>Spring Security</td><td>Protects sensitive health data, complying with privacy standards.</td></tr></tbody></table></figure><p><strong>Key Project Features</strong>:</p><ul><li>Appointment booking and cancellation.</li><li>Patient history tracking.</li><li>Doctor availability checks.</li></ul><p><strong>Project Challenges</strong>:</p><ul><li>Ensuring atomic transactions for bookings using Spring's <code>@Transactional</code> with propagation levels, rolling back on exceptions.</li><li>Validating input data (e.g., dates with <code>@Valid</code> and custom validators) to prevent invalid states, integrating with Bean Validation API for constraints like <code>@Future</code>.</li><li>Scaling for multiple users by implementing pessimistic locking in JPA queries to avoid overbooking scenarios in high-concurrency environments.</li></ul><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Add SMS notifications via Twilio API.</td><td>Twilio SDK, Spring Integration.</td><td>Integrates third-party services, showing real-world integration skills.</td></tr><tr><td>Implement pagination and sorting in queries.</td><td>Spring Data Pageable, Criteria API.</td><td>Optimizes performance, key for data-heavy apps.</td></tr><tr><td>Use Docker for containerization.</td><td>Docker Compose, Dockerfile.</td><td>Introduces DevOps basics, highly valued in modern teams.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Built a Hospital Management System with Spring Boot, processing 1,000+ appointments daily; utilised Spring Data JPA and Swagger for seamless data handling, improving query efficiency by 40%.</li><li>Enforced data privacy with Spring Security and transactional integrity, supporting 200 concurrent sessions; added SMS alerts via Twilio, enhancing patient satisfaction scores.</li><li>Containerized app with Docker, enabling easy deployment; achieved 95% test coverage with JUnit.</li></ul><hr><h2>Intermediate Level Projects Tech-stack:</h2><figure class="table"><table><thead><tr><th>Component</th><th>Tech/Tools</th></tr></thead><tbody><tr><td><strong>System Design &amp; Architecture</strong></td><td>Dynamic Pricing Engine (Strategy Pattern) Matchmaking System (OOP + Design Patterns)</td></tr><tr><td><strong>Database &amp; Caching</strong></td><td>Redis, Caffeine for faster retrieval</td></tr><tr><td><strong>Scheduling &amp; Jobs</strong></td><td>Spring Scheduler, Quartz for Cron Jobs &amp; Background Tasks</td></tr><tr><td><strong>Third-Party Integrations</strong></td><td>Weather API, Currency API, Stripe/PayPal, Maps API, Invoicing &amp; Logging APIs</td></tr><tr><td><strong>Resilience &amp; Error Handling</strong></td><td>Resilience4j, Hystrix (legacy) Retry, Circuit Breakers, Timeouts</td></tr><tr><td><strong>Testing &amp; Load Simulation</strong></td><td>Apache JMeter, Loader.io, k6 Metrics with Prometheus + Grafana</td></tr><tr><td><strong>Deployment &amp; Containers</strong></td><td>Docker, Docker Compose Deploy on AWS ECS, GCP Cloud Run</td></tr></tbody></table></figure><h2>Project 4: Zomato Clone (Food Delivery App)</h2><p><strong>Level:</strong> Intermediate</p><p>Replicate a food ordering system with restaurant listings, orders, and admin controls.</p><p><strong>What You Will Learn</strong>: Caching for performance, transaction management for orders, design patterns (e.g., Singleton for configs), logging/auditing, cron jobs for promotions, and payment integration.</p><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Caching</td><td>Redis/Spring Cache</td><td>Reduces database hits for frequent queries like menu items, improving response times.</td></tr><tr><td>Transactions</td><td>Spring Transaction Management</td><td>Ensures atomicity in order placements and payments.</td></tr><tr><td>Logging/Auditing</td><td>SLF4J with Logback</td><td>Tracks user actions for debugging and compliance.</td></tr><tr><td>Scheduling</td><td>Spring Scheduler</td><td>Automates tasks like daily reports or expirations.</td></tr><tr><td>Payments</td><td>Stripe API</td><td>Handles secure payments, a critical e-commerce feature.</td></tr></tbody></table></figure><p><strong>Key Project Features</strong>:</p><ul><li>User/restaurant/admin APIs.</li><li>Order tracking with real-time updates.</li><li>Promo code application via cron.</li></ul><p><strong>Project Challenges</strong>:</p><ul><li>Managing concurrent orders with Redis distributed locks to prevent race conditions in inventory updates.</li><li>Integrating external payment gateways like Stripe, handling webhooks for asynchronous callbacks and idempotency keys for retry safety.</li></ul><blockquote><p>Food delivery platforms handling high-volume orders daily.</p></blockquote><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Add geolocation with Google Maps API.</td><td>Google Maps SDK, Spring WebClient.</td><td>Enhances realism, showing spatial data skills.</td></tr><tr><td>Implement rate limiting with Spring.</td><td>Spring Boot Bucket4j, Redis.</td><td>Prevents abuse, demonstrating security awareness.</td></tr><tr><td>Use Elasticsearch for search.</td><td>Elasticsearch Starter, Spring Data Elasticsearch.</td><td>Optimizes queries, key for scalable apps.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Created Zomato Clone using Spring Boot, processing 5,000+ orders/hour in simulations; integrated Redis caching and Stripe payments, slashing response times by 60%.</li><li>Applied design patterns and Spring Scheduler for automated promotions; added geolocation via Google Maps, improving delivery accuracy in tests.</li><li>Ensured logging with SLF4J and rate limiting, handling 1,000 users; achieved 80% faster searches with Elasticsearch, showcasing scalable e-commerce expertise.</li></ul><h2>Project 5: Uber Clone (Ride-Sharing App)</h2><p><strong>Level:</strong> Intermediate</p><p>Create a ride-booking system with driver matching, fares, and admin dashboards.</p><p><strong>What You Will Learn</strong>: System design patterns (e.g., Observer for notifications), architectural patterns like layered architecture, caching for locations, and transactions for bookings.</p><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Caching</td><td>Redis</td><td>Caches driver locations for quick matching.</td></tr><tr><td>Transactions</td><td>Spring Transaction Management</td><td>Manages fare calculations and payments atomically.</td></tr><tr><td>Logging/Auditing</td><td>Log4j and Hibernate envers</td><td>Audits ride histories for safety and disputes.</td></tr><tr><td>Scheduling</td><td>Quartz Scheduler</td><td>Schedules maintenance notifications.</td></tr><tr><td>Payments</td><td>PayPal, Stripe, Razorpay API</td><td>Secures transactions in a trust-sensitive app.</td></tr></tbody></table></figure><p><strong>Key Project Features</strong>:</p><ul><li>Real-time ride requests.</li><li>Admin APIs for driver verification.</li><li>Dynamic fare estimation based on factors like distance, time, ratings, etc.</li></ul><p><strong>Project Challenges</strong>:</p><ul><li>Handling geospatial data with PostGIS and spatial queries, optimizing for nearest driver searches.</li><li>Ensuring transaction isolation levels (e.g., <code>SERIALIZABLE</code>) to prevent phantom reads during fare updates in distributed environments.</li><li>Scaling for peak hours by implementing circuit breakers to manage service failures and avoid cascading errors.</li></ul><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Integrate WebSockets for live tracking.</td><td>Spring WebSocket, STOMP.</td><td>Adds real-time capabilities, highly sought after.</td></tr><tr><td>Use circuit breakers with Resilience4j.</td><td>Resilience4j, Spring Cloud.</td><td>Shows fault-tolerance knowledge.</td></tr><tr><td>Add ML for surge pricing simulation.</td><td>Spring AI, TensorFlow Lite.</td><td>Introduces AI, broadening your skill set.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Developed Uber Clone in Spring Boot, matching 2,000+ rides/minute; used Redis for location data and PayPal for secure payments, reducing latency by 45%.</li><li>Implemented Observer pattern and Quartz for notifications; integrated WebSockets for real-time tracking, elevating user experience.</li><li>Added Resilience4j for fault tolerance and ML surge pricing, supporting 500 drivers; impressed with 90% uptime in load tests.</li></ul><h2>Project 6: Airbnb Clone (Vacation Rental App)</h2><p><strong>Level:</strong> Intermediate</p><p>Build a listing platform for properties, bookings, and host management.</p><p><strong>What You Will Learn</strong>: Patterns like Factory for object creation, caching for listings, and auditing for bookings.</p><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Caching</td><td>Caffeine, Redis</td><td>Speeds up property searches.</td></tr><tr><td>Transactions</td><td>Spring Transaction Management</td><td>Handles booking conflicts.</td></tr><tr><td>Logging/Auditing</td><td>SLF4J and Hibernate envers</td><td>Logs user interactions for reviews.</td></tr><tr><td>Scheduling</td><td>Spring Task, Schedulers</td><td>Cleans up expired listings.</td></tr><tr><td>Payments</td><td>Stripe</td><td>Processes secure deposits.</td></tr></tbody></table></figure><p><strong>Key Project Features</strong>:</p><ul><li>Property search and booking.</li><li>Host admin panels.</li><li>Review system.</li></ul><p><strong>Project Challenges</strong>:</p><ul><li>Syncing calendars for availability using <code>iCalendar</code> format or custom cron jobs, preventing double bookings with optimistic concurrency control.</li><li>Managing multi-currency payments with exchange rate APIs, ensuring precision with BigDecimal to avoid floating-point errors.</li><li>Maintaining data consistency across users via distributed caching invalidation strategies.</li></ul><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Add image uploads with AWS S3.</td><td>AWS SDK, Spring Cloud AWS.</td><td>Handles cloud storage, modern tech stack.</td></tr><tr><td>Implement i18n for multi-language.</td><td>Spring Messages, ResourceBundle.</td><td>Shows global app design.</td></tr><tr><td>Use GraphQL for flexible APIs.</td><td>Spring GraphQL, Apollo.</td><td>Advanced API tech, impressive for mid-level.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Engineered Airbnb Clone with Spring Boot, listing 10,000+ properties; employed Caffeine caching and Stripe for bookings, boosting search speed by 55%.</li><li>Used Factory pattern and Spring Task for maintenance; added AWS S3 image uploads, enriching listings with multimedia.</li><li>Supported i18n and GraphQL for flexible queries, handling global users; achieved 85% faster API responses, highlighting international scalability.</li></ul><h2>Project 7: HDFC Net Banking (Banking Application)</h2><p><strong>Level:</strong> Intermediate</p><p>Develop a basic banking system with accounts, transfers, and admin oversight.</p><p><strong>What You Will Learn</strong>: Secure transactions, auditing for compliance, schedulers for interest calculations.</p><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Caching</td><td>Redis</td><td>Caches account balances for quick access.</td></tr><tr><td>Transactions</td><td>Spring Transaction Management</td><td>Ensures ACID properties in transfers.</td></tr><tr><td>Logging/Auditing</td><td>Logback, Slf4j, Hibernate envers</td><td>Records all financial activities for audits.</td></tr><tr><td>Scheduling</td><td>Cron Jobs in Spring</td><td>Automates monthly statements.</td></tr><tr><td>Payments</td><td>PayPal/Stripe</td><td>Simulates fund transfers securely.</td></tr></tbody></table></figure><p><strong>Key Project Features</strong>:</p><ul><li>Account creation and transfers.</li><li>Transaction history.</li><li>Admin fraud detection.</li></ul><p><strong>Project Challenges</strong>:</p><ul><li>Implementing high-security with encryption (e.g., AES for data at rest) and secure random number generation for tokens.</li><li>Handling decimal precision in monetary values using Money API or BigDecimal, avoiding rounding errors in calculations.</li><li>Ensuring compliance by integrating audit logs with timestamps and immutable records using AspectJ for AOP.</li></ul><blockquote><p>Online banking apps for daily finance management.</p></blockquote><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Add two-factor auth with Spring.</td><td>Spring Security OAuth</td><td>Enhances security, critical for fintech.</td></tr><tr><td>Integrate with external APIs for currency exchange.</td><td>Spring WebClient.</td><td>Shows third-party integrations.</td></tr><tr><td>Use blockchain simulation for ledgers (Just a concept)</td><td>Hyperledger Fabric (simulated), Spring Integration.</td><td>Futuristic touch, stands out in interviews.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Built Banking Application in Spring Boot, managing $1M simulated transactions; utilized Redis caching and Spring Transactions for ACID compliance, minimizing errors to 0.1%.</li><li>Incorporated Logback auditing and cron jobs for statements; added 2FA with Spring Security, strengthening fraud prevention.</li><li>Integrated currency APIs and blockchain sim, supporting multi-currency; delivered 95% audit accuracy, positioning as fintech innovator.</li></ul><hr><h2>Advanced Level Projects Tech-stack:</h2><figure class="table"><table><thead><tr><th>Component</th><th>Tech/Tools</th></tr></thead><tbody><tr><td><strong>Microservices Architecture</strong></td><td>Spring Boot + Spring Cloud (Eureka, Config Server, API Gateway) Authentication Service (Keycloak, OAuth2.0, JWT) Notification &amp; Media Management Services</td></tr><tr><td><strong>Polyglot Persistence</strong></td><td>PostgreSQL/MySQL (ACID) DynamoDB/Cassandra (scaling) Redis Cluster (distributed caching) Elasticsearch (search &amp; aggregation) PostGIS/MongoDB Atlas (geospatial queries) Neo4j (graph DB) Pinecone/Weaviate/Milvus (vector DB for ML)</td></tr><tr><td><strong>Messaging &amp; Events</strong></td><td>Kafka, RabbitMQ Event Sourcing &amp; CQRS Handling surge traffic</td></tr><tr><td><strong>Distributed Transactions</strong></td><td>Saga Pattern, Two-Phase Commit, Idempotency</td></tr><tr><td><strong>Inter-Service Communication</strong></td><td>REST (Feign) gRPC WebSockets Kafka Messaging (async)</td></tr><tr><td><strong>Observability &amp; Monitoring</strong></td><td>Zipkin, Jaeger (tracing) Prometheus + Grafana (metrics) ELK Stack (logging) Correlation IDs</td></tr><tr><td><strong>Deployment &amp; Cloud-Native</strong></td><td>Kubernetes, Helm, Jenkins/GitHub Actions (CI/CD) AWS Lambda, Cloud Functions (serverless) Terraform, CloudFormation (IaC)</td></tr><tr><td><strong>Security &amp; Compliance</strong></td><td>Secrets Management (Vault, AWS Secrets Manager) GDPR/PCI compliance</td></tr><tr><td><strong>Scalability &amp; Advanced Features</strong></td><td>Sharding &amp; Replication Multi-Tenancy Architecture (SaaS) AI/ML Integration via REST/gRPC API Gateway with Rate Limiting &amp; Throttling</td></tr></tbody></table></figure><h2>Project 8: BookMyShow Clone (Ticket Booking System)</h2><p>Level: Advanced</p><p>Build a microservices architecture for movie/event ticketing, with services for users, bookings, payments, and notifications.</p><p><strong>What You Will Learn</strong>: Microservices design, Kubernetes deployment, Kafka for messaging, observability with Prometheus/Grafana, logging (ELK stack), auditing, and inter-service communication via REST/gRPC.</p><p><strong>Key Project Features</strong>:</p><ul><li>Scalable services handling millions of users.</li><li>Real-time seat locking with Kafka.</li><li>Distributed transactions.</li><li>Observability dashboards.</li></ul><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Orchestration</td><td>Kubernetes</td><td>Automates deployment and scaling for high availability.</td></tr><tr><td>Messaging</td><td>Kafka</td><td>Enables asynchronous communication for notifications and events.</td></tr><tr><td>Observability</td><td>Prometheus + Grafana</td><td>Monitors metrics and alerts for proactive issue resolution.</td></tr><tr><td>Logging/Auditing</td><td>ELK Stack (Elasticsearch, Logstash, Kibana)</td><td>Centralizes logs for debugging across services.</td></tr><tr><td>Inter-Service</td><td>Spring Cloud Gateway</td><td>Routes and secures communication between microservices.</td></tr></tbody></table></figure><p><strong>Project Challenges</strong>:</p><ul><li>Scaling to billions of transactions by configuring Kafka partitions and consumer groups for high throughput, avoiding bottlenecks in topic replication.</li><li>Managing service discovery in Kubernetes with tools like Consul or Eureka, handling pod evictions and rolling updates without service interruption.</li><li>Achieving eventual consistency in distributed systems using the Saga pattern or 2PC, mitigating failures with compensating transactions.</li></ul><blockquote><p>High-traffic ticketing platforms during peak events like concerts, This level of project shows your backend prowess.</p></blockquote><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Implement CI/CD with Jenkins on Kubernetes.</td><td>Jenkins, Helm Charts.</td><td>Shows DevOps expertise, essential for senior roles.</td></tr><tr><td>Add AI for recommendation engines.</td><td>Spring AI, Apache Mahout.</td><td>Combines backend with ML, highly impressive.</td></tr><tr><td>Simulate load testing with JMeter.</td><td>Apache JMeter, Locust.</td><td>Proves scalability claims with data.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Architected BookMyShow Clone as microservices in Spring Boot, scaling to 1M users and 1B transactions; deployed on Kubernetes with Kafka messaging, achieving 99.9% availability.</li><li>Integrated Prometheus/Grafana for observability and ELK for logging; added CI/CD via Jenkins, accelerating deployments by 70%.</li><li>Implemented AI recommendations and JMeter testing; reduced latency by 50%, demonstrating enterprise-grade resilience.</li></ul><h2>Project 9: Telegram Clone (WebSockets Chat Application)</h2><p>Develop a real-time chat app as microservices, with user auth, messaging, and group chats, deployed on Kubernetes.</p><p><strong>What You Will Learn</strong>: WebSockets for real-time, Kafka for message queuing, observability, logging, and inter-service sync.</p><p><strong>Key Project Features</strong>:</p><ul><li>Scalable to millions of concurrent users.</li><li>Message persistence and delivery guarantees.</li><li>Monitoring for chat latency.</li><li>Audit user interactions.</li></ul><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Orchestration</td><td>Kubernetes</td><td>Manages WebSocket pods for horizontal scaling.</td></tr><tr><td>Messaging</td><td>Kafka</td><td>Buffers and distributes messages reliably.</td></tr><tr><td>Observability</td><td>Micrometer + Prometheus</td><td>Tracks connection metrics.</td></tr><tr><td>Logging/Auditing</td><td>ELK, Hibernate Envers</td><td>Logs chat histories securely.</td></tr><tr><td>Inter-Service</td><td>WebSockets with STOMP</td><td>Enables bidirectional real-time communication.</td></tr></tbody></table></figure><p><strong>Project Challenges</strong>:</p><ul><li>Handling WebSocket connections at scale by configuring session timeouts and heartbeat pings to detect disconnections.</li><li>Partitioning Kafka topics efficiently for group chats, balancing load across brokers to maintain low latency.</li><li>Ensuring data privacy with end-to-end encryption using libs like Bouncy Castle, complying with GDPR-like standards.</li></ul><blockquote><p>Messaging apps like Slack for team communication.</p></blockquote><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Add end-to-end encryption.</td><td>Bouncy Castle, Spring Security.</td><td>Security focus, vital for privacy apps.</td></tr><tr><td>Integrate with push notifications (FCM).</td><td>Firebase SDK, Spring Integration.</td><td>Enhances user experience.</td></tr><tr><td>Use serverless functions for bots.</td><td>AWS Lambda, Spring Cloud Function.</td><td>Modern architecture blend.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Built a WebSockets Chat App in Spring Boot microservices, supporting 1M users; integrated Kafka and Kubernetes for real-time messaging, with 99% delivery rate.</li><li>Added Micrometer/Prometheus monitoring and ELK logging; implemented E2E encryption, prioritizing data privacy.</li><li>Incorporated FCM notifications and serverless bots; reduced latency by 40%, highlighting scalable communication tech.</li></ul><h2>Project 10: Social Media App like LinkedIn</h2><p><strong>Level:</strong> Advanced</p><p>Build a professional networking platform with microservices for profiles, posts, connections, and jobs.</p><p><strong>What You Will Learn</strong>: Scaling for billions of interactions, Kafka for feeds, Kubernetes deployment, full observability stack.</p><p><strong>Key Project Features</strong>:</p><ul><li>Feed generation with Kafka streams.</li><li>Inter-service calls for recommendations.</li><li>Logging all user actions.</li><li>Handle a massive user base.</li></ul><figure class="table"><table><thead><tr><th>Component</th><th>Tool</th><th>Why It Matters</th></tr></thead><tbody><tr><td>Orchestration</td><td>Kubernetes</td><td>Orchestrates services for global users.</td></tr><tr><td>Messaging</td><td>Kafka</td><td>Processes post events and notifications.</td></tr><tr><td>Observability</td><td>Zipkin for tracing</td><td>Visualizes service interactions.</td></tr><tr><td>Logging/Auditing</td><td>ELK Stack</td><td>Audits for content moderation.</td></tr><tr><td>Inter-Service</td><td>Spring Cloud Feign</td><td>Simplifies client-side calls.</td></tr></tbody></table></figure><p><strong>Project Challenges</strong>:</p><ul><li>Personalizing feeds at scale using Kafka Streams for real-time processing, managing state stores for user preferences.</li><li>Managing graph data for connections with eventual consistency, using CRDTs or distributed graphs to resolve conflicts.</li><li>Implementing distributed caching with Redis clusters to handle cache invalidation across microservices.</li></ul><figure class="table"><table><thead><tr><th>Extra Mile</th><th>Tool and Tech</th><th>Impact on Recruiters</th></tr></thead><tbody><tr><td>Add graph DB like Neo4j for connections.</td><td>Neo4j Driver, Spring Data Neo4j.</td><td>Handles complex relationships efficiently.</td></tr><tr><td>Implement content moderation with AI.</td><td>Spring AI, Hugging Face models.</td><td>Addresses real-world challenges.</td></tr><tr><td>Deploy on multi-cloud (AWS + GCP).</td><td>Terraform, Kubernetes Federation.</td><td>Shows cloud-agnostic skills.</td></tr></tbody></table></figure><p><strong>Add in Resume</strong>:</p><ul><li>Created LinkedIn-like Social App with Spring Boot microservices, for 10M users and 1B interactions; used Kafka Streams and Kubernetes, optimizing feeds by 65%.</li><li>Integrated Zipkin tracing and ELK auditing; added Neo4j for connections, enabling efficient networking graphs.</li><li>Applied AI moderation and multi-cloud deploy; improved engagement by 50%, proving enterprise social platform mastery.</li></ul><p>By completing these projects, you'll not only master Spring Boot but also gain insights into real-world development. Tailor them to your resume, host on GitHub, and explain your choices in interviews.</p><hr><h2>Tech Stack Summary:</h2><figure class="table"><table><thead><tr><th>Component</th><th>Beginner Level</th><th>Intermediate Level</th><th>Advanced Level</th></tr></thead><tbody><tr><td><strong>Database &amp; Persistence</strong></td><td>Relational DB Mappings (Spring Data JPA, Hibernate) Query Optimization (JPQL, Indexes)</td><td>Caching with Redis/Caffeine Dynamic Pricing with DB-driven rules</td><td>Polyglot Persistence: Postgres (ACID), DynamoDB/Cassandra (scaling), Redis Cluster (distributed caching), Elasticsearch (search), PostGIS (geospatial), Neo4j (graph), Vector DB (ML)</td></tr><tr><td><strong>Transactions</strong></td><td><code>@Transactional</code> Optimistic &amp; Pessimistic Locking</td><td>Handling concurrent transactions in pricing &amp; booking systems</td><td>Distributed Transactions (Saga, Two-Phase Commit, Idempotency)</td></tr><tr><td><strong>Security &amp; Auth</strong></td><td>Spring Security (JWT, OAuth2) Role-Based Access Control</td><td>API Security for Payments &amp; Third-Party APIs</td><td>Enterprise Auth with OAuth2.0, Keycloak, Secrets Management (Vault, AWS Secrets Manager)</td></tr><tr><td><strong>API &amp; Communication</strong></td><td>CRUD APIs Pagination, Validation, Auditing</td><td>Third-Party Integrations (Weather, Currency, Payments, Maps)</td><td>Inter-Service Communication: REST (Feign), gRPC, WebSockets, Kafka Messaging</td></tr><tr><td><strong>Testing &amp; Quality</strong></td><td>Unit &amp; Integration Tests (JUnit, Mockito) 85%+ coverage</td><td>Load Testing with JMeter/Loader.io, Stress Testing with k6</td><td>Chaos Testing, CI/CD Test Automation (Jenkins, GitHub Actions)</td></tr><tr><td><strong>Scheduling &amp; Jobs</strong></td><td>Basic Scheduling with Spring Scheduler</td><td>Cron Jobs &amp; Background Processing (Quartz)</td><td>Distributed Schedulers in Microservices, Event-Driven Scheduling (Kafka Streams)</td></tr><tr><td><strong>Observability &amp; Logging</strong></td><td>Logging (SLF4J, Logback) Basic Auditing</td><td>Monitoring performance under stress tests with Grafana + Prometheus</td><td>Distributed Tracing (Zipkin, Jaeger), Centralized Logging (ELK Stack), Correlation IDs</td></tr><tr><td><strong>Messaging &amp; Events</strong></td><td>—</td><td>Retry &amp; Resilience with Resilience4j, Circuit Breakers</td><td>Kafka, RabbitMQ for async processing, Event Sourcing &amp; CQRS for large-scale systems</td></tr><tr><td><strong>Deployment &amp; Cloud</strong></td><td>File Uploads to AWS S3/GCP Deploy on AWS EC2/Elastic Beanstalk Intro to Docker</td><td>Docker &amp; Docker Compose Deploy on AWS ECS/GCP Cloud Run</td><td>Kubernetes (K8s), Helm, Serverless (AWS Lambda, Cloud Functions) Infra as Code (Terraform)</td></tr><tr><td><strong>Architecture &amp; Design</strong></td><td>Basic CRUD Architecture</td><td>Matchmaking Systems (OOP + Design Patterns)</td><td>Microservices Ecosystem (Auth, Config, Gateway, Notifications, Domain Services) DDD + Multi-Tenancy Sharding, SaaS Architecture</td></tr><tr><td><strong>Advanced Features</strong></td><td>—</td><td>—</td><td>AI/ML Integration (TensorFlow Serving, PyTorch + gRPC) Vector DBs for semantic search Rate Limiting &amp; Throttling (API Gateway)</td></tr></tbody></table></figure><p>&nbsp;</p><p>&nbsp;</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>Spring Boot Projects</category>
            <category>Design patterns</category>
            <category>LLD</category>
            <category>System Design</category>
            <category>Kafka</category>
            <category>Microservice</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/FROM_TIER_3_COLLEGE_TO_8_5fd78e108b.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot Caching with Redis: Boost Performance with Fast Operations (2025)]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-boot-caching-with-redis-boost-performance-with-fast-operations-2025-1</link>
            <guid>https://www.codingshuttle.com/blogs/spring-boot-caching-with-redis-boost-performance-with-fast-operations-2025-1</guid>
            <pubDate>Fri, 22 Aug 2025 05:14:01 GMT</pubDate>
            <description><![CDATA[Learn how to integrate Redis caching in Spring Boot with step-by-step setup, configuration, and CRUD examples. This guide covers @Cacheable, @CachePut, @CacheEvict, and @Caching annotations, Redis setup with Docker, and best practices to speed up your application with in-memory caching in 2025.]]></description>
            <content:encoded><![CDATA[<p>Caching is a powerful technique to enhance the performance of your Spring Boot application by storing frequently accessed data in memory for rapid retrieval. Redis, a high-performance in-memory data store, is an excellent choice for caching due to its speed and scalability.</p><p>In this blog, we’ll explore how to integrate Redis with Spring Boot to implement caching, covering setup, implementation, and key annotations with practical CRUD examples.</p><h2>Why Use Caching with Redis?</h2><ul><li><strong>Performance Boost</strong>: Redis stores data in memory, enabling sub-millisecond access times, reducing database load.</li><li><strong>Scalability</strong>: Supports distributed caching, ideal for high-traffic applications.</li><li><strong>Flexibility</strong>: Offers various data structures (strings, hashes, lists, etc.) for versatile caching strategies.</li><li><strong>Spring Boot Integration</strong>: Seamlessly integrates with Spring Boot via Spring Data Redis and caching abstractions.</li></ul><h2>Spring Boot Cache Providers</h2><p>Spring Boot supports multiple cache providers through its caching abstraction, allowing developers to switch providers with minimal code changes. Common cache providers include:</p><ul><li><strong>EhCache</strong>: A robust, Java-based cache for local caching, suitable for single-node applications.</li><li><strong>Caffeine</strong>: A high-performance, in-memory cache optimized for Java applications.</li><li><strong>Redis</strong>: An in-memory data store used for distributed caching, offering scalability and persistence options.</li><li><strong>HazelCast</strong>: A distributed cache for clustered environments.</li><li><strong>Simple</strong>: Spring’s default in-memory cache for basic use cases.</li></ul><p>In this blog, we focus on Redis due to its speed, scalability, and seamless integration with Spring Boot.</p><h2>What is Redis?</h2><p>Redis (Remote Dictionary Server) is an open-source, in-memory data structure store used as a database, cache, and message broker. Key features include:</p><ul><li><strong>In-Memory Storage</strong>: Stores data in RAM for ultra-fast access.</li><li><strong>Data Structures</strong>: Supports strings, hashes, lists, sets, and more.</li><li><strong>Persistence</strong>: Offers optional disk persistence for data durability.</li><li><strong>Scalability</strong>: Supports replication and clustering for distributed systems.</li><li><strong>Versatility</strong>: Widely used for caching, session management, and real-time analytics.</li></ul><p>Redis is particularly well-suited for caching due to its low-latency data access and ability to handle large-scale, high-throughput workloads.</p><h2>How Does Redis Caching Work?</h2><p>Redis caching in Spring Boot works by storing the results of expensive operations (e.g., database queries) in Redis. When a method annotated with caching annotations is called:</p><ol><li>Spring checks if the result exists in the Redis cache using a unique key.</li><li>If found (cache hit), the cached result is returned, bypassing the method execution.</li><li>If not found (cache miss), the method executes, and the result is stored in Redis for future requests.</li></ol><p>Spring’s caching abstraction simplifies this process with annotations like <code>@Cacheable</code>, <code>@CachePut</code>, and <code>@CacheEvict</code>, which we’ll explore later.</p><h2>Let's Set Up Our Spring Boot Application!</h2><p>Let’s create a Spring Boot application with Redis caching, implementing CRUD operations with all caching annotations.</p><h3>Step 1: Create a Spring Boot Project</h3><p>Use <a href="https://start.spring.io/">Spring Initializr</a> to generate a project with:</p><ul><li>Spring Web</li><li>Spring Data Redis</li><li>Spring Cache</li></ul><p>Add these dependencies to <code>pom.xml</code> (Maven):</p><pre><code class="language-xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-data-redis&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-cache&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;</code></pre><h3>Step 2: Configure Redis</h3><p>Add Redis connection details to <code>application.properties</code>:</p><pre><code class="language-plaintext">spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.cache.type=redis
spring.cache.redis.time-to-live=600000 # Cache TTL in milliseconds (e.g., 10 minutes)</code></pre><p>Start Redis locally or via Docker:</p><pre><code class="language-plaintext">docker run -d -p 6379:6379 redis</code></pre><h3>Step 3: Enable Caching</h3><p>Add <code>@EnableCaching</code> to your main application class to enable Spring’s caching support:</p><pre><code class="language-java">import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class RedisCachingApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisCachingApplication.class, args);
    }
}</code></pre><h3>Step 4: Create a User Model</h3><p>Create a <code>User</code> class to represent the data we’ll cache:</p><pre><code class="language-java">public class User {
    private Long id;
    private String name;
    private String email;

    public User() {}

    public User(Long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}</code></pre><h3>Step 5: Create a User Service with CRUD Operations</h3><p>Create a <code>UserService</code> class with caching annotations for CRUD operations:</p><pre><code class="language-java">import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    private static final String CACHE_NAME = "users";

    @Cacheable(value = CACHE_NAME, key = "#id")
    public User getUserById(Long id) {
        // Simulate slow database query
        try {
            Thread.sleep(2000); // 2-second delay
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return new User(id, "User " + id, "user" + id + "@example.com");
    }

    @CachePut(value = CACHE_NAME, key = "#user.id")
    public User createUser(User user) {
        // Simulate database save
        return new User(user.getId(), user.getName(), user.getEmail());
    }

    @CachePut(value = CACHE_NAME, key = "#id")
    public User updateUser(Long id, User user) {
        // Simulate database update
        return new User(id, user.getName(), user.getEmail());
    }

    @CacheEvict(value = CACHE_NAME, key = "#id")
    public void deleteUser(Long id) {
        // Simulate database deletion
    }
}</code></pre><h3>Step 6: Create a REST Controller</h3><p>Create a <code>UserController</code> to expose CRUD endpoints:</p><pre><code class="language-java">import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public ResponseEntity&lt;User&gt; getUser(@PathVariable Long id) {
        return ResponseEntity.ok(userService.getUserById(id));
    }

    @PostMapping
    public ResponseEntity&lt;User&gt; createUser(@RequestBody User user) {
        return ResponseEntity.ok(userService.createUser(user));
    }

    @PutMapping("/{id}")
    public ResponseEntity&lt;User&gt; updateUser(@PathVariable Long id, @RequestBody User user) {
        return ResponseEntity.ok(userService.updateUser(id, user));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity&lt;Void&gt; deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}</code></pre><h3>Step 7: Test the Application</h3><ol><li>Start the Redis server.</li><li>Run the Spring Boot application.</li><li>Test endpoints using Postman or curl:<ul><li><code>GET &lt;http://localhost:8080/api/users/1</code>:&gt; First call takes ~2 seconds; subsequent calls are instant due to caching.</li><li><code>POST &lt;http://localhost:8080/api/users</code>&gt; (body: <code>{"id": 2, "name": "John", "email": "john@example.com"}</code>): Creates and caches the user.</li><li><code>PUT &lt;http://localhost:8080/api/users/2</code>&gt; (body: <code>{"name": "John Updated", "email": "john.updated@example.com"}</code>): Updates and refreshes the cache.</li><li><code>DELETE &lt;http://localhost:8080/api/users/2</code>:&gt; Removes the user from the cache.</li></ul></li></ol><p>Verify cache contents in Redis CLI:</p><pre><code class="language-plaintext">redis-cli
&gt; KEYS *
&gt; GET users::1</code></pre><h2>Explanation Of Caching Annotations</h2><p>Spring’s caching annotations simplify cache management. Below are the annotations used in the example, along with <code>@Caching</code>:</p><ul><li><strong>@Cacheable</strong>:<ul><li><strong>Purpose</strong>: Caches the result of a method based on its parameters, skipping execution if the result is already cached.</li><li><strong>Usage in Example</strong>: In <code>getUserById</code>, caches the <code>User</code> object with key <code>id</code> in the <code>users</code> cache. Subsequent calls with the same <code>id</code> return the cached result.</li><li><strong>Example</strong>: <code>@Cacheable(value = "users", key = "#id")</code></li></ul></li><li><strong>@CachePut</strong>:<ul><li><strong>Purpose</strong>: Updates the cache with the method’s result, always executing the method to ensure fresh data.</li><li><strong>Usage in Example</strong>: In <code>createUser</code> and <code>updateUser</code>, updates the cache with the new or modified <code>User</code> object.</li><li><strong>Example</strong>: <code>@CachePut(value = "users", key = "#user.id")</code></li></ul></li><li><strong>@CacheEvict</strong>:<ul><li><strong>Purpose</strong>: Removes specific entries from the cache to prevent stale data.</li><li><strong>Usage in Example</strong>: In <code>deleteUser</code>, removes the user with the specified <code>id</code> from the cache.</li><li><strong>Example</strong>: <code>@CacheEvict(value = "users", key = "#id")</code></li></ul></li><li><strong>@Caching</strong>:<ul><li><strong>Purpose</strong>: Groups multiple cache annotations for complex caching logic, allowing multiple cache operations in a single method.</li><li><strong>Usage</strong>: Not used in the example but useful for scenarios requiring combined operations, like updating one cache and evicting another.</li></ul></li></ul><h2>Best Practices for Redis Caching</h2><ul><li><strong>Set Appropriate TTL</strong>: Configure <code>time-to-live</code> (e.g., 10 minutes in the example) to balance performance and data freshness.</li><li><strong>Use Descriptive Cache Names</strong>: Use clear names like <code>users</code> to organize cache entries.</li><li><strong>Handle Cache Misses</strong>: Ensure your application handles scenarios where data isn’t cached gracefully.</li><li><strong>Monitor Redis</strong>: Use tools like RedisInsight to track cache usage and performance.</li><li><strong>Secure Redis</strong>: Enable authentication and TLS for production environments.</li><li><strong>Evict Strategically</strong>: Clear caches when data changes to avoid serving stale data.</li></ul><h2>Testing Cache Performance</h2><p>To verify caching effectiveness:</p><ol><li><strong>Measure Latency</strong>: Use tools like JMeter or curl to compare response times for cached vs. non-cached requests.</li><li><strong>Monitor Cache Hits</strong>: Use Redis commands like <code>INFO STATS</code> to check cache hit/miss ratios.</li><li><strong>Simulate Load</strong>: Test under high load to ensure Redis handles concurrent requests efficiently.</li></ol><p>Example: For the <code>GET /api/users/1</code> endpoint, the first request takes ~2 seconds, while cached requests are near-instant. This demonstrates significant performance improvement.</p><h2>Conclusion</h2><p>Redis caching with Spring Boot significantly enhances application performance by reducing database load and latency. Using annotations like <code>@Cacheable</code>, <code>@CachePut</code>, <code>@CacheEvict</code>, and <code>@Caching</code>, you can implement efficient caching for CRUD operations. Redis’s speed and Spring’s abstraction make this a powerful combination for scalable applications.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot Caching</category>
            <category>Redis Cache Integration In Spring Boot</category>
            <category>Spring Data Redis Tutorial</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/redis_cf14a4c1bc.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot File Upload with Multipart Support: Complete Guide]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-boot-caching-with-redis-boost-performance-with-fast-operations-2025</link>
            <guid>https://www.codingshuttle.com/blogs/spring-boot-caching-with-redis-boost-performance-with-fast-operations-2025</guid>
            <pubDate>Fri, 22 Aug 2025 05:10:50 GMT</pubDate>
            <description><![CDATA[Learn how to implement file uploads in Spring Boot using Multipart support. Includes REST API, service layer, database integration, and AWS S3 example for scalable file storage.]]></description>
            <content:encoded><![CDATA[<p>File uploading is a key feature in many web applications, whether for user profile images, document uploads, or media files. Spring Boot simplifies this process with its robust support for handling multipart file uploads.</p><p>In this blog, we'll explore how to implement file uploads in a Spring Boot application using multipart support, including a REST controller, service layer, and database integration. We'll also discuss different file upload approaches and why multipart is often the preferred method.</p><h2>Different Ways of File Uploading</h2><p>There are several approaches to handle file uploads in Spring Boot, each suited for specific use cases:</p><ol><li><strong>Multipart Form Data</strong>:<ul><li>Uses the MultipartFile interface to handle files sent via HTTP POST requests.</li><li>Ideal for web forms where users upload files alongside other form data (e.g., name, description).</li><li>Example: Uploading a profile picture with metadata like username and file type.</li></ul></li><li><strong>Base64 Encoded Files</strong>:<ul><li>Files are encoded as Base64 strings and sent in the request body (e.g., as JSON).</li><li>Useful for APIs where files are embedded in payloads, but increases payload size due to encoding.</li><li>Drawback: Less efficient for large files due to encoding overhead.</li></ul></li><li><strong>Direct Stream Upload</strong>:<ul><li>Files are streamed directly to a server or storage service (e.g., Amazon S3) without temporary storage.</li><li>Best for large files or high-performance applications.</li><li>Requires integration with external storage services.</li></ul></li><li><strong>Servlet-based Upload</strong>:<ul><li>Uses HttpServletRequest to access raw input streams for file data.</li><li>More manual and less abstracted than MultipartFile, but offers fine-grained control.</li><li>Suitable for custom or legacy applications.</li></ul></li></ol><p>In this blog, we'll focus on the multipart form data approach due to its simplicity and widespread use in web applications.</p><h2>Why Use Multipart?</h2><p>Multipart form data is the go-to choice for file uploads in Spring Boot for several reasons:</p><ul><li><strong>Efficient File Handling</strong>: Spring Boot's MultipartFile interface abstracts the complexity of handling file streams, making it easy to process uploaded files.</li><li><strong>Support for Metadata</strong>: Multipart requests allow sending files alongside additional data (e.g., file name, type, or description) in a single request.</li><li><strong>Browser Compatibility</strong>: HTML forms natively support multipart form data, making it ideal for web applications with file upload forms.</li><li><strong>Scalability</strong>: Multipart uploads can be integrated with cloud storage services like Amazon S3, allowing scalable file storage.</li><li><strong>Built-in Support</strong>: Spring Boot provides out-of-the-box support for multipart uploads via annotations like @ModelAttribute and configuration properties for file size limits.</li></ul><h2><strong>Implementation: File Upload with Multipart Support</strong></h2><h3>1. Add the following dependencies in your pom.xml :</h3><pre><code class="language-xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
        &lt;artifactId&gt;lombok&lt;/artifactId&gt;
        &lt;optional&gt;true&lt;/optional&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;com.h2database&lt;/groupId&gt;
        &lt;artifactId&gt;h2&lt;/artifactId&gt;
        &lt;scope&gt;runtime&lt;/scope&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;</code></pre><h3>2. <strong>Create the File Upload Request Model</strong> :</h3><pre><code class="language-java">@Data
public class FileUploadRequest {
    private String name;
    private String type;
    private MultipartFile image;
}</code></pre><h3>3. <strong>Define the Entity for File Metadata</strong> :</h3><pre><code class="language-java">@Entity
@Data
public class FileUploading {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String type;
    private String imageURL;
}</code></pre><h3>4. <strong>Implement the File Upload Service</strong> :</h3><pre><code class="language-java">@Service
public class FileUploadingService {
    private final FileUploadingRepository fileUploadingRepository;

    public FileUploadingService(FileUploadingRepository fileUploadingRepository) {
        this.fileUploadingRepository = fileUploadingRepository;
    }

    public FileUploading uploadImage(FileUploadRequest fileUploadRequest) {
        MultipartFile image = fileUploadRequest.getImage();
        String fileName = image.getOriginalFilename();
        // Simulate S3 upload (replace with actual S3 logic)
        String imageUrl = "&lt;https://amazon/images/url/&gt;" + fileName;
        FileUploading fileUploading = new FileUploading();
        fileUploading.setName(fileUploadRequest.getName());
        fileUploading.setType(fileUploadRequest.getType());
        fileUploading.setImageURL(imageUrl);
        return fileUploadingRepository.save(fileUploading);
    }
}</code></pre><p>For real S3 integration, use the AWS SDK:</p><pre><code class="language-java">AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();
s3Client.putObject("your-bucket-name", fileName, image.getInputStream(), new ObjectMetadata());
String imageUrl = s3Client.getUrl("your-bucket-name", fileName).toString();</code></pre><h3>5. <strong>Create the REST Controller</strong> ****:</h3><pre><code class="language-java">@RestController
@RequestMapping("/file-uploading")
public class FileUploadingController {
    private final FileUploadingService fileUploadingService;

    public FileUploadingController(FileUploadingService fileUploadingService) {
        this.fileUploadingService = fileUploadingService;
    }

    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public FileUploading uploadImage(@ModelAttribute FileUploadRequest fileUploadRequest) {
        return fileUploadingService.uploadImage(fileUploadRequest);
    }
}</code></pre><h3>6. <strong>Configure File Upload Limits</strong> :</h3><pre><code class="language-plaintext">spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB</code></pre><h3>That’s It</h3><p>Now you can upload files using this api: <code>http://localhost:8080/file-uploading/upload</code></p><h2>Conclusion</h2><p>Multipart file uploads in Spring Boot are efficient, browser-compatible, and easy to implement with MultipartFile and related annotations. By combining this with database storage and cloud services like S3, you can build robust file upload functionality.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot</category>
            <category>File Upload Tutorial</category>
            <category>Spring Boot MultipartFile Example</category>
            <category>File Upload with AWS S3</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/multi_Part_png_5e4302b05f.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Integrating Stripe Payments in Spring Boot: Step-by-Step Beginner’s Guide (2025)]]></title>
            <link>https://www.codingshuttle.com/blogs/integrating-stripe-payments-in-spring-boot-step-by-step-beginner-s-guide-2025</link>
            <guid>https://www.codingshuttle.com/blogs/integrating-stripe-payments-in-spring-boot-step-by-step-beginner-s-guide-2025</guid>
            <pubDate>Fri, 22 Aug 2025 05:07:47 GMT</pubDate>
            <description><![CDATA[Learn how to integrate Stripe payments in Spring Boot with this beginner-friendly guide. Covers setting up Stripe API keys, creating checkout sessions, handling webhooks, and confirming bookings.]]></description>
            <content:encoded><![CDATA[<p>Integrating payment processing into your Spring Boot application can seem daunting, but with Stripe's robust API and Spring Boot's flexibility, it’s a manageable task. In this guide, we'll walk through the process of integrating Stripe payments into a Spring Boot application, focusing on a booking system example. We'll cover setting up Stripe, initiating a payment session, handling webhooks, and confirming payments.</p><h2>Prerequisites</h2><ol><li>A Stripe account with API keys (secret key and webhook secret).</li><li>A Spring Boot project set up with dependencies like <code>spring-boot-starter-web</code> and <code>stripe-java</code>.</li><li>Basic knowledge of Spring Boot, REST APIs, and Java.</li><li>Add the Stripe Java library to your <code>pom.xml</code>:</li></ol><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;com.stripe&lt;/groupId&gt;
    &lt;artifactId&gt;stripe-java&lt;/artifactId&gt;
    &lt;version&gt;25.6.0&lt;/version&gt;
&lt;/dependency&gt;</code></pre><h2>Step 1: Configuring Stripe in Spring Boot</h2><p>To use Stripe's API, you need to set up your Stripe secret key in the application. This key authenticates your API requests.</p><p>In your <code>application.properties</code> or <code>application.yml</code>, add:</p><pre><code class="language-plaintext">stripe.secret.key=sk_test_your_stripe_secret_key
stripe.webhook.secret=whsec_your_webhook_secret</code></pre><p>Create a configuration class to initialize the Stripe API with the secret key:</p><pre><code class="language-java">import com.stripe.Stripe;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class StripeConfig {

    @Value("${stripe.secret.key}")
    private String stripeSecretKey;

    @PostConstruct
    public void init() {
        Stripe.apiKey = stripeSecretKey; // Set up Stripe API key
    }
}</code></pre><p>This ensures the Stripe API key is set when the application starts.</p><h2>Step 2: Initiating a Payment Session</h2><p>To process payments, you’ll create a Stripe Checkout Session, which redirects users to a Stripe-hosted payment page. Below is an example of initiating a payment for a booking.</p><h3>Controller for Initiating Payment</h3><p>Create a REST endpoint to initiate a payment for a booking:</p><pre><code class="language-java">import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/bookings")
public class BookingController {

    private final BookingService bookingService;

    public BookingController(BookingService bookingService) {
        this.bookingService = bookingService;
    }

    @PostMapping("/{bookingId}/payments")
    public ResponseEntity&lt;BookingPaymentInitResponseDto&gt; initiateBookingPayment(@PathVariable Long bookingId) {
        BookingPaymentInitResponseDto response = new BookingPaymentInitResponseDto(bookingService.initiateBookingPayment(bookingId));
        return new ResponseEntity&lt;&gt;(response, HttpStatus.OK);
    }
}</code></pre><p>The <code>BookingPaymentInitResponseDto</code> is a simple data transfer object (DTO) to return the Stripe session URL:</p><pre><code class="language-java">import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class BookingPaymentInitResponseDto {
    private String sessionUrl;
}</code></pre><h3>Service Logic for Payment Initiation</h3><p>In the service layer, validate the booking, check user authorization, and create a Stripe Checkout Session:</p><pre><code class="language-java">import com.stripe.exception.StripeException;
import com.stripe.model.Customer;
import com.stripe.model.Session;
import com.stripe.param.CustomerCreateParams;
import com.stripe.param.SessionCreateParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
public class BookingService {

    private final BookingRepository bookingRepository;
    private final InventoryRepository inventoryRepository;
    private final String frontendUrl;

    public BookingService(BookingRepository bookingRepository, InventoryRepository inventoryRepository, @Value("${frontend.url}") String frontendUrl) {
        this.bookingRepository = bookingRepository;
        this.inventoryRepository = inventoryRepository;
        this.frontendUrl = frontendUrl;
    }

    @Transactional(noRollbackFor = BookingExpiredException.class)
    public String initiateBookingPayment(Long bookingId) {
        Booking booking = bookingRepository.findById(bookingId)
                .orElseThrow(() -&gt; new ResourceNotFoundException("Booking Not Found With Id: " + bookingId));

        User user = getCurrentUser(); // Assume this retrieves the authenticated user

        if (!user.equals(booking.getUser())) {
            throw new UnAuthorisedException("Booking Does Not Belong To This User With Id: " + user.getId());
        }

        if (hasBookingExpired(booking.getCreatedAt())) {
            inventoryRepository.expireBooking(booking.getRoom().getId(),
                    booking.getCheckInDate(),
                    booking.getCheckOutDate(),
                    booking.getNumberOfRooms());
            booking.setBookingStatus(BookingStatus.EXPIRED);
            bookingRepository.save(booking);
            throw new BookingExpiredException("Booking Has Been Already Expired");
        }

        String sessionUrl = getCheckoutSession(booking, frontendUrl + "/payment/success", frontendUrl + "/payment/failure");
        booking.setBookingStatus(BookingStatus.PAYMENT_PENDING);
        bookingRepository.save(booking);

        return sessionUrl;
    }

    public String getCheckoutSession(Booking booking, String successUrl, String failureUrl) {
        log.info("Creating session for booking with Id: {}", booking.getId());
        User user = getCurrentUser();

        try {
            CustomerCreateParams customerParams = CustomerCreateParams.builder()
                    .setName(user.getName())
                    .setEmail(user.getEmail())
                    .build();
            Customer customer = Customer.create(customerParams);

            SessionCreateParams sessionParams = SessionCreateParams.builder()
                    .setMode(SessionCreateParams.Mode.PAYMENT)
                    .setBillingAddressCollection(SessionCreateParams.BillingAddressCollection.REQUIRED)
                    .setCustomer(customer.getId())
                    .setSuccessUrl(successUrl)
                    .setCancelUrl(failureUrl)
                    .addLineItem(
                            SessionCreateParams.LineItem.builder()
                                    .setQuantity(Long.valueOf(booking.getNumberOfRooms()))
                                    .setPriceData(
                                            SessionCreateParams.LineItem.PriceData.builder()
                                                    .setCurrency("inr")
                                                    .setUnitAmount(booking.getAmount().multiply(BigDecimal.valueOf(100)).longValue())
                                                    .setProductData(
                                                            SessionCreateParams.LineItem.PriceData.ProductData.builder()
                                                                    .setName(booking.getHotel().getName() + " : " + booking.getRoom().getType())
                                                                    .setDescription("Booking ID: " + booking.getId())
                                                                    .build()
                                                    )
                                                    .build()
                                    )
                                    .build()
                    )
                    .build();

            Session session = Session.create(sessionParams);
            booking.setPaymentSessionId(session.getId());
            bookingRepository.save(booking);

            log.info("Session created successfully for booking with Id: {}", booking.getId());
            return session.getUrl();
        } catch (StripeException e) {
            throw new RuntimeException("Failed to create Stripe session", e);
        }
    }
}</code></pre><p>This code:</p><ol><li>Validates the booking and user.</li><li>Checks if the booking has expired.</li><li>Creates a Stripe customer and a checkout session with details like the hotel name, room type, and amount (in INR, multiplied by 100 for Stripe’s cent-based system).</li><li>Updates the booking status to <code>PAYMENT_PENDING</code> and saves the session ID.</li></ol><h2>Step 3: Handling Stripe Webhooks</h2><p>Stripe uses webhooks to notify your application of payment events, such as a completed checkout session. Set up a webhook endpoint to handle these events.</p><h3>Webhook Controller</h3><pre><code class="language-java">import com.stripe.exception.SignatureVerificationException;
import com.stripe.model.Event;
import com.stripe.net.Webhook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/webhook")
public class StripeWebhookController {

    private final BookingService bookingService;
    private final String endpointSecret;

    public StripeWebhookController(BookingService bookingService, @Value("${stripe.webhook.secret}") String endpointSecret) {
        this.bookingService = bookingService;
        this.endpointSecret = endpointSecret;
    }

    @PostMapping("/payment")
    public ResponseEntity&lt;Void&gt; capturePayments(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader) {
        try {
            Event event = Webhook.constructEvent(payload, sigHeader, endpointSecret);
            bookingService.capturePayment(event);
            return ResponseEntity.noContent().build();
        } catch (SignatureVerificationException e) {
            throw new RuntimeException("Invalid webhook signature", e);
        }
    }
}</code></pre><h3>Webhook Handling Logic</h3><p>Add the webhook handling logic to the <code>BookingService</code>:</p><pre><code class="language-java">import com.stripe.model.Session;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
public class BookingService {

    // Other methods as above...

    @Transactional
    public void capturePayment(Event event) {
        if ("checkout.session.completed".equals(event.getType())) {
            Session session = (Session) event.getDataObjectDeserializer().getObject().orElse(null);
            if (session == null) return;

            String sessionId = session.getId();
            Booking booking = bookingRepository.findByPaymentSessionId(sessionId)
                    .orElseThrow(() -&gt; new ResourceNotFoundException("Booking not found for session Id: " + sessionId));

            booking.setBookingStatus(BookingStatus.CONFIRMED);
            bookingRepository.save(booking);

            List&lt;Inventory&gt; lockReservedInventory = inventoryRepository.findAndLockReservedInventory(
                    booking.getRoom().getId(),
                    booking.getCheckInDate(),
                    booking.getCheckOutDate(),
                    booking.getNumberOfRooms());

            inventoryRepository.confirmBooking(
                    booking.getRoom().getId(),
                    booking.getCheckInDate(),
                    booking.getCheckOutDate(),
                    booking.getNumberOfRooms());

            log.info("Successfully confirmed the booking for Booking Id: {}", booking.getId());
        } else {
            log.warn("Unhandled event type: {}", event.getType());
        }
    }
}</code></pre><p>This code:</p><ol><li>Verifies the webhook event using the Stripe webhook secret.</li><li>Processes the <code>checkout.session.completed</code> event to confirm the booking.</li><li>Updates the booking status to <code>CONFIRMED</code> and adjusts inventory (e.g., decreases reserved rooms and increases booked rooms).</li></ol><h2>Step 4: Testing the Integration</h2><ol><li><strong>Set Up Webhooks Locally</strong>: Use a tool like <code>ngrok</code> to expose your local server to Stripe’s webhook events. Configure the webhook URL in the Stripe Dashboard (e.g., <code>https://your-ngrok-url/webhook/payment</code>).</li><li><strong>Test Payment Flow</strong>:<ul><li>Create a booking and initiate a payment via the <code>/api/bookings/{bookingId}/payments</code> endpoint.</li><li>Use Stripe’s test card (e.g., <code>4242 4242 4242 4242</code>) to complete the payment.</li><li>Verify that the webhook updates the booking status to <code>CONFIRMED</code>.</li></ul></li><li><strong>Handle Errors</strong>: Test edge cases like expired bookings or invalid payments to ensure proper exception handling.</li></ol><h2>Best Practices</h2><ul><li><strong>Security</strong>: Store Stripe keys securely (e.g., in environment variables) and validate webhook signatures to prevent unauthorized requests.</li><li><strong>Error Handling</strong>: Handle Stripe exceptions gracefully and provide meaningful error messages to users.</li><li><strong>Logging</strong>: Log important events (e.g., session creation, payment confirmation) for debugging and auditing.</li><li><strong>Testing</strong>: Use Stripe’s test mode extensively before going live.</li></ul><h2>Conclusion</h2><p>Integrating Stripe into a Spring Boot application is straightforward with the right setup. By following this guide, you can enable secure payment processing for your application, handle payment confirmations via webhooks, and manage booking statuses effectively.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>Stripe</category>
            <category>Payment integration</category>
            <category>Stripe Integration With Spring Boot</category>
            <category>Spring Boot Stripe Beginner Guide</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/stripe_blog_dcb644d230.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Java Memory Management Explained: Heap, Stack, Garbage Collection & Optimization (2025 Guide)]]></title>
            <link>https://www.codingshuttle.com/blogs/java-memory-management-explained-heap-stack-garbage-collection-and-optimization-2025-guide</link>
            <guid>https://www.codingshuttle.com/blogs/java-memory-management-explained-heap-stack-garbage-collection-and-optimization-2025-guide</guid>
            <pubDate>Fri, 22 Aug 2025 05:04:33 GMT</pubDate>
            <description><![CDATA[Master Java Memory Management in 2025! Learn how JVM handles heap, stack, method area, garbage collection, references, and optimization techniques. Avoid memory leaks, improve performance, and build reliable Java applications.]]></description>
            <content:encoded><![CDATA[<p>Java’s automatic memory management is one of the main reasons behind its popularity. Developers don’t have to manually allocate or free memory like in C or C++, thanks to the <strong>Java Virtual Machine (JVM)</strong> and its <strong>Garbage Collector (GC)</strong>.</p><p>However, relying blindly on automatic memory management can lead to <strong>performance bottlenecks, memory leaks, and OutOfMemoryErrors</strong>. To write scalable applications, every Java developer should understand <strong>how memory works in JVM, common pitfalls, and best practices</strong>.</p><p>In this article, I’ll explain the <strong>Java memory model, garbage collection, common mistakes, and optimization techniques</strong> with code examples.</p><h2>1. The Structure of Java Memory in JVM</h2><p>When you run a Java program, the JVM divides memory into different regions. Each region has its own purpose.</p><p><strong>Heap Memory</strong> :</p><p>⇒ The <strong>heap</strong> is the main runtime data area where all Java objects and their instance variables are stored. It is managed automatically by the <strong>Garbage Collector (GC)</strong>, which reclaims memory occupied by objects no longer in use.</p><p>⇒ The heap itself is divided into two main regions: the <strong>Young Generation</strong> and the <strong>Old Generation</strong>. The Young Generation is further split into the <strong>Eden Space</strong>, where new objects are first created, and two <strong>Survivor Spaces</strong> (S0 and S1), where objects that survive garbage collection are moved.</p><p><strong>Stack Memory :</strong></p><p>⇒ Each thread in a Java application has its own <strong>stack</strong>, which is used to store method call details, local variables, primitive data types, and references to objects located in the heap. The stack grows and shrinks dynamically as methods are invoked and returned.</p><p>⇒ Memory in the stack is managed automatically and is thread-specific, making it inherently thread-safe. If the stack grows beyond its allocated size, usually due to deep or infinite recursion, the program will throw a <code><strong>StackOverflowError</strong></code>.</p><p><strong>Method Area (MetaSpace in Java 8+) :</strong> ⇒ The <strong>method area</strong> is a special memory region that stores information about classes, including metadata such as class names, access modifiers, superclass information, method bytecode, static variables, and the runtime constant pool.</p><p><strong>PC Register &amp; Native Memory :</strong></p><p>⇒ The <strong>Program Counter (PC) Register</strong> is a tiny but crucial memory area that each thread maintains independently. It holds the address of the <strong>currently executing JVM instruction</strong>, ensuring that instructions are executed in the correct sequence.</p><p><strong>Visualization:</strong></p><pre><code class="language-plaintext">JVM Memory
 ├── Heap
 │   ├── Young Generation (Eden + Survivor)
 │   └── Old Generation
 ├── Stack (per thread)
 ├── Method Area / MetaSpace
 └── Native Memory</code></pre><h2>2. Heap Memory and Generations</h2><p>The <strong>Heap</strong> is the most important memory region in Java. It is divided into <strong>Young Generation</strong> and <strong>Old Generation</strong>.</p><ul><li><strong>Young Generation</strong>: Stores newly created objects. Most objects die here quickly.<ul><li><i>Eden Space</i>: Where new objects are allocated.</li><li><i>Survivor Spaces</i>: Objects that survive GC are moved here.</li></ul></li><li><strong>Old Generation (Tenured)</strong>: Stores long-lived objects that survived multiple GCs.</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">public class MemoryTest {
    public static void main(String[] args) {
        for (int i = 0; i &lt; 100000; i++) {
            String str = new String("Java"); // Created in Heap
        }
    }
}</code></pre><p>Here, most <code>str</code> objects will die quickly and be collected in the <strong>Young Generation</strong>.</p><h2>3. Stack Memory and Local Variables</h2><p>The <strong>Stack</strong> is created for each thread. It stores <strong>method calls and local variables</strong>.</p><p><strong>Example:</strong></p><pre><code class="language-java">public class StackDemo {
    public static void main(String[] args) {
        int x = 10;        // Stored in Stack
        String name = "Hi"; // Reference in Stack, actual object in Heap
    }
}</code></pre><p>If you call a recursive method without a base case, you’ll face <strong>StackOverflowError</strong>.</p><h2>4. Garbage Collection (GC)</h2><p>Java’s <strong>Garbage Collector</strong> automatically reclaims memory from objects that are no longer reachable.</p><h3>Types of Garbage Collectors:</h3><ul><li><strong>Serial GC</strong> – Simple, single-threaded, good for small apps.</li><li><strong>Parallel GC</strong> – Multiple threads, good for throughput.</li><li><strong>CMS (Concurrent Mark Sweep)</strong> – Low pause time.</li><li><strong>G1 GC (Garbage First)</strong> – Default since Java 9, balances throughput and pause time.</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">public class GCExample {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        System.out.println("Free memory: " + runtime.freeMemory());

        for (int i = 0; i &lt; 10000; i++) {
            new String("Memory Leak?");
        }

        System.gc(); // Suggest GC (not guaranteed)
        System.out.println("Free memory after GC: " + runtime.freeMemory());
    }
}</code></pre><h2>5. Common Memory Management Mistakes</h2><h3>1. Forgetting to Remove References (Memory Leaks)</h3><pre><code class="language-java">List&lt;Object&gt; list = new ArrayList&lt;&gt;();
while (true) {
    list.add(new Object()); // Keeps growing, OutOfMemoryError
}</code></pre><p><strong>Fix:</strong> Clear references when no longer needed.</p><pre><code class="language-java">list.clear();</code></pre><h3>2. Using Static Variables Carelessly</h3><pre><code class="language-java">public class Cache {
    private static List&lt;String&gt; cache = new ArrayList&lt;&gt;();
}</code></pre><p>Static variables live until JVM shutdown, leading to <strong>memory leaks</strong> if overused.</p><h2>6. Best Practices for Efficient Memory Management</h2><ol><li>Use <strong>local variables</strong> where possible (automatically cleared after method ends).</li><li>Prefer <strong>StringBuilder</strong> over String concatenation in loops.</li><li>Use <strong>WeakReference / SoftReference</strong> for caches.</li><li>Always <strong>close resources</strong> (<code>try-with-resources</code>).</li><li>Profile memory with tools like <strong>VisualVM, JConsole, YourKit, Eclipse MAT</strong>.</li></ol><h2>Conclusion</h2><p>Understanding <strong>Java memory management</strong> is crucial for building high-performance, scalable applications. By mastering <strong>Heap, Stack, Garbage Collection, and best practices</strong>, you can avoid memory leaks, optimize resource usage, and write more reliable code.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>JVM</category>
            <category>Java Memory Management</category>
            <category>Java Heap And Stack Explained</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/java_memory_mamanegemt_05451c57a9.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Understanding MVC Architecture: A Simple Guide with Examples]]></title>
            <link>https://www.codingshuttle.com/blogs/understanding-mvc-architecture-a-simple-guide-with-examples</link>
            <guid>https://www.codingshuttle.com/blogs/understanding-mvc-architecture-a-simple-guide-with-examples</guid>
            <pubDate>Thu, 21 Aug 2025 13:10:35 GMT</pubDate>
            <description><![CDATA[Learn MVC Architecture with simple, beginner-friendly examples. Understand Model, View, Controller pattern using Spring Boot with real code and HTML views.]]></description>
            <content:encoded><![CDATA[<p>If you are diving into web development or building applications, you have probably heard of <strong>MVC Architecture</strong>. At first, it might sound a bit technical, but once you get the idea it's actually very simple and logical. <strong>MVC</strong> stands for <strong>Model-View-Controller</strong>, and it’s one of the most commonly used design patterns in modern application development.</p><p>In this article, I will explain <strong>MVC Architecture</strong> in a simple, beginner-friendly way, and i will show you some examples to make it more clear. so let’s start.</p><h2><strong>What is MVC Architecture?</strong></h2><p><strong>MVC</strong> stands for <strong>Model-View-Controller</strong>, a design pattern used to organize code in a way that separates different responsibilities in an application. This separation makes your code cleaner, easier to maintain, and scalable. Think of it like organizing your kitchen: you keep ingredients (data), recipes (logic), and plates (display) in separate places so everything stays manageable.</p><p>Here is what each part means:</p><ol><li><strong>Model</strong>: This is the "data" part. It handles the information your app works with, like user details, product lists, or blog posts. It talks to the database and manages the logic for storing or retrieving data.</li><li><strong>View</strong>: This is what users see and interact with, like the webpages or app screens. It’s the "frontend" that displays the data from the Model in a user-friendly way.</li><li><strong>Controller</strong>: This is the "middleman" that connects the Model and View. It listens to user actions (like clicking a button), fetches or updates data from the Model, and sends it to the View to display.</li></ol><p>By splitting these roles, MVC keeps your code organized and avoids the mess of mixing everything together.</p><h2><strong>Why Use MVC?</strong></h2><p>Before MVC, developers often wrote code where data, logic, and display were all jumbled up. Imagine cooking a meal where all your ingredients, utensils, and plates are in one big pile—it’s chaotic! MVC solves this by:</p><ul><li><strong>Separating Concerns</strong>: Each part (Model, View, Controller) has its own job, making it easier to understand and modify code.</li><li><strong>Reusability</strong>: You can reuse Models or Views in different parts of your app.</li><li><strong>Scalability</strong>: As your app grows, MVC makes it easier to add new features without breaking everything.</li><li><strong>Team Collaboration</strong>: Frontend developers can work on Views, backend developers on Models, and both can coordinate through Controllers.</li></ul><h2><strong>How MVC Works (with a Simple Example)</strong></h2><p>Let’s say you’re building a small web app to display a list of products in an online store. Here’s how MVC would work:</p><ol><li><strong>Model</strong>: Stores product data (like name, price, and ID) and handles database operations (like fetching or saving products).</li><li><strong>View</strong>: Shows the product list on a webpage, maybe with a nice table or cards.</li><li><strong>Controller</strong>: Takes user actions (like clicking "Add Product" or "View Details"), talks to the Model to get or update data, and tells the View what to display.</li></ol><h3><strong>Example Scenario</strong></h3><p>Imagine a user clicks a button to see all products:</p><ul><li>The <strong>Controller</strong> catches the click and asks the <strong>Model</strong> for the product list.</li><li>The <strong>Model</strong> queries the database and returns the product data.</li><li>The <strong>Controller</strong> sends this data to the <strong>View</strong>, which shows it as a neat list on the webpage.</li></ul><h2><strong>MVC in Action: A Spring Boot Example</strong></h2><p>Let’s look at a simple example using <strong>Spring Boot</strong> (a popular Java framework that uses MVC). Suppose we’re building a product management app.</p><h3><strong>1. Model</strong></h3><p>The Model represents the data. In Spring Boot, we use a Java class with JPA annotations to map it to a database table.</p><pre><code class="language-java">import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import lombok.Data;

@Entity
@Data
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;
}</code></pre><p>Here, the Product class is our Model. It defines the structure of a product (ID, name, price) and maps to a database table using JPA.</p><h3><strong>2. View</strong></h3><p>The View is the user interface. In Spring Boot, we can use <strong>Thymeleaf</strong> (a templating engine) to create HTML pages. Here’s a simple HTML file to display a product list.</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html xmlns:th="&lt;http://www.thymeleaf.org&gt;"&gt;
&lt;head&gt;
    &lt;title&gt;Product List&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Products&lt;/h1&gt;
    &lt;table&gt;
        &lt;tr&gt;
            &lt;th&gt;ID&lt;/th&gt;
            &lt;th&gt;Name&lt;/th&gt;
            &lt;th&gt;Price&lt;/th&gt;
        &lt;/tr&gt;
        &lt;tr th:each="product : ${products}"&gt;
            &lt;td th:text="${product.id}"&gt;&lt;/td&gt;
            &lt;td th:text="${product.name}"&gt;&lt;/td&gt;
            &lt;td th:text="${product.price}"&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p>This View loops through a list of products (sent by the Controller) and displays them in a table.</p><h3><strong>3. Controller</strong></h3><p>The Controller handles user requests and connects the Model and View. In Spring Boot, we create a @Controller class.</p><pre><code class="language-java">import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;

@Controller
public class ProductController {
    private final ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @GetMapping("/products")
    public String getAllProducts(Model model) {
        List&lt;Product&gt; products = productService.findAll();
        model.addAttribute("products", products);
        return "product-list"; // Refers to the Thymeleaf template
    }
}</code></pre><p>Here, the ProductController fetches all products from a ProductService (which talks to the Model) and passes them to the View (product-list.html).</p><h3><strong>4. Service (Bonus Layer)</strong></h3><p>In real apps, we often add a <strong>Service</strong> layer to handle business logic. It sits between the Controller and Model to keep things clean.</p><pre><code class="language-java">import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class ProductService {
    private final ProductRepository productRepository;

    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public List&lt;Product&gt; findAll() {
        return productRepository.findAll();
    }
}</code></pre><p>The ProductRepository is a Spring Data JPA interface that handles database operations for the Product Model.</p><pre><code class="language-java">import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository&lt;Product, Long&gt; {
}</code></pre><h2><strong>How It All Comes Together</strong></h2><ol><li>The user visits /products in the browser.</li><li>The <strong>Controller</strong> (ProductController) catches the request and calls the <strong>Service</strong> (ProductService).</li><li>The <strong>Service</strong> uses the <strong>Repository</strong> to fetch data from the <strong>Model</strong> (Product).</li><li>The <strong>Controller</strong> sends the product list to the <strong>View</strong> (product-list.html), which displays it as a table.</li></ol><p>This flow keeps everything organized and easy to maintain.</p><h2><strong>Conclusion</strong></h2><p>I hope you now have a clear understanding of how <strong>MVC Architecture</strong> works and why it’s such a popular design pattern in web development. By separating your code into <strong>Model</strong>, <strong>View</strong>, and <strong>Controller</strong>, you can keep things clean, well-organized, and easier to maintain.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>MVC Architecture</category>
            <category>Model View Controller</category>
            <category>MVC with Spring Boot</category>
            <category>Spring Boot Tutorial</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Understanding_MVC_Architecture_1f7805dbd3.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 10 Java Coding Mistakes Every Developer Should Avoid in 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/top-10-java-coding-mistakes-every-developer-should-avoid-in-2025</link>
            <guid>https://www.codingshuttle.com/blogs/top-10-java-coding-mistakes-every-developer-should-avoid-in-2025</guid>
            <pubDate>Mon, 18 Aug 2025 05:03:36 GMT</pubDate>
            <description><![CDATA[Avoid common Java pitfalls that cause bugs, performance issues, and security risks. Discover the top 10 Java coding mistakes with examples and best practices to write clean, efficient, and reliable code in 2025. Perfect for beginners and experienced Java developers.]]></description>
            <content:encoded><![CDATA[<p>Java is a powerful and widely-used programming language for building robust applications. However, even experienced developers can fall into common pitfalls that lead to bugs, performance issues, or security vulnerabilities. Knowing these mistakes and how to avoid them can significantly improve your code quality, it reduce debugging time, and make your applications more reliable.</p><p>So in this article, I will explain the top 10 must-know Java coding mistakes that every Java developer should be familiar with, along with example code snippets. So let’s get started.</p><h2>1. Comparing Strings with == Instead of equals()</h2><p>I’ve seen this mistake trip up many beginners in my projects. Using == checks for reference equality, not content equality, which can lead to unexpected results when comparing strings from different sources. It’s a common bug that causes logical errors, especially in conditions like user input validation.</p><p>Always use the equals() method for string comparisons. For case-insensitive checks, use equalsIgnoreCase().</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">String str1 = "hello";
String str2 = new String("hello");
if (str1 == str2) {
    System.out.println("Equal");  // This won't print
}</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">String str1 = "hello";
String str2 = new String("hello");
if (str1.equals(str2)) {
    System.out.println("Equal");  // This will print
}</code></pre><h2>2. Not Checking for Null Before Accessing Objects</h2><p>NullPointerException is one of the most frequent runtime errors I encounter. It happens when you try to call a method or access a field on a null reference, crashing your program unexpectedly. I personally make it a habit to add null checks early to prevent these crashes in production.</p><p>Use conditional checks or Java’s Optional class to handle potential null values safely.</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">String name = null;
int length = name.length();  // Throws NullPointerException</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">String name = null;
if (name != null) {
    int length = name.length();
} else {
    System.out.println("Name is null");
}</code></pre><p><strong>Or using Optional:</strong></p><pre><code class="language-java">Optional&lt;String&gt; optionalName = Optional.ofNullable(null);
int length = optionalName.map(String::length).orElse(0);</code></pre><h2>3. Modifying a Collection While Iterating Over It</h2><p>I’ve debugged this issue countless times — it leads to ConcurrentModificationException when you add or remove elements from a list during iteration with a for-each loop. This mistake disrupts the iterator and can cause unpredictable behavior in multi-threaded environments.</p><p>Use an Iterator explicitly and call its remove() method, or collect changes in a separate list and apply them after iteration.</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">List&lt;String&gt; list = new ArrayList&lt;&gt;(Arrays.asList("apple", "banana", "cherry"));
for (String fruit : list) {
    if (fruit.equals("banana")) {
        list.remove(fruit);  // Throws ConcurrentModificationException
    }
}</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">List&lt;String&gt; list = new ArrayList&lt;&gt;(Arrays.asList("apple", "banana", "cherry"));
Iterator&lt;String&gt; iterator = list.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    if (fruit.equals("banana")) {
        iterator.remove();
    }
}</code></pre><h2>4. Using Floating-Point Types for Monetary Calculations</h2><p>In financial apps I’ve worked on, using float or double for money leads to precision errors due to binary representation, causing rounding issues like 0.1 + 0.2 != 0.3. This can result in incorrect calculations and serious business problems.</p><p>Use BigDecimal for precise decimal arithmetic, especially for currency.</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">double amount = 0.1 + 0.2;
System.out.println(amount);  // Prints 0.30000000000000004</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">BigDecimal amount = new BigDecimal("0.1").add(new BigDecimal("0.2"));
System.out.println(amount);  // Prints 0.3</code></pre><h2>5. Not Closing Resources Like Streams or Connections</h2><p>Forgetting to close file streams or database connections is a mistake I made early in my career, leading to resource leaks, file handle exhaustion, or OutOfMemory errors. It’s especially problematic in long-running applications.</p><p>Use try-with-resources (introduced in Java 7) to automatically close resources.</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">FileInputStream fis = new FileInputStream("file.txt");
int data = fis.read();
fis.close();  // Might be forgotten or skipped on exception</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">try (FileInputStream fis = new FileInputStream("file.txt")) {
    int data = fis.read();
}  // Automatically closes fis</code></pre><h2>6. Ignoring the Importance of Overriding equals() and hashCode()</h2><p>When using custom objects in collections like HashSet or HashMap, not overriding these methods causes issues because the default implementation uses object references, leading to duplicates or failed lookups. I recommend always overriding them together for consistency.</p><p>Override both methods, using tools like IDE generators for boilerplate.</p><p><strong>Example of bad code (without override):</strong></p><pre><code class="language-java">public class Person {
    private String name;
    // Constructor and getters...
}

Set&lt;Person&gt; set = new HashSet&lt;&gt;();
set.add(new Person("Alice"));
set.add(new Person("Alice"));  // Adds duplicate because references differ</code></pre><p><strong>Example of good code (with override):</strong></p><pre><code class="language-java">public class Person {
    private String name;
    // Constructor and getters...

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}</code></pre><h2>7. Creating Unnecessary Objects in Loops</h2><p>I’ve optimized performance in loops by avoiding this — creating objects like new String or Integer inside tight loops wastes memory and triggers frequent garbage collection. This reduces efficiency, especially in high-performance code.</p><p>Reuse objects or move creation outside the loop when possible.</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">for (int i = 0; i &lt; 1000000; i++) {
    String s = new String("test");  // Unnecessary new object each time
    // Use s...
}</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">String s = "test";  // Created once outside
for (int i = 0; i &lt; 1000000; i++) {
    // Use s...
}</code></pre><h2>8. Using Raw Types Instead of Generics</h2><p>Raw types (like List without ) bypass type safety, leading to ClassCastExceptions at runtime and making code harder to maintain. I suggest using generics from the start for compile-time checks.</p><p>Always specify type parameters in collections to avoid raw types mistake.</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">List list = new ArrayList();
list.add("string");
list.add(123);
String s = (String) list.get(1);  // Throws ClassCastException</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">List&lt;String&gt; list = new ArrayList&lt;&gt;();
list.add("string");
// list.add(123);  // Compile-time error
String s = list.get(0);</code></pre><h2>9. Off-by-One Errors in Loops or Arrays</h2><p>This classic mistake, like indexing from 1 instead of 0 or using &lt;= in loops, causes ArrayIndexOutOfBoundsException or misses elements. I double-check loop bounds in every array operation to avoid it.</p><p>Remember arrays are 0-indexed; use &lt; length for loops to avoid this mistake.</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">int[] arr = {1, 2, 3};
for (int i = 0; i &lt;= arr.length; i++) {
    System.out.println(arr[i]);  // Throws ArrayIndexOutOfBoundsException at i=3
}</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">int[] arr = {1, 2, 3};
for (int i = 0; i &lt; arr.length; i++) {
    System.out.println(arr[i]);
}</code></pre><h2>10. Not Handling Exceptions Properly</h2><p>Swallowing exceptions with empty catch blocks or printing stack traces without action hides errors, making debugging tough and leaving issues unresolved. In production apps I’ve built, proper handling prevents silent failures.</p><p>Log exceptions meaningfully, rethrow if needed, or use custom exceptions for better error handling.</p><p><strong>Example of bad code:</strong></p><pre><code class="language-java">try {
    int x = 1 / 0;
} catch (ArithmeticException e) {
    // Empty catch - error is swallowed
}</code></pre><p><strong>Example of good code:</strong></p><pre><code class="language-java">try {
    int x = 1 / 0;
} catch (ArithmeticException e) {
    System.err.println("Division by zero: " + e.getMessage());
    // Or rethrow: throw new RuntimeException("Math error", e);
}</code></pre><h2>Conclusion</h2><p>These 10 Java coding mistakes are essential for every Java developer to recognize and avoid. They support you throughout the development lifecycle from writing clean code to debugging, optimizing, and maintaining reliable applications.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>Java coding mistakes</category>
            <category>Java best practices</category>
            <category>Java beginner mistakes</category>
            <category>Java tips and tricks 2025</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Top_10_Java_Coding_Mistakes_Every_Developer_Should_Avoid_in_2025_bc74760149.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How I would learn Spring Boot if I could start over]]></title>
            <link>https://www.codingshuttle.com/blogs/how-i-will-start-spring-boot-and-get-hired-if-i-could-start-over</link>
            <guid>https://www.codingshuttle.com/blogs/how-i-will-start-spring-boot-and-get-hired-if-i-could-start-over</guid>
            <pubDate>Tue, 12 Aug 2025 10:12:00 GMT</pubDate>
            <description><![CDATA[After 8 years of rigorous training and spending over 6000 hours learning and mastering Spring Boot, I have figured out the best way to master this tech.]]></description>
            <content:encoded><![CDATA[<p>I’ve spent the last five years of my life mastering advanced <strong>Spring Boot</strong> and over 10 years living and breathing <strong>Java</strong>. In that time, I have closely watched the tech industry in India—especially how companies hire for Java roles—and one thing is clear: Spring Boot has a clear advantage.</p><p>It’s the go-to framework for many enterprises building web apps and microservices. And the demand is only growing. Freshers can land roles paying ₹5–12 LPA, and with experience, that number can easily cross ₹18 LPA. Through my courses, I’ve trained thousands of students on Spring Boot. Along the way, I’ve seen where beginners get stuck, what concepts they overlook, and which skills make the biggest difference in cracking interviews.</p><p>So in this blog, I’m going to share exactly how I’d learn Spring Boot if I were starting today.</p><h2><strong>Phase 1: Master Java Foundations</strong> (2–3 weeks, 15–20 hrs/week)</h2><p>I would focus on building a strong foundation first. Having a solid grasp of Java’s OOP principles before rushing into Spring Boot ensures you can easily understand its abstractions.</p><p><strong>Core Fundamentals</strong></p><ul><li>Object-Oriented Programming: Classes, inheritance, polymorphism, encapsulation.</li><li>Collections: Lists, Maps, Sets, Queue implementations.</li><li>Exception Handling: Try-catch, custom exceptions.</li><li>Lambdas &amp; Streams: Functional programming for modern APIs.</li><li>Multithreading Basics: Understanding concurrency for web applications.</li></ul><p><strong>Extra Mile</strong></p><ul><li>LeetCode or HackerRank: Solve 50 Easy → 50 Medium → 20 Hard Java problems focusing on algorithms that are relevant for backend development. [Check out the <a href="https://www.codingshuttle.com/courses/dsa-prime/">DSA Prime Course</a> to Master DSA in Java]</li><li>Multithreading concepts with Java Executor Framework</li><li>Using Virtual Threads in your Spring Boot Apps</li></ul><blockquote><p>Java has a strong market demand and used broadly in fintech, banking, telecom, and government sectors due to its performance and reliability. Senior Developers with good Java knowledge make over Rs. 40 LPA. But it takes a good understanding of Java to crack those interviews.</p></blockquote><h2><strong>Phase 2: Spring Core Fundamentals</strong> (1-2 weeks)</h2><p>Spring Boot does a lot of configurations automatically for you; however, it’s important to fully understand Spring first, only then will you be able to fully understand and appreciate Spring Boot. Also, these concepts are the most widely asked questions in the Spring Boot interviews.</p><p><strong>Essential Concepts</strong></p><ul><li>Inversion of Control (IoC), Dependency Injection.</li><li>Bean Lifecycle &amp; Scopes.</li><li>Application Context and Spring Container.</li><li>AOP (Aspect Oriented Programming) basics.</li></ul><p><strong>Maven Proficiency</strong></p><ul><li>Master POM structure and version management.</li><li>Build profiles for dev/staging/prod.</li></ul><p><strong>Extra Mile</strong></p><ul><li>Write a small library and publish it to Maven Central.</li><li>Create multiple profiles in a single project (dev/prod) and switch between them with <code>-spring.profiles.active</code>.</li></ul><blockquote><p>Spring Core knowledge pairs well with container technologies and cloud adoption, which are growing priorities across India's IT sector. Having a solid understanding of the Spring Core is important to crack Spring Boot Interviews.</p></blockquote><h2><strong>Phase 3: Spring Boot Fundamentals</strong> (2–3 weeks)</h2><p>Once you know Spring Core, diving into Spring Boot becomes far easier. This is where you’ll see how Spring Boot takes care of tedious setup so you can focus on business logic. Many production projects expect developers to be fluent in these fundamentals from day one.</p><p><strong>Core Features</strong></p><ul><li>Spring Initializr &amp; project setup.</li><li>@SpringBootApplication &amp; auto-configuration.</li><li>Starter dependencies &amp; embedded servers (Tomcat/Jetty/Undertow).</li></ul><p><strong>Deep Dive</strong></p><ul><li>Conditional annotations like <code>@ConditionalOnProperty</code>, <code>@ConditionaOnMissingBean</code></li><li>Internal startup sequence of Spring Boot apps.</li></ul><p><strong>Extra Mile</strong></p><ul><li>Create your own custom Spring Boot starter module.</li><li>Study the <strong>Spring Boot GitHub source code</strong> to understand how AutoConfiguration works internally.</li><li>Benchmark startup time difference between lazy initialization vs default.</li></ul><blockquote><p>Spring Boot powers critical APIs and services at Netflix, Amazon, PayPal, and many Indian startups like Swiggy, MagicPin, Cred, etc. favouring rapid, scalable development with production-ready defaults. But it all starts with the basics.</p></blockquote><h2><strong>Phase 4: REST APIs &amp; Data Management</strong> (3–4 weeks)</h2><p>After mastering app structure, it’s time to create meaningful outputs — APIs that interact with the real world. Here, you’ll learn how to build RESTful endpoints, handle inputs/outputs, secure them, and connect them to databases using Spring Data JPA.</p><p><strong>RESTful Concepts</strong></p><ul><li>CRUD with Spring MVC annotations.</li><li>Input validation, pagination, and projections.</li><li>Controller advice for exception handling.</li></ul><p><strong>Spring Data JPA</strong></p><ul><li>JPA entity relationships (OneToOne, OneToMany, ManyToMany).</li><li>Query Optimisation</li><li>Hibernate and EntityManager</li><li>Transactional propagation and Persistence Context</li></ul><p><strong>Extra Mile</strong></p><ul><li>Implement a <strong>full-featured API</strong> with validation, error handling, and Swagger Docs.</li><li>Optimize JPA queries to avoid N+1 problems; analyze queries with Hibernate Statistics.</li><li>Flyway for DB migrations.</li><li>Build projects using different databases like MongoDB, MySQL, Neo4j, etc.</li></ul><blockquote><p>Focus on building scalable APIs while keeping ACID compliance in mind. Interviewers love to ask questions around concurrent transaction management and database query optimisation.</p></blockquote><h2><strong>Phase 5: Security &amp; Testing</strong> (3–4 weeks)</h2><p>In the real world, APIs often hold sensitive user data and business-critical processes, so you must know authentication, authorization, and secure coding. At the same time, testing ensures your code works reliably even as it evolves. Learning these together forms the habit of writing safe and stable applications right from the start.</p><p><strong>Security</strong></p><ul><li>JWT, OAuth2, and role-based access control.</li><li>CSRF &amp; CORS handling.</li><li>Method-level security.</li></ul><p><strong>Testing</strong></p><ul><li>Unit testing (JUnit, Mockito).</li><li>Integration testing with MockMvc and Testcontainers.</li><li>Analyse test coverage with libraries like Jacoco.</li></ul><p><strong>Extra Mile</strong></p><ul><li>Write <strong>security tests</strong> that attempt unauthorized access and verify correct rejection.</li><li>Implement <strong>auditing with Spring Data</strong> (createdBy, modifiedBy fields).</li><li>Integrate your tests into a <strong>CI/CD pipeline</strong> with GitHub Actions.</li></ul><blockquote><p>One thing beginners often skip is <strong>testing</strong>—but it’s super important. It’s not just about finding bugs; it shows you’re a serious, detail-oriented developer. Most companies expect <strong>80%+ test coverage</strong> using tools like <strong>JUnit</strong> and <strong>Mockito</strong>, and in many places, automated tests hooked into <strong>CI/CD pipelines</strong> are standard practice.</p></blockquote><h2><strong>Phase 6: Production-Ready Features</strong> (2–3 weeks)</h2><p>Once your app works, making it production-ready is the next milestone. Companies hiring senior Spring Boot developers expect knowledge of deployment-level stability measures, so understanding these early will make you more valuable as a developer.</p><p><strong>Monitoring &amp; Observability</strong></p><ul><li>Spring Boot Actuator, custom health checks.</li><li>Structured logging &amp; auditing.</li><li>Tracing with Zipkin or OpenTelemetry</li><li>Enable <strong>Prometheus + Grafana dashboards</strong> for live monitoring.</li></ul><p><strong>Performance Optimization</strong></p><ul><li>Caching with Redis.</li><li>JVM and DB tuning.</li></ul><p><strong>Extra Mile</strong></p><ul><li>Deploy your app to a cloud platform (AWS/Azure/GCP)</li><li>Set up <strong>centralized logging</strong> with ELK stack (Elasticsearch, Logstash, Kibana)</li><li>Service mesh &amp; observability to manage complexity.</li></ul><blockquote><p>Observability is crucial for industry-grade applications. Companies deploy Spring Boot Actuator metrics integrated with Prometheus and Grafana for real-time operational insights and using ELK stack as a standard solution for log aggregation and analysis across microservices.</p></blockquote><h2><strong>Phase 7: Advanced Architecture Patterns</strong> (3–4 weeks)</h2><p>At this stage, you go beyond basic APIs to building enterprise-grade systems. This is where you learn caching strategies, real-time messaging with Kafka/RabbitMQ, and resilience patterns to ensure systems can handle failures gracefully. These skills are highly sought-after in companies dealing with high-volume, low-latency systems such as fintech, e-commerce, and streaming services.</p><p><strong>Caching</strong></p><ul><li>In-memory vs distributed caching.</li><li>Cache invalidation strategies.</li><li>Cacheable with Spring Boot</li></ul><p><strong>Messaging</strong></p><ul><li>Kafka/RabbitMQ for event-driven architectures.</li><li><strong>Event buses:</strong> AWS EventBridge, Google Pub/Sub.</li><li>Patterns: Event sourcing, CQRS (Command Query Responsibility Segregation).</li></ul><p><strong>Extra Mile</strong></p><ul><li>Build a <strong>real-time notification system</strong> using Kafka + WebSockets.</li><li>Benchmark performance with and without caching under load.</li><li>Distributed systems foundations (CAP theorem, replication, partitioning).</li><li>Resilience patterns like circuit breakers &amp; bulkheads.</li></ul><blockquote><p>Kafka and RabbitMQ power event-driven architectures in finance, telecom, and e-commerce giants for asynchronous and reliable communication. Pair this with Resilience4J and Caching to build resilient and high performant Enterprise applications.</p></blockquote><h2><strong>Phase 8: Microservices Architecture</strong> (4–5 weeks)</h2><p>Microservices are the backbone of modern scalable applications, and understanding them will put you on par with top-level backend engineers. Here, you’ll learn service discovery, API gateways, centralized config servers, and containerized deployments. These concepts are essential in large organizations that need to manage hundreds of services seamlessly across cloud environments.</p><p><strong>Spring Cloud</strong></p><ul><li>Eureka for service discovery.</li><li>API Gateway routing &amp; filtering.</li><li>Centralized configuration server.</li></ul><p><strong>Containers</strong></p><ul><li>Docker multi-stage builds for optimization.</li><li>Kubernetes basic deployments.</li><li>Deploy your services on a Kubernetes cluster (GKE, EKS)</li><li>Containerization, Deployments and Services in k8s</li></ul><p><strong>Extra Mile</strong></p><ul><li>Implement the <strong>Saga pattern</strong> for distributed transactions in a sample e-commerce app.</li><li>Integrate <strong>service mesh</strong> (Istio) for observability and policy control.</li><li>Enable <strong>Zipkin-</strong>based distributed tracing and visualize request flow.</li></ul><blockquote><p>Eureka, Consul, and Spring Cloud Gateway are widely used by BFSI and e-commerce firms for dynamic service routing. As the companies are moving towards Cloud-native adoption, the need for developers with the knowledge of distribution systems is evolving day by day.</p></blockquote><p>Next step? Build Advanced Projects, Write Blogs, Make open-source contributions and keep applying for jobs. Tailor your resume with the skills you have learnt and you’ll get hired. This is how I would have learnt Spring Boot if I could start over.</p><p>As a beginner, it’ll take you 20 - 30 weeks to learn all the concepts and double this time to fully master them. Stick to this roadmap, keep building projects, and never stop learning! The technology landscape is constantly evolving, and staying current with the latest developments helps you remain competitive in the job market.</p><p>&nbsp;</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>Spring Boot</category>
            <category>Spring Framework</category>
            <category>Spring Boot Roadmap</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/FROM_TIER_3_COLLEGE_TO_6_e050de4b4b.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[It Took Me 8+ Years to Realise What I'll Tell You in 8 Minutes]]></title>
            <link>https://www.codingshuttle.com/blogs/it-took-me-8-years-to-realise-what-i-ll-tell-you-in-8-minutes</link>
            <guid>https://www.codingshuttle.com/blogs/it-took-me-8-years-to-realise-what-i-ll-tell-you-in-8-minutes</guid>
            <pubDate>Thu, 07 Aug 2025 09:19:42 GMT</pubDate>
            <description><![CDATA[After more than 8 years in the tech industry, I've made countless mistakes, wasted precious time on the wrong things, and learned lessons the hard way. Today, I'm sharing the most critical insights that could have saved me years of struggle.]]></description>
            <content:encoded><![CDATA[<p>There's an old saying that goes “You learn from your mistakes". Some mistakes are bad and waste your precious years, while some mistakes are important for your growth. I have spent over 8 years in the tech industry and mentored thousands of students. In this blog, I’ll share my learnings and mistakes over the past decade so that you don’t waste your time too.</p><h2>1. Stop Prioritising Low-Impact Learning</h2><p>I wasted months perfecting CSS styling and UI Designs while ignoring the elephant in the room, like:</p><ul><li><strong>Database Optimization</strong></li><li><strong>Concurrent Transaction Management</strong></li><li><strong>Low-level System Design.</strong></li></ul><p>I have seen thousands of beginners making the same mistakes. Wasting too much time on perfecting the color and typography. You need to understand that you are not applying for a job as a UI Designer.</p><p>Interview questions like "How do you handle conflict updates in DB in high concurrent environment?" exposed my knowledge gaps. Some common questions asked during your interviews are:</p><ul><li>You have 1000 concurrent users updating the same inventory record. How do you prevent race conditions?</li><li>Design a system handling 1 million requests per minute.</li><li>Design a notification system that processes and sends 10,000 emails per hour while ensuring no duplicate emails are sent.</li><li>How do you implement a rate-limiting mechanism in REST APIs to restrict users to 100 requests per minute per IP address?</li><li>How would you handle distributed transactions across multiple microservices updating different databases simultaneously?</li></ul><h3>The High-Impact Skills You Need to Master</h3><p><strong>Database Optimization:</strong></p><ul><li><strong>Connection pooling</strong> for performance improvement</li><li><strong>JPA transaction propagation</strong> and Isolation levels for data consistency.</li><li><strong>Query optimization</strong> techniques, including proper indexing strategies.</li><li><strong>Concurrent transaction management</strong> to prevent data corruption</li></ul><p><strong>Spring Boot Advanced Features:</strong></p><ul><li><strong>Circuit breakers</strong> with Hystrix for error handling</li><li><strong>Microservice architecture</strong> with service discovery and load balancing</li><li><strong>Apache Kafka</strong> for event-driven communication between services and processing asynchronous requests.</li><li><strong>Caching strategies</strong> using Redis or Hazelcast for response time optimization</li><li><strong>WebFlux and reactive programming</strong> for handling high-throughput scenarios</li><li><strong>Advanced deployment</strong> with Kubernetes and Docker containerization</li><li><strong>Distributed systems</strong>, Saga pattern, and transaction management.</li></ul><blockquote><p>Want to get hired? Stop perfecting basics and Learn what matters to the industry.&nbsp;</p></blockquote><h2>2. Stop Underestimating Java</h2><p>Like most of us, I started my programming journey with the C Language. Then I moved to Java as my first OOP language. I should have continued with Java in development, but here I made the mistake of underestimating this language. I got distracted by the MERN stack hype.</p><p>While everyone was chasing MERN stack trends, Java quietly dominated where it mattered most. Companies in <strong>finance, healthcare, and e-commerce</strong> aren't just using Java – they're exclusively hiring Java developers. I applied for such jobs, but I got rejected during the interviews as they needed people with advanced Java knowledge. Java is dominating the tech industry, but it has a bad PR. People still find it too verbose or difficult to understand. And therefore, very few students opt to learn it.&nbsp;</p><p><strong>Java's Enterprise Reality</strong></p><p>Here's what shocked me: <strong>97% of corporate computers run Java</strong>. Major companies like Netflix use Java for microservices handling millions of users, Amazon leverages it for scalable cloud applications, and Google Cloud officially supports Java as part of its offerings. The healthcare industry is projected to reach $275 billion by 2028, with Java being the preferred choice for building secure, compliant systems.</p><p><strong>The companies hiring Java developers right now:</strong></p><ul><li><strong>Financial services</strong>: Goldman Sachs, Morgan Stanley, JPMorgan Chase: Transaction processing and fraud detection</li><li><strong>Healthcare</strong>: Epic Systems, Cerner, Allscripts: Electronic health records and patient management systems</li><li><strong>E-commerce</strong>: Amazon, eBay, Walmart Labs: Billions of Orders and Transactions</li><li><strong>Enterprise software</strong>: Oracle, SAP, IBM, <strong>Netflix</strong>: Microservices architecture serving 200+ million subscribers</li><li><strong>Consulting</strong>: Accenture, Deloitte, TCS, Infosys: Data processing and recommendation engines</li></ul><p><strong>Salary reality check:</strong></p><ul><li>MERN Stack Developers (Entry-Level): INR 3,00,000–7,20,000 per annum</li><li>Java Developers (Entry-Level): INR 4,00,000–12,00,000 per annum</li><li>Senior Java Developers with Spring Boot: INR 12,00,000–60,00,000 per annum</li><li>Java Architects: INR 40,00,000–80,00,000 per annum</li></ul><h3>Why Java Interview Success Rates Are Higher</h3><p><strong>Low-Level Design (LLD)</strong> questions in interviews became my nightmare until I mastered Java's OOP principles. Java forces you to understand:</p><ul><li><strong>SOLID principles</strong> with real implementation</li><li><strong>Design patterns</strong> like Singleton, Factory, Observer, with practical examples</li><li><strong>Memory management</strong> and garbage collection optimisation</li><li><strong>Abstraction</strong> and proper class hierarchies</li></ul><blockquote><p>MERN is cool, but Java puts food on the table.</p></blockquote><h2>3. Stop Ignoring The Industry Standards</h2><p>I learnt it during my first Job at Urban Company, that recruiters go through your GitHub and analyze the quality of your code. Most of my GitHub projects were basic CRUD applications. No design patterns, no proper error handling, no testing. Result? <strong>Zero interview calls</strong> from good companies. Meanwhile, people with good quality code with Design patterns and other industry standards were getting shortlisted. See, recruiters want smart people to join their teams. It won’t matter how many LeetCode problems you have solved or how good you are at DSA.</p><p>My first day at a real company – I couldn't understand the codebase. Dependency injection, AOP, complex design patterns, and comprehensive testing suites. I felt like I was reading a foreign language.&nbsp;</p><p>Most beginners make the mistake of ignoring or avoiding to learn the Industry standards and thinking they don't have to know all this. They are happy with their mediocre projects and learnings, but that does not impress recruiters.</p><h3>Industry-Standard Project Architecture</h3><p><strong>Essential Design Patterns with Real Examples:</strong></p><ul><li><strong>Factory Pattern</strong>: Creating different payment processors (PayPal, Stripe, Razorpay)</li><li><strong>Observer Pattern</strong>: Real-time notification systems for order status updates</li><li><strong>Strategy Pattern</strong>: Different pricing algorithms for e-commerce platforms</li><li><strong>Builder Pattern</strong>: Complex object creation for configuration management</li></ul><p><strong>Spring Framework Mastery:</strong></p><ul><li><strong>Spring Data JPA + Hibernate</strong>: Advanced features like criteria queries and custom repositories</li><li><strong>Spring Security</strong>: JWT authentication, OAuth2 integration, method-level security</li><li><strong>Spring MVC</strong>: RESTful API design with proper exception handling</li><li><strong>AOP (Aspect-Oriented Programming)</strong>: Cross-cutting concerns like logging and security</li><li><strong>Caching</strong>: Multi-level caching strategies for performance optimization</li><li><strong>Messaging</strong>: Apache Kafka and RabbitMQ for enterprise messaging patterns</li></ul><p><strong>Testing: The Non-Negotiable Skill</strong></p><p>"Untested code is broken code" – this principle saved my career. <strong>Code coverage should be 80%+,</strong> and you must think of all edge cases.</p><ul><li><strong>Unit testing</strong> with JUnit 5 and Mockito for isolated component testing</li><li><strong>Integration testing</strong> with TestContainers for database interactions</li><li><strong>Contract testing</strong> with Pact for microservices communication</li><li><strong>Performance testing</strong> with JMeter for load validation</li><li><strong>Code coverage</strong> with JaCoCo to ensure comprehensive testing</li></ul><p><strong>Microservices with Spring Cloud:</strong></p><ul><li><strong>Service Discovery</strong> with Eureka or Consul</li><li><strong>Circuit Breakers</strong> with Resilience4j</li><li><strong>Distributed Configuration</strong> with Spring Cloud Config</li><li><strong>API Gateway</strong> with Spring Cloud Gateway</li></ul><blockquote><p>The companies need you more than you need them – but only if you have the right skills.</p></blockquote><h2>DevOps, AI, and the Future</h2><p>People say these days, the role of SDE 1 has been delegated to AI, and SDE 1 is expected to perform as good as SDE 2. I would argue that this had always been the case. If you wish to move up your career ladder, you need to perform at the level of your superiors. But with AI, this paradigm is more prominent than ever. Fresher candidates with good knowledge of DevOps and AI integration are preferred over those who don’t want to evolve.</p><p><strong>AI Integration in Java Applications:</strong></p><ul><li><strong>LangChain4j</strong> for building AI-powered applications</li><li><strong>Spring AI</strong> for seamless AI service integration</li><li><strong>Vector databases</strong> for semantic search capabilities</li><li><strong>Machine learning pipelines</strong> with Java-based frameworks</li></ul><blockquote><p>Upgrades are like taxes: painful, inevitable, and worse when ignored.</p></blockquote><p>The choice is yours. You can spend the next few years learning the hard way as I did, or you can take this roadmap and accelerate your career by focusing on what matters in the industry.</p><p>Don't make my mistakes. Choose wisely. Your future self will thank you.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>Tech Jobs</category>
            <category>Industry-Ready</category>
            <category>Tech Hiring</category>
            <category>Programming Mistakes</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/FROM_TIER_3_COLLEGE_TO_5_f444c0908c.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[RabbitMQ Configuration In Spring Boot With Examples]]></title>
            <link>https://www.codingshuttle.com/blogs/rabbit-mq-configuration-in-spring-boot-with-examples</link>
            <guid>https://www.codingshuttle.com/blogs/rabbit-mq-configuration-in-spring-boot-with-examples</guid>
            <pubDate>Sun, 20 Jul 2025 05:11:29 GMT</pubDate>
            <description><![CDATA[Learn how to integrate RabbitMQ with Spring Boot application to enable asynchronous communication in microservices architecture.]]></description>
            <content:encoded><![CDATA[<p>If you are building microservices, you have probably heard the term <strong>message queue</strong>. and it is important for handling communication between services efficiently. Instead of making one service wait for another, messaging lets them talk <strong>asynchronously</strong>. That is where <strong>RabbitMQ</strong> comes in, It is one of the most popular open-source message brokers.</p><p>In this article, I will show you how to integrate RabbitMQ with a Spring Boot application using simple and clear examples.</p><h2><strong>Introduction</strong></h2><ul><li>In modern applications we use microservices architecture, As application grows the connections between these services become large.</li><li>We can’t rely on request/response-based systems in this situation since applications usually wait for another service’s response.</li><li>All these factors create a need for <strong>asynchronous communication</strong> between the microservices, and <strong>Message Based Systems</strong> can help.</li><li>A new component called an&nbsp;<i>intermediary</i>&nbsp;is introduced to communication between two services instead of directly establishing communication between them.</li><li>This middle component is known as <i><strong>Message Broker.</strong></i></li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Message_Broker_2dc4500b33.png" alt="Message Broker" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Message_Broker_2dc4500b33.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Message_Broker_2dc4500b33.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Message_Broker_2dc4500b33.png 750w," sizes="100vw"><figcaption>Message Broker</figcaption></figure><ul><li>Instead of every service trying to understand how to talk to every other service, they all just talk to the <strong>message broker</strong> using a common format.</li><li>Message Brokers can also <strong>store (queue)</strong> messages temporarily. This means if a service is busy or slow, it won’t block others — the message just waits in line. This helps things run faster overall.</li><li>For example, when a user sends a request that needs a lot of processing, the web server can quickly reply and let another worker handle the heavy task in the background.</li></ul><h2><strong>RabbitMQ</strong></h2><ul><li>RabbitMQ is an popular open-source <strong>Message Broker</strong> used for building message-based systems. Although RabbitMQ supports multiple protocols, the most commonly used is <strong>AMQP</strong>.</li><li>AMQP 0–9–1 (Advanced Message Queuing Protocol) is a <strong>messaging protocol.</strong></li><li>It works at the <strong>application layer</strong> and sends data in <strong>binary format</strong>, which is more efficient than plain text. In AMQP, the data is broken into <strong>frames</strong>, which are like small packets that carry information between apps and the message broker.</li></ul><h2>Key Components</h2><p>●&nbsp;<strong>Producer / publisher</strong>: Application that sends the messages.</p><p>●&nbsp;<strong>Consumer / subsciber</strong>: Application that receives the messages.</p><p>●&nbsp;<strong>Queue</strong>: A place where messages are stored until a service (consumer) picks them up.</p><p>●&nbsp;<strong>Connection</strong>: A TCP connection between <strong>producer and consumer</strong> and the <strong>RabbitMQ server.</strong></p><p>●&nbsp;<strong>Channel</strong>: A lightweight communication path inside a connection. You publish or consume messages using channels.</p><p>●&nbsp;<strong>Exchange</strong>: It decides <strong>where</strong> to send a message. Producers send messages to an exchange, and it routes them to the right queue(s) based on rules.</p><p>●&nbsp;<strong>Binding</strong>: Bindings are rules that exchanges use to route messages to queues.</p><p>●&nbsp;<strong>Routing key</strong>: A key that the exchange uses to decide how to route the message to queues. Think of the routing key as an address for the message.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Messaging_Process_db2987fb6a.png" alt="Messaging Process" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Messaging_Process_db2987fb6a.png 129w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Messaging_Process_db2987fb6a.png 412w," sizes="100vw"><figcaption>Messaging Process</figcaption></figure><h2>Steps To Add RabbitMQ In Spring Boot :</h2><p>Let’s build two Spring Boot services: a <strong>producer</strong> to send email messages and a <strong>consumer</strong> to process them. We’ll use RabbitMQ to handle the communication. Ready? Here we go!</p><h3>Step 1: Run RabbitMQ with Docker</h3><p>The easiest way to start RabbitMQ is with Docker. Open your terminal and run:</p><pre><code class="language-plaintext">docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:4-management</code></pre><h3>Step 2: Add This Dependency In Your Spring Boot Project</h3><p>Add this to the <code>pom.xml</code> for both projects:</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-amqp&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><h3>Step 3: Configure RabbitMQ in <code>application.yml</code></h3><pre><code class="language-plaintext">spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest</code></pre><h3>Step 4: Set Up Exchange, Queue, and Binding</h3><p>Create a configuration class in both services to define the queue, exchange, and binding:</p><pre><code class="language-java">package com.example.demo;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfig {

    public static final String EMAIL_EXCHANGE_NAME = "email-exchange";
    public static final String EMAIL_QUEUE_NAME = "email-queue";
    public static final String EMAIL_ROUTING_KEY = "email-routing-key";

    @Bean
    public Queue emailQueue() {
        return new Queue(EMAIL_QUEUE_NAME, true);
    }

    @Bean
    public TopicExchange emailExchange() {
        return new TopicExchange(EMAIL_EXCHANGE_NAME);
    }

    @Bean
    public Binding emailBinding() {
        return BindingBuilder
                .bind(emailQueue())
                .to(emailExchange())
                .with(EMAIL_ROUTING_KEY);
    }
}</code></pre><ul><li><strong>What’s happening?</strong><ul><li>Creates a durable queue (<code>email-queue</code>) that survives RabbitMQ restarts.</li><li>Sets up a topic exchange (<code>email-exchange</code>).</li><li>Binds the queue to the exchange with the routing key <code>email-routing-key</code>.</li></ul></li></ul><h3>Step 5: Create the Producer</h3><p>In the <strong>producer service</strong>, create a service to send messages:</p><pre><code class="language-java">package com.example.demo;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MessagePublisher {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendEmail(String message) {
        rabbitTemplate.convertAndSend(
                RabbitMqConfig.EMAIL_EXCHANGE_NAME,
                RabbitMqConfig.EMAIL_ROUTING_KEY,
                message
        );
        System.out.println("Message sent: " + message);
    }
}</code></pre><p>This sends a message to the <code>email-exchange</code>, which routes it to the <code>email-queue</code>.</p><h3>Step 6: Create the Consumer</h3><p>In the <strong>consumer service</strong>, create a listener to process messages:</p><pre><code class="language-java">package com.example.demo;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

@Service
public class MessageListener {

    private final EmailService emailService;

    public MessageListener(EmailService emailService) {
        this.emailService = emailService;
    }

    @RabbitListener(queues = RabbitMqConfig.EMAIL_QUEUE_NAME)
    public void consumeMessageFromQueue(String message) {
        emailService.sendEmail(message);
        System.out.println("Message received: " + message);
    }
}</code></pre><ul><li><strong>What’s happening?</strong><ul><li>The <code>@RabbitListener</code> listens for messages on <code>email-queue</code>.</li><li>When a message arrives, it’s passed to <code>emailService.sendEmail()</code> (you’d implement this for actual email sending).</li></ul></li></ul><h3>Step 7: To Send JSON Messages</h3><p>To send JSON instead of plain strings, add this bean to <code>RabbitMqConfig</code> in both services:</p><pre><code class="language-java">@Bean
public MessageConverter jsonMessageConverter() {
    return new Jackson2JsonMessageConverter();
}</code></pre><p>This lets you send and receive JSON objects for more complex data.</p><h3>Step 8: Test It</h3><ol><li>Start RabbitMQ with the Docker command.</li><li>Run both Spring Boot apps.</li><li>In the producer, call <code>messagePublisher.sendEmail("Test email!")</code> .</li><li>Check the consumer’s console for the message.</li></ol><p>Visit <code>http://localhost:15672</code> to see messages flowing through the queue in the RabbitMQ dashboard. It’s like watching your app’s mailroom in action!</p><h2>Conclusion</h2><p>By adding RabbitMQ to your Spring Boot apps, you introduce a robust and scalable way to manage inter-service communication. It decouples services, improves responsiveness, and gives you more control over message delivery.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot</category>
            <category>RabbitMQ</category>
            <category>RabbitMQ In Spring Boot</category>
            <category>Message Queue In Spring Boot</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Rabbit_MQ_and_Spring_Boot_24c784b0b4.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[The Showdown: Should You Build Monolithic or Go Microservices?]]></title>
            <link>https://www.codingshuttle.com/blogs/monolithic-architecture-vs-microservices-architecture</link>
            <guid>https://www.codingshuttle.com/blogs/monolithic-architecture-vs-microservices-architecture</guid>
            <pubDate>Fri, 18 Jul 2025 03:46:22 GMT</pubDate>
            <description><![CDATA[Learn the key differences between Monolithic and Microservices architectures with real-world examples, use cases, and a quick comparison table. Perfect guide for system design interviews and modern software development.]]></description>
            <content:encoded><![CDATA[<p>If you are diving into the world of system design, there is high chance of you have heard about <strong>Monolithic Architecture</strong> and <strong>Microservices Architecture</strong>. Because these are most common ways to structure software. Both have their strengths, but they are suited for different scenarios.</p><p>In this article, i will explain both <strong>Monolithic</strong> and <strong>Microservices</strong> Architecture with key differences. This will help you decide which one to use in system design interviews and when developing real-world applications.</p><h2><strong>Monolithic Architecture</strong></h2><p>Monolith architecture refers to a traditional software design approach where an entire application is built as a single, indivisible unit, typically comprising multiple interconnected components or modules.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Monolitic_Diagram_d9f156dcad.png" alt="Monolithic Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Monolitic_Diagram_d9f156dcad.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Monolitic_Diagram_d9f156dcad.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Monolitic_Diagram_d9f156dcad.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Monolitic_Diagram_d9f156dcad.png 1000w," sizes="100vw"><figcaption><strong>Monolithic Architecture</strong></figcaption></figure><p>In this architecture, all functionalities, such as user interface, business logic, and data access, are tightly coupled within the same codebase.</p><h2><strong>Microservices Architecture</strong></h2><p>Microservices architecture is an architectural style where an application is composed of loosely coupled, independently deployable services, each responsible for a specific business function.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Microservices_Diagram_8af74b622c.png" alt="Microservices Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Microservices_Diagram_8af74b622c.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Microservices_Diagram_8af74b622c.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Microservices_Diagram_8af74b622c.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Microservices_Diagram_8af74b622c.png 1000w," sizes="100vw"><figcaption><strong>Microservices Architecture</strong></figcaption></figure><p>These services communicate through well-defined APIs and can be developed, deployed, and scaled independently, allowing for greater agility, flexibility, and resilience in complex software systems.</p><h2>Key Differences Between Monolithic and Microservices Architecture</h2><h3>1. Structure</h3><p><strong>Monolithic :</strong> Everything is in one codebase—frontend, backend, database access, and business logic. It’s a single, tightly coupled unit.</p><p><strong>Microservices :</strong> The application is split into small, independent services, each with its own codebase and database (if needed). Services are loosely coupled and communicate over a network.</p><h3>2. Development and Maintenance</h3><p><strong>Monolithic :</strong> Easier to develop and test for small apps since everything is in one place. However, as the codebase grows, it can become complex and hard to maintain.</p><p><strong>Microservices :</strong> More complex to develop because you’re managing multiple services, but each service is smaller and easier to understand. Teams can work on different services independently.</p><h3>3. Deployment</h3><p><strong>Monolithic :</strong> Deployed as a single unit. If you update one part (e.g., a bug fix in the user module), you redeploy the entire app, which can be risky and slow.</p><p><strong>Microservices :</strong> Each service is deployed independently. You can update the OrderService without touching the UserService, making deployments faster and less risky.</p><p><strong>Example (Deployment Impact):</strong></p><ul><li>Monolithic: Change a single endpoint, and you redeploy the entire app, potentially causing downtime.</li><li>Microservices: Update the OrderService endpoint, and only that service is redeployed.</li></ul><h3>4. Scalability</h3><p><strong>Monolithic :</strong> Scaling means replicating the entire app (e.g., running multiple instances). If one part (like order processing) is resource-heavy, you scale everything, which can be inefficient.</p><p><strong>Microservices :</strong> You can scale individual services. If the OrderService gets heavy traffic, you scale just that service, saving resources.</p><h3>5. Technology Stack</h3><p><strong>Monolithic :</strong> Typically uses a single technology stack (e.g., Java with Spring for everything). Changing tech (e.g., from Java to Python) is a major overhaul.</p><p><strong>Microservices :</strong> Each service can use a different tech stack. For example, OrderService could use Java/Spring, while UserService uses Python/Flask, giving flexibility.</p><h3>6. Communication</h3><p><strong>Monolithic :</strong> Components communicate within the same process (e.g., method calls), which is fast but tightly coupled.</p><p><strong>Microservices :</strong> Services communicate over a network (e.g., REST APIs, message queues), which adds latency but keeps services independent.</p><p>Here, OrderService calls UserService over HTTP, showing how microservices interact.</p><h3>7. Complexity</h3><p><strong>Monolithic :</strong> Simpler for small apps but can become a “big ball of mud” as complexity grows, making debugging and updates harder.</p><p><strong>Microservices :</strong> More complex due to distributed systems (e.g., managing network failures, service discovery). Tools like Docker and Kubernetes help, but there’s a learning curve.</p><h2>Quick Comparison Table</h2><figure class="table"><table><thead><tr><th>Feature</th><th>Monolithic Architecture</th><th>Microservices Architecture</th></tr></thead><tbody><tr><td><strong>Structure</strong></td><td>Single codebase</td><td>Multiple independent services</td></tr><tr><td><strong>Development</strong></td><td>Simpler for small apps, complex for large</td><td>Complex but modular</td></tr><tr><td><strong>Deployment</strong></td><td>Single deployment, riskier</td><td>Independent deployments, safer</td></tr><tr><td><strong>Scalability</strong></td><td>Scales entire app</td><td>Scales individual services</td></tr><tr><td><strong>Tech Stack</strong></td><td>Single stack</td><td>Multiple stacks possible</td></tr><tr><td><strong>Communication</strong></td><td>In-process (fast, coupled)</td><td>Over network (slower, decoupled)</td></tr><tr><td><strong>Complexity</strong></td><td>Simpler initially, harder to maintain</td><td>More complex, easier to maintain</td></tr></tbody></table></figure><h2>When to Use Monolithic Architecture</h2><p>Choose a <strong>Monolithic Architecture</strong> when:</p><ul><li>You’re building a <strong>small or medium-sized app</strong> with straightforward requirements.</li><li>You want <strong>simpler development and deployment</strong> processes.</li><li>Your team is small, and you don’t need to manage multiple services.</li><li>You’re working on a <strong>proof-of-concept</strong> or startup MVP where speed to market matters.</li></ul><p><strong>Example Use Cases:</strong></p><ul><li>Small e-commerce sites</li><li>Internal tools or dashboards</li><li>Simple CRUD applications</li></ul><h2>When to Use Microservices Architecture</h2><p>Choose a <strong>Microservices Architecture</strong> when:</p><ul><li>You’re building a <strong>large, complex application</strong> that needs to scale.</li><li>You want <strong>team autonomy</strong>, where different teams can work on separate services.</li><li>You need <strong>flexibility</strong> to use different tech stacks or scale specific components.</li><li>You’re working on <strong>cloud-native</strong> or <strong>high-traffic systems</strong> (e.g., Netflix, Amazon).</li></ul><p><strong>Example Use Cases:</strong></p><ul><li>Large-scale e-commerce platforms (e.g., order, payment, and inventory services)</li><li>Streaming services (e.g., user profiles, video processing)</li><li>Microservices-based APIs for mobile apps</li></ul><h2>Conclusion</h2><p>Both <strong>Monolithic</strong> and <strong>Microservices Architectures</strong> have their place in software development. Monoliths architecture where an entire application is built as a single, indivisible unit and Microservices architecture where an application is composed of loosely coupled, independently deployable services.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Monolithic vs Microservices</category>
            <category>Monolithic architecture</category>
            <category>Microservices architecture</category>
            <category>System Design</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Monolithic_Architecture_vs_Microservices_Architecture_Cover_82226f5a9c.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Understanding JDK, JRE And JVM In Java With Key Differences]]></title>
            <link>https://www.codingshuttle.com/blogs/understanding-jdk-jre-jvm-in-java</link>
            <guid>https://www.codingshuttle.com/blogs/understanding-jdk-jre-jvm-in-java</guid>
            <pubDate>Wed, 16 Jul 2025 15:37:35 GMT</pubDate>
            <description><![CDATA[Confused about JDK, JRE, and JVM in Java? This beginner-friendly guide breaks down their roles, differences, and how they work together.]]></description>
            <content:encoded><![CDATA[<p>If you have been exploring Java, you have probably heard these three terms <strong>JDK</strong>, <strong>JRE</strong>, and <strong>JVM</strong>. At first, they all sound the same and honestly it is super easy to confuse them. But understanding these terms is important for Java development as well as from an interview point of view.</p><p>So, in this article, we will cover what each one is, how they work together, and their key differences. I will also include a simple code snippet and explain everything in a friendly, easy-to-understand way.</p><h2>What is the JVM?</h2><p>The <strong>Java Virtual Machine (JVM)</strong> is the heart of Java’s “write once, run anywhere” philosophy. It’s a virtual machine that runs Java bytecode, which is the compiled form of your Java code. The JVM acts like a translator, turning this platform-independent bytecode into machine-specific instructions that your computer’s hardware can understand.</p><p>Think of the JVM as a magic box: you feed it bytecode, and it makes sure your program runs on any device—Windows, Mac, Linux, or even a server—without you needing to rewrite the code.</p><p><strong>Key Points:</strong></p><ul><li>The JVM handles memory management, garbage collection, and security.</li><li>It’s platform-specific, so there’s a different JVM for Windows, Linux, etc.</li><li>It doesn’t include tools for writing or compiling code—it just runs it.</li></ul><h2>What is the JRE?</h2><p>The <strong>Java Runtime Environment (JRE)</strong> is a bigger package that includes the <strong>JVM</strong> plus the <strong>standard Java libraries</strong> (like java.util, <a href="http://java.io">java.io</a>, etc.) needed to run Java applications. If you’re just running a Java program (not developing one), the JRE is all you need.</p><p>Think of the JRE as the “player” for Java apps—it provides everything required to execute a Java program but doesn’t include tools for writing or compiling code.</p><p><strong>Key Points:</strong></p><ul><li>The JRE contains the JVM and core libraries (e.g., for file handling, networking).</li><li>It’s enough for end-users who want to run Java apps, like a game or a desktop tool.</li><li>It’s platform-specific, so you download the JRE for your operating system.</li></ul><h2>What is the JDK?</h2><p>The <strong>Java Development Kit (JDK)</strong> is the full toolkit for Java developers. It includes the <strong>JRE</strong> (so it has the JVM and libraries) plus tools like the <strong>Java compiler (javac)</strong>, debugger, and other utilities for writing, compiling, and debugging Java code. If you’re coding Java, you need the JDK.</p><p>Think of the JDK as the complete workshop: it has everything the JRE offers (for running programs) plus the tools to create and build those programs.</p><p><strong>Key Points:</strong></p><ul><li>The JDK includes javac (compiles .java files to .class bytecode), jar (for packaging), and more.</li><li>It’s what developers install to write and test Java applications.</li><li>Like the JRE, it’s platform-specific.</li></ul><p><strong>Example (Using the JDK to Compile and Run):</strong></p><pre><code class="language-java">// HelloWorld.java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello from Java!");
    }
}</code></pre><p>To run this:</p><ol><li>Use the JDK’s javac to compile: javac HelloWorld.java (creates HelloWorld.class bytecode).</li><li>Use the JRE’s java command (via the JVM) to run: java HelloWorld.</li></ol><p>Output: Hello from Java!</p><p>Here, the JDK provides javac to compile the code, the JRE provides the java command, and the JVM executes the bytecode.</p><h2>How Do JDK, JRE, and JVM Work Together?</h2><p>Here’s the flow:</p><ol><li>You write Java code (.java files) using a text editor or IDE.</li><li>The <strong>JDK</strong>’s compiler (javac) turns your code into bytecode (.class files).</li><li>The <strong>JRE</strong> provides the environment to run the bytecode, using the <strong>JVM</strong> to translate it into machine code for your specific hardware.</li><li>The JVM also manages runtime tasks like memory allocation and garbage collection.</li></ol><p>It’s like a team effort: the JDK builds the app, the JRE provides the runtime, and the JVM does the heavy lifting of execution.</p><h2>Key Differences Between JDK, JRE, and JVM</h2><p>Let’s break down the differences to make it super clear.</p><h3>1. Purpose</h3><p><strong>JVM :</strong> Executes bytecode by translating it into machine code. It’s the runtime engine that makes Java programs run.</p><p><strong>JRE :</strong> Provides the environment to run Java programs, including the JVM and standard libraries.</p><p><strong>JDK :</strong> A complete toolkit for developing Java programs. It includes the JRE and development tools like <code>javac</code> (the Java compiler) to compile your code.</p><h3>2. Components</h3><p><strong>JVM :</strong> Just the virtual machine—no libraries or development tools.</p><p><strong>JRE :</strong> Includes the JVM and core Java libraries (e.g., java.lang, java.util).</p><p><strong>JDK :</strong> Includes the JRE (JVM + libraries) plus development tools like javac, jar, and debuggers.</p><h3>3. Size</h3><p><strong>JVM :</strong> The smallest component, just the execution engine (a part of the JRE).</p><p><strong>JRE :</strong> Larger than the JVM, includes the JVM and libraries (typically a few hundred MB).</p><p><strong>JDK :</strong> The largest, includes the JRE plus development tools (often 1GB or more).</p><h3>4. Functionality</h3><p><strong>JVM :</strong> Runs bytecode, manages memory, and optimizes performance (e.g., via the JIT compiler).</p><p><strong>JRE :</strong> Provides the runtime environment to execute Java apps.</p><p><strong>JDK :</strong> Enables development, compilation, and execution of Java programs.</p><h2>Quick Comparison Table</h2><figure class="table"><table><thead><tr><th>Feature</th><th>JVM</th><th>JRE</th><th>JDK</th></tr></thead><tbody><tr><td><strong>Purpose</strong></td><td>Executes bytecode</td><td>Runs Java applications</td><td>Develops and runs applications</td></tr><tr><td><strong>Components</strong></td><td>Execution engine</td><td>JVM + core libraries</td><td>JRE + development tools</td></tr><tr><td><strong>Audience</strong></td><td>Internal to JRE/JDK</td><td>End-users</td><td>Developers</td></tr><tr><td><strong>Size</strong></td><td>Smallest</td><td>Medium (JVM + libraries)</td><td>Largest (JRE + tools)</td></tr><tr><td><strong>Functionality</strong></td><td>Runs bytecode, manages memory</td><td>Provides runtime environment</td><td>Provides development and runtime tools</td></tr></tbody></table></figure><h2>Conclusion</h2><p>The <strong>JVM</strong>, <strong>JRE</strong>, and <strong>JDK</strong> are like a team that makes Java’s magic happen. The JVM is the engine that runs bytecode, the JRE provides the full runtime environment, and the JDK is the complete toolkit for developers.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>JDK vs JRE vs JVM</category>
            <category>Java Interview Preparation</category>
            <category>Java Development</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Understanding_JDK_JRE_And_JVM_In_Java_With_Key_Differences_Cover_7091aa32af.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Difference Between Abstract Class And Interface In Java]]></title>
            <link>https://www.codingshuttle.com/blogs/difference-between-abstract-class-and-interface-in-java</link>
            <guid>https://www.codingshuttle.com/blogs/difference-between-abstract-class-and-interface-in-java</guid>
            <pubDate>Mon, 14 Jul 2025 14:58:59 GMT</pubDate>
            <description><![CDATA[Learn the difference between abstract classes and interfaces in Java with beginner-friendly examples. Understand use cases, key features, and when to use each in your code.]]></description>
            <content:encoded><![CDATA[<p>If you are diving into Java, there is a chance you will get confused between <strong>abstract classes</strong> and <strong>interfaces</strong> at some point. But you are not alone, these two concepts can be confusing at first for beginners. However, they are super important for writing clean, reusable code in Java’s object-oriented world.<br>In this article, I am going to explain the difference between abstract classes and interfaces in a simple and easier way. I have also included code snippets to help you understand the concepts better. So, let’s jump in.</p><h2>What is an Abstract Class?</h2><p>An <strong>abstract class</strong> in Java is a class that can’t be instantiated (you can’t create objects from it directly) and is meant to be extended by other classes. It’s like a half-finished blueprint—you can define some common behavior (methods) and properties (fields), but leave some parts for subclasses to fill in. Abstract classes can have both <strong>implemented methods</strong> (with actual code) and <strong>abstract methods</strong> (without code, just a signature) that subclasses must implement.</p><p>Abstract classes are great when you want to share common functionality across related classes while enforcing certain methods to be implemented by the subclasses.</p><p><strong>Example of an Abstract Class:</strong></p><pre><code class="language-java">abstract class Animal {
    String name; // Field
    Animal(String name) { // Constructor
        this.name = name;
    }
    void eat() { // Implemented method
        System.out.println(name + " is eating.");
    }
    abstract void makeSound(); // Abstract method (no body)
}

class Dog extends Animal {
    Dog(String name) {
        super(name);
    }
    @Override
    void makeSound() { // Must implement abstract method
        System.out.println(name + " says Woof!");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        dog.eat(); // Output: Buddy is eating.
        dog.makeSound(); // Output: Buddy says Woof!
    }
}</code></pre><p>Here, Animal is an abstract class with a shared method (eat) and an abstract method (makeSound) that Dog implements.</p><h2>What is an Interface?</h2><p>An <strong>interface</strong> in Java is like a contract that defines a set of methods a class must implement. It’s 100% abstract by nature (though modern Java allows default methods with implementation). You can’t instantiate an interface, and it’s used to define what a class <i>should do</i> without caring about <i>how</i> it does it. Interfaces are perfect for ensuring different classes follow the same structure, even if they’re unrelated.</p><p>Since Java doesn’t allow multiple inheritance for classes, interfaces let a class implement multiple behaviors by “implementing” multiple interfaces.</p><p><strong>Example of an Interface:</strong></p><pre><code class="language-java">interface Vehicle {
    void start(); // Abstract method
    default void stop() { // Default method (Java 8+)
        System.out.println("Vehicle stopped.");
    }
}

class Car implements Vehicle {
    @Override
    public void start() { // Must implement abstract method
        System.out.println("Car engine started.");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.start(); // Output: Car engine started.
        car.stop(); // Output: Vehicle stopped.
    }
}</code></pre><p>Here, Vehicle is an interface that Car implements, providing its own version of start and using the default stop method.</p><h2>Key Differences Between Abstract Class and Interface</h2><h3>1. Purpose</h3><p><strong>Abstract Class:</strong></p><p>Used when you want to share common code (like fields, constructors, or implemented methods) among related classes. It’s like a parent class that provides a partial implementation for its children.</p><p><strong>Interface:</strong></p><p>Used to define a standard or contract that unrelated classes can follow. It’s about ensuring specific behavior without dictating how it’s implemented (except for default methods).</p><h3>2. Inheritance</h3><p><strong>Abstract Class:</strong></p><p>A class can only extend <strong>one abstract class</strong> because Java doesn’t support multiple inheritance for classes. This limits flexibility if you need multiple behaviors.</p><p><strong>Interface:</strong></p><p>A class can implement <strong>multiple interfaces</strong>, which makes interfaces great for adding multiple roles or behaviors to a class.</p><p><strong>Example:</strong></p><pre><code class="language-java">interface Flyable {
    void fly();
}
interface Swimmable {
    void swim();
}
class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("Duck is flying.");
    }
    @Override
    public void swim() {
        System.out.println("Duck is swimming.");
    }
}</code></pre><p>Here, Duck can implement both Flyable and Swimmable interfaces, but it could only extend one abstract class.</p><h3>3. Fields</h3><p><strong>Abstract Class:</strong></p><p>Can have fields (instance variables) to store state, like name in the Animal example. These can be private, protected, or public.</p><p><strong>Interface:</strong></p><p>Can’t have instance fields. It can only have public static final variables (constants). This makes interfaces stateless by design.</p><p><strong>Example:</strong></p><pre><code class="language-java">abstract class Shape {
    protected String color = "Blue"; // Can have fields
}

interface Drawable {
    String DEFAULT_COLOR = "Red"; // Only constants
}</code></pre><h3>4. Methods</h3><p><strong>Abstract Class:</strong></p><p>Can have both <strong>abstract methods</strong> (no implementation) and <strong>concrete methods</strong> (with implementation). This lets you share common logic.</p><p><strong>Interface:</strong></p><p>Historically, interfaces only had abstract methods, but since Java 8, they can have <strong>default methods</strong> (with implementation) and <strong>static methods</strong>. Still, they’re mainly about defining method signatures.</p><p><strong>Example (Interface with Default Method):</strong></p><pre><code class="language-java">interface Printable {
    void print();
    default void preview() {
        System.out.println("Previewing document.");
    }
}</code></pre><h3>5. Constructors</h3><p><strong>Abstract Class:</strong></p><p>Can have constructors to initialize fields or set up the class. Subclasses call these using super().</p><p><strong>Interface:</strong></p><p>Can’t have constructors since they’re not meant to be instantiated or hold state.</p><h3>6. Access Modifiers</h3><p><strong>Abstract Class:</strong></p><p>Methods and fields can have any access modifier (public, private, protected, etc.), giving you flexibility in controlling access.</p><p><strong>Interface:</strong></p><p>All methods are implicitly public (unless they’re default or static), and all variables are public static final. You can’t make methods private (except private methods in Java 9+ for internal use).</p><h3>7. Use Case</h3><p><strong>Abstract Class:</strong></p><p>Best when you have a group of related classes that share common code and state. For example, Animal as an abstract class for Dog, Cat, etc.</p><p><strong>Interface:</strong></p><p>Best when you want unrelated classes to follow a common behavior or contract. For example, Flyable for Bird and Airplane.</p><h2>Quick Comparison Table</h2><figure class="table"><table><thead><tr><th>Feature</th><th>Abstract Class</th><th>Interface</th></tr></thead><tbody><tr><td><strong>Inheritance</strong></td><td>Single (extends one class)</td><td>Multiple (implements many interfaces)</td></tr><tr><td><strong>Fields</strong></td><td>Can have instance fields</td><td>Only constants (public static final)</td></tr><tr><td><strong>Methods</strong></td><td>Abstract + concrete methods</td><td>Abstract + default/static methods</td></tr><tr><td><strong>Constructors</strong></td><td>Can have constructors</td><td>No constructors</td></tr><tr><td><strong>Access Modifiers</strong></td><td>Any (public, private, etc.)</td><td>Implicitly public for methods</td></tr><tr><td><strong>Use Case</strong></td><td>Shared code for related classes</td><td>Common behavior for unrelated classes</td></tr></tbody></table></figure><h2>When to Use Abstract Class vs Interface</h2><ul><li><strong>Use Abstract Class when:</strong><ul><li>You want to share common code (fields, methods) among related classes.</li><li>You need to maintain state (instance variables).</li><li>You’re modeling a clear “is-a” relationship (e.g., Dog is an Animal).</li></ul></li><li><strong>Use Interface when:</strong><ul><li>You need a contract for unrelated classes to follow.</li><li>You want a class to implement multiple behaviors (e.g., Flyable and Swimmable).</li><li>You’re focusing on “what” a class should do, not “how.”</li></ul></li></ul><h2>Conclusion</h2><p>Understanding the difference between <strong>abstract classes</strong> and <strong>interfaces</strong> is crucial for writing clean, maintainable Java code. Abstract classes are perfect when you need to share common behavior and state across related classes, while interfaces are ideal for defining contracts that can be implemented by any class, regardless of its position in the class hierarchy.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>OOPs</category>
            <category>Object Oriented Programming</category>
            <category>Abstract Class Vs Interface</category>
            <category>Java Beginners Guide</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Diffrence_Between_Abstract_Class_And_Interface_Cover_cba953c6d3.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring vs Spring Boot : Understanding the Key Differences]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-vs-spring-boot-understanding-the-key-differences</link>
            <guid>https://www.codingshuttle.com/blogs/spring-vs-spring-boot-understanding-the-key-differences</guid>
            <pubDate>Mon, 14 Jul 2025 07:57:56 GMT</pubDate>
            <description><![CDATA[Confused between Spring and Spring Boot? This beginner-friendly guide breaks down their key differences, use cases, and code examples to help you decide which one to use.]]></description>
            <content:encoded><![CDATA[<p>If you are diving into Java development, you have heard of <strong>Spring</strong> and <strong>Spring Boot</strong>. They both sound similar, and it’s easy to get confused. But don’t worry I’m here to break it down for you in a simple and easier way.</p><p>In this article, I will explain what each one is, their key differences, and when to use them, with some code snippets to make things crystal clear. By the end, you will know exactly how Spring and Spring Boot fit into your Java projects.</p><h2><strong>What is Spring Framework?</strong></h2><p>Spring is a powerful, open-source framework for building Java applications, especially enterprise-level ones. It came onto the scene in 2003, created by Rod Johnson, and it’s been a game-changer for Java developers. Spring makes it easier to build robust, scalable apps by providing tools for things like dependency injection, managing databases, and handling web requests.</p><p>Think of Spring as a giant toolbox. It’s super flexible but requires you to set up and configure a lot of things manually, like wiring up components or setting up a server.</p><h3><strong>Key Features of Spring Framework</strong></h3><ol><li><strong>Dependency Injection (DI)</strong> : Promotes loose coupling and easier testing.</li><li><strong>Aspect-Oriented Programming (AOP)</strong> : Enables modularization of cross-cutting concerns.</li><li><strong>Data Access</strong> : Simplifies database access with JDBC, ORM, and transaction management.</li><li><strong>Web Framework</strong> : Supports MVC architecture for building web applications.</li></ol><h3><strong>Example of Spring Framework</strong></h3><pre><code class="language-java">// AppConfig.java
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example")
public class AppConfig implements WebMvcConfigurer {
    @Bean
    public MyController myController() {
        return new MyController();
    }
}

// MyController.java
@Controller
public class MyController {
    @GetMapping("/hello")
    @ResponseBody
    public String sayHello() {
        return "Hello from Spring!";
    }
}

// Main.java (used when deploying WAR to external Tomcat server)
public class Main {
    public static void main(String[] args) {
        // Deploy as WAR (web.xml + dispatcher servlet config)
    }
}</code></pre><p>In this example, you need to manually configure the<code>DispatcherServlet</code> and <code>web.xml</code> or use a <code>WebApplicationInitializer</code>. Additionally, you must deploy the application to an external server like Apache Tomcat.</p><h2><strong>What is Spring Boot?</strong></h2><p>Spring Boot is like Spring’s cooler, younger sibling. Introduced in 2014, it’s built on top of Spring but takes away a lot of the manual setup headaches. Spring Boot is all about <strong>convention over configuration</strong> and <strong>rapid development</strong>. It comes with pre-configured defaults, an embedded server (like Tomcat), and “starters” that make it easy to add features like databases or security.</p><p>If Spring is a toolbox, Spring Boot is a pre-assembled kit that lets you start building right away.</p><h3><strong>Key Features of Spring Boot</strong></h3><ol><li><strong>Auto-Configuration</strong> : Automatically configures beans based on dependencies.</li><li><strong>Embedded Server</strong> : Comes with Tomcat, Jetty, or Undertow by default.</li><li><strong>Starter Dependencies</strong> : Simplifies dependency management.</li><li><strong>Spring Boot Actuator</strong> : Provides built-in monitoring and management tools.</li></ol><h3><strong>Example of Spring Boot</strong></h3><pre><code class="language-java">// MyApplication.java
@SpringBootApplication
@RestController
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello from Spring Boot!";
    }
}</code></pre><p>In this example, Spring Boot automatically configures the embedded server and other components. You can run the application as a standalone JAR file without needing an external server.</p><h2><strong>Key Differences Between Spring and Spring Boot</strong></h2><p>Let’s break down the main differences between Spring and Spring Boot so you can see how they compare.</p><h3>1. Configuration</h3><p><strong>Spring:</strong></p><p>Spring requires a lot of manual configuration. You need to set up things like dependency injection, web servers, and database connections, often using XML files or Java-based configuration. This gives you tons of control but can be time-consuming and error-prone.</p><p><strong>Spring Boot:</strong></p><p>Spring Boot uses “auto-configuration.” It automatically sets up your app based on the dependencies you include (like adding a database or web server). You can still customize things, but the defaults get you up and running fast.</p><p><strong>Example (Database Setup in Spring):</strong></p><pre><code class="language-java">@Configuration
public class DatabaseConfig {
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/mydb");
        ds.setUsername("root");
        ds.setPassword("password");
        return ds;
    }
}</code></pre><p><strong>Spring Boot (Same Setup):</strong></p><pre><code class="language-plaintext"># application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver</code></pre><p>Spring Boot does the heavy lifting with just a few lines in a properties file.</p><h3>2. Boilerplate Code</h3><p><strong>Spring:</strong></p><p>With Spring, you write a lot of boilerplate code to set up things like controllers, services, or even a web server. This can make simple projects feel complex.</p><p><strong>Spring Boot:</strong></p><p>Spring Boot cuts down on boilerplate with its starters (pre-packaged dependencies) and annotations like @SpringBootApplication. You write less code to achieve the same result.</p><h3>3. Embedded Server</h3><p><strong>Spring:</strong></p><p>Spring doesn’t come with a built-in server. You need to configure an external server like Tomcat or Jetty, which means extra setup steps.</p><p><strong>Spring Boot:</strong></p><p>Spring Boot includes an embedded server (Tomcat by default). You just run your app with main(), and it’s ready to go—no external server needed.</p><p><strong>Example (Spring Boot’s main method):</strong></p><pre><code class="language-java">@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}</code></pre><p>This starts an embedded server automatically.</p><h3>4. Development Speed</h3><p><strong>Spring:</strong></p><p>Spring is great for complex, highly customized projects, but the setup time can slow you down. It’s like building a house from scratch—you have total control, but it takes effort.</p><p><strong>Spring Boot:</strong></p><p>Spring Boot is designed for speed. Its starters and auto-configuration let you prototype and deploy apps quickly, making it ideal for startups or rapid development.</p><h3>5. Dependency Management</h3><p><strong>Spring:</strong></p><p>You manually add and manage dependencies in your project (e.g., via Maven or Gradle). This gives you flexibility but requires you to know exactly what you need.</p><p><strong>Spring Boot:</strong></p><p>Spring Boot provides “starters” like spring-boot-starter-web or spring-boot-starter-data-jpa. These bundle all the dependencies you need for a specific feature, so you don’t have to hunt them down.</p><p><strong>Example (Maven Dependency for Spring Boot Web):</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p>This one line pulls in everything you need for a web app.</p><h2><strong>When To Use Spring and When To Use Spring Boot?</strong></h2><h3>1. Use Spring Framework when</h3><ul><li>You need full control over configuration.</li><li>You’re building large, complex applications with custom requirements.</li></ul><h3>2. Use Spring Boot when</h3><ul><li>You want to quickly develop stand-alone, production-ready applications</li><li>You are building microservices or REST APIs. and you want to reduce boilerplate code and configuration.</li></ul><h2>Conclusion</h2><p>Spring and Spring Boot are both awesome for Java development, but they serve different needs. Spring is like a custom-built car powerful and flexible, but you need to assemble it yourself. Spring Boot is like a ready-to-drive model with all the bells and whistles included, perfect for getting started fast.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring</category>
            <category>Spring Boot</category>
            <category>Spring vs Spring Boot</category>
            <category>Java Backend</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Spring_vs_Spring_Boot_d351a1a0dd.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Choosing The Best Programming Language to Learn in 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/choosing-the-best-programming-language-to-learn-in-2025</link>
            <guid>https://www.codingshuttle.com/blogs/choosing-the-best-programming-language-to-learn-in-2025</guid>
            <pubDate>Mon, 14 Jul 2025 07:54:22 GMT</pubDate>
            <description><![CDATA[Want to level up your coding skills in 2025? Learn which programming languages are in high demand with real-world use cases and beginner-friendly examples.]]></description>
            <content:encoded><![CDATA[<p>Hey there If you are reading this, you’re probably wondering, “What’s the best programming language to learn in 2025?” It’s a question I get all the time, especially from beginners or folks looking to level up their skills. With so many languages out there, it can feel overwhelming to pick one.</p><p>So In this blog, I’ll break down some of the top programming languages to learn in 2025, their use cases, and why they’re worth your time. I’ll keep it simple, throw in some code snippets where they fit.</p><h2>Why Choosing the Right Language Matters</h2><p>Picking a programming language isn’t just about what’s trendy, it’s about what aligns with your goals. Are you aiming for a web development gig? A data science career? Or maybe you want to build mobile apps? Each language has its strengths, and knowing where they shine helps you make a smart choice. Plus, in 2025, the tech world is evolving fast, AI, cloud computing, and web apps are hotter than ever, and some languages are better suited for these trends.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Choosing_The_Best_Programming_Language_to_Learn_in_2025_a7abf2b92b.png" alt="Choosing The Best Programming Language to Learn in 2025" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Choosing_The_Best_Programming_Language_to_Learn_in_2025_a7abf2b92b.png 156w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Choosing_The_Best_Programming_Language_to_Learn_in_2025_a7abf2b92b.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Choosing_The_Best_Programming_Language_to_Learn_in_2025_a7abf2b92b.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Choosing_The_Best_Programming_Language_to_Learn_in_2025_a7abf2b92b.png 1000w," sizes="100vw"><figcaption>Choosing The Best Programming Language to Learn in 2025</figcaption></figure><h2>Top Programming Languages to Learn in 2025</h2><h3>1. Python</h3><p>Python is&nbsp;<strong>a high-level, versatile, and popular programming language known for its readability and ease of use.</strong></p><p><strong>Why learn it in 2025?</strong></p><p>Python dominates in <strong>data science</strong>, <strong>machine learning</strong>, and <strong>AI</strong>, which are booming fields. It’s also used for web development (with frameworks like Django) and automation. Its simple syntax makes it a great first language, and its huge community means tons of tutorials and libraries.</p><p><strong>Use Cases:</strong></p><ul><li>Data analysis and visualization</li><li>Machine learning (e.g., TensorFlow, PyTorch)</li><li>Web development (Django, Flask)</li><li>Automation and scripting</li></ul><p><strong>Example:</strong></p><pre><code class="language-python"># Simple Python script to print a greeting
name = input("What’s your name? ")
print(f"Hello, {name}! Welcome to Python!")</code></pre><h3>2. JavaScript</h3><p>JavaScript is the king of web development. It runs in browsers and, thanks to Node.js, on servers too. It’s what makes websites interactive.</p><p><strong>Why learn it in 2025?</strong></p><p>If you want to build modern, interactive websites or web apps, JavaScript is a must. Frameworks like React, Vue, and Angular are in high demand, and Node.js lets you use JavaScript for backend work. In 2025, web apps are everywhere, so JavaScript skills are gold.</p><p><strong>Use Cases:</strong></p><ul><li>Frontend web development (React, Vue)</li><li>Backend development (Node.js, Express)</li><li>Mobile apps (React Native)</li><li>Real-time apps (e.g., chat, notifications)</li></ul><p><strong>Example:</strong></p><pre><code class="language-plaintext">// Simple JavaScript to change a webpage’s text
document.getElementById("greeting").innerText = "Hello from JavaScript!";.</code></pre><h3>3. Java</h3><p>Java is a robust, platform-independent language that’s been around since the ‘90s. It runs on the Java Virtual Machine (JVM), so it works on any device.</p><p><strong>Why learn it in 2025?</strong></p><p>Java is still a powerhouse for <strong>enterprise applications</strong>, <strong>backend systems</strong>, and <strong>Android development</strong>. Big companies like banks and e-commerce platforms rely on it for its speed and security. Frameworks like Spring Boot keep it relevant for modern APIs.</p><p><strong>Use Cases:</strong></p><ul><li>Enterprise software</li><li>Android app development</li><li>Backend APIs (Spring Boot)</li><li>Large-scale systems</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello from Java!");
    }
}</code></pre><h3>4. Go (Golang)</h3><p>Go, developed by Google, is a simple, fast language designed for modern systems. It’s known for its performance and ease of use.</p><p><strong>Why learn it in 2025?</strong></p><p>Go is gaining traction for <strong>cloud computing</strong> and <strong>microservices</strong>, thanks to its speed and simplicity. It’s used by companies like Uber and Dropbox for scalable systems. If you’re into DevOps or cloud tech, Go is a great pick.</p><p><strong>Use Cases:</strong></p><ul><li>Cloud-native apps (e.g., Kubernetes, Docker)</li><li>Microservices</li><li>Backend systems</li><li>Networking tools</li></ul><p><strong>Example:</strong></p><pre><code class="language-plaintext">package main
import "fmt"
func main() {
    fmt.Println("Hello from Go!")
}</code></pre><h3>5. Rust</h3><p>Rust is a systems programming language focused on safety and performance. It’s loved for preventing common bugs like memory errors.</p><p><strong>Why learn it in 2025?</strong></p><p>Rust is rising fast, especially for <strong>systems programming</strong>, <strong>blockchain</strong>, and <strong>performance-critical apps</strong>. It’s used in projects like Firefox and by companies like Microsoft and AWS. Its steep learning curve is worth it for cutting-edge tech roles.</p><p><strong>Use Cases:</strong></p><ul><li>Systems programming (e.g., operating systems)</li><li>WebAssembly for fast web apps</li><li>Blockchain and crypto</li><li>Game development</li></ul><p><strong>Example:</strong></p><pre><code class="language-plaintext">fn main() {
    println!("Hello from Rust!");
}</code></pre><h2>How to Choose the Right Language for You</h2><p>If you're a <strong>complete beginner</strong>, I’d suggest starting with <strong>Python</strong>. It's super beginner-friendly because of its clean and readable syntax. You can use it for everything from simple scripts to AI, automation, and web development. If you’re excited about <strong>building websites</strong>, <strong>JavaScript</strong> is a must-learn. It powers almost everything you see in the browser. <strong>Java</strong> is also a solid option for web development, especially on the backend. With frameworks like <strong>Spring Boot.</strong></p><p>If you are interested in <strong>cloud or microservices</strong> Try <strong>Go.</strong> and for <strong>systems programming</strong> learn <strong>Rust.</strong></p><h2>Conclusion</h2><p>Choosing the best programming language to learn in 2025 depends on your goals and interests. Python is a fantastic all-rounder, JavaScript rules the web, Java is great for enterprise, Go shines in cloud systems, and Rust is perfect for cutting-edge tech.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Best Programming Languages</category>
            <category>Programming Languages In 2025</category>
            <category>Python vs Java vs JavaScript</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/choosing_best_programming_lan_to_learn_cover2_d5045a3c91.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Java OOPs Interview Questions And Answers]]></title>
            <link>https://www.codingshuttle.com/blogs/java-oo-ps-interview-questions-and-answers</link>
            <guid>https://www.codingshuttle.com/blogs/java-oo-ps-interview-questions-and-answers</guid>
            <pubDate>Mon, 14 Jul 2025 07:51:59 GMT</pubDate>
            <description><![CDATA[Crack Java interviews with these 20 OOP interview questions and answers. Learn key concepts like inheritance, polymorphism, abstraction, and more with clear examples.]]></description>
            <content:encoded><![CDATA[<p>If you're preparing for Java interviews, one of the most important topics you’ll definitely come across is <strong>OOP - Object Oriented Programming</strong>. Almost everything in Java revolves around objects and classes. So understanding the core OOP concepts is a must for interview.</p><p>In this article, I’ve shared 20 <strong>commonly asked Java OOP interview questions</strong> in simple words. I have included code snippets where they make sense to clear things up. Let’s dive into the questions and answers.</p><h2>1. <strong>What is an object-oriented paradigm?</strong></h2><p>An object-oriented paradigm is a way of designing and writing code based on <strong>real-world objects</strong>.</p><p>Instead of just writing a bunch of functions, you create objects that have their own data (like properties) and behavior (like methods). Think of it as organizing your code like real-world objects—a car has wheels and can drive, a dog has a name and can bark.</p><p>It makes your code more modular, reusable, and easier to maintain. Java is built around this idea, using concepts like inheritance, polymorphism, and encapsulation to structure programs.</p><h2><strong>2. Why do we need OOPs?</strong></h2><p>OOP makes life easier for developers! Here’s why:</p><ul><li><strong>Modularity</strong>: You can break your program into smaller, self-contained objects, making it easier to manage.</li><li><strong>Reusability</strong>: Write a class once, and you can use it everywhere (like a blueprint).</li><li><strong>Scalability</strong>: Big projects are easier to handle because OOP organizes code logically.</li><li><strong>Maintainability</strong>: Fixing or updating code is simpler since changes are often limited to specific classes.</li><li><strong>Real-world modeling</strong>: It mimics how we think about the world (objects like cars, people, etc.), so it’s intuitive.</li></ul><p>Without OOP, you’d end up with messy, hard-to-read code—especially for large projects.</p><h2><strong>3. What is a Class in Java?</strong></h2><p>A <strong>class</strong> is like a blueprint for creating objects. It defines what an object can do (methods) and what data it holds (fields). For example, if you’re modeling a car, the class would define its properties (like color or speed) and behaviors (like drive or stop).</p><p>Here’s a simple example:</p><pre><code class="language-java">public class Car {
    String color; // Property
    int speed;

    void drive() { // Behavior
        System.out.println("Car is driving at " + speed + " km/h");
    }
}</code></pre><p>You can create multiple cars from this class, each with its own color and speed.</p><h2><strong>4. What is an Object in Java?</strong></h2><p>An <strong>object</strong> is an instance of a class. Think of the class as the blueprint and the object as the actual thing built from it. For example, if Car is the class, an object would be a specific car, like a red Toyota going 60 km/h.</p><p>Here’s how you create an object:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        Car myCar = new Car(); // Creating an object
        myCar.color = "Red";
        myCar.speed = 60;
        myCar.drive(); // Output: Car is driving at 60 km/h
    }
}</code></pre><h2>5. What are the Features of OOPs?</h2><p>OOP in Java revolves around four main pillars:</p><ol><li><strong>Encapsulation</strong>: Bundling data and methods together in a class and controlling access (like using private fields and public getters/setters).</li><li><strong>Inheritance</strong>: One class can inherit properties and methods from another (like a child inheriting traits from a parent).</li><li><strong>Polymorphism</strong>: Objects can take on multiple forms—like a method behaving differently based on the object calling it.</li><li><strong>Abstraction</strong>: Hiding complex details and showing only the necessary parts (like using an interface to simplify interactions).</li></ol><p>These make your code flexible, secure, and easier to work with.</p><h2>6. What is a Constructor and Types of Constructors?</h2><p>A <strong>constructor</strong> is a special method in a class that gets called when you create an object. It’s used to initialize the object’s properties. Constructors have the same name as the class and no return type.</p><p>There are two types of constructors:</p><ol><li><strong>Default Constructor</strong>: Automatically provided by Java if you don’t define any. It initializes fields to default values (like 0 or null).</li></ol><pre><code class="language-java">public class Student {
    String name;
    Student() { // Default constructor
        name = "Unknown";
    }
}</code></pre><ol><li><strong>Parameterized Constructor</strong>: Lets you pass values to initialize the object.</li></ol><pre><code class="language-java">public class Student {
    String name;
    int age;
    Student(String n, int a) { // Parameterized constructor
        name = n;
        age = a;
    }
}</code></pre><h2>7. What is a Static Variable?</h2><p>A <strong>static variable</strong> belongs to the class, not to any specific object. It’s shared across all instances of the class. For example, if you want to count how many objects of a class are created, you’d use a static variable.</p><p>Here’s an example:</p><pre><code class="language-java">public class Counter {
    static int count = 0; // Static variable
    Counter() {
        count++;
    }
    public static void main(String[] args) {
        Counter c1 = new Counter();
        Counter c2 = new Counter();
        System.out.println("Total objects: " + Counter.count); // Output: Total objects: 2
    }
}</code></pre><h2>8. What is the this Keyword in Java?</h2><p>The this keyword refers to the current object. It’s super useful when you need to differentiate between instance variables and parameters with the same name.</p><p>For example:</p><pre><code class="language-java">public class Person {
    String name;
    Person(String name) {
        this.name = name; // 'this.name' refers to the instance variable
    }
}</code></pre><p>Here, this.name refers to the class’s name field, while name is the parameter passed to the constructor.</p><h2>9. What is Constructor Chaining in Java?</h2><p><strong>Constructor chaining</strong> is when one constructor calls another constructor in the same class or a parent class. It’s a way to reuse code and avoid duplicating initialization logic.</p><p>You can chain constructors using this() (for the same class) or super() (for the parent class).</p><p>Example:</p><pre><code class="language-java">public class Employee {
    String name;
    int id;
    Employee() {
        this("Unknown", 0); // Calls parameterized constructor
    }
    Employee(String name, int id) {
        this.name = name;
        this.id = id;
    }
}</code></pre><p>Here, the default constructor calls the parameterized constructor to set default values.</p><h2>10. What is Inheritance?</h2><p><strong>Inheritance</strong> lets one class inherit the properties and methods of another class. The class that inherits is called the <strong>child</strong> or <strong>subclass</strong>, and the class it inherits from is the <strong>parent</strong> or <strong>superclass</strong>. It’s great for code reuse.</p><p>Example:</p><pre><code class="language-java">class Animal {
    void eat() {
        System.out.println("This animal eats food");
    }
}
class Dog extends Animal {
    void bark() {
        System.out.println("Dog barks");
    }
}</code></pre><p>A Dog object can use both eat() (from Animal) and bark().</p><h2>11. Why is Multiple Inheritance Not Supported in Java?</h2><p>Java doesn’t allow a class to inherit from multiple classes (multiple inheritance) to avoid complexity and ambiguity. For example, if two parent classes have methods with the same name, which one should the child class use? This is called the <strong>diamond problem</strong>.</p><p>Instead, Java supports multiple inheritance through <strong>interfaces</strong>. A class can implement multiple interfaces, which don’t cause the same conflicts since they only define method signatures.</p><h2>12. What is super in Java?</h2><p>The super keyword refers to the parent class. You can use it to:</p><ul><li>Call the parent class’s constructor (super()).</li><li>Access the parent class’s methods or fields.</li></ul><p>Example:</p><pre><code class="language-java">class Animal {
    String name = "Animal";
}
class Dog extends Animal {
    String name = "Dog";
    void printNames() {
        System.out.println(name); // Dog
        System.out.println(super.name); // Animal
    }
}</code></pre><p>Here, super.name accesses the parent class’s name field.</p><h2>13. What is Data Abstraction in Java?</h2><p><strong>Data abstraction</strong> is about hiding the complex implementation details and showing only the necessary parts to the user. In Java, you achieve this using <strong>abstract classes</strong> or <strong>interfaces</strong>.</p><p>For example, you don’t need to know how a List works internally to use it, you just call methods like add() or remove().</p><p>Example with an abstract class:</p><pre><code class="language-java">abstract class Shape {
    abstract void draw(); // Abstract method
}
class Circle extends Shape {
    void draw() {
        System.out.println("Drawing a circle");
    }
}</code></pre><p>The user only interacts with draw(), not the internal logic.</p><h2>14. What are the Differences Between Abstraction and Encapsulation?</h2><ul><li><strong>Abstraction</strong>: Focuses on hiding complexity and showing only what’s needed. It’s about the “what” (like interfaces or abstract classes).</li><li><strong>Encapsulation</strong>: Focuses on bundling data and methods together and controlling access (like using private fields with public getters/setters). It’s about the “how.”</li></ul><p>Think of abstraction as designing the interface of a car (steering, pedals), while encapsulation is hiding the engine’s inner workings.</p><h2>15. What is Polymorphism and Types of Polymorphism?</h2><p><strong>Polymorphism</strong> means “many forms.” It lets objects of different classes be treated as objects of a common parent class. There are two types:</p><ol><li><strong>Compile-time Polymorphism (Method Overloading)</strong>: Same method name, different parameters in the same class.</li></ol><pre><code class="language-java">class Calculator {
    int add(int a, int b) {
        return a + b;
    }
    int add(int a, int b, int c) {
        return a + b + c;
    }
}</code></pre><ol><li><strong>Runtime Polymorphism (Method Overriding)</strong>: A subclass provides its own implementation of a parent class’s method.</li></ol><pre><code class="language-java">class Animal {
    void sound() {
        System.out.println("Some sound");
    }
}
class Cat extends Animal {
    void sound() {
        System.out.println("Meow");
    }
}</code></pre><h2>16. Difference Between Method Overloading and Method Overriding in Java?</h2><ul><li><strong>Method Overloading</strong>:<ul><li>Happens in the <strong>same class</strong>.</li><li>Same method name, different parameters (number or type).</li><li>Resolved at <strong>compile time</strong>.</li><li>Example: add(int, int) and add(int, int, int).</li></ul></li><li><strong>Method Overriding</strong>:<ul><li>Happens in a <strong>subclass</strong>.</li><li>Same method name and signature as the parent class.</li><li>Resolved at <strong>runtime</strong>.</li><li>Example: Animal’s sound() overridden by Cat’s sound().</li></ul></li></ul><h2>17. What is the final Keyword in Java?</h2><p>The final keyword in Java is used to restrict modification. It can be applied to:</p><ul><li><strong>Variables</strong>: Makes them constant (can’t be changed once set).</li><li><strong>Methods</strong>: Prevents them from being overridden in subclasses.</li><li><strong>Classes</strong>: Prevents them from being extended.</li></ul><p>Example:</p><pre><code class="language-java">final class Immutable {
    final int value = 10; // Constant variable
    final void display() { // Can't be overridden
        System.out.println("Value: " + value);
    }
}</code></pre><p>If you try to extend Immutable or override display(), Java will throw an error.</p><h2>18. <strong>Can we make the Interface </strong><code><strong>final</strong></code><strong>?</strong></h2><p>No, we <strong>can’t make an interface </strong><code><strong>final</strong></code> in Java.</p><p>Because <code>final</code> means <strong>you can't extend or inherit it</strong>. But the whole point of an interface is to <strong>be implemented</strong> by other classes. If we make it final, no class would be able to implement it — which completely breaks the purpose of having an interface.</p><p>So yeah, the compiler won’t even allow it.</p><h2>19. <strong>What is a marker interface?</strong></h2><p>A marker interface is a <strong>special type of interface</strong> that <strong>doesn’t have any methods</strong>.</p><p>Its main job is to <strong>mark or tag</strong> a class so that the JVM or frameworks know something special about that class.</p><p>For example, <code>Serializable</code> is a marker interface. When you make your class implement it, Java knows that your object can be converted into a byte stream.</p><pre><code class="language-java">java
CopyEdit
public class Student implements Serializable {
    // no methods to implement
}</code></pre><p>So even though you don't write any methods, just by adding the interface, you're giving <strong>extra information</strong> about the class.</p><h2>20. What is Method Hiding in Java?</h2><p><strong>Method hiding</strong> happens when a subclass defines a static method with the same name and signature as a static method in the parent class. Unlike method overriding (which works with instance methods), the subclass method hides the parent class’s method, and the method called depends on the reference type, not the object type.</p><p>Example:</p><pre><code class="language-java">class Parent {
    static void show() {
        System.out.println("Parent's static method");
    }
}
class Child extends Parent {
    static void show() {
        System.out.println("Child's static method");
    }
}
class Main {
    public static void main(String[] args) {
        Parent.show(); // Output: Parent's static method
        Child.show();  // Output: Child's static method
    }
}</code></pre><h2>Conclusion</h2><p>That was a lot, but I hope it feels clearer now! Java’s OOP concepts are the backbone of the language, and understanding them will make you shine in interviews. Practice these questions, play around with the code snippets, and you’ll be ready to tackle any OOP question that comes your way.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java OOP Interview Questions</category>
            <category>Object Oriented Programming in Java</category>
            <category>Java OOPs Concepts with Examples</category>
            <category>Java Beginner Interview Preparation</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/20_Java_OO_Ps_Interview_Questions_611bd60e80.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Stack and Heap Memory In Java]]></title>
            <link>https://www.codingshuttle.com/blogs/stack-and-heap-memory-in-java</link>
            <guid>https://www.codingshuttle.com/blogs/stack-and-heap-memory-in-java</guid>
            <pubDate>Sat, 12 Jul 2025 08:06:04 GMT</pubDate>
            <description><![CDATA[Confused about stack vs heap memory in Java? This beginner-friendly guide explains the key differences with examples, diagrams, and real-life code.]]></description>
            <content:encoded><![CDATA[<p>If you are learning Java, you might have come across terms like <strong>stack memory</strong> and <strong>heap memory</strong> and wondered, "What's the difference?" You're not alone! These two play a big role in how Java stores and manages data during program execution.</p><p>In this blog, I will explain <strong>stack vs heap memory</strong> in a super simple way. For better understanding, no confusing terms. Just clear, beginner-friendly explanations with examples.</p><h2>What is Stack Memory?</h2><p>Stack memory is where <strong>Java stores method calls and local variables</strong>. It's fast, organized like a stack of plates (last in, first out), and gets cleaned up automatically when a method finishes.</p><p>Every time you call a method, a new block is added to the stack. When the method is done, its block is removed.</p><p><strong>Think of it like this:</strong></p><ul><li>You call a method: Java pushes it onto the stack.</li><li>The method finishes: Java pops it off the stack.</li></ul><p><strong>What goes into Stack Memory?</strong></p><ul><li>Primitive data types (like <code>int</code>, <code>char</code>, <code>boolean</code>, etc.) declared inside methods.</li><li>References to objects in the heap.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Stack_Memory_digram_d1fcd33c7f.png" alt="Stack Memory Diagram" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Stack_Memory_digram_d1fcd33c7f.png 136w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Stack_Memory_digram_d1fcd33c7f.png 437w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Stack_Memory_digram_d1fcd33c7f.png 656w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Stack_Memory_digram_d1fcd33c7f.png 874w," sizes="100vw"><figcaption>Stack Memory Diagram</figcaption></figure><h3>Example:</h3><pre><code class="language-java">public class StackExample {
    public static void main(String[] args) {
        int a = 10; // stored in stack
        int b = 20; // stored in stack
        int sum = add(a, b); // method call goes to stack
        System.out.println("Sum: " + sum);
    }

    public static int add(int x, int y) {
        return x + y; // x and y are also in stack
    }
}</code></pre><p>Here, all variables like <code>a</code>, <code>b</code>, <code>sum</code>, <code>x</code>, and <code>y</code> are stored in <strong>stack memory</strong>. And both method calls (<code>main</code> and <code>add</code>) sit on the stack during execution.</p><h2>What is Heap Memory?</h2><p>Heap memory is where <strong>Java stores objects and their instance variables</strong>. Unlike the stack, it's shared across the whole application and not cleaned up automatically when a method finishes. Instead, Java uses a <strong>Garbage Collector</strong> to remove unused objects from the heap.</p><p><strong>Think of it like this:</strong></p><ul><li>You create an object, it lives in the heap.</li><li>You stop using it then the Garbage Collector removes it (eventually).</li></ul><p><strong>What goes into Heap Memory?</strong></p><ul><li>Objects created using <code>new</code></li><li>Instance variables (fields) of objects</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Heap_Memory_diagram_38a02d6eb5.png" alt="Heap Memory Diagram.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Heap_Memory_diagram_38a02d6eb5.png 179w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Heap_Memory_diagram_38a02d6eb5.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Heap_Memory_diagram_38a02d6eb5.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Heap_Memory_diagram_38a02d6eb5.png 1000w," sizes="100vw"><figcaption>Heap Memory Diagram.png</figcaption></figure><h3>Example:</h3><pre><code class="language-java">class Car {
    String model; // stored in heap
}

public class HeapExample {
    public static void main(String[] args) {
        Car myCar = new Car(); // Car object is in heap
        myCar.model = "Tesla"; // 'model' also in heap
    }
}</code></pre><p>Here, the <code>Car</code> object and its field <code>model</code> are stored in <strong>heap memory</strong>. But the reference <code>myCar</code> is stored in <strong>stack memory</strong>, pointing to the object in the heap.</p><h2><strong>Differences Between Stack Memory and Heap Space in Java</strong></h2><p>The Stack and Heap has different similarities both in size and efficiency. In this section i will outline the core differences between the stack and Heap space in java.</p><ol><li>In the memory management, Stack follows the LIFO order while the Heap does not follows any order, as it is a dynamic data structure and it’s space complexity tends to be dynamic, allowing for flexible allocation and deallocation of memory.</li><li>The Stack is used for a single thread of execution while Heap is dynamic and robust is used by the entire application.</li><li>Whenever an object is invoked or created, it’s stored automatically into the Heap memory, while the stack memory contains the local variables and reference to the new object created.</li></ol><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Stack_Heap_Diagram_Excel_Draw_0e59d37aa9.png" alt="Stack And Heap Memory Diagram" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Stack_Heap_Diagram_Excel_Draw_0e59d37aa9.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Stack_Heap_Diagram_Excel_Draw_0e59d37aa9.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Stack_Heap_Diagram_Excel_Draw_0e59d37aa9.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Stack_Heap_Diagram_Excel_Draw_0e59d37aa9.png 1000w," sizes="100vw"><figcaption>Stack And Heap Memory Diagram</figcaption></figure><h2>Stack vs Heap - Quick Comparison</h2><figure class="table"><table><thead><tr><th>Feature</th><th>Stack Memory</th><th>Heap Memory</th></tr></thead><tbody><tr><td>Used for</td><td>Method calls, local variables</td><td>Objects and their fields</td></tr><tr><td>Memory size</td><td>Small</td><td>Large</td></tr><tr><td>Access speed</td><td>Faster</td><td>Slower</td></tr><tr><td>Auto-cleanup</td><td>Yes (when method ends)</td><td>No (Garbage Collected)</td></tr><tr><td>Location</td><td>Thread-specific (each thread has its own)</td><td>Shared across all threads</td></tr></tbody></table></figure><h2>Conclusion</h2><p>in short, Stack = short-term, fast, and method-focused and Heap = long-term, object-focused, and managed by Java's Garbage Collector, I hope this article made stack and heap memory easy to understand.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>Stack Memory</category>
            <category>Heap Memory</category>
            <category>Stack Vs Heap</category>
            <category>Memory Management In Java</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Stack_and_Heap_Memory_In_Java_33c1781329.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Java vs JavaScript: Key Differences and Use Cases]]></title>
            <link>https://www.codingshuttle.com/blogs/java-vs-java-script-key-differences-and-use-cases</link>
            <guid>https://www.codingshuttle.com/blogs/java-vs-java-script-key-differences-and-use-cases</guid>
            <pubDate>Sat, 12 Jul 2025 06:48:55 GMT</pubDate>
            <description><![CDATA[Confused between Java and JavaScript? Discover the key differences, real-world use cases, code examples, and when to use each language in modern development.]]></description>
            <content:encoded><![CDATA[<p><strong>Java</strong> and <strong>JavaScript</strong> both sound similar, are they the same thing? If you've ever thought this question, you're not alone. They may have similar names, but these two languages serve entirely different purposes. The confusion between these languages is understandable, especially for beginners.</p><p>So in this article, i have explained <strong>key differences</strong> between <strong>Java</strong> and <strong>JavaScript</strong> along with <strong>code snippets</strong> wherever needed. By the end, you’ll clearly understand the exact difference and know when to use <strong>Java</strong> or <strong>JavaScript</strong>.</p><h2>What is Java?</h2><p>Java is a powerful, statically typed programming language that is used mostly for building backend applications, Android apps, and large enterprise systems. It was developed by Sun Microsystems in 1995 and is now owned by Oracle.</p><p>Java code is compiled into bytecode which runs on the Java Virtual Machine (JVM). This makes it platform-independent, meaning you can write code once and run it anywhere.</p><p><strong>Simple Example:</strong></p><pre><code class="language-java">public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello from Java");
    }
}</code></pre><h2>What is JavaScript?</h2><p>JavaScript is a dynamic, interpreted programming language mainly used to build interactive websites. It was created in 1995 by Brendan Eich and runs directly in web browsers or on the server using Node.js.</p><p>Unlike Java, JavaScript doesn't need compilation. You write and run the code instantly, which makes it great for quick development.</p><p><strong>Simple Example:</strong></p><pre><code class="language-plaintext">console.log("Hello from JavaScript");</code></pre><h2>Key Differences Between Java and JavaScript</h2><h3>1. Compilation vs Interpretation</h3><p><strong>Java:</strong></p><p>Java is a compiled language. This means before your code can run, it needs to be converted into a special format called <i>bytecode</i> using something called a compiler. That bytecode runs on the JVM (Java Virtual Machine), which makes it possible to run the same Java code on any machine. So yeah, it's fast, reliable, and great for big applications.</p><p><strong>JavaScript:</strong></p><p>JavaScript is usually interpreted, which means the browser or runtime (like Node.js) reads and runs the code on the spot. You don’t need to compile it. It’s super handy for writing quick scripts or frontend features. Modern engines do some optimizations under the hood, but you can think of it as running live as you write.</p><h3>2. Typing System</h3><p><strong>Java:</strong> Java uses static typing. Basically, when you create a variable, you have to tell Java what type it is — like a <code>String</code>, <code>int</code>, or <code>boolean</code>. And once it’s set, you can’t change the type. This makes Java code more strict but helps avoid a lot of errors early on.</p><pre><code class="language-java">String name = "Alice"; // Java - Static typing</code></pre><p><strong>JavaScript:</strong></p><p>JavaScript is way more flexible — it uses dynamic typing. You can create a variable and change its type later. For example, a variable can start with a string and later hold a number. It's quick and easy, but sometimes this can lead to unexpected bugs if you're not careful.</p><pre><code class="language-plaintext">let name = "Alice";
name = 25; // JavaScript - Dynamic typing</code></pre><h3>3. Execution Environment</h3><p><strong>Java:</strong></p><p>Java doesn’t run directly on your computer like regular software. It needs the JVM (Java Virtual Machine). The cool part is once you write and compile your Java code, you can run it anywhere the JVM is installed. That’s why Java is called “write once, run anywhere.”</p><p><strong>JavaScript:</strong></p><p>JavaScript runs mostly in browsers — like Chrome, Firefox, etc. That’s why it’s a big part of web development. But thanks to tools like Node.js, you can now run JavaScript on servers too, not just browsers.</p><h3>4. Use Cases</h3><p><strong>Java:</strong></p><p>Java is great for building backend systems, Android apps, and big enterprise software. Companies love it for stuff that needs to be fast, secure, and reliable like banking systems or large-scale web platforms.</p><p><strong>JavaScript:</strong></p><p>JavaScript is the go-to language for building interactive websites. Want to make buttons clickable, forms dynamic, or data update without reloading the page? JavaScript does that. And with things like Node.js, you can even use it to build backend services too.</p><h2>When to Use Java</h2><p>Use Java when you’re working on things like backend services or APIs especially with frameworks like Spring Boot. It’s also the main language for building Android apps, so if mobile is your focus, Java is a solid choice.</p><p>Java is known for being fast, secure, and stable, which makes it perfect for large-scale projects like banking systems, e-commerce platforms, or any software used in big companies. If you're working in a corporate environment, chances are you'll run into Java a lot.</p><p>Choose Java if :</p><ul><li><strong>You're building high-performance backend systems</strong></li><li><strong>You need strong typing and compile-time error checking</strong></li><li><strong>You're developing Android applications</strong></li><li><strong>You're working in enterprise environments</strong></li></ul><h2>When to Use JavaScript</h2><p>Go for JavaScript when you’re building websites or anything users interact with directly in the browser. It’s the language of the web, so whether you're adding buttons, animations, or live data JavaScript makes the page come alive.</p><p>It’s also great for real-time apps like chats, notifications, or anything that updates without reloading the page. And if you’re into full-stack development, you can even use JavaScript on both the frontend and backend (with Node.js), which helps speed up development and keeps your codebase consistent.</p><p>Choose JavaScript if :</p><ul><li><strong>You're building interactive web applications</strong></li><li><strong>You want rapid prototyping and development</strong></li><li><strong>You're working with modern web technologies</strong></li><li><strong>You want to use Node.js for server-side development</strong></li></ul><h2>REST API Example</h2><h3>Java - Spring Boot</h3><pre><code class="language-java">@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{id}")
    public ResponseEntity&lt;String&gt; getUser(@PathVariable int id) {
        return ResponseEntity.ok("User ID: " + id);
    }

    @PostMapping
    public ResponseEntity&lt;String&gt; createUser(@RequestBody String name) {
        return ResponseEntity.status(HttpStatus.CREATED).body("User created: " + name);
    }
}</code></pre><h3>JavaScript - Express.js</h3><pre><code class="language-plaintext">const express = require("express");
const app = express();
app.use(express.json());

app.get("/api/users/:id", (req, res) =&gt; {
    res.send(`User ID: ${req.params.id}`);
});

app.post("/api/users", (req, res) =&gt; {
    res.status(201).send(`User created: ${req.body.name}`);
});

app.listen(3000, () =&gt; console.log("Server started"));</code></pre><h2>Object-Oriented Programming (OOP)</h2><h3>Java Example</h3><pre><code class="language-java">public class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog says Woof!");
    }
}</code></pre><h3>JavaScript Example</h3><pre><code class="language-plaintext">class Animal {
    makeSound() {
        console.log("Animal makes a sound");
    }
}

class Dog extends Animal {
    makeSound() {
        console.log("Dog says Woof!");
    }
}</code></pre><h2>Conclusion</h2><p>Java and JavaScript are both amazing, but they shine in different areas. Java is strong, safe, and great for building big things. JavaScript is flexible, fast, and perfect for building modern, interactive web apps. Now that you know the difference, you can choose the right tool for your next project.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>JavaScript</category>
            <category>Java Vs JavaScript</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Java_Vs_Java_Script_f431f0fa68.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[100 Spring Boot Interview Questions with Answers for 2 to 5 Years Experienced Java Developers]]></title>
            <link>https://www.codingshuttle.com/blogs/100-spring-boot-interview-questions-with-answers-for-2-to-5-years-experienced-java-developers</link>
            <guid>https://www.codingshuttle.com/blogs/100-spring-boot-interview-questions-with-answers-for-2-to-5-years-experienced-java-developers</guid>
            <pubDate>Fri, 11 Jul 2025 04:40:25 GMT</pubDate>
            <description><![CDATA[Master your Spring Boot interviews with this comprehensive guide. It includes 100 most commonly asked Spring Boot interview questions and answers.]]></description>
            <content:encoded><![CDATA[<p>When I started preparing for Spring Boot interviews, I was totally confused because too many topics, too many resources, and I don't know know where to start. So I decided to solve that problem for myself and for others.</p><p>I have created this article with <strong>100 most commonly asked Spring Boot interview questions</strong> written in <strong>very simple language</strong>. These questions are perfect if you're preparing for a backend developer role, especially in <strong>microservices</strong> projects.</p><h3>⇒ Before You Start – Read This First</h3><ul><li>All questions and answers are written in plain English. No complicated words. Perfect for quick learning and revision.</li><li>Where needed, I have added short code snippets that help you understand how things work in a practical way.</li><li>The questions start with simple basics and slowly move toward advanced topics, so you can learn step by step.</li><li>This guide is helpful for:<ul><li>Java developers new to Spring Boot</li><li>Interns and freshers</li><li>Backend developers with 0–3 years of experience</li></ul></li><li>Don’t just read — also <strong>practice these concepts in your own projects</strong>. That’s the best way to remember and understand them better.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/100_spring_boot_interview_questions_a9fb2b5ca7.png" alt="100 spring boot interview questions" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_100_spring_boot_interview_questions_a9fb2b5ca7.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_100_spring_boot_interview_questions_a9fb2b5ca7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_100_spring_boot_interview_questions_a9fb2b5ca7.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_100_spring_boot_interview_questions_a9fb2b5ca7.png 1000w," sizes="100vw"><figcaption>100 spring boot interview questions</figcaption></figure><h3><strong>1. Explain the concept of "convention over configuration" in Spring Boot.</strong></h3><p>Spring Boot uses the idea of "convention over configuration" to make development easier. Instead of asking you to write long configuration files, it provides default settings based on common use cases. This means if you follow standard project structure and naming, Spring Boot will automatically configure many things for you. You can still customize if needed, but in most cases, the default settings just work.</p><p><i>Example:</i></p><p>If you place your controller classes inside a specific package, Spring Boot will automatically scan and register them, no need to manually define each one.</p><h3><strong>2. What is the difference between Spring and Spring Boot?</strong></h3><ul><li><strong>Spring Framework</strong> is a powerful tool to build Java applications, but it needs a lot of setup — like XML or Java-based configuration, server setup, dependency management, etc.</li><li><strong>Spring Boot</strong> is built on top of Spring and removes that extra setup work. It uses auto-configuration, built-in servers (like Tomcat), and ready-to-use starter dependencies to help you create applications faster.</li></ul><p><strong>In short:</strong> Spring gives you tools, Spring Boot gives you a complete toolkit with default setup to start quickly.</p><h3><strong>3. How does Spring Boot simplify the development of Java applications?</strong></h3><p>Spring Boot helps developers by handling most of the setup automatically. Here's how:</p><ul><li><strong>Auto-configuration</strong>: It configures beans automatically based on the libraries you include.</li><li><strong>Starter dependencies</strong>: Just add one starter (like <code>spring-boot-starter-web</code>) and it brings everything you need to build web apps.</li><li><strong>Embedded servers</strong>: No need to install Tomcat or Jetty separately — they come built-in.</li><li><strong>Production-ready features</strong>: With tools like <strong>Spring Boot Actuator</strong>, you get health checks, metrics, and more.</li><li><strong>Developer tools</strong>: Features like hot-reloading (DevTools) make development faster and smoother.</li></ul><h3><strong>4. What are the various ways to create a Spring Boot application?</strong></h3><ol><li><strong>Spring Initializr (</strong><a href="https://start.spring.io"><strong>https://start.spring.io</strong></a><strong>)</strong><ul><li>A web-based tool where you choose project type, dependencies, and download a ready-to-run project.</li></ul></li><li><strong>Spring Boot CLI</strong><ul><li>A command-line tool to quickly run Groovy-based Spring Boot apps.</li></ul></li><li><strong>Manual Setup</strong><ul><li>You can create a Maven or Gradle project and add Spring Boot dependencies manually.</li></ul></li></ol><p>Most developers prefer Spring Initializr because it’s simple and fast.</p><h3><strong>5. What is the role of the @SpringBootApplication annotation?</strong></h3><p><code>@SpringBootApplication</code> is a shortcut annotation that combines three key annotations:</p><ul><li><code>@Configuration</code> – marks the class as a source of bean definitions.</li><li><code>@EnableAutoConfiguration</code> – enables Spring Boot’s auto-configuration feature.</li><li><code>@ComponentScan</code> – tells Spring to scan the current package and its sub-packages for components like controllers, services, etc.</li></ul><p>So when you use <code>@SpringBootApplication</code>, you don’t need to write all three separately. It bootstraps the app and sets up everything you need to start.</p><h3><strong>6. Explain the concept of auto-configuration in Spring Boot.</strong></h3><p>Auto-configuration is one of the most useful features in Spring Boot. It tries to automatically configure your application based on the libraries you have on your classpath.</p><p>For example, if Spring Boot finds the <code>spring-boot-starter-data-jpa</code> dependency and a database like H2 or MySQL in your project, it will automatically configure a <code>DataSource</code>, JPA-related beans, and more — without you writing any configuration.</p><p>It works behind the scenes using <code>@Conditional</code> annotations and checks what classes or beans are present before applying default settings.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/autoconfigurations_da72ecfc03.png" alt="Autoconfigurations" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_autoconfigurations_da72ecfc03.png 195w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_autoconfigurations_da72ecfc03.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_autoconfigurations_da72ecfc03.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_autoconfigurations_da72ecfc03.png 1000w," sizes="100vw"><figcaption>Autoconfigurations</figcaption></figure><h3><strong>7. How does Spring Boot handle dependency management?</strong></h3><p>Spring Boot simplifies dependency management using <strong>starter dependencies</strong>. These are pre-defined sets of libraries bundled together for common tasks.</p><p>For example:</p><ul><li><code>spring-boot-starter-web</code> includes everything needed to build a REST API (Spring MVC, Jackson, embedded Tomcat, etc.).</li><li><code>spring-boot-starter-data-jpa</code> brings in Hibernate, JPA API, and a database driver (like H2 for development).</li></ul><p>Also, Spring Boot uses a <strong>parent POM</strong> (in Maven) to manage compatible versions of libraries, so you don’t have to worry about version conflicts.</p><h3><strong>8. What is the purpose of the application.properties or application.yml file?</strong></h3><p>Used for <strong>externalized configuration</strong> of:</p><ul><li>DB connection</li><li>Logging</li><li>Server port</li><li>Custom application settings</li></ul><h3><strong>9. How can you override the default properties in Spring Boot?</strong></h3><p>You can override default settings in multiple ways:</p><ol><li><code>application.properties</code> or <code>application.yml</code></li><li>Environment variables</li><li>Command-line arguments (like <code>-server.port=8081</code>)</li><li>Programmatically using <code>SpringApplication.setDefaultProperties()</code></li></ol><p>Spring Boot follows a priority order. The general rule is:</p><p><strong>Command-line &gt; Environment variables &gt; application.properties/yml &gt; Default values</strong></p><h3><strong>10. What is the purpose of the @Autowired annotation in Spring Boot?</strong></h3><p><code>@Autowired</code> is used for <strong>dependency injection</strong>, which means Spring will automatically create and inject required objects (beans) for you.</p><p>You can use <code>@Autowired</code> in:</p><ul><li><strong>Fields</strong></li><li><strong>Constructors</strong> (recommended)</li><li><strong>Setters</strong></li></ul><p>For example, if you have a <code>UserService</code> bean and another class needs it, you just add <code>@Autowired</code> and Spring will handle the wiring — no need to <code>new</code> the object manually.</p><h3><strong>11. Explain the concept of profiles in Spring Boot.</strong></h3><p>Spring Boot <strong>profiles</strong> help you manage different configurations for different environments — like development, testing, or production.</p><p>Each profile can have its own set of settings and beans. This way, you don’t have to change your main code when switching environments.</p><p><strong>Example:</strong></p><ul><li><code>application-dev.properties</code> for development</li><li><code>application-prod.properties</code> for production</li></ul><p>When you activate a profile, Spring Boot will load the related properties file and beans automatically.</p><h3><strong>12. How can you enable a specific profile in Spring Boot?</strong></h3><p>You can activate a profile in several ways:</p><ol><li>In <code>application.properties</code> or <code>application.yml</code>:</li></ol><pre><code class="language-java">spring.profiles.active=dev</code></pre><ol><li>As a command-line argument when starting the app:</li></ol><pre><code class="language-java">java -jar app.jar --spring.profiles.active=prod</code></pre><ol><li>As an environment variable:</li></ol><pre><code class="language-java">SPRING_PROFILES_ACTIVE=test</code></pre><p>Once a profile is active, Spring Boot loads the matching config and beans for that profile.</p><h3><strong>13. How does Spring Boot support the creation of RESTful web services?</strong></h3><p>Spring Boot makes it easy to create REST APIs using Spring MVC. Here's how:</p><ul><li>Use <code>@RestController</code> to create REST controllers (which return JSON/XML by default).</li><li>Use annotations like:<ul><li><code>@GetMapping</code>, <code>@PostMapping</code>, <code>@PutMapping</code>, <code>@DeleteMapping</code> for endpoints</li><li><code>@PathVariable</code> to extract values from URLs</li><li><code>@RequestParam</code> to read query parameters</li></ul></li><li>Supports <strong>content negotiation</strong> (returns data in requested format)</li><li>Integrates easily with tools like <strong>Swagger/OpenAPI</strong> for API documentation</li><li>Supports custom <strong>exception handling</strong> using <code>@ControllerAdvice</code></li></ul><h3><strong>14. What is Spring Data JPA, and how does it integrate with Spring Boot?</strong></h3><p><strong>Spring Data JPA</strong> is a part of the Spring ecosystem that helps simplify database access using JPA (Java Persistence API).</p><p>Instead of writing SQL queries or boilerplate code, you just:</p><ul><li>Create <strong>Entity</strong> classes (for database tables)</li><li>Create <strong>Repository interfaces</strong> (like <code>JpaRepository</code> or <code>CrudRepository</code>)</li><li>Spring Boot auto-configures everything based on your setup</li></ul><p>Spring Boot automatically:</p><ul><li>Sets up JPA configurations</li><li>Connects to your database</li><li>Implements basic CRUD methods (like <code>save()</code>, <code>findById()</code>)</li></ul><p>This saves time and reduces repetitive code.</p><h3><strong>15. Explain the role of Spring Security in Spring Boot applications.</strong></h3><p>Spring Security provides a complete security solution for your application. It handles:</p><ul><li><strong>Authentication</strong> – verifying who the user is</li><li><strong>Authorization</strong> – checking what the user is allowed to do</li></ul><p>With Spring Boot, it’s easy to integrate Spring Security. It secures your REST endpoints or web pages by default and can support:</p><ul><li><strong>Form login</strong></li><li><strong>Basic Auth</strong></li><li><strong>JWT tokens</strong></li><li><strong>OAuth2 login (Google, GitHub, etc.)</strong></li></ul><p>It uses security filters and integrates smoothly with Spring MVC, allowing you to secure routes using annotations like <code>@PreAuthorize</code>.</p><h3><strong>16. How can you enable logging in a Spring Boot application?</strong></h3><p>Spring Boot uses <strong>Logback</strong> as the default logging framework. Logging is enabled automatically — you don’t need to add any extra setup to start using it.</p><p>To log messages in your code, you can use <strong>SLF4J</strong> (which works with Logback):</p><pre><code class="language-java">@Slf4j // Lombok annotation
public class MyService {
   public void doSomething() {
       log.info("Processing...");
       log.error("Something went wrong");
   }
}</code></pre><p>You can configure log settings (like log level or log file path) in <code>application.properties</code>:</p><pre><code class="language-plaintext">logging.level.org.springframework=DEBUG
logging.file.name=app.log</code></pre><p>You can also use a custom <code>logback.xml</code> file for advanced configurations.</p><h3><strong>17. What is the purpose of the @RestController annotation?</strong></h3><p><code>@RestController</code> is a shortcut for two annotations:</p><ul><li><code>@Controller</code> – tells Spring this class handles web requests</li><li><code>@ResponseBody</code> – tells Spring to return the response as JSON or XML (instead of rendering a view)</li></ul><p>So when you use <code>@RestController</code>, all your methods return data (usually JSON) directly to the client — perfect for building REST APIs.</p><p><strong>Example:</strong></p><pre><code class="language-java">@RestController
public class UserController {
    @GetMapping("/users")
    public List&lt;User&gt; getUsers() {
        return userService.getAllUsers();
    }
}</code></pre><h3><strong>18. How can you handle exceptions in a Spring Boot application?</strong></h3><p>Spring Boot allows you to handle exceptions in a clean and flexible way:</p><ol><li><strong>Method-level handling</strong> using <code>@ExceptionHandler</code>:</li></ol><pre><code class="language-java">@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity&lt;String&gt; handleNotFound(ResourceNotFoundException ex) {
    return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}</code></pre><p><strong>Global handling</strong> using <code>@ControllerAdvice</code>:</p><p>This lets you manage exceptions for all controllers in one place.</p><pre><code class="language-java">@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity&lt;String&gt; handleAll(Exception ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error: " + ex.getMessage());
    }
}</code></pre><h3><strong>19. Explain the difference between @Component, @Service, and @Repository annotations.</strong></h3><p>All are Spring stereotypes:</p><ul><li><code>@Component</code> is generic</li><li><code>@Service</code> is used for business logic</li><li><code>@Repository</code> is for database access and enables exception translation</li></ul><h3><strong>20. What is the purpose of the @Transactional annotation in Spring Boot?</strong></h3><p><code>@Transactional</code> is used to manage <strong>database transactions</strong> automatically. It ensures that:</p><ul><li>If everything in the method runs fine, the changes are <strong>committed</strong> to the database.</li><li>If an exception happens, Spring will <strong>roll back</strong> the transaction to keep your data safe.</li></ul><p>You can use it at the method or class level:</p><pre><code class="language-java">@Transactional
public void transferMoney(Account from, Account to, BigDecimal amount) {
    debit(from, amount);
    credit(to, amount);
}</code></pre><p>It helps maintain <strong>ACID</strong> properties (Atomicity, Consistency, Isolation, Durability) in your database operations.</p><h3><strong>21. How does Spring Boot support database migrations?</strong></h3><p>Spring Boot supports automatic database schema management using tools like <strong>Flyway</strong> and <strong>Liquibase</strong>.</p><p>These tools allow you to write <strong>versioned SQL scripts</strong> (like <code>V1__create_table.sql</code>, <code>V2__add_column.sql</code>), and Spring Boot will run them in order when the application starts.</p><p>This helps:</p><ul><li>Keep your database schema up to date</li><li>Avoid manual changes in each environment</li><li>Track version history of schema changes</li></ul><p>To use Flyway:</p><pre><code class="language-xml">&lt;!-- In pom.xml --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.flywaydb&lt;/groupId&gt;
    &lt;artifactId&gt;flyway-core&lt;/artifactId&gt;
&lt;/dependency</code></pre><h3><strong>22. What is the role of Spring Boot Actuator?</strong></h3><p>Actuator provides <strong>production-ready monitoring</strong> features through endpoints like:</p><ul><li><code>/health</code> – app health</li><li><code>/info</code> – app metadata</li><li><code>/metrics</code> – performance metrics</li><li><code>/env</code>, <code>/loggers</code>, etc.</li></ul><p>You can also define custom indicators and endpoints.</p><h3><strong>23. How can you configure caching in a Spring Boot application?</strong></h3><p>Steps:</p><ol><li>Add a caching library</li></ol><pre><code class="language-xml">&lt;dependency&gt;
   &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
   &lt;artifactId&gt;spring-boot-starter-cache&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><ol><li>Use <code>@EnableCaching</code></li></ol><pre><code class="language-java">@EnableCaching
@SpringBootApplication
public class MyApp {}</code></pre><ol><li><strong>Use caching annotations</strong> on methods:</li></ol><ul><li><code>@Cacheable</code> – caches method result</li><li><code>@CachePut</code> – updates cache with new value</li><li><code>@CacheEvict</code> – removes cache entry</li></ul><ol><li>Configure properties in <code>application.properties</code> or <code>application.yml</code></li></ol><pre><code class="language-plaintext">spring.cache.type=ehcache</code></pre><h3><strong>24. Explain the concept of Bean scopes in Spring Boot.</strong></h3><p>Bean scopes define <strong>lifecycle and visibility</strong>:</p><ul><li><code>singleton</code> (default): one instance for app</li><li><code>prototype</code>: new instance per request</li><li><code>request</code>: one per HTTP request</li><li><code>session</code>: one per session</li><li><code>application</code>: shared in servlet context</li><li><code>websocket</code>: one per WebSocket session</li></ul><h3><strong>25. What is the purpose of the </strong><code><strong>@Value</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@Value</code> injects values from:</p><ul><li>Properties file</li><li>Environment variables</li><li>Command-line args</li></ul><p>Example:</p><pre><code class="language-java">@Value("${server.port}")
private int port;</code></pre><h3><strong>26. How can you enable Cross-Origin Resource Sharing (CORS) in a Spring Boot application?</strong></h3><p>CORS (Cross-Origin Resource Sharing) allows your frontend (like React or Angular) to call your backend API even if they are on different domains or ports.</p><p>You can enable CORS in two ways:</p><p><strong>Two ways:</strong></p><p><strong>1. Using </strong><code><strong>@CrossOrigin</strong></code><strong> annotation:</strong></p><pre><code class="language-java">@CrossOrigin(origins = "&lt;http://localhost:3000&gt;")
@RestController
public class MyController {
    @GetMapping("/api/data")
    public String getData() {
        return "Hello from backend!";
    }
}</code></pre><p><strong>2. Globally using </strong><code><strong>WebMvcConfigurer</strong></code><strong>:</strong></p><pre><code class="language-java">@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("&lt;http://localhost:3000&gt;")
                .allowedMethods("GET", "POST", "PUT", "DELETE");
    }
}</code></pre><h3><strong>27. Explain the concept of a starter dependency in Spring Boot.</strong></h3><p>A <strong>starter dependency</strong> is a convenient way to include a group of related libraries in your project.</p><p>For example:</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p>This single dependency brings in:</p><ul><li>Spring MVC</li><li>Jackson (for JSON)</li><li>Embedded Tomcat</li><li>Logging</li></ul><h3><strong>28. What is the purpose of the </strong><code><strong>@Async</strong></code><strong> annotation in Spring Boot?</strong></h3><p>The <code>@Async</code> annotation makes a method run <strong>in a separate thread</strong>, so it doesn’t block the main thread.</p><p>This is helpful when doing tasks like sending emails, processing files, or calling external APIs — things that can take time.</p><p>You must:</p><ul><li>Enable async support with <code>@EnableAsync</code></li><li>Configure a <code>TaskExecutor</code> if needed</li></ul><h3><strong>29. How does Spring Boot support the creation of WebSocket applications?</strong></h3><p>You can:</p><ul><li>Use Spring’s WebSocket API</li><li>Define handler classes using <code>WebSocketHandler</code></li><li>Annotate config class with <code>@EnableWebSocket</code></li><li>Integrate with SockJS for fallback support</li></ul><h3><strong>30. Explain the concept of conditional bean registration in Spring Boot.</strong></h3><p>Spring Boot allows you to create beans <strong>only when certain conditions are met</strong> using conditional annotations.</p><p>Some common conditional annotations:</p><ul><li><code>@ConditionalOnClass</code>: Bean is created only if a specific class is on the classpath.</li><li><code>@ConditionalOnMissingBean</code>: Creates a bean only if the same type is not already defined.</li><li><code>@ConditionalOnProperty</code>: Creates a bean only if a specific property exists or has a certain value.</li></ul><h3><strong>31. How can you schedule tasks in a Spring Boot application?</strong></h3><p>Spring Boot makes it easy to run tasks at regular intervals using the <strong>scheduling feature</strong>.</p><p><strong>Steps:</strong></p><ol><li><strong>Enable scheduling</strong> in your main or config class:</li></ol><pre><code class="language-java">@EnableScheduling
@SpringBootApplication
public class MyApp {}</code></pre><ol><li><strong>Use </strong><code><strong>@Scheduled</strong></code><strong> on any method</strong>:</li></ol><pre><code class="language-java">@Scheduled(fixedRate = 5000) // runs every 5 seconds
public void runTask() {
    System.out.println("Running scheduled task...");
}</code></pre><p>You can schedule tasks using:</p><ul><li><code>fixedRate</code> – time between method calls</li><li><code>fixedDelay</code> – time after method finishes</li><li><code>cron</code> – for custom scheduling like <code>@Scheduled(cron = "0 0 * * * *")</code> (every hour)</li></ul><p>Useful for tasks like backups, report generation, or sending emails.</p><h3><strong>32. What is the purpose of the </strong><code><strong>@RequestMapping</strong></code><strong> annotation?</strong></h3><p><code>@RequestMapping</code> is used to map <strong>HTTP requests</strong> to specific controller methods.</p><p>It can define:</p><ul><li>The <strong>URL path</strong> (<code>value</code>)</li><li>The <strong>HTTP method</strong> (<code>GET</code>, <code>POST</code>, etc.)</li><li>Optional <strong>parameters</strong>, <strong>headers</strong>, or <strong>consumes/produces</strong> types</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">@RequestMapping(value = "/users", method = RequestMethod.GET)
public List&lt;User&gt; getAllUsers() {
    return userService.findAll();
}</code></pre><p>Although <code>@RequestMapping</code> works for all HTTP methods, you can use shortcuts like <code>@GetMapping</code>, <code>@PostMapping</code>, etc., for better readability.</p><h3><strong>33. How can you enable HTTPS in a Spring Boot application?</strong></h3><p>Steps:</p><ol><li>Generate SSL certificate and and a <code>.p12</code> keystore.</li><li>Add these properties in <code>application.properties</code>:</li></ol><pre><code class="language-plaintext">server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=yourpass
server.ssl.key-store-type=PKCS12</code></pre><ol><li>Place the <code>keystore.p12</code> file inside your <code>resources</code> folder.</li></ol><p>Once done, your app will be available at <code>https://localhost:8443</code> with SSL enabled. This is important for securing sensitive data in transit.</p><h3><strong>34. Explain the concept of externalized configuration in Spring Boot.</strong></h3><p>Configuration values (like DB URL, ports, etc.) can be moved to external sources:</p><ul><li><code>application.properties</code></li><li>Environment variables</li><li>Command-line args</li><li>Config servers (in microservices)</li></ul><p>This enables easy environment-specific setups.</p><h3><strong>35. What is the purpose of the </strong><code><strong>@RestControllerAdvice</strong></code><strong> annotation?</strong></h3><p><code>@RestControllerAdvice</code> is a <strong>specialized annotation</strong> used to handle exceptions and shared logic for all REST controllers.</p><p>It combines:</p><ul><li><code>@ControllerAdvice</code> – to apply common behavior across multiple controllers</li><li><code>@ResponseBody</code> – so the response is returned as JSON/XML, not a view</li></ul><p><strong>Use cases:</strong></p><ul><li>Global exception handling</li><li>Adding common model attributes</li><li>Modifying response bodies</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity&lt;String&gt; handleNotFound(ResourceNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }
}</code></pre><p>This keeps your controller code clean and separates error-handling logic.</p><h3><strong>36. How does Spring Boot support testing of applications?</strong></h3><p>Spring Boot provides great support for <strong>unit testing</strong> and <strong>integration testing</strong> with built-in tools and annotations.</p><p>Some commonly used features:</p><ul><li><strong>Annotations</strong>:<ul><li><code>@SpringBootTest</code> – loads the full application context for integration testing</li><li><code>@WebMvcTest</code> – tests only the web layer (like controllers)</li><li><code>@DataJpaTest</code> – tests the JPA (database) layer</li></ul></li><li><strong>Mocking support</strong>:<ul><li><code>@MockBean</code> – create and inject mock beans</li><li>Combine with <strong>Mockito</strong> to simulate behaviors</li></ul></li><li><strong>Test utilities</strong>:<ul><li><code>TestRestTemplate</code> – to call real endpoints in integration tests</li><li><code>MockMvc</code> – to test controller layer without starting the full server</li></ul></li><li>Spring Boot also runs tests using <strong>embedded servers</strong>, so you don’t need to deploy your app externally to run full end-to-end tests.</li></ul><h3><strong>37. Explain the purpose of the </strong><code><strong>@PathVariable</strong></code><strong> annotation in Spring Boot.</strong></h3><p><code>@PathVariable</code> is used to extract values from the <strong>URL path</strong> and pass them into your controller method as parameters.</p><p>Example:</p><pre><code class="language-java">@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) { ... }</code></pre><h3><strong>38. What is the difference between </strong><code><strong>@ControllerAdvice</strong></code><strong> and </strong><code><strong>@RestControllerAdvice</strong></code><strong>?</strong></h3><p>Both are used to apply common behavior (like exception handling) across multiple controllers.</p><ul><li><code><strong>@ControllerAdvice</strong></code> – Used for <strong>MVC controllers</strong> that return views (like JSP, Thymeleaf).</li><li><code><strong>@RestControllerAdvice</strong></code> – Used for <strong>REST APIs</strong>, and it automatically includes <code>@ResponseBody</code>, so it returns <strong>JSON/XML</strong> responses.</li></ul><p>Use <code>@RestControllerAdvice</code> when building APIs, and <code>@ControllerAdvice</code> when working with web pages.</p><h3><strong>39. How can you enable Swagger documentation in a Spring Boot application?</strong></h3><p>Steps:</p><ol><li>Add Swagger dependencies.</li><li>Configure metadata (title, version, etc.)</li><li>Use annotations like <code>@Api</code>, <code>@ApiOperation</code></li><li>Access Swagger UI at <code>/swagger-ui.html</code></li></ol><h3><strong>40. What is the purpose of the </strong><code><strong>@RequestBody</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@RequestBody</code> is used to <strong>bind the HTTP request body</strong> (usually JSON or XML) to a Java object.</p><p>Example:</p><pre><code class="language-java">@PostMapping("/user")
public void createUser(@RequestBody User user) { ... }</code></pre><h3><strong>41. How does Spring Boot support message queuing?</strong></h3><p>Spring Boot supports <strong>message queues</strong> like <strong>RabbitMQ</strong> and <strong>Apache Kafka</strong> for building <strong>asynchronous</strong> and <strong>event-driven</strong> systems.</p><p>Key features:</p><ul><li>Add dependencies like:<ul><li><code>spring-boot-starter-amqp</code> (for RabbitMQ)</li><li><code>spring-kafka</code> (for Kafka)</li></ul></li><li>Use listeners to consume messages:</li></ul><pre><code class="language-java">@RabbitListener(queues = "order-queue")
public void receiveMessage(String message) {
    System.out.println("Received: " + message);
}</code></pre><pre><code class="language-java">@KafkaListener(topics = "user-topic")
public void listen(String data) {
    System.out.println("Kafka: " + data);
}</code></pre><ul><li>Spring Boot auto-configures connections based on what’s in the classpath and <code>application.properties</code>.</li></ul><p>Also, you can use Spring’s messaging abstractions like <code>Message</code>, <code>MessageChannel</code>, and <code>MessageConverter</code> to work with different formats.</p><h3><strong>42. What is the purpose of the </strong><code><strong>@Scheduled</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@Scheduled</code> is used to <strong>run methods on a schedule</strong> — like running a task every few seconds, minutes, or at specific times.</p><p>Example:</p><pre><code class="language-java">@Scheduled(fixedDelay = 5000)
public void runTask() { ... }</code></pre><p>Supports <code>fixedRate</code>, <code>fixedDelay</code>, and <code>cron</code>.</p><h3><strong>43. Explain the concept of Actuator endpoints in Spring Boot.</strong></h3><p>Spring Boot Actuator exposes <strong>endpoints</strong> that give useful information about the application’s health and internals.</p><p>Some commonly used endpoints:</p><ul><li><code>/actuator/health</code> – shows app health status</li><li><code>/actuator/info</code> – displays app info (like version, description)</li><li><code>/actuator/metrics</code> – CPU, memory, HTTP request metrics</li><li><code>/actuator/env</code> – view environment properties</li><li><code>/actuator/beans</code> – see all registered Spring beans</li><li><code>/actuator/loggers</code> – manage logging levels at runtime</li></ul><p><strong>To use Actuator:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-actuator&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p>You can also customize or secure these endpoints using your <code>application.properties</code>.</p><h3><strong>44. How can you configure connection pooling in a Spring Boot application?</strong></h3><p>Spring Boot uses <strong>HikariCP</strong> as the default <strong>connection pool</strong> for managing database connections efficiently.</p><p>You can configure pooling options in <code>application.properties</code>:</p><pre><code class="language-plaintext">spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.connection-timeout=30000</code></pre><p>You can also use Tomcat JDBC or DBCP2.</p><h3><strong>45. What is the difference between @ComponentScan and @EnableAutoConfiguration in Spring Boot?</strong></h3><p>Both annotations are important in a Spring Boot application, but they serve different purposes.</p><p><strong>@ComponentScan</strong></p><ul><li>Scans the project packages for Spring components.</li><li>Automatically detects classes annotated with:<ul><li><code>@Component</code></li><li><code>@Service</code></li><li><code>@Repository</code></li><li><code>@Controller</code></li></ul></li><li>Registers them as beans in the Spring container.</li></ul><p>Example:</p><pre><code class="language-java">@ComponentScan("com.example.service")</code></pre><p>This tells Spring to scan the <code>com.example.service</code> package for components.</p><p><strong>@EnableAutoConfiguration</strong></p><ul><li>Automatically configures Spring beans based on the libraries present in the classpath.</li><li>For example, if Spring Boot detects <code>spring-boot-starter-web</code>, it automatically configures:<ul><li>DispatcherServlet</li><li>Jackson</li><li>Embedded Tomcat</li></ul></li></ul><p>In short:</p><ul><li><strong>@ComponentScan → finds your code</strong></li><li><strong>@EnableAutoConfiguration → configures framework components automatically</strong></li></ul><p>Both are included inside <code>@SpringBootApplication</code>.</p><h3><strong>46. How does Spring Boot support internationalization and localization?</strong></h3><p>Spring Boot makes it easy to build apps that support <strong>multiple languages</strong> using <strong>internationalization (i18n)</strong>.</p><ul><li>Message bundles (<code>messages_en.properties</code>, <code>messages_fr.properties</code>)</li><li><code>MessageSource</code> bean configuration</li><li>Resolves locale using <code>Accept-Language</code> header</li></ul><p>Enables dynamic text based on user’s locale.</p><h3><strong>47. Explain the concept of a health indicator in Spring Boot Actuator.</strong></h3><p>A <strong>health indicator</strong> shows the status of a specific part of your app, like the database, disk space, or custom services.</p><p>These health indicators are part of the <code>/actuator/health</code> endpoint.</p><p>Spring Boot includes <strong>built-in health checks</strong>:</p><ul><li>Database connection (<code>DataSourceHealthIndicator</code>)</li><li>Disk space (<code>DiskSpaceHealthIndicator</code>)</li><li>RabbitMQ, Redis, etc.</li></ul><p>You can also create your own:</p><pre><code class="language-java">@Component
public class MyServiceHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        boolean isHealthy = checkSomething();
        return isHealthy ? Health.up().build() : Health.down()
        .withDetail("error", "Service is down").build();
    }
}</code></pre><h3><strong>48. What is the difference between @RequestParam and @PathVariable in Spring Boot?</strong></h3><p>Both annotations are used to extract values from an HTTP request, but they come from different parts of the URL.</p><h3>@PathVariable</h3><p>Used to get values from the <strong>URL path</strong>.</p><p>Example:</p><pre><code class="language-ruby">GET /users/10</code></pre><pre><code class="language-java">@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
    return userService.getUser(id);
}
</code></pre><p>Here <code>10</code> becomes the value of <code>id</code>.</p><h3>@RequestParam</h3><p>Used to read values from <strong>query parameters</strong>.</p><p>Example:</p><pre><code class="language-ruby">GET /users?id=10</code></pre><pre><code class="language-java">@GetMapping("/users")
public User getUser(@RequestParam Long id) {
    return userService.getUser(id);
}</code></pre><p><strong>Simple difference</strong></p><figure class="table"><table><thead><tr><th>Annotation</th><th>Source</th></tr></thead><tbody><tr><td><code>@PathVariable</code></td><td>URL path</td></tr><tr><td><code>@RequestParam</code></td><td>Query parameters</td></tr></tbody></table></figure><h3><strong>49. How can you enable request logging in a Spring Boot application?</strong></h3><p>To see <strong>incoming HTTP requests</strong> and debug better, you can enable request logging.</p><p><strong>Simple way:</strong></p><p>Add this to <code>application.properties</code>:</p><pre><code class="language-plaintext">logging.level.org.springframework.web=DEBUG</code></pre><p><strong>Advanced way (using Logback):</strong></p><p>Create a <code>logback-spring.xml</code> and configure logging pattern and levels.</p><p><strong>Third-party option:</strong></p><p>Use Spring Boot filters like <code>CommonsRequestLoggingFilter</code> for detailed logs:</p><pre><code class="language-java">@Bean
public CommonsRequestLoggingFilter logFilter() {
    CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
    filter.setIncludeQueryString(true);
    filter.setIncludePayload(true);
    filter.setMaxPayloadLength(10000);
    return filter;
}</code></pre><h3><strong>50. Explain the purpose of the </strong><code><strong>@ExceptionHandler</strong></code><strong> annotation in Spring Boot.</strong></h3><p><code>@ExceptionHandler</code> is used to <strong>catch and handle specific exceptions</strong> in your controller methods.</p><p><strong>Why?</strong> So your app doesn’t crash and you can send a proper response (like a 404 or custom error message).</p><p>Example:</p><pre><code class="language-java">@ExceptionHandler(MyException.class)
public ResponseEntity&lt;String&gt; handle(MyException ex) {
    return ResponseEntity.status(500).body("Error occurred");
}</code></pre><h3><strong>51. How does Spring Boot support asynchronous processing?</strong></h3><p>Spring Boot allows methods to run <strong>asynchronously</strong> in a separate thread using the <code>@Async</code> annotation. This helps improve performance by not blocking the main thread during long-running tasks (like sending emails or processing files).</p><ul><li><code>@Async</code> on methods</li><li><code>@EnableAsync</code> in config</li><li>Optional <code>TaskExecutor</code> bean for thread management</li></ul><p>Supports returning <code>CompletableFuture</code>, <code>Future</code>, <code>void</code>.</p><h3><strong>52. What is the purpose of the </strong><code><strong>@EnableAutoConfiguration</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@EnableAutoConfiguration</code> tells Spring Boot to <strong>automatically configure beans and settings</strong> based on the libraries present in the classpath.</p><p>For example:</p><ul><li>If Spring MVC is on the classpath, it sets up a web app.</li><li>If Spring Data JPA is present, it configures a datasource and JPA repositories.</li></ul><p>This saves a lot of manual configuration and helps you get started quickly.</p><h3><strong>53.What is Spring Boot DevTools and why is it used?</strong></h3><p>Spring Boot DevTools is a development tool that improves developer productivity by enabling faster development.</p><p>It provides features like:</p><ul><li><strong>Automatic restart</strong> when code changes</li><li><strong>Live reload</strong> in the browser</li><li><strong>Better development-time configuration</strong></li></ul><p>To enable DevTools, add the dependency:</p><pre><code class="language-xml">&lt;dependency&gt;
 &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
 &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p>When DevTools is enabled, Spring Boot automatically restarts the application whenever a class file changes.</p><p>This saves developers from restarting the application manually.</p><h3><strong>54. What is the difference between @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping?</strong></h3><p>These annotations are shortcut versions of <code>@RequestMapping</code> used for specific HTTP methods.</p><h3>@GetMapping</h3><p>Used to retrieve data.</p><p>Example:</p><pre><code class="language-java">@GetMapping("/users")</code></pre><h3>@PostMapping</h3><p>Used to create new data.</p><p>Example:</p><pre><code class="language-java">@PostMapping("/users")</code></pre><h3>@PutMapping</h3><p>Used to update existing data.</p><p>Example:</p><pre><code class="language-java">@PutMapping("/users/{id}")</code></pre><h3>@DeleteMapping</h3><p>Used to delete data.</p><p>Example:</p><pre><code class="language-java">@DeleteMapping("/users/{id}")</code></pre><p><strong>Summary</strong></p><figure class="table"><table><thead><tr><th>Annotation</th><th>HTTP Method</th><th>Purpose</th></tr></thead><tbody><tr><td>@GetMapping</td><td>GET</td><td>Fetch data</td></tr><tr><td>@PostMapping</td><td>POST</td><td>Create data</td></tr><tr><td>@PutMapping</td><td>PUT</td><td>Update data</td></tr><tr><td>@DeleteMapping</td><td>DELETE</td><td>Delete data</td></tr></tbody></table></figure><p>&nbsp;</p><h3><strong>55. What is the difference between CrudRepository and JpaRepository?</strong></h3><p>Both interfaces are part of Spring Data and help perform database operations.</p><h3>CrudRepository</h3><p>Provides basic CRUD operations like:</p><ul><li><code>save()</code></li><li><code>findById()</code></li><li><code>findAll()</code></li><li><code>delete()</code></li></ul><p>Example:</p><pre><code class="language-java">public interface UserRepository extends CrudRepository&lt;User, Long&gt; {
}</code></pre><h3>JpaRepository</h3><p>Extends <code>CrudRepository</code> and adds additional features such as:</p><ul><li>Pagination</li><li>Sorting</li><li>Batch operations</li></ul><p>Example:</p><pre><code class="language-java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {
}</code></pre><p><strong>Simple difference</strong></p><figure class="table"><table><thead><tr><th>Interface</th><th>Features</th></tr></thead><tbody><tr><td>CrudRepository</td><td>Basic CRUD operations</td></tr><tr><td>JpaRepository</td><td>CRUD + pagination + sorting</td></tr></tbody></table></figure><p>Most Spring Boot applications prefer <strong>JpaRepository</strong>.</p><h3><strong>56. How does Spring Boot handle security vulnerabilities like XSS and CSRF?</strong></h3><p>Spring Boot (with Spring Security) provides basic protections against common web vulnerabilities like:</p><ul><li><strong>XSS (Cross-Site Scripting):</strong><ul><li>By default, template engines like <strong>Thymeleaf</strong> escape user inputs.</li><li>You can also add security headers (e.g., <strong>Content-Security-Policy</strong>) to prevent script execution from untrusted sources.</li></ul></li><li><strong>CSRF (Cross-Site Request Forgery):</strong><ul><li>Spring Security automatically generates a <strong>CSRF token</strong> for every form and checks it on form submissions.</li><li>This prevents unauthorized commands from being executed on behalf of the user.</li></ul></li></ul><p><strong>Best practices for developers:</strong></p><ul><li>Always validate and sanitize user input.</li><li>Use HTTPS in production.</li><li>Don’t disable CSRF protection unless you know exactly why.</li></ul><h3><strong>57. What is the purpose of the </strong><code><strong>@Cacheable</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@Cacheable</code> is used to <strong>store the result of a method</strong> so that future calls with the same input don't need to run the method again — it just returns the cached value.</p><p>Example:</p><pre><code class="language-java">@Cacheable("users")
public User getUserById(Long id) { ... }</code></pre><p>Improves performance by avoiding repetitive computation or DB calls.</p><h3><strong>58. How can you handle file uploads in a Spring Boot application?</strong></h3><p>Spring Boot makes file upload easy using <code>MultipartFile</code>.</p><p><strong>Steps:</strong></p><ol><li><strong>Controller method:</strong></li></ol><pre><code class="language-java">@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
    // save or process the file
    return "Uploaded successfully!";
}</code></pre><ol><li><strong>Set size limits in </strong><code><strong>application.properties</strong></code><strong>:</strong></li></ol><pre><code class="language-plaintext">spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=10MB</code></pre><p>Spring Boot handles the rest — parsing multipart requests and converting uploaded files into <code>MultipartFile</code>.</p><p>You can also write files to disk or store them in a database/cloud storage.</p><h3><strong>59. Explain the concept of circuit breakers in Spring Boot.</strong></h3><p>A <strong>circuit breaker</strong> helps prevent your app from <strong>failing repeatedly</strong> when a downstream service (like an API or database) is not responding.</p><p>It works like this:</p><ul><li>If a service fails multiple times, the circuit <strong>opens</strong>, and further calls are <strong>blocked</strong> to avoid stress.</li><li>After some time, it enters a <strong>half-open</strong> state to test if the service is back.</li><li>If successful, it <strong>closes</strong> the circuit and resumes normal flow.</li></ul><p><strong>In Spring Boot</strong>, use <strong>Resilience4j</strong> (or Hystrix) for circuit breakers:</p><pre><code class="language-java">@CircuitBreaker(name = "inventoryService", fallbackMethod = "fallback")
public Product getInventory(Long id) {
    // call to external service
}</code></pre><p>This improves fault tolerance in <strong>microservice architectures</strong>.</p><h3><strong>60. What is the purpose of the </strong><code><strong>@ControllerAdvice</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@ControllerAdvice</code> is used to <strong>handle common logic</strong> across all controllers.</p><p>You can define:</p><ul><li><strong>Global exception handlers</strong> using <code>@ExceptionHandler</code></li><li><strong>Custom model attributes</strong> shared across multiple controllers using <code>@ModelAttribute</code></li><li><strong>Custom data binders</strong> with <code>@InitBinder</code></li></ul><h3><strong>61. What is Spring Boot CLI?</strong></h3><p>Spring Boot CLI (Command Line Interface) is a tool that allows developers to run Spring Boot applications quickly using simple commands.</p><p>It allows you to:</p><ul><li>Run Groovy-based Spring Boot scripts</li><li>Test small applications quickly</li><li>Prototype APIs without creating a full project</li></ul><p>Example command:</p><pre><code class="language-ruby">spring run app.groovy</code></pre><p>The CLI automatically downloads required dependencies and configures the application.</p><p>However, most developers today prefer <strong>Spring Initializr</strong> and Maven/Gradle projects.</p><h3><strong>62. What is the difference between application.properties and application.yml?</strong></h3><p>Both files are used to configure Spring Boot applications.</p><h3>application.properties</h3><p>Uses <strong>key-value format</strong>.</p><p>Example:</p><pre><code class="language-php">server.port=8081
spring.datasource.url=jdbc:mysql://localhost:3306/db</code></pre><h3>application.yml</h3><p>Uses <strong>YAML format</strong>, which is more readable for nested configurations.</p><p>Example:</p><pre><code class="language-php">server:
  port: 8081

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db</code></pre><p><strong>Difference</strong></p><figure class="table"><table><thead><tr><th>File</th><th>Format</th></tr></thead><tbody><tr><td>application.properties</td><td>key=value</td></tr><tr><td>application.yml</td><td>YAML structured format</td></tr></tbody></table></figure><p>Both work the same way, but <strong>YAML is cleaner for complex configurations</strong>.</p><h3><strong>63. Explain the concept of lazy initialization in Spring Boot.</strong></h3><p><strong>Lazy initialization</strong> means Spring creates a bean <strong>only when it’s first needed</strong>, instead of at application startup.</p><ul><li>Beans are created <strong>on first use</strong>, not at startup</li><li>Saves memory and improves <strong>startup time</strong></li><li>You can force eager init using <code>@Lazy(false)</code></li></ul><h3><strong>64. How can you configure a custom data source in Spring Boot?</strong></h3><p>If the default <code>spring.datasource.*</code> properties aren't enough, you can define a custom <code>DataSource</code> bean.</p><p>Steps:</p><ol><li>Add driver dependency</li><li>Create a config class with <code>@Bean</code> returning a <code>DataSource</code> (e.g., HikariDataSource)</li><li>Set properties like URL, username, password</li></ol><p>Example:</p><pre><code class="language-java">@Bean
public DataSource dataSource() {
    HikariConfig config = new HikariConfig();
    config.setJdbcUrl(...);
    return new HikariDataSource(config);
}</code></pre><h3><strong>65. What is the purpose of the </strong><code><strong>@Profile</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@Profile</code> is used to load <strong>beans or configuration only for specific environments</strong>, such as:</p><ul><li><code>dev</code> – for development</li><li><code>test</code> – for testing</li><li><code>prod</code> – for production</li></ul><p>Example:</p><pre><code class="language-java">@Profile("dev")
@Component
public class DevBean { ... }</code></pre><p>To activate a profile:</p><pre><code class="language-plaintext">profiles.active=dev</code></pre><p>This helps you run the same app with different settings in different environments — without changing code.</p><h3><strong>66. How does Spring Boot handle authentication and authorization?</strong></h3><p>Spring Boot uses <strong>Spring Security</strong> to provide both <strong>authentication</strong> (who you are) and <strong>authorization</strong> (what you're allowed to do).</p><ul><li>Authentication: Form login, JWT, OAuth2, DB, LDAP</li><li>Authorization: Role/permission-based access control</li><li>Declarative rules via annotations like <code>@PreAuthorize</code>, <code>@Secured</code></li></ul><h3><strong>67. What is the purpose of the </strong><code><strong>@Bean</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@Bean</code> is used to tell Spring, “Hey, create and manage this object as a bean.”</p><p>It’s commonly used inside a <code>@Configuration</code> class when you want to define <strong>custom logic</strong> for creating an object</p><p>Example:</p><pre><code class="language-java">@Bean
public MyService myService() {
    return new MyServiceImpl();
}</code></pre><h3><strong>68. How can you enable server-side validation in a Spring Boot application?</strong></h3><p>Server-side validation checks incoming data before it’s processed or saved. Spring Boot uses <strong>Hibernate Validator (JSR-380)</strong> under the hood.</p><p>Steps:</p><ol><li>Add <code>spring-boot-starter-validation</code></li><li>Use annotations like <code>@NotNull</code>, <code>@Size</code></li><li>Add <code>@Valid</code> or <code>@Validated</code> in controllers</li></ol><p>Example:</p><pre><code class="language-java">@PostMapping
public ResponseEntity&lt;?&gt; save(@Valid @RequestBody User user) { ... }</code></pre><h3><strong>69. Explain the concept of the Spring Boot Starter Parent.</strong></h3><p>The <strong>Spring Boot Starter Parent</strong> is a special <strong>Maven parent POM</strong> that provides:</p><ul><li>Default versions for dependencies</li><li>Plugin configs</li><li>Java version, encoding</li></ul><p>It reduces need for manual configuration.</p><h3><strong>70. What is the purpose of the </strong><code><strong>@ConfigurationProperties</strong></code><strong> annotation?</strong></h3><p><code>@ConfigurationProperties</code> is used to <strong>map values from </strong><code><strong>application.properties</strong></code><strong> or </strong><code><strong>application.yml</strong></code> to a Java class.</p><p>This is helpful when you want to group related settings.</p><p>Example:</p><pre><code class="language-java">@ConfigurationProperties(prefix="app")
public class AppConfig {
    private String name;
}</code></pre><p>Requires <code>@EnableConfigurationProperties</code> or be annotated with <code>@Component</code>.</p><h3><strong>71. How can you customize error handling in a Spring Boot application?</strong></h3><p>Spring Boot provides multiple ways to handle and customize errors so your users don’t see raw stack traces.</p><p>Options:</p><ul><li><code>@ControllerAdvice</code> with <code>@ExceptionHandler</code></li><li>Create a <code>CustomErrorController</code> for <code>/error</code></li><li>Customize <code>ErrorAttributes</code> or use <code>ErrorViewResolver</code></li></ul><h3><strong>72. What is the purpose of the </strong><code><strong>@ConditionalOnProperty</strong></code><strong> annotation?</strong></h3><p><code>@ConditionalOnProperty</code> tells Spring to <strong>only create a bean</strong> if a specific property exists and has a certain value.</p><p>Useful for <strong>feature toggles</strong> or enabling/disabling configs based on environment.</p><p>Example:</p><pre><code class="language-java">@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
@Bean
public FeatureBean featureBean() { ... }</code></pre><h3><strong>73. How does Spring Boot support hot reloading during development?</strong></h3><p>Spring Boot supports <strong>hot reloading</strong> using the <strong>DevTools</strong> module.</p><p>Via <strong>Spring Boot DevTools</strong>:</p><ul><li>Auto restarts app on classpath changes</li><li>Enables live reload (e.g., with browser plugin)</li></ul><p>Add this in <code>pom.xml</code>:</p><pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
  &lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;</code></pre><h3><strong>74. What is the purpose of the </strong><code><strong>@EnableScheduling</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@EnableScheduling</code> turns on <strong>Spring’s scheduling support</strong>.</p><p>Once enabled, you can run methods automatically using <code>@Scheduled</code>.</p><pre><code class="language-java">@EnableScheduling
@SpringBootApplication
public class App { ... }</code></pre><p>Without <code>@EnableScheduling</code>, scheduled methods will be ignored.</p><h3><strong>75. What is Spring Boot Admin?</strong></h3><p>Spring Boot Admin is a tool used to <strong>monitor and manage Spring Boot applications</strong>.</p><p>It provides a dashboard where you can see:</p><ul><li>Application health</li><li>Memory usage</li><li>Logs</li><li>Metrics</li><li>Active endpoints</li></ul><p>It uses Spring Boot Actuator to collect data from running applications.</p><p>Developers use Spring Boot Admin to monitor microservices in production environments.</p><h3><strong>76. Explain the concept of YAML configuration in Spring Boot.</strong></h3><p>YAML (<code>application.yml</code>) is an alternative to <code>application.properties</code>. It’s <strong>cleaner and more readable</strong>, especially for nested settings.</p><p>Example:</p><pre><code class="language-plaintext">server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db</code></pre><p>Indentation is important in YAML, use spaces, not tabs. Spring Boot supports both <code>.yml</code> and <code>.properties</code>, so you can use what you prefer.</p><h3><strong>77. What is the purpose of the </strong><code><strong>@ComponentScan</strong></code><strong> annotation?</strong></h3><p><code>@ComponentScan</code> tells Spring where to <strong>look for your beans</strong> (<code>@Component</code>, <code>@Service</code>, <code>@Repository</code>, etc.).</p><p>By default, it scans the package of your main class. But you can customize it.</p><p>Example:</p><pre><code class="language-java">@ComponentScan(basePackages = "com.example")</code></pre><h3><strong>78. How does Spring Boot support microservices development?</strong></h3><p>Spring Boot is a great choice for building microservices because it’s:</p><ul><li><strong>Lightweight</strong> and fast to start</li><li>Comes with <strong>embedded servers</strong> (no need for external Tomcat)</li><li>Has excellent support for REST APIs and Spring Data</li></ul><p>With <strong>Spring Cloud</strong>, it becomes even more powerful:</p><ul><li><strong>Eureka</strong> – service discovery</li><li><strong>Spring Cloud Gateway</strong> – routing and load balancing</li><li><strong>Config Server</strong> – centralized configuration</li><li><strong>Circuit breakers</strong> – with Resilience4j</li></ul><p>It also works well with <strong>Docker</strong> and <strong>Kubernetes</strong>, making it ideal for cloud-native apps.</p><h3><strong>79. What is Spring Cloud and how does it work with Spring Boot?</strong></h3><p>Spring Cloud is a set of tools that helps developers build <strong>distributed systems and microservices architectures</strong>.</p><p>It works on top of Spring Boot and provides solutions for common microservice problems such as:</p><ul><li>Service discovery</li><li>Configuration management</li><li>Load balancing</li><li>Circuit breakers</li><li>API gateway</li></ul><p>Some popular Spring Cloud components include:</p><ul><li><strong>Eureka</strong> – service discovery</li><li><strong>Spring Cloud Gateway</strong> – API gateway</li><li><strong>Config Server</strong> – centralized configuration</li><li><strong>Resilience4j</strong> – fault tolerance</li></ul><p>Spring Boot is used to build individual microservices, while Spring Cloud helps them communicate and manage distributed systems.</p><h3><strong>80. How can you integrate a third-party library with Spring Boot?</strong></h3><p>You can easily use external libraries (like Apache POI, Stripe, Twilio, etc.) with Spring Boot.</p><ol><li>Add the library dependency (e.g., in <code>pom.xml</code>)</li><li>Configure via <code>@Configuration</code> and <code>@Bean</code></li><li>Inject and use the library as a Spring-managed bean</li></ol><h3><strong>81. What is the purpose of the </strong><code><strong>@Import</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@Import</code> is used when you want to <strong>include another </strong><code><strong>@Configuration</strong></code><strong> class</strong> into your current configuration.</p><p>Instead of using <code>@ComponentScan</code> to pick it up automatically, <code>@Import</code> lets you add it <strong>manually</strong>.</p><p>Example:</p><pre><code class="language-java">@Import(AppConfig.class)
public class MainConfig { }</code></pre><h3><strong>82. How can you run a block of code at Spring Boot startup?</strong></h3><p>To run code when the application starts, implement one of these interfaces:</p><ul><li><code>CommandLineRunner</code> – gets raw <code>String[] args</code></li><li><code>ApplicationRunner</code> – gets parsed <code>ApplicationArguments</code></li></ul><p>Example:</p><pre><code class="language-java">@Bean
public CommandLineRunner run() {
    return args -&gt; {
        System.out.println("App started!");
    };
}</code></pre><h3><strong>83. What is the purpose of the </strong><code><strong>@ConditionalOnClass</strong></code><strong> annotation?</strong></h3><p><code>@ConditionalOnClass</code> makes sure a <strong>bean or configuration is only loaded</strong> if a specific class is available in the classpath.</p><p><strong>Use case:</strong> You want to conditionally enable a feature <strong>only if a certain dependency is present</strong>.</p><p>Example:</p><pre><code class="language-java">@ConditionalOnClass(DataSource.class)
public class DataSourceConfig { ... }</code></pre><h3><strong>84. How can you create a custom banner in Spring Boot?</strong></h3><p>Spring Boot shows a banner in the console when the app starts. You can easily customize it.</p><p><strong>Steps:</strong></p><ol><li>Create a file named <code>banner.txt</code></li><li>Place it in <code>src/main/resources</code></li><li>Add ASCII art, app info, or any message</li></ol><p>Want a banner image instead? Use:</p><pre><code class="language-plaintext">banner.image.location=classpath:banner.gif</code></pre><p>To <strong>disable</strong> the banner:</p><pre><code class="language-plaintext">spring.main.banner-mode=off</code></pre><p>Try websites like <a href="http://patorjk.com/software/taag">patorjk.com/software/taag</a> to generate cool ASCII art banners.</p><h3><strong>85. Explain the concept of Spring Boot auto-configuration report.</strong></h3><p>When things <strong>don’t auto-configure</strong> as expected, the <strong>auto-configuration report</strong> helps you debug.</p><p>Enable it by adding this to <code>application.properties</code>:</p><pre><code class="language-plaintext">debug=true</code></pre><p>You get a <strong>report of included and excluded auto-configurations</strong> in the console, useful for debugging config issues.</p><h3><strong>86. How does Spring Boot support configuration metadata generation?</strong></h3><p>Spring Boot can <strong>generate metadata files</strong> that help IDEs like IntelliJ or VS Code offer <strong>autocomplete and validation</strong> for your custom properties.</p><p>This happens when you:</p><ul><li>Use <code>@ConfigurationProperties</code> on your config classes.</li><li>Add the <code>spring-boot-configuration-processor</code> dependency:</li></ul><h3><strong>87. What is the purpose of the </strong><code><strong>@ImportResource</strong></code><strong> annotation?</strong></h3><p><code>@ImportResource</code> lets you <strong>include XML-based Spring configurations</strong> in a Java-based Spring Boot app.</p><p>Example:</p><pre><code class="language-java">@ImportResource("classpath:beans.xml")
public class AppConfig { }</code></pre><h3><strong>88. How can you customize the Spring Boot application context?</strong></h3><p>You can customize the application context (before it's fully initialized) using:</p><ul><li>Creating a subclass of <code>SpringApplication</code></li><li>Using <code>SpringApplicationBuilder</code></li><li>Adding <code>ApplicationContextInitializer</code> or listeners</li></ul><h3><strong>89. How can you enable or disable specific Spring Boot Actuator endpoints?</strong></h3><p>You can manage Actuator endpoints via <code>application.properties</code>:</p><pre><code class="language-plaintext">management.endpoints.web.exposure.include=health,info
management.endpoint.health.enabled=true
management.endpoint.beans.enabled=false</code></pre><h3><strong>90. How does Spring Boot handle logging?</strong></h3><p>Spring Boot uses <strong>Logback</strong> as the default logging framework, but you can also switch to Log4j2, Java Util Logging, etc.</p><p><strong>Basic logging configuration in </strong><code><strong>application.properties</strong></code><strong>:</strong></p><pre><code class="language-plaintext">logging.level.root=INFO
logging.level.org.springframework=DEBUG
logging.file.name=app.log</code></pre><h3><strong>91. What is the purpose of the </strong><code><strong>@EnableConfigurationProperties</strong></code><strong> annotation?</strong></h3><p>This annotation tells Spring Boot to <strong>bind configuration properties</strong> to a plain class — even if it’s not a component (<code>@Component</code> or <code>@Service</code>).</p><p>It’s mostly used when you want to keep configuration classes clean and separate.</p><p>Example:</p><pre><code class="language-java">@EnableConfigurationProperties(MyAppProperties.class)
public class MyAppConfig {
}</code></pre><p>Now Spring Boot will bind values from <code>application.properties</code> or <code>application.yml</code> to <code>MyAppProperties</code>.</p><p>If your <code>@ConfigurationProperties</code> class is already annotated with <code>@Component</code>, you don’t need this.</p><h3><strong>92. How can you access command-line arguments in Spring Boot?</strong></h3><p>Spring Boot apps can read arguments passed from the terminal using:</p><ul><li><code>ApplicationArguments</code> (recommended)</li><li><code>CommandLineRunner</code> or <code>ApplicationRunner</code></li></ul><p><strong>Example with </strong><code><strong>ApplicationArguments</strong></code><strong>:</strong></p><pre><code class="language-java">@Autowired
private ApplicationArguments args;

public void printArgs() {
    System.out.println("Source Args: " + args.getSourceArgs());
    System.out.println("Option Names: " + args.getOptionNames());
}</code></pre><p>You can run the app with:</p><pre><code class="language-plaintext">java -jar app.jar --mode=prod --port=8080</code></pre><h3><strong>93. What is the difference between </strong><code><strong>@Controller</strong></code><strong> and </strong><code><strong>@RestController</strong></code><strong>?</strong></h3><h3><code>@Controller</code>:</h3><ul><li>Used in <strong>web applications</strong> that return <strong>views</strong> like HTML or JSP pages.</li><li>It is part of the <strong>Spring MVC</strong> pattern.</li><li>If you return a string, Spring assumes it is the <strong>name of a view</strong> (like an HTML file).</li><li>To send JSON from here, you must also add <code>@ResponseBody</code> to the method.</li></ul><h3><code>@RestController</code>:</h3><ul><li>Used in <strong>REST APIs</strong> where you want to return <strong>JSON or XML</strong> directly.</li><li>It's the same as using <code>@Controller</code> <strong>+</strong> <code>@ResponseBody</code> on every method.</li><li>Spring automatically converts Java objects to JSON (using Jackson) and sends them in the response.</li></ul><h3><strong>94. How can you enable method-level security in Spring Boot?</strong></h3><p>Spring Boot allows you to <strong>secure individual methods</strong> using annotations.</p><p><strong>Steps:</strong></p><ol><li>Enable method-level security:</li></ol><pre><code class="language-java">@EnableGlobalMethodSecurity(prePostEnabled = true)</code></pre><ol><li>Use any of these:</li></ol><ul><li><code>@PreAuthorize("hasRole('ADMIN')")</code></li><li><code>@Secured("ROLE_USER")</code></li><li><code>@RolesAllowed("ADMIN")</code> (requires additional config)</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) {
    // secured method
}</code></pre><h3><strong>95. What is the purpose of the </strong><code><strong>@SessionAttributes</strong></code><strong> annotation?</strong></h3><p><code>@SessionAttributes</code> is used in Spring MVC to <strong>store model data in the HTTP session</strong> so it can survive across multiple requests.</p><p>Example:</p><pre><code class="language-java">@Controller
@SessionAttributes("user")
public class UserController {

    @ModelAttribute("user")
    public User user() {
        return new User();
    }
}</code></pre><h3><strong>96. How can you configure a Spring Boot app to run on a different port?</strong></h3><p>By default, Spring Boot apps run on port <strong>8080</strong>. To change it, just update the <code>application.properties</code> or <code>application.yml</code> file.</p><p><strong>Example (</strong><code><strong>application.properties</strong></code><strong>):</strong></p><pre><code class="language-plaintext">server.port=8081</code></pre><h3><strong>97. What is the difference between </strong><code><strong>@ModelAttribute</strong></code><strong> and </strong><code><strong>@RequestParam</strong></code><strong>?</strong></h3><ol><li><code><strong>@ModelAttribute</strong></code></li></ol><ul><li>Used when you want to bind <strong>multiple form fields</strong> to a <strong>Java object</strong>.</li><li>Spring automatically fills the fields of the object using the form data.</li><li>Very useful when handling HTML forms (like registration or login).</li></ul><ol><li><code><strong>@RequestParam</strong></code></li></ol><ul><li>Used when you want to get <strong>a single value</strong> from the request, like a query parameter or a form field.</li><li>You manually bind each value to a method parameter.</li></ul><h3><strong>98. How does Spring Boot support REST API versioning?</strong></h3><p>Spring Boot doesn’t have built-in versioning, but you can <strong>easily implement it in your controller layer</strong>.</p><p>Via:</p><ul><li>URL versioning: <code>/api/v1/users</code></li><li>Header versioning: <code>X-API-VERSION: 1</code></li><li>Media type versioning: <code>Accept: application/vnd.api.v1+json</code></li></ul><h3><strong>99. What is the purpose of the </strong><code><strong>@InitBinder</strong></code><strong> annotation in Spring Boot?</strong></h3><p><code>@InitBinder</code> is used to <strong>customize how Spring binds HTTP request data to Java objects</strong>.</p><p><strong>Example use cases:</strong></p><ul><li>Date formatting</li><li>String trimming</li><li>Custom type converters</li></ul><pre><code class="language-java">@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Date.class, new CustomDateEditor(
        new SimpleDateFormat("yyyy-MM-dd"), false));
}</code></pre><h3><strong>100. can configure multiple data sources in Spring Boot?</strong></h3><p>If your app needs to connect to more than one database (e.g., MySQL + PostgreSQL), you can configure <strong>multiple data sources</strong>.</p><p>Steps:</p><ol><li>Define two <code>DataSource</code> beans</li><li>Create two <code>EntityManagerFactory</code> beans</li><li>Configure separate <code>TransactionManager</code>s</li><li>Use <code>@Primary</code> and <code>@Qualifier</code> to differentiate</li></ol><p>Best practice: Keep configs in separate <code>@Configuration</code> classes (e.g., <code>PrimaryDBConfig</code>, <code>SecondaryDBConfig</code>).</p><h2>Conclusion</h2><p>In this article, we explored <strong>100 Spring Boot interview questions</strong> along with their answers to help you strengthen your core knowledge. With this foundation, you are now well prepared to face interviews with confidence.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot Interview Questions</category>
            <category>Spring Boot For Beginners</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_100_spring_boot_interview_questions_a9fb2b5ca7_46cbcf93b0.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top Java Frameworks You Must Know In 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/top-java-frameworks-you-must-know-in-2025</link>
            <guid>https://www.codingshuttle.com/blogs/top-java-frameworks-you-must-know-in-2025</guid>
            <pubDate>Tue, 08 Jul 2025 14:16:27 GMT</pubDate>
            <description><![CDATA[Discover the top Java frameworks every developer should know in 2025, from Spring Boot and Hibernate to JUnit, Kafka, and Micronaut. Build faster and smarter with these powerful tools.]]></description>
            <content:encoded><![CDATA[<p>Java is a popular and trusted programming language used by many developers all over the world. It's known for being flexible, secure, and able to run on different platforms. Thanks to its easy-to-read code and ability to handle both small and large projects, Java is great for building websites, mobile apps, and big business software.</p><p>Java has been around for a long time, which means there are tons of helpful frameworks and libraries available to make development easier. In this article, I am sharing most popular, efficient, and trending Java frameworks that can make your development process faster and smoother.</p><h2>Top Java Frameworks</h2><h2><strong>1. Spring Framework &amp; Spring Boot</strong></h2><p><strong>What is it?</strong></p><p>Spring is the most widely used Java framework today. It helps you build everything — from simple web apps to complex enterprise systems. Spring Boot is an extension of Spring that makes setup and development even easier.</p><p><strong>Why use it?</strong></p><ul><li><strong>Dependency Injection</strong> for cleaner code.</li><li><strong>Spring MVC</strong> for building web apps using the MVC pattern.</li><li><strong>Spring Boot</strong> for rapid, production-ready app development.</li><li>Built-in support for <strong>data access, security</strong>, and <strong>testing</strong>.</li><li>Perfect for <strong>microservices</strong>, <strong>cloud-based apps</strong>, and <strong>REST APIs</strong>.</li></ul><p><strong>Where it's used:</strong></p><p>Web development, enterprise apps, microservices, cloud-native applications, and more.</p><p>Want to master Spring Boot? Check out the <a href="https://www.codingshuttle.com/courses/java-spring-boot-0-to-100/">Spring Boot course</a> by Coding Shuttle and become job-ready today!</p><h2><strong>2. Micronaut</strong></h2><p><strong>What is it?</strong></p><p>Micronaut is a modern JVM-based framework designed for microservices and serverless apps. It’s lightweight, fast, and optimized for low memory use.</p><p><strong>Why use it?</strong></p><ul><li><strong>Faster startup time</strong> thanks to compile-time dependency injection.</li><li>Great for <strong>cloud-native microservices</strong>.</li><li>Built-in <strong>reactive programming support</strong>.</li><li>Easy integration with databases and tools.</li></ul><p><strong>Where it's used:</strong></p><p>High-performance microservices, serverless apps, and cloud environments like Docker and Kubernetes.</p><h2><strong>3. Hibernate</strong></h2><p><strong>What is it?</strong></p><p>Hibernate is the go-to <strong>ORM (Object Relational Mapping)</strong> tool for Java. It lets you map Java objects to database tables, removing the need to write raw SQL.</p><p><strong>Why use it?</strong></p><ul><li><strong>Lazy loading</strong> to boost performance.</li><li>Built-in <strong>caching</strong>.</li><li>Eliminates boilerplate JDBC code.</li><li>Uses its own powerful query language (HQL).</li></ul><p><strong>Where it's used:</strong></p><p>Any Java application that interacts with a relational database like MySQL, PostgreSQL, etc.</p><h2><strong>4. Apache Kafka</strong></h2><p><strong>What is it?</strong></p><p>Apache Kafka is not a framework, but it’s a <strong>must-know stream processing platform</strong> used to handle real-time data at scale.</p><p><strong>Why use it?</strong></p><ul><li><strong>Publish-subscribe model</strong> with high throughput.</li><li>Helps build <strong>event-driven, decoupled systems</strong>.</li><li><strong>Fault-tolerant</strong> and scalable.</li><li>Integrates easily with other tools and databases.</li></ul><p><strong>Where it's used:</strong></p><p>Real-time applications, event streaming, data pipelines, and big data systems.</p><h2><strong>5. JUnit 5</strong></h2><p><strong>What is it?</strong></p><p>JUnit 5 is the most popular <strong>testing framework</strong> for Java. It’s used to write and run unit tests to make sure your code behaves correctly.</p><p><strong>Why use it?</strong></p><ul><li>Powerful <strong>annotations</strong> like <code>@Test</code>, <code>@BeforeEach</code>, and <code>@DisplayName</code>.</li><li>Supports <strong>parameterized tests</strong> and <strong>nested test classes</strong>.</li><li>Fully integrated with IntelliJ IDEA and CI tools.</li></ul><p><strong>Where it's used:</strong></p><p>Unit testing across all types of Java applications.</p><h2><strong>6. Mockito</strong></h2><p><strong>What is it?</strong></p><p>Mockito is a <strong>mocking framework</strong> that helps you isolate and test individual units of code by replacing real dependencies with fake ones.</p><p><strong>Why use it?</strong></p><ul><li>Easily create <strong>mock objects</strong> with <code>@Mock</code>.</li><li>Use <strong>spies</strong> for partial mocking.</li><li>Great for testing services without relying on databases or external APIs.</li></ul><p><strong>Where it's used:</strong></p><p>Unit testing where mocking dependencies is required.</p><h2><strong>7. WireMock</strong></h2><p><strong>What is it?</strong></p><p>WireMock is a tool for <strong>mocking HTTP services</strong>. It acts like a fake server, returning predefined responses to simulate external APIs.</p><p><strong>Why use it?</strong></p><ul><li>Simulate real-world API behavior.</li><li>Add <strong>faults or delays</strong> for stress testing.</li><li>Supports <strong>request matching</strong>, <strong>record/playback</strong>, and more.</li></ul><p><strong>Where it's used:</strong></p><p>Testing microservices that depend on third-party APIs.</p><h2><strong>8. Testcontainers</strong></h2><p><strong>What is it?</strong></p><p>Testcontainers is a library for <strong>integration testing using Docker containers</strong>. It helps you run databases or other services during your tests.</p><p><strong>Why use it?</strong></p><ul><li><strong>Real environment testing</strong> with real containers.</li><li>Works with MySQL, MongoDB, Kafka, RabbitMQ, and more.</li><li>Automatically cleans up resources after testing.</li></ul><p><strong>Where it's used:</strong></p><p>Integration testing, E2E testing in Java apps, especially for microservices.</p><h2><strong>9. Awaitility</strong></h2><p><strong>What is it?</strong></p><p>Awaitility is a Java library for testing <strong>asynchronous and concurrent code</strong>.</p><p><strong>Why use it?</strong></p><ul><li>Waits for conditions to be met with <strong>timeouts</strong>.</li><li>Supports <strong>custom conditions</strong> for more flexible tests.</li><li>Ideal for <strong>async operations</strong>, <strong>delayed responses</strong>, or <strong>concurrent systems</strong>.</li></ul><p><strong>Where it's used:</strong></p><p>Async operations testing, REST API response timing, multithreading scenarios.</p><h2><strong>10. Jackson</strong></h2><p><strong>What is it?</strong></p><p>Jackson is a <strong>JSON library</strong> for Java that helps you read and write JSON data with ease.</p><p><strong>Why use it?</strong></p><ul><li>Easily convert Java objects to JSON and vice versa.</li><li>Support for <strong>annotations</strong>, <strong>streaming</strong>, and <strong>custom serialization</strong>.</li><li>Works with JSON, XML, CSV, YAML, etc.</li></ul><p><strong>Where it's used:</strong></p><p>REST APIs, web apps, or anywhere JSON data is involved.</p><h2><strong>Conclusion</strong></h2><p>In this article, I’ve highlighted some of the most powerful and widely-used Java frameworks like Spring Boot, JUnit, Mockito, and Testcontainers. By learning and using these tools, you can write cleaner code, build applications faster, and scale with confidence.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>Top Java Frameworks 2025</category>
            <category>Best Java Tools for Developers</category>
            <category>Popular Java Frameworks</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Top_Java_Frameworks_31ba7b812e.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[What Does a Java Developer Do? 1 Year to 8+ Years Experience]]></title>
            <link>https://www.codingshuttle.com/blogs/what-does-a-java-developer-do</link>
            <guid>https://www.codingshuttle.com/blogs/what-does-a-java-developer-do</guid>
            <pubDate>Tue, 08 Jul 2025 14:12:17 GMT</pubDate>
            <description><![CDATA[Curious what a Java developer really does? Learn their daily tasks, responsibilities, career paths, and how they build real-world applications using Java, Spring Boot, and more.]]></description>
            <content:encoded><![CDATA[<p>Ever think what a Java developer actually do in a company? It's more than just writing code. Java developers are the brains behind the apps and systems we use every day. from mobile apps and banking software to user recommendations and large enterprise platforms.</p><p>In this blog, we will explore what a Java developer does, core responsibilities, career opportunities, and specialization of a Java developer in different fields.</p><h2><strong>Before Understanding What Does a Java Developer Do ? Lets Understand Who is Java Developer ?</strong></h2><p>A Java developer uses the <strong>Java</strong> programming language to <strong>design, build, test, and maintain software applications</strong>. They work across platforms like web, backend, mobile, or cloud. they are building reliable and secure systems using Java’s powerful ecosystem.</p><h2><strong>Core Responsibilities of a Java Developer</strong></h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Core_Responsibilities_of_a_Java_Developer_e5e661bebc.png" alt="Core Responsibilities of a Java Developer" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Core_Responsibilities_of_a_Java_Developer_e5e661bebc.png 156w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Core_Responsibilities_of_a_Java_Developer_e5e661bebc.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Core_Responsibilities_of_a_Java_Developer_e5e661bebc.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Core_Responsibilities_of_a_Java_Developer_e5e661bebc.png 1000w," sizes="100vw"><figcaption><strong>Core Responsibilities of a Java Developer</strong></figcaption></figure><p>A Java developer's day-to-day work can vary significantly based on their role, experience level, and the type of industry they’re in. However, most Java developers follow a similar set of responsibilities and tasks throughout the week. Let’s break down what a typical week in the life of a Java developer looks like.</p><h3><strong>1. Writing &amp; maintaining code</strong></h3><p>At the heart of a Java developer’s job lies writing clean, efficient, and maintainable code. This means following <strong>Object-Oriented Programming (OOP)</strong> principles, using design patterns, and building modular components that are easy to test and reuse.</p><p>Modern Java developers use tools like <strong>IntelliJ IDEA or Eclipse</strong>, along with <strong>build tools like Maven or Gradle</strong>, to structure their code effectively. Writing good documentation, adhering to naming conventions, and applying best practices ensures that the codebase remains understandable to others (and their future selves).</p><h3><strong>2. Debugging &amp; troubleshooting</strong></h3><p>Even the best-written code can run into unexpected issues. Debugging is a core part of the Java developer’s day, whether it's fixing bugs in staging or resolving incidents in production. This involves:</p><ul><li>Analyzing server logs</li><li>Using breakpoints in IDEs</li><li>Reading stack traces</li><li>Identifying performance bottlenecks or memory leaks</li></ul><h3><strong>3. Building backend APIs</strong></h3><p>These days, APIs have become the backbone of communication for modern applications among the services. A Java developer will work with RESTful and SOAP-based web services, usually with Spring Boot, and JAX-RS. Their role is to make sure that the APIs are secure, scalable, and well-documented for other developers to integrate easily.</p><h3><strong>4. Database integration</strong></h3><p>Java developers frequently work with both relational and NoSQL databases. Using <strong>JDBC, Hibernate</strong>, or <strong>Spring Data JPA</strong>, they connect backend services to databases like <strong>MySQL</strong>, <strong>PostgreSQL</strong>, or <strong>MongoDB</strong>. Their task involves Writing optimized SQL queries, Designing entity relationships, Managing transactions, Indexing and performance tuning etc.</p><h3><strong>5. Performance &amp; security optimization</strong></h3><p>Slow-loading applications can frustrate users and drive them away. That’s why performance optimization is a critical responsibility for Java developers. They actively monitor CPU usage, memory allocation, and garbage collection processes to fine-tune application speed and efficiency. By leveraging performance tuning techniques such as caching (using tools like Redis or Ehcache) and implementing multithreading, developers can significantly boost application responsiveness and overall performance.</p><h3><strong>6. Collaborating &amp; communicating4</strong></h3><p>Java development is a team sport. Developers work closely with frontend engineers, QA testers, DevOps teams, designers, and business analysts. Communication is key — whether it’s during daily standups, sprint planning sessions, or code reviews. <strong>Agile methodologies</strong> like Scrum or Kanban guide the development cycle, while tools like <strong>Jira, Trello</strong>, and <strong>Slack</strong> help keep everyone aligned.</p><h3><strong>7. Learning &amp; staying updated</strong></h3><p>The Java ecosystem is constantly evolving. With new releases (like <strong>Java 17</strong> and <strong>Java 21</strong>) and updates to libraries and frameworks, staying current is a must.</p><p>A good Java developer regularly:</p><ul><li>Follows updates on sites like <strong>InfoQ</strong>, <strong>Baeldung</strong>, and <a href="http://Dev.to"><strong>Dev.to</strong></a></li><li>Experiments with new features (e.g., records, sealed classes)</li><li>Contributes to open-source projects</li><li>Attends meetups or tech conferences</li><li>Learns tools like <strong>Docker, Kubernetes</strong>, and <strong>CI/CD pipelines</strong></li></ul><h2><strong>Career Paths &amp; Specializations of a Java Developer</strong></h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Career_Paths_and_Specializations_of_a_Java_Developer_68189cac28.png" alt="Career Paths &amp; Specializations of a Java Developer" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Career_Paths_and_Specializations_of_a_Java_Developer_68189cac28.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Career_Paths_and_Specializations_of_a_Java_Developer_68189cac28.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Career_Paths_and_Specializations_of_a_Java_Developer_68189cac28.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Career_Paths_and_Specializations_of_a_Java_Developer_68189cac28.png 1000w," sizes="100vw"><figcaption><strong>Career Paths &amp; Specializations of a Java Developer</strong></figcaption></figure><h3><strong>1. Backend Developer</strong></h3><p>A backend developer specializes in server-side logic, APIs, databases, and application architecture. They use Java, Spring Boot, and tools like Hibernate to build scalable and secure backend systems. Their focus is on performance, data handling, and system integration.</p><h3><strong>2. Full-Stack Developer</strong></h3><p>Full-stack developers work on both the frontend and backend of web applications. They use technologies like HTML, CSS, JavaScript (with frameworks like React or Angular) on the frontend, and Java with Spring Boot on the backend. This role requires a well-rounded skill set to build end-to-end features.</p><h3><strong>3. Mobile Developer</strong></h3><p>Mobile developers build native Android applications using Java and the Android SDK. They design smooth, responsive mobile experiences tailored for smartphones and tablets. This path is ideal for those interested in mobile UI/UX and touch-based user interactions.</p><h3><strong>4. Cloud/Microservices Developer</strong></h3><p>These developers design distributed systems using microservices architecture and deploy them on cloud platforms like AWS, Azure, or GCP. They work with tools like Docker, Kubernetes, and Spring Cloud to ensure scalability and resilience. Java plays a key role in building robust service layers.</p><h3><strong>5. Software Architect</strong></h3><p>A software architect defines the overall structure and high-level design of applications. They set coding standards, design patterns, and system integration strategies. Architects often mentor teams and ensure that the software aligns with long-term business goals and technical best practices.</p><h3><strong>6. DevOps Engineer</strong></h3><p>DevOps engineers streamline the software development lifecycle by setting up CI/CD pipelines, automating deployments, and managing infrastructure. They use tools like Jenkins, Docker, Kubernetes, and Ansible to ensure smooth, consistent, and fast releases. Java developers with a DevOps mindset can bridge development and operations effectively.</p><h2><strong>Conclusion</strong></h2><p>In this article, we explored the key responsibilities, career paths, and skills of a modern Java developer. Whether you're aiming to build robust backend systems, dive into cloud technologies, or become a full-stack pro, Java offers a powerful and versatile career path. With the right mindset and continuous learning, anyone can grow into a successful Java developer in today’s tech-driven world.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>What Does a Java Developer Do</category>
            <category>Java Developer Roles and Responsibilities</category>
            <category>Career Paths for Java Developers</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/what_does_java_developer_do_86270ece11.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How I Mastered Java in Just 30 Days: The Ultimate Study Plan]]></title>
            <link>https://www.codingshuttle.com/blogs/learn-java-in-30-days-study-plan</link>
            <guid>https://www.codingshuttle.com/blogs/learn-java-in-30-days-study-plan</guid>
            <pubDate>Mon, 07 Jul 2025 07:03:27 GMT</pubDate>
            <description><![CDATA[Learn Java in 30 days with this structured study plan. Follow this 30-day Java study plan covering everything from fundamentals, OOP, collections, to advanced Java concepts.]]></description>
            <content:encoded><![CDATA[<p>Java is an object-oriented, general-purpose and high demand programming language. It is a versatile, widely used programming language particularly suitable for enterprise-level applications, Android mobile development, and large-scale systems.</p><p>For these reasons learning Java can open doors to countless career opportunities in software development. In this article I will show you how to learn Java in just 30 days.</p><h2><strong>30 Days Java Study Plan</strong></h2><p>Below is a simple, structured weekly plan to help you learn Core Java in just 30 days.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/30_Days_Java_Study_Plan_66cbccc472.png" alt="30 Days Java Study Plan" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_30_Days_Java_Study_Plan_66cbccc472.png 156w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_30_Days_Java_Study_Plan_66cbccc472.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_30_Days_Java_Study_Plan_66cbccc472.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_30_Days_Java_Study_Plan_66cbccc472.png 1000w," sizes="100vw"><figcaption>30 Days Java Study Plan</figcaption></figure><h3><strong>Week 1 : Java Basics</strong></h3><p>Before diving into advanced topics, build a strong foundation by learning Java basics like variables, data types, operators, and control structures. Practice writing small programs to apply these concepts and improve your confidence.</p><p>Here is the list of concepts you need to cover in Week 1.</p><ol><li>Introduction to Java &amp; its Features</li><li>Setting up Java Development Kit (JDK)</li><li>Understanding Java Program Structure</li><li>Writing your first Hello World Program</li><li>Data Types and Variables</li><li>Operators (Arithmetic, Logical, Relational)</li><li>Conditional Statements (if-else, switch)</li><li>Loops (for, while, do-while)</li></ol><h3><strong>Week 2 : Object-Oriented Programming (OOP)</strong></h3><p>Java is an object-oriented language, so mastering OOP concepts is crucial. So after learning Java basics learn about classes, objects, inheritance, polymorphism, and encapsulation. Practice implementing these concepts in your code to solidify your understanding.</p><p>Here is the list of concepts you need to cover in Week 2.</p><ol><li>Introduction to Classes and Objects</li><li>Understanding Methods and Constructors</li><li>OOP Concepts: Encapsulation, Inheritance, Polymorphism, Abstraction</li><li><code>this</code> keyword and Method Overloading</li><li><code>super</code> keyword and Method Overriding</li><li>Access Modifiers (public, private, protected, default)</li></ol><h3><strong>Week 3 : Intermediate Java Concepts</strong></h3><p>After learning OOP concepts, the next step is to explore arrays, strings, exception handling, and collections. These concepts are essential for building real-world Java applications. Practice working with arrays to store data, handle errors using try-catch blocks, and use collections to manage groups of objects.</p><p>Here is the list of concepts you need to cover in Week 3.</p><ol><li>Arrays (Single &amp; Multi-dimensional)</li><li>String Handling &amp; String Methods</li><li>Exception Handling (try-catch-finally)</li><li>Custom Exceptions</li><li>Wrapper Classes &amp; Autoboxing</li><li>Java Packages and Importing Classes</li><li>Java Collection Framework (List, Set, Map)</li></ol><h3><strong>Week 4 : Advance Java Concepts</strong></h3><p>Once you are confident with intermediate concepts, start learning advanced Java features like file handling, multithreading, and JDBC for database connectivity. In this week you will also explore Java 8 features like lambda expressions and streams.</p><p>Here is the list of concepts you need to cover in Week 4.</p><ol><li>Introduction to File Handling (FileReader, FileWriter)</li><li>Basic Multithreading Concepts</li><li>Lambda Expressions and Functional Interfaces (Java 8 Features)</li><li>Stream API Basics for Data Processing</li><li>Introduction to JDBC for Database Connectivity</li></ol><h3>Resources</h3><ol><li><strong>Java Mastery by Anuj Bhaiya :</strong> <a href="https://www.youtube.com/playlist?list=PLUcsbZa0qzu18zPz3EatehQJ5K1jP4IO2">https://www.youtube.com/playlist?list=PLUcsbZa0qzu18zPz3EatehQJ5K1jP4IO2</a></li><li><strong>Complete Java in one Video :</strong> <a href="https://www.youtube.com/watch?v=NNLoi8QqzaY">https://www.youtube.com/watch?v=NNLoi8QqzaY</a></li></ol><h3>Conclusion</h3><p>In this article, i have mentioned a structured 30-day study plan to master Java. By following this approach you can build a strong Java foundation and be ready for real-world software development.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java</category>
            <category>Java Study Plan</category>
            <category>Java Roadmap</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/10_7c17df29a0.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How To Make Money As A Java Developer]]></title>
            <link>https://www.codingshuttle.com/blogs/how-to-make-money-as-a-java-developer</link>
            <guid>https://www.codingshuttle.com/blogs/how-to-make-money-as-a-java-developer</guid>
            <pubDate>Mon, 07 Jul 2025 05:35:46 GMT</pubDate>
            <description><![CDATA[Learn the Top ways to make money as a java developer. From full-time jobs to freelancing, blogging, and building your own products.]]></description>
            <content:encoded><![CDATA[<p>Java is one of the most popular and high demand programming languages in the world. From building enterprise software to modern cloud applications , Java is everywhere. But beyond just learning Java, many developers ask, <i>How can I actually make money as a Java Developer?</i></p><p>In this article, I will explain the most practical ways to start earning as a Java developer, whether you are a beginner, student, or working professional these methods can help you generate income as a Java developer.</p><h2><strong>Why Java Developers Are in High Demand</strong></h2><p>Java is used everywhere, companies like Google, Netflix, Amazon, and many more rely heavily on Java for their backend systems. With its strong community support and frameworks like Spring Boot and Hibernate, Java developers continue to be in high demand. so lets know top ways To Make Money As a Java Developer.</p><h2><strong>Top 7 Ways To Make Money As a Java Developer</strong></h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Top_7_Ways_To_Make_Money_As_A_Java_Developer_dbc14cc464.png" alt="Top 7 Ways To Make Money As A Java Developer" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Top_7_Ways_To_Make_Money_As_A_Java_Developer_dbc14cc464.png 156w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Top_7_Ways_To_Make_Money_As_A_Java_Developer_dbc14cc464.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Top_7_Ways_To_Make_Money_As_A_Java_Developer_dbc14cc464.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Top_7_Ways_To_Make_Money_As_A_Java_Developer_dbc14cc464.png 1000w," sizes="100vw"><figcaption>Top 7 Ways To Make Money As A Java Developer</figcaption></figure><h3><strong>1. Get a Full-Time Job</strong></h3><p>Getting a full-time job is still the most reliable way to earn consistent income. Companies regularly hire Java developers for roles like:</p><ul><li>Backend Developer</li><li>Spring Boot Developer</li><li>Microservices Engineer</li><li>Software Engineer</li></ul><p>If you’ve got a strong grip on Core Java, OOP principles, and popular frameworks like Spring Boot, your chances of landing a job improve significantly.</p><p>Starting salaries might be modest, especially if you’re new, but as you gain experience with tools like Spring Security, databases, and cloud platforms (AWS, Azure), your salary potential grows fast.</p><h3><strong>2. Freelancing</strong></h3><p>Freelancing is a flexible option if you prefer working on short-term projects or building your own schedule. Many businesses look for Java developers on platforms like Upwork, Fiverr, or Freelancer.</p><p>As a freelancer, you might work on developing REST APIs, fixing bugs, enhancing existing applications, or integrating backend services.</p><h3><strong>3. Open Source Contributions &amp; Paid Projects</strong></h3><p>Contributing to open-source projects may not bring immediate income, but it helps build your reputation as a developer. Over time, this can lead to paid collaborations, freelance offers, or even job opportunities.</p><p>Many developers start by contributing to libraries, tools, or frameworks they already use like Spring Boot or Hibernate and gradually become recognized in the community.</p><h3><strong>4. Building Your Own Products</strong></h3><p>If you like creating things from scratch, consider building your own product or tool. Many Java developers have successfully launched:</p><ul><li>SaaS platforms</li><li>Desktop apps with JavaFX</li><li>Spring Boot-based management systems</li></ul><p>For example, you could create an invoice generator for small businesses, a simple CRM tool, atask management app.</p><h3><strong>5. Teaching Java</strong></h3><p>Sharing your knowledge can be a great way to earn. You can start a YouTube channel, create online courses for platforms like Udemy, or offer personal coaching sessions.</p><p>If you can explain Java concepts in a simple, practical way, many beginners will appreciate your content. Teaching also strengthens your own understanding while building your reputation as a developer.</p><h3><strong>6. Technical Blogging</strong></h3><p>Writing technical articles is another way to earn while sharing your experiences. Platforms like Medium offer Partner Programs where popular articles can generate income.</p><p>You can also start your own blog, monetize it with ads, or partner with tech companies for sponsored content. Writing tutorials, project guides, or interview tips related to Java helps attract readers, and over time, your blog can become a valuable income stream.</p><h3><strong>7. Participating in Coding Competitions</strong></h3><p>If you enjoy solving problems, coding competitions can be both fun and rewarding. Platforms like HackerRank, LeetCode, and Codeforces organize contests with cash prizes for top performers.</p><p>Even if you don’t win immediately, participating improves your problem-solving skills, which helps in job interviews and real-world projects.</p><h2><strong>Conclusion</strong></h2><p>In this article, we have learned the top 7 practical ways to make money as a Java Developer. Whether you choose a full-time job, freelancing, teaching, building your own product, or blogging these methods allow you to earn as a Java developer.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Java Developer</category>
            <category>Spring Boot Jobs</category>
            <category>Make Money with Java</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/how_to_make_money_cover_2_66d9a213a8.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Sending Emails through Spring Boot Application - JavaMailSender Made Easy]]></title>
            <link>https://www.codingshuttle.com/blogs/sending-emails-through-spring-boot-application</link>
            <guid>https://www.codingshuttle.com/blogs/sending-emails-through-spring-boot-application</guid>
            <pubDate>Sat, 05 Jul 2025 15:07:12 GMT</pubDate>
            <description><![CDATA[Learn How to Send Emails in Spring Boot with JavaMailSender. Step-by-step guide to implement email integration using Spring Boot Starter Mail for real-world applications.]]></description>
            <content:encoded><![CDATA[<p>Sending emails is a common requirement in real-world applications, whether it’s for account verification, password reset links, order confirmations, or simple notifications. Luckily, Spring Boot makes sending emails easy with minimal setup.</p><p>In this article, I will show you how to send emails using Spring Boot step by step. Whether you’re building a personal project or working on an enterprise application, this guide will help you integrate email functionality quickly.</p><h2><strong>Why Send Emails in Applications?</strong></h2><p>Here are some common use-cases for sending emails:</p><ol><li>Account verification during user signup</li><li>Password reset links for forgot password</li><li>Order or booking confirmations</li><li>Promotional or marketing emails</li><li>System alerts or notifications</li></ol><p>Spring Boot, with the help of <code>JavaMailSender</code> interface, simplifies the process of sending emails from your application.</p><h2><strong>Here is Step-by-Step Guide to Send Emails with Spring Boot</strong></h2><h3><strong>Add Spring Boot Mail Dependency</strong></h3><p>First, add the Spring Boot Starter Mail dependency to <code>pom.xml</code>:</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-mail&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p>If you’re using Gradle:</p><pre><code class="language-plaintext">implementation 'org.springframework.boot:spring-boot-starter-mail'</code></pre><h3><strong>Configure Email Properties</strong></h3><p>In your <code>application.properties</code> or <code>application.yml</code> file add your email server configurations. For this example, we will use <strong>Gmail SMTP</strong>, but you can use other providers as well.</p><pre><code class="language-plaintext">spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=your_email@gmail.com
spring.mail.password=your_app_password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true</code></pre><h3>Lets understand these configurations:</h3><ol><li><a href="http://spring.mail.host=smtp.gmail.com">spring.mail.host=smtp.gmail.com</a> : this tells Spring Boot which mail server to use. Here, we are using Gmail’s SMTP server, if you are using yahoo use, <a href="http://smtp.mail.yahoo.com">smtp.mail.yahoo.com</a>.</li><li>spring.mail.port=587 : the port number used for email transmission. Port <code>587</code> is the standard port for sending emails with <strong>STARTTLS</strong> security.</li><li><a href="mailto:spring.mail.username=your_email@gmail.com">spring.mail.username=your_email@gmail.com</a> : This is your Gmail account id that will be used to send emails.</li><li>spring.mail.password=your_app_password : the password for your email account, here If you're using Gmail, you can’t use your normal account password here. You need to generate an App Password from your Google account settings for this to work securely.</li><li>spring.mail.properties.mail.smtp.auth=true : It means your application will provide a username and password to log in to the mail server.</li><li>spring.mail.properties.mail.smtp.starttls.enable=true : This enables STARTTLS, which adds a layer of security by encrypting the connection between your application and the mail server.</li></ol><h3><strong>Create Email Service to Send Emails</strong></h3><p>We’ll create a simple service class to send emails using <code>JavaMailSender</code>.</p><pre><code class="language-java">import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class EmailService {

    @Autowired
    private JavaMailSender mailSender;

    public void sendSimpleEmail(String toEmail, String subject, String body) {

        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("your_email@gmail.com"); // sender's email
        message.setTo(toEmail);
        message.setSubject(subject);
        message.setText(body);

        mailSender.send(message);

        System.out.println("Email sent successfully to " + toEmail);
    }
}</code></pre><h3><strong>Create a REST API to Trigger Email</strong></h3><p>We can expose an endpoint to trigger the email for testing purposes.</p><pre><code class="language-java">import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/email")
public class EmailController {

    @Autowired
    private EmailService emailService;

    @PostMapping("/send")
    public String sendEmail(@RequestParam String toEmail,
                            @RequestParam String subject,
                            @RequestParam String body) {

        emailService.sendSimpleEmail(toEmail, subject, body);
        return "Email sent successfully!";
    }
}</code></pre><p>You can now test the API using Postman or your browser using this API:</p><pre><code class="language-plaintext">http://localhost:8080/api/email/send?toEmail=recipient@gmail.com&amp;subject=Hello&amp;body=Test Email from Spring Boot</code></pre><p>After hitting this API, the email will be sent to recipient email address that you pass in the <code>toEmail</code> parameter.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_07_05_202447_aa12caf2b2.png" alt="Testing Email Image" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_07_05_202447_aa12caf2b2.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_07_05_202447_aa12caf2b2.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_07_05_202447_aa12caf2b2.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_07_05_202447_aa12caf2b2.png 1000w," sizes="100vw"><figcaption>Testing Email Image</figcaption></figure><h2><strong>Conclusion</strong></h2><p>Sending emails with Spring Boot is simple and production-ready with minimal setup. With the combination of <code>Spring Boot Starter Mail</code> and <code>JavaMailSender</code>, you can integrate email functionality into your application.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring</category>
            <category>Spring Boot Send Email Tutorial</category>
            <category>JavaMailSender</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/sending_email_with_spring_boot_c89d0613c9.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[I Reverse-Engineered Spring Boot - What I Found Will SHOCK You]]></title>
            <link>https://www.codingshuttle.com/blogs/understanding-the-internal-working-of-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/understanding-the-internal-working-of-spring-boot</guid>
            <pubDate>Sat, 05 Jul 2025 08:37:50 GMT</pubDate>
            <description><![CDATA[Understand the Internal Working of Spring Boot. Learn how auto-configuration, starter dependencies, embedded servers, and externalized configurations simplify Java development.]]></description>
            <content:encoded><![CDATA[<p>If you have worked with Spring Boot before, you’ve probably noticed how little setup is required to get things running. You create a project, add a few annotations, maybe change some properties, and boom, your API is live. But this simplicity doesn't happen automatically. Behind the scenes, Spring Boot performs a lot of smart configurations to hide complexity from developers. In this article, I have explained the internal working of Spring Boot in a simple and easy-to-understand way.</p><h2><strong>The Core Building Blocks of Spring Boot</strong></h2><h3><strong>1. SpringApplication Class</strong></h3><p>This is where every Spring Boot application begins. The <code>SpringApplication.run(...)</code> method might look simple, but it kicks off a chain of powerful behind-the-scenes actions that get your app up and running.</p><p><strong>What It Does:</strong></p><pre><code class="language-java">@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}</code></pre><ul><li>Bootstraps the Spring application.</li><li>Sets up the <strong>ApplicationContext</strong> (based on the type of app — web or standalone).</li><li>Triggers <strong>component scanning</strong> to register beans and dependencies.</li><li>Starts the <strong>embedded server</strong> (Tomcat, Jetty, or Undertow) if it's a web app.</li><li>Applies <strong>auto-configuration</strong> based on the dependencies present.</li><li>Publishes key <strong>lifecycle events</strong> like <code>ApplicationStartedEvent</code> and <code>ApplicationReadyEvent</code>.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/intenal_working_spring_boot_e0ef84021d.png" alt="run() method process" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_intenal_working_spring_boot_e0ef84021d.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_intenal_working_spring_boot_e0ef84021d.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_intenal_working_spring_boot_e0ef84021d.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_intenal_working_spring_boot_e0ef84021d.png 1000w," sizes="100vw"><figcaption>run() method process</figcaption></figure><p><strong>How It Works:</strong></p><p>When you call <code>SpringApplication.run(...)</code>, Spring Boot first prepares the environment by setting up properties and configurations. It then loads all the bean definitions and refreshes the application context. Based on your project type, it decides whether to use <code>AnnotationConfigApplicationContext</code> for a non-web app or <code>WebApplicationContext</code> for a web-based one. After that, auto-configuration kicks in — Spring Boot scans your classpath, detects available libraries, and applies smart defaults accordingly. Finally, if it’s a web application, it starts an embedded server like Tomcat, and your app is ready to serve requests.</p><h3>2. @SpringBootApplication Annotation</h3><p>This single annotation is what makes a Spring Boot application tick. It’s actually a <strong>meta-annotation</strong> that wraps three powerful Spring annotations into one.</p><p><strong>What It Does:</strong></p><ul><li><code>@Configuration</code> – Tells Spring that this class contains bean definitions. It’s the starting point for your app’s configuration.</li><li><code>@EnableAutoConfiguration</code> – Triggers Spring Boot’s auto-configuration magic based on the dependencies present in your classpath.</li><li><code>@ComponentScan</code> – Automatically scans the current package and its subpackages to detect and register components like <code>@Component</code>, <code>@Service</code>, <code>@Repository</code>, and <code>@Controller</code>.</li></ul><p><strong>How It Works:</strong></p><p>When the application starts, Spring sees <code>@SpringBootApplication</code> and uses it to bootstrap the context. It processes all three underlying annotations in one go — registers beans, applies auto-configs, and wires up your components. This reduces boilerplate and makes your app setup clean and minimal with just one annotation.</p><h3><strong>3. Auto-Configuration</strong></h3><p>This stands out as the main reason Spring Boot feels so easy to use. it is one of the key features of Spring Boot because it tries to set up your application based on the dependencies you have added in your classpath.</p><p><strong>What It Does:</strong></p><ul><li>If you add spring-boot-starter-web, Spring Boot automatically sets up an embedded web server (like Tomcat) and gets request handling ready to go.</li><li>Include spring-boot-starter-data-jpa, and it configures database connections, scans for entities, and sets up repositories—all without you lifting a finger.</li></ul><p><strong>How It Works:</strong></p><ul><li>Spring Boot scans your classpath to spot libraries and annotations.</li><li>It matches these against a library of predefined configurations stored in @Configuration classes.</li><li>These configurations are conditional—they only kick in if certain conditions are met (e.g., the presence of a web starter triggers a Tomcat setup).</li><li>You can customize or disable this with properties or the exclude attribute if needed.</li></ul><h3><strong>4. Spring Boot Starters Dependencies</strong></h3><p>One of the biggest pain points in Spring framework was managing dependencies. Each module (like Spring MVC, Spring Data JPA, or security) required manual dependency management and this often leading to version conflicts and bloated configurations.</p><p>Spring Boot solves this problem with&nbsp;starter dependencies that are predefined sets of dependencies bundled for specific functionalities.</p><p><strong>How It Works:</strong></p><ul><li>Starters (e.g.,&nbsp;<code><strong>spring-boot-starter-web</strong></code>,&nbsp;<code><strong>spring-boot-starter-data-jpa</strong></code>) group related dependencies together.</li><li>Instead of adding individual libraries (like Tomcat, Jackson, Hibernate), you include a single starter.</li><li>Spring Boot ensures all included libraries versions are compatible with each-other.</li></ul><h3><strong>5. Embedded Servers</strong></h3><p>Traditional Java web applications require deploying WAR files to external servers like Tomcat or Jetty But Spring Boot allows you to run your application as a standalone application without needing a separate server.</p><p><strong>How It Works:</strong></p><ul><li>The&nbsp;<code>spring-boot-starter-web</code>&nbsp;includes an embedded Tomcat server by default.</li><li>When you include a web starter, During the application startup Spring Boot automatically bundles an embedded Tomcat server.</li><li>The server is started when the&nbsp;<code>SpringApplication.run()</code>&nbsp;method is called.</li></ul><h3><strong>6. Externalized Configuration (properties/yml)</strong></h3><p>Hardcoding configuration details like database passwords, API keys, or server ports directly in your code is risky&nbsp;and inflexible. So Spring Boot fixes this problem with externalized configuration with a way to store settings outside your code, making your app more secure and easier to manage.</p><p><strong>How It Works:</strong></p><ul><li>You store configurations in application.properties or application.yml files.</li><li>These can include settings like server ports, database URLs, or logging levels.</li><li>You can create different profiles (e.g., application-dev.properties for development, application-prod.properties for production) to switch settings based on the environment.</li></ul><p>Here is an example of application.properties file:</p><pre><code class="language-java">spring.datasource.url=jdbc:mysql://localhost:3306/mydb  
spring.datasource.username=admin  
spring.datasource.password=secret123  </code></pre><h3><strong>7. SpringApplication.run() - The Entry Point</strong></h3><p>Every Spring Boot application starts with a&nbsp;<code>main()</code>&nbsp;method calling&nbsp;<code>SpringApplication.run()</code>. But what happens behind this simple line?</p><p>Step-by-Step Breakdown:</p><ul><li><strong>Execution Begins</strong>: Your main() method, usually in a class annotated with @SpringBootApplication, runs and calls SpringApplication.run().</li><li><strong>Application Context Creation</strong>: Spring Boot builds the ApplicationContext, the container that holds all your beans (objects managed by Spring). It scans for annotations like @Component, @Service, or @Repository.</li><li><strong>Auto-Configuration Applied</strong>: Based on your classpath dependencies (e.g., web or JPA starters), Spring Boot applies the right configurations.</li><li><strong>Embedded Server Startup</strong>: If a web starter is present, it starts the embedded server (e.g., Tomcat) and sets it to listen on your configured port (default is 8080).</li><li><strong>Initialization Complete</strong>: Any ApplicationContextInitializer or ApplicationListener beans run to perform custom setup tasks.</li><li><strong>Application Ready</strong>: Once the server is up and the context is fully initialized, your app is live, ready to handle requests.</li></ul><h3><strong>Conclusion:</strong></h3><p>Spring Boot simplifies development by handling most of the configurations for you. With features like Auto-Configuration, Starter Dependencies, Embedded Servers and Externalized Configurations helps to build Spring Boot applications fast and hassle-free.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot</category>
            <category>Internal Working Of Spring Boot</category>
            <category>Spring Boot Interview</category>
            <category>Auto-Configurations</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/13_5056e78e24.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 15 JPA Annotations in Spring Boot (With Easy Examples)]]></title>
            <link>https://www.codingshuttle.com/blogs/top-10-jpa-annotations-in-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/top-10-jpa-annotations-in-spring-boot</guid>
            <pubDate>Sat, 05 Jul 2025 08:33:41 GMT</pubDate>
            <description><![CDATA[Discover the 15 most essential JPA annotations in Spring Boot with beginner-friendly explanations and real-world examples. Learn how to map Java classes to database tables, define relationships, and simplify persistence without writing SQL.]]></description>
            <content:encoded><![CDATA[<p><strong>JPA</strong> stands for <strong>Java Persistence API</strong>. it is a specification in Java that provides a standard way to map Java objects or entities to tables in database. It helps developers to perform database operations without writing complex SQL queries manually.</p><p>Before JPA annotations, developers used to interact with database using raw JDBC code. and for this developers need to manually write SQL queries for all database operations. but JPA annotations make much easier when its time to interacting with databases.</p><p>In this article, you will learn the <strong>top 15 essential JPA annotations</strong> that make it easy to map Java classes to database tables, define relationships between entities, and manage data persistence without writing raw SQL.</p><p>So if you are building any project that involves database interactions mastering these annotations is like necessary.</p><h3><strong>1. @Entity</strong></h3><p>The @Entity annotations is most basic annotation in JPA. this annotation is used to mark a Java class as a database entity. that means the class will be mapped to a table in your database. each field in your entity class represents a column in the database table.</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class Product {

    @Id
    private Long id;
    private String name;
    private double price;
}</code></pre><h3><strong>2. @Table</strong></h3><p>The @Table annotations is used to provide additional information about table in database. So as i mentioned before the @Entity annotation marks a class as a database entity but the @Table annotation is used to customize the table's name, schema, and unique constraints etc.</p><p>Example:</p><pre><code class="language-java">@Entity
@Table(name = "products")
@Data
public class Product {

    @Id
    private Long id;
    private String name;
    private double price;
}</code></pre><p>In this example the Java class is Product but the table in the database will be created as “products” because of the @Table(name = "products") annotation.</p><h3><strong>3. @Id</strong></h3><p>In the previous examples you have already seen this @Id annotation inside Product class, so now lets understand this annotation. The @Id annotation is used to specify the <strong>primary key</strong> of an entity it means field that is annotated with @Id annotation acts as a primary key column in database Example:</p><pre><code class="language-java">@Entity
@Data
public class Product {

    @Id
    private Long id;
    private String name;
    private double price;
}</code></pre><p>here the field marked with @Id is treated as <strong>primary key</strong> in the your database Product table.</p><h3><strong>4. @GeneratedValue</strong></h3><p>The @GeneratedValue annotation is used along with @Id annotation so it automatically generate the primary key value for new records, and that is why you do not need to manually assign primary key value for each entry. If you <strong>don’t</strong> use @<strong>GeneratedValue annotation</strong>, you must manually set the value of the primary key every time you create a new entity.</p><p>Also we specify strategies in @GeneratedValue to define how the value should be assign.</p><p>Here is the most common GenerationType Strategies</p><ol><li>GenerationType.IDENTITY : Database auto-increments the ID (most common with MySQL).</li><li>GenerationType.SEQUENCE : Uses database sequences (common in Oracle, PostgreSQL).</li><li>GenerationType.AUTO : JPA picks the strategy based on the database.</li></ol><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}</code></pre><p>Here in product table you do not need to specify the id value each time when you are saving entity because JPA automatically handles the id generation using auto-increment.</p><h3><strong>5. @Column</strong></h3><p>The @Column annotation is used to map entity class field with column in a database table but JPA automatically maps fields to columns by default but this annotation is allows you to specify attributes of the column.</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "product_name", nullable = false, length = 100)
    private String name;

    @Column(nullable = false)
    private double price;
}</code></pre><p>Here is the explanation</p><p>→ name = "product_name", maps name field to product_name in database table column.</p><p>→ nullable = false, specify that the column cannot be NULL.</p><p>→ length = 100, specify that maximum length of the column is 100 characters.</p><h3><strong>6. @Transient</strong></h3><p>The @Transient annotation is used to mark entity field that this field should not be persisted to the table column. So if any field marked with <code>@Transient</code> will be ignored by JPA when performing database operations <code>save()</code>, <code>update()</code>, or fetching records. we use these kind of fields that is needed in business logic, but should not exists in the database table. Example:</p><pre><code class="language-java">@Entity
@Data
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private double price;
    private double tax;

    @Transient
    private double finalPrice;
}</code></pre><p>In this entity “finalPrice” field completely ignore during table creation and any database operations.</p><h3><strong>7. @OneToOne</strong></h3><p>The @OneToOne annotation is used to define a one-to-one relationship between two entities, in simple terms one record in Table A is directly linked to one and only one record in Table B</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToOne
    private Passport passport;
}</code></pre><p>Here the User entity has a reference to the Passport entity and JPA will automatically manage this relationship because of @OneToOne annotation.</p><h3><strong>8. @OneToMany</strong></h3><p>The @OneToMany annotation is used to define a one-to-many relationship between two entities , in simple terms one record in Table A is related to multiple records in Table B. This is a very common relationship in real-world applications.</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "user")
    private List&lt;Order&gt; orders;
}</code></pre><p>Here the User entity has a list of Order entities, we indicate that one&nbsp;id&nbsp;in the user class can have many orders from other entity called Order.</p><h3><strong>9. @ManyToOne</strong></h3><p>The @ManyToOne annotation is used to define a many-to-one relationship between two entities, in simple terms many records in Table A are related to one record in Table B. This is the reverse side of a @OneToMany relationship.</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String product;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}</code></pre><p>Here the Order entity has a user field with @ManyToOne annotation it means many Orders can be linked to one User.</p><h3><strong>10. @ManyToMany</strong></h3><p>The <code>@ManyToMany</code> annotation is used to define a <strong>many-to-many relationship</strong> between two entities, in simple terms many records in Table A are related to many records in Table B. in this type of relationship JPA creates a new mapping table to store references.</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private List&lt;Course&gt; courses;
}</code></pre><p>Here the Student entity has a list of Course entities and @JoinTable annotation creates a join table named student_course to manage the many-to-many relationship. this join table has two columns: student_id and course_id.</p><h3><strong>11. @JoinColumn</strong></h3><p>The <code>@JoinColumn</code> annotation is used to specify the foreign key column in relationships like <code>@ManyToOne</code>, <code>@OneToOne</code>, or even in <code>@OneToMany</code>. Without this annotation, JPA will create the join column with a default name, but with <code>@JoinColumn</code> you can customize the column name and its constraints.</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String product;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
}</code></pre><p>Here, <code>@JoinColumn(name = "user_id")</code> tells JPA to use a column named <code>user_id</code> in the <code>Order</code> table to link to the <code>User</code> entity. The <code>nullable = false</code> ensures every order must be linked to a user.</p><h3><strong>12. @JoinTable</strong></h3><p>The <code>@JoinTable</code> annotation is used with <code>@ManyToMany</code> relationships to define the join (linking) table and its join columns. By default, JPA generates a join table for <code>@ManyToMany</code>, but this annotation lets you customize its name and structure.</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class Teacher {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToMany
    @JoinTable(
        name = "teacher_subject",
        joinColumns = @JoinColumn(name = "teacher_id"),
        inverseJoinColumns = @JoinColumn(name = "subject_id")
    )
    private List&lt;Subject&gt; subjects;
}</code></pre><p>In this example, a join table named <code>teacher_subject</code> is created with two foreign key columns: <code>teacher_id</code> and <code>subject_id</code>, which connect the two entities.</p><h3><strong>13. @Embedded</strong></h3><p>The <code>@Embedded</code> annotation is used when you want to include reusable value-type components (non-entity objects) inside your entity class. These embedded objects don’t have a separate table — their fields are stored as part of the entity’s table.</p><p>Example:</p><pre><code class="language-java">@Embeddable
@Data
public class Address {
    private String street;
    private String city;
    private String zip;
}

@Entity
@Data
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Embedded
    private Address address;
}</code></pre><p>Here, the <code>Address</code> class is embedded inside the <code>Customer</code> table — all its fields (street, city, zip) will become columns in the <code>Customer</code> table.</p><h3><strong>14. @Embeddable</strong></h3><p>The <code>@Embeddable</code> annotation is used on the class that is going to be embedded using <code>@Embedded</code>. It marks that the class is not a full entity but a value object that can be part of other entities.</p><p>This annotation works hand-in-hand with <code>@Embedded</code>.</p><p>Example:</p><pre><code class="language-java">@Embeddable
@Data
public class Address {
    private String street;
    private String city;
    private String zip;
}</code></pre><p>In this case, the <code>Address</code> class is treated as a reusable component that can be used in multiple entities (e.g., <code>Customer</code>, <code>Employee</code>, etc.) without creating a separate table.</p><h3><strong>15. @Lob</strong></h3><p>The <code>@Lob</code> annotation is used when you want to store large objects like text, images, or files in the database. It stands for <strong>Large Object</strong>, and it helps JPA decide whether to store a field as a BLOB (Binary Large Object) or CLOB (Character Large Object) depending on the field type.</p><p>Example:</p><pre><code class="language-java">@Entity
@Data
public class Document {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @Lob
    private String content; // Large text content

    @Lob
    private byte[] fileData; // Binary file (e.g., PDF, image)
}</code></pre><p>Here, <code>content</code> will be stored as CLOB and <code>fileData</code> as BLOB. This is especially useful for documents, images, or file upload scenarios.</p><h3>Conclusion</h3><p>I hope you now have a clear understanding of each JPA annotation covered in this article. These annotations make it easy to map Java classes to database tables, define relationships like one-to-many or many-to-one, and manage data persistence with minimal effort.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>JPA</category>
            <category>Annotations</category>
            <category>Java Persistence API</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/14_6625159d9f.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 20 Essential Spring Boot Annotations for Interviews and Real-World Projects]]></title>
            <link>https://www.codingshuttle.com/blogs/top-15-essential-spring-boot-annotations-for-interviews-and-real-world-projects</link>
            <guid>https://www.codingshuttle.com/blogs/top-15-essential-spring-boot-annotations-for-interviews-and-real-world-projects</guid>
            <pubDate>Sat, 05 Jul 2025 08:27:33 GMT</pubDate>
            <description><![CDATA[Learn the Top 20 Essential Spring Boot Annotations with real-world examples. Master how, where, and why to use them for building scalable, production-ready Java applications.]]></description>
            <content:encoded><![CDATA[<p>When we first start learning Spring Boot, let’s be honest , most of us don’t really understand the actual purpose behind the annotations we use.</p><p>We just memorize things like, I need to put this annotation on the class, this one on the method*,* and somehow the project starts working. But we don’t know why we are doing it and we are just following patterns without really understanding them.</p><p>So using annotations blindly in your project means you are missing out on the bigger picture. So in this article, I am sharing the <strong>Top 20 Essential Spring Boot Annotations</strong>, with detailed explanations like <strong>what is the purpose of each annotation and where exactly it should be placed (class, method, field, etc.), and why it is used.</strong></p><p>And trust me, understanding these annotations properly makes your life much easier and next time you work on a Spring Boot project you can relate these annotations. also it is very important from an interview perspective because interviewers want you to explain these annotations in detail.</p><p>so let’s dive into these top 20 essential annotations in spring boot.</p><h3><strong>1. @SpringBootApplication</strong></h3><p>So, let’s start with the first and one of the most important annotations is @SpringBootApplication. I am sure you have already seen this annotation if you have ever created a Spring Boot project.</p><p>The @SpringBootApplication is typically placed on the <strong>main class</strong> of your Spring Boot project and the reason is simple: this annotation acts as the <strong>entry point</strong> of your application.</p><p>But here is the interesting part that the @SpringBootApplication isn’t just one annotation, it is actually a <strong>combination of three important annotations</strong>. So once you understand these three annotations you basically mastered @SpringBootApplication.</p><ul><li><strong>@Configuration</strong> – This marks the class as a source of bean definitions. In simple terms, this is where Spring knows it can find configuration and beans.</li><li><strong>@EnableAutoConfiguration</strong> – This enables Spring Boot's auto-configuration feature. Spring looks at your project setup, dependencies, and configurations, and automatically sets up a lot of things for you so you don’t have to manually configure everything.</li><li><strong>@ComponentScan</strong> – This enables component scanning for your package and sub-packages. It tells Spring to look for classes annotated with @Component, @Service, @Repository, @Controller, etc., and automatically register them in the application context.</li></ul><p>One last thing, this annotation is typically placed on a <strong>class</strong>, specifically the main class where your application starts.</p><h3><strong>2. @Component</strong></h3><p>The second important annotation is @Component. This annotation is used to create beans in a Spring Boot application. In simple terms, @Component is used to mark a class as a Spring bean, which means that class will be managed by the Spring container.</p><p>You can apply this annotation to a Class, interface, enum, or record, but in real-world projects, we mostly place it on classes.</p><p>So whenever you want Spring to manage your class and automatically create its object as a bean, just put @Component on top of that class.</p><p>Here is an example of @Component annotation :</p><pre><code class="language-java">@Component
public class MyBean {
    public void show() {
        System.out.println("Bean created by Spring");
    }
}</code></pre><h3>3. @Service</h3><p>The next important annotation is @Service. This annotation is used to tell Spring that this class is a <strong>service component</strong> in your project. In simple words, we use @Service to mark classes that contain our <strong>business logic</strong>, meaning this is where your main application logic lives.</p><p>Like @Component annotations you can apply this annotation to a <strong>class</strong>, <strong>interface</strong>, <strong>enum</strong>, or <strong>record</strong>, but most of the time, we place it on <strong>classes</strong>.</p><p>Here is an example of @Service annotation :</p><pre><code class="language-java">@Service
public class ProductService{
    // business logic here
}</code></pre><h3>4. @Repository</h3><p>The @Repository annotation is used to mark a class as a <strong>Data Access Object (DAO)</strong>. We use this for classes that handle <strong>database interaction logic</strong>, like talking to the database using JPA or JDBC.</p><p>Again, you can apply this annotation to a <strong>class</strong>, <strong>interface</strong>, <strong>enum</strong>, or <strong>record</strong>, but mostly it’s placed on classes that deal with database operations.</p><p>Here is an example of @Repository annotation :</p><pre><code class="language-java">public interface EmployeeRepository extends JpaRepository&lt;Employee, Long&gt; {
    List&lt;Employee&gt; findByEmail(String email);
}</code></pre><h3>5. @<strong>RestController</strong></h3><p>The @RestController annotation marks a class as a <strong>REST Controller</strong>, which is used to create RESTful APIs in Spring Boot. It is basically a shortcut for @Controller + @ResponseBody. That means whatever data your methods return is written directly to the <strong>HTTP response</strong>, no need to use @ResponseBody separately.</p><p>Again, this annotation can be applied to a <strong>class</strong>, <strong>interface</strong>, <strong>enum</strong>, or <strong>record</strong>, but in most projects, you will see it on classes.</p><p>Here is an example of @RestController annotation :</p><pre><code class="language-java">@RestController
public class HelloController {
    
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello from API!";
    }
}</code></pre><h3><strong>6. @Autowired</strong></h3><p>The @Autowired annotation is used to <strong>automatically inject dependencies</strong> in Spring Boot. In simple terms, Spring will look for a matching bean and inject it for you, so you do not need to create objects using new keyword.</p><p>It works by type and can be applied to <strong>constructors</strong>, <strong>methods</strong>, <strong>fields</strong>, or <strong>parameters</strong>.</p><p>Here is an example of @Autowired annotation :</p><pre><code class="language-java">@Component
public class Car {
    @Autowired
    private Engine engine;
}</code></pre><h3><strong>7. @Qualifier</strong></h3><p>Sometimes, when you have <strong>multiple beans of the same type</strong>, Spring doesn’t know which one to inject. That’s where @Qualifier helps. It works along with @Autowired to tell Spring <strong>exactly which bean</strong> to inject by specifying the bean name.</p><p>And you can use @Qualifier on <strong>fields</strong>, <strong>parameters</strong>, or <strong>methods</strong>.</p><p>Here is an example of @Qualifier annotation :</p><pre><code class="language-java">@Component("petrolEngine")
public class PetrolEngine implements Engine {}

@Component("dieselEngine")
public class DieselEngine implements Engine {}

@Component
public class Car {
    
    @Autowired
    @Qualifier("dieselEngine")
    private Engine engine;
}</code></pre><h3><strong>8. @Configuration</strong></h3><p>The @Configuration annotation is used to mark a class as a <strong>source of bean definitions</strong>. In simple terms this is your configuration class, where you define beans manually using @Bean methods.</p><p>You can place this annotation on a <strong>class</strong>, <strong>interface</strong>, <strong>enum</strong>, or <strong>record</strong>, but mostly we use it on <strong>classes</strong></p><p>Here is an example of @Configuration annotation : .</p><pre><code class="language-java">@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}</code></pre><h3><strong>9. @Bean</strong></h3><p>The @Bean annotation is used to <strong>manually declare a bean</strong> in your Spring configuration class. It is placed on methods inside a class marked with @Configuration. The method returns the object that Spring will manage as a bean.</p><p>This annotation is only applied to <strong>methods</strong>.</p><p>Here is an example of @Bean annotation :</p><pre><code class="language-java">@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}</code></pre><h3><strong>10. @Value</strong></h3><p>The @Value annotation helps inject <strong>external values</strong>, like properties from application.properties, application.yml, or environment variables, directly into your Spring beans.</p><p>Example:</p><p>@Value("${server.port}") injects the port value from your properties file.</p><p>You can apply @Value to <strong>fields</strong>, <strong>parameters</strong>, or <strong>methods</strong>.</p><h3><strong>11. @RequestMapping</strong></h3><p>The @RequestMapping annotation is used to <strong>map HTTP requests to handler methods</strong> or even at the class level. It supports multiple HTTP methods like GET, POST, PUT, DELETE, etc., so it’s quite flexible.</p><p>And you can place this annotation at both <strong>class-level</strong> and <strong>method-level</strong>.</p><p>Here is an example of @RequestMapping annotation :</p><pre><code class="language-java">@RestController
@RequestMapping("/api")
public class ApiController {

    @RequestMapping("/hello")
    public String hello() {
        return "Hello API";
    }
}</code></pre><h3><strong>12. @PathVariable</strong></h3><p>The @PathVariable annotation is used to extract values from the <strong>URI path</strong>.</p><p>Example:</p><p>If your endpoint is /user/{id}, you can get that id value using @PathVariable("id") Long id in your method parameter.</p><p>So that is why this annotation is applied to <strong>method parameters</strong>.</p><p>Here is an example of @PathVariable annotation :</p><pre><code class="language-java">@GetMapping("/user/{id}")
public String getUser(@PathVariable("id") Long userId) {
    return "User ID is " + userId;
}</code></pre><h3><strong>13. @RequestParam</strong></h3><p>The @RequestParam annotation is used to bind <strong>request parameters</strong>, like query strings or form data, to method parameters.</p><p>Example:</p><p>If your URL is /search?query=java, you can capture the query value like this in your method parameter</p><p>@RequestParam("query") String keyword</p><p>This annotation is applied to <strong>method parameters</strong>.</p><p>Here is an example of @RequestParam annotation :</p><pre><code class="language-java">@GetMapping("/search")
public String search(@RequestParam("keyword") String keyword) {
    return "Searching for: " + keyword;
}</code></pre><h3><strong>14. @Transactional</strong></h3><p>The @Transactional annotation is used to manage <strong>database transactions</strong>. It ensures that a method runs inside a transaction boundary, so either everything inside the method completes successfully or everything rolls back if something fails. and it supports features like rollback, isolation, and propagation settings.</p><p>You can apply @Transactional to classes or methods. Applying it to a class means that all methods inside that class will be executed within a transaction.</p><pre><code class="language-java">@Transactional
public void makePayment() {
	// transaction starts
	// perform multiple DB operations
	// commit if successful, rollback if any exception
}</code></pre><h3><strong>15. @ConditionalOnClass &amp; @ConditionalOnBean</strong></h3><p>These are part of Spring Boot’s <strong>conditional annotations</strong>, mostly used for <strong>auto-configuration</strong>.</p><ol><li>@ConditionalOnClass: The bean will only be registered if the <strong>specified class</strong> is present in the classpath.</li><li>@ConditionalOnBean: The bean will only be registered if the <strong>specified bean</strong> already exists in the Spring context.</li></ol><p>You can apply these annotations to <strong>configuration classes</strong> or <strong>bean methods</strong>.</p><p>Here is an example of @ConditionalOnClass annotation :</p><pre><code class="language-java">@Configuration
public class MyConfig {

    @Bean
    @ConditionalOnClass(name = "com.mysql.cj.jdbc.Driver")
    public DataSource dataSource() {
        return new HikariDataSource();
    }
}</code></pre><h3><strong>16. @GetMapping, @PostMapping, @PutMapping, @DeleteMapping</strong></h3><p>These annotations are shortcuts for <code>@RequestMapping</code> with specific HTTP methods. Instead of using <code>@RequestMapping(method = RequestMethod.GET)</code>, you can just use <code>@GetMapping</code>, and similarly for others.</p><ul><li><code>@GetMapping</code> is used to handle GET requests (like fetching data).</li><li><code>@PostMapping</code> is used for POST requests (usually to create data).</li><li><code>@PutMapping</code> is used for updating existing data.</li><li><code>@DeleteMapping</code> is used to delete data.</li></ul><p>These are applied to <strong>methods</strong> inside controller classes.</p><p>Here is an example:</p><pre><code class="language-java">@RestController
public class ProductController {

    @GetMapping("/products")
    public List&lt;Product&gt; getAllProducts() {
        return productService.findAll();
    }

    @PostMapping("/products")
    public Product createProduct(@RequestBody Product product) {
        return productService.save(product);
    }

    @PutMapping("/products/{id}")
    public Product updateProduct(@PathVariable Long id, @RequestBody Product product) {
        return productService.update(id, product);
    }

    @DeleteMapping("/products/{id}")
    public void deleteProduct(@PathVariable Long id) {
        productService.delete(id);
    }
}</code></pre><h3><strong>17. @EnableJpaRepositories</strong></h3><p>This annotation is used to enable JPA repositories in your Spring Boot application. It tells Spring where to look for interfaces that extend <code>JpaRepository</code> or <code>CrudRepository</code>.</p><p>Usually, you place this annotation in your <strong>configuration class</strong> or <strong>main class</strong>, and you can specify the package where your repositories are located.</p><p>Here is an example:</p><pre><code class="language-java">@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.example.repository")
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}</code></pre><h3><strong>18. @EnableTransactionManagement</strong></h3><p>This annotation is used to enable Spring’s annotation-driven transaction management. If you are using <code>@Transactional</code>, this annotation makes sure that transaction management works correctly behind the scenes.</p><p>It is usually placed on a <strong>configuration class</strong>.</p><p>Here is an example:</p><pre><code class="language-java">@Configuration
@EnableTransactionManagement
public class PersistenceConfig {
    // Your DataSource and EntityManager config
}</code></pre><h3><strong>19. @CrossOrigin</strong></h3><p>The <code>@CrossOrigin</code> annotation is used to enable Cross-Origin Resource Sharing (CORS) in your APIs. This is helpful when your frontend is running on a different domain or port than your backend.</p><p>You can apply this annotation to a <strong>class</strong> or <strong>method</strong> inside your REST controller.</p><p>Here is an example:</p><pre><code class="language-java">@RestController
@CrossOrigin(origins = "&lt;http://localhost:3000&gt;")
public class UserController {

    @GetMapping("/users")
    public List&lt;User&gt; getAllUsers() {
        return userService.findAll();
    }
}</code></pre><h3><strong>20. @ResponseStatus</strong></h3><p>This annotation is used to define the HTTP status code that should be returned from a method. It's very useful in exception handling or when you want to send a specific status like 201 (Created), 404 (Not Found), etc.</p><p>It is usually applied to <strong>methods</strong> or <strong>custom exception classes</strong>.</p><p>Here is an example:</p><pre><code class="language-java">@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}</code></pre><h2><strong>Conclusion:</strong></h2><p>In this article we have learned top 20 essential annotations that every Spring Boot developer should know and these annotations also important in interview perspective as well as building real-world Spring Boot projects.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Annotations</category>
            <category>Spring Boot Interview</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/15_12da5ddb5c.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[12 Spring Boot REST API Best Practices to Build Scalable & Secure Applications]]></title>
            <link>https://www.codingshuttle.com/blogs/best-practices-for-writing-spring-boot-api</link>
            <guid>https://www.codingshuttle.com/blogs/best-practices-for-writing-spring-boot-api</guid>
            <pubDate>Sat, 05 Jul 2025 08:20:54 GMT</pubDate>
            <description><![CDATA[Learn Spring Boot API Best Practices to build scalable, secure, and production-ready REST APIs with proper naming, status codes, DTOs, validation, and exception handling.]]></description>
            <content:encoded><![CDATA[<p>If you are diving into building APIs with Spring Boot then writing APIs that are just work is good but not enough because when you are working on real world applications, APIs that are created with best practices make your development more easier.</p><p>So in this article, I am sharing some real world spring boot API best practices that will help to create scalable, secure, and production ready APIs.</p><h2>1. Use Meaningful &amp; Consistent API Naming</h2><p>When it is time to define API endpoint names in your application use nouns that accurately reflect the resources your API manages (e.g., /products, /users). This makes your APIs more predictable for consumers.</p><p>Here is an example of products crud API endpoint naming convention :</p><pre><code class="language-java">GET    /api/products          // Get all products
GET    /api/products/{id}     // Get product by ID
POST   /api/products          // Create new product
PUT    /api/products/{id}     // Update product
DELETE /api/products/{id}     // Delete product</code></pre><h2>2. Follow a Consistent Project Structure</h2><p>Building APIs with well-organized project structure helps in easy collaboration as well as enhances code readability. It also promotes testing and faster debugging.</p><p>Here is an example of consistent Project Structure :</p><pre><code class="language-java">src/main/java/com/example/project
├── controller    // API endpoints
├── service       // Business logic
├── repository    // Data access layer
├── dto           // Data Transfer Objects
├── model/entity  // Database entities
├── config        // Configuration classes
├── exception     // Custom exceptions</code></pre><h2><strong>3. Use RESTful Conventions</strong></h2><p>When you are building APIs, every API should follow proper HTTP method conventions to make your API predictable and easy to understand for other developers</p><p>Here is an example of using proper HTTP methods :</p><pre><code class="language-java">GET	   =&gt; Retrieve data	              
POST   =&gt; Create a new resource	      
PUT	   =&gt; Update an existing resource	
PATCH	 =&gt; Partially update a resource
DELETE =&gt; Remove a resource	          </code></pre><h2><strong>4. Use Meaningful Status Codes</strong></h2><p>There are many new developers are return <code>200 OK</code> for every response even if something went wrong. which creates confusion for any client. HTTP status codes are useful to tell the client exactly what happened with their request. So using them properly makes your APIs more predictable. Here are some common status codes you should use :</p><pre><code class="language-java">1. 200 OK for success
2. 201 Created for new resources
3. 400 Bad Request for invalid input
4. 404 Not Found when resource doesn’t exist
5. 500 Internal Server Error for unexpected issues</code></pre><h2><strong>5. Use DTOs for Request and Response</strong></h2><p>Exposing entity classes is risky and leads to tight coupling between your API and database structure. So that is why always use DTO (Data Transfer Objects) for receiving data as well as sending data to client.</p><p>For example for user entity we do not share password field in response :</p><pre><code class="language-java">public class UserResponseDto{
    private Long id;
    private String name;
    private String email;
}</code></pre><h2><strong>6. Use V</strong>alidation in DTOs</h2><p>In real world applications never trust the client because they can send incomplete, incorrect, or even malicious data that can break your application. So adding validation in DTO (Data Transfer Objects) helps to avoid incorrect or malicious data.</p><p>Here is an example of adding validation in request DTO :</p><pre><code class="language-java">@Data
public class UserRequestDTO {

    @NotBlank(message = "Name is required")
    private String name;
    
    @Email(message = "Email is not valid")
    private String email;

    @Positive(message = "Age must be greater than 0")
    private int age;
    
    @NotBlank(message = "Password is required")
    private String password;
}</code></pre><h2><strong>7. Use Pagination For Large Dataset</strong></h2><p>When you have thousands or even millions of records in your database and returning all records from one API will slow down your API or overload your server or even some times it will crash the client-side application. That is why Pagination is a must for APIs that deal with large datasets. Pagination helps to split the data into smaller chunks (pages). Here is an example of paginated API in Spring Boot :</p><pre><code class="language-java">@GetMapping("/products")
public Page&lt;ProductResponseDTO&gt; getAllProducts(Pageable pageable) {
    return productService.getAllProducts(pageable);
}</code></pre><h2><strong>8. Use Proper Exception Handling</strong></h2><p>In our project there is a chance that something unexpected happens on the server like record not found, invalid data etc. If you do not handle these kind of exceptions properly, your API will send error messages or even stack traces to the client which is risky. That is why Exception Handling is one of the most important best practices when building Spring Boot APIs.</p><p>Spring Boot provides a clean way to handle exceptions globally using @ControllerAdvice :</p><pre><code class="language-java">@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(RuntimeException.class)
		public ResponseEntity&lt;String&gt; handleRuntimeException(RuntimeException ex) {
		    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
													   .body(ex.getMessage());
		}
		
}</code></pre><h2><strong>9.</strong> Validate Input Data</h2><p>Always validate incoming data to protect your API from bad requests. Use @Valid with Bean Validation annotations like @NotNull, @Size, or @Email.</p><p><strong>Example Approach:</strong></p><ul><li>Annotate your DTO (Data Transfer Object) class with validation constraints.</li><li>Handle validation errors with a custom MethodArgumentNotValidException handler.</li></ul><p>Example :</p><pre><code class="language-java">// UserDTO.java
@Data
public class UserDTO {

    @NotBlank(message = "Username is required")
    @Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters")
    private String username;

    @NotBlank(message = "Email is required")
    @Email(message = "Email should be valid")
    private String email;

    @NotBlank(message = "Password is required")
    @Size(min = 6, message = "Password must be at least 6 characters")
    private String password;
 }
 
 
 // UserController.java
  @RestController
	@RequestMapping("/api/users")
	public class UserController {
	
	    @PostMapping("/register")
	    public ResponseEntity&lt;String&gt; registerUser(@RequestBody @Valid UserDTO userDTO) {
	        // If validation passes, continue with registration logic
	        return ResponseEntity.ok("User registered successfully!");
	    }
	}</code></pre><h2>10. Secure Your API</h2><p>Security is a must! Use spring-boot-starter-security to add authentication and authorization. Implement JWT tokens or OAuth2 for secure access, and restrict endpoints based on roles.</p><p>Example :</p><pre><code class="language-java">@EnableWebSecurity
public class SecurityConfig {
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }
}</code></pre><h2>11. Version Your APIs</h2><p>As your API evolves, version it to avoid breaking existing clients. Use a versioning strategy like /v1/users.</p><pre><code class="language-java">@GetMapping("/v1/users")
public List&lt;UserResponseDTO&gt; getUsersV1() {
    return userService.getAllUsers();
}</code></pre><h2>12. Document Your API</h2><p>Good documentation is a lifesaver for users. Use tools like Springdoc OpenAPI (Swagger) to generate interactive API docs automatically from your code.</p><p>Example :</p><pre><code class="language-java">@Operation(summary = "Get all users")
@GetMapping("/users")
public List&lt;UserResponseDTO&gt; getAllUsers() {
    return userService.getAllUsers();
}</code></pre><h3><strong>Conclusion:</strong></h3><p>By following these best practices for writing spring boot APIs in real-world application makes your APIs clean, efficient, and secure. Also your APIs become predictable with proper endpoint naming, status codes help clients easily understand responses, and for large datasets, pagination ensures quick and efficient data retrieval, making your APIs reliable and performance-friendly.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Rest APIs</category>
            <category>API Design Best Practices</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/best_ways_to_write_spring_boot_apis_7783efba49.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot Folder Structure (Best Practices)]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-boot-folder-structure-best-practices</link>
            <guid>https://www.codingshuttle.com/blogs/spring-boot-folder-structure-best-practices</guid>
            <pubDate>Sat, 05 Jul 2025 07:28:40 GMT</pubDate>
            <description><![CDATA[Learn the best Spring Boot project structure for clean, scalable, and production-ready applications. Organize your codebase with real-world folder structure examples.]]></description>
            <content:encoded><![CDATA[<p>When new spring boot developers start working with Spring Boot Project, they didn’t really care much about project structure.</p><p>It was one of those things where they just wanted the code to work but as projects grow and more classes and files created, that messy structure comes back to haunt you. so it feels frustrating and adding new features felt chaotic. so, a clean and well-organized folder structure isn’t just theoretical best practice it actually makes your life and your team’s life way easier.</p><p>In this blog, I’m sharing some Spring Boot folder structure best practices that will help you keep your codebase clean, maintainable, and easy to scale.</p><h3>But first… why should you even care about folder structure?</h3><p>Here’s what I have learned the hard way:</p><p><strong>1. Clarity &amp; Organization</strong></p><p><strong>2. Scalability</strong></p><p><strong>3. Code Reusability</strong></p><p><strong>4. Easier Testing &amp; Debugging</strong></p><p><strong>5. Friendly for New Team Members</strong></p><p>A good folder structure should help you clearly organize so your team can find files faster. It also promotes testing because you can quickly find the files you need to test or debug, and it avoids confusion during issue fixing bugs and updating existing code.</p><h3>Alright, let’s talk folder structure</h3><p>You’ve probably looked at a Spring Boot project and thought, *“*There are so many folders… do I really need all of these?”</p><p>Trust me, I’ve been there*.* But once your project starts growing, that structure saves you from chaos. So, here’s a breakdown of the well-recognized folder structure for Spring Boot apps, along with why each folder exists</p><h3>Following image shows the well recognized folder structure for Spring Boot application :</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/whole_Projet_9e54ff97bc.png" alt="Spring Boot Project Structure" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_whole_Projet_9e54ff97bc.png 195w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_whole_Projet_9e54ff97bc.png 500w," sizes="100vw"><figcaption>Spring Boot Project Structure</figcaption></figure><h3><strong>Let's understand each folder in great detail :</strong></h3><h3>1. advices.</h3><p>It holds classes like GlobalExceptionHandler to make sure your app returns clean, consistent error responses — no more random stack traces leaking to the client. You can also throw in response wrapper logic here if you want to standardize API responses.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/advices_9410fbb0f0.png" alt="Advices Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_advices_9410fbb0f0.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_advices_9410fbb0f0.png 500w," sizes="100vw"><figcaption>Advices Package</figcaption></figure><h3>2. configs</h3><p>This is where your app-level configurations live. Whether it’s setting up beans, defining global settings, or other custom configs — they all go here in neat, predictable files like AppConfig.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/configs_77e8fa0099.png" alt="Configs Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_configs_77e8fa0099.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_configs_77e8fa0099.png 500w," sizes="100vw"><figcaption>Configs Package&nbsp;</figcaption></figure><h3>3. controllers</h3><p>Your entry point to the outside world. This folder holds your REST API endpoints, handling all incoming HTTP requests and routing them to the right services. Basically, it connects your app to users or clients.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/controllers_143c523ce8.png" alt="Controller Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_controllers_143c523ce8.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_controllers_143c523ce8.png 500w," sizes="100vw"><figcaption>Controller Package</figcaption></figure><h3>4. dtos</h3><p>DTOs (Data Transfer Objects) are your data messengers. They carry structured data between different layers or between front-end and back-end. Keeping them in one place keeps your project clean and avoids mixing internal models with external-facing data.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/dtos_1440230c0f.png" alt="Dtos Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_dtos_1440230c0f.png 194w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_dtos_1440230c0f.png 500w," sizes="100vw"><figcaption>Dtos Package</figcaption></figure><h3>5. entities</h3><p>Your database blueprints live here. These classes represent your tables using JPA annotations, defining relationships, fields, and even enums when needed. They’re the backbone of your app’s data structure.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/entites_4ac239dce3.png" alt="Entities Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_entites_4ac239dce3.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_entites_4ac239dce3.png 500w," sizes="100vw"><figcaption>Entities Package</figcaption></figure><h3>6. exceptions</h3><p>You will have errors so it’s better to handle them properly. This folder contains custom exception classes to manage specific error situations in a clean, predictable way.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/exceptions_c9e4231277.png" alt="Exceptions Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_exceptions_c9e4231277.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_exceptions_c9e4231277.png 500w," sizes="100vw"><figcaption>Exceptions Package</figcaption></figure><h3>7. filters</h3><p>Filters are used to intercept incoming HTTP requests and outgoing responses, allowing you to perform operations like logging, authentication checks, or modifying requests before they reach controllers. The filters folder contains all the custom filters required in the application like JwtFilter and so on.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/filters_a12f5ff5e8.png" alt="Filters Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_filters_a12f5ff5e8.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_filters_a12f5ff5e8.png 500w," sizes="100vw"><figcaption>Filters Package</figcaption></figure><h3>8. repositories</h3><p>The repositories folder contains interfaces that are responsible for data access operations and interacting with the database. These interfaces typically extend Spring Data JPA repositories like JpaRepository that provide built-in CRUD functionality and allow custom query definitions.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/repositories_adf2f4a3c3.png" alt="Repositories Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_repositories_adf2f4a3c3.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_repositories_adf2f4a3c3.png 500w," sizes="100vw"><figcaption>Repositories Package</figcaption></figure><h3>9. services</h3><p>Where your business logic lives. Service interfaces define the logic, while their implementations (usually inside an implementations subfolder) contain the actual code. Keeping interfaces separate from implementations makes your app easier to test, extend, and refactor later.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/services_2805c82872.png" alt="Services Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_services_2805c82872.png 204w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_services_2805c82872.png 500w," sizes="100vw"><figcaption>Services Package</figcaption></figure><h3>10. utils</h3><ul><li>utils folder contains utility classes to keep the codebase organized and modular.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/utils_c34d0de847.png" alt="Utils Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_utils_c34d0de847.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_utils_c34d0de847.png 500w," sizes="100vw"><figcaption>Utils Package</figcaption></figure><h3>11. resources</h3><p>The heart of your config files. It stores things like <code>application.properties</code> or <code>application.yml</code> for environment-specific settings.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/resources_3af115aaa1.png" alt="Resources Package" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_resources_3af115aaa1.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_resources_3af115aaa1.png 500w," sizes="100vw"><figcaption>Resources Package</figcaption></figure><h3><strong>Conclusion:</strong></h3><p>By following a clean and consistent folder structure in your Spring Boot project, you make your codebase easy to navigate, maintainable, and ready to scale. It avoids chaos as your project grows, simplifies debugging.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Munaf Badarpura)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot Folder Structure</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/sprinb_boot_folder2_6d0bee7861.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[SAGA Pattern in Microservices with E-commerce Example]]></title>
            <link>https://www.codingshuttle.com/blogs/saga-pattern-in-microservices-with-e-commerce-example</link>
            <guid>https://www.codingshuttle.com/blogs/saga-pattern-in-microservices-with-e-commerce-example</guid>
            <pubDate>Tue, 13 May 2025 10:53:54 GMT</pubDate>
            <description><![CDATA[Learn the Saga Pattern in Microservices with a Real-World E-commerce Example. Understand how to handle distributed transactions using choreography and orchestration, the pros and cons of 2PC, 3PC, and why Saga is the better solution for data consistency in microservices.]]></description>
            <content:encoded><![CDATA[<p>If you've worked with microservices, chances are you've stumbled upon the term <strong>"Saga Pattern"</strong> at some point. Maybe in a Slack conversation, a tweet from a senior engineer, or that one architectural meeting where everyone was nodding (but only half of us actually knew what was going on 😅).</p><p>So today, I’m going to walk you through this magical concept — not in a robotic, textbook-y way — but like a friend helping you figure this out over a cup of coffee (virtual or real ☕).</p><p>Let’s do this! 🚀</p><h2>Introduction</h2><p>Let’s imagine you're shopping on your favorite e-commerce app 🛍️. You:</p><ol><li>Place an order for a brand-new pair of shoes 👟</li><li>Make the payment 💳</li><li>The system processes shipment 📦</li></ol><p>Now, let’s say everything goes smoothly — fantastic. But wait... what if your payment fails due to a banking glitch? Uh-oh.</p><p>In a <strong>monolithic app</strong>, you'd just roll back the entire transaction since it's all in one place — one database, one transaction scope. Easy-peasy.</p><p>But in a <strong>microservices</strong> setup:</p><ul><li>The <strong>Order Service</strong> creates the order.</li><li>The <strong>Payment Service</strong> handles the transaction.</li><li>The <strong>Shipment Service</strong> prepares to ship the product.</li></ul><p>Each of these has its <strong>own database</strong>. They don’t know what’s going on in the others.</p><p>So if payment fails, your order is still marked as placed unless someone tells the Order Service to cancel it. That’s bad UX. Even worse — it leads to <strong>data inconsistency</strong>.</p><p>🎉 And this is where the <strong>SAGA Pattern</strong> swoops in like a superhero 🦸.</p><h2>The Problem: Distributed Transactions</h2><p>In a monolith, you’ve probably used transactions like:</p><pre><code class="language-php">BEGIN TRANSACTION;
-- Do some stuff
-- Commit if everything's fine, or rollback if not</code></pre><p>All good. Everything is ACID compliant (Atomic, Consistent, Isolated, Durable).</p><p>But in <strong>distributed systems</strong>, there’s no shared database. Transactions are <strong>local</strong> to each microservice. So, if one operation fails, we have to manually undo everything else — and that gets messy fast.</p><p>That’s where <strong>distributed transaction patterns</strong> like <strong>2PC</strong>, <strong>3PC</strong>, and <strong>SAGA</strong> come into play.</p><h2>Two-Phase Commit (2PC)</h2><p><strong>How it works:</strong></p><ol><li><strong>Phase 1: Prepare</strong> – Each service says, "I’m ready to commit."</li><li><strong>Phase 2: Commit</strong> – If all say yes, the coordinator says, "Commit it all."</li></ol><h3>Example:</h3><p>Let’s say you’re placing that e-commerce order.</p><ul><li>Order Service: Ready</li><li>Payment Service: Ready</li><li>Shipment Service: Ready</li></ul><p>Cool. Everyone commits.</p><p>But… what if one of the services crashes <i>after</i> saying "ready" but <i>before</i> committing? 😬 Now you have inconsistent data.</p><h3>Drawbacks of 2PC:</h3><ul><li><strong>Blocking</strong>: Services wait on each other. Not good for performance.</li><li><strong>Single point of failure</strong>: Coordinator goes down? Game over.</li><li><strong>Not fault-tolerant</strong>: Crashes during commit phase = zombies 🧟</li></ul><h2>Three-Phase Commit (3PC)</h2><p>3PC adds a new phase called <strong>"Pre-Commit"</strong> to avoid those zombie states.</p><p><strong>Phases:</strong></p><ol><li>Can you commit? (Like 2PC’s Prepare)</li><li>Pre-commit (Everyone gets a heads-up to get ready)</li><li>Commit</li></ol><h3>Example:</h3><p>Placing the same e-commerce order.</p><ul><li>Phase 1: Everyone says "Yeah, I can commit."</li><li>Phase 2: "Okay, I’m preparing to commit."</li><li>Phase 3: "Do it now!"</li></ul><p>Sounds cool, right?</p><h3>Drawbacks:</h3><ul><li>Still <strong>slow</strong> (3 phases now).</li><li>Still relies on a <strong>central coordinator</strong>.</li><li><strong>Complex AF</strong> (especially when you factor in retries, network failures, etc.)</li></ul><p>So what do we do?</p><p>Say hello to our friendly pattern: <strong>SAGA</strong>.</p><h2>Enter the Saga Pattern</h2><p>Here’s the thing:</p><p>Instead of wrapping everything in a big, scary transaction, <strong>Saga breaks it down into smaller local transactions</strong>.</p><p>Each step is a local transaction. If one step fails, you <strong>trigger a compensating transaction</strong> to undo the previous steps.</p><p>Kinda like:</p><ul><li>Step 1: Create Order</li><li>Step 2: Make Payment</li><li>Step 3: Prepare for Shipment</li></ul><p>If payment fails, the Payment Service emits a <code>PaymentFailedEvent</code>, and the Order Service listens to it and cancels the order (updates the order status to cancelled).</p><p>💡 Think of it like a chain of promises — each with a backup plan.</p><h2>Types of SAGA: Choreography and Orchestration</h2><h3>1. Choreography (Everyone Just Knows What to Do)</h3><ul><li>No central controller.</li><li>Services publish events and listen to other services' events.</li></ul><h3>E-commerce Example:</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/choreography_saga_cd67bec2a4.png" alt="Choreography based Saga" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_choreography_saga_cd67bec2a4.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_choreography_saga_cd67bec2a4.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_choreography_saga_cd67bec2a4.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_choreography_saga_cd67bec2a4.png 1000w," sizes="100vw"><figcaption>Choreography based Saga</figcaption></figure><ol style="list-style-type:decimal;"><li>The Order Service creates an order and emits an OrderCreatedEvent.</li><li>The Payment Service listens to the OrderCreatedEvent, processes the payment, and emits either:</li><li>PaymentCompletedEvent (if successful), or</li><li>PaymentFailedEvent (if failed).</li><li>If payment is successful, the Shipment Service listens to the PaymentCompletedEvent, arranges the shipment, and emits a ShippingArrangedEvent.</li><li>The Order Service listens to the ShippingArrangedEvent and updates the order status to CONFIRMED or SHIPPED.</li><li>If the <strong>Payment Service</strong> emits a <code>PaymentFailedEvent</code>, the <strong>Order Service</strong> listens to it and updates the order status to <code>CANCELLED</code>.</li></ol><p><strong>Pros:</strong></p><ul><li>No central brain.</li><li>Decentralized and loosely coupled.</li></ul><p><strong>Cons:</strong></p><ul><li>Hard to track the flow.</li><li>Debugging is a pain.</li></ul><h3>2. Orchestration (There’s a Conductor)</h3><ul><li>One central <strong>Saga Orchestrator</strong> tells each service what to do.</li></ul><h3>E-commerce Example:</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/orchestration_saga_94b5eab12b.png" alt="Orchestration based Saga" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_orchestration_saga_94b5eab12b.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_orchestration_saga_94b5eab12b.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_orchestration_saga_94b5eab12b.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_orchestration_saga_94b5eab12b.png 1000w," sizes="100vw"><figcaption>Orchestration based Saga</figcaption></figure><ol style="list-style-type:decimal;"><li>A <strong>user</strong> places an order.</li><li>The <strong>Order Service</strong> creates the order and notifies the <strong>Saga Orchestrator</strong>.</li><li>The <strong>Saga Orchestrator</strong> sends a command to the <strong>Payment Service</strong> to initiate the payment.</li><li>If the <strong>payment is successful</strong>, the <strong>Payment Service</strong> emits a <code>PaymentCompletedEvent</code>.</li><li>The <strong>Saga Orchestrator</strong> listens to this event and sends a command to the <strong>Shipping Service</strong> to initiate shipment.</li><li>Once the <strong>shipment is completed</strong>, the <strong>Shipping Service</strong> emits an <code>OrderShippedEvent</code>.</li><li>The <strong>Order Service</strong> listens to the <code>OrderShippedEvent</code> and updates the order status to <code>SHIPPED</code> or <code>COMPLETED</code>.</li></ol><p><strong>If something fails along the way:</strong></p><ol style="list-style-type:decimal;"><li>For example, if the <strong>payment fails</strong>, the <strong>Payment Service</strong> emits a <code>PaymentFailedEvent</code>.</li><li>The <strong>Saga Orchestrator</strong>, upon receiving this event, sends a command to the <strong>Order Service</strong> to cancel the order — this is called a <strong>compensating transaction</strong>.</li></ol><p><strong>Pros:</strong></p><ul><li>Easier to visualize and monitor.</li><li>Centralized error handling.</li></ul><p><strong>Cons:</strong></p><ul><li>Orchestrator can become a bottleneck.</li><li>Slightly more coupling.</li></ul><h2>Real Talk: Saga Isn’t Always Easy</h2><p>Let’s be real — implementing Sagas can be tricky. You have to:</p><ul><li>Define clear <strong>compensation logic</strong>.</li><li>Handle <strong>partial failures</strong>.</li><li>Make sure your services are <strong>idempotent</strong> (retrying should not mess stuff up).</li><li>Maintain proper <strong>logging and tracing</strong>.</li></ul><p>But it’s <strong>way better</strong> than zombie data or blocking your microservices with 2PC!</p><h2>Key Takeaways</h2><ul><li>Distributed transactions are tricky in microservices.</li><li>2PC and 3PC try to solve this but come with serious trade-offs.</li><li>SAGA is a better alternative — breaking transactions into local steps.</li><li>You can implement SAGA via <strong>Choreography</strong> or <strong>Orchestration</strong>.</li></ul><h2>Bonus Tips:</h2><ul><li>Use <strong>Kafka</strong> or <strong>RabbitMQ</strong> for event-driven choreography.</li><li>For orchestration, frameworks like <strong>Axon</strong>, <strong>Camunda</strong>, or even <strong>Netflix Conductor</strong> help a lot.</li><li>Always make compensation actions <strong>safe and idempotent</strong>.</li></ul><h2>Conclusion</h2><p>So, that’s the lowdown on the Saga Pattern. It's like having a backup plan at every step — and let’s face it, we all need a good backup plan in distributed systems (and life 😅). Next time you build a flow with multiple microservices, ask yourself: <strong>“What happens if this step fails?” </strong>If the answer is <strong>“Uh… I dunno,”</strong> then maybe it’s time to bring in a Saga. Stay curious, and happy coding!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Low Level Design</category>
            <category>SAGA Pattern</category>
            <category>Distributed Transactions</category>
            <category>Microservices Architecture</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/1_d43a29d4f0.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[CQRS Design Pattern in Microservices Architectures]]></title>
            <link>https://www.codingshuttle.com/blogs/cqrs-design-pattern-in-microservices-architectures</link>
            <guid>https://www.codingshuttle.com/blogs/cqrs-design-pattern-in-microservices-architectures</guid>
            <pubDate>Mon, 12 May 2025 08:23:43 GMT</pubDate>
            <description><![CDATA[Learn CQRS (Command Query Responsibility Segregation) design pattern with a real-world e-commerce microservices example. Understand how separating read and write operations improves performance, scalability, and system architecture. Ideal for developers building scalable applications.]]></description>
            <content:encoded><![CDATA[<p>Hello devs, today in this blog we are going to learn about the <strong>Command Query Responsibility Segregation (CQRS)</strong> design pattern which is widely used in <strong>microservices architectures</strong>. We'll take an example of an <strong>e-commerce application</strong> to understand CQRS, which will help you relate to a real-life use case. By the end of this blog, you’ll be clear about <strong>where and why to use the CQRS pattern in your microservice architecture</strong>.</p><h2>What is CQRS Design Pattern and Why Is It Needed?</h2><p><strong>CQRS</strong> stands for <strong>Command Query Responsibility Segregation</strong>. It is a software design pattern that <strong>separates</strong> read operations (queries) and write operations (commands) into <strong>different models</strong>.</p><blockquote><p>In simple terms:</p><ul><li><strong>Commands</strong>: Operations that modify data (like create, update, delete).</li><li><strong>Queries</strong>: Operations that read/fetch data (like get orders, list products).</li></ul></blockquote><h2>🤔 Why Separate Read and Write Operations?</h2><p>Let’s take an <strong>e-commerce example</strong> to understand this.</p><p>Imagine you have the following microservices:</p><ol><li><strong>User Service</strong></li><li><strong>Order Service</strong></li><li><strong>Inventory Service</strong></li><li><strong>Product Service</strong></li><li><strong>Shipment Service</strong></li></ol><p>Each service has its own <strong>separate database</strong> (as per microservices best practices — database per service). Now consider a user <strong>John</strong> who has placed 5 orders over the last 3 months. Today, John logs in and clicks on <strong>“View Order History.”</strong></p><p>Now, the request goes to your <strong>Order Service</strong>, which:</p><ul><li>Fetches the list of John’s orders</li><li>Enriches the response with <strong>product names</strong> from Product Service</li><li>Gets shipment status from Shipment Service</li></ul><p>This kind of read operation <strong>touches multiple services</strong> and is often <strong>complex and performance-sensitive</strong>.</p><h3>Problem in Traditional CRUD:</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/traditional_Crud_a4602079ba.png" alt="Traditional CRUD Operations" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_traditional_Crud_a4602079ba.png 152w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_traditional_Crud_a4602079ba.png 487w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_traditional_Crud_a4602079ba.png 731w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_traditional_Crud_a4602079ba.png 974w," sizes="100vw"><figcaption>Traditional CRUD Operations</figcaption></figure><p>If you have the same model for reads and writes:</p><ul><li>Read operations can become <strong>slow</strong> as they try to fetch and join data from multiple microservices/databases.</li><li>Complex read models increase <strong>load</strong> on the write database.</li><li>You might accidentally expose internal fields in read models.</li></ul><h3>Solution: Use CQRS</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/CQRS_pattern_2b44ebe134.png" alt="CQRS Design Pattern" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_CQRS_pattern_2b44ebe134.png 117w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_CQRS_pattern_2b44ebe134.png 376w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_CQRS_pattern_2b44ebe134.png 563w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_CQRS_pattern_2b44ebe134.png 751w," sizes="100vw"><figcaption>CQRS Design Pattern</figcaption></figure><p>CQRS solves this by <strong>decoupling</strong> read and write responsibilities. Here’s how:</p><ul><li>Write models (commands) only care about validating and updating data.</li><li>Read models (queries) are <strong>optimized</strong> for fetching data and are often <strong>denormalized</strong> or use <strong>projections</strong>.</li></ul><h2>How CQRS Works in E-commerce Example</h2><p>Let’s see how John’s order request is handled in a <strong>CQRS-based architecture</strong>:</p><h3>1. 🛒 When John places an order (Command):</h3><ul><li>Request hits the <strong>Order Command API</strong>.</li><li>It goes to the <strong>Command Handler</strong>, which:<ul><li>Validates input</li><li>Updates the <strong>write model database</strong></li></ul></li><li>A <strong>domain event</strong> like <code>OrderPlacedEvent</code> is published.</li></ul><h3>2. 📱 Event Handler listens to the event:</h3><ul><li>Updates a <strong>read database</strong> (can be SQL, NoSQL, or ElasticSearch).</li><li>This read DB is optimized for queries (e.g., has joined data of orders + products + shipment).</li></ul><h3>3. 👀 When John views order history (Query):</h3><ul><li>Request hits the <strong>Order Query API</strong>.</li><li>It fetches directly from the <strong>read database</strong>, no need to talk to multiple services.</li></ul><h2>Advantages of CQRS</h2><ul><li>✅ Improved performance for complex queries</li><li>✅ Better scalability (separate read &amp; write scaling)</li><li>✅ Easier to evolve read models without affecting commands</li><li>✅ Enables <strong>Event Sourcing</strong> if needed</li><li>✅ Ideal for <strong>high read-load systems</strong> like dashboards, analytics, order history</li></ul><h2>⚠️ When Not to Use CQRS</h2><blockquote><p>CQRS adds complexity (event handling, sync issues, eventual consistency). Don’t use it if:</p></blockquote><ul><li>Your system is <strong>simple</strong> CRUD with low scale.</li><li>You don’t need to scale read/write separately.</li><li>You don’t have experience managing async communication or eventual consistency.</li></ul><h2>Conclusion</h2><p>The CQRS design pattern brings significant advantages when building scalable and responsive microservices architectures. By separating the read and write concerns, you not only simplify the data models but also optimize each operation independently. In our e-commerce example, implementing CQRS helps to deliver faster read performance for customers while ensuring that write operations remain consistent and isolated. While it may add some complexity, CQRS becomes a powerful tool in scenarios with high read-to-write ratios, complex queries, or where performance, scalability, and maintainability are key priorities.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Low Level Design</category>
            <category>Microservices</category>
            <category>Microservices Design Patterns</category>
            <category>CQRS Design Pattern</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/2_170636eb54.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[SOLID Principles in Programming: Understanding with Real Life Examples.]]></title>
            <link>https://www.codingshuttle.com/blogs/solid-principles-in-programming-understanding-with-real-life-examples</link>
            <guid>https://www.codingshuttle.com/blogs/solid-principles-in-programming-understanding-with-real-life-examples</guid>
            <pubDate>Mon, 12 May 2025 08:16:57 GMT</pubDate>
            <description><![CDATA[Learn SOLID principles in Programming with real-life examples. Build clean, maintainable, scalable code for robust applications.]]></description>
            <content:encoded><![CDATA[<p>If you're a software developer, you've probably heard of the SOLID principles. They are the backbone of writing clean, maintainable, and scalable code. In this blog, we’ll dive deep into these principles using practical examples from everyday applications like food ordering and ride-booking. Whether you're building a ride-sharing app or a food delivery service, these principles will help you level up your coding game.</p><h2>What are SOLID Principles?</h2><p>SOLID is an acronym for five design principles that help developers write clean, readable, and maintainable code. Let’s break them down and explore each one with relatable, real-world examples. For each principle, we’ll cover its definition, a real-world example of a wrong approach, the issues that arise from not following the principle, and a correct approach with a complete example demonstrating how to use it and resolve the issues.</p><p>The five principles are:</p><ol><li><strong>Single Responsibility Principle (SRP)</strong></li><li><strong>Open/Closed Principle (OCP)</strong></li><li><strong>Liskov’s Substitution Principle (LSP)</strong></li><li><strong>Interface Segregation Principle (ISP)</strong></li><li><strong>Dependency Inversion Principle (DIP)</strong></li></ol><h2>1. Single Responsibility Principle (SRP)</h2><h3>Definition</h3><p>The Single Responsibility Principle states that a class should have only one reason to change, meaning it should have only one responsibility or job. This keeps classes focused and easier to maintain.</p><h3>Real-World Example: Wrong Approach</h3><p>Imagine you’re building a food delivery app like Uber Eats. You create a <code>FoodOrder</code> class that handles everything: calculating the order total, sending notifications to the customer, and saving the order to the database.</p><pre><code class="language-java">class FoodOrder {
    private String orderId;
    private double amount;
    private String customerEmail;

    // Calculate total
    public double calculateTotal() {
        // Logic to calculate total
        return amount;
    }

    // Send email notification
    public void sendNotification() {
        System.out.println("Sending email to " + customerEmail);
    }

    // Save to database
    public void saveToDatabase() {
        System.out.println("Saving order " + orderId + " to database");
    }
}

</code></pre><h3>Issue if We Don’t Follow SRP</h3><p>This <code>FoodOrder</code> class has multiple responsibilities: order calculation, notification, and database operations. If the email notification logic changes (e.g., switching to SMS), or the database schema changes, you’ll need to modify the <code>FoodOrder</code> class. This increases the risk of introducing bugs and makes the class harder to test and maintain.</p><h3>Correct Approach</h3><p>To follow SRP, split the responsibilities into separate classes: one for order calculation, one for notifications, and one for database operations.</p><pre><code class="language-java">// Class responsible for order details and calculation
class FoodOrder {
    private String orderId;
    private double amount;

    public double calculateTotal() {
        // Logic to calculate total
        return amount;
    }

    // Getters and setters
    public String getOrderId() { return orderId; }
    public void setOrderId(String orderId) { this.orderId = orderId; }
    public double getAmount() { return amount; }
    public void setAmount(double amount) { this.amount = amount; }
}

// Class responsible for sending notifications
class NotificationService {
    public void sendNotification(String customerEmail, String message) {
        System.out.println("Sending email to " + customerEmail + ": " + message);
    }
}

// Class responsible for database operations
class OrderRepository {
    public void saveToDatabase(String orderId) {
        System.out.println("Saving order " + orderId + " to database");
    }
}

// Usage
public class FoodDeliveryApp {
    public static void main(String[] args) {
        // Create an order
        FoodOrder order = new FoodOrder();
        order.setOrderId("12345");
        order.setAmount(50.0);

        // Calculate total
        double total = order.calculateTotal();
        System.out.println("Order total: $" + total);

        // Send notification
        NotificationService notificationService = new NotificationService();
        notificationService.sendNotification("customer@example.com", "Your order is confirmed!");

        // Save to database
        OrderRepository repository = new OrderRepository();
        repository.saveToDatabase(order.getOrderId());
    }
}
</code></pre><h3>How We Solved the Issue</h3><p>By splitting the responsibilities, each class now has a single reason to change:</p><ul><li><code>FoodOrder</code> only changes if the order calculation logic changes.</li><li><code>NotificationService</code> only changes if the notification mechanism changes (e.g., adding SMS support).</li><li><code>OrderRepository</code> only changes if the database operations change.This makes the code easier to maintain, test, and extend, reducing the risk of bugs.</li></ul><h2>2. Open/Closed Principle (OCP)</h2><h3>Definition</h3><p>The Open/Closed Principle states that software entities (classes, modules, etc.) should be open for extension but closed for modification. You should be able to add new functionality without changing existing code.</p><h3>Real-World Example: Wrong Approach</h3><p>Suppose you’re building a ride-booking app like Lyft. You have a <code>Ride</code> class that calculates the fare based on the ride type (e.g., economy or premium).</p><pre><code class="language-java">class Ride {
    private String rideType;

    public double calculateFare() {
        if (rideType.equals("economy")) {
            return 10.0;
        } else if (rideType.equals("premium")) {
            return 20.0;
        }
        return 0.0;
    }
}
</code></pre><h3>Issue if We Don’t Follow OCP</h3><p>If you want to add a new ride type (e.g., “shared”), you need to modify the <code>calculateFare</code> method, adding another <code>if</code> condition. This violates OCP because the <code>Ride</code> class is not closed for modification. Every new ride type requires changing the existing code, increasing the risk of errors.</p><h3>Correct Approach</h3><p>Use polymorphism to make the system extensible. Define an interface for fare calculation and create separate classes for each ride type.</p><pre><code class="language-java">// Interface for fare calculation
interface RideType {
    double calculateFare();
}

// Economy ride type
class EconomyRide implements RideType {
    public double calculateFare() {
        return 10.0;
    }
}

// Premium ride type
class PremiumRide implements RideType {
    public double calculateFare() {
        return 20.0;
    }
}

// Shared ride type (new addition)
class SharedRide implements RideType {
    public double calculateFare() {
        return 5.0;
    }
}

// Ride class
class Ride {
    private RideType rideType;

    public Ride(RideType rideType) {
        this.rideType = rideType;
    }

    public double calculateFare() {
        return rideType.calculateFare();
    }
}

// Usage
public class RideBookingApp {
    public static void main(String[] args) {
        // Economy ride
        Ride economyRide = new Ride(new EconomyRide());
        System.out.println("Economy ride fare: $" + economyRide.calculateFare());

        // Premium ride
        Ride premiumRide = new Ride(new PremiumRide());
        System.out.println("Premium ride fare: $" + premiumRide.calculateFare());

        // Shared ride (new type added without modifying Ride class)
        Ride sharedRide = new Ride(new SharedRide());
        System.out.println("Shared ride fare: $" + sharedRide.calculateFare());
    }
}
</code></pre><h3>How We Solved the Issue</h3><p>By using an interface (<code>RideType</code>), we made the <code>Ride</code> class open for extension (new ride types can be added by creating new classes) and closed for modification (no need to change the <code>Ride</code> class when adding a new ride type). This makes the system more flexible and less prone to errors.</p><h2>3. Liskov Substitution Principle (LSP)</h2><h3>Definition</h3><p>The Liskov Substitution Principle states that objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program. Subclasses must behave in a way that doesn’t break the expectations set by the superclass.</p><h3>Real-World Example: Wrong Approach</h3><p>In an e-commerce platform, you have a <code>Payment</code> class for processing payments. You create a subclass <code>CashPayment</code> that doesn’t require a transaction ID, unlike other payment methods.</p><pre><code class="language-java">class Payment {
    public void processPayment() {
        System.out.println("Processing payment with transaction ID");
    }
}

class CashPayment extends Payment {
    public void processPayment() {
        System.out.println("Processing cash payment (no transaction ID)");
    }
}

class PaymentProcessor {
    public void process(Payment payment) {
        payment.processPayment();
    }
}
</code></pre><h3>Issue if We Don’t Follow LSP</h3><p>The <code>CashPayment</code> class overrides <code>processPayment</code> in a way that changes the expected behavior (no transaction ID). If the <code>PaymentProcessor</code> expects a transaction ID for all payments, using <code>CashPayment</code> could break the system, violating LSP.</p><h3>Correct Approach</h3><p>Redesign the class hierarchy to ensure subclasses adhere to the superclass’s contract. Use an interface to define the payment behavior.</p><pre><code class="language-java">// Interface for payment processing
interface Payment {
    void processPayment();
}

// Credit card payment
class CreditCardPayment implements Payment {
    private String transactionId;

    public CreditCardPayment(String transactionId) {
        this.transactionId = transactionId;
    }

    public void processPayment() {
        System.out.println("Processing credit card payment with transaction ID: " + transactionId);
    }
}

// Cash payment
class CashPayment implements Payment {
    public void processPayment() {
        System.out.println("Processing cash payment");
    }
}

// Payment processor
class PaymentProcessor {
    public void process(Payment payment) {
        payment.processPayment();
    }
}

// Usage
public class ECommerceApp {
    public static void main(String[] args) {
        PaymentProcessor processor = new PaymentProcessor();

        // Credit card payment
        Payment creditCard = new CreditCardPayment("TXN123");
        processor.process(creditCard);

        // Cash payment
        Payment cash = new CashPayment();
        processor.process(cash);
    }
}
</code></pre><h3>How We Solved the Issue</h3><p>By using an interface (<code>Payment</code>), we ensure that all payment types implement <code>processPayment</code> in a way that’s compatible with the <code>PaymentProcessor</code>. The <code>CashPayment</code> class no longer breaks the expectation of the system, as it provides its own valid implementation. This adheres to LSP and makes the system more robust.</p><h2>4. Interface Segregation Principle (ISP)</h2><h3>Definition</h3><p>The Interface Segregation Principle states that clients should not be forced to depend on interfaces they do not use. Interfaces should be specific to the needs of the client.</p><h3>Real-World Example: Wrong Approach</h3><p>In a food delivery app, you have an <code>OrderService</code> interface that includes methods for placing orders, tracking orders, and canceling orders. Both customers and restaurants implement this interface.</p><pre><code class="language-java">interface OrderService {
    void placeOrder();
    void trackOrder();
    void cancelOrder();
}

class Customer implements OrderService {
    public void placeOrder() {
        System.out.println("Customer placing order");
    }

    public void trackOrder() {
        System.out.println("Customer tracking order");
    }

    public void cancelOrder() {
        System.out.println("Customer canceling order");
    }
}

class Restaurant implements OrderService {
    public void placeOrder() {
        throw new UnsupportedOperationException("Restaurant cannot place order");
    }

    public void trackOrder() {
        System.out.println("Restaurant tracking order");
    }

    public void cancelOrder() {
        System.out.println("Restaurant canceling order");
    }
}
</code></pre><h3>Issue if We Don’t Follow ISP</h3><p>The <code>Restaurant</code> class is forced to implement <code>placeOrder</code>, which it doesn’t need, leading to an <code>UnsupportedOperationException</code>. This violates ISP because the interface is too broad, forcing clients to implement irrelevant methods.</p><h3>Correct Approach</h3><p>Split the interface into smaller, specific interfaces that clients can implement as needed.</p><pre><code class="language-java">// Interface for placing orders
interface OrderPlacement {
    void placeOrder();
}

// Interface for tracking orders
interface OrderTracking {
    void trackOrder();
}

// Interface for canceling orders
interface OrderCancellation {
    void cancelOrder();
}

// Customer implements all interfaces
class Customer implements OrderPlacement, OrderTracking, OrderCancellation {
    public void placeOrder() {
        System.out.println("Customer placing order");
    }

    public void trackOrder() {
        System.out.println("Customer tracking order");
    }

    public void cancelOrder() {
        System.out.println("Customer canceling order");
    }
}

// Restaurant implements only relevant interfaces
class Restaurant implements OrderTracking, OrderCancellation {
    public void trackOrder() {
        System.out.println("Restaurant tracking order");
    }

    public void cancelOrder() {
        System.out.println("Restaurant canceling order");
    }
}

// Usage
public class FoodDeliveryApp {
    public static void main(String[] args) {
        // Customer actions
        Customer customer = new Customer();
        customer.placeOrder();
        customer.trackOrder();
        customer.cancelOrder();

        // Restaurant actions
        Restaurant restaurant = new Restaurant();
        restaurant.trackOrder();
        restaurant.cancelOrder();
    }
}
</code></pre><h3>How We Solved the Issue</h3><p>By splitting the <code>OrderService</code> interface into smaller interfaces (<code>OrderPlacement</code>, <code>OrderTracking</code>, <code>OrderCancellation</code>), we ensure that clients like <code>Restaurant</code> only implement the methods they need. This adheres to ISP, making the code cleaner and more maintainable.</p><h2>5. Dependency Inversion Principle (DIP)</h2><h3>Definition</h3><p>The Dependency Inversion Principle states that high-level modules should not depend on low-level modules; both should depend on abstractions. Additionally, abstractions should not depend on details; details should depend on abstractions.</p><h3>Real-World Example: Wrong Approach</h3><p>In a ride-booking app, you have a <code>RideService</code> class that directly depends on a <code>PaymentProcessor</code> class for processing payments.</p><pre><code class="language-java">class PaymentProcessor {
    public void processPayment() {
        System.out.println("Processing payment with credit card");
    }
}

class RideService {
    private PaymentProcessor paymentProcessor;

    public RideService() {
        this.paymentProcessor = new PaymentProcessor();
    }

    public void bookRide() {
        paymentProcessor.processPayment();
        System.out.println("Ride booked");
    }
}
</code></pre><h3>Issue if We Don’t Follow DIP</h3><p>The <code>RideService</code> class is tightly coupled to the <code>PaymentProcessor</code> class. If you want to support a different payment method (e.g., PayPal), you’ll need to modify the <code>RideService</code> class, violating DIP and making the system less flexible.</p><h3>Correct Approach</h3><p>Introduce an abstraction (interface) for payment processing and inject the dependency into the <code>RideService</code> class.</p><pre><code class="language-java">// Interface for payment processing
interface PaymentProcessor {
    void processPayment();
}

// Credit card payment processor
class CreditCardProcessor implements PaymentProcessor {
    public void processPayment() {
        System.out.println("Processing payment with credit card");
    }
}

// PayPal payment processor
class PayPalProcessor implements PaymentProcessor {
    public void processPayment() {
        System.out.println("Processing payment with PayPal");
    }
}

// Ride service
class RideService {
    private PaymentProcessor paymentProcessor;

    public RideService(PaymentProcessor paymentProcessor) {
        this.paymentProcessor = paymentProcessor;
    }

    public void bookRide() {
        paymentProcessor.processPayment();
        System.out.println("Ride booked");
    }
}

// Usage
public class RideBookingApp {
    public static void main(String[] args) {
        // Book ride with credit card
        PaymentProcessor creditCardProcessor = new CreditCardProcessor();
        RideService rideService1 = new RideService(creditCardProcessor);
        rideService1.bookRide();

        // Book ride with PayPal
        PaymentProcessor payPalProcessor = new PayPalProcessor();
        RideService rideService2 = new RideService(payPalProcessor);
        rideService2.bookRide();
    }
}
</code></pre><h3>How We Solved the Issue</h3><p>By introducing the <code>PaymentProcessor</code> interface and injecting the dependency into <code>RideService</code>, we decoupled the high-level module (<code>RideService</code>) from the low-level module (<code>CreditCardProcessor</code> or <code>PayPalProcessor</code>). This adheres to DIP, making the system more flexible and easier to extend with new payment methods.</p><h2>Conclusion</h2><p>The SOLID principles are more than just guidelines—they’re a mindset for writing clean, maintainable, and scalable code. By applying these principles in real-world applications like food delivery, ride-booking, and e-commerce platforms, you can create systems that are easier to understand, test, and extend. Each principle addresses a specific aspect of software design, and together, they form a powerful approach for building robust applications.</p><p>Start incorporating SOLID principles into your projects today, and you’ll notice a significant improvement in your code quality. Happy coding!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Low Level Design</category>
            <category>Solid Principles</category>
            <category>Java</category>
            <category>Object Oriented Programming</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/3_4dec010859.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 50 Java Interview Questions and Answers That You Must Know]]></title>
            <link>https://www.codingshuttle.com/blogs/top-50-java-questions-for-interview-2025</link>
            <guid>https://www.codingshuttle.com/blogs/top-50-java-questions-for-interview-2025</guid>
            <pubDate>Fri, 14 Feb 2025 21:07:34 GMT</pubDate>
            <description><![CDATA[Looking for a resource to cover the top Java Interview questions before your next interview? You are at the right place.  This article covers key topics such as Core Java, OOPs concepts, Java 8+ features, and the Collection Framework, helping readers prepare effectively for Java-related job interviews.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p><strong>Programming languages</strong>(JAVA, C, C++, Python) help us to communicate with computers. A <strong>paradigm (basically in programming)</strong> is a pattern that guides how programming languages are structured to solve different problems. <strong>OOP (Object Oriented Programming)</strong> is a programming paradigm, based on the usage of objects.</p><h2>List of Top 50 Mostly Asked Java Questions for Interview with Proper Answers (2025)</h2><p>All questions are suitable for freshers and experienced everyone, and all answers are suitable for interview purposes for 2025.</p><h2>Top 20 mostly asked Java Interview Questions on Core Java</h2><h3>1. What is Java?</h3><p>Java is a <strong>high-level</strong> and <strong>platform-independent</strong> programming language, designed by <strong>James Gosling</strong> at <strong>Sun Microsystems</strong>. Java follows the Object-Oriented Programming Paradigm. Java allows Primitive Datatypes. For writing, compiling, and debugging Java programs, we need <strong>JDK (including JRE, JVM, and Development tools)</strong>.</p><h3>2. Features of Java?</h3><p>Java has so many strong and good features, making it more versatile and powerful for solving any problems and building diverse applications. All features are understandable for all types of students.</p><p>Let’s talk about the Features of Java :</p><ol><li><strong>Platform Independent:</strong> No need to depend on any platform for code execution. Java follows the ‘<strong>Write once, Run anywhere</strong>’ rules. Java-written codes (.java files) are converted into Java bytecodes (.class flies) by the Java compiler (javac). These bytecodes are interpreted and ready to execute on any platform by the JVM.</li><li><strong>Object Oriented:</strong> A design around objects (representation of real-world entities). ****By following the OOP paradigm Java enables reusable, modular, flexible, and secure code.</li><li><strong>Simple and Familiar:</strong> Syntax of Java is as easy, clean, and understandable as C, and C++ languages. If you are familiar with these languages (C, and C++) then it will be easy to learn Java also. These make Java simple and familiar.</li><li><strong>Secure:</strong> Java does not allow the <strong>Pointer</strong> concept (inside pointer we directly access the memory). Java uses <strong>references</strong> that have been designed to prevent memory stolen. For these Java is a more secured language.</li><li><strong>Robust:</strong> Java offers <strong>automatic memory management</strong>, and <strong>automatic garbage collection</strong> to prevent unnecessary memory leaks. To prevent errors, Java uses <strong>comprehensive exception handling</strong> mechanism. These make Java robust.</li><li><strong>Multithreaded:</strong> Java ****supports multithreading to execute multiple threads concurrently. This optimizes CPU usage.</li><li><strong>High-Performance: Just In Time (JIT)</strong> compiler translates Java bytecodes to native machine code (Machine understandable code) at the time of run-time. This process is a faster way for application execution. These make Java a high-performance language.</li><li><strong>Distributed:</strong> Java is distributed because it allows applications to run on multiple computers or servers of a network with some features like <strong>Remote Method Invocation</strong>, <strong>Enterprise JavaBeans,</strong> etc.</li><li><strong>Network-centric:</strong> For real-time communication with private networks, Java provides built-in networking support to create networking-based applications. That makes Java as a network-centric.</li><li><strong>Versatile:</strong> Java is versatile for the usage of so many different fields ( Android application development, Web application development, IoT devices, gaming, etc.).</li><li><strong>Dynamic:</strong> Java supports dynamic memory allocation and allows the loading of all classes at the run-time, which makes Java dynamic.</li><li><strong>Extensible:</strong> Java supports external models and libraries which makes Java extensible.</li></ol><h3>3. What is JVM?</h3><p><strong>Java Virtual Machine (JVM</strong>) is a process virtual machine. It provides a runtime environment (<strong>Java Runtime Environment</strong>) to execute the byte code of a single application independently.</p><p>JVM is a runtime engine. Java’s <strong>Write Once Run Anywhere (WORA)</strong> behavior is enabled by using <strong>JRE, Java Runtime Environment</strong> is a core component of JVM for executing the java byte code.</p><p>At the time of compilation, the source code (.java files) converts to the Java byte code (.class files) with the use of the javac compiler. This byte code is processed to execute with the help of multiple stages of execution of JVM.</p><p>JVM is responsible for making Java Platform-Independent, Secure, High-performance, and Robust.</p><h3>4. Difference between JVM, JRE, and JDK?</h3><p><strong>Java Virtual Machine (JVM</strong>) is a process virtual machine. It provides a runtime environment (<strong>Java Runtime Environment</strong>) to execute the byte code of a single application independently.</p><p><strong>Java Runtime Environment(JRE)</strong> is a core component of JVM for executing the java byte code.</p><p><strong>Java Development Kits (JDK)</strong> is used to develop, compile, and run Java applications. JDK is a combined version of JRE + Developments Tools and JRE is a Combined version of JVM + Libraries + Others tools.</p><h3>5. Why java is Platform Independent language?</h3><p>At the time of compilation, the source code (.java files) converts to the Java byte code with the use of the javac compiler. Java’s <strong>Write Once Run Anywhere (WORA)</strong> behavior is enabled by using <strong>JRE, Java Runtime Environment</strong> is a core component of JVM for executing the java byte code. JVM is responsible for making Java Platform-Independent.</p><h3>6. Why java is Object Oriented Language?</h3><p>Java is an <strong>Object-Oriented Programming (OOP)</strong> language because it is based on <strong>objects and classes</strong> and follows <strong>four OOP principles</strong>:</p><ol><li><strong>Encapsulation</strong> – Data hiding using private fields and access through methods.</li><li><strong>Abstraction</strong> – Hides implementation details using abstract classes &amp; interfaces.</li><li><strong>Inheritance</strong> – Reusability of code using <code>extends</code> (class) &amp; <code>implements</code> (interface).</li><li><strong>Polymorphism</strong> – Same method behaves differently in different classes (overloading &amp; overriding).</li></ol><h3>7. Why java is not fully Object-oriented?</h3><p><strong>Java is not 100% Object-Oriented</strong> because:</p><ul><li>It supports <strong>primitive data types</strong> (<code>int</code>, <code>char</code>, <code>float</code>, etc.), which are not objects.</li><li>It allows <strong>static methods</strong> and <strong>variables</strong>, which belong to a class rather than an object.</li></ul><h3>8. What is Constructor? Why do we need Constructors?</h3><p>Constructors look like methods or functions. Constructors have no return type. Constructors are automatically called when an object is instantiated.</p><p><strong>Why do we need Constructors?</strong></p><ul><li><strong>Initialization:</strong> Constructors allow setting initial values for object attributes during object creation.</li><li><strong>Object Creation Process:</strong> They ensure that objects are properly set up before they are used, preventing errors due to uninitialized data.</li><li><strong>Custom Initialization:</strong> You can define multiple constructors with different parameters to provide flexibility in object creation.</li></ul><h3>9. What is the difference between <code>==</code> and <code>equals()</code> in Java?</h3><p><code>==</code> : is used to compare object references or primitive values.</p><pre><code class="language-java">public class EqualsOperator {
    public static void main(String[] args) {

        int l1 = 5;
        int l2 = 5;
        boolean b2 = (l1==l2);  //true

         }
}</code></pre><p><code>equals()</code> : Compares the specified object with this list for equality.</p><pre><code class="language-java">public class EqualMethod {
    public static void main(String[] args) {

        List&lt;Integer&gt; l1 = new ArrayList&lt;&gt;(5);
        List&lt;Integer&gt; l2 = new ArrayList&lt;&gt;(5);

        boolean b1 = l1.equals(l2);   //true
        
        }
}
</code></pre><h3>10. Explain the difference between <code>String</code>, <code>StringBuilder</code>, and <code>StringBuffer</code></h3><p><strong>String</strong> is immutable and not thread-safe, ideal for fixed text.</p><p><strong>StringBuilder</strong> is mutable, non-thread-safe, and offers better performance in single-threaded scenarios.</p><p><strong>StringBuffer</strong> is also mutable but thread-safe, making it suitable for multi-threaded environments, though it’s slower than StringBuilder due to synchronization overhead.</p><h3>11. What is the purpose of <code>static</code> keyword?</h3><p>The <code>static</code> keyword in Java is used to define class-level variables, methods, and blocks that belong to the class rather than individual instances. Static variables are shared among all instances of a class, while static methods can be called directly on the class and can only access static members. Static blocks are used for initializing static variables, and static nested classes can exist independently of the outer class's instances.</p><h3>12. What is the <code>String</code> pool in Java?</h3><p>The <strong>String Pool</strong> in Java is a memory area in the Heap that stores <strong>string literals</strong> to optimize memory usage by reusing identical string values. When a string literal is created, Java checks the pool to see if it already exists and reuses it; otherwise, it adds the new string to the pool. Strings created using <code>new</code> are stored outside the pool.</p><h3>13. What is garbage collection in Java?</h3><p><strong>Garbage Collection (GC)</strong> automatically removes <strong>unused objects</strong> from memory, preventing memory leaks and optimizing performance. It uses a <strong>mark-and-sweep</strong> algorithm and calls <code>finalize()</code> before object removal. GC ensures <strong>efficient memory management</strong>, reducing manual effort and improving application stability. Calling the <strong>gc</strong> method suggests that the Java Virtual Machine expends effort toward recycling unused objects to make the memory they currently occupy available for reuse by the Java Virtual Machine. The call <code>System.*gc*()</code> is effectively equivalent to the call: <code>Runtime.*getRuntime*().gc()</code>.</p><h3>14. What is the role of the <code>this</code> keyword in Java?</h3><p><code><strong>this</strong></code> is a way to refer to and interact with the current object, improving code clarity and flexibility.</p><p><code><strong>this</strong></code> refers to the <strong>current instance</strong> of the class. It helps differentiate <strong>instance variables</strong> from <strong>local variables</strong>, invoke <strong>methods</strong> and <strong>constructors</strong> of the current object, and return the <strong>current object</strong> itself from a method. We mostly use to <strong>remove</strong> any <strong>Ambiguity</strong> in variable.</p><pre><code class="language-java">class Car {
    String model;
    
    //constructors
    Car(String model) {
        this.model = model;  // 'this.model' refers to the instance variable
    }
    
    //methods
    Car getCar() {
        return this;  // Returns the current object
    }
    
     void start() {
        System.out.println("Car started");
    }

    void drive() {
        this.start();  // Calls the current class method
    }
    
    
    
}
</code></pre><h3>15. What is the difference between a constructor and a method?</h3><p>Both are defined as functions, but they are declared differently.</p><p><strong>Constructor:</strong></p><ul><li>The constructor name is the same as the classes. Constructors have no return type, not even <code>void</code>.</li><li>Constructors are used to initialize objects when they are created.</li><li>Constructors are automatically called when an object is instantiated.</li></ul><pre><code class="language-java">public class Animal{

   int a;

   //default constructor
   Animal(){
      System.out.println("This is a Constructor");
   }
   
   //parameterized constructor
   Animal(int a){
      a=this.a;
   }
   public static void main(String[] args) {
       Animal obj1 = new Animal();
       Animal obj2 = new Animal(8);
      }
}</code></pre><p><strong>Method:</strong></p><ul><li>The method can have any name, following the class naming conventions.</li><li>Methods can return values (any type, including <code>void</code>).</li><li>Methods are used to perform specific actions or behaviors.</li><li>Methods must be explicitly called by an object or class.</li></ul><pre><code class="language-java">class Car {
    String model;

    // Method
    void startEngine() {
        System.out.println("Engine started!");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car1 = new Car();
        car1.startEngine();  // Method is called here
    }
}
</code></pre><h3>16. How does Optional work in Java 8?</h3><p><code>Optional&lt;T&gt;</code> is one of the many containers newly introduced by JAVA 8 in its <code>java.util</code> package. This class is all about the situations where a value may be present or absent; hence, there will be no more <code>null</code>. This would make for minimal use, or no use at all, of <code>NullPointerException</code>.</p><h3>17. What is dependency injection in Java?</h3><p><strong>Dependency Injection (DI)</strong> can be defined as a design pattern in Java in which the concerned object receives its other associated dependencies from outside its domain instead of creating them internally. This loose coupling makes the code very maintainable, testable, and scalable.</p><p><strong>Types of Dependency Injection</strong></p><p><strong>Constructor Injection</strong> (Injection through Constructor) – Dependencies are injected through the constructor.</p><pre><code class="language-java">public class Service {
    private Repository repository;
    public Service(Repository repository) {
        this.repository = repository;
    }
}</code></pre><p><strong>Setter Injection</strong> – It is the injection of dependencies through setter methods.</p><pre><code class="language-java">public class Service {
    private Repository repository;
    public void setRepository(Repository repository) {
        this.repository = repository;
    }
}</code></pre><p><strong>Field Injection</strong> – Injecting dependencies directly into fields by using annotation (Spring Framework).</p><pre><code class="language-java">@Autowired
private Repository repository;</code></pre><h3>18. What are the advantages of using Java Generics?</h3><p>Generics are <strong>Parameterized Typed</strong>. By using generics, it is possible to create classes, interfaces, and methods that work for different data types. You can use Generics methods, interfaces, and fields for multiple different data types.</p><ul><li><strong>Type Safety</strong> – Prevents <code>ClassCastException</code> by enforcing type checks at compile-time.</li><li><strong>Code Reusability</strong> – Generic classes and methods can work with multiple data types.</li><li><strong>Elimination of Type Casting</strong> – Reduces the need for explicit casting, making code cleaner.</li><li><strong>Improved Readability &amp; Maintainability</strong> – Enhances code clarity and reduces errors.</li><li><strong>Better Performance</strong> – Compile-time checks improve efficiency by avoiding runtime overhead.</li></ul><h3>19. Java 17 features</h3><p><strong>Oracle</strong> introduced <strong>Java 17,</strong> the LTS Java version, in September 2021 to improve and upgrade the application’s <strong>stability, performance, and garbage collection to enhance security and API.</strong> Java 17 resolves these issues with <strong>Sealed Classes, Pattern Matching, Records, ZGC, and better API security</strong>.</p><h3>20. What is the <code>Collectors</code> class in Java 8?</h3><p>The <code>Collectors</code>class in Java 8 is part of the package <code><strong>java.util.stream</strong></code>, and it gives static factory methods to collect stream elements into various data structures such as lists, sets, and maps and to perform accumulation operations on them.</p><h2>Top 20 mostly asked Java Interview Questions on OOPs And Collection Framework</h2><h3>1. OOPs Concept: 4pillars of OOPs</h3><p><strong>OOP (Object Oriented Programming)</strong> is a programming paradigm, based on the usage of objects. Java, C++, etc. are an <strong>Object-Oriented Programming (OOP)</strong> language because it is based on <strong>objects and classes</strong> and follows <strong>four OOP principles</strong>:</p><ul><li><strong>Encapsulation:</strong> Restricting direct access to data and allowing controlled access via methods. To achieve encapsulation, we use different access modifiers (to get access publicly and privately…), these make code more secure and reusable. Using getter setter to get the access of private properties.<ul><li><strong>Examples:</strong> <strong>Daily wearing Bags:</strong> The books inside a bag are <strong>private</strong> (protected from direct access). You can only <strong>access them</strong> using a zipper (getter method) or <strong>place books inside</strong> using an opening (setter method).</li></ul></li></ul><pre><code class="language-java">class Bags {
    private String book;   // Private property (data hiding)
    
    public String getBook() { return book; }    //you can get a private variable
    
    public void setBook(String bookName) { this.book = bookName; }   //you can set the value of a private variable
}
</code></pre><ul><li><strong>Abstraction:</strong> Hiding implementation details and showing only essential features. It improves <strong>code simplicity and usability</strong>.<ul><li><strong>Examples: A TV :</strong> You <strong>use a remote</strong> to <strong>change channels</strong> (essential functionality).You <strong>don’t need to know</strong> how internal circuits work.</li></ul></li></ul><pre><code class="language-java">abstract class TV {
    abstract void changeChannel();  // Abstract method (no implementation)
}

class SmartTV extends TV {
    @Override
    void changeChannel() {  
        System.out.println("Switching to next channel...");
    }
}
</code></pre><ul><li><strong>Inheritance:</strong> Enabling one class to inherit properties and behavior from another. It reduces <strong>code duplication</strong> and makes maintenance easier.<ul><li><strong>Examples: Family Inheritance:</strong> A <strong>child inherits features</strong> from parents, like eye color and habits. The child can <strong>also have their own unique features</strong>.</li></ul></li></ul><pre><code class="language-java">class Parent {
    void nature() {
        System.out.println("Parent is kind and hardworking.");
    }
}

class Child extends Parent {
    void hobby() {
        System.out.println("Child loves painting.");
    }
}

public class FamilyTest {
    public static void main(String[] args) {
        Child c = new Child();
        c.nature();  // Inherited from Parent
        c.hobby();   // Child's own method
    }
}
</code></pre><ul><li><strong>Polymorphism:</strong> Allowing methods to perform differently based on the object type (overloading &amp; overriding) improves <strong>code flexibility</strong>.<ul><li><strong>Examples: A Person in Different Roles:</strong> A <strong>teacher in class</strong> (explains topics). The <strong>same person at home</strong> (cooks, relaxes).</li></ul></li></ul><pre><code class="language-java">class Person {

    void cook() {
        System.out.println("Person is cooking at home");
    }
    
    void cook(String CookingItems) {   // Method Overloading - Compile-time Polymorphism
        System.out.println("Person is cooking " + CookingItems + " at home");
    }
    
    
}
class Teacher extends Person {
    @Override
    void cook() {    // Method Overriding - Runtime Polymorphism
        System.out.println("Person is cooking at school");
    }
}
</code></pre><h3>2. What is the difference between abstraction and encapsulation?</h3><ul><li><strong>Abstraction</strong> focuses on <strong>hiding implementation details</strong> and exposing only the essential features of an object. It simplifies complexity by allowing the user to interact with a system without worrying about the inner workings. It is achieved using abstract classes and interfaces. The goal is to show <strong>what an object does</strong>, not how it does it. An example of abstraction is an ATM: users can withdraw money without needing to know the internal workings of the ATM.</li><li><strong>Encapsulation</strong>, on the other hand, is about <strong>protecting data</strong> and restricting access to it. This is done by making fields private and providing controlled access through public methods like getters and setters. The focus here is on <strong>how the data is accessed</strong> and modified, ensuring the internal state of an object is protected from unauthorized access. A good example of encapsulation is a bank account: the balance is private, and users can only interact with it through controlled methods like deposit and withdrawal.</li></ul><h3>3. What is an abstract class and how is it different from an interface?</h3><ul><li>An <strong>abstract class</strong> is a class that cannot be instantiated on its own and is meant to be extended by other classes. It can have both abstract (without implementation) and concrete (with implementation) methods, as well as instance variables and constructors. Abstract classes are used when you want to provide a common base with shared behavior and force subclasses to implement specific methods.</li><li>An <strong>interface</strong>, on the other hand, defines a contract of methods that a class must implement. Before Java 8, interfaces could only contain abstract methods, but from Java 8 onwards, they can also contain default methods (with implementation), static methods, and private methods. Interfaces allow for <strong>multiple inheritance</strong>, meaning a class can implement multiple interfaces, while abstract classes allow <strong>single inheritance</strong>.</li></ul><h3>4. What is a <code>Functional Interface</code> in Java 8?</h3><p>A <strong>Functional Interface</strong> in Java 8 is an informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification. Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract. These interfaces are intended to be used with <strong>lambda expressions</strong> or <strong>method references</strong>, enabling functional programming paradigms in Java.</p><pre><code class="language-java">@java.lang.FunctionalInterface
interface FunctionalInterface {
    int add(int a,int b);
    
}
</code></pre><h3>5. What are lambda expressions in Java? What are the benefits of using Java 8 Lambda expressions?</h3><p>Lambda expressions in Java, introduced in Java 8, provide a concise way to represent methods that can be passed around as arguments. They consist of parameters, an arrow token (<code>-&gt;</code>), and a body. The benefits include more concise and readable code, support for functional programming, improved performance, cleaner code with functional interfaces, and easier parallel processing using streams. Lambda expressions enhance Java's ability to handle functional programming patterns, making the code more expressive and efficient.</p><pre><code class="language-java">public class Lambda {
    public static void main(String[] args) {
        List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.stream().filter(n -&gt; n % 2 == 0).forEach(System.out::println);

    }
}
</code></pre><h3>6. Explain the <code>Comparable</code> and <code>Comparator</code> interfaces in Java.</h3><p>The <strong>Comparable</strong> interface is used to define a natural ordering of objects within the class itself by overriding the <code>compareTo()</code> method, typically for a single sorting criterion.</p><p>The <strong>Comparator</strong> interface, on the other hand, allows for multiple sorting orders by implementing the <code>compare()</code> method in a separate class or as a lambda expression. While <strong>Comparable</strong> is for default sorting, <strong>Comparator</strong> is used when different sorting strategies are needed.</p><h3>7. What is the use of <code>default</code> methods in interfaces?</h3><p><strong>Default methods in interfaces</strong> (introduced in Java 8) allow an interface to provide a method implementation. They also help resolve ambiguity in multiple inheritance scenarios.</p><h3>8. What are the advantages of using the <code>interface</code> in Java?</h3><ul><li><strong>Multiple Inheritance</strong>: They allow classes to implement multiple interfaces, supporting multiple inheritance.</li><li><strong>Loose Coupling</strong>: Interfaces promote decoupling between components, making the code more maintainable and testable.</li><li><strong>Abstraction</strong>: They define behavior without implementation details, achieving abstraction.</li><li><strong>Code Reusability</strong>: Multiple classes can implement the same interface, enabling code reuse.</li><li><strong>Flexibility</strong>: They allow easy changes to the implementation without affecting the rest of the code.</li><li><strong>Polymorphism</strong>: Interfaces enable polymorphism, allowing different classes to be treated uniformly.</li><li><strong>Functional Programming Support</strong>: Java 8 interfaces can have default methods supporting functional programming.</li></ul><h3>9. What are the different types of access modifiers in Java?</h3><p>To achieve <strong>data hiding</strong> we need access modifiers. Access modifiers in Java are used to control the visibility and accessibility of classes, methods, constructors, and variables.</p><p><strong>public:</strong> We can access the public members from anywhere (Universally accessible).</p><pre><code class="language-java">public class Animal {
    public String name;
}</code></pre><p><strong>private:</strong> We can access the private members only from the same class. If you want to access it from outside, then you have to generate a getter-setter method (public method) inside that class where you define the private members.</p><pre><code class="language-java">class Animal {
    private String name;  // Not accessible outside the class
}</code></pre><p><strong>protected:</strong> We can access the protected members within the same package and by subclasses (including subclasses in other packages).</p><pre><code class="language-java">class Animal {
    protected void sound() {
        System.out.println("Animal makes a sound");
    }
}</code></pre><p><strong>default:</strong> We can access only within the same packages. When no access modifier is specified, it is considered <strong>default</strong> or <strong>package-private</strong>.</p><pre><code class="language-java">class Animal {
    void sound() {  // No modifier, so it's package-private
        System.out.println("Animal makes a sound");
    }
}</code></pre><h3>10. Explain the concept of polymorphism in Java.</h3><p>The term "polymorphism" is derived from the Greek words <strong>"poly"</strong> (meaning many) and <strong>"morph"</strong> (meaning form). It refers to the ability of an object to take on multiple forms.</p><p>It has two types:</p><ol><li><strong>Compile-time Polymorphism (Method Overloading)</strong>: Same method name with different parameters, resolved at compile time.</li><li><strong>Runtime Polymorphism (Method Overriding)</strong>: A subclass redefines a superclass method, with the method to be called determined at runtime based on the object type.</li></ol><p>Polymorphism enhances flexibility and code reusability, allowing methods to behave differently based on input parameters or object type.</p><h3>11. What is the role of the <code>super</code> keyword in Java?</h3><p>The <code>super</code> keyword in Java is used to refer to the parent class members (methods, fields, constructors) from a child class. It allows calling overridden methods, accessing parent class constructors, and resolving conflicts between parent and child class members with the same name. It enables better control and interaction in an inheritance hierarchy.</p><pre><code class="language-java">class Animal {   //parent class
    
    String name;  //parent Class Fields:

    Animal(String name) {  //parent class constructor
        System.out.println("Animal name: " + name);
    }

    void sound() {  //parent class method
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {   //child class
    
    String name = super.name;  //access Parent Class Fields

    Dog(String name) {
        super(name); // calls the constructor of Animal class
        System.out.println("Dog created");
    }

    void sound() {
        super.sound(); // Calls the method from Animal class
        System.out.println("Dog barks");
    }
}
</code></pre><h3>12. What is method overloading and method overriding?</h3><p><strong>Method Overloading :</strong></p><ol><li>Same Class</li><li>Same Method name</li></ol><pre><code class="language-java">class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
    
    void sound(String animalType) {
        System.out.println(animalType+" makes a sound");
    }
}
</code></pre><ul><li><strong>Method Overriding:</strong></li></ul><ol><li>Same method name</li><li>Same return type</li><li>Same parameter</li></ol><p>different class (one is super/parent class another is/are sub/child class).</p><p>Method overriding occurs when a subclass provides its own implementation of a method that is already defined in its superclass. It is resolved at <strong>runtime</strong> (dynamic polymorphism).</p><pre><code class="language-java">class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class AnimalTypes extends Animal {
    @Override
    void sound() {
        System.out.println("Dog barks");
    }
}
</code></pre><h3>13. What is the difference between <code>List</code>, <code>Set</code>, and <code>Map</code> interfaces in Java?</h3><ul><li><strong>List</strong>:<ul><li>Represents an ordered collection of elements.</li><li>Allows duplicate elements and maintains the insertion order.</li><li>Common implementations: <code>ArrayList</code>, <code>LinkedList</code>.</li><li>Example: <code>List&lt;String&gt; list = new ArrayList&lt;&gt;();</code></li></ul></li><li><strong>Set</strong>:<ul><li>Represents a collection of unique elements (no duplicates allowed).</li><li>Does not guarantee any specific order of elements.</li><li>Common implementations: <code>HashSet</code>, <code>LinkedHashSet</code>, <code>TreeSet</code>.</li><li>Example: <code>Set&lt;String&gt; set = new HashSet&lt;&gt;();</code></li></ul></li><li><strong>Map</strong>:<ul><li>Represents a collection of key-value pairs, where each key is unique and maps to a specific value.</li><li>Allows fast lookup of values based on keys.</li><li>Common implementations: <code>HashMap</code>, <code>LinkedHashMap</code>, <code>TreeMap</code>.</li><li>Example: <code>Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();</code></li></ul></li></ul><h3>14. Explain the concept of exception handling in Java.</h3><p>The exception handling in Java is a way for developers to handle run-time errors without terminating the program. This is achieved by catching, i.e., capturing these exceptions and taking appropriate action.</p><p><strong>Java exceptions are classified into the following types:</strong></p><ul><li><strong>Checked Exceptions</strong> – Handled by the programmer and checked during compile time (e.g., <code>IOException</code>, <code>SQLException</code>).</li><li><strong>Unchecked Exceptions</strong> – Occur mostly because of programming errors and are therefore neglected by the programmer (e.g., <code>NullPointerException</code>, <code>ArrayIndexOutOfBoundsException</code>).</li><li><strong>Errors</strong> – Serious conditions impossible to handle such as <code>OutOfMemoryError</code>, <code>StackOverflowError</code>.</li></ul><h3>15. What is the difference between <code>final</code>, <code>finally</code>, and <code>finalize</code> in Java?</h3><p><code><strong>final</strong></code><strong> – Prevents Modification</strong></p><ul><li>Following its initialization, it cannot be modified.</li><li>Can not be overridden by any subclass.</li><li>Can not be inherited (subclassed).</li></ul><p><code><strong>finally</strong></code><strong> – Ensures Code Execution</strong></p><ul><li>After exception handling.</li><li>Executed whether or not the exception has originated.</li><li>Used file cleanup, connection release, etc.</li></ul><p><code><strong>finalize()</strong></code><strong> – Called Before Object is Garbage Collected</strong></p><ul><li>Defined in Object class.</li><li>For cleanup processing before object destruction.</li><li>Not recommended because the Garbage Collection is unpredictable.</li></ul><h3>16. What is a checked exception and an unchecked exception in Java?</h3><p>The exception handling in Java is a way for developers to handle run-time errors without terminating the program. This is achieved by catching, i.e., capturing these exceptions and taking appropriate action.</p><p><strong>Checked exceptions</strong> are exceptions that must be handled at compile time using <code>try-catch</code> or <code>throws</code> . If the programmer doesn't apply it, then this causes the program not to compile. These exceptions are used in things like, for example, file not found (<code>FileNotFoundException</code>) or database error (<code>SQLException</code>).</p><pre><code class="language-java">try {
    FileReader file = new FileReader("test.txt"); // FileNotFoundException
} catch (FileNotFoundException e) {
    System.out.println("File not found!");
}
</code></pre><p><strong>Unchecked exceptions</strong> shall demand no explicit handling because they occur at <strong>runtime</strong>. Since they are caused by <strong>programming mistakes</strong>—for example, trying to access a null reference (<code>NullPointerException</code>), division by zero (<code>ArithmeticException</code>), or an incorrect index value for an array (<code>IndexOutOfBoundsException</code>)—in addition to those cases where they occur.</p><pre><code class="language-java">int num = 10 / 0; // ArithmeticException
</code></pre><h3>17. What is a <code>try-catch-finally</code> block in Java?</h3><p><code><strong>try</strong></code><strong> Block:</strong> Contains code that may throw an exception.</p><p><code><strong>catch</strong></code><strong> Block:</strong> Handles specific exceptions that occur in the **<code>try</code>**block.</p><p><code><strong>finally</strong></code><strong> Block:</strong> Executes <strong>always</strong>, whether an exception occurs or not.</p><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {
        try {
            int result = 10 / 0; // Exception occurs
        } catch (ArithmeticException e) {
            System.out.println("Error: Cannot divide by zero!");
        } finally {
            System.out.println("Finally block always executes.");
        }
    }
}</code></pre><h3>18. What is <code>Thread</code> in Java?</h3><p>A <strong>thread</strong> in Java is the smallest, concurrent unit of execution in a process. Java has built-in features for multithreading so that several threads can run together to boost the performance of the application.</p><p><strong>How to Create a Thread?</strong></p><p><strong>By extending the Thread class:</strong> Override the run() method and call start() to begin execution.</p><pre><code class="language-java">class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running...");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start(); // Starts the thread
    }
}
</code></pre><p><strong>By implementing the Runnable interface:</strong> Implement the Runnable, give an instance to the Thread object, and call start().</p><pre><code class="language-java">class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Thread is running...");
    }
}

public class Main {
    public static void main(String[] args) {
        Thread t1 = new Thread(new MyRunnable());
        t1.start();
    }
}
</code></pre><p><strong>Thread Lifecycle in Java:</strong></p><p><strong>New</strong>-Newly Born (Created but not yet started).</p><p><strong>Runnable</strong>—Ready to execute but waiting for CPU.</p><p><strong>Running</strong> execution in progress.</p><p><strong>Blocked/Waiting</strong>—Temporarily on Hold/Suspended.</p><p><strong>Terminated</strong>—Execution is complete.</p><h3>19. What is the difference between <code>wait()</code> and <code>sleep()</code> methods in Java?</h3><p>Both wait() and sleep() are different in Java: they allow execution to be paused.</p><p><strong>The wait() Method</strong></p><p>It is defined in the Object class. It is used for thread synchronization (waits for notification). The method releases the monitor lock while waiting. It must be called from inside synchronized blocks. The method can be resumed with <code>notify()</code> or <code>notifyAll()</code>.</p><p><strong>The sleep() Method</strong></p><p>It is defined in the<code>Thread</code> class. It is used to pause execution for a specified time. It does not release the lock; instead, it merely pauses execution. It can be interrupted from another thread using <code>interrupt()</code>.</p><h3>20. What is <code>deadlock</code> in Java, and how can it be prevented?</h3><p>A deadlock occurs in Java when two or more threads are holding locks on certain resources and are thereby waiting for one another to release those locks, forming a circular dependency. Thus, the threads stay blocked forever. A deadlock occurs when multiple threads hold locks and wait for each other indefinitely; it can either be prevented outright or resolved once it occurs.</p><p><strong>How to Prevent Deadlock in Java?</strong></p><ul><li>Always lock in the same order so that a circular dependency is not formed. Example: Lock A, then lock B.</li><li>Use tryLock() in ReentrantLock to Avoid Blocking Forever: A thread can acquire a lock if it is free.</li><li>Assign Locking Order: Always lock in a fixed and predefined order to avoid circular dependency formation.</li><li>Use a Timeout Strategy: Lock.tryLock(timeout, TimeUnit.SECONDS) to avoid waiting indefinitely.</li><li>Minimize the Locking Scope: Lock only the critical section to lessen contention.</li></ul><h2>Top 10 mostly asked Java Interview Questions on Advanced Java And APIs</h2><h3>1. Explain <code>Stream</code> API in Java 8 and how it differs from <code>Collection</code>?</h3><p>Java 8 introduced the <code>Stream</code> API, which lets a person work functionally on the collections to get them processed efficiently. The operations allowed include filtering, mapping, reducing, and sorting the items using a pipeline without modifying the data source.</p><p><strong>Key Features of Stream API:</strong></p><p>Functional (using Lambda expressions).</p><p>Allowing parallel processing for better performance.</p><p>Doing lazy evaluation (operations only get executed when required).</p><p>Providing a clean and readable way to manipulate the data.</p><p><strong>how does it differ from </strong><code><strong>Collection</strong></code><strong>?</strong></p><p>The Stream API can work on collections in a functional, efficient, and parallel way. Unlike collections, however, streams don't carry data but act lazily and immutably on top of that data.</p><h3>2. What is <code>ExecutorService</code> in Java?</h3><p>Mode of <code>ExecutorService</code> Java has more to offer in the form of high-level threading control. It also dwells in the domain of <strong>java.util.concurrent</strong> and abstracts the management of thread pools from arbitrary concurrency management into task submission.</p><p><code>ExecutorService</code> proves to be a boon for concurrent and parallel extent in Java. Thread management becomes much simpler with it, and tasks or asynchronous functions can be simultaneously carried out in the thread pool, which ends up proving to be a performance and resource engine boost.</p><p>Thread pooling keeps management of activities to be performed without the constant overhead of instantiating threads to do it. Task submission can happen with either <strong>Runnable</strong> or <strong>Callable</strong> objects. It provides methods for shutting down <strong>gracefully</strong> where new tasks are not accepted while the currently executing tasks are still being completed.</p><h3>3. What is the use of <code>volatile</code> keyword in Java?</h3><p>In Java, the volatile keyword guarantees that if one or more threads change the value of a variable, the latest value will always be seen by all threads. That is, value <strong>caching</strong> and <strong>optimization</strong>-related problems that arise in a multi-threaded environment are overcome.</p><h3>4. What is the role of <code>StackTrace</code> in Java exception handling?</h3><p>The <code>StackTrace</code> in Java offers an elaborate description of the stack at the point where an exception occurs. It is used to <strong>debug</strong> and give error <strong>diagnoses</strong>. It'll eavesdrop on the chain of method calls leading to the exception, including class names, method names, and number of lines.</p><p><strong>Role of</strong> <code>StackTrace</code><strong>:</strong></p><p><strong>Debugging:</strong> Indicating the point at which the exception manifests itself to find it in the code.</p><p><strong>Call Path:</strong> Displaying the sequence of methods leading to an exception.</p><p><strong>Cause Analysis:</strong> Indicating the precise line in the source code where the exception occurred.</p><p><strong>Logging:</strong> Useful for logging errors in production environments for later analysis.</p><p><strong>Exception Traversal:</strong> For tracing the journey of exceptions over the methods.</p><h3>5. Explain Java's memory model.</h3><p>In Java, the Memory Model defines how variables are stored in memory and how they are accessed by threads in a multithreaded environment concerning visibility, atomicity, and ordering.</p><p><strong>Main Memory vs. Working Memory:</strong></p><p>Main Memory: Shared among all threads and includes variables that are stored inside it.</p><p>Working Memory: Own private working memory copy of those variables kept by each thread.</p><p><strong>Visibility:</strong></p><p>When a thread changes the value of a variable, it guarantees that other threads will see the new value. You can enforce this by either adding the volatile keyword or using synchronized blocks.</p><p><strong>Atomicity:</strong></p><p>Operations on a single variable (like read or write) are atomic; that is, they cannot be interrupted. Compound operations (like increment, which reads, modifies, and writes) are not atomic automatically and generally require synchronization.</p><p><strong>Ordering:</strong></p><p>The happens-before order is what ensures that some operations will be visible to other threads in a strict order. For example, if a thread writes to a volatile variable, all other threads would be able to see it instantaneously.</p><h3>6. What is a Singleton design pattern in Java?</h3><p>The singleton design pattern guarantees that there is only one instance of a class and provides a global point of access for that instance. It is implemented through:</p><ul><li>Private constructor prevents instantiation from outside the class.</li><li>The static method (getInstance()) serves to provide the instance.</li><li>This is lazy initialization that ensures that the instance is created only when required.</li></ul><p><strong>Pros:</strong></p><ul><li>Gives a single-instance guarantee.</li><li>Resource efficient.</li></ul><p><strong>Cons:</strong></p><ul><li>Global state may lead to problems.</li><li>Difficult to test and manage in multi-threaded environments.</li></ul><h3>7. Explain the Producer-Consumer problem in Java.</h3><p>The <strong>Producer-Consumer</strong> problem is associated with two types of threads: producers that create and insert data into the shared buffer and consumers that take the data from the buffer. The task is to make producers wait when the size of the buffer is full and consumers wait when the buffer runs empty.</p><p><strong>The main points are:</strong></p><ul><li>The <strong>producers</strong> add the data to the buffer and wait if it is full.</li><li>The <strong>consumer</strong> consumes data from the buffer and waits if it is empty.</li><li>Synchronize the threads using wait() and notify() to enable the distribution of mutual exclusion between them.</li></ul><p><strong>Common objective:</strong></p><p>To maintain effective handling of their shared resources between multiple producers and consumers, keeping any possible data consistency from being compromised.</p><h3>8. What is the difference between <code>synchronized</code> and <code>concurrent</code> collections in Java?</h3><p><strong>Synchronized Collections</strong>:</p><ul><li>Thread-safe by synchronizing methods.</li><li>Locks entire collection, which can cause performance issues.</li><li>Examples: <code>Vector</code>, <code>Hashtable</code>, <code>Collections.synchronizedList()</code>.</li></ul><p><strong>Concurrent Collections</strong>:</p><ul><li>Thread-safe with fine-grained locking.</li><li>Allows multiple threads to operate concurrently with better performance.</li><li>Examples: <code>ConcurrentHashMap</code>, <code>CopyOnWriteArrayList</code>, <code>BlockingQueue</code>.</li></ul><h3>9. How do you use the <code>reduce()</code> method in Java Streams?</h3><p>The reduce() method of the Java Streams framework is used to accumulate the stream elements into a single result. It takes a binary operator to combine the elements.</p><p><strong>Syntax:</strong></p><pre><code class="language-java">Optional&lt;T&gt; reduce(BinaryOperator&lt;T&gt; accumulator)

T reduce(T identity, BinaryOperator&lt;T&gt; accumulator)
</code></pre><p>The first variant returns an Optional type T, whereas the second variant returns a non-optional result with the help of an identity value.</p><pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, (a, b) -&gt; a + b);  // Output: 15
</code></pre><h3>10. Features of Java 8?</h3><p>Java 8 was critical in adding to the few basic features, which attested to the fact that the enhancement of the languages was realistic.</p><p><strong>Lambda Expressions:</strong> Internalizes function-style syntax to enable passing behavior. Eg: (a, b) -&gt; a + b.</p><p><strong>Streams API:</strong> Functional-style processing of sequences (e.g., collections). Provides filter(), map(), reduce(), etc.</p><p><strong>Functional Interfaces:</strong> Interfaces with only one abstract method that may use lambda expressions. Eg: @FunctionalInterface public interface MyFunction { void apply(); }.</p><p><strong>Default Methods:</strong> Methods have a body for interfaces: Backwards compatible. Eg: default void newMethod() { ... }.</p><p><strong>Method References:</strong> A shorthand for lambda expressions. Eg: String::toUpperCase.</p><p><strong>Optional Class:</strong> It wraps values to effectively prevent NullPointerExceptions. Eg: Optional&lt;String&gt; name = Optional.of("John").</p><p><strong>New Date and Time API:</strong> A more powerful API with which date/time manipulation has been made available (java.time). Eg: LocalDate.now().</p><p><strong>Nashorn</strong> has proven to be an advanced and better-performing engine for running JavaScript code with Java applications.</p><p><strong>CompletableFuture:</strong> Asynchronous programming is thereby possible, creating a non-blocking operation:</p><p><strong>Parallel Streams:</strong> Processing using multiple streams, hence more time-efficient.</p><h2>Conclusion:</h2><p>The definitive article concerning the 50 most frequently asked Java interview questions covers everything from core Java to OOP and the collection framework. Candidates are fortified in their Java knowledge and problem-solving methodologies by elucidating pertinent concepts like JVM, JDK, JRE, platform independence, OOP principles, memory management, multithreading, exception handling, and Java 8+ features.</p><p>For an interview to be successful, coding practice and making optimized solutions go hand in hand with the latest updates on Java. With ample insight into all these concepts, you will be ready for every theoretical and coding challenge a Java interview throws at you.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Java</category>
            <category>Interview Questions Answers</category>
            <category>OOPs And Collection Framework</category>
            <category>Advanced Java And APIs</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/4_45ac5c674f.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[A Complete Guide to Java Collection Framework : Java Tutorial]]></title>
            <link>https://www.codingshuttle.com/blogs/java-collection-framework-java-collections</link>
            <guid>https://www.codingshuttle.com/blogs/java-collection-framework-java-collections</guid>
            <pubDate>Fri, 14 Feb 2025 20:50:15 GMT</pubDate>
            <description><![CDATA[Let's explore the key collection types like List, Set, Map, and Queue. It covers essential concepts such as iterators, sorting, searching, and thread-safe collections, helping developers efficiently manage and manipulate data in Java applications.]]></description>
            <content:encoded><![CDATA[<h2>Introduction:</h2><p>The <strong>Java Collection Framework</strong> is a comprehensive set of <strong>classes</strong> (<strong>ArrayList, LinkedList, HashSet, PriorityQueue</strong>) and <strong>interfaces</strong> (<strong>List, Set, Queue</strong>) and <strong>implementations</strong> in <strong>Java</strong>. That provides powerful <strong>data structures</strong> and <strong>algorithms</strong> for <strong>storing</strong>, <strong>handling</strong>, <strong>manipulating</strong>, and <strong>reusable-efficiently implementing</strong> collections of objects. The Java Collections are used from<code>java.util.*</code> package.</p><h3><strong>Importance and Use Cases Of Java Collection Framework</strong></h3><ul><li>It provides <strong>pre-implemented</strong> data architecture which helps to <strong>reduce</strong> programming effort.</li><li>It offers <strong>optimized</strong> implementations that help to <strong>enhance</strong> performance.</li><li>It provides <strong>consistent APIs</strong> across different collection types.</li><li>For <strong>sorting</strong> (<strong>sort()</strong>), <strong>searching</strong> (<code>binarySearch()</code>), and <strong>iterating</strong> () inside the <strong>data structure</strong>, ****makes these operations <strong>easier</strong> by providing the necessary <strong>methods</strong>.</li><li>It supports <strong>concurrent collections</strong> (<code>ConcurrentHashMap</code>) for <strong>thread-safe</strong> operations.</li><li>It helps to enable <strong>cache implementations</strong> (<code>LinkedHashMap</code> ) for <strong>LRU</strong> (<strong>Least Recently Used</strong>) <strong>caching</strong>.</li><li>It gives the facility of <strong>graph &amp; tree structures</strong> by implementing <strong>graph traversal algorithms</strong> using <code>HashMap</code> and <code>TreeSet</code>.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Java_Collection_Framework_dddd693169.png" alt="Java Collection Framework.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Java_Collection_Framework_dddd693169.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Java_Collection_Framework_dddd693169.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Java_Collection_Framework_dddd693169.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Java_Collection_Framework_dddd693169.png 1000w," sizes="100vw"><figcaption>Java Collection Framework</figcaption></figure><h2>Java Collections: (<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html">Oracle_Docs_For_Inbuilt_Methods_Of_Java_Collections_Class</a>)</h2><p>The <strong>Java Collections</strong> is a Java class. This class consists exclusively of static methods that operate on or return collections. It contains polymorphic algorithms that operate on collections, "<strong>wrappers</strong>", which return a new collection backed by a specified collection, and a few other odds and ends. The methods of this class all throw a <strong>NullPointerException</strong> if the collections or class objects provided to them are null. This class is a member of the Java Collections Framework.</p><blockquote><p><strong>Classes</strong> are <strong>user-defined blueprints</strong> for creating objects. They define fields (variables) and methods (functions) but do not occupy memory until an object is created. <strong>Objects</strong> are <strong>instances of a class</strong> that represent real-world entities. They are used to access the fields and methods defined in the class.</p></blockquote><h2>Java Wrapper Class And Generics:</h2><h3>Java Wrapper Class:</h3><p>The Wrapper class wraps a value of the primitive type (int, long, float) int in an object. An object of type Wrapper Class contains a single field whose type is primitive.</p><blockquote><p><strong>Primitive Data types:</strong> The Java programming language is statically typed, meaning that all variables must be declared before being used. There are <strong>eight primitive data types</strong> in Java: <strong>int</strong>, <strong>float</strong>, <strong>long</strong>, <strong>double</strong>, <strong>char</strong>, <strong>boolean</strong>, <strong>byte</strong>, and <strong>short</strong>.</p></blockquote><h3>Why we need Wrapper Class:</h3><ul><li>The classes (ArrayList, Vector) of <code>java.util.*</code> Packages are mainly worked to handle <strong>Object</strong>s.</li><li>An Object is needed to support synchronization in multithreading.</li></ul><figure class="table"><table><tbody><tr><td><strong>Wrapper Class</strong></td><td><strong>Primitive Data Types</strong></td></tr><tr><td>Integer</td><td>int</td></tr><tr><td>Float</td><td>float</td></tr><tr><td>Long</td><td>long</td></tr><tr><td>Double</td><td>double</td></tr><tr><td>Character</td><td>char</td></tr><tr><td>Boolean</td><td>boolean</td></tr><tr><td>Byte</td><td>byte</td></tr><tr><td>Short</td><td>short</td></tr></tbody></table></figure><p><strong>Autoboxing:</strong> The <strong>conversion process</strong> of primitive data types to their corresponding wrapper class that is ‘long’ to ‘Long’.</p><p><strong>Unboxing:</strong> This is the reverse process of the Autoboxing process. The conversion process of a wrapper class to primitive data types that is ‘Long’ to ‘long’.</p><h3>Generics: Parameterized Typed</h3><p>By using generics, it is possible to create classes, interfaces, and methods that work for different data types. Generics are used to prevent <code>ClassCastException</code> by enforcing type checks at <strong>compile-time</strong>.</p><pre><code class="language-java">public class GenericsName&lt;E&gt; {
    private E data;
    GenericsName(E e){
        e=this.data;
    }
    E GenericsMethod(E e){
        return e;
    }
    public static void main(String[] args) {
        GenericsName&lt;String&gt; stringGenericsName = new GenericsName&lt;&gt;("Hi! Hello");   

        GenericsName&lt;Integer&gt; integerGenericsName = new GenericsName&lt;&gt;(25);

        GenericsName&lt;Float&gt; floatGenericsName = new GenericsName&lt;&gt;(22f);

        GenericsName&lt;Boolean&gt; booleanGenericsName = new GenericsName&lt;&gt;(true);
        
    }
}
</code></pre><h3>Bounded Generic Types:</h3><p>Generic classes can only work with children’s data type of <code>Number</code> class (e.g. Integer, Float, etc.). You can not use it for primitive data types.</p><blockquote><p><code>Number</code> class: The abstract class <strong>Number</strong> is the superclass of platform classes representing numeric values that are convertible to the primitive types byte, double, float, int, long, and short.</p></blockquote><h2>Java Iterable Interface: (<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html">Oracle_Docs_Jdk8_For_Inbuilt_Methods_Of_Iterable_Interface</a>)</h2><p>Implementing this interface allows an object to be the target of the enhanced for statement (sometimes called the "for-each loop" statement). It performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.</p><pre><code class="language-java">public interface Iterable&lt;T&gt; {...}   // Returns an iterator over elements of type T.
</code></pre><blockquote><p><strong>Interfaces</strong> are introduced for achieving abstraction and multiple inheritance. It provides full abstraction. Objects cannot be created directly from interfaces; at least one class must implement them.</p><ul><li><strong>Abstract Methods</strong> – Implicitly <code>public</code> and <code>abstract</code>, declared without an implementation.</li><li><strong>Default Methods (Java 8+)</strong> – Have an implementation and can be overridden.</li><li><strong>Static Methods (Java 8+)</strong> – Have an implementation but cannot be overridden.</li><li><strong>Private Methods (Java 9+)</strong> – Used for code reuse within the interface but not accessible outside.</li></ul></blockquote><h2>Java Collection Interfaces: (<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html">Oracle_Docs_Jdk8_For_InBuilt_Methods_Of_ Java_Collection_Interface</a>)</h2><p>The root interface in the collection hierarchy. A collection represents a group of objects known as its elements. Some collections allow duplicate elements, and others do not. Some are ordered, and others are unordered. Collections that have a defined <strong>encounter order</strong> are generally subtypes of the <strong>SequencedCollection</strong> interface. The JDK does not provide any direct implementations of this interface; it provides implementations of more specific <strong>sub-interfaces</strong> like <strong>Se</strong>t and <strong>List</strong>. This interface is typically used to pass collections around and manipulate them where maximum generality is desired. This interface is a member of the Java Collections Framework.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Collection_e89a465563.png" alt="Collection.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Collection_e89a465563.png 215w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Collection_e89a465563.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Collection_e89a465563.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Collection_e89a465563.png 1000w," sizes="100vw"><figcaption>Collections</figcaption></figure><h3>Java List Interface: (<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html">Oracle_Docs_Jdk8_For_In_Built_Methods_Of_List_Interface</a>)</h3><p>An ordered collection, where the user has precise control over where in the list each element is inserted. Unlike sets, lists typically allow duplicate elements. The List interface provides four methods for positional (indexed) access to list elements. Lists (like Java arrays) are zero-based.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/List_Interface_65940e7ba9.png" alt="List Interface.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_List_Interface_65940e7ba9.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_List_Interface_65940e7ba9.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_List_Interface_65940e7ba9.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_List_Interface_65940e7ba9.png 1000w," sizes="100vw"><figcaption>List</figcaption></figure><ul><li><strong>ArrayList</strong> or <strong>Resizable-array</strong> implementation of the List interface. Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. This implementation is not <strong>synchronized</strong>. <strong>Internal working of ArrayList:</strong> Initially, <strong>Array</strong> has a certain capacity, and elements are added and filled up. When the capacity is reached, the ArrayList creates a new larger array and copies the elements from the old array to the new one. This process of resizing and coping is transparent to the user.</li></ul><pre><code class="language-java">List&lt;Integer&gt; integerList = new ArrayList&lt;&gt;();
</code></pre><ul><li><strong>LinkedList</strong> (Doubly-linked list) implementation of the List and Deque interfaces. This implementation is not <strong>synchronized</strong>.</li></ul><pre><code class="language-java">List&lt;Integer&gt; integerList = new LinkedList&lt;&gt;();</code></pre><ul><li><strong>Stack</strong> represents a last-in-first-out (LIFO) stack of objects.</li></ul><pre><code class="language-java">List&lt;Integer&gt; integerList = new Stack&lt;&gt;();
</code></pre><ul><li><strong>Vector</strong> implements a growable array of objects. Like an array, it contains components that can be accessed using an integer index. However, the size of a Vector can grow or shrink as needed to accommodate adding and removing items after the Vector has been created.</li></ul><pre><code class="language-java">List&lt;Integer&gt; integerList = new Vector&lt;&gt;();</code></pre><h3>Java Set Interface:</h3><p>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Oracle_Docs_Jdk8_For_Inbuilt_Methods_Of_Set_Interface</a>)</p><p>A collection that contains no duplicate elements. All basic operations execute in constant time.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Set_Interface_1a72c89a5d.png" alt="Set Interface.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Set_Interface_1a72c89a5d.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Set_Interface_1a72c89a5d.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Set_Interface_1a72c89a5d.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Set_Interface_1a72c89a5d.png 1000w," sizes="100vw"></p><ul><li><strong>HashSet:</strong> This class implements the Set interface, backed by a hash table (actually a <strong>HashMap</strong> instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.</li></ul><pre><code class="language-java">Set&lt;Integer&gt; set = new HashSet&lt;&gt;();
</code></pre><ul><li><strong>EnumSet:</strong> A specialized Set implementation for use with enum types. All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created.</li><li><strong>LinkedHashSet:</strong> Hash table and linked list implementation of the Set interface, with well-defined encounter order.</li></ul><pre><code class="language-java">Set&lt;Integer&gt; set = new LinkedHashSet&lt;&gt;();
</code></pre><ul><li><strong>TreeSet:</strong> A NavigableSet implementation based on a TreeMap. The elements are ordered using their natural ordering.</li></ul><pre><code class="language-java">Set&lt;Integer&gt; set = new TreeSet&lt;&gt;();</code></pre><h3>Java Queue Interface: (<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html">Oracle_Docs_Jdk8_For_Inbuilt_Methods_Of_Queue_Interface</a>)</h3><p>A collection designed for holding elements before processing in order elements in a FIFO (first-in-first-out) manner.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Queue_Interface_98d0af2785.png" alt="Queue Interface.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Queue_Interface_98d0af2785.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Queue_Interface_98d0af2785.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Queue_Interface_98d0af2785.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Queue_Interface_98d0af2785.png 1000w," sizes="100vw"><figcaption>Queue</figcaption></figure><ul><li><strong>ArrayDeque:</strong> Resizable-array implementation of the Deque interface. Array deques have no capacity restrictions; they grow as necessary to support usage.</li></ul><pre><code class="language-java">Queue&lt;Integer&gt; queue = new ArrayDeque&lt;&gt;();
</code></pre><ul><li><strong>LinkedList:</strong> Doubly-linked list implementation of the List and Deque interfaces. Implements all optional list operations, and permits all elements (including null).</li></ul><pre><code class="language-java">Queue&lt;Integer&gt; queue = new LinkedList&lt;&gt;();</code></pre><ul><li><strong>PriorityQueue:</strong> An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time,</li></ul><pre><code class="language-java">Queue&lt;Integer&gt; queue = new PriorityQueue&lt;&gt;();
</code></pre><h3>Java Map Interface:(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Oracle_Docs_Jdk8_For_Inbuilt_Methods_Of_Map_Interface</a>)</h3><p>An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value. The Map interface provides three collection views, which allow a map's contents to be viewed as a set of keys, a collection of values, or set of key-value mappings.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Map_Interface_d58abd4b50.png" alt="Map Interface.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Map_Interface_d58abd4b50.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Map_Interface_d58abd4b50.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Map_Interface_d58abd4b50.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Map_Interface_d58abd4b50.png 1000w," sizes="100vw"><figcaption>Map</figcaption></figure><ul><li><strong>HashMap:</strong> Hash table-based implementation of the Map interface. This implementation provides all of the optional map operations and permits null values and the null key.</li></ul><pre><code class="language-java">Map&lt;Integer,Integer&gt; map = new HashMap&lt;&gt;();
</code></pre><ul><li><strong>TreeMap:</strong> A Red-Black tree-based NavigableMap implementation. The map is sorted according to the natural ordering of its keys.</li></ul><pre><code class="language-java">Map&lt;Integer,Integer&gt; map = new TreeMap&lt;&gt;();</code></pre><ul><li><strong>EnumMap:</strong> A specialized Map implementation for use with enum type keys. All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created.</li><li><strong>LinkedHashMap:</strong> Hash table and linked list implementation of the Map interface, with well-defined encounter order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries.</li></ul><pre><code class="language-java">Map&lt;Integer,Integer&gt; map = new LinkedHashMap&lt;&gt;();
</code></pre><ul><li><strong>WeakHAshMap:</strong> Hash table based implementation of the Map interface, with weak keys. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use.</li></ul><pre><code class="language-java">Map&lt;Integer,Integer&gt; map = new WeakHashMap&lt;&gt;();</code></pre><h3>Java Iterator Interface: (<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html">Oracle_Docs_Jdk8_For_Inbuilt_Methods_Of_Iterator_Interface</a>)</h3><p>An iterator over a collection. Iterator takes the place of Enumeration in the Java Collections Framework. Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.</p><h2>Concurrent Collections in Java:</h2><p>Concurrent collections in Java (<code>java.util.concurrent</code>) provide <strong>thread-safe</strong> alternatives to traditional collections, preventing issues like <code>ConcurrentModificationException</code> while improving performance in multi-threaded environments.</p><h3><strong>Key Concurrent Collections:</strong></h3><ol><li><code><strong>CopyOnWriteArrayList</strong></code> – A thread-safe <code>ArrayList</code> that creates a new copy on modification, ideal for read-heavy scenarios.</li><li><code><strong>ConcurrentHashMap</strong></code> – A thread-safe <code>HashMap</code> that uses segmentation for better performance.</li><li><code><strong>ConcurrentLinkedQueue</strong></code> – A non-blocking, thread-safe queue based on linked nodes.</li><li><code><strong>BlockingQueue</strong></code> (<code>ArrayBlockingQueue</code>, <code>LinkedBlockingQueue</code>) – Used in producer-consumer patterns, blocks when full/empty.</li><li><code><strong>ConcurrentSkipListMap</strong></code> – A thread-safe, sorted <code>TreeMap</code> alternative using a skip list algorithm.</li></ol><h2>Comparable &amp; Comparator: (Java 8)</h2><p><strong>Comparator:</strong> A comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections. sort or Arrays. sort) to allow precise control over the sort order. Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps) or to provide an ordering for collections of objects that don't have a natural ordering. The ordering imposed by a comparator c on a set of elements S is said to be consistent with equals if and only if c. compare(e1, e2)==0 has the same boolean value as e1.equals(e2) for every e1 and e2 in S.</p><pre><code class="language-java">class NameComparator implements Comparator&lt;Student&gt; {
    @Override
    public int compare(Student s1, Student s2) {
        return s1.name.compareTo(s2.name);  // Sorting by Name
    }
}</code></pre><p><strong>Usage:</strong> <code>Collections.*sort*(list, new NameComparator());</code></p><p><strong>Comparable:</strong> This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method. Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections. sort (and Arrays. sort). Objects that implement this interface can be used as keys in a sorted map or as elements in a sorted set, without the need to specify a comparator. The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e. compareTo(null) should throw a NullPointerException even though e. equals(null) returns false.</p><pre><code class="language-java">class Student implements Comparable&lt;Student&gt; {
    int id;
    String name;

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int compareTo(Student other) {
        return this.id - other.id;  // Ascending order by ID
    }
}</code></pre><ul><li><strong>Usage:</strong></li></ul><p><code>List&lt;Student&gt; list = new ArrayList&lt;&gt;();</code></p><p><code>list.add(new Student(2, "Alice"));</code></p><p><code>list.add(new Student(1, "Bob"));</code></p><p><code>Collections.*sort*(list);</code></p><h2>Java Collection Performance Optimization:</h2><ul><li><strong>Choose the Right Collection Type</strong> – Use <code>ArrayList</code> for fast lookups, <code>LinkedList</code> for frequent insertions, <code>HashMap</code> for fast key-value access, and <code>TreeSet/TreeMap</code> for sorted data.</li><li><strong>Optimize Initial Capacity &amp; Load Factor</strong> – Avoid frequent resizing by setting an initial capacity (<code>new ArrayList&lt;&gt;(1000)</code>, <code>new HashMap&lt;&gt;(16, 0.75f)</code>).</li><li><strong>Use Efficient Iteration</strong> – Prefer enhanced for-loops or iterators for modifications.</li><li><strong>Use Concurrent Collections</strong> – For multi-threading, use <code>ConcurrentHashMap</code>, <code>CopyOnWriteArrayList</code>, and <code>ConcurrentLinkedQueue</code>.</li><li><strong>Use Unmodifiable Collections</strong> – Reduce memory usage with <code>Collections.unmodifiableList()</code>.</li><li><strong>Leverage Java 8 Streams &amp; Parallel Processing</strong> – Use <code>parallelStream()</code> for large collections but avoid for small ones.</li><li><strong>Avoid Auto-Boxing</strong> – Use primitive arrays (<code>int[]</code>) instead of <code>ArrayList&lt;Integer&gt;</code>.</li><li><strong>Use Efficient Sorting</strong> – Utilize <code>Collections.sort()</code> or <code>Arrays.parallelSort()</code> for large datasets.</li><li><strong>Remove Elements Efficiently</strong> – Use <code>filter()</code> instead of <code>removeIf()</code> to avoid performance overhead.</li><li><strong>Avoid Redundant Collections</strong> – Use <code>Set</code> to remove duplicates efficiently.</li></ul><h2>Conclusion:</h2><p>This article provides an overview of the Java Collection Framework, which offers pre-implemented data structures like <code>List</code>, <code>Set</code>, <code>Queue</code>, and <code>Map</code> to store and manipulate collections of objects. It highlights key components such as interfaces, classes, and wrapper classes, along with the benefits of using generics, autoboxing, and thread-safe collections. The framework simplifies working with collections, ensuring optimized performance and consistency in Java applications.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Java</category>
            <category>Java 8</category>
            <category>Java Collection Framework</category>
            <category>Java Collections</category>
            <category>Comparator vs Comparable</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/collection_framework_e704dff4f2.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 8 Features of JDK 17 That You Must Know:  LTS, Features & Performance In Java]]></title>
            <link>https://www.codingshuttle.com/blogs/jdk-17-new-features-lts-features-and-performance-in-java</link>
            <guid>https://www.codingshuttle.com/blogs/jdk-17-new-features-lts-features-and-performance-in-java</guid>
            <pubDate>Fri, 14 Feb 2025 20:27:28 GMT</pubDate>
            <description><![CDATA[This article explores JDK 17's key features, including sealed classes, pattern matching for switch, and macOS AArch64 support, along with major improvements, deprecations, and removals in this LTS release.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p><strong>Oracle</strong> introduced <strong>Java 17, the LTS Java version, in September 2021 to improve and upgrade the application’s stability, performance, and garbage collection, to enhance security, and API.</strong> You can visit their official website, <strong>Oracle Help CenterJDK 17 Documentation—</strong><a href="https://docs.oracle.com/en/java/javase/17/">https://docs.oracle.com/en/java/javase/17/</a>. <strong>JDK 17 is free</strong> for production and redistribution under the <a href="https://www.oracle.com/downloads/licenses/no-fee-license.html">https://www.oracle.com/downloads/licenses/no-fee-license.html</a>.</p><blockquote><p><strong>LTS: Long-Time Support (LTS)</strong> in Java means a version that provides <strong>updated security, fixed bugs, and improved performance</strong> for the long term, ensuring enterprise applications stability. <strong>Java 8 (LTS), Java 11 (LTS), Java 17 (LTS),</strong> and <strong>Java 21 (LTS)</strong> are some <strong>Java (LTS) Versions</strong>.</p></blockquote><h3><strong>Limitations of Java 8:</strong></h3><ul><li>It lacks parallelism improvements. It has no multi-core processing support.</li><li>It requires more boilerplate code. Because it has no sealed classes or records.</li><li>It is less efficient than modern GCs.</li><li>It is a complex type of handling. It does not allow any pattern matching for the switch case.</li><li>Due to the weak security management (Weaker API encapsulation and outdated TLS) of this version, still it has security risks.</li><li>It has no LTS official support since Oracle ended updates in 2019.</li></ul><h3><strong>Limitation of Java 11:</strong></h3><ul><li>It still does not allow any pattern matching for the switch case.</li><li>It allows more boilerplate for data classes. Because it has no sealed classes or records.</li><li>Advanced <strong>ZGC(Z Garbage Collector) optimizations</strong> are required.</li><li>External dependencies are required.</li><li>For the HTTP clients, few improvements are required.</li></ul><p><strong>Java 17 resolves these issues</strong> with <strong>Sealed Classes, Pattern Matching, Records, ZGC, and better API security</strong>.</p><p>Go to Oracle’s official website, and you can download the JDK and install it on different operating systems. <a href="https://docs.oracle.com/en/java/javase/17/install/overview-jdk-installation.html">https://docs.oracle.com/en/java/javase/17/install/overview-jdk-installation.html</a>.</p><blockquote><p><strong>Java Development Kits (JDK)</strong> is used to develop, compile, and run Java applications. JDK is a combined version of JRE + Developments Tools and JRE is a Combined version of JVM + Libraries + Others tools. <strong>Java Runtime Environment</strong> is a core component of JVM for executing the java byte code.</p></blockquote><h2>Top Most New Enhancements And Features In JDK 17:</h2><p>To improve securities, developers’ productivity, and performances, many different topmost new features and enhancements are introduced by JDK 17, as outlined in various <strong>JEP</strong>s (<strong>JDK Enhancements Proposal</strong>s). To make Java’s outgoing commitment more modernization and adaptability, some features have been removed and deprecated by JDK 17.</p><blockquote><p><strong>JEP</strong>: It is a structured proposal or process to modify, remove, or add some features inside JDK.</p></blockquote><h3>1. Sealed Classes(<a href="https://openjdk.org/jeps/409">jeps-409</a>): <strong>Restricting the implementation with Sealed classes and Interfaces</strong></h3><p>We can achieve <strong>restricted</strong>/<strong>controlled</strong> inheritance by using <strong>sealed classes</strong>. Sealed classes must have at least one subclass. You can use one or more classes as permitted.</p><p>Imagine a <strong>government-issued ID card</strong> (like a passport or driver's license).</p><p><strong>You can have only specific types of ID cards</strong> (e.g., Passport, Driver’s License, or National ID).</p><p><strong>No one can randomly create a new type of government-issued ID</strong> without approval.</p><p>The government <strong>controls and restricts</strong> which ID types exist for security and standardization.</p><p>Similarly, in Java:</p><p><strong>Sealed classes</strong> define a <strong>fixed set of allowed subclasses</strong>—just like the government defines valid ID types.</p><p><strong>No unauthorized subclass</strong> can be created—just like you can't issue your own government ID.</p><p><strong>Controlled hierarchy ensures consistency and safety</strong>—just like ID verification.</p><pre><code class="language-java">public sealed class GovernmentIssuedDCard permits Passport, DriverLicense{
}

final class Passport extends GovernmentIssuedDCard {
    
}
final class DriverLicense extends GovernmentIssuedDCard {
    
}
</code></pre><h3>2. Pattern Matching for Switch(<a href="https://openjdk.org/jeps/406">jeps-406</a>):</h3><p>It simplifies code by allowing switch statements to handle different data types more efficiently, reducing boilerplate.</p><h3>3. New macOS AArch64 Support(<a href="https://openjdk.org/jeps/391">jeps-391</a>):</h3><p>It provides native support for Apple's M1 chips, enhancing performance and efficiency on macOS devices.</p><h3>4. <strong>New macOS Rendering Pipeline</strong>(<a href="https://openjdk.org/jeps/382">jeps-382</a>):</h3><p>It improves graphics rendering on macOS by leveraging Apple Metal API for better performance.</p><h3>5. <strong>macOS/AArch64 Port(</strong><a href="https://openjdk.org/jeps/391">jeps-391</a><strong>):</strong></h3><p>It ensures full compatibility and optimized performance on ARM-based Macs.</p><h3>6. <strong>Enhanced Pseudo-Random Number Generators(</strong><a href="https://openjdk.org/jeps/356">jeps-356</a><strong>):</strong></h3><p>It introduces new and flexible APIs for better randomness control in cryptographic and simulation applications.</p><h3>7. <strong>Implement Context-Specific Deserialization Filters(</strong><a href="https://openjdk.org/jeps/415">jeps-415</a><strong>):</strong></h3><p>It strengthens security by preventing deserialization attacks through customizable filters.</p><h3>8. <strong>Foreign Function &amp; Memory API(</strong><a href="https://openjdk.org/jeps/412">jeps-412</a><strong>):</strong></h3><p>It allows Java applications to efficiently interact with native code and memory, replacing unsafe methods like <code>sun.misc.Unsafe</code>.</p><h2>Removed Features and Options:</h2><h3>1. <strong>Strongly Encapsulate JDK Internals(</strong><a href="https://openjdk.org/jeps/403">jeps-403</a><strong>):</strong></h3><p>It enforces stricter module boundaries, reducing unintended dependencies and improving long-term maintainability.</p><h3>2. <strong>Remove RMI Activation(</strong><a href="https://openjdk.org/jeps/407">jeps-407</a><strong>):</strong></h3><p>It removes outdated Remote Method Invocation (RMI) activation, encouraging modern alternatives.</p><h3>3. <strong>Remove the Experimental AOT and JIT Compiler(</strong><a href="https://openjdk.org/jeps/410">jeps-410</a><strong>):</strong></h3><p>It discards experimental features that didn’t gain adoption, focusing on more stable optimizations.</p><h2>Deprecated Features and Options:</h2><h3>1. <strong>Deprecate the Applet API for Removal(</strong><a href="https://openjdk.org/jeps/398">jeps-398</a><strong>):</strong></h3><p>Since modern browsers no longer support Java Applets, this feature is marked for removal.</p><h3>2. <strong>Deprecate the Security Manager for Removal(</strong><a href="https://openjdk.org/jeps/411">jeps-411</a><strong>):</strong></h3><p>The security manager is outdated and being replaced with modern security frameworks.</p><h2>Known Issues:</h2><p>One of the <strong>known issues</strong> in JDK 17 is related to the <strong>JDK XSLT Transformer</strong>, which has certain limitations.</p><h3><strong>JDK XSLT Transformer Limitations:</strong></h3><p>These limitations can affect performance and functionality, particularly when dealing with large XML transformations. Developers should be aware of these restrictions and consider alternative solutions or workarounds if they encounter issues during XML processing.</p><h2>Conclusion:</h2><p>In this article, we explored the new features and enhancements in <strong>JDK 17</strong>, including <strong>Sealed Classes</strong>, <strong>Pattern Matching for Switch</strong>, and <strong>macOS AArch64 support</strong>, all aimed at improving security, performance, and developer productivity. With its <strong>LTS</strong> status, JDK 17 ensures long-term stability, making it a crucial update for Java developers looking to build modern, efficient applications.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Java</category>
            <category>JDK 17 Features</category>
            <category>JDK</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/top_feature_of_jdk_17_6b32d9b43a.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[JVM Architecture Explained Simply (With Diagram & Real-Life Example)]]></title>
            <link>https://www.codingshuttle.com/blogs/how-jvm-works-internally</link>
            <guid>https://www.codingshuttle.com/blogs/how-jvm-works-internally</guid>
            <pubDate>Fri, 14 Feb 2025 20:21:09 GMT</pubDate>
            <description><![CDATA[Understand what the Java Virtual Machine (JVM) is and how it works in this beginner-friendly guide. Learn about JVM architecture, key components like the class loader, execution engine, and runtime data areas.]]></description>
            <content:encoded><![CDATA[<p>If you have ever wondered how Java programs run on any device whether it’s your laptop, a server, or even a phone. The reason is the <strong>Java Virtual Machine (JVM)</strong> is the magic behind Java’s “write once, run anywhere” promise.</p><p>In this article, I’m going to break down what the JVM is, how it’s built, its key components, and why it’s so important, all in a simple and friendly way.</p><h2>What is JVM?</h2><p>The <strong>Java Virtual Machine (JVM)</strong> is like a virtual computer that runs Java programs. When you write Java code, it gets compiled into something called <strong>bytecode</strong>—a special format that’s not tied to any specific hardware. The JVM takes this bytecode and translates it into instructions your actual computer can understand, whether it’s running Windows, macOS, Linux, or something else.</p><p>Think of the JVM as a translator who speaks every computer’s language. You give it your Java bytecode, and it figures out how to make it work on whatever device you’re using. This is why Java apps are so portable—you don’t need to rewrite your code for different platforms.</p><h2>What is JVM Architecture?</h2><p>The JVM’s architecture is like a well-organized kitchen where different stations work together to cook your Java program. It’s a virtual machine that mimics a real computer, with its own memory, processor, and systems to manage your code. At a high level, the JVM takes your bytecode, processes it, and turns it into machine code that your hardware understands.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/JVM_Architecture_60b9dc09c4.png" alt="JVM Architecture.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_JVM_Architecture_60b9dc09c4.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_JVM_Architecture_60b9dc09c4.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_JVM_Architecture_60b9dc09c4.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_JVM_Architecture_60b9dc09c4.png 1000w," sizes="100vw"><figcaption>JVM Architecture</figcaption></figure><p>The architecture has three main parts:</p><ul><li><strong>Class Loader</strong>: Loads your Java classes into memory.</li><li><strong>Runtime Data Areas</strong>: Manages memory for your program’s data (like variables and objects).</li><li><strong>Execution Engine</strong>: Runs the bytecode, either by interpreting it or compiling it to machine code.</li></ul><p>These parts work together like a team to make sure your Java program runs smoothly.</p><h2>JVM Components</h2><p>Let’s break down the JVM’s key components—it’s like peeking under the hood of a car to see how it works.</p><h3>1. Class Loader</h3><p>The <strong>Class Loader</strong> is responsible for loading your .class files (bytecode) into memory. It’s like a librarian who finds and organizes books (classes) before you can read them.</p><p><strong>How it works:</strong></p><ul><li><strong>Loading</strong>: Reads .class files from your project or libraries.</li><li><strong>Linking</strong>: Verifies the bytecode is valid, prepares memory, and resolves references (like connecting classes to their dependencies).</li><li><strong>Initialization</strong>: Sets up static variables and runs static blocks.</li></ul><p>There are three types of class loaders:</p><ul><li><strong>Bootstrap Class Loader</strong>: Loads core Java classes (e.g., java.lang.String).</li><li><strong>Extension Class Loader</strong>: Loads extension classes (e.g., from jre/lib/ext).</li><li><strong>Application Class Loader</strong>: Loads your app’s classes.</li></ul><h3>2. Runtime Data Areas</h3><p>This is the JVM’s memory management system, like different shelves in a pantry for storing ingredients. It’s split into several areas:</p><ul><li><strong>Method Area</strong>: Stores class structures, like method code and metadata. Shared across all threads.</li><li><strong>Heap</strong>: Where objects and their instance variables live. Also shared across threads.</li><li><strong>Stack</strong>: Each thread gets its own stack to store method calls, local variables, and partial results.</li><li><strong>PC Register</strong>: Each thread has a Program Counter to track which instruction is being executed.</li><li><strong>Native Method Stack</strong>: Handles native methods (e.g., C code called via JNI).</li></ul><p>**Example:**When you create an object like String name = "Alice";, the String object goes in the <strong>Heap</strong>, and the name reference goes in the <strong>Stack</strong>.</p><h3>3. Execution Engine</h3><p>The <strong>Execution Engine</strong> is the part that actually runs your program. It’s like the chef who takes the recipe (bytecode) and cooks the meal (executes the program). It has three main parts:</p><ul><li><strong>Interpreter</strong>: Reads bytecode line by line and executes it. It’s fast to start but slower for repeated tasks.</li><li><strong>Just-In-Time (JIT) Compiler</strong>: Converts frequently used bytecode into native machine code for faster execution. It optimizes “hot spots” (code run often).</li><li><strong>Garbage Collector</strong>: Cleans up unused objects in the Heap to free memory. It runs automatically to prevent memory leaks.</li></ul><p><strong>Example of JIT in Action:</strong></p><pre><code class="language-java">public class LoopExample {
    public static void main(String[] args) {
        int sum = 0;
        for (int i = 0; i &lt; 1000000; i++) {
            sum += i; // This loop is a "hot spot"
        }
        System.out.println("Sum: " + sum);
    }
}</code></pre><p>The JIT compiler notices the loop runs a million times and compiles it to native code, making it faster after a few iterations.</p><h2>Importance of JVM - Why is Java Essential?</h2><p>The JVM is the backbone of Java’s popularity, and here’s why it’s such a big deal:</p><h3>1. Write Once, Run Anywhere</h3><p>Java code is compiled into bytecode, and <strong>that same bytecode can run on any platform</strong> — Windows, macOS, Linux, or even mobile devices — as long as there’s a JVM installed. This makes Java incredibly <strong>portable</strong>.</p><h3>2. High Performance with JIT</h3><p>Thanks to the <strong>Just-In-Time (JIT) Compiler</strong>, the JVM doesn’t just interpret code — it <strong>optimizes it at runtime</strong>, making long-running Java applications surprisingly fast and efficient.</p><h3>3. Smart Memory Management</h3><p>Manual memory cleanup? Nope. The JVM has a built-in <strong>Garbage Collector</strong> that automatically handles memory allocation and deallocation. This helps reduce memory leaks and crashes.</p><h3>4. Security Built-In</h3><p>The JVM includes features like <strong>bytecode verification</strong> and a <strong>Security Manager</strong>, which help protect your applications from malicious code or unwanted access.</p><h3>5. Scales From Small to Massive</h3><p>Whether you're building a small utility or a huge enterprise-level system, the JVM can handle it. Many large-scale, <strong>high-performance systems run on the JVM</strong> — from banking software to cloud-native microservices.</p><h3>6. Huge Ecosystem Support</h3><p>Java’s vibrant ecosystem — <strong>Spring, Hibernate, Apache Kafka</strong>, and even <strong>Kotlin</strong> — all rely on the JVM. It’s the foundation of one of the most active software development communities in the world.</p><h2>Conclusion</h2><p>The JVM is like the important person behind every Java program, it make sure your code runs smoothly on any device. and because of the <strong>Java Virtual Machine (JVM),</strong> Java is portable, fast, and secure and perfect for everything from tiny apps to massive enterprise systems.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>JVM</category>
            <category>Java Virtual Machine</category>
            <category>How JVM Works</category>
            <category>Java Virtual Machine</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/7_285c9e5d33.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[A Complete Guide to String, StringBuffer and StringBuilder in Java]]></title>
            <link>https://www.codingshuttle.com/blogs/a-complete-guide-to-string-string-buffer-and-string-builder-in-java</link>
            <guid>https://www.codingshuttle.com/blogs/a-complete-guide-to-string-string-buffer-and-string-builder-in-java</guid>
            <pubDate>Fri, 14 Feb 2025 19:43:15 GMT</pubDate>
            <description><![CDATA[This article explores Strings in Java, focusing on immutability, memory management, and performance. It also compares String, StringBuilder, and StringBuffer, highlighting their key differences in mutability and thread safety.]]></description>
            <content:encoded><![CDATA[<h2>Introduction:</h2><p><strong>String</strong> is a <strong>sequence of characters</strong>. In Java, the String class represents character strings. All string literals in Java programs, such as <strong>"abc"</strong>, are implemented as instances of this class. Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.</p><p>For example: <code>String str = "abc";</code></p><p>Is equivalent to:</p><p><code>char data[] = {'a', 'b', 'c'};</code></p><p><code>String str1 = new String(data);</code></p><h2><strong>String Creation and Initialization</strong>: How to create and store Java String</h2><p>There are <strong>two main ways</strong> to create and initialize a string:</p><ol><li><strong>Using String Literals (Static Memory)</strong></li><li><strong>Using the </strong><code><strong>new</strong></code><strong> Keyword (Heap Memory)</strong></li></ol><h3>1. Using String Literals:</h3><p><strong>Syntax:</strong> <code>&lt;String Class Type&gt; &lt;Obj or Variable name&gt; = "&lt;Variable value&gt;";</code></p><p>String Literal is any sequence of characters enclosed within <code>" "</code> double quotes. It is stored inside the <strong>String Pool (Static Memory)</strong>.</p><p><strong>Examples:</strong> <code>String str = "abc";</code></p><h3><strong>Advantages of String Literals:</strong></h3><ul><li>Memory optimization due to <strong>String Pool</strong>.</li><li>Strings are <strong>shared</strong>, avoiding unnecessary object creation.</li></ul><h3>2. Using the <code><strong>new</strong></code><strong> Keyword:</strong></h3><p><strong>Syntax:</strong> <code>&lt;String Class Type&gt; &lt;Obj or Variable name&gt; = &lt;'new' keyword&gt; &lt;String Constructor&gt;;</code></p><p>New objects are created by JVM for using of <code><strong>new</strong></code> keyword. It is stored inside the <strong>Heap memory</strong>.</p><p><strong>Examples:</strong> <code>String str2 = new String("Hello, World!");</code></p><h3><strong>Disadvantages of Using </strong><code><strong>new</strong></code><strong> Keyword:</strong></h3><ul><li><strong>More memory consumption</strong> as each <code>new</code> call creates a separate object.</li><li><strong>Less efficient</strong> compared to String literals when dealing with frequent string operations.</li></ul><h2><strong>String Pool and Interning</strong>: Memory Allocations:</h2><ul><li><strong>What is the String Pool?</strong><ul><li>The <strong>String Pool</strong> is a special memory area inside the <strong>Heap</strong> that stores <strong>string literals</strong> (<code>"Hello"</code>, <code>"Java"</code>, etc.).</li><li>It helps <strong>save memory</strong> by <strong>reusing</strong> existing string objects instead of creating new ones.</li></ul></li><li><strong>How Strings Are Stored in the Pool?</strong><ul><li>When a <strong>string literal</strong> (<code>String s = "Java";</code>) is created, Java <strong>checks the pool</strong>:<ul><li>If <strong>it exists</strong>, the reference is reused.</li><li>If <strong>it doesn’t exist</strong>, a <strong>new object is added</strong> to the pool.</li></ul></li><li>Strings created using <code>new String("Java")</code> are stored <strong>outside the pool</strong> in the Heap.</li></ul></li></ul><p><strong>Memory Efficiency</strong></p><ul><li><strong>Advantage</strong>: Saves memory by avoiding duplicate string objects.</li><li><strong>Best Practice</strong>: Use <strong>string literals</strong> (<code>"text"</code>) instead of <code>new String("text")</code>.</li></ul><h2><strong>String Immutability</strong>: Why are Strings immutable?</h2><p><strong>Immutable</strong> is a state/value of an object that can not be changed after creation. You can't change its value once you create any String object. That’s why Java Strings are immutable. Immutability provides security, memory efficiency, and thread safety. Performance benefits include hashcode caching and memory optimization in the String Pool.</p><pre><code class="language-java">public class StringInJava {

    public static void main(String[] args) {

        String str = "abc";
        str.concat("def");

        System.out.println(str);  //output "abd"
    }
}
</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_09_044600_b2468bcc6d.png" alt="String" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_09_044600_b2468bcc6d.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_09_044600_b2468bcc6d.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_09_044600_b2468bcc6d.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_09_044600_b2468bcc6d.png 1000w," sizes="100vw"><figcaption>String output</figcaption></figure><h3>Why Are Strings Immutable?</h3><ul><li><strong>String Pool Optimization:</strong> Enables <strong>memory reuse</strong>, reducing redundant object creation.</li><li><strong>Security:</strong> Prevents unauthorized modification in sensitive operations (e.g., passwords, URLs).</li><li><strong>Thread Safety:</strong> Multiple threads can <strong>share String objects</strong> safely without synchronization.</li><li><strong>Performance Boost:</strong> <strong>Hashcode caching</strong> improves efficiency in <strong>HashMap</strong> and <strong>HashSet</strong>.</li><li><strong>Prevents Unintentional Modifications:</strong> Ensures <strong>predictable behavior</strong> when used across different references.</li></ul><h2>Common String Methods:</h2><p>You can visit Oracle’s official documentary <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html">https://docs.oracle.com/javase/8/docs/api/java/lang/String.html</a></p><h2><strong>String Comparison</strong>:</h2><p><code><strong>equals(Object obj)</strong></code>: This is a case-sensitive comparison. If two string contents are equal then return true, otherwise return false.</p><pre><code class="language-java">public class StringInJava {

    public static void main(String[] args) {

        String str1 = "abc";
        String str2 = "Abc";
        String str3 = "abc";

        System.out.println("Comparison between str1 and str2 = "+str1.equals(str2));  // false
        System.out.println("Comparison between str1 and str3 = "+str1.equals(str3));  //true
    }
}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_09_050659_5a683a0452.png" alt="equals method" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_09_050659_5a683a0452.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_09_050659_5a683a0452.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_09_050659_5a683a0452.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_09_050659_5a683a0452.png 1000w," sizes="100vw"><figcaption>equals method output</figcaption></figure><ul><li><code><strong>compareTo(String anotherString)</strong></code>: Compares two strings lexicographically (dictionary order), considering case. It returns:<ul><li><code>0</code> if the strings are equal.</li><li>A negative value if the first string is lexicographically less.</li><li>A positive value if the first string is lexicographically greater.</li></ul></li></ul><pre><code class="language-java">public class StringInJava {

    public static void main(String[] args) {

        String str1 = "abc";
        String str2 = "abcd";
        String str3 = "abc";
        String str4 = "ab";

        System.out.println("Comparison between str1 and str2 = "+str1.compareTo(str2));
        System.out.println("Comparison between str1 and str3 = "+str1.compareTo(str3));
        System.out.println("Comparison between str3 and str4 = "+str3.compareTo(str4));
    }
}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_09_051137_5c99b82ac7.png" alt="compareTo method" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_09_051137_5c99b82ac7.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_09_051137_5c99b82ac7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_09_051137_5c99b82ac7.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_09_051137_5c99b82ac7.png 1000w," sizes="100vw"><figcaption>compareTo method output</figcaption></figure><p><code><strong>compareToIgnoreCase(String anotherString)</strong></code>: Similar as compareTo() and without case sensitive.</p><pre><code class="language-java">public class StringInJava {

    public static void main(String[] args) {

        String str1 = "abc";
        String str2 = "Abcd";
        String str3 = "Abc";
        String str4 = "ab";

        System.out.println("Comparison between str1 and str2 = "+str1.compareToIgnoreCase(str2));
        System.out.println("Comparison between str1 and str3 = "+str1.compareToIgnoreCase(str3));
        System.out.println("Comparison between str3 and str4 = "+str3.compareToIgnoreCase(str4));
    }
}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_09_051545_50f5441cd0.png" alt="compareToIgnoreCase method" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_09_051545_50f5441cd0.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_09_051545_50f5441cd0.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_09_051545_50f5441cd0.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_09_051545_50f5441cd0.png 1000w," sizes="100vw"><figcaption><code><strong>compareToIgnoreCase method output</strong></code></figcaption></figure><h2><strong>StringBuilder: (</strong><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html">Oracle_Docs_Jdk8_For_Inbuilt_Methods_Of_StringBuilder</a>)</h2><p>This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. A mutable sequence of characters. Instances of StringBuilder are not safe for use by multiple threads. If such synchronization is required then it is recommended that StringBuffer be used. Every string builder has a capacity. As long as the length of the character sequence contained in the string builder does not exceed the capacity, it is not necessary to allocate a new internal buffer. If the internal buffer overflows, it is automatically made larger.</p><pre><code class="language-java">public class StringInJava {

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");
        sb.append(" World"); // StringBuilder allows appending without creating new objects
        System.out.println(sb.toString()); // "Hello World"

    }
}

</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_09_052743_8e8dfd1016.png" alt="StringBuilder" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_09_052743_8e8dfd1016.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_09_052743_8e8dfd1016.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_09_052743_8e8dfd1016.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_09_052743_8e8dfd1016.png 1000w," sizes="100vw"><figcaption>StringBuilder output</figcaption></figure><h2><strong>StringBuffer</strong>: (<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html">Oracle_Docs_Jdk8_For_Inbuilt_Methods_Of_StringBuffer</a>)</h2><p>String buffers are safe for use by multiple threads. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls. Every string buffer has a capacity. As long as the length of the character sequence contained in the string buffer does not exceed the capacity, it is not necessary to allocate a new internal buffer array. If the internal buffer overflows, it is automatically made larger.</p><pre><code class="language-java">public class StringInJava {

    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("Hello");
        sb.append(" World"); // StringBuffer allows thread-safe appending
        System.out.println(sb.toString()); // "Hello World"

    }
}
</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_09_052943_cbee59a024.png" alt="StringBuffer" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_09_052943_cbee59a024.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_09_052943_cbee59a024.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_09_052943_cbee59a024.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_09_052943_cbee59a024.png 1000w," sizes="100vw"><figcaption>StringBuffer output</figcaption></figure><h2>Conclusion:</h2><p>This article highlights the differences between <strong>String</strong>, <strong>StringBuffer</strong>, and <strong>StringBuilder</strong> in Java. <strong>String</strong> is immutable and efficient in memory usage, while <strong>StringBuffer</strong> is thread-safe but slower due to synchronization. <strong>StringBuilder</strong> offers better performance in single-threaded environments as it is mutable and not synchronized.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Java</category>
            <category>String</category>
            <category>String Pool</category>
            <category>StringBuilder</category>
            <category>StringBuffer</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/8_52c3a534a6.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[@Controller vs @RestController in Spring Boot: Key Differences with Examples]]></title>
            <link>https://www.codingshuttle.com/blogs/difference-between-controller-and-rest-controller-in-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/difference-between-controller-and-rest-controller-in-spring-boot</guid>
            <pubDate>Fri, 14 Feb 2025 19:18:20 GMT</pubDate>
            <description><![CDATA[Learn the difference between @Controller and @RestController in Spring Boot with real examples, use cases, and beginner-friendly explanations. Master when and how to use each annotation to build web pages or RESTful APIs effectively.]]></description>
            <content:encoded><![CDATA[<p>If you are a beginner in Spring Boot, there is a high chance you might get confused between <code>@Controller</code> and <code>@RestController</code>. Because they sound similar right? And to be honest when I first started learning Spring Boot, I was confused too. But now, I clearly understand the difference between them.</p><p>So in this article, I’m going to explain the difference between <code>@Controller</code> and <code>@RestController</code>, so that the next time you see these annotations, you will have a clear idea in your mind. I have also included code snippets to help you understand better. So, let’s jump into it!</p><h2>Overview of @Controller</h2><p>The <code>@Controller</code> annotation is part of the Spring MVC framework and is used to mark a class as a web controller. It is typically used to handle HTTP requests and return views (e.g., HTML pages) or data to be rendered by a view resolver. This annotation is ideal for traditional web applications where the response is often a rendered webpage.</p><ul><li><strong>Purpose</strong>: Handles HTTP requests and returns a view or data to be processed by a view resolver.</li><li><strong>Response Type</strong>: Typically returns a <code>String</code> representing the name of a view (e.g., a JSP or Thymeleaf template) or a <code>ModelAndView</code> object.</li><li><strong>Use Case</strong>: Suited for applications that serve web pages or need to integrate with a view technology.</li><li><strong>Annotation Composition</strong>: <code>@Controller</code> is a specialization of the <code>@Component</code> annotation, enabling the class to be auto-detected by Spring’s component scanning.</li></ul><h3>Example of @Controller</h3><pre><code class="language-java">import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MyController {

    @GetMapping("/welcome")
    public String welcome(Model model) {
        model.addAttribute("message", "Welcome to Spring Boot!");
        return "welcome"; // Returns the name of the view (e.g., welcome.html)
    }
}</code></pre><p>In this example, the <code>@Controller</code> annotation marks the class as a web controller. The <code>welcome</code> method handles a GET request to <code>/welcome</code>, adds a message to the model, and returns the name of a view (<code>welcome</code>). Spring’s view resolver will map this to a template (e.g., <code>welcome.html</code>) for rendering.</p><h2>Overview of @RestController</h2><p>The <code>@RestController</code> annotation, introduced in Spring 4.0, is a specialized version of <code>@Controller</code> designed for RESTful web services. It combines <code>@Controller</code> and <code>@ResponseBody</code>, meaning that the return value of a method is automatically serialized into the HTTP response body (typically as JSON or XML) without requiring a view resolver.</p><ul><li><strong>Purpose</strong>: Handles HTTP requests and returns data directly in the response body, typically in JSON or XML format.</li><li><strong>Response Type</strong>: Returns objects that are serialized into JSON/XML by Spring’s <code>HttpMessageConverter</code>.</li><li><strong>Use Case</strong>: Ideal for building REST APIs where the client expects data rather than rendered views.</li><li><strong>Annotation Composition</strong>: <code>@RestController</code> is a convenience annotation that combines <code>@Controller</code> and <code>@ResponseBody</code>.</li></ul><h3>Example of @RestController</h3><pre><code class="language-java">import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyRestController {

    @GetMapping("/api/greeting")
    public String greeting() {
        return "Hello, Spring Boot!";
    }
}</code></pre><p>In this example, the <code>@RestController</code> annotation marks the class as a REST controller. The <code>greeting</code> method handles a GET request to <code>/api/greeting</code> and returns a <code>String</code> that is directly written to the HTTP response body as plain text or JSON (depending on the configuration).</p><h2>Key Differences Between @Controller and @RestController</h2><p>Here is a detailed comparison of <code>@Controller</code> and <code>@RestController</code> based on various aspects:</p><figure class="table"><table><thead><tr><th><strong>Aspect</strong></th><th><strong>@Controller</strong></th><th><strong>@RestController</strong></th></tr></thead><tbody><tr><td><strong>Purpose</strong></td><td>Used for traditional web applications to return views or templates.</td><td>Used for RESTful APIs to return data (e.g., JSON/XML) directly.</td></tr><tr><td><strong>Annotation Composition</strong></td><td>Only includes <code>@Controller</code> (a specialization of <code>@Component</code>).</td><td>Combines <code>@Controller</code> and <code>@ResponseBody</code>.</td></tr><tr><td><strong>Response Handling</strong></td><td>Returns view names or <code>ModelAndView</code> for rendering by a view resolver.</td><td>Returns objects serialized into the response body (e.g., JSON/XML).</td></tr><tr><td><strong>View Resolver</strong></td><td>Requires a view resolver to map view names to templates (e.g., Thymeleaf, JSP).</td><td>Does not use a view resolver; responses are serialized directly.</td></tr><tr><td><strong>Use Case</strong></td><td>Web applications with server-side rendering (e.g., serving HTML pages).</td><td>REST APIs for mobile apps, single-page applications (SPAs), or microservices.</td></tr><tr><td><strong>Method-Level Annotation</strong></td><td>Requires <code>@ResponseBody</code> to return data directly in the response body.</td><td><code>@ResponseBody</code> is implicit for all methods; no need to specify.</td></tr></tbody></table></figure><h2>When to Use @Controller vs. @RestController</h2><p><strong>Use </strong><code><strong>@Controller</strong></code>:</p><p>When I work on a Spring Boot project that needs to show HTML pages, I use <code>@Controller</code>. It’s perfect for traditional web apps where you want to return a full webpage instead of just data.</p><p>This annotation works well with template engines like Thymeleaf, JSP, or FreeMarker. I just return the name of the view (like an HTML file), and Spring Boot takes care of showing it to the user.</p><p>For example, if I’m building a website where users can browse a list of products, I’d use <code>@Controller</code> to handle the request and return a Thymeleaf page that displays the products nicely.</p><p><strong>Use </strong><code><strong>@RestController</strong></code>:</p><p>On the other hand, I use <code>@RestController</code> when I’m building REST APIs that send data like JSON or XML to the client.</p><p>What I like about <code>@RestController</code> is that it makes things easier because I don’t need to add <code>@ResponseBody</code> to every method. It automatically takes whatever I return (like an object) and converts it into a proper response, usually in JSON format.</p><p>For example, if I’m creating an API for a mobile app that needs user profile data, I would use <code>@RestController</code> to return that data directly as JSON.</p><h2>Combining @Controller and @RestController in a Single Application</h2><p>In some Spring Boot applications, you may need both <code>@Controller</code> and <code>@RestController</code>. For example:</p><ul><li>Use <code>@Controller</code> for serving web pages to users (e.g., a login page or dashboard).</li><li>Use <code>@RestController</code> for providing API endpoints that the frontend (e.g., a React or Angular app) consumes.</li></ul><h3>Example of Combined Usage</h3><pre><code class="language-java">import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Controller
class WebController {
    @GetMapping("/home")
    public String home(Model model) {
        model.addAttribute("title", "Home Page");
        return "home"; // Returns home.html
    }
}

@RestController
class ApiController {
    @GetMapping("/api/data")
    public String getData() {
        return "{\\"message\\": \\"API Data\\"}";
    }
}</code></pre><p>In this example, <code>WebController</code> serves a webpage, while <code>ApiController</code> provides a REST API endpoint.</p><h2>Conclusion</h2><p>In short, The <code>@Controller</code> is used to return view pages, while <code>@RestController</code> is used to return data, typically in JSON or XML format. It also includes <code>@ResponseBody</code> by default so you don’t need to add again where we use <code>@RestController</code> annotation. I hope you now have a clear picture of the difference between <code>@Controller</code> and <code>@RestController</code>, and the next time you see these annotations, you will have a proper understanding of what they do.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Spring Boot</category>
            <category>Difference Between @Controller And @Restcontroller</category>
            <category>Spring Boot Rest API</category>
            <category>Spring Boot Annotations</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Controller_vs_Rest_Controller_in_Spring_Boot_Key_Differences_with_Examples_f282f4a4a4.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Java Flow Control: A guide to understand the If-else and Loops in Java]]></title>
            <link>https://www.codingshuttle.com/blogs/java-flow-control</link>
            <guid>https://www.codingshuttle.com/blogs/java-flow-control</guid>
            <pubDate>Fri, 14 Feb 2025 08:48:18 GMT</pubDate>
            <description><![CDATA[This article provides an in-depth exploration of Java flow control statements, covering decision-making, looping, and branching mechanisms. With clear explanations, syntax examples, and practical applications, it serves as a valuable resource for both beginners and experienced developers aiming to enhance their Java programming skills.]]></description>
            <content:encoded><![CDATA[<h2>Introduction:</h2><p>In Java, flow control statements dictate the order in which instructions are executed, enabling developers to manage the program's execution path based on specific conditions or repetitions. These statements are fundamental for implementing your code's decision-making, looping, and branching mechanisms.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Flow_Control_e29f114889.png" alt="Flow Control.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Flow_Control_e29f114889.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Flow_Control_e29f114889.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Flow_Control_e29f114889.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Flow_Control_e29f114889.png 1000w," sizes="100vw"><figcaption>Flow Control</figcaption></figure><h2>1. Decision-Making Statements (Conditional Statements):</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Conditional_Statement_140c7c3294.png" alt="Conditional Statement.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Conditional_Statement_140c7c3294.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Conditional_Statement_140c7c3294.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Conditional_Statement_140c7c3294.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Conditional_Statement_140c7c3294.png 1000w," sizes="100vw"><figcaption>Conditional Statements</figcaption></figure><p>In Java, decision-making statements help to control the flow of execution based on certain conditions. These statements evaluate the expressions and execute the different code blocks depending on whether the conditions are true or false.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Condition_491e37fc1d.png" alt="Condition.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Condition_491e37fc1d.png 119w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Condition_491e37fc1d.png 380w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Condition_491e37fc1d.png 571w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Condition_491e37fc1d.png 761w," sizes="100vw"><figcaption>Condition</figcaption></figure><h3>a. <code>if</code> Statement:</h3><p>It evaluates a boolean expression; if true, executes the associated block of code.</p><pre><code class="language-java">public class FlowControlStatements {

    public static void main(String[] args) {
        
        boolean condition = true;
        
        if(condition) System.out.println("Hi");
    }

}
</code></pre><h3>b. <code><strong>if-else</strong></code><strong> Statement:</strong></h3><p>Provides an alternative path if the <code>if</code> condition evaluates to false.</p><pre><code class="language-java">public class FlowControlStatements {

    public static void main(String[] args) {

        boolean condition = false;

        if(condition) System.out.println("Hi");

        else System.out.println("Hello");
    }

}
</code></pre><h3>c. <code><strong>if-else-if</strong></code><strong> Ladder:</strong></h3><p>Chains multiple conditions; executes the block where the condition is true.</p><pre><code class="language-java">public class FlowControlStatements {

    public static void main(String[] args) {

        int condition = 9;

        if(condition &gt; 10) System.out.println("Yes! condition &gt; 10");

        else if (condition &gt; 0) System.out.println("Yes! condition &gt; 0");

        else System.out.println("Yes! condition &lt; 0");
    }

}
</code></pre><h3>d.<code>switch</code> Statement:</h3><p>It allows the selection among multiple options based on the value of an expression.</p><pre><code class="language-java">public class FlowControlStatements {

    public static void main(String[] args) {

        int condition = 1;

        switch (condition){
            case 1:
                System.out.println("condition = 1");
                break;
            case 2:
                System.out.println("condition = 2");
                break;
            default:
                System.out.println("condition &gt; 1 and condition &gt; 2");

        }
    }

}
</code></pre><p><strong>Ternary Operator:</strong> It is used to evaluate a test condition and executes a block of code based on the result of the condition. This operator replaces certain types of if-else statements.</p><p><strong>Syntax:&nbsp;</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Ternary_operator_3b24b81275.png" alt="Ternary operator.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Ternary_operator_3b24b81275.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Ternary_operator_3b24b81275.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Ternary_operator_3b24b81275.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Ternary_operator_3b24b81275.png 1000w," sizes="100vw"><figcaption>Ternary Operator</figcaption></figure><pre><code class="language-java">public class FlowControlStatements {


    int condition = 1;

    boolean TernaryOperation() {
        return condition == 1 ? true : false;
    }

    public static void main(String[] args) {

        FlowControlStatements obj = new FlowControlStatements();
        if(obj.TernaryOperation()) System.out.println("True");
        else System.out.println("False");
    }

}</code></pre><h2>2. Looping Statements (Iteration Statements):</h2><ol><li>Initialization Expression(s)</li><li>Test Expressions (Conditions)</li><li>Body of the Loop</li><li>Update Expressions</li></ol><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Looping_Statements_b260473afe.png" alt="Looping Statements.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Looping_Statements_b260473afe.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Looping_Statements_b260473afe.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Looping_Statements_b260473afe.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Looping_Statements_b260473afe.png 1000w," sizes="100vw"><figcaption>Looping</figcaption></figure><p>Looping statements in Java allow executing a code block multiple times until a specified condition is met. This helps in reducing redundancy and improving efficiency in programs.</p><h3>a.<code>for</code> Loop:</h3><p>The <strong>traditional </strong><code><strong>for</strong></code><strong> loop</strong> is used when we need <strong>explicit control</strong> over the loop index. It is useful for iterating over an array or a list where we may need to modify elements or access specific indices.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/For_loop_8f834aaa5c.png" alt="For loop.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_For_loop_8f834aaa5c.png 162w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_For_loop_8f834aaa5c.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_For_loop_8f834aaa5c.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_For_loop_8f834aaa5c.png 1000w," sizes="100vw"><figcaption>For loop</figcaption></figure><p><strong>Syntax:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/For_loop_Syntax_5e72d9c342.png" alt="For loop Syntax.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_For_loop_Syntax_5e72d9c342.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_For_loop_Syntax_5e72d9c342.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_For_loop_Syntax_5e72d9c342.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_For_loop_Syntax_5e72d9c342.png 1000w," sizes="100vw"><figcaption>For loop Syntax</figcaption></figure><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {

        int n = 10;

        for(int i=0; i&lt;n; i++){
            System.out.println(i);
        }

    }

}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_135243_ce209123e2.png" alt="For loop" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_135243_ce209123e2.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_135243_ce209123e2.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_135243_ce209123e2.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_135243_ce209123e2.png 1000w," sizes="100vw"><figcaption>For loop Output</figcaption></figure><h3>b. Enhanced <code>for</code> Loop (for-each):</h3><p>Introduced in Java 5, the <strong>for-each loop</strong> is a <strong>simplified</strong> way of iterating over arrays and collections. It <strong>does not require an index</strong> and is <strong>read-only</strong> (modifications to elements are not possible directly).</p><p><strong>Syntax:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/for_each_d39ffd7967.png" alt="for-each.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_for_each_d39ffd7967.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_for_each_d39ffd7967.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_for_each_d39ffd7967.png 750w," sizes="100vw"><figcaption>for-each loop</figcaption></figure><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {

        int[] numbers = {10, 20, 30, 40, 50};

        for (int num : numbers) {
            System.out.println(num);
        }


    }

}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_180252_666faa290d.png" alt="for-each" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_180252_666faa290d.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_180252_666faa290d.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_180252_666faa290d.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_180252_666faa290d.png 1000w," sizes="100vw"><figcaption>for-each output</figcaption></figure><h3>c. <code>while</code> Loop:</h3><p>The <strong>condition is checked first</strong> before executing the loop body. If the condition is <strong>false initially</strong>, the loop body <strong>will not execute even once</strong>. It is an <strong>entry-controlled loop</strong> (checks condition before execution).</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/While_loop_38fae583f1.png" alt="While loop.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_While_loop_38fae583f1.png 190w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_While_loop_38fae583f1.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_While_loop_38fae583f1.png 750w," sizes="100vw"><figcaption>while loop</figcaption></figure><p><strong>Syntax:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/While_loop_syntax_391989489f.png" alt="While loop syntax.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_While_loop_syntax_391989489f.png 123w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_While_loop_syntax_391989489f.png 395w," sizes="100vw"><figcaption>while loop syntax</figcaption></figure><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {

        int n = 10;
        int i = 0;

        while(i&lt;n){
            System.out.println(i);
            i++;

        }

    }</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_180910_6336a4c95e.png" alt="while loop" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_180910_6336a4c95e.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_180910_6336a4c95e.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_180910_6336a4c95e.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_180910_6336a4c95e.png 1000w," sizes="100vw"><figcaption>while loop output</figcaption></figure><h3>d. <code>do-while</code> Loop: (Executes Once Even if Condition is False)</h3><p>The <strong>loop body executes first</strong>, then the condition is checked. Ensures that the loop <strong>executes at least once</strong>, even if the condition is <strong>false</strong> initially. It is an <strong>exit-controlled loop</strong> (checks condition after execution).</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/do_while_loop_20472f511c.png" alt="do-while loop.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_do_while_loop_20472f511c.png 192w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_do_while_loop_20472f511c.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_do_while_loop_20472f511c.png 750w," sizes="100vw"><figcaption>do while loop output</figcaption></figure><p><strong>Syntax:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/do_while_syntax_c63a5871a6.png" alt="do-while syntax.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_do_while_syntax_c63a5871a6.png 123w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_do_while_syntax_c63a5871a6.png 395w," sizes="100vw"><figcaption>do-while loop syntax</figcaption></figure><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {

        int n = 10;
        int i = 10;

        do{

            System.out.println(i);
            i++;

        }while(i&lt;n);

    }

}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_182146_bea16b0267.png" alt="do-while loop" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_182146_bea16b0267.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_182146_bea16b0267.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_182146_bea16b0267.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_182146_bea16b0267.png 1000w," sizes="100vw"><figcaption>do-while loop output</figcaption></figure><blockquote><p><strong>Logical Operator: “AND” (&amp;&amp;), “OR”(||)</strong> and <strong>“NOT”(!)</strong> are ****used to perform logical operations. <strong>Relational Operator: “==”, “!=”, “&gt;”, “&lt;”, “&gt;=”, “&lt;=”,</strong> are ****used to check the relation between two operands.</p></blockquote><h2>3. Jump Statements (Branching Statements):</h2><p>Jump statements (also called <strong>branching statements</strong>) in Java <strong>control the flow</strong> of execution by transferring it to another part of the program.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Branching_Statements_332e8457e4.png" alt="Branching Statements.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Branching_Statements_332e8457e4.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Branching_Statements_332e8457e4.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Branching_Statements_332e8457e4.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Branching_Statements_332e8457e4.png 1000w," sizes="100vw"><figcaption>Branching</figcaption></figure><h3>a. <code>break</code> Statement (Exiting a Loop or Switch Case):</h3><p>The <code>break</code> statement <strong>terminates</strong> the loop. (<code>switch</code> statement immediately).</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/break_ea9f9d8165.png" alt="break .png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_break_ea9f9d8165.png 86w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_break_ea9f9d8165.png 276w," sizes="100vw"><figcaption>break</figcaption></figure><p><strong>Syntax:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/break_4cfdaed620.png" alt="break.png"><figcaption>break syntax</figcaption></figure><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {

        int n = 10;
        int i = 0;

        while(i&lt;n){

            if(i==5) break;
            else System.out.println("i != n");

            i++;
            System.out.println(i);

        }
        System.out.println("Loop ended");

    }

}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_184555_f95bd34a6f.png" alt="break" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_184555_f95bd34a6f.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_184555_f95bd34a6f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_184555_f95bd34a6f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_184555_f95bd34a6f.png 1000w," sizes="100vw"><figcaption>break output</figcaption></figure><h3>b. <code>continue</code> Statement <strong>(Skip Current Iteration)</strong>:</h3><p>The <code>continue</code> statement <strong>skips the current iteration and moves to the next iteration of the loop.</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/continue_3ec1e606d5.png" alt="continue .png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_continue_3ec1e606d5.png 109w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_continue_3ec1e606d5.png 351w," sizes="100vw"><figcaption>continue</figcaption></figure><p><strong>Syntax:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/continue_29623b46bf.png" alt="continue.png"><figcaption>continue syntax</figcaption></figure><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {


        for (int i = 1; i &lt;= 5; i++) {
            if (i % 2 == 0) {
                continue; // Skips even numbers
            }
            System.out.println("Number: " + i);
        }

    }

}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_190834_aeeebad7e1.png" alt="continue" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_190834_aeeebad7e1.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_190834_aeeebad7e1.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_190834_aeeebad7e1.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_190834_aeeebad7e1.png 1000w," sizes="100vw"><figcaption>continue output</figcaption></figure><h3>Labeled Blocks (Labeled Break and Labeled Continue):</h3><p>Labeled blocks in Java are <strong>advanced control flow techniques</strong> that allow breaking out of or continuing a specific loop when dealing with <strong>nested loops</strong>. A <strong>label</strong> in Java is an <strong>identifier</strong> followed by a colon (<code>:</code>) placed before a loop. It helps in controlling <strong>which loop should be affected</strong> by <code>break</code> or <code>continue</code>.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/labled_dc97dfd9b9.png" alt="labled .png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_labled_dc97dfd9b9.png 113w," sizes="100vw"><figcaption>labeled</figcaption></figure><p><strong>Labeled </strong><code><strong>continue</strong></code><strong> Statement:</strong> Used to skip the current iteration of a specific outer loop instead of the nearest one. Regular <code>continue</code> only affects the inner loop, but labeled <code>continue</code> affects the outer loop.</p><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {
        outerLoop:
        // Label for outer loop
        for (int i = 1; i &lt;= 3; i++) {
            for (int j = 1; j &lt;= 3; j++) {
                if (i == 2 &amp;&amp; j == 2) {
                    System.out.println("Skipping iteration for i=2");
                    continue outerLoop; // Skips rest of outer loop iteration
                }
                System.out.println("i: " + i + ", j: " + j);
            }
        }
        System.out.println("Loop finished!");
    }
}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_193234_b6b50728d3.png" alt="Labeled continue " srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_193234_b6b50728d3.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_193234_b6b50728d3.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_193234_b6b50728d3.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_193234_b6b50728d3.png 1000w," sizes="100vw"><figcaption><strong>Labeled </strong><code><strong>continue</strong></code><strong>&nbsp; output</strong></figcaption></figure><p><strong>Labeled </strong><code><strong>break</strong></code><strong> Statement:</strong> Used to terminate a specific outer loop instead of just the inner loop. Regular <code>break</code> only exits the nearest loop, but labeled <code>break</code> exits the labeled loop.</p><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {
        outerLoop: // Label for outer loop
        for (int i = 1; i &lt;= 3; i++) {
            for (int j = 1; j &lt;= 3; j++) {
                System.out.println("i: " + i + ", j: " + j);
                if (i == 2 &amp;&amp; j == 2) {
                    System.out.println("Breaking out of outer loop!");
                    break outerLoop; // Exits both loops
                }
            }
        }
        System.out.println("Loop finished!");
    }
}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_193625_a67754f84f.png" alt="Labeled break " srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_193625_a67754f84f.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_193625_a67754f84f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_193625_a67754f84f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_193625_a67754f84f.png 1000w," sizes="100vw"><figcaption><strong>Labeled </strong><code><strong>break</strong></code><strong>&nbsp;output</strong></figcaption></figure><h3>c. <code>return</code> Statement (Exit from a Method):</h3><p>The <code>return</code> statement <strong>terminates a method</strong> and optionally returns a value.</p><pre><code class="language-java">public class FlowControlStatements {

        public static int square(int num) {
            return num * num; // Returns square of number
        }

        public static void main(String[] args) {
            int result = square(5);
            System.out.println("Square: " + result);
        }
}
</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_192327_396ce3489e.png" alt="return Statement " srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_192327_396ce3489e.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_192327_396ce3489e.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_192327_396ce3489e.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_192327_396ce3489e.png 1000w," sizes="100vw"><figcaption><code>return</code> Statement &nbsp;output</figcaption></figure><h2>4. Exception Handling (Try-Catch-Finally):</h2><p><code><strong>try</strong></code><strong> Block:</strong> Contains code that may throw an exception.</p><p><code><strong>catch</strong></code><strong> Block:</strong> Handles specific exceptions that occur in the **<code>try</code>**block.</p><p><code><strong>finally</strong></code><strong> Block:</strong> Executes <strong>always</strong>, whether an exception occurs or not.</p><pre><code class="language-java">public class FlowControlStatements {
    public static void main(String[] args) {
        try {
            int result = 10 / 0; // Exception occurs
        } catch (ArithmeticException e) {
            System.out.println("Error: Cannot divide by zero!");
        } finally {
            System.out.println("Finally block always executes.");
        }
    }
}
</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_02_11_194430_943037d213.png" alt="try-catch-finally" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_02_11_194430_943037d213.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_02_11_194430_943037d213.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_02_11_194430_943037d213.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_02_11_194430_943037d213.png 1000w," sizes="100vw"><figcaption>try-catch-finally</figcaption></figure><h2>Conclusion:</h2><p>This article uses examples and syntax to explore Java flow control statements, including decision-making, looping, and branching mechanisms. Mastering these concepts enhances code efficiency, readability, and logical structuring in Java programming.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Java</category>
            <category>Control flow</category>
            <category>labeled looping</category>
            <category>looping</category>
            <category>Conditional</category>
            <category>Branching</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/java_flow_controle_3fda8b1641.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[CompletableFuture in Java 8: Async Made Easy (Full Guide)]]></title>
            <link>https://www.codingshuttle.com/blogs/a-comprehensive-guide-to-java-completable-future</link>
            <guid>https://www.codingshuttle.com/blogs/a-comprehensive-guide-to-java-completable-future</guid>
            <pubDate>Fri, 14 Feb 2025 08:22:09 GMT</pubDate>
            <description><![CDATA[Understand CompletableFuture with 10 real async patterns, error handling & best practices.
]]></description>
            <content:encoded><![CDATA[<h2>Introduction:</h2><p><strong>CompletableFuture</strong> is a class in Java's <code>java.util.concurrent</code> package that <strong>Java 8</strong> brought in. This class has an impact on asynchronous programming. It lets you create code that doesn't block, runs at the same time, and responds to events in a way that's easier to read and more effective. You can finish it yourself, or it can finish on its own when the work is done. It gives you a <strong>Supplier instance</strong> as <strong>a lambda expression that does the math and gives back the answer</strong>.</p><blockquote><p>In <strong>Synchronous programming</strong>, each job runs one after the other. This means the program waits for one job to end before it starts the next one.<br><br><strong>Asynchronous programming</strong> lets tasks run out of order, allowing multiple operations to happen at the same time or without waiting or blocking. This approach boosts productivity, makes systems more responsive, and helps them grow, especially in apps that need to handle many tasks at once. If you're creating web servers, mobile apps, or apps that work with lots of data, asynchronous programming helps you build systems that are effective, quick, and able to handle growth.</p></blockquote><h3><strong>Evolution of Asynchronous Programming in Java</strong></h3><ol><li><strong>Pre-Java 5 (Manual Threads &amp; Runnables)</strong><ul><li>Used <code>Thread</code> and <code>Runnable</code> to run tasks asynchronously.</li><li>Issues: Manual thread management, resource-heavy, no direct return values.</li></ul></li><li><strong>Java 5 (</strong><code><strong>Future</strong></code><strong> and </strong><code><strong>ExecutorService</strong></code><strong>)</strong><ul><li>Introduced <code>Future</code> for handling async tasks with <code>ExecutorService</code>.</li><li>Issues: <code>get()</code> blocks execution, no easy chaining, and poor exception handling.</li></ul></li><li><strong>Java 7 (Fork/Join Framework)</strong><ul><li>Optimized parallel execution for CPU-intensive tasks.</li><li>Issues: Complex API, not ideal for I/O operations.</li></ul></li><li><strong>Java 8 (</strong><code><strong>CompletableFuture</strong></code><strong>)</strong><ul><li>Fully non-blocking, supports method chaining (<code>thenApply()</code>, <code>thenCombine()</code>).</li><li>Built-in exception handling (<code>exceptionally()</code>, <code>handle()</code>).</li><li>Allows combining multiple async tasks efficiently.</li><li>Solves all previous limitations, making Java async programming more scalable.</li></ul></li></ol><blockquote><p><strong>Future in Java: Future&lt;T&gt;</strong> is an interface of java from Java's <code>java.util.concurrent</code> package which is used to handle asynchronous computations. It checks that the task is done properly or canceled.</p></blockquote><h2>Key Features of <code>Completable</code>:</h2><p><strong>Asynchronous Task Management:</strong> Allows tasks to run the main program independently without waiting or blocking.</p><p><strong>Flexible Completion Handling:</strong> Provides methods (e.g. <code>thenRun</code>, <code>thenApply</code>, and <code>thenAccept</code> ) to handle task results once completed.</p><p><strong>Exception Handling:</strong> Enables to manage exceptions (that occur at the time of asynchronous execution).</p><p><strong>Task Combination:</strong> Supports to combine multiple tasks using methods (e.g. <code>thenCombine</code> and <code>allOf</code>).</p><h2>Implementation of CompletableFuture in Java:</h2><p><code>CompletableFuture</code> allows for powerful, non-blocking asynchronous programming in Java. It provides:</p><ul><li><strong>Easy chaining of tasks</strong>.</li><li><strong>Exception handling</strong> for asynchronous operations.</li><li><strong>Handling multiple asynchronous tasks</strong> (using <code>allOf()</code>, <code>anyOf()</code>, and <code>thenCombine()</code>).</li><li><strong>Custom execution via Executors</strong>.</li><li><strong>Efficient parallel task execution</strong>.</li></ul><p>By leveraging <code>CompletableFuture</code>, Java developers can build more <strong>responsive</strong>, <strong>scalable</strong>, and <strong>efficient</strong> applications.</p><h3>1. Basic CompletableFuture Example using: <strong>Creating a CompletableFuture Class</strong></h3><p>Create an object/instance of the CompletableFuture class using <code>*supplyAsync*()</code> which is a supplier. This supplier provides a functional interface that only returns a value.</p><pre><code class="language-java">import java.util.concurrent.CompletableFuture;

public class LearnCompletableFutureClass {
    public static void main(String[] args) throws Exception{
        CompletableFuture&lt;String&gt; objOfCompletableFuture = CompletableFuture.supplyAsync(()-&gt;{
            return "Hello World";
        });
        System.out.println(objOfCompletableFuture.get());
    }
}</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_01_31_134045_440175aa93.png" alt="Basic CompletableFuture Example using: Creating a CompletableFuture Class" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_01_31_134045_440175aa93.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_01_31_134045_440175aa93.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_01_31_134045_440175aa93.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_01_31_134045_440175aa93.png 1000w," sizes="100vw"><figcaption>Basic CompletableFuture Example using: <strong>Creating a CompletableFuture Class</strong></figcaption></figure><h3>2. Chaining Tasks with CompletableFuture</h3><p>One of the most powerful features of <code>CompletableFuture</code> is <strong>chaining</strong> multiple tasks together. This is useful when you need to process results step-by-step or handle a series of dependent tasks.</p><pre><code class="language-java">import java.util.concurrent.CompletableFuture;

public class LearnCompletableFutureClass {
    public static void main(String[] args) throws Exception{
        CompletableFuture&lt;Integer&gt; objOfCompletableFuture = CompletableFuture.supplyAsync(()-&gt;{
            return 10;
        });

        // Asynchronous tasks

        objOfCompletableFuture.thenApplyAsync(result -&gt; {
            return result + 10;
        })
        .thenApplyAsync(result -&gt; {
            return result * 100;
        })
        .thenAccept(result -&gt; {
            System.out.println(result);
        });

    }
}</code></pre><ul><li><code><strong>thenApplyAsync()</strong></code>: Allows chaining additional computations.</li><li><code><strong>thenAccept()</strong></code>: Consumes the final result after all computations.</li></ul><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_01_31_163151_601cb779ee.png" alt="Chaining Tasks with CompletableFuture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_01_31_163151_601cb779ee.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_01_31_163151_601cb779ee.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_01_31_163151_601cb779ee.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_01_31_163151_601cb779ee.png 1000w," sizes="100vw"><figcaption>Chaining Tasks with CompletableFuture</figcaption></figure><h3>3. Handling Multiple CompletableFutures with <code>allOf()</code> , <code>anyOf()</code></h3><p>Multiple CompletableFuture tasks are executed parallelly. You can use <code><strong>anyOf()</strong></code> or <code><strong>allOf()</strong></code> to wait for the completion of multiple futures.</p><pre><code class="language-java">import java.util.concurrent.CompletableFuture;

public class LearnCompletableFutureClass {
    public static void main(String[] args) throws Exception{

        CompletableFuture&lt;Integer&gt; task1 = CompletableFuture.supplyAsync(()-&gt;{
            return 10;
        });
        CompletableFuture&lt;Integer&gt; task2 = CompletableFuture.supplyAsync(()-&gt;{
            return 20;
        });

        CompletableFuture&lt;Void&gt; result1 = CompletableFuture.allOf(task1,task2);

        result1.thenRun(()-&gt;{

            // this try-catch block for get() method
            try {
                System.out.println("Final result: " +(task1.get()+task2.get()));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }


        });

        CompletableFuture&lt;Object&gt; anyFuture = CompletableFuture.anyOf(task1, task2);

        anyFuture.thenAccept(result2 -&gt; {
            System.out.println("First completed result: " + result2);
        });

    }
}</code></pre><ul><li><code>allOf()</code>: Returns a new CompletableFuture when all tasks are done successfully otherwise if any of task fails then it throws an exception.</li><li><code><strong>anyOf()</strong></code>: Returns when any one of the provided futures completes.</li></ul><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_01_31_174743_a0a9273338.png" alt=" Handling Multiple CompletableFutures with allOf() , anyOf()" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_01_31_174743_a0a9273338.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_01_31_174743_a0a9273338.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_01_31_174743_a0a9273338.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_01_31_174743_a0a9273338.png 1000w," sizes="100vw"><figcaption>&nbsp;Handling Multiple CompletableFutures with <code>allOf()</code> , <code>anyOf()</code></figcaption></figure><h3>4. Handling Exceptions in CompletableFuture</h3><p>Exception handling in asynchronous tasks is easier with <code>CompletableFuture</code>. You can use methods like <code><strong>exceptionally()</strong></code>, <code><strong>handle()</strong></code>, or <code><strong>whenComplete()</strong></code> to deal with errors gracefully.</p><pre><code class="language-java">import java.util.concurrent.CompletableFuture;

public class LearnCompletableFutureClass {
    public static void main(String[] args) throws Exception{
        CompletableFuture&lt;Integer&gt; task2 = CompletableFuture.supplyAsync(()-&gt;{

                if(true) throw new RuntimeException("This is a Runtime exception");   // we need a true condition for throwing this exception

            return 20;   //mandatory for return type integer
        });

        task2.exceptionally(ex -&gt; {
            System.out.println("Error: " + ex.getMessage());
            return 0;  // Return a default value in case of error
        }).thenAccept(result -&gt; {
            System.out.println("Result: " + result);
        });

    }
}
</code></pre><ul><li><code><strong>exceptionally()</strong></code><strong> :</strong> Handles exceptions by providing a fallback value.</li><li><code><strong>handle()</strong></code><strong> :</strong> Handles both success and failure, allowing transformation of results.</li><li><code><strong>whenComplete()</strong></code><strong> :</strong> Executes a callback after completion without modifying the result.</li></ul><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_01_31_180301_e39656de87.png" alt="Handling Exceptions in CompletableFuture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_01_31_180301_e39656de87.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_01_31_180301_e39656de87.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_01_31_180301_e39656de87.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_01_31_180301_e39656de87.png 1000w," sizes="100vw"><figcaption>Handling Exceptions in CompletableFuture</figcaption></figure><h3>5. Combining Results from Multiple Futures Using <code>thenCombine()</code>,<code>thenCompose()</code> , <code>thenApply()</code>: <strong>Composing CompletableFuture</strong></h3><p>CompletableFuture can compose multiple asynchronous tasks.</p><pre><code class="language-java">import java.util.concurrent.CompletableFuture;

public class LearnCompletableFutureClass {
    public static void main(String[] args) throws Exception{
        CompletableFuture&lt;Integer&gt; task1 = CompletableFuture.supplyAsync(()-&gt;{
            return 20;
        });

        CompletableFuture&lt;Integer&gt; task2 = CompletableFuture.supplyAsync(()-&gt;{
            return 10;
        });

        task2.thenCombine(task1,(task2Result,task1Result)-&gt; task1Result + task2Result)
                .thenAccept(sum -&gt; System.out.println("Final result of the sum: "+sum));

        CompletableFuture&lt;Integer&gt; finalResult = task1.thenCompose(result1 -&gt;
                task2.thenApply(result2 -&gt; result1 * result2)
        );
        finalResult.thenAccept(mul-&gt; System.out.println("Final result of multiply: "+mul));

        task1.thenApply(result-&gt;result / 5).thenAccept(div-&gt; System.out.println("Final result of divide: "+div));

    }
}

</code></pre><ul><li><code>thenCombine()</code> : Combines results of two independent futures when both complete</li><li><code>thenCompose()</code> : Chains dependent futures, using the result of the first to create a new future.</li><li><code>thenApply()</code> : Transforms the result of a completed future into another value.</li></ul><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_01_31_183230_1b29338ced.png" alt="Combining Results from Multiple Futures Using thenCombine(),thenCompose() , thenApply(): Composing CompletableFuture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_01_31_183230_1b29338ced.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_01_31_183230_1b29338ced.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_01_31_183230_1b29338ced.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_01_31_183230_1b29338ced.png 1000w," sizes="100vw"><figcaption>Combining Results from Multiple Futures Using <code>thenCombine()</code>,<code>thenCompose()</code> , <code>thenApply()</code>: <strong>Composing CompletableFuture</strong></figcaption></figure><h3>6. Using <code>runAsync()</code> for Non-returning Tasks</h3><p>Use <code>runAsync()</code> for tasks that do not return a value, such as logging or background operations.</p><pre><code class="language-java">import java.util.concurrent.CompletableFuture;

public class LearnCompletableFutureClass {
    public static void main(String[] args) throws Exception{
        CompletableFuture&lt;Void&gt; future = CompletableFuture.runAsync(() -&gt; {
            System.out.println("Task executed in the background");
        });

    }
    future.join();
}
</code></pre><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_01_31_184155_0d7c2457ab.png" alt="Using runAsync() for Non-returning Tasks" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_01_31_184155_0d7c2457ab.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_01_31_184155_0d7c2457ab.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_01_31_184155_0d7c2457ab.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_01_31_184155_0d7c2457ab.png 1000w," sizes="100vw"><figcaption>Using <code>runAsync()</code> for Non-returning Tasks</figcaption></figure><h3>7. Using a Custom Executor with CompletableFuture</h3><p>To control the concurrency and manage the number of threads, you can provide a <strong>custom executor</strong> for asynchronous tasks.</p><pre><code class="language-java">import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class LearnCompletableFutureClass {
    public static void main(String[] args) throws Exception{
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        CompletableFuture&lt;Void&gt; future = CompletableFuture.runAsync(() -&gt; {
            System.out.println("Task executed using custom executor");
        }, executorService);

        future.join();
        executorService.shutdown();

    }
}
</code></pre><ul><li><code>ExecutorService</code> manages asynchronous tasks by providing thread pooling and lifecycle control. It simplifies concurrent task execution, improving performance and resource management.</li></ul><p><strong>Output:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2025_01_31_190152_71b5ca3caf.png" alt="Using a Custom Executor with CompletableFuture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2025_01_31_190152_71b5ca3caf.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2025_01_31_190152_71b5ca3caf.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2025_01_31_190152_71b5ca3caf.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Screenshot_2025_01_31_190152_71b5ca3caf.png 1000w," sizes="100vw"><figcaption>Using a Custom Executor with CompletableFuture</figcaption></figure><p><strong>Note:</strong> If you don't call <span style="background-color:rgba(135,131,120,.15);color:#EB5757;font-family:&quot;SFMono-Regular&quot;, Menlo, Consolas, &quot;PT Mono&quot;, &quot;Liberation Mono&quot;, Courier, monospace;">future.get()</span> or wait for the task to complete, the program might terminate before the background task finishes executing, depending on how the JVM handles the thread.</p><h2>Core Difference between Future and CompletableFuture:&nbsp;</h2><p><code>Future</code> is a simpler interface to asynchronous task management: with methods like get() that require the blocking of the current thread. Conversely, <code>CompletableFuture</code> is much more sophisticated and allows non-blocking operations for chaining tasks and better handling of exceptions. Use Future for straightforward, once-off tasks that can afford to block. Use CompletableFuture for more complex and chained non-blocking task workflows with good exception handling.</p><figure class="table"><table><tbody><tr><td style="width:206px;"><strong>Features</strong></td><td style="width:239px;"><strong>Future&lt;T&gt; In Java</strong></td><td style="width:345px;"><strong>CompletableFuture&lt;T&gt; In Java</strong></td></tr><tr><td style="width:206px;">Introduced</td><td style="width:239px;">In Java 5</td><td style="width:345px;">In Java 8</td></tr><tr><td style="width:206px;">Asynchronous Execution</td><td style="width:239px;">Yes, but limited</td><td style="width:345px;">Yes, but without any limitation</td></tr><tr><td style="width:206px;">Non-blocking Calls</td><td style="width:239px;">No, must use <code>get()</code> which blocks</td><td style="width:345px;">Yes, supports non-blocking methods like <code>thenApply()</code>, <code>thenAccept()</code></td></tr><tr><td style="width:206px;">Manual Completion</td><td style="width:239px;">No, only the computation can set the result</td><td style="width:345px;">Yes, can manually complete with <code>complete()</code> or <code>completeExceptionally()</code></td></tr><tr><td style="width:206px;">Chaining Operations</td><td style="width:239px;">No, requires additional handling</td><td style="width:345px;">Yes, allows method chaining (<code>thenApply()</code>, <code>thenCompose()</code>)</td></tr><tr><td style="width:206px;">Exception Handling</td><td style="width:239px;">No built-in exception handling</td><td style="width:345px;">Provides <code>exceptionally()</code>, <code>handle()</code> for error handling</td></tr><tr><td style="width:206px;">Multiple Futures Combination</td><td style="width:239px;">Not supported directly</td><td style="width:345px;">Supports combining multiple futures (<code>thenCombine()</code>, <code>allOf()</code>, <code>anyOf()</code>)</td></tr><tr><td style="width:206px;">Thread Pool</td><td style="width:239px;">Uses <code>ExecutorService.submit()</code></td><td style="width:345px;">Uses ForkJoinPool but can accept custom executors</td></tr></tbody></table></figure><h2>Conclusion:</h2><p>We explored the CompletableFuture in Java, &nbsp;and how it is designed to simplify asynchronous programming. Non-blocking execution allows for the chaining of tasks and handling concurrent tasks. The exception handling, timeout management, and task interruption offered by CompletableFuture are simple and make it suitable for writing scalable and fast applications. Top Ranking Keywords: CompletableFuture Java, Asynchronous programming Java, Non-blocking execution, Java task composition, Scalable applications.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Java</category>
            <category>Java 8 features</category>
            <category>Java Completable Future</category>
            <category>Non-blocking execution</category>
            <category>Java task composition</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/11_6278b14dd1.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 20 Microservice interview questions for Advanced Spring Boot Developers in 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/top-20-microservice-interview-questions-for-advanced-spring-boot-developers-in-2025</link>
            <guid>https://www.codingshuttle.com/blogs/top-20-microservice-interview-questions-for-advanced-spring-boot-developers-in-2025</guid>
            <pubDate>Fri, 31 Jan 2025 11:50:56 GMT</pubDate>
            <description><![CDATA[This blog covers the top 20 microservices interview questions, providing clear explanations and examples to help you prepare for your Spring Boot interviews. Topics range from the fundamentals of microservices architecture to advanced concepts like service discovery, API gateways, and distributed tracing.]]></description>
            <content:encoded><![CDATA[<p>If you’re preparing for spring boot interviews, chances are you’ll come across some questions about microservices. They’re a big deal in tech right now, and I can tell you from experience, they’re definitely something you want to have a handle on. I’ve worked with Spring Boot enough to know how tricky these concepts can feel at first, so I decided to put together a list of the top 20 microservices interview questions I’ve seen asked. I’ll keep things simple, with clear examples to make sure you really get it. That way, you’ll be able to walk into your interview feeling ready and confident. Let’s get into it!</p><h2>1. What is a microservice? How is it different from a monolith?</h2><p>A microservice is a small, independently deployable service that handles one specific job ike managing user profiles or processing payments and chats with others via APIs or messages. It’s like a team of specialists working together.</p><p><strong>Difference from a monolith:</strong> A monolith is one huge app where everything (UI, logic, database) is tangled up, making it tough to scale or update. Microservices break that into tiny, separate pieces, so each can grow or change on its own without messing with the others. It’s all about flexibility and speed!</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/monolith_vs_microservice_8abbc3ccc7.png" alt="Monolith vs Microservice" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_monolith_vs_microservice_8abbc3ccc7.png 192w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_monolith_vs_microservice_8abbc3ccc7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_monolith_vs_microservice_8abbc3ccc7.png 750w," sizes="100vw"><figcaption>Monolith vs Microservice</figcaption></figure><hr><h2>2. How do microservices communicate with each other?</h2><p>Microservices usually talk through REST APIs over HTTP for quick requests, or message queues like RabbitMQ or Kafka for async tasks—like sending a confirmation email. Sometimes, they use gRPC for fast, binary communication.</p><p>It’s like sending letters (REST), passing notes (messaging), or using a walkie-talkie (gRPC)—each method fits different needs, and you add security (like SSL) to keep it safe.</p><h2>3. What is service discovery, and why do we need it?</h2><p><strong>Service discovery</strong> is a mechanism that allows microservices to <strong>automatically register themselves</strong> and <strong>locate other services</strong> in the system.</p><p>Service discovery is like a digital address book. With tons of microservices popping up or moving around, it helps them find each other’s current IP and port without you manually updating lists.</p><p>We need it because hardcoding addresses in a dynamic cloud setup is a headache—tools like Eureka or Consul make it automatic and stress-free.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/service_discovery_92db8531e3.png" alt="service discovery" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_service_discovery_92db8531e3.png 217w," sizes="100vw"><figcaption>Service Discovery</figcaption></figure><h2>4. What is the role of Spring Cloud in microservices?</h2><p>Spring Cloud is a set of tools and frameworks built on top of Spring Boot, designed specifically to solve common challenges in building and managing <strong>distributed microservices systems</strong>. These challenges include configuration management, service discovery, load balancing, routing, fault tolerance, and more.</p><p><strong>How is Spring Cloud helpful :</strong></p><p>When you move from a monolithic application to microservices, things get complicated—services need to find each other, handle failure gracefully, share configuration, and route requests properly. Spring Cloud simplifies these problems by offering out-of-the-box solutions, so developers don’t have to reinvent the wheel.</p><p><strong>Role of Spring Cloud in microservices</strong></p><p>Spring Cloud is like your trusty sidekick for microservices with Spring Boot. It brings tools like:</p><ul><li><strong>Eureka</strong> for service discovery</li><li><strong>Spring Cloud Config</strong> for centralized configuration</li><li><strong>Spring Cloud Gateway</strong> for intelligent routing</li><li><strong>Resilience4j</strong> for fault tolerance and circuit breaking</li><li><strong>Sleuth + Zipkin</strong> for distributed tracing and monitoring</li></ul><p>It is like your trusty sidekick for microservices with Spring Boot. It brings tools like Eureka for finding services, Spring Cloud Gateway for routing, Spring Cloud Config for settings, and Resilience4j for circuit breaking.</p><p>It’s a one-stop shop that speeds up building robust, scalable microservices—making your life a lot easier!</p><h2>5. How do you handle configuration in microservices?</h2><p>In a microservices architecture, each service is independent and often runs in different environments (dev, test, staging, prod). Hardcoding configuration like database URLs, API keys, or feature flags into code leads to security risks and poor scalability. That's why <strong>externalizing and managing configuration</strong> properly is essential.</p><p><strong>Ways to manage configuration in microservices:</strong></p><ol><li><strong>Spring Cloud Config Server</strong> is commonly used to handle configuration centrally. It allows you to store all your service configs in one place (like a Git repo), and microservices can fetch their settings at startup.</li><li>You can also define environment-specific properties using <strong>profiles</strong> in <code>application.yml</code> or <code>application-dev.yml</code>, <code>application-prod.yml</code>, etc.</li><li>For sensitive values like passwords or secret keys, it’s a good practice to use <strong>environment variables</strong>, or integrate with <strong>vaults</strong> (e.g., HashiCorp Vault, AWS Secrets Manager).</li><li>When configs change, use the <code><strong>/actuator/refresh</strong></code> endpoint (with Spring Cloud Bus if needed) to update live services <strong>without restarting</strong> them.</li></ol><h2>6. What is an API Gateway, and why is it important?</h2><p>An <strong>API Gateway</strong> acts as the <strong>single entry point</strong> for all client requests to your microservices system. Instead of calling each service directly, clients send requests to the gateway, which then routes them to the appropriate backend service.</p><p><strong>Why is it important?</strong></p><p>In a microservices architecture, exposing each service directly to clients leads to:</p><ul><li>Complex client-side logic</li><li>Security vulnerabilities</li><li>Tight coupling between clients and services</li></ul><p><strong>Key responsibilities of an API Gateway:</strong></p><ol><li><strong>Routing</strong> – Directs client requests to the appropriate microservice</li><li><strong>Security</strong> – Handles authentication/authorization (e.g., JWT validation)</li><li><strong>Rate limiting</strong> – Prevents abuse with throttling or quotas</li><li><strong>Load balancing</strong> – Distributes traffic efficiently</li><li><strong>Logging &amp; Monitoring</strong> – Captures request/response data</li><li><strong>Request transformation</strong> – Modifies headers, payloads, or paths before forwarding</li><li><strong>Hiding internal structure</strong> – Keeps service URLs hidden from the public</li></ol><h2>7. How do you implement security in microservices?</h2><p><strong>Security in microservices is layered</strong>—you need to protect services from unauthorized access while still enabling smooth communication between them.</p><p>Here’s how I usually implement it:</p><h3>1. <strong>Authentication with JWT</strong></h3><p>I use <strong>Spring Security</strong> with <strong>JWT (JSON Web Tokens)</strong> to authenticate users. After a successful login, the authentication server generates a JWT, which clients send in the <code>Authorization</code> header for every request.</p><p>Example:</p><p><strong>Client → API Gateway → Auth Server → Generates JWT</strong></p><pre><code class="language-java">java
CopyEdit
// Filter to validate JWT on every request
public class JwtAuthFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        if (token != null &amp;&amp; token.startsWith("Bearer ")) {
            String jwt = token.substring(7);
            // validate JWT and set authentication in context
        }
        chain.doFilter(request, response);
    }
}</code></pre><h3>2. <strong>Authorization per service (Role-based Access)</strong></h3><p>Each microservice has its own <strong>Spring Security config</strong>, so I can define what roles can access which endpoints.</p><pre><code class="language-java">java
CopyEdit
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .anyRequest().authenticated();
    }
}</code></pre><h3>3. <strong>Secure Gateway with Authentication Check</strong></h3><p>The <strong>API Gateway</strong> is the first point of contact—it validates the JWT before forwarding the request. If the token is invalid, the request is blocked.</p><h3>4. <strong>Other Best Practices</strong></h3><p>it is essential to <strong>enable HTTPS</strong> to ensure all communication between clients and services is encrypted and secure. Sensitive information like secret keys, API tokens, or credentials should never be hardcoded; instead, they should be managed using <strong>environment variables</strong> or integrated <strong>secrets managers</strong> like AWS Secrets Manager or HashiCorp Vault. To maintain proper isolation and security between services, avoid passing client JWTs directly—use <strong>internal service credentials</strong> for inter-service communication when necessary. Additionally, always implement a <strong>secure refresh token mechanism</strong> to allow users to maintain their session without needing to log in repeatedly, while still keeping the system protected from token reuse or theft.</p><h2>8. What is circuit breaking, and how does it help?</h2><p>A Circuit Breaker prevents cascading failures in Microservices by temporarily stopping calls to a failing service. If failures exceed a threshold, it "opens," blocking requests. After a cooldown, it moves to a&nbsp;<strong>half-open</strong>&nbsp;state to test if recovery is possible. If successful, it&nbsp;<strong>closes</strong>&nbsp;and resumes normal operation.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/circuit_breaking_1713fe06e4.png" alt="circuit breaking" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_circuit_breaking_1713fe06e4.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_circuit_breaking_1713fe06e4.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_circuit_breaking_1713fe06e4.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_circuit_breaking_1713fe06e4.png 1000w," sizes="100vw"><figcaption>Circuit Breaking</figcaption></figure><p><strong>Example:</strong></p><p>If the "Payments" service is down, the "Orders" service can skip payment processing and notify the user instead of waiting indefinitely.</p><p><strong>Implementation:</strong>&nbsp;Can be implemented using&nbsp;<strong>Resilience4j</strong>&nbsp;with Spring Boot to configure failure thresholds and recovery log</p><h2>9. Explain the role of Eureka in a Spring Boot microservice architecture.</h2><p>Eureka is my go-to service registry. Services check in with it to say they’re alive, and others look it up to find them—no need for hardcoded URLs.</p><p>It’s dynamic and flexible, making it easy to scale or replace services on the fly—love that adaptability!</p><h2>10. How can you achieve load balancing in microservices?</h2><p>To distribute traffic evenly across multiple instances of a service, I use <strong>Spring Cloud LoadBalancer</strong>, or in older setups, <strong>Netflix Ribbon</strong>. These tools automatically pick the best available instance using strategies like round-robin or random selection.</p><p>Think of it like a <strong>smart waiter</strong> who guides incoming guests (requests) to available tables (service instances), ensuring that no single table gets overcrowded. This helps improve performance, avoids bottlenecks, and keeps your services healthy under load.</p><h2>11. What are some common challenges in a microservices architecture?</h2><p>Working with microservices brings flexibility, but it also introduces a set of challenges. Some key ones I’ve faced include:</p><ul><li><strong>Maintaining data consistency</strong> across services</li><li><strong>Managing inter-service dependencies</strong></li><li><strong>Dealing with network latency and timeouts</strong></li><li><strong>Handling distributed logging and monitoring</strong></li><li><strong>Coordinating deployment and versioning across teams</strong></li></ul><p>It’s a bit like <strong>herding cats</strong>—every service wants to do its own thing. But with the help of tools like <strong>centralized logging</strong>, <strong>distributed tracing</strong>, and <strong>container orchestration</strong>, it becomes manageable and even enjoyable.</p><h2>12. How do you manage logging across multiple microservices?</h2><p>To keep logs organized and useful across services, I use <strong>SLF4J with Logback</strong> for structured logging, and then forward logs to a centralized system like the <strong>ELK Stack (Elasticsearch, Logstash, Kibana)</strong> or <strong>Graylog</strong>.</p><p>I also add <strong>correlation IDs</strong> to each request, which makes it easy to trace a single transaction as it flows across multiple services.</p><p>It’s like keeping a <strong>shared journal</strong>, where every service writes its part of the story—making it far easier to debug and understand what's happening end-to-end.</p><h2>13. What is distributed tracing?</h2><p><strong>Distributed tracing</strong> helps track a single request as it flows through multiple microservices. It captures the full journey—including which services were called, how long each step took, and where any delays or errors occurred.</p><p>Tools like <strong>Zipkin</strong> and <strong>Jaeger</strong> make this visual by showing timelines and service maps.</p><p>It’s like having a <strong>GPS for your backend</strong>—you can instantly spot where a request slowed down or failed, which is super helpful for debugging and performance tuning.</p><h2>14. How do microservices share data?</h2><p>Microservices <strong>don’t share a common database</strong>—each one manages its own data to maintain independence and loose coupling. When they need to exchange information, they communicate through <strong>REST APIs</strong>, <strong>GraphQL</strong>, or <strong>message queues</strong> like RabbitMQ or Kafka.</p><p>It’s kind of like each microservice keeps its own <strong>private notebook</strong>, but when needed, it <strong>passes a note</strong> to another one to share updates. This approach keeps services isolated yet connected.</p><h2>15. What is eventual consistency?</h2><p><strong>Eventual consistency</strong> means that when data is updated in one service, it may take some time before that change is reflected across other services. Instead of syncing immediately, the system <strong>eventually becomes consistent</strong>, usually through <strong>event-driven communication</strong>.</p><p>For example, when an order is placed, the inventory service may update a little later through an event.</p><p>It’s a <strong>trade-off</strong> between speed and accuracy—but works well when real-time syncing isn’t critical, and system <strong>availability</strong> is more important.</p><h2>16. How do you test microservices?</h2><p>I use a <strong>multi-layered testing approach</strong> to ensure my microservices are reliable:</p><ol><li><strong>Unit tests</strong> with <strong>JUnit</strong> and <strong>Mockito</strong> to test business logic in isolation</li><li><strong>Integration tests</strong> to verify communication with components like databases or other services</li><li><strong>Contract tests</strong> using <strong>Spring Cloud Contract</strong> to ensure services agree on the request/response formats</li><li><strong>End-to-end (E2E) tests</strong> with tools like <strong>Postman</strong>, <strong>RestAssured</strong>, or <strong>Selenium</strong> to simulate real-world usage</li></ol><p>It’s like testing a recipe <strong>at every step</strong>—from ingredients to the final dish—making sure the whole meal turns out just right!</p><h2>17. What is a saga pattern in microservices?</h2><p>The <strong>saga pattern</strong> is a way to manage <strong>distributed transactions</strong> across multiple microservices. Instead of relying on a traditional database transaction, it breaks the process into smaller steps, where <strong>each service performs a local transaction and publishes an event</strong>.</p><p>If something goes wrong mid-way (like payment failing after booking), it <strong>triggers compensating actions</strong> (like canceling the booking) to keep the system consistent.</p><p>There are two ways to implement sagas:</p><ul><li><strong>Choreography</strong> – services react to each other’s events (no central brain)</li><li><strong>Orchestration</strong> – a <strong>central coordinator</strong> tells each service what to do next</li></ul><p>It’s like booking a trip: if the hotel’s unavailable, you cancel the flight and refund the payment—<strong>graceful rollback</strong> in action.</p><h2>18. How do you version your APIs in microservices?</h2><p>API versioning helps you update services <strong>without breaking existing clients</strong>. I usually version using the <strong>URL path</strong> (e.g., <code>/v1/users</code>) or via <strong>custom request headers</strong>.</p><p><strong>Example using URL versioning:</strong></p><pre><code class="language-java">@GetMapping("/v1/users")
public List&lt;UserDTO&gt; getUsers() {
    return userService.getAllUsers();
}</code></pre><p>This ensures <strong>backward compatibility</strong>—so clients using older versions still work while newer ones enjoy the updated features.</p><p>It’s like updating a <strong>cookbook</strong> with new versions of recipes, but still keeping the originals handy for loyal fans.</p><h2>19. What is the difference between orchestration and choreography in microservices?</h2><p>When microservices need to collaborate on a business process—like order placement, payment, and shipping—they can coordinate in two styles: <strong>orchestration</strong> and <strong>choreography</strong>.</p><ul><li><strong>Orchestration</strong> means one service (or a central coordinator) takes charge, telling each microservice what to do and when—like a <strong>conductor leading an orchestra</strong>. This approach is easier to manage in complex workflows but introduces tight control.</li><li><strong>Choreography</strong>, on the other hand, lets each service act <strong>independently</strong> by listening to and reacting to events. No central authority—just services dancing in sync to the beat of messages. It’s more <strong>loosely coupled</strong>, like a <strong>jazz band improvising together</strong>.</li></ul><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Orchestration_vs_Choreography_97e495046f.png" alt="Orchestration vs Choreography" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Orchestration_vs_Choreography_97e495046f.png 234w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Orchestration_vs_Choreography_97e495046f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Orchestration_vs_Choreography_97e495046f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Orchestration_vs_Choreography_97e495046f.png 1000w," sizes="100vw"><figcaption>Orchestration vs Choreography</figcaption></figure><p>I choose between the two depending on complexity: <strong>Orchestration</strong> offers more control, while <strong>choreography</strong> gives more flexibility and scalability. Both have their charm—and knowing when to use which is key to building elegant distributed systems.</p><h2>20. How do you deploy microservices in production?</h2><p>Deploying microservices at scale is all about <strong>automation, containerization, and observability</strong>.</p><p>I start by using <strong>Docker</strong> to package each microservice with its dependencies, ensuring it runs the same everywhere—from dev to prod. Then, I rely on <strong>Kubernetes</strong> to orchestrate these containers: it handles scaling, service discovery, self-healing, and rolling updates like a pro.</p><p>To automate the whole delivery process, I use <strong>CI/CD pipelines</strong> with tools like <strong>Jenkins, GitHub Actions, or GitLab CI</strong>, which make testing and deployment seamless. For observability, I integrate <strong>Prometheus</strong> and <strong>Grafana</strong> for metrics, and tools like <strong>ELK or Loki</strong> for centralized logging.</p><p>It’s like managing a <strong>fleet of food trucks</strong>—each running independently, but all part of a coordinated system that scales smoothly, stays updated, and gets monitored in real-time.</p><h2>Conclusion</h2><p>Finally we have covered a lot for from the <strong>fundamentals of microservices</strong> to <strong>advanced deployment and design patterns</strong>. These 20 microservice questions are your key to nailing that 2025 interview as an advanced Spring Boot developer. Also these <strong>interview questions</strong> are more than just Q&amp;A, they're your cheat sheet to mastering microservices in <strong>Spring Boot</strong>. Whether you're preparing for a <strong>2025 job interview</strong>, building real-world projects, or improving your backend architecture, this guide gives you the clarity and confidence about microservices.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Microservices</category>
            <category>Microservices Interview Questions</category>
            <category>Spring Boot Interview Questions</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/12_16618576d5.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 10 Must-Know Spring Boot Concepts for Java Developers]]></title>
            <link>https://www.codingshuttle.com/blogs/top-10-must-know-spring-boot-concepts-for-java-developers</link>
            <guid>https://www.codingshuttle.com/blogs/top-10-must-know-spring-boot-concepts-for-java-developers</guid>
            <pubDate>Fri, 31 Jan 2025 11:37:29 GMT</pubDate>
            <description><![CDATA[Want to become a Java Developer? Here are the top 10 Spring Boot concepts you must know in 2025.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p>If you're just starting out with <strong>Spring Boot</strong>, you might feel like there’s a lot to take in especially because it’s such a powerful tool for building Java applications. But don’t worry, I’m here to walk you through some of the key concepts you should definitely get familiar with. Think of this as the “Spring Boot essentials” that you’ll want under your belt, whether you're just beginning or have been working with it for a little while.</p><h2>1. <strong>Spring Boot Starter Projects</strong></h2><p>One of the first things that will probably blow your mind when working with Spring Boot is <strong>starter projects</strong>. They’re like pre-packaged templates that Spring Boot provides for common app setups. It’s like a shortcut. For example, if you want to create a web app, you can just pull in <code>spring-boot-starter-web</code>, and <i>boom</i> you get everything set up, including Spring MVC, Tomcat, and Jackson (the JSON library). No need to manually configure those things one by one. You save time, and you get a reliable, working setup right away.</p><h2>2. <strong>Auto-Configuration</strong></h2><p>This is one of Spring Boot’s coolest features. <strong>Auto-configuration</strong> means that Spring Boot will automatically configure your application based on the libraries you’ve added to your project. So, let’s say you add <code>spring-boot-starter-data-jpa</code> to your project for database interactions. Spring Boot will automatically configure Hibernate, JPA, and even data source connections without you lifting a finger. It’s like Spring Boot is looking at your dependencies and thinking, "Oh, you need this? I’ve got you covered." That’s one of the reasons why Spring Boot speeds up development so much.</p><h2>3. <strong>Embedded Servers</strong></h2><p>So, if you’ve worked with Java in the past, you probably remember the whole hassle of setting up an external server, like Tomcat, right? You had to install it, configure it, and get everything just right before even running your app. Well, Spring Boot makes all of that way simpler with its <strong>embedded servers</strong>. Basically, Spring Boot comes with a server built right into the framework—Tomcat, Jetty, or whatever you prefer—so you don’t need to bother with setting up anything externally. You just run your application directly from the command line, and the server fires up automatically. This is a game-changer because it makes your life easier and cuts down on all the extra steps when you’re just trying to get your app up and running.</p><h2>4. <strong>Spring Boot Annotations</strong></h2><p>If you’ve started using Spring Boot, you’ve probably noticed that annotations are everywhere and for good reason. They make things way easier. Let me break down a few that you’ll use all the time:</p><ul><li><code><strong>@SpringBootApplication</strong></code>: Think of this one as your app's main entry point. It’s the big, important annotation that marks the class where everything starts. It’s kind of like a shortcut because it combines a few other important annotations for you (like <code>@Configuration</code>, <code>@EnableAutoConfiguration</code>, and <code>@ComponentScan</code>).</li><li><code><strong>@RestController</strong></code>: If you’re building a REST API, this one’s essential. It combines <code>@Controller</code> and <code>@ResponseBody</code>, making it easy to handle web requests and automatically send responses in various formats like JSON, XML, or even custom formats, depending on the request. This eliminates a lot of the boilerplate code you’d otherwise need to handle different response types.</li><li><code><strong>@Autowired</strong></code>: This one is a huge time-saver. It’s all about dependency injection basically, it allows Spring Boot to automatically wire up your beans. Instead of having to manually set things up yourself, Spring Boot does the heavy lifting, so your code stays cleaner and more maintainable.</li></ul><p>Once you get comfortable with these, you’ll realize just how much they streamline the development process. You won’t have to worry about a ton of configuration, and your code will stay neat and easy to follow.</p><h2>5. <strong>Application Properties</strong></h2><p>Configuring your Spring Boot app is usually done in <strong>application.properties</strong> (or <strong>application.yml</strong>) files. This is where you’ll set things like the database URL, logging levels, and server ports.</p><p>For instance, you might have something like this to configure your database:</p><pre><code class="language-java">spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=secret
server.port=8080
</code></pre><p>It’s a pretty straightforward way to externalize your configuration. Plus, Spring Boot makes it easy to have different properties for different environments—like dev, test, and prod—just by creating different profiles.</p><h2>6. <strong>Spring Boot Actuator</strong></h2><p>Once your app is up and running in production, you’ll want to know how it’s doing. That’s where <strong>Spring Boot Actuator</strong> comes in. It’s a set of tools that helps you monitor your app’s health, performance, and various metrics. For example, you can check the <code>/actuator/health</code> endpoint to see if your app is running smoothly, or <code>/actuator/metrics</code> to get a look at things like memory usage and request counts.</p><p>It’s a lifesaver when you need to keep an eye on your app in production without setting up tons of extra monitoring tools.</p><h2>7. <strong>Spring Data JPA</strong></h2><p>If you're working with databases, you need to know about <strong>Spring Data JPA</strong>. This library helps you interact with your database using JPA (Java Persistence API) and makes life a lot easier. It takes care of all the boring CRUD (Create, Read, Update, Delete) operations for you. Just create an interface that extends <code>JpaRepository</code>, and Spring Boot will automatically implement it for you.</p><p>Here’s an example:</p><pre><code class="language-java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {
    List&lt;User&gt; findByLastName(String lastName);
}
</code></pre><p>The best part? You don’t have to write any implementation code. Spring Boot does all that under the hood.</p><h2>8. <strong>Spring Security</strong></h2><p>Security is always a top priority in backend development. <strong>Spring Security</strong> is Spring’s framework for handling authentication and authorization. It allows you to secure your application with minimal effort. You can set up authentication methods, restrict access to certain parts of your app, and even integrate with things like JWT for stateless authentication.</p><p>While it may seem a bit overwhelming at first, once you get a feel for it, Spring Security will become an essential tool for any project.</p><h2>9. <strong>Spring Boot DevTools</strong></h2><p>Want to speed up your development process? <strong>Spring Boot DevTools</strong> is here to help. It comes with features like <strong>automatic restarts</strong> and <strong>live reload</strong>—which means when you make changes to your code, the app automatically restarts, so you don’t have to manually restart it yourself.</p><p>It’s a small thing, but it can make a big difference in your workflow.</p><h2>10. <strong>Testing in Spring Boot</strong></h2><p>Testing is one of those things that you can’t skip if you want a solid app. With Spring Boot, it’s pretty easy to get started. For full integration tests, you’ve got <code>@SpringBootTest</code>. But let’s say you just need to test a specific part, like your web controllers or repositories—use <code>@WebMvcTest</code> or <code>@DataJpaTest</code>.</p><p>What I love is how much Spring Boot takes care of for you. It sets up a lot of the testing environment, so you don’t have to waste time on all that boilerplate. You can just focus on writing the tests that actually matter to your app.</p><h2>Conclusion</h2><p>Once you get a good grip on these Spring Boot concepts, you'll start noticing how much smoother your development process becomes. They’re the stuff that really makes building applications easier, faster, and more manageable. Don’t stress about knowing everything perfectly from the start—just keep playing around with the features and practicing. Over time, you’ll get more comfortable with it all, and before long, it’ll just feel like part of your regular workflow.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring</category>
            <category>Spring Boot</category>
            <category>Spring Boot Concepts</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/top_10_spring_boot_concetps_b99e389953.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 6 Spring Boot Annotations Every Spring Boot Developer Need to Know in 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/top-6-spring-boot-annotations-you-need-to-know-in-2025</link>
            <guid>https://www.codingshuttle.com/blogs/top-6-spring-boot-annotations-you-need-to-know-in-2025</guid>
            <pubDate>Fri, 31 Jan 2025 11:25:35 GMT</pubDate>
            <description><![CDATA[In this blog I have listed six essential Spring Boot annotations every developer should know in 2025. It covers key annotations like @SpringBootApplication, @RestController, and @Async and many more, helping you streamline development and improve application efficiency.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p>What makes Spring Boot such a favorite among developers? For me, it’s how it simplifies the whole process. You don’t have to wrestle with a ton of configuration or waste time on repetitive tasks it just works, and it lets you focus on the actual coding. But honestly, what really stands out are the annotations. They save so much time by cutting out unnecessary boilerplate code and letting you zero in on what matters most.</p><p>In this blog, I’ll share six Spring Boot annotations that I think are absolute must-knows as we head into 2025. Let’s get started!</p><h2>1. @SpringBootApplication</h2><h3><strong>What It Does:</strong></h3><p>The <code>@SpringBootApplication</code> annotation is the backbone of any Spring Boot application. It's essentially a combination of three crucial annotations: <code>@Configuration</code>, <code>@EnableAutoConfiguration</code>, and <code>@ComponentScan</code>.</p><ul><li><strong>@Configuration</strong> tells Spring that this class contains bean definitions.</li><li><strong>@EnableAutoConfiguration</strong> enables Spring Boot's auto-configuration magic, automatically setting up the beans based on the project's dependencies.</li><li><strong>@ComponentScan</strong> makes Spring Boot automatically detect and register spring-managed beans in the classpath. (@Component, @RestController, @Service, @Repository).</li></ul><h3><strong>Why You Need It:</strong></h3><p>You only need this one annotation at the entry point of your application (usually in the <code>main</code> class), and Spring Boot will handle the rest. It significantly reduces the need for configuration and makes your life easier.</p><pre><code class="language-java">@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}</code></pre><h2>2. @RestController</h2><h3><strong>What It Does:</strong></h3><p>The <code>@RestController</code> annotation is used to define a controller in a Spring Boot application that handles HTTP requests and sends back HTTP responses. It's a convenience annotation that combines <code>@Controller</code> and <code>@ResponseBody</code>, meaning you don't need to annotate each method with <code>@ResponseBody</code> individually.</p><h3><strong>Why You Need It:</strong></h3><p>If you’re building a RESTful web service, <code>@RestController</code> is a must-have. It simplifies your code by eliminating the need to return views. Instead, it automatically serializes the response body into JSON or XML, making it ideal for APIs.</p><pre><code class="language-java">@RestController
@RequestMapping("/api")
public class MyController {

    @GetMapping("/greet")
    public String greet() {
        return "Hello, Spring Boot!";
    }
}</code></pre><h2>3. @Autowired</h2><h3><strong>What It Does:</strong></h3><p>The <code>@Autowired</code> annotation is used for dependency injection in Spring Boot. It tells Spring to automatically inject the required bean into your class at runtime.</p><h3><strong>Why You Need It:</strong></h3><p>Instead of manually creating instances of your dependencies, <code>@Autowired</code> lets Spring handle it for you. This is especially useful in large applications where managing dependencies manually would be tedious.</p><pre><code class="language-java">@Component
public class MyService {

    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}</code></pre><p>In the example above, <code>@Autowired</code> tells Spring to inject an instance of <code>MyRepository</code> into <code>MyService</code> at runtime.</p><h2>4. @Value</h2><h3><strong>What It Does:</strong></h3><p>The <code>@Value</code> annotation is used to inject values into Spring beans from external sources like <code>application.properties</code> or <code>application.yml</code>.</p><h3><strong>Why You Need It:</strong></h3><p>This annotation is perfect for configuring your application with properties without hardcoding values into your code. It makes your app more flexible and easier to configure for different environments (development, production, etc.).</p><pre><code class="language-java">@Component
public class MyService {

    @Value("${spring.application.name}")
    private String appName;

    public void printAppName() {
        System.out.println("App Name: " + appName);
    }
}</code></pre><p>In the example above, Spring Boot will inject the value of <code>spring.application.name</code> from the <code>application.properties</code> file into the <code>appName</code> field.</p><h2>5. @Async</h2><h3><strong>What It Does:</strong></h3><p>The <code>@Async</code> annotation is used to run methods asynchronously in Spring Boot. When you mark a method with <code>@Async</code>, Spring will execute it in a separate thread, allowing the main thread to continue executing without waiting for the method to complete.</p><h3><strong>Why You Need It:</strong></h3><p>Applications are expected to handle a growing number of concurrent tasks. By using <code>@Async</code>, you can keep your app responsive and efficient, especially when dealing with time-consuming tasks like I/O operations or external API calls.</p><pre><code class="language-java">@Async
public CompletableFuture&lt;String&gt; fetchData() {
    try {
        Thread.sleep(2000); // Simulate long-running task
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return CompletableFuture.completedFuture("Data fetched successfully!");
}</code></pre><p>This method will run in the background, letting the main thread keep doing other tasks.</p><h2>6. @Entity</h2><h3><strong>What It Does:</strong></h3><p>The <code>@Entity</code> annotation marks a class as an entity bean that should be mapped to a database table. It’s part of JPA (Java Persistence API) and tells Spring Boot that this class should be managed by the persistence context.</p><h3><strong>Why You Need It:</strong></h3><p>If you’re working with a relational database, <code>@Entity</code> is essential for defining the structure of your database tables and letting Spring Boot automatically handle CRUD (Create, Read, Update, Delete) operations through repositories.</p><pre><code class="language-java">@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String email;

    // Getters and setters
}</code></pre><p>In the example above, <code>@Entity</code> maps the <code>User</code> class to a database table, and Spring Boot will automatically manage it using JPA repositories.</p><h2>Conclusion</h2><p>Spring Boot has a bunch of annotations that can seriously simplify your coding life. Once you start using them, you’ll notice how much easier it is to get things done without worrying about writing a ton of repetitive code. As web applications keep getting more demanding and complex, knowing how and when to use these annotations can make a big difference in how efficient and scalable your projects are.</p><p>So, to wrap it up, the six annotations we talked about—<code>@SpringBootApplication</code>, <code>@RestController</code>, <code>@Autowired</code>, <code>@Value</code>, <code>@Async</code>, and <code>@Entity</code> are tools you’ll find yourself reaching for almost every day. Get comfortable with them, and you’ll be better equipped to build robust, modern Spring Boot applications that stand the test of time.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring</category>
            <category>Spring Boot</category>
            <category>Spring Boot Annotations</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/top_6_spring_boot_annotations_b40bd71635.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Understanding The @async Annotation In Spring Boot ]]></title>
            <link>https://www.codingshuttle.com/blogs/understanding-the-async-annotation-in-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/understanding-the-async-annotation-in-spring-boot</guid>
            <pubDate>Fri, 31 Jan 2025 11:06:40 GMT</pubDate>
            <description><![CDATA[In this blog, I'll provide a simple guide to using the @Async annotation in Spring Boot, helping you improve application performance by running tasks asynchronously. I will also cover setup, usage, and best practices for efficient thread management and error handling.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p>If you’re diving into web development, you’ve probably heard that speed and responsiveness are key, right? That’s where asynchronous programming comes into play. It’s one of those tools you didn’t know you needed until you do. If you’re using Spring Boot, you’ve probably bumped into the <code>@Async</code> annotation at some point, but what does it actually do, and why should you care? Let’s break it down in a way that actually makes sense, without all the jargon.</p><h2>So, What’s <code>@Async</code> All About?</h2><p><code>@Async</code> is like telling Spring, “Hey, this task? Let it run in the background while I get on with other stuff.” When you throw <code>@Async</code> on a method, Spring takes that method and hands it off to a different thread, leaving your main thread free to keep doing its thing. It’s like delegating a long-running task to someone else so you don’t have to sit there twiddling your thumbs waiting for it to finish. So, whether it’s pulling data from an API or doing some heavy lifting in your code, <code>@Async</code> helps keep things moving without holding up the rest of your app.</p><h2>How Does It Actually Work?</h2><p>So, how does Spring make all this magic happen? Well, it uses something called a <strong>task executor</strong>. This is just a fancy way of saying it manages a pool of threads to handle asynchronous methods. When you mark a method with <code>@Async</code>, Spring grabs an available thread from this pool and runs the method on it.</p><p>If you don’t specify a custom executor, Spring will use a default one. But, if you’ve got more specific needs (like controlling the number of threads or tweaking how tasks are handled), you can easily create a custom executor. It gives you a lot of flexibility to fine-tune how your app runs.</p><h2>Steps to Use the <code>@Async</code> Annotation</h2><h3>1. Enable Asynchronous Processing</h3><p>Before you can start using the <code>@Async</code> annotation, you need to enable asynchronous processing in your Spring Boot application. You can do this by adding the <code>@EnableAsync</code> annotation to one of your configuration classes.</p><pre><code class="language-java">@Configuration
@EnableAsync
public class AsyncConfig {
}</code></pre><p>The <code>@EnableAsync</code> annotation tells Spring to look for methods annotated with <code>@Async</code> and handle them asynchronously.</p><h3>2. Annotate Your Method</h3><p>Once asynchronous processing is enabled, you can annotate any method you want to run asynchronously with <code>@Async</code>.</p><pre><code class="language-java">@Async
public void processData() {
    // Time-consuming task
}</code></pre><p>In this case, the <code>processData</code> method will run in a separate thread, allowing the main thread to continue executing other code.</p><h3>3. Return Type Consideration</h3><p>The return type of an asynchronous method is important. The method can either return <code>void</code>, <code>Future</code>, or <code>CompletableFuture</code>. If you need to get a result from the asynchronous task, you’ll want to use <code>Future</code> or <code>CompletableFuture</code>.</p><p>Here’s an example using <code>CompletableFuture</code>:</p><pre><code class="language-java">@Async
public CompletableFuture&lt;String&gt; fetchData() {
    // Simulate some long-running task
    return CompletableFuture.completedFuture("Data fetched successfully!");
}</code></pre><p>With <code>CompletableFuture</code>, you can even chain multiple asynchronous tasks together or apply transformations to the result once the task completes.</p><h3>4. Calling an Asynchronous Method</h3><p>When calling an asynchronous method, it behaves just like any other method, but the difference is that it runs in the background. Here’s how you would call the <code>fetchData()</code> method from another component:</p><pre><code class="language-java">@Autowired
private MyService myService;

public void process() {
    CompletableFuture&lt;String&gt; result = myService.fetchData();
    // You can continue doing other work here while fetchData runs in the background
}</code></pre><h3>Handling Exceptions</h3><p>One of the challenges with asynchronous methods is handling exceptions. Since asynchronous methods run in a separate thread, exceptions thrown inside those methods won’t be caught in the usual try-catch blocks. To deal with this, you can use the <code>@Async</code> method’s <code>Future</code> or <code>CompletableFuture</code> to handle exceptions.</p><p>For example, you could use <code>CompletableFuture.exceptionally()</code> to manage errors:</p><pre><code class="language-java">@Async
public CompletableFuture&lt;String&gt; fetchData() {
    return CompletableFuture.supplyAsync(() -&gt; {
        // Simulate a failure
        if (someCondition) {
            throw new RuntimeException("Something went wrong!");
        }
        return "Data fetched successfully!";
    }).exceptionally(ex -&gt; {
        // Handle the exception
        return "Failed to fetch data: " + ex.getMessage();
    });
}</code></pre><h3>Customizing the Task Executor</h3><p>While Spring Boot provides a default task executor, you may need more control over the execution of your asynchronous methods. You can define a custom task executor by adding a bean to your configuration:</p><pre><code class="language-java">@Bean
public TaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setMaxPoolSize(10);
    executor.setQueueCapacity(25);
    executor.initialize();
    return executor;
}</code></pre><p>This custom executor will control how many threads Spring uses to handle asynchronous tasks, ensuring you don’t overload your system.</p><h3>Things to Keep in Mind</h3><ul><li><strong>Thread Management:</strong> Make sure the thread pool size is configured properly. Too many threads can cause resource exhaustion, while too few can lead to tasks queuing up.</li><li><strong>Asynchronous Method Visibility:</strong> Only methods in Spring-managed beans can be asynchronous. If you try to mark a method in a non-Spring bean with <code>@Async</code>, it won’t work.</li><li><strong>Non-blocking Operations:</strong> <code>@Async</code> is ideal for non-blocking operations. If the task involves waiting on I/O or external services, asynchronous processing can make a big difference in performance.</li></ul><h3>Example with Output:</h3><p>Let’s say you have a service that fetches user data asynchronously. We’ll mock up an example with <code>@Async</code> and <code>CompletableFuture</code> to simulate the process of fetching user data and processing something else in the meantime.</p><h3>Service Class (<code>MyService.java</code>)</h3><pre><code class="language-java">import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;

@Service
public class MyService {

    @Async
    public CompletableFuture&lt;String&gt; fetchData() {
        try {
            // Simulate a delay, like fetching data from an API or database
            Thread.sleep(2000); // 2 seconds delay
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return CompletableFuture.completedFuture("User data fetched successfully!");
    }
}</code></pre><h3>Controller or Another Class Where You Call the Service (<code>MyController.java</code>)</h3><pre><code class="language-java">import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;

@RestController
public class MyController {

    @Autowired
    private MyService myService;

    @GetMapping("/process")
    public String process() {
        // Start the async task
        CompletableFuture&lt;String&gt; result = myService.fetchData();

        // Simulate doing something else while the async task runs
        for (int i = 0; i &lt; 5; i++) {
            System.out.println("Doing other work... " + (i + 1));
            try {
                Thread.sleep(500); // 0.5 seconds work simulation
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // Get the result from the async task
        String asyncResult = result.join(); // Wait for the async task to finish
				System.out.println("Finished processing. " + asyncResult); // Print the result
        // Return the final result
        return "Finished processing. " + asyncResult;
    }
}</code></pre><h3>Breakdown of What Happens:</h3><ol><li>When you hit the <code>/process</code> endpoint, the <code>process()</code> method in <code>MyController</code> is triggered.</li><li>It starts the <code>fetchData()</code> method asynchronously. The method begins to run on a separate thread, simulating a 2-second delay (like waiting for an API response).</li><li>While the async task is running, the main thread continues doing other work. In this case, it prints <code>"Doing other work..."</code> 5 times, with a 0.5-second delay between each print.</li><li>After the async task finishes (after 2 seconds), we call <code>result.join()</code> to get the result from the <code>CompletableFuture</code>. Once that’s done, the final message is returned.</li></ol><h3>Output:</h3><p>When you hit the <code>/process</code> endpoint, the output will look something like this in the console:</p><pre><code class="language-plaintext">Doing other work... 1
Doing other work... 2
Doing other work... 3
Doing other work... 4
Doing other work... 5
Finished processing. User data fetched successfully!</code></pre><p>Here’s what happens step-by-step:</p><ul><li>The <code>"Doing other work..."</code> messages are printed while the async task is running in the background.</li><li>After the background task finishes, you get the <code>"Finished processing. User data fetched successfully!"</code> message returned to the user.</li></ul><h2>Conclusion</h2><p>The <code>@Async</code> annotation in Spring Boot is a powerful tool for making your application more responsive by executing tasks asynchronously. By offloading time-consuming tasks to background threads, you improve the overall user experience and system efficiency. Whether you're fetching data from a remote server or processing complex calculations, asynchronous methods can significantly boost performance. Just be mindful of thread management and exception handling to ensure everything runs smoothly.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring</category>
            <category>Spring Boot</category>
            <category>@async annotation in spring boot</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/aysnc_annotation_466d220b15.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Best Way To Master Spring Boot - A Complete Roadmap in 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/best-way-to-master-spring-boot-a-complete-roadmap-2025</link>
            <guid>https://www.codingshuttle.com/blogs/best-way-to-master-spring-boot-a-complete-roadmap-2025</guid>
            <pubDate>Fri, 31 Jan 2025 10:52:26 GMT</pubDate>
            <description><![CDATA[This blog is a complete roadmap to mastering Spring Boot, breaking down complex concepts into simple, structured phases. Whether you're a beginner or someone struggling with overwhelming documentation, this guide will help you navigate Spring Boot efficiently and build real-world applications with confidence.]]></description>
            <content:encoded><![CDATA[<p>When I first heard about Spring Boot, I didn’t know what the buzz was all about. People kept saying it was <i>the</i> tool for building Java applications, but when I opened the documentation for the first time, I’ll be honest it felt overwhelming. There were annotations everywhere, configuration options I’d never heard of, and concepts like microservices that seemed way out of reach.</p><p>But here’s the thing: once I found a clear path to learning Spring Boot, it all started making sense. I realized it wasn’t about trying to understand everything at once but about taking it step by step. Now, having worked with Spring Boot on real-world projects, I’ve put together a roadmap to help others avoid the same confusion I had.</p><p>If you’re ready to master Spring Boot without wasting time on unnecessary detours, let me guide you through the process. This roadmap is based on what actually works not just theory. Let’s jump in!</p><h2><strong>What You Should Know Before Diving into Spring Boot</strong></h2><ul><li><strong>Java and OOP Basics:</strong> Since Spring Boot is built on Java, you'll need a solid grasp of Java and its object-oriented principles. Things like classes, objects, inheritance, polymorphism, and interfaces are a big part of how everything works. If you’re also comfortable with collections, exception handling, and generics, you’ll have a much smoother time.</li><li><strong>Databases and SQL:</strong> A basic understanding of relational databases (like MySQL or PostgreSQL) and SQL will really come in handy when you're dealing with Spring Data JPA and how Spring Boot interacts with databases.</li><li><strong>Web Development Basics:</strong> It’s helpful to have a basic understanding of how web apps run. Things like how browsers communicate with servers (HTTP), what REST APIs are all about, and how data moves around the web will make learning Spring Boot a lot easier.</li></ul><h2>Before We Dive into the Spring Boot Roadmap</h2><p>Let’s pause for a second. You’re probably wondering, “If Spring is already there, why do we even need Spring Boot?” That question crossed my mind too when I first heard about it.</p><p>Here’s the deal: Spring is amazing, no doubt about it. It gives you all the tools to build powerful Java applications. But let me be honest: when I started with Spring, it felt like I spent more time configuring things than actually building anything. Setting up XML files, managing dependencies, and figuring out how to wire everything together was a lot.</p><p>That’s why Spring Boot is such a game-changer. It takes all the complexity of Spring and simplifies it. For example, you don’t need to set up an external server anymore it gives you one built-in. It also auto-configures a lot of stuff so you can hit the ground running. Think of it like upgrading from a basic toolkit to a power tool—it doesn’t replace Spring, but it makes using it so much smoother and faster.</p><p>Once I started working with Spring Boot, I realized how much time it saved. It’s honestly one of the reasons I didn’t give up on Java during those early days!</p><p>Now that we’ve got that cleared up, let’s get into the actual roadmap.</p><h2>Complete Roadmap to master Spring Boot</h2><p>When I first started learning Spring Boot, I had no idea what topics I actually needed to understand to build a simple Spring Boot application. Well, over time, I figured out the essentials that made everything click. It wasn’t about knowing everything right away but focusing on the key areas that really matter. If you’re starting out or feeling lost in the details, don’t worry here’s the roadmap I wish I had when I was getting into it.</p><p><strong>The roadmap is divided into 10 phases:</strong></p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/spring_boot_roadmap_00bc291d14.png" alt="spring_boot_roadmap.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_spring_boot_roadmap_00bc291d14.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_spring_boot_roadmap_00bc291d14.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_spring_boot_roadmap_00bc291d14.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_spring_boot_roadmap_00bc291d14.png 1000w," sizes="100vw"><figcaption>Spring Boot Road map</figcaption></figure><h3><strong>Phase 1: Understand Spring Boot Core Concepts</strong></h3><p>When I first started learning Spring Boot, it felt like there was a mountain of stuff to figure out. But honestly, once I broke it down and started with the basics, everything started to make sense. In this first phase, I want to help you get familiar with the core stuff that’ll make everything else easier down the line. Don’t stress about knowing it all right away—just focus on getting comfortable with these key concepts.</p><p><strong>1. Spring Architecture</strong></p><p>You’ll start by understanding how Spring Boot fits into the larger Spring ecosystem and what makes it stand out for building Java apps.</p><p><strong>2. Spring IOC Container</strong></p><p>Learn how Spring Boot manages your application’s objects using the <strong>IOC container</strong>, which takes care of things like creation, configuration, and dependency management.</p><p><strong>3. Create Your First Spring Boot Project</strong></p><p>Using <strong>Spring Initializr</strong>, you’ll quickly spin up your first project, setting the stage for everything you’ll build later.</p><p><strong>4. Spring Boot Application Properties</strong></p><p>You’ll need to know where and how to manage your application’s settings—like server ports and database info—through the <code>application.properties</code> or <code>application.yml</code> file.</p><p><strong>5. Understand Spring Beans</strong></p><p>Get to know <strong>Beans</strong> the building blocks of your Spring Boot app and how Spring manages them automatically.</p><p><strong>6. Dependency Injection</strong></p><p>A big part of Spring Boot is <strong>Dependency Injection (DI)</strong>, which helps you keep things neat and organized by automatically injecting dependencies into your classes.</p><p><strong>7. Spring Context</strong></p><p>The <strong>Spring Context</strong> is where all your Beans live. It helps tie everything together, so understanding how it works is crucial for structuring your app.</p><p><strong>8. Spring Boot Annotations</strong></p><p>Spring Boot relies on some key <strong>annotations</strong> (like <code>@SpringBootApplication</code>) to set things up automatically, so getting familiar with them will save a lot of time.</p><p><strong>9. Spring Boot Auto Configuration</strong></p><p>One of Spring Boot’s biggest features is <strong>Auto Configuration</strong>, which takes care of a lot of the setup for you—like configuring your database or web server just by adding the right dependencies.</p><h3><strong>Phase 2: Building Web Applications and RESTful APIs</strong></h3><p>Coming to the next phase, In this phase, we’re going to start building actual web applications and APIs. Don’t worry, we’ll keep it simple and focus on the core things that’ll make your app run.</p><p><strong>1. Understand Spring MVC Architecture</strong></p><p>First, get the gist of Spring MVC. It's how Spring Boot handles your requests and sends them where they need to go. Once you get how it works, it’ll make the rest of building your app so much easier.</p><p><strong>2. Learn About Controllers</strong></p><p>Now, controllers. These are crucial they take requests and send them to the right place in your app. Learn how to set them up, and you’ll be able to route the requests properly to the respective methods.</p><p><strong>3. Start Building RESTful APIs</strong></p><p>You’ll need to know how to build RESTful APIs. These are basically the bridges between your app and the outside world. It’s how other apps can interact with yours, so you’ll need to learn how to set up these endpoints and get data in and out.</p><p><strong>4. Binding and Validating Data</strong></p><p>As users interact with your app, they’ll be sending data. Learn how to bind that data to your models and make sure it’s legit before processing it. If there’s something wrong, you want to catch it early.</p><p><strong>5. Handling Exceptions and Custom Error Pages</strong></p><p>Things will break. But instead of showing a generic error page, you can make it more user-friendly by handling exceptions and showing custom error pages. It’s a small thing, but it makes a big difference.</p><p><strong>6. Using Interceptors</strong></p><p>Interceptors might sound like a lot, but really, they’re just tools that help you do things like logging or checking if someone’s logged in before hitting your controller. They're super helpful for making sure everything flows smoothly behind the scenes.</p><h3><strong>Phase 3: Mastering Spring Data JPA</strong></h3><p>Here’s where things start to get real with databases. If you’ve been wondering how to get your app to talk to a database without losing your mind, this is the phase for that. When I started with Spring Data JPA, I had no idea what “repositories” or “entities” even meant. But the more I worked with it, the clearer it became.</p><p><strong>1. Understand Spring Data JPA</strong></p><p>Start by getting a solid understanding of what Spring Data JPA is and why it’s so useful. It’s the framework that simplifies working with databases, and once you get it, you’ll wonder how you ever did things without it.</p><p><strong>2. Learn About JPA Repository Interface</strong></p><p>JPA repositories are one of the main building blocks of Spring Data JPA. Understanding how they work will make things like querying and managing data super easy.</p><p><strong>3. Master Entity Mapping</strong></p><p>Learn how to map your Java objects to database tables using entity mapping. It’s all about making sure your Java classes and database tables talk to each other correctly.</p><p><strong>4. Explore Fetching Strategies</strong></p><p>Learn about the different fetching strategies and how they affect the performance of your application. It’s all about getting the data you need, without overloading your app.</p><p><strong>5. Get to Know Repositories and Query Methods</strong></p><p>You’ll want to dig deeper into repositories and how to create custom query methods to fetch exactly the data you need. This is where things get more dynamic and flexible.</p><p><strong>6. Set Up MySQL with Spring Data JPA</strong></p><p>Setting up a MySQL database to work with Spring Data JPA is an essential skill. It’s a little setup work, but once it’s done, you’ll be able to manage your data like a pro.</p><p><strong>7. Learn JPQL and Native Queries</strong></p><p>JPQL (Java Persistence Query Language) and native queries let you write custom queries for more control. These will come in handy when you need something more specific than the default methods Spring gives you.</p><p><strong>8. Understand Paging and Sorting</strong></p><p>When your data grows, you’ll need ways to paginate and sort it efficiently. This is essential for performance, especially when dealing with large datasets.</p><p><strong>9. Understand Locking</strong></p><p>Learn about optimistic and pessimistic locking to ensure that data is handled safely when multiple users or processes are trying to access it at the same time.</p><p><strong>10. Master Transactions</strong></p><p>Finally, get familiar with transactions. Understanding how to manage them is key to making sure your data is consistent and reliable, especially when things go wrong.</p><h3><strong>Phase 4: Use Spring Boot Production-Ready Features</strong></h3><p>This phase is all about getting your app ready for the real world. It’s not just about making it work; it’s about making sure it can handle the chaos of production. This is where you’ll learn to add the extra touches that make your app reliable and easier to manage once it’s live.</p><p>Here’s what you’ll want to explore:</p><ol><li><strong>Dev Tools</strong>: These tools are a lifesaver during development—they make testing and debugging faster with auto-reload and other handy features.</li><li><strong>Auditing with Hibernate:</strong> Learn how to track changes in your database, like knowing who updated what and when.</li><li><strong>RestClient:</strong> If your app needs to talk to another API, this is how you’ll make it happen.</li><li><strong>Logging:</strong> Trust me, you’ll thank yourself later when you have proper logs to figure out why something broke.</li><li><strong>Actuator:</strong> This helps you monitor your app’s health and performance once it’s running in production.</li><li><strong>Swagger:</strong> Make your APIs user-friendly by documenting them so others can understand and use them easily.</li></ol><h3><strong>Phase 5: Spring Security</strong></h3><p>The next phase is all about understanding security. It is going to be hard for the first time to understand, but trust me, once you start getting into it, it’s not as complicated as it seems.</p><ol><li><strong>How Spring Security Works:</strong> Before you jump into setting things up, it’s useful to know the basics of how security works in Spring Boot.</li><li><strong>JWT (JSON Web Tokens):</strong> This is the magic behind modern app security. You’ll see why JWT is such a big deal and how it helps keep your app safe.</li><li><strong>User Signups and Logins with JWT:</strong> Setting up a secure login and signup system is key. With JWT, this becomes a lot smoother.</li><li><strong>Authenticating Requests with JWT:</strong> Once you have users signing in, you need a way to make sure that every request is coming from someone who’s properly authenticated. JWT helps you do that.</li><li><strong>OAuth2 Client Authentication:</strong> If you want users to log in with their Google, Facebook, or other social accounts, OAuth2 is how you do it.</li><li><strong>Role-Based Access:</strong> You’ll want to make sure only certain users can access specific parts of your app. This is where role-based access comes in.</li><li><strong>Handling Security Exceptions:</strong> Let’s face it, errors will happen. But handling them correctly, especially security-related ones, is super important.</li></ol><h3><strong>Phase 6: Spring Boot Testing</strong></h3><p>Testing might not be the most exciting thing, but trust me, it's one of the most important skills you can learn. In this phase, you'll get hands-on with testing to ensure your Spring Boot apps are solid.</p><p><strong>1. Understanding JUnit and AssertJ</strong></p><p>Start by learning JUnit for writing test cases and AssertJ for fluent assertions that make your tests more readable.</p><p><strong>2. Unit Testing the Persistence Layer</strong></p><p>Learn how to test your database interactions to ensure data is being saved and retrieved correctly from your database.</p><p><strong>3. Understanding Mockito</strong></p><p>Dive into Mockito for mocking external dependencies in your tests, so you don’t have to worry about real database connections or third-party services.</p><p><strong>4. Unit Testing the Service Layer</strong></p><p>Test the logic in your service layer, ensuring that your business logic works as expected without connecting to a real database.</p><p><strong>5. Integration Testing the Presentation Layer</strong></p><p>Wrap it all up by testing the presentation layer (controllers) to ensure that your APIs and web interfaces are functioning correctly together.</p><h3><strong>Phase 7: Microservice Architecture and Advanced Microservice Concepts</strong></h3><p>Alright, now we're diving into the world of microservices. This phase is all about breaking your application into smaller, independent services that can scale and work together. It's a game-changer for building flexible, maintainable apps. Here's the path you'll follow:</p><p><strong>1. Microservice Architecture</strong></p><p>Get a solid grasp of what microservices are all about. You’ll see how breaking an app into smaller, self-contained services can make it more scalable and easier to manage.</p><p><strong>2. Service Discovery with Eureka</strong></p><p>Service discovery with Eureka will help your services find and communicate with each other automatically, so you don’t have to hardcode any URLs.</p><p><strong>3. Spring Cloud API Gateway</strong></p><p>Set up an API Gateway that acts as the traffic cop for your microservices, directing requests to the right service while adding an extra layer of security.</p><p><strong>4. API Gateway Filters and Authentication with Custom GatewayFilters</strong></p><p>Customize how requests pass through the API Gateway, adding filters for things like authentication and monitoring to keep things secure and efficient.</p><p><strong>5. OpenFeign Microservice Communication</strong></p><p>OpenFeign simplifies the communication between microservices. Instead of manually handling HTTP requests, you can just call methods, and OpenFeign takes care of the rest.</p><p><strong>6. Circuit Breaker, Retry, and Rate Limiter with Resilience4J</strong></p><p>Keep your app running smoothly even when things go wrong. Resilience4J helps you add retries, circuit breakers, and rate limiting to prevent system failures.</p><p><strong>7. Centralized Configuration Server using GitHub</strong></p><p>You don’t want to manage configuration for each service separately. With GitHub as your centralized config server, you can store all your configurations in one place and make life easier.</p><p><strong>8. Distributed Tracing using Zipkin and Micrometer</strong></p><p>Tracing is crucial when you’re dealing with multiple microservices. Zipkin and Micrometer let you track requests as they travel across services, helping you debug and keep everything running smoothly.</p><p><strong>9. Centralized Logging with the ELK Stack</strong></p><p>Centralized logging is a lifesaver when you’re working with microservices. The ELK stack lets you collect logs from all your services in one place, making it easier to monitor and troubleshoot.</p><h3><strong>Phase 8: Optimizing Spring Boot App for better performance with Modern Tools</strong></h3><p>Now we’re entering a phase that’s all about making your Spring Boot application faster, more efficient, and ready for production. This isn’t just about writing more code—it’s about using the right tools and techniques to ensure that your app can handle real-world loads with ease. Here’s what you need to focus on:</p><p><strong>1. Caching with Redis</strong></p><p>If your application has lots of data that doesn't change often, repeatedly fetching it from the database can slow things down. That's where <strong>Redis</strong> comes in. It’s an in-memory data store that lets you cache frequently accessed data. This means your app doesn’t need to keep hitting the database, resulting in faster response times. By using Redis for caching, you’ll reduce the load on your database, speed up your app, and deliver a better experience for your users.</p><p><strong>2. Apache Kafka</strong></p><p>As your app grows, managing communication between different services can get tricky. <strong>Apache Kafka</strong> helps solve this problem by enabling event-driven architecture. Kafka allows your services to communicate asynchronously through messages or events. Instead of tightly coupling your services together, you can publish messages to Kafka, and other services can subscribe to those messages. This decoupling makes your app more scalable and flexible, allowing different parts of your system to operate independently, making it easier to manage as it grows.</p><h3><strong>Phase 9: CI/CD and Cloud Deployment for Spring Boot</strong></h3><p>Our next phase focuses on getting your Spring Boot app ready for real-world deployment. This is where you’ll dive into automating your deployment process with CI/CD tools and take your app to the cloud. Here’s what you’ll cover:</p><p><strong>1. CI/CD Concepts</strong></p><p>Learn the basics of Continuous Integration and Continuous Deployment to streamline your workflow.</p><p><strong>2. Setting up Jenkins</strong></p><p>Set up Jenkins to automate builds, tests, and deployments for your Spring Boot app.</p><p><strong>3. Git Version Control</strong></p><p>Use Git to manage your code and integrate it into your CI/CD pipeline.</p><p><strong>4. Automated Testing in CI</strong></p><p>Automate unit and integration tests to ensure your app is stable before deployment.</p><p><strong>5. Dockerizing Your Spring Boot App</strong></p><p>Learn how to containerize your Spring Boot app with Docker for consistent deployment.</p><p><strong>6. Deploying to the Cloud</strong></p><p>Deploy your Dockerized app to cloud platforms like AWS, Azure, or Google Cloud.</p><p><strong>7. Using Kubernetes for Scaling</strong></p><p>Learn and Use the Kubernetes engine to manage and scale your Spring Boot app in production.</p><p><strong>8. Cloud Monitoring and Logging</strong></p><p>Set up monitoring tools like Prometheus and Grafana to keep an eye on your app’s performance in the cloud.</p><h3><strong>Phase 10: Stay Updated and Keep Building Projects</strong></h3><p>Alright, here’s the deal: Now that you’ve got a solid handle on Spring Boot, it’s time to take things to the next level. The truth is, no matter how much you learn, there’s always more to discover and more projects to build. This phase is all about keeping that momentum going and continuing to learn.</p><ol><li><strong>Stay Updated:</strong> Spring Boot evolves constantly. You’ll want to keep an eye on the latest updates and new features. That way, you’re always in the know and ready to implement the best practices. Keep an eye on the Spring blog, follow devs on Twitter, and watch for new tutorials.</li><li><strong>Build Real Projects:</strong> The more you build, the more you learn. Take on personal projects that interest you, and try to solve problems that you’ve personally faced. Build things that challenge you and make you grow. Nothing beats the learning you get from creating something real.</li><li><strong>Contribute to Open Source:</strong> If you feel confident enough, try getting involved in open-source projects. It’s a great way to contribute to the community, learn from others, and tackle real-world problems. Even small contributions can teach you a ton.</li><li><strong>Join Developer Communities:</strong> Whether it’s on Slack, Reddit, or at a local meetup, joining a community can do wonders. You’ll meet other developers, share knowledge, and get feedback on your work. There’s always something new to learn from others.</li></ol><h2>Conclusion</h2><p>Mastering Spring Boot is all about taking it step by step and focusing on the key concepts. Keep building real-world projects, stay updated, and embrace the learning process. With persistence, you'll confidently create powerful applications in no time.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring</category>
            <category>Spring Boot</category>
            <category>Spring Boot complete Roadmap</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/best_waay_to_mster_spring_boot_af310a3013.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How To Become A Fullstack Java Developer in 2025: [Complete Roadmap and Resources]]]></title>
            <link>https://www.codingshuttle.com/blogs/how-to-become-a-full-stack-developer</link>
            <guid>https://www.codingshuttle.com/blogs/how-to-become-a-full-stack-developer</guid>
            <pubDate>Fri, 31 Jan 2025 10:34:20 GMT</pubDate>
            <description><![CDATA[Whether you're a fresher or an experienced developer looking to upskill, this guide will help you navigate the journey toward becoming a proficient full-stack developer.
This blog provides a clear roadmap to becoming a full-stack developer, covering essential front-end, back-end, database management, and cloud deployment skills. ]]></description>
            <content:encoded><![CDATA[<p>The demand for full-stack developers has increased nowadays, Fullstack developers are those who build and maintain the both front-end and back-end parts of the application. Companies are looking for full-stack developers as they play an important role in understanding the complete process of building an application from scratch and scaling it. If you are a fresher or an experienced developer who wants to grow more then switching to full-stack development is going to be the best decision for you.</p><p>This blog will provide you with a clear path to becoming a full-stack developer, regardless of your level of experience or your consideration of changing careers.</p><h2>What is a Full-Stack Development?</h2><p>The term "Full-Stack" means the combination of those technologies which are required to build both the front-end and back-end parts of an application. Therefore Full-Stack development can be referred to as the process of developing both the front-end (client-side) and back-end (server-side) of the application.</p><h2>Skills Required to Become a Full-Stack Developer</h2><p>To become a successful full-stack developer, you need to master several essential skills. These can be broken down into <strong>front-end</strong>, <strong>back-end</strong>, <strong>database management,</strong> and <strong>cloud deployment</strong> process</p><h3>1. Front-End Skills</h3><p><strong>Front-end</strong> is all about developing the UI/UX of the application basically the visual elements like buttons, forms, menus, layouts, etc.</p><p>To master front-end skills you need to learn concepts like HTML, CSS, JS, Javascript libraries like React,js, Angular.js, and CSS frameworks like Bootstrap CSS, Tailwind CSS etc.</p><h3>2. Back-End Skills</h3><p><strong>Back</strong>-<strong>end</strong> is all about server-side development where business logic is written to process the data and stored in the database along with handling APIs for processing the client request and sending responses back to the client securely.</p><p>To master back-end skills, you need to learn programming languages with their framworks like Java (Spring Boot), Python (Django, Flask, FastAPI), JavaScript/TypeScript (Node.js), PHP (Laravel), Ruby (Ruby on Rails), C# (.NET Core), GoLang.</p><h3>3. Database Management</h3><p>Learning database management is important for full-stack developers as it involves designing, data modeling, implementing, and managing the storage and retrieval of data that your application uses. You should be able to choose the right type of database for your project and write queries to interact with it.</p><p>You have to get familiar with the following database types:-</p><ol><li>Relational Databases i.e SQL (MySQL, PostgreSQL)</li><li>Non-Relational Databases i.e NO SQL (MongoDB, Cassandra, Redis)</li></ol><h3>4. Cloud deployment</h3><p>Once you develop the front-end and back-end of your application you test your application on <a href="http://localhost">localhost</a> i.e on your machine itself, after testing you have to make your application accessible to the world so that everyone can use it, for that, you need to deploy the application on cloud servers i.e on the machines which are running for 24 Hrs somewhere in the world. With this you don’t need to manage physical servers and infrastructure, it also provides scalability, and reliability.</p><p>You need to be familiar with any of these major cloud providers services:</p><ol><li>Amazon Web Services (AWS)</li><li>Google Cloud Platform (GCP)</li><li>Microsoft Azure</li></ol><h2>Steps to Master a Full-Stack Development</h2><p>Now let’s go step by step in detail to master full-stack development skills.</p><h3>1. Learn the Fundamentals of Programming</h3><p>Before diving into full-stack development, it's important to have a familiarity or proficiency in programming language. If you're a complete beginner, Pick one programming language and start learning Core programming concepts.</p><p>You can pick any one of the programming languages from below:</p><ol><li><strong>Java</strong>: It is one of the robust language used in back-end development to build enterprise-level backend applications. Spring Boot (developed in Java) is one of the popular frameworks in the industry used to build secure and scalable back-end applications.</li><li><strong>Java Script</strong>: It is the most important language because in front-end development you will be using frameworks (React.js, Angular.js ) of JavaScript. Java Script is also a common choice for full-stack development as you can do front-end as well as back-end development (Node.js). The popular tech stack in which Java script is used is the MERN stack (Mongo, Express.js, React.js, Node.js).</li><li><strong>Python</strong>: Python is one of the versatile language used in data science, scripting, and for building backend applications with its frameworks like Django and Flask. It is easily understandable for beginners.</li></ol><p>Once you pick any of the programming languages start learning the following Core programming concepts:</p><p><strong>Variables</strong>: Understand how to store and manipulate the data using variables. Variables in which you are going to store the data can be of any data type like integers (whole numbers), floating-point numbers (decimals), Strings (text), and boolean (true/false values).</p><p><strong>Data Structures:</strong> This is important to learn because you will widely use data structure to organize and manage user’s data efficiently. For example, storing the user's email in a set data structure when retrieved from the database, so that only unique emails are present even after you merge the other list of emails with it**.** Familiarize yourself with fundamental data structures like arrays (ordered lists), dictionaries/Maps (Key-value pairs), and Sets (Collection of unique elements), etc.</p><p><strong>Operators:</strong> Learn to use arithmetic operators (+, -, *, /), comparison operators (==, !=, &gt;, &lt;, &gt;=, &lt;=), logical operators (AND, OR, NOT), and assignment operators (=, +=, -=, etc.). as these are used to perform operations on data.</p><p><strong>Control Flow:</strong></p><p>Mastering control flow is essential for creating programs that can make decisions and repeat actions. This involves:</p><ul><li><strong>Conditional Statements (if, else if, else):</strong> Executing different blocks of code based on conditions.</li><li><strong>Loops (for, while, do-while):</strong> Repeating a block of code multiple times.</li></ul><p><strong>Functions:</strong> Understanding how to create reusable blocks of code (functions or methods) to perform specific tasks is important. This promotes code organization and reduces redundancy. Key concepts include function parameters (inputs), return values (outputs), and scope (visibility of variables).</p><p><strong>Object-Oriented Programming (OOP)</strong></p><p>It is strictly required for all full-stack roles, OOP is a powerful paradigm that helps organize complex code. You have to master Key OOP concepts like:</p><ul><li><strong>Classes and Objects:</strong> Creating blueprints (classes) for objects that encapsulate data (attributes) and behavior (methods).</li><li><strong>Inheritance:</strong> Creating new classes based on existing ones, inheriting their properties and methods.</li><li><strong>Polymorphism:</strong> The ability of objects of different classes to respond to the same method call in their own specific ways.</li><li><strong>Encapsulation:</strong> Hiding the internal implementation details of an object and exposing only a public interface.</li></ul><h3>2. Master Front-End Development</h3><p>Once you understand programming basics, move on to front-end development. Begin with <strong>HTML</strong>, <strong>CSS</strong>, and <strong>JavaScript</strong>. After that, you can explore front-end libraries and frameworks like <strong>React</strong>, <strong>Angular</strong>, and <strong>Tailwind CSS</strong> a CSS utility framework. These tools will help you to build modern, interactive web applications.</p><h3>2.1. HTML (HyperText Markup Language)</h3><p>HTML is the foundation of any web page. It is a markup language used to structure content on the web. Start learning the following concepts of HTML:</p><ul><li><strong>Learn the basics</strong>: Understand HTML elements and tags such as <code>&lt;h1&gt;</code> for headings, <code>&lt;p&gt;</code> for paragraphs, and <code>&lt;div&gt;</code> for containers.</li><li><strong>Forms</strong>: Master form elements like <code>&lt;input&gt;</code>, <code>&lt;textarea&gt;</code>, and <code>&lt;button&gt;</code> to accept user input, and learn about form validation techniques.</li><li><strong>Semantic HTML</strong>: Use semantic tags like <code>&lt;article&gt;</code>, <code>&lt;section&gt;</code>, <code>&lt;header&gt;</code>, and <code>&lt;footer&gt;</code> to improve accessibility and SEO.</li><li><strong>Attributes</strong>: Learn to add properties to elements using attributes such as <code>id</code>, and <code>class</code>.</li><li><strong>Links and Media</strong>: Understand how to embed links (<code>&lt;a&gt;</code>), images (<code>&lt;img&gt;</code>), videos (<code>&lt;video&gt;</code>), and audio (<code>&lt;audio&gt;</code>) to the webpage.</li></ul><h3>2.2. CSS (Cascading Style Sheets)</h3><p>CSS is used to style HTML elements and control the visual appearance of a web page.</p><ul><li><strong>Selectors</strong>: Learn to target HTML elements using different selectors (class, ID, attribute, pseudo-classes, etc.).</li><li><strong>Box Model</strong>: Understand how margins, borders, padding, and content work together to create the layout.</li><li><strong>Flexbox and Grid</strong>: Master modern layout techniques like Flexbox and CSS Grid to design responsive and flexible layouts.</li><li><strong>Responsive Design</strong>: Use media queries to ensure your designs look great on all devices (mobile, tablet, desktop).</li><li><strong>Styling Techniques</strong>:<ul><li>Play around with Colors, fonts, and typography.</li><li>Learn Animations and transitions for adding interactivity.</li><li>Learn to use Custom properties (CSS variables) for reusable and maintainable styles.</li></ul></li></ul><h3>2.3. JavaScript</h3><p>JavaScript is the programming language that brings interactivity to web pages. Master the following Important concepts of Java Script:</p><ul><li><strong>DOM Manipulation</strong>: Learn how to access and modify HTML elements dynamically using the Document Object Model (DOM).</li><li><strong>Event Handling</strong>: Understand how to add interactivity by handling user events like clicks, keypresses, and form submissions.</li><li><strong>APIs and AJAX</strong>: Learn to fetch data from external APIs and update web pages dynamically without reloading them.</li><li><strong>ES6+ Features</strong>: Master modern JavaScript syntax, including arrow functions, template literals, destructuring, and promises.</li><li><strong>Browser Storage</strong>: Understand how to store and retrieve data using local storage, session storage, and cookies.</li></ul><h3>Front-End Libraries and Frameworks</h3><p>Once you have a good understanding of HTML, CSS, and JavaScript, you can move on to learning popular front-end libraries and frameworks. These tools make it easier to build and manage complex user interfaces.</p><h3>2.4. Tailwind CSS</h3><p>Tailwind CSS is a utility-first CSS framework that allows you to quickly style your application by using pre-defined utility classes directly in your HTML or JSX.</p><ul><li><strong>Utility-First Approach</strong>: Instead of writing custom CSS, you will use classes to style elements. For example, <code>bg-blue-500</code> for a blue background or <code>p-4</code> for padding.</li><li><strong>Responsive Design</strong>: Easily build responsive layouts using breakpoints like <code>sm</code>, <code>md</code>, <code>lg</code>, and <code>xl</code>. For example, <code>sm:p-2 md:p-4</code> applies different padding on smaller or larger screens.</li><li><strong>Custom Themes</strong>: Tailwind allows you to extend its default design system with your own colors, spacing, and typography using the <code>tailwind.config.js</code> file.</li><li><strong>Flexbox and Grid Utilities</strong>: Quickly build layouts using utilities like <code>flex</code>, <code>grid</code>, <code>gap</code>, and <code>justify-center</code>.</li><li><strong>Plugins</strong>: Tailwind has an ecosystem of plugins, such as typography, forms, and animations, to further enhance its capabilities.</li><li><strong>Productivity</strong>: Tailwind speeds up development by reducing the need to write custom CSS. This makes it especially useful for prototyping and creating consistent designs across projects.</li></ul><h3>2.5. React.js</h3><p>React.js, developed by Facebook, is one of the most popular front-end libraries for building user interfaces.</p><ul><li><strong>Component-Based Architecture</strong>: Learn how to break down your UI into reusable components.</li><li><strong>JSX</strong>: Understand how to write HTML-like syntax within JavaScript to define UI elements.</li><li><strong>State Management</strong>: Learn how to manage and update the state of your application with React's <code>useState</code> and <code>useReducer</code> hooks.</li><li><strong>Props</strong>: Learn to pass data between components using props.</li><li><strong>React Router</strong>: Understand how to handle client-side routing for single-page applications (SPAs).</li><li><strong>Hooks</strong>: Explore React hooks like <code>useEffect</code> for side effects and <code>useContext</code> for sharing state.</li></ul><h3>2.6. Angular</h3><p>Angular, developed by Google, is a full-fledged front-end framework for building scalable and feature-rich web applications.</p><ul><li><strong>TypeScript</strong>: Angular is built with TypeScript, so learn the basics of TypeScript before learning Angular.</li><li><strong>Modules</strong>: Understand how Angular organizes code into modules.</li><li><strong>Components and Templates</strong>: Learn to create components and design their templates.</li><li><strong>Data Binding</strong>: Explore one-way and two-way data binding techniques, which are widely used.</li><li><strong>Directives</strong>: Learn to use built-in directives like <code>ngFor</code> and <code>ngIf</code> to manipulate DOM elements.</li><li><strong>Services and Dependency Injection</strong>: Learn how to use services for sharing data and functionality across components.</li><li><strong>Routing and Navigation</strong>: Understand Angular's routing system for building SPAs.</li></ul><h3>3. Dive Into Back-End Development</h3><p>With a strong front-end foundation, you can now shift your focus to the back-end. Back-end development involves managing the server, database, and application logic that power your web applications. Start by learning a server-side programming language and its frameworks, learn to integrate databases, and write APIs to enable seamless communication between the front-end and back-end.</p><h3><strong>3.1. Node.js and Express.js (JavaScript Runtime)</strong></h3><p>If you’re already comfortable with JavaScript, stepping into back-end development with <strong>Node.js</strong> and <strong>Express.js</strong> is a logical choice. Node.js allows you to run JavaScript on the server side, while Express.js is a lightweight framework that simplifies building web applications and APIs.</p><h3><strong>3.1.1. Node.js</strong>: The Foundation</h3><p>Node.js is a <strong>runtime environment</strong> built on Chrome's V8 JavaScript engine. It enables you to use JavaScript outside the browser, making it possible to create full-stack applications with a single programming language.</p><ul><li><strong>Why Choose Node.js?</strong><ul><li><strong>Asynchronous and Non-blocking</strong>: Node.js uses an event-driven model, which makes it highly efficient for handling multiple simultaneous connections.</li><li><strong>Single Language</strong>: Write both front-end and back-end in JavaScript, streamlining the development process.</li><li><strong>Large Ecosystem</strong>: The Node Package Manager (NPM) provides access to thousands of libraries and modules.</li><li><strong>Best Suited For</strong>: Real-time applications like chat apps, gaming servers, or collaborative tools, as well as lightweight APIs and microservices.</li></ul></li><li><strong>Core Concepts to Learn in Node.js</strong>:<ul><li>Event loop and asynchronous programming (callbacks, promises, <code>async/await</code>).</li><li>Handling HTTP requests and responses with Node.js modules like <code>http</code>.</li><li>File system operations and working with streams and buffers.</li><li>Using Node.js to connect to databases like MongoDB or MySQL.</li></ul></li></ul><h3><strong>3.1.2. Express.js</strong>: Simplifying Node.js Development</h3><p>Express.js is a fast, unopinionated, and minimalist web framework built for Node.js. It provides tools to handle routing, middleware, and request/response logic, making back-end development easier and more organized.</p><ul><li><strong>Why Choose Express.js?</strong><ul><li><strong>Simplifies Routing</strong>: Express makes defining and handling routes straightforward, with support for RESTful API design.</li><li><strong>Middleware Support</strong>: Add custom logic or pre-built modules (like authentication, error handling, or logging) between request and response cycles.</li><li><strong>Customizable</strong>: Allows for flexible architecture and choice of tools/libraries.</li><li><strong>Best Suited For</strong>: Building scalable APIs, single-page applications, and server-side rendered applications.</li></ul></li><li><strong>Core Concepts to Learn in Express.js</strong>:<ul><li>Setting up a basic Express server and defining routes.</li><li>Handling different HTTP methods (GET, POST, PUT, DELETE).</li><li>Using middleware for tasks like authentication, logging, or data validation.</li><li>Serving static files and creating dynamic pages with templating engines like Pug or EJS.</li><li>Building RESTful APIs and integrating them with front-end frameworks.</li></ul></li></ul><h3><strong>3.2. Django or Flask Framework</strong></h3><p>If Python is your preferred programming language, <strong>Django</strong> and <strong>Flask</strong> are two of the most popular frameworks for back-end development. Both frameworks simplify the process of building robust, scalable, and secure web applications, but they cater to different needs.</p><h3><strong>3.2.1. Django</strong>: The "Batteries-Included" Framework</h3><p>Django is a high-level framework designed to let you focus on writing your application without worrying about reinventing the wheel. It comes with a lot of built-in tools that make development faster and more efficient.</p><ul><li><strong>Why Choose Django?</strong><ul><li><strong>All-in-One Solution</strong>: Django includes features like an ORM (Object Relational Mapper), authentication, admin panel, and URL routing right out of the box.</li><li><strong>Security</strong>: Django is built with security in mind, helping protect against common vulnerabilities like SQL injection, cross-site scripting (XSS), and cross-site request forgery (CSRF).</li><li><strong>Rapid Development</strong>: Its "batteries-included" philosophy lets you build a fully functional app quickly.</li><li><strong>Best Suited For</strong>: Complex projects with multiple features, such as e-commerce platforms, social networks, or large content management systems.</li></ul></li><li><strong>Core Concepts to Learn in Django</strong>:<ul><li>Setting up a Django project and app structure.</li><li>Using the built-in admin interface to manage data.</li><li>Defining models and connecting to a database using Django's ORM.</li><li>Creating dynamic templates with Django’s templating engine.</li><li>Writing views and mapping URLs.</li></ul></li></ul><h3><strong>3.2.2. Flask</strong>: The Lightweight and Flexible Option</h3><p>If you prefer a minimalistic and flexible approach, Flask might be the right choice. It’s a microframework, meaning it provides the essentials to get started but allows you to pick and choose additional tools or libraries based on your needs.</p><ul><li><strong>Why Choose Flask?</strong><ul><li><strong>Lightweight and Simple</strong>: Flask is minimal by design, giving you full control over your application structure.</li><li><strong>Customizable</strong>: Unlike Django, Flask doesn’t impose a lot of built-in functionality. This makes it great for small, custom projects or developers who like to build things their way.</li><li><strong>Best Suited For</strong>: Prototyping, smaller projects, or when you want to have complete control over your application stack.</li></ul></li><li><strong>Core Concepts to Learn in Flask</strong>:<ul><li>Setting up a basic Flask application and understanding the project structure.</li><li>Using Flask's routing system to map URLs to functions.</li><li>Rendering templates using Jinja2 (Flask’s templating engine).</li><li>Integrating databases with extensions like SQLAlchemy.</li><li>Building REST APIs with Flask.</li></ul></li></ul><h3><strong>3.2.3. Which One Should You Choose?</strong></h3><p>The choice between Django and Flask largely depends on the project requirements and your personal preference:</p><ul><li>If you’re building something complex or need a lot of built-in functionality to save time, go with <strong>Django</strong>.</li><li>If you’re working on a small or highly customized project and want full control, <strong>Flask</strong> might be a better fit.</li></ul><h3><strong>3.3. Spring Boot Framework</strong></h3><p>If you're inclined towards Java for back-end development, then <strong>Spring Boot Framework</strong> is a powerful and widely used option. It simplifies the development of production-ready, scalable, and robust applications. Spring Boot removes much of the boilerplate code and configuration, enabling developers to focus on writing business logic.</p><ul><li><strong>Why Choose Spring Boot?</strong><ul><li><strong>Rapid Development</strong>: Provides built-in configurations and tools to get your application up and running quickly.</li><li><strong>Microservices Ready</strong>: Ideal for building microservices architectures with features like embedded servers, easy deployment, and seamless integration with cloud platforms.</li><li><strong>Production-Ready</strong>: Comes with features like health monitoring, metrics, and externalized configuration out of the box.</li><li><strong>Strong Ecosystem</strong>: Integrates well with other Spring modules like Spring Data (for database access), Spring Security, and Spring Cloud.</li></ul></li><li><strong>Core Concepts to Learn in Spring Boot</strong>:<ol><li><strong>Dependency Injection</strong>:<ul><li>Understand how Spring Boot uses dependency injection (DI) to manage objects and reduce tight coupling in your code.</li></ul></li><li><strong>RESTful APIs</strong>:<ul><li>Learn to build REST APIs using annotations like <code>@RestController</code>, <code>@GetMapping</code>, <code>@PostMapping</code>, etc.</li></ul></li><li><strong>Embedded Servers</strong>:<ul><li>Spring Boot includes embedded servers like Tomcat or Jetty, so you can run your application without deploying it separately.</li></ul></li><li><strong>Database Integration</strong>:<ul><li>Use Spring Data JPA to interact with relational databases, and tools like Hibernate for ORM (Object Relational Mapping).</li></ul></li><li><strong>Configuration and Profiles</strong>:<ul><li>Learn how to externalize configurations with <code>application.properties</code> or <code>application.yml</code> and manage environments using profiles (e.g., dev, test, production).</li></ul></li><li><strong>Spring Boot Actuator</strong>:<ul><li>Use Actuator to monitor application health, gather metrics, and manage operational concerns.</li></ul></li><li><strong>Security</strong>:<ul><li>Learn to Implement authentication and authorization with Spring Security.</li></ul></li></ol></li></ul><h3>4. Understand Database Management</h3><p>Learn how to manage data using databases. Start with relational databases (SQL) and then explore NoSQL options. Practice by building small applications that interact with a database to store and retrieve data. Apart from this, you should also learn data modeling i.e you should be able to create UML class diagrams of your project representing all the tables and their relations.</p><h3><strong>4.1. Relational Databases</strong> (SQL-based)</h3><p>Relational databases use structured tables with relationships between them, making them suitable for applications with complex data models.</p><ul><li>Examples: <strong>MySQL</strong>, <strong>PostgreSQL</strong>, <strong>SQLite</strong>.</li><li><strong>Core Concepts to be learned</strong>:<ul><li>Writing SQL queries (SELECT, INSERT, UPDATE, DELETE).</li><li>Joining tables to retrieve related data.</li><li>Database normalization and schema design.</li><li>Indexing for performance optimization.</li></ul></li></ul><h3><strong>4.2. Non-Relational Databases</strong> (NoSQL)</h3><p>NoSQL databases are designed for flexibility and scalability, making them ideal for applications with unstructured or rapidly changing data.</p><ul><li>Examples: <strong>MongoDB</strong>, <strong>Cassandra</strong>, <strong>Redis, Neo4j</strong></li><li><strong>Core Concepts to be learned</strong>:<ul><li>Storing data as key-value pairs, documents (JSON), or graphs.</li><li>Querying NoSQL databases using native methods (e.g., MongoDB's <code>find()</code>).</li><li>Managing collections, documents, and indexes.</li></ul></li></ul><h3>5. Build Real World Projects</h3><p>The best way to learn is by doing. Start building projects that challenge you to use both front-end and back-end technologies. This could be anything from a simple to-do app to a more complex social media platform. Projects will help you understand how to integrate all parts of the stack and solve real-world problems.</p><p><strong>Here are a few examples:</strong></p><ul><li><strong>Blog Platform</strong>: A basic CRUD application for managing posts and comments.</li><li><strong>E-commerce Backend</strong>: Build APIs for managing products, users, orders, and payments.</li><li><strong>Authentication System</strong>: Implement user registration, login, and role-based access control.</li></ul><h3>6. Cloud Deployment</h3><p>Once you develop the full-stack application and test locally it’s time to make your application accessible to users anywhere in the world. For that, you have to deploy your application on cloud platforms.</p><h3><strong>6.1. Key Steps for Cloud Deployment</strong></h3><ol><li><strong>Prepare Your Application</strong><ul><li>Ensure your application is production-ready.</li><li>Minimize hardcoded values and configure environment variables for sensitive data like API keys and database credentials.</li><li>Test the application extensively in your local environment.</li></ul></li><li><strong>Choose a Cloud Provider</strong><ul><li>Select a cloud service provider based on your requirements, budget, and familiarity. Below is a breakdown of the top three providers:<ul><li><strong>AWS</strong>: Known for its extensive services and global infrastructure.</li><li><strong>GCP</strong>: Renowned for its data analytics and AI/ML tools.</li><li><strong>Azure</strong>: Integrated with Microsoft tools, ideal for enterprise applications.</li></ul></li></ul></li><li><strong>Set Up a Cloud Account</strong><ul><li>Create an account with your chosen provider.</li><li>Understand their pricing structure to optimize costs.</li></ul></li><li><strong>Containerize Your Application</strong><ul><li>Use <strong>Docker</strong> to containerize your application. Containers package your application and its dependencies, ensuring consistency across different environments.</li><li>Create a <code>Dockerfile</code> that specifies how to build and run your application.</li><li>Test the container locally using Docker Compose.</li></ul></li><li><strong>Choose a Deployment Service</strong><ul><li>Use a managed service provided by your cloud platform to deploy your application. Common services include:<ul><li>AWS Elastic Beanstalk, EC2, or ECS.</li><li>GCP App Engine or Kubernetes Engine.</li><li>Azure App Services or AKS (Azure Kubernetes Service).</li></ul></li></ul></li><li><strong>Deploy Your Application</strong><ul><li>Push your code to a version control system like GitHub.</li><li>Configure the deployment pipeline using tools like <strong>GitHub Actions</strong>, <strong>Jenkins</strong>, or <strong>GitLab CI/CD</strong>.</li><li>Deploy the application to your chosen cloud service.</li></ul></li><li><strong>Set Up a Domain and SSL</strong><ul><li>Purchase a domain or use a free one provided by the cloud provider.</li><li>Set up DNS records to point to your application.</li><li>Enable SSL/TLS to secure communication between users and your application.</li></ul></li><li><strong>Monitor and Scale</strong><ul><li>Use monitoring tools like AWS CloudWatch, GCP Monitoring, or Azure Monitor to track application performance.</li><li>Configure auto-scaling policies to handle traffic spikes.</li></ul></li></ol><h2>Common Mistakes to Avoid</h2><ul><li><strong>Focusing on Just One Part</strong>: Many aspiring developers fall into the trap of focusing solely on either front-end or back-end development. As a full-stack developer, you need to balance both sides.</li><li><strong>Skipping the Basics</strong>: Don’t rush into frameworks and libraries without understanding the fundamentals of programming and web development.</li><li><strong>Not Building Enough Projects</strong>: Simply learning the theory is not enough. Practical experience is essential to becoming a proficient full-stack developer.</li></ul><h2>Coding Shuttle's Recommended Course</h2><p>If you are looking for a full-stack development course in a structured format then <strong>Coding Shuttle's Full-Stack Development Course is the most recommended course</strong> for you. This structured program is designed to guide you from the fundamentals to advanced concepts, covering <strong>React</strong> (front-end) and <strong>Spring Boot</strong> (back-end) while building <strong>production-ready,</strong> <strong>real-world</strong> projects and deploying them on a cloud.</p><p>Checkout → <a href="https://www.codingshuttle.com/courses/batchBundle/java-react-full-stack/">Coding Shuttle Full-Stack Course</a></p><h2>Conclusion</h2><p>Becoming a full-stack developer is a rewarding journey that requires dedication, continuous learning, and hands-on practice. By mastering both front-end and back-end technologies, you'll be equipped to build fully functional web applications. Whether you're aiming to build your own startups, work for established companies, or freelance, being a full-stack developer opens a world of opportunities.</p><p>Start with the basics, build projects, and keep learning. The path might seem challenging at times, but with persistence, you’ll find yourself growing into a versatile and in-demand developer ready to take on any project.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Full Stack development</category>
            <category>Full Stack development guide</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/how_to_become_full_stack_developer_1201ccd725.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Step by Step guide to Deploy a Spring Boot App on AWS Elastic Beans stalk]]></title>
            <link>https://www.codingshuttle.com/blogs/step-by-step-guide-to-deploy-a-spring-boot-app-on-aws-elastic-beans-stalk</link>
            <guid>https://www.codingshuttle.com/blogs/step-by-step-guide-to-deploy-a-spring-boot-app-on-aws-elastic-beans-stalk</guid>
            <pubDate>Mon, 06 Jan 2025 12:22:15 GMT</pubDate>
            <description><![CDATA[This step-by-step guide walks you through deploying a Spring Boot application on AWS Elastic Beanstalk. It covers the essential setup, including configuring the environment, IAM roles, and database integration, ensuring a seamless deployment. By the end, you'll have your Spring Boot app running on AWS with auto-scaling and load balancing capabilities.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p>In today's world, cloud computing has become a crucial part of modern web application deployment. Among the many cloud platforms available, AWS (Amazon Web Services) stands out with its powerful, scalable, and reliable services. One of the easiest ways to deploy and manage your Java Spring Boot application on AWS is by using <strong>AWS Elastic Beanstalk</strong>.</p><p>AWS Elastic Beanstalk abstracts away much of the complex infrastructure management while offering a simple platform to deploy, manage, and scale applications. In this guide, we will walk you through a step-by-step process to deploy your Spring Boot application on AWS Elastic Beanstalk.</p><h2>Initial Setup to be done</h2><ol><li>First of all, visit aws website and create your AWS account If you don’t have an account on AWS.</li><li>Before we move forward to deploy our spring boot app on AWS Elastic Beanstalk make sure you have created postgres db-instance on AWS RDS.</li><li>Also, you need to be ready with your spring boot project, In this blog, I am going to deploy my library-management spring boot application on AWS Elastic Beanstalk. You will need to just build the jar file of your project and simply deploy it on Elastic Beanstalk.</li></ol><h2>Steps to create Elastic Beanstalk environment on aws</h2><p>Login to your aws account and open aws services from there select Elastic Beanstalk service and click on create application.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/1_16e6d6e092.png" alt="AWS Elastic Beanstalk Service" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_1_16e6d6e092.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_1_16e6d6e092.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_1_16e6d6e092.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_1_16e6d6e092.png 1000w," sizes="100vw"><figcaption>AWS Elastic Beanstalk Service</figcaption></figure><p>After clicking on create application button you will be redirected to the configure environment page and this is step-1, you have to complete all 6 steps to setup your AWS Elastic Beanstalk environment.</p><h3>Step 1 :- Configure environment</h3><p>In step 1 you have to configure your environment. In Environment tier section just select web server environment this says that your elastic beanstalk environment will run a website, web application, or web API that serves HTTP requests.</p><p>In Additional infromation section give application name, since we are deploying our spring boot library-management application I will give the name as library-management-service</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/2_60e2f9973c.png" alt="Configure Environment" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_2_60e2f9973c.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_2_60e2f9973c.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_2_60e2f9973c.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_2_60e2f9973c.png 1000w," sizes="100vw"><figcaption>Configure Environment</figcaption></figure><p>After giving application name the environment name will be automatically set based on the name you have provided for your application.</p><p>Basically elastic beanstalk creates environment to run you applications, you can have more than one applications under one environment.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/3_c9d2e83dc9.png" alt="Environment Information" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_3_c9d2e83dc9.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_3_c9d2e83dc9.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_3_c9d2e83dc9.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_3_c9d2e83dc9.png 1000w," sizes="100vw"><figcaption>Environment Information</figcaption></figure><p>In the Environment information section you have to also set the domain, with this domain you will be able to access your running spring boot application from anywhere. Just enter the domain name of your choice and click on check availability button to check if domain is available or not. This domain will be your load balancer url which is spinned by elastic beanstalk for you. You can also provide the environment description if you want, we will leave it empty.</p><p>Next is Platform section, in this we will select platform as Java and platform branch as Corretto 21 with platform version as 4.2.2 you can select the latest one.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/4_a5c99a6ab8.png" alt="Managed Platforms" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_4_a5c99a6ab8.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_4_a5c99a6ab8.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_4_a5c99a6ab8.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_4_a5c99a6ab8.png 1000w," sizes="100vw"><figcaption>Managed Platforms</figcaption></figure><p>Next is Application code section, here we will select sample application, by selecting this elastic beanstalk will deploy a sample application for us on starting the elastic beanstalk environment</p><p>Further we will see how to deploy our spring boot application instead of this sample application</p><p>In the next section (Presets) select Single instance (free tier eligible).</p><p>Afer doing this click on next button to move to next step.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/5_6c4453a112.png" alt="Application Code Info" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_5_6c4453a112.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_5_6c4453a112.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_5_6c4453a112.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_5_6c4453a112.png 1000w," sizes="100vw"><figcaption>Application Code Info</figcaption></figure><h3>Step 2 :- Configure service access</h3><p>Next step is one of the important step as we are going to set IAM roles (service roles) and IAM EC2 instance profiles this allows Elastic Beanstalk to create and manage your environment. Both the IAM role and instance profile must be attached to IAM managed policies that contain the required permissions.</p><p>To create a Instance profile go to IAM Roles in AWS and press create role button</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/6_8e92b74896.png" alt="IAM Roles" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_6_8e92b74896.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_6_8e92b74896.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_6_8e92b74896.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_6_8e92b74896.png 1000w," sizes="100vw"><figcaption>IAM Roles&nbsp;</figcaption></figure><p>After that you have to follow the 3 steps to create role for ec2</p><p>Step 1 - Select trusted entity Select AWS service as trusted entity and in use case select EC2 as use case and click on next button.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/7_2e2fd1f214.png" alt="Select Trusted Entity" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_7_2e2fd1f214.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_7_2e2fd1f214.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_7_2e2fd1f214.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_7_2e2fd1f214.png 1000w," sizes="100vw"><figcaption>Select Trudted Entity</figcaption></figure><p>Step 2 - Add permission</p><p>In step 2 select two permissions <strong>AWSElasticBeanstalkCustomPlatformforEC2Role and AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy</strong> and click on next button.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/8_c96a6724b5.png" alt="Permission Policies" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_8_c96a6724b5.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_8_c96a6724b5.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_8_c96a6724b5.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_8_c96a6724b5.png 1000w," sizes="100vw"><figcaption>Permission Policies</figcaption></figure><p>Step 3 - Name, review and create</p><p>In the last step give name to the role “<strong>aws-elasticbeanstalk-ec2-role</strong>” and review all the settings then click on create role</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/9_061e82229a.png" alt="Role Name" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_9_061e82229a.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_9_061e82229a.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_9_061e82229a.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_9_061e82229a.png 1000w," sizes="100vw"><figcaption>Role Name</figcaption></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/10_016256704b.png" alt="Permission Policy Summary" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_10_016256704b.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_10_016256704b.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_10_016256704b.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_10_016256704b.png 1000w," sizes="100vw"><figcaption>Permission Policy Summary</figcaption></figure><p><strong>After creating the role come back to your step 2 - Configure service access</strong></p><p>To create service role select Create and use new service role option.</p><p>And in EC2 instance profile we have to select the role which we created “<strong>aws-elasticbeanstalk-ec2-role</strong>”.</p><p>After doing this click on next button to move to next step.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/11_a920c550a5.png" alt="Configure Service Access" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_11_a920c550a5.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_11_a920c550a5.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_11_a920c550a5.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_11_a920c550a5.png 1000w," sizes="100vw"><figcaption>Configure Service Access</figcaption></figure><h3>Step 3 :- <strong>Set up networking, database, and tags</strong></h3><p>In the next step under the VPC section select the default VPC and under insthe tance settings section check on the Activated option to assign a public IP address to the Amazon EC2 instances in your environment.</p><p>Select all availability zones under Insrtance subnets to make your instance available in all zones.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/12_53a41739b7.png" alt="Instance settings" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_12_53a41739b7.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_12_53a41739b7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_12_53a41739b7.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_12_53a41739b7.png 1000w," sizes="100vw"><figcaption>Instance settings</figcaption></figure><p>The next section is the Database section we will not configure any DB here as we already have set our RDS instance. Also it is not recommended to configure DB here because if we delete our environment then we will loss our database too.</p><p>Next scroll down and simply click on next button.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/13_cd15256be4.png" alt="Database Configuration" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_13_cd15256be4.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_13_cd15256be4.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_13_cd15256be4.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_13_cd15256be4.png 1000w," sizes="100vw"><figcaption>Database Configuration</figcaption></figure><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/14_d5463d4204.png" alt="Database default settings" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_14_d5463d4204.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_14_d5463d4204.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_14_d5463d4204.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_14_d5463d4204.png 1000w," sizes="100vw"><figcaption>Database default settings</figcaption></figure><h3>Step 4:- <strong>Configure instance traffic and scaling</strong></h3><p>In the next step under instance section select root volume type as General Purpose 3 SSD.</p><p>Size 10 GB, IOPS 100, Throughput 125 MiB/s</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/15_dc574a7b4c.png" alt="Configure instance traffic and scaling" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_15_dc574a7b4c.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_15_dc574a7b4c.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_15_dc574a7b4c.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_15_dc574a7b4c.png 1000w," sizes="100vw"><figcaption>Configure instance traffic and scaling</figcaption></figure><p>Next in Amazon CloudWatch monitoring select interval as 5 minutes, this is the time interval between when metrics are reported from the EC2 instances.</p><p>Keep IMDS 1 (<strong>Instance metadata service</strong>) as deactivated. Your environment's platform supports both IMDSv1 and IMDSv2. To enforce IMDSv2, deactivate IMDSv1.</p><p>In EC2 security group section, select default security groups to control traffic.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/16_2c5bf73427.png" alt="EC2 security groups" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_16_2c5bf73427.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_16_2c5bf73427.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_16_2c5bf73427.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_16_2c5bf73427.png 1000w," sizes="100vw"><figcaption>EC2 security groups</figcaption></figure><p>Next scroll down you will see Capacity section, We have to configure the compute capacity of your environment and auto scaling settings to optimize the number of instances used.</p><p>Select environment type as load balanced. You can develop and test an application in a single-instance environment to save costs and then upgrade to a load-balanced environment when the application is ready for production.</p><p>Specify the min and max number of instances you want in environment on scaling up and down, I have selected min as 1 and max 4, so that up-to 4 instances will be spinned as the traffic increases basically the load/CPU utilization of instances increases.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/17_7147f2e3ea.png" alt="Auto scaling group" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_17_7147f2e3ea.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_17_7147f2e3ea.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_17_7147f2e3ea.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_17_7147f2e3ea.png 1000w," sizes="100vw"><figcaption>Auto scaling group</figcaption></figure><p>Select On Demand Instances option under Fleet compositions, scroll down and rest keep all default</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/18_daefe86f37.png" alt="Fleet Composition" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_18_daefe86f37.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_18_daefe86f37.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_18_daefe86f37.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_18_daefe86f37.png 1000w," sizes="100vw"><figcaption>Fleet Composition</figcaption></figure><p>After scrolling downyou will see Architecture section, select x86_64. The processor architecture determines the instance types that are made available. You can’t change this selection after you create the environment.</p><p>Under Instance Types choose t3.micro or any other as per your requirement</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/19_02895e5f4d.png" alt="Architecture and Instance types" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_19_02895e5f4d.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_19_02895e5f4d.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_19_02895e5f4d.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_19_02895e5f4d.png 1000w," sizes="100vw"><figcaption>Architecture and Instance types</figcaption></figure><p>Scroll down and in scaling cooldown keep 150 seconds</p><p>Next you will see the scaling triggers section, under that keep the metric parameter CPUUtilization that is monitored to determine if the environment's capacity is too low or too high.</p><p>Choose how the metric is interpreted as Average under Statistic and select unit as Percent. Select 1 min for period between metric evaluations.</p><p>Select 5 min for the amount of time a metric can exceed a threshold before triggering a scaling operation under Breach duration.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/20_fd70a6aab7.png" alt="Scaling triggers" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_20_fd70a6aab7.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_20_fd70a6aab7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_20_fd70a6aab7.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_20_fd70a6aab7.png 1000w," sizes="100vw"><figcaption>Scaling triggers</figcaption></figure><p>Next scroll down and select upper threshold as 80 and lower threshold as 40 with Scale up increment 1 and Scale down increment -1 .</p><p>Overall this settings says if the CPU utilization is beyond 80% over a period of 5 min when it is checked every 1 min it will scale up 1 instance. Similarly scale down by 1 instance if CPU utilization is below 40%.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/21_01ea7a330e.png" alt="Scaling trriggers settings" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_21_01ea7a330e.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_21_01ea7a330e.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_21_01ea7a330e.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_21_01ea7a330e.png 1000w," sizes="100vw"><figcaption>Scaling trriggers settings</figcaption></figure><p>Next Scroll down you will get Load balancer network settings, Keep visibility as public, you can make your load balancer internal if your application serves requests only from connected VPCs. Public load balancers serve requests from the Internet. We will keep public.</p><p>Also select all Availability zones for your load balancer subnets.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/22_3f6f18a9d0.png" alt="Load balancer network settings" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_22_3f6f18a9d0.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_22_3f6f18a9d0.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_22_3f6f18a9d0.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_22_3f6f18a9d0.png 1000w," sizes="100vw"><figcaption>Load balancer network settings</figcaption></figure><p>Next scroll down and select Application load balancer and dedicated, Under listeners keep default port as 80, protocol HTTP and enabled.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/23_7977d08e2c.png" alt="Load balancer types" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_23_7977d08e2c.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_23_7977d08e2c.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_23_7977d08e2c.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_23_7977d08e2c.png 1000w," sizes="100vw"><figcaption>Load balancer types</figcaption></figure><p>Next in processes you will see the health check and default it is “/” path, for that in your project you have to add controller for health check also.</p><pre><code class="language-java">@RestController
public class HealthCheckController {
    @GetMapping("/")
    public ResponseEntity&lt;String&gt; healthCheckController(){
        return ResponseEntity.ok("Ok");
    }
}</code></pre><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/24_518b3ddb81.png" alt="Health check path" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_24_518b3ddb81.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_24_518b3ddb81.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_24_518b3ddb81.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_24_518b3ddb81.png 1000w," sizes="100vw"><figcaption>Health check path</figcaption></figure><p>Next scroll down and keep everything default, you can configure Elastic Load Balancing to capture logs with detailed information about requests sent to your Load Balancer. Logs are stored in Amazon S3 by enbling it.</p><p>After that click next button to go to next step.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/25_f62cc0ce24.png" alt="Log files access" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_25_f62cc0ce24.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_25_f62cc0ce24.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_25_f62cc0ce24.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_25_f62cc0ce24.png 1000w," sizes="100vw"><figcaption>Log files access</figcaption></figure><h3>Step 5:- <strong>Configure updates, monitoring, and logging</strong></h3><p>In the next step, in monitoring section select basic monitoring and keep rest as default.</p><p>You can activate managed platform updates to apply platform updates automatically during a weekly maintenance window that you choose. Your application stays available during the update process. For now we will not activate, you can also give email to receive email notifications for important events from your environment.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/26_faf1d8cd57.png" alt="Managed platform updates" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_26_faf1d8cd57.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_26_faf1d8cd57.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_26_faf1d8cd57.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_26_faf1d8cd57.png 1000w," sizes="100vw"><figcaption>Managed platform updates</figcaption></figure><p>Next scroll down you will see Rolling updates and deployments, In Application deployments section Choose all at once Amazon Elastic Beanstalk propogates source code changes and software configuration updates also choose Fixed Batch size type. Rest keep all default.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/27_992adcf428.png" alt="Rolling updates and deployments" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_27_992adcf428.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_27_992adcf428.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_27_992adcf428.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_27_992adcf428.png 1000w," sizes="100vw"><figcaption>Rolling updates and deployments</figcaption></figure><p>Next scroll down and you will get Environment properties settings under Platform software section, here you have to add all the environment properties required for your spring boot application and click next button, rest click all default under Platform software section.</p><p>The following properties will be passed in the application as environment properties, After doing so click on next button to go to finat step.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/28_c23e8f3b35.png" alt="Environment properties" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_28_c23e8f3b35.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_28_c23e8f3b35.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_28_c23e8f3b35.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_28_c23e8f3b35.png 1000w," sizes="100vw"><figcaption>Environment properties</figcaption></figure><p>Note:- make sure that your application.propertie files has the same environment variables which you have created.</p><pre><code class="language-java">spring.application.name=librarymanagement

#Port configuration
server.port=8081

#DB configuration
spring.datasource.url=jdbc:postgresql://${DB_HOST_URL}:5432/${DB_NAME}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true</code></pre><h3>Step 6:- Review</h3><p>On the last step review all configuration and click on submit button.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/29_b33956e55f.png" alt="Review" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_29_b33956e55f.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_29_b33956e55f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_29_b33956e55f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_29_b33956e55f.png 1000w," sizes="100vw"><figcaption>Review</figcaption></figure><p>After that Elastic Beanstalk will launch your environment, it takes few minutes to launch the environment .</p><p>Once the environment is launched successfully, you can see that health status is green under Environment overview section, you can verify that the simple web application is running by just pasting the url in browser which is present under Domain in Environment overview.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/30_dd8afbc065.png" alt="Envrionment launched" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_30_dd8afbc065.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_30_dd8afbc065.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_30_dd8afbc065.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_30_dd8afbc065.png 1000w," sizes="100vw"><figcaption>Envrionment launched</figcaption></figure><p>You will see this page once you paste the domain url in browser. This is the sample application which elastic beanstalk deployed for us. Now we have to deploy our spring boot library-management application in this environment.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/31_c6f10e8548.png" alt="Sample web application " srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_31_c6f10e8548.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_31_c6f10e8548.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_31_c6f10e8548.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_31_c6f10e8548.png 1000w," sizes="100vw"><figcaption>Sample web application&nbsp;</figcaption></figure><h2>Deploying spring boot application on Elastic Beanstalk environment</h2><p>To deploy you spring boot application on elastic beanstalk environment, first build the jar file of your spring boot application.</p><p>Go to your elastic beanstalk environment in aws and click on upload deploy button which is present at top right corner.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/32_6f7e881f7f.png" alt="Library management service environment" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_32_6f7e881f7f.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_32_6f7e881f7f.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_32_6f7e881f7f.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_32_6f7e881f7f.png 1000w," sizes="100vw"><figcaption>Library management service environment</figcaption></figure><p>You will get this pop-up click on choose file button and select the jar file of your spring boot application. You will get jar file under the target folder after doing maven package.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/33_b2d67c42be.png" alt="Upload and deploy spring boot application" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_33_b2d67c42be.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_33_b2d67c42be.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_33_b2d67c42be.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_33_b2d67c42be.png 1000w," sizes="100vw"><figcaption>Upload and deploy spring boot application</figcaption></figure><p>In the version label give v1 and you can edit the deployment preferences, but we will keep the default one “<strong>Rolling</strong>” and click on deploy button.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/34_d77e8268dd.png" alt="Upload spring boot application" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_34_d77e8268dd.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_34_d77e8268dd.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_34_d77e8268dd.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_34_d77e8268dd.png 1000w," sizes="100vw"><figcaption>Upload spring boot application</figcaption></figure><p>After few minutes elastic beanstalk will deploy your spring boot application to ec2 instances.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/35_d84efa5644.png" alt="Environment overview after spring boot app deployment" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_35_d84efa5644.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_35_d84efa5644.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_35_d84efa5644.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_35_d84efa5644.png 1000w," sizes="100vw"><figcaption>Environment overview after spring boot app deployment</figcaption></figure><p>After successful deployment, you will be able to access the application by simply pasting the domain URL in browser and you will get the OK response from the Health Controller.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/36_7fc1b78f2b.png" alt="Ok Response from health controller" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_36_7fc1b78f2b.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_36_7fc1b78f2b.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_36_7fc1b78f2b.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_36_7fc1b78f2b.png 1000w," sizes="100vw"><figcaption>Ok Response from health controller</figcaption></figure><h2>Conclusion</h2><p>Deploying a Spring Boot application on AWS Elastic Beanstalk is a streamlined process that abstracts much of the complexity of infrastructure management. By following the steps outlined, you can set up a robust and scalable environment to host your application. AWS Elastic Beanstalk not only simplifies deployment but also offers flexibility in scaling and monitoring, making it an excellent choice for developers looking to focus on building applications rather than managing servers. With your application now live, you can leverage AWS's features to enhance performance and reliability as your needs grow.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>AWS Elastic Beanstalk</category>
            <category>Spring Boot Application deployment on AWS Cloud</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/awss_5e0ffffe0b.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 5 Spring Boot Training courses in 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/top-5-spring-boot-training-courses-in-2025</link>
            <guid>https://www.codingshuttle.com/blogs/top-5-spring-boot-training-courses-in-2025</guid>
            <pubDate>Mon, 06 Jan 2025 11:48:30 GMT</pubDate>
            <description><![CDATA[This blog highlights the top 5 Spring Boot courses to help developers, from beginners to seasoned professionals, master the framework and enhance their skills. Each course offers unique insights and hands-on experience, making them valuable resources for anyone looking to excel in Spring Boot and backend development.]]></description>
            <content:encoded><![CDATA[<p>2025 is here, and the IT job market is buzzing with demand for Spring Boot Java developers. Whether you're a seasoned developer aiming to level up your skills for a current project, exploring a career shift into backend development, or a fresh graduate eager to break into the tech world, mastering Spring Boot is a game-changer. The internet is flooded with Spring Boot courses, but finding truly up-to-date and relevant training can be a challenge. Thankfully, some exceptional resources are leading the way in 2025.</p><h2>Following are the top 5 spring boot training courses that you must check out in 2025.</h2><h3><strong>1. Spring Boot 0-100 Course by Anuj Sharma</strong></h3><p><strong>Platform</strong>:- Coding Shuttle website</p><p><a href="https://www.codingshuttle.com/courses/batchBundle/java-spring-boot-0-to-100/"><strong>Course Link</strong></a></p><p>A<strong>bout course</strong>:-</p><p>The Spring Boot 0-100 course by Anuj Sharma on Coding Shuttle is designed for developers of all experience levels, from freshers to seasoned professionals. It takes you on a comprehensive journey, starting with the fundamentals topics in spring boot and progressing to advanced topics like microservices and Kubernetes.</p><p>The course is divided into two phases (0-100), 0-1 covers essential concepts, while 1-100 dives into advanced topics, ensuring a strong foundation before tackling complex subjects. This course covers building industry-ready projects in the live classes that simulate real-world applications like Uber clone, LinkedIn clone, Airbnb clone and many more, which will give you valuable practical experience.</p><p>A key highlight of this course is its well-structured learning path, guiding learners systematically from fundamental concepts to advanced concepts and ensuring a comprehensive understanding.</p><p>The course was launched in June 2024, it has positive reviews across platforms like Quora, Reddit, and LinkedIn. The next cohort is currently ongoing, If you're serious about mastering Spring Boot and taking your development skills to the next level, the Spring Boot 0-100 course is a highly recommended investment in 2025.</p><h3><strong>2. Spring Boot 3, Spring 6 &amp; Hibernate for Beginners by</strong> Chad Darby</h3><p><strong>Platform</strong>:- Udemy</p><p><a href=" https://www.udemy.com/course/spring-hibernate-tutorial"><strong>Course Link</strong></a></p><p><strong>About course</strong>:-</p><p>This top-selling Udemy course by Chad Darby is a great choice for Java developers looking to master Spring Boot and Hibernate. Learn to build powerful Java applications with Spring Boot's efficient framework and Hibernate's seamless database interaction by developing a real-time project with Thymeleaf and Spring Boot, complete with CRUD (Create, Read, Update, Delete) database operations.</p><p>The course is fully up-to-date and covers the latest versions of Spring Boot 3, Spring 6, and Hibernate 6, including new content on Spring Boot 3, Spring Data JPA, Spring Data REST, and Thymeleaf, helping you quickly get up to speed with these technologies.</p><p>As a Udemy course, you'll benefit from lifetime access, allowing you to learn at your own pace and revisit sections as needed.</p><p>While the course is well-suited for beginners with basic Java experience, it also offers valuable knowledge for more seasoned developers. Spring Boot and Hibernate are powerful tools, and this course empowers Java programmers of all skill levels to build robust applications.</p><p>Overall, this comprehensive course by Chad Darby provides a solid foundation for mastering Spring Boot and Hibernate, making it a highly recommended starting point for Java developers seeking to enhance their application development skills.</p><h3><strong>3. Master Spring Boot 3 &amp; Spring Framework 6 with Java by Ranga Karanam</strong></h3><p><strong>Platform</strong>:- Udemy</p><p><a href="https://www.udemy.com/course/spring-boot-and-spring-framework-tutorial-for-beginners"><strong>Course Link</strong></a></p><p><strong>About course</strong>:-</p><p>This comprehensive course by Ranga Karanam on Udemy is ideal for beginner Java programmers who want to build their first full-stack application. You'll learn the fundamentals of Spring Framework and Spring Boot, along with how to create web applications, build robust RESTful APIs for data exchange, and integrate Spring Boot and React to build modern full-stack applications.</p><p>Since this is also a Udemy course, you’ll benefit from lifetime access, allowing you to learn at your own pace and revisit sections as needed.</p><p>Overall, if you're a beginner Java developer looking to build real-world applications with Spring Boot, React, and AWS, this course is a highly recommended starting point.</p><h3><strong>4. Java Spring Framework 6 with Spring Boot 3 by Navin Reddy</strong></h3><p><strong>Platform</strong>:- Udemy</p><p><a href="https://www.udemy.com/course/spring-5-with-spring-boot-2/"><strong>Course Link</strong></a></p><p><strong>About course</strong>:-</p><p>This course by Navin Reddy on Udemy is a perfect starting point for anyone new to Java who wants to explore and learn Spring Framework and Spring Boot. It covers everything from the fundamentals of Java programming to advanced Spring Boot concepts.</p><p>Since this is also a Udemy course, you'll benefit from lifetime access, allowing you to learn at your own pace and revisit sections as needed.</p><p>Overall, this is a well-regarded course for beginners looking to kickstart their Java Spring Boot development journey.</p><h3><strong>5. Building Scalable Java Microservices with Spring Boot and Spring Cloud by Google</strong></h3><p><strong>Platform</strong>:- Coursera</p><p><a href="https://www.coursera.org/learn/google-cloud-java-spring"><strong>Course Link</strong></a></p><p><strong>About course</strong>:-</p><p>This course equips you with the skills to design and build robust microservices applications using Spring Boot and Spring Cloud. You'll delve into the world of microservices, a software architecture ideal for the cloud with its focus on scalability and independent deployments.</p><p>Throughout the course, you'll gain hands-on experience by working with real-world Google Cloud services, including Cloud SQL, a managed relational database for your Java applications, with the option to migrate to Spanner, Google Cloud's globally distributed database; Cloud Pub/Sub, to implement efficient message exchange between your microservices; and Cloud Trace, to gain insights into application performance by learning distributed tracing techniques. You'll also explore additional Google Cloud services like Cloud Storage and App Engine for deployment.</p><p>This course will teach you to design and develop microservices using Spring Boot and Spring Cloud, manage application configuration with Spring Cloud Config, integrate Google Cloud services seamlessly into your applications.</p><p>This course is ideal for Java developers with basic experience and a general understanding of Google Cloud. It's particularly beneficial for those seeking to build scalable and cloud-native applications using microservices architecture.</p><p>By combining theoretical knowledge with practical labs, this comprehensive course equips you with the necessary skills to confidently build and deploy microservices on Google Cloud.</p><h2>Conclusion</h2><p>The demand for skilled Spring Boot developers is only growing, and these courses provide a fantastic opportunity to gain the in-demand skills you need. We hope this guide has helped you find a course that aligns with your learning goals. Take some time to explore the course links provided, consider your preferred learning pace, and start learning Spring Boot today!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot Courses</category>
            <category>Spring Boot Courses 2025</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/top_5_course_98f33c8694.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Why do the big tech companies choose Spring Boot to build their Microservice Application?]]></title>
            <link>https://www.codingshuttle.com/blogs/why-do-the-big-tech-companies-choose-spring-boot-to-build-their-microservice-application</link>
            <guid>https://www.codingshuttle.com/blogs/why-do-the-big-tech-companies-choose-spring-boot-to-build-their-microservice-application</guid>
            <pubDate>Mon, 06 Jan 2025 11:40:56 GMT</pubDate>
            <description><![CDATA[This blog explores why major tech companies like Netflix, Uber, and Intuit choose Spring Boot for their microservices applications. It highlights key benefits such as streamlined development, robust ecosystem support, cloud-native readiness, and scalability. Discover how Spring Boot's productivity-boosting features and strong community make it the go-to framework for large-scale systems.]]></description>
            <content:encoded><![CDATA[<p>In today's fast-paced tech landscape, building applications that are both agile and highly scalable is crucial. Microservices have become the go-to architectural pattern for achieving this, and among the many frameworks available, Spring Boot consistently emerges as a top choice, especially among industry giants. But what makes Spring Boot so popular with companies like Netflix, Uber, and Intuit? Let's explore the key reasons.</p><h2><strong>1. Streamlined Microservice Development: Less Boilerplate, More Business Logic</strong></h2><p>One of Spring Boot's most significant advantages is its simplicity. It significantly reduces boilerplate code and complex configurations, allowing developers to focus on what matters most: building core business logic. Features like auto-configuration and embedded servers mean less time spent on infrastructure setup and more time spent delivering value. This efficiency is a game-changer, especially in large-scale systems where speed and agility are essential.</p><h2><strong>2. A Robust Ecosystem That Just Works: Spring Cloud, Spring Data, and More</strong></h2><p>The Spring ecosystem is a comprehensive suite of tools and integrations that work seamlessly together, providing a powerful foundation for microservice architectures:</p><ul><li><strong>Spring Cloud:</strong> Offers crucial distributed system patterns such as service discovery (think Eureka or Consul), circuit breakers (like Hystrix or Resilience4j), and load balancing (Ribbon or Spring Cloud Load Balancer). These are essential for managing complex microservice deployments.</li><li><strong>Spring Data:</strong> Simplifies database interactions, abstracting away much of the repetitive data access code and supporting various data stores (relational, NoSQL, etc.).</li><li><strong>Spring Security:</strong> Provides robust security features for authentication, authorization, and protection against common vulnerabilities.</li></ul><p>Companies like <strong>Netflix</strong>, known for its massive streaming platform, rely heavily on Spring Boot and the Spring Cloud ecosystem to manage the complexity of its microservice architecture, ensuring high availability and scalability for millions of users.</p><h2><strong>3. Cloud-Native and Kubernetes Ready: Designed for Modern Deployments</strong></h2><p>Modern microservices are often deployed in cloud environments. Spring Boot is built with cloud-native principles in mind, offering seamless integration with leading cloud platforms like AWS, Azure, and Google Cloud. Its compatibility with container orchestration tools like Kubernetes makes it a perfect fit for managing large-scale, distributed systems—the backbone of many big tech operations.</p><h2><strong>4. Scaling for High Traffic and Performance: Handling Massive Loads</strong></h2><p>Tech giants handle massive amounts of traffic daily, and Spring Boot is designed to handle this kind of scale. Its support for asynchronous processing, reactive programming (via Spring WebFlux), and horizontal scaling enables applications to maintain high performance even under extreme load. <strong>Uber</strong>, a global ride-hailing company, leverages Spring Boot's scalability to manage its massive real-time operations, ensuring smooth service for millions of riders and drivers.</p><h2><strong>5. Boosting Developer Productivity: Faster Development Cycles</strong></h2><p>Spring Boot is designed to enhance developer productivity with features like:</p><ul><li><strong>Embedded Servers (Tomcat, Jetty, Undertow):</strong> Eliminates the need for external server deployments, streamlining the development and deployment process.</li><li><strong>Auto-configuration:</strong> Reduces manual configuration, allowing developers to focus on writing code.</li><li><strong>Spring Boot Actuator:</strong> Provides production-ready endpoints for monitoring and managing applications, offering valuable insights into application health and performance.</li></ul><p>These features significantly accelerate development cycles, a critical advantage for tech companies that need to iterate quickly and stay ahead of the competition.</p><h2><strong>6. Proven Reliability and Stability: A Trusted Framework</strong></h2><p>Spring Boot has a long history of being thoroughly tested and used by countless organizations worldwide. Its maturity and stability make it a trusted choice for mission-critical applications where reliability and uptime are paramount.</p><h2><strong>7. A Thriving Community and Extensive Support: A Wealth of Resources</strong></h2><p>A large and active community, combined with comprehensive documentation and readily available online resources (like Stack Overflow), means developers can quickly find solutions to problems and access best practices. This robust support system is invaluable, especially for large tech companies onboarding new developers or tackling complex challenges.</p><h2><strong>8. Polyglot Support and Flexible Integration: Adapting to Diverse Tech Stacks</strong></h2><p>While Java is a core strength, Spring Boot also supports other JVM languages like Kotlin and Groovy, providing flexibility for teams with diverse skill sets and preferences. This adaptability is a significant advantage in large organizations with heterogeneous tech stacks.</p><h2><strong>9. Built-in Security Features with Spring Security: Protecting Sensitive Data</strong></h2><p>Security is a top priority for any tech company. Spring Boot integrates seamlessly with Spring Security, providing robust out-of-the-box solutions for authentication, authorization, and protection against common security vulnerabilities. Companies like <strong>Intuit</strong>, handling sensitive financial data, rely on Spring Security within their Spring Boot applications to maintain the highest security standards.</p><h2><strong>10. Future-Proof and Continuously Evolving: Staying Ahead of the Curve</strong></h2><p>Spring Boot is constantly evolving to embrace new technologies and trends, including reactive programming, serverless architectures, and support for the latest cloud platforms and technologies like GraalVM and native image compilation. This future-proof approach is a major advantage for big tech companies planning for long-term projects and innovation.</p><h2>Conclusion</h2><p>For big tech companies like Netflix, Uber, and Intuit, Spring Boot isn't just a framework; it's a strategic choice. Its combination of simplicity, scalability, reliability, and cloud-native capabilities makes it a powerful tool for building and managing complex microservice architectures. Whether you're building a small application or a large-scale distributed system, Spring Boot provides the essential tools and features you need to succeed in today's demanding tech landscape.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Benefits of Spring Boot for Enterprises</category>
            <category>Why Big Tech Chooses Spring Boot</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/comapnies_choos_microservice_470b03bdf6.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 10 Spring Boot Open-source Projects in 2025 to learn best-practices.]]></title>
            <link>https://www.codingshuttle.com/blogs/top-10-spring-boot-open-source-projects-in-2025-to-learn-best-practices</link>
            <guid>https://www.codingshuttle.com/blogs/top-10-spring-boot-open-source-projects-in-2025-to-learn-best-practices</guid>
            <pubDate>Mon, 06 Jan 2025 11:31:43 GMT</pubDate>
            <description><![CDATA[This blog showcases the top 10 Spring Boot open-source projects on GitHub in 2025, perfect for gaining practical insights into building production-ready applications. From microservices to enterprise apps, these projects offer diverse use cases, clean code, and active communities. Dive in to explore best practices and advance your Spring Boot skills!]]></description>
            <content:encoded><![CDATA[<p>Spring Boot has become the go-to framework for Java developers building everything from simple web apps to complex microservices architectures. But how do you go beyond the basics and truly master Spring Boot? One of the best ways is by diving into the world of open source. By exploring and even contributing to real-world projects, you gain invaluable insights into best practices, design patterns, and the nuances of building production-ready applications.</p><p>This blog highlights ten fantastic Spring Boot open-source projects on GitHub that you should definitely check out in 2025. Whether you're a seasoned developer or just starting your Spring Boot journey, there's something here for everyone.</p><h2><strong>What Makes a Good Learning Project?</strong></h2><p>Before we dive in, let's talk about what we looked for in these projects:</p><ul><li><strong>Active Community &amp; Maintenance:</strong> We wanted projects that are actively maintained and have a healthy community, ensuring you'll find support and up-to-date code.</li><li><strong>Clean Code &amp; Documentation:</strong> Well-structured code and clear documentation are crucial for learning. You shouldn't have to spend hours deciphering cryptic code.</li><li><strong>Real-World Use Cases:</strong> We prioritized projects that tackle common development challenges, giving you practical experience.</li><li><strong>Variety:</strong> We aimed for a mix of project types, showcasing different aspects of Spring Boot.</li></ul><h2><strong>Let's Get Started: Top 10 Spring Boot Open-Source Projects</strong></h2><h3><strong>1. Piggymetrics</strong></h3><p><a href="https://github.com/sqshq/piggymetrics">Github Repo</a> (13k+ stars)</p><p>This project is a microservice-based personal finance manager. It's a great example of how to build a distributed system using Spring Boot, Spring Cloud, and other related technologies. You'll get to see how things like service discovery, circuit breakers, and distributed tracing work in practice. It also uses Spring Data JPA for persistence and Spring Security for securing the application. If you're interested in microservices, this is a must-see.</p><h3><strong>2. Spring Boot Admin</strong></h3><p><a href="https://github.com/codecentric/spring-boot-admin">Github Repo</a> (12.4k+ stars)</p><p>Ever wondered how to monitor and manage your Spring Boot applications in production? Spring Boot Admin provides a sleek UI for exactly that. It gives you insights into application health, metrics, logs, and more. It integrates seamlessly with Spring Cloud Netflix components like Eureka and Hystrix, making it a valuable tool for anyone working with microservices. This project is a fantastic resource for learning about the operational aspects of Spring Boot.</p><h3><strong>3. Spring Pet clinic</strong></h3><p><a href="https://github.com/spring-projects/spring-petclinic">Github Repo</a> (7.9k+ stars)</p><p>This is the classic Spring example application. While it might seem simple at first glance, Petclinic is packed with valuable lessons. It demonstrates core Spring Boot concepts like dependency injection, auto-configuration, and data access using JPA. It's a perfect starting point for beginners and a useful reference for experienced developers.</p><h3><strong>4. Metasfresh</strong></h3><p><a href="https://github.com/metasfresh/metasfresh">Github Repo</a> (1.8k+ stars)</p><p>If you're looking for a more challenging project, Metasfresh is worth exploring. It's an open-source ERP system built with Spring Boot. This project dives deep into complex business logic, domain-driven design, and advanced data modeling. It's a great way to see how Spring Boot can be used to build large-scale enterprise applications.</p><h3><strong>5. Spring Security, React, Ant Design Polls App</strong></h3><p><a href="https://github.com/callicoder/spring-security-react-ant-design-polls-app">Github Repo</a> (1.8k+ stars)</p><p>This project offers a practical example of building a full-stack web application with Spring Boot on the backend and React with Ant Design on the front end. It focuses on secure authentication and authorization using Spring Security and demonstrates how to build RESTful APIs for communication between the front end and back end. It's a great learning resource for full-stack developers.</p><h2><strong>More Projects to Explore:</strong></h2><p>While the top five offer a great starting point, there are other noteworthy projects you can explore:</p><h3><strong>6. E-commerce Project with Spring Boot</strong></h3><p><a href="https://github.com/jaygajera17/E-commerce-project-springBoot">Github Repo</a> (625+ stars)</p><p>A good starting point for learning e-commerce development with Spring Boot.</p><h3><strong>7. Springy Store Microservices</strong></h3><p><a href="https://github.com/mohamed-taman/Springy-Store-Microservices">Github Repo</a> (573+ stars)</p><p>Another microservices-based e-commerce project.</p><h3><strong>8. BookStoreApp: Distributed Application</strong></h3><p><a href="https://github.com/serlesen/microservices-bookstore">Github Repo</a> (339+ stars)</p><p>A smaller spring boot project focused on a bookstore application.</p><h3><strong>9. Internet Banking Concept - Microservices</strong></h3><p><a href="https://github.com/JavatoDev-com/internet-banking-concept-microservices">Github Repo</a> (306+ stars)</p><p>A conceptual project exploring microservices in the context of Internet banking.</p><h3><strong>10. Voting App</strong></h3><p><a href="https://github.com/JolaPsh/voting-system">Github Repo</a> (34+ stars)</p><p>A simple voting application showcasing basic Spring Boot features.</p><h2><strong>Why Learn from Open Source?</strong></h2><p>Learning from open source offers several advantages:</p><ul><li><strong>See How the Pros Do It:</strong> Learn from experienced developers and see how they structure their projects.</li><li><strong>Practical Experience:</strong> Gain hands-on experience by exploring real-world use cases.</li><li><strong>Stay Up-to-Date:</strong> Keep up with the latest trends and best practices in the Spring Boot ecosystem.</li></ul><h2><strong>Get Involved!</strong></h2><p>Don't just passively browse the code. Try contributing to these projects! Even small contributions like fixing typos or improving documentation can be a valuable learning experience.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot Open Source Projects</category>
            <category>Spring Boot Github Projects</category>
            <category>Open Source Github</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/top_10_open_source_projects_8f34326560.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Security is Really Not that Hard. Internal working of Spring Security]]></title>
            <link>https://www.codingshuttle.com/blogs/spring-security-is-really-not-that-hard-internal-working-of-spring-security</link>
            <guid>https://www.codingshuttle.com/blogs/spring-security-is-really-not-that-hard-internal-working-of-spring-security</guid>
            <pubDate>Mon, 06 Jan 2025 10:40:25 GMT</pubDate>
            <description><![CDATA[This blog simplifies the inner workings of Spring Security, explaining key concepts like authentication, authorization, and filters. It covers the default behavior when adding spring-boot-starter-security, the role of DaoAuthenticationProvider, and the authentication flow, including how user credentials are validated and secured using JWT.]]></description>
            <content:encoded><![CDATA[<p>When it comes to securing applications, Spring Security is often considered a complex and intimidating framework. However, once you understand how it works under the hood, you'll realize it's not as hard as it seems. This blog will break down the internal workings of Spring Security in a simple and approachable way. We will understand what happens internally when you enter a username and password and how it validates that it is really you.</p><h2>The Core Concepts of Spring Security</h2><p>Before diving into its internal workings, let’s clarify some core concepts:</p><ul><li><strong>Authentication</strong>: Verifying the identity of a user (e.g., checking username and password).</li><li><strong>Authorization</strong>: Determining what resources or actions a user is allowed to access.</li><li><strong>Filters</strong>: Intercepting requests and applying security logic before they reach the application.</li><li><strong>Security Context</strong>: Holding security-related information for the current user, such as their identity and roles.</li></ul><h2>Let’s understand the working of spring security</h2><p>Once you add the <strong>spring-boot-starter-security</strong> dependency in the pom.xml file Spring boot auto-configured the security with sensible defaults defined in WebSecurityConfiguration class.</p><pre><code class="language-xml">&lt;dependency&gt;
	&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
	&lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-java">@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity(securedEnabled = true)
public class WebSecurityConfig {

    private final JwtAuthFilter jwtAuthFilter;
    private final OAuth2SuccessHandler oAuth2SuccessHandler;

    private static final String[] publicRoutes = {
            "/error", "/auth/**"
    };

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .authorizeHttpRequests(auth -&gt; auth
                        .requestMatchers(publicRoutes).permitAll()
                        .anyRequest().authenticated())
                .csrf(csrfConfig -&gt; csrfConfig.disable())
                .sessionManagement(sessionConfig -&gt; sessionConfig
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)

        return httpSecurity.build();
    }

    @Bean
    AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
</code></pre><p>In a Spring Boot application, SecurityFilterAutoConfiguration automatically registers the DelegationFilterProxy filter with the name springSecurityFilterChain.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/image_1_627cebac98.png" alt="Spring Security Filter Chain" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_image_1_627cebac98.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_image_1_627cebac98.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_image_1_627cebac98.png 750w," sizes="100vw"><figcaption>Spring Security Filter Chain</figcaption></figure><p>From the above image you can understand that when client or user makes a request the request has to go through lot of filters as shown in above image before it reaches the Dispatcher servlet and from there to controllers.</p><p>So Once the request reaches to DelegatingFilterProxy, Spring delegates the processing to FilterChainProxy bean that utilizes the SecurityFilterChainProxy bean that utilizes the SecurityFilterChain to execute the list of all filters to be invoked for the current request.</p><p>So basically when you add the <strong>spring-boot-starter-security</strong> dependency <strong>it do’s the following things:</strong></p><ol><li>Creates a bean named springSecurityFilterChain. Registers the filter with a bean named springSecurityFilterChain with the Servlet container for every request.</li><li>HTTP basic authentication for authenticating requests made with remoting protocols and web services.</li><li>Generate a default login form.</li><li>Creates a user with a username of user and a password that is logged to the console.</li><li>Protect the password storage with BCrypt.</li><li>Enables logout feature.</li><li>Enables other features such as protection from CSRF attacks and session fixation.</li></ol><p>So this is all that you get by default when you add spring-boot-starter-security dependency.</p><h2>Now Let’s Understand the internal working of spring security</h2><p>When user login at that time In order to authenticate the user against the user present in database or not with correct credentials, we need to make use of DaoAuthenticationProvider which is one of the AuthenticationProvider.</p><p>And for that we need to create the bean of AuthenticationManager in Confiuration class also we have to create bean for passwordEncoder with this we will be able to encode the user password during authentication process and will be used by <strong>DaoAuthenticationProvider</strong>.</p><pre><code class="language-java">@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Bean
    AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
</code></pre><p>Once we do this, we need to make our <code>User</code> entity class implement the <code>UserDetails</code> interface and override methods like <code>getPassword()</code> and <code>getUsername()</code>. This is necessary because Spring Security requires an implementation of <code>UserDetails</code> to understand which fields in the <code>User</code> entity should be used for authentication (e.g., <code>username</code> and <code>password</code>). Additionally, the <code>UserDetails</code> interface helps specify which field in the entity will hold the roles or authorities of the user, enabling Spring Security to manage authorization effectively.</p><pre><code class="language-java">@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
public class User implements UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String email;
    private String password;
    private String name;

    @ElementCollection(fetch = FetchType.EAGER)
    @Enumerated(EnumType.STRING)
    private Set&lt;Role&gt; roles;

    @Override
    public Collection&lt;? extends GrantedAuthority&gt; getAuthorities() {
        Set&lt;SimpleGrantedAuthority&gt; authorities = new HashSet&lt;&gt;();
        roles.forEach(
                role -&gt; {
                    authorities.add(new SimpleGrantedAuthority("ROLE_"+role.name()));
                }
        );
        return authorities;
    }

    @Override
    public String getPassword() {
        return this.password;
    }

    @Override
    public String getUsername() {
        return this.email;
    }
}
</code></pre><p>Next we have to create a UserService class which is going to be implemented by UserDetailsService and we have to override a method loadUserByUsername(String username).</p><p>Implementing <code>UserDetailsService</code> and overriding <code>loadUserByUsername(String username)</code> is the standard way to integrate Spring Security with your user database. This method is invoked during authentication to fetch the user details by the provided username (or email in our case).</p><pre><code class="language-java">@Service
@RequiredArgsConstructor
public class UserService implements UserDetailsService {

    private final UserRepository userRepository;
    private final ModelMapper modelMapper;
    private final PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return userRepository.findByEmail(username)
                .orElseThrow(() -&gt; new BadCredentialsException("User with email "+ username +" not found"));
    }
}
</code></pre><p>During Login we will be providing the new object of UsernamePasswordAuthenticationToken, here the implementation class of AuthenticationManager is <strong>ProviderManager</strong> which will iterates through its configured <code>AuthenticationProviders</code>. It finds a <code>Provider</code> that <i>supports</i> the type of <code>Authentication</code> object it received (in this case, <code>DaoAuthenticationProvider</code> usually supports <code>UsernamePasswordAuthenticationToken</code>).</p><pre><code class="language-java">@Service
@RequiredArgsConstructor
public class AuthService {

    private final AuthenticationManager authenticationManager;
    private final JwtService jwtService;
    private final UserService userService;
    private final SessionService sessionService;

    public LoginResponseDto login(LoginDto loginDto) {
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(loginDto.getEmail(), loginDto.getPassword())
        );

        User user = (User) authentication.getPrincipal();
        String accessToken = jwtService.generateAccessToken(user);

        return new LoginResponseDto(user.getId(), accessToken);
    }
}
</code></pre><h2>Now Let’s understand how <code>DaoAuthenticationProvider</code> works and helps us to Authenticate the User</h2><p>After the <strong>ProviderManager</strong> finds that <strong>DaoAuthenticationProvider</strong> supports the provided authentication object it will call the authenticate method of <code>DaoAuthenticationProvider</code> .</p><p>Now <code>DaoAuthenticationProvider</code> calls the <code>UserDetailsService</code>'s <code>loadUserByUsername()</code> method, passing the username from the <code>Authentication</code> object. The <code>UserDetailsService</code> queries the database and returns a <code>UserDetails</code> object containing the user's information (username, encoded password, authorities).</p><p>The <code>DaoAuthenticationProvider</code> uses the configured <code>PasswordEncoder</code> to compare the password provided by the user in the <code>Authentication</code> object with the encoded password retrieved from the <code>UserDetails</code>. If the passwords match and the user is valid , create a fully authenticated <code>Authentication</code> object and If authentication fails (wrong password, user not found, etc.), throw an <code>AuthenticationException</code>.</p><h2>Understanding the Complete Authentication flow with diagram</h2><p>Following image shows the complete authentication flow when user login.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/image_2_3e60a030f7.png" alt="Authentication Flow Diagram" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_image_2_3e60a030f7.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_image_2_3e60a030f7.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_image_2_3e60a030f7.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_image_2_3e60a030f7.png 1000w," sizes="100vw"><figcaption>Authentication Flow Diagram</figcaption></figure><p>When user or client makes login request at that time we will call the AutheticationManager authenticate method by passing the Authentication object <strong>UsernamePasswordAuthenticationToken</strong> with principal as email and credentials as password.</p><pre><code class="language-java">Authentication authentication = authenticationManager.authenticate(
	new UsernamePasswordAuthenticationToken(loginDto.getEmail(), loginDto.getPassword())
);
</code></pre><p>Now the <strong>ProviderManager</strong> which is the ****implementation of AuthenticationManager will loop throug the list of AuthenticationProviders, this AuthenticationProvider Interface has two methods support and authenticate, all the implementation classes of AuthenticationProvider overrides this two methods.</p><pre><code class="language-java">package org.springframework.security.authentication;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

public interface AuthenticationProvider {
    Authentication authenticate(Authentication authentication) throws AuthenticationException;

    boolean supports(Class&lt;?&gt; authentication);
}
</code></pre><p>One of the AbstractClass called <code>AbstractUserDetailsAuthenticationProvider</code> implements the AuthenticationProvider interface and this abstract class is extended by <code>DaoAuthenticationProvider</code></p><p>This <code>DaoAuthenticationProvider's</code> authenticate method is invoked and it calls UserDetailService’s (which delegates controll to UserService) loadUserByUsername method by passing the username from the <code>Authentication</code> object. The <code>UserDetailsService</code> queries the database and returns a <code>UserDetails</code> object containing the user's information (username, encoded password, authorities).</p><p>The <code>DaoAuthenticationProvider</code> uses the configured <code>PasswordEncoder</code> to compare the password provided by the user in the <code>Authentication</code> object with the encoded password retrieved from the <code>UserDetails</code>. If the passwords match and the user is valid, create a fully authenticated <code>Authentication</code> object and If authentication fails (wrong password, user not found, etc.), throw an <code>AuthenticationException</code>.</p><pre><code class="language-java">public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
    private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
    private PasswordEncoder passwordEncoder;
    private volatile String userNotFoundEncodedPassword;
    private UserDetailsService userDetailsService;
    private UserDetailsPasswordService userDetailsPasswordService;
    private CompromisedPasswordChecker compromisedPasswordChecker;

    public DaoAuthenticationProvider() {
        this(PasswordEncoderFactories.createDelegatingPasswordEncoder());
    }

    public DaoAuthenticationProvider(PasswordEncoder passwordEncoder) {
        this.setPasswordEncoder(passwordEncoder);
    }

    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        if (authentication.getCredentials() == null) {
            this.logger.debug("Failed to authenticate since no credentials provided");
            throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        } else {
            String presentedPassword = authentication.getCredentials().toString();
            if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
                this.logger.debug("Failed to authenticate since password does not match stored value");
                throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
            }
        }
    }

    protected void doAfterPropertiesSet() {
        Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
    }

    protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        this.prepareTimingAttackProtection();

        try {
            UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);
            if (loadedUser == null) {
                throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
            } else {
                return loadedUser;
            }
        } catch (UsernameNotFoundException var4) {
            UsernameNotFoundException ex = var4;
            this.mitigateAgainstTimingAttack(authentication);
            throw ex;
        } catch (InternalAuthenticationServiceException var5) {
            InternalAuthenticationServiceException ex = var5;
            throw ex;
        } catch (Exception var6) {
            Exception ex = var6;
            throw new InternalAuthenticationServiceException(ex.getMessage(), ex);
        }
    }

    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        String presentedPassword = authentication.getCredentials().toString();
        boolean isPasswordCompromised = this.compromisedPasswordChecker != null &amp;&amp; this.compromisedPasswordChecker.check(presentedPassword).isCompromised();
        if (isPasswordCompromised) {
            throw new CompromisedPasswordException("The provided password is compromised, please change your password");
        } else {
            boolean upgradeEncoding = this.userDetailsPasswordService != null &amp;&amp; this.passwordEncoder.upgradeEncoding(user.getPassword());
            if (upgradeEncoding) {
                String newPassword = this.passwordEncoder.encode(presentedPassword);
                user = this.userDetailsPasswordService.updatePassword(user, newPassword);
            }

            return super.createSuccessAuthentication(principal, authentication, user);
        }
    }

    private void prepareTimingAttackProtection() {
        if (this.userNotFoundEncodedPassword == null) {
            this.userNotFoundEncodedPassword = this.passwordEncoder.encode("userNotFoundPassword");
        }

    }

    private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken authentication) {
        if (authentication.getCredentials() != null) {
            String presentedPassword = authentication.getCredentials().toString();
            this.passwordEncoder.matches(presentedPassword, this.userNotFoundEncodedPassword);
        }

    }

    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
        this.passwordEncoder = passwordEncoder;
        this.userNotFoundEncodedPassword = null;
    }

    protected PasswordEncoder getPasswordEncoder() {
        return this.passwordEncoder;
    }

    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    protected UserDetailsService getUserDetailsService() {
        return this.userDetailsService;
    }

    public void setUserDetailsPasswordService(UserDetailsPasswordService userDetailsPasswordService) {
        this.userDetailsPasswordService = userDetailsPasswordService;
    }

    public void setCompromisedPasswordChecker(CompromisedPasswordChecker compromisedPasswordChecker) {
        this.compromisedPasswordChecker = compromisedPasswordChecker;
    }
}
</code></pre><h2>Using JWT Token for Authentication</h2><p>Once the authentication is done by <strong>DaoAuthenticationProvider</strong> we create the jwt access token with the help of jwt service. During jwt token creation we will set the userId as the subject and add the remaining details like email and roles in claims. The roles that we added will be used during authorizing the user.</p><pre><code class="language-java">@Service
public class JwtService {

    @Value("${jwt.secretKey}")
    private String jwtSecretKey;

    private SecretKey getSecretKey() {
        return Keys.hmacShaKeyFor(jwtSecretKey.getBytes(StandardCharsets.UTF_8));
    }

    public String generateAccessToken(User user) {
        return Jwts.builder()
                .subject(user.getId().toString())
                .claim("email", user.getEmail())
                .claim("roles", user.getRoles().toString())
                .issuedAt(new Date())
                .expiration(new Date(System.currentTimeMillis() + 1000*60*10))
                .signWith(getSecretKey())
                .compact();
    }

    public String generateRefreshToken(User user) {
        return Jwts.builder()
                .subject(user.getId().toString())
                .issuedAt(new Date())
                .expiration(new Date(System.currentTimeMillis() + 1000L *60*60*24*30*6))
                .signWith(getSecretKey())
                .compact();
    }

    public Long getUserIdFromToken(String token) {
        Claims claims = Jwts.parser()
                .verifyWith(getSecretKey())
                .build()
                .parseSignedClaims(token)
                .getPayload();
        return Long.valueOf(claims.getSubject());
    }

}
</code></pre><p>Note:- You have to add the following dependencies in the pom.xml file to use jwt token in spring boot application.</p><pre><code class="language-xml">&lt;dependency&gt;
	&lt;groupId&gt;io.jsonwebtoken&lt;/groupId&gt;
	&lt;artifactId&gt;jjwt-api&lt;/artifactId&gt;
	&lt;version&gt;0.12.6&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
	&lt;groupId&gt;io.jsonwebtoken&lt;/groupId&gt;
	&lt;artifactId&gt;jjwt-impl&lt;/artifactId&gt;
	&lt;version&gt;0.12.6&lt;/version&gt;
	&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
	&lt;groupId&gt;io.jsonwebtoken&lt;/groupId&gt;
	&lt;artifactId&gt;jjwt-jackson&lt;/artifactId&gt;
	&lt;version&gt;0.12.6&lt;/version&gt;
	&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
</code></pre><p>Requests made for signup and login will be permitted and not be authenticated, but all othe requests that user will make after login by sending the accessToken in the header will go through securityFilterChain for authentication.</p><pre><code class="language-java">@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity(securedEnabled = true)
public class WebSecurityConfig {

    private final JwtAuthFilter jwtAuthFilter;
    private final OAuth2SuccessHandler oAuth2SuccessHandler;

    private static final String[] publicRoutes = {
            "/error", "/auth/**"
    };

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .authorizeHttpRequests(auth -&gt; auth
                        .requestMatchers(publicRoutes).permitAll()
                        .anyRequest().authenticated())
                .csrf(csrfConfig -&gt; csrfConfig.disable())
                .sessionManagement(sessionConfig -&gt; sessionConfig
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)

        return httpSecurity.build();
    }

    @Bean
    AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
</code></pre><h2><strong>Authenticating the user with the provided accessToken in the header.</strong></h2><p>So far we have seen that when user makes the login request after signup user will get an accessToken and that accessToken will be passed in the next requests made by user to access any content or resource from database.</p><pre><code class="language-java">@Component
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {

    private final JwtService jwtService;
    private final UserService userService;

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver handlerExceptionResolver;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        try {
            final String requestTokenHeader = request.getHeader("Authorization");
            if (requestTokenHeader == null || !requestTokenHeader.startsWith("Bearer")) {
                filterChain.doFilter(request, response);
                return;
            }

            String token = requestTokenHeader.split("Bearer ")[1];
            Long userId = jwtService.getUserIdFromToken(token);

            if (userId != null &amp;&amp; SecurityContextHolder.getContext().getAuthentication() == null) {
                User user = userService.getUserById(userId);
                UsernamePasswordAuthenticationToken authenticationToken =
                        new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                authenticationToken.setDetails(
                        new WebAuthenticationDetailsSource().buildDetails(request)
                );
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
            filterChain.doFilter(request, response);
        } catch (Exception ex) {
            handlerExceptionResolver.resolveException(request, response, null, ex);
        }
    }
}
</code></pre><p>Let’s breakdown the code for JwtAuthFilter to understand ut</p><p>The <code>JwtAuthFilter</code> class is a custom Spring Security filter used to validate JWT (JSON Web Token) authentication in an application. Here’s what the filter does, step-by-step:</p><ol><li><strong>Extract the Token</strong>:<ul><li>It checks the <code>Authorization</code> header of the incoming HTTP request for a token. If the header is missing or does not start with <code>"Bearer"</code>, it skips further processing and lets the request proceed to further filter that is UsernamePasswordAuthenticationFilter which will throw Authentication exception as it will not get the authentication object.</li></ul></li><li><strong>Validate and Parse the Token</strong>:<ul><li>If a token is found, it extracts the token value and uses <code>JwtService</code> to decode and extract the user ID embedded in the token.</li></ul></li><li><strong>Set Authentication</strong>:<ul><li>If the user ID is valid and the <code>SecurityContextHolder</code> does not already have an authentication object:<ul><li>The filter fetches the corresponding user details using <code>UserService</code>.</li><li>It creates a <code>UsernamePasswordAuthenticationToken</code> with the user’s details and authorities.</li><li>The token is stored in the <code>SecurityContextHolder</code>, marking the request as authenticated for the next filter i.e UsernamePasswordAuthenticationFilter will find that authentication object is present in security context so no need to perform authentication and it will simply pass the request to next filter in chain and from here the request is now send to dispatcher servlet and from dispatcher servlet to controller.</li></ul></li></ul></li><li><strong>Handle Exceptions</strong>:<ul><li>Any exceptions during the process are resolved using the <code>HandlerExceptionResolver</code>, ensuring proper error handling and response generation.</li></ul></li><li><strong>Continue the Filter Chain</strong>:<ul><li>After processing, the filter calls <code>filterChain.doFilter()</code> to pass the request to the next filter in the chain and the request is passed to UsernamePasswordAuthenticationFilter.</li></ul></li></ol><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/image_3_7664cc59cd.png" alt="Authenticating Client Request Flow" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_image_3_7664cc59cd.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_image_3_7664cc59cd.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_image_3_7664cc59cd.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_image_3_7664cc59cd.png 1000w," sizes="100vw"><figcaption>Authenticating Client Request Flow</figcaption></figure><p>The above image shows the complete flow that we have discussed so far.</p><h2>Conclusion</h2><p>So, as we've seen, Spring Security can seem a bit intimidating at first glance. But once you get a handle on how it works behind the scenes the <strong>filters</strong>, the <strong>AuthenticationManager</strong>, <strong>DaoAuthenticationProvider</strong>, and the <strong>UserDetailsService</strong> it all starts to make sense. You can actually configure and tweak your app's security pretty confidently. It's a powerful tool, and honestly, it's not as tough as it looks.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Security</category>
            <category>Spring Security Internal Working</category>
            <category>Spring Security Advance</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/spring_security_b421041dbe.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Is learning and mastering Spring & Spring boot worth it in 2025 ?]]></title>
            <link>https://www.codingshuttle.com/blogs/is-learning-and-mastering-spring-and-spring-boot-worth-it-in-2025</link>
            <guid>https://www.codingshuttle.com/blogs/is-learning-and-mastering-spring-and-spring-boot-worth-it-in-2025</guid>
            <pubDate>Mon, 06 Jan 2025 10:29:26 GMT</pubDate>
            <description><![CDATA[This blog explores the enduring relevance of Spring and Spring Boot in 2025, highlighting their role in enterprise-grade applications, microservices, and modern development practices. It provides insights into why mastering these frameworks is essential for career growth, offering unmatched reliability, flexibility, and productivity in the Java ecosystem.]]></description>
            <content:encoded><![CDATA[<h2><strong>Introduction</strong></h2><p>You know that feeling when you're deciding whether to learn something new? That little voice in your head asking, <i>Is this really worth my time?</i> I’ve been there. Nobody wants to spend weeks (or months) learning a technology only to realize it's outdated before they even get to use it.</p><p>So, what about Spring and Spring Boot in 2025? Are they still worth learning?</p><p>Honestly, I’d say <i>yes</i>, without a doubt. And I don’t say that just because it’s popular. I’ve seen how these frameworks make life easier for developers, and how they help to build scalable applications without reinventing the wheel. They’re not just surviving in the industry they’re thriving.</p><p>In this blog, I’ll share why Spring and Spring Boot are still a solid investment for your career and why learning them might just be one of the best decisions you make. Let’s dive in.</p><h2><strong>Why Spring and Spring Boot Remain Essential</strong></h2><p>Spring has been a bedrock for Java developers for years, known for its robust handling of complex enterprise applications. Spring Boot builds upon this foundation, streamlining development by minimizing configuration and boilerplate.</p><h3><strong>Here's why they're still highly relevant in 2025:</strong></h3><p>You know, every year, there’s some new buzzword in tech—some new framework that people swear is going to replace everything. But here’s the thing: Spring and Spring Boot aren’t going anywhere. And I say this from experience.</p><p>If you’ve worked in the Java world, you already know how many companies rely on Spring. Banks, fintech startups, large-scale e-commerce apps—you name it. These companies aren’t going to wake up one day and decide to throw away years of stable, battle-tested code just because something new popped up. They need developers who <i>know</i> Spring, who can maintain these systems, and who can improve them without breaking everything.</p><p>And then there’s Spring Boot. If you’ve ever had to manually configure a Spring app (XML hell, anyone?), you <i>know</i> how much easier Boot makes things. It just works. Microservices? Cloud deployment? Security? Everything fits together without you having to spend hours tweaking configs.</p><p>So, if you’re wondering whether learning Spring and Spring Boot is still worth it in 2025, here’s my honest take: If you’re planning to work with Java, learning them is one of the smartest things you can do. The demand is there, the ecosystem is rock solid, and companies <i>need</i> developers who can handle real-world applications—not just chase the latest shiny tech.</p><h2><strong>Why Choose Spring Boot in 2025?</strong></h2><p>So, you might be wondering, with all these new frameworks out there, why stick with Spring Boot? It’s not exactly the shiny new thing, right? But here’s the thing—Spring Boot’s been around long enough to prove it’s not going anywhere, and here’s why I still think it’s worth it.</p><h3><strong>1. It’s Battle-Tested</strong></h3><p>Let’s be real, businesses aren’t throwing their big projects at something that hasn’t been through the ringer. Spring Boot’s been in the game for a long time, and that means it’s reliable. No surprises, no “let’s see if this works.” If you’re working on anything that requires stability, it’s a safe bet.</p><h3><strong>2. Makes You Actually Get Stuff Done</strong></h3><p>I can’t even count how much time Spring Boot has saved me by handling the setup for me. It does the boring, repetitive stuff—like configurations, embedded servers—so I can just dive into what actually matters: coding the business logic. It’s like someone handed you a fully loaded toolbox. You just get to work.</p><h3><strong>3. You’re Not Alone—The Community’s Huge</strong></h3><p>There’s no shortage of resources with Spring Boot. Honestly, the community is one of the best parts. If you hit a roadblock, there’s always someone on Stack Overflow, GitHub, or even Reddit who’s dealt with the same thing. And the official docs? Solid. No need to reinvent the wheel.</p><h3><strong>4. It Doesn’t Force You into One Way of Doing Things</strong></h3><p>You can’t always predict how things will change in a project. Spring Boot knows this. It doesn’t lock you into any one architecture, whether you’re dealing with old-school monolithic systems or you’re building out microservices and deploying them on Kubernetes. It just works, no matter what you need it to do.</p><h3><strong>5. It’s Always Moving Forward</strong></h3><p>The best part? Spring Boot’s not resting on its laurels. It keeps adapting—supporting newer concepts like reactive programming, serverless, and all that cloud-native stuff. So, even with all the hype around the newest tech, Spring Boot stays relevant and doesn’t fall behind.</p><h2><strong>Who Should Learn Spring and Spring Boot? (And Why It Matters for Your Career)</strong></h2><p>Alright, let’s be real for a minute. If you’re aiming to make a solid career in backend development or enterprise Java, you can’t afford to skip over Spring and Spring Boot. These frameworks are everywhere, and trust me, knowing them opens up a ton of doors in the tech world. They’re not just “good to know”—they’re pretty much essential.</p><h3><strong>So who should be learning Spring and Spring Boot, and why is it so important?</strong></h3><h3><strong>1. Aspiring Backend Developers</strong></h3><p>If you’re starting out, getting familiar with Spring is a no-brainer. Spring Boot, in particular, will make your life a lot easier. You’ll get to work with a framework that’s used in a lot of real-world applications, and learning it early on will give you a major edge when you start looking for your first job. It’s one of those skills that makes you stand out from the crowd, for sure.</p><h3><strong>2. Enterprise Java Developers</strong></h3><p>If you’ve been doing Java for a while but haven’t picked up Spring, now’s the time. In the enterprise space, Spring is basically the default for large-scale applications. If you want to work on systems that are running the core of major companies, you’ll need to know Spring. And if you want to move up to senior positions like Software Architect or Tech Lead, Spring expertise is usually a must-have.</p><h3><strong>3. Cloud and Microservices Devs</strong></h3><p>Spring Boot is especially useful if you're aiming to work with microservices and cloud platforms. It’s kind of the go-to framework for cloud-native applications. Whether you’re looking at AWS, Google Cloud, or Azure, Spring Boot integrates like a charm. If you’re hoping to get into modern architectures and cutting-edge tech, this is one of the best ways to do it.</p><h3><strong>4. Experienced Devs Looking for the Next Step</strong></h3><p>Even if you’ve been coding for a while, there’s still a lot to gain from Spring Boot. It’s not just about learning new tools—it’s about making your workflow smoother and faster. With all its features like auto-configuration and embedded servers, you’ll spend less time setting things up and more time actually coding. For senior developers, that means more productivity and, of course, more opportunities to take on leadership roles.</p><h2><strong>Final Verdict: A Strategic Investment in Your Future</strong></h2><p>Spring and Spring Boot are still a solid bet for anyone in Java development. In 2025, if you're serious about what you’re doing, learning these frameworks is more of a no-brainer than a choice.</p><h3><strong>Why It’s Worth It:</strong></h3><ul><li><strong>The Job Market Loves It:</strong> People still want Spring Boot developers. It’s one of those skills that’s always in demand, and yes, it pays well. If you’re looking to grab a job or even make a career move, this is the way to go.</li><li><strong>Job Security:</strong> Think about it—so many big companies depend on Spring. They’re not going to just scrap all their Spring apps overnight. That means if you’re in this space, there’s going to be work for you for a long time.</li><li><strong>Cool Projects to Work On:</strong> I’ve been on some awesome projects that use Spring Boot—cloud, and microservices, It’s never boring, and you get to see the real-world impact of your code.</li><li><strong>Room to Grow:</strong> Not only is Spring Boot going to get you in the door, but it can take you places. Lead roles, architect positions, even management if that’s the route you want to take. This is one of those skills that just keeps on giving.</li></ul><p>In short, mastering Spring Boot isn’t just for the here and now. It’s a smart move for the long haul. Whether you're getting started or looking to level up, it’s a good investment.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot relevance</category>
            <category>Why Spring Boot in 2025</category>
            <category>Mastering Spring Boot in 2025</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/leaning_springboot_9c5716b120.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Kafka In Spring Boot — Effortless Messaging Made Easy]]></title>
            <link>https://www.codingshuttle.com/blogs/how-to-work-with-apache-kafka-in-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/how-to-work-with-apache-kafka-in-spring-boot</guid>
            <pubDate>Tue, 17 Dec 2024 17:47:12 GMT</pubDate>
            <description><![CDATA[This article explores Apache Kafka, highlighting its high-throughput, low-latency real-time data processing capabilities and integration with Spring Boot. It covers Kafka's architecture, fault tolerance, and the transition to KRaft mode for improved scalability in modern distributed systems.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p>Apache Kafka is an <strong>open-source distributed event streaming platform</strong> designed for high-throughput, low-latency real-time data processing. Initially developed by LinkedIn and later donated to the Apache Software Foundation, it is widely used for real-time pipelines and streaming applications.</p><h2><strong>Why Kafka is Essential in Distributed Systems</strong></h2><p>As distributed systems grow, traditional request-response communication struggles with challenges like:</p><ol><li><strong>Handling Large Data Streams</strong>: Managing high-velocity data efficiently.</li><li><strong>Decoupling Services</strong>: Allowing independent evolution of services without tight dependencies.</li><li><strong>Ensuring Fault Tolerance</strong>: Avoiding data loss and maintaining reliability during failures.</li></ol><p>Kafka addresses these problems by being <strong>horizontally scalable</strong>, <strong>fault-tolerant</strong>, and fast. It follows a <strong>publish-subscribe (pub-sub) model</strong>, enabling producers to write and consumers to read messages independently. This decoupling ensures seamless communication between systems.</p><h2><strong>Key Concepts of Apache Kafka</strong></h2><p><strong>Topics</strong>:</p><p>Data in Kafka is organized into <strong>topics</strong>. A topic is a logical channel where messages are written (produced) by <strong>producers</strong> and read (consumed) by <strong>consumers</strong>.</p><p><strong>Producers</strong>:</p><p>Producers are the entities that publish (write) messages to Kafka topics.</p><p><strong>Consumers</strong>:</p><p>Consumers are the entities that subscribe to Kafka topics to read (consume) messages.</p><p><strong>Brokers</strong>:</p><p>Kafka runs as a cluster of one or more servers called <strong>brokers</strong>, which store and manage the data. Each broker is responsible for maintaining a portion of the data.</p><p><strong>Partitions</strong>:</p><p>Topics are split into <strong>partitions</strong> to enable parallel processing and scalability. Each partition is an ordered log of messages.</p><p><strong>Offset</strong>:</p><p>Each message in a partition has a unique <strong>offset</strong> that serves as its identifier, ensuring that the messages are processed in order.</p><p><strong>Replication</strong>:</p><p>Kafka replicates data across brokers for fault tolerance. This ensures that data is available even if a broker fails.</p><h2><strong>Use Cases of Apache Kafka</strong></h2><p><strong>Real-Time Data Processing</strong>:</p><p>Process streams of data in real-time, such as website activity tracking.</p><p><strong>Log Aggregation</strong>:</p><p>Collect and aggregate logs from multiple systems into a single source.</p><p><strong>Event Sourcing</strong>:</p><p>Store events as a log for systems where state changes need to be captured reliably.</p><p><strong>Data Integration</strong>:</p><p>Stream data between various systems and databases, making it an excellent tool for creating data pipelines.</p><p><strong>Analytics</strong>:</p><p>Process and analyze data streams to derive insights, such as monitoring user behavior or fraud detection.</p><h2><strong>Why Use Kafka?</strong></h2><ul><li><strong>High Performance</strong>: Kafka is designed to handle large volumes of data with low latency.</li><li><strong>Scalability</strong>: It can scale horizontally by adding more brokers and partitions.</li><li><strong>Durability</strong>: Kafka persists data to disk and replicates it across brokers for fault tolerance.</li><li><strong>Flexibility</strong>: It supports both real-time and batch processing.</li><li><strong>Decoupling Systems</strong>: Kafka acts as an intermediary, reducing the dependency between producers and consumers.</li></ul><h2><strong>When NOT to Use Kafka</strong></h2><ul><li><strong>Simple Request-Response:</strong> Use REST APIs or gRPC for synchronous communication.</li><li><strong>Small Projects:</strong> Kafka is overkill; consider RabbitMQ or ActiveMQ.</li><li><strong>High Latency Tolerance:</strong> Use database polling or batch jobs instead.</li><li><strong>Monolithic Apps:</strong> Kafka adds unnecessary complexity; better for microservices.</li></ul><h2><strong>Key Features of Kafka</strong></h2><p><strong>Massive Scalability</strong>:</p><p>Kafka can scale across <strong>100s of nodes</strong>, making it suitable for large distributed systems.</p><p><strong>High Throughput</strong>:</p><p>It can process <strong>hundreds of MB/s</strong> and <strong>millions of messages per second</strong>.</p><p><strong>Low Latency</strong>:</p><p>Kafka delivers messages with latencies as low as <strong>2ms</strong>, ensuring real-time responsiveness.</p><p><strong>Fault Tolerance</strong>:</p><p>With data replication, Kafka ensures reliability and prevents data loss in case of failures.</p><h3><strong>Example</strong></h3><p>Imagine an <strong>e-commerce platform</strong>:</p><ol><li><strong>Order System</strong> (Producer): Sends order events (e.g., "Order Placed").</li><li><strong>Kafka</strong>: Receives and stores these events in a topic called "orders."</li><li><strong>Warehouse System</strong> (Consumer): Subscribes to the "orders" topic to process fulfillment.</li></ol><blockquote><p><i><strong>NOTE:</strong></i> LinkedIn uses Kafka to process 1 Billion messages per day</p></blockquote><h2>The Kafka Architecture</h2><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_12_17_205132_fc75d8faa0.png" alt="Kafka Architecture" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2024_12_17_205132_fc75d8faa0.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2024_12_17_205132_fc75d8faa0.png 500w," sizes="100vw"><figcaption>Kafka Architecture</figcaption></figure><p><strong>1. Partitioning of Topics</strong>: Kafka splits topics into partitions, enabling parallel processing. Each message is assigned to a partition based on a key or round-robin.&nbsp;<br>Imagine a <strong>library</strong> (Kafka topic) that stores books (messages). The library has several <strong>shelves</strong> (partitions), and each book needs to be placed on a shelf.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_12_17_205601_f556618974.png" alt="Partitioning of Topics" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2024_12_17_205601_f556618974.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2024_12_17_205601_f556618974.png 500w," sizes="100vw"><figcaption><strong>Partitioning of Topics</strong></figcaption></figure><p><strong>2. Message Ordering</strong>: Kafka guarantees ordering <strong>within a partition</strong>, but not across partitions. Imagine the <strong>post office</strong> is responsible for delivering letters (messages) to different <strong>addresses</strong> (consumers). However, there are <strong>multiple postal workers</strong> (partitions) in the post office, each handling a different type of letter. The post office ensures that the letters are delivered in the exact order they are received, but this guarantee is only for <strong>letters handled by the same postal worker</strong> (partition). If the letters are handled by different postal workers, their order might not be the same.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_12_17_205951_2bcdf1f59a.png" alt="Message Ordering" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2024_12_17_205951_2bcdf1f59a.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2024_12_17_205951_2bcdf1f59a.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2024_12_17_205951_2bcdf1f59a.png 750w," sizes="100vw"><figcaption><strong>Message Ordering</strong></figcaption></figure><p><strong>3. Message Re-reading by Consumers</strong>: Yes, consumers can read the same message multiple times within the retention period (default 7 days), as Kafka stores messages and tracks consumer offsets.&nbsp;<br>Just like a <strong>librarian</strong> can re-check books (messages) multiple times during their availability in the library (within the retention period), <strong>Kafka consumers</strong> can re-read the same message as long as it is within the configured retention period. Kafka keeps track of consumer <strong>offsets</strong>, allowing them to go back and read older messages, ensuring flexibility and reprocessing capabilities for the consumers.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_12_17_210152_6a3e2504be.png" alt="Message Re-reading by Consumers" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2024_12_17_210152_6a3e2504be.png 230w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2024_12_17_210152_6a3e2504be.png 500w," sizes="100vw"><figcaption><strong>Message Re-reading by Consumers</strong></figcaption></figure><p><strong>4. Adding New Consumers</strong>: When a new consumer joins a group, Kafka <strong>rebalances</strong> partition assignments. Consumers may start reading from new or multiple partitions.&nbsp;<br>Just like a <strong>library</strong> efficiently assigns books (partitions) to librarians (consumers) to manage the workload, <strong>Kafka</strong> ensures that when a new consumer joins, it rebalances the partitions. This allows the system to handle more traffic (messages) efficiently by distributing the load across more consumers, ensuring high availability and parallel processing.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_12_17_205226_e66c4ac248.png" alt="Adding New Consumers" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2024_12_17_205226_e66c4ac248.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2024_12_17_205226_e66c4ac248.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Screenshot_2024_12_17_205226_e66c4ac248.png 750w," sizes="100vw"><figcaption><strong>Adding New Consumers</strong></figcaption></figure><p><strong>5. Broker Failures</strong>: Kafka ensures fault tolerance via <strong>replication</strong>. If a broker goes down, a replica takes over as the leader, and consumers continue reading from available brokers.&nbsp;<br>In the real world, the <strong>team of chefs</strong> ensures that the kitchen keeps working even if one chef (broker) becomes unavailable by relying on backup chefs (replicas). Kafka’s <strong>replication</strong> mechanism ensures that even if a broker fails, the system remains fault-tolerant, and consumers can continue to process messages without disruption.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_12_17_205646_8fd15f1536.png" alt="Broker Failures" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Screenshot_2024_12_17_205646_8fd15f1536.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Screenshot_2024_12_17_205646_8fd15f1536.png 500w," sizes="100vw"><figcaption><strong>Broker Failures</strong></figcaption></figure><p><strong>6. Message Availability After Days</strong>: Consumers can read messages that are within the configured retention period, even if produced days ago. In the real world, the <strong>library system</strong> ensures that books (messages) are available for borrowing (consumption) within a certain timeframe, after which they are removed. Similarly, in Kafka, consumers can read messages that are still within the configured retention period, even if the messages were produced days ago.</p><p>This design allows Kafka to offer <strong>scalability, reliability</strong>, and <strong>fault tolerance</strong> in distributed systems.</p><ul><li><strong>Traditional Architecture (ZooKeeper-based)</strong>: Kafka used <strong>ZooKeeper</strong> for cluster management, metadata, and leader election.</li><li><strong>Kafka Raft (KRaft) Mode</strong>: Replaces ZooKeeper with the <strong>Raft consensus protocol</strong>, simplifying metadata management, leader election, and scalability.</li><li><strong>Benefits of KRaft</strong>:<ul><li>Simplified architecture with no ZooKeeper dependency.</li><li>Improved scalability and fault tolerance.</li><li>Easier management and better performance.</li></ul></li></ul><p>Kafka is transitioning to KRaft mode for a more streamlined, efficient distributed system.</p><h2>How to work with Apache Kafka in Spring Boot</h2><p>Working with Apache Kafka in Spring Boot involves setting up Kafka producers and consumers to handle messages. Here’s a step-by-step guide:</p><p><strong>Build two projects one acts as producer another act as consumer with kafka dependency</strong></p><ul><li><strong>Project 1</strong> acts as a <strong>Kafka Producer</strong></li><li><strong>Project 2</strong> acts as a <strong>Kafka Consumer</strong></li></ul><h2><strong>Step: 1. Add Dependencies</strong></h2><p>Both projects need the <strong>Spring Kafka dependency</strong>.</p><h3>Maven Dependency:</h3><p>Add this to <code>pom.xml</code> for both projects:</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.kafka&lt;/groupId&gt;
    &lt;artifactId&gt;spring-kafka&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><p>Or when you build your project using <a href="https://start.spring.io/">https://start.spring.io/</a> you add these dependencies.</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/application_386c1ab7e8.png" alt="Apache kafka dependency" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_application_386c1ab7e8.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_application_386c1ab7e8.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_application_386c1ab7e8.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_application_386c1ab7e8.png 1000w," sizes="100vw"><figcaption>Apache kafka dependency</figcaption></figure><p><strong>Next configured the kafka (inside yaml or properties)</strong></p><h2><strong>Step:2. Producer Configuration (Project 1)</strong></h2><h3><strong>application.yml (Producer)</strong>:</h3><pre><code class="language-java">kafka:
  topic:
    user-random-topic: massage-topic

spring:
  kafka:
    bootstrap-servers: localhost:9092
    producer:
          key-serializer: org.apache.kafka.common.serialization.LongSerializer
          value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
</code></pre><p>You can also configure your database and port according to what you want inside the properties or YAML file.</p><h3><strong>Create Kafka Topic Configuration</strong>:</h3><p>Kafka will auto-create a topic if it does not exist. However, it's a good practice to explicitly configure it:</p><pre><code class="language-java">import org.apache.kafka.clients.admin.NewTopic;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class KafkaTopic {

    @Value("${kafka.topic.user-random-topic}")
    private String KAFKA_TOPIC ;

    @Bean
    public NewTopic massageTopic(){
        return new NewTopic(KAFKA_TOPIC,3,(short)1);
    }
}
</code></pre><p><code><strong>return new NewTopic(KAFKA_TOPIC, 3, (short) 1);</strong></code>:</p><ul><li>This creates a <strong>Kafka topic</strong> with the following parameters:The <code>NewTopic</code> class is used to create and configure topics in Kafka.<ul><li><code>KAFKA_TOPIC</code>: This is the name of the Kafka topic, which is injected from the properties file (e.g., <code>"message-topic"</code>).</li><li><code>3</code>: This is the <strong>number of partitions</strong> for the topic. It indicates how many partitions the topic will have. More partitions mean more parallelism and scalability.</li><li><code>(short) 1</code>: This is the <strong>number of replicas</strong> for the topic. In this case, there will be one replica for the topic, which provides redundancy and fault tolerance.</li></ul></li><li>When we run and hit the endpoint<ul><li>The consumer subscribes to <code>massage-topic</code> (created with 3 partitions).</li><li>Kafka assigns 3 partitions to the consumer (<code>massage-topic-0</code>, <code>massage-topic-1</code>, and <code>massage-topic-2</code>).</li><li>The consumer starts receiving messages and processes them (e.g., the message <code>"hiii"</code>).</li></ul></li></ul><h3><strong>Producer Controller</strong>:</h3><p>Create a REST endpoint to trigger sending messages.</p><pre><code class="language-java">import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class UserKafkaProducer{

    private final KafkaTemplate&lt;String,String&gt; kafkaTemplate;

    @Value("${kafka.topic.user-random-topic}")
    private String KAFKA_TOPIC ;

    @PostMapping("/{massage}")
    public ResponseEntity&lt;String&gt; sendMassage(@PathVariable String massage){

        kafkaTemplate.send(KAFKA_TOPIC,massage);

        return ResponseEntity.ok("Massage sent!"+"    "+massage);
    }
}

</code></pre><h2><strong>Step:3. Consumer Configuration (Project 2)</strong></h2><h3><strong>application.yml (Consumer)</strong>:</h3><pre><code class="language-java">spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      key-deserializer: org.apache.kafka.common.serialization.LongDeserializer
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      group-id: ${spring.application.name}
</code></pre><h3><strong>Consumer Service</strong>:</h3><p>This class listens to messages from the Kafka topic.</p><pre><code class="language-java">import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class UserKafkaConsumer {

    @KafkaListener(topics = "massage-topic")
    public void handleUserRandomTopic(String massage){

        log.info("massage received: {}",massage);

    }
}
</code></pre><p><strong>Note: </strong>By default, <span style="background-color:rgba(135,131,120,.15);color:#EB5757;font-family:&quot;SFMono-Regular&quot;, Menlo, Consolas, &quot;PT Mono&quot;, &quot;Liberation Mono&quot;, Courier, monospace;">auto.create.topics.enable</span> is <span style="background-color:rgba(135,131,120,.15);color:#EB5757;font-family:&quot;SFMono-Regular&quot;, Menlo, Consolas, &quot;PT Mono&quot;, &quot;Liberation Mono&quot;, Courier, monospace;"><strong>true</strong></span>, allowing Kafka to automatically create topics with default settings when producers or consumers interact with non-existent topics.</p><h2><strong>Step:4. Start Kafka Server</strong></h2><p><strong>1. Download Kafka</strong>:</p><p><strong>Visit Kafka's Quickstart Page</strong>:</p><p>Go to the official <a href="https://kafka.apache.org/quickstart">Kafka Quickstart page</a> to get the latest version.</p><p><strong>Download the Latest Version</strong>: You can either download the Kafka release directly from the official site or use the following link to fetch the version 3.9.0:</p><p><strong>Download from official mirror</strong>: <a href="https://www.apache.org/dyn/closer.cgi?path=/kafka/3.9.0/kafka_2.13-3.9.0.tgz">Download Kafka 3.9.0</a></p><p><strong>2. Extract Kafka</strong></p><ul><li>After downloading the <code>.tgz</code> file, use the following command to extract it:<br>$ tar -xzf kafka_2.13-3.9.0.tgz<br>$ cd kafka_2.13-3.9.0<br>This will extract the contents of Kafka into a folder named <span style="background-color:rgba(135,131,120,.15);color:#EB5757;font-family:&quot;SFMono-Regular&quot;, Menlo, Consolas, &quot;PT Mono&quot;, &quot;Liberation Mono&quot;, Courier, monospace;">kafka_2.13-3.9.0</span>.</li></ul><p><strong>3. Start the Kafka environment</strong></p><p><i><strong>NOTE:</strong> Your local environment must have Java 8+ installed.</i></p><p><strong>Kafka Modes: KRaft or ZooKeeper</strong></p><p>Kafka can run in two configurations: <strong>KRaft mode</strong> or <strong>ZooKeeper mode</strong>. Follow the steps below for KRaft mode.</p><p><strong>Kafka with KRaft</strong> (Without ZooKeeper):</p><ol><li><strong>For Mac:</strong><ol><li><strong>Generate a Cluster UUID:&nbsp;</strong><br>KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"<br>&nbsp;</li><li><strong>Format Log Directories:&nbsp;</strong><br>$ bin/kafka-storage.sh format --standalone -t $KAFKA_CLUSTER_ID -c config/kraft/reconfig-server.properties<br>&nbsp;</li><li><strong>Start the Kafka Server:</strong><br>$ bin/kafka-server-start.sh config/kraft/reconfig-server.properties<br>&nbsp;</li></ol></li><li><strong>For Windows:&nbsp;</strong><ol><li><strong>Generate a Cluster UUID:</strong><ol><li><strong>Using PowerShell</strong>&nbsp;<br>KAFKA_CLUSTER_ID="$(bin/windows/kafka-storage.bat random-uuid)"<br><br><ol><li><strong>Windows Command Prompt</strong><br>&nbsp;i. Generate&nbsp;<br>bin\windows\kafka-storage.bat random-uuid<br><br>ii. Set <span style="background-color:rgba(135,131,120,.15);color:#EB5757;font-family:&quot;SFMono-Regular&quot;, Menlo, Consolas, &quot;PT Mono&quot;, &quot;Liberation Mono&quot;, Courier, monospace;">KAFKA_CLUSTER_ID</span><br>&nbsp;set KAFKA_CLUSTER_ID=&lt;Created ID&gt;<br>&nbsp;</li></ol></li></ol></li><li><strong>Format Log Directories:</strong><ol><li><strong>Using PowerShell</strong>&nbsp;<br>bin/windows/kafka-storage.bat format -t $KAFKA_CLUSTER_ID -c config/kraft/reconfig-server.properties<br>&nbsp;</li><li><strong>Windows Command Prompt</strong>&nbsp;<br>bin\windows\kafka-storage.bat format -t %KAFKA_CLUSTER_ID% -c config\kraft\reconfig-server .properties --standalone<br>&nbsp;</li></ol></li><li><strong>Start the Kafka Server:</strong><ol><li><strong>Using PowerShell</strong>&nbsp;<br>bin/windows/kafka-server-start.bat config/kraft/reconfig-server.properties<br>&nbsp;</li><li><strong>Windows Command Prompt</strong>&nbsp;<br>bin\windows\kafka-server-start.bat config\kraft\reconfig-server.properties<br>&nbsp;</li></ol></li></ol></li></ol><h2><strong>Step:5. Run Producer and Consumer</strong></h2><ol><li><strong>Run Project 1 (Producer Application)</strong>.</li><li><strong>Run Project 2 (Consumer Application)</strong>.</li><li>Send a message using the Producer's endpoint:<br><br>http://localhost:8010/hiii<br>&nbsp;</li><li>The Consumer will log the received message:<br>&nbsp;</li></ol><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_12_17_202511_3c7223a034.png" alt="message received"><figcaption>message received</figcaption></figure><h2>Conclusion</h2><p>This article provides an overview of Apache Kafka, emphasizing its role in distributed systems by ensuring scalability, fault tolerance, and high performance. It covers Kafka's architecture, real-time use cases, and practical integration with Spring Boot for efficient data processing and service decoupling. Kafka is a powerful event streaming platform for handling real-time data at scale, suitable for diverse applications but should be chosen based on project needs and complexity.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Kafka</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/apache_kafka_e20fe6e1ac.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[5 Spring Boot Project Ideas That Will Skyrocket Your Portfolio]]></title>
            <link>https://www.codingshuttle.com/blogs/top-5-spring-boot-project-ideas</link>
            <guid>https://www.codingshuttle.com/blogs/top-5-spring-boot-project-ideas</guid>
            <pubDate>Sat, 14 Dec 2024 13:22:41 GMT</pubDate>
            <description><![CDATA[This blog presents the Top 5 Spring Boot Project Ideas with detailed descriptions, essential features, and recommended technologies. Whether it's an E-Commerce platform, Food Delivery System, or Online Examination System]]></description>
            <content:encoded><![CDATA[<p>Spring Boot is one of the most popular frameworks for building robust and scalable applications. If you're looking to enhance your portfolio or gain practical experience, working on Spring Boot projects is a great way to do so. Here are the <strong>Top 5 Spring Boot Project Ideas</strong> that will help you sharpen your skills and stand out as a developer.</p><h2>1. E-Commerce Application</h2><p><strong>Description</strong>:</p><p>Develop a feature-rich e-commerce platform where users can browse products, add them to a cart, and place orders. Include features for admin management to handle inventory and customer orders.</p><p><strong>Features</strong>:</p><ul><li><strong>User Management</strong>: Registration, login, and role-based access for customers and admins.</li><li><strong>Product Catalog</strong>: Categories, filters, and search functionality.</li><li><strong>Shopping Cart</strong>: Add, remove, and update items.</li><li><strong>Order Management</strong>: Checkout process with payment gateway integration (mock or real).</li><li><strong>Admin Dashboard</strong>: Manage products, inventory, and orders.</li></ul><p><strong>Technologies</strong>:</p><ul><li><strong>Backend</strong>: Spring Boot with JPA/Hibernate.</li><li><strong>Database</strong>: MySQL or PostgreSQL.</li><li><strong>Frontend</strong>: Thymeleaf or Angular/React for a modern interface.</li><li><strong>APIs</strong>: REST APIs with Swagger documentation.</li></ul><h2>2. Online Food Delivery System</h2><p><strong>Description</strong>:</p><p>Build a system similar to Swiggy or Zomato, where users can order food from various restaurants, and delivery personnel can manage order deliveries.</p><p><strong>Features</strong>:</p><ul><li><strong>User Module</strong>: Register, login, and browse restaurants.</li><li><strong>Restaurant Module</strong>: Add menus, update prices, and manage orders.</li><li><strong>Order Management</strong>: Place and track orders with real-time status updates.</li><li><strong>Delivery Module</strong>: Assign delivery personnel and update order status.</li><li><strong>Payment Integration</strong>: Mock payment processing.</li></ul><p><strong>Technologies</strong>:</p><ul><li><strong>Backend</strong>: Spring Boot with Hibernate and REST APIs.</li><li><strong>Database</strong>: PostgreSQL for relational data.</li><li><strong>Frontend</strong>: React or Angular for a dynamic user interface.</li><li><strong>Others</strong>: Integration with WebSockets for real-time updates.</li></ul><h2>3. Library Management System</h2><p><strong>Description</strong>:</p><p>A library management system to manage book rentals, inventory, and user registrations for both students and staff.</p><p><strong>Features</strong>:</p><ul><li><strong>User Management</strong>: Role-based access for students, librarians, and admins.</li><li><strong>Book Catalog</strong>: Add, update, and search for books.</li><li><strong>Borrow and Return System</strong>: Track borrowed books with due dates and fines.</li><li><strong>Admin Module</strong>: Manage users and inventory.</li><li><strong>Notifications</strong>: Email or SMS reminders for due dates.</li></ul><p><strong>Technologies</strong>:</p><ul><li><strong>Backend</strong>: Spring Boot with JPA.</li><li><strong>Database</strong>: MySQL for relational data storage.</li><li><strong>Frontend</strong>: Thymeleaf or a JavaScript framework.</li><li><strong>Others</strong>: Integration with a scheduler for reminders.</li></ul><h2>4. Employee Management System</h2><p><strong>Description</strong>:</p><p>Develop an application to manage employees, including their records, salaries, attendance, and leaves.</p><p><strong>Features</strong>:</p><ul><li><strong>Employee Module</strong>: Add, view, update, and delete employee records.</li><li><strong>Attendance Tracking</strong>: Record daily attendance with timestamps.</li><li><strong>Leave Management</strong>: Apply, approve, and reject leaves.</li><li><strong>Payroll Management</strong>: Calculate and manage salaries based on attendance and leave.</li><li><strong>Reports</strong>: Generate detailed reports for admin use.</li></ul><p><strong>Technologies</strong>:</p><ul><li><strong>Backend</strong>: Spring Boot with REST APIs.</li><li><strong>Database</strong>: PostgreSQL or MongoDB for flexibility.</li><li><strong>Frontend</strong>: Bootstrap with Thymeleaf for simplicity or React/Angular for modern design.</li><li><strong>Others</strong>: Role-based authentication with Spring Security.</li></ul><h2>5. Online Examination System</h2><p><strong>Description</strong>:</p><p>Build a platform where students can take exams online, and instructors can create and evaluate tests.</p><p><strong>Features</strong>:</p><ul><li><strong>Student Module</strong>: Register, log in, and attempt exams.</li><li><strong>Instructor Module</strong>: Create, edit, and delete questions and exams.</li><li><strong>Exam Module</strong>: Timed tests with multiple-choice and descriptive questions.</li><li><strong>Result Management</strong>: Automatic grading for objective questions and manual grading for descriptive ones.</li><li><strong>Admin Module</strong>: Oversee the system and manage users.</li></ul><p><strong>Technologies:</strong></p><ul><li><strong>Backend</strong>: Spring Boot with JPA.</li><li><strong>Database</strong>: MySQL or PostgreSQL.</li><li><strong>Frontend</strong>: Angular or React for a dynamic UI.</li><li><strong>Others</strong>: Integration with WebSockets for real-time exam monitoring.</li></ul><h2>Conclusion</h2><p>These Spring Boot project ideas not only help you learn the core features of Spring Boot but also provide you with practical, real-world experience. Start with one of these projects and customize it to add your unique touch. Good luck building amazing applications!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot Project Ideas</category>
            <category>Spring Boot Top Projects</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/spring_boot_project_idea_c15a738329.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 20 Spring Boot Interview Questions for 3 years of experience Professionals]]></title>
            <link>https://www.codingshuttle.com/blogs/op-20-spring-boot-interview-questions-for-3-years-of-experience-professionals</link>
            <guid>https://www.codingshuttle.com/blogs/op-20-spring-boot-interview-questions-for-3-years-of-experience-professionals</guid>
            <pubDate>Sat, 14 Dec 2024 13:14:57 GMT</pubDate>
            <description><![CDATA[Master your Spring Boot interviews with this comprehensive guide! Designed for professionals with 3 years of experience, this blog covers 20 essential questions and answers]]></description>
            <content:encoded><![CDATA[<p>Spring Boot has become the go-to framework for Java developers due to its simplicity and productivity. If you're preparing for a Spring Boot interview with 3 years of experience, here are <strong>20 essential questions and answers</strong> to help you ace your interview.</p><h2>1. What is the purpose of Spring Boot’s @EnableAutoConfiguration annotation?</h2><p><strong>Answer:</strong> The <code>@EnableAutoConfiguration</code> annotation is used to enable Spring Boot's auto-configuration mechanism. It attempts to automatically configure your Spring application based on the libraries available on the classpath. For example, if <code>spring-data-jpa</code> is on the classpath, Spring Boot will configure a JPA EntityManagerFactory.</p><h2>2. How<code>@SpringBootApplication</code> and <code>@EnableAutoConfiguration</code> related?</h2><p><strong>Answer:</strong></p><p><strong>Relationship between </strong><code><strong>@SpringBootApplication</strong></code><strong> and </strong><code><strong>@EnableAutoConfiguration</strong></code>:</p><ul><li><code>@SpringBootApplication</code> includes <code>@EnableAutoConfiguration</code> as part of its functionality. Therefore, when you use <code>@SpringBootApplication</code> in your main application class, you're automatically enabling auto-configuration without needing to explicitly annotate your class with <code>@EnableAutoConfiguration</code>.</li><li>The key difference is that <code>@SpringBootApplication</code> is a higher-level annotation combining multiple annotations (@Configuration, @EnableAutoConfiguration, @ComponentScan), whereas <code>@EnableAutoConfiguration</code> is focused solely on auto-configuration. Using <code>@SpringBootApplication</code> simplifies the setup process, while <code>@EnableAutoConfiguration</code> can be used independently when you want to enable auto-configuration in a class without requiring component scanning or bean definitions.</li></ul><h2>3. What is the difference between @Component, @Repository, and @Service annotations in Spring Boot?</h2><p><strong>Answer:</strong></p><ul><li><code>@Component</code>: A generic stereotype for any Spring-managed component.</li><li><code>@Repository</code>: A specialization of <code>@Component</code> for data access layers; it also provides additional capabilities like exception translation.</li><li><code>@Service</code>: A specialization of <code>@Component</code> for service layers to indicate business logic.</li></ul><h2>4. How does Spring Boot support asynchronous processing?</h2><p><strong>Answer:</strong> Spring Boot supports asynchronous processing using the <code>@Async</code> annotation. To enable it, you need to add <code>@EnableAsync</code> in a configuration class. Methods annotated with <code>@Async</code> run in a separate thread pool and return a <code>Future</code> or <code>CompletableFuture</code>.</p><h2>5. What is the significance of Spring Boot’s @Conditional annotations?</h2><p><strong>Answer:</strong> Spring Boot’s <code>@Conditional</code> annotations allow beans to be loaded conditionally based on:</p><ul><li>The presence/absence of a class (<code>@ConditionalOnClass</code> or <code>@ConditionalOnMissingClass</code>).</li><li>A specific property value (<code>@ConditionalOnProperty</code>).</li><li>A particular bean being defined (<code>@ConditionalOnBean</code>).</li><li>A custom condition (<code>@Conditional</code>).</li></ul><h2>6. How does Spring Boot handle logging?</h2><p><strong>Answer:</strong> Spring Boot uses <strong>SLF4J</strong> as the default logging API and <strong>Logback</strong> as the default implementation. Logging levels can be configured in <code>application.properties</code> or <code>application.yml</code>. Example:</p><pre><code class="language-java">logging.level.org.springframework=DEBUG
logging.level.com.example=ERROR</code></pre><p>You can also customize Logback by providing a <code>logback-spring.xml</code> file in the <code>resources</code> folder.</p><h2>7. What is CSRF protection in Spring Security and how can you disable it ?</h2><p><strong>Answer:</strong></p><p><strong>CSRF (Cross-Site Request Forgery)</strong> is an attack where a user is tricked into performing unintended actions on a web application they are authenticated to. Spring Security provides protection against CSRF attacks by requiring a CSRF token for sensitive requests (like <code>POST</code>, <code>PUT</code>, <code>DELETE</code>), which ensures the request is coming from the legitimate user.</p><h3><strong>How CSRF Protection Works:</strong></h3><ul><li>Spring Security generates a CSRF token for each session.</li><li>The client must send this token in each sensitive request.</li><li>If the token doesn't match the server's stored token, the request is rejected.</li></ul><h3><strong>Disabling CSRF Protection:</strong></h3><p>For stateless applications (e.g., APIs using JWT), you can disable CSRF as it's not necessary. You can disable it with the following configuration:</p><pre><code class="language-java">@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        .antMatchers("/public/**").permitAll()
        .anyRequest().authenticated();
}</code></pre><h3><strong>When to Disable CSRF:</strong></h3><ul><li>When Using <strong>stateless authentication</strong> (like JWT) or <strong>APIs</strong>.</li><li>Not needed if you're not using session-based authentication.</li></ul><h2>8. What is the purpose of the <code>SecurityContextHolder</code> in Spring Security?</h2><p><strong>Answer:</strong></p><p><code>SecurityContextHolder</code> holds the security context of the current user, which contains the authentication information. This context is typically stored in a thread-local variable and is accessible throughout the request cycle. It provides access to the <code>Authentication</code> object, which contains details about the authenticated user.</p><h2>9. What are the benefits of Spring Boot’s actuator endpoints?</h2><p><strong>Answer:</strong> Spring Boot Actuator provides endpoints to monitor and manage your application. Benefits include:</p><ul><li>Real-time application monitoring.</li><li>Health checks with <code>/actuator/health</code>.</li><li>Metrics collection with <code>/actuator/metrics</code>.</li><li>Thread dump analysis with <code>/actuator/threaddump</code>.</li><li>Easy integration with tools like Prometheus and Grafana.</li></ul><h2>10. How does Spring Boot’s @Value annotation work?</h2><p><strong>Answer:</strong> The <code>@Value</code> annotation is used to inject values from properties files, system environment variables, or command-line arguments. Example:</p><pre><code class="language-java">@Value("${app.name}")
private String appName;</code></pre><p>If <code>app.name</code> is defined in <code>application.properties</code>, its value will be injected into <code>appName</code>.</p><h2>11. What is Spring Boot’s WebClient, and how does it differ from RestTemplate?</h2><p><strong>Answer:</strong></p><ul><li>RestTemplate is blocking and synchronous, which means the calling thread waits for the HTTP response before moving on. RestTemplate is more straightforward for simpler, traditional applications that don't require reactive features.</li><li>WebClient is non-blocking, meaning it allows asynchronous, non-blocking calls, and is more suitable for high-performance, scalable applications. WebClient is ideal for reactive applications and environments where performance is crucial, particularly when making multiple concurrent HTTP requests.</li></ul><h2>12. How does Spring manage dependency injection for circular dependencies?</h2><p><strong>Answer:</strong> Circular dependencies occur when two or more beans depend on each other directly or indirectly.</p><p><strong>Example:</strong></p><pre><code class="language-java">@Component
public class A {
    @Autowired
    private B b;
}

@Component
public class B {
    @Autowired
    private A a;
}</code></pre><p>Spring resolves them by using:</p><ul><li><strong>Setter Injection:</strong> Defers bean initialization until all dependencies are available. This allows Spring to create the beans and then set their dependencies afterward.</li></ul><pre><code class="language-java">@Component
public class A {
    private B b;

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

    public void doSomething() {
        System.out.println("Class A is working with B.");
    }
}

@Component
public class B {
    private A a;

    @Autowired
    public void setA(A a) {
        this.a = a;
    }

    public void doSomething() {
        System.out.println("Class B is working with A.");
    }
}</code></pre><ul><li><code><strong>@Lazy</strong></code><strong> Annotation:</strong> Defers initialization of one of the beans.</li></ul><pre><code class="language-java">@Component
public class A {
    @Autowired
    @Lazy
    private B b;

    public void doSomething() {
        System.out.println("Class A is working with B.");
    }
}

@Component
public class B {
    @Autowired
    private A a;

    public void doSomething() {
        System.out.println("Class B is working with A.");
    }
}</code></pre><ul><li>Refactoring to Break the Dependency If possible, refactor the design to remove the circular dependency. For instance, introduce a third bean (a mediator) that acts as a bridge between <code>A</code> and <code>B</code>.</li></ul><pre><code class="language-java">@Component
public class Mediator {
    @Autowired
    private A a;

    @Autowired
    private B b;

    public void doSomething() {
        System.out.println("Mediator is coordinating between A and B.");
        a.doSomething();
        b.doSomething();
    }
}

@Component
public class A {
    public void doSomething() {
        System.out.println("Class A is working.");
    }
}

@Component
public class B {
    public void doSomething() {
        System.out.println("Class B is working.");
    }
}</code></pre><h2>13. Explain the role of <code>@Primary</code>, <code>@Qualifier</code>, and <code>@Profile</code> in bean selection.</h2><p><strong>Answer:</strong></p><ul><li><code>@Primary</code>: Marks a bean as the default for autowiring when multiple candidates are available.</li><li><code>@Qualifier</code>: Used to specify the exact bean to inject when ambiguity exists.</li><li><code>@Profile</code>: Activates beans only in specific environments based on the active profile (e.g., <code>dev</code>, <code>prod</code>).</li></ul><h2>14. What is the difference between <code>@Bean</code> and <code>@Component</code>?</h2><p><strong>Answer:</strong></p><ul><li><code>@Component</code>: Used for automatic bean detection and registration during classpath scanning.</li><li><code>@Bean</code>: Used to explicitly declare a bean in a <code>@Configuration</code>annotated class, typically for third-party library objects or complex initialization logic. It is used when you need more control over the bean instantiation process</li></ul><h2>15. What is a Circuit Breaker, and how do you implement it in Spring Boot?</h2><p><strong>Answer:</strong> A circuit breaker prevents a system from making repeated failed calls to a service. In Spring Boot, it can be implemented using Resilience4j:</p><ol><li>Add the <code>resilience4j-spring-boot2</code> dependency.</li><li>Annotate methods with <code>@CircuitBreaker</code>.</li></ol><p>Example:</p><pre><code class="language-java">@CircuitBreaker(name = "serviceA", fallbackMethod = "fallback")
public String callServiceA() {
    return restTemplate.getForObject("&lt;http://service-a/api&gt;", String.class);
}

public String fallback(Throwable t) {
    return "Fallback response";
}</code></pre><h2>16. How do you secure Spring Boot REST APIs using OAuth2 for login with a provider like Google?</h2><p><strong>Answer:</strong></p><p><strong>Add Dependency:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-oauth2-client&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p><strong>Configure Client Registration:</strong> Add the client ID and secret in <code>application.yml</code>:</p><pre><code class="language-java">spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: YOUR_CLIENT_ID
            client-secret: YOUR_CLIENT_SECRET</code></pre><p><strong>Implement Security Configuration:</strong></p><p>Use <code>.oauth2Login()</code> in your <code>HttpSecurity</code> setup:</p><pre><code class="language-java">http
    .authorizeRequests()
    .antMatchers("/public/**").permitAll()
    .anyRequest().authenticated()
    .and()
    .oauth2Login(oauth2 -&gt; oauth2
        .failureUrl("/login?error=true")
        .successHandler(oAuth2SuccessHandler));</code></pre><p><strong>Handle OAuth2 Success:</strong> Implement a custom success handler:</p><pre><code class="language-java">@Component
public class OAuth2SuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException 
    {
        OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
        String email = ((DefaultOAuth2User) token.getPrincipal()).getAttribute("email");
        // Fetch or save user and generate tokens
        String accessToken = jwtService.generateAccessToken(user);
        response.sendRedirect("&lt;http://localhost:8080/home.html?token=&gt;" + accessToken);
    }
}</code></pre><p><strong>Process Tokens:</strong> Use your <code>JwtService</code> to generate and validate access and refresh tokens for secured API access.</p><h2>17. What is the purpose of <code>@DataJpaTest</code> in Spring Boot?</h2><p><strong>Answer:</strong> <code>@DataJpaTest</code> is used for testing the JPA repository layer. It configures an in-memory database and loads the repository beans but excludes other Spring components like the service or controller layer. It is primarily used for testing database interactions in isolation. Example:</p><pre><code class="language-java">@RunWith(SpringRunner.class)
@DataJpaTest
public class MyRepositoryTest {

    @Autowired
    private MyRepository myRepository;

    @Test
    public void testRepositoryMethod() {
        MyEntity entity = myRepository.save(new MyEntity("Test"));
        assertNotNull(entity);
    }
}</code></pre><h2>18. What are @ConfigurationProperties in Spring Boot?</h2><p><strong>Answer:</strong></p><p><code>@ConfigurationProperties</code> binds hierarchical configuration properties to Java objects.&nbsp;</p><p>Example:</p><pre><code class="language-java">@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String version;
}</code></pre><h3><code><strong>@ConfigurationProperties(prefix = "app")</strong></code></h3><ul><li>Maps properties with the prefix <code>app</code> to the fields of this class. For example:<br>If your <code>application.yml</code> has:</li></ul><pre><code class="language-java">app:
  name: MyApplication
  version: 1.0.0</code></pre><p>These values will automatically be set to the <code>name</code> and <code>version</code> fields of the <code>AppProperties</code> class.<br>Example Usage:<br>You can now inject <code>AppProperties</code> into any other Spring component using <code>@Autowired</code>:</p><pre><code class="language-java">@Component
public class MyService {
    private final AppProperties appProperties;

    @Autowired
    public MyService(AppProperties appProperties) {
        this.appProperties = appProperties;
    }

    public void printAppDetails() {
        System.out.println("App Name: " + appProperties.getName());
        System.out.println("App Version: " + appProperties.getVersion());
    }
}</code></pre><h2>19. How does Spring Boot handle caching, and what are the different annotations available for caching?</h2><p><strong>Answer:</strong> Spring Boot handles caching through its <code>@Cacheable</code>, <code>@CachePut</code>, and <code>@CacheEvict</code> annotations.</p><ul><li><code>@Cacheable</code>: Caches the result of a method. If the method is called with the same parameters, the cached result is returned instead of executing the method again.</li><li><code>@CachePut</code>: Updates the cache with the method’s result, even if the result already exists in the cache.</li><li><code>@CacheEvict</code>: Removes data from the cache. It can be used for clearing caches after an update.</li></ul><p>Example:</p><pre><code class="language-java">@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) { ... }

@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) { ... }

@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) { ... }</code></pre><h2>20. What are the different scopes of Spring Beans?</h2><p><strong>Answer:</strong></p><p>Spring supports the following bean scopes:</p><ol><li><code><strong>singleton</strong></code> (default):<ul><li>A single shared instance of the bean is created and used throughout the Spring IoC container. This is the default scope if no scope is specified.</li><li>Every request for this bean will return the same instance.</li></ul></li><li><code><strong>prototype</strong></code>:<ul><li>A new instance of the bean is created each time it is requested from the Spring container.</li><li>This scope is suitable for beans that need to be stateless or have a short lifecycle.</li></ul></li><li><code><strong>request</strong></code> (Web applications only):<ul><li>A new instance is created for each HTTP request.</li><li>The bean is only available during the lifecycle of the HTTP request and is discarded after the request is completed.</li></ul></li><li><code><strong>session</strong></code> (Web applications only):<ul><li>A new instance is created for each HTTP session.</li><li>The bean is tied to the HTTP session and remains active for the duration of that session.</li></ul></li><li><code><strong>application</strong></code> (Web applications only):<ul><li>A single instance of the bean is created for the entire ServletContext (the entire web application).</li><li>The bean is shared across all HTTP requests and sessions in the application.</li></ul></li><li><code><strong>websocket</strong></code> (Web applications only):<ul><li>A new instance is created for each WebSocket connection.</li><li>The bean is tied to the lifecycle of a WebSocket connection and is discarded once the connection is closed.</li></ul></li></ol><h2>Conclusion</h2><p>Preparing for a Spring Boot interview as a professional with 3 years of experience requires a solid grasp of the framework’s key concepts, annotations, and practical implementations. This blog has covered some of the most important interview questions to help you build confidence and showcase your expertise during the interview.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot Interview Questions</category>
            <category>3 years experience Spring Boot interview questions</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/top_20_spring_boot_interview_6989680f5a.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Crack Your Next Interview: Top 12 Java 8 Questions and Answers For 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/top-10-java-8-interview-questions</link>
            <guid>https://www.codingshuttle.com/blogs/top-10-java-8-interview-questions</guid>
            <pubDate>Sat, 14 Dec 2024 11:37:16 GMT</pubDate>
            <description><![CDATA[Discover the top Java 8 interview questions and answers for 2025. This guide covers key features like Lambda Expressions, Stream API, Functional Interfaces, Optional, and more.]]></description>
            <content:encoded><![CDATA[<p>If you are preparing for Java interview, Java 8 is a important because it introduced game changing features that are still widely used in 2025. Whether you are a beginner or brushing up your skills, these questions will help you to understand Java 8 features.</p><p>In this article, I have explained the top Java 8 interview questions with clear, friendly answers. I have also added code snippets wherever needed to improve understanding.</p><h2>1. What are the key features introduced in Java 8?</h2><p>Java 8, released in 2014, brought some major upgrades to make coding easier and more powerful. The key features are:</p><ul><li><strong>Lambda Expressions</strong>: Write concise code for functional interfaces (more on this later).</li><li><strong>Stream API</strong>: Process collections efficiently with functional-style operations.</li><li><strong>Functional Interfaces</strong>: Interfaces with a single abstract method, like Runnable or Comparator.</li><li><strong>Default Methods</strong>: Add methods with implementation to interfaces without breaking existing code.</li><li><strong>Optional</strong>: Handle null values safely to avoid NullPointerException.</li><li><strong>Date and Time API</strong>: A modern replacement for the old Date and Calendar classes.</li><li><strong>Method References</strong>: Shorthand for lambda expressions to refer to methods directly.</li></ul><p>These features make Java more expressive and functional, so expect interviewers to focus on them.</p><h2>2. What is a Lambda Expression, and how does it work?</h2><p>A <strong>Lambda Expression</strong> is a concise way to represent a method of a functional interface. It’s like a shortcut for anonymous classes, letting you write less code for simple operations. The syntax is: (parameters) -&gt; expression or (parameters) -&gt; { statements; }.</p><p><strong>Example:</strong></p><pre><code class="language-java">import java.util.Arrays;
import java.util.List;

public class LambdaExample {
    public static void main(String[] args) {
        List&lt;String&gt; names = Arrays.asList("Alice", "Bob", "Charlie");
        // Lambda to print each name
        names.forEach(name -&gt; System.out.println(name));
    }
}</code></pre><p><strong>Output:</strong></p><pre><code class="language-plaintext">Alice
Bob
Charlie</code></pre><p>Here, name -&gt; System.out.println(name) is a lambda that replaces an anonymous Consumer implementation. Lambdas shine in functional programming, making code shorter and clearer.</p><h2>3. What is a Functional Interface?</h2><p>A <strong>Functional Interface</strong> is an interface with exactly one abstract method. It’s used with lambda expressions and method references. Java 8 introduced the @FunctionalInterface annotation to enforce this rule.</p><p><strong>Example:</strong></p><pre><code class="language-java">@FunctionalInterface
interface MyFunction {
    void apply(String input);
}

public class FunctionalInterfaceExample {
    public static void main(String[] args) {
        MyFunction func = (s) -&gt; System.out.println("Hello, " + s);
        func.apply("Alice"); // Output: Hello, Alice
    }
}</code></pre><p>Java’s java.util.function package provides built-in functional interfaces like Consumer, Predicate, and Function.</p><h2>4. What is the Stream API, and how is it used?</h2><p>The <strong>Stream API</strong> lets you process collections of data in a functional, declarative way. You can chain operations like filtering, mapping, or sorting without explicit loops. Streams are lazy—they only execute when a terminal operation (like collect or forEach) is called.</p><p><strong>Example:</strong></p><pre><code class="language-java">import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {
    public static void main(String[] args) {
        List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);
        // Filter even numbers and collect to a new list
        List&lt;Integer&gt; evens = numbers.stream()
                                     .filter(n -&gt; n % 2 == 0)
                                     .collect(Collectors.toList());
        System.out.println(evens); // Output: [2, 4]
    }
}</code></pre><p>Here, stream() creates a stream, filter keeps even numbers, and collect gathers the results. Streams make code concise and readable.</p><h2>5. What are Default Methods in Interfaces?</h2><p><strong>Default Methods</strong> allow you to add methods with implementation in interfaces. This lets you extend interfaces without breaking existing classes that implement them. Use the default keyword.</p><p><strong>Example:</strong></p><pre><code class="language-java">interface Vehicle {
    default void stop() {
        System.out.println("Vehicle stopped.");
    }
    void drive(); // Abstract method
}

class Car implements Vehicle {
    @Override
    public void drive() {
        System.out.println("Car is driving.");
    }
}

public class DefaultMethodExample {
    public static void main(String[] args) {
        Car car = new Car();
        car.drive(); // Output: Car is driving.
        car.stop(); // Output: Vehicle stopped.
    }
}</code></pre><p>Default methods are great for evolving APIs without forcing all implementing classes to change.</p><h2>6. What is the Optional class, and how does it help?</h2><p>The <strong>Optional</strong> class is a wrapper for values that might be null. It encourages safer coding by making you explicitly handle the possibility of null values, reducing NullPointerException.</p><p><strong>Example:</strong></p><pre><code class="language-java">import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        Optional&lt;String&gt; name = Optional.ofNullable(null);
        // Check if value is present
        String result = name.orElse("Unknown");
        System.out.println("Name: " + result); // Output: Name: Unknown
    }
}</code></pre><p>Here, orElse provides a default if the Optional is empty. Methods like isPresent(), orElseGet(), and ifPresent() make Optional powerful for null handling.</p><h2>7. What is the difference between map and flatMap in Streams?</h2><ul><li>map: Transforms each element in a stream to another element, producing a one-to-one mapping.</li><li>flatMap: Flattens nested collections (like streams of lists) into a single stream, handling one-to-many mappings.</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MapVsFlatMap {
    public static void main(String[] args) {
        List&lt;List&lt;String&gt;&gt; nestedList = Arrays.asList(
            Arrays.asList("A1", "A2"),
            Arrays.asList("B1", "B2")
        );

        // Using map (keeps nested structure)
        List&lt;List&lt;String&gt;&gt; mapped = nestedList.stream()
                                             .map(list -&gt; list)
                                             .collect(Collectors.toList());
        System.out.println(mapped); // Output: [[A1, A2], [B1, B2]]

        // Using flatMap (flattens structure)
        List&lt;String&gt; flattened = nestedList.stream()
                                          .flatMap(list -&gt; list.stream())
                                          .collect(Collectors.toList());
        System.out.println(flattened); // Output: [A1, A2, B1, B2]
    }
}</code></pre><p>map keeps the lists intact, while flatMap merges them into a single list.</p><h2>8. What is the new Date and Time API in Java 8?</h2><p>Java 8’s <strong>Date and Time API</strong> (in java.time) replaces the clunky Date and Calendar classes. It’s more intuitive and thread-safe, with classes like LocalDate, LocalTime, and LocalDateTime.</p><p><strong>Example:</strong></p><pre><code class="language-java">import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateTimeExample {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
        System.out.println("Today: " + today.format(formatter)); // Output: Today: 23-07-2025
    }
}</code></pre><p>The new API is easier to use, immutable, and avoids issues like thread-safety problems in the old Date class.</p><h2>9. What are Method References, and how do they differ from Lambda Expressions?</h2><p><strong>Method References</strong> are a shorthand for lambda expressions that call an existing method. They use the :: operator and make code cleaner.</p><p><strong>Example:</strong></p><pre><code class="language-java">import java.util.Arrays;
import java.util.List;

public class MethodReferenceExample {
    public static void main(String[] args) {
        List&lt;String&gt; names = Arrays.asList("Alice", "Bob", "Charlie");
        // Lambda
        names.forEach(name -&gt; System.out.println(name));
        // Method Reference
        names.forEach(System.out::println);
    }
}</code></pre><p>Both print the same output, but System.out::println is more concise than the lambda. Types of method references include:</p><ul><li>Class::staticMethod (e.g., Math::abs)</li><li>instance::instanceMethod (e.g., String::toUpperCase)</li><li>Class::new (for constructors)</li></ul><h2>10. What is the difference between intermediate and terminal operations in Streams?</h2><ul><li><strong>Intermediate Operations</strong>: Transform or filter a stream and return another stream (lazy). Examples: filter, map, sorted.</li><li><strong>Terminal Operations</strong>: Produce a result or side effect and end the stream. Examples: collect, forEach, reduce.</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">import java.util.Arrays;
import java.util.List;

public class StreamOperations {
    public static void main(String[] args) {
        List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);
        // Intermediate: filter, map
        // Terminal: forEach
        numbers.stream()
               .filter(n -&gt; n % 2 == 0) // Intermediate
               .map(n -&gt; n * 2) // Intermediate
               .forEach(System.out::println); // Terminal, Output: 4, 8
    }
}</code></pre><h2>11. What are the differences between a Stream and a Collection?</h2><p>A <strong>Stream</strong> and a <strong>Collection</strong> both handle data, but they serve different purposes:</p><ul><li><strong>Purpose</strong>:<ul><li><strong>Collection</strong>: Stores data in memory (e.g., List, Set). It’s about holding and managing data.</li><li><strong>Stream</strong>: Processes data in a functional, pipeline-like way without storing it. It’s about computation.</li></ul></li><li><strong>Mutability</strong>:<ul><li><strong>Collection</strong>: Mutable—you can add, remove, or modify elements.</li><li><strong>Stream</strong>: Immutable—you can’t change the source data; streams generate new results.</li></ul></li><li><strong>Execution</strong>:<ul><li><strong>Collection</strong>: Data is eagerly loaded (all elements are in memory).</li><li><strong>Stream</strong>: Lazy—operations are only executed when a terminal operation is called.</li></ul></li><li><strong>Reusability</strong>:<ul><li><strong>Collection</strong>: Can be reused multiple times.</li><li><strong>Stream</strong>: Can only be consumed once; you need a new stream for further operations.</li></ul></li></ul><p><strong>Example:</strong></p><pre><code class="language-java">import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamVsCollection {
    public static void main(String[] args) {
        List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);

        // Collection: Store and manipulate data
        numbers.add(6); // Error: UnsupportedOperationException (immutable list)
        System.out.println("Collection: " + numbers); // Output: Collection: [1, 2, 3, 4, 5]

        // Stream: Process data
        List&lt;Integer&gt; evens = numbers.stream()
                                     .filter(n -&gt; n % 2 == 0)
                                     .collect(Collectors.toList());
        System.out.println("Stream result: " + evens); // Output: Stream result: [2, 4]
    }
}</code></pre><h2>12. What is the Optional class in Java 8? Why is it useful?</h2><p>The <strong>Optional</strong> class is a wrapper for values that might be null. It encourages safer coding by making you explicitly handle the possibility of null values, reducing NullPointerException.</p><p><strong>Why it’s useful:</strong></p><ul><li>Prevents null-related bugs by forcing you to check for presence.</li><li>Improves code readability with methods like orElse, ifPresent, and orElseGet.</li><li>Encourages a functional programming style for handling missing values.</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        Optional&lt;String&gt; name = Optional.ofNullable(null);
        // Check if value is present
        String result = name.orElse("Unknown");
        System.out.println("Name: " + result); // Output: Name: Unknown

        // Using ifPresent
        name.ifPresent(n -&gt; System.out.println("Name is: " + n)); // No output
    }
}</code></pre><h2>Conclusion</h2><p>Java 8 features like lambdas, streams, and the new Date/Time API revolutionized how we write Java code, and they’re still super relevant in 2025. Mastering Java 8 is a stepping stone toward becoming a proficient Java developer. These concepts not only boost your chances in interviews but also prepare you for real-world backend systems.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Java</category>
            <category>Java 8</category>
            <category>Java Interview Questions</category>
            <category>Advance Java</category>
            <category>Core Java</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Crack_Your_Next_Interview_Top_12_Java_8_Questions_and_Answers_For_2025_5e2e147f70.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Instantly Deploy Spring Boot with Docker Compose — Step-by-Step Guide]]></title>
            <link>https://www.codingshuttle.com/blogs/how-to-setup-docker-compose-for-a-basic-spring-boot-application</link>
            <guid>https://www.codingshuttle.com/blogs/how-to-setup-docker-compose-for-a-basic-spring-boot-application</guid>
            <pubDate>Sat, 14 Dec 2024 11:16:42 GMT</pubDate>
            <description><![CDATA[Learn how to containerize a Spring Boot application and its dependencies using Docker Compose. This blog covers creating a simple Spring Boot project with PostgreSQL, writing a Dockerfile for containerization, configuring docker-compose.yml for multi-container orchestration]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p><strong>Docker Compose</strong> simplifies running multi-container Docker applications by managing services through a single configuration file. For a Spring Boot application, it helps containerize the application and its dependencies, like a database, for seamless deployment. This guide walks you through setting up Docker Compose for a basic Spring Boot application.</p><h2>Steps</h2><h2><strong>Step-1 Create Simple Spring boot project</strong></h2><ol><li>Visit <a href="https://start.spring.io/">https://start.spring.io/</a> and create the basic spring boot project, we will create a basic messaging project which will store text messages in postgreSQL database</li></ol><figure class="image image_resized" style="width:75%;"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/spring_Initializer_1_f56ed32457.png" alt="springInitializer_1.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_spring_Initializer_1_f56ed32457.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_spring_Initializer_1_f56ed32457.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_spring_Initializer_1_f56ed32457.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_spring_Initializer_1_f56ed32457.png 1000w," sizes="100vw"></figure><ol><li>Add the dependencies as shown in above figure and generate the zip folder, after generating the zip folder extract the folder and open the project in Intellij or any other editor you prefer.</li></ol><h2><strong>Step-2 Project Structure</strong></h2><p>Create the Controller Endpoints, Service and Repository for the project, we will be creating simple messaging app which will allow us to create message and store them in postgres DB and fetch all the messages.</p><ol><li>Entity class</li></ol><pre><code class="language-java">@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Message {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String title;
}</code></pre><ol><li>Repository</li></ol><pre><code class="language-java">@Repository
public interface MessagingRepository extends JpaRepository&lt;Message,Long&gt; {
}</code></pre><ol><li>Service</li></ol><pre><code class="language-java">@Service
@RequiredArgsConstructor
public class MessagingService {
    private final MessagingRepository messagingRepository;

    public Message createMessage(Message message){
        return messagingRepository.save(message);
    }

    public List&lt;Message&gt; getMessages(){
        return messagingRepository.findAll();
    }
}</code></pre><ol><li>Controller</li></ol><pre><code class="language-java">@RestController
@RequestMapping("/messages")
@RequiredArgsConstructor
public class MessagingController {
    private final MessagingService messagingService;

    @PostMapping("/createMessage")
    ResponseEntity&lt;Message&gt; createMessage(@RequestBody Message message){
        System.out.println(message.getId());
        return ResponseEntity.ok(messagingService.createMessage(message));
    }

    @GetMapping
    ResponseEntity&lt;List&lt;Message&gt;&gt; getMessages(){
        return ResponseEntity.ok(messagingService.getMessages());
    }
}</code></pre><p>Application properties</p><p>Configure database related configuration in <a href="http://application.properties">application.properties</a> file</p><pre><code class="language-php">spring.application.name=messaging

server.port=8080

spring.datasource.url=jdbc:postgresql://messaging-db:5432/messaging_db
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=create-drop</code></pre><p>Note:- Here messaging-db is the container name in which the postgres is running.</p><h2><strong>Step-3 Docker Installation</strong></h2><ol><li>Visit <a href="https://docs.docker.com/desktop/setup/install/windows-install/">https://docs.docker.com/desktop/setup/install/windows-install/</a> to install docker desktop on windows.</li><li>Visit <a href="https://docs.docker.com/desktop/setup/install/mac-install/">https://docs.docker.com/desktop/setup/install/mac-install/</a> to install docker on mac system.</li><li>After installing docker on your machine start docker engine.</li></ol><h2><strong>Step-4 Creating Docker file</strong></h2><ol><li>We have to create a Dockerfile and place it at a root directory of our project, with the help of this docker file we can build the docker image of our project.</li><li>Dockerfile</li></ol><pre><code class="language-php">FROM maven:3.9.4-eclipse-temurin-21-alpine

WORKDIR /app

COPY .mvn/ .mvn
COPY mvnw pom.xml ./
RUN ./mvnw dependency:go-offline

COPY src ./src

CMD ["./mvnw", "spring-boot:run"]</code></pre><ol><li>Understanding the Dockerfile</li></ol><p>This <code>Dockerfile</code> creates a Docker image for the Spring Boot application. It uses Maven as the build tool and ensures all dependencies are resolved before running the application. Let’s explore each line: -&nbsp;</p><ol style="list-style-type:decimal;"><li><strong>Base Image:</strong><ul><li>Uses the official Maven Docker image (<code>maven:3.9.4-eclipse-temurin-21-alpine</code>) as the foundation.</li><li>This image is lightweight (<code>alpine</code>) and includes:</li><li>Maven version <code>3.9.4</code> for building the application.</li><li>Java Development Kit (JDK) version <code>21</code> (Temurin), compatible with Spring Boot.</li></ul></li></ol><ol><li><strong>Setting the Working Directory - WORKDIR /app</strong><ul><li>Sets the working directory for the image to <code>/app</code>.</li><li>All subsequent commands will run inside this directory.</li></ul></li><li><strong>Copy Maven Wrapper Files</strong><br>&nbsp;&nbsp;<strong> &nbsp;COPY .mvn/ .mvn</strong><br><strong>&nbsp; &nbsp; COPY mvnw pom.xml ./</strong><ul><li><code>.mvn/</code> and <code>mvnw</code>: The Maven Wrapper files allow the project to use a specific Maven version without requiring Maven pre-installed on the host.</li><li><code>pom.xml</code>: The Maven Project Object Model file containing dependency and build configurations.</li></ul></li><li><strong>Download Dependencies - RUN ./mvnw dependency:go-offline</strong><ul><li>Downloads all project dependencies and plugins required for the build.</li><li>Ensures the container can build the application without accessing the internet later, improving speed and reliability.</li></ul></li><li><strong>Copy Application Source Code - COPY src ./src</strong><ul><li>Copies the entire <span style="background-color:rgba(135,131,120,.15);color:#EB5757;font-family:&quot;SFMono-Regular&quot;, Menlo, Consolas, &quot;PT Mono&quot;, &quot;Liberation Mono&quot;, Courier, monospace;">src</span> directory from the local machine into the <span style="background-color:rgba(135,131,120,.15);color:#EB5757;font-family:&quot;SFMono-Regular&quot;, Menlo, Consolas, &quot;PT Mono&quot;, &quot;Liberation Mono&quot;, Courier, monospace;">/app/src</span> directory inside the container.</li></ul></li><li><strong>Start the Application - CMD ["./mvnw", "spring-boot:run"]</strong><ol><li><strong>CMD -</strong> Defines the command to run the Spring Boot application using the Maven Wrapper.</li><li><strong>spring-boot:run</strong> : Launches the Spring Boot application directly from the source, ideal for development environments.</li></ol></li></ol><h2><strong>Step-5 Creating Docker-compose file for your spring boot project</strong></h2><ol style="list-style-type:decimal;"><li>Create docker-compose.yml file and place it at the root dir of your project</li><li>docker-compose.yml file</li></ol><pre><code class="language-php">version: '3.8'

services:
  messaging-app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    depends_on:
      - messaging-db
    networks:
      - messaging-network
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/messaging_db
      SPRING_DATASOURCE_USERNAME: postgres
      SPRING_DATASOURCE_PASSWORD: postgres

  messaging-db:
    image: postgres:15
    container_name: postgres_db
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: messaging_db
    ports:
      - "5432:5432"
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - messaging-network

volumes:
  db_data:

networks:
  messaging-network:</code></pre><h2><strong>Before moving forward let's understand the docker-compose file</strong></h2><p>Breaking Down the <code>docker-compose.yml</code> File for Messaging App. This <code>docker-compose.yml</code> file defines a multi-container setup for the Messaging App, which includes a Spring Boot application (<code>messaging-app</code>) and a PostgreSQL database (<code>messaging-db</code>). Let's walk through each section to understand its purpose.</p><ol><li>Version version: '3.8’ - Specifies the Docker Compose file format version. Version <code>3.8</code> is the latest supported version for modern Docker setups, ensuring compatibility with features like custom networks.</li><li><strong>Services</strong>: The <code>services</code> section defines the containers that make up the application.</li></ol><ul><li><strong>build</strong>:<ul><li>Specifies the build context (<code>.</code> refers to the current directory) and the <code>Dockerfile</code> used to containerize the application.</li></ul></li><li><strong>ports</strong>:<ul><li>Maps port <code>8080</code> on the host machine to port <code>8080</code> in the container, making the application accessible locally at <code>http://localhost:8080</code>.</li></ul></li><li><strong>depends_on</strong>:<ul><li>Ensures the <code>messaging-db</code> service (PostgreSQL database) starts before the <code>messaging-app</code> service.</li></ul></li><li><strong>networks</strong>:<ul><li>Connects the <code>messaging-app</code> container to the <code>messaging-network</code> for isolated communication between services.</li></ul></li><li><strong>environment</strong>:<ul><li>Overrides database configuration in the Spring Boot application:<ul><li><code><strong>SPRING_DATASOURCE_URL</strong></code>: Points to the <code>messaging-db</code> service at <code>messaging_db</code>, the alias provided by the Docker Compose network.</li><li><code><strong>SPRING_DATASOURCE_USERNAME</strong></code><strong> and </strong><code><strong>SPRING_DATASOURCE_PASSWORD</strong></code> : Credentials for the PostgreSQL database.</li></ul></li></ul></li><li><strong>image</strong>:<ul><li>Specifies the PostgreSQL Docker image version <code>15</code>.</li></ul></li><li><strong>container_name</strong>:<ul><li>Assigns the container a fixed name (<code>postgres_db</code>) for easier identification in commands and logs.</li></ul></li><li><strong>environment</strong>:<ul><li>Configures the PostgreSQL instance:<ul><li><code><strong>POSTGRES_USER</strong></code>: Database username.</li><li><code><strong>POSTGRES_PASSWORD</strong></code>: Database password.</li><li><code><strong>POSTGRES_DB</strong></code>: Creates a default database named <code>messaging_db</code>.</li></ul></li></ul></li><li><strong>ports</strong>:<ul><li>Maps port <code>5432</code> on the host to port <code>5432</code> inside the container, enabling local access to the database.</li></ul></li><li><strong>volumes</strong>:<ul><li>Defines a persistent volume (<code>db_data</code>) to store PostgreSQL data, ensuring data is not lost when containers are restarted.</li></ul></li><li><strong>networks</strong>:<ul><li>Connects the database to the same <code>messaging-network</code> for seamless communication with the application.</li></ul></li></ul><ol><li><strong>Volumes</strong><ul><li>Creates a named volume (<code>db_data</code>) to persist PostgreSQL data outside the container lifecycle.</li><li>Stored data survives container restarts or removal, making it ideal for production setups.</li></ul></li><li><strong>Networks</strong><ul><li>Defines a custom Docker network (<code>messaging-network</code>) for the <code>messaging-app</code> and <code>messaging-db</code> services.</li><li>Ensures isolated and secure communication between the containers, preventing interference from other Docker networks.</li></ul></li></ol><h2><strong>Step-6 Run Docker Compose</strong></h2><p>Run command</p><ol><li>Open a terminal in your project directory.</li><li>Run the following command to build and start the containers:</li></ol><pre><code class="language-ruby">docker-compose up --build</code></pre><p>Verify:</p><ul><li>Your Spring Boot app should be accessible at http://localhost:8080.</li><li>PostgreSQL is running at localhost:5432.</li></ul><h2><strong>Step-7 Testing</strong></h2><ol><li>Test your endpoints using tools like Postman or CURL.</li><li>&nbsp;logChecks to ensure the services are communicating:</li></ol><pre><code class="language-ruby">docker-compose logs messaging-app
docker-compose logs messaging-db</code></pre><h2><strong>Step-8 Clean Up</strong></h2><p>To stop and remove containers, use:</p><pre><code class="language-ruby">docker-compose down</code></pre><h2>Conclusion</h2><p>Using Docker Compose, you can streamline development by creating isolated environments for your Spring Boot application and its dependencies. This setup ensures consistency, scalability, and ease of deployment.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Docker Compose</category>
            <category>Docker</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/dockerr_1b428e1f4a.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Coding Shuttle’s 0 to 100 Spring Boot Course: Inside The Most Searched Course On The Internet]]></title>
            <link>https://www.codingshuttle.com/blogs/how-is-the-coding-shuttle-spring-boot-0-to-100-course-the-best-resource-in-2025</link>
            <guid>https://www.codingshuttle.com/blogs/how-is-the-coding-shuttle-spring-boot-0-to-100-course-the-best-resource-in-2025</guid>
            <pubDate>Sat, 14 Dec 2024 10:27:48 GMT</pubDate>
            <description><![CDATA[Master backend development in 2025 with the Coding Shuttle Spring Boot 0 to 100 Course by Anuj Bhaiya. From fundamentals to advanced microservices]]></description>
            <content:encoded><![CDATA[<p>In the ever-evolving tech landscape of 2025, mastering backend development is essential for developers aiming to work on scalable, production-grade systems. The <strong>Coding Shuttle Spring Boot 0 to 100 Course</strong> by Anuj Bhaiya is the ultimate resource for developers looking to excel. Here's why this course sets the benchmark for Spring Boot learning.</p><h2>A Revolutionary Curriculum for Backend Developers</h2><p>The course offers a unique, all-encompassing curriculum that transitions learners from foundational Spring Boot concepts to advanced microservice architectures. It is designed for developers of all skill levels, ensuring that even beginners can seamlessly build expertise.</p><p><strong>Topics Covered:</strong></p><ul><li><strong>Spring Boot Fundamentals:</strong> IoC Container, Beans, Dependency Injection, and AutoConfigurations.</li><li><strong>REST API Development:</strong> Learn to build RESTful APIs, handle exceptions, and polish responses for production-ready systems.</li><li><strong>Microservice Architecture:</strong> Create modular services, implement service discovery, and secure microservices using JWT.</li><li><strong>Integration with Modern Tools:</strong> Redis, Kafka, Docker, Kubernetes, and the ELK stack for logging.</li><li><strong>Advanced Features:</strong> Circuit breaker patterns with Resilience4J, centralized configurations with Spring Cloud Config, and API gateways with Spring Cloud Gateway.</li></ul><h2>Hands-On Learning with Real-World Projects</h2><p>The course doesn’t stop at theory—it immerses you in building real-world, industry-relevant projects that mimic complex production environments.</p><h3><strong>Phase 0-1 Projects</strong></h3><ul><li><strong>Airbnb Clone:</strong> Learn the intricacies of building a robust backend for a rental platform.</li><li><strong>BookMyShow Clone:</strong> Dive into the complexities of ticket booking systems, from managing seat availability to advance transactions.</li></ul><h3><strong>Phase 1-100 Projects</strong></h3><ul><li><strong>LinkedIn Clone (with Microservices):</strong> Master the microservice architecture while creating a professional networking platform.</li><li><strong>X (Twitter Clone):</strong> Master the art of building high-performance systems that handle real-time user interactions, support scalable communication networks, and efficiently manage dynamic content updates.</li></ul><p>These projects ensure that learners gain practical exposure, understand system design principles, and can confidently tackle real-world backend challenges.</p><h2>Why This Course Stands Out in 2025</h2><h3><strong>1. Project-Based Learning</strong></h3><p>Unlike traditional courses, the <strong>Coding Shuttle Spring Boot 0 to 100 Course</strong> emphasizes <strong>learning by doing.</strong> By working on these advanced projects, learners understand not just <i>what</i> to do but also <i>why</i> and <i>how</i>—essential skills for modern developers.</p><h3><strong>2. Live Support and Weekly Classes</strong></h3><p>The combination of <strong>pre-recorded videos</strong> for self-paced learning and <strong>weekly live classes</strong> sets this course apart. Every Saturday, learners join live sessions where they implement the week’s concepts and get real-time feedback and doubt resolution.</p><h3><strong>3. Master Microservices and Modern Tools</strong></h3><p>The course’s focus on microservices reflects the shift in the tech industry toward modular, scalable architectures. Coupled with tools like <strong>Redis</strong>, <strong>Kafka</strong>, <strong>Docker</strong>, and <strong>Kubernetes</strong>, it ensures learners are equipped to work on the most advanced systems.</p><h3><strong>4. All-Inclusive Curriculum</strong></h3><p>The course covers every aspect of Spring Boot development, from foundational concepts to building, deploying, and managing microservices in production environments.</p><h3><strong>5. Industry-Relevant Skills</strong></h3><p>The course mirrors the backend challenges faced by companies like Airbnb, LinkedIn, and Twitter. By the end of the program, learners are ready to tackle production systems at any scale.</p><h2>Real-World Tools and Techniques</h2><p>The course introduces students to modern tools that are indispensable for backend developers in 2025:</p><ul><li><strong>Spring Boot Actuator:</strong> Monitor application performance.</li><li><strong>Swagger and OpenAPI:</strong> Create detailed API documentation.</li><li><strong>Docker and Kubernetes:</strong> Deploy scalable applications.</li><li><strong>Kafka:</strong> Build event-driven architectures.</li><li><strong>Spring Cloud Tools:</strong> Implement service discovery, centralized configuration, and API gateways.</li><li><strong>CI/CD Pipelines:</strong> Automate deployments using AWS CodePipeline and Elastic Beanstalk.</li></ul><p>These tools are integrated into the projects, ensuring learners don’t just learn them in isolation but see their real-world applications.</p><h2>What Makes This Course Better Than Other Resources?</h2><ol><li><strong>Practical Approach:</strong> While many courses stick to theoretical concepts, this one emphasizes hands-on projects, giving learners a competitive edge.</li><li><strong>Real-Time Interaction:</strong> Weekly live classes help clear doubts and provide personalized guidance, unlike pre-recorded courses on platforms like Udemy.</li><li><strong>Cutting-Edge Technologies:</strong> From microservices to Kubernetes, the course keeps up with the latest industry trends.</li><li><strong>Well-Structured Learning Path:</strong> Learners progress systematically from basic concepts to advanced systems, ensuring no gaps in understanding.</li></ol><h2>Final Thoughts</h2><p>I learned Spring Boot from this course and now I am confident in my capabilities with Spring Boot. The <strong>Coding Shuttle Spring Boot 0 to 100 Course</strong> is more than a learning resource—it’s a career accelerator. By the end of the course, you’ll have built scalable systems like <strong>Airbnb</strong>, <strong>BookMyShow</strong>, <strong>LinkedIn</strong>, and <strong>X (Twitter)</strong>, gained expertise in microservices, and mastered tools like Docker, Kubernetes, and Kafka.</p><p>If you’re serious about backend development and want to work on production-level systems in 2025, this course is your ultimate guide. With its practical projects, cutting-edge curriculum, and live interaction, the <strong>Coding Shuttle Spring Boot Course</strong> is truly the best resource for developers this year.</p><p><strong>Start your journey now and become a backend expert with Anuj Bhaiya’s guidance!</strong></p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring boot Course</category>
            <category>Coding Shuttle Spring Boot 0 to 100 Course</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/spring_boot_0_to_100_4a6942ce76.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[10 Essential Java Design Patterns Every Developer Should Master (With Code Examples)]]></title>
            <link>https://www.codingshuttle.com/blogs/top-8-design-patterns-in-java</link>
            <guid>https://www.codingshuttle.com/blogs/top-8-design-patterns-in-java</guid>
            <pubDate>Thu, 12 Dec 2024 13:21:20 GMT</pubDate>
            <description><![CDATA[Learn 10 essential Java design patterns every developer should know, including Singleton, Factory, Builder, Observer, and more. Each pattern includes simple explanations, real-world examples, and practical Java code.]]></description>
            <content:encoded><![CDATA[<p>When you're working on any project, writing clean and reusable code becomes important and that's where <strong>design patterns</strong> come in. Also, if you're preparing for an interview, there is a high chance you will be asked to explain some design patterns. For that, having a clear understanding of design patterns is like necessary.</p><p>In this article, I have explained each design pattern in an easy and simple way. I have also included code snippets and <strong>"when to use"</strong> sections for each pattern to help you understand better. So, let's jump into the world of design patterns!</p><h3><strong>1. Singleton Pattern</strong></h3><p>The <strong>Singleton Pattern</strong> ensures that a class has <strong>only one instance</strong> throughout the entire application and provides a <strong>global point of access</strong> to that instance. Think of a scenario where you have a single database connection or a configuration manager, you don't want to create multiple objects for these, as they can be heavy and may lead to inconsistencies. That’s where Singleton comes into play.</p><p>In Java, you implement a Singleton by making the constructor <code>private</code>, so no other class can create its object directly. You then create a static method (usually called <code>getInstance()</code>) which will return the same instance every time it's called.</p><pre><code class="language-java">public class DatabaseConnection {

    private static DatabaseConnection instance;

    // private constructor prevents instantiation
    private DatabaseConnection() {
        System.out.println("Connecting to database...");
    }

    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
}</code></pre><p>Now whenever you need a connection:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        DatabaseConnection db1 = DatabaseConnection.getInstance();
        DatabaseConnection db2 = DatabaseConnection.getInstance();

        System.out.println(db1 == db2); // true
    }
}</code></pre><p>Here, <code>db1</code> and <code>db2</code> are both pointing to the <strong>same object</strong>, showing how Singleton avoids multiple object creation. This pattern is useful in logging, configuration classes, and connection pools.</p><h3>When to use the <strong>Singleton Pattern</strong></h3><ul><li>When only <strong>one instance</strong> of a class should exist across the application.</li><li>When you need <strong>centralized configuration</strong>, logging, or caching.</li><li>For shared <strong>resources like database connections</strong> or file systems.</li></ul><h3><strong>2. Factory Pattern</strong></h3><p>The <strong>Factory Pattern</strong> helps in creating objects <strong>without exposing the object creation logic</strong> to the client. Instead of using <code>new</code> keyword in different places, you use a factory class to decide which class object should be created, based on input. This becomes extremely useful when you have <strong>multiple subclasses of a parent/interface</strong>, and you want to manage object creation centrally.</p><p>Imagine a graphic design app where users can draw different shapes like circles, squares, or triangles. Rather than creating each shape manually, a factory can handle it.</p><pre><code class="language-java">interface Shape {
    void draw();
}

class Circle implements Shape {
    public void draw() {
        System.out.println("Drawing Circle");
    }
}

class Square implements Shape {
    public void draw() {
        System.out.println("Drawing Square");
    }
}

class ShapeFactory {
    public static Shape getShape(String type) {
        if ("circle".equalsIgnoreCase(type)) {
            return new Circle();
        } else if ("square".equalsIgnoreCase(type)) {
            return new Square();
        }
        return null;
    }
}</code></pre><p>Client usage becomes easy and clean:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        Shape shape1 = ShapeFactory.getShape("circle");
        shape1.draw(); // Drawing Circle

        Shape shape2 = ShapeFactory.getShape("square");
        shape2.draw(); // Drawing Square
    }
}</code></pre><p>This pattern is great when the logic to create an object is complex or involves decision-making. It also keeps your code <strong>open for extension but closed for modification</strong>, which is one of the SOLID principles.</p><h3>When to use the <strong>Factory Pattern</strong></h3><ul><li>When object creation logic is <strong>complex</strong> or involves <strong>decision-making</strong>.</li><li>When you want to create objects <strong>without exposing the actual class</strong>.</li><li>When you need <strong>loose coupling</strong> between client code and actual implementations.</li></ul><h3><strong>3. Builder Pattern</strong></h3><p>The <strong>Builder Pattern</strong> is perfect when you need to construct <strong>complex objects step-by-step</strong>, especially if some fields are optional. It helps you avoid the problem of <strong>constructor overloading</strong>, where you end up writing multiple constructors with different parameter combinations.</p><p>Let’s say you’re building a <code>User</code> object where some properties like <code>name</code> and <code>email</code> are required, but others like <code>age</code>, <code>phone</code>, or <code>address</code> are optional. The builder pattern makes this process more readable and less error-prone.</p><pre><code class="language-java">public class User {
    private String name;
    private String email;
    private int age;

    private User(UserBuilder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.age = builder.age;
    }

    public static class UserBuilder {
        private String name;
        private String email;
        private int age;

        public UserBuilder setName(String name) {
            this.name = name;
            return this;
        }

        public UserBuilder setEmail(String email) {
            this.email = email;
            return this;
        }

        public UserBuilder setAge(int age) {
            this.age = age;
            return this;
        }

        public User build() {
            return new User(this);
        }
    }

    public String toString() {
        return name + " | " + email + " | " + age;
    }
}</code></pre><p>You can now build an object like this:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        User user = new User.UserBuilder()
                .setName("Munaf")
                .setEmail("munaf@example.com")
                .setAge(18)
                .build();

        System.out.println(user);
    }
}</code></pre><p>The Builder pattern makes your code <strong>cleaner, more readable, and flexible</strong>, especially for creating DTOs or response models in large applications.</p><h3>When to use the Builder <strong>Pattern</strong></h3><ul><li>When you need to <strong>build complex objects</strong> with many optional parameters.</li><li>When object creation requires a <strong>step-by-step process</strong>.</li><li>To avoid constructor overload with many parameters.</li></ul><h3><strong>4. Prototype Pattern</strong></h3><p>The <strong>Prototype Pattern</strong> is used when you want to <strong>create a copy of an existing object</strong> instead of building a new one from scratch. It’s very useful when object creation is <strong>expensive or time-consuming</strong>, like when loading from a database or performing deep configuration.</p><p>In Java, this pattern uses the <code>clone()</code> method (from <code>Cloneable</code> interface) to make a duplicate of an object.</p><pre><code class="language-java">class Vehicle implements Cloneable {
    private String type;

    public Vehicle(String type) {
        this.type = type;
    }

    public Vehicle clone() {
        try {
            return (Vehicle) super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    public void setType(String type) {
        this.type = type;
    }

    public String toString() {
        return "Vehicle: " + type;
    }
}</code></pre><p>Here’s how it works:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        Vehicle car = new Vehicle("Car");

        Vehicle carCopy = car.clone();
        carCopy.setType("Bike");

        System.out.println(car);      // Vehicle: Car
        System.out.println(carCopy);  // Vehicle: Bike
    }
}</code></pre><p>Notice how cloning saves time by copying an existing object. The Prototype pattern is used in real-world apps where object configuration is heavy, and you want to quickly make a copy and just tweak a few things.</p><p>Perfect! Let’s continue our blog with the remaining <strong>4 Java design patterns</strong> in the same beginner-friendly, paragraph style — keeping it simple, practical, and code-backed.</p><h3>When to use the Prototype <strong>Pattern</strong></h3><ul><li>When object creation is <strong>expensive</strong> or <strong>time-consuming</strong>.</li><li>When you need to create <strong>many copies of similar objects</strong>.</li><li>To <strong>clone existing objects</strong> instead of building new ones from scratch.</li></ul><h3><strong>5. Adapter Pattern</strong></h3><p>The <strong>Adapter Pattern</strong> is used when you want to <strong>make two incompatible interfaces work together</strong>. It acts like a bridge or a connector between two classes that otherwise cannot communicate. Imagine you bought a charger from the US, but you’re in India — an adapter allows it to fit the socket here. This design pattern does the same with classes.</p><p>In Java, this is commonly used when integrating third-party APIs or legacy code with your new system.</p><p>Let’s say you have an <code>AdvancedMediaPlayer</code> which supports only <code>.vlc</code> and <code>.mp4</code> files, but your application uses a generic <code>MediaPlayer</code> interface.</p><pre><code class="language-java">interface MediaPlayer {
    void play(String audioType, String fileName);
}

class VlcPlayer {
    public void playVlc(String fileName) {
        System.out.println("Playing VLC file: " + fileName);
    }
}

class VlcAdapter implements MediaPlayer {
    private VlcPlayer vlcPlayer;

    public VlcAdapter() {
        vlcPlayer = new VlcPlayer();
    }

    public void play(String audioType, String fileName) {
        if ("vlc".equalsIgnoreCase(audioType)) {
            vlcPlayer.playVlc(fileName);
        }
    }
}</code></pre><p>Now we plug this adapter into our application:</p><pre><code class="language-java">class AudioPlayer implements MediaPlayer {
    public void play(String audioType, String fileName) {
        if ("mp3".equalsIgnoreCase(audioType)) {
            System.out.println("Playing MP3 file: " + fileName);
        } else if ("vlc".equalsIgnoreCase(audioType)) {
            MediaPlayer adapter = new VlcAdapter();
            adapter.play(audioType, fileName);
        } else {
            System.out.println("Format not supported");
        }
    }
}</code></pre><p>Usage:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        AudioPlayer player = new AudioPlayer();
        player.play("mp3", "song.mp3");
        player.play("vlc", "video.vlc");
    }
}</code></pre><p>This pattern is perfect when you're dealing with legacy code or third-party tools that don’t directly match your interface needs.</p><h3>When to use the Adapter <strong>Pattern</strong></h3><ul><li>When two classes <strong>don’t match interfaces</strong> but need to work together.</li><li>When integrating with <strong>legacy code</strong> or <strong>third-party libraries</strong>.</li><li>To make existing classes <strong>compatible with new code</strong>.</li></ul><h3><strong>6. Observer Pattern</strong></h3><p>The <strong>Observer Pattern</strong> defines a one-to-many relationship between objects. When <strong>one object changes</strong>, all its dependent objects (observers) are <strong>automatically notified and updated</strong>. You’ve definitely seen this in real life — for example, subscribing to a YouTube channel. Once the channel posts a video, all subscribers get notified.</p><p>This is very common in event-driven systems, UI frameworks, and messaging systems.</p><p>Let’s see how this works in Java:</p><pre><code class="language-java">import java.util.*;

interface Observer {
    void update(String message);
}

class Subscriber implements Observer {
    private String name;

    public Subscriber(String name) {
        this.name = name;
    }

    public void update(String message) {
        System.out.println(name + " received: " + message);
    }
}</code></pre><p>Now we need a <code>Subject</code> that notifies subscribers:</p><pre><code class="language-java">class Channel {
    private List&lt;Observer&gt; subscribers = new ArrayList&lt;&gt;();

    public void subscribe(Observer observer) {
        subscribers.add(observer);
    }

    public void notifyAllSubscribers(String message) {
        for (Observer obs : subscribers) {
            obs.update(message);
        }
    }
}</code></pre><p>Usage:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        Channel codingShuttle = new Channel();

        Subscriber s1 = new Subscriber("Munaf");
        Subscriber s2 = new Subscriber("Ravi");

        codingShuttle.subscribe(s1);
        codingShuttle.subscribe(s2);

        codingShuttle.notifyAllSubscribers("New Spring Boot video is live!");
    }
}</code></pre><p>This pattern keeps your code <strong>loosely coupled</strong>, and is useful in applications where data change needs to be broadcasted — like stock prices, chat apps, and notification systems.</p><h3>When to use the Observer <strong>Pattern</strong></h3><ul><li>When <strong>multiple objects</strong> need to be notified when <strong>one object changes</strong>.</li><li>In <strong>event-driven systems</strong> like GUIs, chat apps, or notification systems.</li><li>When implementing <strong>publish-subscribe</strong> behavior.</li></ul><h3><strong>7. Strategy Pattern</strong></h3><p>The <strong>Strategy Pattern</strong> is all about <strong>choosing a behavior at runtime</strong>. Instead of writing complex <code>if-else</code> or <code>switch</code> statements, you define multiple strategies (algorithms), and select one dynamically.</p><p>Let’s say you’re building a payment system that supports different methods: Credit Card, UPI, or PayPal. Using strategy pattern, you can switch between these strategies easily without changing core logic.</p><pre><code class="language-java">interface PaymentStrategy {
    void pay(double amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("Paid ₹" + amount + " using Credit Card");
    }
}

class UPIPayment implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("Paid ₹" + amount + " using UPI");
    }
}</code></pre><p>Now we plug this into a <code>PaymentService</code> class:</p><pre><code class="language-java">class PaymentService {
    private PaymentStrategy strategy;

    public PaymentService(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void makePayment(double amount) {
        strategy.pay(amount);
    }
}</code></pre><p>Usage:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        PaymentService service1 = new PaymentService(new CreditCardPayment());
        service1.makePayment(2500);

        PaymentService service2 = new PaymentService(new UPIPayment());
        service2.makePayment(1200);
    }
}</code></pre><p>This pattern helps in <strong>separating different behaviors</strong>, making the code <strong>easier to extend and test</strong>. You can add a new payment method without touching any existing code.</p><h3>When to use the Strategy <strong>Pattern</strong></h3><ul><li>When you need to <strong>choose behavior/algorithm at runtime</strong>.</li><li>To eliminate long <strong>if-else</strong> or <strong>switch</strong> statements.</li><li>When you want to make a class <strong>open to extension but closed to modification</strong>.</li></ul><h3><strong>8. Decorator Pattern</strong></h3><p>The <strong>Decorator Pattern</strong> is used to <strong>dynamically add new functionality</strong> to an object without modifying its original code. It’s like adding toppings on a pizza — the base remains the same, but you can add cheese, mushrooms, or paneer to customize it.</p><p>Let’s build a simple coffee ordering system where you can add milk, sugar, etc., on top of base coffee.</p><pre><code class="language-java">interface Coffee {
    String getDescription();
    double getCost();
}

class SimpleCoffee implements Coffee {
    public String getDescription() {
        return "Simple Coffee";
    }

    public double getCost() {
        return 50;
    }
}</code></pre><p>Now let’s add decorators:</p><pre><code class="language-java">class MilkDecorator implements Coffee {
    private Coffee coffee;

    public MilkDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    public String getDescription() {
        return coffee.getDescription() + ", Milk";
    }

    public double getCost() {
        return coffee.getCost() + 10;
    }
}

class SugarDecorator implements Coffee {
    private Coffee coffee;

    public SugarDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    public String getDescription() {
        return coffee.getDescription() + ", Sugar";
    }

    public double getCost() {
        return coffee.getCost() + 5;
    }
}</code></pre><p>Usage:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        coffee = new MilkDecorator(coffee);
        coffee = new SugarDecorator(coffee);

        System.out.println("Order: " + coffee.getDescription());
        System.out.println("Cost: ₹" + coffee.getCost());
    }
}</code></pre><p>Output:</p><pre><code class="language-plaintext">Order: Simple Coffee, Milk, Sugar
Cost: ₹65.0</code></pre><p>The Decorator pattern is very powerful when you want to add features <strong>without altering the existing code</strong>, and is commonly used in logging, security, and user interface designs.</p><h3>When to use the Decorator <strong>Pattern</strong></h3><ul><li>When you want to <strong>add responsibilities/features dynamically</strong> to an object.</li><li>To <strong>extend functionality</strong> without modifying the original class.</li><li>For <strong>flexible and reusable wrappers</strong> (e.g., UI components, logging).</li></ul><h3><strong>9. Proxy Pattern</strong></h3><p>The <strong>Proxy Pattern</strong> provides a <strong>placeholder or substitute</strong> for another object to control access to it. Think of it like a receptionist at a company. You don’t directly talk to the boss — the receptionist acts as a <strong>middle layer</strong> to either pass the message or deny access.</p><p>This pattern is especially useful in cases like <strong>lazy initialization</strong>, <strong>access control</strong>, <strong>caching</strong>, or <strong>logging</strong>. You wrap the original object with another class (the proxy) and intercept calls to it.</p><p>Let’s take an example of an <code>Internet</code> interface where access to certain websites is restricted.</p><pre><code class="language-java">interface Internet {
    void connectTo(String serverHost) throws Exception;
}</code></pre><p>Now the actual internet class:</p><pre><code class="language-java">class RealInternet implements Internet {
    public void connectTo(String serverHost) {
        System.out.println("Connecting to " + serverHost);
    }
}</code></pre><p>Let’s create a proxy that adds restrictions:</p><pre><code class="language-java">import java.util.*;

class ProxyInternet implements Internet {
    private Internet internet = new RealInternet();
    private static List&lt;String&gt; bannedSites;

    static {
        bannedSites = new ArrayList&lt;&gt;();
        bannedSites.add("facebook.com");
        bannedSites.add("instagram.com");
    }

    public void connectTo(String serverHost) throws Exception {
        if (bannedSites.contains(serverHost.toLowerCase())) {
            throw new Exception("Access Denied to " + serverHost);
        }
        internet.connectTo(serverHost);
    }
}</code></pre><p>Usage:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        Internet net = new ProxyInternet();

        try {
            net.connectTo("google.com");        // Allowed
            net.connectTo("facebook.com");      // Blocked
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}</code></pre><p>This pattern is commonly used in frameworks like Spring AOP, where proxy classes wrap services to add logging, security, or transactional behavior.</p><h3>When to use the Proxy <strong>Pattern</strong></h3><ul><li>When you want to <strong>control access</strong> to another object.</li><li>For <strong>lazy loading</strong>, <strong>caching</strong>, <strong>logging</strong>, or <strong>security checks</strong>.</li><li>When adding a <strong>middle layer</strong> between client and real object.</li></ul><h3><strong>10. Command Pattern</strong></h3><p>The <strong>Command Pattern</strong> is used to <strong>encapsulate a request as an object</strong>, allowing us to parameterize clients with different requests, queue them, or log them. Think of it like placing an order at a restaurant — the waiter (command object) takes the order and passes it to the kitchen (receiver) without the customer needing to know how it’s cooked.</p><p>This is very useful in <strong>UI buttons, undo/redo operations, task scheduling</strong>, and even <strong>remote controls</strong>.</p><p>Let’s see an example of a remote control turning devices ON/OFF.</p><pre><code class="language-java">interface Command {
    void execute();
}

class Light {
    public void turnOn() {
        System.out.println("Light turned ON");
    }

    public void turnOff() {
        System.out.println("Light turned OFF");
    }
}</code></pre><p>Now we create command objects:</p><pre><code class="language-java">class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.turnOn();
    }
}

class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.turnOff();
    }
}</code></pre><p>And finally, a simple remote control to trigger these:</p><pre><code class="language-java">class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}</code></pre><p>Usage:</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        Light livingRoomLight = new Light();
        Command on = new LightOnCommand(livingRoomLight);
        Command off = new LightOffCommand(livingRoomLight);

        RemoteControl remote = new RemoteControl();

        remote.setCommand(on);
        remote.pressButton();  // Light turned ON

        remote.setCommand(off);
        remote.pressButton();  // Light turned OFF
    }
}</code></pre><p>This pattern is helpful when you need to <strong>separate the object that invokes a command from the one that knows how to perform it</strong>, making your code more flexible and modular.</p><h3>When to use the Command <strong>Pattern</strong></h3><ul><li>When you need to <strong>encapsulate actions/operations as objects</strong>.</li><li>For <strong>undo/redo</strong>, <strong>task queues</strong>, or <strong>remote execution</strong>.</li><li>When you want to <strong>decouple the sender and receiver</strong> of a request.</li></ul><h3>Conclusion</h3><p>Finally, we have covered 10 of the most popular design patterns that are widely used in real-world projects and often asked in interviews. I hope you now have a clear picture in your mind of how each design pattern works. I also suggest practicing each design pattern on your own to understand it better and apply it effectively in your code.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Java</category>
            <category>Java Design Patterns</category>
            <category>Singleton Pattern</category>
            <category>Factory Pattern</category>
            <category>Builder Pattern</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/10_Essential_Java_Design_Patterns_Every_Developer_Should_Master_9485559200.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot Exception Handling Made Easy: Pro Tips the Pros Don’t Share]]></title>
            <link>https://www.codingshuttle.com/blogs/how-to-handle-exceptions-in-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/how-to-handle-exceptions-in-spring-boot</guid>
            <pubDate>Thu, 12 Dec 2024 12:18:46 GMT</pubDate>
            <description><![CDATA[This article discusses common exceptions in Spring Boot, such as HttpRequestMethodNotSupportedException and DataIntegrityViolationException, and the use of @RestControllerAdvice for centralized handling. It provides best practices and examples to build secure, robust applications.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2><p>Exception handling is a crucial aspect of any application. It ensures that when an error occurs, the application responds gracefully instead of crashing or exposing sensitive information. In Spring Boot, exception handling can be customized to provide meaningful error messages, maintain application security, and improve the user experience.</p><p><strong>Why Exception Handling Matters:</strong></p><ul><li>Prevents application crashes.</li><li>Provides meaningful feedback to the client.</li><li>It avoids exposing sensitive information about the backend.</li><li>Helps log and debug issues efficiently.</li></ul><p>Spring Boot applications may encounter various types of exceptions. These exceptions can be categorized based on their source or type, such as HTTP-related, database-related, validation, or application-specific exceptions. Below is a comprehensive explanation of common exceptions you may encounter during Spring Boot development:</p><h3><strong>1. HTTP Exceptions</strong></h3><h3><strong>a. </strong><code><strong>HttpRequestMethodNotSupportedException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when the HTTP method (e.g., <code>POST</code>, <code>GET</code>) is not allowed for the requested endpoint.</li><li><strong>Example</strong>: Accessing a <code>POST</code> endpoint with a <code>GET</code> request.</li><li><strong>Default Status Code</strong>: <code>405 Method Not Allowed</code></li></ul><h3><strong>b. </strong><code><strong>HttpMediaTypeNotSupportedException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when the client sends data in a format not supported by the API (e.g., <code>application/xml</code> instead of <code>application/json</code>).</li><li><strong>Default Status Code</strong>: <code>415 Unsupported Media Type</code></li></ul><h3><strong>c. </strong><code><strong>HttpMessageNotReadableException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when Spring cannot parse the request body into the expected object (e.g., invalid JSON syntax).</li><li><strong>Default Status Code</strong>: <code>400 Bad Request</code></li></ul><h3><strong>d. </strong><code><strong>MissingServletRequestParameterException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when a required request parameter is missing.</li><li><strong>Default Status Code</strong>: <code>400 Bad Request</code></li></ul><h3><strong>2. Validation Exceptions</strong></h3><h3><strong>a. </strong><code><strong>MethodArgumentNotValidException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when validation on an object fails (e.g., <code>@NotBlank</code> or <code>@Valid</code>).</li><li><strong>Default Status Code</strong>: <code>400 Bad Request</code></li></ul><h3><strong>b. </strong><code><strong>ConstraintViolationException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when a constraint violation happens on a method argument annotated with <code>@Validated</code>.</li><li><strong>Default Status Code</strong>: <code>400 Bad Request</code></li></ul><h3><strong>3. Security Exceptions</strong></h3><h3><strong>a. </strong><code><strong>AccessDeniedException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when a user tries to access a resource they don't have permission for.</li><li><strong>Default Status Code</strong>: <code>403 Forbidden</code></li></ul><h3><strong>b. </strong><code><strong>AuthenticationException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when authentication fails, such as invalid credentials.</li><li><strong>Default Status Code</strong>: <code>401 Unauthorized</code></li></ul><h3><strong>4. Database Exceptions</strong></h3><h3><strong>a. </strong><code><strong>DataIntegrityViolationException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when a database constraint is violated (e.g., unique constraint, foreign key constraint).</li><li><strong>Default Status Code</strong>: <code>500 Internal Server Error</code></li></ul><h3><strong>b. </strong><code><strong>EntityNotFoundException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when an entity is not found in the database.</li><li><strong>Default Status Code</strong>: <code>404 Not Found</code></li></ul><h3><strong>5. Application-Specific Exceptions</strong></h3><h3><strong>a. </strong><code><strong>CustomException</strong></code></h3><ul><li><strong>Cause</strong>: A user-defined exception to encapsulate specific error scenarios.</li><li><strong>Default Status Code</strong>: Depends on your implementation.</li></ul><h3><strong>6. Deserialization Exceptions</strong></h3><h3><strong>a. </strong><code><strong>JsonMappingException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when Spring fails to map a JSON object to a Java object due to mismatched properties.</li><li><strong>Default Status Code</strong>: <code>400 Bad Request</code></li></ul><h3><strong>b. </strong><code><strong>JsonParseException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when Spring fails to parse the JSON due to malformed syntax.</li><li><strong>Default Status Code</strong>: <code>400 Bad Request</code></li></ul><h3><strong>7. General Exceptions</strong></h3><h3><strong>a. </strong><code><strong>IllegalArgumentException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when a method receives an illegal argument.</li><li><strong>Default Status Code</strong>: <code>400 Bad Request</code></li></ul><h3><strong>b. </strong><code><strong>NullPointerException</strong></code></h3><ul><li><strong>Cause</strong>: Occurs when your code tries to access a <code>null</code> object.</li><li><strong>Default Status Code</strong>: <code>500 Internal Server Error</code></li></ul><h3><strong>c. </strong><code><strong>Exception</strong></code></h3><ul><li><strong>Cause</strong>: Catches any unhandled exceptions in the application.</li><li><strong>Default Status Code</strong>: <code>500 Internal Server Error</code></li></ul><p>Understanding and handling exceptions effectively ensures your Spring Boot application is robust, user-friendly, and secure. These are the most common exceptions you'll encounter, along with strategies to manage them gracefully.</p><h2><strong>What Happens When an Exception Occurs?</strong></h2><p><strong>Without Handling</strong>:</p><p>Spring Boot uses a default error handler if you don't handle exceptions. For example, if a user accesses an invalid endpoint, the response might look like this:</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/error_080413f5bf.png" alt="Whitelable error page" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_error_080413f5bf.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_error_080413f5bf.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_error_080413f5bf.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_error_080413f5bf.png 1000w," sizes="100vw"><figcaption>Whitelable error page</figcaption></figure><p>While helpful, this needs more customization, making it easier to provide meaningful feedback or protect sensitive information.</p><p><strong>With Custom Handling</strong>:</p><p>You can intercept exceptions and provide your response. For example:</p><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/error1_4f47321cb4.png" alt="404 not found" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_error1_4f47321cb4.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_error1_4f47321cb4.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_error1_4f47321cb4.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_error1_4f47321cb4.png 1000w," sizes="100vw"><figcaption>404 not found</figcaption></figure><p>This is achieved using Spring Boot’s exception-handling mechanisms.</p><h2><strong>Default Exception Handling in Spring Boot</strong></h2><p>Spring Boot’s default error-handling mechanism is tied to <code>ErrorController</code>. By default, errors are mapped to <code>/error</code>, handled internally by Spring Boot.</p><h3><strong>Example: Hitting an Invalid Endpoint</strong></h3><p>If you hit an endpoint like <code>/api/nonexistent</code>, Spring Boot returns a standard response with <code>404 Not Found</code>. This behavior is good for development but often unsuitable for production.</p><p>To customize this behavior, we need to write our own exception-handling logic.</p><h2><strong>Understanding </strong><code><strong>@RestControllerAdvice</strong></code></h2><p><code>@RestControllerAdvice</code> is a Spring annotation that allows centralizing exception-handling logic across the entire application. It works alongside <code>@ExceptionHandler</code>.</p><h3><strong>Key Concepts</strong></h3><p><code><strong>@RestControllerAdvice</strong></code><strong>:</strong></p><p>A class annotated with <code>@RestControllerAdvice</code> intercepts exceptions globally for all controllers.</p><p><code><strong>@ExceptionHandler</strong></code><strong>:</strong></p><p>This annotation is used to specify the type of exceptions a method should handle.</p><p>Let’s implement a global exception handler for a simple <code>Employee</code> API.</p><h3><strong>Step 1: Create a Custom Exception</strong></h3><pre><code class="language-java">public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}</code></pre><h3><strong>Step 2: Implement a Global Exception Handler</strong></h3><pre><code class="language-java">import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


@RestControllerAdvice
public class GlobalExceptionHandler {
   @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity&lt;ApiError&gt; notFoundResource(ResourceNotFoundException ex){
        return new ResponseEntity&lt;&gt;(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
    }</code></pre><h3><strong>How It Works</strong></h3><ul><li>When a <code>ResourceNotFoundException</code> is thrown, the <code>handleResourceNotFound</code> method executes.</li><li>If any other exception occurs, the <code>handleGeneralException</code> method handles it.</li></ul><h1><strong>Structured Error Responses</strong></h1><p>Returning plain strings in responses can be uninformative. Instead, return structured JSON responses that provide more clarity.</p><h3><strong>1. Define an Error Response Object</strong></h3><pre><code class="language-java">import lombok.Data;
import org.springframework.http.HttpStatusCode;

import java.time.LocalDateTime;

@Data
public class ErrorResponse {
    private String message;
    private String details;
    private LocalDateTime timestamp;
    private HttpStatusCode statusCode;

    public ErrorResponse(String message, String details,HttpStatusCode statusCode) {
        this.message = message;
        this.details = details;
        this.timestamp = LocalDateTime.now();
        this.statusCode = statusCode;
    }
}</code></pre><h3><strong>2. Modify the Exception Handler</strong></h3><pre><code class="language-java">@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity&lt;ErrorResponse&gt; handleResourceNotFound(ResourceNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(ex.getMessage(), "Resource not found",HttpStatusCode.valueOf(404));
        return new ResponseEntity&lt;&gt;(error, HttpStatus.NOT_FOUND);
    }
  }
</code></pre><h3><strong>3. Response Example:</strong></h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/error2_b9bb3f5630.png" alt="Resource not found (404 not found error)" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_error2_b9bb3f5630.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_error2_b9bb3f5630.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_error2_b9bb3f5630.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_error2_b9bb3f5630.png 1000w," sizes="100vw"><figcaption>Resource not found (404 not found error)</figcaption></figure><p>Exception handling in Spring Boot is robust and flexible. With <span style="background-color:rgba(135,131,120,.15);color:#EB5757;font-family:&quot;SFMono-Regular&quot;, Menlo, Consolas, &quot;PT Mono&quot;, &quot;Liberation Mono&quot;, Courier, monospace;">@RestControllerAdvice</span>, custom exceptions, and validation error handlers, you can create a user-friendly and secure API. Combine this with logging and structured responses for a professional-grade application.</p><h2>Conclusion</h2><p>This article highlighted the significance of exception handling in Spring Boot, focusing on improving application stability, security, and user experience. By using @RestControllerAdvice and custom exceptions, developers can deliver meaningful error messages and structured responses. Effective exception handling is essential for building robust, user-friendly APIs.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Spring Boot</category>
            <category>Exception Handling</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/exception_handling_d34204914a.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot Beginner’s Guide: Build Java Applications Fast with Auto-Configuration]]></title>
            <link>https://www.codingshuttle.com/blogs/what-is-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/what-is-spring-boot</guid>
            <pubDate>Wed, 11 Dec 2024 13:49:27 GMT</pubDate>
            <description><![CDATA[Learn what Spring Boot is, how it works, and why developers love it. This beginner-friendly guide covers Spring Boot’s key features, benefits, auto-configuration magic, and a step-by-step setup to build your first Java backend application.]]></description>
            <content:encoded><![CDATA[<p>Spring Boot is a powerful framework for building Java-based applications. It is highly used for the rapid development of Java-based applications. With the help of Spring Boot, developers can focus more on building the application's business logic than wasting a lot of time in setting up and configuring the application.</p><p>In this guide, I will explain <strong>what Spring Boot is</strong>, why developers love it, and how you can get started with it, even if you are completely new. So let’s jump in.</p><h2><strong>What Is Spring Boot?</strong></h2><p><strong>Spring Boot</strong> is a popular Java framework that makes it super easy to create backend applications. It’s built on top of the Spring Framework but removes a lot of the pain of manual setup.</p><p>With Spring Boot, you don’t need to spend hours configuring XML files or setting up complicated dependencies. Instead, it comes with <strong>pre-configured templates</strong> (called starters) and sensible defaults, so you can focus on writing actual business logic.</p><p>When I first started with Spring Boot, I was genuinely impressed by its <strong>auto-configuration</strong> feature. It felt like magic just by adding the right dependencies, Spring Boot would automatically configure the necessary components for me. I didn’t have to waste time writing long XML configurations or doing repetitive setup work. I could just focus on building my application.</p><h2><strong>Why Use Spring Boot?</strong></h2><h3>1. Faster Development</h3><p>Setting up a project with Spring Boot is ridiculously quick, especially using <strong>Spring Initializr</strong>. You just choose your dependencies, download the project, and you’re ready to code. No endless setup steps, no complicated environment preparation, it’s like skipping straight to the fun part.</p><h3>2. No XML Hell</h3><p>Gone are the days of writing huge XML configuration files just to get your app running. Spring Boot replaces most of that with simple annotations and smart defaults. It feels refreshing to focus on <i>what</i> your app should do, rather than <i>how</i> to wire everything together.</p><h3>3. <strong>Production-Ready</strong></h3><p>Even without touching a single extra library, Spring Boot gives you tools like <strong>Actuator</strong> for monitoring, gathering metrics, checking health endpoints, and more. It’s like having a built-in dashboard for your application’s well-being something that’s usually a pain to set up manually.</p><h3>4. <strong>Embedded Servers</strong></h3><p>You don’t have to separately install or configure Tomcat, Jetty, or Undertow. Spring Boot embeds them right into your application, meaning you can run your backend with a simple <code>java -jar</code> command. It’s one of those things you don’t appreciate until you realize how much setup time it saves.</p><h3>5. <strong>Huge Community</strong></h3><p>With millions of developers using Spring Boot, you’re never really coding alone. If you get stuck, there’s a high chance someone has already faced and solved the exact same problem, whether it’s on Stack Overflow, GitHub, or official docs. This makes learning and troubleshooting a whole lot easier.</p><h2><strong>How Spring Boot Works</strong></h2><p>One of the coolest things about Spring Boot is its <strong>auto-configuration</strong> magic. It’s like having a super-smart assistant that looks at the dependencies in your project and then quietly sets up all the necessary configurations for you — without you having to lift a finger.</p><p>For example, let’s say you add <code>spring-boot-starter-web</code> to your project. Spring Boot immediately understands, “Ah, this person is building a web application.” And just like that, it configures an embedded web server (like Tomcat), sets up request mapping, JSON handling, and a bunch of other web-related stuff in the background.</p><p>The best part? You don’t have to manually write endless boilerplate or mess around with XML files. Spring Boot does the heavy lifting so you can just start coding your controllers, services, and actual business logic.</p><p>When I first experienced this, it honestly felt like magic I remember running my app for the first time and thinking, <i>“Wait… that’s it? No setup headaches?”</i></p><h2><strong>Getting Started with Spring Boot</strong></h2><p>Starting a Spring Boot project is actually very simple. You just need to:</p><ol><li>Open your browser and visit <a href="https://start.spring.io">https://start.spring.io</a>.</li><li>Select <code>Maven</code> or <code>Gradle</code> depending on your preference. I usually go with <strong>Maven</strong>.</li><li>Select <code>Java</code> (most common), but Kotlin and Groovy are also available.</li><li>I recommend going with the <strong>latest stable version</strong> unless your project needs a specific version.</li><li>Add Project Metadata</li><li>Click <strong>“Add Dependencies”</strong> and search for what you need.</li><li>Click "Generate”, This will download a ZIP file containing your Spring Boot project.</li><li>Unzip the project and import in your IDE</li></ol><p>That’s it, there is no complex setup, no manual server installation.</p><h2><strong>Example: A Simple Spring Boot Application</strong></h2><p>Here’s a small example that prints “Hello World” in the browser:</p><pre><code class="language-java">import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @GetMapping("/")
    public String hello() {
        return "Hello World from Spring Boot!";
    }
}</code></pre><p>Run this, open your browser at <code>http://localhost:8080</code>, and you’ll see your message.</p><h2>Conclusion</h2><p>Spring Boot is one of those tools that makes backend development less frustrating and more fun. You can go from zero to a running application in just a few minutes. If you are a beginner, I recommend building a small project maybe a simple REST API and experimenting with different dependencies. This hands-on approach will help you understand Spring Boot much better.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Spring</category>
            <category>Spring Boot</category>
            <category>Spring Boot Tutorial</category>
            <category>Spring Boot Guide</category>
            <category>Backend Development</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/The_spring_boot_guide_881ca8b43f.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How Spring Boot Powers Applications Like Uber and LinkedIn | Real-World Examples]]></title>
            <link>https://www.codingshuttle.com/blogs/how-spring-boot-powers-applications-like-uber-and-linked-in</link>
            <guid>https://www.codingshuttle.com/blogs/how-spring-boot-powers-applications-like-uber-and-linked-in</guid>
            <pubDate>Sat, 07 Dec 2024 14:15:18 GMT</pubDate>
            <description><![CDATA[Discover how Spring Boot can power apps like Uber and LinkedIn. Learn real-world use cases for ride-hailing platforms, networking apps, and scalable backend systems.]]></description>
            <content:encoded><![CDATA[<p>Spring Boot is one of those frameworks that can handle almost anything you throw at it from small side projects to powering massive, secure, and super-efficient backend systems. Big names like Uber and LinkedIn use it to keep their apps running smoothly at scale.</p><p>In this article, I will share how Spring Boot could fit into something like a Uber project or even a LinkedIn style platform.</p><h2>Uber Like Application</h2><h3><strong>1. Ride Requests &amp; Matching</strong></h3><p>In any ride-hailing app, the first thing a user does is request a ride. With <strong>Spring Boot</strong>, creating a REST API to handle these requests is super quick.</p><p>When a rider sends a request, the API instantly checks for available drivers nearby and matches them using your custom matching logic (like shortest distance or driver rating).</p><p>The best part is that Spring Boot handles all the boring setup, so you just focus on the business logic for example, “find the 5 closest drivers within 3 km and assign one instantly.” This makes the whole process fast and reliable.</p><h3><strong>2. Real-Time Tracking</strong></h3><p>Nobody likes waiting without knowing where their ride is. That’s why <strong>real-time tracking</strong> is so important.</p><p>With <strong>Spring Boot</strong> and <strong>WebSockets</strong> (or STOMP over Spring Messaging), you can push live location updates directly to the rider’s app.</p><p>So instead of the app constantly asking “where’s my driver?”, the driver’s location is pushed instantly from the server to the user in real time. This keeps the app snappy and reduces server load.</p><h3><strong>3. Payment Processing</strong></h3><p>Handling money is serious business, and you can’t cut corners here.</p><p>With <strong>Spring Security</strong>, you can ensure all payment-related APIs are fully protected. Then, by integrating with payment gateways (like Stripe, Razorpay, or PayPal), you can securely process transactions without storing sensitive card details yourself.</p><p>Spring Boot makes this easier by giving you clean integration options and security features out of the box so your payment flow remains safe and smooth for both riders and drivers.</p><h3><strong>4. Driver Management</strong></h3><p>Behind every ride-hailing app is a fleet of drivers, and managing them efficiently is crucial.</p><p>With <strong>Spring Boot</strong> and <strong>Spring Data JPA</strong>, you can quickly build CRUD APIs to <strong>register new drivers</strong>, <strong>update their details</strong>, and <strong>track their status</strong> (available, busy, offline).</p><p>Since JPA handles most of the SQL work for you, your code stays clean, and database operations remain simple even when dealing with thousands of drivers.</p><h3><strong>5. Analytics &amp; Insights</strong></h3><p>Numbers don’t lie they tell you how your business is really doing.</p><p>With <strong>Spring Boot Actuator</strong> and <strong>Micrometer</strong>, you can collect data like total rides completed, revenue generated, and driver performance metrics.</p><p>This data can then be sent to monitoring tools like Prometheus or Grafana, giving you beautiful dashboards and insights to improve decision-making.</p><h2><strong>LinkedIn-Style Networking Platform</strong></h2><h3><strong>1. User Profiles</strong></h3><p>Every networking platform starts with profiles. With <strong>Spring Data JPA</strong>, you can easily store all the important user details like name, headline, skills, education, work experience, and even profile pictures in the database.</p><p>When someone opens a profile, JPA helps fetch the data instantly without you writing long SQL queries. Updating a profile is just as smooth whether it’s adding a new skill, changing a profile picture, or updating the “About” section, JPA makes the interaction with the database quick and reliable. This keeps the user experience fast and seamless.</p><h3><strong>2. Connections &amp; Messaging</strong></h3><p>The whole point of a networking platform is to connect people. With <strong>Spring Boot REST APIs</strong>, you can build endpoints to send connection requests, accept them, or decline them. Once two users are connected, you can use <strong>WebSockets</strong> to enable real-time messaging.</p><p>That means when someone sends a message, it appears instantly in the other person’s chat window without refreshing the page.</p><p>This setup works perfectly for quick back-and-forth conversations, making the platform feel alive and engaging, just like modern chat apps.</p><h3><strong>3. Job Postings</strong></h3><p>Helping people find jobs is often a core feature in a professional networking app. By using a <strong>microservices</strong> architecture, you can build a dedicated job posting service that handles everything from creating a job listing to managing applications.</p><p>Companies can log in, post their openings, edit them if needed, and review applicants. On the user side, they can search for jobs, apply directly, and track their application status.</p><p>All through secure APIs that ensure sensitive data stays protected. Separating this into a microservice also makes it easier to scale when job activity spikes.</p><h3><strong>4. Feed &amp; Recommendations</strong></h3><p>The feed is the heartbeat of a networking platform. Using <strong>Spring Batch</strong>, you can process large volumes of data in the background to personalize each user’s feed.</p><p>This might include posts from their connections, trending articles in their industry, or updates from companies they follow. At the same time, recommendation algorithms can suggest new people to connect with based on shared interests, mutual connections, or job history.</p><p>Since Spring Batch handles bulk processing efficiently, you can keep the feed relevant and updated without slowing down the rest of the app.</p><h3><strong>5. Search &amp; Filters</strong></h3><p>Search is one of the most used features in a platform like this, and speed is everything. By combining <strong>Spring Boot</strong> with <strong>Elasticsearch</strong>, you can build a lightning-fast search engine that returns results in milliseconds.</p><p>Users can type in keywords to find profiles, jobs, or posts, and use filters for things like location, skills, industry, or experience level.</p><p>Even if your database has millions of records, Elasticsearch makes it feel instant. This makes discovering opportunities and people smooth and frustration-free.</p><h2><strong>Conclusion</strong></h2><p>Spring Boot isn’t just a “Java framework”, it is a complete toolkit that can scale from a side project to the backbone of global platforms like Uber and LinkedIn. Its <strong>auto-configuration</strong>, <strong>microservices support</strong>, and <strong>production-ready tools</strong> mean you can focus on business logic while Spring Boot handles the heavy lifting.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Spring Boot</category>
            <category>Java Backend</category>
            <category>Uber App Development</category>
            <category>LinkedIn Clone</category>
            <category>Microservices with Spring Boot</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/How_spring_boot_power_app_like_uber_and_linkedin_bb9c0b9881.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How I Transformed My Coding Career With 100 Days of Spring Boot]]></title>
            <link>https://www.codingshuttle.com/blogs/how-to-master-spring-boot-in-100-days-study-plan</link>
            <guid>https://www.codingshuttle.com/blogs/how-to-master-spring-boot-in-100-days-study-plan</guid>
            <pubDate>Sat, 07 Dec 2024 09:38:10 GMT</pubDate>
            <description><![CDATA[Master Spring Boot in just 100 days with this structured study plan! Designed for beginners and intermediate learners]]></description>
            <content:encoded><![CDATA[<p>Spring Boot has become the go-to framework for Java developers looking to build powerful, scalable, and modern applications. Mastering it in just 100 days is entirely possible with a structured approach. This study plan is designed for beginners and intermediate learners alike, helping you gradually build your knowledge and skills.</p><h2>Why Master Spring Boot?</h2><p>Spring Boot simplifies application development with features like auto-configuration, embedded servers, and production-ready tools. Mastering it can open doors to building microservices, RESTful APIs, and enterprise-grade applications.</p><h2>Study Plan Overview</h2><ul><li><strong>Duration:</strong> 100 days</li><li><strong>Daily Commitment:</strong> 1–2 hours</li><li><strong>Prerequisites:</strong> Basic Java knowledge, understanding of core Spring concepts like Dependency Injection and IoC.</li></ul><hr><h3><strong><u>Phase 1: Foundation (Days 1–20)</u></strong></h3><h3>Goals:</h3><ul><li>Understand the basics of Spring Framework and Spring Boot.</li><li>Set up your development environment.</li></ul><h3>Topics to Cover:</h3><ol><li><strong>Spring Framework Basics:</strong><ul><li>Dependency Injection (DI) and Inversion of Control (IoC).</li><li>Beans and ApplicationContext.</li></ul></li><li><strong>Introduction to Spring Boot:</strong><ul><li>What is Spring Boot?</li><li>Benefits over traditional Spring.</li><li>Setting up a Spring Boot project using Spring Initializr.</li></ul></li><li><strong>Development Environment:</strong><ul><li>Install IDE (IntelliJ IDEA, Eclipse).</li><li>Install JDK, Maven, and Git.</li></ul></li></ol><h3>Activities:</h3><ul><li>Build a "Hello, World!" application in Spring Boot.</li><li>Explore the structure of a Spring Boot project.</li></ul><h3><strong><u>Phase 2: Core Features (Days 21–40)</u></strong></h3><h3>Goals:</h3><ul><li>Learn core Spring Boot features like auto-configuration and application properties.</li><li>Understand the use of REST APIs and databases.</li></ul><h3>Topics to Cover:</h3><ol><li><strong>Spring Boot Annotations:</strong><ul><li><code>@SpringBootApplication</code>, <code>@RestController</code>, <code>@Service</code>, <code>@Repository</code>.</li><li><code>@ComponentScan</code> and <code>@Configuration</code>.</li></ul></li><li><strong>Configuration and Profiles:</strong><ul><li><code>application.properties</code> vs <code>application.yml</code>.</li><li>Using Spring profiles for environment-specific configurations.</li></ul></li><li><strong>Working with REST APIs:</strong><ul><li>Creating REST controllers.</li><li>Handling GET, POST, PUT, DELETE requests.</li></ul></li><li><strong>Database Integration:</strong><ul><li>Introduction to JPA and Hibernate.</li><li>Configuring H2 database.</li></ul></li></ol><h3>Activities:</h3><ul><li>Build a simple CRUD API using Spring Boot and H2.</li><li>Add environment-specific configurations using profiles.</li></ul><h3><strong><u>Phase 3: Advanced Features (Days 41–70)</u></strong></h3><h3>Goals:</h3><ul><li>Explore advanced features like security, testing, and monitoring.</li><li>Learn about building scalable applications.</li></ul><h3>Topics to Cover:</h3><ol><li><strong>Spring Boot Security:</strong><ul><li>Basics of Spring Security.</li><li>Implementing authentication and authorization.</li></ul></li><li><strong>Testing:</strong><ul><li>Writing unit tests with JUnit and Mockito.</li><li>Integration testing with <code>@SpringBootTest</code>.</li></ul></li><li><strong>Spring Boot Actuator:</strong><ul><li>Monitoring application health.</li><li>Understanding common Actuator endpoints.</li></ul></li><li><strong>Building Production-Ready Apps:</strong><ul><li>Externalized configurations using <code>application.properties</code>.</li><li>Logging with SLF4J and Logback.</li></ul></li></ol><h3>Activities:</h3><ul><li>Secure your CRUD API with Spring Security.</li><li>Write test cases for REST endpoints.</li></ul><h3><strong><u>Phase 4: Microservices (Days 71–90)</u></strong></h3><h3>Goals:</h3><ul><li>Learn to build and manage microservices using Spring Boot.</li></ul><h3>Topics to Cover:</h3><ol><li><strong>Introduction to Microservices:</strong><ul><li>What are microservices?</li><li>Advantages of microservices architecture.</li></ul></li><li><strong>Spring Cloud Basics:</strong><ul><li>Service discovery with Eureka.</li><li>API Gateway with Zuul or Spring Cloud Gateway.</li><li>Centralized configuration with Spring Cloud Config.</li></ul></li><li><strong>Inter-Service Communication:</strong><ul><li>Using Feign clients.</li><li>REST and gRPC communication.</li></ul></li></ol><h3>Activities:</h3><ul><li>Build a microservices-based application with two services.</li><li>Set up Eureka for service discovery.</li></ul><h3><strong><u>Phase 5: Project and Review (Days 91–100)</u></strong></h3><h3>Goals:</h3><ul><li>Apply everything you’ve learned in a capstone project.</li><li>Review and revise critical concepts.</li></ul><h3>Topics to Cover:</h3><ul><li>Capstone Project:<ul><li>Build a complete application (e.g., a food delivery app or task management system).</li><li>Include REST APIs, security, database integration, and monitoring.</li></ul></li><li>Revision Topics:<ul><li>Spring Boot annotations.</li><li>Microservices concepts.</li><li>Testing strategies.</li></ul></li></ul><h3>Activities:</h3><ul><li>Deploy your capstone project on AWS Elastic Beanstalk or Heroku.</li><li>Write a blog or create a portfolio to showcase your project.</li></ul><h2><strong>Tips for Success</strong></h2><ol><li><strong>Practice Regularly:</strong> Build small applications alongside theory.</li><li><strong>Explore Documentation:</strong> Spring Boot’s <a href="https://spring.io/projects/spring-boot">official documentation</a> is an excellent resource.</li><li><strong>Join Communities:</strong> Engage in forums like Stack Overflow or Reddit’s r/javahelp.</li><li><strong>Stay Consistent:</strong> Dedicate a specific time daily to study and code.</li></ol><h2><strong>Conclusion</strong></h2><p>By following this 100-day plan, you’ll master Spring Boot step-by-step, gaining the confidence to build real-world applications and excel in your career. Remember, consistency and hands-on practice are key. Happy coding!</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot Study plan</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/100_days_spring_boot_e188711c66.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Are You Making These Spring Boot Mistakes? 5 Mistakes That Beginners Make]]></title>
            <link>https://www.codingshuttle.com/blogs/top-5-challenges-student-face-in-learning-spring-boot</link>
            <guid>https://www.codingshuttle.com/blogs/top-5-challenges-student-face-in-learning-spring-boot</guid>
            <pubDate>Sat, 07 Dec 2024 09:28:24 GMT</pubDate>
            <description><![CDATA[Spring Boot simplifies Java application development but poses unique challenges for students, especially beginners. This article highlights the top 5 challenges learners face]]></description>
            <content:encoded><![CDATA[<p>Spring Boot is a powerful framework that simplifies the development of Java applications. However, learning Spring Boot can be challenging for students, especially those new to frameworks or enterprise-level programming. Here are the top five challenges students face when learning Spring Boot, along with tips to overcome them.</p><h2>1. Understanding Spring Core Concepts</h2><h3>The Challenge:</h3><p>Spring Boot is built on top of the Spring Framework. Many students dive straight into Spring Boot without a solid understanding of core Spring concepts like <strong>Dependency Injection (DI)</strong>, <strong>Inversion of Control (IoC)</strong>, and <strong>Bean Management</strong>. This makes it difficult to grasp how Spring Boot automates configurations.</p><h3>How to Overcome:</h3><ul><li><strong>Learn the Basics First:</strong> Start with core Spring concepts before moving to Spring Boot. Build small projects using Spring to understand manual configurations.</li><li><strong>Hands-On Practice:</strong> Create simple applications using IoC containers and manual dependency wiring to solidify your understanding.</li></ul><h2>2. Dealing with Auto-Configuration</h2><h3>The Challenge:</h3><p>Spring Boot’s <strong>auto-configuration</strong> simplifies setup, but students often find it hard to understand how and why certain configurations are applied automatically. This "magic" can feel overwhelming.</p><h3>How to Overcome:</h3><ul><li><strong>Trace the Code:</strong> Use tools like IntelliJ IDEA to explore the source code of Spring Boot starters.</li><li><strong>Disable Auto-Configuration:</strong> Experiment with disabling auto-configuration (<code>@EnableAutoConfiguration(exclude = ...)</code>) to learn how manual configurations work.</li><li><strong>Study Documentation:</strong> The Spring Boot documentation provides detailed explanations of auto-configuration.</li></ul><h2>3. Configuring Databases</h2><h3>The Challenge:</h3><p>Connecting Spring Boot to databases like MySQL, PostgreSQL, or MongoDB can be tricky. Students struggle with configuring properties, understanding JPA, and managing connection pools.</p><h3>How to Overcome:</h3><ul><li><strong>Start with In-Memory Databases:</strong> Begin with simpler databases like H2 or HSQLDB to learn configurations.</li><li><strong>Learn JPA Basics:</strong> Understand how JPA works, including entities, repositories, and queries.</li><li><strong>Use Examples:</strong> Follow official Spring Boot guides for database integration.</li></ul><h2>4. Mastering Security Features</h2><h3>The Challenge:</h3><p>Spring Security, while powerful, is one of the most challenging aspects of Spring Boot. Setting up authentication, authorization, and understanding concepts like filters, CSRF, and roles can be overwhelming.</p><h3>How to Overcome:</h3><ul><li><strong>Learn Step-by-Step:</strong> Start with basic authentication and gradually explore advanced features like JWT and OAuth2.</li><li><strong>Use Debugging Tools:</strong> Analyze request/response headers and session data to understand how security mechanisms work.</li><li><strong>Practice Real Scenarios:</strong> Build mini-projects like login systems or APIs with role-based access control.</li></ul><h2>5. Understanding Microservices Architecture</h2><h3>The Challenge:</h3><p>Spring Boot is often used to build <strong>microservices</strong>, but understanding the architecture, communication between services, and tools like Spring Cloud can be daunting.</p><h3>How to Overcome:</h3><ul><li><strong>Learn the Basics of Microservices:</strong> Understand the principles of microservices architecture, such as decentralized data management and inter-service communication.</li><li><strong>Start Small:</strong> Build a small application with just two services to understand how they interact.</li><li><strong>Explore Tools:</strong> Use Spring Cloud features like Eureka for service discovery and Spring cloud routing for API Gateway step-by-step.</li></ul><h3><strong>Conclusion</strong></h3><p>Learning Spring Boot can seem overwhelming at first, but these challenges are surmountable with a structured approach and consistent practice. Start small, understand the basics, and don’t hesitate to explore Spring Boot's official documentation and community forums for help.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot challenges</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/challanges_d342555264.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Spring Boot Interview Questions for 2025 – Real Examples & Explanations]]></title>
            <link>https://www.codingshuttle.com/blogs/20-most-asked-spring-boot-interview-questions</link>
            <guid>https://www.codingshuttle.com/blogs/20-most-asked-spring-boot-interview-questions</guid>
            <pubDate>Sat, 07 Dec 2024 09:04:37 GMT</pubDate>
            <description><![CDATA[Get ready for your next Java interview with this ultimate guide to Spring Boot interview questions in 2025. Learn key concepts like auto-configuration, REST API creation, dependency injection, Actuator, security, and more.]]></description>
            <content:encoded><![CDATA[<p>If you are preparing for Java interview, chances are you will face questions about <strong>Spring Boot. I</strong>t is a favorite for building modern, scalable and industry ready applications. Whether you are new to Spring Boot or brushing up for a interview, this article will definitely help you.</p><p>In this article, I have explained top spring boot interview questions in a simple and friendly way, making them easy to understand.</p><h2>1. What is Spring Boot, and why is it used?</h2><p><strong>Spring Boot</strong> is an extension of the Spring framework designed to simplify building production-ready Java applications. It offers auto-configuration, embedded servers, and “starter” dependencies to reduce setup time and boilerplate code.</p><p><strong>Why it’s used:</strong></p><ul><li><strong>Rapid development</strong>: Auto-configuration and starters streamline setup, letting you focus on business logic.</li><li><strong>Production-ready</strong>: Built-in monitoring (via Actuator), logging, and metrics make it enterprise-friendly.</li><li><strong>Microservices</strong>: Ideal for building scalable, independent services.</li><li><strong>Embedded servers</strong>: No need for external servers like Tomcat; everything runs out of the box.</li></ul><p>It’s popular for web apps, APIs, and microservices due to its simplicity and robust ecosystem.</p><h2>2. What are the key features of Spring Boot?</h2><p>Spring Boot’s key features make it a developer favorite:</p><ul><li><strong>Auto-Configuration</strong>: Automatically sets up beans based on dependencies (e.g., database or web server configs).</li><li><strong>Starters</strong>: Pre-packaged dependencies for specific use cases (e.g., spring-boot-starter-web for REST APIs).</li><li><strong>Embedded Servers</strong>: Includes Tomcat, Jetty, or Undertow for instant deployment.</li><li><strong>Spring Boot Actuator</strong>: Provides endpoints like /health and /metrics for monitoring.</li><li><strong>Spring Boot CLI</strong>: Run apps or scripts from the command line.</li><li><strong>Production-ready tools</strong>: Built-in support for logging, profiles, and externalized configuration.</li><li><strong>Spring Initializr</strong>: A web tool to bootstrap projects with the right dependencies.</li></ul><p>These features cut down development time and ensure scalability.</p><h2>3. What is the @SpringBootApplication annotation?</h2><p>@SpringBootApplication is a convenience annotation that combines three key annotations:</p><ul><li>@EnableAutoConfiguration: Enables Spring Boot’s auto-configuration magic.</li><li>@ComponentScan: Scans for Spring components (e.g., @Controller, @Service) in the package and sub-packages.</li><li>@Configuration: Marks the class as a source of bean definitions for the Spring context.</li></ul><p>This single annotation sets up your entire Spring Boot application, making it the entry point for most projects.</p><p><strong>Example:</strong></p><pre><code class="language-java">@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}</code></pre><h2>4. What are Spring Boot Starters?</h2><p><strong>Starters</strong> are dependency descriptors that bundle related libraries for specific functionality, like web development, data access, or security. They simplify dependency management by ensuring compatible versions of libraries.</p><p><strong>Examples:</strong></p><ul><li>spring-boot-starter-web: For building REST APIs or MVC apps.</li><li>spring-boot-starter-data-jpa: For database access with Hibernate.</li><li>spring-boot-starter-security: For authentication and authorization.</li></ul><p>Instead of manually adding individual libraries, you include a starter, and Spring Boot handles the rest.</p><p><strong>Example:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><h2>5. What is Spring Boot Auto-Configuration?</h2><p><strong>Auto-Configuration</strong> is Spring Boot’s ability to automatically configure beans based on the dependencies in your classpath. For example, if you include spring-boot-starter-data-jpa, Spring Boot sets up a DataSource, JPA, and Hibernate without manual configuration.</p><p><strong>How it works:</strong></p><ul><li>Scans your classpath for libraries (e.g., H2, MySQL, or Tomcat).</li><li>Applies sensible defaults (e.g., database connection settings).</li><li>Allows customization via application.properties or application.yml.</li></ul><p>This reduces boilerplate and speeds up development, but you can override defaults if needed.</p><p><strong>Example:</strong></p><pre><code class="language-plaintext"># application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password</code></pre><h2>6. How does Spring Boot differ from Spring Framework?</h2><ul><li><strong>Spring Framework</strong>: A powerful but complex framework requiring manual configuration (e.g., XML or Java config) for beans, servers, and dependencies. It’s flexible but time-consuming.</li><li><strong>Spring Boot</strong>: Built on Spring, it simplifies setup with auto-configuration, starters, and embedded servers. It’s designed for rapid development and production-ready apps.</li></ul><p><strong>Key differences:</strong></p><ul><li>Spring Boot reduces boilerplate and setup time.</li><li>Spring Boot includes embedded servers; Spring requires external servers.</li><li>Spring Boot is opinionated with defaults; Spring offers more control.</li></ul><h2>7. What is the Spring Boot Actuator?</h2><p><strong>Spring Boot Actuator</strong> provides production-ready endpoints for monitoring and managing your application. These endpoints expose information like health status, metrics, environment details, and more.</p><p><strong>Common endpoints:</strong></p><ul><li>/actuator/health: Checks if the app and its dependencies (e.g., database) are up.</li><li>/actuator/metrics: Provides performance metrics (e.g., memory usage).</li><li>/actuator/info: Displays custom app info.</li></ul><p>**How to enable:**Add spring-boot-starter-actuator to your project and configure which endpoints to expose in application.properties.</p><p><strong>Example:</strong></p><pre><code class="language-plaintext"># application.properties
management.endpoints.web.exposure.include=health,info,metrics</code></pre><h2>8. What is the purpose of application.properties or application.yml?</h2><p>These files store configuration settings for your Spring Boot application, such as database connections, server ports, logging levels, or custom properties. application.yml is preferred for complex, hierarchical configs due to its readability.</p><p><strong>Example use cases:</strong></p><ul><li>Set server port: server.port=8081</li><li>Configure database: spring.datasource.url=jdbc:mysql://localhost:3306/mydb</li><li>Enable Actuator endpoints: management.endpoints.web.exposure.include=*</li></ul><p>They externalize configuration, making it easy to tweak settings without changing code.</p><p><strong>Example (application.yml):</strong></p><pre><code class="language-plaintext">server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password</code></pre><h2>9. How do you create a REST API in Spring Boot?</h2><p>To create a REST API, use @RestController with annotations like @GetMapping, @PostMapping, etc., to define endpoints. Spring Boot’s spring-boot-starter-web provides all necessary dependencies.</p><p><strong>Steps:</strong></p><ol><li>Add spring-boot-starter-web to your project.</li><li>Create a @RestController class with endpoint methods.</li><li>Use annotations to map HTTP requests to methods.</li></ol><p>This sets up a RESTful service with minimal code, leveraging Spring Boot’s embedded server.</p><p><strong>Example:</strong></p><pre><code class="language-java">import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello from Spring Boot!";
    }
}</code></pre><h2>10. What is Dependency Injection in Spring Boot?</h2><p><strong>Dependency Injection (DI)</strong> is a design pattern where dependencies are injected into a class rather than created inside it. Spring Boot uses annotations like @Autowired to manage DI.</p><p><strong>Benefits:</strong></p><ul><li>Reduces tight coupling between classes.</li><li>Makes testing easier with mock dependencies.</li><li>Centralizes bean management in the Spring context.</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Service
public class MyService {
    public String getMessage() {
        return "Hello from Service!";
    }
}

@RestController
public class MyController {
    @Autowired
    private MyService myService;

    @GetMapping("/message")
    public String getMessage() {
        return myService.getMessage();
    }
}</code></pre><h2>11. What is Spring Boot Starter Parent?</h2><p><strong>Spring Boot Starter Parent</strong> is a parent POM file in Maven that provides default configurations, dependency versions, and plugins for Spring Boot projects. It ensures consistent builds and simplifies pom.xml.</p><p><strong>Key benefits:</strong></p><ul><li>Predefined dependency versions (no need to specify versions for Spring libraries).</li><li>Default plugins for building and packaging (e.g., executable JARs).</li><li>Standard Java version and encoding settings.</li></ul><p><strong>Example (pom.xml):</strong></p><pre><code class="language-xml">&lt;parent&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
    &lt;version&gt;3.3.2&lt;/version&gt;
&lt;/parent&gt;</code></pre><h2>12. How do you connect a Spring Boot application to a database?</h2><p>Use spring-boot-starter-data-jpa for database access with JPA/Hibernate. Configure the database in application.properties or application.yml.</p><p><strong>Example:</strong></p><pre><code class="language-java">import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository&lt;User, Long&gt; {
}

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    // Getters and setters
}</code></pre><pre><code class="language-plaintext">spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update</code></pre><h2>13. What is Spring Boot DevTools?</h2><p><strong>Spring Boot DevTools</strong> enhances development by enabling features like automatic restarts when code changes and live reload in browsers.</p><p>Add this to your pom.xml, and your app restarts automatically on code changes <strong>:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
    &lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;</code></pre><h2>14. How do you handle exceptions in Spring Boot?</h2><p>Use @ControllerAdvice and @ExceptionHandler to handle exceptions globally across your application. This ensures consistent error responses for REST APIs.</p><p><strong>Key points:</strong></p><ul><li>@ControllerAdvice defines a global exception handler.</li><li>@ExceptionHandler specifies which exceptions to catch and how to respond.</li><li>Return custom error messages or HTTP status codes (e.g., 400, 500).</li></ul><p>This approach keeps error handling centralized and reusable.</p><p><strong>Example:</strong></p><pre><code class="language-java">import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity&lt;String&gt; handleIllegalArgument(IllegalArgumentException ex) {
        return new ResponseEntity&lt;&gt;("Error: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }
}</code></pre><h2>15. What is the @EnableAutoConfiguration annotation?</h2><p>@EnableAutoConfiguration enables Spring Boot’s auto-configuration, which sets up beans based on classpath dependencies. It’s part of @SpringBootApplication.</p><p><strong>Example:</strong></p><pre><code class="language-java">@SpringBootApplication // Includes @EnableAutoConfiguration
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}</code></pre><h2>16. How do you implement security in Spring Boot?</h2><p>Use spring-boot-starter-security to add authentication and authorization. Configure security rules using a SecurityFilterChain bean.</p><p><strong>Key features:</strong></p><ul><li>Secure endpoints with role-based access.</li><li>Support for OAuth2, JWT, or form-based login.</li><li>Customizable via SecurityFilterChain to define access rules.</li></ul><p>This makes it easy to secure REST APIs or web apps.</p><p><strong>Example:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre><pre><code class="language-java">import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
            .requestMatchers("/public").permitAll()
            .anyRequest().authenticated()
            .and().formLogin();
        return http.build();
    }
}</code></pre><h2>17. What is the difference between @Controller and @RestController?</h2><ul><li>@Controller: Marks a class as a web controller for MVC apps, typically returning view names (e.g., for Thymeleaf).</li><li>@RestController: A specialized @Controller that returns data (e.g., JSON) directly, combining @Controller and @ResponseBody.</li></ul><p><strong>Example:</strong></p><pre><code class="language-java">@RestController
public class MyRestController {
    @GetMapping("/api/hello")
    public String sayHello() {
        return "Hello from REST!";
    }
}</code></pre><h2>18. How do you create a Spring Boot executable JAR?</h2><p>Spring Boot’s Maven or Gradle plugin packages your app into an executable JAR with all dependencies and an embedded server.</p><p><strong>Steps:</strong></p><ol><li>Include the Spring Boot plugin in pom.xml or build.gradle.</li><li>Run mvn package or gradle build.</li><li>Execute the JAR with java -jar target/myapp.jar.</li></ol><p>This creates a single, deployable artifact for easy distribution.</p><h2>19. What is Spring Boot Actuator’s /health endpoint?</h2><p>The /health endpoint, part of Spring Boot Actuator, shows the application’s health status, including dependencies like databases or external services.</p><p><strong>Details:</strong></p><ul><li>Returns {"status":"UP"} if the app is healthy.</li><li>Can include details (e.g., database status) with management.endpoint.health.show-details=always.</li><li>Enabled with spring-boot-starter-actuator and exposed via properties.</li></ul><p>It’s critical for monitoring in production environments.</p><p><strong>Example:</strong></p><pre><code class="language-plaintext">management.endpoints.web.exposure.include=health</code></pre><h2>20. How do you implement caching in Spring Boot?</h2><p>Use spring-boot-starter-cache with annotations like @EnableCaching and @Cacheable to cache expensive operations.</p><p><strong>Steps:</strong></p><ol><li>Add spring-boot-starter-cache.</li><li>Enable caching with @EnableCaching.</li><li>Use @Cacheable on methods to cache their results.</li></ol><p><strong>Example:</strong></p><pre><code class="language-java">import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Service;

@EnableCaching
@Service
public class MyService {
    @Cacheable("data")
    public String getData(String key) {
        // Simulate slow operation
        return "Data for " + key;
    }
}</code></pre><h2>Conclusion</h2><p>Spring Boot is famous for building modern Java applications, and these 20 questions cover the core topics like auto-configuration, REST APIs, caching, security, and more. If you understand these well, you’ll feel much more confident and definitely stand out in interviews.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Santosh Mane)</author>
            <category>Spring Boot</category>
            <category>Spring</category>
            <category>Spring Boot Interview Questions</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/The_Spring_Boot_Blog_363f388959.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[10 Essential Tools Every Spring Boot Developer Should Master in 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/essential-tools-every-spring-boot-developer-should-know</link>
            <guid>https://www.codingshuttle.com/blogs/essential-tools-every-spring-boot-developer-should-know</guid>
            <pubDate>Sat, 07 Dec 2024 07:48:40 GMT</pubDate>
            <description><![CDATA[Discover the 10 most essential tools for Spring Boot developers in 2025, including IntelliJ IDEA, Postman, Docker, JUnit, and more. Learn how these tools streamline project setup, testing, deployment, and security for backend Java applications.]]></description>
            <content:encoded><![CDATA[<p><strong>Spring Boot</strong> is a popular Java framework for building backend applications. And knowing the right tools for Spring Boot can improve your coding, testing, deployment, and monitoring processes. These tools boost your productivity and save you time. So in this article, I will explain the <strong>top 10 must-know Spring Boot tools</strong> that every Spring Boot developer should be familiar with. So let’s get started.</p><h2>1. <strong>Spring Initializr</strong></h2><p>I always start my Spring Boot projects using <strong>Spring Initializr</strong>. It’s a free online tool that helps you generate a clean project structure with the right dependencies, Spring Boot version, and build tool (Maven or Gradle).</p><p>You just visit <a href="http://start.spring.io">start.spring.io</a>, select your settings, and download the ZIP file that’s it. Super easy and time-saving.</p><p><strong>Steps to Use Spring Initializr:</strong></p><ol><li>Open your browser and visit <a href="https://start.spring.io">https://start.spring.io</a>.</li><li>Select <code>Maven</code> or <code>Gradle</code> depending on your preference. I usually go with <strong>Maven</strong>.</li><li>Select <code>Java</code> (most common), but Kotlin and Groovy are also available.</li><li>I recommend going with the <strong>latest stable version</strong> unless your project needs a specific version.</li><li>Add Project Metadata</li><li>Click <strong>“Add Dependencies”</strong> and search for what you need.</li><li>Click "Generate”, This will download a ZIP file containing your Spring Boot project.</li><li>Unzip the project and import in your IDE</li></ol><h2>2. <strong>IntelliJ IDEA</strong></h2><p><strong>IntelliJ IDEA</strong> is hands down my favorite IDE for Spring Boot development. It offers smart features like auto-completion, live templates, Spring annotations support, and even debugging tools.</p><p>I personally use it for all my Spring Boot projects the Ultimate version is great if you want advanced tools, but the Community version works fine too for most needs.</p><p>If you're serious about backend development, you should definitely try IntelliJ.</p><h2>3. <strong>Maven</strong></h2><p><strong>Maven</strong> is the build tool I use in most of my projects. It handles dependency management, builds your project, and packages it — all through a simple <code>pom.xml</code>.</p><p>Thanks to Spring Boot's starters like <code>spring-boot-starter-web</code>, working with Maven becomes very smooth.</p><p>I suggest sticking with Maven when you're starting out, it keeps things simple.</p><p>Example of adding dependencies in <code>pom.xml</code> :</p><pre><code class="language-xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;</code></pre><h2>4. <strong>JUnit</strong></h2><p><strong>JUnit</strong> is the go-to testing framework in Spring Boot. With annotations like <code>@SpringBootTest</code> and <code>@MockBean</code>, testing services, repositories, and controllers becomes very easy.</p><p>I’ve used JUnit in almost every project — it’s a must-have if you want bug-free code and clean deployments.</p><p>Example of basic JUnit test :</p><pre><code class="language-java">@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    void shouldReturnUserById() {
        User user = userService.getUserById(1L);
        assertNotNull(user);
    }
}</code></pre><h2>5. <strong>Postman</strong></h2><p>Whenever I build APIs with Spring Boot, <strong>Postman</strong> is my best friend. It helps me test my endpoints by sending real HTTP requests and checking the responses.</p><p>I really suggest using Postman while building or debugging APIs, it’ll save you hours of guesswork.</p><p><strong>Steps to Download and Install Postman :</strong></p><ol><li>Open your browser and go to: <a href="https://www.postman.com/downloads/">https://www.postman.com/downloads/</a></li><li>Postman will automatically detect your operating system. Click the <strong>Download</strong> button for your OS (e.g., Windows, macOS, or Linux).</li><li>Once the <code>.exe</code> (Windows) or <code>.zip</code>/<code>.dmg</code> (macOS) file is downloaded, locate it in your <strong>Downloads</strong> folder.</li><li>Run the installer for <strong>Windows</strong>, double-click the <code>.exe</code> file and for <strong>macOS</strong>, open the <code>.dmg</code> file and drag Postman to the Applications folder.</li><li>After installation, you can now open <strong>Postman</strong>.</li></ol><h2>6. <strong>Docker</strong></h2><p>If you want your Spring Boot app to run the same on every machine, use <strong>Docker</strong>. I’ve used it to containerize my apps and deploy them easily without worrying about environment issues.</p><p>I suggest learning Docker early it’s super helpful for deployment and team collaboration.</p><p>Example of Dockerfile for spring boot :</p><pre><code class="language-plaintext">FROM openjdk:17
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]</code></pre><h2>7. <strong>Flyway</strong></h2><p><strong>Flyway</strong> is a great tool for handling database version control. I use it to manage schema migrations, especially when working with teams or multiple environments.</p><p>If you're tired of manually updating your DB schema, Flyway is the solution.</p><p>Example of migration file (V1__create_users_table.sql) :</p><pre><code class="language-plaintext">CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    email VARCHAR(100) UNIQUE
);</code></pre><p>And in application.properties :</p><pre><code class="language-plaintext">spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration</code></pre><h2>8. <strong>Spring Boot Actuator</strong></h2><p><strong>Actuator</strong> adds production-ready features to your app — like health checks, metrics, environment info, and more. It's very useful when your app goes live.</p><p>I recommend enabling Actuator when deploying your project — it helps you monitor your app without writing extra code.</p><p>Example of enabling actuator :</p><p>In <code>pom.xml</code>:</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-actuator&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p>In <code>application.properties</code>:</p><pre><code class="language-plaintext">management.endpoints.web.exposure.include=health,info</code></pre><p>Then access health endpoint at:</p><pre><code class="language-plaintext">&lt;http://localhost:8080/actuator/health&gt;</code></pre><h2>9. <strong>Lombok</strong></h2><p><strong>Lombok</strong> is one of my personal favorites. It reduces boilerplate code using annotations like <code>@Getter</code>, <code>@Setter</code>, <code>@AllArgsConstructor</code>, etc.</p><p>I’ve saved so much time using Lombok, especially when writing model or DTO classes. Just don’t forget to install the Lombok plugin in your IDE.</p><p>Example of using lombok in entity :</p><pre><code class="language-java">import lombok.Getter;
import lombok.Setter;
import lombok.NoArgsConstructor;

@Getter
@Setter
@NoArgsConstructor
@Entity
public class User {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private String email;
}</code></pre><h2>10. <strong>Spring Security</strong></h2><p>If your app needs login functionality or role-based access, then <strong>Spring Security</strong> is the tool for that. It handles authentication and authorization out of the box.</p><p>I use Spring Security in all my production-level apps — it’s reliable and integrates smoothly with Spring Boot.</p><p>Example of basic security config :</p><pre><code class="language-java">@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
          .authorizeHttpRequests()
            .requestMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
          .and()
            .formLogin();
        return http.build();
    }
}</code></pre><h2>Conclusion</h2><p>These 10 tools Spring Initializr, IntelliJ IDEA, Maven, JUnit, Postman, Docker, Flyway, Spring Boot Actuator, Lombok, and Spring Security are essential for every Spring Boot developer. They support you throughout the development lifecycle from setting up your project to building, testing, deploying, and securing it.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Spring</category>
            <category>Spring Boot</category>
            <category>Java</category>
            <category>Backend Development</category>
            <category>Programming Tools</category>
            <category>Developer Productivity</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Should_Master_in_2025_25078446cf.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Top 7 Spring Boot Libraries Every Developer Should Master in 2025]]></title>
            <link>https://www.codingshuttle.com/blogs/top-5-spring-boot-libraries-you-need-to-know-about</link>
            <guid>https://www.codingshuttle.com/blogs/top-5-spring-boot-libraries-you-need-to-know-about</guid>
            <pubDate>Sat, 07 Dec 2024 07:42:56 GMT</pubDate>
            <description><![CDATA[Discover the top 7 Spring Boot libraries from Spring Boot Starter Web to Spring Cloud that will boost your productivity, simplify development, and help you build production-ready apps.]]></description>
            <content:encoded><![CDATA[<p>A&nbsp;<strong>library</strong>&nbsp;is a collection of pre-written code that provides reusable functionality for your project. It is a&nbsp;<strong>type of dependency</strong>, but not all dependencies are libraries. Libraries are specific reusable code collections included as part of a dependency. When you add a dependency, it often includes multiple libraries bundled together.</p><p>In this article, I will explain some of the <strong>most useful Spring Boot libraries</strong> you should know about. These will not only speed up your development process but also make your code cleaner and easier to maintain. I will also include simple examples so you can understand better.</p><h2><strong>1. Spring Boot Starter Web</strong></h2><p>The Spring Boot Starter Web dependency simplifies web application development by providing all the essential tools and libraries for building web-based or API-driven applications. It automatically configures everything necessary to develop and deploy web applications with Spring Boot.</p><p>When I first used Spring Boot Starter Web, I was genuinely happy to see that I didn’t have to manually add multiple web dependencies, everything I needed was already there.</p><p><strong>Key Features:</strong></p><ol><li>Embedded Tomcat (or Jetty/Undertow) server — no separate installation required.</li><li>Built-in support for REST APIs and JSON (via Jackson).</li><li>Automatic configuration for MVC controllers.</li></ol><p><strong>Adding the Dependency :</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p><strong>Example:</strong></p><pre><code class="language-java">@RestController
public class HelloController {
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello from Spring Boot!";
    }
}</code></pre><h2><strong>2. Spring Data JPA</strong></h2><p>Spring Data JPA makes working with databases much easier by providing a clean, object-oriented approach to data access. Instead of writing long and complex SQL queries, you can simply create Java interfaces and Spring Data JPA handles the rest for you.</p><p>When I first started using it, I was amazed at how quickly I could perform CRUD operations without writing even a single SQL statement.</p><p><strong>Key Features:</strong></p><ol><li>Simplifies database operations with Repository interfaces.</li><li>Automatically generates SQL queries based on method names.</li><li>Supports pagination and sorting out of the box.</li></ol><p><strong>Adding the Dependency:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p><strong>Example:</strong></p><pre><code class="language-java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {
    List&lt;User&gt; findByName(String name);</code></pre><h2><strong>3. Spring Security</strong></h2><p>Spring Security is the go-to framework for securing your Spring Boot applications. It handles authentication, authorization, and other security concerns with minimal configuration.</p><p>When I implemented it for the first time, I liked how quickly I could protect my APIs and add login functionality without writing too much boilerplate code.</p><p><strong>Key Features:</strong></p><ol><li>Handles both authentication and authorization.</li><li>Supports multiple authentication methods (form login, JWT, OAuth2, etc.).</li><li>Highly customizable for complex security requirements.</li></ol><p><strong>Adding the Dependency:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p><strong>Example:</strong></p><pre><code class="language-java">@RestController
public class SecureController {
    @GetMapping("/secure")
    public String secureEndpoint() {
        return "This is a secured endpoint!";
    }
}</code></pre><h2><strong>4. Spring Boot Actuator</strong></h2><p>Spring Boot Actuator gives you production-ready tools to monitor and manage your application. With just one dependency, you can get insights into your app’s health, metrics, and environment.</p><p>When I first explored Actuator, I was surprised by how many ready-to-use endpoints it offered without extra setup.</p><p><strong>Key Features:</strong></p><ol><li>Health checks and application info endpoints.</li><li>Metrics for performance monitoring.</li><li>Easy integration with monitoring tools like Prometheus and Grafana.</li></ol><p><strong>Adding the Dependency:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-actuator&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p><strong>Example:</strong></p><p>Access <code>http://localhost:8080/actuator/health</code> to see the health status of your application.</p><h2><strong>5. Lombok</strong></h2><p>Lombok helps you reduce boilerplate code in your Java classes. It automatically generates getters, setters, constructors, and more at compile time.</p><p>The first time I used Lombok, I instantly loved how clean my entities and DTOs looked without all those repetitive getter and setter methods.</p><p><strong>Key Features:</strong></p><ol><li>Generates getters, setters, constructors, equals, hashCode, and toString methods automatically.</li><li>Reduces boilerplate and improves code readability.</li><li>Works seamlessly with Spring Boot projects.</li></ol><p><strong>Adding the Dependency:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
    &lt;artifactId&gt;lombok&lt;/artifactId&gt;
    &lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;</code></pre><p><strong>Example:</strong></p><pre><code class="language-java">import lombok.Data;

@Data
public class User {
    private Long id;
    private String name;
}</code></pre><h2><strong>6. Jakarta Validation</strong></h2><p>Jakarta Validation (formerly Bean Validation) helps you validate user input before it even reaches your business logic. It works beautifully with Spring Boot and can save you from a lot of manual validation code.</p><p>When I first tried it, I appreciated how easy it was to add validation rules directly to my entity fields.</p><p><strong>Key Features:</strong></p><ol><li>Built-in annotations like <code>@NotNull</code>, <code>@Size</code>, <code>@Email</code>, etc.</li><li>Customizable validation messages.</li><li>Integrates seamlessly with Spring Boot controllers.</li></ol><p><strong>Adding the Dependency:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;jakarta.validation&lt;/groupId&gt;
    &lt;artifactId&gt;jakarta.validation-api&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p><strong>Example:</strong></p><pre><code class="language-java">public class UserDTO {
    @NotNull
    @Size(min = 3, max = 50)
    private String name;
}</code></pre><h2><strong>7. Spring Cloud</strong></h2><p>Spring Cloud is a set of tools for building distributed systems and microservices. It makes it easier to handle service discovery, configuration management, load balancing, and more.</p><p>When I started using it, I realized how much simpler it made developing microservices that need to work together.</p><p><strong>Key Features:</strong></p><ol><li>Service discovery with Netflix Eureka.</li><li>Centralized configuration management with Spring Cloud Config.</li><li>Intelligent routing and load balancing with Spring Cloud Gateway.</li></ol><p><strong>Adding the Dependency:</strong></p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre><p><strong>Example:</strong></p><pre><code class="language-java">@SpringBootApplication
public class MicroserviceApplication {
    public static void main(String[] args) {
        SpringApplication.run(MicroserviceApplication.class, args);
    }
}</code></pre><h2>Conclusion</h2><p>Mastering these Spring Boot libraries can completely change how you build applications. They don’t just save you time they make your code cleaner, easier to maintain, and ready for production. From creating simple REST APIs to building large-scale, secure, and distributed systems, these libraries are your ultimate toolkit.</p>]]></content:encoded>
            <author>contact@codingshuttle.com (Shreya Adak)</author>
            <category>Spring</category>
            <category>Spring Boot</category>
            <category>Spring Boot libraries</category>
            <category>Spring Boot tutorial</category>
            <category>Spring Cloud microservices</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Top_7_Spring_Boot_Libraries_30e5ae306c.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Operating Systems In One Shot]]></title>
            <link>https://www.codingshuttle.com/blogs/operating-systems-in-one-shot</link>
            <guid>https://www.codingshuttle.com/blogs/operating-systems-in-one-shot</guid>
            <pubDate>Sun, 29 Sep 2024 06:14:04 GMT</pubDate>
            <description><![CDATA[Cover the complete Operating Systems In One Go, Best suited for last minute prep for your Interviews or University exams. Cheers!]]></description>
            <content:encoded><![CDATA[<h3>1. <strong>What is an Operating System &amp; Types of OS</strong></h3><p>An operating system (OS) is software that acts as an interface between computer hardware and user applications. It manages the resources and provides services for the efficient and secure execution of programs. The primary functions of an operating system include process management, memory management, file system management, device management, and user interface.</p><p>There are several types of operating systems, including:</p><ol><li><strong>Windows</strong>: Developed by Microsoft, Windows is a widely used operating system for personal computers. It offers a user-friendly interface, supports a vast range of software applications, and is compatible with various hardware configurations.</li><li><strong>macOS</strong>: Developed by Apple, macOS is the operating system used on Apple Mac computers. It provides a sleek and intuitive user interface, seamless integration with other Apple devices, and a robust ecosystem of software applications.</li><li><strong>Linux</strong>: Linux is an open-source operating system that is highly customisable and widely used in server environments and embedded systems. It offers a high level of stability, security, and flexibility. Numerous distributions of Linux, such as Ubuntu, Fedora, and CentOS, cater to different user needs.</li><li><strong>Unix</strong>: Unix is a powerful multi-user operating system that served as the foundation for many other operating systems, including Linux and macOS. It provides a stable and secure environment and is famous for server applications.</li><li><strong>Android</strong>: Developed by Google, Android is an open-source operating system primarily designed for mobile devices such as smartphones and tablets. It offers a rich ecosystem of applications and customisation options.</li><li><strong>iOS</strong>: Developed by Apple, iOS is the operating system used on iPhones, iPads, and iPods. It provides a seamless and secure user experience, focusing on performance and integration with other Apple devices.</li><li><strong>Real-Time Operating Systems (RTOS)</strong>: RTOS is designed for systems that require deterministic and real-time response. It is commonly used in embedded systems, control systems, and IoT devices.</li></ol><h3>2. <strong>Difference between Multiprogramming, Multiprocess, Multitasking, and Multithreading</strong></h3><ol><li><strong>Multiprocess</strong>: Multiprocess refers to the execution of multiple processes on a system with multiple CPUs or CPU cores. Each process is an instance of a running program, and multiple processes can execute concurrently. In multiprocess systems, each process has its own memory space and resources. Multiprocessing aims to increase system throughput and provide faster execution by distributing the workload across multiple processors.</li><li><strong>Multithreading</strong>: Multithreading involves executing multiple threads within a single process. A thread is a lightweight unit of execution that can run concurrently with other threads within the same process. Threads share the same memory space and resources, such as file handles and network connections. Multithreading allows for parallel execution within a process, enabling better utilization of system resources and potentially improving performance by dividing tasks into smaller units of work that can be executed concurrently.</li><li><strong>Multiprogramming</strong>: Multiprogramming is a technique where multiple programs are loaded into memory simultaneously, and the CPU switches between them to execute instructions. The purpose of multiprogramming is to maximize CPU utilization and keep the CPU busy by quickly switching between different programs when one is waiting for I/O or other operations. Each program has its own separate memory space.</li><li><strong>Multitasking</strong>: Multitasking is a technique that allows multiple tasks or processes to run concurrently on a single CPU. The CPU time is divided among the tasks, giving the illusion of parallel execution. The operating system switches between tasks rapidly, giving each task a time slice or quantum to execute. Multitasking is commonly used in modern operating systems to provide responsiveness and the ability to run multiple applications simultaneously.</li></ol><h3>3. Process vs Threads vs Programs</h3><ul><li><strong>Program</strong>: A program is a set of instructions written in a programming language that performs a specific task or set of tasks. It is typically stored in a file on disk and represents an executable entity. Programs can be compiled or interpreted, and they serve as a blueprint for the execution of tasks on a computer system.</li><li><strong>Process</strong>: A process is an instance of a program in execution. When a program is loaded into memory and executed, it becomes a process. A process is an independent entity with its own memory space, resources, and execution context. It has its own program counter, stack, and variables. Processes are managed by the operating system, and each process runs in its own protected memory space. Processes can be concurrent and communicate with each other through inter-process communication mechanisms.</li><li><strong>Thread</strong>: A thread is a unit of execution within a process. It represents a sequence of instructions that can be scheduled and executed independently. Threads share the same memory space and resources within a process. Multiple threads within a process can run concurrently, allowing for parallel execution of tasks. Threads within the same process can communicate and share data more easily compared to inter-process communication. However, each thread has its own program counter and stack.</li></ul><p>In summary, a program is a set of instructions, a process is an instance of a program in execution with its own resources and memory space, and a thread is a unit of execution within a process that allows for the concurrent execution of tasks. Processes provide isolation and protection between different instances of a program, while threads within a process share resource and enable parallel execution of tasks.</p><h3>4. Various Process States</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/process_scheduling_dca7781437.png" alt="Various process states in Operating System Process scheduling" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_process_scheduling_dca7781437.png 195w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_process_scheduling_dca7781437.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_process_scheduling_dca7781437.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_process_scheduling_dca7781437.png 1000w," sizes="100vw"><figcaption>Various process states in Operating System Process scheduling</figcaption></figure><h3>5. CPU scheduling Algorithms</h3><p>CPU scheduling algorithms are used by the operating system to determine the order in which processes are executed on the CPU.</p><ol><li><strong>First-Come, First-Served (FCFS):</strong> In the FCFS scheduling algorithm, the process that arrives first is executed first. It follows a non-preemptive approach, meaning that once a process starts running, it continues until it completes or voluntarily gives up the CPU. FCFS is simple to understand but may lead to poor utilization of the CPU if long processes arrive before shorter ones.</li><li><strong>Shortest Job Next (SJN) or Shortest Job First (SJF):</strong> SJN or SJF scheduling selects the process with the shortest total execution time next. It can be either non-preemptive or preemptive. In the non-preemptive variant, the process continues executing until it completes, whereas in the preemptive variant, if a new process with a shorter burst time arrives, the currently running process may be preempted. SJN/SJF aims to minimize the average waiting time and is suitable when burst times are known in advance.</li><li><strong>Round Robin (RR):</strong> Round Robin is a preemptive scheduling algorithm that assigns a fixed time quantum (e.g., 10 milliseconds) to each process in a circular manner. Once a process exhausts its time quantum, it is moved to the back of the ready queue, allowing the next process in line to execute. RR provides fair execution to all processes but may suffer from high context-switching overhead and may not be efficient for long-running processes.</li><li><strong>Priority Scheduling:</strong> Priority scheduling assigns a priority value to each process, and the CPU is allocated to the process with the highest priority. It can be either preemptive or non-preemptive. In preemptive priority scheduling, if a higher-priority process arrives, the currently running process may be preempted. In non-preemptive priority scheduling, the process continues executing until it completes or voluntarily gives up the CPU. Priority scheduling can suffer from starvation if a lower-priority process never gets a chance to execute.</li><li><strong>Multilevel Queue Scheduling:</strong> Multilevel queue scheduling divides the ready queue into multiple priority queues, each with its own scheduling algorithm. Processes are initially placed in the highest-priority queue and can move between queues based on predefined criteria. This approach allows for the differentiation of processes based on their priority or characteristics, such as foreground or background tasks. Each queue can use a different scheduling algorithm, such as FCFS, SJF, or RR, suitable for the processes within that queue.</li></ol><h3>6. Critical section Problem</h3><p>The critical section represents a portion of code or a block where a process or thread accesses a shared resource, such as a variable, file, or database. It's a section that needs to be executed in an atomic or mutually exclusive manner.</p><p>To maintain data integrity and avoid conflicts, only one process or thread should be allowed to enter the critical section at a time. This ensures that no two processes interfere with each other and modify shared resources simultaneously, preventing inconsistencies or incorrect results.</p><h3>7. Process synchronisation</h3><p>Process synchronization is like a traffic signal that helps regulate the flow of vehicles at an intersection. In the context of computing, it refers to techniques and mechanisms used to coordinate the execution of processes or threads so that they can work together harmoniously.</p><p>Imagine multiple processes or threads working on different tasks simultaneously. Process synchronization ensures that they cooperate and communicate effectively to avoid conflicts and ensure proper order of execution. It helps prevent issues like race conditions, data inconsistencies, or deadlocks that can arise when multiple processes or threads access shared resources simultaneously.</p><p>Here are the key requirements of synchronization mechanisms:</p><ol><li><strong>Mutual Exclusion</strong>: The synchronization mechanism should enforce mutual exclusion, which means that only one process or thread can access a shared resource or enter a critical section at a time. It ensures that concurrent access to shared resources does not result in conflicts or inconsistencies.</li><li><strong>Progress</strong>: The synchronization mechanism should allow processes or threads to make progress by ensuring that at least one process/thread can enter the critical section when it desires to do so. It avoids situations where all processes/threads are blocked indefinitely, leading to a deadlock.</li><li><strong>Bounded Waiting</strong>: The synchronization mechanism should provide a guarantee that a process/thread waiting to enter a critical section will eventually be allowed to do so. It prevents a process/thread from being starved or waiting indefinitely to access a shared resource</li></ol><h3>8. Process Synchronisation Mechanisms</h3><p>Here are some of the mechanisms that fulfill the above process synchronization requirements:</p><ol><li><strong>Locks/Mutexes</strong>: Locks or mutexes (mutual exclusions) provide a simple and effective way to achieve mutual exclusion. They allow only one process or thread to acquire the lock at a time, ensuring exclusive access to a shared resource or critical section. Locks can be implemented using hardware instructions or software constructs.</li><li><strong>Semaphores</strong>: Semaphores are synchronization objects that can be used to control access to shared resources. They can be implemented as binary semaphores (mutexes) or counting semaphores. Counting semaphores allow a specified number of processes or threads to access a shared resource simultaneously. Semaphores provide mechanisms for mutual exclusion, signaling, and coordination.</li><li><strong>Read-Write Locks</strong>: Read-write locks provide synchronization mechanisms for scenarios where multiple readers can simultaneously access a shared resource without conflicts, but exclusive access is required for writers. Read locks can be acquired simultaneously by multiple readers, while write locks are exclusive. Read-write locks allow for better concurrency when reading is more frequent than writing.</li></ol><h3>9. Deadlock</h3><figure class="image image_resized image-style-side" style="width:42.78%;"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_10_03_at_12_21_06_PM_3de194940f.png"></figure><p>A Deadlock is a situation where each of the computer processes waits for a resource that is being assigned to another process. In this situation, none of the process gets executed since the resource it needs, is held by some other process that is also waiting for some other resource to be released.</p><p>Necessary Conditions for Deadlocks:</p><ul><li><strong>Mutual Exclusion</strong> A resource can only be shared in a mutually exclusive manner. It implies that two processes cannot use the same resource at the same time.</li><li><strong>Hold and Wait</strong> A process waits for some resources while holding another resource at the same time.</li><li><strong>No preemption</strong> The process once scheduled will be executed till the completion. No other process can be scheduled by the scheduler meanwhile.</li><li><strong>Circular Wait</strong> All the processes must be waiting for the resources in a cyclic manner so that the last process is waiting for the resource which is being held by the first process.</li></ul><h3>10. Deadlock Handling Techniques</h3><ol><li><strong>Deadlock Prevention</strong>: Deadlock prevention techniques aim to eliminate one or more of the necessary conditions for deadlock to occur. These conditions include mutual exclusion, hold and wait, no preemption, and circular wait. By ensuring that one or more of these conditions are not satisfied, deadlocks can be prevented from happening in the first place. However, prevention techniques may impose restrictions on resource allocation and may not be always feasible or efficient.</li><li><strong>Deadlock Avoidance</strong>: Deadlock avoidance techniques use resource allocation algorithms and resource request protocols to avoid situations that may lead to deadlocks. These techniques involve the use of resource allocation graphs, bankers' algorithm, or other dynamic allocation strategies. The idea is to have a system that can predict whether granting a resource request will lead to a potential deadlock. If a request might cause a deadlock, it is delayed until granting it will not cause any issues.</li><li><strong>Deadlock Detection</strong>: Deadlock detection techniques involve periodically examining the resource allocation state to determine if a deadlock has occurred. This can be achieved through algorithms such as the resource-allocation graph or the Banker's algorithm. When a deadlock is detected, the system can take appropriate actions to resolve it, such as terminating processes, resource preemption, or rolling back the system to a safe state.</li><li><strong>Deadlock Recovery</strong>: Deadlock recovery techniques are used to recover from a deadlock once it has been detected. This involves terminating one or more processes involved in the deadlock to break the circular wait and release the resources held by those processes. The terminated processes can be restarted later to continue their execution.</li><li><strong>Deadlock Ignorance</strong>: Some systems choose to ignore the problem of deadlocks entirely. This approach assumes that deadlocks will rarely occur and focuses on other system aspects. However, it is generally not recommended unless deadlocks are extremely rare or have minimal impact on system functionality. Operating systems like Windows and Linux mainly focus on performance. However, the performance of the system decreases if it uses a deadlock handling mechanism all the time if a deadlock happens 1 out of 100 times then it is completely unnecessary to use the deadlock handling mechanism all the time.</li></ol><h3>11. Memory Management</h3><p>Fixed partitioning and dynamic partitioning are two approaches used in memory management systems to allocate and manage memory resources. Let's discuss each approach:</p><p><strong>Fixed Partitioning:</strong> In fixed partitioning, memory is divided into fixed-sized partitions or blocks, and each partition is assigned to a specific process or task. The system allocates a predetermined amount of memory to each partition, which remains fixed throughout the execution.</p><p>Fixed partitioning is relatively simple to implement and provides fast memory allocation. However, it can lead to inefficient memory utilization due to internal fragmentation, especially when processes have varying memory requirements.</p><p><strong>Dynamic Partitioning:</strong> Dynamic partitioning, also known as variable partitioning, addresses the limitation of fixed partitioning by allowing memory to be allocated and deallocated dynamically based on the size requirements of processes.</p><p>Dynamic partitioning provides better memory utilization compared to fixed partitioning, as memory can be allocated based on actual requirements. However, managing fragmentation and efficiently allocating and deallocating memory can be more complex.</p><p>Memory management techniques, such as compaction or memory allocation algorithms like <strong>first-fit, best-fit, or worst-fit,</strong> are employed to optimize memory utilization and minimize fragmentation in dynamic partitioning systems.</p><h3>12. Partition and Memory allocation</h3><ol><li><strong>First Fit</strong>: The first-fit algorithm allocates the first available memory block that is large enough to accommodate the process. It starts searching from the beginning of the memory and selects the first suitable block encountered. This algorithm is simple and provides fast allocation, but it may result in relatively larger leftover fragments.</li><li><strong>Best Fit</strong>: The best-fit algorithm searches for the smallest available memory block that is large enough to accommodate the process. It aims to minimize leftover fragments by choosing the most optimal block. This algorithm can lead to better overall memory utilization, but it may involve more time-consuming searches.</li><li><strong>Worst Fit</strong>: The worst-fit algorithm allocates the largest available memory block to the process. This approach intentionally keeps larger fragments to accommodate potential future larger processes. While it may seem counterintuitive, it can help reduce fragmentation caused by small processes and improve overall memory utilization.</li></ol><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Screenshot_2024_10_03_at_12_22_50_PM_c9e61af6a8.png"><figcaption>Paging</figcaption></figure><h3>14. Virtual Memory</h3><p>Virtual memory is a concept that lets a computer use more memory than it actually has. It creates an imaginary memory space by combining physical memory (RAM) and secondary storage (like a hard disk). When a program needs more memory than is available in RAM, it temporarily moves some data to the secondary storage. This allows the computer to run larger programs and handle multiple tasks at once. Virtual memory also provides memory protection, ensuring that programs can't access each other's memory directly.</p><p>Instead of loading one big process in the main memory, the Operating System loads the different parts of more than one process in the main memory.</p><p>By doing this, the degree of multiprogramming will be increased and therefore, the CPU utilization will also be increased.</p><h3>15. Page replacement algorithms</h3><p><strong>First-In-First-Out Page Replacement Algorithm</strong></p><p>In FIFO page replacement, the operating system maintains a queue or list of pages in the order they were brought into memory. When a page fault happens (i.e., the required page is not in memory), the page at the front of the queue, which was the earliest one to be brought in, is selected for replacement. The new page is then brought into memory, and the page at the front of the queue is removed.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/First_In_First_Out_Page_Replacement_Algorithm_e2e402368d.png" alt="First-In-First-Out Page Replacement Algorithm.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_First_In_First_Out_Page_Replacement_Algorithm_e2e402368d.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_First_In_First_Out_Page_Replacement_Algorithm_e2e402368d.png 500w," sizes="100vw"></p><p><strong>Optimal Page replacement</strong></p><p>In this algorithm, pages are replaced which would not be used for the longest duration of time in the future.</p><p>In theory, optimal page replacement provides the best possible performance by minimizing the number of page faults. However, in practice, it is not feasible to implement the optimal page replacement algorithm in most real-world scenarios. The main reason for this is that the algorithm requires knowledge of future page references, which is generally impossible to determine in advance.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Optimal_Page_replacement_d6d60e09b3.png" alt="Optimal Page replacement.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Optimal_Page_replacement_d6d60e09b3.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Optimal_Page_replacement_d6d60e09b3.png 500w," sizes="100vw"></p><p><strong>Least Recently Used</strong></p><p>In this algorithm, the page will be replaced which is least recently used.</p><p>LRU works on the principle that pages that have been recently accessed are more likely to be accessed again in the near future. By replacing the least recently used pages, it aims to retain the frequently accessed pages in memory, reducing the number of page faults and improving overall system performance.</p><p><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Least_Recently_Used_ed21d3b1ab.png" alt="Least Recently Used.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Least_Recently_Used_ed21d3b1ab.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Least_Recently_Used_ed21d3b1ab.png 500w," sizes="100vw"></p><h3>16. Thrashing</h3><figure class="image image_resized image-style-side" style="width:45.58%;"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Thrashing_460ff00dee.png" alt="Thrashing.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Thrashing_460ff00dee.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Thrashing_460ff00dee.png 500w," sizes="100vw"></figure><p>Thrashing refers to a situation in computer systems where the system spends a significant amount of time and resources continuously swapping pages between physical memory (RAM) and secondary storage (such as a hard disk) due to excessive paging activity. In thrashing, the system is busy moving pages in and out of memory rather than executing useful work, leading to severe degradation in performance.</p><h3>17. Segmentation</h3><p>Segmentation&nbsp;divides processes into smaller subparts known as&nbsp;<strong>modules</strong>. The divided segments need not be placed in contiguous memory. Since there is no contiguous memory allocation, internal fragmentation does not take place. The length of the segments of the program and memory is decided by the purpose of the segment in the user program.</p><figure class="image image-style-side"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Segmentation_2fac319c9e.png" alt="Segmentation.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Segmentation_2fac319c9e.png 200w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Segmentation_2fac319c9e.png 500w," sizes="100vw"></figure><p>Segmentation&nbsp;came into existence because of the problems with the paging technique. In the case of the&nbsp;paging technique, a function or piece of code is divided into pages without considering that the relative parts of code can also get divided. Hence, for the process in execution, the CPU must load more than one page into the frames so that the complete related code is there for execution. Paging took more pages for a process to be loaded into the main memory.</p><p>Hence, segmentation was introduced in which the code is divided into modules so that related code can be combined in one single block.</p><h3>18. Disk Management</h3><figure class="image"><img src="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/Disk_management_f250fc6e37.png" alt="Disk management.png" srcset="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/thumbnail_Disk_management_f250fc6e37.png 245w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/small_Disk_management_f250fc6e37.png 500w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/medium_Disk_management_f250fc6e37.png 750w,https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/large_Disk_management_f250fc6e37.png 1000w," sizes="100vw"><figcaption>Disk Sector, Spindle and Boom</figcaption></figure><p><strong>Seek Time</strong></p><p>Seek time is the time taken in locating the disk arm to a specified track where the read/write request will be satisfied.</p><p><strong>Rotational Latency</strong></p><p>It is the time taken by the desired sector to rotate itself to the position from where it can access the R/W heads.</p><h3>19. Disk scheduling algorithms</h3><p>Disk scheduling is a key component of disk management that determines the order in which disk I/O (input/output) requests are processed and serviced by the disk controller. It aims to minimize the seek time and rotational latency and maximize the overall disk performance.</p><ol><li><strong>FCFS (First-Come, First-Served)</strong>: This is the simplest disk scheduling algorithm that processes requests in the order they arrive. It does not consider the position of the disk head or the proximity of the requests, resulting in potential delays if there are long seek times between requests.</li><li><strong>SSTF (Shortest Seek Time First)</strong>: This algorithm selects the request with the shortest seek time from the current position of the disk head. It minimizes the average seek time and reduces the overall disk access time. However, it may lead to starvation of requests located farther away from the current position.</li><li><strong>SCAN</strong>: Also known as the elevator algorithm, SCAN moves the disk head in one direction (e.g., from the outermost track to the innermost or vice versa) and services requests along the way. Once it reaches the end, it changes direction and continues the same process. This algorithm provides a fair distribution of service and prevents starvation, but it may result in longer response times for requests at the far ends of the disk.</li><li><strong>C-SCAN (Circular SCAN)</strong>: Similar to SCAN, C-SCAN moves the disk head in one direction, but instead of reversing direction, it jumps to the other end of the disk and starts again. This ensures a more consistent response time for all requests, but it may cause delays for requests that arrive after the head has passed their location.</li><li><strong>LOOK</strong>: LOOK is a variant of SCAN that only goes as far as the last request in its current direction. Once there are no more requests in that direction, it reverses direction. This reduces unnecessary traversal of the entire disk and improves response times for requests.</li><li><strong>C-LOOK (Circular LOOK)</strong>: Similar to C-SCAN, C-LOOK jumps to the other end of the disk without servicing requests along the way. This reduces seek time and improves disk throughput.</li></ol>]]></content:encoded>
            <author>contact@codingshuttle.com (Anuj Kumar Sharma)</author>
            <category>Operating Systems</category>
            <enclosure url="https://cs-prod-assets-bucket.s3.ap-south-1.amazonaws.com/operating_system_in_one_video_thumbnail_04dddacdb4.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>