Cycle Detection
Sikllarni aniqlash
CNAME yozuvi bitta nomni boshqasining taxallusi qiladi: www.example.com uchun CNAME yozuvi example.comga ishora qilsa, "www.example.com qanday?" degan savolga javob berish uchun avval "example.com qanday?" deb so'rashingiz kerak. Agar o'sha yozuv ham CNAME bo'lsa, yana bir qadam davom etasiz — toki CNAME bo'lmagan (masalan A) yozuvga yetguningizcha.
Bu — zanjir bo'ylab yurish, va siz buni allaqachon bilasiz: for bilan davom eting, joriy nomni har safar yangilang, CNAME bo'lmagan yozuvga yetganingizda to'xtang.
current := name
for {
r := FindByName(records, current)
if r.Type != "CNAME" {
return *r, nil // yakuniy javob topildi
}
current = r.Value // zanjirni davom ettiring
}Lekin zona noto'g'ri sozlangan bo'lsa nima bo'ladi? A CNAME Bga, B esa qaytadan CNAME Aga ishora qilsa — bu sikl. Yuqoridagi sikl hech qachon CNAME bo'lmagan yozuvga yetmaydi va abadiy aylanaveradi.
Yechim — Count Everything darsidagi map andazasi: map[string]bool bilan qaysi nomlarni allaqachon ko'rganingizni kuzatib boring. Agar joriy nom to'plamda allaqachon bo'lsa, demak siz aylanib kelyapsiz — sikl aniqlandi, xato bilan to'xtang.
visited := make(map[string]bool)
current := name
for {
if visited[current] {
return DNSRecord{}, fmt.Errorf("cname cycle detected at %s", current)
}
visited[current] = true
// ...davomi
}Bu — Where Memory Lives darsida ko'rgan maplarning yana bir amaliy qo'llanilishi: bool qiymatlar bu yerda ma'lumot emas, faqat "buni allaqachon ko'rdim" degan belgi vazifasini bajaradi.
>_ Exercise
FindByName(records []DNSRecord, name string) *DNSRecord sizga allaqachon berilgan — u faqat nom bo'yicha (turini hisobga olmasdan) qidiradi va topilmasa nil qaytaradi.
ResolveCNAME(records []DNSRecord, name string) (DNSRecord, error) funksiyasini yozing, u CNAME zanjiri bo'ylab yuradi va yakuniy (CNAME bo'lmagan) yozuvni qaytaradi.
Talablar
- •Joriy nomdan boshlang,
FindByNamebilan uning yozuvini toping - •Agar yozuv topilmasa,
fmt.Errorf("no record found for %s", current)qaytaring - •Agar yozuv
CNAMEbo'lmasa, uninilxato bilan qaytaring — bu yakuniy javob - •Agar yozuv
CNAMEbo'lsa, joriy nomni uningValuesiga o'zgartirib, davom eting - •Ko'rilgan har bir nomni
map[string]boolbilan kuzatib boring; nom qaytadan uchrasa,fmt.Errorf("cname cycle detected at %s", current)qaytaring
Misollar:
- •
ResolveCNAME(records, "www.example.com")—www.example.comCNAMEorqaliexample.comga, u esaAyozuvga olib boradi, shuning uchun o'shaAyozuvninilxato bilan qaytaradi - •
ResolveCNAME(records, "a.loop.com")—a.loop.com→b.loop.com→a.loop.comsikliga tushadi, xato qaytaradi
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Zanjir bo'ylab yurish oddiy for sikli. Zanjir sikllanib qolishi mumkin bo'lsa, map[string]bool bilan ko'rilgan qadamlarni kuzatib boring — nom qaytadan uchrasa, bu cheksiz aylanish emas, aniq xato bo'lishi kerak.
NEXT UP
Zone Transfer
$ go run main.go
Kodingizni ishga tushiring