Archives pour la catégorie “Développement”


C’est le grand mal des projets informatiques ! Je connais peu de projets qui prennent vraiment au sérieux la phase d’estimation. C’est pourtant à partir de ces estimations que sont établis de beaux diagramme de gantt qui se révèlent faux dès la première semaine de développement. Or un projet mal estimé c’est un projet qui démarre mal dans la vie… il sortira certainement en retard ou bâclé.

Pourtant estimer est une tache difficile qui mérite qu’on s’y attarde un minimum. Voici un petit quizz inspiré de celui que vous pouvez lire dans Software Estimation de Steve McConnel. Essayez d’y répondre de telle sorte que vos estimations vous donne 90% chance d’avoir la bonne réponse. Si vous ne connaissez pas une réponse, n’allez pas voir sur Wikipedia mais faite plutôt une estimation suffisamment large pour englober la bonne réponse avec 90% de chance.

Faire le quizz

Quizz Estimation

Si vous avez 9 bonnes réponses ou plus, bravo !
Vous savez estimer avec une certitude de 90%.

Si vous avez 8 bonnes réponses ou moins, vous avez été un peu trop optimiste dans vos estimations. Vous avez essayé sur certaines questions de mettre une fourchette qui se rapproche au maximum de la bonne réponse. C’est tout à votre honneur mais mieux vaut toujours une estimation trop large qu’une estimation fausse !

Le developpeur est en effet une espèce (allez savoir pourquoi) de nature plutot optimiste. Quand on lui demande combien de temps ca lui prendra de rajouter la fonctionnalité n°245, il vous répondra qu’il suffit d’ajouter un bouton ici, un bout de code là et que le tour est joué. En bref: “En 2h c’est bouclé !”.
Dans la réalité au bout de 3h de travail, c’est presque fini.. mais pas complètement: “Donnes-moi encore 15 minutes pour boucler l’affaire”. Au bout de 4h, ça y est ! C’est fini… sauf qu’il reste encore 2 ou 3 bugs à corriger pour que ça puisse être livré. Classiquement, il aura fallu 1 journée de travail pour implémenter la fonctionnalité alors que la tache avait été estimée à 2h.

Pourquoi se mettre dans une situation comme ça tout seul? Quand on vous demande d’estimer une tache, n’essayez pas de faire votre kéké pour impressionner la galerie (genre, moi je code plus vite que tout le monde) et essayez de faire l’estimation la plus juste.

Quelques conseils pour terminer:

  • Si vous manquez d’information pour faire votre estimation, prenez le temps de réunir les informations qu’il vous faut. Ça peut être de faire un mini prototype, d’aller regarder le temps effectivement pris pour faire une tache similaire, etc.
  • Si votre chef insiste pour vous faire baisser votre estimation, ne soyez pas politiquement correct. Dites-lui que vous pensez sincèrement que votre estimation est juste et qu’il peut consulter ses archives pour voir qu’une tache de ce genre prend effectivement le temps que vous avez estimé (et si votre chef ne garde pas un historique de chaque tache, avec l’estimation et le temps effectivement requis, demandez-lui de commencer à le faire.

Comments Un commentaire »

Quand on développe une application Internet riche en HTML/AJAX, Flex ou Silverlight, nous sommes à la croisée des chemins, entre pages Web et applications riches.

Et quand vient l’heure d’ajouter un bouton à l’application, je me pose toujours la question de savoir s’il vaut mieux mettre un bouton qui ressemble à un…bouton, ou bien un bouton qui ressemble à un hyperlien.

Cliquez moi

On peut considerer que les hyperliens ont pour unique fonction d’amener l’utilisateur sur une nouvelle page HTML dans le navigateur. C’est leur vocation première et devrait donc rester leur vocation unique. Mais les applications Internet riches ont de ceci de particulier qu’elles n’ont en fait qu’une seule page qui peut changer du tout au tout. Un clic sur un bouton dans une telle application peut donc - meme si l’adresse de la page ne change pas - amener sur une autre interface graphique que l’on pourrait considérer comme une nouvelle page.

On pourrait donc utiliser les hyperliens dans les applications Internet riches quand l’action qui se trouve derrière le bouton va le faire changer d’interface graphique.

Au niveau de l’ergonomie, on peut aussi remarquer que les boutons sont beaucoup plus voyant que les hyperliens. On pourrait donc réserver les boutons aux actions que l’on veut mettre en valeur, et mettre des hyperliens pour les actions que l’on ne veut pas mettre en avant.

Regardez l’interface de Google Analytics permettant de choisir une date et remarquez comme la commande Apply utilise un bouton et la commande Cancel, un hyperlien (Et pour mettre cette dernière encore moins en avant, notez que le mot cancel ne commence pas par une majuscule).

Bouton ou hyperlien? les deux!

Que pensez-vous de cette utilisation des hyperliens dans les applications Internet riches ? Est-ce intuitif ?

Comments Un commentaire »

Lorsque je dois démarrer un nouveau logiciel, une nouvelle application Web ou une nouvelle fonctionnalité, et que les idées sont à peu près claires sur ce qu’on veut obtenir, je commence systématiquement par maquetter l’interface utilisateur.

Inutile de démarrer les développements si on ne sait pas exactement ce que l’on veut. Bizarrement, peu de développeurs ont le reflexe de prototyper correctement l’interface utilisateur avant de coder. Pourtant, pour se mettre d’accord avec les utilisateurs, ou même pour se rendre compte du résultat des développements, rien ne vaut un bon dessin.

Pour les premières maquettes de l’interface utilisateur, un dessin à main levé suffit. Soit je dessine sur une feuille blanche que je scanne ensuite, soit j’utilise ma palette graphique pour dessiner à la main. Dans tous les cas, la maquette ressemble à quelque chose comme ça:

Prototype à main levé

A ce stade on peut déjà avoir un feedback des utilisateurs et essayer de travailler sur l’ergonomie et le placement des différents éléments graphiques. Comme vous le voyez, c’est rapide à faire et ça permet de faire un premier round de discussions qui sont - je vous l’assure - toujours très pertinentes.

Une fois qu’un consensus se dégage, on peut maquetter plus finement en essayant d’avoir le résultat final tel qu’il sera à l’écran. On peut faire ce genre de maquette en HTML, sous forme d’image avec Photoshop ou Paint Shop Pro, ou encore avec le designer graphique qui va avec votre environnements de développement (Visual Studio, Flex Builder, etc.). Dans le cas de la page d’accueil de Google, on obtiendrait donc une image comme ça:

Google Prototype Avancé

Là on est prêt à développer… quoique. Il peut également être intéressant de maquetter ce qui se passe quand on clique sur les boutons, pour rendre la maquette plus interactive, et bien montrer à quoi sert tel ou tel bouton.
Jusqu’à présent, je n’utilisait que des outils RAD (Visual Studio, Flex Builder, etc.) ou des fichiers HTML pour faire ce genre de maquettes interactives. Mais j’ai récemment découvert que l’on pouvait utiliser PowerPoint pour créer de véritables maquettes interactives. Pour notre exemple avec Google, cela donne une maquette comme ça (cliquez sur les zones jaunes):

Maquette Interactive Google

Maquette Interactive Google (google.pss, lisible sous Powerpoint XP/2003/2007 et OpenOffice 2.x)

L’idée c’est de désactiver le passage automatique à la slide suivante quand on clique sur la souris, et pour naviguer de mettre des zones rectangulaires semi-transparentes qui sont des liens vers d’autres slides.

On peut également utiliser Powerpoint pour faire des “maquettes papier” interactives avec le Powerpoint Prototype Toolkit que je vous recommande chaudement.

Comments Un commentaire »

Un logiciel n’a pas besoin d’être rapide… il doit juste ne pas être lent!

Pour cela il suffit juste que le logiciel effectue les taches demandées dans un temps jugé acceptable par l’utilisateur. Et autant l’utilisateur attendra facilement d’attendre quelques secondes pour obtenir le résultat d’un traitement couteux, autant il ne comprendra pas si le logiciel mouline ne serait-ce qu’une seconde a chaque copier/coller.

Le temps qu’un utilisateur est prêt à attendre dépend de ce qu’il considère comme normal. Et cette norme évolue… Prenez la recherche d’un email. Il y a 5 ans, un utilisateur de Microsoft Outlook acceptait d’attendre quelques minutes pour obtenir le résultat d’une recherche visant à retrouver un ancien mail. Aujourd’hui ce n’est plus le cas. Des logiciels comme Lookout ou bien Gmail rendent leur verdict en quelques secondes et ont donc fait évoluer l’attente des utilisateurs.
Donc lorsque vous développez votre logiciel, ayez les mêmes attentes que les utilisateurs en termes de performance. Inutile pour autant d’optimiser toutes les parties du logiciel….

Dragster Lego

Voici quelques conseils pour vous aider à développer un logiciel suffisamment rapide pour vos utilisateurs :

  • Lors de la phase de conception, écartez les architectures qui ne vous permettront pas d’atteindre des performances suffisantes. Dans le cadre d’un logiciel de gestion d’email, par exemple, écartez toutes les architectures qui nécessitent plusieurs minutes pour effectuer une recherche.
  • Lors du développement quotidien du logiciel, ne vous focalisez pas sur la performance. Mais:
    • Procédez à une phase d’optimisation régulièrement (à chaque fois que vous finissez une itération, une fonctionnalité, …). Lors de cette phase d’optimisation, utilisez un profiler pour déterminer ce qu’il faut optimiser.
    • Testez régulièrement votre logiciel avec de gros volumes de données.
  • Si votre logiciel effectue des taches potentiellement longue, affichez une barre de progression ou un indicateur d’activité ainsi qu’un bouton « Annuler » pour stopper immédiatement l’opération. Cela permet à vos utilisateurs d’abandonner une tache si ils la jugent trop lente.
    Et ne faites pas comme certains logiciels qui mettent un bouton « Annuler » mais qui est tellement mal programmé que lorsqu’on appuie dessus, non seulement l’opération ne s’arrete pas et se poursuit jusqu’à son terme, mais en plus embraye ensuite sur une interminable phase d’annulation des modifications effectuées.

Comments Pas de commentaire »

Suite à mon billet sur la salaison des mots de passe et sur les Rainbow tables, j’ai appris que calculer une empreinte de mot de passe avec un algorithme tel que SHA-1 ou MD5, même avec du sel, n’est plus très sûr.

le problème est que ces algorithmes de hachage ont été conçus dans le but d’être rapides car ils sont au cœurs de nombreux système cryptographiques. Ils ont également été conçus pour pouvoir tourner sur du matériel spécialisé. Le résultat c’est que mon PC pour calculer un peu plus d’un million d’empreintes SHA-1 par seconde, et presque deux millions par seconde avec MD5. Il existe également des circuits imprimés spécialisés qui peuvent calculer une centaine de millions d’empreintes SHA-1/MD5 par seconde, mettez-en 10.000 en parallèle et vous pouvez casser tout mot de passe de 1 à 10 caractères en une seule journée.

La conclusion, c’est qu’un algorithme rapide est exactement ce que l’on ne veut pas lorsqu’on calcule une empreinte de mot de passe. Utiliser un algorithme rapide comme SHA-1 ou MD5 pour calculer l’empreinte de mots de passe est aussi stupide que de ne pas mettre de sel avant de calculer l’empreinte. Ne le donc faites pas!

Utilisez un algorithme de hachage lent. Un tel algorithme demande énormément de temps pour calculer son empreinte, et n’est pas adapté pour tourner sur du matériel spécialisé. Il ne pourra donc jamais être cassé par des attaques par force brute.

L’état de l’art dans ce domaine aujourd’hui s’appelle BCrypt. Il a été mis au point en 1999 pour OpenBSD. Son principal avantage est que c’est vous, le programmeur, qui décidez combien de temps prend le calcul d’une empreinte. Mais attention, BCrypt est fait pour être lent. Sur mon PC, avec le réglage le plus rapide, le calcul d’une empreinte demande 2 msec, soit 500 empreintes par seconde. On est loin du million d’empreinte obtenu avec SHA-1 ou MD5. Avec le réglage par défaut, mon PC ne génère pas plus de 15 empreintes par seconde.

En conclusion, voici quelques règles à suivre pour stocker des mots de passe:

Règle numéro 1: Stockez l’empreinte des mot de passe, pas les mot de passe eux-même.

  • Ne stockez pas les mot de passe en clair
  • Ne stockez pas non plus une version cryptée des mot de passe. Les algorithmes de cryptage comme AES, DES, 3DES, BlowFish, RC4 ou RSA sont donc à bannir car ils sont réversibles par nature.

Règle numéro 2: Utilisez un algorithme de calcul d’empreinte si possible lent et éprouvé

Utilisez si possible BCrypt. Il est disponible pour Java, .NET, PHP, et bien d’autres langages encore.

Si vous ne pouvez vraiment pas, essayez d’utiliser SHA-512/384/256. Sinon SHA-1. En dernier recours MD5.

A savoir: MD5 a été cracké et SHA-1 n’est plus considéré comme sûr.

Règle numéro 3: Ajoutez du sel avant de calculer les empreintes.

  • Le sel ajouté doit avoir été calculé avec une fonction cryptographique de génération de nombre aléatoire. Il faut donc le stocker à coté de l’empreinte.
  • Le sel doit également être différent pour tous les utilisateurs (pour éviter les attaques sur un lot d’empreintes).
  • Le sel doit être suffisamment long (12 caractères ou 24 octects au minimum).

La bonne méthode est la suivante (en pseudo Java)

// Calcule l'empreinte d'un mot de passe
public String computePasswordHash(String password) {
// Génère un tableau aléatoire de 32 octets
byte[] salt = CryptographicRandomNumberGenerator.getBytes(32);

// Calcule l’empreinte du mot de passe en utilisant le sel généré (le sel est inclus dans l’empreinte retourné)
return hashPassword(password, salt);
}

// Verifie que le mot de passe fourni correspond à celui qui a servir à calculer l’empreinte fournie.
public boolean checkPassword(String text, String hash) {
// Récupère le sel contenu dans l’empreinte.
String[] hashAndSalt = String.split(hash, “$”);
byte[] salt = Base64.decode(hashAndSalt[1]);

// Calcule l’empreinte du mot de passe fourni avec le sel récupéré ci-dessus.
String hashedText = hashPassword(text, salt);

// Regarde si les empreintes sont indentiques.
return hashedText.equals(hash);
}

private String hashPassword(String password, byte[] salt) {
byte[] pwd = password.getBytes(”UTF-8″);
byte[] saltedPwd = Array.join(pwd, salt);
byte[] hash = hashFunction(saltedPwd);
return Base64.encode(hash) + “$” + Base64.encode(salt);
}

Enfin sachez qu’il existe aujourd’hui une méthode pour ne plus avoir à stocker les mots de passe nommée SRP. Si vous pouvez l’utiliser, c’est encore mieux que de stocker les mots de passe.

Comments Pas de commentaire »