Tym razem nie tylko analizujemy kod, ale także go poprawiamy, bo autor pozwolił sobie na stworzenie pętli nieskończonej i chyba tego nie zauważył. Do dzieła.
Nasz przedmiot badań:
class SinglyLinkedList{
constructor(){
this.head = null;
this.tail = null;
this.length = 0;
}
//(...)
unshift(val){
var newNode = new Node(val);
if(!this.head) {
this.head = newNode;
this.tail = this.head;
}
newNode.next = this.head;
this.head = newNode;
this.length++;
return this;
}
}
Ok, zróbmy coś takiego:
var list = new SinglyLinkedList()
list.unshift(100);
console.log(list.head); //Node {val: 100, next: {Node: val: 10, next: { (...)}
console.log(list.head.next); //tu powinien być null
Ten var to jeszcze autor. Wylogowanie list.head i list.head.next to już ja.
Cóż, poprawmy to:
unshift(val){
var newNode = new Node(val);
if(!this.head) {
this.head = newNode;
this.tail = this.head;
this.length++;
return this;
}
newNode.next = this.head;
this.head = newNode;
this.length++;
return this;
}
Brzydko, tylko logikę poprawiliśmy. Zobaczmy czy działa:
var list = new SinglyLinkedList()
list.unshift(100);
console.log(list.head); //Object { val: 100, next: null }
console.log(list.head.next); //null
Teraz rozumiem ten bias pracodawców wobec osób po kursach internetowych. Pamiętajcie, że bezpłatne tutoriale są jeszcze gorsze! I albo wszystko ogarniesz sam, albo będziesz na te klocki wiecznie za głupi (ale hej, tutoriale możesz produkować, bootcampy to też niezły interes).
Nie wszystko ogarniesz od razu, ale koniec końców albo wszystko ogarniesz, albo nauczyłeś się ctrl+c i paru terminów, przypominasz w ten sposób chatGPT, który umie gadać o tematach, których nie rozumie.
Rekurencja, iteracja, ctrl+c, ctrl+v, oto algorytm. Ja: Ej, ale ty po returnie mi dodałeś to co miałeś dodać, ten kod jest nieosiągalny. Chat: Tso?
PS. To, że w kursie pojawił się błąd to jedno, to, że nikt tego nie zauważył to jeszcze inne. Nie bądźmy bezmyślnymi kopiującymi, bo nigdy do niczego nie dojdziemy!
EDIT: Technicznie rzecz biorąc, mamy tu do czynienia nie z pętlą nieskończoną tylko circular reference, dlatego żaden error nie wyskakuje, dopóki nie przeiterujemy sobie po tej liście (lub jak ja oragniamy to logicznie i czytając kod wyczujemy, że coś nie teges).
Ta referencja kołowa jest zła z logicznego punktu widzenia i czyni naszą listę po pierwsze nieużywalną, po drugie czymś, co listą wiązaną nie jest i nie działa z przeznaczeniem.
Ale referencja kołowa jest też zła sama w sobie, no może nie zła, ale trzeba na nią uważać nawet wtedy, gdy jest to zgodnie z naszym założeniem i przeznaczeniem.
Języki wysokopoziomowe „nie muszą martwić się” o memory leaki, bo garbage collector „robi wszystko za nas”. Mniej więcej tak samo jak nie musimy się martwić o średniki w JS, bo ASI (do czasu pierwszego wielolinijkowego returna bez średnika).
Generalnie, obiekty są usuwane z pamięci gdy już nie są potrzebne. Garbage collector ma kilka faz (zależy od języka programowania) i ten mechanizm sprawdzania, czy dana zmienna będzie jeszcze używana czy można się jej pozbyć z pamięci działa całkiem sprawnie.
Referencja kołowa w wielu językach wysokopoziomowych blokuje możliwość działania garbage collectora. To jest, zmienna już nie jest potrzebna, ale ta zmienna wskazuje na coś, co ma referencję kołową.
To się wszystko zmienia, nie tylko w zależności od języka, ale i jego wersji, natomiast warto mieć to na uwadze i uważać na referencje kołowe. Goto i inne „straszaki” ludzie widzą z daleka (w JS nie ma goto btw) ale to trudno zauważyć.
Tym bardziej warto hobbystycznie w miarę możliwości niskopoziomowe (z dzisiejszej perspektywy niskopoziomowe) języki programowania poznawać i się nimi bawić.
Warto też eksperymentować, sprawdzać co się stanie, gdy wsadzimy printf w printf jako „%d” albo co się stanie, gdy użyjemy pustej pętli for i tak dalej.
Niskopoziomowe (z dzisiejszego punktu widzenia) języki mają też zupełnie inne zasady pisania bezpiecznego kodu. Na zachętę rzucę tylko jeden taki przykład, jakim jest Yoda Notation:
if (42 == $value) { /* ... */ }
// Reads like: "If 42 equals the value..."
Przykład w PHP, ale jest to dziwactwo, które przyszło z C. Czemu tak?
Bo do 42 nie da się przypisać wartości, zaś postawić jeden znak „=” mniej łatwo…
Dlatego zawsze uważajmy, co piszemy. Zawsze wszystko testujmy i stosujmy się do najlepszych praktyk.
I poznawajmy jak najwięcej, nie tylko to co musimy, bądź nam się wydaje, że tylko to jest dla nas istotne.
Zepsułem SEO swoimi wywodami, także koniec lekcji, więcej w następnych odcinkach…