Julia Evans
Accessible, friendly explanations of debugging, Linux, networking, and more.
debuggingLinuxnetworking
- Examples for the tcpdump and dig man pages
- Notes on clarifying man pages
- Some notes on starting to use Django
- A data model for Git (and other docs updates)
- Notes on switching to Helix from vim
- New zine: The Secret Rules of the Terminal
- Using `make` to compile C programs (for non-C-programmers)
- Standards for ANSI escape codes
- How to add a directory to your PATH
- Some terminal frustrations
- What's involved in getting a "modern" terminal setup?
- Why pipes sometimes get "stuck": buffering
- "Rules" that terminal programs follow
- Importing a frontend Javascript library without a build system
- New microblog with TILs
- ASCII control characters in my terminal
- Using less memory to look up IP addresses in Mess With DNS
- Some notes on upgrading Hugo
- Terminal colours are tricky
- Some Go web dev notes
- Reasons I still love the fish shell
- Migrating Mess With DNS to use PowerDNS
- Go structs are copied on assignment (and other things about Go I'd missed)
- Entering text in the terminal is complicated
- Reasons to use your shell's job control
- New zine: How Git Works!
- Notes on git's error messages
- Making crochet cacti
- Some Git poll results
- The "current branch" in git
- How HEAD works in git
- Popular git config options
- Dealing with diverged git branches
- Inside .git
- Do we think of git commits as diffs, snapshots, and/or histories?
- Some notes on NixOS
- 2023: Year in review
- Mounting git commits as folders with NFS
- git branches: intuition & reality
- Some notes on nix flakes
- How git cherry-pick and revert use 3-way merge
- git rebase: what can go wrong?
- Confusing git terminology
- Some miscellaneous git facts
- New talk: Making Hard Things Easy
- In a git repository, where do your files live?
- Notes on using a single-person Mastodon server
- What helps people get comfortable on the command line?
- Some tactics for writing in public
- Behind "Hello World" on Linux
- Why is DNS still hard to learn?
- Lima: a nice way to run Linux VMs on Mac
- Open sourcing the nginx playground
- New zine: How Integers and Floats Work
- Some blogging myths
- New playground: memory spy
- Introducing "Implement DNS in a Weekend"
- New talk: Learning DNS in 10 years
- New playground: integer.exposed
- A list of programming playgrounds
- Building a custom site for zine feedback
- Some possible reasons for 8-bit bytes
- How do Nix builds work?
- Some notes on using nix
- Writing Javascript without a build system
- Print copies of The Pocket Guide to Debugging have arrived
- Why does 0.1 + 0.2 = 0.30000000000000004?
- Examples of problems with integers
- Examples of floating point problems
- Some business graphs for 2022
- New zine: The Pocket Guide to Debugging
- A debugging manifesto
- Tips for analyzing logs
- A couple of Rust error messages
- Making a DNS query in Ruby from scratch
- Why do domain names sometimes end with a dot?
- How to send raw network packets in Python with tun/tap
- Some ways to get better at debugging
- A toy remote login server
- What happens when you press a key in your terminal?
- Monitoring tiny web services
- Notes on running containers with bubblewrap
- sqlite-utils: a nice way to import data into SQLite for analysis
- Pages that didn't make it into "How DNS Works"
- New zine: How DNS Works!
- A list of new(ish) command line tools
- Implementing a toy version of TLS 1.3
- Celebrate tiny learning milestones
- How to use undocumented web APIs
- Some tiny personal programs I've written
- Some things about getaddrinfo that surprised me
- Things that used to be hard and are now easy
- The multiple meanings of "nameserver" and "DNS resolver"
- A toy DNS resolver
- Reasons for servers to support IPv6
- Hosting my static sites with nginx
- Some ways DNS can break
- How to find a domain's authoritative nameservers
- Why might you run your own DNS server?
- 2021: Year in review
- New tool: Mess with DNS!
- DNS "propagation" is actually caches expiring
- How to use dig
- Debugging a weird 'file not found' error
- Some notes on using esbuild
- How do you tell if a problem is caused by DNS?
- How to get useful answers to your questions
- Tools to explore BGP
- All my zines are now available in print!
- New tool: an nginx playground
- Teaching by filling in knowledge gaps
- Debugging by starting a REPL at a breakpoint is fun
- Quadratic algorithms are slow (and hashmaps are fast)
- Write good examples by starting with real code
- Reasons why bugs might feel "impossible"
- You can now buy print version of my zines!
- Blog about what you've struggled with
- How to look at the stack with gdb
- The OSI model doesn't map well to TCP/IP
- I put all of my comics online!
- Notes on building debugging puzzles
- What problems do people solve with strace?
- A tool to spy on your DNS queries: dnspeep
- A little tool to make DNS queries
- Day 57: Trying to set up GitHub Actions
- Day 53: a little nginx, IPv6, and wireguard
- Day 52: testing how many Firecracker VMs I can run
- Day 51: Fixed my logging and made a couple of puzzles
- Day 50: Building some tarballs for puzzles, and trying to make a kernel boot faster
- Day 49: making the VMs boot faster
- Day 48: Another Go program, and a little vim configuration
- Day 47: Using device mapper to manage Firecracker images
- Day 46: debugging an iptables problem
- Firecracker: start a VM in less than a second
- Day 44: Building my VMs with Docker
- Day 43: Building VM images
- Day 42: Writing a Go program to manage Firecracker VMs
- Day 41: Trying to understand what a bridge is
- Day 40: screen flickering & a talk about containers
- Day 39: Customizing gotty's terminal
- Day 38: Modifying gotty to serve many different terminal applications at once
- Day 37: A new laptop and a little Vue
- Server-sent events: a simple way to stream events from a server
- Day 35: Launching my VMs more reliably
- Day 34: Learning about qemu
- Day 33: pairing is magic and beautiful git diffs
- Day 32: A Rails model that doesn't use the database with ActiveHash
- Docker Compose: a nice way to set up a dev environment
- 2020: Year in review
- Day 24: a short talk about blogging myths, and a debugging tip
- Day 23: a little Rails testing
- Day 22: getting OAuth to work in Rails
- Day 21: wrangling systemd & setting up git deploys to a VM
- How I write useful programming comics
- Day 19: Clustering faces (poorly) using an autoencoder
- Day 20: trying to figure out how Google Cloud IAM works
- Day 18: an answer to an autoencoder question
- Day 17: trying to wrap my head around autoencoders
- An attempt at implementing char-rnn with PyTorch
- Day 13: BPTT, and debugging why a model isn't training is hard
- Day 11: learning about learning rates
- New zine: Hell Yes! CSS!
- Day 10: Training an RNN to count to three
- Day 9: Generating a lot of nonsense with an RNN
- Day 8: Start with something that works
- Day 5: drawing lots of faces with sketch-rnn
- How do you write simple explanations without sounding condescending?
- Day 3: an infinitely tall fridge
- Day 2: Rails associations & dragging divs around
- Day 1: a confusing Rails error message
- A new way I'm getting feedback on my zines: beta readers!
- I'm doing another Recurse Center batch!
- A few things I've learned about email marketing
- ninja: a simple way to do builds
- Wizard Zines' first print run: Help! I have a Manager!
- Implementing 'focus and reply' for Fastmail with JMAP
- Some possible future zines
- Some more CSS comics
- An attempt to make a font look more handwritten
- Some CSS comics
- When your coworker does great work, tell their manager
- scanimage: scan from the command line!
- saturday comics: a weekly mailing list of programming comics
- Tell candidates what to expect from your job interviews
- entr: rerun your build when files change
- A little bit of plain Javascript can do a lot
- Questions to help people decide what to learn
- Metaphors in man pages
- Why strace doesn't work in Docker
- New zine: How Containers Work!
- Getting started with shaders: signed distance functions!
- New zine: Become a SELECT Star!
- PaperWM: tiled window management for GNOME
- "server" is hard to define
- Solutions to the tiny window manager challenge
- Challenge: Write a bouncy window manager
- What makes a programming exercise good?
- How containers work: overlayfs
- Some notes on vector drawing apps
- SQLite is really easy to compile
- Some research on shipping print zines
- Your Linux Toolbox: a box set of my free zines
- SQL queries don't start with SELECT
- Zine revenue for 2019
- Notes on building SQL exercises
- Taking a year to explain computer things
- New zine: HTTP: Learn your browser's language!
- How to put an HTML page on the internet
- How to write zines with simple tools
- git exercises: navigate a repository
- curl exercises
- What does debugging a program look like?
- Why are monoidal categories interesting?
- New zine: Bite Size Networking!
- Organizing this blog into categories
- !!Con 2019: submit a talk!
- Networking tool comics!
- A few early marketing thoughts
- Some nonparametric statistics math
- 2018: Year in review
- New talk: High Reliability Infrastructure Migrations
- How do you document a tech project with comics?
- An example of how C++ destructors are useful in Envoy
- Some notes on running new software in production
- Tailwind: style your site without writing any CSS!
- When does teaching with comics work well?
- Some Envoy basics
- New zine: Oh shit, git!
- Some possible career goals
- Why sell zines?
- An awesome new Python profiler: py-spy!
- Editing my blog's HTTP headers with Cloudflare workers
- Who pays to educate developers?
- How to teach yourself hard things
- I started a corporation!
- A few recent podcasts
- New zine: Bite Size Command Line!
- IP addresses & routing
- netdev day 2: moving away from "as fast as possible" in networking code
- netdev day 1: IPsec!
- How I use Wireshark
- Batch editing files with ed
- How to get a core dump for a segfault on Linux
- New zine: Profiling & tracing with perf!!
- Reverse engineering the Notability file format
- Open source sabbatical = awesome
- Documentation site for rbspy!
- Talks I'd love to see at RustConf
- A few things I've learned about computer networking
- How does the internet work? podcast
- Prototyping an ltrace clone using eBPF
- Profiler week 6/7: more experiments, and a `report` subcommand!
- Working remotely, 4 years in
- Writing performance reviews with positive constructive feedback
- Profiler week 5: Mac support, experiments profiling memory allocations
- Writing eBPF tracing tools in Rust
- Spying on a Ruby process's memory allocations with eBPF
- Profiler week 4: callgrind support, containers, Mac progress!
- I think I found a Mac kernel bug?
- How do you spy on a program running in a container?
- How do you read the memory maps of a Mac process?
- Profiler week 3: refactoring, better testing, and an alpha release!
- Profiler week 2: support for 1.9.3 -> 2.5.0, and line numbers!
- Should I pause a Ruby process to collect its stack?
- Rust in 2018: it's way easier to use!
- Profiler adventures: resolving symbol addresses is hard!
- Profiler week 1: testing & profiling stripped binaries
- How does gdb call functions?
- 2017: Year in review
- My first Rust macro
- Debugging a segfault in my Rust program
- Bindgen: awesome Rust tool for generating C bindings
- How are Ruby's headers different from Python's headers?
- How often do Ruby's stack struct definitions change?
- How do Ruby & Python profilers work?
- Taking a sabbatical to work on Ruby profiling tools
- New zine: So you want to be a wizard
- What's a reference in Rust?
- Linux comics: a small zine
- How do groups work on Linux?
- Glitch: write fun small web projects instantly
- Binder: an awesome tool for hosting Jupyter notebooks
- Operating a Kubernetes network
- Reasons Kubernetes is cool
- Profiling Go programs with pprof
- How I spent my time at the Recurse Center
- Finding out if/why a server is dropping packets
- What's a network interface?
- Telling people what you're working on
- Debugging netlink requests
- Learning at work
- Figuring out how to contribute to open source
- How Kubernetes certificate authorities work
- Cherry picking commits & shell scripting in golang
- How does the Kubernetes scheduler work?
- Linux tracing systems & how they fit together
- Notes on BPF & eBPF
- a tiny whack-a-mole game
- What can developers learn from being on call?
- Awesome NLP tutorials by Allison Parrish
- Log-structured storage
- Iptables basics
- A few things I've learned about Kubernetes
- Async IO on Linux: select, poll, and epoll
- "Let's learn tcpdump" zine: now available for everyone
- Handwritten books
- A small website mystery
- Like zines about computers? You might love Bubblesort Zines
- Using the Strict-Transport-Security header
- New zine: let's learn tcpdump!
- No feigning surprise
- The fish shell is awesome
- Some good "Statistics for programmers" resources
- Making small culture changes
- netdev conference, day 3
- netdev conference, day 2
- How to filter packets super fast: XDP & eBPF!
- netdev conference, day 1
- Slow down your internet with tc
- Bash scripting quirks & safety tips
- Blogging principles I use
- ftrace: trace your kernel functions!
- Writing down my career
- Swapping, memory limits, and cgroups
- Hiring & opportunity
- How do these "neural network style transfer" tools work?
- Weird unix thing: 'cd //'
- How big can a packet get?
- A magical machine learning art tool
- Dissecting an SSL certificate
- Choosing the "best software"
- A tiny zine about machine learning
- An idea for a programming book
- How do you make an awesome team?
- Rules of programming experiments
- Systems We Love 2016
- A container networking overview
- What's interesting about UDP?
- 2016: Year in review
- How much memory is my process using?
- Things to learn about Linux
- "A Critique of the CAP Theorem"
- Ideas about how to use AWS
- Why cute drawings?
- What happens when you run a rkt container?
- Running containers without Docker
- A few questions about open source
- Consistency vs availability (wat?)
- A litmus test for job descriptions
- What's devops?
- Operations for software developers for beginners
- What even is a container: namespaces and cgroups
- Switching to Hugo
- What happens when you start a process on Linux?
- A list of Linux container software
- "I just want to run a container!"
- Getting things done
- A swiss army knife of debugging tools: talk & transcript
- Some questions about Docker and rkt
- How I got a CS degree without learning what a system call is
- Learning systems programming with Rust
- New zine: Linux debugging tools you'll love
- Asking good questions is hard (but worth it)
- How (and why) I made a zine
- Why do UDP packets get dropped?
- Release it, then build it
- How do you decide what to work on?
- How does gdb work?
- Benchmarking correctly is hard (and techniques for doing it better)
- How do HTTP requests get sent to the right place?
- PolyConf 2016
- Linux debugging tools I love
- Why do we use the Linux kernel's TCP stack?
- Using ltrace to debug a memory leak
- Should you be scared of Unix signals?
- How to spy on a Ruby program
- A useful new strace feature
- Ideas for making better conference talks & conferences
- Learning to like design documents
- Three ways to solve hard programming problems
- "advice" for aspiring tech bloggers
- Notes from my PyData Berlin keynote
- A few reasons to be skeptical of machine learning
- homu + highfive: awesome bots that make open source projects easier
- Investigating Erlang by reading its system calls
- A second try at using Rust
- What are SSL ciphers & session keys?
- A workshop on strace & tcpdump
- The Etsy site performance report is amazing
- How does knowledge get locked up in people's heads?
- CDNs aren't just for caching
- you can take the derivative of a regular expression?!
- Some links on Java garbage collection
- Java garbage collection can be really slow
- Looking inside machine learning black boxes
- Some of my favorite blogs
- I conquered thread pools! For today, at least.
- Thread pools! How do I use them?
- I/O matters.
- How do you do capacity planning?
- tcpdump is amazing
- How does perf work? (in which we read the Linux kernel source)
- Women-only spaces are a hack
- Surprises in Ruby HTTP libraries
- What is "the stack"?
- perf top: an awesome way to spy on CPU usage
- How to measure your CPU time: clock_gettime!
- Why I love log files
- Have high expectations for your computers
- TIL: clock skew exists
- How CPU load averages work (and using them to triage webserver performance!)
- Fast integer sets with Roaring Bitmaps (and, making friends with your modern CPU)
- Sendfile (a system call for web developers to know about!)
- Calling C from Rust
- Guessing Linux kernel registers
- Talking about stock options = awesome
- Java isn't slow
- Winning the bias-variance tradeoff
- Surviving meetings while remote
- Things you should know about stock options before negotiating an offer
- 2015: Year in review
- Women in Machine Learning 2015 (fun!!!)
- Why Ruby’s Timeout is dangerous (and Thread.raise is terrifying)
- How I got better at debugging
- Why you should understand (a little) about TCP
- Docker is amazing
- PAPERS ARE AMAZING: Profiling threaded programs with Coz
- A millisecond isn't fast (and how we made it 100x faster)
- Some easy statistics: Bootstrap confidence intervals
- AdaCamp Montreal 2015
- Learning at open source sprints (no preparation required)
- Seeing system calls with perf instead of strace
- Senior engineering & fantasy heroes
- Nancy Drew and the Case of the Slow Program
- You can choose who submits talks to your conference
- 1:1 topic ideas
- How the locate command works (and let's write a faster version in one minute!)
- How gzip uses Huffman coding
- How I learned to program in 10 years
- A/A testing
- Data Day Texas 2015
- On reading the source code, not the docs
- Programming doesn't belong to men (it belongs to me)
- Fear makes you a worse programmer
- Reproducing awesomeness
- Diving into concurrency: trying out mutexes and atomics
- Spying on Hadoop with strace
- LD_PRELOAD is super fun. And easy!
- PyData NYC (I gave a machine learning talk! yay!)
- Fun with machine learning: logistic regression!
- Fun with machine learning: does your model actually work?
- What women in technology really think (150 of them, at least)
- Working remote, 8 months in (seeing humans is important!)
- How to set up a blog in 5 minutes
- How does SQLite work? Part 2: btrees! (or: disk seeks are slow don't do them!)
- How does SQLite work? Part 1: pages!
- Strange Loop 2014
- You can be a kernel hacker!
- How is a binary executable organized? Let's explore it!
- What happens if you write a TCP stack in Python?
- Pair programming is amazing! Except... when it's not.
- Open sourced talks!
- Fun with stats: How big of a sample size do I need?
- How I did Hacker School: ignoring things I understand and doing the impossible
- Machine learning isn't Kaggle competitions
- Asking questions is a superpower
- Should my conference do anonymous review?
- Working remote, 3 months in
- Anonymous talk review is amazing.
- Diving into HDFS
- I can spy on my CPU cycles with perf!
- Computers are *fast*!
- Don't feel guilty about not contributing to open source
- Debug your programs like they're closed source!
- ♥ PyCon
- Becoming a better developer (it's not just writing more programs)
- "Ask if you have questions" isn't enough
- Reports from remote-land: remote pairing works great!
- Recovering files using /proc (and spying, too!)
- My Rust OS will never be finished (and it's a success!)
- Writing an OS in Rust in tiny steps (Steps 1-5)
- Debugging shared library problems with strace
- Hacker School's Secret Strategy for Being Super Productive (or: Help.)
- Pair programming
- More practical uses for strace!
- Using strace to avoid reading Ruby code
- Spying on ssh with strace
- "How was Hacker School?"
- A few blogs I really like
- Three steps to learning GDB
- Sounding confident in interviews
- CUSEC = fun
- What my technical interviews have looked like
- You should give talks. They will be awesome. Here's why!
- 4 paths to being a kernel hacker
- Some things my kernel can't do
- Questions I'm asking in interviews
- Coding strategies
- When is "guys" gender neutral? I did a survey!
- A pandas cookbook
- Understanding how killall works using strace
- Day 45: I now have Rust code for executing executables!
- Day 44: qemu + gdb = so great
- Day 43: SOMETHING IS ERASING MY PROGRAM WHILE IT’S RUNNING (oh wait oops)
- Day 42: How to run a simple ELF executable, from scratch (I don't know)
- Day 39: Writing malloc wrong, for fun
- Day 40: 12 things I learned today about linkers.
- Day 40: Linkers are amazing.
- Day 38: After 6 days, I have problems that I can't understand at all
- Day 37: After 5 days, my OS doesn't crash when I press a key
- Day 36: On programming without malloc
- Day 35: Types in Rust, for beginners
- How to call Rust from assembly, and vice versa
- Videos from PyData NYC are up!
- What happens when you run 'Hello, world'
- Writing a kernel using rustboot & rust-core
- Day 34b: Writing curl using my TCP stack
- Day 33: How to make music with ClojureScript
- Day 31: Binary trees with core.logic!
- Day 30: Making music in Clojure with Overtone. Clojure bugs with laziness! Fun!
- Day 27: Automatically testing changes in state! Visualizing my Git workflow! Floats!
- Day 25: ACK all the things
- Day 26: Trying to describe the TCP state machine in a readable way. Failing.
- Women in Technology workshop at PyData NYC
- Day 23: Started writing a TCP stack in Python
- Day 21: Trying to TCP
- Day 19: A few reasons why networking is hard
- Day 20: Traceroute in 15 lines of code using Scapy
- Day 18: ARP cache poisoning (or: In ur connection, sniffing ur packets)
- Day 17: How to write a buffer overflow exploit
- Day 16: gzip + poetry = awesome
- Day 15: How a .gz file is structured, redux
- Day 14: When it's hard to write tests, that's when I should be testing
- Day 12: Why Julia likes Julia
- Day 11: How does gzip work?
- Day 9: Bytecode is made of bytes! CPython isn't scary!
- Day 8: Julia writes Julia! And remembers that open source is hard.
- Day 6: I wrote a rootkit!
- Day 5: I wrote a kernel module!!!
- Day 4: Processes vs threads, and kernel modules!
- Day 3: What does the Linux kernel even do?
- Hacker School Day 1: Messing around with the stack in C
- Hacker School Day -4: unit testing in C. checkmk!
- Julia Serano's 'Excluded'
- PyData Boston 2013
- Open Data Exchange 2013