Design Pattern Evangelist Blog

Smart pointers about software design

Maintained by Jim Humelsine | Table of Contents | RSS Feed | Edit on GitHub

Beyond Onboarding

What Your First Year as a Software Engineer Is Really Like


Introduction

Onboarding might last for several days or several weeks as I described in Acquiring and Onboarding Your First Job, but then what?

Onboarding ends. The real challenge begins.

The first year of a software engineering career is not about mastering syntax or algorithms. It’s about learning how software is actually built, maintained, and evolved in the real world.

These are personal observations that may not apply universally and will evolve over time.

The First-Year Learning Curve

It often takes several months to a year before a new developer feels comfortable and productive in a professional codebase.

You are learning the product, the tools, the architecture, the business domain, and the team’s development practices all at the same time. That is a lot to absorb.

Feeling overwhelmed during the first few months is normal. You’re not expected to know everything. Stay curious, keep asking good questions, and focus on steady progress rather than immediate mastery.

The first year isn’t just about surviving the learning curve. It’s about building the foundation for everything that follows.

Continuing Education

Your Computer Science degree is not the end of your education. It is the beginning.

You’ve been studying Computer Science. Your career will be Software Engineering. They are related, but different as I described in You Studied Computer Science. Your Career Will Be Software Engineering.

An academic Computer Science assignment is basically a scoped and well-defined problem to be completed and handed in the following week. You may be part of a small team for larger projects, but for the most part, you tend to be the only person working on your assignment. The main goal is for the code to produce the right answer. You may never look at the code again.

Things will change in your business career. The problems will be broader and less well defined. The customer won’t be able to describe what they want, but they’ll know it when they see it. Or more likely, they tell you that what they see isn’t what they wanted.

You can look for solutions anywhere. The solution, in whatever form it may take, may need to be maintained for years as the customer requests new features and modifications.

You’re not in it alone. You’re part of a team. Solve problems together.

Continuing education is about how concepts come together in real systems.

Here are some broad areas for your continued learning.

Domain

One of the biggest gaps between academic study and professional work is understanding the problem space itself.

Many early-career developers believe their job is to write code. It isn’t. Your job is to solve problems in a domain. Code is just the tool.

As I mentioned in Paradigm Shift, data structures and algorithms aren’t enough. You will need to know how to apply these to create solutions to problems within your customer’s domain, which might cause a new software developer to ask, “What’s the customer’s domain?”

Domain is a major concept in Domain-Driven Design, which I’ll cover in the future (TBD). A domain is the customer’s business context. Netflix’s domain is streaming video content. Linkedin’s domain is allowing users to create a network of professional connections. Amazon’s original domain was selling books, but it’s expanded beyond that.

Knowing how to code is insufficient. Knowing how to code to solve a problem in the customer’s domain is what’s required.

Most software engineers learn their customer’s domain on the job. This takes time. Ask questions beyond the code:

Once you’ve learned the domain for one customer, it will become easier to learn the domain for another customer. It’s similar to how people who learn two natural languages while growing up find it easier to learn additional languages than those who only learned one native language.

My first customer domain was telecommunications. My second customer domain was military applications. I used to joke that there wasn’t much difference between the C++ code I wrote for telecom network elements and military tanks, except that network elements didn’t tend to roam around fields firing shells.

Building Production Software

Understanding the domain is only part of the equation. The other part is understanding how real software systems are built, delivered, and maintained at scale.

Production software is different than programming assignments. Production software is larger. It takes more staff and time to develop. It’s constantly evolving. It must be maintained for months and even years. It has paying customers and actual users who depend upon it.

Ownership and Responsibility

Responsibility means:

Early in your career, this often starts small. Fixing a bug thoroughly instead of patching it. Improving documentation. Following up on issues after deployment.

Over time, responsibility becomes one of the defining traits of a strong engineer.

I used to think of the code I wrote as my code. It wasn’t. I may have designed and implemented the code, but it was part of the project. I needed to design and implement code that anyone on the team should have been able to read, comprehend and modify as needed.

I didn’t own it, but I was responsible for it. Responsibility doesn’t end when the code compiles. It ends when the problem is solved.

Estimation and Uncertainty

Most tasks take longer than you expect, especially when you are unfamiliar with the codebase or domain. When one of my managers asked for my estimates, he told me to double it and then double it again.

Estimates are not commitments. They are best guesses based on incomplete information. Software engineering is the art of making decisions with incomplete information.

There’s a constant tradeoff between accuracy and precision. Here’s an example:

Estimates are requested to determine staff resource allocation and expected delivery dates. Imprecise and inaccurate estimates make planning more difficult.

Most estimates tend to be along the lines of: I can deliver that feature in 34 days, plus or minus 10 days.

A reasonable estimate is more like a probability range from worst case to best case scenarios. Short term estimates tend to be more accurate than long term estimates.

Over time, your estimates will improve, but they will never be perfect.

Estimates are often missed. A former department head had what I thought was an excellent heuristic when having to report missed estimates:

Inform the client ahead of a missed deadline by the same amount of time expected to miss the deadline.

For example:

Design and Architecture

Design and architecture are skills that develop slowly as you work in real systems and see the consequences of early design choices. Good architecture is often invisible when it works well and painfully obvious when it does not. The concepts below help you reason about those tradeoffs.

Development Practices

Development practices are not rules you follow out of obligation. They are habits experienced engineers rely on to keep systems maintainable as they grow. Early in your career, the focus is usually on making things work. These practices help ensure they keep working as the system evolves.

Debugging

Production software always has bugs lurking within it. The right set of circumstances may not trigger the bugs for years. Then at the worst possible time, the planets align, and an unknown bug rears its ugly head.

Production errors are rarely isolated or well-defined. Debugging often involves incomplete information, multiple systems, and a fair amount of guesswork. You will find yourself trying to debug behavior in code you did not write, and the original author has long since left the company. Tracking down these bugs is a skill you will develop throughout your career.

Debugging comes in many forms. Here’s one of my favorite finds from the 1980s:

Our builds were flaky. Some developers couldn’t complete full builds, while others had no problems. It wasn’t a major issue, but it slowed down those who couldn’t build consistently.

Then one day I had a thought. We worked on Unix mainframes. Some developers had vt100 terminals. Others had hp terminals. I remembered the vt100 terminal developers having problems, but I couldn’t recall any of the hp terminal developers having problems. It couldn’t be terminal dependent, could it?

I tried a full build on my vt100 terminal. It failed. I set my Unix TERM variable to TERM=hp and started another build. It passed. I reset it back to TERM=vt100, and it failed.

I strolled over to one of our hp terminal developer’s office and asked her to do a full build. It passed. I asked her to set TERM=vt100, and it failed. She set it back to hp, and it worked. Aha! It was terminal dependent!

We tracked it down to a build script that called ex. I’ll spare you the technical details other than to say that ex is terminal dependent, and the command didn’t work for a vt100 terminals, but it worked for the hp terminals. Fortunately, it was an easy fix. We only needed to change ex to ed.

I created a ticket and assigned it to build script team. Their manager refused to accept the ticket. He absolutely refused to accept it even in the face of obvious evidence. At that point, I decided to take matters into my own hands. I claimed the ticket for myself and made the one letter change in the script. The problem disappeared.

Delivery and Operations

Writing code is only the beginning of delivering software. That code must be built, tested, deployed, and observed in environments where real users depend on it. Delivery and operations are the systems and practices that make that possible safely and repeatedly.

Process and Workflow

Process exists because software is built by groups of people over time. As systems and teams scale, informal coordination stops working. Workflow provides the structure that keeps many moving parts aligned.

Reality of Work

Writing code is a small part of software engineering. Communication, coordination, and organizational alignment often take as much time as implementation.

New Technology

Even after you begin to understand how systems are built today, one reality remains constant: the tools and technologies themselves won’t stand still.

I stated in Software Engineering Problems:

The half-life for technology in the Computer Science field is about three to five years and possibly even shorter with the advent of Generative AI. All technology I learned in college was mostly obsolete a decade or so into my career.

Technology evolves quickly, and engineers must continuously adapt.

Right now, the greatest disruptive technology is Generative AI. Those who learn how to leverage it will have an advantage over those who do not. More on this in an upcoming blog (TBD).

Use LLMs thoughtfully to understand the business and technology but verify anything they produce. They hallucinate/confabulate results.

Use LLMs to summarize documents, understand legacy code, or act as a junior pair programmer. They are useful tools, not authorities.

Trust but verify. Never assume correctness.

Do not put any company proprietary content, documentation or code, in a generic LLM, such as ChatGPT. We don’t know how it might absorb that content and redistribute it. Ask your mentor/manager which LLMs you can safely use. Hopefully, your new employer has a company-approved LLM that you can use safely.

Educational Resources

There is so much more to explore. The internet is filled with educational resources for Software Engineering. Most are free or a reasonable price.

An early draft listed many of these here, but the list became a bit too long to include. I’ll cover these resources in a future post. (TBD).

Managing Your Career

Technical growth is only part of a successful career. The other part is learning how to navigate the profession itself.

You can be a strong engineer and still stall if you don’t actively manage your career.

You’re responsible for your career. Here are some ways to take control of it.

These aren’t technical skills. They’re career skills. And over time, they often matter just as much as your technical ability.

Feedback and Communication

Software Engineering is a social activity. You will get feedback on your work. Code reviews, design discussions, and even casual conversations are all part of how knowledge is shared across a team. Seek and apply feedback early and often. Silence and hesitation slow you down far more than asking a “simple” question.

Expand Your Experience

Don’t get typecast.

Consider new assignments.

I joined my project’s system testing team (QA) for a yearlong rotation when they were short staffed. As I was leaving that rotation, I was offered another yearlong rotation as a business analyst (BA) when the previous BA resigned unexpectedly. Those rotations led to a promotion. I also developed a better understanding of what it meant to be a QA or a BA, but most importantly I learned that I only wanted to be a developer.

Consider new opportunities outside of your current company. You are ultimately responsible for your own career. Remember, You are a Mercenary.

I’ve worked in companies ranging from a few dozen employees to over 100,000, from small teams to true behemoths.

In the largest organizations, I often felt more energy went into internal competition than external competition.

At a startup, much of that overhead disappeared. We were all rowing in the same direction, but in a much smaller, more fragile boat.

Eventually, that boat sank. The behemoth is still lumbering along.

Learn new skills, even if they don’t directly apply to your current job. Pick something that’s interesting to you. It doesn’t matter what it is. You don’t know where it may become useful.

Those new skills are the preparation that allow you to take advantage of opportunity when it strikes. Some may just call it luck, but I prefer this interpretation:

Luck is when preparation meets opportunity — Seneca

Become a Teacher or Mentor

Teaching accelerates mastery.

You’ll learn more by teaching or explaining something. The TV show The Pitt has featured – See one. Do one. Teach one. (SODOTO). It places you in a different frame of mind, much like Rubber Ducking. You may be surprised by how much you actually know and understand when you have to present it. I’ve often felt like I didn’t understand something well, and then it came up in a conversation. I found that I could describe it with more knowledge and confidence that I thought I had.

You may get questions or feedback when teaching or mentoring that makes you think even more about the topic that helps you gain even better understanding. This applies to almost anything, technology, processes, patterns, business domain, etc.

Loyalty

Be rational, not sentimental.

The days of a job for life disappeared decades ago.

Don’t expect loyalty from employers, and don’t assume obligations beyond your own career goals.

Loyalty goes both ways. Don’t hesitate to take a better offer. You might get some resistance to leave and even a guilt trip. I once heard a response when management tries to dissuade you from taking a new offer: It would be financially irresponsible for me to not accept this offer. If it’s a really good offer, there’s not much management can say other than to make a counter offer.

Don’t feel guilty. They will survive. Your employer won’t think twice when they have to let you go.

A better offer might not just mean more money. Consider the entire package:

These are personal choices that only you can weigh and consider.

However, when accepting a new position, whether it’s an internal transfer or moving to a new company, try to stay for at least one year before moving on.

Keep Records

Your memory is unreliable. Your records are reliable.

Keep a running list of accomplishments. A previous manager asked me to send him an email every Friday afternoon listing what I had accomplished that week. It was the basis of our weekly one-on-one meetings.

I continued the practice even without managerial prompting. But rather than send an email, I would imagine what I would email to my manager, and I documented it in an electronic file. It made my annual self-assessment much easier, since I had a record of what I had done. I spotted something almost every year that I had either forgotten about, or I had falsely remembered happening in a previous year. If I can’t remember what I had done, I couldn’t expect my manager to have known what I had done.

In addition to weekly summaries, consider documenting whole stories that feature what you’ve done. These stories will be useful for your current job and for interviews for future jobs too.

These records become the foundation for your resume, performance reviews, and future interviews.

Summary

The first year can feel overwhelming. That’s normal. You’re learning more than just code. You’re learning how the profession actually works.

The engineers who succeed long-term aren’t the ones who knew the most on day one. They’re the ones who never stop learning.

Previous: Acquiring and Onboarding Your First Job

Next: WORK IN PROGRESS – Educational Resources for Continued Learning

Home: Design Pattern Evangelist Blog