At 19, I dropped out of college and moved to San Francisco. I had a job offer from Taos Consulting as a Unix system administrator. However, before my first day of work, I was lured by a startup in the city where I worked as a software engineer for an email subsystem.
I never doubted my ability to find a job. There were plenty of opportunities, and more importantly, the bar for hiring was low. If you knew how to work with HTML or were familiar with the command line, chances are someone would pay you for it.
Was I a natural prodigy who loved tinkering with computer keyboards? Absolutely not. I was home-schooled in a remote area of Idaho. I didn't touch a computer until I was 16 and off to college. I fled to university on a classical piano performance scholarship, which I then traded for a series of non-technical majors: classical Latin and Greek, music theory, philosophy. Everything I knew about computers, I learned on the job, working as a system administrator for the university and computer science department.
In retrospect, I was fortunate to have entered the industry when I did. The thought of what would have happened if I had entered the industry a few years later terrifies me. All the rungs that my friends and I used to climb into the profession have long since disappeared.
The software industry is maturing
This is precisely what happens when an industry matures. The early days of any field are like the Wild West, with low barriers to entry, minimal regulation, and standards that are just budding. If you look at the early history of other industries (medicine, movies, broadcasting), you'll find striking similarities.
There is a magical moment in the early days of any young technology when the lines between roles are blurred, and anyone with drive, curiosity, and a willingness to work hard can seize opportunities.
This state does not last long. It cannot and should not. The required knowledge and experience you must have before entering the profession increases dramatically. The risks grow, the tasks become heavier, and the cost of making mistakes rises. We develop certifications, training, standards, and legal rituals. We argue about whether software engineers are really engineers.
Software is an apprentice industry
Today, you would not want a teenage dropout like me to become your pager after junior year in college. The required knowledge to enter this profession is growing, the pace is quickening, and the risks are increasing, so you can no longer learn everything on the job as I once did.
However, you cannot learn everything you need to know in college either. A computer science degree generally prepares you better for a life in computer research rather than being a day-to-day software engineer. A more practical path into the profession might be attending a good coding boot camp that emphasizes problem-solving and learning the modern toolkit. In either case, what you learn is not "how to do the job," but "enough foundational knowledge to understand and use the tools you need to learn the job."
The software industry is an apprentice industry. You cannot learn to be a software engineer by reading books. You can only learn by doing... practicing, practicing, practicing. No matter what your education, most of the learning happens on the job—and that's just the way it is. And it never ends! Learning and teaching are lifelong practices; they have to be, because the industry changes so rapidly.
It takes a full seven-plus years to cultivate a competent software engineer. (Or, as most career ladders call it, "Senior Software Engineer.") This means it takes years of daily work writing, reviewing, and deploying code alongside more experienced engineers in teams. That's just how long it takes.
What does "senior engineer" mean?
This is where I often encounter some indignant pushback on my timelines, such as:
"Seven years?! Pshaw, I did it in two!"
"I was promoted to Senior Software Engineer in less than five years!"
Great. Yes, seven years is not magical. But it takes time and experience to become a seasoned engineer, a backbone of the team. More importantly, it takes practice.
I think we've gotten used to using "Senior Software Engineer" to refer to engineers who can deliver code and produce a net positive effect on productivity, and I think that's a huge mistake. This implies that junior engineers must be a net negative effect on productivity, which is incorrect. It also overlooks the true nature of software engineering work, where writing code is only a small part of it.
To me, becoming a senior engineer has little to do with your ability to write code. It has more to do with your ability to understand, maintain, interpret, and manage large bodies of production software, as well as the ability to translate business requirements into technical implementations. Much of the work revolves around designing and orchestrating these large, complex sociotechnical systems, with code being just one manifestation of these systems.
What does it mean to be a senior engineer? It means you've learned how to learn and how to teach; how to hold these models in your mind and reason about them, and how to maintain, extend, and operate on these systems over time. It means you have good judgment and trusted intuition.
This brings us to the issue of artificial intelligence.
We must stop cannibalizing our own future
Getting that first engineering job is really, really hard. It wasn't until I saw my sister (freshly graduated, top of her class, some practical experience, extremely driven) struggle for nearly two years to find a formal job in her field that I realized how hard it was. That was a few years ago; anecdotally, it seems to have gotten harder since then.
In the past year, I've read a lot of articles about entry-level jobs in various industries being replaced by artificial intelligence. Some of these articles make absolute sense. Any tedious job, such as converting documents from one format to another, reading and summarizing large volumes of text, or replacing one set of icons with another, seems to have obvious vulnerabilities. It doesn't seem very revolutionary to me; it's just extending the existing wave of automation to include textual materials and mathematical content.
However, recently, some executives in the tech industry and so-called "thought leaders" seem to really believe that generative artificial intelligence is about to replace all the work done by junior engineers. I've read a lot of articles about how the work of junior engineers is being automated away, or how the demand for junior engineers is decreasing. It drives me crazy.
All of this suggests a deep misunderstanding of what engineers actually do. If we don't hire and train junior engineers, we are cannibalizing our own future. We have to stop doing this.
Writing code is the easy part
People think that writing code is the hardest part of software development. But it's not. It never has been, and it never will be. Writing code is the easiest part of software engineering, and it's getting easier all the time. The hard part is what you do with the code—operating it, understanding it, extending it, and managing it throughout its lifecycle.
Junior engineers start by learning how to write and debug lines of code, functions, and snippets. As you practice and become a senior engineer, you learn to build systems with software and guide those systems through waves of change and transformation.
Sociotechnical systems consist of software, tools, and people; understanding them requires familiarity with the interplay between software, users, production, infrastructure, and constant change over time. These systems are extremely complex, prone to chaos, uncertainty, and emergent behavior. If someone claims to understand the system they are developing and operating, then that system is either very small or (more likely) they do not understand enough to know what they do not know. In other words, code is easy, but systems are hard.
The current wave of generative artificial intelligence tools helps us generate large amounts of code quickly. The easy part is becoming easier at an astonishing rate. But it does nothing to help with the work of managing, understanding, or operating the code.
Generating code is easy; generating good code is hard
If you've read a lot of the exciting think pieces, you might have a mental image of software engineers gleefully typing prompts for ChatGPT or using Copilot to generate vast amounts of code, then submitting whatever appears to GitHub and leaving for the day. This does not match our reality.
The correct way to view tools like Copilot is more like a very fancy autocomplete or copy-paste feature, or perhaps a combination of Stack Overflow search results with Google's "I'm Feeling Lucky." You roll the dice every time.
They work best when there is a parallel file already in the file and you just want to copy-paste and make minor modifications. Or when you're writing tests and you have a fairly repetitive YAML block that it repeats the pattern with, inserting the correct columns and field names like an autotemplate.
But you cannot trust the generated code. I cannot stress this enough. AI-generated code always looks fairly reasonable, but even if it kind of "works," it rarely aligns with your needs. It will gladly generate