Was sind Enterprise JavaBeans?

13.02.2017

Enterprise JavaBeans (EJB’s) werden unter Java EE (Enterprise Edition) serverseitig eingesetzt, um Client/Server Systeme umzusetzen. Will man eine Java EE Applikation bauen, kommt man darum um EJB’s nicht herum. (Siehe Tomcat oder Websphere? )

In den EJB’s wird hauptsächlich Geschäftslogik eingebaut. Die ursprüngliche Idee war es, dass sich ein Programmierer mehr auf die Geschäftslogik konzentrieren konnte.

Der Einsatz von EJB’s passiert hauptsächlich auf der Stufe Anwendungsserver – Siehe Was ist ein verteiltes System?

Wie kann ich mir eine EJB vorstellen?

Nun, eine Enterprise JavaBean ab Version 3.0 ist schlussendlich nur ein einfaches POJO – Ein Plan Old Java Object.

Ein POJO ist eine einfache Java Klasse mit Attributen wie zum Bespiel Name und Vorname. Zu den Attributen gibt es klassischerweise Getter und Setter, um die Werte von ausser zu setzen oder zu holen.

Bei den EJB’s werden diese POJO’s noch mit Annotationen angereichert, um ihnen gewisse Eigenschaften zu verleihen.

Sie sehen also, dass EJB’s eigentlich nichts kompliziertes sind.

Wo kann EJB den Programmierer unterstützen?

Die EJB Technologie entlastet einen Programmierer bei der Übertragung der Daten vom Client zum Server, der Datenhaltung, der Systemüberwachung und bei allen Aspekten der Security wie etwa der Zugriffssicherheit. Diese Aufgaben übernimmt der Java EE Application Server.

Welche Typen von EJB’s gibt es?

Grundsätzlich unterscheidet man drei verschiedene EJB Typen:

1. Bei Stateless Session Beans sind zwei aufeinanderfolgende Aufrufe voneinander unabhängig und kennen sich grundsätzlich nicht. Eine solche Klasse hat keinen Zustand.

2. Bei Stateful Session Beans haben die Beans einen Status. Darum können Aufrufe hintereinander aufeinander aufbauen. Man spricht dabei von einem Zustandsautomaten. Der Zustand eines solchen Beans bleibt also bestehen über einen Methodenaufruf hinweg. Ein Client ist über mehrere Methodenaurufe hinweg an dasselbe Bean gebunden, bis dieses zerstört wird.

3. Bei Entities handelt sich um die bereits erwähnten simplen POJO’s. Genauer gesagt steckt hinter einer Entity am Ende ein konkretes Objekt, etwa ein Konto oder eine Transaktion.

Die Geschäftslogik steckt in den Session Beans – Etwa das Ausführen einer Transaktion, das addieren zweier Zahlen oder sonst eine Operation.

Entities sind Klassen aus der objektorientierten Welt und werden verwendet, um Daten in Datenbanken zu speichern (Thema objekt-relationales Mapping, siehe Was ist JPA? ).

Gibt es sonst noch etwas Erwähnenswertes?

Für einen Einstieg in Enterprise JavaBeans sollte dieser Artikel genügen. Man könnte vielleicht noch anmerken, dass EJB’s von einem sogenannten EJB-Container verwaltet werden beziehungsweise darauf laufen. Diesem kann dann auch mitgeteilt werden, wie er mit einer EJB umgehen soll, ob er etwa eine Bean für jeden Client neu instanzieren soll oder alle Clients eine Bean miteinander teilen.

Was ist ein verteiltes System?

13.02.2017

Grosse Applikationen in einem Unternehmen laufen heutzutage nicht mehr auf einem einzigen Rechner, sondern auf mehreren Servern. Ist eigentlich auch logisch, denn wenn der Hauptcomputer ausfallen würde und man etwa die Buchhaltungsapplikation nicht mehr verwenden könnte, wäre das nicht gerade optimal.

Läuft eine Applikation auf mehreren Servern spricht man von einem verteilten System. Bei ganz grossen Firmen ist das System nicht nur verteilt auf mehrere Server, sondern die Server selber sind auch von der Lokation her an verschiedenen Orten. Die Daten werden dann üblicherweise dupliziert und redundant gehalten. So kann ein Serverzentrum die volle Funktionalität übernehmen, wenn das zweite ausfallen würde – Am Besten so, dass der Kunde nichts davon merkt.

Was sind die Vorteile von verteilten Systemen?

Nun, wie erwähnt will man die Ausfallsicherheit eines Systems erhöhen. Stellen Sie sich vor, das Ebanking ihrer Bank würde für eine Woche ausfallen – Das wäre eine Katastrophe!

Desweiteren hat man bei einem verteilten System die Möglichkeit, bei der Überlastung eines Servers die Last auf weitere Server zu verteilen, siehe Was ist ein Load Balancer?

Aus diesen Gründen ist es daher sowieso keine Frage, ob grosse Firmen ein verteiltes System verwenden oder nicht. Systeme von Grossfirmen sind mittlerweile riesig und über etliche Jahre gewachsen. Systeme haben auch die Natur, dass sie sich ständig ändern. Daher muss die Architektur so skalierbar sein wie möglich.

Was ist eine typische Architektur eines verteilten Systems?

Eine Architektur, die man am sehr oft antrifft, ist die sogenannte Three Tier Architektur. Mit Tier ist dabei einfach eine Stufe einer Applikation gemeint.

Beim Tier 1 geht es um den Kunden, der an seinem Computer sitzt und die Anwendung er Firma benutzt. Er wird üblicherweise Client genannt. Diese Stufe findet also beim Kunden auf seinem Computer statt – Heutzutage normalerweise im Browser, da man praktisch nur noch Webapps baut statt echte Desktopprogramme.

Der Tier 2 geschieht dann bereits auf den Servern einer Firma. Dort läuft die Stufe der Anwendungsserver oder Applikationsserver. Die Benutzereingaben werden dort gesammelt und je nachdem, was gemacht werden muss, werden verschiedene Module aufgerufen. Dort ist auch der Kern oder der Wert einer Firma versteckt: In den Algorithmen und der Geschäftslogik.

Im Tier 3 geht es dann noch darum, die Daten zu persistieren und auf Datenbanken abzuspeichern.

Haben alle Firmen dieselbe Architektur?

Ha, schön wäre es! Wie es in der Natur des Menschen liegt, hat jede Firma ihre eigene Architektur und sogar innerhalb einer Firma existieren zig Architekturen, die verwendet werden. Alte Systeme werden am Leben gelassen, weil man zum Beispiel den alten Code nicht mehr versteht und lieber nichts ändert. Neue Systeme richten sich nicht an alten Systemen. Mitarbeiter werden ausgetauscht, die jeweils unterschiedliche Technologien bevorzugen oder kennen – Da passiert viel in einer wirklich grossen Firma.

Denken Sie auch daran, dass die Three Tier Architektur wirklich nur ein ganz grundlegender, traditioneller Gedanke ist. Innerhalb einer Stufe können verschiedene Unterstufen und Technolgien zum Einsatz kommen.

Ein Client kann zum Beispiel eine mit Java und JavaScript gebaute Buchhaltungssoftware verwenden, die per REST Services mit dem Applikationsserver kommuniziert. Im Applikationsserver gibt es nun eine Applikation, welche die Benutzerdaten in einer Oracle Datenbank abspeichert und mit Java darauf zugreift. Die Buchhaltungsdaten selber werden aber an einen Cobolservice weitergereicht, der diese Daten wiederum in einer DB2 Datenbank abspeichert.

Sie sehen, in der Realität können sehr viele Stufen durchlaufen werden, wenn man in einer Webapplikation einen simplen Knopfdruck macht.

Was ist das Gradientenabstiegsverfahren?

11.02.2017

Dieses Verfahren braucht man beim Machine Learning Algorithmus Adaline, weshalb ich hier einen mathematischen Einstieg in das Thema geben möchte. Beachten Sie, dass ich kein Mathematiker bin. Falls etwas nicht stimmt, dürfen Sie mich gerne korrigieren.

Das Gradientenabstiegsverfahren ist ein Verfahren, um bei einer Funktion das Minimum oder das Maximum zu finden.

Das kann ich schon mit Analysis!

Wie man das Minimum oder das Maximum findet haben wir in der Analysis gelernt:

Beispielfunktion:

f(x) = x^2 - 2x + 2

Vorgehen:
1. Die erste Ableitung von f herausfinden und = 0 setzen und auflösen

f'(x) = 2x - 2 = 0
x = 1

2. Bonusschritt: Die zweite Ableitung von f herausfinden und den gefundenen x-Wert aus 1 einsetzen

ist f'' < 0 -> Maximum
ist f'' > 0 -> Minimum

f''(x) = 2 -> Also ein Minimum

Warum also das Gradientenverfahren?

Also zuerst einmal schreibe ich extra diesen Blogeintrag, um das Gradientenverfahren zu erläutern, da wünsche ich mir schon ein bisschen Interesse! Und zweitens hat man in der Realität oftmals nicht solche einfache Funktionen wie x^2 – 2x + 2, sondern hochkomplizierte Gleichungen. Und wenn man diese dann noch = 0 setzen und auflösen soll – viel Spass damit!

Was ist denn ein Gradient?

Ah, jetzt also plötzlich doch Interesse. Nun, ein Gradient zeigt den höchsten Punkt einer Funktion. Oder etwa auf den höchsten Punkt beziehungsweise den steilsten Anstieg eines Berges.

Ich denke, so kann man sich das am Besten vorstellen. Stellen Sie sich vor, sie gingen mit einer Klasse von Schülern zum Matterhorn spazieren. Und ein Schüler hat eine ganz besondere Macke: Er zeigt mit seinem Arm immer genau zur Spitze des Berges. Den Schüler dürfen Sie dann spasseshalber Gradient nennen.

Wenn Sie sich ein Vektorfeld vorstellen, also etwa ein Feld mit 10*10 Punkten, dann würde von jedem Punkt aus ein Vektor zum höchsten Ding zeigen – Sei dieses Ding nun der wärmste Ort, der höchste Berg oder der hellste Punkt. Je nachdem, was Sie halt gerade für ein Bild anschauen. Und bei jedem Punkt gibt es einen solchen Gradienten.

Aber wir suchen doch das Minimum nicht den höchsten Berg

Ja genau, darum heisst es auch Gradientenabstiegsverfahren. Aber das kommt nicht so sehr drauf an. Man kann mit dem Gradientenverfahren ein Maximum oder ein Minimum suchen, dabei ändert sich nur ein Plus zu einem Minus.

Genug gequatscht!

Genau, jetzt schauen wir uns das Gradientenabstiegsverfahren an. Wir suchen also das Minimum einer Funktion.

Zuerst einmal das ganz allgemeine Vorgehen: Beim Gradientenabstiegsverfahren fängt man bei irgendeinem x Wert der gegebenen Funktion an. Dazu bildet man an diesem Punkt den Gradienten, also den Vektor, der zum tiefsten Punkt zeigt (und eben nicht zum höchsten, weil wir suchen ja das Minimum – sollte klar sein).

Dann gehen wir auf der Funktion in Richtung des Minimums um eine gewisse Schrittlänge. Nun sind wir dem Minimum also ein wenig nähergekommen.

Und jetzt berechnen wir wieder den aktuellen Gradienten, gehen dann eine Schrittlänge etc. bis wir beim Minimum angekommen sind.

Man merkt, dass man beim Minimum angekommen ist, wenn der y-Wert mit dem gefundenen x-Wert nicht mehr kleiner wird. Dann ist man beim Minimum.

gradient-descent

Und wie berechnet man den Gradienten?

Ganz einfach mit der (partiellen) Ableitung!

Beispiel: Wir haben die Funktion: f(x) = x^2 – 2x + 2 und wollen davon das Minimum herausfinden.

1. Wählen Sie eine zufälliges x

Etwa x = 3

2. Leiten Sie die Funktion ab

f'(x) = 2x - 2

3. Setzen Sie das x in die Ableitung

f'(3) = 2*3 - 2 = 4

4. Analysieren Sie das Ergebnis

Sie wissen hoffentlich noch, dass die Ableitung auch die Steigung des Vektors (oder der Tangente) an einem Punkt bedeutet.

Ist die Steigung positiv, geht der Vektor von links unten nach rechts oben. Ist die Steigung negativ, geht sie von links oben nach rechts unten.

Wenn nun die Steigung positiv ist, heisst das, wir sind bereits am Minimum vorbei und müssen zurück auf der Funktion – Wir müssen also unser gewähltes x verkleinern.

steigungen.png

Beim Maximum ist es übrigens dasselbe Verfahren einfach „Vorwärts gehen“ und „Rückwärts gehen“ sind vertauscht.

Ist die Steigung negativ, sind wir vor dem Minimum und müssen auf der Funktion vorwärts gehen – Und unser gewähltes x ein wenig vergrössern.

5. Nun können Sie also das neue x mit der gewählten Schrittlänge herausfinden und dann zum Schritt 3 gehen, bis das Minimum gefunden ist.

Was heisst partielle Ableitung schon wieder?

Bei der Funktion oben hatten wir nur eine Variable, nämlich x. Oftmals hat man aber noch ein y und vielleicht noch ein z. Für den Gradienten muss man dann die partielle Ableitung machen. Das bedeutet, man leitet die Funktion nach jeder dieser drei Variablen ab. Leitet man etwa nach x ab, werden y und z wie Konstanten behandelt. Am einfachsten stellt man sich für y und z dann zum Beispiel eine 1 vor und leitet die Variablen so ab, wie man eine 1 ableiten würde.

Beispiel
f(x,y,z) = x^2 * y^2 + z^3

Abgeleitet nach x = 2x * y^2

Abgeleitet nach y = 2y * x^2

Abgeleitet nach z = 3z^2

Diese drei Teile in einem Vektor geschrieben gibt dann den Gradientenvektor. Sucht man dann etwa den Gradienten beim Punkt P(1,1,1) setzt man diese Werte einfach in den Gradientenvektor und erhält den Gradientenvektor beim Punkt 1,1,1 = (2, 2, 3).

Die Länge des Gradientenvektors steht dabei für seine Steilheit/Steigung. Die Länge eines Vektors berechnet man folgendermassen:

|(2, 2, 3)| = WurzelVon( 2^2 + 2^2 + 3^2 ) = 4.12

Die Ableitung einer einfachen Funktion nach x ist wie gesagt die Steigung der Funktion. Und Steigung bedeutet nichts anderes als die Änderung der Funktion beziehungsweise irgendeiner Grösse. Mathematisch gesehen ist die partielle Ableitung einer Funktion die Veränderung dieser Grösse in eine der drei Richtungen x, y oder z.

Nabla

Nachdem mir kein besserer Wortwitz für diesen Nabla Absatz eingefallen ist als „Das Kind muss sich früher oder später von seinen Eltern abnabla“ habe ich es gelassen.

Auf jeden Fall ist der Nabla Operator das Dreieck, dass nach unten zeigt, und steht schlussendlich für einen Vektor, der die partiellen Ableitungen beinhaltet. Dieses komische Ding, das wie eine verkehrte 6 aussieht, steht für die partielle Ableitung.

nabla

Warum zeigt der Gradient immer zum höchsten Punkt? Magic?

Das scheint mir eine längere Geschichte zu sein weshalb ich einen eigenen Artikel dazu schreiben werde.

Ich bin verwirrt – Wo waren wir?

Also nochmals kurz zusammengefasst: Das Gradientenverfahren verwenden wir, um das Minimum oder Maximum einer Funktion zu finden. Man fängt dabei bei einem Punkt der Kurve an und berechnet den Gradienten mit der partiellen Ableitung nach jeder Variablen. Der Gradient zeigt immer zum höchsten/tiefsten Punkt. Wenn man diesen berechnet hat, weiss man, ob man auf der Funktion vor oder zurück muss, um zum Minimum/Maximum zu kommen. Dabei verwendet man eine gewisse Schrittlänge, mit der man sich dem Minimum/Maximum nähert.

Scheint eine bombensichere Sache zu sein

Nun, etwas muss man beachten: Die Schrittlänge darf nicht zu gross sein, da man dann Gefahr läuft, über das Minimum hinüberzuspringen und es so zu verpassen. Macht man dann den nächsten Schritt, springt man wieder über das Minimum – Und so kann das dann endlos weitergehen.

Die Schrittlänge muss daher genügend klein gewählt werden. Ist sie aber „zu“ klein, kann es ewig dauern, bis man beim Minimum angekommen ist.

schrittlaenge

Um diesen beiden Problemen entgegenzuwirken, macht man oftmals eine Standardisierung, welche die Daten den Eigenschaften einer Standardnormalverteilung anpassen. Aber auch dies ist eine Geschichte für ein anderes Mal.