Docker Compose ile Çoklu Servis Orkestrasyonu: Tek Dosyada Uyumlu Konteynerler

Modern bir uygulama nadiren tek başına çalışır: API’nin veritabanına, arka plan işlerinin kuyruk sistemine, tüm ekibin de tutarlı bir geliştirme ortamına ihtiyacı vardır. Docker Compose, bu parçaları tek tek docker run komutlarıyla başlatmak yerine, aralarındaki ilişkiyi bildirime dayalı bir YAML dosyasında tanımlamanızı sağlar. Sonuç, “benim makinemde çalışıyordu” cümlesini daha az duyduğunuz, tekrarlanabilir bir çalışma düzenidir.

docker-compose-ile-41

Devamı...

CI/CD’de SAST ve DAST: Güvenliği Pipeline’ın İlk Vatandaşı Yapmak

cicdde-sast-ve-18

Modern yazılım ekipleri için hız tek başına başarı ölçütü değildir: Güvenli olmayan bir özelliği dakikalar içinde canlıya almak, sadece hatayı daha hızlı yaymaktır. Bu nedenle CI/CD pipeline’ına güvenlik taramalarını eklemek, güvenliği sürüm sonundaki bir denetim kapısı olmaktan çıkarıp geliştirme yaşam döngüsünün doğal parçası hâline getirir. SAST ve DAST araçları bu yaklaşımın iki güçlü, fakat farklı bakış açısına sahip oyuncusudur.

Devamı...

CAP Teoremini E-Ticaret Sepetinde Simüle Etmek

Dağıtık sistemler, tek bir veritabanına güvenmek yerine veriyi birden fazla düğümde tutarak ölçeklenebilirlik ve hata toleransı sağlar. Ancak ağ bölünmesi yaşandığında sihirli bir biçimde hem her isteğe anında cevap verip hem de tüm kopyaları kusursuz biçimde eşitleyemezler. CAP teoremi bu zorunlu ödünleşimi görünür kılar. Bunu teorik bir üçgen olarak ezberlemek yerine, e-ticaret sepeti ve stok ekranı üzerinde küçük bir simülasyonla incelemek çok daha öğreticidir.

Devamı...

Birim, Entegrasyon ve Uçtan Uca Testler: Güvenilir Yazılımın Test Piramidi

Yazılım güvenilirliği, yalnızca uygulamanın bir kez çalışmasıyla ölçülmez; değişikliklerden sonra da doğru davranmasını sürdürebilmesiyle ölçülür. İşte test piramidi, ekiplerin sınırlı zaman ve kaynakla hangi testlere ne kadar yatırım yapması gerektiğini anlatan pratik bir modeldir. Piramidin tabanında hızlı ve bol miktarda birim testi, ortasında bileşenlerin birlikte çalışmasını doğrulayan entegrasyon testleri, tepesinde ise gerçek kullanıcı yolculuklarını sınayan az sayıda uçtan uca test bulunur.

Devamı...

Apache Spark ile Büyük Veri İşleme: Dağıtık Hesaplamanın Gücü

apache-spark-ile-34

Bir sunucunun belleğine sığmayan, klasik araçlarla işlenmesi saatler hatta günler süren verilerle karşılaşıldığında sahneye Apache Spark çıkar. Spark; veriyi birden fazla makineye bölerek aynı işi paralel gerçekleştiren, hızlı ve genel amaçlı bir dağıtık hesaplama motorudur. Log analizi, öneri sistemleri, ETL hatları ve makine öğrenmesi gibi alanlarda devasa veri kümelerini yönetilebilir parçalara dönüştürür.

Devamı...

Specification Pattern ile Karmaşık İş Kurallarını Evcil Hale Getirmek

İş kuralları büyüdükçe kod tabanında küçük bir canavar belirir: her yerde çoğalan if koşulları. “Müşteri aktif mi?”, “Sepet tutarı yeterli mi?”, “Ürün stokta mı?” gibi sorular önce masum görünür; sonra aynı kontroller servis, API ve rapor katmanlarında kopyalanır. Specification Pattern, bu kuralları isimlendirilmiş, test edilebilir ve birleştirilebilir nesnelere dönüştürerek canavarı evcilleştirir.

Devamı...

SMT Solver’lar Nasıl Çalışır? Program Doğrulamada Matematiksel Mantığın Gücü

Bir programın her olası girdide güvenli çalıştığını kanıtlamak, yalnızca binlerce test yazmakla mümkün değildir. İşte bu noktada SMT (Satisfiability Modulo Theories) solver’ları devreye girer: Mantıksal formüllerin, tamsayı aritmetiği, diziler, bit vektörleri ve eşitlik gibi teoriler altında tutarlı olup olmadığını incelerler. Kısacası solver’a “Bu koşulları aynı anda sağlayan bir durum var mı?” diye sorarız; yanıt çoğu zaman programdaki hatayı ya da kanıtı ele verir.

Devamı...

Semantic Release Otomasyonu: Commit Geçmişinden Akıllı Sürüm Yönetimi

semantic-release-otomasyonu-21

Bir projenin sürümünü elle artırmak, değişiklik listesini yazmak ve paketi yayımlamak küçük ekiplerde bile sürpriz derecede hataya açıktır. Semantic Release, Git commit geçmişini okuyarak bu ritüelleri otomatikleştirir: doğru sürüm numarasını hesaplar, CHANGELOG üretir, etiketi oluşturur ve istenirse npm gibi kayıt depolarına paketi yollar. Böylece ekip, “hangi değişiklik major olmalıydı?” tartışmasını yayın gecesine bırakmaz.

Devamı...

Refactoring Desenleri: Davranışı Korumayı Öğrenen Kod

Bir kod tabanını iyileştirmek, her zaman yeni özellik eklemek anlamına gelmez. Bazen en değerli geliştirme; çalışan ama okunması zor, genişletmesi pahalı ve hata üretmeye yatkın kodu daha anlaşılır hâle getirmektir. Refactoring, dışarıdan gözlemlenen davranışı değiştirmeden kodun iç tasarımını düzenleme disiplinidir. Amaç yalnızca “güzel kod” yazmak değil; gelecekteki değişikliklerin maliyetini ve riskini azaltmaktır.

refactoring-desenleri-davranisi-23

Devamı...

Program Sentezi: Örneklerden Çalışan Kod Üretmenin Mantığı

Program sentezi, bir programcının her satırı elle yazması yerine sistemin verilen niyetten, kısıtlardan veya giriş-çıkış örneklerinden çalışan bir program üretmesidir. İlk bakışta “yapay zekâ kod yazıyor” kadar sihirli görünür; fakat mutfakta oldukça somut fikirler vardır: arama, mantıksal çıkarım, istatistiksel öğrenme ve doğrulama. Amaç yalnızca örnekleri ezberleyen bir fonksiyon değil, daha önce görülmemiş girdilerde de doğru davranan genellenebilir bir program bulmaktır.

Devamı...

Outbox Pattern ile Mikro Servislerde Veri Kaybını Önleme

Mikro servis mimarisinde bir siparişi veritabanına kaydedip ardından OrderCreated olayını mesaj kuyruğuna göndermek basit görünür. Fakat veritabanı işlemi başarılı olurken broker bağlantısı koparsa ne olur? Sipariş vardır, olay yoktur ve stok, ödeme ya da bildirim servisleri bu siparişi hiç öğrenemez. Outbox Pattern, bu can sıkıcı “yarım kalmış başarı” durumunu güvenilir ve izlenebilir bir akışa dönüştürür.

Devamı...

Meet in the Middle: Üstel Aramayı İkiye Bölmenin Olimpiyat Hilesi

meet-in-the-77

Bazı problemler ilk bakışta masum görünür: Elimizde $n$ eleman vardır, her biri için seç veya seçme kararı veririz. Ancak bu küçük kararların toplamı $2^n$ farklı kombinasyon üretir. $n=40$ için yaklaşık bir trilyon olasılık demektir; bilgisayarınızın fanı bu noktada dramatik bir monoloğa başlayabilir. Ortadan Buluşma (Meet in the Middle, MITM), arama uzayını iki parçaya ayırarak bu üstel duvarı aşmaya yarayan klasik olimpiyat tekniğidir.

Devamı...

Mediator Tasarım Deseni: Nesneler Arasındaki Trafiği Yönetmek

Bir sınıfın diğer beş sınıfı doğrudan tanıdığı bir uygulama, küçükken masum görünür; büyüdükçe ise kabloları birbirine dolanmış bir sunucu odasına dönüşür. Mediator (Arabulucu) tasarım deseni, nesnelerin birbirleriyle doğrudan konuşması yerine merkezi bir arabulucu üzerinden iletişim kurmasını sağlar. Böylece sınıflar arası bağımlılık azalır, iletişim kuralları tek bir noktada toplanır ve sistemi değiştirmek daha güvenli hale gelir.

mediator-tasarim-deseni-11

Devamı...

KMP Algoritması ile Metin Eşleştirme: Doğrusal Zamanda Kalıp Avı

kmp-algoritmasi-ile-33

Bir metin içinde belirli bir kelimeyi, DNA dizisini ya da log kaydındaki hatayı aramak ilk bakışta basit görünür. Ancak metin milyonlarca karakter, kalıp da binlerce karakter olduğunda “uyuşmazsa başa dön” yaklaşımı pahalılaşır. Knuth-Morris-Pratt (KMP) algoritması, daha önce öğrendiği eşleşme bilgisini çöpe atmadan ilerleyerek bu problemi doğrusal zamanda çözen klasik bir tekniktir.

Devamı...

Hexagonal Architecture Nedir? İş Mantığını Altyapıdan Özgürleştirmek

Bir uygulamanın veritabanını PostgreSQL’den MongoDB’ye taşımak, REST API yerine mesaj kuyruğu kullanmak ya da ödeme sağlayıcısını değiştirmek neden iş kurallarını kırmalıdır? Hexagonal Architecture, bu soruya güçlü bir “kırmamalı” yanıtı verir. Alistair Cockburn tarafından ortaya atılan bu yaklaşım, uygulamanın kalbi olan iş mantığını kullanıcı arayüzü, veritabanı ve harici servis gibi değişken ayrıntılardan izole eder.

Devamı...

Git Hooks ile Otomasyon: Commit ve Push İşlemlerini Güvenceye Alın

git-hooks-ile-64

Bir projede hatalı biçimlendirilmiş kodun, çalışmayan testlerin veya yanlışlıkla eklenmiş gizli anahtarların depoya ulaşması oldukça can sıkıcıdır. Kod incelemesi bu sorunların bir kısmını yakalasa da insan dikkati sınırlıdır. Git Hooks, Git olayları gerçekleştiğinde çalışan küçük betiklerle bu kontrolü otomatikleştirir. Böylece commit ve push süreci yalnızca bir kayıt işlemi değil, kalite kapısından geçen kontrollü bir akış hâline gelir.

Git hook’ları, yerel depodaki .git/hooks dizininde bulunan çalıştırılabilir dosyalardır. Git belirli bir olayı algıladığında ilgili dosyayı çağırır. Örneğin pre-commit, commit nesnesi oluşturulmadan hemen önce; pre-push ise uzak depoya veri gönderilmeden önce çalışır. Temel fikir basittir: betik 0 ile çıkarsa işlem sürer, sıfır dışı bir çıkış kodu üretirse Git işlemi durdurur.

Devamı...

Git Bisect: Hatayı Getiren Commit’i Dedektif Gibi Bulun

Bir projenin dün çalışan, bugün ise gizemli biçimde çöken bir sürümünü düşünün. Yüzlerce commit arasından “suçlu” değişikliği tek tek incelemek hem sabır hem de kahve tüketimi gerektirir. git bisect, bu işi ikili arama algoritmasıyla otomatikleştirir: Bildiğiniz iyi ve kötü commit’ler arasındaki geçmişi bölerek hatayı oluşturan ilk commit’i bulur.

Devamı...

Feature Flag Sistemleri: Kod Dağıtmadan Özellik Açıp Kapatmanın Mimarisi

feature-flag-sistemleri-78

Modern yazılım ekipleri için bir özelliği geliştirmek ile onu kullanıcılara sunmak aynı olay olmak zorunda değildir. Feature flag (özellik bayrağı), uygulamaya dağıtılmış fakat henüz herkese görünür olmayan davranışları çalışma anında kontrol etmeyi sağlar. Böylece büyük sürümler yerine küçük, geri alınabilir ve ölçülebilir değişiklikler yapılır. Bir nevi sahne arkasında dekor hazırdır; perdeyi ne zaman açacağınıza bayrak karar verir.

Devamı...

Diferansiyel Test: Yazılımları Birbirine Hakem Yapmak

diferansiyel-test-yazilimlari-61

Bir programın sonucunun doğru olup olmadığını her zaman elle hesaplamak kolay değildir. Özellikle derleyiciler, kriptografi araçları, veritabanları veya karmaşık hesaplama kütüphanelerinde beklenen çıktıyı üreten bir test oracle’ı yazmak başlı başına zor bir projeye dönüşür. Diferansiyel test (differential testing), bu sorunu zekice tersine çevirir: Aynı girdiyi benzer görevi yapan iki ya da daha fazla bağımsız yazılıma gönderir, sonra çıktıları karşılaştırır. Sonuçlar ayrışıyorsa ortada araştırmaya değer bir hata, belirsiz spesifikasyon veya uyumsuzluk vardır.

Devamı...

DDD ile Karmaşık İş Problemlerini Yazılım Modeline Dönüştürmek

Karmaşık bir iş alanını yazılıma aktarmak, veritabanına birkaç tablo eklemekten çok daha fazlasıdır. Sigorta poliçeleri, kargo rotaları veya kampanya kuralları gibi alanlarda asıl zorluk; kodun iş dilinden kopmasıdır. Domain-Driven Design (DDD), yazılımın merkezine teknik ayrıntıları değil, işletmenin gerçek kurallarını koyar. Amaç, uzmanların anlattığı dünyayı geliştiricilerin sürdürülebilir biçimde modelleyebilmesidir.

ddd-ile-karmasik-58

Devamı...