The goal of this series is to share my journey on how I went from a bootcamp student to senior software engineer. Finding a new job after graduation was one of the toughest and most rewarding experiences I've ever had. I'm hoping that those who read this series could learn from the things I did right and from my many mistakes.
In the previous blog post, I had mentioned the importance of learning and why it's a core fundamental requirement to becoming a software engineer. In order to fuel your motivation to learn, you have to be ambitious and you have to constantly challenge yourself. If done properly, you're going to excel quickly and succeed in the industry. If done improperly, you'll feel defeated and burn out. The goal of this section is to learn about the time I crashed and burned, and the times I actually did it right.
I've had a lot of ambitions of wanting to try or learn something new, but the way I went about it often left me defeated. I've always told myself that I wanted to good at Go, Rust, Server Side Rendering, Blogging, and etc.,. Usually these fantasies fell short of being an accomplishment because I wasn't prepared, focused, or shifted to the hottest new tech that someone else was learning. My goals and the time that I had allocated to achieving them were not reasonable. There were times I tried to bunch all of these goals together (this is a bad idea).
Find a friend who has similar ambitions as you and challenge each other. Have the other person give you exercises or obstacles, review your PRs, or evaluate your ideas. Treat this person like a gym buddy, someone to spot you when you need an extra push or to give you motivation when you feel like slacking off.
I've had a lot of fun taking on challenges with someone else. Usually, you can make a game out of it by using small wagers like coffee. It deters you from cheating because if you cheat, you are the one losing out and the most you gain is a cup of coffee.
Here are some of my favorite challenges:
I received the challenge to contribute to open source from a close friend, who is CEO/CTO of a start up. Back when I was unemployed and I was struggling through interviews, my friend had advised me to contribute to open source projects. He noted it was a great way to work with other people, get feedback on how to improve your code/habits, and it gives you challenging tasks/projects that are not self-defined.
I spent a few weeks trying to find a project to work on, one that would be simple enough for a newbie to the open source community. I eventually landed on Professor-Redwood: Pokemon Go Discord Bot. I was a pretty avid Pokemon Go player at the time, and was really interested in working with bots. I reached out to the maintainers and they were happy to have me help out. It took a while to get started and I was really nervous about submitting my initial PRs, but after a few weeks I was making changes like clockwork.
I eventually began taking a lot of ownership over the project, and I was made one of the admins. I helped with some small infrastructure issues, migrated the bot to Google Cloud Platform, and reviewed a bunch of PRs by new developers that had joined in. Although I'm no longer an active maintainer, I always look back at this project as my foundation (I actually got another job at an early stage startup from this project).
This was probably the most challenging exercise that I had to overcome. Not only did I come from a breed of developers who learned from GUI based editors, I had also just bought a split keyboard, the ErgoDox EZ: An Incredible Mechanical Ergonomic Keyboard, which I would be using for the entirety of the week. The wager would be one week of coffee from the elusive starbucks reserve.
The reason why I had wanted to use vim was because I had read that a lot of engineers get a huge productivity boost from it. Also, whenever you are SSH'ing into a box, you can't just prop up sublime text or VS Code, you’re forced into vim or an equivalent anyway. A lot of GUI based editors got their inspirations for hot keys from editors like vim or emacs.
Coding with vim on a split, ergonomic keyboard had a huge learning curve. It instantly dropped my productivity for the projects I had been working on dramatically for the first two days. Like, 3 WPM productivity. However, once I felt familiar and comfortable, I felt like a rock star by the end of the week.
I am currently 1/3 of the way through this exercise. The idea came up when I had lost a bet back at GopherCon 2018, and I was told 90 consecutive days of Go with at least one relevant and meaningful commit, per day. With this challenge, it was extremely difficult because I tried my best to avoid using a computer during the weekends or vacations to clear my mind. I had tried to do this challenge five times, before giving up due to lack of ideas on projects.
The Go Programming Language had been a language that I had wanted to learn, even during the days I was at a bootcamp. It touts great performance by using a safe concurrency model, readability from an opinionated linter, and type safety. Additionally, it was a functional language as opposed to an Object Oriented Programming Language. Fundamentally, a lot of these concepts were different from Node.js. That was a lot of the draw for me, I wanted to expand my skill set with a different way on approaching problems.
With this challenge I set some core projects, all of which are small, manageable and extendable after they are completed. The toughest part of the challenge is a commit for 90 consecutive days, however this taught me to use my 90 days wisely. If I had been working on one project for a bit too long or if I was stuck, I'd shift priorities about learning a foreign Go concept for a day. As long as it had contributed to my goal, I'd do it.
- lambda functions to replace services (for work)
- database utility tool (for work)
- Go HTTP server
- Form Scraper (for work)
- Rebuild a previous Node.js project, the Go way
- Exercise and practice a Go fundamental concept (slices, channels, go routines)
- Learning about profiling
- Learning about debugging
- Best Practices with Testing in Go
Having a task list of projects also helped. For each new project that I had started on, I listed out core fundamental features that satisfied the requirement. When I had a new idea for a feature, I would add it to a list for version 2, so I would not fall astray from completing my initial goals.
Pro-tip: Lambda functions are great for one off projects. If you've never heard for AWS Lambda, Google Cloud Functions, or serverless based technology, it's essentially meant to be a function that gets executed on invocation, but it does not stay online and idle waiting for your next call as opposed to a server. A container is spun up, your code is executed, and the container is destroyed. Serverless functions should be kept small, and should be used to accomplish one thing simply, reducing the run time and memory usage.
With this approach, I'm learning the language through practical use cases, and the repetition of doing it daily has made me familiar with the syntax and nuances that I've come across. Having myself do a commit everyday has kept me focused on the underlying goal, while giving me some leeway on working on other things.
I developed a small framework for creating new challenges.
Here's some examples of those that fit the framework:
- Answer 1 question a week on Stack Overflow
- 90 consecutive days of functional programming (1 commit a day)
- Obtain an AWS Solutions Architect in 3 months time
Here's how the challenges in the example fit the framework. They are simple; I'm not mastering anything, but instead each of them have the verb of doing something. They offer a level of complexity, things that I'm not used to doing such as answering questions on Stack Overflow, or programming in Go. The goals are measurable by the number of things that I am achieving in a given timeframe. Finally, the goals are realistic enough to fit my current schedule. I know that these are things that I can commit to.
My framework isn't always perfect for everyone and everything. I try to use this as a general guideline on how to approach something rather than approaching things in absolutes. Figuring out how to challenge and motivate yourself is a challenge in itself.
Challenging yourself... sounds cliche right? It is, but there is a reason why I am talking about it. This is not a self help, motivation, or better yourself series. However, you should know that no one is going to push you or get you to the next level other than yourself. It does not matter whether you went to the top/highest rated bootcamp with a post-grad hire rate of 98%+ or received a Computer Science degree from a great university, you need drive to move to the next level.
If you don't enjoy being challenged then software engineering is not for you. This is the fight or flight scenario: You're going to be put in many situations where you're going to have to learn a new programming language, use an unfamiliar tool, switch to a different vendor (AWS to Google), work on a code base where styles/guidelines are different than what you're used to, or run into a complex product requirement due Monday. The best way to prepare yourself for those types of challenges is to training your “doing” muscles.
Challenging yourself trains and prepares you for challenges in the future. There will be a time in your new job or new career, where you will have to get yourself ready to learn the next thing. Do your best to manage expectations and develop a plan to set yourself up for success.
For my next post, I will actually go into some tips of highly effective new developers. Stay tuned.