I don’t have the traditional programmer’s background. I don’t have CS degree, didn’t do well in math and wasn’t interested in programming in high school. I had exactly one IT class where we were taught Pascal.
I considered programming exciting for no more than a few minutes. Then my interest faded as the teacher hammered us with dry theory. Oh well, back to history and sports then.
I found myself in a coding bootcamp by sheer chance and in the next seven years I went from a self-taught developer to technical lead in the Financial Times. I realised there are a lot of people in the same place I was a few years ago.
People that feel confused, unsure and wandering how to move forward in the industry. Doubting whether this is the right place or path for them. The sense of being an impostor is relentless. Lurking in your mind, waiting for just a sign of doubt.
I finally got the courage to write this. An open, vulnerable, personal post with reflections on my journey so far.
Table of Contents
- It’s worth it
- Starting out as a self-taught-developer
- How to keep going?
- Interviews
- Imposter syndrome
- Writing bad code
- Idealism
- Always ask the question
- Generalist or specialist
- Be intentional
- Startups and large corporations
- Changing jobs
- Chasing titles
- Being a senior engineer
- Beyond senior
- A word to those just starting out
It's worth it #
I don’t remember how many times I’ve asked myself whether the struggle is worth it. Constantly reading, learning - trying to keep up with the rapid pace of the industry.
After a few years I can say that programming turned into a passion of mine but it definitely wasn’t one at the start. I found myself in the industry by accident and I will lie if I say that the pay wasn’t a factor.
But I had always wanted to do something creative and this industry was welcoming to people with non-traditional backgrounds. It can give you a good career and the rare chance to do something meaningful.
I’ve considered quitting more than once because I wasn’t growing with the rate I expected to. Each time I decided to stick around just a little longer and each time I convinced myself to stay. Once I got the hang of whatever I was having trouble with, it got so exciting. I just needed more time to learn than I imagined.
Slowly I got used to confusion and I stopped getting frustrated when things didn’t make sense. Complex products are not easy to build and staring at the screen in bewilderment is sometimes half the job.
We create applications and systems out of nothing and that’s the closest we can get to sorcery, so here’s another reason to stick around.
Starting out as a self-taught-developer #
It’s important to have a structured source of information early or you can get lost in the endless amount of courses available. I did a bootcamp but setting up a learning plan on your own is doable as well. Just make sure to find a schedule or a road map so you can use it as reference.
Before you put money and time into it, pick a random language and give a programming tutorial a try. Any language works. Write some code for a couple of weeks and see if you can imagine doing that for a living. Some people prefer careers with more communication and as a developer you will often spend the afternoon in the company of the debugger.
If it got you excited and your first infinite loop didn’t scare you, there are still some things you need to consider. People usually study for 3-4 years to become software engineers. The way to match that as a self-taught developer is through experience.
Don’t chose a language only based on what you or a friend likes. Look at the job market and see the available positions. The language becomes just a medium of expression with experience but at first knowing your way around it helps a lot.
In my case I started with PHP and JavaScript. There were many small agencies in my area that used them and I managed to land an internship a year after I started studying. Now I work with Go - you don’t have to work with the same language your whole career. You just need a starting point.
I wouldn’t start with math or algorithms. To me programming is a creative profession, not a purely logical one. Our work is closer to that of a writer or a painter than that of a scientist. I would advise you to learn a language and start creating things with it. Whether it’s an API or a UI or a simple script that automates a task. You will learn more than doing leetcode problems.
Having an end goal gives you an incentive to understand things. Whenever you see a term that you don’t understand, look it up. Whenever an algorithm or data structure is mentioned - see how it works.
How to keep going? #
At first programming felt like running in water. It’s an environment in which a single incorrect character can bring an error message upon you and that was terrifying. Coming out of high school, I associated the colour red with failure so I cringed inside each time it didn’t compile.
My problem was that I didn’t approach problems with curiosity. I wanted to get things to work, achieve the desired outcome and go to the next task. I wasn’t trying to understand, just force the computer to produce what I wanted.
If you’re doing the same, that’s not the right attitude to move forward with. It’s better to sit on a problem for a week and understand it in depth than go through ten different ones and barely manage to get them to run.
Intuition is built when you understand something. If you don’t, next time you will be solving the same problem again. And again. Until it clicks.
If you’re focused on the result you will be frustrated when you don’t get it. Learn to enjoy the journey and the process of solving a problem. That’s what the job is going to be like - sometimes you will sit on a tough challenge for days, even weeks.
But for this mindset shift to happen you need time. Some people need more others less. Don’t compete, just keep coding and keep studying.
Interviews #
Interviews are considered stressful no matter the industry. Some person you’re meeting for the first time is going to decide your future after a two hour conversation. But let me give you some words of encouragement - everyone during the interview process is on your side.
The company wants to hire an engineer, the person interviewing you would like their team to grow and you’d like to get a job. The recruiter will probably get a bonus too. No one is interested in you failing the process because it’s an investment of time and effort. You just need to show that you’ve got the right knowledge.
What to do if you don’t know the answer to a question? Think about it and see if you can derive an answer in a logical way. Give an educated guess with the reasoning behind it. But if it’s something that you’re completely unfamiliar with - be honest. Don’t try to bullshit your way through the question. Experienced interviewers will see through that immediately and it won’t leave a good impression.
When I started interviewing people, my director told me that our goal is to evaluate the breadth and depth of the person’s knowledge. They don’t have to know everything. I believe that most interviewers follow the same principle.
Imposter syndrome #
Building a career as a self-taught developer is not easy. My knowledge was often put to question. “He doesn’t even know what a pointer is”, “Bootcamp graduates are just coders, not real engineers”, “Are you confident in his work having in mind his experience?”.
Those are some of the most soul crushing sentences that I’ve heard.
I was running with the constant feeling that I’d be discovered and thrown out. That guy doesn’t know how to do a breadth first search! Each day was a challenge for me to defend the idea that I belong in this world. I loved coding, I loved building things and I wanted to be here.
But the days passed, I did my job and no one told me to leave. Then months passed. Then years. At some point I realised that this is my career now and I belong here.
The sense that your knowledge is not enough doesn’t go away. Never. I was a tech lead and I still doubted myself. There is so much to learn in our industry that a lifetime wouldn’t be enough. There are things that you won’t know, there are things that you’ll forget. And that’s okay.
Of course, being self-taught is not an excuse for incompetence. We all need to strive to be better, to learn and to grow. But your background won’t matter as long as you’re a good human being and have the right knowledge.
What’s the cure for imposter syndrome?
I’m afraid that there isn’t one or at least I don’t know it. I can only comfort you that you’re not alone in this. Some days are going to go bad and you’ll despair over programming again. We all have those days and we’ll continue having them.
Writing bad code #
There’s never been code that I haven’t wanted to rewrite. It could be a day, a month or a year but I’ve always found better ways to express my thinking. As you learn new concepts you will wander how you could’ve written such tangled code before.
Don’t let perfectionism be your enemy. Everything you write can be improved and it will become legacy one day.
Not liking your old work is a sign of growth. It means that you now recognise patterns that you didn’t even know existed. It means that you approach problems in better ways. In fact, not seeing problems with your old work might be a sign that you’ve plateaued.
When you see a library with a good API be sure that the author didn’t come up with it on the first try. Well-written code is usually a result of rigorous reviews and refactoring.
Painters don’t create a drawing in one go - at first they create shapes, then they add details, erase and add details again. Good writing sounds so natural but only because it’s undergone multiple edits.
Your code won’t be perfect from the start. Keep rewriting.
Idealism #
The courses we take, the forums, the blog posts - they show us an idealistic world in which everyone follows the best practices. They world as it should be. But for seven years I haven’t seen a company with a perfect codebase and no tech debt.
Theory doesn’t always blend well with the real world. You will see a lot of compromises, excuses and obvious anti-patterns in production codebases. You will be a witness to rushed decisions because of deadlines and nasty bugs that slip under the radar. I’ve contributed a few of my own.
Those things happen. We work in imperfect conditions with limited resources. Sometimes it’s the best that the people before you managed to do. You don’t know if you would’ve been able to do a better job in their shoes.
When you’re just getting started everything feels complex. But after you gain some experience you start seeing the problems with other people’s code. I’ve heard a lot of complaining from colleagues and I’ve done my fair share as well. One day you come to terms with the fact that real world is not always what you see in the blog posts and that is liberating.
We should all strive to be better at our work. But don’t let idealism get you frustrated. Look at it like this - you’ve got a chance to make things better. Do your best.
Always ask the question #
When you’re a beginner you have a free pass to ask all the questions you can think of. No matter how stupid you think something sounds it’s better to ask and understand than build knowledge on top of shaky foundations.
There are still no expectations of you and you don’t have a professional reputation to maintain. Take full advantage of this opportunity. When you find a concept you don’t understand, write it down and ask someone about it. This is how you become a more valuable member of the team.
Don’t worry about wasting people’s time - our whole industry is built on knowledge sharing. Companies hold events so they can describe the intricate details of their architecture. Developers write blog posts when they do something interesting. People are eager to share what they know.
One day when you’re the person with experience you can pay back the favour and help those who are just starting out.
Generalist or specialist #
At first it’s better to focus on one niche area because it allows you to maximise knowledge. This can be JavaScript and React or Java and Spring or C# and ASP.NET - you get my point.
But after you become comfortable with the work - branch your knowledge. Even the simplest applications are made of multiple components. Understanding of the different areas of the stack will be valuable to you no matter where you go.
The industry seems to be moving in a direction that favours people with broad knowledge so you don’t want to be specialised in only one area. But you don’t want to be a generalist either since complex problems require proficiency.
The best place to be is somewhere in the middle. Strong knowledge in one technology and good understanding of many others. They call this being T-shaped.
I’m no DevOps but I know enough to set up my own CI pipeline and write a CloudFormation configuration. I’m no database guru but I can design a schema and create the indexes that I need. Having broad knowledge will give you more autonomy as an engineer.
Be intentional #
You can’t let your career be up to chance. Eventually you have to pick a goal in your journey and make decisions that take you closer to it. Of course, when you’re starting out you should just aim to get experience. But after a couple of years you need to find out where you want to be.
If you want to build a startup one day, you’d be better off working for one before that. See the problems, make friends in the startup scene and see if it holds up to your expectations. If you want to maximise your earnings, then pick more lucrative technologies and become proficient with them.
Ask yourself what’s important to you - that will help you recognise what opportunities get you closer to it.
I knew I wanted to build UIs. I realised that I’m a visual person and would rather build interfaces, interactions and animations. To find a good place to grow I even had to relocate.
A few years after that I decided that I want to grow as an engineer and work with distributed systems - that made my career decisions easy.
Startups and large corporations #
I got familiar with startup culture early. The IT community in my town is small and I quickly got to know people who were running their own businesses (or they tried to). There was plenty of freelance work available since someone was always pivoting or building a feature.
I romanticised the startup life. Working long hours, building something against all odds and spending time with people who thought about the future. It was my way of rebelling against the normal way of life.
At one point I had a day job and did part-time work for two startups. I kept this pace up only for a few months before the burnout came crashing in. When it did, it took a great toll on my personal life and I decided to make some changes.
I started appreciating the craft more. Not just putting features together but designing an implementation. Most of the code I’d written so far was put together in caffeine fuelled evenings and its quality attested to that.
I was amazing at getting things to work. But I’d never worked on anything that had to scale. I knew next to nothing about architecture and infrastructure. Testing was a distant afterthought. Most of the projects I worked on ran on a single Digital Ocean droplet.
I found out that what fascinates me in the industry is the craftsmanship. It was difficult to admit but I didn’t want to build a company - I wanted to build software. I wanted to think about scalability, architecture and software design, not product market fit.
So I left my startup aspirations behind (at least for now) and decided to enjoy the journey of growing as an engineer.
Changing jobs #
There are two things that I’m looking for in a job - learning and earning. Having both is great, one is enough but neither isn’t. Ideally you want to be at a place that pays well and gives you room to grow but not all opportunities exist at all times.
The trade-off that you’re making depends on your position in life and what’s important to you at this point. As a beginner I’d recommend aiming for jobs where you can learn the most. They will allow you to find more profitable positions in the future.
Chasing titles #
I’ve always been forward driven. I did a lot of martial arts when I was younger and didn’t shy away from competition. Naturally, I respected titles.
To me senior engineers were the equivalents of black belts in Jiu-Jitsu. The title represented how good of a developer you are. But focusing on that is not a good way to grow because titles are sometimes subjective.
I was willing to accept an offer just because of a fancy sounding name. To be given a title means that you’ve grown right? Well, there are plenty of companies that would give you any title you require, short of CTO, in order to attract you. Chasing titles is a good way to feed your ego but not your mind.
My priorities were off. In our industry it’s knowledge that brings the most benefits. As they say in martial arts, the belt covers two inches of your ass, the rest you need to take care of yourself.
Ego can hold you back from good opportunities if they can’t match your current title. Sounds cliched but it is true.
One of the toughest decisions I’ve made was going from senior to mid-level engineer at a larger company. Looking back it was the best choice in my career for I learned more than I could’ve in my previous role. When I got the chance to join a strong team I didn’t hesitate going from tech lead to senior engineer.
Being a senior engineer #
Ask a hundred people about what makes someone a senior engineer and you’ll get a hundred different answers. The common idea in all descriptions that I’ve heard throughout the years is deep technical knowledge but there’s always something more.
Some say you need to be a leader, others that you need to communicate well. In some companies senior engineers are given line management responsibilities. Often they need to lead initiatives and complex tasks. They need to help others, to guide and support their more junior colleagues.
I can’t get to a proper definition but being a senior engineer means that you can make an impact. You’re not just another developer - you’re the person others go to with their problems. Your opinion is asked for in meetings. You are expected to make decisions.
You’re the person that puts his work aside so you can help a struggling colleague. Even though your hands are itching to write you know that when the others are blocked it doesn’t matter how much you can accomplish. To me, a senior engineer is someone that holds the team together.
Beyond senior #
This is the place where I’m at right now. There are two directions that you can take - management or further technical growth. None of them are easy and contrary to popular belief, management is not the natural path of progression. Not everyone should and not everyone wants to be one.
I always thought I wanted to be a manager. When I became one I realised that I’m more of a leader. The difference is that I want to be with the people doing the charge. It was hard for me to detach myself from the work and be satisfied with a high level view.
I spent half a year doing more talking than writing and this didn’t give me the sense of fulfilment I expected. Don’t get me wrong leading is an incredible experience. I managed to make an impact that I wouldn’t have been able to do otherwise. We delivered a grossly underestimated project and I got one of my reports promoted. But I always felt that I could help more by writing code.
Maybe I’ll go back to management after a while, I just find coding too exciting to step away from it now.
A word to those just starting out #
Whatever happens don’t let yourself become cynical. It takes a long time, it’s not easy but it’s worth it. You’ll learn a lot, meet great people and build the future. What more could you ask for?