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

Devamı...
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ı...
İş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ı...

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

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

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

Devamı...
Bir mikroservis çöktüğünde sorun çoğu zaman yalnızca o servisle sınırlı kalmaz. Ona istek gönderen uygulamalar yanıt bekler, bağlantı havuzları dolar, iş parçacıkları tükenir ve masum servisler de domino taşları gibi devrilmeye başlar. Circuit Breaker Pattern, elektrik sigortasına benzeyen bir koruma mekanizması kurarak bu zincirleme felaketi durdurur.
Devamı...
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ı...

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

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

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

Devamı...