Turk Ninja youtube kanalı açıldı. Buradan ulaşabilirsiniz.


Turk Ninja youtube kanalı açıldı. Buradan ulaşabilirsiniz.

Spring Framework'ün tarihçesi


Spring Framework, Java platformu için kapsamlı bir programlama ve yapılandırma modeli sunan popüler bir uygulama geliştirme çerçevesidir. Rod Johnson tarafından geliştirilen Spring, ilk olarak 2002 yılında "Expert One-on-One J2EE Design and Development" adlı kitapta ortaya kondu. Spring Framework, J2EE (şimdi Jakarta EE olarak bilinir) uygulamalarının geliştirilmesini daha kolay hale getirmek amacıyla tasarlanmıştır.



Spring'in ilk resmi sürümü (Spring Framework 1.0), Mart 2004'te yayımlandı. Bu sürüm, JavaBeans konfigürasyonunu, programatik işlem yönetimini ve JDBC abstraction katmanını içeren temel özellikleri sunuyordu. O zamandan bu yana, Spring sürekli olarak gelişti ve birçok yeni özellik ekledi.


Spring 2.0 (Ekim 2006) ile birlikte, XML tabanlı yapılandırma dosyalarına ek olarak anotasyon tabanlı yapılandırmayı ve Aspect-Oriented Programming (AOP) desteğini tanıttı.


Spring 3.0 (Aralık 2009) sürümü, Java 5 üzerinde çalışan ilk Spring sürümü oldu ve genel anotasyon tabanlı yapılandırma desteğini genişletti, REST web servislerine yönelik desteği artırdı.


Spring 4.0 (Aralık 2013) Java 8 desteği, WebSocket programlama modeli ve daha fazlasını ekleyerek modern Java geliştirme trendlerine uyum sağladı.


Spring 5.0 (Eylül 2017), Spring Framework'ün reaktif programlama modelini destekleyen ilk büyük sürümüydü. Bu sürüm ayrıca JDK 9 modülerliği, Kotlin dili için daha iyi destek ve çeşitli core API iyileştirmeleri sundu.


Spring'in popülerliği, Spring Boot, Spring Cloud ve Spring Security gibi ekosistemdeki diğer projelerin gelişimiyle daha da arttı. Spring Boot, bağımsız, üretim kalitesindeki Spring tabanlı uygulamaların kolayca oluşturulmasını sağlar, ve mikro servis mimarileri için tercih edilen bir çözüm haline geldi.


Günümüzde, Spring Framework ve onun ekosistemi, kurumsal Java uygulamaları geliştirme konusunda en popüler ve güçlü araçlardan biri olmaya devam etmektedir. Her yeni sürümle birlikte, geliştiricilerin modern web uygulamalarını daha hızlı ve daha etkili bir şekilde oluşturmasını sağlayacak yenilikler ve iyileştirmeler sunulmaktadır.


Spring Framework'ün evrimi, teknoloji dünyasındaki değişimlere ve Java topluluğunun ihtiyaçlarına yanıt olarak sürekli olarak devam etti. Özellikle bulut tabanlı uygulama geliştirme, mikro servis mimarileri ve reaktif programlama gibi alanlardaki gelişmeler, Spring ekosisteminin genişlemesinde önemli bir rol oynadı.


Spring Boot, Spring ekosistemindeki en önemli gelişmelerden biridir. Spring Boot, Spring tabanlı uygulamaların yapılandırmasını büyük ölçüde basitleştirerek ve otomatikleştirerek, geliştirme sürecini hızlandırmıştır. Geliştiriciler artık boilerplate kod yazmadan ve karmaşık yapılandırma dosyaları ile uğraşmadan Spring uygulamalarını kolayca oluşturabilir, paketleyebilir ve dağıtabilirler. Spring Boot'un bu yaklaşımı, özellikle mikro servisler ve bulut tabanlı uygulamalar için idealdir.


Spring Cloud, bulut tabanlı mikro servis mimarilerini desteklemek için geliştirilmiş bir dizi araç ve kütüphaneden oluşur. Spring Cloud, hizmet keşfi, yapılandırma yönetimi, mesajlaşma, yük dengesi ve devre kesici gibi mikro servis desenlerini kolayca uygulamanıza olanak tanır. Bu, geliştiricilerin dağıtık sistemler oluşturmasını ve yönetmesini daha basit ve daha esnek hale getirir.


Spring Framework 5 ve sonraki sürümleri, reaktif programlama modelini tam anlamıyla benimsemiştir. Bu model, yüksek hacimli, düşük gecikmeli ve kaynak verimli uygulamalar oluşturmak için tasarlanmıştır. Reactor kütüphanesi üzerine inşa edilmiş olan Spring WebFlux, Spring 5 ile birlikte tanıtıldı ve reaktif web uygulamalarının oluşturulmasını sağlar. Bu, özellikle gecikme süresi düşük ve yüksek performans gerektiren uygulamalar için büyük bir avantaj sağlar.


Spring Security, güvenlik konularına odaklanan başka bir önemli projedir. Spring Security, uygulamaları yetkilendirme, kimlik doğrulama ve koruma gibi güvenlik tehditlerine karşı korumak için kapsamlı bir güvenlik çerçevesi sağlar. Modern güvenlik gereksinimlerine uyum sağlamak için sürekli olarak güncellenmektedir.


Spring Framework ve onun çevresindeki projeler, modern uygulama geliştirme pratiğinde önemli bir yer tutmaktadır. Açık kaynak olmaları, geniş bir topluluk tarafından desteklenmeleri ve sürekli olarak yenilikçi özellikler eklemeleri, Spring'i Java dünyasında lider bir çerçeve haline getirmiştir. Günümüzde, Spring ekosistemi, geliştiricilere uygulamalarını hızlı bir şekilde geliştirmeleri, test etmeleri ve ölçeklendirmeleri için güçlü araçlar ve kütüphaneler sunmaya devam etmektedir. Bu sürekli yenilik ve adaptasyon, Spring'in gelecekte de Java uygulama geliştirmede merkezi bir rol oynamaya devam edeceğinin bir göstergesidir.

Softtech 2024 Teknoloji Raporu


 


Rapora buradan ulaşabilirsiniz...





Key Project Driver - Temel Proje Dinamiği nedir? Örnek senaryolar ile anlatır mısın?



"Key Project Driver" ifadesi Türkçeye "Ana Proje Sürücüsü" veya "Temel Proje Dinamiği" olarak çevrilebilir. Bu terim, genellikle bir projenin başarısını doğrudan etkileyen ana faktörleri veya unsurları ifade etmek için kullanılır. Proje yönetiminde, bu "sürücüler" proje hedeflerine ulaşmada kritik öneme sahip olan faktörlerdir ve genellikle proje planlaması ve yönetimi sırasında dikkate alınır. Bu terim aynı zamanda proje sonuçlarını en çok etkileyen değişkenler veya koşullar anlamına da gelebilir ve proje başarısını maksimize etmek için bu sürücülerin yönetilmesi gerektiğini vurgular.



Örnek senaryolar ile anlatır mısın?


Elbette, "Key Project Driver" yani proje için anahtar sürücülerin nasıl işlediğine dair birkaç örnek senaryo üzerinden açıklama yapalım:


Örnek Senaryo 1: Yeni Ürün Geliştirme Projesi

Bir teknoloji şirketi, piyasaya sürülecek yeni bir akıllı telefon geliştirmektedir. Bu projenin anahtar sürücüleri şunlar olabilir:


Teknolojik Yenilik: Telefonun piyasada öne çıkmasını sağlayacak yenilikçi özellikler.

Pazarlama Stratejisi: Ürünün hedef kitlesine ulaşmasını sağlayacak etkili bir pazarlama planı.

Zamanlama: Ürünün piyasa trendlerine uygun bir zamanda piyasaya sürülmesi.

Bu durumda, proje yöneticisi ve takımı, bu üç anahtar sürücü üzerinde odaklanarak projenin başarılı olmasını sağlamak için stratejiler geliştirmelidir.


Örnek Senaryo 2: Yazılım Geliştirme Projesi

Bir yazılım şirketi, yeni bir mobil uygulama geliştirmektedir. Bu projenin anahtar sürücüleri şunlar olabilir:


Kullanıcı Deneyimi (UX): Kullanıcıların uygulamayı kolay ve verimli bir şekilde kullanabilmesi.

Güvenlik: Kullanıcı verilerinin korunması ve güvenlik ihlallerinin önlenmesi.

Performans: Uygulamanın hızlı ve sorunsuz çalışması.

Projede başarıya ulaşmak için, ekip bu faktörlere öncelik vererek geliştirme ve test süreçlerini yönetmelidir.


Örnek Senaryo 3: Altyapı Geliştirme Projesi

Bir belediye, yeni bir toplu taşıma sistemi kurmaktadır. Projenin anahtar sürücüleri şunlar olabilir:


Bütçe Yönetimi: Projeyi tahsis edilen bütçe içinde tamamlamak.

Toplumsal Kabul: Projenin yerel halk tarafından kabul görmesi ve desteklenmesi.

Çevresel Etki: Projenin çevreye olan etkisinin minimize edilmesi.

Bu proje için başarı, bu üç temel sürücüyü dikkate alarak planlama ve uygulama yapılmasına bağlıdır.


Sonuç

Her bir örnek, projenin türüne bağlı olarak farklı anahtar sürücülerin olabileceğini göstermektedir. Proje yöneticileri, bu sürücüleri tanımlamak ve yönetmek için stratejik planlama yapmalıdır. Bu sürücülerin doğru yönetimi, projenin hedeflerine ulaşmasında kritik bir rol oynar.

Proje yönetimi Iron Triangle nedir?



Proje yönetimi içinde "iron triangle" veya Türkçesiyle "demir üçgen", proje yönetiminin üç temel kısıtlamasını ifade eder: kapsam, zaman ve maliyet. Bu üçgen, projelerin başarısının bu üç ana faktörün dengesine bağlı olduğunu vurgular. Demir üçgen modeli, herhangi bir projenin yönetilmesi sırasında bu üç faktör arasındaki ilişkiyi gösterir ve projenin başarılı olabilmesi için bu üç faktörün birbirleriyle uyum içinde olması gerektiğini öne sürer. Bu faktörlerden herhangi birinde yapılan değişikliklerin diğer iki faktör üzerinde etkileri olacaktır. Örneğin, projenin kapsamının genişletilmesi genellikle daha fazla zaman ve/veya maliyet gerektirir. Demir üçgen, projenin kalitesini de dolaylı olarak etkileyebilir; çünkü kapsam, zaman ve maliyet arasındaki dengenin bozulması projenin kalitesini olumsuz yönde etkileyebilir.



Kapsam: Projede yer alacak işlerin ve hedeflerin tamamını ifade eder. Projenin neyi başarması gerektiğini tanımlar.

Zaman: Projenin tamamlanması için gereken süreyi ifade eder. Bu, projenin başlangıç ve bitiş tarihleri arasındaki zaman dilimini kapsar.

Maliyet: Projeyi tamamlamak için gereken toplam finansal kaynağı ifade eder. Bu, işgücü, malzemeler, teknoloji ve diğer tüm giderleri içerir.

Demir üçgen modeli, proje yöneticilerinin projeleri etkili bir şekilde planlamaları, uygulamaları ve kontrol etmeleri için önemli bir araçtır. Bu model sayesinde, proje yöneticileri projelerin kapsamını, zamanını ve maliyetini dengede tutarak, projelerin başarılı bir şekilde tamamlanmasını sağlamayı hedeflerler.

Ekip Toplojisi - Conway Yasası ve Farklı Ekip Çeşitleri ve Ekiplerin Etkilişimi

"Team Topologies" kitabı, özellikle teknoloji ve iş dünyasında çalışan profesyoneller için, ekiplerin daha etkili bir şekilde organize edilmesi ve yönetilmesi konusunda değerli içgörüler ve yönlendirmeler sunar. Ekip yapılarını, amaçlarını ve etkileşimlerini yeniden düşünme ihtiyacı üzerinde durarak, okuyuculara ekip etkinliğini ve iş akışını optimize etme konusunda kapsamlı bir rehber sağlar



Organizasyon yapılarının nasıl daha etkili bir şekilde düzenlenebileceğini, ekip etkileşimlerinin ve bilişsel yükün yönetilmesinin önemini vurgular. Ayrıca, ekiplerin daha hızlı ve esnek bir şekilde çalışabilmesi için gerekli olan yapısal düzenlemeleri ve çalışma prensiplerini sunar. Kitap, teknoloji ve iş ekiplerinin daha iyi organize edilmesi, böylece hızlı ve etkili bir akışın sağlanması konusunda rehberlik eder.



Özellikle, Conway Yasası'nın yeniden canlanışına dikkat çekerken, yazılım mimarisinin ve ekip yapısının birbiriyle ne kadar uyumlu olduğunu belirtir. Ekipler arası etkileşim modelleri ve bilişsel yükü azaltma yolları da dahil olmak üzere, etkili bir organizasyon yapısının nasıl oluşturulacağına dair stratejiler sunar.


Kitabın ileri bölümlerinde, statik ve dinamik ekip topolojileri, ekip türlerinin dört temel kategorisi (yayın uyumlu ekipler, yetenek ekipleri, karmaşık alt sistem ekipleri ve platform ekipleri) ve bu ekiplerin nasıl etkileşime girebileceği detaylandırılır. Bu yapının, organizasyonlara daha esnek ve yanıt verici bir yapı kazandırdığı ve sonuç olarak iş ve teknoloji ekiplerinin daha hızlı bir şekilde ilerlemesine olanak tanıdığı vurgulanır​ (Runn)​.


Conway Yasası, teknoloji ve iş ekiplerinin yapılandırılması ve organizasyon içi iletişim yapılarının, tasarlanan sistemlerin şeklini nasıl etkilediğine dair önemli bir teoriyi sunar. 1967'de Melvin Conway tarafından ortaya atılan bu yasa, "Organizasyonlar, sistem tasarımlarını, bu organizasyonların iletişim yapılarının kopyaları olarak üretmeye zorlanır" şeklinde özetlenir. Yani, bir organizasyonun iç iletişim yapısı neyse, tasarladığı sistemler de genellikle o yapıyı yansıtır​ (Atlassian)​.


Bu yasa, ekip topolojilerinde önemli bir rol oynar çünkü ekip yapılandırmasının ve ekip arası etkileşimlerin, yazılım mimarileri üzerinde doğrudan bir etkisi olduğunu belirtir. Bu durum, özellikle büyük ve karmaşık yazılım sistemleri inşa eden organizasyonlar için geçerlidir. Organizasyonlar, işlevsel silolara (örneğin, QA, DBA veya güvenlik gibi belirli bir fonksiyonda uzmanlaşmış ekipler) veya farklı coğrafi bölgeler için satış kanalları etrafında düzenlendiklerinde, baştan sona akış için iyi mimarilere sahip yazılım sistemlerini üretme olasılıkları düşük olur​ (IT Revolution)​.


Modern yazılım geliştirme dünyasında, mikroservisler, bulut bilişim, konteynerlar ve sunucusuz teknolojiler gibi yenilikler, yerel olarak ekip performansını iyileştirebilir. Ancak organizasyon büyüdükçe, bu yeniliklerin tam faydalarını elde etmek zorlaşır. Ekiplerin kuruluşu ve aralarındaki etkileşimler genellikle geçmiş projeler ve/veya eski teknolojileri yansıtır. Bu, organizasyonun, gerçek, saha iletişim yapısını yansıtan veya taklit eden tasarımlar üretmeye zorlandığı anlamına gelir. Bu, yazılım sistemlerini tasarlarken ve inşa ederken stratejik öneme sahiptir​ (IT Revolution)​.


COVID-19 pandemisi sırasında artan uzaktan çalışma ve uzaktan iletişim araçlarının kullanımı, iletişim desenlerini ve dolayısıyla yazılım mimarisi kararlarını nasıl etkileyeceği konusunda yeni soruları da beraberinde getirdi. Fiziksel yakınlığın iletişim kalıpları üzerinde önemli bir etkisi olduğu, ancak uzaktan çalışmanın artık daha yaygın kabul görmesi ve talep edilmesiyle, bu yeni çalışma şekillerinin organizasyonlar üzerindeki etkilerinin tam olarak nasıl ortaya çıkacağının hala bilinmediği belirtiliyor​ (Thoughtworks)​.


Conway Yasası, yazılım mimarileri ve ekip yapılarını tasarlarken veya yeniden düzenlerken isomorfik kuvvetten yararlanmak için göz önünde bulundurulması gereken bir kavramdır. Bu, organizasyonun yazılım teslimat hızı üzerinde büyük bir etkiye sahip olabilecek, ekipler arası gereksiz iletişimi kısıtlayarak hızlı akışı sağlama ihtiyacını vurgular​ (IT Revolution)​.



"Team Topologies" kitabı, etkili yazılım teslimatı ve iş akışı için ekip yapılandırması üzerine dört ana ekip tipini tanımlar:


Yayın Uyumlu Ekipler (Stream-aligned teams): Bunlar, belirli bir iş domaini veya yetenek doğrultusunda sürekli iş akışına odaklanmış ekiplerdir. Yayın uyumlu ekipler, tek bir ürün veya hizmet üzerinde çalışır ve müşteri geri bildirimlerine hızla yanıt verme avantajına sahiptirler. Bu ekipler, çoğunlukla müşteriye daha yakın çalışır ve neredeyse gerçek zamanlı olarak sorunlara tepki gösterebilir.


Yetenek Ekipleri (Enabling teams): Teknik bir domainde uzmanlaşmış olan bu ekipler, yayın uyumlu ekiplerin karşılaştığı sorunları anlamak ve onlara yardımcı olmak amacıyla varlar. Kendi çözümlerini dayatmak yerine, yayın uyumlu ekiplerin kapasitelerini geliştirmeye odaklanırlar. Bu ekipler, bilgi paylaşımını kolaylaştırmak ve yayın uyumlu ekiplerin yeteneklerini geliştirmek için içeriden destek sağlar.


Karmaşık Alt Sistem Ekipleri (Complicated subsystem teams): Bu ekipler, yayın uyumlu ekipler için bilişsel yükü azaltan karmaşık alt sistemler üzerinde çalışır. Örneğin, matematiksel modeller veya yüz tanıma motorları gibi özel bilgi gerektiren sistemler üzerinde çalışabilirler. Bu ekipler var olduğunda, bir yayın uyumlu ekibin kendi başına geliştirmesi zor olan sistemleri ele alırlar.


Platform Ekipleri (Platform teams): Yayın uyumlu ekiplerin kendi işlerini otomatik olarak, bağımsız bir şekilde teslim etmelerini sağlamak için gerekli araçları, API'ları, hizmetleri ve bilgiyi sağlayan ekiplerdir. Platform ekipleri, iç hizmetler sağlayarak yayın uyumlu ekiplerin daha yüksek seviyeli hizmetler sunmasını kolaylaştırır. Bu ekiplerin odak noktası, sağladıkları hizmetlerin güvenilirliği ve yayın uyumlu ekiplerden gelen geri bildirimlerdir.


Bu dört ekip türü, organizasyonların yazılım teslimatını hızlandırmak ve sürekli iyileştirmek için nasıl yapılandırılabileceğine dair bir çerçeve sunar. Ekip topolojileri, hızlı ve güvenli sonuçlar elde etmek için gerekli olan ekip etkileşim modellerini ve yazılım mimarilerini şekillendirmede kritik bir rol oynar.

Yayın uyumlu ekipler (Stream-aligned teams), 


"Team Topologies" yaklaşımında merkezi bir role sahiptir ve modern yazılım geliştirme ve ürün yönetiminde giderek daha fazla önem kazanmaktadır. Bu ekipler, belirli bir iş akışı, ürün, hizmet veya işlevsellik etrafında organize edilir ve bu odaklanma, müşteri ihtiyaçlarına ve geri bildirimlerine hızlı bir şekilde yanıt verebilmelerini sağlar. Bu ekip yapısı, aşağıdaki özelliklere sahiptir:


Müşteri Odaklılık: Yayın uyumlu ekipler, doğrudan müşterilerle etkileşime girerek veya müşteri geri bildirimlerini toplayarak müşteri ihtiyaçlarını anlama konusunda önceliklidir. Bu, ürün veya hizmetin sürekli olarak iyileştirilmesini sağlar.


Esneklik ve Hız: Bu ekipler, hızlı karar verme ve uygulama yetenekleri sayesinde piyasadaki değişikliklere veya teknolojik gelişmelere çabuk uyum sağlayabilir. Bu, rekabet avantajı sağlar ve müşteri memnuniyetini artırır.


Çapraz Fonksiyonellik: Yayın uyumlu ekipler genellikle çeşitli disiplinlerden uzmanları içerir. Yazılım geliştiriciler, ürün yöneticileri, kalite güvence uzmanları ve kullanıcı deneyimi tasarımcıları gibi farklı roller, aynı hedeflere ulaşmak için birlikte çalışır.


Sürekli Öğrenme ve İyileştirme: Bu ekipler, sürekli öğrenme ve kendini geliştirme kültürünü benimser. Hatalardan ders almak ve süreçleri iyileştirmek için düzenli retrospektifler yaparlar.


Yayın uyumlu ekiplerin başarısında, uygun teknolojik araçların ve süreçlerin seçimi de önemlidir. Sürekli entegrasyon ve sürekli teslimat (CI/CD) gibi uygulamalar, yazılım geliştirme sürecinin hızını ve verimliliğini artırır. Ayrıca, mikroservis mimarileri ve bulut teknolojileri gibi modern yaklaşımlar, ekiplerin daha esnek ve ölçeklenebilir sistemler inşa etmesine olanak tanır.


Yayın uyumlu ekiplerin etkinliği, sadece iç dinamikleriyle sınırlı değildir; aynı zamanda diğer ekip türleriyle olan etkileşimleri de önem taşır. Yetenek ekipleri, karmaşık alt sistem ekipleri ve platform ekipleri ile olan işbirlikleri, genel organizasyonel hedeflere ulaşmada kritik rol oynar. Bu işbirlikleri sayesinde, yayın uyumlu ekipler kendi alanlarındaki sorunlara odaklanabilirken, organizasyon genelindeki bilgi paylaşımı ve sinerji artar.


Bu yaklaşım, modern iş dünyasının hızla değişen gereksinimlerine yanıt vermek için esnek ve dinamik ekip yapılarının nasıl oluşturulabileceğine dair değerli içgörüler sunar.


Yetenek ekipleri (Enabling teams), 


organizasyonların yazılım geliştirme süreçlerini iyileştirmek ve hızlandırmak için kritik bir rol oynar. Bu ekiplerin asıl amacı, teknik yetkinlikler veya metodolojiler konusunda yayın uyumlu ekiplere destek sağlamak ve onların kendilerini geliştirmelerine yardımcı olmaktır. Yayın uyumlu ekiplerin karşılaştığı zorlukları anlamak ve bu ekiplere rehberlik etmek, yetenek ekiplerinin temel görevidir.


Yetenek ekipleri, özellikle yeni teknolojiler, yazılım geliştirme pratikleri veya araçlar konusunda uzmanlaşmıştır. Bu ekipler, yayın uyumlu ekiplerin ihtiyaç duyduğu bilgi ve becerileri geliştirmelerine yardımcı olmak için tasarlanmıştır. Yayın uyumlu ekiplerin karşılaştığı teknik zorlukların üstesinden gelmelerine yardımcı olarak, organizasyon genelinde bilgi akışını ve öğrenmeyi teşvik ederler.


Yetenek ekipleri, yayın uyumlu ekiplere doğrudan müdahale etmek yerine, onları güçlendirir ve destekler. Bu, yayın uyumlu ekiplerin bağımsızlığını ve özerkliğini korurken, aynı zamanda onların daha etkili ve verimli çalışmalarını sağlar. Yayın uyumlu ekipler, yetenek ekiplerinden aldıkları destekle, kendi sorumluluk alanlarındaki zorluklarla daha iyi başa çıkabilir ve daha yenilikçi çözümler geliştirebilirler.


Örneğin, bir yetenek ekibi, mikroservis mimarileri, konteynerizasyon veya sürekli entegrasyon ve sürekli teslimat (CI/CD) gibi alanlarda uzmanlaşmış olabilir. Bu ekibin görevi, bu konularda yayın uyumlu ekiplere eğitim ve danışmanlık sağlamak, en iyi uygulamaları ve başarı hikayelerini paylaşmak ve yayın uyumlu ekiplerin bu tekniklerden tam olarak yararlanmalarını sağlamak olacaktır.


Sonuç olarak, yetenek ekipleri, yayın uyumlu ekiplerin teknik kapasitelerini artırarak ve onları yeni teknolojiler ve metodolojiler konusunda bilgilendirerek, organizasyonun genel performansını ve rekabet gücünü artırır. Bu yaklaşım, bilgi ve becerilerin organizasyon genelinde yayılmasını sağlar ve yenilikçi çözümlerin daha hızlı bir şekilde geliştirilmesine olanak tanır.



Karmaşık alt sistem ekipleri (Complicated subsystem teams), 


"Team Topologies" yaklaşımının bir parçası olarak, organizasyonların bilişsel yük yönetimi ve uzmanlık derinliğine odaklanmasına olanak tanır. Bu ekipler, genellikle yüksek düzeyde teknik uzmanlık gerektiren, karmaşık ve özelleşmiş sistemlerin geliştirilmesinden sorumludur. Yayın uyumlu ekiplerin genel iş akışını kesintiye uğratmadan, bu karmaşık sistemler üzerinde çalışarak, tüm organizasyonun verimliliğini ve etkinliğini artırırlar.


Bu yaklaşımın avantajlarından bazıları şunlardır:


Bilişsel Yükün Azaltılması: Karmaşık alt sistem ekipleri, yayın uyumlu ekiplerin üzerindeki bilişsel yükü azaltır. Bu, yayın uyumlu ekiplerin daha genel ve müşteri odaklı sorunlara odaklanmasına, karmaşık teknik detaylarla boğulmadan ürün ve hizmetlerini geliştirmeye devam etmesine olanak tanır.


Uzmanlık Derinliği: Karmaşık alt sistem ekipleri, özel bilgi gerektiren alanlarda derin uzmanlığa sahiptir. Bu, yüksek performanslı, güvenilir ve ölçeklenebilir sistemlerin geliştirilmesini sağlar. Örneğin, yapay zeka, büyük veri analizi, kriptografi gibi alanlarda uzmanlaşmış ekipler, bu teknolojilerin organizasyon genelinde etkili bir şekilde kullanılmasını sağlar.


Yenilik ve Araştırma: Karmaşık alt sistem ekipleri, sadece mevcut sistemlerin bakımı ve iyileştirilmesiyle sınırlı değildir; aynı zamanda yeni teknolojilerin araştırılması ve geliştirilmesinde de kritik bir role sahip olabilirler. Bu, organizasyonun teknoloji ve inovasyon alanında rekabet avantajı elde etmesine yardımcı olur.


Risk Yönetimi: Karmaşık sistemler üzerinde çalışan bu ekipler, potansiyel riskleri daha iyi tanımlayabilir ve yönetebilir. Bu, sistemin genel güvenilirliğini artırır ve potansiyel hataların veya güvenlik açıklarının erken bir aşamada tespit edilip çözülmesine olanak tanır.


Karmaşık alt sistem ekiplerinin başarısı, uygun araçlar, teknikler ve süreçlerle desteklendiğinde maksimize olur. Mikroservis mimarileri, konteyner teknolojileri ve sürekli entegrasyon/desim süreçleri gibi modern yazılım geliştirme pratikleri, bu ekiplerin etkinliğini artırır. Ayrıca, ekip üyeleri arasındaki etkili iletişim ve işbirliği, karmaşık teknik zorlukların üstesinden gelmede kritik öneme sahiptir.


Sonuç olarak, karmaşık alt sistem ekipleri, modern teknoloji ekosistemlerinde giderek daha karmaşık hale gelen sistemlerin geliştirilmesi ve yönetilmesinde kilit bir role sahiptir. Bu ekipler, organizasyonların teknik mükemmellik ve yenilikçilik hedeflerine ulaşmalarına önemli ölçüde katkıda bulunur.


Platform ekipleri, 


"Team Topologies" yaklaşımında önemli bir yere sahip olan ve yazılım geliştirme süreçlerinde kritik bir rol oynayan ekiplerdir. Bu ekipler, yayın uyumlu ekiplerin ve diğer ekip türlerinin daha verimli ve etkili bir şekilde çalışmalarını sağlayan araçlar, API'lar, hizmetler ve bilgi sağlar. Platform ekiplerinin odak noktası, sağladıkları hizmetlerin güvenilirliğini ve kalitesini maksimize etmek ve yayın uyumlu ekiplerin ihtiyaçlarına yanıt vermektir.


Platform ekiplerinin temel görevleri ve sağladığı avantajlar şunlardır:


Etkinlik ve Verimlilik: Platform ekipleri, yayın uyumlu ekiplerin kendi işlerini daha etkin ve verimli bir şekilde yürütebilmeleri için gerekli altyapıyı ve araçları sağlar. Bu, geliştirme süreçlerini hızlandırır ve ürünün piyasaya sürülme süresini kısaltır.


Otomasyon ve Ölçeklenebilirlik: Sağladıkları araçlar ve hizmetler aracılığıyla, platform ekipleri süreçleri otomatize etmeye ve sistemlerin ölçeklenebilirliğini artırmaya yardımcı olur. Bu, organizasyonların büyüme ve değişen ihtiyaçlara uyum sağlama kapasitesini güçlendirir.


Yüksek Seviyeli Hizmet Sunumu: Platform ekipleri tarafından sunulan iç hizmetler, yayın uyumlu ekiplerin daha karmaşık olmayan, tekrarlanabilir görevlere daha az zaman harcamasını ve bunun yerine daha yüksek değerli işlere odaklanmasını sağlar.


Güvenilirlik ve Süreklilik: Platform ekipleri, sağladıkları hizmetlerin sürekli olarak güvenilir ve kullanılabilir olmasını sağlamak için çalışır. Bu, tüm organizasyonun genelinde sistemlerin dayanıklılığını ve sürekliliğini artırır.


Geri Bildirim ve İyileştirme: Yayın uyumlu ekiplerden gelen geri bildirimler, platform ekipleri için önemlidir. Bu geri bildirimler, platformun sürekli iyileştirilmesi ve yayın uyumlu ekiplerin ihtiyaçlarının daha iyi karşılanması için kullanılır.


Platform ekipleri, modern yazılım geliştirme ortamlarında merkezi bir öneme sahip olup, diğer ekiplerin daha hızlı, daha esnek ve daha etkili bir şekilde çalışmasına olanak tanıyan bir altyapı ve destek sistemi sağlar. Bu yaklaşım, organizasyonların teknolojiyi daha etkili bir şekilde kullanarak rekabet avantajı elde etmelerine ve müşteri memnuniyetini artırmalarına yardımcı olur.

Yazılım mülakatlarında sorulan, String konusu altındaki soruların çeşitleri, çözüm patternleri ve java ile kodlamaları

Yazılım mülakatlarında "String" konusu altında sorulan sorular genellikle belirli kategorilere ayrılabilir. Her bir kategori için tipik soru türlerini, çözüm patternlerini ve Java ile örnek kodlamaları aşağıda bulabilirsiniz. İlk olarak en sık karşılaşılan birkaç kategori ve bu kategorilere ait örnek sorularla başlayalım:





1. String Manipülasyonu ve Analizi

Bu kategori altında sorulan sorular, stringlerin değiştirilmesi, dönüştürülmesi veya analiz edilmesi ile ilgilidir. Bu tür sorular genellikle stringler arasındaki ilişkileri anlamak, belirli bir patterni bulmak veya belirli bir formata göre stringleri düzenlemek üzerine kuruludur.


Soru Örneği: String Ters Çevirme

"Soru: Bir stringi tersine çeviren bir fonksiyon yazın."


Çözüm Patterni: Bu sorunun çözümünde genellikle iki pointer kullanılır: biri stringin başında, diğeri sonunda. Bu iki pointer, string üzerinde içe doğru hareket ederek karşılıklı elemanları yer değiştirir.


Java Kodu:


java

Copy code

public String reverseString(String s) {

    char[] chars = s.toCharArray();

    int left = 0;

    int right = s.length() - 1;

    while (left < right) {

        // Karakterleri yer değiştir

        char temp = chars[left];

        chars[left] = chars[right];

        chars[right] = temp;

        

        // Pointer'ları güncelle

        left++;

        right--;

    }

    return new String(chars);

}

2. String Matching ve Arama Algoritmaları

Bu kategorideki sorular, genellikle bir string içerisinde bir alt stringin, patternin veya karakterin aranması ve bulunması ile ilgilidir. Bunlar, efektif arama algoritmaları ve string manipülasyonu tekniklerini gerektirebilir.


Soru Örneği: Substring Bulma

"Soru: Bir string içinde başka bir stringin (substring) ilk olarak bulunduğu indeksi döndüren bir fonksiyon yazın."


Çözüm Patterni: Naive bir yaklaşımda, ana string üzerinde döngü kurarak her pozisyonda substring için eşleşme aranır. Daha efektif bir çözüm için KMP (Knuth-Morris-Pratt) gibi özel arama algoritmaları kullanılabilir.


Java Kodu (Naive Approach):


java

Copy code

public int strStr(String haystack, String needle) {

    if (needle.isEmpty()) return 0;

    for (int i = 0; i <= haystack.length() - needle.length(); i++) {

        for (int j = 0; j < needle.length(); j++) {

            if (haystack.charAt(i + j) != needle.charAt(j)) break;

            if (j == needle.length() - 1) return i; // Eşleşme bulundu

        }

    }

    return -1; // Eşleşme bulunamadı

}


3. String Dönüşümleri

Bu kategori, bir string'in başka bir formata veya düzene dönüştürülmesiyle ilgili soruları içerir. Bu dönüşümler, karakterleri değiştirmeyi, kelimeleri yeniden düzenlemeyi veya belirli bir patterni takip ederek string'i yeniden formatlamayı içerebilir.


Soru Örneği: Kelimelerin Baş Harflerini Büyütme

"Soru: Bir cümledeki her kelimenin baş harfini büyük harfe çeviren bir fonksiyon yazın."


Çözüm Patterni: Bu sorunun çözümünde, öncelikle cümleyi kelimelere ayırmak gerekir. Ardından her kelimenin ilk harfini büyük harfe çevirip, kelimeleri tekrar birleştirirsiniz.


Java Kodu:


java

Copy code

public String capitalizeFirstLetter(String sentence) {

    String[] words = sentence.split(" ");

    StringBuilder result = new StringBuilder();

    

    for (String word : words) {

        if (!word.isEmpty()) {

            result.append(Character.toUpperCase(word.charAt(0)))

                  .append(word.substring(1))

                  .append(" ");

        }

    }

    

    return result.toString().trim();

}

4. String Sayı İşlemleri

Bu kategori, string olarak ifade edilen sayılarla işlem yapmayı gerektiren soruları kapsar. Bu işlemler, sayıların toplanması, çıkarılması, çarpılması veya bölünmesi gibi aritmetik işlemleri içerebilir.


Soru Örneği: String olarak verilen iki sayıyı çarpma

"Soru: İki string olarak verilen sayıyı çarpan ve sonucu string olarak döndüren bir fonksiyon yazın."


Çözüm Patterni: Bu tür bir sorun için, genellikle sayıların her bir basamağı ayrı ayrı çarpılır ve sonuçlar uygun şekilde birleştirilir. İşlem, basit çarpma işlemleri ve taşıma işlemlerini takip eder.


Java Kodu:


java

Copy code

public String multiplyStrings(String num1, String num2) {

    int m = num1.length(), n = num2.length();

    int[] pos = new int[m + n];

   

    for(int i = m - 1; i >= 0; i--) {

        for(int j = n - 1; j >= 0; j--) {

            int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');

            int sum = mul + pos[i + j + 1];

   

            pos[i + j] += sum / 10;

            pos[i + j + 1] = sum % 10;

        }

    }  

    

    StringBuilder sb = new StringBuilder();

    for(int p : pos) if(!(sb.length() == 0 && p == 0)) sb.append(p);

    return sb.length() == 0 ? "0" : sb.toString();

}

5. Palindrom Kontrolü

Palindromlar, tersten okunduğunda da aynı kalan kelimeler, ifadeler veya sayılardır. Bu tür sorular, bir string'in palindrom olup olmadığını kontrol etmeyi gerektirir.


Soru Örneği: Palindrom Kontrolü

"Soru: Verilen bir stringin palindrom olup olmadığını kontrol eden bir fonksiyon yazın."


Çözüm Patterni: Bu sorunun çözümü genellikle iki pointer kullanarak yapılır: biri stringin başında diğeri sonunda. Bu iki pointer içe doğru hareket ederken, karşılaştırma yapar.


Java Kodu:


java

Copy code

public boolean isPalindrome(String s) {

    s = s.replaceAll("[^A-Za-z0-9]", "").toLowerCase();

    int left = 0, right = s.length() - 1;

    while (left < right) {

        if (s.charAt(left) != s.charAt(right)) {

            return false;

        }

        left++;

        right--;

    }

    return true;

}

Graph veri yapısı, avantajları dezavantajları, kullanım alanları. Java ile implementasyonu

Graph  veri yapısı, avantajları dezavantajları, kullanım alanları



Graf veri yapısı, düğümler (veya köşe noktaları) ve bu düğümleri birbirine bağlayan kenarlar (veya bağlantılar) arasındaki ilişkileri modellemek için kullanılır. Graf teorisi, matematik ve bilgisayar bilimlerinde önemli bir yer tutar ve çeşitli gerçek dünya problemlerinin çözümünde kullanılır.


Avantajları

Esnek Veri Modellemesi: Graf yapısı, karmaşık ilişkileri modellemek için uygun esneklik sağlar. Hiyerarşik, ağ ve diğer karmaşık ilişkisel yapıları doğal bir şekilde ifade edebilir.

Sorgulama Gücü: Graf veri yapıları, derinlemesine arama (DFS), genişlik öncelikli arama (BFS) gibi algoritmaları kullanarak karmaşık sorguları ve veri analizlerini kolaylaştırır.

Yüksek Bağlantılı Veri İçin Uygun: Sosyal ağlar, öneri sistemleri, bağlantı analizleri gibi yüksek derecede bağlantılı veri setleri için idealdir.

Yol ve Ağ Analizleri: En kısa yol, ağ akışı, bağlantılı bileşenler gibi problemleri çözmede etkilidir.

Dezavantajları

Mekansal Verimlilik: Graf yapısı, özellikle yoğun grafiklerde, kenarların depolanması nedeniyle büyük miktarda hafıza kullanabilir.

İşlemsel Maliyet: Büyük grafikler üzerinde kompleks sorgular ve analizler işlemsel olarak pahalı olabilir. Optimizasyon ve etkin algoritmalar gerektirir.

Yönetim Zorluğu: Graf veri yapılarının yönetimi ve optimizasyonu, özellikle büyük ölçekte, karmaşık olabilir.

Algoritma Karmaşıklığı: Bazı graf algoritmaları, özellikle büyük ve karmaşık grafiklerde, yüksek zaman karmaşıklığına sahip olabilir.

Kullanım Alanları

Sosyal Ağ Analizi: Kullanıcıların birbirleriyle olan ilişkilerini analiz etmek ve öneri sistemleri geliştirmek için kullanılır.

Yol ve Ağ Optimizasyonu: GPS navigasyon sistemleri, ağ tasarımı ve optimizasyonu gibi alanlarda en kısa yol hesaplamaları yapmak için kullanılır.

Bilgi Grafları ve Öneri Sistemleri: Ürünler, filmler, haberler gibi öğeler arasındaki ilişkileri modellemek ve kişiselleştirilmiş öneriler sunmak için kullanılır.

Biyoinformatik: Genetik, proteinler ve diğer biyolojik veriler arasındaki ilişkileri analiz etmek için kullanılır.

Ağ Güvenliği: Ağ trafiğini ve saldırı modellerini analiz etmek, güvenlik ihlallerini tespit etmek için kullanılır.

Graf veri yapıları, esnekliği ve geniş uygulama yelpazesi nedeniyle birçok farklı sektörde ve problem setinde kullanılmaktadır. Ancak, kullanımlarının avantajları kadar, yönetim ve optimizasyon zorlukları da göz önünde bulundurulmalıdır.

Java ile implementasyonu


Java'da graf veri yapısını temsil etmek için çeşitli yöntemler bulunmaktadır. En yaygın iki yöntem, komşuluk matrisi ve komşuluk listesi kullanmaktır. Burada, basit bir yönlendirilmemiş graf için komşuluk listesi kullanarak bir implementasyon sunacağım. Komşuluk listesi, her düğüm için bir liste içinde o düğüme komşu olan tüm düğümlerin bir listesini tutar. Bu yöntem, kenar sayısının düğüm sayısından çok daha az olduğu seyrek grafikler için daha verimlidir.


Graf Sınıfı

İlk olarak, Graf sınıfını ve temel fonksiyonlarını tanımlayalım:


java

Copy code

import java.util.*;


// Graf sınıfı

public class Graf {

    private Map<Integer, List<Integer>> komşulukListesi;


    // Graf constructor

    public Graf() {

        komşulukListesi = new HashMap<>();

    }


    // Kenar eklemek için fonksiyon

    public void kenarEkle(int kaynak, int hedef) {

        if (!komşulukListesi.containsKey(kaynak))

            komşulukListesi.put(kaynak, new ArrayList<>());

        if (!komşulukListesi.containsKey(hedef))

            komşulukListesi.put(hedef, new ArrayList<>());


        komşulukListesi.get(kaynak).add(hedef);

        komşulukListesi.get(hedef).add(kaynak); // Yönlendirilmemiş graf için

    }


    // Grafı yazdırmak için fonksiyon

    public void grafıYazdır() {

        for (int kaynak : komşulukListesi.keySet()) {

            System.out.print("Düğüm " + kaynak + " komşuları: ");

            for (int komşu : komşulukListesi.get(kaynak)) {

                System.out.print(komşu + " ");

            }

            System.out.println();

        }

    }

}

Ana Sınıf

Grafı test etmek ve kullanmak için bir ana sınıf oluşturalım:


java

Copy code

public class Main {

    public static void main(String[] args) {

        Graf graf = new Graf();

        

        // Kenarları ekleyelim

        graf.kenarEkle(0, 1);

        graf.kenarEkle(0, 4);

        graf.kenarEkle(1, 2);

        graf.kenarEkle(1, 3);

        graf.kenarEkle(1, 4);

        graf.kenarEkle(2, 3);

        graf.kenarEkle(3, 4);

        

        // Grafı yazdıralım

        graf.grafıYazdır();

    }

}

Bu kod parçası, birkaç düğüm ve kenar içeren basit bir yönlendirilmemiş graf oluşturur ve grafın komşuluk listesini yazdırır. Java'da graf yapısını kullanarak daha karmaşık işlemler yapabilirsiniz, örneğin en kısa yol bulma, grafı gezmek için derinlik/büyüklük öncelikli arama algoritmalarını uygulayabilirsiniz. Graf teorisi ve algoritmaları, karmaşık problemleri çözmede güçlü araçlar sunar.


Komşuluk matrixi ile yap


Komşuluk matrisi kullanarak Java'da graf implementasyonu, özellikle yoğun grafiklerde veya grafın tamamının sıkça incelendiği durumlarda tercih edilir. Komşuluk matrisi, bir grafın düğümleri arasındaki kenarların varlığını ve ağırlıklarını (varsa) bir matris formunda temsil eder. Bu yöntemde, matrisin her satırı ve sütunu birer düğüme karşılık gelir. Düğümler arasında bir kenar varsa, matrisin ilgili hücresi 1 (veya kenarın ağırlığı) olarak işaretlenir; aksi takdirde 0 olarak kalır.


Graf Sınıfı

java

Copy code

public class Graf {

    private final int düğümSayısı;

    private int[][] komşulukMatrisi;


    // Graf constructor

    public Graf(int düğümSayısı) {

        this.düğümSayısı = düğümSayısı;

        komşulukMatrisi = new int[düğümSayısı][düğümSayısı];

    }


    // Kenar eklemek için fonksiyon

    public void kenarEkle(int kaynak, int hedef) {

        komşulukMatrisi[kaynak][hedef] = 1;

        komşulukMatrisi[hedef][kaynak] = 1; // Yönlendirilmemiş graf için

    }


    // Kenar silmek için fonksiyon

    public void kenarSil(int kaynak, int hedef) {

        komşulukMatrisi[kaynak][hedef] = 0;

        komşulukMatrisi[hedef][kaynak] = 0; // Yönlendirilmemiş graf için

    }


    // Grafı yazdırmak için fonksiyon

    public void grafıYazdır() {

        System.out.println("Komşuluk Matrisi:");

        for (int i = 0; i < düğümSayısı; i++) {

            for (int j = 0; j < düğümSayısı; j++) {

                System.out.print(komşulukMatrisi[i][j] + " ");

            }

            System.out.println();

        }

    }

}

Ana Sınıf

Grafı test etmek ve kullanmak için bir ana sınıf oluşturalım:


java

Copy code

public class Main {

    public static void main(String[] args) {

        int düğümSayısı = 5;

        Graf graf = new Graf(düğümSayısı);

        

        // Kenarları ekleyelim

        graf.kenarEkle(0, 1);

        graf.kenarEkle(0, 4);

        graf.kenarEkle(1, 2);

        graf.kenarEkle(1, 3);

        graf.kenarEkle(1, 4);

        graf.kenarEkle(2, 3);

        graf.kenarEkle(3, 4);

        

        // Grafı yazdıralım

        graf.grafıYazdır();

    }

}

Bu kod, bir grafın komşuluk matrisini oluşturur, bazı kenarlar ekler ve komşuluk matrisini konsola yazdırır. Komşuluk matrisi yöntemi, grafın görselleştirilmesi ve analiz edilmesi için basit ve doğrudan bir yol sunar. Ancak, seyrek grafiklerde hafıza kullanımı açısından verimsiz olabilir, çünkü matrisin büyük bir kısmı 0'larla dolu olacaktır.


Komşuluk matrixinde düğüm sayısı belli değilse?


Komşuluk matrisinde düğüm sayısının baştan belli olmadığı durumlar için Java'da dinamik bir yapı kullanmak gerekebilir. Bu tür durumlar, düğümlerin zamanla eklenip çıkarıldığı uygulamalarda karşımıza çıkabilir. Java'da ArrayList kullanarak bir komşuluk matrisini dinamik bir şekilde yönetebiliriz. Bu yöntem, matrisin boyutunu ihtiyaç duydukça artırabilir veya azaltabilir.


Dinamik Graf Sınıfı

Aşağıdaki örnekte, ArrayList'lerin ArrayList'ini kullanarak dinamik bir komşuluk matrisi oluşturduk. Bu yapı sayesinde, grafın boyutunu çalışma zamanında değiştirebiliriz.


java

Copy code

import java.util.ArrayList;


public class DinamikGraf {

    private ArrayList<ArrayList<Integer>> komşulukMatrisi;


    public DinamikGraf() {

        komşulukMatrisi = new ArrayList<>();

    }


    // Yeni bir düğüm ekler ve gerekli boyutta matrisi genişletir

    public void düğümEkle() {

        for (ArrayList<Integer> satır : komşulukMatrisi) {

            satır.add(0); // Yeni düğüm için her satıra 0 ekler

        }

        ArrayList<Integer> yeniSatır = new ArrayList<>(komşulukMatrisi.size() + 1);

        for (int i = 0; i < komşulukMatrisi.size() + 1; i++) {

            yeniSatır.add(0); // Yeni satırı 0'larla doldurur

        }

        komşulukMatrisi.add(yeniSatır); // Yeni satırı matrise ekler

    }


    // Kenar ekler

    public void kenarEkle(int kaynak, int hedef) {

        // İndeks kontrolü

        if (kaynak < komşulukMatrisi.size() && hedef < komşulukMatrisi.size()) {

            komşulukMatrisi.get(kaynak).set(hedef, 1); // Kenarı ekler

            komşulukMatrisi.get(hedef).set(kaynak, 1); // Simetrik olduğundan, yönlendirilmemiş graf için

        }

    }


    // Grafı yazdırır

    public void grafıYazdır() {

        System.out.println("Komşuluk Matrisi:");

        for (ArrayList<Integer> satır : komşulukMatrisi) {

            for (int değer : satır) {

                System.out.print(değer + " ");

            }

            System.out.println();

        }

    }

}

Ana Sınıf

Grafı test etmek için bir ana sınıf oluşturalım:


java

Copy code

public class Main {

    public static void main(String[] args) {

        DinamikGraf graf = new DinamikGraf();

        

        // Düğümleri ekleyelim

        graf.düğümEkle(); // 0. düğüm

        graf.düğümEkle(); // 1. düğüm

        graf.düğümEkle(); // 2. düğüm

        

        // Kenarları ekleyelim

        graf.kenarEkle(0, 1);

        graf.kenarEkle(1, 2);

        

        // Grafı yazdıralım

        graf.grafıYazdır();

    }

}

Bu örnekte, ArrayList kullanarak dinamik bir komşuluk matrisi yönetimi sağlanmıştır. Bu yapı, düğüm sayısı baştan belli olmayan ve çalışma zamanında değişebilen uygulamalar için uygun bir çözümdür. Ancak, bu yöntem, büyük grafiklerde veya sık sık boyut değişikliği gerektiren durumlarda performans açısından maliyetli olabilir. Optimizasyon ve performans dengesi, uygulamanın gereksinimlerine göre değerlendirilmelidir.

Rastgele İçerik

DonanımHaber

© tüm hakları saklıdır
made with by templateszoo