Genel Programming Notes 1
Genel Programming Notes 1
ArrayList Verileri saklamak için dinamik bir array kullanır. Array kullandığı için yavaştır. Eğer bir
elemanı silinirse hepsi birer kayar. Sadece list gibi davranabilir çünk sadece List interface'ini
implemente ediyor. Verilere ulaşma açısından iyidir.
Linked List birbirine bağlı doğrusal bir dizi öğeden oluşan sıralı bir yapıdır. Liked list verileri
saklamak için doubly linked list kullanır. ArrayList'ten daha hızlıdır çünkü doubly list kullanır. Bir
eleman silindiğinde kaydırma durumu yoktur. Hem bir list hem de queue gibi davranabilir
çünkü list ve Deque interface'lerini implemente eder. Veriyi işleme açısından iyidir.
Set kendisine verilen elemanların her birinin sadece bir tanesini tutar. Tekrarlanan elemanları
barındırmaz.
List nesnesi kendisine verilen elemanları sıralı bir şekilde tutar. Tekrarlananlar olabilir
Map Her biri birbirinden farklı anahtarlar ile eşleştirilen nesnelerden oluşturulur.
Sıralama Algoritmaları
Search Algoritmaları
En kötüsü linear search algoritmasıdır. BinarySearch sıralı lsiteleri arar. Yarısını böle böle gider.
Karmaşıklığı o(log n)'dir. Binary her zaman orta öğeye gider. Öte yandan Interpolation seach key
değerine göre farklı konumlara gidebilir.
Kruskal,Prim, BinarySearchTree
String algoritmaları
Boyer-Moore(Aranan kelime kaydırılır).Reverse Factor Algorithm
CAP theorem
C-Consistency: Veritabanına yazılan verilerin tutarlı olması, bütün clientların aynı veriyi görmesi.
A-Availability: Her cliend her zaman okuma ya da yazma işlemleri yapabilmeli.
P-Partition Tolerance: Sistem ağ bölünmelerine rağmen çalışır.
Docker ve Kubernetes
Docker'ın VM(Virtual Machine)'den en büyük farkı donanımları sanallaştırmaya ihtiyaç duymadan
işletim desteği ile çalışabilmesidir. Hazır imajlar docker hub'da dağıtılıyor. Docker normal
bilgisayarlarda ya da sunucularda çalışabiliyor. Bu çalışan docker api üzerinden istek atabiliyoruz. Bu
docker'ların birden fazla sunucuda çalışan hali kubernetes'dir.
Kafka vs RabbitMQ
Kafka genellikle büyük ölçekli uygulamalarda kullanılır. Saniyede bir kaç milyon mesajın üstesinden
gelebilir. Mesajlar kalıcı olur. Mesajlar kaybolmaz, persistant olarak saklanır. Dezavantajı .Net
geliştirme ortamında resmi desteği yok.
RabbitMQ, yüksek performansa ihtiyaç duyulduğunda, geliştirme ortamı .Net ise, mesajın ulaşımını
garanti altına almak gerekirse ve kafkaya göre daha az sayıda mesajlaşma yapılıyorsa kullanılır.
RabbitMQ restart olursa bütün mesajlar kaybolur.
TDD
Legacy code nedir? Testi bulunmayan, artık kullanılmayan dillere dayanan koddur. TDD aslında
bizim kodumuzun istenen ihtiyaçları karşılıyor mu? İstenen problemleri çözüyor mu? Input'lara
doğru yanıt veriyor mu? bunu gösterir. Önce fail edecek testler yazılır, sonra bu testleri geçirmeye
çalışıp refactor adımına geçilir. Refactor adımında kodumuzu nasıl daha clean yapabiliriz onu
düşünürüz.
Unit test en küçük birimlerin yani fonksiyonların test edildiği test türüdür. O fonksiyonun kendi
başına nasıl çalıştığına bakılır.
Integration Test Birden fazla component'in bir arada uyumlu bir şekilde çalışıp çalışmadığını test eder.
Acceptance Test Kullanıcı kabul testidir. Üretilen bir ürünün kullanıcı ya da kullanıcılar tarafından test
edilip onaylanmasıdır.
Performans ve Yük Testleri
Load Test Darboğazları yük altında test eder.
Stress Test Uygulamayı kırmak üzerine yapılan testlerdir.
Spike Test Anlık trafiğin yükselmelerine veya düşüşlerine sistemin nasıl cevap verdiği test edilir.
TDD sadece gerekli sınıf ve metotlar için zaman harcar, daha sonra kullanılacağı varsayılan metotları
yazmamızı engeller. Test coverage'ları geniş olur. Hemen hemen her satır kod test tarafından
çalıştırılır. Testler aslında sistemin nasıl çalıştığını gösteren dökümantasyon olarak da düşünülebilir.
Debug yaparak yazarken gelişime açık testler yazılmalı, testlerin çalışma sırası birbirini etkilememeli,
önemli olmamalıdır. TDD'nin maliyetli oluşu BDD'yi ortaya çıkartmıştır.
BDD
Konuşma dilinde test senaryoları yazma olanağı sağlar. İş analistleri, müşteri ile yaptığı görüşmeler
sonrası kullanıcı hikayeleri oluşturur, sonra bu hikayeler üzerinden given when then senaryoları
kurularak;
Müşteri ihtiyacına göre oluşturulan hikayeler koda döküldüğü için ihtiyaçlar daha iyi karşılanır.
Konuşma dilinde yazıldığı için ekibe yeni katılan biri kolayca anlayabilir.
Clean Code
Kodun temiz olması ekipteki başka kişilerin kodu kolay şekilde anlayabilmesi ve geliştirebilmesidir
(readibility, changebility, extensibility)
Temiz kod yazmak için if else yazmak yerine polymorphism tercih edilmeli. Dependency Injection,
tutarlı olmalı heryerde aynı yöntem kullanılmamalı, bağımlılıktan kaçınılmalı, isimlendirmeler doğru
yapılmalı, SOLID prensiplerine uymalı, testleri yazılmış olmalı.
Microservice Architecture
Microservice mimarisi, tek bir uygulama geliştirirken modüler bir yapıda her biri küçük servis olarak
düşünülmesi gereken ve her bir servisinde kendi işini ve iletişimini yürütebilen, çok karmaşık
olmayan ve başka servislere bağımlılığı az olan mekanizmalara sahip bir yaklaşımdır. Servislerin
bağımsız olarak bakımı yapılabilir, izlenebilir ve dağıtılabilir yapıya sahip olmalıdır.
Microservice mimarisinin başlangıç noktası SOA’dır. Microservice, SOA yani services oriented architecture
üzerine kurulmuş bir mimaridir.
Service oriented architecture (SOA), uygulamaların birbirleriyle tek bir makine veya ağ üzerinden birden
çok makineye dağıtıldığında, servislerin dağıtım sistemde iletişim kurmasını sağlayabilen bir mimaridir.
Servisler birbirinden bağımsız olarak, herhangi bir platformda ayrı ayrı deploy edilebilir.
Microserviceler, otomatize bir biçimde gerekli aşamalardan geçerek (Unit Tests, Integration
Tests, Sonarqube,Automation Tests) deploy edilmelidir. Bu mekanizma, projede kaliteyi artırır.
Her bir servis bağımsız olarak geliştirilebilmeli, test edilebilmeli, deploy edilebilmelidir. Böylece
uygulamanın kalitesi ve esnekliği artar
Herhangi bir servisteki sorun, diğer servisleri etkilemez, böylece kullanıcılar diğer servisleri
kullanabilir konumda olur.
Projenin herhangi bir servisinde oluşacak bir sorun, projenin diğer servislerini etkilemeyeceği
için, sistem hala çalışmaya devam eder.
Her bir servis farklı dil veya farklı database kullanabilir. Her farklı özellik, diğer özelliklerden
bağımsız olarak farklı bir ekip tarafından farklı bir teknoloji kullanılarak gerçekleştirilebilir.
Bu microserviceler, fonksiyonlarını yerine getirmek için kendi yük dengeleyici(load balancing) ve
uygulama ortamlarına sahiptir ve aynı zamanda kendi veritabanlarında veri saklamalıdır.
Tüm microserviceler birbirleriyle REST veya Message Bus üzerinden haberleşmelidir. İkisi birden
de kullanılabilir.
Decoupling — Bir sistemdeki servisler büyük ölçüde birbirinden bağımsızdır.
Componentization — Microserviceler, kolayca değiştirilebilen ve versiyonları artırılabilen
bağımsız bileşenlerdir.
Business Capabilities — Bir microservice basit bir yapıdadır ve tek bir göreve odaklanır.
Autonomy — Geliştiriciler ve ekipler birbirlerinden bağımsız olarak çalışabilir, böylece hızlıca
geliştirme ve test süreçleri yürütülebilir.
Continuous Delivery — Yazılım geliştirme, test etme ve onaylama sistematik otomasyonu ile
sık sık yazılım sürümlerini canlıya almaya otomatik bir biçimde izin verir. Servisler ayrı ayrı
deploy edilebileceği için, deployment süresi kısalır ve maliyet zamanla azalır.
Decentralized Governance — Odak, doğru iş için doğru aracı kullanmaktır. Bu, standart bir
teknoloji veya yapıyı zorunlu kılmadığı anlamına gelir. Geliştiriciler, sorunlarını çözmek için en iyi
teknolojiyi seçme özgürlüğüne sahiptir
Agility — Microserviceler çevikliği destekler. Herhangi bir yeni özellik hızla geliştirilip sisteme
adapte edilebilir.
Monolitik bir uygulama, birden fazla modül içeren tek bir kod tabanına sahiptir. Modüller,
fonksiyonel veya teknik özelliklerine göre ayrılmıştır. Tüm uygulamayı build eden tek bir derleme
sistemine sahiptir. Ayrıca tek bir çalıştırılabilir veya deploy edilebilir dosyaya sahiptir. Başlatılacağı
zaman ya da durdurulacağı zaman ve hatta çöktüğü zaman uygulamanın tamamı bu durumdan
etkilenir. Yani uygulama, yaşamı boyunca tek bir parça halinde hareket eder
Uygulamanın küçük bir kısmında yapılan bir değişiklik, monolitik bir projenin tümünün yeniden
derlenmesi ve tüm uygulamanın deploy edilmesini gerektirir.
Daha kolay hata ayıklama ve uçtan uca test etme: Microservice mimarisinin aksine,
monolitik uygulamaların hata ayıklaması ve test edilmesi çok daha kolaydır. Monolitik bir
uygulama tek bir bölünmez proje olduğundan, uçtan uca testleri çok daha hızlı şekilde
gerçekleştirebilirsiniz.
Kolay deployment: Monolitik uygulamaların tek bir parça oluşu ile bağlantılı bir avantajı ise
kolay dağıtımdır. Tek bir parçayı deploy etmek onlarca servisi deploy etmekten çok daha
kolaydır.
Görece geliştirmesi basittir. Monolitik bir uygulamayı genel prensiplere uyarak modüler bir
biçimde yazmak, her bir modülü servis olarak yazmaktan çok daha kolaydır.
Karmaşıklık: Bir monolitik uygulama büyüdüğünde, anlaşılamayacak kadar karmaşık hale gelir.
Değişiklik yapma zorluğu:. Herhangi bir kod değişikliği tüm sistemi etkiler, bu nedenle tamamen
bütün parçaların kontrol edilmesi gerekir.
Ölçeklenebilirliği(Scaleable) düşük: Bileşenleri bağımsız olarak scale edemezsiniz. Tüm
uygulamayı ölçeklemeniz gerekir.
Cross Cutting Concerns denmesinin sebebi projeyi dikine kesmesinden kaynaklı, dikine kesmesinin
altında yatan anlam ise katman bağımsız, projenin istenilen yerinde kullanılması, kullanılan yerden
soyutlanmış olmasından kaynaklıdır. Özetle yazılımın birden fazla yerinde kullanılan, fonksiyonel
olmayan ihtiyaçlar denilebilir.
AGILE
Agile modeli proje yönetimi, yazılım geliştirme sürecinde karşılaşılan problemleri çözmek üzere, sık
aralıklarla parça parça yazılım teslimatını ve değişikliği teşvik eden bir yazılım geliştirme modelidir.
Agile manifestosu 4 temel değere odaklanır.
İş süreçleri ve araçlardan ziyade bireyler ve aralarındaki iletişim değerlidir.
Kapsamlı bir dökümantasyon sürecinden ziyade, çalışan bir yazılım ortaya koymak değerlidir.
Müşteri ile işbirliği yapmak sözleşme görüşmelerinden daha önemlidir.
Değişime cevap vermek, mevcut planı izlemekten daha değerlidir.
Agile proje yönetme metodolojilerinden biri SCRUM'dır. Haftalık çalışma planları Sprint'lerdir.
CI/CD
CI: Continious Integration, kod üzerinde yapılan değişiklik sonrası sistemin çalışır durumda olduğu,
yapılan değişiklikğin sorunlara yol açmadığını tespit etmek için kullanılan sistemdir. Sorunları ve
kırılmaları tespit edebilmek için birim testleri kullanılır.
CD Continious Delivery, CI'ın bir uzantısıdır. başarılı olan bir yapıyı (build) bir ortama atma
durumunun otomatik olan yoludur. Teslimat ile dağıtım arasında küçük bir fark vardır. Teslimat
manuel yolla, dağıtım ise otomatik yapılır. Sürekli teslimat düzgün bir şekilde uygulanırsa, müşteriler
standartlaştırılmış bir test sürecinden geçmiş yapıya sahip olacaklardır.
Örnek verecek olursak; Netflix, tamamen otomatik bir sürekli dağıtım sistemine sahiptir. Dağıtımlar
otomatik olduğundan ve herhangi bir zamanda gerçekleşebileceğinden, uygulamanız, yeni bir
sürüm dağıtıldığında geçici kesintilerden etkilenmeyecek şekilde tasarlanmalıdır.
Hibernate
RedHat şirketi tarafından Java platformunda yazılmış bir ORM (Object/Relational Mapping) aracıdır.
Hibernate bir ORM frameworküdür .ORM(Object Relational Mapping-Nesne İlişkisel Eşleme), nesne
tabanlı (object oriented) dillerdeki nesnelerin, ilişkisel veri tabanlarındaki (relational databases)
kayıtlara nasıl karşılık geldiğini yürüten bir teknolojidir.
Hibernate’ in faydası;
-Kod yazımını kısaltmak veya kolaylaştırmak
-Yazılım bakımını kolaylaştırmak vb. verilebilir.
Anotasyon
Developlement anında IDE veya compiler tarafından yada run-time anında framework
tarafından yorumlanan ifadelerdir.
Bir öğenin tanımını yapar, ne yapması gerektiğini açıklar ve yazılım geliştirme sürecini hem
hızlandırır hem de kolaylaştırır.
Anotasyonlar kodun içerisinde tanımlandıktan sonra, işlevsel hale gelebilmeleri için Spring
tarafından 2 defa taranırlar.
İlk önce yalnızca anotasyonları (spring tarafından yönetilen bean) taranır ve yapılması gereken
görev eşleştirmeleri yapılır.
İkinci taramada ise anotasyon tanımlamasına göre işlemini yapar.
Tüm Spring Bean’leri “App Context” yada "Spring Context" (IoC container) adı verilen bir
container içinde yaşarlar.
Anotasyonlar çok güçlü kullanımlardır ve çok farklı şekillerde kullanılabilirler. Birkaç örnek vermek
gerekirse:
@Configuration: Bean tanımlamaları gibi tanımlamalar için bir Bean sınıfı olduğunu belirtir.
@Controller : Request'leri yakalayabilme yeteneği olan bir web controller sınıfını belirtir.
id = sınıf adı
class = sınıfın konumu
@Qualifier
Eğer bir interface birden fazla sınıf tarafından implemente edildiyse, bu sınıflardan hangisine ait
fonksiyonun kullanacağını bilmek için, @Autowired tanımlamasına ek olarak
@Qualifier("sınıfadı") bir anotasyon daha eklendiği takdirde, Spring gerekli injection'ı
sağlayacaktır.
@Component
Bir sınıfı bean olarak işaretler. Bu sayede Spring'in component tarayıcısı bu sınıfı alıp "App Context"
içerisine ekler. Genel amaçlı kullanım içindir.
@Component tanımı aslında XML dosyası içindeki şu tanımlamaya eşittir;
Projenin business logic kısmında kullanılır ve tanımlandığı sınıf "Bean" sınıfı haline gelir. @Service
anotasyonu yerine aynı işlemi yapan ve temel anotasyon olan @Component de kullanılabilir fakat,
@Service anotasyonu amacımıza yönelik daha fazla şey sunuyor. Yani @Component tanımlamasının
aynısı ama bir üst modelidir diyebiliriz. Ayrıca @Service kullanımı, tanımlandığı sıfının bir servis sınıfı
olduğunu belirtip, anlaşılırlığı arttırması açısından daha uygundur.
Yani başka bir deyişle, @Service, @Repository, @Controller, @Configuration tanımları, daha özel
kullanımlar için @Component tanımlamasının özelleşmiş halleridir. En basit örneği
özelleşmiş exception çıktıları almak. Bu tür özel tanımlamaları amacına uygun yerlerde kullanarak,
daha özel exception çıktıları alınabilir. Örneğin, @Repository kullanımı, kullanıldığı sınıfta herhangi
bir istisna durum oluşursa, hata olarak veritabanına özel exceptionlar dönecektir.
@RestController
@ResponseBody ve @ResponseEntity
@Entity
CrudRepository
Repository interface'ini implemente eder. Genel olarak Create,Read,Update ve Delete
operasyonlarını barındırır.
saveAll() metodunun dönüş tipi Iterable'dır. Sadece CRUD işlemleri yapılacaksa bu implementasyon
daha hızlı olacaktır.
JpaRepository
PagingAndSorting 'i ve oda CrudRepository'i implemente eder. CRUD operasyonlarının yanı sıra
ekstra olarak flush(), saveAndFlush() ve deleteInBatch() metodlarınıda barındırır. saveAll()'un dönüş
tipi List'tir. Crud işlemlerinin yanı sıra toplu işlemlerde yapılacaksa JpaRepository kullanılması daha
iyidir.
PagingAndSorting
CrudRepository'i implemente eder. Crud operasyonlarının yanı sıra, sayfalama ve sıralama
metodlarıda mevcuttur.
JpaRepository > PagingAndSortingRepository >CrudRepository
IoC Container
Üst seviyeli sınıfımızın ihtiyaç duyduğu nesnenin instance(örneğini) bizim için arka planda tutuyor.
Bir kutu gibidir. İstediğimiz interface nesnemizin somut örneğini istediğimiz zaman bize verir.
Circuit Breaker
Türkçe anlamıyla sigorta şalteri. Sistemde aşırı yüklenmenin olduğu durumların üstesinden gelmek
için kullanılan bir devre elemanıdır. Sistemimize Microservice mimarisini uygulamadık ve ardışık
olarak birbirine request gönderen bir dizi servisimiz mevcut. diğer bütün servisler gibi bu dizideki
servislerinde down olma ihtimali var ve eğer herhangi biri request'lere cevap veremezse bu bütün
akışı aksatıp bir dizi ardışık hataya sebep olabilir. Eğer bu cevap dönemeyen requesti yapan çok fazla
caller olursa bu da kaynak tüketimini kritik düzeyde arttırıp bir çok servisi ve bütün sistemi
etkileyecek bir dizi ciddi soruna yol açabilir. Circuit breaker bu gibi durumlarda bir devre anahtarı
gibi davranarak belli bir threshold'un (eşik değeri) üstünde hata alındığında, response dönemeyen
servise gelen request'leri servise iletmeden(open_state), requestlere bir hata mnesajı veya bilgi verici
bir mesajla geri dönüş yaparak sistemin gereksiz yere aşırı yüklenmesini engeller. Belli bir timeouttan
sonra gelen requestlerin bir kısmını servise ileterek test yapıp sistem durumunu kontrol eder
(half_open_state). eğer sıkıntı giderilmiş ise bütün isteklerin geçmesine izin verir (closed_state) ve
sistem düzenini korumuş olur, eğer test çağrılarıda hata mesajı alıyorsa, yine request'lere error
dönüp bu döngüyü devam ettirir.
Netflix Hystrix ve Resilience4j örnek verilebilir.
REST istemci-sunucu arasında hızlı ve kolay iletişim kurulmasını sağlayan bir servis yapısıdır. Açılımı
Representational State Transfer'dir. Rest, servis yönelimi mimari üzerine oluşturulan yazılımlarda
kullanılan bir veri transfer yöntemidir. HTTP üzerinde çalışır ve diğer alternatiflerine göre daha
basittir, minimum içerik ile veri alıp gönderdiği için de daha hızlıdır. İstemci ve sunucu arasında XML
veya JSON verilerini taşıyarak uygulamaların haberleşmesini sağlar. REST standartlarına uygun
yazılan web servislerini RESTful servisler diyoruz. REST stateless'dir, yani durum bilgisini saklamaz.
REST standartlarında istemci-sunucu arasında taşınan verilerde ekstra başlık bilgileri saklanmaz,
istemciye ait detaylar bulunmaz, bu bilgiler istemci-sunucu arasında taşınmaz. Dolayısıyla servis
yönelimli uygulamalarda REST bize lightweight bir çözüm yapısı sunar.
Teorik olarak SOAP bir protokol, REST ise bir kurallar dizisidir. Bu iki teoremi doğrudan kıyaslamak
biraz yanlış olsa da, SOAP servisleri RPC(Remote Process Call- uzaktaki bir prosedürün çağırılması)
çalışma yöntemini kullanır, bir dizi güvenlik protokollerini içerisinde barındırır, state bilgisini request
ve response'larda saklar. Ancak REST'te bu durum daha farklıdır. REST servisler doğrudan URL
çağırılarak çalışır, arada ek bir bileşen, yöntem veya protokol bulunmaz. SOAP bir servisi
uygulamanıza dahil edebilmeniz için servisin WDL'ine ihtiyaç duyarsınız, proxy sınıfları oluşturmanız
gerekir, uzaktaki metotları tetikleyecek bileşenlere ihtiyaç vardır, servis ile ilgili herşeyi bilmek
zorundasınızdır, belirli standartları yerine getirmeden SOAP bir servisi çağıramazsınız. Ancak, REST ile
yazılmış bir servis ile çalışmak için ihtiyacımız olan tek şey URL'dir.
Basit yapısı, kolay uygulanması, esnek olması.. bunlar RESTful servislerin artı yönleri, bazı eksi yönleri
de var tabii ki, güvenlik bunlardan bir tanesidir. SOAP servislerde standartlar gereği bir çok güvenlik
mekanizması otomatik olarak elinizin altındadır. Ancak RESTful servislerde güvenlik konuları
geliştirilen yazılımın bir parçasıdır. İletişim seviyesinde güvenlik (transport level security) genellikle
token aracılığıyla yapılır.
RESTful servisler veri iletiminde farklı HTTP metotlarını kullanmaktadır. Bunlar GET, PUT, POST,
DELETE metotlarıdır.
POST ile PUT Arasındaki Fark
PUT metodu "idempotent" olarak tanımlanmıştır. Yani aynı kaynak path üzerinde gerçekleştirilen
birden fazla PUT request'i server tarafında ilk PUT request'inin yaptığından başka bir state
değişlikliğine neden olmaz. Oysa durum POST için bundan çok farklıdır. POST ile aynı resource
path'ine yapılan birden fazla request her seferinde server tarafından bir state değişikliğine neden
olacaktır.
# POST /companies
{
"companyName":"Harezmi",
"companyLocation":"Ankara"
}
----------
# POST /companies
{
"companyName":"Harezmi",
"companyLocation":"Ankara"
}
Ard arda iki defa aynı POST request'i server'da aynı içerikte iki farklı resource oluşturulmasına neden
olabilir.
#PUT /companies/1
{
"companyName":"Harezmi",
"companyLocation":"Ankara"
}
----------
#PUT /companies/1
{
"companyName":"Harezmi",
"companyLocation":"Ankara"
}
Ard arda iki defa PUT request'i geldiğinde ise server ilk seferde resource'u oluşturur. ikinci ve diğer
PUT request'lerinde ise belirtilen path'deki resource'un içeriği güncellenecektir. Request'lerde her
seferinde aynı içerik submit edildiği için server tarafında da bir state değişikliği söz konusu
olmayacaktır. Yeni bir resource oluşturulması da söz konusu değildir.
İkinci fark ise POST ve PUT metoduna parametre olarak verilen resource path'i ile ilgilidir. POST
metoduna yeni oluşturulacak olan resource path'ini verirseniz 404 resource not found
hatası alırsınız. POST ile yeni bir resource oluşturulurken path'inin aynı olacağı parent resource
path'ini vermeniz yeterlidir. Başka bir ifade ile yeni resource path'inin ne olacağına server tarafı karar
vermektedir. PUT metodunda ise oluşturulacak yeni resource'un path'ini de request'de vermek
gereklidir. Yani PUT metodunda ise oluşturulacak resource path'ine client karar vermektedir.
#POST /companies/1
{
"companyName":"Harezmi",
"companyLocation":"Ankara"
}
/companies/1 isimli bir resource mevcut değil ise yukarıdaki HTTP request'i hata verecektir. Yeni bir
resource oluşturmak için POST'un kullanımı aşağıdaki gibi olmalıdır.
#POST /companies
{
"companyName":"Harezmi",
"companyLocation":"Ankara"
}
#PUT /companies/1
{
"companyName":"Harezmi",
"companyLocation":"Ankara"
}
Kısa-süreli feature branchler ile yaptığımız geliştirmeler daha sık trunk(master) branch’e
alınacağı için merge işlemi kolay olur.
Feature branch yöntemi ile çalışırken branch'lerin kısa-süreli (bir kişinin maksimum bir kaç gün
çalıştığı) olması çok önemli. Aksi takdirde trunk based development tekniğinin bütün avantajı
kaybedilmiş olur.
Feature Flags
Bu teknik genellikte trunk based development tekniği ile beraber kullanılır. Trunk based
development tek branch üzerinden çalıştırmayı gerektirdiği için feature flagler kapat/aç
mekanizması ile hem yapmış olduğumuz geliştirmeleri kontrollü olarak yayına almamıza olanak
sağlar, hem de bir hata olması durumunda ilgili özelliğin hızlıca kapatılmasına olanak sağlar.
Ayrıca feature flag'ler yeni geliştirdiğimiz özelliği yalnızca belli bir kullanıcı kitlesine açarak canary
release'lerde çıkmamıza olanak sağlar.
Branch By Abstraction
Trunk üzerinde tamamlanması uzun sürecek geliştirmeleri aşamalı olarak gerçekleştirebilmek için
kullanılabilecek bir yöntemdir.
Nasıl uygulanır?
Docker
En net tanımıyla tamamıyla open source bir 'container' teknolojisidir. Docker, aynı işletim sistemi
üzerinde, yüzlerce hatta binlerce birbirinden izole ve bağımsız container'lar sayesinde sanallaştırma
sağlayan bir teknolojidir. Web uygulamalarımızın kolayca kurulumunu, testini, çalışmasını ve
deployment'ını sağlar. Bunun yanında sunucu maliyetlerini önemli ölçüde azaltır.
Docker Daemon : Hpervisor'ün docker'daki karşılığıdır. Bütün CPU ve RAM vb. gibi işletim sistemine
ait işlerin yapıldığı bölümdür.
Container : Docker daemon tarafından Linux çekirdeği içerisinde birbirinden izole olarak çalıştırılan
process'lerin her birine verilen isimdir. VM analojisinde Docker'ı Hypervisor'e benzetirsek fiziksel
sunucu üzerinde halihazırda koşturulmakta olan her bir işletim sisteminin (sanal sunucunun)
Docker'daki karşılığı Container'dır.
Image : Container'lar layer halindeki Image'lardan oluşur. Docker Image ise containerlara kurulacak
ve run edilecek olan uygulamaların veya OS'lerin image dosyalarıdır. Örnek verecek olursak
mysql,mongodb,redis,ubuntu..
Aslında container içerisindeki image'ların içeriklerinin ve tanımlamalarının gerekli tutulduğu bir
dosya var. Bu dosyamızın adı Dockerfile. Bir bakıma container'lar içindeki image'ların
registration'ını yapan bir dosya. Her bir image Dockerfile dediğimiz bu dosya altında tanmlanması
zorunludur.
Docker CLI : Kullanıcının Docker Daemon ile konuşmasını sağlayan, docker komutlarının çalıştırıldığı
CLI ekranıdır.
Docker Compose : Compose, birden fazla containere sahip docker uygulamalarını tanımlamak ve
çalıştırmak için kullanılır. compose ile uygulamanızın servislerini configure etmek için bir YAML
dosyası kullanılır. Ardından, tek bir komutla configure ettiğiniz ayarlar ile tüm servislerinizi oluşturup
başlatabilirsiniz.
Compose tüm ortamlarda çalışır: production, staging, development, testing ve diğer CI iş akışlarıda
dahil olmak üzere
1. Uygulamamızın ortamını Dockerfile dosyası ile herhangi bir yerden yeniden üretebilecek şekilde
tanımlayın.
2. [Link] uygulamalarınızı izole ortamda beraber çalışacak şekilde yaml dosyası
içerisine set edebiliriz.
3. docker-compose up komutu ile birlikte tüm uygulamamızı başlatır ve çalıştırabiliriz.
Docker avantajları
Docker saniyeler içerisinde başlar, çünkü içerisinde barındırdığı her bir yapı container sadece
birer process'tir. Böylece karşımıza lightweight bir yapı çıkar. Buda bizi sanal makinelerin
hantallığından kurtarmış oluyor.
Daha hızlı deployment süreci, docker'ı kullanmak için yeni bir environemnt kurmaya gerek
yoktur. Farklı sunucularda çalışmak isteyen developer'lar sadece docker image'lerini indirip o
sunucuda image'leri çalıştırmaları yeterlidir.
Daha kolay yönetim ve ölçeklendirme, bir sanal makineye göre docker üzerindeki container'ler
çok daha kolay bir şekilde çalıştırılabilir veya istediğimiz zaman yok edelebilir. Container'ları
manage etmek için farklı tool'lar mevcuttur. En çok Orchestrator diye nitelendirilen
Kubernetes teknolojisi daha popüler olarak kullanılıyor. Kubernetes, kısaca container kullanan
uygulamaları dağıtımını, ölçeklendirmesini ve yönetilmesini otomatik hale getiren açık kaynak
kodlu bir sistemdir.
Daha iyi kaynak kullanımı, sanal makinelere göre tek bir sunucu üzerindeki kaynak tüketimi
docker'da çok daha verimlidir. Daha az kaynak tüketimi ile daha fazla container'ı çalıştırabiliriz.
Deployment verimliliği, Local'inizde çalıştırdığımız her şey burada da aynı şekilde çalışacak.
Popüler cloud servislerle entegre edilebilir, Docker,AWS, Microsoft Azure, Ansible, Kubernetes,
Istio ve daha fazla tool ve cloud hizmetlerle entegre şekilde çalışabilir.
Docker open source bir sanallaştırma teknolojisidir. Ama bildiğimiz klasik sanal makinelerden
(Hypervisor, VMware) biraz farklı olarak sanallaştırma yapar. Bunun nedeni ise sanal makinelerde
bulunan hypervisor katmanının bulunmaması ve container dediğimiz birbirinden tamamen bağımsız
ve izole process'lerden oluşmadırıdr. Docker üzerinde host edildiği tek bir OS (işletim sistemi)
üzerinde yüzlerce ve binlerce docker container çalışabilir ve bu container'lar sistem dosyalarını
paylaşımlı olarak kullandıkları için kaynak tüketimleri oldukça düşük olduğu için maliyetleri de
düşüktür.
Sanal makine sistemlerinde, her bir sanal makine kendi işletim sistemini kullanır ve kendi
kütüphaneleri vardır.
VM (Virtual Machine)
Docker
docker pull
Belirtilen Image’ı lokal registry’ye indirir. Örnek: docker
<repository_name>/<image_name>:
pull gsengun/jmeter3.0:1.7
<image_tag>
docker run -it <image_id veya Verilen Image’dan terminal’i attach ederek bir
image_name> CMD Container oluşturur
docker rmi -f <image_id veya İlgili Image’ı zorlayarak kaldırır, başka isimlerle
image_name> Tag’lenmiş Image’lar -f ile kaldırılabilir
docker volume ls -f
Dangling Volume’ları listeler
dangling=true
docker exec <container_id> Çalışan bir Container içinde bir komut koşturmak için
<command> kullanılır
Java programlama dili ile yazılmış olan uygulama ve appletlerin çalışmasını sağlayan bileşenler ileJVM
e kütüphaneler sağlar. Derlenmiş bytecode lar direk olarak CPU üzerinde çalışmazlar. CPU tarafından
anlaşılması için aradaki JVM bytecode'ları okunabilir makine kodları olarak yorumlar. aslında; Java
bytecode ların bütün platformlarda çalışması JRE sayesindedir. İçerisinde; JVM, Core kitaplıkları ve
Java yazılımında yazılan uygulamaları ve küçük uygulamaları çalıştırmak için diğer ek bileşenleri içerir.
JRE'nin görevi Java kodları derlendikten sonra ara dil olarak kabul edilen Java bayt kodlarını
oluşturmaktır. Bu byte kodlar bütün işletim sistemler için aynıdır.
Java'da geliştirme yapmak isteyen her developer'ın mutlaka indirmesi gereken bir bileşendir. Kısaca
Java için SDK diyebiliriz. Hem yorumlayıcı hem de derleyici görevini üstlenmektedir. JRE ile birlikte
appletleri ve uygulamaları geliştirirken zorunlu olan debuggers ve compilers gibi geliştirme araçlarını
da bünyesinde bulundurur.
Bir process'in birden fazla işi aynı anda yapmasını sağlayan yapılara thread denir. Bir process
bünyesinde bir veya birden fazla thread barındırabilir. Thread'ler aynı anda sadece tek bir işi
yapabilir. Thread'ler aynı zamanda ligth-weight-process(hafif siklet process) olarak da
nitelendirilebilir. Bir process içerisinde birden fazla thread çalıştırmasına multi-thread diyoruz.
Thread'ler çok çekirdekli işlemcilerde farklı çekirdeklerde eş zamanlı olarak çalışabilir. Bu yaklaşıma
da parallel programming diyoruz.
Çalışan programlara process denir. Örnek olarak Word,Excel veya herhangi başka bir uygulama
henüz çalışmıyorken bir programdır. Programlar çalıştırıldığında process olarak nitelendirilir.
Process'ler hayatlarına tek thread ile başkar ve thread'e de main thread adı verilir. Diğer thread'ler
ise programın çalışma esnasında sistem fonksiyonları tarafından oluşturulmaktadır. Bir process
kendi içerisinde başka bir process daha oluşturabilir, bu process'e child process adı verilir.
Paralellism birden fazla işlemci ya da çekirdekte aynı anda işlem yapılması anlamında gelmektedir.
Concurrency ise tek bir process üzerinde eş zamanlı olarak birden fazla operasyonun
gerçekleşmesidir.
Aksi belirtilmediği sürece Windows işletim sistemlerinde varsayılan thread boyutu 1MB'dır. Linux
sistemlerde ise varsayılan thread boyutu versiyondan versiyona değişiklik gösterebilir (2MB - 32MB).
Multithreading nedir ?
Programın çalışması tek bir process üzerinden sağlanırken, bu process üzerinde birden fazla işlem
parçacığı çalışmaktadır. Process üzerinde çalışan bu çoklu işlem parçacıkları, asenkron olarak farklı
görevleri yerine getirmek için kullanılırlar. Bu sayede birbirlerini beklemesi gerekmeyen işlemlerin,
tek bir process üzerinde asenkron olarak gerçekleştirilmeleri sağlanır ve performans arttırılmış olur.
Maven
Her kütüphane için gerekli olan JAR dosyalarını indirmek ve projeye uygun olarak yerleştirmek
(classpath) gerekir. Maven proje dosyasına eklenen bağımlılıklar ile kolay bir şekilde indirmeyi ve
proje yerleştirmeyi sağlar.
Mocking nedir?
Mocking(mocklama), popüler yazılım metodolojisi olan TDD ve özelde birim testlerinin (unit test),
test ettikleri sistemi izole etmede kullandığı yöntemlerden biridir. Bu yöntemler, geniş anlamıyla
test dublörleri (test double) olarak tanımlanabilir. Test dublörleri, test edilen sistemin bağımlı
olduğu diğer birimlerin yerini tutar. Bu izolasyona birim testlerinde ihtiyaç duyulmasının 2 sebebi
vardır:
1. Birim testleri, genelde test ettikleri sistemin kendisi ile ilgili varsayımları doğrulamak için yazılır.
2. Test dublörleri, davranış ve kullanım şekillerine göre çeşitlenir. Bunlardan en çok kullanılanları
dummy, fake, stub, spy ve mock'tur denebilir. Bu çeşitliliğe sebep olan genel faktörler, bu
dublörlerin beklenen işi yapıp yapmadığı ve yaparken nasıl bir davranış gösterdiği ile ilgilidir.
Mock'ların genel kullanım şekli, yerine geçtiği bağımlılık üzerinde, test edilen sistemin yapması
beklenen işlerin yapılıp yapılmadığını doğrulamak olarak tanımlanabilir. Mock nesnelerin casus
nesnelerden (spy) farkı, her ikiside üzerlerinde yapılan işlemleri takip ederken, mock'lar bu işlemi
testlerin doğrulama (assert) kısmına da entegre ederler.
Koleksiyonlar - Collections
Java koleksiyon çatısı altında 3 ana koleksiyon tipi sunmaktadır. SET, LIST, MAP ve yine bunlara ait
aynı isimde 3 interface bulumaktadır. Bu interface arabirimlerin nesneleri şunlardır:
Set Nesnesi: Kendisine verilen elemanların her birinde sadece bir tanesini tutar Kopya ya da
tekrarlanan elemanları barındırmaz.
List Nesnesi Kendisine verilen elemanları sıralı şekilde tutar. Tekrarlanan elemanları barındırabilir.
Map Nesnesi :Her biri birbirinden farklı anahtarlar ile eşleştirilen nesnelerden oluşur.
Array : Hafızada ard arda tutulur. Yeni bir eleman eklemek istediğimiz de hafızada yeni bir yer açılıyor
bütün elemanları oraya taşıyoruz. Bu yüzden yeni eleman ekleme masraflı oluyor. Dynamic Array
kullanabiliriz ama bu seferde boş yere hafıza yer ayırmış oluyoruz. Array'lerde erişim kolaydır.
LinkedList: Hafızada yan yana tutmak istediğim verileri, hafızada dağılmış şekilde tutabiliriz. Yan
yana zorunluluğu yoktur. Örneğin bir sinemaya arkadaş grubu ile gidiyoruz, yan yana oturma şartı
yok ama yeni gelen kişi son kişiye oturacağı yeri söylecek.
Array LinkedList
Arrayin istediğimiz elemanına sabit sürede Eleman eklemek ve silmek arraylere göre
erişebiliyoruz daha kolay
Dizilerin belirli bir kapasitesi vardır (Program Bir kapasitesi yoktur belleğin izin verdiği
başladığında belirlenir) miktarda büyüyebilirler.
Bir diziye eleman eklemek ve çıkartmak çok Eleman eklemek ve çıkartmak nispeten daha
maliyetlidir. kolaydır.
Stack ve Queue
Stack ve Queue'ları array ve linked list'leri kullanarak oluşturabiliyoruz.
Stack: LIFO yapısını kullanır. (Last In First Out), tek yönlü bir eleman ekleme vardır, ortasına
eklemek-çıkartmak gibi bir durum yoktur.
Push: Stack'e eleman eklemek (Yığının en üstüne ekler)
Pop: Stack'ten eleman almak( Yığının en üstünden eleman çıkartır)
Hash Table
Hash table ürünlerin fiyatını ezbere bilen bir çalışan gibidir.
Ürünlerin isimlerini ve fiyatlarını array'in elemanları olarak tutup bu sorunu çözebiliriz ama ürünleri
array'de tek tek aramak istemiyoruz, anında aradığım ürünün fiyatını bulmak istiyorum.
Array'lerde kaçıncı eleman olursa olsun sabit erişme süresi vardı, Bu sabit sürede erişmeyi
lokasyon bazlı değil, tanım bazlı kulanmak istiyorum. Bana [Link]ı getir değil, bana
elmaya karşılık gelen elamanı/fiyatını getir demek istiyorum.
Bize birisi bir ürünün fiyatını sorduğunda bu ürünü oluşturduğumuz fonksiyona besleyip
array'deki index'i neredeymiş onu bulacağız.
Bu fonksiyona Hash Function, Hash function + Array yapısına da Hash Table deniyor.
Burada Key bizim ürün isimlerimiz ve Value'larımızda fiyatlarımız.
Hash Function
3. Hash function'ın çıktılarının sınırlarında (range) olmalı array'in boyutu. Array'de olmayan
bir index'i üretmemeli.
Malesef her seferinde aynı girdiye farklı sonuç veremiyor Hash Function, bu duruma
Collision deniyor.
Collision
Çarpışma olduğunda Array'imizdeki index bir linked list'e geniş[Link] biz anında fiyatı
bulmak istiyorduk, linked list ile bu avantajımızı kaybettik.
Algoritma Analizinde
Çalışma süresi (Execution Time)
İfade sayısı
Büyüme hızı (Rate of growth)
a bakarız. Genellenebilir bir analiz yapmak için, her algoritmayı aynı bilgisayar ile test ediyor gibi
yaparız. Bu hayali makineye RAM (Random Access Machine) diyoruz.
Ram'in özellikleri
Time Complexity
Kullanacağımız algoritmayı test etmek istiyoruz. Problem aynı olsa da farklı inputlar için
algoritmamız farklı performans senaryoları üretebilir.
Diyelim ki bir kelimenin anlamını sözlükte arıyorum. Arama için sayfalara tek tek bakıyorum.
Burada algoritmam sayfalara tek tek bakmak,inputta aradığım kelime.
Aradığım kelimenin boyutu aynı olsa da hangi harfle başladığına göre değişebilir. Yani input
algoritmanın yapacağı işlem sayısını etkileyebiliyor. Bu yüzden analizimizi 3 ana başlık altında
yapabiliriz. Worst case, Avarage case, Best Case.
1. Worst Case: Vereceğimiz inputun algoritmamızı en yavaş (en fazla işlem yapacak) şekilde
çalıştırdığı durum. Aradığımız kelimenin "z" ile başlaması.
2. Average Case: Genel olarak beklediğim durum.
3. Best Case: Vereceğimiz inputun algoritmamızı en hızlı şekilde çalıştırdığı durum.
Algoritmamızın çalışmasını en iyi yansıtan average case, ama bu durumu analiz etmek
diğerlerine göre çok daha zor. Input'ların geldiği dağılımı bilip ona göre analiz etmek gerekiyor.
Worst Case'e göre analiz yaparsak, performansımız için üst sınır çizmiş oluruz. Böylece worst
case için bizi tatmin eden bir algoritmamız varsa, average case zaten bundan daha iyi (veya
aynı) performans vereceği için oda bizi tatmin edecektir.
Sorting
[65,27,13,23,10]
En baştan başlarım en küçüğü bulup en başa yazarım, en başta olan ile de onun yerini değiştirdim.
[10,27,13,23,65] => artık 0. index'te ki eleman küçük bundan sonra [Link]'ten itibaren en küçüğü
buluyorum.
[10,13,27,23,65] => artık 1. index' ekadar sıralı olduğunu biliyorum, ve bu şekilde en sona kadar
gidiyorum.
[10,13,23,27,65]
Elimdeki sayı dizisini bir anda sıralamak yerine, parçalara ayırıp, ayırdığım parçaları daha küçük
parçaları kendi aralarında sıralayıp daha birleştirsem daha iyi bir perfomans alabiliyorum.
Tek eleman kalana kadar 2'ye bölüyoruz. Ve daha sonra birleştiriyoruz. Birleştirirken sıralama
yapıyoruz ve her seferinde elimizde sıralı küçük bir dizi oluyor.
Quick sort
Worst Case : O(n²)
Average Case: O ( n logn ) (Katsayısı merge sorttan az olduğu için daha hızlı olabiliyor.)
Bir pivot seçiyoruz. Sayı dizinin en başına gidip sayıya bakıyoruz pivottan küçükse soluna büyükse
sağına alıyoruz. Pivot hariç listenin bütün elemanlarını tarıyoruz. (n-1 işlem yapıyoruz).
Pivotun solunda küçükler sağında büyükler ve daha sonra aynısını böldüğüm sayı dizilerinde
yapıyoruz.
Arama algoritmaları ise istediğim özellikteki verinin elimdeki veri setlerinde aranıp, bulunup
getirilmesi demek. Bunun hızlı olmasına önem gösterilir.
İkili arama algoritması, elimizde bulunan veri dizisini sıralı olduğunu varsayıyor, bu durumu
değiştirerek sonuca varmak istiyor.
İkili arama algoritması, diziyi her seferinde ikiye bölerek ikili arama yapar. Sıralı bir listem var ise
benim Big-o logn olarak karşımıza çıkıyor.
Average O (logn)
Worst O (n)
Insertion O (logn)
Random Access yapamaz
Neden Spring Boot Kullanmalıyız?
Stability (Kararlı)
Spring ekosistemindeki, core ve merkezi Spring modeller uzun süredir kararlı olduğundan ve
çoğu değişiklik geriye dönük olarak uyumludur. SpringBoot belirli bir değişiklik yayınlıyorsa, o
değişikliği önceden duyururi böylece Spring Boot'a dayalı olarak oluşturulan tüm
uygulamaların, otomatik olarak güncelleneceğini bilirsiniz, bu şekilde uygulamanızın sorunsuz
bir geniş yolunu sağlar ve uygulamanızın çalışmasında herhangi bir sorun olmadığını bilirsiniz.
Based on JVM (JVM'e dayalı)
Connectivity
İlişkisel veritabanları, nosql veritabanları ve hatta queue servisleri ile bağlantı kurmanız çok
kolay. Herhangi bir data access teknolojisini bağlamak çok kolay.
Cloud Native
Bulut uygulamalarının dağıtım ilkelerini takip eder ve paketten çıkarttığınız gibi bulut için
hazırdır. Yani Spring Boot ve Spring Cloud ile birlikte distributed sistemleri kolay bir şekilde
oluşturabilirsiniz.
Flexibility
Klasik sunucu taraflı web uygulamaları,Restful servisler ve hatta Command Line uygulamaları
bile geliştirmemize imkan sunuyor.
Open Source
Spring Boot, Java geliştirme için Spring çerçevesinin kullanımını basitleştirmeyi amaçlayan bir Spring
modülüdür. Hemen çalıştırabileceğiniz stand-alone Spring tabanlı uygulamalar oluşturmak için
kullanılır.Hızlı uygulama gelişimini amaçlar.
Spring Boot framework ile beraberinde gelenler;
Uygulamanın hızlı bir şekilde başlatılması için bir dizi varsayılan yapılandırmayı yüklemek için
otomatik yapılandırma sağlar.
Embedded Tomcat Server ile birlikte gelir
Maven konfigürasyonlarını kolay hale getirir.
Geliştirme ve test için CLI tool sağlar.
Bağımlılık yönetimini sağlamak için Spring Boot başlatıcılarıyla birlikte gelir ve ayrıca çeşitli
güvenlik ölçümleri sağlar.
Development ve production'da uygulamayı izlemek ve yönetmek için çok çeşitli API'lerden
oluşur.
Spring JDBC, Spring ORM, Spring Data, Spring Security gibi Spring Ecosystem ile ortak kodlardan
kaçınarak kolayca entegre olur.
Spring CLI : Groovy kullanmanıza olanak sağlar böylece boilerplate kodları yazmadan devam
edebilirsiniz.
Spring Initializer: İstediğimiz gerekliliklere göre bize temel konfigürasyonları hazır bir web
projesi üretip verir.
Spring Actuator: Bu özellik, Spring Boot uygulamalarını çalıştırırken yardım sağlar.
Starter Dependency: Bu özelliğin yardımıyla Spring Boot, ortak bağımlılıkları bir araya toplar.
Auto-configuration: Spring Boot'un otomatik yapılandırma özelliği, üzerinde çalıştığınız projeye
göre varsayılan yapılandırmaların yüklenmesine yardımcı olur.
Logging and Security: Spring Boot'un bu özelliği, Spring Boot kullanılarak yapılan tüm
uygulamaların sorunsuz bir şekilde güvenli bir şekilde korunmasını sağlar.
Maven kullanarak Spring Boot projesi oluşturmanın birden fazla yolu vardır
Application Properties
Command Line Properties
Profile Specific Properties
Spring Boot application'ı "Run as Java Application" olarak çalıştırdığımızda arka planda
neler olur?
Run as Java application dediğimiz de otomatik olarak tomcat server ayağa kaldırılır.
Spring Boot başlatıcıları, uygulamada bağımlılıkları etkinleştirmek için kullanılabilen bir dizi uygun
bağımlılık yönetimi sağlayıcısıdır. Bu başlangıçlar, geliştirmeyi kolay ve hızlı hale getirir. Mevcut tüm
başlatıcılar [Link] grubu altında gelir.
spring-boot-starter
spring-boot-stater-jdbc
spring-boot-starter-web
spring-boot-starter-data-jpa
spring-boot-starter-security
spring-boot-starter-aop
spring-boot-starter-test
Bu, Spring Boot'un harika bir özelliğidir ve bunun yardımıyla, çalışan bir uygulamada neler olduğunu
görebilirsiniz (Bean tanımlama, işlemci kullanımı vb.). Spring Actuator, kullanıma hazır REST
noktalarına erişmek ve web'den her türlü bilgiyi almak için çok kolay bir yol sağlar. Yaptığımız ya da
yapacağımız Spring Boot uygulamalarımızın endpoint yardımı ile çalışan Spring Boot uygulaması
hakkında bilgi almamızı sağlamaktadır.
Server-side Java template ş[Link] uygulamanız için doğal bir şablon sunmayı amaçlar ve
Spring Framework ve HTML Java Web Uygulamaları ile iyi bir şekilde bütünleşebilir.
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Uygulama üretimde çalışıyorsa, bu modül otomatik olarak devre dışı bırakılır, arşivlerin yeniden
paketlenmesi de varsayılan olarak hariç tutulur.
[Link]'de
[Link]=true
Spring Boot CLI, resmi Spring Framework tarafından desteklenen bir araçtır. Spring Boot projesini
yürütme adımları aşağıdaki gibidir:
Resmi siteden CLI aracını indirin ve zip dosyasını çıkarın. Spring kurulumunda bulunan bin
klasörü, Spring Boot uygulamasını yürütmek için kullanılır.
Spring Boot CLI groovy dosyaları çalıştırdığından, Spring Boot uygulaması için groovy dosya
oluşturmanız gerekir. Bunu yapmak için terminali açın ve mevcut dizini bin klasörüne değiştirin.
Custom endpoint oluşturmak için Spring Boot 2.x'da @Endpoint anotasyonunu kullanabiliriz.
Spring Boot ayrıca Spring MVC, Jersey vb. yardımıyla HTTP üzerinden @WebEndpointor,
@WebEndpointExtension kullanarak endpoint oluşturmamıza olanak sağlar.
veritabanlarını, bulut tabanlı veri hizmetlerini ve diğer veri erişim teknolojilerini kullanmasını
kolaylaştırmayı amaçlar.
Bu nedenle, temel olarak, veri erişimini kolaylaştırır ve yine de temeldeki verileri tutar.
Spring Boot auto configuration deyince aklınıza ne geliyor ve auto configuration'ı nasıl
kapatırsınız?
Auto-configuration, uygulama için gerekli yapılandırmayı otomatik olarak bizim yerimize halleder.
Örneğin, uygulamanın class path'inde data bean'iniz varsa, JDBC şablonunu otomatik olarak
yapılandırır.
@EnableAutoConfiguration(exclude={[Link]})
@SpringBootApplication
main class yada bootstrap class'da kullanılır.
@Configuration, @ComponentScan ve @EnableAutoConfiguration anotasyonlarının
kombinasyonudur.
@EnableAutoConfiguration
Projede auto-configuration ve component taramayı aktif eder.
@Configuration ve @ComponentScan'ın kombinasyonudur.
Bunu yapmak için, entity'deki değişiklikleri kontrol etmek istemediğimiz için işlemi read only olarak
ayarlarız.
YAML dosyasının bir [Link]'e göre avantajı, verilerin hiyerarşik bir biçimde
saklanmasıdır. Böylece, bir sorun olduğunda geliştiricilerin hata ayıklaması çok kolay hale geliyor.
DispatcherServlet nedir
JWT Nedir?
JWT, Base64 biçiminde kodlanmış 3 ayrı JSON parçasından oluşmaktadır. Parçalar nokta (.)
sembolüyle ayrılmakta ve bir bütün olarak JWT’yi temsil etmektedir.
Avantajları
JWT’ler durumsuz (stateless) oldukları için kullanıcı durumlarının elde edilmesi için veritabanı
sorgulamasına gerek kalmaz.
Dezavantajları
JWT anahtarı yeterince güçlü değilse kırılması daha kolay olur.
Collection
"Collection" interface'den katılım alan alt sınıflar "[Link]" paketi altında toplanmıştır. "Collection"
interface ile liste tipinde veri tutan bir veri yapısında hangi işlevlerin olması gerektiği belirtilmiştir.
Liste tipinde veri tutacak olan her sınıf doğrudan veya dolaylı yoldan bu interface'den katılım
almalıdır. Bu nedenle soyağacının en tepesinde "Collection" interface yer almaktadır.
Java Collection sınıfları ile liste halindeki veri üzerinde arama, ekleme, silme ,sıralama gibi işlemler
yapabilirsiniz.