CHAPTER 01 · FOUNDATIONS

What is Coding?

Before we write a single line of Go, let's zoom out. Coding (also called programming or software development) is the act of writing precise instructions that a computer can carry out. Those instructions add up to everything from a tiny shell script to the app store in your pocket, from a spreadsheet to a jet's autopilot.

This chapter answers four questions that will make the rest of the course make sense: what is code, how does a computer actually run it, what kinds of languages exist, and where does Go sit among them.

Learning objectives

  • Explain, in one sentence, what code is.
  • Describe the path source code takes from your editor to the CPU.
  • Distinguish compiled, interpreted, and bytecode/JIT languages, and know which bucket Go is in.
  • Recognize the major language families (systems, scripting, functional, markup, query).
  • Articulate why Go was a deliberate choice for this course.

What is coding?

At its core, a program is a recipe: a numbered list of steps detailed enough that a machine with no common sense can follow it and get the same result every time. You write the recipe in a programming language, a notation humans can read that can be translated into something the computer understands.

A trivial example in Go looks like this:

package main

import "fmt"

func main() {
    name := "world"
    fmt.Println("Hello,", name)
}

That's six lines of precise instruction: declare a program, bring in a tool for printing, define an entry point, store the word "world" in a labeled box called name, and print a greeting. We'll unpack every part of this program in Chapter 4. For now, just notice that the code describes behavior using English-looking words and punctuation, not 1s and 0s.

i
"Programming" vs "coding" vs "software engineering" These words are used interchangeably. Technically, coding is the act of writing instructions, programming is the broader activity including design and debugging, and software engineering wraps it all in process (requirements, testing, maintenance). In practice, nobody nitpicks. This course uses all three.

How computers actually run code

Deep down, a CPU only understands one thing: binary instructions. Every program you've ever run (your browser, your game, this very web page's JavaScript) ends its life as a stream of 1s and 0s shuffling through silicon.

From source to silicon

A sequence of translations gets us from human-readable code to CPU-executable electricity:

Source code you write this main.go Translator compiler or interpreter Machine code binary instructions 01001010… CPU executes it (your computer)
Every programming language is, at the end of the day, a way to reach the CPU.

Why binary?

Transistors (the building blocks of a CPU) are essentially switches: they're either on or off. We call those states 1 and 0. A modern CPU contains billions of them. By combining them into patterns, the hardware can represent numbers, characters, colors, and (crucially) the operations it should perform.

Here's a whirlwind translation of our Hello, world! in three layers, from the most human to the least:

// Level 1: Go source (what you read and write)
fmt.Println("Hello,", "world")
# Level 2: x86-64 assembly (roughly, a human-readable sketch of machine code)
MOV    RDI, addr_of_string
CALL   fmt.Println
# Level 3: Raw machine code (what the CPU actually decodes)
48 8D 3D 00 00 00 00
E8 00 00 00 00

You will never write level 3 by hand (and level 2 only in very niche situations). That's the whole point of a high-level language like Go: it keeps you in level 1 while handling levels 2 and 3 automatically.

Peek under the hood (for later) Go ships with a built-in disassembler. Once you've written your first program, you can run go tool objdump -s main.main ./hello to see the actual machine instructions Go generated from your code. Don't worry about this now, but know that Go is never a black box.

Compiled vs interpreted

Languages differ in when the translation from source code to machine code happens. The three broad models are:

COMPILED (Go, C, Rust) source compiler (once) binary ready to ship CPU runs it fast · must recompile per OS/CPU INTERPRETED (Python, Ruby, JavaScript*) source interpreter reads + runs line by line (every time you run the program) output flexible · typically slower BYTECODE + JIT (Java, C#, modern JS engines) source bytecode VM + JIT warms up CPU runs it portable · peak speed after warmup
When does translation happen? That's the key difference. *Modern JavaScript engines use bytecode + JIT, not pure interpretation.

What each model trades off

Model Translation Runtime speed Portability Examples
Compiled Once, ahead of time Fastest One binary per OS/CPU Go, C, C++, Rust
Interpreted Every run, line by line Slowest (often) Runs anywhere the interpreter does Python, Ruby, Bash
Bytecode + JIT Ahead of time to bytecode, JIT at runtime Close to compiled, after warm-up Run anywhere the VM runs Java, C#, Kotlin, modern JS

Go is firmly in the compiled camp. When you run go build, Go produces a single, self-contained binary file that the CPU runs directly. No virtual machine, no interpreter, no "node_modules", no JVM. This is a big reason Go programs start so quickly and ship so easily (Chapter 4 will show this in action).

!
The lines are fuzzy In practice, most languages blend models. Python "compiles" to bytecode (.pyc files) before interpreting. JavaScript engines like V8 use aggressive JIT compilation. Even Go has a runtime for goroutine scheduling and garbage collection. Don't let purists fight over precise definitions. The table above captures the practical differences.

Types of programming languages

Besides when they translate (compiled vs interpreted), languages differ in what they're designed for. You'll hear people group them by family:

  • Systems / general-purpose: build pretty much anything; performance-sensitive code, infrastructure, CLIs. Examples: Go, C, C++, Rust, Java.
  • Scripting / dynamic: quick automation, glue code, prototypes, data analysis. Examples: Python, Ruby, Bash, Lua.
  • Functional: emphasize pure functions and immutability. Examples: Haskell, Elixir, OCaml, Clojure.
  • Markup: describe structure rather than behavior. Not really programming languages, but you'll read and write them constantly. Examples: HTML, XML, Markdown.
  • Query: ask questions of data stores. Examples: SQL, GraphQL, SPARQL.
  • Domain-specific: hyper-specialized. Examples: Dockerfile, Terraform HCL, regex, CSS.

Many languages fit in more than one box. Go, for instance, is general-purpose but especially loved for backend services, CLIs, and networked infrastructure.

Where Go fits

If you squint at the families above, you can see why someone would pick one over another for a given job. Where does Go sit?

  • Speed of a compiled language: Go compiles to a static binary that runs as fast as C or C++ for most day-to-day code.
  • Simplicity of a scripting language: the syntax is intentionally small. You can read a Go program you've never seen and roughly understand it. This is by design.
  • Concurrency built in: go and channels are language keywords. No extra libraries needed. (Chapters 24–26.)
  • Ergonomic tooling: formatter, linter, test runner, benchmark runner, and doc generator all ship with the compiler.
  • A single deployable file: the classic Go pitch. Build once, copy the binary, run anywhere.

That's why Go powers so much modern infrastructure: Docker, Kubernetes, Terraform, Prometheus, etcd, CockroachDB, Caddy, Hugo, and so on. When you need a fast, reliable backend service or command-line tool, Go is a strong default. You'll meet each of these strengths firsthand throughout this course.

Why learn to code?

A quick aside worth reading if you're on the fence:

  1. Problem-solving muscle. Coding teaches you to break fuzzy problems into tiny, precise steps. This skill transfers to basically everything else.
  2. Leverage. A short script can do in seconds what would take a human hours, every week, forever.
  3. Career optionality. Software touches every industry; coding skills expand what jobs and roles are available to you.
  4. Creation, not just consumption. Knowing how software works changes you from a user into a maker. You can build the tool you wished existed.
How to actually learn in this course Read a chapter, then run the example. Read the next section, then change the example and run it again. Reading without typing is the single fastest way to convince yourself you understand something you don't. Every page in this course has an Open Go Playground button: use it.

Check your understanding

Practice exercises

EXERCISE 1

Classify the language

For each of the following languages, write down whether you think it's compiled, interpreted, or bytecode + JIT. If unsure, guess, then look it up.

  1. Go
  2. Python
  3. Rust
  4. JavaScript (in a modern browser like V8)
  5. Bash
  6. Java

No code to write. This is a thinking exercise.

Show one possible answer
  1. Go: compiled. Produces a static binary via go build.
  2. Python: mostly interpreted (it compiles to .pyc bytecode behind the scenes, then interprets that).
  3. Rust: compiled. LLVM-backed, produces native binaries.
  4. JavaScript: bytecode + JIT in modern engines like V8. "Interpreted" is the textbook answer but practically inaccurate today.
  5. Bash: interpreted. The bash program reads and runs your script line by line.
  6. Java: bytecode + JIT. Compiled to .class files, run by the JVM which JITs hot code to native.
EXERCISE 2

Read (not write!) your first Go program

Below is a slightly bigger Go snippet than the one at the top of this chapter. You don't know Go yet, but you know English. Read it slowly and try to predict, in plain words, what it will print when you click Open Go Playground and run it there.

package main

import "fmt"

func main() {
    languages := []string{"Go", "Python", "Rust", "JavaScript"}
    fmt.Println("Languages I know about:")
    for i, lang := range languages {
        fmt.Printf("  %d. %s\n", i+1, lang)
    }
    fmt.Printf("That's %d languages total.\n", len(languages))
}

Then click Open Go Playground, run the snippet there, and compare the output to your prediction. Did you get it right? Anything surprising?

Show expected output & notes
Languages I know about:
  1. Go
  2. Python
  3. Rust
  4. JavaScript
That's 4 languages total.

Things to notice, even without "knowing" Go yet:

  • []string{"Go", "Python", ...}: a list of text items. Go calls these slices (Chapter 13).
  • for i, lang := range languages: loop over the list, giving each item an index i and a value lang.
  • %d is a placeholder for a number, %s for a string, same idea as printf in other languages.
  • len(...): the built-in length function.

We'll meet every one of these in future chapters. Today, the goal is just to see that you can already mostly read Go.

Further reading

Felt solid? Lock it in.