PHP Anwendungen mit Redis Beschleunigen

  • [English en] This article is only visible for logged in Patreons. With your Patreon membership you help me to keep this page up to date.
  • [Deutsch de] Dieser Artikel ist nur für eingeloggte Patreons sichtbar. Mit ener Patreon Mitgliedschaft helft Ihr mir diese Seite stets aktuell zu halten.
  • [Español es] Este artículo sólo es visible para los Patreons registrados. Con tu suscripción a Patreon me ayudas a mantener esta página actualizada.
To view this content, you must be a member of Elmar's Patreon at $2.99 USD or more
Already a qualifying Patreon member? Refresh to access this content.

Konfigurationsdateien in Softwareanwendungen

Wieso benötigen wir überhaupt die Möglichkeit Konfigurationen einer Anwendung in Textdateien zu speichern? Genügt nicht einfach eine Datenbank für diesen Zweck? Die Anwort auf diese Frage ist recht trivial. Denn die Information wie sich eine Anwendung mit einer Datenbank verbinden kann lässt sich ja schlecht in der Datenbank selbst speichern.

Jetzt könnte man sicher argumentieren das man solche Dinge mit einer integrierten Datenbank (embedded) wie beispielsweise SQLlite hinbekommt. Das mag auch grundsätzlich korrekt sein. Leider ist diese Lösung für hoch skalierbare Anwendungen nicht wirklich praktikabel. Zudem muss man nicht immer gleich mit Kanonen auf Spatzen schießen. Das Speichern wichtiger Konfigurationsparameter in Textdateien hat bereits eine lange Tradition in der Softwareentwicklung. Mittlerweile haben sich aber auch verschiedene Textformate wie INI, XML, JSON und YAML für diesen Anwendungsfall etabliert. Aus diesem Grund stellt sich die Frage auf welches Format man am besten für das eigene Projekt zurück greifen sollte.

INI Dateien

Eines der ältesten Formate sind die bekannten INI Dateien. Sie speichern Informationen nach dem Schlüssel = Wert Prinzip. Wenn ein Schlüssel in solch einer INI Datei mehrfach vorkommt wird der finale Wert immer durch den zuletzt in der Datei vorkommenden Wert überschrieben.

; Example of an INI File
[Section-name]
key=value ; inline

text="text configuration with spaces and \' quotas"
string='can be also like this'
char=passwort

# numbers & digets
number=123
hexa=0x123
octa=0123
binary=0b1111
float=123.12

# boolean values
value-1=true
value-0=false
INI

Wie wir in dem kleinen Beispiel sehen können ist die Syntax in INI Dateien sehr einfach gehalten. Der Sektionsname [section] dient vor allem der Gruppierung einzelner Parameter und verbessert die Lesbarkeit. Kommentare können entweder durch ; oder # gekennzeichnet werden. Ansonsten gibt es die Möglichkeit verschiedene Text- und Zahlen-Formate, sowie Boolean-Wert zu definieren.

Web Entwickler kennen INI Files vor allem von der PHP Konfiguration, der php.ini in der wichtige Eingenschaften wie die Größe des Datei-Uploads festgelegt werden kann. Auch unter Windows sind INI Dateien noch immer verbreitet, obwohl seit Windows 95 für diesen Zweck die Registry eingeführt wurde.

Properties

Eine andere sehr bewährte Lösung sind sogenannte property Files. Besonders verbreitet ist diese Lösung in Java Programmen, da Java bereits eine einfache Klasse mitbringt die mit Properties umgehen kann. Das Format key=value ist den INI Dateien entlehnt. Kommentare werden ebenfalls mit # eingeleitet.

# PostgreSQL
hibernate.dialect.database = org.hibernate.dialect.PostgreSQLDialect
jdbc.driverClassName = org.postgresql.Driver
jdbc.url = jdbc:postgresql://127.0.0.1:5432/together-test
Plaintext

Um in Java Programmen beim Einlesen der .propreties auch die Typsicherheit zu gewährleisten hat die Bibliothek TP-CORE eine erweiterte Implementierung. Trotz das die Properties als Strings eingelesen werden kann auf die Werte mittels Typisierung zugegriffen werden. Eine ausführliche Beschreibung wie die Klasse PropertyReader verwendet werden kann findet sich in der Dokumentation.

Auch im Maven Build Prozess können .property Dateien als Filter für Substitutionen genutzt werden. Selbstredend sind Properties nicht nur auf Maven und Java beschränkt. Auch in Sprachen wie Dart, nodeJS, Python und Ruby ist diese Konzept nutzbar. Um eine größtmögliche Kopatibilität der Dateien zwischen den verschiedene Sprachen zu gewährleisten, sollten exotische Optionen zur Notation vermieden werden.

XML

XML ist seit vielen Jahren auch eine weit verbreitete Option Konfigurationen in einer Anwendung veränderlich zu speichern. Gegenüber INI und Property Dateien bietet XML mehr Flexibilität in der Definition der Daten. Ein sehr wichtiger Aspekt ist die Möglichkeit fixe Strukturen über eine Grammatik zu definieren. Dies erlaubt eine Validierung auch für sehr komplexe Daten. Dank der beiden Prüfmechanismen Wohlgeformtheit und Datenvalidierung gegen eine Grammatik lassen sich mögliche Konfigurationsfehler erheblich reduzieren.

Bekannte Einsatzszenarien für XML finden sich beispielsweise in Java Enterprise Projekten (J EE) mit der web.xml oder der Spring Framework und Hibernate Konfiguration. Die Mächtigkeit von XML gestattet sogar die Nutzung als Domain Specific Language (DSL) wie es bei dem Build Werkzeug Apache Maven zum Einsatz kommt.

Dank vieler frei verfügbarer Bibliotheken existiert für nahezu jede Programmiersprache eine Implementierung um XML Dateien einzulesen und gezielt auf Daten zuzugreifen. Die bei Web Entwicklern beliebte Sprache PHP hat zum Beispiel mit der Simple XML Erweiterung einen sehr einfache und intuitive Lösung um mit XML umzugehen.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/assembly/ApplicationContext.xml</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>${jsf.project.stage}</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>
XML

JSON

JavaScript Object Notation oder kurz JSON ist eine vergleichsweise neue Technik, obwohl diese mittlerweile auch schon einige Jahre existiert. Auch JSON hat für nahezu jede Programmiersprache eine entsprechende Implementierung. Das häufigste Einsatzszenario für JSON ist der Datentausch in Microservices. Der Grund liegt in der Kompaktheit von JSON. Gegenüber XML ist der zu übertragene Datenstrom in Webservices wie XML RPC oder SOAP mit JSON auf Grund der Notation wesentlich geringer.

Ein signifikanter Unterschied zwischen JSON und XML besteht aber auch im Bereich der Validierung. Grundsätzlich findet sich auf der offiziellen Homepage [1] zu JSON keine Möglichkeit eine Grammatik wie in XML mit DTD oder Schema zu definieren. Auf GitHub existiert zwar ein Proposal zu einer JSON Grammatik [2] hierzu fehlen aber entsprechende Implementierungen um diese Technologie auch in Projekten einsetzen zu können.

Eine Weiterentwicklung zu JSON ist JSON5 [3] das bereits 2012 begonnen wurde und als Spezifikation in der Version 1.0.0 [4] seit dem Jahr 2018 offiziell veröffentlicht ist. Zweck dieser Entwicklung war es die Lesbarkeit von JSON für Menschen erheblich zu verbessern. Hier wurden wichtige Funktionen wie beispielsweise die Möglichkeit Kommentare zu schreiben hinzugefügt. JSON5 ist als Erweiterung vollständig zu JSON kompatibel. Um einen kurzen Eindruck zu JSON5 zu gewinnen hier ein kleines Beispiel:

{
  // comments
  unquoted: 'and you can quote me on that',
  singleQuotes: 'I can use "double quotes" here',
  lineBreaks: "Look, Mom! \
No \\n's!",
  hexadecimal: 0xdecaf,
  leadingDecimalPoint: .8675309, andTrailing: 8675309.,
  positiveSign: +1,
  trailingComma: 'in objects', andIn: ['arrays',],
  "backwardsCompatible": "with JSON",
}
JSON5

YAML

Viele moderne Anwendungen wie zum Beispiel das Open Source Metrik Werkzeug Prometheus nutzen YAML zur Konfiguration. Die sehr kompakte Notation erinnert stark an die Programmiersprache Python. Aktuell ist YAML in der Version 1.2 veröffentlicht.

Der Vorteil von YAML gegenüber anderen Spezifikationen ist die extreme Kompaktheit. Gleichzeitig besitzt die Version 1.2 eine Grammatik zu Validierung. Trotz der Kompaktheit liegt der Fokus von YAML 1.2 in einer guten Lesbarkeit für Maschinen als auch Menschen. Ob YAML diese Ziel erreicht hat überlasse ich jedem selbst zu entscheiden. Auf der offiziellen Homepage findet man alle Ressourcen die für eine Verwendung im eigenen Projekt benötigt werden. Dazu zählt auch eine Übersicht zu den vorhandenen Implementierungen. Das Design der YAML Homepage gibt auch schon eine guten Vorgeschmack auf die Übersichtlichkeit von YAML Dateien. Anbei noch ein sehr kompaktes Beispiel einer Prometheus Konfiguration in YAML:

global:
  scrape_interval:     15s
  evaluation_interval: 15s

rule_files:
  # - "first.rules"
  # - "second.rules"

#IP: 127.0.0.1
scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ['127.0.0.1:8080']

  # SPRING BOOT WEB APP
  - job_name: spring-boot-sample 
    scrape_interval: 60s
    scrape_timeout: 50s
    scheme: "http"
    metrics_path: '/actuator/prometheus' 
    static_configs:
     - targets: ['127.0.0.1:8888']
    tls_config:
     insecure_skip_verify: true
YAML

Resumee

Alle hier vorgestellten Techniken sind im paktischen Einsatz in vielen Projekten erprobt. Sicher mag es für spezielle Anwendungen wie REST Services einige Präferenzen geben. Für meinen persönlichen Geschmack bevorzuge ich für Konfigurationsdateien das XML Format. Dies ist leicht im Programm zu verarbeiten, extrem flexibel und bei geschickter Modellierung auch kompakt und hervorragend für Menschen lesbar.

Referenzen

Ruby: die Entwicklungsumgebung einrichten

Ruby ist seit vielen Jahren eine sehr etablierte Programmiersprache, die durchaus auch Anfängern empfohlen werden kann. Ruby folgt dem objektorientierten Paradigma und enthält sehr viele Konzepte um OOP gut zu unterstützen. Außerdem lassen sich dank dem Framework Ruby on Rails sehr leicht komplexe Webanwendungen entwickeln.

Die schwierigste Hürde beim Einstieg in Ruby die es zu meistern gilt, ist die Installation der gesamten Entwicklungsumgebung. Aus diesem Grund habe ich dieses kurze Tutorial zum Einstieg mit Ruby verfasst. Beginnen wir daher auch gleich mit der Installation.

Mein Betriebssystem ist ein Debian 12 Linux und Ruby lasst sich sehr einfach mit der Anweisung sudo apt-get install ruby-full installieren. Dieses Vorgehen kann auf alle Debian basierte Linux Distributionen wie z. B. Ubuntu übertragen werden. Anschließend kann mit ruby -v der Erfolg in der Bash überprüft werden.

ed@:~$ ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu]
Bash

Wenn wir nun dem Tutorial auf der Ruby on Rails Homepage folgen und das Rails Framework über gem rails installieren wollen stoßen wir bereits auf das erste Problem. Wegen fehlender Berechtigungen lassen sich keine Bibliotheken für Ruby installieren. Nun konnten wir auf die Idee kommen die Bibliotheken als Superuser mit sudo zu installieren. Dies Losung ist leider nur temporär und verhindert das später in der Entwicklungsumgebung die Bibliotheken korrekt gefunden werden. Besser ist es ein Ordner für die GEMs im home Verzeichnis des Nutzers anzulegen und dies über eine Systemvariable bereitzustellen.

export GEM_HOME=/home/<user>/.ruby-gems

export PATH=$PATH:/home/<user>/.ruby-gems

Die oben stehende Zeile ist an das Ende der Datei .bashrc einzutragen, damit die Änderungen auch persistent bleiben. Wichtig ist das <user> gegen den richtigen Nutzernamen ausgetauscht wird. Den Erfolg dieser Aktion lasst sich über gem environment überprüfen und sollte eine ähnliche Ausgabe wie nachstehend ergeben.

ed@:~$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 3.3.15
  - RUBY VERSION: 3.1.2 (2022-04-12 patchlevel 20) [x86_64-linux-gnu]
  - INSTALLATION DIRECTORY: /home/ed/.ruby-gems
  - USER INSTALLATION DIRECTORY: /home/ed/.local/share/gem/ruby/3.1.0
  - RUBY EXECUTABLE: /usr/bin/ruby3.1
  - GIT EXECUTABLE: /usr/bin/git
  - EXECUTABLE DIRECTORY: /home/ed/Programs/gem-repository/bin
  - SPEC CACHE DIRECTORY: /home/ed/.local/share/gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /etc
  - RUBYGEMS PLATFORMS:
     - ruby
     - x86_64-linux
  - GEM PATHS:
     - /home/ed/Programs/gem-repository
     - /home/ed/.local/share/gem/ruby/3.1.0
     - /var/lib/gems/3.1.0
     - /usr/local/lib/ruby/gems/3.1.0
     - /usr/lib/ruby/gems/3.1.0
     - /usr/lib/x86_64-linux-gnu/ruby/gems/3.1.0
     - /usr/share/rubygems-integration/3.1.0
     - /usr/share/rubygems-integration/all
     - /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - /home/ed/.local/bin
     - /usr/local/bin
     - /usr/bin
     - /bin
     - /usr/local/games
     - /usr/games
     - /snap/bin
     - /home/ed/Programs/maven/bin
     - /usr/share/openjfx/lib
- /home/ed/.local/bin
Bash

Mit dieser Einstellung lassen sich nun ohne Schwierigkeiten Ruby GEMs installieren. Das probieren wir auch gleich aus und installieren das Ruby on Rails Framework, was uns bei der Entwickelung von Webapplikationen unterstützt: gem install rails. Dies sollte nun ohne Fehlermeldungen durchlaufen und mit dem Kommando rails -v sehen wir ob wir erfolgreich waren.

Im nachsten Schritt konnen wir nun ein neues Rails Projekt anlegen. Hier bediene ich mich dem Beispiel aus der Ruby on Rails Dokumenmtation und schreibe in die Bash: rails new blog. Dies erzeugt ein entsprechendes Verzeichnis namens blog mit den Projektdateien. Nachdem wir in das Verzeichnis gewechselt sind müssen wir noch alle Abhängigkeiten installieren. Das geschieht über: bundle install.

Hier stoßen wir nun auf ein weiteres Problem. Die Installation lasst sich nicht beenden weil es anscheinend ein Problem mit der Bibliothek psych gibt. Das tatsachliche Problem ist allerdings, dass auf der Betreibssystem Ebene die Unterstützung fur YAML Dateien fehlt. Das lasst sich sehr schenll beheben in dem das YAML Paket nachinstalliert wird.

sudo apt-get install libyaml-dev

Das Problem mit psych bei Ruby on Rails besteht schon eine Weile und ist mit der YAML Installation behoben so, dass nun auch die Anweisung bundle install erfolgreich durchlauft. Jetzt sind wir auch in der Lage den Server fur die Rails Anwendung zu starten: bin/rails server.

ed@:~/blog$ bin/rails server
=> Booting Puma
=> Rails 7.1.3.3 application starting in development 
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.2 (ruby 3.1.2-p20) ("The Eagle of Durango")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 12316
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
Bash

Rufen wir nun im Webbrowser die URL http://127.0.0.1:3000 auf sehen wir unser Rails Webanwendung.

Mit diesen Schritten haben wir nun eine funktionierende Ruby Umgebung auf unserem System erstellt. Nun ist es an der Zeit sich für eine geeignete Entwicklungsumgebung zu entscheiden. Wer nur gelegentlich ein paar Scripte anpasst dem genügen VIM und Sublime Text als Editoren. Fur komplexe Software Projekte sollte wiederum auf eine vollstandige IDE zurückgegriffen werden, da dies die Arbeit erheblich vereinfacht. Die beste Empfehlung ist die kostenpflichtige IDE RubyMine von JetBrains. Wer Ruby Open Source Projekte als Entwickler unterstützt kann eine kostenfreie Lizenz beantragen.

Eine frei verfügbare Ruby IDE ist VSCode von Microsoft. Hier müssen aber zunächst ein paar Plugins eingebunden werden und für meine Geschmack ist VSCode auch nicht sehr intuitiv. Ruby Integration für die klassischen Java IDEs Eclipse und NetBeans sind recht veraltet und nur mit sehr viel Mühe zum Laufen zu bekommen.

Damit haben wir auch schon alle wichtigen Punkte die notwendig sind eine funktionierende Ruby Umgebung auf dem eigenen System einzurichten besprochen. Ich hoffe mit diesem kleine Workshop die Einstiegshürde zum Erlernen von Ruby erheblich gesenkt zu haben. Wenn Ihr diesen Artikel mögt freue ich mich über ein Like und die Weiterempfehlung an eure Freunde.

PHP 8 und GDLib im Docker Container

  • [English en] This article is only visible for logged in Patreons. With your Patreon membership you help me to keep this page up to date.
  • [Deutsch de] Dieser Artikel ist nur für eingeloggte Patreons sichtbar. Mit ener Patreon Mitgliedschaft helft Ihr mir diese Seite stets aktuell zu halten.
  • [Español es] Este artículo sólo es visible para los Patreons registrados. Con tu suscripción a Patreon me ayudas a mantener esta página actualizada.
To view this content, you must be a member of Elmar's Patreon at $2.99 USD or more
Already a qualifying Patreon member? Refresh to access this content.

Stumblin’In; Arbeiten mit Internationale Teams

  • [English en] This article is only visible for logged in Patreons. With your Patreon membership you help me to keep this page up to date.
  • [Deutsch de] Dieser Artikel ist nur für eingeloggte Patreons sichtbar. Mit ener Patreon Mitgliedschaft helft Ihr mir diese Seite stets aktuell zu halten.
  • [Español es] Este artículo sólo es visible para los Patreons registrados. Con tu suscripción a Patreon me ayudas a mantener esta página actualizada.
To view this content, you must be a member of Elmar's Patreon at $2.99 USD or more
Already a qualifying Patreon member? Refresh to access this content.

Die dunkle Seite der künstlichen Intelligenz

Als Techniker bin ich recht schnell von allen möglichen Dingen zu begeistern, die irgendwie blinken und piepsen, ganz gleich, wie unnütz diese auch sein mögen. Elektronikspielereien ziehen mich an, wie das Licht Motten. Seit einer Weile ist eine neue Generation Spielwaren für die breite Masse verfügbar: Anwendungen der Künstlichen Intelligenz, genauer gesagt künstliche neuronale Netze. Die frei verfügbaren Anwendungen leisten bereits Beachtliches und es ist erst der Anfang dessen, was noch möglich sein wird. Vielen Menschen ist die Tragweite KI-basierter Anwendungen noch gar nicht bewusst geworden. Das ist auch nicht verwunderlich, denn das, was gerade im Sektor KI geschieht, wird unser Leben nachhaltig verändern. Wir können also zu Recht sagen, dass wir in einer Zeit leben, die gerade Geschichte schreibt. Ob die kommenden Veränderungen etwas Gutes werden, oder sie sich als eine Dystopie entpuppen, wird an uns liegen.

java Aktuell 2024.01

Als ich im Studium vor sehr vielen Jahren als Vertiefungsrichtung Künstliche Intelligenz gewählt hatte, war die Zeit noch von sogenannten „Expertensystemen“ geprägt. Diese regelbasierten Systeme waren für ihre Domäne hochspezialisiert und wurden für entsprechende Experten ausgelegt. Das System sollte die Experten bei der Entscheidungsfindung unterstützen. Mittlerweile haben wir auch die notwendige Hardware, um viel allgemeinere Systeme zu schaffen. Wenn wir Anwendungen wie ChatGPT betrachten, basieren diese auf neuronalen Netzen, was eine sehr hohe Flexibilität in der Verwendung erlaubt. Der Nachteil ist allerdings, dass wir als Entwickler kaum noch nachvollziehen können, welche Ausgabe ein neuronales Netz für eine beliebige Eingabe erzeugt. Ein Umstand, der die meisten Programmierer, die ich kenne, eher eine ablehnende Haltung einnehmen lässt, da diese so nicht mehr Herr über den Algorithmus sind, sondern nur noch nach dem Prinzip Versuch und Irrtum agieren können.

Dennoch ist die Leistungsfähigkeit neuronaler Netze verblüffend. Vorbei scheint nun die Zeit, in der man sich über unbeholfene, automatisierte, Software-gestützte Übersetzungen lustig machen kann. Aus eigener Erfahrung weiß ich noch, wie mühselig es war, den Google Translator aus dem Deutschen einen vernünftigen Satz ins Spanische übersetzen zu lassen. Damit das Ergebnis brauchbar war, konnte man sich über die Option Englisch – Spanisch behelfen. Alternativ, wenn man nur ein rudimentäres Englisch für den Urlaubsgebrauch spricht, konnte man noch sehr einfache deutsche Sätze formulieren, die dann wenigsten inhaltlich korrekt waren. Die Zeitersparnis für automatisiert übersetzte Texte ist erheblich, obwohl man diese Korrektur lesen muss und gegebenenfalls ein paar Formulierungen angepasst werden müssen.

So sehr ich es schätze, mit solchen starken Werkzeugen arbeiten zu können, müssen wir uns aber auch im Klaren sein, dass es auch eine Schattenseite gibt. Denn je mehr wir unserer täglichen Aufgaben über KI-gestützte Tools erledigen, umso mehr verlieren wir die Fähigkeit, diese Aufgaben künftig weiterhin manuell bearbeiten zu können. Für Programmierer bedeutet dies, dass sie im Laufe der Zeit über KI-gestützte IDEs ihre Ausdrucksfähigkeit im Quellcode verlieren. Das ist natürlich kein Prozess, der über Nacht stattfindet, sondern sich schleichend einstellt. Aber sobald diese Abhängigkeit einmal geschaffen ist, stellt sich die Frage, ob die verfügbaren, liebgewonnenen Werkzeuge weiterhin kostenfrei bleiben oder, ob für bestehende Abonnements möglicherweise drastische Preiserhöhungen stattfinden. Denn es sollte uns schon klar sein, das kommerziell genutzte Werkzeuge, die unsere Produktivität erheblich verbessern, üblicherweise nicht zum Schnäppchenpreis verfügbar sind.

Ich denke auch, dass das Internet, wie wir es bisher gewohnt sind, sich in Zukunft sehr stark verändern wird. Viele der kostenlosen Angebote, die bisher durch Werbung finanziert sind, werden mittelfristig verschwinden. Schauen wir uns dazu einmal als Beispiel den Dienst „Stack Overflow“ an – in Entwicklerkreisen eine sehr beliebte Wissensplattform. Wenn wir nun künftig für die Recherche zu Fragestellungen der Programmierung ChatGPT oder andere neuronale Netze nutzen, sinken für Stack Overflow die Besucherzahlen kontinuierlich. Die Wissensbasis wiederum, die ChatGPT nutzt, basiert auf Daten von öffentlichen Foren wie Stack Overflow. Somit wird auf absehbare Zeit Stack Overflow versuchen, seine Dienste für KIs unzugänglich zu machen. Es könnte sicher auch eine Einigung mit Ausgleichszahlungen zu Stande kommen, sodass die wegfallenden Werbeeinnahmen kompensiert werden. Denn als Techniker muss uns nicht ausschweifend dargelegt werden, dass für ein Angebot wie Stack Overflow erhebliche Kosten für den Betrieb und die Entwicklung anfallen. Es bleibt dann abzuwarten, wie die Nutzer das Angebot künftig annehmen werden. Denn wenn auf Stack Overflow keine neuen Daten zu Problemstellungen hinzukommen, wird die Wissensbasis für KI-Systeme auch uninteressant. Daher vermute ich, dass bis zirka 2030 vor allem hochwertige Inhalte im Internet kostenpflichtig werden.

Wenn wir die Prognose des mittelfristigen Trends über den Bedarf von Programmierern betrachten, kommen wir zu der Frage, ob es künftig eine gute Empfehlung sein wird, Informatik zu studieren oder eine Ausbildung als Programmierer anzutreten. Ich sehe hier tatsächlich eine positive Zukunft und würde jedem, der eine Ausbildung als Berufung versteht und nicht als Notwendigkeit ansieht, seinen Lebensunterhalt zu bestreiten, in seinem Vorhaben bekräftigen. Meiner Ansicht nach werden wir weiterhin viele innovative Köpfe benötigen. Lediglich jene, die sich anstatt sich mit Grundlagen und Konzepten zu beschäftigen, lieber mal schnell ein aktuelles Framework erlernen wollen, um aufkommende Hypes des Marktes mitzunehmen, werden sicher nur noch geringen Erfolg in Zukunft erzielen. Diese Beobachtungen habe ich aber auch bereits vor der breiten Verfügbarkeit von KI-Systemen machen können. Deshalb bin ich der festen Überzeugung, dass sich langfristig Qualität immer durchsetzen wird.

Dass man sich stets Themen möglichst kritisch und aufmerksam nähern sollte, betrachte ich als eine Tugend. Dennoch muss ich sagen, dass so manche Ängste im Umgang mit KI recht unbegründet sind. Sie haben ja schon einige meiner möglichen Zukunftsvisionen in diesem Artikel kennengelernt. Aussagen wiederum, dass die KI einmal unsere Welt übernehmen wird, indem sie unbedarfte Nutzer subtil beeinflusst, um diese zu Handlungen zu motivieren, halte ich für einen Zeitraum bis 2030 eher für reine Fantasie und mit dem aktuellen Erkenntnisstand unbegründet. Viel realistischer sehe ich das Problem, dass findige Marketingleute das Internet mit minderwertigen, ungeprüften, nicht redigierten, KI-generierten Artikeln übersähen, um ihr SEO-Ranking aufzupeppen und diese wiederum als neue Wissensbasis der neuronalen Netze die Qualität künftiger KI-generierter Texte erheblich reduziert.

Die bisher frei zugänglichen KI-Systeme haben gegenüber dem Menschen einen entscheidenden Unterschied. Ihnen fehlt die Motivation, etwas aus eigenem Antrieb zu tun. Erst durch eine extrinsische Anfrage durch den Nutzer beginnt die KI, eine Fragestellung zu bearbeiten. Interessant wird es dann, wenn eine KI sich aus eigenem Antrieb heraus selbstgewählten Fragestellungen widmet und diese auch eigenständig recherchiert. In diesem Fall ist die Wahrscheinlichkeit sehr hoch, dass die KI sehr schnell ein Bewusstsein entwickeln wird. Läuft eine solche KI dann noch auf einem Hochleistungsquantencomputer, haben wir nicht genügend Reaktionszeit, um gefährliche Entwicklungen zu erkennen und einzugreifen. Daher sollten wir uns durchaus das von Dürrenmatt geschaffene Drama „Die Physiker “ in unserem Bewusstsein halten. Denn die Geister, die ich einmal rief, werde ich möglicherweise nicht so schnell wieder los.

Grundsätzlich muss ich zugeben, dass mich das Thema KI weiterhin fasziniert und ich auf die künftige Entwicklung sehr gespannt bin. Dennoch finde ich es wichtig, auch vor der dunklen Seite der Künstlichen Intelligenz den Blick nicht zu versperren und dazu einen sachlichen Diskurs zu beginnen, um möglichst schadenfrei das vorhandene Potenzial dieser Technologie auszuschöpfen.

Linux verstehen: die Wiederentdeckung der Freude an Technologie

Seit Windows 10 verlieren Nutzer mehr und mehr die Kontrolle über ihre Systeme. Das Schlüsselwort ist Governance (oder besser Bevormundung), wo Unternehmen versuchen, ihre Nutzer zu erziehen. Keine Sorge, ich werde keine große Rede über die Willensfreiheit und die bösen Tech-Unternehmen halten. In diesem Artikel gebe ich Ihnen die Möglichkeit, die Kontrolle über Ihr Computergerät zurückzugewinnen. Verabschieden Sie sich von Microsoft und Windows und beginnen Sie Ihre Reise mit Linux.

Um das Jahr 2015 herum fasste ich den Entschluss, mich von Microsoft Windows zu lösen und zu 100% auf Linux umzusteigen. Ich hatte zu diesem Zeitpunkt bereits einige Erfahrungen mit Linux auf der Serverseite. Aber Linux täglich auf dem Desktop für alle Aufgaben zu verwenden, war eine neue Herausforderung, denn die Dinge sind nicht gleich. So verbrachte ich rund 4 Wochen und mehrere Versuche damit, eine Linux-Desktop-Distribution zu finden, die am besten zu meinen Bedürfnissen passt. Die Dinge, auf die man achten muss, um das beste Ergebnis für sich selbst zu erzielen, sind die Verfügbarkeit eines riesigen Software-Repositorys, aus dem man alle Anwendungen beziehen kann, die man braucht. Ein weiterer wichtiger Punkt ist das Aussehen und die Bedienung des Desktops. Auch hier gibt es mehrere Optionen, aus denen man auswählen kann. Bevor ich einen kurzen Überblick über Distributionen und Desktops gebe, muss ich das Problem der Softwareversionen und Repositories erklären.

Ein Software-Repository ist einfach ein großer Speicher, in dem die Binärdateien und Installationsprogramme für Ihre Anwendung abgelegt sind. Wenn Sie sich für eine Distribution und eine bestimmte Version entschieden haben, haben Sie ein definiertes Repository, in dem Sie Ihre Software und Distributions-Updates erwerben können. Nehmen wir an, wir haben eine Linux-Distribution mit einer Version von 2019. Der Support für diese Version läuft, sagen wir mal, bis 2020. Das bedeutet für das Software-Repository, dass die enthaltene Software nur einen Stand aus dieser Zeit enthält. Wenn Sie für diese Distribution die neueste GIMP-Version wie 2.10.36 vom November 2023 haben möchten, können Sie diese nicht aus dem ursprünglichen Distribution Repository beziehen. Die letzte Softwareversion für GIMP im ursprünglichen Repository ist die Version von 2020. Das gleiche Problem besteht bei älteren Softwareversionen. Dies ist ein sehr spezifisches Problem für Softwareentwickler und verfügbare Programmiersprachen. Wenn Sie alte PHP- oder JAVA-Anwendungen pflegen müssen, benötigen Sie ganz bestimmte Compiler und Interpreter, die möglicherweise nicht in Ihrem Software-Repository enthalten sind. Um dieses Problem zu lösen, gibt es verschiedene Lösungen. Entwickler können zum Beispiel Docker verwenden. Als normaler Benutzer können Sie versuchen, ältere oder neuere Versionen einer Software direkt vom Entwickler/Hersteller zu erhalten. Mit diesem Wissen können wir nun lernen, was eine Distribution ist und welche davon existiert.

Wenn Sie eine Linux-Distribution oder kurz Distro für sich auswählen möchten, haben Sie eine riesige Auswahl. Aber was ist eine Distro? Im Allgemeinen kann man sagen, dass ein Hersteller einen Linux-Kernel, eine Sammlung von Software und ein Repository zusammenstellt und alles mit seinem eigenen Look and Feel dekoriert. Es ist auch möglich, dass man sein eigenes Linux erstellt, einschließlich der Kompilierung eines eigenen Kernels. Aber Linux ist nicht gleich Linux. Wir müssen zwischen Linux und Unix unterscheiden. Linux ist ein Derivat von Unix, wie der Name LinUx eine Kombination aus Linus und Unix bereits vermuten lässt. Der große Unterschied zwischen Linux und Unix besteht in der Netzwerkfunktionalität, die bei Unix weiter fortgeschritten ist. Das Betriebssystem (BS) von Apple basiert beispielsweise auf Unix. Ein sehr verbreitetes Unix-Betriebssystem ist FreeBSD. BSD bedeutet Barkley Software Distribution und wird von der Barkley Universität in Kalifornien kontinuierlich weiterentwickelt.

5
Rate your favorite Linux Distribution

Daneben gibt es drei Haupt Linux-Zweige, die auch weitere Ableitungen enthalten. Als erstes gibt es das aus Deutschland stammende Suse mit dem YAST Paketmanager für den Zugriff auf die Software-Repositories. Suse 7.2 war übrigens mein erster Desktop-Test im Jahr 2002. Suse ist nicht so verbreitet. Deswegen ist es manchmal recht schwierig, für spezielle Fragen oder Probleme ausreichend Inhalte zu finden. Eine weitere Distribution kommt von Red Hat, einem Open-Source Pionier. RHEL oder Red Hat Enterprise Linux ist eine kommerzielle Linux-Serverdistribution. Der Grund dafür ist, dass ein kommerzielles Linux für Server-Produktivsystemen vorhanden ist. Mit einer RHEL-Lizenz erhalten Unternehmen von Red Hat professionelle Unterstützung in Notfällen. Der Red Hat Desktop wird nicht mehr unterstützt und wurde auf Fedora Linux gewandelt. Der Standardpaketmanager für deren Software-Repositorys ist YUM. Der letzte Zweig der wichtigsten Linux-Distributionen ist Debian mit einer großen Auswahl an Unterdistributionen. Alle beliebten Einsteiger-Distributionen wie Linux Mint, Ubuntu oder Zorin OS basieren auf Debian. Als ich 2015 auf den Linux-Desktop umgestiegen bin, habe ich mit Ubuntu Mate LTS angefangen und bin seit Ende 2023 auf Debian 12 mit einem Gnome 3-Desktop umgestiegen. Der Standardpaketmanager für Debian-Systeme ist APT. Ubuntu führte 2023 seinen eigenen SNAP Paketmanager ein.

Ein weiterer wichtiger Begriff im Linux-Universum ist der Desktop-Manager. Hier stehen zur Auswahl: KDE, Gnome, Mate, XFCE und Cinnamon. Wie meine Liste der Distributionen ist auch die Liste der verfügbaren Desktops nicht vollständig. Ich kann im Unfang dieses Artikels nur die häufigsten erwähnen. Die meisten Linux-Distributionen verfügen standardmäßig über mehrere Desktop-Manager. Sie können daher während des Anmeldevorgangs auswählen, welchen Desktop Sie verwenden möchten. So können Sie ganz einfach ausprobieren, welcher Desktop am besten zu Ihnen passt. Später, wenn Sie mehr Erfahrung haben und Ihre Wahl für Ihre tägliche Arbeit bereits getroffen haben, können Sie unerwünschte Desktops während des Installationsvorgangs abwählen, um etwas Speicherplatz zu sparen.

Das schwierigste am Anfang meines Linux-Abenteuer war es zu verstehen, wo die Dinge gespeichert werden. Beispielsweise wird Software von Drittanbietern normalerweise im Verzeichnis opt installiert. Kompliziert ist auch das Berechtigungssystem für Dateien und Verzeichnisse auf ext3/ext4. Dieses Konzept existiert nicht im Windows FAT- oder NTFS-Dateisystem. Aber keine Sorge das bekommt man recht schnell bei der täglichen Arbeit in den Griff.

Microsoft Surface 3 PRO mit Ubuntu Linux

Als ich zum ersten Mal Ubuntu ausprobierte war das etwa 2010 als der Herstelle Canonical standardmäßig den UNITY Desktop einführte. Es gefiel mir nicht, weil es viel Werbung und unerwünschte Apps wie Spotify und Facebook enthielt. Ich habe herausgefunden, dass Ubuntu eine Version mit einem Gnome Dektop-Klon namens Mate hat. Ich beschloss diesen auszuprobieren und war vom ersten Moment an begeistert. Nach der ersten Installation auf meinem Laptop im Jahr 2015 musste ich bis 2023 nur noch 2 Mal Ubuntu neu auf meinem System installieren. Der Grund dafür war, dass ich meine interne SSD zunächst gegen 1 TB und später gegenuna historia sobre el 2 TB ausgetauscht habe. Es gab keine Probleme, dass die Systeme langsamer wurden oder die Festplatte mit verwaisten Dateien zugemüllt wurde. Keine regelmäßigen Reinigungs- und Wartungsaufgaben wie sie unter Windows üblich sind. Das System funktionierte stabil und ohne schwerwiegende Abstürze. Ich hatte auch nie Probleme mit Hardwaretreibern. Alle meine neuen Komponenten wurden unter Linux immer korrekt erkannt und es gibt oft kleine Verwaltungstools. Zum Beispiel Stremdeck UI oder Noson für Sonos Lautsprecher. Als ich im Dezember 2023 meinen neuen Laptop bekam beschloss ich, von Ubuntu auf das Original Debian umzusteigen. Weil Ubuntu von einem Unternehmen gemacht wird und sie oft beschließen ihren eigenen Weg zu gehen. Wer weiß ob sie in Zukunft ein ähnliches Verhalten wie Microsoft an den Tag legen werden. Ich bevorzuge es meinen Übergang immer frühzeitig zu vollziehen ohne Druck, um vorbereitet zu sein bevor mir keine andere Wahl bleibt.

Natürlich verwende ich auf meinem System ein Antivirenprogramm und eine Firewall. Da Linux nicht vor bösen Angriffen geschützt ist, sind auch Schutzmaßnahmen erforderlich.

Viele Leute vermasseln den Wechsel von Microsoft Office zu Libre Office. Das wirkliche Geheimnis um das Layout nicht zu verlieren besteht darin, auf die Schriftarten zu achten. Wenn die MS Office-Originaldokumente die standardmäßigen Microsoft-Schriftarten verwenden, müssen diese auch auf dem Linux-Computer installiert sein. So wird das Layout des Office-Dokuments nicht zerszört.

Für mich besteht keine wirkliche Notwendigkeit, zu Windows zurückzukehren. Nun ja, ich bin auch kein Gamer aber auch dafür gibt es viele Lösungen. Steam ist zum Beispiel unter Linux verfügbar. Die meisten Leute, die ich kenne, spielen nicht einmal mehr auf PCs oder Laptops, sondern bevorzugen Konsolen wie PlayStation. Für mich ist Linux cool, weil ich die volle Kontrolle über mein System habe, es kostenlos ist und ich es nach meinen Wünschen anpassen kann. Wer einen alten Laptop besitzt, der mit Windows nicht mehr funktioniert kann versuchen Linux darauf zu installieren und das Ergebnis genießen.

Ruby: die Entwicklungsumgebung einrichten

Setzen Sie in wenigem Minuten eine Ruby Entwicklungsumgebung für die ersten Schritte mit dem Web...

Linux verstehen: die Wiederentdeckung der Freude an Technologie

Es ist an der Zeit wieder die Kontrolle über seine Hardware zu bekommen, denn um...

Tschüß Privatsphäre, Tschüß Freiheit

Je öfter wiederholt werden muss wie gut unsere Meinungsfreiheit ist um so weniger können wir...

Arbeiten mit Textdateien auf der Linux-Shell

Die Kommandozeile ist unter Linux ein mächtiges Werkzeug. In diesem Artiekl lernen Sie verschiedene Helferlein...

Arbeiten mit Textdateien auf der Linux-Shell

Linux entwickelt sich mehr und mehr zu einem beliebten Betriebssystem für IT-Profis. Einer der Gründe für diese Entwicklung sind die Serverlösungen. Stabilität und geringer Ressourcenverbrauch sind einige der wichtigsten Eigenschaften für diese Wahl. Wer schon einmal mit einem Microsoft Server herumgespielt hat, wird den grafischen Desktop bei einem Linux Server vermissen. Nach dem Einloggen in einen Linux Server siht man nur die Kommandozeile, die auf Eingaben wartet.

In diesem kurzen Artikel stelle ich einige hilfreiche Linux-Programme zur Umgang mit Text Dateien auf der Kommandozeile vor. Auf diese Weise lassen sich leicht Informationen sammeln, zum Beispiel aus Protokolldateien (Logfiles). Bevor ich beginne, möchte ich noch einen einfachen und leistungsfähigen Editor namens joe empfehlen.

Strg + C – Abbrechen der aktuellen Bearbeitung einer Datei ohne Speichern der Änderungen
Strg + KX – Beenden der aktuellen Bearbeitung und Speichern der Datei
Strg + KF – Text in der aktuellen Datei suchen
Strg + V – Einfügen der Zwischenablage in das Dokument (CMD + V für Mac)
Strg + Y – Aktuelle Zeile an der Cursorposition löschen

Um joe auf einer Debian-basierten Linux-Distribution zu installieren, müssen Sie nur folgendes eingeben:

1. Wenn Sie Inhalte in einer großen Textdatei finden müssen, ist GREP Ihr bester Freund. Mit GREP können Sie nach Textmustern (Pattern) in Dateien suchen.

gerp <pattern> file.log
    -n : number of lines that matches
    -i : case insensitive
    -v : invert matches
    -E : extended regex
    -c : count number of matches
    -l : find filenames that matches the pattern
Bash

2. Wenn Sie Netzpakete analysieren müssen, ist NGREP das Werkzeug Ihrer Wahl.

ngrep -I file.pcap
    -d : specify the network interface
    -i : case insensitive
    -x : print in alternate hexdump
    -t : print timestamp
    -I : read a pcap file
Bash

3. Wenn Sie die Änderungen zwischen zwei Versionen einer Datei sehen wollen, ist DIFF genau das Richtige für Sie.

diff version1.txt version2.txt
    -a : add
    -c : change
    -d : delete
     # : line numbers
     < : file 1
     > : file 2
Bash

4. Manchmal ist es notwendig, die Einträge in einer Datei in eine bestimmte Reihenfolge zu bringen. SORT wird Ihnen bei dieser Aufgabe helfen.

sort file.log 
     -o : write the result to a file
     -r : reverse order
     -n : numerical sort
     -k : sort by column
     -c : check if orderd
     -u : sort and remove
     -f : ignore case
     -h : human sort
Bash

5. Wenn Sie Strings innerhalb eines großen Textes ersetzen müssen, z. B. durch Suchen und Ersetzen, können Sie dies mit SED, dem Stream-Editor, tun.

sed s/regex/replace/g
     -s : search
     -g : replace
     -d : delete
     -w : append to file
     -e : execute command
     -n : suppress output
Bash

6. Das Parsen von Feldern mit Begrenzungszeichen in Textdateien kann mit CUT durchgeführt werden.

cut -d ":" -f 2 file.log
     -d : use the field delimiter
     -f : field numbers
     -c : specific characters position
Bash

7. Die Extraktion von Teilstrings, die nur einmal in einer Textdatei vorkommen, erreichen Sie mit UNIQ.

uniq file.txt
     -c : count the numbers of duplicates
     -d : print duplicates
     -i : case insesitive
Bash

8.  AWK ist eine Programmiersprache, mit der Daten manipuliert werden können.

awk {print $2} file.log
Bash

Ruby: die Entwicklungsumgebung einrichten

Setzen Sie in wenigem Minuten eine Ruby Entwicklungsumgebung für die ersten Schritte mit dem Web...

Linux verstehen: die Wiederentdeckung der Freude an Technologie

Es ist an der Zeit wieder die Kontrolle über seine Hardware zu bekommen, denn um...

Tschüß Privatsphäre, Tschüß Freiheit

Je öfter wiederholt werden muss wie gut unsere Meinungsfreiheit ist um so weniger können wir...

Arbeiten mit Textdateien auf der Linux-Shell

Die Kommandozeile ist unter Linux ein mächtiges Werkzeug. In diesem Artiekl lernen Sie verschiedene Helferlein...

Test First?

java Aktuell 2024.03

Als ich vor über 10 Jahren begonnen habe testgetrieben zu programmieren, waren mir sehr viele verschiedene Konzepte theoretisch bekannt. Aber diese Sichtweise erst Testfälle zu schrieben und dann die Implementierung umzusetzen war irgendwie nicht der Weg mit dem ich gut zurecht gekommen bin. Wenn ich ehrlich bin ist das bis heute der Fall. So das ich eine für mich funktionierende Adaption des TDD Paradigma von Kent Beck gefunden habe. Aber langsam der Reihe nach. Vielleicht ist mein Ansatz ja für den einen oder anderen ebenfalls recht hilfreich.

Ich komme ursprünglich aus einem Umfeld für hoch skalierbarer Webanwendungen auf die sich all die tollen Theorien aus dem universitären Umfeld in der Praxis nicht ohne weiteres umsetzen lassen. Der Grund liegt vor allem in der hohen Komplexität solcher Anwendungen. Zum einen sind verschiedene Zusatzsysteme wie In Memory Cache, Datenbank und Identität und Zugriffs Management (IAM) ein Teil des Gesamtsystems. Zum Anderen verstecken viele moderne Frameworks wie OR Mapper Komplexität hinter verschiedene Zugriffsschichten. All diese Dinge müssen wir als Entwickler heutzutage beherrschen. Deshalb gibt es robuste, praxiserprobte Lösungen die gut bekannt sind aber wenig Verwendung finden. Kent Beck mit ist eine der wichtigsten Stimmen für den praktischen Einsatz automatisierter Softwaretest.

Wenn wir uns auf das Konzept TDD einlassen wollen ist es wichtig nicht jedes Wort zu sehr auf die Goldwaage zu legen. Es ist nicht alles in Stein gemeißelt. Wichtig ist das Ergebnis am Ende des Tages. Aus diesem Grund ist es unabdinglich sich die Zielvorgabe aller Bemühungen vor Augen zu führen um dann einen persönlichen Mehrwert zu erzielen. Also schauen wir uns zu erst einmal an was wir überhaupt bezwecken wollen.

Der Erfolg gibt uns Recht

Als ich meine ersten Gehversuche als Entwickler unternommen hatte benötigte ich stetiges Feedback ob das was ich da gerade zusammen bauen auch wirklich funktioniert. Diese Feedback habe ich meist dadurch erzeugt, in dem ich meine Implementierung einerseits mit unzähligen Konsolenausgaben gespickt habe und andererseits habe ich immer versucht alles in eine Benutzeroberfläche einzubinden um mich dann ‚manuell durchzuklicken‘. Im Grunde ein sehr umständliches Test Setup, das dann auch am Schuß wieder zu entfernen ist. Wenn dann noch spätere Bugfixes vorgenommen werden mussten ging das ganze Prozedere wieder von Neuem los. Alles irgendwie unbefriedigend und weit entfernt von einer produktiven Arbeitsweise. Irgendwie musste das verbessert werden ohne das man sich jedes Mal neu erfindet.

Schließlich hat mein ursprünglicher Ansatz genau zwei markante Schwachstellen. Die offensichtlichste ist das ein und auskommentieren von Debug Informationen über die Konsole.

Viel schwerwiegender ist aber der zweite Punkt. Denn all das erworbene Wissen zu dieser speziellen Implementierung ist nicht konserviert. Es droht also über die Zeit zu verblassen und schlußendlich auch verloren zu gehen. Ein solches Spezialwissen ist für viele nachfolgende Prozessschritte in der Softwareentwicklung aber äußerst wertvoll. Damit meine ich explizit das Thema Qualität. Refactoring, Code Reviews, BugFixes und Change Requests sind nur einige der möglichen Beispiele wo tiefgreifendes Detailwissen gefragt ist.

Für mich persönlich kommt auch hinzu, das mich monoton wiederholbare Arbeiten schnell ermüden und ich diese dann sehr gern vermeiden möchte. Sich immer wieder aufs neue mit der selben Testprozedur durch eine Anwendung zu klicken ist weit davon entfernt was für mich einen erfüllten Arbeitstag ausmacht. Ich möchte neue Dinge entdecken. Das kann ich aber nur wenn ich nicht in der Vergangenheit gefangen gehalten werde.

Konferenzvortrag

Die trauen sich aber was

Bevor ich aber darauf eingehe wie ich meinen Entwicklungsalltag durch TDD aufgepeppt habe muss ich noch ein paar Worte über Verantwortung und Mut loswerden. Immer wieder wird mir in Gesprächen erklärt das ich ja recht habe aber man können das alles ja nicht selber umsetzen, weil der Projektleiter oder irgend ein anderer Vorgesetzter kein grünes Licht gibt.

Eine solche Einstellung ist in meinen Augen äußerst unprofessionell. Ich frage doch auch nicht den Marketingleiter welcher Algorithmus am besten terminiert. Er hat schlichtweg keine Ahnung, denn es ist auch nicht sein Aufgabengebiet. Ein Projektleiter der sich gegen das testgetriebene Arbeiten im Entwicklungsteam ausspricht hat aber auch seinen Beruf verfehlt. In der heutigen Zeit sind Testframeworks so gut in die Build Umgebung integriert, das die Vorbereitung für TDD sich selbst für unerfahrene Personen in wenigen Augenblicken umsetzen lässt. Es ist also nicht notwendig das Vorhaben an die große Glocke zu hängen. Denn ich kann versprechen das selbst bei den ersten Gehversuchen nicht mehr Zeit benötigt wird als mit der ursprünglichen Vorgehensweise. Ganz im Gegenteil sehr schnell wird sich eine merkliche Erhöhung der Produktivität einstellen.

Die erste Stufe der Evolution

Wie bereits erwähnt ist Logging für mich ein zentrale Teil der testgetriebene Entwicklung. Wann immer es sinnvoll erscheint versuche ich den Zustand von Objekten oder Variablen auf der Konsole auszugeben. Wenn wir hierfür die aus der verwendeten Programmiersprache zur Verfügung gestellten Mittel nutzen, bedeute dies das wir diese Systemausgaben nach getaner Arbeit mindestens auskommentieren müssen und bei späterer Fehlersuche wieder einkommentieren. Ein redundantes und fehleranfälliges Vorgehen.

Nutzen wir hingegen von beginn an ein Logging Framework so können wir die Debug Informationen getrost im Code stehen lassen und deaktivieren diese später im Produktivbetrieb über den eingestellten Log Level.

Ich nutze Logging aber auch als Tracer. Das heißt jeder Konstruktor einer Klasse schreibt während er aufgerufen wird einen entsprechenden Log Eintrag im Log Level Info. Damit kann man sehen in welcher Reihenfolge Objekte instanziiert werden. Hin und wieder bin ich so auch auf die übermäßig oft vorkommende Instanziierung eines einzelnen Objektes aufmerksam geworden. Dies ist hilfreich für Maßnahmen zur Performance und Speicheroptimierung.

Fehler die bei der Ausnahmebehandlung geworfen werden logge ich je nach Kontext als Error oder Warning. Das ist später im Betrieb ein sehr hilfreiches Mittel um Fehlern auf die Spur zu kommen.

Wenn ich also eine Datenbankzugriff habe, schreibe ich also eine Logausgabe im Log Level Debug wie das zugehörige SQL zusammen gebaut wurde. Führt dieses SQL zu einer Exception, weil ein Fehler enthalten ist so wird diese Exception mit dem Log Level Error geschrieben. Findet wiederum eine einfache Suchanfrage mit korrekter SQL Syntax statt und die Ergebnismenge ist leer wird dieses Ereignis je nach Bedarf entweder als Debug oder Warning klassifiziert. Handelt es sich beispielsweise um eine Loginanfrage mit falschem Benutzernamen oder Passwort neige ich dazu mich für den Log Level Warning zu entscheiden, da dies im Betrieb eventuell sicherheitstechnische Aspekte enthält.

Im gesamten Kontext konfiguriere ich das Logging für die Testfallausführung eher sehr geschwätzig und beschränke mich auf eine reine Konsolenausgabe. Im Betrieb wiederum werden die Logging Informationen in eine Logfile geschrieben.

Die Henne oder das Ei

Wenn wir mit dem Logging die Voraussetzung für eine zusätzliche Feedbackschleife gelegt haben stellt sich im nächsten Schritt die Frage wie geht es weiter. Wie bereits erwähnt tue ich mich sehr schwer erst einen Testfall zu schreiben um dann eine entsprechende Implementierung dafür zu finden. Vor diesem Problem stehen auch viele andere Entwickler die mit TDD beginnen.

Eine Sache die ich bereits voraus nehmen kann ist das Problem, das man bei einer Implementierung darauf achten muss diese auch testbar zu halten. Habe ich erst den Testfall so merke ich umgehend ob das was ich gerade erstelle auch wirklich testbar ist. Erfahrene TDD Entwickler haben recht schnell in Fleisch und Blut übernommen wie testbarer Code auszusehen hat. Der wichtigste Punkt hierbei ist das Methoden stets einen Rückgabewert haben sollten, der möglichst nicht null ist. So etwas erreicht man beispielsweise wenn man anstatt null eine leere Liste zurück gibt.

Die Vorgabe einen Rückgabewert zu haben liegt an der Art und Weise wie Unit Test Frameworks arbeiten. Ein Testfall vergleicht den Rückgabewert einer Methode mit einem Erwartungswert. Die Testzusicherung (engl. Assertation) kennt verschiedene Ausprägungen und kann entsprechend: gleich, ungleich, wahr oder falsch sein. Natürlich gibt es hier auch verschieden Variationen. So kann es unter Verwendung von Exceptions möglich sein Methoden die keinen Rückgabewert haben zu testen. Alle diese Details erschließen sich bei der Anwendung in sehr kurzer Zeit. So das jeder ohne langwierige Vorbereitungen umgehend loslegen kann.

Bei der Lektüre des Buches Test Driven Development by Example von Kent Beck finden wir auch schnell eine Erklärung warum die Testfälle zu erst geschrieben werden sollten. Es handelt sich um einen psychologischen Faktor. Es soll uns dabei helfen den üblichen Stress der im Projekt entsteht besser zu bewältigen. Es erzeugt in uns einen mentalen Zustand über den Zustand und Fortschritt der aktuellen Arbeit. Es leitet uns in eine iterativen Prozess die vorhandene Lösung schrittweise über die verschiedenen Testfälle weiter auszubauen und zu verbessern.

Für alle die wie ich aber zu beginn einer Implementierung noch keine konkrete Vorstellung über das fertige Ergebnis haben ist dieser Ansatz schwer umzusetzen. Der bezweckte Effekt der Entspannung kehrt sich ins negative um. Da wir Menschen alle unterschiedlich sind müssen wir also herausfinden wie wir ticken um das bestmögliche Ergebnis zu erzielen. Ganz so wie es mit Lernstrategien ist. Manche Menschen verarbeiten Informationen besser visuell andere eher haptisch und wieder andere extrahieren alles wichtige aus gesprochenem. Versuchen wir uns also nicht wider unserer Natur zu verbiegen um mittelmäßige oder schlechte Ergebnis zu produzieren.

Den ersten Strich zeichnen

Mir erschließt sich ein Thema eben erst während ich damit arbeite. Also Versuche ich mich solange an einer Implementierung bis ich ein erstes Feedback benötige. Genau dann schreibe ich den ersten Test. Es ergebenen sich bei diesem Vorgehen automatisch Fragen bei der jede einzelne einen eigenen Testfall wert ist. Finde ich alle vorhanden Ergebnisse? Was passiert wenn die Ergebnismenge leer ist. Wie lässt sich die Ergebnismenge eingrenzen? Alles Punkte die sich auf einem Zettel notieren und Schritt für Schritt abhaken lassen. Die Idee eine Aufgabenliste auf einem Zettel zu notieren hatte ich schon sehr lange bevor ich das bereits erwähnte Buch von Kent Beck gelesen habe. Es hilft mir schnelle Gedanke zu konservieren ohne mich von meinem aktuellen Tun ablenken zu lassen. Außerdem vermittelt es am Ende des Tages ein Gefühl etwas geschafft zu haben.

Da ich nicht warte bis ich alles Umgesetzt habe, um den ersten Test zu schreiben ergibt sich auch bei diesem Vorgehen ein iterativer Ansatz. Ich merke auch sehr schnell wenn mein Entwurf nur unzureichend testbar ist, da ich sofort eine Rückmeldung erhalte. Daraus ergibt sich meine eigene Interpretation für TDD die sich durch den permanenten Wechsel zwischen Implementieren und Test schreiben auszeichnet.

Als Ergebnis meiner frühen TDD Versuche habe ich bereits in der ersten Woche eine Beschleunigung meiner Arbeitsweise bemerkt. Ich bin auch sicherer geworden. Aber auch die Art und Weise wie ich Programmiere hat sich schon sehr zeitig zu verändern begonnen. Mir ist aufgefallen das mein Code kompakter und robuster geworden ist. Dinge die sich erst mit der Zeit aufgezeigt hatten ergaben sich bei Tätigkeiten wie Refactoring und Erweiterungen. Fehlgeschlagene Testfälle haben mich vor bösen Überraschungen bewahrt.

Ohne Übereifer beginnen

Wenn wir uns in einem bestehenden Projekt dazu entschließen TDD einzusetzen ist es eine schlechte Idee loszulegen und für bestehende Funktionalität Testfälle zu schreiben. Abgesehen von der Zeit die hierfür eingeplant werden muss wird das Ergebnis die hohen Erwartungen nicht erfüllen.

Eines der Probleme ist das man sich nun in jede Funktionalität neu einarbeiten muss und das ist sehr Zeitaufwendig. Die Qualität der so entstandene Testfälle ist auch unzureichend. Das Problem ergibt sich auch aus der Erfahrung. Wird die Erfahrung erst aufgebaut so ist die Qualität der Testfälle auch noch nicht ganz optimal und möglicherweise muss auch Code umgeschrieben werden, damit dieser Testbar wird. Es entstehen also eine Menge Risiken die für das tägliche Projektgeschäft problematisch sind.

Ein bewährtes Vorgehen TDD einzuführen ist es einfach für die aktuelle Implementierung an der man gerade arbeitet einzusetzen. Es wird also der ist Zustand des aktuellen Problems durch automatisierte Tests dokumentiert. Da man sich bereits auf vertrautem Terrain befindet muss man sich nicht erst in eine neue Thematik einarbeiten, so das man sich voll auf das formulieren von aussagekräftigen Tests konzentrieren kann. Abgesehen davon, das man ungefragt Verantwortung über fremde Arbeiten übernimmt wenn man für diese Testfälle umgesetzt.

Bestehende Funktionalität wird nur bei Fehlerkorrekturen entsprechend um Testfälle ergänzt. Für die Korrektur muss man sich eh mit den Implementierungsdetails auseinander setzen, so das hier genügend Wissen vorhanden ist wie eine Funktionalität sich verhalten sollte. Die so entstandene Tests dokumentieren zusätzlich auch die Korrektur und stellen für die Zukunft sicher das sich das Verhalten bei Optimierungsarbeiten nicht verändert.

Folgt man dieser Vorgehensweise diszipliniert verliert man sich nicht in sogenannter hektischer Betriebsamkeit, die wiederum das Gegenteil von Produktivität ist. Zudem erwirbt man so recht schnell fundiertes Wissen wie effektive und aussagekräftige Tests umgesetzt werden können. Erst wenn ausreichend Erfahrung gesammelt wurde und möglicherweise umfangreiche Refactorings geplant werden, dann kann man überlegen wie für das gesamte Projekt die Testabdeckung schrittweise verbessert werden kann.

Qualitätsstufe

Nur weil Testfälle vorhanden sind bedeutet dies nicht das diese auch eine Aussagekraft haben. Genausowenig beweist eine hohe Testabdeckung das ein Programm fehlerfrei ist. Eine hohe Testabdeckung stellt nur sicher das sich ein Programm im Rahmen der Tests verhält.

Wir kann man also sicherstellen das die vorhandene Tests auch wirklich eine Bereicherung sind und eine gute Aussagekraft haben? Der erste und meines Erachtens wichtigste Punkt ist Testfälle möglichst kurz zu halten. Das heißt im Konkreten, das ein Test nur eine explizite Fragestellung beantwortet, z. B. Was passiert wenn die Ergebnismenge leer ist? Entsprechend der Fragestellung ergibt sich dann auch die Benennung der Testmethode. Den Mehrwert dieser Vorgehensweise ergibt sich in dem Moment wenn der Testfall fehlschlägt. Ist der Test sehr kurzgefasst lässt sich oft schon an der Testmethode ablesen worin das Problem besteht, ohne sich erst langwierig in einen Testfall einzuarbeiten zu müssen.

Ein anderer wichtiger Punkt im TDD Vorgehen ist für meine umgesetzte Funktionalität sowohl die Testabdeckung für Codezeilen als auch für Verzweigungen zu überprüfen. Kann ich zum Beispiel in einer IF-Abfrage das Eintreten einer einzelnen Bedingung nicht simulieren, so kann diese Bedingung bedenkenlos gestrichen werden.

Natürlich hat man im eigenen Projekt auch genügend Abhängigkeiten zu fremden Bibliotheken. Nun kann es vorkommen das eine Methode aus dieser Bibliothek eine Ausnahme wirft, die durch keinen Testfall simuliert werden kann. Das ist genau der Grund wieso man zwar eine hohe Testabdeckung anstreben sollte aber nicht verzweifeln muss wenn 100% nicht erreicht werden können. Gerade bei der Einführung von TDD ist ein gutes Maß für die Testabdeckung größer als 85% üblich. Mit wachsender Erfahrung des Entwicklungsteams kann dieser Wert bis zu 95% angehoben werden.

Abschließend ist aber noch anzumerken, das man sich nicht zu sehr in den Eifer begibt. Denn es kann auch schnell übertrieben werden und dann sind die ganzen gewonnene Vorteile schnell wieder dahin. Und zwar geht es um den Punkt das man keine Tests schreibt die wiederum Tests testen. Hier beißt sich die Katze in den Schwanz. Das gilt auch für Bibliotheken von Fremdanbietern. Für diese werden ebenfalls keine Test geschrieben. Kent Beck äußert sich hierzu sehr klar: Selbst wenn es gute Gründe gibt dem Code anderer zu misstrauen, teste ihn nicht. Externer Code erfordert mehr eigene Implementierungslogik.

Lessons Learned

Gerade die Erkenntnisse die sich bei dem Versuch eine möglichst hohe Testabdeckung zu erzielen sind die, welche sich beim künftigen Programmieren auswirken. Der Code wird kompakter und robuster.

Die Produktivität steigt einfach durch die Tatsache, das fehleranfällige und monotone Arbeiten durch Automatisierung vermieden werden. Es entstehen keine zusätzlichen Arbeitsschritte denn alte Gewohnheiten werden durch neue, bessere ersetzt.

Ein Effekt den ich immer wieder beobachten konnten, wenn sich einzelne Personen aus dem Team für TDD entschieden haben, wurden deren Erfolge schnell beachtet. Innerhalb weniger Wochen hat dann das gesamte Team TDD entwickelt. Jeder einzelne nach seinen eigene Fähigkeiten. Manche mit Test First andere wiederum so wie ich es gerade beschrieben habe. Zum Schluß zählt das Ergebnis und das war einheitlich hervorragend. Wenn die Arbeit leichter fällt und am Ende des Tages jeder einzelne auch noch das Gefühl hat auch etwas geleistet zu haben bewirkt dies im Team einen enormen Motivationsschub, der dem Projekt und dem Arbeitsklima eine gewaltigen Auftrieb verschafft. Also worauf warten Śie noch? Probieren Sie es am besten gleich selber aus.

Test First?

Testgetrieben Entwicklung klingt ja ganz vernünftig. Zumal anschließend auch voll automatisierte Tests vorhanden sind. Aber...

Faktor Mensch! – wiederholbare Projekterfolge mit SCRUM

Zu der Erkenntnis, dass Menschen Projekte machen, gelangt man nicht erst durch die Lektüre von...

Tschüß Privatsphäre, Tschüß Freiheit

Die im Oktober 2023 veröffentlichten neuen AGB für Microsoft-Dienste lösten in der IT-Welt einen Aufschrei aus. Der Grund war ein Absatz, in dem es hieß, dass mittlerweile alle Microsoft-Dienste auf künstlicher Intelligenz basieren. Diese K.I. soll dazu dienen, Urheberrechtsverletzungen zu erkennen. Dazu gehören Dinge wie Musik, Filme, Grafiken, E-Books und natürlich auch Software. Falls diese K. I. Urheberrechtsverletzungen auf dem System erkennt, sollten diese Dateien automatisch vom „System“ gelöscht werden. Derzeit ist nicht klar, ob diese Regel für die eigene lokale Festplatte oder nur für die Dateien in der Microsoft Cloud gilt. Microsoft hat außerdem erklärt, dass Benutzer, die gegen die Urheberrechtsbestimmungen verstoßen, künftig von allen Microsoft-Diensten ausgeschlossen werden sollen.

Dieser Ausschluss hat verschiedene ‘Geschmäckle’. Die ersten Fragen, die mir in den Sinn kommen, sind: Was passiert mit kostenpflichtigen Abonnements wie Skype? Werde ich gesperrt und anschließend wird mein ungenutztes Guthaben zurückerstattet? Ein noch schlimmeres Szenario wäre, dass ich möglicherweise auch all mein Guthaben und digitale Käufe wie den Zugang zu Spielen und anderen Dingen verliere. Oder sind kostenpflichtige Abonnements davon nicht betroffen? Bisher ist dieser Teil nicht klar.

Wenn Sie ein Apple-Benutzer sind und denken dass dies keine Auswirkungen auf Sie hat, stellen Sie sicher, dass Sie keinen Microsoft-Dienst verwenden, von dem Sie nicht wissen das dieser zu Microsoft gehört. Nicht jedes Produkt enthält den Firmennamen. Denken Sie darüber nach, denn wer weiß, ob diese Produkte Ihr System ausspionieren. Einige Anwendungen wie Skype, Teams, Edge Browser und Visual Studio Code sind auch für andere Plattformen wie Apple und Linux verfügbar.

Microsoft besitzt außerdem die Quellcode-Hosting-Plattform GitHub und ein soziales Netzwerk für Spezialisten namens LinkedIn. Mit Office 360 können Sie die gesamte Microsoft Office Suite per Webbrowser als Cloud-Lösung nutzen und alle Ihre Dokumente werden in der Microsoft Cloud gespeichert. Dieselbe Cloud, in der US-Regierungsinstitutionen wie die CIA, die NSA und viele andere ihre Dateien aufbewahren. Nun, es scheint wohl ein sicherer Ort für alle Ihre Gedanken zu sein, die in ein Office Dukument niedergeschreiben wurden.

Dieses kleine Detail zu Office-Dokumenten führt uns zu einer kleinen Randbemerkung in den neuen Geschäftsbedingungen von Microsoft. Der Kampf gegen Hassrede. Was auch immer das heißt. Öffentliche Beleidigungen und Verleumdungen werden seit jeher vom Gesetzgeber strikt als Straftat behandelt. Es ist kein Kavaliersdelikt, der mit einem kleine bußgeld geahndet wird. Daher ist mir nicht klar, was dieses ganze Gerede über Hassreden bedeutet. Vielleicht ist es ein Versuch, eine öffentliche Zensur der Meinungsfreiheit einzuführen.

Aber zurück zum Randhinweis der Microsoft-Nutzungsbedingungen zu Hassreden. Microsoft hat so etwas geschrieben wie: Wenn Hassreden festgestellt werden, wird der Benutzer verwarnt und wenn die Verstöße mehrmals auftreten, wird das Microsoft-Konto des Benutzers deaktiviert.

Wenn Sie vielleicht denken, dass dies nur etwas ist, was jetzt von Microsoft passiert, stellen Sie sicher, dass viele andere Unternehmen daran arbeiten, gleichwertige Dienste einzuführen. Die Kommunikationsplattform Zoom beispielsweise beinhaltete auch K. I. -Techniken, um die Benutzerkommunikation zu ‘Trainingszwecken’ zu beobachten.

Bei all diesen Neuigkeitenstellt sich eine große Frage die beantwortet werden muss: Was kann ich selbst tun? Die Lösung ist einfach. Verlassen Sie das digitale Universum und gehen Sie zurück in die reale Welt. Schalten Sie das Gehirn wieder ein. Benutzen Sie Stift und Papier, zahlen Sie bar, lassen Sie Ihr Smartphone zu Hause und dort niemals auf dem Nachttisch. Wenn Sie es nicht verwenden, schalten Sie es aus! Treffen Sie Ihre Freunde, wann immer es möglich ist physisch und bringen Sie dann nicht Ihr Smartphone mit. Es wird keine Regierung, keinen Präsidenten und keinen Messias geben, die eine Veränderung herbeiführen wird. Es ist an uns, dies zu tun.

Ruby: die Entwicklungsumgebung einrichten

Setzen Sie in wenigem Minuten eine Ruby Entwicklungsumgebung für die ersten Schritte mit dem Web...

Linux verstehen: die Wiederentdeckung der Freude an Technologie

Es ist an der Zeit wieder die Kontrolle über seine Hardware zu bekommen, denn um...

Tschüß Privatsphäre, Tschüß Freiheit

Je öfter wiederholt werden muss wie gut unsere Meinungsfreiheit ist um so weniger können wir...

Arbeiten mit Textdateien auf der Linux-Shell

Die Kommandozeile ist unter Linux ein mächtiges Werkzeug. In diesem Artiekl lernen Sie verschiedene Helferlein...