Suffix Automaton ile O(N) Zamanda Alt Dize Analizi

suffix-automaton-ile-87

Bir metindeki farklı alt dizgileri tek tek saklamaya kalkarsak, kısa sürede bellek canavarı üretiriz. Uzunluğu $N$ olan bir dizginin $O(N^2)$ adet alt dizgi aralığı bulunabilir. Suffix Automaton ya da kısaca SAM, bütün bu alt dizgileri en fazla $2N-1$ durum kullanarak temsil eder ve soldan sağa tek geçişte, yani $O(N)$ zamanda kurulabilir.

Devamı...

Property-Based Testing: Örnekleri Değil, Kuralları Sınayın

Geleneksel testlerde genellikle belirli bir girdi seçer, beklenen çıktıyı yazar ve sonucu karşılaştırırız. Peki seçmediğimiz binlerce girdi ne olacak? Property-Based Testing, birkaç mutlu örneğe güvenmek yerine yazılımın her geçerli durumda koruması gereken kuralları tanımlar. Test aracı da çok sayıda veri üreterek bu kuralları bozmaya çalışır; adeta kodumuza yaratıcı ve biraz da huysuz bir denetçi göndeririz.

Devamı...

Observability Üçlüsü: Log, Metric ve Trace ile Sistemin Röntgenini Çekmek

Bir uygulamanın çalışıyor olması, sağlıklı olduğu anlamına gelmez. Kullanıcılar yavaşlıktan yakınırken sunucunun neşeyle “200 OK” demesi mümkündür. Observability, yani gözlemlenebilirlik; sistemin iç durumunu dışarıya ürettiği sinyallerden anlayabilme yeteneğidir. Bu sinyallerin klasik üçlüsü log, metric ve trace verileridir. Tek başlarına faydalı, birlikte kullanıldıklarında ise dijital bir dedektif ekibi kadar etkilidirler.

observability-uclusu-log-93

Devamı...

Mutation Testing: Testleriniz Gerçekten Güçlü mü, Yoksa Sadece Yeşil mi?

Test ekranındaki bütün işaretlerin yeşil olması insana huzur verir. Fakat yeşil testler, kodun doğru çalıştığını kanıtlamaktan çok mevcut beklentilerin karşılandığını söyler. Peki testlerimiz kritik bir hata karşısında gerçekten kırılıyor mu? Mutation testing, yani mutasyon testi, üretim koduna kontrollü küçük hatalar ekleyerek bu soruya oldukça eğlenceli ve zaman zaman acımasız bir cevap verir.

Devamı...

Maximum Bipartite Matching: Hopcroft-Karp Algoritmasının O(E√V) Büyüsü

İşleri çalışanlara, öğrencileri projelere veya sürücüleri teslimatlara atamak istediğimizi düşünelim. Her aday yalnızca belirli seçeneklerle eşleşebiliyorsa problemimiz bir iki parçalı graf eşleşmesi problemine dönüşür. Tek tek eşleşme aramak kolay görünse de veri büyüdüğünde klasik yöntemler nefes nefese kalır. Hopcroft-Karp ise artırma yollarını toplu biçimde işleyerek sahneye çıkar ve karmaşıklığı $O(E\sqrt{V})$ seviyesine indirir.

Devamı...

Idempotency: Aynı API İsteği İki Kere Gelirse Ne Olmalı?

idempotency-ayni-api-27

Bir kullanıcı “Öde” düğmesine bastı, internet bağlantısı kısa süreliğine koptu ve istemci aynı isteği yeniden gönderdi. Müşteriden iki kez para mı çekmeliyiz? Elbette hayır! İşte idempotency, aynı işlemin birden fazla kez talep edilmesine rağmen sistemin nihai durumunun yalnızca bir kez çalıştırılmış gibi kalmasını sağlayan tasarım ilkesidir.

Devamı...

Heavy-Light Decomposition: Ağaç Yollarını Segment Ağacına Taşımak

Bir ağaçta “$u$ ile $v$ arasındaki düğümlerin toplamı nedir?” veya “bu yol üzerindeki bütün değerleri artır” gibi işlemler ilk bakışta masum görünür. Ancak her sorguda yolu adım adım yürümek, çarpık bir ağaçta $O(n)$ zaman harcatabilir. Heavy-Light Decomposition, kısaca HLD, ağacı değiştirmek yerine yolları akıllıca numaralandırır ve zor görünen yol işlemlerini segment ağacının sevdiği dizi aralıklarına dönüştürür.

Devamı...

Graf Teorisinde Çift Bağlantılı Bileşenler ve Köprüleri Bulmak

Bir bilgisayar ağında tek bir kablonun kopması sistemi iki parçaya ayırabilir mi? Ya da bir sosyal ağdaki tek bir kullanıcının ayrılması topluluklar arasındaki iletişimi kesebilir mi? Graf teorisindeki köprüler, eklem noktaları ve çift bağlantılı bileşenler, ağların bu dramatik zayıflıklarını ortaya çıkarmamızı sağlar.

Devamı...

Geriye İzlemeli Aramada Alpha-Beta Budaması: Satranç Motorlarının Matematiksel Makası

Bir satranç motoru geleceği gerçekten görmez; olası hamleleri dallanan dev bir ağaç üzerinde sistematik biçimde dener. Ancak bütün dalları incelemek, daha açılışta hesaplama kaynaklarını tüketir. Alpha-beta budaması, sonuca etki etmeyeceği matematiksel olarak kanıtlanan dalları keserek motorun aynı sürede çok daha derine inmesini sağlayan akıllı makastır.

geriye-izlemeli-aramada-93

Devamı...

Geometrik Kesilen Çizgiler: Voronoi Diyagramları ve Delaunay Nirengisi

Bir şehre yeni itfaiye istasyonları yerleştirdiğimizi düşünelim. Her mahalle hangi istasyona daha yakın? İstasyonları birleştirerek düzgün ve çakışmayan bir iletişim ağı nasıl kurabiliriz? İlk sorunun cevabı Voronoi diyagramı, ikincisinin güçlü adaylarından biri ise onun geometrik ikizi olan Delaunay nirengisidir. Bu iki yapı; haritacılıktan oyun geliştirmeye, robot rotalarından kablosuz ağlara kadar şaşırtıcı ölçüde geniş bir kullanım alanına sahiptir.

Devamı...

Eşleştirme Oyunlarında Grundy Sayıları: Kazandıran Hamlenin Matematiği

Bir masanın üzerindeki çubukları, taşları veya eşleşebilen kartları sırayla kaldırdığınızı düşünün. Kurallar basit görünür: Hamle yapamayan kaybeder. Fakat hangi hamlenin kazandıracağını bulmak, özellikle bağımsız oyun parçaları birleştiğinde, sezgiden fazlasını gerektirir. Grundy sayıları ya da diğer adıyla nimber, her oyun durumunu tek bir sayıyla özetleyerek bu karmaşayı yönetilebilir bir matematik problemine dönüştürür.

Devamı...

Dinamik Programlamada Hız Sihri: Knuth Optimizasyonunun Sırları

Dinamik programlama bazen doğru bağıntıyı bulduğumuz anda bizi sevindirir, ardından $O(N^3)$ zaman karmaşıklığıyla moralimizi bozar. Özellikle bir aralığı en uygun noktadan bölmeye dayanan problemlerde aynı geçişler tekrar tekrar incelenir. Knuth optimizasyonu, optimum bölme noktalarının düzenli hareket ettiğini matematiksel olarak kanıtlayabildiğimiz durumlarda bu kübik maliyeti $O(N^2)$ seviyesine indiren zarif bir tekniktir.

Devamı...

Dinamik Bağlantılı Bileşenler: Zamanı Böl, Grafı Fethet

Bir sosyal ağda arkadaşlıklar kuruluyor, bozuluyor ve arada “Ali ile Ayşe hâlâ dolaylı olarak bağlantılı mı?” soruları geliyor. Graf sürekli değişirken her sorguda baştan DFS çalıştırmak mümkündür; fakat performansınız kısa sürede dramatik bir vedaya hazırlanır. Çevrimdışı dinamik bağlantılılık, tüm işlemleri önceden bilmenin avantajını kullanarak zamanı parçalara ayırır ve bağlantıları geri alınabilir bir DSU ile takip eder.

Devamı...

CQRS: Okuma ve Yazma Modellerini Neden Ayırıyoruz?

Bir e-ticaret uygulamasında ürün satın almak ile ürün listesini görüntülemek aynı veri üzerinde çalışıyor gibi görünür. Ancak satın alma işlemi stok kontrolü, ödeme ve iş kuralları gerektirirken listeleme işlemi yalnızca hızlı ve zengin bir görünüm ister. CQRS, bu iki farklı ihtiyacı tek bir modelin omuzlarına yüklemek yerine okuma ve yazma taraflarını birbirinden ayırır.

cqrs-okuma-ve-67

Devamı...

Commit’ten Üretime: CI/CD Pipeline’larının Anatomisi

Bir geliştirici kodunu depoya gönderdiğinde görünmez bir fabrika çalışmaya başlar: kaynak kod derlenir, testlerden geçirilir, paketlenir ve kontrollü biçimde kullanıcılarla buluşturulur. CI/CD pipeline adı verilen bu otomatik yolculuk, “Benim bilgisayarımda çalışıyordu!” cümlesini tarihe gömmeyi hedefleyen teknik aşamalar ile güvenlik kapılarından oluşur.

committen-uretime-cicd-48

Devamı...

Brian Kernighan Algoritmasıyla Set Bitlerini Şimşek Hızında Saymak

Bir tam sayının ikili gösteriminde kaç tane 1 bulunduğunu saymak ilk bakışta sıradan bir döngü problemi gibi görünür. Ancak düşük seviyeli programlamanın büyüsü, bazen bütün bitleri tek tek dolaşmak yerine yalnızca ilgilendiğimiz bitlere dokunabilmemizdir. Brian Kernighan algoritması, her turda sağdaki bir adet set bitini temizleyerek gereksiz döngüleri ortadan kaldıran zarif bir bit maskeleme hilesidir.

Devamı...

Aho-Corasick ve Dinamik Programlama ile Yasaklı Kelimelerden Kaçınan Metin Üretimi

aho-corasick-ve-37

Bir alfabenin karakterlerini kullanarak belirli uzunlukta metinler üretmek kolaydır: alfabe boyutu $K$, metin uzunluğu $N$ ise toplam $K^N$ seçenek vardır. Ancak metnin içinde “abc”, “kedi” veya “virus” gibi yasaklı kelimelerin hiç geçmemesini istediğimizde işler karışır. Her dizgiyi tek tek üretip kontrol etmek astronomik derecede pahalıdır. Neyse ki Aho-Corasick otomatı ile dinamik programlamayı birleştirerek tüm geçerli dizgileri üretmeden sayabiliriz.

Devamı...

Ağaçlarda Euler Turu Tekniği: Alt Ağaçları Tek Boyutlu Dizide Yakalamak

agaclarda-euler-turu-67

Bir şirket hiyerarşisindeki yöneticileri, dosya sistemindeki klasörleri veya bir oyundaki yetenek ağacını düşünün. Bu yapılarda “X düğümünün altındaki bütün değerlerin toplamı nedir?” gibi sorgular sıkça karşımıza çıkar. Ağacı her sorguda yeniden dolaşmak pahalıdır; Euler Turu Tekniği (ETT), alt ağaçları tek boyutlu ve kesintisiz dizi aralıklarına dönüştürerek segment ağacının süper güçlerinden yararlanmamızı sağlar.

Devamı...

Ağaç İçi Mesafelerin Gizli Silahı: Centroid Decomposition

Bir ağaçta iki düğüm arasındaki mesafeyi hesaplamak kolaydır; fakat binlerce güncelleme ve sorgu geldiğinde işler hızla dallanıp budaklanır. Centroid Decomposition, ağacı dengeli biçimde parçalara ayırarak mesafe problemlerini yaklaşık $O(\log n)$ katman üzerinden çözmemizi sağlar. Kısacası ağacın fiziksel yapısını değiştirmeden, onun üzerinde ikinci ve dengeli bir “centroid ağacı” kurarız.

agac-ici-mesafelerin-68

Devamı...