ProgramlamaOrta Seviye Backend Go Geliştirici

Go'da kanal aracılığıyla değerler iletildiğinde ne oluyor: kopyalama nasıl çalışır, hangi türler değerle iletilir, karmaşık yapıların veya işaretçilerin iletilmesi durumunda nasıl tesadüfen race elde edilebilir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Go'da herhangi bir türdeki değerleri kanallar aracılığıyla göndermek mümkündür: int, struct, işaretçiler, arayüzler vb.

  • «Değer ile iletim»: standart türler ve işaretçi içermeyen yapılar kopyalanır, alıcı kendi kopyasını alır ve değişiklikler orijinalini etkilemez.
  • Race kontrolü: eğer bir işaretçi kanal üzerinden gönderilirse, iki taraf (gönderen ve alıcı) aynı bellek alanı üzerinde çalışır - veri yarışı olabilir!
  • İç içe işaretçileri olan karmaşık yapılar: ana yapı değer ile iletilse bile, içindeki işaretçiler referanslar olarak kopyalanır ve iç içe nesnelerde veri yarışı mümkün olur.

Kod ve örnek:

type Data struct { N int } c := make(chan Data) d := Data{N: 1} c <- d // yapı tamamen kopyalanır p := &Data{N: 3} c2 := make(chan *Data) c2 <- p // kanaldan aynı nesneye işaretçi gitti

Kandırmaca sorusu

Eğer bir kanala bir işaretçi alanı içeren bir yapı gönderilirse - kanaldan her iki uçta bu alanı değiştirildiğinde race condition olur mu?

Cevap:

  • Race mümkündür! Yapı kopyalanır, ancak içteki işaretçi aynı bellek alanına işaret eder. Eğer her iki taraf referans üzerinden verileri değiştirirse, bir yarış durumu ortaya çıkar.

Örnek:

type Box struct { Ptr *int } x := 10 chanBox := make(chan Box) chanBox <- Box{Ptr: &x} // hem gönderen hem de alıcı x'e erişime sahip!

Konunun detaylarına dair bilgi eksikliği nedeniyle oluşan gerçek hata örnekleri


Hikaye

Dağıtılmış kuyrukta sıkça "rastgele" çökme ve görev yapısında gizemli değerler vardı. Kanal aracılığıyla ortak yapılar üzerinde değişiklik yapan işaretçileri gönderiyorlardı. Veri kopyalarına geçilmesine karar verildi.


Hikaye

Asenkron mesaj işleme, içinde ortak diziye işaretçiler bulunan yapılarla çalışıyordu. Parallelde kanal aracılığıyla aynı bellek kısmı farklı yerlerden değiştiriliyordu, bu da gizli hatalara ve veri bozulmasına yol açıyordu.


Hikaye

Push bildirimleri servisi, işaretçileri işleyen goroutinelar tarafından daha sonra işlenen nesnelere kanal aracılığıyla iletiliyordu. Kanal kapatılırken, bazı yapılar hala değiştirilerek panik veya veri yarışı yaratıyordu. Göndermeden önce yapı kopyalamaya geçmek işe yaradı.