Tout comme le titre l'indique, quel est votre problème d'interview sur tableau blanc préféré, et pourquoi s'est-il avéré efficace pour vous?
Junior, senior, Java, C, Javascript, PHP, SQL, pseudo-code, etc.
Je demande au candidat de concevoir une solution à un problème que j'ai réellement rencontré dans mon travail quotidien. Ce faisant, j'essaie de créer un dialogue entre moi et le candidat. J'essaie de discuter de la conception qu'il construit comme si je n'avais jamais pensé au problème auparavant.
Ce que j'essaie d'évaluer, c'est si nous sommes capables de nous comprendre et si nous pouvons parler d'un problème technique sans confusion.
(Pour un développeur de bureau Java)
Concevoir une API pour gérer le historique de navigation d'un navigateur web (page précédente, page suivante, lister les 10 pages précédentes), et qui peut être réutilisable dans de nombreuses parties de l'application (ici je donne des exemples concrets dans notre application). Esquissez ensuite une implémentation.
J'aime celui-ci, car il est assez simple, il est facile à illustrer, il peut être résolu étape par étape (ajoutez des comportements supplémentaires sans tout casser), il permet de parler des cas Edge et de la gestion des erreurs, et il permet également de parler de données structures.
J'ai trouvé celui-ci extrêmement éclairant lors des entretiens avec les candidats et le filtrage de ceux sans affaires. Il est similaire en complexité à Fizz Buzz, mais se concentre sur les compétences de base de données.
Assuming the following basic table structure
Documents (DocID, DocDate)
Keywords (KeyWordID, KeyWord)
DocumentKeywords (DocID,KeywordID)
Write a query to return the following:
Part 1: Documents with a DocDate after 4/1/1995
Part 2: Documents that contain the keyword "Blue"
Part 3: Documents that contain the either the keyword "Blue" or "Yellow"
Part 4: Documents that contain the both the keywords "Blue" and "Yellow"
Je les laisse l'écrire dans n'importe quelle variante SQL qu'ils souhaitent et je ne suis pas trop pointilleux sur les problèmes de syntaxe mineurs. Je veux principalement savoir qu'ils comprennent les concepts de base des bases de données relationnelles.
La plupart des candidats peuvent passer la partie 3 sans aucun problème. Vous seriez étonné de voir combien pensent que la réponse à la partie 4 consiste simplement à changer l'opérateur de OR à AND dans la clause where.
"Dessinez pour moi sur le tableau blanc le design du dernier projet sur lequel vous avez travaillé, sans me révéler aucun détail sensible."
Implémentez strcpy
, strcmp
et vos amis.
Mon préféré qui englobe quelques disciplines est de compter le nombre de nœuds dans un arbre binaire étant donné l'interface (en C #):
public interface IBinaryTree<T>
{
IBinaryTree<T> Left
{
get;
}
IBinaryTree<T> Right
{
get;
}
T Data
{
get;
}
// Other properties and methods not germane to this problem.
}
et juste pour le plaisir, voici l'implémentation, même si la personne interrogée n'a pas besoin de voir cela.
public sealed class BinaryTree<T> : IBinaryTree<T>
{
private readonly IBinaryTree<T> left;
private readonly IBinaryTree<T> right;
private readonly T data;
public BinaryTree(
IBinaryTree<T> left,
IBinaryTree<T> right,
T data)
{
this.left = left;
this.right = right;
this.data = data;
}
public IBinaryTree<T> Left
{
get
{
return this.left;
}
}
public IBinaryTree<T> Right
{
get
{
return this.right;
}
}
public T Data
{
get
{
return this.data;
}
}
// Other properties and methods not germane to this problem.
}
et la classe assistante:
public static class BinaryTreeNodeCounter
{
public static int CountNodes<T>(this IBinaryTree<T> tree)
{
// TODO: What goes here?
}
}
La solution que j'aime voir est la suivante:
public static class BinaryTreeNodeCounter
{
public static int CountNodes<T>(this IBinaryTree<T> tree)
{
return tree == null
? 0
: 1 + tree.Left.CountNodes() + tree.Right.CountNodes();
}
}
Comme il démontre la connaissance de:
Deux questions qui ont suscité des discussions intéressantes sur le tableau blanc pour moi sont
Ils commencent simplement et deviennent de plus en plus complexes.
Je n'aime pas utiliser un puzzle ou une question de conception comme question de tableau blanc. Je préfère les questions simples et directes qui testent la capacité du candidat à écrire du code. Mes favoris sont:
1) Écrivez une fonction pour inverser une liste liée individuellement. (Il faut un certain temps avant de se rendre compte qu'ils ont besoin de 3 pointeurs.)
2) Étant donné un arbre binaire, trouvez la profondeur de l'arbre binaire. (Cette question teste leur capacité à écrire du code récursif. Permet de vérifier si leur cas de base est intact.)
3) Écrivez une procédure de recherche binaire d'un tableau d'entiers. (Comme le dit Jon Bentley (dans Programming Pearls), beaucoup de gens ont tendance à faire des erreurs en écrivant la recherche binaire. On peut ensuite faire un suivi avec trouver des bogues, écrire des cas de test, parcourir le code, etc.)
Nous l'avons utilisé dans une entreprise pour laquelle je travaillais.
Nous avons remis au candidat un morceau de papier utilisé pour le suivi du temps. C'était une véritable feuille de temps utilisée par l'une ou nos divisions. Nous avons demandé au candidat de nous guider tout au long du processus de conception pour créer un meilleur outil de suivi du temps. Pas de frontières, n'a pas dit quelle langue, etc., je veux juste voir à quel point le candidat était "au cycle de vie complet". Cela nous a permis de mieux comprendre comment ils ont rassemblé les exigences. Comment ils ont structuré les tables de base de données, quel type d'interface utilisateur ils pourraient faire. Des compétences en communication étaient évidemment nécessaires pour cette tâche. Cela se faisait généralement dans une pièce avec plusieurs grands tableaux blancs et durait jusqu'à 2 heures.
Nous avons embauché plusieurs personnes en utilisant ce processus et si elles ont vraiment bien fait la tâche, elles l'ont vraiment bien fait pour nous. S'ils étaient marginaux et nous avons décidé de les engager quand même (sujet séparé), ils étaient des programmeurs marginaux.
J'utilise un problème qui concerne mon domaine de programmation.
Si je développe des applications Web, je veux voir comment elles pourraient rédiger un formulaire Web qui supprime des enregistrements et quelle approche ils pourraient adopter pour supprimer l'enregistrement de la base de données, par exemple. Cela me dit s'ils connaissent les principes de base de la base de données, comment ils interagissent avec l'utilisateur pour vérifier la suppression et s'ils savent ce qu'est une suppression logicielle.
Je n'ai pas de favori. Le problème que je choisis variera considérablement en fonction du travail.
Peu m'importe s'ils peuvent résoudre le problème complètement ou non dans une interview, quelles technologies et quels langages ils utilisent, ou à quel point leur code est nul sur un tableau blanc. Je cherche un schéma de pensée; Je veux voir s'ils savent réfléchir et résoudre les problèmes.
Mon préféré était celui d'un de mes amis.
Écrivez-moi une fonction pour générer/imprimer/stocker les premiers "n" nombres premiers, puis expliquer comment cela fonctionne et son efficacité.
Cela fonctionne bien car:
C'est une question algorithmique, donc elle nécessite que la personne interrogée soit capable de penser puis d'expliquer sa pensée - pour que vous puissiez voir comment fonctionne son cerveau.
C'est indépendant de la langue.
Presque personne ne réussit complètement (il y a généralement un cas Edge qui leur manque (1 ou 2 normalement), ou ils ne traitent pas les nombres négatifs, donc vous pouvez voir comment ils gèrent les bugs et se faire dire qu'ils ont tort.
La plupart le font comme un tamis simple mais très lent (par exemple, 80% des gens vérifieront que n est un nombre premier en divisant n par tous les entiers inférieurs à n), ce qui vous donne beaucoup de possibilités pour des conversations sur la façon dont ils pourraient améliorer l'algorithme basé sur les compromis espace/temps, par exemple "Pourquoi divisez-vous un nombre par 4 si vous savez déjà qu'il n'est pas divisible par 2?" ou "Vous avez compris que vous devez seulement diviser par tous les nombres premiers inférieurs à sqrt (n), mais cela vous oblige à stocker ces nombres quelque part, alors quelles sont les implications de cela?")
Il n'est pas nécessaire qu'ils obtiennent la bonne réponse. Si quelqu'un peut penser et expliquer sa pensée, alors il est loin d'être un bon candidat.
Cela dépend vraiment de ce que vous recherchez, en tant qu'organisation qui fait beaucoup de travail Web dynamique impliquant des images, j'ai tendance à aimer poser une question de géométrie pertinente pour le travail. Dans tous les cas, j'ai tendance à poser une question de géométrie, car je trouve que c'est un bon test de mathématiques qui est agréable et visuel et peut montrer la capacité d'un candidat à présenter visuellement son travail et à résoudre méthodiquement un problème.
Pour les candidats avancés, je pose parfois la question suivante:
Cette image montre un croissant de lune. La largeur du croissant de B à D est de 9 cm et entre E et F, 5 cm. C est le centre du plus grand cercle.
a) Veuillez calculer l'aire du croissant.
b) Décrivez les calculs nécessaires pour redimensionner une image afin qu'elle tienne dans le cercle intérieur à partir de n'importe quelle taille donnée et placez-la dans le cercle si le point central est connu.
Pour une question plus simple, je donne généralement le même genre de question, mais j'utilise l'exemple "carré dans un cercle dans un carré". Bien que ce soit très facile, je m'attendrais donc à une algèbre parfaite.
En plus de cela, j'ai tendance à leur demander de créer un algorithme pour générer toutes les combinaisons d'un ensemble de données de longueur variable.
Les meilleures réponses FizzBuzz que j'ai vues sont:
SQL Server 2008
;WITH mil AS (
SELECT TOP 100 ROW_NUMBER() OVER ( ORDER BY c.column_id ) [n]
FROM master.sys.all_columns as c
CROSS JOIN master.sys.all_columns as c2
)
SELECT CASE WHEN n % 3 = 0 THEN
CASE WHEN n % 5 = 0 THEN 'FizzBuzz' ELSE 'Fizz' END
WHEN n % 5 = 0 THEN 'Buzz'
ELSE CAST(n AS char(6))
END + CHAR(13)
FROM mil
C # (simple)
foreach (int number in Enumerable.Range(1, 100))
{
bool isDivisibleBy3 = (number % 3) == 0;
bool isDivisibleBy5 = (number % 5) == 0;
if (isDivisibleBy3)
Console.Write("Fizz");
if (isDivisibleBy5)
Console.Write("Buzz");
if (!isDivisibleBy3 && !isDivisibleBy5)
Console.Write(number);
Console.WriteLine();
}
C # (intelligent)
Enumerable
.Range(1, 100)
.Select(i =>
i % 15 == 0 ? "FizzBuzz" :
i % 5 == 0 ? "Buzz" :
i % 3 == 0 ? "Fizz" :
i.ToString())
.ToList()
.ForEach(s => Console.WriteLine(s));
Quelque chose appelé aff_z, qui faisait partie des examens C de mon école d'ingénieur et a été utilisé comme un test "factice" pour faire échouer les étudiants au retour des vacances (notre système de notation impliquait que l'échec d'un test arrêtait le marquage, donc l'échec de ce test factice serait invalider tout votre test vous oblige à prêter attention aux détails débiles). Je l'ai réutilisé une ou deux fois lors des interviews.
Quoi qu'il en soit ... j'ai oublié la formulation exacte mais c'était quelque chose comme ça ...
Write a function taking a single char parameter named c and returning nothing (void).
You function must satisfy the following requirements:
- if c is bigger or equal to 0, then print 'z' to standard output
- if c is stricly smaller than 0 , then print 'z' to standard output
- in any other case, print the letter 'z' to standard output
Ce qui est triste, c'est que non seulement certains élèves trouveraient des solutions extrêmement compliquées lorsque la réponse est assez évidente, mais que certains réussiraient même à échouer.
Et croyez-le ou non, cela s'est également produit lors des entretiens.
Le faire dans les entretiens était assez amusant, car certains candidats commençaient à écrire les branches possibles et réalisaient ensuite ce qui ne va pas (évidemment, si vous ne leur demandez que oralement, il est tout à fait compréhensible qu'ils le fassent pendant que vous parlez ... mais si vous donnez-le par écrit, je trouve ça déroutant ...)
C'est stupide, mais je suppose que c'est un filtrage minimaliste (de même, lors de l'embauche de programmeurs JS, je demande toujours comment déclarer une variable, puis en fonction de leur réponse, l'utilisation de var fait ou non une différence. Très souvent, un moment triste, honnêtement.)
Je recherche quelques éléments parmi les candidats que j'ai interviewés. Pour une raison que je ne peux pas décrire en ligne, nous obtenons des candidats assez pauvres, et j'en suis venu à m'y attendre, donc je suis assez facile avec eux. Même encore, je cherche:
Sensibilisation au design.
"Montrez-moi la structure du tableau pour un programme de carnet d'adresses qui a des contacts avec des prénoms et des noms qui peuvent avoir plusieurs numéros de téléphone avec une description du numéro (cellule/domicile/travail/etc.)"
Je ne cherche pas un diagramme de spécification UML 2.0 ici, un simple diagramme à bulles ici est très bien. Tant que c'est raisonnable.
Connaissance du travail avec une base de données (c.-à-d. SQL)
Connaissance des tests
Supposons qu'il existe une méthode avec la signature public IEnumerable<PhoneNumber> GetPhoneNumbers(string lastName)
qui renvoie les résultats de votre requête antérieure. Supposons que si vous passez un null dans la méthode, il lève une NullReferenceException. Écrivez un test pour démontrer cette fonctionnalité.
Écrivez un test qui démontre que GetPhoneNumbers renverra un numéro de téléphone à domicile (123)456-7890 pour quelqu'un avec le nom de famille "smith".
Connaissance de l'écriture de code
Mettez en œuvre une méthode qui satisfera aux exigences des tests que vous avez écrits.
Compte tenu du nombre et de la qualité des candidats que nous avons reçus, j'ai interviewé tous ceux qui ont déjà fait une demande sérieuse. Je n'ai embauché personne.
Écrivez un algorithme pour le problème suivant: Étant donné un nombre n, affichez le nombre total d'arbres binaires (uniques) qui ont n nœuds.
Ainsi, pour n= 0 et n= 1, la réponse est 1. Pour n= 2, vous avez 2: le nœud racine, puis le deuxième nœud à gauche ou à droite.
Vous pouvez obtenir un aperçu des techniques de conception et voir s'ils pensent à la récursivité ou à la mémorisation ou à la solution de programmation dynamique.
[Voir aussi ce StackOverflow discussion pour le cas connexe, mais différent, des arbres de recherche binaire.]
Si je devais interviewer un développeur de logiciels, je lui demanderais de concevoir un logiciel et de décrire la configuration matérielle requise pour supprimer les entrées en double d'un fichier arbitrairement volumineux contenant un nom complet sur chaque ligne. Je laisse délibérément certaines parties de la description du problème ambiguë. Ensuite, je le mets au défi de voir s'il comprend l'analyse et la clarification des exigences, des différents compromis, des structures de données et des algorithmes, des E/S (stockage secondaire), des technologies logicielles et matérielles, de l'évolutivité, etc.
Je pense que c'est un problème petit mais difficile, révélant les connaissances et les capacités du candidat dans de nombreux domaines informatiques.
Mon problème de tableau blanc C++ préféré est d'avoir le candidat à implémenter
Vector3 a(1, 0, 0), b(0, 1, 0); // Mathematical 3D vectors
double c = 7.0;
double d = a * c;
Vector3 e = a * b;
De cela je peux apprendre
Implement function/method(on c/c++/c# whatever), which calculates n-th item of Fibonacci sequence
Beaucoup de gars pourraient s'en tenir à ça. Si une solution est donnée, elle utilise généralement la récursivité. Après ça:
Implement the same via 'for'-loop
Je ne peux pas vous dire, combien de boursiers ne réussissent pas les deux tâches - 50% des candidats.
C'est pourquoi je l'aime :)
Pour les bases de données, je choisis:
Tableau: Objets ID Nom 1 Bodkin Van Horn 2 Hoos-Foos 3 Hoos-Foos 4 Hot- Shot 5 Face de ballon Marvin O'Gravel 6 Snimm 7 Face de ballon Marvin O'Gravel 8 Face de ballon Marvin O'Gravel 9 Dave
Écrivez-moi du SQL qui dédoublonnera une table comme celle-ci en fonction du nom (et je me fiche de l'ID que je récupère, mais celui qui est retourné doit être valide pour ce nom). Ainsi, la table une fois que le SQL correct aura été appliqué présentera quelque chose comme:
Tableau: Objets ID Nom 1 Bodkin Van Horn 2 Hoos-Foos 4 Hot-Shot 5 Marvin O 'Face de ballon en gravier 6 Snimm 9 Dave
Je l'aime parce que:
(C'est là que je trouve qu'il y a une façon tout à fait triviale de le faire et je l'ai compliqué pendant toutes ces années).
Je les laisse généralement esquisser un schéma de principe du dernier système sur lequel ils ont travaillé, en leur posant des questions sur les relations entre les blocs et que je les laisse élaborer sur le bloc sur lequel ils travaillaient/étaient en charge. Vous pouvez en apprendre beaucoup de cet exercice, comme la façon dont on regarde au-delà de son petit domaine, combien est-il important pour lui de savoir "où" il agit, vous pouvez également en apprendre davantage sur le rôle qu'il jouait, était-ce une clé ou un côté rôle.
Comment représenteriez-vous un jeu de 52 cartes standard? Tout langage de programmation est très bien. Comment mélangeriez-vous les cartes?
Vous avez un bol avec 200 poissons dedans. 99% de ces poissons ne sont pas des guppys. Combien de poissons devez-vous retirer pour que 2% de ce qui reste sont des guppys. Montre ton travail.
Il s'agit de confondre les exigences. Il est dit de cette façon de changer de perspective plusieurs fois au cours de la même question. Il s'agit de voir s'ils peuvent comprendre ce qui se passe réellement.
Vous seriez surpris du nombre de personnes qui se trompent.
Une question que j'utilise depuis qu'elle a été utilisée sur moi est la suivante:
Écrivez une fonction pour imprimer tous les nombres entre 1 et 100.
Une grande partie de la raison pour laquelle je l'utilise est due au fait que vous pouvez ensuite y apporter une solution et vous déplacer dans différentes directions:
Comment modifieriez-vous la fonction pour imprimer tous les nombres entre 1 et 1000, 10000 ou n?
Leurs réponses à ces questions pourraient vous donner un aperçu de la façon dont ils répondent aux exigences changeantes et s'ils peuvent reconnaître les considérations de performances. Un candidat solide pourrait répondre par une question concernant la fonction requise pour la fréquence à laquelle elle serait appelée.
Aller dans une direction différente:
Comment changeriez-vous les choses si vous saviez que cette fonction allait être appelée plusieurs fois par minute et que les performances étaient un problème?
J'utilise cela comme un moyen de vérifier leur pensée latérale. Étant donné que le calcul des nombres premiers peut être lent à mesure que la valeur maximale augmente, il est parfois plus logique d'utiliser simplement une sorte de table de recherche calculée ou précalculée qui est ajustée en fonction du problème que vous essayez de résoudre.
En voici une pour susciter la réflexion - C'est simple, implique un peu de mathématiques et vérifie les connaissances du candidat en conception informatique de base (débordement, représentation numérique, etc.):
Écrivez un programme (ou une procédure) qui prend une paire d'entiers X, Y en entrée et détermine si X * Y est divisible par 10. REMARQUE IMPORTANTE: X et Y peuvent être suffisamment grands pour que X * Y déborde du plus grand type entier disponible sur votre machine.
T_BOOL MultipleOfTen(int x, int y)
{
return((x%2==0 || y%2==0) && (x%5==0 || y%5==0));
}
Mon préféré est de commencer par demander le prototype de printf. Puis, étant donné une API de bas niveau printc (char c), qui imprimera un caractère, implémentez printf. Donne toutes sortes de réponses intéressantes comme la pile fait partie du CPU. Comme vous l'avez peut-être deviné, je viens d'un milieu C et intégré.
J'ai quelques favoris, mais en voici quelques-uns qui reviennent presque toujours. La plupart du temps, je fais des entretiens techniques de dernière ronde (C++), alors privilégiez les questions plus longues et plus ouvertes qui mènent à de nouveaux domaines d'intérêt. Il n'y a pas de "bonne" réponse, juste une ouverture à une autre conversation.
1) Implémentation d'un pointeur partagé de base, explications des lacunes par rapport aux pointeurs partagés tr1 ou boost dans leur implémentation, comment il doit être utilisé, etc.
2) Une révision du code. Pour les employés expérimentés, nous nous attendons à ce qu'ils soient en mesure d'examiner en toute confiance certains codes fournis pour les problèmes de conception, les erreurs, les horreurs de codage et les problèmes potentiels de maintenabilité. Aussi, bien sûr, comment ils le corrigeraient; et parfois comment ils transmettraient ce message au développeur junior qu'ils abattent.
Remplissez la méthode suivante: PS Un mode d'un nombre est le nombre (dans la liste) qui a le plus d'occurrences.
public int getMode(List<Integer> numberList) {
}
C'est pour voir que votre code est efficace.