
I sent a copy of my resume to HubSpot, and one of their talent acquisition people got me on the phone to talk. It sounded like a potentially good fit, and I was invited to take the HubSpot coding challenge.
Which I did.
I have written about how badly coding challenges are often designed and how to do it better. It seems that HubSpot has also introspected on coding challenges and came to the same conclusion a few years ago and revamped their process.
The new HubSpot coding assessment is a small coding project, which you can perform using whatever tools you’d like. It has a 3-hour time limit, but they’ve designed it, they say, to fit into an hour or two. (More on this later.) Your solution does an HTTP GET at a specific URL, using a personalized API key, and the server sends a data structure encoded in JSON. Then your code needs to do some computation on the data and to POST the result to another URL.
This does not raise any of my red flags. It sounded pretty exciting, so I was looking forward to completing it.
Beforehand prep
I did as much as I could before beginning, using whatever information I had.
I knew the solution would be a REST client, so I chose Node.js as an environment. JavaScript grew up doing REST clients. (Back in the day, we used to call it “AJAX,” even after we exchanged XML for JSON.) And Node now brings all of that to the command line.
I spent a few days refreshing my JavaScript, delving into Node, and developing a minimal REST-client app that GETs data from a URL and POSTs it back, complete with an integration test. I even created a package that can be used to quickly spin up a minimal REST server in Node, for automated integration testing.
After I felt I had done all I could to master the background, I took a break over the long Fourth of July weekend.
The following Tuesday, I clicked on the challenge link.
Tackling the challenge
Without getting into details that HubSpot wants to remain private, my solution involved several processing steps:
- GET the input dataset from a specified URL, using a personal API key.
- Rearrange the input data into a more workable form.
- Calculate the desired answer to the challenge problem. (This is the business logic of the application.)
- Format the answer per the API requirements.
- POST the result to another specified URL, using the API key.
All pretty standard stuff.
Everything except for step 3 is coordination: I/O and rearranging data. Most of it can be expressed semi-declaratively in JavaScript, that is, without mutable state, and my top-level function (which I called main
) has no mutable state. The code that implements the core algorithm (step 3) went into its own module, and everything else went into the main script.
After setting up a skeleton project, the first thing I did was to write an integration test for the main script. This test spins up an in-memory HTTP server, with mocks that implement the API’s GET and POST methods. Then it spawns the main script, waits for it to exit, and checks whether it fetched the input dataset and provided the correct result. It does so using the sample data that HubSpot provided in the project requirements.
Most of this integration test was modified boilerplate from my previous experiments with my minimal REST client the previous week. Even so, it took almost an hour to complete (and contained a couple of bugs that would come back to bite me later). This test code would be instrumental in testing and debugging the final app and would become part of the final package.
So over a third of the way into the allotted time, and all I have to show for it is a not-yet-used integration test. I think you can sense where this is going.
I developed the business-logic module using test-first programming. This actually proceeded quickly and smoothly. The core algorithm requires some data structures and clear thinking, but it isn’t terribly clever—nor does it need to be. I wish I could say more because I’m really quite proud of it. And in the real world, if needed, the code could easily be adapted to run under a map-reduce or streaming framework, in order to scale to handle as much data as you want.
With the business logic fully and correctly implemented, I returned to the main script. By this time, I had used more than half my allotted time, and I was starting to get worried. I implemented the main script and hit “run” on my integration test. And…
Bugs, bugs, bugs
Lots of typos. You know that phase of debugging in which you run, observe some syntax or other stupid error, fix it, rerun, observe the next error, fix it, rerun again, repeat ad nauseam?
At one point, the base URL and API key weren’t getting parsed correctly from the command line. WTF? I’m using commander; it’s foolproof—I thought. Turns out, I misspelled the names of the properties used to access those values, and JavaScript (being a loosely typed language) was simply returning undefined
.
I finally got the thing running, then discovered that my getDataset
function (which uses fetch to GET the input dataset) was now returning undefined
.
Huh? This is f*ing boilerplate. What could possibly have gone wrong?
At this point, I had all the pieces in place, and I only had a few minutes remaining in my allotted 3 hours. So I ran the script against the real service. It correctly fetched the (massive amount of production) input data, calculated an answer, and sent back a result.
But it was the wrong result.
Nonetheless, at least I knew the undefined input dataset was a problem with my test, not with my code. Hacking with it for several more minutes, I discovered that I had—yes—accomplished another typo. Shrug.
By this time, the 3 hours had expired, and I was feeling much less stress.
I finally got the test running to a point where I could debug the main script. I had originally misformatted the result data. More debugging. More fixes.
The test still didn’t correctly detect success, but this was because the result data includes several arrays that are order-insensitive. So in my test assertions, I needed to first convert those arrays to Set
s before comparing them.
However, I was confident that I had worked through all the issues. I ran the script against the real service, and it succeeded.
Time limits and effort estimation
“The coding project has a 3-hour time limit, but we’ve designed it to ideally be completable in 1-2 hours.”
I “finished” in 3 hours 20 minutes, then spent another hour performing minor refactorings and fleshing out the documentation—the spit and polish. Oh, and I fixed that final assertion in the integration test.
We used to say: In order to get a realistic estimate of how much effort your software project will take, you should start with what you think it will take and then multiply by 3.
Now, to be fair, I don’t know how long candidates usually take to complete this project. (And I also don’t know the quality of their code.) I may have taken longer to POST an initial correct result because:
- I wrote my tests first, including the integration test.
- I wrote some of my documentation first, when it helped to solidify my thoughts and document my logic.
- I also snagged several times on bugs. Working through these did not take hours, though they did push me over the 3-hour limit.
But color me unconvinced.
Tests and documentation are not afterthoughts, but rather part of the process. You either acknowledge this and write them up-front, or else you spend even more time patching things up afterward. I used my tests in order to get my code working, as in each case they were key to helping me test (duh) and debug my code. I documented what I was doing so that I wouldn’t lose my train of thought as I worked through the phases of the project. And all of this became part of the final package.
To HubSpot’s credit, they did allow me to complete the project and submit it, even after the 3 hours were up. And they gave me as much time as I wanted after submitting a correct result to “clean up the code afterwards.” These are all positives.
And I admit that I enjoyed the project.
However…
The only concern I have is reflected in one piece of advice given me before I even started:
“I’d suggest being pragmatic about it rather than trying to be perfect, at least on your first pass.”
I’m not sure what that means.
So-called “quick and dirty” may be dirty, but it’s hardly quick. I mean, yeah, if I had just flung down code without tests, I might’ve gotten lucky and hacked together a working solution. And there are techniques to hack code faster (which we used to use before we had test frameworks). I could have, for example, hard-coded the sample input data in a getDataset
stub, debugged my application without a test, and then written the test afterward.
Is that the kind of developer you want to hire?
Tests and documentation are part of the process, not an afterthought.
I’ll have to see what they think of my solution.
May all your bars turn from red to green.
Tim
By Onbench February 5, 2021 - 4:47 am
Thank you for the information! Interesting post
By Rick Brownall August 11, 2021 - 8:16 am
Thank for this post, it was interesting to see the interview process of an established firm from a developers perspective.
By RK April 29, 2022 - 12:14 pm
Hi Tim, Were you selected after the delayed submission of the code?
Or were you rejected? I have also completed the test but took 4 extra minutes.
By Tim King June 15, 2022 - 7:33 am
I was not chosen. They said that, in their experience, the coding test is a good indicator of how well candidates perform in the interview process and on the job. (I don’t know how they determined that without distorting the measurement with confirmation bias, but whatever.)
If I were to do it over again, I would start by prototyping a solution, as quickly as possible, just to feed a correct answer back to the automated endpoint. If I understand correctly, that stops the clock. Then I would throw away that solution and start over again with production-quality code.
We do that in real life, but usually only when the prototype teaches us something. We’ll put together a spike solution in order to learn about the technology stack or the problem domain or as a proof of concept. But most of the time, if I understand the technology and domain, if I have a working top-level architecture sketched out, if we know we’re going forward with the project, and if the risk exposure is otherwise low, I will not recommend a throw-away prototype.
In this case, however, given that I needed to have a demo within a certain time period, it would have been prudent to prototype the solution. In real life, such demos don’t tell us much about the project, but they make some executives feel better. If we were having a two-way discussion about risk exposure, then I would feel better about the approach, but that discussion also rarely occurs.
By Chris January 23, 2023 - 5:41 pm
Nice article!… I noticed the code challenge statements were the same as you already described through the writing.
In my case, I started the test late in the night (wrong decision… ), I got a bit frustrated about not getting the correct response format after having dedicated the 3 hours, so I went to sleep. Next day, I continued with the test (afternoon). I was aware that I was missing one use case, however I decided to submit the solution, taken into account that they mention in the challenge preparation video that is better to upload something no matter if a wrong answer is provided, so I took the risk.
I got the following “robotic-answer” via email:
….”First off, thank you so much for taking the time to complete the code test. I know it’s a big ask with everything else you must have going on. That being said, based on the team’s review of your solutions and the current pool of candidates, we’re not going to be moving forward at this point. We have found that the code test tends to be a very strong indicator of success in the remainder of the interview process as well as on the job.
Due to the volume of candidates, we are unable to provide feedback at this stage in the process but we encourage you to visit HubSpot’s Careers Blog for additional tips on interviewing at HubSpot.
We very often revisit candidates and have a solid track record of hiring folks down the line, once they either gain some more experience or have better luck with the code test the second time around.”….
It’s a bit controversial the fact they say that they look for more experienced candidates, but they also said that is a “lucky matter” when it comes to solving the test.
It’s a bit funny the way they value finding the right solution by a sort of magic spell or just because you were lucky to provide a non-optimized result, even roughly developed code due to the need for submitting a solution in three hours. (No hate… just ironic hehe).
Afterward, I found the correct solution (I noticed the API key they provided me was still working) and I got the following email…
….”Congratulations on completing the HubSpot coding challenge! Your solution was completed after the three-hour time limit but we’d still love to see your work.
Feel free to polish up what you have a bit if you want to before you send in the code, although there is no obligation to do so. We’re not looking for fully optimized, commented code – we’re more curious about how you chose to implement a solution.”…
Finally, I think they did not review the code itself, they just dismissed my actually wrong and very first solution, they also looked at the submitting times and whether the candidate found the correct solution or not, in order to pass this code challenge.
I just wanted to share my thoughts, I wish you all the best 🙂 … I think luck it’s the sum of the passion, work, and effort you put on your daily basis no matter if you fail the first time.
By Manda Murphy October 24, 2022 - 6:11 pm
This was very informative. I just completed the hubspot challenge yesterday. Had the correct solution in 1.5 hours except for 1 stupid type-o that had me panicked to the point that I gave up. Uploaded my code. Took a long break. Came back past the time and figured out the type-o and it worked fine. I beat myself by being too nervous about the time. I would also say that this challenge is very much geared towards an object oriented solution and using an OO language would probably be easier (at least, IMO). Impressed that you got the solution with JS. Believe it or not, they invited me for another round of interviews. So I think it’s important to submit the code at the 3 hour mark so they can see what you accomplished, and how, in the given timeframe. It was pretty obvious from my submission that I made a stupid type-o, which I communicated to the recruiter. to me this was the best code assessment I have done. It’s a very “real world” approach – not some silly algorithm that has no merit in real code environment. And I loved that I could do it on my own schedule, when I was ready, without eyes watching me, and use the internet for solutions. HubSpot also provides enough information that you can wireframe a template before starting, which I highly recommend. The solution took 1 hour and that was pretty much just me typing. Testing took 30 minutes. Me panicking took the rest of the time. LOL
By nfrhlRIg April 10, 2025 - 4:01 pm
524264 716752Interested in start up a online business on line denotes revealing your service also providers not only to humans within your town, nevertheless , to numerous future prospects which are cyberspace on several occasions. pays everyday 559902
By บาคาร่า ufa11k April 11, 2025 - 3:24 am
983782 920176There some fascinating points in time in this post but I dont know if I see these center to heart. There might be some validity but Ill take hold opinion until I explore it further. Excellent article , thanks and then we want a great deal more! Put into FeedBurner too 791115
By อัพเกรดไฟหน้ารถยนต์ April 11, 2025 - 3:24 am
196259 384643A domain name is an identification label which defines a realm of administrative autonomy, authority, or control within the Internet. Domain names are also critica for domain hostingwebsite hosting 937665
By read more April 11, 2025 - 5:00 am
177463 657596We offer the best practical and most applicable solutions. All our Sydney plumbers are experienced and qualified and are able to swiftly assess your difficulty and uncover the very best remedy. 112756
By 1xbet April 11, 2025 - 8:08 pm
847875 27275I do not have a bank account how can I place the order? 227397