First, the cloud gave us abstractions that made it easier to forget failure. Infrastructure became someone else's problem, and many systems were designed around happy paths with reliability added later ... managed services remain up ...
Now, it is an AI speed-at-all-costs culture that is forcing us to ship code that just works 80% of the time, because it is okay if things fail 20% of the time, but we need to ship faster.
Software was supposed to be predictable. Somewhere along the way, we started treating reliability as a tradeoff, and it is now becoming the norm. I do hope we come back to building software that people can depend on and something we are proud of.
A small experiment with Claude Code:
Hotel room search, built twice.
1) Vaadin + Spring Boot + jOOQ + Testcontainers + PostgreSQL: 3 minutes.
2) Angular + Python + DynamoDB: about 5x longer.
Why the gap? One stack is one language, one runtime, and a clear data model. The other is two ecosystems, two languages, and design decisions that need to be made up front.
Choose your tech stack wisely.
"Do fundamentals still matter?" The moral high ground says - they do, and I agree. But the motivation loop that made people great at fundamentals is broken.
Fundamentals were rewarding because we immediately applied them to solve problems better and, more importantly, gave us an edge over others. Say we write a wire protocol - then concepts like endianness come in handy when we serialize the data and solve our problem. That tight feedback loop is what drove curiosity.
But with AI handling the implementation, we skip from "I have a problem" straight to "it's solved," without the middle step where understanding actually forms. We can still force ourselves to study the output afterward, but reviewing someone else's (AI) solution is very different from building it ourselves.
Honestly, some fundamentals will be valuable to understand conceptually, but rarely practiced. Others will become even more critical because they are what you need to evaluate AI output and catch what it gets wrong.
The hard part is that we are living through the transition. Nobody knows which fundamentals will fade and which will become indispensable.
But until that becomes clear, I would still bet on building strong fundamental muscles for problem-solving.
Let me talk about something obvious but with a bit of quantification...
Theoretically, both arrays and linked lists take O(n) time to traverse, but here's what actually happens when you benchmark by summing 100k integers
- Array: 68,312 ns
- Linked List: 181,567 ns
Summing an array is ~3x faster than LinkedList. Same algorithm, same complexity, but wildly different performance.
The reason is cache behavior. When you access array[0], the CPU fetches an entire cache line (64 bytes), which includes array[0] through array[15]. The next 15 accesses are essentially free. Arrays hit the cache about 94% of the time.
Linked lists suffer from pointer chasing. Each node is allocated separately by malloc(), scattered randomly in memory. Each access likely requires a new cache line fetch, resulting in a 70% cache miss rate.
This is a good example of why Big O notation tells only part of the story. Spatial locality and cache-friendliness can make a 2-3x difference even when the theoretical complexity is identical.
I am sure you would have known this, but this crude benchmark quantifies just how fast cache-friendly algorithms can be.
Hope this helps.