ProgramlamaBackend Geliştirici

Go'da slices ile çalışmanın özelliklerini tanımlayın: nil slice nedir, uzunluk ve kapasite arasındaki fark nedir ve slice'ı veri sızıntısı veya panik olmadan nasıl doğru bir şekilde artırabilirsiniz?

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

Cevap.

Slice, Go'da dizilerle çalışmanın temel yapısal birimi olan dinamik bir dizidir. Tarihsel olarak, programlama dilleri sabit diziler veya daha ağır yapılar sunmuştur. Go, memory koleksiyonlarını otomatik boyut yönetimi ve uzunluğu değiştirme yeteneği ile işlemek için slices'ı kullanışlı bir araç olarak uygulamıştır.

Sorun bellek yönetimini doğru bir şekilde yapmak, sınır durumlarını (boş, nil, dolu slice'lar) işlemek ve bir slice'ın uzunluğu ile kapasitesi arasındaki farkı anlamaktır.

Çözüm ise yerleşik len(), cap() fonksiyonlarını doğru bir şekilde kullanmak ve Go'nun slice ile ilgili sözleşmelerine uymaktır.

Kod örneği:

var a []int // nil slice, len=0, cap=0 b := make([]int, 0) // boş slice, len=0, cap=0 c := make([]int, 3, 5) // len=3, cap=5 c = append(c, 4, 5, 6) // cap otomatik olarak artırılacak

Anahtar özellikler:

  • Nil slice (var s []int) hiç bellek tahsis etmez, sadece içsel olarak boş slice'dan (make([]int, 0)) farklıdır.
  • Uzunluk mevcut eleman sayısını, kapasite ise ek bellek tahsisi gerektirmeden maksimum sayıyı gösterir.
  • Append yapıldığında, eğer kapasite yetersizse, arka planda yeni bir tane oluşturulur ve eski veriler değişmeden kalır.

Kandırma Soruları.

Nil slice'a append yaptığında slice'ın uzunluğu ve kapasitesi ne olur?

Nil slice (var s []int) append(s, 1) sonrasında uzunluğu 1, kapasitesi 1 olan bir slice olur — Go otomatik olarak depolama alanı ayırır.

var s []int s = append(s, 42) // s artık [42], len=1, cap=1

Nil olan bir slice'ın kapasitesine erişilebilir mi?

Evet, nil slice'da len ve cap fonksiyonları her ikisi de 0 döner. Panik olmaz.

var s []int fmt.Println(len(s), cap(s)) // 0 0

Nil olan bir slice'a bellek tahsisi olmadan indeksle bir eleman atamaya çalıştığınızda ne olur?

index out of range hatası alırsınız, çünkü slice'ta hiç eleman yoktur.

var s []int s[0] = 1 // panic: runtime error: index out of range

Tipik Hatalar ve Anti-Desenler

  • Belirli bir uzunluk gerektiren bir işlevde nil slice veya boş slice geçirirken yapılan hatalar.
  • Kapasite artışını hesaba katmadan slice'ı doldurmak ve append ile kötü yazılmış döngüler.
  • Eleman eklemek için append yerine indeksten atama yapma girişimleri.

Gerçek Hayat Örneği

Olumsuz Durum

Ekip, Go sunucusunda her yerde yalnızca var s []T kullanmaya karar verdi ve bunun her zaman make([]T, 0) ile eşdeğer olduğunu beklediler. Sonuç olarak, bazı JSON serileştirmeleri null yerine [] döndürdü.

Artılar:

  • Başlangıçta daha az bellek tahsisi.

Eksiler:

  • JSON'un doğru çalışmaması (sonuçta dizi yerine null geldi).
  • İndekse erişimde çalışma zamanı hataları.

Olumlu Durum

make([]T, 0, 100) kullanarak ön tahsis yapıldıktan sonra döngüde sadece append kullanmak. Bu, bellek tahsisini en aza indirir ve genellikle performansta kazanımlar sağlar.

Artılar:

  • Bellekle etkin çalışma.
  • Serileştirme sırasında panik ve beklenmedik değerler yok.

Eksiler:

  • Beklenen eleman sayısı ile belirlenen kapasitenin uyuşmaması durumunda bellek israfı olabilir.