DEV Community

Cover image for Seasoned Developer Advice after 25 years in IT
Emanuele Bartolesi for Playful Programming

Posted on AI-assisted

Seasoned Developer Advice after 25 years in IT

I've now been working in IT for exactly 25 years.

My impostor syndrome is still very much present. Writing an article called "seasoned developer advice" makes me hesitate a little. There is always something I don't know, a technology I haven't used, or someone who understands a subject much better than I do.

But after 25 years, I think I can start sharing a few thoughts.

These are opinions about how to work, build software, and stay in this profession. Take what helps, question the rest, and adapt it to the team and situation you have in front of you.

Ask the question you are embarrassed to ask

01-ask-questions

If a requirement is unclear, ask about it before you turn it into code.

What does "active customer" mean? Who can approve this operation? What should happen when the external service is unavailable? These questions can feel basic, especially when everyone else in the meeting appears to understand everything.

I would rather admit that I don't understand a business rule than build an entire feature around my interpretation of it. The same applies to an unfamiliar piece of code. Ask someone to walk you through it, then explain it back in your own words.
This step is even easier with AI nowdays, but asking a colleague still an easier thing to understand maybe something that AI doesn't know behind a business choice or something like that.

Experience should make it easier to say "I don't know yet." I still have to remind myself of that.

Give coordination an owner

Plush Emanuele arranging connected task cards on a felt board.

Developers need time to develop. If the lead developer also has to chase every dependency, negotiate the scope, update stakeholders, and organize the release, account for that work in the plan.

On a larger project, I would want someone explicitly responsible for coordination. That might be a project manager, a delivery lead, or another role that fits the organization. On a small team, it may be a shared responsibility, but the decisions still need an owner.

A date written in a ticket does not resolve a blocked dependency. Someone has to talk to the other team, agree on what happens next, and adjust the plan when the answer changes.

When estimating a feature, include that work. A week full of meetings leaves less time for implementation than a week with clear decisions and uninterrupted time.
Actually we are still doing this mistake to "overmeetings" but I hope it will change soon or later.

Make meetings earn their place

Plush Emanuele at a meeting table with an hourglass and a decision board.

I don't think every team needs the same meeting schedule.

A short conversation with the person who understands the business process can be useful while a feature is taking shape. Showing a working screen may reveal that the approval flow is wrong before you spend another week building it.

A daily meeting where everyone reads out tickets already visible on the board is harder to justify.

For me, a useful meeting resolves a question, exposes a dependency, or produces a decision. If an update can be written down and read when people have time, try that. If a disagreement needs a conversation, have the conversation.

Record the outcome where the work lives. A decision made on a call is easy to miss if the developer implementing it was somewhere else.

Write code for the person who has to change it

Plush Emanuele showing readable code on a laptop beside connected modules.

Readable code matters most when someone needs to fix it under pressure.

I prefer a method with a clear name and an obvious flow over an abstraction that takes three files to understand. There are good reasons for abstraction, but I want to know which problem it solves before adding another layer.

The same caution applies to shared code. Two methods that look similar may represent business rules that will evolve independently. Putting them in one common library creates a relationship you will have to maintain.

Extract code when the shared behavior is understood. If several applications depend on it, think about compatibility, ownership, and how updates will reach them. Publishing a package creates a responsibility beyond the original project.
Still a valid advice also for we use a lot of AI for writing code.
We need anywayt to review what is written to understand if we can read and understand the code anyway.

Leave the explanation you would want to find later

Plush Emanuele writing diagrams in a notebook beside a laptop.

Code can show what happens without explaining why it must happen that way.

A comment explaining that a file format is required by an external system is useful. A comment saying that the next line increments a counter usually adds little.

I want documentation that helps someone do the work: how to run the application, which configuration is needed, how to execute the tests, and what to check when a deployment fails. Keep those instructions close to the repository and update them when the workflow changes.

There is also value in a short decision note. If the team rejected a queue because the current workload did not justify operating one, record that reasoning and the condition that would make you reconsider.

AI can help draft these explanations. Check them against the code and the actual setup before treating them as documentation. A plausible installation guide that cannot be followed is another problem for the next developer to debug.

Think about the application after it leaves your machine

Plush Emanuele inspecting a server with a recovery arrow and a shield.

A feature needs more than a successful local run.

Before shipping, I want to know how we will recognize a failure and what we can do about it. A useful log entry should give enough context to trace an operation without exposing credentials or customer data. An exception with no context can leave you searching through several unrelated requests.

Be deliberate about tests, too. If a feature moves data between customers, test that boundary. If it sends notifications, consider what happens when an operation is repeated. The failure case should influence the test, rather than becoming an afterthought once the happy path passes.

And discuss recovery. Reverting code will not undo every effect of that code. A database change or an email already sent needs its own consideration.

These questions belong in development, while you can still change the design without an incident forcing the decision.

Review the code without making it personal

Plush Emanuele reviewing a laptop with a magnifying glass and a friendly feedback bubble.

Having someone question your implementation can be uncomfortable. With impostor syndrome already in the room, a review comment can feel larger than it is.

Try to keep the conversation specific. Explain which behavior concerns you, point to the assumption, and suggest a way to verify it. "What happens if this request is retried?" is a useful opening for a discussion.

As the author, explain your reasoning and be willing to change it. As the reviewer, distinguish a defect from a preference. A naming choice does not deserve the same treatment as a missing authorization check.

I also like reviews small enough that a colleague can understand the change properly. If a bug fix includes a folder reorganization and a new framework, consider separating those decisions.

The goal is a change the team understands well enough to maintain. Being the person who wins the argument contributes very little to that.

Make maintenance part of the plan

Plush Emanuele maintaining a software box beside a calendar.

Framework upgrades, dependency updates, and refactoring need time on the calendar.

It is easy to postpone them because the application still works. When you do, be explicit about what you are accepting and when you will revisit it. Otherwise, postponement becomes the plan by default.

A refactoring ticket should name the problem it will address. Perhaps adding a validation rule currently requires changing five different places. That gives the team a concrete improvement to assess and a way to tell whether the work helped.

I would apply the same discipline to modernization. Explain what the upgrade enables, which risk it addresses, and how you will validate the change. The age of a framework alone is a weak explanation for rewriting a working application.

Keep learning through things you can use

Plush Emanuele learning from a book and experimenting with a laptop.

You cannot study every language, framework, cloud service, and AI tool that appears.

Choose something relevant and spend enough time with it to understand where it helps. Build a small application, add a feature to a side project, or investigate a part of your production system that you usually avoid.

A course can give you structure. Applying the lesson gives you questions the course may never have covered.

I would also leave room to learn from colleagues. Someone with less experience may know a tool or technique you have never used. Twenty-five years in IT should not make that conversation awkward.

Your main language is useful expertise. Stay curious about the parts around it: the database query, the deployment pipeline, or the interface the user has to navigate. A problem does not stop at the boundary of your preferred stack.

Choose tools you can trust and understand

Plush Emanuele choosing tools beside a laptop and a small AI robot.

Use an editor that lets you work comfortably. Learn its debugger, navigation, and refactoring tools before assuming a different editor will solve your frustration.

I would take the same approach to AI. Start with work where you can judge the result: exploring unfamiliar code, preparing a first test draft, or checking an implementation for missed cases.

Read the output and run the checks. When the tool proposes a design, ask what assumptions it made. You remain responsible for the change you submit.

Trying another tool or model can be useful when it answers a specific question about your workflow. You don't need a collection of subscriptions just to feel current.

Build a way of working you can keep doing

Plush Emanuele taking a coffee break beside a closed laptop.

After 25 years, I want my advice to include what happens away from the keyboard.

Take breaks. Get up, walk around, do sports, and give yourself permission to stop staring at the same problem. If you are stuck, ask for help rather than making another exhausted hour the price of proving that you can solve it alone.

Talk to teammates sometimes without a ticket as the agenda. It is easier to ask someone a difficult question when your only interaction with them has not been a review disagreement.

And keep something outside work. There will always be another release, article, framework, or project. Closing the laptop does not mean you stopped caring about your profession.

I still don't feel that 25 years gives me an answer to everything. It does give me enough reason to share these thoughts, even while the impostor syndrome tells me to wait a little longer.


If you enjoyed this blog post and want to learn more about C# development, you might be interested in subscribing to my bi-weekly newsletter called Dev Dispatch. By subscribing, you will get access to exclusive content, tips, and tricks, as well as updates on the latest news and trends in the development world. You will also be able to interact with me, and share your feedback and suggestions. To subscribe, simply navigate to https://buttondown.email/kasuken?tag=devto, enter your email address and click on the Subscribe button. You can unsubscribe at any time. Thank you for your support!

Top comments (0)