Several times a week I get emails or LinkedIn messages from recent or soon-to-be code school graduates, asking to buy me coffee or jump on a phone call to share career advice. I've been in a similar spot to where they are, trying to excel in the industry and looking for mentors. In fact, I kind of feel like I've been an apprentice for the last 11 years, and I don't foresee that self-identification ending anytime soon. So I'd really love to be able to help, and besides, one of our explicit company principles is about teaching "anyone with a willingness to learn."
But while I want to help personally, with limited time and my other work and family responsibilities, it's not scalable for me to meet with everybody. So typically I refer these folks to my fantastic colleagues who run our recruiting and hiring efforts, via our contact form's "Careers/Apprenticeship" option. But I still feel bad about needing to say "no" to people's requests for help, so I want to share something with them.
In this article, I'd like to share some tips for early-career developers, including code school grads. They're based on my own experiences, which means there's survivorship bias here, so I'd encourage you to take what works for you, and leave what doesn't.
Learning & Improving
OK, so you've invested a bunch of time, and probably money, into your progress in the software industry. Hopefully your teachers, mentors, or code school have been honest with you about software as a career requiring continuous learning and improvement. The most important advice I can share with you, as you're starting out, is that a career is a long road, with many twists and turns along the way. The best way I know of to excel in software is to keep a growth mindset. The more you can learn and improve, the more career options you'll have.
I like to think about my own improvement broken down along two lines: input and output. I've tended to go through phases in my career where I've done more input than output, and (less often) vice versa, but I've found both to be essential for improvement.
There are innumerable ways to gain knowledge: articles, books, papers, MOOCs, conversations, experimentation, project documentation, access to experts who are willing to answer questions, and many more. Quality and efficiency vary across these and other mechanisms, and many of us learn in different ways. Personally, I've gotten a ton of value out of reading books and applying what I've learned.
Reading blog posts like this one is a baby step: hopefully it'll help a bit, but it's the tip of the iceberg. I'd really recommend concentrating your reading more on classic books that'll help you throughout your career. Book authors have spent many months, maybe years, distilling their years of experience into a well-crafted format that you can inhale over a few weekends.
Being willing to read is a superpower in our industry. It really is.
I'll mostly stick to broad areas here rather than specific book recommendations, but you can check out my Goodreads profile for more specifics if you're curious.
Learn about software career development. For broad career development issues, I'll make an exception in this post and highly recommend Apprenticeship Patterns, The Pragmatic Programmer, and The Passionate Programmer. Bluntly, if you were to stop reading this post right now and go read those three books instead, I'd think you made a wise decision.
Learn about code. Again, I prefer books to blog posts, for the reasons above—not just because I wrote a very niche book about Clojure macros [and you should absolutely ignore that book for now, unless you're already into Clojure]. Learn about the specific languages and frameworks that you're concentrating on. Learn about software design & architecture principles and patterns. Learn about test-driven development and refactoring. Learn about the platform you're deploying to. Learn about foundational computer science concepts.
Learn about communication. There's a lot of material out there, both in the software space and outside. The way you communicate is a crucial part of the way others perceive you, whether it's in conversations, in emails, or in documentation. We're all working with other people, whether they're teammates, managers, end users, or in some other role. If you are a nice person who communicates like a jerk, people are going to think you're a jerk—you'll need to know how to fix that. Learn about logical fallacies, cognitive biases, and nonviolent communication. Look for materials on communicating in effective writing, presentations, and difficult conversations.
Read open-source code. My experience is that reading OSS code is most effective when you've got a specific purpose in mind. But it can also be instructional to clone a repository from GitHub, run the tests, try and reproduce issues in the issue tracker, etc. At worst, you get an idea of how someone else codes and what's easy or hard for you to understand. And at best, you'll find yourself leaning over into the output side of things, which we'll discuss next.
Write code. This isn't necessarily the most important skill you'll need in your software career, but it's certainly the one that's most unique to the role of a software developer. There are lots of ways to practice writing code, but my personal favorite is doing code katas.
Code katas have a couple of main schools of thought, and I like both of them for different reasons:
- Repetition. By solving the same problem many times with the same or similar solutions, you get to understand the problem really well. This gives you a sense of mastery, which I've found to be great for my emotional well-being when I'm mostly frustrated by programming problems. You can treat these as either a meditation, where you're thinking deeply, or as a race, where you're honing your skills with the tools. Some folks even treat repetition katas as a performance, with or without musical or spoken accompaniment.
- New problems/solutions. The idea here is that most of the coding part of the job is about thinking about and solving new problems, ones that might be related to ones you've seen before but aren't identical. With new problem katas, you're intentionally putting yourself in the uncomfortable position of not-knowing, where we each need to learn to be OK as we're moving toward solutions. You can find lots of examples of bite-sized katas—many have ridiculous names, but they can still be great exercises to work through.
Katas are typically fairly constrained problems compared with "the real world"—more on the order of a single sitting, though some can get quite tricky and take much longer.
Breakable toys are much more realistic and larger-scope projects than katas, but they still aren't mission-critical. So it's OK if they get broken as you're learning. Having a breakable toy lets you see how different ideas work in the long term, which is super-helpful in the work world.
Open source software can be pretty intimidating to get into, but there are a few reasons I still think it's a good idea to look at. First, you can get practice learning a new codebase. This will come in handy again and again throughout your career. Second, for many (not all) open-source projects, the level of code quality is pretty high. You'll get a chance to see how experienced folks approach problems and solve them, by browsing issue and pull request history.
The intimidation factor is real, though. Make sure to pick friendly projects! You can get a rough idea of project friendliness by browsing the mailing list, group chat, or project issues. Or by asking some trusted mentors.
Aside from picking projects based on friendliness, you'll probably find it helpful to start by learning to use the project really well if you don't already. This will force you to go through the existing documentation, and you'll probably find some low-hanging fruit: typos, grammar issues, hard-to-understand explanations, etc. You may even find that there's no documentation at all. If you have a hard time ramping up on an open-source project after reading the documentation, that's a bug that you can offer your help on! Many projects also tag issues as "beginner" or "newbie" friendly—this doesn't necessarily mean new programmers, it could just mean new contributors to this project. I've also heard good things about OSS issue aggregators like OpenHatch and Up for Grabs for finding projects that fit the bill here.
One caution here is to balance your need for progress against maintainers' own time management. Contributions work best when you clearly state the problem you're trying to solve, offer your proposed solution, and be prepared for your solution to be rejected. So if you're time-conscious, you'll probably want to shoot for early feedback on your ideas for improvement. And try not to feel too hurt if the maintainers don't respond for awhile—they've got a lot of stuff going on too.
Practice empathy and communication in your daily interactions. When little misunderstandings occur, ask yourself how they happened and what you can do in the future to prevent them. And how can you get past the misunderstanding with everyone feeling better afterward than before. When you're talking, ask yourself what your audience needs from you—do they need all the details, or do they mostly care about the highest-level bits? These skills are among the most crucial for any job that requires collaboration, and software development is all about collaboration: with other developers, with managers, with other colleagues, with end users, etc. Communication is a huge area, one where I still feel pretty weak—I'm actually in the process of looking for some explicit coaching in this area. Point being: the journey continues!
Blog or journal. During my apprenticeship at 8th Light, I wrote a blog post every day, and it was a huge help in my development. It forced me to reflect on what I'd learned that day, which helped on those frustrating days where nothing seemed to go right. Putting my daily struggles and learning needs into words required me to understand them much better than if I hadn't written them down. And that made it much easier for me to get past those struggles. This kind of journaling doesn't have to be public, but making it public is useful for some folks in getting feedback, and it also gives you something to share with potential employers if you want.
Managing your time
So input & output can both be hugely beneficial, but how do we decide what to work on? I know a lot of folks, myself included, want to get great at every aspect of software, but it's just not realistic.
Even if we had unlimited time this would be impossible, but other responsibilities like children and second jobs compound the issue: we have to learn to manage our time really efficiently. Every time we do sit down to learn something, we have to make a decision whether to widen our breadth of knowledge, or to dig deeper into something we're already familiar with. Then we have to decide which thing within those two broad categories we're going to tackle. And so on.
So you'll want to decide what your goals are at a high level, and find ways to move in that direction incrementally. One idea is to take a tip from agile project management: take your big hairy audacious goal (product), figure out the first step or two towards it (releases), break the first one down to the first few medium-sized goals toward it (epics), and break those down into goals that you can knock out in a single sitting (stories). In this way, you can fit learning into the space that's available, rather than having to rely on luxuries like wide-open nights and weekends.
Tracking that incremental motion toward your big goals can be super-motivating when you look back at what you've accomplished. And of course, reflecting on what you've done also gives you a chance to identify roadblocks, understand them, and figure out how to remove them. You'll probably find your goals changing as your job needs and interests change, so it's healthy to revisit those from time to time as well. Just be wary of shifting goals too often—progress takes time, even when you're laser-focused.
We all need feedback. Without feedback on how we're progressing, it's easy to divorce our own self-assessment from reality, and to think that we're doing much worse or better than we really are. There's also a massive amount of information out there, and mentors can help point us to the best resources for where we are.
Of course, I'm biased toward formal mentorship like what we offer in 8th Light's apprenticeship program, where your primary job is learning. But I won't lie, this is a huge investment for our company that requires a tremendous amount of buy-in at every level—not every company can make this work. In Chicago, we're also working on a program to provide companies with continuing education for software developers that you could ask your boss about if you're interested.
Whether "apprentice" is part of your job description or not, try to find at least one person who can help guide you in your progress. My first real mentor didn't have a formal mentoring role, but he was the developer in the next cube, he was a few years ahead of me in experience, and he understood how to communicate the basics. Between his direct feedback and the books he told me to read, pretty quickly I was ramped up enough on the CSS box model that I could slice & dice Photoshop docs into reasonably standards-compliant XHTML websites (and this was before flexbox!). So informal mentorship can work great, and it's much easier to find, because it happens naturally with friendly coworkers and acquaintances (and even with some unfriendly ones).
You can find mentors outside the workplace, too. A few ideas:
- CodeNewbie is a Twitter chat, podcast, blog, and community with tons of great ideas about breaking into and excelling in this industry, with participants at all levels.
- Social media: Despite its [my] faults, I've found Twitter to be particularly well-populated with software experts sharing tips, links, and stories. And some people are willing to answer questions directly—others have too many folks jostling for their attention, so don't feel too bad if they can't make time for you directly.
- User groups: If you're in an area that has them and you can make the timing work, user groups can be a great place to meet other folks who are excited about software. Check out Meetup for topics you might be interested in. Introduce yourself and make connections—if you're like me this will be hard, but you might just meet your next employer here.
- Open source software: The people reviewing your pull requests are already giving you direct feedback! Maybe not career-level stuff, but they might be up for that too as you contribute more.
- Our Chicago location is starting a trial "external mentorship" program to provide guidance, code review, and networking for early-career folks looking for Junior Developer roles. It'll be free, just a way for us to help more folks. Let us know if you'd like to get involved.
Stepping back a bit, if you're looking for a mentor, I recommend starting with informal relationships and getting help with specific questions, rather than asking folks a broader "will you mentor me?" It's much easier for folks to commit to carving out bounded time to help you—the broader mentoring question, even when people understand it (they won't always!), is abstract enough that the commitment seems almost infinite. Besides, the name of the relationship isn't all that important—what you really want here is to get external feedback and make progress toward your goals.
Software is a really interesting industry. There's always so much more we can learn from each other, and so much more we can teach each other. I look forward to hearing about your successes!
And perhaps most importantly, don't forget to pay it forward, and help out those who are coming up behind you!