{"componentChunkName":"component---src-templates-page-js","path":"/gizlilik-politikasi/","result":{"data":{"sitePage":{"id":"SitePage /gizlilik-politikasi/"}},"pageContext":{"url":"/gizlilik-politikasi/","relativePath":"gizlilik-politikasi.md","relativeDir":"","base":"gizlilik-politikasi.md","name":"gizlilik-politikasi","frontmatter":{"title":"Gizlilik Politikası","subtitle":"AstroFal, Gizem'e Sor, Lazca Sözlük, Ses Değiştirici, Düzce'm, PetGuru","excerpt":"Asnus uygulamaları için gizlilik politikası","img_alt":"","template":"page","img_path":"images/c2ab78.jpg"},"html":"<h2>Uygulamalarımız</h2>\n<p>Bu gizlilik politikası aşağıdaki uygulamalarımız için geçerlidir:</p>\n<ul>\n<li><strong>AstroFal</strong> - Astroloji ve burç uygulaması</li>\n<li><strong>Gizem'e Sor</strong> - Soru-cevap uygulaması</li>\n<li><strong>Lazca Sözlük</strong> - Lazca-Türkçe sözlük uygulaması</li>\n<li><strong>Ses Değiştirici</strong> - Ses efektleri uygulaması</li>\n<li><strong>Düzce'm</strong> - Düzce şehir rehberi uygulaması</li>\n<li><strong>PetGuru</strong> - Evcil hayvan bakım uygulaması</li>\n</ul>\n<hr>\n<h2>Gizlilik Politikası</h2>\n<p><strong>Son güncelleme:</strong> Ocak 2025</p>\n<p>Gizliliğiniz bizim için önemlidir. Asnus olarak, uygulamalarımızı kullanırken topladığımız bilgilerle ilgili gizliliğinize saygı duyuyoruz.</p>\n<h3>Topladığımız Bilgiler</h3>\n<p>Uygulamalarımız aşağıdaki bilgileri toplayabilir:</p>\n<ul>\n<li><strong>Cihaz bilgileri:</strong> Cihaz modeli, işletim sistemi sürümü</li>\n<li><strong>Kullanım verileri:</strong> Uygulama içi etkileşimler ve tercihler</li>\n<li><strong>Reklam kimliği:</strong> Kişiselleştirilmiş reklamlar için (izin verildiğinde)</li>\n</ul>\n<h3>Bilgilerin Kullanımı</h3>\n<p>Topladığımız bilgileri şu amaçlarla kullanıyoruz:</p>\n<ul>\n<li>Uygulama deneyimini iyileştirmek</li>\n<li>Teknik sorunları tespit etmek ve çözmek</li>\n<li>Anonim kullanım istatistikleri oluşturmak</li>\n<li>Reklam hizmetleri sunmak</li>\n</ul>\n<h3>Üçüncü Taraf Hizmetler</h3>\n<p>Uygulamalarımız aşağıdaki üçüncü taraf hizmetleri kullanabilir:</p>\n<ul>\n<li><strong>Google AdMob</strong> - Reklam hizmetleri</li>\n<li><strong>Google Analytics / Firebase</strong> - Kullanım analizi</li>\n<li><strong>Google Play Hizmetleri</strong> - Uygulama işlevselliği</li>\n</ul>\n<p>Bu hizmetlerin kendi gizlilik politikaları bulunmaktadır.</p>\n<h3>Veri Güvenliği</h3>\n<p>Verilerinizi korumak için ticari olarak kabul edilebilir güvenlik önlemleri uyguluyoruz. Ancak, internet üzerinden hiçbir veri aktarım yöntemi %100 güvenli değildir.</p>\n<h3>Çocukların Gizliliği</h3>\n<p>Uygulamalarımız 13 yaşın altındaki çocuklara yönelik değildir. Bilerek 13 yaşın altındaki çocuklardan kişisel bilgi toplamıyoruz.</p>\n<h3>Değişiklikler</h3>\n<p>Bu gizlilik politikasını zaman zaman güncelleyebiliriz. Değişiklikler bu sayfada yayınlanacaktır.</p>\n<h3>İletişim</h3>\n<p>Gizlilik politikamızla ilgili sorularınız için bizimle iletişime geçebilirsiniz:</p>\n<p><strong>E-posta:</strong> info@asnus.com</p>\n<hr>\n<h2>Privacy Policy (English)</h2>\n<p><strong>Last updated:</strong> January 2025</p>\n<p>Your privacy is important to us. At Asnus, we respect your privacy regarding any information we collect while you use our applications.</p>\n<h3>Information We Collect</h3>\n<p>Our applications may collect the following information:</p>\n<ul>\n<li><strong>Device information:</strong> Device model, operating system version</li>\n<li><strong>Usage data:</strong> In-app interactions and preferences</li>\n<li><strong>Advertising ID:</strong> For personalized ads (when permitted)</li>\n</ul>\n<h3>Use of Information</h3>\n<p>We use the collected information for:</p>\n<ul>\n<li>Improving app experience</li>\n<li>Identifying and resolving technical issues</li>\n<li>Creating anonymous usage statistics</li>\n<li>Providing advertising services</li>\n</ul>\n<h3>Third-Party Services</h3>\n<p>Our applications may use the following third-party services:</p>\n<ul>\n<li><strong>Google AdMob</strong> - Advertising services</li>\n<li><strong>Google Analytics / Firebase</strong> - Usage analytics</li>\n<li><strong>Google Play Services</strong> - App functionality</li>\n</ul>\n<p>These services have their own privacy policies.</p>\n<h3>Data Security</h3>\n<p>We implement commercially acceptable security measures to protect your data. However, no method of data transmission over the internet is 100% secure.</p>\n<h3>Children's Privacy</h3>\n<p>Our applications are not intended for children under 13. We do not knowingly collect personal information from children under 13.</p>\n<h3>Changes</h3>\n<p>We may update this privacy policy from time to time. Changes will be posted on this page.</p>\n<h3>Contact</h3>\n<p>For questions about our privacy policy, please contact us:</p>\n<p><strong>Email:</strong> info@asnus.com</p>","pages":[{"url":"/contact/","relativePath":"contact.md","relativeDir":"","base":"contact.md","name":"contact","frontmatter":{"title":"İletişim","hide_title":false,"sections":[{"section_id":"contact-form","type":"section_form","content":"Aşağıdaki formu eksiksiz doldurarak bizimle iletişime geçebilirsiniz.","form_id":"contactForm","form_action":"https://mailthis.to/destek@asnus.com","form_fields":[{"input_type":"text","name":"isim","label":"İsim","default_value":"İsminiz","is_required":true},{"input_type":"email","name":"email","label":"E-mail","default_value":"E-mail adresiniz","is_required":true},{"input_type":"select","name":"konu","label":"Konu","default_value":"Konunuz","options":["Hata Ve Öneri","Sponsorluk","Diğer"]},{"input_type":"textarea","name":"mesaj","label":"Mesaj","default_value":"Mesajınız"},{"input_type":"checkbox","name":"onay","label":"Bu formun, benimle iletişime geçilebilmesi için gönderilen bilgilerimi sakladığını biliyor ve onaylıyorum."}],"submit_label":"Gönder"}],"template":"advanced"},"html":""},{"url":"/gizlilik-politikasi/","relativePath":"gizlilik-politikasi.md","relativeDir":"","base":"gizlilik-politikasi.md","name":"gizlilik-politikasi","frontmatter":{"title":"Gizlilik Politikası","subtitle":"AstroFal, Gizem'e Sor, Lazca Sözlük, Ses Değiştirici, Düzce'm, PetGuru","excerpt":"Asnus uygulamaları için gizlilik politikası","img_alt":"","template":"page","img_path":"images/c2ab78.jpg"},"html":"<h2>Uygulamalarımız</h2>\n<p>Bu gizlilik politikası aşağıdaki uygulamalarımız için geçerlidir:</p>\n<ul>\n<li><strong>AstroFal</strong> - Astroloji ve burç uygulaması</li>\n<li><strong>Gizem'e Sor</strong> - Soru-cevap uygulaması</li>\n<li><strong>Lazca Sözlük</strong> - Lazca-Türkçe sözlük uygulaması</li>\n<li><strong>Ses Değiştirici</strong> - Ses efektleri uygulaması</li>\n<li><strong>Düzce'm</strong> - Düzce şehir rehberi uygulaması</li>\n<li><strong>PetGuru</strong> - Evcil hayvan bakım uygulaması</li>\n</ul>\n<hr>\n<h2>Gizlilik Politikası</h2>\n<p><strong>Son güncelleme:</strong> Ocak 2025</p>\n<p>Gizliliğiniz bizim için önemlidir. Asnus olarak, uygulamalarımızı kullanırken topladığımız bilgilerle ilgili gizliliğinize saygı duyuyoruz.</p>\n<h3>Topladığımız Bilgiler</h3>\n<p>Uygulamalarımız aşağıdaki bilgileri toplayabilir:</p>\n<ul>\n<li><strong>Cihaz bilgileri:</strong> Cihaz modeli, işletim sistemi sürümü</li>\n<li><strong>Kullanım verileri:</strong> Uygulama içi etkileşimler ve tercihler</li>\n<li><strong>Reklam kimliği:</strong> Kişiselleştirilmiş reklamlar için (izin verildiğinde)</li>\n</ul>\n<h3>Bilgilerin Kullanımı</h3>\n<p>Topladığımız bilgileri şu amaçlarla kullanıyoruz:</p>\n<ul>\n<li>Uygulama deneyimini iyileştirmek</li>\n<li>Teknik sorunları tespit etmek ve çözmek</li>\n<li>Anonim kullanım istatistikleri oluşturmak</li>\n<li>Reklam hizmetleri sunmak</li>\n</ul>\n<h3>Üçüncü Taraf Hizmetler</h3>\n<p>Uygulamalarımız aşağıdaki üçüncü taraf hizmetleri kullanabilir:</p>\n<ul>\n<li><strong>Google AdMob</strong> - Reklam hizmetleri</li>\n<li><strong>Google Analytics / Firebase</strong> - Kullanım analizi</li>\n<li><strong>Google Play Hizmetleri</strong> - Uygulama işlevselliği</li>\n</ul>\n<p>Bu hizmetlerin kendi gizlilik politikaları bulunmaktadır.</p>\n<h3>Veri Güvenliği</h3>\n<p>Verilerinizi korumak için ticari olarak kabul edilebilir güvenlik önlemleri uyguluyoruz. Ancak, internet üzerinden hiçbir veri aktarım yöntemi %100 güvenli değildir.</p>\n<h3>Çocukların Gizliliği</h3>\n<p>Uygulamalarımız 13 yaşın altındaki çocuklara yönelik değildir. Bilerek 13 yaşın altındaki çocuklardan kişisel bilgi toplamıyoruz.</p>\n<h3>Değişiklikler</h3>\n<p>Bu gizlilik politikasını zaman zaman güncelleyebiliriz. Değişiklikler bu sayfada yayınlanacaktır.</p>\n<h3>İletişim</h3>\n<p>Gizlilik politikamızla ilgili sorularınız için bizimle iletişime geçebilirsiniz:</p>\n<p><strong>E-posta:</strong> info@asnus.com</p>\n<hr>\n<h2>Privacy Policy (English)</h2>\n<p><strong>Last updated:</strong> January 2025</p>\n<p>Your privacy is important to us. At Asnus, we respect your privacy regarding any information we collect while you use our applications.</p>\n<h3>Information We Collect</h3>\n<p>Our applications may collect the following information:</p>\n<ul>\n<li><strong>Device information:</strong> Device model, operating system version</li>\n<li><strong>Usage data:</strong> In-app interactions and preferences</li>\n<li><strong>Advertising ID:</strong> For personalized ads (when permitted)</li>\n</ul>\n<h3>Use of Information</h3>\n<p>We use the collected information for:</p>\n<ul>\n<li>Improving app experience</li>\n<li>Identifying and resolving technical issues</li>\n<li>Creating anonymous usage statistics</li>\n<li>Providing advertising services</li>\n</ul>\n<h3>Third-Party Services</h3>\n<p>Our applications may use the following third-party services:</p>\n<ul>\n<li><strong>Google AdMob</strong> - Advertising services</li>\n<li><strong>Google Analytics / Firebase</strong> - Usage analytics</li>\n<li><strong>Google Play Services</strong> - App functionality</li>\n</ul>\n<p>These services have their own privacy policies.</p>\n<h3>Data Security</h3>\n<p>We implement commercially acceptable security measures to protect your data. However, no method of data transmission over the internet is 100% secure.</p>\n<h3>Children's Privacy</h3>\n<p>Our applications are not intended for children under 13. We do not knowingly collect personal information from children under 13.</p>\n<h3>Changes</h3>\n<p>We may update this privacy policy from time to time. Changes will be posted on this page.</p>\n<h3>Contact</h3>\n<p>For questions about our privacy policy, please contact us:</p>\n<p><strong>Email:</strong> info@asnus.com</p>"},{"url":"/ihsansunman/","relativePath":"ihsansunman.md","relativeDir":"","base":"ihsansunman.md","name":"ihsansunman","frontmatter":{"title":"İhsan Sunman","author":"ihsansunman","hide_title":true,"excerpt":"ihsansunman.asnus.com","sections":[],"template":"authorblog"},"html":""},{"url":"/about/","relativePath":"about.md","relativeDir":"","base":"about.md","name":"about","frontmatter":{"title":"Hakkımızda","subtitle":"Asnus Blog Teknoloji Konusunda Makaleleri Paylaştığımız Bir Web Sitesidir.","img_path":"images/kind-giraffe.png","img_alt":"ASNUS-LOGO","template":"page"},"html":"<p>Merhaba arkadaşlar,</p>\n<p>Öncelikle hepiniz blogumuza hoşgeldiniz. Uzun zamandır aklımızda olan ‘acaba bu işin altından kalkabilir miyim?’ sorusunu da düşünerek blogumuzu an itibariyle açtım. Blogumuz daha çok alanında bilgi sahibi olduğumuz için bilgisayar alanına hitap eden Bilişim ve Teknoloji, Yazılım ve Donanım, Ağ Teknolojisi, Web Programları, İpuçları ve Bilgi makalelerini siz okurlar ile paylaşacağız.</p>\n<p>Blogumuzun ziyaretçi kitlesine göre ilerleyen zamanlarda kategorileri de artacaktır. Yazacağımız ders makalelerinde mümkün olduğunca özgün olmaya ve anlatılabilir, uygulanabilir şekilde belirtmeye çalışacağız. Elbette ki bazı kaynaklara başvuracağız ancak yine de özgün olmak ana hususumuz olacaktır.</p>\n<p>Umarız blogumuz uzun yıllar internet serüveninde sizlerin sayesinde ayakta olur ve şimdiden takipleriniz için teşekkür eder ‘favori bloğunuz’ olmamızı da dileriz 🙂</p>\n<p>Samet &#x26; İhsan</p>\n<blockquote>\n<p>Her zaman bir şeyleri nasıl daha iyi yapabileceğinizi düşününün ve kendinizi sorgulayın. <cite>Elon Musk</cite></p>\n</blockquote>\n<p><em>Okuduğunuz için teşekür ederiz!</em></p>\n<p><a href=\"https://asnus.com/asnus-data-protection-and-privacy-policy\">Gizlilik Sözleşmesi</a></p>"},{"url":"/blog/","relativePath":"blog/index.md","relativeDir":"blog","base":"index.md","name":"index","frontmatter":{"title":"Tüm Gönderiler","template":"blog"},"html":""},{"url":"/sametsunman/","relativePath":"sametsunman.md","relativeDir":"","base":"sametsunman.md","name":"sametsunman","frontmatter":{"title":"Samet Sunman","author":"sametsunman","hide_title":true,"excerpt":"sametsunman.asnus.com","sections":[],"template":"authorblog"},"html":""},{"url":"/","relativePath":"index.md","relativeDir":"","base":"index.md","name":"index","frontmatter":{"title":"Anasayfa","hide_title":true,"sections":[{"section_id":"hero","type":"section_hero","title":"Asnus Blog'a Hoşgeldiniz!","content":""},{"section_id":"about","type":"section_content"},{"section_id":"featured-posts","type":"featured_posts","title":"Editörün Seçimi","posts_number":2},{"section_id":"recent-posts","type":"section_posts","title":"Son Gönderiler","posts_number":6,"actions":[{"label":"Tüm Gönderiler","url":"blog/","style":"button"}]}],"template":"advanced"},"html":""},{"url":"/posts/apache-maven-windowsa-nasil-yuklenir/","relativePath":"posts/apache-maven-windowsa-nasil-yuklenir.md","relativeDir":"posts","base":"apache-maven-windowsa-nasil-yuklenir.md","name":"apache-maven-windowsa-nasil-yuklenir","frontmatter":{"title":"Apache Maven Windows'a nasıl yüklenir?","author":"sametsunman","subtitle":"Maven bir proje yönetim aracıdır. Gelişiricilere projenin tüm yaşam döngüsüne müdahale edebileceği bir yapı sağlar. Proje kurulumu ve yeniden kullanılabilirliği kolaylaştırır. Geliştirme sürecini basitleştirir ve bu süreci standart hale getirir. Bunlara ek olarak proje bağımlılıklarını yönetmesi de Maven’ın en önemli özelliklerinden birisidir.","date":"2019-12-22","thumb_img_alt":"apache-maven","content_img_alt":"apache-maven","excerpt":"Maven bir proje yönetim aracıdır. Gelişiricilere projenin tüm yaşam döngüsüne müdahale edebileceği bir yapı sağlar. Proje kurulumu ve yeniden kullanılabilirliği kolaylaştırır. Geliştirme sürecini basitleştirir ve bu süreci standart hale getirir. Bunlara ek olarak proje bağımlılıklarını yönetmesi de Maven’ın en önemli özelliklerinden birisidir.","canonical_url":"","template":"post","thumb_img_path":"images/apache-maven.jpg","content_img_path":"images/apache-maven.jpg"},"html":"<p>Apache Maven'in resmi sitesinde kurulumu biraz kafa karıştırıcı bulunabilir. Bu yüzden türkçe yönerge iyi olacağını düşündüm.</p>\n<p><strong>Maven Kurulumu</strong></p>\n<p>Önkoşullar: JDK 1.6 ya da daha üst sürümünün sisteminizde kurulu olması.</p>\n<ol>\n<li><a href=\"https://maven.apache.org/download.cgi\">https://maven.apache.org/download.cgi</a> linkine tıklayarak Maven’ın kendi sitesinden işletim sistemimize uygun olan sürümünü indiriyoruz. Kararsızsanız \"Binary zip archive\" olanını indirebilirsiniz.</li>\n<li>İndirdiğiniz .zip uzantılı dosyayı istediğiniz yere çıkartabilirsiniz. Kuruluma gerek yoktur. Genelde C dizinine çıkartılır. Burada C içerisinde apps isimli klasöre çıkartılmış örnek üzerinden gideceğiz.</li>\n<li>Kuruluma devam etmeden önce Ortam Değişkenlerinde JAVA_HOME değişkeninin tanımlandığını kontrol ediyoruz. Eğer yoksa aşağıdaki resimdeki gibi tanımlayabilirsiniz</li>\n</ol>\n<p>Kontrol Paneli>Sistem Özellikleri>Gelişmiş>Ortam değişiklikleri</p>\n<ol start=\"4\">\n<li>Şimdi Maven için M2<em>HOME ve MAVEN</em>HOME ortam değişkenlerini tanımlayacağız. Maven’ı nereye çıkarttıysak o dizini belirteceğiz.</li>\n</ol>\n<p><img src=\"/images/apache-47.png\" alt=\"images/apache-47.png\"></p>\n<ol start=\"5\">\n<li>Son olarak yine aynı sayfadaki path değişkenine tıklayıp edit dedikten sonra en sona gidip bir noktalı virgül koyuyoruz. Ardından %M2_HOME%\\bin tanımını ekliyoruz. Bu işlemi Maven komutlarını her yerden çalıştırabilmek için yapıyoruz.</li>\n</ol>\n<p><img src=\"/images/apache-57.png\" alt=\"images/apache-57.png\"></p>\n<ol start=\"6\">\n<li>Maven kurulum işlemleri bu kadar. Şimdi windows komut istemini açarak mvn –version yazalım. Eğer görseldeli gibi benzer bir yazı ile karşılaşırsanız Maven düzgün bir şekilde yüklenmiş demektir.</li>\n</ol>\n<p><img src=\"/images/apache-64.png\" alt=\"images/apache-64.png\"></p>"},{"url":"/posts/bilgisayar-kumesi-nedir/","relativePath":"posts/bilgisayar-kumesi-nedir.md","relativeDir":"posts","base":"bilgisayar-kumesi-nedir.md","name":"bilgisayar-kumesi-nedir","frontmatter":{"title":"Bilgisayar Kümesi Nedir?","author":"ihsansunman","subtitle":"Günümüzde birçok işlemimizi bilgisayar vasıtasıyla yapıyoruz. Bazen bilgisayar ile yapılan işlemler bilgisayarımızı zorlamaya başlar. Bunun için insanlar birçok yöntem geliştirmiştir. Bilgisayarımızın donanımını artırmakta işe yarayabilir ancak günümüzde tek bir bilgisayarın yapamayacağı işlemler yapmak zorunda kalıyoruz. ","date":"2019-12-14","thumb_img_alt":"","content_img_alt":"","excerpt":"Günümüzde birçok işlemimizi bilgisayar vasıtasıyla yapıyoruz. Bazen bilgisayar ile yapılan işlemler bilgisayarımızı zorlamaya başlar. Bunun için insanlar birçok yöntem geliştirmiştir. Bilgisayarımızın donanımını artırmakta işe yarayabilir ancak günümüzde tek bir bilgisayarın yapamayacağı işlemler yapmak zorunda kalıyoruz. Bunun için birçok bilgisayarda işlem yapmamız gerekmektedir.","canonical_url":"","template":"post","content_img_path":"images/computerclus.jpg","thumb_img_path":"images/computerclus.jpg"},"html":"<h2>Bilgisayar Kümesi (Computer Cluster)</h2>\n<p>Bunun için birçok bilgisayarda işlem yapmamız gerekmektedir. Günümüzde bu bilgisayarları ağ bağlantısı ile bir araya getirip sanki bir bilgisayarmış gibi davranmalarına yarayan sistemler geliştirilmiştir. Bu sisteme bilgisayar kümesi yani computer cluster denilir.</p>\n<p>Kişisel bilgisayarlarımız ile bir bilgisayar kümesi oluşturmak mümkün ancak günümüzde küme oluşturmak için özel üretilen kartlar mevcuttur. Hatta Raspberry adı verilen mini board PC’ler ile küme oluşturulması son zamanda oldukça artmıştır.</p>\n<p>Bir bilgisayar kümesi neden oluşturulur; yüksek verim gücüne ulaşmak, yüksek üretim gücüne ulaşmak, sürekli erişebilirlik ve de sistemimizin büyümek için rahat kullanım sağlaması.</p>\n<p>Kullanım alanlarına göre bilgisayar kümelerinin sınıfları:</p>\n<ul>\n<li><em>Yüksek devamlılık kümeleri (High-Availability Clusters):</em> Bazen oluşturulan kümeler daha fazla güç için değil sürekli erişebilirlik için oluşturulur. Örneğin bir web sitesinin güçten daha çok sürekliliği önemlidir. Herhangi bir hata anında bir bilgisayarın bozulup kapanması durumunda bir diğer bilgisayar anında işleme devam etmesi gerekmektedir.</li>\n<li><em>Yük dengeleyici kümeler (Load-Balancing Clusters):</em> Birçok araştırma işlemlerinde, hesaplama işlemlerinde yüksek işlemci gücü gerekir. Bir bilgisayarın işlem limiti mevcuttur ve bu kadar yüksek işlemi yapmakta yavaş kalabilir. Bundan dolayı yükü dengeleyecek bilgisayar kümesi oluşturulursa bu işlemleri birçok işlemci kendi arasında paylaşarak daha hızlı ve daha fazla işlem yapılmaya olanak sağlanacaktır.</li>\n<li><em>Yüksek performanslı kümeler (High-Performance Clusters):</em> Bilgisayarda performansı olabildiğince arttırmaya çalışıyoruz. Bunun bir yolu da yüksek performanslı kümeler oluşturmaktır. Günümüzde kripto para madenciliği için maden çiftliği kuruluyor. Kripto para madeni için oldukça güçlü işlemci (CPU) ve oldukça güçlü ekran kartları (GPU) gerekmektedir. Hatta günümüzde maden için özel ekran kartları ve işlemciler üretilmektedir.</li>\n<li><em>Heterojen Kümeler (Heterogeneous Clusters)</em>: Aslında heterojen kümeler kullanım alanı için oluşturulan bir küme değildir. Sistemimizi büyütmek için rahat kullanım sağlaması gerektiğinden daha öncesinde bahsettim. Birçok sistem Homojen Kümeler (Homogeneous Clusters) yani kümedeki tüm donanım ve işletim sistemi aynı olarak oluşturulur. Ancak daha sonrasında sistemimizi belli nedenlerden büyütmemiz gerekir. Her yeni sistem büyütmesinde farklı donanımlar eklenir. Hatta farklı işletim sistemleri eklenir bundan dolayı aynı kümenin içindeki farklı gruplarında farklı donanımlar bulunabilir. Sistemler homojen kümelerden gelişe gelişe heterojenleştirilerek büyümesi beklenir.</li>\n</ul>\n<p>Kaynaklar:</p>\n<ol>\n<li><a href=\"http://en.wikipedia.org/wiki/Computer_cluster\">http://en.wikipedia.org/wiki/Computer_cluster</a></li>\n<li><a href=\"http://tr.wikipedia.org/wiki/Bilgisayar_k%C3%BCmesi\">http://tr.wikipedia.org/wiki/Bilgisayar_kümesi</a></li>\n<li><a href=\"https://e-bergi.com/y/bilgisayar-kumeleri\">https://e-bergi.com/y/bilgisayar-kumeleri</a></li>\n<li><a href=\"http://www.hpc.msstate.edu/computing/history\">http://www.hpc.msstate.edu/computing/history</a></li>\n</ol>"},{"url":"/sulesavas/","relativePath":"sulesavas.md","relativeDir":"","base":"sulesavas.md","name":"sulesavas","frontmatter":{"title":"Şule Savaş","author":"sulesavas","hide_title":true,"excerpt":"sulesavas.asnus.com","sections":[],"template":"authorblog"},"html":""},{"url":"/posts/c-ve-javascriptte-eposta-dogrulama/","relativePath":"posts/c-ve-javascriptte-eposta-dogrulama.md","relativeDir":"posts","base":"c-ve-javascriptte-eposta-dogrulama.md","name":"c-ve-javascriptte-eposta-dogrulama","frontmatter":{"title":"C# ve JavaScript'te E-Posta Doğrulama","author":"sametsunman","subtitle":"Bir metnin e-posta olup olmadığını doğrulamak isteyebilir. Bunu iki farklı dilde nasıl yapabileceğimizi gösterelim","date":"2020-04-21","thumb_img_alt":"email-validation","content_img_alt":"email-validation","excerpt":"Bir metnin e-posta olup olmadığını doğrulamak isteyebilir. Bunu iki farklı dilde nasıl yapabileceğimizi gösterelim","canonical_url":"","template":"post","thumb_img_path":"images/email-validation.png","content_img_path":"images/email-validation.png"},"html":"<p>Bir metnin e-posta olup olmadağı aşağıdaki fonksiyonu kullanarak doğrulanabilir.</p>\n<p><strong>c#</strong></p>\n<pre><code>    public void SendEmail(){\n    \n                            if (!ValidateEmail(mailTo))\n                        {\n                            MessageBox.Show(\"Invalid To mail address\");\n                            return;\n                        }\n    \n    }\n\n        private bool ValidateEmail(string emailAddress)\n        {\n            string patternStrict = @\"^(([^&#x3C;>()[\\]\\\\.,;:\\s@\\\"\"]+\"\n                + @\"(\\.[^&#x3C;>()[\\]\\\\.,;:\\s@\\\"\"]+)*)|(\\\"\".+\\\"\"))@\"\n                + @\"((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\"\n                + @\"\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+\"\n                + @\"[a-zA-Z]{2,}))$\";\n            System.Text.RegularExpressions.Regex reStrict = new System.Text.RegularExpressions.Regex(patternStrict);\n            bool isStrictMatch = reStrict.IsMatch(emailAddress);\n            return isStrictMatch;\n        }\n</code></pre>\n<p><strong>JavaScript</strong></p>\n<pre><code>&#x3C;script>\nfunction SendEmail() {\n                let mailTo =document.getElementById(\"mailTo\").value;  \n                \n                if (!validateEmail(mailTo)) {\n                    alert('Invalid To mail address.');\n                    return;\n                }\n                }\n\n    function ValidateEmail(email) {\n        var re = /^(([^&#x3C;>()\\[\\]\\\\.,;:\\s@@\"]+(\\.[^&#x3C;>()\\[\\]\\\\.,;:\\s@@\"]+)*)|(\".+\"))@@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n        return re.test(String(email).toLowerCase());\n    }\n    &#x3C;/script>\n</code></pre>"},{"url":"/posts/bilgisayarinizdaki-sesi-kablosuz-olarak-telefona-nasil-iletilir/","relativePath":"posts/bilgisayarinizdaki-sesi-kablosuz-olarak-telefona-nasil-iletilir.md","relativeDir":"posts","base":"bilgisayarinizdaki-sesi-kablosuz-olarak-telefona-nasil-iletilir.md","name":"bilgisayarinizdaki-sesi-kablosuz-olarak-telefona-nasil-iletilir","frontmatter":{"title":"Bilgisayarınızdaki  ses kablosuz olarak telefonanasıl iletilir?","author":"sametsunman","subtitle":"Bilgisayarımızda hoparlör ya da kulaklık olmayabilir. Hatta ses sürücüsü dahi olmayabilir. Daha önce işyerimdeki bilgisayarımın hoparlörü olmadığını farkettim ve de bir video izlemem gerekiyordu. İnternette biraz araştırma yaptım. Farkettim ki bu durumda bilgisayardaki sesi telefondan dinleyebiliriz. Nasıl mı? Hadi bakalım..","date":"2019-12-26","thumb_img_alt":"soundwire","content_img_alt":"soundwire","excerpt":"Bilgisayarımızda hoparlör ya da kulaklık olmayabilir. Hatta ses sürücüsü dahi olmayabilir. Daha önce işyerimdeki bilgisayarımın hoparlörü olmadığını farkettim ve de bir video izlemem gerekiyordu. İnternette biraz araştırma yaptım. Farkettim ki bu durumda bilgisayardaki sesi telefondan dinleyebiliriz. Nasıl mı? Hadi bakalım..","canonical_url":"","template":"post","thumb_img_path":"images/soundwire.jpg","content_img_path":"images/soundwire.jpg"},"html":"<p><strong>1. Sanal ses sürücüsü yükleme</strong></p>\n<p>Bilgisayarınızda hoparlör varsa ama yine de telefonuza ses iletmek istiyorsanız bu adımı geçebilirsiniz.</p>\n<p>Öncelikle <a href=\"https://www.vb-audio.com/Cable/index.htm\">https://www.vb-audio.com/Cable/index.htm</a> adresinden downloada basarak sanal sürücümüzün dosyasını indiriyoruz. Dosyaları zipten çıkararak uygun olan yükleme exesine sağ tıklayarak yönetici oalrak çalıştırıyoruz. Yükleme adımlarını geçerek programımızı yüklüyoruz. Sağ alt köşede ses simgesi aktif olduysa kurulum başarılıdır.</p>\n<p><strong>2. Sesi telefona iletme</strong>,</p>\n<p>İşte eğlenceli kısım. Öncelikle belirteyim bilgisayar ve telefonunuz aynı ağda olması gerekiyor :)</p>\n<p><a href=\"http://georgielabs.net\">http://georgielabs.net</a> Bu adresten bilgisarınıza uygun olanı yükleyin. </p>\n<p>Aynı şekilde Google Playden (<a href=\"http://play.google.com/store/apps/details?id=com.georgie.SoundWire\">http://play.google.com/store/apps/details?id=com.georgie.SoundWire</a>) uygulamayı telefona yükleyin.</p>\n<p><img src=\"/images/soundware-app.jpeg\" alt=\"images/soundware-app.jpeg\"></p>\n<p>Şimdi ise telefonuzundaki uygulamadan bilgisayarın ip adresini girin. Ip adresi bilgisayardaki programda gözüküyor. Daha sonra ise ikona tıklayarak uygulamayı aktif edin. Bilgisayarınızdaki programda connected yazısı gördüyseniz eğer işlem başarılıdır.</p>\n<p><img src=\"/images/soundware-software.png\" alt=\"images/soundware-software.png\"></p>\n<p>İşte bu kadar. İyi eğlenceler</p>"},{"url":"/posts/debounce-nedir-ve-nasil-kullanilir/","relativePath":"posts/debounce-nedir-ve-nasil-kullanilir.md","relativeDir":"posts","base":"debounce-nedir-ve-nasil-kullanilir.md","name":"debounce-nedir-ve-nasil-kullanilir","frontmatter":{"title":"Debounce Nedir ve Nasıl Kullanılır?","subtitle":"Debounce, sürekli olarak tekrarlanan işlemleri kontrol altına almak için kullanılan bir tekniktir. Örneğin, bir kullanıcının bir arama kutusuna metin girdiğini ve bu metni kullanarak bir servise istek göndermeyi düşünelim. Kullanıcı her tuşa bastığında, isteği hemen göndermek yerine belirli bir zaman dilimi sonunda göndermek isteyebilirsiniz. Bu, her tuşa basışta servisiniz üzerinde gereksiz bir yük oluşturmaktan kaçınmanıza yardımcı olur. ","date":"2023-09-25T00:00:00.000Z","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/debounceMain.png","content_img_path":"images/debounceMain.png"},"html":"<h2>Debounce Nasıl Çalışır?</h2>\n<p>Örnek üzerinden devam edelim. Kullanıcı bir <code>&#x3C;input/></code> alanına aramak istediği kelimeyi yazdığında, bu kelime ile ilgili sonuçların görüntülendiği bir yapı hayal edin. Bu girdi değeri her değiştiğinde ilgili servise giderek sonuçları alacağımız bir fonksiyonumuz olsun. Ancak her tuşa bastığınızda bu işlevi çağırmak, servisinizi gereksiz yere yorabilir. İşte burada bir zamanlayıcı kullanabilirsiniz. Bu, her tuşa bastığınızda işlevin her çalıştırıldığında zamanlayıcı sıfırlanır. Bu sayede isteği göndermek için belirli bir zaman dilimini bekler. Kullanıcı yeni bir giriş yapmadıkça zamanlayıcı sıfırlanmaz ve belirlediğiniz süre sonunda istek gönderilir.</p>\n<p><img src=\"https://asnus.com/images/nondebounce.png\" alt=\"nondebounce\"></p>\n<p>Yukarıda örneğini göstermiş olduğum gibi kullanıcı her bir harfi değiştirdiğinde servisimize giderek bir istek atıyoruz.  Aşağıdaki örnekte ise kullanıcı veri girişini tamamlandığında isteği gönderecektir.</p>\n<p><img src=\"https://asnus.com/images/debounce.png\" alt=\"debounce\"></p>\n<p>Örnekleri canlı olarak da inceleyebilirsiniz.</p>\n<iframe src=\"https://codesandbox.io/embed/asnus-nondebounce-ffkv9h?fontsize=14&hidenavigation=1&theme=dark\"\n     style=\"width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;\"\n     title=\"asnus-nonDebounce\"\n     allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n     sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n   ></iframe>\n<iframe src=\"https://codesandbox.io/embed/asnus-debounce-dp279x?fontsize=14&hidenavigation=1&theme=dark\"\n     style=\"width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;\"\n     title=\"asnus-Debounce\"\n     allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n     sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n   ></iframe>\n<h2>Debounce Nasıl Kullanılır?</h2>\n<p>JavaScript(ES6) ve React için debounce kullanımını inceleyelim. 400ms olarak belirlediğimiz zaman boyunca yeniden fonksiyonumuz çalıştırılmadığı durumda yazdığımız fonksiyon çalışacaktır. Ancak fonksiyon her çağrıldığında verdiğimiz zamanlayıcı sıfırlayacaktır. Verilen zamanı yapımıza uygun değiştirebiliriz. Bu yapıyı dilediğimiz yazılım diline uygun düzenleyebiliriz.</p>\n<pre><code class=\"language-jsx\">let timer;\nfunction getSearchResults(){\n      clearTimeout(timer);\n    timer = setTimeout(() => { \n            /* İlgili işlemleri yapacak fonksiyonumuz */ \n        }, 400);\n}\n</code></pre>\n<pre><code class=\"language-jsx\">import { useRef } from 'react';\n\nconst timerRef = useRef(null);\n\nconst getSearchResults = () => {\n        clearTimeout(timerRef .current);\n        timerRef.current = setTimeout(() => {\n            /* İlgili işlemleri yapacak fonksiyonumuz */\n        }, 400);\n    };\n</code></pre>\n<p>Yukarıda vermiş olduğum örnekte yorum satırı olarak verdiğim satıra kullanıcının etkileşimin bitmesi durumunda sistemimize yaptırmak istediğimiz işlemi yazabiliriz. Görüldüğü gibi bu sistemi kurmak oldukça basittir. Basitliği yanı sıra, belirli sorunları çözmede de yardımcı olabilir.</p>"},{"url":"/posts/chatgpt-nedir-ve-nasil-kullanilir/","relativePath":"posts/chatgpt-nedir-ve-nasil-kullanilir.md","relativeDir":"posts","base":"chatgpt-nedir-ve-nasil-kullanilir.md","name":"chatgpt-nedir-ve-nasil-kullanilir","frontmatter":{"title":"ChatGPT Nedir ve Nasıl Kullanılır?","subtitle":"ChatGPT, OpenAI tarafından geliştirilen bir dil modelidir. Bu model, bir konuşmayı takip edebilme ve doğal dil kullanarak cevaplar verebilme yeteneğine sahip olan bir dil modelidir. Bu model, dil üzerinde yoğun bir şekilde çalışan bir dil modelidir ve birçok farklı dil ve dil kombinasyonu için kullanılabilir. ","date":"2022-12-05T00:00:00.000Z","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/Ekran görüntüsü 2022-12-05 093729.png","content_img_path":"images/Ekran görüntüsü 2022-12-05 093729.png"},"html":"<p>ChatGPT kullanımı oldukça basittir. Öncelikle, modeli indirip yüklemek gerekir. Daha sonra, kullanıcının modeli kullanarak bir konuşma yapmak istediği dil seçimi yapması gerekir. Daha sonra, kullanıcı modeli kullanarak bir konuşma başlatabilir ve model, doğal dil kullanarak cevaplar verebilir.</p>\n<p>Modelin kullanımı için birkaç örnek vardır. Örneğin, bir kullanıcı modeli bir konuşma ortamında kullanarak, modeli bir arkadaşı ile konuşturabilir. Bu sayede model, doğal dil kullanarak cevaplar vererek bir konuşma simüle edebilir. Ayrıca, bir kullanıcı modeli bir chatbot olarak kullanarak, modeli bir web sitesinde ya da bir mobil uygulamada kullanarak, kullanıcılara doğal dil kullanarak cevaplar verebilir.</p>\n<p>Genel olarak, ChatGPT bir dil modelidir ve dil üzerinde yoğun bir şekilde çalışan bir model olarak tasarlandı. Bu model, doğal dil kullanarak cevaplar verebilme yeteneğine sahip olduğu için, birçok farklı dil ve dil kombinasyonu için kullanılabilir. Kullanımı da oldukça basittir ve kullanıcılar modeli bir konuşma ortamında ya da bir chatbot olarak kullanarak faydalanabilirler.</p>\n<ul>\n<li>Bu makale ChatGPT tarafından yazılmıştır.</li>\n</ul>"},{"url":"/posts/devops-nedir/","relativePath":"posts/devops-nedir.md","relativeDir":"posts","base":"devops-nedir.md","name":"devops-nedir","frontmatter":{"title":"DevOps Nedir?","author":"ihsansunman","subtitle":"Birçok şirkette birden fazla departman bulunmaktadır. Bunlardan biri olan Bilgi Teknolojileri (IT) departmanının altında yazılımın geliştirilmesinden sorumlu takım “Geliştiriciler” ve bu yazılımların işletilmesinden sorumlu takım olan “Operasyon” birimleri bulunmaktadır. DevOps ise bu iki birimin ingilizceleri olan developers ve operations’un ilk üç harflerinden oluşur. Bu kavram iki birimin en etkili iletişim ile daha verimli olabilmeleri için bir arada çalışmasını belirtir.","date":"2019-11-26","thumb_img_alt":"","content_img_alt":"","excerpt":"Birçok şirkette birden fazla departman bulunmaktadır. Bunlardan biri olan Bilgi Teknolojileri (IT) departmanının altında yazılımın geliştirilmesinden sorumlu takım “Geliştiriciler” ve bu yazılımların işletilmesinden sorumlu takım olan “Operasyon” birimleri bulunmaktadır. DevOps ise bu iki birimin ingilizceleri olan developers ve operations’un ilk üç harflerinden oluşur. Bu kavram iki birimin en etkili iletişim ile daha verimli olabilmeleri için bir arada çalışmasını belirtir. ","canonical_url":"","template":"post","thumb_img_path":"images/devops1.png","content_img_path":"images/devops1.png"},"html":"<p>Bu iki biriminde farklı görev ve sorumlulukları bulunur. Geliştirici birimi; uygulamayı kodlar, uygulamayı yayınlar, güncelleştirme ve iyileştirmeleri yapar, uygulamayı test eder. Operasyon birimi ise; uygulamanın barınacağı alt yapıyı tasarlar, gerekli ağ ve güvenliği sağlar, uygulamanın izlenmesini sağlar, kaynak kullanımını ve bu kaynağın kullanım durumuna göre artırılmasını belirler.</p>\n<p>DevOps’un daha hızlı ve verimli çalışmasını sağlayan durum iki farklı birimin tek çatı altına girip işlemlerin bir arada yapılmasıdır. Ve bu işlemlerin sürekli ve aralıksız gerçekleşmesi ile yapılan uygulama sürekli gelişir.</p>\n<p>DevOps birçok insan tarafından bir felsefe olarak da anılır. Ancak günümüzde firmaların DevOps’u bir pozisyon ismi olarak kullandığını görmekteyiz.</p>\n<p>DevOps’un faydaları ise birimlerin daha verimli çalışmaları, sürekli üretim, sorunlara daha hızlı çözümler üretebilmek, daha hızlı teslim, daha düzenli çalışanlar, daha güvenirlik vb.</p>"},{"url":"/posts/git-ile-iki-projeyi-birlestirmek/","relativePath":"posts/git-ile-iki-projeyi-birlestirmek.md","relativeDir":"posts","base":"git-ile-iki-projeyi-birlestirmek.md","name":"git-ile-iki-projeyi-birlestirmek","frontmatter":{"title":"Git ile iki projeyi birleştirme","subtitle":"Merhaba arkadaşlar, bazen iki farklı projeyi birleştirmek gerekebilir. Farklı bir projeyi  kendi projemize entegre etmek isteriz. Veya aynı proje için iki farklı repo açılmış ve birleştirmek gerekebilir. Bu durumda bu konu size yardımcı olacaktır.","date":"2021-05-13","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/git-project.png","content_img_path":"images/git-project.png"},"html":"<p>İki adet repomuz olsun. Biri YENİ-PROJE, diğeri ise ESKİ-PROJE olsun. Burada yapacağımız ESKİ-PROJE dosyalarını YENİ-PROJE dosyalarının içine dahil ederek YENİ-PROJE'yi güncellemek olacaktır. Bu işlemi sağlarken git kullanmanın da güzelliğini görüyor olacağız. Demek istediğim şu; bir proje geliştiriyoruz. belli kısmı hazır olsun A kişisi bu projeyi geliştirsin. B kişisi ise bu geliştirmeden bağımsız yeri geliştirsin. Birleştirme sağlanırken bağımsız dosyalar sorunsuz entegre olurken, aynı dosyalar veya aynı satırlarda yapılan değğişiklikleri herhangi bir git sistemi (VS Code, Android Studio, Gitkraken) bize hangi kodun kalıcağını veya birleştirme sağlanıp sağlanmıyacağını soruyor olacak. Bu durum ise olası sorunları bizim kontrolümüze bırakıyor olacaktır. </p>\n<p>Gelelim bu işlemi nasıl sağlayacağımıza:</p>\n<pre><code>cd path/to/YENİ-PROJE\ngit remote add ESKİ-PROJE /path/to/ESKİ-PROJE\ngit fetch ESKİ-PROJE --tags\ngit merge --allow-unrelated-histories ESKİ-PROJE/master\ngit remote remove ESKİ-PROJE //Eğer ESKİ-PROJE'nin silinmesini istemiyorsanız bunu yapmayın.\n</code></pre>"},{"url":"/posts/dns-nasil-calisir-ve-guvenlik-sorunlari-nelerdir/","relativePath":"posts/dns-nasil-calisir-ve-guvenlik-sorunlari-nelerdir.md","relativeDir":"posts","base":"dns-nasil-calisir-ve-guvenlik-sorunlari-nelerdir.md","name":"dns-nasil-calisir-ve-guvenlik-sorunlari-nelerdir","frontmatter":{"title":"DNS Nasıl Çalışır ve Güvenlik sorunları nelerdir?","author":"ihsansunman","subtitle":"DNS, Domain Name System kelimelerinin kısaltılmış halidir. Türkçe karşılığı Alan İsimlendirme Sistemi’dir. İnternetimizin adres defterine benzetebiliriz. İnternette gezinmemiz için gerekli olan adresleri tutan bir sistemdir.","date":"2019-12-15","thumb_img_alt":"","content_img_alt":"","excerpt":"DNS, Domain Name System kelimelerinin kısaltılmış halidir. Türkçe karşılığı Alan İsimlendirme Sistemi’dir. İnternetimizin adres defterine benzetebiliriz. İnternette gezinmemiz için gerekli olan adresleri tutan bir sistemdir. IP adresini daha önceden duymuşsunuzdur. İnternette gezindiğimiz her web sitesinin bir IP adresi vardır. Eğer DNS olmasaydı Google ’ye girmek istediğimizde www.google.com adresi yerine 172.217.169.206 gibi uzun ve karmaşık sayılar ile web sitelere girmemiz gerekecekti.","canonical_url":"","template":"post","thumb_img_path":"images/dns.png","content_img_path":"images/dns.png"},"html":"<h2>DNS Nasıl Çalışır ve Güvenlik sorunları nelerdir?</h2>\n<p><strong>DNS Nedir?</strong></p>\n<p>IP adresini daha önceden duymuşsunuzdur. İnternette gezindiğimiz her web sitesinin bir IP adresi vardır. Eğer DNS olmasaydı Google ’ye girmek istediğimizde www.google.com adresi yerine 172.217.169.206 gibi uzun ve karmaşık sayılar ile web sitelere girmemiz gerekecekti. Bu hem akılda kalması çok zor hem de gereksiz bir uğraş olurdu. Bunun yerine DNS sistemi bize bu IP adresi yerine daha basit olan alan adları ile internette daha rahat gezinmemizi sağlıyor.</p>\n<p><strong>DNS Nasıl Çalışır?</strong></p>\n<p>Bir web siteye girmek istedik. Adres çubuğuna girmek istediğimiz adresi girdik. Burada örnek www.google.com.tr olsun. Öncelikle tarayıcımız bu alan adını bilgisayarımızdaki çerezlere bakar. Eğer burada varsa IP adresi bulacağı için hızlı bir şekilde açacaktır. Ancak bu çerezler genelde 1 saat, 1 gün gibi bir sürede temizlenir. Girdiğimiz adres çerezlerde yoksa genelde internet sağlayıcılarımızın sunduğu DNS sunucularına gideriz. Ve orada bu alan adına karşılık gelen IP adresini bulup siteye rahatça gireriz. Peki ya bu sunucular nasıl bu kadar hızlı şekilde istediğimiz alan adının karşılığı olan IP adresi buluyor. Bu sistemi bir ağaca benzetebiliriz, dallanan bir ağaca. Örneğimize bakalım sonu tr ile bitiyor. Bu adresin hangi ülkede olduğunu belli eder. Bu sitemiz Türkiye’de bulunmakta. İkinci olarak .com yazısı ile karşılaşıyoruz. Bunlara üst düzey domain denilir. Com bir ticari kuruluş olduğunu belli eder. En sonunda ise google yani sitemizin adı yazar. Bu şekilde IP adresimizi bulunur.</p>\n<p><strong>DNS Güvenlik Sorunları Nelerdir?</strong></p>\n<p>Bahsettiğim gibi bir sunucu var ve karşılık gelen IP adresi üzerinden siteye girebiliyoruz. Peki ya siber saldırganlar siz farkında olmadan karşılık gelen IP adresini değiştirdiğini düşünün. Siz bir siteye girmek istiyorsunuz ama aslında o siteye benzeyen başka bir siteye girmişsiniz. Farkında olmadan kredi kartı bilgilerini girdiğiniz anda bu bilgiler saldırganların eline geçebilir. Bu yüzden güvendiğimiz DNS servisini tercih etmenizin ne kadar önemli olduğunu anlayabiliriz.</p>"},{"url":"/posts/excelde-calisma-kitabini-otomatik-kaydetme/","relativePath":"posts/excelde-calisma-kitabini-otomatik-kaydetme.md","relativeDir":"posts","base":"excelde-calisma-kitabini-otomatik-kaydetme.md","name":"excelde-calisma-kitabini-otomatik-kaydetme","frontmatter":{"title":"Excelde çalışma kitabını otomatik kaydetme","subtitle":"Merhaba arkadaşlar, İş yerimde elektrik kesintisinden dolayı önemli bilgiler kayboluyordu, buna çözüm üretmek adına çalışma kitabını otomatik kaydetmeyi öğrendim ve uyguladım, Bunu sizlerle paylaşmak istedim umarım yararlı olur.","date":"2021-01-24","thumb_img_alt":"Excel-oto","content_img_alt":"Excel-oto","excerpt":"Merhaba arkadaşlar, İş yerimde elektrik kesintisinden dolayı önemli bilgiler kayboluyordu, buna çözüm üretmek adına çalışma kitabını otomatik kaydetmeyi öğrendim ve uyguladım, Bunu sizlerle paylaşmak istedim umarım yararlı olur.","canonical_url":"lorem-ipsum","author":"sulesavas","template":"post","thumb_img_path":"images/Excel-oto.png","content_img_path":"images/Excel-oto.png"},"html":"<p>Öncelikle Excel dosyamızı açalım. Geliştirici sekmesini aktif edelim.</p>\n<p>Geliştirici sekmesini aktif etmek için;</p>\n<p>Dosya sekmesine tıklıyoruz aşağıda yer alan seçeneklere tıklayıp sol taraftaki şeridi özelleştir bölümünden geliştirici kutucuğunu aktif edip tamama tıklıyoruz. Geliştirici sekmemiz aktif oldu  :)</p>\n<p>Şimdi geliştirici sekmesinden Visual Basic e tıklayalım. Açılan pencerede Insert kısmından yeni Module ekleyelim. Sonrasında ise açılan pencereye aşağıdaki kodları yapıştıralım.</p>\n<pre><code>Sub OtoKaydetme()\n\nDim wb As Workbook\nDim durtime As Integer\ndurtime = 1\n\n    \n\nWith Application\n.DisplayAlerts = False\n.EnableEvents = False\nFor Each wb In Application.Workbooks\nIf Not wb.ReadOnly And Windows(wb.Name).Visible Then\nwb.Save\n\nEnd If\nNext wb\n.DisplayAlerts = False\n.EnableEvents = True\n.OnTime Now + TimeValue(\"00:00:05\"), \"OtoKaydetme\"\n\nEnd With\n\nExit Sub\n\nsonlandir:\n\nEnd Sub\n</code></pre>\n<p>Şimdi ise soldan BuÇalışmaKitabı dosyasını açıyoruz ve üstteki General yazan açılır menüden Workbook u seçelim ve alttaki kodu yapıştıralım.</p>\n<pre><code>Private Sub Workbook_Open()\n\nCall OtoKaydetmeModule.OtoKaydetme\n\nEnd Sub\n</code></pre>\n<p>Böylece yapmış olduğumuz Module ü 5 sn de bir çağıracak ve sayfamız otomatik kaydolacak.</p>\n<p>İyi çalışmalar...</p>"},{"url":"/posts/github-api-dosya-paylasimi/","relativePath":"posts/github-api-dosya-paylasimi.md","relativeDir":"posts","base":"github-api-dosya-paylasimi.md","name":"github-api-dosya-paylasimi","frontmatter":{"title":"Github API ile Dosya Yükleme, Düzenleme ve Silme Nasıl Yapılır?","subtitle":"Github projenize uzaktan dosya yüklemek ve bu dosyayı düzenleme ihtiyacı duydunuz mu? ","date":"2022-11-11T00:00:00.000Z","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/git-api.webp","content_img_path":"images/git-api.webp"},"html":"<p>Şuan bu yazının bulunduğu blog Github Repo'sundan yayınlanmaktadır. Her bir yazının yayınlanması için Github Repo'suna yeni bir dosya göndermemiz gerekmektedir. Bu sebeple Github API kullanarak form yapısından dosya gönderme işlemi hazırladık. Gelin bu işlemi nasıl yaptığımızdan biraz bahsedelim.</p>\n<p><strong>Dosyalara Ulaşmak</strong></p>\n<p>Öncelikle Git Repo'muza ulaşabilmemiz adına <code>https://api.github.com/repos/asnuscom/asnus/contents</code> endpointini kullanabiliriz. Buradan repoya ait dosyalar ve indirme uzantılarına ulaşabiliriz. Eğer bir webform hazırlıyorsanız buradan iletişim kurulacak ise bu endpoint size dosyaları sağladığı için dosyalarınızın listesini oluşturmanıza olanak tanır.</p>\n<p><img src=\"https://asnus.com/images/api-req.png\" alt=\"API Request\"></p>\n<p><strong>Dosya Yükleme ve Düzenleme</strong></p>\n<p>Öncelikle yükleme, düzenleme ve silme işlemleri için bir tokena ihtiyacımız var. <a href=\"https://github.com/settings/tokens/new\">New Token</a> adresinden bir token almamız gerekmektedir. İzin olarak 'Repo' iznini onaylamamız yeterli olacaktır. Oluştur dediğimizde token bize verilecek. Burada dikkat edilmesi gereken nokta bu token bir kere verilecektir. Kaybetmeniz durumunda tekrar oluşturmanız gerekecektir.</p>\n<pre><code>const content = btoa(unescape(encodeURIComponent(\"Dosya içeriği\")))\nconst data = JSON.stringify({\n          message: `Commit Mesajı`,\n          content: `${content}`,\n        });\nvar config = {\n          method: \"put\",\n          url: `https://api.github.com/repos/${Kullanıcı İsmi}/${Repo İsmi}/contents/${Oluşturulmasını istediğiniz dosya}.txt`,\n          headers: {\n            Authorization: `Bearer ${Token}`,\n            \"Content-Type\": \"application/json\",\n          },\n          data: data,\n        };\naxios(config)\n          .then(function (response) {\n            console.log(response);\n          })\n          .catch(function (error) {\n            console.log(error);\n          });\n</code></pre>\n<p>Yukarıda bulunan kod bloğunu kendi yapınıza uygun düzenliyebilirsiniz. <code>Dosya içeriği</code> yazan bölüme isterseniz bir yazıyı, isterseniz ise bir resmi koyabilirsiniz. Buraya konulan her türlü içerik Base64 formatına çevrilerek Github Reponuza iletilmektedir. Bu sebeple sorun vermemektedir. Aynı dosya ismine sahip endpointe tekrar istek attığınızda ise içerik yeni göndermiş olduğunuz haline düzenlenecektir.</p>\n<p><strong>Dosya Silme</strong></p>\n<p>Dosya silme işlemi yukardaki yapıya benzer bir şekilde yapılmaktadır. Bu sefer içerik göndermemize gerek bulunmamaktadır. Methodu 'DELETE' olarak düzenleyip istek attığımızda ise ilgili endpointteki dosya silinecektir. Burada yine commit mesajı yazmamız gerektiğini unutmayalım.</p>\n<p>Bu yöntem ile projelerinize uzaktan erişebilir. Ve dilediğiniz gibi dosya gönderebilir veya silebilirsiniz.</p>"},{"url":"/posts/git-kullanimi-ve-kafa-karistiran-seyler/","relativePath":"posts/git-kullanimi-ve-kafa-karistiran-seyler.md","relativeDir":"posts","base":"git-kullanimi-ve-kafa-karistiran-seyler.md","name":"git-kullanimi-ve-kafa-karistiran-seyler","frontmatter":{"title":"Git: Herkesin Kafasını Karıştıran Şeyler","author":"sametsunman","subtitle":"Git öğrenmeye başladığında her şey güzel gider. Sonra bir gün \"detached HEAD\" görürsün ve panik başlar. Bu yazıda git'in kafanı karıştıran taraflarını açıklıyoruz.","date":"2025-12-16","thumb_img_alt":"git","content_img_alt":"git","excerpt":"Git öğrenmeye başladığında her şey güzel gider. Sonra bir gün \"detached HEAD\" görürsün ve panik başlar. Bu yazıda git'in kafanı karıştıran taraflarını açıklıyoruz.","canonical_url":"","template":"post","thumb_img_path":"images/git_banner.png","content_img_path":"images/git_banner.png"},"html":"<p>Git kullanmaya başladığında <code>add</code>, <code>commit</code>, <code>push</code> öğrenirsin. \"Ne varmış bunda?\" dersin. Sonra bir gün conflict çıkar, <code>detached HEAD</code> uyarısı görürsün, yanlışlıkla bir şeyleri silersin... Ve o an anlarsın ki git derin bir okyanus.</p>\n<p>Gel, bu okyanusta kaybolmamak için en kafa karıştıran şeyleri konuşalım.</p>\n<h2>1. merge vs rebase - Ezelı Tartışma</h2>\n<p>İki branch'i birleştirmek istiyorsun. İki seçenek var:</p>\n<h3>merge</h3>\n<pre><code class=\"language-bash\">git checkout main\ngit merge feature\n</code></pre>\n<p>Bu, feature branch'indeki değişiklikleri main'e getirir ve bir \"merge commit\" oluşturur. Tarihçe şöyle görünür:</p>\n<pre><code>*   Merge branch 'feature'\n|\\\n| * feature commit 2\n| * feature commit 1\n* | main commit\n|/\n* ortak commit\n</code></pre>\n<h3>rebase</h3>\n<pre><code class=\"language-bash\">git checkout feature\ngit rebase main\n</code></pre>\n<p>Bu, feature branch'ini alır ve main'in ucuna \"yapıştırır\". Sanki feature'ı main'den yeni başlatmışsın gibi olur:</p>\n<pre><code>* feature commit 2\n* feature commit 1\n* main commit\n* ortak commit\n</code></pre>\n<h3>Hangisini Kullanmalı?</h3>\n<ul>\n<li><strong>merge</strong>: Tarihçeyi olduğu gibi korumak istiyorsan. Takım çalışmasında genelde daha güvenli.</li>\n<li><strong>rebase</strong>: Temiz, düz bir tarihçe istiyorsan. Ama dikkat: <strong>paylaşılmış branch'lerde rebase yapma!</strong> Başkalarının işini mahvedersin.</li>\n</ul>\n<p>Altın kural: \"Kendi local branch'inde rebase yap, paylaşılmış branch'lerde merge yap.\"</p>\n<h2>2. reset vs revert - Geri Alma İşleri</h2>\n<p>Bir commit'i geri almak istiyorsun. Ama nasıl?</p>\n<h3>git reset</h3>\n<p>Commit'leri tarihten siler (aslında silmez ama öyle görünür):</p>\n<pre><code class=\"language-bash\"># Son commit'i geri al, değişiklikleri staged tut\ngit reset --soft HEAD~1\n\n# Son commit'i geri al, değişiklikleri unstaged tut\ngit reset --mixed HEAD~1\n\n# Son commit'i geri al, değişiklikleri tamamen sil\ngit reset --hard HEAD~1\n</code></pre>\n<p><strong>Dikkat:</strong> <code>--hard</code> tehlikelidir. Kaydedilmemiş değişikliklerin gider.</p>\n<h3>git revert</h3>\n<p>Commit'i geri alan yeni bir commit oluşturur:</p>\n<pre><code class=\"language-bash\">git revert abc123\n</code></pre>\n<p>Tarihçeyi değiştirmez, sadece \"bu commit'i geri aldım\" diye yeni bir commit ekler.</p>\n<h3>Hangisini Kullanmalı?</h3>\n<ul>\n<li><strong>reset</strong>: Local'de, henüz push etmediğin commit'ler için</li>\n<li><strong>revert</strong>: Push ettiğin, başkalarıyla paylaştığın commit'ler için</li>\n</ul>\n<h2>3. Detached HEAD - Bu Da Ne?</h2>\n<p>Şu mesajı gördüğünde panik yapma:</p>\n<pre><code>You are in 'detached HEAD' state...\n</code></pre>\n<p>Bu sadece şu anlama geliyor: Bir branch'te değilsin, direkt bir commit'e bakıyorsun.</p>\n<p>Nasıl olur?</p>\n<pre><code class=\"language-bash\">git checkout abc123  # Bir commit hash'ine checkout\ngit checkout v1.0    # Bir tag'e checkout\n</code></pre>\n<p>Bu durumda yaptığın commit'ler hiçbir branch'e ait olmaz. Kaybolabilirler!</p>\n<h3>Çözüm</h3>\n<pre><code class=\"language-bash\"># Ya bir branch oluştur\ngit checkout -b yeni-branch\n\n# Ya da mevcut branch'ine geri dön\ngit checkout main\n</code></pre>\n<h2>4. Staging Area - Neden Var Bu?</h2>\n<p>Yeni başlayanlar hep sorar: \"Neden direkt commit etmiyoruz? Bu <code>add</code> ne işe yarıyor?\"</p>\n<p>Staging area (index), commit'e neyin gireceğini seçmeni sağlar. Diyelim 5 dosya değiştirdin ama sadece 3'ünü commit etmek istiyorsun:</p>\n<pre><code class=\"language-bash\">git add dosya1.js dosya2.js dosya3.js\ngit commit -m \"Sadece bu üçü\"\n</code></pre>\n<p>Hatta bir dosyanın sadece bazı satırlarını bile seçebilirsin:</p>\n<pre><code class=\"language-bash\">git add -p dosya.js\n</code></pre>\n<p>Bu sana her değişikliği tek tek sorar: \"Bunu ekleyeyim mi?\"</p>\n<h2>5. Stash - Değişiklikleri Kenara Koy</h2>\n<p>Bir şey üzerinde çalışıyorsun, acil başka branch'e geçmen gerekti. Ama commit etmek istemiyorsun çünkü iş yarım.</p>\n<pre><code class=\"language-bash\"># Değişiklikleri sakla\ngit stash\n\n# Başka branch'e geç, işini yap\ngit checkout main\n# ...\n\n# Geri dön ve değişiklikleri geri al\ngit checkout feature\ngit stash pop\n</code></pre>\n<h3>Stash İpuçları</h3>\n<pre><code class=\"language-bash\"># Stash'e isim ver\ngit stash save \"Login sayfası yarım kaldı\"\n\n# Stash listesini gör\ngit stash list\n\n# Belirli bir stash'i geri al\ngit stash apply stash@{2}\n\n# Stash'i silmeden uygula\ngit stash apply\n\n# Stash'i uygula ve sil\ngit stash pop\n</code></pre>\n<h2>6. Cherry-pick - Tek Commit Seç Al</h2>\n<p>Başka bir branch'ten sadece bir commit'i almak istiyorsun:</p>\n<pre><code class=\"language-bash\">git cherry-pick abc123\n</code></pre>\n<p>Bu, o commit'i alır ve şu anki branch'ine uygular. Çok kullanışlı ama dikkatli ol, aynı değişiklik iki yerde olunca ileride conflict çıkabilir.</p>\n<h2>7. Conflict Çözme - Kaçınılmaz Son</h2>\n<p>İki kişi aynı satırı değiştirince conflict çıkar:</p>\n<pre><code>&#x3C;&#x3C;&#x3C;&#x3C;&#x3C;&#x3C;&#x3C; HEAD\nconst x = 1;\n=======\nconst x = 2;\n>>>>>>> feature\n</code></pre>\n<p>Bu şu demek:</p>\n<ul>\n<li><code>&#x3C;&#x3C;&#x3C;&#x3C;&#x3C;&#x3C;&#x3C; HEAD</code> ile <code>=======</code> arası: Senin branch'indeki versiyon</li>\n<li><code>=======</code> ile <code>>>>>>>> feature</code> arası: Gelen branch'teki versiyon</li>\n</ul>\n<h3>Nasıl Çözersin?</h3>\n<ol>\n<li>Dosyayı aç</li>\n<li>Hangisi doğruysa onu bırak, diğerini ve işaretleri sil</li>\n<li><code>git add dosya.js</code></li>\n<li><code>git commit</code></li>\n</ol>\n<p>Ya da ikisini birleştir:</p>\n<pre><code class=\"language-javascript\">const x = 3; // İkisinin ortası bir değer\n</code></pre>\n<h3>VS Code Kullanıyorsan</h3>\n<p>VS Code conflict'leri çok güzel gösteriyor. \"Accept Current\", \"Accept Incoming\", \"Accept Both\" butonları var. Hayat kurtarıcı.</p>\n<h2>8. reflog - Git'in Gizli Süper Gücü</h2>\n<p>Bir şeyleri mahvettin, commit'lerin kayboldu mu? Panik yapma:</p>\n<pre><code class=\"language-bash\">git reflog\n</code></pre>\n<p>Bu, yaptığın her şeyin kaydını tutar. Reset, checkout, merge... Hepsi burada.</p>\n<pre><code>abc123 HEAD@{0}: reset: moving to HEAD~1\ndef456 HEAD@{1}: commit: Önemli değişiklik\nghi789 HEAD@{2}: checkout: moving from main to feature\n</code></pre>\n<p>Kayıp commit'ini buldun mu?</p>\n<pre><code class=\"language-bash\">git checkout def456\n# veya\ngit reset --hard def456\n</code></pre>\n<p><strong>reflog hayat kurtarır.</strong> Unutma.</p>\n<h2>9. .gitignore Çalışmıyor!</h2>\n<p><code>.gitignore</code>'a ekledin ama dosya hala takip ediliyor? Çünkü dosya zaten git'e eklenmişti.</p>\n<pre><code class=\"language-bash\"># Önce git'ten kaldır (dosyayı silmez)\ngit rm --cached dosya.txt\n\n# Sonra commit et\ngit commit -m \"dosya.txt artık takip edilmiyor\"\n</code></pre>\n<p>Klasör için:</p>\n<pre><code class=\"language-bash\">git rm -r --cached klasor/\n</code></pre>\n<h2>10. Upstream ve Origin - Kim Bu İnsanlar?</h2>\n<ul>\n<li><strong>origin</strong>: Senin remote repository'n (genelde GitHub'daki repo)</li>\n<li><strong>upstream</strong>: Fork ettiğin orijinal repository</li>\n</ul>\n<pre><code class=\"language-bash\"># Origin'i gör\ngit remote -v\n\n# Upstream ekle (fork'larda)\ngit remote add upstream https://github.com/orijinal/repo.git\n\n# Upstream'den güncelleme al\ngit fetch upstream\ngit merge upstream/main\n</code></pre>\n<h2>11. git pull vs git fetch</h2>\n<h3>fetch</h3>\n<p>Sadece remote'taki değişiklikleri indirir, birleştirmez:</p>\n<pre><code class=\"language-bash\">git fetch origin\n</code></pre>\n<p>Sonra istersen incele:</p>\n<pre><code class=\"language-bash\">git log origin/main\ngit diff main origin/main\n</code></pre>\n<h3>pull</h3>\n<p>fetch + merge yapar:</p>\n<pre><code class=\"language-bash\">git pull origin main\n# Şuna eşit:\n# git fetch origin\n# git merge origin/main\n</code></pre>\n<p><strong>Tavsiye:</strong> Önce <code>fetch</code> yap, bak ne gelmiş, sonra <code>merge</code> yap. Daha kontrollü.</p>\n<h2>12. Commit Mesajı Yazma Sanatı</h2>\n<p>Kötü commit mesajları:</p>\n<pre><code>fix\nasdasd\nwip\ndeğişiklik yaptım\n</code></pre>\n<p>İyi commit mesajları:</p>\n<pre><code>feat: Kullanıcı giriş sayfası eklendi\nfix: Login butonunun tıklanmama sorunu düzeltildi\nrefactor: Auth servisindeki tekrar eden kod temizlendi\ndocs: README'ye kurulum adımları eklendi\n</code></pre>\n<h3>Conventional Commits</h3>\n<p>Bu format çok yaygın:</p>\n<pre><code>&#x3C;tip>: &#x3C;açıklama>\n\n[opsiyonel gövde]\n\n[opsiyonel footer]\n</code></pre>\n<p>Tipler:</p>\n<ul>\n<li><code>feat</code>: Yeni özellik</li>\n<li><code>fix</code>: Bug düzeltme</li>\n<li><code>docs</code>: Dokümantasyon</li>\n<li><code>style</code>: Kod formatı (işlevsel değişiklik yok)</li>\n<li><code>refactor</code>: Kod düzenleme</li>\n<li><code>test</code>: Test ekleme</li>\n<li><code>chore</code>: Build, config değişiklikleri</li>\n</ul>\n<h2>Bonus: Faydalı Alias'lar</h2>\n<p><code>.gitconfig</code> dosyana ekle:</p>\n<pre><code class=\"language-ini\">[alias]\n    st = status\n    co = checkout\n    br = branch\n    ci = commit\n    lg = log --oneline --graph --decorate\n    unstage = reset HEAD --\n    last = log -1 HEAD\n    undo = reset --soft HEAD~1\n</code></pre>\n<p>Artık <code>git st</code> yazman yeterli.</p>\n<h2>Son Söz</h2>\n<p>Git başta zor görünür ama mantığını kavradıktan sonra vazgeçilmez oluyor. En önemli şey: <strong>Deney yap, ama önemli projelerde değil!</strong></p>\n<p>Bir test repository'si oluştur, içinde her şeyi dene. Reset yap, rebase yap, conflict oluştur, çöz. Korkmadan öğrenirsin.</p>\n<p>Ve unutma: <code>git reflog</code> her zaman arkanda.</p>\n<hr>\n<p><em>Git ile ilgili sorularını yorumlarda paylaş. Hangi komut kafanı karıştırıyor?</em></p>"},{"url":"/posts/javascript-array-object-properties-sum/","relativePath":"posts/javascript-array-object-properties-sum.md","relativeDir":"posts","base":"javascript-array-object-properties-sum.md","name":"javascript-array-object-properties-sum","frontmatter":{"title":"Javascript'te bir array object'nin içindeki veriler nasıl toplanır?","subtitle":"Fonksiyon kullanarak bir nesne dizisinin içerisindeki belirli bir niteliklerin toplamını getirebiliriz. ","date":"2022-11-10T00:00:00.000Z","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"sametsunman","template":"post","thumb_img_path":"images/sumFloatingArray.png","content_img_path":"images/sumFloatingArray.png"},"html":"<p>Aşağıdaki fonksiyonu kullanarak bir nesne içerisindeki belirli bir properties'lerin toplamını verir.\narr: Array object'sini ifade eder.\nname: Property ismini ifade eder.</p>\n<pre><code>    const sumFloatingArray = (arr, name) => {\n        return parseFloat(arr.reduce((acc, obj) => acc + (parseFloat(obj[name]) ?? 0.0), 0) || 0);\n    };\n</code></pre>"},{"url":"/posts/javascript-ile-sayfalari-otomatik-olarak-scrolllamak/","relativePath":"posts/javascript-ile-sayfalari-otomatik-olarak-scrolllamak.md","relativeDir":"posts","base":"javascript-ile-sayfalari-otomatik-olarak-scrolllamak.md","name":"javascript-ile-sayfalari-otomatik-olarak-scrolllamak","frontmatter":{"title":"Javascript ile sayfaları otomatik olarak scroll'lamak","author":"sametsunman","subtitle":"Twitter, facebook gibi akış sayfaları yüklemek için farenizin tekerini kullanarak sürüklemeniz gerekmektedir. Bunu javascript ile otomatik yapabilirsiniz.","date":"2020-07-17","thumb_img_alt":"infinityScroll","content_img_alt":"infinityScroll","excerpt":"Twitter, facebook gibi akış sayfaları yüklemek için farenizin tekerini kullanarak sürüklemeniz gerekmektedir. Bunu javascript ile otomatik yapabilirsiniz.","canonical_url":"","template":"post","thumb_img_path":"images/infinityScroll.png","content_img_path":"images/infinityScroll.png"},"html":"<p>Yukarıdaki gibi tarayıcınızın F12'ye basarak ya da sağ tıkta öğeyi incele diyerek geliştirici sayfasını açın. Konsol bölümüne aşağıdaki kodu yapıştırın.</p>\n<pre><code>function pageScroll() {window.scrollBy(0,100);scrolldelay = setTimeout(pageScroll,1);}pageScroll();\n</code></pre>\n<p>Böylece sayfa otomatik olarak aşağı inecek ve tüm sayfa yüklenecek. Sayfanın sonu varsa sonuna ulaşabileceksiniz.</p>"},{"url":"/posts/javascript-asenkron-programlama/","relativePath":"posts/javascript-asenkron-programlama.md","relativeDir":"posts","base":"javascript-asenkron-programlama.md","name":"javascript-asenkron-programlama","frontmatter":{"title":"JavaScript'te Asenkron Programlama: Callback'ten Async/Await'e","author":"sametsunman","subtitle":"Callback hell'de kaybolmuş, Promise zincirlerinde boğulmuş biri misin? Merak etme, JavaScript'in asenkron dünyasını en baştan, adım adım anlatıyoruz.","date":"2025-12-16","thumb_img_alt":"javascript async","content_img_alt":"javascript async","excerpt":"Callback hell'de kaybolmuş, Promise zincirlerinde boğulmuş biri misin? Merak etme, JavaScript'in asenkron dünyasını en baştan, adım adım anlatıyoruz.","canonical_url":"","template":"post","thumb_img_path":"images/async_js.png","content_img_path":"images/async_js.png"},"html":"<p>JavaScript tek thread'li bir dil. Yani aynı anda sadece bir iş yapabilir. Peki API'den veri çekerken sayfa nasıl donmuyor? İşte asenkron programlamanın sihri burada başlıyor.</p>\n<p>Bu yazıda callback'lerden başlayıp, Promise'lere, oradan da async/await'e kadar tüm yolculuğu yapacağız.</p>\n<h2>Önce Senkron vs Asenkron Nedir?</h2>\n<h3>Senkron Kod</h3>\n<pre><code class=\"language-javascript\">console.log(\"1\");\nconsole.log(\"2\");\nconsole.log(\"3\");\n// Çıktı: 1, 2, 3 (sırayla)\n</code></pre>\n<p>Her satır bir önceki bitmeden çalışmaz. Basit ve öngörülebilir.</p>\n<h3>Asenkron Kod</h3>\n<pre><code class=\"language-javascript\">console.log(\"1\");\nsetTimeout(() => console.log(\"2\"), 1000);\nconsole.log(\"3\");\n// Çıktı: 1, 3, 2\n</code></pre>\n<p><code>setTimeout</code> asenkron. JavaScript \"1 saniye sonra çalıştır\" der ve devam eder. \"3\" yazdırılır, 1 saniye sonra \"2\" gelir.</p>\n<h2>Callback - Her Şeyin Başladığı Yer</h2>\n<p>Callback, bir fonksiyona parametre olarak verdiğin başka bir fonksiyon. \"İşin bitince bunu çağır\" demek gibi.</p>\n<pre><code class=\"language-javascript\">function veriCek(callback) {\n  setTimeout(() => {\n    const veri = { isim: \"Ahmet\", yas: 25 };\n    callback(veri);\n  }, 1000);\n}\n\nveriCek((sonuc) => {\n  console.log(sonuc); // { isim: \"Ahmet\", yas: 25 }\n});\n</code></pre>\n<p>Güzel görünüyor değil mi? Ama bekle...</p>\n<h3>Callback Hell (Piramit of Doom)</h3>\n<p>Birden fazla asenkron işlem sırayla yapman gerekince:</p>\n<pre><code class=\"language-javascript\">kullaniciyiGetir(1, (kullanici) => {\n  siparisleriGetir(kullanici.id, (siparisler) => {\n    siparisDetayGetir(siparisler[0].id, (detay) => {\n      odemeGetir(detay.odemeId, (odeme) => {\n        kargoTakip(odeme.kargoNo, (kargo) => {\n          console.log(kargo);\n          // Daha da derine inebilir...\n        });\n      });\n    });\n  });\n});\n</code></pre>\n<p>Buna \"Callback Hell\" veya \"Pyramid of Doom\" deniyor. Okumak zor, debug etmek kabus, hata yakalamak imkansıza yakın.</p>\n<h3>Error Handling Sorunu</h3>\n<pre><code class=\"language-javascript\">veriCek((hata, sonuc) => {\n  if (hata) {\n    console.error(hata);\n    return;\n  }\n  baskaBirsey(sonuc, (hata2, sonuc2) => {\n    if (hata2) {\n      console.error(hata2);\n      return;\n    }\n    // Her seviyede hata kontrolü...\n  });\n});\n</code></pre>\n<p>Her callback'te ayrı ayrı hata kontrolü. Çıldırtıcı.</p>\n<h2>Promise - Kurtarıcı Geliyor</h2>\n<p>ES6 ile birlikte Promise geldi ve hayatımız değişti.</p>\n<p>Promise, gelecekte bir değer döneceğini \"söz veren\" bir nesne. Üç durumu var:</p>\n<ul>\n<li><strong>pending</strong>: Henüz sonuçlanmadı</li>\n<li><strong>fulfilled</strong>: Başarıyla tamamlandı</li>\n<li><strong>rejected</strong>: Hata oluştu</li>\n</ul>\n<h3>Promise Oluşturma</h3>\n<pre><code class=\"language-javascript\">const soz = new Promise((resolve, reject) => {\n  setTimeout(() => {\n    const basarili = true;\n\n    if (basarili) {\n      resolve({ isim: \"Ahmet\", yas: 25 });\n    } else {\n      reject(new Error(\"Bir şeyler ters gitti\"));\n    }\n  }, 1000);\n});\n</code></pre>\n<h3>Promise Kullanma</h3>\n<pre><code class=\"language-javascript\">soz\n  .then((sonuc) => {\n    console.log(sonuc);\n  })\n  .catch((hata) => {\n    console.error(hata);\n  });\n</code></pre>\n<h3>Callback Hell'i Promise ile Çözme</h3>\n<pre><code class=\"language-javascript\">kullaniciyiGetir(1)\n  .then(kullanici => siparisleriGetir(kullanici.id))\n  .then(siparisler => siparisDetayGetir(siparisler[0].id))\n  .then(detay => odemeGetir(detay.odemeId))\n  .then(odeme => kargoTakip(odeme.kargoNo))\n  .then(kargo => console.log(kargo))\n  .catch(hata => console.error(\"Bir yerde hata oluştu:\", hata));\n</code></pre>\n<p>Düz bir zincir! Okunması çok daha kolay. Ve tek bir <code>catch</code> tüm hataları yakalar.</p>\n<h3>Promise Metodları</h3>\n<h4>Promise.all - Hepsini Bekle</h4>\n<p>Birden fazla Promise'i paralel çalıştır, hepsi bitince devam et:</p>\n<pre><code class=\"language-javascript\">const p1 = fetch('/api/kullanici');\nconst p2 = fetch('/api/urunler');\nconst p3 = fetch('/api/kampanyalar');\n\nPromise.all([p1, p2, p3])\n  .then(([kullanici, urunler, kampanyalar]) => {\n    console.log(\"Hepsi geldi!\");\n  })\n  .catch(hata => {\n    // Herhangi biri başarısız olursa burası çalışır\n  });\n</code></pre>\n<p><strong>Dikkat:</strong> Biri bile reject olursa, tümü başarısız sayılır.</p>\n<h4>Promise.allSettled - Hepsinin Sonucunu Al</h4>\n<p>Hepsi bitsin, başarılı veya başarısız farketmez:</p>\n<pre><code class=\"language-javascript\">Promise.allSettled([p1, p2, p3])\n  .then(sonuclar => {\n    sonuclar.forEach(sonuc => {\n      if (sonuc.status === 'fulfilled') {\n        console.log('Başarılı:', sonuc.value);\n      } else {\n        console.log('Başarısız:', sonuc.reason);\n      }\n    });\n  });\n</code></pre>\n<h4>Promise.race - İlk Gelen Kazanır</h4>\n<p>Hangisi önce biterse onun sonucunu al:</p>\n<pre><code class=\"language-javascript\">const yavas = new Promise(resolve => setTimeout(() => resolve('Yavaş'), 2000));\nconst hizli = new Promise(resolve => setTimeout(() => resolve('Hızlı'), 500));\n\nPromise.race([yavas, hizli])\n  .then(sonuc => console.log(sonuc)); // \"Hızlı\"\n</code></pre>\n<p>Timeout mekanizması için kullanışlı:</p>\n<pre><code class=\"language-javascript\">const timeout = new Promise((_, reject) =>\n  setTimeout(() => reject(new Error('Zaman aşımı!')), 5000)\n);\n\nPromise.race([fetch('/api/veri'), timeout])\n  .then(sonuc => console.log(sonuc))\n  .catch(hata => console.error(hata)); // 5 saniyede cevap gelmezse hata\n</code></pre>\n<h4>Promise.any - İlk Başarılı Olan</h4>\n<p>race'e benzer ama sadece başarılı olanları dikkate alır:</p>\n<pre><code class=\"language-javascript\">Promise.any([p1, p2, p3])\n  .then(ilkBasarili => console.log(ilkBasarili));\n</code></pre>\n<p>Hepsi reject olursa <code>AggregateError</code> fırlatır.</p>\n<h2>Async/Await - Promise'in Şeker Kaplaması</h2>\n<p>ES2017 ile gelen async/await, Promise'leri senkron kod gibi yazmamızı sağlar.</p>\n<h3>Temel Kullanım</h3>\n<pre><code class=\"language-javascript\">async function veriGetir() {\n  const sonuc = await fetch('/api/kullanici');\n  const veri = await sonuc.json();\n  return veri;\n}\n</code></pre>\n<p><code>await</code> kelimesi Promise'in resolve olmasını bekler. Ama sadece <code>async</code> fonksiyonların içinde kullanabilirsin.</p>\n<h3>Callback Hell'i Async/Await ile Çözme</h3>\n<p>Hatırla o korkunç piramidi:</p>\n<pre><code class=\"language-javascript\">async function tumSurec() {\n  const kullanici = await kullaniciyiGetir(1);\n  const siparisler = await siparisleriGetir(kullanici.id);\n  const detay = await siparisDetayGetir(siparisler[0].id);\n  const odeme = await odemeGetir(detay.odemeId);\n  const kargo = await kargoTakip(odeme.kargoNo);\n\n  console.log(kargo);\n}\n</code></pre>\n<p>Senkron kod gibi görünüyor ama asenkron çalışıyor. Güzel değil mi?</p>\n<h3>Hata Yakalama</h3>\n<pre><code class=\"language-javascript\">async function veriGetir() {\n  try {\n    const sonuc = await fetch('/api/kullanici');\n    const veri = await sonuc.json();\n    return veri;\n  } catch (hata) {\n    console.error(\"Hata oluştu:\", hata);\n    throw hata; // Hatayı yukarı fırlat\n  }\n}\n</code></pre>\n<p><code>try/catch</code> kullan. Bildiğin senkron hata yakalama gibi.</p>\n<h3>Paralel İşlemler</h3>\n<p>Dikkat! Bu yavaş:</p>\n<pre><code class=\"language-javascript\">async function yavas() {\n  const a = await islem1(); // 2 saniye\n  const b = await islem2(); // 2 saniye\n  // Toplam: 4 saniye\n}\n</code></pre>\n<p>Her await bir öncekinin bitmesini bekliyor. Ama işlemler birbirinden bağımsızsa:</p>\n<pre><code class=\"language-javascript\">async function hizli() {\n  const [a, b] = await Promise.all([\n    islem1(),\n    islem2()\n  ]);\n  // Toplam: 2 saniye (paralel çalışır)\n}\n</code></pre>\n<p>Ya da şöyle:</p>\n<pre><code class=\"language-javascript\">async function hizli2() {\n  const p1 = islem1(); // Başlat\n  const p2 = islem2(); // Başlat\n\n  const a = await p1; // Bekle\n  const b = await p2; // Bekle\n}\n</code></pre>\n<h3>Arrow Function ile</h3>\n<pre><code class=\"language-javascript\">const veriGetir = async () => {\n  const sonuc = await fetch('/api/veri');\n  return sonuc.json();\n};\n</code></pre>\n<h3>IIFE (Immediately Invoked Function Expression)</h3>\n<p>Top-level await yoksa (eski Node.js veya browser):</p>\n<pre><code class=\"language-javascript\">(async () => {\n  const veri = await veriGetir();\n  console.log(veri);\n})();\n</code></pre>\n<h3>Top-Level Await</h3>\n<p>ES2022 ve modern ortamlarda modül içinde direkt kullanabilirsin:</p>\n<pre><code class=\"language-javascript\">// module.js\nconst veri = await fetch('/api/veri');\nexport default veri;\n</code></pre>\n<h2>Gerçek Dünya Örneği</h2>\n<p>Bir kullanıcı profil sayfası düşün:</p>\n<pre><code class=\"language-javascript\">async function profilSayfasiniYukle(userId) {\n  try {\n    // Paralel istekler\n    const [kullanici, gonderiler, takipciler] = await Promise.all([\n      fetch(`/api/kullanici/${userId}`).then(r => r.json()),\n      fetch(`/api/kullanici/${userId}/gonderiler`).then(r => r.json()),\n      fetch(`/api/kullanici/${userId}/takipciler`).then(r => r.json())\n    ]);\n\n    return {\n      kullanici,\n      gonderiler,\n      takipciler,\n      yuklenmeTarihi: new Date()\n    };\n  } catch (hata) {\n    console.error('Profil yüklenemedi:', hata);\n    return null;\n  }\n}\n\n// Kullanım\nconst profil = await profilSayfasiniYukle(123);\nif (profil) {\n  renderProfil(profil);\n} else {\n  gosterHataMesaji();\n}\n</code></pre>\n<h2>Yaygın Hatalar ve Çözümleri</h2>\n<h3>1. await Unutmak</h3>\n<pre><code class=\"language-javascript\">// YANLIŞ\nasync function hatali() {\n  const veri = fetch('/api/veri'); // Promise döner, veri değil!\n  console.log(veri); // Promise { &#x3C;pending> }\n}\n\n// DOĞRU\nasync function dogru() {\n  const response = await fetch('/api/veri');\n  const veri = await response.json();\n  console.log(veri);\n}\n</code></pre>\n<h3>2. forEach ile await</h3>\n<pre><code class=\"language-javascript\">// YANLIŞ - await çalışmaz!\nids.forEach(async (id) => {\n  await islem(id);\n});\n\n// DOĞRU - for...of kullan\nfor (const id of ids) {\n  await islem(id);\n}\n\n// VEYA - paralel çalıştır\nawait Promise.all(ids.map(id => islem(id)));\n</code></pre>\n<h3>3. Reject'i Yakalamamak</h3>\n<pre><code class=\"language-javascript\">// YANLIŞ - hata yakalanmaz\nasync function tehlikeli() {\n  const veri = await fetch('/api/veri');\n  return veri.json();\n}\ntehlikeli(); // Hata olursa? Unhandled rejection!\n\n// DOĞRU\ntehlikeli().catch(hata => console.error(hata));\n\n// VEYA\ntry {\n  await tehlikeli();\n} catch (hata) {\n  console.error(hata);\n}\n</code></pre>\n<h2>Özet: Hangisini Ne Zaman Kullan?</h2>\n<table>\n<thead>\n<tr>\n<th>Yöntem</th>\n<th>Ne Zaman</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Callback</td>\n<td>Event listener'lar, basit tek seferlik işler</td>\n</tr>\n<tr>\n<td>Promise</td>\n<td>Kütüphane yazıyorsan, zincirleme işlemler</td>\n</tr>\n<tr>\n<td>Async/Await</td>\n<td>Çoğu durumda (en okunabilir)</td>\n</tr>\n<tr>\n<td>Promise.all</td>\n<td>Paralel bağımsız işlemler</td>\n</tr>\n<tr>\n<td>Promise.race</td>\n<td>Timeout, ilk cevap yeter senaryoları</td>\n</tr>\n</tbody>\n</table>\n<h2>Son Söz</h2>\n<p>JavaScript'in asenkron yapısı başta kafa karıştırıcı olabilir. Ama mantığını kavradıktan sonra çok güçlü bir araç haline geliyor.</p>\n<p>Şunu unutma:</p>\n<ul>\n<li><strong>Callback</strong>: Tarihin tozlu sayfaları (ama hala event'lerde kullanılıyor)</li>\n<li><strong>Promise</strong>: Callback hell'in ilacı</li>\n<li><strong>Async/Await</strong>: Promise'in okunabilir hali</li>\n</ul>\n<p>Günümüzde async/await tercih ediliyor. Kod daha temiz, hata ayıklama daha kolay. Ama Promise'leri de iyi anla çünkü async/await'in altında Promise var.</p>\n<p>Pratik yap, gerçek projeler yaz. Bir süre sonra asenkron düşünmek doğal gelecek.</p>\n<hr>\n<p><em>Asenkron JavaScript hakkında soruların varsa yorumlarda paylaş. Hep birlikte öğrenelim!</em></p>"},{"url":"/posts/javascript-click-fonsksiyonu-tetikleme/","relativePath":"posts/javascript-click-fonsksiyonu-tetikleme.md","relativeDir":"posts","base":"javascript-click-fonsksiyonu-tetikleme.md","name":"javascript-click-fonsksiyonu-tetikleme","frontmatter":{"title":"Javascript ile bir elementin click fonksiyonu nasıl tetiklenir?","subtitle":"JQuery kullanmadan pure javascript ile bir html elementinin tıklanması nasıl tetikleneceğini inceleyelim. ","date":"2023-01-13T00:00:00.000Z","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"sametsunman","template":"post","thumb_img_path":"images/javascript-click-trigger.jpg","content_img_path":"images/javascript-click-trigger.jpg"},"html":"<p>Bu aslında JQuery ile oldukça basit.\nÖrneğin 'blah' id'li bir element aşağıdaki kod ile basitçe tetiklenebilir.</p>\n<pre><code>$('#blah').trigger('click');\n</code></pre>\n<p>Ancak, temel javascriptte bir kaç kod daha yazılmalı. Bu durumda aşağıdaki şekilde kullanabiliyoruz.</p>\n<pre><code>var event = document.createEvent(\"Event\");\nevent.initEvent(\"click\", false, true);\nvar element = document.getElementById(\"blah\");\nelement.dispatchEvent(event);\n</code></pre>\n<p>Burdana sonrası sizin hayal gücünüze bağlı, ister bunu bir fonksiyon içerisinde kullanın, isterseniz de modern ulaşamadığınız javascript kütüphaneleri için kullanın.</p>\n<p>Örneğin aşağıdaki örnekte ben, 'devextreme' kütüphanesindeki delete butonunu tetiklemek için kullandım:\n<img src=\"http://asnus.com/images/javascript-click-trigger.jpg\"></p>"},{"url":"/posts/javascriptte-bir-nesne-dizisi-nasil-siralanir/","relativePath":"posts/javascriptte-bir-nesne-dizisi-nasil-siralanir.md","relativeDir":"posts","base":"javascriptte-bir-nesne-dizisi-nasil-siralanir.md","name":"javascriptte-bir-nesne-dizisi-nasil-siralanir","frontmatter":{"title":"Javascript'te bir nesne dizisi nasıl sıralanır?","author":"sametsunman","subtitle":"Sort metoduyla bir diziyi sıralamak oldukça kolay, ancak bu dizi, bir nesne dizisiyse işimiz biraz daha karmaşık. Hadi bakalım.","date":"2020-03-16","thumb_img_alt":"javascript-sorting","content_img_alt":"javascript-sorting","excerpt":"Sort metoduyla bir diziyi sıralamak oldukça kolay, ancak bu dizi, bir nesne dizisiyse işimiz biraz daha karmaşık. Hadi bakalım.","canonical_url":"","template":"post","thumb_img_path":"images/javascript-sorting.png","content_img_path":"images/javascript-sorting.png"},"html":"<p>itemList adında json formatında bir nesnemiz olsun:</p>\n<pre><code>var itemList = [{id:1,name:'samet'},{id:2,name:'ihsan'},{id:3,name:'şule'},{id:4,name:'alp'},]\n</code></pre>\n<p>Bu listeyi isme göre alfabetik sıraya dizmek için aşağıdaki fonksiyonu kullanabiliriz:</p>\n<pre><code>  var newItemList = itemList.sort(this.compare);\n\n  compare(a, b) {\n\n    let comparison = 0;\n    if (a.name > b.name) {\n      comparison = 1;\n    } else if (a.name &#x3C; b.name) {\n      comparison = -1;\n    }\n    return comparison;\n  }\n</code></pre>\n<p>Yada ES6 kullanıyorsanız şu şekilde çok daha kısa şekilde yapabilirsiniz:</p>\n<pre><code>  var newItemList = itemList.sort((a, b) => a.name.localeCompare(b.name);\n  \n</code></pre>"},{"url":"/posts/kibanada-elasticsearch-index-istatistiklerini-gorme-ve-kayitlari-silme/","relativePath":"posts/kibanada-elasticsearch-index-istatistiklerini-gorme-ve-kayitlari-silme.md","relativeDir":"posts","base":"kibanada-elasticsearch-index-istatistiklerini-gorme-ve-kayitlari-silme.md","name":"kibanada-elasticsearch-index-istatistiklerini-gorme-ve-kayitlari-silme","frontmatter":{"title":"Kibana'da ElasticSearch index istatistiklerini görme ve kayıtları silme","author":"sametsunman","subtitle":"Kibana üzerinden elastic search verilerini silmek ve veri istatistiklerini görmek oldukça kolay, hadi bakalım.","date":"2020-08-24","thumb_img_alt":"kibana","content_img_alt":"kibana","excerpt":"Kibana'daki bir index'e ait bilgileri görmek istiyorsak aşağıdaki komutu Dev Tools sekmesinden konsola yazabiliriz.","canonical_url":"","template":"post","thumb_img_path":"images/kibana.png","content_img_path":"images/kibana.png"},"html":"<p>Kibana'daki bir index'e ait bilgileri görmek istiyorsak aşağıdaki komutu Dev Tools sekmesinden konsola yazabiliriz.</p>\n<pre><code>GET /index_name/_stats\n</code></pre>\n<p>Eğer bir index'in altındaki belli bir aralıktaki kayıtları silmek istiyorsak da 'lt parametresine zaman aralığı vererek  kayıtları silebiliriz. Aşağıdaki kayıtta bugünden itibaren son 1 ayın kayıtlarını silecek</p>\n<pre><code>DELETE /anlik_mail/\n{\n\"query\": {\n\"range\": {\n\"@timestamp\": {\n\"lt\": \"now-30d\"\n}\n}\n}\n}\n</code></pre>"},{"url":"/posts/javascript-ile-harflerden-avatar-resmi-olusturma/","relativePath":"posts/javascript-ile-harflerden-avatar-resmi-olusturma.md","relativeDir":"posts","base":"javascript-ile-harflerden-avatar-resmi-olusturma.md","name":"javascript-ile-harflerden-avatar-resmi-olusturma","frontmatter":{"title":"JavaScript ile Harflerden Avatar Resmi Oluşturma","author":"sametsunman","subtitle":"Kullanıcıların profil resmi olmadığında insan silüeti göstermek yerine isminin baş harflerinden bir resim oluşturabiliriz. Böylece her kullanıcının kendine özgü profil resmi olacak. Hadi Javascript ile nasıl yapıldığına bakalım.","date":"2019-11-03","thumb_img_alt":"canvas-avatar","content_img_alt":"canvas-avatar","excerpt":"Kullanıcıların profil resmi olmadığında insan silüeti göstermek yerine isminin baş harflerinden bir resim oluşturabiliriz. Böylece her kullanıcının kendine özgü profil resmi olacak. Hadi Javascript ile nasıl yapıldığına bakalım.","canonical_url":"","template":"post","thumb_img_path":"images/canvasAvatar.jpg","content_img_path":"images/canvasAvatar.jpg"},"html":"<pre><code>          &#x3C;canvas\n            className=\"user-avatar rounded-circle mr-2\"\n            id=\"canvas\"\n            width=\"50\"\n            height=\"50\"\n            alt=\"User Avatar\">&#x3C;/canvas>\n</code></pre>\n<p>Html kodumuzu body kısmına ekleyelim</p>\n<pre><code>&#x3C;script>\n    //Adımızı tanımlıyoruz\n    var name = 'Samet Sunman';\n    //Adımızın başharfini ve soyadımızın başharfini buluyoruz\n    var initial = name.charAt(0) + name.charAt(name.search(\" \") + 1);\n    //Renk belirlemek için rastgele bir sayı belirliyoruz\n    var color = Math.floor(Math.random() * 360);\n\n    var canvas = document.getElementById(\"canvas\");\n    var ctx = canvas.getContext(\"2d\");\n    var radius = canvas.height / 2;\n\n    ctx.translate(radius, radius);\n    \n    //Bir daire oluşturuyoruz\n    ctx.beginPath();\n    ctx.arc(0, 0, radius, 0, 2 * Math.PI);\n    ctx.fillStyle = 'hsl(' + color + ', 100%, 30%)';\n    ctx.fill();\n\n    //Harfleri de dairenin üzerine ekliyoruz\n    ctx.beginPath();\n    ctx.font = \"25px Arial\";\n    ctx.fillStyle = \"white\";\n    ctx.textAlign = \"center\";\n    ctx.fillText(initial, 0, 9);\n&#x3C;/script>\n</code></pre>\n<p>İşte bu kadar, ismimizin baş harflerinden rasfele renklerden avatar yapmış olduk.</p>"},{"url":"/posts/linux'ta-initramfs-hatasi-nasil-duzeltilir/","relativePath":"posts/linux'ta-initramfs-hatasi-nasil-duzeltilir.md","relativeDir":"posts","base":"linux'ta-initramfs-hatasi-nasil-duzeltilir.md","name":"linux'ta-initramfs-hatasi-nasil-duzeltilir","frontmatter":{"title":"Linux'ta Initramfs Hatası Nasıl Düzeltilir?","author":"ihsansunman","subtitle":"Bu hata genelde disk üzerinde bir sorunla karşılaşıldığında bu hatayı ekranımızda görürüz. Sistem işlem anında kapandığında veya diskinizde bad sector gibi ciddi bir sorun oluştuğunda bu hatayı alırız.","date":"2019-12-19","thumb_img_alt":"","content_img_alt":"","excerpt":"Bu hata genelde disk üzerinde bir sorunla karşılaşıldığında bu hatayı ekranımızda görürüz. Sistem işlem anında kapandığında veya diskinizde bad sector gibi ciddi bir sorun oluştuğunda bu hatayı alırız. ","canonical_url":"","template":"post","thumb_img_path":"images/initramfs.jpg","content_img_path":"images/initramfs.jpg"},"html":"<h2>Initramfs Hatası Çözümü</h2>\n<p>Öncelikle yanımızda Linux kurulum USB’si veya CD’si olması lazım çünkü sağlam çalışan bir linux gerekiyor. Linux’u USB üzerinden başlatalım. Daha sonrasında Uç Birimi açalım.</p>\n<pre><code>sudo fsck /dev/sda1 \n</code></pre>\n<p>Yukarıdaki komutu başlatalım. Sda1 bizim dosya sistemimizin neresi olduğunu belirtir. Eğer farklı bir konuma kurulum yaptıysanız sda1 kısmını kendinize göre lütfen düzeltiniz. Fsck kısmı dosya sistemimizin durumunu kontrol eden komuttur. Sorun olduğunda ise düzeltme sağlanır. Ancak sürekli bu hatayı alıyorsanız diskinizi kontrol ediniz. Çünkü bad sector olma olasılığı yüksek. Burada ise yeni bir disk almanızı tavsiye ediyorum.</p>"},{"url":"/posts/nedir-bu-react/","relativePath":"posts/nedir-bu-react.md","relativeDir":"posts","base":"nedir-bu-react.md","name":"nedir-bu-react","frontmatter":{"title":"React - Nedir Bu React?","subtitle":"React nedir sorusuna verilebilecek en kısa cevap \"Javascript Kütüphanesi\" olacaktır. Peki neden buna ihtiyaç duyduk? Neden kütüphane oluşturulması gerekti, bunları cevaplamamız gerekir.","date":"2022-04-15","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/react-1.png","content_img_path":"images/react-1.png"},"html":"<p>Vanilla Javascript'te <em>(console veya document çıktı sunan, JQuery gibi her hangi bir kütüphaneye sahip olmayan Javascript'in yalın halidir.)</em> efor sarf ederek yaptığımız bir işlemi React ile daha az efor ve kod yapısı ile yapabiliriz.</p>\n<p>Javascript imperative bir programlama dilidir. Yani her işlemi tek tek açıklamamız ve bildirmemiz gereken bir yapısı vardır. Örneğin bir H1 elementi oluşturalım ve bunu sayfamızın \"body\" kısmına ekleyelim. </p>\n<pre><code>const siteHeader = document.createElement(\"h1\");  \nsiteHeader.innerHtml = \"Siteme Hoşgeldiniz\"; \ndocument.body.append(siteHeader);\n</code></pre>\n<p>Burada Vanilla Javascript kullanarak öncelik olarak h1 elementi oluşturduk. İçerisine \"Siteme Hoşgeldiniz\" yazısını yazdırdık. Son olarak ise body kısmına bu elementimizi aktarmış olduk.</p>\n<p>Aynı işlemi declarative programlama kullanan react ile yaptığımızda ise sadece ne yapmak istediğimizi bildirmemiz yeterli olacaktır.</p>\n<pre><code>return(\n     &#x3C;h1>Siteme Hoşgeldiniz&#x3C;/h1>\n)\n</code></pre>\n<p>Gördüğünüz gibi XML yapısı gibi sadece tagleme yaparak react kütüphanesine h1 elementi içerisine yazı yazdırmak istediğimizi bildirdik. Daha az kod ile aynı çıktıyı almış olduk. </p>\n<p>Burada dikkat etmemiz gereken unsur ise return dönerken wrapper element kullanmamız gerektiği olacaktır. Tek çıktı yapması sebebi ile return içerisinde tek bir element olmalı. Diğer elementler bu elemente dahil olmalıdır. </p>\n<pre><code>return(\n    &#x3C;div>Hello&#x3C;/div>\n    &#x3C;div>React&#x3C;/div>\n)\n</code></pre>\n<p>Bu şekilde olduğunda iki farklı element olduğundan hata alırız. Ancak bu iki elementi tek bir element içerisinde döndürdüğümüzde hata almadan çıktımızı görürüz.</p>\n<pre><code>return(\n    &#x3C;div>\n    &#x3C;div>Hello&#x3C;/div>\n    &#x3C;div>React&#x3C;/div>\n    &#x3C;/div>\n)\n</code></pre>"},{"url":"/posts/net-core-web-apida-put-ve-delete-icin-cors-hatasi/","relativePath":"posts/net-core-web-apida-put-ve-delete-icin-cors-hatasi.md","relativeDir":"posts","base":"net-core-web-apida-put-ve-delete-icin-cors-hatasi.md","name":"net-core-web-apida-put-ve-delete-icin-cors-hatasi","frontmatter":{"title":".NET Core Web API'da PUT ve DELETE için CORS Hatası","author":"sametsunman","subtitle":"Üzerinde çalıştığımız bir projede yerel makinede sorun yokken iis üzerinde GET,POST gibi isteklerde sorun olmazken önyüzde(React, Axios) PUT ve DELETE için cors hatası alıyorduk. ","date":"2020-11-26","thumb_img_alt":"web-dav","content_img_alt":"web-dav","excerpt":"Üzerinde çalıştığımız bir projede yerel makinede sorun yokken iis üzerinde GET,POST gibi isteklerde sorun olmazken önyüzde(React, Axios) PUT ve DELETE için cors hatası alıyorduk. ","canonical_url":"","template":"post","thumb_img_path":"images/webDav.png","content_img_path":"images/webDav.png"},"html":"<p>İnternetten araşttırdığımda ise aşağıdaki yöntemi buldum.</p>\n<p>Sorunumuz .Net Core'un Web API tarafında varsayılan olarak yalnızca GET, POST, OPTIONS ve HEAD isteklerine izin vermesinden kaynaklı. PUT ve DELETE’e izin vermek için, IIS'te Web.Config dosyasından aşağıdaki gibi WebDAV işleyicisini ve modülünü istek kanalından kaldırmanız gerekiyor. Böylece servislerimiz sorunsuzca çalışıyor</p>\n<pre><code>&#x3C;system.webServer>\n  .\n  .\n  \n  &#x3C;handlers>\n      &#x3C;remove name=\"WebDAV\" />\n    &#x3C;/handlers>\n    \n    &#x3C;modules runAllManagedModulesForAllRequests=\"true\">\n      &#x3C;remove name=\"WebDAVModule\"/>\n    &#x3C;/modules>\n    \n  .\n  .\n&#x3C;/system.webServer>\n</code></pre>\n<p><em>Kaynak: <a href=\"https://stackoverflow.com/questions/40776787/how-to-get-cors-to-work-with-asp-net-core-web-api-server-angular-2-client\">https://stackoverflow.com/questions/40776787/how-to-get-cors-to-work-with-asp-net-core-web-api-server-angular-2-client</a></em></p>"},{"url":"/posts/net-core-3te-coravel-kullanarak-arkaplanda-calisan-job-olusturma/","relativePath":"posts/net-core-3te-coravel-kullanarak-arkaplanda-calisan-job-olusturma.md","relativeDir":"posts","base":"net-core-3te-coravel-kullanarak-arkaplanda-calisan-job-olusturma.md","name":"net-core-3te-coravel-kullanarak-arkaplanda-calisan-job-olusturma","frontmatter":{"title":".NET Core 3'te Coravel kullanarak arkaplanda çalışan job oluşturma","author":"sametsunman","subtitle":"Net Core'u bilmeyen yoktur, günümüzde  yaygın kullanılan bir framework. Platformlar arası, mimariler arasında tutarlı, komut satırı araçları, esnek dağıtım, uyumlu, açık kaynak gibi özelliklere sahip olması ve Microsoft tarafından desteklenmesi ön plana çıkıyor.","date":"2020-03-09","thumb_img_alt":"coravel","content_img_alt":"","excerpt":"Net Core'u bilmeyen yoktur, günümüzde  yaygın kullanılan bir framework. Platformlar arası, mimariler arasında tutarlı, komut satırı araçları, esnek dağıtım, uyumlu, açık kaynak gibi özelliklere sahip olması ve Microsoft tarafından desteklenmesi ön plana çıkıyor.","canonical_url":"","template":"post","content_img_path":"images/coravel.png"},"html":"<p>Worker servisleri, .NET Core 3 tarafından sunulan yeni bir şablon. Şimdi, .NET Core 3 Worker hizmetini ve Coravel'i birleştirerek bir zamanlayıcı job'ını nasıl uygulanacağını görelim .</p>\n<p><strong>Worker Servisi nedir?</strong>\nWorker Servisi, e-posta gönderme, sms gönderme, olay yayını, belirli bir zamanda bazı verileri tetikleme, maaş hesaplaması vb. gibi fonksiyonları arkaplanda gerçekleşterebilir.</p>\n<p>Bir örnekle anlayalım:</p>\n<p><strong>Önkoşul</strong>\n.NET Core 3 SDK'yı resmi Microsoft sitesinden <a href=\"https://dotnet.microsoft.com/download/dotnet-core/3.0\">indirin</a>.</p>\n<p><strong>Yeni bir klasör oluşturma</strong>\nBu klasörde aşağıdaki komutu çalıştırın. Bu worker servisinin bir şablonu kullanarak örnek bir konsol uygulaması oluşturur.</p>\n<pre><code>dotnet new worker  \n</code></pre>\n<p><img src=\"/images/netcore-worker.png\" alt=\"images/netcore-worker.png\"></p>\n<p>Projeyi Visual Studio'da açalım. Progam.cs dosyası aşağıdaki gibi görünecek.</p>\n<pre><code>using System;  \nusing System.Collections.Generic;  \nusing System.Linq;  \nusing System.Threading.Tasks;  \nusing Microsoft.Extensions.DependencyInjection;  \nusing Microsoft.Extensions.Hosting;  \n  \nnamespace CoreWorkerServiceSchedularJob  \n{  \n    public class Program  \n    {  \n        public static void Main(string[] args)  \n        {  \n            CreateHostBuilder(args).Build().Run();  \n        }  \n  \n        public static IHostBuilder CreateHostBuilder(string[] args) =>  \n            Host.CreateDefaultBuilder(args)  \n                .ConfigureServices((hostContext, services) =>  \n                {  \n                    services.AddHostedService&#x3C;Worker>();  \n                });  \n    }  \n}  \n</code></pre>\n<p><strong>Coravel'i yapılandırılması</strong></p>\n<p>NuGet Package konsolunda aşağıdaki komutu çalıştırın.</p>\n<pre><code>dotnet add package coravel  \n</code></pre>\n<p><strong>Invocable uygulama</strong></p>\n<p>\"Job çalıştırıldı....... !!!\" gibi bir metni yazdığımız sınıfımıza (CoreWorkerServiceSchedularJob.cs) ekleyelim.</p>\n<pre><code>using Coravel.Invocable;  \nusing System;  \nusing System.Collections.Generic;  \nusing System.Text;  \nusing System.Threading.Tasks;  \n  \nnamespace CoreWorkerServiceSchedularJob  \n{  \n    class MyFirstJob  : IInvocable  \n    {  \n        public Task Invoke()  \n        {  \n            Console.WriteLine(\"Job çalıştırıldı.......!!!\" + DateTime.Now.ToString());  \n            return Task.CompletedTask;  \n        }  \n    }  \n}  \n</code></pre>\n<p><strong>Job'ı kaydetme ve zamanı belirtme</strong></p>\n<p>Şimdi işimizi .NET Core'un service container'ına kaydedelim ve beş saniye için zamanı belirleyelim. İsterseniz başka bir sıklık belirtebilir yada spesifik bir zaman belirleyebilirsiniz. Program.cs dosyasının son kodu aşağıdaki gibidir.</p>\n<pre><code>using System;  \nusing System.Collections.Generic;  \nusing System.Linq;  \nusing System.Threading.Tasks;  \nusing Coravel;  \nusing Microsoft.Extensions.DependencyInjection;  \nusing Microsoft.Extensions.Hosting;  \n  \nnamespace CoreWorkerServiceSchedularJob  \n{  \n    public class Program  \n    {  \n        public static void Main(string[] args)  \n        {  \n            IHost host = CreateHostBuilder(args).Build();  \n            host.Services.UseScheduler(scheduler => {  \n                \n                // Remind schedular to repeat the same job in every five-second   \n                scheduler  \n                    .Schedule&#x3C;MyFirstJob>()  \n                    .EveryFiveSeconds();  \n  \n  \n            });  \n            host.Run();  \n        }  \n  \n        public static IHostBuilder CreateHostBuilder(string[] args) =>  \n            Host.CreateDefaultBuilder(args)  \n                .ConfigureServices(services =>  \n                {  \n                    services.AddScheduler();  \n  \n                    // register job with container  \n                    services.AddTransient&#x3C;MyFirstJob>();  \n                });  \n    };  \n}  \n</code></pre>\n<p><strong>Uygulamayı çalıştırma zamanı</strong></p>\n<p>Uygulamanın çıktısına bakalım.</p>\n<p><img src=\"/images/coravel.png\" alt=\"images/coravel.png\"></p>\n<p>.NET Core 3 ve Worker hizmeti şablonu ve Coravel paketinin bir kombinasyonuyla sadece 5 dakikalık sürede bir zamanlayıcı görevi oluşturmuş olduk.</p>\n<p>Kolay gelsin!</p>"},{"url":"/posts/netcore-projesi-nginx-sunucu-uzerinde-nasil-yayinlanir/","relativePath":"posts/netcore-projesi-nginx-sunucu-uzerinde-nasil-yayinlanir.md","relativeDir":"posts","base":"netcore-projesi-nginx-sunucu-uzerinde-nasil-yayinlanir.md","name":"netcore-projesi-nginx-sunucu-uzerinde-nasil-yayinlanir","frontmatter":{"title":".NET Core Projesi Ubuntu Nginx Sunucu Üzerinde Nasıl Yayınlanır?","author":"sametsunman","featured":true,"subtitle":"Merhaba arkadaşlar. Bu yazımda başlıktan da anlaşıldığı gibi Asp.Net ile kodladığımız bir projeyi web ortamında yayınlayıp kullanılabilir hale getirme konusuna değineceğim. Bildiğiniz gibi web uygulamalarını tamamladığımız  zaman internet ortamına o haliyle yükleyemeyiz. Web ortamında çalışabilecek hale getirmek için projelerimizi publish etmemiz gerekir. Hadi nasıl yapıldığına bakalım.","date":"2019-09-23","thumb_img_alt":"netcore-linux-nginx","content_img_alt":"netcore-linux-nginx","excerpt":"Merhaba arkadaşlar. Bu yazımda başlıktan da anlaşıldığı gibi Asp.Net ile kodladığımız bir projeyi web ortamında yayınlayıp kullanılabilir hale getirme konusuna değineceğim. Bildiğiniz gibi web uygulamalarını tamamladığımız  zaman internet ortamına o haliyle yükleyemeyiz. Web ortamında çalışabilecek hale getirmek için projelerimizi publish etmemiz gerekir. Hadi nasıl yapıldığına bakalım.","canonical_url":"denmeee","template":"post","thumb_img_path":"images/cover.svg","content_img_path":"images/cover.svg"},"html":"<p>İlk önce terminal üzerinden .NET Core sdk'sını ve runtime'ını kuralım:</p>\n<pre><code>wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb\nsudo dpkg -i packages-microsoft-prod.deb\nsudo add-apt-repository universe\nsudo apt-get install apt-transport-https\nsudo apt-get update\nsudo apt-get install dotnet-sdk-2.2\nsudo apt-get install aspnetcore-runtime-2.2\n</code></pre>\n<p>Şimdi ise projemizi yayınlayalım:</p>\n<pre><code>dotnet publish --configuration Release\n</code></pre>\n<p>Projemizin dosyaları şu dizinde bulunacak, \"bin/Release/&#x3C;framework_adi>/Publish\"</p>\n<p>Uygulamayı test edelim:</p>\n<p>Komut satırından uygulamayı çalıştırın: dotnet &#x3C;uygulama_adi>.dll.\nBir tarayıcıda, uygulamanın Linux üzerinde varsayılan olarak <a href=\"http://localhost:5000\">http://localhost:5000</a> adresinde çalışıyor olmalı.</p>\n<p>Nginx'i kuralım:</p>\n<pre><code>sudo apt-get install nginx\nsudo service nginx start\nsudo service nginx status\n</code></pre>\n<p>Ve config dosyalarını düzeltelim:</p>\n<pre><code>sudo nano /etc/nginx/sites-available/default\n</code></pre>\n<p>aşağıdaki şekilde düzeltelim:</p>\n<pre><code>server \n{\n   listen 81; \n   location / \n   {      \n      proxy_pass http://localhost:5000;\n      proxy_http_version 1.1;\n      proxy_set_header Upgrade $http_upgrade;\n      proxy_set_header Connection keep-alive;\n      proxy_set_header Host $host;\n      proxy_cache_bypass $http_upgrade;\n   }\n}\n</code></pre>\n<p>Yaptığımız değişiklikleri kaydedelim:</p>\n<pre><code>sudo nginx -t\nsudo nginx -s reload\n</code></pre>\n<p>Nginx'in yazılacak WebAPI servisi özelinde ilgili Kestrel Process'ini ayağa kaldıracağını bilmesi gerekiyor. IIS'in Worker Process çalışma modeline benzer bir yaklaşım olarak düşünelim. Bunun için service uzantılı bir dosya yazmak lazım.</p>\n<pre><code>sudo gedit /etc/systemd/system/kestrel-&#x3C;proje-adi>.service\n</code></pre>\n<p>Şu şekilde dosyayı düzenleyelim:</p>\n<pre><code>[Unit]\nDescription=BaseWebAPI(Standard Asp.Net Web API 2.0 project) on NGinx\n \n[Service]\nWorkingDirectory=/var/www/&#x3C;Proje-Klasörü>\nExecStart=/usr/bin/dotnet/ /var/www/&#x3C;Proje-Klasörü>/&#x3C;Proje-Adi>.dll\nRestart=always\nRestartSec=30\nSyslogIdentifier=dotnet-&#x3C;Proje-Adi>\nUser=www-data\nEnvironment=ASPNETCORE_ENVIRONMENT=Production\nEnvironment=DOTNET_PRINT_TELEMETRY_MESSAGE=false\n \n[Install]\nWantedBy=multi-user.target\n</code></pre>\n<p>Ve son olarak servislerimizi çalıştıralım:</p>\n<pre><code>sudo systemctl enable kestrel-baseapi.service\nsudo systemctl start kestrel-baseapi.service\n</code></pre>\n<p>Bu da nginx'i yeniden çalıştırıyor:</p>\n<pre><code>sudo service nginx restart\n</code></pre>\n<p>İşte bu kadar, sitemiz yayında :)</p>"},{"url":"/posts/nextjs-modern-web-gelistirme/","relativePath":"posts/nextjs-modern-web-gelistirme.md","relativeDir":"posts","base":"nextjs-modern-web-gelistirme.md","name":"nextjs-modern-web-gelistirme","frontmatter":{"title":"Next.js: Modern Web Geliştirmenin Olmazsa Olmazı","author":"sametsunman","subtitle":"React biliyorsun ama production'a çıkınca SEO, performans, routing derken kafan karışıyor mu? Next.js tam da bu sorunları çözmek için var. Gelin Next.js 15 ile neler değişti, neler yapabiliyoruz birlikte bakalım.","date":"2025-12-01","thumb_img_alt":"nextjs","content_img_alt":"nextjs","excerpt":"React biliyorsun ama production'a çıkınca SEO, performans, routing derken kafan karışıyor mu? Next.js tam da bu sorunları çözmek için var. Gelin Next.js 15 ile neler değişti, neler yapabiliyoruz birlikte bakalım.","canonical_url":"","template":"post","thumb_img_path":"images/next_js.jpg","content_img_path":"images/next_js.jpg"},"html":"<p>React harika bir kütüphane. Component mantığı, state yönetimi, hooks... Ama bir noktada fark ediyorsun ki sadece React yetmiyor. SEO için server-side rendering lazım, routing için kütüphane lazım, API yazmak için backend lazım, build optimizasyonu lazım...</p>\n<p>İşte Next.js burada devreye giriyor. Vercel'in geliştirdiği bu framework, React'in üzerine production-ready özellikler ekliyor. Ve Next.js 15 ile işler daha da kolaylaştı.</p>\n<h2>Next.js Nedir?</h2>\n<p>Next.js, React tabanlı bir full-stack web framework'ü. Şunları kutudan çıkar çıkmaz veriyor:</p>\n<ul>\n<li>Server-Side Rendering (SSR)</li>\n<li>Static Site Generation (SSG)</li>\n<li>File-based Routing</li>\n<li>API Routes</li>\n<li>Image Optimization</li>\n<li>Font Optimization</li>\n<li>Built-in CSS/Sass desteği</li>\n<li>Ve çok daha fazlası...</li>\n</ul>\n<h2>Next.js 15 ile Gelen Yenilikler</h2>\n<h3>1. React 19 Desteği</h3>\n<p>Next.js 15, React 19 ile tam uyumlu. Bu demek oluyor ki:</p>\n<ul>\n<li><strong>React Compiler</strong>: Artık <code>useMemo</code> ve <code>useCallback</code> ile uğraşmana gerek yok. Compiler otomatik optimize ediyor.</li>\n<li><strong>Server Components</strong>: Varsayılan olarak component'ler server'da render ediliyor.</li>\n<li><strong>Actions</strong>: Form işlemleri çok daha kolay.</li>\n</ul>\n<h3>2. Turbopack Artık Stable</h3>\n<p>Development server'ı artık Turbopack ile çalışıyor. Ne demek bu?</p>\n<pre><code class=\"language-bash\">next dev --turbo\n</code></pre>\n<ul>\n<li><strong>%76 daha hızlı</strong> local server başlatma</li>\n<li><strong>%96 daha hızlı</strong> kod güncellemeleri (Fast Refresh)</li>\n<li>Büyük projelerde bile anında güncelleme</li>\n</ul>\n<p>Webpack'e elveda!</p>\n<h3>3. Async Request API'leri</h3>\n<p><code>headers</code>, <code>cookies</code>, <code>params</code> ve <code>searchParams</code> artık asenkron:</p>\n<pre><code class=\"language-javascript\">// Eskiden\nexport default function Page({ params }) {\n  const { id } = params;\n}\n\n// Next.js 15'te\nexport default async function Page({ params }) {\n  const { id } = await params;\n}\n</code></pre>\n<p>Neden mi? Daha iyi performans ve streaming desteği için.</p>\n<h3>4. Caching Değişiklikleri</h3>\n<p>Next.js 15'te caching varsayılan olarak kapalı. Bu önemli bir değişiklik:</p>\n<pre><code class=\"language-javascript\">// Artık her seferinde fresh data çeker\nconst res = await fetch('https://api.example.com/data');\n\n// Cache istiyorsan belirt\nconst res = await fetch('https://api.example.com/data', {\n  cache: 'force-cache'\n});\n</code></pre>\n<p><code>GET</code> route handler'ları da artık varsayılan olarak cache'lenmiyor.</p>\n<h3>5. Partial Prerendering (PPR)</h3>\n<p>Sayfanın statik ve dinamik kısımlarını ayırabiliyorsun:</p>\n<pre><code class=\"language-javascript\">// layout.js\nexport const experimental_ppr = true;\n</code></pre>\n<p>Statik kısımlar anında yüklenir, dinamik kısımlar streaming ile gelir. En iyi iki dünyanın birleşimi!</p>\n<h2>App Router vs Pages Router</h2>\n<p>Next.js'te iki routing sistemi var. Yeni projelerde <strong>App Router</strong> kullan.</p>\n<h3>App Router (Önerilen)</h3>\n<pre><code>app/\n├── page.js           → /\n├── about/\n│   └── page.js       → /about\n├── blog/\n│   ├── page.js       → /blog\n│   └── [slug]/\n│       └── page.js   → /blog/:slug\n└── layout.js         → Tüm sayfalara uygulanır\n</code></pre>\n<h3>Temel Dosyalar</h3>\n<ul>\n<li><code>page.js</code> - Sayfa component'i</li>\n<li><code>layout.js</code> - Paylaşılan layout</li>\n<li><code>loading.js</code> - Loading UI (otomatik Suspense)</li>\n<li><code>error.js</code> - Error boundary</li>\n<li><code>not-found.js</code> - 404 sayfası</li>\n</ul>\n<h2>Server Components vs Client Components</h2>\n<p>Next.js 15'te varsayılan olarak tüm component'ler <strong>Server Component</strong>.</p>\n<h3>Server Component</h3>\n<pre><code class=\"language-javascript\">// Bu server'da çalışır (varsayılan)\nasync function KullaniciListesi() {\n  const kullanicilar = await db.kullanici.findMany();\n\n  return (\n    &#x3C;ul>\n      {kullanicilar.map(k => &#x3C;li key={k.id}>{k.isim}&#x3C;/li>)}\n    &#x3C;/ul>\n  );\n}\n</code></pre>\n<p>Avantajları:</p>\n<ul>\n<li>Direkt veritabanına erişebilirsin</li>\n<li>API key'leri güvenle kullanabilirsin</li>\n<li>Bundle size küçülür (bu kod client'a gitmez)</li>\n</ul>\n<h3>Client Component</h3>\n<pre><code class=\"language-javascript\">'use client'; // Bu satır şart!\n\nimport { useState } from 'react';\n\nfunction Sayac() {\n  const [sayi, setSayi] = useState(0);\n\n  return (\n    &#x3C;button onClick={() => setSayi(sayi + 1)}>\n      Tıklama: {sayi}\n    &#x3C;/button>\n  );\n}\n</code></pre>\n<p>Ne zaman Client Component kullanmalı?</p>\n<ul>\n<li><code>useState</code>, <code>useEffect</code> gibi hook'lar</li>\n<li>Event listener'lar (<code>onClick</code>, <code>onChange</code>...)</li>\n<li>Browser API'leri (<code>window</code>, <code>localStorage</code>...)</li>\n<li>Class component'ler</li>\n</ul>\n<h2>Data Fetching</h2>\n<h3>Server Component'lerde</h3>\n<pre><code class=\"language-javascript\">async function Blog() {\n  // Direkt async/await kullan\n  const posts = await fetch('https://api.example.com/posts')\n    .then(res => res.json());\n\n  return (\n    &#x3C;ul>\n      {posts.map(post => &#x3C;li key={post.id}>{post.title}&#x3C;/li>)}\n    &#x3C;/ul>\n  );\n}\n</code></pre>\n<h3>Cache Kontrolü</h3>\n<pre><code class=\"language-javascript\">// Her istekte fresh data\nfetch(url, { cache: 'no-store' });\n\n// Cache'le (varsayılan değil artık!)\nfetch(url, { cache: 'force-cache' });\n\n// Belirli süre cache'le\nfetch(url, { next: { revalidate: 3600 } }); // 1 saat\n</code></pre>\n<h3>Revalidation</h3>\n<pre><code class=\"language-javascript\">// Sayfa seviyesinde\nexport const revalidate = 60; // 60 saniyede bir yenile\n\n// On-demand revalidation\nimport { revalidatePath, revalidateTag } from 'next/cache';\n\nrevalidatePath('/blog');\nrevalidateTag('posts');\n</code></pre>\n<h2>Server Actions</h2>\n<p>Form işlemleri artık çok kolay. API route yazmana gerek yok!</p>\n<pre><code class=\"language-javascript\">// actions.js\n'use server';\n\nexport async function kullaniciEkle(formData) {\n  const isim = formData.get('isim');\n  const email = formData.get('email');\n\n  await db.kullanici.create({\n    data: { isim, email }\n  });\n\n  revalidatePath('/kullanicilar');\n}\n</code></pre>\n<pre><code class=\"language-javascript\">// page.js\nimport { kullaniciEkle } from './actions';\n\nexport default function KullaniciFormu() {\n  return (\n    &#x3C;form action={kullaniciEkle}>\n      &#x3C;input name=\"isim\" placeholder=\"İsim\" />\n      &#x3C;input name=\"email\" placeholder=\"E-posta\" />\n      &#x3C;button type=\"submit\">Ekle&#x3C;/button>\n    &#x3C;/form>\n  );\n}\n</code></pre>\n<p>JavaScript disable olsa bile çalışır!</p>\n<h3>useFormStatus ile Loading</h3>\n<pre><code class=\"language-javascript\">'use client';\nimport { useFormStatus } from 'react-dom';\n\nfunction GonderButonu() {\n  const { pending } = useFormStatus();\n\n  return (\n    &#x3C;button disabled={pending}>\n      {pending ? 'Gönderiliyor...' : 'Gönder'}\n    &#x3C;/button>\n  );\n}\n</code></pre>\n<h3>useActionState ile Form State</h3>\n<pre><code class=\"language-javascript\">'use client';\nimport { useActionState } from 'react';\nimport { girisYap } from './actions';\n\nfunction GirisFormu() {\n  const [state, action, pending] = useActionState(girisYap, null);\n\n  return (\n    &#x3C;form action={action}>\n      &#x3C;input name=\"email\" />\n      &#x3C;input name=\"sifre\" type=\"password\" />\n      {state?.hata &#x26;&#x26; &#x3C;p className=\"error\">{state.hata}&#x3C;/p>}\n      &#x3C;button disabled={pending}>Giriş Yap&#x3C;/button>\n    &#x3C;/form>\n  );\n}\n</code></pre>\n<h2>Metadata ve SEO</h2>\n<pre><code class=\"language-javascript\">// Statik metadata\nexport const metadata = {\n  title: 'Sayfa Başlığı',\n  description: 'Sayfa açıklaması',\n  openGraph: {\n    title: 'OG Başlık',\n    description: 'OG Açıklama',\n    images: ['/og-image.jpg'],\n  },\n};\n\n// Dinamik metadata\nexport async function generateMetadata({ params }) {\n  const post = await getPost(params.slug);\n\n  return {\n    title: post.title,\n    description: post.excerpt,\n  };\n}\n</code></pre>\n<h2>Image Optimization</h2>\n<pre><code class=\"language-javascript\">import Image from 'next/image';\n\nfunction Profil() {\n  return (\n    &#x3C;Image\n      src=\"/profil.jpg\"\n      alt=\"Profil fotoğrafı\"\n      width={300}\n      height={300}\n      priority // LCP için önemli görsellerde\n      placeholder=\"blur\" // Lazy loading sırasında blur efekti\n    />\n  );\n}\n</code></pre>\n<p>Next.js otomatik olarak:</p>\n<ul>\n<li>WebP/AVIF'e dönüştürür</li>\n<li>Responsive srcset oluşturur</li>\n<li>Lazy loading uygular</li>\n<li>Layout shift'i önler</li>\n</ul>\n<h2>Route Handlers (API Routes)</h2>\n<pre><code class=\"language-javascript\">// app/api/kullanicilar/route.js\nimport { NextResponse } from 'next/server';\n\nexport async function GET() {\n  const kullanicilar = await db.kullanici.findMany();\n  return NextResponse.json(kullanicilar);\n}\n\nexport async function POST(request) {\n  const body = await request.json();\n  const yeniKullanici = await db.kullanici.create({ data: body });\n  return NextResponse.json(yeniKullanici, { status: 201 });\n}\n</code></pre>\n<h3>Dinamik Route Handler</h3>\n<pre><code class=\"language-javascript\">// app/api/kullanicilar/[id]/route.js\nexport async function GET(request, { params }) {\n  const { id } = await params;\n  const kullanici = await db.kullanici.findUnique({ where: { id } });\n\n  if (!kullanici) {\n    return NextResponse.json({ error: 'Bulunamadı' }, { status: 404 });\n  }\n\n  return NextResponse.json(kullanici);\n}\n</code></pre>\n<h2>Middleware</h2>\n<p>Her request'te çalışan kod:</p>\n<pre><code class=\"language-javascript\">// middleware.js (root'ta)\nimport { NextResponse } from 'next/server';\n\nexport function middleware(request) {\n  // Auth kontrolü\n  const token = request.cookies.get('token');\n\n  if (!token &#x26;&#x26; request.nextUrl.pathname.startsWith('/dashboard')) {\n    return NextResponse.redirect(new URL('/giris', request.url));\n  }\n\n  return NextResponse.next();\n}\n\nexport const config = {\n  matcher: ['/dashboard/:path*', '/profil/:path*']\n};\n</code></pre>\n<h2>Proje Yapısı Önerisi</h2>\n<pre><code>app/\n├── (auth)/\n│   ├── giris/\n│   │   └── page.js\n│   └── kayit/\n│       └── page.js\n├── (main)/\n│   ├── layout.js\n│   ├── page.js\n│   └── blog/\n│       └── page.js\n├── api/\n│   └── kullanicilar/\n│       └── route.js\n├── layout.js\n└── globals.css\n\ncomponents/\n├── ui/\n│   ├── Button.js\n│   └── Input.js\n└── Header.js\n\nlib/\n├── db.js\n└── utils.js\n\nactions/\n└── kullanici.js\n</code></pre>\n<p>Parantez içindeki klasörler (<code>(auth)</code>, <code>(main)</code>) route group. URL'de görünmez, sadece organizasyon için.</p>\n<h2>Deployment</h2>\n<p>Vercel'e deploy etmek çok kolay:</p>\n<pre><code class=\"language-bash\">npm i -g vercel\nvercel\n</code></pre>\n<p>Ya da GitHub'a push et, Vercel otomatik deploy eder.</p>\n<p>Self-host için:</p>\n<pre><code class=\"language-bash\">npm run build\nnpm start\n</code></pre>\n<p>Docker ile:</p>\n<pre><code class=\"language-dockerfile\">FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci\nCOPY . .\nRUN npm run build\nEXPOSE 3000\nCMD [\"npm\", \"start\"]\n</code></pre>\n<h2>Performans İpuçları</h2>\n<ol>\n<li><strong>Server Component'leri tercih et</strong> - Client bundle küçülür</li>\n<li><strong>Dynamic imports kullan</strong> - Lazy loading</li>\n</ol>\n<pre><code class=\"language-javascript\">import dynamic from 'next/dynamic';\n\nconst HeavyComponent = dynamic(() => import('./HeavyComponent'), {\n  loading: () => &#x3C;p>Yükleniyor...&#x3C;/p>\n});\n</code></pre>\n<ol start=\"3\">\n<li><strong>Image component'i kullan</strong> - Otomatik optimizasyon</li>\n<li><strong>Font optimization</strong> - <code>next/font</code> ile</li>\n</ol>\n<pre><code class=\"language-javascript\">import { Inter } from 'next/font/google';\n\nconst inter = Inter({ subsets: ['latin'] });\n\nexport default function Layout({ children }) {\n  return (\n    &#x3C;html className={inter.className}>\n      &#x3C;body>{children}&#x3C;/body>\n    &#x3C;/html>\n  );\n}\n</code></pre>\n<ol start=\"5\">\n<li><strong>Bundle Analyzer</strong> - Neyin şişirdiğini gör</li>\n</ol>\n<pre><code class=\"language-bash\">npm i @next/bundle-analyzer\n</code></pre>\n<h2>Son Söz</h2>\n<p>Next.js, React ekosisteminin en güçlü framework'ü. Vercel'in arkasında olması, sürekli gelişim ve mükemmel dokümantasyon ile production-ready uygulamalar yapmak hiç bu kadar kolay olmamıştı.</p>\n<p>Next.js 15 ile gelen React 19 desteği, Turbopack, ve geliştirilmiş caching mekanizmaları framework'ü daha da güçlü kıldı.</p>\n<p>Yeni bir proje başlıyorsan, Next.js'i kesinlikle değerlendir. Öğrenme eğrisi React biliyorsan çok düşük, kazanımlar ise çok yüksek.</p>\n<hr>\n<p><em>Next.js hakkında sorularınız varsa yorumlarda paylaşın. Birlikte öğrenelim!</em></p>"},{"url":"/posts/otomatik-klavye-ve-mouse-kontrolu/","relativePath":"posts/otomatik-klavye-ve-mouse-kontrolu.md","relativeDir":"posts","base":"otomatik-klavye-ve-mouse-kontrolu.md","name":"otomatik-klavye-ve-mouse-kontrolu","frontmatter":{"title":"Bilgisayarınızı uyanık tutun. Mouse otomatik olarak nasıl hareket ettirilir? Klavye tuşuna nasıl otomatik bastırılır?","subtitle":"Bazı durumlarda bilgisayarımız uyku moduna geçmemesi için klavyeden tuşa basmalı ya da mouse'u hareket ettirmeliyiz. Uykuya geçme süresini bilgisayar ayarlarından değiştirebiliriz. Peki ya değiştiremediğimiz durumlarda ne yapabiliriz? ","date":"2022-11-11T00:00:00.000Z","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"sametsunman","template":"post","thumb_img_path":"images/mouse-and-keyboard.jpg","content_img_path":"images/mouse-and-keyboard.jpg"},"html":"<p><strong>1. Yazılım yolu ile fare ve klavye hareketlerini kaydetme</strong></p>\n<p>En basit ve en güzel yöntemlerden biri budur. Bilgisayarınıza kurduğunuz programlarla, mouse'unuzu ya da klavye'nizi programlayabilirsiniz.\n\nÖrnek olarak;</p>\n<ul>\n<li><a href=\"https://www.gezginler.net/indir/automouser.html\">AutoMouser</a></li>\n</ul>\n<p><img src=\"https://www.gezginler.net/indir/resim-grafik/t_automouser-1405699871.jpg\"></p>\n<p>Klavye ve Fare Otomatik Tıklama Programı ile ister farenizin isterse klavyenizin belirlediğiniz tuşları veya hareketleri otomatik olarak istediğiniz zamanda ve istediğiniz tekrarda yapmasını sağlayabilirsiniz.\n\n</p>\n<ul>\n<li><a href=\"https://www.gezginler.net/indir/ghost-mouse.html\">Ghost Mouse</a></li>\n</ul>\n<p><img src=\"https://www.gezginler.net/indir/resim-grafik/t_ghost-mouse-1400243050.jpg\"></p>\n<p>Küçük boyutu ve basit arayüzüyle kullanım kolaylığı sunan Ghost Mouse oyun ve çeşitli programlarda gerçekleştirmeniz gereken mouse hareketlerini otomatik hale getirerek zaman ve enerji tasarrufu sağlar.\n\n\n\n\n<strong>2. Script ile</strong></p>\n<p>Bilgisayarda basitçe oluşturacağımız kod satırlarıyla da otomatik olarak klavyedeki belirli süre içersinde otomatik olarak tuşlara bastırabiliriz.</p>\n<p><strong><em>1.Yol</em></strong></p>\n<p>Hemen bir not defteri açıp aşağıdaki kodları yazın:</p>\n<pre><code>`\nset wsc = CreateObject(\"WScript.Shell\")\nDo\n    WScript.Sleep(5*60*1000)\n    wsc.SendKeys(\"{F13}\")\nLoop\n`\n</code></pre>\n<p>Daha sonrasında ise bu belgeyi farklı kaydederek noSleep.vbs adıyla kaydedin. Kaydettiğiniz dosyayı açtığınızda 5 dakikada bir klavyemizde gizli olan F13 tuşuna basılacak. Böylece bilgisayarımız uyku moduna girmeyecektir. Dilerseniz F13 yerine NUMLOCK yada diğer tuş kombinasyonlarını yazabilirsiniz. Yine aynı şekilde sayılarla oynayarak süreyi düşürebilir ya da arttırabilirsiniz.</p>\n<p><strong><em>2.Yol</em></strong></p>\n<p>Bence en güzel ve en işe yarayan yöntem bu. Çünkü herhangi bir admin yetkisi istemiyor.</p>\n<p>Bir not defterinde aşağıdaki kod satırlarını yazın.</p>\n<pre><code>`\n $MYJOB = Start-Job -ScriptBlock {\n    $MOVEMENTSIZE = 10\n    $SLEEPTIME = 60\n\n    Add-Type -AssemblyName System.Windows.Forms\n        while ($true) { \n            $POSITION = [windows.Forms.Cursor]::Position\n            $POSITION.x += $MOVEMENTSIZE\n            $POSITION.y += $MOVEMENTSIZE\n            [windows.Forms.Cursor]::Position = $POSITION\n            Start-Sleep -Seconds $SLEEPTIME\n            $POSITION = [windows.Forms.Cursor]::Position\n            $POSITION.x -= $MOVEMENTSIZE\n            $POSITION.y -= $MOVEMENTSIZE\n            [Windows.Forms.Cursor]::Position = $POSITION\n            Start-Sleep -Seconds $SLEEPTIME\n            [windows.Forms.SendKeys]::Sendwait('[F13}')\n        }\n    }\n`\n</code></pre>\n<p><img src=\"https://asnus.com/images/noSleep2.png\">\n\nBu kodları noSleep.ps1 adıyla kaydedebilirsiniz. Sonrasında kaydedilen dosyaya sağ tıklayarak düzenleye basın. Dosya PowerShell ISE'de açılacaktır. Run tuşuna basarak komutlarımız çalışmaya başlayacaktır. Burada yapılan işlemler 60 snde bir mouse'u hareket ettirmek ve klavyede F13 tuşuna basmaktır. Dilerseniz süreyi ve tuşu ayarlayabilirsiniz.\n\n<strong>3. Video yardımıyla</strong></p>\n<p>Bir diğer yöntemiz ise video oynatmak. Evet, böyle bir yöntem mevcut. Yukarıdaki durumlar işe yaramadığında, örneğin bilgisayarınıza yazılım kurma izniniz yoksa bu yöntemi deneyebilirsiniz.\n\n<img src=\"https://i.ytimg.com/vi/v4bav9V9Bi8/maxresdefault.jpg\">\n\nKullanımı ise gayet basit. Aşağıdaki videoları tabletinizde ya da telefonunuzda açın. Daha sonrasında ise üzerine mouse'unuzu yerleştirin. İşte bu kadar!\n</p>\n<ul>\n<li><a href=\"https://www.youtube.com/watch?v=gVs0unbKAN4&#x26;t=12s\">Mouse Mover/Jiggler | Manipulation | Cheat | 2 Hours Video</a></li>\n<li><a href=\"https://www.youtube.com/watch?v=cYCmQBDvHlY\">Mouse jiggler 100 % working ( WOW ) simply superb</a></li>\n<li><a href=\"https://www.youtube.com/watch?v=S-bmhahLdEU\">Mouse Jiggler 2 Hours - Keep Computer Awake</a></li>\n</ul>\n<p>Tabi bu yöntem maalesef her mouse ile çalışmayabilir. Size tavsiyem kırmızı ışıklı mouse ile denemeniz.</p>\n<p><strong>4. Araç yardımıyla</strong></p>\n<p>Bu yöntem video yöntemine benziyor. Satın alacağınız bir alet ile mouse'unuzu hareket ettirebilirsiniz.</p>\n<p><a href=\"https://c1.neweggimages.com/ProductImageCompressAll1280/ASSAD2204050E15URF6.jpg\"></a></p>\n<p>Ülkemizde satışına rastlamadım. Ancak Aliexpress ya da Amazon üzerinden kolaylıkla sipariş edebilirsiniz.</p>\n<ul>\n<li><a href=\"https://tr.aliexpress.com/item/1005002536221819.html?gatewayAdapt=glo2tur\">Aliexpress Mouse Jiggler</a></li>\n<li><a href=\"https://www.amazon.com/WiebeTech-Programmable-Mouse-Jiggler-MJ-3/dp/B00MTZY7Y4\">Amazon WiebeTech Programmable Mouse Jiggler</a></li>\n<li><a href=\"https://www.amazon.com/CHOKMAX-Undetectable-Simulate-Automatic-Movement/dp/B09Z1Q66YB\">Amazon CHOKMAX Mouse Jiggler, Undetectable Mouse Mover</a></li>\n<li><a href=\"https://www.n11.com/urun/tech8-mouse-jiggler-tespit-edilemez-yazilimsiz-mouse-pad-sanat-19630385?magaza=bonusticaret\">N11 Tech8 Mouse Jiggler</a></li>\n</ul>\n<p>Hadi sağlıcakla!</p>"},{"url":"/posts/production-modda-react-sayfa-yenilerken-404-not-found-sorunu/","relativePath":"posts/production-modda-react-sayfa-yenilerken-404-not-found-sorunu.md","relativeDir":"posts","base":"production-modda-react-sayfa-yenilerken-404-not-found-sorunu.md","name":"production-modda-react-sayfa-yenilerken-404-not-found-sorunu","frontmatter":{"title":"Production Mod'da React Sayfa Yenilerken 404 Not Found Sorunu","author":"sametsunman","subtitle":"React uygulamanızı development mod'da çalıştırırken sorun yok ancak production mod'da yani server'a deploy ettiğinizde sayfayı yenilediğinizde yada yeni sekmede açtığınızda sayfa bulunamadı hatası alıyorsanız çözümü burada.","date":"2020-02-21","thumb_img_alt":"404-not-found","content_img_alt":"404-not-found","excerpt":"React uygulamanızı development mod'da çalıştırırken sorun yok ancak production mod'da yani server'a deploy ettiğinizde sayfayı yenilediğinizde yada yeni sekmede açtığınızda sayfa bulunamadı hatası alıyorsanız çözümü burada.","canonical_url":"","template":"post","content_img_path":"images/404-not-found.png","thumb_img_path":"images/royal-owl.png"},"html":"<p>Sunucunuzun config ayarlarını hangisini kullanıyorsanız aşağıdaki şekilde güncelleyin. Bu şekilde sayfalarınız doğru şekilde yönlendirilecek.</p>\n<p><strong>Express</strong></p>\n<pre><code>app.get('/*', function(req, res) {\n  res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {\n    if (err) {\n      res.status(500).send(err)\n    }\n  })\n})\n</code></pre>\n<p><strong>Appache (.htaccess)</strong></p>\n<pre><code>RewriteBase /\nRewriteRule ^index\\.html$ - [L]\n RewriteCond %{REQUEST_FILENAME} !-f\n RewriteCond %{REQUEST_FILENAME} !-d\nRewriteRule . /index.html [L]\n</code></pre>\n<p><strong>Nginx (.conf)</strong></p>\n<pre><code>location / {\n  if (!-e $request_filename){\n    rewrite ^(.*)$ /index.html break;\n  }\n}\n</code></pre>\n<p><strong>IIS (web.config)</strong></p>\n<pre><code>&#x3C;configuration>\n    &#x3C;system.webServer>\n&#x3C;rewrite>\n  &#x3C;rules>\n    &#x3C;rule name=\"Rule1\" stopProcessing=\"true\">\n      &#x3C;match url=\"^index\\.html$\" ignoreCase=\"false\" />\n      &#x3C;action type=\"None\" />\n    &#x3C;/rule>\n    &#x3C;rule name=\"Imported Rule 2\" stopProcessing=\"true\">\n      &#x3C;match url=\".\" ignoreCase=\"false\" />\n      &#x3C;conditions>\n        &#x3C;add input=\"{REQUEST_FILENAME}\" matchType=\"IsFile\" ignoreCase=\"false\" negate=\"true\" />\n        &#x3C;add input=\"{REQUEST_FILENAME}\" matchType=\"IsDirectory\" ignoreCase=\"false\" negate=\"true\" />\n      &#x3C;/conditions>\n      &#x3C;action type=\"Rewrite\" url=\"/index.html\" />\n    &#x3C;/rule>\n  &#x3C;/rules>\n&#x3C;/rewrite>\n    &#x3C;/system.webServer>\n&#x3C;/configuration>\n</code></pre>"},{"url":"/posts/petguru-hikayemiz/","relativePath":"posts/petguru-hikayemiz.md","relativeDir":"posts","base":"petguru-hikayemiz.md","name":"petguru-hikayemiz","frontmatter":{"title":"PetGuru: Bir Hayalin ve Mia'nın Kodlara Dönüşme Hikayesi","author":"sametsunman","subtitle":"Bu proje, sadece aylardır üzerinde çalıştığımız bir kod yığını değil; aynı zamanda hayatıma yön veren küçük dostum, kedim Mia'nın bana fısıldadığı bir hayalin ürünü. Uykusuz geceler geçirdiğimiz, bazen sinir olup bazen de \"vay be, bunu biz mi yaptık?\" dediğimiz projemiz PetGuru sonunda hazır!","date":"2025-12-16","thumb_img_alt":"petguru","content_img_alt":"petguru","excerpt":"Bu proje, sadece aylardır üzerinde çalıştığımız bir kod yığını değil; aynı zamanda hayatıma yön veren küçük dostum, kedim Mia'nın bana fısıldadığı bir hayalin ürünü. Uykusuz geceler geçirdiğimiz, bazen sinir olup bazen de \"vay be, bunu biz mi yaptık?\" dediğimiz projemiz PetGuru sonunda hazır!","canonical_url":"","template":"post","thumb_img_path":"images/petguru-thumbnail.png","content_img_path":"images/petguru-thumbnail.png"},"html":"<p>Merhaba sevgili hayvan dostları!</p>\n<p>Bugün sizlerle çok özel bir şey paylaşmak istiyorum. Bu proje, sadece aylardır üzerinde çalıştığımız bir kod yığını değil; aynı zamanda hayatıma yön veren küçük dostum, kedim Mia'nın bana fısıldadığı bir hayalin ürünü. Uykusuz geceler geçirdiğimiz, bazen sinir olup bazen de \"vay be, bunu biz mi yaptık?\" dediğimiz projemiz <strong>PetGuru</strong> sonunda hazır!</p>\n<h2>Her Şey Mia'nın Bakışları ve Bir Kayıp İlanıyla Başladı</h2>\n<p>Yıllarca kurumsal dünyanın karmaşasında, kodlar ve teslim tarihleri arasında koşturdum. İşimi seviyordum, evet. Ama akşam eve döndüğümde, Mia'nın o sessiz ama derin karşılamasıyla yüzleştiğimde, içimde hep aynı ses yankılanıyordu: \"Daha fazlasını yapabilirsin. İçinde kalp atışı olan bir şeye dokunabilirsin.\"</p>\n<p>PetGuru, işte bu sese kulak vermemle başladı. Ve geçen yıl mahallemizdeki bir kedi kaybolduğunda, bu kişisel vizyon bir eylem planına dönüştü. Sahipleri çaresizce her yere ilan astı, sosyal medyada paylaştı ama düzgün bir platform yoktu. İlanlar kaynıyor, bilgiler dağınık, iletişim zordu. O an dedik ki: \"Bu iş böyle olmaz. Evcil hayvan sahiplerinin tek bir yerden her şeyi yapabilecekleri bir platform lazım.\"</p>\n<p>Ve işte PetGuru böyle doğdu; Mia'dan gelen ilhamla, tüm can dostlarımızın hayatını kolaylaştırmak için.</p>\n<h2>Peki Ne Var Bu Uygulamada?</h2>\n<p>Dur dur, hepsini anlatayım çünkü gerçekten gurur duyuyoruz:</p>\n<h3>Kayıp Dostlarımız İçin</h3>\n<p>Evcil hayvanınız kaybolduğunda panik yaparsınız, biliyoruz. PetGuru'da saniyeler içinde <a href=\"https://www.petguru.com.tr/kayip-hayvanlar\">kayıp ilanı</a> oluşturabilir, harita üzerinde son görüldüğü yeri işaretleyebilir ve çevredeki hayvanseverlere anında ulaşabilirsiniz. Bulanlar da aynı şekilde <a href=\"https://www.petguru.com.tr/kayip-hayvanlar/bulundu-ekle\">\"buldum\" ilanı</a> açabiliyor.</p>\n<h3>Sahiplendirme - Bir Can Bir Yuva Bekliyor</h3>\n<p>Barınaklarda, sokaklarda yüzlerce can yuva bekliyor. PetGuru ile <a href=\"https://www.petguru.com.tr/hayvan-sahiplenme\">sahiplendirme ilanları</a> oluşturabilir, filtreleyebilir ve o tatlı gözlere bakıp \"tamam, sen benimsin\" diyebilirsiniz. Her sahiplendirme ilanının arkasında bir umut var.</p>\n<h3>Eşleştirme - Aşk Buldur!</h3>\n<p>Evet, Tinder ama evcil hayvanlar için! Kedinize ya da köpeğinize uygun eş mi arıyorsunuz? <a href=\"https://www.petguru.com.tr/hayvan-eslestirme\">Eşleştirme</a> sayfasında ırk, yaş, lokasyon filtreleriyle en uygun adayları bulun. Kim bilir, belki de en tatlı yavrular bu eşleşmelerden doğacak.</p>\n<h3>Sağlık Takibi - Çünkü Onlar Konuşamaz</h3>\n<p>Aşı tarihleri, veteriner ziyaretleri, ilaçlar, kilo takibi... Hepsini tek yerden yönetin. Hatırlatmalar sayesinde hiçbir aşıyı kaçırmayın. Sağlık geçmişi her zaman elinizin altında.</p>\n<h3>Forum &#x26; Blog - Bilgi Paylaştıkça Çoğalır</h3>\n<p>\"Kedim neden sürekli miyavlıyor?\", \"Köpeğim çimenleri yiyor normal mi?\"... Bu soruları hepimiz sorduk. <a href=\"https://www.petguru.com.tr/forum\">Forum</a>'da deneyimli hayvan sahipleriyle sohbet edin, <a href=\"https://www.petguru.com.tr/blog\">blog</a> yazılarından faydalı bilgiler edinin.</p>\n<h3>Pet Shop - İhtiyaçlar Bir Tık Uzağında</h3>\n<p>Mama, oyuncak, tasma, kum... Evcil dostlarınız için gereken her şey <a href=\"https://www.petguru.com.tr/magaza\">mağazamızda</a>. (Yakında!)</p>\n<h3>Mesajlaşma - Doğrudan İletişim</h3>\n<p>Sahiplendirme ya da eşleştirme ilanlarında birini beğendiniz mi? Doğrudan mesaj atın, tanışın, konuşun.</p>\n<h3>QR Kod Sistemi - Kaybolursa Bile Bulunsun</h3>\n<p>Her evcil hayvan için benzersiz QR kod! Tasmasına takın, birisi bulduğunda QR'ı okutup size doğrudan ulaşsın. Süper değil mi?</p>\n<h2>Teknoloji Aşkına!</h2>\n<p>Tamam, biraz teknik konuşalım çünkü arkada ciddi bir mühendislik var:</p>\n<p><strong>Web Tarafı:</strong></p>\n<ul>\n<li>Next.js 15 + React 19 (En son teknoloji, en hızlı render)</li>\n<li>Material-UI 7 (Göze hoş gelen, kullanımı kolay arayüz)</li>\n</ul>\n<p><strong>Mobil Tarafı:</strong></p>\n<ul>\n<li>React Native + Expo 54 (Tek kodla hem iOS hem Android)</li>\n<li>Expo Router (Dosya bazlı routing, çok temiz)</li>\n</ul>\n<p><strong>Backend:</strong></p>\n<ul>\n<li>Firebase (Authentication, Firestore, Storage, Cloud Functions)</li>\n<li>Gerçek zamanlı senkronizasyon</li>\n</ul>\n<p><strong>Ortak Silahlarımız:</strong></p>\n<ul>\n<li>TypeScript (Hata yapmak zor, kod yazmak kolay)</li>\n<li>Zustand (State management'ın en şık hali)</li>\n<li>TanStack Query (Veri çekme işlerinin ustası)</li>\n<li>React Hook Form + Yup (Formlar artık kabus değil)</li>\n</ul>\n<p><strong>3 Dil Desteği:</strong>\nTürkçe, İngilizce ve İspanyolca! Çünkü hayvan sevgisi evrensel.</p>\n<h2>Monorepo: Kod Düzeni Her Şeydir</h2>\n<p>Projemiz Yarn Workspaces ile monorepo yapısında:</p>\n<pre><code>petguru-app/\n├── apps/\n│   ├── expo/      → Mobil uygulama\n│   ├── next/      → Web uygulaması\n│   └── functions/ → Firebase Cloud Functions\n├── packages/\n│   ├── app/       → Paylaşılan mantık (hooks, store, i18n)\n│   ├── firebase/  → Firebase servisleri\n│   └── types/     → TypeScript tipleri\n</code></pre>\n<p>Web ve mobil aynı kodu paylaşıyor. Bir yerde değişiklik yapınca her yere yansıyor. DRY (Don't Repeat Yourself) prensibinin kitabını yazdık resmen.</p>\n<h2>Uykusuz Geceler, Kahve Deryaları (ve Mia)</h2>\n<p>Bu projeyi yaparken neler yaşamadık ki:</p>\n<ul>\n<li>\"Bu bug nereden geldi?\" diye saatlerce araştırmalar</li>\n<li>Ekran başında geçen o uzun gecelerde, beni ayakta tutan iki şey vardı: Biri, bu platformun hayvanseverlerin hayatına dokunacağının hayali; diğeri ise yanı başımdaki en büyük destekçim, kedim Mia'nın klavyemin üzerine yatarak verdiği (bazen zoraki de olsa) molalar.</li>\n<li>\"Expo neden build etmiyor?\" çığlıkları</li>\n<li>Firebase kurallarıyla olan aşk-nefret ilişkimiz</li>\n<li>\"Dark mode'u da ekleyelim\" dedikten sonraki 3 günlük macera</li>\n<li>TypeScript'in \"bu tip yanlış\" deyip haklı çıkması</li>\n</ul>\n<p>Ama her şeye değdi. Çünkü şimdi elimizde hayvanseverlerin hayatını kolaylaştıracak, içinde bir kalp atışı olan bir uygulama var.</p>\n<h2>Artık Hazırız!</h2>\n<p>PetGuru artık canlı ve sizi bekliyor:</p>\n<ul>\n<li>Web'den hemen kullanabilirsiniz</li>\n<li>Android ve iOS uygulamaları mağazalarda</li>\n</ul>\n<h2>Son Söz</h2>\n<p>Bu uygulama sadece bir kod yığını değil. Her satırında hayvan sevgisi, her özelliğinde \"keşke olsa\" düşüncesi var. Kayıp bir kediyi sahibine kavuşturmak, barınaktaki bir köpeğe yuva bulmak, hasta bir evcil hayvanın aşısını unutmamak... Bunların hepsi PetGuru ile artık çok daha kolay.</p>\n<p>PetGuru, Mia'ya ve tüm can dostlarına yazdığımız bir sevgi mektubudur. Evcil dostlarınız için en iyisini hak ediyor. Biz de onlar için en iyisini yapmaya çalıştık.</p>\n<p><strong>PetGuru - Patili dostlarınız için her şey tek yerde.</strong></p>\n<p>Sevgilerle,\nPetGuru Ekibi (ve Projenin Baş İlham Kaynağı Mia!)</p>\n<hr>\n<p><em>P.S: Bir bug bulursanız kızmayın, bize söyleyin düzeltelim. Bir öneriniz varsa mutlaka yazın. Bu uygulama sizin için, sizinle birlikte büyüyecek.</em></p>\n<p><a href=\"https://www.petguru.com.tr\">www.petguru.com.tr</a></p>"},{"url":"/posts/projede-git-kullanici-adi-ve-epostasi-nasil-degistirilir/","relativePath":"posts/projede-git-kullanici-adi-ve-epostasi-nasil-degistirilir.md","relativeDir":"posts","base":"projede-git-kullanici-adi-ve-epostasi-nasil-degistirilir.md","name":"projede-git-kullanici-adi-ve-epostasi-nasil-degistirilir","frontmatter":{"title":"Projede Git kullanıcı adı ve e-postası nasıl değiştirilir?","author":"sametsunman","subtitle":"Git'e projemizi atarken mevcut adımızı değiştirmek istersek config ayarlarını değiştirmemiz gerekiyor. ","date":"2020-10-19","thumb_img_alt":"github-config","content_img_alt":"github-config","excerpt":"Git'e projemizi atarken mevcut adımızı değiştirmek istersek config ayarlarını değiştirmemiz gerekiyor. ","canonical_url":"","template":"post","content_img_path":"images/github-config.png","thumb_img_path":"images/github-config.png"},"html":"<h2>Global olarak ayarları değiştirmek</h2>\n<ol>\n<li>Komut çalıştırın (ör: git bash)</li>\n<li>Kullanıcı adınızı ayarlayın:\n<code>git config --global user.name \"İSİM SOYİSİM\"</code></li>\n<li>E-Postanızı ayarlayın:\n<code>git config --global user.email \"ORNEK@asnus.com\"</code></li>\n<li>\n<p>Son olarak e-posta ve kullanıcı adınızı teyit edin</p>\n<pre><code># kullanıcı adı gösterme\ngit config user.name\n</code></pre>\n</li>\n</ol>\n<h1>e-posta gösterme</h1>\n<p>git config user.email</p>\n<pre><code>## Tek bir proje dizini için ayarları değiştirmek\n1. Komut çalıştırın (ör: git bash) ve ilgili klasörü gidin(ör: cd C:\\repos)\n2. Kullanıcı adınızı ayarlayın:\n`git config user.name  \"İSİM SOYİSİM\"`\n3. E-Postanızı ayarlayın:\n`git config user.email \"ORNEK@asnus.com\"`\n4. Son olarak e-posta ve kullanıcı adınızı teyit edin\n</code></pre>\n<h1>kullanıcı adı gösterme</h1>\n<p>git config user.name</p>\n<h1>e-posta gösterme</h1>\n<p>git config user.email</p>\n<pre><code></code></pre>"},{"url":"/posts/react-buton-ile-veri-kopyalama/","relativePath":"posts/react-buton-ile-veri-kopyalama.md","relativeDir":"posts","base":"react-buton-ile-veri-kopyalama.md","name":"react-buton-ile-veri-kopyalama","frontmatter":{"title":"React'te Component içindeki yazı nasıl panoya kopyalanır?","subtitle":"Bir buton yardımıyla, component içindeki metini ya da zengin veriyi pano'ya(clipboard'a) nasıl kopyalanacağını anlatacağım.","date":"2022-10-05","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"sametsunman","template":"post","thumb_img_path":"images/copyToClipBoard.jpg","content_img_path":"images/copyToClipBoard.jpg"},"html":"<p>React projemde aşağıdaki gibi farklı componentlerden oluşan bir yapım vardı. Buradaki tüm yazılanları müşteri bir buton yardımı ile kopyalamak istiyordu. </p>\n<p><img src=\"https://asnus.com/images/copyToClipBoard.png\" alt=\"useMemo Çıktısı\"></p>\n<p>Bunun için bir fonksiyon tanımlayıp buton ile çağırarak yazıların kopyalanmasını sağlayabildik. Fonksiyonumuz aşağıdaki gibi:</p>\n<pre><code>const childRef = useRef();\n\nconst copyToClipBoard = () => {\n\n  \n  const range = document.createRange();\n  range.selectNode(childRef.current);\n  window.getSelection().removeAllRanges();\n  window.getSelection().addRange(range);\n  document.execCommand('copy');\n  window.getSelection().removeAllRanges();\n  \n}\n</code></pre>\n<p>Yukarıdaki ref.current'i useRef ile kopyalamak istediğimiz component'e tanımladık.</p>\n<pre><code>return(\n&#x3C;div>\n  &#x3C;div ref={childRef}>\n    &#x3C;span style={{color:red}}>Kopyalanacak Veri&#x3C;/span>\n  &#x3C;/div>\n  &#x3C;button onClick={() => copyToClipBoard()}>Kopyala&#x3C;/button>\n&#x3C;/div>\n)\n</code></pre>\n<p>İşte bu kadar! Butona tıklayarak yazımızı stil ile beraber panoya kopyalayabilir istediğimiz yere yapıştırabiliriz.</p>"},{"url":"/posts/react-custom-hook/","relativePath":"posts/react-custom-hook.md","relativeDir":"posts","base":"react-custom-hook.md","name":"react-custom-hook","frontmatter":{"title":"React - Custom Hook Nedir ve Nasıl Kullanılır?","subtitle":"Hook, React'ın 18.6 versiyonu ile kodlarımıza dahil olan yapılardır. Class component yapısına gerek olmadan, function component içerisinde de state yapısını kullanabilmemize olanak tanır.","date":"2022-04-19","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/reactCustomHook.png","content_img_path":"images/reactCustomHook.png"},"html":"<p>Custom Hook ise tekrarlanan kodun önüne geçebilmemiz adına ortaya çıkan bir yapıdır. Custom Hook yapısı ile tekrar kullanılabilir fonksiyonlar oluştururuz. Böylelikle daha temiz bir kod yapısı ve basitlik elde ederiz.</p>\n<p>Örnek bir yapıyı birlikte deneyelim: </p>\n<p><em>İlgili kod yapısına doğrudan <a href=\"https://codesandbox.io/s/customhook-asnus-zwl5rt\">bu adresten</a> erişebilirsiniz.</em></p>\n<p>Öncelik olarak customHook.js dosyası oluşturarak buraya kullanacağımız Custom Hook yapısını tanımlayalım.</p>\n<pre><code class=\"language-javascript\">import { useState, useEffect } from \"react\";\n\nfunction useCustomHook(initializer, componentName) {\n  // \"set\" diyerek hook yapımızı oluşturuyoruz.\n  const [counter, setCounter] = useState(initializer);\n\n  // setCounter'i çağırarak \"counter\" sayımıza +1 vereceğimiz fonksiyonu oluşturuyoruz.\n  function resetCounter() {\n    setCounter(counter + 1);\n  }\n\n  useEffect(() => {\n    // useEffect kullanarak counter değiştiğinde console.log çıktısını sağlıyoruz.\n    console.log(componentName + \" butonuna \" + counter + \" kere tıklandı.\");\n  }, [counter, componentName]);\n   \n  // counter değiştiğinde resetCounter fonksiyonun çağrılmasını sağlıyoruz.\n  return resetCounter;\n}\n\nexport default useCustomHook;\n</code></pre>\n<p>Bu tanımları sağladığımızda Custom Hook yapımızı oluşturmuş oluyoruz. Bu Hook yapısını farklı componentlerde kullanalım. Bunun için FirstComponent.js adlı bir dosya oluşturuyoruz.</p>\n<pre><code class=\"language-javascript\">import React from \"react\";\n\n// Custom Hook yapısını çağrıyoruz\nimport useCustomHook from \"../useCustomHook\";\n\nfunction FirstComponent(props) {\n  // Custom Hook yapısına 0 ve \"FirstComponent\" değerlerini döndüyoruz.\n  const clickedButton = useCustomHook(0, \"FirstComponent\");\n\n  return (\n    &#x3C;div>\n      &#x3C;h2> Bu FirstComponent'dir.&#x3C;/h2>\n      &#x3C;button onClick={clickedButton}>Tıklayınız!&#x3C;/button>\n    &#x3C;/div>\n  );\n}\n\nexport default FirstComponent;\n</code></pre>\n<p>Farkı anlayabilmemiz için SecondComponent.js adlı bir dosya daha oluşturalım. Ve Custom Hook yapısına farklı değerleri döndürelim.</p>\n<pre><code class=\"language-javascript\">import React from \"react\";\n\nimport useCustomHook from \"../useCustomHook\";\n\nfunction SecondComponent(props) {\n  const clickedButton = useCustomHook(0, \"SecondComponent\");\n\n  return (\n    &#x3C;div>\n      &#x3C;h2> Bu SecondComponent'dir. &#x3C;/h2>\n      &#x3C;button onClick={clickedButton}>Tıklayınız!&#x3C;/button>\n    &#x3C;/div>\n  );\n}\n\nexport default SecondComponent;\n</code></pre>\n<p>Son işlem olarak bu iki yapımızı App.js de çağıralım. Ve çıktımızı kontrol edelim.</p>\n<pre><code class=\"language-javascript\">import React from \"react\";\nimport FirstComponent from \"./components/FirstComponent\";\nimport SecondComponent from \"./components/SecondComponent\";\n\nfunction App() {\n  return (\n    &#x3C;div className=\"App\">\n      &#x3C;h1>Merhaba Dünya!&#x3C;/h1>\n      &#x3C;FirstComponent />\n      &#x3C;SecondComponent />\n      &#x3C;p>ASNUS&#x3C;/p>\n    &#x3C;/div>\n  );\n}\n\nexport default App;\n</code></pre>\n<p>Çıktımızı aşağıdaki gibi almamız gerekmektedir. Böylelikle tek bir hook oluşturarak ayrı componentlerde ayrı değerler dönebildik. </p>\n<p><img src=\"https://asnus.com/images/custom_hook_cikti.png\" alt=\"Custom Hook Çıktısı\"></p>\n<p>Daha fazla hook örneği için <a href=\"https://antonioru.github.io/beautiful-react-hooks/\">Beautiful React Hooks</a> sayfasına veya <a href=\"https://github.com/antonioru/beautiful-react-hooks\">Github</a> sayfasına bakabilirsiniz.</p>"},{"url":"/posts/react-hooks-rehberi/","relativePath":"posts/react-hooks-rehberi.md","relativeDir":"posts","base":"react-hooks-rehberi.md","name":"react-hooks-rehberi","frontmatter":{"title":"React Hooks: Kafanı Karıştırmadan Öğren","author":"sametsunman","subtitle":"useState, useEffect, useRef derken kafan mı karıştı? Merak etme, hepimiz oradan geçtik. Bu yazıda React Hooks'u sanki kahve içerken sohbet ediyormuşuz gibi anlatacağım.","date":"2025-12-05","thumb_img_alt":"react hooks","content_img_alt":"react hooks","excerpt":"useState, useEffect, useRef derken kafan mı karıştı? Merak etme, hepimiz oradan geçtik. Bu yazıda React Hooks'u sanki kahve içerken sohbet ediyormuşuz gibi anlatacağım.","canonical_url":"","template":"post","thumb_img_path":"images/react-hooks.png","content_img_path":"images/react-hooks.png"},"html":"<p>Hatırlıyor musun, eskiden React'ta class component yazardık? <code>this.state</code>, <code>this.setState</code>, <code>componentDidMount</code>... Bir sürü şey ezberlemen gerekirdi. Sonra 2019'da React ekibi dedi ki: \"Yeter artık, hayatınızı kolaylaştıralım.\" Ve Hooks doğdu.</p>\n<p>Şimdi gel, bu hook'ları bir güzel anlatalım.</p>\n<h2>useState - En Temel Arkadaşın</h2>\n<p>Diyelim ki bir sayaç yapıyorsun. Eskiden class component yazıp <code>this.state</code> falan derdin. Şimdi?</p>\n<pre><code class=\"language-javascript\">import { useState } from 'react';\n\nfunction Sayac() {\n  const [sayi, setSayi] = useState(0);\n\n  return (\n    &#x3C;div>\n      &#x3C;p>Sayı: {sayi}&#x3C;/p>\n      &#x3C;button onClick={() => setSayi(sayi + 1)}>Artır&#x3C;/button>\n    &#x3C;/div>\n  );\n}\n</code></pre>\n<p>İşte bu kadar. <code>useState(0)</code> diyorsun, sana iki şey veriyor:</p>\n<ul>\n<li><code>sayi</code>: Şu anki değer</li>\n<li><code>setSayi</code>: Değeri değiştirmek için kullanacağın fonksiyon</li>\n</ul>\n<p>Parantez içindeki <code>0</code> başlangıç değeri. String, array, object ne istersen koyabilirsin.</p>\n<h3>Küçük Bir İpucu</h3>\n<p>State'i güncellerken önceki değere ihtiyacın varsa, şöyle yap:</p>\n<pre><code class=\"language-javascript\">setSayi(oncekiDeger => oncekiDeger + 1);\n</code></pre>\n<p>Neden mi? Çünkü React bazen state güncellemelerini toplu yapar. Bu şekilde her zaman en güncel değeri alırsın.</p>\n<h2>useEffect - Yan Etkilerin Kralı</h2>\n<p>\"Yan etki\" kulağa kötü bir şey gibi geliyor ama değil. API'den veri çekmek, DOM'u manuel değiştirmek, timer kurmak... Bunların hepsi yan etki.</p>\n<pre><code class=\"language-javascript\">import { useState, useEffect } from 'react';\n\nfunction Profil({ userId }) {\n  const [kullanici, setKullanici] = useState(null);\n\n  useEffect(() => {\n    // Component yüklendiğinde veya userId değiştiğinde çalışır\n    fetch(`/api/kullanici/${userId}`)\n      .then(res => res.json())\n      .then(data => setKullanici(data));\n  }, [userId]); // Bağımlılık dizisi\n\n  if (!kullanici) return &#x3C;p>Yükleniyor...&#x3C;/p>;\n  return &#x3C;h1>{kullanici.isim}&#x3C;/h1>;\n}\n</code></pre>\n<p>O sondaki <code>[userId]</code> çok önemli. React'a \"sadece userId değiştiğinde bu effect'i tekrar çalıştır\" diyorsun.</p>\n<h3>Bağımlılık Dizisi Olayı</h3>\n<ul>\n<li><code>[]</code> (boş dizi): Sadece component ilk yüklendiğinde çalışır</li>\n<li><code>[userId]</code>: userId her değiştiğinde çalışır</li>\n<li>Hiç yazmazsan: Her render'da çalışır (genelde istemezsin bunu)</li>\n</ul>\n<h3>Temizlik Yapma</h3>\n<p>Bir timer kurdun veya bir event listener ekledin. Component kaldırılınca bunları temizlemen lazım, yoksa memory leak olur:</p>\n<pre><code class=\"language-javascript\">useEffect(() => {\n  const timer = setInterval(() => {\n    console.log('Tick!');\n  }, 1000);\n\n  // Cleanup fonksiyonu\n  return () => {\n    clearInterval(timer);\n  };\n}, []);\n</code></pre>\n<h2>useRef - DOM'a Dokunmak İstediğinde</h2>\n<p>Bazen bir input'a focus vermek veya bir elementin boyutunu ölçmek istersin. İşte useRef bunun için:</p>\n<pre><code class=\"language-javascript\">import { useRef } from 'react';\n\nfunction Form() {\n  const inputRef = useRef(null);\n\n  const focusla = () => {\n    inputRef.current.focus();\n  };\n\n  return (\n    &#x3C;div>\n      &#x3C;input ref={inputRef} type=\"text\" />\n      &#x3C;button onClick={focusla}>Input'a Focusla&#x3C;/button>\n    &#x3C;/div>\n  );\n}\n</code></pre>\n<h3>useRef'in Gizli Süper Gücü</h3>\n<p>useRef sadece DOM için değil. Render'lar arasında bir değeri saklamak istiyorsan ama bu değer değiştiğinde yeniden render olmasını istemiyorsan, useRef kullan:</p>\n<pre><code class=\"language-javascript\">function Zamanlayici() {\n  const renderSayisi = useRef(0);\n\n  renderSayisi.current += 1;\n\n  console.log(`Bu component ${renderSayisi.current} kez render oldu`);\n\n  // ...\n}\n</code></pre>\n<h2>useMemo - Gereksiz Hesaplamaları Önle</h2>\n<p>Diyelim ki çok ağır bir hesaplama yapıyorsun. Her render'da tekrar hesaplanmasını istemezsin:</p>\n<pre><code class=\"language-javascript\">import { useMemo } from 'react';\n\nfunction Liste({ items, filtre }) {\n  const filtrelenmisListe = useMemo(() => {\n    console.log('Filtreleme yapılıyor...');\n    return items.filter(item => item.includes(filtre));\n  }, [items, filtre]);\n\n  return (\n    &#x3C;ul>\n      {filtrelenmisListe.map(item => &#x3C;li key={item}>{item}&#x3C;/li>)}\n    &#x3C;/ul>\n  );\n}\n</code></pre>\n<p><code>items</code> veya <code>filtre</code> değişmedikçe, filtreleme tekrar yapılmaz. Önceki sonuç kullanılır.</p>\n<h3>Ama Dikkat!</h3>\n<p>Her şeyi useMemo'ya sarma. useMemo'nun kendisi de bir maliyet. Sadece gerçekten ağır işlemlerde kullan.</p>\n<h2>useCallback - Fonksiyonları Hafızaya Al</h2>\n<p>Bu biraz useMemo'ya benziyor ama fonksiyonlar için:</p>\n<pre><code class=\"language-javascript\">import { useCallback } from 'react';\n\nfunction Uygulama() {\n  const [sayi, setSayi] = useState(0);\n\n  const pisBirsey = useCallback(() => {\n    console.log('Tıklandı!');\n  }, []);\n\n  return &#x3C;Buton onClick={pisBirsey} />;\n}\n</code></pre>\n<p><code>Buton</code> component'i <code>React.memo</code> ile sarılmışsa, <code>tikla</code> fonksiyonu her render'da yeniden oluşmaz. Böylece <code>Buton</code> gereksiz yere render olmaz.</p>\n<h2>useContext - Prop Drilling'e Son</h2>\n<p>10 seviye derinlikte bir component'e veri mi geçirmen gerekiyor? Her seviyede prop olarak mı taşıyacaksın? Hayır!</p>\n<pre><code class=\"language-javascript\">import { createContext, useContext } from 'react';\n\n// Context oluştur\nconst TemaContext = createContext('light');\n\n// Provider ile sar\nfunction Uygulama() {\n  return (\n    &#x3C;TemaContext.Provider value=\"dark\">\n      &#x3C;Sayfa />\n    &#x3C;/TemaContext.Provider>\n  );\n}\n\n// Derinlerde bir yerde kullan\nfunction DerinComponent() {\n  const tema = useContext(TemaContext);\n  return &#x3C;div className={tema}>Tema: {tema}&#x3C;/div>;\n}\n</code></pre>\n<p>Artık aradaki tüm component'lere prop geçirmene gerek yok.</p>\n<h2>useReducer - Karmaşık State İçin</h2>\n<p>useState yetmiyorsa, birden fazla state birbiriyle bağlantılıysa, useReducer kullan:</p>\n<pre><code class=\"language-javascript\">import { useReducer } from 'react';\n\nconst initialState = { count: 0 };\n\nfunction reducer(state, action) {\n  switch (action.type) {\n    case 'artir':\n      return { count: state.count + 1 };\n    case 'azalt':\n      return { count: state.count - 1 };\n    case 'sifirla':\n      return { count: 0 };\n    default:\n      return state;\n  }\n}\n\nfunction Sayac() {\n  const [state, dispatch] = useReducer(reducer, initialState);\n\n  return (\n    &#x3C;div>\n      &#x3C;p>Sayı: {state.count}&#x3C;/p>\n      &#x3C;button onClick={() => dispatch({ type: 'artir' })}>+&#x3C;/button>\n      &#x3C;button onClick={() => dispatch({ type: 'azalt' })}>-&#x3C;/button>\n      &#x3C;button onClick={() => dispatch({ type: 'sifirla' })}>Sıfırla&#x3C;/button>\n    &#x3C;/div>\n  );\n}\n</code></pre>\n<p>Redux'a benziyor değil mi? Zaten Redux'un temel mantığı bu.</p>\n<h2>React 19 ile Gelen Yenilikler</h2>\n<p>React 19 ile birkaç güzel şey geldi:</p>\n<h3>use() - Artık Promise'leri Direkt Kullan</h3>\n<pre><code class=\"language-javascript\">import { use } from 'react';\n\nfunction Kullanici({ userPromise }) {\n  const kullanici = use(userPromise);\n  return &#x3C;h1>{kullanici.isim}&#x3C;/h1>;\n}\n</code></pre>\n<h3>useFormStatus - Form Durumunu Takip Et</h3>\n<pre><code class=\"language-javascript\">import { useFormStatus } from 'react-dom';\n\nfunction GonderButonu() {\n  const { pending } = useFormStatus();\n  return (\n    &#x3C;button disabled={pending}>\n      {pending ? 'Gönderiliyor...' : 'Gönder'}\n    &#x3C;/button>\n  );\n}\n</code></pre>\n<h3>useOptimistic - İyimser Güncellemeler</h3>\n<p>Kullanıcı bir şey yaptığında, sunucu cevabını beklemeden UI'ı güncelle:</p>\n<pre><code class=\"language-javascript\">import { useOptimistic } from 'react';\n\nfunction Yorumlar({ yorumlar }) {\n  const [iyimserYorumlar, iyimserEkle] = useOptimistic(\n    yorumlar,\n    (state, yeniYorum) => [...state, yeniYorum]\n  );\n\n  // Form gönderildiğinde iyimserEkle çağır\n  // Sunucu cevabını beklemeden yorum görünür\n}\n</code></pre>\n<h2>Kendi Hook'unu Yaz</h2>\n<p>En güzel şeylerden biri: Kendi hook'unu yazabilirsin!</p>\n<pre><code class=\"language-javascript\">function useLocalStorage(key, initialValue) {\n  const [value, setValue] = useState(() => {\n    const saved = localStorage.getItem(key);\n    return saved ? JSON.parse(saved) : initialValue;\n  });\n\n  useEffect(() => {\n    localStorage.setItem(key, JSON.stringify(value));\n  }, [key, value]);\n\n  return [value, setValue];\n}\n\n// Kullanımı\nfunction Ayarlar() {\n  const [tema, setTema] = useLocalStorage('tema', 'light');\n  // ...\n}\n</code></pre>\n<h2>Hook Kuralları (Bunları Ezberle!)</h2>\n<ol>\n<li><strong>Hook'ları sadece en üst seviyede çağır.</strong> Döngü, koşul veya iç fonksiyonlarda kullanma.</li>\n</ol>\n<pre><code class=\"language-javascript\">// YANLIŞ\nif (kosul) {\n  const [deger, setDeger] = useState(0);\n}\n\n// DOĞRU\nconst [deger, setDeger] = useState(0);\nif (kosul) {\n  // deger'i burada kullan\n}\n</code></pre>\n<ol start=\"2\">\n<li><strong>Hook'ları sadece React fonksiyonlarında çağır.</strong> Normal JavaScript fonksiyonlarında değil.</li>\n</ol>\n<h2>Son Sözler</h2>\n<p>Hook'lar React'ı çok daha keyifli hale getirdi. Başta biraz kafa karıştırıcı olabilir ama bir kere alıştın mı, class component'lere geri dönmek istemezsin.</p>\n<p>En önemli üçlü: <code>useState</code>, <code>useEffect</code>, <code>useRef</code>. Bunları iyi öğren, gerisi gelir.</p>\n<p>Takıldığın yer olursa, React dökümantasyonu gerçekten çok iyi. Bir de pratik yap, bol bol yaz. Yazarak öğrenilir bu işler.</p>\n<hr>\n<p><em>Hooks hakkında aklına takılan bir şey varsa yorumlarda sor. Hep beraber öğrenelim!</em></p>"},{"url":"/posts/react-native-env-dosyası/","relativePath":"posts/react-native-env-dosyası.md","relativeDir":"posts","base":"react-native-env-dosyası.md","name":"react-native-env-dosyası","frontmatter":{"title":"React Native'de ENV Dosyası Nasıl Oluşturulur ve Nasıl Kullanılır?","subtitle":"`.env` dosyası, bir proje için kullanılacak ortam değişkenlerinin (environment variables) tutulduğu bir dosyadır. Bu dosya, projenin çalıştırılacağı ortamda (örneğin, test ortamı, üretim ortamı gibi) değişebilecek olan değerlerin tutulduğu bir yerdir. ","date":"2023-01-02T00:00:00.000Z","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/react-native-env.png","content_img_path":"images/react-native-env.png"},"html":"<p>Örneğin, bir web uygulamasında kullanılan bir veritabanının adresi ve kullanıcı adı gibi bilgilerin tutulduğu bir dosya olabilir.</p>\n<p><code>.env</code> dosyaları genellikle bir projenin kaynak kodu ile birlikte saklanır, ancak projenin çalıştırılacağı ortamdan bağımsızdır ve bu nedenle projenin kaynak kodu deposuna yüklenmez. Bu sayede, projenin farklı ortamlarda çalıştırılması sırasında çevre değişkenlerinin değerleri değiştirilebilir.</p>\n<p>Öncelik olarak <code>react-native-dotenv</code> paketini projemize yükleyelim.</p>\n<pre><code>npm i react-native-dotenv\n</code></pre>\n<p>Projemizde bulunan <code>babel</code> çeviricinin yeni eklediğimiz pakete uyumunu sağlayabilmek adına yapılandırmalarını sağlıyalım. Projemizde bulunan <code>babel.configure.js</code> dosyasını düzenliyelim. İçerisine aşağıdaki ayarlamaları sağlıyalım.</p>\n<pre><code>module.exports = {\n  \"plugins\": [\n    [\"module:react-native-dotenv\", {\n      \"moduleName\": \"@env\",\n      \"path\": \".env\",\n      \"blacklist\": null,\n      \"whitelist\": null,\n      \"safe\": false,\n      \"allowUndefined\": true\n    }]\n  ]\n}\n</code></pre>\n<p>Ortam değişkinleri için gerekli ayarlamaları sağladık. Sıra kullanımına geldi. Projemize <code>.env</code> isminde bir dosya açalım. İçerisine kullanacağımız değişkenleri belirleyelim.</p>\n<p><img src=\"https://asnus.com/images/env-code.png\" alt=\"env-code\"></p>\n<p>Daha sonra oluşturduğumuz bu değişkenleri kullanacağımız dosya içerisinde değişkenlerimizi çağırıp işlemleri sağlayabiliriz.</p>\n<pre><code>import { API_KEY, APP_NAME, APP_VERSION, AUTH_DOMAIN } from '@env';\n\nconsole.log(APP_NAME); // Çıktı Olarak \"Asnus\" ifadesi gelecektir.\n</code></pre>\n<p>Ayrıca, .env dosyasının içeriği projenin çalıştırılacağı ortamdan bağımsızdır ve bu nedenle projenin farklı ortamlarda çalıştırılması sırasında çevre değişkenlerinin değerleri değiştirilebilir. Örneğin, test ortamı için .env.test, üretim ortamı için de .env.production gibi. Bu sayede, her ortam için farklı çevre değişkenleri kullanılabilir.</p>\n<p>Not: Eğer projenizin çalıştırılacağı ortamı belirtmek istemiyorsanız, varsayılan olarak .env dosyasını kullanabilirsiniz. Bu dosya, projenin çalıştırılacağı ortam belirtilmezse varsayılan olarak kullanılır.</p>\n<p>Bu blog yazısında <code>react-native</code> projemizde ortam değişkenlerini nasıl kullanacağımıza baktık. <code>react-native-dotenv</code> npm paketini kurduktan sonra <code>babel.config.js</code> dosyamızı yapılandırdık. Son olarak, bir env dosyası oluşturduk ve kullanmak istediğimiz dosyada/kaynak kodda ortam değişkenini içe aktardık.</p>"},{"url":"/posts/react-native-linux-kurulumu/","relativePath":"posts/react-native-linux-kurulumu.md","relativeDir":"posts","base":"react-native-linux-kurulumu.md","name":"react-native-linux-kurulumu","frontmatter":{"title":"React Native Linux Kurulumu","subtitle":"Merhaba arkadaşlar, Linux işletim sistemleri üzerinde bir React Native uygulaması nasıl geliştirmek için gerekli yazılımların kurulumlarını anlatmak istiyorum.","date":"2020-12-26","thumb_img_alt":"react-native","content_img_alt":"react-native","excerpt":"Merhaba arkadaşlar, Linux işletim sistemleri üzerinde bir React Native uygulaması nasıl geliştirmek için gerekli yazılımların kurulumlarını anlatmak istiyorum.","canonical_url":"","author":"sametsunman, ihsansunman","featured":true,"template":"post","thumb_img_path":"images/react-native.png","content_img_path":"images/react-native.png"},"html":"<p>Öncelikle şunu söylemeliyim Linux’ta React Native CLI ile IOS için uygulama geliştirme desteklenmiyor. O yüzden yazımızda yalnızca Android için kurulum adımlarından bahsedeceğiz.</p>\n<p>Kendi bilgisayarımda Linux Mint 20 kurulu, ancak Ubuntu ve diğer Debian tabanlı sistemlerle kurulum, benzerlik göstermekte. Hemen uygulama geliştirmek için gereksinimlerimize bakalım.</p>\n<ul>\n<li>NodeJS ve NPM</li>\n<li>NPM</li>\n<li>JDK</li>\n<li>Android Studio ve SDK</li>\n<li>Watchman</li>\n<li>Text editörü (VS Code, ATOM, Sublime Text vb.)</li>\n<li>Android Emulatörü (İsteğe Bağlı)(Genymotion vb.)</li>\n</ul>\n<h3>Node JS Kurulumu</h3>\n<p>NodeJs için 10 ya da daha üst versiyonu kurmamız gerekiyor. Birden fazla kurulum yöntemi var ancak bana göre en kolay PPA ile kurulum yapmak. Dilerseniz resmi sitesinden de yardım alabilirsiniz.</p>\n<p><a href=\"https://nodejs.org/en/download/package-manager/\">https://nodejs.org/en/download/package-manager/</a></p>\n<p>İlk adım olarak paket deposunu güncelleyin.</p>\n<p>Sonrasında NodeJS için gerekli paketi yükleyin. Şuan son sürüm 14 versiyon olduğu için ben onu kuruyorum.</p>\n<p>NodeJs ile birlikte npm de kurulacaktır. Ve son olarak nodejs versiyonunu kontrol edin.</p>\n<p>Başarılı olduysa, size versiyonu verecektir.</p>\n<h3>Java Development Kit Kurulumu</h3>\n<p>JDK da uygulama geliştirmemiz için gerekli olan bileşenlerden, kurulumu da oldukça basit. Yine gerekli durumlarda resmi site dökümasyonuna bakmanızı tavsiye ederim.</p>\n<p><a href=\"https://www.oracle.com/java/technologies/javase-jdk15-downloads.html\">https://www.oracle.com/java/technologies/javase-jdk15-downloads.html</a></p>\n<p>Yukarıdaki linkte öncelikle oturum açmanız gerekiyor ve sonrasında Linux x64 Debian Package (Debian kurulum paketi) indirin. İndirilen dosyayı direk açarak kurulum gerçekleştirin.</p>\n<h3>Watchman Kurulumu</h3>\n<p>Watchman ne işe yarıyor derseniz, Facebook tarafından dosya sistemlerini izleyen ve performans açısından mutlaka önerilen bir yazılım. Kurmak için öncelikle Homebrew’i kurmak gerekiyor.</p>\n<p>Ardından da watchman’i yükleyelim</p>\n<h3>Android Studio Kurulumu</h3>\n<p>En önemli kısım burası, Android Studio ve Sdk kurulumu biraz zahmetli ve uzun sürmekte, sabırlı olmanız gerekiyor.</p>\n<p>İlk adım olarak Resmi web sitesinden tar.gz dosyasını indirmeniz gerek.</p>\n<p><a href=\"https://developer.android.com/studio\">https://developer.android.com/studio</a></p>\n<p>İndirdiğiniz dosyayı bir dizine çıkarmanız gerekmekte, ben indirdiğimiz yerden local dizinine kopyalıyorum.</p>\n<p>Daha sonra ise android studio’yu başlatmamız gerekiyor. Ancak öncesinden Menü’ye bir kısayol oluşturalım. Bunun için ise Menü’ye sağ tıklayıp yapılandıra tıklayalım. Ardından ise menü sekmesinden ‘Menü düzenleyiciyi aç’ butonuna tıklayalım. Yeni menü’ye tıklayıp komut kısmında Android Studio’yu kopyaladığımız dizinin altında bin klasöründe studio.sh dosyasını seçelim. Dilerseniz ikon da ekleyebilirsiniz. Herşey doğru şekilde yapıldıktan sonra Menü’de Android Studio’yu görebileceksiniz.</p>\n<p>Şimdi Android Studio’yu açıp, ilk kurulumu yapalım. Bu adım internet hızınıza bağlı olarak biraz uzun sürecektir.</p>\n<h3>Android SDK Kurulumu</h3>\n<p>Android Studio Kurulumunu yaptıktan sonra Tools>Android>SDK Manager kısmından SDK kurulumunu yapalım. Açılan pencerede sağ alttan “Show Package Details” seçimini yapalım ve sonra React Native güncel olarak Android 10'u desteklediği için menüden “Android SDK Platform 29”, “Intel x86 Atom_64 System Image” ve “Google APIs Intel x86 Atom_64 System Image” seçeneklerini seçerek gerekli kurulumları yapıyoruz.</p>\n<h3>Ortam Değişkenlerinin Tanımlanması</h3>\n<p>Bilgisayarınızın ev dizini diye geçen kullanıcı dizinine gidin. Sağ tıklayıp gizli dosyaları göster diyin ve .bashrc dosyasını bir metin düzenleyicisi ile açıp aşağıdaki kodları en alta yapıştırın. Böyle Android kurulumlarınız diğer programlar tarafından erişilebilecek.</p>\n<h3>Android Emülatör Kurulumu</h3>\n<p>Burada üç seçeneğimiz var, ilki android Studionun kendi emülatörünü kullanmak, ikincisi Genymotion gibi diğer yazılımları kullanmak ve diğeri ise kendi telefonumuzu kullanmak.</p>\n<p><strong>Android Studio Emulator</strong></p>\n<p>Tools>Android>AVD Manager’e tıklayarak diyalog penceresini açalım,ardından “Create Virtual Device” a tıklayalım, herhangi bir cihaz seçelim, indirdiğimiz sdk ile uyumlu bir emülatör yaratalım. Burda dikkat etmeniz gerekem bilgisayar ve uygulamanızla uygun bir sdk seçmeniz gerekiyor.</p>\n<p>Herşey doğru şekilde yapıldıysa emülatörü başlatabilirsiniz.</p>\n<p><strong>Genymotion</strong></p>\n<p>Android Studio’nun oldukça hantal olmasından dolayı, kendi emülatörü yerine genymotion tercih edebilirsiniz. Ama öncesinde virtualbox kurmamız gerekiyor.</p>\n<p>Ardından ise genymotion’ı kendi sitesinden sistemimize uygun olanını indirip yine klasöre çıkararak kuralım.</p>\n<p><a href=\"https://medium.com/r/?url=https%3A%2F%2Fwww.genymotion.com%2Fdownload%2F\">https://www.genymotion.com/download/</a></p>\n<p>Yukarıdaki kodda indirdiğimiz dosyayı opt dizinine taşıyoruz. Daha sonra ise yapmamız gereken gerekli izinleri vermek. Aşağıdaki kodları sırasıyla yapalım.</p>\n<p>Kısayol oluşturmak için Android Studio’daki gibi yine menü düzenleyiciden “/opt/genymobile/genymotion/genymotion” komutunu ekleyebiliriz.</p>\n<p>Emülatör’ü çalıştırdıktan sonra önce oturum açmamız gerekiyor, ardından da bir cihaz yaratmamız gerekiyor.</p>\n<p><strong>Fiziksel Cihaz Bağlanması</strong></p>\n<p>Emülatörler yerine kendi telefonumuzu da uygulamalarımız için kullanabiliriz ve bu windows işletim sistemine göre oldukça kolay, çünkü cihazımızın driver’ı otomatik yüklüyor.</p>\n<p>Hemen anlatalım, ilk önce kurulum yapmamız gerekiyor.</p>\n<p>Ardından Android Studio’u açalım, telefonumuzun geliştirici seçeneklerinden (Eğer telefonunuzda yoksa Android sürümünüze 5 kere tıklamanız gerekli) “USB Hata Ayıklama” seçeneğini aktifleştirelim, ardından usb kablo ile bağlayalım. Ve telefonunuza gelen hata ayıklama ile ilgili bildirimi kabul edelim. Böylece Android Studio’da sağ üstte telefonunuzu görebileceksiniz. Eğer görmüyorsanız. Uygulamada Cihaz ayarları kısmından kurulum yapmayı deneyebiliriniz.</p>\n<h3>Visual Studio Code Kurulumu</h3>\n<p>Uyguluma geliştirmek için bir çok yardımcı aracı, eklentileri, kendine ait uçbirimi, git sistemi olması nedeniyle ben VS Code kullanıyorum. Dilerseniz başka IDE ya da kod düzenleyicisi de kullanabilirsiniz.</p>\n<p><a href=\"https://code.visualstudio.com/Download\">https://code.visualstudio.com/Download</a> adresinden işletim sisteminize uygun deb paketini indirelim ve dosyayı direk açarak kuralım.</p>\n<h3>React Native Uygulaması Oluşturulması ve Çalıştırılması</h3>\n<p>Herşey hazırsa bir uçbirim açalım ve ilk uygulamamızı oluşturalım:</p>\n<p>Ardından oluşturduğumuz proje klasörünü VS Code’da açalım. Öncelikle terminal pencerimizden uygulamayı başlatalım.</p>\n<p>Emülatörü çalıştıralım ya da fiziksel cihazımızı bağlayalım ve uygulamayı çalıştıralım. Ardından yeni bir terminalde şu kodu çalıştıralım:</p>\n<p>Uygulamamızı çalıştırırken benim gibi envoriment ile ilgili hata alırsanız, öncelikle ortam değişkenlerini doğru şekilde tanımladığınızdan emin olun eğer işe yaramıyorsa “android/gradle/wrapper/gradle-wrapper.properties” dosyasında gradle versiyonuzu 6.5'e yükseltmeyi deneyin.</p>\n<p>Herşey yolunda gittiyse ilk uygulamamız emülatörde göreceksiniz. Şimdi dilerseniz App.Js’ten başlayarak düzenleme yapabilirisiniz :)</p>\n<p>İyi şanslar. Peace :)</p>"},{"url":"/posts/react-redux-yerine-zustand-kullanimi/","relativePath":"posts/react-redux-yerine-zustand-kullanimi.md","relativeDir":"posts","base":"react-redux-yerine-zustand-kullanimi.md","name":"react-redux-yerine-zustand-kullanimi","frontmatter":{"title":"React'ta Redux Yerine Zustand Kullanımı","author":"sametsunman","subtitle":"Redux'un karmaşık yapısından ve boilerplate kodlarından sıkıldıysanız, Zustand tam size göre. Minimal, hızlı ve öğrenmesi kolay bir state management kütüphanesi olan Zustand ile projelerinizi nasıl sadeleştirebileceğinizi keşfedin.","date":"2025-12-10","thumb_img_alt":"zustand","content_img_alt":"zustand","excerpt":"Redux'un karmaşık yapısından ve boilerplate kodlarından sıkıldıysanız, Zustand tam size göre. Minimal, hızlı ve öğrenmesi kolay bir state management kütüphanesi olan Zustand ile projelerinizi nasıl sadeleştirebileceğinizi keşfedin.","canonical_url":"","template":"post","thumb_img_path":"images/redux-zustand.jpg","content_img_path":"images/redux-zustand.jpg"},"html":"<p>State management, React uygulamalarının en kritik konularından biri. Yıllarca Redux bu alanda standart oldu, ancak son yıllarda daha minimal ve kullanımı kolay alternatifler ortaya çıktı. Bunların başında <strong>Zustand</strong> geliyor.</p>\n<h2>Redux'un Sorunları</h2>\n<p>Redux güçlü bir araç, ancak bazı dezavantajları var:</p>\n<ul>\n<li><strong>Çok fazla boilerplate kod</strong>: Action types, action creators, reducers, store configuration...</li>\n<li><strong>Öğrenme eğrisi yüksek</strong>: Yeni başlayanlar için kavramları anlamak zor</li>\n<li><strong>Dosya yapısı karmaşık</strong>: Basit bir state için bile birden fazla dosya gerekebiliyor</li>\n<li><strong>Bundle size</strong>: Redux + React-Redux birlikte oldukça büyük</li>\n</ul>\n<h2>Zustand Nedir?</h2>\n<p>Zustand (Almanca \"durum\" anlamına gelir), minimalist bir state management kütüphanesidir. Sadece <strong>~1KB</strong> boyutunda ve sıfır bağımlılığa sahip.</p>\n<h2>Zustand'ın Avantajları</h2>\n<h3>1. Minimal Boilerplate</h3>\n<p>Redux'ta basit bir counter için:</p>\n<pre><code class=\"language-javascript\">// Redux - actions.js\nexport const INCREMENT = 'INCREMENT';\nexport const increment = () => ({ type: INCREMENT });\n\n// Redux - reducer.js\nconst counterReducer = (state = { count: 0 }, action) => {\n  switch (action.type) {\n    case 'INCREMENT':\n      return { count: state.count + 1 };\n    default:\n      return state;\n  }\n};\n\n// Redux - store.js\nimport { createStore } from 'redux';\nexport const store = createStore(counterReducer);\n\n// Redux - Component\nimport { useSelector, useDispatch } from 'react-redux';\nconst Counter = () => {\n  const count = useSelector(state => state.count);\n  const dispatch = useDispatch();\n  return &#x3C;button onClick={() => dispatch(increment())}>{count}&#x3C;/button>;\n};\n</code></pre>\n<p>Zustand'da aynı işlem:</p>\n<pre><code class=\"language-javascript\">// Zustand - store.js\nimport { create } from 'zustand';\n\nconst useStore = create((set) => ({\n  count: 0,\n  increment: () => set((state) => ({ count: state.count + 1 })),\n}));\n\n// Zustand - Component\nconst Counter = () => {\n  const { count, increment } = useStore();\n  return &#x3C;button onClick={increment}>{count}&#x3C;/button>;\n};\n</code></pre>\n<p>Farkı görüyor musunuz? <strong>Tek dosya, tek hook, işlem tamam.</strong></p>\n<h3>2. Provider Gerekmez</h3>\n<p>Redux'ta uygulamanızı <code>&#x3C;Provider></code> ile sarmalamanız gerekir. Zustand'da buna gerek yok:</p>\n<pre><code class=\"language-javascript\">// Redux\n&#x3C;Provider store={store}>\n  &#x3C;App />\n&#x3C;/Provider>\n\n// Zustand - Direkt kullan, sarmalama yok!\n&#x3C;App />\n</code></pre>\n<h3>3. TypeScript Desteği Mükemmel</h3>\n<p>Zustand, TypeScript ile sorunsuz çalışır:</p>\n<pre><code class=\"language-typescript\">interface BearState {\n  bears: number;\n  increase: (by: number) => void;\n}\n\nconst useBearStore = create&#x3C;BearState>()((set) => ({\n  bears: 0,\n  increase: (by) => set((state) => ({ bears: state.bears + by })),\n}));\n</code></pre>\n<h3>4. Async İşlemler Çok Kolay</h3>\n<p>Redux'ta async işlemler için Redux Thunk veya Redux Saga gerekir. Zustand'da direkt yazabilirsiniz:</p>\n<pre><code class=\"language-javascript\">const useStore = create((set) => ({\n  users: [],\n  loading: false,\n  fetchUsers: async () => {\n    set({ loading: true });\n    const response = await fetch('/api/users');\n    const users = await response.json();\n    set({ users, loading: false });\n  },\n}));\n</code></pre>\n<h3>5. Seçici (Selector) Performansı</h3>\n<p>Zustand, sadece kullandığınız state parçası değiştiğinde component'i yeniden render eder:</p>\n<pre><code class=\"language-javascript\">// Sadece 'bears' değiştiğinde render olur\nconst bears = useBearStore((state) => state.bears);\n\n// Sadece 'fish' değiştiğinde render olur\nconst fish = useBearStore((state) => state.fish);\n</code></pre>\n<h3>6. Middleware Desteği</h3>\n<p>Persist, devtools, immer gibi middleware'ler kolayca eklenebilir:</p>\n<pre><code class=\"language-javascript\">import { create } from 'zustand';\nimport { persist, devtools } from 'zustand/middleware';\n\nconst useStore = create(\n  devtools(\n    persist(\n      (set) => ({\n        count: 0,\n        increment: () => set((state) => ({ count: state.count + 1 })),\n      }),\n      { name: 'counter-storage' }\n    )\n  )\n);\n</code></pre>\n<h3>7. LocalStorage Entegrasyonu</h3>\n<p><code>persist</code> middleware ile state'inizi otomatik olarak localStorage'a kaydedebilirsiniz:</p>\n<pre><code class=\"language-javascript\">import { persist } from 'zustand/middleware';\n\nconst useStore = create(\n  persist(\n    (set) => ({\n      theme: 'light',\n      setTheme: (theme) => set({ theme }),\n    }),\n    {\n      name: 'app-settings',\n      storage: createJSONStorage(() => localStorage),\n    }\n  )\n);\n</code></pre>\n<h3>8. React Dışında da Kullanılabilir</h3>\n<p>Zustand, vanilla JavaScript'te de çalışır:</p>\n<pre><code class=\"language-javascript\">const { getState, setState, subscribe } = useStore;\n\n// React olmadan state'e erişim\nconsole.log(getState().count);\n\n// State değişikliklerini dinleme\nsubscribe((state) => console.log('State changed:', state));\n</code></pre>\n<h2>Redux vs Zustand Karşılaştırma Tablosu</h2>\n<table>\n<thead>\n<tr>\n<th>Özellik</th>\n<th>Redux</th>\n<th>Zustand</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Bundle Size</td>\n<td>~7KB + React-Redux ~5KB</td>\n<td>~1KB</td>\n</tr>\n<tr>\n<td>Boilerplate</td>\n<td>Çok</td>\n<td>Minimal</td>\n</tr>\n<tr>\n<td>Öğrenme Eğrisi</td>\n<td>Yüksek</td>\n<td>Düşük</td>\n</tr>\n<tr>\n<td>Provider Gerekli</td>\n<td>Evet</td>\n<td>Hayır</td>\n</tr>\n<tr>\n<td>TypeScript</td>\n<td>Ek ayar gerekli</td>\n<td>Doğal destek</td>\n</tr>\n<tr>\n<td>Async İşlemler</td>\n<td>Middleware gerekli</td>\n<td>Doğrudan</td>\n</tr>\n<tr>\n<td>DevTools</td>\n<td>Redux DevTools</td>\n<td>Aynı DevTools</td>\n</tr>\n<tr>\n<td>Middleware</td>\n<td>Evet</td>\n<td>Evet</td>\n</tr>\n</tbody>\n</table>\n<h2>Ne Zaman Redux, Ne Zaman Zustand?</h2>\n<p><strong>Zustand tercih edin:</strong></p>\n<ul>\n<li>Küçük-orta ölçekli projeler</li>\n<li>Hızlı prototipleme</li>\n<li>Basit state yönetimi</li>\n<li>Yeni projelere başlarken</li>\n</ul>\n<p><strong>Redux tercih edin:</strong></p>\n<ul>\n<li>Çok büyük ve karmaşık uygulamalar</li>\n<li>Time-travel debugging kritikse</li>\n<li>Takım zaten Redux'a alışkınsa</li>\n<li>Strict unidirectional data flow gerekiyorsa</li>\n</ul>\n<h2>Kurulum</h2>\n<pre><code class=\"language-bash\">npm install zustand\n# veya\nyarn add zustand\n</code></pre>\n<h2>Sonuç</h2>\n<p>Zustand, React state management'ı için mükemmel bir alternatif. Daha az kod yazarak daha çok iş yapmanızı sağlıyor. Redux'un sunduğu özelliklerin çoğunu çok daha basit bir API ile sunuyor.</p>\n<p>Yeni bir projeye başlıyorsanız veya mevcut projenizi sadeleştirmek istiyorsanız, Zustand'ı denemenizi şiddetle tavsiye ederim. Bir kere kullandıktan sonra Redux'a geri dönmek istemeyeceksiniz!</p>\n<hr>\n<p><em>Zustand hakkında sorularınız varsa yorumlarda belirtebilirsiniz. İyi kodlamalar!</em></p>"},{"url":"/posts/regex-ile-turkce-karakter-denetimi/","relativePath":"posts/regex-ile-turkce-karakter-denetimi.md","relativeDir":"posts","base":"regex-ile-turkce-karakter-denetimi.md","name":"regex-ile-turkce-karakter-denetimi","frontmatter":{"title":"Regex ile Türkçe Karakter Denetimi","author":"sametsunman","subtitle":"lorem-ipsum","date":"2021-01-13","thumb_img_alt":"regex","content_img_alt":"regex","excerpt":"lorem-ipsum","canonical_url":"","template":"post","thumb_img_path":"images/regex.png","content_img_path":"images/regex.png"},"html":"<pre><code>Regex rgx = new Regex(\"(?:[^a-zA-Z0-9ğüşöçıİĞÜŞÖÇ!?.\\\\-*() ,&#x3C;>'\\\":/=]| (?&#x3C;=['\\\"])s)\", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);\n            string content = \"\";\n\n            if (rgx.Matches(product.Content).Count &#x3C; 150)\n            {\n                content = rgx.Replace(product.Content, String.Empty); \n\n            }\n</code></pre>\n<p><a href=\"https://regexr.com\">https://regexr.com</a></p>"},{"url":"/posts/react-usememo/","relativePath":"posts/react-usememo.md","relativeDir":"posts","base":"react-usememo.md","name":"react-usememo","frontmatter":{"title":"React - useMemo Nedir ve Nasıl Kullanılır?","subtitle":"useMemo, gereksiz render işleminin önüne geçmek sebebi ile değişmeyen state'lere sahip sayfaların render işlemini engeller.","date":"2022-10-05","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/useMemo.jpg","content_img_path":"images/useMemo.jpg"},"html":"<p>React ile hazırladığımız projede oluşturduğumuz state'leri farklı componentlere aktarmamız gerekebilir. Bu durumda state değişmese bile o componentlerin de render edilme sorunu ile karşılaşırız.</p>\n<p>Herhangi bir props yollamadığımız durumlarda o sayfanın render edilmesini export ederken React.memo ile dışa aktarım yaptığımızda bu sorunu çözebiliriz.</p>\n<pre><code>import React from \"react\";\n\nfunction Header() {\n  return (\n    &#x3C;div>\n      &#x3C;div>Header&#x3C;/div>\n    &#x3C;/div>\n  );\n}\nexport default React.memo(Header);\n</code></pre>\n<p>Ancak componentimize prop göndermek istediğimizde state değişmese dahi componentin de tekrar çalıştığını görürüz. Bu sorunu çözmek için ise oluşturduğumuz state'i useMemo kullanarak oluşturmamızdır. </p>\n<p><img src=\"https://asnus.com/images/usememo-cikti.png\" alt=\"useMemo Çıktısı\"></p>\n<p>Yukarıda görüldüğü gibi oluşturduğumuz objenin içerisi değişmesi durumunda Header componenti render ediliyor. Aşağıda bulunan kod ile inceleme sağlayabilirsiniz. </p>\n<iframe src=\"https://codesandbox.io/embed/sparkling-silence-3lvgw2?autoresize=1&expanddevtools=1&fontsize=14&hidenavigation=1&theme=dark\"\n     style=\"width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;\"\n     title=\"sparkling-silence-3lvgw2\"\n     allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n     sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n></iframe>\n<p><a href=\"https://codesandbox.io/s/sparkling-silence-3lvgw2?autoresize=1&#x26;expanddevtools=1&#x26;fontsize=14&#x26;hidenavigation=1&#x26;theme=dark\"><img src=\"https://codesandbox.io/static/img/play-codesandbox.svg\" alt=\"Edit sparkling-silence-3lvgw2\"></a></p>\n<p>Reactın bu özelliği sayesinde gereksiz renderın önüne geçebiliriz.</p>"},{"url":"/posts/vs-code'da-github-deposuna-proje-aktarmak/","relativePath":"posts/vs-code'da-github-deposuna-proje-aktarmak.md","relativeDir":"posts","base":"vs-code'da-github-deposuna-proje-aktarmak.md","name":"vs-code'da-github-deposuna-proje-aktarmak","frontmatter":{"title":"VS Code'da Github Deposuna Proje Aktarmak","subtitle":"Merhaba arkadaşlar, günümüzde birçok proje VS Code ile yazılmakta. Ve bu projeleri GitHub depolarında saklıyoruz. Peki yeni başlayanlar için bu bağlantıyı nasıl sağlayacağız ve güncellemeleri nasıl yapacağız bunu öğreneceğiz.","date":"2021-01-30","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/git0.png","content_img_path":"images/git0.png"},"html":"<p>Öncelik olarak VS Code üzerinden yeni bir depo oluşturalım. Sol menüden \"Source Control\" kısmına girerek \"Publish to GitHub\"  butonuna tıklayarak üst kısımda çıkan bölmeden ayarlamaları yaparak depoyu oluşturuyoruz.</p>\n<p><img src=\"https://raw.githubusercontent.com/asnuscom/asnus/master/static/images/git1.png\"></p>\n<p>Daha sonrasında yeni bir terminal başlatmak adına yukarıdaki menüden  Terminal > New Terminal tuşlamalarını yaparak terminalimizi başlatalım.  Açılan terminale daha öncesinde de <a href=\"https://asnus.com/posts/projede-git-kullanici-adi-ve-epostasi-nasil-degistirilir/\">şu konuda</a> bahsettiğimiz gibi GitHub kullanıcı adı ve mail adreslerimizi ayarlıyalım.</p>\n<pre><code>git config user.name \"KULLANICIADI\"\ngit config user.email \"KULLANICIADI@MAIL.COM\"\ngit remote add origin https://github.com/ihsansunman/test.git\ngit branch -M main\ngit push -u origin main\n</code></pre>\n<p>Artık dosyalarımızın GitHub depomuzda olduğunu göreceksiniz. Ayarlamalarımızı da yaptıktan sonra düzenlemelerimizi işlemek (commit) için yine \"Source Control\" üzerinden aşağıda bulunan görselde \"MESAJINIZ\" yazan yere yapılan değişiklikleri yazarak yukarıda bulanan tik (check) işaretine basarak değğişiklerimizi ayarlıyalım. Ve en son halini görselde bulunan \"Push\" seçeneği ile GitHub ile eşitleyelim. Artık bu şekilde deponuzu güncelleyebilirsiniz.</p>\n<p><img src=\"https://raw.githubusercontent.com/asnuscom/asnus/master/static/images/git2.png\"></p>\n<p>İyi Kodlamalar.</p>"},{"url":"/posts/windows-10'da-komuttan-kablosuz-baglanti-paylasma/","relativePath":"posts/windows-10'da-komuttan-kablosuz-baglanti-paylasma.md","relativeDir":"posts","base":"windows-10'da-komuttan-kablosuz-baglanti-paylasma.md","name":"windows-10'da-komuttan-kablosuz-baglanti-paylasma","frontmatter":{"title":"Windows 10'da Komuttan Kablosuz Bağlantı Paylaşma","author":"ihsansunman","subtitle":"Merhaba arkadaşlar bazen ethernetten (kablolu bağlantı) bazen ise wi-fi (kablosuz bağlantı) ile gelen internetin bilgisayar aracılığı ile tekrar kablosuz bir şekilde paylaşmamız gerekir. Yeni bilgisayarlarda \"Mobil Etkin Nokta\" sekmesi ile paylaşım sağlayabiliyoruz. Ancak eski sürüm Windows 10 ve eski bilgisayarlarımızda bu sekme çıkmıyor. Bundan dolayı Komut İstemcisinden kablosuz bağlantı paylaşmayı görelim:","date":"2020-04-12","thumb_img_alt":"","content_img_alt":"","excerpt":"Merhaba arkadaşlar bazen ethernetten (kablolu bağlantı) bazen ise wi-fi (kablosuz bağlantı) ile gelen internetin bilgisayar aracılığı ile tekrar kablosuz bir şekilde paylaşmamız gerekir. Yeni bilgisayarlarda \"Mobil Etkin Nokta\" sekmesi ile paylaşım sağlayabiliyoruz. Ancak eski sürüm Windows 10 ve eski bilgisayarlarımızda bu sekme çıkmıyor.","canonical_url":"","template":"post","thumb_img_path":"images/cmd2.png","content_img_path":"images/cmd2.png"},"html":"<ul>\n<li>Öncelikle arama kısmına \"cmd\" yazarak komut istemcimizi bulduktan sonra yönetici olarak başlatalım.</li>\n</ul>\n<p><img src=\"https://raw.githubusercontent.com/asnuscom/asnus/master/static/images/cmd1.png\" alt=\"image\"></p>\n<ul>\n<li>Daha sonra ilk komutumuzu yazıyoruz:\n\"<code>netsh wlan set hostednetwork mode=allow ssid=asnus key=ihsansunman</code>\"\nBurada ssid paylaştışımız internetin adını ve key ise şifresini belirtir. Bunları kendimize göre ayarlıyalım. (Boşluk kullanmıyalım hata alabilirsiniz.)</li>\n</ul>\n<p><img src=\"https://raw.githubusercontent.com/asnuscom/asnus/master/static/images/cmd2.png\" alt=\"image2\"></p>\n<ul>\n<li>Komutu girdikten sonra successfully yazısını görürsek başarılı olmuştur anlamına gelir.</li>\n<li>Ayarımızı yaptıktan sonra paylaşımı başlatmak için şu komutu çalıştıralım: \"<code>netsh wlan start hostednetwork</code>\"</li>\n<li>“The hosted network started.” bildirimini gördükten sonra Ağ Paylaşım Merkezini açıyoruz.</li>\n<li>Bağdaştırıcı Ayarlarını Değiştirin sekmesine giriyoruz.</li>\n</ul>\n<p><img src=\"https://raw.githubusercontent.com/asnuscom/asnus/master/static/images/cmd3.png\" alt=\"image3\"></p>\n<ul>\n<li>Ağ Bağlantılarında hangi internetimizi paylaşmak istiyorsak ona sağ tıklayıp paylaşım sekmesine geliyoruz.</li>\n<li>“Diğer ağ kullanıcıları, bu bilgisayarın internet bağlantısı yoluyla bağlansın“ seçeneğini seçip yeni oluşturduğumuz “Yerel Ağ Bağlantısı” seçeneğini seçip tamam diyoruz.</li>\n</ul>\n<p><img src=\"https://raw.githubusercontent.com/asnuscom/asnus/master/static/images/cmd4.png\" alt=\"image4\"></p>\n<p>Telefon, tablet veya başka bir cihazdan kontrol ettiğiniz taktirde seçtiğiniz ssid ismini görüyor olacaksınız. İyi internette gezinmeler dilerim.</p>"},{"url":"/posts/windowsta-orijinal-degil-yazisi-nasil-kaldirilir/","relativePath":"posts/windowsta-orijinal-degil-yazisi-nasil-kaldirilir.md","relativeDir":"posts","base":"windowsta-orijinal-degil-yazisi-nasil-kaldirilir.md","name":"windowsta-orijinal-degil-yazisi-nasil-kaldirilir","frontmatter":{"title":"Windows'ta \"Windows Orijinal Değil\" Yazısı Nasıl Kaldırılır?","author":"sametsunman","subtitle":"Windows'umuz orijinal lisansına sahip olmadığımız taktirde, sağ alt köşede uyarı metni verir. Bu durum oldukça can sıkıcı olabilir. Çünkü tüm ekranlarda göze batarken, aynı zamanda arkaplan resmi de değiştirmemize izin vermez. Hadi nasıl kaldırabileceğimize bakalım.","date":"2019-12-02","thumb_img_alt":"windows-original-uyarisi","content_img_alt":"windows-original-uyarisi","excerpt":"Windows'umuz orijinal lisansına sahip olmadığımız taktirde, sağ alt köşede uyarı metni verir. Bu durum oldukça can sıkıcı olabilir. Çünkü tüm ekranlarda göze batarken, aynı zamanda arkaplan resmi de değiştirmemize izin vermez. Hadi nasıl kaldırabileceğimize bakalım.","canonical_url":"lorem-ipsum","template":"post","thumb_img_path":"images/windows-original-uyarisi.jpg","content_img_path":"images/windows-original-uyarisi.jpg"},"html":"<p>Notepad yada başka bir yazı düzenleyici programı açın ve aşağıdaki komutları yapıştırın.</p>\n<pre><code>@echo off\ntaskkill /F /IM explorer.exe\nexplorer.exe\nexit\n</code></pre>\n<p>Farklı Kaydet (Ctrl+Shift+S) yaparak \".txt\" formatını \".bat\" formatına çevirin. Daha sonra kaydedip dosyaya sağ tıklayarak \"Yönetici olarak çalıştır\"a tıklayın.</p>\n<p>Bilgisayarınızı yeniden başlattığınızda yazı kaybolmuş olacak</p>"},{"url":"/posts/windows-forms-uygulamasina-nasil-konsol-baglanabilir/","relativePath":"posts/windows-forms-uygulamasina-nasil-konsol-baglanabilir.md","relativeDir":"posts","base":"windows-forms-uygulamasina-nasil-konsol-baglanabilir.md","name":"windows-forms-uygulamasina-nasil-konsol-baglanabilir","frontmatter":{"title":"Windows Forms uygulamasına nasıl konsol bağlanabilir?","author":"sametsunman","subtitle":"Daha önce oluşturduğumuz Forms uygulamasında çeşitli sebeplerden dolayı konsol uygulaması da kullanmak isteyebiliriz. Nasıl yapılacağına bakalım.","date":"2020-07-17","thumb_img_alt":"win-forms-console","content_img_alt":"win-forms-console","excerpt":"Daha önce oluşturduğumuz Forms uygulamasında çeşitli sebeplerden dolayı konsol uygulaması da kullanmak isteyebiliriz. Nasıl yapılacağına bakalım.","canonical_url":"","template":"post","content_img_path":"images/win-forms-console.jpg","thumb_img_path":"images/win-forms-console.jpg"},"html":"<p><strong>1. Yöntem</strong></p>\n<p>Windows Form oluşturun...</p>\n<p>Sonra: Project Properties (Proje Tercihleri) -> Application (Uygulama) -> Output Type (Çıkış Türü) -> Console Application (Konsol Uygulaması)</p>\n<p><strong>2. Yöntem</strong></p>\n<p>Aşağıdaki kodu Form1_Load ya da Main metoduna yazarak, WinForms uygulamasında konsolu kullanabilirsiniz.</p>\n<pre><code>using System.Runtime.InteropServices;\n\nprivate void Form1_Load(object sender, EventArgs e)\n{\n    CreateConsole();\n    Console.WriteLine(\"Hello World!\");\n\n}\n\n[DllImport(\"kernel32.dll\", SetLastError = true)]\n[return: MarshalAs(UnmanagedType.Bool)]\nstatic extern bool CreateConsole();\n</code></pre>\n<p>Böyle Form ve Konsol uygulaması birlikte çalışmış olacak. İyi çalışmalar</p>"},{"url":"/posts/yuksek-cozunurluklu-gorselleri-sikistirma/","relativePath":"posts/yuksek-cozunurluklu-gorselleri-sikistirma.md","relativeDir":"posts","base":"yuksek-cozunurluklu-gorselleri-sikistirma.md","name":"yuksek-cozunurluklu-gorselleri-sikistirma","frontmatter":{"title":"Yüksek Çözünürlüklü Görselleri Sıkıştırma (Compressor.JS)","subtitle":"Firebase gibi sistemlerin bir kotası bulunur. Bu sistemlere yüksek çözünürlüklü görseller yüklendiği taktirde istek indirme kotaları çok hızlı bir şekilde dolmaktadır. Bu gibi sorunları çözebilmek için resimlerin kalitesinden çok fazla ödün vermeden veri boyutlarını düşürmeği sağlayabiliriz. ","date":"2023-02-22T00:00:00.000Z","thumb_img_alt":"","content_img_alt":"","excerpt":"","canonical_url":"","author":"ihsansunman","template":"post","thumb_img_path":"images/Ekran görüntüsü_20230222_101735.png","content_img_path":"images/Ekran görüntüsü_20230222_101735.png"},"html":"<p>Bu işlemi yapabilmek için <a href=\"https://github.com/fengyuanchen/compressorjs\">Compressor.js</a> isimli kütüphane bize yardımcı olacaktır. Aşağıda bulunan görsel giriş ve çıkış görsellerimizi göstermektedir. Fark edilemiyecek kadar küçük bir kayıp ile 2MB boyutlardan 50KB gibi boyutlara inebiliriz.</p>\n<p><img src=\"https://asnus.com/images/Untitled.png\" alt=\"Untitled\"></p>\n<p>Öncelikle kütüphanemizi projemize dahil edelim.</p>\n<pre><code class=\"language-jsx\">npm install compressorjs\n</code></pre>\n<p>Aşağıda bulunan örnek bir React projesinde olacaktır.  İlgili kütüphaneyi çağırarak %40 kalite düşürerek yeni bir görsel oluşturmasını sağlayalım.</p>\n<pre><code class=\"language-jsx\">import React, { useState } from \"react\";\nimport Compressor from \"compressorjs\";\n\nconst FileInput = () => {\n  const [file, setFile] = useState(null);\n\n  const compressorImage = (file) => {\n    // Eğer bir dosya gelmediyese fonksiyonu kırmak için kontrol sağlanır.\n    if (!file) {\n      return;\n    }\n    new Compressor(file, {\n      // Kalite %40, genişlik ise maksimum 1000px olacak şekilde ayarlamalar verilir.\n      // Bu ayarlamaları kendinize göre ayarlayabilirsiniz.\n      quality: 0.4,\n      maxWidth: 1000,\n      success(result) {\n        // Firebase File türünde veri istediği için çıkan görüntüyü dönüştürüyoruz.\n        const outFile = new File([result], file.name, { type: result.type });\n        // Sonuç görseli kullanabilmek için tanımlanan state'de aktarırız.\n        setFile(outFile);\n      },\n      error(err) {\n        console.log(err.message);\n      },\n    });\n  };\n\n  return (\n    &#x3C;>\n      &#x3C;input\n        type=\"file\"\n        onChange={(event) => {\n          compressorImage(event.target.files[0]);\n        }}\n        accept=\"/image/*\"\n      />\n    &#x3C;/>\n  );\n};\n\nexport default FileInput;\n</code></pre>\n<p>Artık çıktımızı istediğimiz gibi kullanabiliriz. Doğrudan firebase gibi sistemlere iletebiliriz. Verilen örnekte çıkan Blob nesnesi File’a çevriliyor. Eğer Blob kullanmak isterseniz doğrudan çıkan <code>result</code> çıktısını kullanabilirsiniz.</p>"},{"url":"/posts/linux-xfce-cihazlarda-vnc-baglantisinda-goruntu-gelmemesi/","relativePath":"posts/linux-xfce-cihazlarda-vnc-baglantisinda-goruntu-gelmemesi.md","relativeDir":"posts","base":"linux-xfce-cihazlarda-vnc-baglantisinda-goruntu-gelmemesi.md","name":"linux-xfce-cihazlarda-vnc-baglantisinda-goruntu-gelmemesi","frontmatter":{"title":"Linux-XFCE Cihazlarda VNC Bağlantısında Görüntü Gelmemesi","author":"ihsansunman, sametsunman","subtitle":"Linux cihazıma TightVNC Server kurdum ancak VNC ile bağlanmaya çalıştığımda gri bir ekran karşıladı beni. Aslında böyle bir ekran bizi karşıladığında sorunsuzca bağlandık demektir. Ancak bağlantı ekranımızda gerekli bileşenleri cihazımız otomatik açmadığını anlarız. Bunu da küçük bir düzenleme ile bu sorunu düzeltebiliriz. Ancak cihazımız XFCE arayüzünde ise bu işlem çalışabilir. Diğer arayüzlerde uyarlama yaparak da çözebilirsiniz.","date":"2020-04-09","thumb_img_alt":"VNC","content_img_alt":"VNC","excerpt":"Linux cihazıma TightVNC Server kurdum ancak VNC ile bağlanmaya çalıştığımda gri bir ekran karşıladı beni. Aslında böyle bir ekran bizi karşıladığında sorunsuzca bağlandık demektir. Ancak bağlantı ekranımızda gerekli bileşenleri cihazımız otomatik açmadığını anlarız.","canonical_url":"","template":"post","thumb_img_path":"images/w2CQO.png","content_img_path":"images/w2CQO.png"},"html":"<p>Kök dosya sistemimizde ~/.vnc/xstartup dosyasını yönetici izni ile açalım.</p>\n<pre><code>#!/bin/sh\n\nxrdb $HOME/.Xresources\nxsetroot -solid grey\n#x-terminal-emulator -geometry 80x24+10+10 -ls -title \"$VNCDESKTOP Desktop\" &#x26;\n#x-window-manager &#x26;\n# Fix to make GNOME work\nexport XKL_XMODMAP_DISABLE=1\n/etc/X11/Xsession\nstartxfce4 &#x26;\n</code></pre>\n<p>Yukardakine benzer bir metin bizi karşılayacaktır. Sonuna şu ibareleri eklersek sorun düzelecektir.</p>\n<pre><code>#!/bin/sh\n\nxrdb $HOME/.Xresources\nxsetroot -solid grey\nx-terminal-emulator -geometry 80x24+10+10 -ls -title \"$VNCDESKTOP Desktop\" &#x26;\nx-window-manager &#x26;\n# Fix to make GNOME work\nexport XKL_XMODMAP_DISABLE=1\nunset SESSION_MANAGER\nunset DBUS_SESSION_BUS_ADDRESS\n\n/etc/X11/Xsession\n\nxfce4-panel &#x26;\nxfsettingsd &#x26;\nxfwm4 &#x26;\nxfdesktop &#x26;\npcmanfm &#x26;\nxfce4-terminal &#x26;\n</code></pre>"}],"site":{"siteMetadata":{"description":"Asnus Blog Teknoloji Konusunda Makaleleri Paylaştığımız Bir Web Sitesidir.","layout_style":"overflow","palette":"blue","header":{"title":"Asnus","tagline":"Teknolojiye dair ipuçları..","profile_img":"images/logo.svg","profile_img_alt":"Asnus WEB","background":"dark","has_nav":true,"nav_links":[{"label":"ANASAYFA","url":"/","style":"link"},{"label":"Tüm Yazılar","url":"/blog/","style":"link"},{"label":"Hakkımızda","url":"/about/","style":"link"},{"label":"İletişim","url":"/contact/","style":"link"}],"has_social":true,"social_links":[{"label":"GitHub","url":"https://github.com/asnuscom","style":"icon","icon_class":"fa-github","new_window":true},{"label":"Twitter","url":"https://twitter.com/asnusweb","style":"icon","icon_class":"fa-twitter","new_window":true},{"label":"Instagram","url":"https://www.instagram.com/asnusweb","style":"icon","icon_class":"fa-instagram","new_window":true},{"label":"LinkedIn","url":"https://www.linkedin.com/","style":"icon","icon_class":"fa-linkedin","new_window":true}]},"footer":{"content":"©2021 ASNUS. ALL RIGHT ARE RESERVED","links":[]},"title":"ASNUS","favicon":"images/favicon.ico"},"pathPrefix":"","data":{}},"menus":{}}},"staticQueryHashes":[]}