GoDasturchi
Cycle Detection

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.

example.go
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.

example.go
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, FindByName bilan uning yozuvini toping
  • Agar yozuv topilmasa, fmt.Errorf("no record found for %s", current) qaytaring
  • Agar yozuv CNAME bo'lmasa, uni nil xato bilan qaytaring — bu yakuniy javob
  • Agar yozuv CNAME bo'lsa, joriy nomni uning Valuesiga o'zgartirib, davom eting
  • Ko'rilgan har bir nomni map[string]bool bilan kuzatib boring; nom qaytadan uchrasa, fmt.Errorf("cname cycle detected at %s", current) qaytaring

Misollar:

  • ResolveCNAME(records, "www.example.com")www.example.com CNAME orqali example.comga, u esa A yozuvga olib boradi, shuning uchun o'sha A yozuvni nil xato bilan qaytaradi
  • ResolveCNAME(records, "a.loop.com")a.loop.comb.loop.coma.loop.com sikliga tushadi, xato qaytaradi

Stuck? Reveal a hint to help you.

Hints (0/4)

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

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

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.

example.go
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.

example.go
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, FindByName bilan uning yozuvini toping
  • Agar yozuv topilmasa, fmt.Errorf("no record found for %s", current) qaytaring
  • Agar yozuv CNAME bo'lmasa, uni nil xato bilan qaytaring — bu yakuniy javob
  • Agar yozuv CNAME bo'lsa, joriy nomni uning Valuesiga o'zgartirib, davom eting
  • Ko'rilgan har bir nomni map[string]bool bilan kuzatib boring; nom qaytadan uchrasa, fmt.Errorf("cname cycle detected at %s", current) qaytaring

Misollar:

  • ResolveCNAME(records, "www.example.com")www.example.com CNAME orqali example.comga, u esa A yozuvga olib boradi, shuning uchun o'sha A yozuvni nil xato bilan qaytaradi
  • ResolveCNAME(records, "a.loop.com")a.loop.comb.loop.coma.loop.com sikliga tushadi, xato qaytaradi

Stuck? Reveal a hint to help you.

Hints (0/4)

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