beginner 24 min read

Glossary of software development terms

This is a plain-language reference for the key terms used across the Intro to Software Development path. Definitions are short on purpose; each links to the lesson that explains the idea in full. Terms are grouped by theme and roughly ordered from foundational to advanced within each group, following the shape of the path itself.

Want the long version? Many of these terms — every programming language and core concept here — have a full, in-depth article in the GopherTrunk Field Guide, and the first mention of a covered term on any page links straight to it.

History and hardware

Hardware — The physical parts of a computer you can touch: chips, memory, drives, screens. Software is the instructions that run on it. See What is software?

Software — Instructions that tell hardware what to do. Unlike hardware, it can be changed without rebuilding the machine. See What is software?

Stored-program computer — A design where a program is held in the same memory as the data it works on, so the machine can be reprogrammed instead of rewired. This idea underpins essentially every modern computer. See What is software?

Firmware — Low-level software baked into a device that controls its hardware directly, sitting between pure hardware and ordinary programs. See What is software?

Operating system (OS) — The software that manages a computer’s hardware and resources and gives other programs a consistent way to run. See What is software?

Vacuum tube — An early electronic switch used in the first electronic computers; large, hot, and unreliable compared with what replaced it. See The story of computing hardware

Punch card — A stiff card with holes punched in it, used to feed programs and data into early computers. See The story of computing hardware

ENIAC — One of the first general-purpose electronic computers (1940s), built from thousands of vacuum tubes. See The story of computing hardware

Transistor — A tiny electronic switch that replaced the vacuum tube, making computers far smaller, faster, and more reliable. See The story of computing hardware

Integrated circuit — Many transistors fabricated together on a single chip, the building block of modern electronics. See The story of computing hardware

Microprocessor — A complete processing unit on a single chip; the “brain” that runs a computer’s instructions. See The story of computing hardware

Moore’s Law — The observation that the number of transistors on a chip roughly doubles every couple of years, driving decades of rapid improvement in computing. See The story of computing hardware

Mainframe — A large, powerful central computer shared by many users, common in early business and institutional computing. See From the internet to the edge

Client-server — A model where client programs request services from a central server that holds shared data or logic. See From the internet to the edge

Cloud — Computing power and storage provided over the internet on demand, instead of from machines you own and run yourself. See From the internet to the edge

Edge computing — Running computation close to where data is produced (devices, sensors, local servers) rather than in a distant data centre, to reduce latency. See From the internet to the edge

Open source — Software whose source code is published so anyone can read, use, and contribute to it, usually under a licence that permits this. See From the internet to the edge

Languages and paradigms

Machine code — The raw numeric instructions a processor executes directly. Everything else eventually becomes machine code. See The birth of languages

Assembly — A human-readable shorthand for machine code, with one line roughly per processor instruction. See The birth of languages

High-level language — A language written in terms closer to human ideas than to the hardware, then translated down to machine code. See The birth of languages

Compiler — A program that translates source code into another form, typically machine code or bytecode, before it runs. See The birth of languages

Paradigm — A broad style of organising programs and thinking about problems, such as object-oriented or functional. See Language families

Imperative — A style where you write step-by-step instructions that change the program’s state. See Language families

Procedural — An imperative style organised around procedures or functions that you call to do work. See Language families

Object-oriented — A style that bundles data and the behaviour that acts on it into objects. See Language families

Functional — A style that builds programs from functions and favours immutable data and avoiding side effects. See Language families

Declarative — A style where you describe what you want rather than the steps to compute it, as in a database query. See Language families

Multi-paradigm — A language that supports more than one paradigm, letting you mix styles as it suits the problem. See Language families

How code runs

Compiled language — A language whose programs are translated to machine code ahead of time, then run directly by the processor. See Compiled vs interpreted

Interpreted language — A language whose programs are read and executed on the fly by an interpreter, with no separate build step. See Compiled vs interpreted

Bytecode — A compact, portable intermediate form between source code and machine code, run by a virtual machine. See Compiled vs interpreted

Virtual machine — A software layer that executes bytecode, letting the same program run on different hardware. See Compiled vs interpreted

JIT (just-in-time compilation) — Compiling code to machine code while the program runs, combining the portability of bytecode with much of the speed of compiled code. See Compiled vs interpreted

Ahead-of-time (AOT) compilation — Compiling a program fully before it runs, so no compilation happens at run time. See Compiled vs interpreted

Managed language — A language that runs on a runtime which handles services like memory management and safety for you, rather than leaving them to the programmer. See A tour of the languages

Types and memory

Static typing — Types are checked before the program runs, catching many mistakes at compile time. See Type systems

Dynamic typing — Types are checked while the program runs, giving flexibility at the cost of later error detection. See Type systems

Strong vs weak typing — How strictly a language stops you from mixing incompatible types; strong typing resists silent conversions, weak typing allows more of them. See Type systems

Type inference — When the language works out a value’s type for you, so you do not have to write it explicitly. See Type systems

Type safety — The guarantee that operations only run on compatible types, preventing whole classes of bugs. See Type systems

Gradual typing — Mixing static and dynamic typing in one program, adding type checks where they help and leaving them out elsewhere. See Type systems

Stack — A region of memory used for short-lived data like function calls and local variables, managed automatically in last-in first-out order. See Memory management

Heap — A region of memory for data whose size or lifetime is not known in advance, allocated and freed more flexibly than the stack. See Memory management

Pointer — A value that holds the memory address of something else, letting code refer to data indirectly. See Memory management

Manual memory management — When the programmer explicitly allocates and frees memory, with full control but more room for error. See Memory management

Garbage collection — Automatic reclaiming of memory the program no longer uses, so the programmer does not free it by hand. See Memory management

Memory leak — Memory that is allocated but never released, slowly consuming resources until the program slows or crashes. See Memory management

Ownership — A model where each piece of data has a clear owner responsible for its lifetime, used to manage memory safely without a garbage collector. See Memory management

Borrow checker — A compiler feature (notably in Rust) that enforces ownership and borrowing rules to prevent memory errors before the program runs. See Memory management

Concurrency

Concurrency — Structuring a program so several tasks make progress in overlapping time periods, whether or not they truly run at the same instant. See Concurrency models

Parallelism — Actually running multiple tasks at the same time, typically on multiple processor cores. See Concurrency models

Thread — An independent path of execution within a program; multiple threads can run concurrently and share memory. See Concurrency models

Async/await — Language syntax for writing concurrent code that waits for slow operations without blocking, in a style that reads like ordinary sequential code. See Concurrency models

Goroutine — A lightweight, cheap unit of concurrent execution in Go, many of which can run at once. See Concurrency models

Channel — A typed conduit for passing values safely between concurrent tasks, coordinating them by communication rather than shared memory. See Concurrency models

Actor model — A concurrency approach where independent actors hold private state and interact only by sending messages. See Concurrency models

Race condition — A bug where the result depends on the unpredictable timing of concurrent tasks accessing shared data. See Concurrency models

Deadlock — A standstill where tasks each wait for a resource another holds, so none can ever proceed. See Concurrency models

Security

Memory safety — A property that prevents bugs like accessing memory you should not, which are a major source of security vulnerabilities. See Language security

Undefined behaviour — Code whose result the language does not define, which may work by luck but can fail unpredictably or open security holes. See Language security

Buffer overflow — Writing past the end of a block of memory, corrupting nearby data and a classic route to security exploits. See Language security

Dependency — External code your program relies on, pulled in so you do not have to write it yourself. See Language security

Supply chain — The full set of tools, libraries, and dependencies that go into building your software, each of which can introduce risk. See Language security

CVE (Common Vulnerabilities and Exposures) — A publicly catalogued, uniquely identified security flaw in a piece of software. See Language security

Sandboxing — Running code in a restricted environment so it cannot harm the rest of the system even if it misbehaves. See Language security

Principles of good code

Readability — How easily a human can understand code; the primary thing clean code optimises for, since code is read far more than written. See Writing readable code

Naming — Choosing clear, intention-revealing names for variables, functions, and types so code explains itself. See Writing readable code

Code smell — A surface sign that something may be wrong with the design, hinting at a deeper problem worth a closer look. See Writing readable code

DRY (Don’t Repeat Yourself) — Avoid duplicating knowledge; keep each piece of logic in one place so changes happen once. See DRY, KISS, and YAGNI

KISS (Keep It Simple, Stupid) — Prefer the simplest solution that works; complexity should be earned, not added by default. See DRY, KISS, and YAGNI

YAGNI (You Aren’t Gonna Need It) — Don’t build features or flexibility on speculation; add them when a real need appears. See DRY, KISS, and YAGNI

Separation of concerns — Splitting a system so each part handles one distinct responsibility, keeping concerns from tangling together. See DRY, KISS, and YAGNI

SOLID — A set of five object-oriented design principles that together encourage flexible, maintainable code. See SOLID

Single responsibility — The idea that a unit of code should have one reason to change, that is, one clear job. See SOLID

Open/closed — Code should be open to extension but closed to modification, so you add behaviour without rewriting what works. See SOLID

Liskov substitution — A subtype should be usable anywhere its base type is expected, without breaking the program. See SOLID

Interface segregation — Prefer several small, focused interfaces over one large one, so users depend only on what they need. See SOLID

Dependency inversion — Depend on abstractions rather than concrete details, so high-level code is not tied to low-level specifics. See SOLID

Dependency injection — Supplying a component’s dependencies from outside rather than having it create them, making code easier to test and swap. See SOLID

Abstraction — Hiding details behind a simpler interface so you can use something without knowing how it works inside. See Abstraction and coupling

Encapsulation — Bundling data with the code that uses it and hiding the internals, so outside code interacts only through a defined surface. See Abstraction and coupling

Interface — The agreed surface through which one piece of code talks to another, independent of the implementation behind it. See Abstraction and coupling

Coupling — How dependent two parts of a system are on each other; loose coupling makes change safer and easier. See Abstraction and coupling

Cohesion — How well the parts of a single unit belong together; high cohesion means a component does one thing well. See Abstraction and coupling

Leaky abstraction — An abstraction that forces you to understand the details it was meant to hide. See Abstraction and coupling

Robustness and errors

Error handling — How a program detects, reports, and recovers from things going wrong. See Robustness and errors

Exception — A signal that an error occurred, which interrupts normal flow so it can be caught and handled elsewhere. See Robustness and errors

Edge case — An unusual or extreme input or situation at the boundary of what code expects, where bugs often hide. See Robustness and errors

Defensive programming — Writing code that anticipates bad input and misuse, checking assumptions rather than trusting them. See Robustness and errors

Fail fast — Detecting problems and stopping immediately, rather than continuing in a broken state that is harder to diagnose. See Robustness and errors

Graceful degradation — Continuing to provide reduced but useful service when part of a system fails, instead of collapsing entirely. See Robustness and errors

Idempotency — A property where doing an operation more than once has the same effect as doing it once, which makes retries safe. See Robustness and errors

Design patterns

Design pattern — A reusable, named solution to a problem that recurs in software design. See What are design patterns?

Anti-pattern — A common response to a problem that looks helpful but causes more harm than good. See What are design patterns?

Gang of Four — The four authors of the influential 1994 book that catalogued the classic object-oriented design patterns. See What are design patterns?

Boilerplate — Repetitive setup code you must write that carries little unique meaning of its own. See What are design patterns?

Factory — A creational pattern that creates objects through a dedicated method, hiding which concrete type is built. See Creational patterns

Builder — A creational pattern that constructs a complex object step by step, separating how it is built from what it becomes. See Creational patterns

Singleton — A creational pattern that ensures a class has only one instance and provides a single point of access to it. See Creational patterns

Adapter — A structural pattern that wraps one interface so it looks like another, letting incompatible parts work together. See Structural patterns

Facade — A structural pattern that puts a simple front over a complex subsystem, giving callers an easier way in. See Structural patterns

Decorator — A structural pattern that adds behaviour to an object by wrapping it, without changing the original. See Structural patterns

Observer — A behavioural pattern where objects subscribe to another object and are notified automatically when it changes. See Behavioural patterns

Strategy — A behavioural pattern that lets you swap interchangeable algorithms behind a common interface at run time. See Behavioural patterns

State pattern — A behavioural pattern where an object changes its behaviour as its internal state changes, as if changing class. See Behavioural patterns

Publish/subscribe — A messaging pattern where publishers send events without knowing who, if anyone, is listening, and subscribers receive the events they care about. See Behavioural patterns

Concurrency and architecture patterns

Pipeline — A design where data flows through a series of stages, each doing one step of the processing. See Concurrency and pipelines

Producer/consumer — A pattern where producers create work items and consumers process them, usually buffered by a queue between them. See Concurrency and pipelines

Backpressure — A mechanism that lets a slow consumer signal a fast producer to slow down, preventing work from piling up uncontrollably. See Concurrency and pipelines

Message queue — A buffer that holds messages between parts of a system so senders and receivers do not have to act at the same moment. See Concurrency and pipelines

Layered architecture — Organising a system into stacked layers (such as presentation, logic, data) where each layer talks mainly to the one below. See Architectural patterns

Event-driven — An architecture where components react to events as they happen rather than being called in a fixed sequence. See Architectural patterns

Plugin architecture — A design where a core program can be extended by add-on modules without changing the core itself. See Architectural patterns

MVC (Model-View-Controller) — A pattern that separates data (model), presentation (view), and input handling (controller) so each can change independently. See Architectural patterns

Monolith — An application built and deployed as a single unit, with all its parts in one codebase. See Architectural patterns

Microservices — An architecture that splits an application into small, independently deployable services that communicate over a network. See Architectural patterns

Process, methodology and delivery

SDLC (software development life cycle) — The overall sequence of stages a project moves through, from idea and requirements to delivery and maintenance. See The SDLC and methodologies

Waterfall — A sequential approach where each phase is completed before the next begins, with little going back. See The SDLC and methodologies

Agile — A flexible approach that delivers software in small increments and adapts to change instead of following a fixed plan. See The SDLC and methodologies

Scrum — A popular Agile framework that organises work into fixed-length sprints with defined roles and ceremonies. See The SDLC and methodologies

Kanban — An Agile method that visualises work on a board and limits how much is in progress at once to keep flow steady. See The SDLC and methodologies

Sprint — A short, fixed time box (often one to four weeks) in which a Scrum team completes a planned chunk of work. See The SDLC and methodologies

MVP (minimum viable product) — The smallest version of a product that delivers real value and can be learned from. See The SDLC and methodologies

Version control — A system that records changes to code over time, letting you review history, recover old states, and collaborate safely. See Version control and collaboration

Repository — The store of a project’s files together with their full change history under version control. See Version control and collaboration

Commit — A saved snapshot of changes in version control, with a message describing what changed and why. See Version control and collaboration

Branch — A separate line of development where you can work without affecting the main version until you are ready. See Version control and collaboration

Merge — Combining the changes from one branch into another. See Version control and collaboration

Pull request — A proposal to merge your changes, opened so others can review and discuss them first. See Version control and collaboration

Code review — Having another developer read proposed changes to catch problems and share knowledge before they merge. See Version control and collaboration

Testing

Unit test — An automated test that checks one small piece of code in isolation. See Testing

Integration test — A test that checks that several parts work correctly together. See Testing

End-to-end test — A test that exercises the whole system the way a real user would, from start to finish. See Testing

Regression test — A test that guards against a previously fixed bug coming back. See Testing

TDD (test-driven development) — A practice of writing a failing test first, then writing just enough code to make it pass. See Testing

Mock — A stand-in for a real dependency in a test, used to isolate the code under test and control its surroundings. See Testing

Code coverage — A measure of how much of your code your tests actually exercise. See Testing

Golden file — A saved reference output that a test compares against to catch unintended changes. See Testing

Build and delivery

Build system — Tooling that turns source code into a runnable program, handling compilation and assembly steps. See Builds and CI/CD

Dependency management — Declaring, fetching, and tracking the external libraries a project relies on, including their versions. See Builds and CI/CD

Continuous integration (CI) — Automatically building and testing every change as it is merged, so problems surface early. See Builds and CI/CD

Continuous delivery (CD) — Automating the steps to release software so a tested change can be shipped quickly and reliably. See Builds and CI/CD

Artifact — A built output of the process, such as a binary or package, that can be stored and deployed. See Builds and CI/CD

Cross-compilation — Building a program on one type of machine to run on a different type, such as compiling on a laptop for a small device. See Builds and CI/CD

Documentation and maintenance

Documentation — Written explanation of how software works and how to use it, for users and future maintainers. See Documentation and maintenance

Refactoring — Improving the internal structure of code without changing what it does, to keep it clean as it grows. See Documentation and maintenance

Technical debt — The future cost of taking shortcuts now; like financial debt, it accrues interest until you pay it down. See Documentation and maintenance

Deprecation — Marking a feature as outdated and discouraged, signalling it will be removed so users can move off it. See Documentation and maintenance

Bus factor — The number of people who would have to be lost before a project stalls; a bus factor of one is a warning sign. See Documentation and maintenance

Choosing a language

Lock-in — Becoming so tied to a particular technology that moving away from it is costly or impractical. See Why language choice matters

Switching cost — The effort, time, and risk involved in moving from one technology to another. See Why language choice matters

Ecosystem — The libraries, tools, and community around a language that make it more or less productive in practice. See Why language choice matters

Requirements — What a system must actually do and the conditions it must meet, gathered before deciding how to build it. See Starting from requirements

Constraint — A fixed limit the solution must respect, such as a deadline, budget, platform, or performance target. See Starting from requirements

Real-time — A requirement that a system respond within strict, guaranteed time limits, where being late is itself a failure. See Starting from requirements

Performance — How fast and efficiently a program runs with the resources it has. See Performance vs productivity

Productivity — How quickly and easily developers can build and change software, often traded off against raw performance. See Performance vs productivity

Premature optimization — Tuning for speed before you know it matters, adding complexity that often is not needed. See Performance vs productivity

Native library — Precompiled code, often written in a lower-level language, that a program calls for speed or to reach system features. See Performance vs productivity

Domain — The particular problem area or field a piece of software serves, which shapes what tools fit best. See Choosing a language for the domain

Systems programming — Writing low-level software like operating systems, drivers, and runtimes, where control and performance matter most. See Choosing a language for the domain

Embedded — Software that runs on small, resource-limited devices dedicated to a specific job rather than general computing. See Choosing a language for the domain

Scripting — Writing short, often interpreted programs to automate tasks or glue other tools together. See Choosing a language for the domain

Decision framework — A structured way to weigh options against your needs so a choice is reasoned rather than arbitrary. See A decision framework

Prototype — A quick, throwaway or rough build made to test an idea or reduce uncertainty before committing to it. See A decision framework

Trade-off — A choice where gaining one quality means giving up another, such as speed versus simplicity. See A decision framework

Going solo and shipping

Solo developer — Someone who builds and maintains software largely on their own, wearing every role at once. See The solo developer mindset

Tech stack — The combined set of languages, frameworks, and tools chosen to build a project. See Choosing your stack

Framework — A reusable foundation that provides structure and calls your code, shaping how an application is built. See Choosing your stack

Library — A collection of reusable code you call from your own program to avoid reinventing common functionality. See Choosing your stack

IDE (integrated development environment) — An editor bundled with tools like building, debugging, and code navigation in one place. See The development environment workflow

Linter — A tool that scans code for likely mistakes and style problems without running it. See The development environment workflow

Formatter — A tool that automatically rewrites code into a consistent style, ending arguments over layout. See The development environment workflow

Dotfiles — Personal configuration files for your tools and shell, often kept in version control to reproduce your setup. See The development environment workflow

Devcontainer — A defined, containerised development environment so everyone (including future you) works with the same setup. See The development environment workflow

Build-test loop — The fast cycle of changing code, building it, and running tests that drives day-to-day development. See The development environment workflow

Scope creep — The gradual, unplanned growth of what a project is meant to do, which threatens deadlines and focus. See Scoping a project

Milestone — A meaningful checkpoint in a project marking that a defined chunk of work is complete. See Scoping a project

Specification — A clear written statement of what is to be built and how it should behave. See Scoping a project

Pre-commit hook — An automated check that runs before a commit is recorded, blocking obvious problems early. See Quality when you are solo

Guardrail — An automated check or constraint that keeps you from making certain mistakes, even when no one is reviewing. See Quality when you are solo

Packaging and distribution

Binary — A compiled, runnable file produced from source code, ready to execute on a target machine. See Packaging and distribution

Semantic versioning — A version-numbering scheme (major.minor.patch) that signals the nature of each change to users. See Packaging and distribution

Release — A specific, packaged version of software made available for people to use. See Packaging and distribution

Package manager — A tool that installs, updates, and manages software and its dependencies for you. See Packaging and distribution

Code signing — Cryptographically marking software so users can verify who produced it and that it has not been tampered with. See Packaging and distribution

Checksum — A short value computed from a file that lets you verify the file downloaded intact and unaltered. See Packaging and distribution

Release notes — A summary of what changed in a release, telling users what is new, fixed, or removed. See Shipping and maintaining

Maintenance — The ongoing work of keeping released software working: fixing bugs, updating dependencies, and adapting to change. See Shipping and maintaining