DEV Community

loading...

Interview question for a Senior Js Developer, final part (Answer)

eulier profile image Eulier Gonzalez ・4 min read

In my last post i talked about, how i went from looking for a job using the ApplyByAPI to an interview question.

I split this in two part, so you can watch it in another tab, and switch it easily, instead of wheeling up and down with the mouse.

This is just for educational purposes.

Answer 1

The error take place when the condition evaluate the "Superman is awesome!" and the indexOf method return 0 (which is the index) and it's evaluate as false, so to prevent this, we could wrap the expression and compare to less than 0. (-1 means it could not found it).

function validateString(str) {
    if ((str.toUpperCase().indexOf('superman'.toUpperCase())) < 0) {
        throw new Error('String does not contain superman');
    } 
}
Enter fullscreen mode Exit fullscreen mode

Answer 2

If you need to search elements in a sorted array, binary search algorithm is the way to go, their Big O is O(log n), so the steps to do it is:

  1. Define let start = 0 and let end = n-1 (where n-1 is the last element of the sorted array)
  2. If start < end, then stop: target is not present in array. Return -1.
  3. 2. Compute guess as the average of start and end, rounded down (so that get an integer).
  4. If array[guess] equals target, then stop. You found it! Return guess.
  5. If the guess was too low, that is, array[guess] < target, then set start = guess + 1.
  6. Otherwise, the guess was too high. Set end = guess - 1.
  7. Go to step 2
function binarySearch(sortedArray, key){
    let start = 0;
    let end = sortedArray.length - 1;

    while (start <= end) {
        let guess = Math.floor((start + end) / 2);

        if (sortedArray[middle] === key) {
            return guess;
        } else if (sortedArray[middle] < key) {
            start = guess + 1;
        } else {
            end = guess - 1;
        }
    }
    return -1;
}
Enter fullscreen mode Exit fullscreen mode

Answer 3

const phonenumberFormatter = (numberString, delimiter = '-') => {
    let arrayInputPhoneNumberString = numberString.trim().split('')
    let arrayOutputPhoneNumberString = []
    const lengthUSPhoneBlock = 10 // 3-3-4 US block standard
    let counterLenPhoneBlock = 0

    arrayInputPhoneNumberString.forEach( (value) => {
        if (parseInt(value) === 0 || parseInt(value)) {
            counterLenPhoneBlock++
            arrayOutputPhoneNumberString.push(value)
            if (counterLenPhoneBlock === 3 || counterLenPhoneBlock === 6 ) {
                arrayOutputPhoneNumberString.push(delimiter)
            }
        }
    })

    if(counterLenPhoneBlock === lengthUSPhoneBlock) {
        return arrayOutputPhoneNumberString.join('').toString()
    }

    return 'missing numbers, check your phonenumber again'
}
Enter fullscreen mode Exit fullscreen mode

Answer 4

// Assuming we set up our enviroment to use Import ES6 Syntax

import fizzBuzz from './fizzbuzz';

describe('Fizzbuzz Test', () => {

    test('output 1 for input 1', () => {
        expect(fizzBuzz).toEqual(1)
    });

    test('output "Fizz" for input 3', () => {
        expect(fizzBuzz).toEqual('Fizz')
    });

    test('output "Buzz" for input 5', () => {
        expect(fizzBuzz).toEqual('Buzz')
    });

    test('output 7 for input 7', () => {
        expect(fizzBuzz).toEqual(7)
    });

    test('output "Fizz" for input 9', () => {
        expect(fizzBuzz).toEqual('Fizz')
    });

    test('output "Buzz" for input 10', () => {
        expect(fizzBuzz).toEqual('Buzz')
    });

    test('output "FizzBuzz" for input 15', () => {
        expect(fizzBuzz).toEqual('FizzBuzz')
    });

    test('output "FizzBuzz" for input 45', () => {
        expect(fizzBuzz).toEqual('FizzBuzz')
    });
})
Enter fullscreen mode Exit fullscreen mode

Answer 5

    const hash = (name) => {
      let hash = 0;
      for (var i = 0; i < name.length; i++) {
        /* 
        * retrieve the UTF-16 value 
        * while shift left the hash value 
        * (an hex value can be represent up to (2^5 -1) from 0 - 15 )
        * minus the previous hash value ( for more random purpose )
        */
        hash = name.charCodeAt(i) + ((hash << 5) - hash);
      }
      return hash;
    }

    const getColorFromName = (name) => {
        let hashCode = hash(name)
        let value = 0
        let color = "#"
        /*
        * Build the hex char, i.e. #000000 
        */
        for (let i = 0; i < 3; i++) {
            /*
            * Nudge right 8 position from the hash up to 3 times 
            * and bring the commons bits from the hexadecimal higgest value.
            * Then, build the color string.
            */
            value = (hashCode >> (i * 8)) & 0xFF;
            color += ('00' + value.toString(16)).substr(-2);
        }
        return color
    }
Enter fullscreen mode Exit fullscreen mode

To make code much modular and easy to maintain, we can pass to getColorFromName() the hash function as a second parameter.

Answer 6

In our IIFE, we need to access to addEventListener from the getElementById, so when listen the 'click' event,
we can trigger our code.

(function(){
    for (var i = 0, l = 10; i < l; i++) {
        document.getElementById('button-' + i).addEventListener('click', function (event) {
            console.log('Line %s', i);
        })
    }
})();
Enter fullscreen mode Exit fullscreen mode

However there is a couple gotchas here, hoisting and closure. You see, hosting is a very annyoning concept in the ES5
and below, is the process of initialize all functions and variables and place them into memory.
Functions are hosted in memory, but variable are initializes as undefined, this is a behaviour we can avoid using
let & const thanks to the block scope, but this is for ES6, and we need to solve this on ES5.

So, we can use closure, and they allow functions to gain access variables to outer scope from inner scope. The Javascript Engine will keep those variables around inside function if they have reference to them, instead of "sweeping" them away after they popped off the call stack. Here is how we can solve this.

(function(){
    for (var i = 0, l = 10; i < l; i++) {
        (function(i){
            document.getElementById('button-' + i).addEventListener('click', function (event) {
                console.log('Line %s', i);
            })
        })(i)
    }
})();
Enter fullscreen mode Exit fullscreen mode

Here is the code sample with the html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="button-0">click 0</button>
    <button id="button-1">click 1</button>
    <button id="button-2">click 2</button>
    <button id="button-3">click 3</button>
    <button id="button-4">click 4</button>
    <button id="button-5">click 5</button>
    <button id="button-6">click 6</button>
    <button id="button-7">click 7</button>
    <button id="button-8">click 8</button>
    <button id="button-9">click 9</button>
</body>
<script>
(function(){
    for (var i = 0, l = 10; i < l; i++) {
        (function(i){
            document.getElementById('button-' + i).addEventListener('click', function (event) {
                console.log('Line %s', i);
            })
        })(i)
    }
})();
</script>
</html>
Enter fullscreen mode Exit fullscreen mode

Answer 7

An iterable is a generalization of arrays, and technically having a method Symbol.iterator makes one.

function isIterable(obj) {
  // checks for null and undefined
  if (obj == null) {
    return false;
  }
  return typeof obj[Symbol.iterator] === 'function';
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)

pic
Editor guide