Skip to main content
SEMastery
Fundamentalsbeginner

How to Be a Better Software Engineer in 2023 (A Beginner's Guide)

Simple, beginner-friendly habits to grow as a software engineer: clean code, testing, SOLID, version control, refactoring, and learning the right way.

11 min readUpdated November 28, 2025

Introduction

Imagine you are learning to cook. On your first day you burn the rice and the curry is too salty. But you do not give up. You cook again tomorrow. You taste as you go. You ask your mother why the dal turned out watery. After a few months, you can cook a full meal without even looking at a recipe.

Becoming a better software engineer works the same way. Nobody is born knowing how to write good code. You get better by doing it again and again, by tasting your work as you go, and by asking questions when something feels wrong.

This guide gives you simple, practical habits to grow as an engineer. You do not need to be a genius. If you can keep a steady habit, like watering a plant a little every day, you will improve. Let us walk through the habits one by one.

Growth comes from a loop you repeat, not a single big jump.

Habit 1: Write code people can read

Here is a secret that surprises new engineers. Code is read far more often than it is written. You type a method once, but you and your teammates may read it a hundred times over the next year. So the kind thing to do is make the reading easy.

The first step is good names. A good name tells you what something does without making you guess. Compare these two snippets.

// Hard to read: what is d? what is x?
public decimal Calc(decimal d, int x)
{
    return d - (d * x / 100);
}
 
// Easy to read: the names tell the story
public decimal ApplyDiscount(decimal price, int discountPercent)
{
    return price - (price * discountPercent / 100);
}

Both methods do the same thing. But the second one explains itself. You do not need a comment to understand it. That is the goal: code that reads like a sentence.

The second step is small methods. A method should do one job. If you find a method doing five things, split it into five small methods with clear names. Small methods are easier to read, easier to test, and easier to fix.

Habit 2: Learn the SOLID principles slowly

SOLID is a set of five ideas that help you write code that is easy to change. You do not need to master all five today. Learn them one at a time, over months. Here is a friendly summary.

LetterShort namePlain meaning
SSingle ResponsibilityOne class should have one job.
OOpen/ClosedAdd new behaviour without editing old code.
LLiskov SubstitutionA child class should work wherever its parent works.
IInterface SegregationMany small interfaces beat one giant one.
DDependency InversionDepend on ideas (interfaces), not on details.

The most useful one for beginners is the first: Single Responsibility. When a class does only one thing, it is easy to name, easy to test, and easy to change. Here is a tiny example of moving from a class that does too much to one that is focused.

// Too many jobs in one place
public class OrderService
{
    public void PlaceOrder(Order order)
    {
        // saves to database
        // sends an email
        // writes to a log file
    }
}
 
// Each job lives in its own place
public class OrderService
{
    private readonly IOrderRepository _repository;
    private readonly IEmailSender _email;
 
    public OrderService(IOrderRepository repository, IEmailSender email)
    {
        _repository = repository;
        _email = email;
    }
 
    public void PlaceOrder(Order order)
    {
        _repository.Save(order);
        _email.SendConfirmation(order);
    }
}

The second version is longer, but each part now has one clear job. When the email rules change later, you only touch the email class. Nothing else breaks.

Habit 3: Write tests, even small ones

A test is just code that checks your code. It runs your method and asks: did you get the answer I expected? When you have tests, you can change your code without fear, because the tests will shout if you break something.

Good unit tests follow a simple memory trick called FIRST. It helps you remember what a healthy test looks like.

The FIRST rules for good unit tests

Fast
Independent
Repeatable
Self-checking
Timely

Steps

1

Fast

Runs in a blink.

2

Independent

Needs no other test.

3

Repeatable

Same result always.

4

Self-checking

Passes or fails on its own.

5

Timely

Written close to the code.

A healthy test runs quickly, stands alone, gives the same result every time, checks itself, and is written early.

Here is what a small test looks like in .NET using xUnit. It checks that our discount method works.

public class DiscountTests
{
    [Fact]
    public void ApplyDiscount_RemovesTenPercent()
    {
        // Arrange
        var calculator = new PriceCalculator();
 
        // Act
        decimal result = calculator.ApplyDiscount(100m, 10);
 
        // Assert
        Assert.Equal(90m, result);
    }
}

Notice the three steps: Arrange (set things up), Act (run the thing), Assert (check the answer). This pattern keeps tests tidy. Start with one test for one method. You do not need to test everything on day one. A few tests are far better than zero.

Tests act like a safety net when you change code.

Habit 4: Use version control like a pro

Version control, usually Git, is a time machine for your code. It saves snapshots of your work so you can go back if something breaks. Every engineer uses it, every single day.

The key habit is small, frequent commits. A commit is one saved snapshot with a short message. Do not save a huge messy blob once a week. Instead, save a small focused change often, and write a clear message about what you did.

Commit messageIs it good?Why
"fix"NoFix what? You will forget by tomorrow.
"stuff"NoMeans nothing to anyone.
"Fix discount rounding for large orders"YesClear and specific.
"Add email confirmation after order is placed"YesTells the whole story.

Good commit messages are a gift to your future self and your teammates. When a bug appears, clear messages help everyone find when and why it started.

Habit 5: Refactor in small steps

Refactoring means improving the shape of your code without changing what it does. Think of it like tidying your room. The room still has the same furniture, but now you can walk around without tripping.

The safe way to refactor is in tiny steps, with tests running after each step. Rename one variable. Run tests. Split one method. Run tests. If the tests stay green, you know you did not break anything.

Safe refactoring is a tight loop with tests as the guard.

Never do a giant rewrite of everything at once. Big rewrites are scary and often introduce new bugs. Small steps keep you safe and let you stop at any time with working code.

Habit 6: Pick the right tools, and know their cost

A better engineer chooses tools wisely. In the .NET world, the platform keeps moving forward, so stay roughly current. As of now, .NET 10 is the long-term support release, C# 14 has shipped, and C# 15 brings exciting features like union types in the .NET 11 preview. You do not need to use the newest thing the day it lands, but knowing what exists helps you make good choices.

One important habit is to check the licence of the libraries you add. Some popular libraries have changed how they are licensed. For example, MediatR and MassTransit, which were free and open source for years, have moved to a commercial licence. That does not make them bad. It just means you should check the terms before you depend on them in a paid product, especially at work. A good engineer reads the fine print so there are no surprises later.

Choosing a library the careful way

Need it?
Maintained?
Licence ok?
Add it

Steps

1

Need it?

Can plain code do it?

2

Maintained?

Recent updates and care.

3

Licence ok?

Free or commercial?

4

Add it

Now depend on it safely.

Before you add a dependency, run through a few quick checks so you do not get stuck later.

Habit 7: Read code written by others

You learn cooking faster by watching a good cook. The same is true for code. Open a well-loved open source project on GitHub and read how the maintainers write methods, name things, and organise files. You will pick up patterns you would never invent on your own.

When you read, ask simple questions. Why did they split this into two classes? Why is this method so short? How do they handle errors? Over time, the good habits seep into your own work without you trying hard.

Habit 8: Communicate clearly with humans

This surprises many new engineers: the job is not only about machines. You spend a lot of time talking to people. You explain your plan, you ask questions, you review a teammate's work, you write a clear message in a pull request.

The same skill that makes good code, simple and clear, makes good communication. Use short sentences. Explain the why, not just the what. When you ask for help, share what you tried and what error you saw. People love helping someone who has already done their homework.

Habit 9: Be kind to your future self

Every choice you make today is a gift or a trap for the you of six months from now. A clear name is a gift. A clever one-liner that nobody understands is a trap. A test is a gift. A skipped test is a trap.

When you write code, picture a tired version of yourself reading it late at night, half asleep, trying to fix a bug. Make that person's life easy. That single habit, thinking of the next reader, quietly improves everything else.

Putting it all together

You do not have to adopt every habit today. Pick one this week. Maybe it is writing your first test. Next week, pick another, like writing clearer commit messages. Small steady steps add up to a big change over a year.

Each habit feeds the others, and the whole loop lifts your skill.

Remember the cooking story. The first meals are messy. That is fine. You keep cooking, you keep tasting, and one day you make a meal you are proud of. Software engineering is the same. Show up, practice a little every day, and be patient with yourself.

References and further reading

Quick recap

  • Write code people can read: clear names and small methods beat clever tricks.
  • Learn SOLID slowly, starting with Single Responsibility: one class, one job.
  • Write tests, even small ones, and remember the FIRST rules.
  • Use Git with small, frequent commits and clear messages.
  • Refactor in tiny steps, with tests running as your safety net.
  • Choose tools wisely and always check the licence (for example, MediatR and MassTransit are now commercial).
  • Read other people's code, communicate clearly, and be kind to your future self.
  • Improve a little each week. Steady habits beat one big rush.

Related Posts