<?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://program.sonsuz.us/feed.xml" rel="self" type="application/atom+xml" /><link href="https://program.sonsuz.us/" rel="alternate" type="text/html" /><updated>2026-10-22T18:05:48+00:00</updated><id>https://program.sonsuz.us/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">Bir Boşluk, Bütün Disk: rm -rf Komutunun Tehlikeli Anatomisi</title><link href="https://program.sonsuz.us/posts/bir-bosluk-butun-disk-rm-rf-komutunun-tehlikeli-anatomisi/" rel="alternate" type="text/html" title="Bir Boşluk, Bütün Disk: rm -rf Komutunun Tehlikeli Anatomisi" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/bir-bosluk-butun-disk-rm-rf-komutunun-tehlikeli-anatomisi</id><content type="html" xml:base="https://program.sonsuz.us/posts/bir-bosluk-butun-disk-rm-rf-komutunun-tehlikeli-anatomisi/"><![CDATA[<p>Terminalde tek bir boşluğun ne kadar pahalı olabileceğini görmek istiyorsanız, <code class="language-plaintext highlighter-rouge">rm -rf</code> bunun en ürkütücü örneklerinden biridir. Yanlış yazılmış veya hatalı genişletilmiş bir yol; belgeleri, uygulamaları, yapılandırmaları ve yedekleri saniyeler içinde silebilir. Üstelik komut çoğunlukla “Emin misiniz?” diye sormaz. Klavyedeki minicik bir hata, dijital bir meteor etkisi oluşturabilir.</p>

<p>``</p>

<h2 id="rm--rf-gerçekte-ne-yapar"><code class="language-plaintext highlighter-rouge">rm -rf</code> gerçekte ne yapar?</h2>

<p><code class="language-plaintext highlighter-rouge">rm</code>, dosya ve dizinleri kaldırır. <code class="language-plaintext highlighter-rouge">-r</code> seçeneği dizinlerin içine özyinelemeli olarak girilmesini, <code class="language-plaintext highlighter-rouge">-f</code> ise uyarıların bastırılıp işlemin zorlanmasını sağlar. Başka bir deyişle komutun mantığı kabaca şöyledir:</p>

\[Silme\ Riski \approx Yetki \times Hedef\ Kapsamı \times Otomasyon\ Hızı\]

<p>Kök kullanıcı yetkisiyle geniş bir hedef seçildiğinde üç çarpan da büyür. Sonuç, geri dönüşüm kutusuna taşınan dosyalar değil; dosya sistemi kayıtlarının doğrudan kaldırılmasıdır.</p>

<table>
  <thead>
    <tr>
      <th>İfade</th>
      <th>Kabuğun yorumu</th>
      <th>Risk</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">rm -rf ./build</code></td>
      <td>Geçerli dizindeki <code class="language-plaintext highlighter-rouge">build</code> klasörü</td>
      <td>Sınırlı</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">rm -rf ./build/*</code></td>
      <td>Klasörün görünür içerikleri</td>
      <td>Orta</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">rm -rf /*</code></td>
      <td>Kök altındaki girdiler</td>
      <td>Felaket</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">rm -rf /</code></td>
      <td>Kök dizinin kendisi</td>
      <td>Felaket; bazı sistemlerde engellenir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">rm -rf / tmp/proje</code></td>
      <td>İki ayrı hedef: <code class="language-plaintext highlighter-rouge">/</code> ve <code class="language-plaintext highlighter-rouge">tmp/proje</code></td>
      <td>Felaket</td>
    </tr>
  </tbody>
</table>

<p>Burada önemli bir düzeltme var: <code class="language-plaintext highlighter-rouge">rm -rf /</code> ile <code class="language-plaintext highlighter-rouge">rm -rf /*</code> arasındaki fark yalnızca boşluk değildir; yıldız karakteri kabuk tarafından genişletilir. Modern GNU <code class="language-plaintext highlighter-rouge">rm</code>, <code class="language-plaintext highlighter-rouge">/</code> hedefini genellikle <code class="language-plaintext highlighter-rouge">--preserve-root</code> korumasıyla reddeder. Ancak <code class="language-plaintext highlighter-rouge">/*</code>, kabuk tarafından <code class="language-plaintext highlighter-rouge">/etc</code>, <code class="language-plaintext highlighter-rouge">/home</code>, <code class="language-plaintext highlighter-rouge">/usr</code> gibi ayrı hedeflere dönüştürülebildiğinden bu korumayı aşabilir. Yani iki komut da güvenli değildir.</p>

<h2 id="boşluk-hatası-nasıl-felakete-dönüşür">Boşluk hatası nasıl felakete dönüşür?</h2>

<p>Shell, boşluğu argüman ayırıcı olarak kullanır. Örneğin amaç <code class="language-plaintext highlighter-rouge">/tmp/proje</code> içeriğini silmekken yanlışlıkla yolun ortasına boşluk eklenirse komut iki farklı hedef algılayabilir. Benzer şekilde boş bir değişken de beklenmeyen bir hedef meydana getirir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># TEHLİKELİ ÖRNEK: Değişken boşsa hedef beklenenden farklılaşabilir.</span>
<span class="nb">rm</span> <span class="nt">-rf</span> <span class="s2">"</span><span class="nv">$TARGET</span><span class="s2">"</span>/<span class="k">*</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">TARGET</code> boş olduğunda ifade <code class="language-plaintext highlighter-rouge">/*</code> biçimine yaklaşır. Bu nedenle değişken kullanmadan önce hem doluluk hem de izin verilen kök yol denetlenmelidir.</p>

<h2 id="daha-güvenli-bir-silme-deseni">Daha güvenli bir silme deseni</h2>

<p>Aşağıdaki yaklaşım hedefi doğrular, mutlak yola dönüştürür ve yalnızca belirlenmiş çalışma alanı içindeki dizinlere izin verir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>
<span class="nb">set</span> <span class="nt">-euo</span> pipefail

<span class="nv">target</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">1</span><span class="k">:-}</span><span class="s2">"</span>
<span class="nv">allowed_root</span><span class="o">=</span><span class="s2">"/srv/builds"</span>

<span class="k">if</span> <span class="o">[[</span> <span class="nt">-z</span> <span class="s2">"</span><span class="nv">$target</span><span class="s2">"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
  </span><span class="nb">echo</span> <span class="s2">"Hata: Hedef boş olamaz."</span> <span class="o">&gt;</span>&amp;2
  <span class="nb">exit </span>1
<span class="k">fi

</span><span class="nv">resolved</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span><span class="nb">realpath</span> <span class="nt">--</span> <span class="s2">"</span><span class="nv">$target</span><span class="s2">"</span><span class="si">)</span><span class="s2">"</span>

<span class="k">if</span> <span class="o">[[</span> <span class="s2">"</span><span class="nv">$resolved</span><span class="s2">"</span> <span class="o">!=</span> <span class="s2">"</span><span class="nv">$allowed_root</span><span class="s2">"</span>/<span class="k">*</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
  </span><span class="nb">echo</span> <span class="s2">"Hata: İzin verilen alanın dışında: </span><span class="nv">$resolved</span><span class="s2">"</span> <span class="o">&gt;</span>&amp;2
  <span class="nb">exit </span>1
<span class="k">fi

</span><span class="nb">printf</span> <span class="s1">'Silinecek hedef: %s\n'</span> <span class="s2">"</span><span class="nv">$resolved</span><span class="s2">"</span>
<span class="nb">rm</span> <span class="nt">-rf</span> <span class="nt">--</span> <span class="s2">"</span><span class="nv">$resolved</span><span class="s2">"</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">set -u</code>, tanımsız değişkenleri hata kabul eder. <code class="language-plaintext highlighter-rouge">realpath</code>, <code class="language-plaintext highlighter-rouge">..</code> ve sembolik bağlantı kaynaklı belirsizlikleri azaltır. <code class="language-plaintext highlighter-rouge">--</code> ise tireyle başlayan bir dosya adının seçenek sanılmasını engeller. Yine de bu kod, yedeklemenin yerini tutmaz.</p>

<h2 id="kazayı-önlemek-için-pratik-kurallar">Kazayı önlemek için pratik kurallar</h2>

<ol>
  <li>Komutu çalıştırmadan önce hedefi <code class="language-plaintext highlighter-rouge">printf '%q\n' "$target"</code> ile görüntüleyin.</li>
  <li>Önce <code class="language-plaintext highlighter-rouge">ls</code> veya <code class="language-plaintext highlighter-rouge">find</code> kullanarak kapsamı inceleyin.</li>
  <li>Betiklerde <code class="language-plaintext highlighter-rouge">set -euo pipefail</code> etkinleştirin.</li>
  <li>Kritik işlemleri root yerine sınırlı yetkili kullanıcıyla yürütün.</li>
  <li>Snapshot ve çevrimdışı yedek bulundurun; aynı diskteki kopya gerçek yedek değildir.</li>
  <li>Etkileşimli kullanımda <code class="language-plaintext highlighter-rouge">rm -I</code> seçeneğini değerlendirin.</li>
</ol>

<p>Yanlış silme gerçekleşirse sistemi hemen kullanmayı bırakmak, diske yeni veri yazmamak ve profesyonel kurtarma araçlarına yönelmek gerekir. En iyi kurtarma stratejisi ise hâlâ kazadan önce hazırlanmış, düzenli olarak test edilen bir yedektir.</p>

<p><img src="/img/bir-bosluk-butun-16.svg" alt="bir-bosluk-butun-16" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="linux" /><category term="shell" /><category term="bash" /><category term="rm-komutu" /><category term="veri-güvenliği" /><category term="devops" /><summary type="html"><![CDATA[Terminalde tek bir boşluğun ne kadar pahalı olabileceğini görmek istiyorsanız, rm -rf bunun en ürkütücü örneklerinden biridir. Yanlış yazılmış veya hatalı genişletilmiş bir yol; belgeleri, uygulamaları, yapılandırmaları ve yedekleri saniyeler içinde silebilir. Üstelik komut çoğunlukla “Emin misiniz?” diye sormaz. Klavyedeki minicik bir hata, dijital bir meteor etkisi oluşturabilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/bir-bosluk-butun-16.png" /><media:content medium="image" url="https://program.sonsuz.us/img/bir-bosluk-butun-16.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ Atama Operatöründe Copy-and-Swap ile Güçlü İstisna Güvenliği</title><link href="https://program.sonsuz.us/posts/c-atama-operatorunde-copy-and-swap-ile-guclu-istisna-guvenligi/" rel="alternate" type="text/html" title="C++ Atama Operatöründe Copy-and-Swap ile Güçlü İstisna Güvenliği" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-atama-operatorunde-copy-and-swap-ile-guclu-istisna-guvenligi</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-atama-operatorunde-copy-and-swap-ile-guclu-istisna-guvenligi/"><![CDATA[<p>C++’ta kaynak yöneten bir sınıfa atama operatörü yazmak, ilk bakışta birkaç alanı kopyalamaktan ibaret görünür. Fakat bellek ayırma işlemi yarıda başarısız olursa nesne hangi durumda kalacaktır? <strong>Copy-and-swap</strong>, yeni durumu önce güvenli bir geçici nesnede hazırlayıp yalnızca başarı kesinleştiğinde devreye alarak bu sorunu zarifçe çözer.</p>

<p><img src="/img/c-atama-operatorunde-36.svg" alt="c-atama-operatorunde-36" /></p>

<p>``</p>
<h2 id="önce-problem-sil-sonra-kopyala">Önce problem: Sil, sonra kopyala</h2>

<p>Dinamik dizi yöneten basit bir sınıf düşünelim. Tehlikeli bir atama operatörü eski belleği önce silebilir, ardından yeni bellek ayırmaya çalışabilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Buffer</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">Buffer</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">delete</span><span class="p">[]</span> <span class="n">data_</span><span class="p">;</span>
    <span class="n">size_</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">size_</span><span class="p">;</span>
    <span class="n">data_</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="n">size_</span><span class="p">];</span> <span class="c1">// std::bad_alloc fırlatabilir</span>
    <span class="n">std</span><span class="o">::</span><span class="n">copy</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">data_</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="n">data_</span> <span class="o">+</span> <span class="n">size_</span><span class="p">,</span> <span class="n">data_</span><span class="p">);</span>
    <span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">new</code> başarısız olduğunda eski veri çoktan kaybedilmiştir. Üstelik <code class="language-plaintext highlighter-rouge">data_</code>, silinmiş belleği gösterebilir. Nesne artık yalnızca yanlış değil, yıkıcısı çalıştığında ikinci kez silme yapabilecek kadar tehlikelidir.</p>

<p>İstisna güvenliği genellikle üç seviyede değerlendirilir:</p>

<table>
  <thead>
    <tr>
      <th>Garanti</th>
      <th>İstisna sonrası durum</th>
      <th>Copy-and-swap</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Garanti yok</td>
      <td>Nesne bozulabilir</td>
      <td>Önler</td>
    </tr>
    <tr>
      <td>Temel garanti</td>
      <td>Nesne geçerlidir, değeri değişebilir</td>
      <td>Aşar</td>
    </tr>
    <tr>
      <td>Güçlü garanti</td>
      <td>İşlem ya tamamen olur ya hiç olmamış sayılır</td>
      <td>Sağlar</td>
    </tr>
    <tr>
      <td>Fırlatmama garantisi</td>
      <td>İşlem istisna üretmez</td>
      <td>Yalnızca <code class="language-plaintext highlighter-rouge">swap</code> için beklenir</td>
    </tr>
  </tbody>
</table>

<p>Güçlü garantiyi matematiksel olarak bir durum geçişi gibi ifade edebiliriz. Eski durum $S$, hedef durum $T$ ise:</p>

\[\operatorname{assign}(S,T)=
\begin{cases}
T, &amp; \text{işlem başarılıysa} \\
S, &amp; \text{istisna oluşursa}
\end{cases}\]

<p>Yani yarım kalmış, garip bir $S’$ durumuna izin verilmez.</p>

<h2 id="copy-and-swap-nasıl-çalışır">Copy-and-swap nasıl çalışır?</h2>

<p>Teknik üç adımdan oluşur:</p>

<ol>
  <li>Sağ taraftaki nesnenin geçici bir kopyasını oluştur.</li>
  <li>Geçici nesne ile mevcut nesnenin kaynaklarını değiştir.</li>
  <li>Geçici nesne kapsam dışına çıkınca eski kaynakları otomatik olarak yok etsin.</li>
</ol>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;cstddef&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;utility&gt;</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">Buffer</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">explicit</span> <span class="n">Buffer</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
        <span class="o">:</span> <span class="n">size_</span><span class="p">(</span><span class="n">size</span><span class="p">),</span> <span class="n">data_</span><span class="p">(</span><span class="n">size</span> <span class="o">?</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="n">size</span><span class="p">]{}</span> <span class="o">:</span> <span class="nb">nullptr</span><span class="p">)</span> <span class="p">{}</span>

    <span class="n">Buffer</span><span class="p">(</span><span class="k">const</span> <span class="n">Buffer</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span>
        <span class="o">:</span> <span class="n">size_</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">size_</span><span class="p">),</span>
          <span class="n">data_</span><span class="p">(</span><span class="n">size_</span> <span class="o">?</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="n">size_</span><span class="p">]</span> <span class="o">:</span> <span class="nb">nullptr</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">copy</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">data_</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="n">data_</span> <span class="o">+</span> <span class="n">size_</span><span class="p">,</span> <span class="n">data_</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">Buffer</span><span class="p">(</span><span class="n">Buffer</span><span class="o">&amp;&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="k">noexcept</span>
        <span class="o">:</span> <span class="n">size_</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">exchange</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">size_</span><span class="p">,</span> <span class="mi">0</span><span class="p">)),</span>
          <span class="n">data_</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">exchange</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">data_</span><span class="p">,</span> <span class="nb">nullptr</span><span class="p">))</span> <span class="p">{}</span>

    <span class="o">~</span><span class="n">Buffer</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">delete</span><span class="p">[]</span> <span class="n">data_</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">friend</span> <span class="kt">void</span> <span class="n">swap</span><span class="p">(</span><span class="n">Buffer</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="n">Buffer</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="k">noexcept</span> <span class="p">{</span>
        <span class="k">using</span> <span class="n">std</span><span class="o">::</span><span class="n">swap</span><span class="p">;</span>
        <span class="n">swap</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">size_</span><span class="p">,</span> <span class="n">b</span><span class="p">.</span><span class="n">size_</span><span class="p">);</span>
        <span class="n">swap</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">data_</span><span class="p">,</span> <span class="n">b</span><span class="p">.</span><span class="n">data_</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">Buffer</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="n">Buffer</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">swap</span><span class="p">(</span><span class="o">*</span><span class="k">this</span><span class="p">,</span> <span class="n">other</span><span class="p">);</span>
        <span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span>
    <span class="p">}</span>

<span class="k">private</span><span class="o">:</span>
    <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size_</span><span class="p">{};</span>
    <span class="kt">int</span><span class="o">*</span> <span class="n">data_</span><span class="p">{};</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Buradaki kritik ayrıntı, parametrenin <code class="language-plaintext highlighter-rouge">const Buffer&amp;</code> yerine <strong>değerle</strong> alınmasıdır. Bir lvalue gönderildiğinde kopya kurucu, rvalue gönderildiğinde ise taşıma kurucu geçici <code class="language-plaintext highlighter-rouge">other</code> nesnesini hazırlar. Böylece tek operatör hem kopyalama hem taşıma atamasını karşılayabilir.</p>

<p>Kopyalama sırasında <code class="language-plaintext highlighter-rouge">new</code> istisna fırlatırsa fonksiyon gövdesine henüz girilmez; <code class="language-plaintext highlighter-rouge">*this</code> değişmeden kalır. Kopya başarıyla oluşursa <code class="language-plaintext highlighter-rouge">swap</code> yalnızca boyut ve işaretçi gibi ucuz üyeleri değiştirir. Bu nedenle <code class="language-plaintext highlighter-rouge">swap</code> fonksiyonunun <code class="language-plaintext highlighter-rouge">noexcept</code> olması güçlü garantinin merkezidir. Değişimden sonra <code class="language-plaintext highlighter-rouge">other</code>, hedef nesnenin eski belleğini taşır ve yıkıcısı bu belleği temizler. RAII burada temizlik ekibidir; hem de fazla mesai ücreti istemez.</p>

<h2 id="geleneksel-atama-ile-karşılaştırma">Geleneksel atama ile karşılaştırma</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Elle yazılmış atama</th>
      <th>Copy-and-swap</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kendine atama kontrolü</td>
      <td>Genellikle <code class="language-plaintext highlighter-rouge">this != &amp;other</code> gerekir</td>
      <td>Doğal olarak güvenlidir</td>
    </tr>
    <tr>
      <td>Hata yönetimi</td>
      <td>Karmaşık geri alma kodu gerekir</td>
      <td>Geçici nesne geri almayı sağlar</td>
    </tr>
    <tr>
      <td>Kod tekrarı</td>
      <td>Yüksek olabilir</td>
      <td>Kopya kurucu ve <code class="language-plaintext highlighter-rouge">swap</code> yeniden kullanılır</td>
    </tr>
    <tr>
      <td>Performans</td>
      <td>Bellek yeniden kullanılabilir</td>
      <td>Her kopyada yeni kaynak ayırabilir</td>
    </tr>
  </tbody>
</table>

<p>Copy-and-swap temiz ve güvenlidir; ancak her zaman en hızlı çözüm değildir. Büyük tamponlarda mevcut kapasiteyi yeniden kullanmak önemliyse özel bir atama operatörü daha verimli olabilir. Ayrıca sınıf yalnızca <code class="language-plaintext highlighter-rouge">std::vector</code>, <code class="language-plaintext highlighter-rouge">std::string</code> ve akıllı işaretçiler gibi RAII türlerinden oluşuyorsa en iyi seçenek çoğu zaman <strong>Rule of Zero</strong>, yani özel atama operatörü yazmamaktır.</p>

<p>Özetle copy-and-swap, işlemi önce hazırla, sonra tek ve güvenli adımla yayımla yaklaşımıdır. <code class="language-plaintext highlighter-rouge">swap</code> gerçekten <code class="language-plaintext highlighter-rouge">noexcept</code> olduğu sürece atama işlemini bir veritabanı işlemi gibi davranmaya yaklaştırır: ya commit gerçekleşir ya da nesne eski hâlinde kalır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="copy-and-swap" /><category term="istisna-güvenliği" /><category term="operator-overloading" /><category term="raii" /><category term="modern-c++" /><summary type="html"><![CDATA[C++’ta kaynak yöneten bir sınıfa atama operatörü yazmak, ilk bakışta birkaç alanı kopyalamaktan ibaret görünür. Fakat bellek ayırma işlemi yarıda başarısız olursa nesne hangi durumda kalacaktır? Copy-and-swap, yeni durumu önce güvenli bir geçici nesnede hazırlayıp yalnızca başarı kesinleştiğinde devreye alarak bu sorunu zarifçe çözer.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-atama-operatorunde-36.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-atama-operatorunde-36.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# Diziler ve String İşlemleri: Veriyi Düzenlemenin Akıllı Yolları</title><link href="https://program.sonsuz.us/posts/c-diziler-ve-string-islemleri-veriyi-duzenlemenin-akilli-yollari/" rel="alternate" type="text/html" title="C# Diziler ve String İşlemleri: Veriyi Düzenlemenin Akıllı Yolları" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-diziler-ve-string-islemleri-veriyi-duzenlemenin-akilli-yollari</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-diziler-ve-string-islemleri-veriyi-duzenlemenin-akilli-yollari/"><![CDATA[<p>C# dünyasında diziler ve metinler, veriyi saklamanın ve işlemenin temel araçlarıdır. Bir sınıftaki notları, oyun haritasındaki hücreleri veya bir metindeki kelimeleri yönetirken bu yapılarla karşılaşırız. Diziler düzenli veri kutuları gibiyken <code class="language-plaintext highlighter-rouge">string</code>, karakterlerden oluşan özel ve değiştirilemez bir koleksiyondur. Gelin bu araçların teorisini ve pratik kullanımını birlikte inceleyelim.</p>

<p>``</p>

<h2 id="dizilerin-temel-mantığı">Dizilerin temel mantığı</h2>

<p>Dizi, aynı türden belirli sayıda elemanı ardışık indekslerle saklayan veri yapısıdır. İndeksler sıfırdan başladığı için uzunluğu $n$ olan bir dizinin geçerli indeks aralığı $0 \le i &lt; n$ şeklindedir. Bir elemana indeksle erişmenin zaman karmaşıklığı sabittir:</p>

\[T(n)=O(1)\]

<p>Buna karşılık aranan değerin konumu bilinmiyorsa tüm elemanların gezilmesi gerekebilir ve doğrusal aramanın maliyeti $O(n)$ olur.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span><span class="p">[]</span> <span class="n">notlar</span> <span class="p">=</span> <span class="p">{</span> <span class="m">75</span><span class="p">,</span> <span class="m">90</span><span class="p">,</span> <span class="m">68</span><span class="p">,</span> <span class="m">100</span> <span class="p">};</span>
<span class="kt">int</span> <span class="n">toplam</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>

<span class="k">foreach</span> <span class="p">(</span><span class="kt">int</span> <span class="n">not</span> <span class="k">in</span> <span class="n">notlar</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">toplam</span> <span class="p">+=</span> <span class="n">not</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">double</span> <span class="n">ortalama</span> <span class="p">=</span> <span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="n">toplam</span> <span class="p">/</span> <span class="n">notlar</span><span class="p">.</span><span class="n">Length</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">$"Ortalama: </span><span class="p">{</span><span class="n">ortalama</span><span class="p">:</span><span class="n">F2</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>
</code></pre></div></div>

<p>Bu örnek tek boyutlu diziyi dolaşır. Tür dönüşümü yapılmasaydı iki <code class="language-plaintext highlighter-rouge">int</code> değerin bölümü tam sayı üretirdi; <code class="language-plaintext highlighter-rouge">(double)</code> dönüşümü küsuratı korur.</p>

<h2 id="çok-boyutlu-ve-düzensiz-diziler">Çok boyutlu ve düzensiz diziler</h2>

<p>Çok boyutlu diziler satır ve sütunları eşit olan dikdörtgen tabloları temsil eder. Düzensiz, yani jagged diziler ise her satırında farklı sayıda eleman taşıyabilen dizilerin dizisidir.</p>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>Tanım</th>
      <th>Uygun kullanım</th>
      <th>Erişim biçimi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tek boyutlu</td>
      <td>Doğrusal eleman listesi</td>
      <td>Notlar, fiyatlar</td>
      <td><code class="language-plaintext highlighter-rouge">dizi[i]</code></td>
    </tr>
    <tr>
      <td>Çok boyutlu</td>
      <td>Dikdörtgen matris</td>
      <td>Tahta, tablo, piksel alanı</td>
      <td><code class="language-plaintext highlighter-rouge">dizi[i, j]</code></td>
    </tr>
    <tr>
      <td>Jagged</td>
      <td>Satır uzunlukları değişken yapı</td>
      <td>Gruplar, değişken seviyeler</td>
      <td><code class="language-plaintext highlighter-rouge">dizi[i][j]</code></td>
    </tr>
  </tbody>
</table>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span><span class="p">[,]</span> <span class="n">harita</span> <span class="p">=</span>
<span class="p">{</span>
    <span class="p">{</span> <span class="m">1</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">1</span> <span class="p">},</span>
    <span class="p">{</span> <span class="m">0</span><span class="p">,</span> <span class="m">1</span><span class="p">,</span> <span class="m">0</span> <span class="p">}</span>
<span class="p">};</span>

<span class="kt">int</span><span class="p">[][]</span> <span class="n">gruplar</span> <span class="p">=</span>
<span class="p">{</span>
    <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="m">10</span><span class="p">,</span> <span class="m">20</span> <span class="p">},</span>
    <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="m">30</span><span class="p">,</span> <span class="m">40</span><span class="p">,</span> <span class="m">50</span> <span class="p">},</span>
    <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="m">60</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="n">harita</span><span class="p">[</span><span class="m">1</span><span class="p">,</span> <span class="m">1</span><span class="p">]);</span> <span class="c1">// 1</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">gruplar</span><span class="p">[</span><span class="m">1</span><span class="p">][</span><span class="m">2</span><span class="p">]);</span> <span class="c1">// 50</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">int[,]</code> tek bir dikdörtgen bloktur. <code class="language-plaintext highlighter-rouge">int[][]</code> içindeki her satır ise bağımsız bir dizidir. Bu esneklik bellek kullanımını azaltabilir; ancak satırların ayrı ayrı oluşturulması ve kontrol edilmesi gerekir.</p>

<h2 id="string-karakter-dizisinden-daha-fazlası">String: Karakter dizisinden daha fazlası</h2>

<p><code class="language-plaintext highlighter-rouge">string</code>, kavramsal olarak karakter dizisine benzese de <strong>immutable</strong>, yani değiştirilemez bir referans türüdür. Birleştirme veya değiştirme işlemi mevcut metni düzenlemez; yeni bir <code class="language-plaintext highlighter-rouge">string</code> üretir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span> <span class="n">mesaj</span> <span class="p">=</span> <span class="s">"  C# diziler eğlencelidir  "</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">temiz</span> <span class="p">=</span> <span class="n">mesaj</span><span class="p">.</span><span class="nf">Trim</span><span class="p">();</span>
<span class="kt">string</span><span class="p">[]</span> <span class="n">kelimeler</span> <span class="p">=</span> <span class="n">temiz</span><span class="p">.</span><span class="nf">Split</span><span class="p">(</span><span class="sc">' '</span><span class="p">,</span> <span class="n">StringSplitOptions</span><span class="p">.</span><span class="n">RemoveEmptyEntries</span><span class="p">);</span>
<span class="kt">string</span> <span class="n">sonuc</span> <span class="p">=</span> <span class="kt">string</span><span class="p">.</span><span class="nf">Join</span><span class="p">(</span><span class="s">" | "</span><span class="p">,</span> <span class="n">kelimeler</span><span class="p">).</span><span class="nf">ToUpperInvariant</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="n">sonuc</span><span class="p">);</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">Trim</code> kenar boşluklarını kaldırır, <code class="language-plaintext highlighter-rouge">Split</code> metni parçalara ayırır, <code class="language-plaintext highlighter-rouge">Join</code> parçaları yeniden birleştirir. <code class="language-plaintext highlighter-rouge">ToUpperInvariant</code>, sonucu kullanıcının bölgesel dil ayarlarından bağımsız biçimde büyük harfe dönüştürür.</p>

<table>
  <thead>
    <tr>
      <th>İşlem</th>
      <th>Yöntem</th>
      <th>Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Arama</td>
      <td><code class="language-plaintext highlighter-rouge">Contains</code>, <code class="language-plaintext highlighter-rouge">IndexOf</code></td>
      <td>Metin veya konum bulur</td>
    </tr>
    <tr>
      <td>Parçalama</td>
      <td><code class="language-plaintext highlighter-rouge">Split</code>, <code class="language-plaintext highlighter-rouge">Substring</code></td>
      <td>Alt metin üretir</td>
    </tr>
    <tr>
      <td>Değiştirme</td>
      <td><code class="language-plaintext highlighter-rouge">Replace</code></td>
      <td>Yeni metin döndürür</td>
    </tr>
    <tr>
      <td>Doğrulama</td>
      <td><code class="language-plaintext highlighter-rouge">StartsWith</code>, <code class="language-plaintext highlighter-rouge">EndsWith</code></td>
      <td><code class="language-plaintext highlighter-rouge">bool</code> değer üretir</td>
    </tr>
  </tbody>
</table>

<h2 id="çok-sayıda-birleştirmede-stringbuilder">Çok sayıda birleştirmede StringBuilder</h2>

<p>Döngü içinde <code class="language-plaintext highlighter-rouge">+</code> kullanmak çok sayıda geçici nesne oluşturabilir. Bu durumda <code class="language-plaintext highlighter-rouge">StringBuilder</code>, değiştirilebilir bir karakter tamponu sunar:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">System.Text</span><span class="p">;</span>

<span class="kt">var</span> <span class="n">rapor</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">StringBuilder</span><span class="p">();</span>
<span class="k">foreach</span> <span class="p">(</span><span class="kt">int</span> <span class="n">not</span> <span class="k">in</span> <span class="n">notlar</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">rapor</span><span class="p">.</span><span class="nf">Append</span><span class="p">(</span><span class="s">"Not: "</span><span class="p">).</span><span class="nf">AppendLine</span><span class="p">(</span><span class="n">not</span><span class="p">.</span><span class="nf">ToString</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="n">rapor</span><span class="p">.</span><span class="nf">ToString</span><span class="p">());</span>
</code></pre></div></div>

<p>Az sayıdaki birleştirmede string interpolation okunaklıdır; yoğun işlemlerde ise <code class="language-plaintext highlighter-rouge">StringBuilder</code> daha verimlidir. Özetle doğru dizi türünü veri şekline, doğru metin aracını da işlem yoğunluğuna göre seçmek hem performansı hem kod okunabilirliğini artırır.</p>

<p><img src="/img/c-diziler-ve-74.svg" alt="c-diziler-ve-74" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="diziler" /><category term="string" /><category term="jagged-array" /><category term="stringbuilder" /><category term="programlama" /><summary type="html"><![CDATA[C# dünyasında diziler ve metinler, veriyi saklamanın ve işlemenin temel araçlarıdır. Bir sınıftaki notları, oyun haritasındaki hücreleri veya bir metindeki kelimeleri yönetirken bu yapılarla karşılaşırız. Diziler düzenli veri kutuları gibiyken string, karakterlerden oluşan özel ve değiştirilemez bir koleksiyondur. Gelin bu araçların teorisini ve pratik kullanımını birlikte inceleyelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-diziler-ve-74.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-diziler-ve-74.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ İsim Alanları: Büyük Projelerde İsim Çakışmalarına Son</title><link href="https://program.sonsuz.us/posts/c-isim-alanlari-buyuk-projelerde-isim-cakismalarina-son/" rel="alternate" type="text/html" title="C++ İsim Alanları: Büyük Projelerde İsim Çakışmalarına Son" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-isim-alanlari-buyuk-projelerde-isim-cakismalarina-son</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-isim-alanlari-buyuk-projelerde-isim-cakismalarina-son/"><![CDATA[<p><img src="/img/c-isim-alanlari-19.svg" alt="c-isim-alanlari-19" /></p>

<p>Bir projede yalnızca birkaç değişken ve sınıf varken isim bulmak kolaydır. Ancak kod tabanı büyüdükçe farklı geliştiricilerin aynı <code class="language-plaintext highlighter-rouge">Logger</code>, <code class="language-plaintext highlighter-rouge">Config</code> veya <code class="language-plaintext highlighter-rouge">User</code> adını kullanması kaçınılmaz hâle gelir. C++ isim alanları, yani <code class="language-plaintext highlighter-rouge">namespace</code> yapıları, bu isimleri mantıksal gruplara ayırarak derleyiciye hangi varlığı kastettiğimizi söyler. Kısacası namespace, kod dünyasının mahalle adresidir: Aynı isimli iki kişi olabilir, yeter ki farklı adreslerde yaşasın!</p>

<p>``</p>

<h2 id="i̇sim-çakışması-neden-oluşur">İsim çakışması neden oluşur?</h2>

<p>C++ dilinde bir ismin hangi bölgeden erişilebilir olduğunu belirleyen kurallara <strong>kapsam</strong>, yani scope denir. Global kapsamda tanımlanan isimler projenin birçok noktasından görülebildiği için çakışma olasılığı yükselir. Bir projede birbirinden bağımsız $n$ bileşen ve her bileşende ortalama $k$ genel isim bulunduğunu düşünelim. Karşılaştırılabilecek isim çiftlerinin sayısı yaklaşık olarak şöyledir:</p>

\[P = \frac{(nk)(nk-1)}{2}\]

<p>Bu ifade doğrudan kesin çakışma sayısını vermez; proje büyüdükçe riskin neden hızla arttığını gösterir. İsimleri namespace gruplarına bölmek, karşılaştırma alanını küçültür.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Kullanım örneği</th>
      <th style="text-align: right">Çakışma riski</th>
      <th>Okunabilirlik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Global isim</td>
      <td><code class="language-plaintext highlighter-rouge">Logger</code></td>
      <td style="text-align: right">Yüksek</td>
      <td>Orta</td>
    </tr>
    <tr>
      <td>Namespace içindeki isim</td>
      <td><code class="language-plaintext highlighter-rouge">app::Logger</code></td>
      <td style="text-align: right">Düşük</td>
      <td>Yüksek</td>
    </tr>
    <tr>
      <td>İç içe namespace</td>
      <td><code class="language-plaintext highlighter-rouge">company::app::Logger</code></td>
      <td style="text-align: right">Çok düşük</td>
      <td>Yüksek</td>
    </tr>
  </tbody>
</table>

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

<p>Bir isim alanı <code class="language-plaintext highlighter-rouge">namespace</code> anahtar sözcüğüyle tanımlanır. Aynı sınıf adı farklı alanlarda güvenle bulunabilir:</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">
</span>
<span class="k">namespace</span> <span class="n">Database</span> <span class="p">{</span>
    <span class="k">class</span> <span class="nc">Connection</span> <span class="p">{</span>
    <span class="nl">public:</span>
        <span class="kt">void</span> <span class="n">open</span><span class="p">()</span> <span class="k">const</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">"Veritabanı bağlantısı açıldı.</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">};</span>
<span class="p">}</span>

<span class="k">namespace</span> <span class="n">Network</span> <span class="p">{</span>
    <span class="k">class</span> <span class="nc">Connection</span> <span class="p">{</span>
    <span class="nl">public:</span>
        <span class="kt">void</span> <span class="n">open</span><span class="p">()</span> <span class="k">const</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">"Ağ bağlantısı açıldı.</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">};</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">Database</span><span class="o">::</span><span class="n">Connection</span> <span class="n">database</span><span class="p">;</span>
    <span class="n">Network</span><span class="o">::</span><span class="n">Connection</span> <span class="n">network</span><span class="p">;</span>

    <span class="n">database</span><span class="p">.</span><span class="n">open</span><span class="p">();</span>
    <span class="n">network</span><span class="p">.</span><span class="n">open</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">::</code> operatörüne <strong>kapsam çözümleme operatörü</strong> denir. <code class="language-plaintext highlighter-rouge">Database::Connection</code>, derleyiciye yalnızca <code class="language-plaintext highlighter-rouge">Connection</code> sınıfını değil, sınıfın tam adresini verir.</p>

<h2 id="using-kullanırken-dikkat"><code class="language-plaintext highlighter-rouge">using</code> kullanırken dikkat</h2>

<p>Uzun isimleri sürekli yazmamak için <code class="language-plaintext highlighter-rouge">using</code> bildirimi kullanılabilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="n">Database</span><span class="o">::</span><span class="n">Connection</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">Connection</span> <span class="n">connection</span><span class="p">;</span>
    <span class="n">connection</span><span class="p">.</span><span class="n">open</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu yöntem yalnızca ihtiyaç duyulan ismi mevcut kapsama taşır. Buna karşılık aşağıdaki kullanım özellikle başlık dosyalarında risklidir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
</code></pre></div></div>

<p>Bu ifade <code class="language-plaintext highlighter-rouge">std</code> içindeki çok sayıda ismi görünür yapar. Projede başka bir <code class="language-plaintext highlighter-rouge">count</code>, <code class="language-plaintext highlighter-rouge">distance</code> veya <code class="language-plaintext highlighter-rouge">begin</code> tanımı varsa belirsizlik oluşabilir.</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
      <th>Öneri</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::string</code></td>
      <td>Açık ve güvenli</td>
      <td>Biraz uzun</td>
      <td>Genel olarak tercih edilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">using std::string</code></td>
      <td>Kısa ve kontrollü</td>
      <td>Yerel çakışma olabilir</td>
      <td>Dar kapsamda kullanılabilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">using namespace std</code></td>
      <td>Çok kısa</td>
      <td>Pek çok ismi içeri taşır</td>
      <td>Başlık dosyalarında kaçınılmalıdır</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇ç-içe-ve-anonim-namespace">İç içe ve anonim namespace</h2>

<p>Modern C++ ile iç içe isim alanları daha kısa yazılabilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">namespace</span> <span class="n">company</span><span class="o">::</span><span class="n">project</span><span class="o">::</span><span class="n">logging</span> <span class="p">{</span>
    <span class="kt">void</span> <span class="n">write</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">message</span><span class="p">)</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">message</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Fonksiyonun tam adı <code class="language-plaintext highlighter-rouge">company::project::logging::write</code> olur. Bu yapı şirket, ürün ve modül katmanlarını ifade etmek için kullanışlıdır.</p>

<p>Anonim namespace ise bir kaynak dosyasındaki isimleri yalnızca o çeviri birimine özel tutar:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">namespace</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">calculateSecretValue</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="mi">42</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu fonksiyona başka bir <code class="language-plaintext highlighter-rouge">.cpp</code> dosyasından erişilemez. Böylece uygulama içi yardımcı fonksiyonlar dış dünyaya sızmaz.</p>

<h2 id="pratik-kurallar">Pratik kurallar</h2>

<ul>
  <li>Namespace adlarını modül sınırlarına göre seçin.</li>
  <li>Başlık dosyalarında <code class="language-plaintext highlighter-rouge">using namespace</code> kullanmayın.</li>
  <li>Çok genel <code class="language-plaintext highlighter-rouge">Utils</code> veya <code class="language-plaintext highlighter-rouge">Common</code> adları yerine anlamlı alanlar oluşturun.</li>
  <li>Genel API’lerde kısa ama ayırt edici isimler tercih edin.</li>
  <li>Aynı namespace’i birden fazla dosyada genişletebileceğinizi unutmayın.</li>
</ul>

<p>Doğru namespace tasarımı yalnızca derleyici hatalarını önlemez; kodun sahibini, amacını ve mimari konumunu da anlatır. Büyük bir C++ projesinde düzen, iyi seçilmiş isimlerle; güvenlik ise o isimlere doğru adresleri vermekle başlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="namespace" /><category term="isim alanları" /><category term="yazılım mimarisi" /><category term="modüler programlama" /><summary type="html"><![CDATA[Bir projede yalnızca birkaç değişken ve sınıf varken isim bulmak kolaydır. Ancak kod tabanı büyüdükçe farklı geliştiricilerin aynı Logger, Config veya User adını kullanması kaçınılmaz hâle gelir. C++ isim alanları, yani namespace yapıları, bu isimleri mantıksal gruplara ayırarak derleyiciye hangi varlığı kastettiğimizi söyler. Kısacası namespace, kod dünyasının mahalle adresidir: Aynı isimli iki kişi olabilir, yeter ki farklı adreslerde yaşasın!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-isim-alanlari-19.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-isim-alanlari-19.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# Kalıtım ve Sanal Metotlar: override, new ve Polimorfizm Rehberi</title><link href="https://program.sonsuz.us/posts/c-kalitim-ve-sanal-metotlar-override-new-ve-polimorfizm-rehberi/" rel="alternate" type="text/html" title="C# Kalıtım ve Sanal Metotlar: override, new ve Polimorfizm Rehberi" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-kalitim-ve-sanal-metotlar-override-new-ve-polimorfizm-rehberi</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-kalitim-ve-sanal-metotlar-override-new-ve-polimorfizm-rehberi/"><![CDATA[<p><img src="/img/c-kalitim-ve-20.svg" alt="c-kalitim-ve-20" /></p>

<p>Kalıtım, bir sınıfın başka bir sınıftaki veri ve davranışları devralmasını sağlayan nesne yönelimli programlama tekniğidir. C# tarafında bu mekanizma yalnızca kod tekrarını azaltmaz; doğru kullanıldığında değiştirilebilir, genişletilebilir ve test edilebilir sistemlerin temelini oluşturur. Ancak <code class="language-plaintext highlighter-rouge">virtual</code>, <code class="language-plaintext highlighter-rouge">override</code> ve <code class="language-plaintext highlighter-rouge">new</code> anahtar sözcükleri karıştırılırsa masum görünen bir sınıf hiyerarşisi küçük bir sürpriz fabrikasına dönüşebilir.
``</p>

<h2 id="kalıtımın-temel-mantığı">Kalıtımın temel mantığı</h2>

<p>Türetilmiş sınıf, temel sınıfın erişilebilir üyelerini devralır. C# dilinde sınıf türetmek için sınıf adından sonra <code class="language-plaintext highlighter-rouge">:</code> kullanılır:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Hayvan</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">string</span> <span class="n">Ad</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span> <span class="p">=</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">void</span> <span class="nf">Beslen</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">$"</span><span class="p">{</span><span class="n">Ad</span><span class="p">}</span><span class="s"> besleniyor."</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">Kedi</span> <span class="p">:</span> <span class="n">Hayvan</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">void</span> <span class="nf">Mirla</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">$"</span><span class="p">{</span><span class="n">Ad</span><span class="p">}</span><span class="s"> mırlıyor."</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Kedi</code>, kendi <code class="language-plaintext highlighter-rouge">Mirla</code> metoduna ek olarak <code class="language-plaintext highlighter-rouge">Hayvan</code> sınıfındaki <code class="language-plaintext highlighter-rouge">Ad</code> ve <code class="language-plaintext highlighter-rouge">Beslen</code> üyelerini kullanabilir. Buradaki ilişki “Kedi bir Hayvan’dır” şeklinde okunur. Bu <strong>is-a</strong> ilişkisi mantıklı değilse kalıtım yerine bileşim tercih edilmelidir.</p>

<p>Bir hiyerarşideki sınıf sayısını $n$, her sınıfta tekrarlanacak ortak davranış miktarını $m$ kabul edersek kaba tekrar maliyeti $n \times m$ olur. Ortak davranışı temel sınıfa taşımak bu miktarı yaklaşık $m + n$ seviyesine indirebilir. Elbette gerçek tasarım kalitesi yalnızca satır sayısıyla ölçülmez.</p>

<h2 id="sanal-metot-ve-ezme-işlemi">Sanal metot ve ezme işlemi</h2>

<p>Temel sınıf, alt sınıfların bir davranışı değiştirmesine izin vermek için metodu <code class="language-plaintext highlighter-rouge">virtual</code> olarak tanımlar. Türetilmiş sınıf ise <code class="language-plaintext highlighter-rouge">override</code> ile aynı sözleşmenin yeni uygulamasını sunar:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Hayvan</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">virtual</span> <span class="k">void</span> <span class="nf">SesCikar</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">"Bilinmeyen hayvan sesi"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">Kedi</span> <span class="p">:</span> <span class="n">Hayvan</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">SesCikar</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">"Miyav!"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="n">Hayvan</span> <span class="n">dost</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Kedi</span><span class="p">();</span>
<span class="n">dost</span><span class="p">.</span><span class="nf">SesCikar</span><span class="p">();</span> <span class="c1">// Miyav!</span>
</code></pre></div></div>

<p>Değişkenin derleme zamanı türü <code class="language-plaintext highlighter-rouge">Hayvan</code>, gerçek nesnenin türü ise <code class="language-plaintext highlighter-rouge">Kedi</code> olmasına rağmen <code class="language-plaintext highlighter-rouge">Kedi.SesCikar</code> çalışır. Buna çalışma zamanı polimorfizmi denir. Hangi uygulamanın seçileceği nesnenin gerçek türüne göre belirlenir.</p>

<h2 id="override-ile-new-arasındaki-kritik-fark"><code class="language-plaintext highlighter-rouge">override</code> ile <code class="language-plaintext highlighter-rouge">new</code> arasındaki kritik fark</h2>

<p><code class="language-plaintext highlighter-rouge">new</code>, temel sınıftaki üyeyi ezmez; onu gizler. Bu nedenle çağrılacak metot, referansın derleme zamanı türüne bağlıdır.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Temel</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">void</span> <span class="nf">Yaz</span><span class="p">()</span> <span class="p">=&gt;</span> <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Temel"</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">Turemis</span> <span class="p">:</span> <span class="n">Temel</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">new</span> <span class="k">void</span> <span class="nf">Yaz</span><span class="p">()</span> <span class="p">=&gt;</span> <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Türetilmiş"</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">Turemis</span> <span class="n">a</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Turemis</span><span class="p">();</span>
<span class="n">Temel</span> <span class="n">b</span> <span class="p">=</span> <span class="n">a</span><span class="p">;</span>

<span class="n">a</span><span class="p">.</span><span class="nf">Yaz</span><span class="p">();</span> <span class="c1">// Türetilmiş</span>
<span class="n">b</span><span class="p">.</span><span class="nf">Yaz</span><span class="p">();</span> <span class="c1">// Temel</span>
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th><code class="language-plaintext highlighter-rouge">override</code></th>
      <th><code class="language-plaintext highlighter-rouge">new</code></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Amaç</td>
      <td>Sanal davranışı değiştirmek</td>
      <td>Üyeyi gizlemek</td>
    </tr>
    <tr>
      <td>Seçim zamanı</td>
      <td>Çalışma zamanı</td>
      <td>Derleme zamanı</td>
    </tr>
    <tr>
      <td>Temel metot gereksinimi</td>
      <td><code class="language-plaintext highlighter-rouge">virtual</code> veya <code class="language-plaintext highlighter-rouge">abstract</code> olmalı</td>
      <td>Böyle bir gereksinim yok</td>
    </tr>
    <tr>
      <td>Polimorfizm</td>
      <td>Destekler</td>
      <td>Gerçek polimorfizm sağlamaz</td>
    </tr>
    <tr>
      <td>Tipik kullanım</td>
      <td>Genişletilebilir tasarım</td>
      <td>Bilinçli ad çakışması</td>
    </tr>
  </tbody>
</table>

<h2 id="base-abstract-ve-sealed"><code class="language-plaintext highlighter-rouge">base</code>, <code class="language-plaintext highlighter-rouge">abstract</code> ve <code class="language-plaintext highlighter-rouge">sealed</code></h2>

<p>Ezilen metot içinde temel davranışı korumak için <code class="language-plaintext highlighter-rouge">base</code> kullanılabilir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">SesCikar</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">base</span><span class="p">.</span><span class="nf">SesCikar</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">"Ardından özel kedi sesi: Miyav!"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bir davranışın mutlaka alt sınıflarca uygulanması gerekiyorsa <code class="language-plaintext highlighter-rouge">abstract</code> daha güçlü bir sözleşme kurar. Daha fazla ezilmesini engellemek içinse metoda <code class="language-plaintext highlighter-rouge">sealed override</code> yazılabilir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">Odeme</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">abstract</span> <span class="kt">bool</span> <span class="nf">Gerceklestir</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">tutar</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">KartlaOdeme</span> <span class="p">:</span> <span class="n">Odeme</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">sealed</span> <span class="k">override</span> <span class="kt">bool</span> <span class="nf">Gerceklestir</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">tutar</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">tutar</span> <span class="p">&gt;</span> <span class="m">0</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>İyi bir polimorfik tasarımda kullanıcı kodu somut sınıflara değil, temel sınıf veya arayüz sözleşmesine bağımlı olur. Alt türler temel türün yerine geçtiğinde programın anlamı bozulmamalıdır; bu yaklaşım Liskov Yerine Geçme İlkesi’nin özüdür. Kısacası davranış gerçekten çeşitlenecekse <code class="language-plaintext highlighter-rouge">virtual/override</code>, zorunlu uygulanacaksa <code class="language-plaintext highlighter-rouge">abstract</code>, yalnızca isim çakışması bilinçli biçimde yönetilecekse <code class="language-plaintext highlighter-rouge">new</code> kullanılmalıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="kalıtım" /><category term="polimorfizm" /><category term="oop" /><category term="sanal-metotlar" /><category term="dotnet" /><summary type="html"><![CDATA[Kalıtım, bir sınıfın başka bir sınıftaki veri ve davranışları devralmasını sağlayan nesne yönelimli programlama tekniğidir. C# tarafında bu mekanizma yalnızca kod tekrarını azaltmaz; doğru kullanıldığında değiştirilebilir, genişletilebilir ve test edilebilir sistemlerin temelini oluşturur. Ancak virtual, override ve new anahtar sözcükleri karıştırılırsa masum görünen bir sınıf hiyerarşisi küçük bir sürpriz fabrikasına dönüşebilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-kalitim-ve-20.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-kalitim-ve-20.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# Unsafe Kod ve İşaretçiler: Belleğe Doğrudan Dokunmak</title><link href="https://program.sonsuz.us/posts/c-unsafe-kod-ve-isaretciler-bellege-dogrudan-dokunmak/" rel="alternate" type="text/html" title="C# Unsafe Kod ve İşaretçiler: Belleğe Doğrudan Dokunmak" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-unsafe-kod-ve-isaretciler-bellege-dogrudan-dokunmak</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-unsafe-kod-ve-isaretciler-bellege-dogrudan-dokunmak/"><![CDATA[<p><img src="/img/c-unsafe-kod-73.svg" alt="c-unsafe-kod-73" /></p>

<p>C# çoğunlukla güvenli ve yönetilen bir dünyada çalışır: Belleği çöp toplayıcı düzenler, dizilerin sınırları denetlenir ve geliştirici adres hesaplarıyla uğraşmaz. Ancak görüntü işleme, oyun motorları, yerel kütüphane entegrasyonu veya çok düşük gecikmeli sistemler söz konusu olduğunda bu konforun küçük bir performans maliyeti olabilir. <code class="language-plaintext highlighter-rouge">unsafe</code> kod, C# geliştiricisine C++ benzeri işaretçilerle belleğe doğrudan erişim imkânı verir. Güçlüdür; fakat emniyet kemerini çıkarmaya benzediği için dikkatli kullanılmalıdır.</p>

<p>``</p>

<h2 id="yönetilen-bellekten-işaretçilere">Yönetilen bellekten işaretçilere</h2>

<p>Normal C# referansı bir nesneyi gösterir, ancak nesnenin fiziksel adresini geliştiriciye açmaz. İşaretçi ise bellekteki adresi doğrudan tutar. <code class="language-plaintext highlighter-rouge">int*</code> ifadesi, bir <code class="language-plaintext highlighter-rouge">int</code> değerinin adresini taşıyan işaretçi anlamına gelir.</p>

<p>Bir işaretçinin kaba bellek modeli şöyle ifade edilebilir:</p>

\[\text{hedef adres} = \text{başlangıç adresi} + i \times \text{veri tipi boyutu}\]

<p>Örneğin <code class="language-plaintext highlighter-rouge">int</code> 4 baytsa <code class="language-plaintext highlighter-rouge">p + 3</code>, başlangıçtan yaklaşık $3 \times 4 = 12$ bayt ilerideki elemana ulaşır. İşaretçi aritmetiği bayt yerine hedef türün boyutunu hesaba kattığından kullanışlıdır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Güvenli C#</th>
      <th>Unsafe C#</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Bellek erişimi</td>
      <td>Referanslar üzerinden</td>
      <td>Doğrudan adres üzerinden</td>
    </tr>
    <tr>
      <td>Sınır kontrolü</td>
      <td>Genellikle var</td>
      <td>İşaretçide yok</td>
    </tr>
    <tr>
      <td>Çöp toplayıcı uyumu</td>
      <td>Otomatik</td>
      <td>Sabitleme gerekebilir</td>
    </tr>
    <tr>
      <td>Hata riski</td>
      <td>Daha düşük</td>
      <td>Bellek bozulması mümkün</td>
    </tr>
    <tr>
      <td>Tipik kullanım</td>
      <td>İş uygulamaları</td>
      <td>Yerel API, medya, oyun, optimizasyon</td>
    </tr>
  </tbody>
</table>

<h2 id="unsafe-kodu-etkinleştirme">Unsafe kodu etkinleştirme</h2>

<p>Önce proje dosyasına aşağıdaki ayar eklenir:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;PropertyGroup&gt;</span>
  <span class="nt">&lt;AllowUnsafeBlocks&gt;</span>true<span class="nt">&lt;/AllowUnsafeBlocks&gt;</span>
<span class="nt">&lt;/PropertyGroup&gt;</span>
</code></pre></div></div>

<p>Visual Studio kullanılıyorsa aynı seçenek proje özelliklerindeki <strong>Build &gt; Allow code that uses the unsafe keyword</strong> alanından etkinleştirilebilir. Ardından yalnızca gerekli metot veya blok <code class="language-plaintext highlighter-rouge">unsafe</code> olarak işaretlenmelidir; tüm sınıfı tehlike bölgesine çevirmek şart değildir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">unsafe</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">DegeriDegistir</span><span class="p">()</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">sayi</span> <span class="p">=</span> <span class="m">10</span><span class="p">;</span>
    <span class="kt">int</span><span class="p">*</span> <span class="n">adres</span> <span class="p">=</span> <span class="p">&amp;</span><span class="n">sayi</span><span class="p">;</span>

    <span class="p">*</span><span class="n">adres</span> <span class="p">=</span> <span class="m">42</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="n">sayi</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">&amp;sayi</code>, değişkenin adresini alır. <code class="language-plaintext highlighter-rouge">*adres</code> ise o adresteki değere erişir; buna <strong>dereference</strong> işlemi denir. Sonuç <code class="language-plaintext highlighter-rouge">42</code> olur. Yanlış veya artık geçerli olmayan bir adres kullanılırsa çalışma zamanı her zaman sizi kurtaramaz.</p>

<h2 id="gc-hareketine-karşı-fixed">GC hareketine karşı <code class="language-plaintext highlighter-rouge">fixed</code></h2>

<p>Çöp toplayıcı, belleği sıkıştırırken yönetilen nesnelerin yerini değiştirebilir. Bir dizi işaretçiyle işlenirken taşınırsa işaretçi eski adresi göstermeye devam eder. <code class="language-plaintext highlighter-rouge">fixed</code>, nesneyi blok süresince yerine sabitler:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">unsafe</span> <span class="k">static</span> <span class="kt">int</span> <span class="nf">Topla</span><span class="p">(</span><span class="kt">int</span><span class="p">[]</span> <span class="n">sayilar</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">toplam</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>

    <span class="k">fixed</span> <span class="p">(</span><span class="kt">int</span><span class="p">*</span> <span class="n">baslangic</span> <span class="p">=</span> <span class="n">sayilar</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">sayilar</span><span class="p">.</span><span class="n">Length</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
            <span class="n">toplam</span> <span class="p">+=</span> <span class="p">*(</span><span class="n">baslangic</span> <span class="p">+</span> <span class="n">i</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">toplam</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu kod dizinin başlangıç adresini alır ve işaretçi aritmetiğiyle elemanları gezer. <code class="language-plaintext highlighter-rouge">fixed</code> blokları kısa tutulmalıdır; uzun süre sabitlenen nesneler çöp toplayıcının belleği verimli düzenlemesini zorlaştırabilir.</p>

<h2 id="stackalloc-ve-modern-alternatifler"><code class="language-plaintext highlighter-rouge">stackalloc</code> ve modern alternatifler</h2>

<p>Küçük, geçici tamponlar yığında oluşturulabilir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">unsafe</span> <span class="k">static</span> <span class="kt">int</span> <span class="nf">KarelerToplami</span><span class="p">(</span><span class="kt">int</span> <span class="n">adet</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">int</span><span class="p">*</span> <span class="n">tampon</span> <span class="p">=</span> <span class="k">stackalloc</span> <span class="kt">int</span><span class="p">[</span><span class="n">adet</span><span class="p">];</span>
    <span class="kt">int</span> <span class="n">toplam</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">adet</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
    <span class="p">{</span>
        <span class="n">tampon</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">=</span> <span class="n">i</span> <span class="p">*</span> <span class="n">i</span><span class="p">;</span>
        <span class="n">toplam</span> <span class="p">+=</span> <span class="n">tampon</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">toplam</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">stackalloc</code>, çöp toplayıcıya yük bindirmez; ancak yığın kapasitesi sınırlıdır. Büyük veya kullanıcı tarafından kontrol edilen boyutlar yığın taşmasına yol açabilir. Ayrıca pek çok senaryoda <code class="language-plaintext highlighter-rouge">Span&lt;T&gt;</code> aynı performans hedefini daha güvenli sınır kontrolleriyle karşılar.</p>

<table>
  <thead>
    <tr>
      <th>Araç</th>
      <th style="text-align: right">Güvenlik</th>
      <th>Uygun senaryo</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Dizi</td>
      <td style="text-align: right">Yüksek</td>
      <td>Genel amaçlı veri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Span&lt;T&gt;</code></td>
      <td style="text-align: right">Yüksek</td>
      <td>Hızlı dilimleme ve tamponlar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">stackalloc</code></td>
      <td style="text-align: right">Orta</td>
      <td>Küçük, kısa ömürlü tampon</td>
    </tr>
    <tr>
      <td>Ham işaretçi</td>
      <td style="text-align: right">Düşük</td>
      <td>Yerel API ve özel optimizasyon</td>
    </tr>
  </tbody>
</table>

<p>Unsafe kod otomatik olarak daha hızlı değildir. JIT derleyicisi güvenli kodu zaten güçlü biçimde optimize eder. Önce BenchmarkDotNet gibi araçlarla ölçüm yapılmalı, darboğaz kanıtlanmalı ve yalnızca kritik bölüm unsafe hâle getirilmelidir. Kural basit: Ölçmeden işaretçiye sarılmayın; kullandığınızda adresleri, sınırları ve nesne ömürlerini titizlikle yönetin.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="unsafe" /><category term="işaretçiler" /><category term="bellek-yönetimi" /><category term="performans" /><category term="dotnet" /><summary type="html"><![CDATA[C# çoğunlukla güvenli ve yönetilen bir dünyada çalışır: Belleği çöp toplayıcı düzenler, dizilerin sınırları denetlenir ve geliştirici adres hesaplarıyla uğraşmaz. Ancak görüntü işleme, oyun motorları, yerel kütüphane entegrasyonu veya çok düşük gecikmeli sistemler söz konusu olduğunda bu konforun küçük bir performans maliyeti olabilir. unsafe kod, C# geliştiricisine C++ benzeri işaretçilerle belleğe doğrudan erişim imkânı verir. Güçlüdür; fakat emniyet kemerini çıkarmaya benzediği için dikkatli kullanılmalıdır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-unsafe-kod-73.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-unsafe-kod-73.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Cerrahın Parmak Ucunu Uzaklara Taşımak: Haptik Cerrahi Robotlar</title><link href="https://program.sonsuz.us/posts/cerrahin-parmak-ucunu-uzaklara-tasimak-haptik-cerrahi-robotlar/" rel="alternate" type="text/html" title="Cerrahın Parmak Ucunu Uzaklara Taşımak: Haptik Cerrahi Robotlar" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/cerrahin-parmak-ucunu-uzaklara-tasimak-haptik-cerrahi-robotlar</id><content type="html" xml:base="https://program.sonsuz.us/posts/cerrahin-parmak-ucunu-uzaklara-tasimak-haptik-cerrahi-robotlar/"><![CDATA[<p>Bir üzümü kabuğunu yırtmadan soymaya çalıştığınızı düşünün; şimdi bunu milimetrik damarların arasında, robot kollarıyla ve ekrana bakarak yaptığınızı hayal edin. Robotik cerrahi yüksek çözünürlüklü görüntü ve hassas hareket kontrolü sağlasa da cerrahın doğal bir yeteneğini sınırlayabilir: dokunmayı. Haptik geri bildirim, robotun karşılaştığı kuvvetleri cerrahın ellerine aktararak bu eksik halkayı tamamlamayı amaçlar.</p>

<p>``</p>

<h2 id="haptik-geri-bildirim-nasıl-çalışır">Haptik geri bildirim nasıl çalışır?</h2>

<p>Haptik cerrahi sistem, temelde çift yönlü bir iletişim döngüsüdür. Cerrah ana kontrol kollarını hareket ettirir; robot bu komutları hastanın yanındaki aletlere iletir. Alet uçlarındaki kuvvet ve tork sensörleri dokuyla etkileşimi ölçer. Ölçülen veriler, motorlar aracılığıyla kontrol kollarında direnç veya titreşim olarak yeniden üretilir.</p>

<p>Bu süreç üç temel bileşene dayanır:</p>

<ol>
  <li><strong>Algılama:</strong> Kuvvet, basınç, titreşim ve doku deformasyonu ölçülür.</li>
  <li><strong>İletim:</strong> Veriler düşük gecikmeyle kontrol konsoluna taşınır.</li>
  <li><strong>Yeniden üretim:</strong> Cerrahın eline kontrollü bir mekanik tepki uygulanır.</li>
</ol>

<p>İdeal durumda cerrah, sert bir tümör dokusuyla yumuşak çevre dokusu arasındaki farkı yalnızca görüntüden değil, elindeki dirençten de anlayabilir. Sistem adeta robot koluna görünmez sinir uçları ekler.</p>

<h2 id="kuvvet-ölçekleme-ve-hareket-filtreleme">Kuvvet ölçekleme ve hareket filtreleme</h2>

<p>Robotun hissettiği kuvvetin cerraha bire bir aktarılması her zaman güvenli değildir. Bunun yerine kuvvet ölçekleme uygulanır:</p>

\[F_{el} = kF_{doku}\]

<p>Burada $F_{doku}$ robot ucunun ölçtüğü kuvveti, $F_{el}$ cerraha uygulanan geri bildirimi, $k$ ise ölçekleme katsayısını gösterir. Örneğin $k=0.4$ seçildiğinde 5 newtonluk temas, cerraha 2 newton olarak hissettirilir. Böylece bilgi korunurken yorulma ve ani tepki riski azaltılabilir.</p>

<p>Aynı sistem cerrahın el titremesini de filtreleyebilir. İnsan elindeki küçük, istemsiz hareketler yazılımla bastırılırken bilinçli hareketler küçültülerek robot ucuna aktarılır. Cerrah kontrol kolunu 10 milimetre hareket ettirdiğinde aletin yalnızca 1 milimetre ilerlemesi mümkün olabilir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Görsel geri bildirim</th>
      <th>Haptik geri bildirim</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Doku sertliğini algılama</td>
      <td>Dolaylı</td>
      <td>Doğrudan kuvvet hissiyle</td>
    </tr>
    <tr>
      <td>Aşırı baskıyı fark etme</td>
      <td>Görüntüde deformasyon gerekir</td>
      <td>Direnç anında hissedilebilir</td>
    </tr>
    <tr>
      <td>Öğrenme biçimi</td>
      <td>Göz-el koordinasyonu</td>
      <td>Göz-el-dokunma koordinasyonu</td>
    </tr>
    <tr>
      <td>Temel sınırlama</td>
      <td>Derinlik ve görüntü kalitesi</td>
      <td>Sensör doğruluğu ve gecikme</td>
    </tr>
  </tbody>
</table>

<h2 id="hassas-operasyonlardaki-rolü">Hassas operasyonlardaki rolü</h2>

<p>Haptik geri bildirim özellikle mikrocerrahi, beyin cerrahisi, damar onarımı ve hassas dikiş işlemlerinde değerlidir. İnce bir damarı tutarken fazla kuvvet uygulamak dokuyu zedeleyebilir; yetersiz kuvvet ise iğnenin veya dokunun kaymasına neden olabilir. Ölçülebilir kuvvet sınırları, cerrahı tehlikeli bölgeye yaklaşırken uyarabilir.</p>

<p>Basitleştirilmiş bir güvenlik denetimi şöyle modellenebilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">haptik_uyari</span><span class="p">(</span><span class="n">olculen_kuvvet</span><span class="p">,</span> <span class="n">guvenli_sinir</span><span class="p">):</span>
    <span class="n">oran</span> <span class="o">=</span> <span class="n">olculen_kuvvet</span> <span class="o">/</span> <span class="n">guvenli_sinir</span>

    <span class="k">if</span> <span class="n">oran</span> <span class="o">&gt;=</span> <span class="mf">1.0</span><span class="p">:</span>
        <span class="k">return</span> <span class="sh">'</span><span class="s">hareketi durdur ve güçlü titreşim üret</span><span class="sh">'</span>
    <span class="k">elif</span> <span class="n">oran</span> <span class="o">&gt;=</span> <span class="mf">0.8</span><span class="p">:</span>
        <span class="k">return</span> <span class="sh">'</span><span class="s">kontrol kolundaki direnci artır</span><span class="sh">'</span>
    <span class="k">return</span> <span class="sh">'</span><span class="s">normal geri bildirim uygula</span><span class="sh">'</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">haptik_uyari</span><span class="p">(</span><span class="mf">1.7</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">))</span>
</code></pre></div></div>

<p>Bu örnek, ölçülen kuvvet güvenli sınırın yüzde 80’ine ulaştığında direnci artırır. Gerçek sistemlerde kararlar çok daha yüksek frekansta alınır; sensör birleştirme, mekanik modeller ve hata toleranslı kontrol algoritmaları kullanılır.</p>

<h2 id="her-dokunuş-kusursuz-mu">Her dokunuş kusursuz mu?</h2>

<p>Henüz değil. İletişim gecikmesi, sensör gürültüsü, sterilizasyon gereksinimleri ve çok küçük kuvvetlerin doğru ölçülmesi önemli mühendislik problemleridir. Gecikmiş geri bildirim, cerrahın gerçekte sona ermiş bir teması hâlâ hissediyormuş gibi tepki vermesine yol açabilir. Bu nedenle kararlı bir kontrol döngüsü, yalnızca güçlü motorlardan değil, doğru zamanlama ve güvenilir yazılımdan doğar.</p>

<p>Gelecekte yapay zekâ, farklı dokuların haptik imzalarını sınıflandırarak cerraha ek uyarılar sunabilir. Ancak amaç cerrahın kararını devralmak değil, görüşüne güvenilir bir dokunma kanalı eklemektir. Kısacası haptik cerrahi robotlar, robotu daha kuvvetli değil, daha ölçülü ve daha hissedebilir hâle getirir.</p>

<p><img src="/img/cerrahin-parmak-ucunu-27.svg" alt="cerrahin-parmak-ucunu-27" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="robotik" /><category term="haptik" /><category term="cerrahi robotlar" /><category term="biyomedikal" /><category term="yapay zeka" /><category term="sağlık teknolojileri" /><summary type="html"><![CDATA[Bir üzümü kabuğunu yırtmadan soymaya çalıştığınızı düşünün; şimdi bunu milimetrik damarların arasında, robot kollarıyla ve ekrana bakarak yaptığınızı hayal edin. Robotik cerrahi yüksek çözünürlüklü görüntü ve hassas hareket kontrolü sağlasa da cerrahın doğal bir yeteneğini sınırlayabilir: dokunmayı. Haptik geri bildirim, robotun karşılaştığı kuvvetleri cerrahın ellerine aktararak bu eksik halkayı tamamlamayı amaçlar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/cerrahin-parmak-ucunu-27.png" /><media:content medium="image" url="https://program.sonsuz.us/img/cerrahin-parmak-ucunu-27.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Eklem Sınırları Robotu Tekilliğe Nasıl Sürükler?</title><link href="https://program.sonsuz.us/posts/eklem-sinirlari-robotu-tekillige-nasil-surukler/" rel="alternate" type="text/html" title="Eklem Sınırları Robotu Tekilliğe Nasıl Sürükler?" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/eklem-sinirlari-robotu-tekillige-nasil-surukler</id><content type="html" xml:base="https://program.sonsuz.us/posts/eklem-sinirlari-robotu-tekillige-nasil-surukler/"><![CDATA[<p>Bir robot kolu hedefe giderken yalnızca “Nereye ulaşmalıyım?” sorusunu sormaz; eklemlerinin ne kadar dönebileceğini de hesaba katmak zorundadır. Yörünge geometrik olarak kusursuz görünse bile eklem sınırları alternatif hareketleri kapatarak robotu tekil veya tekilliğe çok yakın bir konfigürasyona zorlayabilir. Sonuçta hızların büyüdüğü, kontrolün zorlaştığı ve robotun dramatik biçimde “Ben buradan dönemiyorum!” dediği bir durum ortaya çıkar.</p>

<p><img src="/img/eklem-sinirlari-robotu-40.svg" alt="eklem-sinirlari-robotu-40" /></p>

<p>``</p>

<h2 id="eklem-sınırı-ile-tekillik-aynı-şey-mi">Eklem sınırı ile tekillik aynı şey mi?</h2>

<p>Hayır. Eklem sınırı, bir eklemin izin verilen konum aralığıdır:</p>

\[q_i^{\min} \le q_i \le q_i^{\max}\]

<p>Tekillik ise robotun Jacobian matrisinin rank kaybettiği konfigürasyondur. Uç efektör hızı ile eklem hızları arasındaki ilişki</p>

\[\dot{x}=J(q)\dot{q}\]

<p>şeklindedir. Kare bir Jacobian için $\det(J)=0$ olduğunda matematiksel tekillik oluşur. Kare olmayan sistemlerde en küçük tekil değer $\sigma_{\min}$ sıfıra yaklaştıkça tekillik riski artar.</p>

<p>Eklem sınırı doğrudan Jacobian’ı tekil yapmaz. Ancak planlayıcının kullanabileceği konfigürasyon uzayını daraltır. Normalde robot, tekil bölgenin çevresinden farklı bir dirsek veya bilek duruşuyla dolaşabilir. Bu alternatif eklem sınırını aşıyorsa planlayıcı tekilliğe yakın rotayı seçmek zorunda kalabilir.</p>

<table>
  <thead>
    <tr>
      <th>Durum</th>
      <th>Matematiksel gösterge</th>
      <th>Pratik sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Eklem sınırı</td>
      <td>$q_i \approx q_i^{\min}$ veya $q_i^{\max}$</td>
      <td>Hareket seçeneği azalır</td>
    </tr>
    <tr>
      <td>Tekillik</td>
      <td>$\sigma_{\min}(J) \approx 0$</td>
      <td>Eklem hızları büyür</td>
    </tr>
    <tr>
      <td>İkisi birlikte</td>
      <td>Dar uygulanabilir bölge ve kötü Jacobian</td>
      <td>Planlama ya başarısız olur ya da riskli yol üretir</td>
    </tr>
  </tbody>
</table>

<h2 id="yörünge-neden-tehlikeli-hâle-gelir">Yörünge neden tehlikeli hâle gelir?</h2>

<p>Ters hız kinematiğinde genellikle</p>

\[\dot{q}=J^{\dagger}(q)\dot{x}\]

<p>kullanılır. Tekilliğe yaklaşırken sözde ters $J^{\dagger}$ çok büyük değerler üretebilir. Robot küçük bir Kartezyen hız için bile aşırı eklem hızı ister. İstenen kaçış yönü eklem sınırı tarafından engelleniyorsa durum daha da kötüleşir.</p>

<p>Örneğin altı eksenli bir kolun bilek eklemi üst sınıra dayanmış olsun. Uç efektör yönelimini korumak için aynı hareketi başka eklemler paylaşabilir; fakat kol tamamen uzanmışsa Jacobian da rank kaybedebilir. Böylece hem hareket serbestliği azalır hem de sayısal çözüm kararsızlaşır.</p>

<h2 id="planlayıcı-bunu-nasıl-fark-eder">Planlayıcı bunu nasıl fark eder?</h2>

<p>Manipülebilirlik ölçütü yaygın bir erken uyarıdır:</p>

\[w(q)=\sqrt{\det(JJ^T)}\]

<p>$w(q)$ küçüldükçe robot tekilliğe yaklaşır. Eklem sınırına yakınlık için ayrıca ceza fonksiyonu tanımlanabilir:</p>

\[C_{limit}(q)=\sum_i \left(\frac{q_i-q_i^{mid}}{q_i^{max}-q_i^{min}}\right)^2\]

<p>Aşağıdaki Python kodu, bir aday konfigürasyonun en küçük tekil değerini ve eklem sınırı cezasını hesaplar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>

<span class="k">def</span> <span class="nf">trajectory_cost</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">q_min</span><span class="p">,</span> <span class="n">q_max</span><span class="p">):</span>
    <span class="c1"># Küçük sigma, tekilliğe yakınlığı gösterir.
</span>    <span class="n">sigma_min</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="nf">svd</span><span class="p">(</span><span class="n">J</span><span class="p">,</span> <span class="n">compute_uv</span><span class="o">=</span><span class="bp">False</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>

    <span class="c1"># Eklem aralığının merkezinden uzaklaşmayı cezalandırır.
</span>    <span class="n">q_mid</span> <span class="o">=</span> <span class="p">(</span><span class="n">q_min</span> <span class="o">+</span> <span class="n">q_max</span><span class="p">)</span> <span class="o">/</span> <span class="mf">2.0</span>
    <span class="n">span</span> <span class="o">=</span> <span class="n">q_max</span> <span class="o">-</span> <span class="n">q_min</span>
    <span class="n">limit_cost</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(((</span><span class="n">q</span> <span class="o">-</span> <span class="n">q_mid</span><span class="p">)</span> <span class="o">/</span> <span class="n">span</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span>

    <span class="n">singularity_cost</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">/</span> <span class="p">(</span><span class="n">sigma_min</span> <span class="o">+</span> <span class="mf">1e-4</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">singularity_cost</span> <span class="o">+</span> <span class="mf">2.0</span> <span class="o">*</span> <span class="n">limit_cost</span>
</code></pre></div></div>

<p>Bu maliyet, RRT*, CHOMP veya optimizasyon tabanlı planlayıcılarda aday yolları karşılaştırmak için kullanılabilir. Katsayılar robotun hız, güvenlik ve görev önceliklerine göre ayarlanmalıdır.</p>

<h2 id="kaçınma-stratejileri">Kaçınma stratejileri</h2>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Avantaj</th>
      <th>Sınırlama</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sönümlü en küçük kareler</td>
      <td>Tekillikte hız patlamasını azaltır</td>
      <td>Kartezyen hata oluşturabilir</td>
    </tr>
    <tr>
      <td>Null-space hareketi</td>
      <td>Fazladan serbestliği eklem merkezleme için kullanır</td>
      <td>Redundant robot gerektirir</td>
    </tr>
    <tr>
      <td>Tekillik maliyeti</td>
      <td>Riskli bölgeleri önceden dışlar</td>
      <td>Optimizasyonu zorlaştırabilir</td>
    </tr>
    <tr>
      <td>Yeniden yol planlama</td>
      <td>Alternatif dirsek ve bilek duruşu bulur</td>
      <td>Hesaplama süresini artırır</td>
    </tr>
  </tbody>
</table>

<p>Özetle eklem sınırları tekilliğin matematiksel sebebi değildir; fakat güvenli kaçış yollarını kapatan güçlü bir tetikleyicidir. Sağlam bir planlayıcı konum sınırlarını, Jacobian kondisyonunu, hız limitlerini ve alternatif kinematik dalları birlikte değerlendirmelidir. Robotun hedefe ulaşması yetmez; hedefe eklemlerini düğüm yapmadan ulaşması gerekir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="robotik" /><category term="yörünge-planlama" /><category term="tekillik" /><category term="eklem-sınırları" /><category term="jacobian" /><category term="kinematik" /><summary type="html"><![CDATA[Bir robot kolu hedefe giderken yalnızca “Nereye ulaşmalıyım?” sorusunu sormaz; eklemlerinin ne kadar dönebileceğini de hesaba katmak zorundadır. Yörünge geometrik olarak kusursuz görünse bile eklem sınırları alternatif hareketleri kapatarak robotu tekil veya tekilliğe çok yakın bir konfigürasyona zorlayabilir. Sonuçta hızların büyüdüğü, kontrolün zorlaştığı ve robotun dramatik biçimde “Ben buradan dönemiyorum!” dediği bir durum ortaya çıkar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/eklem-sinirlari-robotu-40.png" /><media:content medium="image" url="https://program.sonsuz.us/img/eklem-sinirlari-robotu-40.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Java Collections Framework: List, Set ve Map ile Veriyi Dizginlemek</title><link href="https://program.sonsuz.us/posts/java-collections-framework-list-set-ve-map-ile-veriyi-dizginlemek/" rel="alternate" type="text/html" title="Java Collections Framework: List, Set ve Map ile Veriyi Dizginlemek" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/java-collections-framework-list-set-ve-map-ile-veriyi-dizginlemek</id><content type="html" xml:base="https://program.sonsuz.us/posts/java-collections-framework-list-set-ve-map-ile-veriyi-dizginlemek/"><![CDATA[<p>Bir uygulamada verileri saklamak kolaydır; onları doğru sırada tutmak, tekrarları engellemek ve hızlıca bulmak ise asıl meseledir. Java Collections Framework, bu ihtiyaçlar için <code class="language-plaintext highlighter-rouge">List</code>, <code class="language-plaintext highlighter-rouge">Set</code> ve <code class="language-plaintext highlighter-rouge">Map</code> gibi hazır veri yapıları sunar. Böylece tekerleği yeniden icat etmek yerine doğru koleksiyonu seçip iş mantığına odaklanabiliriz.</p>

<p><img src="/img/java-collections-framework-11.svg" alt="java-collections-framework-11" /></p>

<p>``</p>

<h2 id="collections-framework-nedir">Collections Framework nedir?</h2>

<p>Collections Framework; veri yapılarından, bunlarla çalışan arayüzlerden ve yardımcı algoritmalardan oluşan standart bir Java API’sidir. Hiyerarşinin merkezinde <code class="language-plaintext highlighter-rouge">Collection&lt;E&gt;</code> arayüzü bulunur. <code class="language-plaintext highlighter-rouge">List&lt;E&gt;</code> ve <code class="language-plaintext highlighter-rouge">Set&lt;E&gt;</code> bu arayüzden türetilirken <code class="language-plaintext highlighter-rouge">Map&lt;K, V&gt;</code>, anahtar-değer modeli nedeniyle ayrı bir hiyerarşide yer alır.</p>

<p>Buradaki <code class="language-plaintext highlighter-rouge">E</code>, koleksiyonda saklanan elemanın türünü belirten generic parametredir. Örneğin <code class="language-plaintext highlighter-rouge">List&lt;String&gt;</code>, yalnızca metin saklamayı amaçlar. Bu yaklaşım çalışma zamanında ortaya çıkabilecek tür hatalarını derleme aşamasına taşır.</p>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>Sıralama</th>
      <th>Tekrar</th>
      <th>Erişim biçimi</th>
      <th>Tipik kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">List</code></td>
      <td>Korunur</td>
      <td>İzin verilir</td>
      <td>İndeks</td>
      <td>Alışveriş sepeti</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Set</code></td>
      <td>Uygulamaya bağlı</td>
      <td>Engellenir</td>
      <td>Eleman</td>
      <td>Benzersiz kullanıcılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Map</code></td>
      <td>Uygulamaya bağlı</td>
      <td>Anahtarlar benzersizdir</td>
      <td>Anahtar</td>
      <td>Kimlikten kayıt bulma</td>
    </tr>
  </tbody>
</table>

<h2 id="list-sıralı-veri-dünyası">List: Sıralı veri dünyası</h2>

<p><code class="language-plaintext highlighter-rouge">List</code>, elemanların eklenme sırasını korur ve aynı değerin birden fazla kez bulunmasına izin verir. En yaygın uygulaması <code class="language-plaintext highlighter-rouge">ArrayList</code> sınıfıdır. İndeksle erişim ortalama $O(1)$ zaman karmaşıklığına sahiptir. Ancak listenin ortasına eleman eklemek, sonraki elemanların kaydırılmasını gerektirdiğinden $O(n)$ olabilir.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">diller</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;();</span>
<span class="n">diller</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Java"</span><span class="o">);</span>
<span class="n">diller</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Python"</span><span class="o">);</span>
<span class="n">diller</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Java"</span><span class="o">);</span>

<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">diller</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">));</span> <span class="c1">// Java</span>
<span class="n">diller</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="s">"Python"</span><span class="o">);</span>
</code></pre></div></div>

<p>Bu kod sıralı bir dil listesi oluşturur. İkinci <code class="language-plaintext highlighter-rouge">Java</code> kabul edilir çünkü <code class="language-plaintext highlighter-rouge">List</code> tekrarları yasaklamaz. Sıkça baştan veya ortadan ekleme yapılacaksa bağlantılı düğümler kullanan <code class="language-plaintext highlighter-rouge">LinkedList</code> düşünülebilir; fakat çoğu genel senaryoda <code class="language-plaintext highlighter-rouge">ArrayList</code> daha iyi başlangıç seçimidir.</p>

<h2 id="set-tekrarlara-geçit-yok">Set: Tekrarlara geçit yok</h2>

<p><code class="language-plaintext highlighter-rouge">Set</code>, her elemanın yalnızca bir kez bulunmasını sağlar. <code class="language-plaintext highlighter-rouge">HashSet</code>, elemanları hash değerleri üzerinden yönetir ve ekleme, silme, arama işlemlerinde ortalama $O(1)$ performans sunar.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Set</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">roller</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HashSet</span><span class="o">&lt;&gt;();</span>
<span class="n">roller</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"admin"</span><span class="o">);</span>
<span class="n">roller</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"editor"</span><span class="o">);</span>
<span class="n">roller</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"admin"</span><span class="o">);</span>

<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">roller</span><span class="o">.</span><span class="na">size</span><span class="o">());</span> <span class="c1">// 2</span>
</code></pre></div></div>

<p>İkinci <code class="language-plaintext highlighter-rouge">admin</code> eklenmez. Ekleme sırası önemliyse <code class="language-plaintext highlighter-rouge">LinkedHashSet</code>, elemanların doğal veya özel bir kurala göre sıralanması gerekiyorsa <code class="language-plaintext highlighter-rouge">TreeSet</code> kullanılabilir. <code class="language-plaintext highlighter-rouge">TreeSet</code> işlemleri dengeli ağaç yapısı nedeniyle genellikle $O(\log n)$ maliyetindedir.</p>

<h2 id="map-anahtarı-ver-değeri-al">Map: Anahtarı ver, değeri al</h2>

<p><code class="language-plaintext highlighter-rouge">Map</code>, verileri anahtar-değer çiftleri hâlinde saklar. Telefon rehberindeki isim-numara ilişkisi buna güzel bir örnektir. <code class="language-plaintext highlighter-rouge">HashMap</code>, benzersiz anahtarlar kullanır; aynı anahtarla yeniden değer eklenirse eski değer güncellenir.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Map</span><span class="o">&lt;</span><span class="nc">Integer</span><span class="o">,</span> <span class="nc">String</span><span class="o">&gt;</span> <span class="n">kullanicilar</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HashMap</span><span class="o">&lt;&gt;();</span>
<span class="n">kullanicilar</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="mi">101</span><span class="o">,</span> <span class="s">"Ayşe"</span><span class="o">);</span>
<span class="n">kullanicilar</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="mi">102</span><span class="o">,</span> <span class="s">"Mert"</span><span class="o">);</span>
<span class="n">kullanicilar</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="mi">101</span><span class="o">,</span> <span class="s">"Deniz"</span><span class="o">);</span>

<span class="nc">String</span> <span class="n">ad</span> <span class="o">=</span> <span class="n">kullanicilar</span><span class="o">.</span><span class="na">getOrDefault</span><span class="o">(</span><span class="mi">101</span><span class="o">,</span> <span class="s">"Bulunamadı"</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ad</span><span class="o">);</span> <span class="c1">// Deniz</span>
</code></pre></div></div>

<p>Harita üzerinde güvenli dolaşmak için <code class="language-plaintext highlighter-rouge">entrySet()</code> kullanılabilir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="o">(</span><span class="nc">Map</span><span class="o">.</span><span class="na">Entry</span><span class="o">&lt;</span><span class="nc">Integer</span><span class="o">,</span> <span class="nc">String</span><span class="o">&gt;</span> <span class="n">kayit</span> <span class="o">:</span> <span class="n">kullanicilar</span><span class="o">.</span><span class="na">entrySet</span><span class="o">())</span> <span class="o">{</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">kayit</span><span class="o">.</span><span class="na">getKey</span><span class="o">()</span> <span class="o">+</span> <span class="s">": "</span> <span class="o">+</span> <span class="n">kayit</span><span class="o">.</span><span class="na">getValue</span><span class="o">());</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="yardımcı-işlemler-ve-doğru-seçim">Yardımcı işlemler ve doğru seçim</h2>

<p><code class="language-plaintext highlighter-rouge">Collections</code> yardımcı sınıfı; sıralama, ters çevirme ve en küçük elemanı bulma gibi algoritmalar sağlar.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">List</span><span class="o">&lt;</span><span class="nc">Integer</span><span class="o">&gt;</span> <span class="n">puanlar</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;&gt;(</span><span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="mi">70</span><span class="o">,</span> <span class="mi">95</span><span class="o">,</span> <span class="mi">82</span><span class="o">));</span>
<span class="nc">Collections</span><span class="o">.</span><span class="na">sort</span><span class="o">(</span><span class="n">puanlar</span><span class="o">);</span>
<span class="nc">Collections</span><span class="o">.</span><span class="na">reverse</span><span class="o">(</span><span class="n">puanlar</span><span class="o">);</span>
</code></pre></div></div>

<p>Seçim kuralı basittir: Konum ve sıra önemliyse <code class="language-plaintext highlighter-rouge">List</code>, benzersizlik önemliyse <code class="language-plaintext highlighter-rouge">Set</code>, bir anahtardan değere ulaşılacaksa <code class="language-plaintext highlighter-rouge">Map</code> kullanılır. Ayrıca <code class="language-plaintext highlighter-rouge">HashMap</code> ve <code class="language-plaintext highlighter-rouge">HashSet</code> içinde özel nesneler saklanırken <code class="language-plaintext highlighter-rouge">equals()</code> ile <code class="language-plaintext highlighter-rouge">hashCode()</code> metotlarının tutarlı tanımlanması gerekir. Eşit kabul edilen iki nesne için şu ilişki korunmalıdır: $a.equals(b) \Rightarrow a.hashCode() = b.hashCode()$. Doğru koleksiyon seçimi hem kodu okunabilir kılar hem de uygulamanın gereksiz yere kaplumbağa moduna geçmesini engeller.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="java" /><category term="collections" /><category term="list" /><category term="set" /><category term="map" /><category term="veri-yapıları" /><summary type="html"><![CDATA[Bir uygulamada verileri saklamak kolaydır; onları doğru sırada tutmak, tekrarları engellemek ve hızlıca bulmak ise asıl meseledir. Java Collections Framework, bu ihtiyaçlar için List, Set ve Map gibi hazır veri yapıları sunar. Böylece tekerleği yeniden icat etmek yerine doğru koleksiyonu seçip iş mantığına odaklanabiliriz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/java-collections-framework-11.png" /><media:content medium="image" url="https://program.sonsuz.us/img/java-collections-framework-11.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Java Lambda İfadeleri: Anonim Davranışları Arayüzlere Bağlamak</title><link href="https://program.sonsuz.us/posts/java-lambda-ifadeleri-anonim-davranislari-arayuzlere-baglamak/" rel="alternate" type="text/html" title="Java Lambda İfadeleri: Anonim Davranışları Arayüzlere Bağlamak" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/java-lambda-ifadeleri-anonim-davranislari-arayuzlere-baglamak</id><content type="html" xml:base="https://program.sonsuz.us/posts/java-lambda-ifadeleri-anonim-davranislari-arayuzlere-baglamak/"><![CDATA[<p>Java 8 ile hayatımıza giren lambda ifadeleri, davranışı veri gibi taşımanın kısa ve güçlü bir yoludur. Başka bir deyişle, yalnızca değerleri değil, çalıştırılacak işlemleri de metotlara gönderebiliriz. Bu yaklaşım; tekrar eden kodu azaltır, koleksiyon işlemlerini okunabilir hâle getirir ve Java’ya fonksiyonel programlama dünyasından kullanışlı araçlar kazandırır.</p>

<p>``</p>

<h2 id="lambda-ifadesinin-teorik-temeli">Lambda ifadesinin teorik temeli</h2>

<p>Klasik nesne yönelimli programlamada davranışlar genellikle sınıfların metotları içinde bulunur. Fonksiyonel yaklaşımda ise bir işlem, başka bir işleme parametre olarak aktarılabilir veya sonuç olarak döndürülebilir. Matematikteki bir fonksiyonu şöyle gösterebiliriz:</p>

\[f(x) = x \times 2\]

<p>Java’daki karşılığı <code class="language-plaintext highlighter-rouge">(x) -&gt; x * 2</code> biçiminde yazılabilir. Burada sol taraf parametreleri, <code class="language-plaintext highlighter-rouge">-&gt;</code> operatörü bağlantıyı, sağ taraf ise çalıştırılacak gövdeyi temsil eder.</p>

<p>Genel lambda söz dizimi şöyledir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">(</span><span class="n">parametreler</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">ifade</span>
</code></pre></div></div>

<p>Birden fazla komut varsa süslü parantez ve gerektiğinde <code class="language-plaintext highlighter-rouge">return</code> kullanılır:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="n">toplam</span> <span class="o">=</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="o">;</span>
    <span class="k">return</span> <span class="n">toplam</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Lambda kendi başına havada duran isimsiz bir metot değildir. Java, lambdanın hangi parametreleri alacağını ve hangi türü döndüreceğini bir <strong>fonksiyonel arayüzün</strong> tek soyut metodundan öğrenir. Bu ilişkiye hedef tipleme denir.</p>

<h2 id="fonksiyonel-arayüz-nedir">Fonksiyonel arayüz nedir?</h2>

<p>Yalnızca bir soyut metoda sahip arayüzler fonksiyonel arayüz olarak kullanılabilir. <code class="language-plaintext highlighter-rouge">@FunctionalInterface</code> zorunlu değildir; ancak yanlışlıkla ikinci bir soyut metot eklenmesini engellediği için önerilir.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@FunctionalInterface</span>
<span class="kd">interface</span> <span class="nc">Hesaplayici</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="nf">hesapla</span><span class="o">(</span><span class="kt">int</span> <span class="n">a</span><span class="o">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Bu arayüze farklı davranışlar bağlayabiliriz:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Hesaplayici</span> <span class="n">topla</span> <span class="o">=</span> <span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="o">;</span>
<span class="nc">Hesaplayici</span> <span class="n">carp</span> <span class="o">=</span> <span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">a</span> <span class="o">*</span> <span class="n">b</span><span class="o">;</span>

<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">topla</span><span class="o">.</span><span class="na">hesapla</span><span class="o">(</span><span class="mi">4</span><span class="o">,</span> <span class="mi">3</span><span class="o">));</span> <span class="c1">// 7</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">carp</span><span class="o">.</span><span class="na">hesapla</span><span class="o">(</span><span class="mi">4</span><span class="o">,</span> <span class="mi">3</span><span class="o">));</span>  <span class="c1">// 12</span>
</code></pre></div></div>

<p>Aynı arayüz iki farklı algoritmayı temsil eder. Böylece “hangi işlem yapılacak?” kararı, işlemi kullanan koddan ayrılır.</p>

<h2 id="anonim-sınıf-ile-lambda-karşılaştırması">Anonim sınıf ile lambda karşılaştırması</h2>

<p>Lambda ifadelerinden önce aynı davranış çoğunlukla anonim sınıfla yazılırdı:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Hesaplayici</span> <span class="n">topla</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Hesaplayici</span><span class="o">()</span> <span class="o">{</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">hesapla</span><span class="o">(</span><span class="kt">int</span> <span class="n">a</span><span class="o">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">};</span>
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Anonim sınıf</th>
      <th>Lambda</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kod uzunluğu</td>
      <td>Daha fazla</td>
      <td>Daha kısa</td>
    </tr>
    <tr>
      <td>Hedef</td>
      <td>Sınıf veya arayüz</td>
      <td>Fonksiyonel arayüz</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">this</code> anlamı</td>
      <td>Anonim nesneyi gösterir</td>
      <td>Dış kapsamdaki nesneyi gösterir</td>
    </tr>
    <tr>
      <td>Okunabilirlik</td>
      <td>Basit işlemlerde düşük</td>
      <td>Küçük davranışlarda yüksek</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/java-lambda-ifadeleri-62.svg" alt="java-lambda-ifadeleri-62" /></p>

<p>Lambda her zaman daha iyi değildir. İşlem uzuyor, çok sayıda koşul içeriyor veya yeniden kullanılacak hâle geliyorsa isimlendirilmiş bir metot daha anlaşılır olabilir.</p>

<h2 id="hazır-fonksiyonel-arayüzler">Hazır fonksiyonel arayüzler</h2>

<p>Java, <code class="language-plaintext highlighter-rouge">java.util.function</code> paketinde sık kullanılan arayüzleri hazır sunar:</p>

<table>
  <thead>
    <tr>
      <th>Arayüz</th>
      <th style="text-align: right">Girdi</th>
      <th style="text-align: right">Çıktı</th>
      <th>Amaç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Predicate&lt;T&gt;</code></td>
      <td style="text-align: right"><code class="language-plaintext highlighter-rouge">T</code></td>
      <td style="text-align: right"><code class="language-plaintext highlighter-rouge">boolean</code></td>
      <td>Koşul sınamak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Function&lt;T, R&gt;</code></td>
      <td style="text-align: right"><code class="language-plaintext highlighter-rouge">T</code></td>
      <td style="text-align: right"><code class="language-plaintext highlighter-rouge">R</code></td>
      <td>Dönüştürmek</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Consumer&lt;T&gt;</code></td>
      <td style="text-align: right"><code class="language-plaintext highlighter-rouge">T</code></td>
      <td style="text-align: right">Yok</td>
      <td>Değeri tüketmek</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Supplier&lt;T&gt;</code></td>
      <td style="text-align: right">Yok</td>
      <td style="text-align: right"><code class="language-plaintext highlighter-rouge">T</code></td>
      <td>Değer üretmek</td>
    </tr>
  </tbody>
</table>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Predicate</span><span class="o">&lt;</span><span class="nc">Integer</span><span class="o">&gt;</span> <span class="n">ciftMi</span> <span class="o">=</span> <span class="n">sayi</span> <span class="o">-&gt;</span> <span class="n">sayi</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="o">;</span>
<span class="nc">Function</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Integer</span><span class="o">&gt;</span> <span class="n">uzunluk</span> <span class="o">=</span> <span class="n">metin</span> <span class="o">-&gt;</span> <span class="n">metin</span><span class="o">.</span><span class="na">length</span><span class="o">();</span>
<span class="nc">Consumer</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">yazdir</span> <span class="o">=</span> <span class="n">metin</span> <span class="o">-&gt;</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">metin</span><span class="o">);</span>
<span class="nc">Supplier</span><span class="o">&lt;</span><span class="nc">Double</span><span class="o">&gt;</span> <span class="n">rastgele</span> <span class="o">=</span> <span class="o">()</span> <span class="o">-&gt;</span> <span class="nc">Math</span><span class="o">.</span><span class="na">random</span><span class="o">();</span>
</code></pre></div></div>

<p>Örneğin çiftlik kontrolü matematiksel olarak $n \bmod 2 = 0$ koşuluna dayanır. <code class="language-plaintext highlighter-rouge">Predicate</code>, bu koşulu yeniden kullanılabilir bir davranışa dönüştürür.</p>

<h2 id="stream-api-ile-kullanım">Stream API ile kullanım</h2>

<p>Lambdaların en eğlenceli sahnesi Stream API’dir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">isimler</span> <span class="o">=</span> <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Ada"</span><span class="o">,</span> <span class="s">"Ahmet"</span><span class="o">,</span> <span class="s">"Ece"</span><span class="o">,</span> <span class="s">"Mehmet"</span><span class="o">);</span>

<span class="n">isimler</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
      <span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">isim</span> <span class="o">-&gt;</span> <span class="n">isim</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">&gt;=</span> <span class="mi">4</span><span class="o">)</span>
      <span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="nl">String:</span><span class="o">:</span><span class="n">toUpperCase</span><span class="o">)</span>
      <span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">);</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">filter</code> eleme, <code class="language-plaintext highlighter-rouge">map</code> dönüştürme, <code class="language-plaintext highlighter-rouge">forEach</code> ise sonuçları tüketme davranışını alır. <code class="language-plaintext highlighter-rouge">String::toUpperCase</code> bir metot referansıdır ve uygun lambda ifadesinin daha kısa gösterimidir.</p>

<p>Sonuç olarak lambda ifadeleri yalnızca sözdizimsel şeker değildir; davranışları arayüzler üzerinden aktararak gevşek bağlı, test edilebilir ve ifade gücü yüksek kod yazmamızı sağlar. Kısa işlemlerde lambda, karmaşık iş kurallarında ise anlamlı isimlere sahip metotlar kullanmak en dengeli yaklaşımdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="java" /><category term="lambda" /><category term="fonksiyonel programlama" /><category term="fonksiyonel arayüz" /><category term="stream api" /><summary type="html"><![CDATA[Java 8 ile hayatımıza giren lambda ifadeleri, davranışı veri gibi taşımanın kısa ve güçlü bir yoludur. Başka bir deyişle, yalnızca değerleri değil, çalıştırılacak işlemleri de metotlara gönderebiliriz. Bu yaklaşım; tekrar eden kodu azaltır, koleksiyon işlemlerini okunabilir hâle getirir ve Java’ya fonksiyonel programlama dünyasından kullanışlı araçlar kazandırır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/java-lambda-ifadeleri-62.png" /><media:content medium="image" url="https://program.sonsuz.us/img/java-lambda-ifadeleri-62.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>