Wed, Dec 29, 2004
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.
Mon, Dec 27, 2004
# 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…
Sat, Dec 25, 2004
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.
Tue, Dec 21, 2004
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 !
Fri, Dec 17, 2004
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
Thu, Dec 9, 2004
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) :
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…
Sun, Dec 5, 2004
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 ^^.
Tue, Nov 30, 2004
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.
Fri, Nov 19, 2004
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 ?
Wed, Nov 17, 2004
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 :-)