20 mins

As a programmer, how can you gain the skills you want and need to shape your team, your workplace, and your industry?

Around this time of year, many years ago, I received my first offer for a programming job. At the time I had written Java academically, and then I had written some Ruby in a post-academic program. So I showed up for my first day as a software engineer at Pivotal Labs, and they started me on a Golang project.

Over the next three years, I moved from project to project and picked up Java (for server and Android), Objective C (for iOS), .Net, Swift (also for iOS), React, Kotlin, and Python. I got good at picking up a new language or framework every few months. I could ramp up to a professional level on a new technology in two to three weeks.

But even if you’re working in the same programming language for a long time, tech is a fast-changing field. Languages and libraries come out with new versions, the preferred tools change.

Maybe my experience at Pivotal Labs is an extreme example, but we all do this to some degree. We keep pace with our current field, and our field is constantly changing. And we’ve developed strategies for this. We have learned to Google the error message. We have some sense of what to try to get it working again. We know how to run short experiments, to get quick feedback on how to fix problems. And those skills allow us to keep up with our field, perhaps without even meaning to.

They allow us to stay current, and the longer we continuously stay current, the larger library of experience we build up behind us to inform what to do the next time we need to do an unfamiliar task.

I call this leveling up passively.

If you’ve participated in any role-playing games like Dungeons and Dragons or a first-person console game, you’ve experienced leveling up passively. You keep playing, you keep solving little problems, you keep gaining experience points, and then your character’s level rises incrementally from one to two…to three….to four.

You know how to level up passively, and it’s great for staying current on the skills you already have. But when our work is changing, that’s not enough. We need to pick up new skills to thrive amidst all this change. And that doesn’t just happen; we have to make it happen by learning the skill of learning new skills.

You know you’re able to learn because you do it all the time as you’re passively leveling up. But when you add a skill set to that raw talent, you have something a little different. Instead of leveling up passively, we’d be leveling up deliberately.

What does it mean to level up deliberately?

 1. Develop a specific vision.

Back in 2014, I told myself 'I’d really like to know about machine learning.' It’s a great idea, but it’s completely not specific! Curriculum design is the art of taking a vague idea like that and turning it into a series of steps that works for a diverse group of people who all learn different things at different rates. It’s difficult. Even many of the published curricula on machine learning didn’t work for me. They didn’t work for me for two reasons:

The first reason curricula didn’t work for me is that I like to dig holes. When I’m listening to a lecture or reading a blog post and I come across a concept that I don’t quite understand, my instinct is to dig deeper. So I’ll go and find another blog post that explains that concept, but that blog post introduces another concept and I have to find out about that, and so on and so forth until I have seventeen tabs open and I don’t remember where I came from anymore. It’s hard to measure how you’re doing when your progress on the curriculum doesn’t account for all the times you stopped to dig holes.

The second reason curricula didn’t work for me is that my failure to follow the ever-forward path of a curriculum made me susceptible to mood metrics. On days when I had gotten enough sleep and I was feeling good, I was happy with my progress so far on knowing about machine learning. After all, I knew more things! And the concepts I understood, I understood deeply. But on days when I felt anxious or depressed, or I had slept poorly or I’d had an altercation at work—on those days I felt the complete opposite. On those days it looked to me like I had hardly gotten anywhere and I would never accomplish my goal. It’s hard to work on something when you feel so terribly about your progress.

So I switched from following curricula to working on practice projects. I knew I wanted to become a machine learning expert, but why? What was I going to do with all that expertise?

Well, if I were a machine learning expert, I’d be able to use my expertise to help identify bias in compensation plans. So I did a practice project about that. And if I were a machine learning expert, I could build visualizations that made it easier for people to understand what machine learning models were doing. So I started doing that. I came from a software engineering background, and I could take the principles of test-driven development from software engineering and figure out how they applied to machine learning code. So I started doing that.

My projects don’t stop me from digging holes, but they add focus to my hole-digging. I keep digging until I find what I need to implement and explain the next step of my project. And then I feel motivated to move on, because I want to do the project.

So when folks have struggled with traditional curricula, this is what I suggest: figure out what, specifically, you want to do with the expertise you’re trying to build, and start doing that. Find the knowledge as you need it to do that thing.

 2. Rely on discipline.

Do you know the one trick to staying motivated all the time through a long slog? It’s very simple. Don’t.

No matter what I’m doing, and no matter how much I want to accomplish some long-term goal in theory, I have days when I wake up and I don’t want to do the thing that will take me one step closer to that goal. And that’s okay. We don’t feel great every day. We don’t wake up with the same motivation – or at least, it’s rare. So instead what I have learned to do is to take the next step whether I feel motivated or not.

There are some tricks to this. The first trick is to build it into my routine. When I work out, I do it in the morning. I like to have my coffee and walk to the gym and watch the sun rise. I like to sweat while it’s still cool outside and enjoy the endorphin rush on my walk to work afterward. Some days, I wake up and I don’t want to go, but then to not go I’d have to figure out how my routine changes. It’s mentally easier to keep doing my routine that I’ve practiced. So if I can manage it, I find setting aside time in my routine this way to be immensely helpful.

The second trick is to have a contingency plan. When I wake up and I don’t want to go, I don’t feel surprised or upset about that. I don’t take it as a sign that I’m just not cut out to be an athlete. Instead, I find one of my special 'I don’t feel like it' tee shirts. This is the stoic, valorizing one that says 'Because I said I would.' I also have one that says 'I don’t wanna' in all caps. I love these shirts.

I also have some special coffee that my friend gave me as a gift. I save gift coffees, and I make them on days when I don’t feel like doing things. They are a special treat that I get for doing the things anyway. And then I go to the gym in my 'I don’t wanna' tee shirt, and I do what I can, and afterward I take a gold star sticker and I stick it in my personal calendar.

The third trick is to keep a calendar. Or a journal. Or some method that works for you of keeping track of your work over time. I like to look back at it and see all the stars. They remind me that I can make progress even when I don’t feel like it. I also like to look back at it to see how far I’ve come, so on days when the mood metrics tell me I’m not doing well, I can remind myself where I was a month ago, or a year ago, and see that I am definitely doing something. Finally I look back to identify patterns. Maybe I discover that I don’t feel like going after a weekend with a lot of travel, or with poor sleep, and I can adjust accordingly. That’s what works for me, and if it doesn’t work for you don’t do it. But if you haven’t done it before, it might be worth a try.

3. Start with questions. 

Suppose I want to learn more about the history of web requests. There are a couple of ways I can do that. The first is to start with a book or an article, read it from start to finish, and hope that it answers my questions, or get sidetracked onto whatever else it talks about, or let a current of links wash me out to sea.

What has worked better for me is starting with questions rather than sources, and fishing for the answers to those questions. For example, I know that the SOAP web request protocol came along sometime in the ’90s. But the very first internet-transmitted message definitely happened in the ’60s or ’70s. So when did the internet go from an academic project to something that companies used? And when companies started using it, what happened between then and the SOAP web request in the ’90s?

I’ll search for answers to these questions with the help of Google or with the help of a book index. And then when I have what I need, I move on to the next source, going down my list of questions until I have learned what I set out to learn.

When I am doing research like this, there are certain questions that I think it is particularly important to ask. Every time I ask them, my understanding of the topic becomes much more interesting, so I’m passing them on to you.

First, if I’m answering a question and most of the sources I’m reading seem to be of the same opinion about it, I’ll purposely go looking for sources that have a different opinion about that thing. Wherever one perspective prevails, other perspectives have been pushed underground. And those perspectives often have important things to say. Understanding all the perspectives–including the dissenting ones–helps me make better decisions about the information I am learning. I am not missing an insightful angle just because it wasn’t popular.

Second, if I am reading an academic paper to find out if a certain procedure works or not, I’ll make sure I have read any limitations described in the paper. But I’ll also ask what limitations aren’t described in the paper. Not to shoot down somebody’s paper, but to understand a broader question: how and when could I apply this in the real world? As a software engineer, when I’m deciding how to write some piece of the app, it’s my job to consider the benefits and the risks of various approaches. Same with theoretical approaches, or cutting-edge approaches.

Third, if I am struggling to find the answers to my questions in literature, I find myself asking, who can help me? I think it’s easy, especially in tech, to feel like you’re alone and you need to be able to solve problems yourself. But I have found that not to be true. Sometimes it’s a matter of reaching out to a coworker or colleague to get another set of eyes on whatever I’m working on. 

If that doesn’t work, then I’ll ask an expert. And I have been repeatedly surprised by the generosity of experts. The first time I ever needed to implement Spring Batch in something, we had a complicated use case and I somehow just couldn’t get it to go. So I reached out to the team, and one of the Spring core contributors pair programmed with me to get the thing working. Another time, I was working with XGBoost, which is a machine learning library that relies on a particular, custom-crafted data structure called a DMatrix. But I couldn’t find anything online about how the data structure was built, so I reached out to a developer advocate on LinkedIn, and she gave me an insightful answer.

I have found community on Twitter and Github, in Slack channels and in Gitter forums. And it’s one of my favorite ways to learn because I get to meet people in the process. That brings me to my last item for today about leveling up deliberately:

4. Take care of each other.

When I was a beginning developer, just starting out in the professional world, I learned the most from a technique I called commit tracing. I would pick a commit–which is sort of like a unit of work for a developer–that had been published by one of the more experienced developers on my team. And then I would hand-copy their changes, word for word, into a notebook.

In order for this to work, the commit had to have a clear message on it about what it did, for example, 'Add subscribe button to the main page.' And the changes in it had to be everything needed to add that button, and nothing extra–because I wouldn’t always be able to tell myself if code was relevant or not.

As I got more experienced, I found myself thinking about my commits. 'If a beginner developer were to trace this commit, would it help them…or would it confuse them? Am I including the right changes in this? Am I omitting the irrelevant stuff? Am I naming it clearly?'

This exercise gives me a chance to think about how I can help others level up, too. I can teach, I can mentor, of course. But there’s something else I can do, which is to leave artifacts in the world that help others level up without me knowing about it.

I do a similar thing with blog posts. When I started my blog, I didn’t always know what people wanted to read, so I tried different things until I discovered which blog posts people read the most.

One thing I tried was that, if I had run into a particularly thorny technical problem and I couldn’t find documentation on it, and I’d had to ask people or tinker with things or write a custom solution, I would write about that. I would make it so the next person who had to do this wouldn’t face the same obstacle course that I did.

You know, those posts get some of the most reads, because it turns out…that I am very rarely the only person who has to do the thing I struggled to do. Those blog posts help people that I don’t know. And on days when the mood metrics get to me, and I feel like I’m not progressing, I think about those people, and it helps.

The bottom line on leveling up

We’re in a constantly changing field, and we have already learned to adapt to that field all the time–to level up passively. But we can also learn to level up deliberately, to gain the skills we want, and to shape our teams, our workplaces, and our industry. We can do it by developing a specific vision, by strengthening and relying on our discipline, by asking questions and fishing for answers, and by taking care of each other.