Computer Science
Otomata Teorisi Sohbetleri: Bölüm 2 - İşin Matematiği
December 6, 2025
İnşaat mühendisliğinde statik ve mukavemet neyse, bizim meslekte de Otomata Teorisi odur. Nasıl ki bir mimar yerçekimini yok sayıp “bence bu kolon burayı taşır, çok şık duruyor” diyemezse, iyi bir yazılımcı da hesaplamanın matematiksel sınırlarını görmezden gelemez.
Yazılım dünyasında şöyle bir yanılgı var: “Kod çalışıyorsa doğrudur.” Hayır, kod çalışıyordur ama belki de henüz çökmesi için gereken o özel veri kombinasyonuyla karşılaşmamıştır. Hesaplama teorisini yok sayarsanız, o bina ilk büyük yükte (trafik artışında veya beklenmedik bir kullanıcı girdisinde) çatlar. Bizim dünyamızda bu çatlak; sistemin kilitlenmesi, veritabanının tutarsız hale gelmesi veya kodun bir süre sonra kimsenin dokunmaya cesaret edemediği, her dokunanın elinde kalan o meşhur “makarna”ya dönüşmesidir.
Çoğumuz üniversitede bu dersi gördük, kabul edelim; sıkıcıydı. Tahtaya çizilen yuvarlaklar (q0, q1), oklar, garip lambda (λ) sembolleri… “Bunlar gerçek hayatta ne işime yarayacak? Müşteri benden login sayfası istiyor, Turing makinesi değil!” dedik.
Oysa işin rengi hiç öyle değil. Framework’ler, kütüphaneler moda gibidir; gelir ve geçer. Dün jQuery vardı, bugün React var, yarın başka bir şey olacak. Ama Otomata Teorisi 70 yıldır değişmedi. Çünkü bu işin fiziği bu. 1950’de bir makinenin nasıl çalışması gerektiğine dair matematik neyse, bugün Cloud üzerinde koşan bir Kubernetes cluster’ının arkasındaki matematik de odur.
Gelin, bu teorinin neden sadece akademik bir hobi olmadığını, aksine “Senior” olmanın yolunu nasıl kısalttığını ve geceleri rahat uyumanın formülü olduğunu konuşalım.
1. Test Yazmak Yetmez: “Düşünmediğin” Senaryoyu Nasıl Test Edersin?
Hepimiz test yazıyoruz (yani, umarım yazıyoruzdur). Ama birim testlerinde çok temel bir mantık hatamız var: Deterministik körlük.
Test yazarken senaryoyu sen kuruyorsun. “Kullanıcı butona basarsa ne olur?”, “Şifreyi yanlış girerse ne olur?” diye düşünürsün. Bu testler, kodun senin düşündüğün gibi çalışıp çalışmadığını ölçer. Peki ya kodun, senin hiç aklına gelmeyen bir durumda nasıl davrandığı?
Durum Patlaması
Modern yazılımlar artık çok karmaşık. Sisteme eklediğin masum görünen her yeni boolean değişken (örneğin: isLogin, hasError, isLoading, isRetrying), sistemin olası hallerini matematiksel olarak ikiye katlar.
- 1 değişken = 2 durum.
- 10 değişken = 1024 farklı durum.
- 20 değişken = 1 milyonun üzerinde farklı durum.
Hangi insan beyni 1 milyon farklı kombinasyonu (örneğin: isLoading=true ama data=null ve isError=false iken kullanıcının “Geri” tuşuna basması durumu) aynı anda aklında tutup buna test yazabilir? İşte bug’lar tam olarak bu “arada kalmış”, kimsenin düşünmediği gri bölgelerde yaşar.
Şekil 1: Karmaşık boolean değişkenlerin yarattığı kaos (sol) ile Sonlu Durum Makinesinin (FSM) sunduğu düzenli yapı (sağ) arasındaki fark.
Çözüm: T.S. Chow ve W-Set Yöntemi
Bell Labs’den T.S. Chow gibi efsaneler, bu işi şansa bırakmamak için Sonlu Durum Makineleri teorisini geliştirdiler. Diyorlar ki; eğer kritik bir modülü (mesela bir ATM yazılımını veya ödeme geçidini) kafana göre if-else ile kodlamak yerine, kağıt üzerinde bir FSM olarak çizersen, işin rengi değişir.
FSM kullandığında “W-set” denilen bir yöntemle, sistemin için matematiksel bir test kümesi oluşturabilirsin. Bu test kümesi rastgele değildir, sana şunları matematiksel kesinlikle garanti eder:
- Durum Kapsaması: Tasarladığın her duruma (Örn: “Para Sayılıyor”, “Kart İade Edildi”) kod içinde gerçekten ulaşılabiliyor mu? Yoksa “Ölü Kod” var mı?
- Geçiş Doğrulaması: “Şifre Girildi” durumundan “Para Çekme” durumuna geçerken, sistemin mutlaka “Bakiye Kontrolü” yapması gerektiğini matematiksel olarak zorunlu kıldın mı?
- Yasaklı Geçiş Kontrolü: Kullanıcının, ödeme yapmadan doğrudan “Sipariş Onaylandı” durumuna atlamasının imkansız olduğunu kanıtladın mı?
Normal testlerle %80 kapsama ulaşıp mutlu olursun. Otomata teorisi ile kritik akışlarda %100 mantıksal kapsama ulaşırsın.
2. Mikroservislerin Kabusu: “Neden Kilitlendik?”
Dağıtık sistemler, mikroservisler, blockchain, event-driven architecture… Kulağa çok havalı geliyor ama aslında hepsi birer saatli bomba.
Senaryo tanıdık: Servis A, işlem yapmak için Servis B’den veri bekliyor. Servis B işini bitirmek için Servis C’ye gidiyor. Servis C ise bir veriyi doğrulamak için tekrar Servis A’ya dönüyor.
Sonuç? Herkes birbirini bekliyor. Kimse adım atamıyor. Sistem dondu. Deadlock.
Daha kötüsü de var: Livelock. İki insan dar bir koridorda karşılaşır, ikisi de aynı anda yol vermek için sağa çekilir, sonra aynı anda sola çekilirler ve sonsuza kadar dans ederler ya; servislerin de sürekli birbirine hata mesajı gönderip işlemi bir türlü bitiremediği durumdur bu.
Bu hatalar senin bilgisayarında asla çıkmaz. Çünkü senin bilgisayarında ağ gecikmesi yok, trafik yok. Bu hatalar, “Black Friday” günü trafik patlayınca, yani en olmamasının gerektiği anda production ortamında çıkar.
İletişimsel Otomatlar ve Koreografi
İşte burada “İletişimsel Otomatlar” devreye giriyor. İşin uzmanları (Imperial College London, CNRS) diyor ki; “Servisleri kafana göre konuşturma. Önce global bir koreografi tasarla.”
Bunu bir tiyatro oyunu senaryosu gibi düşün. Kimin ne zaman konuşacağı, kimin kimi bekleyeceği “Global Tip” olarak tanımlanır.
Global: Müşteri -> Sipariş -> (Ödeme ? Onay : Red) -> Müşteri
Şekil 2: Mikroservisler arasında kilitlenmeyi önleyen, önceden tasarlanmış bir iletişim koreografisi.
Otomata teorisi, bu senaryoyu analiz eder ve “Kilitlenmeme” garantisi verir. Sonra derleyici, bu büyük senaryoyu her servise “izdüşürür”.
Ödeme Servisi’ne der ki: “Sen sadece Sipariş’ten mesaj bekle, sonra Banka’ya git, sonucu Müşteri’ye dön.”
Eğer her servis kendi rolünü doğru oynarsa, sistemin bütününün kilitlenmesi matematiksel olarak imkansızdır. Geceleri “acaba sistem çöktü mü?” diye uyanmak zorunda kalmazsın.
3. Regex: Elindeki Bombanın Farkında Mısın?
Dürüst olalım, hepimiz StackOverflow’dan Regex kopyalıyoruz. “E-posta doğrulama regex” yazıp ilk geleni yapıştırıyoruz. Ama o kopyaladığın ^([a-zA-Z0-9]+)*$ gibi masum görünen satırın arkasında bir canavar yatıyor olabilir.
Regex aslında metin tabanlı minik bir programlama dilidir ve arkasında bir otomat çalışır. Eğer dikkatsizce, ReDoS açığı olan bir desen yazarsan, basit bir form kontrolü bile sunucunun işlemcisini %100’e kilitler ve siteyi çökertir.
Backtracking Cehennemi
Neden mi? Çünkü çoğu modern dil (Python, Java, JS) NFA tabanlı motorlar kullanır. NFA’lar “şansını dener”.
Eşleşme bulamazsa, “Acaba şurada yanlış mı yaptım?” der ve geriye döner. Kötü yazılmış bir Regex’te, eşleşmeyen uzun bir metin verdiğinde, motor milyarlarca farklı kombinasyonu denemeye başlar. Bir bakmışsın, tek bir request sunucuyu kilitlemiş.
Chomsky Hiyerarşisi: Neyi Nerede Kullanmalısın?
Otomata teorisi sana sadece Regex’i değil, Chomsky Hiyerarşisini de öğretir. Bu hiyerarşi sana şunu söyler:
- Düzenli Diller: Basit desenler için. Hafızası yoktur. Sayamaz.
- Bağlamdan Bağımsız Diller: HTML, JSON, XML gibi iç içe yapıları ayrıştırmak için.
Bunu bilmeyen yazılımcı ne yapar? HTML’i Regex ile parse etmeye çalışır (<.*?>). Ama Regex, açılan <div> etiketinin nerede kapandığını “hatırlayamaz” çünkü bir yığını yoktur. Sonuç: Kırık, güvensiz ve hatalı çalışan parserlar.
4. Oyun ve Arayüz Geliştirme: “Boolean Cehennemi”nden Çıkış
Özellikle Frontend (React, Vue, Mobile) yazan arkadaşların en büyük derdi: Durum Yönetimi.
Kodun içinde genellikle şöyle şeyler görüyoruz:
if (!isLoading && !isError && data != null && isUserActive && !isRetrying) {
// Göster
}
Bu kod kırılgandır. Yarın birisi gelip “bir de isOffline modu ekleyelim” derse, tüm o if mantığını yeniden kurman gerekir. Hata yapma ihtimalin %100’e yakındır.
Ayrıca, sistemin aynı anda hem isLoading: true hem isError: true olması mümkün müdür? Mantıken hayır, ama değişkenler bağımsız olduğu sürece kodun bunu yapabilir. Buna “İmkansız Durum” denir. Kullanıcıya hem “Yükleniyor” dönen tekerleği gösterip hem de altında “Hata Oluştu” yazısı çıkarmak, amatörlüktür.
Çözüm: Açık Durum Makineleri
Çözüm yine otomatlar. XState gibi kütüphaneler veya Redux’taki state mantığı, aslında birer FSM’dir.
Şekil 3: Bir kullanıcı arayüzünün (UI) olası durumlarını ve geçişlerini gösteren durum diyagramı. Ara durumların (gri alanların) nasıl elimine edildiğine dikkat edin.
Sistemi “değişkenler yığını” olarak değil, “Durumlar” olarak düşünürsün:
- IDLE (Boşta)
- LOADING (Yükleniyor)
- SUCCESS (Başarılı)
- FAILURE (Hata)
Geçişler bellidir: LOADING durumundan sadece SUCCESS veya FAILURE durumuna geçilebilir. Arada gri alan yoktur. Kodun temizlenir, okunabilir hale gelir ve en önemlisi; öngörülebilir olur.
Oyunlarda da bu böyledir. Bir düşman karakterinin yapay zekasını if’lerle yazarsan o karakter duvara takılır, sizi görmesine rağmen ateş etmez. Ama bir Durum Makinesi ile yazarsan (Devriye Gez -> Oyuncuyu Gör -> Siper Al -> Saldır), karakter tutarlı davranır.
Hatta, Minecraft veya Terraria gibi oyunlardaki o sonsuz ve doğal görünen mağaralar, nehirler nasıl yapılıyor sanıyorsunuz? Rastgele noktalar koyarak değil. Hücresel Otomatlar denilen, basit komşuluk kurallarına dayalı sistemlerle. “Eğer etrafımda 4 duvar varsa ben de duvar olayım” gibi basit bir kural, milyonlarca hücrede işletildiğinde ortaya muazzam doğal yapılar çıkar.
5. Gerçeklik Kontrolü: Bu Teori Olmadan Kod Yazılmaz mı?
Buraya kadar anlattıklarımız, Otomata Teorisinin ne kadar güçlü bir araç olduğunu gösteriyor. Ancak dürüst bir parantez açalım: Turing makinesinin nasıl çalıştığını resmi olarak bilmeden de başarılı, zengin ve saygın bir yazılımcı olabilir misiniz? Kesinlikle evet.
Sektörde “Senior” unvanına sahip olup DFA ile NFA arasındaki farkı akademik olarak bilmeyen binlerce harika mühendis var. Bu teoriyi bir “kapı bekçisi” olarak görmeyin. Kimse sizden günlük işinizde Turing makinesi ispatı istemeyecek.
Sezgi vs. Bilim: Zaten Yapıyorsunuz!
Deneyimli yazılımcılar, yıllar içinde yedikleri tokatlarla (bug’lar, gece yarısı çöküşleri) bu prensipleri sezgisel olarak öğrenirler. Bir noktada, “Bu boolean değişkenler başımı ağrıtıyor, durumu tek bir yerde tutayım” derler. Yani aslında Sonlu Durum Makinesini yeniden keşfederler, sadece adının bu olduğunu veya arkasındaki matematiği bilmezler.
Otomata Teorisi öğrenmek, bu 10 yıllık deneme-yanılma sürecini 6 aya indirir.
- Hızlandırıcıdır: Size tekerleği yeniden icat ettirmez; tekerleğin neden döndüğünü öğretir.
- Dil Birliğidir: Ekip arkadaşınıza “Burada işler karıştı” demek yerine “Burada NFA gibi davranan belirsiz bir yapı var, bunu deterministik hale getirelim” dediğinizde, sorunun çözümü herkes için netleşir.
Özetle: Bu teori olmadan da uçabilirsiniz, ama aerodinamik bilirseniz türbülanslarda panik yapmaz, krizi mühendislik hassasiyetiyle yönetirsiniz.
Son Söz: Zanaatkar Olmak
Kod yazmak sadece syntax ezberlemek, API dokümantasyonu okumak değildir. İşin mühendislik kısmı, yazdığın sistemin her koşulda, her yük altında nasıl davranacağını bilmekten geçiyor.
Otomata teorisi, o belirsizlik sisini dağıtan en güçlü fenerdir. Bu yazıyı, “bunu bilmeyen kod yazamaz” şeklinde bir dogma olarak değil, “bunu bilen çok daha güvenli ve keyifli kod yazar” şeklinde bir davet olarak okuyun.
Emin ol, öğreneceğin bir sonraki popüler JavaScript kütüphanesinden çok daha fazla işine yarayacak ve seni “kod yazan eleman”dan “sistemi tasarlayan mühendis”e dönüştürecek.
Meraklısı İçin Kaynakça (Derinlemesine Okuma)
Eğer “Tamam ikna oldum, nereden başlamalı?” diyorsan, işte sana akademik ama bir o kadar da ufuk açıcı kaynaklar:
Temeller ve Mantık (Regex & Derleyiciler)
- “Regular Expressions and Automata” (Jurafsky & Martin)
- Neden Okumalı: Regex motorlarının kaputunun altında ne döndüğünü, NFA/DFA farkını ve metin işlemeyi harika anlatır.
- PDF İndir (Stanford/Colorado Edu)
- “Tree Automata Techniques and Applications” (TATA)
- Neden Okumalı: Biraz daha ileri seviye; program doğrulama ve statik analiz için başucu kitabıdır.
- Kitap PDF İndir (Inria/ENS Lyon)
Güvenilirlik ve Dağıtık Sistemler
- “Testing Software Design Modeled by Finite-State Machines” (T.S. Chow)
- Neden Okumalı: FSM ile %100 test kapsamına nasıl ulaşılır? Bu işin matematiği burada.
- PDF İndir (ETH Zurich Mirror)
- “Multiparty Session Types Meet Communicating Automata”
- Neden Okumalı: Mikroservis mimarisinde Deadlock’sız bir hayat mümkün mü? Evet, kanıtı burada.
- PDF İndir (Royal Holloway Univ)
- “Symbolic Automata” (Microsoft Research)
- Neden Okumalı: Büyük veri ve sonsuz alfabelerle modern otomatlar nasıl çalışır?
- PDF İndir (Arxiv)
Oyun Geliştirme ve Pratik
- “Finite State Machines in Game Development”
- Neden Okumalı: Oyun yapay zekasını (AI) spagetti koda çevirmeden yönetmek için.
- PDF İndir (IJARSCT)
- “Procedural Map Generation using Automata”
- Neden Okumalı: Rastgele ama mantıklı haritalar (mağaralar, dünyalar) yaratmanın sırrı: Hücresel Otomatlar.
- PDF İndir (Procedural Gen)
Yorumlar