
Du traducteur : nous avons publié un article pour vous , le plus souvent proposés aux développeurs lors des entretiens d'embauche. Cet article sera particulièrement utile aux programmeurs débutants.
Les entretiens dans les entreprises technologiques sont depuis longtemps devenus une légende urbaine. Il n'y a pas de quoi s'étonner — réussir un entretien permet d'obtenir un bon emploi. Mais ce n'est pas si simple, car il est souvent nécessaire de résoudre des problèmes complexes.
Souvent, la plupart de ces problèmes n'ont pas de rapport avec le travail que le candidat réalisera, mais il faut quand même les résoudre. Parfois, il faut le faire sur un tableau, sans pouvoir vérifier avec Google ou toute autre source. Oui, la situation change progressivement, et certaines entreprises renoncent à ces entretiens, mais de nombreux employeurs restent attachés à cette tradition. Cet article est dédié à l'analyse des problèmes typiques en JavaScript, qui sont souvent utilisés comme tâches pour les candidats.
Rappelons-le : pour tous les lecteurs de « Habr » — une réduction de 10 000 roubles lors de l'inscription à tout cours Skillbox avec le code promo « Habr ».
Skillbox recommande : Cours pratique .
L'essentiel est une préparation approfondie pour votre entretien
Oui, avant de commencer à examiner les problèmes, examinons quelques conseils généraux pour la préparation à l'entretien.
L'essentiel est de se préparer à l'avance. Vérifiez à quel point vous vous souvenez des algorithmes et des structures de données, et approfondissez vos connaissances dans les domaines qui vous sont moins familiers. Il existe de nombreuses plateformes en ligne qui peuvent vous aider à vous préparer à réussir des entretiens. Nous vous conseillons , , et .
Il est important d'apprendre à verbaliser la solution à haute voix. Il est préférable d'expliquer aux examinateurs ce que vous faites, plutôt que de simplement écrire sur le tableau (ou de taper du code sur l'ordinateur, aussi en silence). De cette façon, si vous faites une erreur dans le code, mais que votre raisonnement est globalement correct, vous pouvez augmenter vos chances de succès.
Il faut réfléchir au problème avant de commencer à le résoudre. Dans certains cas, il est possible de comprendre superficiellement la tâche et de partir dans la mauvaise direction. Il peut être utile de poser quelques questions clarificatrices à l'intervieweur.
Il faut s'entraîner à écrire du code à la main, et non sur un PC. Il arrive qu'au cours des entretiens, le candidat reçoive un marqueur et un tableau sans aucune indication ni formatage automatique. Lors de la recherche d'une solution, il est utile d'écrire son code sur une feuille de papier ou directement sur le tableau. Si l'on garde tout en tête, il est facile d'oublier quelque chose d'important.
Exercices standards en JavaScript
Il est probable que certaines de ces tâches vous soient déjà familières. Soit vous avez déjà passé des entretiens où il fallait résoudre quelque chose de similaire, soit vous vous y êtes entraîné lors de l'apprentissage de JavaScript. Eh bien, il est temps de les résoudre à nouveau, et ce, avec une explication détaillée du processus.
Palindrome
Un palindrome est un mot, une phrase ou une séquence de caractères qui se lit exactement de la même manière dans les deux sens. Par exemple, "Anna" est un palindrome, alors que "table" et "John" ne le sont pas.
Énoncé
Une chaîne est donnée ; il faut écrire une fonction qui renvoie true si la chaîne est un palindrome et false sinon. Il faut tenir compte des espaces et de la ponctuation.
palindrome('racecar') === true
palindrome('table') === false
Analyse de la tâche
L'idée principale ici est d'inverser la chaîne. Si la chaîne "inversée" est identique à l'originale, alors nous avons un palindrome et la fonction doit renvoyer true. Sinon, elle doit renvoyer false.
Solution
Voici le code permettant de résoudre le problème du palindrome.
const palindrome = str => {
// transformer la chaîne en minuscules
str = str.toLowerCase()
// inverser la chaîne d'entrée et renvoyer le résultat de la
// comparaison
return str === str.split('').reverse().join('')
}La première étape consiste à transformer les caractères de la chaîne d'entrée en minuscules. Cela garantit que le programme compare les caractères eux-mêmes et non pas leur casse ou autre chose.
La deuxième étape est d'inverser la chaîne. Ce n'est pas compliqué : il faut la transformer en tableau à l'aide de la méthode .split() (bibliothèque String). Ensuite, nous inverserons le tableau en utilisant .reverse() (bibliothèque Array). La dernière étape consiste à transformer le tableau inversé en chaîne via .join() (bibliothèque Array).
Maintenant, il ne reste plus qu'à comparer la chaîne "inversée" avec l'originale, renvoyant ainsi le résultat true ou false.
FizzBuzz
L'une des tâches les plus populaires lors des entretiens.
Énoncé
Il est nécessaire d'écrire une fonction qui affiche dans la console les chiffres de 1 à n, où n est un entier que la fonction reçoit comme paramètre, avec les conditions suivantes :
- afficher fizz pour les nombres multiples de 3 ;
- afficher buzz à la place des nombres multiples de 5;
- afficher fizzbuzz à la place des nombres multiples de 3 et 5.
Exemple
Fizzbuzz(5)
Résultat
// 1
// 2
// fizz
// 4
// buzz
Analyse de la tâche
L'essentiel ici est la méthode de recherche des nombres multiples en utilisant JavaScript. Cela peut être réalisé à l'aide de l'opérateur de module ou du reste — %, qui permet d'afficher le reste lors de la division de deux nombres. Si le reste est 0, cela signifie que le premier nombre est un multiple du second.
12 % 5 // 2 -> 12 n'est pas un multiple de 5
12 % 3 // 0 -> 12 est un multiple de 3
Ainsi, si on divise 12 par 5, on obtient 2 avec un reste de 2. Si on divise 12 par 3, on obtient 4 avec un reste de 0. Dans le premier cas, 12 n'est pas un multiple de 5, dans le second — 12 est un multiple de 3.
Solution
La solution optimale serait le code suivant :
const fizzBuzz = num => {
for(let i = 1; i <= num; i++) {
// vérifier si le nombre est un multiple de 3 et 5
if(i % 3 === 0 && i % 5 === 0) {
console.log('fizzbuzz')
} // vérifier si le nombre est un multiple de 3
else if(i % 3 === 0) {
console.log('fizz')
} // vérifier si le nombre est un multiple de 5
else if(i % 5 === 0) {
console.log('buzz')
} else {
console.log(i)
}
}
}La fonction effectue les vérifications nécessaires à l'aide d'opérateurs conditionnels et renvoie le résultat attendu par l'utilisateur. Dans cette tâche, il est important de prêter attention à l'ordre des opérateurs if…else : commencer par la double condition (&&) et se terminer par le cas où aucun nombre multiple n'a été trouvé. Ainsi, nous couvrons toutes les options.
Anagramme
C'est un mot qui contient toutes les lettres d'un autre mot dans la même quantité, mais dans un ordre différent.
Énoncé
Il faut écrire une fonction qui vérifie si deux chaînes sont des anagrammes, sans tenir compte de la casse. Seuls les caractères sont pris en compte ; les espaces ou la ponctuation ne sont pas considérés.
anagram('finder', 'Friend') -> true
anagram('hello', 'bye') -> false
Analyse de la tâche
Il est important de vérifier chaque lettre dans les deux chaînes d'entrée et leur fréquence dans chacune d'elles.
finder -> f: 1 friend -> f: 1
i: 1 r: 1
n: 1 i: 1
d: 1 e: 1
e: 1 n: 1
r: 1 d: 1
Pour stocker les données des anagrammes, il est conseillé de choisir une structure comme un objet littéral JavaScript. La clé dans ce cas serait le caractère de la lettre, la valeur — le nombre de ses occurrences dans la chaîne actuelle.
Il y a d'autres conditions :
- Il faut s'assurer que la casse des lettres n'est pas prise en compte lors de la comparaison. Il suffit de convertir les deux chaînes en minuscules ou en majuscules.
- Exclure de la comparaison tous les non-symboles. Il est préférable de travailler avec .
Solution
// helper function that builds the
// object to store the data
const buildCharObject = str => {
const charObj = {}
for(let char of str.replace(/[^w]/g).toLowerCase()) {
// if the object has already a key value pair
// equal to the value being looped over,
// increase the value by 1, otherwise add
// the letter being looped over as key and 1 as its value
charObj[char] = charObj[char] + 1 || 1
}
return charObj
}
// main function
const anagram = (strA, strB) => {
// build the object that holds strA data
const aCharObject = buildCharObject(strA)
// build the object that holds strB data
const bCharObject = buildCharObject(strB)
// compare number of keys in the two objects
// (anagrams must have the same number of letters)
if(Object.keys(aCharObject).length !== Object.keys(bCharObject).length) {
return false
}
// if both objects have the same number of keys
// we can be sure that at least both strings
// have the same number of characters
// now we can compare the two objects to see if both
// have the same letters in the same amount
for(let char in aCharObject) {
if(aCharObject[char] !== bCharObject[char]) {
return false
}
}
// if both the above checks succeed,
// you have an anagram: return true
return true
}Faites attention à l'utilisation de dans le snippet ci-dessus. Cette méthode renvoie un tableau contenant les noms ou les clés dans le même ordre qu'ils apparaissent dans l'objet. Dans ce cas, le tableau sera :
['f', 'i', 'n', 'd', 'e', 'r']
De cette manière, nous obtenons les propriétés de l'objet sans avoir à effectuer une boucle volumineuse. Ce procédé peut être utilisé avec la propriété .length pour vérifier si les deux chaînes contiennent le même nombre de caractères — c'est une caractéristique importante des anagrammes.
Recherche des voyelles
Une tâche assez simple, qui apparaît souvent lors des entretiens.
Énoncé
Il faut écrire une fonction prenant une chaîne en argument et renvoyant le nombre de voyelles contenues dans la chaîne.
Les voyelles sont «a», «e», «i», «o», «u».
Exemple :
findVowels('hello') // —> 2
findVowels('why') // —> 0
Solution
Voici la solution la plus simple :
const findVowels = str => {
let count = 0
const vowels = ['a', 'e', 'i', 'o', 'u']
for(let char of str.toLowerCase()) {
if(vowels.includes(char)) {
count++
}
}
return count
}Il est important de noter l'utilisation de la méthode .includes(). Elle est accessible à la fois pour les chaînes et les tableaux. Il est conseillé de l'utiliser pour vérifier si un tableau contient une certaine valeur. Cette méthode renvoie true si le tableau contient la valeur spécifiée, et false sinon.
Il existe également une solution plus concise au problème :
const findVowels = str => {
const matched = str.match(/[aeiou]/gi)
return matched ? matched.length : 0
}Ici, la méthode .match() est utilisée, ce qui permet de mettre en œuvre une recherche efficace. Si l'expression régulière en tant qu'argument de la méthode est trouvée dans la chaîne spécifiée, la valeur de retour devient un tableau de caractères correspondants. Sinon, .match() renvoie null.
Fibonacci
Une tâche classique que l'on peut rencontrer lors d'entretiens de différents niveaux. Il convient de rappeler que la séquence de Fibonacci est une série de nombres, où chaque nombre suivant est la somme des deux précédents. Ainsi, les dix premiers nombres sont les suivants : 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.
Énoncé
Il faut écrire une fonction qui renvoie le n-ème terme d'une séquence donnée, où n est le nombre passé en argument de la fonction.
fibonacci(3) // —> 2
Cette tâche implique de passer dans la boucle un nombre de fois spécifié par l'argument, en retournant la valeur à la position correspondante. Cette façon de poser le problème nécessite l'utilisation de boucles. Si vous utilisez la récursivité à la place, cela pourrait plaire à l'intervieweur et vous donner quelques points supplémentaires.
Solution
const fibonacci = num => {
// stocker la séquence de Fibonacci que vous allez
// générer dans un tableau et
// initialiser le tableau avec les deux premiers
// nombres de la séquence
const result = [0, 1]
for(let i = 2; i <= num; i++) {
// ajouter la somme des deux nombres
// précédant la position de i dans le tableau résultat
// à la fin du tableau résultat
const prevNum1 = result[i - 1]
const prevNum2 = result[i - 2]
result.push(prevNum1 + prevNum2)
}
// retourner la dernière valeur dans le tableau résultat
return result[num]
}Dans le tableau des résultats, les deux premiers nombres sont présents dans la rangée, car chaque entrée de la séquence est la somme des deux nombres précédents. Au tout début, il n'y a pas deux nombres que l'on peut prendre pour obtenir le nombre suivant, donc la boucle ne peut pas les générer automatiquement. Mais, comme nous le savons, les deux premiers nombres sont toujours 0 et 1. Par conséquent, on peut initialiser le tableau des résultats manuellement.
En ce qui concerne la récursivité, c'est à la fois plus simple et plus compliqué :
const fibonacci = num => {
// si le nombre est 0 ou 1, retourner le nombre
if(num < 2) {
return num
}
// récursivité ici
return fibonacci(num - 1) + fibonacci(num - 2)
}Nous continuons à appeler fibonacci(), en passant des nombres de plus en plus petits comme arguments. Nous arrêtons lorsque l'argument passé est égal à 0 ou 1.
Sortie
Vous avez probablement déjà rencontré l'une des tâches mentionnées si vous avez passé des entretiens pour un poste de développeur frontend ou JavaScript (surtout au niveau junior). Mais même si vous ne les avez pas rencontrées, elles peuvent être utiles à l'avenir — au minimum pour votre culture générale.
Skillbox recommande :
- Cours en ligne appliqué .
- Cours en ligne .
- Cours pratique d'un an .
Source : habr.com
