In a randomised trial published in January 2026, 52 junior engineers were asked to learn an unfamiliar Python library. Half had an AI assistant; half had the documentation. The AI group scored 50% on a comprehension quiz afterwards. The manual group scored 67%.
The speed advantage that justifies reaching for the assistant did not appear either — the AI group finished about two minutes faster, a difference that was not statistically significant, and several spent 11 of their 40 minutes composing prompts.
That result reframes the whole question of how to get better at programming, because the fastest way to produce working code and the fastest way to become someone who can write it are now, measurably, different things. What follows is ten habits that survive that distinction.
Table of Contents
- 1. Practise Deliberately, Not Just Often
- 2. Use AI as a Tutor, Not a Contractor
- 3. Read More Code Than You Write
- 4. Get Your Code Reviewed by Someone Better Than You
- 5. Learn One New Language Every Year — For the Ideas
- 6. Rebuild Something You Already Built
- 7. Contribute to Open Source
- 8. Teach It to Somebody
- 9. Practise Problems Deliberately, Not Compulsively
- 10. Build Things Nobody Asked For
- What to Do This Month
- Key Takeaways
- Frequently Asked Questions
- Conclusion
1. Practise Deliberately, Not Just Often
Writing more code is not the same as getting better at writing code. Ten years of building the same CRUD screens produces one year of experience repeated ten times.
Deliberate practice means working at the edge of what you can currently do, where you fail often enough to learn something. The signal you are in the right place is discomfort: if the code flows without difficulty, you are rehearsing rather than practising.
Concrete version of this habit: pick one thing per month you cannot currently do — write a parser, implement a B-tree, build a toy interpreter — and do it badly, then read a good implementation and do it again.
2. Use AI as a Tutor, Not a Contractor
This is the habit that changed most in the last three years, and the evidence on it is unusually specific.
The trial above found that how you use the assistant mattered more than whether you used it. Participants who asked conceptual questions — “how does this work”, “why is this the idiomatic approach” — retained the material. Participants who delegated wholesale — “write this for me”, “fix this bug” — did not, and the steepest decline was in debugging skill specifically.
The practical rule: ask for explanations, not implementations. When you do generate code, immediately ask why it works, then write it again yourself without looking. The friction you are removing is the friction that produces learning.
The researchers are careful about the limits of their own study, and so should you be: the sample was 52 people, comprehension was measured immediately rather than months later, and the setup used a sidebar assistant rather than an agentic coding tool. Anthropic, who ran it, notes that effects with agentic tools may be more pronounced rather than less.
There is a second-order reason to take this seriously. Employment data from the same period shows entry-level developer roles contracting sharply — Stanford’s 2026 AI Index reports employment for developers aged 22–25 down nearly 20% since late 2022, while employment for older developers at the same firms grew. If the junior roles where skills were traditionally built are shrinking, the responsibility for building them shifts to you.
3. Read More Code Than You Write
Most programmers write far more code than they read, which is backwards. Reading exposes you to solutions you would not have invented and to conventions you would not have guessed.
Where to start, in increasing difficulty: the standard library of a language you use, a small well-regarded tool (SQLite, Redis, curl), then a subsystem of something large. Do not try to read a whole codebase — pick one feature and trace it end to end.
Concrete version: every time you use a library function you do not fully understand, open its implementation. Most of the time it is shorter than you expect. Our list of C and C++ source code sites is a starting point for finding readable projects.
4. Get Your Code Reviewed by Someone Better Than You
Code review is the highest-bandwidth feedback available to a programmer, and most people under-use it by treating it as an approval gate rather than a conversation.
Ask for the review you actually need. “Does this look right?” invites a rubber stamp. “I chose a hash map here over a sorted vector — is that wrong?” invites the answer you want.
If you have no reviewer, automated review is a partial substitute: static analysis catches a real class of defect before a human sees it, and the guide to static code analysis tools covers what each one actually finds.
5. Learn One New Language Every Year — For the Ideas
The Pragmatic Programmer’s advice, and it is still sound, but the reason matters more than the rule. The point is not to add languages to a CV; it is that each paradigm changes what you notice.
Learning a functional language makes you see mutable state everywhere afterwards. Learning C makes memory visible. Learning a language with a strong type system changes how you think about making invalid states unrepresentable.
Choose for contrast, not similarity. If you write C++, learning Java will teach you less than learning Haskell, Rust or Lisp.
6. Rebuild Something You Already Built
Looking back at old code and wincing is the most reliable evidence of growth there is — but the habit is more useful if you go one step further and rebuild rather than just cringe.
Reimplementing something you understand removes the problem-solving load and leaves only the craft. You already know what it should do, so all your attention goes on how it should be structured.
Concrete version: take a project from two years ago and rewrite one module. The diff is a measurement of what you have learned.
7. Contribute to Open Source
Open source solves the two hardest problems in deliberate practice: finding a real problem to work on, and getting expert feedback for free.
The persistent myth is that you need expertise to contribute. The opposite is closer to true — projects are usually short of people willing to improve documentation, reproduce bug reports, and write tests, and those tasks are how you learn a codebase.
Concrete first contribution: find a project you actually use, look for issues tagged good first issue, and read the contributing guide before writing anything. Your first pull request being rejected is a normal and useful outcome.
8. Teach It to Somebody
Explaining something is the fastest way to find the parts you do not actually understand. The effect is well established in education research, where it goes by the name of the protégé effect — people learn material better when they expect to teach it, and better again when they do.
Concrete versions, in increasing difficulty: answer a question on Stack Overflow, write up a bug you solved, give a lunchtime talk to your team, write a tutorial.
The failure mode to watch for: if your explanation relies on “it just works this way”, you have found a gap rather than an explanation.
9. Practise Problems Deliberately, Not Compulsively
Competitive programming and interview-style problems build a specific and genuinely useful skill: recognising which algorithm a disguised problem needs. They do not build software design skill, and treating them as general practice is a common mistake.
Use them for what they are good at. A focused month on programming contests and challenges before an interview is well spent; five years of daily problem-solving in place of building things is not.
Concrete version: when you fail to solve one, do not read the solution immediately. Sit with it for a day. The solution you read after struggling sticks; the one you read after five minutes does not.
10. Build Things Nobody Asked For
Every habit above is a way of improving at somebody else’s problem. Personal projects are where you choose the problem, which means you also choose the constraints — and constraint choice is most of engineering.
Pick projects with a forcing function. “Learn Rust” is not a project. “Write a Redis clone in Rust that passes the real Redis test suite” is, because it tells you when you are done and when you are wrong.
If you need structure rather than a blank page, working through a free programming course alongside a project gives you both.
What to Do This Month
Ten habits is a reading list, not a plan. If you want one:
- Pick one thing you cannot do and spend the month failing at it (habit 1).
- Change how you prompt. For four weeks, ask AI assistants only for explanations, never implementations (habit 2).
- Read one implementation of something you use daily (habit 3).
- Ask one specific question in your next code review (habit 4).
That is four habits, one month, and all of them are free.
Key Takeaways
- How you use AI matters more than whether you use it. In a 2026 randomised trial, developers who asked for explanations scored 67% on comprehension; those who delegated code scored 50%.
- The expected speed benefit did not appear in that trial — about two minutes over 40, not statistically significant.
- Deliberate practice means discomfort. If the code flows easily you are rehearsing, not learning.
- Read more code than you write, and read implementations of things you already use.
- Learn languages for contrast, not for the CV. A different paradigm changes what you notice.
- Rebuild old projects. The diff between the old version and the new one is the clearest measurement of progress you will get.
- Competitive programming builds one specific skill. Use it before interviews; do not mistake it for general practice.
Frequently Asked Questions
Conclusion
Most advice on improving as a programmer has been stable for decades — practise, read code, take feedback, teach — and the reason it is stable is that it describes how people learn anything difficult. None of that is obsolete.
What changed is the cost of the shortcut. It has never been easier to produce working code you do not understand, and the evidence now suggests that doing so has a measurable price in comprehension and especially in debugging skill. The habits above all share a property worth noticing: each one deliberately keeps some friction in place. That is not nostalgia for doing things the hard way. It is that the friction is where the learning was all along. The software development section covers the practices these habits feed into.




