You might not know about me that I have conducted tech interviews with over 500 software developers from more than twenty countries with the objective of identifying and hiring the best talent. I have also been in the candidate position, interviewing for positions ranging from junior developer to CTO.
In this series, I am exposing the secrets of JavaScript interviewing. You will get a chance to solve a tech interview exercise every single week. You will not only refresh your JavaScript skills, but above all, you will learn the mindset required for solving interview exercises. We will start with simple tasks, and then transition to complex exercises that you could even use to build your portfolio.
Exercise
Suppose an array of numbers is given. Create toPalindrome
method that creates a palindrome out of your array in the following way:
> const arr = [1,2,3];
[1, 2, 3]
> const arr2 = arr.toPalindrome()
[1, 2, 3, 2, 1]
> const arr3 = arr2.toPalindrme()
[1, 2, 3, 2, 1, 2, 3, 2, 1]
> console.log( arr, arr2, arr3 );
[1, 2, 3] [1, 2, 3, 2, 1] [1, 2, 3, 2, 1, 2, 3, 2, 1]
undefined
toPalindrome()
returns a new array. It keeps the element arr[ arr.length - 1 ]
the same, and concatenates all the other elements of the array after the end in reverse order.
I encourage you to solve this exercise on your own before checking the reference solution. Even if you solve this exercise, you may learn a lot from my reference solution, as I will reveal my thought process to you both from an interviewer’s and from a candidate’s perspective.
Solution
This exercise is straightforward, it only requires basic JavaScript knowledge, including JavaScript prototypes.
We can go on the safe route, and just use basic ES5 constructs.
Array.prototype.toPalindrome = function() {
const result = this.slice();
for ( var i = this.length - 2; i >= 0; --i ) {
result.push( this[i] );
}
return result;
}
> [1, 2, 3].toPalindrome()
[1, 2, 3, 2, 1]
> [1, 2, 3].toPalindrome().toPalindrome()
[1, 2, 3, 2, 1, 2, 3, 2, 1]
In order to solve this task, you need to know the following about JavaScript:
- To create an array method, we need to extend the prototype of the
Array
object
- The
slice
method without arguments clones an array of integers. In reality, this is a shallow copy, which is absolutely fine in case of atomic values like integers. To read more about cloning, check out my blog post Cloning Objects in JavaScript and Understanding Value and Reference Types in JavaScript.
- We use a simple
for
loop to iterate on the elements of the original array that we want to push
to the end of the array. Push modifies the original result
array.
This is a safe and straightforward solution. You can use some more native array methods to make the solution more compact:
Array.prototype.toPalindrome = function() {
return this.slice().concat( this.slice( 0, this.length - 1 ).reverse() )
}
> [1, 2, 3].toPalindrome()
[1, 2, 3, 2, 1]
> [1, 2, 3].toPalindrome().toPalindrome()
[1, 2, 3, 2, 1, 2, 3, 2, 1]
The solution can be explained as follows:
slice
still makes a shallow copy of the original array
this.slice( 0, this.length - 1 )
makes a shallow copy of the original array, excluding the last element
reverse
reverses the elements of the array. Although reverse
mutates the original array, we are mutating the shallow copy this.slice( 0, this.length - 1 )
.
concat
concatenates two arrays
> const arr = [1,2,3];
// slice: shallow copy
> const arr2 = arr.slice();
[1, 2, 3]
> arr2[ 1 ] = 5;
> console.log( arr, arr2 );
[1, 2, 3] [1, 5, 3]
> const arr3 = arr.slice( 0, arr.length - 1 );
[1, 2]
// reverse
> arr2.reverse();
> console.log( arr, arr2 );
[1, 2, 3] [3, 5, 1]
// concat
> arr.concat( arr3 );
[1, 2, 3, 1, 2]
> console.log( arr, arr3 )
[1, 2, 3] [1, 2]
> arr.concat( arr3.reverse() )
[1, 2, 3, 2, 1]
> arr3
[2, 1]
If we use ES6, we can replace the slice
and the concat
methods with the spread operator:
Array.prototype.toPalindrome = function() {
return [...this, ...this.slice( 0, this.length - 1 ).reverse() ];
}
If you would like to read more about the spread operator, sign up for my ES6 minicourse or check out my article on the Spread Operator and Rest Parameters.
As you can see, this simple exercise is linked to a lot of JavaScript knowledge. A good interview question often reveals how well a candidate can use their thought process as well as JavaScript language constructs for delivering a working solution.
Now that we have solved this exercise together, don’t forget that there are four pillars for a successful tech interview:
- Tech skills
- Problem solving skills
- Soft skills
- Personal Branding
This blog addresses the first two skills. My other blog, devcareermastery.com addresses soft-skills, and my book The Developer’s Edge – How to Double Your Career Speed with Soft-Skills helps you with soft-skills as well as with your personal brand.
If you are interested in fine-tuning your JavaScript skills as well as your soft skills, I highly recommend that you consider purchasing The JavaScript Developer’s Career Bundle. This bundle contains my book ES6 in Practice, 4.5 hours of JavaScript videos, and The Developer’s Edge. You will not only be fully up-to-date with the latest version of JavaScript, but you will also learn how to build a fulfilling career for yourself.