Managing project tools with Go
Comparing approaches for managing non-application tool dependencies in Go projects, including go tool, tools.go, and go run.
Comparing approaches for managing non-application tool dependencies in Go projects, including go tool, tools.go, and go run.
A custom shell-based solution for automatically installing and switching Go versions when changing directories.
Essential Go concurrency patterns including goroutines, channels, mutexes, and common synchronization techniques.
Using bitwise operators in Go to manipulate individual flags within a single integer for compact state management.
A hands-on guide to building and deploying edge applications with Fastly Compute using JavaScript, Go, or Rust compiled to Wasm.
Why an interface holding a nil pointer is not itself nil in Go, and how typed nils can cause unexpected behavior.
Implementing CI/CD across dev, stage, and prod environments using GitHub Actions with Terraform Cloud for state management.
A comprehensive guide to designing, documenting, and validating APIs using the OpenAPI specification.
A step-by-step guide to writing a custom Terraform provider in Go using the terraform-plugin-sdk.
A reference guide to Rust's smart pointer types: Box, Rc, Arc, Cell, and RefCell, with usage notes and trade-offs.
Updated guide for setting up a new macOS laptop including GPG/SSH key backup, Homebrew, Zsh, Neovim, and password store configuration.
How to install, manage, and switch between multiple Go versions using official tools and custom shell functions.
Configuring Neovim with LSP support for Rust and Go development, including required executables and plugin setup.
A working solution for fixing broken Vim colour themes using Neovim, a proper terminal, and correct tmux configuration.
An overview of my current developer toolchain including Ghostty, Neovim, Zsh, and a curated set of CLI utilities.
A personal Go style guide covering naming, error handling, interfaces, slice gotchas, and function design patterns.
A comprehensive guide to building CI/CD pipelines with GitHub Actions, covering workflows, jobs, steps, and reusable patterns.
A deep dive into powerful Vim features including macros, global commands, substitutions, quickfix lists, and autocomplete without plugins.
A practical explanation of Rust's memory management model covering stack vs heap, ownership rules, borrowing, and lifetimes.
A practical walk-through of Go's reflect package using a real CLI flags library as the guiding example.
A structured approach to evaluating and comparing external code libraries using a comparison matrix of key properties.
Implementing rate limiting at the CDN edge for public-facing services, covering algorithms and practical trade-offs.
A deep dive into the .git directory, plumbing vs porcelain commands, and how git works under the hood.
Understanding Python context managers: what they are, why they matter for resource cleanup, and how to implement them.
A step-by-step guide to understanding iterators, generators, and coroutines in Python, building from first principles.
What the tox tool is, how to configure tox.ini, and why its config file is used by other Python tools like flake8 and pytest.
How to manage multiple Python versions, set up virtual environments, and handle project dependencies on macOS.
A guide to Python's asyncio module covering async/await, event loops, tasks, and when to use asyncio vs threading or multiprocessing.
A deep dive into how Go arrays and slices work, including memory layout, append behavior, and capacity gotchas.
Tools and techniques for limiting your online exposure, covering encrypted DNS, VPNs, Tor, and browser privacy.
A practical guide to HTTP caching covering Cache-Control, Surrogate-Control, and caching strategies at client and proxy layers.
Step-by-step guide for setting up a new macOS development environment with Homebrew, Git, Python, Go, Vim, and tmux.
How to use git worktrees to work on multiple branches simultaneously without stashing.
Implementations of merge sort, quick sort, binary search, BFS, DFS, and Dijkstra's algorithm in Python.
Lessons learned from years of remote working, covering routines, communication, impact, health, and building relationships.
A practical guide to mocking resources in Python tests using unittest.mock, covering decorators, patching, and common pitfalls.
A quick reference for calculating Big O time complexity by identifying dominant operations in an algorithm.
An introduction to Big O notation and algorithmic time complexity with Python examples for common operations.
A high-level overview of scalar, composite, and abstract data types along with common data structures like arrays, linked lists, trees, and hash tables.
Python development practices for 2019 including type hints, static analysis with mypy, interfaces, and dependency management.
How to set up and configure Webpack and Babel for writing cross-compatible modern ES2015+ JavaScript code.
A guide for software engineers considering the transition to engineering management, covering responsibilities, communication, and motivation.
How to conduct architecture interviews effectively, why whiteboard interviews are not inherently bad, and what to look for in candidates.
How to run effective blameless post-mortems, including scheduling, invitees, attitude, and a reusable template.
Building a Slackbot for incident management that creates channels, auto-invites responders, and looks up service runbooks.
A practical guide to designing flexible Go code using interfaces, dependency injection, and programming to abstractions.
Defining the spectrum from monolith to nano services and when each granularity of service architecture is appropriate.
A deep dive into AWS Cognito covering user pools, identity pools, and building an authentication system for web applications.
Practical advice for managers and reports on running meaningful one-to-one meetings that build trust and drive career growth.
A concise project management checklist covering roles, priorities, user stories, and rollout planning for technical leads.
A curated list of recommended books covering programming, architecture, testing, management, and communication.
Building a Python encryption library using scrypt for key derivation, covering KDF, PBKDF2, and digest generation.
How to add fast, free, client-side search to a static site using Lunr.js without any server-side dependencies.
Key topics and questions to cover when interviewing at a new company, from culture and process to tech stack and vision.
Building a reverse proxy in Go using httputil.ReverseProxy, from simple single-origin to configurable multi-route setups.
A concise reference explaining the differences between hashing, encryption, and encoding with practical examples.
An explanation of how terminals, kernels, and shells relate to each other and how programs interact with them.
A beginner-friendly introduction to statistics covering data types, frequency, averages, distributions, and graph visualisation.
Practical guidelines for building performant and reliable NSQ queue reader services in Python.
Best practices for application monitoring covering metrics, alerting strategies, data aggregation, and graph selection.
A concise set of guidelines for running effective load tests, covering real datasets, traffic distribution, and tooling.
A practical guide to application logging covering log levels, structured logging, and choosing between logs and metrics.
A deep dive into how Fastly's CDN works, covering Varnish internals, clustering, shielding, and edge programming gotchas.
Techniques and tools for profiling Python applications including timers, cProfile, line_profiler, memory_profiler, and pyflame.
Techniques and tools for profiling Go applications including pprof, benchmarks, and memory management analysis.
How to use Docker containers as clean, isolated development environments for Python and Go projects.
An overview of a layered personal security architecture using GPG keys, encrypted password stores, and SSH key management.
A comprehensive cheat sheet covering Go fundamentals, from types and control flow to concurrency and testing.
Key concepts from learning C including compilation, memory management, pointers, and how higher-level languages abstract these details.
How to navigate Unix manual page sections, sub-sections, and search across them effectively.
Explaining the difference between Linux system calls and C library wrapper functions, and where to find documentation for each.
A tour through bits, bytes, RAM, base number systems, and binary encoding fundamentals for newcomers to computing.
Setting up Pass, a GPG-based command-line password manager, as a free and secure alternative to GUI tools like 1Password.
An overview of command-line debugging tools like tcpdump, telnet, netstat, and others for diagnosing network and application issues.
Best practices for writing clear, well-structured pull requests including size, process, and description formatting.
A gentle introduction to Big O notation covering logarithms, factorials, and how to reason about algorithm growth rates.
A list of ideal qualities for software developers including humility, patience, analytical thinking, and clear communication.
Explains the differences between git merge, rebase, and squash strategies with practical examples.
An introduction to Google's gRPC framework covering Protocol Buffers, service definitions, and building clients and servers.
A simple Bash script that monitors web pages for failures and sends Slack notifications when endpoints return non-200 status codes.
Exploring different RPC implementations in Go including net/rpc, JSON-RPC, and gRPC with Protocol Buffers.
How Go's http.HandlerFunc adapter uses a func type to satisfy the Handler interface and enable flexible HTTP routing.
How to configure multiple SSH keys on one machine to work with separate GitHub accounts.
A quick introduction to HTTP/2 covering persistent connections, multiplexing, header compression, and server push.
An introduction to using GNU Make as a modern build and automation tool, with practical Makefile examples.
How to configure nginx with client certificate authentication using Docker, including CA and CRL setup.
A comprehensive guide to how the Domain Name System works, covering IPv4, IPv6, DNS resolution, and record types.
A hands-on guide to cryptographic keys, PKI, GPG, OpenSSH, OpenSSL, and Keybase for encrypting and signing data.
A walkthrough of configuring nginx as a reverse proxy inside Docker containers to serve a backend application.
Lessons from building high-traffic systems at BBC News on complexity, caching, automation, and keeping software simple.
An exploration of shared memory vs message passing concurrency models including threads, locks, actors, and CSP.
A team workflow for GitHub PRs using interactive rebase, squash commits, and cherry-pick merges.
Exploring recursion in JavaScript, the tail call optimisation problem, and techniques like trampolining to work around stack limits.
A summarised reference of commonly used refactoring techniques distilled from Fowler and Beck's Refactoring books.
A breakdown of the MVC pattern and its evolution into MVCP with a dedicated Presenter layer for cleaner separation of concerns.
A beginner-friendly guide to common unix shell commands and scripting fundamentals for everyday use.
Key takeaways from Robert C. Martin's Clean Coder on professionalism, responsibility, testing, and time management.
How thinking in terms of messages rather than method calls improves OO design, illustrated with Ruby's Proxy pattern.
Distilled principles of good OO design from Sandi Metz covering dependencies, interfaces, duck typing, and inheritance.
A collection of useful Git commands and tips for everyday version control tasks.
A beginner-friendly introduction to JavaScript covering syntax, terminology, data types, and core language features.
A quick introduction to writing maintainable CSS using the Block, Element, Modifier (BEM) naming convention.
Understanding the difference between native ECMAScript methods and host environment methods, and how to detect each reliably.