Archiv für den Monat: Februar 2014

Goto Fail als Lehrstück

Während dem vergangenen Wochenende und dem Anfang dieser Woche wurde der Fehler in der Zertifikats-Überprüfung in Apples Code ausführlich diskutiert. Der Quellcode kann öffentlich angesehen werden und dass die fehlerhafte Codezeile dann auch noch „goto fail“ heisst hat natürlich viele ermutigt mit Häme nicht zu sparen.

Goto Fail

Die Code-Zeile, die das Problem verursachte (gelb hervorgehoben)

Eine Variante dieses Fehlers hatte ich auch als Punkt 6 in den 9 unbeliebtesten Entdeckungen in fremdem Code beschrieben.

Ob der Fehler durch ein automatisches Mergen von zwei Codefiles, unkonzentriertes arbeiten beim Code schreiben oder ein unbeabsichtigtes Kopieren der Codezeile entstanden ist kann nur anhand der Codefiles nicht erörtert werden. Gleichwohl darf man aus den Fehlern anderer lernen und so habe ich mir Gedanken gemacht, wie dieser Fehler hätte vermieden werden können.

Hier ein paar Punkte, die aus meiner Sicht das Risiko vermindert hätten:

  • Code Reviews
    Wenn Code Änderungen von einer zweiten Person überprüft werden ist die Gefahr kleiner, dass ein solcher Fehler hinein rutscht. Ausgeschlossen werden kann es natürlich trotzdem nicht, denn Menschen machen Fehler.
  • Warnungen einschalten und beachten
    Da ich die Umgebung nicht kenne, mit der OS X und iOS gebuildet wird kann ich nicht beurteilen, ob der Compiler hier Unterstützung geboten hätte. Aber viele Compiler geben ab einem bestimmten Warning-Level eine Warnung oder sogar einen Fehler aus, wenn Codeabschnitte vorhanden sind, die gar nie erreicht werden können. Dabei müssen dann aber auch die Warnungen entsprechend beachtet werden, nicht wie in Punkt 7 meiner unbeliebtesten Entdeckungen in fremdem Code.
  • Coding Guidelines
    Mit Coding Guidelines, die verlangen, dass jeder Block mit geschweiften Klammern eingefasst wird, hätte dieser Fehler vermieden werden können oder er wäre vermutlich eher aufgefallen. Auch ein fehlerhaftes Mergen mit diesem Resultat wäre vermutlich nicht passiert. Die Guidelines müssen aber auch wieder durch ein Code Review oder durch ein Tool überprüft und durchgesetzt werden.

Fehler passieren, und vielleicht versteckt sich in all den Codezeilen, die ich schon geschrieben habe ein ähnlicher Fehler. Wenn ein solcher Fehler öffentlich wird versuche ich deshalb lieber, daraus zu lernen als über den Verursacher zu spotten.

Zeitgeist 2013

Wie schon 2011 und 2012 veröffentliche ich auch für das Jahr 2013 ein paar Statistiken aus meinen Piwik-Analysen.

Suchbegriffe

Auch dieses Jahr hat der Suchbegriff „Suchbegriff nicht definiert“ die Rangliste sowohl im Blog als auch auf der Webseite dominiert. Da er mehr als 2/3 aller Einträge ausmacht ist eine Auswertung anhand der Piwik-Daten nicht sinnvoll.

Und da das Google Webmaster-Tool die Abfragen nur für die letzten 90 Tage ermöglicht muss ich diese Statistik für dieses Jahr schuldig bleiben.

Dass es für das nächste Jahr mit der Suchbegriff-Statistik wieder klappt kann ich noch nicht versprechen.

Browser

Gegenüber 2012 ist im 2013 der Marktanteil des Firefox bei den Zugriffen auf die Webseite zurückgegangen. Chrome hat dafür auf der Webseite Boden gut gemacht. Im Blog hat der Internet Explorer Marktanteile verloren, die der Safari für sich beanspruchen konnte. Die Zahlen des Opera-Browsers bleiben in etwa gleich und weitere Browser haben nur einen minimalen Anteil an den Besuchen.

Browser-Marktanteil Web 2013

Browser-Marktanteil Web 2013

Browser-Marktanteil Blog 2013

Browser-Marktanteil Blog 2013

Browser Webseite (%) Blog (%)
Firefox 42 36
Chrome 27 28
Internet Explorer 21 18
Opera 5 3
Safari 4 14
Andere 1 1

Suchmaschinen

Bei der Liste der wichtigsten Suchmaschinen hat sich wiederum nicht viel geändert, die Marktdominanz von Google ist immer noch beängstigend hoch. Nur beim Blog liegt Bing wieder auf dem dritten Rang, den vorher Bing Images belegte. Da aber Bing Images gar nicht mehr in Erscheinung tritt ist anzunehmen, dass Bing und Bing Images als Bing-Verweise gerechnet werden.

Rang Webseite Blog
1 Google Google
2 Bing Google Images
3 Yahoo! Bing

Aufgrund der Google-Übermacht (um 98% bei Webseite und Blog) erspare ich mir die Grafiken zu den Suchmaschinen.

Verweise

Und zum Abschluss wiederum die Liste der wichtigsten Domänen, die auf meine Webseiten verlinken:

Rang Webseite Blog
1 nsis.sourceforge.net www.rolandbaer.ch
2 de.wikipedia.org m.facebook.com
3 forum.computerbild.de www.facebook.com
4 blog.rolandbaer.ch www.michaljanik.cz
5 de.answers.yahoo.com plus.url.google.com

Fazit

Grosse Veränderungen gegenüber dem letzten Jahr gab es auch dieses Jahr nicht. Es sind immer noch die selben Themen, verweisenden Seiten und besonders die selben Suchmaschinen, welche die Besucher auf meine Webseiten bringen. Wie schon im Fazit des letzten Jahres prognostiziert gab es hauptsächlich bei den Browsern einige Verschiebungen. Ob sich diese Verschiebungen auch im Jahr 2014 fortsetzen werden wird dann in einem Jahr klar sein.

Piwik 2.0.3 – CNIL empfiehlt Piwik

Logo Piwik 2

Logo Piwik 2

Mitte Januar wurde der Release 2.0.3 von Piwik veröffentlicht. Es handelt sich dabei um ein Bugfix-Release, für den 40 Tickets geschlossen wurden.

Die Commission nationale de l’informatique et des libertés (CNIL) in Frankreich hat Piwik analysiert und als das einzige Web Analytics Tool ausgezeichnet, das mit dem Datenschutz vollständig vereinbart werden kann. Dazu hat das CNIL auch den Source Code analysiert und ein Dokument als Hilfsmittel für die Konfiguration von Piwik (französisch, pdf) erstellt.

Die Ankündigung ist auf dem Piwik Blog (in Englisch, kurz) und auf der Webseite des CNIL (in französisch, ausführlich) zu lesen.

Welcher Constructor wird aufgerufen?

Image courtesy of "artur84" / FreeDigitalPhotos.net

Image courtesy of „artur84“ / FreeDigitalPhotos.net

Seit der Version 4.0 sind in C# Methoden mit Parametern erlaubt, die einen Default-Wert besitzen. Dies kann auch auf Contructor-Methoden angewendet werden, also z.B.

1
2
3
4
5
6
7
8
9
10
11
12
public class A
{
  public A()
  {
    // ...
  }
 
  public A(string x = "default")
  {
    // ...
  }
}

Die Frage ist nun: Welcher Constructor wird verwendet, wenn ich eine Instanz mit A a = new A(); erzeuge?

Versuch 1

Im oben beschriebenen Fall kann dies schnell beantwortet werden, indem man es einfach ausprobiert:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace ConstructorQuiz1
{
  class Program
  {
    static void Main(string[] args)
    {
      A a1 = new A();
      A a2 = new A("fix");
    }
  }
 
  public class A
  {
    public A()
    {
      System.Console.WriteLine("A()");
    }
 
    public A(string x = "default")
    {
      System.Console.WriteLine(x);
    }
  }
}

Und hier das Resultat:

A()
fix

Man sieht also, dass der „am besten passende“ Constructor verwendet wird und der Default-Wert keine Verwendung findet. (wenn der Standard-Constructor A() nicht existieren würde, würde natürlich der Default-Wert verwendet).

Versuch 2

Wenn man aber mit den Access Modifiers herumspielt ist das ganze nicht mehr so eindeutig. Setzen wir einmal den Access Modifier des Standard-Constructors auf internal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace ConstructorQuiz2
{
  class Program
  {
    static void Main(string[] args)
    {
      A a1 = new A();
      A a2 = new A("fix");
    }
  }
 
  public class A
  {
    internal A()
    {
      System.Console.WriteLine("A()");
    }
 
    public A(string x = "default")
    {
      System.Console.WriteLine(x);
    }
  }
}

Das Ergebnis ist immer noch das selbe, hier hat der geänderte Access Modifier also noch keine Wirkung gezeigt.

Versuch 3

Versuchen wir jetzt aber mal von Aussen zuzugreifen:

1
2
3
4
5
6
7
8
9
10
11
namespace ConstructorQuiz3
{
  class Program
  {
    static void Main(string[] args)
    {
      ConstructorQuiz2.A a1 = new ConstructorQuiz2.A();
      ConstructorQuiz2.A a2 = new ConstructorQuiz2.A("fix");
    }
  }
}

Dieser Code muss mit einer Referenz auf den compilierten Code aus dem zweiten Beispiel enthalten. Dies erfolgt beim Command Line Tool csc mit dem Parameter /r=<filename>.

Das Resultat sieht nun anders aus:

default
fix

Es wird jetzt also der Constructor mit dem Default-Wert aufgerufen, da der Standard-Constructor von der Dritt-Assembly nicht aufgerufen werden darf.

Fazit

Wann welcher Constructor verwendet wird ist nicht nur von den Parametern sondern auch von den Access Modifiern und dem Kontext abhängig.