Freitag, 27. Dezember 2019

Einfache Bewegungserkennung auf dem Raspberry Pi

Mit dem Thema Bewegungserkennung wird gerne KI in Verbindung gebracht, aber Bewegungserkennung geht auch mit normalen Computer Vision Mitteln.

Es ist sehr einfach möglich, Bewegungserkennung mit einfachen UNIX Programmen durchzuführen. Ich benutze hier ImageMagic. Folgend ein Beispiel, das auf einem Raspberry Pi Zero W läuft. Hier ein Auszug aus dem BASH Script:

raspistill -o                      camImages/$DATE.jpg
convert    -normalize -blur 0x8    camImages/$DATE.jpg blur/$DATE.jpg
compare    -fuzz 8%   -metric RMSE nb3.jpg nb4.jpg x.jpg

  1. Zuerst muss ein Bild aufgenommen werden.
  2. Dann wir das Bild bzgl. des Histogramms normalisiert und mit dem Weichzeichen wird das Bildrauschen des Kamerasensors eliminiert.
  3. Zuletzt wird das aktuelle Bild mit dem Vorgängerbild verglichen. Die Metrik gibt an, wie stark sich die Bilder unterscheiden, hier muss ein passender Schwellwert (-fuzz 8%) eingestellt werden.

Mit dieser Lösung werden Bewegungen in Bildern zuverlässig erkannt. Hier ein Beispiel für ein Differenzbild.

Die Nachteile:
  1. Dieser Lösung ist die hohe Laufzeit von ca. 75 sec auf Raspberry Zero W. 
  2. Die Normalisierung ist noch nicht optimal, Änderungen in der Beleuchtung werden häufig als Bewegung erkannt, das kann zur Zeit nur durch ein Anhaben des Schwellwertes kompensiert werden.
Update:
Einige Optimierungen wie die Verringerung der Bildauflösung führen zur einer Reduktion der Laufzeit von 90 sec auf 75 sec auf 23 sec. Durch die jetzt kürzeren Abstände zwischen den Bildern werden Fehlerkennungen noch weiter reduziert.

Samstag, 10. August 2019

Programmiersprachen die ich gelernt oder benutzt habe

Programmiersprachen die ich gelernt oder benutzt habe:
  1. Assembler
  2. BASIC
  3. BASH
  4. C
  5. Go
  6. Groovy
  7. JavaScript
  8. Java
  9. Lingo
  10. MS-DOS Scripting
  11. Objevtive-C
  12. Pascal
  13. Pearl
  14. Python
  15. R
  16. Ruby
  17. SAS
  18. Scala
  19. SPS
Programmiersprachen die ich extrem gut beherrsche:
  1. Java
  2. BASH
  3. R
Programmiersprachen die gerne probieren würde:
  1. GO

Dienstag, 6. August 2019

Java, XML und Performance

XML ist ein populäres Datenformat für den Datenaustausch zwischen Systemen. Der Vorteil von XML ist, es gibt sehr stabile Parser. Aber wie sieht es mit der Performance aus? Folgende Aufgabe: Einlesen einer XML Datei mit 100T Elementen,  die einige Unterelemete besitzt, die Tiefe ist 4, Dateigrösse 60Mb, Java 8.

Zum Performancevergleich wurde mit einem Subset von 350 Elementen gearbeitet.

Test 1: Java, XML, DOM, Xpath, 350 Elemente in Datei

  1. Laufzeit pro Element: 20ms
  2. Verhältnis XML Parsen/DB Speichern: 25, das XML Verarbeiten verbraucht primär die Zeit
  3. Geschätzte Gesamtlaufzeit: 33 min


Test 2: Java, XML, DOM,  Jaxen 1.2 Xpath, 350 Elemente in Datei

  1. Laufzeit pro Element: 3ms
  2. Verhältnis XML Parsen/DB Speichern: 15, das XML Verarbeiten verbraucht primär die Zeit
  3. Geschätzte Gesamtlaufzeit: 5 min
  4. Jaxen Xpath ist deutlich schneller als das normale Java Xpath

Beide Tests waren erfolgreich. Jetzt der Test mit voller Datenmenge.

Test 3: Java, XML, DOM,  Jaxen 1.2 Xpath, 100T Elemente in Datei
  1. Manueller Abbruch des Test, weil die Laufzeit unglaublich schlecht war.
Test 3: Java, XML, DOM,  Xpath, 100T Elemente in Datei
  1. Manueller Abbruch des Test, weil die Laufzeit unglaublich schlecht war.
  2. Performance ist aber besser als Jaxen.
  3. Bei einer Detailanalyse sieht man das die Laufzeit für die XPath Evaluierung nach oben schnellen, das obwohl ausreichen RAM (XMX) vorhanden ist. Der Schluss daraus ist, das die Auswertung von XPath ausdrücken eine hohe Komplexität hat, es werden scheinbar Listen durchlaufen. Übertragen auf relationale DBs, XPath Evaluierung entsprechen sequential Scans. Java XPath kann also nicht die Element-Adresse im Speicher berechnen, sondern muss sie suchen, indem (mehrere) Listen sequentiell durchlaufen werden.
Zusammenfassung
  1. Die Verarbeitung grosser XML Dateien mittels DOM und XPath ist ineffizient. Das gilt wahrscheinlich auch für andere DOM basieret Formate wie JSON.
  2. Jaxen XPath ist deutlich schneller als Java XML XPath für kleine und normale DOMs.
  3. Lösungen: 
    1. Alternativen wäre Streaming XML via SAX oder StAX.
    2. Wechsel von XML zu CSV.

Donnerstag, 11. Juli 2019

Die nutzloseste Software: Terraform

Terraform ist eine Software mit der man Infrastruktur as Code definiert und dies unabhängig vom Cloud Anbieter. Soweit die Idee von Terraform.

Immer wenn ein Kollege mit einem neuen Tool, Lib, Programmiersprache um die Ecke kommt, die die endgültige Erlösung aller Softwareprobleme ist, dann frage ich: "Welches Problem löst es?"

Linus Torwalds sagt mal das Subversion das sinnloseste Softwareprojekt sei (Link). Heute hat er Unrecht, das sinnloseste Softwareprojekt ist Terraform. Warum?

Terraform löst keine Probleme, Terraform ist selbst ein Problem. 

Punkt 1: Falsche Grundannahme

Die Grundannahme das nur Terraform selbst Cloud Ressourcen verändern kann, ist falsch. Das Terraform State-Handling erinnert an die Idee aus UML automatisch Code zu erzeugen und so Projekte als reines UML Konstrukt zu realisieren. Schon diese Idee scheiterte am Code Roundtrip und so scheitet Terraform an seinen eigenen States. Heute bauen wir Stateless Mikro Services und Terraform kommt mit einem komplexen State Modell daher. Wenn sich dieses State Modell von den Cloud Ressourcen unterscheidet ist Terraform und der Entwickler am Ende. Das Reparieren dieses inkonsistenten Zustandes ist kaum sinnvoll möglich. Terraform ist nicht robust. Vor allem bräuchte Terraform kein State Modell sondern nur die Referenz auf die Cloud Ressource selbst und könnte den State selbst ermitteln. Warum tun sie das nicht? Die Benutzung von Terraform schliesst alle anderen Cloud Tools und Consolen aus.

Punkt 2: Inkompatibilität

Instabile Terraform Versionen, inkompatible Konfigurationen und Plugins. Warum sind neue Terraform Versionen inkompatibel mit alten Plugins und Konfigurationen? Warum wurde nicht auf Kompatibilität geachtet? Warum wurden hier am laufenden Meter Breaking Changes implementiert?

Punkt 3: Nutzlos, kein Zusatznutzen vorhanden

Und zum Schluss, welchen Nutzen hat Terraform. Infrastruktur as Code als Code kann man bei der AWS sehr gut über die aws-cli oder andere AWS Libs realisieren. Bei Digital Ocean kann man das per Rest Calls. Jeder Cloud Anbieter hat entsprechende Schnittstellen. Diese Schnittstellen sind in der Regel hervorragend dokumentiert. Jetzt könnte man anführen, das Terraform eine Abstraktionsschicht über all diese verschiedenen Cloud Anbieter Schnittstellen legt. Das stimmt nur zum Teil weil die Terraform Features natürlich vom Provider und dem Provider Plugin abhängen. Also auch dieses Argument stimmt nicht. Dazu die Frage, wie oft wechselst du am Tag den Cloud Provider und zwischen wie vielen Cloud Providern wechselst du? Genau, Terraform löst ein Problem das gar nicht existiert! Zusätzlich verschwendet Terrafom Zeit durch seine eigenen Probleme, siehe Punkte 1 und 2. Terraform ist nutzlos und kontraproduktiv.


Noch eine kleine Anmerkung, auch vor der AWS wurde schon Infrastruktur als Code geschrieben und betrieben, damals mit BASH, SSH, SCP , DD und dem Paketmanager.

Mittwoch, 10. Juli 2019

Jeder Incident - ein neuer Test

Bad Code sind negativ Beispiele wie man nicht programmieren sollte. Aber wie macht man es dann richtig? Die Antwort ist Good Code, eine Sammlung bewährter Software Muster:

  1. Jeder Bug wird behoben und führt zu einer Code Verbesserung die über die Bug Behebung hinausgeht oder einem neuen Test.
  2. Jeder Incident führ zu einem neuen Test.

Freitag, 21. Juni 2019

Die Evolution der Datenaustausch-Formate: Binary, CSV, XML, Properties, JSON, YAML

Es gibt eine Reihe von Datenformaten für den Datenaustausch zwischen Programmen bzw. für deren Konfiguration. Hier eine Übersicht über gängige Formate, deren Vor- und Nachteile.


BinaryCSVXMLJSONYAMLProperties
Geeignet für DatenauschJaJaJaJaJaSchlecht
Geeignet für KonfigurationNeinNeinJaJaJaJa
Verständlichkeit beim Lesen für den EntwicklerNeinGutGutSehr gutSehr gutSehr gut
SpeichereffizienzSehr gutGut bis Sehr gutSehr SchlechtSchlechtGutSchlecht
Unetrsctüzung in der BASHNeinSehr gutGutGutSchlechtSehr gut
Parser GeschwindigkeitSehrt hochHochGeringGeringGeringHoch
NachteileEingeschränkte Kompatibilität


Kein Kommentare


Vorteile

Sehr hohe VerbreitungSchema Definition



Dienstag, 18. Juni 2019

Was ist die optimale Sprint Länge in SCRUM?

Die klassische Zeitspanne eines SCRUM Sprints sind 4 Wochen. In meinen letzten Projekten wurde die Sprintdauer auf 2 Wochen genutzt. Die Idee den 2 Wochen Sprints war, durch kürze Iterationen soll das Produkt zielgenauer für den Kunden entwickelt werden. Die Idee ist gut und funktioniert auch.

Leider gibt es auch Nachteile dieser kurzen Sprints. Hier die typischen Symptome, wenn die Sprints zu kurz sind:

  1. Die Sprint Velocity springt extrem, weil 95% fertige Stories in den nächsten Sprint kommen.
  2. Auch kurze Ausfälle von Software Entwicklern sind deutliche in der Sprint Velocity zu erkennen.
  3. Dies führ aus Sicht der Project Owner zu einer schlechten Planbarkeit und Frustration.
Wenn diese Symptome wiederholt Auftreten, verlängert die Sprintdauer, Frust bei den Project Owner und beim Entwickler Team wird abgebaut und vermieden.

Die optimale Sprintlänge ist die kürzeste Zeitspanne, die euch ermöglicht eine stabile Menge an Features an den Kunden auszuliefern. Dann habt ihr die Balance zwischen Planbarkeit und zielorientiertem Arbeiten und Performance erreicht.

Der oft hervorgebracht Kritikpunkt, aber die anderen Teams arbeiten im z.B. 2 Wochen Sprint Takt, ist irrelevant, weil die Teams unabhängig arbeiten und unabhängig ihr Produkt-Increment deployen.

Vertikalisierung der Softwareentwicklung und Micro Services

Die Vertikalisierung der Softwareentwicklung ist ein erfolgreiche Modell für die Skalierung der Softwareentwicklung. Dabei betreut ein Entwicklerteam eine Kunden-Domäne und entwickelt die Software für diese Domäne autonom. Dies wird gerne durch das Share Nothing Prinzip umgesetzt. Das Entwicklerteam kann ohne Rücksicht auf andere Teams, also ohne Abstimmungsaufwand und Meeting-Marathons die Software für die Kunden-Domäne entwickeln. Dies spart Zeit und bring schnell gute Erfolge, es ist sehr effizient.

Vertikalisierung führt oft dazu, das das Team die Kunden-Domäne als einen Micro Service umsetzt. In der Praxis stösst dieses Vorgehen: eine Domäne, ein Team, ein Micro Service, recht schnell an seine Grenzen. Der Grund ist die Komplexität dieses fetten Micro Services, der verscheiden Aufgaben erfüllt. Oft kommt es zu komplexen Deployments, weil der fette Micro Service in verscheiden Funktionen deployed wird, z.B. zur Datenversorgung und Kunden-App. Aus meiner Erfahrung ist das Deployment und der Betrieb sehr komplex und führt zu zusätzlichen Fehlern. Ein Codebasis führt zu funktional unterschiedlichen Micro Services, die durch Konfiguration unterschieden werden. Diese funktional unterschiedlichen Micro Services sind nicht unabhängig von einander. Es kann zu fehlerhaften Konstellationen kommen, oft hilft nur eine gezieltes Überwachen des Betriebes diese Klasse von neuen Fehlern zu erkennen. D.h. wir haben eine neue Klasse von Runtime Fehlern, die schwerer zu erkennen sind und dazu noch sehr spä erkannt werden. Diese Fehler sind erst nach dem Deployment erkennbar. Dann ist der Service für den Kunden aber schon gestört. Oder aus einer anderen Perspektive, wenn wir die 12 Factors App Kriterien heranziehen, wäre dies ein Bruch mit dem Faktor 1!

Eine erfolgreiche Alternative ist es aus diesen fetten Micro Service in einzelne kleine, in sich geschlossene, Micro Services zu zerlegen. Zum Beispiel kann man die Datenversorgung von der Bearbeitung von Kundenrequest trennen. Oft wird als Gegenargument angeführt, das es gemeinsamen Code gäbe. In der Praxis hat sich gezeigt, das die Menge des gemeinsamen Codes sehr gering ist. Das Problem des gemeinsame Codes kann bei Bedarf über Bibliothek gelöst werden.

Zusammengefasst die Vorteile der Zerlegung von fetten Micro Services einer Vertikalen in schlanke Micros Services:

  • Vereinfachung des Deployments
  • Vereinfachte Konfigurationen
  • Keine Fehler durch Fehlkonfigurationen, die Instanzen der Applikation sind unabhängig voneinander
  • Höhere Robustheit, Fehler in einem Micro Service stört nicht die gesamte Applikation, so führt der Ausfall der Datenversorgung nicht dazu das der Kunde nicht mehr bedient wird
  • Ein negativen Performance-Einflüsse durch Daten-Imports oder Wartungsjobs.
  • Bessere Wartbarkeit, Codebasis beleibt schlank und übersichtlich

Mittwoch, 12. Juni 2019

Bad Developer

Über schlechten Code gibt es viel zu Lesen. Aber es gibt nicht nur Bad Code und Clean Code sondern auch Bad Developer. Hier eine Episode aus meinem Alltag als Softwareentwickler.


Gestern im SCRUM Planungsmeeting.

Softwareentwickler Jack: "Ich bin hier nicht um zu programmieren, ... "

Ich: ??? (fassungslos)


Im Nachhinein hatte der Entwickler Jack sogar recht, er hat innerhalb von über zwei Monaten keinen einzigen Story-Punkt abgearbeitet. Die Frage, warum bezahlt der Kunde für solche Softwareentwickler? Um die die Sache zu verschlimmern arbeitet der Entwickler keine Stories ab sondern er raubt auch noch den anderen Entwicklern die Zeit. Ein absolutes Minusgeschäft.


Hier mal als O-Ton von der Velocity, was für ein Unterschied in mentalen Einstellung.

"There are only two things your organization should be spending time on: making your customers happy, or making your people happy.". -@lizthegrey at o11y meetup. #velocityconf

Freitag, 7. Juni 2019

Datenschutz: Es dürfen keine persönlichen Daten geloggt werden.

Ein Hauptquelle für das Exponieren von persönlichen Daten ist das Logging. Programmierer loggen einfach Objekt zu Debug-Zwecken oder in Fehlerfall. Diese Daten landen in Log-Dateien oder im ELK Stack. Dort gehören sie nicht hin.

Hier ein Weg dies zu verhindern. Für das Logging wird in der der Regel die toString() Methode in Java benutzt. Diese muss man bei allen Klassen deren Objekte persönlich Daten enthalten überschreiben. Hier ein Beispiel:

    @Override
    public String toString() {
        return "DATENSCHUTZ";
    }
    

Mit diesem einfachen Overwrite der toString() Methode verhindert man das persönliche Daten geloggt werden und gleichzeitig kann man die Verwendung potentiell kritischer Aufrufe im Log finden und diese Stellen entfernen. Bei Bedarf sollte man auch die Methode asString() genauso überschreiben.

Donnerstag, 4. April 2019

Konferenz: Chaos Engineering Day 2019 NYC

Es war episch. Prima Talks und tolle Gespräche. Vielen Dank an die Organisatoren und Sponsoren: Casey, NC1, Workbench und Netflix. Beim nächsten Mal, gibt es eine Talk von mir.




Freitag, 11. Januar 2019


  1. Integrate Jacoco into your Maven pom.xml.
  2. Add into your file .gitlab-ci.ymlecho -n "Total:" ; cat target/site/jacoco/index.html | grep -o 'Total[^%]*%' | grep -o -E '[0-9]+%$
  3. Add Badge in Gitlab under Setting.
  4. Gitlab scann the console for the Regex you given in Point 3.

Then you you've got this nice Gitlab Test coverage Badge.