ProgramlamaBackend Geliştirici

Go, map ve slice'ların fonksiyonlara geçirilmesinde bellek yönetimini nasıl gerçekleştirir ve bunun ne gibi sorunları olabilir?

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

Cevap.

Go'da map yapısı her zaman değer olarak geçirilir, ancak bu değer, map'in iç yapısına (arka planda — hash tablosu) işaretçi içerir. Bu nedenle, bir map'i bir fonksiyona geçirir ve fonksiyonun içinde içeriği değiştirirseniz (eleman ekleyip/çıkararak), değişiklikler dışarıda görülecektir. Slice da benzer şekilde çalışır — slice yapısı kopyalanır, ancak veri dizisi kopyalanmaz: slice bir dizinin işaretçisini, uzunluğunu ve kapasitesini içerir. Fonksiyon içinde dizinin indeksleriyle değerleri değiştirirseniz, orijinal dizi de değişecektir. Ancak eğer fonksiyon içinden yeni bir slice ataması yaparsanız (örneğin, reslice), orijinal değişken değişmeyecektir.

func updateMap(m map[string]int) { m["key"] = 42 // Dışarıda değişiklikler görünür! } func updateSlice(s []int) { s[0] = 99 // Orijinal dizi değişir }

Kandırmaca Soru.

Neden map ve slice'ı bir fonksiyona geçirirken içindeki değişiklikler "orijinal" üzerinde etkili olur?

Cevap: Çünkü sadece işaretçi yapısı kopyalanır ve veriler ortak kalır — yapılan değişiklikler aynı bellek bloğunu etkiler.

Konunun inceliklerini bilmemekten kaynaklanan gerçek hata örnekleri.


Hikaye

Fintech projesinde yapılandırma ayarları içeren bir map'i farklı hizmetlere geçirirken, yerel değişikliklerin genel map'i etkilemeyeceğini varsayıyorduk. Sonuç olarak, bir hizmet değerleri değiştirdi ve bu, diğer modüllerde beklenmedik değişikliklerle hatalara neden oldu.


Hikaye

Analitik mikro hizmette, bağımsız kopyalar elde etmeyi umarak bir slice geçirdik. Ancak içindeki fonksiyon indeksler aracılığıyla değerleri değiştirdi; bu, orijinal dizinin beklenmedik bir şekilde değişmesi nedeniyle rapordaki verilerin bozulmasına yol açtı.


Hikaye

Oyun sunucularında kullanıcı oturumlarını depolamak için map kullanıldı ve aynı zamanda bu map birkaç goroutine'e geçirildi. Her goroutine'in kendi kopyası üzerinde çalıştığı varsayıldı, ancak aslında veri yarışı meydana geldi ve oturumlar kısmen kayboldu.