Deadlock Teorisi: Dört Koşul Sistemi Nasıl Kilitler?

Bir restoranda iki aşçı düşünün: Birinin tava, diğerinin bıçak tuttuğunu; fakat ikisinin de yemeği tamamlamak için diğer araç gerece ihtiyaç duyduğunu hayal edin. Kimse elindekini bırakmazsa mutfak sonsuza kadar bekler. İşletim sistemlerinde bu tatsız tabloya deadlock, yani kilitlenme denir.

Devamı...

Copy-on-Write: Kopyalamadan Kopya Oluşturmanın Akıllı Yolu

Bir nesnenin kopyasını çıkarmak çoğu zaman masum görünür: bellekte yeni bir alan ayır, verileri taşı ve devam et. Ancak yüzlerce megabaytlık verilerle çalışıyorsak bu işlem hem zaman hem bellek tüketir. Copy-on-Write, kısaca CoW, “Gerçekten değiştirmeyeceksen neden kopyalıyorsun?” diyerek iki kopyanın aynı belleği geçici olarak paylaşmasını sağlar.

Devamı...

Condition Variable: Thread’ler Birbirini Nasıl Bekler?

Bir thread’in sürekli “Hazır mı? Hazır mı? Şimdi hazır mı?” diye kontrol yapması, işlemciyi gereksiz yere meşgul eden dijital bir sabırsızlıktır. Condition variable, thread’lerin belirli bir koşul gerçekleşene kadar verimli biçimde uyumasını ve koşul değiştiğinde yeniden çalışmasını sağlayan bir senkronizasyon aracıdır.

Devamı...

Branch Prediction’ın İç Dünyası: CPU Geleceği Nasıl Tahmin Ediyor?

branch-predictionin-ic-50

Modern bir CPU, yalnızca komutları çalıştıran hızlı bir hesap makinesi değildir; aynı zamanda geleceği tahmin etmeye çalışan minik bir falcıdır. Programdaki if, switch ve döngü koşulları işlem akışını değiştirdiğinde CPU, sonucun hesaplanmasını beklemek yerine hangi yolun izleneceğini tahmin eder. Bu mekanizmaya branch prediction, yani dallanma tahmini denir.

Devamı...

ABI Nedir? Derlenen Programların Görünmez Ortak Dili

Bir C fonksiyonunu Rust’tan çağırdığınızda ya da işletim sistemi derlenmiş programınızı çalıştırdığında taraflar kaynak kodu tartışmaz. Bunun yerine; parametrelerin nereye konacağı, sonuçların nasıl döndürüleceği ve belleğin nasıl düzenleneceği gibi önceden belirlenmiş kurallara uyarlar. İşte bu görünmez anlaşmanın adı ABI, yani Application Binary Interface’tir.

Devamı...

Treap: Rastgeleleştirilmiş Dengeli Ağacın Zarif Mantığı

treap-rastgelelestirilmis-dengeli-27

İkili arama ağaçları hızlıdır; tabii ağaç bir bambu dalına dönüşmediği sürece! Sıralı veriler sıradan bir ikili arama ağacına eklendiğinde yapı doğrusal bir liste gibi uzayabilir. Treap, bu sorunu katı dengeleme kuralları yerine rastgelelik kullanarak çözer. İsmi de iki yapının birleşiminden gelir: tree ve heap. Sonuç, şaşırtıcı derecede basit ama beklenen performansı oldukça güçlü bir veri yapısıdır.

Devamı...

Tip Sistemlerinin Evrimi: Weak Typing’den Dependent Type’lara

Tip sistemleri, programlarımızın hangi değerlerle hangi işlemleri yapabileceğini belirleyen görünmez trafik kurallarıdır. İlk bakışta yalnızca “bu değişken sayı mı, metin mi?” sorusuyla ilgileniyor gibi görünürler. Oysa weak typing’den dependent type’lara uzanan yolculuk; hataları ne zaman yakaladığımızı, kod hakkında neleri kanıtlayabildiğimizi ve derleyiciye ne kadar sorumluluk verdiğimizi anlatır.

Devamı...

Suffix Automaton: Bir Metnin Bütün Alt Dizelerini Sıkıştırarak Temsil Etmek

Elimizde uzun bir metin olduğunu ve bu metindeki bütün bitişik alt dizeleri saklamak istediğimizi düşünelim. Uzunluğu $n$ olan bir metin, en fazla $n(n+1)/2$ farklı konum aralığı içerir. Hepsini ayrı ayrı depolamak karesel bir felakete dönüşebilir. Suffix Automaton, yani son ek otomatı, aynı bilgiyi yalnızca $O(n)$ durum ve geçişle temsil eden zarif bir veri yapısıdır.

suffix-automaton-bir-13

Devamı...

Structural Typing ve Nominal Typing: “Neyi Biliyorsun?” mu “Kimsin?” mi?

Bir nesne kapıya geldiğinde tip sistemi ona iki farklı soru sorabilir: “Gerekli özelliklere sahip misin?” veya “Hangi sınıfa mensupsun?” Structural typing ilk soruyla, nominal typing ise ikinci soruyla ilgilenir. Bu ayrım yalnızca akademik bir sınıflandırma değildir; kodun yeniden kullanılabilirliğini, güvenliğini ve API tasarımını doğrudan etkiler.

structural-typing-ve-39

Devamı...

Sparse Table: Değişmeyen Aralık Sorgularını O(1)’de Cevaplamak

Bir dizi üzerinde tekrar tekrar “şu aralıktaki en küçük eleman nedir?” diye sorulacağını, fakat dizinin hiçbir zaman değişmeyeceğini düşün. Her sorguda aralığı baştan sona dolaşmak gereksiz bir maraton olur. Sparse Table, biraz ön hazırlık yaparak minimum, maksimum ve EBOB gibi değişmeyen aralık sorgularını $O(1)$ sürede cevaplayan zarif bir veri yapısıdır.

Devamı...

Reflection: Çalışan Bir Program Aynaya Baktığında Ne Görür?

Bir programın çalışırken kendi sınıflarını, metotlarını ve alanlarını inceleyebilmesi kulağa bilim kurgu gibi gelebilir. Oysa reflection, modern programlama dillerinde test araçlarından web çatılarının otomatik yapılandırmasına kadar pek çok sistemin görünmez kahramanıdır. Program aynaya bakıp “Ben hangi türüm, hangi yeteneklere sahibim?” diye sorar; reflection API’si de ona cevap verir.

Devamı...

Probabilistic DP: Olasılıklı Olimpiyat Problemlerini Durumlara Ayırma Sanatı

probabilistic-dp-olasilikli-29

Bir zar atılıyor, yazı gelirse ilerliyor, tura gelirse başa dönüyorsun… İlk bakışta şans oyunu gibi görünen bu problemler, doğru durumlar tanımlandığında gayet düzenli birer dinamik programlama sorusuna dönüşür. Probabilistic DP, rastgele olayların sonuçlarını tek tek simüle etmek yerine her durumdan ulaşılabilecek sonuçların olasılıklarını matematiksel olarak birleştirir.

Devamı...

Pattern Matching’in Evrimi: switch İfadelerinden Yapısal Eşleşmeye

Programlamada karar vermek uzun süre “Bu değer kaç?” sorusuna cevap aramak demekti. Ancak modern uygulamalarda değerler; listelerden, nesnelerden, ağaçlardan ve iç içe geçmiş veri yapılarından oluşuyor. Bu nedenle diller de basit switch ifadelerinden, verinin hem biçimini hem içeriğini inceleyebilen pattern matching yaklaşımına evrildi. Başka bir deyişle artık yalnızca kutunun etiketine değil, kutunun içine ve düzenine de bakıyoruz.

pattern-matchingin-evrimi-94

Devamı...

Palindromic Tree: Bütün Palindromları Tek Yapıda Toplamak

palindromic-tree-butun-36

Bir metindeki bütün palindromları bulmak ilk bakışta kolay görünür: Her merkezi seç, iki yana doğru genişle ve eşleşmeler bitene kadar devam et. Fakat metin uzadığında ve aynı palindromlar tekrar tekrar karşımıza çıktığında işler karışır. Palindromic Tree, diğer adıyla Eertree, farklı palindromları tek bir yapıda saklayarak bu karmaşayı oldukça zarif biçimde çözer.

Devamı...

Monotonic Stack: Dizideki Görünmeyen İlişkileri Tek Geçişte Yakalamak

Bir dizide her elemanın sağındaki ilk büyük değeri bulmanız istendiğinde, akla hemen iç içe döngüler gelebilir. Ancak bu yaklaşım büyüyen girdilerde bilgisayarınızı küçük bir jet motoruna dönüştürür. Monotonic Stack, henüz cevabı bulunmamış elemanları düzenli biçimde saklayarak görünmeyen komşuluk ilişkilerini tek geçişte ortaya çıkarır.

monotonic-stack-dizideki-81

Devamı...

Monotonic Queue: Kayan Pencerelerde Maksimum ve Minimum Avı

Bir dizide belirli genişlikteki pencereyi soldan sağa kaydırıp her konumdaki maksimum veya minimum değeri bulmak, ilk bakışta zararsız görünen bir problemdir. Fakat pencere büyüdükçe her adımda tüm elemanları yeniden taramak, işlemciyi küçük bir maratona çıkarır. Monotonic Queue, yalnızca işe yarayabilecek adayları saklayarak bu avı doğrusal zamanda tamamlar.

Devamı...

Kodun Aynaya Bakışı: Macros ve Metaprogramming

kodun-aynaya-bakisi-12

Bir programın başka bir program üretmesi ilk bakışta bilim kurgu gibi gelebilir. Oysa derleyicilerden web çatılarındaki otomatik yönlendirmelere kadar pek çok araç bu fikri kullanır. Metaprogramming, kodu veri gibi okuyup değiştirme veya yeni kod üretme tekniğidir; macro ise bu geniş ailenin en tanınmış üyelerinden biridir.

Devamı...

Inclusion-Exclusion Principle: Üst Üste Binen Kümeleri Doğru Saymak

Bir etkinliğe katılanların 30’u Python, 25’i JavaScript biliyorsa toplam 55 yazılımcımız olduğunu düşünebiliriz. Fakat iki dili de bilenler varsa aynı kişileri iki kez saymış oluruz. Inclusion-Exclusion Principle, Türkçesiyle Dahil Etme–Hariç Tutma İlkesi, tam olarak bu tür üst üste binmeleri düzeltmek için kullanılan zarif bir sayma yöntemidir.

Devamı...

Gradual Typing: Statik ve Dinamik Tiplerin Aynı Dilde Dansı

Bir programlama dili hem özgür ruhlu hem de disiplinli olabilir mi? Gradual Typing, yani kademeli tipleme, bu soruya güçlü bir “evet” yanıtı verir. Geliştiriciye dinamik tiplerin esnekliğini sunarken ihtiyaç duyulan bölgelerde statik tip denetimini devreye sokar. Böylece mevcut bir projeyi baştan yazmadan, tip güvenliğini adım adım artırmak mümkün olur.

Devamı...

Foreign Function Interface: Programlama Dilleri Arasında Köprü Kurmak

foreign-function-interface-85

Bir Python uygulamasının C ile yazılmış ışık hızındaki bir kütüphaneyi çağırması veya Rust kodunun işletim sistemine ait işlevleri kullanması sihir değildir. Bu iletişimi sağlayan mekanizma Foreign Function Interface, kısaca FFI olarak adlandırılır. FFI, farklı kurallara ve çalışma zamanlarına sahip programlama dillerinin aynı masaya oturup anlaşmasını sağlayan teknik bir tercümandır.

Devamı...