Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Three hours seems a bit much. Was there anybody where the signal wasn't clear in the first hour but the signal somehow became clear in hour 2 or 3?



It depends on the project, but it actually can take 2 or more hours.

It can start with getting it to compile in the first place. I've spent days on building C code bases, getting the dependencies there, everything in place, then you wait, then there is some error, then you google, then you don't find anything, then you debug a makefile of one of the dependencies, etc etc. Some projects don't compile with packages from apt-get at all. Take most Rust projects for example, unless you are using a rolling release distro, your rustc version is too old.

Then you need to look at the quality of the code base. Sure maybe it's just a simple else if chain and one of them has an add and sets result = a + b; inside. Then you can copy it, modify it for multiplication, done. Trivial!

But maybe it's done via a plugin system and spread over 5 different components, and there's actually two plugins you have to add, one for the repl, one for the internal handling, and there is non trivial communication between them. So you copy the 2 thousand lines of plugin code spread over 8 files and there's a bug. How do you debug it?

You also need to be able to start the thing. Maybe it's not meant to run on developer's laptops but instead is deployed in the cloud and you have to use some unfamiliar tooling to access it?

Now, apparently in this instance the project was easy to compile, modular enough (and also not too modular) for the position needing the change to be identified in quick time, and easy enough to run and test that you could also explain your solution in one hour. But this is not guaranteed.


Any interviewer who designed a question with those kinds of pitfalls in it has done a bad job. This question is good partly because the memcached codebase is itself good. It’s not so abstract that the candidate needs to chew through a whole class hierarchy or plugin system in order to make changes, and yet it is complicated enough that the will have to make important choices, particularly with how to handle a new type of operation.


> But maybe it's done via a plugin system and spread over 5 different components, and there's actually two plugins you have to add, one for the repl, one for the internal handling, and there is non trivial communication between them. So you copy the 2 thousand lines of plugin code spread over 8 files and there's a bug. How do you debug it?

In enterprise Java, there is almost certainly a crazy amount of indirection, both static and compile-time.

A trivial task like "Write an API to retrieve a certain set of records from the database, and return them to the client caller" can involve:

1. Figuring out how the framework calls your API, and where the parameters are in the call. This is specified in some config (yaml/xml/whatever) file somewhere that the framework reads so that it can validate the parameters before it passes them to your code.

2. Figuring out the config-file syntax for specifying the validation criteria for each parameter and for the return value.

3. Determining if the specified list of columns is already encapsulated in an existing class. If it is, you're luck, just instantiate that class with the correct criteria and read the fields into the instance you will return to the framework.

4. If no existing class satisfies your needs (99 times out of a 100, there won't be), you realise by looking at similar existing API code that you need to create a application-logic level class that contains fields with all the values you require.

5. You do #5 above; then you read the existing API callchain again, and see that all other application-logic level classes don't talk to the DB directly anyway. They go through a DB-level class. This is because at some point in the future someone may want to swap out the underlying DB with another DB.

6. The DB-level class is tied to a specific ORM (say, MyBatis). It uses classes generated by MyBatis. You write your DB-level class to use a MyBatis-generated DAOClass.

7. You then dig into the details of the ORM, figure out which config-file (xml/yaml/whatever) to modify, how to write the template that contains the specific parameterised SQL statement (if using SQL), how to specify to the ORM that each column be matched to a specific Java type, and how to convert it if it is some other type.

8. You Aren't Done Yet! For each of those classes you created (the API handler, the Application-level class, the Dao class and maybe the generated classes from the ORM, you need to write unit-tests! The unit tests, in this simple example, will easily be twice as large as the actual new code written/generated.

9. You're done, for now, until integration testing in a pipeline fails. But that's a different issue that will always exist regardless of language or development methodology, so that one gets a pass.

And, believe it or not, the above is actually a simplified version of how it actually gets done. For example, there's going to be more lines of code mocking an instance in the tests than there are lines of code implementing the class itself.

Also, the framework calls your API, but your API probably doesn't directly instantiate the Application-level class - it hands it off to a 'call_handler' type of class that performs a threaded/sleep invocation[1] of an actual 'call' method in your API class.

Also, anything your class may need (instances of other classes that perform non-local stuff, like recording metrics, logging, lookups, etc) will be injected at runtime, and so you cannot simply declare an instance of the (for example) LookUpAddress class - you have to request an instance of that class from some sort of dependency mapper or injector, which will be provided to you when the framework calls into you.

This is normal. There are various reason for every single step above, and large companies (FAANGs, for example) will adhere to every single step (and more, like using classBuilders) because it checks all the boxes except velocity.

A startup, OTOH, had better forgo all of the above; create a monolith with no runtime injection or modification and skip all the unit tests (use more beefed up integration tests, for example). A startup can't afford to spend a day adding a single simple API, when, in the same time, they might be adding 25 new simple APIs.

There's no point in all of the rituals if the startup finds out 5 months in that the product doesn't have market-fit. It's better to determine market-fit in the first month or two.

Having paying customers is more important than having dependency injection, or the ability to switch databases.

[1] When not using Java, the 'call_handler' will use some sort of async/await call to do a proper async request.


I'm not sure where the three hour thing is coming from. During my tenure, we gave candidates one hour.


Out of thin air:

> I forget how much time they gave for it. Let’s say three hours, counting the time to explain the problem.


ankrgyl claims to be the author of the question; I don't think they're the author of this blog post about the question.


The blog post is where that duration came from; I think both the asker and the question author missed the first part of the line from it I quoted.

If you search the rest of the comments here for "three hour" there's quite a few people jumping on that rather than just accepting it as "eh, I don't remember so I'll just throw something out there".




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: