I did and a technical interview while down with the flu and it cost me a job offer.
It was the final stage of the hiring process: the technical interview. Before this, I received a take-home coding task (it was easy, fetch data from an API, then sort and order it), and many questions were about the code in my solution. "This should be easy, right? I wrote this code. So what if I'm a bit ill," I thought. Wrong, when you're ill, you get penalties to your stats. In my case, INT saves always take a -2 penalty, even if it's "just a cold." My thinking is slowed and sluggish, and I miss incredibly obvious things and make awfully stupid mistakes (same when I'm tired, I miss obvious things and make silly mistakes then). Like trying to return a <p>
tag inside another <p>
tag because I didn't read the code a line above. The stress of the interview makes this even worse…
I’m currently a lvl 3 frontend dev (2 years of commercial exp + 1 year of learning) and in my current job I do lots of things: I write plenty of small projects in vanilla HTML, CSS (SCSS) and occasionally JavaScript for numerous clients of the company I’m working for, I do quality checks for the work supplied by freelancers (in terms of coding standards and adherence to strict technical requirements), and I write React components for a huge app we’re building. This app is a comprehensive solution for all things e-commerce-related, like inventory management, asset management, web scraper, newsletter, virtual workspaces, and many more. There are coding standards I have to adhere to that I didn’t come up with and had no chance to question (due to constant pressure of tight deadlines and a “work, work, work” mentality). It has a microfrontend architecture that I don’t fully grasp and wouldn’t be able to replicate in my own project (or maybe I would, I never tried, because I’ve never developer such a huge project on my own yet). Despite all that, I still contribute a lot to the project: I write reusable React components, I ensure code quality by participating in code reviews, and when the backend is lagging behind, I use dummy data, then connect them to the frontend once the API is ready. Sometimes it happens that dummy data have a different structure than live data from the API, so I need to correct the types in TypeScript to match those. I introduced a few features from scratch, refactored the code in lots of places, and fixed several bugs, so overall I'm feeling pretty confident in my current role, to the point that I'm trying to level up and get to that “mid” dev position. Also, that's why I didn't think much about revising theory before this interview (also, when sick all you want to do is sleep, not think) or checking my code twice - I wrote it, so I should know the What and the Why. This is what doomed me. Maybe I’m at the peak of mount stupid and this interview put me back in my place (that I know nothing).
When I was studying at the university, I always hated oral exams as they were much more stressful than written ones (for the record: I studied chemistry, so despite being science-oriented, I lack a traditional tech background). I should have treated this interview as an exam and prepared for it, but I didn’t, see the cover image.
The interview started with a simple data structures question: what is a Set? My thinking was so slow and I was so stressed that I was confused and thought the interviewer was asking about a state setter method. I used a Set in my code to extract all the company names that the API was returning to display them (without duplicates) in a company selector filter. So, what is a Set? It’s a built-in JavaScript object that lets you store a collection of values without duplicates. I don’t even remember what I answered. Another question: what is Strict Mode in React and why is it used? Well, Vite uses it as a default, and I used Vite to set up my take-home project. It helps to catch bugs like infinite loops and so on.
While the full answer should be: Strict Mode is used only during development to help you catch some common bugs early, like missing useEffect cleanups (that's why useEffect hooks are always run twice during development), missing ref cleanup (so ref callbacks are also run twice), and it highlights deprecated APIs.
What are keys
in React? Again, I struggled with the answer because I do like to give a proper definition, yet I struggle with properly naming things I’m unsure of. So I went with something along the lines that “keys
are like ids for virtual DOM elements, but not really ids”. React key
is an attribute used to uniquely identify an item, for example while mapping over an array. It should be either a unique string or a number. Ideally keys
should be included in data rather than generated on the fly. They are needed for DOM updates when the array elements change order due to sorting, addition or deletion. They should be unique between siblings, but can be the same for different JSX nodes in two different arrays. Thing is, I add a key
prop automatically when I map over an array - since I learned that it is necessary (or else React throws errors), I never think twice about it, especially at work, where each items in an array comes with a uniqid prop.
What’s the difference between forEach
and map
? That’s another one where I gave a half-good answer. Both are built-in JavaScript methods used to perform actions on each item in an array while iterating over it, but the main difference is that forEach
does not modify the original array, while map
creates a new array, leaving the original unchanged. There’s another example where it’s easy to fall into doing things automatically—I never needed to modify the original items in an array, so I always use map
. Heck, I even get warnings from ESLint in my code when I accidentally use forEach
.
What do I use for debugging? Here my thoughts strayed towards proper debuggers, which I’ve never used because I don’t know how or why. I often use console.log
or browser dev tools, check the browser console for errors, check the Network tab for errors in HTTP requests, and I also always check my terminal for TypeScript errors. I use try… catch…
in my code, and I use a linter, but this wasn’t part of my answer due to impaired comprehension (-2 to INT). Even W3Schools teaches that console.log
is a JS debugging technique. Chrome for developers gives a nice overview of how to use the built-in debugger in the browser, and that’s something I need to learn to descend from the peak of my mount stupid.
What is useEffect
used for in React? It’s used for executing a side effect, which is something that renders a component impure (a pure function is a function that for a given input always returns the same output). A side effect in React is any operation that affects something outside of the component’s scope, such as data fetching, setting a timeout, updating the DOM manually, or interacting with browser storage. Junior devs like me often use useEffect for data fetching (unless they learn how to write their own hooks and/or how to use axios or Tanstack query) without thinking: why? What are we doing here? Fetching data from an API. Why this way, what are the consequences? What is the dependency array and why do we need it? What will happen if we don’t provide it? (The effect will run on every render, which may cause an infinite loop). What will happen if we leave the dependency array empty? (The effect will run only once).
How do you cancel an HTTP request? By using an AbortController, which works with the native fetch()
method. It allows you to cancel a request before it completes. It is helpful for preventing race conditions between requests, avoiding memory leaks, handling rapid user inputs (it cancels old requests when a new one starts), and optimizing performance. It's a really helpful method.
Why did I use TypeScript? Side note: there is a way to answer a question wrong. One of those is by being too honest. What I answered: “Out of habit, and because I wanted to show that I can use it.” (I probably added some more words to my answer, but the gist of it was as quoted above.) Luckily, the interviewer kept drilling with questions like: “Why not JavaScript, how is it better, etc.” There is this ongoing debate among developers, JS vs. TS. Some arguments against TS are that it slows you down (type errors everywhere), that you write more code (and a general rule of thumb is: more code means more bugs), and that it is less flexible than JS. To be honest, I lack the experience in JS to be able to tell whether the less flexibility of TS is a good or a bad thing. My main experience writing JS code is conditional logic or DOM manipulation to show and hide elements, some calculations on dates, comparison sliders (e.g., like here on this project that I recently developed for work), and some fun exercises I did when I was learning JS with FreeCodeCamp (legacy course). I haven’t written a web app in vanilla JS, without using a framework or TypeScript (yet). It may be a good educational exercise to help me appreciate components and strict typing even more. But back to the question: why (how) is TypeScript better than JavaScript? Without going too deep into the whole debate, JS is a loosely typed language. It makes odd type coercions and other strange things. TypeScript prevents that and gives you more control over it. TS allows you to catch errors at compile time, it provides better code documentation (due to types), and it helps catch common errors that stem from undefined
and null
and write checks in the code to handle such cases.
What is the difference between a type and an interface? I tend to use them pretty much interchangeably in my code. As a rule, I use an interface for props in a component and a type for data that interacts with the backend. Both are highly similar. According to TypeScript documentation, almost all features of an interface are available in a type, with the key difference being that an interface is always extendable while a type cannot be reopened to add more properties. So it makes sense to use an interface for a component that may change and get new properties, and a type for data that interacts with an API.
What’s the difference between localStorage and cookies? I had no idea how to answer this one, because I never read about those. All I know is that they exist and that I can save some user settings (e.g. theme) in localStorage. Both are mechanisms to store some data on the client and are networking terms. They differ in amount of data they can hold, the time the data persists, and some other things. Below is a nice tabular overview of the differences:
Do I know any CSS preprocessors (SASS, LESS) and what do they do that CSS cannot? Luckily, SASS is one of the very first things I learned on the job. It is used extensively at my current workplace, and compared with regular CSS, it is awesome. It offers plenty of extra functionality: functions, conditional logic, mixins, partials, and many more. It works well together with CSS frameworks like Bootstrap as it allows generating a class for every variable. Thanks to partials, you can split your style sheets, and it handles nesting differently than CSS. It also works well with BEM naming rules (also thanks to nesting), which allows writing more concise code. I happen to use it daily, and whenever I need to go back to basic CSS, I feel like there’s something missing.
What is WCAG? This is an easy one, though I forgot the full name of the abbreviation. It's the Web Content Accessibility Guidelines, which define a set of rules (or guidelines, but I like to think of them as rules) for creating web pages and apps that are accessible to people with disabilities. For example, to make your website easy to navigate using a keyboard or a screen reader, choose a color scheme with recommended contrast, use semantic HTML tags (as they help with screen reader navigation), always add descriptive alt
attributes to images, include other attributes like labels for form fields, provide visual feedback for focused elements (focus:visible
), and so on. Sometimes it means adding an aria attribute to your HTML elements. The main goal is to make the web friendly and accessible to everyone, not just sighted users with a mouse.
There was also a question, or rather a live coding request, to open the code of my app, share my screen, and make every name show up in red if it has an even number of letters. This is when stress and being sick took over me (I’m also a terminal case of forgetting my own name when observed), and I wrote this monster and wondered why it didn’t work:
If I used Next.js for this project, it would probably steer me toward the correct answer by throwing a hydration error, and I would realize that I’m trying to render a <p>
tag inside another <p>
tag, instead of adding a class dynamically. I assume my interviewers now think I’m a moron and not even a junior.
I also got some questions related to syntax, like the nullish coalescing operator and optional chaining. The thing is, sometimes it isn’t easy to explain what something with a very technical-sounding name is, but if you see the code, you know what it is and when to use it. For instance, I used the nullish coalescing operator (or: ??
) to set the default view to be a list (there is a switcher between list and grid view):
it means that if there is no value (null
) in localStorage with the key isListView
, set it to true
. It is similar to ||
(logical OR
operator), but slightly different, as it is a special case of logical OR.
Logical or ||
returns the first truthy value (so it checks for null
, undefined
, 0
, empty string ““
, NAN
or false
)
While nullish coalescing ??
returns the first defined (non-null) value, so it only checks for null
or undefined
values:
Another syntax-related question was about optional chaining. I use it a lot in JSX when accessing properties of objects. Sometimes a property doesn’t exist, so it is always safer to access it with optional chaining ?.
. Then, if that property is not accessible, the expression short-circuits and returns undefined instead of throwing an error (in this case, availableCountries may be undefined because it comes from the data from the API).
(here is also that Set that opened the interview. Why did I want a Set here? Because I didn’t want any duplicates in the dropdown options).
Learning to code is a long and perilous journey. You may feel like you've escaped Tutorial Hell by building your own projects, like me, but you might find yourself at the Peak of Mount Stupid. It’s only slightly better than Tutorial Hell, but if you’re here, it means you know how to do things, but you don’t know why those things are done. To descend from the Peak of Mount Stupid, start not only reading the docs of the technologies you’re using but also questioning the way things are done. Why are we doing things this way? Why is this way better than the other? What’s the difference between x and y? Why did you choose tech x over tech y for your project? Asking the “how?” questions will only give you knowledge, but the “why?” questions will give you an understanding of underlying principles. And this is what helps you get down from the Peak of Mount Stupid. That’s what I will try to do.
References: