codete How to Prepare for a Frontend Developer Interview Tips from Our Tech Recruiters 1 main 903d99e8e2
Codete Blog

How to Prepare for a Frontend Developer Interview? Tips from Our Tech Recruiters

Olaf Cichocki f433dd0788
Jakub Pietras af7d556dd3

09/04/2020 |

11 min read

Olaf Cichocki,

Jakub Pietras

Hello! As Senior FE Developers and technical recruiters for Codete, we (Jakub and Olaf) would like to share some tips about the most important topics which you should know when applying for a Frontend Developer position at any company. 

These topics are the core of your knowledge and define your performance and skills when working on a day-to-day basis. It’s a given that you probably know or have heard about most of them. However, very often there are hidden details that impact how JavaScript works, but they may not be so easy to find. 

We hope to highlight some useful areas to read about before your next interview. Without any further ado, let’s start!

 

Frontend Developer interview – topics to revise

  1. Variable declaration keywords and scope
  2. Closures
  3. Event loop
  4. Fundamentals

 

Variable declaration keywords and scope

This is the most frequent question asked in JavaScript developer interviews. By “variable declaration keywords” we mean “var”, “let” and “const”. Each of these has different effects when used, and that’s an area which most of the recruiters like to check. 

Let’s take a look at those keywords and common pitfalls when describing how they work.

var has function scope – it is important to remember that “function” scope is not “global”. It can be global, but only if declared at the top level (and if you use ES6 modules, it’s going to be scoped inside the module only). It is also hoisted to the top of the function.

let and const both have “block” scope. That means variables declared with those keywords will be visible between braces {} (be it loop braces, or conditional expression braces).

Bonus: “let” and “const” are both hoisted, but (!) we can’t “profit” from that because of something called Temporal Dead Zone. TDZ simply means we will get a reference error if we try to use these variables before their initialization – so they behave as if they are not hoisted.

const is also an immutable primitive value or an immutable reference to a complex type. It is important to remember here that if we declare a variable referring to an array or an object using “const” – we can’t change the reference, but we still can change the contents. 

An important tip here – “what is Object.freeze()?“ is a common follow-up question here, and the answer is: it is used to make an object immutable (it’s a shallow operation though, so if you want to make it deeply immutable you have to do it recursively).

Bonus: Learn about Object.seal(), it’s similar to Object.freeze(), but has different effects on property descriptors of the affected object.

Closures

Oh boy, this is a tough one! Developers use closures all the time when writing in JavaScript, but very often have serious issues trying to describe how they work. You can be almost sure that closures will find you, be it in form of a purely theoretical question or a live coding task that will require you to use them.

Let’s start with a textbook definition:

 “closures” are a combination of a function declaration and the lexical environment (surrounding scopes) in which it was declared.

Okay – that’s kind of hard to understand, isn’t it? 

Let’s break it down into parts. When we declare a function, we create a new “closure”. The function we are declaring can access variables outside of it – so if we have a function inside a function, the inner one can access variables declared in the outer one. 

The closure is the function we just declared, along with all the variables outside it which it can use. Closures live until a reference to the function exists – because if we can still somehow call the function, we need all the variables which it can access to still exist, too. The closure will be deleted by the garbage collector once we can no longer call the function which it encloses.

An example is worth more than a thousand words:

function createClosure() {
  const testVariable = 2;

  return function newFunctionToCreateClosure() {
    console.log(testVariable);
  };
}

(() => {
  const ourNewFunction = createClosure(); // a closure is created

  ourNewFunction(); // "2" is logged in console
})(); // we use an IIFE here to lose the reference to "ourNewFunction"

// here we no longer have any possible way to access "ourNewFunction"
// garbage collector removes our closure containing "testVariable" 

Event loop

It’s one of the harder topics to discuss because it’s a part of the more advanced knowledge regarding JavaScript. While the event loop is not something we have to think about every time we write a function, it’s something that can be a great aid in understanding why our code works as it does. 

If you are applying for a Senior Frontend Developer position, you have to be ready to describe what event loop is and how it works (it’s great to know this as a Mid Developer also). 

First of all, a straight ball: javascript in the browser is single-threaded. The next question coming up after that is “well, how is it possible that we execute asynchronous operations if there is only a single thread?”. We can do that thanks to the event loop. 

The event loop manages the order in which various operations are processed, which includes carrying out tasks asynchronously. It consists of three elements:

  • heap (space in memory, nothing much for us to understand here)
  • call stack containing function calls
  • message queue containing messages with attached tasks (callbacks to execute)

 

Now, for some explanation

“Call stack” – here the “stack” part comes from the well-known data structure (First In Last Out) in which each following item is added on top of the stack, and we can always only look at the top, so after adding 10 items we need to pop 9 items to arrive back at the first one. 

This is how function “frames” are managed. Each deeper function we call is added on top of the stack and must be finished before we go back down. This also explains what a “stack overflow” error is – if we call too many functions inside other functions we eventually run out of space to put another call on the stack (happens often during recursion).

Again, let’s see this on an example:

function outerFunction() { // added to the stack
  // outerFunction starts being executed 

  (function innerFunction() { // added to the stack
    // innerFunction starts being executed

    (function superDeepFunction() { // added to the stack
       // here we have 3 elements in the stack
       // superDeepFunction is the one on top and has to be completely finished
    })();

    // once superDeepFunction finishes, JS engine goes back to executing innerFunction
  })();

  // and only after innerFunction finishes execution, we arrive at this place
}

“Message queue” – here we have all the asynchronous actions. Every time we call setTimeout(), send AJAX requests, use Promises or execute any other asynchronous action – a new entry is added to the queue. 

Just like a call stack, a message queue is based on a well-known data structure called “queue” (First In First Out) in which items are removed in the order they were added. Each message has its attached “task”. Tasks are separated into micro and macro tasks.

 

How does this all go together?

When the call stack is empty, the JS engine moves to execute tasks in the queue. It executes all microtasks (like Promises) and a single macrotask (like setTimeout) and then goes back to the call stack. This is why setTimeout(function, 0) will not execute immediately – it can usually take even up to a few milliseconds because the current call stack has to be emptied first.

Be ready to explain the event loop, show off your skills to the recruiter.

Fundamentals

Nowadays we seem to live in an Everything-in-JS world, when we often abstract things like DOM and CSS in JavaScript, using libraries like React, or Styled Components. During many recruitments, we have noticed a trend that it is harder and harder to find people with a good grasp of other fundamental technologies like HTML and CSS. 

People tend to forget about the basics, and it always makes a good impression if you know them. For example, things as simple as knowing the semantic meaning of HTML tags – for example <figure> and <figcaption> – can show the recruiter that you didn’t forget about web fundamentals, especially if they look for someone for an SEO-heavy project. 

Then we come to CSS, which seems like something everybody knows, but most people don't understand. Recruiters can ask you about things like CSS Specificity and selector strength. Or they can ask how animations work, how to optimize them.

 

When applying for a Senior Frontend position, it is important to have a solid understanding of the principles of programming

While in your everyday work you might not use algorithmic knowledge to the extent that it is used on the backend, some practical knowledge may be required. For example, during the interview you may be tasked to prepare a function that operates on some data structure, returns some value from the sequence, or deal with a problem using currying or recursion – all of those are basic tasks that don’t require extensive knowledge, but easily show how the candidate thinks, how they analyze the problem and what steps they take to finish the task. 

Here speed is less important than quality, so please take your time to explain your logic, and while you can take some shortcuts, it is best to explain them, and generally – try to write quality code. Of course, nobody expects you to write it perfectly from the get-go.

 Write it fast and dirty if needed, but refactor it before submitting it to the recruiter. 

 

To give you an easy example, let’s take a look at one of the most famous live coding tasks for junior-level developers: FizzBuzz.

Log all numbers from 1 to 100, but if the number can be divided by:

3 – log „Fizz”,

5 – log „Buzz”,

3 and 5 - log „FizzBuzz”.

This task is very easy, but we can get a lot of different implementations, and those can tell a lot about the developer. Let’s start with something like this: 

for (let i = 1; i <= 100; i++) {
	if (i % 3 === 0) {
		if (i % 5 === 0) {
			console.log('FizzBuzz');
		} else {
			console.log('Fizz');
		}
	} else if (i % 5 === 0) {
		console.log('Buzz');
	} else {
		console.log(i);
	}
}

This is a very naive implementation that can be sometimes written by beginners. Let’s try to clean it up a little.

for (let i = 1; i <= 100; i++) {
	if (i % 15 === 0) { // (i % 3 === 0 && i % 5 === 0)
		console.log('FizzBuzz');
	} else if (i % 3 === 0) {
		console.log('Fizz');
	} else if (i % 5 === 0) {
		console.log('Buzz');
	} else {
		console.log(i);
	}
}

As you can see, we improved the code quality by getting rid of one level of ifs. Also, we are checking if % 3 === 0 && i % 5 === 0 but we simplify it further using i % 15 === 0 – it is not something noted in the task, but we can easily notice this by ourselves. 

Much better, right? It is quite a good answer, but there is never only one good answer. 

Let’s take a look at an alternative approach using guard clause pattern, and string concatenation.

for (let i = 1; i <= 100; i++) {
  let result = '';

  if (i % 3 === 0) {
    result += ('Fizz');
  } 
  if (i % 5 === 0) {
    result += 'Buzz';
  } 
  
  console.log(result || i);
}

We reduced the number of logic and got a result differently. There are a lot of different ways we can write the same thing. There isn’t one correct way to write code (although I believe there are a lot of incorrect ones). 

When tasked with writing code try to write clean code, name your variables like a sane person, and if you need to do something in a quick and dirty way, just try to clean up afterward.

That’s it! We’re keeping our fingers crossed for your Frontend Developer recruitment processes. Who knows, maybe one day we’ll get to meet at Codete? Feel free to check out our current job openings

Rated: 5.0 / 1 opinions
Olaf Cichocki f433dd0788

Olaf Cichocki

Olaf is a Senior Frontend Developer with a rare affinity for CSS. When he’s not coding at work, he’s probably using his computer to learn Elixir (which is also coding, but shh) or browse memes. Offline, he’s a huge fan of board games and the unofficial president of our Codete Board Games Club. He’s a proud owner of two cute dogs, Merry and Pippin.

Jakub Pietras af7d556dd3

Jakub Pietras

Jakub is a Senior Frontend Developer who keeps on pulling all-nighters to learn as much JavaScript and React as possible. He has three cats to support him during the tough times when the console goes all red, and the Continuous Integration builds fail. Hit him up if you ever need a comment for every single line of code in your pull request.

Our mission is to accelerate your growth through technology

Contact us

Codete Global
Spółka z ograniczoną odpowiedzialnością

Na Zjeździe 11
30-527 Kraków

NIP (VAT-ID): PL6762460401
REGON: 122745429
KRS: 0000983688

Get in Touch
  • icon facebook
  • icon linkedin
  • icon instagram
  • icon youtube
Offices
  • Kraków

    Na Zjeździe 11
    30-527 Kraków
    Poland

  • Lublin

    Wojciechowska 7E
    20-704 Lublin
    Poland

  • Berlin

    Bouchéstraße 12
    12435 Berlin
    Germany