Das Programmierer-Einstellungsinterview: Beispielfragen

Das Programmierer-Einstellungsinterview: Beispielfragen

Es gibt viele verschiedene Sichtweisen bei einem Interview.

Die beste Ausgangslage hat hier derjenige, der sich flexibel in die verschiedenen Standpunkte der Partner hineinversetzen kann. So merkt er schneller, was der Sinn einer Frage ist, welche Antwort die gewünschte sein kann, und ob hinter bestimmten Fragen oder Antworten evtl. Dinge stehen, die auf einen späteren größeren Konflikt hindeuten könnten.

Hier will ich ein paar Beispiele für primär technische Fragen geben, anhand derer bis zu einem gewissen Grade festgestellt werden kann, ob der Kandidat fachlich etwas taugt.

Wichtig ist stets – nicht nur hier – die Qualität der Fragen, die man stellt. Nur, wenn die Fragen bedacht gestellt werden, läßt sich auch aus der Antwort etwas herableiten. Fragen, die Wissen abfragen sind oft weniger sinnvoll als Fragen, die Denkmuster aufzeigen. Wissen läßt sich schnell erlernen und nachlesen – eine Denk- und Herangehensweise hingegen läßt sich oft im Laufe einer Beschäftigung nicht ändern.

AHA-Fragen: Fragen wie in der Public Key Kryptographie

Es gibt eine Reihe von „AHA”-Fragen. Das sind Fragen, die sehr einfach sind, wenn man die Antwort kennt, und (teilweise) bedeutend schwieriger, wenn man eben jene Antwort nicht kennt. (Das erinnert einen vielleicht an Aufgaben mit Public/Private Keys in der Kryptographie. Diese sind mit Public Key zwar auch zu lösen, der Private Key enthält jedoch oft die entscheidende Information, die die Lösung um viele Größenordnungen leichter werden läßt. Um bei dem Beispiele zu bleiben: wer würde die Leistung, einen Code einmal mit Private Key und einmal mit Public Key zu entschlüsseln gleich bewerten? Das sind verschiedene Welten!) Stellt man einem Kandidaten so eine Frage, findet man also insbesondere heraus, ob er die Frage bereits kennt oder nicht, weniger, ob er diese Aufgabenstellung wirklich lösen kann.

Mir wurde einmal folgender Code gezeigt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
 
public class Singleton
{
   private static Singleton instance;
 
   private Singleton() {}
 
   public static Singleton Instance
   {
      get
      {
         if (instance == null)
         {
            instance = new Singleton();
         }
         return instance;
      }
   }
}

Um das ganze etwas spannender zu machen hieß die Klasse dann auch nicht Singleton sondern foo oder so ähnlich.

Wenn man ein Singleton schon einmal gesehen hat, ist der Code leicht zu erkennen. Hat man ein Singleton noch nie gesehen ist die Frage einiges schwerer zu beantworten. Andererseits sollte jeder Programmierer wohl schon einmal ein Singleton gesehen haben. Auch der Anwendungsfall „nur ein Objekt in der gesamten Applikation” ist schnell erklärt. Egal, was der Kandidat sagt, hier ist eher spannend, was er als zweites sagt. Kennt er das Singleton, kann man weiter bohren. Kennt er es nicht, kann man seine Kombinationsfähigkeit testen und ihn evtl. mit kleinen Hinweisen leiten.

Spannender wird es, wenn es um reale Anwendungsfälle geht. Wann wird ein Singleton in der Realität eingesetzt? Hier geht es z. B. um Resourcen(kontrolle), die man nicht per Mutex schützen möchte oder auch um z. B. Konfigurationsdaten, die systemweit verfügbar sein sollten.

Interessant kann auch ein Vergleich mit einer „Sparversion” sein.

1
2
3
4
5
using System;
 
public static class Singleton
{
}

Diese überläßt der Laufzeitumgebung die Erstellung des Objektes und erzeugt das Objekt insbesondere immer, auch wenn es gar nicht benutzt wird (im Gegensatz zu obigem Code).

Auch lassen sich weitere Fragen finden: welche Probleme ergeben sich (mit obiger Version)? Da fallen zum einen parallele Anwendungen ein (siehe die sehr umfangreiche sowie inspirierende Abhandlung von C# in Depth). Zum anderen fielen mir verteilte Systeme ein, wo man aber ohnehin ganz andere Ansätze benutzen muß.

Bücher und Fortbildung

Apropos C# in Depth. Eine gute Frage mag auch immer sein, welches Buch man als letztes gelesen hat. Von Clean Code sollte man zumindest schon einmal gehört haben, auch.. wenn viele Tips dort schlicht nicht umsetzbar sind und auch gar nicht umgesetzt werden sollten. Aber viele Gedanken lassen sich auch gut übernehmen. Ansonsten gibt es natürlich das erwähnte C# in Depth, eines der besten und auch inspirierendsten C#-Bücher. Hier werden einige Besonderheiten der Programmiersprache gut erklärt. Es ist zwar bei weitem nicht so anspruchsvoll wie Bücher über Meta-Template-Programmierung in C++ wie z. B. Modern C++ Design, geht aber trotzdem in die Tiefe und liefert wertvolle Informationen. Sollte man einen C++ Programmierer suchen und man hat jemanden vor sich sitzen, der ein paar Punkte aus dem Buch Modern C++ Design erklären kann sollte man ihn schnell einstellen, auch wenn man Templates gar nicht benutzt. Der Inhalt des Buches setzt ein sehr tiefes Verständnis sowie eine sehr gute Denkfähigkeit beim Leser voraus.

Daneben gibt es zahllose andere sehr gute Bücher, wie z. B. Code Complete. Hat man schon In Search of Stupidity gelesen sollte man hoffen, daß der Kandidate dreimal über das beliebte „Schreiben wir schnell mal alles neu, diesmal mit einem schönen Design, das leicht erweiterbar ist!” nachdenkt und so die Firma nicht in den Ruin treibt, wenn der Hauptumsatzbringen über Jahre keine neuen Verkäufe generiert und die neue Version natürlich (innen) häßlicher ist und 2 Jahre verspätet auf den Markt kommt.

Eigener Code

Ich würde mir auch nicht die Gelegenheit nehmen lassen – wenn der Kandidat schon gezeigt hat, daß er ein wenig auf dem Kasten hat – ihm ein Stück eigenen Code zu zeigen und um Kommentare zu bitten. Das kann natürlich der tolle Code sein, den wir gestern geschrieben haben, und auf den wir unendlich stolz sind, es kann aber auch (besser) ein alter Code sein, für den wir uns schämen, vlt. auch von unserem Vorgänger. Gibt der Kandidat hier ein paar sinnvolle Verbesserungsvorschläge, vlt. sogar mit Hinweisen, wie diese im wahren Leben umgesetzt werden können sowie, wie Zeit für diese gefunden werden kann, ist das eine sehr gute Sache. Tendenziell lebt jedes Stück Code wohl immer doppelt so lange wie geplant, und fängt bereits während der geplanten Lebenszeit damit an, immer schlechter wartbar zu werden – bis man sich schließlich dazu durchringt, alles neu zu schreiben, und diesmal hoffentlich all seine Hausaufgaben gemacht hat – auch, wenn das so gut wie nie passiert (siehe auch den Fall von Netscape und anderen in In Serach of Stupidity).

Was gibt es noch für schöne Fragen?

Fragen, die das analytische Denken prüfen, halte ich für sehr gut. Nur Leute, die sich ausgiebig auf Assessment-Center vorbereitet haben werden mit Fragen wie „Wie viele Smarties passen in einen Smart?” etwas anfangen können. Dabei kann hier jeder einfach zeigen, daß er logisch denken und Rechnungen grob überschlagen kann. Fangen wir mal an.. (alles natürlich nur grob geschätzt und gerundet): ein Smartie ist ca. 1-2mm dick, ich gehe mal von einem Volumen von 0,1cm2 aus. Damit passen in 1 m3 10 x 1003, da ein m3 ja 1003 cm3 enthält. (Dabei vernachlässige ich das Volumen, wo es keine Smarties geben kann, weil es ja aufgrund der Form auch Lücken geben muß.) Also passen in einen m3 ca. 10 Millionen Smarties. Wow, daran kann man lang essen. Ein Smart nun wiederum ist nicht so groß, vielleicht 2 m3 Innenraum. Also würden 20 Millionen Smarties in einen Smart passen, nach meiner Rechnung.

Besonders gerne habe ich die Kandidaten auch immer ein kurzes Programm schreiben lassen. Nur auf dem Papier – was natürlich ganz andere Bedingungen sind als an dem PC. Hier sollte man also nur minimal auf Syntax achten und auch Pseudosprachen zulassen, wenn der Bewerber nicht gerade gesagt hat, er wäre die Kapazität in einer bestimmten Sprache. Auch sollte man die Nervosität nicht unterschätzen. Und stets hilfsbereit sein. Jeder steht mal auf dem Schlauch. Allein.. der gute Bewerber wird mehr (oder alles) allein und zufriedenstellend lösen, während sich andere komplett durch die Lösung ziehen lassen.

Sehr einfache Beispiele von Aufgaben, die ich benutzt habe, sind:

String-Umkehr

1
2
3
4
5
6
7
8
9
char *str;
char tmp;
int len = strlen(str);
for (int i = 0; i < len/2; ++i)
{
  temp = str[i];
  str[i] = str[len-i];
  str[len-i] = temp;
}

So eine Funktion programmiert natürlich nur runter, wer sich ein wenig mit Indices und for-Schleifen auskennt. Typische Fehler sind die Unkenntnis der Swap-Operation (so sparen sich einige z. B. die temporäre Variable), oder der Index wird komplett bis zum Ende gezählt. Eine einfache Variante vertauscht nicht, sondern legt ein zusätzliches Ergebnisarray an, wo der umgekehrte String hingespeichert wird.
Ich habe immer, wenn ich einen Fehler gesehen habe, Fragen gestellt, die entweder direkt auf den Fehler hinzielen, meistens jedoch auch Beispiele für falsche Ausgaben aufgezeigt. Also im Zweifelsfall bereits einen 2 Zeichen langen Eingabestring gegeben und den Kandidaten darum gebeten, den Algorithmus kurz in Gedanken über die Eingabe laufen zu lassen. So wäre z. B. bei einem Index, der bis zum Ende läuft der Ausgabestring gleich dem Eingabestring. Wir der Swap nicht korrekt durchgeführt verändern wir den String zum Palindrom, etc.

Eine andere (sehr) einfache Aufgabe ist der Test, ob eine Zahl einer Zweierpotenz ist. Das schöne hieran ist u. a., daß es nahezu unzählig viele Herangehensweisen gibt. Hier kann auch die Kreativität des Kandidaten geprüft werden.
Beispiele:

  1. Test mit pow-Funktion und Runden (kleine Fehleranfälligkeit)
  2. Kontinuierlich durch 2 dividieren, Rest betrachten: sollte 0 sein, so lange Zahl > 1
  3. Zweierdarstellung betrachten, alle Ziffern rechts neben der linken 1 sollten eine 0 sein (im Endeffekt das gleiche wie Variante 2.

Fortgeschrittene Fragen

Wenn man sich bei Microsoft bewirbt oder auch bei Google, erwarten den Kandidaten ganz andere Fragen – weil hier nur die Besten genommen werden. Das kann man sich als Interviewer zu Nutzen machen und eben jene Fragen dem Kandidaten stellen (einfach mal googlen oder auf nächsten vergleichbaren Beitrag hier warten). Oft geht es hier um komplette Implementierungen mittelkomplexer Probleme, die oft eine besondere algorithmische Lösung haben. Bei Google wird hier (große Datenmengen!) z. B. sehr wert auf Konstrukte wie Hashmaps gelegt. Das läßt sich natürlich nicht direkt auf andere Firmen übertragen. Jemanden, der sehr gut mathematische Algorithmen implementieren kann mag bei Datenbanken passen müssen. (Wobei die Leute, die in der Mathematik und im Allgemeindenken gut sind auch sehr oft gute Programmierer abgeben).

Einfache Beispiele lassen sich auch direkt mit Konstrukten der Sprache verbinden. So sollte z. B. jeder Kandidat gut mit Iteratoren umgehen können – zumindest, wenn es um einen C++ Entwickler geht.

C# Entwickler können spannende Fälle mit dem yield-Schlüsselwort konstruieren. Etwas ähnliches fehlt in vielen anderen Sprachen – hier kann man leicht überprüfen, ob es sich um einen generischen Programmierer handelt oder um einen Programmierer, der die Besonderheiten einer bestimmten Sprache bereits gut beherrscht.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        static IEnumerable<int> YieldTest1()
        {
            for (int i = 0; i < 10; ++i)
                if ((i % 2) == 0)
                    yield return i;
        }
 
        static IEnumerable<int> YieldTest2()
        {
            foreach (int i in YieldTest1())
                if (i > 4)
                    yield return i;
        }
 
        static void YieldTest()
        {
            foreach (int i in YieldTest2())
                Console.WriteLine(i);
        }
 
        static void Main(string[] args)
        {
            YieldTest();
        }

Mit yields lassen sich – wie hier gesehen – insbesondere auch schöne Verschaltungen erzeugen. Daten können so gefiltert oder auch verarbeitet werden. Natürlich gibt es deutlich sinnvollere Anwendungsgebiete als das hier gezeigte Beispiel. Auch sollte einem die Verwandtschaft (zumindest dieser Beispiele) zu einer Linq-Abfrage auffallen.

Probleme lösen lassen, die gerade anliegen

Dieser Ansatz hat viele Vorteile. Einer davon ist, daß man zu dem Zeitpunkt des Interviews sehr gut im Thema drin ist. Ein weiterer Vorteil ist, daß man nur gewinnen kann: evtl. fällt einem Kandidaten die perfekte Lösung ein, auf die man nie selber gekommen wäre. Schließlich läßt sich daraus ein für beide Seiten sehr angenehme Gedankenaustausch herausleiten: aus dem „Wir haben da gerade folgendes Problem..” evtl. noch mit ein paar weiteren Beschreibungen und versuchten Lösungsansätzen läßt sich ein wenig verkrampftes Gespräch ziehen, zumal nur mit minimalem Erfolgsdruck, sollte doch der Kandidat auch schnell merken, daß der Interviewer selber an der Aufgabe zu knabbern hat – alles, was er in der kurzen Zeit des Interviews einwerfen kann wird mehr sein, als der Interviewer erwarten könnte.

Dem Kandidaten sagen, was ihn erwartet

Neulich habe ich von folgendem Sachverhalt bei einem Einstellungsinterview gehört: in der Anzeige (wissenschaftliches Umfeld) wurde kräftig der Himmel auf Erden versprochen – spannende, herausfordernde Anforderungen, die jeden Tag zu einem (positiven) Abenteuer werden lassen. (Bei der Bezahlung wurde wohl nicht viel verschwiegen – die ist mies.) Beim Interview sollten die Kandidaten (es wurden nur die schlechtesten eingeladen – es hatten sich wohl auch Doktoren und Leute mit mehreren Abschlüssen gemeldet) dann u. a. von Diktiergeräten abtippen und ähnliches. Das hatte jedoch mit der Stellenausschreibung wenig zu tun. Und – Insiderwissen – mit der Stelle auch nicht viel, da hat wohl jemand das Gespräch völlig falsch vorbereitet. Natürlich hatte von den Kandidaten auch niemand Lust, unter diesen Bedingungen zu arbeiten.

Was sollte man als wichtige Lehre hieraus ziehen? Realistische Erwartungen wecken und erfüllen – oder sogar überbieten. Und vor allem im Interview und danach auch noch einmal dem Kandidaten die Möglichkeit geben, sich weiter mit dem zukünftigen Aufgabengebiet und den Aufgaben vertraut zu machen. Sollte er nach 2 Monaten kündigen ist auch niemandem geholfen.

Oh, und apropos Erwartungen.. ich frage mich immer wieder, warum so oft in einem Interview gefragt wird, warum ich mich gerade bei der Firma beworben habe. Nun – die Antwort – die ehrliche Antwort – lautet normalerweise: das war nur eine von vielen Firmen, bei denen ich mich beworben habe – und jede wäre für mich genau gleichwertig. Ich hoffe auf gutes Geld, spannende Aufgaben und eine angenehme Atmosphäre. Der Rest ist jedoch komplett austauschbar. Hier sollte man zu Anfang nicht allzuviel erwarten – Loyalität und Begeisterung wachsen sich mit der Zeit, wenn man ihnen einen fruchtbaren Boden bereitet. Aus einem Internetauftritt oder einer bunten Marketingbroschüre ergibt sich so etwas jedenfalls nicht.

Fazit

Es gibt eine Reihe von Punkten, die ein Interview beeinflussen können, evtl. sogar den richtigen Kandidaten verschrecken. Eine angenehme Atmosphäre, in der der Kandidat zeigen kann, was er wirklich kann, ist sehr hilfreich.

Auch ist wichtig, daß der Kandidat Aufgaben löst und dabei die Möglichkeit bekommt, seine Fähigkeiten unter Beweis zu stellen sowie zu glänzen. Und, wenn er dann Aufgaben löst, sollten dies Aufgaben sein, die er sehr wahrscheinlich nicht kennt (zumindest sollte der Interviewer einschätzen können, wie schwierig die Aufgabe für den Kandidaten mit seinen erwarteten Fähigkeiten sein sollte). Hier sollte man ein wenig rumbohren. Es gehört ein vollkommen anderes Fähigkeitengebilde dazu, eine bekannte Lösung wiederzugeben und selber mit einer originellen Lösung in einem bis dato unbekannten Bereich hervorzukommen. Gerade das wird jedoch oft erwartet, und demnach sollte man auch hierauf achten.

Weiterführendes

Hiermit wird die bestehende Serie von Artikeln über Interviews ergänzt.
Das Programmierer-Einstellungsinterview: die Sicht des Programmierers
Das Programmierer-Einstellungsinterview: die Sicht des Interviewers

One thought on “Das Programmierer-Einstellungsinterview: Beispielfragen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.