6 dk okuma

Yazılım Mühendisliğinin Evrimi

Yazılım Mühendisliğinin Evrimi

2027'ye yaklaşırken yazılım dünyası, takip etmesi zor bir hızla şekil değiştiriyor. 2023 daha dün gibi; ChatGPT ve Claude'un adını yeni yeni duyduğumuz, onları merakla denediğimiz günler. Oysa o günlerdeki geliştirme alışkanlıklarımız, bugünkülerle neredeyse taban tabana zıt.

O zamanlar kodu biz yazıyor, hatayı biz arıyor, PR'ı satır satır biz okuyorduk. Yapay zekâ, takıldığımızda danıştığımız bir yardımcıydı. Bugün ise roller yer değiştirdi: Kodu çoğunlukla model yazıyor, biz yönlendiriyor ve onaylıyoruz. Öyle ki bir PR'ı review etmek ya da debug yapmak bile insanı üşendirir oldu; "bunu da prompt olarak verelim, o arkadaş debug yapsın 😄" noktasındayız. İstisnalar elbette vardır, ama hemen hemen herkesin artık bu şekilde yazılım geliştirdiğini düşünüyorum.

Çöplük ve Sorumluluk

Hepimiz biliyoruz ki böyle devam edersek (ki ediyoruz 😄) koca bir çöplük inşa edeceğiz. Anlamadığımız kodu onaylıyor, okumadığımız PR'ları birleştiriyor, nedenini bilmediğimiz bir düzeltmeyle hatayı "kapatıyoruz". Tek başına küçük görünen bu kısayollar, üst üste binince kimsenin tam olarak hâkim olmadığı bir sisteme dönüşüyor.

Bu ilk tehlike. Asıl tehlike ise bu çöplüğün sorumluluğunu almak zorunda kalacağımız an. Canlıda bir şey patladığında "kodu yapay zekâ yazdı" demek bir açıklama değil. Commit'i atan, PR'ı onaylayan sizseniz, o kod sizindir.

Dolayısıyla önlem almak zorundayız. Bence önlemin adı belli: Ürettiğimiz her şeyi anlayabilecek ve gerektiğinde savunabilecek seviyeye gelmek. Yani kodu yazmayı bıraksak bile ona sahip çıkmayı bırakmamak.

Yazılım mühendisliğinin şekil değiştirdiğini söylerken kastettiğim tam olarak bu. Eskiden junior bir geliştiriciden beklenen, kendisine verilen işi yapmasıydı; mimari kararları vermek, riskleri görmek ve kodun bütününe sahip çıkmak senior'ların işiydi. Artık işi yapan büyük ölçüde model. Geriye kalan, yani kararı vermek, sonucu denetlemek ve sorumluluğu üstlenmek, tırnak içinde söylüyorum, bir "senior" işi. Bu yüzden junior bir geliştirici de bu mesleği sürdürebilmek için kısmen bir senior gibi düşünmek zorunda.

Değişmeyen: Temeller

Peki bu, temelleri bir kenara bırakabileceğimiz anlamına mı geliyor? Hayır. Kıdemsiz bir geliştiriciyi kıdemli yapan yakıt hâlâ aynı: yaşadığı deneyimler ve çözdüğü problemler.

Tasarım desenlerini öğreniyordunuz, yine öğreneceksiniz. DevOps öğreniyordunuz, yine öğreneceksiniz. Clean code prensiplerini, hata ayıklamayı, bir sistemin neden yavaşladığını bulmayı deneyimliyordunuz; bunlar da yerinde duruyor.

Hatta önemleri arttı. Modelin önerdiği çözümün kötü bir tasarım olduğunu fark etmek için iyi tasarımın neye benzediğini bilmeniz gerekiyor. Bilmediğiniz bir şeyi denetleyemezsiniz. Yani değişen, neyi bilmeniz gerektiği değil; bu bilgiyi nasıl kullandığınız. Eskiden bilginizi kod yazarken kullanıyordunuz, şimdi yazılan kodu yönetirken ve denetlerken kullanıyorsunuz.

Değişen: Öğrenme Hızı

Asıl değişen şey, bunları öğrenmenin kolaylaşması.

İleri seviye bir konuyu öğrenmenin zorluğu yalnızca konuyu anlamakta değildi; o sürecin içinde kalabilmekteydi. Bilmediğiniz bir konu doğası gereği sıkıcıdır ve sıkılan insan da zor anlar. Yani konu zaten zordu, sıkıcılık onu iki kat zorlaştırıyordu. Aynı videoyu tekrar tekrar izliyor, bir makaleyi okuyup anlamayınca başka bir makale arıyorduk.

Şimdi buna gerek yok. Hatta bu yazıyı bile okumak zorunda değilsiniz, bir yapay zekâya özetletebilirsiniz 😄 Yapay zekâyla birebir, sohbet tadında konuşarak çok daha hızlı öğrenebiliyorsunuz. Anlamadığınız yeri tekrar sorabiliyor, kendi projenizden örnek isteyebiliyorsunuz. Süreç kısalıyor ve sıkılmaya fırsat kalmıyor.

Ama burada da bir tuzak var: Bir konuyu hızlıca dinlemiş olmak, onu öğrenmiş olmak demek değil. Yapay zekâ her şeyi o kadar akıcı anlatıyor ki anladığınızı sanıyorsunuz. Bu da bizi yine o çöplüğe götürüyor.

Benim önerim, yapay zekâyı yalnızca anlatıcı olarak değil, sınav yapan biri olarak da kullanmanız. "Bana açıkla" demekle yetinmeyin; "şimdi bana soru sor, cevaplarımdaki boşlukları göster" deyin. Bir hatayı ona çözdürmeden önce sebebini önce siz tahmin edin. Öğrenmeyi hızlandıran araç, aynı zamanda öğrenmeyi atlamanızı da kolaylaştırıyor; hangisini yapacağınız size kalmış.

Mülakatlar: Artık Ne Soruluyor?

Bu değişim yalnızca nasıl çalıştığımızı değil, nasıl işe alındığımızı da etkiliyor.

İş başvurusundan önce CV'mizi günceller, GitHub hesabımızı bir elden geçirir, orayı diri tutmaya çalışırdık 😊 Bunlar hâlâ geçerli. Ama bir de live coding vardı; ya da şirket bir task verir, bilgimizi ve deneyimimizi onunla ölçerdi. İşte bu kısım gerçekten şekil değiştirdi.

Artık bir problemi yapay zekâ ile çözdüğümüz aşikâr. Bunu herkes biliyor; şirketler de biz de. Şirketlerin kendi geliştiricileri de bu şekilde çalışıyor. Bunun önüne geçmeye çalışmak hiç akıllıca değil. Dolayısıyla "bu problemi çözebiliyor musun?" sorusu eski anlamını yitiriyor, çünkü cevap neredeyse her zaman evet.

Önem kazanan sorular şunlar:

  • Ne yaptın? Problemi nasıl tanımladın, kapsamını nasıl belirledin?
  • Nasıl planladın? İşi parçalara mı ayırdın, modele tek seferde mi verdin? Neden?
  • Ne düşündün? Hangi alternatifleri değerlendirdin, hangisini neden seçtin?
  • Neyi reddettin? Yapay zekânın önerdiği ama senin kabul etmediğin ne oldu, neden?
  • Nasıl doğruladın? Çıkan sonucun doğru olduğundan nasıl emin oldun?

Bence bu listedeki en ayırt edici soru "Neyi reddettin?". Yapay zekânın her önerisini kabul eden biriyle onu yöneten biri arasındaki fark tam olarak burada ortaya çıkıyor. "Hiçbir şeyi reddetmedim, hepsi çalıştı" cevabı, aslında hiçbir şeyi denetlemediğiniz anlamına gelir.

Şirketler bunları merak ediyor ve çok haklılar. Çünkü bu cevaplar, sizinle çalıştıklarında ortaya çıkacak işin nasıl çıkacağına ve ne kadar sağlam olacağına dair en güçlü ipuçlarını veriyor. Kodun kendisi artık sizi pek anlatmıyor; o kodu nasıl ortaya çıkardığınız anlatıyor.

Kısacası iki açıdan da sonuç aynı. Birincisi, iyi bir yazılım geliştirici olma hayali olan bir junior, senior gibi davranmayı öğrenmeli; bu artık çok daha erişilebilir. İkincisi, şirketler de tam olarak bunu arayacak. Junior alacaklar ama "ne kadar senior gibi çalışıyor?" diye bakacaklar 😄 Hatta zamanla junior ve senior kavramları bugünkü anlamlarını yitirebilir, yerlerine yenileri gelebilir. Belki gelmiştir bile.

Düşüncenin Yazılı İzi: CLAUDE.md

Somut bir örnek vermeden yazıyı bitirmek istemem.

Eskiden "nasıl düşündün?" sorusunun cevabı mülakatta havada kalırdı; aklınızda ne varsa sözlü anlatırdınız. Artık bu düşüncenin yazılı bir izi olabilir. Claude Code gibi araçlar, projenin kök klasöründeki CLAUDE.md adlı dosyayı her oturumun başında okur. Bu dosyaya yazdığınız kurallar, modelin o projede nasıl davranacağını belirler.

Bu dosyanın değeri bir şablonu doldurmaktan değil, içine yazdığınız kararlardan gelir. Farkı iki satırla göstereyim:

Sıradan: "Testleri her zaman çalıştır."

Mühendis: "Ödeme modülünde mock kullanma; mock'lu testler geçti ama canlıda yuvarlama hatası çıktı. Bu modülde testler sandbox ortamına gider."

İlki herkesin kopyalayabileceği bir kural. İkincisinin arkasında yaşanmış bir hata, çıkarılmış bir ders ve verilmiş bir karar var. Yani tam olarak mülakatta duyulmak istenen şey. Ya da yazılım geliştirirken deneyimini yapay zeka ajanına da aktarmak.

Aşağıda bu mantıkla yazılmış kısa bir örnek var. Örnekte NodeJS kullandım ama dil önemli değil; önemli olan her kuralın yanında bir "neden" olması.

CLAUDE.md

Proje

Küçük işletmeler için sipariş takip API'si. NodeJS + PostgreSQL.

Komutlar

  • Tüm testler: npm test
  • Tek test: npm test -- orders.test.ts

Benimle nasıl çalışmalısın

  • Kod yazmadan önce planını madde madde yaz ve onayımı bekle.
  • Bir hatayı düzeltmeden önce bana sebebini sor; önce ben tahmin edeyim.
  • Önerdiğin çözümün bir alternatifini ve onu neden seçmediğini de yaz.

Kararlar (ve nedenleri)

  • Para tutarları kuruş cinsinden tam sayı tutulur, float kullanılmaz.
    Neden: Ondalık yuvarlama farkları faturalarda tutarsızlık çıkardı.
  • orders tablosuna doğrudan yazma; her zaman OrderService üzerinden git.
    Neden: Stok düşümü ve loglama orada yapılıyor, atlanırsa veri bozuluyor.
  • Yeni paket eklemeden önce sor.
    Neden: Projeyi küçük tutmak ve güvenlik açığı yüzeyini daraltmak istiyorum.
  • Entity / Model de değişiklik yapman gerektiğinde bunu onayımı almadan asla yapma.

Yapma

  • Testi geçirmek için testi silme veya atlama.
  • .env dosyasını okuma, commit'leme.

Bu tabiki çok basit, sadece konuyu izah edebilmek için. Dikkat ederseniz "Benimle nasıl çalışmalısın" bölümü yalnızca daha iyi kod için değil, sizin öğrenmeniz için de yazılmış: Model önce plan yapıyor, siz onaylıyorsunuz; hatanın sebebini önce siz tahmin ediyorsunuz. "Kararlar" bölümü ise zamanla büyüyen bir mühendislik günlüğüne dönüşüyor. Model aynı hatayı ikinci kez yaptığında, onu engelleyen kuralı nedeniyle birlikte buraya ekleyin.

Birkaç ay sonra bu dosya, "nasıl çalışıyorsun?" sorusuna verebileceğiniz en somut cevap olur. Bir mülakatta bu dosyayı açıp her satırın hikâyesini anlatabiliyorsanız, bir LeetCode çözümünden çok daha fazlasını göstermiş olursunuz.

Son Söz

Zaman içinde LLM'leri daha verimli kullanmak üzerine yazmaya devam edeceğim. Hatta daha ileri gidip yalnızca LLM kullanımını değil, AI Engineering konularını da işlemek istiyorum. Bu bazen bir blog yazısı olur, bazen YouTube kanalımda bir video. Bu hem benim konuları derinlemesine öğrenmeme yardımcı oluyor hem de sizlere bir nebze fayda sağladığımı görmek beni mutlu ediyor.

Sizin şirketinizde mülakatlar değişti mi? Yapay zekâyla çalışırken en son neyi reddettiniz? Düşüncelerinizi yazının altında tartışabiliriz. Görüşmek üzere 😊