A few weeks ago, a friend texted me asking for advice. She was interested in learning how to code and wanted to know how I had done it.

While I did take a handful of Computer Science classes in college, I consider most of my relevant, day-to-day software development skills to be things I picked up through self-guided learning.

My initial advice for her was going to be pretty banal – sign up for Codecademy or Treehouse or one of the many “learn to code in 12 weeks” bootcamps.

But before I could send her that text, I realized that my own path to becoming a full-time, freelance software developer didn’t really look anything like that.

While there are a growing number of programs, classes and websites that purport to teach you coding skills in a short amount of time – and I’ve played with a few of them myself – I don’t really see them as an effective path to learning the kinds of skills one needs to be a competent software developer.

And so, to answer her question, I decided to take some time to look back on what I actually did, and what got me to the point I’m at today, earning a living writing code for people.

Text files ending in .html

It all really got started for me out of sheer boredom over winter break in 2008, during my freshman year of college. Having refreshed my Facebook News Feed for the millionth time that day and not found anything interesting, I decided to click the magic “view source” option in the browser and see if I could understand any of the HTML. Of course, it was all completely indecipherable to me, but I did notice the “.php” extension in the facebook.com/home.php URL.

That piqued my interest and after a bit of googling I discovered that PHP was some kind of language that would produce HTML for a browser to read. It all sounded really complicated so I figured I’d just start with the HTML part.

I opened up Notepad on my Windows laptop and saved a file to the desktop, making sure to change the extension from “homepage.txt” to “homepage.html”. From there, I read through the w3schools tutorials on HTML and built a page using table elements for layouts.

I’ll always remember the first time I opened a new tab in my browser and opened the HTML file on my desktop and saw a freaking web page that I had just freaking made. I mean look at it! It looks like a web page, and I made it!





It was probably the first big “AHAHAHA!” moment that got me hooked on building stuff with code. I felt like a superhuman. Maybe I could build a site like Facebook! But not quite yet…

I bought a domain, picked a $5 webhost and figured out how to upload my shiny new HTML file so that the world could see it. I proudly emailed my site to some of the guys that worked on the campus life blog.

After a few days, I hadn’t heard back from them, but I bumped into one of them on the quad. “Yah… your site is… umm… you should really learn CSS,” he told me, shuffling his feet and avoiding eye-contact. “Using tables for your layout is a bad idea, and using inline styles is… you should learn CSS.”

I felt so ashamed. Rather than being a beautiful work of art, someone who knew what they were talking about told me, ever-so-politely, that my code was a steaming pile of turds. Maybe this coding thing was going to be a lot harder than I thought.

I went to the campus library and found a book on CSS that was probably a thousand pages long. “Nope, not reading that,” I thought. I’ll stick with using tables for layouts, thank you very much.

Getting started with PHP

Fast forward a few months and I had added several HTML files to my website. But it felt lacking, it didn’t “do” anything, just showed the same text to every visitor, over and over again.

I started looking into PHP again. At this point, I had learned a thing or two about if-statements and for-loops from my Computer Science 101 class, so it was a bit less intimidating.

My first project was adding a “guestbook” to my website, that would email me whenever someone left a note. This was super exciting because now my website actually did something! People could interact with it and change it so it wasn’t always the same!

You might think that I had to setup a database and “learn” SQL in order to be able to insert people’s comments into said database, and then read those comments back out when the page was loaded.

What actually happened was that I spent many hours googling around for “PHP guestbook script”, copy/pasting the parts of other people’s code that seemed to be working until it did what I wanted. I was a hacker, not a developer.

I got a few “nice job” comments from my friends over the next few days, and each email notification I received made me so proud that I had built something that worked on the internet.

But it only took a few more days before the spambots found my lonely little website and proceeded to fill my guestbook with ads for enlargement supplements. My wonderful little guestbook was being vandalized by strangers on the internet whom I didn’t even know!

“The internet must be a scary place.”

Building a Blog

By the fall of 2009, blogging was starting to be something that average-joe people did. It didn’t occur to me that there’d already be software built to make this process easy, so I set out to build my own little blogging engine so that I could participate.

I created a folder for all the blog entries, and would add HTML files whenever I wanted to add a new article. I gave them datestamp file names like “2009-10-04.html” and wrote a simple loop in PHP to iterate over files in the directory, concatenate them together, add a header and footer and build my HTML homepage.

There was no way to view a single article by itself, there was only one page with every article strung together. Wanting to give my “audience” (aka my parents and college roommate) more control over their browsing experience, I began learning AJAX and added some buttons that let a visitor choose which month’s articles they wanted to see. Then the for-loop that strung together articles would filter out ones that didn’t have the right numbers in the filename. Brilliant! It felt so simple and elegant and look at me making a freaking blog as if I know what I’m doing. People might actually think I know how to do this stuff.

At some point, as a prank, one of my friends on the swim team started going into the school library and setting the browsers’ homepage to be my new blog. I didn’t have any analytics setup so I had no idea I was getting all of this traffic until an acquaintance from one of my classes mentioned he had seen my blog on the library’s computer.

A bit ashamed of the new-found attention, and worried that people might think I was the one who was setting my site as the homepage, I hunted down the perpetrator and asked him to stop. His response was to laugh maniacally and basically say, “make me.”

Realizing that diplomacy had failed, I knew that I needed to resort to bigger guns – code. So I hatched a plan: if a visitor was coming to my website from an IP address on campus, I’d redirect them to an embarrassing picture I dug up on Facebook of said friend drunkenly at a party, with a note about how he had been messing with the school computers, and offering a link to Google, a site the unsuspecting visitor might actually wanted to go to.

I visited the “what is my IP address” websites from a few different spots on campus to get a sense of the IP address ranges an on-campus visitor might have. Then it took a few hours of googling around for how to find a visitor’s IP addresses in the request and how read and write HTTP headers and how redirect users to a different page, but eventually, my plan was complete. I called a few friends at other schools and had them visit my site to make sure they weren’t seeing the image, and then I tried it from the library computers to make sure they were.

I felt like a mad scientist. Look at how much power I wielded with my simple website! Someone was trying to use it to embarrass me, but I was able to come up with a clever solution and a few lines of code to turn it around on him!

Learning More About Media & Content on the Web

In the spring of 2010, I started a college music blog with a friend and former roommate. This time, instead of building my own blogging engine, I did a bit more research and discovered blogger and wordpress and found them to be infinitely more powerful and flexible than anything I had written.

Since I didn’t know about version control, I just threw all of my old code away. Won’t need this anymore!

By the fall of 2010, the music blog was having fairly moderate success – thousands of daily visitors and climbing. I remember the first time I walked by someone I didn’t know who was on their computer, browsing the site.

Hell yah, baby! The internet has so much potential for building cool stuff and reaching new people!

That fall, I came up with the idea of creating a site that would aggregate content from the top music blogs. Basically an RSS reader for people who didn’t know what that was or want to use one.

I did a bit of googling about how to read RSS feeds and found a lot of people recommended using a particular library. I didn’t know what a “library” was, but I looked at some example code that used it and it seemed pretty cool.

You mean I don’t have to fetch the URLs and parse the different XML formats myself? I can just tell this library the sites that I care about and then simply read out their content? And I can use this code for free? Wow, open source code is great! Thanks, whoever wrote this.

I put the site together in about a week and coordinated a big, splashy launch with the sites it featured. I pulled in 14,000 visitors that first week.

Learning a Second Language, Properly This Time

By the summer of 2011, I was an intern on the marketing team at a mid-sized software company. The company had open seating where all the teams were mixed, so I was sitting among real programmers and tried to overhear their conversations to find out what that was like.

I heard that you could now buy servers from amazon.com and that Twitter released some CSS that everyone could use. Javascript was getting more popular, but Python was the way to go if you want to have code running on the server.

I offered to build some internal tools for the marketing team. I had never built something that wasn’t my idea before, and certainly never anything that a real business relied on, so I was really nervous.

I decided I needed to level-up and start writing code that was written cleanly and that executed efficiently. No more copy/pasting other random code snippets from the internet, I needed to Know What I Was Doing™.

The code I wrote wasn’t just going to be hidden on my web server – other, real developers might actually see it, so it needed to be in ship-shape.

I decided I had to learn Python, so I read the 20 chapter introduction on python.org and got all sorts of confused about all sorts of stuff. What’s a tuple for? I don’t understand how default parameters work. What the heck is a splat?

I learned about object-oriented programming and how to write files of code that didn’t just execute from top to bottom (“scripting”, I learned that was called).

Eventually I put together a data pipeline that took data from one system, changed its formatting, and inserted it into another system. I had to learn about SOAP and APIs and these reverse-API things called “webhooks”.

The pipeline helped save a coworker hours each week of manual data processing. She was elated that I had automated this work for her, and she was super encouraging about it. “Thank you so much! This is amazing!”

A few months later though, she was singing a different tune. For some unknown reason, my code was no longer working and everything was getting out of sync. “Where is all my data?? It needs to be there! Everything is getting backed up! What’s going on?”

Holy shit. I had no idea what to do or what had happened. My code didn’t change, and the server seems to still be up. “Uhhh….” was all I could muster.

Here I was, thinking I was a programmer and building things that a large company trusted to move important, timely data around. When it broke, I had no idea what to do.

I recruited a few friends on the engineering team to help me figure out what was going on and one of them quickly suggested one of the APIs I was using had changed. “Of course! That made so much sense, why couldn’t I have thought of that…”

I was disappointed in myself and I felt embarrassingly incompetent. Maybe I should stick to marketing. This coding things seems really hard. I don’t know if I’m cut out for it.

A Fragile “Web Developer” Complex

Several months after that incident I was asked to work on a public web app we were building to help generate leads for the business.

It was going to be written in Python but it would also use this thing called a “web framework” that helped you organize your code and did a lot of things for you like handling requests and talking to databases and stuff.

“Django,” it was called. The difficulty I had pronouncing its name was foreshadowing for the massive struggle I would soon encounter when I tried to actually build things with it.

This time, there were a few engineers from the core product team assigned to work with me and a few other interns on the project. All I really remember from those next few weeks was struggling for hours and hours just trying to get the code to run on my Windows laptop, and feeling like a complete failure.

Nothing was working and I was too embarrassed to ask for help, but I also couldn’t make heads or tails of the errors I was getting by myself.

Fortunately, the real engineers I was working with were very patient and kind. “Yah, Windows is tough, its not your fault,” they’d say, reassuringly. “Believe it or not, I used to struggle with this kind of stuff too.” I assumed he was lying to help me save face, but I appreciated the sentiment.

Eventually, I started to get more comfortable working with Django and Python. I hung out in the Computer Science department on campus and started reading books about Python. I remember the first time I successfully used a list comprehension and a lambda function. Fuck yah, this is like real programming!

I decided to rebuild my college music blog aggregator in Python and planned to add a bunch of features. One of which was the ability to learn your preferences based on the articles you clicked on and somehow highlight other articles you might like.

I started reading a bit about machine learning and, to my surprise, it wasn’t totally over my head. I could follow along and build a few of the toy projects in the book that I checked out from the library. But eventually it was finals week and the book was due back and I never implemented anything. Maybe some day.

By this time, I had gotten a bit of a reputation as a “coder” on campus and I was approached by a fellow senior who had an idea for a startup. The idea was born out of the struggle his younger sister was having sharing and discussing prom dress ideas. He had a cool name for it and it seemed like something I could reasonably build. And so, the social network for fashion was born.

The server-side Python stuff was pretty straightforward, the hard part was making the website look and feel like a social network. Facebook had set the bar really high – people expected everything to happen magically with no page reloads. If someone posted a comment with a URL, that comment needed to show up in the discussion thread immediately, the URL needed to be detected and turned into a clickable link, and we needed to try to pull in a preview of the page they’d linked to. All of that just to support URLs in comments!

I wove a tangled web of jQuery with tons of nested callbacks stuffed inside $(document).ready() . Things were getting unwieldy, fast. At one point I decided it would be a good idea to upgrade the version of bootstrap we were using and I noticed a bunch of tiny things broke. I had no comprehensive way to test everything or manage other people’s code that I was depending on. I got very little sleep that week, staying up to odd hours playing whack-a-mole with these bugs.

But despite how embarrassingly ugly the code was, the site looked alright and functioned decently. Smart people that I trusted to be honest told me the site looked “cool”. Man, look at me tricking people into thinking I can build quality software.

I started reading more books and blogs about building software for the web at scale. I started learning about best practices and why they were important. It wasn’t just that your code needed to barely function, it should be easy to read, scale and maintain in the future too.

By the time graduation rolled around in the spring of 2012, the site ended up petering out, as most startups do, but I was really proud of what we built.

Sneaking onto a Software Engineering Team

The job offer I had after graduation was to join the marketing team at the same company where I had screwed up the pipeline and taken forever on the web app.

I was supposed to join a group within marketing known as the “Marketeers” who built stuff to support marketing. But a few weeks before my start date, that group was moved from being within marketing to being a part of the product team, where it would have better engineering support and management.

I was given the option – I could either stay in marketing and join a different group, or I could move over to the product team and be an engineer. I’d have a quick interview to make sure I wouldn’t be over my head, but if I got the green light, I’d officially become a “product engineer”.

The interview was with a senior engineering manager who had a reputation for being curt and ruthless. To say I was nervous was a tremendous understatement. He asked me to show him something I had worked on and I tried pulling up the homepage of the social network I had built. It took 30 excruciating seconds to load.

He glanced at me sideways. “Why is this so slow?” I rambled something about lots of database queries and shuffling data around and maybe one of the servers is down. “How would you debug this?” I had heard of the Django Debug Toolbar which makes it easy to see where your slow queries are in an application, so I mentioned that.

He scrolled around and clicked on a few things. “Alright” he said. I was in.

I guess I had built a few pieces of software and had definitely learned a lot in the past year or so. And now, here I was, on an actual software engineering team.

I was working with other real engineers who followed best practices. I was using a proper IDE and a well-tuned development environment that I setup in a single morning.

I got to hang out with Javascript developers and ops gurus and ask them a million questions. I had an opportunity to see what real-life, production, high-quality code for thousands of paying customers looks like.

Things were going great until suddenly, they weren’t. On a Friday afternoon, I accidentally hard-coded some admin configuration data, shipped them to production, and then packed up and went home. Within a few minutes, part of the product was broken for all customers, and I had taken down the homepage of the company I worked for. A coworker was able to roll back my commit and someone else had to restore the homepage from a backup.

“What am I doing here? I don’t deserve to be here.”

Gaining Confidence

By the middle of 2013, I had started working on a few more independent side projects. I tried to do another startup, building a marketing platform for musical artists and learned the hard way why real-time analytics at scale is such a rare feature in big products (hint: it’s really hard).

I started working with the Flask web framework for Python, instead of Django. I could see differences and similarities in how things are done, and started to recognize high-level design patterns. I also started learning more advanced web topics like caching and database optimizations and service-oriented architectures.

That summer, I got a job as employee #1 at an ad-tech startup. In my interview, I remember being able to answer most of their questions about load balancing algorithms and their tradeoffs, and what HTTP, TCP and UDP were and how they differed. I struggled a bit doing some joins in SQL but I went home and watched some coursera classes and was teaching the topic to some junior developers we hired a few months later.

I told them in my interview that I didn’t know much about lua or nginx or high performance computing or “big data” or any of the other technologies they were using, but I was told not to worry. I’d figure it out.

And eventually, I did.

I started working more independently and designing systems with decreasing oversight. I still managed to ship code on a Friday afternoon that broke everything, but this time I realized right away, fixed it, and wrote up a post-mortem to share what went wrong with the team.

I was able to keep track of “code smells” – small symptoms of some larger issues – and got better at spotting them in my own code. I kept an eye on the things we were doing as a team and looked for patterns of behavior we could improve.

I lead the charge to come up with our own internal git best practices and organized a weekly tech talk to help people share what they’d learned with the team. I no longer felt like an impostor when I told people I was a software developer.

It only took me six years.

Lessons & Advice

I realize this story is already pretty long, so I’ll try to summarize some takeaways for people thinking about starting this journey.

Don't just read and watch other people code, do it yourself

There are a lot of well-meaning people who will tell you to watch these videos or follow this tutorial and you’ll be able to code in no time.

In my experience, this method of learning “feels” fast cause look at what you just built! But when you have to step away from the lesson and build your own thing, you often haven’t actually learned much about how to solve problems with the technology. Just do whatever feels natural to you and get started.

Start with projects you want to work on

It doesn’t matter if what you’re doing has already been done. Just build a version of something you’d use yourself and iterate on it.

Having a personal interest in the problem will help you come up with creative solutions and will keep you interested when you inevitably get stuck on something.

There will be lows

You’re going to get frustrated and screw things up and be embarrassed and want to quit. That never stops happening, no matter what level you get to (as far as I can tell).

Err on the side of making the mistakes yourself, not getting it "right"

There are a million different blog posts containing conflicting information about the “proper” ways to do everything. If you feel stuck, just keep on pushing forward with your original idea and make it work. You will eventually figure it out and will be so much prouder of your solution because you stuck it out. Plus, you may pick up a battle scar or two which helps guide you next time you’re solving a similar problem.

Learn only as much as you need to know, just when you need to know it

Start with a problem you’re trying to solve – like getting information from RSS feeds or sending email – and learn just enough so that your program does that. Then move on to solving the next problem.

It’s going to be difficult enough to cram a new technology into your brain and make sense of it all, don’t try to pull in superfluous information with it.

As you get more experience, your learning style will change. But don’t try to learn everything right out of the gates. Just what you need to solve the next problem.

Learning is about solving problems, not memorizing syntax

Even though all of those weird symbols and rules for writing things feel like some esoteric mumbo-jumbo, you’ll get past that relatively quickly.

No one gets good at programming by memorizing all of the weird little rules and bits of the language. Instead, focus on using code to solve problems. You can build tons of stuff only knowing arrays, hashes/dicts, if-statements and for-loops. In fact, I got by for years only knowing those 4 things.

It's an ongoing learning process

There’s always more to know, and the state-of-the-art and “best practices” are constantly evolving over time.

If you’re expecting it to be like riding a bike, where once you get over the hump of figuring it out for the first time, you can stay competent and relevant forever, you might get overwhelmed. But if you love learning – from others and from your own mistakes – it’s a great place to be.

They say that if you aren’t embarrassed by the quality of the code you wrote 6 months ago, you’re not learning fast enough.

You probably know more than you realize

There’s something called impostor syndrome which the astute reader might have noticed I was exhibiting at several points in this article.

It’s a psychological condition that’s fairly common in amongst people who write code, where you don’t really recognize all that you’ve learned and accomplished. You chalk successes up to luck and good timing, whereas failures feel like something you really deserved.

I’m not really sure why it’s so common in this business, but I see it everywhere when people downplay their successes and accomplishments. You might end up doing it too, so be sure to give a hearty fist pump when you finally fix that bug or solve that problem. You earned it.

Send me a note on Twitter if you enjoyed the post.

Thanks for reading this far! If I sound like someone you might want to work with, I’m currently accepting new clients. Get in touch :)