Lessons learned from a decade of programming

Recently, as I was pondering about my career and what I’ve accomplished so far (and haven’t accomplished), I realized it’s been around 10 years since the first time I got paid for a programming job.

The very first assignment I received was from a local chorus band, which had a tiny budget for a new website. I worked my ass off to get them the best possible website I could given my limited skills at the time. It reduced my hourly rate to less than what I could’ve earned working at a fish & chips shop, but I felt an undeniable sense of accomplishment in making money from website coding.Since those humble beginnings, I have been fortunate enough to work at a digital marketing agency, a university’s IT team, an early-stage cryptocurrency start-up, a Fortune 500 behemoth, as an independent contractor, and then at Uber. Now, I'm back into freelancing and indie hacking.

During the decade of programming, I learned a whole lot -- not only about programming, per se, but also about other related skills and topics, i.e. soft skills, tech market, personal development, etc. In this article, I want to share with you some of the key lessons that transformed and catalyzed my career in hopes that they do the same for others.

Patience is key.

Most of the things you code take much longer than you'd like, and you will constantly run into all kinds of bugs or unexpected problems. Try not to panic, ever. Most problems can be solved with a diligent approach. Sometimes, you just need to bang your head at a problem for long enough before a solution appears seemingly out of nowhere. There are instances where you’ll need to refer to someone with more experience for help, and inevitably, there are cases where you’ll simply need to give up and try a different approach.

Anyhow, get used to the fact that your job as a programmer is to solve problems. In order to solve those problems, you need to always stay clear-headed and optimistic that a solution can be found.

Patience plays a huge role, as a lot of the problems you’ll run into seem as though they shouldn’t exist at all, like some minor package upgrade breaking your code or tools not working for inexplicable  reasons. That’s just part of the daily grind and either you have to accept it as part of the job or you’ll go crazy.

Leverage existing solutions.

The key to building a successful career as a programmer is cultivating the ability to learn and research quickly. Google-ing is a skill you can develop, and I have certainly gotten good at it over the years. There are many times where I spent far too much time writing custom code for a problem only later to find that there is some library or code snippet somewhere that already does exactly what you want.

Thus, my best advice is to always thoroughly research what’s already available out there to help solve your problem and leverage that solution as much as possible. Besides, a lot of programming nowadays is glueing things together so the better you get at it, the more value you can create in less time.

A successful career requires a healthy body and mind.

Yes, you can still achieve a lot while eating burritos and drinking Coke. However, your potential diminishes  if you never learn to take care of your body. I can tell you from experience that whenever I fall off the wagon health-wise -- either due to bad eating habits, going to sleep late, not moving enough, etc. -- my productivity vastly diminishes. While I can adequately perform even in a suboptimal state, having a healthy body and mind reaps immense productivity dividends.

Salesmanship pays off.

Even in a career like programming, one benefits tremendously  from being able to sell their skills and ideas. I especially noticed this while working at Uber, where blindly implementing features at your manager’s request only gets you so far. In order to climb up the ladder, one has to become great at identifying problems and proposing solutions in a convincing way. This way, you can influence various product decisions and become an effective problem-solver instead of merely a competent coder.

Knowing how to sell applies to other work arrangements, too. For example, if you want to get better clients as a freelancer, you also must sell yourself in some manner, as potential clients need confidence that you’re the right person for the job. The ability to sell yourself will set you apart from the average coder, giving you a competitive edge in the job market.

Master fundamentals; stay away from fads.

It’s well-known dogma that in a programming career, it’s essential to stay ahead of new tech to avoid becoming outdated (with some exceptions). Even in my case, there are technologies that were industry standard, and I used extensively, that are already obsolete. I’m looking at you, jQuery.

However, even though constant learning iis a must, I’d advise you to stay pragmatic and always question whether what you are learning is fundamental to your discipline and  unlikely to attenuate any time soon, or whether it’s shiny tech that has not yet proven the longevity of its relevance.

When it comes to learning new technologies, I am usually quite conservative and defensive of my time and energy and thus wait to see whether some new library or frameworkI might consider learning is here to stay. Even for fundamental topics, I question whether I really need to learn it now, or if there is a better way to  improve my skills, like simply experimenting with something myself rather than starting a course on some new topic.

Roadmap.sh has some great resources -- especially for those closer to the beginning of their careers -- for deciding what to learn next and in what order.

Get used to not knowing what’s happening underneath.

Computing is built on the idea of abstraction. This means that in order to write functional code, you do not have to understand the details of TCP/IP protocol, how a computer processor works, how the library that you use for queueing does its magic, or even how V8 translates JavaScript code into machine code.

No matter at which level of abstraction you are programming, there is always going to be a layer below. It can feel disconcerting, especially if you like to feel in control. However, you have to let this one go and accept that you will never know absolutely everything, even in your own computer, and that’s okay.

Programming is not a dead-end job.

A dead-end job is a job where there is little or no chance of career development or advancement to a higher-paid position. There’s a common misconception that programming may be one of those jobs because at some point, growth opportunities become limited, especially if you do not work at one of Big Tech companies, which have a tall career ladder for managers and engineers alike.

And while I do think that knowledge gained after the first few years of programming becomes increasingly incremental, and thus the biggest salary growth is most likely going to happen toward the first decade of your career, there is still a never-ending supply of ways to grow as an engineer. I find that if you keep the same hungry spirit for improvement as when you started programming, you will soon reach  a stage where the things you are capable of building are unreplicable by other programmers. If your skills become increasingly rare and valuable, you can charge increasingly higher rates. There is a great book on the topic called Deep Work that discusses that exact point in more detail.

Alternatively, if you decide that programming may not be something that you want to do forever, it’s a great step toward the next path in your career, whatever it may be. The problem-solving mindset that a programmer has to develop to be successful can translate into an effective tool for any other professional outlet.

Managing expectations is part of your job.

One of the mistakes I made at the beginning of my career was being too eager to prove myself and, in turn, frequently overpromising on how fast I could deliver a new feature. However, over the years, I learned that it’s much better to set realistic expectations rather than overpromise, even if your manager or client pushes you to do so.

The first obvious reason to push back on pressured deadlines is to provide  more leeway if development does not go as fast as expected, which is almost always the case.

The second is that  your client or boss usually depends on your deliverables, as they themselves have to report to someone else or have some kind of deadline. Thus, over the long-term, they will appreciate it if you’re straightforward in regard to how long you think things are really going to take and try to stick to those estimates. In this way, they can better plan and avoid frustration from stakeholders when things go  slower than promised.

Granted, giving estimates is an incredibly difficult skill, and your estimates will almost always be off by a factor of 1.5-3x or more. However, it’s a skill you do get better at with time, and while I still find myself being too optimistic with timelines for most tasks, I’m much better than I once was.

Customers don’t care about your code.

While coding is indeed a craft, unfortunately for us programmers, customers rarely care how the code looks underneath. This means that you should always strive to write the most pragmatic code possible. The stability and maintainability of code should be the first priority, not using some fancy new programming paradigm or framework. Quite often, trying to use what’s latest and fanciest actually results in more problems than it’s worth. There is a great essay, “Choose Boring Technology,” that gives deeper insight on this topic.

There is no one path to success.

During my career, I’ve met a lot of different kinds of successful programmers, and the way they reached success varies wildly. Some are generalists; some are specialists. Some attended university; some did not. Some work 4 days a week; others work only remotely. Some work at large corporations; others only do contracting jobs. Some have open-source projects on GitHub, and others don’t.

The key message here is that you should do you. Don’t be afraid to experiment and find what works for you. And while it’s helpful to see how people further in their careers got to where they are now, don’t get too hung up on it. See what moves and inspires you, and do as much of that as possible.

Don’t get hung up on titles; focus on balance in your bank account.

While job titles do matter if you are looking for prestige, I’d argue that what matters the most at the end of the day is how much you actually get paid and what work-life balance you’re allowed. Thus, I try to not get hung up on how my title sounds and rather focus on what my actual responsibilities are and how much I will get compensated for taking care of them. I often receive job offers for senior developer positions, but they pay even less than what junior engineers make at any Big Tech company or even what you could earn in a week by doing contracting work. Go figure.

Pay close attention to your workplace.

There is a really interesting study, “Why Measure Performance,” that tried to measure which factors have the most notable  correlations with coding performance. The study was conducted by asking all participants to implement a medium-sized program and then measuring how fast they did it, as well as how many bugs were in the program.

Interestingly, language used to implement the program, years of experience, and salary were non-factors when measuring participants' output. This means that none of those factors could predict how well or how fast a person would perform the task. Also, even the number of defects introduced in the program were not a factor, meaning that those that implemented the program quickly did not necessarily introduce more bugs while doing so.

Another interesting note is that peers from the same organization performed relatively similarly, and the biggest difference in performance arose from peers from different organizations. Over 92 competing organizations, the best organization (the one with the best average performance of its representatives) worked 11.1 times faster than the worst organization.

So finally, what is the one factor that did correlate with participants' performance? It’s the workplace. The top quartile, those who did the exercise most effectively, worked in the space that was quieter, bigger, more private, and better protected from interruption.

This may only show that those that perform well tend to choose workplaces that have those qualities. However, given my experience, I’d say that it’s definitely not just that. Whenever I have to work in crowded open-offices, my productivity absolutely plummets. One of key reasons is probably that, at least in my case, I have to spend a lot of extra energy just to avoid distractions from people walking around and talking, which, for me, is a major productivity-killer. So, now, whenever I’m evaluating a new job opportunity and the position is on-site, I pay close attention to what my workplace is going to look like, as I know that it will have dramatic effects on my productivity and personal wellbeing.

Impostor syndrome is real.

Impostor syndrome refers to feelings of inadequacy that persist despite evident success. According to a recent survey by Blind, 58% of tech workers feel like impostors. For me, impostor syndrome manifests as a fear of being exposed for not actually knowing as much as others might think I do. This is really evident in interviews, as I get genuinely surprised each time when the interviewers or clients actually think of me as a good candidate.

Having said that, as I keep developing as a professional, I realize that there is indeed a whole lot that I don’t know about my craft and may never have time to learn. However, all one can do in this case is accept the fact that no one ever knows everything. Also, during those times of inadequacy, I like to remind myself of what I’ve managed to achieve to bring some rational thought into the racing mind.

Finally, in regard to managing impostor syndrome, what really helps is comparing your current self to your past self to see where the trajectory is headed. As long as it’s going in the positive direction, you are doing fine.

Aim to never do the same work twice.

Identify where the bottlenecks are in your workflow and aim to automate them or minimize their impact. Any repeatable task that can be automated and is not yet automated should be considered a bug in your workflow. While sometimes it can feel cumbersome automating every aspect of one’s workflow, picking at least the lowest-hanging fruit is going to provide huge productivity gains over the long-term. These gains are not only due to time saved, but more importantly are due to fewer interruptions for  mundane tasks, thus having more focus for difficult, creative aspects of the job.

As a quick first step for instant improvement to one’s productivity, start using a snippets tool -- something like Snippets Lab, for example. Each time you search for a code snippet, create an isolated piece of code that could be useful in other projects, or need to save a hard-to-remember server command, save them in your snippets tool with titles and tags that make them easy to find in the future. I only started doing this a couple years back, but it is perhaps the most important habit I wish I’ve started sooner.

Technical debt is not free.

Technical debt is a debt like any other and has both benefits and drawbacks. Sometimes, it’s worth taking on the debt if it gives you leverage to move faster and, for example, helps your company avoid going bankrupt. However, deciding to take on technical debt needs to be communicated with your manager or client so that they are clear about  taking technical debt and avoid surprises when at some point in the future, it may hinder development velocity.

Another note on the topic is that you can’t keep taking technical debt forever, as at some point, it becomes such a burden that it gets very challenging to maintain a codebase or make any changes to it. Thus, when taking technical debt, be mindful of whether it’s essential given the circumstances or whether it’s just laziness on your part for not doing it properly.

Final note.

I hope you took away something useful from the lessons I summed up here. There are many others that I might have forgotten about or didn’t articulate in the article well enough. Anyhow, all I can say is that so far, programming has proved to be an intellectually-rewarding and lucrative career. And really, just like any other career, what matters most is what you make of it. Now, let’s hope for as eventful a next decade as the first one. 🤞