12 ms·
Async Queue – One of my favorite programming interview questions
- comrade1234 1y agoDo I have to use JavaScript? I'd write it in Java in a way that it would be trivial to ramp up the number of connections in the pool once they fix their stupid server.
- deleted 1y ago[deleted]
- vrighter 1y agoTalk about javascript, present code in typescript. This would put me (the interviewee) off
- dudeinjapan 1y agoHmm… this code doesn’t work in the real world unless you only run it on a single machine. Perhaps a more interesting question is how to make a multi-node queue with max N concurrent requests.
- davidgomes 1y agoThe whole point of this interview is that the candidate is operating on a single-threaded environment.
- ramon156 1y agoThese are multiple assumptions "This queue is only on one machine and on one thread", what's the real world use-case here? Not saying there's none but make it clear. I wouldn't want to work for a company that has to think of some random precise question instead of e.g. "when would you not use mysql?"
- dudeinjapan 1y agoI guess I don’t want to hire candidates who assume the world is single-threaded
- jonchurch_ 1y agoThis is handled in the framing of the question: “… it doesn't ever have to handle more than one request at once (at least from the same client, so we can assume this is a single-server per-client type of architecture).“ For sure a multithreaded async queue would be a very interesting interview, but if you started with the send system the interview is constructed around youd run out of time quickly.
- reillyse 1y agoI dunno, seems like a really confusing question. Communication is important but I can imagine that explaining this verbally on the spot to an interviewee would not be straightforward especially because the assumptions made around single threading get confusing. If it's just a Javascript question say that - because it seems it basically is. Writing this in go would be super easy so I think the question is just asking people how well they understand Javascript.
- qu0b 1y agoYeah, I really don’t see how this is a sensible interview question. It does not even mention async await syntax. Expecting knowledge on callbacks seems dated.
- numbsafari 1y ago> seems like a really confusing question Agreed. ‘sendOnce’ implies something very specific in most async settings and, in this interview question, is being used to mean something rather different.
- isbvhodnvemrwvn 1y agoThat makes it even better, the candidate should ask clarifying questions. I've worked with people who, when encountering some amount of ambiguity, either throw their hands up, or make some random assumptions. Ability to communicate effectively to bridge the gaps in understanding is what I'd expect from any candidate, especially more senior ones.
- mgfist 1y agoSure, but this isn't a back&forth interview - it's a blog post. The author could have included a section with clarifying questions they expect the candidate to ask, and responses to those questions. As it stands, we still don't know why the server was broken in this way and why they created a work around in the client instead of fixing the server.
- 8note 1y ago
- ZiiS 1y agoInterviews are a two way street. If you strongly imply that working around servers that only do one thing is part of your day to day work, a lot of people will want to work somewhere they can learn about more modern software.
- armitron 1y agoThis is one of the most confusing and badly worded interview problems I've ever seen. If I had been given this problem, I'd view it as a signal that I'd be wasting my time working with the folks that thought it was good.
- jonchurch_ 1y agoMaybe I came into this article knowing too much about the solution, but I dont agree with commenters saying this is a poorly designed interview question. Its a blog post as well, not the format that would be presented to a candidate. I think it has clear requirements and opportunities for nudges from the interviewer without invalidating the assessment (when someone inevitably gets tunnel vision on one particular requirement). It has plenty of ways for an interviewee to demonstrate their knowledge and solve the problem in different ways. Ive run debounce interview questions that attempt to exercise similar competency from candidates, with layering on of requirements time allowing (leading/trailing edge, cancel, etc) and this queue form honestly feels closer to what Id expect devs to actually have built in their day to day.
- aidos 1y agoI feel similarly and again. We actually have this pattern in our codebase and, while we don’t have all the features on top, it’s a succinct enough thing to understand that also gives lots of opportunity for discussion.
- michaelsalim 1y agoSame here. I thought that this specific problem is not that uncommon. On top of my mind: say if the endpoint you're hitting is rate-limited. It doesn't even have to be an API call. I think I've probably written something with the same pattern once or twice before. I do agree that this is quite javascript specific though.
- reillyse 1y agoIf it’s rate limited it’s handling the concurrency for you. Just back off from the rate limit.
- MatthiasPortzel 1y agoI could write a solution to this pretty quickly, I’m very comfortable with callbacks in JavaScript and I’ve had to implement debouncing before. But this interviewer would then disqualify me for not using AI to write it for me. So I don’t understand what the interviewer is looking for.
- ncann 1y ago> Here's a naive, faulty implementation For this first implementation, I don't see anything ever added to the queue. Am I missing something? New task is added to the queue if the queue is not empty only, but when the queue is empty the task is executed and the queue remains empty so in the end the queue is always empty?
- JohnKemeny 1y agoThat's how I read it too. Nothing is ever added.
- Arch-TK 1y agoThat's correct.
- 63stack 1y agoAnother thing is that the article emphasized that it's single threaded. That by itself guarantees that there will only ever be 1 inflight request, since calling the send() function will block until the request completes, and the callback is called. If there is some kind of cooperative multitasking going on, then it should be noted in the pseudo code with eg. async/await or equivalent keywords. As the code is, send() never gives back control to the calling code, until it completely finishes.
- _benton 1y agoJS has an event loop, it's single threaded but still lets you write asynchronous code. let send = (payload, callback) => fetch(...).then(callback) fetch() returns a promise synchronously, but it's not awaited.
- 63stack 1y agoI'm well aware, but the send() function in the article is not marked as async, and has no .then() calls.
- gpderetta 1y agoit is too abstract to say for sure, but send might just block until the request is handled off to the next layer (for example succesfully written to the OS network socket buffer), so unless the server carefully closes its recv window until it is done handling the request[1] , no, I wouldn't expect send to block until the server is done handling the request. [1] i.e. backpressure, which would actually be the ideal way for the server to implement whatever rate limiting it wants, but we are assuming here that the server has a less than ideal interface.
- bluelightning2k 1y agoInterestingly I think I would over-think this. The interviewer is assuming a single server, running in a VPS type environment. There's also no notion of state persistence/timeout/recovery etc. I think I'd immediately have started factoring those things in. ALSO while JavaScript is a single threaded environment, the while solution would still basically work due to the scheduler (at least if you yield, await sleep, etc.)
- jnettome 1y agothanks for sharing and by reading the blogpost and the comments I think I get the whole point: it's all about how engineers understand the requests and the reasoning about how does it approach that more than the code itself. If this raw code really works or not it's almost secondary here - IMHO nobody I'll start coding a real queue out of blue like this.
- deleted 1y ago[deleted]
- 4ndrewl 1y agoDefinitely one of those where the interviewer wants to show how smart they are.
- IdontKnowRust 1y agoOh I see what you're doing here...this is just an interview to massage the interviewer's ego. It must be so boring working you
- fastball 1y agoHow does this interview question massage the interviewer's ego?
- thedude14 1y agoAs a self promoting post I think the author did a good job. As an interview format, I would rather work somewhere less ego driven development and more real problem oriented workplace. But that is just me. Someone could prefer these kind of interviews. I also did a set of questions for java engineers in the past and I always felt there is something really icky. I also noticed the engineers with huge ego revel in these kind of candidate assessments as it makes the feel good, but the candidate performance is poorly tested. Thats what the probation period is for. Just ask the candidate whats his experience. Asking these "cleverly" designed problems is nice for the interviever importance of keeping his job, but is not really usefull. You could even miss a good engineer. Perhaps i see this too narrow and you just really want to observe what the candidate is thinking, but you could make a couple of not really complicated questions and you could see where he is at. I dont bite this head-game at all.
- lubujackson 1y agoI agree to a point. For me, what chaffs is the convulted prompt that goes against all my instincts for how to design something simply and clearly. "Ok, but if you had to code something convulted and illogical..." I tend to have trouble with these sorts of black box problems not because of the challenge but because of going down the path feels wrong I would expect my day to day at the company would be surrounded by too clever solutions. Also, recognize a minimum requirement to solve this under interview pressure is a lot of low-level futzing with Javascript async and timeout details. Not everyone comes in with that knowledge or experience, and it's fine if that is a hard requirement but it seems ancillary to the goal of "interviewing engineers". I can't imagine anyone solving this or even knowing how to prompt AI in the right ways without a fair bit of prior knowledge.
- GeoAtreides 1y ago> and more real problem oriented workplace I literally had to implement this exact queue mechanism because of a 3rd party integration with an uncooperative server it's a pretty real problem
- dawnerd 1y ago
- lordnacho 1y agoThe explanation is way too long, in an area that is pretty big and can be done in many ways. Couple this with candidates who will variously be fearful of asking to many or too few questions, and you just have confusion about who is good and who is not.
- nothrabannosir 1y agofor the record (and disregarding how appropriate this is as an interview question): in JS you can (ab)use the event loop and promise chains to do this for you without managing any queues or lists manually. You have a single `let job = Promise.success();` as a global var, and scheduling a new job becomes `job = job.then(f, errHandler).then(callback, errHandler)`. It's a nightmare to debug (because you can't "see" the in-process queue) but it means you don't have to muck around with manual lists, queues, loops, shift/unshift, "isProcessing" flags etc, all of which is basically you reimplementing that native functionality in user space. It completely sidesteps the bug of TFAs naive implementation. Not advocating for this in prod but in the context of a programming puzzle it can be neat. late edit: ironically this is also a comment on the LLM talk in TFA: messing with the event loop like this can give you a strong mental model of JS semantics. Using LLMs I would just have accepted a loop and never learned about promise chains. This is the risk in using LLMs: you plateau. If you will allow a tortured metaphor: my naive understanding of SR is that you always move at light speed, but in 4 dimensions, so the faster you move in the 3D world, the slower you move through time, and vice versa. Skill is similar: your skill vector is always a fixed size (= "talent"?). If you use LLMs, it's basically flat: complete tasks fast but learn nothing. Without them, you move diagonally upwards: always improving, but slower in the "task completion" plane. Are you ready to plateau?
- deleted 1y ago[deleted]
- odo1242 1y agoHonestly that’s not even an abuse of the event loop / Promises. Making a queue like this is literally one of the intended uses of Promises.
- bmacho 1y agoIf you don't care about the order of requests then you can just set up a flag to denote if a task is running, and keep rescheduling the other tasks. Something like let isProcessing = false; async function checkFlagAndRun(task) { if (isProcessing) { return setTimeout(() => checkFlagAndRun(task), 0); } isProcessing = true; await task(); isProcessing = false; } should do the trick. You can test it with function delayedLog(message, delay) { return new Promise(resolve => { setTimeout(() => { console.log(message); resolve(); }, delay); }); } function test(name,num) { for (let i = 1; i <= num; i++) { const delay = Math.floor(Math.random() * 1000 + 1); checkFlagAndRun(() => delayedLog(`${name}-${i} waited ${delay} ms`, delay)); } } test('t1',20); test('t2',20); test('t3',20); BTW, for 4 scheduled tasks, it basically always keeps the order, and I am not sure why. Even if the first task always runs first, the rest 3 should race each other. 5 simultaneously scheduled tasks ruins the order.
- brettgriffin 1y agoI'm not going to dive into the specifics of my thoughts on this question. I think a lot of comments here address this. But does anyone else get embarrassed of their career choice when you read things like this? I've loved software since I was a kid, but as I get older, and my friends' careers develop in private equity, medicine, law, {basically anything else}, I can tell a distinct difference between their field and mine. Like, there's no way a grown adult in another field evaluates another grown adult in the equivalent mechanism of what we see here. I know this as a fact. I just saw a comment last week of a guy who proudly serves millions of webpages off a CSV-powered database, citing only reasons that were also covered by literally any other database. It just doesn't feel like this is right.
- brunooliv 1y agoAgreed, this is just terrible for the field as a whole it’s like we’re regressing or something
- joquarky 1y agoWhen I started writing code for a living 30 years ago, we were mostly left alone to solve problems. Now it feels like I'm back in high school, including strict irrelevant rules to be followed, people constantly checking in on you, and especially all of the petty drama and popularity contests.
- esafak 1y agoWhich part, the fact that you have to answer such questions to get a job? Those other fields are more established and have formal barriers to entry.
- ThrowawayR2 1y agoLawyers have law school after a degree, a bar exam, legal liability for malpractice, and ongoing licensing requirements. Medicine has medical school after a degree, a 5+ year residency under close supervision with significant failure rates, legal liability for malpractice, and ongoing licensing requirements. So explain to us what it is that you "know this for a fact" regarding how they have it easier. Most of the people reading this, myself included, would never have been allowed into this industry, let alone been allowed to stay in it, if the bar were as high as law or medicine.
- rubyn00bie 1y agoI’m really confused why this is an “async queue.” Seems pretty synchronous to me since requests are completed in order, one at a time. I literally wrote something to do this in the past few months. This was to work around JavaScript’s asynchronous IO making a shit show of updates from library being used in the client. I had to queue requests in JavaScript, have them execute in order (FIFO), and explicitly described it “synchronous.” Is it only “async” because it’s doing it in JavaScript and the underlying network request API is asynchronous? Seems like, IMHO, a really bad way to describe the desired result since all IO in JavaScript is going to be async by default.
- 8note 1y agothe async part isnt very exciting, but its the callback after the entry has been through the queue and worked on. its certainly serialized, but nothing fancy otherwise. it would be synchronous if you blocked the requester until the request go through the queue and then completed. you wouldnt need to introduce an async/await. you can see examples in JS on the node FS functions. the defualt ones are async, but they have some magic wrappers that make it actually sychronous and block the event loop from running until the file is loaded
- deleted 1y ago[deleted]
- dakiol 1y agoI don’t know anything about the author, so just speculating here: assuming that the interview lasts 1h, it’s not realistic (nor fair) to judge the candidate’s answer if the interviewer has spent more than 1h to think about the problem and potential solution(s). Interviewers have thought about the problem they propose countless of times (at least once per interview they have hold) each time refines their understanding of the problem, and so they become god of their tiny realm. Candidates have less than one hour, add to that stress and a single shot to get it more or less right. You’re not assessing candidate’s ability to code nor their ability to handle new requirements as they come.
- fastball 1y agoSo do you want to give candidates infinite time (which they won't have on-the-job) or not attempt to assess their coding ability or what?
- saagarjha 1y agoI spend more time than my interviewees on the question to try to solve the problem every way that it is possible to solve it. If a candidate picks any of the solutions they pass. If they pick a solution I didn't know of they also pass (with flying colors) but I fail.
- dakiol 1y agoHere’s an idea for fair interviews: Interviewer and candidate meet at time X for 1h session of “live coding”. A saas throws at them both one problem at random. Let the game begin. The company can decide if they want interviewer and candidate to collaborate together to solve the problem (the saas is the judge) or perhaps they both need to play against each other and see who gets the optimal solution. You can add a twist (faangs most likely): if the candidate submits a “better” answer than the interviewer’s , candidate takes over their job. An LLM could be very well behind the saas. Oh boy, I wouldn’t feel that nervous anymore in any interview. Fairness is the trick. One feels so underpowered when you know that the interviewer knows every detail about the proposed problem. But when both have no idea about the problem? That’s levelling the field!
- billforsternz 1y ago> if the candidate submits a “better” answer than the interviewer’s , candidate takes over their job Corporate life meets the squid games (I quite like it:)
- glitchc 1y agoWhy would anyone agree to participate in interviews then? Do we then force developers to conduct interviews? If so, which ones? The superstars or the ones on PIP? You can see where this is going..
- tengbretson 1y agoI guess think of it as a promotion/relegation league system, except you get relegated to the "unemployeed" league.
- yoz-y 1y agoMight be a whoosh, but really don’t understand the idea of seeing the interviewer as an adversary. Stress in interviews comes from many places but honestly one of the roles of the interviewer is to bring it down.
- 1y ago
- koakuma-chan 1y agoIn another thread I asked if leetcode style questions are still common, and the answer I got was yes, so where would I encounter this kind of question? I only ever got leetcode style questions or something like "what is the difference between var and let"
- relativeadv 1y ago> "This is a good way to test how "AI-native" the candidate is." yuck
- ww520 1y agoIf I were asked this question, the first thing I said would be this is a poorly designed architecture. Client is the poor place to do throttling by itself. It has no information on the aggregated load of the system. It makes assumption that leads to complicate code in the sample code. There're more robust and better ways to do flow control and throttling.
- 8note 1y agothe intro isnt throttling, its request serialization. there isnt some limit to keep your requests to, just that its one at a time. it could go as fast or as slow as the individual requests finish. its still not a great architecture, but its different from throttling
- ww520 1y ago> But that server is faulty!! If it has to handle multiple requests at once, it starts to break down. So, we decide to make our server's life easier by trying to ensure, from the client, that it doesn't ever have to handle more than one request at once
- deleted 1y ago[deleted]
- wonnage 1y agoThe minDelay extension feels contrived and also the solution sucks. None of the pending requests are actually added to the queue until the timeout is finished, meaning you have no knowledge of all these delayed requests until the timeout passes and they all enqueue themselves
- evil-olive 1y agoechoing the other comments about this being a rather terrible interview question... > this interview can be given in JavaScript or any other language it's a language-agnostic question...but it revolves around the assumption of making a callback on request completion. which is common in JS, but if you were solving this in some other language, that's usually not idiomatic at all. followed by: > For candidates without JavaScript experience or doing this interview in pseudo-code, you have to tell them that there's another function available to them now with the following signature: > declare function setTimeout(callback: () => void, delayMs: number): number; so you add in this curveball of delaying requests (it's unclear why?), and it's trivial to solve...using a function from the JS stdlib. and if the candidate is not using JS, you need to tell them "oh there's a function from JS that you can assume is available" > After sendOnce is implemented, it's time to make the interview a lot more interesting. This is where you can start to distinguish less skilled software engineers from more skilled software engineers. You can do this by adding a bunch of new requirements to the problem as you originally specified it, this code is a workaround for a buggy server. and for Contrived Interview Reasons we can't modify the server at all, only the client. in that scenario, "extend it into a generic queue with a bunch of bells and whistles" is maybe the worst design decision you could pursue? this thing, if it existed in the real world, should be named something like SingleRequestQueueForWorkingAroundHopelesslyBuggyServer with comments explaining the backstory for why it needs to exist. working around the hopelessly buggy server should be roped off into one small corner of the codebase, and not allowed to infect other code that makes normal requests to non-buggy servers.
- resonious 1y agoI dunno about you, but I spend a good amount of time writing my way around buggy servers that I can't change. It seems pretty realistic to me.
- rustystump 1y agoI think we all have but that doesn't change that this is almost exclusively a js specific interview question with a very js'y solution to the point of hammering in a imagined "js land" api. I am not against testing deeper language understanding for a job that requires it but the layers of contrivances to make it "not only js" rightfully rubs non-js devs the wrong way. This comes from someone who loves them some js. The AI ick at the end makes what would have been mildly interesting, incoherent and uninteresting.
- didip 1y agoThe use-case described is ill suited to be addressed by the client. Which make the whole coding exercise moot. What if there are 1 million users opening the browser at the same time? The queue question is fun but doing it in the client is not right.
- resonious 1y agoThis might be a server interacting with another server.
- fastball 1y agoThis is addressed in the article. > So, we decide to make our server's life easier by trying to ensure, from the client, that it doesn't ever have to handle more than one request at once (at least from the same client, so we can assume this is a single-server per-client type of architecture).
- cdrini 1y agoYeah I think the premise is a bit poorly designed, I would just wave it away and focus on the queue. The coding problem itself is pretty well defined. And I think the premise is intentionally presented kind of poorly defined, which makes me think it's meant to not really be part of the problem.
- neallindsay 1y agoPromises in JS make this stuff much easier (at least to my mind): const lockify = f => { let lock = Promise.resolve() return (...args) => { const result = lock.then(() => f(...args)) lock = result.catch(() => {}) return result.then(v => v) } }
- fastball 1y agoEasier to write. But there is a case to be made that code which can be understood without understanding somewhat esoteric language internals is superior.
- yeasku 1y agoIs code wrote for a broken server. It makes no sense even with common js idiom.
- fastball 1y agoOk, but that's not relevant to my point. Plus, in real life you do need to interact with broken servers – that doesn't mean you should make your code less readable as well.
- neallindsay 1y agoI guess "esoteric" is in the eye of the beholder, but Promises seem a lot easier than the old callback style we used to use for asynchronous operations.
- jtchang 1y agoIs the send function considered non-blocking?
- isbvhodnvemrwvn 1y agoWhy would it have a completion callback if it wasn't?
- _benton 1y agoYou can also schedule code to run each "tick" of the event loop, which is a non-blocking version of a while loop. Or you could promisify the send function and use normal async/await. let q = Promise.resolve(), sendAsync = (p) => new Promise(r => send(p, r)), sendOnce = (p, c, ms) => setTimeout(_ => q.then(_ => sendAsync(p)).then(c), ms) Or you could actually spin up a new worker thread and get multithreading :P
- charleslmunger 1y agoI've implemented multiple production versions of this problem (but not in JavaScript)[1], so maybe my view of this problem is miscalibrated... This feels both too easy and too hard for an interview? I would expect almost any new grad to be able to implement this in the language of their choice. Adding delays makes it less trivial, except that the answer is... Just use the function provided by the language. That's the right answer for real code, but what are you really assessing by asking it? [1] https://github.com/google/guava/blob/master/guava/src/com/google/common/util/concurrent/ExecutionSequencer.java https://github.com/google/guava/blob/master/guava/src/com/go...
- fastball 1y agoYou explained how it is too easy, so how is it also too hard?
- charleslmunger 1y agoIt's too hard because the variations you could add to it (multi threading) that add enough depth to make it hard make it too hard, in my opinion. If you look at the implementation I linked in my previous comment, it's fully lock-free, which is pretty unreasonable to expect from anyone who isn't already familiar with lock free concurrency. On the other hand the version with a lock is basically identical to the single thread version. Asking for the two-lock queue is also a bad interview question because it's not something you'd reasonably expect someone to derive in an interview. The other examples given for fleshing it out are all pretty similar; if a candidate can do one, chances are they can do the others too. If you want to get a decent signal if candidate skill, you have to ask a question easy enough that any candidate you'd accept can answer it, then incrementally add difficulty until you've given the candidate a chance to show off the limit of their abilities (at least as applied to your question). Otherwise you ask a too-easy question which everyone nails, then make it way too hard and everyone fails. Or you ask a too-easy question and follow it up with additional enhancements that don't actually add much difficulty, and again all the candidates look similar. That's just my experience; the author seems pleased with the question so maybe they're getting good signal out of it.
- kazinator 1y agoI did this in the firmware of a VoIP base station. I was informed by the radio firmware guys that a certain kind of request from the host could not be handled concurrently by the radio module due to an unchecked conflict over some global piece of memory or whatever. I create a wait-free circular buffer for serializing the requests of that type, where the replies from the previous request would kick down the next one. No mutexes, only atomic compare-swap.
- charleslmunger 1y agoHow did you make it wait free with only compare and swap?
- IgorPartola 1y agoIt’s funny because I have had ti implement “serialized fetch()” a few times recently, with delays and random jitter too. I think this question is a bit confusing in its wording even though the concept is actually quite useful in practice. First, async queues have nothing to do with network coms. You can have a async queues for local tasks. Also while it is obvious to most that you shouldn’t do this, you can also satisfy the requirements to this task by polling the queue and flag using setTimeout() or setInterval(): on invocation, check if there is anything in the queue and if so, if we aren’t waiting on a response fire off the next send(). Retry logic with this system is always a problem. Do you block the queue forever by retrying a request that will never complete (which lets the queue grow infinite in size), or do you give up after some number of retired? If you give up, does that invalidate all queued requests? Some? None? This becomes application-specific. For this kind of thing I have implemented it using multiple parallel queues. That is, you request a send() but using a specifically named queue so that if one queue’s serialized requests break, other queues aren’t affected. If you do something like `sendOnce(payloadA, callbackA, 5000); sendOnce(payloadB, callbackB, 1);` should payloadB be sent in 1ms or 5000 + RTT + 1ms? You could solve this in the JavaScript environment by using something like WebSockets or WebTransport much more trivially than by using send() which is I assume a thinly veiled fetch(). This probably fails OP’s interview but in reality leverages the lower level queueing/buffering. A more fun and likely more illuminating question would be to do something like provide a version of send() that uses a callback for the response and ask to convert it to a promise. This is a really fun one that I had to deal with when using WebCodecs: a video decoder uses callbacks to give you frames but for example Safari has a bug where it will return frames that are encoded as delta frames out of presentation order. So the much better API is to feed a bunch of demuxed encoded chunks to a wrapper around VideoDecoder, and then wait for the resolution (or rejection) of a promise where the result is all the decoded frames at once. This problem really gets at the concept of callbacks vs promises which I think is the right level of abstraction for evaluating how someone thinks of single threaded concurrency. You also can get a really good feel for a person’s attitude here if they refuse to use callbacks or promises (or the async/await sugar around promises).
- bvrmn 1y agoI don't understand what's tricky about converting callback-style to promise-style. Even writing a decorator is trivial.
- nmca 1y agoWhy is the method called sendOnce? It’s send with a capacity limiter / semaphore right, so what about it is Once?
- saagarjha 1y agoI think it really ought to be called "sendOneAtATime" but I assume the author just picked a bad name for it.
- mgradowski 1y agoI'm really confused because I had to scroll half the comment section for the word `semaphore`. This seems to be an interview question about JS esoterica, not concurrent programming.
- ayaros 1y agoI made use of this in my LisaGUI project; I referenced an absolutely fantastic example on this on SO: https://stackoverflow.com/a/63208885 https://stackoverflow.com/a/63208885
- joquarky 1y agoI'd just have them play Factorio and watch how they reason.
- ykonstant 1y agoUh oh, I am horrible at Factorio \(〇_o)/ But I am a mathematician, I wonder if that makes things better or worse... (•ิ_•ิ)?
- SAI_Peregrinus 1y agoI've seen somewhat similar things in embedded development, e.g. ADCs with a triggered conversion mode that start a new conversion on receipt of a new trigger, abandoning a previous conversion if one was in progress. They fire an interrupt when the conversion completes. Not in any way buggy or unexpected, ICs generally either can block or can immediately respond but can't queue multiple requests. Of course on the embedded side you're likely using C, quite likely an RTOS and thus threads, but if you're just using a superloop then you've got a single-threaded system (though with the complication of interrupt handlers) a bit like the interview asks about. I'd probably use a state machine for this with a superloop design, just about everything "async" in embedded boils down to writing a state machine & polling it. Actually writing a fully general-purpose async queue for embedded systems is rather more work, because you'll have to consider how it can be used from within the interrupt context. You really shouldn't block in an interrupt context, so all the queue operations need to be non-blocking. That turns it into something far too complex for an interview question.
- robertlagrant 1y ago> (a lot of people resort to some type of blocking sleep style function call to solve the delay part of this problem) In many async languages you can do an async sleep (e.g. Python's asyncio.sleep()) which is a sleep that uses the event loop. Really, that's all Javascript's setTimeout() is doing anyway; it's just named differently.
- andrewstuart 1y ago“Can you work out the tricks that require this previous experience? If you can then you’re smart if not then you’re worthless.” Just say no thanks and walk out if this is their core way to assess your capabilities.
- xg15 1y ago> The bug in this implementation is that if sendOnce is called consecutively and the previous request hasn't finished yet, then we violate the "one request at a time" requirement. Maybe I haven't had enough coffee yet, but the "naive" implementation looks like it wouldn't use the queue at all, regardless how quickly or slowly you fire off the requests. The code is literally if (requestQueue.length === 0) { ... } else { requestQueue.push(...) } with no other push() anywhere else. So how would the queue ever get nonempty in the first place?
- pavlov 1y agoThis interview starts off with the interviewer saying it's going to be in JavaScript, and then introducing a piece of code that's clearly not JavaScript: declare function send<P>( payload: P, callback: () => void ): void; Doesn't inspire confidence in the interviewer's level of preparation.
- ipnon 1y agoAs long as the candidate feels confused and the interviewer feels brilliant then all is well in the world.
- diesal11 1y agoEh, the implementation is all Javascript and can be approached in any language. They're just providing function signatures with types so the candidate knows what they're working with. Also the signatures are Typescript, which really isn't that far off in the context of an interview. Even in a pure JS codebase it's not uncommon for IDEs to pull the TS definitions of packages to provide basic type checking. But even pure JS libraries will normally provide typed signatures in their documentation. If anything I'd say this shows that the interviewer is prepared, by ensuring the candidate has what they need to complete the question.
- saagarjha 1y ago> or any other language (even just pseudo-code)
- jwmoz 1y agoThis is a complete nonsense. OP has invented a tricky technical test for themselves which they have spent long amounts of time thinking about. In an interview a candidate is not in that mindset, at least I am not. Under stress and anxiety it is very difficult to fully understand things and build good cognitive structures in the mind.
- dzonga 1y ago[dead]
- bborud 1y agoIf I were interviewed by someone presenting me with this task, I would spend a bit of time helping the interviewer clean up the problem and try to get to where they can explain what they want with just words. Clearly. I’m not sure we’d necessarily get to the part where any kind of solution is proposed, but it would give me a lot of information about what kind of developer culture to expect at this company. Just by how the problem is presented, I probably wouldn’t want to work for this company. Imagine having to work on real problems with people who demonstrate such poor problem formulation skills.
- saagarjha 1y agoHe gave you a function, its signature, and its context in the codebase. I don't really know what you are looking for to make it clearer.
- bborud 1y agoI've conducted a fair number of interviews. At least one of the problems I pose to candidates are to test if they will ask questions that clarifies what I am asking for. Because being able to articulate both what you want to accomplish and what the non-negotiable constraints are, is a key skill. The more senior you are, the higher this part of the interview gets weighted. This is also how a candidate can get to know the interviewer and possibly the company he is interviewing at. What does the interviewer say when you start picking apart what they are actually asking about. The way this problem is posed has two main issues. The first is that it is unclear what the interviewer actually wants. The second is that the problem to be solved isn't well defined. This is later confirmed when we read the blog posting and it is revealed that rather than designing a solution to a problem, the interviewer expects the candidate to hack their way to a solution. Not to recognize what you are trying to accomplish and reason about how to solve such problems, but just peck at the problem. Mess with the code. To make matters worse, it would appear that the interviewer is approaching the problem in a dubious manner -- solving a server problem by depending on the clients to cooperate. That should make you suspicious. It gets further confused by adding poorly motivated extensions to the problem while misusing nomenclature. It appears he is asking for how to solve a difficult problem in messaging systems, but he isn't. He is asking for convenient ways to implement something much simpler. Which even makes me question if he would have recognized someone smarter than him misunderstanding and solving a harder problem -- someone who is capable of solving the kind of problems his use of nomenclature hints at, but apparently wasn't after. Now, think about your reaction to this problem formulation from my perspective. From the perspective of someone who wants to hire senior developers. When I hire people I need people who can solve problems. Lacking that, I need someone I can train to solve problems. I have no need for people who dig themselves out of holes brute force. This is why some portion of my interview questions will only work if the candidate asks questions. Some of these interview questions are really easy to solve from a technical/algorithmic point of view, but only if you can identify the underlying problem. If I had presented the problem as stated to a candidate and they did what the interviewer seemed to want, I'd probably have added them to the reject pile for lack of ability to take a step back and point out that this is a bit silly.
- saagarjha 1y agoPosting interview questions on Hacker News is so funny. Regardless of what the question is half the people will tell you that it's an interviewer ego trip that has no relevance to the real world while the other half will explain how interviews are actually a total waste of time and how carpenters do it right (obviously, without actually consulting how carpenters do their interviews). If the question has anything in it that's not an array then it's called "Leetcode" and clearly FAANG-engineer biased. If it has any other form then it's too confusing and too contrived. Of course, the end result of this discussion is that the author is a horrible employee at a horrible workplace and nobody should ever want to work with them. Thank god that 'randomuser123 was able to figure out that they were telling on themselves and explaining that if they were in this interview they'd stand up and tell the interviewer how their entire architecture was wrong and they should be ashamed for even asking the question instead of changing the world around them. And then everyone claps.
- davidgomes 1y agoPhenomenal comment, thank you for writing it, made my day :)
- gloosx 1y agoThe proper implementation looks kinda bulky to me. Are you not allowed to use promises? Feels more like a naive solution for anyone who has few months of experience with javascript or is it cheating? const PromiseQueue = { queue: Promise.resolve(true), sendOnce(request) { return new Promise((resolve, reject) => { this.queue = this.queue .then(request) .then(resolve) .catch(reject) }) } }
- a-priori 1y agoYou'll need to flatten the promise periodically if you use this approach, otherwise your performance will degrade a bit each time you enqueue something.
- mohsen1 1y agoNeat! and minimum delay can be done with Promise.race
- mind-blight 1y agoI actually tried to use this pattern to make an audio controller interface much nicer. If you get a long enough queue, you'll start to run into errors (I'm forgetting the exact message, but it was similar to a maximum recursion depth)
- gloosx 1y agoThis most likely happened because you had a queue operation which started another queue operation so a recursion was created which consumed every bit of memory it had available.
- damidekronik 1y agoAnd then once The Anyone gets few more years of experience they revert back to the bulky one.
- gloosx 1y agoDunno, every queue in every major library/project I saw is implemented like this. This is quite readable if you're familiar with js promises.
- stevrdjhon 1y ago[dead]
- octo888 1y agoAs a general comment, I wish hiring managers found some other outlets for their enormous ego and insecurities than the process of hiring of software engineers. I understand their argument that they have 1,000,000,000 applicants for every job so it's absolutely totally super required to be like. But companies still paying 2019 wages and are CRUD shops really need to bring it down a notch. You're getting a billion applicants because people are desperate and there are tons of CS grads, not because you're the greatest company on earth
- ctvo 1y ago> You're getting a billion applicants because people are desperate and there are tons of CS grads, not because you're the greatest company on earth How does this change the point? They would still like the best candidate out of that pool, not any warm body, since they have limited positions. What is your approach to hiring and evaluating talent knowing the large number of applicants and how easy it is to _talk about software development_ vs. _actually developing software_, and how expensive and difficult it is to deal with a bad hire, even in America.
- deleted 1y ago[deleted]
- stevepotter 1y agoWhen I interview a candidate, I focus primarily on what they've done. Ideally they'd have a body of work online that I can view beforehand. Then I go through a high level system design and have a collaborative conversation. Last, I give a pretty straightforward coding question, whose purpose is only to make sure they aren't full of shit, which often they are. The mistake I see interviewers make is that they are looking for the candidate to solve some kind of puzzle, and the focus is kept on whether they had that "ah-ha" moment vs a clean implementation. Maybe this would be a good approach for a job that required defusing a bomb, but this is relaxed desk work haha. I once had someone bomb the coding, then email me a few hours after with a clean answer. One of the best hires I ever had.
- kinow 1y agoI follow the dame process. I explain beforehand what kind of questions will be asked, and emphasize there are no tricky questions, that we are just curious about their experience, area of interest, preferences for designing ode, how they tackle ode quality and user support, etc. Haven't had any major issues hiring this way, but I did reject people that appeared to be full-of as your said, or didn't have anything public on github/company gitlab/dockerhub/researchgate/etc.. With exceptions for entry level positions and a few that worked in research or govt where work couldn't be made public (they still normally have some participation in research publications, conferences, technotes, etc.)
- quibono 1y ago> didn't have anything public on github/company gitlab/dockerhub/researchgate/ What if the company GitLab/DockerHub instance is restricted and you can't get code samples (I think this is very common)? Or a different example: I have a few public repositories on GitHub but most of them are private - it seems like that's something you'd perceive negatively?
- FirmwareBurner 1y agoI guess they just don't want to hire/interview workers who don't have public work. Maybe they pay very well and can be selective with their candidates, especially in this market. Or they live in some SV bubble where every workers has public work so it's the norm where they live. Where I live in Europe 90%+ of workers barring those currently in academia, have no public work because most companies don't publish their work, so you'd never hire anyone with that barrier.
- donatj 1y agoOne of the best interview questions I ever received, I was asked to explain how something I liked worked in detail. Could be literally anything, just break it down step by step. I was told I could use the whiteboard but didn't have to. I broke down a project I was particularly proud of drawing charts explaining internals. It was clearly both a test of communication and reasoning skills, but it was frankly kind of fun to answer and put me at ease.
- kinow 1y agoAfter some years applying for different positions, I started asking receuiters about their hiring process and straight out dropping out when there were technical tests like this. Even when you nail the test, it is no guarantee you won't be just wasting your time. I explain to the recruiter why I am turning down that opportunity and thank them. Best jobs I had were mainly via my network of friends, or reaching out to engineers directly asking about their companies and open positions, then sharing CV and GitHub, then chatting about technologies used, bugs in production, and other past experiences.
- MichaelRo 1y agoWell, I had an interview recently where I passed with flying honors the technical interview but they failed me at "cultural fit", which was strangely, the last one in the series. Now I must say that I got the vibe from the start they weren't interested in hiring me as much as extracting proprietary quant / trading information from me, but I played along since I was also interested in their culture. So at the final interview, I get a series of questions that basically The Senate asked Cosa Nostra in https://en.wikipedia.org/wiki/United_States_Senate_Special_Committee_to_Investigate_Crime_in_Interstate_Commerce https://en.wikipedia.org/wiki/United_States_Senate_Special_C... And foolish me, maybe, instead of taking the 5th Amendment "I respectfully decline to answer on the grounds that my answer may tend to incriminate me", I foolishly (did I say that again), gave a straight answer. From that on it was only downfall. Watch this movie, it's insightful: https://www.youtube.com/watch?v=TXdC293horg https://www.youtube.com/watch?v=TXdC293horg When you interview, remember, HR and hiring manager are fucking pigs. Anything you say can and will be used against you. So when they ask you of a situation of what you didn't like about your colleagues, you invoke Amendment 5: "I never had a situation where I didn't like my colleagues". When they ask you about how you handled a missed deadline you answer: "I never missed a deadline". And so on. They won't hire you probably any way. No point giving them pigs material to use against you.
- time0ut 1y agoThis is not the worst interview question I have seen, but it sure could use some improvement. The naming of things is pretty confusing. Async queue, send once, and send many all threw me off and aren't good descriptions for what we are trying to do. I hope this isn't reflective of the company's actual code base. A bit of a red flag. It also is framed as not a JS question but then the interviewer wants an answer that only makes sense in JS. It also isn't even modern JS. A couple more red flags there. I dislike questions like this in general, but I've done interviews where they facilitated a decent conversation. It really depends. It is also just a blog post so hard to infer a lot about the author's actual interview style. Maybe it is great and collaborative. It does remind me of some of the worst engineers I have ever worked with and their interview style though...
- jwrallie 1y agoI think also trying to work around a faulty server with client code is a bit weird, I could see it happening in practice but my first instinct given this interview would be to insist the server should receive some attention first, or if it is impossible at least this queue should be implemented by another process or machine near the server side. I agree this could work if framed as a coworker rubber ducking his problems to you and asking for ideas to get to a solution, because it could clear up the naming issues and focus on the candidate solving problem skills without the pressure about giving the one right answer to the problem.
- tekkk 1y agoHeh heh. I dont understand what the fuss is about, AsyncQueue is kinda cool in JS. I use it, from time to time, to implement async generators that can be iterated over with for await. Although my implementation doesnt have any sequencing as never had need for it but, more importantly, it has retrying and timeouts. Well retrying I might have implemented on level higher. Maybe I'm just one of the rare few who actually would have enjoyed this type of question as a chance to brag about my version. Kinda neat as I've never been interested in programming challenges to, for once, know exactly the solution.
- tekkk 1y agoWhile I'm at it, here's my version, if people want to see and give feedback: export interface AsyncQueueOptions { timeoutSeconds?: number } export class AsyncQueue<T> { private readonly queue: Promise<T | undefined>[] = [] readonly timeoutSeconds: number private timeout: ReturnType<typeof setTimeout> | undefined private reject = () => {} private resolve = (value: T | PromiseLike<T>) => {} /** * @param timeoutSeconds @default 25 */ constructor({ timeoutSeconds = 25 }: AsyncQueueOptions = {}) { this.timeoutSeconds = timeoutSeconds if (timeoutSeconds > 100) { console.warn(`You are initializing AsyncQueue with over 100s timeout: ${timeoutSeconds}`) } this.queue.push( new Promise<T | undefined>((resolve, reject) => { this.resolve = resolve this.reject = reject this.timeout = setTimeout(() => resolve(undefined), timeoutSeconds * 1000) }) ) } next(): Promise<T | undefined> | undefined { return this.queue.shift() } push(msg: T) { this.resolve(msg) this.queue.push( new Promise<T | undefined>((resolve, reject) => { this.resolve = resolve this.reject = reject clearTimeout(this.timeout) this.timeout = setTimeout(() => resolve(undefined), this.timeoutSeconds * 1000) }) ) } close(msg?: T) { if (msg) { this.resolve(msg) } clearTimeout(this.timeout) } }
- delegate 1y ago"But that server is faulty!! If it has to handle multiple requests at once, it starts to break down." Ok. I know this is all hypothetical. But I don't buy this premise. Why is the server faulty ? In what way does it fail ? How do you know it's because it's processing more than one request at a time ? What if there are multiple clients each doing one request only ? Do you have control over the server code ? If so, fix it there! --- The point is, this solution is fixing the wrong problem and introducing a new one down the line. If the bug on the server gets fixed, you've now implemented an artificial performance bottleneck on the client. Devs who know about it are going to leave the org, others are going to try to 'optimize' the code around it with other hacks, since by allowing these kinds of fixes you're building to the wrong kind of culture. Always fix the root issue. Or change the premise of the problem.
- dekhn 1y agoIn the interview, am I allowed to fix the server (which apparently "breaks down handling concurrent requests") instead of working on this silly programming exercise? What about proxy solutions? IE, proxies that take concurrent requests and serialize them? The question mainly seems to be working around framework limitations and broken externalities, and the interviewing is providing a signal ("you do not want to work here")
- 12_throw_away 1y agoI would respectfully suggest that this entire approach creates a pathological distributed system, where the client is trying to internally keep track of the state of a server, but without any of the supervision tools would need to do so reliably. (And, as a bonus, it's doing this with a callback hell) What happens if either one restarts/crashes? What happens if you accidentally launch 2 clients?
- rehevkor5 1y agoTheir "proper implementation" lacks sufficient error/exception handling around the callback() call. It'll become permanently broken if it throws anything.
- tk90 1y ago> Can they read code and debug it in their head? > Strong engineers, however, can break out the two problems and solve them at the same time. Disagree so much with this. A "good" engineer breaks a problem down, solves them one by one, and avoids mentally juggling multiple things at once if possible.
- bravesoul2 1y agoIt's a great question if you want a Node.js developer. But what if they come from a Go or Java background. You shouldn't have a favourite question. You need interview questions that create good information signals efficiently. You want the candidate to show off. If they are not strong on async then give them a threading question or something else.
- shallmn 1y agoI have worked in software development for over 35 years. In that time I have found that the most proficient teams are based on having smart people working in teams that get along well. We’d probably call that emotional safety today, but previously, we just said that everyone worked well together. I don’t know what jobs require interviewing for such a specific response, maybe I’ve never needed that skill set on my team. Intelligent, small ego, team players have been the best teams I have worked with, and I’ll continue to hire based on my gut for those individuals.
- ozgrakkurt 1y agoThis is not really correct, what happens if the server receives a request and starts processing it but couldn’t send ack response? In this sense what use is the “proper” implementation in the blog? In general interview programming questions really feel useless, especially if you consider candidates will be optimising for solving interview questions instead of being good at doing their job