The following is the current version of a section in my book on interviewing for technical roles. I’m trying to help out with any advice I can while I’m putting all of this together. As part of that, I’m looking for constructive criticism and feedback. My experiences as an engineer are also not universal and so my own biases will creep up in my writing. With your input, I’m hoping to refine my own writing to help other folks out. If you’d be so kind to offer your advice in response, I would love to hear it.
For many in tech, coding is a core part of the job. While a lot of interviewing is talking about programming, it’s likely that a team will want to see code you’ve written before bringing you on board, even before in person interviews. One option some companies choose is giving out a homework assignment or requesting a code sample from prospective employees. From the vantage point of a company, it’s a low cost filter – you can start mapping a candidate’s abilities early on before investing too heavily in employee time through direct screening. The effort is shifted to you, the potential hire, to invest your time in answering code related questions or provide a sufficient showcasing of your work. With some strategic planning, you can leverage this hard work early in the process as a platform to build a strong case to hire you!
It’s worth noting that code samples and homework are not universal. Some companies are without the resources to add yet another layer of interviewing into their process, focusing on discussions and in person coding instead. There are also technical roles in engineering that don’t require a level of programming skill warranting a code sample as a filter in the process either – think technical managers, data analysts, and some ops related roles. Ask the hiring manager or recruiter as you first make contact, as they should be able to fill you in more.
What’s the difference between a Code Sample and Homework?
A code sample is typically a small piece of what could be considered a portfolio for a programmer. It’s typically freeform, offering flexibility in what you’re being asked to submit. Have you built a project as a hobby in your spare time or contributed to open source? Maybe you’ve worked with a tool that your prospective team uses in their stack or have a home brew frontend framework. The lack of a defined structure means you get to choose how best to represent yourself. And you can have fun with it!
A code sample by its nature offers a loose interpretation on requirements, which can lead to uncertainty on your part. An ambiguous request lacking specific directions can make it difficult to gauge what is “good” to submit. How much is too much or too little? If I’m proficient in a language that my reviewer isn’t, how does that affect their judgment of my work? We’ll look more at how to best answer these and other uncertainties later in this section.
A homework assignment has more structure and relies on a question/answer format. It may be one medium sized project, such as implement a particular algorithm, or it may be several smaller individual questions to answer. By defining the direction for the assignment, a company is looking to clarify the goals for you as a candidate and for potential reviewers who may be looking for consistency to compare apples to apples. The questions may have a discrete answer they’re looking for (“Given this directory of files, count the number of instances of ‘Foo’ in each file”) or writing a function to solve a set problem (“Write a regular expression to parse the following zip codes from these lines”). It’s not uncommon for these take home assignments to have a timed constraint either.
This imposed structure lends itself to more rigidity in the response. For example, open ended questions might not be so open ended if there’s a bias towards a particular implementation. Questions looking for a concrete answer (e.g. “Did they come up with 42?”) leave no wiggle room for partial credit. Time limits can be equally stifling if you’re keeping strict to the rules, which doesn’t offer a strong signal for an engineer’s skills. Who says coming up with the “right” answer in one hour is much better than answering it with more thoughtfulness in two? The clear-cut nature of a homework assignment can produce false negatives, which can be especially damaging to a candidate so early in the interview process, as candidates proficient in quiz taking don’t always equate to adept engineers.
Making the assignment work for you
There’s a ton of information to be gleaned about how you write code. Think about this: your code sample lives in a source control repository (git, mercurial, or svn as a few examples) and is accompanied by a readme file and a discrete directory structure containing code with clear, consistent design choices. Your classes are well constructed with functions that do just enough and no more than they have to. This says a lot about your programming style. Conversely, if a sample is one file five thousand lines long with little whitespace, mixed naming conventions of functions with camel case and underscores, and poorly named variables, then it might be difficult to incorporate that engineer’s style with your current codebase. There’s an aphorism that says “Always code as if the person who ends up maintaining your code will be a violent psychopath who knows where you live.” Even if that “psychopath” is you 6 months from now.
If you’ve been asked to submit a free form code sample or an open ended ask to showcase your talents, try to cater it to the role in particular. If you know ruby and it’s a ruby shop, that would work well! Of course, you might not know the language of choice for the position. That’s ok too, just make note of it alongside your sample stating how principles you’ve worked into the project are language agnostic. This applies the same for homework assignments if details are not specified. Similarly, the Venn diagram of your skills and those required may not entirely overlap. Before my systems engineering role at Etsy, I had been working on an internal only platform for a smaller number of clients. I had been using PHP, which was a great fit, but the scope of impact from a few hundred people to several million as external consumers meant how I put together my code had to change. No two jobs will line up perfectly, so cater to the intersection of the skill sets you possess and those required for the position. Every time you communicate with the company, you have the opportunity to set the stage as to why you’re right for this job. Take home assignments are yet another opportunity to tip the scales to your favor.
What are Engineers looking for in Homework and Code Samples?
To summarize everything you will need to include is beyond the scope of this book and several others after it. If no two engineers are quite the same and will interpret code differently, it’s near impossible to guarantee any submission will be universally praised. That said, it’s helpful to think about what engineers will want to read and what will get them excited to work with you. What assumptions will they make about working with you if they were to hire you? When working on a code sample or homework assignment, think about the readability and the runnability of the submission.
Readability defines the effort involved for someone to understand what your code is trying to accomplish. Code not maintained is code that breaks – people are what make our systems work. Engineering should be collaborative and therefore concepts within it easy to share. If it’s frustrating to work with code someone has written, I tend to avoid it for fear of breaking its functionality. And if it’s already broken, I can’t fix it if I don’t know what it’s trying to accomplish. By making your code easy to grok, you’re acknowledging your part in building this collaborative approach to engineering.
Runnability is how easy it is to get it set up and how well it runs during execution. Will it require an hour to compile and many different libraries with very specific versions? Or does it come ready out of the box? If it’s a CLI tool, does it have too few flags to give it full functionality or too many to overwhelm a user? How well does it run in a browser, and does it require a long wait for many separate assets to download? These are just a few questions to ask. In short, make your code seamless to execute and quick to run with little effort by your users.
A non-exhaustive list of concepts to keep in mind while putting together your assignment:
- Comment often but not profusely. It doesn’t have to be every line (some code can and should be self explanatory), but include above functions and alongside lines that might need a bit more insight as to why you made a choice. This helps to bridge the gap between you and your reader. If you’re using multiple files or classes, likewise comment at the top of each.
- Keep code blocks to a reasonable length. Smaller, discrete blocks of code can be mentally abstracted and better understood over large, unwieldy multi-hundred line blocks. This is often referred to as the Single Responsibility Principle. What’s reasonable, you might ask? There are no hard and fast rules that apply. If you have trouble understanding all of the functionality of a block of code at a given time, it may be worth refactoring into smaller pieces.
- Name your functions and classes well. Names should be consistent using a known convention (camelCase, snake_case, PascalCase, or other similar scheme). They should also be declarative of their functionality without being a run on sentence in length themselves, making it burdensome to type out every time.
- Write tests. It doesn’t need to be 100% code coverage, but acknowledging that tests are important and that you know how to write them can tick off another box on the list of good engineering practices.
- Avoid deeply nested loops. If you have several layers of loops in your code, you can probably take time to refactor your approach to the problem.
- Set up a Readme. Self explanatory code is great, but I shouldn’t have to read its entirety before knowing what it does and how to run it. It doesn’t have to be a multi-page user manual, but an overview can go a long way.
- Keep it DRY (Don’t Repeat Yourself). Repetition in code, especially in a code sample, means you’re forcing yourself to maintain more code, which means more work when things change and when you’re sussing out problems.
- Keep execution simple. Features are great, but if there are a hundred options to choose from, they’ll be mostly ignored. Do a few things and do them well.
- Make your code easy to execute. If your code requires compilation, include the build files needed and expectations of environment to run in (and avoid needing escalated privileges!). Ditch any specific versions or cutting edge libraries as requirements as well. If you can, make it platform agnostic, so it can be run in many environments. If that requires too much overhead, have a working online resource where you can see it in action.
- Understand resource limitations. Will it use many CPU cores, require high network bandwidth, or tons of RAM? Emphasize an understanding of those costs wherever you can when designing and implementing your code sample.
- Sanity check your code. An edge case missed can be excused, but if you have major bugs in your code or it fails to compile, that is a big red flag for companies. This may seem obvious, but you’d be surprised at how often making a “last minute tweak” before submitting will break things.
In general, think about what engineers will want to read and how you can make it easy on them.
Ideas to Inspire
Without a project or a problem statement to work on, a code sample can be open ended to the point of paralyzing you with innumerable options. There’s also no specific book to reference for a homework assignment, so there may be a strong sense of inertia to overcome when answering a question in just the right way. If you’re coming out of college or other similar institution, many of your projects may be more academic in nature, such as an implementation of a known solved problem. For self taught or code school engineers, there can be the worry that your project quite isn’t “ready” for professional development. With all of this in mind, how do you design and code an entire project from thin air?
Focus on what code samples and homework are trying to achieve: gaining another facet of perspective in pairing your talents with a company’s requirements for a role. Try to look for the intersection of all these great skills you’ve developed and the problem statement given for the position. It may be helpful to explore the job description and the products a company offers and try to break down how they might work. What tools do you have that can solve those problems, and potentially add new features to their suite? All the better, if there’s a public API, try brainstorming some ideas on how you can expand upon existing components. Take a practical approach to solving an engineering problem laid out in front of you.
If you or your potential company has a flair for more artistic endeavors, you can take your idea for a code sample in that direction as well. Choosing a more stylish project over pure functionality can demonstrate your ability to think beyond an assignment as dictated. A creative outlet in engineering can’t be understated, a rare talent for someone to take an idea and grow it beyond given parameters. This may prove easier for frontend folks, as it can often be a more visual medium.
Still feeling a bit lost? Here are a few more idea you can run with for your project, broken down by role:
Ed. Note: If you have more suggestions for code sample ideas, let me know in the comments. Thanks!
For Junior Engineering roles…
- Your personal website you’ve designed on your own.
- A creative way to connect one or more API’s. Think of some of your favorite products and see if there are open API’s to interact with. Examples include Google Maps, Twitter, and Steam.
- A Slack bot to pull down info into your channel or fetch resources.
- A card game (Poker, Blackjack, etc.) on the command line.
- A class inheritance schema with a driver file to demonstrate Object Oriented Programming principles.
For Frontend Developers…
- An ajax request sending input from a form to an origin server and returning a manipulation of the data (such as a rot13 letter substitution cipher or pig latin translation).
- A drag and drop interface for sorting HTML elements on a web page.
- A page demonstrating a responsive approach to displaying a website in multiple browsers and mobile devices (with screenshots of how they would appear in each).
- Two pages visually the same but with js blocks, css assets, various usage of fonts, and images loaded in differing orders to demonstrate an understanding of how page load speeds and their order affect a user’s experience.
For Infrastructure Engineers…
- A port of an existing toolset to a new language. Note: indicate that it is indeed a port with reference to the original to avoid the potential accusation of plagiarism!
- Implementation of one or more design patterns: Singleton, Decorator, Observer, etc.
- An extension to existing popular software, such as an Apache module or a Ruby gem.
- A well documented RESTful API of your own (even if the functionality is just stubs).
- Monitoring a known piece of infrastructure, sending metrics to a service to be collected and displayed in a graph.
- A health check for an external service (like Nginx), checking various endpoints and modifying the response based on response codes returned.
- One or more chef recipes, roles, and templates to show your understanding of config management across a fleet of servers.
- A creative take on a popular service or tool (I have a friend who wrote his own web server in bash on a dare!).
There’s no shame in asking questions to clarify points for an assignment if you’re unsure about details. Engineers ask questions all the time to better understand problem statements. That’s a critical part of our job, and having empathy for the needs of others plays a strong role in that. If you can’t understand the requirements to solve someone’s issue, you can’t properly develop a solution for it.
Asking earlier in the process is preferred over later. If you email 4 hours before an assignment is due, it can appear as if you’ve been procrastinating, which can in turn be a potential signal for someone who isn’t strong with meeting deadlines. Questions can be asking about a preferred language or style, length preferred, environments to run in, uncertainty about how a question is worded, or even approach to the problem. Phrasing helps here as well. Asking “I don’t know how to do this, can you offer guidance?” isn’t going to impress folks much, as it sounds as though you need hand holding through the work. Instead, try “I have a couple design choices I’m deciding between, with the pros and cons of each. Is there a preference?”. You’re demonstrating your ability to reason about a problem, weighing the choices you have before you and discussing it with engineers you would be working with. If they decline to answer or are unable, use your best judgment and mention other options in the readme or in any areas for comments.
I would avoid asking questions external to anyone not directly involved in the interview process. Posting on a job board, in StackOverflow, or asking a friend for pointers isn’t in the spirit of the assignment. Your contact in the interview process may give you more strict directions, such as avoiding any resources at all or allowing for referential material (e.g. looking up the order of arguments for a PHP array search function) but not explicitly looking up the answer to a question. Violating that rule is a surefire way to get rejected quickly.
Pushing Back Against Assignments
After telling you about all the ways to approach putting together an assignment, I’m now going to tell you how not to work on one. There’s a belief in some circles in the industry that companies shouldn’t require a code sample or a homework assignment. You don’t have a job at this point and you’re committing yourself to work. That labor goes without compensation and will most likely never be used in any meaningful context beyond that interview. Worse still, you don’t get the job and they could keep your code to use. Some folks have full time jobs, take care of family members, study for exams, or have disabilities that make an exhaustive non-stop cycle of working untenable. Not everyone can afford to do take home assignments.
I’m not going to lecture on the improprieties of code samples or homework as part of the interview, as I don’t think declarative, all-encompassing statements apply to everyone in all situations. Some engineers have strong antipathy for assignments while others prefer it over other methods like whiteboarding or pair programming for examining one’s ability to code. I’ll only tell you what I’m comfortable with and what I’m in a place of privilege to do. I have a preference for working on a project at home where I can think through a problem without feeling someone else’s eyes observing me as I think through a problem. I have a family I want to spend time with and I need to unwind after a work day, but I’m healthy enough to make the time to put into preparing for interviews this way. Even with limits imposed, there’s more time to think through the implications of a project without each keystroke in a terminal or character being examined. Writing down ideas and deleting them doesn’t carry with it an implicit feeling of judgment like it does in person.
If your strengths or abilities don’t afford you a take home assignment as a strong indicator of your prowess as an engineer, you have the option of saying so. That could have negative implications depending on the company you’re applying to, but it’s a decision you’ll want to make if you feel that you can better present yourself elsewhere. If the time commitment is an issue, ask that the coding work be done on premises as part of your in person interview, though you may be timed a bit more strictly as a result. If you’re being asked to do more than a few hours of work on a project that seems like it’ll be used in a production environment, you can also ask to be paid as a freelancer for your time, which if they agree can show their earnestness in interviewing you. Likewise, you can point them to projects or open source you’ve created before, then discuss some of the design decisions you’ve implemented. Finding common ground that best suits everyone is ideal to show commitment to the interview without sacrificing yourself.
Header Photo: https://www.flickr.com/photos/76462417@N04/33384277193