Interviewantworten II – die erste Antwort

Die Frage war, warum Object.hashCode() und Object.equals(Object) immer beide überschrieben werden sollten.

Die Antwort findet sich direkt in der Javadoc-Dokumentation von Object.hashCode():

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

Vereinfacht gesagt: Überschreibt man nur equals() und es werden zwei unterschiedliche Instanzen einer Klasse verglichen, die laut equals() aber gleich sind, so bricht man den Kontrakt von Object.hashCode(). Die beiden HashCodes wären unterschiedlich, obwohl die Objekte nach equals() gleich sind.

Um das Ganze ein wenig praktischer zu beschreiben, nehmen wir folgende Klasse an:

public class Person {
  private String firstName;
  private String lastName;
  private Date dateOfBirth;
  private String favoriteBeer;

  // ...getter/setter

  // wir nehmen an, zwei Personen sind identisch, wenn sie gleich heißen und am gleichen Tag geboren wurden

  // bitte IMMER @Override nutzen, wenn Java >= 1.5 verwendet wird!
  @Override
  public boolean equals(Object o) {
    Person otherPerson = (Person) o;
    return
      firstName.equals(o.getFirstName()) &&
      lastName.equals(o.getLastName()) &&
      dateOfBirth.equals(o.getDateOfBirth());
  }
}

In obigem Beispiel wurde nur equals überschrieben und dieser Vergleich macht durchaus Sinn. Aber was passiert, wenn wir zwei Personen gleichen Namens und mit gleichem Geburtsdatum in ein HashSet einfügen wollen? Da das HashSet – wie der Name schon sagt – den HashCode eines Objekts als Vergleichsfunktion heranzieht um zu bestimmen, ob dieses Objekt schon einmal im Set vorhanden ist, würden problemlos beide Objekte im Set abgelegt werden. Und das, obwohl sie doch equals() sind! Hier hilft natürlich, eine .hashCode()-Methode zu schreiben, die genau die gleichen Felder berücksichtigt wie .equals().

Das Erstellen von hashCode und equals ist übrigens mit IDEs einfach gemacht. Unter Eclipse kann man über Source -> generate hashCode() and equals() komfortabel auswählen, welche Felder in die Methoden einbezogen werden sollen. Andere IDEs bieten vermutlich ähnliche Funktionen. Programmatisch kann man über den EqualsBuilder respektive den HashCodeBuilder aus den Apache Commons diese Sachen einfach erledigen.

Interviewfragen II – Java

Hier mal einige Java-spezifische Interviewfragen, die ich teilweise selber erfahren habe, teilweise ich mir aber auch einfach nur ausgedacht habe. Dass sie daher etwas Web-Programmierungs-lastig sind bitte ich zu entschuldigen.

  • Warum sollte
    Object.equals(Object)

    immer überschrieben werden, wenn auch

    Object.hashCode()

    überschrieben wird?

  • Was sind die Unterschiede eines Request-Response-basierten Web-Frameworks im Vergleich zu einem komponentenbasierten Framework? Kennen Sie Beispiele für das eine oder das andere?
  • Was ist der Unterschied zwischen einem Application Server (wie z.B. JBoss AS) und einem Servlet-Container wie z.B. Tomcat?
  • Welche Einsatzszenarien fallen Ihnen für eine Message-Queue ein?
  • Welche Tools kennen Sie, mit denen die Zusammenarbeit zwischen mehreren Entwicklern, Testern und anderen Projektbeteiligten verbessert werden kann?

Diese Fragen werde ich der Reihe nach beantworten, wobei natürlich auch vorab schon Antworten und Vorschläge erwünscht sind!

Interviewfragen I

Zu Beginn direkt mal ein Klassiker:

Schreiben Sie ein Programm, welches die Zahlen von 1 bis 100 ausgibt. Immer, wenn eine Zahl durch 3 teilbar ist, soll statt der Zahl das Wort foo ausgegeben werden, ist die Zahl durch 5 teilbar das Wort bar. Ist die Zahl sowohl durch 3 als auch durch 5 teilbar, soll das Wort foobar anstatt der Zahl ausgegeben werden.

Mögliche Lösung:

for ($i = 1; $i <= 100; $i++) {
  if ($i % 3 == 0) {
    echo "foo";
  }
  if ($i % 5 == 0) {
    echo "bar";
  }
  if ($i % 3 != 0 && $i % 5 != 0) {
    echo $i;
  }
  echo "\n";
}

Interviewfragen – Einleitung

So, da ich ja inzwischen festangestellter Softwareentwickler bin und auf dem Weg dorthin auch einige Vorstellungsgespräche hatte, möchte ich hier eine neue Reihe starten, in der ich Programmierfragen erläutere, die in solchen technischen Jobinterviews vorkommen können. Die Fragen sind üblicherweise nicht übermäßig kompliziert und es gibt im Allgemeinen auch nicht die korrekte Lösung, aber es gibt durchaus bessere und schlechtere Lösungen. Eine mögliche Lösung werde ich immer im Eintrag selber erwähnen, andere Ideen sind in den Kommentaren gerne willkommen.

Woher ich die Fragen habe? Teilweise aus eigenen Vorstellungsgesprächen, teilweise von StackOverflow, teilweise auf anderen Seiten gefunden. Wo immer möglich werde ich die Quelle angeben.

Auch wenn hin und wieder mal Fragen zu einer speziellen Programmiersprache dabei sein werden, sollten die Fragen üblicherweise ohne Kenntnis einer speziellen Sprache zu beantworten sein. Meine Lösungsvorschläge werde ich auch in Pseudocode niederschreiben.

Ich hoffe, ich kann mit dieser Serie dem einen oder der anderen helfen und/oder Freude bereiten.