web-dev-qa-db-fra.com

Je connais très bien JavaScript, mais je bombarde les interviews de codage

Je suis donc actuellement à la recherche d'un nouveau poste de développeur front-end. Je connais très bien JavaScript et je peux m'exprimer poétiquement sur les fermetures, le currying, l'héritage prototypique, les modèles de conception, les performances des applications et l'architecture globale du front-end. Mais pourtant je finis toujours par bombarder des entretiens d'embauche. (Pour info, la plupart des emplois pour lesquels j'interviewe sont pour la construction de SPA avec une sorte de cadre MVC)

Habituellement, les tests de codage sont de petits extraits de code de choses que je ne rencontre jamais professionnellement. Comme écrire une fonction pour résoudre une sorte de problème mathématique. Mis à part la maladresse héritée d'essayer de coder tout en tenant le téléphone dans une main et en laissant un étranger voir votre écran et regarder chaque personnage que vous tapez, je ne vois généralement pas ce genre de choses dans le monde réel.

Est-ce une sérieuse compétence qui me manque ou les enquêteurs me posent-ils des questions non pertinentes? Je suppose que je devrais travailler sur ma programmation fonctionnelle et mes algorithmes, mais je n'ai pas trouvé beaucoup de bonnes ressources sur le Web (ou sur papier). Des suggestions?

33
Mike Fisher

L'écriture de code n'est qu'une partie du processus d'entrevue.

En fait, la résolution du problème logique n'est qu'une partie de la tâche d'écriture de code.

Les enquêteurs veulent être sûrs que:

  • Vous pouvez écrire du code. De nombreux candidats ayant dix ans d'expérience professionnelle dans une langue ne peuvent pas écrire de code du tout, et ce test vise à rejeter ces candidats.

  • Vous pensez à un problème avant d'écrire du code. Beaucoup sautaient sur leurs claviers, écrivaient des dizaines de lignes de code, puis trouvaient qu'ils avaient mal compris le problème d'origine, car ils n'avaient pas pris le temps d'y penser.

  • Vous êtes capable de vous adapter lors de l'écriture de code. Supposons que vous ayez trouvé une solution, mais lorsque vous avez commencé à la mettre en œuvre, il est apparu que votre première idée n'était pas la meilleure; pouvez-vous passer rapidement à un meilleur, éventuellement refactoriser le code que vous avez écrit?

Cela signifie également que ces entretiens devraient être plus interactifs . Au lieu de taper d'une seule main, achetez un kit mains libres ou appelez via Skype et utilisez un casque. Tapez pendant que vous tapez au travail, tout en commentant et en expliquant ce que vous faites: cela deviendra soudainement beaucoup moins gênant.

Avez-vous fait de la programmation par paires? Si oui, la situation de l'entretien est très similaire, sauf que l'intervieweur peut ne pas vous donner son avis, et vous ne lui demandez pas de changer de clavier avec vous lorsque vous avez terminé.

Voici quelques exemples d'un problème purement mathématique et comment il montre les compétences non mathématiques d'un développeur.

Exemple 1: simple codage exercice

Vous devez implémenter le calculateur de nombres de Fibonacci en JavaScript. Vous devriez pouvoir modifier l'index. La séquence de Fibonacci suit ces règles:

  1. Les deux premiers nombres de la séquence sont 0 et 1,
  2. Chaque numéro suivant est la somme des deux précédents.

Exemple: [~ # ~] f [~ # ~] = 0, [~ # ~] f [~ # ~]1 = 1, [~ # ~] f [~ # ~]2 = 1, [~ # ~] f [~ # ~]3 = 2, [~ # ~] f [~ # ~]dix = 55.

Vous avez trois minutes.

Ici, l'intervieweur souhaite que vous réfléchissiez le plus rapidement possible, trouviez la solution et la mettiez rapidement en œuvre. Un tel exercice n'est pas lié à ce que font les développeurs réels et est beaucoup plus proche de ce que vous pouvez trouver en faisant un diplôme CS, mais les enquêteurs aiment ce genre de choses, alors faisons-le. De plus, la contrainte de temps rend impossible tout test automatisé, donc l'intervieweur ne s'attend probablement pas à cela de votre part.

"La description de l'algorithme me fait penser à la récursivité. La deuxième règle conduit à la fonction récursive suivante. "

var fibonacci = function (n) {
    return fibonacci(n - 2) + fibonacci(n - 1);
};

console.log(fibonacci(10));

"Pour mettre fin à la récursivité, nous ajouterons les cas spéciaux en remplaçant le corps de la fonction fibonacci."

switch (n) {
    case 0: return 0;
    case 1: return 1;
    default: return fibonacci(n - 2) + fibonacci(n - 1);
}

"Terminé."

Conclusion

Comme je l'ai dit, un tel exercice n'a aucun rapport avec le travail réel d'un développeur. Cela le rend-il vide de sens? Pas vraiment, car au moins, cela montre que la personne:

  • Est capable de penser à un problème. Certains candidats seront totalement perdus et, sous le stress, prendront plus que le temps alloué juste pour réfléchir à une manière possible d'aborder le problème.

  • Connaît la récursivité ou est capable de contourner la récursivité à travers une boucle ordinaire. Plus tard, l'intervieweur peut demander s'il existe des moyens d'utiliser/de ne pas utiliser la récursivité, et quels sont les avantages/inconvénients de la récursivité.

  • Connaît les bases du langage de programmation. Peu importe si la personne a utilisé switch, une clause de garde, une conditionnelle ou n dictionnaire : selon le contexte, différents candidats choisiront différents outils pour accomplir la même chose.

  • Reste concentré sur le problème, sans apporter de choses comme les tests unitaires, l'évolutivité ou les performances. L'intervieweur peut alors demander pourquoi, en termes de performances, la fonction ci-dessus est terrible, en s'attendant à ce que le candidat explique ce qui doit être fait pour amener les performances à un niveau raisonnable.

Exemple 2: questions délicates

Vous devez implémenter le calculateur de nombres de Fibonacci en JavaScript. Il devrait être aussi rapide que possible. Vous devriez pouvoir changer l'indice allant de 0 à 100. La séquence de Fibonacci suit ces règles:

  1. Les deux premiers nombres de la séquence sont 0 et 1,
  2. Chaque numéro suivant est la somme des deux précédents.

Exemple: [~ # ~] f [~ # ~] = 0, [~ # ~] f [~ # ~]1 = 1, [~ # ~] f [~ # ~]2 = 1, [~ # ~] f [~ # ~]3 = 2, [~ # ~] f [~ # ~]dix = 55.

Vous avez trois minutes.

Maintenant, nous avons une contrainte intéressante qui montre que l'intervieweur ne se soucie pas vraiment de la capacité du candidat à résoudre des problèmes, mais plutôt de sa capacité à deviner quels moyens sont plus rapides que d'autres.

Ces questions délicates invitent généralement à des réponses délicates. Ici, compte tenu des contraintes de temps, il n'y a aucun moyen de faire plusieurs implémentations, de les comparer, de profiler la plus rapide et de proposer une solution optimale.

Au lieu de cela, qu'en est-il:

"Laissez-moi Google" Premiers numéros de Fibonacci "... Ce semble prometteur. Avec un facile (ce serait un oxymore) expression régulière, nous pouvons construire une liste de valeurs séparées par des virgules. "

sed -e "s;\([0-9]*\) \([0-9]*\);'\2',;g" fbncc10.txt | tr '\n' ' '

"Enfin, le programme lui-même."

var map = ['0', '1', '1', '2', '3', '5', '8', '13', '21', '34', '55', '89', '144', '233', '377', '610', '987', '1597', '2584', '4181', '6765', '10946', '17711', '28657', '46368', '75025', '121393', '196418', '317811', '514229', '832040', '1346269', '2178309', '3524578', '5702887', '9227465', '14930352', '24157817', '39088169', '63245986', '102334155', '165580141', '267914296', '433494437', '701408733', '1134903170', '1836311903', '2971215073', '4807526976', '7778742049', '12586269025', '20365011074', '32951280099', '53316291173', '86267571272', '139583862445', '225851433717', '365435296162', '591286729879', '956722026041', '1548008755920', '2504730781961', '4052739537881', '6557470319842', '10610209857723', '17167680177565', '27777890035288', '44945570212853', '72723460248141', '117669030460994', '190392490709135', '308061521170129', '498454011879264', '806515533049393', '1304969544928657', '2111485077978050', '3416454622906707', '5527939700884757', '8944394323791464', '14472334024676221', '23416728348467685', '37889062373143906', '61305790721611591', '99194853094755497', '160500643816367088', '259695496911122585', '420196140727489673', '679891637638612258', '1100087778366101931', '1779979416004714189', '2880067194370816120', '4660046610375530309', '7540113804746346429', '12200160415121876738', '19740274219868223167', '31940434634990099905', '51680708854858323072', '83621143489848422977', '135301852344706746049', '218922995834555169026', '354224848179261915075'];

var fibonacci = function (n) {
    return map[n];
};

console.log(fibonacci(10));

Conclusion

Les questions délicates invitent à des réponses délicates. Ne soyez pas héroïque et ne commencez pas l'analyse comparative et le profilage lorsque vous n'avez que trois minutes. Pensez à des façons intelligentes de résoudre le problème tout en utilisant votre expérience. Mon expérience me donne un indice que l'utilisation d'une carte peut être plus rapide que le calcul du nombre. Cela peut être faux, mais cette tentative est à prévoir compte tenu de la contrainte de temps.

Connaître vos outils aide également et est une partie essentielle des compétences des développeurs: sans connaître les expressions régulières, je passerais les trois minutes allouées à rechercher une liste séparée par des virgules ou commencerais à écrire un analyseur qui construira le tableau dont j'ai besoin.

N'oubliez pas qu'un bon développeur n'est pas celui qui commence à coder tout de suite, mais qui sait comment éviter de coder lorsqu'une meilleure opportunité est disponible. Certains intervieweurs n'hésiteront pas à vous donner des devoirs qui ressemblent à des codages, mais qui ne nécessitent presque aucun code.

Exemple 3: application complète développement

Vous devez implémenter la séquence de Fibonacci en JavaScript. La longueur de la séquence est déterminée lors de l'exécution du programme. La séquence suit ces règles:

  1. Les deux premiers nombres de la séquence sont 0 et 1,
  2. Chaque numéro suivant est la somme des deux précédents.

Exemple: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.

L'application doit être présentée comme une page Web, permettant à l'utilisateur de spécifier la longueur de la séquence via un champ de saisie.

Vous avez une heure.

Commençons.

"L'exemple de séquence est très utile, car il me permettra d'avoir un tas de tests unitaires pour m'assurer que mon implémentation ne semble pas complètement fausse. En général, j'utilise Mocha pour node.js ou QUnit pour JavaScript côté client, mais ici, par souci de simplicité, je vais simplement lancer un tas de fonctions de test. "

"Je commence par créer des fichiers index.htm Et fib.js. Ensuite, je remplis index.htm De code vraiment minimaliste et non conforme au W3C (nous pourrons y revenir plus tard si vous êtes également intéressé par mes compétences HTML). "

<label>Length</label> <input id="length" value="15" />
<input id="compute" type="button" value="Compute" />
<div id="result" style="font-weight:bold;"></div>
<div id="tests"></div>
<script src="fib.js"></script>

"Écrivons maintenant du code qui appellera la fonction générateur de Fibonacci et affichera les résultats."

fibonacci = (function () {
    var compute,
        init;

    compute = function (length) {
        // TODO: Implement Fibonacci sequence.
        return [1, 2, 3];
    };

    init = function () {
        var button = document.getElementById('compute');
        button.addEventListener('onclick', function () {
            var length = parseInt(document.getElementById('length').value, 10),
                result;

            console.log(
                'Computing Fibonacci sequence of length ' + length + '.'
            );

            result = compute(length);
            document.getElementById('result').innerText = result.join(', ');
        });
    };

    return {
        compute: compute,
        init: init
    };
}());

"Il est temps d'exécuter le code pour la première fois et ... cela ne fonctionne pas. Rien ne se passe. Pourquoi?"

"OK, j'ai oublié la fibonacci.init(); à la fin. Je l'ai ajouté, et pourtant, rien ne se passe, alors qu'il devrait au moins afficher le message dans la console. Attendez, c'est vrai, ce n'est pas onclick, mais click; J'utilise JQuery si souvent que je commence à oublier les noms des événements en JavaScript simple. "

"Ajoutons quelques tests."

ensureAreEqual = function (expected, actual) {
    var testResultsContainer = document.getElementById('tests');
    testResultsContainer.innerText += (expected.equals(actual) ?
            '.' :
            ('Actual [' + actual.join(', ') + '] is different from ' +
             'expected [' + expected.join(', ') + '].'));
};

test = function () {
    ensureAreEqual([0], compute(1));
};

"La comparaison des tableaux peut être délicate, donc je viens de copier-coller le code Array.prototype.equals De cette réponse ."

"Maintenant que nous exécutons l'application, elle affiche:"

[1, 2, 3] réel est différent de [0] attendu.

"Le test a échoué, ce qui était très attendu, étant donné notre implémentation réelle (return [1, 2, 3];) De la séquence de Fibonacci. Il est temps de changer cela. "

"A partir de l'instruction d'origine, la séquence de Fibonacci commence par [0, 1], Donc compute devient:"

compute = function (length) {
    var fib = [0];
    return fib;
};

"Cela permet de passer le premier test, et nous pouvons maintenant écrire notre deuxième."

ensureAreEqual([0, 1], compute(2));

"Il échoue, donc nous revenons à compute et le modifions."

compute = function (length) {
    var fib = [0, 1];
    return length === 1 ? [0] : fib;
};

"Maintenant, les deux tests réussissent, et il est temps de passer à des cas non-Edge."

compute = function (length) {
    var fib = [0, 1],
        i,
        next,
        current = 1,
        previous = 0;

    for (i = 2; i < length; i += 1) {
        next = current + previous;
        previous = current;
        current = next;
        fib.Push(next);
    }

    return length === 1 ? [0] : fib;
};

"Les trois tests réussissent maintenant, sauf que le résultat ne semble pas correct pour des longueurs plus grandes telles que 100. Pour obtenir ces résultats correctement, nous aurions dû utiliser une bibliothèque de précision arbitraire . Il y a aussi des choses à améliorer. Par exemple, les conventions de dénomination sont parfois trop mauvaises (qu'est-ce que fib?). Le code JavaScript lié au HTML doit également aller vers un autre objet, ainsi que tester le code. De plus, je n'ai pas testé compute(0) et je n'ai pas vérifié les entrées. "

Conclusion

En parcourant l'exemple, vous pouvez voir l'interaction attendue lors d'une entrevue. Tout n'a pas été fluide (j'ai fait plusieurs erreurs au début, ce qui m'a conduit à une situation embarrassante où rien ne se passe lorsque je lance l'application), et l'approche originale était boiteuse si nous devons prendre en charge une grande longueur de séquence, mais j'ai réussi montrer que:

  • Je peux gérer différents problèmes,
  • J'utilise le développement piloté par les tests, la séquence de Fibonacci étant une excellente opportunité pour cela,
  • Je copie-colle du code lorsque la source est fiable et l'écrire à partir de zéro semble extrêmement compliqué et sujet aux erreurs,
  • Je ne compte pas trop sur des bibliothèques telles que JQuery,
  • J'ai choisi la bonne portée: puisque l'intervieweur veut vérifier mes compétences JavaScript, je ne perdrai pas de temps à écrire du HTML parfait et propre: ne pas passer de temps ici permet de passer plus de temps à écrire des tests unitaires,
  • Je sais quand terminer et dire que j'ai fini, tout en gardant à l'esprit qu'un tas de choses ne sont pas parfaites (comme compute(0) qui échouera, mais cela n'a pas d'importance pour la démo).

C'est exactement ce qu'un enquêteur doit attendre de vous.

52
Arseni Mourzenko