[ 2021-January-18 13:43 ]
I've been working professionally as a software engineer since 2006, which means I've been doing this long enough that people now ask me for advice. I've only changed jobs 3 times in my career, so I'm not sure I'm an expert. However, I decided I should write down my advice, to clarify my thinking and to efficiently share it with others. This turned out much longer than I expected, so I guess I have lots of opinions!
Know what you want
My job search often starts with a nagging feeling that something isn't quite right. My first task is to figure out more precisely what I want. You might already know, but making time to think about it helps me understand what I'm looking for. You need some criteria to decide which opportunities to pursue, and which are not for you. You need to be honest with yourself. It is totally fine if your list of desired job attributes includes things like "any job", "more money", "working fewer hours," or "a prestigious employer." The most important part is to end up with something that will make you happy, not something that impresses your friends or family.
I've never explicitly written a list down, but every time I've been looking for a job, I've had some goals. At the very beginning of my career, it was "any software job in New York." At another point, I wanted to work at a small company that was growing rapidly. It has taken time to figure out what motivates me at work, and my answers continue to change. One thing I have found useful is to cast a wide net at the beginning of the process, and talk to many friends and acquaintances about what they are working on. Having these conversations helps me understand what things I find exciting, and what things I don't.
Get help from your friends
After you have some ideas about what you are looking for, you should reach out to anyone who might be able to refer you to any company. You never know what companies your acquaintances might have connections to, unless you ask. It helps everyone to get referred to jobs. It helps the job seeker because they are more likely to get an initial interview. It helps the referrer because their peers will be inclined to return the favour in the future. It helps the company because it makes the recruiting process more efficient. Prioritize people who can give you strong referrals. The ideal is someone who has worked closely with you, and will speak highly of you.
Get at least 2-3 offers, so apply to approximately 10 places
You need more than one offer to negotiate effectively. It also makes me feel more confident about my decision to know I had other choices, and I picked the best available option. Like any other sales process, you should work backwards from your goal to figure out how many places you need to apply to. Someone I know who shared their process with me had an impressive 66% success rate at every step. This means to get 2 offers, they needed 3 interviews, and needed to apply to 5 companies. Everyone's success rate is going to differ, but this math means you need to apply to a lot of places. I think most people should expect to apply to approximately 10 places to make the numbers work, although this will vary wildly depending on the stage of your career.
Improve your resume
The point of a resume is to get the interview. The more experienced you are, the less your resume matters, since experienced candidates have less trouble getting interviews. However, it is still worth spending a few hours making your resume good, since everyone will ask for one. My resume advice:
- Get someone who works at a different company to proofread it. This helps ensure you do not include company-specific details. You must avoid typos or grammar errors.
- Ensure you can talk about anything in more detail. People will ask you about random bullet points from your resume. Don't include things you don't want to discuss.
- Describe your specific work, and the impact of why it mattered. For example, don't just say "lowered page loading time," but include "unblocking a new video previews feature".
- Include specific numbers, where possible. This makes it seem more real, and communicates the scale of impact. For example, instead of "lowered page loading time", say "reduced median page load time from 1s to 100ms".
This is basically the same way you need to describe your accomplishments to get promoted. For inspiration, I suggest reading your employer's engineering career ladder, Julia Evans on brag documents, and Will Larson on Staff Engineer Promotion Packets.
Order your interviews from least to most desirable
You should interview with the companies you are the least interested in first, so you can practice on ones that matter less. Like all skills, you will get better at interviews as you do them. You also want all your offers within a few weeks of each other, so you can evaluate and negotiate them together. This means you need to control your interview schedule. Tell the recruiters when you want your offers, and work with them to schedule interviews at an appropriate time. The best recruiters understand how the game works and will accommodate you.
Prepare for your interviews
I learned that preparing for interviews is important when we were interviewing for the acquisition of my failed startup. It had been about 8 years since I had interviewed anywhere. We were cocky. None of us prepared at all. Let's just say that first interview did not go as well as we had hoped. Afterward, we got a friend to do practice interviews. We had one 4 hour session where we were each interviewed, then we critiqued our performance. That was a great learning experience, since it is very rare that you get specific feedback about how you can improve. I also read Cracking the Coding Interview. It has good advice about the general process, but I mostly skipped the coding practice questions.
It is hard work, but the hours you spend preparing will pay off over multiple years, by allowing you to get a job you want, and to be compensated better. It is probably one of the highest leverage activities for accelerating your career. Remember that interviews are more than coding questions! Don't forget to practice behavioural questions, system design, and be prepared to answer questions about your resume. Get a friend you trust to interview you, or try one of the online services that run practice interviews. Getting specific feedback about where you can improve allows you to improve much faster than trying to figure it out on your own (which can also work). I've included some more specific interview advice at the end of this article.
Negotiate your offer
Nearly every offer can be improved, so you need to negotiate it. If you want more advice, multiple people have recommended the book Getting More, but I have not read it yet.
- Get multiple offers. Business school people talk about "BATNA": The Best Alternative To a Negotiated Agreement. This means having alternatives that you are willing to take, so you can walk away from the negotiation. This can include staying at your current employer. Having multiple offers also provides you with more information about what what your "market rate" compensation is.
- Be respectful and polite to everyone you talk to, and don't lie. I have heard of offers being rescinded after people are rude or who misrepresent the facts while negotiating. The justification is that rude or untrustworthy people make bad co-workers. This is another place where bias can creep in, when people get offers rescinded for behaviour that would be accepted in white men. As a white man, I haven't observed this first hand, but I've heard enough stories that I'm sure it happens occasionally. If it happens to you, it is tremendously unjust. The only bright side is that you just discovered they are a problematic employer before you worked for them.
- I do not talk about my salary expectations, except in vague terms. Recruiters and employers negotiate job offers every day. I do it once every 4 or 5 years at most. They have a lot more information and practice. To help level the playing field, I want them to make their initial best offer, and we can work from there. On rare occasions I have provided vague guidance like "I expect the salary to be competitive with large publicly traded software companies" to ensure neither of us wastes time with an interview if that is not going to be possible.
- When being told an offer details, I do not discuss my reaction. I take notes, I ask questions to clarify the details, and then tell the recruiter I need to think about it. I want time to think about how to negotiate the offer. The only exception has been the rare time that the offer is bad enough that I clearly will not accept it as-is. In that case, I tell them directly: this is less than I was expecting, but I still delay the follow up to think about my approach.
- If you have multiple offers, I suggest asking every other employer if they can beat it. Tell the company that made the best offer that they have the best offer, but you are waiting for others to make counter-offers. Sometimes this will cause them to preemptively increase their offer. Don't do this more than once or twice, since there is some risk a recruiter will decide you are just using them to get more money out of your preferred employer.
- Consider trading one form of compensation for another, to fine tune your best offer. The intention is to make the package better for you, while the employer feels it is the same. For example, if you think the stock is risky, you could ask to reduce your stock package, in exchange for increasing your base salary by a proportional amount. Or you could try to negotiate away a signing bonus, in exchange for more salary. You could also ask for more vacation days, or other changes to your employment agreement. At most software companies, base salary is constrained to a "band" by the "level" you are being hired at. It is very rare that a recruiter or hiring manager can adjust your starting salary outside of that band. However, signing bonus and stock packages tend to be less constrained, so you may have more ability to negotiate for those.
- One strategy I like is once you get your preferred employer close to what you want, you can tell them "If you change X, I will agree to the offer immediately." You need to be prepared to accept the offer if they do match your demand, otherwise you are at risk of losing the offer. I think this works because when the recruiter and hiring manager know there won't be more rounds of negotiation, they are incentivized to make it happen.
Specific Interview Advice: Coding
- I start by asking clarifying questions, to ensure I understand the problem. Next, I write a basic example or two, if they are not provided. This can catch miscommunications early. I add to the examples as I find "special" cases, while working through the problem. After I understand the problem, I describe my high level approach, and confirm that it sounds acceptable with the interviewer. Often, they will guide you towards a "better" solution if you are close but not on quite the right track.
- My approach is to literally say "I'm going to start with the simplest thing I can think of, even though this is probably not optimal." I try not to waste time thinking about "smarter" algorithmic approaches. In my opinion, getting a working naive solution is much better than having half of a smarter solution. However, I do check with the interviewer that this is acceptable. They will usually tell you if it is or not.
- If you are using a computer, ask your interviewer if you can search for documentation or examples. Some will allow it, some will not. Run your code incrementally as you write it, rather than waiting until the end when you need to fix a large pile of typos and compiler errors. Finally, if you are using your own computer, come prepared with a project pre-configured in your favourite IDE, This will demonstrate your familiarity with software engineering practices and tools, and will score you some small bonus points.
- Bring your computer with a project pre-configured in your favourite IDE, ideally with an "empty" unit test. When someone asks you to write code, bring out your computer and ask if you can use it, rather than writing on the whiteboard. Many people will let you, even if they don't normally ask people to use a computer. I think it gives you a small advantage if you can demonstrate that your solution works with a small test. Offer to email the interviewer the code at the end. On rare cases people will insist you write on the whiteboard. Don't complain if they do.
- If you run out of time, or hit a problem you can't fix, you should describe what you would do next before the interview ends.
Specific Interview Advice: Design
- These interviews are intentionally vague. You need to start by asking questions to clarify the requirements, just like you would if asked to implement a new feature. Be mindful of the time, however. Some people ask too many questions, then run out of time to fully describe their design.
- Describe the system from the big picture, down to the details, rather than the opposite. I recommend starting with a high-level block diagram, a description of how a user will using the system, or an API. This helps communicate your thinking to your interviewer, and gives them a complete picture, no matter where you stop the interview. You then iteratively add detail until you run out of time.
- Draw a diagram, and use it while talking. It does not need to be detailed, but you should have one box with a label for every important component. I recommend standing in front of the white board, and literally pointing at a box every time you talk about it. It sounds a bit silly, but it helps ensure you and your interviewer are thinking about the same thing, particularly if there are more than 3 components.
- Say when you don't know something, but demonstrate that you can make reasonable assumptions. You are not expected to know everything. If something comes up that you are not familiar with, tell your interviewer, but follow it with a hint that you are happy to make some assumptions about it. For example, I don't really know anything about training a machine learning system. If I were asked a question about it, I would say "I don't know how machine learning algorithms work, but I know we need to provide them lots of training data. Can I assume I have a library that I will call with a single example, and it will return success or failure when it is done training?" A good interviewer will provide you with the right information to continue the interview, either way.
- Don't say anything you aren't willing to talk about in more detail. If you do need to mention something you aren't totally sure about, say it. It is much better to say something like "I think I might be getting this wrong, but I think this might be called idempotent", then to say "this is idempotent" and be wrong, or to be asked about why it is important, and not be able to answer.
- Name specific technologies as examples of what you would use, to demonstrate that you know about them, and to make your design more concrete. For example, if you need a database, don't just say "we should use a database." It is better to say "we should use a relational database, maybe Postgres." If you aren't very familiar with the technologies, disclose that in advance when you mention it. For example, "We should probably use a message queue. I haven't worked with them, but I think Kafka is popular."
- Briefly explain why you want to do things in a certain way. For example, "we should have a separate search service and a upload service" is okay, but "we should have a separate search service and upload service because I think they will have performance requirements" is better. The entire point of a design interview is to understand how you think, so you need to explain it.
- Design: If you realize you made a mistake, or want to change something you previously mentioned, explicitly point it out. It is a good thing to re-evaluate previous decisions as you explore the design. It is a bad thing to ignore it and hope your interviewer does not notice.
- Do a back of the envelope estimate, if a good example comes up. If you can show your thinking numerically, it is a lot more convincing than vague statements like "that sounds large" or "that should fit on one machine." For example, "we said we need to handle 10k requests a day. That is 10k/24/60 requests per minute. I'm going to get the math wrong without a calculator, but that is about 10k/20/100 = 10k/2000 = 5 requests per minute. That seems pretty tiny. Even if we assume peak load is higher than average load, we should be able to handle that on one machine."
- Hint about your areas of strength. While you are describing a component, if you could describe it in great detail, you should drop a hint. This lets your interviewer ask about it, if they are interested. Interviewers are also trying to evaluate your technical depth, so being able to demonstrate deep expertise in some area is excellent. For example, you can say something like "I'd like to make sure there isn't a problem with duplicate message processing here, but let's not worry about that for the moment", or "this seems similar to a project I worked on before, so we might be able to make this more efficient if we used use a storage engine like RocksDB, but let's assume we have something that works for now."