Give me six hours to chop down a tree and I will spend the first four sharpening the axe. (Abraham Lincoln)
A collection of full-stack resources for programmers.
The goal of this page is to make you a more proficient developer. You’ll find only resources that I’ve found truly inspiring, or that have become timeless classics.
Principles
This page is not meant to be comprehensive. I am trying to keep it light and not too overwhelming.
The selection of articles is opinionated.
I don’t necessarily agree with or endorse every single line that is written in every single one of those resources. The same applies to their authors: I don’t endorse everything each of those authors has said and will ever say.
Items:
🧰 : list of resources
📖 : book
🎞 : video/movie extract/movie/talk
🏙 : slides/presentation
⭐️ : must-read
📃 : paper
Contributing to this list
Feel free to open a PR to contribute!
I will not be adding everything: as stated above, I am trying to keep the list concise.
📖 Release It!: this books goes beyond code and gives you best practices for building production-ready software. It will give you about 3 years worth of real-world experience.
📖 Structure and interpretation of Computer Programs (free): One of the most influential textbooks in Computer Science (written and used at MIT), SICP has been influential in CS education. Byte recommended SICP “for professional programmers who are really interested in their profession”.
There are some free books available, including:
📖 Professional software development: pretty complete and a good companion to this page. The free chapters are mostly focused on software development processes: design, testing, code writing, etc. - and not so much about tech itself.
A good high-level summary of fundamental engineering practices.
The root cause of bad software has less to do with specific engineering choices, and more to do with how development projects are managed.
There is no such thing as platonically good engineering: it depends on your needs and the practical problems you encounter.
Software should be treated not as a static product, but as a living manifestation of the development team’s collective understanding.
Software projects rarely fail because they are too small; they fail because they get too big.
Beware of bureaucratic goals masquerading as problem statements. If our end goal is to make citizens’ lives better, we need to explicitly acknowledge the things that are making their lives worse.
Building software is not about avoiding failure; it is about strategically failing as fast as possible to get the information you need to build something good.
If you (or your team) are shooting yourselves in the foot constantly, fix the gun
Assess the trade-off you’re making between quality and pace, make sure it’s appropriate for your context
Spending time sharpening the axe is almost always worth it
If you can’t easily explain why something is difficult, then it’s incidental complexity, which is probably worth addressing
Try to solve bugs one layer deeper
Don’t underestimate the value of digging into history to investigate some bugs
Bad code gives you feedback, perfect code doesn’t. Err on the side of writing bad code
Make debugging easier
When working on a team, you should usually ask the question
Shipping cadence matters a lot. Think hard about what will get you shipping quickly and often
Expert Generalists, martinfowler.com, proposes an interesting take on the “T-shaped engineer”
The Characteristics of an Expert Generalist: Curiosity, Collaborativeness, Customer Focus, Favor Fundamental Knowledge, Blend of Generalist and Specialist Skills, Sympathy for Related Domains
Assessing Expert Generalists: hiring and career progression
Growing Expert Generalists: From Tools to Fundamentals
“Why does our attention keep drifting toward tool expertise? It isn’t because people are shortsighted or lazy; it’s because the fundamentals are hard to see amid the noise.”
Expert Generalists still need Specialists
Expert Generalists in the Age of LLMs
“Similarly to a specialist, an LLM can rapidly answer questions that an Expert Generalist will have when working in a new domain.”
“Rather than looking for “the answer”, they prompt them to generate questions, explaining mechanisms, and providing examples and even tools that help explore the underlying mechanisms of an idea.”
One hundred lines of simplicity is better than twenty lines of complexity.
If your abstractions are leaking, it’s not due to some law of the universe; you just suck at abstracting. Usually, you didn’t specify the abstraction narrowly enough.
If you avoid changing a section of code for fear of awakening the demons therein, you are living in fear. If you stay in the comfortable confines of the small section of the code you wrote or know well, you will never write legendary code. All code was written by humans and can be mastered by humans.
If there’s clearly a right way to do something and a wrong way, do it the right way. Coding requires incredible discipline.
The best way to get the right answer is to try it the wrong way.
Practice tells you that things are good or bad; theory tells you why.
Not being qualified to solve a problem is no reason not to solve it.
If you don’t understand a system you’re using, you don’t control it. If nobody understands the system, the system is in control.
The Missing Semester of Your CS Education, MIT. Includes lectures about the shell, editors, data wrangling, git, debugging and profiling, meta programming, security and cryptography.
“Using links instead of foreign keys to express relationships in APIs reduces the amount of information a client needs to know to use an API, and reduces the ways in which clients and servers are coupled to each other.”
In the triumvirate of software, product managers, designers, and software engineers, only the engineers are expected to turn off their creative minds and just produce.
Both engineers and product managers tend to think, incorrectly, that product specifications or requirements are equivalent to the furniture manual from Ikea.
This is one of the top things that make engineers grumpy: constantly shifting priorities.
Even though many engineers will complain that product managers change their minds, almost none will account for that in their time estimates.
Computer science programs aren’t about preparing you for the tasks you’ll face in industry.
When there are more engineers than can be used, engineering time ends up going away from developing and towards planning, synchronization, and coordination.
Great product engineers know that minimum lovable products need the right depth
Product-minded engineers quickly map out edge cases and think of ways to reduce work on them: often bringing solutions that require no engineering work
Engage in user research and customer support
Bring well-backed product suggestions to the table
If you want to make progress on the things that matter most, you need to decide who you’re going to disappoint. It’s inevitable.
The best investment you can make is your own education. Never stop learning. The second best investment you can make is building your network through authentic and meaningful interactions. It is what you know and who you know.
You’ll never get what you don’t ask for or actively seek out. Go for it!
It’s not about the light at the end of the tunnel. It’s the tunnel. Show up every day and enjoy the process.
A great teammate always puts the organization and its purpose ahead of their own self interests.
Pick your spots. We have limited time and our brains can only process so much. Focus is key. Choose wisely.
Every person is likely struggling with something. Be kind. Be helpful.
Beginner’s mind accepts the fact that absolute knowledge is infinite and thus keeping score is a waste of time.
Mastery is simply the accumulation of momentum, not the accumulation of knowledge.
Dealing with ego distraction has taught me to love the problem solving process. It’s taught me to love and respect the learning process. As a result I’m more productive. I’m less anxious. I’m a better teammate. I’m a better friend and a better thinker.
Imposter syndrome is underrated: a lot of talk goes into overcoming imposter syndrome. I say embrace self-skepticism and doubt yourself every day. In a fast-moving industry where lots of your knowledge expires every year, even the most junior people around you constantly cook up skills you don’t have; you stay competitive by applying with the determination (and even fear) of the novice. The upside of this treadmill is that every engineer is on it: just because you’re an imposter doesn’t mean that other people are more deserving than you, because they’re imposters too. You should advocate for yourself, take risks, pat yourself on the back when things go well, and, as you start to build a track record of solving problems, trust your skills and adaptability. Just make no mistake: you’re only as good as the last problem you solve.
Dan Heller, Building a Career in Software
I had learned already never to empty the well of my writing, but always to stop when there was still something there in the deep part of the well, and let it refill at night from the springs that fed it. – Ernest Hemingway
Biases don’t only apply to hiring. For instance, the fundamental attribution bias also applies when criticizing somebody’s code written a long time ago, in a totally different context.
The reason we want to buy as much as possible is that an organisation has a limited capacity for expertise, so we don’t want to have to become experts on things that don’t make up a competitive advantage.
If someone tells me they can build something cheaper than a vendor, I’m immediately skeptical because I don’t think most people can accurately forecast the actual cost of maintenance in the long term.
Advice you get is someone’s attempt to synthesize their experiences, not an accurate statement about how the world works.
Build a reservoir of prestige.
Some folks are so good at something that they end up being irreplaceable in their current role, which causes them to get stuck in their role even if they’re a good candidate for more interesting ones.
Great relationships will follow you everywhere you go. Bad ones too.
Early in your career, try to work at as many different kinds of companies and in different product vertical as you can.
The biggest gains come from combining disciplines.
Stop Avoiding Politics is a good contrarian take on the current (negative) connotation of the word “politics”.
In a way, it is unfortunate that “politics” got that connotation since Aristotle rightfully considered politics the highest form of practical wisdom, since it has to do with humans as social animals.
“Good politics is just being strategic about relationships and influence in the service of good outcomes.”
Examples: building relationships before you need them, understanding the incentives, managing up effectively, creating win-win situation, being visible.
“The alternative to good politics isn’t no politics. It’s bad politics winning by default. It’s the loud person who’s wrong getting their way because the quiet person who’s right won’t speak up.”
I’m not saying that it’s never appropriate to implement complex configuration, a rules-engine or a DSL, Indeed I would jump at the chance of building a DSL given the right requirements, but I am saying that you should understand the implications and recognise where you are on the clock before you go down that route.
Initially there was hope that non-technical business users would be able to use the GUI to configure the application, but that turned out to be a false hope; the mapping of business rules into the engine requires a level of expertise that only some members of the development team possess.
PACELC theorem: “in case of network partitioning (P) in a distributed computer system, one has to choose between availability (A) and consistency (C) (as per the CAP theorem), but else (E), even when the system is running normally in the absence of partitions, one has to choose between latency (L) and consistency (C).”
“The issue with the Five Whys is that it’s tunnel-visioned into a linear and simplistic explanation of how work gets done and events transpire.”
“Human error becomes a starting point, not a conclusion.” (Dekker, 2009)
“When we ask ‘how?’, we’re asking for a narrative.”
“When it comes to decisions and actions, we want to know how it made sense for someone to do what they did.”
At each “why” step, only one answer will be selected for further investigation. Asking “how” encourage broader exploration.
“In accident investigation, as in most other human endeavours, we fall prey to the What-You-Look-For-Is-What-You-Find or WYLFIWYF principle. This is a simple recognition of the fact that assumptions about what we are going to see (What-You-Look-For), to a large extent will determine what we actually find (What-You-Find).” (Hollnagel, 2009, p. 85) (see illustration of WYLFIWYF)
“A final reason why a ‘root cause’ may be selected is that it is politically acceptable as the identified cause. Other events or explanations may be excluded or not examined in depth because they raise issues that are embarrassing to the organization or its contractors or are politically unacceptable.” (Nancy Leveson, Engineering a Safer World, p. 20)
Bounded rationality: rational individuals will select a decision that is satisfactory rather than optimal
The article provide concrete ways and questions to solicit stories from people, which will yield better insights.
What were you expecting to happen?
If you had to describe the situation to your colleague at that point, what would you have told?
Did this situation fit a standard scenario?
What were you trying to achieve?Were there multiple goals at the same time?Was there time pressure or other limitations on what you could do?
📖 Design Patterns: Elements of Reusable Object-Oriented Software: dubbed “the gang of four”, this is almost a required reading for any developer. A lot of those are a bit overkill for Python (because everything is an object, and dynamic typing), but the main idea (composition is better than inheritance) definitely is a good philosophy.
📖 Clean Architecture, Robert C. Martin. Uncle Bob proposes an architecture that leverages the Single Responsibility Principle to its fullest. A great way to start a new codebase. Also checkout the clean architecture cheatsheet and this article.
📖 Game Programming Patterns: a book about design, sequencing, behavioral patterns and much more by Robert Nystrom explained through the medium of game programming. The book is also free to read online here.
Education of a Programmer: a developer’s thoughts after 35 years in the industry. There’s a particularly good section about design & complexity (see “the end to end argument”, “layering and componentization”).
Complexity and Strategy: interesting perspective on complexity and flexibility with really good examples (e.g. Google Apps Suite vs. Microsoft Office).
There are four properties of software systems which make building software hard: Complexity, Conformity, Changeability and Invisibility
There are ways to address this:
Exploiting the mass market to avoid constructing what can be bought. (“Buy vs. Build”)
Using rapid prototyping as part of a planned iteration in establishing software requirements.
Growing software organically, adding more and more function to systems as they are run, used, and tested
Identifying and developing the great conceptual designers of the rising generation.
(also included in The Mythical Man-Month)
Out of the Tar Pit, Ben Moseley, Peter Marks (2006) introduces the distinction between essential and accidental complexity
Complexity is the root cause of the vast majority of problems with software today. Unreliability, late delivery, lack of security — often even poor performance in large-scale systems can all be seen as deriving ultimately from unmanageable complexity.
Quoting Djikstra: “testing is hopelessly inadequate….(it) can be used very effectively to show the presence of bugs but never to show their absence.”
Functional programming goes a long way towards avoiding the problems of state-derived complexity, thanks to immutability and clear separation of state and logic.
Programming should be regarded as an activity by which the programmers form or achieve a certain kind of insight, a theory, of the matters at hand. This suggestion is in contrast to what appears to be a more common notion, that programming should be regarded as a production of a program and certain other texts.
The building of the program is the same as the building of the theory of it by the team of programmers.
A well-crafted monolith with truly isolated modules is often much more flexible than a bunch of microservices.
Three decades on, microkernel-based GNU Hurd is still in development, and monolithic Linux is everywhere
“Reduce cognitive load by limiting the number of choices.” (Rob Pike)
The same rule applies to all sorts of numeric statuses (in the database or wherever) - prefer self-describing strings.
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody. (Hyrum’s Law)
DDD is about problem space, not about solution space.
Familiarity is not the same as simplicity
The more mental models there are to learn, the longer it takes for a new developer to deliver value.
“Simplicity is a great virtue, but it requires hard work to achieve and education to appreciate. And to make matters worse, complexity sells better.”
— Edsger Dijkstra
You can use an eraser on the drafting table or a sledge hammer on the construction site. (Frank Lloyd Wright)
Simple Made Easy 🎞, Rich Hickey. This is an incredibly inspiring talk redefining simplicity, ease and complexity, and showing that solutions that look easy may actually harm your design.
Bram Moolenaar (Vim author), Seven habits of effective text editing (presentation). This is about Vim but it contains good lessons about why investing time in learning how to be productive with your text editors pays off.
VScode is one of the most popular text editors as of writing.
OO vs FP, Robert C. Martin, The Clean Code Blog. A pretty interesting take on the differences between OOP and FP from an expert in OOP.
OO is not about state. Objects are bags of functions, not bags of data.
Functional Programs, like OO Programs, are composed of functions that operate on data.
FP imposes discipline upon assignment.
OO imposes discipline on function pointers.
The principles of software design still apply, regardless of your programming style. The fact that you’ve decided to use a language that doesn’t have an assignment operator does not mean that you can ignore the Single Responsibility Principle.
Playbooks “reduce stress, the mean time to repair (MTTR), and the risk of human error.”
Using a template can be beneficial because starting from a blank document is incredibly hard.
The Curse of Knowledge is a cognitive bias that occurs when someone is communicating with others and unknowingly assumes the level of knowledge of the people they are communicating with.
Make your content easy to glance over.
If a script is longer than a single line, treat it like code, and check it into a repository to be source control and potentially tested.
Pages should be urgent, important, actionable, and real.
Err on the side of removing noisy alerts – over-monitoring is a harder problem to solve than under-monitoring.
Symptoms are a better way to capture more problems more comprehensively and robustly with less effort.
Include cause-based information in symptom-based pages or on dashboards, but avoid alerting directly on causes.
The further up your serving stack you go, the more distinct problems you catch in a single rule. But don’t go so far you can’t sufficiently distinguish what’s going on.
If you want a quiet oncall rotation, it’s imperative to have a system for dealing with things that need timely response, but are not imminently critical.
This classical article has now become a chapter in Google’s SRE book.
🏙 The Paradox of Alerts: why deleting 90% of your paging alerts can make your systems better, and how to craft an on-call rotation that engineers are happy to join.
Postmortem
A great example of a postmortem from Gitlab (01/31/2017) for an outage during which an engineer’s action caused the irremediable loss of 6 hours of data.
High reliability organisations — which have less than their fair share of accidents — recognise that human variability is a force to harness in averting errors, but they work hard to focus that variability and are constantly preoccupied with the possibility of failure
“Let’s plan for a future where we’re all as stupid as we are today.”
– Dan Milstein
Example outline for a postmortem:
Executive Summary
Impact
Root cause
Impact
Number of impacted users
Lost revenue
Duration
Team impact
Timeline
Detection
Resolution
Root cause analysis
E.g. with 5 whys method
Lessons learned
Things that went well
Things that went poorly
Action items (include direct links to task tracking tool)
Tasks to improve prevention (including training)
Tasks to improve detection (including monitoring and alerting)
Tasks to improve mitigation (including emergency response)
Note: this is about you as an interviewee, not as an interviewer. To check out my list of resources for interviewers, go to my engineering-management repository.
“As a medium, books are surprisingly bad at conveying knowledge, and readers mostly don’t realize it.”
“In learning sciences, we call this model “transmissionism.” It’s the notion that knowledge can be directly transmitted from teacher to student, like transcribing text from one page onto another. If only!”
“By re-testing yourself on material you’ve learned over expanding intervals, you can cheaply and reliably commit huge volumes of information to long-term memory.”
Stick to the minimum information principle: the material you learn must be formulated in as simple way as it is
Cloze deletion is easy and effective: Kaleida’s mission was to create a … It finally produced one, called Script X. But it took three years
Graphic deletion is as good as cloze deletion
Avoid sets
Avoid enumerations
Combat interference - even the simplest items can be completely intractable if they are similar to other items. Use examples, context cues, vivid illustrations, refer to emotions, and to your personal life
Personalize and provide examples - personalization might be the most effective way of building upon other memories. Your personal life is a gold mine of facts and events to refer to. As long as you build a collection for yourself, use personalization richly to build upon well established memories
Provide sources - sources help you manage the learning process, updating your knowledge, judging its reliability, or importance
Prioritize - effective learning is all about prioritizing.
Step 2: When you learn something, learn it to where you can explain it to a child.
Step 3: Instead of arbitrarily memorizing things, look for the explanation that makes it obvious.
Most people overestimate what they can do in 1 year and underestimate what they can do in a decade.
– Bill Gates
Frankly, though, I think most people can learn a lot more than they think they can. They sell themselves short without trying.
One bit of advice: it is important to view knowledge as sort of a semantic tree — make sure you understand the fundamental principles, ie the trunk and big branches, before you get into the details/leaves or there is nothing for them to hang on to.
— Elon Musk
“Experience is something you don’t get until just after you need it.”
― Steven Wright
Tell me and I forget. Teach me and I remember. Involve me and I learn.
– Benjamin Franklin
Education is the kindling of a flame, not the filling of a vessel.
– Socrates
That which we persist in doing becomes easier for us to do; not that the nature of the thing itself is changed, but that our power to do is increased.
– Ralph Waldo Emerson
A wise man can learn more from a foolish question than a fool can learn from a wise answer.
– Bruce Lee
A lecture has been well described as the process whereby the notes of the teacher become the notes of the student without passing through the mind of either.
— Mortimer Adler
Fools learn from experience. I prefer to learn from the experience of others.
— Bismark
Back to Basics, Joel Spolsky. Explains why learning low level programming is important.
I think that some of the biggest mistakes people make even at the highest architectural levels come from having a weak or broken understanding of a few simple things at the very lowest levels.
The Math Behind Artificial Intelligence - Tiago Monteiro. Covers linear algebra, calculus, probability, and optimization theory in the context of AI and machine learning.
Logging does not make much sense in monitoring and error tracking. Use better tools instead: error and business monitorings with alerts, versioning, event sourcing.
Logging adds significant complexity to your architecture. And it requires more testing. Use architecture patterns that will make logging an explicit part of your contracts
Logging is a whole infrastructure subsystem on its own. And quite a complex one. You will have to maintain it or to outsource this job to existing logging services
A good availability metric should be meaningful, proportional, and actionable. By “meaningful” we mean that it should capture what users experience. By “proportional” we mean that a change in the metric should be proportional to the change in user-perceived availability. By “actionable” we mean that the metric should give system owners insight into why availability for a period was low. This paper shows that none of the commonly used metrics satisfy these requirements…
Don’t even start considering solutions until you Understand the problem. Your goal should be to “solve” the problem mostly within the problem domain, not the solution domain.
eNumerate multiple candidate solutions. Don’t just start prodding at your favorite!
Sometimes smart thinkers just don’t know when to stop, and they create these absurd, all-encompassing, high-level pictures of the universe that are all good and fine, but don’t actually mean anything at all.
Your typical architecture astronaut will take a fact like “Napster is a peer-to-peer service for downloading music” and ignore everything but the architecture, thinking it’s interesting because it’s peer to peer, completely missing the point that it’s interesting because you can type the name of a song and listen to it right away.
“A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over, beginning with a working simple system.”
— John Gall, General systemantics, an essay on how systems work, and especially how they fail…, 1975 (this quote is sometime referred as “Galls’ law”)
“Software engineering is what happens to programming when you add time and other programmers.”
You can’t connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something — your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.
“The most surprising thing is that you wouldn’t let anyone steal your property, but you consistently let people steal your time, which is infinitely more valuable.” — Seneca
JavaScript and maybe another interpreted language (Python, Ruby, etc.). Interpreted languages are useful for quick one-off automation scripts, and fastest to write for interviews. JavaScript is ubiquitous.
Effective Programs - 10 Years of Clojure 🎞, Rich Hickey. The author of Clojure reflects on his programming experience and explains the rationale behind some of Clojure’s key design decisions.
These new perspectives, these ideas and patterns — they linger, they stay with you, even if you end up in another language. And that is powerful enough to keep on learning new languages, because one of the best things that can happen to you when you’re trying to solve a problem is a change of perspective.
I draw the line between declarative and non-declarative at whether you can trace the code as it runs. Regex is 100% declarative, as it’s untraceable while the pattern is being executed.
In 1-2 sentences, what is the book about as a whole?
What are the 3-4 central questions it tries to answer?
Summarize the answers in one paragraph each.
What are the most important things you have learned personally?
There was an interesting contrarian take in the Hacker News thread: “Once I relaxed and decided, ‘If the stuff in this book is good enough, my brain will keep it FOR me’ both my satisfaction AND utility of books increased dramatically.”
I read pretty slowly. I take notes, I underline, I highlight, I jot my thoughts in the margins, I pause if I encounter an especially interesting passage or idea.
“Listening to books instead of reading them is like drinking your vegetables instead of eating them”
“You will not learn anything of lasting importance from TV, movies, podcasts…they’re junk food. Successful people converge on 3 ways to learn: lots of reading time, some exercises and projects, and conversations with people who are slightly ahead of them.”
Every programmer ever born thinks whatever idea just popped out of their head into their editor is the most generalized, most flexible, most one-size-fits all solution that has ever been conceived.
It is three times as difficult to build reusable components as single use components.
A reusable component should be tried out in three different applications before it will be sufficiently general to accept into a reuse library.
It’s 2025 and it’s faster for me to have ChatGPT or Cursor whip up a dependency free implementation of these common functions, than it is for me to start figuring out a dependency.
The whole point of [actual] distributed systems engineering is you assume you’re going to fail at some point in time and you design the system in such a way that the damage, at each point is minimized, that recovery is quick, and that the risk is acceptably balanced with cost.
How can you cut the blast radius for a similar event in half?
Differentiate between deployment (0 risk) and release
Build a deploy-observe-release pipeline
Make incremental rollouts the norm (canaries, %-based rollouts, etc.)
Test configuration changes just like you test code
Default to roll back, avoid fixing forward (slow!)
Eliminate gray failures - prefer crashing to degrading in certain cases
Prefer loosely coupled services at the expense of latency or correctness
Use poison tasters (isolate handling of client input)
Implement per-request-class backpressure
Have proper visibility from a client/end-user standpoint (client-side metrics)
Written by members of Google’s SRE team, with a comprehensive analysis of the entire software lifecycle - how to build, deploy, monitor, and maintain large scale systems.
Canonical definition of TTD (Time To Detect) TTM (Mitigate), TTR (Recover), TBF (Time Between Failure)
Quotes:
Quality is a snapshot at the start of life and reliability is a motion picture of the day-by-day operation.
– NIST
Reliability is the one feature every customer users. – An auth0 SRE.
Articles:
I already mentioned the book Release it! above. There’s also a presentation from the author.
A Map of Sync categorizes state sync into 9 dimensions.
Data model:
Size: How large is the data set that a single client can access?
Update rate: How often do clients send updates?
Structure: Is the data rich with structure or flat and unstructured?
Systems requirements:
Input latency: How long can updates be delayed while maintaining a good user experience?
Offline: How many interactions does the app need to support offline?
Concurrent clients: How many concurrent clients will look at the same data?
Programming model:
Centralization: How centralized is the programming model and infrastructure? Flexibility: How flexible are sync policies, especially around conflict resolution?
Consistency: What types of invariants can the application assert about its data model, and how strong can these invariants be?
System administration
🧰 kahun/awesome-sysadmin: a curated list of amazingly awesome open source sysadmin resources
High Scalability: great blog about system architecture, its weekly review article are packed with numerous insights and interesting technology reviews. Checkout the all-times favorites.
Today, any code that a developer dislikes is branded as technical debt.
Ward Cunningham invented the debt metaphor to explain to his manager that building iteratively gave them working code faster, much like borrowing money to start a project, but that it was essential to keep paying down the debt, otherwise the interest payments would grind the project to a halt.
Ur-technical debt is generally not detectable by static analysis.
Be clear about the different types of tests that you want to write. Agree on the naming in your team and find consensus on the scope of each type of test.
Every single test in your test suite is additional baggage and doesn’t come for free.
Web Browser Engineering: this book explains how to build a basic but complete web browser, from networking to JavaScript, in a couple thousand lines of Python.
A URI is a string of characters that identifies a resource. Its syntax is <scheme>:<authority><path>?<query>#<fragment>, where only <scheme> and <path> are mandatory. URL and URN are URIs.
A URL is a string of characters that identifies a resource located on a computer network. Its syntax depends on its scheme. E.g. mailto:billg@microsoft.com.
A URN is a string of characters that uniquely identifies a resource. Its syntax is urn:<namespace identifier>:<namespace specific string>. E.g. urn:isbn:9780062301239
From the HN discussion: “Writing a couple of pages of design docs or an Amazon-style 6 pager or whatever might take a few days of work, but can save weeks or more of wasted implementation time when you realise your system design was flawed or it doesn’t address any real user needs.”
If you’ve done great work, if you’ve produced superb software or fixed a fault with an aeroplane or investigated a problem, without telling anyone you may as well not have bothered.
The reason writing a good 4 page memo is harder than “writing” a 20 page powerpoint is because the narrative structure of a good memo forces better thought and better understanding of what’s more important than what, and how things are related.
Powerpoint-style presentations somehow give permission to gloss over ideas, flatten out any sense of relative importance, and ignore the interconnectedness of ideas.
Table of Contents
Professional Programming - about this list
A collection of full-stack resources for programmers.
The goal of this page is to make you a more proficient developer. You’ll find only resources that I’ve found truly inspiring, or that have become timeless classics.
Principles
Items:
Contributing to this list
Feel free to open a PR to contribute!
I will not be adding everything: as stated above, I am trying to keep the list concise.
Must-read books
I’ve found these books incredibly inspiring:
There are some free books available, including:
Must-read articles
Other general material and list of resources
Other lists
Books
Articles
Axioms
Courses
Topics
Accounting
Algorithm and data structures
Other resources:
Here are some useful & interesting algo & DS visualizations:
Example implementations:
Algorithms in distributed systems:
API design & development
General REST content:
Example guidelines:
More specific topics:
Attitude, habits, mindset
Dan Heller, Building a Career in Software
Procrastination
Authentication/authorization
Automation
Best practices
Beyond software engineering & random
Biases
Biases don’t only apply to hiring. For instance, the fundamental attribution bias also applies when criticizing somebody’s code written a long time ago, in a totally different context.
Business
Buy vs. Build
Cache
Career growth
About senior engineers:
Choosing your next/first opportunity
Getting to Staff Eng
Characters sets
Chess
(yes - chess gets its own section :)
Clouds
Code reviews
Coding & code quality
isEachUserLoggedInis better thanareUsersLoggedInorisUsersLoggedIn)isPaidForis better thanwasPaidFor)isEnabledis better thanisDisabled)Communication
See also the Writing section
Compilers
Configuration
Continuous Integration (CI)
Data analysis & data science
Databases
See also the SQL section.
Scaling databases:
NoSQL
Postgres
“Just use postgres”:
Data formats
libphonenumber.Data science/data engineering
Debugging
Also see the Incident Response section in this doc
strace,tcpdump)Design (visual, UX, UI, typography)
I highly recommend reading The Non-Designer’s Design Book. This is a pretty short book that will give you some very actionable design advices.
Articles :
Typograhy: see “Typography” section
Resources:
Design (OO modeling, architecture, patterns, anti-patterns, etc.)
Here’s a list of good books:
One of the absolute references on architecture is Martin Fowler: checkout his Software Architecture Guide.
Articles:
Resources:
Design: database schema
created_at,created_byetc.Design: patterns
Design: simplicity
Dev environment & tools
Tools
MakefileArticle about tools:
Docker
See also the Python-specific section in charlax/python-education.
HEALTHCHECKin Docker Compose not your DockerfileRUN,COPY,ADD)COPYoverADDENTRYPOINTandCMDHEALTHCHECKinstructionlatesttag..dockerignorefile (include**/.git, etc.)hadolint)Documentation
Dotfiles
Articles
Editors & IDE
Vim
Feel free to check my vim configuration and my vim cheatsheet.
Other editors:
Email
Engineering management
Checkout my list of management resources.
Exercises
The best way to learn is to learn by doing.
Practice:
Experimentation
Functional programming (FP)
Games development
Graphics
Hardware
HTTP
Humor
O(1/N)algorithm.Incident response (oncall, alerting, outages, firefighting, postmortem)
Also see this section on my list of management resources, “Incident response”.
Also see the Debugging section in this doc.
Alerting:
Postmortem
Example outline for a postmortem:
Internet
Interviewing
Note: this is about you as an interviewee, not as an interviewer. To check out my list of resources for interviewers, go to my engineering-management repository.
Questions you should ask:
Résumé:
See also the exercises section in this document.
Kubernetes
Large Language Model (LLM)
Learning & memorizing
Learn how to learn!
About flashcards:
About Zettelkasten and PKM (personal knowledge management): see Personal knowledge management
Richard Feynman’s Learning Strategy:
Licenses (legal)
Linux (system management)
Low-code/no-code
Low-level, assembly
Machine learning/AI
Math
Marketing
Network
Observability (monitoring, logging, exception handling)
See also: Site Reliability Engineering (SRE)
Logging
Error/exception handling
Metrics
Monitoring
Open source
Operating system (OS)
Over-engineering
— John Gall, General systemantics, an essay on how systems work, and especially how they fail…, 1975 (this quote is sometime referred as “Galls’ law”)
— Rob Pike, Go at Google: Language Design in the Service of Software Engineering
— Steve Jobs
Performance
Personal knowledge management (PKM)
Personal productivity
Check out this section on my list of management resources, “Personal productivity”.
Perspective
Privacy
Problem solving
Product management for software engineers
See the Product management section on my entrepreneurship-resources list of resources.
Project management
See the Project management section on my engineering-management list of resources.
Programming languages
I would recommend learning:
A bit more reading:
– Bjarne Stroustrup (C++ creator)
List of resources:
Python
For Python check out my professional Python education repository.
JavaScript
In this repository: check ./training/front-end/
JavaScript is such a pervasive language that it’s almost required learning.
Garbage collection
Programming paradigm
Public speaking (presenting)
Reading
Refactoring
Regex
Releasing & deploying
Versioning
Checklists
Feature flags
Testing in production
Reliability
See also System architecture
Books:
Quotes:
Articles:
Resources:
Integration patterns (dependency management)
Resiliency
Search
Security
Training for developers:
List of resources:
Research papers
Shell (command line)
SQL
State
System administration
System architecture
See also Reliability, Scalability
Reading lists:
Blogs:
Books:
Articles:
Architecture patterns
Microservices/splitting a monolith
Scalability
See also: Reliability, System architecture
Site Reliability Engineering (SRE)
See: Reliability
Technical debt
Testing
Why test:
How to test:
Test pyramid:
End-to-end tests:
Tools
Type system
Typography
Version control (Git)
Learning Git, courses and books:
Cheat sheets:
More specific topics:
Work ethics, productivity & work/life balance
Check out this section on my list of engineering-management resources, “Personal productivity”.
Web development
In this repository: check training/web-dev/ and ./training/front-end/
Learning guide and resources:
Topics:
URLs:
<scheme>:<authority><path>?<query>#<fragment>, where only<scheme>and<path>are mandatory. URL and URN are URIs.mailto:billg@microsoft.com.urn:<namespace identifier>:<namespace specific string>. E.g.urn:isbn:9780062301239Writing (communication, blogging)
➡️ See also my engineering-management list
Guides & classes about technical writing:
Resources & inspiration for presentations
Keeping up-to-date
Website and RSS feeds (I use Feedly):
Security:
Newsletters:
Blogs:
Concepts
Glossary
My other lists