I’ve designed and built high-throughput, low-latency systems for 15 years.
Before I show you how I do it, let me share with you what it means to learn programming.
Introduction
The code you write reflects the way you think. The code itself is just a way to have a conversation with the engine that is the computer that executes your code in a runtime context.
Computers do not communicate the way people communicate. But the nature of communication itself is fundamentally the same.
How People Communicate
People communicate through influence. Influence is a general form of communication that incorporates thoughts, beliefs, and emotions. We use metaphors, body language, and social context to communicate indirectly.
People “know what you mean”, even if you don’t specifically say it. And people remember how you make them feel more clearly than specifically what you say.
Systems do not work this way. Period.
How Systems Communicate
Systems communicate through control. They have no beliefs, emotions, or metaphors. They have no memory of how you make them feel. They simply do what you tell them to do.
Coding is a form of one-way communication from people to computers. The computer does not guess what you mean. It does not have the option to pause and ask for clarification. It does not have the option to ignore you. It simply does what you tell it to do.
If you leave gaps in your communication, the computer will fill in the gaps with its own assumptions. These assumptions become bugs. The assumptions may be accurate sometimes, even most of the time. But they will be wrong sometimes. And when they are wrong, the system will behave in unpredictable ways.
What It Means to Learn Programming
Learning to code is about thinking clearly. Until you think clearly, you will not be able to communicate clearly with the computer. And until you can communicate clearly with the computer, you will not be able to build reliable systems.
A reliable system is an aggregation of reliable components.
Here’s how I do it:
Understand CS Fundamentals
- Data Structures
- Algorithms
- SQL Databases
- Programming Languages
Distributed Systems Fundamentals
- Concurrency
- Clustering
- Distributed Transactions
- CAP & PACELC Theorems
- Polling, Long-Polling, and Pub-Sub
- ACID, BASE, and Eventual Consistency
- Consensus Protocols
- PAXOS,
- Virtual Synchrony
- Gossip Protocols
- Replication and Sharding
- Hashing and DHTs
- Cryptography
- Using keys and certificates for identity, integrity, and authenticity
- MapReduce
Software Engineering Fundamentals
- Version Control with Git and Github
- Agile, Scrum, Kanban
- CI/CD
System Design Fundamentals
- Observability and SLA/O/Is
- Metrics vs. Logs vs. Events
- Monoliths, Distributed Monoliths, and Microservices
- NoSQL Databases (column, document, and blob stores)
- Clustering and Proxies
- Rate Limiting, Load Balancing
- Caching (especially cache consistency)
- REST and JSON encoding
- GraphQL and projections
- GRPC and protobuf encoding
- Kafka and Avro encoding