This is a story about finding a job as a senior software engineer in Toronto - with a twist: just having moved there from Germany.
I was prepared. I had a plan. But it failed completely - at first. I had to adapt and learn. It was a roller coaster ride.
I tell my story because it might help others learn from my mistakes. This is not meant as a bigger statement about immigration or the state of the tech scene. It's simply about my experience.
Please note: I will not mention the names of companies. This way, I can speak more openly without hurting anyone's reputation - most of all mine. Again, it is not intended to denounce anyone, but to give an insight into how I found my job.
I'm a software engineer, working in software for almost 10 years, having prior startup experience and coming from a Java/Scala background with React, Go and Node experience from side projects.
Although I had quite a good idea of what I wanted, I was open to jobs that didn't fit my criteria perfectly. Since I immensely enjoyed working on a product at my last employer, I wanted to do that again. The tech stack was not that important, but there were certain things I didn't want to touch again (like PHP and Angular.js 1.x). Furthermore, I was looking for companies with 20 to 100 engineers. Coming from a smaller startup, I wanted to experience what a significantly larger one feels like. The type of industry wasn't that important to me, however, shady business models like online gambling were on my blacklist.
At first, I wanted to get a broad overview of the opportunities in Toronto. By searching through job boards, lists of great workplaces or "startups to watch", I compiled an extensive list of startups.
I used Trello to keep track of all of them. I always made a note about a company's tech stack and their industry. Additionally, I put them on a Google My Maps to see where startups are usually located. Since I didn't have an apartment yet either, it was useful to know where I should live if I wanted to be close to work.
I categorized each company into "Hell, no!" (red), "Well... maybe" (yellow) and "Wow" (green) based on their tech, industry and what I could find on Glassdoor.
As a result of my research, I noticed that the companies I found the most interesting were not using Java but Python, Ruby or Node. Out of dozens of startups, I actually found just one that was Java-based. Fortunately, there was still enough time to tip the odds in my favor.
I had played around with Python for a data science project at my last company. I liked it. The momentum seemed to be on Python's side, compared to Ruby which seems to be on the decline. Since I already had quite some experience in Node from toy projects, I bet on Python.
As a consequence, I read two Python books, one to learn the basics and one about more advanced patterns. Furthermore, I practiced with a variety of coding challenge websites - which helped me to apply my new skills, learn various aspects of the language and, by looking at other user's solutions, about idiomatic Python usage.
Around the same time, I also had an idea for a side project. Since it was my impression that having a side project was almost required these days, I got to work and started implementing my idea in Python - two birds with one stone.
The final result is subvoc. It allows people to search for difficult words in movies. The idea being that if English is not your native language but you are quite advanced, you can see which words in the movie you just watched in English are the most difficult and you can learn their meaning.
As part of my research I learned that most jobs are not found online, they can only be accessed through your network. Knowing the right person is the way to go in North America. And while I read this over and over, I thought it wouldn't apply to me. I'm a software engineer after all, I thought, there is a huge demand for me. Virtually every company I was interested in had a job opening that roughly fit my experience. I'm going to be fine, I thought.
Within a few days, I had applied to five companies online. I took a bit of time to craft a cover letter for each of them. They weren't perfect, but quite good. Then I was waiting for all the inquiries to fill up my inbox.
Even one company where I seemed to be an almost 100% fit didn't get back to me.
I was questioning everything. Is my resume not good enough? Is my cover letter bad? Is my skill set not required? Am I lacking experience? Is it because I'm not Canadian? Doubt and uncertainty were getting to me.
I knew that going forward, this approach wouldn't work. Fortunately, I had tested this out first and didn't target my most sought-after companies right away. But what could I do differently now?
Plan B, then
Good thing I started going to every tech meetup in the city I could find the time for. Basically, every night of the first three weeks I met people from the tech scene. This was a crucial step to getting into the scene quickly. At those meetups I could visit company offices, talk to fellow engineers, learn about the state of IT in Toronto and simply expand my network.
But what can work even better is to actually present something at a meetup. I managed to secure a spot in the local Hack&Tell. I presented my side project (and unexpectedly won a Raspberry Pi). When I attended the Python meetup, I took the opportunity to talk about interesting technologies and concepts on stage that I had discovered with my side project. This put me in the spotlight. And people started mentioning to me that they were hiring ...
Then I learned that there are two big online tech Slack communities: TorontoJS and Techmasters. Naturally, I joined them and started reading and contributing a little bit. I then took the initiative and asked around for job opportunities in the #jobs channel. I described what I was looking for and told them to contact me via Slack. A few developers did. One conversation actually led to an interview. Another one informed me about companies to avoid and eventually put me in contact with a recruiter he trusted.
I didn't have any experience with recruiters before. Usually, they write me on LinkedIn and I ignore them. Now I was desperate. I talked to the recruiter that was recommended to me for an hour. He was very insightful. Asked me questions that helped me realize what's important. Shared a few tips on how to improve my resume. He also gave me a rough idea about what salary I could expect. All in all, the conversation was extremely helpful.
Another thing that worked in my favor was that someone from my last workplace knew a few people in Toronto from an annual HR conference. She put me in contact with a person who introduced me to someone at an innovation hub that worked with a lot of startups. We had a short meeting and I came out with a couple of intros to the companies I was interested in. Jackpot! The network at work.
More online applications
But there were a few companies left that I simply couldn't get closer to. I decided to submit an online application again. I completely re-did my resume, applying the tips I got so far, put a lot of effort into polishing my LinkedIn profile, asked for a couple more recommendations from former colleagues and invested more time into the cover letters.
A few things that I changed in my resume:
- make the skill section even easier to spot and scan by putting it in a right-hand column instead of the bottom third
- add a short summary section where you mention how many years of experience you have in the very first line
- make sure each bullet point fits on a single line
- use colors to highlight different sections
The result? I got two responses out of two applications I sent out.
I had also heard of those platforms where you put up your profile and companies start contacting you. I tried Hired. It took about two hours to set everything up. When my profile went online, it was exhilarating. Inquiries were pouring in. Within a day, I had 10 companies interested in me. Unfortunately, most of them didn't fit my criteria: they were large enterprise companies, not located in Toronto or early-stage startups. In the end, I talked to two of the companies. All in all, it was a rewarding experience.
The first hurdle of the interview process is almost always a phone call with someone from HR. There are tons of tips online about this step but here is what I observed.
First of all, do your research! Know what the company does, what industry they are in. Bonus points: Read 1-2 blog posts and casually mention things you picked up. Set up an account with them and explore the product, if possible. I also tried to find the most important qualities the company expects from its job ads (e.g. speed) and then used these to describe myself.
Secondly, everyone usually asks the same questions. The top 5 for me have been:
- Why do you want to work for us?
- Could you tell me something about yourself?
- What was your biggest accomplishment?
- Are you applying elsewhere? / Do you already have an offer?
- What are your salary expectations?
Don't forget, this is an HR professional. They are trying to see if you can form complete sentences, know who you are talking to and are - just very roughly - a fit with what they are looking for. Help them understand, use a few keywords from the job ad, put things in perspective and explain the positive impact you had in layman's terms.
Coding challenges are a very distinct IT phenomenon. In what other profession do you find such an elaborate and commonplace procedure to put applicants to the test? Maybe this should give us all something to ponder. Why is it that someone who worked at various tech companies, has an active GitHub profile and a blog, is asked to go through programming puzzles? I digress.
Here are the coding challenges I had to do:
HackerRank is a platform dedicated to coding challenges. You can practice them in a multitude of programming languages. Their business model is to sell this platform to companies as a way to test applicants.
My challenge involved nine exercises, for example:
- Write a regex to validate an IP4 address
- Determine whether a sequence of brackets is balanced
- Model the design of a vending machine
- Find the largest possible difference in an array
- Merge two sorted arrays
- Multiple choice: Which of these Java statements initializes an array?
The trick is that you only have 90 minutes. But at least you are allowed to use an IDE and your language's documentation. Furthermore, there are tests you can run your solution against and get prompt feedback.
To be honest, I hated that test. I had actually practiced on HackerRank now and then and recognized two of the exercises. But still, in the end I only finished about 80% before the time was up. I knew that the test was designed to make me fail but this didn't help me feel better.
This test was very similar to the one before but on a different platform and much more relaxed. There was no countdown. This made a huge difference in how I could approach the exercises.
The challenges were:
- Duplicate an array
- Fix the code to only print out even numbers
- Fix the code to calculate the square of two numbers
- Refactor some code to make it more functional
- Explain what
["123", "456", "789a", ...].map(parseInt)returns
- What ECMAScript proposal are you most excited about?
- Given a set of requirements, what tech stack would you choose?
I enjoyed this challenge much more than the previous one. The questions didn't test whether I could find an algorithm to completely artificial problems but rather explored various aspects of programming: understanding and fixing existing code, refactoring, and higher-level thinking and opinions.
parseInt has some very weird behavior. But fortunately, you can just go and read the documentation since there is no countdown.
Another company asked me to create a web application based on a short specification. I liked that I was able to pick any language and framework I wanted to. Furthermore, the project was related to the company's business and was described very well.
While they said I shouldn't spend more than a "couple of hours" on it, it took me pretty much one and a half days to finish. This was mostly due to the fact that I picked a tech stack I'm not as well-versed in as I am in Java (but building frontends in Java is a pain). Another reason was that I hadn't used PostgreSQL in a while (was required to be used).
Anyway, when I finished and packaged it up, I was very close to submitting it. But then I realized I hadn't tried to run the bundle I created. I tried it and the app didn't start. I forgot to add one of the directories. I fixed it, tried again and it worked. Good thing I hadn't sent the broken one!
All in all, I thought this was a fun and worthwhile challenge, albeit a bit too time-consuming.
From another company, I received a comparatively tiny but still very difficult challenge. From a list of events, I was supposed to find and return a list of all event pairs that overlap. On top of that, I was asked to write it in the programming language they chose. I only had a bit of experience with that language. Since it's a functional programming language, I made sure to write the algorithm as idiomatic as possible.
Coming up with the algorithm took me about an hour - but implementing it as concise, functional and efficient as I could took me roughly three hours. I used tests to cover all the edge cases and to make sure that I was submitting a working solution.
This was a very cool challenge. I got to solve a tricky problem and play around with a new programming language.
Last but not least, I was asked to prepare a tiny ToDo application (which took me about an hour). Then, during a call with an engineer, I was required to add a few additional features.
In the end, I was asked about the space and time complexity of the last, most challenging algorithm. All in all, quite straightforward. I found it very important to have a dialogue with the interviewer. Especially, asking him to clarify constraints and requirements made a huge difference. Just starting to code is usually a bad move.
Ignoring the Challenge
I got a challenge from a company and due to my prioritization and commitments, I wasn't able to work on it before the deadline. I wrote them and explained the situation, telling them that I cannot interview with them any longer since I'm too busy with other companies.
To my surprise, they offered to fly me in to their New York headquarters straight away to meet the team. I was baffled. Ultimately, I didn't think the company was a good fit, though and I had to move on.
Before my first interview, I wasn't really nervous. I saw it as a trial run.
At first, I was asked by the CTO to speak about my previous work experience and I got to explain my biggest accomplishment in-depth at the whiteboard. They were quite impressed.
Then, there was a coding challenge. I was asked to prepare my development environment beforehand. The exercise was to implement the Game of Life, pairing with the VP of Engineering. This was interesting because it wasn't purely about my coding skills but also about my communication skills.
At first, things went quite badly. I wasn't as confident in Python as I thought I would be. I made a bunch of amateur mistakes in the first five minutes. But thanks to my test-driven approach, I was gradually gaining confidence. In the end, I finished on time with a working solution. Success! The CTO and VP of Engineering both commented on the solution being very succinct.
Apparently, everyone was fairly impressed because suddenly the CEO was coming in and interviewing me. We spoke for over an hour. I asked about the main challenges and the future direction of the company. He asked what my expectations for the role and salary were. After a long afternoon, I left the interview room in a very good mood and expected an offer very soon.
After two days, I got an email. They declined. I was quite surprised, wondering what I had done wrong. The person that got me the interview later found out that they were indeed impressed but didn't think they had a suitable role for me at the company at the moment.
My second interview was with a company that seemed like a natural fit for me technology-wise: They use Java for everything. On the one hand, I was confident because of my vast Java experience - but on the other hand, I didn't yet know the reason why my first interview didn't get me an offer and feared I was doing something fundamentally wrong.
I met with three people who would each throw various tests at me.
The first one was basically a Java quiz: What can be marked as
final? What types of visibility exist? What is the default behavior of
==? What is the relation between
equals? I knew most of it but it was getting harder with every question. When I was asked how the Java
HashMap implementation works, I drew a blank. I've used it hundreds of thousands of times throughout my career but the last time I thought about how hash maps work internally was at university. Needless to say, it didn't go so well. One part of me was angry at myself for not knowing that, and the other part was angry at the interviewer for asking such a low-level question.
The second interviewer drew their app's dashboard on the whiteboard and asked me to design a REST API for it. I developed a solution fairly quickly and discussed the trade-offs of being RESTful and optimizing for performance. I even touched on GraphQL.
The third interview was about design. I was tasked with designing the objects of a multi-player chess game. I found it very contrived. The interviewer also didn't seem very confident. It was an odd experience.
I got a call the next morning. They made me an offer. I told them, I'm still talking to other companies and they were okay with that but wanted an answer soon.
The process for my next interview was very organized.
When I arrived, I was given a quick tour of the office. Unfortunately, my impression was very negative. They had a common area (loud!) right beside the desks (supposed to be quiet!). The office was almost completely devoid of natural light - it felt like a bunker. Afterwards, I was placed in a meeting room where I had four interviews, each one hour long.
The first one built upon a homework I was given. My task was to adapt my solution to new requirements. This was fun, sort of. There were two interviewers and we all huddled around my 13" laptop. As I worked through the exercise, I felt a bit overwhelmed by the various edge cases and the expectant interviewers. I wasn't able to get it done in time. The biggest issue was that even after the interviewers left, my brain was still busy solving the last task. It took me quite a while to let go and re-focus.
The next interview was about data modeling and system design. At first, I was tasked with modeling a 'receipt'. But my head was still busy with the last exercise. To make matters worse, I was also confused about the whole concept: In Germany, you usually deal with invoices, not receipts. The interviewers didn't seem capable of guiding me through this problem. Anyway, I stumbled through the exercise and was pretty disappointed how things went so far.
But then it turned around. We had a bit of time left and I was given a system design question: designing an OCR for receipts. Now, before I went into the interview, I read something on Glassdoor and found a hint on this question. The day before the interview I worked through the problem twice. It blew them away. I was able to come up with a very good solution extremely quickly. I could tell they were impressed. I'll let you decide whether this was unethical.
Then, I talked to two development managers about the way they worked and two 'regular' people about their culture in my last interview. Nothing too spectacular.
The next morning, I got an offer. They told me, my offer was the highest salary obtainable for my respective role. And indeed, it exceeded my general salary expectations for Toronto by 15%. This gave me a huge confidence boost.
#4 & #5
These interviews were very different from the others.
In the first one, I talked to a development manager for about two hours. Since I had solved an online coding challenge beforehand, we focused on high-level questions. Interestingly, we talked a lot about how to pick tools and technologies. For example, how to decide between Angular and React.
I was invited for a second interview to meet the VP of Engineering. The interview quickly uncovered that they had a different role in mind for me than I did. In the end, they told me that they would get back to me - but I sent an email the next morning telling them I don't think it a good fit and that was that.
I can not talk about this one since I had to sign an NDA. Bummer.
Fast forward to the next day, I got an offer.
After all was said and done, I had three offers. They were very different. For example, the difference between the highest and lowest salary was 23%! And that's not counting additional benefits like catered lunch, health benefits etc.
I scheduled a phone call with a manager from each of the companies and talked to them for an hour each. We discussed details like on-call requirements, the team I would join, things I would work on and so on. I also consulted a friend (fellow software engineer) to get a second opinion.
After extensive considerations, I made my choice. I picked the company where I felt I could grow further as a software engineer, that seemed to have a great work-life balance, excellent compensation and worked on stuff that mattered.
It's like a sales pipeline: I applied to 14 companies, talked to 8, interviewed at 5 and got an offer from 3. You see how the numbers get smaller? If your pipeline dries out, the odds of getting an offer decline dramatically.
Talk to everyone: Even though I was hesitant to talk to a recruiter at first, it helped me immensely. He didn't find me a job per se but gave me some insights about the local tech scene and HR best practices, I needed as a newcomer.
High-level matters: Maybe it's because I applied for more senior positions only but in general, there were hardly any low-level questions during the on-site interviews. Interviewers were interested in how I design systems, object relations, and APIs. Sure, I had to actually code, too - but nobody cared to quiz me about what ACID is or had me code on a whiteboard.
Side projects are not that helpful: So at least for a senior developer, having a side project didn't seem to make much of a difference. Nobody asked anything about it. I tried to bring it up in my cover letter or during phone screenings for full-stack positions but I don't know if it had any effect. Even the Python-heavy companies didn't seem to care - which surprised me. Then again, one company wouldn't even interview me because I didn't have enough experience with their Python stack. So in the end, it didn't really seem to help that much.
Have your personal elevator pitch ready: The only 'question' I was consistently asked in every interview by every person I met was: "Tell me about yourself." You need a good answer here. It allows you to shape the narrative, to paint a picture of yourself. Make it short and compelling. Make it count.
Pick one stack and go with it: During the interviews - with the better companies at least - I was allowed to choose the stack I was comfortable with to solve a problem. This made a huge difference and helped me 'cheat' a bit by picking a typed language (Typescript) so I didn't have to rely on my stressed out brain to provide me with all the function names on the spot.
Be able to talk about a project in depth: When the inevitable question "What are you most proud of?" comes up, it's your turn to impress. You should be able to provide sufficient context for the listener to understand why it was indeed that impressive. Furthermore, if you are asked by an engineer, you can show off your technical expertise. Go into detail as much as you can. Make it painfully obvious that you know what you are talking about.
Leverage the opportunity to prepare: In half of the interviews, I was instructed to prepare a development environment ahead of time. This is your chance to set yourself up for success. I pre-installed a bunch of helper libraries for the most common use cases like templating, making HTTP requests, and serving REST APIs. Another great idea is to have a test runner ready, running on every file save for continuous feedback.
Know complexity and scalability: Every time I had to code something, I was asked about the time and space complexity as well as whether I can simply make it more efficient. Now and then, I was also asked what would happen if the input became gigantic so it wouldn't work on a single machine anymore. It's crucial to have answers here.
Simplify your resume: First of all, my resume for the first batch of online applications was not good. It was too long and not 'easily scannable'. Since people in HR receive so many applications, they allegedly only look at a resume for 10-30 seconds. During most interviews, I could tell that the interviewer hadn't read my resume for more than one minute. People are busy. The lesson here is to make it suuuuper easy to learn the most important facts about you. Basically, apply the lessons from Don't Make Me Think. If they judge you by keywords, put a lot of keywords in. This cannot be overstated.