cover-image

My First Tech Interview Experience

#jobinterviews
#algorithms

Andrew Vo-Nguyen

November 17, 2020

6 min read

So three weeks ago I landed my first Software Development job interview. I was recommended by a fellow friend that I met at University this semester. It was for a a role as a Junior Software Developer.

I got the call on Monday afternoon from the HR department to participate in a Zoom interview on Tuesday. This gave me less than 24 hours to prepare. Leading up the interview I wrote down what my soft skills were, my weaknesses, strengths and my coding philosophy, and my intentions as a Software Developer.

12pm Tuesday...I logged into the Zoom call and was greeted by HR, the Manager and a Senior Software Developer. All was going well when I was chatting about my passion for Front End Development, React and various JavaScript technologies. We eventually got to the business end of the interview. The "whiteboard" session. Due to COVID, the interview has to be conducted over Zoom. This type of exercise I assume would normally be conducted on a real whiteboard using pseudo code, however in this case I had to share my screen and let the interviewers watch me code live. This was incredibly daunting as they could see all my inefficiencies in problem solving, but on the other hand, it is probably a great way for them to assess my performance as a programmer.

Problem 1

Can you implement a function to get the intersection of a list of arrays?

Example outputs:

1intersect([[7, 3, 6, 10], [9, 10, 3]])
2//return [10, 3]<br/>
3
4intersect([[9, 10, 3], [7, 3, 6, 10], [3, 7]])
5//return [3]
6
7intersect([[2, 3], [4, 5]])
8//return []
9
10intersect([[2, 3 ,5]])
11//return [2, 3 ,5]

My Initial Solution

1function intersect(listOfArray) {
2  const flattenedArray = listOfArray.flat();
3  const uniqueNumbers = [...new Set(flattenedArray)];
4  const intersectingNumbers = [];
5  uniqueNumbers.forEach((uniqueNumber) => {
6    let count = 0;
7    flattenedArray.forEach((flattenedNumber) => {
8      if (uniqueNumber === flattenedNumber) {
9        count++;
10      }
11    });
12    if (count > 1) {
13      intersectingNumbers.push(uniqueNumber);
14    }
15  });
16  return intersectingNumbers;
17}

My initial solution passed the first sample input with flying colours, however failed the others. I was only accounting for numbers that appeared more than once in the flattened array, when I should have been checking if they appeared in "every" inner array.

My Final Solution

1function intersect(listOfArray) {
2  const flattenedArray = listOfArray.flat();
3  const uniqueNumbers = [...new Set(flattenedArray)];
4  const intersectingNumbers = [];
5  uniqueNumbers.forEach((uniqueNumber) => {
6    let count = 0;
7    flattenedArray.forEach((flattenedNumber) => {
8      if (uniqueNumber === flattenedNumber) {
9        count++;
10      }
11    });
12    // if (count > 1) { <-- Original Solution
13    // Correct Solution
14    if (count === listOfArray.length) {
15      intersectingNumbers.push(uniqueNumber);
16    }
17  });
18  return intersectingNumbers;
19}

As you can see, only a single line of code was required to be adjusted for all the test cases to pass. Admittedly, I was overwhelmed during the interview and buckled a little under the pressure. I ended up fixing my solution and sending it to the interviewer the next day. I think they appreciated that 😬.

Problem 2

Given an array of integers and a target integer, implement a function that returns the indices and values of the first pair of numbers that add up to the target

For example:

1const twoSum = (array, target){
2	//Implementation
3}
4
5// Example outputs:
6
7console.log(twoSum([3 4, 9, 1, 7, 5, 5], 10);
8//has to print [{index: 2, value: 9}, {index: 3, value: 1}]
9
10console.log(twoSum([3, 4, 9, 1, 7, 5, 5], 6);
11//has to print [{index: 3, value: 1}, {index: 5, value: 5}]
12
13console.log(twoSum([3, 4, 9, 1, 7, 5, 5], 15);
14//has to print []

My Solution

1const twoSum = (array, target) => {
2  let lowestIndex = array.length - 1;
3  let result = [];
4
5  for (const [firstIndex, firstNumber] of array.entries()) {
6    for (const [secondIndex, secondNumber] of array.entries()) {
7      if (firstIndex !== secondIndex) {
8        if (firstNumber + secondNumber === target) {
9          const minIndex = Math.min(firstIndex, secondIndex);
10          if (minIndex < lowestIndex) {
11            lowestIndex = minIndex;
12            result = [
13              {
14                index: firstIndex,
15                value: firstNumber,
16              },
17              {
18                index: secondIndex,
19                value: secondNumber,
20              },
21            ];
22          }
23        }
24      }
25    }
26  }
27  return result;
28};

My approach here was to iterate over each number in the array and add it with every other number in the array that isn't itself. Once there was a match, get the indexes of both the outer number and the inner number and compare the minimum to lowestIndex.

Using this approach, I unfortunately failed the first test case as my result was:

[ { index: 0, value: 3 }, { index: 4, value: 7 } ]

I didn't quite understand the question's definition of "first pair of numbers" 🤷‍♂️, and I believe it could have be interpreted in many ways. By now, I had felt super flustered and my heart was racing 💯 miles an hour. I was 0/2 for problems solved and would need a hail mary to get me out of this interview alive.

Problem 3

Can you implement a function to returns all the indices of occurrence of a specified value in a string?

You cannot use the built-in indexOf function or similar

1function findAllIndices (stringToCheck, specifiedValue) {
2//Implementation
3
4}
5
6// Example outputs:
7findAllIndices('the fox jumps over the dog', 'the')
8//expecting [0, 19]
9
10findAllIndices('the fox jumps over the dog', 'brown')
11//expecting []
12
13findAllIndices('the fox jumps over the dog', 'o')
14//expecting [5, 14, 24]
15
16findAllIndices('the fox jumps over the dog', ' ')
17//expecting [3, 7, 13, 18, 22]

My Solution

1function findAllIndices(stringToCheck, specifiedValue) {
2  const result = [];
3  const specifiedValueLength = specifiedValue.length;
4  for (const [index, _letter] of stringToCheck.split("").entries()) {
5    const substring = stringToCheck.substring(
6      index,
7      index + specifiedValueLength
8    );
9    if (substring === specifiedValue) {
10      result.push(index);
11    }
12  }
13  console.log(result);
14}

It looked like the gods had shown me mercy 😇, or most likely this was just a pity question that the interviewers decided to give me while they were thinking in their heads "surely he can't screw this one up".

And screw this one up...I didn't. To solve this problem, it was quite simple. There was some string manipulation and some simple string comparisons. I basically iterated over each substring of the length of the specified value and did a comparison. If there was a string comparison match, it's index would get pushed onto the final result array.

The interview took about an hour and twenty minutes due to my struggles through each problem. I had a quick opportunity to share some of the projects that I was currently working on which was greatly appreciated on my part.

As soon as I hung up the Zoom call, my head dropped onto the table in disappointment thinking "I screwed this up so bad". It was unlike any other interview I had attended for other jobs. Because it was a challenge, it felt like it would be something of more worth than a other jobs where the interview process was super chilled. After calming my emotions, I took the opportunity to appreciate the experience for what it was. If I didn't get the job, I would use it as fuel to make sure I don't make the same mistakes again for future interviews.

Did I get the job? stay tuned... 😯