Changing jobs are not easy, let alone switching to another industry.
Nowadays getting job offers from top software companies take considerable effort and quite bit of luck. Coming from embedded software test area, I was fortunate to get multiple offers as software development engineer. I want to share the journey with those of you who also want to pursue a career in the blooming software industry.
My seeding motivation was the lack of job satisfaction in my previous job as a software test engineer. Most of my job involved creating complex environments to conduct tests for telecommunications handsets. I would not say that was easy work because making sure the test condition is met take lots of effort. But for me what was always missing was the magic word: Design.
Without opportunity to participate in the design process, I always felt that I was testing a black box. If anything goes wrong, one has no clue about the cause of the problem nor the potential solution. As a person who is always curious about how things work, a deprivation grew worse over the years.
On the other hand, as a software engineer you would have opportunity to design a product from bottom up. You would be able to come up with features that dramatically improve the performance of a service. Having taken data structures and algorithms courses in school, it occurred to me that I might have a chance to work as a software engineer as well.
Preparation and Dedication
The job market of software industry is highly competitive. As an experienced professional, I was not only competing with tens of thousands of new grads but also with senior software engineers who had been working in the industry for years. I figured that I need to work on the following in order to succeed:
- A great resume with software dev projects in popular technologies
- Solid data structure and algorithms knowledge
- Distributed systems design knowledge and best practice
Data Structure and Algorithms
I started working on data structures and algorithms from around a year ago. I picked Python as my main programming language for the following reasons.
- Python is one of the most popular languages in the world, so almost surely your interviewers also know the language well.
- The collections standard library provides full support for various data structures required to solve algorithm problems, and they are handy to use.
- Python programs are significantly shorter than other languages such as Java, therefore more suitable for limited space on whiteboards.
As a first step, I went over all of the basic algorithms and came up with a set of templates in order to code fast in an interview environment. Another benefit for having templates is that for complicated algorithms such as topological sort, one tends to miss some small steps when writing on a whiteboard. For example, you can have a template of breadth-first search algorithm that searches shortest distance from source to target for just around 15-line in Python.
With these templates and around one hundred hours of practices, I was able to solve around 200 medium-level questions on Leetcode.
But I still had some difficulties solving hard-level problems. Putting them together, the following types of problems were most challenging for me.
- Dynamic programming: sometimes the subproblems are quite difficult to think of.
- Sliding window algorithm: how to choose and maintain the invariance in the window.
- Data Structure Design problems: satisfying all the tight time-complexity for each function is tricky.
- Key construction for some problems required hash table data structure.
After hours practice, you might still fail to come up with solution for some hard problems. Nevertheless, I suggest you focus on medium level questions and especially the graph algorithms, including algorithms for binary trees. A special type of tree called Trie appears more and more frequently in coding interviews. The prime reason is Trie are very useful in production environment. Here is a interesting one liner creation of a Trie tree in Python:
Trie = lambda: defaultdict(Trie)
I had no idea what system design meant and failed a few onsite interviews because of it. A typical system design question asks you to elaborate the main component and design process for a web service such as Facebook newsfeed.
Then I found a book called Designing Data-Intensive Applications. This book is fantastic.
From basic key-value store to data storage in databases; from data representations to ACID properties; from offline systems such as Map-Reduce to hybrid systems such as message queues, this is the book you need to understand how modern distributed systems are designed and implemented.
Nevertheless, software engineering is a practical business. To learn how graph databases work, I implemented an autocomplete system using Neo4j database. I chose MongoDB for document storage when I was working on a log-processing framework, therefore got familiar with one of the most popular noSQL databases.
The Kleppmann book plus doing projects is the key to succeeding system design interviews.
Failure is the mother of success.
I failed onsite interviews 4 times before getting my first offer.
Sometimes you solved all problems brilliantly but failed the interview; while sometimes you struggled in one or two rounds but succeed in the end. There is an uncontrollable factor called luck that might be pivotal.
It is frustrated to be rejected after an onsite interview, but don’t lose confidence and keep applying to other companies.
Some tips for succeeding onsite interviews:
- Practice whiteboard writing and communication skills.
- Unblock yourself by drawing examples and ask for hints.
- Come up with a workable solution and improve on it.
- Do not get distracted if you did not do well in one round of onsite interview, keep it up for the other rounds.
Bonus: My first month as software development engineer
I decided to join an Internet company because of its startup environment and product impact.
The first day was all excitement. I learnt what the team is doing and started setting up environment on a shiny MacBook Pro.
The struggle for the first week was using source-control. Having used GitHub web UI for more than one year, I didn’t know much about using git on command lines. The key to understand git protocol is considering each commit as a node on a tree graph. Then you can understand concepts such as branches.
Git is the primary development tool to learn for developers.
Tips for surviving the first month are getting a good “entrance” point and a good IDE for the language of your codebase. A good entrance point is the very first source file you start from exploring a vast codebase. Having a good IDE makes your lookups of the data types much faster. Notably, not any single IDE works for all languages. So choose the best one, such as PyCharm for Python.
The most striking finding for me is how few lines of code you need to write when you implement some feature. You are likely to spend 80% of your developer time reading other people’s code. This is absolutely important. You want to make sure that your changes or additions do not break other people’s code. Equally important is documentation. A good documentation provides assurance for long-term maintainability and enhances team collaboration of a repository.
When I started this journey, I should have read more articles to avoid many detours I took. And I hope this article helps you find more efficient methods to tackle the challenging software engineering interviews. And I wish you would be as excited as I was when getting the first offer. Because at that moment you knew all those sleepless nights were worth it.