[{"data":1,"prerenderedAt":213},["ShallowReactive",2],{"article-categories":3,"article-tags":115,"articles-list":116,"articles-recent":205},[4,20,30,40,51,62,72,84,94,104],{"categoryId":5,"name":6,"slug":7,"description":8,"icon":9,"color":10,"displayOrder":11,"articleCount":12,"parentCategoryId":13,"parentCategoryName":13,"subCategories":14,"isActive":15,"isDeleted":16,"createDate":17,"updatedDate":18,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"0291a794-76d1-4c63-b9bf-a20789876848","Teknoloji Rehberleri","teknoloji-rehberleri","Teknoloji dunyasina dair kapsamli rehberler","i-lucide-book-open","#2196F3",1,2,null,[],true,false,"2026-03-19T06:22:06.0549517","2026-08-20T18:48:49.4028438","ea4ea297-567a-491b-ac52-37db0674498b",{"categoryId":21,"name":22,"slug":23,"description":24,"icon":25,"color":26,"displayOrder":12,"articleCount":11,"parentCategoryId":13,"parentCategoryName":13,"subCategories":27,"isActive":15,"isDeleted":16,"createDate":28,"updatedDate":29,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"b87109f1-e65c-4443-9f3a-44517bc15ab7","Yazılım Geliştirme","yazilim-gelistirme","Programlama dilleri, frameworkler ve best practice yazilari","i-lucide-code","#10B981",[],"2026-03-03T08:21:13.8850795","2026-08-20T11:16:10.9662071",{"categoryId":31,"name":32,"slug":33,"description":34,"icon":35,"color":36,"displayOrder":12,"articleCount":11,"parentCategoryId":13,"parentCategoryName":13,"subCategories":37,"isActive":15,"isDeleted":16,"createDate":38,"updatedDate":39,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"0b5613ea-6d78-4df4-afbf-1a9f0672d790","Yazılım Mimarisi","yazilim-mimarisi","Yazılım mimarisi desenleri ve en iyi pratikler","i-lucide-network","#9C27B0",[],"2026-03-19T06:22:06.0951316","2026-08-20T18:48:49.729034",{"categoryId":41,"name":42,"slug":43,"description":44,"icon":45,"color":46,"displayOrder":47,"articleCount":11,"parentCategoryId":13,"parentCategoryName":13,"subCategories":48,"isActive":15,"isDeleted":16,"createDate":49,"updatedDate":50,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"e0735b8e-d777-4a36-92d5-99be044a09eb","Yapay Zeka","yapay-zeka","AI, ML ve derin öğrenme konularinda makaleler","i-lucide-brain","#8B5CF6",3,[],"2026-03-03T08:21:13.9334821","2026-08-20T11:16:13.1400074",{"categoryId":52,"name":53,"slug":54,"description":55,"icon":56,"color":57,"displayOrder":58,"articleCount":11,"parentCategoryId":13,"parentCategoryName":13,"subCategories":59,"isActive":15,"isDeleted":16,"createDate":60,"updatedDate":61,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"bf107cba-1ea4-4e09-9e30-a60b696c80cd","Backend Geliştirme","backend-gelistirme","Backend teknolojileri ve API geliştirme","i-lucide-server","#4CAF50",4,[],"2026-03-19T06:22:06.1172387","2026-08-20T18:48:50.373417",{"categoryId":63,"name":64,"slug":65,"description":66,"icon":67,"color":68,"displayOrder":69,"articleCount":11,"parentCategoryId":13,"parentCategoryName":13,"subCategories":70,"isActive":15,"isDeleted":16,"createDate":71,"updatedDate":13,"deletedDate":13,"createdUserId":19,"updatedUserId":13,"deletedUserId":13},"e43829ce-9504-4ccf-bbd6-9861953242aa","DevOps","devops","CI/CD, Docker, Kubernetes ve bulut servisleri","i-lucide-cloud","#EF4444",5,[],"2026-03-03T08:21:14.0194291",{"categoryId":73,"name":74,"slug":75,"description":76,"icon":77,"color":78,"displayOrder":79,"articleCount":80,"parentCategoryId":13,"parentCategoryName":13,"subCategories":81,"isActive":15,"isDeleted":16,"createDate":82,"updatedDate":83,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"78e05871-4b6d-41bb-aed7-eda0f1622ef0","Çocuk Gelişimi","cocuk-gelisimi","Çocuk gelişimi, dijital içerik ve ebeveynlik üzerine yazılar.","i-lucide-sprout","#22C55E",20,11,[],"2026-06-17T10:58:08.1185023","2026-08-20T18:48:51.0259664",{"categoryId":85,"name":86,"slug":87,"description":88,"icon":89,"color":90,"displayOrder":79,"articleCount":47,"parentCategoryId":13,"parentCategoryName":13,"subCategories":91,"isActive":15,"isDeleted":16,"createDate":92,"updatedDate":93,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"e1232012-c57e-4112-944e-f165cad271a2","Okul Öncesi Eğitim","okul-oncesi-egitim","Okul öncesi çocuklar için sayılar, harfler, renkler ve şekiller — BapatiKids eğitim içerikleri.","i-lucide-graduation-cap","#3B82F6",[],"2026-06-23T17:52:15.8211976","2026-08-20T18:48:51.3560763",{"categoryId":95,"name":96,"slug":97,"description":98,"icon":99,"color":46,"displayOrder":100,"articleCount":11,"parentCategoryId":13,"parentCategoryName":13,"subCategories":101,"isActive":15,"isDeleted":16,"createDate":102,"updatedDate":103,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"57debdec-84b5-40c9-8d85-299fed503702","Bapati Kids Müzik & Şarkılar","bapati-kids-muzik-sarkilar","BapatiKids çocuk şarkıları ve müzik içerikleri.","i-lucide-music",21,[],"2026-06-23T17:52:16.3956393","2026-08-20T18:48:51.7183087",{"categoryId":105,"name":106,"slug":107,"description":108,"icon":109,"color":110,"displayOrder":111,"articleCount":12,"parentCategoryId":13,"parentCategoryName":13,"subCategories":112,"isActive":15,"isDeleted":16,"createDate":113,"updatedDate":114,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"330349ce-cef4-4dff-96db-294a9b666200","Finans","finans","Finans, yatırım ve birikim üzerine genel bilgilendirme yazıları.","i-lucide-trending-up","#14B8A6",30,[],"2026-06-17T13:36:45.3851222","2026-08-20T18:48:52.0482284",[],{"items":117,"totalCount":204},[118,133,149,161,174,191],{"articleId":119,"title":120,"slug":121,"content":122,"summary":123,"featuredImage":124,"metaTitle":120,"metaDescription":125,"metaKeywords":126,"isPublished":15,"publishedAt":127,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":129,"authorId":19,"categoryId":21,"categoryName":22,"tags":130,"isActive":15,"isDeleted":16,"createDate":131,"updatedDate":132,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"e85c02fe-7c3c-4a3e-8213-1fbbe6e31fdf","Big-O Karmaşıklığı Nedir? Algoritma Performansını Anlamak","big-o-karmasikligi-nedir-algoritma-performansi","\u003Ch2>Big-O Ne Söyler, Ne Söylemez?\u003C/h2>\n\u003Cp>Big-O gösterimi bir kodun kaç saniye süreceğini söylemez. Söylediği şey, veri miktarı arttıkça çalışma süresinin nasıl büyüyeceğidir.\u003C/p>\n\u003Cp>Bu ayrım önemlidir: küçük veri kümelerinde O(n²) bir çözüm, O(n log n) bir çözümden daha hızlı çalışabilir. Fark, veri büyüdükçe ortaya çıkar. Yani Big-O bir ölçüm değil, bir \u003Cstrong>eğilim tahminidir\u003C/strong>. Doğru soru \"şu an ne kadar sürüyor\" değil, \"veri on kat artarsa ne olur\" sorusudur.\u003C/p>\n\u003Cp>Aynı işi yapan beş farklı yaklaşımın, veri büyüdükçe nereye gittiğini tek tabloda görmek meseleyi kapatır:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Karmaşıklık\u003C/th>\u003Cth>n = 10\u003C/th>\u003Cth>n = 1.000\u003C/th>\u003Cth>n = 1.000.000\u003C/th>\u003Cth>Tipik örnek\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>O(1)\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>Sözlükten anahtarla okuma\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>O(log n)\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>10\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>İkili arama, index taraması\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>O(n)\u003C/td>\u003Ctd>10\u003C/td>\u003Ctd>1.000\u003C/td>\u003Ctd>1.000.000\u003C/td>\u003Ctd>Listeyi bir kez dolaşmak\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>O(n log n)\u003C/td>\u003Ctd>33\u003C/td>\u003Ctd>10.000\u003C/td>\u003Ctd>20.000.000\u003C/td>\u003Ctd>Verimli sıralama\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>O(n²)\u003C/td>\u003Ctd>100\u003C/td>\u003Ctd>1.000.000\u003C/td>\u003Ctd>1.000.000.000.000\u003C/td>\u003Ctd>İç içe iki döngü\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Son satıra dikkat edin: bir milyon kayıtta O(n²), O(n)'e göre \u003Cstrong>bir milyon kat\u003C/strong> daha fazla iş yapar. Bu, \"biraz yavaş\" değil \"hiç bitmiyor\" demektir.\u003C/p>\n\n\u003Ch2>O(1): Veri Ne Kadar Büyürse Büyüsün\u003C/h2>\n\u003Cp>Sabit zamanlı işlemler, veri miktarından etkilenmez. Bir dizinin belirli bir indisindeki elemana erişmek buna örnektir. Hash tabanlı yapılarda anahtarla arama da ortalama durumda O(1) kabul edilir; sözlük ve küme yapılarını bu kadar kullanışlı yapan özellik budur.\u003C/p>\n\u003Cpre>\u003Ccode># n ne olursa olsun tek adım\nkullanicilar = {\"a1\": \"Ayşe\", \"b2\": \"Mehmet\", \"c3\": \"Zeynep\"}\nad = kullanicilar[\"b2\"]        # O(1)\n\nliste = [\"Ayşe\", \"Mehmet\", \"Zeynep\"]\nad = liste[1]                  # O(1)\u003C/code>\u003C/pre>\n\u003Cp>\"Ortalama durumda\" ifadesi önemli: hash çakışması yoğunlaşırsa bu erişim kötü senaryoda O(n)'e kadar düşebilir. Pratikte standart kütüphanelerin sözlük uygulamaları bunu sizin yerinize yönetir, ama kendi hash fonksiyonunuzu yazıyorsanız akılda tutulmalıdır.\u003C/p>\n\n\u003Ch2>O(log n): Her Adımda Yarıya Bölmek\u003C/h2>\n\u003Cp>Logaritmik karmaşıklık, her adımda arama alanını ikiye bölen algoritmalarda karşımıza çıkar. İkili arama klasik örnektir.\u003C/p>\n\u003Cpre>\u003Ccode>def ikili_arama(sirali_dizi, hedef):\n    \"\"\"Ön koşul: dizi SIRALI olmalı. Sıralı değilse sonuç anlamsızdır.\"\"\"\n    alt, ust = 0, len(sirali_dizi) - 1\n    adim = 0\n    while alt \u003C= ust:\n        adim += 1\n        orta = (alt + ust) // 2          # her turda alan yarıya iner\n        if sirali_dizi[orta] == hedef:\n            return orta, adim\n        if sirali_dizi[orta] \u003C hedef:\n            alt = orta + 1\n        else:\n            ust = orta - 1\n    return -1, adim\n\ndizi = list(range(1_000_000))\nprint(ikili_arama(dizi, 999_999))   # (999999, 20) — bir milyon eleman, 20 adım\u003C/code>\u003C/pre>\n\u003Cp>Bir milyon elemanlı sıralı bir dizide aranan değeri bulmak yaklaşık yirmi adım sürer. Aynı işi baştan sona tarayarak yapmak bir milyon adım demektir. Veritabanı index'lerinin sorguları hızlandırmasının arkasındaki mantık da budur — ve aynı sebeple \u003Cstrong>index'siz bir sütunda arama, tablo büyüdükçe doğrusal olarak yavaşlar\u003C/strong>.\u003C/p>\n\n\u003Ch2>O(n): Doğrusal Artış\u003C/h2>\n\u003Cp>Bir koleksiyonu baştan sona bir kez dolaşan her işlem doğrusaldır. Veri iki katına çıktığında süre de yaklaşık iki katına çıkar. Çoğu günlük işlem bu sınıfa girer ve pratikte gayet kabul edilebilirdir.\u003C/p>\n\u003Cp>Dikkat edilmesi gereken nokta, doğrusal bir işlemin başka bir doğrusal işlemin içine yerleştirilmesidir; o noktada karmaşıklık sessizce kareselleşir. Ve bu, çoğu zaman iç içe iki \u003Ccode>for\u003C/code> gibi görünmez:\u003C/p>\n\u003Cpre>\u003Ccode># Görünürde tek döngü — ama içindeki `in` araması listede O(n)\ndef ortak_olanlar(a, b):\n    return [x for x in a if x in b]      # O(n × m) — gizli kareselleşme\n\n# Aynı iş, küme ile: `in` araması O(1)'e iner\ndef ortak_olanlar_hizli(a, b):\n    b_kume = set(b)                      # O(m), bir kez\n    return [x for x in a if x in b_kume] # O(n)\u003C/code>\u003C/pre>\n\u003Cp>İki liste de 10.000 elemanlıysa üstteki 100 milyon karşılaştırma yapar, alttaki 20 bin. Kod neredeyse aynı görünür; fark yalnızca bir \u003Ccode>set()\u003C/code> çağrısıdır.\u003C/p>\n\n\u003Ch2>O(n²): Sessiz Performans Katili\u003C/h2>\n\u003Cp>İç içe iki döngü, çoğu zaman farkında olmadan yazılır. Bin elemanlı bir liste için bu bir milyon işlem demektir; on bin eleman için yüz milyon. Uygulamanın test ortamında sorunsuz çalışıp üretimde yavaşlamasının en yaygın nedeni budur: \u003Cstrong>test verisi küçüktür, gerçek veri değildir.\u003C/strong>\u003C/p>\n\u003Cp>Aynı tuzağın en pahalı hâli veritabanında görülür ve adı \u003Cem>N+1 sorgu\u003C/em> problemidir:\u003C/p>\n\u003Cpre>\u003Ccode>// YANLIŞ: 1 sorgu liste için, her sipariş için 1 sorgu daha\nvar siparisler = db.Siparisler.ToList();          // 1 sorgu\nforeach (var s in siparisler)\n    Console.WriteLine(s.Musteri.Ad);              // her turda ayrı sorgu!\n// 1.000 sipariş -> 1.001 veritabanı gidiş dönüşü\n\n// DOĞRU: ilişkili veriyi tek seferde getir\nvar siparisler = db.Siparisler\n                   .Include(s =&gt; s.Musteri)\n                   .ToList();                      // 1 sorgu\nforeach (var s in siparisler)\n    Console.WriteLine(s.Musteri.Ad);               // ek sorgu yok\u003C/code>\u003C/pre>\n\u003Cp>Buradaki maliyet CPU değil \u003Cstrong>ağ gecikmesidir\u003C/strong>. Her sorgu 2 ms sürse bile 1.000 sorgu 2 saniye eder; sayfa açılmaz. Çözüm genellikle iç döngüyü bir sözlük araması ya da tek bir toplu sorgu ile değiştirmektir.\u003C/p>\n\n\u003Ch2>Bellek de Bir Karmaşıklıktır\u003C/h2>\n\u003Cp>Big-O yalnızca süre için değil, bellek için de kullanılır. Bazen ikisi arasında bilinçli bir takas yaparsınız: yukarıdaki \u003Ccode>set(b)\u003C/code> örneği O(m) ek bellek harcayarak süreyi O(n×m)'den O(n)'e indirir.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Yaklaşım\u003C/th>\u003Cth>Süre\u003C/th>\u003Cth>Ek bellek\u003C/th>\u003Cth>Ne zaman\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Doğrudan tarama\u003C/td>\u003Ctd>O(n×m)\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>Veri küçük, bellek kısıtlı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Küme/sözlük kurma\u003C/td>\u003Ctd>O(n+m)\u003C/td>\u003Ctd>O(m)\u003C/td>\u003Ctd>Veri büyük — varsayılan tercih\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Önce sıralayıp ikili arama\u003C/td>\u003Ctd>O(m log m + n log m)\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>Sıralı erişim de gerekiyorsa\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Bir milyonluk veride \"biraz bellek harcayıp çok zaman kazanmak\" neredeyse her zaman doğru taraftır; bunun istisnası gömülü sistemler gibi belleğin gerçekten kıt olduğu ortamlardır.\u003C/p>\n\n\u003Ch2>Amortize Edilmiş Karmaşıklık: Ortalama Değil, Yayılmış\u003C/h2>\n\u003Cp>Bazı işlemler çoğu zaman ucuzdur ama arada bir pahalıya patlar. Dinamik dizinin sonuna eleman eklemek buna örnektir: yer varken O(1)'dir, dolduğunda tüm dizi daha büyük bir alana kopyalanır ve o tek işlem O(n) olur.\u003C/p>\n\u003Cp>Buna rağmen listeye ekleme \"O(1) amortize\" sayılır. Sebebi şu: kapasite her seferinde ikiye katlandığı için pahalı kopyalama giderek seyrekleşir; n ekleme işleminin toplam maliyeti O(n)'de kalır, yani \u003Cstrong>ekleme başına ortalama sabit\u003C/strong>.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>İşlem\u003C/th>\u003Cth>Tipik durum\u003C/th>\u003Cth>Kötü durum\u003C/th>\u003Cth>Amortize\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Listeye sona ekleme\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>O(n) — yeniden boyutlandırma\u003C/td>\u003Ctd>O(1)\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Sözlüğe ekleme\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>O(n) — yeniden hash'leme\u003C/td>\u003Ctd>O(1)\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Listenin başına ekleme\u003C/td>\u003Ctd>O(n)\u003C/td>\u003Ctd>O(n)\u003C/td>\u003Ctd>O(n)\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Bu ayrım gerçek zamanlı sistemlerde önemlidir: amortize O(1) \"her işlem hızlı\" demek değil, \"uzun vadede ortalama hızlı\" demektir. Her isteğin sabit sürede bitmesi gereken bir yerde, o arada bir gelen O(n) tırmanışı gecikme grafiğinde diken olarak görünür.\u003C/p>\n\u003Cp>Bilinen bir boyut varsa kapasiteyi baştan ayırmak bu dikenleri tamamen ortadan kaldırır:\u003C/p>\n\u003Cpre>\u003Ccode>// 100.000 elemanlık büyümede ~17 kez yeniden boyutlandırma yapar\nvar liste = new List&lt;int&gt;();\n\n// Kapasite baştan ayrıldı: hiç yeniden boyutlandırma yok\nvar liste = new List&lt;int&gt;(100_000);\u003C/code>\u003C/pre>\n\n\u003Ch2>Doğru Veri Yapısı, Yarısı Çözülmüş Problem\u003C/h2>\n\u003Cp>Karmaşıklık çoğu zaman algoritmadan değil, seçilen veri yapısından gelir. Listede arama yapmak doğrusaldır; sözlükte arama yapmak sabittir.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>İşlem\u003C/th>\u003Cth>Liste / Dizi\u003C/th>\u003Cth>Sözlük (hash)\u003C/th>\u003Cth>Küme\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>İndisle erişim\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Değer arama\u003C/td>\u003Ctd>O(n)\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>O(1)\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Sona ekleme\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>O(1)\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Başa ekleme\u003C/td>\u003Ctd>O(n)\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Silme (değere göre)\u003C/td>\u003Ctd>O(n)\u003C/td>\u003Ctd>O(1)\u003C/td>\u003Ctd>O(1)\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Sıra korunur mu\u003C/td>\u003Ctd>Evet\u003C/td>\u003Ctd>Ekleme sırası\u003C/td>\u003Ctd>Hayır\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Sık arama yapacaksanız sözlük, sıralı erişim gerekiyorsa liste, benzersizlik gerekiyorsa küme uygun seçimdir. Bu seçimleri baştan doğru yapmak, sonradan yapılacak optimizasyon çalışmalarının çoğunu gereksiz kılar.\u003C/p>\n\n\u003Ch2>Ne Zaman Önemsemeli?\u003C/h2>\n\u003Cp>Her kod parçası için karmaşıklık analizi yapmak gereksiz bir yüktür. Yüz elemanlık bir liste üzerinde O(n²) çalışmak kimseyi rahatsız etmez. Asıl dikkat edilmesi gereken yerler, \u003Cstrong>veri miktarının zamanla büyüyeceği\u003C/strong> kısımlardır: kullanıcı listeleri, log kayıtları, sipariş geçmişi.\u003C/p>\n\u003Cp>Pratik yaklaşım şudur: önce çalışan ve okunabilir kodu yaz, ölç, sonra yalnızca gerçekten darboğaz olan yeri iyileştir. Ölçmek de tahmin etmekten kolaydır:\u003C/p>\n\u003Cpre>\u003Ccode>import time\n\ndef sure_olc(fonksiyon, *args):\n    bas = time.perf_counter()\n    sonuc = fonksiyon(*args)\n    return sonuc, (time.perf_counter() - bas) * 1000   # ms\n\n# Aynı işi iki boyutta ölç: süre 10 kat mı, 100 kat mı arttı?\n# 10 kat  -> O(n)      · sorun yok\n# 100 kat -> O(n²)     · veri büyüdükçe patlayacak\u003C/code>\u003C/pre>\n\u003Cp>Bu tek ölçüm, karmaşıklık analizi yapmadan da sınıfı size söyler: veriyi on katına çıkarın, süreye bakın. Süre on katına çıktıysa doğrusalsınız; yüz katına çıktıysa kareselsiniz ve o kod parçası er ya da geç sorun çıkaracaktır.\u003C/p>\n\n\u003Chr>\n\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Big-O'yu görsel örneklerle anlattığımız bölüm, 'Her Yazılımcının Bilmesi Gerekenler' serimizin bir parçası; seride veri yapılarından eşzamanlılığa kadar 15 temel konu yer alıyor.\u003C/p>\n\u003Cp>\u003Ca href='/videos/big-o-karmasikligi-o1-olog-n-on-on-gorerek-ogren'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/a7UI5Ga-kzw' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech' target='_blank' rel='noopener'>Kanala abone ol\u003C/a>\u003C/p>\u003Chr>\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Bilgisayarların içinde neler olup bittiğini anlattığımız video, performans konusuna farklı bir açıdan bakıyor.\u003C/p>\u003Cp>\u003Ca href='/videos/bilmedigin-10-bilgisayar-gercegi-yazilimcilar-bile-sasiriyor'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/wSv0E_h3Myg' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech?sub_confirmation=1' target='_blank' rel='noopener'>Bapati kanalına abone ol\u003C/a>\u003C/p>","Big-O gösterimi nedir, bir algoritmanın performansı nasıl değerlendirilir? Karmaşıklık sınıflarını gerçek kod örnekleriyle açıklıyoruz.","https://img.youtube.com/vi/a7UI5Ga-kzw/hqdefault.jpg","Big-O gösterimi nedir, algoritma performansı nasıl ölçülür? Karmaşıklık sınıfları, gerçek kod örnekleri ve pratikte asıl neyin önemli olduğu bir arada.","big-o, algoritma karmaşıklığı, zaman karmaşıklığı, performans, veri yapıları, o(n), o(log n), yazılım geliştirme, algoritma, optimizasyon","2026-07-27T22:02:00",0,6,[],"2026-07-27T19:02:02.5913418","2026-08-23T13:45:17.1567973",{"articleId":134,"title":135,"slug":136,"content":137,"summary":138,"featuredImage":139,"metaTitle":135,"metaDescription":140,"metaKeywords":141,"isPublished":15,"publishedAt":127,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":129,"authorId":19,"categoryId":63,"categoryName":64,"tags":142,"isActive":15,"isDeleted":16,"createDate":147,"updatedDate":148,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"d6cacc1b-e7f3-428a-b868-9cf94b01f531","Docker Nedir? Konteyner, Image ve Dockerfile Temelleri","docker-nedir-konteyner-image-dockerfile-temelleri","\u003Ch2>Çözdüğü Problem: \"Bende Çalışıyordu\"\u003C/h2>\n\u003Cp>Bir uygulamanın geliştirici makinesinde çalışıp sunucuda çalışmaması, yazılım dünyasının en eski sürtüşmelerinden biridir. Sebep genellikle sürüm, bağımlılık ya da yapılandırma farkıdır — makinede kurulu olan ama kimsenin farkında olmadığı bir kütüphane, farklı bir çalışma zamanı sürümü, eksik bir ortam değişkeni.\u003C/p>\n\u003Cp>Docker bu problemi kökten ele alır: uygulamayı yalnızca kodla değil, çalışması için gereken her şeyle birlikte paketler. Sonuç olarak aynı paket, geliştiricinin dizüstünde de, test sunucusunda da, bulutta da aynı şekilde davranır.\u003C/p>\n\n\u003Ch2>Konteyner ve Sanal Makine Aynı Şey Değil\u003C/h2>\n\u003Cp>Sanal makine, kendi işletim sistemi çekirdeğini taşır. Konteyner ise ana makinenin çekirdeğini paylaşır; yalnızca uygulama ve bağımlılıkları izole edilir.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>\u003C/th>\u003Cth>Sanal makine\u003C/th>\u003Cth>Konteyner\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Kendi çekirdeği\u003C/td>\u003Ctd>Var\u003C/td>\u003Ctd>Yok — ana makineyi paylaşır\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Tipik boyut\u003C/td>\u003Ctd>GB'lar\u003C/td>\u003Ctd>MB'lar\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Başlangıç süresi\u003C/td>\u003Ctd>Dakikalar\u003C/td>\u003Ctd>Saniyeler\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Aynı sunucuda kaç tane\u003C/td>\u003Ctd>Onlarca\u003C/td>\u003Ctd>Yüzlerce\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>İzolasyon sınırı\u003C/td>\u003Ctd>Donanım düzeyi — keskin\u003C/td>\u003Ctd>Süreç düzeyi — daha yumuşak\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Farklı işletim sistemi\u003C/td>\u003Ctd>Çalıştırabilir\u003C/td>\u003Ctd>Çekirdek uyumu gerekir\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Konteynerler çekirdek düzeyinde tam izolasyon sunmaz. Güvenlik sınırı sanal makine kadar keskin değildir; \u003Cstrong>güvenilmeyen kodu çalıştırıyorsanız\u003C/strong> bu ayrım mimari kararlarda belirleyici olur.\u003C/p>\n\n\u003Ch2>Image ve Container İlişkisi\u003C/h2>\n\u003Cp>Image, çalıştırılabilir bir şablondur: salt okunur, değişmez bir paket. Container ise o image'ın çalışan bir örneğidir. Sınıf ve nesne ilişkisine benzetmek, kavramı oturtmak için pratik bir yoldur.\u003C/p>\n\u003Cpre>\u003Ccode># Image indir (şablon)\ndocker pull mcr.microsoft.com/dotnet/aspnet:8.0\n\n# Aynı image'dan üç bağımsız container\ndocker run -d --name api-1 -p 5001:8080 bapati-api:1.4.0\ndocker run -d --name api-2 -p 5002:8080 bapati-api:1.4.0\ndocker run -d --name api-3 -p 5003:8080 bapati-api:1.4.0\n\n# Ne çalışıyor, ne kadar yer kaplıyor?\ndocker ps\ndocker image ls\ndocker stats --no-stream\u003C/code>\u003C/pre>\n\u003Cp>Her container kendi yazılabilir katmanına sahiptir ve birbirinden bağımsız çalışır. \u003Ccode>api-1\u003C/code> içinde bir dosya oluşturmanız \u003Ccode>api-2\u003C/code>'yi etkilemez — ve \u003Ccode>api-1\u003C/code> silindiğinde o dosya da gider.\u003C/p>\n\n\u003Ch2>Dockerfile ve Katman Mantığı\u003C/h2>\n\u003Cp>Dockerfile, image'ın nasıl oluşturulacağını anlatan tarif dosyasıdır. Her satır image'a yeni bir katman ekler ve \u003Cstrong>katmanlar önbelleğe alınır\u003C/strong>. Bu nedenle nadiren değişen adımları üste, sık değişen adımları alta yazmak build sürelerini belirgin biçimde kısaltır.\u003C/p>\n\u003Cpre>\u003Ccode># --- 1. AŞAMA: derleme ---\nFROM mcr.microsoft.com/dotnet/sdk:8.0 AS derleme\nWORKDIR /kaynak\n\n# Önce SADECE proje dosyaları: bağımlılıklar nadiren değişir,\n# bu katman kaynak kod değiştiğinde önbellekten gelir.\nCOPY *.sln .\nCOPY BapatiApi.API/*.csproj        BapatiApi.API/\nCOPY BapatiApi.Application/*.csproj BapatiApi.Application/\nRUN dotnet restore\n\n# Kaynak kod en sona: her commit'te değişen tek katman bu olsun\nCOPY . .\nRUN dotnet publish BapatiApi.API/BapatiApi.API.csproj -c Release -o /cikti\n\n# --- 2. AŞAMA: çalışma ---\n# SDK (~800 MB) nihai imaja girmez, yalnızca runtime (~220 MB) kalır\nFROM mcr.microsoft.com/dotnet/aspnet:8.0\nWORKDIR /uygulama\nCOPY --from=derleme /cikti .\n\n# root olarak çalıştırma\nRUN adduser --disabled-password --gecos \"\" bapati\nUSER bapati\n\nEXPOSE 8080\nENTRYPOINT [\"dotnet\", \"BapatiApi.API.dll\"]\u003C/code>\u003C/pre>\n\u003Cp>Bu dosyadaki üç karar, üç ayrı sorunu çözüyor:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Karar\u003C/th>\u003Cth>Kazanç\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Ccode>.csproj\u003C/code>'ları önce kopyalamak\u003C/td>\u003Ctd>Kod değiştiğinde \u003Ccode>restore\u003C/code> yeniden çalışmaz — build dakikalardan saniyelere iner\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Çok aşamalı build\u003C/td>\u003Ctd>Derleme araçları nihai imaja girmez — boyut ~3 kat küçülür\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>USER bapati\u003C/code>\u003C/td>\u003Ctd>Container ele geçirilse bile root yetkisi yok\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Bir de \u003Ccode>.dockerignore\u003C/code> dosyası şart: onsuz \u003Ccode>COPY . .\u003C/code> satırı \u003Ccode>node_modules\u003C/code>, \u003Ccode>bin\u003C/code>, \u003Ccode>obj\u003C/code> ve \u003Ccode>.git\u003C/code> klasörlerini de build bağlamına taşır ve her build'i yavaşlatır.\u003C/p>\n\u003Cpre>\u003Ccode># .dockerignore\n**/bin\n**/obj\n**/node_modules\n**/.git\n**/.vs\n**/*.user\n**/appsettings.Development.json\u003C/code>\u003C/pre>\n\n\u003Ch2>Veri Nerede Durur? Volume Meselesi\u003C/h2>\n\u003Cp>Container silindiğinde içindeki yazılabilir katman da silinir. Veritabanı verisini container içinde tutmak bu nedenle kalıcı bir çözüm değildir.\u003C/p>\n\u003Cpre>\u003Ccode># YANLIŞ: container silindiğinde veri de gider\ndocker run -d --name db postgres:16\n\n# DOĞRU: veri adlandırılmış bir volume'da, container'dan bağımsız\ndocker volume create bapati-db-veri\ndocker run -d --name db \\\n  -v bapati-db-veri:/var/lib/postgresql/data \\\n  -e POSTGRES_PASSWORD_FILE=/run/secrets/db_sifre \\\n  postgres:16\n\n# Container'ı sil, yeniden oluştur — veri yerinde\ndocker rm -f db\ndocker run -d --name db -v bapati-db-veri:/var/lib/postgresql/data postgres:16\u003C/code>\u003C/pre>\n\u003Cp>Kalıcı olması gereken her şeyin volume üzerinde tutulması, en sık atlanan ama en pahalıya mal olan kurallardan biridir. Volume'un iki türü vardır: \u003Cem>adlandırılmış volume\u003C/em> (Docker yönetir, üretim için uygundur) ve \u003Cem>bind mount\u003C/em> (ana makinedeki bir klasörü bağlar, geliştirmede kod paylaşmak için pratiktir).\u003C/p>\n\n\u003Ch2>Docker Compose ile Çoklu Servis\u003C/h2>\n\u003Cp>Gerçek uygulamalar tek konteynerden oluşmaz: API, veritabanı, önbellek ve belki bir mesaj kuyruğu bir arada çalışır. Compose, bu servisleri tek bir yapılandırma dosyasında tanımlamanızı ve hepsini tek komutla ayağa kaldırmanızı sağlar.\u003C/p>\n\u003Cpre>\u003Ccode>services:\n  api:\n    build: .\n    ports:\n      - \"5000:8080\"\n    environment:\n      ConnectionStrings__Varsayilan: \"Host=db;Database=bapati;Username=bapati\"\n    depends_on:\n      db:\n        condition: service_healthy      # sadece \"başladı\" değil, \"hazır\"\n    restart: unless-stopped\n\n  db:\n    image: postgres:16\n    volumes:\n      - db-veri:/var/lib/postgresql/data\n    environment:\n      POSTGRES_DB: bapati\n      POSTGRES_USER: bapati\n      POSTGRES_PASSWORD: ${DB_SIFRE}    # .env dosyasından, dosyaya yazılmaz\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U bapati\"]\n      interval: 5s\n      retries: 5\n\nvolumes:\n  db-veri:\u003C/code>\u003C/pre>\n\u003Cp>Dikkat edilecek iki nokta var. Birincisi: API, veritabanına \u003Ccode>localhost\u003C/code> ile değil \u003Cstrong>servis adıyla\u003C/strong> (\u003Ccode>Host=db\u003C/code>) bağlanır — Compose her servis için ağ içinde bir ad çözümlemesi kurar. İkincisi: \u003Ccode>depends_on\u003C/code> tek başına yalnızca \"başlatma sırasını\" belirler; veritabanının bağlantı kabul etmeye \u003Cem>hazır\u003C/em> olmasını beklemek için \u003Ccode>healthcheck\u003C/code> gerekir. Bu ayrım, \"API açılışta veritabanına bağlanamıyor ama yeniden başlatınca düzeliyor\" sorununun tam sebebidir.\u003C/p>\n\u003Cp>Yeni bir geliştiricinin projeye katıldığı ilk gün ortamı dakikalar içinde kurabilmesi, çoğu ekipte Compose'un en somut faydasıdır:\u003C/p>\n\u003Cpre>\u003Ccode>git clone https://github.com/bapati/api.git\ncd api\ncp .env.ornek .env\ndocker compose up -d          # hepsi ayakta\u003C/code>\u003C/pre>\n\n\u003Ch2>Yaygın Hatalar\u003C/h2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Hata\u003C/th>\u003Cth>Sonucu\u003C/th>\u003Cth>Doğrusu\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Parolayı Dockerfile'a yazmak\u003C/td>\u003Ctd>Katmanlarda kalıcı olur, imajı alan herkes görür\u003C/td>\u003Ctd>Ortam değişkeni ya da secret\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>latest\u003C/code> etiketi\u003C/td>\u003Ctd>Bugün çalışan yapı yarın farklı sürümle gelir\u003C/td>\u003Ctd>Sürümü sabitle: \u003Ccode>postgres:16.2\u003C/code>\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>root olarak çalıştırmak\u003C/td>\u003Ctd>Container ele geçerse yetki tam\u003C/td>\u003Ctd>\u003Ccode>USER\u003C/code> ile yetkisiz kullanıcı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Container'a SSH ile bağlanmak\u003C/td>\u003Ctd>Değişiklik kayıt dışı kalır, yeniden üretilemez\u003C/td>\u003Ctd>Değişikliği Dockerfile'a yaz\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Log'u dosyaya yazmak\u003C/td>\u003Ctd>Container silinince log da gider\u003C/td>\u003Ctd>\u003Ccode>stdout\u003C/code>'a yaz, Docker toplasın\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>.dockerignore\u003C/code> yok\u003C/td>\u003Ctd>Build bağlamı yüzlerce MB olur\u003C/td>\u003Ctd>bin, obj, node_modules hariç\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Sağlık kontrolü yok\u003C/td>\u003Ctd>Ölü container ayakta görünür\u003C/td>\u003Ctd>\u003Ccode>HEALTHCHECK\u003C/code> tanımla\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Parola konusunda sık yapılan bir incelik hatası da şudur: bir katmanda dosya oluşturup sonraki katmanda silmek onu \u003Cstrong>imajdan silmez\u003C/strong>. Katmanlar yığın gibi birikir; silinen dosya alt katmanda durmaya devam eder ve \u003Ccode>docker history\u003C/code> ile görülebilir.\u003C/p>\n\n\u003Ch2>Üretime Çıkarken: Boyut, Sağlık ve Tarama\u003C/h2>\n\u003Cp>Geliştirmede çalışan bir yapılandırma üretim için yeterli değildir. Üç şey eklenir: imaj küçültme, sağlık kontrolü ve güvenlik taraması.\u003C/p>\n\u003Cp>İmaj boyutu yalnızca disk meselesi değildir — her dağıtımda ağdan indirilir, her ölçekleme adımında yeniden çekilir. Temel imaj seçimi tek başına büyük fark yaratır:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Temel imaj\u003C/th>\u003Cth>Yaklaşık boyut\u003C/th>\u003Cth>Not\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Ccode>dotnet/sdk:8.0\u003C/code>\u003C/td>\u003Ctd>~800 MB\u003C/td>\u003Ctd>Yalnızca derleme aşamasında\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>dotnet/aspnet:8.0\u003C/code>\u003C/td>\u003Ctd>~220 MB\u003C/td>\u003Ctd>Standart çalışma imajı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>dotnet/aspnet:8.0-alpine\u003C/code>\u003C/td>\u003Ctd>~110 MB\u003C/td>\u003Ctd>Daha küçük, farklı libc\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>node:20\u003C/code>\u003C/td>\u003Ctd>~1,1 GB\u003C/td>\u003Ctd>Tam araç zinciri\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>node:20-alpine\u003C/code>\u003C/td>\u003Ctd>~140 MB\u003C/td>\u003Ctd>Yerel modüllerde derleme gerekebilir\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Sağlık kontrolü ise orkestratörün \"bu container gerçekten hizmet veriyor mu\" sorusunu cevaplamasını sağlar. Süreç ayakta ama uygulama kilitlenmişse, sağlık kontrolü olmadan hiçbir şey fark etmez:\u003C/p>\n\u003Cpre>\u003Ccode>HEALTHCHECK --interval=30s --timeout=3s --start-period=20s --retries=3   CMD wget -qO- http://localhost:8080/saglik || exit 1\u003C/code>\u003C/pre>\n\u003Cp>Son olarak imajı yayınlamadan önce taramak gerekir. Kendi kodunuz temiz olsa bile temel imajdaki bir kütüphane bilinen bir açık taşıyor olabilir:\u003C/p>\n\u003Cpre>\u003Ccode># Bilinen güvenlik açıklarını tara\ndocker scout cves bapati-api:1.4.0\n\n# Katman katman ne kadar yer kaplıyor, hangi adım şişiriyor?\ndocker history bapati-api:1.4.0 --no-trunc\u003C/code>\u003C/pre>\n\u003Cp>Bu üç adımı dağıtım hattına (CI) koymak, sorunları üretimde değil derleme aşamasında yakalamayı sağlar.\u003C/p>\n\n\u003Ch2>Konteynerin Zihniyeti\u003C/h2>\n\u003Cp>Docker'ı verimli kullanmanın anahtarı bir araç değil bir yaklaşım: container'lar \u003Cstrong>tek iş yapan ve gerektiğinde atılabilen\u003C/strong> birimlerdir. Bir container'ı silip yeniden oluşturmak, onu tamir etmekten daha ucuz olmalıdır.\u003C/p>\n\u003Cp>Bu yaklaşım üç pratik kurala iner: durumu container dışında tut (volume ya da veritabanı), yapılandırmayı ortam değişkeniyle ver, ve her değişikliği imaja yaz. Bu üçü sağlandığında ölçekleme, güncelleme ve geri alma işlemlerinin hepsi tek komuta iner.\u003C/p>\n\n\u003Ch2>Geliştirme Ortamında Docker\u003C/h2>\u003Cp>Docker’ın en hızlı karşılık verdiği yer üretim değil, geliştirme ortamıdır. Bir projeye yeni katılan geliştiricinin veritabanı, önbellek ve mesaj kuyruğu kurmakla geçirdiği ilk gün, hazır bir yapılandırma dosyasıyla birkaç dakikaya iner.\u003C/p>\u003Cp>Bunun ötesinde bir fayda daha var: \u003Cstrong>sürüm çakışmalarının ortadan kalkması\u003C/strong>. Aynı makinede iki farklı projenin iki farklı veritabanı sürümüne ihtiyaç duyması, konteyner olmadan zahmetli bir iştir; konteynerle her proje kendi sürümünü taşır.\u003C/p>\u003Cp>Geliştirme ortamında sık kullanılan bir kolaylık da kaynak kodun konteynere bağlanmasıdır. Böylece kod değişikliği için imajın yeniden oluşturulması gerekmez; dosya değişir, uygulama yeniden başlar. Bu düzen, üretimde tercih edilmez ama geliştirmede döngüyü belirgin biçimde hızlandırır.\u003C/p>\u003Chr>\n\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Docker'ı uygulamalı anlattığımız bölüm 'Her Yazılımcının Bilmesi Gerekenler' serimizde; ayrıca BapatiVault serisinin final bölümünde bir .NET 8 API'sini Docker ile paketleyip dağıtıyoruz.\u003C/p>\n\u003Cp>\u003Ca href='/videos/docker-konteynerler-nedir-image-container-dockerfile-compose'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/7fOdCXsZVXM' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech' target='_blank' rel='noopener'>Kanala abone ol\u003C/a>\u003C/p>\u003Chr>\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Bir .NET uygulamasının konteynerle paketlenip dağıtıma hazırlanmasını uygulamalı gösterdiğimiz bölümle devam edebilirsiniz.\u003C/p>\u003Cp>\u003Ca href='/videos/unit-test-docker-net-8-xunit-moq-deploy-seri-finali-bapativault-bolum-1212'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/eL7BMwsm9zs' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech?sub_confirmation=1' target='_blank' rel='noopener'>Bapati kanalına abone ol\u003C/a>\u003C/p>","Docker nedir, konteyner ile sanal makine arasındaki fark ne? Image, Dockerfile, katman mantığı ve Compose temelleri sade anlatımla ele alınıyor.","https://img.youtube.com/vi/7fOdCXsZVXM/hqdefault.jpg","Docker nedir, konteyner ile sanal makine farkı ne? Image, Dockerfile, katman mantığı, volume ve Compose temelleri sade ve uygulamalı anlatımla.","docker, konteyner, container, image, dockerfile, docker compose, devops, sanallaştırma, dağıtım, deploy, mikroservis",[143],{"tagId":144,"name":145,"color":146},"3d2fc7de-a2ad-404e-8099-b4b74ec9bc22","Docker","#2496ED","2026-07-27T19:02:02.77665","2026-08-23T13:45:15.0665551",{"articleId":150,"title":151,"slug":152,"content":153,"summary":154,"featuredImage":155,"metaTitle":151,"metaDescription":156,"metaKeywords":157,"isPublished":15,"publishedAt":127,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":129,"authorId":19,"categoryId":52,"categoryName":53,"tags":158,"isActive":15,"isDeleted":16,"createDate":159,"updatedDate":160,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"915879bf-e92c-4f49-9acd-be70747999e1","REST API Nedir? Endpoint, HTTP Metotları, JSON ve Token","rest-api-nedir-endpoint-http-metotlari-json","\u003Ch2>API Neyi Çözüyor?\u003C/h2>\n\u003Cp>Bir mobil uygulama, bir web arayüzü ve bir muhasebe sistemi aynı veriye ihtiyaç duyduğunda, her biri için ayrı bir veri erişim katmanı yazmak sürdürülebilir değildir. Kural bir yerde değişince üç yeri birden güncellemeniz gerekir — ve biri mutlaka unutulur.\u003C/p>\n\u003Cp>API, veriyi ve iş kurallarını tek bir yerde toplayıp dışarıya standart bir arayüzle sunar. İstemcilerin hangi teknolojiyle yazıldığı önemsiz hale gelir. REST ise bu arayüzü HTTP'nin kendi kavramları üzerine kurma yaklaşımıdır: kaynaklar, adresler ve metotlar.\u003C/p>\n\n\u003Ch2>Kaynak ve Endpoint Tasarımı\u003C/h2>\n\u003Cp>REST'te her şey bir kaynaktır ve kaynaklar \u003Cstrong>isimlerle\u003C/strong> temsil edilir, fiillerle değil. Fiili adres değil, HTTP metodu belirler.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Yanlış\u003C/th>\u003Cth>Doğru\u003C/th>\u003Cth>Neden\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Ccode>GET /kullaniciGetir?id=5\u003C/code>\u003C/td>\u003Ctd>\u003Ccode>GET /kullanicilar/5\u003C/code>\u003C/td>\u003Ctd>Fiil metotta, kaynak adreste\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>POST /kullaniciSil\u003C/code>\u003C/td>\u003Ctd>\u003Ccode>DELETE /kullanicilar/5\u003C/code>\u003C/td>\u003Ctd>Silme işlemi DELETE'tir\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET /kullanici/5/siparisGetir\u003C/code>\u003C/td>\u003Ctd>\u003Ccode>GET /kullanicilar/5/siparisler\u003C/code>\u003C/td>\u003Ctd>Hiyerarşi adreste görünür\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET /tumKullanicilar\u003C/code>\u003C/td>\u003Ctd>\u003Ccode>GET /kullanicilar?sayfa=2&amp;adet=20\u003C/code>\u003C/td>\u003Ctd>Sayfalama olmadan liste büyür\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Çoğul isim kullanmak ve hiyerarşiyi adreste göstermek okunabilirliği belirgin biçimde artırır. Ancak hiyerarşiyi ikiden fazla seviyeye taşımamak gerekir: \u003Ccode>/kullanicilar/5/siparisler/12/kalemler/3\u003C/code> yerine \u003Ccode>/siparis-kalemleri/3\u003C/code> hem daha kısa hem daha esnektir.\u003C/p>\n\u003Cp>\u003Cstrong>Liste uçları her zaman sayfalanmalıdır.\u003C/strong> Bugün 40 kayıt döndüren bir uç, iki yıl sonra 40.000 kayıt döndürür ve o gün hem sunucu hem istemci tarafında sorun çıkarır.\u003C/p>\n\n\u003Ch2>HTTP Metotları ve Anlamları\u003C/h2>\n\u003Cp>Bu anlamlara sadık kalmak yalnızca estetik bir tercih değildir; önbellekleme, yeniden deneme ve ara katman davranışları bu sözleşmeye göre çalışır.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Metot\u003C/th>\u003Cth>Ne yapar\u003C/th>\u003Cth>Güvenli\u003C/th>\u003Cth>Tekrarlanabilir\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>GET\u003C/td>\u003Ctd>Okur, durumu değiştirmez\u003C/td>\u003Ctd>Evet\u003C/td>\u003Ctd>Evet\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>POST\u003C/td>\u003Ctd>Yeni kayıt oluşturur\u003C/td>\u003Ctd>Hayır\u003C/td>\u003Ctd>Hayır\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>PUT\u003C/td>\u003Ctd>Kaydı bütünüyle değiştirir\u003C/td>\u003Ctd>Hayır\u003C/td>\u003Ctd>Evet\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>PATCH\u003C/td>\u003Ctd>Kaydın bir kısmını günceller\u003C/td>\u003Ctd>Hayır\u003C/td>\u003Ctd>Genelde evet\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>DELETE\u003C/td>\u003Ctd>Siler\u003C/td>\u003Ctd>Hayır\u003C/td>\u003Ctd>Evet\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>\"Tekrarlanabilir\" sütunu pratikte kritiktir: ağ koptuğunda istemci isteği yeniden gönderir. PUT'u iki kez göndermek zararsızdır, POST'u iki kez göndermek \u003Cstrong>iki sipariş\u003C/strong> demektir. Ödeme gibi kritik uçlarda bu yüzden istemciden bir \u003Cem>idempotency key\u003C/em> alıp aynı anahtarla gelen ikinci isteği yok saymak gerekir.\u003C/p>\n\n\u003Ch2>Durum Kodları: Sessiz Ama Kritik\u003C/h2>\n\u003Cp>Her cevabı 200 döndürüp hatayı gövdeye yazmak yaygın bir kestirme yoldur ve istemci tarafında karmaşaya yol açar: istemci artık her cevabın gövdesini ayrıştırmadan başarılı olup olmadığını bilemez.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Kod\u003C/th>\u003Cth>Anlamı\u003C/th>\u003Cth>İstemci ne yapmalı\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>200 OK\u003C/td>\u003Ctd>Başarılı\u003C/td>\u003Ctd>Veriyi kullan\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>201 Created\u003C/td>\u003Ctd>Kayıt oluşturuldu\u003C/td>\u003Ctd>\u003Ccode>Location\u003C/code> başlığını oku\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>204 No Content\u003C/td>\u003Ctd>Başarılı, gövde yok\u003C/td>\u003Ctd>Gövde ayrıştırma\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>400 Bad Request\u003C/td>\u003Ctd>İstek geçersiz\u003C/td>\u003Ctd>Kullanıcıya alan hatalarını göster\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>401 Unauthorized\u003C/td>\u003Ctd>Kimlik doğrulanmadı\u003C/td>\u003Ctd>Giriş ekranına yönlendir\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>403 Forbidden\u003C/td>\u003Ctd>Kimlik var, yetki yok\u003C/td>\u003Ctd>\"Yetkiniz yok\" mesajı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>404 Not Found\u003C/td>\u003Ctd>Kaynak yok\u003C/td>\u003Ctd>Boş durum göster\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>409 Conflict\u003C/td>\u003Ctd>Çakışma (mükerrer kayıt)\u003C/td>\u003Ctd>Kullanıcıya sebebi söyle\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>422\u003C/td>\u003Ctd>Biçim doğru, iş kuralı ihlali\u003C/td>\u003Ctd>Kural mesajını göster\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>429\u003C/td>\u003Ctd>Çok fazla istek\u003C/td>\u003Ctd>\u003Ccode>Retry-After\u003C/code> kadar bekle\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>500\u003C/td>\u003Ctd>Sunucu hatası\u003C/td>\u003Ctd>Genel hata, tekrar dene\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>401 ile 403 arasındaki farkı doğru kullanmak, istemcinin kullanıcıya doğru mesajı göstermesini sağlar: biri \"giriş yap\" der, diğeri \"yetkin yok\". Karıştırıldığında kullanıcı, yetkisi olmadığı bir sayfada sonsuz döngüde oturum açmaya çalışır.\u003C/p>\n\n\u003Ch2>Tutarlı Cevap Zarfı\u003C/h2>\n\u003Cp>Bir endpoint düz metin, diğeri nesne, bir başkası hata durumunda bambaşka bir yapı döndürdüğünde istemci kodu hızla karmaşıklaşır. Tüm cevapları ortak bir zarf içinde döndürmek, istemci tarafında tek bir işleme kuralı yazmayı mümkün kılar.\u003C/p>\n\u003Cpre>\u003Ccode>// Başarılı\n{\n  \"isSuccess\": true,\n  \"data\": { \"id\": 42, \"ad\": \"Ayşe Yılmaz\", \"eposta\": \"ayse@ornek.com\" },\n  \"message\": null,\n  \"errors\": []\n}\n\n// Doğrulama hatası — HTTP 400 ile birlikte\n{\n  \"isSuccess\": false,\n  \"data\": null,\n  \"message\": \"Doğrulama hatası\",\n  \"errors\": [\n    { \"field\": \"eposta\", \"code\": \"INVALID_FORMAT\", \"message\": \"Geçerli bir e-posta girin\" },\n    { \"field\": \"yas\",    \"code\": \"OUT_OF_RANGE\",   \"message\": \"Yaş 18'den küçük olamaz\" }\n  ]\n}\u003C/code>\u003C/pre>\n\u003Cp>Hata nesnesinde \u003Ccode>field\u003C/code> ve \u003Ccode>code\u003C/code> alanlarının bulunması iki şeyi mümkün kılar: arayüz hatayı doğru form alanının altında gösterebilir, ve istemci mesajın metnine değil \u003Cstrong>koduna\u003C/strong> göre karar verebilir. Mesaj metnine dayanan istemci kodu, çeviri eklendiği gün kırılır.\u003C/p>\n\u003Cp>Bu yaklaşımı kendi projelerimizde \u003Ccode>OperationResult\u003C/code> deseniyle uyguluyoruz; hem başarı hem hata aynı biçimde dönüyor.\u003C/p>\n\n\u003Ch2>Filtreleme, Sıralama ve Alan Seçimi\u003C/h2>\n\u003Cp>Liste uçları pratikte hiçbir zaman \"hepsini getir\"den ibaret kalmaz. İstemci filtrelemek, sıralamak ve bazen yalnızca birkaç alanı istemek ister. Bunları her uç için ayrı ayrı icat etmek yerine tek bir sözleşmeye oturtmak gerekir.\u003C/p>\n\u003Cpre>\u003Ccode>GET /api/v1/siparisler\n      ?durum=beklemede,onaylandi     # çoklu değer virgülle\n      &amp;olusturma_min=2026-01-01      # aralık: _min / _max\n      &amp;olusturma_max=2026-06-30\n      &amp;ara=yilmaz                    # serbest metin araması\n      &amp;sirala=-olusturmaTarihi,tutar  # başındaki \"-\" azalan demek\n      &amp;alanlar=id,tutar,durum         # yalnızca gerekli alanlar\n      &amp;sayfa=2&amp;adet=20\u003C/code>\u003C/pre>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Kural\u003C/th>\u003Cth>Neden\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Sıralama alanları beyaz listeden\u003C/td>\u003Ctd>Rastgele sütun adı kabul etmek SQL enjeksiyonuna ve index'siz sorguya kapı açar\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>adet\u003C/code> için üst sınır\u003C/td>\u003Ctd>\u003Ccode>adet=1000000\u003C/code> tek istekle sunucuyu düşürebilir\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Toplam sayı da dönsün\u003C/td>\u003Ctd>İstemci sayfa sayısını hesaplayabilsin\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Varsayılan sıralama sabit olsun\u003C/td>\u003Ctd>Sırasız sorguda aynı kayıt iki sayfada birden çıkabilir\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Son madde sessiz bir hata kaynağıdır: veritabanı, açık bir \u003Ccode>ORDER BY\u003C/code> olmadan satır sırasını garanti etmez. Sayfalama yapan her sorgunun \u003Cstrong>benzersiz bir alanla\u003C/strong> (en azından ikincil olarak \u003Ccode>id\u003C/code> ile) sıralanması gerekir.\u003C/p>\n\n\u003Ch2>Kimlik Doğrulama ve Token\u003C/h2>\n\u003Cp>Sunucunun her istekte kullanıcıyı yeniden tanıması gerekir. Token tabanlı yaklaşımda kullanıcı bir kez giriş yapar ve karşılığında imzalı bir token alır. Sonraki isteklerde bu token \u003Ccode>Authorization\u003C/code> başlığında taşınır; sunucu imzayı doğrular, oturum bilgisini bellekte tutmak zorunda kalmaz.\u003C/p>\n\u003Cpre>\u003Ccode>GET /api/v1/siparisler?sayfa=1&amp;adet=20 HTTP/1.1\nHost: api.ornek.com\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\nAccept: application/json\u003C/code>\u003C/pre>\n\u003Cp>Bir JWT üç bölümden oluşur ve \u003Cstrong>orta bölümü şifreli değildir, yalnızca kodlanmıştır\u003C/strong> — herkes okuyabilir. İmza içeriğin değiştirilmediğini garanti eder, gizliliğini değil. Bu yüzden token'ın içine parola, TC kimlik numarası gibi hassas veri konmaz.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Konu\u003C/th>\u003Cth>Doğru yaklaşım\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Erişim token'ı süresi\u003C/td>\u003Ctd>Kısa: 15 dakika – birkaç saat\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Yenileme (refresh) token'ı\u003C/td>\u003Ctd>Uzun ömürlü, sunucuda iptal edilebilir\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Saklama yeri\u003C/td>\u003Ctd>\u003Ccode>HttpOnly\u003C/code> çerez tercih edilir; \u003Ccode>localStorage\u003C/code> XSS'e açıktır\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>İçerik\u003C/td>\u003Ctd>Kullanıcı kimliği ve roller — hassas veri yok\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Taşıma\u003C/td>\u003Ctd>Yalnızca HTTPS üzerinden\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Süresiz token, çalındığında sınırsız erişim demektir. Kısa ömürlü erişim token'ı + iptal edilebilir yenileme token'ı ikilisi, bu riski yönetilebilir bir pencereye indirir.\u003C/p>\n\n\u003Ch2>Sürümleme ve Belgeleme\u003C/h2>\n\u003Cp>Yayına çıkmış bir API'nin sözleşmesini bozmak, ona bağlı tüm istemcileri kırar. Burada ayrım nettir: \u003Cem>ekleme\u003C/em> kırıcı değildir, \u003Cem>çıkarma ve değiştirme\u003C/em> kırıcıdır.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Değişiklik\u003C/th>\u003Cth>Kırıcı mı\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Cevaba yeni alan eklemek\u003C/td>\u003Ctd>Hayır\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>İsteğe bağlı yeni parametre eklemek\u003C/td>\u003Ctd>Hayır\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Alan adını değiştirmek\u003C/td>\u003Ctd>\u003Cstrong>Evet\u003C/strong>\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Alanı kaldırmak\u003C/td>\u003Ctd>\u003Cstrong>Evet\u003C/strong>\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Alanın tipini değiştirmek\u003C/td>\u003Ctd>\u003Cstrong>Evet\u003C/strong>\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Zorunlu yeni parametre eklemek\u003C/td>\u003Ctd>\u003Cstrong>Evet\u003C/strong>\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Kırıcı değişiklikler sürüm üzerinden yönetilir; adres tabanlı sürümleme (\u003Ccode>/api/v1/...\u003C/code>) en yaygın ve en okunabilir yöntemdir. Eski sürümü hemen kapatmak yerine bir süre yan yana çalıştırmak ve kaldırılacağını başlıkla duyurmak, istemci ekiplerine geçiş süresi tanır.\u003C/p>\n\u003Cp>Swagger benzeri araçlarla üretilen canlı belgeler, API'yi kullanacak ekibin işini kolaylaştırdığı gibi kendi ekibiniz için de referans oluşturur. Belgelerin koddan üretilmesi ayrıca şu faydayı sağlar: \u003Cstrong>belge, gerçekte çalışan koddan sapamaz.\u003C/strong>\u003C/p>\n\n\u003Ch2>Yayına Almadan Önce Kontrol Listesi\u003C/h2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Konu\u003C/th>\u003Cth>Neden gerekli\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Tüm liste uçlarında sayfalama\u003C/td>\u003Ctd>Veri büyüdükçe cevap ve bellek şişer\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>İstek hız sınırı (rate limit)\u003C/td>\u003Ctd>Tek istemci tüm kapasiteyi tüketebilir\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Girdi doğrulama, her uçta\u003C/td>\u003Ctd>İstemciye güvenilmez\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>CORS yalnızca bilinen kaynaklara\u003C/td>\u003Ctd>Tarayıcıdan kötüye kullanımı engeller\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Hata gövdesinde iç detay yok\u003C/td>\u003Ctd>Yığın izi saldırgana harita verir\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Zaman alanları UTC ve ISO 8601\u003C/td>\u003Ctd>Saat dilimi hataları en sinsi hatalardır\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>İstek kimliği (correlation id)\u003C/td>\u003Ctd>Sorun çıktığında logda izlenebilsin\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Bu listenin çoğu maddesi sonradan eklenmesi zor olan şeylerdir. Özellikle sayfalama ve sürümleme, ilk günden düşünülmediğinde geri dönüşü pahalı olan iki karardır.\u003C/p>\n\n\u003Chr>\n\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> REST API'yi temelden anlattığımız bölüm 'Her Yazılımcının Bilmesi Gerekenler' serimizde; BapatiVault serisinde ise .NET 8 ile sıfırdan bir API inşa ediyoruz.\u003C/p>\n\u003Cp>\u003Ca href='/videos/rest-api-json-nasil-calisir-endpoint-metotlar-json-token'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/EjQdMpsb4ak' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech' target='_blank' rel='noopener'>Kanala abone ol\u003C/a>\u003C/p>\u003Chr>\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> REST API kavramlarını uygulamalı gösterdiğimiz videoyla konuyu pekiştirebilirsiniz.\u003C/p>\u003Cp>\u003Ca href='/videos/rest-api-json-nasil-calisir-endpoint-metotlar-json-token'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/EjQdMpsb4ak' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech?sub_confirmation=1' target='_blank' rel='noopener'>Bapati kanalına abone ol\u003C/a>\u003C/p>","REST API nedir, nasıl tasarlanır? Endpoint, HTTP metotları, durum kodları ve JSON yapısını örneklerle ve sık yapılan hatalarla ele alıyoruz.","https://img.youtube.com/vi/EjQdMpsb4ak/hqdefault.jpg","REST API nedir, nasıl çalışır? Endpoint, HTTP metotları, durum kodları ve JSON yapısı örneklerle ve sık yapılan hatalarla birlikte anlatılıyor.","rest api, api, endpoint, http metotları, json, jwt, token, durum kodları, backend geliştirme, web servisi, api tasarımı",[],"2026-07-27T19:02:02.9718141","2026-08-23T13:45:16.7722595",{"articleId":162,"title":163,"slug":164,"content":165,"summary":166,"featuredImage":167,"metaTitle":163,"metaDescription":168,"metaKeywords":169,"isPublished":15,"publishedAt":170,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":129,"authorId":19,"categoryId":5,"categoryName":6,"tags":171,"isActive":15,"isDeleted":16,"createDate":172,"updatedDate":173,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"d49afff6-833b-407d-a46b-75ae9da35d6f","Exchange Server Nedir? Kurumsal E-posta Altyapısının Temelleri","exchange-server-nedir-kurumsal-eposta-altyapisi","\u003Ch2>Neden Kendi Mail Sunucun?\u003C/h2>\n\u003Cp>Bulut tabanlı e-posta hizmetleri yaygınlaşsa da, verinin kurum sınırları içinde kalmasını gerektiren düzenlemeler ya da mevcut altyapı yatırımları nedeniyle şirket içi Exchange kurulumları hâlâ yaygındır.\u003C/p>\n\u003Cp>Exchange Server, posta kutularını, dağıtım gruplarını, takvimleri ve ortak klasörleri tek bir yönetim noktasından denetlemenizi sağlar. Karşılığında ise kurulum, sertifika, yedekleme ve güvenlik sorumluluğu tamamen size geçer.\u003C/p>\n\u003Cp>Karar vermeden önce iki modelin gerçekte neyi devrettiğine bakmak faydalı olur:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Konu\u003C/th>\u003Cth>Şirket içi Exchange\u003C/th>\u003Cth>Bulut (Exchange Online)\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Verinin konumu\u003C/td>\u003Ctd>Kendi veri merkezinizde\u003C/td>\u003Ctd>Sağlayıcının bölgesinde\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Güncelleme / yama\u003C/td>\u003Ctd>Sizde — güvenlik açıkları kritik\u003C/td>\u003Ctd>Sağlayıcıda\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Sertifika yönetimi\u003C/td>\u003Ctd>Sizde\u003C/td>\u003Ctd>Sağlayıcıda\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Yedekleme ve kurtarma\u003C/td>\u003Ctd>Sizde\u003C/td>\u003Ctd>Kısmen sağlayıcıda\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Maliyet biçimi\u003C/td>\u003Ctd>Peşin donanım + lisans + emek\u003C/td>\u003Ctd>Kullanıcı başına aylık\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Özelleştirme sınırı\u003C/td>\u003Ctd>Geniş\u003C/td>\u003Ctd>Sağlayıcının izin verdiği kadar\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Şirket içi tercih ediliyorsa, \u003Cstrong>yama yönetimi pazarlık konusu değildir\u003C/strong>. Exchange, internete açık olduğu için geçmişte en çok hedef alınan ürünlerden biri olmuştur; güncellenmeyen bir sunucu kurumun en zayıf noktasıdır.\u003C/p>\n\n\u003Ch2>Sunucu Rolleri ve Kurulum Öncesi\u003C/h2>\n\u003Cp>Exchange kurulumu, Active Directory ortamının hazır olmasını şart koşar. Şema hazırlığı yapılmadan kurulum ilerlemez ve bu adım \u003Cstrong>forest genelinde kalıcı bir değişikliktir\u003C/strong> — geri alınamaz, bu yüzden önce test ortamında denenir.\u003C/p>\n\u003Cpre>\u003Ccode># Şemayı ve AD'yi hazırla (Schema Admins + Enterprise Admins yetkisi gerekir)\n.\\Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON /PrepareSchema\n.\\Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON /PrepareAD /OrganizationName:\"Bapati\"\n.\\Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataON /PrepareAllDomains\n\n# Ön gereksinim Windows özellikleri\nInstall-WindowsFeature Server-Media-Foundation, NET-Framework-45-Features, `\n  RPC-over-HTTP-proxy, RSAT-Clustering, RSAT-Clustering-CmdInterface, `\n  WAS-Process-Model, Web-Asp-Net45, Web-Basic-Auth, Web-Client-Auth, `\n  Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, `\n  Web-Http-Logging, Web-Http-Redirect, Web-Http-Tracing, Web-ISAPI-Ext, `\n  Web-ISAPI-Filter, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service, `\n  Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, `\n  Web-Static-Content, Web-Windows-Auth, Web-WMI, Windows-Identity-Foundation\u003C/code>\u003C/pre>\n\u003Cp>Klasik rol ayrımında Mailbox rolü posta kutularını barındırır, Client Access istemci bağlantılarını karşılar, Hub Transport ise mesaj yönlendirmesini üstlenir. Yeni sürümlerde bu roller Mailbox rolünde birleştirilmiş, yalnızca Edge Transport ayrı kalmıştır.\u003C/p>\n\n\u003Ch2>Mailbox Database: Hepsini Tek Yere Koymayın\u003C/h2>\n\u003Cp>Tüm posta kutularını tek bir veritabanında toplamak kurulum aşamasında pratik görünür; ancak yedekleme süresi ve kurtarma riski açısından sağlıklı değildir. Tek veritabanı bozulduğunda \u003Cem>herkes\u003C/em> etkilenir ve geri dönüş, veritabanının tamamının kopyalanması kadar sürer.\u003C/p>\n\u003Cpre>\u003Ccode># Amaca göre ayrı veritabanları; veri ve log farklı disklerde\nNew-MailboxDatabase -Name \"DB-Personel\" `\n  -EdbFilePath  \"E:\\Exchange\\DB-Personel\\DB-Personel.edb\" `\n  -LogFolderPath \"F:\\Exchange\\Logs\\DB-Personel\"\n\nNew-MailboxDatabase -Name \"DB-Arsiv\" `\n  -EdbFilePath  \"E:\\Exchange\\DB-Arsiv\\DB-Arsiv.edb\" `\n  -LogFolderPath \"F:\\Exchange\\Logs\\DB-Arsiv\"\n\nMount-Database \"DB-Personel\"\nMount-Database \"DB-Arsiv\"\n\n# Boyut ve son yedek tarihini izle — \"son tam yedek\" alanı boşsa alarm ver\nGet-MailboxDatabase -Status |\n  Select-Object Name, DatabaseSize, LastFullBackup, Mounted |\n  Format-Table -AutoSize\u003C/code>\u003C/pre>\n\u003Cp>Veri (\u003Ccode>.edb\u003C/code>) ve log dosyalarını farklı disklere yerleştirmek yalnızca performans meselesi değildir: log diski dolduğunda veritabanı kendini kapatır, ama veri diski ayrı olduğu için kurtarma çok daha temiz ilerler.\u003C/p>\n\u003Cp>\u003Cstrong>Tam yedek almak da bir bakım işidir.\u003C/strong> Exchange, işlem loglarını ancak başarılı bir tam yedek sonrası temizler (circular logging kapalıysa). Yedek alınmayan bir sunucuda log diski sessizce dolar ve posta akışı bir sabah durur.\u003C/p>\n\n\u003Ch2>Accepted Domain ve E-mail Address Policy\u003C/h2>\n\u003Cp>Exchange'in hangi alan adına gelen postaları kabul edeceğini accepted domain tanımı belirler. Bu tanım olmadan dışarıdan gelen mailler reddedilir.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Accepted domain türü\u003C/th>\u003Cth>Anlamı\u003C/th>\u003Cth>Ne zaman\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Authoritative\u003C/td>\u003Ctd>Bu alan adının tüm kutuları bende\u003C/td>\u003Ctd>Ana kurumsal alan adı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Internal Relay\u003C/td>\u003Ctd>Bir kısmı bende, kalanını içeride başka sunucuya ilet\u003C/td>\u003Ctd>Göç dönemi, birleşme\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>External Relay\u003C/td>\u003Ctd>Kutular dışarıda, ben yalnızca aktarırım\u003C/td>\u003Ctd>Bağlı şirket, dış sağlayıcı\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cpre>\u003Ccode>New-AcceptedDomain -Name \"Bapati\" -DomainName \"bapati.com\" -DomainType Authoritative\n\n# Yeni açılan her kutuya ad.soyad@bapati.com biçiminde adres ata\nNew-EmailAddressPolicy -Name \"Standart\" `\n  -IncludedRecipients MailboxUsers `\n  -EnabledEmailAddressTemplates \"SMTP:%g.%s@bapati.com\" `\n  -Priority 1\nUpdate-EmailAddressPolicy -Identity \"Standart\"\u003C/code>\u003C/pre>\n\u003Cp>Authoritative yerine yanlışlıkla relay seçmek, mailin kendi sunucusuna geri dönüp durduğu \u003Cem>mail döngüsü\u003C/em> hatasının klasik sebebidir.\u003C/p>\n\n\u003Ch2>Dışarıdan Mail Alabilmek: MX, NAT ve Port 25\u003C/h2>\n\u003Cp>Bir kurumun mail alabilmesi için üç şeyin aynı anda doğru olması gerekir: DNS'te MX kaydı, güvenlik duvarında 25 portunun yönlendirilmesi ve Exchange üzerinde uygun receive connector.\u003C/p>\n\u003Cp>Bugün bunlara dördüncüsü de eklendi: \u003Cstrong>gönderdiğiniz mailin karşı tarafça kabul edilmesi için kimlik doğrulama kayıtları\u003C/strong>. Bunlar olmadan mailleriniz büyük sağlayıcılarda doğrudan spam klasörüne düşer.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Kayıt\u003C/th>\u003Cth>Ne söyler\u003C/th>\u003Cth>Örnek\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>MX\u003C/td>\u003Ctd>Bu alan adının postası hangi sunucuya teslim edilecek\u003C/td>\u003Ctd>\u003Ccode>10 mail.bapati.com\u003C/code>\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>SPF\u003C/td>\u003Ctd>Bu alan adı adına kimler mail gönderebilir\u003C/td>\u003Ctd>\u003Ccode>v=spf1 mx -all\u003C/code>\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>DKIM\u003C/td>\u003Ctd>Mail yolda değiştirilmemiş (imza)\u003C/td>\u003Ctd>Seçici + genel anahtar\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>DMARC\u003C/td>\u003Ctd>SPF/DKIM başarısızsa ne yapılsın\u003C/td>\u003Ctd>\u003Ccode>v=DMARC1; p=quarantine\u003C/code>\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>PTR\u003C/td>\u003Ctd>Giden IP'nin ters kaydı sunucu adıyla uyuşuyor\u003C/td>\u003Ctd>ISP'den istenir\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Sorun yaşandığında tahmin yürütmek yerine mesaj izleme kayıtlarına bakmak gerekir. Mailin nerede takıldığını tek komut gösterir:\u003C/p>\n\u003Cpre>\u003Ccode># Son 2 saatte bu adrese gelen/giden her hareket\nGet-MessageTrackingLog -Start (Get-Date).AddHours(-2) `\n  -Recipients \"ayse.yilmaz@bapati.com\" |\n  Select-Object Timestamp, EventId, Source, Sender, MessageSubject |\n  Sort-Object Timestamp\n\n# Kuyrukta bekleyen var mı, sebebi ne?\nGet-Queue | Where-Object { $_.MessageCount -gt 0 } |\n  Select-Object Identity, Status, MessageCount, LastError\u003C/code>\u003C/pre>\n\u003Cp>\u003Ccode>EventId\u003C/code> alanı okumayı bilene çok şey söyler: \u003Ccode>RECEIVE\u003C/code> geldi, \u003Ccode>DELIVER\u003C/code> kutuya düştü, \u003Ccode>FAIL\u003C/code> reddedildi, \u003Ccode>DEFER\u003C/code> ertelendi. Kayıtta hiç iz yoksa mail sunucuya hiç ulaşmamış demektir; sorun DNS ya da güvenlik duvarındadır.\u003C/p>\n\n\u003Ch2>OWA, Sertifika ve O Meşhur Uyarı\u003C/h2>\n\u003Cp>Outlook Web App, kullanıcıların tarayıcıdan e-postaya erişmesini sağlar. İç ağda çalıştırmak kolaydır; asıl mesele dışarıya güvenli biçimde açmaktır.\u003C/p>\n\u003Cp>Kurulumla gelen self-signed sertifika tarayıcıda güven uyarısı üretir. Uyarının en sık sebebi, sertifikadaki adın kullanıcıların yazdığı adresle uyuşmamasıdır. Çözüm iki adımlıdır: dış adı kapsayan geçerli bir sertifika, ve \u003Cstrong>iç/dış URL'lerin aynı ada hizalanması\u003C/strong>.\u003C/p>\n\u003Cpre>\u003Ccode>$ad = \"mail.bapati.com\"\nforeach ($svc in \"OWA\",\"ECP\",\"OAB\",\"EWS\",\"ActiveSync\",\"MAPI\") {\n  switch ($svc) {\n    \"OWA\"         { Set-OwaVirtualDirectory        -Identity \"*\\owa (Default Web Site)\"        -InternalUrl \"https://$ad/owa\"        -ExternalUrl \"https://$ad/owa\" }\n    \"ECP\"         { Set-EcpVirtualDirectory        -Identity \"*\\ecp (Default Web Site)\"        -InternalUrl \"https://$ad/ecp\"        -ExternalUrl \"https://$ad/ecp\" }\n    \"OAB\"         { Set-OabVirtualDirectory        -Identity \"*\\OAB (Default Web Site)\"        -InternalUrl \"https://$ad/OAB\"        -ExternalUrl \"https://$ad/OAB\" }\n    \"EWS\"         { Set-WebServicesVirtualDirectory -Identity \"*\\EWS (Default Web Site)\"       -InternalUrl \"https://$ad/EWS/Exchange.asmx\" -ExternalUrl \"https://$ad/EWS/Exchange.asmx\" }\n    \"ActiveSync\"  { Set-ActiveSyncVirtualDirectory -Identity \"*\\Microsoft-Server-ActiveSync (Default Web Site)\" -InternalUrl \"https://$ad/Microsoft-Server-ActiveSync\" -ExternalUrl \"https://$ad/Microsoft-Server-ActiveSync\" }\n    \"MAPI\"        { Set-MapiVirtualDirectory       -Identity \"*\\mapi (Default Web Site)\"       -InternalUrl \"https://$ad/mapi\"       -ExternalUrl \"https://$ad/mapi\" }\n  }\n}\n\n# Otomatik yapılandırma adresi de aynı ada bakmalı\nSet-ClientAccessService -Identity EXCH01 -AutoDiscoverServiceInternalUri \"https://$ad/Autodiscover/Autodiscover.xml\"\u003C/code>\u003C/pre>\n\u003Cp>İç ağdaki kullanıcıların da dış adı çözebilmesi için iç DNS'te aynı ada bir kayıt açmak (split-brain DNS) gerekir; aksi halde ofiste sertifika uyarısı, dışarıda sorunsuz erişim gibi tuhaf bir tablo çıkar.\u003C/p>\n\n\u003Ch2>Kota ve Arşivleme\u003C/h2>\n\u003Cp>Sınırsız posta kutusu, er ya da geç dolan bir disk demektir. Exchange üç eşik sunar ve bunları veritabanı düzeyinde tanımlayıp istisnaları kutu bazında yönetmek en sürdürülebilir yoldur.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Eşik\u003C/th>\u003Cth>Aşılınca ne olur\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Ccode>IssueWarningQuota\u003C/code>\u003C/td>\u003Ctd>Kullanıcıya uyarı maili gider, her şey çalışır\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>ProhibitSendQuota\u003C/code>\u003C/td>\u003Ctd>Gönderemez, almaya devam eder\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>ProhibitSendReceiveQuota\u003C/code>\u003C/td>\u003Ctd>Ne gönderir ne alır — gönderen geri dönüş alır\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cpre>\u003Ccode>Set-MailboxDatabase \"DB-Personel\" `\n  -IssueWarningQuota           4.5GB `\n  -ProhibitSendQuota           5GB `\n  -ProhibitSendReceiveQuota    5.5GB\n\n# En çok yer kaplayan 15 kutu — disk dolmadan önce bakılacak yer\nGet-MailboxStatistics -Database \"DB-Personel\" |\n  Sort-Object TotalItemSize -Descending |\n  Select-Object DisplayName, TotalItemSize, ItemCount -First 15\u003C/code>\u003C/pre>\n\u003Cp>Journal Rule ise kurumsal yazışmaların ayrı bir posta kutusunda saklanmasını sağlar; yasal saklama yükümlülüğü olan kurumlar için gereklidir. Journaling'in disk tüketimini ciddi biçimde artırdığını — pratikte yazışma hacmini ikiye katladığını — ve bu nedenle kapsamının baştan planlanması gerektiğini unutmamak gerekir.\u003C/p>\n\n\u003Ch2>Hibrit: İkisinin Arasında Kalmak\u003C/h2>\n\u003Cp>Pratikte kurumların çoğu ikisinin arasında bir yerdedir. Bir kısım posta kutusu şirket içinde, bir kısmı bulutta durur; kullanıcılar bu ayrımı hissetmez. Buna hibrit yapılandırma denir ve genellikle iki sebeple kurulur: kademeli göç, ya da bazı kutuların kalıcı olarak içeride tutulması zorunluluğu.\u003C/p>\n\u003Cp>Hibritin bedeli, iki ortamın da yönetilmesidir. Kimlik eşitlemesi, ortak alan adı, serbest/meşgul takvim paylaşımı ve posta akışı yönlendirmesi ayrı ayrı kurulur.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Bileşen\u003C/th>\u003Cth>Görevi\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Azure AD Connect\u003C/td>\u003Ctd>Şirket içi AD hesaplarını buluta eşitler\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Hybrid Configuration Wizard\u003C/td>\u003Ctd>Bağlayıcıları ve güven ilişkisini kurar\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Organization Relationship\u003C/td>\u003Ctd>İki taraf arasında takvim paylaşımı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Send/Receive Connector\u003C/td>\u003Ctd>Posta akışının iki yönde de sürmesi\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cpre>\u003Ccode># Bir posta kutusunu buluta taşı (şirket içi kabuktan)\nNew-MoveRequest -Identity \"ayse.yilmaz@bapati.com\" `\n  -Remote -RemoteHostName \"mail.bapati.com\" `\n  -TargetDeliveryDomain \"bapati.mail.onmicrosoft.com\" `\n  -RemoteCredential (Get-Credential) `\n  -BadItemLimit 10\n\n# Taşımanın durumu\nGet-MoveRequest | Get-MoveRequestStatistics |\n  Select-Object DisplayName, StatusDetail, PercentComplete, BytesTransferred\u003C/code>\u003C/pre>\n\u003Cp>Göç tamamlansa bile \u003Cstrong>şirket içi Exchange sunucusu genellikle tamamen kaldırılamaz\u003C/strong>: hesaplar şirket içi AD'de yönetildiği sürece, posta özniteliklerini düzenlemek için en az bir yönetim sunucusu gerekir. Bu sunucunun da güncel tutulması gerektiğini planlamaya dahil etmek gerekir.\u003C/p>\n\n\u003Ch2>Kurulumdan Sonra Unutulan Üç Şey\u003C/h2>\n\u003Cp>Sahada en sık karşılaşılan sorunlar kurulum hatalarından değil, kurulumdan sonra yapılmayanlardan doğar:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Atlanan iş\u003C/th>\u003Cth>Ne zaman patlar\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Tam yedek planlanmamış\u003C/td>\u003Ctd>Log diski dolduğu gün posta akışı durur\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Sertifika bitiş tarihi izlenmiyor\u003C/td>\u003Ctd>Süre dolduğu sabah kimse bağlanamaz\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Güvenlik güncellemeleri ertelenmiş\u003C/td>\u003Ctd>İnternete açık sunucu hedef olur\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>SPF/DKIM/DMARC kurulmamış\u003C/td>\u003Ctd>Giden mailler karşı tarafta spam'e düşer\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Disk boş alanı izlenmiyor\u003C/td>\u003Ctd>Veritabanı kendini kapatır\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Bu beş maddeyi bir izleme sistemine bağlamak, Exchange yönetiminin gündelik yükünü belirgin biçimde azaltır.\u003C/p>\n\n\u003Chr>\n\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Exchange Server eğitim serimizde kurulumdan MX kaydına, public folder'dan room mailbox yapılandırmasına kadar tüm adımları uygulamalı olarak anlatıyoruz.\u003C/p>\n\u003Cp>\u003Ca href='/videos/exchange-server-kurulumu-ht-mailbox-cas-ve-dag-hazirlik-1'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/A2BIIrVWtVk' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech' target='_blank' rel='noopener'>Kanala abone ol\u003C/a>\u003C/p>\u003Chr>\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Exchange kurulumunu ve yönetimini adım adım gösterdiğimiz seriyle devam edebilirsiniz.\u003C/p>\u003Cp>\u003Ca href='/videos/exchange-server-kurulumu-ht-mailbox-cas-ve-dag-hazirlik-1'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/A2BIIrVWtVk' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech?sub_confirmation=1' target='_blank' rel='noopener'>Bapati kanalına abone ol\u003C/a>\u003C/p>","Exchange Server nedir, kurumsal e-posta altyapısında ne işe yarar? Posta kutusu, veritabanı, sertifika ve akış kuralları temelleriyle ele alınıyor.","https://img.youtube.com/vi/A2BIIrVWtVk/hqdefault.jpg","Exchange Server nedir, kurumsal e-posta altyapısı nasıl kurulur? Posta kutusu, veritabanı, sertifika ve akış kuralları sade biçimde anlatılıyor.","exchange server, kurumsal e-posta, mailbox database, mx kaydı, owa, outlook web app, accepted domain, smtp, mail sunucusu, windows server","2026-07-27T22:01:59",[],"2026-07-27T19:02:02.0934893","2026-08-23T13:45:16.1446769",{"articleId":175,"title":176,"slug":177,"content":178,"summary":179,"featuredImage":180,"metaTitle":176,"metaDescription":181,"metaKeywords":182,"isPublished":15,"publishedAt":170,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":183,"authorId":19,"categoryId":41,"categoryName":42,"tags":184,"isActive":15,"isDeleted":16,"createDate":189,"updatedDate":190,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"b82f687d-13dd-4fe1-bf9f-a53e96103e56","LLM Nasıl Çalışır? Token, Embedding ve Transformer Sade Anlatım","llm-nasil-calisir-token-embedding-transformer","\u003Ch2>Temel Fikir: Sıradaki Kelimeyi Tahmin Etmek\u003C/h2>\n\u003Cp>Büyük dil modellerinin yaptığı iş, dışarıdan göründüğü kadar karmaşık değildir: verilen metnin ardından hangi parçanın gelme olasılığının yüksek olduğunu tahmin ederler. Bu tahmini defalarca tekrarlayarak cümleler, paragraflar ve sayfalar üretirler.\u003C/p>\n\u003Cp>Yani model bir cevabı baştan planlayıp yazmaz; parça parça ilerler. Her adımda elinde olan tek şey, o ana kadar yazılmış metindir.\u003C/p>\n\u003Cp>\"Türkiye'nin başkenti\" ifadesinden sonra modelin gördüğü tablo kabaca şöyledir:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Aday parça\u003C/th>\u003Cth>Olasılık\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd> Ankara\u003C/td>\u003Ctd>%94\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd> İstanbul\u003C/td>\u003Ctd>%3\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd> ise\u003C/td>\u003Ctd>%1\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>diğer binlerce aday\u003C/td>\u003Ctd>%2\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Model bu listeden birini seçer, seçtiğini metnin sonuna ekler ve aynı işlemi baştan yapar. \u003Cstrong>Cevabın tamamı, bu tek adımın binlerce kez tekrarıdır.\u003C/strong> Modelin güçlü ve zayıf yanlarının çoğu doğrudan bu çalışma biçiminden kaynaklanır.\u003C/p>\n\u003Cp>Seçimin ne kadar \"cesur\" olacağını \u003Ccode>temperature\u003C/code> belirler: 0'a yakın değerlerde model hep en yüksek olasılıklı adayı seçer ve tekrara düşer; yüksek değerlerde çeşitlenir ama tutarlılığı azalır.\u003C/p>\n\n\u003Ch2>Token: Model Kelimeleri Değil Parçaları Görür\u003C/h2>\n\u003Cp>Model metni kelime kelime değil, token adı verilen parçalar hâlinde işler. Bir token bazen tam bir kelime, bazen kelimenin bir bölümü, bazen tek bir karakterdir.\u003C/p>\n\u003Cp>Türkçe gibi eklemeli dillerde bu ayrım doğrudan cebinize dokunur. Aynı anlamı taşıyan iki cümlenin maliyeti eşit değildir:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Metin\u003C/th>\u003Cth>Karakter\u003C/th>\u003Cth>Yaklaşık token\u003C/th>\u003Cth>Karakter/token\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Ccode>The capital of Turkey is Ankara.\u003C/code>\u003C/td>\u003Ctd>32\u003C/td>\u003Ctd>~7\u003C/td>\u003Ctd>4,6\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>Türkiye'nin başkenti Ankara'dır.\u003C/code>\u003C/td>\u003Ctd>31\u003C/td>\u003Ctd>~14\u003C/td>\u003Ctd>2,2\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>\u003Ccode>kararlaştırılamamışlardan\u003C/code>\u003C/td>\u003Ctd>25\u003C/td>\u003Ctd>~11\u003C/td>\u003Ctd>2,3\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Aynı içerik Türkçede kabaca \u003Cstrong>iki katı token\u003C/strong> tüketir. Ücretlendirme ve bağlam sınırı token üzerinden hesaplandığı için, Türkçe bir uygulamada aynı bütçeyle yarı kadar metin işlersiniz. Bu, tasarım aşamasında hesaba katılması gereken somut bir kısıttır.\u003C/p>\n\u003Cpre>\u003Ccode># Tahmin etmek yerine ölçmek: token sayısını doğrudan saymak\nimport tiktoken\n\nkodlayici = tiktoken.get_encoding(\"cl100k_base\")\n\nfor metin in [\"The capital of Turkey is Ankara.\",\n              \"Türkiye'nin başkenti Ankara'dır.\"]:\n    parcalar = kodlayici.encode(metin)\n    print(f\"{len(parcalar):3} token | {metin}\")\n    print(\"      \", [kodlayici.decode([p]) for p in parcalar])\u003C/code>\u003C/pre>\n\u003Cp>Bu ayrıntı bir yan etki daha üretir: model kelimeyi bütün olarak görmediği için harf saymak, kelimeyi tersten yazmak ya da kafiye bulmak gibi işlerde beklenmedik biçimde zorlanır. Sorun zekâ değil, girdiyi hiç o çözünürlükte görmemesidir.\u003C/p>\n\n\u003Ch2>Embedding: Anlamı Sayıya Çevirmek\u003C/h2>\n\u003Cp>Model sayılarla çalışır; dolayısıyla her token bir sayı vektörüne dönüştürülür. Bu vektörlere embedding denir ve tipik olarak yüzlerce ya da binlerce boyutu vardır.\u003C/p>\n\u003Cp>Embedding'lerin değerli tarafı, benzer anlamdaki ifadelerin bu sayı uzayında birbirine yakın düşmesidir. \"Doktor\" ile \"hemşire\" arasındaki mesafe, \"doktor\" ile \"traktör\" arasındakinden kısadır — üstelik ikinci çift yazım olarak birbirine daha çok benzemesine rağmen.\u003C/p>\n\u003Cpre>\u003Ccode>// İki metnin anlamca yakınlığı: kosinüs benzerliği\nfunction kosinusBenzerligi(a, b) {\n    let carpim = 0, normA = 0, normB = 0\n    for (let i = 0; i \u003C a.length; i++) {\n        carpim += a[i] * b[i]\n        normA  += a[i] * a[i]\n        normB  += b[i] * b[i]\n    }\n    return carpim / (Math.sqrt(normA) * Math.sqrt(normB))\n}\n\n// 1'e yakın: aynı şeyden bahsediyorlar\n// 0'a yakın: ilgisiz\n// Arama motorunuzun \"anlamca en yakın 5 belge\" sorgusu tam olarak budur.\u003C/code>\u003C/pre>\n\u003Cp>Bu özellik, arama ve benzerlik bulma gibi işlerin temelini oluşturur; aşağıda değineceğimiz RAG mimarilerinin çalışma mantığı da buna dayanır. Kelime eşleşmesine dayalı klasik aramanın kaçırdığı \"zam\" ↔ \"ücret artışı\" ilişkisini embedding yakalar.\u003C/p>\n\n\u003Ch2>Attention: Hangi Kelimeye Ne Kadar Bakmalı?\u003C/h2>\n\u003Cp>Bir cümleyi anlamak için her kelimeye eşit ağırlık vermek yanlış sonuç üretir. \"Çantayı masaya koydum çünkü \u003Cem>ağırdı\u003C/em>\" cümlesinde \"ağırdı\" kelimesinin neyi nitelediğini bulmak gerekir — çanta mı, masa mı? İnsan bunu bağlamdan çözer; modelin de bir mekanizmaya ihtiyacı vardır.\u003C/p>\n\u003Cp>Attention mekanizması tam olarak bunu yapar: her token üretilirken, girdideki diğer token'lara ne kadar dikkat edileceğini hesaplar. \"Ağırdı\" işlenirken ağırlığın büyük kısmı \"çantayı\" üzerine düşer.\u003C/p>\n\u003Cp>Transformer mimarisinin dil işlemede önceki yaklaşımları geride bırakmasının temel sebebi budur. Ancak bir bedeli vardır: attention, her token'ı diğer \u003Cem>tüm\u003C/em> token'larla karşılaştırır.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Bağlam uzunluğu\u003C/th>\u003Cth>Karşılaştırma sayısı\u003C/th>\u003Cth>Göreli maliyet\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>1.000 token\u003C/td>\u003Ctd>1 milyon\u003C/td>\u003Ctd>1×\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>10.000 token\u003C/td>\u003Ctd>100 milyon\u003C/td>\u003Ctd>100×\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>100.000 token\u003C/td>\u003Ctd>10 milyar\u003C/td>\u003Ctd>10.000×\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Bağlamı iki katına çıkarmak maliyeti iki değil \u003Cstrong>dört katına\u003C/strong> çıkarır. \"Tüm belgeleri prompt'a koyalım\" fikrinin neden hızla pahalılaştığı buradan anlaşılır.\u003C/p>\n\n\u003Ch2>Eğitim: Pretraining, Fine-tuning ve RLHF\u003C/h2>\n\u003Cp>Model önce çok büyük miktarda metin üzerinde genel dil yeteneği kazanır; bu aşamaya pretraining denir ve maliyetin neredeyse tamamı buradadır.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Aşama\u003C/th>\u003Cth>Ne öğretir\u003C/th>\u003Cth>Veri ölçeği\u003C/th>\u003Cth>Kim yapar\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Pretraining\u003C/td>\u003Ctd>Dilin genel yapısı ve dünya bilgisi\u003C/td>\u003Ctd>Trilyonlarca token\u003C/td>\u003Ctd>Model sağlayıcısı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Fine-tuning\u003C/td>\u003Ctd>Belirli görev, biçim ya da üslup\u003C/td>\u003Ctd>Binlerce örnek\u003C/td>\u003Ctd>Sağlayıcı ya da siz\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>RLHF\u003C/td>\u003Ctd>Hangi cevabın tercih edildiği\u003C/td>\u003Ctd>İnsan karşılaştırmaları\u003C/td>\u003Ctd>Model sağlayıcısı\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Modelin \"yardımcı ve zararsız\" cevaplar vermeye yönelmesi büyük ölçüde RLHF aşamasının ürünüdür. Aynı aşama, modelin bazen fazla temkinli davranmasının da sebebidir.\u003C/p>\n\u003Cp>Pratikte sık karıştırılan bir nokta: \u003Cstrong>fine-tuning modele yeni bilgi öğretmenin verimli yolu değildir.\u003C/strong> Kurum belgelerinizi modele \"öğretmek\" istiyorsanız, doğru araç genellikle fine-tuning değil RAG'dır. Fine-tuning biçimi ve üslubu öğretir; güncel bilgiyi değil.\u003C/p>\n\n\u003Ch2>Neden Uydurur? Halüsinasyon Meselesi\u003C/h2>\n\u003Cp>Model doğruluk değil olasılık optimize eder. Bilmediği bir konuda da istatistiksel olarak makul görünen bir cevap üretir; bu cevabın gerçekle örtüşme garantisi yoktur.\u003C/p>\n\u003Cp>Halüsinasyon bir arıza değil, çalışma biçiminin doğal sonucudur. Model \"bilmiyorum\" demek için de bir sebep görmelidir; varsayılan davranışı, en olası devamı yazmaktır.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Risk yüksek\u003C/th>\u003Cth>Risk düşük\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Tarihler, sayılar, istatistikler\u003C/td>\u003Ctd>Metni özetlemek\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Kaynak, makale, kitap adı\u003C/td>\u003Ctd>Üslup ve biçim değiştirmek\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Kişiye özel ve nadir bilgiler\u003C/td>\u003Ctd>Verilen metinden soru cevaplamak\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Güncel olaylar\u003C/td>\u003Ctd>Sınıflandırma ve etiketleme\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Kesin API imzaları, sürüm numaraları\u003C/td>\u003Ctd>Taslak üretmek\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Sağdaki sütunun ortak özelliği dikkat çekicidir: \u003Cstrong>cevabın malzemesi zaten prompt'un içindedir.\u003C/strong> Pratik önlem de buradan çıkar — modeli doğrulanabilir bir kaynağa bağlamak.\u003C/p>\n\n\u003Ch2>RAG: Cevabı Kendi Belgelerinizden Ürettirmek\u003C/h2>\n\u003Cp>RAG (Retrieval-Augmented Generation) yaklaşımı, soruyu doğrudan modele sormak yerine önce kendi belgelerinizde arar, bulduğu parçaları prompt'a ekler ve modelden \u003Cem>yalnızca bunlara dayanarak\u003C/em> cevap vermesini ister.\u003C/p>\n\u003Cpre>\u003Ccode># RAG'ın tamamı dört adımdır\nsoru = \"Yıllık izin devri kaç gün?\"\n\n# 1) Soruyu vektöre çevir\nsoru_vektoru = embed(soru)\n\n# 2) En yakın belge parçalarını bul (embedding benzerliği)\nparcalar = vektor_deposu.ara(soru_vektoru, adet=5)\n\n# 3) Bulunanları prompt'a koy ve sınırı açıkça söyle\nistem = f\"\"\"Aşağıdaki belge parçalarına DAYANARAK cevapla.\nCevap parçalarda yoksa \"belgelerde bulamadım\" de, tahmin etme.\n\n--- BELGELER ---\n{chr(10).join(parcalar)}\n\n--- SORU ---\n{soru}\"\"\"\n\n# 4) Modele sor\ncevap = model.uret(istem)\u003C/code>\u003C/pre>\n\u003Cp>Bu yaklaşımın üç kazancı var: cevap güncel belgeye dayanır, kaynağı gösterilebilir, ve model bilmediğinde susmaya yönlendirilir. Fine-tuning'in aksine belge güncellendiğinde modeli yeniden eğitmeniz gerekmez — sadece dizini tazelersiniz.\u003C/p>\n\n\u003Ch2>İstemi Nasıl Yazmalı?\u003C/h2>\n\u003Cp>Modelin nasıl çalıştığını bilmek, istemi (prompt) yazarken doğrudan işe yarar. Model bir sonraki parçayı bağlama bakarak seçtiğine göre, istem aslında \u003Cem>o bağlamı kurma işidir\u003C/em>.\u003C/p>\n\u003Cp>Üç kural, pratikte farkın büyük kısmını açıklar:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Kural\u003C/th>\u003Cth>Neden işe yarıyor\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Rolü ve hedef okuru söyle\u003C/td>\u003Ctd>Bağlamı daraltır, üslubu belirler\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Çıktının biçimini örnekle göster\u003C/td>\u003Ctd>Model biçimi de tahmin eder; örnek en güçlü ipucudur\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Neyi yapmayacağını da yaz\u003C/td>\u003Ctd>\"Bilmiyorsan söyle\" demeden model susmayı seçmez\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Aynı işi isteyen iki istem arasındaki fark genellikle şudur:\u003C/p>\n\u003Cpre>\u003Ccode>Zayıf:\n  \"Bu logu incele.\"\n\nGüçlü:\n  \"Aşağıdaki IIS erişim logunu inceleyen bir sistem yöneticisisin.\n   Yalnızca 5xx dönen istekleri listele.\n   Çıktı biçimi — her satır için tek satır:\n     &lt;saat&gt; | &lt;durum&gt; | &lt;yol&gt; | &lt;olası sebep&gt;\n   Sebebi logdan çıkaramıyorsan 'belirsiz' yaz, tahmin etme.\n\n   --- LOG ---\n   {log}\"\u003C/code>\u003C/pre>\n\u003Cp>Uzun istem her zaman iyi istem değildir: bağlama koyduğunuz her gereksiz cümle hem maliyeti artırır hem de attention'ı asıl işten uzaklaştırır. İyi istem uzun değil, \u003Cstrong>belirsizliği az\u003C/strong> olandır.\u003C/p>\n\n\u003Ch2>Geliştirici İçin Ne Anlama Geliyor?\u003C/h2>\n\u003Cp>LLM'i sihirli bir kutu değil, olasılıksal bir bileşen olarak görmek doğru beklenti kurmayı sağlar. Kritik kararları doğrulamasız biçimde ona bırakmamak gerekir.\u003C/p>\n\u003Cp>Tasarım aşamasında hesaba katılacak somut kısıtlar şunlardır:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Kısıt\u003C/th>\u003Cth>Pratik karşılığı\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Bağlam sınırı\u003C/td>\u003Ctd>Uzun belgeler parçalanmalı, hepsi birden gönderilemez\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Token maliyeti\u003C/td>\u003Ctd>Türkçede aynı içerik ~2 kat pahalı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Gecikme\u003C/td>\u003Ctd>Cevap token token üretilir; uzun cevap uzun bekleme\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Belirsizlik\u003C/td>\u003Ctd>Aynı girdi her seferinde aynı çıktıyı vermeyebilir\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Doğrulanabilirlik\u003C/td>\u003Ctd>Sayı ve kaynak içeren cevaplar kontrol edilmeli\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>En sağlıklı kullanım, modeli bir taslak üreticisi ve hızlandırıcı olarak konumlandırıp son kontrolü insana bırakmaktır. Bu, modelin yeteneğini küçümsemek değil; nasıl çalıştığını bilerek kullanmaktır.\u003C/p>\n\n\u003Chr>\n\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Yapay Zeka ve LLM serimizde bu kavramların her birini ayrı bölümlerde ele alıyoruz: token ve embedding'den transformer'a, RAG'dan prompt mühendisliğine kadar.\u003C/p>\n\u003Cp>\u003Ca href='/videos/llm-nasil-calisir-chatgpt-bir-sonraki-kelimeyi-nasil-tahmin-ediyor'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/nJb6q5btOTI' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech' target='_blank' rel='noopener'>Kanala abone ol\u003C/a>\u003C/p>\u003Chr>\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Dil modellerinin bir sonraki kelimeyi nasıl tahmin ettiğini anlattığımız videoyla konuyu görsel olarak takip edebilirsiniz.\u003C/p>\u003Cp>\u003Ca href='/videos/llm-nasil-calisir-chatgpt-bir-sonraki-kelimeyi-nasil-tahmin-ediyor'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/nJb6q5btOTI' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech?sub_confirmation=1' target='_blank' rel='noopener'>Bapati kanalına abone ol\u003C/a>\u003C/p>","Büyük dil modelleri nasıl çalışır? Token, embedding, transformer ve attention kavramlarını matematiğe girmeden sade örneklerle açıklıyoruz.","https://img.youtube.com/vi/nJb6q5btOTI/hqdefault.jpg","Büyük dil modelleri nasıl çalışır? Token, embedding, transformer ve attention kavramları matematiğe girmeden, sade ve somut örneklerle anlatılıyor.","llm, büyük dil modeli, chatgpt, transformer, attention, token, embedding, yapay zeka, makine öğrenmesi, halüsinasyon, prompt mühendisliği",7,[185],{"tagId":186,"name":187,"color":188},"b663cf80-0dcf-4f2e-a02a-bbc427882f88","AI","#ff6f61","2026-07-27T19:02:02.3265184","2026-08-23T13:45:16.4617192",{"articleId":192,"title":193,"slug":194,"content":195,"summary":196,"featuredImage":197,"metaTitle":193,"metaDescription":198,"metaKeywords":199,"isPublished":15,"publishedAt":200,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":183,"authorId":19,"categoryId":5,"categoryName":6,"tags":201,"isActive":15,"isDeleted":16,"createDate":202,"updatedDate":203,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},"d4e895c5-9974-435d-b451-542728d7aa47","Active Directory Nedir? Domain, OU, GPO ve Kullanıcı Yönetimi","active-directory-nedir-domain-ou-gpo-kullanici-yonetimi","\u003Ch2>Active Directory Neyi Çözer?\u003C/h2>\n\u003Cp>On kişilik bir ofiste her bilgisayarın kendi kullanıcı hesabını taşıması sorun yaratmaz. Yüz kişiye çıktığınızda ise aynı yaklaşım sürdürülemez hale gelir: parola değişikliği yüz makineye tek tek gitmek, işten ayrılan birinin erişimini kesmek ise unutulan bir makinede açık kalan bir kapı demektir.\u003C/p>\n\u003Cp>Active Directory (AD), kullanıcıları, bilgisayarları ve yetkileri tek bir merkezde toplayan dizin hizmetidir. Bir kullanıcıyı bir kez tanımlarsınız; o kullanıcı ağdaki tüm kaynaklara aynı kimlikle erişir. Devre dışı bırakmak da tek bir işleme iner.\u003C/p>\n\u003Cp>Aşağıdaki tablo, aynı işin iki yaklaşımda ne kadar sürdüğünü kabaca özetliyor. Sayılar 100 kullanıcılı tipik bir ortam içindir.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>İşlem\u003C/th>\u003Cth>Dağıtık (yerel hesaplar)\u003C/th>\u003Cth>Active Directory\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Yeni çalışan tanımlama\u003C/td>\u003Ctd>Her makinede ayrı hesap\u003C/td>\u003Ctd>Tek nesne, tüm ağda geçerli\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>İşten ayrılan erişimi kesme\u003C/td>\u003Ctd>Makine makine dolaşmak\u003C/td>\u003Ctd>Hesabı devre dışı bırakmak\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Parola politikası uygulama\u003C/td>\u003Ctd>Makine başına ayar\u003C/td>\u003Ctd>Tek GPO, tüm domain\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Yazılım dağıtımı\u003C/td>\u003Ctd>Elle kurulum\u003C/td>\u003Ctd>GPO ya da dağıtım aracı\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Kim neye erişiyor?\u003C/td>\u003Ctd>Cevaplanması zor\u003C/td>\u003Ctd>Grup üyeliğinden okunur\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Buradaki asıl kazanç zamandan tasarruf değil, \u003Cstrong>hesap verebilirlik\u003C/strong>. Dağıtık yapıda \"bu klasöre kimler erişebiliyor\" sorusunun güvenilir bir cevabı yoktur.\u003C/p>\n\n\u003Ch2>Domain, Forest ve Domain Controller\u003C/h2>\n\u003Cp>Domain, ortak bir güvenlik sınırını paylaşan nesneler kümesidir. Forest ise bir veya daha fazla domain'i kapsayan en dış sınırdır. Güvenlik açısından asıl sınır forest'tır: iki domain aynı forest içindeyse, birinde yönetici olan kişi diğerini de etkileyebilecek yollara sahiptir.\u003C/p>\n\u003Cp>Domain Controller (DC), AD veritabanını barındıran ve kimlik doğrulama isteklerini karşılayan sunucudur. Tek DC ile çalışmak mümkündür ama risklidir: o sunucu düştüğünde kimse oturum açamaz. Bu yüzden üretim ortamlarında en az iki DC bulundurulur.\u003C/p>\n\u003Cp>Kurulumun kendisi grafik arayüzden yapılabilir, ancak PowerShell hem tekrarlanabilir hem de belgelenebilir olduğu için tercih edilir:\u003C/p>\n\u003Cpre>\u003Ccode># Rolü kur (henüz domain oluşmaz)\nInstall-WindowsFeature AD-Domain-Services -IncludeManagementTools\n\n# Yeni bir orman ve ilk domain'i oluştur\nInstall-ADDSForest `\n  -DomainName \"bapati.local\" `\n  -DomainNetbiosName \"BAPATI\" `\n  -InstallDns `\n  -DomainMode WinThreshold `\n  -ForestMode WinThreshold\n\n# İkinci DC'yi mevcut domain'e ekle (ayrı sunucuda)\nInstall-ADDSDomainController `\n  -DomainName \"bapati.local\" `\n  -InstallDns `\n  -Credential (Get-Credential)\u003C/code>\u003C/pre>\n\u003Cp>Domain adı seçimi sonradan değiştirilmesi en zor kararlardan biridir. \u003Ccode>.local\u003C/code> gibi uydurma bir uzantı yerine, sahip olduğunuz bir alan adının alt bölümünü kullanmak (\u003Ccode>ic.bapati.com\u003C/code> gibi) sertifika ve dış entegrasyon işlerini yıllar sonra kolaylaştırır.\u003C/p>\n\n\u003Ch2>AD ve DNS Ayrılmaz İkilidir\u003C/h2>\n\u003Cp>Active Directory'nin DNS'e bağımlılığı çoğu zaman hafife alınır. İstemciler, hangi sunucunun Domain Controller olduğunu DNS üzerindeki SRV kayıtlarından öğrenir. Bu kayıtlar yoksa AD, çalışıyor olmasına rağmen bulunamaz.\u003C/p>\n\u003Cp>Sorunun belirtisi genellikle \"domain'e katılamıyorum\" ya da \"oturum açma çok yavaş\" olur; kaynağı ise neredeyse her zaman ad çözümlemesidir. İlk bakılacak yer şudur:\u003C/p>\n\u003Cpre>\u003Ccode># DC'yi ilan eden SRV kaydı gerçekten var mı?\nnslookup -type=SRV _ldap._tcp.dc._msdcs.bapati.local\n\n# İstemcinin gördüğü DNS sunucusu hangisi?\nGet-DnsClientServerAddress -AddressFamily IPv4\n\n# DC'nin kendi sağlık kontrolü\ndcdiag /test:dns /v\u003C/code>\u003C/pre>\n\u003Cp>Pratik kural: \u003Cstrong>domain üyesi makineler birincil DNS olarak her zaman Domain Controller'ı göstermelidir\u003C/strong>, doğrudan bir public DNS'i değil. Dış adlara erişim, DC üzerindeki yönlendirici (forwarder) ayarıyla çözülür.\u003C/p>\n\n\u003Ch2>Organizational Unit (OU): Sadece Klasör Değil\u003C/h2>\n\u003Cp>OU'lar ilk bakışta düzen amaçlı klasörler gibi görünür. Asıl işlevleri ise Group Policy'nin uygulanma noktası ve yetki devrinin sınırı olmalarıdır. Bu yüzden OU yapısını departmanlara göre değil, \u003Cstrong>uygulanacak politikalara ve yetki devrine göre\u003C/strong> tasarlamak daha sağlıklı sonuç verir.\u003C/p>\n\u003Cp>Departman temelli bir ağaç ilk yıl düzenli görünür; şirket büyüyüp bir kişi iki departmanda çalışmaya başladığında ya da politika bir departmanın yalnızca yarısına uygulanması gerektiğinde çatlar.\u003C/p>\n\u003Cpre>\u003Ccode># Kullanıcı ve bilgisayar nesnelerini ayrı tutan basit bir iskelet\nNew-ADOrganizationalUnit -Name \"Bapati\" -Path \"DC=bapati,DC=local\"\nNew-ADOrganizationalUnit -Name \"Kullanicilar\" -Path \"OU=Bapati,DC=bapati,DC=local\"\nNew-ADOrganizationalUnit -Name \"Bilgisayarlar\" -Path \"OU=Bapati,DC=bapati,DC=local\"\nNew-ADOrganizationalUnit -Name \"Servis Hesaplari\" -Path \"OU=Bapati,DC=bapati,DC=local\"\u003C/code>\u003C/pre>\n\u003Cp>Varsayılan \u003Ccode>Users\u003C/code> ve \u003Ccode>Computers\u003C/code> birer container'dır, OU değildir; onlara Group Policy bağlayamazsınız. Domain'e yeni katılan bilgisayarların doğrudan doğru OU'ya düşmesi için varsayılan hedefi değiştirmek gerekir:\u003C/p>\n\u003Cpre>\u003Ccode>redircmp \"OU=Bilgisayarlar,OU=Bapati,DC=bapati,DC=local\"\nredirusr \"OU=Kullanicilar,OU=Bapati,DC=bapati,DC=local\"\u003C/code>\u003C/pre>\n\n\u003Ch2>Gruplar ve AGDLP Kuralı\u003C/h2>\n\u003Cp>AD'de üç grup kapsamı bulunur ve hangisinin nerede kullanılacağı, özellikle çok domain'li yapılarda kritiktir.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Kapsam\u003C/th>\u003Cth>Üye alabildiği\u003C/th>\u003Cth>Tipik kullanım\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Global\u003C/td>\u003Ctd>Kendi domain'indeki hesaplar\u003C/td>\u003Ctd>Rolü/görevi temsil eder: \"Muhasebe\"\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Domain Local\u003C/td>\u003Ctd>Her domain'den hesap ve global grup\u003C/td>\u003Ctd>Kaynağa izin verilen yer: \"Muhasebe-Klasor-Yazma\"\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Universal\u003C/td>\u003Ctd>Forest'taki her domain'den\u003C/td>\u003Ctd>Çok domain'li yapılarda köprü\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Yaygın kabul gören yaklaşım \u003Cstrong>AGDLP\u003C/strong> kısaltmasıyla anılır: hesapları (\u003Cem>Account\u003C/em>) global gruplara koyun, global grupları (\u003Cem>Global\u003C/em>) domain local gruplara (\u003Cem>Domain Local\u003C/em>) üye yapın, izinleri (\u003Cem>Permission\u003C/em>) domain local gruplara verin.\u003C/p>\n\u003Cpre>\u003Ccode># A: hesap  ->  G: rol grubu\nNew-ADGroup -Name \"GG-Muhasebe\" -GroupScope Global -Path \"OU=Kullanicilar,OU=Bapati,DC=bapati,DC=local\"\nAdd-ADGroupMember -Identity \"GG-Muhasebe\" -Members \"ayse.yilmaz\",\"mehmet.demir\"\n\n# DL: kaynak grubu  ->  P: izin\nNew-ADGroup -Name \"DL-Muhasebe-Yazma\" -GroupScope DomainLocal -Path \"OU=Kullanicilar,OU=Bapati,DC=bapati,DC=local\"\nAdd-ADGroupMember -Identity \"DL-Muhasebe-Yazma\" -Members \"GG-Muhasebe\"\n\n# NTFS izni yalnızca DL gruba verilir, kullanıcıya asla\n$yol = \"D:\\Paylasim\\Muhasebe\"\n$acl = Get-Acl $yol\n$kural = New-Object System.Security.AccessControl.FileSystemAccessRule(\n  \"BAPATI\\DL-Muhasebe-Yazma\",\"Modify\",\"ContainerInherit,ObjectInherit\",\"None\",\"Allow\")\n$acl.AddAccessRule($kural)\nSet-Acl $yol $acl\u003C/code>\u003C/pre>\n\u003Cp>Bu zincire uyulduğunda bir kişinin erişimini değiştirmek tek bir grup üyeliğine iner ve yetki yapısı yıllar sonra bile okunabilir kalır. Uyulmadığında ise \"kim neye neden erişiyor\" sorusu kısa sürede cevaplanamaz hale gelir.\u003C/p>\n\n\u003Ch2>Group Policy ile Merkezi Yönetim\u003C/h2>\n\u003Cp>Group Policy (GPO), ayarları tek noktadan tanımlayıp binlerce makineye uygulamanızı sağlar. Parola politikası, ekran kilidi, yazıcı dağıtımı, yazılım kurulumu ve klasör yönlendirmesi bunların yalnızca birkaçıdır.\u003C/p>\n\u003Cp>GPO'lar dört seviyede işler ve çakışma olduğunda \u003Cstrong>en son uygulanan kazanır\u003C/strong>. Sıralamayı bilmemek, \"ayarı yaptım ama uygulanmıyor\" sorununun en yaygın nedenidir.\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Sıra\u003C/th>\u003Cth>Seviye\u003C/th>\u003Cth>Not\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Local\u003C/td>\u003Ctd>Makinenin kendi politikası, en zayıf\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Site\u003C/td>\u003Ctd>Ağ konumuna göre\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Domain\u003C/td>\u003Ctd>Tüm domain geneli\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>OU (en içteki en son)\u003C/td>\u003Ctd>En güçlü — çakışmada bu kazanır\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>İki istisna bu sırayı bozar: \u003Cem>Enforced\u003C/em> işaretlenmiş bir GPO alttakiler tarafından ezilemez, \u003Cem>Block Inheritance\u003C/em> uygulanmış bir OU üsttekileri almaz. İkisini birden kullanmak ortamı kısa sürede takip edilemez hale getirdiği için, ikisini de istisnai tutmak gerekir.\u003C/p>\n\u003Cp>Bir ayarın neden uygulanmadığını tahmin etmek yerine ölçmek mümkündür:\u003C/p>\n\u003Cpre>\u003Ccode># Politikayı hemen yenile\ngpupdate /force\n\n# Bu makine/kullanıcı hangi GPO'ları aldı, hangileri neden elendi?\ngpresult /h C:\\rapor.html /f\n\n# Uzaktan, belirli bir kullanıcı için modelleme\nGet-GPResultantSetOfPolicy -User BAPATI\\ayse.yilmaz -Computer PC-042 -ReportType Html -Path C:\\rsop.html\u003C/code>\u003C/pre>\n\n\u003Ch2>En Az Yetki Prensibi\u003C/h2>\n\u003Cp>Her işi Domain Admin hesabıyla yapmak pratik görünür ama kurumsal güvenliğin en zayıf halkasıdır. Bu hesabın ele geçirilmesi, tüm ortamın ele geçirilmesi anlamına gelir — ve bu genellikle sofistike bir saldırıyla değil, yönetici hesabıyla açılmış bir oturumda tıklanan bir ekle olur.\u003C/p>\n\u003Cp>Uygulaması kolay, etkisi yüksek üç alışkanlık:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Alışkanlık\u003C/th>\u003Cth>Neyi engeller\u003C/th>\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Günlük iş için standart hesap, yönetim için ayrı hesap\u003C/td>\u003Ctd>Yönetici oturumunda çalışan zararlının tüm ortamı ele geçirmesini\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Yardım masasına \u003Cem>Delegation of Control\u003C/em> ile sınırlı yetki\u003C/td>\u003Ctd>Parola sıfırlamak için Domain Admin verilmesini\u003C/td>\u003C/tr>\n\u003Ctr>\u003Ctd>Yönetici hesaplarıyla iş istasyonlarına oturum açmamak\u003C/td>\u003Ctd>Kimlik bilgisinin uç noktada bellekte kalmasını\u003C/td>\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Delegation, grafik arayüzde sihirbazla yapılabildiği gibi betikle de tanımlanabilir. Örneğin yardım masasına yalnızca belirli bir OU'da parola sıfırlama yetkisi vermek:\u003C/p>\n\u003Cpre>\u003Ccode>$ou   = \"OU=Kullanicilar,OU=Bapati,DC=bapati,DC=local\"\n$grup = \"BAPATI\\GG-YardimMasasi\"\n\n# Yalnızca \"Reset Password\" genişletilmiş hakkı, yalnızca bu OU altında\ndsacls $ou /I:S /G \"${grup}:CA;Reset Password;user\"\ndsacls $ou /I:S /G \"${grup}:WP;pwdLastSet;user\"\u003C/code>\u003C/pre>\n\u003Cp>Yetki devrinin sınırı OU olduğu için, OU tasarımını politika ve yetkiye göre yapma önerisi burada karşılığını buluyor.\u003C/p>\n\n\u003Ch2>Yedekleme Olmadan Hiçbiri Anlamlı Değil\u003C/h2>\n\u003Cp>AD'nin geri dönüşü, düzgün alınmış bir \u003Cstrong>System State\u003C/strong> yedeğine bağlıdır. Bu yedek AD veritabanını (\u003Ccode>ntds.dit\u003C/code>), SYSVOL'ü ve registry'yi kapsar. Sanal makinenin anlık görüntüsü bunun yerini tutmaz: eski bir anlık görüntüye dönmek çoğaltmayı bozabilir.\u003C/p>\n\u003Cpre>\u003Ccode># System State yedeği (Windows Server Backup kurulu olmalı)\nwbadmin start systemstatebackup -backupTarget:E: -quiet\n\n# Geri Dönüşüm Kutusu'nu etkinleştir (bir kez açılır, kapatılamaz)\nEnable-ADOptionalFeature \"Recycle Bin Feature\" `\n  -Scope ForestOrConfigurationSet `\n  -Target \"bapati.local\"\n\n# Yanlışlıkla silinen bir kullanıcıyı üyelikleriyle birlikte geri getir\nGet-ADObject -Filter 'Name -like \"*Yilmaz*\"' -IncludeDeletedObjects |\n  Restore-ADObject\u003C/code>\u003C/pre>\n\u003Cp>AD Recycle Bin, silinen nesneyi grup üyelikleriyle birlikte dakikalar içinde geri getirir ve gündelik hataların büyük kısmını çözer. Ancak bir DC'nin donanım arızası, veritabanı bozulması ya da fidye yazılımı gibi durumlarda tek çare System State yedeğidir.\u003C/p>\n\u003Cp>Son bir hatırlatma: \u003Cstrong>test edilmemiş yedek, yedek değildir.\u003C/strong> Geri dönüş provasını izole bir ortamda yılda en az bir kez yapmak, felaket anında öğrenilecekleri sakin bir günde öğrenmenizi sağlar.\u003C/p>\n\n\u003Ch2>Nereden Başlamalı?\u003C/h2>\n\u003Cp>Sıfırdan kuran biri için makul bir sıra şudur: önce tek DC ve DNS ile çalışan bir laboratuvar kurun, ardından OU iskeletini ve bir parola politikası GPO'sunu ekleyin, sonra AGDLP ile bir paylaşımı yetkilendirin. Bu üç adım AD'nin günlük kullanımının büyük kısmını kapsar. İkinci DC, DHCP ve yedekleme bunun üzerine rahatça oturur.\u003C/p>\n\n\u003Chr>\n\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Bu konuların tamamını uygulamalı olarak anlattığımız Active Directory eğitim serisi 26 bölümden oluşuyor: kurulumdan GPO'ya, DHCP'den yedeklemeye kadar adım adım ilerliyoruz.\u003C/p>\n\u003Cp>\u003Ca href='/videos/adim-adim-active-directory-kurulumu-dc-dns-dhcp-adc-gc-1'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/aFkACN9hrSU' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech' target='_blank' rel='noopener'>Kanala abone ol\u003C/a>\u003C/p>\u003Chr>\u003Cp>\u003Cstrong>Daha fazlası:\u003C/strong> Active Directory kurulumunu ve yönetimini sıfırdan anlattığımız seriyle konuyu uygulamalı takip edebilirsiniz.\u003C/p>\u003Cp>\u003Ca href='/videos/adim-adim-active-directory-kurulumu-dc-dns-dhcp-adc-gc-1'>Videoyu sitemizde izle\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://youtu.be/aFkACN9hrSU' target='_blank' rel='noopener'>YouTube'da aç\u003C/a> &nbsp;·&nbsp; \u003Ca href='https://www.youtube.com/@BapatiTech?sub_confirmation=1' target='_blank' rel='noopener'>Bapati kanalına abone ol\u003C/a>\u003C/p>","Active Directory nedir, kurumsal ağda ne işe yarar? Domain, OU, GPO ve kullanıcı yönetimi kavramlarını sahadan örneklerle ele alıyoruz.","https://img.youtube.com/vi/aFkACN9hrSU/hqdefault.jpg","Active Directory nedir, nasıl çalışır? Domain, OU, grup ilkesi ve kullanıcı yönetimi kavramları sahadan örneklerle sade biçimde anlatılıyor.","active directory, domain controller, organizational unit, group policy, gpo, kullanıcı yönetimi, windows server, kurumsal ağ, sistem yöneticisi, dns, dhcp","2026-07-27T22:01:58",[],"2026-07-27T19:02:01.6429816","2026-08-23T13:45:15.745448",24,[206,208,211],{"articleId":119,"title":120,"slug":121,"content":122,"summary":123,"featuredImage":124,"metaTitle":120,"metaDescription":125,"metaKeywords":126,"isPublished":15,"publishedAt":127,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":129,"authorId":19,"categoryId":21,"categoryName":22,"tags":207,"isActive":15,"isDeleted":16,"createDate":131,"updatedDate":132,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},[],{"articleId":134,"title":135,"slug":136,"content":137,"summary":138,"featuredImage":139,"metaTitle":135,"metaDescription":140,"metaKeywords":141,"isPublished":15,"publishedAt":127,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":129,"authorId":19,"categoryId":63,"categoryName":64,"tags":209,"isActive":15,"isDeleted":16,"createDate":147,"updatedDate":148,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},[210],{"tagId":144,"name":145,"color":146},{"articleId":150,"title":151,"slug":152,"content":153,"summary":154,"featuredImage":155,"metaTitle":151,"metaDescription":156,"metaKeywords":157,"isPublished":15,"publishedAt":127,"references":13,"authors":13,"viewCount":128,"likeCount":128,"commentCount":128,"readingTime":129,"authorId":19,"categoryId":52,"categoryName":53,"tags":212,"isActive":15,"isDeleted":16,"createDate":159,"updatedDate":160,"deletedDate":13,"createdUserId":19,"updatedUserId":19,"deletedUserId":13},[],1789725833917]