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ı...

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ı...

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ı...

UART ve Seri Haberleşme: İki Cihazın En Sade Sohbet Protokolü

Bir mikrodenetleyicinin sensörle, bilgisayarla veya başka bir kartla konuşmasını sağlamanın en kolay yollarından biri UART’tır. Karmaşık ağ katmanları, IP adresleri ya da bağlantı pazarlıkları yoktur; iki taraf doğru hızda dinler ve bitler sırayla yola çıkar. Kısacası UART, elektronik dünyasının “aynı dili ve tempoyu biliyorsak konuşabiliriz” anlaşmasıdır.

Devamı...

Time-Series Database’ler: Zaman Damgalı Veriler Neden Farklı Davranır?

Bir sunucunun CPU kullanımı, elektrik sayacının ölçümü, borsa fiyatı veya akıllı saatin kaydettiği nabız aynı temel özelliği taşır: Her değer belirli bir zaman anına aittir. Klasik veritabanları bu kayıtları elbette saklayabilir; ancak veri saniyede binlerce kez akmaya başladığında zaman, sıradan bir sütun olmaktan çıkar ve veri modelinin başrol oyuncusuna dönüşür.

Devamı...

SPI Protokolü: Yüksek Hızlı Çevresel Donanım İletişiminin Mantığı

Bir mikrodenetleyicinin sensör, ekran, ADC, DAC veya flash bellek gibi çevresel donanımlarla hızlı konuşması gerektiğinde SPI çoğu zaman sahneye çıkar. Açılımı Serial Peripheral Interface olan bu protokol, veriyi bit bit aktarmasına rağmen yüksek saat frekansı ve basit çalışma mantığı sayesinde oldukça hızlıdır. Kısacası SPI, donanım dünyasının “lafı dolandırmadan doğrudan konuşan” iletişim yöntemlerinden biridir.

Devamı...

SOLID Gerçek Projelerde: Prensip mi, Dogma mı?

SOLID, yazılım ekiplerinin toplantılarda ciddi yüz ifadeleriyle andığı; kod incelemelerinde ise bazen kılıç gibi kullandığı beş tasarım prensibidir. Doğru uygulandığında değişime dayanıklı kod üretir, yanlış yorumlandığında üç satırlık işlem için on iki arayüz ve yirmi sınıf doğurabilir. Dolayısıyla asıl soru “SOLID kullanmalı mıyız?” değil, “Hangi maliyet karşılığında ve hangi problem için kullanmalıyız?” olmalıdır.

solid-gercek-projelerde-75

Devamı...

Sensör Kalibrasyonu: Kusurlu Ölçüm Cihazından Güvenilir Veri Üretmek

Bir sıcaklık sensörünü buzlu suya daldırdığınızda 0 °C yerine 2,4 °C göstermesi onun işe yaramaz olduğu anlamına gelmez. Sensör yalnızca biraz “dürüstlük eğitimine” ihtiyaç duyuyor olabilir! Kalibrasyon, cihazın ürettiği ham değerlerle güvenilir referans değerler arasındaki ilişkiyi modelleyerek ölçüm hatasını azaltma işlemidir.

sensor-kalibrasyonu-kusurlu-78

Devamı...