I'm about two years into my software engineering career and have started feeling lost because of how quickly AI-assisted development has become part of the job. Early on, I learned backend development by reading documentation, studying existing code, debugging problems, and figuring things out myself. My first job gave me significant ownership of a backend project, and that hands-on experience made me genuinely excited about programming.
A few months ago, I joined a much larger company hoping to learn about large-scale systems from more experienced engineers. Instead, over the past six months I've become heavily dependent on AI tools and Cursor. My productivity has increased, but I feel like I'm losing the part of development that helped me learn. I used to carefully review generated code and make sure I understood it. Now the codebases are large enough that I often rely on the tool's understanding of the system instead of building that understanding myself.
I'm worried that, this early in my career, I'm becoming good at shipping code without developing strong engineering fundamentals. I raised the concern with my manager, who suggested using AI as a learning tool instead of relying on mentorship, but I'm not sure how to do that effectively.
How can I use AI without outsourcing the thinking and learning parts of engineering? If you were two years into your career today, what would you focus on learning? Should junior engineers use AI differently from more experienced developers?
4 Answers
Keep strengthening the skills that let you judge whether generated code is appropriate: data structures, databases, networking, operating systems, testing, security, debugging, and system design. In a large codebase, learn the boundaries and invariants of the system rather than trying to memorize every line.
For each task, try this workflow: understand the requirement, map the affected components, write a short design or implementation plan, implement a small piece, and test it before expanding. Ask AI to produce explanations, diagrams, alternatives, and review comments. You can also recreate unfamiliar behavior in a tiny throwaway project so you learn the underlying concept instead of merely accepting the generated solution.
Your long-term value will come from understanding problems, systems, and tradeoffs—not from typing every line manually. Learn how to clarify requirements with stakeholders, design clean interfaces, reason about failure modes, operate services, and explain technical decisions. Those skills make you better at using AI because you can tell when its proposal is incomplete or architecturally wrong.
At the same time, don’t accept the idea that coding fundamentals no longer matter. You still need enough hands-on practice to debug, read unfamiliar code, trace data flow, and understand runtime behavior. Set aside regular time for deliberate practice or a small personal project where you solve problems without an assistant. That will rebuild confidence without requiring you to abandon AI at work.
Use AI as a reviewer and tutor, not as an unquestioned implementation engine. Before asking it to change anything, write down your own understanding of the problem and a rough plan. Then ask the AI to critique the plan, identify edge cases, security concerns, and assumptions. Have it explain the relevant code and suggest tests, but make the final design decisions yourself.
A useful habit is to occasionally start a fresh conversation and ask the model to review the code as if someone else wrote it. Challenge confident claims and verify important details against documentation, tests, and the actual system. This lets you benefit from its speed while still practicing analysis.
There is no single correct rule such as never letting AI write production code. Real teams have delivery pressure, and refusing useful tools entirely can put you at a disadvantage. The important distinction is whether you remain accountable for the result.
Limit the size of generated changes, keep commits focused, require tests, and read every meaningful diff. AI is often useful for boilerplate, test cases, refactoring, documentation drafts, locating bugs, and exploring unfamiliar APIs. It is much less trustworthy when asked to make broad architectural changes without precise context. If you cannot explain why a change works and what could break, it is not ready to ship.
That balance matters because some teams measure delivery speed and do not leave much time for studying every detail. A practical compromise is to learn deeply on a few representative tasks, while using reviews, tests, and small changes to control risk on routine work.

A good test is to disable the assistant briefly for a small task and see where you get stuck. Use that difficulty to identify a specific gap—perhaps SQL, concurrency, testing, or deployment—and study that topic directly rather than trying to quit every tool at once.