Skip to content

Instantly share code, notes, and snippets.

@AlexanderViand
Last active March 15, 2018 15:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexanderViand/865582c6985fa275c9566460b0860036 to your computer and use it in GitHub Desktop.
Save AlexanderViand/865582c6985fa275c9566460b0860036 to your computer and use it in GitHub Desktop.
Debugging sample based on debugging a student submission

How to Debug

Tests laufen lassen und einen aussuchen

Zu erst habe ich die Tests in IntelliJ ausgeführt. Da haben sortEmpty,generic und create23 gefailed. In sortEmpty und generic gab es ArrayIndexOutOfBoundsException, von den beiden hörte sich der empty-test einfacher an.

Debugging emptySort()

Also habe ich in emptySort() einen Breakpoint vor dem a.sort() (also auf die gleiche Zeile) gesetzt und habe den Test dann debuged (Name rechts-anklicken "Debug sortEmpty()" oder mit Tastatur-shortcut).

Am Breakpoint angekommen bin ich in a.sort() rein-gesteppt (F7), dann nochmal in recursiveSort(numbers.length) bis ich in deiner eigentlichen Sortierfunktion war. Dort dann Zeile für Zeile durch gesteppt (F8) bis es gecrashed ist, als es im else Teil das maximum lesen wollte (array index 0 war natürlich im empty array out of bounds).

Da ja laut Aufgabenblatt bei $until = 0$ die Rekursion abbrechen soll habe ich einfach die ganze else Geschichte entfernt. Danach habe ich wieder alle tests laufen lassen: emptySort passt jetzt, aber generic und create23 failen weiter.

Debugging Generic

Weil exceptions finden einfacher ist als "logische" Fehler (falsch sortiert) habe ich mir als nächstes generic angeschaut. Hier musste ich natürlich immer in den Rekursiven Fall "rein"steppen (F7) und nicht "drüber"steppen (F8).

Bis "ganz runter" (until = 0) ging alles gut, also wusste ich das der Fehler beim "hochgehen" passieren musste. Also habe ich den Code in der if Klausel angeschaut und sofort gemerkt das until < this.numbers.length() und int max = this.numbers[until+1] ein Problem ist denn ein Array von Länge $n$ hat nur $n-1$ Positionen d.h. wenn man $i &lt; n$ testet wird der letzte fall dann $[n-1+1] = [n]$ sein und das ist OutOfBounds.

Wenn man das nicht direkt sieht kann man aber auch einfach wieder weiter mit F8 steppen bis es crashed und dann weiss man wo es crashed.

Als erstes habe ich die crashende Zeile auf int max = this.numbers[until] geändert, denn wir wollen ja den Bereich [until,numbers.length) durchsuchen - siehe Beschreibung. Alle Positionen von 0 bis und mit until-1 wurden ja durch Rekursion schon sortiert. Jetzt also müssen wir den grössten Wert aus until bis ende finden. Der Aufruf auf numbers[until] ist auch sicher wegen dem if und weil kein +1 mehr drin ist.

Dann habe ich direkt gesehen, dass am Ende das this.numbers[until+1] = max natürlich auch crashen wird. Aber das könnte man auch durch neues debuggen rausfinden. Zum Glück ist auch das "doppelt" falsch: Einmal crashed es, und einmal ist es die falsche Stelle. Laut Aufgabe soll recursiveSort das Maximum ja mit der Zahl an Stelle until-1 vertauschen.

Daraus merken wir direkt, dass wir nicht nur das maximum brauchen sondern auch die Position vom maximum, damit wir die andere Zahl da hin packen können. Also fügen wir eine Variable dafür hinzu und updaten es wenn wir max upadten.

Jetzt können wir am Ende die Zahlen vertauschen (brauchen dafür natürlich eine hilfsvariable damit wir keine "verlieren)

Wieder alle tests laufen lassen: Juhu, nichts neues! Aber leider failed generic immer noch und create23 auch. Aber zum Glück crashed generic nicht mehr. Stattdessen ist der "String nicht well formed"...Mhh, also ein Problem mit toString(). Mh, das Test Pattern enthält delim und wenn wir das anschauen (rechtsclick Go To -> Go To oder Cmd/Ctrl+B) dann sehen wir das es als ", ", d.h. mit Leerzeichen definiert ist und in deinem toString() kein Leerzeichen nach dem Komma ist. Easy fix!

Ok, generic failed immer noch aber wengistens create23 ist wohl dadurch schon magisch gefixed. Yay! Neuer Fehler bei generic: Wrong order at position .. of array. Also stimmt die Sortier Logik irgendwo nicht...

Die Stelle ist erst irgendwo im Array, d.h. vermutlich hat es was mit dem maximum finden und swappen zu tun (sonst würde es schon direkt an Stelle 1 oder so fehlschlagen)...

Beim durchsteppen setze ich einen Breakpoint auf die if(until < numbers.length() Zeile und benutze Resume Program (Cmd+Option+R oder Ctrl+Alt+R) um bis zum nächsten Breakpoint (also wieder der gleiche, nur ein level "höher" zu gehen. Dabei achte ich einfach nur im Variablen Fenster auf this und schaue zu wie es die Sachen sortiert. Irgendwann macht es einen Fehler und ich sehe: Aha, da war das Element was da stand grösser als das was es da hin geswappt hat. Also schaue ich auf den code und denke "Klar, int max = numbers[until] kann ein Problem sein wenn numbers[until-1] grösser ist, weil wir dann das "kleinere" max dahin swappen würden. Also wird es auf int max = numbers[until-1] geändert.

YES!! IT WORKS!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment