Software engineering is changing faster than at any point in recent memory.
A few years ago, AI-assisted development mostly meant autocomplete. Today, developers can ask an AI agent to inspect a repository, implement a feature, generate tests, debug an error, refactor several files, explain unfamiliar code, write database migrations, create API documentation, and review a pull request.
The obvious question is:
If AI can write increasingly large amounts of software, what happens to software engineers?
I think the wrong response is trying to compete with AI at typing code.
The better response is becoming the engineer who knows what should be built, how it should be designed, whether the generated implementation is correct, and how the entire system behaves in production.
AI is making code cheaper.
Engineering is not becoming cheaper.
In many ways, engineering judgment is becoming more valuable.
This article is about how software engineers can adapt to that change and remain valuable even as AI becomes dramatically better at writing code.
The uncomfortable truth: code generation is becoming a commodity
For decades, being able to translate requirements into working code was one of the most valuable skills in software development.
That is still valuable.
But the economics are changing.
Suppose a company needs:
- a CRUD dashboard
- REST APIs
- authentication
- database migrations
- validation
- unit tests
- a React interface
- Docker configuration
- CI/CD
- documentation
Five years ago, producing all of this required a significant amount of manual development.
Today, an experienced developer using modern AI tools can generate a large portion of it much faster.
The developer is still necessary, but the bottleneck has moved.
The difficult part increasingly becomes:
- understanding the actual requirement
- deciding the architecture
- defining boundaries
- identifying edge cases
- reviewing generated code
- protecting security
- handling failures
- designing data correctly
- operating the system
- deciding what should not be built
This distinction matters.
If your value proposition is:
"I can write controllers faster than another developer."
AI is becoming serious competition.
If your value proposition is:
"I can take an unclear business problem, design a maintainable system, use AI to accelerate implementation, verify the result, deploy it safely, and operate it at scale."
You are much harder to replace.
AI will not remove software engineering
It will remove parts of software engineering.
That has happened repeatedly throughout the history of our industry.
Developers once manually managed memory for almost everything.
Then garbage collection became common.
Developers once manually configured physical servers.
Then virtualization appeared.
Then cloud computing.
Then infrastructure as code.
Developers once manually created almost every UI component.
Then component libraries and frameworks became widespread.
Developers once manually searched documentation every time they forgot an API.
Then search engines, Stack Overflow, IDE intelligence, and eventually AI assistants changed that workflow.
Each abstraction removed work.
It did not remove software development.
Instead, developers started building more complicated systems.
AI is another abstraction layer, although potentially a much larger one.
The important question is therefore not:
"Will AI write code?"
It obviously will.
The important question is:
"What skills become valuable when producing code itself becomes significantly easier?"
That is where engineers should focus.
1. Stop identifying yourself by how much code you write
A common mistake developers make is measuring productivity through code production.
Lines of code.
Number of commits.
Number of endpoints.
Number of features implemented.
These were never particularly good measurements.
With AI, they become even less meaningful.
Consider two developers.
Developer A writes 3,000 lines of code implementing a complicated permission system.
Developer B realizes the requirements can be solved using the application's existing authorization model and implements the same functionality in 300 lines.
Who produced more value?
Probably Developer B.
Now add AI.
An AI agent might generate those 3,000 lines in minutes.
That does not automatically make the implementation good.
More code means:
- more paths to test
- more places for bugs
- more maintenance
- more cognitive load
- more security surface
- more dependencies
- more opportunities for inconsistent behavior
The valuable engineer is increasingly the person who knows which code does not need to exist.
2. Become excellent at problem decomposition
One of the most useful skills in AI-assisted development is breaking large problems into well-defined smaller problems.
Consider this requirement:
Build a notification system.
That sounds simple.
But an experienced engineer immediately starts asking questions.
What channels exist?
- SMS
- push notifications
- in-app notifications
- webhooks
Are notifications synchronous or asynchronous?
Can users configure preferences?
What happens when delivery fails?
Should retries occur?
How many retries?
Do we need idempotency?
Do notifications have priority levels?
How do we prevent duplicate delivery?
Should messages be localized?
Are there rate limits?
How will providers be switched?
Do we need delivery analytics?
How long should notification history be retained?
Do users need unread counters?
What happens when one provider goes down?
The difference between junior and senior engineering often exists inside these questions.
AI can generate a notification service.
But if your request is poorly structured, you may receive an implementation that looks impressive while failing under real production conditions.
Good engineers turn vague requirements into clear constraints.
For example:
Notification Service
Channels:
- Email
- SMS
- In-app
Delivery:
- Queue based
- At least once delivery
Requirements:
- Idempotency key for each message
- Exponential retry
- Maximum 5 attempts
- Dead letter queue after failure
- User-level channel preferences
- Provider abstraction
- Delivery logs
- Per-provider rate limiting
Volume:
- 1 million notifications/day
Latency:
- 95% of queued messages processed within 30 seconds
Now AI has something useful to work with.
Your ability to structure problems determines the quality of your AI-assisted output.
3. Learn system design
If there is one area I would recommend developers invest heavily in, it is system design.
AI can generate individual components quickly.
But real systems involve interactions between components.
Consider building something like Uber.
The UI might be relatively straightforward.
The difficult engineering questions are elsewhere.
How do you track drivers?
How frequently should location be updated?
Where should location data live?
How do you find nearby drivers efficiently?
What happens when two drivers accept the same request?
How do you prevent duplicate rides?
How do you process payments?
How do you handle unreliable mobile networks?
How do you synchronize ride state?
How do you scale WebSocket connections?
How do you distribute requests geographically?
How do you recover from partial failures?
How do you handle event ordering?
How do you detect fraudulent behavior?
AI can help implement each subsystem.
But somebody still needs to understand how they fit together.
That requires knowledge of:
- distributed systems
- databases
- networking
- queues
- caching
- concurrency
- consistency
- availability
- fault tolerance
- observability
- security
These concepts become more important as AI allows engineers to build larger systems faster.
4. Become very good at reading code
There is an interesting shift happening.
Historically, developers spent significant amounts of time writing code.
AI-assisted developers increasingly spend more time reviewing code.
Imagine an AI agent produces this pull request:
+2,847 lines
-431 lines
23 files changed
The AI claims:
Implemented payment retry logic with idempotency protection.
Your job is not finished.
It has barely started.
You need to understand:
- Does the implementation match the requirements?
- Can duplicate payments occur?
- Are transactions handled correctly?
- What happens when the payment provider times out?
- Is the retry logic safe?
- Is there a race condition?
- Are logs leaking payment information?
- Are errors observable?
- Are tests meaningful?
- Did the agent modify unrelated code?
The ability to understand unfamiliar code quickly becomes extremely valuable.
This means developers should practice:
- reading large codebases
- tracing execution paths
- understanding call graphs
- analyzing database queries
- identifying side effects
- recognizing architectural boundaries
- spotting suspicious abstractions
You do not want to become someone who can only produce software through prompts.
If an AI writes something you cannot understand, you do not really control the software.
5. Master debugging
AI is excellent when the problem is clearly described.
Production bugs often are not.
Imagine customers report:
Checkout occasionally freezes.
That is the entire bug report.
The logs show nothing obvious.
It only happens approximately 2 percent of the time.
Now you have an engineering investigation.
You might inspect:
Browser
↓
Load Balancer
↓
Application API
↓
Payment Service
↓
Database
↓
Queue
↓
External Payment Gateway
The problem might be:
- connection pool exhaustion
- database locks
- request timeout configuration
- payment gateway latency
- duplicate transaction locks
- Redis failure
- queue congestion
- race conditions
- frontend retry behavior
- DNS resolution
- network packet loss
AI can help investigate each possibility.
But someone still needs to form hypotheses and gather evidence.
Strong debugging requires a mental model of the system.
The typical process looks something like this:
Symptom
↓
Collect evidence
↓
Form hypothesis
↓
Design experiment
↓
Validate
↓
Identify root cause
↓
Implement fix
↓
Verify
↓
Prevent recurrence
Developers who can debug complicated systems will continue to be extremely valuable.
6. Learn how databases actually work
AI can generate SQL.
That does not mean the SQL is good.
For example:
SELECT *
FROM orders
WHERE user_id = 123
ORDER BY created_at DESC;
Looks fine.
Now imagine the orders table contains 500 million rows.
Suddenly questions appear.
Do we have an index?
Should it be:
INDEX(user_id)
or:
INDEX(user_id, created_at)
What does the query plan show?
Should old orders be archived?
Should the table be partitioned?
Would a read replica help?
What is the write volume?
What isolation level is being used?
Could this query contribute to lock contention?
AI can suggest answers.
But database performance depends heavily on actual workload.
Engineers should understand:
- indexes
- transactions
- isolation levels
- query plans
- locking
- normalization
- denormalization
- replication
- partitioning
- connection pools
- caching
Database mistakes often remain invisible during development and become expensive only after scale arrives.
7. Understand distributed systems
Once applications become large enough, distributed systems problems appear everywhere.
You may have:
Client
↓
API Gateway
↓
Authentication Service
↓
Order Service
↓
Payment Service
↓
Inventory Service
↓
Message Queue
↓
Notification Service
Now everything can fail independently.
The payment may succeed while your API request times out.
The message broker may deliver the same event twice.
Events may arrive in the wrong order.
A database may become temporarily unavailable.
Two services may disagree about state.
Understanding concepts such as these becomes important:
Idempotency
The same request should be safe to execute multiple times where required.
Eventual consistency
Different parts of the system may temporarily contain different states.
Retry strategies
Retries must avoid overwhelming an already failing dependency.
Circuit breakers
Stop repeatedly calling unhealthy services.
Dead-letter queues
Preserve messages that repeatedly fail processing.
Distributed tracing
Follow a request across multiple services.
Saga patterns
Coordinate multi-step business transactions without a global database transaction.
AI can implement these patterns.
But choosing the wrong pattern can make a system significantly more complicated.
Architecture is about knowing when complexity is justified.
8. Learn networking fundamentals
Many developers know frameworks extremely well but have only a vague understanding of what happens between:
fetch("/api/orders")
and the server receiving the request.
That knowledge becomes extremely useful during production incidents.
Understand:
- DNS
- TCP
- HTTP
- TLS
- proxies
- load balancers
- CDN behavior
- WebSockets
- connection pooling
- timeouts
- retries
- ports
- firewalls
When a customer says:
The website works on mobile data but not Wi-Fi.
Framework knowledge will probably not solve the problem.
Networking knowledge might.
9. Security knowledge becomes more important
AI makes software easier to produce.
Unfortunately, it also makes insecure software easier to produce.
Suppose an AI generates:
$user = User::find($request->user_id);
$user->update([
'role' => $request->role
]);
The code works.
But should the current user be able to modify that user?
Should they be able to assign the admin role?
Where is authorization?
Where is validation?
Could mass assignment create additional problems?
AI often optimizes toward "make the feature work."
Production engineers must think:
How can this feature fail or be abused?
Developers should understand:
- authentication
- authorization
- SQL injection
- XSS
- CSRF
- SSRF
- insecure direct object references
- secret management
- credential rotation
- API security
- encryption
- rate limiting
- dependency vulnerabilities
AI increases development speed.
Security review must keep pace.
10. Treat AI output like code from a very fast junior developer
This mental model is useful.
Imagine a developer who:
- types extremely quickly
- knows thousands of libraries
- never becomes tired
- can read enormous amounts of code
- produces solutions immediately
But this developer can also:
- misunderstand requirements
- invent APIs
- introduce security vulnerabilities
- over-engineer solutions
- miss subtle race conditions
- confidently explain incorrect assumptions
Would you deploy everything they wrote without review?
Probably not.
That is roughly how AI-generated code should be treated.
Use it aggressively.
Trust it selectively.
Verify important behavior.
11. Learn to give AI context, not just prompts
Developers often focus too much on "prompt engineering."
For serious software development, context engineering is more important.
Compare these requests.
Bad:
Create authentication.
Better:
Implement authentication using Laravel Sanctum.
Requirements:
- Existing User model must remain unchanged
- Authentication is API-only
- Use Form Requests for validation
- Controllers should contain no business logic
- Authentication logic belongs in AuthService
- Responses must use existing ApiResponse helper
- Add feature tests
- Do not add new dependencies
Even better is providing AI access to:
- architecture documentation
- coding standards
- database schema
- existing examples
- test conventions
- domain terminology
- repository structure
The quality of AI-generated code depends heavily on the quality of context.
12. Build architectural guardrails
This becomes particularly important when AI agents produce larger amounts of code.
Suppose your architecture requires:
Controller
↓
Service
↓
Repository
↓
Database
Without enforcement, AI might produce:
Controller
↓
Database
or:
Controller
↓
RandomHelper
↓
Repository
or place business logic directly inside routes.
Documentation helps.
Automated enforcement is better.
Use tools such as:
- static analysis
- linters
- dependency rules
- architectural tests
- type systems
- automated tests
- formatting rules
- CI checks
For example, architecture rules can enforce:
Controllers cannot directly access repositories.
Domain modules cannot import infrastructure modules.
Payment code cannot import UI modules.
When AI generates code, deterministic rules can reject invalid implementations automatically.
This creates an important pattern:
Human defines architecture
↓
AI generates implementation
↓
Automated rules validate structure
↓
Tests validate behavior
↓
Human reviews important decisions
That is significantly more scalable than manually inspecting everything.
13. Testing becomes more valuable, not less
AI can generate code faster than humans can manually verify it.
That means automated verification becomes critical.
Suppose an agent generates ten features in an afternoon.
Without tests, your verification burden becomes enormous.
With a strong test suite, you can quickly detect regressions.
Your development workflow might become:
Requirement
↓
AI implementation
↓
Static analysis
↓
Unit tests
↓
Integration tests
↓
Architecture tests
↓
Security checks
↓
Human review
Tests become part of the control system around AI.
A good engineer does not only ask:
Can AI write this feature?
They ask:
How will I know the feature is correct?
14. Learn observability
Many software bugs cannot be reproduced locally.
You need visibility into production.
That means understanding:
- structured logs
- metrics
- tracing
- dashboards
- alerts
- error tracking
Consider a request traveling through several systems.
POST /checkout
↓
Order API
↓
Inventory Service
↓
Payment Service
↓
Payment Gateway
Without tracing, you may only know:
Checkout failed.
With distributed tracing:
POST /checkout 4.8s
├── inventory.reserve 80ms
├── order.create 35ms
└── payment.charge 4.6s
└── external.gateway 4.5s
Now the problem becomes much easier to understand.
AI can help interpret telemetry.
But telemetry must exist first.
15. Learn cloud and infrastructure
You do not need to become a full-time DevOps engineer.
You should understand how software actually runs.
Learn the basics of:
- Linux
- containers
- Docker
- reverse proxies
- CI/CD
- cloud computing
- load balancing
- autoscaling
- DNS
- storage
- secrets
- monitoring
An engineer who can write an application but cannot understand its production environment has a major blind spot.
AI makes deploying software easier.
That means more developers will deploy software.
Production knowledge therefore becomes more valuable, not less.
16. Understand cost
A system can be technically correct and financially terrible.
Imagine an AI feature that sends every request to a powerful LLM.
Suppose:
100,000 users
× 20 requests/day
= 2,000,000 AI requests/day
A tiny architectural decision can suddenly become a major monthly expense.
The same applies to:
- database queries
- object storage
- bandwidth
- logging
- background jobs
- serverless execution
- API providers
Good engineers think about economics.
Questions include:
- Can this operation be cached?
- Can requests be batched?
- Does this data need permanent storage?
- Should this workload run asynchronously?
- Do we need this expensive model?
- Could a deterministic algorithm solve this?
- Can we reduce token consumption?
Engineering is not only about making systems work.
It is about making them sustainable.
17. Develop product thinking
This may be one of the biggest career advantages in the AI era.
Developers traditionally receive requirements:
Build feature X.
Strong product engineers ask:
Why?
Suppose somebody requests:
Add real-time notifications using WebSockets.
Before implementation, ask:
What problem are we solving?
Maybe users simply need to know when a report is finished.
A full WebSocket infrastructure might be unnecessary.
Possible alternatives:
Polling
Server-Sent Events
Push notifications
Email
Background refresh
WebSockets
The correct engineering solution depends on the product requirement.
AI can quickly implement the wrong solution.
Engineers must determine the right one.
18. Communication becomes a technical skill
The stereotype of the brilliant developer who cannot communicate becomes increasingly difficult to sustain.
Modern engineering involves constant communication with:
- product managers
- designers
- customers
- DevOps engineers
- security teams
- executives
- other developers
- AI agents
Engineers need to explain:
- trade-offs
- risks
- architecture
- timelines
- technical limitations
- failure scenarios
- alternative approaches
Consider the difference between:
We need to refactor the backend.
and:
Checkout failures are increasing because payment processing and order creation currently share one synchronous transaction. Separating payment processing into an asynchronous workflow would reduce request failures, but it requires approximately two weeks of engineering and introduces eventual consistency.
The second explanation allows the business to make a decision.
That is engineering communication.
19. Specialize, but understand the full system
There is a common debate:
Should developers become specialists or generalists?
The best answer is usually both.
You want depth in one or two areas.
For example:
Backend Engineering
↓
Laravel / .NET / Node.js
↓
Databases
↓
Distributed Systems
But you should understand adjacent systems:
Frontend
Cloud
Networking
Security
DevOps
Product
AI
You do not need expert-level knowledge everywhere.
You need enough knowledge to understand how your decisions affect the overall system.
This is sometimes called a T-shaped skill profile.
AI makes this particularly powerful because it can help fill temporary knowledge gaps while your deeper expertise provides judgment.
20. Do not become framework-dependent
Framework knowledge is useful.
Framework identity is dangerous.
If your professional identity is:
I am a Laravel developer.
then a major change in Laravel, PHP, or market demand can feel threatening.
A more durable identity is:
I am a backend engineer who currently uses Laravel heavily.
The difference is subtle but important.
Learn concepts underneath frameworks.
Instead of only learning:
Cache::remember(...)
understand:
- cache-aside
- TTL
- invalidation
- distributed caching
- cache stampedes
- consistency trade-offs
Instead of only learning:
DB::transaction(...)
understand:
- ACID
- locks
- isolation
- deadlocks
- transaction boundaries
Framework APIs change.
Engineering concepts survive much longer.
21. Learn multiple paradigms
You do not need to learn every programming language.
But learning different ecosystems expands how you think.
For example:
Laravel teaches productive web application development.
Go may teach simplicity and concurrency.
Rust forces you to think carefully about memory and ownership.
Java or C# introduces mature enterprise architecture patterns.
JavaScript exposes asynchronous programming deeply.
SQL teaches declarative thinking.
Functional languages introduce immutability and composition.
AI makes exploring new languages dramatically easier.
You can ask it:
I know Laravel.
Explain dependency injection in ASP.NET Core by comparing it with Laravel's service container.
Or:
Explain Go channels using concepts familiar to a Node.js developer.
Use AI as a learning accelerator.
22. Build things
Reading about AI will not prepare you for AI-assisted engineering.
Using it will.
Take a real project.
Build something with:
- authentication
- API
- database
- caching
- queues
- WebSockets
- background workers
- monitoring
- CI/CD
- production deployment
Use AI throughout the process.
But pay attention to where it succeeds and fails.
You will quickly discover something.
AI is extremely good when:
- requirements are precise
- patterns already exist
- tasks are local
- tests define expected behavior
- architecture is clear
AI becomes less reliable when:
- requirements are ambiguous
- multiple services interact
- business rules are undocumented
- bugs are non-deterministic
- infrastructure is involved
- historical architectural decisions matter
That experience is difficult to learn from tutorials.
23. Build reusable engineering systems
One major productivity advantage is creating reusable infrastructure.
Instead of asking AI to design your architecture from scratch for every project, build templates.
For example:
my-saas-template/
├── auth/
├── billing/
├── notifications/
├── queue/
├── monitoring/
├── logging/
├── docker/
├── ci/
└── tests/
Include:
- coding standards
- architecture guidelines
- authentication
- authorization
- error handling
- API conventions
- test infrastructure
- logging
- CI/CD
Then AI operates inside a known environment.
This produces far more predictable results.
24. Learn to manage AI agents
There is an emerging engineering skill that did not exist in the same form a few years ago.
Managing coding agents.
Instead of:
Developer → Code
the workflow becomes:
Developer
↓
Task definition
↓
AI agent
↓
Implementation
↓
Automated verification
↓
Developer review
Eventually one engineer may coordinate multiple agents.
For example:
Engineer
├── Agent A: Backend API
├── Agent B: Frontend
├── Agent C: Tests
├── Agent D: Documentation
└── Agent E: Code review
The engineer becomes partly an orchestrator.
But orchestration requires architecture.
Without clear boundaries, multiple agents can produce conflicting implementations.
The human must define:
- interfaces
- ownership
- constraints
- acceptance criteria
- architectural rules
This is much closer to technical leadership than traditional solo coding.
25. Use AI to increase your learning speed
One of the biggest opportunities of AI is not code generation.
It is education.
Previously, learning distributed systems might involve:
- books
- courses
- documentation
- blog posts
- experimentation
Those are still valuable.
But now you can have interactive explanations.
For example:
Explain database isolation levels using an e-commerce checkout example.
Then:
Show me how a race condition can happen under READ COMMITTED.
Then:
Write a PostgreSQL example that reproduces the race condition.
Then:
Show three ways to fix it and explain the trade-offs.
Then:
Quiz me on the concept.
This creates an incredibly powerful learning environment.
Developers who use AI only for generating CRUD code are missing a much larger opportunity.
26. Build your own judgment
There is one dangerous side effect of AI-assisted development.
You can appear more capable than you actually are.
A developer might generate:
- Kubernetes manifests
- distributed queues
- event-driven systems
- complex SQL
- encryption code
- OAuth flows
without truly understanding any of them.
Everything works until it does not.
Then the developer has no mental model for debugging the system.
Avoid this trap.
Whenever AI generates something important, ask:
Why does this work?
What assumptions does it make?
What can fail?
What alternatives exist?
What trade-offs were made?
How would this behave under load?
You do not need to manually write every line.
You should understand the important decisions.
27. Learn when not to use AI
AI is not automatically the best tool for every problem.
Sometimes writing five lines yourself is faster than describing them.
Sometimes deterministic tooling is safer.
Sometimes documentation is more authoritative.
Sometimes a compiler error tells you exactly what is wrong.
Sometimes production telemetry matters more than AI speculation.
Sometimes a simple shell command gives the answer immediately.
Good engineers choose tools based on the problem.
Not because the tool is fashionable.
28. Your GitHub activity may change
Traditional developer portfolios often emphasize commits.
In an AI-heavy development environment, commits may become less meaningful.
Imagine one engineer producing the equivalent implementation output of several developers because AI agents handle much of the mechanical work.
What becomes interesting instead?
Projects that demonstrate:
- architectural quality
- production readiness
- reliability
- scale
- thoughtful technical decisions
- documentation
- observability
- security
- real users
A small production system with thoughtful engineering can demonstrate more ability than hundreds of tutorial repositories.
29. Junior developers face the biggest challenge
Entry-level developers traditionally learned through tasks such as:
Create this CRUD page.
Fix this validation bug.
Add this endpoint.
Write this migration.
Update this component.
AI can already handle many of those tasks.
That creates a difficult question:
How do juniors gain experience if beginner tasks disappear?
The answer is not skipping fundamentals.
It is learning them faster.
Junior developers should spend serious time understanding:
- data structures
- algorithms
- HTTP
- SQL
- Git
- debugging
- operating systems
- networking
- testing
- software design
Then use AI to build significantly more projects than previous generations could.
A junior engineer who has built and operated ten serious applications with AI assistance may gain exposure to problems that previously required several years of work.
The opportunity is enormous if AI is used for learning rather than replacing thinking.
30. Senior developers must change too
Experience does not automatically protect someone from disruption.
A senior engineer who refuses AI may eventually compete against engineers of similar experience who use AI effectively.
Imagine two senior developers.
Both understand:
- architecture
- databases
- distributed systems
- product engineering
But one also uses AI effectively for:
- repository exploration
- test generation
- implementation
- refactoring
- documentation
- debugging
- research
That developer may be significantly faster.
The future is probably not:
AI vs developers
It is:
Developers using AI
vs
Developers not using AI effectively
31. A practical AI-assisted engineering workflow
Here is a workflow I think works well.
Step 1: Understand the problem yourself
Do not immediately ask AI to code.
Write:
Problem
Constraints
Expected behavior
Edge cases
Performance requirements
Security requirements
Step 2: Design the architecture
Define:
Components
Responsibilities
Data model
Interfaces
Dependencies
Failure modes
You can ask AI to critique your design.
Do not automatically ask AI to make every architectural decision.
Step 3: Define acceptance criteria
Example:
Given a user has already paid an invoice,
when the payment webhook is delivered again,
the system must not create another payment.
Acceptance criteria reduce ambiguity.
Step 4: Ask AI to implement a small slice
Prefer:
Implement PaymentWebhookHandler only.
over:
Build the entire billing system.
Smaller changes are easier to review.
Step 5: Run automated verification
Use:
Tests
Static analysis
Type checking
Linting
Security scanning
Architecture checks
Step 6: Review the code
Inspect:
Correctness
Security
Error handling
Performance
Maintainability
Architecture
Step 7: Test failure scenarios
Ask:
What if Redis is unavailable?
What if this request runs twice?
What if the payment provider times out?
What if the database transaction fails?
What if two workers process this simultaneously?
Happy paths are easy.
Production systems fail through unhappy paths.
32. Skills I would learn if I were starting today
If I were preparing for the next several years of software engineering, I would prioritize roughly this stack.
Core programming
Learn at least one language deeply.
Understand:
- data structures
- algorithms
- concurrency
- memory basics
- error handling
- type systems
Backend fundamentals
Understand:
HTTP
REST
authentication
authorization
caching
queues
background jobs
WebSockets
Databases
Learn SQL seriously.
Understand:
indexes
transactions
locking
query plans
replication
Infrastructure
Learn:
Linux
Docker
CI/CD
cloud fundamentals
DNS
load balancing
Software architecture
Study:
modularity
domain boundaries
event-driven architecture
distributed systems
failure handling
Security
Understand common application vulnerabilities and secure engineering practices.
AI-assisted development
Learn how to:
provide repository context
design agent tasks
review generated code
build automated guardrails
use AI for debugging
use AI for learning
Communication
Practice writing:
design documents
technical proposals
incident reports
architecture explanations
That combination creates an engineer who can operate well above the code-generation layer.
33. The new abstraction layer of software engineering
Software development has continuously moved upward.
We went from:
Machine code
↓
Assembly
↓
High-level languages
↓
Frameworks
↓
Cloud platforms
↓
AI-assisted development
Each layer makes the lower layer easier to manipulate.
But somebody still needs to understand what the system should do.
The developer of the future may spend less time manually implementing every detail.
Instead, they may spend more time:
- designing systems
- defining constraints
- reviewing generated changes
- coordinating agents
- analyzing production behavior
- improving developer infrastructure
- making product decisions
That does not sound like the death of software engineering.
It sounds like another evolution of it.
34. Do not try to beat AI at being AI
AI has several advantages you cannot compete with.
It can read faster.
It can generate code faster.
It can search enormous amounts of information.
It does not become tired after writing repetitive tests.
Trying to preserve your career by becoming a faster code typist is probably the wrong strategy.
Focus on things where engineering judgment matters:
What should we build?
Why should we build it?
How should the system behave?
What can go wrong?
What architecture fits the problem?
What trade-offs are acceptable?
How do we know the implementation is correct?
How will we operate it in production?
Those are much harder questions.
35. The strongest engineer may produce less code
This is perhaps the strangest consequence of AI-assisted development.
A highly productive engineer may personally type less code than before.
Instead, they might spend their day:
30 minutes understanding requirements
45 minutes designing architecture
20 minutes defining implementation tasks
AI generates code
40 minutes reviewing changes
30 minutes testing failure scenarios
20 minutes reviewing observability
15 minutes documenting architectural decisions
The final output might represent several days of traditional implementation work.
The engineer still did significant engineering.
Typing simply became a smaller part of it.
What should you do starting now?
Do not panic about AI.
But do not ignore it either.
Use it every day.
Use it to build.
Use it to learn.
Use it to read unfamiliar repositories.
Use it to write tests.
Use it to challenge your architecture.
Use it to investigate bugs.
Use it to automate repetitive work.
At the same time, strengthen the skills AI-generated code still depends on:
- architecture
- debugging
- databases
- distributed systems
- networking
- security
- testing
- infrastructure
- product thinking
- communication
Most importantly, keep understanding the systems you build.
Do not become a developer whose entire engineering process is:
Prompt
↓
Copy
↓
Paste
↓
Deploy
Build a process closer to:
Understand
↓
Design
↓
Specify
↓
Generate
↓
Verify
↓
Observe
↓
Improve
That difference matters.
Final Thoughts
AI is going to write a lot of software.
That is no longer a particularly controversial prediction.
But software engineering has never been only about writing code.
The difficult parts have always included understanding incomplete requirements, managing complexity, debugging strange behavior, making architectural trade-offs, protecting users, operating systems reliably, and deciding what should be built.
AI makes implementation faster.
That means engineers can attempt larger things.
And larger systems create more engineering problems, not fewer.
So the goal should not be surviving AI by avoiding it.
The goal should be moving one abstraction level higher.
Become the engineer who can use AI to transform an idea into a reliable system.
Understand the problem.
Design the architecture.
Define the constraints.
Let AI accelerate the mechanical work.
Then verify everything that matters.
The developers who do that will not simply survive the AI era.
They will be able to build more than software engineers from any previous generation.
Top comments (0)