mardi 11 novembre 2008

Réviser les notions de base

Dans le dernier billet de ma série Comment rester à jour pour les développeurs, j'aborde l'importance de bien maîtriser les notions de base.

On entend souvent qu'il est important de rester à jour par rapport aux nouveautés. C'est indéniable. Par contre, je trouve qu'on néglige parfois de s'assurer qu'on maîtrise toujours bien les aspects élémentaires pour un développeur. Avec le temps, certaines des notions de base se perdent à cause d'habitudes qu'on a prises dans le passé. On finit par faire certaines choses machinalement, sans trop se rappeler pourquoi.

On pourrait discuter longuement de plusieurs de ces notions de base, mais dans ce billet, je vais me concentrer sur deux aspects: les structures de données de bases, ainsi que les particularités des plates-formes de développement.

Structures de données de base


Les structures de données sont parmi les premières choses que les futurs développeurs apprennent dans les cours de Programmation 101! Et pour cause: ce sont les éléments de base pour le traitement de l'information.

Les structures de données élémentaires sont les tableaux, les tableaux dynamiques, les listes chaînées et les tables de hachage. Il y en a bien sûr plusieurs autres, mais ce sont les plus courantes. Pour chacune de ces structures, il est important de bien connaître leurs particularités respectives ainsi que de savoir dans quel contexte elles doivent être utilisées. Pour chacune des situations suivantes, essayer de déterminer laquelle des structures est la plus appropriée:

1. Vous devez faire des insertions à différents endroits de la structure.
2. Vous devez faire des accès directs à des éléments de la structure.
3. Vous devez conserver l'ordre des éléments dans la structure.
4. Vous devez associer chaque élément de la structure avec une clé.

Ces situations ne sont pas que théoriques. Ce sont des situations que les développeurs rencontrent fréquemment dans leur travail de tous les jours. Mais si on a pris l'habitude, par exemple, de toujours utiliser un tableau dans toutes les situations, il est clair qu'on utilise pas toujours le meilleur outil disponible.

Un tableau est une zone de mémoire continue et de taille fixe. Il est facile d'y récupérer directement un élément (#2). Le tableau dynamique est une structure semblable à un tableau, mais dans laquelle on peut insérer de nouveaux éléments, car la taille du tableau dynamique peut varier. La liste chaînée est une structure où chaque élément maintient un pointeur vers l'élément suivant (et précédent dans le cas d'une liste doublement chaînée). Il est aisé d'y insérer un élément à n'importe quel endroit de la structure, car il suffit seulement de changer les pointeurs (#1 et 3). Finalement, la table de hachage associe à chaque élément une clé unique qui permet de le récupérer sans parcourir la structure (#4).

La notation grand O, utilisée en théorie de la complexité, permet de définir un ordre de grandeur pour les opérations sur les structures de données.

Structure
Accès direct
Insertion/suppression à la fin
Insertion/suppression au milieu
Tableau
O(1)
n/a *
n/a *
Tableau dynamique
O(1)
O(1)
O(n)
Liste chaînée
O(n)
O(1)
O(1)
Table de hachage
O(1)n/a **
n/a **
(*) Dans un tableau, comme la taille est fixe, on ne peut faire d'insertion ou de suppression.
(**) Dans une table de hachage, c'est la structure qui gère l'emplacement des éléments.

La notation O(1) signifie que l'opération s'effectue en temps constant. La notation O(n) signifie que la performance de l'opération est proportionnelle au nombre d'éléments dans la structure. Ainsi, une opération en temps O(1) s'effectue plus rapidement qu'une opération en temps O(n). Bien sûr, pour des petits nombres d'éléments, c'est négligeable. Mais si vous devez gérer un grand nombre d'éléments, il est important d'avoir constamment ces notions à l'esprit.

En Java, la classe ArrayList est un tableau dynamique, la classe LinkedList est une liste doublement chaînée et la classe HashMap est une table de hachage. Il existe d'autres classes qui implémentent ces mêmes structures, mais ces classes sont très souvent utilisées.

Les particularités des plates-formes de développement


Que ce soit .NET, Ruby, Java ou une autre, chaque plate-forme de développement possède ses particularités que tous les développeurs travaillant avec elles doivent bien connaître. Ces particularités sont souvent là pour des raisons toutes à fait uniques à la plate-forme, mais elles sont très importantes à connaître pour être efficace. Souvent, ces particularités imposent des façons de travailler qui deviennent finalement des habitudes. Et après, on peut finir par oublier pourquoi on a ses habitudes. D'où l'importance de s'assurer de réviser au besoin le détail de ces particularités.

Par exemple, pour la plate-forme Java, vérifier si vous comprenez les particularités suivantes:

* Quelle est la différence entre une exception déclarée (checked exception) et une exception à l'exécution (runtime exception)?
* Pourquoi les méthodes destroy, resume, stop et suspend de la classe Thread ont-elles été marquées comme désuètes (deprecated), c'est-à-dire qu'on doit éviter de les utiliser?
* Pourquoi ne peut-on pas hériter de la classe String et qu'est-ce que cela a comme conséquence?
* Quelle est la différence entre les classes Hashtable et HashMap ou entre Vector et ArrayList?
* Dans quels cas doit-on définir les méthodes equals et hashCode pour un Java Bean?

L'important, ce n'est pas nécessairement de connaître dans le détail absolu ces particularités, mais d'en savoir assez pour faire de bons choix.

Il est donc important de prendre du temps pour réviser les notions de base. Il faut éviter de faire des choses seulement par habitude. Il suffit parfois seulement de quelques minutes sur Google pour réviser et rester à jour!

mardi 4 novembre 2008

La réalité est-elle toujours calculable?

Je suis en train de lire le numéro de juillet de Science & Vie et j'ai trouvé très intéressant l'article "Ce qu'on ne peut calculer est-il encore réel?'. Cet article rapporte un article du physicien Scott Aaronson qui postule que si un modèle proposé pour expliquer un phénomène naturel ne peut être calculé dans un délai "raisonnable" par un ordinateur, c'est qu'il est forcément faux!

Par exemple, en biologie, on explique le fonctionnement des protéines en proposant un modèle où elles se configurent de façon aléatoire avant de s'arrêter à une configuration stable (je suis loin d'être un connaisseur!). Selon Aaronson, ce modèle est invraisemblable car même un hypothétique ordinateur quantique ne pourrait reproduire ce modèle à cause du trop grand nombre de combinaisons à effectuer.

Cet article fait référence à plusieurs notions de la théorie de la complexité. Un bon rappel de ces notions peut être trouvé sur le site du cours INF 6460.