Devoxx 2014

Im Jahr 2014 habe ich die Devoxx in Antwerpen besucht.

Hier sind ein paar Notizen dazu:

Was ist Devoxx?

  • Devoxx ist eine Konferenz der belgischen Java-User-Group
  • Belgien ist dreisprachig, Konferenz aber 100% in Englisch
  • Lokation in riesigem Kinokomplex guter Sound, gute Sitze, gute Projektoren, „cool“
  • 8 tracks, bei Keynotes „overflow“
  • Gut organisiert (dies Jahr sicher), unterhaltsamer als andere Konferenzen…
  • Schwesterkonferenzen:
  • Devoxx FR
  • Devoxx PL
  • Devoxx UK
  • Voxxed (Berlin, Ticino,….)

Themen & Hauptsponsoren

  • Java / Oracle
  • Android / Oracle
  • Startups, Business, IT in Großfirmen / ING-Bank
  • Java-Server, JBoss, Deployment / Redhat
  • JVM-Sprachen
  • Web
  • SW-Architektur
  • Security
  • Was sonst noch so ins Umfeld passt und sich jemand traut, vorzutragen…

Scala und Java8

  • Viele Features von Scala sind mit java8-Lambdas auch in Java verfügbar
  • Problem: verschiedene Implementierung, Interoperabilität
  • Bestrebung Scala weiterzuentwickeln damit lambdas von Java und von Scala besser miteinander interoperabel sind.

Monads

  • Konzept aus der Kategorientheorie (5% der Mathematiker machen Algebra, 5% der Algebraiker machen Kategorientheorie, aber für funktionale Programmiersprachen plötzlich relevant)
  • Monoid (+, *, concat,…)
  • Funktor
  • Monad (de: Monade)
    Wikipedia de
    Wikipedia en
  • (T, \eta, \mu)
  • Beispiel List mit einem Functor F: (A\rightarrow B)\rightarrow (List[A]\rightarrow List[B])
    \mu ist flatten: List[List[A]]\rightarrow List[A]; \eta: A\rightarrow List[A]

Probability & Decisions

  • Thema: Software für automatische Steuerung
  • Heuristik auf Wahrscheinlichkeitstheorie
  • False positives / false negatives: was tut weh? (meistens beide…)
  • Wahrscheinlichkeitstheorie und Verwendung gut erklärt

Clojure

  • Clojure ist eine andere JVM-Sprache
  • Ein Lisp-Dialekt, zu erkennen daran, dass der Quelltext überwiegend aus runden Klammern besteht (+ (* 3 4) (* 5 6))…
  • Funktionales Paradigma stark unterstützt
  • Dynamische Typisierung (für uns: Alles als „Object“ deklariert, implizite Casts bei Methodenaufrufen)
  • Nach Java selbst, Scala, Groovy und Javascript die mir am fünfthäufigsten begegnende JVM-Sprache

MapReduce

  • „No one at Google uses MapReduce anymore“
  • Google hat das verallgemeinert
  • Optimierungen: spare Schritte, fasse zusammen etc.
  • Als Cloud-Service angeboten (Cloud Dataflow)

Key Note ING

  • ING versteht sich als „open bank“
  • Nicht gemeint, dass das Geld „offen“ rumliegt, aber offen für neue Ideen
  • Schnittstelle zur Bank ist Mobile-App
  • IT hat viel Einfluss („IT driven business“)
  • Man schaut, was gut machbar ist
  • Agile Prozesse (Scrum) vs. Enterprise IT
  • Umbau der IT auf diese agilen Prozesse schrittweise
  • „Enterprise IT is what does not work“

Material Design

  • Vortrag über GUI-Design mit Android und Web
    Material Design
  • Visuelle Ideen für beide Plattformen verfügbar
  • Polymerdesign für Web

SW-Architektur mit Spring

  • Spring 4.1
  • „works with WebSphere“
  • DRY
  • Lambda aus Java8 kann viele APIs vereinfachen statt anonymen inneren Klassen mit einer Methode
  • Generic Messaging Interface (war JMS nicht schon das???)
  • Caching, Achtung beim Testen abschaltbar
  • Testen auf http://start.spring.io/
  • Spring funktioniert mit Java gut, mit Groovy auch (aus demselben Haus…) mit Scala „experimentell“

Lambda_behave

  • High-Level testing-Framework
  • Verwendet Java8-Features (Lambda etc)
  • Beschreibung in natürlicher Sprache
  • Failure-Meldungen lesbar
  • Wie Cucumber…
  • Zufallsquelle konfigurierbar (extrem wichtig für manche Tests!!)

Builtin Types of Scala and Java

  • In Java gibt es „primitive“ (long, int, byte, char, short, double,…)
  • Probleme bei Arithmetik mit int, long & Co:  Überlauf findet unerkannt statt
  • Mit float und double Rundungsfehler
  • Mit BigInteger, BigDecimal, Complex, Rational fehleranfällige, umständliche und unlesbare Syntax
  • In Scala kann man a=b*c+d*e auch für neu definierte numerische Typen schreiben.
  • Anmerkung dazu: Oracle-Java-Leute finden Idee von Operator-Überladen für numerische Typen inzwischen interessant, solange man nicht Exceptions mit Collections multipliziert und durch Swing-Komponenten dividiert…
  • Spire library

Zukunft von Java (9, 10, …)

Teil I

  • Q&A-Sitzung (Fragen per Twitter schreiben)
  • Numerische Typen sind Thema. Dass primitive Typen sich so verhalten wie heute und quasi der „default“ sind, wird sich nicht ändern
  • Thema Generics und Type-Erasure (wo ist das Problem)?
  • Jigsaw vs. Jars vs. OSGi  noch offen, aber jar bleibt
  • Jigsaw-Repository  Wird man wohl bei maven-Central, Oracle funktioniert nicht so, dass sie jigsaw-Repository für third-Party bei sich hosten

Teil II

  • Benchmarking mit Java schwierig wegen hotspot-Optimierung
  • JMH gutes Tool dafür
  • Neue Ideen immer schwierig umzusetzen, weil man kompatibel zu alten Versionen sein will.
  • Java bekommt vielleicht „repl“

Teil III

  • Collection literals (für Java 7 versprochen!!!) sind für Java8 nicht gekommen, für Java9 unwahrscheinlich
  • Mit Value-Types aber eher zu haben, daher nicht vorher…
  • Für Set und List mittels
    new TreeSet(Arrays.asList(m1, m2, m3,…., mn))
    schon heute einigermaßen darstellbar
  • Für Maps wenn man sowas wie Pair-hätte, was wiederum auf „Tupel“ aufbaut, die kommen werden, wenn es Value-Types gibt

Teil IV

  • Tail-Recursion kann nun optimiert werden
  • Wegen Security-Manager, der Stacktrace analysiert hat, lange nicht möglich
  • C und Lisp können das seit Jahrzehnten…
  • Aussage: Generics sind schwierig, aber wenn man sie mal verstanden hat, sind sie leicht… Also „dranbleiben“
  • Covarianz und Contravarianz (Bei Array falsch gelöst)

Teil V

  • Arrays 2.0: Indizierung mit long möglich, ein bißchen wie List, aber mit Array-Syntax… (Studien und Papers, nicht konkret)
  • Listen haben heute extrem-Implementierung ArrayList und LinkedList. Wir wollen „sophisticated“ List vielleicht Hybrid
  • Checked-Exceptions: kritisches Thema, schwierig mit Generics und mit Lambda. Zu viele Exceptions sind checked. Z.B. bei close()

Semantische Quelltextanalyse

  • Hilfreich für High-Level-Testing-Tools
  • Statische und dynamische Analyse
  • Dataflow-Analyse: ungeprüfte Daten von außen  SQL-injection, aber auch CSS, HTML, JavaScript, JVM-Sprachen/Bytecode

Funktionale Ideen in Java

  • Funktional:
  • Funktionen oder Methoden sind „first class citizen“
  • Higher order Functions (konnte schon C)
  • Closure
  • Immutability (Funktion gibt immer dasselbe raus)
  • Unter der Tischdecke „lazy“-Konstrukte
  • Bei großen Strukturen immer Frage: Immutability vs. Performance
  • Aber Funktional ist Thread-freundlicher

50 new things in Java8

Teil I

  • Lambda (s.u.)
  • Streams (s.u.)
  • Default-Implementierungen in Interfaces
  • Date/Time (wie Joda-Time)
  • Optional (besser als null)
  • Libraries können mit Lambda arbeiten
  • Parallel (mit Vorsicht verwenden)

Teil II

  • String.join()
  • So was wie „find“ in Unix/Linux
  • Comparator schreiben einfacher
  • Maps of Maps, Maps of Collections einfacher
  • Sortieren besser: quicksort statt mergesort, parallelisierbar

Groovy für Android

  • Problem bei JVM-Sprachen außer Java: Bibliothek muss in jeder App mitkommen
  • Lösung: Tool zum jar-optimieren
  • Zweites Problem: dynamische Sprachen müssen auf Device „on demand“ kompiliert werden
  • Lösung: „statisch“ Programmieren, dynamische Features möglich, aber nicht performant

Lambdas

  • Lambdas sind anonyme Funktionen
  • Idee gegeben: Interface XY mit einer Methode uvw()
  • Statt
    XY xy = new XY() {
    public long uvw(long x) { return x*x }
    };
    neu
    XY xy = x -> x*x;
  • kürzer, lesbarer, wartbarer, man kann Interface oft sparen
  • Closure bedeutet, dass (final-)Variablen aus dem umgebenden Kontext dort eingebunden werden
  • Instanz-Methoden sind eigentlich auch Closure, sie binden die Instanz in der sie definiert sind Closure-mäßig ein.

 Streams

  • Streams sind im Dunstkreis von Collection, Iterable, Iterator, aber was anderes
  • Erlauben Methoden, die „Funktion“ auf alle Elemente loslassen
  • Elegant programmierbar sind Dinge wie
    • Summe
    • Produkt
    • Maximum
    • Erstes / Letztes Elment mit Eigenschaft
    • alle mit Eigenschaft
    • alle transformierten Elemente
  • Sinnvoll: nicht dasselbe wie Iterable, Iterator, Collection,…

 Links

Share Button

Random-Access und UTF-8

English

Es ist eine schöne Sache, dass man „Random-Access-Dateien“ verwenden kann und die Möglichkeit hat, effizient zu einer beliebigen Byteposition zu springen, um ab dort zu lesen oder zu schreiben.

Das gilt auch für Textdateien, bei denen pro Zeichen eine feste Anzahl Bytes verwendet wird, z.B. immer genau ein Byte oder immer genau zwei Bytes pro Zeichen.

Nun ist aber der neue Standard für Text-Dateien UTF-8. Da funktioniert das auch fast so, weil bei vielen Sprachen die Zeichen immer noch meistens ein Byte groß sind.
Aber wenn man zu einer bestimmten Byte-Position springt, kann es passieren, dass man mitten zwischen den Bytes eines Zeichens („Code Point“) landet und nicht am Anfang eines Zeichens. Woher soll man das erkennen, wenn man nicht den Effizienzgewinn von Random-Access wegwirft und die Datei Byte für Byte und Zeichen für Zeichen liest, bis man an der betreffenden Stelle ist?
Nun lässt sich das aber finden, da UTF-8 Self-synchronizing ist. Man weiss, dass das erste Byte einer Bytesequenz, die ein Zeichen beschreibt, entweder mit 11 oder mit 0 anfängt. Alle weiteren Bytes fangen mit 10 an. So lässt sich vorwärts oder rückwärts an den Anfang eines Zeichens springen, das zumindest so nahe wie möglich an der gewünschten Position beginnt.
Schwieriger wird es, wenn man nicht an eine bestimmte Byte-Position, sondern an eine bestimmte Zeichenposition springen will.
Man kann das zwar schätzen, aber man weiß nie genau, wie lang die Zeichen in dem übersprungenen Bereich als Bytesequenz sind. Das lässt sich mit einer Indexstruktur in einer zweiten Datei oder in einem dafür abgestellten Bereich der Datei lösen, wo vermerkt ist, an welcher Byteposition man jeweils den Beginn von Zeichen k*b findet, wobei b eine „Blockgröße“, z.B. 1024 Zeichen, ist. Solange man nur hinten anhängt und nicht mitten in der Datei etwas überschreibt, sollte das möglich sein.

Share Button

Memory bei Java-Zeichenketten

Es hat von Java 1.6 nach Java 1.7 eine für den Memoryverbrauch relevante Änderung gegeben.
Bis Java 1.6 wurde bei substring eine Zeichenkette konstruiert, die das selbe interne Array von Zeichen (char) referenziert und nur andere Werte für Anfang und Länge enthält. Das hatte den Vorteil, dass in vielen Fällen Memory gespart wurde, weil man die Teilzeichenkette nicht nochmal speichern musste. Auch das Umkopieren wurde gespart. Nun war es aber wichtig, in manchen Fällen so etwas wie
String mySubString = new String(origString.substring(3, 5));
statt
String mySubString = origString.substring(3, 5);
zu verwenden, wenn nämlich origString sehr viel länger als mySubString war und sehr viel früher obsolet wurde als mySubString. Wer das vergessen hat, hat so ein Memoryleak gebaut.
Das wurde in Java 1.7 „gefixt“, nun wird das Array mit den Zeichen intern immer kopiert, weil die Entwickler nicht verstanden haben, mit diesen beiden Möglichkeiten richtig umzugehen. Leider hat man nun aber die andere Möglichkeit nicht mehr zur Verfügung.
Was kann man tun, wenn man eine Memory-intensive Applikation schreiben will, in der viele langlebige Zeichenketten vorkommen, die Teil einer längeren, ebenfalls langlebigen Zeichenkette sind?
Die erste Frage ist immer, ob man mit der neue Implementierung nicht doch leben kann.
Da die Zeichenkette sehr tief in Java verankert ist, kann man sie nicht so leicht ersetzen bzw. muss etwas hässlicheren Code schreiben, um explizit die eigene Zeichenkette zu verwenden. Wenn nötig ist das aber machbar: Man nimmt von gnuClasspath java.lang.String und refactored das zu einem anderen Package- und Klassennamen. Daraus lässt sich dann leicht das gewünschte bauen. Wichtig sind Konversionsroutinen nach java.lang.String in beide Richtungen.

Links:

Share Button

Chemnitzer Linuxtage

Es gibt diese Veranstaltung nun schon seit 16 Jahren und ich war noch nie da…
Aber es muss gut sein:

Chemnitzer Linuxtage 2015

Share Button

Transaktionsisolation

English

Dieser Artikel basiert auf einem Vortrag, den ich bei der Ruby on Rails User Group Schweiz in Zürich gehalten habe.

Naiver Zugang zu Transaktionen

Alle reden von Transaktionen, aber wer kennt sich wirklich gut damit aus?
Ist es vielleicht wie beim Multithreading, wo man sehr viele Leute findet, die behaupten, sich gut auszukennen, aber sehr wenige Multithreading-Programme, die wirklich unter Last auch korrekt laufen?

Immerhin haben wir so eine ganz brauchbare Vorstellung:

  • Wir beginnen implizit oder explizit eine Transaktion
  • Wir führen eine oder mehrere Operationen durch (z.B. SQL-Befehle)
  • Wir beschließen am Ende entweder ein „roll-back“ oder „commit“
  • Roll-back stellt den Zustand von vor der Transaktion wieder her
  • Commit akzeptiert die Änderungen definitiv

Das ist doch überschaubar. Warum brauchen wir da noch komplizierten Kram?

Wenn wir uns in einer einfachen Welt bewegen, wo nur ein DB-User mit einer Session auf der Datenbank ist.

Die komplizierte Welt

In einer komplizierten Welt finden leider parallele Aktivitäten statt.
Mehrere Threads, Prozesse oder auch externe Datenbank-Clients greifen auf die Datenbank zu.

Was machst das so kompliziert?
Wenn Dinge parallel werden, dann ist jeder Entwickler gut darin, das im Griff zu haben, aber komischerweise funktioniert es dann meistens gar nicht oder zumindest nur auf dem Laptop des Entwicklers, nicht aber langfristig auf dem Server unter Last.
Aber die Leute, die Datenbankprodukte entwickeln, sind wirklich gut. Datenbanken laufen mit vielen parallelen Zugriffen unter Last auf Millionen von Rechner und funktionieren dabei noch recht zuverlässig.
Nun haben wir aber ein paar zusätzliche Fragen:

  • Was passiert mit unvollständigen Transaktionen vor dem Commit?
  • Was passiert mit erfolgreich abgeschlossenen Transaktionen während eines langen SELECTs oder einer langen lesenden Transaktion?
  • Dasselbe betrifft auch lange Transaktionen, die Daten verändern, aber dabei auch lesend zugreifen.

Eine Naive Anforderung wäre, dass andere Clients die Transaktion entweder ganz oder gar nicht sehen. Reicht das?
Man stelle sich ein Problem vor, das in einer langweiligen Informatik I-Vorlesung in meinem Studium real war:

  • Die Vorlesung geht 90 min ohne Pause.
  • Der „Hörsal“ ist eine Maschinenhalle, die man provisorisch mit Stühlen ausgestattet hat.
  • Etwa 600 Leute sind anwesend.
  • Es gehen dauernd Leute raus.
  • Am Schluss der Vorlesung ist der Hörsal immer noch ziemlich voll.
  • Wie viele Leute sind zu einer bestimmten Zeit in dem Hörsal?
  • Eine präzise und korrekte Zahl existiert immer, denn so brutale Sachen wie halbe Studenten waren damals nicht üblich.
  • Aber das Zählen ist schwierig, weil während dem Zählen dauernd Leute den Raum verlassen.
  • Merke: Das Verlassen des Hörsals ist eine Transaktion. Nach dem Commit ist die betreffende Person draußen, vorher drin.

Da kommt nun das berühmte Snapshot too old ins Spiel, das einige von uns, die noch mit Oracle arbeiten, recht gut kennen. Oracle hat das Problem, die Hörer im Hörsaal zu zählen, nämlich gelöst. Und ähnliche Probleme auch. Das SELECT bei Oracle bekommt für seine Verarbeitungszeit einen konsistenten Datenstand, der auf dem Zustand beim Start der Abfrage basiert.
Transaktionen, die währenddessen erfolgreich mit einem Commit abgeschlossen werden, werden nicht berücksichtigt. Das wird „Snapshot“ genannt. Sehr lange laufende SELECTs, die auf Daten zugreifen, die sich häufig ändern, scheitern manchmal mit „Snapshot too old“.

Präzisierung

Diese Konzepte werden jetzt etwas präzisiert, aber die Details nachzulesen sprengt sicher den Rahmen eines Blog-Artikels.
Es geht um:

  • Anomalien (Read phenomena)
  • Transaction-Isolation-Levels
  • ACID

Anomalien bezeichnen ein unerwartetes oder unwillkommenes Verhalten beim Lesen.

„Dirty Read“ bedeutet, dass auf Daten zugegriffen werden kann, die in einer anderen Transaktion geändert werden, bevor sie committed worden sind. Das widerspricht jeder intuitiven Vorstellung von Transaktionen. Eine interessante Frage ist aber, ob die Transaktion, die die Daten verändert, bei ihren Zugriffen jeweils den Stand nach den eigenen Veränderungen sehen kann oder ob dies erst nach dem eigenen Commit möglich ist. Bei Oracle galt immer der erste Fall, außer es hat sich kürzlich geändert, was ich aber stark bezweifle.

„Non-repeatable read“ steht für Leseoperationen auf denselben Daten während einer Transaktion, die aufgrund in anderen Transaktionen vorgenommener Änderungen verschiedene Ergebnisse liefern. Das ist genau das Problem mit dem großen Höraal. Oracle vermeidet das zum Beispiel standardmäßig.

„Phantom reads“ stehen für Leseoperationen, bei denen zwar Daten sich selbst nicht ändern können, aber durch DELETE und INSERT Datensätze wegfallen oder hinzukommen können.

Isolationslevel bezeichnen eine Einstellung einer Datenbank und die Anforderungen dazu.

„Read Uncommited“ erlaubt „dirty read“. Mir ist kein Fall bekannt, in dem das tatsächlich so praktiziert wird. Diese Einstellung ist für parallel mehrfach verwendete Datenbanken kaum brauchbar. Man kann das konfigurieren und der Standard erlaubt Datenbanken „besser“ als das zu sein.

„Read Committed“ steht dafür, dass man nur Daten von vollständig abgeschlossenen Transaktionen sehen kann. Das bedeutet also, das „dirty read“ ausgeschlossen ist, aber „non-repeatable read“ möglich ist. Das ist die Grundeinstellung für viele Datenbanken, z.B. für PostgresSQL.

„Repeatable Reads“ steht für eine Einstellung, die die Daten gegenüber UPDATEs scheinbar konstant hält. Das unterbindet „non-repeatable-read“, aber nicht „phantom-read“.

Bei der Einstellung „Serializable“ werden alle Transaktionen komplett entflochten. Man bekommt das Verhalten als wären alle Transaktionen in einer Warteschlange (Queue) und es würde immer nur jeweils eine nach der anderen abgearbeitet, womit wir wieder am Anfang wären, aber das stimmt nicht ganz. Zunächst mal werden sogar phantom-reads unterbunden.

Reale Datenbanken

Reale-Datenbanken haben eine Standardeinstellung („default“) für die Transaktionsisolation, aber sie dürfen immer besser als der eingestellte Wert sein, ohne den Standard zu verletzen. Das gibt also die Möglichkeit, Mischformen zu implementieren. Oracle hat mit „read-only“ sogar einen zusätzlichen Wert.

Nun gibt es verschiedene Wege, so etwas zu implementieren, grob gesagt sind es Locking oder Multiversion. Beim Locking werden Datensätze, Bereich, Spalten, Tabellen oder ganze Schemata gelockt, also exklusiv von einer Transaktion in Anspruch genommen. Bei Multiversion werden verschiedene Kopien der Daten erstellt und jeweils mit diesen gearbeitet. Es bleibt eine Herausforderung, die Daten am Schluss zusammenzufügen.

Verschiedene Datenbankprodukte nutzen den Interpretationsspielraum des Standards recht gut aus. Z.B. ist Oracle natürlich der Standard und man muss nur so tun, als halte man sich an den SQL-Standard.

Ich empfehle am Anfang eines Projekts eine weise Entscheidung über die Wahl der Datenbank zu treffen. Gerade hier bei den Transaktions-Isolations-Levels zeigt sich einmal mehr, dass die verschiedenen Datenbanken nicht so gleich sind und deshalb der Astausch gegen ein anderes Produkt problematisch und teuer sein kann.

ACID

ACID ist das englische Wort für Säure. In der Chemie nennt man Substanzen mit einen pH-Wert < 7 Säuren.
Hier ist aber „ACID“ ein Acronym:

  • Atomicity
  • Consistency
  • Isolation
  • Durability

Ein paar Links

Share Button

Früher ging alles schneller

Früher ging alles schneller, aber dann kamen die Computer und haben alles kompliziert gemacht.
Oder es wurden einfache Computer durch komplizierte ersetzt.

Nur zwei Beispiele:
Früher hatten die Leute beim Fahrkartenschalter der Bahn ein mechanisches Gerät, mit dem sie blitzschnell die gewünschte Fahrkarte generieren konnten. Die Fahrkarte war nur so groß wie zwei mittelgroße Münzen nebeneinander, passte also noch in das Gepäck. Und die Schlangen im Bahnhof waren noch kurz, weil alles blitzschnell ging.
Dann kamen Computer und die richtigen Schlangen. Die Computer hatten solche grünen Terminals und Masken, wo man mit ein paar Tasten die Fahrkarte bekam. Für den geübten Eisenbahner immer noch schnell. In der Bank hatten sie auch solche Terminals und man war auch dort schnell.
Dann kam aber Coolness ins Spiel. Die Arbeitsplätze bei Banken und Bahnschaltern bekamen grafische Oberflächen. Plötzlich waren die Schlangen lang und man brauchte viel Zeit.

Was sollte der Quatsch? Es ist wie mit Malerei und Fotografie. Der Maler, der heute fotografisch perfekt malen kann, ist nicht mehr so gefragt, das kann man mit digitalen oder analogen Kameras auch als Laie schaffen. Aber der Maler, der irgendwas Schönes malt, was man nicht so leicht fotografieren kann, ist noch interessant.
Fahrkarten und Geldabhebungen und Überweisungen und Überprüfung des Kontostands kann man heute an Automaten oder im Internet erledigen. Oder mit dem Mobiltelefon.
Der Schalter bekommt eine andere Funktion, denn dort kann man die Spezialitäten bekommen, die weder die grün-schwarze Terminal-Maske noch die coolste Mobile-App bieten können. Auslandsfahrkarten waren noch in den 80er-Jahren sehr schwierig zu kriegen. Man musste zum Sonderschalter, das Geld vorauszahlen und dann wurde die Reservierung per Telex oder Fax an die Partnerbahn geschickt und wenn man Pech hatte, klappte es dann doch nicht. Heute kauft man die einfach.

Share Button

Login-Verfahren

Karl Brodowsky IT Sky Consulting GmbH

English

Für die Authentisierung in Webapplikationen gibt es verschieden Ansätze.
Ich beschreibe einmal einige, die mir tatsächlich begegnet sind, und mache mir ein paar Gedanken, was man davon erwarten kann.

Nun ist die Frage, ob so etwas nicht sehr einfach ist, man muss nur irgendwo Namen und Passwörter speichern und dann beim login einen Abgleich machen. Das können die ganzen coolen Frameworks heute gut, egal ob Java, Ruby, Perl, PHP, Scala, F# oder Python.

Aber es kommen einige Fragen auf:
– Sicherheit
– Vergessene Passwörter
– Benutzerfreundlichkeit

Beispiele für E-Banking und anderes

  • „Taschenrechner“
  • RSA-Zahlen-Generator
  • SMS
  • Zettel mit 100 Codes
  • Android-App
  • USB-Device
  • SmartCard
  • Einfach Username + Password
  • Login mit Google, Twitter oder Facebook

Taschenrechner

  • Auf Login-Seite Username + Password eingeben
  • PIN Code in TR eingeben
  • Code von Login-Seite in TR eingeben
  • Ergebnis von Taschenrechner ablesen
  • In Login-Seite eingeben

Security.Fragen:

  • Abhängig davon, wie der Taschenrechner funktioniert
  • Weil der Taschenrechner einen PIN-Code braucht gewisse Sicherheit gegen Verlust + Diebstahl

Praktische Fragen:

  • Taschenrechner nie dabei
  • Wer bezahlt die teure Hardware
  • Distribution der Hardware muss organisiert werden

Zusammenfassung:

Diese Methode is potentiell recht gut, wenn sie sauber und mit guten Algorithmen und guten Daten implementiert ist.

RSA-Zahlen-Generator

  • Auf der Login-Seite wird zusätzlich ein vom Gerät abgelesener 6-stelliger Code eingegeben.
  • Alle paar Sekunden/Minuten ändert sich der angezeigte Code

Security-Fragen

  • Sieht gut aus weil es von RSA kommt
  • Sind die Uhren immer gut genug synchron? Es scheint so.
  • Kein zusätzlicher Schutz, wenn das Gerät gestohlen wird
  • Kein Challenge-Response, nicht so gut wie der Taschenrechner

Praktische Fragen:

  • Gerät ist klein genug um es immer dabei zu haben
  • Gerät ist sehr teuer

SMS

  • username und password eingeben
  • code kommt als SMS
  • Code eingeben

Security-Fragen

  • Wie sicher ist das Mobilnetz?
  • Wie sicher ist das Telefon? Altes Nokia mit Prepaid-SIM ist sicher, aber modernes Smartphone riskanter
  • Für m-banking problematisch, wenn beides auf demselben Telefon läuft

Praktische Fragen

  • Telefon ist immer dabei
  • Aber nicht, wenn man dem Smartphone nicht traut und ein zweites braucht
  • SMS gehen verloren
  • Manche Leute haben viele SIM-Karten. Ist aber nicht so verbreitete Gewohnheit, man zahlt sehr gerne große Roaming-Rechnungen
  • Batterie kann leer sein. (Nur ein Problem der älteren Generation)
  • SMS-Roaming-Gebühren spielen für diesen Anwendungsfall keine große Rolle

Zusammenfassung

Solider Mechanismus, aber etwas schlechter als Taschenrechner.

Zettel mit 100 Codes

  • Login mit Username und Password
  • Die Seite verlangt Code von einer bestimmten Seite und einer bestimmten Nummer
  • Jede Nummer wird nur einmal verwendet
  • Neuer Zettel, wenn alter ca. 80% aufgebraucht

Security-Fragen

  • Hängt von der Qualität der Zahlen ab
  • Papier kann verloren gehen oder gestohlen werden
  • Drucken und Handhaben der Zahlen bietet viele Schwachstellen im ganzen Prozess

Praktische Fragen

  • Papier muss von Kunde und Bank verwaltet und aufbewahrt werden
  • Muss immer dabei sein, eventuell als Foto auf dem Telefon
  • Muss sorgfältig aufbewahrt werden

Zusammenfassung

Mechanismus rangiert irgendwo im Mittelfeld. Abgesehen davon, dass es nicht so cool ist, ist es nicht wirklich schlecht, aber schlechter als der Taschenrechner.

Android App

Oder mit anderen Smartphones auch machbar…

  • Login mit Username und Password
  • Ein farbiger Code wird angezeigt:

code

  • Starte Android-App die den Code fotografiert und auswertet.
  • Eine 6-stellige Zahl und eventuell mehr Information wird angezeigt.
  • 6-stelligen Code auf Login-Seite eingeben
  • Bemerkung: Die App muss personalisiert werden und funktioniert nur für das eigene e-Banking

Security-Fragen

  • Kein Password innerhalb der App
  • Telefon muss sicher aufbewahrt werden und Password- oder PIN-Schutz haben
  • Positiv ist, dass es so einfach geht, dass man das Verfahren auch zur Verifizierung einzelner Buchungen mit neuem Empfänger verwenden kann.
  • Der Code kann Information transportieren, die man in der App anzeigen kann

Praktische Fragen

  • Braucht passendes Smartphone
  • Smartphone ist immer dabei

USB-Device

Ein USB-Gerät wird in den Rechner gesteckt. Dieses kann „smart“ sein und direkt mit dem Server kommunizieren. Man kann sogar ein speziell sicheres Linux vom USB-Stick booten für das E-Banking.

Ich habe nur theoretisches Wissen dazu, keine Erfahrungen.

Security-Fragen

  • Hat sehr viel Potential
  • Ein manipulierter PC kann viel schaden, idealerweise aber den Traffic zwischen Device und Server nicht manipulieren.

Praktische Fragen

  • braucht speziellen USB-stick
  • USB ist in manchen Großbetrieben abgeschaltet, speziell das Booten von USB
  • Gerätetreiber sind immer ein Problem, wenn man sie braucht

Smart Card

Wie USB-Gerät, nur mit SmartCard statt USB-Stick.

Username + Password

  • Für E-Banking nicht genug, aber es soll Banken geben, denen das egal ist
  • Für einfache Applikationen ist es heikel, Username und Passörter auf dem eigenen Server zu haben
  • Immer noch der Default-Ansatz, einfach
  • Wie geht die User-Verwaltung??

Security-Fragen

  • Niedrigste Security
  • Benutzer- und Password-Datenbank ist immer ein Risiko, siehe iCloud

Login mit Google

  • Benutze google+, facebook, twitter etc. für login
  • Hier nehmen wir Google an um weniger schreiben und lesen zu müssen…
  • Bei Google einloggen. Sind wir sowieso normalerweise schon
  • Klick auf „Login mit Google“
  • Beim ersten Mal fragt Google, ob sie der Applikation die Identität geben dürfen.
  • In den Google-Settings kann das entfernt werden.

Security-Fragen:

  • Wie sehr lieben wir die NSA
  • User management kann Google besser als wir
  • OAuth2 ist unser Freund, nicht so schwierig zu verwenden

Immer dran denken

  • Wir sollten immer https verwenden
  • http bedeutet, dass Passwörter im Klartext übertragen werden, „Freunde“ im Netz können sie mitlesen.
  • Wenn es um Geld geht, geht http gar nicht, nur https
  • Das hilft jedenfalls etwas.
  • Wer weiß, was die NSA über https weiß, was nicht veröffentlicht worden ist?

Ich möchte diese Seite bald auf https umstellen… 😉

Share Button

Auf GPU rechnen

Heutige Rechner haben bekanntlich sehr leistungsfähige CPUs mit „Quadcore“ und mehr.
Aber auch die Grafikkarten sind ziemlich toll geworden und haben zum Teil auch so große eigene Lüfter wie die CPU.
Sie haben eine Menge eigenes Memory und sie können recht komplizierte Operationen selbsttätig rechnen, natürlich nur für die grafische Darstellung.

Nun stellt sich die Frage, ob man das auch sonst zum Rechnen benutzen kann. Man hört Geschichten, dass die Grafikkarte um Größenordnungen leistungsfähiger als die CPU sei. Warum schaffen das die Grafikkartenhersteller so leicht nebenbei, besser als die CPU in deren Kernaufgabe zu sein und außerdem noch Grafik darzustellen?

Grafikkarten bieten die Möglichkeit, massiv parallel zu rechnen, aber nach dem Prinzip SIMD. Das heißt, dass ein oder sehr wenige Befehlsströme verarbeitet werden und eine große Zahl von Recheneinheiten jeweils den identischen Code mit verschiedenen Daten ausführt. Für Vektoroperationen ist das optimal. Und es erklärt auch die brachiale Leistung der Grafikchips, weil man den aufwändigen Teil, Maschinencode zu interpretieren, nur einmal (oder wenige Male) baut und nur die eigentliche Recheneinheit mehrfach. Man bekommt so mit derselben Siliziummenge mehr Rechenleistung, aber mit der Einschränkung, SIMD (oder fast SIMD) zu sein. Aber man hat diese Geräte in den Rechnern drin. Es gibt sogar „Grafikkarten“, die nur rechnen können, aber bei denen man die eigentlichen Grafikchips weggelassen hat. Und viele Rechner haben den Grafikkern mit auf dem selben Chip wie die CPU-Kerne, so dass man eine einfache Grafik zur Verfügung hat, aber man baut dann doch zusätzlich noch eine externe Grafikkarte ein, die noch besser ist. Selbst ohne die Grafikfähigkeit zu gefährden hat man also eine GPU zum Rechnen übrig.

Nun ist das Programmieren dieser Geräte nicht so einfach. Grundsätzlich muss man sich mit einem völlig neuen Programmiermodell herumschlagen. Viele Algorithmen lassen sich speziell für SIMD entwickeln, aber sie sind anders als was wir gewohnt sind und automatisch lässt sich da nur beschränkt etwas optimieren. In der Regel muss man also mit C das Programm schreiben und kann dabei auf OpenCL bauen. Das ist ein nützlicher Standard, der einiges erleichtert, aber es bleibt schwierig. Für manche Zwecke lohnt es sich aber, den Entwicklungsaufwand zu treiben.

Vor ein paar Tagen habe ich drei Vorträge über Ansätze gehört, F# zu verwenden, um die GPU zu programmieren. Man kann also unter Einhaltung gewisser Regeln F#-Programme schreiben, die sich etwa in OpenCL übersetzen lassen und dann compiliert die GPU nutzen:

  • FSCL: Homogeneous Programming and Execution on Heterogeneous Platforms (by Gabriele Cocco, Pisa University)
  • Professional GPU Development with F# and the Alea Compiler Suite (by Daniel Egloff, QuantAlea)
  • New Abstractions for Radically Simplified GPU Programming in F# and .NET (by Luc Bläser, HSR, based on joint work with QuantAlea)

All diese Ansätze sollten schon heute oder zumindest in zukünftigen Implementierungen auch für Mono laufen und damit für Linux zur Verfügung stehen.

Es würde wohl den Rahmen dieses Artikels sprengen, im Einzelnen darauf einzugehen, aber vielleicht kann ich noch Links bekommen, die auf weiterführendes Material zu den einzelnen Lösungsansätzen führen.

Share Button

Alle zwei Wochen

Ich werde den Rhythmus dieses Blog auf alle 14 Tage umstellen.

Share Button

Einheiten mitführen

Typische Programme rechnen mit Größen, also mit Zahlwerten, die mit irgendeiner Einheit kombiniert sind. Das können Temperaturen, Längen, Zeitdauern, Geldbeträge und vieles mehr sein. Weil früher jedes Byte teuer war, hat sich etabliert, dass man nur mit den Zahlwerten arbeitet und die Einheiten implizit durch die Programmlogik ins Spiel kommen. Das funktioniert in einfache Fällen, wo die Einheit wirklich klar ist. Wenn aber mehrere Einheiten im Spiel sind, ist es besser, diese auch mitzuführe, außer bei dieser massiv strapazierten inneren Schleife, die man in Wirklichkeit im ganzen Programm doch nicht findet.

Man kann das durch Typisierung erreichen, also etwa Typen wie „KelvinTemperatur“ definieren oder man kann einen Typ „Temperatur“ definieren, der den Betrag und die Einheit enthält. So können bestimmte Fehler zur Laufzeit oder sogar zur Compilezeit entdeckt werden oder sogar passende Umrechnungen verwendet werden, wenn man eine Fahrenheit und eine Kelvintemperatur addiert.

Java bekommt hier einen Minuspunkt, weil man dort nicht vernünftig die elementaren Operationen für solche Typen definieren kann.

Die meisten anderen modernen Programmiersprachen können das natürlich.

Share Button