<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-08-04T10:13:29+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Arayüzler: Nesne Yönelimli Tasarımın Görünmez Sözleşmeleri</title><link href="https://sonsuzus.github.io/posts/arayuzler-nesne-yonelimli-tasarimin-gorunmez-sozlesmeleri/" rel="alternate" type="text/html" title="Arayüzler: Nesne Yönelimli Tasarımın Görünmez Sözleşmeleri" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/arayuzler-nesne-yonelimli-tasarimin-gorunmez-sozlesmeleri</id><content type="html" xml:base="https://sonsuzus.github.io/posts/arayuzler-nesne-yonelimli-tasarimin-gorunmez-sozlesmeleri/"><![CDATA[<p>Bir orkestrada her müzisyen farklı bir enstrüman çalabilir; ancak şefin verdiği işaretlerin ne anlama geldiğini hepsi bilir. Nesne yönelimli programlamadaki <strong>arayüzler (interfaces)</strong> de benzer biçimde çalışır. Bir sınıfın iç dünyasını yönetmez, fakat dışarıya hangi özellikleri ve davranışları sunması gerektiğini açıkça bildirir. Böylece birbirinden farklı nesneler, ortak bir sözleşmeye uyarak aynı sistem içinde güvenle çalışabilir.
``</p>

<h2 id="arayüz-tam-olarak-nedir">Arayüz tam olarak nedir?</h2>

<p>Arayüz, bir nesnenin <strong>ne yapacağını</strong> tanımlayan; bunu <strong>nasıl yapacağını</strong> ise uygulayıcı sınıfa bırakan soyut bir şablondur. Örneğin <code class="language-plaintext highlighter-rouge">OdemeYontemi</code> isimli bir arayüz, her ödeme yönteminin <code class="language-plaintext highlighter-rouge">ode()</code> metoduna sahip olmasını zorunlu kılabilir. Kredi kartı, banka havalesi veya dijital cüzdan bu işlemi farklı şekilde gerçekleştirir; önemli olan, dışarıdan bakıldığında hepsinin aynı davranışı sunmasıdır.</p>

<p>Bu düşünceyi küme mantığıyla ifade edebiliriz. Bir $I$ arayüzünün zorunlu tuttuğu davranış kümesi $B_I$, bir $C$ sınıfının sunduğu davranış kümesi ise $B_C$ olsun. Sınıfın sözleşmeyi sağlaması için şu koşul geçerlidir:</p>

\[B_I \subseteq B_C\]

<p>Yani sınıf, arayüzde belirtilen bütün üyeleri içermelidir; isterse bunlara yeni özellikler ve metotlar da ekleyebilir.</p>

<h2 id="sınıf-soyut-sınıf-ve-arayüz-farkı">Sınıf, soyut sınıf ve arayüz farkı</h2>

<p>Bu üç yapı sıkça aynı çekmeceye atılsa da görevleri farklıdır:</p>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>Temel amacı</th>
      <th>Uygulama kodu</th>
      <th>Çoklu kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sınıf</td>
      <td>Veri ve davranışı gerçekleştirmek</td>
      <td>Tamdır</td>
      <td>Genellikle tek kalıtım</td>
    </tr>
    <tr>
      <td>Soyut sınıf</td>
      <td>Ortak temel ve kısmi uygulama sunmak</td>
      <td>Kısmi olabilir</td>
      <td>Dile bağlıdır</td>
    </tr>
    <tr>
      <td>Arayüz</td>
      <td>Uyulacak sözleşmeyi tanımlamak</td>
      <td>Genellikle davranış bildirir</td>
      <td>Bir sınıf birden fazlasını uygulayabilir</td>
    </tr>
  </tbody>
</table>

<p>Arayüzü bir <strong>priz standardı</strong>, sınıfı ise o prize bağlanan cihaz gibi düşünebiliriz. Televizyon ile kahve makinesinin iç mekanizması aynı değildir; fakat ikisi de uygun fişe sahipse elektrik altyapısıyla iletişim kurabilir.</p>

<h2 id="typescript-ile-sözleşme-oluşturmak">TypeScript ile sözleşme oluşturmak</h2>

<p>Aşağıdaki örnekte bütün bildirim servislerinin uyması gereken yapı tanımlanıyor:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">BildirimServisi</span> <span class="p">{</span>
  <span class="nl">servisAdi</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nf">gonder</span><span class="p">(</span><span class="nx">alici</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">mesaj</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nx">boolean</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">EpostaServisi</span> <span class="k">implements</span> <span class="nx">BildirimServisi</span> <span class="p">{</span>
  <span class="nx">servisAdi</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">E-posta</span><span class="dl">"</span><span class="p">;</span>

  <span class="nf">gonder</span><span class="p">(</span><span class="nx">alici</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">mesaj</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">alici</span><span class="p">}</span><span class="s2"> adresine gönderildi: </span><span class="p">${</span><span class="nx">mesaj</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
    <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">kullaniciyiBilgilendir</span><span class="p">(</span>
  <span class="nx">servis</span><span class="p">:</span> <span class="nx">BildirimServisi</span><span class="p">,</span>
  <span class="nx">alici</span><span class="p">:</span> <span class="kr">string</span>
<span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
  <span class="nx">servis</span><span class="p">.</span><span class="nf">gonder</span><span class="p">(</span><span class="nx">alici</span><span class="p">,</span> <span class="dl">"</span><span class="s2">Siparişiniz hazır!</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">kullaniciyiBilgilendir</code> fonksiyonu doğrudan <code class="language-plaintext highlighter-rouge">EpostaServisi</code> sınıfına bağımlı değildir. Yalnızca <code class="language-plaintext highlighter-rouge">BildirimServisi</code> sözleşmesini tanır. Daha sonra SMS veya mobil bildirim sınıfı eklendiğinde fonksiyonun değiştirilmesi gerekmez. Kodun yeni davranışlara açılırken mevcut yapıda değişiklik istememesi, <strong>Açık/Kapalı Prensibi</strong> ile uyumludur.</p>

<h2 id="gevşek-bağlılık-neden-değerlidir">Gevşek bağlılık neden değerlidir?</h2>

<p>Bir sınıf başka bir somut sınıfa doğrudan bağımlıysa değişiklikler zincirleme etki yaratabilir. Arayüz kullanıldığında bağımlılık, uygulama ayrıntısına değil soyut sözleşmeye yönelir. Bu yaklaşım <strong>Bağımlılıkların Tersine Çevrilmesi Prensibi</strong>nin temelidir.</p>

<table>
  <thead>
    <tr>
      <th>Doğrudan bağımlılık</th>
      <th>Arayüz tabanlı bağımlılık</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Bileşenler sıkı bağlıdır</td>
      <td>Bileşenler değiştirilebilir</td>
    </tr>
    <tr>
      <td>Testlerde gerçek servis gerekebilir</td>
      <td>Sahte servis kolayca yazılabilir</td>
    </tr>
    <tr>
      <td>Değişiklik riski yüksektir</td>
      <td>Etki alanı daha sınırlıdır</td>
    </tr>
    <tr>
      <td>Yeniden kullanım zordur</td>
      <td>Esneklik daha yüksektir</td>
    </tr>
  </tbody>
</table>

<p>Örneğin test sırasında gerçekten e-posta göndermek yerine aynı arayüzü uygulayan bir <code class="language-plaintext highlighter-rouge">SahteBildirimServisi</code> kullanılabilir. Böylece test hızlı, ücretsiz ve öngörülebilir olur.</p>

<h2 id="her-yere-arayüz-eklenmeli-mi">Her yere arayüz eklenmeli mi?</h2>

<p>Hayır. Tek uygulaması bulunan ve değişme ihtimali düşük, küçük yapılara sırf “kurumsal görünsün” diye arayüz eklemek gereksiz karmaşıklık yaratabilir. Arayüzler özellikle birden fazla uygulama beklendiğinde, dış sistemler soyutlandığında veya bileşenlerin bağımsız test edilmesi gerektiğinde değerlidir.</p>

<p>Kısacası arayüzler yalnızca metot listeleri değildir; ekipler ve bileşenler arasında kurulmuş teknik anlaşmalardır. İyi tasarlanmış bir arayüz, nesnenin iç ayrıntılarını gizlerken beklentileri netleştirir. Kod değiştikçe sözleşme sabit kalabiliyorsa sistem daha esnek, test edilebilir ve sürdürülebilir hâle gelir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="arayüzler" /><category term="nesne yönelimli programlama" /><category term="yazılım tasarımı" /><summary type="html"><![CDATA[Bir orkestrada her müzisyen farklı bir enstrüman çalabilir; ancak şefin verdiği işaretlerin ne anlama geldiğini hepsi bilir. Nesne yönelimli programlamadaki arayüzler (interfaces) de benzer biçimde çalışır. Bir sınıfın iç dünyasını yönetmez, fakat dışarıya hangi özellikleri ve davranışları sunması gerektiğini açıkça bildirir. Böylece birbirinden farklı nesneler, ortak bir sözleşmeye uyarak aynı sistem içinde güvenle çalışabilir.]]></summary></entry><entry><title type="html">Diziler ve Demetler: Bellekte Düzen, Hız ve Esneklik</title><link href="https://sonsuzus.github.io/posts/diziler-ve-demetler-bellekte-duzen-hiz-ve-esneklik/" rel="alternate" type="text/html" title="Diziler ve Demetler: Bellekte Düzen, Hız ve Esneklik" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/diziler-ve-demetler-bellekte-duzen-hiz-ve-esneklik</id><content type="html" xml:base="https://sonsuzus.github.io/posts/diziler-ve-demetler-bellekte-duzen-hiz-ve-esneklik/"><![CDATA[<p>Bir alışveriş sepetinde aynı türden ürünleri yan yana dizmek kolaydır; fakat ürünün adı, fiyatı ve stok durumu gibi farklı bilgileri tek paket hâlinde taşımak başka bir düzen gerektirir. Programlamada dinamik diziler aynı türdeki elemanları büyüyebilen bir koleksiyonda saklarken demetler, farklı türdeki belirli sayıda değeri sıralı bir bütün olarak tutar. Aralarındaki asıl fark yalnızca sözdiziminde değil, belleğin nasıl ayrıldığı ve veriye nasıl erişildiğindedir.</p>

<p>``</p>

<h2 id="dinamik-dizilerin-bellek-düzeni">Dinamik dizilerin bellek düzeni</h2>

<p>Klasik bir dizi, aynı veri türündeki elemanları çoğunlukla bellekte <strong>ardışık</strong> olarak saklar. İlk elemanın adresi $A$, her elemanın boyutu $s$ ise $i$ indisli elemanın adresi yaklaşık olarak şöyle hesaplanır:</p>

\[Adres(i) = A + i \times s\]

<p>Bu basit formül sayesinde indisle erişim $O(1)$ zaman karmaşıklığına sahiptir. İşlemci önbelleği de komşu elemanları birlikte getirebildiği için diziler üzerinde sırayla dolaşmak oldukça hızlıdır.</p>

<p>Dinamik diziler ise çalışma sırasında büyüyebilir. C++ dilindeki <code class="language-plaintext highlighter-rouge">std::vector</code>, bunun yaygın bir örneğidir. Vector genellikle üç bilgiyi yönetir: veri bloğunun adresi, mevcut eleman sayısı ve ayrılmış kapasite.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">puanlar</span><span class="p">;</span>
    <span class="n">puanlar</span><span class="p">.</span><span class="n">reserve</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span> <span class="c1">// Dört elemanlık belleği önceden ayırır.</span>

    <span class="n">puanlar</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="mi">70</span><span class="p">);</span>
    <span class="n">puanlar</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="mi">85</span><span class="p">);</span>
    <span class="n">puanlar</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="mi">92</span><span class="p">);</span>

    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Boyut: "</span> <span class="o">&lt;&lt;</span> <span class="n">puanlar</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Kapasite: "</span> <span class="o">&lt;&lt;</span> <span class="n">puanlar</span><span class="p">.</span><span class="n">capacity</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">size</code>, gerçekten bulunan eleman sayısını; <code class="language-plaintext highlighter-rouge">capacity</code> ise yeniden bellek ayırmadan saklanabilecek eleman sayısını gösterir. Kapasite dolduğunda daha büyük bir blok ayrılır, eski elemanlar yeni alana taşınır ve eski blok serbest bırakılır. Bu işlem tek seferde $O(n)$ maliyetlidir. Ancak kapasite geometrik olarak büyütüldüğünden <code class="language-plaintext highlighter-rouge">push_back</code> işleminin amortize maliyeti $O(1)$ kabul edilir.</p>

<h2 id="demetler-neden-farklıdır">Demetler neden farklıdır?</h2>

<p>Demet, farklı türdeki değerleri belirli bir sırada ve sabit sayıda tutar. Örneğin bir öğrenciyi kimlik numarası, isim ve not ile temsil edebiliriz:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;tuple&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="kt">double</span><span class="o">&gt;</span> <span class="n">ogrenci</span><span class="p">{</span><span class="mi">42</span><span class="p">,</span> <span class="s">"Ada"</span><span class="p">,</span> <span class="mf">91.5</span><span class="p">};</span>

    <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">numara</span><span class="p">,</span> <span class="n">ad</span><span class="p">,</span> <span class="n">notu</span><span class="p">]</span> <span class="o">=</span> <span class="n">ogrenci</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">numara</span> <span class="o">&lt;&lt;</span> <span class="s">" - "</span> <span class="o">&lt;&lt;</span> <span class="n">ad</span> <span class="o">&lt;&lt;</span> <span class="s">" - "</span> <span class="o">&lt;&lt;</span> <span class="n">notu</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki elemanların türleri derleme zamanında bellidir ve sonradan dördüncü bir alan eklenemez. Yapısal bağlama, indis yerine anlamlı değişken adlarıyla çalışmayı kolaylaştırır. Bununla birlikte <code class="language-plaintext highlighter-rouge">std::tuple</code> elemanlarının fiziksel sıralaması ve yerleşimi uygulamaya bağlı olabilir; ardışık bir ham dizi gibi yorumlanmamalıdır.</p>

<p>Farklı türlerin hizalama gereksinimleri nedeniyle demet içinde <strong>padding</strong> adı verilen kullanılmayan baytlar oluşabilir. Yaklaşık toplam boyut şu düşünceyle modellenebilir:</p>

\[Toplam\ Boyut \geq \sum_{k=1}^{n} sizeof(T_k)\]

<p>Eşitsizliğin nedeni hizalama boşlukları ve kütüphane uygulamasının tercih ettiği yerleşimdir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Dinamik dizi</th>
      <th>Demet</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Eleman türleri</td>
      <td>Genellikle aynı</td>
      <td>Farklı olabilir</td>
    </tr>
    <tr>
      <td>Eleman sayısı</td>
      <td>Çalışma zamanında değişebilir</td>
      <td>Derleme zamanında sabittir</td>
    </tr>
    <tr>
      <td>Bellek</td>
      <td>Ayrı, ardışık veri bloğu</td>
      <td>Nesnenin kendi yerleşimi</td>
    </tr>
    <tr>
      <td>Erişim</td>
      <td>Çalışma zamanı indisi</td>
      <td>Derleme zamanı konumu</td>
    </tr>
    <tr>
      <td>Büyüme maliyeti</td>
      <td>Yeniden ayırma ve taşıma</td>
      <td>Büyüme desteklenmez</td>
    </tr>
    <tr>
      <td>Kullanım amacı</td>
      <td>Liste ve koleksiyon</td>
      <td>Sabit yapılı kayıt veya dönüş değeri</td>
    </tr>
  </tbody>
</table>

<h2 id="hangisini-seçmeliyiz">Hangisini seçmeliyiz?</h2>

<p>Aynı türden, sayısı değişebilen verileri işleyecekseniz dinamik dizi doğal seçimdir. Sensör ölçümleri, puan listeleri ve oyun nesneleri buna örnektir. Bir fonksiyondan farklı türde birkaç değeri birlikte döndürmek veya küçük, sabit bir kayıt oluşturmak istiyorsanız demet daha uygundur.</p>

<p>Yine de alanların özel anlamları varsa <code class="language-plaintext highlighter-rouge">tuple</code> yerine adlandırılmış bir <code class="language-plaintext highlighter-rouge">struct</code> kullanmak okunabilirliği artırır. Kısacası dizi, büyüyebilen düzenli bir raf; demet ise bölmeleri önceden belirlenmiş bir araç çantasıdır. Doğru seçim, hem bellek davranışını hem de kodun anlaşılabilirliğini doğrudan etkiler.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="arrays" /><category term="tuples" /><category term="bellek yönetimi" /><summary type="html"><![CDATA[Bir alışveriş sepetinde aynı türden ürünleri yan yana dizmek kolaydır; fakat ürünün adı, fiyatı ve stok durumu gibi farklı bilgileri tek paket hâlinde taşımak başka bir düzen gerektirir. Programlamada dinamik diziler aynı türdeki elemanları büyüyebilen bir koleksiyonda saklarken demetler, farklı türdeki belirli sayıda değeri sıralı bir bütün olarak tutar. Aralarındaki asıl fark yalnızca sözdiziminde değil, belleğin nasıl ayrıldığı ve veriye nasıl erişildiğindedir.]]></summary></entry><entry><title type="html">Enum Nedir? Sihirli Değerleri Anlamlı Sabitlere Dönüştürmek</title><link href="https://sonsuzus.github.io/posts/enum-nedir-sihirli-degerleri-anlamli-sabitlere-donusturmek/" rel="alternate" type="text/html" title="Enum Nedir? Sihirli Değerleri Anlamlı Sabitlere Dönüştürmek" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/enum-nedir-sihirli-degerleri-anlamli-sabitlere-donusturmek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/enum-nedir-sihirli-degerleri-anlamli-sabitlere-donusturmek/"><![CDATA[<p>Bir siparişin durumunu <code class="language-plaintext highlighter-rouge">1</code>, kullanıcı rolünü <code class="language-plaintext highlighter-rouge">"A"</code>, haftanın gününü ise <code class="language-plaintext highlighter-rouge">4</code> ile temsil ettiğinizi düşünün. Bu değerler çalışır; fakat kodu aylar sonra okuyan geliştirici için küçük bir bilmeceye dönüşür: “1 hazırlanıyor mu, kargoda mı?” Enum, ilişkili sabitleri anlamlı isimlerden oluşan tek bir tür altında toplayarak bu bilmeceleri ortadan kaldırır.</p>

<p>``</p>

<h2 id="enum-mantığı">Enum mantığı</h2>

<p>Enum, yani <em>enumeration</em> veya numaralandırma, alabileceği değerler önceden belirlenmiş kategorik bir veri türüdür. Bir <code class="language-plaintext highlighter-rouge">SiparisDurumu</code> değişkeni yalnızca <code class="language-plaintext highlighter-rouge">Bekliyor</code>, <code class="language-plaintext highlighter-rouge">Hazirlaniyor</code>, <code class="language-plaintext highlighter-rouge">Kargoda</code> ya da <code class="language-plaintext highlighter-rouge">TeslimEdildi</code> gibi tanımlanmış seçeneklerden birini taşır. Böylece hem insan hem de derleyici değişkenin anlamını bilir.</p>

<p>Matematiksel açıdan enum değerlerini sonlu bir küme gibi düşünebiliriz:</p>

\[S = \{Bekliyor, Hazirlaniyor, Kargoda, TeslimEdildi\}\]

<p>Bir sipariş durumu değişkeni için $d \in S$ koşulu geçerlidir. <code class="language-plaintext highlighter-rouge">Patates</code> gibi kümede bulunmayan bir değerin atanması tür güvenli bir dilde derleme hatası üretir. Enum’un temel avantajı tam olarak budur: Geçersiz durumları daha program çalışmadan yakalamak.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Örnek</th>
      <th style="text-align: right">Okunabilirlik</th>
      <th style="text-align: right">Hata riski</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sihirli sayı</td>
      <td><code class="language-plaintext highlighter-rouge">durum == 2</code></td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Yüksek</td>
    </tr>
    <tr>
      <td>Metin</td>
      <td><code class="language-plaintext highlighter-rouge">durum == "Kargoda"</code></td>
      <td style="text-align: right">Orta</td>
      <td style="text-align: right">Yazım hatasına açık</td>
    </tr>
    <tr>
      <td>Enum</td>
      <td><code class="language-plaintext highlighter-rouge">durum == SiparisDurumu.Kargoda</code></td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Düşük</td>
    </tr>
  </tbody>
</table>

<h2 id="temel-kullanım">Temel kullanım</h2>

<p>C# ile bir sipariş durumunu şöyle modelleyebiliriz:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">enum</span> <span class="n">SiparisDurumu</span>
<span class="p">{</span>
    <span class="n">Bekliyor</span> <span class="p">=</span> <span class="m">1</span><span class="p">,</span>
    <span class="n">Hazirlaniyor</span> <span class="p">=</span> <span class="m">2</span><span class="p">,</span>
    <span class="n">Kargoda</span> <span class="p">=</span> <span class="m">3</span><span class="p">,</span>
    <span class="n">TeslimEdildi</span> <span class="p">=</span> <span class="m">4</span><span class="p">,</span>
    <span class="n">IptalEdildi</span> <span class="p">=</span> <span class="m">5</span>
<span class="p">}</span>

<span class="n">SiparisDurumu</span> <span class="n">durum</span> <span class="p">=</span> <span class="n">SiparisDurumu</span><span class="p">.</span><span class="n">Kargoda</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="n">durum</span> <span class="p">==</span> <span class="n">SiparisDurumu</span><span class="p">.</span><span class="n">Kargoda</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Siparişiniz yola çıktı!"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki sayısal karşılıklar depolama, veritabanı uyumluluğu veya dış sistemlerle iletişim için kullanılabilir. Ancak uygulama kodunda sayı yerine isim tercih edilir. <code class="language-plaintext highlighter-rouge">3</code> tek başına sessiz ve gizemliyken <code class="language-plaintext highlighter-rouge">SiparisDurumu.Kargoda</code> adeta megafonla ne olduğunu söyler.</p>

<p>Enum değerleri <code class="language-plaintext highlighter-rouge">switch</code> ifadeleriyle de oldukça uyumludur:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span> <span class="nf">MesajOlustur</span><span class="p">(</span><span class="n">SiparisDurumu</span> <span class="n">durum</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">durum</span> <span class="k">switch</span>
    <span class="p">{</span>
        <span class="n">SiparisDurumu</span><span class="p">.</span><span class="n">Bekliyor</span> <span class="p">=&gt;</span> <span class="s">"Sipariş onay bekliyor."</span><span class="p">,</span>
        <span class="n">SiparisDurumu</span><span class="p">.</span><span class="n">Hazirlaniyor</span> <span class="p">=&gt;</span> <span class="s">"Mutfakta hareket var!"</span><span class="p">,</span>
        <span class="n">SiparisDurumu</span><span class="p">.</span><span class="n">Kargoda</span> <span class="p">=&gt;</span> <span class="s">"Paket yolda."</span><span class="p">,</span>
        <span class="n">SiparisDurumu</span><span class="p">.</span><span class="n">TeslimEdildi</span> <span class="p">=&gt;</span> <span class="s">"Afiyet olsun!"</span><span class="p">,</span>
        <span class="n">SiparisDurumu</span><span class="p">.</span><span class="n">IptalEdildi</span> <span class="p">=&gt;</span> <span class="s">"Sipariş iptal edildi."</span><span class="p">,</span>
        <span class="n">_</span> <span class="p">=&gt;</span> <span class="s">"Bilinmeyen durum."</span>
    <span class="p">};</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu fonksiyon, her kategoriyi açıkça ele alır ve durum ile kullanıcı mesajı arasındaki ilişkiyi merkezi bir yerde tutar.</p>

<h2 id="bayrak-enumları">Bayrak enum’ları</h2>

<p>Bazı kategorilerde değişken aynı anda birden fazla seçeneği taşımalıdır. Dosya izinleri bunun klasik örneğidir. İkili sistemde her seçeneğe $2^n$ biçiminde bir değer verirsek seçenekleri bit düzeyinde birleştirebiliriz:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Flags</span><span class="p">]</span>
<span class="k">public</span> <span class="k">enum</span> <span class="n">DosyaIzni</span>
<span class="p">{</span>
    <span class="n">Yok</span> <span class="p">=</span> <span class="m">0</span><span class="p">,</span>
    <span class="n">Oku</span> <span class="p">=</span> <span class="m">1</span><span class="p">,</span>      <span class="c1">// 2^0</span>
    <span class="n">Yaz</span> <span class="p">=</span> <span class="m">2</span><span class="p">,</span>      <span class="c1">// 2^1</span>
    <span class="n">Calistir</span> <span class="p">=</span> <span class="m">4</span>  <span class="c1">// 2^2</span>
<span class="p">}</span>

<span class="n">DosyaIzni</span> <span class="n">izin</span> <span class="p">=</span> <span class="n">DosyaIzni</span><span class="p">.</span><span class="n">Oku</span> <span class="p">|</span> <span class="n">DosyaIzni</span><span class="p">.</span><span class="n">Yaz</span><span class="p">;</span>
<span class="kt">bool</span> <span class="n">yazabilir</span> <span class="p">=</span> <span class="n">izin</span><span class="p">.</span><span class="nf">HasFlag</span><span class="p">(</span><span class="n">DosyaIzni</span><span class="p">.</span><span class="n">Yaz</span><span class="p">);</span>
</code></pre></div></div>

<p>Burada birleşik değer $1 + 2 = 3$ olur; fakat kod hâlâ anlamlı isimlerle çalışır. Normal enum tek seçim, bayrak enum’u ise kontrollü çoklu seçim için uygundur.</p>

<table>
  <thead>
    <tr>
      <th>Enum türü</th>
      <th>Kullanım alanı</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Standart enum</td>
      <td>Birbirini dışlayan durumlar</td>
      <td>Sipariş durumu</td>
    </tr>
    <tr>
      <td>Bayrak enum’u</td>
      <td>Birleşebilen seçenekler</td>
      <td>Dosya izinleri</td>
    </tr>
  </tbody>
</table>

<h2 id="ne-zaman-kullanılmamalı">Ne zaman kullanılmamalı?</h2>

<p>Seçenekler çalışma sırasında veritabanından ekleniyor, sık sık değişiyor veya kullanıcı tarafından yönetiliyorsa enum fazla katı kalabilir. Böyle durumlarda tablo, yapılandırma dosyası ya da sınıf tabanlı bir model daha uygundur. Ayrıca enum üyelerini silmek veya sayısal değerlerini değiştirmek, kayıtlı eski verilerle uyumsuzluk yaratabilir.</p>

<p>Özetle enum; sınırlı, kararlı ve anlamlı kategorileri modellemek için küçük ama etkili bir araçtır. Sihirli değerleri kovar, otomatik tamamlama desteği sunar, geçersiz atamaları azaltır ve kodu kendi kendini açıklayan bir belgeye dönüştürür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="enum" /><category term="veri yapıları" /><category term="temiz kod" /><summary type="html"><![CDATA[Bir siparişin durumunu 1, kullanıcı rolünü "A", haftanın gününü ise 4 ile temsil ettiğinizi düşünün. Bu değerler çalışır; fakat kodu aylar sonra okuyan geliştirici için küçük bir bilmeceye dönüşür: “1 hazırlanıyor mu, kargoda mı?” Enum, ilişkili sabitleri anlamlı isimlerden oluşan tek bir tür altında toplayarak bu bilmeceleri ortadan kaldırır.]]></summary></entry><entry><title type="html">Fonksiyonlarda Tip Belirtimiyle Öngörülebilir ve Güvenli Kod</title><link href="https://sonsuzus.github.io/posts/fonksiyonlarda-tip-belirtimiyle-ongorulebilir-ve-guvenli-kod/" rel="alternate" type="text/html" title="Fonksiyonlarda Tip Belirtimiyle Öngörülebilir ve Güvenli Kod" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/fonksiyonlarda-tip-belirtimiyle-ongorulebilir-ve-guvenli-kod</id><content type="html" xml:base="https://sonsuzus.github.io/posts/fonksiyonlarda-tip-belirtimiyle-ongorulebilir-ve-guvenli-kod/"><![CDATA[<p>Bir fonksiyonun yalnızca ne yaptığını değil, hangi verileri kabul edip hangi türde sonuç ürettiğini bilmek, yazılım geliştirmeyi tahmin oyunundan çıkarır. Parametre ve dönüş tipi belirtimleri; modüller arasındaki sözleşmeyi görünür kılar, hataları erkenden yakalar ve kod tamamlama araçlarını daha kullanışlı hâle getirir. Kısacası tipler, fonksiyonların kapısındaki “Giriş şartları ve çıkış garantisi” tabelasıdır.</p>

<p>``</p>

<h2 id="fonksiyon-sözleşmesi-nedir">Fonksiyon sözleşmesi nedir?</h2>

<p>Bir fonksiyonu matematiksel olarak $f: A \rightarrow B$ biçiminde düşünebiliriz. Burada $A$, fonksiyonun kabul ettiği değerler kümesini; $B$ ise üretebileceği sonuçlar kümesini temsil eder. Örneğin iki tam sayıyı toplayan bir fonksiyon şu sözleşmeye sahiptir:</p>

\[topla: \mathbb{Z} \times \mathbb{Z} \rightarrow \mathbb{Z}\]

<p>Bu ifade, iki tam sayı verildiğinde sonucun da tam sayı olacağını söyler. Programlama dillerindeki tip belirtimleri aynı fikri kaynak koda taşır. Böylece fonksiyonun davranışını anlamak için gövdesindeki her satırı okumak gerekmez.</p>

<p>TypeScript ile basit bir örnek:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">topla</span><span class="p">(</span><span class="nx">a</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">b</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">sonuc</span> <span class="o">=</span> <span class="nf">topla</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">8</span><span class="p">);</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">a: number</code> ve <code class="language-plaintext highlighter-rouge">b: number</code> parametre sınırlarını, son <code class="language-plaintext highlighter-rouge">: number</code> ise dönüş garantisini belirtir. <code class="language-plaintext highlighter-rouge">topla("12", 8)</code> çağrısı çalışma aşamasına ulaşmadan hata verir. Böylece JavaScript’in sürprizli birleştirme davranışı yerine öngörülebilir toplama işlemi elde edilir.</p>

<h2 id="tipli-ve-tipsiz-yaklaşım">Tipli ve tipsiz yaklaşım</h2>

<p>Tip belirtimi yalnızca sözdizimsel bir süs değildir. Özellikle birçok modülün ve geliştiricinin bulunduğu projelerde iletişim aracına dönüşür.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Belirtimsiz fonksiyon</th>
      <th>Tipleri belirtilmiş fonksiyon</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Hata zamanı</td>
      <td>Genellikle çalışma zamanı</td>
      <td>Çoğunlukla derleme veya analiz zamanı</td>
    </tr>
    <tr>
      <td>Editör desteği</td>
      <td>Sınırlı tahmin</td>
      <td>Güçlü tamamlama ve uyarılar</td>
    </tr>
    <tr>
      <td>Yeniden düzenleme</td>
      <td>Daha riskli</td>
      <td>Daha kontrollü</td>
    </tr>
    <tr>
      <td>Dokümantasyon</td>
      <td>Gövdeyi okumak gerekebilir</td>
      <td>İmza önemli bilgi sağlar</td>
    </tr>
    <tr>
      <td>Esneklik</td>
      <td>Yüksek fakat belirsiz</td>
      <td>Sınırları tanımlı</td>
    </tr>
  </tbody>
</table>

<p>Dinamik dillerde de aynı avantajlardan yararlanılabilir. Python tip ipuçları çalışma zamanında zorunlu doğrulama yapmasa da <code class="language-plaintext highlighter-rouge">mypy</code> ve benzeri araçlar tarafından denetlenebilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">indirimli_fiyat</span><span class="p">(</span><span class="n">fiyat</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">oran</span><span class="p">:</span> <span class="nb">float</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
    <span class="sh">"""</span><span class="s">Fiyata belirtilen oranda indirim uygular.</span><span class="sh">"""</span>
    <span class="k">return</span> <span class="n">fiyat</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">oran</span><span class="p">)</span>

<span class="n">sonuc</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="nf">indirimli_fiyat</span><span class="p">(</span><span class="mf">250.0</span><span class="p">,</span> <span class="mf">0.20</span><span class="p">)</span>
</code></pre></div></div>

<p>Hesaplama $y = x(1-r)$ formülünü uygular. İmza sayesinde <code class="language-plaintext highlighter-rouge">fiyat</code> ve <code class="language-plaintext highlighter-rouge">oran</code> değerlerinin ondalıklı sayı, sonucun da <code class="language-plaintext highlighter-rouge">float</code> olması beklendiği hemen anlaşılır.</p>

<h2 id="daha-kesin-modeller-kurmak">Daha kesin modeller kurmak</h2>

<p>Her şeyi <code class="language-plaintext highlighter-rouge">string</code>, <code class="language-plaintext highlighter-rouge">number</code> veya <code class="language-plaintext highlighter-rouge">object</code> olarak işaretlemek yeterli değildir. Alan modelini temsil eden özel tipler, geçersiz durumların oluşturulmasını zorlaştırır.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Kullanici</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">id</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
  <span class="nl">ad</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">aktif</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">function</span> <span class="nf">gorunenAd</span><span class="p">(</span><span class="nx">kullanici</span><span class="p">:</span> <span class="nx">Kullanici</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">kullanici</span><span class="p">.</span><span class="nx">aktif</span>
    <span class="p">?</span> <span class="nx">kullanici</span><span class="p">.</span><span class="nx">ad</span>
    <span class="p">:</span> <span class="s2">`</span><span class="p">${</span><span class="nx">kullanici</span><span class="p">.</span><span class="nx">ad</span><span class="p">}</span><span class="s2"> (pasif)`</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu fonksiyon rastgele bir nesne değil, gerekli alanları taşıyan bir <code class="language-plaintext highlighter-rouge">Kullanici</code> ister. Dönüş değerinin daima metin olduğu da garanti edilir. Başka bir modül fonksiyonu kullanırken iç uygulamaya değil bu sözleşmeye bağımlı olur.</p>

<h2 id="aşırı-katılığa-dikkat">Aşırı katılığa dikkat</h2>

<p>Tip güvenliği, her fonksiyonu gereksiz ölçüde daraltmak anlamına gelmez. Aynı mantık farklı türlerle çalışıyorsa generic tipler kullanılabilir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">ilkEleman</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">liste</span><span class="p">:</span> <span class="nx">T</span><span class="p">[]):</span> <span class="nx">T</span> <span class="o">|</span> <span class="kc">undefined</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">T</code>, esnekliği korurken giriş ve çıkış arasındaki ilişkiyi kaybetmez. Sayı listesi sayı, metin listesi metin döndürür. Boş liste ihtimali ise <code class="language-plaintext highlighter-rouge">undefined</code> ile açıkça modellenir.</p>

<p>Sonuç olarak iyi tip belirtimi, “Bu fonksiyon muhtemelen ne döndürür?” sorusunu ortadan kaldırır. Küçük projelerde okunabilirlik, büyük projelerde modüler güvenlik sağlar. En iyi yaklaşım; anlamlı alan tipleri oluşturmak, belirsiz <code class="language-plaintext highlighter-rouge">any</code> kullanımını azaltmak ve hata ihtimallerini dönüş tipinde açıkça ifade etmektir. Tipler kelepçe değil, kodun korkuluklarıdır: hareketi engellemez, uçurumdan düşmeyi önler.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="tip güvenliği" /><category term="fonksiyonlar" /><category term="modüler programlama" /><summary type="html"><![CDATA[Bir fonksiyonun yalnızca ne yaptığını değil, hangi verileri kabul edip hangi türde sonuç ürettiğini bilmek, yazılım geliştirmeyi tahmin oyunundan çıkarır. Parametre ve dönüş tipi belirtimleri; modüller arasındaki sözleşmeyi görünür kılar, hataları erkenden yakalar ve kod tamamlama araçlarını daha kullanışlı hâle getirir. Kısacası tipler, fonksiyonların kapısındaki “Giriş şartları ve çıkış garantisi” tabelasıdır.]]></summary></entry><entry><title type="html">Git Tarihçesinde Zaman Yolculuğu: Log, Reset ve Revert</title><link href="https://sonsuzus.github.io/posts/git-tarihcesinde-zaman-yolculugu-log-reset-ve-revert/" rel="alternate" type="text/html" title="Git Tarihçesinde Zaman Yolculuğu: Log, Reset ve Revert" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/git-tarihcesinde-zaman-yolculugu-log-reset-ve-revert</id><content type="html" xml:base="https://sonsuzus.github.io/posts/git-tarihcesinde-zaman-yolculugu-log-reset-ve-revert/"><![CDATA[<p>Bir Git deposunun geçmişi, projenin nasıl geliştiğini anlatan dijital bir seyir defteridir. Her commit; yapılan değişiklikleri, değişikliği yapan kişiyi ve önceki duruma giden bağlantıyı saklar. Yanlış bir commit oluşturduğumuzda paniğe kapılmak yerine bu kayıtları okuyabilir, ardından <code class="language-plaintext highlighter-rouge">reset</code> veya <code class="language-plaintext highlighter-rouge">revert</code> ile güvenli bir zaman yolculuğuna çıkabiliriz.</p>

<p>``</p>

<h2 id="git-geçmişinin-teorik-yapısı">Git geçmişinin teorik yapısı</h2>

<p>Git commit’leri yalnızca sıralı kayıtlar değildir. Her commit, kendisinden önce gelen commit’in kimliğini taşıyan bir düğümdür. Basitleştirilmiş bir geçmiş şöyle gösterilebilir:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A &lt;- B &lt;- C &lt;- D
               ^
              HEAD
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">HEAD</code>, üzerinde çalıştığımız dalın güncel commit’ini işaret eder. Bir commit kimliği; içerik, yazar, zaman ve üst commit bilgileri kullanılarak üretilen bir özettir. Kavramsal olarak bunu şöyle düşünebiliriz:</p>

\[CommitID = Hash(içerik + yazar + zaman + parent)\]

<p>Bu yapı sayesinde geçmişteki bir commit değiştirilirse onu izleyen kimlikler de değişir. Bu nedenle yayımlanmış geçmişi yeniden yazmak ekip çalışmalarında risklidir.</p>

<h2 id="geçmişi-git-log-ile-okumak">Geçmişi <code class="language-plaintext highlighter-rouge">git log</code> ile okumak</h2>

<p>İlk inceleme aracımız <code class="language-plaintext highlighter-rouge">git log</code> komutudur:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git log
</code></pre></div></div>

<p>Bu komut commit kimliklerini, yazarları, tarihleri ve mesajları gösterir. Daha okunabilir bir görünüm için şu sürüm oldukça kullanışlıdır:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git log <span class="nt">--oneline</span> <span class="nt">--graph</span> <span class="nt">--decorate</span> <span class="nt">--all</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">--oneline</code> kayıtları kısaltır, <code class="language-plaintext highlighter-rouge">--graph</code> dallanmaları görselleştirir, <code class="language-plaintext highlighter-rouge">--decorate</code> dal ve etiket adlarını ekler. Belirli bir dosyanın geçmişini incelemek için ise şunu kullanabiliriz:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git log <span class="nt">--oneline</span> <span class="nt">--</span> src/app.js
</code></pre></div></div>

<p>Commit’in hangi değişiklikleri yaptığını görmek için <code class="language-plaintext highlighter-rouge">git show &lt;commit-id&gt;</code> kullanılabilir. Böylece geri alma kararı vermeden önce “Suçlu gerçekten bu commit mi?” sorusunu yanıtlarız.</p>

<h2 id="reset-mi-revert-mü">Reset mi, revert mü?</h2>

<p>İki komut da geri dönüş sağlar fakat yöntemleri farklıdır:</p>

<table>
  <thead>
    <tr>
      <th>Komut</th>
      <th style="text-align: right">Geçmişi yeniden yazar mı?</th>
      <th style="text-align: right">Yeni commit üretir mi?</th>
      <th>Uygun kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">reset --soft</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Hayır</td>
      <td>Commit’i silip değişiklikleri staged tutmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">reset --mixed</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Hayır</td>
      <td>Değişiklikleri çalışma alanında bırakmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">reset --hard</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Hayır</td>
      <td>Yerel değişiklikleri tamamen atmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">revert</code></td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">Evet</td>
      <td>Paylaşılmış commit’i güvenle geri almak</td>
    </tr>
  </tbody>
</table>

<h3 id="reset-ile-işaretçiyi-taşımak">Reset ile işaretçiyi taşımak</h3>

<p>Son commit mesajı veya içeriği yanlışsa ve henüz uzak depoya gönderilmediyse şu komut kullanılabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git reset <span class="nt">--soft</span> HEAD~1
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">HEAD~1</code>, güncel commit’in bir önceki atasını ifade eder. Commit kaldırılır ancak değişiklikler staging alanında kalır; böylece düzenleyip yeniden commit oluşturabiliriz.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git reset <span class="nt">--hard</span> HEAD~1
</code></pre></div></div>

<p>Bu sürüm hem commit’i hem de dosya değişikliklerini siler. Kaydedilmemiş çalışmalar açısından oldukça tehlikelidir. Kısacası <code class="language-plaintext highlighter-rouge">--hard</code>, Git dünyasının “Emin misin?” diye iki kez sormamız gereken kırmızı düğmesidir.</p>

<h2 id="revert-ile-güvenli-geri-alma">Revert ile güvenli geri alma</h2>

<p>Hatalı commit uzak depoya gönderildiyse geçmişi değiştirmek yerine ters değişiklik oluşturan yeni bir commit eklemek daha güvenlidir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git revert a1b2c3d
</code></pre></div></div>

<p>Geçmiş başlangıçta $A \rightarrow B \rightarrow C$ ise ve <code class="language-plaintext highlighter-rouge">C</code> geri alınırsa sonuç $A \rightarrow B \rightarrow C \rightarrow C^{-1}$ olur. Yani <code class="language-plaintext highlighter-rouge">C</code> kaybolmaz; etkisini tersine çeviren kayıt eklenir. Bu yaklaşım denetlenebilirliği korur ve ekip arkadaşlarının geçmişiyle çatışmaz.</p>

<h2 id="yanlış-reset-yaptıysak-ne-olacak">Yanlış reset yaptıysak ne olacak?</h2>

<p>Git çoğu zaman kaçış kapısını açık bırakır. <code class="language-plaintext highlighter-rouge">reflog</code>, <code class="language-plaintext highlighter-rouge">HEAD</code> işaretçisinin önceki konumlarını gösterir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git reflog
git reset <span class="nt">--hard</span> HEAD@<span class="o">{</span>1<span class="o">}</span>
</code></pre></div></div>

<p>İkinci komut, uygun kayıt seçildiğinde bizi reset öncesindeki konuma döndürebilir. Yine de reflog kalıcı bir yedek değildir.</p>

<p>Pratik kural basittir: Önce <code class="language-plaintext highlighter-rouge">log</code> ve <code class="language-plaintext highlighter-rouge">show</code> ile incele, paylaşılmamış geçmişte dikkatli biçimde <code class="language-plaintext highlighter-rouge">reset</code>, paylaşılmış geçmişte ise çoğunlukla <code class="language-plaintext highlighter-rouge">revert</code> kullan. Komutu çalıştırmadan önce <code class="language-plaintext highlighter-rouge">git status</code> kontrolü yapmak da zaman makinesine emniyet kemeri takmak gibidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Git" /><category term="Versiyon Kontrolü" /><category term="Hata Yönetimi" /><summary type="html"><![CDATA[Bir Git deposunun geçmişi, projenin nasıl geliştiğini anlatan dijital bir seyir defteridir. Her commit; yapılan değişiklikleri, değişikliği yapan kişiyi ve önceki duruma giden bağlantıyı saklar. Yanlış bir commit oluşturduğumuzda paniğe kapılmak yerine bu kayıtları okuyabilir, ardından reset veya revert ile güvenli bir zaman yolculuğuna çıkabiliriz.]]></summary></entry><entry><title type="html">Jenerikler (Generics): Tek Kodla Birçok Türü Güvenle Yönetmek</title><link href="https://sonsuzus.github.io/posts/jenerikler-generics-tek-kodla-bircok-turu-guvenle-yonetmek/" rel="alternate" type="text/html" title="Jenerikler (Generics): Tek Kodla Birçok Türü Güvenle Yönetmek" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/jenerikler-generics-tek-kodla-bircok-turu-guvenle-yonetmek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/jenerikler-generics-tek-kodla-bircok-turu-guvenle-yonetmek/"><![CDATA[<p>Bir fonksiyonu <code class="language-plaintext highlighter-rouge">int</code> için yazıp ardından <code class="language-plaintext highlighter-rouge">string</code>, <code class="language-plaintext highlighter-rouge">double</code> ve kendi sınıflarımız için kopyalamak, yazılım dünyasının pek de eğlenceli olmayan tekrarlarından biridir. Jenerikler (generics), algoritmayı veri tipinden ayırarak aynı kodun farklı türlerle güvenli biçimde çalışmasını sağlar. C++ şablonlarını andıran bu yaklaşım, özellikle C#, Java ve TypeScript gibi dillerde yeniden kullanılabilir yapıların temelini oluşturur.</p>

<p>``</p>

<h2 id="temel-fikir-türü-şimdi-değil-kullanırken-belirle">Temel fikir: Türü şimdi değil, kullanırken belirle</h2>

<p>Normal bir fonksiyon parametrelerinin türünü önceden bilir. Jenerik fonksiyon ise gerçek türün yerine <code class="language-plaintext highlighter-rouge">T</code> gibi bir <strong>tür parametresi</strong> kullanır. Buradaki <code class="language-plaintext highlighter-rouge">T</code>, “her şey serbest” anlamına gelmez; derleyicinin çağrı sırasında belirleyeceği bir tür değişkenidir.</p>

<p>Matematiksel olarak normal bir fonksiyonu $f: int → int$ biçiminde düşünürsek, jenerik karşılığı $f_T: T → T$ olur. Başka bir ifadeyle algoritma sabit kalırken tür değişebilir:</p>

\[T \in \{int, string, Customer, Product, \ldots\}\]

<p>Derleyici <code class="language-plaintext highlighter-rouge">T</code> yerine kullanılacak gerçek tipi izlediği için yanlış tür atamaları çalışma zamanına bırakılmaz. Böylece hem tekrar azalır hem de tip güvenliği korunur.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th style="text-align: right">Yeniden kullanım</th>
      <th style="text-align: right">Tip güvenliği</th>
      <th style="text-align: right">Dönüşüm ihtiyacı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Her tür için ayrı kod</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Yok</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">object</code> kullanmak</td>
      <td style="text-align: right">Orta</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Genellikle var</td>
    </tr>
    <tr>
      <td>Jenerik kullanmak</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Genellikle yok</td>
    </tr>
  </tbody>
</table>

<h2 id="jenerik-fonksiyon-örneği">Jenerik fonksiyon örneği</h2>

<p>Aşağıdaki C# fonksiyonu, verilen iki değerin yerini türlerinden bağımsız olarak değiştirir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="k">void</span> <span class="n">YerDegistir</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="k">ref</span> <span class="n">T</span> <span class="n">sol</span><span class="p">,</span> <span class="k">ref</span> <span class="n">T</span> <span class="n">sag</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">T</span> <span class="n">gecici</span> <span class="p">=</span> <span class="n">sol</span><span class="p">;</span>
    <span class="n">sol</span> <span class="p">=</span> <span class="n">sag</span><span class="p">;</span>
    <span class="n">sag</span> <span class="p">=</span> <span class="n">gecici</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="n">x</span> <span class="p">=</span> <span class="m">10</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">y</span> <span class="p">=</span> <span class="m">20</span><span class="p">;</span>
<span class="nf">YerDegistir</span><span class="p">(</span><span class="k">ref</span> <span class="n">x</span><span class="p">,</span> <span class="k">ref</span> <span class="n">y</span><span class="p">);</span>

<span class="kt">string</span> <span class="n">ilk</span> <span class="p">=</span> <span class="s">"Ada"</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">ikinci</span> <span class="p">=</span> <span class="s">"Linus"</span><span class="p">;</span>
<span class="nf">YerDegistir</span><span class="p">(</span><span class="k">ref</span> <span class="n">ilk</span><span class="p">,</span> <span class="k">ref</span> <span class="n">ikinci</span><span class="p">);</span>
</code></pre></div></div>

<p>Fonksiyon iki kez çağrılır: ilkinde <code class="language-plaintext highlighter-rouge">T</code>, <code class="language-plaintext highlighter-rouge">int</code>; ikincisinde <code class="language-plaintext highlighter-rouge">string</code> olur. Aynı algoritma kullanılırken derleyici iki değerin de uyumlu türde olmasını denetler. Örneğin bir <code class="language-plaintext highlighter-rouge">int</code> ile <code class="language-plaintext highlighter-rouge">string</code> değerini yanlışlıkla değiştirmeye çalışmak derleme hatası üretir. Hata erkenden yakalanır; gece yarısı gelen sürpriz hata bildirimi başka güne kalır.</p>

<h2 id="jenerik-sınıflar-ve-kısıtlamalar">Jenerik sınıflar ve kısıtlamalar</h2>

<p>Jenerikler yalnızca fonksiyonlarda değil, sınıflarda ve arayüzlerde de kullanılabilir. Aşağıdaki depo, yalnızca kimliği bulunan sınıfları kabul eder:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">interface</span> <span class="nc">IEntity</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">Id</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>

<span class="k">class</span> <span class="nc">Depo</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="k">where</span> <span class="n">T</span> <span class="p">:</span> <span class="n">IEntity</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="k">readonly</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">kayitlar</span> <span class="p">=</span> <span class="k">new</span><span class="p">();</span>

    <span class="k">public</span> <span class="k">void</span> <span class="nf">Ekle</span><span class="p">(</span><span class="n">T</span> <span class="n">kayit</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="n">kayitlar</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="n">kayit</span><span class="p">);</span>

    <span class="k">public</span> <span class="n">T</span><span class="p">?</span> <span class="nf">Bul</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">kayitlar</span><span class="p">.</span><span class="nf">FirstOrDefault</span><span class="p">(</span><span class="n">x</span> <span class="p">=&gt;</span> <span class="n">x</span><span class="p">.</span><span class="n">Id</span> <span class="p">==</span> <span class="n">id</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">where T : IEntity</code> ifadesi bir <strong>jenerik kısıtlamadır</strong>. Bu sayede derleyici, <code class="language-plaintext highlighter-rouge">T</code> nesnelerinde <code class="language-plaintext highlighter-rouge">Id</code> özelliğinin bulunduğunu bilir. Kısıtlama olmasaydı <code class="language-plaintext highlighter-rouge">x.Id</code> kullanımının güvenli olduğuna karar veremezdi.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>C++ Template</th>
      <th>C# Generic</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tür kontrolü</td>
      <td>Şablon oluşturulurken</td>
      <td>Derleme ve çalışma zamanı tür sistemiyle</td>
    </tr>
    <tr>
      <td>Kısıtlama yaklaşımı</td>
      <td>Concepts / ifadeler</td>
      <td><code class="language-plaintext highlighter-rouge">where</code> kısıtları</td>
    </tr>
    <tr>
      <td>İlkel amaç</td>
      <td>Genel algoritmalar</td>
      <td>Güvenli ve yeniden kullanılabilir yapılar</td>
    </tr>
  </tbody>
</table>

<h2 id="neden-object-yeterli-değil">Neden <code class="language-plaintext highlighter-rouge">object</code> yeterli değil?</h2>

<p>Her değeri <code class="language-plaintext highlighter-rouge">object</code> olarak saklamak ilk bakışta kolay görünür. Ancak geri alırken tür dönüşümü gerekir ve yanlış dönüşüm çalışma zamanında patlayabilir. Değer tiplerinde kutulama ve kutudan çıkarma maliyeti de oluşabilir. Jenerikler, tür bilgisini koruyarak bu riskleri ve gereksiz dönüşümleri azaltır.</p>

<p>Yine de her yere <code class="language-plaintext highlighter-rouge">&lt;T&gt;</code> serpiştirmek iyi tasarım değildir. Algoritma gerçekten türden bağımsızsa jenerik kullanmak mantıklıdır. Türlere göre tamamen farklı davranışlar gerekiyorsa arayüz, kalıtım veya strateji deseni daha anlaşılır olabilir.</p>

<p>Özetle jenerikler, “bir kez yaz, birçok türle güvenle kullan” ilkesini hayata geçirir. Daha az kopya kod, daha erken hata tespiti ve daha temiz API’ler sağlar. Doğru kısıtlamalarla birleştiğinde <code class="language-plaintext highlighter-rouge">T</code>, belirsiz bir harf olmaktan çıkıp güçlü bir tasarım aracına dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="generics" /><category term="csharp" /><category term="tip-güvenliği" /><summary type="html"><![CDATA[Bir fonksiyonu int için yazıp ardından string, double ve kendi sınıflarımız için kopyalamak, yazılım dünyasının pek de eğlenceli olmayan tekrarlarından biridir. Jenerikler (generics), algoritmayı veri tipinden ayırarak aynı kodun farklı türlerle güvenli biçimde çalışmasını sağlar. C++ şablonlarını andıran bu yaklaşım, özellikle C#, Java ve TypeScript gibi dillerde yeniden kullanılabilir yapıların temelini oluşturur.]]></summary></entry><entry><title type="html">Pull Request ve Code Review: Kodun Ana Projeye Güvenli Yolculuğu</title><link href="https://sonsuzus.github.io/posts/pull-request-ve-code-review-kodun-ana-projeye-guvenli-yolculugu/" rel="alternate" type="text/html" title="Pull Request ve Code Review: Kodun Ana Projeye Güvenli Yolculuğu" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/pull-request-ve-code-review-kodun-ana-projeye-guvenli-yolculugu</id><content type="html" xml:base="https://sonsuzus.github.io/posts/pull-request-ve-code-review-kodun-ana-projeye-guvenli-yolculugu/"><![CDATA[<p>Bir özellik geliştirdiniz, testleri çalıştırdınız ve kodunuz bilgisayarınızda kusursuz görünüyor. Peki bu kod doğrudan ana projeye eklenmeli mi? Genellikle hayır! Pull Request ve Code Review süreçleri, kodun ana dala ulaşmadan önce teknik doğruluk, okunabilirlik, güvenlik ve ekip standartları açısından denetlendiği bir kalite kapısı oluşturur.
``</p>

<h2 id="pull-request-nedir">Pull Request nedir?</h2>

<p><strong>Pull Request (PR)</strong>, bir dalda yapılan değişikliklerin başka bir dala alınması için oluşturulan resmi bir birleştirme talebidir. GitHub bu adı kullanırken GitLab aynı kavrama <strong>Merge Request</strong> der. İsimler değişse de temel fikir aynıdır: “Değişikliklerimi tamamladım; lütfen inceleyin ve uygunsa ana projeye dahil edin.”</p>

<p>PR yalnızca kod farklarını gösteren bir ekran değildir. Değişikliğin amacı, test yöntemi, ilişkili görevler, ekran görüntüleri ve inceleme konuşmaları için ortak bir çalışma alanıdır. Böylece kodun neden değiştirildiği, aylar sonra bile commit geçmişinden daha rahat anlaşılır.</p>

<p>Tipik akış şöyledir:</p>

<ol>
  <li>Ana daldan yeni bir özellik dalı oluşturulur.</li>
  <li>Değişiklikler küçük ve anlamlı commit’lerle kaydedilir.</li>
  <li>Dal uzak depoya gönderilir.</li>
  <li>Bir Pull Request açılır.</li>
  <li>Otomatik testler ve statik analiz araçları çalışır.</li>
  <li>İnceleyiciler yorum yapar veya değişiklik ister.</li>
  <li>Onaylanan kod ana dalla birleştirilir.</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git switch main
git pull
git switch <span class="nt">-c</span> feature/kullanici-arama

<span class="c"># Kod değişikliklerinden sonra</span>
git add <span class="nb">.</span>
git commit <span class="nt">-m</span> <span class="s2">"Kullanıcı arama filtresi eklendi"</span>
git push <span class="nt">-u</span> origin feature/kullanici-arama
</code></pre></div></div>

<p>Bu komutlar güncel <code class="language-plaintext highlighter-rouge">main</code> dalından bağımsız bir geliştirme dalı oluşturur, değişiklikleri kaydeder ve PR açılabilmesi için uzak depoya gönderir.</p>

<h2 id="code-review-neden-gereklidir">Code Review neden gereklidir?</h2>

<p><strong>Code Review</strong>, başka bir geliştiricinin değişiklikleri sistematik biçimde değerlendirmesidir. Amaç hata avına çıkıp yazarı köşeye sıkıştırmak değil; ortak kod tabanını iyileştirmek ve ekip içinde bilgi paylaşmaktır. İnceleme sırasında doğruluk, performans, güvenlik, test kapsamı, isimlendirme ve sürdürülebilirlik değerlendirilir.</p>

<p>Basitleştirilmiş bir kalite modeli şöyle düşünülebilir:</p>

\[Q = w_dD + w_tT + w_oO + w_gG\]

<p>Burada $D$ doğruluğu, $T$ test edilebilirliği, $O$ okunabilirliği ve $G$ güvenliği temsil eder. $w$ katsayıları ise projenin öncelikleridir. Örneğin finans uygulamasında güvenliğin ağırlığı, küçük bir tanıtım sitesine göre daha yüksek olabilir.</p>

<table>
  <thead>
    <tr>
      <th>Kontrol alanı</th>
      <th>İnceleyicinin sorusu</th>
      <th>Olası risk</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Doğruluk</td>
      <td>Kod beklenen işi yapıyor mu?</td>
      <td>Yanlış sonuç</td>
    </tr>
    <tr>
      <td>Okunabilirlik</td>
      <td>İsimler ve akış anlaşılır mı?</td>
      <td>Bakım maliyeti</td>
    </tr>
    <tr>
      <td>Testler</td>
      <td>Kritik senaryolar sınanmış mı?</td>
      <td>Regresyon</td>
    </tr>
    <tr>
      <td>Güvenlik</td>
      <td>Girdi doğrulama yeterli mi?</td>
      <td>Veri sızıntısı</td>
    </tr>
    <tr>
      <td>Performans</td>
      <td>Gereksiz işlem veya sorgu var mı?</td>
      <td>Yavaşlama</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇yi-bir-pr-nasıl-hazırlanır">İyi bir PR nasıl hazırlanır?</h2>

<p>İyi PR küçük, odaklı ve açıklayıcıdır. Aynı talepte hem kullanıcı araması eklemek hem dosya yapısını tamamen değiştirmek, incelemeyi zorlaştırır. Büyük PR’larda bilişsel yük artar; gözden kaçan hata olasılığı da yükselir. Kabaca inceleme etkinliğini</p>

\[E \propto \frac{1}{S}\]

<p>şeklinde düşünebiliriz. Burada $S$, değişiklik boyutudur. Bu kesin bir fizik yasası değildir; küçük değişikliklerin daha dikkatli incelenebildiğini anlatan pratik bir modeldir.</p>

<p>PR açıklamasında şu bilgiler bulunmalıdır:</p>

<ul>
  <li>Değişikliğin amacı ve kapsamı</li>
  <li>İlgili görev veya hata kaydı</li>
  <li>Değişikliğin nasıl test edildiği</li>
  <li>Arayüz değiştiyse ekran görüntüsü</li>
  <li>Bilinen sınırlamalar ve riskler</li>
</ul>

<h2 id="yapıcı-inceleme-kültürü">Yapıcı inceleme kültürü</h2>

<p>Yorumlar kişiye değil koda yöneltilmelidir. “Bunu yanlış yazmışsın” yerine “Bu koşul boş değer geldiğinde hata üretebilir; burada erken dönüş kullanabilir miyiz?” demek daha yapıcıdır. Yazar da her yorumu saldırı olarak görmemeli, ancak gerekçesini açıklayamadığı önerileri körü körüne uygulamamalıdır.</p>

<table>
  <thead>
    <tr>
      <th>Zayıf yaklaşım</th>
      <th>Yapıcı yaklaşım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>“Bu kod kötü.”</td>
      <td>“Bu fonksiyonu bölmek okunabilirliği artırabilir.”</td>
    </tr>
    <tr>
      <td>“Böyle yapılmaz.”</td>
      <td>“Projedeki mevcut servis desenini kullanabilir miyiz?”</td>
    </tr>
    <tr>
      <td>Sessizce onaylamak</td>
      <td>Kritik senaryoları ve testleri doğrulamak</td>
    </tr>
  </tbody>
</table>

<p>Sonuç olarak Pull Request bir izin ekranı, Code Review ise bürokratik bir engel değildir. İkisi birlikte hataları erken yakalayan, ekip bilgisini çoğaltan ve ana dalı güvenilir tutan bir mühendislik pratiğidir. Sağlıklı ekiplerde hedef, kimin haklı olduğunu kanıtlamak değil; kodu birlikte daha doğru, anlaşılır ve sürdürülebilir hâle getirmektir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Git" /><category term="Pull Request" /><category term="Code Review" /><summary type="html"><![CDATA[Bir özellik geliştirdiniz, testleri çalıştırdınız ve kodunuz bilgisayarınızda kusursuz görünüyor. Peki bu kod doğrudan ana projeye eklenmeli mi? Genellikle hayır! Pull Request ve Code Review süreçleri, kodun ana dala ulaşmadan önce teknik doğruluk, okunabilirlik, güvenlik ve ekip standartları açısından denetlendiği bir kalite kapısı oluşturur.]]></summary></entry><entry><title type="html">Sınıflar ve Erişim Belirleyicilerle Güvenli Kapsülleme</title><link href="https://sonsuzus.github.io/posts/siniflar-ve-erisim-belirleyicilerle-guvenli-kapsulleme/" rel="alternate" type="text/html" title="Sınıflar ve Erişim Belirleyicilerle Güvenli Kapsülleme" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/siniflar-ve-erisim-belirleyicilerle-guvenli-kapsulleme</id><content type="html" xml:base="https://sonsuzus.github.io/posts/siniflar-ve-erisim-belirleyicilerle-guvenli-kapsulleme/"><![CDATA[<p>Bir sınıfı yalnızca değişkenleri ve metotları bir araya getiren bir kutu olarak düşünmek eksik kalır. İyi tasarlanmış bir sınıf, kendi verisini koruyan ve dış dünyaya kontrollü bir kullanım alanı sunan küçük bir kale gibidir. <code class="language-plaintext highlighter-rouge">public</code>, <code class="language-plaintext highlighter-rouge">private</code> ve <code class="language-plaintext highlighter-rouge">protected</code> erişim belirleyicileri ise bu kalenin hangi kapılarının herkese, hangilerinin yalnızca içeridekilere açılacağını belirler.
``</p>

<h2 id="kapsülleme-neden-gereklidir">Kapsülleme neden gereklidir?</h2>

<p>Nesne yönelimli programlamanın temel ilkelerinden biri olan <strong>kapsülleme</strong>, bir nesnenin durumunu temsil eden veriler ile bu verileri yöneten davranışların aynı sınıfta toplanmasıdır. Ancak asıl amaç, alanları sınıfın içine taşımaktan daha fazlasıdır: Verinin geçersiz veya tehlikeli biçimde değiştirilmesini önlemek.</p>

<p>Bir sınıfın durumunu $S$, izin verilen geçerli durumlar kümesini ise $V$ ile gösterelim. İyi bir sınıfın hedefi şudur:</p>

\[S \in V\]

<p>Dışarıdaki kod alanları doğrudan değiştirebiliyorsa bu koşul kolayca bozulabilir. Örneğin bir banka hesabının bakiyesi, kontrol yapılmadan negatif bir değere dönüştürülebilir. Kapsülleme sayesinde değişiklikler metotlar üzerinden geçirilir ve sınıf kendi kurallarını korur.</p>

<h2 id="erişim-belirleyiciler-ne-söyler">Erişim belirleyiciler ne söyler?</h2>

<p>Java, C# ve C++ gibi dillerde ayrıntılar değişebilse de temel yaklaşım benzerdir:</p>

<table>
  <thead>
    <tr>
      <th>Belirleyici</th>
      <th style="text-align: right">Aynı sınıf</th>
      <th style="text-align: right">Alt sınıf</th>
      <th style="text-align: right">Dış kod</th>
      <th>Yaygın kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">public</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Evet</td>
      <td>Kullanıcıya sunulan metotlar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">private</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">Hayır</td>
      <td>Alanlar ve iç yardımcı metotlar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">protected</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Genellikle hayır</td>
      <td>Kalıtıma özel genişletme noktaları</td>
    </tr>
  </tbody>
</table>

<p><code class="language-plaintext highlighter-rouge">public</code>, sınıfın dış dünyaya verdiği sözleşmedir. Bu nedenle her alanı veya metodu düşünmeden <code class="language-plaintext highlighter-rouge">public</code> yapmak, evin bütün kapılarını açık bırakmaya benzer. <code class="language-plaintext highlighter-rouge">private</code>, bir üyenin yalnızca tanımlandığı sınıf tarafından kullanılmasını sağlar. <code class="language-plaintext highlighter-rouge">protected</code> ise özellikle kalıtım sırasında alt sınıflara kontrollü erişim vermek için kullanılır.</p>

<h2 id="java-ile-kapsüllenmiş-hesap-örneği">Java ile kapsüllenmiş hesap örneği</h2>

<p>Aşağıdaki sınıf, bakiyeyi dışarıdan doğrudan değiştirmeye izin vermez:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">BankAccount</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">owner</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">balance</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nf">BankAccount</span><span class="o">(</span><span class="nc">String</span> <span class="n">owner</span><span class="o">,</span> <span class="kt">double</span> <span class="n">initialBalance</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">initialBalance</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalArgumentException</span><span class="o">(</span><span class="s">"Başlangıç bakiyesi negatif olamaz."</span><span class="o">);</span>
        <span class="o">}</span>
        <span class="k">this</span><span class="o">.</span><span class="na">owner</span> <span class="o">=</span> <span class="n">owner</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">balance</span> <span class="o">=</span> <span class="n">initialBalance</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">deposit</span><span class="o">(</span><span class="kt">double</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">amount</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalArgumentException</span><span class="o">(</span><span class="s">"Tutar pozitif olmalıdır."</span><span class="o">);</span>
        <span class="o">}</span>
        <span class="n">balance</span> <span class="o">+=</span> <span class="n">amount</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">withdraw</span><span class="o">(</span><span class="kt">double</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">amount</span> <span class="o">&lt;=</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">amount</span> <span class="o">&gt;</span> <span class="n">balance</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
        <span class="o">}</span>
        <span class="n">balance</span> <span class="o">-=</span> <span class="n">amount</span><span class="o">;</span>
        <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">double</span> <span class="nf">getBalance</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">balance</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">balance</code> alanı <code class="language-plaintext highlighter-rouge">private</code> olduğu için aşağıdaki müdahale derleme hatası üretir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">BankAccount</span> <span class="n">account</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BankAccount</span><span class="o">(</span><span class="s">"Ada"</span><span class="o">,</span> <span class="mi">1000</span><span class="o">);</span>
<span class="c1">// account.balance = -5000; // Erişim yasak!</span>
<span class="n">account</span><span class="o">.</span><span class="na">deposit</span><span class="o">(</span><span class="mi">250</span><span class="o">);</span>
<span class="n">account</span><span class="o">.</span><span class="na">withdraw</span><span class="o">(</span><span class="mi">100</span><span class="o">);</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">deposit</code> ve <code class="language-plaintext highlighter-rouge">withdraw</code> metotları birer kontrol noktasıdır. Para yatırıldıktan sonra yeni bakiye matematiksel olarak</p>

\[B_{yeni} = B_{eski} + T, \quad T &gt; 0\]

<p>şeklinde hesaplanır. Böylece nesnenin iş kuralları tek yerde uygulanır.</p>

<h2 id="protected-kullanırken-dikkat">Protected kullanırken dikkat</h2>

<p>Bir alt sınıfın bazı davranışları özelleştirmesi gerekiyorsa <code class="language-plaintext highlighter-rouge">protected</code> yararlı olabilir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">RewardAccount</span> <span class="kd">extends</span> <span class="nc">BankAccount</span> <span class="o">{</span>
    <span class="kd">protected</span> <span class="kt">double</span> <span class="nf">calculateBonus</span><span class="o">(</span><span class="kt">double</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">amount</span> <span class="o">*</span> <span class="mf">0.02</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Ancak alanları doğrudan <code class="language-plaintext highlighter-rouge">protected</code> yapmak, alt sınıfların geçersiz değerler atamasına yol açabilir. Bu yüzden alanları yine <code class="language-plaintext highlighter-rouge">private</code> tutup, gerektiğinde <code class="language-plaintext highlighter-rouge">protected</code> metotlar sağlamak daha güvenlidir. Kalıtım var diye kasanın anahtarını teslim etmek gerekmez!</p>

<h2 id="getter-ve-setter-her-zaman-çözüm-mü">Getter ve setter her zaman çözüm mü?</h2>

<p>Her <code class="language-plaintext highlighter-rouge">private</code> alan için otomatik olarak getter ve setter üretmek gerçek kapsülleme değildir. Kontrolsüz bir <code class="language-plaintext highlighter-rouge">setBalance()</code> metodu, alanı <code class="language-plaintext highlighter-rouge">public</code> yapmakla neredeyse aynı riski taşır. Sınıfın teknik yapısını değil, anlamlı davranışlarını dışarı açmak gerekir. <code class="language-plaintext highlighter-rouge">setBalance(500)</code> yerine <code class="language-plaintext highlighter-rouge">deposit(500)</code> denmesi, işlemin niyetini ve kurallarını açıkça ifade eder.</p>

<p>Özetle alanlarda varsayılan tercihiniz <code class="language-plaintext highlighter-rouge">private</code>, dışarıya sunulan güvenli davranışlarda <code class="language-plaintext highlighter-rouge">public</code>, alt sınıfların kontrollü biçimde kullanacağı genişletme noktalarında ise <code class="language-plaintext highlighter-rouge">protected</code> olmalıdır. Böylece sınıflar yalnızca veri taşımaz; kendi tutarlılığını koruyan güvenilir yazılım bileşenlerine dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="nesne yönelimli programlama" /><category term="sınıflar" /><category term="kapsülleme" /><summary type="html"><![CDATA[Bir sınıfı yalnızca değişkenleri ve metotları bir araya getiren bir kutu olarak düşünmek eksik kalır. İyi tasarlanmış bir sınıf, kendi verisini koruyan ve dış dünyaya kontrollü bir kullanım alanı sunan küçük bir kale gibidir. public, private ve protected erişim belirleyicileri ise bu kalenin hangi kapılarının herkese, hangilerinin yalnızca içeridekilere açılacağını belirler.]]></summary></entry><entry><title type="html">Temel Veri Tipleriyle Güvenli Kodun Temelleri</title><link href="https://sonsuzus.github.io/posts/temel-veri-tipleriyle-guvenli-kodun-temelleri/" rel="alternate" type="text/html" title="Temel Veri Tipleriyle Güvenli Kodun Temelleri" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/temel-veri-tipleriyle-guvenli-kodun-temelleri</id><content type="html" xml:base="https://sonsuzus.github.io/posts/temel-veri-tipleriyle-guvenli-kodun-temelleri/"><![CDATA[<p>Bir programın dünyayı nasıl algıladığını hiç düşündünüz mü? Bizim için yaş, isim ve ışığın açık olup olmadığı farklı kavramlardır. Bilgisayar açısından da bunlar sırasıyla sayı, metin ve mantıksal değer olarak temsil edilir. Temel veri tipleri, verinin anlamını belirleyerek yanlış değerlerin daha kod çalışmadan yakalanmasını sağlar. Kısacası tipler, değişkenlerin kapısında bekleyen seçici güvenlik görevlileridir.</p>

<p>``</p>

<h2 id="temel-veri-tipi-nedir">Temel veri tipi nedir?</h2>

<p>Bir veri tipi, bellekte saklanan değerin nasıl yorumlanacağını ve üzerinde hangi işlemlerin yapılabileceğini tanımlar. Örneğin <code class="language-plaintext highlighter-rouge">10</code> sayısına <code class="language-plaintext highlighter-rouge">5</code> eklemek matematiksel toplama üretirken, <code class="language-plaintext highlighter-rouge">"10"</code> metnine <code class="language-plaintext highlighter-rouge">"5"</code> eklemek çoğu dilde <code class="language-plaintext highlighter-rouge">"105"</code> sonucunu verir.</p>

<p>Bir değişkeni matematiksel olarak değer kümesiyle ifade edebiliriz. <code class="language-plaintext highlighter-rouge">boolean</code> tipindeki bir $b$ değişkeninin alabileceği değerler şöyledir:</p>

\[b \in \{true, false\}\]

<p>Benzer biçimde, 0 ile 120 arasında sınırlandırılmış bir yaş değeri için hedeflenen küme şudur:</p>

\[yas \in \mathbb{Z}, \quad 0 \le yas \le 120\]

<p>Tip sistemi ilk bölümde değerin sayı olmasını garanti edebilir. Aralık gibi daha özel iş kuralları ise doğrulama kodları veya gelişmiş tip teknikleri gerektirir.</p>

<h2 id="en-yaygın-temel-tipler">En yaygın temel tipler</h2>

<table>
  <thead>
    <tr>
      <th>Tip</th>
      <th>Örnek</th>
      <th>Kullanım alanı</th>
      <th>Uygun olmayan değer</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">number</code></td>
      <td><code class="language-plaintext highlighter-rouge">42</code>, <code class="language-plaintext highlighter-rouge">3.14</code></td>
      <td>Yaş, fiyat, puan</td>
      <td><code class="language-plaintext highlighter-rouge">"kırk iki"</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">string</code></td>
      <td><code class="language-plaintext highlighter-rouge">"Ada"</code></td>
      <td>İsim, açıklama, adres</td>
      <td>Sayısal hesaplama</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">boolean</code></td>
      <td><code class="language-plaintext highlighter-rouge">true</code></td>
      <td>Açık/kapalı durumları</td>
      <td><code class="language-plaintext highlighter-rouge">"belki"</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">null</code></td>
      <td><code class="language-plaintext highlighter-rouge">null</code></td>
      <td>Bilinçli olarak boş değer</td>
      <td>Gerçek veri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">undefined</code></td>
      <td><code class="language-plaintext highlighter-rouge">undefined</code></td>
      <td>Henüz atanmamış değer</td>
      <td>Kesin sonuç</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">bigint</code></td>
      <td><code class="language-plaintext highlighter-rouge">9007199254740993n</code></td>
      <td>Çok büyük tam sayılar</td>
      <td>Ondalıklı işlemler</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">symbol</code></td>
      <td><code class="language-plaintext highlighter-rouge">Symbol("id")</code></td>
      <td>Benzersiz anahtarlar</td>
      <td>Kullanıcı metni</td>
    </tr>
  </tbody>
</table>

<p><code class="language-plaintext highlighter-rouge">null</code> ve <code class="language-plaintext highlighter-rouge">undefined</code> birbirine benzese de aynı şeyi anlatmaz. <code class="language-plaintext highlighter-rouge">null</code>, geliştiricinin bilinçli biçimde “burada değer yok” demesidir. <code class="language-plaintext highlighter-rouge">undefined</code> ise değerin henüz tanımlanmadığını belirtir. Bu ayrım, özellikle API yanıtlarında oldukça önemlidir.</p>

<h2 id="tip-kısıtlaması-neden-güvenlidir">Tip kısıtlaması neden güvenlidir?</h2>

<p>Dinamik tipli JavaScript’te aşağıdaki değişken önce sayı, ardından metin olabilir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">puan</span> <span class="o">=</span> <span class="mi">90</span><span class="p">;</span>
<span class="nx">puan</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">doksan</span><span class="dl">"</span><span class="p">;</span>
</code></pre></div></div>

<p>Kod sözdizimi açısından geçerlidir; ancak daha sonra <code class="language-plaintext highlighter-rouge">puan / 2</code> işlemi yapılırsa beklenmeyen bir sonuç oluşabilir. TypeScript ile değişkenin kabul edeceği değer türü baştan belirtilir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">puan</span><span class="p">:</span> <span class="kr">number</span> <span class="o">=</span> <span class="mi">90</span><span class="p">;</span>
<span class="nx">puan</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>       <span class="c1">// Geçerli</span>
<span class="c1">// puan = "doksan"; // Derleme hatası</span>

<span class="kd">const</span> <span class="nx">basariliMi</span><span class="p">:</span> <span class="nx">boolean</span> <span class="o">=</span> <span class="nx">puan</span> <span class="o">&gt;=</span> <span class="mi">50</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">mesaj</span><span class="p">:</span> <span class="kr">string</span> <span class="o">=</span> <span class="nx">basariliMi</span> <span class="p">?</span> <span class="dl">"</span><span class="s2">Tebrikler!</span><span class="dl">"</span> <span class="p">:</span> <span class="dl">"</span><span class="s2">Tekrar dene</span><span class="dl">"</span><span class="p">;</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">puan</code> yalnızca sayı, <code class="language-plaintext highlighter-rouge">basariliMi</code> yalnızca mantıksal değer ve <code class="language-plaintext highlighter-rouge">mesaj</code> yalnızca metin kabul eder. Hatalı atama yorumdan çıkarılırsa TypeScript, program çalıştırılmadan geliştiriciyi uyarır. Böylece hata üretim ortamında kullanıcıyla tanışmadan önce yakalanır.</p>

<h2 id="tip-çıkarımı-ve-açık-tanımlama">Tip çıkarımı ve açık tanımlama</h2>

<p>TypeScript her zaman tipin açıkça yazılmasını istemez:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">kullaniciAdi</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">deniz</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// string olarak çıkarılır</span>
<span class="kd">let</span> <span class="nx">girisSayisi</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>        <span class="c1">// number olarak çıkarılır</span>
<span class="kd">let</span> <span class="nx">aktif</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>           <span class="c1">// boolean olarak çıkarılır</span>
</code></pre></div></div>

<p>Bu mekanizmaya <strong>tip çıkarımı</strong> denir. Başlangıç değeri tip hakkında yeterli bilgi veriyorsa kısa ve okunaklı kod sağlar. Fonksiyon parametrelerinde ise açık tip kullanmak daha güvenlidir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">indirimliFiyat</span><span class="p">(</span><span class="nx">fiyat</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">oran</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">fiyat</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="nx">oran</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">sonuc</span> <span class="o">=</span> <span class="nf">indirimliFiyat</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">);</span> <span class="c1">// 400</span>
</code></pre></div></div>

<p>Formül $F_{son} = F \times (1-r)$ şeklindedir. Tipler <code class="language-plaintext highlighter-rouge">fiyat</code> ve <code class="language-plaintext highlighter-rouge">oran</code> değerlerinin metin olmasını engeller; fakat oranın 0 ile 1 arasında olduğunu tek başına doğrulamaz. Bu nedenle çalışma zamanı kontrolleri tip sisteminin tamamlayıcısıdır.</p>

<h2 id="sonuç">Sonuç</h2>

<p>Temel veri tipleri yalnızca sözdizimsel ayrıntılar değildir; programın veri sözleşmesini oluşturur. Doğru tip seçimi otomatik tamamlama kalitesini artırır, yeniden düzenlemeyi kolaylaştırır ve hataları erkenden görünür kılar. Değişkene “her şeyi kabul et” demek pratik görünebilir, fakat güvenli yazılım çoğu zaman doğru yerde nazikçe “hayır” diyebilen yazılımdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="veri tipleri" /><category term="TypeScript" /><category term="tip güvenliği" /><summary type="html"><![CDATA[Bir programın dünyayı nasıl algıladığını hiç düşündünüz mü? Bizim için yaş, isim ve ışığın açık olup olmadığı farklı kavramlardır. Bilgisayar açısından da bunlar sırasıyla sayı, metin ve mantıksal değer olarak temsil edilir. Temel veri tipleri, verinin anlamını belirleyerek yanlış değerlerin daha kod çalışmadan yakalanmasını sağlar. Kısacası tipler, değişkenlerin kapısında bekleyen seçici güvenlik görevlileridir.]]></summary></entry><entry><title type="html">Tip Çıkarımı: Derleyicinin Kodunuzdaki Sessiz Dedektifliği</title><link href="https://sonsuzus.github.io/posts/tip-cikarimi-derleyicinin-kodunuzdaki-sessiz-dedektifligi/" rel="alternate" type="text/html" title="Tip Çıkarımı: Derleyicinin Kodunuzdaki Sessiz Dedektifliği" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/tip-cikarimi-derleyicinin-kodunuzdaki-sessiz-dedektifligi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/tip-cikarimi-derleyicinin-kodunuzdaki-sessiz-dedektifligi/"><![CDATA[<p>Bir değişken tanımlarken veri türünü yazmadığınız hâlde editörünüzün onun sayı mı, metin mi yoksa daha karmaşık bir nesne mi olduğunu bilmesi sihir gibi görünebilir. Aslında perde arkasında çalışan mekanizma <strong>tip çıkarımıdır</strong>. Derleyici, atanan ifadeyi inceleyerek uygun türü belirler; böylece kod kısalırken statik tip güvenliği büyük ölçüde korunur.
``</p>

<h2 id="tip-çıkarımı-tam-olarak-nedir">Tip çıkarımı tam olarak nedir?</h2>

<p>Tip çıkarımı, derleyicinin bir ifadenin veri türünü programcının açık bildirimine ihtiyaç duymadan hesaplamasıdır. Basit bir modelle değişkenin türünü şöyle gösterebiliriz:</p>

\[T(x) = T(e)\]

<p>Burada $x$ değişkeni, $e$ ise ona atanan ifadedir. Örneğin <code class="language-plaintext highlighter-rouge">x = 42</code> ifadesinde derleyici, <code class="language-plaintext highlighter-rouge">42</code> sabitinin türünü inceler ve dile bağlı olarak <code class="language-plaintext highlighter-rouge">int</code>, <code class="language-plaintext highlighter-rouge">Int</code> veya benzeri bir tür seçer.</p>

<p>Bu işlem çoğunlukla <strong>derleme zamanında</strong> gerçekleşir. Yani program çalışırken tür tahmini yapılmaz; derleyici daha çalıştırılabilir dosya üretilmeden önce kararını verir. Bu nedenle tip çıkarımı, dinamik tiplemeyle aynı şey değildir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Tip çıkarımı</th>
      <th>Dinamik tipleme</th>
      <th>Açık statik tipleme</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tür ne zaman belirlenir?</td>
      <td>Derleme zamanında</td>
      <td>Çalışma zamanında</td>
      <td>Programcı yazarken</td>
    </tr>
    <tr>
      <td>Türü kim belirtir?</td>
      <td>Derleyici</td>
      <td>Çalışan program</td>
      <td>Geliştirici</td>
    </tr>
    <tr>
      <td>Sonradan farklı tür atanabilir mi?</td>
      <td>Genellikle hayır</td>
      <td>Genellikle evet</td>
      <td>Hayır</td>
    </tr>
    <tr>
      <td>Kod uzunluğu</td>
      <td>Kısa</td>
      <td>Kısa</td>
      <td>Daha uzun</td>
    </tr>
    <tr>
      <td>Erken hata yakalama</td>
      <td>Güçlü</td>
      <td>Daha sınırlı</td>
      <td>Güçlü</td>
    </tr>
  </tbody>
</table>

<h2 id="derleyici-nasıl-karar-verir">Derleyici nasıl karar verir?</h2>

<p>Derleyici önce sağ taraftaki ifadeyi analiz eder. Sabitleri, fonksiyonların dönüş türlerini, operatörleri ve varsa genel tür kısıtlarını değerlendirir. Ardından bulunan türü değişkenle eşleştirir.</p>

<p>C# dilindeki şu örneğe bakalım:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">puan</span> <span class="p">=</span> <span class="m">95</span><span class="p">;</span>             <span class="c1">// Derleyici türü int olarak çıkarır.</span>
<span class="kt">var</span> <span class="n">mesaj</span> <span class="p">=</span> <span class="s">"Başarılı"</span><span class="p">;</span>   <span class="c1">// Tür string olur.</span>
<span class="kt">var</span> <span class="n">oran</span> <span class="p">=</span> <span class="m">0.85</span><span class="p">;</span>           <span class="c1">// Varsayılan olarak double seçilir.</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">var</code>, değişkenin türsüz olduğu anlamına gelmez. <code class="language-plaintext highlighter-rouge">puan</code>, derleme sonrasında kesin biçimde <code class="language-plaintext highlighter-rouge">int</code> kabul edilir. Bu yüzden aşağıdaki atama geçersizdir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">puan</span> <span class="p">=</span> <span class="m">95</span><span class="p">;</span>
<span class="n">puan</span> <span class="p">=</span> <span class="s">"Doksan beş"</span><span class="p">;</span> <span class="c1">// Hata: string, int değişkenine atanamaz.</span>
</code></pre></div></div>

<p>Derleyicinin ilk değerden hareket etmesi, türün daha sonra sürekli değişebileceği anlamına gelmez. İlk ifade yalnızca başlangıçtaki <strong>kanıttır</strong>; ulaşılan tür ise değişkenin kapsamı boyunca geçerli sözleşmedir.</p>

<h2 id="fonksiyonlarda-ve-koleksiyonlarda-çıkarım">Fonksiyonlarda ve koleksiyonlarda çıkarım</h2>

<p>Tip çıkarımı yalnızca basit değişkenlerle sınırlı değildir. Genel fonksiyon çağrılarında tür parametreleri de argümanlardan bulunabilir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">ilkEleman</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">liste</span><span class="p">:</span> <span class="nx">T</span><span class="p">[]):</span> <span class="nx">T</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">sonuc</span> <span class="o">=</span> <span class="nf">ilkEleman</span><span class="p">([</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">]);</span>
<span class="c1">// T, number olarak çıkarılır; sonuc da number olur.</span>
</code></pre></div></div>

<p>Derleyici burada dizinin elemanlarını inceler ve şu ilişkiyi kurar:</p>

\[T([10,20,30]) = number[] \Rightarrow T = number\]

<p>Bu yaklaşım, genel ve yeniden kullanılabilir kod yazmayı kolaylaştırır. Programcı her çağrıda <code class="language-plaintext highlighter-rouge">&lt;number&gt;</code> yazmak zorunda kalmaz.</p>

<h2 id="ne-zaman-açık-tür-yazılmalı">Ne zaman açık tür yazılmalı?</h2>

<p>Tip çıkarımı faydalı olsa da her yerde kullanmak okunabilirliği artırmaz. Değer türü ilk bakışta belliyse çıkarım idealdir. Karmaşık API dönüşlerinde, değişkenin niyetini vurgulamak gerektiğinde veya daha geniş bir tür hedeflendiğinde açık bildirim daha anlaşılır olabilir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">puanlar</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="p">{</span> <span class="m">70</span><span class="p">,</span> <span class="m">85</span><span class="p">,</span> <span class="m">100</span> <span class="p">};</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">var</code> kullanmak mümkün olsa da açık tür, kodun yalnızca <code class="language-plaintext highlighter-rouge">List&lt;int&gt;</code> uygulamasına değil <code class="language-plaintext highlighter-rouge">IEnumerable&lt;int&gt;</code> sözleşmesine dayandığını anlatır.</p>

<p>Kısacası tip çıkarımı, geliştiricinin yerine rastgele karar veren bir mekanizma değil; ifadelerden, kısıtlardan ve dil kurallarından mantıksal sonuç üreten bir derleyici özelliğidir. Doğru kullanıldığında kodu sadeleştirir, tekrarları azaltır ve tip güvenliğinden vazgeçmeden daha akıcı programlama sağlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="tip çıkarımı" /><category term="derleyici" /><category term="statik tipleme" /><summary type="html"><![CDATA[Bir değişken tanımlarken veri türünü yazmadığınız hâlde editörünüzün onun sayı mı, metin mi yoksa daha karmaşık bir nesne mi olduğunu bilmesi sihir gibi görünebilir. Aslında perde arkasında çalışan mekanizma tip çıkarımıdır. Derleyici, atanan ifadeyi inceleyerek uygun türü belirler; böylece kod kısalırken statik tip güvenliği büyük ölçüde korunur.]]></summary></entry></feed>