webfactory Neuigkeiten https://www.webfactory.de/assets-version-1525864281/bundles/webfactorywebsite/img/inside-logo.png Logo Webfactory http://www.webfactory.de Zend_Feed_Writer 2 (http://framework.zend.com) https://www.webfactory.de/blog/ © 2018 webfactory GmbH Microservices aus einer monolithischen Webanwendung extrahieren Typischerweise ist die Unübersichtlichkeit des Monolithen ein großes Problem. Sein schierer Umfang, mangelhafte Dokumentation und die Abwesenheit seiner ursprünglichen Entwickler erschweren uns häufig das Verständnis seiner internen Komponenten und ihrer Abhängigkeiten. Vielleicht gibt es Indizien wie Namespaces - aber niemand kann garantieren, dass die Ordnungsprinzipien über alle Entwickler hinweg mit dem gleichen Elan befolgt wurden. Spätestens beim Einsatz schwarzer Magie hilft auch keine statische Code-Analyse mehr - und wir leben in ständiger Angst, dass eine Änderung unbeabsichtigte Nebeneffekte haben könnte.

Sobald wir den alten Code verstanden haben, jucken uns wahrscheinlich schon mehrere Refactorings in den Fingern. Hier schnell etwas gerade ziehen, jenes nebenher vereinfachen. Aber der Monolith ist komplex, und ehe wir uns versehen, grinst uns ein sehr, sehr zotteliges Yak an, das wir zumindest in dem Moment doch lieber nicht rasieren wollen.

Deshalb ist es wichtig, eine Strategie mit ganz vielen Reißleinen zu haben. Sobald wir bemerken, dass wir uns verrannt haben, müssen wir schnell wieder auf den letzten Commit fliehen, in Sicherheit durchatmen und dann noch einmal frisch anfangen können. Aber Moment mal - ist das nicht ein Standardproblem der Software-Entwicklung? Ja! Und es gibt auch eine Standardlösung: automatisierte Software-Tests.

Automatisierte Black-Box-Tests

Im besten Fall decken wir mit (z.B. in behat geschriebenen) Black-Box-Tests alle Funktionen des als Microservice zu extrahierenden Features ab. Wir klicken das Feature im Monolithen einmal komplett durch und halten unsere Beobachtungen als Test-Erwartungen fest. So können wir nicht nur später die Funktionalität absichern, sondern lernen auch nach und nach die Details des zu extrahierenden Features kennen.

Beispielsweise können wir HTTP-Status-Code und spezifische Seiteninhalte für die Feature-Startseite testen, für eine Login-Funktion, Erstellen-, Lesen-, Bearbeiten- und Löschen-Operationen, das Abschicken einer Suchmaske und die entsprechende Ergebnisliste. Bei diesem explorativen Ansatz sollten wir berücksichtigen, ob es verschiedene Benutzergruppen (z.B. Administratoren) und damit eingehende Rechte gibt und für jedes dieser Rechte den Zugriffsschutz testen.

Unit-Tests sind in diesem Kontext weniger relevant. Denn zu diesem Zeitpunkt wissen wir noch nicht genug über den Monolithen bzw. den zu extrahierenden Microservice, als dass wir zu jeder getesteten Unit sagen könnten: Dies ist ihr Kontext und daher ist sie ir/relevant für uns.

Tipp: Datenbank-Dumps mit Slimdump
Mit den Black-Box-Tests können wir schon einmal annähern, welche Tabellen der Microservice benötigt bzw. welche Datenzeilen wir für unsere Test-Fixtures benötigen. Später werden wir das noch weiter eingrenzen können, aber für den Moment wollen wir unser Wissen schon einmal festhalten. Dazu können wir beispielsweise in slimdump, einem Tool für hochgradig konfigurierbare MySQL-Dumps, eine Konfigurationsdatei anlegen, versionieren und mit unseren Kollegen teilen.
Neben der Tabellen- und Datenzeilenauswahl können wir beispielsweise konfigurieren, dass Benutzernamen und E-Mail-Adressen einer User-Tabelle nur anonymisiert gedumpt werden oder dass wir aus Performance-Gründen in jener Tabelle nur 10% der Datensätze und keine BLOBs dumpen wollen.

Grüne Wiese oder Klon?

Wie starten wir konkret mit dem Microservice? Bei Null auf der grünen Wiese oder als Klon des Monolithen, von dem wir dann alles wegschneiden, was nicht zum Microservice gehört? Für beide Varianten gibt es gute Gründe, aber für mich kocht die Entscheidung auf die Abwägung zwischen diesen drei wesentlichen Kriterien ein:

  1. Menge der Einschränkungen: Auf der grünen Wiese starten wir mit minimalen Einschränkungen, im Klon nehmen wir erstmal dessen komplette technische Welt mit.

  2. Nutzung alter Meta-Daten: Meiner Erfahrung nach ist insbesondere die Commit Message History oftmals die einzige Chance, eine Stelle mit besonders verrücktem Code zu verstehen. Insbesondere, wenn durch eine Ticket-Nummer der Kontext der letzten Code-Änderungen deutlich wird.

  3. Latenz bis zur Live-Schaltung des Microservices: Starten wir unseren Microservice auf der grünen Wiese, haben wir eine sehr hohe Latenz, bis er live geschaltet werden kann: er muss erstmal von Grund auf entwickelt werden.
    Wenn wir dagegen den Microservice als Klon des Monolithen erstellen und auf einem eigenen Host betreiben, kann der prinzipiell sofort live gehen. Wir richten einfach irgendeinen Proxy (z.B. Varnish oder mit Apache Rewrite-Rules) vor dem Original-Monolithen ein, der Requests an den Microservice an dessen Host und alle anderen Requests wie gehabt an den Monolithen-Host leitet. Vielleicht müssen wir uns noch um Details bzgl. Cookies, Sessions und URL-Rewriting kümmern - aber das ist offensichtlich immer noch erheblich weniger Latenz als die komplette Neuentwicklung auf der grünen Wiese.

In meiner Erfahrung überwiegen die Argumente für den Start mit dem Klon. Ich vermute, dieser Weg ist im Allgemeinen auch ökonomischer: denn so viel Spaß die grüne Wiese auch bereiten mag - sie scheint mir nur ein Euphemismus für einen teilweisen Rewrite zu sein, der Klon dagegen die Basis für ein Refactoring.

Wahrscheinlich gibt es auch Projekte mit besonderen Umständen, in denen die grüne Wiese die klar bessere Entscheidung ist - an solchen habe ich aber noch nicht gearbeitet. Daher behandelt der weitere Artikel den Klon-Weg.

Tipp: Lauffähigen Monolithen behalten
Falls wir den Monolithen bereits installiert haben, sollten wir den tunlichst bis zur Live-Schaltung des Microservices behalten. Denn wir werden im Laufe des Projekts anhand von Heuristiken Entscheidungen treffen, die sich erst Tage später als falsch herausstellen können. Vielleicht schneiden wir zu viel Code weg oder vereinfachen ihn zu stark und stellen erst im Nachhinein fest, dass uns ein Test fehlte, der genau das anzeigen würde.
In solchen Momenten ist es extrem praktisch, schnell in einer lauffähigen Version des Monolithen nachsehen zu können, wie eine bestimmte Verarbeitung konkret ablief.

Erkennung ungenutzter Ressourcen

Wenn wir unseren künftigen Microservice als Klon des Monolithen aufgesetzt haben - wie erkennen wir die ungenutzten Ressourcen, die wir wegschneiden müssen, damit nur der Microservice übrig bleibt? Allgemein gilt:

Ungenutzte Ressourcen = alle Ressourcen - genutzte Ressourcen

Alle Ressourcen einer Art stehen typischerweise bereits als Liste bereit (z.B. bei Dateien mit ls) und die genutzten Ressourcen ermitteln wir mithilfe unserer Black-Box-Tests. Dazu müssen wir nur eine passende Form des Coverage Loggings aktivieren, die Tests ausführen und dann die Coverage in ein aussagekräftiges Format bringen. Schließlich bilden wir deren Differenz und haben damit die ungenutzten Ressourcen.

Unsere Tests haben also eine Doppelrolle: Erstens sichern wir mit Ihnen die Korrektheit des Codes und zweitens verwenden wir ihre Coverage zur Ermittlung der ungenutzten Ressourcen.

Schauen wir uns mal im Detail an, wie die Ermittlung der genutzten Ressourcen bei verschiedene Ressourcen-Arten funktioniert.

Genutzte PHP-Dateien

Die meisten PHP-Frameworks verarbeiten Requests über einen einen FrontController. In einen solchen können wir uns leicht einhaken und z.B. xdebug die Code Coverage loggen und die Pfade der genutzten Dateien in einer Datei used-files.txt ausgeben lassen:

<?php
// Coverage sammeln lassen
xdebug_start_code_coverage();

// Original-FrontController
$app = new App();
$app->handle($_REQUEST);

// Pfade genutzter Dateien schreiben
$outFile = fopen('used-files.txt', 'a');
fwrite(
  $outFile,
  implode(PHP_EOL, array_keys(xdebug_get_code_coverage()))
);
fclose($outFile);

Wir könnten dafür beispielsweise auch sysdig einsetzen, ein Tool zur Überwachung und Analyse von system calls und Linux kernel events. Dessen großer Vorteil ist, dass wir damit nicht nur verwendete PHP-Dateien erfassen, sondern alle geöffneten Dateien - also z.B. auch Konfigurationsdateien und View-Templates. Größter Nachteil ist, dass der benötigte Umfang nur auf Linux verfügbar ist.

Genutzte Composer-Pakete

Wenn wir die used-files.txt aus dem vorigen Abschnitt auf die Dateien filtern, die in einem Unterverzeichnis von composers vendor-Verzeichnis liegen, können wir aus ihren Pfaden unmittelbar die genutzten Composer-Pakete ablesen.

Genutzte MySQL-Tabellen

Ein Coverage Logging ist leicht z.B. mit folgenden SQL-Statements zu aktivieren:

SET global general_log = 1;
SET global log_output = 'table';

Führen wir nun unsere Tests aus, werden die SQL-Queries in der Tabelle mysql.general_log geloggt (die wir deshalb vorher vermutlich TRUNCATEn möchten). Aus diesen können wir die Namen der genutzten Tabellen extrahieren. Das ist händisch allerdings schnell zu mühsam. Denn zum einen werden es typischerweise sehr viele Queries sein. Zum anderen müssten wir bei jedem Query genau hinschauen, an welchen Stellen Tabellennamen vorkommen können: kommagetrennt in der FROM-Klausel, in der JOIN-Klausel und in Sub-Queries.

Genutzte Frontend-Assets

Die Pfade zu genutzten Frontend-Assets wie Bildern, Schriftarten, Javascript- und CSS-Dateien finden wir als Hits in den Webserver-Access-Logs. Mit einem regulären Ausdruck (für das Apache Standard-Access-Log-Format z.B. #"(?:get|post) ([a-z0-9\_\-\.\/]*)#i) können wir sie herausfiltern. Doch dabei gibt es ein paar Probleme:

Assets-Download: Das Standard-behat-Setup verwendet Goutte als Webbrowser, der keine Bilder, kein Javascript und kein CSS runterlädt und ggf. ausführt. Das heißt, diese Hits fehlen im Logfile. Als Lösung können in behat aber auch andere Browser bzw. Browser-Treiber angebunden werden - mittels Selenium auch Firefox, Chrome oder sogar eine Armada von Browserstack.

Konkatenierungen: Jahrelang haben wir die Performance von Webanwendungen verbessert, indem wir Javascript und CSS in wenigen Dateien konkateniert haben, um so die Anzahl der TCP-Verbindungen an unseren Server zu senken. Dieser Ansatz hat sich mit HTTP/2 überholt, wird aber noch viel in Legacy-Monolithen zu finden sein. Dann ist eine Aussage wie “screen.css und app.js werden genutzt” nur wenig hilfreich.

Hier könnte es am Einfachsten sein, die Konkatenierung auszuschalten und die Quelldateien direkt im HTML einzubetten - wenn denn noch leicht herauszufinden ist, welche Datei auf welche Seite eingebunden gehört.

Falls nicht, könnte die Coverage auf Zeilenebene innerhalb der Dateien in Verbindung mit Sourcemaps ausgewertet werden. Die zeilenbasierte Coverage ist wiederum ein eigenes Problem.

Automatisierte Zeilen-Coverage in Javascript und CSS: Für Javascript gibt es eine Vielzahl von Coverage-Logging-Tools wie Istanbul, JSCover und Blanket.js (und bis dieser Artikel erscheint, gibt es vermutlich wieder drei neue). Diese können an JS-Testrunner wie Karma oder Jasmin angebunden werden. Zusammen mit den eigentlichen Javascript-Tests kommt hier möglicherweise einiges an Aufwand hinzu.

Bei CSS ist die Lage noch schwieriger, aber immerhin gerade in Bewegung: Beispielsweise hat Chrome seit der Version 59 ein eigenes Panel für die CSS Coverage. Die Ermittlung der Coverage funktioniert grob so, dass für alle Selektoren in den geladenen CSS-Dateien geprüft wird, ob sie im geladenen Dokument treffen. Falls ja, werden sie und die damit verbundenen Statements als benutzt markiert. Das ist zwar nicht perfekt, scheint aber eine brauchbare Heuristik zu sein. Leider sind weder Ein- noch Ausgabe für diesen Prozess leicht automatisierbar. Es bleibt zu hoffen, dass entsprechende Methoden mittelfristig in der puppeteer-API ergänzt werden.

Wer diesen Prozess unbedingt jetzt schon automatisieren will, kann sich z.B. mit dem Firefox Plugin “Dust-Me Selectors” notbehelfen. Dort können eine Sitemap eingegeben und die resultierende Coverage auf Datei- und Zeilenebene als JSON exportiert werden.

Automatisierung mit dem Zauberlehrling

Der Zauberlehrling ist ein Open Source-Tool, das bei der Extraktion von Microservices unterstützen soll. Insbesondere automatisiert es einige Schritte zur Erkennung ungenutzter Ressourcen:

bin/console show-unused-php-files --pathToInspect --pathToOutput --pathToBlacklist usedFiles

zeigt die ungenutzten PHP-Dateien an. Als Eingabe dient das weiter oben erstellte used-files.txt. Außerdem können der zu untersuchende Pfad auf dem Dateisystem, eine Ausgabe-Datei und eine Blacklist konfiguriert werden, um z.B. Temp-Verzeichnisse auszuschließen oder solche, von denen bekannt ist, dass sie nicht von den Black-Box-Tests abgedeckt werden (z.B. Pfade für Unit-Tests).

bin/console show-unused-composer-packages --vendorDir composerJson usedFiles

zeigt die vermeintlich ungenutzten Composer-Pakete. Die Qualität der Aussage korreliert unmittelbar mit dem Inhalt der usedFiles-Datei: Für den Zauberlehrling gilt ein Paket als genutzt, wenn mindestens eine Datei darin genutzt wird. Enthält die usedFiles-Datei beispielsweise nur mit xdebug ermittelte PHP-Dateien, werden Composer-Pakete, die ausschließlich aus View-Templates oder Konfiguration bestehen, niemals als genutzt erkannt und immer als vermeintlich ungenutzt ausgegeben werden. Mit sysdig erstellte usedFiles-Dateien sind daher hier vorteilhafter.

bin/console show-unused-mysql-tables

ermittelt mit einem SQL-Parser aus der MySQL-Log-Tabelle die genutzten Tabellen, bildet die Differenz zu allen und zeigt die vermeintlich ungenutzten Tabellen an.

bin/console show-unused-public-assets --regExpToFindFile --pathToOutput --pathToBlacklist pathToPublic pathToLogFile

zeigt die vermeintlich ungenutzten Frontend-Assets. Nimmt die Pfade des Public-Verzeichnisses und Access-Logs als Eingabe und kann mit dem regulären Ausdruck zur Erkennung der Dateipfade im Access-Log, der Ausgabe-Datei und einer Blacklist (wie bei den ungenutzten PHP-Dateien) konfiguriert werden.

Kurze Entwicklungs-Zyklen

Die Automatisierung durch den Zauberlehrling ermöglicht das Arbeiten in kurzen Entwicklungszyklen. Nach einem initialen Coverage-Durchlauf können diese wie folgt aussehen:

  1. Ungenutzte Ressource löschen
  2. Tests ausführen (der Geschwindigkeit halber ohne Coverage)
  3. ggf. gelöschte Ressource wiederherstellen, Code oder Tests fixen
  4. committen
  5. zurück zu 1. oder Abbruch.

Sind die erkannten ungenutzten Ressourcen gelöscht, sollte wieder ein Testlauf mit Code Coverage durchgeführt werden. Es lohnt sich auch ein Blick auf die Liste der genutzten Dateien - vielleicht sind hier noch niedrig hängende Früchte zu erkennen. Wenn beispielsweise in einem Composer-Paket nur noch wenige Dateien benötigt werden, können wir es vielleicht ganz überflüssig machen und als Abhängigkeit entfernen. Vielleicht finden wir auch im Kontext unseres Microservices überflüssige Abstraktionen, die wir jetzt vereinfachen können.

Und anschließend nicht vergessen: die Tests wieder ausführen :)

___

Dieser Artikel erschien zuerst im PHP Magazin 2.18. Er basiert auf einem ausführlicheren Vortrag auf der FrOSCon 2017, dessen Mitschnitt beim CCC und auf Youtube veröffentlicht ist.

]]>
Wed, 23 May 2018 11:02:42 +0200 https://www.webfactory.de/blog/microservices-aus-einer-monolithischen-webanwendung-extrahieren https://www.webfactory.de/blog/microservices-aus-einer-monolithischen-webanwendung-extrahieren webfactory GmbH webfactory GmbH 0
Girls'Day bei der webfactory Nachdem uns im März eine E-Mail von einer Mutter einer Bonner Schülerin erreicht hat, in der sie fragte, ob ihre Tochter im Rahmen des Girls'Day zu uns in die Firma kommen könnte, haben wir uns auf der offiziellen Seite als Botschafter für mehr Frauen in der IT-Branche angemeldet.

Ich habe bereits 2015 einen Girls'Day organisiert, als ich noch bei IBM gearbeitet habe und nahm mich daher ohne zu zögern dieser Aufgabe an. Damals war das Feedback sehr positiv, sodass ich die Agenda vollständig übernommen habe:

  1. Kennenlernrunde
  2. Vorstellung der Tätigkeiten in den verschiedenen Rollen bei der webfactory (Backend-Entwicklerin, Designerin, Projektmanagerin)
  3. Spielerisch Programmieren lernen mit der "hour of code" https://code.org/learn
  4. Gemeinsames Mittagessen
  5. Erarbeitung und Präsentation einer eigenen Projektidee

Mit der Unterstützung von meinen Kollegen Eva, Jano und Søren haben wir die Mädchen durch das Programm begleitet.

Mein persönlicher Höhepunkt waren die kreativen Projektideen und der feste Vorsatz von einem der zwei Projektteams, von denen sich zwei von vier Teammitgliederinnen zuvor noch nicht kannten, sich in der Freizeit zu treffen, um das Projekt weiterzuentwickeln.

Schließlich erhielt jede Teilnehmerin noch eine Liste von nützlichen Ressourcen, um mehr über Webentwicklung und Programmierung zu lernen:

Wir sind gespannt auf die nächsten Marktführer für Mode-Sale-Finder und community-driven Fitnessratgeber im Web.

Unser Angebot auf der Girls'Day Website: https://www.girls-day.de/aktool/ez/eventvcard.aspx?id=73844

]]>
Mon, 30 Apr 2018 11:05:45 +0200 https://www.webfactory.de/blog/girls-day-2018 https://www.webfactory.de/blog/girls-day-2018 webfactory GmbH webfactory GmbH 0
Advanced subsearches and transactions in Splunk: Tracing qmail deliveries The email in question was part of a larger mail processing job, and we're using qmail to process these mails. Yes, qmail – it works great when it comes to doing high-volume, outbound-only deliveries in short time. 

The problem challenge is that qmail has an interesting way of logging in the current log, which looks like this:

@400000005aa66b052a527324 new msg 33778541
@400000005aa66b052a527edc info msg 33778541: bytes 7703 from <sender@host.tld> qp 21534 uid 64011
@400000005aa66b052a840e5c starting delivery 7512293: msg 33778541 to remote recipient@host.tld
@400000005aa66b060a418aac delivery 7512293: success: 176.34.178.125_accepted_message./Remote_host_said:_250_OK_id=1evM4J-0005W8-QC/
@400000005aa66b060a419a4c end msg 33778541

I am not talking about the funny-looking tai64 timestamps, but rather the message and delivery ids. There are several problems with this:

  • The message id is based on the Linux filesystem inode id for the mail file sitting in the queue. While being unique at a given time, multiple different mails will use the same message id over time.
  • The delivery id is just a counter that increments with every message processed. It will start from scratch if you restart qmail, and so again, this id is not unique over a longer time.
  • While you get the information that a particular delivery has been started for a given message id, all further information regarding the progress of this delivery is logged only with the delivery id, but does not show the message id again. That's probably due to the way the qmail architecture uses different processes for isolated tasks.

In order to get a comprehensive Splunk report for a given email address and to make it run in acceptable time, I had to learn about Splunk subsearches and transaction grouping.

Use a subsearch to narrow down relevant events

First, lets start with a simple Splunk search for the recipient address.

index=mail sourcetype=qmail_current recipient@host.tld

In particular, this will find the starting delivery  events for this address, like the third log line shown above. Having done our homework, Splunk extractions are set up in a way that we get the qmail_msg and qmail_delivery fields for this event.

Now, in order to get a complete report including delivery progress, we need to consider all log events that include either the appropriate message id or delivery id. 

With a default Splunk subsearch, the outer search will get all events where every field returned from the subsearch matches.

This works because Splunk applies the format  command implicitly on subsearches. Try this:

index=mail sourcetype=qmail_current recipient@host.tld | fields qmail_msg qmail_delivery | format

This will return a single event with a field named search  and a value like

( ( qmail_delivery="8227046" AND qmail_msg="33565415" ) OR ( qmail_delivery="7947353" AND qmail_msg="33719121" ) OR ...)

Splunk will first execute the subsearch. Then, the value from this search  field is taken as a replacement for the subsearch part of the query. Finally, the resulting query is executed.

You can, in fact, put the format command in your subsearch yourself and use parameters to modify the resulting string. Let's do this and directly combine it with a subsearch:

index=mail sourcetype=qmail_current [
    search index=mail sourcetype=qmail_current recipient@host.tld 
    | fields qmail_msg qmail_delivery  | format  "" "" "OR" "" "OR" ""
]

This search fetches all log events that either have a message id or a delivery id for any message or delivery ids that appears in context with the recipient address.

Group events as transactions

You can then use the transaction command to group events. As you can see from the log excerpt above, qmail transactions start with new msg  and end with end msg . We need to pick the message id from the start event and also include all events that have this message id and occur before the end event.

Additionally, the delivery id makes up the transaction. The transaction command is smart enough to pick up any delivery id that appears together with the message id we're following, and it can use this delivery id to include further events, even if they lack the message id. The transaction documentation has an example for this.

Adding a maximum duration between single transaction events for added performance, this gives us

| transaction qmail_msg qmail_delivery
    startswith="new msg" endswith="end msg"
    maxpause=1h

Now the last step is to once again filter out transactions that do not contain our intended recipient. Those transactions may show up because, as I stated in the beginning, the ids used by qmail are not unique. So while the subsearch finds the right ids for our particular recipient, the outer search may produce too many intermediate results.

We remove those transactions by applying a final

| search recipient@host.tld 

The result

Putting it all together, we get

index=mail sourcetype=qmail_current [
    search index=mail sourcetype=qmail_current recipient@host.tld
    | fields qmail_msg qmail_delivery
    | format  "" "" "OR" "" "OR" ""  
]
    | transaction qmail_msg qmail_delivery
          startswith="new msg" endswith="end msg" maxpause=1h
    | search recipient@host.tld

Most Splunk queries like this seem to do magic. And once they work, you tend to forget how they work or why they probably produce correct results. In part, this is why I am writing this up as a note to my future self.

Also, because a query like this is hard to remember or to re-construct, I saved this search as a Splunk dashboard. That allows you to add a handy input box for the address et voilà, we have a simple-to-use interface for our next support call.

]]>
Fri, 16 Mar 2018 09:47:31 +0100 https://www.webfactory.de/blog/splunk-subsearch-transaction-qmail-deliveries https://www.webfactory.de/blog/splunk-subsearch-transaction-qmail-deliveries webfactory GmbH webfactory GmbH 0
Ein paar Worte zum Schluss Frohe Weihnachten

Danke!

Weil es so schön ist, fangen wir doch gleich einmal mit dem Dank an: Liebe Kunden, die Zusammenarbeit mit euch ist das Kernstück unserer Arbeit. Wie könnten wir also nicht mit euch beginnen? Wir danken euch dafür, dass ihr uns – viele von euch schon seit so vielen Jahren – euer Vertrauen schenkt. Jeder einzelne von euch liegt uns wirklich sehr am Herzen und wir sind nach wie vor fest davon überzeugt, die besten Kunden der Welt zu haben! Auch 2017 haben wir wieder einige spannende Aufgaben gemeinsam mit euch gestemmt. An großen Projekten hervorzuheben ist sicherlich der schrittweise Launch der Staatsoper Berlin von Juni bis Oktober. Das Projekt hat uns trotz – oder vielleicht gerade wegen – seiner Komplexität und seines Umfangs sehr viel Spaß gemacht. Wir freuen uns ganz besonders darüber, dass das gute Feedback des Staatsoper-Teams uns direkt ein Folgeprojekt für das Staatstheater Darmstadt in die Firma gespült hat. Neben den Webprojekten aus dem künstlerischen Feld begleitet uns außerdem fast schon das ganze Jahr die Überarbeitung der Website des Gemeinsamen Bundesausschuss, die wir 2018 fertigstellen werden. Auch Jugend für Europa hat uns dieses Jahr wieder einige Projekte beschert: Besonders spannend ist dabei gerade die Umsetzung der Website für das neue Förderprogramm des Europäischen Solidaritätskorps, das 2018 an den Start geht. 

Danke sagen möchten wir außerdem auch all unseren externen Kooperationspartnern und Helferlein, die uns auch in diesem Jahr wieder an vielen Fronten unterstützt haben: Lieben Dank an Benjamin O’Daniel für die Unterstützung bei unserer Mitarbeitersuche und für all den wertvollen Input. Danke an Ruth und ihr Team von kaffeetante.net für die tolle Kooperation bei unserem FrOSCon-Kaffeestand. Danke an die Odenthal-Illustratoren für unsere schönen, neuen Team-Avatare und danke auch an unsere gute Bürofee Jutta für all die Blumen, Kürbisse, Kerzen und Schokoladen, mit denen du uns dieses Jahr eine Freude gemacht hast. 

Webfactory 2017 intern

Für unseren kleinen webfactory Mikrokosmos war das Jahr unseres 20. Geburtstags relativ turbulent. Besonders beeinflusst hat uns sicherlich der Verlust von gleich drei Kolleg*innen in der ersten Jahreshälfte. Auch viele unserer Kunden haben dies leider durch einige Projektverzögerungen zu spüren bekommen. An dieser Stelle danken wir euch hier noch einmal ganz herzlich für eure Geduld. Auf der anderen Seite freuen wir uns sehr darüber, drei neue Kolleg*innen dazugewonnen zu haben, die uns maßgeblich im Frontend, in der Konzeption und Projektorganisation unterstützen. Damit sind wir aber noch lange nicht am Ende, denn im Backend suchen wir immer noch dringend nach Verstärkung. Im vergangenen Jahr haben wir im Hinblick auf die Mitarbeitersuche erstmals in der Firmengeschichte einen eigenen, kleinen Konferenzstand auf der FrOSCon12 betreut und im nächsten Jahr legen wir direkt noch einen drauf: Ab Januar könnt ihr an ausgewählten Bushaltestellen im Bonner Stadtgebiet unsere knallorangene Stellenanzeige bewundern. 

Eine weitere große Veränderung dieses Jahr betrifft die Art und Weise, wie wir unsere Aufgaben organisieren. Seit einigen Monaten sind wir damit beschäftigt, dafür ein sogenanntes Kanban-System in unsere Projektabläufe zu integrieren (dazu sicherlich zu einem späteren Zeitpunkt einmal mehr). Auch wenn wir noch nicht am Ende angelangt sind, so haben wir doch das Gefühl, schon einiges in eine sehr positive Richtung bewirkt zu haben. Insgesamt erhoffen wir uns von der Umstellung eine Intensivierung unseres Arbeitsfokus, einen schnelleren Durchlauf der einzelnen Aufgaben und eine Verbesserung in der Vorhersagbarkeit von Projektlaufzeiten. 

Bei aller Ernsthaftigkeit darf aber auch der Spaß nicht zu kurz kommen, dieses Jahr zum Beispiel in Form eines Paintball-Teamevents. Und auch, wenn es vielleicht nur eine Kleinigkeit ist, freuen wir uns darüber, dass wir uns nach wie vor jeden Mittag zu einem gemeinsamen und vor allem selbst zubereiteten Essen zusammenfinden. Wir glauben, dass wir nur dann zur Höchstform auflaufen, wenn wir zufrieden mit dem sind, was wir tun und wenn wir nicht nur auf Effizienz und Output blicken, sondern ebenso auf soziale Faktoren achtgeben. Somit versuchen wir in unserer Firma einen Ort zu schaffen, an dem alle offen und ehrlich miteinander reden können und auch den Bedürfnissen einzelner Raum gegeben wird. 2017 konnten wir wieder einen stattlichen Jahresbonus an all unsere Mitarbeiter ausschütten und dem Team mit der Zahlung eines 13. Gehalts eine Freude machen. Zum Jahresende haben sich auch auf der sozialen Ebene noch einige Neuerungen ergeben: Seit kurzem bieten wir allen Mitarbeitern die Möglichkeit, jeden Morgen vor Arbeitsbeginn an einer fünfminütigen Meditationsübung teilzunehmen. 2018 wollen wir außerdem ausprobieren, wie sich das Leben mit einem Bürohund anfühlt. 

Zu guter Letzt bleibt nur noch zu sagen: Wir freuen uns auf 2018 und sind gespannt, was das neue Jahr zu bieten hat!

Wir wünschen euch allen fröhliche Weihnachten und einen guten Start in das neue Jahr.

Herzliche Grüße
eure webfactory 

]]>
Tue, 19 Dec 2017 13:55:47 +0100 https://www.webfactory.de/blog/ein-paar-worte-zum-schluss-2017 https://www.webfactory.de/blog/ein-paar-worte-zum-schluss-2017 webfactory GmbH webfactory GmbH 0
UXBN@webfactory zu Performance und UX-Test-Methodenmix Nachdem die Teilnehmer gemütlich eingetroffen und mit Getränk und Snacks in der Hand in eine erste Networking-Runde gestartet waren, machte unser Kollege Søren mit seinem Vortrag zu Performance als neuer UX-Grundanforderung den Anfang.

Nach einer kurzen Einordnung, warum Performance (im Sinne von schnellen Ladezeiten und zügig verfügbarer Interaktivität auf Webseiten oder in Apps) ein wichtiges Thema ist, führte Søren die Anwesenden durch eine Reihe von Erkenntnissen der Neurowissenschaften zu Zeit, Zeitwahrnehmung und vor allem der "Psychologie des Wartens". Wichtigstes Take-away: es gibt einen erheblichen Unterschied zwischen objektiv messbarer Zeit und dem, was das menschliche Hirn daraus macht. 

Neben der Unterstützung von Entwicklern bei der Reduktion der objektiven Ladezeiten können sich UX-Spezialisten genau diesen Unterschied mit schlauen Tricks zu Nutze machen, um einen wichtigen Beitrag zur Optimierung der vom Nutzer empfundenen ("perceived") Performance zu leisten. Søren stellte dazu sieben Maßnahmen anhand von praktischen Beispielen vor.

Nach kurzer und diskussionsreicher Pause ging es weiter mit Bastian Weber, der extra aus dem fernen Dresden angereist war, um uns Lehren aus der täglichen Arbeit mit A/B-Tests bei der m-pathy GmbH näherzubringen.

Bastian stellte vor allem heraus, dass A/B-Tests nur eine von vielen Methoden sind, sich einer optimalen User Experience anzunähern. Insbesondere gab er zu bedenken, dass ein A/B-Test nicht notwendigerweise ein korrektes Gesamtbild zeigen muss: In einem Beispiel wären A/B-Tests zur Verbesserung der Absprungraten auf einer bestimmten Seite (hier: Liste von Suchergebnissen) nicht sinnvoll gewesen, da das Problem der Nutzer tatsächlich auf der vorherigen Seite (hier: dem Suchformular) lag.

Neben der Empfehlung, immer lieber auf einen guten Methodenmix zu setzen, als sich auf eine "Lieblingsmethode" zu beschränken, gab Bastian noch ein paar Tipps, wie man zu guten Test-Hypothesen kommt – und wie nicht. 

Nach den beiden Vorträgen ließen wir den Abend bei entspannt-angeregten Gesprächen und netzwerkeliger Atmosphäre langsam ausklingen und freuen uns auf neue UX Themen im nächsten Jahr – sehr gerne auch wieder bei uns im wfLab!

---

* Der Vortrag von Jörg Niesenhaus über Erfahrungen aus 5 Jahren Arbeit mit Gamification musste krankheitsbedingt leider kurzfristig ausfallen, wird aber im Januar beim nächsten UXBN Termin bei Aktion Mensch nachgeholt.
 

]]>
Tue, 12 Dec 2017 13:40:39 +0100 https://www.webfactory.de/blog/uxbn-bei-webfactory-performance-methodenmix https://www.webfactory.de/blog/uxbn-bei-webfactory-performance-methodenmix webfactory GmbH webfactory GmbH 0
Erasmus+ Social Inclusion Days: Dinner in the Dark bei der webfactory Die 21 Teilnehmerplätze für Erasmusstudierende in Bonn waren innerhalb von zwei Stunden nach Beginn der Anmeldung vergeben und wir freuten uns über das große Interesse.

Es galt ein Menü, Tische, Sitzplätze, Geschirr, Besteck und Augendbinden zu organisieren. 

Trotz des engen Zeitplans ist am Freitagabend alles bereit und das dreiköpfige Koch-Team bezieht um 17:30 Uhr die webfactory Küche, wo sie für den Rest des Abends kulinarische Genüsse zaubern. Ab 18 Uhr wird das webfactory Lab umgebaut und Augenbinden werden vorbereitet, bis kurz vor 19 Uhr schon die ersten Gäste eintreffen. Jeder Gast bekommt die Augen verbunden und wird daraufhin zu einem zufällig zugewiesenen Platz an der großen Tafel geführt. 

Als wir den ersten Gang, Feldsalat mit Feta, Granatapfel und Walnüssen, servieren, sind neue Bekanntschaften geschlossen und von oberflächlichen Gesprächen ist keine Spur. Oft wird eine leere Gabel zum Mund geführt, weswegen manche auf manuellere Methoden umsteigen. Für die Organisatoren bieten sich recht amüsante Szenen, zum Beispiel als wir den Teller einer Teilnehmerin entfernen, sodass sie mit Gabel und Löffel den Tisch nach ihrem Salat absucht.

Vor dem Hauptgang servieren wir den Gästen erst noch ein paar Gegenstände, die sie in Teams abtasten, um zu erkennen, worum es sich handelt.

Als Hauptspeise gibt es Nudeln mit Kirschtomaten und Weißweinsauce, welche eine willkommene Abwechslung von den schwer zu befördernden Salatblättern bieten.

Im Anschluss verwöhnt uns das Koch-Team mit einem Bratapfel-Schichtdessert, dessen Keksboden für besondere Verwirrung bei der Identifizierung sorgte.

Bei einem „Dinner in the Dark“ hat man nicht nur ein erhöhtes Geschmacksempfinden, sondern bekommt auch einen Eindruck davon, wie es ist, blind zu sein. Nachdem unsere Gäste die Augenbinden abnehmen dürfen, sagt mir eine Teilnehmerin, dass sie sich zu Hause unbedingt informieren müsse, wie blinde Menschen mit den Herausforderungen zurechtkommen, mit denen Sie sich in den vergangenen zwei Stunden zum ersten Mal konfrontiert sah.

Zum Abschluss zeigen wir zur Belustigung noch die Fotos und Videos des Abends auf der Leinwand.

Unsere Gäste und das ESN Bonn bedanken sich herzlich für die großzügige zur-Verfügung-Stellung der webfactory Räumlichkeiten!

]]>
Mon, 04 Dec 2017 16:24:41 +0100 https://www.webfactory.de/blog/erasmus-social-inclusion-days-dinner-in-the-dark https://www.webfactory.de/blog/erasmus-social-inclusion-days-dinner-in-the-dark webfactory GmbH webfactory GmbH 0
A love letter to the CSS :not() pseudo-class When it comes to CSS and code management, we have long since made the move to BEM and ITCSS with a smattering of Functional CSS. If you haven't heard of one or any of those, have a look at the following articles (familiarity with ITCSS at least is sort of required for the rest of this post):

BEM:

ITCSS:

Functional CSS:

Done? Splendid. Onwards!

As you (now) know, ITCSS was created by Harry Roberts and is essentially a system that helps you to embrace the cascade (the "C" in CSS) and avoid writing convoluted selectors with ever increasing specificity (often referred to as "specificity hell" or "specificity wars") as projects and/or teams grow. ITCSS solves this by organizing your styles in layers from very generic to very specific. Our typical setup for a SCSS-based project follows Harry's layer suggestions quite closely:

  • Settings – Variables for breakpoints, colors, font sizes, …
  • Tools - Mixins & functions
  • Generic - Baseline rules like normalize/reset and box-sizing
  • Elements - Baseline rules for HTML elements, a bit like normalize++
  • Objects - Abstractions and patterns like media object, grids etc.
  • Components - Discrete parts of the UI like buttons and and links, but also composites like accordions, main navigation, page header etc.
  • Trumps - Very specific overrides, mostly functional helper classes for layout (margins, paddings)

Among those, the "elements" layer is dedicated to styling pure HTML element selectors, while the code in the following layers uses classes exclusively (HTML element selectors should be avoided here to keep specificity low).

ITCSS helps us to write styles with the cascade, where we embrace the fact that rules of the same specificity in a lower layer – aka "later" in a concatenated production file - will overwrite earlier rules. However, we make an effort to use overwrites sparsely and avoid complexity (or, as many CSS developers have come to call it, "dark magic").

The  :not()  pseudo-class is the newest tool in our belt for this endeavor. Without it, we used to declare rules for properties like  font-size line-height color font-weight  and especially  margin  in the "elements" layer (i.e. for headings or lists), only to reset them later in the "components" layer for BEM-elements like  news__title  or  accordion__header  that use an appropriate HTML element and not a  <div> . This could be a heading, its level depending on the document outline (i.e.  <h3> ), but it would not necessarily look like a third-level heading.

"Then why do you style classless HTML elements in the first place?", you ask? Excellent question! Let me digress a little.

At webfactory, we help create content-heavy websites that are powered by our content management system (CMS) wfDynamic. Content editors (the people) usually work with so-called WYSIWYG editors (the software) that support text formatting from italic and bold to inserting different types of headlines, lists, tables, links, etc. If you have worked with WYSIWYG editors before, you will know that the good ones produce well-formed, semantic HTML like  <ul><li>…</li></ul>  for unordered lists or  <h2>…</h2>  for sub-headings – HTML without classes.

Obviously, this WYSIWYG content needs to look just as right and correspond to the project's design guidelines as more "handcrafted" components like news teasers or FAQ accordions, where the content is directly retrieved from a database and marked up in a view template by a developer.

This poses a dilemma: It's necessary to style classless HTML elements so WYSIWYG content looks great, but at the same time we don't relish the thought of resetting  margin  or  list-style  for every non-content kind of  <ul>  we want to use in our templates (i.e. for navigation or a tabs component). In the past, we solved this by wrapping any WYSIWYG content in a  <div class="wysiwyg">…</div>  and used the selector to apply our styles contextually, like so:

.wysiwyg {
    h2 { … }
    ul { … }
}

// Note: This kind of rule nesting is a feature provided by SCSS.








The above is a perfectly valid method, but it never felt right. What if we have a design for lists or headings that applies to a majority of all lists or headings with only a few exceptions? The contextual approach requires us to create an additional class with the same styles we used for the  .wysiwyg -selector that can be applied to handcrafted components like  news__title . Again, this is a perfectly valid technique which can be made more maintainable by including a Sass mixin in both use cases (which in turn negates the necessity of a specific class). And still we believed there had to be an easier way that required less code. And there is!

Enter the  :not()  pseudo-class

From MDN web docs:

The  :not()  CSS pseudo-class represents elements that do not match a list of selectors. Since it prevents specific items from being selected, it is known as the negation pseudo-class.

We do not know why it took us so long to realize this, but you can specifically target HTML elements without a class by simply applying  :not([class])  to them.

Here's a simple example of how this looks in a current project:

h2:not([class]) {
    color: #555555;
    font-size: 24px;
    font-weight: 300;
    line-height: 1.2;
}








And a more complex one:

// Due to design and implementation choices, we can reset all our
// unordered lists to a common baseline
ul {
    list-style: none;
    margin-top: 0;
    margin-bottom: 0;
    margin-left: 0;
    padding-left: 0;
}

// All classless unordered lists have an orange bullet and
// are slightly spaced (by applying a margin-top to
// consecutive list items)
ul:not([class]) {
    li {
        line-height: 1.375;
        padding-left: 1.15em;
        position: relative;

        &::before {
            content: '•';
            color: #ff8c00;
            font-size: 1.5em;
            line-height: 1;
            position: absolute;
            top: 0;
            left: .1em;
    }

    + li {
        margin-top: 5px;
    }
}








Suddenly, all our problems vanish into thin air:

  • we can style WYSIWYG content without a contextual class
  • we do not have to overwrite any unwanted rules for our handcrafted components with classes
  • we can benefit from the generic rules for HTML elements whenever we want, simply by omitting to apply a class to them

We have used this approach for the better part of three months now and not encountered any downsides yet.

What do you think?

]]>
Fri, 24 Nov 2017 17:08:56 +0100 https://www.webfactory.de/blog/a-love-letter-to-the-css-not-pseudo-class https://www.webfactory.de/blog/a-love-letter-to-the-css-not-pseudo-class webfactory GmbH webfactory GmbH 0
BonnAgile Meetup zu Gast bei der webfactory mit "Dynamic UI Composition für µServices" Thomas Vidic und Andreas Kluth von REWE digital hatten eine spannende Frage für den letzten Bonner Agile Tech Talk vor der Winderpause mitgebracht: wie geht man mit Frontend-Komponenten für eine Webseite um, wenn hinter der Seite bis zu 25 Entwicklerteams stehen, die möglichst autonom an Microservices arbeiten sollen?

Die Entwicklerszene ist sich grundsätzlich einig, dass eine Microservice Architektur für viele Projekte mehr Vor- als Nachteile mit sich bringt, weil sie vor allem ermöglicht, dass mehrere Entwicklungsteams unabhängig voneinander arbeiten können, ohne viel Kommunikations- und Koordinationsaufwand zu erzeugen. Tatsächlich ist eine klare Kapselung von Aufgaben im Sinne der Unix-Philosophie ("Do one thing and do it well") im Backend recht einfach möglich, weil man Funktionen wie "Nutzer kann sich mehrere Produktfotos ansehen" und "Nutzer kann ein Produkt in den Warenkorb ablegen" völlig unabhängig voneinander betrachten und umsetzen kann. Dagegen gibt es im Frontend (also "im Browser") die Herausforderung, viele dieser programmatisch deutlich unterscheidbaren Funktionen auf einer Seite gleichzeitig und nebeneinander anzuzeigen. Hier entstehen schnell viele Fragen im Hinblick auf konsistentes User Interface (UI) versus autonome Entwicklung, duplizierten Code versus geteilte und versionierte Komponenten, usw.

Thomas skizzierte in seinem Vortrag die Erfahrungen, die REWE digital in den letzten Jahren in diesem Bereich gemacht hat, und stellte drei grundlegende Herangehensweisen vor, die sie für ihre Architektur evaluiert haben:

  1. Frontend-"Monolith" – ein dediziertes Frontend-Team verantwortet das gesamte User Interface und konsumiert von anderen Entwicklerteams hauptsächlich Daten über API-Endpunkte.
    Hauptvorteil: "alles aus einer Hand", damit konsistente Gestaltung und kein wild wuchernder Code
    Hauptnachteil: skaliert schlecht, ein Team wird zum Flaschenhals für alle anderen Teams
  2. "Micropages" – Jede Seite wird als eigenständiger Service betrachtet und isoliert von einem zuständigen Team verwaltet und vertikal integriert, d.h. Backend und Frontend liegen im gleichen Team und eine überall verwendete Komponente wie die Navigation wird im Zweifelsfall von jedem Team neu umgesetzt.
    Hauptvorteil: Maximale Autonomie mit Null Abhgängigkeiten
    Hauptnachteil: Maximale Code-Duplikation bei großer Gefahr von visueller/funktionaler Inkonsistenz
  3. "Dynamic Frontend Composition" — Kritische und komplexe Features kommen vollständig (Backend und Frontend) aus dedizierten Teams und werden von anderen Teams über Integrationsmechanismen zu ganzen Seiten zusammengestellt.
    Hauptvorteile: Kritische Features können autonom entwickelt werden und ihre visuelle/funktionale Konsistenz wird durch die Einbindung zur Laufzeit in ihrer jeweils aktuellen Version zu jedem Zeitpunkt gewährleistet
    Hauptnachteil: Teams, die übergeordnete Seiten verwalten und kritische Komponenten einbinden, verlieren ein Stück weit die Kontrolle über diese kritischen Bestandteile "ihrer" Seiten

Im Folgenden ging Thomas näher auf Details ihrer auf der "Dynamic Frontend Composition" basierenden, aktuellen Architektur ein und schilderte erste Erfolge bei ihrer kürzlichen Umstellung der "In den Warenkorb"-Komponente. Er stellte dazu den "Dynamic User Interface Composer" (DUC) vor, der ähnlich wie Zalandos tailor für die Komposition unterschiedlicher Teile einer Seite zum fertigen Endergebnis im Browser des Nutzers verantwortlich ist.

Im Anschluss an den Vortrag entwickelte sich eine spannende Diskussion mit vielen Detailfragen, so dass der zweite Teil des Abends mit etwas Verspätung erst um 21:00 Uhr weiterging. Andreas Kluth hatte sich zur Aufgabe gemacht, den von REWE digital in Node.js entwickelten (und proprietären) DUC in Java nachzubauen, um einerseits zu zeigen, dass "Java noch lange nicht tot ist" und andererseits eine Implementierung der Kernidee ihrer Software als Open-Source veröffentlichen zu können.

Andreas nahm die Zuschauer mit auf eine geführte Tour durch die Implementierung einer Demo-Produktseite und konnte zum Schluss sogar in unter 10 Minuten beispielhaft einen neuen Service ins Leben rufen, über den eine Empfehlungen-Komponente dynamisch in die Produktdetailseite integriert wurde. Chapeau!

Wir haben uns sehr über die exzellenten Vorträge und die rege Teilnahme gefreut, und hoffen, dass BonnAgile nicht zum letzten Mal bei uns zu Gast war. Vielen Dank an dieser Stelle noch einmal besonders an Andreas, der neben seinem Vortrag ganz nebenbei auch die Organisation der Meetup-Reihe mitverantwortet.

]]>
Fri, 10 Nov 2017 08:47:47 +0100 https://www.webfactory.de/blog/bonnagile-meetup-zu-gast-mit-dynamic-ui-composition-fuer-microservices https://www.webfactory.de/blog/bonnagile-meetup-zu-gast-mit-dynamic-ui-composition-fuer-microservices webfactory GmbH webfactory GmbH 0
Reste retten nach Feierabend: Rudirockt bei der webfactory So kam es, dass ich am 13. Oktober schon zum dritten Mal bei “Rudirockt" bzw. in diesem Fall bei "Rudi rettet Reste” in unserem schönen Bistro servieren konnte.

Rudirockt wurde 2005 von vier Aachener Studenten konzipiert, um Studenten dabei zu helfen Kontakte zu knüpfen. Die Idee haben sie auf der Website rudirockt.de umgesetzt, ein soziales Netzwerk für stadtübergreifende “running dinner”. Man meldet sich in Zweier-Teams an und muss nur noch die Adresse der Küche angeben. Einen Tag vor dem Event erhält man dann eine generierte “Route” zugeschickt, dort steht wo und bei wem man jeweils die Vor-, Haupt- und Nachspeise isst.

Man kann sich Rudirockt als soziales Drei-Gänge-Menü vorstellen: Bei jedem Gang kommen drei Teams (also sechs Personen) zusammen und die Gruppen variieren jedes Mal, sodass man an diesem Abend mit insgesamt zwölf verschiedenen Personen aus den anderen Teams gegessen haben wird.

Die webfactory bietet mit der reich ausgestatteten Küche und dem gemütlichen Bistro inklusive Tischkicker die optimale Location für ein solches Event.

Während ich bei den letzten beiden Events die Hauptspeise als Wunschgang angegeben habe, entschloss ich mich dieses Mal für die Nachspeise, denn diese hat den Vorteil, dass die Gäste nicht noch weiter zum nächsten Gang gehen müssen.

Zum Nachtisch haben wir Käsekuchen nach österreichischem Rezept und eine Cidre-Bowle serviert, während die Zitronen und Orangen für Letztere ganz nach dem Motto "Rudi rettet Reste" von Foodsharing kamen. Außerdem gab es noch veganen Vanillejoghurt mit selbstgemachter Erdbeermarmelade, da wir aus der Route entnehmen konnten, dass sich ein Gast vegan ernährt.

Bei interessanten Gesprächen und viel Lachen klingelte es plötzlich an der Tür. Vier Rudirocker sind auf das fröhliche Treiben im Bistro aufmerksam geworden und haben außerdem ein Team vom vorhergehenden Mittagessen durch die großen Fenster erspäht. Selbstverständlich lud ich sie ein, sich dazu zu gesellen und so vergrößerte sich unsere Runde.

Nachdem noch zwei Freunde meines Nachtischteams dazugestoßen sind, waren wir komplett und nach einem durstlöschendem Kartenspiel war auch die Cidre-Bowle längst ausgetrunken.

Mit diesem Blog-Beitrag möchte ich mich für die tollen Möglichkeiten bedanken, die mir die webfactory sowohl im Beruf, als auch in der Freizeitgestaltung bietet :-)

Rudirockt wurde 2013 sogar bei “Land der Ideen” ausgezeichnet.
 

]]>
Mon, 30 Oct 2017 15:42:29 +0100 https://www.webfactory.de/blog/reste-retten-nach-feierabend-rudirockt-bei-der-webfactory https://www.webfactory.de/blog/reste-retten-nach-feierabend-rudirockt-bei-der-webfactory webfactory GmbH webfactory GmbH 0
Was sind eure Lieblings-Fachbücher? Wir haben die Besucher der FrOSCon-Konferenz gefragt Insgesamt haben wir in unserer Auswertung 329 einzelne Nennungen berücksichtigt. Eine geringe Anzahl an Titeln konnten wir leider bei aller Mühe nicht entziffern. Diese haben wir hier nicht weiter beachtet. Wir sprechen im folgenden Text auch von „Publikationen“ statt von „Büchern“, da nicht jeder genannte Titel auch ein Buch im eigentlichen Sinne war. Die 329 Nennungen haben wir dann zunächst in „fachfremde Publikationen“ einerseits und „fachspezifische“ bzw. „fachnahe Publikationen“ andererseits eingeteilt. Es stellte sich nämlich heraus, dass die Umfrageteilnehmer es mit der Bitte um Nennung von Fachbüchern nicht ganz so eng gesehen haben. Unter die „fachfremde“ Kategorie fielen somit sowohl einige Comics, als auch belletristische Werke wie die „Harry Potter“- oder „Game of Thrones“-Reihe (wobei wir uns bei letzterer gar nicht ganz sicher sind, ob sie wirklich so fachfremd ist: Immerhin verdeutlicht das GOT-Universum doch sehr anschaulich, welche Probleme eine existierende Konkurrenzsituation auf dem Markt mit sich bringt und wie man damit umgehen kann). Außerdem haben wir Publikationen sowie Texte anderer Fachrichtungen – zum Beispiel aus der Astrophysik oder aus dem juristischen Fachbereich – in die „fachfremde“ Kategorie eingeordnet. Wie man Abbildung 1 entnehmen kann, machte diese Gruppe insgesamt 19,1 % der genannten Publikationen aus. 

Abbildung 2 wiederum verdeutlicht, wie sich die „fachnahen“ und „fachspezifischen Publikationen“ zusammensetzten. Als „fachspezifisch“ haben wir dabei Titel eingeordnet, die sich tatsächlich direkt mit Themen aus dem IT- und Webbereich beschäftigen. In die „fachnahe“ Kategorie wiederum fielen themenverwandte Publikationen aus Bereichen wie Projektmanagement, Mathematik oder den Ingenieurwissenschaften. Ein Buch zur Aerodynamik hat uns bei der Einteilung dabei einige Kopfschmerzen bereitet. Wir haben es aber letzten Endes unter „fachnahe Publikationen“ gezählt – wer weiß, was der interessierte Leser an Informationen daraus mitgenommen haben mag. ;-)

Der Großteil der „fachspezifischen“- und „fachnahen Publikationen“ waren in der Tat Einzelnennungen; uns bot sich also ein sehr diverses Bild. Um das Ganze trotz der Diversität der Titel dennoch grafisch irgendwie sinnvoll darstellen zu können, haben wir uns maßgeblich auf die Publikationen konzentriert, die mehr als 3 unabhängige Nennungen erhalten haben. Dies traf auf insgesamt 8 Bücher (hier auch im tatsächlichen Wortsinne zu verstehen) zu, wobei wir zwei von diesen (LPIC-1 und LPIC-2) für unsere Darstellung zusammengefasst betrachtet haben. Als Spitzenreiter (mit insgesamt 16 Nennungen; also 6 %) stellte sich „Clean Code“ von Robert C. Martin heraus, was auch eines unserer eigenen Lieblingsbücher ist. Bei drei der Titel mussten wir ein bisschen raten, was genau gemeint sein könnte, weil es beispielsweise mehrere Buchtitel mit demselben Namen aber unterschiedlichen Autoren gab. Dies war der Fall bei den Titeln: „Linux-Server“, „Modern operating Systems“ und „Design Patterns“. Unter dem genannten Titel „Java ist auch eine Insel“ wiederum finden sich verschiedene Bücher mit unterschiedlichen Subtiteln, die allerdings alle von Christian Ullenboom geschrieben sind.

Grafische Auswertung der FrOSCon-Umfrage

]]>
Mon, 09 Oct 2017 15:58:47 +0200 https://www.webfactory.de/blog/was-sind-eure-lieblingsfachbuecher-wir-haben-die-besucher-der-froscon-konferenz-gefragt https://www.webfactory.de/blog/was-sind-eure-lieblingsfachbuecher-wir-haben-die-besucher-der-froscon-konferenz-gefragt webfactory GmbH webfactory GmbH 0