ASP.NET Core Mülakat Soruları: HTTP İstek Hattını ve DI Kapsamlarını İzleyin

ASP.NET Core mülakat sorularını gerçek HTTP izleriyle çalışın. Middleware sırası, scoped ve singleton kimlikleri, kısa devre ve hata sınırını açıklayın.

Author: PracHub

Published: 10/11/2026

ASP.NET Core Mülakat Soruları: HTTP İstek Hattını ve DI Kapsamlarını İzleyin

October 11, 2026

Quick Overview

ASP.NET Core mülakatına hazırlanan backend adayları için gerçek Kestrel HTTP istekleriyle middleware sırası, scoped/singleton/transient örnek kimlikleri, kısa devre ve hata işleyicisinin konumunu açıklayan Türkçe teknik çalışma. Özgün sipariş API’sindeki 46 doğrulama; normal akışı, erken ve endpoint hatalarını ve yanlış scoped constructor başlangıç hatasını ayırır. Resmi Microsoft davranışları, çalıştırılmış deney sonuçları ve teşhis önerileri açıkça ayrılır.

Software EngineerFree

Bir ASP.NET Core mülakatında middleware sırasını ve DI yaşam sürelerini tanımlamak başlangıçtır. Asıl soru, aynı uygulamaya gelen iki istekte hangi kodun çalıştığını ve hangi nesnenin paylaşıldığını gösterebilmektir. Bir isteğin 500 dönmesi de hata işleyicisinin devreye girdiğini tek başına kanıtlamaz. Olay sırası handler’ın çalışıp çalışmadığını, yanıt gövdesi üretilen hatayı, örnek kimlikleri ise DI kapsamının sınırını gösterir.

Bu yazıdaki sipariş API'si özgün bir çalışma örneğidir. .NET SDK 10.0.401 ve ASP.NET Core 10.0.12 ile yerel Kestrel üzerinde gerçek HTTP istekleri gönderilerek 46 doğrulama çalıştırıldı. Microsoft'un resmi belgeleri davranış kurallarını destekliyor; aşağıdaki yollar, kayıtlar ve sonuçlar bizim deneyimize ait. Aday raporları kullanılmıyor ve herhangi bir şirketin soru sıklığı ya da değerlendirme ölçütü hakkında iddia bulunmuyor.

İki HTTP isteği ayrı scoped örnekleri kullanırken aynı singleton kimliğini paylaşır.

İstek hattını izledikten sonra Build a Dual Fixed-Window Rate-Limiting Middleware sorusuna geçebilirsiniz. Buradaki kısa devre davranışını, bu kez hangi isteğin sınıra takılması gerektiği üzerinden savunmanız gerekir.

Önce normal isteğin girişini ve çıkışını tahmin edin

Resmi davranış: middleware, kendisinden sonraki bileşeni çağırabilir ve bu çağrının öncesinde veya sonrasında işlem yapabilir. Sonraki bileşeni çağırmaması hattı kısa devre eder. Bu nedenle sırayı yalnızca yukarıdan aşağıya okumak yeterli değildir; await next(...) sonrasındaki dönüşü de izlemelisiniz. Microsoft middleware belgeleri bu yürütme modelini açıklar.

Deneyde dış gözlemci, hata işleyicisi, gate, kapsam kaydı yapan middleware ve endpoint bulunuyor. Gate, normal sipariş isteklerini geçiriyor. Endpoint GET /orders/17 için {"orderId":17,"status":"draft"} döndürüyor. Sipariş işleme, ödeme veya veri tabanı işlemi yapılmıyor; amaç hattın davranışını görünür kılmak.

Normal isteğin tamamlanmış kaydı şöyle:

outer:in
gate:in
scope:in
endpoint
scope:out
gate:out
outer:out

İlk üç kayıt içeri doğru ilerleyişi, son üç kayıt çağrıların çözülmesini gösteriyor. Hata işleyicisi bu başarılı istekte handler:catch yazmıyor. Listede görünmemesi, başarılı akışta hiç çağrılmadığı anlamına gelmez; yalnızca hata dalının çalışmadığını gösterir. Önce kaydın neyi temsil ettiğini belirleyin; aksi halde çalışmayan bir hata dalını, hiç girilmeyen middleware ile karıştırabilirsiniz.

Mülakatta şu soruyla devam edin: “Endpoint yanıtı yazdıysa scope:out neden hâlâ var?” Çünkü yanıt üretmek, daha önce next çağrısını bekleyen kodu ortadan kaldırmaz. Bu örnekte çıkış kayıtları finally bloklarında tutuluyor. Böylece normal dönüşte ve istisna sırasında hangi katmanların gerçekten açıldığını izleyebiliyoruz.

Gözlem yöntemi de önemlidir. Endpoint'in JSON gövdesine o ana kadarki logları koyarsanız henüz oluşmamış çıkış olaylarını göremezsiniz. Deney, tamamlanmış izi dış katmanın finally bloğunda saklıyor; daha sonra ayrı bir /audit/{id} isteğiyle okuyor. Testler gerektiğinde bu kaydı bekliyor. Audit isteğinin kendisi başka bir HTTP isteğidir; sipariş isteğinin kapsamına dahil değildir.

Aynı istek içinde hangi DI örnekleri eşleşmeli?

Resmi DI kuralı: scoped servis aynı kapsam içinde tekrar kullanılır; web uygulamalarında normal istek işleme bir istek kapsamı kullanır. Transient servis her çözümlemede oluşturulur. Singleton servis aynı servis sağlayıcısı üzerinden paylaşılır. Bu tanımlar kullanıcı hesabına, metoda veya bütün dağıtık sisteme göre kurulmaz. Microsoft servis yaşam süreleri referansını bu sınırlarla okuyun.

Deney üç küçük kimlik servisi kaydediyor:

builder.Services.AddScoped<RequestStamp>();
builder.Services.AddSingleton<SingletonStamp>();
builder.Services.AddTransient<TransientStamp>();

Her servis oluşturulduğunda bir GUID alıyor. Middleware ve endpoint aynı servis türlerini ayrı ayrı çözümlüyor. Endpoint ayrıca scoped servisi context.RequestServices üzerinden ikinci kez istiyor. Bu son çözümleme yalnızca kimlik karşılaştırmasını göstermek için var; uygulama kodunda bağımlılıkları açık parametrelerle ifade etmek daha okunur bir başlangıçtır.

İki ardışık sipariş isteğinde doğrulanan ilişkiler aşağıda. Harfler gerçek GUID'lerin okunabilir karşılıklarıdır; sabit değerler değildir.

Çözümleme noktasıR1: /orders/17R2: /orders/18Kontrol edilen ilişki
Middleware scopedABA ve B farklı
Endpoint scopedABKendi isteğinin middleware örneğiyle aynı
Endpoint ikinci scoped çözümlemeABAynı kapsam içinde yine aynı
Middleware singletonGGİki istekte aynı
Endpoint singletonGGMiddleware singleton'ı ile aynı
Middleware transientT1T3Endpoint çözümlemesinden ayrı
Endpoint transientT2T4T1 ≠ T2 ve T3 ≠ T4

Buradan “scoped her çağrıda yenidir” sonucu çıkmaz. Aynı istekte üç scoped çözümleme aynı kimliği verdi. “Singleton güvenlidir” sonucu da çıkmaz. Kimlik paylaşımını doğruladık; eşzamanlı yazma güvenliğini test etmedik. Gerçek bir singleton değişebilir istek verisi tutuyorsa, iki isteğin aynı nesneye erişmesi ayrıca incelenmelidir.

Görseldeki birleşen oklar ortak singleton kimliğini anlatır; scoped servislerin singleton'a bağımlı olduğunu gösteren bir nesne grafiği değildir. Uygulamamız bu kimlik servislerini birbirinden bağımsız kaydeder. Mülakatta da yaşam süresi tablosunu bir bağımlılık grafiğiyle karıştırmayın.

Cevabınızı kapsam sınırına bağlayın: aynı kullanıcı art arda iki istek gönderse de farklı istek kapsamları oluşur. Tersine, bir istekte birden fazla metot aynı scoped servisi kullanabilir. Açıkça yeni bir kapsam oluşturulursa ilişkinin yeniden değerlendirilmesi gerekir. GUID tablosu bu örneğin davranışını kanıtlar; her olası kapsam tasarımını kapsamaz.

Conventional middleware scoped servisi nereden almalı?

Resmi ASP.NET Core kuralı: conventional middleware'in scoped bağımlılığını constructor'da tutmak yerine Invoke veya InvokeAsync parametresinden almak gerekir. Constructor ile oluşturulan middleware'in ömrü istek kapsamıyla aynı değildir. Özel middleware yazma belgesi bu ayrımı açıkça ele alır.

Çalıştırılan sınıftaki ilgili bölüm:

public sealed class ScopeStampMiddleware(RequestDelegate next) {
    public async Task InvokeAsync(HttpContext context, RequestStamp scoped,
        SingletonStamp singleton, TransientStamp transient) {
        var trace = (TracePacket)context.Items["trace"]!;
        trace.Events.Add("scope:in");
        trace.Ids["middlewareScope"] = scoped.Id;
        trace.Ids["middlewareSingleton"] = singleton.Id;
        trace.Ids["middlewareTransient"] = transient.Id;
        try { await next(context); }
        finally { trace.Events.Add("scope:out"); }
    }
}

Constructor yalnızca sonraki bileşeni alıyor; scoped servis istek sırasında yöntem parametresinden geliyor. Kötü varyantta RequestStamp constructor parametresine taşındı. Deney hem ValidateScopes hem ValidateOnBuild seçeneklerini açıkça etkinleştirdi. Sonuç, uygulamanın başlangıçta root provider üzerinden scoped servis çözümlenemediği hatasıyla durmasıydı. Bu bir HTTP 500 sonucu değil: sunucu isteği kabul edecek noktaya gelmedi.

Bu ayarlar deneyde Production ortamında da açıkça verildi. Dolayısıyla sonucu “Production varsayılan olarak aynı doğrulamayı yapar” diye sunmayın. Hatanın hangi ayarla görünür olduğunu söylemek, yalnızca hata mesajını ezberlemekten daha değerlidir.

IMiddleware alternatifini sorarlarsa ayrı bir etkinleştirme modeli olduğunu belirtin. Resmi factory tabanlı yaklaşım middleware'i istek başına etkinleştirebilir ve scoped constructor bağımlılıklarını destekler. Bu, yukarıdaki conventional constructor'ı kendiliğinden güvenli yapmaz. Bu deney IMiddleware varyantını çalıştırmadı; açıklama resmi factory etkinleştirme belgesine dayanıyor.

Gate kısa devre yaptığında hangi olaylar kaybolur?

Özgün deneyde /blocked yolu 403 ve {"code":"LAB_BLOCKED"} döndürür. Gate bu dalda next çağırmaz. Tamamlanmış iz şu olur:

outer:in → gate:in → gate:blocked → gate:out → outer:out

scope:in, endpoint ve scope:out yoktur. ScopeStampMiddleware’e girilmediği için middlewareScope, middlewareSingleton ve middlewareTransient kimlikleri de kaydedilmemiştir. Bundan “framework hiçbir servis oluşturmadı” sonucunu çıkaramayız; gözlemimiz yalnızca belirlediğimiz çözümleme noktalarıyla sınırlıdır.

Gate'in kendi çıkışı vardır, çünkü giriş yapmış ve finally bloğu açılmıştır. Henüz girilmeyen scope middleware'inin çıkışı ise yoktur. Bu iki yokluk ve varlık, 403 durum kodundan daha fazla bilgi verir: isteğin nerede durduğunu ve hangi katmanların kapanması gerektiğini gösterir.

Bu gate gerçek kimlik doğrulama veya yetkilendirme uygulaması değildir. Yol adına göre çalışan eğitim dalıdır. Üretimde rol, claim veya erişim politikası tasarlamak için bunu kopyalamayın. Buradaki mülakat becerisi, terminal dalın sonraki işlemleri durdurduğunu ve önceki katmanların dönüşünü koruduğunu açıklamaktır.

Kendi varyantınızda rate limit eklediğinizde aynı soruyu sorun: reddedilen istek endpoint'e ulaşmalı mı, sayaç güncellemesi hangi koşulda olmalı ve gözlemci reddetme nedenini nasıl ayırmalı? Bunlar tasarım önerileridir; deneyin doğruladığı rate-limit davranışları değildir.

Hata işleyicisinin yeri neden 500 sonucunu değiştirir?

Resmi hata işleme davranışı: exception middleware yalnızca kendi sonrasında çalışan hattaki uygun istisnaları yakalayabilir. Yanıt başlamışsa hata yanıtı üretmenin ayrıca sınırları vardır. Microsoft hata işleme belgesi yerleşimi bu yüzden önemli kılar.

İki çalışan varyant kurduk. Doğru varyantta handler gate'ten önce, geç varyantta scope middleware'inden sonra kaydedildi. /explode-before gate içinde, /explode-endpoint endpoint içinde istisna fırlatıyor. Her iki hatada da yanıt henüz başlamamıştır.

İstekHandler gate'ten önceHandler scope'tan sonra
/explode-before500, LAB_FAILURE JSON; handler:catch var500, boş gövde; handler:catch yok
/explode-endpoint500, LAB_FAILURE JSON; handler yakalar500, LAB_FAILURE JSON; handler yine yakalar

İki erken hata da 500 döndürdü, fakat yalnızca biri bizim hata dalımızdan geçti. Geç varyantta gate handler'a ulaşmadan fırlattığı için handler hiç açılmadı. Bu ortamda işlenmeyen hata Kestrel'den boş 500 yanıtıyla gözlendi. Bunu bütün barındırma yapılandırmalarının değişmez hata gövdesi olarak genellemeyin.

Handler önce kaydedildiğinde gate hatasını yakalar; geç kaydedildiğinde handler'a hiç girilmez.

Endpoint hatasının izleri de sınırın yerini gösterir:

Handler önce:
outer:in → gate:in → scope:in → scope:out
→ gate:out → handler:catch → outer:out

Handler geç:
outer:in → gate:in → scope:in → handler:catch
→ scope:out → gate:out → outer:out

İlkinde scope ve gate kapanırken istisna dıştaki handler'a ilerler. İkincisinde içteki handler istisnayı yanıtlayınca scope ve gate normal dönüşe devam eder; finally kayıtları yine yazılır. “Tüm 500'ler yakalanıyor” iddiasını yalnızca endpoint hatasıyla sınamak bu kusuru kaçırır.

Mülakatta hatayı bir sonraki kontrolle daraltın

Bir servis “bazen yanlış istek verisi görüyor” denildiğinde önce singleton'ın suçlu olduğunu ilan etmek yerine gözlem önerebilirsiniz: iki ayrı correlation ID, scoped örnek kimliği ve verinin yazıldığı çözümleme noktası. Bu kontrol, belirsiz bir “bazen” şikâyetini karşılaştırabileceğiniz iki somut isteğe dönüştürür; henüz teşhis değildir. Deneydeki kimlik ilişkileri böyle bir kontrolü tasarlamayı öğretir; gerçek bir sızıntıyı tespit ettiğimizi göstermez.

Cevabınızı şu akışla kurun: “Önce iki isteğin ayrı kapsam kullandığını kontrol ederim. Sonra değişebilir verinin singleton'da veya başka ortak durumda tutulup tutulmadığına bakarım. Kimlikler doğruysa veri kaynağını ve eşzamanlı erişimi ayrıca incelerim.” Her adım, önceki gözlemin dışarıda bıraktığı açıklamayı daraltır.

Hata gövdesi tutarsızsa benzer biçimde başarılı endpoint'i tekrar çağırmak yerine erken middleware hatasını üretin. Handler kaydı, gövde ve son çıkış olayı birlikte kontrol edilmelidir. Loglara gerçek kullanıcı verisi eklemek gerekmez; sentetik kimlikler bu eğitim sorusunu yanıtlar.

46 doğrulamanın 44’ü doğru ve geç handler varyantlarının HTTP sonuçlarını, olay sırasını ve örnek eşitliklerini; ikisi kötü constructor’ın başlangıç hatasını ve kapsam doğrulama mesajını kontrol ediyor. Bu sayı 46 ayrı HTTP isteği demek değildir. TestHost veya WebApplicationFactory kullanılmadı; istekler loopback Kestrel'e gönderildi. Veri tabanı, yük, iptal ve disposal zamanlaması bu çalışmanın dışında. Resmi entegrasyon testi yaklaşımı, daha büyük uygulamalarda test sunucusu ve yapılandırma seçenekleri için ayrı bir referanstır.

Testin geçmesi hangi soruları açık bırakır?

Bir kontrolü nasıl bozacağınızı bilmek, neyi ölçtüğünüzü de gösterir. Scoped kaydını transient yaparsanız aynı istekteki middleware ve endpoint kimliklerinin eşitlik kontrolü başarısız olmalıdır. Gate’in reddetme dalına yanlışlıkla next eklerseniz yalnızca 403 kontrolüne güvenmeyin: endpoint kaydı ortaya çıkabilir ve başlamış yanıta ikinci kez yazılabilir. Handler’ı geç konuma taşıdığınızda ise başarılı sipariş kontrolleri hâlâ geçer; erken hata gövdesi ve handler olayı ayrışır. Bunlar kendi çalışmanızda uygulayabileceğiniz değişiklik önerileridir; kaydedilmiş üç varyantın dışında ek mutasyon testi yapıldığını iddia etmiyoruz.

Bu ayrımı mülakat cevabında açık tutun: “Başarı yolu geçti, fakat erken hata yolu henüz kontrol edilmedi.” Böyle bir cümle, eksik kanıtı tamamlanmış sonuç gibi sunmadan bir sonraki testi belirler. Aynı durum servis yaşam süresi için geçerlidir. İki ardışık istekte singleton kimliğinin aynı olması, iki eşzamanlı isteğin değişebilir alanları güvenle kullanacağını kanıtlamaz. Bunun için paylaşılmış alanı, beklenen sonucu ve çakışmayı üreten düzeni ayrıca tanımlamak gerekir.

Gözlem aracının da sınırları var. Deneyin trace registry’si singleton ve sözlüğü ConcurrentDictionary; her isteğin olay listesi ise kendi HttpContext.Items alanında. Bu tasarım, bütün nesne grafiğinin her kullanımda thread-safe olduğu anlamına gelmez. Özellikle aynı istekte paralel dallar ortak listeye yazarsa ayrıca eşzamanlılık tasarımı gerekir. Bu deney böyle paralel dallar çalıştırmadı.

Registry eğitim kolaylığı için bellekte tutuluyor; kapasite sınırı, kayıt temizleme ve kimlik çakışması politikası uygulanmadı. Testler benzersiz X-Trace değerleri kullandı. Üretim gözlemlenebilirliği için bu yapıyı aynen taşımak yerine saklama süresini, erişimi ve correlation ID kaynağını belirlemek gerekir. Buradaki kanıt, kontrollü deneyin izidir; hazır bir üretim loglama sistemi değildir.

Aynı muhakemeyi beş somut soruya taşıyın

Bu doğrulanmış PracHub soruları HTTP akışı, paylaşılan durum ve servis sınırları için aktarım alıştırmalarıdır. Hepsinin ASP.NET Core kullandığını veya aynı işveren sürecine ait olduğunu iddia etmiyoruz.

PracHub sorusuBu yazıdan taşıyacağınız kontrol
Build a Dual Fixed-Window Rate-Limiting MiddlewareReddedilen isteğin sonraki işleme geçmediğini ve sınır durumunu gösterin.
Review a PR for thread-safe request handlingİstek verisiyle ortak durumu ayırın; eşzamanlılık iddiası için ayrıca kanıt isteyin.
Design a REST API Abstraction LayerHTTP hata davranışının hangi katmana ait olduğunu açıklayın.
Implement a rail freight quote API service layer and scale it for slow dependenciesBağımlılık sınırını ve yavaş çağrının etkilediği istek yolunu belirleyin.
Design a Robust Feature Flag Evaluation Engineİstek bağlamının yanlışlıkla ortak değişebilir durumda kalmadığını sorgulayın.

Şimdi rate-limiting middleware sorusunu açın. Koddan önce kabul edilen ve reddedilen birer isteğin olay sırasını yazın. Ardından hangi durumun paylaşılması gerektiğini, hangi durumun yalnızca isteğe ait olduğunu ve bir hata sınırının hangi çağrıları çevrelediğini açıklayın. Sonuç tahmininizden farklıysa yalnızca ilk ayrışan olayı bulun; bütün hattı bir anda değiştirmeden o çağrının öncesini ve sonrasını yeniden kontrol edin. Bu çalışma, yaşam süresi isimlerini sayabilmenin ötesinde, cevabınızı gözlenebilir davranışla savunmanızı sağlar.

Sources and Further Reading


Comments (0)