The 100 Terms Every Software Engineer Must Know

32 min read
Software Engineering
The 100 Terms Every Software Engineer Must Know

Software engineering has its own language, and fluency in that language separates engineers who can contribute from engineers who can lead. You can write working code without knowing what "idempotent" means, but the moment you're debugging a payment system at 2 a.m., or reviewing a system design doc, or interviewing for a senior role, precise vocabulary becomes the difference between solving the problem in five minutes and spending an afternoon reinventing wheels that already have names.

This guide walks through 100 terms that show up constantly in real engineering work — not academic trivia, but the vocabulary you'll actually hear in code reviews, architecture meetings, and production incident channels. Each term includes a plain-language explanation, why it matters in practice, and a code snippet or concrete example so the concept sticks rather than just sounding familiar.

We've organized the terms into ten thematic groups so you can either read straight through or jump to the area you need most: computational fundamentals, data structures and algorithms, software design, distributed systems, databases, networking and APIs, DevOps and infrastructure, security, testing and quality, and the newer vocabulary of AI and data engineering that's now unavoidable in modern stacks.

Table of Contents

  1. Computational Fundamentals
  2. Data Structures & Algorithms
  3. Software Design & Architecture
  4. Distributed Systems
  5. Databases & Data Storage
  6. Networking & APIs
  7. DevOps, Cloud & Infrastructure
  8. Security
  9. Testing & Quality
  10. AI, ML & Modern Data Engineering

Computational Fundamentals

These are the bedrock concepts that inform how you think about every piece of code you write, regardless of language or framework.

1. Idempotency

An operation is idempotent if performing it multiple times produces the same result as performing it once. Setting a variable to a fixed value is idempotent; incrementing it is not.[1]

python
# Idempotent
user.status = "active"

# Not idempotent
user.login_count += 1

Idempotency matters most at API boundaries, where network failures force clients to retry requests. If a "charge customer" endpoint isn't idempotent, a dropped response can cause a customer to be billed twice, because the client has no way of knowing whether the original request actually succeeded. The standard fix is an idempotency key: the client generates a unique token per logical operation, and the server stores the result keyed to that token so repeated requests return the cached outcome instead of re-executing the action.[2][1]

2. Determinism

A deterministic function always produces the same output given the same input, with no dependency on external state, randomness, or timing. Pure functions are deterministic by definition. Determinism is why unit tests are reliable — a non-deterministic function (one that reads the system clock, calls random(), or depends on network state) is inherently harder to test and reason about.

3. Mutability vs. Immutability

A mutable object can be changed after creation; an immutable one cannot. Immutability eliminates an entire class of bugs caused by unexpected shared-state modification.

javascript
// Mutable — risky if shared across functions
const config = { retries: 3 };
config.retries = 5; // silently changes shared object

// Immutable pattern
const updatedConfig = { ...config, retries: 5 };

Languages like Rust and functional-first frameworks (Redux, React state) lean heavily on immutability specifically because shared mutable state is one of the most common sources of concurrency bugs.

4. Big-O Notation

Big-O notation describes how an algorithm's running time or memory usage grows as input size increases, abstracting away hardware-specific constants to focus on scalability. An O(n) algorithm scales linearly; an O(n²) algorithm gets dramatically slower as data grows.

python
# O(n) - linear search
def find_linear(arr, target):
    for item in arr:
        if item == target:
            return True
    return False

# O(log n) - binary search on sorted data
def find_binary(arr, target):
    low, high = 0, len(arr) - 1
    while low <= high:
        mid = (low + high) // 2
        if arr[mid] == target:
            return True
        elif arr[mid] < target:
            low = mid + 1
        else:
            high = mid - 1
    return False

The practical lesson: an O(n²) algorithm that's fine on 100 rows can silently become a production incident when a dataset grows to 10 million rows. Complexity analysis is how you predict that failure before it happens.

5. Time Complexity vs. Space Complexity

Time complexity measures how execution time scales with input; space complexity measures how memory usage scales. Engineers frequently trade one for the other — caching results (memoization) increases space usage to reduce time complexity, which is a deliberate, common tradeoff rather than a mistake.

6. Recursion

A function that calls itself to solve smaller instances of the same problem, with a base case that stops the recursion. Recursion is elegant for tree traversal, divide-and-conquer algorithms, and problems with naturally nested structure.

python
def factorial(n):
    if n <= 1:  # base case
        return 1
    return n * factorial(n - 1)  # recursive case

Every recursive call consumes stack memory, so deep recursion without a proper base case causes a stack overflow — a classic bug in code that looks correct but wasn't tested against large inputs.

7. Memoization

A caching technique that stores the results of expensive function calls and returns the cached result when the same inputs occur again, dramatically speeding up recursive or repeated computations.

python
from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

Without memoization, naive recursive Fibonacci is O(2^n). With it, it drops to O(n) because each unique subproblem is computed only once.

8. Pure Functions

A pure function has no side effects and always returns the same output for the same input — it doesn't modify external state, doesn't perform I/O, and doesn't depend on anything outside its own arguments. Pure functions are trivially testable and safely composable, which is why functional programming principles have crept into mainstream backend and frontend code alike.

9. Higher-Order Functions

A function that takes another function as an argument, returns a function, or both. map, filter, and reduce are the classic examples, and understanding them is foundational to modern JavaScript, Python, and functional-style code in any language.

javascript
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);

10. Closures

A closure is a function that retains access to variables from its enclosing scope even after that outer function has finished executing. Closures are the mechanism behind private state in JavaScript modules, memoization implementations, and event handler patterns.

javascript
function createCounter() {
  let count = 0;
  return function () {
    count += 1;
    return count;
  };
}

const counter = createCounter();
counter(); // 1
counter(); // 2

Data Structures & Algorithms

11. Arrays vs. Linked Lists

Arrays store elements in contiguous memory, giving O(1) index access but O(n) insertion in the middle. Linked lists store elements as nodes with pointers to the next node, giving O(1) insertion at known positions but O(n) access by index. Choosing between them is a real architectural decision, not academic trivia — a queue-heavy system benefits from linked structures, while random-access-heavy code benefits from arrays.

12. Hash Maps (Hash Tables)

A hash map stores key-value pairs using a hash function to compute an index into an underlying array, giving average O(1) lookup, insertion, and deletion.

python
user_cache = {}
user_cache["user_123"] = {"name": "Alex", "plan": "pro"}
print(user_cache.get("user_123"))  # O(1) average lookup

Hash collisions — where two different keys hash to the same bucket — degrade performance to O(n) in the worst case, which is why hash function quality and load factor matter for anything performance-critical.

13. Trees and Binary Search Trees

A tree is a hierarchical data structure with a root node and child nodes. A binary search tree (BST) keeps left children smaller and right children larger than their parent, enabling O(log n) search, insertion, and deletion when balanced. File systems, database indexes, and DOM structures are all real-world trees.

14. Graphs

A graph is a set of nodes (vertices) connected by edges, used to model networks, relationships, and dependencies. Graphs can be directed or undirected, weighted or unweighted. Dependency resolution in package managers, route-finding in maps, and social network connections are all graph problems.

15. Stacks and Queues

A stack is Last-In-First-Out (LIFO) — think of the browser's "back" button or the call stack that tracks function execution. A queue is First-In-First-Out (FIFO) — think of a print queue or a task processing pipeline.

python
# Stack
stack = []
stack.append("A")
stack.append("B")
stack.pop()  # returns "B"

# Queue
from collections import deque
queue = deque()
queue.append("A")
queue.append("B")
queue.popleft()  # returns "A"

16. Sorting Algorithms (Quicksort, Mergesort)

Quicksort partitions data around a pivot and recursively sorts each partition, averaging O(n log n) but degrading to O(n²) on already-sorted or adversarial input. Mergesort splits data in half, recursively sorts each half, and merges — reliably O(n log n) at the cost of extra memory. Knowing which sort your language's built-in sort() uses under the hood (often a hybrid like Timsort) matters when performance is on the line.

17. Binary Search

A search algorithm that repeatedly halves a sorted search space, achieving O(log n) time — dramatically faster than linear search for large datasets, but only valid on sorted data.

18. Dynamic Programming

An optimization technique that solves complex problems by breaking them into overlapping subproblems, solving each subproblem once, and storing the result (memoization) or building solutions bottom-up (tabulation). Classic use cases include shortest-path algorithms, string edit distance, and resource allocation problems.

19. Greedy Algorithms

An algorithmic strategy that makes the locally optimal choice at each step, hoping it leads to a globally optimal solution. Greedy algorithms are fast and simple but don't always guarantee the best answer — understanding when greedy fails (and dynamic programming is needed instead) is a real interview and design skill.

20. Amortized Complexity

The average performance of an operation over a sequence of operations, even if individual operations occasionally cost more. A dynamic array's append operation is O(1) amortized even though occasional resizing operations cost O(n), because those expensive resizes happen rarely enough that the average stays constant.


Software Design & Architecture

21. SOLID Principles

Five design principles — Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion — that guide maintainable object-oriented design. Violating Single Responsibility, for instance, produces classes that do too much and become fragile every time requirements shift.

22. Design Patterns

Reusable solutions to commonly occurring problems in software design. The Singleton pattern ensures a class has only one instance; the Factory pattern delegates object creation to a dedicated method; the Observer pattern lets objects subscribe to state changes in another object.

python
class Singleton:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

Design patterns aren't rules to memorize for interviews — they're a shared vocabulary that lets engineers describe a solution in one word ("just use an Observer here") instead of a paragraph.

23. Dependency Injection

A design pattern where an object's dependencies are provided from the outside rather than created internally, making code more testable and loosely coupled.

python
# Without dependency injection
class OrderService:
    def __init__(self):
        self.db = PostgresDatabase()  # tightly coupled

# With dependency injection
class OrderService:
    def __init__(self, db):
        self.db = db  # can inject a mock for testing

24. Coupling and Cohesion

Coupling measures how dependent modules are on each other; cohesion measures how closely related the responsibilities within a single module are. The engineering goal is low coupling, high cohesion — modules that do one thing well and don't require deep knowledge of each other's internals to work together.

25. Monolith vs. Microservices

A monolith is a single deployable application containing all business logic; microservices split functionality into independently deployable services communicating over a network. Microservices offer independent scaling and deployment at the cost of network latency, distributed debugging complexity, and operational overhead — a tradeoff many teams adopt before they actually need it.

26. API Gateway

A single entry point that routes client requests to the appropriate backend microservice, often handling authentication, rate limiting, and request aggregation in one place so individual services don't duplicate that logic.

27. Domain-Driven Design (DDD)

An approach to software design that models code around the business domain, using concepts like Entities, Aggregates, and Bounded Contexts to keep complex business logic organized and aligned with how the business actually thinks about its own operations.

28. Event-Driven Architecture

A design where components communicate by producing and consuming events rather than calling each other directly. A "user signed up" event might trigger a welcome email service, an analytics service, and a CRM sync service — each independently, without the signup code knowing any of them exist.

29. Separation of Concerns

The principle of dividing a program into distinct sections, each addressing a separate concern (data access, business logic, presentation). MVC (Model-View-Controller) is the most famous implementation of this principle in application frameworks.

30. Technical Debt

The implied cost of future rework caused by choosing an easy, short-term solution instead of a better, more thorough approach. Technical debt isn't inherently bad — sometimes shipping fast and refactoring later is the correct business decision — but unmanaged debt compounds until it slows every future feature.

31. Refactoring

Restructuring existing code without changing its external behavior, to improve readability, reduce complexity, or prepare for new features. Reliable refactoring depends on a solid test suite — without tests, refactoring is indistinguishable from rewriting blind.

32. Abstraction

Hiding implementation details behind a simpler interface. When you call sort() on a list, you don't need to know whether it uses quicksort or mergesort internally — that's abstraction doing its job.

33. Polymorphism

The ability of different objects to respond to the same method call in their own way. A Shape base class might define area(), with Circle and Square subclasses each implementing it differently — calling code doesn't need to know which specific shape it's working with.

python
class Shape:
    def area(self):
        raise NotImplementedError

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    def area(self):
        return 3.14159 * self.radius ** 2

class Square(Shape):
    def __init__(self, side):
        self.side = side
    def area(self):
        return self.side ** 2

34. Encapsulation

Bundling data and the methods that operate on it within a single unit, while restricting direct access to internal state from outside that unit — typically via private fields and public getter/setter methods.

35. Inversion of Control (IoC)

A principle where the flow of control is handed to a framework or container rather than the application code itself. Dependency injection is one implementation of IoC; frameworks like Spring and Angular are built around IoC containers that manage object lifecycles for you.


Distributed Systems

36. CAP Theorem

The CAP theorem states that a distributed data store can only guarantee two of three properties simultaneously: Consistency (every read gets the latest write), Availability (every request gets a response), and Partition Tolerance (the system keeps working despite network failures between nodes). Since network partitions are unavoidable in real distributed systems, the practical choice is really between consistency and availability during a partition.[3][4]

During a network partition, you must choose:
CP (Consistency + Partition Tolerance)  system may reject requests to stay consistent
AP (Availability + Partition Tolerance)  system stays responsive but may serve stale data

This is why MongoDB and traditional relational replicas lean CP, while Cassandra and DynamoDB lean AP by default — the choice reflects what kind of failure the system's designers considered more damaging to the business.[5]

37. Eventual Consistency

A consistency model where, given enough time without new updates, all replicas of data will converge to the same value — but at any given moment, different nodes might return different (stale) results. DNS is the classic real-world example: updates propagate gradually rather than instantly everywhere.

38. Strong Consistency

Guarantees that any read receives the most recent write, no matter which node handles the request. Strong consistency simplifies application logic but usually costs latency or availability, especially across geographically distributed systems.

39. Distributed Transactions and the Two-Phase Commit

A protocol for ensuring all nodes in a distributed transaction either commit or roll back together, avoiding partial failures. The coordinator first asks all participants to "prepare" (phase one), and only tells them to commit once everyone confirms readiness (phase two). Two-phase commit guarantees atomicity but blocks if the coordinator crashes mid-transaction, which is why many modern systems prefer the Saga pattern instead.

40. Saga Pattern

An alternative to distributed transactions where a sequence of local transactions each publish an event that triggers the next step, with explicit compensating actions to undo previous steps if something later in the sequence fails. Sagas trade strict atomicity for resilience and scalability in microservice architectures.

41. Message Queues and Pub/Sub

A message queue (like RabbitMQ) delivers each message to exactly one consumer, decoupling producers from consumers and smoothing traffic spikes. A publish/subscribe system (like Kafka) broadcasts each message to every subscriber, enabling one event to fan out to multiple independent downstream systems.

Producer  Queue  [Consumer A] (message removed after processing)

Producer  Topic  [Subscriber A]
                   [Subscriber B]
                   [Subscriber C]

42. Load Balancing

Distributing incoming network traffic across multiple servers to prevent any single server from becoming a bottleneck. Common algorithms include round-robin (rotate evenly), least-connections (send to the least busy server), and consistent hashing (route the same client to the same server whenever possible, useful for caching).

43. Horizontal vs. Vertical Scaling

Vertical scaling adds more resources (CPU, RAM) to an existing machine; horizontal scaling adds more machines and distributes load between them. Horizontal scaling is generally preferred for resilience — a single more powerful machine is still a single point of failure, while a fleet of smaller machines can lose one node without an outage.

44. Consensus Algorithms (Raft, Paxos)

Algorithms that allow a group of distributed nodes to agree on a single value or sequence of operations even in the presence of failures. Raft, designed to be more understandable than Paxos, underpins tools like etcd and Consul, which many distributed systems rely on for leader election and configuration consistency.

45. Sharding

Splitting a large dataset across multiple database instances (shards) based on a key, so no single machine has to store or serve the entire dataset. Sharding enables horizontal database scaling but introduces complexity around cross-shard queries and rebalancing when a shard grows unevenly.

46. Replication

Copying data across multiple nodes to improve availability and read performance. Master-slave (or primary-replica) replication routes writes to one node and reads to many; multi-master replication allows writes to multiple nodes at the cost of more complex conflict resolution.

47. Circuit Breaker Pattern

A resilience pattern that stops sending requests to a failing downstream service after a threshold of failures, giving that service time to recover instead of being hammered by retries during an outage. After a cooldown period, the circuit breaker allows a limited number of test requests through before fully re-opening traffic.

python
class CircuitBreaker:
    def __init__(self, failure_threshold=5):
        self.failure_count = 0
        self.threshold = failure_threshold
        self.is_open = False

    def call(self, func, *args):
        if self.is_open:
            raise Exception("Circuit is open, request blocked")
        try:
            result = func(*args)
            self.failure_count = 0
            return result
        except Exception:
            self.failure_count += 1
            if self.failure_count >= self.threshold:
                self.is_open = True
            raise

48. Rate Limiting

Restricting how many requests a client can make within a time window, protecting infrastructure from abuse or accidental overload. Token bucket and sliding window are the two most common algorithms, with token bucket allowing controlled bursts and sliding window enforcing smoother, stricter limits.

49. Backpressure

A mechanism where a system signals upstream producers to slow down when it can't process data fast enough, preventing memory exhaustion or crashes. Streaming frameworks like Reactive Streams and Kafka consumers implement backpressure explicitly rather than letting queues grow unbounded.

50. Leader Election

The process by which distributed nodes agree on a single coordinator (leader) responsible for making decisions or sequencing operations, typically re-triggered automatically if the current leader fails. ZooKeeper and etcd are commonly used to implement leader election reliably.


Databases & Data Storage

51. ACID Properties

Atomicity, Consistency, Isolation, and Durability — the four guarantees that define reliable database transactions. Atomicity ensures a transaction either fully completes or fully rolls back; Isolation ensures concurrent transactions don't corrupt each other's intermediate state; Durability ensures committed data survives a crash.

52. Normalization and Denormalization

Normalization organizes relational data to eliminate redundancy, typically by splitting data into related tables (following normal forms like 1NF, 2NF, 3NF). Denormalization deliberately reintroduces redundancy to optimize read performance, trading some storage efficiency and update complexity for faster queries — a common choice in analytics and read-heavy systems.

53. Indexes

A data structure (usually a B-tree or hash index) that speeds up data retrieval by avoiding a full table scan, at the cost of extra storage and slower writes since the index must update alongside the data.

sql
CREATE INDEX idx_users_email ON users(email);

-- This query now uses the index instead of scanning every row
SELECT * FROM users WHERE email = '[email protected]';

Over-indexing is a real anti-pattern: every additional index slows down inserts and updates, so indexes should target genuinely slow, frequently-run queries rather than being added defensively everywhere.

54. SQL vs. NoSQL

SQL databases (PostgreSQL, MySQL) enforce a fixed schema and relational structure, favoring strong consistency and complex joins. NoSQL databases (MongoDB, DynamoDB, Cassandra) trade schema rigidity for flexibility and horizontal scalability, generally favoring availability over strict consistency. Neither is universally "better" — the decision depends on whether your data is naturally relational and whether you need strict transactional guarantees or massive horizontal scale.

55. Database Transactions and Isolation Levels

A transaction groups multiple operations into a single atomic unit. Isolation levels (Read Uncommitted, Read Committed, Repeatable Read, Serializable) control how much concurrent transactions can see of each other's uncommitted changes — stricter isolation prevents anomalies like dirty reads and phantom reads but reduces concurrency throughput.

56. Deadlocks

A situation where two or more transactions each hold a lock the other needs, and neither can proceed. Databases detect deadlocks and abort one of the transactions to break the cycle, which is why application code must handle transaction retries gracefully rather than assuming every transaction succeeds on the first attempt.

57. Connection Pooling

Reusing a fixed set of database connections across requests instead of opening and closing a new connection for every query, since establishing a database connection is relatively expensive. Connection pool exhaustion — every connection busy and new requests queuing — is one of the most common causes of mysterious application slowdowns under load.

58. Caching (Cache Invalidation)

Storing frequently accessed data in a fast-access layer (often in-memory, like Redis) to avoid repeatedly querying a slower source. The hard part is cache invalidation — deciding when cached data becomes stale and must be refreshed. Phil Karlton's famous quip, "there are only two hard things in computer science: cache invalidation and naming things," reflects how genuinely tricky this problem is in practice.

python
def get_user(user_id):
    cached = redis_client.get(f"user:{user_id}")
    if cached:
        return json.loads(cached)
    user = db.query_user(user_id)
    redis_client.set(f"user:{user_id}", json.dumps(user), ex=300)  # 5-min TTL
    return user

59. Data Warehousing (Star Schema)

A data warehouse organizes data specifically for analytics rather than transactional workloads, often using a star schema with a central fact table (recording events, like sales) surrounded by dimension tables (describing attributes, like customer or product details). This structure makes aggregate queries across large historical datasets fast and intuitive.

60. OLTP vs. OLAP

Online Transaction Processing (OLTP) systems handle many small, fast read/write operations — think of a checkout system processing individual orders. Online Analytical Processing (OLAP) systems handle complex queries across large datasets for reporting and analysis. The two workloads have opposite performance profiles, which is why production databases and analytics warehouses are usually kept physically separate.


Networking & APIs

61. REST (Representational State Transfer)

An architectural style for APIs built around stateless requests to resource-based URLs, using standard HTTP methods (GET, POST, PUT, DELETE) to represent operations. RESTful design treats "users" and "orders" as resources with predictable, consistent URL patterns rather than exposing arbitrary remote procedure calls.

GET    /users/123         fetch a user
POST   /users              create a user
PUT    /users/123         replace a user
PATCH  /users/123         partially update a user
DELETE /users/123         delete a user

62. GraphQL

A query language for APIs that lets clients specify exactly which fields they need in a single request, avoiding the over-fetching or under-fetching problems common with rigid REST endpoints. A single GraphQL query can fetch a user, their orders, and each order's line items in one round trip, where REST might require three separate calls.

63. gRPC

A high-performance remote procedure call framework built on HTTP/2 and Protocol Buffers, commonly used for service-to-service communication inside a microservices architecture where speed and strict typed contracts matter more than human-readable payloads.

64. Webhooks

A way for one system to notify another about an event by sending an HTTP request to a pre-registered URL when that event occurs, rather than forcing the receiving system to repeatedly poll for updates. Payment providers use webhooks extensively to notify merchant systems when a transaction completes.

65. Idempotent HTTP Methods

GET, PUT, and DELETE are defined as idempotent by the HTTP specification — calling them repeatedly with the same input should have the same effect as calling them once. POST is not idempotent by default, which is exactly why idempotency keys (see term 1) matter most for POST-based payment and order-creation endpoints.

66. Status Codes (2xx, 4xx, 5xx)

HTTP status codes communicate the outcome of a request: 2xx means success, 3xx means redirection, 4xx means a client-side error (bad request, unauthorized, not found), and 5xx means a server-side error. Correctly distinguishing 4xx from 5xx in your own API responses matters enormously for monitoring — a spike in 5xx errors signals your system is broken, while a spike in 4xx often signals client misuse or a documentation gap.

67. DNS (Domain Name System)

The system that translates human-readable domain names into IP addresses. When you type a URL, your browser queries DNS resolvers, which check cached records or walk up a hierarchy of authoritative name servers until they find the IP address to actually connect to.

68. TCP/IP and the Three-Way Handshake

TCP (Transmission Control Protocol) establishes a reliable connection between client and server using a three-way handshake — SYN, SYN-ACK, ACK — before any application data is exchanged. This handshake guarantees both sides are ready to communicate and agree on initial sequence numbers, forming the reliability foundation underneath HTTP.

69. TLS/SSL and HTTPS

Transport Layer Security encrypts data in transit between client and server, preventing eavesdropping and tampering. HTTPS is simply HTTP layered on top of TLS. The TLS handshake uses asymmetric cryptography to securely exchange a symmetric session key, which is then used to encrypt the actual data because symmetric encryption is far faster for bulk data transfer.

70. CDN (Content Delivery Network)

A geographically distributed network of servers that cache and serve content from a location physically closer to the end user, reducing latency and offloading traffic from the origin server. Static assets — images, CSS, JavaScript bundles — are the classic CDN use case, but modern CDNs also cache dynamic API responses at the edge.

71. WebSockets

A protocol that establishes a persistent, full-duplex connection between client and server, allowing both sides to push data at any time without the overhead of repeated HTTP requests. WebSockets power real-time features like live chat, collaborative editing, and live dashboards.

72. API Versioning

The practice of maintaining multiple concurrent versions of an API so existing clients don't break when the API evolves. Common strategies include URL versioning (/v1/users), header-based versioning, and content negotiation — each with different tradeoffs around discoverability and cache-friendliness.

73. Rate Limiting Headers and Pagination

Well-designed APIs communicate rate limit status via response headers (X-RateLimit-Remaining) and paginate large result sets using cursor-based or offset-based pagination rather than returning unbounded lists that could crash a client or overload the server on a single request.


DevOps, Cloud & Infrastructure

74. CI/CD (Continuous Integration / Continuous Deployment)

Continuous Integration automatically builds and tests code every time it's pushed, catching integration bugs early instead of discovering them at release time. Continuous Deployment extends this by automatically releasing every change that passes the pipeline to production, without manual intervention.

yaml
# Simplified GitHub Actions workflow
name: CI
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm install
      - run: npm test
      - run: npm run build

75. Containers and Docker

A container packages an application together with everything it needs to run — libraries, dependencies, runtime — into a single portable unit that behaves consistently across development, staging, and production environments. Unlike a virtual machine, a container shares the host operating system's kernel, using Linux namespaces and cgroups to isolate processes, which makes containers dramatically lighter-weight and faster to start than full VMs.

76. Kubernetes

An orchestration platform that automates deploying, scaling, and managing containerized applications across a cluster of machines. Core Kubernetes objects include Pods (the smallest deployable unit, usually one container), Deployments (which manage a set of replica pods and handle rolling updates), and Services (which provide a stable network endpoint for a set of pods that come and go).

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-server
  template:
    metadata:
      labels:
        app: api-server
    spec:
      containers:
        - name: api-server
          image: myregistry/api-server:1.4.2
          ports:
            - containerPort: 8080

77. Infrastructure as Code (IaC)

Managing and provisioning infrastructure through machine-readable configuration files rather than manual setup, making infrastructure changes version-controlled, repeatable, and reviewable through the same processes as application code. Terraform is the most widely adopted tool in this space, allowing engineers to declare desired infrastructure state and let the tool figure out what changes to apply.

hcl
resource "aws_instance" "web_server" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.micro"
  tags = {
    Name = "web-server-prod"
  }
}

78. Immutable Infrastructure

An approach where servers are never modified after deployment — instead, any change requires building and deploying a brand new instance from an updated image, then destroying the old one. This eliminates configuration drift (where servers slowly diverge from each other due to manual patches) and makes rollbacks as simple as redeploying the previous image.

79. Blue-Green Deployment

A release strategy that maintains two identical production environments ("blue" and "green"), with live traffic pointed at one while the other receives the new release. Once the new version passes validation, traffic is switched over instantly, and the old environment stays on standby for immediate rollback if something goes wrong.

80. Canary Deployment

A release strategy that rolls out a new version to a small subset of users or servers first, monitors for errors, and gradually increases traffic to the new version if metrics look healthy — limiting the blast radius of a bad release compared to deploying to 100% of traffic at once.

81. Observability: Logs, Metrics, and Traces

Observability is the ability to understand a system's internal state from its external outputs, built on three pillars. Logs record discrete events with contextual detail. Metrics are numeric measurements aggregated over time (request count, latency percentiles, error rate). Traces follow a single request's journey across multiple services, showing exactly where time was spent in a distributed call chain.

82. SLA, SLO, and SLI

A Service Level Indicator (SLI) is a measured metric, like 99.95% of requests succeeding. A Service Level Objective (SLO) is the internal target for that metric, like "99.9% success rate over 30 days." A Service Level Agreement (SLA) is the external, often contractual, commitment made to customers — usually looser than the internal SLO to leave engineering margin for error.

83. Error Budget

The acceptable amount of unreliability a system is allowed before its SLO is breached, calculated as 100% minus the SLO target. If your SLO is 99.9% uptime, your error budget is 0.1% of time — roughly 43 minutes per month — and teams can spend that budget deliberately on risky releases or experiments rather than treating every minor outage as a crisis.

84. FinOps (Cloud Cost Optimization)

The discipline of managing cloud spend collaboratively across engineering, finance, and operations teams, treating cost as a first-class engineering metric alongside performance and reliability. Common FinOps practices include rightsizing over-provisioned instances, using reserved or spot instances for predictable or interruptible workloads, and tagging resources so spend can be attributed to specific teams or features.

85. Auto-Scaling

Automatically adjusting the number of running instances of an application based on real-time demand, scaling out during traffic spikes and scaling in during quiet periods to control cost without sacrificing performance during peak load.


Security

86. Public Key Cryptography

An encryption scheme using a mathematically linked key pair — a public key that can be shared openly and a private key that must stay secret. Data encrypted with the public key can only be decrypted with the corresponding private key, which is the mechanism underlying HTTPS, SSH, and digital signatures.

87. OAuth 2.0

An authorization framework that lets a user grant a third-party application limited access to their resources on another service, without sharing their password. When you click "Sign in with Google," you're initiating an OAuth 2.0 authorization code flow — the application receives a scoped access token rather than your actual Google credentials.

88. JWT (JSON Web Tokens)

A compact, self-contained token format used to represent claims (like user identity) between two parties, cryptographically signed so the receiving party can verify it hasn't been tampered with. A JWT has three base64-encoded parts — header, payload, and signature — and is commonly used for stateless authentication in APIs.

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIxMjMifQ.4f1g8k...
    header (algorithm)    payload (claims)       signature

89. SQL Injection

An attack where malicious input is inserted into a database query, exploiting improperly sanitized user input to execute unintended commands. Parameterized queries (prepared statements) are the standard defense — they treat user input strictly as data, never as executable SQL syntax.

python
# Vulnerable
query = f"SELECT * FROM users WHERE email = '{user_input}'"

# Safe  parameterized
cursor.execute("SELECT * FROM users WHERE email = %s", (user_input,))

90. Cross-Site Scripting (XSS)

An attack where malicious scripts are injected into web pages viewed by other users, typically because user-generated content is rendered without proper escaping. Output encoding and Content Security Policy headers are the primary defenses.

91. Cross-Site Request Forgery (CSRF)

An attack that tricks an authenticated user's browser into submitting an unwanted request to a site where they're already logged in, exploiting the browser's automatic inclusion of cookies. CSRF tokens — unique, unpredictable values embedded in forms and validated server-side — prevent forged requests from third-party sites.

92. Zero Trust Architecture

A security model built on the principle "never trust, always verify" — no user or device is trusted by default, regardless of whether they're inside or outside the traditional network perimeter. Every request is authenticated and authorized individually, using continuous verification and least-privilege access rather than assuming anything inside the corporate firewall is automatically safe.[6]

93. Principle of Least Privilege

Granting users and systems only the minimum permissions necessary to perform their function, so a compromised account or service has the smallest possible blast radius. Overly broad IAM roles in cloud environments are one of the most common real-world security misconfigurations.

94. Encryption at Rest vs. In Transit

Encryption at rest protects stored data (on disk, in a database) from unauthorized access if the storage medium itself is compromised. Encryption in transit (TLS) protects data as it moves across a network from interception. A genuinely secure system needs both — encrypting one without the other leaves an obvious gap.

95. Threat Modeling (STRIDE)

A structured process for identifying potential security threats to a system before it's built or deployed. STRIDE is a common framework categorizing threats as Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, and Elevation of privilege — walking through each category against your system's components surfaces risks that ad hoc review often misses.


Testing & Quality

96. Unit, Integration, and End-to-End Testing

Unit tests verify a single function or component in isolation, typically mocking external dependencies. Integration tests verify that multiple components work correctly together, such as an API endpoint talking to a real database. End-to-end tests simulate a full user journey through the entire system, from UI interaction to backend response. The testing pyramid principle recommends having many fast unit tests, fewer integration tests, and the fewest (slowest, most brittle) end-to-end tests.

python
# Unit test example (pytest)
def test_calculate_discount():
    assert calculate_discount(price=100, percent=10) == 90

97. Test-Driven Development (TDD)

A development practice where you write a failing test before writing the implementation code, then write just enough code to make the test pass, then refactor — the "red, green, refactor" cycle. TDD forces you to think about a function's interface and expected behavior before getting lost in implementation details.

98. Mocking and Stubbing

Mocking replaces a real dependency (a database, an external API) with a fake version that records how it was called and lets you assert on that interaction. Stubbing replaces a dependency with one that returns predetermined, hardcoded responses. Both let you test code in isolation without relying on slow, flaky, or unavailable external systems.

python
from unittest.mock import Mock

payment_gateway = Mock()
payment_gateway.charge.return_value = {"status": "success"}

result = process_order(payment_gateway, amount=50)
payment_gateway.charge.assert_called_once_with(50)

99. Code Coverage

A metric measuring what percentage of your codebase is executed by your test suite. High coverage doesn't guarantee correctness — a test can execute a line without meaningfully asserting anything about its behavior — but persistently low coverage in critical paths is a reliable early warning sign of fragile, under-tested code.

100. A/B Testing

A controlled experiment that shows two variants of a feature to different user segments and measures which performs better against a defined metric, like conversion rate. Rigorous A/B testing requires calculating adequate sample size in advance and correctly interpreting statistical significance — stopping a test early because the numbers "look good" is one of the most common ways teams fool themselves with bad experimental design.


Bringing It All Together

Vocabulary alone doesn't make you a better engineer, but shared vocabulary is what makes collaboration fast. When a teammate says "let's just put a circuit breaker around that call" or "this needs to be idempotent before we retry," precise terms compress an entire design conversation into a sentence. That compression is exactly what senior engineers rely on daily — not because they're showing off, but because it lets a team reason about tradeoffs quickly instead of re-deriving first principles in every meeting.

The 100 terms above aren't exhaustive, and no single engineer uses all of them in daily work — a frontend specialist leans harder on rendering and accessibility vocabulary, while a platform engineer lives inside Kubernetes and observability terms. What matters is recognizing the shape of a problem quickly enough to know which corner of this vocabulary to reach for, and having the underlying concept solid enough that you can explain it to someone else, not just recite its definition.

Sources

  1. Idempotency, a key term in distributed systems | Software Engineering Dictionary{:target="_blank"}
  2. What is Idempotency? A guide to API reliability
  3. CAP theorem - Wikipedia
  4. CAP Theorem Simplified
  5. The CAP Theorem EXPLAINED (Why Your Data Architecture Must Choose Carefully)
  6. High-Demand Tech Skills in the UK in 2026
  7. CAP Theorem Explained: Distributed Systems Series
  8. Vector Embeddings Explained: From Basics to Production - Tetrate
  9. Understanding Idempotency: A Guide to Reliable System Design
  10. Vector Embeddings Explained in 20 Mins
  11. Vector Embeddings Explained Simply (With an Easy Example)
  12. What is Idempotence? Explained with Real-World Examples
  13. The CAP Theorem in DBMS - GeeksforGeeks
  14. How Vector Embeddings Work (with 3D Visualization) | AI for Beginners
  15. What Is Idempotence?
  16. CAP Theorem - Consistency, Availability and Partition Tolerance - System Design

STAY CONNECTED WITH THE EXPAT COMMUNITY

Subscribe to get expat tips, local insights, and connect with professionals around the world.