← emrevarol.com Materyaller & Kontrol Listesi →
A2SV · University of Rwanda

İçindekiler

En İyi Kodlama Pratikleri ve Etkili Kod İnceleme

A2SV - Ruanda Üniversitesi

Kod yazmak kolaydır

Sürdürülebilir kod yazmak zordur

Bir ekibin güvenebileceği kod yazmak yazılım mühendisliğidir

Bu Dersin Gerçekte Konusu

Sadece söz dizimi değil

Sadece “temiz kod” değil

Sadece GitHub mekanikleri değil

Bu ders mühendislik disiplini hakkındadır

İyi mühendislik hız yaratır. Kötü mühendislik kaos yaratır.

Acı Bir Gerçek

Bir proje nadiren insanların hiç kod yazamamasından dolayı başarısız olur.

Bir proje çoğu zaman kodun şu hale gelmesinden dolayı başarısız olur:

Anlaşılmaz

Test edilemez

İncelenmesi imkansız

Değiştirilmesi zor

Yanlış Öğrenci Zihniyeti

Yaygın tehlikeli düşünceler:

“Çalışıyor, yeterince iyi.”

“Sonra temizleriz.”

“Testler çok fazla zaman alıyor.”

“Küçük değişiklikler için inceleme gerekmez.”

“Ekip arkadaşlarım anlayacaktır.”

Bunun neden tehlikeli olduğu:

Sonra genellikle hiç gelmez

Küçük kötü alışkanlıklar ekip kültürü olur

Ekip kültürü ürün kalitesine dönüşür

Doğru Mühendislik Zihniyeti

Profesyonel bir mühendis şunu sorar:

Başka bir kişi bunu hızlıca anlayabilir mi?

Bu daha sonra güvenle değiştirilebilir mi?

Bu test edilebilir mi?

Bu iyi bir şekilde incelenebilir mi?

Bu ekibi hızlandırır mı yoksa yavaşlatır mı?

Kötü Kodun Maliyeti

Kötü kod şunlara neden olur:

Daha fazla hata

Daha yavaş uyum süreci

Zorlu hata ayıklama

Tekrarlanan iş

Değişikliklerden sonra bozulan özellikler

Kod tabanına dokunma korkusu

İyi Kodun Faydaları

İyi kod şunları sağlar:

Daha hızlı geliştirme

Daha kolay iş birliği

Daha güvenli yeniden düzenleme

Daha iyi incelemeler

Daha fazla güven

Daha tutarlı ürünler

Anahtar Mesaj

“Kodunuz sadece bilgisayar için değildir. Kodunuz ekip arkadaşlarınız, gelecekteki kendiniz ve ürün içindir.”

Programlama ve Yazılım Mühendisliği

Programlama

Kodun çalışmasını sağlamak

Yazılım Mühendisliği

Kodu güvenilir, sürdürülebilir, iş birliğine uygun ve üretime hazır hale getirmek

Bir Betik Çalışabilir. Bir Sistem Hayatta Kalmalıdır.

Bir betik yalnızca şuna ihtiyaç duyabilir:

Doğru mantık

Bir sistem şunlara ihtiyaç duyar:

Açık yapı

Testler

İncelemeler

Sürüm kontrolü

Öngörülebilir dağıtım

Ekip anlayışı

Kod Yazıldığından Çok Okunur

Gerçek:

Bir fonksiyonu bir kez yazarsınız

Ekip arkadaşlarınız onu düzinelerce kez okur

Gelecekteki siz, aylar sonra hiçbir şey hatırlamadan okur

Bu nedenle:

Okunabilirlik isteğe bağlı değildir

Okunabilirlik doğruluğun bir parçasıdır

Kötü Örnek: “Çalışıyor” Yeterli Değildir

def f(x, y, z):
    if x:
        if y > 0:
            return z * 0.2
    return 0

Sorunlar:

f nedir? Ne hesaplıyor?

x, y, z nedir?

0.2 neyi temsil ediyor?

Hiç kimse bunu güvenle inceleyemez, test edemez veya bakımını yapamaz

Daha İyi Örnek: Anlam Görünür Olmalıdır

def calculate_discount(price, has_membership, loyalty_points):
    if not has_membership:
        return 0
    if loyalty_points <= 0:
        return 0
    return price * 0.2

Ne iyileşti:

Fonksiyon adı amacı açıklıyor

Parametreler anlamlı

Mantık bir cümle gibi okunuyor

İnceleyici doğruluğu hemen kontrol edebilir

Mühendislik Standardı

Sadece şunu sormayın: “Çalışıyor mu?”

Ayrıca şunu da sorun:

Okunabilir mi?

Test edilebilir mi?

Değiştirmek güvenli mi?

Bunu bir PR'da onaylar mıydım?

İlke 1: İsimlendirme Bir Tasarım Aracıdır

Kötü isimlendirme kafa karışıklığı yaratır. İyi isimlendirme netlik yaratır.

İsimler şunları ortaya koymalıdır: bir şeyin ne olduğu, ne yaptığı, neden var olduğu.

Kötü İsimlendirme Örneği

def calc(a, b):
    return a * b

Sorunlar:

calc ne hesaplıyor?

a ve b nedir?

Alan, fiyat, herhangi bir şey olabilir - bilinmesi imkansız

İnceleyici doğruluğu doğrulayamaz

Daha İyi İsimlendirme Örneği

def calculate_total_price(unit_price, quantity):
    return unit_price * quantity

Faydalar:

Amaç hemen anlaşılır

Parametreler kendilerini açıklar

İnceleyici doğrulayabilir: “Evet, toplam fiyat = birim fiyat × miktar”

Gelecekteki geliştiriciler bu fonksiyonu yanlış kullanmayacaktır

İyi İsimlendirme Neleri Önler

Tanıdık olmayan kodu okurken kafa karışıklığını azaltır

Fonksiyon davranışı hakkında yanlış varsayımları önler

Parametrelerin yanlış kullanımını önler

Yanlış anlamadan kaynaklanan gelecekteki hataları önler

Bir değişkenin ne olduğunu açıklamak için yorum yazmanız gerekiyorsa, isim muhtemelen yanlıştır.

İlke 2: Bir Fonksiyon Tek Bir Açık Görev Yapmalıdır

Bir fonksiyon çok fazla şey yaptığında, test etmek zorlaşır, yeniden kullanım imkansız hale gelir ve hata ayıklama acı verici olur.

Kötü Örnek: Çok Fazla Sorumluluk

def register_user(user):
    validate_user(user)
    save_user_to_database(user)
    send_welcome_email(user)
    log_activity(user)
    notify_admin(user)

Sorunlar:

Bir fonksiyonda beş sorumluluk

E-posta göndermeden kayıt test edilemez

E-posta başarısız olursa, kullanıcı yine de kaydedilir mi?

Herhangi bir adımı yeniden kullanmak imkansız

Daha İyi Örnek: Sorumlulukları Ayırın

def register_user(user):
    validate_user(user)
    save_user_to_database(user)

def onboard_user(user):
    send_welcome_email(user)
    log_activity(user)

def handle_registration(user):
    register_user(user)
    onboard_user(user)
    notify_admin(user)

Faydalar:

Her fonksiyonun açık, tek bir amacı var

Her biri bağımsız olarak test edilebilir

Hata yönetimi kontrol edilebilir hale gelir

İlke 3: Tekrarlama Bir Hata Fabrikasıdır

Tekrarlanan mantık, kaçırılan düzeltmeler, kod tabanında tutarsızlık ve maliyetli bakım demektir.

Kötü Örnek: Tekrarlanan Mantık

# In checkout.py
final_price = price - price * 0.1

# In invoice.py
final_price = price - price * 0.1

# In report.py
final_price = price - price * 0.1
Bu 7 yerde görünüyorsa ve indirim oranı 0.15'e değişirse, 7'sini de bulup güncellemeniz gerekir. Birini kaçırırsanız? Sessiz bir hatanız olur.

Daha İyi Örnek: Ortak Mantığı Merkezileştirin

def apply_discount(price, discount_rate):
    return price * (1 - discount_rate)

# Everywhere:
final_price = apply_discount(price, 0.1)

Faydalar:

Tek doğru kaynak

Bir kez değiştir, her yerde düzelt

Test etmesi kolay

Bulmak ve denetlemek kolay

İlke 4: Test Edilebilirlik Tasarımı Etkilemelidir

Kodunuzu test etmek zorsa, muhtemelen kötü tasarlanmıştır.

Test edilebilir kod modüler, açık ve net giriş-çıkışlara sahiptir.

Test Edilmesi Zor Kod Örneği

def process_order(order_id):
    order = db.get_order(order_id)         # database call
    user = db.get_user(order.user_id)      # database call
    send_email(user.email, order.summary)  # side effect
    db.mark_processed(order_id)            # database call

Sorunlar:

Gerçek bir veritabanı olmadan test edilemez

Gerçek e-posta göndermeden test edilemez

Tüm yan etkiler sıkı sıkıya bağlı

Daha Test Edilebilir Tasarım

def process_order(order, user, email_sender, db):
    email_sender.send(user.email, order.summary)
    db.mark_processed(order.id)

Faydalar:

Bağımlılıklar enjekte edilir - taklit etmesi kolay

Her bağımlılık bağımsız olarak test edilebilir

Mantık altyapıdan ayrılmış

Fonksiyon imzası tam olarak neye ihtiyacı olduğunu söyler

İlke 5: Sessizce Değil, Açıkça Başarısız Olun

Sessiz başarısızlıklar en tehlikeli hata türüdür.

Bir şeyler ters gittiğinde, bunu yüksek sesli ve açık yapın.

Kötü Hata Yönetimi

def get_user_age(user):
    if user is None:
        return None
    if user.birthday is None:
        return None
    return calculate_age(user.birthday)

Risk:

Çağıran taraf None alır ve nedenini bilmez

Hata gizlenir ve sessizce yayılır

Hata ayıklama bir tahmin oyununa dönüşür

Daha Açık Hata Yönetimi

def get_user_age(user):
    if user is None:
        raise ValueError("User must not be None")
    if user.birthday is None:
        raise ValueError("User birthday is missing")
    return calculate_age(user.birthday)

Faydalar:

Hata hemen görünür

Mesaj tam olarak neyin yanlış olduğunu söyler

Hata erken yakalanır, ileriki aşamalarda değil

İlke 6: Karmaşıklık Pahalıdır

Karmaşık kod zeki değildir. Bakımı, incelemesi ve hata ayıklaması pahalıdır.

Karmaşık Örnek

def get_price(user, product):
    if user.is_member:
        if product.on_sale:
            if user.loyalty_points > 100:
                return product.price * 0.7
            else:
                return product.price * 0.8
        else:
            return product.price * 0.9
    else:
        if product.on_sale:
            return product.price * 0.95
        else:
            return product.price

Derin iç içe geçmiş, takip etmesi zor, hata çıkarması kolay

Daha Basit Örnek

def get_discount_rate(user, product):
    if not user.is_member and not product.on_sale:
        return 0
    if not user.is_member and product.on_sale:
        return 0.05
    if user.is_member and not product.on_sale:
        return 0.1
    if user.loyalty_points > 100:
        return 0.3
    return 0.2

def get_price(user, product):
    return product.price * (1 - get_discount_rate(user, product))

Düz, okunabilir, her durum açık ve test edilebilir

İlke 7: Küçük Değişiklikler Büyük Karmaşık Değişiklikleri Yener

Büyük değişiklikler:

İncelemesi zor

Yüksek hata riski

Birleştirmesi acı verici

Kafa karıştıran git geçmişi

Küçük değişiklikler:

İncelemesi kolay

Düşük risk

Hızlı birleştirme

Açık geçmiş

Mühendislik Kuralı

Tercih edin:

Daha küçük fonksiyonlar

Daha küçük commit'ler

Daha küçük PR'lar

Daha küçük inceleme birimleri

Küçük, odaklanmış değişiklikleri anlamak, incelemek, test etmek ve geri almak daha kolaydır.

Git ve GitHub İş Akışı

İş akışı olmadan ekipler şunları oluşturur:
üzerine yazılan kod, incelenmemiş değişiklikler, bozuk main branch'ler, kafa karışıklığı.

Doğru Temel İş Akışı

main feature branch oluştur kod yaz küçük değişiklikler commit'le PR aç incele iyileştir main'e birleştir
Bu isteğe bağlı değildir. Bu minimum profesyonel iş akışıdır.

Asla Doğrudan Main Üzerinde Çalışmayın

Main her zaman dağıtılabilir olmalıdır

Doğrudan commit'ler incelemeyi atlar

Birleştirme çakışmaları yıkıcı hale gelir

Temiz bir şekilde geri alma yolu yok

Ekip kod tabanına olan güvenini kaybeder

Main bozuksa, herkes engellenir. Onu koruyun.

Bir Branch Neyi Temsil Eder

Kötü branch isimleri:

fix
my-branch
test123
update

Daha iyi branch isimleri:

feature/user-registration
fix/login-redirect-bug
chore/update-dependencies
refactor/split-order-service

Bir branch adı işin amacını tanımlamalıdır

Commit'ler Bir Hikaye Anlatmalıdır

Kötü commit mesajları:

fix
update
wip
asdf
changed stuff

İyi commit mesajları:

fix: redirect to login after session timeout
feat: add email validation to registration
refactor: extract discount logic into helper
test: add edge cases for price calculator
docs: update API authentication section

İyi Bir PR İncelenebilirdir

Küçük ve tek bir şeye odaklanmış

Açık bir başlık ve açıklamaya sahip

Değişikliğin neden yapıldığını açıklar

Uygunsa testleri içerir

İlgisiz değişiklikleri karıştırmaz

İyi bir PR açıklaması şu soruları yanıtlar: Ne değişti? Neden? Nasıl test edilir?

Kötü PR ve İyi PR

Kötü PR:

Başlık: “güncellemeler”

Açıklama yok

47 dosya değişti

Özellik + yeniden düzenleme + stil düzeltmesini karıştırır

Test yok

İyi PR:

Başlık: “feat: kayıta e-posta doğrulaması eklendi”

Açıklama yaklaşımı anlatır

4 dosya değişti

Tek bir özelliğe odaklanmış

Birim testleri içerir

Profesyonel Bir Depo Sadece Kod Değildir

Ciddi bir depo yapı, dokümantasyon, yapılandırma ve standartları içerir - sadece kaynak dosyaları değil.

Örnek Depo Yapısı

project/
├── src/
│   ├── models/
│   ├── services/
│   ├── routes/
│   └── utils/
├── tests/
│   ├── unit/
│   └── integration/
├── .github/
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── README.md
├── requirements.txt
├── Makefile
└── .env.example

README Neden Önemlidir

Bir README yeni bir ekip üyesine şunları söylemelidir:

Projenin ne yaptığı

Nasıl kurulacağı

Nasıl çalıştırılacağı

Testlerin nasıl çalıştırılacağı

Nasıl katkıda bulunulacağı

README'si olmayan bir depo şunu söyleyen bir depodur: “Kendin çöz.”

İyi Bir README Şunları İçerir

Proje adı ve tek satırlık açıklama

Ön koşullar (Python sürümü, bağımlılıklar)

Kurulum adımları

Yerel olarak nasıl çalıştırılacağı

Testlerin nasıl çalıştırılacağı

Gerekli ortam değişkenleri

Proje yapısına genel bakış

Katkıda bulunma kılavuzları

Deponuz Kafa Karıştırıcıysa, Ekibiniz Yavaşlar

Bir ekip arkadaşının proje yapınızı anlamaya harcadığı her dakika, özellik geliştirmediği bir dakikadır.

Depo netliği, ekibinize duyulan saygının bir biçimidir.

Test Kültürü

Yaygın bahaneler:

“Testler için zamanımız yok”

“Benim bilgisayarımda çalışıyor”

“Testler bizi yavaşlatıyor”

Gerçek:

Test yapmamak için zamanınız yok

Her bilgisayarda çalışması gerekiyor

Testler sizi sonradan yavaşlamaktan kurtarır

Testler Size Gerçekte Ne Verir

Kodu değiştirme güveni

Daha hızlı hata ayıklama - testler neyin nerede bozulduğunu gösterir

Beklenen davranışın dokümantasyonu

Yeniden düzenleme için güvenlik ağı

Kodunuzun çalıştığının kanıtı

Testler güçlü ekipleri yavaşlatmaz. Güçlü ekiplerin güvenle hızlı ilerlemesini sağlar.

Çok Basit Bir Örnek

def add(a, b):
    return a + b

Basit fonksiyon. Doğru çalıştığını nasıl bilebiliriz?

Bir test yazarız.

Temel Pytest Örneği

def test_add_returns_sum():
    assert add(2, 3) == 5

Açık, okunabilir, çalıştırması hızlı

add bozulursa, bu test hemen yakalar

Bu testin neyi kontrol ettiğini herkes anlayabilir

İyi Testler Sadece Mutlu Yolu Kontrol Etmez

Başka ne test etmeliyiz?

Negatif sayılar

Sıfır değerleri

Çok büyük sayılar

Tür uyumsuzlukları (uygunsa)

Sınır koşulları

Hata durumları

Mutlu yol, hataların gizlenmediği yerdir. Uç durumlar, hataların yaşadığı yerdir.

Örnek: Daha Faydalı Testler

def test_add_positive_numbers():
    assert add(2, 3) == 5

def test_add_negative_numbers():
    assert add(-1, -2) == -3

def test_add_with_zero():
    assert add(0, 5) == 5
    assert add(5, 0) == 5

def test_add_mixed_signs():
    assert add(-3, 5) == 2

Her testin ne doğruladığını anlatan açık bir adı var

Testsiz Ne Olur

Hatalar üretime ulaşır

Yeniden düzenleme korkutucu hale gelir

Bir değişikliğin bir şeyi bozup bozmadığını kimse bilmez

Manuel test yavaş ve güvenilmezdir

Regresyonlar sürekli geri gelir

Ekip koda olan güvenini kaybeder

Testlerle Ne Olur

Hatalar birleştirmeden önce yakalanır

Yeniden düzenleme güvenli ve hızlıdır

CI regresyonları otomatik olarak yakalar

Yeni ekip üyeleri beklenen davranışı anlar

Dağıtımlar güvenle yapılır

Ekip hızı zamanla artar

CI/CD ve Kalite Kapıları

CI = Sürekli Entegrasyon (Continuous Integration)

Main branch'e ulaşmadan önce her değişikliği otomatik olarak doğrulayın.

CI Neden Önemlidir

CI şunları önler:

Bozuk kodun main'e ulaşması

Test edilmemiş kodun birleştirilmesi

Stil tutarsızlıkları

“Benim bilgisayarımda çalışıyor” sorunları

CI şunları sağlar:

Otomatik kalite kontrolleri

Her PR'da hızlı geri bildirim

Tutarlı standartlar

Ekip güveni

Yaygın CI Kontrolleri

Tüm testleri çalıştır (birim + entegrasyon)

Kod biçimlendirmesini kontrol et (black, prettier, vb.)

Linter çalıştır (pylint, eslint, flake8)

Tür ek açıklamalarını kontrol et (mypy)

Test kapsamını ölç

Güvenlik taraması

Derleme kontrolü (proje derleniyor/oluşuyor mu?)

GitHub Actions Example

name: Python Checks
on:
  pull_request:
  push:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install -r requirements.txt
      - run: pytest

Bu Ne Sağlar

Her PR otomatik olarak testleri çalıştırır

Bozuk PR'lar birleştirilemez (branch korumasıyla)

Ekibin testleri çalıştırmayı hatırlamasına gerek yok

Geri bildirim hızlı ve tutarlı

CI kapıdaki bir nöbetçi gibidir. Bozuk kodun main branch'inize girmesine izin vermez.

Kapsam Kontrolleri

Test kapsamı, kodunuzun ne kadarının testler tarafından çalıştırıldığını ölçer.

Yüksek kapsam, hata olmadığı anlamına gelmez

Düşük kapsam, büyük test edilmemiş alanlar demektir

Kapsam bir kılavuzdur, garanti değildir

Dikkat: %100 kapsam peşinde koşmayın. Önemsiz getter ve setter'lar yerine önemli mantığı ve uç durumları test etmeye odaklanın.

Pratik Kalite Kuralı

Çoğu proje için iyi hedefler:

Temel olarak %70-85 test kapsamı

Tüm kritik iş mantığı test edilmiş

Temel fonksiyonlar için tüm uç durumlar test edilmiş

Birleştirmeden önce CI geçmeli (istisna yok)

Her PR'da linter ve biçimlendirici kontrolleri

Kalite kapıları bürokrasi değildir. Onlar mühendislik altyapısıdır.

Etkili Kod İnceleme

Kod inceleme şu değildir:

Bir formalite

Bir mühür basma işlemi

Bir güç gösterisi

Kod inceleme şudur:

Bir kalite sohbeti

Bir öğrenme fırsatı

Bir ekip savunma mekanizması

Ekipler Neden Kod İnceler

Hataları üretime ulaşmadan yakalayın

Ekip genelinde bilgi paylaşın

Tutarlı kod kalitesini koruyun

Kod tabanının sahipliğini yayın

Birbirinden öğrenin ve öğretin

Ekip güveni oluşturun

Zayıf İnceleme ve Etkili İnceleme

Zayıf inceleme:

Diff'e 30 saniye göz at

“Onayla”ya tıkla

Yorum bırakma

Kodu çalıştırma

Etkili inceleme:

Değişen her satırı oku

Mantığı ve uç durumları kontrol et

Açıklayıcı sorular sor

Saygılı bir şekilde iyileştirmeler öner

Testlerin var olduğunu doğrula

Etkili Kod İnceleme Nasıl Yapılır

Şunları kontrol edin:

Doğruluk - mantık yapması gerekeni yapıyor mu?

Okunabilirlik - sormadan anlayabiliyor musunuz?

İsimlendirme - isimler açık ve doğru mu?

Tekrarlama - gereksiz yere tekrarlanan bir şey var mı?

Hata yönetimi - uç durumlar kapsanmış mı?

Testler - yeni mantık için testler var mı?

Kapsam - PR odaklanmış mı kalıyor?

İnceleyici Zihniyeti

İnceleme sırasında şu soruları yanıtlayın:

Bu kodun ne yaptığını anlıyor muyum?

Bunun bakımını yapmaktan rahat olur muydum?

Sessizce bozulabilecek bir şey var mı?

Eksik testler var mı?

PR açıklaması doğru mu?

Yeni bir ekip üyesi bunu anlar mı?

Kötü İnceleme Yorumu

“Bu yanlış.”

Neden zayıf:

Neyin yanlış olduğunu açıklamaz

Neden yanlış olduğunu açıklamaz

Bir iyileştirme önermez

Geri bildirim değil, saldırı gibi hissedilir

Yazarın zamanını boşa harcar

Daha İyi İnceleme Yorumu

“Bu fonksiyon kullanıcı bulunamadığında None döndürüyor, ancak 42. satırdaki çağıran taraf None kontrolü yapmıyor. Bu, çalışma zamanında bir AttributeError'a neden olabilir. Burada bir istisna fırlatabilir veya çağıran tarafa bir None kontrolü ekleyebilir miyiz?”

Neden işe yarar:

Sorunu açıklar

Etkisini gösterir

Somut bir düzeltme önerir

Yazara bir iş birlikçi olarak davranır

Sürtünmeyi Azaltmak İçin Sorular Kullanın

Komutlar yerine meraklı sorular kullanın:

“Bu girdi negatif olursa ne olur?”

“Bunu erken dönüşle basitleştirebilir miyiz?”

“Bunun için mevcut yardımcı fonksiyonu kullanmamamızın bir nedeni var mı?”

“Bunu ayrı bir fonksiyona çıkarmak daha açık olmaz mı?”

Sorular diyaloğu davet eder. Komutlar direnç yaratır.

Güçlü İnceleme Odağı Örnekleri

Güçlü bir inceleyici şunları fark eder:

Açıklamasız sihirli sayılar

Uç durumlar için eksik hata yönetimi

Çıkarılması gereken tekrarlanan mantık

Birden fazla iş yapan fonksiyonlar

Tutarsız isimlendirme kuralları

Eksik veya yetersiz testler

Güvenlik endişeleri (sabit kodlanmış gizli anahtarlar, SQL injection, vb.)

Bu Kodu Bir İnceleyici Gibi Okuyun

def calc(items):
    t = 0
    for i in items:
        if i["type"] == "book":
            t += i["price"] * 0.9
        else:
            t += i["price"]
    return t

İnceleyici olarak sorun:

calc ne hesaplıyor?

0.9 ne anlama geliyor? Neden özellikle kitaplar?

Bir öğenin “type” veya “price” anahtarı yoksa ne olur?

Testler nerede?

Daha İyi İncelenebilir Sürüm

BOOK_DISCOUNT_RATE = 0.1

def get_item_price(item):
    price = item["price"]
    if item["type"] == "book":
        return price * (1 - BOOK_DISCOUNT_RATE)
    return price

def calculate_cart_total(items):
    return sum(get_item_price(item) for item in items)

İyileştirmeler:

Sihirli sayı adlandırılmış sabitle değiştirildi

Fiyatlandırma mantığı kendi fonksiyonuna çıkarıldı

Her fonksiyon bağımsız olarak test edilebilir

İnceleyicilerin Yapmaması Gerekenler

Bunun için linter varken stil detaylarını eleştirmek

Yazarın kodunu kendi tarzlarında yeniden yazmak

Okumadan onaylamak

Kişisel tercih için (doğruluk değil) PR'ı engellemek

Küçümseyici veya umursamaz olmak

İletişim olmadan incelemeleri günlerce geciktirmek

Kodu Anlamıyorsanız, Onaylamayın

“Kodu anlamıyorsanız, onaylamayın.”

Onay sorumluluk demektir.
O kod bir hataya neden olursa, hesap verebilirliği paylaşırsınız.

İncelemeyi Profesyonelce Nasıl Karşılarsınız

Yapmayın:

Geri bildirimi kişisel almayın

Dinlemeden tartışmayın

Önerileri hemen reddetmeyin

Saldırıya uğramış hissetmeyin

Yapın:

Her yorumu dikkatlice okuyun

Gerekirse açıklama isteyin

İnceleyicilere zaman ayırdıkları için teşekkür edin

Mantığınızı saygılı bir şekilde açıklayın

Değişiklikleri hızla yapın

İncelemeye Kötü Yanıt

“Gayet iyi çalışıyor. Test ettim.”
“Bu sadece bir stil tercihi.”
“Bunun için zamanımız yok.”
“Onaylayabilir misin?”

Bu yanıtlar iş birliğini kapatır ve güveni aşındırır

İncelemeye İyi Yanıt

“İyi yakalama - o uç durumu kaçırmışım. Son commit'te düzelttim.”
“Haklısınız. Bu yaklaşımı [neden] tercih ettim. Hala daha iyi olduğunu düşünüyorsanız değiştirmekten memnuniyet duyarım.”
“Detaylı inceleme için teşekkürler. Burada yeni bir şey öğrendim.”

Bu yanıtlar güven oluşturur ve ekibi güçlendirir

İnceleme Kazanmak İçin Değildir

Amaç şu değildir:

Haklı olduğunuzu kanıtlamak

Egonuzu savunmak

Hızlı onay almak

Amaç şudur:

Daha iyi kod göndermek

Birbirinden öğrenmek

Güvenilir bir ürün oluşturmak

Mühendis olarak büyümek

GenAI'dan Nasıl Faydalanılır

AI mühendisleri daha hızlı yapabilir, ama aynı zamanda daha özensiz de yapabilir.

AI'yı mühendislik muhakemesinin yerini alan bir araç olarak değil, bir asistan olarak kullanın.

GenAI'nın İyi Kullanımları

Zaman kazanmak için şablon kod üretin

Mevcut fonksiyonlar için test senaryoları taslağı oluşturun

Tanıdık olmayan kodu veya kütüphaneleri açıklayın

Alternatif yaklaşımlar önerin

Dokümantasyon yazmaya yardımcı olun

Hata mesajlarını analiz ederek hata ayıklamaya yardımcı olun

PR göndermeden önce kodu ön incelemeye tabi tutun

GenAI'nın Zayıf Kullanımı

AI'yı anlamadan kullanmak:

“Bana bir giriş sistemi yaz” → kopyala-yapıştır → gönder
“Bu hatayı düzelt” → öneriyi körü körüne uygula
“Tüm testlerimi üret” → asla okuma

Kodu açıklayamıyorsanız, ona sahip değilsiniz

Anlamadığınız hatalara sahip AI üretimi kod, hiç kod olmamasından daha kötüdür

GenAI'nın Güçlü Kullanımı

Daha iyi istemler, daha iyi sonuçlar:

“Bu fonksiyonu kaçırmış olabileceğim uç durumlar için incele”
“Bu fonksiyon için negatif sayılar ve boş girdi dahil pytest testleri üret”
“Bunu iç içe koşullar yerine erken dönüşler kullanacak şekilde yeniden düzenle”

Belirli, odaklanmış istemler faydalı, incelenebilir çıktı üretir

Test Üretimi İçin İyi İstem Örneği

# Prompt to AI:
"Write pytest tests for this function.
Include: happy path, negative input, zero, empty list, and type error.
Use descriptive test names."

# Function:
def calculate_average(numbers):
    if not numbers:
        raise ValueError("Cannot average empty list")
    return sum(numbers) / len(numbers)

İstem neyin test edileceği ve testlerin nasıl adlandırılacağı konusunda spesifik

Üretilen testleri hala inceleyip ayarlarsınız

Kod İnceleme İçin İyi İstem Örneği

# Prompt to AI:
"Review this function as a senior engineer.
Check for:
- edge cases
- naming clarity
- error handling
- testability
- any potential bugs

Be specific and suggest improvements."

Ekip arkadaşınız incelemeden önce AI'yı “ilk inceleyici” olarak kullanın

Bu, bariz sorunları yakalar ve inceleyicinin zamanından tasarruf sağlar

VS Code ve Editör Entegrasyonları

Geliştirme için faydalı AI araçları:

GitHub Copilot - satır içi kod önerileri

Claude Code (CLI) - terminal tabanlı AI asistanı

Cursor - AI tabanlı kod editörü

Codeium - ücretsiz AI otomatik tamamlama

İyi kullanım alanları:

Tekrarlayan kalıpları otomatik tamamlama

Docstring'ler üretme

Karmaşık kod bölümlerini açıklama

Test yapısı önerme

AI Üretimi Kod İçin Kural

AI üretimi herhangi bir kodu birleştirmeden önce şunları yapmalısınız:

Anlayın - her satırı okuyun

Açıklayın - ne yaptığını ve neden yaptığını tarif edebilmelisiniz

Test edin - kendi testlerinizle doğrulayın

Onaylayın - PR'ınızda siz yazmışsınız gibi davranın

Commit'te adınız varsa, kod sizindir. Kimin veya neyin ürettiği önemli değildir.

Canlı Demo: Kötü Bir Pull Request İnceleme

Birlikte gerçek bir PR'ı inceleyeceğiz ve şunları belirleyeceğiz:

• Kötü isimlendirme
• Eksik hata yönetimi
• Tekrarlanan mantık
• Eksik testler
• Belirsiz commit mesajları
• Kapsam genişlemesi

Canlı Demo Hedefi

Bu demodan sonra şunları yapabilmelisiniz:

PR diff'ini eleştirel okumak

En az 5 tür sorun belirlemek

Yapıcı inceleme yorumları yazmak

Belirli iyileştirmeler önermek

Engelleyici sorunlar ile öneriler arasında ayrım yapmak

Kod inceleme bir beceridir. Her beceri gibi, bilinçli pratikle gelişir.

Ödev: Bir Pull Request'i Mühendis Gibi İnceleyin

Görev:

GitHub'da açık kaynaklı bir PR bulun (veya eğitmen tarafından sağlananı kullanın)

En az 5 öz içerikli yorumla bir inceleme yazın

Her yorum belirli bir sorunu tanımlamalı ve bir iyileştirme önermelidir

Teslim gereksinimleri:

İncelediğiniz PR'ın bağlantısı

İnceleme yorumlarınız (ekran görüntüsü veya markdown)

Kısa bir yansıtma: başka birinin kodunu incelemekten ne öğrendiniz?

Son Mesaj

“Harika mühendisler sadece kodun çalışmasını sağlamaz. Kodu anlaşılır, test edilebilir, incelenebilir ve güvenilir yaparlar.”

Teşekkürler

“Bugün temizlemek için çok meşgul olduğunuz kod, yarın ekibinize sahip olan sorun haline gelir.”

Emre Varol · A2SV · Ruanda Üniversitesi

emrevarol.com