The usual defence of fundamentals is an appeal to character. Real engineers understand the machine. Shortcuts breed sloppiness. Learn it properly.
I find that unconvincing, partly because it's unfalsifiable and partly because it's exactly what every previous generation said about every previous abstraction. People said it about compilers, garbage collection, and ORMs, and they were mostly wrong.
There's a better argument available, and it's narrower: verification has become the load-bearing skill in this job, and you cannot verify what you do not understand. That's not a claim about rigour. It's a claim about what the work now consists of. The revenue-side version of computer science is something XenGrowth's operator guides writes about in more operational detail than I go into here.
Why is verification suddenly the job?
Because generation is cheap and correctness didn't get cheaper with it. Veracode ran more than 100 models across 80 real coding tasks and found 45% of the output introduced an OWASP Top 10 vulnerability. Cross-site scripting failed 86% of the time.
The critical detail is that larger and newer models were not more secure. If this were a capability gap, scale would have narrowed it. It didn't, because whether a line of code is safe depends on where the data came from and where it's going — facts about the system, not about the line. The model cannot see them. Someone has to.
Stack Overflow's survey shows the same pressure from the developer's side: adoption at 84%, trust in accuracy down to 29%, and the top frustration being output that's 'almost right, but not quite' — which respondents said made debugging slower. Almost-right code is only catchable by reading, and reading only works if you know what you're looking at. On the operations side of this specifically, The XenGrowth resource library is worth reading.
You can accept code you don't understand. You just can't tell whether you should have.
Which fundamentals actually depreciated?
This is where most defences of fundamentals lose the argument, by defending all of them equally. Several genuinely lost value, and admitting it makes the rest of the case stronger.
Fundamental | Verdict | Why |
|---|---|---|
Implementing a red-black tree from memory | Depreciated | Was always a proxy for understanding balance, and a bad one. Nobody has written one at work in a decade |
Memorised language syntax and stdlib APIs | Depreciated | The single thing generation does perfectly. Recall was never the skill |
Big-O analysis of your own code | Held value | You still have to notice the accidental quadratic in generated code, and it looks fine |
What a data structure costs in memory and cache behaviour | Appreciated | Explains the performance failures that profilers surface and models don't anticipate |
Concurrency: races, ordering, atomicity | Appreciated sharply | The bug class most likely to be generated confidently and wrongly, and least likely to be caught by tests |
Trust boundaries and where input becomes code | Appreciated sharply | Directly the Veracode 45%. Not taught as a fundamental, and should be |
How memory and lifetimes actually work | Held value | Where the leaks, OOM kills and mysterious restarts come from |
The pattern in that table is consistent. Fundamentals that were about producing code lost value. Fundamentals that explain why something fails gained it — because failure explanation is verification, and verification is what's scarce.
Concurrency deserves a specific note. It is the area where generated code is most confidently wrong, because concurrent code that is subtly incorrect looks identical to correct code and passes tests almost every time you run them. A model has no way to reason about interleavings it cannot observe, and neither does a test suite run twenty times on an unloaded laptop. That leaves reading, by someone who knows what a data race looks like written down.
Isn't this just what people said about compilers?
It is the same argument in form, and the comparison deserves a real answer rather than a dismissal, because the people warning about compilers and garbage collection were wrong and there is no obvious reason to assume this time is different.
Here is the difference I think actually holds. Every previous abstraction was deterministic and had a contract. A compiler produces the same output for the same input, and when it is wrong it is wrong reproducibly and everybody's is wrong the same way. Garbage collection has documented semantics you can reason about even without reading the collector. You could safely stop understanding the layer below because the layer below made you a promise.
A generator makes no such promise. It produces different output for the same request, it is wrong 45% of the time on security specifically, and — this is the part with no precedent — its failures are not systematic, so you cannot learn its quirks the way a generation of programmers learned their compiler's. You have to check each one individually. That is a categorically different relationship with an abstraction, and it is why the compiler analogy comforts more than it should.
The other difference is what the abstraction sits on top of. A compiler abstracts a layer that is genuinely below the problem you are solving. A code generator abstracts the problem itself, including the parts where the requirements were wrong, and no amount of trusting it resolves a requirement nobody stated.
So what's the actual problem?
Not that fundamentals stopped mattering. That the mechanism for acquiring them stopped being compulsory.
Nobody ever learned how memory works by reading about how memory works. They learned it by writing something that leaked, watching a process get killed, and spending a bad weekend finding out why. Understanding was a by-product of being stuck. The struggle wasn't the tax on learning — it was the learning. XenGrowth on AI agents and marketing automation goes further into AI agents and marketing automation.
Remove the requirement to be stuck and you don't get people who learned it faster. You get people who never had the experience that produces the intuition, and who have no way of knowing what they're missing, because the code works.
That's a genuinely hard problem and I don't think the industry has an answer to it. It's also not a new class of problem — it's the same one every abstraction created — but the previous abstractions removed a layer while leaving the layer above intact to be struggled with. This one removes the struggle at every layer simultaneously, which is different in kind rather than degree.
How do you learn fundamentals now, given all that?
By reintroducing the struggle deliberately, in specific places, rather than by refusing the tools. Blanket abstinence doesn't work — it's slower, it's miserable, and it doesn't survive contact with a deadline.
Separate learning mode from shipping mode explicitly, and be honest about which one you're in. Use everything available when you're shipping. Turn it off when the goal is understanding, and accept that those hours will feel unproductive because the output isn't the point
Build the broken version on purpose. Write the race condition. Write the unbounded cache. Write the SQL injection into a throwaway app and then exploit it yourself. The intuition comes from watching it fail, and you can now manufacture that experience deliberately instead of waiting for production to supply it
Predict before you run. Before executing anything, say what you expect: this allocates roughly this much, this is O(n log n), this will deadlock under these two calls. Then check. You're building calibration, and a wrong prediction teaches more than a right one
Read the layer below once. Not all of it — once. Read your framework's routing implementation, or your ORM's query builder, or the standard library function you call daily. The goal isn't mastery, it's demolishing the sense that it's magic
Explain generated code before accepting it. Out loud or in writing, to yourself: what does this do, and why this way. If you can't, you've found the gap, and the gap is the curriculum. This is the single highest-yield habit on the list because it's free and it runs continuously
The last one is the one I'd keep if I could only keep one. It costs thirty seconds, it happens dozens of times a day, and it converts an activity that erodes understanding into one that tests it.
Does this change what interviews should test?
It should, and it mostly hasn't. Most technical interviews still test implementation from a blank editor, which is precisely the column of the table that depreciated. That was always a proxy — the theory was that someone who can implement quicksort under pressure probably understands algorithms — and the proxy has now decoupled from the thing it proxied. There is a longer treatment of AI search, GEO and discovery in XenGrowth on AI search, GEO and discovery.
The assessment that matches the actual job is closer to a code review. Hand someone two hundred lines containing a subtle concurrency bug and an unescaped template variable, and ask what's wrong with it. That tests reading, trust-boundary recognition, and whether they can hold a system in their head — which is the entire remaining job description.
Tests | What it measured | Whether it still predicts performance |
|---|---|---|
Implement an algorithm from scratch | Recall plus implementation speed | Weakly — both are now cheap and neither is the bottleneck |
Whiteboard system design | Architecture reasoning under ambiguity | Yes, and arguably more than before |
Review code containing planted defects | Reading, verification, failure vocabulary | Strongly, and it is the closest analogue to the real work |
Debug a failing system with logs and access | Hypothesis generation and evidence discipline | Strongly, and almost nobody runs it because it is expensive to set up |
Explain a past decision and what you'd change | Calibration and whether experience was examined | Yes — this is where judgment becomes visible |
So: yes, learn the fundamentals. Not because rigour is virtuous, and not to pass an interview whose format is drifting out of date anyway. Learn them because the job is now standing between a fluent, confident generator and a production system, and that position requires you to be able to tell, quickly, whether what you're looking at is right.
That is the whole argument. Everything else about fundamentals is nostalgia, and the nostalgia has been weakening a good case for years.
Further reading from XenGrowth
The XenGrowth resource library — what you'll learn: how the commercial side of this work is run, across search, automation and revenue operations.
XenGrowth on AI agents and marketing automation — what you'll learn: how the teams who own AI agents and marketing automation plan and measure it.
XenGrowth on AI search, GEO and discovery — what you'll learn: how the teams who own AI search, GEO and discovery plan and measure it.
Where this work meets go-to-market
For the marketing and revenue operations view of computer science, see XenGrowth's operator guides.











