Showing posts with label PlatformEngineering. Show all posts
Showing posts with label PlatformEngineering. Show all posts

Sunday, August 24, 2025

The Engineering Fundamentals AI Can't Teach You (But Will Thank You For Learning)


Introduction

AI-powered coding tools are transforming how engineers work, from writing code faster to reducing boilerplate. But here’s the truth: when production issues hit, or when you need to design systems that scale and perform reliably, no AI tool can replace deep technical fundamentals. These skills separate average coders from true engineers.

Here’s a breakdown of the key areas every software engineer should master today:

1. Redis: High-Speed Data Access
AI tools can autocomplete your queries, but when you need blazing-fast data retrieval or to handle sudden traffic spikes, Redis expertise is invaluable. Learn its data structures, caching patterns, and persistence models.

2. Docker & Kubernetes: Building and Scaling
Code completion doesn’t deploy containers. Knowing how to package applications with Docker and orchestrate them with Kubernetes ensures your code is ready for the real world—build, ship, and scale seamlessly.

3. Message Queues (Kafka, RabbitMQ, SQS): Decoupling and Resilience
Distributed systems thrive on loose coupling. Message queues handle spikes, failures, and asynchronous workflows. AI won’t tell you why messages vanished at 3 AM, but hands-on queueing experience will.

4. ElasticSearch: Beyond Keyword Search
Search and analytics aren’t solved by simple LIKE queries. ElasticSearch helps you build full-text search, log analysis, and real-time dashboards at scale.

5. WebSockets: Real-Time Systems
Chats, games, trading dashboards—real-time needs a robust communication layer. WebSockets enable bi-directional, low-latency connections. Learning to design and maintain fault-tolerant channels is essential.

6. Distributed Tracing: Navigating Microservices
With dozens of services talking to each other, tracing gives visibility. Tools like Jaeger or Zipkin show exactly where failures occur. AI might say “trace it,” but you need to know how to set it up effectively.

7. Logging & Monitoring: Your Early Warning System
Logs are your forensic evidence when things go wrong. Combine structured logging with monitoring solutions (Prometheus, Grafana) to spot problems before users do.

8. Concurrency & Race Conditions: Taming the Beast
Async code and multithreading introduce subtle bugs. Understanding locks, semaphores, and safe concurrent patterns will save countless hours of debugging.

9. Load Balancers & Circuit Breakers: Staying Up Under Stress
When services fail or traffic surges, load balancers and fault-tolerant patterns keep your systems alive. Knowing when and how to implement them is critical.

10. API Gateways & Rate Limiting: Protecting Your Services
Public APIs are magnets for abuse. Gateways, throttling, and quota enforcement prevent downtime, overuse, and security holes.

11. SQL vs NoSQL: The Right Tool for the Job
Every database has strengths and trade-offs. Learn to evaluate schema design, consistency, and performance needs before picking SQL or NoSQL.

12. CAP Theorem & Consistency Models: Thinking Distributed
Trade-offs between consistency, availability, and partition tolerance define distributed systems. Understanding these principles makes you a system designer, not just a coder.

13. CDN & Edge Computing: Speeding Up Globally
Global users demand fast response times. CDNs and edge networks push content closer to users, reducing latency and improving reliability.

14. Security Basics: Building Trust
OAuth, JWT, encryption—these aren’t optional. A single security misstep can undo years of work. Learn to integrate security at every layer.

15. CI/CD & Git: Automating Quality
AI might generate code, but you still need robust pipelines for testing, deployments, and rollbacks. Master Git workflows and CI/CD tools for seamless releases.

Conclusion
AI will make you faster, but fundamentals make you effective. Write scripts, break systems, monitor failures, and learn by doing. These hands-on skills are what make you stand out—not just as someone who writes code, but as an engineer who builds resilient, scalable systems.

Saturday, July 26, 2025

Concurrency ≠ Parallelism: Here’s Why It Matters

Once upon a time, computers had a single CPU and could run only one task at a time.

Still it completed tasks faster than humans.

concurrency is not parallelism

Yet the system wasted CPU time waiting for input-output (I/O) responses, such as keyboard input.

And the system became slow and non-responsive as the number of tasks grew.

So they set up a scheduler and broke down each task into smaller parts.

A CPU Running Concurrent Tasks
A CPU Running Concurrent Tasks

The scheduler assigns a specific time for processing each task and then moves to another. Put simply, the CPU runs those micro tasks in an interleaved order.

The technique of switching between different tasks at once is called concurrency.

But concurrency only creates an illusion of parallel execution.

The performance worsens when the number of tasks increases. Because each task has to wait for its turn, causing an extra delay.

CPU Cores Running Tasks in Parallel
CPU Cores Running Tasks in Parallel

So they added extra CPU cores. And each CPU core could run a task independently.

Think of the CPU core as a processing unit within the CPU; it handles instructions.

The technique of handling many tasks at once is called parallelism. It offers efficiency.

Concurrency Is Not Parallelism

Concurrency is about the design, while parallelism is about the execution model.

Let’s dive in:

1. Concurrency vs Parallelism

Concurrency vs Parallelism
Concurrency vs Parallelism

Imagine concurrency as a chef making doner kebab for 3 customers. He switches between fries, meat, and vegetables.

And consider parallelism as 3 chefs making doner kebab for 3 customers; all done at the same time.1

The CPU-intensive tasks run efficiently with parallelism.

Yet parallelism wastes CPU time when there are I/O heavy tasks.

Also running tasks on different CPUs doesn’t always speed them up. Because coordinating tasks for independent execution is necessary.

Concurrency + Parallelism = High Throughput
Concurrency + Parallelism = High Throughput

So combine concurrency with parallelism to build efficient, scalable, and responsive systems.

Besides simultaneous changes to the same data might corrupt it.

Yet it’s difficult to determine when a thread will get scheduled or which instructions it’ll run.

So it’s necessary to use synchronization techniques, such as locking.

Think of a thread as the smallest processing unit scheduled by the operating system.

Synchronizing CPU Access Using Locks
Synchronizing CPU Access Using Locks

A thread must acquire the lock to do a set of operations. While another thread can use the CPU only after the current thread releases the lock.

The 2 popular synchronization primitives are mutex and semaphore. They’re used to coordinate access to a shared resource.

A mutex allows only 1 thread to access the shared resource at a time. While semaphore limits the number of threads accessing a shared resource at a time.

Mutex vs Semaphore
Mutex vs Semaphore

Imagine the mutex as a single key to enter the building. And think of the semaphore as a bowl of keys to enter a building.

Besides programming languages, such as Go, allow to build concurrent and parallel solutions without explicit locking mechanisms.

Ready for the best part?

2. Use Cases

Here are some use cases of concurrency and parallelism in system design:

Concurrency and Parallelism in System Design
Concurrency and Parallelism in System Design
  • A client fetches data via asynchronous callbacks. While main thread handles user input to keep the UI responsive.

  • A load balancer uses non-blocking I/O or a thread pool to avoid connection queuing.

  • A server uses event-driven or multi-threading models to handle requests. Also many servers could be installed for parallelism.

  • A connection pooler allows clients to share a set of database connections. While queries get executed in parallel across those connections.

A sharded database allows clients to make parallel queries and then merge the responses. Besides the client could access and change data at once using database concurrency techniques.


Concurrency is not parallelism; instead, it’s a way of structuring tasks to enable parallelism. Thus making it easy to scale.

One should break down a problem into smaller, independent tasks for concurrency. Then compose the smaller tasks in parallel to solve the problem efficiently.

Remember, a system in which all tasks run in parallel and stay busy all the time has the maximum throughput.

My Profile

My photo
can be reached at 09916017317