yoklateknik mülakat

Backend Python Memory Performance Mülakat Soruları

75 doğrulanmış Backend Python Memory Performance mülakat sorusu — cevaplarıyla çöz, açıklamalarıyla öğren, gerçek simülasyonda kendini test et.

Gerçek simülasyonu dene →

Örnek sorular

Python Memory PerformanceZorluk 1
x = [1, 2, 3]
y = x
del x

Bu kod çalıştıktan sonra [1, 2, 3] listesine ne olur?
  • aHemen silinir, çünkü del x listenin kendisini kaldırır
  • bCanlı kalır, çünkü y hâlâ ona referans verir ve refcount yalnızca 2'den 1'e düşer
  • cBuna yalnızca cycle-detecting collector karar verir; refcounting'in burada rolü yoktur
  • ddel x hata fırlatır, çünkü başka bir isim aynı nesneye hâlâ referans verirken bir ismi silmek yasaktır
Açıklama:del x, x adının bağlanmasını kaldırır ve nesnenin reference count'unu bir azaltır. y hâlâ aynı listeyi gösterdiği için refcount yalnızca 2'den 1'e düşer, bu yüzden CPython nesneyi canlı tutar. Liste ancak refcount 0'a ulaştığında, yani y de artık ona referans vermediğinde bellekten atılır.
Python Memory PerformanceZorluk 2
import sys

a = []
b = a
print(sys.getrefcount(a))

Burada yazdırılan sayı neyi temsil eder?
  • aListeye olan her referans, çağrının kendi geçici referansı dahil (bu her zaman oluşturulur) — genelde 3
  • bYalnızca a ve b, çünkü çağrının kendisi nadiren referans sayılır — genelde 2
  • cAynı nesneye kaç isim alias olursa olsun her zaman 1
  • dTypeError fırlatır, çünkü listeler hashlenemez
Açıklama:sys.getrefcount(obj), çağrıldığı andaki obj reference count'unu raporlar; ama obj'yi argüman olarak geçirmenin kendisi çağrı süresince ekstra, geçici bir referans oluşturur. a ve b aynı listeye bağlıyken sayı genelde 2 değil 3 çıkar (a, b ve çağrının kendi geçici referansı).
Python Memory PerformanceZorluk 2
def f():
    x = [1, 2, 3]
    return None

f()

f() döndükten sonra içinde oluşturulan listeye ne olur?
  • aProgram bitene kadar bellekte kalır, çünkü Python yerel nesneleri erken serbest bırakması beklenmez
  • bSonraki çağrılarda yeniden kullanılmak üzere global bir önbelleğe taşınır
  • cgc.get_objects() aracılığıyla sonsuza kadar erişilebilir kalır
  • dFrame yok edildiğinde refcount 0'a düşer, CPython listeyi hemen serbest bırakır
Açıklama:Listeye tek referans yerel isim x'tir. f() döndüğünde stack frame'i (ve tuttuğu yerel değişkenler) yok edilir, bu yüzden x'in listeye referansı ortadan kalkar. Refcount 0'a ulaştığında CPython'ın reference-counting collector'ı listeyi hemen serbest bırakır — bu basit, döngüsel olmayan durumda bir garbage collection döngüsü beklemeye gerek yoktur.
Python Memory PerformanceZorluk 2
İki nesne, a ve b, birbirine referans veriyor (a.other = b, b.other = a) ve programdaki başka hiçbir isim ikisine de referans vermiyor. Reference counting tek başına neden bunları serbest bırakmaz?
  • aReference counting yeterli zaman geçtikten sonra kendiliğinden 0'a ulaşır
  • bCircular reference'lar yasaktır ve oluşturulur oluşturulmaz hata fırlatır
  • cHer iki refcount da hep 0'ın üstünde kalır, bu yüzden yalnızca gc cycle collector geri kazanabilir
  • dCPython bu tür circular reference'ları sızıntıyı önlemek için sessizce weak reference'a çevirir
Açıklama:a veya b'ye işaret eden hiçbir dış isim olmasa bile a hâlâ b'ye, b de hâlâ a'ya referans tutar; bu yüzden saf reference counting ile hiçbirinin refcount'u asla 0'a düşmez. Bu tam olarak generational cycle-detecting garbage collector'ın (gc modülü) var olma sebebidir: periyodik olarak yalnızca birbirlerinden erişilebilen nesne gruplarını arar ve geri kazanır.
Python Memory PerformanceZorluk 2
class Node:
    def __init__(self):
        self.other = None

a = Node()
b = Node()
a.other = b
b.other = a

del a
del b

del a; del b sonrası, iki Node nesnesi yalnızca reference counting ile hemen serbest bırakılır mı?
  • aHayır — her biri diğerinden gelen 1 refcount'u korur, collector çalışana kadar
  • bEvet, del kaç referans olursa olsun genelde anında serbest bırakmayı zorlar
  • cEvet, Python kendine referans veren attribute'ları tespit edip del'de sıfırlar
  • dHayır, ve sürecin geri kalanında hiçbir zaman serbest bırakılmazlar
Açıklama:a ve b isimlerini silmek yalnızca dışarıdan olan referansları kaldırır; ama a.other hâlâ b'yi, b.other hâlâ a'yı gösterir. Her nesnenin refcount'u yalnızca 2'den 1'e düşer, asla 0'a değil, bu yüzden düz reference counting onları geri kazanamaz. Generational gc collector çalışana kadar (otomatik olarak bir noktada ya da açık bir gc.collect() ile) çöp olarak kalırlar; collector çalıştığında izole döngüyü tanır ve ikisini de serbest bırakır.
Python Memory PerformanceZorluk 3
Bir toplu iş, sıcak bir döngüde collection maliyetini azaltmak için başlangıçta gc.disable() çağırıyor. Haftalar sonra, uzun çalıştırmalarda bellek kullanımı istikrarlı biçimde büyüyor ve bir bellek profiler'ı birbirine referans veren (parent/child geri referansları) birçok Node benzeri nesnenin biriktiğini gösteriyor. En olası açıklama nedir?
  • agc.disable() yalnızca generation 2'yi kapatır; genç nesillerdeki döngüler hâlâ otomatik toplanır
  • bBüyüme gc.disable() ile ilgisizdir; bunun yerine bir C extension sızıntısı olmalıdır
  • cgc.disable() cycle collector'ı tamamen kapatır; bu yüzden sonrasında oluşan döngüler basitçe sızar
  • dgc.disable() yalnızca gc debug istatistik yazdırmasını bastırır, collection'ın kendisini değil
Açıklama:gc.disable(), otomatik generational cycle collector'ın hiç çalışmamasını sağlar. Reference counting döngüsel olmayan çöpü her zamanki gibi geri kazanmaya devam eder, ama collector kapalıyken herhangi bir nesne döngüsü (parent/child geri referansları gibi) kendiliğinden asla serbest bırakılmaz — gc.enable() çağrılıp bir döngü sonunda çalışana ya da gc.collect() açıkça çağrılana kadar bellekte kalırlar. Döngüsel yapılara dayanan kod için gc'yi performans kazancı adına kapatmak, bu kazancı yavaş ama istikrarlı bir bellek sızıntısıyla takas eder.

3300 soruluk Backend bankasında kendini sına.

Mülakata başla