What should you know if you want to apply for an engineering position here?
Well, first of all, you want to be here.
We work on projects that matter and build tools that make a positive difference in the world. The complexity and scale of our data and the problem domains we work in are hugely engaging giving us the opportunity to truly innovate; we advance the state of the art in our field.
If that isn’t enough, DomainTools leadership sets our direction but gives the engineers the freedom to plot the course. Respect, openness and trust flow both up and down the organization, and this has a massive impact on what motivates us. We aren’t driven by deadlines or budgets or pointy haired bosses. We are driven by doing excellent work to solve tough problems that add value to our organization as we work together to make the world a better place.
This is an amazing place to come to work every day. But in order to maintain this sort of organization, we are very invested in our hiring process. We want to bring on engineers who can take ownership of business problems and deliver best fit solutions, and we also want engineers we hire to know that if we’ve brought them on board it is because we are confident they can do the work. Because of this, a lot of thought goes into how we conduct our interviews.
When DomainTools goes through a round of hiring software engineers, as we are right now, we try to make sure we are asking the right questions. Our on-site interviews have a Google-ish feel to the technical depth we plumb while also taking a holistic view of the candidate through each round of interviews. And we are always re-evaluating our approach.
One subject that frequently comes up when we evaluate our interview process is how much focus to put on algorithm complexity analysis, sorts, and other puzzles that our engineers are actively encouraged to avoid implementing because they are “solved” problems.
We don’t expect candidates to be able to derive dijkstra’s algorithm from scratch or know the time and space complexity of every sort off the top of their head. Memorizing facts isn’t what we are about. We do, however, want to probe critical thinking skills, assess how people approach solving problems, and learn whether or not they are willing and able to do the research necessary to handle the very tough problems we actually do have.
We care about asking these questions because we want to be able to trust our engineers to make the right call when we have to decide whether to build or buy something.
Algorithm analysis and purchasing decisions? What does one have to do with the other? Maybe everything.
In software, as with Lando Calrissian building Cloud City, we don’t start from the actual ground and build up from there. We use off the shelf components and build on top of them. This includes operating systems, language libraries and more application specific third party tools. Eventually, as we get closer to our core business, it becomes necessary to write code to get the actual job done.
But how much code should we write? Should we only ever write strictly business logic? That’s unrealistic. Should we maintain our own in-house linux kernel fork customized and optimized for our use case? Probably not unless our product is a linux distro.
When we get to that blurry line between what other people have done and what our business needs to do, how do we decide whether to build or buy?
Engineering time costs a great deal of money and it’s easy to think the right answer is to prioritize using as much pre-existing code as possible. Don’t reinvent the wheel, as the saying goes.
But the build/buy decision is an engineering decision. Cookie cutter decision making is not engineering and solving engineering problems with stock solutions leads to the wrong decisions being made. Sometimes wheels won’t fit or aren’t built right for the task, and only engineers can tell you this.
Engineers are creative problem solvers. Every hour of every day we are running some sort of mental cost/benefit analysis. Every line of code that isn’t essentially already written by the functional needs of a project is a defacto business decision made by the engineer and later approved or rejected by the other engineers reviewing the code.
The role is not really about writing code. Sure, the job can’t get done without code, but it’s just the tool of the trade. Engineering is making difficult and complex business decisions based on knowledge of the problem domain, concrete data, and experience.
We trust our engineers to make these decisions because we value an understanding of algorithms and theory in our interviews. Memorizing a lot of “good” ways to tackle challenges is possible, but when a company pushes the boundaries of what is possible as much as we do, good is frequently not good enough. We need real engineering, we need decision making, and we need concrete data. How do we know when a merge sort is faster than an insertion sort? Because there is math for that and we’ve done the research.
Often we need to understand why something was built in a certain way to make the right call. Essentially, engineers need to know how to have built many of the tools they use to understand whether or not it is the right fit for the task. Even sorting methods that come baked into every programming language we use.
If you can show us your ability to reason through fundamental algorithms, then we know we are hiring someone we can trust to make the right call when choosing or designing higher level tools and systems.
For any hiring managers reading this, if your organization isn’t plotting a trajectory that leads you to the best fit implementation of your core competency, you are betting against your company. The way to get there is to hire great engineers that you can trust to understand the business and see the best practical technological path to a solution given the constraints. We know we are doing that by asking deeply technical questions about solved problems and why those solutions are the right ones during our interview process.