Styles

vendredi 30 octobre 2009

Quelle est votre opinion la plus controversée sur la programmation ?

Je me baladais l’autre jour sur stackoverflow.com, le site de questions/réponses de Jeff Atwood que tout le monde attendait (vu le nombre de questions et réponses déjà présentes sur le site). Il y a toujours des questions qui cherchent à polémiquer, à créer des controverses, à relancer des guerres maintes fois débattues (la guerre des éditeurs, des OS…).

Je suis tombé par hasard sur cette question : Quelle est votre opinion la plus controversée sur la programmation ? Autant dire que ça doit inspirer pas mal de monde… et en effet, des pages et des pages d’opinions les plus diverses sont reliées à cette question.

Plusieurs opinions m’ont paru intéressantes, voici traduit en français celles de la première page, donc celles les plus intéressantes, puisque c’est l’objectif de stackoverflow.com de faire remonter le plus en haut les meilleures réponses aux questions :

  • La seule “bonne pratique” que vous devez utiliser tout le temps est “Utilisez votre cerveau”.
  • Les programmeurs qui ne codent pas pendant leur temps libre pour s’amuser ne deviendront jamais aussi bon que ceux qui le font.
  • La plupart des commentaires dans le code sont en fait une forme pernicieuse de duplication de code.
  • Les programmeurs ne sont pas tous nés égaux.
  • XML est très surfait.
  • “Trouver sur google” (googling) est bien.
  • Je n’arrive pas à comprendre pourquoi les gens pensent que Java est absolument le meilleur langage de programmation à enseigner en université
  • Si vous ne connaissez qu’un seul langage, quel que soit le niveau de connaissance de celui-ci, vous n’êtes pas un bon programmeur
  • La performance compte.
  • Les instructions “print” sont une manière valide de débugguer du code.
  • Les “Getters” et les “Setters” sont bien trop utilisés
  • SQL est du code. Traîtez-le comme tel.
  • Votre travail est de vous mettre au chômage.
  • Si vous êtes un développeur, vous devez être capable d’écrire du code.
  • La lisibilité est la chose la plus importante de votre code
  • Les diagrammes UML sont très surfaits.
  • L’utilisation de la notation hongroise doit être punie par la mort
  • Les modèles de conception font plus de mal à une bonne conception qu’ils ne l’aident effectivement.
  • Les tests unitaires ne vous aideront pas à écrire du bon code.
  • Ecrivez des méthodes courtes.
  • C’est acceptable d’écrire du code jetable de temps en temps.
  • Moins de code est mieux que plus de code.
  • PHP craint ;-)
  • Code == Conception
  • Il n’y a rien de mal à mettre des binaires dans le système de contrôle de code source.
  • Le développement logiciel n’est qu’un job.
  • Chaque développeur doit être familiarisé avec l’architecture des ordinateurs modernes
  • Les architectes / concepteurs de logiciels sont très surfaits.
  • Il n’y a pas d’approche « taille unique pour tout le monde » du développement.
Et ce n’est que la première page ! C’est du même acabit pendant 13 pages. On peut noter les autres opinions suivantes qui ont le mérite de provoquer aussi la controverse et force à réfléchir sur la futilité ou l’utilité de nos pratiques au jour le jour :
  • La plupart des programmeurs professionnels craignent un max.
  • Vous devez savoir taper à la machine pour être un programmeur
  • C++ est l’un des pires langages de programmation jamais conçu
  • Le monde a besoin de plus de GOTOs
  • Les architectes qui ne codent pas sont inutiles
  • Les programmeurs qui passent leur journée à répondre à des questions sur Stackoverflow ne font probablement pas le travail pour lequel ils sont payés.
  • Les mauvais programmeurs sont Langage-Agnostiques
  • Les utilisateurs ne sont pas idiots, vous l’êtes.
  • La documentation générée est presque tout le temps totalement inutile
  • Vous n’avez pas toujours besoin d’une base de données
  • Chaque développeur doit passer plusieurs semaines, voire des mois, à développer des systèmes sur papier avant de commencer à construire des systèmes sur électronique. Ils doivent aussi être forcés à utiliser leur système.
Tout cela est un méli-mélo de sagesse populaire, d’opinions tout faites, l’intérêt étant que tout porte à controverse, ça permet de se confronter à ce que ressent profondément notre profession (pour certains) ou notre « art » (pour les autres).

mardi 13 octobre 2009

Bases de données temporelles

Quand il s'agit de gérer des périodes de temps, SQL n'est pas très bien pourvu, et le modèle relationnel classique ne s'y prête pas naturellement. Sans essayer de passer par du TSQL2 et de s'attacher une technologie que finalement peu de monde utilise (l’utilisez-vous ?, je ne l’ai jamais vu en pratique sur des applications d'entreprise), on peut, avec malice, trouver des solutions pour représenter les différents états dans le temps d'un fait.

Tout est affaire de point de vue. Si vous avez une application tournant au dessus d’un modèle relationnel, il n’est pas nécessaire de modifier le code de celle-ci pour permettre l’historisation automatique des données manipulées.

Il n’y a qu’à remplacer les tables à historiser par des vues :
  • la vue a exactement les mêmes colonnes que la table qu’elle remplace
  • la vue est construite au dessus d’une table d’historisation contenant les mêmes colonnes qu’initialement, plus 2 nouvelles colonnes :
- DEBUT
- FIN
  • [DEBUT;FIN[ correspond à l’interval de temps pendant lequel l’entité a la même valeur (dans ses autres colonnes) (attention : DEBUT est inclus, FIN est exclu)
On peut vouloir stocker le temps-valide ou le temps transaction :

* Le temps-valide (ou « temps logique ») dénote la période de temps durant laquelle un fait est vrai par rapport avec la réalité.

* Le temps-transaction (ou « temps physique ») est la période de temps pendant laquelle un fait est stocké dans la base de données.

* La donnée bitemporelle combine à la fois le temps-valide et le temps-transaction.

A noter que ces deux périodes de temps n'ont pas à être égales pour un fait unique. Imaginez que nous ayons une base de données temporelle stockant des données relatives au 18ème siècle. Le temps-valide de ces faits se situe quelque part entre 1701 et 1800, tandis que le temps transaction débute quand on insère le fait dans la base de données, par exemple le 21 janvier 1998.

L’objectif est de pouvoir consulter la base de données à un instant T. Pour cela, il faut faire attention d’historiser aussi les données dépendantes par contrainte.

Les bases temporelles permettent souvent de différencier les programmeurs sur framework des programmeurs sur base de données. Un programmeur sur base de données va implémenter une base de données temporelle avec des vues et des triggers, offrant une vue propre des données à un instant T. Le programmeur sur framework va implémenter les règles de gestion du temps en Java au lieu d’utiliser des triggers et des vues et va aboutir, avec une grande probabilité, à une machine à gaz inmaintenable au bout de 3 mois.

Les vues et les triggers des bases de données sont des outils puissants et naturels pour implémenter :
  • le contrôle d’accès fin aux données,
  • l’historisation des données sous la forme de base de données temporelle.
Il est vain d’essayer de reproduire ces fonctionnalités au niveau de la couche applicative. Bizarrement, la mise en place de base de données temporelle est rarement évoquée sur asktom.oracle.com

Pour info, j'ai traduit la page Temporal database (Base de données temporelle) dans Wikipedia, histoire de combler à mon humble mesure le vide sidéral des articles informatiques en Français.

Pour en savoir plus sur les bases de données temporelle, autant consulter la liste de liens de Troels ou encore cette Introduction aux bases de données temporelles.

lundi 28 septembre 2009

Efficacité des tests unitaires

Les tests unitaires ne sont pas une solution à un problème, mais plutôt le symptôme de notre incapacité à produire du code correct dès le premier jet. Quand la même personne réalise le test unitaire et le code à tester, elle a toujours du mal à s'auto-critiquer, même en voulant honnêtement produire le code le plus propre possible. Un code est beaucoup plus critiqué, explicité, quand ce n'est pas la même personne qui code et qui teste. Cela me rappelle une étude citée par Steve McConnell dans "Code Complete 2nd Edition" qui m'apparut alors comme une révélation :
"Le test logiciel a une efficacité limité quand elle est utilisée seule - le taux moyen de détection d'erreur est seulement de 30 pourcent pour les tests unitaires, 35 pourcents pour les tests d'intégration et 35 pourcents pour des beta-tests de petits volumes. Par contre, l'efficacité des inspections de la conception et du code est de 55 et 60 pourcents. (Jones, Capers. 1996. "Software Defect-Removal Efficiency," IEEE Computer, April 1996)." -- Code Complete, 21.1. Overview of Collaborative Development Practices
L'inspection de code, formelle ou pas, est plus efficace que les tests unitaires et d'intégration. Avec de bonnes checklists, il est très intéressant de provoquer des critiques constructives sur chaque aspect d'une architecture et du code correspondant, en commençant par les plus sensibles. De plus, une personne porte beaucoup plus de soins à son code quand il sait que celui-ci va être inspecté par une autre personne. Une fois le squelette d'une architecture revue, il devient moins critique de relire tout le code développé sur celle-ci. Et on peut accélérer le développement comme nous le rappelle Jamie Zawinski :
"Les tests unitaires semblent biens en principe. Avec un rythme de développement tranquille, c'est certainement la voie à prendre. Mais quand on regarde de plus près, "nous devons aller de zéro à terminé en six semaines", et bien, je ne peux pas le faire à moins d'enlever quelque chose. Et ce que je vais enlever sont tous les trucs qui ne sont pas absolument critiques. Et les tests unitaires ne sont pas critiques. S'il n'y a pas de tests unitaires, le client ne s'en plaindra pas". -- Coders at Work
Quand les délais de livraison sont très courts par rapport à l'ampleur du code à développer, le ratio nombre de fonctionnalités sur le temps devient tel que le respect des délais est entièrement déterminé par la rapidité de frappe des développeurs sur leur clavier.

Et dans ce cas là, s'il n'y a pas de temps pour faire des tests unitaires, autant avoir des codeurs expérimentés codant juste du premier coup, ou sachant trouver la source de n'importe quel problème en un temps fini. Mais quand on en est à ce niveau, c'est qu'on n'est pas sure d'avoir du boulot si le logiciel à produire ne sort pas à la date cible.

Il peut être raisonnable de choisir de coder des solutions "Quick & Dirty" dans une première phase pour pouvoir respecter les délais tout en sachant qu'on contracte une dette technique importante qu'il faudra un jour payer dans une prochaine release sous peine de voir le logiciel se scléroser complètement.

Mais quel projet informatique, une fois parti sur le chemin séduisant du "quick & dirty" est prêt à payer sa dette pour revenir à un système "sain" de corps (le code) et d'esprit (la conception) ? Tant que le paiement des intérêts de la dette technique permette de continuer à développer de nouvelles fonctionnalités dans les temps impartis, qui se soucie de rembourser la dette ? s'il n'y a aucun intérêt business de nettoyer le code et l'architecture, mieux vaux continuer à coder comme avant.

J'ai rarement vu une maintenance d'un logiciel prenant régulièrement du temps sur chaque release pour corriger/mettre au propre des parties du code. J'ai toujours vu des applications devenir de grosses machines à gaz et être à terme refondue entièrement (la dette technique de l'application disparaît alors complètement). C'est peut-être malheureux à dire, mais c'est la sombre réalité du monde de l'informatique : la plupart des applications sur lesquelles nous sommes amenés à intervenir ont une énorme dette technique, et on a rarement l'espoir de voir s'améliorer une application sans que celle-ci soit entièrement refondue.

Il faut s'y faire, et autant apprendre à coder juste et de façon défensive dès le premier coup.

jeudi 17 septembre 2009

Inadaptation d’impédance objet-relationel : plus qu'une inadaptation, une incompréhension

Cet été 2009, Thomas Kyte, expert développement sous Oracle bien connu, s’est largement étendu sur son site AskTom de questions/réponses, sur l’inadaptation d’impédance objet-relationel (object-relational impedance mismatch). Sur un ton direct et tranchant, il nous délivre son point de vue sur la place des « applications » notamment Java EE et de leurs rôles dans la gestion des données. Il fini par énoncer cette règle à suivre absolument :
Ne laissez aucun développeur qui code en Java, Visual Basic, C et autres langages de ce genre, écrire du code contenant SELECT, INSERT, UPDATE, DELETE ou MERGE dedans. Donnez leur accès à une série de procédures stockées qui retournent les données dont ils ont besoin, ou qui traitent les transactions nécessaires au système lui-même.
Assez radical il est vrai, Tom ne considère les applications au dessus des bases de données que comme de simples interfaces homme-machine (en gros, de simples JSP ou pages PHP suffisent pour faire interagir un client avec le serveur de données). Pour lui, autant ne pas donner aux applications un accès direct aux tables, au modèle de données parce que les applications vont et viennent rapidement mais les données,… les données vivent pour toujours ! :

… je peux à la rigueur mettre tout le SQL dans la base de données au lieu que dans du XML, ce n’est ni un gros problème pour moi ni un gros gain d’un côté technique…

Cela m’indique (« ni un gros gain ») que vous n’avez pas fait de bases de données depuis longtemps. Votre application – la chose pour laquelle vous vous concentrez aujourd’hui en 2009 – elle n’existera plus vers 2013. Mais la donnée, elle, sera toujours là. Et si vous avez caché tout ce qui concerne les données dans votre application obsolète écrite dans un langage mort, avec des frameworks que personne ne considère plus utiliser (rappelez-vous, c’est 2013, plus 2009 maintenant) – vous nous forcerez à l’en arracher entièrement et à le recommencer.
Le reste des réponses de Tom est du même acabit. C’est comme si le monde était séparé en deux : les programmeurs sur framework et les programmeurs sur base de données. En entreprise, la plupart des applications existent pour gérer l’information, gérer des données. Les traitements associés sont rarement compliqués et ne font jamais appel à des experts en algorithmie.

Dans quel cas a-t-on réellement besoin d'une machine à gaz ORM ? Quels sont les clients qui analysent leur métier en termes d’objets ? Parmi ces clients, quels sont ceux qui comprennent toutes les notions, aspects et pièges de l’orienté-objet ?

J’ai rencontré il y a quelques temps, en 2007, un client pour lequel j’ai du réaliser un audit de sécurité sur son application Java. Quand arrive le moment de lire le code source de l’application (qui date de 2002), un effroi (les englishs diraient, « WTF » à ce moment là) m’envahi quand je réalisai que ce qui avait été codé était un véritable serveur d’application complet codé à la main, spécifiquement pour ce client !

Ah, les développeurs s’en étaient donné à cœur joie pour créer cette majestueuse machine à gaz, capable de gérer des composants aussi complexes que des EJB 1.0, inmaintenables et inmaintenu actuellement, puisque plus personne n’a plus le temps de se pencher sur son fonctionnement, les développeurs initiaux ayant changés au moins 3 fois de société de service entre temps. Et puis, ce n’est pas un simple serveur d’application minimaliste qui a été codé, mais un énorme tas de technologies du moment comme par exemple, CORBA et IIOP qui étaient en vogue au moment du développement de cette application.

J’aurais pu me dire que tout cela était nécessaire à l’époque, notamment pour supporter une charge importante, des changements de configuration fréquents, un clustering, de la réplication de sessions, de l’intégration d’autres systèmes… Que nenni ! Toute cette machinerie ne sert qu’à gérer une cinquantaine de tables dans une base oracle et ne fait qu’1 ou 2 appels vers des WebServices, 1 intégration avec un LDAP… et puis c’est tout !


Autant dire que tout ce code Java ne sert strictement à rien ! Et coûte énormément à maintenir… Une simple application générée par « Oracle Application Express » aurait suffit. Je vous passe les autres détails de l’architecture de cette application, qui révèle bien que le client n’a pas du tout investi sur sa base de données mais uniquement sur des programmes en Java… Pour quelle raison ? J’ai beau tourner maintes et maintes fois la question dans ma tête je ne vois pas de raison logique à tout ça. C’est certainement une question de mode du moment.

jeudi 10 septembre 2009

Template, Modèle de Construction, Code Snippet : une réutilisation nécessaire

Quelle est la plus importante habitude à prendre dans sa carrière d’informaticien ? On passe souvent des heures voire des jours à faire fonctionner un morceau de code, et on apprend toujours beaucoup de choses pendant ce processus de conception. La conception a cela de pervers qu’on ne connaît la bonne solution qu’une fois qu’on la conçue.

Ainsi, la conception est toujours un processus assez long et périlleux, il est donc plus que nécessaire de capitaliser sur ses expériences et les expériences des autres. La meilleure application étant celle pour laquelle on n’a à développer aucune ligne de code, la capitalisation qu’on entend ici est donc la constitution d’un ensemble de « modèles » (templates) ou « d’extrait de code » (code snippet) configurables, personnalisables et extensibles à souhait.

Quand on y pense, même pour des applications simples à concevoir comme des sites Web au dessus d’une base de données, il y a tellement d’exigences et de contraintes à prendre en compte (comme par exemple, la disponibilité, la sécurité, les performances…) qu’un cerveau humain n’est pas la plus fiable des machines pour les concevoir. Ne serait-ce que du simple fait qu’un être humain n’est pas constant et oublie vite les détails.

Ce qui motive le plus un informaticien à faire de la conception c’est l’objectif de ne jamais avoir à recoder deux fois la même chose, ou, mieux encore, ne jamais recoder deux choses similaires. Le copier/coller de code à la main (pratique la plus répandue dans notre profession, bien plus que l’exercice de réflexion) est à généraliser dans le cadre de la construction. Les « templates » permettent de générer des milliers de lignes de code et ce, sans l’introduction de bug si votre modèle est parfait.

Les templates : bien mieux qu'une photocopieuse...

La programmation orienté modèle (Template-oriented programming) devient de plus en plus pertinente du fait de la standardisation des solutions et des conceptions sous-jacentes, notamment par l’application des « modèles de conception ». A l’instar des modèles de conception, les templates de code pourraient s’appeler des « modèles de construction », puisqu’il s’agit de standardiser/automatiser la construction d’application. Autrement dit, il devient facile de récupérer des applications correctement codées comme, par exemple, les exemples d’application fournis par Spring (situées dans le bundle Spring) ou dans le Java EE SDK, d’en créer des modèles de code et d’automatiser la création d’application standard en fonction d’un modèle conceptuel des données et des traitements.

La meilleure pratique à s’imposer dès son plus jeune âge dans le métier est donc la transformation de code s’exécutant (« running code ») en code réutilisable pour d’autres projets. Personnellement, je me suis construit une petite application Web pour recueillir tous mes templates, et me permettre de générer du code en fonctions de configurations et de modélisation des informations à gérer. Mais ce genre d’outil se retrouve dans pratiquement tous les IDE dignes de ce nom par exemple Visual Studio, Eclipse, Emacs (avec aussi les abbrevs par exemple) ou dans d’autres outils innombrables (par exemple CodeSmith) …

J’essaie de passer du temps en fin de projet pour réutiliser de tout code qui a été programmé à la main. Comparez le temps nécessaire pour transformer du code en template et le temps que l’on peut gagner quand on va générer des applications avec ces nouveaux templates, et vis-à-vis du nombre de fois qu’on va générer ce code. On y gagne dans la plupart des cas. Il faut bien sur, faire attention à la licence associée au code source.

Qu’est-ce qui sépare un développeur d’un développeur expérimenté ? Le nombre de « modèles de construction » à sa disposition et sa capacité à programmer automatiquement. Faire soi-même un système de génération de code source ou d’application complète permet de maîtriser ce que l’on génère pour mieux en connaître les limites.

Qu’est-ce qui sépare un développeur expérimenté d’un guru respectable et respectée ? Le guru fait de la génération de code qui génère du code qui génère du code… Il fait de la production de modèle de construction, un processus récursif.

On peut extraire des modèles à partir de ses expériences sur des projets, mais on peut tout autant tirer parti des expériences des autres, à partir des exemples donnés dans les livres techniques. Toute lecture d’un livre doit s’accompagner d’un enrichissement de son système de génération de code. A chaque fois que je crée un modèle, je me demande « qu’est-ce qui peut être différencié dans ce code : qu’est-ce qui peut être demandé par un client, qu’est-ce qui est du ressort de l’implémentation uniquement ».

Les templates peuvent être utilisés pour autre chose que la génération de code comme par exemple :
  • générer automatiquement de la documentation (avec des formats de fichier sous format texte comme le RTF, XML par exemple)
  • générer automatiquement de la configuration de middleware comme la configuration d’Apache httpd ou tomcat, ou la configuration de progiciels…
Le domaine d’application de la génération de fichier est sans limites… Un système de gestion de templates peut servir aussi à se souvenir de l’ensemble des paramètres à saisir, l’ensemble de questions à se poser, comme une checklist ce qui permet de ne rien oublier.

A chaque fois que je code quelque chose j’essaie de me poser la question : est-ce que je serai capable de reproduire ce code dans 5 ans sans réfléchir ? Pour être sur de pouvoir ressortir ce code plusieurs années après, je le transforme en template et mon système doit permettre de générer du code qui s’exécute sans problème ou doit fournir des instructions suffisamment claires pour l’intégrer ou l’exécuter.

Et après ça, je peux oublier ce bout de code et dormir sur mes deux oreilles…

jeudi 3 septembre 2009

L'orienté objet : plus qu'un cache misère

Quels sont les caractéristiques principales d'un programme écrit par un néophyte ? des noms de variables incompréhensibles ? aucune organisation du code ? La pire, et malheureusement la plus fréquente, car inhérente à l'incompréhension de la notion d'abstraction, c'est l'utilisation généralisée de variables globales.

L'emploie de variables globales, faut-il le rappeler, est considéré comme une mauvaise pratique, du fait même de sa "non-localité" : une variable globale peut être modifiée de n'importe où (sans même parler de sa volatilité), et n'importe quelle partie d'un programme peut en être dépendante. Cela rend donc le programme inmaintenable à partir d'une certaine taille.

Vulgaire pédanterie d'un béotien en mathématique : l'emploi de variables globales et les dépendances qu'il instille entre toutes les parties d'un programme me fait penser visuellement à un pavage hyperbolique du disque de Poincaré. Il montre bien que toute chose est dépendante d'une autre et change de couleur aux croisements des autres dépendances.

L'orienté-objet force à l'abstraction mais n'empêche pas les variables globales de proliférer. Au delà d'éléments globaux d'une application, l'emploie de variables globales s'est immiscé subrepticement au cœur des classes d'objet, et le paradigme Orienté-Objet en a fait son beurre.

On pourrait même croire que, suite à la reconnaissance, par toute la communauté des programmeurs, de l'emploie de variables globales comme mauvaise pratique, des êtres mal intentionnés auraient inventés un paradigme leur permettant de programmer localement avec des variables globales, de restreindre, en fait, les variables globales à quelques fonctions.

L'orienté-objet n'est qu'une manière déguisée de programmer en utilisant des variables globales. Il pousse (mais n'oblige pas) à s'intéresser aux invariants de classe et d'objet, de savoir, en fait, gérer des variables globales pour qu'elles ne posent aucun problème lors de l'appel des méthodes.

Nombreux ont été les échecs quant à la préservation de l'intégrité des données d'une classe vis à vis de ses méthodes. Il est apparu, avec le temps, des principes de construction d'une classe, qui permettent de mettre de l'ordre dans la gestion de ces variables globales, locale à un objet ou à une classe d'objet. Ces principes ont été clairement exprimés par Robert C. Martin dans ses livres et sur le site Web de sa société Object Mentor.

Les principes de conception de classes orientée-objet sont regroupés au travers de la mnémonique SOLID, et permettent ainsi de surpasser la difficulté de maintenir des données globales dans un objet :
  • S : Single Responsability Principle (SRP) : There should never be more than one reason for a class to change.
  • O : Open-Closed Principle (OCP) : A module should be open for extension but closed for modification.
  • L : Liskov Principle (LSP) : Subclasses should be substitutable for their base classes
  • I : Interface Segregation Principle (ISP) : Many client specific interfaces are better than one general purpose interface
  • D : Dependency Inversion Principle (DIP) : Depend upon Abstractions. Do not depend upon concretions.
Robert C. Martin énonce aussi des principes d'architecture des modules (packages) très intéressants qui permettent de mieux gérer les dépendances des modules entre eux à fin de tenir la plus grande promesse de l'orienté objet : la réutilisabilité.
  • Release Reuse Equivalency Principle (REP)
  • Common Closure Principle (CCP)
  • Common Reuse Principle (CRP)
  • Acyclic Dependencies Principle (ADP)
  • Stable Dependencies Principle (SDP)
  • Stable Abstractions Principle (SAP)
Ces principes sont tout aussi importants que ceux relevant de la conception de classes, et des outils permettent de vérifier de façon automatique dans la plupart des cas, qu'on ne les enfreint pas. C'est le cas de JDepend dans le monde Java, NDepend pour le monde .NET, PHP Depend, Module::Dependency pour Perl...

C'est bien le genre de métrique qu'on a envi, en tant que chef de projet, de mettre dans les 'hooks' de subversion et de bloquer tout commit qui ne les satisferait pas. Quand on a la responsabilité d'un projet pour lequel on vous a affecté sans possibilité de discuter, des débutants, on croit toujours pouvoir être Big Brother et scruter le moindre faits et gestes des développeurs, en leur mettant par exemple, comme dans les sous-doués passe le bac, une bonne décharge électrique à chaque fois qu'ils essaient de commiter du code pas convenable.

Le problème c'est que tout ces principes ne sont pas toujours mis en œuvre dans les modules et librairies de base des langages comme Java notamment (par exemple, la fameuse classe Date qui au fur et à mesure des versions de java s'est vue refondre entièrement sans jamais atteindre une bonne implémentation, des fous sont même allez jusqu'à déposer un brevet logiciel pour refondre cette classe. La description du brevet est instructive sur les limites de la classe Date)

Ceci dit, une orientation objet bien maîtrisée peut aboutir aux nobles objectifs qu'elles s'était fixés dans la mesure où l'on sait que l'on joue avec le feu des variables globales.

jeudi 27 août 2009

De l'agilité des légos et des logiciels afférents

Il faut bien avouer cette sombre évidence : un informaticien cherche toujours à ramener son travail à un jeu de légo.

Loin d'être un trouble obsessionnel compulsif, il lui semble que le monde devrait être plus simple, et devrait normalement se soumettre à la réduction induite par la modélisation.

Si la construction d'application s'apparentait à des Légos comme le sous-entend OSGi, on n'aurait pas besoin de développeur, il suffirait d'emboîter des composants les uns dans les autres. Or, l'innovation d'une application n'est pas là. Vous pouvez faire de très belles constructions en légo, mais l'utilité de celles-ci restera à démontrer par l'expérience. Le simple rapprochement de fonctionnalités dans une combinaison originale peut s'avérer intéressante dans certains cas, et toute une profession s'en contente largement en attendant la prochaine véritable innovation.

Au delà de la réduction à un jeu de légo, nombreux sont ceux qui cherchent à insuffler une marque de sérieux à une activité dénigrée dès qu'on prononce son nom : la programmation. Le mot programmation est connoté négativement par tous les professionnels et clients du secteur informatique. Ce terme ramène trop à la base de l'activité, au travail le plus bas niveau et pourtant le seul qui produise de la valeur réelle : la création d'un programme en vue de le faire exécuter par l'automate informatique. Pour cacher la dure réalité d'une profession de tapeur à la machine, nombre d'informaticiens ou pseudo-informaticiens se vêtissent d'un jargon sans cesse renouvelé pour mieux périmer les vieux termes et ceux qui les utilisent encore.

Aujourd'hui, seules les méthodes "agiles" sont considérées comme crédibles. Une pratique de développement logiciel qui ne s'apparente pas au mouvement "Agile" est à priori suspecte. L'ajout d'un adjectif comme agile à des noms déjà vagues, prête souvent à confusion, car cela pousse à croire que les objets en questions sont relatifs. Cela s'apparente au relativisme ambiant : le relativisme culturel que des intégristes religieux cherchent à promouvoir pour justifier leurs agissements dans certaines contrées, ou comme dernièrement, le Président de la République Française avec sa "Laïcité positive" (sous entendu, il existe une laïcité négative). Une méthode agile exclue toutes les autres et les ramène au rang de méthodes forcément non-agiles, donc lourdes, dépassées, ...

Hep, Hep, toi qui veux être dans le coup, sache que "Agile" est maintenant un terme dépassé, il faut parler de ARxTA ... "Agile", comme tout terme-réclame est utile aux professionnels, tant pour les clients que pour les fournisseurs de solutions. Cela permet de rapprocher des points vus autour de mots clés clairement identifiés, ce qui créé une sorte de communauté avec ses codes, son jargon, ses pratiques, techniques et traditions : une véritable culture en sorte.

Au delà de ces mouvements passionnés, des individualités surgissent, émergent, montre les nouvelles cimes à atteindre par leurs actions au jour le jour. Il est toujours étonnant de voir que malgré les énormes entreprises commerciales aux bénéfices records (même en ces temps de crise), de simples individus arrivent à imposer leurs créations comme autant de nouvelles évidences pour la profession. C'est pourtant dans de petits bureaux, dans de non moins petites salles IRC de discussions que se forgent les technologies de demain. Une startup sait qu'elle est sur la bonne voie quand elle peut produire son application sans recours à des fonds extérieurs, ces fonds ne servant qu'à accélérer plus ou moins un mouvement incessant et irréductible, dirigé vers la réussite.

Pour illustrer la capacité d'un individu à produire de petites merveilles, j'ai pensé vous faire profiter de la voix cristalline de Imogen Heap qui, aidé par un MacBook il est vrai, arrive, à elle seule, à oindre de saintes notes de ses propres mains dans nos esgourdes.



Non, on a beau dire que la perfection n'est pas de ce monde, mais le chemin de l'excellence cherche à nous y mener en tout cas, chaque jour nous ramenant à la dure réalité et à notre propre dépouillement face à la grandeur des exigences et contraintes de nos applications. Ce n'est pas ce qu'on appelle le mythe de Sisyphe ?

jeudi 20 août 2009

Grippe A (H1N1) : l'avez-vous mise dans les risques de votre projet ?

La grippe A (H1N1) va (ou est déjà) arriver massivement en France, avec normalement un pic en septembre 2009. Ce n'est pas une grippe qui semble plus grave qu'une autre mais elle a la particularité d'être très contagieuse. Ce qui veut dire qu'il y a un risque réel d'avoir 5 % à 15 % des effectifs des projets absent 1 ou 2 semaines un jour ou l'autre pour arrêt maladie. Ce peut être aussi des parents qui s'absentent pour garder leurs enfants car ceux-ci ne peuvent plus être reçus à l'école pour cause de grippes trop nombreuse dans leur classe.


En bref, la probabilité d'avoir des ressources en moins sur les projets est très forte et doit normalement être prise en compte dans votre suivi des risques, sous peine d'avoir de grosses surprises et d'autant plus grosses déconvenues sur les estimations des délais de livraison.

Si vous pensez pouvoir arguer que vos retards de livraisons sont dus à la grippe et que votre client ne va pas ciller face à cet argument, bien à votre aise de ne pas suivre ce risque et de laisser aller vos projets tels qu'ils sont aujourd'hui.

Dans le cas contraire, il est temps de suivre le risque, de se préparer à contrer les absences, ainsi que renégocier les modalités de livraison avec vos clients : vous pouvez toujours tenir vos délais et enlever certaines fonctionnalités de la listes des fonctionnalités obligatoires à livrer (les mettre alors dans la listes des fonctionnalités "si possible").

En tout cas, il faut être clair avec le client sur ce risque pour éviter toute surprise mal venue.

Il est toujours inquiétant de voir que dans certaines sociétés, le rythme des projets et des livraisons envisagées n'a pas baissé, voire a même augmenté pour répondre à la crise. Mais c'est prendre un gros risque que d'ignorer ce qui va arriver de façon quasi certaine. Le fait qu'on ne maîtrise pas les impacts de la grippe n'est pas une excuse pour ne pas les anticiper.

Que vous soyez chef de projet, directeur de projet ou simple exécutant, pensez à voir l'impact de votre absence ou de l'absence de vos confrères sur les projets sur lesquels vous travaillez. Je serais vous, je ne prendrais pas d'engagement inconsidérés durant la période de cette rentrée 2009. Mais qui prend d'ailleurs d'engagements inconsidérés ? Le tout est de considérer que les changements sont inévitables sur les projets, et il s'agit de les gérer explicitement.

jeudi 13 août 2009

Dates cibles et échéances : compromis comme promis

Tout le monde a, un jour, travaillé sur un projet si mal défini ou si maladroitement suivi qu'on a plus qu'une seule envie : quitter le radeau avant qu'il ne coule. Vu la proportion gigantesque de projets ne respectant ni ses délais, ni son périmètre initial ou ses coûts (source), il est très probable que vous ayez déjà participé à ce genre de fiasco.

Dans les projets à la dérive, les échéances (deadlines) sont souvent dépassées, faisant éclater des disputes sans fin dans le but de trouver des coupables, mais surtout pas d'essayer de remettre de l'ordre pour la suite du projet.

Quand ces horribles projets finissent par mourir définitivement (et ça peut prendre beaucoup de temps !), il est toujours intéressant de se pencher dessus à froid, pour essayer de comprendre ce qui n'a pas marché. Ce travail de reflexion à posteriori (les anglosaxons aiment bien utiliser le terme « project post-mortem ») est malheureusement trop rarement effectué, ou seulement de façon incomplète.

Sur plusieurs de ces projets, on s'aperçoit que les échéances ont été définies avant même d'estimer quoique ce soit sur le projet. De plus, ces dates n'ont jamais été remises en causes pendant toute la durée du projet. Est-ce que ce sont réellement des échéances (deadlines) ou seulement des dates cibles (« target dates ») ? Une date cible est bien différente d'une échéance. C'est ce que décrit clairement Conrad Weisert dans son article « Les échéances et dates cibles des projets : 5 conseils pour éviter le désastre » :
La plupart des « échéances » (deadlines) ne sont en fait que des dates cibles. La différence réside dans ce qui survient si la date n'est pas respectée :
  • quand une échéance est ratée, il ne reste plus aucun intérêt à compléter l'engagement. Par exemple :
    • s'inscrire à une compétition
    • publier le catalogue de Noël prochain
  • Quand une date cible est ratée, les conséquences peuvent être aussi désastreuses que pour une échéance, mais vous avez toujours à finir le travail. Si « date cible » semble trop vague pour vous, alors remplacez cette expression par « date de fin » ou « date de livraison ».
Encore faut-il gérer correctement la planification d'un projet de développement pour pouvoir définir des dates cibles ou des échéances. Cela nécessite de maîtriser un tant soit peu l'art délicat de l'estimation et d'être en mesure d'offrir des preuves de celle-ci.

Sur son site, Conrad revient sur ces notions importantes, en relation avec la gestion de projet et le développement logiciel. L'estimation n'est pas qu'une affaire d'expérience. C'est aussi et surtout le moyen de montrer par « a + b » qu'un projet tiens la route et saura tenir ses délais. Or seul celui qui dit que quelque chose peut être fait doit en apporter la preuve. Un client ou une division Marketing d'une entreprise se doit d'être ambitieux quant à la définition du produit et à ses dates de livraison ou de mise sur le marché. Or ce n'est ni le client ni cette division marketing qui vont prouver qu'on est capable de réaliser ses rêves. C'est au chef de projet (ou au chargé d'affaire dans le cas de sous-traitances de développement) de trouver des solutions qui puissent répondre au mieux aux exigences et contraintes exposées.

La définition de plan permet d'éclaircir le projet et de notamment exprimer de nouvelles exigences et contraintes liées aux solutions. Ce n'est qu'en face des éléments issues de toutes les parties que l'investisseur (le client, la division marketing...) lance le projet.

Dans le cadre de la sous-traitance de production (pour le développement logiciel au forfait par exemple), il est facile pour un chef de projet de se faire imposer des dates cibles du simple fait:
  • de la relation contractuelle qui existe entre le client et son cahier de charge d'un côté, et le fournisseur et sa volonté de gagner le contrat de l'autre (souvant « à tout prix »).
  • de la rédaction de la réponse à l'appel d'offre par une personne (un « chargé d'affaire ») autre que celui qui va mener le projet jusqu'à son terme.
Même dans le cas de sous-traitance, il est souhaitable que la réponse à l'appel d'offre soit ambitieuse et rédigée par une personne autre que le chef de projet, car ce dernier a naturellement tendance à voir énormément de risques et à avoir une attitude extrêmement prudente, encore plus s'il n'est pas « intéressé » personnellement (oui, oui, par cette basse chose qu'on appelle « l'argent ») au projet. Mais c'est au final, au chef de projet de ramener tout le monde à la réalité.

jeudi 6 août 2009

AJAX et Performance : un oxymore

N'avez-vous pas l'impression qu'AJAX (Asynchronous Javascript and XML) nous ramène en un temps où les ressources matérielles étaient chères et lentes, où les compilateurs ne savaient rien optimiser et qu'il était difficile de fiabiliser son code ? Développer en Ajax, c'est retrouver le bidouillage d'antan, quand il fallait lutter à chaque pas contre les limites du système cible. Oui, ce satané Javascript qui a plus à voir avec Lisp qu'avec Java, est bien la cause de ce problème. Où plutôt la mise en œuvre de ce langage dans un paradigme (AJAX) créé dans le but unique de palier aux problèmes d'un autre paradigme (le Web) pour obtenir des applications d'un paradigme historiquement éprouvé (le Client-Serveur).

En effet, les technologies supportant l'AJAX sont plus qu'inefficaces, elles sont inappropriées. Les navigateurs Web ne sont pas conçus à la base, pour être des plateformes d'exécution d'application.
Javascript a été mis en place dans les navigateurs (Netscape Navigator à l'origine) pour palier à l'aspect statique des pages et du protocole orienté document qu'est HTTP.

Pour que Javascript s'exécute rapidement, il a donc fallu implémenter un interpréteur très simple et ne réalisant que peu d'optimisations. On ne retrouve pas en Javascript les optimisations que l'on considère comme évidentes dans n'importe quel autre compilateur :

Il faut donc coder en Javascript d'une manière spécifique, en connaissance de cause. Cette leçon nous est donnée par Douglas Crockford dans sa présentation « Ajax Performance ». Il nous donne quelques exemples puis exprime la philosophie générale de l'optimisation Ajax : Alors qu'il est logique de penser qu'il faut toujours essayer d'avoir des algorithmes de complexité en O(1), O(log n) plutôt que O(n), O(n2) ou O(en), l'important est d'avoir n le plus petit possible quelque soit la complexité. Le client Ajax n'est là que pour présenter une vue réduite des données du serveur.

Ce qui est étonnant c'est l'intitulé de la série de présentation de Douglas qui s'appelle « Javascript : the good parts ». Je comprend bien qu'il veuille prêcher pour sa paroisse, son langage de prédilection, mais heureusement qu'il a un œil critique sur sa technologie fétiche et montre bien qu'il faut aller bien loin pour trouver de « bons côtés » à Javascript. Il a du vouloir attirer tous les zélotes de l'Ajax et du javascript à sa présentation pour mieux leur montrer les limites de leurs croyances. Car toute « nouvelle » technologie , s'apparente plus à l'émergence d'une secte qu'à une avancée scientifique majeure. AJAX n'est plus très nouveau d'ailleurs.

Heureusement la réalité est toujours là et les « bonnes pratiques » informatiques sont toujours d'actualité même en Javascript. Douglas ne fait que reprendre à raison les principes éprouvés de l'optimisation de code.

On a beau critiquer Javascript, on peut aussi l'apprécier pour ses aspects qui le différencient tant de Java justement, comme par exemple : l'héritage par prototype, la programmation fonctionnelle que l'on peut en faire, notamment, grâce aux fonctions d'ordre supérieur. Le Javascript est, de fait, un des langages les plus utilisés aujourd'hui.

Ça peut être amusant de faire de l'Ajax (c'est d'ailleurs quelque chose que nombre de développeurs réalisaient il y a de cela déjà bien longtemps, avant même qu'on y mis un nom dessus) mais franchement, aujourd'hui, ce qui est le plus productif c'est de ne carrément pas coder du tout : utiliser des outils pour générer les interfaces graphiques et des applications.

Qu'on le veuille ou non, le coût d'un développeur français est tellement élevé par rapport à un développeur indien (7 à 10 fois son prix) par exemple qu'il devient complètement improductif de lui demander de développer à la main des applications Ajax.

En france, à Montpellier, il y a PC SOFT (un nom de boîte qu'on imagine sans hésitation sortir des années 80) qui produit WEBDEV dans le même esprit que WINDEV. Parmi mes collègues développeurs, rare sont ceux qui préconise de développer avec de tels outils de génération d'application. J'ai l'impression qu'ils disent cela parce que WINDEV est vieux et que tout ce qui est vieux en informatique devient plus ou moins ringard.

Personnellement, leur nouvel outil WEBDEV semble intéressant pour produire des applications Web / AJAX sans coder quoi que ce soit. Pour la plupart des petites et moyennes applications, c'est largement suffisant car ce sont essentiellement des applications de gestion de l'information. Dans le cas de besoins spécifiques, on peut toujours développer spécifiquement une extension et l'intégrer à l'application.

Il existe aussi Oracle Application Express pour la génération automatique d'application au dessus d'une base Oracle sans écrire une seule ligne de code. Ce composant est souvent disponible chez les client qui ont achetés des licences database serveurs, sans qu'ils le sachent vraiment. Le client paie cher des technologies dont seulement 10% sont réellement utilisées (et ces 10% se retrouvent souvent aussi bien en Open Source...)

Tout cela va dans le sens de considérer XML, HTML, CSS et Javascript comme étant du binaire illisible qu'il s'agit de traiter uniquement via des outils de haut-niveau et des ateliers de génie logiciel (AGL). Seul les développeurs de composants et d'atelier logiciels ont à se pencher sur ces technologies au jour le jour.

mercredi 15 avril 2009

Travailler de manière productive

Faisant parti d’un grand groupe de télécommunication, je suis amené à être en contact avec de nombreux interlocuteurs, pour les divers projets que je mène en parallèle. Par jour je reçois entre 50 et 100 emails nouveaux. Mon travail est asservi par de nombreuses « deadlines », des échéances qu’on ne peut louper sous peine de retarder le projet de 4 à 6 mois.

Pour gérer un tel flux d’informations, d’actions à entreprendre, et de travail à réaliser, il faut s’organiser. Par la force des choses, j’ai du adapter ma façon de travailler pour rendre les choses maîtrisables et efficace.

Tout d’abord, mon outil principal, quand je fais de la direction de projet (ou de programmes dans certains cas), c’est mon client email : Outlook en l’occurrence. Par bien des aspects, cet outil peut en énerver plus d’un, mais, par d’autres, il devient indispensable et irremplaçable par d’autres outils du marché (que ça soit opensource ou non).

Quand mon flux d’email quotidien ne dépassait pas les 20 emails par jours, je triais chaque email reçu en fonction de son projet associé, et du type d’email. Mais quand on en est à plus de 50 emails par jours, le tri devient inutile voire constitue une perte de temps certaine. Quand on se rend compte que la durée de vie d’un email est parfois très courte (quelques minutes) à quoi bon trier.

La solution : ne plus trier ses emails et faire de la recherche full-text ou par champs dans tout vos emails. Pour ne pas surcharger le serveur d’email, j’archive tous les emails du serveurs qui ont plus d’1 jour. L’archivage consiste à mettre les emails du serveur sur mon disque local dans un répertoire Outlook du même nom : Inbox. Oui, tout est dans Inbox, je ne trie plus rien, à quoi bon perdre du temps quand on peut faire une recherche détaillée sur l’ensemble de ses emails.

Bien sur, inutile de compter sur l’outil de recherche fulltext de Outlook qui est complètement désuet par rapport à l’ampleur de la tâche : rechercher un email particulier dans une archive contenant plus de 2 ans d’emails (20Go de données) est impossible pour l’outil standard Outlook. Il vous faut un outil de recherche bien plus puissant. Et j’ai trouvé ça avec Lookout, outil maintenant disparu mais que le développeur original de l’outil à montré comment l’installer par soi-même via une petite manip.

J’ai réussi à installer Lookout sur Outlook 2003 sans problème en suivant la procédure. Et maintenant je n’utilise plus que cet outil pour faire de la recherche fulltext. Rendez-vous compte, avec son puissant système d’indexation basé sur Lucene.NET, il est capable de me retrouver un email par tous mes emails en moins d’une seconde ! C’est vraiment un outil pratique quand on a gérer des tonnes d’emails. En plus, il permet de faire des recherches compliquées sur les emails, par exemple, selon les valeurs de certains champs (To, From, Subject…)

Pour s’y retrouver parmi les emails, j’utilise aussi les Flags et les vues. Si je détecte des actions à réaliser lors de la lecture d’un email, je me pose la question : est-ce que l’action prend moins de 2 minutes à réaliser (cf. GTD). Si oui, alors je fais l’action tout de suite, sinon, je flaggue l’email :
o En Rouge : pour une tâche à faire ASAP

o En Orange : pour une tâche qui peut être remise à plus tard (peut attendre)

o En Vert : pour une tâche que je dois déléguer

o En bleu : pour une tâche déléguée pour laquelle j’attends une réponse

o En violet : pour un email qu’il faut que je lise mais qui peut me prendre du temps
Quand un email nécessite plusieurs tâches, ou si la tâche n’est pas évidente d’après l’email, je crée un nouvel email que je m’envoie et retrouve donc dans mon Inbox. Je luis attribue alors un flag comme décrit ci-dessus. Pour chaque tâche j’essaie de mettre aussi la « Due date », l’échéance à respecter pour finir la tâche.

Avec une telle organisation, adaptée de Getting Things Done de David Allen, je suis capable de gérer des centaines d’emails par jour tout en « prioritisant » mon travail et permettant ainsi de travailler de long moment sur une seule activité tout en sachant qu’est-ce qu’il me reste à faire après, sans oublier une seule tâche.

Ce qui est important dans tout ça, c'est de déterminer quelles sont les tâches qui ont vraiment de l'importance et celles qui n'en ont pas ou moins. Car faire plein de choses sans importance permet de remplir facilement sa journée de travail, mais n'aboutis à aucune valeur ajoutée.

samedi 28 mars 2009

Délire paranoïaque de programmation

N'avez vous jamais eu envie de contrôler entièrement l'environnement informatique cible de votre programme pour être sûr à 100% de ce que vous développez ? C'est certainement le rêve d'un paranoïaque doublé d'un introverti incapable d'accepter les limites de ce monde (et de lui-même par la même occasion). Mais dans le monde en crise qu'est supposé est le notre, avoir l'entière maîtrise d'un monde binaire peut se révéler rassurant pour certains. Même si cette passion est destructrice quand on ne s'ouvre plus sur le reste du monde.

Le vrai délire créatif des paranoïaques que nous sommes, nous les informaticiens, passe par la connaissance des fonctionnements les plus bas niveau de la machine, d'arriver clairement à savoir ce qui se passe en temps réel dans chaque partie de l'ordinateur. Quelle joie alors de programmer pour une console de jeux plutôt que sur un boufficiel comme l'est un système d'exploitation commercial. C'est ce que nous rappelle Jasper Vijn dans son excellent tutoriel pour le développement GBA :
D'un point de vue programmation, le GBA (ou n'importe quelle autre console) est totalement différent d'un PC. Il n'y a pas de système d'exploitation, pas de pagaille avec des drivers et des incompatibilités avec le matériel. Ce sont des bits aussi loin que l'oeil puisse voir. En fait, les PC ne sont aussi que des bits, mais c'est plusieurs niveaux en dessous. Sur une console, c'est juste vous, le CPU et la mémoire. En gros, c'est le rêve du Vrai Programmeur.
Quand on en vient au niveau bit, on est confronté à plein de ravissantes choses comme l'ABI (Application Binary Interface) et plus spécifiquement l'EABI ARM pour ce qui est du développement pour GBA ou NDS.
La compréhension de ce qui se passe en dessous du langage de programmation de haut niveau devient nécessaire, si ce n'est obligatoire pour éviter de grosses bévues. Savoir programmer au niveau assembleur n'est pas forcément inutile quand vous êtes embarqué dans un projet de type Java ou .NET. Comprendre le bytecode et la JVM peut se révéler utile dans certains cas, notamment pour la maîtrise des performances.

C'est ce que nous montrais brillamment Peter Haggar dans son livre Mieux programmer en Java , maintenant épuisé en Français mais qui se trouve encore en version anglaise dans son livre Practical Java Programming Language Guide.

Il avait organisé son livre en ateliers avec pour chacun, un point particulier d'attention où la solution Java n'est pas aussi simple qu'elle n'y parait. Dans plusieurs de ces ateliers, la référence au bytecode produit pour expliquer le pourquoi du comment est inévitable, comme par exemple l'atelier 40 page 118 : "Utiliser System.arrayCopy pour copier des tableaux".

On peut s'en apercevoir aussi dans ses articles en ligne comme par exemple Double-checked locking and the Singleton pattern où il y a encore un deassemblage du code pour mieux comprendre ce qui se passe.

Des particularités de la machine sont à prendre en compte quand on développe si bas, comme par exemple l'alignement de données et de structures, l'endianness, les différentes méthodes de copie de données (tableaux, copie de structure (le C permet de faire de la copie de structure sans appel de fonction particulière : que se passe-t-il vraiment alors ?) , copieurs standards comme memcpy(), et des routines spécifiques à GBA ou NDS comme CpuFastSet() et le DMA).

Pour la plupart des applications de gestion de l'information (disons que la règle du 80/20 s'applique encore ici), le développeur n'a pas besoin de se soucier de tous ces détails, les langages de haut niveau (je les appellerais plutôt des langages plus abstrait) arrivant bon an, mal an à offrir des performances acceptables dans la plus part des situations les plus courantes. Mais, il y a toujours ce 20% des applications (ou disons les 20% des fonctionnalités des 20% des 80% de toutes les applications ... ) qui sont toujours importantes à maîtriser complètement sous peine de ne pouvoir délivrer le logiciel. Dans ces cas, là, deux choix s'offre à vous, puisque le monde est toujours divisé en 2 :
- soit tu creuses (tu cherches à comprendre la complexité des ordinateurs et les conséquences de tes paroles en langage de programmation)

- soit tu tiens un pistolet chargé sur un autre qui creuse (l'autre qui creuse est celui qui va maîtriser le sujet et la machine pour toi... et qui en redemandera encore après çà ;) )

jeudi 19 février 2009

OpenBSD et les caractéristiques "par défaut"

L'intérêt d'un système d'exploitation comme OpenBSD c'est qu'il ne fait pas de compromis sur plusieurs sujets et ainsi, offre des caractéristiques par défaut sans avoir à réfléchir plus que de dérouler les manuels utilisateurs.

OpenBSD est sécurisé par défaut, et est mis à jour par défaut tous les 6 mois. Quand on a autre chose à faire que de régler des problèmes d'interopérabilité entre les composants hardware, les composants software ... c'est l'idéal, on peut alors se concentrer sur ce que l'on désire réellement faire.

Oui, même s'il est toujours intéressant d'installer de configurer et d'optimiser un système d'exploitation, à moins que vous soyez un développeur du système d'exploitation, l'important se trouve ailleurs, dans l'utilisation du matériel et du système d'exploitation pour atteindre un but qu'on s'est fixé. C'est ce que nous rappelle Miod Vallat et Marc Espie dans leur interview à la radio, dans l'émission Symbiose. On peut toujours aboutir à l'augmentation/amélioration du code de l'OS, mais c'est pas le but en soi.

Cet aspect "par défaut" serait intéressant à généraliser à d'autres éléments d'un ordinateur. Je pense notamment, qu'il serait intéressant de pouvoir acquérir des PC sauvegardé "par défaut" avec un système de backup matériel et logiciel correctement configuré par défaut pour ne plus avoir à se soucier de ce sujet.

Au moins pour les ordinateurs personnels. Notamment avoir des ordinateurs portable dont les données sont cryptées et sauvegardées par défaut. C'est rarement fait par défaut, il y a toujours une procédure longue et fastidieuse (mais c'est parce que ce n'est pas un sujet simple).

jeudi 12 février 2009

Système embarqué et programmation Nintendo DS

M’étant épris de la nintendo DS, je me suis mis à expérimenter un développement pour cette merveille de raffinement technologique. Quand on étudie l’architecture de cette machine, on ne peut s’empêcher de penser que ses concepteurs ont pris du plaisir à la concevoir. En voyant la représentation de l’architecture ci-dessous, cela m’a tout de suite rappelé celle de l’Amiga qui tirait plus sa force de son chipset original que de son processeur proprement dit :

La nintendo DS a deux processeurs différents : un ARM7TDMI et un ARM946E-S partageant des espaces mémoires en commun, ayant à leur disposition, différents types de mémoire plus ou moins rapide (DTCM et ITCM, WRAM, ICACHE et DCACHE de l’ARM9…)

Programmer pour la nintendo DS, c’est bien programmer pour "un système embarqué" (embedded). Un des concepts importants en programmation embarqué est l’utilisation de registre mappé sur la mémoire : « memory-mapped registers ». Ce genre de technique apporte son lot de problèmes et de solution, notamment par l'emploi, en langage C, du mot clé "volatile", qui n'a rien à voir avec les oiseaux, comme nous le montre très bien Nigel Jones dans How to use C's volatile keyword et que je vous traduirais ainsi :
Les système embarqués contiennent du vrai matériel, habituellement avec des périphériques sophistiqués. Ces périphériques contiennent des registres dont les valeurs peuvent changer de façon asynchrone vis à vis du déroulement du programme. Pour prendre un exemple très simple, considérez un registre de status sur 8 bits qui soit mappé sur la mémoire à l'adresse 0x1234. Il est nécessaire de scruter le registre de status jusqu'à ce qu'il ne soit plus égal à 0. Une implémentation naive et incorrecte pourrait être comme cela :

uint8_t * pReg = (uint8_t *) 0x1234;

// Wait for register to become non-zero.
while (*ptr == 0);
// Do something else.

Cela va très certainement ne pas fonctionner dès que vous allez autoriser les optimisations du compilateur, du fait que le compilateur va générer de l'assembleur qui va ressembler à ça :

     mov ptr, #0x1234
mov a, @ptr
loop bz loop

La logique de l'optimisateur est assez simple : ayant déjà lu la valeur de la variable dans l'accumulateur (à la deuxième ligne de l'assembleur), il n'y a pas besoin de la relire puisque la valeur sera toujours la même. Ainsi, en troisième ligne, on abouti à une boucle infinie. Pour forcer le compilateur à faire ce que nous voulons, nous modifions la déclaration en :

uint8_t volatile * pReg = (uint8_t volatile *) 0x1234;

L'assembleur va maintenant ressembler à ça :
      mov ptr, #0x1234
loop mov a, @ptr
bz loop

Le comportement désiré est obtenu.
C’est dans ce genre d’exemple qu’on s’aperçoit qu’il est toujours bon de savoir ce qui se passe en dessous (en assembleur) du langage que l’on utilise (le langage C).

La programmation sur Nintendo DS regroupe un ensemble d'avantages certains pour le jeune programmeur (comme pour les moins jeunes comme moi :) ) :

- programmation directe pour la machine : il n'y a pas de système d'exploitation entre le programme que vous concevez et la machine. Cela oblige à comprendre comment fonctionne réellement un système embarqué, et un système informatique tout court.

- programmation d'une console de jeu : c'est motivant (c'est fun quoi :) ) parce qu'on peut arriver à avoir beaucoup d'effets graphiques 2D, 3D et sonores, et puis il y a aussi une véritable tablette graphique, une connexion réseau Wifi, un microphone intégré (et bientôt un appareil photo sur la nouvelle console Nintendo DSi)

- simplicité du kit de développement grâce à devkitpro qui contient tout ce qui est nécessaire pour développer correctement sur Nintendo DS. Cela permet d'apprendre le langage C pour ce qu'il a de meilleur : un accès très bas niveau et performant.

Aujourd'hui, j'imagine que pour un gosse qui découvre l'informatique et veut y mettre les mains, la Nintendo DS est bien plus motivante, dans un premier temps, que d'attaquer directement des systèmes embarqués ou de la programmation Web. Il est toujours important de s'essayer dans le domaine où on a le plus d'endurance aux échecs, là où vous retrouverez le plus facilement de la motivation même en face de problèmes insondables. Garder du plaisir à programmer c'est ça qui permet d'aller au delà des bugs et problèmes, et d'aboutir à des systèmes géniaux comme ce à quoi ont aboutis les concepteurs de la Nintendo DS.

Dans un deuxième temps, après s'être fait la main sur cette console, on peut toujours se tourner vers des systèmes qui nous plaisent mieux, comme des systèmes embarqués (Arduino ou le .NET Micro Framework par exemple), des systèmes d'exploitation (Linux ou pourquoi pas OpenBSD, voire même s'essayer à décoder les tripes de Windows) ou encore des applications Web / SGBD...

jeudi 5 février 2009

Les télécoms et leurs acronymes

Dans tout métier, il y a un jargon qui permet de parler plus rapidement de choses reconnues et employées par toutes les professionnels du domaine. Pour aller encore plus vite, on peut aussi employer des acronymes ou des abréviations. Ils permettent :
- d’accumuler en un minimum de lettre un ensemble de mots

- d’aider sa mémoire en fournissant de fait, des mnémoniques pour la remémoration de choses complexes, abstraites ou longues.
On peut aller encore plus loin en construisant des acronymes à partir d’autres acronymes, comme par exemple l’acronyme issu du domaine des Télécommunication : LNS qui veut dire L2TP Network Server, où L2TP veut dire Layer 2 Tunneling Protocol. On peut bien sur en citer d’autres : AJAX, GTK

Quand les acronymes d’un domaine professionnel arrive dans le grand public, on arrive souvent à des incompréhensions, des exclusions entre les personnes qui savent et les personnes qui ne comprennent pas.

Par exemple, l’acronyme PCMCIA bien connu des informaticiens, est inconnu pour la plupart des personnes qui achète un PC portable grand public, mais c’est pourtant un élément mis en avant sur les étiquettes destinées aux acheteurs. Aujourd’hui on n’en parle plus puisque personne ne comprend ce terme. Il y en a même qui ont finit par traduire PCMCIA par un rétro-acronyme : People Can't Memorize Computer Industry Acronyms.

Quel est l’informaticien qui a retenu ce que PCMCIA veut dire : Personal Computer Memory Card International Association Maintenant, les cartes PCMCIA sont appelée PC Card, terme hypergénérique qui ne veut rien dire en particulier si ce n’est que c’est une carte qui va dans un PC.

Le domaine des télécom est celui où j’ai vu le plus d’acronymes employés. Les acronymes sont parfois en français ou en anglais. Toute la journée, il n’y a pas une phrase où on n’emploie pas un. Ce sont parfois des acronymes du domaine des télécom, mais ce sont aussi des acronymes spécifiques à l’entreprise. Il faut plusieurs mois, voire plusieurs années pour s’y retrouver. Il y en a tellement que leur décomposition en mot n’est parfois plus connue par les gens qui les emploie.

Quand j’écoute mes collègues travailler, discuter, et quand je m’écoute parler (ça m’arrive souvent :) ), je me rends compte que réellement, toutes les phrases, sans exception, emploie au moins un acronyme. Comme derrière un jargon, il est facile de se cacher derrière eux. On a toujours l’impression de passer pour plus intelligent que l’on est, comme s’ils allaient de soi et que si vous ne le connaissez pas, c’est que vous êtes certainement dépassé.

Un des livres qui m’a permis de mieux comprendre l’ensemble des acronymes du domaine des télécoms est Telecommunications Essentials (2nd Edition) de Lillian Goleniewski. L’intérêt de ce livre est qu’il couvre l’ensemble du domaine, ce qui est assez impressionnant en 928 pages. Il ne rentre pas dans les détails les plus infimes de chaque protocole, technologie ou standard, mais va suffisamment loin pour permettre une compréhension solide de tout ce qui a trait aux télécoms (du champ électromagnétique aux architectures de service sur IP, en passant par le bon vieux téléphone RTC…)


Mais tout cela prend du temps, bien qu’ayant eu une formation en informatique et télécommunications, il faut quand même plusieurs années pour maîtriser l’ensemble des acronymes qu’il est nécessaire d’utiliser pour construire les offres de service de télécommunication d’aujourd’hui. Car, comme dans la plupart des domaines, une entreprise offre une valeur ajouté à un client, quand elle arrive à intégrer l’ensemble des technologies (on parle souvent de convergence, puisque des technologies différentes, voix, réseau, video, services, convergent vers une offre de service particulière au client). Or pouvoir construire des offres convergentes, nécessite de comprendre la multitude de technologies en présence, même s’il n’est pas nécessaire de les maîtriser.

Au-delà des acronymes, le jargon des informaticiens est parfois imagé et enrichi par des néologismes, et étrangement, le français n’est pas délaissé. En voici un florilège :

- Babasse: nom générique pour un ordinateur (voir aussi ordi ou bécane). Son utilisateur s'appelle un babasseur, on dit souvent babasseur fou quand il y a excès.

- Brouteur : Jeu de mot avec le terme routeur, machine qui achemine les paquets réseaux. Fréquemment utilisé lorsque celle-ci sature.

- CLCLMPALC : Comité de lutte contre les messages persos à la con : message utilisé principalement par les amoureux de la langue française, de l'orthographe, de la syntaxe, et des belles phrases, en guise de contestation à l'émergence d'un nouveau style d'écriture, se retrouvant dans les messages personnels dans certains logiciels de messagerie instantanée, ou encore dans les forums.

- Impacter : avoir un effet

- Interface chaise-clavier : surnom péjoratif donné à l'utilisateur. Souvent utilisé comme manière détournée de dire qu'un problème informatique a comme origine l'utilisateur.

- PetitMou : Traduction française (péjorative) du nom de Microsoft (micro = petit et soft = tendre, doux, ou mou dans le cas présent) En vogue dans les années 1990, probablement apparu avec Windows 95.

- Plat de spaghettis : Se dit d'un programme non structuré, dont le déroulement est aussi aisé à suivre que de trouver les extrémités correspondantes de spaghettis dans une assiette.

- Prout : Abréviation française peu élégante du terme iproute, ou routage IP.

- Usine à gaz: lorsque, généralement suite à de nombreuses maintenances successives ou en raison d'une mauvaise identification des cas généraux au profit des cas particuliers, un logiciel est devenu trop compliqué et inefficace, il devient "une usine à gaz". Sa refonte et la suppression du code mort sont alors impératifs.

- Windaube : Surnom irrévérencieux donné au système d'exploitation Windows de Microsoft afin de stigmatiser ses imperfections.

Je ne vous parle pas des acronymes récursifs qu’affectionnent les hackers.

jeudi 29 janvier 2009

Disque dur externe et capitalisation

Pourquoi faire simple quand on peut faire compliqué. Étant en possession d’un disque dur externe de 120Go Western Digital (il n'en font plus des comme ça, le remplaçant étant le Western Digital My Passport Essential), j’ai pour objectif d’y déposer tout mon environnement de travail, que ce soit les applications ou les données que j’utilise au jour le jour.

Mon but est de ne plus avoir besoin de quoi que ce soit sur le disque dur interne du PC sur lequel je travaille, de considérer réellement le PC comme un terminal banalisé, interchangeable de façon transparente avec n’importe quel autre PC Wintel compatible.

Mais pourquoi tant d’efforts pour être indépendant de la machine ? Tout simplement parce que je suis parti du constat suivant :

- tout d’abord entre mes lieux de travail (j’en ai plusieurs), chez moi, chez des amis ou la famille, je suis amené à travailler avec 8 PC différents :
  • 3 PC au travail (1 desktop pour le développement, 1 ordi portable, 1 desktop chez le(s) client(s) )
  • 4 ordinateurs chez moi (3 ordi portable + 1 vieux PC de 1998)
  • 1 PC différent par ami ou la famille

- Sur tout ces PC, des systèmes d’exploitations différents sont installés (principalement Windows et Linux, mais aussi un OpenBSD).

- Quand je change de projet, de mission ou de client, quand le temps passe et que mes PC deviennent obsolètes, je dois les changer et me retrouve avec des PC vierge de toute installation environ tous les deux ans.

- J’aime travailler avec des environnements riches en outils (130 applications installées sur mon disque dur externe pour le moment)

Bref, l’installation d’environnements complets entièrement adaptés à mes besoins prend beaucoup de temps et je ne peux pas me permettre d’installer certains outils sur tous les PC que je rencontre.

Ainsi, il est apparu bien pratique de posséder un disque dur externe d’une capacité suffisante pour y stocker :

- toutes les applications de bureautique, de développement (y compris des serveurs comme par exemple Jboss Server, Apache httpd/php/mysql), de loisirs dont j'ai besoin

- Toutes mes données de travail, et ce de façon sécurisée et facilement backupable.

Globalement, sur le disque dur externe, j’ai :

- à la racine, un fichier script d’initialisation par type d’environnement (1 pour Windows, 1 pour Linux, etc.) qui s’exécute au branchement sur le PC du disque dur et configure le PC d’une certaine manière pour me permettre de lancer n’importe quelle application sans problème. Il s’agit notamment de déclarer des variables d’environnement utilisées par les outils.

- Dans un répertoire soft non-crypté, j’ai rassemblé l’ensemble des applications Windows de mon environnement. Chaque application est dans son répertoire dont le nom est construit de la manière suivante : nomduproduit-version (par exemple emacs-22.2). Les applications sont la plupart du temps déposées directement dans ce répertoire, sans configuration particulière. Je ne backup pas le répertoire soft, considérant que si le disque dur est défaillant, je pourrai toujours retrouver les applications sur internet et les réinstaller.

- Je crée des volumes truecrypt (plusieurs s’il le faut) pour y stocker toutes mes données de travail. Ces volumes sont encryptés avec un mot de passe dur. Je crée des volumes truecrypt d’une taille de 4Go histoire de pouvoir facilement les graver sur un DVD-ROM pour faire des backups, et formatés en FAT32 histoire de ne pas avoir de sécurité associée à tous les fichiers et pouvoir ainsi passer de PC en PC sans problème. Les scripts de démarrage me demandent mon mot de passe et montent automatiquement ces volumes sur le système hôte. L'intérêt de truecrypt, c'est qu'il fonctionne aussi sous linux, ça permet d'ouvrir mes volumes truecrypt quelque soit le système d'exploitation.

- Un script de fermeture (appelé « stop ») permet de déconfigurer proprement l’environnement pour le remettre comme précédemment, d’arrêter toutes les applications issues du disque dur externe et de démonter les volumes truecrypt

- Un menu avec des liens vers toutes les applications installées sur mon DD externe est placé dans le menu Démarrer / Programme de l’utilisateur en cours. Cela permet de retrouver des liens pour lancer toutes les applications disponibles.

- J’ai même mis un Raccourci vers Emacs dans le menu contextuel SendTo (Envoyer vers) histoire de pouvoir envoyer n’importe quel fichier vers mon éditeur préféré.

Concrètement, lorsque je branche mon DD externe sur un machine Wintel, une fenêtre me demande automatiquement mon mot de passe truecrypt, puis monte les volumes truecrypt grâce à ce mot de passe et configure tout l’environnement pour permettre à toutes les applications de fonctionner.

Je lance automatiquement svnserve sur un repository placé sur un disque crypté. J’ai ainsi tout un environnement de développement avec versionning prêt à l’emploi et configuré pour s’intégrer avec Emacs.

Ainsi, dès que j’ai une nouvelle application à essayer, des nouveaux composants emacs lisp à installer, le temps que je passe à installer les composants sur le disque dur externe est capitalisé pour l’avenir et je n’ai pas à refaire toutes les manipulations sur chaque PC que j’utilise.

Pour ce qui est des applications Windows qui doivent absolument utiliser la base de registre, j’utilise l’outil sandboxie qui permet de faire fonctionner toute application dans un bac à sable entièrement fermé. Mais finalement, après 2 ans d’utilisation de mon disque dur externe, je m’aperçois que je n’utilise jamais d’application de ce type, et donc je ne recours jamais à sandboxie.

Quand mon installation prend un certain nombre d’opérations manuelles non évidentes, ou pas très bien décrites dans le manuel utilisateur, je me construis une check-list reprenant l’ensemble des étapes que j’ai réalisé pour installer le logiciel. Cela m’assure que si mon disque dur externe plante, je peux très rapidement réinstaller le logiciel sans trop réfléchir.


Globalement, je ne regrette vraiment pas d’avoir tout passé sur ce disque dur externe. Avec 5400RPM sur USB 2.0 (480Mb/s), la vitesse de transfert me suffit amplement pour travailler correctement.

jeudi 22 janvier 2009

La base de données cette inconnue...

Aujourd'hui, la plupart des applications développées sont des applications Web. Non pas qu'on ne construise plus d'autres types d'applications, mais, en quantité d'applications développées, ce sont bien les applications de types Web qui sont les plus nombreuses.

Quand on analyse ce qui constitue la plupart des applications Web, on s'aperçoit ensuite que chaque site Web est secondé par une base de données en arrière plan. Ce qui fait la force du Web c'est la facilité avec laquelle il est possible de publier des données en grand nombre et d'offrir des fonctionnalités sur ces données. Quand les années passent, les technologies de présentation des données (client lourd, client Web...) sont les premières à faire les frais de l'apparition de nouveaux concurrents. Mais, en arrière plan, la base de données est toujours là, fidèle au poste, toujours aussi importante dans l'architecture globale de l'application.

Quand on veut faire carrière dans l'informatique, on cherche à maitriser les outils dont on dispose et qui sont généralement mis en œuvre dans les projets. Personnellement, je n'ai pas le temps de réapprendre tous les 3 ans une nouvelle technologie de présentation (par exemple, en ce moment, c'est le phénomène Adobe AIR et toutes les technologies Flex qui ont le vent en poupe). Je n'ai plus l'age de passer des heures inconsidérées sur mon ordi à essayer la moindre nouveauté.


Et puis, les technologies se succédant les unes aux autres, on s'aperçoit que, bien que nouvelles, elles ne sont pas innovantes, ce ne sont que de nouvelles créations, très reluisantes, mais n'apportant pas de réelle nouveautés. Dans ce cadre là, un programmeur a tout intérêt à maîtriser au moins un système de gestion de base de données quel qu'il soit pour avoir à se pencher sur les défis réels de la mise en place de sites web : la montée en charge d'une application à accès concurrents.

Le coût global d'une requête Web sur un site Web secondé par une base de données est en grande partie due à l'accès et au traitement de la donnée, pas à se mise en forme à travers des pages HTML, Ajax, ou autre. Avec un jeu de données de test automatisé, et un grand nombre de requêtes clientes, le programmeur est tout de suite confronté à un problème de capacité. Il doit surtout faire preuve de maîtrise de son système de gestion de bases de données pour pouvoir le régler correctement pour répondre à la demande, et ce pour toutes les requêtes concurrentes.

La maîtrise d'une technologie comme Oracle, PostgreSQL ou MySQL prend déjà tant de temps que je ne vois pas où est l'intérêt de passer tout son temps sur des technologies de GUI qui évoluent au gré des modes et du temps. De toute manière, il existe de nombreux outils de développement suffisamment évolués pour ne pas avoir à taper une ligne de codes pour réaliser les tâches les plus classiques de la couche présentation.

Je ne comprend pas pourquoi tant de développeurs que j'ai côtoyé utilisent le système de gestion de base de données comme une boîte noire, comme étant juste un système de persistance d'objets. L'erreur classique est de trouver du code itératif dans une couche métier Java alors qu'une simple requête SQL aurait suffit. Les systèmes de persistance comme Hibernate ont longtemps promu des méthodes de programmation où le système de gestion de bases de données est réduit à une réceptacle abstrait et dont on doit absolument pouvoir interchanger si l'humeur nous en dit. Or, tous ces systèmes d'abstraction vis à vis du SGBD sont finalement la plus part du temps complètement inutiles sachant :

- qu'il est extrêmement rare de changer brusquement de technologies de base de données puisque, à part faire un mauvais choix, la plus part des SGBD sont maintenant extrêmement bien rodés pour ce qu'ils ont à faire.

- qu'on a tout intérêt à tirer au maximum partie des services offerts par le SGBD pour réaliser les fonctionnalités à implémenter car le paradigme de programmation SQL, bien qu'imparfait, reste toujours supérieure à une approche procédurale classique quand il s'agit de traîter des lots de données.

- si on doit utiliser un SGBD payant comme Oracle, c'est vraiment du gâchis de le considérer comme une boîte noire et de ne pas utiliser toutes les fonctionnalités que vous avez chèrement payées.

Tom Kyte résume très bien cette situation dans son livre Expert Oracle Database Architecture :
The single most common reason for database project failure is insufficient practical knowledge of the database - a basic lack of understanding of the fundamental tool that is being used. The black box approach involves a conscious decision to protect the developers from the database - they are actually encouraged to not learn anything about it ! In many cases, they are prevented from exploiting it. The reasons for this approach appear to be related to FUD (Fear, Uncertainty, and Doubt). The accepted wisdom is that database are "hard", and that SQL, transactions, and data integrity are "hard". The solution: don't make anyone do anything "hard". They treat the database as a black box and have some software tool generate all of the code. They try to insulate themselves with many layers of protection so that they do not have to touch this "hard" database.
Philip Greenspun le disait déjà de son temps dans Philip and Alex's Guide to Web Publishing :
Any interesting Web/RDBMS problem can be solved using just the standard software shipped with the RDBMS. If you can't solve it with those tools, you can't solve it with any tool no matter how glitzy and turnkey. The critical element is not the tools, it is the programmer.

In terms of maintainability, clarity of code, software development cycle, and overall Web server performance and reliability, the simplest tools such as Microsoft Active Server Pages are superior to virtually any of the expensive Web development systems out there.

Il est vraiment dommage de ne pas s'intéresser à son SGBD car il permet pourtant de réaliser de grandes applications, solides et montant correctement en charge. De plus, il permet de faire face à des situations délicates de façon élégante.