Le guide ultime des questions d'entretien d'embauche

Questions d'entretien en Python

Pour réussir dans les métiers du développement, il faut non seulement maîtriser l'art de passer des entretiens, mais aussi l'art de les faire passer. En tant que développeur Python, vous devez être capable de répondre à toutes les questions que l'on vous pose en entretien avec assurance et fluidité. En tant que recruteur, vous devez être capable de formuler une liste complète de questions, en rapport avec la description du poste. N'attendez pas d'un jeune diplômé qu'il vous brosse le tableau global de l'architecture du système que vous envisagez et ne cherchez pas à évaluer pas la pertinence d'un architecte en lui posant des questions sur la syntaxe.

Python est un langage efficace et élégant, avec des frameworks stables, évolutifs et réputés comme Django, Flask et Pyramid, utilisés par une communauté en constante croissance. Voici quelques questions qui vous aideront à appréhender la plupart des fondamentaux de Python lors d'un entretien avec un recruteur :

1. Expliquez brièvement le processus d'exécution d'un fichier Python ?

Réponse :

Python est un langage interprété. L'interpréteur Python, en coulisse, convertit votre code source en bytecode (fichiers .pyc), puis les exécute pour vous.

Réponses alarmantes :

  1. Pas sûr·e de la différence entre la compilation et l'interprétation.
  2. Aucune connaissance des fichiers .pyc et/ou de leur différence avec les fichiers .py.

2. Nous savons que Python est un langage orienté objet, mais a-t-il des spécificateurs d'accès ?

Réponse :

Non. Python est un langage moderne orienté objet qui considère l'utilisation de spécificateurs d'accès (par exemple, privé et public en C++) comme dépassée et redondante.

Réponses alarmantes :

  1. Je ne sais pas ce que sont les spécificateurs d'accès.

3. Comment fonctionne l'opérateur ternaire en Python ? Peut-on assigner une valeur à une variable à l'intérieur d'un opérateur ternaire ?

Réponse :

L'ordre des arguments dans l'opérateur ternaire de Python est différent de celui de la plupart des langages, où l'on écrit d'abord la condition, puis les deux expressions. En Python, il faut l'écrire : A si condition sinon B.

L'exécution est court-circuitée de telle sorte que seul A est évalué si la condition est vraie, et seul B est exécuté, au cas où elle serait fausse.

Pour la deuxième partie : Non, les affectations ou les déclarations (par exemple : pass) ne peuvent pas être utilisées au sein d'un opérateur ternaire.

Réponses alarmantes :

  1. "Oui" à la deuxième partie de la question.

4. Pouvez-vous expliquer comment une exception peut être attrapée dans un programme Python ?

Réponse :

En entourant votre code entre les mots-clés try et except . Vous pouvez soit utiliser les exceptions intégrées de Python, soit définir une nouvelle classe d'exception. Vous pouvez également soulever une exception dans un cas spécifique en utilisant le mot-clé raise .

Réponses alarmantes :

  1. Aucune mention de l'essai et sauf des mots-clés.

5. Comment testeriez-vous un code Python ?

Réponse :

Python a quelques modules sympas pour écrire des tests comme unittest et Doctest qui sont fournis avec la bibliothèque standard de Python. Vous pouvez également utiliser des outils tels que py.test, Hypothesis, mock, tox et Unittest2.

Réponses alarmantes :

  1. N'est pas capable de mentionner au moins 2 ou 3 noms parmi ceux mentionnés ci-dessus.

6. Que sont les blocs Python et comment les définir ?

Réponse :

Le code source Python est organisé en définissant des blocs par indentation. Les blocs peuvent contenir des blocs et peuvent eux-mêmes faire partie de blocs plus importants.

Réponses alarmantes :

  1. Pas d'insistance sur la signification de l'indentation.

7. Si vous devez choisir entre une liste, un ensemble et un dictionnaire pour stocker 10 millions d'entiers, qu'allez-vous utiliser ? N'oubliez pas que vous souhaiterez plus tard interroger la fréquence d'un nombre dans l'ensemble de données.  

Réponse :

Comme nous devons tenir compte des occurrences multiples d'un nombre, nous ne pouvons pas choisir un ensemble, car il ne stocke pas les doublons par conception.

Pour trouver la fréquence d'un numéro dans une liste, vous devrez l'itérer complètement, ce qui rendra la recherche O(n) complexe et inefficace.

Un dictionnaire vous permet cependant de stocker des paires clé-valeur. Vous pouvez enregistrer un nombre comme clé et le nombre de fois qu'il a été enregistré comme valeur. De cette façon, chaque fois que vous voulez interroger la fréquence, vous pouvez obtenir le résultat dans O(1). Un dictionnaire est donc le meilleur choix dans ce cas particulier.

Réponses alarmantes :

  1. Choisit l'ensemble.
  2. Cela n'explique pas les processus de base de stockage et d'interrogation associés à chaque type de données.

8. Veuillez énumérer quelques différences entre les listes et les tuples en Python.

Réponse :

Les listes Python sont mutables, tandis que les Tuples ne peuvent pas être éditées.

Les tuples peuvent être définis avec une liste d'entiers séparés par des virgules, avec ou sans parenthèses. D'autre part, les listes sont définies par des crochets ou en utilisant le constructeur de liste.

Réponses alarmantes :

  1. Aucune mention de la différence de mutabilité.

9. Quand devez-vous utiliser la copie superficielle au lieu de la copie profonde, et vice versa ?

Réponse :

Lorsque vous faites une copie superficielle, un nouvel objet est créé et il conserve les pointeurs de référence de l'objet original. Comme le processus de copie superficielle n'est pas récursif, les copies des objets enfants originaux ne sont pas créées. En gros, vous avez donc deux objets qui partagent le même ensemble d'éléments. Cela signifie que toute modification apportée à l'objet copié se reflète instantanément dans l'objet original.

Dans le cas d'une copie profonde, cependant, un processus de copie récursif est effectué, et des copies de tous les objets enfants sont créées. Ainsi, si vous apportez une modification à l'objet copié, elle ne se reflétera pas dans l'objet original.

Le moment et la raison pour lesquels vous devriez choisir l'un ou l'autre dépendent du cas d'utilisation, mais il est primordial que vous compreniez le fonctionnement interne des deux processus.

Réponses alarmantes :

  1. Impossible d'expliquer de manière cohérente comment la mémoire des deux copies est gérée.

10. Qu'est-ce qu'une compréhension de liste et pourquoi l'utiliser, le cas échéant ?

Réponse :

La compréhension des listes est un excellent moyen de définir des listes où chaque élément résulte en fait d'une opération effectuée sur chaque élément d'une autre liste ou d'une séquence. Par exemple, si vous voulez stocker une liste de carrés des 10 premiers nombres premiers, vous pouvez utiliser la compréhension de liste pour le faire. Cependant, la compréhension de liste ne doit pas être utilisée pour des itérations triviales comme l'impression de valeurs, etc. Ne les utilisez que si vous voulez construire une liste résultante qui contient les valeurs mises à jour.

Réponses alarmantes :

  1. N'a pas su préciser quand utiliser ou ne pas utiliser les compréhensions de liste.

11. Que savez-vous du verrouillage global de l'interpréteur ?

Réponse :

Le Global Interpreter Lock, alias GIL, est un mutex qui empêche plusieurs threads d'exécuter simultanément le bytecode Python. Ce verrou est nécessaire parce que la gestion de la mémoire dans CPython n'est pas sûre pour les threads. Cela peut empêcher les applications multi-threads d'utiliser plusieurs CPU et constitue donc un goulot d'étranglement. Cependant, toutes les opérations ne sont pas concernées par le GIL, comme les opérations d'entrée/sortie ou certains calculs effectués dans les bibliothèques (par exemple numpy).

Réponses alarmantes :

  1. Jamais entendu parler.

12. Is None ou == None, que devez-vous utiliser et pourquoi ? Y a-t-il une différence entre les opérateurs == et is?

Réponse :

Oui, il y a une différence entre == et est. Le premier vérifie l'équivalence et le second vérifie si les deux objets spécifiés sont effectivement identiques.

Cela étant dit, dans le cas de None, il n'y a pas de différence entre les deux. Pourquoi ? Parce qu'il n'y a qu'un seul objet " None ".

En règle générale, il faut utiliser la méthode "Is None".

Réponses alarmantes :

  1. Ne mentionne aucun des trois points ci-dessus.

13. Quelle serait la sortie de ce code ?

def f(a,list=[]):
    for i in range(a):
        list.append(i*i)
    print(list) 
 
f(3)
f(2,[1,2,3])
f(2) 

[0, 1, 4] [1,2,3,0,1] [0, 1, 4, 0,1]

L'élément clé à retenir ici est que l'objet liste n'est créé qu'une fois, lorsque la fonction est définie. Au premier et au troisième appel, l'objet liste est le même. Cependant, lors du deuxième appel, nous avons utilisé un autre objet pour l'argument liste.

Réponses alarmantes :

  1. Je ne savais pas que la valeur par défaut de l'argument "liste" n'était créée qu'une seule fois.

14. Dans une fonction, quelle est la signification de *args et **kwargs ?

Réponse :

L'astérisque *args est utilisé dans la définition d'une fonction lorsque vous n'êtes pas sûr·e du nombre d'arguments que vous pourriez avoir à passer à une certaine fonction.

Le double astérisque **kwargs vous permet d'envoyer des arguments chiffrés à une fonction, qui peut contenir autant d'arguments que vous le souhaitez.

Réponses alarmantes :

  1. Il ne mentionne pas la différence entre les deux.

15. Quelle serait la sortie de ce code ?

list = ['1',2', '3', '4', '5']
print (list[12:]) 

Répondez : Le résultat serait [] et non une erreur d'index. Cela est dû au fait que nous essayons de récupérer la tranche et que nous ne spécifions que l'index de départ.

Réponses alarmantes :

  1. N'importe quelle erreur.

16. Veuillez indiquer quelques différences entre Python 2.x et 3.x ?

Réponse :

Il y a plus de changements/mises à jour en Python 3 qu'on ne peut en mentionner, mais voici les plus connus :

  1. Modification de la syntaxe d'impression.
  2. Modification du comportement de la division des nombres entiers. Par exemple, 3/2 = 1 en Python 2 contre 1,5 en Python 3.
  3. Introduction de l'Unicode et des classes à deux octets.
  4. Une nouvelle méthode "__contient__" pour l'objet de portée, qui permet de fixer le processus de recherche.
  5. Application de la nouvelle syntaxe pour soulever les exceptions ; c'est-à-dire que vous obtiendrez une erreur si vous n'entourez pas l'argument de l'exception de parenthèses.
  6. Dépréciation de la méthode .next(). Seule la fonction next reste.
  7. Une erreur de type est maintenant soulevée à juste titre chaque fois que deux types non ordonnés sont comparés.

Réponses alarmantes :

  1. Incapacité à identifier au moins 3,4 différences entre les deux versions (en particulier si vous interrogez une ressource expérimentée).

17. Quelles sont les raisons de ne pas aimer Python ?

Réponse :

Cette question est importante car elle fait réfléchir le/la candidat·e. Il n'y a pas d'unanimité concernant les réponses, mais un développeur Python expérimenté et impartial aura toujours quelque chose à dire. Si jamais Python ne plaît réellement pas à une personne, elle pourra vous expliquer avec véhémence ce qu'elle n'aime pas (ou comprendre ce que certaines personnes n'aiment pas) à propos du langage.

Voici quelques exemples de sujets qui pourraient être abordés par le/la candidat·e :

  1. La compatibilité avec Python 2 est un problème, alors que la version 3 a été publiée il y a plus de 10 ans.
  2. L'utilisation de l'espace pour définir les blocs.
  3. GIL.
  4. Dactylographie dynamique.

Réponses alarmantes :

  1. "Rien qui ne me vienne à l'esprit".

Le mot de la fin

Cette liste comprenait une série de questions faciles, délicates et difficiles. Elle devrait donc vous permettre d'évaluer astucieusement le niveau d'expérience de la plupart des candidats. Encore une fois, ne prenez pas la décision finale en vous basant sur le manque de familiarité d'une personne avec des choses triviales comme certaines limitations linguistiques ou syntaxiques, car elles ne sont pas difficiles à apprendre (Python est plus facile que PHP!). Ce que vous devez savoir, c'est s'ils sont capables ou non de distinguer le bien du mal, lorsqu'ils écrivent (ou conçoivent) le code de votre application. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est de procéder à une évaluation pratique de la programmation.