kopf.lastig | Alles mögliche zu Themen wie Familie, Beruf, Medien etc. …

CAT | Software-Entwicklung

Wir hatten folgendes Problem.

Symptom: Manchmal wurden Bilder nicht geladen, Manchmal gab es Fehlermeldungen am Anfang oder Ende einer Seite.

Umgebung: J2EE-Anwendung auf Oracle IAS 9.0.4 (2 OC4J-instanzen) unter Sun Java VM 1.4.2 auf HP-UX, 8 Prozessor-Maschine, als Entwicklungsumgebung.

Analyse:

  1. vmstat sagt: ca. 35-40 Prozesse laufen ständig, Anteil user 15%, Anteil sys 85%, idle 0%. Memory ist nicht knapp, Paging kaum
  2. top sagt: eine oc4j-Instanz verursacht die prozessorlast
  3. die log-files sind leer! (0 bytes)
  4. jvm-stacktrace ergibt keine weiteren auffälligkeiten (kein anwendungscode im stacktrace, mostly waits oder Input/outputs)

Wir spielen das vorletzte build ein, welches am tag zuvor noch gelaufen ist.

Analyse:

  1. redeploy sehr langsam
  2. symptom und analyseergebnisse bleiben gleich

Wir rufen beim betrieb an.

Ergebnis: Filesystem voll!

nachdem der betrieb das problem behoben hatte, lief die anwendung (nach dem redeploy der aktuellen version) wieder normal.

·

Schon seit einiger Zeit bin ich zufriedener Nutzer von “Safari Books Online“. Dort kann man IT-Bücher online – gegen ein monatliches Entgelt versteht sich.

Es gibt einen 14-Tage Test-Zugang. Hier 6 Gründe, wozu man diesen Testzugang nutzen kann:

  1. Hast Du von einem interessanten Fachbuch gelesen oder gehört? Dann schau nach, ob es dieses Buch online bei Safari gibt, und wenn ja, ob es hält, was es verspricht.
  2. Planst Du, ein Buch “in Papierform” zu erwerben und kannst noch nicht beurteilen, ob es “das Richtige” ist? Dann hast Du die Möglichkeit, es online “durchzublättern” und eine beliebig umfangreiche Leseprobe vorzunehmen.
  3. Was gibt es für Bücher zu dem Gebiet, auf dem Du gerade arbeitest? Vielleicht beleuchtet das eine oder andere Aspekte, in die Du noch nicht so tief vorgedrungen bist oder gibt weiterführende Tipps.
  4. Willst Du Dein Wissen über aktuelle Themen in der IT erweiterten, dann suche Dir Bücher zu diesen Themen heraus (z.B. Service Oriented Architecture, Model Driven Architecture, …)
  5. Vielleicht gibt es ein “klassisches” Buch, in das Du schon immer mal einen Blick werfen wolltest (z.B. “Code Complete” von Steve McConnell).
  6. Last But not Least: (Technologie-neutrale) Buchempfehlungen für Softwareentwickler von der IEEE Computer Society

Es gibt übrigens auch Bücher zum Thema “IT Management”, Karriere u.ä.

Kürzlich wurde Version 2.0 von JAMon veröffentlicht. JAMon ist eine kleine, für Java-Anwendungen nützliche Monitoring-Bibliothek.

In Version 1 gab es die Möglichkeit, Ausführungszeiten von Code programmatisch zu messen:

JAVA:
  1.  
  2. Monitor m = MonitorFactory.start("berechnung");
  3. BerechnungsModul.berechne();
  4. m.stop();
  5.  

misst die Ausführungszeit der berechne-Methode. Das interessante hierbei ist

  1. Statistiken werden über die Ausführungszeiten (genauer: Ausführungsdauer) erstellt (Summe, Mittelwert, Standardabweichung und sogar Einteilung in bestimmte Klassen),
  2. Ausführungszeiten werden Namen gegeben (hier "berechnung") und
  3. Die Statistiken können als HTML-Report ausgegeben (programmatisch oder per JSP).

Damit ist schon viel getan, u.a.:

  • in Webanwendungen kann ich einen Servletfilter erstellen, der die Ausführungsdauer aller (oder nur bestimmter) Aufrufe misst (dies hat bei geringem Aufwand großen Nutzen),
  • Aufrufe an "externe Systeme" (z.B. Datenbank, Web-Services oder Betriebssystem) können gemessen werden
  • anhand der Messergebnisse kann der Entwickler abschätzen, ob eine Optimierung notwendig ist
  • anhand der Messergebnisse (z.B. im Vergleich zum Vortag) kann der Betrieb abschätzen, ob sich das System derzeit aussergewöhnlich verhält.

In Version 2 (ein komplettes Redesign) kommt hinzu, dass ich nicht nur Zeiten messen kann, sondern beliebige Einheiten. Ich kann z.B. eine Statistik über die Trefferzahl einer Suche führen:

JAVA:
  1.  
  2. int treffer = Suche.ausfuehren(...)
  3. MonitorFactory.add("treffer","anzahl",treffer);
  4.  

fügt die Trefferzahl dem Statistikeintrag "treffer", die in der Einheit "anzahl" gemessen wird, zu. Bisher habe ich nur noch nicht herausgefunden, wie man Klassen (im Sinne von "Unterteilung des Wertebereiches") für nutzerdefinierte Einheiten definieren kann.
Alles in allem ein Tool, welches einen großen Nutzen bringt. Das Spring-Framework unterstützt JAMon.

·

Picture this: after we had moved an old app from an old server to a new one, we kept getting "I/O Exception: Broken Pipe" now and then from our database connections. In the new environment, database lives on a different server than our app (as opposed to the old environment). Is there something wrong with the network?

My suspects turned out right: it's the firewall between app and database. It drops "unused" tcp connections after an hour. For some security reasons, this cannot be changed.

As our apps is rather old, some parts of it still do not use a connection pool and so there are db connnections that "linger" around unused for an hour and are used thereafter - bang, I/O exception.

So watch out for that and use a connection pool. Possibly one that can shrink (i.e. throw away unused connections).

Chapter 8 introduces Criteria Queries. Only QueryTest.java is affected. Besides the usual net.sf.hibernate to org.hibernate package import renaming, net.sf.hibernate.expressions in Hibernate 2 is replaced by org.hibernate.criterion.

Moreover, change the line

JAVA:
  1.  
  2. Example example = Example.create(new Artist(namePattern, null, null));
  3.  

to

JAVA:
  1.  
  2. Artist artist = new Artist();
  3. artist.setName(namePattern);
  4. Example example = Example.create(artist);
  5.  

because Hibernate 3 has generated no argument constructors only.

· ·

Nov/05

29

Domain-Driven Design

Die letzten Wochen habe ich "Domain-Driven Design" von Eric Evans gelesen (bei Lehmanns, Amazon). Ich finde, dieses Buch ist für Software-Entwickler sehr empfehlenswert, die sich des objektorientierte Programmiermodells bedienen.

Im Buch geht es darum, wie man gute Objektmodell für Fachdomänen erstellt (daher Domain-driven). Da es sich um ein ganzes Buch zu diesem Thema handelt, fängt es gar nicht erst bei "Substantive sind potentielle Klassen" an, wie es sonst doch recht üblich in OO-Büchern ist. Evans stellt Patterns vor, die ganz unterschiedlichen Scope haben (von "Entities" bis "Systemmetapher") und stellt diese Patterns auch in Zusammenhang zueinander.

Das Ziel von domain-driven design sind "Deep Models", d.h. Modelle und deren Implementierung (!!!), die aus der vertieften Analyse der Domäne entstehen. Ihr Mehrwert ist ein tiefes Verständnis der Domäne durch die Entwickler, eine größere Übereinstimmung im Wissen der Entwickler und Fachleute, verbesserte Wartbarkeit und vereinfachte Erweiterbarkeit.

Ganz klar wird allerdings herausgestellt, dass domain-driven design kein "must-have" ist, sondern das es auch Alternativen gibt.

Domain-driven design bedeutet nicht up-front design, sondern: Modell und Implementierung gehören zusammen; das Modell benötigt das Feedback durch die Implementierung. Es wird durch vertiefende Kenntnis (das ist ein Prozess!) der Entwickler über die Domäne gewonnen, Refactoring überträgt neu gewonnene Kenntisse auf das Modell und damit die Implementierung.

Highlights für mich sind:

  • Unterscheidung zwischen Entities und Value Objects
  • Layers - so habe ich mir das schon immer vorgestellt
  • Ubiquitous Language - eine gemeinsame (Fach-)Sprache ist Voraussetzung für gute Kommunikation
  • Intention-Revealing Interfaces - verbessert Lesbarkeit des Codes, damit Wartbarkeit und Verständlichkeit
  • Bounded Context - in welchem Kontext gilt ein Modell überhaupt (davon kann es in einer Anwendung mehrere geben)
  • Responsibility Layers - Verantwortlichkeiten innerhalb eines Objektmodell in Schichten aufteilen

Das Buch kann man auch bei Safari online lesen.

Chapter 7 is working in Hibernate 3 (as opposed to chapter 6). The most challanging in this chapter migrationwise are StereoVolumeType.java and SourceMediaType.java . Change the import-package names. The Usertype-stuff is now under the package "org.hibernate.usertype". It won't compile, yet as there are some methods missing. For SourceMediaType.java:

JAVA:
  1.  
  2. public Object replace(Object original, Object target, Object owner)
  3.     throws HibernateException {
  4.  
  5.         return original;
  6.    }
  7.  
  8. public Serializable disassemble(Object value) {
  9.        return (Serializable) deepCopy(value);
  10.  }
  11.  
  12. public Object assemble(Serializable cached,
  13.                            Object owner)
  14.     {
  15.         // Our value type happens to be serializable, so we have an easy out.
  16.         return deepCopy(cached);
  17.     }
  18.  
  19. public int hashCode(Object o) { return o.hashCode(); }
  20.  

For StereoVolumeType.java:

JAVA:
  1.  
  2. public Object replace(Object original, Object target,SessionImplementor session,
  3.                       Object owner)
  4.     throws HibernateException {
  5.                    
  6.                    return deepCopy((StereoVolumeType)original);
  7.   }
  8.                
  9. public int hashCode(Object o) { return o.hashCode(); }
  10.  
  11. public Object replace(Object original, Object target, Object owner)
  12.                throws HibernateException {
  13.                    
  14.                    return original;
  15.  }
  16.  

That's it.

· ·

Wir haben letztens unseren defekten Videorekorder durch einen neuen ersetzt. Nun stand ich vor dem Problem, alle Kanäle so einzuspeichern wie auf dem Fernseher. Ich habe mich dafür entschieden, einen automatischen Sendersuchlauf durchzuführen und dann mit der vorhandenen Funktion "2 Kanäle vertauschen" alle Kanäle an ihren richtigen Platz zu bewegen.


Welcher Algorithmus ist hier der beste?
Gegeben sei eine unsortierte Liste von Zahlen (die Zahl steht für die entgültige Senderplatzierung) sowie eine Vergleichsfunktion und eine Funktion zum Vertauschen von zwei Kanalplätzen. Gesucht ist der günstigste Algorithmus, um die Zahlen zu sortieren. Günstig meint minimal bzgl. der Summe der Distanzen, über die Kanäle vertauscht werden. Die Distanzen sind deshalb wichtig, weil ich auf der Fernbedienung entsprechend oft "vor" bzw. "zurück" drücken muss. Dies sollte minimal sein.

Die erste Idee ist natürlich, die klassischen Suchalgorithmen zu untersuchen. Ich bin nach Selection Sort vorgegangen. Quicksort fällt mir ein, weil dort auch Elemente vertauscht werden. Auch Bubble Sort nicht vergessen, weil dort nur benachbarte Elemente vertauscht werden, die Distanz also immer 1 ist.

Vielleicht gibt es einen anderen günstigen Algorithmus, weil wir hier ja Besonderheiten vorliegen haben: Gegeben ist eine Permutation von Zahlen 1 .. N, nicht eine beliebige Zahlenfolge.

Ich werde mal einige Untersuchungen durchführen und die Ergebnisse an dieser Stelle veröffentlichen.

Update 03.11.2005: Ich habe drei Algorithmen untersucht: BubbleSort, SelectionSort und QuickSort.

Den Standard-BubbleSort-Algorithmus habe modifiziert, s.d. die Liste vorwärt und rückwärts durchschritten wird - da die Distanz zwischen zwei Vertauschungen wichtig ist, hilft dies, diese Distanzen zu veringern.

Während ich SelectionSort aus dem Lehrbuch angewendet habe, ist meine Quicksort-Implementierung mit den "üblichen" Optimierungen versehen: für kleine Teilmengen wird SelectionSort angewendet. Die Wahl des Pivot-Elementes ist einfach, da die Positionsnummer mit dem Wert zusammenfällt und damit immer der "mittlere" Wert einer Liste genommen werden kann.

Zu den Ergebnissen: BubbleSort bleibt am wenigsten effizient. SelectionSort und QuickSort liefern sich ein Kopf-an-Kopf-Rennen, wobei es darauf ankommt, ab welcher Listenlänge QuickSort auf SelectionSort zurückfällt.

Wie folgendes Diagramm zeigt, "gewinnt" BubbleSort gegen SelectionSort ziemlich unabhängig von der Anzahl der Kanäle: der durchschnittliche Rang beträgt 1,8 (Rang 1 für den Gewinner, Rang 2 für den Verlierer, bei 2000 zufälligen Kanalbelegungen).
BubbleSort vs. SelectionSort

Beim Rennen SelectionSort gegen QuickSort ist der Ausgang abhängig von der Anzahl der Kanäle sowie dem Schwellwert, ab dem Quicksort in SelectionSort übergeht. Mit zunehmender Anzahl von Kanälen wird Quicksort stärker, bei ca. 39 Kanälen gibt es im Mittel ein "Unentschieden". Der Einfluss des genannten Schwellwertes läßt sich schlecht beschreiben. Das folgende Diagramm zeigt eine "Draufsicht" auf ein 3D-Diagramm. Die X-Koordinate ist der genannte Schwellwert, die Y-Koordinate die Anzahl der Kanäle. Die Farbe kodiert den mittleren Rang. Alles "ab" orange (und "höher") stellt den Gewinn (im Mittel) für QuickSort dar. Die blaue Fläche rechts der Diagonale steht "keine Messung", da dort der Schwellwert höher als die Hälfte der Anzahl der Kanäle liegt.
SelectionSort vs. Quicksort
Es scheint also so zu sein, dass eine "Vorsortierung" mittels Quicksort desto vorteilhafter ist, je größer die Anzahl der Kanäle.

Es bleibt die Frage, ob es einen anderen, günstigeren Algorithmus gibt.

No tags

<< Latest posts

Older posts >>

Theme Design by devolux.nh2.me