Suite et fin d'une série d'article relatant mon expérience avec les entretiens d'embauche "du bon côté" du bureau. Cette fois-ci, les réponses au formulaire !

Questionnaire

Ces questions permettent de vous situer vis à vis de la programmation et de l'informatique en général. Il est normal de ne pas tout connaître ; )

Écriture et lecture de code

Que fait la requête SQL suivante :

SELECT Marque, AVG(Prix)
FROM Produits
GROUP BY Marque

La requête récupère, pour chaque marque, le prix moyen des produits de la marque.
Objectivement, ce n'est pas du SQL de haut niveau ou propriétaire ; et pourtant j'ai vu des gens qui exhibaient fièrement leur "certification Oracle" échouer sur cette question. Ça pose les bases pour le reste du questionnaire !

En javascript (ou un framework JS que vous préciserez), comment peut-on récupérer un objet par son identifiant (attribut id en HTML) ?

/**
 * Récupère un objet par son identifiant
 * 
 * @param string id l'identifiant recherché
 * @return DOMElement l'élément d'identifiant correspondant
 */
function getById(id)
{
	//En pur Javascript, en utilisant l'API DOM :
   return document.getElementById(id);
   //En jQuery :
   return $('#' + id);
}

Que fait l'expression CSS suivante ? Pouvez-vous donner un fragment de code HTML sur lequel elle s'appliquerait ?

#space .space_list  a:hover{
	background:#777777;
}

La question était un peu piège, car on peut croire que space et space_liste sont des mots clés réservés – cela dit, n'importe quelle personne qui a écrit au moins une feuille de style CSS pourrait dire que "ce sélecteur applique la couleur #777777 lorsque la souris passe sur un élément de type <a> contenu dans un balise de classe space_liste elle-même contenue dans un balise d'identifiant space". Bonus si on me disait que la couleur pouvait se simplifier en #777. On pouvait aussi me dire que c'était du gris (mais je conçois qu'on n'apprenne pas par cœur les codes héxadécimaux). Malus si on me disait que :hover voulait dire "un élément caché" (pas compris celle-là, mais on me l'a sorti deux fois. Des idées ?)

Pouvez-vous rédiger en PHP (ou autre si inconnu) une fonction prenant un tableau en paramètre et renvoyant la somme des éléments de tableau ?

D'un point de vue logicien, la réponse à cette question est "Oui" (== oui, je peux). Mais on s'en doute, j'en demandais un petit peu plus ;)

<?php
/**
 * Calcule la somme des valeurs du tableau.
 *
 * @param array $tableau le tableau sur lequel effectuer la somme
 *
 * @return int la somme
 */
function somme_tableau(array $tableau)
{
	$somme = 0;
	foreach($tableau as $element)
	{
		$somme += $element;
	}
	
	return $somme;
}

Les solutions dans d'autres langages, avec des for, voire même en oubliant le return final ou les point-virgules étaient acceptées.
Je ne me souciais pas du guide de style (variables en anglais / français, positionnement des accolades, présence d'espaces avant / après les parenthèses).
Sérieusement, cette question vous paraît dure ? Pour moi, c'est la base de n'importe quel langage et n'importe quelle personne qui marque "programmeur" sur son CV devrait savoir faire. Et pourtant... c'était loin d'être le cas.

Pouvez-vous rédiger en PHP (ou autre si inconnu) une classe modélisant un utilisateur (propriétés et fonctions à votre discrétion) ?

<?php
class Utilisateur
{
	protected $login;
	protected $password;
	
	public function __construct($login, $password)
	{
		$this->login = $login;
		$this->password = $password;
	}
	
	public function getLogin()
	{
		return $this->login;
	}
	
	public function setLogin($login)
	{
		$this->login = $login;
	}
	
	//...
}

Cette question bidon permet juste de vérifier que le concept de classe est connu. Je ne m'attendais pas à des miracles où à un code de deux cent lignes : juste les bases. La réponse ci-dessus me convenait, avec bonus pour des fonctions documentées ou un hashage du password -- mais encore une fois, la solution simple au-dessus suffisait.

Et pourtant ! J'ai vu de tout et n'importe quoi -- une fois questionné, le gars finissait par avouer qu'il n'avait jamais fait de POO.
Mention spéciale pour la réponse suivante :

class Utilisateurs
	return date('d/M/Y');

Si quelqu'un la comprend, je veux bien qu'il m'explique !

Pouvez-vous rédiger en PHP (ou autre si inconnu) un programme affichant tous les nombres de 1 à 50, en remplaçant les multiples de 3 par ping, les multiples de 5 par pong et les multiples de 3 et 5 par ping pong ?

<?php
for($i = 1; $i < 50; $i++)
{
	if($i % 15 == 0)
	{
		echo 'pingpong';
	}
	else if($i % 3 == 0)
	{
		echo 'ping';
	}
	else if($i % 5 == 0)
	{
		echo 'pong';
	}
	else
	{
		echo $i;
	}
	echo '
'; }

C'est la question de Coding Horror francisée, et en soi il n'y a pas de réel problème.
D'accord, il y a quelques chausses-trappes (et des solutions plus élégantes que je vous laisse rechercher !), mais dans l'ensemble c'est une problématique que l'on rencontre souvent en développement ; sur le web ou ailleurs : mettre une ligne sur deux d'un tableau d'une certaine couleur, itérer entre plusieurs joueurs... la connaissance du modulo est précieuse.

Bonus pour ceux qui faisaient une solution plus élégante ou plus concise.
Le <br /> pouvait être absent ou un autre séparateur (\n, PHP_EOL...).
Pas de malus pour ceux qui mettaient le modulo 15 après les modulos 3 et 5 (ça ne fonctionne pas, mais l'idée est là).
Pas de malus pour ceux qui ignoraient comment faire un modulo dans le langage choisi mais qui connaissaient le nom ou l'idée mathématique derrière.

Écrivez une expression régulière basique permettant de valider une date de naissance (au format JJ/MM/AAAA)

Regexp : ^[0-9]{2}/[0-9]{2}/[0-9]{4}$. Toutes les autres solutions étaient aussi acceptées (sans les ^ et $, avec des classes de caractères, avec une meilleure précision (validation partielle du mois), avec parenthèses capturantes...). Et pourtant, personne ne l'a eu juste. J'avoue être surpris, car je me sers régulièrement des expressions éponymes (!).

Que pensez-vous du code suivant ?

<?php
$v = $_GET["prenom"];
echo "Bonjour $v !";

include('sql_connect.php');

$reply = mysql_query("INSERT INTO Visiteurs VALUES('" . $v . "')");

include('../../pages/' . $v . '.html');
die();

Olà. Olà. J'ai vu tout et n'importe quoi. "Ça affiche 'bonjour'". "Ça crée un membre".
D'accord, ce n'est pas vraiment faux (et encore), mais ce n'était pas le but de la question ! Voici les commentaires qu'on pouvait faire (ce qui me passe par la tête, on peut probablement en dire encore plus) :

<?php
$v = $_GET["prenom"];
//Nom de variable peu explicite

echo "Bonjour $v !";
//Utilisation de double-quotes et remplacement dans les double-quotes : lent et déconseillé (en plus d'un potentiel XSS, $v venant de $_GET)

include('sql_connect.php');
//include n'est pas une fonction, mais un mot-clé et ne doit donc pas être entouré de parenthèses. Enfin... je dis ça, mais il m'arrive d'en mettre quand ça clarifie ou quand je récupère une variable en retour.

$reply = mysql_query("INSERT INTO Visiteurs VALUES('" . $v . "')");
//Une des lignes les plus critiques !
//1 : injection SQL. On peut faire tout et n'importe quoi avec la base de données avec ça... c'est une des leçons de base de n'importe quel tuto PHP : never trust user input !
//2 : mysql_* est une API qui commence à vraiment dater...

include('../../pages/' . $v . '.html');
//Inclusion de n'importe quel fichier du serveur oO

die();
//die() est déprécié au profit d'exit().

Bon, la plupart des remarques c'est du chipotage. Les vrais problèmes sont bien entendus l'injection SQL et l'inclusion de fichiers... ça devrait sauter aux yeux de n'importe quel web-développeur.

Écrivez en pseudo-algorithme un code calculant de façon récursive la factorielle d'un nombre n.

Pour rappel, factorielle(5) = 5 * 4 * 3 * 2 * 1.

fonction factorielle(n)
	si n == 0
		renvoyer 1
	sinon
		renvoyer n*factorielle(n-1)

Question classique de récursivité...

Connaissances informatiques

En programmation orientée objet, quelle est la particularité d'une classe abstraite ?

Ahaha ! Encore une fois j'en ai vu des vertes et des pas mûres. La bonne réponse est bien sûre qu'elle ne peut pas être directement instanciée, et qu'il faut l'étendre avec une ou des classes filles pour implémenter les méthodes abstraites.

Rapidement, comment représenter des données hiérarchiques dans une base de données ?

Par exemple, un arbre de catégories : une catégorie principale qui peut avoir un ou plusieurs enfants, qui peuvent eux-même avoir un ou plusieurs enfants, etc.

Là, je suis resté estomaqué. Je m'attendais à deux réponses : la propre et la sale, et même la sale me convenait.
Et pourtant, peu savaient faire ça... pas même la fan de BDD citée plus haut :D

  • Solution sale : on met une clé étrangère parent sur la table Categories qui contient la catégorie parente, et null pour la racine. Schéma de la table : Categories[Categorie NOT NULL, Parent].
  • Solution propre 1 : on utilise la représentation intervallaire (nested sets). Je ne demandais même pas d'explications mathématiques sur le principe !
  • Solution propre 2 : on utilise CTE (mais pas sous MySQL :()

Quand peut-on dire d'un graphe qu'il admet un parcours hamiltonien ?

Ok, cette question était une blague ;) Cela dit, on m'a dit que c'était "le plus court chemin" plusieurs fois. En fouillant un peu, j'en suis arrivé à la conclusion qu'il s'agissait d'une confusion avec Djikstra.

Comment quitte-t-on l'éditeur de texte vi ?

Pour cette question et la suivante, je n'attendais qu'une seule bonne réponse, car il me paraissait normal de ne pas maîtriser Windows et Linux. Et effectivement, tout le monde connaissait la réponse à l'une ou l'autre.
Pour la réponse : echap suivi de ":q" ou ":wq" ou ":q!"

Comment ouvrir une console sous Windows et afficher son adresse IP (sur Internet et/ou sur la box) ?

Démarrer, [exécuter,] cmd, ipconfig.

Quelle est la complexité (en notation grand O) d'un algorithme affichant tous les nombres de 1 à n, en remplaçant les multiples de 3 par ping, les multiples de 5 par pong et les multiples de 3 et 5 par ping pong ? (cf. questions code)

Info Flash : la complexité n'est au programme de quasi aucune école. Info flash : la réponse est simple, O(n).

Quelle entreprise possède Youtube ?

J'ai eu quelques remarques de collègues sur la pertinence de cette question, mais elle me paraissait une bonne façon de sonder les connaissances informatiques générales de la personne en face de moi. La réponse est Google – tout le monde le savait.

En MVC, qui effectue les requêtes SQL permettant de récupérer un objet dont une des propriétés devra être affichée ?

Mouarf. Entre ceux qui ne savaient pas ce qu'était MVC et ceux qui répondaient "C" ou "V"...
Ah, la question n'est pas claire ? Exact. Mais j'acceptais toutes les réponses si elles étaient bien justifiées !

Quel nombre suit F en hexadécimal ?

"Aucun". Ah bon ? "0". Ah bon ? "9". "Ah bon ?". Et 10, ça ne tente personne ?

$\sum_{i=0}^{\infty} \frac{1}{i^2} = ?$

Deuxième question "inutile", permettant à la fois de voir si la personne maîtrisait LaTeX et si elle s'y connaissait un peu en maths. Je n'en tenais pas compte, c'était de la pure curiosité.

Bonus

You're the captain of a pirate ship and your crew gets to vote on how the gold is divided up. If fewer than half of the pirates agree with you, you die. How do you recommend apportioning the gold in such a way that you get a good share of the booty, but still survive ?

Question honteusement volée à Google, qui permettait aussi de tester le niveau d'anglais (basique !). Comparativement aux autres questions posées par Google, celle-ci était assez simple... même si j'ai eu droit à des réponses surprenantes : "je me casse avec le trésor". Et après tout, pourquoi pas ;) ?

En conclusion...

J'espère ne pas avoir fait d'erreurs dans la correction ! Sinon, n'hésitez pas à me les signaler.
C'est triste à dire, mais la plupart des candidats à un stage de programmation sont incapables... de programmer la plus simple des choses. Pour beaucoup, l'informatique reste une sorte de boite magique, dans laquelle le copier-coller est roi et la compréhension absente.
C'est bien dommage.

D'un autre côté, ça me permet aussi de faire un tri totalement subjectif des formations. Et y a certaines écoles que je ne conseillerai plus dès maintenant... quand 5 personnes d'une même école font les mêmes fautes de raisonnement et s'avèrent incapables de coder le moindre programme, il y a clairement du souci à se faire.

Vos remarques sur le questionnaire pour de futures améliorations sont les bienvenues ! Idem si vous avez des commentaires, que vous le trouvez trop dur / trop facile... ou qu'une question vous bloque encore !

Annexe : quelques questions de Google

À côté d'eux, ce questionnaire est basique !

  • You have a stream of infinite queries (ie: real time Google search queries that people are entering). Describe how you would go about finding a good estimate of 1000 samples from this never ending set of data and then write code for it.
  • There is an array A[N] of N numbers. You have to compose an array Output[N] such that Output[i] will be equal to multiplication of all the elements of A[N] except A[i]. For example Output[0] will be multiplication of A[1] to A[N-1] and Output[1] will be multiplication of A[0] and from A[2] to A[N-1]. Solve it without division operator and in O(n).
  • How do you find out the fifth maximum element in an Binary Search Tree in efficient manner. Note: You should not use use any extra space. i.e sorting Binary Search Tree and storing the results in an array and listing out the fifth element.
  • What kind of data structure would you use to index annagrams of words? e.g. if there exists the word “top” in the database, the query for “pot” should list that.