jeudi, 16 novembre 2006

Entretien d'embauche avec Google

Les RH de Google m'ont contacté il y a maintenant 3 semaines afin de me faire passer la première étape de leur entretien d'embauche.

L'interview, technique, c'est déroulé en 2 parties de 45 minutes chacune, durant lesquelles un ingénieur Google m'a posé des questions techniques. Apparemment il n'y avait pas un nombre défini de questions, mais tant qu'une réponse jugé satisfaisante était trouvée, on passait à une autre, inventée on the fly mais en relation avec notre CV.

Voici un petit aperçu des 10 questions auxquelles j'ai réussi à répondre. Elles sont traduites en franglais_geek1 pour les besoins du billet, et je n'y fait figurer que celles que j'ai trouvé intéressantes ou qui sont faciles d'exposer sur un blog :

  1. Implémentez en C la fonction assert(i > 0) de manière à ce que la condition "i > 0" soit affichée en cas d'erreur
  2. Même chose en C++, afin que le code suivant soit bien formé :
    assert(i > 0) << "message" << i ;
  3. Triez un tableau d'un million d'entier (int sur 4 bytes) stockée sur un disque dur en ne disposant qu'une mémoire de 2 MB. Comment vous y prenez vous ?
  4. Implémentez une classe qui contient 3 méthodes :
    - void push(int)
    - int pop()
    - int minimum()
    dont les 3 méthodes s'exécute avec une complexité en O(1)
  5. Trouvez une méthode efficace qui permet de détecter une boucle dans une liste chainée, sans pouvoir modifier les éléments de la liste ni recopier en entier la liste.
Les questions sont posées sans temps de préparation, ni ordinateur ou autres documents d'aide. On remarquera que les réponses, une fois connue, ne sont pas si compliquées qu'elles en auraient l'air.

1. Première hypothèse, avant que l'expert ne précise que la condition "i > 0" doit être affichée :

void assert (int cond) {
  if (cond == 0) {
    printf("Erreur");
    exit(1);
  }
}

Le problème se corse quand il s'agit d'afficher textuellement "i > 0", car en passant par un argument, il sera évalué avant d'être passer par valeur, donc on perd toute chance de pouvoir l'afficher. Ma deuxième version en passant un pointeur de fonction en paramètre s'est vite avérée fastidieuse, et l'idée d'utiliser par une marco et ses possibilités de manipulation de strings m'a soudain frappée, pour finalement donner quelque chose :

#define assert(cond) if ((cond) == 0) { \
  printf("Erreur "); \
  printf(#(cond)); \
  exit(1); \
}

2. Une fois la première question complétée, la deuxième est devenue triviale : il suffit d'ajouter cout à la fin de la macro pour que si la condition était différente de 0, on continue avec cout.

#define assert(cond) if ((cond) == 0) { \
  printf("Erreur "); \
  printf(#(cond)); \
  exit(1); \
} \
cout

3. 1 million d'entiers sur 4 bytes nous fait 4MB, donc trop pour tenir en entier dans la mémoire. Il faut donc partager le tableau en 2, trier chaque partie en utilisant n'importe quel algorithme de tri, puis fusionner les 2 tableaux à l'aide d'un tri par fusion.

4. La complexité en O(1) nous suggère directement l'utilisation d'une liste chainée. Push et pop deviennent donc trivial, push ajoute l'élément à en tête de liste, pop retourne en enlève le premier élément de la liste.
Le problème se pose maintenant pour la méthode qui retourne le minimum, qui est doit aussi se faire en O(1). Il est donc impossible de faire une recherche, car aucune méthode de recherche n'est en O(1). L'idée est donc de maintenir une deuxième liste chainée qui contiendra ces minimums. Donc on modifie push pour tester si la valeur à ajouter est plus petite OU EGALE au minimum, et si c'est le cas on ajoute aussi l'élément dans la liste des minimums, et pop pour enlever l'élément de la liste des minimums si cet élément est le minimum.

En pseudo Java ça nous donne quelque chose du style :

LinkedList l;
LinkedList m;
void push (int e) {
  if (e <= m.top()) {
    m.push(e);
  }
  l.push(e);
}
int pop() {
  int e = l.pop();
  if (e == l.top()) {
    l.pop();
  }
  return e;
}
int minimum() {
  return m.top();
}

5. La solution trivial qui est de marquer les noeuds parcourus n'est pas envisageable, car elle sous-entendrait de modifier le contenu des noeuds, ce qui n'est justement pas possible.
Une bonne solution est donc d'inverser les liens en parcourant la liste, et si on revient au noeud initial on sera sûr d'avoir une boucle. En parcourant la liste dans l'ordre inverse et en réinversant les liens, il est possible de remettre la liste dans l'état qu'on avait avant de débuter la recherche. A noter qu'il est impératif de s'assurer qu'un seul processus n'accède à la liste en simultané, car durant la recherche la liste est modifiée.

2 entretiens sur 6, prochain épisode pour bientôt j'espère...

mercredi, 8 novembre 2006

PHP Multithread

Non, faire tourner PHP en multithread n'est pas un mythe !
C'est possible de lancer des processus fils grâce au module pcntl, et à les synchroniser avec le module sémaphore, de préférence en ligne de commande (la doc précise que leur utilisation en module apache peut amener à des résultats erronés).

Voici donc un petit article qui démontre par un exemple comment implémenter un démon multithread en PHP.

mercredi, 11 octobre 2006

Covoiturage

Premier jour de covoiturage. Tout c’est bien passé, à part une petite frayeur dans un bouchon.

Je ne peux pas encore me prononcer sur les effets à long terme du covoiturage, mais j’ai déjà trouvé que c’était plus sympa le trajet à 2. L'heure de trajet est passée bien plus vite, et suivant les personnes qui accompagnent, les échanges peuvent être intéressants et constructifs.

Dès la semaine prochaine on charge 2 personnes supplémentaires.

On a l’air vachement moins égoïste à 2-3 dans une voiture…

Un serveur en overload

Quels sont les signes qu'un serveur est en overload ?

La réponse est relativement simple un outil de monitoring tel que mrtg ou maintenant rrdtool est installé sur le serveur.

Considérons le graphique suivant :



Il représente la charge d'un serveur sur une moyenne journalière, avec en y le % de charge. Dès juillet, l'augmentation de la charge non négligeable que subit le serveur est un signe qu'il faut envisager rapidement un remplacement par une machine plus puissante. L'augmentation est linéaire, elle nous permet donc une bonne projection et donc une bonne prévision de quand le serveur arrivera à une charge moyenne de 100%.

mardi, 10 octobre 2006

Les billets de mon ancien blog

Comme je l'ai dit ici, je compte utiliser régulièrement ce blog. Et en fonction du temps disponible, je vais faire revivre d'ancien billet qui sont partis aux oubliettes en même temps que mon ancien blog.

Ne soyez donc pas surpris de voir des billets qui commencent par "Initialement posté sur Noisette.ch", ce billet vont s'entremêler aux nouveaux.

lundi, 2 octobre 2006

Linked In

Après avoir reçu plusieurs invitations d'amis et collègues, j'ai finalement rejoins la grande famille de LinkdeIn, sur lequel vous pouvez consulter mon profile et mes connexions : http://www.linkedin.com/in/benoitperroud

Je ne sais pas encore si ce site va me servir pour trouver un futur emploi, mais j'ai trouvé le concept intéressant, et je compte bien arriver à plus de 90% dans toutes les options :)

vendredi, 29 septembre 2006

Les algorithmes de recherche binaire et par fusion sont bogués

C'est la constatation alarmante qu'a fait Joshua Bloch, Software développeur chez Google, dans son article Nearly All Binary Searches and Mergesorts are Broken (Presque tous les algorithme de recherche binaire et par fusion sont bogués) et il en explique précisément la cause.

Il cite en exemple la méthode binarySearch de la librairie java.util.Arrays, qu'il a lui même écrit avant de quitter Sun.

La ligne contenant ce bug est la suivante :

int mid = (low + high) / 2;


Le bug en question est un "bête" integer overflow qui peut apparaître si on manipule un tableau de l'ordre de plus de 2^30 éléments.

Le plus dérangeant dans cette histoire banale est que ce genre de bug, pourtant trouvé dans une routine de peu de lignes, est passé inaperçu pendant près de 60 ans.

Cet exemple démontre très précisément qu'il est impossible d'écrire du code sans bugs, et que donc les prochaines améliorations seront plus d'en limiter les conséquences que de les éradiquer.

mardi, 26 septembre 2006

Gentoo avec Apache2 + PHP5 + Suexec + FastCGI (dynamic)

FastCGI est un concept tout à fait intéressant qui permet, dans le cadre de PHP, d'allier rapidité et sécurité. Il permet conjointement d'avoir la rapidité de mod_php avec la sécurité de PHP/CGI, notemment en terme de droits d'utilisateurs.
Je ne vais pas vous refaire une série de benchmark comme c'est le cas sur beaucoup d'autre site, mais je viens de réaliser un article explicant en détail l'installation, la configuration et surtout les problèmes qu'on peut rencontrer avec la mise en place PHP, FastCGI dynamique et Suexec :

Pourquoi les mots "Chers Concitoyens"

Je ne souhaite pas vraiment m'étendre sur des discours politiques car ceux-ci ne sont pas ma tasse de thé, et encore moins dans l'esprit que je compte tenir sur mon blog.

Mais au lendemain des votations fédérales sur le durcissement du droit d'asile, le préfix "con" du terme concitoyens retrouve tout son sens.

La question est donc lancée : « Mais qu’avez-vous donc fait ? ». Seul l’avenir nous le dira...

jeudi, 21 septembre 2006

Mes cours de Master : terminés

Alors que mon travail de diplôme est déjà bien entamé, je voulais juste m'arrêter un peu sur mes résultats du Master à l'EPFL.

Le détail des notes peut être trouvé sur mon site : Mes notes de Master, et il y a 2 choses importantes à relever : 5.57 de moyenne (sur 6) sur l'année, et aucune note en dessous de 5.

Ce que j'aimerais montrer par là, ce n'est pas combien je suis fort et tout, loin de moi cette idée narcissique, mais plutôt qu'avec de la motivation et de la persévérance, on arrive à nos fins (et en passant faire un clin d'oeil à certains détracteurs du redoublement dans les universités, mais une réponse plus complète viendra peut-être dans un autre billet, intitulé quelque chose comme "L'apprentissage par l'échec").

La motivation est une capacité merveilleuse dont nous a dotés mère Nature, grâce à laquelle on peut bouger des montagnes. La motivation donne des ailes, décuple les forces, mais ne serait qu'un feu de paille si la persévérance ne prenait pas la relève. La persévérance, elle, est plutôt une discipline de vie, une force mentale qui, si elle est utilisée à outrance, se transforme rapidement en obstination.

J'ai appris, après deux échecs, à dompter ma motivation, puis j'ai cultivé ma persévérance pour finalement arriver là ou j'en suis aujourd'hui, en train de faire mon travail de diplôme dans le groupe Kudelski. Et je suis convaincu que refaire la deuxième année était pour moi la meilleure chose, tant cette année est importante sur le plan théorique. Finir une branche avec juste la moyenne, c'est suffisant, mais à mes yeux actuels ça n'est pas assez pour prétendre avoir compris les finesses de la matière et pouvoir tisser des liens avec d'autres branches. J'ai réussi à le faire grâce au travail, et ça se ressent à beaucoup de niveaux.

Le travail n'est pas une source de frustration, bien au contraire. Et la recette en est bien simple :

  • Immergez-vous dans un projet,
  • Adoptez un état d'esprit positif et la motivation grandira d'elle-même,
  • Fixez-vous des objectifs à court et moyen terme pour favoriser la persévérance.