Část II:Chyby
Existuje starý programátorský vtip, který zní podobně jako
Myslím, že bychom do tohoto seznamu měli přidat třetí (čtvrtý?) problém:třídění věcí.
Řazení věcí
V informatice existuje mnoho různých způsobů, jak věci třídit. Studenti C.S. se učí o časové a prostorové složitosti těchto třídicích algoritmů, youtubeři z nich vytvářejí skvělé vizualizace a příležitostně chlap jménem Tim vymyslí nový.
Ale je tu jeden aspekt třídicích algoritmů, který se – alespoň pro mě – zdá zcela nemožný:zapamatovat si, jakým směrem jsou věci seřazeny.
Řeknete-li skupině lidí:"dobře, všichni, postavte se do jednořadé řady, seřazené podle výšky", další otázka, kterou byste mohli položit, je "dobře, ale kterým směrem?" Kdo by měl stát vpředu z řady? Nejnižší osoba nebo nejvyšší osoba?
V programování definujeme porovnávací funkce, které popisují, jak seřadit jakékoli objekty, které nás zajímají.
Některé srovnávací funkce se zdají samozřejmé. Například v TypeScriptu s použitím výchozího string
srovnání...
const array: string[] = ["cherry", "apple", "banana"]
array.sort()
//...
...očekávali bychom array
seřadit podle abecedy s apple
jako první (0
th) prvek tříděného pole
//...
console.log(array) // [ 'apple', 'banana', 'cherry' ]
console.log(array[0]) // apple
Ale často budeme pracovat s objekty složitějšími než string
s a budeme muset definovat vlastní porovnávací funkce. Jedná se o funkce, které přebírají dva prvky typu T
a vrátí number
a používají se k řazení polí typu T
:
type T = string
const newArray: T[] = ["cherry", "apple", "banana"]
function comparison(t1: T, t2: T): number {
return t1.charCodeAt(0) - t2.charCodeAt(0)
}
newArray.sort(comparison)
console.log(newArray) // ?
console.log(newArray[0]) // ?
Bez čtení dokumentů bude console.log()
s výše poskytují stejný výsledek jako předchozí? Co takhle něco trochu jednoduššího -- seřadit pole number
s:
type T = number
const newArray: T[] = [42, 2112, 19]
function comparison(t1: T, t2: T): number {
return t2 - t1
}
newArray.sort(comparison)
console.log(newArray) // ?
console.log(newArray[0]) // ?
Bude první výše uvedený prvek 19
? Nebo 2112
? Jste si jistý?
Rozumím užitečnosti třídicích algoritmů a rozumím potřebě ternární (větší, menší nebo stejné) návratové hodnoty, a tedy number
jako návratový typ namísto boolean
, ale srovnávací funkce jsou jen jednou z věcí, které jsem vždy musel pokaždé testovat. Někdy ve vývoji a někdy ve výrobě.
Co se tedy stalo?
S tím, co jsme se dozvěděli výše, byste nyní měli být schopni vidět, co se pokazilo s mým počátečním kódem. Problém byl tady
// get the blog post date from its git commit date
const gitLog = SlugFactory.git.log({ file: `blog/${slug.params.slug}.md` });
return gitLog.then(lines => {
const dates = lines.all.map(each => each.date);
// if blog post hasn't been committed yet, use current date
const date = dates[0] ?? new Date().toISOString();
return new FrontMatter(slug.params.slug, title, description, date, rawContent);
});
git log
vrátí odevzdání seřazené podle data, takže novější potvrzení jsou na prvním místě a později závazky přicházejí později. Takže dates[0]
, výše, je nejnovější potvrzení vráceno z git log
a každému příspěvku na blogu bylo přiděleno datum "publikace" posledního odevzdání, ve kterém byl příspěvek upraven.
Kdy byly tyto blogové příspěvky naposledy upraveny? No, všechny byly upraveny ve stejném odevzdání, protože smyslem odevzdání bylo odstranění date
parametr z přední hmoty. V podstatě jsem si pletl lastUpdated
datum a published
datum. Jedním z nich je první prvek v seznamu (dates[0]
) a jeden z nich je posledním prvkem v seznamu (dates[dates.length-1]
).
Takže jak jsem řekl, počítačová věda má čtyři těžké problémy.
Na další
Když je to opraveno, jdeme na závody, ne?
Oh... no, to není správné.
Oba tyto dva příspěvky byly zveřejněny 2. ledna (Hello, World! a Git Hooks), nikoli 6. ledna. Proč tedy oba měli špatné datum?
Správně, je to další chyba... Nebo ano?
Zjistěte to v napínavém konečná instalace této záhady ladění!