Mathematische Formeln in WordPress

English

In diesem Blog ist nun das Plugin WP QuickLaTeX installiert, das das \LaTeX-Rendering bei QuickLaTeX durchführen lässt.

Wenn eine Seite nur mit [{\sf latexpage}] beginnt, kann man Formeln mittels \backslash(\ldots\backslash) oder \backslash[\ldots\backslash] einbetten und in LaTeX-Notation formulieren.

Nun ist es möglich, in diesem Blog mathematische Formeln zu verwenden, z.B.:

    \[ \bigwedge_{z\in\Bbb C}\, \sin z = \sum_{k=0}^\infty \frac{(-1)^k z^{2k+1}}{(2k+1)!}=z-\frac{z^3}{6}+\frac{z^5}{120}-\frac{z^7}{5040}+\ldots \]

    \[ \bigwedge_{z\in\Bbb C}\, \cos z = \sum_{k=0}^\infty {\frac{(-1)^k z^{2k}}{(2k)!}}=1-\frac{z^2}{2}+\frac{z^4}{24}-\frac{z^6}{720}+\ldots \\ \]

    \[ {\bigwedge_\stackrel{z\in\Bbb C}{\cos z \ne 0}} \tan z = \frac{\sin z}{\cos z} \\ \]

    \[ {\bigwedge_\stackrel{z\in\Bbb C}{\sin z \ne 0}} \cot z = \frac{\cos z}{\sin z} \\ \]

    \[ {\bigwedge_\stackrel{z\in\Bbb C}{\cos z \ne 0}} \sec z = \frac{1}{\cos z} \\ \]

    \[ {\bigwedge_\stackrel{z\in\Bbb C}{\sin z \ne 0}} \csc z = \frac{1}{\sin z} \\ \end{align} \]

    \[ \sec(z) = 4\pi \, \sum_{k=0}^{\infty} \frac{(-1)^k(2k+1)} {(2k+1)^2 \pi^2 - 4 z^2 } \]

    \[ \csc(z) = \frac{1}{z} - 2z \, \sum_{k=1}^{\infty}\frac{(-1)^k} {k^2\pi^2-z^2} = \sum_{k=-\infty}^\infty \frac{(-1)^k \, z}{z^2-k^2\pi^2} \]

Ich werde also, wenn es sinnvoll ist, entsprechende mathematische Formeln damit schreiben und nicht mehr irgendwelches unübersichtliches ASCII-Gebastel dafür benutzen.

Warum benutzt man sowas nicht für Entwicklungsumgebungen von Programmiersprachen? Wenn eine Formel „steht“, könnte man sie viel schöner anzeigen als mit diesem Zeichensalat im Editor. Nun ja, ich glaube, Donald Knuth hat das vor einigen Jahrzehnten auch mal gemeint und dann das sogenannte „literate programming“ erfunden. Der Quelltext ist also eine Datei, aus der man mit weave und tangle (oder fweave und ftangle oder cweave und ctangle) einerseits eine .tex-Datei und andererseits eine kompilierbare nicht-literarische Quelltext-Datei generieren kann. So läßt sich für den Leser ein wunderschöner Ausdruck erzeugen und der Compiler baut das auführbare Programm. Eine kleine Spur dieser Ideen ist ja mit javadoc und rubydoc und perldoc verwirklicht worden, aber das mit den Formeln fehlt natürlich noch.

Share Button

Automatic Test of Links

Deutsch

Running a web site with hundreds or thousands of links it is essential to have automatic mechanisms for testing these links. Many tools are available for this. I am using the Perl library LWP. My page www.it-sky-consulting.com has only about 130 links, but off course I want to establish processes that scale.

The problem is that in some cases naïve automatic tests do not work very well, mostly because the web servers react differently to test scripts than to a real browser. Some examples:

  • Language settings of the browser sometimes lead to language specific pages. It would be best to test with several language settings.
  • Some pages result in an error code (usually 500) when accessed by a script, but work fine in a browser.
  • Some servers avoid returning the error code 404 (or maybe 403) for pages that no longer exist. Instead they forward to a human readable error page with code 200, which looks ok to the script. The page forwarded to contains a friendly description of the error, which is hard (but not totally impossible) to recognize by a script. Often the name of the error page contains „404“.
  • Domains are actually given up.  Usually some company grabs these domains and puts their content on them, hoping to gather some part of the traffic of the former web site.  This is often commercial, but might even be x-rated content.

So automatic checking of web links remains difficult and still requires some manual work.  5% of the links cause about 95% of the work.

I am interested in improving these processes in order to increase the quality of the tests and to decrease the effort.

Share Button

Links automatisch überprüfen

English

Bei einer Webseite mit hunderten oder tausenden von Links ist es sehr hilfreich, wenn man diese automatisiert überprüfen kann. Dafür gibt es viele Hilfsmittel. Ich verwende die Perl-Library LWP.  Ja, www.it-sky-consulting.com hat heute nur etwa 130 verschiedene Links, aber ich möchte natürlich auch dafür Prozesse haben, die skalieren.

Ein Problem ist aber, daß einige Webseiten auf solche Testskripte anders reagieren als auf einen Browser. Ein paar Beispiele:

  • Spracheinstellungen des Browsers führen dazu, daß zu einer sprachspezifischen Seite weitergeleitet wird.  Man müßte also mit etlichen Spracheinstellungen testen.
  • Manche Seiten ergeben beim automatisierten Test einen Fehler, z.B. Fehlercode 500, funktionieren aber im Browser.
  • Manche Server geben bei längst nicht mehr vorhandenen Seiten nicht den Fehlercode 404 (oder eventuell 403), sondern leiten an eine Seite weiter, auf der freundlich auf die Fehlersituation hingewiesen wird.  Wenn man die Sprache der Seite versteht, ist das gut.  Für ein Skript relativ schwierig zu lernen, auch wenn man gewisse Muster beachten kann:  Die Weiterleitung geht häufig auf die Home-Seite des Servers oder auf eine Seite, in deren Dateiname „404“ vorkommt.
  • Es wird immer mal wieder eine Domain aufgegeben.  Meistens wird die dann sofort von einer Firma übernommen, die dort ihren Content, z.B. Werbung, plaziert, in der Hoffnung den Traffic der etablierten Seite erben zu können.

So bleibt die automatische Überwachung der Links immer noch schwierig und erfordert gewisse manuelle Tätigkeiten.  Nicht die 80-20-Regel gilt hier, sondern es ist eher so, daß 5% der Links etwa 95% der Arbeit machen.

Ich interessiere mich dafür, diese Prozesse weiter zu verbessern, also die Qualität der Überprüfungen zu erhöhen und den Aufwand zu verringern.

Share Button

Overflow of Integer Types

Deutsch

Handling of integral numbers has always been one of the basic capabilities of our computing devices. Any common programming language since the fifties provides this in some way.

There are some significant differences between the ways integral numbers are handled in different programming languages.

Dealing with the overflow

There are several approaches:

  1. Integral numbers can have any number of digits, as far as the memory allows. Results of calculations that need more bytes to be stored than the input are stored in as many bytes as needed to be represented completely. There is no need to deal with overflow, unless the numbers are so big and so many that they eat up the available memory. Examples: Common Lisp, Ruby
  2. Integral numbers have a fixed number of bits. If a calculation results in a number that cannot be expressed in these many bits, the upper bits are tacitly discarded, unless each operation is accompanied by elaborate indirect checks for overflow. Examples: C, Java
  3. Integral numbers have a fixed number of bits. If a calculation results in a number that cannot be expressed in these many bits, an exception is thrown. I do not have any examples, maybe someone can suggest an example.
  4. Integral numbers have a fixed number of bits. For results of a multiplication, a type with twice as many bits as the two factors is used. For results of addition, a type with as many bits as the summands is used, but a carry bit is provided, too. This is the extra bit that is needed to express the result in all possible cases. Using this carry bit and feeding it into the next addition, it is possible to add numbers of arbitrary length, as needed for solution 1. Multiplication, Division and Subtraction can be implemented in a similar manner. Example: Assembly language
  5. Not integers are available and floating point numbers have to be used instead. Example: Lua

Evaluation

Solution 1 is exactly what is needed for application development. Counting of bits, checking for overflow and such practices are just absurd during the development of business logic. This is quite a strong argument in favor of using Ruby (or Lisp) for application development.

Solution 2 is simply crap. I consider this the most serious design bug of C and Java. Rounding is something that we can accept in many cases, but that discards the lower bits. Here we tacitly discard the upper bits. Average software developers do not really want to deal with these issues, sometimes they are simply ignored, because the bugs do not occur frequently and are not discovered during the testing phase. Throwing away the carry bit, which contains very important information for implementing solution 1 or for just recognizing overflows is not a good idea. There are workarounds for this, but they double the runtime of certain calculation intensive software.

Solution 3 would be acceptable, but I consider solution 4 better. Low level code should leave it to the developer if an exception is thrown or if the situation can be handled.

Solution 4 is quite acceptable and useful for low level programming, but not for typical application development. Sometimes access to bits and bytes is needed explicitly, for example to talk to external hardware, to implement the lower layers of network protocols or similar issues. It can be useful for very performance critical calculations, where it can be guaranteed that no overflows occur. The possibility to deal with a carry bit at least optionally cannot do any harm. Unfortunately this is currently only (or almost only?) possible in assembly languages. For implementing integer arithmetic for languages like Ruby or Lisp, some implementation that works with solution 2 by doing crappy workarounds needs to be provided, but for common CPU-architectures it is possible to provide an implementation in assembly language based on solution 4, that will run about twice as fast.

Solution 5 is just an unnecessary restriction.

Conclusion

Many software developers think that this does not interest them or is not their problem. I recommend to take this issue serious. The bugs caused by the tacit overflow are hard to find, because they can occur anywhere and they might not show during testing. But then they occur with some weird combination of data on the productive system. Who wants to find the cause of a weird bug, that surfaces far away from the real cause? Only solution 1 allows the application developer to safely ignore these problems.

Share Button

Überlauf bei ganzzahligen Datentypen

English

Der Umgang mit ganzzahligen Datentypen (Integers u.ä.) gehört zu den grundlegenden Fähigkeiten unserer Rechner. Das kann jede gängige Programmiersprache seit den 50er Jahren.

Es gibt jedoch einige Aspekte, wie sich die Verwendung der Ganzzahlen in verschiedenen Programmiersprachen unterscheidet.

Umgang mit dem Überlauf

Für die Größe der Ganzzahlen gibt es mehrere Ansätze:

  1. Ganzzahlen werden automatisch mit so vielen Stellen gespeichert, wie nötig sind.  Wenn durch eine Rechnung ein Ergebnis entsteht, das mehr Stellen benötigt, werden entsprechend viele Stellen bereitgestellt.  Man muss sich also nicht um die Größe und den Überlauf kümmern, außer man schöpft den Hauptspeicher aus.  Beispiele: Common Lisp, Ruby
  2. Ganzzahlen haben eine bestimmte Anzahl von Bits.  Wenn durch eine Berechnung ein Ergebnis entsteht, das mit der vorgegebenen Anzahl von Bits nicht ausdrückbar ist, werden die oberen Bits einfach weggeworfen, ohne dass man davon etwas merkt. Außer man macht nach jeder Operation aufwendige Überprüfungen.  Beispiele: C, Java
  3. Ganzzahlen haben eine bestimmte Anzahl von Bits.  Wenn durch eine Berechnung ein Ergebnis entsteht, das mit der vorgegebenen Anzahl von Bits nicht ausdrückbar ist, wird eine Exception ausgelöst.  Mir fallen im Moment keine Beispeiele ein, die diesen Weg gewählt haben.
  4. Ganzzahlen haben eine bestimmte Anzahl von Bits.  Für Ergebnisse von Multiplikation wird ein Typ verwendet, der doppelt so viele Bits hat.  Für Ergebnisse von Addition wird ein Typ mit genauso vielen Bits verwendet, aber man erhält zusätzlich noch ein Carry-Bit für den Übertrag.  Damit lassen sich durch interiertes Addieren von Teilen einer langen Zahl auch Langzahlen mit beliebig vielen Stellen addieren.  Multiplizieren, Dividieren und Subtrahieren von Langzahlen lässt sich auch auf ähnliche Weise bewerkstelligen.  Beispiel: Assembler
  5. Ganzzahlen werden ganz weggelassen und man behilft sich mit Fließkommazahlen.  Beispiel: Lua

Bewertung

Lösung 1 ist das, was man für Applikationsentwicklung haben sollte.  Das Zählen von Bits, Überprüfen von Überläufen u.s.w. ist für die Entwicklung von Business-Logik einfach abwegig.  Für mich durchaus ein Argument, Ruby (oder Lisp) vor Java zu bevorzugen, wenn es um Applikationsentwicklung geht.

Die Lösung 2 ist einfach unsinnig und wohl der größte Designfehler von C und Java.  Rundung ist etwas, was man noch akzeptieren kann, aber dass stattdessen die oberen Stellen stillschweigend weggeworfen werden, ist ein „Feature“, mit dem der durchschnittliche Software-Entwickler nicht umgehen will bzw. das man auch ignoriert, weil es ja meistens gut geht und man mit dem Fehler nicht rechnet.  Außerdem wirft man mit dem Carry-Bit wichtige Information zur Implementierung von Lösung 1 weg, was bei rechenintensiver Software ungefähr eine Verdopplung der Laufzeit nach sich zieht.

Lösung 3 wäre im Gegensatz zu Lösung 2 schon grundsätzlich brauchbar, ich halte aber Lösung 4 für besser.

Lösung 4 ist akzeptabel für Low-Level-Programmierung, als nicht für Applikationsentwicklung.  Manchmal braucht man wirklich Bits- und Bytes explizit, um z.B. externe Hardware anzusteuern, Netzwerkprotokolle auf den untersten Schichten zu implementieren o.ä.  Die Möglichkeit, ein Carry-Bit dabei zumindest optional berücksichtigen, kann nicht schaden.  Leider ist dies meines Wissens (fast?) nur in Assemblersprachen so umgesetzt und wenn man eine Langzahlarithmetik zum Beispiel für Ruby implementiert, dann muss man in C ein Gebastel auf der Grundlage von Lösung 2 in Kauf nehmen, kann aber für bekannte gängige CPUs zusätzlich eine etwa doppelt so schnelle Implementierung in Assembler auf der Grundlage von Lösung 4 anbieten.

Lösung 5 ist am falschen Ende gespart.

Fazit

Viele Software-Entwickler meinen, dass sie das Thema nicht interessiert oder nicht betrifft.  Ich empfehle aber, dieses Thema ernst zu nehmen.  Die Fehler durch den stillschweigenden Arithmetiküberlauf sind sehr schwierig zu finden, weil sie überall auftreten können und weil sie beim Testen womöglich nicht einmal auffallen, da erst in der Produktion Daten auftreten, die den Überlauf auslösen. Nur Lösung 1 erlaubt es dem Applikationsentwickler, sich die Beschäftigung mit der Überlaufproblematik weitgehend zu sparen.

Share Button

Antispam-Plugin

WordPress empfiehlt als Antispam-Plugin Akismet. Dieses werde ich hier jedoch nicht verwenden. Die Funktionisweise von Akismet besteht darin, alle Daten von Kommentatoren an die in den Vereinigten Staaten stehenden Akismet-Server zu übertragen, auf denen die Funktionalität zum Erkennen von Spam umgesetzt ist. Technisch gesehen ist so ein zentraler Server sicher interessant und je mehr Daten er sammelt, desto zuverlässiger kann er Spam erkennen.

Jedoch ist dieser Ansatz für europäische Blogs problematisch. Die Informationen, die öffentlich sichtbar werden, also der Kommentartext, sind mit etwas gesundem Menschenverstand unproblematisch, weil dieser Blog weltweit lesbar. Aber nicht-öffentliche Informationen, wie z.B. IP-Adressen, Mailadressen u.s.w. sollten nicht einfach so herausgegeben werden. Artikel dazu findet man beliebig viele, ich verweise mal auf Wikipedia, Sergej Müllers Blog, Datenwachschutzblog und auf die Möglichkeit, beliebig viele weitere Artikel zu dem Thema mit der Suchmaschine des Vertrauens zu finden.

So werde ich mir irgendwann einmal Alternativen zu Aksimet ansehen, z.B Antispam Bee, Mollom, Defensio oder Typepad Antispam.

Vielleicht reicht der Captcha-Mechanismus auch aus, um Spam zu unterbinden. Zur Zeit ist WordPress so konfiguriert, daß ich Kommentare zu den Artikeln manuell freischalten muß. Das beabsichtige ich zu tun, solange sie zum Thema sind und nicht grobe Verstöße gegen ungeschriebene, allgemeingültige Nettiquette Regeln beinhalten. Da Spam-Kommentare inhärent „off-topic“ sind und außerdem noch gegen die Nettiquette verstoßen, werde ich sie auf jeden Fall nicht freischalten. Aus heutiger Sicht ist also ein Antispam-Plugin für diesen Blog noch nicht eilig.

Wer sich aus Datenschutzgründen dafür interessiert: Die Server, auf denen dieser Blog läuft, stehen in Deutschland. Der Internetverkehr dorthin kann aber irgendwelche Wege durch irgendwelche Länder nehmen und unterwegs analysiert werden. Das ließe sich mit https verhindern oder zumindest erschweren, nur unterstütze ich zur Zeit leider kein https.

Anmerkung: Inzwischen ist der Spam auf diesem Blog zur Plage geworden. Deshalb setze ich jetzt Antispam-Bee ein, was den europäischen Datenschutzbestimmungen gereicht werden soll.

Share Button

Latency of DB-connections

Deutsch

Applications that are using a database are often running slower than one would  expect by the power of the hard- and software.  Both DB server and application server are running on powerful machines that are not even close to their limits.

The problem is the connection between the two servers. This connection is off course very fast, which can be quite impressive when huge amounts of data need to be transferred, all at once.  Ideally think of the huge  resultset  of one query.

Typical database access operations need multiple accesses to the DB-server.  Each one of these works according to a communication protocol.  Usually this implies some round trips.  So many small accesses to the database tend to slow the whole application, because it is mostly waiting for the connection.

What can be done about this?
First of all the real bottleneck should be identified before optimizing something that is not the problem.

It does make a lot of  sense to optimize the application for larger and fewer queries, so more data is transferred at once.  This may not be easy with frameworks, especially if eclipselink or hibernate is used.  A typical anti pattern is to read a large number of records from the database and then fetch detail information for each record from another table, with one request for each record.  This can usually be avoided by using complex SQL queries and it is sometimes worth the effort.  As always optimizations should only be done where they are either not very intrusive or where the benefit is likely to justify them.

Another more general optimization is to put application and database on the same server.  This is often not easy, because many system administrators do not like this too well.  But if sufficient performance can only be achieved by putting all on one server, this is recommended.  Maybe it is an advantage of NoSQL databases that system administrators do not know any best practices that suggest to install database and application on different servers, so they can be running on the same server, thus eliminating most (but not all) of the latency.

Share Button

Latenz von DB-Verbindungen

English

Applikationen, die eine Datenbank verwenden, sind oft zu langsam, obwohl man doch einen großen Server für die Applikation und einen zweiten großen Server für die Datenbank bereitgestellt hat. Und schaut man sich diese beiden an, sind sie womöglich noch nicht einmal so stark ausgelastet.

Das Problem ist, dass die Verbindung zwischen den beiden Servern zwar sehr schnell ist, was man vor allem daran sieht, wenn man große Datenmengen auf einmal überträgt.

Typische Datenbank-Applikationen benötigen aber viele einzelne Zugriffe auf die Datenbank. Bei jedem dieser Zugriffe muss ein Kommunikationsprotokoll angewendet werden, also mehrere Male eine Antwort über die Verbindung abgewartet werden. Deshalb führen viele kleine Datenbankzugriffe zu einer Verlangsamung der Applikation, weil dauernd auf die Netzwerkkommunikation gewartet werden muss.

Was kann man tun?
Sinnvoll ist sicher, die Applikation so zu optimieren, dass durch geschickte Queries mehr Daten auf einmal übertragen werden. Das ist oft nicht einfach, wenn man Frameworks wie zum Beispiel Hibernate oder Eclipselink verwendet.
Eine andere Optimierung ist es, Datenbank und Applikation auf demselben Server laufen zu lassen. Diese Optimierung ist auch nicht einfach, weil das die Systemadministratoren in der Regel überhaupt nicht mögen, aber es ist eine Möglichkeit, die man doch in Betracht ziehen sollte, wenn sich anders keine hinreichend gute Performance erzielen lässt.

Share Button