En Popüler C# ve .NET Mülakat Soruları ve Çözümleri

C Sharp mülakat soruları, yani C# ve .NET geliştirici adaylarının dil temellerini, bellek yönetimini, asenkron programlamayı ve ASP.NET Core mimarisini ne kadar derinden anladığını ölçer. 2012'den beri web projeleri yönetiyorum ve ekibe arka uç geliştirici alırken bu soruları masanın öbür tarafından soruyorum. Bu yazıda en sık karşılaştığım soruları, kısa çözümleriyle birlikte konu konu paylaşıyorum.
Liste, junior seviyeden kıdemli seviyeye doğru ilerliyor. Önce dilin temel davranışlarını, ardından koleksiyonları ve asenkron programlamayı, en sonda da ASP.NET Core, Entity Framework Core ve sistem tasarımı sorularını ele alıyorum. Her bölümde mülakatçının duymak istediği gerekçeyi ve adayların en sık düştüğü tuzağı ayrıca belirtiyorum. Böylece yalnız cevabı değil, cevabın arkasındaki mantığı da hazırlamış olursunuz. Bu yazıdaki önerilerin hiçbiri bir işe alım garantisi değildir; saha tecrübeme dayalı bir çalışma çerçevesidir ve her şirketin kendi değerlendirme ölçütleri vardır.
Amacım ezber listesi vermek değil. Her sorunun altında mülakatçının gerçekte neyi dinlediğini de anlatıyorum, çünkü iyi bir yanıt tanımı tekrar etmekten çok nedenini açıklar. Yazılımla ilgili diğer içeriklere yazılım kategorisinden ulaşabilirsiniz.
C Sharp mülakat soruları nelerdir ve hangi konuları kapsar?
C Sharp mülakat soruları beş ana başlığı kapsar: tip sistemi ve bellek, nesne yönelimli tasarım, koleksiyonlar ile LINQ, async/await ile eşzamanlılık, ASP.NET Core ile bağımlılık enjeksiyonu. Kıdem arttıkça sorular tanımdan çıkar; performans, hata ayıklama ve mimari karar gerekçesine kayar.
Hazırlanırken her başlıktan birkaç soruyu kendi cümlelerinizle yanıtlamayı deneyin. Ardından kısa bir kod parçası yazıp neden çalıştığını sesli anlatın. Mülakatçılar çoğunlukla doğru cevaptan çok düşünme sırasını izler; bu yüzden "bilmiyorum ama şöyle akıl yürütürdüm" demek, uydurma bir cevaptan her zaman daha iyi sonuç verir.
- Temel seviye: değer ve referans tipleri, string davranışı, erişim belirleyiciler.
- Orta seviye: LINQ, IEnumerable ve IQueryable farkı, async/await, istisna yönetimi.
- İleri seviye: çöp toplayıcı, Span, bağımlılık ömürleri, performans ölçümü.
C Sharp mülakat sorularında .NET sürümleri neden gündeme gelir?
Bu soru, adayın ekosistemi takip edip etmediğini anlamak içindir. Microsoft'un resmi .NET destek politikasına göre her kasım ayında yeni bir ana sürüm çıkar. Çift numaralı sürümler LTS olarak üç yıl, tek numaralılar ise STS olarak iki yıl ücretsiz destek alır.
Aynı sayfaya göre .NET 10 bir LTS sürümüdür ve desteği Kasım 2028'e kadar sürer. .NET 8 ile .NET 9 ise Kasım 2026'da destek dışına çıkar. Dolayısıyla "yeni projeye hangi sürümle başlarsınız?" sorusuna iyi yanıt, sürüm numarasını söylemekle bitmez; destek takvimini ve yükseltme maliyetini de hesaba katar.
Ayrıca .NET Framework ile modern .NET arasındaki farkı bilmenizi isterler. Framework yalnız Windows üzerinde çalışır ve bakım modundadır. Modern .NET ise çapraz platformdur, Linux konteynerlerinde rahatça koşar.
Değer tipi ile referans tipi arasındaki fark nedir?
Klasik bir açılış sorusudur. Değer tipleri (int, double, bool, struct, enum) veriyi doğrudan taşır; bir değişkeni diğerine atadığınızda kopya oluşur. Referans tipleri (class, string, array, delegate) ise nesnenin adresini taşır; atama yaptığınızda iki değişken aynı nesneyi gösterir.
Burada sık yapılan hata, "değer tipleri stack'te, referans tipleri heap'te durur" cümlesini kesin kural gibi söylemektir. Ancak bir sınıfın alanı olan int, sınıfla birlikte heap'te yaşar. Microsoft'un değer tipleri dokümantasyonu da ayrımı konuma göre değil, kopyalama davranışına göre tanımlar.
Örneğin Point p2 = p1; p2.X = 5; satırı struct için p1'i değiştirmez, class için değiştirir. Mülakatta bu küçük örneği yazıp açıklarsanız soru kapanır.
Boxing ve unboxing performansı nasıl etkiler?
Boxing, bir değer tipinin object ya da arayüz tipine atanırken heap üzerinde bir kutuya sarılmasıdır. Unboxing ise bu kutudan değeri geri çıkarmaktır. Her boxing yeni bir heap nesnesi üretir; bu da çöp toplayıcıya ek yük bindirir.
Örneğin eski ArrayList koleksiyonuna int eklediğinizde çalışma zamanı her elemanı bir kutuya sarar. Generic List<int> ise bu maliyeti ortadan kaldırır. Bu nedenle mülakatçı genellikle "generic'ler neden var?" sorusunu buraya bağlar.
İyi bir yanıt ölçümle biter: sıcak bir döngüde boxing şüphesi varsa BenchmarkDotNet ile bellek tahsisini ölçersiniz, tahmine dayanmazsınız.
String neden değiştirilemez ve StringBuilder ne zaman gerekir?
C# dilinde string değiştirilemez (immutable) bir referans tipidir. Bir stringi birleştirdiğinizde mevcut nesne değişmez, yeni bir nesne oluşur. Bu tasarım thread güvenliği ve string havuzu (interning) için avantaj sağlar.
Öte yandan döngü içinde yüzlerce kez birleştirme yaparsanız her adımda yeni bir nesne doğar. Böyle durumlarda StringBuilder tek bir tampon üzerinde çalışır ve tahsisi ciddi ölçüde azaltır. Yine de iki üç birleştirme için StringBuilder kullanmak kodu gereksiz yere uzatır; derleyici basit birleştirmeleri zaten verimli hâle getirir.
Mülakatçı burada genellikle "== ile Equals farkı" sorusuna geçer. String için ikisi de içerik karşılaştırır, çünkü string == operatörünü aşırı yükler.
Abstract class ile interface arasında nasıl seçim yaparsınız?
Bu soru nesne yönelimli tasarım anlayışınızı ölçer. Abstract class ortak durum (alan) ve ortak davranış taşıyabilir; bir sınıf ise yalnız tek bir sınıftan kalıtım alabilir. Interface bir sözleşme tanımlar ve bir sınıf birden fazla interface uygulayabilir.
C# 8 ile gelen varsayılan arayüz metotları bu ayrımı biraz bulanıklaştırdı. Yine de pratik kural değişmedi:
- Nesneler arasında "bir türüdür" ilişkisi ve ortak durum varsa abstract class seçersiniz.
- Farklı sınıflara ortak bir yetenek kazandırmak istiyorsanız interface seçersiniz.
- Test edilebilirlik ve bağımlılık enjeksiyonu hedefliyorsanız interface çoğu zaman daha esnektir.
Kısacası mülakatçı tanım değil, gerekçe duymak ister. Kendi projenizden bir örnek verirseniz yanıtınız çok daha güçlü durur.
SOLID ilkelerini C# kodunda nasıl gösterirsiniz?
SOLID sorusunda beş harfi saymak yetmez; her ilkeyi somut bir kod kararıyla eşleştirmeniz gerekir. Örneğin tek sorumluluk ilkesi, sipariş kaydeden bir sınıfın e-posta göndermemesi demektir. Açık kapalı ilkesi ise yeni bir ödeme yöntemi eklerken mevcut switch bloğunu değil, yeni bir sınıfı değiştirmenizdir.
Liskov ilkesinde klasik örnek, dikdörtgenden türeyen kareyi kullanır. Arayüz ayrımı ilkesi, dev bir IRepository yerine küçük ve amaca özel arayüzler önerir. Bağımlılığı tersine çevirme ilkesi ise ASP.NET Core'un bağımlılık enjeksiyonuyla doğrudan örtüşür.
Bu bölümde dürüst olmak da puan kazandırır. Her ilkeyi her yerde uygulamak aşırı soyutlamaya yol açar; küçük bir servis için beş katmanlı mimari kurmak bakım maliyetini artırır. Bunu söyleyebilen aday, deneyimli olduğunu gösterir.
IEnumerable ile IQueryable arasındaki fark nedir?
Entity Framework Core kullanan her ekip bu soruyu sorar. IEnumerable bellekteki koleksiyon üzerinde çalışır; filtreyi C# tarafında uygularsınız. IQueryable ise bir ifade ağacı taşır ve sorgu sağlayıcısı bu ağacı SQL'e çevirir.
Pratik sonuç şöyledir: DbSet üzerinde erken ToList() çağırırsanız bütün tabloyu belleğe çekip sonra filtrelersiniz. Where koşulunu ToList() öncesinde yazarsanız filtre veritabanında çalışır. Dolayısıyla yanlış sırayla yazdığınız tek bir satır, üretimde ciddi bir yavaşlığa yol açabilir.
| Özellik | IEnumerable | IQueryable |
|---|---|---|
| Çalıştığı yer | Uygulama belleği | Veri kaynağı (örneğin SQL) |
| Filtre | C# delegeleriyle | İfade ağacıyla, SQL'e dönüşür |
| Uygun kullanım | Bellekteki listeler | Veritabanı sorguları |
| Risk | Gereksiz veri çekme | Çevrilemeyen ifade hatası |
LINQ'da ertelenmiş çalışma (deferred execution) ne demektir?
LINQ sorguları, siz sonucu tüketene kadar çalışmaz. Where ya da Select yazdığınızda yalnız bir tarif oluşturursunuz; foreach, ToList(), Count() gibi bir çağrı gelince sorgu gerçekten koşar.
Mülakatçılar genellikle şu tuzağı kurar: aynı IEnumerable değişkenini iki kez foreach ile dolaşırsanız sorgu iki kez çalışır. Veritabanı sorgusunda bu, iki ayrı SQL çağrısı anlamına gelir. Bu yüzden sonucu birden fazla kez kullanacaksanız bir kez ToList() ile somutlaştırırsınız.
Ayrıca kapanış (closure) davranışını bilmenizi isterler. Sorgu içinde kullandığınız dış değişken, sorgu çalıştığı andaki değeri taşır; tanımlandığı andaki değeriyle değil.
async ve await gerçekte nasıl çalışır?
async/await, bekleyen bir işlemi thread'i bloke etmeden sürdürmenizi sağlar. Derleyici async metodu bir durum makinesine çevirir. await noktasına gelince, görev henüz bitmediyse metot çağırana döner; görev tamamlanınca kalan kısım devam eder.
En sık yanlış anlama, "async yeni bir thread açar" düşüncesidir. Oysa G/Ç işlemlerinde (HTTP isteği, veritabanı sorgusu) bekleme sırasında hiçbir thread meşgul olmaz. Microsoft'un asenkron programlama rehberi de bu ayrımı G/Ç bağımlı ve CPU bağımlı iş olarak açıklar.
Mülakatçı ardından şu hataları sorar:
- .Result ya da .Wait() kullanmak: senkronizasyon bağlamı olan ortamlarda kilitlenmeye yol açabilir.
- async void yazmak: istisnayı yakalayamazsınız; yalnız olay işleyicilerde kabul görür.
- CPU bağımlı işi await ile hızlanacak sanmak: bu iş için Task.Run gerekir.
Task ile Thread arasındaki fark nedir?
Thread, işletim sisteminin yürütme birimidir ve oluşturması pahalıdır. Task ise "gelecekte tamamlanacak bir iş" soyutlamasıdır; çoğu zaman thread havuzunda çalışır, bazen hiç thread kullanmaz. Bu nedenle modern C# kodunda doğrudan Thread oluşturmak nadirdir.
Sonraki adımda mülakatçılar genellikle ValueTask konusunu açar. ValueTask, sonucun çoğu zaman senkron döndüğü sıcak yollarda tahsisi azaltır. Ancak iki kez await edilemez ve yanlış kullanımda hata üretir; bu yüzden varsayılan tercih Task olarak kalır.
Ayrıca CancellationToken sorusuna hazır olun. Uzun süren her asenkron metoda iptal jetonu geçirmek, istemci bağlantıyı kestiğinde sunucunun boşuna çalışmasını engeller.
Çöp toplayıcı (GC) ve IDisposable nasıl birlikte çalışır?
.NET çöp toplayıcısı yönetilen belleği otomatik temizler ve nesneleri nesillere (generation 0, 1, 2) ayırır. Kısa ömürlü nesneler 0. nesilde hızla temizlenir; uzun yaşayanlar üst nesillere geçer. Büyük nesneler ise ayrı bir yığında (LOH) yaşar. Ayrıntılar GC temelleri dokümantasyonunda yer alır.
Öte yandan GC yalnız belleği bilir. Dosya tanıtıcısı, veritabanı bağlantısı, soket gibi yönetilmeyen kaynakları siz serbest bırakırsınız. IDisposable ve using bloğu bu işe yarar; using, blok bitince Dispose çağrısını garanti eder.
İyi bir yanıt finalizer'a da değinir: finalizer yalnız yönetilmeyen kaynağı doğrudan tutan sınıflar içindir ve nesnenin toplanmasını geciktirir. Dispose içinde GC.SuppressFinalize çağırmanızın nedeni budur.
Bağımlılık enjeksiyonunda Singleton, Scoped ve Transient farkı nedir?
ASP.NET Core yerleşik bir bağımlılık enjeksiyonu kapsayıcısıyla gelir. Servisi kaydederken üç ömürden birini seçersiniz. Microsoft'un DI dokümantasyonu bu ömürleri şöyle tanımlar:
- Transient: her istendiğinde yeni bir örnek oluşur.
- Scoped: her HTTP isteği boyunca tek bir örnek yaşar.
- Singleton: uygulama boyunca tek bir örnek yaşar.
Asıl soru bunun arkasından gelir: Singleton bir servise Scoped bir DbContext enjekte ederseniz ne olur? Bu hataya "captive dependency" denir; DbContext ilk isteğin kapsamında kalır ve thread güvenli olmadığı için eşzamanlı isteklerde bozulur. Geliştirme ortamında kapsam doğrulaması bu durumu başlangıçta yakalar.
ASP.NET Core'da middleware hattı nasıl işler?
Middleware, her HTTP isteğinin sırayla geçtiği bileşen zinciridir. Her bileşen isteği işler, bir sonrakine iletir ya da hattı kısa devre yaparak yanıtı kendisi döndürür. Dönüşte yanıt aynı zinciri ters sırada geçer.
Bu yüzden sıralama kritiktir. Örneğin UseAuthentication, UseAuthorization'dan önce gelmelidir; aksi hâlde yetkilendirme kimliği bilmeden çalışır. İstisna yakalama katmanı ise en başa yakın durmalıdır ki sonraki bileşenlerin hatalarını yakalayabilsin.
Mülakatçı bazen kısa bir özel middleware yazmanızı ister: isteğin süresini ölçüp log'a yazan bir bileşen iyi bir örnektir. Kodu yazarken, özellikle await next(context) çağrısının öncesini ve sonrasını ayırmanız, akışı anladığınızı gösterir.
Entity Framework Core'da N+1 problemini nasıl çözersiniz?
N+1 problemi, bir liste için bir sorgu atıp ardından her eleman için ilişkili veriyi ayrı ayrı çektiğinizde ortaya çıkar. Yüz siparişlik bir listede yüz bir sorgu oluşur. Genellikle tembel yükleme (lazy loading) açıkken fark edilmeden olur.
Çözüm seçenekleri şunlardır: Include ile ilişkili veriyi baştan yüklemek, Select ile yalnız gereken alanları bir DTO'ya yansıtmak ya da büyük birleştirmelerde AsSplitQuery kullanmak. Yalnız veri gösteren ekranlarda AsNoTracking eklemek, değişiklik izleme maliyetini de düşürür.
Üstelik en ikna edici yanıt teşhisle başlar. EF Core'un ürettiği SQL'i log'dan okuduğunuzu, sorgu sayısını ölçtüğünüzü anlatırsanız mülakatçı gerçek bir üretim sorununu çözdüğünüzü anlar. SQL tarafında kendinizi güçlendirmek isterseniz aynı seriden veritabanı sorgu senaryolarını da inceleyebilirsiniz.
İstisna yönetiminde hangi hatalardan kaçınırsınız?
İstisna sorusu, üretimde kod yazmış adayı hemen ayırır. İlk kural şudur: yakalayamayacağınız istisnayı yakalamayın. Boş bir catch bloğu hatayı gizler ve sorunu günler sonra çok daha pahalı bir yerde karşınıza çıkarır.
İkinci kural yeniden fırlatmayla ilgilidir. catch içinde throw ex; yazarsanız yığın izini sıfırlarsınız; throw; ise orijinal izi korur. Bu küçük fark, gece yarısı üretimde bir hatayı ararken size saatler kazandırır.
Ayrıca istisnayı akış kontrolü için kullanmayın. Kullanıcı girdisi geçersizse bir sonuç nesnesi ya da doğrulama hatası döndürmek, istisna fırlatmaktan hem daha ucuz hem daha okunaklıdır. ASP.NET Core tarafında ise merkezi bir hata işleyici ve ProblemDetails yanıtı kurmanız, API tüketicilerine tutarlı bir sözleşme sunar.
- Genel Exception yerine mümkün olan en özel tipi yakalayın.
- Log'a mesajla birlikte bağlamı da yazın: kullanıcı, istek kimliği, girdi.
- finally ya da using ile kaynakları her koşulda serbest bırakın.
Birim testlerini C# projesinde nasıl yazarsınız?
Mülakatçılar test sorusunu genellikle "bu kodu nasıl test ederdiniz?" diye sorar. xUnit, NUnit ve MSTest en yaygın çatılardır; hangisini seçtiğinizden çok, testin yapısını anlatmanız önemlidir. Arrange, Act, Assert düzeni, her testin tek bir davranışı doğruladığını gösterir.
Bağımlılıkları taklit etmek için Moq ya da NSubstitute gibi kütüphaneler kullanırsınız. Ancak burada dengeyi kaçırmamak gerekir: her şeyi taklit eden bir test, gerçek davranışı değil kendi kurgusunu doğrular. Bu yüzden veritabanı katmanında bellek içi sağlayıcı yerine Testcontainers ile gerçek bir veritabanı kullanan entegrasyon testlerini tercih eden ekipler çoğalıyor.
Üstelik ASP.NET Core, WebApplicationFactory ile uygulamayı test içinde ayağa kaldırmanıza izin verir. Böylece bir uç noktayı HTTP seviyesinde, middleware hattıyla birlikte doğrularsınız. Mülakatta bu üç katmanı, yani birim, entegrasyon ve uçtan uca testi ayırt edebilmeniz olgunluk işaretidir.
Generic kısıtlar ve kovaryans hakkında ne sorarlar?
Generic sorusu genellikle "where T : class ne işe yarar?" diye başlar. Kısıtlar, generic tipe hangi işlemleri uygulayabileceğinizi derleyiciye bildirir. Örneğin where T : new() kısıtı, metot içinde yeni bir T örneği oluşturmanıza izin verir; where T : IComparable<T> ise karşılaştırma yapmanızı sağlar.
Ardından kovaryans ve kontravaryans gelir. IEnumerable<out T> kovaryanttır; bu sayede bir IEnumerable<string> değerini IEnumerable<object> bekleyen bir metoda geçebilirsiniz. Action<in T> ise kontravaryanttır ve tersi yönde çalışır.
Peki List<string> neden List<object> yerine geçemez? Çünkü List hem okuma hem yazma sunar; bu dönüşüme izin verseydi listeye bir int eklemeniz mümkün olurdu. Bu gerekçeyi açıklayan aday, tip güvenliğini gerçekten anladığını kanıtlar.
Thread güvenliğini nasıl sağlarsınız?
Eşzamanlılık sorusu genellikle küçük bir sayaç örneğiyle başlar: iki thread aynı int değişkenini artırırsa sonuç neden eksik çıkar? Çünkü artırma işlemi okuma, toplama ve yazma adımlarından oluşur; araya başka bir thread girebilir. Buna yarış durumu (race condition) denir.
Çözüm seçenekleri maliyete göre sıralanır. Basit sayaçlar için Interlocked.Increment yeterlidir. Birden fazla alanı birlikte değiştiriyorsanız lock bloğu kullanırsınız. Paylaşılan sözlükler için ise ConcurrentDictionary hazır bir yapı sunar.
Ancak async kodda lock kullanamazsınız, çünkü lock içinde await yazmaya derleyici izin vermez. Bu durumda SemaphoreSlim ve WaitAsync ikilisini tercih edersiniz. Mülakatçı bu ayrıntıyı biliyorsanız hemen fark eder; böylece gerçek bir asenkron serviste kilit sorunu çözdüğünüz anlaşılır.
Span ve Memory tipleri ne işe yarar?
Span<T>, bir dizi, string ya da yığın belleği üzerinde kopya oluşturmadan dilim almanızı sağlayan bir yapıdır. Örneğin uzun bir metinden bir parçayı Substring ile alırsanız yeni bir string oluşur; AsSpan ile aldığınızda ise hiçbir tahsis yapmazsınız.
Öte yandan Span bir ref struct olduğu için yalnız yığında yaşar. Bu nedenle bir sınıfın alanı olamaz ve async metotlarda await sınırını geçemez. Bu kısıtı aşmak için Memory<T> kullanırsınız; Memory heap üzerinde saklanabilir ve ihtiyaç anında Span'e dönüşür.
Kısacası bu soru, kıdemli adayın yüksek performanslı kod yazıp yazmadığını ölçer. Ayrıştırıcı, serileştirici ya da yoğun trafikli bir API yazdıysanız, Span ile ölçtüğünüz tahsis düşüşünü örnek olarak anlatabilirsiniz.
Delegate, event ve lambda ifadeleri arasındaki ilişki nedir?
Delegate, bir metodu değişken gibi taşıyan tip güvenli bir referanstır. Func ve Action, hazır generic delegate tipleridir. Lambda ifadesi ise bir delegate örneğini kısa yoldan yazmanın sözdizimidir.
Event, delegate üzerine inşa edilen bir erişim kısıtıdır. Dışarıdan yalnız abone olabilir (+=) ya da aboneliği kaldırabilirsiniz (-=); olayı yalnız tanımlayan sınıf tetikler. Bu kısıt, başka bir sınıfın tüm aboneleri silmesini engeller.
Sık gelen devam sorusu bellek sızıntısıdır. Uzun yaşayan bir yayıncıya kısa ömürlü bir nesne abone olur ve aboneliği kaldırmazsa, GC o nesneyi toplayamaz. Kısacası event aboneliği de temizlenmesi gereken bir kaynaktır.
Record, struct ve class arasında nasıl karar verirsiniz?
Record, C# 9 ile gelen ve değer eşitliği sunan bir tiptir. İki record aynı değerleri taşıyorsa eşittir; class'ta ise varsayılan eşitlik referansa bakar. with ifadesiyle bir kopyayı küçük bir değişiklikle üretebilirsiniz; bu da değişmez veri modellerini kolaylaştırır.
Pratik ayrım şöyledir: DTO ve olay mesajları için record, küçük ve kısa ömürlü değerler için struct (ya da record struct), kimliği ve değişen durumu olan varlıklar için class seçersiniz. Büyük bir struct'ı sık kopyalamak ise performansı düşürür; bu yüzden struct'ları küçük tutarsınız.
Mülakatçı burada pattern matching'e de geçebilir. switch ifadeleri ve özellik desenleri, record'larla birlikte okunaklı iş kuralları yazmanızı sağlar.
Canlı kodlama bölümünde hangi soruları çözersiniz?
C Sharp mülakat soruları arasında canlı kodlama genellikle orta zorluktadır. Amaç algoritma yarışması değil, temiz ve test edilebilir kod görmektir. Sık karşılaştığım görevler şunlardır:
- Bir metindeki kelime sıklığını Dictionary ya da GroupBy ile hesaplamak.
- İki sıralı listeyi tek geçişte birleştirmek.
- Basit bir LRU önbelleğini Dictionary ve LinkedList ile kurmak.
- Bir API'den gelen veriyi async olarak çekip hata ve zaman aşımını yönetmek.
Çözerken önce kenar durumları sorun: boş girdi, null, çok büyük veri. Ardından basit bir çözüm yazın, sonra karmaşıklığı tartışın. Bu sıra, mülakatçıya sizinle çalışmanın nasıl olacağını gösterir.
Kıdemli .NET pozisyonlarında sorular nasıl değişir?
Kıdem arttıkça C Sharp mülakat soruları sistem tasarımına kayar. "Saniyede binlerce isteği karşılayan bir sipariş servisi nasıl kurarsınız?" gibi açık uçlu sorularda önbellek, kuyruk, veritabanı indeksleri ve gözlemlenebilirlik birlikte masaya gelir.
Bu aşamada teknik doğruluk kadar ödünleşim anlatımı önemlidir. Mikroservis mi, modüler monolit mi sorusunun tek bir doğru cevabı yoktur; ekip büyüklüğü ve dağıtım sıklığı kararı belirler. Ön yüz tarafında benzer bir tartışmayı micro frontend mimarisi yazısında ele almıştım.
Ayrıca performans sorunlarını nasıl teşhis ettiğinizi merak ederler. dotnet-counters, dotnet-trace ve bellek dökümü analizi gibi araçları kullandığınızı somut bir örnekle anlatmanız fark yaratır.
Web performansı ve SEO bilgisi .NET geliştiricisine neden puan kazandırır?
Kurumsal projelerde arka uç geliştirici, sayfanın ne kadar hızlı açıldığından doğrudan sorumludur. Sunucu yanıt süresi yavaşsa ön yüz ne kadar iyi olursa olsun kullanıcı bekler. Bu yüzden müşteri tarafında çalışan ekipler, hız ile arama görünürlüğü arasındaki bağı anlayan geliştiriciyi tercih eder.
Örneğin ASP.NET Core'da yanıt sıkıştırma, çıktı önbelleği ve doğru HTTP başlıkları doğrudan ölçülebilir kazanç sağlar. Bu bağlantıyı site hızının SEO'ya etkisi yazısında ayrıntılı anlattım. Ölçümü nasıl yapacağınızı ise Lighthouse ile performans testi rehberinde bulabilirsiniz.
Ek olarak yönlendirme ve robots kuralları da arka uçta yaşar. Bir taşıma sonrasında 301 zincirlerini yönlendirme denetleyici ile, tarama kurallarını ise robots.txt oluşturucu ile kontrol edebilirsiniz. Teknik temeli merak ediyorsanız teknik SEO ipuçları yazısı iyi bir başlangıçtır.
C Sharp mülakat sorularına son hafta nasıl hazırlanırsınız?
Son haftayı yeni konu öğrenmekle değil, bildiğinizi anlatılabilir hâle getirmekle geçirin. Saha tecrübeme göre şu plan işe yarar; ancak bu bir garanti değil, başlangıç önerisidir:
- Yukarıdaki başlıkların her birinden iki soruyu sesli yanıtlayın ve kaydedin.
- Her gün kısa bir canlı kodlama görevini zaman tutarak çözün.
- Özgeçmişinizdeki her projeden bir zor hatayı ve nasıl çözdüğünüzü hazırlayın.
- Şirketin kullandığı .NET sürümünü ve mimarisini iş ilanından ya da teknik blogundan öğrenin.
Son olarak soru sormayı unutmayın. Kod inceleme süreci, test kültürü ve dağıtım sıklığı hakkında soru sormak, ekibe gerçekten ilgi duyduğunuzu gösterir. Ekip tarafındaysanız ve bir web projesi için doğru teknik ortağı arıyorsanız web tasarım hizmeti sayfama göz atabilirsiniz.




