My Recent Job Interview & What I Learned
As a web developer, I’ve had a fair share of job interviews. Some go well, others, not so well. In this article, I wish to talk about my recent tech interview, and what I learned in the process. It was an enlightening experience, one which challenged me to recite the saying, “You Don’t Know JS“, over and over again, as I drowned in my “Good Life” track by Kehlani and G-Easy on my way back home.
Although the entire interview revolved around different subjects, the primary focus was on Javascript, of which this article will go into sharing the experience.
I must say it was one of the best, lovely in-person interviews I’ve had so far in a long time. At least, I was not asked the question: “How Do I See myself in 5 years time?”
To all future employers, my answer to the “How Do I see myself in 5 years time” is this. Take note:
“Learning more, advancing, embracing new challenges and gaining more experience in doing what I do, and with all that, give what I can back to the community as and when necessary.
“And ooh, I hope to be my current age + 5!”
To give a very accurate answer, I would need to ask The Flash to send me to the future.
I don’t think such a question is of any use and this StackOverflow article hammers on the point better:
If you’ve been through interviews at some companies that are not as good at interviewing, then you probably had some questions on your list such as
- Where do you see yourself in 5 years? // Sipping Mars-grown-and-brewed ‘Covfefe’ with Elon on Mars!
- Why do you want to work here? // Because I don’t have a job, can’t you see!
- How do you handle disagreements with coworkers? // Like Patrick, SpongeBob Square Pant’s friend!
As much as I don’t bother answering questions like the above during an interview with all seriousness, it give me insight a bit into who will be interviewing me.
That was just by the way.
The Job Role
For the job role, which is related to teaching ‘technology related technologies’, not just knowing your stuff, but understanding them is crucial. To be an effective teacher, being able to express the understanding behind a process, a tool and the how-tos at the most fundamental approach possible is essential.
As part of the interview, I was put on a Javascript hot seat, kinda. How did I do? Looking back, I think I failed my Javascript. However, it’s been a huge learning experience for me, and I learned a lot through questions I, in turn, asked.
Here’s why.
The Elephant in the Room
Let’s talk about some of the Javascript questions that came through. However, before that, I wanna drop the coding question that was presented to me to solve. The solution will be at the end of this article.
See if you can solve it on your own. I couldn’t solve the question at first try, without extra research.
The question: Write a function, which accepts a string as an argument, and returns either true or false, whether the string can be made into a palindrome or not, respectively.
For example:
aabb
is not a palindrome. However, it can be rearranged to form a palindrome – even two:abba
andbaab
So, the function is only responsible to check NOT whether a string is a palindrome or not, but rather, to check IF a string CAN become a palindrome.
A function like this (python) checks whether a string IS or IS NOT a palindrome:
str("str") == str("str")[::-1]Or in Javascript:
"str" === "str".split('').reverse();BUT, the solution wanted for the problem above, there is no interest in knowing if a string is a palindrome or not. Rather, the interest is in whether the string can be rearranged, as in, the individual letters in the strings can be rearranged to form a palindrome.
Although I knew palindromes, this was new to me. I had played with palindromes a long time ago, however, not with this approach. Or have I?
Long story short, I couldn’t solve the problem during the interview. In fact, looking back, the path I took in solving was likely not going to get the required result for all the possible edge cases of solving such a problem.
At a later section of this article, the solution is given. However, see if you can solve a problem like that on your own. You can always check the solution below to learn more. I’ve provided details and a breakdown of the solution in there.
Javascript Interview Questions
In the process of the interview, during the Javascript part, these are some of the questions that came through that I remember.
What is Function Programming and Object Oriented Programming?
I would see a functional program when shown. I can identify an Object Oriented Program when I see. Yet, defining, not so great. I did a few reading afterward, and the explanation tied into what I already knew, yet couldn’t express in simple and right terms.
A rough basic way of thinking of Functional Programming is to imagine a function which when given the same arguments, produces the same results all the time, always.
With such an approach, it is always easy to predict the results of a function with the given arguments, as the result will remain the same, whether run once, twice or more.
It is more complex and extensive to define in just a line, however the above sets you on the right path, and you may throw in some of the concepts of functional programming such as:
- High Order & First Class Functions: A function that takes another function (its result) as argument or returns a function as a result
- Pure Functions: A function with no side effects, as in depends not on any free variable (a variable with changing states/values), or does not affect aspects such as I/O of the system.
- An example should help:
var x = "str".length
returns3
.x
will always return 3, as long as the argument is alwaysstr
- However, a date function returning date or time will always return different values always, since the state of time changes. Therefore, a function like this:
function myDate() { return Date.now() };
will always return a different value, and it can be said the functionmyDate()
is an impure function
- An example should help:
Did I explain Functional Programming anything close to the above during the interview? Nope.
Then Object Oriented Programming?
As the name suggests, the paradigm revolves around the concepts of “Objects”, therefore, one might have a “Car” object, which has features (attributes) such as color
, model
, etc, and can have actions or procedures (methods), such as drive()
, brake()
, horn()
etc
The fundamental objects created go on, in turn, to be interacted with other objects to make a meaningful program.
A “Class” is, therefore, the definition and or data format and procedures (methods) for a given type or class, meanwhile “Objects” are the actual instances of a “Class”
An example would do, right?
class Car(): # This is the "Class", namely, "Car" color = 'red' model = 'm39 2017' def brake(self): print('Stopping car') def accel(self): print('Accelerating') myCar = Car() # This is the Object, an instance of the "Car" Class myCar.color # 'red' myCar.model # 'm39 2017' myCar.brake() # 'Stopping Car' myCar.accel() # 'Accelerating'
The example sets the tone right, and sends a clear message you know your stuff, right!
Constants
Let us use this preamble code:
// this doesn't work const myVar = 'Hello'; myVar = 'Goodbye'; console.log(myVar); // this throws error // TypeError: Assignment to constant variable // this works const myArray = ['hello', 'hi'] myArray.push('duh'); console.log(myArray); // ['hello', 'hi', 'duh']
Why does the first example fail, but the second works? Well, it is as a result of this, as the documentation puts it:
The
const
declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object’s contents (e.g. its parameters) can be altered.
In the case above, the variable, myArray
is an Array Object. Attempting to change the myArray
type to something else, such as to a primitive type won’t work.
However, a big, HOWEVER, changing the contents of the Array Object, in this case, the ['hello', 'hi']
, such as pushing a new value onto the array should work.
INFINITY
What happens if you divide 5 by 0 in Javascript, namely, 5 / 0
?
No. You don’t get a DivisionError or whatever common sense has trained us to believed. Thanks to Javascript, it is believed dividing a number by zero equals INFINITY
.
If you, for a second, though Javascript is entirely sane, then there you have it. Even a grade school kid mathematician understands the fact that dividing any number by zero is impossible, and throws an error. In Javascript, it’s a no.
You get this in Python instead:
>>> 5/0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero
Thank you, Python!
Concurrency vs Parallelism vs Multithreading
Until my interview, the first two terms meant the same to me. Multithreading, not very sure what it truly meant. Compiling Blender, one could use make -j 16
, where 16 threads, or processes will be initiated, all working in tandem to build the code. Thus, on an i7 (8-core) machine, that is 2 threads per core.
The canonical definition though is considered to be: (from Wikipedia):
In computer architecture, multithreading is the ability of a central processing unit (CPU) or a single core in a multi-core processor to execute multiple processes or threads concurrently, appropriately supported by the operating system.
So how different with Parallelism or Concurrency?
From the little reading I’ve done, I think of it roughly as so, using the understanding from HyperVisors or VirtualBoxes:
The Task: Open 10 tabs in Chrome and Firefox, using Windows and Ubuntu operating systems.
Approaches:
- A single core (with 2 threads, running concurrently):
- Will spin up the Windows Guest VM (thread 1).
- pauses thread 1. Starts Ubuntu VM (thread 2)
- interchangeably continues with thread 1 & 2 – alternatingly
It does this alternating between the threads until each Chrome and Firefox browser opens up 10 tabs on Windows and Ubuntu. Concurrency at work.
- 2 Cores (with a single thread each):
- Core 1 spins up a Windows VM and works its way to the end
- AT THE SAME TIME, Core 2 also spins up an Ubuntu VM and works its way to the end
- All things being equal, assuming it takes 10 seconds for Core 1 to finish task, it’ll take Core 2 the SAME amount of time, 10 seconds to complete the Windows part task.
With the two approaches above, assuming a single part of the task cost 10 seconds to complete, it can take 20 seconds via Approach 1, but only 10 seconds on approach two.
Parallelism: Two or more independent (or related tasks takes different paths, yet code combines all the paths results at the end) tasks running at the same time, executed by two or more cores.
Concurrency: Two or more independent (or related tasks takes different paths, yet code combines all the paths results at the end) tasks running alternatively, executed by a single core.
Right?
I have no idea if what I said makes any sense nor is right. Just expressing my understanding from reading resources like this: Concurrency vs Parallelism
Let vs Var
The differences between let
and var
is best displayed via examples. The difference is scoping. var
is scoped to the nearest function block and let
is scoped to the nearest enclosing block.
Explaining via examples make the whole picture clearer. These examples are taken from StackOverflow:
var you = "you"; //global scope let me = "me"; // global scope console.log(window.you) // you console.log(window.me) // undefined. // Global variables defined with // let will not be added as properties on // the global window object like those defined with var. // Next example function allyIlliterate() { //tuce is *not* visible out here for( let tuce = 0; tuce < 5; tuce++ ) { //tuce is only visible in here (and in the for() parentheses) //and there is a separate tuce variable for each iteration of the loop } //tuce is *not* visible out here } function byE40() { //nish *is* visible out here for( var nish = 0; nish < 5; nish++ ) { //nish is visible to the whole function } //nish *is* visible out here } // Another example 'use strict'; let me = 'foo'; let me = 'bar'; // SyntaxError: Identifier 'me' has already been declared 'use strict'; var me = 'foo'; var me = 'bar'; // No problem, `me` is replaced.
Now you get the difference?
In summary
The above questions and other related ones came up during the lively interview, not all I remembered to write talk about. However, they were technical, with a coding task, in which I move on to solve in the next section.
I learned a lot in the process, and happy to have had the opportunity. It was a timely reminder that, “I don’t know JS“.
Solution to Problem
Unlike a mere checking, if a string is a palindrome or not, this problem had some few tweaks and caveats up its sleeves. Now you could call it an algorithm, one that will always get what we want to be done, done! And right!
Thinking Process
A string that can be a palindrome follows a pattern. This pattern is what allows the algorithm work on any type of string, and get it right always!
So, what pattern then? Consider these examples and see if you get the pattern:
baba
can becomeabba
orbaab
which are all palindromes, but the actual stringbaba
is not a palindromegodgo
can becomegodog
orogdgo
which are all palindromes, but the actual stringgodgo
is not a palindrome
I couldn’t get the pattern without help from the interviewers. And the pattern is this:
To determine if a string can be rearranged to become a palindrome, there should be a less than or equal to 1 odd group of letters in the string.
Let that soak in for a second.
abba
for example:
- There is 1 group of the letter
a
and another 1 group ofb
, which satisfies the pattern.a
appears 2 times (one letter group)b
appears 2 times (one letter group)- 2, 2
for godgo
:
- There is 1 group of the letter
g
, 1 group of the lettero
, and another group of the letterd
g
appears twice (one letter group)o
appears twice (one letter group)d
appears once (another letter group)- 2, 2, 1
However, abc
as an example:
- There is 1 group of the letter
a
, 1 group of the letterb
, and another group of the letterc
a
appears once (one letter group)b
appears once (one letter group)c
appears once (one letter group)- 1, 1, 1
With the above pattern in mind, we can have this assumption:
- You have to count all the letters and check if there are letters with odd counts. If there are more than one letter with an odd counts the string does not satisfy the above palindrome condition.
- Furthermore, since a string with an even number letters must not have a letter with an odd count it is not necessary to check whether string length is even or not:
This is one way to solve the problem (taken from here):
// Taken from: https://codereview.stackexchange.com/a/77517/128226 // I couldn't solve it on my own. Reading about the problem landed me // to the approach below, which took me a while to fully comprehend. function canRearrangeToPalindrome(str) { var str = str.toLowerCase(); var letterCounts = {}; // initialize letter count object var letter; var palindromeSum = 0; // loop through the string, // anytime a letter is met, increment the letter's counter for (var i = 0; i < str.length; i++) { letter = str[i]; letterCounts[letter] = letterCounts[letter] || 0; letterCounts[letter]++; } // loop through the letter counts // increment palindromeSum by 1 if letter count is odd // otherwise palindromeSum will default to 0 for (var letterCount in letterCounts) { palindromeSum += letterCounts[letterCount] % 2; } // if there is odd letter groups less than 2 console.log(palindromeSum < 2); //document.write(palindromeSum < 2); } canRearrangeToPalindrome('baba'); // true canRearrangeToPalindrome('abc'); // false