Kategorien
Themen

Generatoren, Segen oder Fluch?

Zuerst, ich mag Generatoren, ein Compiler ist auch ein Generator, der aus etwas, was ich verstehe, etwas generiert, was der Computer versteht.

Andere Generatoren nehmen dem Programmierer viel Arbeit ab, zum Beispiel das Generieren der Getter und Setter in Eclipse. Die Getter und Setter werden nur einmal generiert und danach modifiziert!

Als Programmierer verbringt man viel Arbeitszeit mit dem Debuggen von Programmen. Natürlich nicht den selbst erstellten, die sind ja fehlerfrei, oder?

Vor einigen Jahren durfte ich eine Unschärfe in einem 3270 Dialog-Programm suchen. Das Programm war mit einem Generator „Telon“ erzeugt worden und zeigte laut Bug-Meldung manchmal den letzten Datensatz in einer Liste nicht an. Das Problem war anhand des Modells, das der Generator als Eingabe verwendete, nicht zu erkennen. Der Kollege, der einige Zeit vorher das Programm erstellt hatte, war auch nicht mehr greifbar. Also habe ich mich zwei Tag durch die vielen tausend Zeilen generierten, sehr schlecht lesbare, die Technologie des Herstellers verschleiernden Code mit dem Debugger gewühlt. Das Problem war eigentlich trivial, am Ende der CURSOR Verarbeitung von zwei mit UNION verbundenen SELECT Anweisungen wurde der SQL-Code so interpretiert, dass der letzte Satz nicht in die anzuzeigende Liste übernommen wurde. Die Prüfung des SQL Codes und ggf. das Setzen des richtigen SQL Codes, damit anschliessend der generierte Code auch den letzten Satz übernahm, war schnell im Modell eingebaut, das Programm neu generiert und kompiliert. Aber die zwei Tage „auf den Bildschirm starren“ war sehr anstrengend. Hätte ich auf Level des Modells debuggen können, hätte ich das Problem wohl in wenigen Minuten gefunden. 

In meiner Anfangszeit, so vor dreizig Jahren, habe ich auch einen Generator (für dBase, unter MS-DOS eine weit verbreitete „Datenbank“ mit Programmiersprache) geschrieben. Damit hatte ich dann einige Anwendungen generiert und im Einsatz. Aber es gab den ein oder anderen Bug im generierten Code, der natürlich nicht beim Testen des Generators und meiner ersten (Test-) Anwendung auffiel, sondern später, als etliche Programme mit dem Generator erzeugt waren. Das Finden des Fehlers dauerte von Minuten bis zu einer halben Stunde, die Änderungen im Generator hatte ich 5 Minuten eingebaut, das Neugenerieren und Testen der Anwendungen brauchte dann so ein bis zwei Tage. 

Das musste doch besser gehen, sagte ich mir.
Aber leider nicht in dBase! Mit „Clipper“ (einen Compiler für dBase) konnte ich die Idee umsetzen. Ich baute einen Rahmen (Framework) und eine Anzahl an Library Funktionen. Die für die jeweilige Anwendung benötigte Funktionalität baute ich in Prozeduren ein, die die Library Funktionen nutzten und die ich beim Framework anmeldete. Damit wurde nichts mehr generiert, sondern die Dinge, die bisher der Generator „schrieb“, waren jetzt „einfach da“. Bug gab es auch hier, aber nach dem Finden und Beseitigen musste nur noch der Linker laufen.

Beim Übersetzen der Library-Funktionen hatte ich meist mit Absicht die Debugger-Unterstützung ausgeschaltet, so konnte ich die Anwendung testen und wanderte nicht in die Tiefen der allgemeinen Funktionen.

Ich sehe seitdem Generatoren kritisch.
Einfache Dinge, siehe Getter und Setter, machen Sinn.

Generatoren für komplexe Dinge sind schneller erstellt wie ein entsprechendes Framework.

Aber das Debuggen muss auf Ebene des Generator Inputs, also des Modells, erfolgen können. 
Und hier werden Generatoren, die einfach nur Sourcen in einer Zielsprache (COBOL, JAVA, …) erstellen, scheitern. 
Das Debuggen wird in der Zielsprache stattfinden müssen, und der Debugger kann nicht die „allgemeinen“ Teile der generierten Sourcen ausblenden und nur die für die zu testende Anwendung speziellen Teile anzeigen.
Der Entwickler hat „in seinem Kopf“ ständig den Generator am Laufen, er muss das Modell, in dem sein Programm erstellt wurde, ja ständig mit der Source im Debugger, also den aus dem Modell generierten Code, abgleichen.

Fehlerbeseitigung am Generator bedeutet immer, aller Programme neu zu generieren und zu testen.

Es soll übrigens Programmierer geben, die in generierten Sourcen ändern. Wenn dieses vor dem Neugenerieren nicht auffällt, beginnen die Probleme erst.

Kategorien
Themen

Es muss nicht immer XML sein

XML ist die Lösung aller Probleme, wird vielfach geschrieben.

Ich mag XML, ich nutze XML, zum Beispiel für mein Profil, für Schnittstellen (WebServices), teilweise für INI-Dateien (Programmeinstellungen), …
Vor XML habe ich SGML genutzt, und finde die beiden deutlich besser wie die IDL von CORBA.

Der grosse Vorteil von XML ist die Möglichkeit, eine XML Anwendung in eine andere XML Anwendung zu Transformieren. XML selber ist ja nur ein kurzer Satz an Regeln, jedes Element beginnt mit einem Start-Tag <DiesesIstEinElement> und endet mit einem End-Tag </DiesesIstEinElement> und nur innerhalb eines Elements dürfen andere Elemente enthalten sein. 

Über die DTD, XSD oder Relax wird der genaue Syntax der Anwendung, zum Beispiel der Aufbau einer Nachricht zum Handel mit Aktien, beschrieben. 

XHTML ist eine XML Anwendung. HTML ist übrigens eine SGML Anwendung, deshalb sind zum Beispiel Dinge wie <p><b>Test</p></b> in HTML erlaubt, bei XML wäre die Regel der „well formed“ verletzt.

Um zum Beispiel aus der XML Anwendung, in dem ich mein Profil pflege und die ich mit DTD (es war im Jahr 1999, da gab es nur DTD) beschrieben haben, ein HTML Dokument oder ein FOP (der Input zu Apache FO, um dann ein PDF zu erzeugen), wird ein XLST genutzt.

Für die Umwandlung des XML, das ein WebService liefert, in das hausinterne XML Format, wird auch XLST genutzt. Ein solches XLST ist ein XML, das in etwa den Aufbau des Ziel XML hat, in zusätzlich XPath Ausdrücke enthält, um die Daten aus der Quell XML Anwendung einzufügen.

Bei einfachen Transformationen ist das XLST schnell zu erstellen.
In COBOL würde das gleiche mit
move CORR Input to Output
gemacht werden, wenn die Namen innerhalb von Input zu denen von Output passen und die Formate kompatible sind.

Bei komplexen Transformationen wird XLST schnell sehr unübersichtlich. Dann ist es besser ein Programm zu schreiben.

Aber wohl liegt nun der Vorteil von XML?

XML ist für einen Menschen, der über die entsprechende Ausbildung und Erfahrung verfügt, besser zu lesen wie ein Flatformat File.
Dafür ist das Flatformt File für einen Computer einfacher zu verstehen.
Und für einen erfahrenen Programmierer (nur diese verfügen in der Regel über die Ausbildung und Erfahrung, ein XML auf Fehler zu prüfen oder direkt zu editieren) und auch für Anwender gibt es Tools, um ein Flatformat lesbar darzustellen und zu editieren (zum Beispiel CompuWare FileAid auf IBM Mainframes).

Der eigentliche Grund für XML ist aber ein anderer: Die verschiedenen Zeichensätze, die bei Computern verwendet werden.

Unicode, also der 16 Bit Zeichensatz, mit dem alle Zeichen, die auf der Erde benötigt werden, eindeutig beschreibbar sind, ist eine recht junge Entwicklung. 

Vor 30 Jahren wurde vielfach ein 7 Bit Zeichensatz verwendet, der ASCII Zeichensatz. Da er für die USA entwickelt wurde, fehlen dort die deutschen Umlaute, also gab es dann den DIN Zeichensatz, wo die 7 Bit Werte für die eckigen und geschweiften Klammern und einige andere Zeichen des ASCII Zeichensatzes für die Umlaute verwendet wurden. Mit dem DIN Zeichensatz kann man also nicht C oder Java programmieren. 

Deshalb erweiterte IBM für den PC den Zeichensatz auf 8 Bit, die unter Hälfte entspricht dem ASCII Zeichensatz, die obere Hälfte beinhaltet u.a. die Umlaute. Neben IBM erfand auch Microsoft einen 8 Bit Zeichensatz für Windows (ANSI), die untere Hälfte ist wieder der ASCII Zeichensatz, die obere Hälfte enthält teilweise die gleichen Zeichen, aber in einer anderen Kodierung. Für die westeuropäischen Sprachen waren alle notwendigen Zeichen im IBM-PC und im ANSI-Zeichensatz enthalten, aber nicht für andere Sprachen. Also gibt es eine sehr große Anzahl an verschiedenen 8 Bit Zeichensätzen.

Auf dem Grossrechnern gibt es den EBDIC Zeichensatz. Der wichtigste Unterschied zu den PC Zeichensätzen ist die Sortierung.
Auf dem PC gilt Space < 0 < 9 < A < a,
bei EBDIC Space < A < a < 0 < 9. 

Da die Grossrechner nicht nur in den USA und Westeuropa laufen, gibt es hier auch verschiedene Zeichensätze mit verschiedenen Sonderzeichen. Für Deutschland nutzte man früher meist EBDIC 273, mit Einführung des Euro-Zeichens den EBDIC 1141.

Bei XML sollte in der ersten Zeile ein Hinweis auf den verwendeten Zeichensatz stehen, damit weiss der Zielcomputer, ob und wenn ja welche Zeichensatz-Transformation benötigt wird.

Diese Information kann aber auch beim Transfer zwischen verschiedenen Rechnern mitgegeben werden, so etwas kennt jedes File-Transfer Programm und auch FTP.

In XML sind alle Werte als Zeichen kodiert, die Zahl „minus Siebenunddreizig“ steht als „-37“ im XML. 

In Flatfiles kann „-37“ binär (als signd integer im Dualsystem „1000.0000.0010.0101“), BCD (jede Ziffer wird mit 4 Bit kodiert, das Vorzeichen ist das letzte Halbbyte, also in hexadezimal System „037C“) oder als Zahl aus 8 Bit Zeichen, wobei das Vorzeichen im oberen Halbbyte des letzten Bytes steht (im Hex-Darstellung auf dem Mainframe „F3D7“).
Wie soll nun ein Programm zur Zeichensatz-Umwandlung wissen, dass das Zeichen ab der 89. Stelle die Zahl „-37“ ist, und nicht ein Zeichen, das umzuwandeln ist?

Wenn in dem Flatformat nun keine binären Zahlen, sondern nur druckbare Zeichen gespeichert werden, ist die Gefahr gebannt. Wenn auf der COBOL Seite die Zahl als „PIC SZZ9 Sign is Leading Separator“ definiert wird und auf der anderen Rechnern auch mit druckbaren Zeichen für Zahlen gearbeitet wird, können die Systemprogramm zum Datentransfer einfach genutzt werden.

Ein XML

<kunde>
<nummer>4711<nummer>
<vormane>Hans</vorname>
<name>Testmann</name>
<telefon>
<lfdNr>1</lfdNr>
<telefonnummer>555-123-456</telefonnummer>
</telefon>
<telefon>
<lfdNr>2</lfdNr>
<telefonnummer>555-234-567</telefonnummer>
</telefon>
</kunde>

ist sehr gut lesbar, meist sieht das XML aber so aus:
<kunde><nummer>4711<nummer><vormane>Hans</vorname><name>Tstmann</name><telefon><lfdNr>1</lfdNr><telefonnummer>555-123-456</telefonnummer></telefon><telefon><lfdNr>2</lfdNr><telefonnummer>555-234-567</telefonnummer></telefon></kunde>

Der Inhalt kann auch als Flatformat: Satzart, Key, Satzdetail gespeichert werden, 

kunde 004711Hans Testmann
telefon00471101555-123-456
telefon00471102555-234-567

Für einen Computer ist das Parsen dieses Formats wesentlich einfacher und verbraucht deutlich weniger Zeit.

Es ist übrigens ein Leichtes, in Java eine Daten-Klasse zu erstellen, die XML, Festformate, CSV und auch JSON (die Methode, mit der in JavaScript Daten beschrieben werden) lesen und schreiben kann.
Auch die Bereitstellung als JDBC ResultSet oder SQL Insert / Update / Delete / Select ist recht einfach machbar.
Ob man für die Beschreibung der Inhalte eher Meta-Klasse nutzt, oder aus einer UML oder sonstigen Beschreibung die Klasse generiert, ist den Umständen im Projekt geschuldet und keine strategische Entscheidung.

Kategorien
Themen

64 Bit ist der Tod von Unix

Nun ja, die Überschrift ist etwas provokant. Aber etwas ist schon dran.

Bei Unix und den meisten heutigen Betriebssystemen ist alles ein File.

Ein File ist ein Konstrukt, damit mehr Daten gespeichert werden können wie die CPU in ihrem Adressraum ansprechen kann.

Erinnern wir uns an die 16 Bit Systeme (CP/M), 20 Bit Systeme (MS-DOS), 24 Bit Systeme (OS/2 1.x, MVS), 31 Bit Systeme (OS/2, OS/390, beide übrigens 31 Bit, weil so 24 Bit Lademodule ohne erneute Übersetzung zusammen mit 31 Bit Modulen verwendet werden konnten), 32 Bit Systeme (Windows NT, die meisten älteren Unix Versionen), so reichte der Adressraum nicht, um einen üblichen „Hintergrundspeicher“, also eine Floppy oder eine Harddisk, komplett adressieren zu können.

Also baute man ein File-System mit 512 Byte Sektoren (es gibt auch Festplatten mit 4kb Sektoren), diese werden meist zu vier oder zu einer höheren Zweierpotenz zu einem Block gruppiert, und das Betriebssystem lädt den Inhalt eines Blocks in den Hauptspeicher (RAM) oder sichert einen Block auf der Festplatte.

Als die meisten von Uns von 16 Bit (Windows 95) auf 32 Bit (Windows XP) umsteigen, waren die Festplatten schon deutlich über 4 GB gross, also zu gross für einen 32 Bit Adressraum.

Nun haben wir 64 Bit, klingt im Vergleich zu 32 Bit nicht wesentlich mehr, also statt 2 Kisten Bier nun 4 Kisten Bier? Aber bei einem Adressraum meinen wir 2 hoch 32 oder 2 hoch 64.

Was ist nun 2 hoch 64, eine lange Zahl!

Rechnen wir mal anders: Ein 64 Bit Computer läuft ohne Unterbrechung 5 Jahre und soll nur Daten, die über eine Schnittstelle (Ethernet) angeliefert werden, in seinem Adressrum speichern.

5 Jahre sind 5 * 365,25 * 24 * 60 * 60, also 157.788.000, also 2 hoch 27,23 Sekunde. 
Um es einfach zu haben, sagen wir 2 hoch 28 Sekunden.
Um 2 hoch 64 Bytes in 2 hoch 28 Sekunden zu schreiben, müssen pro Sekunde 2 hoch (64 – 28), also 2 hoch 36 Bytes geliefert werden, also etwa 69 GB pro Sekunde, Also muss die Ethernet Schnittstelle 690 Gbits/sec liefern. Pro Byte (8 Bit) müssen 10 Bits inklusive der Steuerungs- und Kontroll-Bits über die Leistung gehen.

Sie werden jetzt sagen: 
5 Jahre hält kein Computer ohne Störung, richtig. 
690 GBit/sec ist kaum zu schaffen, richtig.
Und was nützen uns die Daten nach 5 Jahren, wir wollen sie lesen und verarbeiten, sehr richtig.

Beim Programmieren sollte man die Variablen immer auf Word-Grenzen beginnen lassen. Ansonsten verdoppeln sich die Zugriffszeiten. Beginnt die Variable mit dem Inhalt „Hallo“ auf einer Wortgrenze, reicht ein Zugriff, liegt sie aber ab dem 5 Byte im 64 Bit Word, muss zuerst der Word 1 „####Hall“ gelesen werden, der Inhalt zu „Hall____“ geschoben werden, das Word 2 „o#######“ gelesen und das „o“ kopiert werden. Also sollte die Adressierung nicht pro Byte sondern pro Wort (64 Bit, also 8 Bytes) erfolgen, der Adressraum sind also 2 hoch 64 Worte, und schon sind wir bei 5600 GBit/sec.  

Also reicht ein Adressraum von 64 Bits, wer mehr braucht, wird eher mehrere von einander unabhängige Computer nutzen.

Das Konstrukt „File“ brauchen wir nicht mehr, um Daten in den Adressraum der CPU ein- und auszulagern. Eine „Datei“ ist ein Stück Adressraum in ausreichender Grösse und das Betriebssystem hat den Namen (Verzeichniseintrag) mit der Startadresse verknüpft. Damit ist der Zugriff für ein Anwendungsprogramm, oder auch eine Datenbank, sehr einfach, Startadresse plus Position addieren und zugreifen.

Der Preis eines Speichermediums steigt mit der Zugriffsgeschwindigkeit, darum der L1-, L2-, L3-Cache, das RAM, die SSD Festplatte, die normale Festplatte und schliesslich das Bandlaufwerk. Und für die Verwaltung sorgt die MMU (Memory Management Unit), Intel hat sie mit dem 80386 eingeführt, bei den Betriebssystem, die noch auf 80286 liefen, war die Speicherverwaltung nicht nur wegen der Segmente ein Krampf. Linux entstand, also PCs mit 80386 bezahlbar wurden, nur eben waren die 32 Bit Adressraum nicht ausreichend um auf ein File-System zu verzichten.

Seit einigen Jahren haben wir 64 Bit CPUs mit eingebauter MMU, trotzdem plagen wir uns noch mit dem File-IO, warum?

Kategorien
Themen

Datenbanken

Ich möchte jetzt nicht über Hierarchische Datenbanken, Netzwerk Datenbanken oder anderen Formen, mit denen ich während des Studiums vor 30 Jahren konfrontiert worden bin, schreiben.  

Manchmal hatte ich mit IBM IMS-DB, also einer Hierarchischen Datenbank, in Projekte zu tun, weil es noch eine Anwendung mit langer Historie gab, aber es war die Ausnahme.

Die „neuen“ NoSQL Datenbanken sind interessant, wenn man grosse Datenbestände eindampfen möchte, um in Realtime Auswertungen auf riesige Datenbestände fahren zu können. Das sind neue, interessante Anwendungen, aber eher Nischen. 

Jedes Unternehmen hat Buchhaltungs-, Kundenstamm-Daten und Kontobewegungen und das Finanzamt wird sich bei einer Betriebsprüfung nicht mit den „eingedampften“ Daten, sprich das Buchhaltungsjournal wurde zur die Bilanz verdichtet, zufrieden geben. 
 
Eine sehr gute Methode, die Daten physikalisch zu speichern, ist das Relationale Datenbank-Modell. 

Eine Datenbank ist etwas, was Transaktionen bereitstellt, also ACID. Weiterhin stellt eine Datenbank als Abfrage-Sprache (DML) und Definitions-Sprache (DDL) SQL zur Verfügung. Andere DML / DDL gab es, aber es hat sich SQL als Standard herausgebildet. 

MySQL wird meist mit der Storage-Engine MyISAM verwendet, insbesondere bei CMS oder ähnlichen Anwendungen steht das schnelle Lesen im Vordergrund, geschrieben wird hier wenig, deshalb ist ACID nicht wichtig. Falls ACID benötigt wird, gibt es andere Storage-Engines (InnoDB).

Vor 25 Jahren gab es einige kommerzielle Relationale Datenbanksysteme (ADABAS, SyBase, Informix, SESAM, …). Viele dieser DBMS sind heute noch verfügbar, wurden bei meinen Kunden in den letzten Jahren aber nur selten bei neuen Projekten verwendet.

Heute gibt es einige OpenSource DBMS. An erste Stelle ist MySQL zu nennen. Hiervon gibt es einige „Abspaltungen“, nach dem Oracle MySQL beim Kauf von SUN übernommen hatte. Andere bekannte OpenSource DBMS sind PostGre oder Derby. 

Es gibt auch einige sehr kompakte OpenSource Datenbanken, zum Beispiel SQLite. Mein TV-SAT Receiver verwendet diese Datenbank, ob mit SQLite sinnvoll ein Mehrbenutzer-Warenwirtschaftssystem zu betreiben ist?

In der Microsoft Welt ist der MS SQL-Server von Bedeutung, MS-Access ist eher eine Desktop Datenbank.

Im kommerziellen Umfeld unter den Betriebssystemen Linux, Unix und auch z/OS sind primär zwei DBMS zu finden, Oracle und IBM DB2. Mit diesen beiden Systemen arbeite ich seit über 20 Jahren, da die meisten meiner Kunden auch IBM z/OS einsetzen, mit Schwerpunkt IBM DB2.

Bei der Sprache SQL gibt es einen ANSI-Standard. In der Regel wird in der Anwendungsentwicklung hiervon auch nur ein Subset genutzt. 

Ich nutze SQL recht intensiv, DML Statements mit mehreren hundert Zeilen, Common Table Expressions, Scalar Funktionen, Expressions, Outer Joins über einige Tabellen, … Aber ich habe keine Schalter „DB2 / Oracle“ im Kopf, in den letzten Jahren sind mir keine Unterschiede zwischen Oracle und DB2 SQL aufgefallen. Sicher, früher gab es den sehr alten Oracle Syntax für Outer Joins (das „+“), aber Oracle hat sich den ANSI-SQL angepasst, und IBM hat vieles der Oracle DML in seine Datenbank eingebaut.

Vor einige Jahren meinte ein Entwickler bei einem Gespräch, dass es doch einen Unterschied zwischen DB2 und Oracle gibt. Er war gerade dabei, eine COBOL Anwendung von z/OS, IBM COBOL und DB2 auf Linux, MicroFocus COBOL und Oracle zu portieren. Beim Format der Timestamps in COBOL gibt es einen Unterschied. 
Bei der alten Version auf dem Mainframe mit DB2 steht , bei der neuen Version mit Oracle aber “2015-03-15 16:04:05.123“. 
Dabei störte ihn wohl nicht die letzten 3 Stellen. Wenn die Datenbank über 1000 Transaktionen pro Sekunde schafft und der Timestamp weiterhin eindeutig bleiben soll, sind die zusätzlichen Stellen notwendig.
Arbeit machte das Leerzeichen statt des Bindestrichs zwischen Tag und Stunde und vor allem die Doppelpunkte statt dem Punkt zwischen Stunde, Minute und Sekunde.
Das Problem wäre auch aufgetreten, wenn er statt einer Oracle Datenbank eine IBM DB2 (egal of z/OS oder Unix) genommen hätte.
Der Grund ist der ODBC-Treiber, den MicroFocus wohl nutzt. Die Umsetzung des SQL Datentype Timestamp ist bei ODBC etwas anders definiert.
Greift man per JDBC, also der Java-Variante von ODBC, auf eine Orcale oder DB2 Datenbank zu, kommen die Timestamps wie erwartet im ODBC Format, also die Version mit den Doppelpunkten, greift man per SPUFI (also z/OS 3270 Terminal) auf die gleiche DB2 Datenbank zu, sieht man die Punkte.

Welche der beiden Datenbank genutzt wird, ist sicher abhängig von der Plattform und den Lizenzkosten. Aber aus der Sicht eines Entwicklers sind die SQL Statements kompatible. 

Es gibt sicher Möglichkeiten in DB2 und vor allem Oracle, die sich so nicht bei dem anderen DBMS nutzen lassen, aber dazu muss sich der Entwickler anstrengen und er sollte dafür gute Gründe haben.

Kategorien
Themen

Benutzerinterface, wie geht das?

In den letzten 30 Jahren bin ich wohl „jeder Sau, die durchs Dorf getrieben wird“ auch hinterher gelaufen. 

Angefangen vom eigenen Zeileneditor in Basic, den Masken von dBase, die nach meinen Bedürfnissen geänderte Maskenverwaltung von Clipper / xBase, den „SAA Tools für C“, der auch nach meinen Erfordernissen angepassten Fensteroberfläche von Microsoft VisualBasic for DOS, dem GUI von Windows in den verschiedenen Versionen, zwischendrin dem von OS/2, diversen Fensterverwaltungen unter X-Window, MVC, AWT, Swing „native“, Swing mit den Frameworks meiner verschiedenen Kunden, SWT, GWT und HTML habe ich auf dem PC wohl alles mitgemacht, was so kam und vielfach auch wieder ging.

Bei FAT-Clients und auch bei Clients, die „nur“ die Masken fest kodiert haben, entsteht ein sehr grosser Verteilungsaufwand. Mal eben schnell eine Maske ändern dauert 5 Minuten, das Verteilen, insbesondere mit den Vorbereitungen, eher 6 bis 8 Wochen.

Auf dem Grossrechner habe ich ISPF Masken in COBOL von Hand programmiert (war an der Hochschule) und verschiedene Tools und Generatoren genutzt, je nach dem, was der Kunde einsetzte.

Wirklich brauchbar war unter Siemens BS2000 das Benutzer-Interface von Siline-200, auf einem 9750 Terminal wurde lokal editiert, der DÜ-Taste die komplette Maske an den Rechner übertragen, dort sah der Entwickler die Daten in einer Struktur (Copystrecke), verarbeitete sie komplett, füllte die Struktur für die Folge-Maske und fertig.

GUIs, wenn sie heute neu konzipiert werden, nutzen HTML5. Die ersten HTML Masken waren nicht besonders sexy, mittlerweile ist die Benutzerinteraktion dank AJAX genauso gut wie bei Masken mit Swing oder SWT.

Ich sehe aber HTML kritisch.
Zum einen wird ein WebServer benötigt, also eine zustandsbehafteter Server, den sich viele Benutzer teilen und dessen Ausfall weite Kreise zieht. Also werden mehrere WebServer eingesetzt, die den jeweiligen Session-Zustand auf einen zentralen Speicher hinterlegen, damit beim nächsten Aufruf der Session der jetzt an der Reihe stehende Server den Session-Zustand einlesen kann.

Benutzer arbeiten nicht immer durch, es gibt Kundenanrufe, Kollegen, die Hilfe brauchen, die Mittagspause, … Der Zustand einer begonnenen Session muss vom WebServer verwaltet werden, und die vielen „toten“ Sessions belasten den Server. Die „toten“ Sessions werden nach einer Weile „entsorgt“, meist eine Sekunde, bevor der Anwender wieder mit der Anwendung arbeitet. 

HTML nutzt http bzw. https als Transportprotokoll. Der Vorteil, die entsprechenden Ports sind in jeder Firewall offen, man muss keinen Antrag bei den Server-Administratoren stellen. Der Nachteil, die entsprechenden Ports sind offen. Bildlich gesprochen, wenn unsere Anwendung ein grosse Veranstaltung wäre und unsere Daten sind die VIPs, müssen sie zusammen mit der Masse der Besucher durch den Haupteingang, damit kein Antrag für die Benutzung des Nebeneingangs gestellt werden muss. Die Sicherheitskäfte der VIPs sind nicht gerade begeistert.

Für die Darstellung der Maske und der Benutzerinteraktion werden Standard-Tools, die WebBrowser, genutzt, dieses klingt erst einmal gut. Mittlerweile sind die WebBrowser weitgehend normiert, so dass die früher üblichen Browser-Weichen nur noch im geringen Mass benötigt werden.
Aber die Browser „gehören“ nicht uns, sondern Microsoft, Mozilla, Apple (Webkit) und Google (Chrome wurde auf Basis von WebKit entwickelt, vor einiger Zeit wollte Google aber die Kontrolle über seinen Fork von Webkit).
Browser werden auch in unsicheren Bereichen des Internets eingesetzt, ein Klick auf einem Links in der Email oder den Suchergebnissen von Google oder Bing, und schon strömt schädlicher Code auf den eigenen Rechner. Dann muss der Browser den Angriff abwehren. 
Viele nützliche Eigenschaften des Browsers, die wir für die bessere Benutzerinteraktion verwenden, können auch von den „bösen Jungs“ etwas anders eingesetzt werden, und dann wird der Browser Hersteller die Lücke schliessen, gut so, aber unsere Anwendung läuft nicht mehr.

In HTML ist ein Literal oder ein Eingabefeld ein Literal oder ein Eingabefeld, weitere Zusammenhänge lassen sich zwar über „div“ / „span“ nachbilden, aber nicht in der Detailtiefe, die manchmal notwendig ist. Solange der Browser ausreichend Platz zum Rendern hat, kein Problem, auf einer mobilen Plattform werden die Inhalte zwar dargestellt, aber nicht in der Optik, die ein sinnvolles Arbeiten ermöglicht.

Statt eines WebBrowser sollte ein Generischer Client eingesetzt werden.
Das ist ein Stück Software, das von Unternehmen selber zusammengestellt und gewartet, also kontrolliert wird.
Die Anbindung an der Server kann deshalb entsprechend der Erfordernisse erfolgen, also statt eines http / https mit Load Balancers, Firewall und verschiedenen WebServern wird ein Messaging Server, also ein Asynchroner Transaktionsmonitor direkt vom Client angesprochen. 
Der verwendete Port und die Verschlüsselung  können selber festgelegt werden und damit wird es einem Angreifer erschwert, einzubrechen. 
Die Transaktionsmonitore sind für eine hohe Performance und Verfügbarkeit ausgelegt, sie sind auch die Grundlage für die bekannten kommerziellen Application Server nach J2EE.
Lesende Zugriff (auf unkritische Daten) kann der Client auch direkt auf einer Datenbank durchführen.

Der Generische Client verwaltet seine Session, die Server sind also zustandslos. Falls ein Server ausfällt, kann ein anderer einfach weiterarbeiten. Bricht die Session ab, weil der Computer des Benutzers ein Problem hat, ist nur dieser Benutzer betroffen. Den Server ist die Anzahl der Benutzer egal, es geht nur um Anfrage pro Zeiteinheit. Ob die Anfrage von einem Benutzer oder einem anderen Server-Prozess kommt, bemerkt der Server nicht, es ist für ihn transparent.

Der Generische Client enthält keinen anwendungsspezifischen Code. 

Er ist auch mit einem Auto-Update ausgestattet, regelmässig (täglich) fragt diese Basis-Komponente beim Server nach, ob es eine verbesserte Version gibt, lädt und installierte diese bei Bedarf.

Beim Start wird der Client vom Server mit der „Start-Maske“ versorgt, diese wird dargestellt. 

Nach einer Aktion des Benutzers sendet der Client die Anfrage (XML) an den Server, dieser antwortet mit einer Nachricht (z.B. in XML). 

Im Kopf der Nachricht ist der Name und die Version der jetzt benötigten Maske enthalten, der Client schaut in seinen Cache, ob die Maske dort schon vorhanden ist, falls nicht, wird sie beim Server angefordert.

Die Maske ist auch eine XML-Anwendung, ähnlich XHTML.

Einige Felder werden Auswahl-Felder (Drop-Down) sein, zu denen ein Wertebereich (Geschlecht, Mehrwertsteuer-Schlüssel, Kundensystematik, …), definiert ist. Diese Wertbereiche hat der Client auch unter einem Namen und einer Versionsnummer in seinem Cache gespeichert, beim Laden der Maske wird die Version mit der auf den Server abgeglichen und bei Bedarf ein Update angefordert.

Die Maske sind „Eingabe-Gruppen“, sie bestehen aus Literalen, Eingabe-Feldern und weiteren Eingabe-Gruppen. Diese sind logisch gruppiert sind, also nicht nach Zeile/Spalte.

Eingabe-Felder können eine Picture-Klausel, ähnlich wie in dBase, enthalten. Hierüber kann auch die Bildschirmtastatur auf einem Touch-Screen gesteuert werden.

Jeder Eingabe-Gruppe und jedes Eingabe-Feld hat für die Events (Init, Repaint, Get Focus, Edit, Lost Focus, Destroy, …) ein Standard-Verhalten, das über in der Maske hinterlegten Code (JavaScript) überschrieben werden kann. 

Das Verhalten bei „Lost Focus“ kann zur Überprüfung der Benutzereingaben genutzt werden, z.B. kein Geburtsdatum in der Zukunft (Feld-Ebene) oder kein Vertragsbeginn vor der Volljährigkeit (Gruppe, Vergleich Vertragsdatum > Geburtsdatum plus 18 Jahre). Die Methode, die das Standardverhalten überschreibt, kann natürlich auch zuerst das Standardverhalten abfragen, um z.B. vorher den 29.02.2015 als Fehleingabe zu erkennen.

Der Anwender sieht den Arbeitsbereich, dort werden die Eingabe-Gruppen angezeigt und zwei Buttons „Abbrechen“ und „Speichern“. Es kann auch das Button-Paar „Beenden“ und „Ändern“ vorgeschaltet werden.

Falls notwendig kann auch eine Druck-Funktion über einen Button aufgerufen werden. Das Layout des Ausdrucks kann vom Layout auf dem Bildschirm abweichen und als Ausgabemedium bietet sich PDF an. 

Der Arbeitsbereich kann in Tabs / Reitern unterteilt werden, dieses ist auf dem Desktop sinnvoll, auf einem mobilen Geräte geht die Übersichtlichkeit verloren.

Auf dem Desktop kann im Generischen Client auch mehrere Sessions angezeigt werden, bei einem 4 Zoll Bildschirm sollte auch hier die Bedienbarkeit geprüft werden.

Der Generische Client muss verschiedene Feldtypen anzeigen können.
Wenn das CAD-Programm weiterhin genutzt wird, braucht sicher nicht dessen Bildschirm in eine Eingabemaske gesteckt werden. 
Interaktive Charts (z.B. Wertpapierkurs-Verläufe) können sinnvoll sein, die Bedienelemente sollten aber noch bedienbar sein. 
Normale Bilder sind recht einfach zu platzieren, hier sollte eine Maximalgrösse in Bezug auf die zur Verfügung stehende Fläche angegeben werden.

Bei den Eingabefeldern für Tastatureingaben sind in zwei Gruppen einzuteilen, einzeilige und mehrzeilige Felder.

Mehrzeilige Felder sind eher die Ausnahme, hier können Notizen und vielleicht Briefe erfasst werden. Deshalb sollten neben einer reinen Text-Version auch eine Version für formatierte Texte vorhanden sein. Für die Formatierung bietet sich HTML an, es ist aber auch RTF denkbar. Spezielle  Formate, z.B. Microsoft Word, sollten nur genutzt werden, wenn es auf allen Platzformen, die auch in ferner Zukunft genutzt werden könnten, zur Verfügung steht.

Bei den einzeiligen Eingabefeldern gibt es Texte, Zahlen mit oder ohne Komma, Datums- und Uhrzeit-Felder, Auswahl-Felder (Drop Down), Boolsche Werte (Radio-Buttons).

Die Anordnung der Eingabe-Gruppen, Literale und Eingabe-Felder sollte nach einfachen Regeln für die jeweilige Plattform erfolgen. Eine Regel, die auf dem Desktop, zum Beispiel Windows, OSX oder Linux, sehr gut ist, kann auf einer mobilen Plattform, Windows, iOS oder Android nicht sinnvoll sein. Beim Layout ist die Bildschirmgrösse wichtig, aber der Eingabe aber auch die Eingabemethode, also Tastatur / Maus gegenüber Touch-Screen.

Bei Auswahlfeldern und Boolschen Werten können je nach Plattform verschiedene Darstellungen und Eingabeverfahren sinnvoll sein. Hier sollte der Designer des Generischen Clients für eine Plattform eine Entscheidung treffen, der Entwickler, der die Maske (also für alle Plattformen) erstellt, sollte sich dessen bewusst sein.

Die Umsetzung des Generischen Clients ist eine sehr überschaubare Aufgabe, wenn nicht die Notwendigkeit der Verfügbarkeit des Know-Hows über eine längere Zeit wäre, könnte es ein Werkstudent umsetzen.

Kategorien
Themen

Der Weg weg vom Mainframe

In vielen Unternehmen gibt es eine über viele Jahrzehnte entstandene Anwendungs-Landschaft. Viele Kernbereiche wurden zu einer Zeit entwickelt, als nur ein Mainframe die notwendige Leistung und Sicherheit lieferte.

Die Mainframe Anwendungen laufen seit Jahrzehnten stabil, aber die Anzahl der Spezialisten, die den Betrieb und die notwendigen Anpassungen benötigt werden, nimmt ab.

Also ist eine Umstellung auf Techniken, die heute an Hochschulen vermittelt werden, mittelfristig zu planen.

Vielfach wurde versucht, einen Unix Server zu kaufen, darauf eine Oracle Datenbank zu betrieben und in einem BigBang die gesamte Anwendungs-Landschaft umzustellen. Die meisten dieser Versuche führten zum Weiterbetrieb des Mainframes auf unbestimmte Zeit.

Die Begründung ist einfach, die Business Analysten, die vor 30 Jahren die fachlichen Konzepte für die Mainframe Anwendungen erstellt haben, sind schon lange in Rente. Die fachlichen Änderungen, die seitdem umzusetzen waren, sind nicht vollständig dokumentiert. Ein aktuelles Fachkonzept für das gesamte Anwendungssystem, das für die komplette Neuimplementierung benötigt würde, existiert also nicht.

In der Zeit, in der dieses Fachkonzept durch Analyse der alten Programm Sourcen und intensiven Gesprächen mit dem jeweils zuständigen Fachbereichen entsteht, ergeben sich neue gesetzliche Anforderungen oder die alten Programme müssen an geänderte betrieblichen Anforderungen angepasst werden.

Es ist also unmöglich, den fachlichen Ist-Zustand der Anwendungs-Landschaft zu beschreiben und anschliessend in der neuen Technik umzusetzen, zu testen und in Betrieb zu nehmen.

Für Teilbereiche, die innerhalb einiger Wochen zu analysieren, umzusetzen, zu testen und in Betrieb zu nehmen sind, wäre es möglich. Aber dazu muss die neue Technik auf die Datenquellen des Mainframe zugreifen können, oder der Mainframe muss auf die neue Datenbank zugreifen.

Auch wenn es in der neuen Java Welt die beste Middleware als Open Source gibt, wenn von der alten Welt darauf nicht zugreifen werden kann, eine Umstellung würde den nicht durchführbaren Big-Bang bedeuten.

Aber aus der Java Welt kann man die Middleware, die der Mainframe beherrscht, nutzen.

Middleware sind zum einen die Datenbank und zum anderen ein asynchroner Transaktionsmonitor, also für einem IBM Mainframe IBM DB2 und IBM MQS.

Beides kostet Geld, ja viel Geld. Dieses Geld wird aber schon seit Jahren ausgegeben, und der Betrag ändert sich nicht (oder kaum), wenn statt eines COBOL Programmes ein Java Programm die Datenbankoperation auslöst.

Viele Entwickler in der Java Welt meinen, eine DB2 ist keine „Oracle Datenbank“, es gibt nichts besseres und sicheres als Oracle.

Dass die Backend Systeme der grossen Banken und Bank-Organisationen nutzen DB2, wird leider auch im Informatikstudium nicht vermittelt.

Weiterhin sind viele Java Entwickler der Meinung, dass DB2 ja kaum genutzt wird (siehe „2 Takt Diesel“, davon gibt auch nur wenige, aber 70% des Welthandels werden damit abgewickelt, denn sie treiben die Hochseeschiffe an) und das SQL von DB2 läuft nicht auf Oracle.

Beide können ANSI-SQL und fast alle Erweiterungen sind kompatible.

Wobei, alles, was über den ANSI Standard hinausgeht, sollte gut begründet sein. Es gibt ja auch andere Datenbanksysteme, die weit weniger kosten, und auf die später umgestiegen werden könnte.

Und ein IBM MQS kann von Java auch als JMS angesprochen werden. IBM WebSphere, also der Java Applicatioin Server von IBM, hat als technische Basis auch MQS, deshalb hat IBM das Produkt zu „WebSphere MQ“ umbenannt.

Sollten doch später eine Middleware um Einsatz kommen, die nicht Syntax-kompatible ist, sind die Zugriffe auf die Middleware so zu kapseln, dass später nur einige wenige Module schnell angepasst werden müssen.

Es gibt auch Vorgehensweisen, bei denen Java auf vorhandene Mainframe Module zugreifen kann, aber unser Ziel ist es ja, die Mainframe Technik abzulösen.

Also, von der Java Seite ist alles technisch möglich, nur muss auch auf der Mainframe Seite administrativ die Zugriffe zugelassen werden.

Und es gibt noch ein weiteres Problem, den Mainframe gibt es seit über 50 Jahren, DB2 erst seit knapp 40 Jahren und MQS gute 20 Jahre.

Es gibt also Technik, die heute noch genutzt wird, die älter ist.

Ein Beispiel ist IMS DB, eine hierarchische Datenbank. Hier ist die Zugriffslogik und damit auch die Transaktionslogik anders. Am besten stellt man sich IMS DB als eine Art XML oder ein daraus abgeleitetes DOM vor. Es gibt eine Kunden, zu diesem Kunden gehört ein Konto. Wechselt dieses Konto den Inhaber, wird nicht die Rollentabelle geändert, sondern das Konto wird innerhalb einer Transaktion bei alten Inhaber physikalisch gelöscht und beim neuen Inhaber eingefügt, also umgehängt.

Hier macht es Sinn, noch auf dem Mainframe die Zugriffsmodule und vor allem die Zugriffslogik auf das Relationale Modell, also DB2, umzustellen.

Eine andere Technik zum Speichern ist VSAM. Dieses ist ein Index Sequentielle transaktionsorientierte Systemdienst. Diese Basis nutzt auch DB2 auf dem Mainframe. Die Zugriffslogik ist identisch, es ist also einfach möglich, bestehende VSAM Zugriffsmodule auf DB2 umzustellen. Es ist zu prüfen, ob ggf. durch den zusätzlichen DB2 Workload Lizenzkosten entstehen.

Eine „normale“ Sequentielle Datei gibt es auch in Java, diese anzusprechen ist einfach.

Aber hier gibt es vielleicht ein Problem bei Zahlen. Auf dem Mainframe werden gerne BCD Zahlen (COMP-3) genutzt. Hier wird jede Ziffer in einem Halb-Byte (4 Bit) gespeichert und das letzte Halb-Byte ist das Vorzeichen.

Binärzahlen, also Integer oder Long sind auf dem Mainframe eher unüblich, bereiten aber auch Probleme.

Weiterhin gibt die Zahlen, bei denen jede Ziffer in einem Byte gespeichert wird. Ist die Zahl vorzeichenbehaftet, wird das Minus-Zeichen im vorletzten Halb-Byte gespeichert.
Schickt man solche Zahlenwerte durch eine Zeichensatz-Umwandlung, entsteht Chaos. Also zuerst alle numerischen Variablen auf dem Mainframe als druckbare Zeichen definieren, bei denen das Vorzeichen der führende Trenner ist, also “ -123.45″.

Gerne wird auch in einem ersten Schritt versucht, die bisherigen COBOL Sourcen auf einen Unix Rechner laufen zu lassen. Es gibt einen Hersteller, der eine entsprechende Umgebung seit Jahrzehnten bereitstellt. Ob es sinnvoll ist, eine Anwendung auf eine andere Plattform zu portieren, hierbei aber auch in Zukunft auf die alten Knowhow Träger angewiesen zu sein, ist zu hinterfragen. Und es lauern noch einige Fallstricke, sei es nur der andere Zeichensatz, so dass auf einmal „A > 1“ wahr ist (EBCDIC versus ASCII) oder das Format eines Timestamp Strings.

Die Umstellung erfordert also mehrere Schritte und sollte die komplette Ablösung zum Ziel haben.

Im ersten Schritt ist technisch zu analysieren, wo noch „Vor DB2 Technik“, also IMS DB, VSAM oder anderen Nicht DB2 Datenhaltung genutzt wird.

Diese Anwendungen sind dann umzustellen, entweder weiterhin als Mainframe Anwendung, die jetzt DB2 nutzt, oder falls möglich und sinnvoll, gleich als Java Anwendung.

Im zweiten Schritt, möglichst zeitgleich mit dem ersten Schritt, sind auf dem Host alle Schnittstellen, insbesondere die Zwischendateien, zu prüfen. Alle binär kodierten Inhalte (COMP-3 Zahlen und ähnliches) sind auf druckbare Zeichen umzustellen.

Jetzt können die weiteren Schritte geplant werden. Einzelne Anwendungen, ja sogar einzelne Module können umgestellt werden.

Die noch 3270 Terminals nutzenden Dialoganwendungen sind sicher ein guter Anfang.

Sollte in den Präsentation Modulen, die die Bildschirmsteuerung durchführen, auch Fachlogik enthalten sein, ist diese natürlich zuerst auszulagern, sprich statt eines „PERFORM“ wird ein „CALL“ durchgeführt.

Die Fachlogik der Anwendungen kann noch auf dem Mainframe liegen. Hier ist eine Kapsel über MQS zu erstellen. Statt des „CALL“ aus dem COBOL Programm wird vom Java Programm eine MQS Message mit Namen und Schnittstellen-Parameter gesendet, die auf dem Host empfangen wird. Das zentrale Modul erkennt am Namen, welchen Call es durchzuführen hat, ruft das Fachmodul auf und sendet das Ergebnis per MQS zurück.

Häufig werden die Schnittstellen Parameter in XML (SOAP) verpackt oder es wird eine REST Schnittstelle genutzt. Die Umwandung ist jedoch aufwendig, insbesondere auf dem Mainframe. Besser ist es, dem Mainframe als Parameter einen String mit einer festen Länge zu senden. Wie in Java ein String aus verschiedenen Parametern aufzubauen und später wieder zu zerlegen ist, weiss jeder Programmierer, hierfür gibt es String.format(). Auf dem Mainframe gibt es eine entsprechende Copystrecke. Ein Tool, das auf Basis einer COBOL Copystrecke die passende Java Formatanweisung, auf Basis einer Java Formatanweisung eine COBOL Copystrecke oder auf Basis einer fachlichen Schnittstellenbeschreibung beides erzeugt, ist für einen erfahrenen Programmierer eine Fingerübung.

Im Zweifel sollte eine aktuell genutzte fachliche Logik nur an einer Stelle, sprich in einer Sprache, implementiert werden. Wenn also alle Dialog Module auf Java umgestellt sind (jetzt kann auch der bisherige Transaktion Monitor CICS oder IMS DC auf dem Mainframe abgeschaltet werden), kann mit der Umstellung der Fachmodule von COBOL auf Java begonnen werden.

Neue Fachmodule, die nur von Java Anwendungen genutzt werden, wurden natürlich sofort in Java erstellt.

Jetzt bleibt nur noch das „Batch-Geschäft“. Also die Batch-Anwendungen, die meist nachts laufen und die grossen Datenmengen bearbeiten. Vielfach nutzen die Batch-Programme auch Fachmodule, die auch in Dialog Anwendungen genutzt werden, die per CALL aufgerufen werden.

Eine Umstellung auf Java ist leicht zu programmieren, aber die Anforderungen an die Performance sind schwer zu erfüllen. Das Problem ist nicht die Rechenleistung auf dem Java Application Server, sondern die Datenbankanbindung.

Auf dem Host schreibt DB2 seine Ergebnisse auf eine Speicherstelle, kurz gesagt einen Speicher Chip, und das COBOL Programm liest seine Daten genau von diesem Speicher Chip, verarbeitet die Daten und schreibt die Ergebnisse auf einen Speicher Chip, von dem anschließend DB2 die zu schreibenden Daten liest.

Bei einer JDBC Anbindung schreibt die Datenbank ihre Ergebnisse auf eine Speicherstelle, der serverseitige Teil der JDBC Verbindung liest die Daten, konvertiert eventuell den Zeichensatz, packt die Daten in einen „JDBC Umschlag“ und übergibt seinen Umschlag an den Netzwerktreiber im Betriebssystem, dieser packt den Umschlag in den „logischen Netzwerk Umschlag“ ein und übergibt seinen Umschlag an die Netzwerk Hardware. Dort werden dann Pakete gepackt und auf die Reise geschickt. Sicher gibt auf der Reise noch einige „Zollkontrollen“, sprich Firewalls, wo die Pakete ausgepackt und auf den zulässigen Inhalt geprüft werden. Auf dem Java Server angekommen, werden die Pakete auf Vollständigkeit geprüft. Dort werden die vollständigen Pakete, dann die Umschläge ausgepackt und endlich kann der JDBC Treiber die Daten empfangen und ausliefern.

Bei einer Dialoganwendung, wo viele Benutzer jeweils einen Datensatz aus der Datenbank holen, bearbeiten und wieder auf die Datenbank, fällt der im Hintergrund ablaufende Aufwand nicht auf, aber bei einem Batchprogramm, das Millionen von Datensätzen in kürzester Zeit lesen und schreiben muss, fällt der Aufwand durch eine deutlich längere Laufzeit auf.

Am Besten liegen der Datenbank und der Java Server im Netz dicht bei einander, also möglich nur wenige Router, Load Balancer und vor allem Firewalls dazwischen. Aber auch dieses kann eventuell nicht reichen, die geforderte Laufzeit zu erreichen.

Dann sollten der Netzwerk Verkehr vermindert werden. Hierbei kommt es nicht auf die Menge an Daten, also Kilobytes, sondern auf die Anzahl an Paketen an. Ein Pakete mit 1000 Bytes Daten dürfte im Vergleich zu 10 Paketen mit jeweils 10 Bytes Daten schneller übertragen werden.

Eine gute Idee die Verlagerung der Logik auf den Datenbank Server. Über Scalar Functions, Common Expression Tables und ähnlichen Dingen kann viel Logik direkt abgebildet werden und mittels eine Updates oder eines „Insert from Select“ vom Java Server auf dem Datenbank Server ausgelöst werden.

Stored Procedures sind eine weiter Möglichkeit, dieser Vorteil wird jedoch durch die Einführung einer weiteren Programmiersprache erkauft.

Ein weitere Weg ist, auf dem Datenbank Server (Teile) der Tabellen zu entladen, der FTP auf einen Anwendungsserver zu senden. Hier wird dann die Datei als sequentielle Datei verarbeitet, eine Ausgabedatei geschrieben, diese per FTP auf den Datenbank Server geschickt, in eine temporäre Tabelle geladen und schliesslich ersetzt der Inhalt der temporären Tabelle Teile der Datenbank Tabelle. Das Vorgehen ist sehr schnell, ein ähnliches Vorgehen habe ich mehrfach bei sehr grossen Migrationen auf dem Mainframe genutzt, aber der Ablauf ist sehr komplex und fehleranfällig, bedarf also eines genauen Tests und einer ständigen Überwachung.

Soll Logik auf dem Datenbank Server ausgeführt werden, ist sicherzustellen, dass auch ein für den späteren Einsatz geplante Datenbank diese Logik versteht.

Wie Sie sehen, ist die Umstellung nicht trivial, wird mehrere Jahre dauern und erfordert in der Anfangsphase viele Mainframe Spezialisten, wobei der Bedarf im Laufe der Umstellung abnimmt. Und es braucht Spezialisten, die die Mainframe und die Java Welt kennen, einerseits als Dolmetscher zwischen den Mainframe und den Java Spezialisten und auch als Übersetzer der Mainframe Logik auf die Java Logik.

Kategorien
Themen

COBOL modern

Ich habe COBOL noch zu Zeiten des ANSI-74 Standards kennengelernt, hier fehlten etliche Dinge, die eine moderne Programmiersprache auszeichnet. Aber seit gut 25 Jahren ist COBOL-85 verfügbar. Hier sind alle notwendigen Statements vorhanden, um gut strukturierte Programm zu erstellen, in einigen Bereichen ist COBOL sogar weiter wie andere Sprachen, das EVALUATE fehlt mir zum Beispiel in JAVA.

Die Verteufelung des Befehls GOTO kann ich nicht verstehen, auch wenn ich sehr gut ohne einen Sprungbefehl programmieren kann (ich habe lange Jahre in dBase, Clipper und xBase++ programmiert, dort gibt es keinen Sprungbefehl). Sicher war es zu der Zeit, wo die Kollegen, die mit COBOL-74 arbeiten mussten und hier mit dem GOTO Spaghetti Code schrieben, wichtig, den Gebrauch von GOTO in der alten Weise zu verhindern. Aber jede Anweisung innerhalb einer Section in ein 

IF KEIN-FEHLER

END-IF

zu setzen, oder extrem kleine Sections zu schneiden, verunstaltet die Programme und erschwert den Überblick über den Programmfluss. 

Der Einsatz des Befehls GOTO mit einem Sprungziel in der gleichen Section weiter unten ist sinnvoll. Das Werfen einer Exception in Java ist ja auch ein GOTO bis zu der Stelle, wo die Exception aufgefangen wird.

Der Aufbau einer Section nach folgendem Muster hat sich bewährt: 

MySection section.
Start.
Anweisungen

if Ein-Fehler-Ist-Aufgetreten goto FehlerVerarbeitung end-if

goto Ende.
FehlerVerarbeitung.

contiune.
Ende.
exit. 

Die Namen einer Paragraphen in jeder Section sollten identisch sein, also „Start.“, „FehlerVerarbeitung.“ und „Ende.“. Es macht das Kopieren von Programmzeilen einfacher und vor allem meldet der Compiler einer Fehler, wenn das Sprungziel nicht in der Section definiert ist, da er kann in den anderen Sections viele Paragraphen mit dem Namen finden.

Ein Kollege in einem Projekt umging das GOTO mit dem Befehl „NEXT SENTENCE“, also ein GOTO bis nach dem nächsten Punkt. Sofern eine Section nur zwei Paragraphen hat, der zweite Paragraph nur aus einen „EXIT.“ besteht und Punkte nur beim Paragraphen sowie den jeweils letzten Statement vorkommen, ist alles super. Ich hatte nach dem Ausscheiden des Kollegen aus dem Projekt seine Programme übernommen, wusste von seinem Vorgehen nichts und kopierte eine Abfolge von Statements aus einem anderen, älteren Programm in eine Section. In den älteren Programm (wohl in den 1980zigern entstanden) waren, die früher übliche, alle Statements mit einem Punkt beende. Bis ich das Problem erkannte, dauerte es etwas.

Der Punkt in COBOL ist wichtig, aber kann leicht übersehen werden. Am Ende der Section- oder Paragraphen-Definition muss ein Punkt stehen und dort sieht man ihn auch. Nach nach einem EXIT oder einem GOBACK steht ein Punkt. Ansonsten sollte der Punkt am Ende eines Paragraphen nicht am letzten Statement stehen, sondern in einer eigenen Zeile mit der „Blickfang“ „CONTINUE.“.

Vielfach werden in COBOL-Programmen nur Grossbuchstaben verwendet. Zu Zeiten von Lochkarten und vor allem Kettendruckern, die meist keine Kleinbuchstaben drucken konnten, hatten die Kollegen auch keine andere Möglichkeit. Eine Schreibweise mit COBOL-Statements in Kleinbuchstaben und Namen in „Camelback“ Schreibweise, z.B. 

move DerErsteWert to DerZweiteWert

hat sich in Projekten bewährt. 

Was ist auf den ersten Blick verständlicher?
move Humus to blumentopferde
oder
move Humus to BlumentoPferde
oder
move Humus to BlumenTopfErde

Insbesondere wenn Teile des Projektes in Java implementiert werden, sollten die Variablen die gleichen Namen haben und identisch geschrieben werden.

Über das Einrücken und seinen Sinn brauche ich wohl kein Wort zu verlieren. Leider gab es einige Kollegen, die den Sinn nicht erkannt hatten. Diese Programm in Form zu bringen ist zwar zuerst etwas Arbeit, die Zeit kostet. Aber im Anschluss gewinnt man bei der Wartung deutlich an Zeit.

Ein Problem von COBOL ist, dass es in einem Programm nur einen globalen Namensraum gibt. Hiermit kann man leben. Die Verwendung des COPY REPLACING beim Einbinden einer Copystrecke vereinfacht das Programmieren. Leider kennt der INCLUDE des SQL-Präprozessors kein REPLACING. Dann muss mit dem „IN“ oder „OF“ zum Qualifizieren gearbeitet werden. In Projekten hat sich die Verwendung von „IN“ für das Qualifizieren und die Verwendung von „OF“ für Adressen (Pointer) als gut herausgestellt.

Eine weitere Möglichkeit, Namensraume zu unterteilen sind Unterprogramme, die per CALL aufgerufen werden. Diese können als eigenständige Lademodule vorliegen, als Embedded Unterprogramme per Copy-Anweisung eingebunden werden oder direkt in das Programm geschrieben werden.

Als Befürworter des dynamischen Linkens sehe ich Vorteile bei der Verwendung von eigenständigen Lademodulen. Bei sehr zeitkritischen Anwendungen kann das Einbinden in die Source des Hauptprogramms Zeitvorteile bringen, die den Nachteil, dass bei einer Änderung ein einem Embedded Unterprogramm alle betroffenen Programme neu zu übersetzen sind, ausgleicht.

Kategorien
Themen

COBOL Entwickler

Sie benötigen einen COBOL Entwickler, welche Frage stellen sie zuerst:

„Was ist die Environment Division?“

Der Nicht-COBOL Entwickler weisst es nicht.

Der Anfänger kann Ihnen alle hier möglichen Statements aufzählen.

Der Profil sagt, dass er diese Division immer kopiert, und deshalb nicht weiss, was drin steht.

Kategorien
Themen

Denke einfach

Viele Entwickler, gerade im Bereich der neuen Techniken, sind neugierig und versuchen gerne etwas neues.

Das führt manchmal zu folgender Situation, die ich hier bildlich beschreiben möchte:

Es ist ein Bild an die Wand zu hängen.

Die erfahrenen Entwickler nehmen einen Hammer und schlagen einen Nagel in die Wand.

Einige Entwickler sind der Meinung: „Tunnelbohrmaschinen sind Open-Source“ oder „Wir haben eine Unternehmenslizenz für Tunnelbohrmaschinen“ sowie „Ich habe gelesen, wie man eine Tunnelbohrmaschine bedient“.

Nun sind einige Wände aus Beton, da kann man keinen Nagel einschlagen. Nun steigen einige weitere Entwickler auf die Tunnelbohrmaschine um.

Und einige, insbesondere Projektleiter, meinen „Da nehmen wir etwas Geld in die Hand und kaufen einen Luftdübel, den hat mir letzte Woche der Software-Anbieter XY empfohlen“. Der ‚Luftdübel‘ ist ein tolles Produkt, einfach den Luftdübel in die Luft stecken, Schraube rein drehen, kann bis zu 5 Tonnen belastet werden.

Der erfahrene Entwickler nimmt seine Schlagbohrmaschine, damit ist das Loch schnell in der Wand, einen käuflichen Dübel plus Schraube rein, und das Bild kann aufgehängt werden.

Frameworks, Bibliotheken und ähnliches müssen für viele Anwendungsfälle passen und sind häufig aus diesem Grund komplex im Aufbau und im Einsatz.
Meist setzen sie noch weitere Frameworks, Bibliotheken und ähnliches mit einer bestimmten Versionsnummer voraus.
Komplex wird es, wenn für die Problemlösung Funktionen aus zwei Bibliotheken zu nutzen sind, die aber jeweils von einer dritten Bibliothek eine jeweils unterschiedliche Version benötigen.
Kann man den Einsatz eines grossen Frameworks durch das Schreiben von hundert Zeilen Code vermeiden, ist die selbstgeschriebene, nur für den bestimmten Zweck gedachte einfache Lösung besser, insbesondere in der Wartung über den Lebenszyklus der Anwendung.

Kategorien
Themen

Künstliche Intelligenz und Algorithmen

In der aktuellen Diskussion werden der Begriff „KI“ für „Künstliche Intelligenz“, englische „AI“ für „Artificial intelligence“ und der Begriff Algorithmus vermischt.

Hierdurch entstehen nach meiner Meinung Gefahren bei der Diskussion und den Schlussfolgerungen.

Ein Algorithmus ist eine „Handlungsanweisung“. Diese Handlungsanweisung muss nicht in einem Computer ausgeführt werden, auch ein Kochrezept ist ein Algorithmus. Ebenso die Bauanleitung für ein IKEA Regal, das Zusammenbauen eines PKW auf einem Fliessband, …

Es gibt einfache Algorithmen. Schauen Sie einmal auf die Kochanleitung für eine Tütensuppen: „Inhalt in 750 ml lauwarmes Wasser einrühren, aufkochen, 5 Minuten bei geringer Wärme köcheln lassen.“

Es gibt komplexe Algorithmen. Die Suche einer Bahnverbindung gehört wohl dazu.Vor 40 Jahren suchte ein erfahrener Mensch, meist ein Bahn-Beamter, in dem Kurs-Buch (dicker Papier-Wälzer) die passende Verbindung heraus. Hierzu gab es Handlungsanweisungen, die der Beamte in seiner Ausbildung gelernt hatte. Heute wird dieser Algorithmus durch einen Computer durchgeführt, aber im Grundsatz ist es immer noch der gleiche Vorgang.

Es gibt sehr komplexe Algorithmen. Ein Beispiel ist das Optimieren von Datenbank-Abfragen. Bei grossen Datenbeständen kann eine nicht optimal formulierte Abfrage mehrere Stunden dauern. In den Datenbank-Programmen gibt es „Optimierer“, also Algorithmen, die eine Abfrage so umstellen, dass sie schnell ausgeführt werden kann. Zu den technischen Hintergründen sind viele dicke Bücher geschrieben worden, für deren Verständnis man eine immense Vorbildung braucht.

Menschen, die bei den Herstellern der Datenbanksystem beschäftigt sind, haben Algorithmen entwickelt, die die Abarbeitung der Abfrage optimal anordnen. Die Algorithmen merken sich auch ihre Erkenntnis, um sie bei Optimierungen ähnlicher Abfragen nutzen zu können.

Es gibt auch Algorithmen, die sehr kritisch betrachtet werden, die Scoring Algorithmen. Hier prüft ein Computer auf Basis des Namens, der Alters, der Wohnadresse, … ob ein Vertrag, ein Kredit oder eine Versicherung mit der Person ein zu grosses Risiko darstellt. Bis vor einigen Jahren wurde diese Tätigkeit von Menschen im „Back-Office“, also ohne direkten Kontakt zum Kunden, erledigt. Für einen Kredit für einen Neuwagen ist ein Arbeitsaufwand von einer halben Stunde sicher tragbar, was aber, wenn es bei einem Online-Händler um eine Kauf auf Rechnung für 10,- EUR geht? Letztlich arbeitet heute der Computer mit etwa dem gleichen Algorithmus wie der Sachbearbeiter im Back-Office vor 20 Jahren.

Was ist also ein Algorithmus?

Jemand definiert eine Handlungsanweisung und jemand oder etwas führt sie aus.

Definieren kann der Mitarbeiter der Tütensuppen-Firma, ein Mitarbeiter aus der Rechtsabteilung, ein Spezialist eines Datenbanksystem-Herstellers, aber auch ein Wal (ja, die im Meer schwimmenden Säugetiere).

Der Algorithmus, also die Handlungsanweisungen wird durch den Käufer der Tütensuppe, den Mitarbeiter im Back-Office, die Datenbank oder Jung-Walen bei der Heringsjagd ausgeführt.

Ich arbeite seit über 30 Jahren als „Algorithmus Entwickler“ für die Computer-Systeme bei grossen Unternehmen. Von Fachbereich-Spezialisten, z.B. aus der Vertragsverwaltung, bekomme ich eine Vorgabe, was der Algorithmus machen soll. Diese Vorgabe heisst Fach-Konzept. Ich erstelle dann ein technisches Konzept, dass ich mit Kollegen und auch den Fachbereich abstimme. Aus dem technischen Konzept wird dann der Computer-Algorithmus implementiert. Zuerst teste ich zusammen mit Kollegen aus der Computer-Abteilung die Implementierung. Dann wird das Programm von speziell ausgebildeten Testern auf Basis des Fach-Konzeptes geprüft. Bevor das Programm wirklich zum Einsatz kommt, prüfen die Mitarbeiter des Fachbereichs noch einmal das Programm auf „Herz und Nieren“.

Wichtig ist, viele Menschen, die auch ihre Ethischen Werte nicht vergessen, erstellen und prüfen den Algorithmus.

Nun kommen wir zur Künstlichen Intelligenz.

Eine Tochterfirma von Google forscht in diesem Bereich sehr intensiv.

Mitte 2017 erstellten sie eine KI auf Basis von Neuronalen Netzwerken, die sehr gut das Spiel GO (ein asiatisches Strategiespiel) beherrschte, und zwar so gut, dass kein anderer Computer und erst recht kein Mensch diese KI schlagen konnte.

Im Herbst 2017 kamen sie dann auf die Idee, die KI sollte Schach spielen.

Die KI wurde „zurückgesetzt“, vergass also alles zum Thema GO.

Nun wurden der KI die Schach-Regeln beigebracht, und zwar genau das, was man einem Kind erklärt, bevor man die erste Runde mit ihm spielt. Welche Figuren gibt es, wie können sie gezogen werden, alles bis hin zur Rochade, und nicht mehr!

Dann durfte die KI vier Stunden gegen sich selber spielen, dieses war die Lernphase.

Anschliessend spielte die KI gegen das besten Schach-Programm, also einen Algorithmus.

In diesem Algorithmus ist das Wissen der besten Schachspieler und Software-Entwickler in den letzten Jahrzehnten eingeflossen. Ein Mensch braucht gegen diesen Algorithmus nicht anzutreten, er verliert sowieso.

Nun spielten die KI und der Algorithmus 100 Partien, die KI gewann 22 Spiele, 78 waren remis, der Algorithmus gewann kein Spiel!

Die KI erreichte also in 4 Stunden Lernphase eine Spielstärke, die deutlich über einen Algorithmus mit mehreren Jahrzehnten Entwicklungsdauer lag.

Im Herbst 2018 wurden einige der Spiele veröffentlicht, ähnlich den Spielen um die Schach-Weltmeisterschaft bei Menschen.

Schachspieler analysierten die Spiele, eine überraschende Erkenntnis war: Die KI spielt nicht wie ein Computer, sondern eher wie ein Mensch!

Mit KI beschäftige ich mich seit meinem Studium mal mehr, mal weniger intensiv, beruflich erstelle ich ja Algorithmen.

Vor 30 Jahren gab es LISP, eine Programmiersprache, die für KI geeignet ist, PROLOG, eine deklarative Sprache für die „Zielsuche“ und Expertensysteme, letztlich Algorithmen, die komplexe Entscheidungen herleiten sollten. Aber alles hat wenige mit den heutigen KI Systemen zu tun.

Eine KI ist heute zumeist ein Neuronales Netzwerk. Ähnlich den Neuronen in unserem Gehirn verknüpfen sich die (vielen) Neuronen in dem Netzwerk untereinander. Nicht jedes Neuron mit allen anderen Neuronen, sondern jeweils ein Neuron nur mit einigen anderen Neuronen. Zwischen den Neuronen werden einfachste Nachrichten ausgetauscht. Hierbei kommt es weniger auf den Inhalt, sondern auf die Frequenz, also die Anzahl der Nachrichten pro Zeiteinheit, an. Ab einen Schwellwert an Nachrichten pro Zeiteinheit, die ein Neuron erhält, beginnt es Nachrichten an andere Neuronen zu senden. In der Lernphase lernt jedes Neuron, ab welchen Schwellwert es selber senden soll, und von welchen Neuronen es Nachrichten empfangen und an welche Neuronen es seine Nachrichten schicken soll. Und bei einem Neuronalen Netzwerk endet die Lernphase nicht, es kennt den Spruch „Das haben wir immer schon so gemacht“ nicht!

Einen sehr guten Artikel über die Arbeitsweise eines Neuronalen Netzwerkes las ich vor einigen Jahren in der Computerzeitschrift CT. Es ging um keinen Computer, sondern um einen Ameisenstaat. In einem Ameisenstaat suchen die Arbeiterinnen ausgehend vom Ameisenbau nach Futter. Auf ihrem Weg hinterläßt jede Ameise eine feine Duftspur, die sich aber mit der Zeit verflüchtig. Findet eine Ameise keine Futterstelle, sucht sie weiter und ihre Duftspur verfliegt. Wege zu ergiebigen Futterstellen werden von vielen Arbeiterinnen genutzt, deshalb ist hier die Duftspur besonders kräftig. Die anderen Arbeiterinnen folgen der stärksten Duftspur und finden so auf dem schnellsten Weg zur Futterstelle. Einige verlassen aber den Pfad zufällig (?) und finden vielleicht einen noch schnelleren Weg zu dieser Futterstelle, oder aber eine andere ergiebige Futterstelle. Damit wird diese Duftspur stärker, während die alte Duftspur immer schwächer wird.

An den Beispiel Ameisen-Duftspur erkennt man auch das Problem bei der Konstruktion von Neuronalen Netzwerken. Verfliegt die Duftspur zu schnell, gibt es Chaos wegen fehlender Informationen, verfliegt die Duftspur zu langsam, gibt es Chaos, weil zu viele unnütze Informationen vorliegen.

Beobachten Sie über längere Zeit das Treiben in der Umgebung eines Ameisenbaus. Sie kennen jetzt die Regeln, nach denen Ameisen die optimalen Wege zum Futter finden. Können Sie voraussagen, welche Wege in einer Stunde von den Ameisen genutzt werden?

Ein Neuronales Netzwerk und die Ameisen „lernen“ iterativ und evolutionär! Die Implementation eines Algorithmus ist ein einmaliger Vorgang. Vielleicht dient der Algorithmus als Vorlage bei der Entwicklung des nächsten Algorithmus, der Algorithmus ändert sich aber nicht. Sein Arsenal an Aktionen ist am Ende seiner Implementierung vollständig definiert und damit reproduzierbar testbar.

Während der vier Stunden Lernphase für Schach prüfte kein Mensch, wie die KI arbeitet. Wie sollten auch Menschen etwas prüfen, was besser ist wie der beste Algorithmus, den viele Experten in vielen Jahrzehnten entwickelt haben.

Damit entfällt auch der Mensch (oder der Wal) als Kontrollinstanz, die ethische Grundsätze hat.

Die Regeln, die die KI als Schranken hatten, also welche Figuren gibt es, wie dürfen sie gezogen werden und wie andere Figuren schlagen, waren ja so einfach und auch vollständig der KI beigebracht. Und das Verhalten der KI hatte ja keine Auswirkung auf die übrige Welt.

Facebook forscht auch im Bereich KI. Dort wollte man vor einiger Zeit wissen, wie sich zwei KI System mit einander unterhalten. Begonnen habe die beiden KI mit Englisch, aber sie entwickelten sich weiter und erfanden eine neue Sprache, Geheimsprache ist hier nach meiner Meinung der falsche Begriff. Da nun die Menschen der Kommunikation nicht mehr folgen konnten, wurde das Experiment beendet und beide KI Systeme abgeschaltet.

Es hat bei diesem Experiment die einfache Regel „Unterhaltet Euch auf Englisch“ gefehlt.

Die Marketing-Abteilungen vieler Unternehmen sprechen von „KI“, wenn sie das Ergebnis ihrer Kollegen aus der Entwicklungsabteilung, also das Ergebnis deren „natürlichen menschlichen Intelligenz“, möglichst marktschreierisch anpreisen. Und die Öffentlichkeit meint, „KI“ wäre auch nur ein Algorithmus, der von Menschen mit ethischen Grundsätzen entwickelt worden ist.

Aktuell befinden wir uns noch in der Forschungsphase. Aber eine KI, die bessere Weg für die Probleme der Menschheit, also Hunger, Umweltverschmutzung, Ressourcenknappheit, … findet, ist für uns als Menschen ein grosser Segen!

Bleibt nur ein Problem: Was ist, wenn wir beim Start der KI eine Regel vergessen oder falsch ausgedrückt haben? Eine Lösung für die oben genannten Probleme könnte ja auch eine Erde ohne Menschen sein.

Jetzt brauchen wir Menschen, die ständig prüfen, ob die KI noch in unserem Sinn und Interesse arbeitet.

Diese Menschen können das „Prüfen“ nicht gelernt haben, sie müssen die Fähigkeit schon besitzen.

Warum kann das „Prüfen“ nicht gelernt werden?

Wenn es ein Mensch lernen kann, müsste es ja auch zumindest einen Menschen geben, der es lehren kann.

Und nun stellt sich die Frage, warum genau dieser Mensch nicht für die fehlenden Regeln gesorgt hat, bevor die KI gestartet wurde.

Diese Menschen müssen ethisch und moralisch hohen Ansprüchen genügen, denn sie haben eine grosse Verantwortung. Die KI Systeme sorgen dafür, dass die Menschen, auch wenn es deutlich über acht Milliarden Menschen sind, leben können, ohne die Erde für künftige Generationen unbewohnbar zu machen. Werden die KI Systeme abgeschaltet, werden sicher viele Menschen deswegen sterben, aber sicher werden die „Prüfer“ zu den Überlebenden gehören, oder etwa nicht?

Wir brauchen also Menschen, die über die nötige Auffassungsgabe verfügen.

Diese müssen, ohne dass „Mitbewerber“ oder deren Eltern versuchen, sie wie auch immer zu übertrumpfen, ausgewählt und ihre Fähigkeiten durch eine passende Ausbildung verfeinert werden.

Und von diesen Menschen dürften wir weltweit nur sehr wenige haben.

Andere vielfach beschworene Gefahren von KI System und der weiteren Automatisation sehe ich nicht. Es wird die Gefahr des Abbaus von Arbeitsplätze genannt.

Die Menschen arbeiten, um ihre Ziele, also die Möglichkeit zum Konsum und Anerkennung zu erreichen.

Durch KI Systeme und die weitere Automatisation werden nicht weniger, sondern eher mehr Güter und Dienstleistungen erzeugt.

Haben die Menschen weniger Einkommen, also Anrecht auf Konsum, würde weniger gekauft und damit in der Zukunft weniger produziert werden.

Zehntausend Menschen, die einen Kleinwagen kaufen möchten, aber nicht das notwendige Einkommen, also „das Anrecht auf Konsum“, haben, können nicht als Konsumenten durch einen Superreichen „ersetzt“ werden, der einen Super-Sportwagen kauft.

Damit ergeben sich Umschichtungen in der Erwerbswelt, diese kennen wir aus der Geschichte. Früher waren fast alle Menschen in der Landwirtschaft tätig, und heute?

Bei personenbezogene Dienstleistungen, also Pflege, Erziehung und in vielen weiteren Feldern, sind KI Systeme und Roboter nicht die Lösung. Und die persönliche Pflege eines Menschen ist sicher eine Tätigkeit, die mehr Anerkennung erhält wie das formale Prüfen von dutzenden Haftpflichtschäden pro Tag.

Künstlerische und kunsthandwerkliche Tätigkeiten sowie Pflege- und Erziehungsberufe, die häufig freiberufliche ausgeübt werden, sind heute schlechter bezahlt im Vergleich zu festangestellten Verwaltungs- oder Fliessband-Berufen. Hier wird es sicher Umstellungen geben müssen. Ein erster Schritt wäre der Schwenk von einer einkommensbezogenen Erhebung von Steuern und Sozialabgaben hin zu Verbrauchssteuern, zum Beispiel der Mehrwert-, Energie-, Umweltbelastungs- und Genussmittelsteuern. Weiterhin sollte es ein Grundeinkommen, das von der Gesellschaft zur Verfügung gestellt wird, geben. Dieses Grundeinkommen wird pro Kopf gezahlt und es gibt keine weitere staatlichen Zuwendungen. Das Grundeinkommen sollte für ein ruhiges Leben in einer Lebensgemeinschaft auf dem Land reichen. Wer in München wohnen oder einen Sportwagen fahren möchte, muss dazu verdienen.

März 2019