Skip to content

Part 2 -- Installation & Getting Ready to Build

Installing Go

Option 1: MSI Installer (Recommended)

  1. Download the latest installer from go.dev/dl
  2. Run the .msi installer
  3. Go installs to C:\Program Files\Go by default
  4. The installer adds C:\Program Files\Go\bin to your PATH automatically

Option 2: Winget

winget install GoLang.Go

Option 3: Chocolatey

choco install golang

Verify installation:

go version
# go version go1.22.x windows/amd64

Option 1: Homebrew (Recommended)

brew install go

Option 2: Official Installer

  1. Download the .pkg from go.dev/dl
  2. Run the installer
  3. Go installs to /usr/local/go

Verify installation:

go version
# go version go1.22.x darwin/arm64

Option 1: Official Tarball (Recommended)

# Download (check go.dev/dl for latest version)
wget https://go.dev/dl/go1.22.2.linux-amd64.tar.gz

# Remove any previous installation and extract
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.22.2.linux-amd64.tar.gz

# Add to PATH (add to ~/.bashrc or ~/.zshrc for persistence)
export PATH=$PATH:/usr/local/go/bin

Option 2: Snap

sudo snap install go --classic

Verify installation:

go version
# go version go1.22.x linux/amd64

Understanding Go's Environment

Key Environment Variables

Variable Default Purpose
GOROOT Where Go is installed Location of the Go SDK. Rarely needs changing.
GOPATH $HOME/go (or %USERPROFILE%\go) Where Go stores downloaded modules and built binaries
GOBIN $GOPATH/bin Where go install places compiled binaries
GOPROXY https://proxy.golang.org,direct Module proxy for downloading dependencies
GOMODCACHE $GOPATH/pkg/mod Cache for downloaded module source code

Check your current environment:

go env

Check specific variables:

go env GOPATH GOROOT GOBIN

The GOPATH Directory Structure

$GOPATH/
├── bin/          # Compiled binaries from 'go install'
├── pkg/
│   └── mod/      # Downloaded module source code (module cache)
└── src/          # (Legacy) Before modules, source code lived here

Common Mistake

With Go modules (Go 1.11+), you do not need to work inside GOPATH. You can create projects anywhere on your filesystem. The GOPATH/src layout is legacy.


Editor Setup

  1. Install Visual Studio Code
  2. Install the Go extension by the Go Team at Google:
    • Open VS Code → Extensions → Search "Go" → Install the one by "Go Team at Google"
  3. Open any .go file -- VS Code will prompt to install Go tools. Click Install All.

This installs:

Tool Purpose
gopls Language server (IntelliSense, navigation, refactoring)
dlv Debugger (delve)
staticcheck Advanced linter
gotests Test generation
goplay Playground integration

Recommended VS Code Settings (.vscode/settings.json):

{
    "go.lintTool": "golangci-lint",
    "go.lintFlags": ["--fast"],
    "go.formatTool": "goimports",
    "go.useLanguageServer": true,
    "editor.formatOnSave": true,
    "[go]": {
        "editor.defaultFormatter": "golang.go",
        "editor.codeActionsOnSave": {
            "source.organizeImports": "explicit"
        }
    }
}
  1. Download GoLand (paid, 30-day trial)
  2. Install and open
  3. GoLand auto-detects your Go installation
  4. Everything works out of the box -- debugger, test runner, profiler, database tools

GoLand is the most feature-rich Go IDE but requires a JetBrains license.

Editor Go Support
Neovim gopls via LSP + nvim-lspconfig
Sublime Text LSP package + gopls
Emacs lsp-mode + gopls
Vim vim-go plugin or gopls via CoC

Your First Go Program

Step 1: Create a Project

# Create a directory anywhere on your filesystem
mkdir hello-go
cd hello-go

# Initialize a Go module
go mod init hello-go

This creates a go.mod file:

go.mod
module hello-go

go 1.22

Step 2: Write Code

Create main.go:

main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, Go!")
}

Step 3: Run It

# Compile and run in one step
go run main.go
# Output: Hello, Go!

# Or build a binary first, then run it
go build -o hello .
./hello
# Output: Hello, Go!

Understanding the Code

Element Meaning
package main This file belongs to the main package -- the entry point for executables
import "fmt" Import the fmt (format) package from the standard library
func main() The main function in the main package is where execution begins
fmt.Println() Print a line to stdout with a newline

Key Rule

Every Go executable must have a package main with a func main(). Library packages use different names and don't have main().


Essential Go Commands

Build & Run

go run main.go              # Compile and run
go run .                    # Compile and run entire package
go build                    # Build binary (same name as module)
go build -o myapp .         # Build binary with custom name
go install                  # Build and install to $GOBIN

Modules & Dependencies

go mod init myproject       # Initialize a new module
go mod tidy                 # Add missing, remove unused dependencies
go get github.com/pkg/lib   # Add a dependency
go get -u ./...             # Update all dependencies
go mod vendor               # Copy dependencies into vendor/
go mod download             # Pre-download dependencies (for Docker builds)

Testing

go test ./...               # Run all tests in all packages
go test -v ./...            # Verbose output
go test -run TestName ./... # Run specific test
go test -race ./...         # Run with race detector
go test -cover ./...        # Show coverage percentage
go test -bench=. ./...      # Run benchmarks

Code Quality

go fmt ./...                # Format all code (canonical style)
go vet ./...                # Static analysis for bugs
golangci-lint run           # Run multiple linters (install separately)

Information

go doc fmt.Println          # View documentation for a symbol
go env                      # Print all Go environment variables
go version                  # Print Go version
go list -m all              # List all dependencies

Project Structure Conventions

Go doesn't enforce a project structure, but the community follows a standard layout:

Small Project (CLI Tool / Library)

myproject/
├── go.mod
├── go.sum
├── main.go           # Entry point (for executables)
├── handler.go        # Other source files in the same package
├── handler_test.go   # Test files end in _test.go
└── README.md

Medium Project (API Service)

myproject/
├── cmd/
│   └── server/
│       └── main.go       # Entry point
├── internal/             # Private packages (not importable by others)
│   ├── handler/
│   │   ├── handler.go
│   │   └── handler_test.go
│   ├── service/
│   │   └── service.go
│   └── repository/
│       └── repository.go
├── pkg/                  # Public packages (importable by others)
│   └── models/
│       └── models.go
├── go.mod
├── go.sum
├── Dockerfile
└── README.md

Large Project (Multiple Services)

myproject/
├── cmd/
│   ├── api-server/
│   │   └── main.go
│   ├── worker/
│   │   └── main.go
│   └── cli/
│       └── main.go
├── internal/
│   ├── api/
│   ├── worker/
│   └── shared/
├── pkg/
│   ├── models/
│   └── client/
├── proto/                # Protocol buffer definitions
├── scripts/              # Build/deploy scripts
├── deployments/          # Docker, Kubernetes configs
├── go.mod
├── go.sum
├── Makefile
└── README.md

Interview Insight

The internal/ directory is special in Go. Packages under internal/ can only be imported by code within the parent of internal/. This is enforced by the compiler, making it the only visibility mechanism beyond exported/unexported identifiers. Mentioning this in interviews shows you understand Go's module system deeply.


Installing Additional Tools

# Install golangci-lint (meta-linter)
go install github.com/golangci-lint/golangci-lint/cmd/golangci-lint@latest

# Install delve debugger
go install github.com/go-delve/delve/cmd/dlv@latest

# Install mockgen (for generating mocks)
go install go.uber.org/mock/mockgen@latest

# Install protoc-gen-go (for Protocol Buffers)
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

Verifying Everything Works

Run this checklist after installation:

# 1. Go is installed
go version

# 2. Environment is correct
go env GOPATH GOROOT

# 3. Can create and run a program
mkdir -p /tmp/gotest && cd /tmp/gotest
go mod init test
echo 'package main; import "fmt"; func main() { fmt.Println("Ready!") }' > main.go
go run main.go

# 4. Tests work
echo 'package main; import "testing"; func TestOK(t *testing.T) {}' > main_test.go
go test -v

# 5. Formatting works
go fmt ./...

# 6. Vet works
go vet ./...

If all commands succeed, you're ready to start building with Go.