Linux, MacOS ou Windows

Récemment, au cours des réunions familiales qui se produisent communément en ces moments noëliens, un membre de ma famille m’a demandé ce qui lui serait nécessaire pour être en mesure de faire du traitement vidéo.

Ni lui ni sa femme ne sont passionnés d’informatique comme vous (hein ?) et moi (bon, ça ok). Ils ont encore moins l’esprit hacker, comme beaucoup de gens par ailleurs. Je ne les vois pas s’extasier devant un “Rhoo, c’est quand même génial les systèmes de fichiers journalisés, je viens de crasher mon kernel et paf ! je reboote comme si de rien n’était” (non pas que ça se produise souvent, loin de là, mais je cherchais un exemple :-p) ou devant un “Ouaaaah, c’est vraiment beau cet écran bleu qui apparaît au milieu de ma gravure”.

En fait, ma réflexion fut rapide : j’ai beau être fermement convaincu de l’avenir de GNU/Linux, je suis conscient qu’il n’est actuellement pas encore tout à fait prêt pour permettre une utilisation simplissime et rapidement installable pour un utilisateur qui découvre ce qu’est une souris. Certaines distributions facilitent certes la vie, mais allez ensuite brancher à votre ordinateur le dernier truc bidule firewire et essayez de le faire fonctionner sans passer en mode administrateur énervé et vous comprendrez qu’il y a encore un peu de travail…

Ensuite, j’ai pensé à Windows. Et là je me suis dit : “non plus, non”. Quitte à conseiller un environnement propriétaire, je ne vais pas conseiller ça. Certes, certains périphériques sont détectés dès l’installation, mais pour certains autres, cela devient vite l’horreur. Je me souviens par exemple de ma webcam qui marchait fort bien, jusqu’au jour où paf, marche plus. Les drivers devaient être installés (ça marchait ptête sans jusque là, mais bien sûr…). Et puis, si c’est pour que ça me contraigne à installer moults antivirus, firewall et à aller vérifier la machine régulièrement, merci bien.

Quitte à être dans un environnement propriétaire et à payer peut-être le tout un peu cher, je préfère de loin leur conseiller un environnement complet dont l’éditeur n’a pas le souci des deux précédents : à savoir fonctionner avec des matériels et des configurations différentes et parfois pour le moins exotiques. Non, je préfère conseiller un environnement complet ou l’unification est complète, le choix clair.

Un Mac.

Je découvre cet environnement depuis quelques temps en jouant avec de temps en temps sur le portable de Vincent et il est clair que c’est MacOSX qui conviendra le mieux. Ils veulent du support, de la simplicité et quelque chose qui fonctionne.

Pour Linux, ce qui m’inquiète c’est la simplicité. Je suis sûr d’arriver à le faire fonctionner et à rendre cette machine totalement fonctionnelle pour longtemps. Ensuite, ils n’auraient plus qu’à suivre mes directives pour l’utilisation au jour le jour. Mais combien de temps cela va-t-il me prendre ? Je n’ai pas 20 ou 30 heures en ce moment à consacrer à cette installation.

Pour Windows, c’est plutôt la longévité qui m’inquiète. Comme chacun sait, il n’est pas rare sous cet OS d’avoir quelque chose qui fonctionne. Et puis un jour, tiens non… Ça marche plus. Et je ne veux pas avoir à gérer ça, hors de question. Si je n’utilise plus Windows sur ma machine depuis plusieurs années maintenant, c’est bien une des raisons qui m’y ont poussé et je ne veux pas le revivre.

Donc, Mac, voilà. Mac.

Qu’est-ce que vous en pensez ?

PS : Les avis que je donne ici des trois OS cités sont ceux issus de mon expérience personnelle. Je connais assez bien windows pour l’avoir longtemps utilisé avant d’arriver à GNU/Linux. Je connais peu Mac, mais le peu que j’en ai vu et entendu semble aller largement dans mon sens.

Maintenant, je suis sûr de ce que j'aurais dû acheter pour Noël

# free
            total       used       free     shared    buffers     cached
Mem:        256628     244344      12284          0      89268      41800
-/+ buffers/cache:     113276     143352
Swap:       491360     304768     186592

Là, ça devient vraiment urgent…

Joyeux noël

Mon cul…

Enfin, joyeux noël à vous disons toujours.

Moi, j’ai été obligé de tapoter sur mon portable jusqu’à 22h00 pour terminer un compte-rendu de sécurité réseau à rendre aujourd’hui. J’ai le cerveau qui me fait mal à chaque fois que je pense à ce qu’il me reste à faire :

  • rendu cahier des charges techniques du projet de génie logiciel pour jeudi prochain au plus tard
  • CORBA JavaCard, Interceptor
  • exposé réseau, Wifi, WPA

Je suis fatigué, très fatigué.

Vivent les études et merde à ceux qui croient qu’on s’y repose.

Foutage de gueule

On se demandait quand est-ce qu’on allait entendre reparler des brevets logiciels. Vous savez, le genre de choses qui a permis à Kodak d’attaquer Sun pour “tout système ayant recours à des processus d’interaction entre programmes et notamment via la gestion d’objets ou de données partagés”… Et de gagner…

Oui, vous ne rêvez pas. Vous voyez beaucoup de systèmes qui ne tomberaient pas sous le coup d’une définition de brevet aussi vague ? Les IPC, les threads, les fichiers même (!), etc. Tous ces concepts sont alors clairement brevettés…

Ce point fait aussi en ce moment couler beaucoup d’encre (:/) sur la ml debian.

Et bien, ils ont décidé de le refaire passer au vote aujourd’hui. Ce point sera traité aujourd’hui à 15h lors d’une réunion des ministres de l’agriculture. DE L’AGRICULTURE !!!. Comment faire adopter une directive par des gens en leur soumettant un sujet totalement hors du champ de leur compétence ! C’est vraiment du foutage de gueule.

Alors, vous aussi jouez votre rôle. Parlez-en autour de vous et envoyez un mail, comme moi et beaucoup d’autres, à communication(at)agriculture(point)gouv(point)fr pour exprimer votre opposition. Vous pouvez utiliser le modèle de lettre fourni ici pour ce faire.

Mise à jour du 23 décembre 2004 :

Cette opération scandaleuse n’est pas passée grâce en grande partie au ministre de la Pologne qui s’est déplacé en personne pour faire retirer ce point de la liste ! Merci la Pologne !

Unable to compile kernel

Ce billet sera aussi en anglais mais je mettrais aussi les messages d’erreurs produits par le noyau en français. En bref, gcc-3.4 : pas glop pour la compilation du noyau (2.4.27).

Well, this one will be in english too although I’m going to put french error messages too. It will let french users find the information in typing the message in google.

If you’re trying to compile the Linux kernel with gcc 3.4, you may have noticed that it generates an error. I didn’t find quickly because I had forgotten I had changed the symbolic link to point to gcc-3.4 instead of the default 3.3 version. To be able to compile, just be sure you’re not using gcc 3.4, it worked for me :-)

In english :

sched.c:213: error: conflicting types for 'reschedule_idle'
sched.c:210: error: previous declaration of 'reschedule_idle' was here
sched.c:213: error: conflicting types for 'reschedule_idle'
sched.c:210: error: previous declaration of 'reschedule_idle' was here
sched.c:371: error: conflicting types for 'wake_up_process'
/usr/src/kernel-source-2.4.27/include/linux/sched.h:603: error: previous declaration of 'wake_up_process' was here
sched.c:371: error: conflicting types for 'wake_up_process'
/usr/src/kernel-source-2.4.27/include/linux/sched.h:603: error: previous declaration of 'wake_up_process' was here
sched.c:409: error: conflicting types for 'schedule_timeout'
/usr/src/kernel-source-2.4.27/include/linux/sched.h:148: error: previous declaration of 'schedule_timeout' was here
sched.c:409: error: conflicting types for 'schedule_timeout'
/usr/src/kernel-source-2.4.27/include/linux/sched.h:148: error: previous declaration of 'schedule_timeout' was here
sched.c:739: error: conflicting types for '__wake_up'
/usr/src/kernel-source-2.4.27/include/linux/sched.h:595: error: previous declaration of '__wake_up' was here
...
make[3]: *** [sched.o] Error 1
make[3]: Leaving directory `/usr/src/kernel-source-2.4.27/kernel'
make[2]: *** [first_rule] Error 2
make[2]: Leaving directory `/usr/src/kernel-source-2.4.27/kernel'
make[1]: *** [_dir_kernel] Error 2
make[1]: Leaving directory `/usr/src/kernel-source-2.4.27'
make: *** [stamp-build] Error 2

In french :

sched.c:213: erreur: types conflictuels pour « reschedule_idle »
sched.c:210: erreur: déclaration précédente de « reschedule_idle » était ici
sched.c:213: erreur: types conflictuels pour « reschedule_idle »
sched.c:210: erreur: déclaration précédente de « reschedule_idle » était ici
sched.c:371: erreur: types conflictuels pour « wake_up_process »
/usr/src/kernel-source-2.4.27/include/linux/sched.h:603: erreur: déclaration précédente de « wake_up_process » était ici
sched.c:371: erreur: types conflictuels pour « wake_up_process »
/usr/src/kernel-source-2.4.27/include/linux/sched.h:603: erreur: déclaration précédente de « wake_up_process » était ici
sched.c:409: erreur: types conflictuels pour « schedule_timeout »
/usr/src/kernel-source-2.4.27/include/linux/sched.h:148: erreur: déclaration précédente de « schedule_timeout » était ici
sched.c:409: erreur: types conflictuels pour « schedule_timeout »
/usr/src/kernel-source-2.4.27/include/linux/sched.h:148: erreur: déclaration précédente de « schedule_timeout » était ici
sched.c:739: erreur: types conflictuels pour « __wake_up »
...
make[3]: *** [sched.o] Erreur 1
make[3]: Leaving directory `/usr/src/kernel-source-2.4.27/kernel'
make[2]: *** [first_rule] Erreur 2
make[2]: Leaving directory `/usr/src/kernel-source-2.4.27/kernel'
make[1]: *** [_dir_kernel] Erreur 2
make[1]: Leaving directory `/usr/src/kernel-source-2.4.27'
make: *** [stamp-build] Erreur 2

Best Practices in Java

This post is a translation of this one. Many people commented it at the moment it was published although it was only available to those who speak french.

I found it very interesting to try and compare my opinion with the others. I thought it would be great to extend the possible field of this post to the world into re-publishing (and adapting) it in english. The other interest I see is that I could be corrected for my english mistakes :).

It is the first time I do that, I bet that won’t be the last one :).


Today, we’re going to speak about best practices in the Java programming language. We’ll speak about the API classes that are fonctionnally deprecated, we’ll speak about evolutivity and abusive inheritance, all of this framed by design patterns.

The forbidden classes

I still find projects on the web that are using the following classes (surely this list isn’t exhaustive, but these two are the most common) :

  • Hashtable
  • Vector

You must not use theses classes. They are still present only to assure upward compatibility. The jvm 1.4 must be able to run a program written for the 1.0, this version can in fact contain objects of this type because their alternative only appear in the 1.2 version.

Since the 1.2 so, it mustn’t be used anymore. Then why, you say, didn’t they deprecated those classes since this version ? That’s very simple : Hashtable is a hash table (a key-value list) and Vector is designed to manage an objects list… That’s to say extremely common and used objects. So, Sun decided not to deprecate it to prevent old programs developed with the 1.2 from getting hundreds, even thousands of warnings during the compilation.

Why not use them ?

Those classes are “synchronized”, they are what we call thread-safe. It means that when you’re in an environment containing more than one thread of process, if you use them, you’re sure your data will keep coherent. That wouldn’t be the case without synchronization.

The point is that this fonctionnality is far from being used in all projects. In fact, we’re not allways using our objects in a concurrent context (and that’s a good thing). Speaking about performances, this synchronization is not free (as in free beer ^^) (we’re used to hear about five times slower with synchro). So you see that using a Vector to store your lists is commonly a pure waste of performances.

The alternatives

But which classes should I use as a replacement ? Those one, their non thread-safe equivalents :

  • ArrayList for Vector
  • HashMap for Hashtable
So what if I want a thread-safe container ?

If you we’re thinking about this question, congratulations. In a concurrential environment, you must always synchronize objects in one way or another… There’s two solutions to do it :

Synchronization where it’s necessary using a non synchronized container

  • Pros : Possible performance gain because you perfectly control the synchronization of your code ;
  • Cons : More difficult because you’ve got to take care not to forget this synchro if you don’t want to get strange results, or worst : totally upset.

Use of synchronized container :

  • Pros : Just concentrate one good time on the development of the container. Then you’ll be able to use it without fearing inconsistencies during execution ;
  • Cons : Possible loss of performance because you might use synchronization where it’s not necessary.

Fortunately, you say, the class Vector which you can use when you need a _thread-safe_ container. But no, you can drop this class. Instead, use the static method Collections.synchronizedList(). you’ll get a synchronized list from one that is not. At the same, you’ll be using the important pattern which consists in hiding implementations. Great ! That’s what I’m going to speak now ! :-)

Increase code evolutivity

Hide implementation

A lot of applications are still using Vector today, why ? Because this class has been used everywhere without being hidden by a class or an interface.

Since the 1.2, Vector implements the List interface, so do ArrayList and LinkedList. When using a list, the implementation must be hidden. To do it, just say you’re using a class that implements List. If you get used to do it everywhere, you’ll see that it becomes really simple to change implementation afterwards. For example, if you decide that ArrayList doesn’t fit you anymore, you could easily replace it by a personal implementation of List, nobody will know it and all the code that isn’t yours will keep unchanged (ant that’s the BIG point).

The factories

Use factories to create your objects. This way you’ll be easily able to hide an implementation.

Example : Pouet must be able to say hello

public interface Pouet
{
  /**
   * Displays hello to the screen
   */
  public void sayHello();
}

Very well, so the first thing to do is writing an implementation of Pouet :

public class PouetImpl implements Pouet
{
  public void sayHello()
  {
     System.out.println("Hello");
  }
}

If you only do this, the users of your class won’t have any other choice than writing

PouetImpl pouet = new PouetImpl();

And they are a bit more experienced

Pouet pouet = new PouetImpl();

Then they’ll use Pouet and not PouetImpl everywhere in their code. The problem is that you’re letting others make choices in the way of using your code. As much as possible, you’ve got to reduce the number of ways you provide to do things. If you don’t do this, you’ll meet akward maintenance problems…

If they’re a bit experienced, they’ll try to centralize this code. For example, they will write the factory you should have written :

public final class PouetFactory
{
  public Pouet createPouet()
  {
     return new PouetImpl();
  }
  /**
   * Singleton for this factory.
   */
  public static PouetFactory getFactory()
  {
     if(pouetFactory==null)
     {
        pouetFactory = new PouetFactory();
     }
     return pouetFactory;
  }
  private static final pouetFactory;

  private PouetFactory()
  {
  }
}

Here, we took care of doing 3 things :

  • provide a static method getFactory() ou getInstance() ;
  • put a private constructor to forbid the factory instantiation by external code ;
  • set the class final to prevent inheritance.

You see that if I want to use anything else than PouetImpl, nobody will know it if I correctly designed my code into forcing to use it in the way I want (putting for example the PouetImpl class protected if possible. This way, it won’t be instantiable by another object than one of the package). I’ll be able to easily change the implementation impacting the fewest code.

Abusive inheritance

In the serie of the anti-evolutive code, let’s put at the top the excessive inheritances. Have’nt you already inherit from a JFrame only to display a poor window that provides nothing more than the original JFrame ? If yes, stop it. You’ve got to use delegation in most cases. That’s to say wrap the used object and provide a getComponent() method that returns a Component for example.

Inheritance isn’t a non-important or non-impacting choice, this design choice must be motivated. When you do, that’s because you want to change a particular part of the behaviour of the object. If not, don’t inherit, use delegation.

That will do for today

Right, that’s all for today. I’ve got still other things I want to speak about. I will have to find time to do it, which is not done yet :-). I’d like to speak about DAO, de commons-logging, de JNI with you… Well, quite a lot of things.

If you disagree with some points ou if you want some more explanations, use the comments… It’s designed for that :-).

Note for english readers : if you see sentences you don’t understand. Let me know. I may have used somes expressions coming from french that aren’t understandable in english…

Adorables enfants

Une de mes proches connaissances est professeur des écoles. Elle a récemment fait passer des évaluations à ses CE1.

Dans les connaissances évaluées, il y avait la ponctuation et les types de phrase. Une petite fille, à la question “Écris une phrase qui montre que tu es en colère.”, a répondu de la façon suivante :

“Conare de seure !”

:-)

Le professeur a été obligé de constater que le point évalué, utiliser la forme exclamative, était acquis ^^.

Gérer les services lancés au démarrage de la machine

Une personne a posé une question hier soir sur la mailing-list debian au sujet des services que sa Knoppix (distribution dérivée de debian) lance au démarrage.

Comme il n’était pas d’accord avec tout ce que la machine lancait, il a essayé d’empêcher ça en supprimant les scripts présents dans /etc/init.d… Je lui ai alors expliqué comment faire mieux et plus propre à mon sens.

Voici donc l’explication en question revue un petit peu. Je pense qu’elle évoluera s’il s’avère que j’ai dit des bêtises. Je suis bien sûr conscient que ce type d’explications existe déjà en maints endroits, mais je vais le refaire moi-même pour plusieurs raisons :

  • c’est une explication rapide destinée à un problème précis : éviter de démarrer des services inutiles. Ce n’est pas une explication complète du fonctionnement des runlevels sous Linux ;
  • ça me permet de mieux comprendre ;
  • avec tes yeux et tes connaissances, lecteur, si je raconte n’importe quoi, tu pourras me le dire. J’éviterai ainsi de continuer à raconter ledit n’importe quoi :-) ;
  • et SURTOUT … je suis sur mon blog alors je fais ce que je veux, na !

Les services sur debian (selon batmat, donc…)

Déjà, première chose, si on souhaite qu’un service ne soit jamais jamais jamais lancé, a priori, la meilleure solution est de supprimer le logiciel par apt-get remove.

Si on souhaite par contre le garder, mais qu’on ne veut pas qu’il soit lancé au démarrage “normal” de ta machine, il vaut mieux simplement supprimer le lien symbolique dans /etc/rcX.d.

/etc/rcX.d ?

Le noyau Linux fonctionne avec ce qu’on appelle des runlevels, des niveaux d’exécution. Le runlevel par défaut est défini en haut du fichier /etc/inittab (man inittab) par la ligne suivante :

id:2:initdefault:

Le plus souvent, c’est comme ci-dessus le niveau 2 qui est utilisé pour le démarrage “normal” (0 pour halt, 1 pour single-user : mode sans-réseau en mode utilisateur unique, 2 à 5 pour les modes multi-utilisateurs, 6 pour le reboot).

Il y a autant de /etc/rcX.d que de runlevels (i.e. X vaut de 0 à 6). Dans le répertoire rcX.d tous les script commençant par S seront exécutés à l’entrée dans le runlevel. Ceux commençant par K seront exécutés au moment de la sortie du runlevel. Ces scripts ne sont en fait que des liens symboliques vers ceux de /etc/init.d.

Si le runlevel 2 est aussi celui par défaut sur votre machine, il suffit donc de regarder les /etc/rc2.d/S* et de supprimer ceux qui correspondent aux services qu’on ne veut pas lancer.

Comme ça, on garde la possibilité de démarrer simplement un service en cas de besoin (en root /etc/init.d/un_service start) sans pour autant qu’il soit chargé tout seul au démarrage de la machine. C’est par exemple ce que je fais pour Apache/MySQL que je n’utilise qu’occasionnellement pour des tests et que je ne veux pas lancer systématiquement sur mon poste de travail.

Empêcher le redimensionnement de la fenêtre du navigateur

Un peu comme le target=_blank, le redimensionnement de ma fenêtre de navigation m’exaspère. Et comme ça m’énerve, j’ai cherché à corriger ça.

J’ai donc ouvert cette chère adresse bien connue about:config et me suis mis en recherche d’une propriété de resize. Avec la version 1.0 de Firefox, la page about:config possède un filtre. Je tape r e s i et là, il ne reste plus que quelques propriétés.

C’est du javascript qui permet de redimensionner la fenêtre, donc j’essaie un nom qui me paraît cohérent : dom.disable_window_move_resize que je passe à true.

Ça marche ! Plus de redimensionnement sauvage :-). Décidément, j’aime beaucoup Firefox.

Par contre, je ne sais pas si cette propriété était présente dans les versions précédentes de FF. Ça marche chez vous ? En quelle version ?

Lecteur mon amour

Après une discussion aujourd’hui avec quelques lecteurs assidus de ce blog, je me suis décidé à coder un petit peu.

Résultat :

  • Il est confirmé que j’ai du mal en php… ^^ J’ai vraiment du mal à m’y mettre. J’ai pour habitude de tester les fonctions ou les choses que j’écris séparément du reste avant de l’intégrer. En php, vu mon niveau, ça veut dire abuser du echo un peu partout. Y a-t-il des méthodes plus propres et moins contraignantes (à cause du fichier sur serveur ftp distant à uploader à chaque nouvelle modification) pour tester des bouts de code en PHP que d’utiliser la méthode ancestrale de l’affichage à l’écran ? Pour l’instant, la seule solution à peu prêt convenable que j’aie trouvée est d’installer apache en local. Mais c’est un peu chiant de devoir par exemple installer dotclear ici et en local à la fois, il me semble…

  • J’ai quand même finalement réussi à ajouter la rustine qui va maintenant te permettre à toi, lecteur adoré, de pouvoir obtenir le fil rss des billets sans la catégorie blogounette

Pourquoi ?

Ben, parce qu’il parait que ce blog aurait une fâcheuse tendance à devenir inintéressant. Je suis conscient que les doses d’humour (particulier, j’en conviens) présentées assez régulièrement ici peuvent finir par lasser.

Donc, maintenant, je peux continuer à avoir mes moments de délires sans impacter ceux qui ne souhaitent suivre que les billets succeptibles d’être intéressants. À ce propos, je suis désolé de ne pas poster en ce moment beaucoup de billets de ce type, le temps me manque. C’est aussi pour ça qu’il est plus facile de marcher en mode blog-minute… :-)

Bref, paf ! pastèque, je vous redonne encore une fois le lien vers le fil rss sans les blagues. Cette fonction étant nouvelle, j’ai eu beau la tester, elle cause peut-être des soucis que je n’aurais pas repérés. Faites moi signe donc si vous décelez un petit problème.

Pour finir, mes excuses à Antoine qui me faisait remarquer aujourd’hui même que mes numéros de billets atteindraient bientôt la centaine. Chose à laquelle j’ai répondu en disant qu’il me semblait que c’en était plutôt aux alentours de 80/85. Et bien non, il avait raison. D’ailleurs, ce billet est déjà le 101e et j’ai même dédié mon 100e à Firefox :-)

Page 23 of 33 Older