Yazılım Mülakatı Soruları (Junior, Medior, Senior)
- Repo yenidir. Sürekli olarak güncellenmektedir. Takibe almayı unutmayın. (Star, Watch)
- Sadece soruların olduğu listeye buradan ulaşabilirsiniz.
- Girdiğiniz mülakatlar da karşınıza çıkan soruları eklemek isterseniz pull request gönderebilirsiniz. Merge ediyorum.
Virtual class nedir?
- Virtual yapısı, nesne yönelimli programlama (OOP) konseptlerinden biridir ve bir sınıfın üye işlevlerinin, türetilmiş sınıflar tarafından yeniden tanımlanabileceği anlamına gelir. Bu, türetilmiş sınıfların üye işlevlerinin davranışını kontrol etmesine izin verir.
Partial class nedir?
- Partial sınıflar, C# programlama dilindeki bir özelliktir. Bir sınıfı bölümlere ayırmak ve farklı dosyalarda tanımlamak için kullanılırlar. Partial sınıflar, aynı sınıfa ait kodun farklı dosyalarda veya ayrı bölmelerde dağıtılmasına izin verir.
- Bu özellik, büyük ölçekli projelerde sınıfların daha iyi organize edilmesini sağlar ve birden fazla geliştirici aynı sınıf üzerinde çalışırken çakışmaları azaltır. Örneğin, bir sınıfın uygulama mantığını, arayüz tanımlarını veya veritabanı işlemlerini farklı dosyalarda belirli bölümlere ayırabilirsiniz.
- Partial sınıfların kullanımı, sınıfın kodunun karmaşıklığını azaltır ve sınıfın bakımını ve genişletilebilirliğini kolaylaştırır. Ayrıca, otomatik kod üreten araçlar veya tasarım araçları tarafından üretilen kodu manuel olarak genişletebilir ve değiştirebilirsiniz.
- Kısacası, partial sınıflar, bir sınıfın kodunu farklı dosyalarda veya bölmelerde organize etmek ve büyük projelerde sınıfın geliştirilmesini kolaylaştırmak için kullanılan bir C# özelliğidir.
Static durumları ve kullanımı hakkında açıklama yapınız?
- Static, OOP'de kullanılan bir anahtar sözcüktür ve sınıf üyeleri veya değişkenler tanımlarken kullanılabilir. Bu, sınıfın örneğine bağlı olmayan bir değişken veya fonksiyon olduğunu gösterir ve bu değişken veya fonksiyona sınıfın adıyla erişilebilir.
nopCommerce projesi nedir? (Gireceğiniz mülakat firmasının sektörü e-ticaret ise...)
- nopCommerce, açık kaynaklı bir e-ticaret platformudur ve .NET teknolojileri kullanılarak geliştirilmiştir. Bu proje, birçok dilde ve para biriminde çeviri desteği, esnek ürün yönetimi ve ödeme entegrasyonu gibi özellikler sunar.
Elasticsearch nedir?
- Elasticsearch, açık kaynaklı bir arama ve analiz motorudur ve büyük miktardaki verileri işlemek ve aramak için kullanılır. Elasticsearch, bir ilişkisel veritabanından farklıdır ve verileri JSON belgeleri olarak saklar.
Redis nedir?
- Redis, açık kaynaklı bir anahtar-değer depolama sistemidir ve en çok performanslı ve ölçeklenebilir uygulamalarda kullanılır. Redis, verileri bellek içinde saklar ve bu nedenle hızlı bir şekilde erişilebilir.
İlişkisel ve NoSQL veritabanlarını açıklayınız?
- İlişkisel veritabanları, verileri birbirleriyle ilişkili tablolarda saklar. Bu, SQL dilinin kullanılmasıyla yapılandırılmıştır. NoSQL veritabanları ise yapılandırması daha esnektir ve genellikle yüksek performanslı uygulamalarda kullanılır.
Lazy loading, encapsulation, polymorphism, inheritance verileri nedir?
- Bu konular, OOP'nin temel prensipleridir ve yazılım geliştirme sürecinde sık sık kullanılır. Lazy loading, uygulamanın ihtiyacı olduğu anda verileri yükler ve gereksiz yere kaynak tüketimini önler. Encapsulation, sınıfın içindeki verilerin ve işlevlerin korunmasını sağlar ve sınıfın dışındaki etkileşimlerin kısıtlanmasına yardımcı olur. Polymorphism, bir nesnenin farklı şekillerde davranabilmesini sağlar. Inheritance, bir sınıfın başka bir sınıftan türetilmesini ve üye işlevlerinin ve değişkenlerinin miras alınmasını sağlar.
SOLID prensipleri hakkında açıklama yapabilirmisin?
- SOLID, yazılım geliştirme dünyasında sık sık kullanılan bir prensipler kümesidir. SOLID, Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation ve Dependency Inversion olmak üzere beş prensipten oluşur. Bu prensipler, yazılım geliştiricilerinin yazılımın esnekliğini artırmasına ve daha sürdürülebilir bir kod tabanı oluşturmasına yardımcı olur.
- Solid prensipleri, yazılım geliştirme sürecinde kaliteli, sürdürülebilir ve esnek bir kod oluşturmayı hedefleyen bir dizi kurallardır. SOLID, Robert C. Martin tarafından önerilen ve beş temel prensibi içeren bir akronimdir:
- Single Responsibility Principle (Tek Sorumluluk Prensibi): Her sınıf veya modül, yalnızca bir tek sorumluluğa sahip olmalı ve bu sorumluluğu başarılı bir şekilde yerine getirmelidir.
- Open/Closed Principle (Açık/Kapalı Prensibi): Bir yazılım birimi (sınıf, fonksiyon, modül) değişikliklere kapalı (closed) olmalı, ancak yeni işlevsellik eklemek için açık (open) olmalıdır. Yani mevcut kodu değiştirmek yerine, yeni özellikler eklemek için genişletilebilir olmalıdır.
- Liskov Substitution Principle (Liskov Yerine Geçme Prensibi): Bir üst sınıfın nesneleri, onun alt sınıfları tarafından yerine geçebilmelidir. Yani alt sınıflar, üst sınıfın belirlediği davranışları korumalı ve bu davranışları değiştirmeden genişletebilmelidir.
- Interface Segregation Principle (Arayüz Ayrım Prensibi): İstemcilerin kullanmadığı özellikleri içeren geniş arayüzler yerine, daha küçük ve özelleştirilmiş arayüzler kullanılmalıdır. Bir sınıf, sadece ihtiyaç duyduğu metotları içeren arayüzleri uygulamalıdır.
- Dependency Inversion Principle (Bağımlılığı Tersine Çevirme Prensibi): Yüksek seviyeli modüller, düşük seviyeli modüllere doğrudan bağlı olmamalıdır. Bunun yerine, her iki seviyenin de soyutlamalara (abstractions) bağımlı olması gerekmektedir.
- Bu prensipler, yazılımın daha kolay bakım yapılabilir, test edilebilir ve genişletilebilir olmasını sağlar. Aynı zamanda kodun tekrar kullanılabilirliğini artırır ve bağımlılıkları azaltır.
Procedure ve Function arasındaki fark nedir, ne amaçla kullanırız?
-
Prosedürler ve fonksiyonlar, programlarda tekrar kullanılabilir kod blokları oluşturmak için kullanılan yapısal programlama araçlarıdır. İkisi arasındaki temel fark, geri dönüş değeri olup olmamasıdır. Prosedürler, belirli bir görevi gerçekleştirmek için kullanılan kod bloklarıdır. Geri dönüş değeri yoktur veya değeri yok sayılır. Genellikle verileri işlemek, ekrana çıktı yazdırmak veya başka bir işlemi gerçekleştirmek gibi işlevleri yerine getirmek için kullanılırlar.
-
Fonksiyonlar ise prosedürlerden farklı olarak geri dönüş değeri olan kod bloklarıdır. Fonksiyonlar, belirli bir hesaplama yapar ve sonucu çağıran yere döndürür. Fonksiyonlar, genellikle bir değeri hesaplamak, işlemek ve bu değeri geri döndürmek için kullanılır. Hangisini tercih edeceğiniz, yapmanız gereken işin doğası ve ihtiyaçlarınıza bağlıdır. Eğer bir görevi gerçekleştirmek için geri dönüş değeri gereksizse veya dikkate alınmayacaksa, prosedür kullanabilirsiniz.
-
Örneğin, ekrana bir metin yazdırmak veya verileri sıralamak için bir prosedür kullanabilirsiniz. Ancak, bir hesaplama yapmanız veya bir değeri döndürmeniz gerekiyorsa, fonksiyonları tercih etmek daha uygun olabilir. Örneğin, iki sayının toplamını hesaplamak veya bir liste içindeki en büyük sayıyı bulmak için bir fonksiyon kullanabilirsiniz. Özetlemek gerekirse, prosedürler genellikle görevleri gerçekleştirmek için kullanılırken, fonksiyonlar hesaplamalar yapmak ve sonuçları döndürmek için tercih edilir. Hangisini seçeceğiniz, işin doğasına ve ihtiyaçlarınıza bağlıdır.
Dependency injection nedir?
- Dependency Injection (DI), yazılım geliştirme sürecinde sık sık kullanılan bir tasarım desenidir. Bu desen, bir nesnenin ihtiyaç duyduğu bağımlılıkları dışarıdan almasına ve sınıfın içinde doğrudan oluşturulmamasına izin verir. Bu, sınıfların daha bağımsız hale gelmesini ve daha kolay test edilebilir hale gelmesini sağlar.
- Dependency Injection, bir yazılım tasarım deseni olarak, bağımlılıkların (dependencies) dışarıdan bir bileşenin içine enjekte edilmesini sağlar. Bu desen, bir bileşenin bağımlılıklarını oluşturmak ve yönetmek yerine, bu bağımlılıkların dışarıdan bir kaynak tarafından sağlanmasını sağlar.
- Bir örnekle açıklamak gerekirse, bir Araba nesnesi oluşturmak istediğimizi düşünelim. Araba'nın bir motor, lastikler, direksiyon vb. gibi birçok bağımlılığı vardır. Geleneksel bir yaklaşımda, Araba nesnesi oluşturulurken bu bağımlılıkların her biri tek tek oluşturulur veya oluşturulması için başka bir bileşen çağrılır.
- Fakat bu yaklaşım, kodun karmaşıklaşmasına ve sıkı bir şekilde bağımlı hale gelmesine neden olabilir. Bu durumda, Dependency Injection kullanarak Araba nesnesini oluşturmak daha uygun olacaktır.
- Dependency Injection kullanarak, Araba bileşenini oluşturmak istediğimizde, Araba'nın bağımlılıkları dışarıdan bir kaynaktan (örneğin bir IOC Container) alınır ve Araba bileşenine enjekte edilir. Bu sayede Araba bileşeni, bağımlılıklarını yönetmek yerine, bunları dışarıdan gelen kaynak tarafından sağlanır.
- Özetle, Dependency Injection, kodun daha modüler ve esnek olmasını sağlar. Bu desen, yazılım bileşenlerinin birbirlerine sıkı bir şekilde bağımlı olmaktan kurtulmasına ve daha kolay test edilebilmesine olanak tanır.
Örnek;
public class Araba {
private Motor motor;
private Tekerlekler tekerlekler;
private Direksiyon direksiyon;
public Araba(Motor motor, Tekerlekler tekerlekler, Direksiyon direksiyon) {
this.motor = motor;
this.tekerlekler = tekerlekler;
this.direksiyon = direksiyon;
}
// Araba'nın diğer metotları...
}
Abstract ve interface benzerlik farklılıkları nelerdir?
- Abstract ve Interface, OOP'de sık kullanılan kavramlardır. Abstract sınıflar, bir sınıfın soyut bir temel sınıfı olduğunu belirtir ve soyut işlevleri veya değişkenleri içerebilir. Interface'ler ise, bir sınıfın uygulaması gereken belirli işlevleri tanımlar ve sınıflar arasındaki bağımlılıkları azaltmak için kullanılır.
Docker nedir kısaca açıklarmısınız?
- Docker, yazılım uygulamalarının hızlı bir şekilde dağıtılmasını, yönetilmesini ve çalıştırılmasını sağlayan bir platformdur. Docker, uygulamanın bağımlılıklarını ve konfigürasyonunu içeren sanal ortamlar oluşturur.
RabbitMQ nedir?
- RabbitMQ, açık kaynaklı bir mesajlaşma aracıdır ve uygulamalar arasındaki mesajlaşmayı kolaylaştırır. Bu araç, birçok farklı protokolü destekler ve birçok dilde kullanılabilir.
Microservice ve monolitik sistemler arasındaki farklılıklar nelerdir?
- Microservice mimarisi, bir uygulamanın farklı işlevlerinin farklı servisler halinde ayrılmasıdır. Bu yaklaşım, uygulamayı daha esnek hale getirir, ölçeklenebilirliği artırır ve hata ayıklama ve bakımı kolaylaştırır. Monolitik mimari ise, tüm uygulamanın tek bir yapıda oluşturulmasıdır. Bu yaklaşım, uygulama geliştirmeyi daha kolay hale getirir, ancak büyük uygulamalarda ölçeklenebilirlik sorunlarına neden olabilir. Microservice yaklaşımı, uygulamanın her bir işlevini ayrı ayrı yönetme ve ölçekleme imkanı sağlar.
AddScope, AddSingleton, AddTransient nedir kısa ve net bir şekilde açıklayabilirmisin?
- AddScope: Bu metot, bağımlılık enjeksiyonu konteynerine bir servis kaydederken, bu servisin her talep edildiğinde bir kapsam (scope) boyunca aynı örneğini döndürmesini sağlar. Kapsam boyunca aynı örneğin kullanılması, örneğin bir HTTP isteği süresince aynı servis nesnesinin paylaşılmasını sağlar. Bu genellikle, bir istek içinde birden fazla bileşenin aynı verilere veya durumlara erişmesi gerektiği durumlarda kullanılır.
- AddSingleton: Bu metot, bağımlılık enjeksiyonu konteynerine bir servis kaydederken, bu servisin uygulama ömrü boyunca yalnızca bir kez oluşturulup paylaşılmasını sağlar. Herhangi bir talep edildiğinde aynı örneği döndürür. Bu, uygulama boyunca tek bir örnek kullanmak istediğiniz durumlarda faydalıdır. Örneğin, bir konfigürasyon ayarını veya veritabanı bağlantısını paylaşmak için kullanılabilir.
- AddTransient: Bu metot, her talep edildiğinde yeni bir örnek oluşturarak her bir talep için farklı bir örneği döndürmek üzere bir servis kaydeder. Yani her talep edildiğinde bir örnek oluşturulur ve bu örnek sadece bu talep için kullanılır. Bu, hafızada paylaşımlı bir durumu veya veriyi saklamak yerine, her talep edildiğinde taze bir örneğe ihtiyaç duyduğunuz durumlarda kullanışlıdır. Örneğin, geçici bellek kullanıcı oturumlarını veya işlem durumunu depolamak için kullanılabilir.
- Bu üç metot, bağımlılıkların nasıl kaydedileceği ve hangi örneklerin nasıl döndürüleceği konusunda farklı davranışları temsil eder. Uygulamanızın gereksinimlerine göre doğru yöntemi seçmek önemlidir.
Int32 ve Int64 arasında ki fark nedir?
- Int32 ve Int64, tamsayı veri tiplerini ifade eder. Farkları, temsil ettikleri tamsayı değerlerinin boyutlarından kaynaklanır.
- Int32, 32 bit (4 byte) uzunluğunda bir tamsayıyı temsil eder. Bu veri tipi, -2,147,483,648 ile 2,147,483,647 arasındaki tamsayı değerlerini alabilir. Negatif ve pozitif değerler için aynı miktarda alan ayrılır.
- Int64 ise 64 bit (8 byte) uzunluğunda bir tamsayıyı temsil eder. Bu veri tipi, -9,223,372,036,854,775,808 ile 9,223,372,036,854,775,807 arasındaki tamsayı değerlerini alabilir. Negatif ve pozitif değerler için aynı miktarda alan ayrılır.
- Bu nedenle, Int32 daha küçük bir değer aralığına ve daha az bellek kullanımına sahiptirken, Int64 daha büyük bir değer aralığına ve daha fazla bellek kullanımına sahiptir. Seçiminiz, temsil etmek istediğiniz değerlerin aralığına bağlı olacaktır.
DataRow ve DataReader arasındaki fark nedir?
- DataRow ve DataReader, .NET Framework'teki ADO.NET kütüphanesindeki farklı sınıflardır ve veritabanı işlemleriyle ilgili farklı amaçlar için kullanılırlar.
- DataRow, DataTable nesnesindeki bir veri kaydını temsil eder. DataTable, tablo yapısında verileri depolamak için kullanılan bir sınıftır. DataRow ise DataTable içindeki her bir veri kaydını temsil eder. Bir DataRow nesnesi, tablodaki her bir sütunun değerlerini saklar.
- DataReader ise veritabanı işlemlerinde verileri okumak için kullanılan bir sınıftır. Bir veritabanı sorgusu çalıştırıldığında, DataReader sorgu sonucundaki veri akışını temsil eder ve verileri satır satır okur. DataReader, verileri sorgudan döndürerek, bellekte daha az yer kaplayarak daha hızlı ve verimli bir şekilde çalışır. Verileri tek yönlü (forward-only) olarak okur, yani ileri doğru hareket ederek verilere erişir. DataReader, veritabanı bağlantısı açık olduğu sürece verileri okumaya devam eder.
- Özetle, DataRow verileri tablo yapısında saklamak ve işlemek için kullanılırken, DataReader verileri veritabanından okumak ve işlemek için kullanılır.
Dictionary ile List arasında ki fark nedir hangisi daha hızlı çalışır?
- C# dilinde Dictionary ve List, farklı veri yapılarıdır ve farklı amaçlar için kullanılırlar. İkisi arasındaki ana fark, verileri nasıl depoladıkları ve erişim süreleridir.
- Depolama Yapısı:
- List: List, elemanları bir sıra içinde depolar. Her eleman bir indeks numarasıyla erişilebilir ve elemanlar eklenme sırasına göre tutulur.
- Dictionary: Dictionary, bir anahtar-değer çiftleri koleksiyonunu depolar. Her bir anahtar benzersiz olmalıdır ve her anahtarın karşısında bir değer bulunur. Anahtarlar, elemanları hızlı bir şekilde erişmek için kullanılır.
- Erişim Süresi:
- List: List, indeks numarasına dayalı olarak elemanlara erişir. Dolayısıyla, bir elemana erişmek için indeks numarasını bilmek gereklidir. Elemanlara erişim süresi O(1) olarak kabul edilir.
- Dictionary: Dictionary, anahtarlar aracılığıyla elemanlara erişir. Anahtarın değeri bulmak için bir karma işlev kullanılır. Bu karma işlemi sayesinde elemanlara hızlı bir şekilde erişilebilir. Elemanlara erişim süresi de O(1) olarak kabul edilir.
- Sonuç olarak, Dictionary ve List arasında erişim hızı açısından bir fark yoktur, her ikisi de O(1) süresinde elemanlara erişir. Ancak, elemanlara erişmek için kullanılan yöntemler farklıdır. Listeler, indeks numaralarına dayalı olarak elemanlara erişim sağlar, Dictionary'ler ise anahtarlar aracılığıyla elemanlara erişir. Dolayısıyla, kullanmanız gereken veri yapısı, işlevsel gereksinimlerinize ve verilerinizi nasıl organize etmek istediğinize bağlıdır.
Sealed class nedir?
- C# dilinde "sealed" (mühürlü) bir sınıf, miras alınmasını engellemek için kullanılan bir özelliktir. Sealed sınıflar, alt sınıfların oluşturulmasını ve bu sınıflardan türetilmelerini önler. Yani, bir sınıfı sealed olarak işaretlerseniz, başka bir sınıfın bu sınıftan türemesine izin vermezsiniz.
- Sealed sınıflar genellikle, tamamen oluşturulmuş ve genişletilmesine veya değiştirilmesine ihtiyaç duyulmayan sınıflar için kullanılır. Bu, sınıfın davranışını veya yapısını değiştirmemeyi ve sağlam bir şekilde korumayı amaçlayan tasarım kararlarında kullanışlı olabilir.
- Bir sınıfı sealed olarak işaretlemek, kodunuzun belirli bir noktada kesintiye uğramasını engellemeye yardımcı olabilir. Sealed sınıflar aynı zamanda performans açısından da iyileştirme sağlayabilir, çünkü C# derleyicisi, sealed sınıfların daha verimli bir şekilde optimize edilebileceğini bilir.
- Sonuç olarak, sealed sınıflar C# dilinde miras alınmasını engelleyen sınıflardır. Bu özellik, kodunuzun sağlamlığını korumak ve belirli bir tasarımı güvence altına almak için kullanılabilir.
- Detaylı kaynak; https://www.borakasmer.com/cda-sihirli-sealed-keywordu/
Record class nedir?
- C# 9.0 ile birlikte gelen "record" sınıfı, sadece veri taşıyan ve genellikle değişmez olan veri yapılarını temsil etmek için kullanılan bir sınıf türüdür. "record" sınıfları, değer nesneleri (value objects) olarak adlandırılan ve özellikleri üzerinden eşitlik ve eşleştirme gibi işlemler gerçekleştiren sınıfları tanımlamak için kullanılır.
- "record" sınıfları, verileri depolamak için otomatik olarak gerekli tüm kodu oluştururlar. Bu, özellikleri tanımlarken getter ve setter gibi ayrı kodları yazmanıza gerek kalmadan basit bir şekilde özellikleri belirtebileceğiniz anlamına gelir. Ayrıca, "record" sınıfları varsayılan olarak "değer eşitliği" (value equality) olarak adlandırılan işlemleri destekler. Yani, iki "record" nesnesi aynı değere sahipse, bunlar eşit olarak kabul edilir.
- Aşağıda basit bir "record" sınıfı örneği verilmiştir:
public record Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
public int Age { get; init; }
}
- Yukarıdaki örnekte, "Person" sınıfı, bir kişinin adını, soyadını ve yaşını depolayan bir "record" sınıfıdır. "init" özelliği, özelliklerin sadece başlatıcı tarafından ayarlanabileceğini belirtir, yani sınıf oluşturulduktan sonra değerleri değiştirilemez.
- "record" sınıfları, özellikleri üzerinden desen eşleştirmesi (pattern matching) gibi işlemleri kolaylaştırır ve hızlıca verileri kopyalayıp değiştirmenizi sağlar. Ayrıca, "record" sınıfları, diğer sınıflarla birlikte kullanıldığında kodun daha okunabilir ve sürdürülebilir olmasını sağlayabilir.
- Bu nedenlerle, C# "record" sınıfları genellikle verileri taşımak, eşleştirmek ve karşılaştırmak için kullanılan basit veri yapısı sınıflarını tanımlamak için tercih edilir.
CQRS Design Pattern nedir?
-
CQRS, "Command Query Responsibility Segregation" (Komut Sorgu Sorumluluğu Ayrımı) kelimelerinin baş harflerinden oluşan bir tasarım desenidir. Bu desen, bir uygulama veya sistemdeki komutları (command) ve sorguları (query) ayrı ayrı ele almayı önerir.
-
Geleneksel bir mimaride, komutlar ve sorgular genellikle aynı veri modelini kullanır ve aynı arayüzleri kullanarak veriye erişirler. Ancak CQRS deseninde, komutlar ve sorgular ayrı ayrı ele alınır ve farklı modeller ve mekanizmalar kullanılır.
-
CQRS deseninde, komutlar veri üzerinde değişiklik yapmak için kullanılır. Bunlar genellikle veri ekleme, güncelleme veya silme gibi işlemleri temsil eder. Komutlar, işlem sonrası geri bildirim veya asenkron olaylar yoluyla sonuç döndürebilir.
-
Sorgular ise veriye erişmek ve okumak için kullanılır. Sorgular, genellikle veriyi sorgulama, filtreleme ve görüntüleme gibi işlemleri gerçekleştirmek için kullanılır. Sorgular, performans ve ölçeklenebilirlik açısından optimize edilmiş ayrı bir veri modeli kullanabilir.
-
CQRS deseni, bir uygulamanın karmaşık işlemleri ve veri erişimi gerektiren senaryolarında kullanışlı olabilir. Özellikle büyük ve karmaşık sistemlerde, okuma ve yazma işlemlerinin farklı gereksinimlere sahip olduğu durumlarda CQRS deseni kullanılabilir. Bu desen, sistem performansını artırabilir, ölçeklenebilirliği iyileştirebilir ve kod tabanını daha modüler hale getirebilir.
-
Ancak CQRS deseni, uygulama geliştirme sürecindeki karmaşıklığı artırabilir ve gereksinimleri daha iyi anlamayı gerektirebilir. Bu nedenle, kullanılacağı senaryolar dikkatlice değerlendirilmeli ve doğru bir şekilde uygulanmalıdır.
DDD Design Pattern nedir?
-
DDD (Domain-Driven Design), yazılım geliştirme sürecinde bir tasarım yaklaşımı ve bir dizi prensiptir. DDD'nin temel amacı, karmaşık iş mantığını ve etkileşimleri içeren bir yazılımın anlaşılabilir, sürdürülebilir ve esnek bir şekilde geliştirilmesini sağlamaktır.
-
DDD'nin kullanımı, bir yazılım projesindeki temel iş alanı (domain) kavramlarına odaklanmayı ve bu kavramları yazılım modeline doğru şekilde yansıtmayı hedefler. İş alanı, bir organizasyonun ana faaliyetlerini ve süreçlerini temsil eden kritik iş kurallarını içerir. DDD, bu iş kurallarını ve iş süreçlerini anlamaya, modellemeye ve uygulamaya yönelik bir metodoloji sunar.
-
DDD'nin sağladığı faydalar şunlardır:
-
Derin iş anlayışı: DDD, proje paydaşları arasında ortak bir dil oluşturmayı teşvik eder. Bu, işin gerçek dünyadaki süreçlerini ve gereksinimlerini anlamaya yönelik derin bir iş anlayışının geliştirilmesini sağlar. Böylece, yazılım modeli işin gerçek ihtiyaçlarını doğru bir şekilde yansıtabilir.
-
Esneklik ve evrilebilirlik: DDD, yazılımın evrimsel olmasını sağlar. İş mantığındaki değişiklikler, yazılım modelinde yapılan değişikliklerle uyumlu olacak şekilde kolayca gerçekleştirilebilir. DDD'nin bileşenler arasındaki net sınırlarının ve iyi tanımlanmış bağlantılarının olması, değişikliklerin diğer bileşenlere minimum etkisini sağlar.
-
Daha iyi modülerlik: DDD, iş domainini ve bileşenlerin sorumluluklarını net bir şekilde tanımlar. Bu, yazılımın modüler bir yapıya sahip olmasını sağlar. Modülerlik, bileşenlerin bağımsız olarak geliştirilmesini, test edilmesini ve sürdürülmesini kolaylaştırır.
-
Test edilebilirlik: DDD, iş domainindeki iş kurallarını açık bir şekilde ifade etmeyi teşvik eder. Bu, iş kurallarının doğru bir şekilde test edilmesini sağlar. DDD, test edilebilirlik için mocklama ve taklit (stub) gibi teknikleri destekler.
-
Ekip işbirliği: DDD'nin ortak bir dil ve net bir iş domaini modeli sağlaması, ekipler arasında daha iyi bir işbirliği sağlar. İş süreçlerini anlamak ve yazılım modelini paylaşmak, iş analistleri, geliştiriciler ve diğer paydaşlar arasında etkili bir iletişimi teşvik eder.
-
DDD, karmaşık iş mantığını yönetmek için bir dizi prensip, tasarım deseni ve teknik sağlar. Bu yaklaşım, yazılım projelerinin başarılı bir şekilde geliştirilmesi ve sürdürülmesi için değerli bir araçtır.
Outbox Design Pattern nedir, ne için kullanılır?
- Hazırlanıyor...
Aggregate Root nedir?
-
Aggregate kökü (Aggregate Root), bir yazılım sistemi içindeki nesnelerin hiyerarşik ilişkilerinin yönetildiği bir kavramdır. Bu kavram, Domain Driven Design (DDD) adı verilen bir yazılım tasarım yaklaşımının bir parçasıdır.
-
Aggregate, birbirleriyle yakından ilişkili olan nesnelerin bir gruplamasıdır. Aggregate Root ise bu gruplamadaki ana veya kök nesnedir. Bir Aggregate Root, bir Aggregate içinde diğer nesnelerle etkileşim kurabilen ve onları yöneten bir nesnedir. Diğer nesneler, sadece Aggregate Root üzerinden erişilebilir ve bu sayede Aggregate'ın tutarlılığı korunur.
-
Aggregate Root'un birkaç önemli işlevi vardır:
-
Tutarlılık sağlama: Aggregate Root, içindeki diğer nesnelerin durumunu yöneterek, Aggregate'ın tutarlılığını korur. Yani, Aggregate'ın bileşenleri arasındaki ilişkileri kontrol eder ve Aggregate'ın bütünlüğünü sağlar.
-
İşlem sınırlarını tanımlama: Aggregate Root, Aggregate içindeki işlemlerin sınırlarını belirler. Diğer nesneler yalnızca Aggregate Root üzerinden erişilebildiği için, Aggregate'ın dışındaki nesneler doğrudan değiştirilemez veya etkileşimde bulunamaz. Bu, Aggregate'ın bütünlüğünü korumaya yardımcı olur ve sistemdeki yanlışlık riskini azaltır.
-
Nesneler arasında birbirine bağlılık sağlama: Aggregate Root, içindeki diğer nesnelerin birbirleriyle ilişkili olduğu bir yapı sağlar. Nesneler arasındaki bağlantıları yönetir ve bu bağlantıların tutarlı kalmasını sağlar.
-
Aggregate Root, bir yazılım sistemindeki karmaşayı azaltmak ve sistemdeki nesnelerin düzenlenmesini ve yönetilmesini kolaylaştırmak için kullanılır. DDD'nin temel prensiplerinden biridir ve yazılım tasarımında Aggregate'ların doğru şekilde tanımlanması ve kullanılması önemlidir.
-
Örnek;
-
Varsayalım ki bir müşteri (Customer) ve bu müşterinin siparişleri (Order) adında iki sınıfımız var. Bu iki sınıf arasında Aggregate Root ilişkisi bulunacak.
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
// Diğer özellikler
// Customer sınıfı, Order nesnelerinin bir koleksiyonunu içeriyor
public ICollection<Order> Orders { get; set; }
// Aggregate Root işlemleri
public void PlaceOrder(Order order)
{
// Siparişin geçerli olup olmadığını kontrol etme
// Diğer işlemler
Orders.Add(order);
}
public void CancelOrder(Order order)
{
// Siparişin iptal işlemleri
// Diğer işlemler
Orders.Remove(order);
}
}
public class Order
{
public int Id { get; set; }
public DateTime OrderDate { get; set; }
// Diğer özellikler
}
-
Yukarıdaki örnekte Customer sınıfı, Aggregate Root rolünü üstleniyor. Orders koleksiyonu üzerinden Customer'ın ilişkili olduğu Order nesnelerine erişim sağlanıyor. Customer sınıfı, PlaceOrder ve CancelOrder gibi işlemleri gerçekleştirerek Aggregate Root'un tutarlılığını sağlıyor.
-
Bu örnekte, Aggregate Root olan Customer sınıfı üzerinden Order nesneleri yönetiliyor. Order nesneleri, Customer sınıfının içindeki Orders koleksiyonuna eklenip çıkarılıyor. Bu şekilde Aggregate Root ilişkisi ve tutarlılık sağlanmış oluyor.
JWT Token ve Yapısı Nedir?
-JWT, kimlik doğrulama ve yetkilendirme için kullanılan bir token formatıdır.
JWT Yapısı
Header
JWT'nin imzalanması/şifrelenmesinde kullanılan algoritmayı içerir, genellikle HMAC SHA-256 veya HS256 olarak ayarlanır.
Payload(veri taşıyıcı)
Gerçek verileri içerir. Bu veriler, JSON formatında key-value çiftleri olarak temsil edilir.
Signature
İmza, header ve payload'ın birleştirilmesiyle oluşturulan bir koddur. İmza, headerda belirtilen algoritmaya göre oluşturulur. İmzanın doğrulanmasıyla, JWT'nin bütünlüğü sağlanır ve içerdiği verilerin güvenilirliği sağlanır.
JWT Authentication-Authorization Süreci Nedir?
-JWT, kimlik doğrulama (authentication) ve yetkilendirme (authorization) süreçlerinde kullanılır. Bir kullanıcı oturum açtığında, sunucu tarafından verilen bir JWT ile kullanıcının kimliği doğrulanır ve bu token, kullanıcının her isteğinde sunucuya gönderilerek yetkilendirme işlemleri gerçekleştirilir. Kaynak sunucusu, JWT'yi doğrulamak zorundadır.
OAuth 2.0 nedir?
-OAuth, kullanıcıların bir uygulamaya erişim yetkisi verme ve yetkilendirme işlemlerini sağlayan bir protokoldür.Örneğin, bir kullanıcının Facebook hesabını kullanarak başka bir uygulamaya erişim sağlamak istediğinde, OAuth protokolü kullanılarak yetkilendirme sağlanır.
Value Object, Reference Object arasındaki farklar nelerdir. Açıklayınız?
- Value Object, değeri üzerinden karşılaştırılan ve değişmez bir yapıdır, referansı yoktur. Örneğin, tarih veya para birimi.
- Reference Object, bellekte referansa sahip nesnelerdir ve kimlikleri vardır. Değişebilirler.
Entity kavramları nedir kısaca özetleyiniz?
- Entity, benzersiz bir kimliğe sahip olan ve yaşam döngüsü boyunca değişen bir nesnedir. Örneğin, bir kullanıcı veya bir sipariş.
Event sourcing pattern hakkında ne biliyorsunuz nedir açıklayabilirmisiniz?
- Event Sourcing, verilerin her değişikliğinin olaylar (events) aracılığıyla kaydedildiği bir tasarım desenidir. Bu olaylar daha sonra geçmiş durumun yeniden oluşturulması veya analiz için kullanılabilir.
RabbitMQ Exchange Nedir ? Exchange Tipleri nelerdir?
- RabbitMQ Exchange, mesajların kuyruklara yönlendirildiği bir aracıdır. Exchange tipleri şunlardır: direct, fanout, topic, headers.
Fair Dispatch nedir? Nasıl kullanılır?
- Fair Dispatch, çoklu tüketiciye sahip bir RabbitMQ kuyruğunda mesajların adil bir şekilde dağıtılması anlamına gelir. Bunu sağlamak için, "prefetch count" ayarını kullanabilirsiniz. Detaylandırmak sizin elinizde.
Builder Design Pattern nedir ne amaçla kullanılır?
- Builder Tasarım Deseni, karmaşık nesnelerin oluşturulmasını basitleştirmek için kullanılır. Nesne oluşturma adımlarını ayırarak ve ardışık bir şekilde yapılandırarak kullanılır.
Spesification Design Pattern nedir ne amaçla kullanılır?
- Specification Tasarım Deseni, belirli bir kriteri karşılayan nesneleri filtrelemek veya seçmek için kullanılır. Özellikle sorgulamalarda ve filtrelemelerde kullanışlıdır.
Factory Design Pattern nedir ne amaçla kullanılır?
- Factory Tasarım Deseni, nesne oluşturmayı merkezileştirir ve farklı alt sınıf türlerini döndürmek için kullanılır. Nesne oluşturma sürecini soyutlar.
Saga Distributed Transactions Pattern nedir ne amaçla kullanılır?
- Saga, birçok adımdan oluşan işlemleri birden fazla servis arasında koordine etmek için kullanılan bir desen veya modeldir. Dağıtık işlemlerin güvenli ve tutarlı bir şekilde yürütülmesini sağlar.
ConcurrentBag nedir ne için kullanırız?
- ConcurrentBag, çoklu iş parçacığı tarafından erişilen bir koleksiyon türüdür ve özellikle paralel programlamada kullanılır. Ekleme ve çıkarmaları destekler.
Lock mekanizması nedir hiç kullandın mı ? Ne için kullandın?
- Kilitleme, çoklu iş parçacığı tarafından aynı anda erişilen kritik bölgeleri korumak için kullanılır. Özellikle paylaşılan verilere güvenli erişim sağlamak için kullanılırım. Örneğin, Monitor veya Mutex kullanabilirsiniz.
Thread Safe – ConcurrentQueue, ConcurrentDictionary, ConcurrentBag, ConcurrentStack ve BlockingCollection Koleksiyonları hakkında neler biliyorsunuz?
- Bu koleksiyonlar, çoklu iş parçacıkları arasında veri paylaşımını güvenli bir şekilde sağlayan koleksiyon türleridir. İş parçacıkları arasında eşzamanlı erişimi desteklerler.
Asenkron programlama nedir? Hangi problemlere çözüm sağlamaktadır?
- Asenkron programlama, uzun süren işlemleri engellemeden çalıştırmak için kullanılır. Özellikle kullanıcı arayüzü etkileşimi gibi durumlarda yanıt süresini artırır.
ORM nedir? .Net/.Net Core platformlarında yaygın olarak kullanılan ORM teknolojileri hangileridir?
- ORM (Object-Relational Mapping), nesne tabanlı programlama dilleri ile ilişkisel veritabanları arasında veri dönüşümünü kolaylaştıran bir yazılım teknolojisidir. .NET/.NET Core'da Entity Framework ve NHibernate gibi ORM teknolojileri yaygın olarak kullanılır.
Hangfire nedir? Hangi amaçla kullanılmaktadır?
- Hangfire, .NET tabanlı uygulamalar için planlanmış görevlerin ve arka plan işlemlerinin yönetimi için kullanılan bir açık kaynaklı bir kütüphanedir. Görevlerin otomatik olarak çalıştırılması ve izlenmesini sağlar.
CI/CD nedir?
- CI/CD (Continuous Integration/Continuous Delivery), yazılım geliştirme süreçlerinde sürekli entegrasyon ve sürekli dağıtım uygulamalarını ifade eder. Sürekli entegrasyon, yazılım değişikliklerinin sürekli olarak ana koda entegre edilmesini içerir. Sürekli dağıtım, yazılımın sürekli olarak kullanılabilir durumda olmasını sağlar.
Daha önce .Net/.Net Core platformlarında hangi test framework'lerini kullandınız?
- Bu soruya özel deneyiminizi belirtmeniz gerekecektir. .NET platformunda yaygın olarak kullanılan test framework'leri arasında NUnit, xUnit ve MSTest bulunur.
IoC nedir? Ne için kullanılır?
- IoC (Inversion of Control), yazılım bileşenlerinin nasıl birbirleriyle etkileşime geçeceğinin yönetildiği bir tasarım prensibidir. Geleneksel yaklaşımda bileşenler birbirlerine doğrudan bağımlıdır, ancak IoC'de bu bağımlılık tersine çevrilir ve bileşenlerin kontrolü dışarıdan sağlanır. Bu, yazılımın daha esnek, test edilebilir ve bakımı kolay hale gelmesini sağlar.
Docker ve Docker Compose arasında ki fark nedir?
-
Docker, uygulamaları konteynerlere paketlemek ve dağıtmak için kullanılan bir konteynerleştirme platformudur. Konteynerler, bir uygulamanın çalışması için gereken tüm bağımlılıkları içeren taşınabilir ve izole edilmiş bir ortam sağlar. Docker, bir uygulamanın birden fazla ortamda sorunsuz bir şekilde çalışmasını sağlar ve sunucu, masaüstü ve bulut gibi farklı platformlarda çalışabilen hafif ve hızlı konteynerler oluşturur.
-
Docker Compose ise Docker konteynerlerinin yönetimi için kullanılan bir araçtır. Docker Compose, tek bir yerde birden fazla konteyneri tanımlamak ve bunları bir arada çalıştırmak için YAML tabanlı bir dosya formatı kullanır. Bu dosya, birden fazla konteynerin oluşturulmasını, yapılandırılmasını ve birbirleriyle etkileşimini tanımlar. Docker Compose, çok bileşenli uygulamaları kolayca çalıştırmak ve yönetmek için kullanılır.
-
Özetle, Docker konteynerlerinin oluşturulması ve yönetimi için Docker kullanılırken, Docker Compose ise birden fazla konteynerin bir arada çalıştırılmasını ve yönetilmesini sağlar. Docker Compose, konteyner tabanlı uygulamaların hızlı ve tutarlı bir şekilde dağıtılmasını kolaylaştırır.