Ein Plädoyer gegen Outsourcing

cats-phone[1]

Nachdem ich immer und immer wieder mit Argumenten für Outsourcing – oder auch “Near-/Off-Shore Development” oder wie man es auch immer nennen schönreden möchte – überschwemmt werde, möchte ich nun ein für alle mal klarstellen: Outsourcing ist eine schlechte Idee.

In meiner Heimat, der Software-Entwicklung, bedeutet Outsourcing, dass die Entwicklung (oder ein Teil davon) an einen meist geografisch deutlich entfernten und preislich (zumindest auf den ersten Blick) äußerst begünstigten Ort ausgelagert wird. Nicht zu selten kann es sich dabei um eine (Tochter-)Firma in einer indischen (in Bangalore haben IBM, HP, Accenture etc. Niederlassungen), kanadischen, irischen oder einer auch (nah-)östlichen Stadt handeln. So kann man sich Software in vermeintlich lukrativen, weil anfangs deutlich kostengünstigeren, (Sub-)Unternehmen erstellen lassen.

Warum überhaupt?

Nicht selten wird outgesourced, da das Know-How im eigenen Unternehmen fehlt und ebenso die Zeit, dieses aufzubauen. So werden als Quick’n’Dirty-Alternativen Dienstleister engagiert, die das Gewünschte anbieten und mit einem Stundensatz bestechten, der bei vielleicht nur einem Drittel von dem in Österreich/Deutschland liegt. Auf dem Prinzip der Auslagerung basiert ja eigentlich die gesamte IT-Branche, da Aufträge an andere vergeben werden und gern für ein fertiges Produkt inkl. Gewährleistung gezahlt wird – ein sowieso vollkommen veralteter Gedanke, Software als in sich abgeschlossenes Werk zu betrachten. Denn Software lebt! Wird Software nicht mehr weiterentwickelt, stirbt sie fast augenblicklich.

Häufig wird Outsourcing so eingesetzt, dass billige “Fachkräfte” eingekauft werden, um einen Engpass im Unternehmen auszugleichen. So wird ein Teil der Entwicklung dann vielleicht nach Bangalore ausgelagert, aber das Management bleibt in Wien. Dabei werden aber oft einige Kosten nicht mitgerechnet, wie der Mehraufwand in der Qualitätssicherung, der Kommunikation oder der (Wieder-)Eingliederung des Know-Hows in das Unternehmen. Kurzfristig lassen sich sehr wohl Kosten reduzieren, aber langfristig halst man sich ein teures Problem auf, das man vermeiden hätte könnten.

Die Lüge

Was häufig bei Outsourcing zugunsten der hübsch niedrigen Zahlen für den Entwicklerstundensatz vergessen wird, ist:

  • Persönliche Kommunikation kann NICHT ersetzt werden.
    Im Sinne von Scrum sitzt das Entwickler-Team möglichst im selben Zimmer.
  • Kulturelle Unterschiede zwischen Entwicklern unterschiedlicher Länder.
    Das bedeutet vor allem Arbeitsmoral und Loyalität.
  • Verständigungsprobleme aufgrund unterschiedlicher Sprachen.
  • Der immer unterschätzte Koordinationsaufwand.
    Wenn wir Entwickler schon schwer verstehen, was das Marketing will, obwohl wir beim selben Meetingraum sitzen…
  • Know-How-Verlust.
  • Höherer Planungsaufwand.
    Auch nach Fertigstellung des Projektes zur Reintegration ins auftraggebende Unternehmen.
  • Enorme Qualitätssicherungskosten.
    Zumindest das Userinterface muss erneut wieder von einem deutschen Native Speaker überprüft werden. Rechtschreib- und Grammatikfehler werden nicht erkannt.
  • Verlust des informellen Informationsaustausches.
    Plauderei beim Mittagessen etc.
  • Schlechtes Image.
    Die Zeiten, als Outsourcing noch als gute Möglichkeit gewertet wurde, sind definitiv vorbei.
  • Verlagerung der Wirtschaftsleistung weg ins Ausland.
    Besonders gefällt mir die Beschreibung bei der Vergabe des Negativpreises des Unwort des Jahres (und das war schon 1996!):
    Imponierwort, das der Auslagerung/Vernichtung von Arbeitsplätzen einen seriösen Anstrich zu geben versucht”

Outsourcing macht meines Erachtens nur Sinn, wenn:
– es sich nicht um das Kerngeschäft des Unternehmens handelt,
– es ein in sich abgeschlossenes englischsprachiges Projekt handelt (und alle “Externen” auch gut Englisch können),
– nicht agil entwickelt wird (allerdings sowieso eine Todsünde – Ich schlafe ja bekanntlich mit dem Agilen Manifest unter dem Kopfkissen. Und das ruhig und sehr zufrieden).

Machen wir es richtig!

Die Alternative zu Outsourcing liegt somit auf der Hand: Aufbau eines qualifizierten (agilen) Teams als eigene Abteilung oder Subunternehmen in unmittelbarer Nähre zum Produktmanagement statt Ausgliederung. Sollen einzelne Mitarbeiter (kurzfristig) ersetzt werden, dann können das gern externe sein, die sich aber möglichst stark ins Team integrieren (Anwesenheit). Outsourcing sollte nur im äußersten Notfall in Erwägung gezogen werden, und am besten nicht mal dann. Lieber qualifizierte Software-Entwickler einladen und Know-How im eigenen Unternehmen aufbauen. Versteht mich nicht falsch, ich bin nicht eine, die glaubt, dass ihre Mitarbeier nur dann arbeiten, wenn ich sie sehe. In einem gut eingespielten Team kann Homeoffice durchaus üblich sein… aber das zu erörtern sprengt nun hier wohl den Rahmen.

Ich liebe und lebe agile Software-Entwicklung und arbeite gern eng mit meinen Mitarbeitern, Kollegen und Kunden zusammen. Als Scrum-Master kenne ich die Vorteile von Transparenz, Kommunikation und Innovation und bringe diese täglich zum Einsatz.

Naja. Und falls jemand diesbezüglich eine Beratungsleitung von mir in Anspruch nehmen möchte… Nun ja, ihr wisst ja, wo ihr mich findet. ;)

Update: Ein weiterer Artikel im Standard gegen Outsourcing in öffentlichen Vergabeverfahren http://mobil.derstandard.at/1397520665108/Sozialpartner-Oeffentliche-Auftraege-nicht-an-Billigstbieter

cat-content-540x304[1]

Java: break, continue, return in Loops

Although this is pretty basic Java functionality I often have to look this up, because I confound these calls, esp. break and continue. So this is my cheat sheet:

Break

for (..) {
  ..
  // leave loop immediately
  break;
  ..
}

Continue

for (..) {
  ..
  // continue loop with next iteration
  continue;
  ..
}

Return

for (..) {
  ..
  // leave calling method
  return;
  ..
}

Meine erste Android App

Für mein Foodblog chefbabe.at habe ich eine Android App geschrieben:

chefbabe_app

Sie repräsentiert die Android App Version des Foodblogs chefbabe.at

Die köstliche Chefbabe App ist da! :)

chefbabe.at jetzt auch auf deinem Android-Telefon.
Nie mehr ein Rezept versäumen mit der Sofort-Benachrichtigung.
Kreative Idee gefällig? Einfach schütteln!

google play

Features:
– Liste der Rezepte inkl. “Schmökern”-Ansicht (nur Bilder), Nachladen bei Scrollen, Ansicht des Blogbeitrags, “Neu laden”…
– Schüttelfunktion! (Zufallsrezept)
– Benachrichtigungen bei neuen Rezepten
– Teilen eines Rezepts
– Suchen
– Über-Seite (wer kocht hier?)

Chefbabe.at ist das erste Foodblog* mit eigener App. Viel Spaß beim Mitnaschen! :)

Herunterladen und Bewerten unter: https://play.google.com/store/apps/details?id=at.electrobabe.chefbabe

Migrating a Full Text Search

Zusammen mit meinen Kollegen Siegfried Goeschl und Andreas Rappold habe ich ein Paper über unsere Arbeit bei willhaben.at geschrieben. Wir haben in einem groß angelegten Projekt die bestehende Suchmaschine (ESP FAST) für die Volltextsuche bei willhaben durch ein neues Open Source System (Apache SOLR) ersetzt. Wie wir das ganze geschafft haben und welche Testansätze wir verfolgt haben, kann man im PDF MigratingAFullTextSearch erfahren.

Der Beitrag ist beim Ministry of Testing in der Rubrik “The Testing Planet” erschienen.

ministry of testing logo

Nexus 4 vs. Galaxy Nexus

Nun ist es schließlich doch so weit, dass das neueste Nexus (Nexus 4, dieses mal von LG statt Samsung) den Weg in meine nach Technik geifernden Hände gefunden hat.

nexus

Der Grund fürs Wechseln: Beim Galaxy Nexus ist mir innerhalb der letzten einundhalb Jahre, die ich es hatte, zweimal das Gorilla-Glass-Display gesprungen, obwohl es mir aus nicht allzu hoher Höhe aus der Hand gerutscht ist. Das Display zu tauschen kostet beim Galaxy Nexus allerdings satte 200€ (da nicht nur das Glas, sondern auch die angebrachte Platine und somit eigentlich fast das gesamte Grät getauscht wird), deswegen habe ich beim zweiten Glasbruch entschieden, doch ein neues Gerät zu kaufen.

Der aufmerksame Leser kann sich wohl noch an meinen Artikel Galaxy Nexus vs. Nexus S erinnern, deswegen möchte ich auch hier einen Vergleich anstellen:

  • Beeindruckend war vor allem der Preis, denn ich hab das Nexus 4 bei einem Angebot um 330€ gekauft. Das Galaxy Nexus kostet jetzt neu noch immer etwa das Gleiche.
  • Das Nexus 4 ist selbstverständlich wieder deutlich schneller als das Galaxy Nexus, hat ein besseres Display und einen ausdauernderen Akku.
  • Wovor ich schon von Freunden gewarnt worden bin: Die Hinterseite des Nexus 4 bestehlt auch aus Glas und ist daher besonders rutschig (beim Galaxy Nexus war die Hinterseite hübsch ergonomisch geformt und hatte eine Struktur), allerdings hat mein Nexus 4 zwei kleine Knubbeln (die gibts erst ab einer neueren Version), die den Sound der unten gelegenen Lautsprecher verbessern und außerdem die Unterseite nicht ganz so rutschig machen.
  • Wie es bereits keine herausnehmbare Micro-SD-Karte gibt, kann man nun beim Nexus 4 nicht mal mehr schnell den Akku austauschen, da das Gerät komplett verarbeitet ist.
  • Das Nexus 4 arbeitet mit einer Micro-SIM statt einer normalen SIM-Karte – da musste ich mal schnell die Schere zücken ;)
  • Die Kamera vom Nexus 4 kann jedenfalls nur besser werden, da die vom Galaxy Nexus leider nicht so besonders war.
  • Auf das Wireless Charging (über Induktion) bin ich auch noch sehr gespannt :)

Wem das nicht gereicht hat, hier gibt es noch weitere 19 gute Gründe, um vom Galaxy Nexus auf das Nexus 4 umzusteigen. Hübsche Vergleichsbilder  gibt auf engadget.

Beim Handy-Neueinrichten hat mir übrigens wieder meine Checkliste geholfen.

re:publica 2013 in Berlin

re:publica

Dieses Jahr hab auch ich mich zur re:publica in Berlin eingefunden, einer Konferenz über digitale Medien – dem Woodstock für Onliner.

Neben zahlreichen Österreichern (twittert denn gerade überhaupt jemand aus Wien?!) sind selbstverständlich viele andere internationale Gäste zum selbsternannten “Happening” gepilgert. Ob es die Reise wert war, weiß ich noch nicht, allerdings kann ich schon vorab den ersten Tag kurz resümieren: Viel Interessantes, viel Fades, viel Inspirierendes – wie auf jeder Konferenz.

Eine Zusammenfassung der Konferenz folgt selbstverständlich.
re:publica 13

Best of Source Code Comments

via http://kalekushal.blogspot.co.at/2012/01/funny-source-code-comments.html

/**
* For the brave souls who get this far: You are the chosen ones,
* the valiant knights of programming who toil away, without rest,
* fixing our most awful code. To you, true saviors, kings of men,
* I say this: never gonna give you up, never gonna let you down,
* never gonna run around and desert you. Never gonna make you cry,
* never gonna say goodbye. Never gonna tell a lie and hurt you.
*/

//
// Dear maintainer:
//
// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
//
// total_hours_wasted_here = 16
//

// TODO: Fix this. Fix what?

// no comments for you
// it was hard to write
// so it should be hard to read
// I will give you two of my seventy-two virgins if you can fix this.

options.BatchSize = 300; //Madness? THIS IS SPARTA!

// I am not responsible of this code.
// They made me write it, against my will.

//Dear future me. Please forgive me.
//I can't even begin to express how sorry I am.

double penetration; // ouch

# To understand recursion, see the bottom of this file.
At the bottom file:
# To understand recursion, see the top of this file.

//I am not sure why this works but it fixes the problem.

//somedev1 - 6/7/02 Adding temporary tracking of Logic screen
//somedev2 - 5/22/07 Temporary my ass

/*
* You may think you know what the following code does.
* But you dont. Trust me
* Fiddle with me, and youll spend many a sleppless
* night cursing the moment you thought you be clever
* enough to "optimize" the code below.
* Now close this file and go play with something else.

// drunk, fix later

// Magic. Do not touch.

Exception up = new Exception("Something is really wrong.");
throw up; //ha ha

//When I wrote this, only God and I understood that I was doing
//Now, God only knows

// if i ever see this again i'm going to start bringing guns to work

/*
* OK; before you read the following code know what I am trying to do.
* I needed to get the list of child catagories from the root node so that
* the root node didn't appear in the selection box. But for some stupid
* fucking reason the stupid fucking DBA wont let me access the items using
* indices and I instead have to use their stupid fucking Iterator
* implementation. So there.
*/
$firstList = $this->getRootNode()->getChildren();
foreach ($firstList as $node)
{
$nodes = $node->getChildren();
break; // wtf?
}

SyBase: List Constraints to Foreign Key

select
fko.name    "Foreign key name",
par.name    "Referenced table name",
fk1.name || ' -> ' || pk1.name "Reference 1",
fk2.name || ' -> ' || pk2.name "Reference 2",
fk3.name || ' -> ' || pk3.name "Reference 3",
fk4.name || ' -> ' || pk4.name "Reference 4"
from
sysobjects      tab                                       join
sysconstraints  con on tab.id        = con.tableid        join
sysobjects      fko on con.constrid  = fko.id             join
sysreferences   ref on con.constrid  = ref.constrid       join
sysobjects      par on par.id        = ref.reftabid  left join
---- 1. Column
syscolumns      fk1 on ref.fokey1    = fk1.colid and
ref.tableid   = fk1.id        left join
syscolumns      pk1 on ref.refkey1   = pk1.colid and
ref.reftabid  = pk1.id        left join
---- 2. Column
syscolumns      fk2 on ref.fokey2    = fk2.colid and
ref.tableid   = fk2.id        left join
syscolumns      pk2 on ref.refkey2   = pk2.colid and
ref.reftabid  = pk2.id        left join
---- 3. Column
syscolumns      fk3 on ref.fokey3    = fk3.colid and
ref.tableid   = fk3.id        left join
syscolumns      pk3 on ref.refkey3   = pk3.colid and
ref.reftabid  = pk3.id        left join
---- 4. Column
syscolumns      fk4 on ref.fokey4    = fk4.colid and
ref.tableid   = fk4.id        left join
syscolumns      pk4 on ref.refkey4   = pk4.colid and
ref.reftabid  = pk4.id        -- Et cetera...
where
tab.type = 'U'      and
fko.name = 'FOREIGN_KEY_NAME' and
fko.type = 'RI'

no comment ;)

How developers feel

via http://www.lordofthejars.com/2013/02/the-reality-of-developers-life.html (see more at http://devopsreactions.tumblr.com/)

 

When you upload something to production environment:

When you find a problem solution without searching in Google:

When you close your IDE without saving the code:
 
When you try to fix a bug at 3AM:
 
When your regular expression returns what you expect it:
 
When my boss reported me that the module I have been working will never be used:
 
When I show to my boss that I have fixed a bug:
 
When I upload a code without tests and it works as expected:
 
When marketing folks show to developers what they have sold:
 
The first time you apply a CSS to a web page:
 
When the sysadmin gives you root access:
 
When you run your script the first time after several hours working on it:
 
When you go on weekend and everyone else are at office trying to fix all issues:
 
When your boss finds someone to fix a critical bug:
 
When you receive an extra paid if project ends before deadline:
When something that had worked on Friday and on Monday did not work:
 
When you develop without specifications:
 
When boss tells me that “tests are for those who doesn’t know how to code”:
 
When you update a database script and you note that you have deleted whole database: