👀 یک نکته مهم برای Developerها
گاهی ما بهعنوان Developer فقط این سؤال را میپرسیم:
اما در سیستمهای حساس باید چند سؤال دیگر هم بپرسیم:
🔹 آیا User دقیقاً میداند چه چیزی را تأیید میکند؟
🔹 آیا عملیات به یک Business Object مشخص متصل است؟
🔹 اگر داده بعداً تغییر کرد، Signature همچنان چه چیزی را نمایندگی میکند؟
🔹 آیا میتوان یک Authorization را در Context دیگری استفاده کرد؟
🔹 آیا Audit Trail کافی برای اثبات Intent کاربر داریم؟
🔹 آیا سیستم فقط Valid بودن Signature را بررسی میکند یا Context امضا را هم بررسی میکند؟
امضای دیجیتال فقط این نیست که:
سؤال مهمتر این است:
برای همین، در طراحی سرویسهای حساس نباید فقط به Implementation نگاه کنیم.
گاهی لازم است از کد فاصله بگیریم و از خودمان بپرسیم:
اگر من جای کاربر بودم، آیا دقیقاً میدانستم چه چیزی را دارم تأیید میکنم؟
چون در نهایت، Security فقط جلوگیری از Attack نیست.
گاهی Security یعنی مطمئن شویم سیستم دقیقاً همان چیزی را انجام میدهد که کاربر فکر میکند دارد انجام میدهد. 🔐
گاهی ما بهعنوان Developer فقط این سؤال را میپرسیم:
«آیا API درست کار میکند؟»
اما در سیستمهای حساس باید چند سؤال دیگر هم بپرسیم:
🔹 آیا User دقیقاً میداند چه چیزی را تأیید میکند؟
🔹 آیا عملیات به یک Business Object مشخص متصل است؟
🔹 اگر داده بعداً تغییر کرد، Signature همچنان چه چیزی را نمایندگی میکند؟
🔹 آیا میتوان یک Authorization را در Context دیگری استفاده کرد؟
🔹 آیا Audit Trail کافی برای اثبات Intent کاربر داریم؟
🔹 آیا سیستم فقط Valid بودن Signature را بررسی میکند یا Context امضا را هم بررسی میکند؟
🎯 در نهایت
امضای دیجیتال فقط این نیست که:
«این Signature معتبر است؟»
سؤال مهمتر این است:
«این Signature دقیقاً چه چیزی را، توسط چه کسی، در چه زمانی و با چه میزان آگاهی و رضایتی تأیید کرده است؟»
برای همین، در طراحی سرویسهای حساس نباید فقط به Implementation نگاه کنیم.
گاهی لازم است از کد فاصله بگیریم و از خودمان بپرسیم:
اگر من جای کاربر بودم، آیا دقیقاً میدانستم چه چیزی را دارم تأیید میکنم؟
چون در نهایت، Security فقط جلوگیری از Attack نیست.
گاهی Security یعنی مطمئن شویم سیستم دقیقاً همان چیزی را انجام میدهد که کاربر فکر میکند دارد انجام میدهد. 🔐
#تصمیمهای_مهندسی | Engineering Decisions
یه Feature قرار بود دو هفتهای آماده بشه.
روز اول دربارهی Architecture بحث کردیم.
روز دوم دربارهی Database.
روز سوم دربارهی اینکه Sync باشه یا Async.
روز چهارم هنوز داشتیم گزینهها رو مقایسه میکردیم.
روز پنجم یکی گفت:
«بذاریم فعلاً بیشتر بررسی کنیم.»
هفته دوم هم گذشت. Feature هنوز نوشته نشده بود.
جالب اینجاست که هیچکس تصمیم اشتباهی نگرفته بود.
اصلاً تصمیمی نگرفته بودیم.
این یکی از چیزهایی بود که بعداً فهمیدم:
گاهی ترس از گرفتن تصمیم اشتباه،
باعث میشه تیم وارد چرخهی Analysis Paralysis بشه.
برای هر تصمیم:
و همیشه یک دلیل جدید برای ادامهی بررسی وجود دارد.
در حالی که خیلی از تصمیمهای Engineering برگشتپذیرند.
اگر امروز یک Implementation انتخاب کنیم و فردا بفهمیم مناسب نیست،میتوانیم تغییرش بدهیم.
اما اگر سه هفته فقط دربارهاش صحبت کنیم،
آن سه هفته دیگر برنمیگردد.
برای همین الان وقتی با یک تصمیم مواجه میشوم، اول میپرسم:
این تصمیم Reversible است یا Irreversible؟
اگر Reversible باشد، لازم نیست برای رسیدن به ۱۰۰٪ اطمینان صبر کنیم.
با اطلاعات کافی تصمیم میگیریم،
پیاده میکنیم،Measure میکنیم،
و اگر لازم بود تغییر میدهیم.
چون در Engineering، تصمیم بد قابل اصلاح است.
اما تصمیم نگرفتن هم هزینه دارد.
و گاهی خیلی بیشتر از چیزی که فکر میکنیم. Perfect Decision نداریم؛ فقط Decisionی داریم که با اطلاعات فعلی، منطقیترین گزینه است.
یه Feature قرار بود دو هفتهای آماده بشه.
روز اول دربارهی Architecture بحث کردیم.
روز دوم دربارهی Database.
روز سوم دربارهی اینکه Sync باشه یا Async.
روز چهارم هنوز داشتیم گزینهها رو مقایسه میکردیم.
روز پنجم یکی گفت:
«بذاریم فعلاً بیشتر بررسی کنیم.»
هفته دوم هم گذشت. Feature هنوز نوشته نشده بود.
جالب اینجاست که هیچکس تصمیم اشتباهی نگرفته بود.
اصلاً تصمیمی نگرفته بودیم.
این یکی از چیزهایی بود که بعداً فهمیدم:
گاهی ترس از گرفتن تصمیم اشتباه،
باعث میشه تیم وارد چرخهی Analysis Paralysis بشه.
برای هر تصمیم:
Option A
Option B
Option C
Option D
...
و همیشه یک دلیل جدید برای ادامهی بررسی وجود دارد.
در حالی که خیلی از تصمیمهای Engineering برگشتپذیرند.
اگر امروز یک Implementation انتخاب کنیم و فردا بفهمیم مناسب نیست،میتوانیم تغییرش بدهیم.
اما اگر سه هفته فقط دربارهاش صحبت کنیم،
آن سه هفته دیگر برنمیگردد.
برای همین الان وقتی با یک تصمیم مواجه میشوم، اول میپرسم:
این تصمیم Reversible است یا Irreversible؟
اگر Reversible باشد، لازم نیست برای رسیدن به ۱۰۰٪ اطمینان صبر کنیم.
با اطلاعات کافی تصمیم میگیریم،
پیاده میکنیم،Measure میکنیم،
و اگر لازم بود تغییر میدهیم.
چون در Engineering، تصمیم بد قابل اصلاح است.
اما تصمیم نگرفتن هم هزینه دارد.
و گاهی خیلی بیشتر از چیزی که فکر میکنیم. Perfect Decision نداریم؛ فقط Decisionی داریم که با اطلاعات فعلی، منطقیترین گزینه است.
🏗 راز معماری نابودنشدنی با Coupling و Cohesion
اگر بخواهیم فقط با دو مفهوم بفهمیم یک طراحی نرمافزاری چقدر سالم است، یکی از بهترین نقاط شروع این دو مفهوماند:
🔗 Coupling
🧩 Cohesion
خیلی وقتها این دو را کنار هم میشنویم، اما دقیقاً نمیدانیم چه مشکلی را حل میکنند.
بیایید از یک سؤال ساده شروع کنیم:
اگر فردا بخواهیم یک قسمت از سیستم را تغییر بدهیم، چند قسمت دیگر مجبور میشوند همراه آن تغییر کنند؟
پاسخ این سؤال، ما را مستقیماً به سمت Coupling میبرد.
🔗 ءCoupling چیست؟
ءCoupling یعنی میزان وابستگی بین Components مختلف سیستم.
هرچه دو Component برای کار کردن بیشتر به جزئیات یکدیگر وابسته باشند، Coupling آنها بیشتر است.
مثلاً:
{
اینجا
private readonly PaymentService _payment;
private readonly InventoryService _inventory;
private readonly EmailService _email;
public async Task CreateOrder()
{
await _payment.Pay();
await _inventory.Reserve();
await _email.Send();
}
}
OrderService مستقیماً به سه Component دیگر وابسته است.حالا فرض کنید API مربوط به
PaymentService تغییر کند.احتمالاً باید
OrderService را هم تغییر بدهیم.این یعنی یک تغییر محلی، اثر خود را به بیرون منتقل کرده است.
این همان چیزی است که در معماری میخواهیم تا حد امکان کنترلش کنیم.
🧩 ءCohesion چیست؟
ءCohesion تقریباً سؤال برعکس را میپرسد:
چیزهایی که داخل یک Component قرار دادهایم، واقعاً چقدر به یکدیگر مربوط هستند؟
اگر یک کلاس، Module یا Service روی یک هدف مشخص متمرکز باشد، Cohesion بالاتری دارد.
مثلاً:
├── AddItem()
├── RemoveItem()
├── CalculateTotal()
└── ApplyDiscount()
تمام این رفتارها حول یک مفهوم مشترک قرار گرفتهاند:🎯 Order
این یعنی Cohesion مناسب.
اما اگر همان کلاس تبدیل شود به:
├── CreateOrder()
├── SendEmail()
├── ResizeImage()
├── GenerateReport()
├── CreateUser()
├── ProcessPayment()
└── ClearCache()
دیگر یک مسئولیت مشخص نداریم.
کلاس به یک محل تجمع Business Logicهای نامرتبط تبدیل شده است.
اینجا Cohesion پایین آمده است.
🎯 پس هدف معماری چیست؟
یک قاعده بسیار مهم:
High Cohesion + Low Coupling
یعنی:
🧩 داخل هر Component، چیزهایی که واقعاً به هم مربوطاند کنار هم باشند.
و:
🔗 بین Componentها، وابستگی غیرضروری حداقل باشد.
این ترکیب یکی از اصول مهم در طراحی سیستمهای قابل نگهداری و قابل تغییر است. AWS نیز در راهنمای معماری خود برای Microservices صراحتاً بر Loose Coupling و High Functional Cohesion تأکید میکند.
💣 اما یک نکته مهم وجود دارد... Low Coupling به معنی:
«هیچ وابستگیای نباید وجود داشته باشد»
نیست.
این تصور اشتباه است.
یک سیستم بدون وابستگی عملاً وجود ندارد.
مثلاً:
↓
Payment
ءOrderبرای انجام یک فرآیند ممکن است واقعاً به Payment نیاز داشته باشد.
مسئله این نیست که Dependency را صفر کنیم.
مسئله این است که:
ءDependencyها را در مرزهای درست قرار دهیم.
🎯 یک معیار بسیار کاربردی
وقتی میخواهی تصمیم بگیری دو Component باید کنار هم باشند یا جدا، این سؤالها را بپرس:
🔹 آیا معمولاً با هم تغییر میکنند؟
🔹 آیا برای انجام یک Business Capability به یکدیگر نیاز دارند؟
🔹 آیا دادههایشان به شدت به هم وابسته است؟
🔹 آیا Transactionهای مشترک دارند؟
🔹 آیا یکی بدون دیگری میتواند مستقل Deploy شود؟
🔹 آیا یکی باید بتواند بدون دیگری کار کند؟
🔹 آیا تیمهای متفاوت مسئول آنها هستند؟
این سؤالها به ما کمک میکنند Boundary را بر اساس رفتار واقعی سیستم پیدا کنیم، نه بر اساس سلیقه.
Forwarded from کدهالیک | codehalic
وقتی بکاند پروژه C# باشه و فرانتاند TypeScript، بزرگترین دردسر اینه که مجبوری ساختار دیتا (مثل DTOها) رو دو جا تعریف کنی و اگه فیلدی تو بکاند عوض بشه، تازه تو Runtime ارورها خودشون رو نشون میدن. اما با معماری Monorepo و ابزار Nx میشه یه Type Safety یکپارچه و فولاستک ساخت! راهحلش اینه که به کمک OpenAPI موقع بیلد شدن پروژهی داتنت، کانترکتهای API به صورت اتوماتیک تولید بشن؛ بعد ابزاری مثل
https://nx.dev/blog/dotnet-openapi-type-safety
@codehalics | کدهالیک
openapi-ts این خروجی رو میخونه و تایپهای فرانتاند رو دقیقاً از روش جنریت میکنه. شاهکارِ Nx اینجاست که با سیستم قدرتمند Task Graph خودش، این پروسه رو به هم زنجیر و هوشمندانه کش Cache میکنه؛ یعنی به محض اینکه یه پراپرتی رو تو کدهای C# تغییر بدی، Nx خودش جریان رو میفهمه، تایپها رو آپدیت میکنه و خطای ناهماهنگی فرانتاند رو همون لحظه تو زمان کامپایل نشون میده تا دیگه هیچوقت باگهای ناشی از تغییر API به پروداکشن نرسن!https://nx.dev/blog/dotnet-openapi-type-safety
@codehalics | کدهالیک
📌200+ سوال مصاحبه واقعی (بخش1️⃣)
[ BUCKET 1 — C# AND .NET ]
🧠 فصل ۱ — انواع و سیستم نوعها (۵ سؤال)
1️⃣ تفاوت بین Value Type و Reference Type در #C چیست؟
2️⃣ تفاوت بین float، double و decimal چیست و هرکدام را چه زمانی استفاده میکنید؟ 🔢💰
3️⃣ تفاوت بین string و StringBuilder چیست و هرکدام در چه شرایطی مناسب هستند؟ 📝
4️⃣ ءBoxing و Unboxing چیست؟ یک مثال کوتاه بزنید و هزینهی آن را توضیح دهید. 📦
5️⃣ ءref struct چیست؟ چه محدودیتهایی دارد و چه مشکلی را حل میکند؟ ⚡️
⚙️ فصل ۲ — عملگرها، دستورات و Expressionها (۲ سؤال)
6️⃣ عملگر Null-Coalescing (??) و عملگر Null-Conditional (?.) چیستند؟
7️⃣ حلقهی foreach در پشت صحنه به چه چیزی کامپایل میشود؟ 🔍
🏗 فصل ۳ — شیءگرایی: کلاسها، وراثت و چندریختی (۵ سؤال)
8️⃣ تفاوت بین یک Abstract Class و یک Interface چیست؟
9️⃣ ءPolymorphism (چندریختی) چیست و #C چگونه از طریق virtual و override از آن پشتیبانی میکند؟ 🔄
🔟 ءPrimary Constructor در C# 12 چیست و چه تفاوتی با یک Constructor معمولی دارد؟ 🆕
1️⃣1️⃣ ءInit-Only Setter چیست و چه مشکلی را حل میکند؟ 🔒
2️⃣1️⃣ ءRuntime چگونه یک Virtual Call را با استفاده از VTable Lookup در مقایسه با یک Interface Call اجرا و Dispatch میکند؟ ⚙️🧠
📦 فصل ۴ — Records، Anonymous Types و Tupleها (۳ سؤال)
3️⃣1️⃣ ءrecord در #C چیست و چه تفاوتی با class دارد؟
4️⃣1️⃣ ءEquality در recordها در مقایسه با classها چگونه کار میکند؟ ⚖️
5️⃣1️⃣ چه زمانی record struct را به record class ترجیح میدهید؟ 🤔
🧬 فصل ۵ — Generics و Variance (۳ سؤال)
6️⃣1️⃣ ءGeneric Constraints چیستند و چه انواعی از آنها وجود دارد؟
7️⃣1️⃣ ءCovariance و Contravariance را با استفاده از in و out توضیح دهید. برای هرکدام مثالی با <IEnumerable<T و <Action<T بزنید. 🔄
8️⃣1️⃣ ءJIT چگونه کدهای Generic را برای Value Typeها در مقایسه با Reference Typeها تخصصیسازی میکند؟ این موضوع چه تأثیری بر Performance دارد؟ 🚀
🗂 فصل ۶ — Collections (۵ سؤال)
9️⃣1️⃣ تفاوت بین <IEnumerable<T و <ICollection<T چیست؟
0️⃣2️⃣ ءConcurrent Collections در NET. چیستند؟ چند مورد از آنها را نام ببرید و کاربرد هرکدام را توضیح دهید. 🔄
1️⃣2️⃣ ء<FrozenSet<T و <FrozenDictionary<TKey, TValue چیستند و چه زمانی نسبت به یک Dictionary معمولی Performance بهتری دارند؟ ❄️🚀
2️⃣2️⃣ ء<Dictionary<TKey TValue در داخل چگونه پیادهسازی شده است و چه عواملی روی Performance جستوجوی آن تأثیر میگذارند؟ 🔍
3️⃣2️⃣ ءConcurrentDictionary چگونه بهصورت همزمان بهروزرسانیها را مدیریت میکند؟ استراتژی Locking آن را توضیح دهید. 🔒⚙️
🎯 فصل ۷ — Delegates، Events و Lambdas (۴ سؤال)
4️⃣2️⃣ تفاوت بین یک Delegate و یک Event چیست؟
5️⃣2️⃣ ءClosure چیست و قوانین مربوط به Captured Variables چگونه است؟ 🧠
6️⃣2️⃣ ءExpression Tree چیست و چه تفاوتی با یک Delegate دارد؟ 🌳
7️⃣2️⃣ ءMulticast Delegate چیست و اگر یکی از Handlerها Exception ایجاد کند، چه اتفاقی میافتد؟ ⚡️
🔎 فصل ۸ — LINQ (۵ سؤال)
8️⃣2️⃣ تفاوت بین <IEnumerable<T و <IQueryable<T در LINQ چیست؟
9️⃣2️⃣ ءDeferred Execution در LINQ چیست؟ مثالی بزنید که نشان دهد چه زمانی این موضوع اهمیت پیدا میکند. ⏳
0️⃣3️⃣ ء<IAsyncEnumerable<T چیست و چگونه آن را با await foreach مصرف میکنید؟ ⚡️
1️⃣3️⃣ ءLINQ Provider مربوط به EF Core چگونه Expression Treeها را به SQL تبدیل میکند؟ 🗄
2️⃣3️⃣ چرا استفاده از Count() == 0 روی یک <IEnumerable<T میتواند بدتر از Any() باشد؟ و آیا شرایطی وجود دارد که استفاده از آن مشکلی نداشته باشد؟ 🤔
🧩 فصل ۹ — Pattern Matching (۱ سؤال)
3️⃣3️⃣ ءList Pattern در C# 11 چیست و چه قابلیتهایی را در اختیار ما قرار میدهد؟ 📋
⚠️ فصل ۱۰ — Nullable Reference Types (۱ سؤال)
4️⃣3️⃣ رفتار Nullable Reference Types در Runtime چگونه است؟ آیا این Annotationها در Runtime اعمال و enforce میشوند؟ 🧠⚙️
⏱️ ءPeriodicTimer در NET.؛ چه زمانی بهتر از Task.Delay است؟
خیلی وقتها در پروژههای NET. نیاز داریم یک عملیات را بهصورت دورهای اجرا کنیم:
🔹 هر ۳۰ ثانیه وضعیت سفارشها را بررسی کنیم
🔹 هر ۵ دقیقه Cache را Refresh کنیم
🔹 هر یک دقیقه Jobهای Pending را پردازش کنیم
🔹 هر چند دقیقه اطلاعات یک سرویس خارجی را Sync کنیم
اولین چیزی که خیلی از Developerها مینویسند چیزی شبیه این است:
while (!cancellationToken.IsCancellationRequested)
{
await DoSomethingAsync();
await Task.Delay(
TimeSpan.FromMinutes(5),
cancellationToken);
}
این کد کاملاً معتبر است و در بسیاری از سناریوها هم انتخاب خوبی است.
اما از NET 6. به بعد، یک API مشخص برای همین مدل سناریو داریم:
PeriodicTimerمایکروسافت آن را بهعنوان Timerای معرفی میکند که امکان waiting asynchronously for timer ticks را فراهم میکند.
⏱️ ءPeriodicTimer دقیقاً چیست؟
ء
PeriodicTimer در namespace زیر قرار دارد:System.Threading
و استفاده اصلی آن این است که بهجای Callback-based Timer، منتظر Tick بعدی Timer بمانیم:
using var timer = new PeriodicTimer(
TimeSpan.FromMinutes(5));
while (await timer.WaitForNextTickAsync(cancellationToken))
{
await DoSomethingAsync(cancellationToken);
}
اینجا یک نکته مهم وجود دارد:
ء( )
WaitForNextTickAsync یک <ValueTask<bool برمیگرداند.تا زمانی که Tick بعدی اتفاق نیفتاده، کد شما منتظر میماند و بعد از Tick وارد بدنه حلقه میشود.
اگر Timer متوقف شود، این متد میتواند
false برگرداند و حلقه تمام شود. همچنین ( )Dispose میتواند یک WaitForNextTickAsync فعال را متوقف کند و باعث شود false برگردد.🔄 پس چه فرقی با Task.Delay دارد؟
مثلاً این دو کد را ببینید.
با
Task.Delay:while (!cancellationToken.IsCancellationRequested)
{
await DoSomethingAsync(cancellationToken);
await Task.Delay(
TimeSpan.FromMinutes(5),
cancellationToken);
}
و با
PeriodicTimer:using var timer = new PeriodicTimer(
TimeSpan.FromMinutes(5));
while (await timer.WaitForNextTickAsync(
cancellationToken))
{
await DoSomethingAsync(cancellationToken);
}
از نظر نتیجه ظاهری، هر دو میتوانند یک کار را بهصورت دورهای اجرا کنند.
اما مدل ذهنی آنها متفاوت است.
ء
Task.Delay میگوید:بعد از این مدت دوباره ادامه بده.
در حالی که
PeriodicTimer میگوید:من یک Timer دورهای دارم؛ وقتی Tick بعدی رسید، اجازه بده ادامه بدهم.
برای سناریوهایی که ذاتاً periodic هستند، این مدل بسیار واضحتر است.
⚠️ اما یک اشتباه مهم
نباید تصور کنیم:
PeriodicTimer
یعنی Job شما هر دقیقاً ۵ دقیقه یکبار اجرا میشود.
فرض کنید:
Period = 5 minutes
Tick #1
↓
DoSomethingAsync()
↓
7 minutes
↓
Tick #2
در این مدت شما دوباره
WaitForNextTickAsync() را صدا نزدهاید.طبق مستندات،
PeriodicTimer برای استفاده توسط یک consumer در هر لحظه طراحی شده است و فقط یک WaitForNextTickAsync() باید همزمان در حال انتظار باشد.بنابراین نباید از آن انتظار داشته باشید که برای هر Tick یک اجرای موازی از Job ایجاد کند.
🧠 این رفتار در BackgroundService خیلی کاربردی است
مثلاً فرض کنید در یک سیستم فروشگاهی میخواهیم هر ۳۰ ثانیه سفارشهای Pending را بررسی کنیم:
public sealed class OrderWorker(
IServiceScopeFactory scopeFactory)
: BackgroundService
{
protected override async Task ExecuteAsync(
CancellationToken stoppingToken)
{
using var timer = new PeriodicTimer(
TimeSpan.FromSeconds(30));
while (await timer.WaitForNextTickAsync(
stoppingToken))
{
using var scope =
scopeFactory.CreateScope();
var service =
scope.ServiceProvider
.GetRequiredService<IOrderService>();
await service.ProcessPendingOrdersAsync(
stoppingToken);
}
}
}
اینجا Flow کاملاً مشخص است
و وقتی Application در حال Shutdown باشد، CancellationToken میتواند انتظار Timer را متوقف کند.
📌 پس PeriodicTimer برای چه چیزی مناسب است؟
✅ اجرای Periodic یک عملیات درون یک Process
✅ ءBackground Workerهای ساده
✅ ءPolling
✅ ءCache Refresh
✅ بررسی دورهای وضعیت
✅ ءCleanupهای ساده
✅ ءSync دورهای
و مخصوصاً زمانی که میخواهید این منطق را بهشکل async و قابل Cancellation بنویسید.
#تصمیمهای_مهندسی | Engineering Decisions
یه زمانی فکر میکردم هر چیزی که دوباره استفاده میشه، باید سریع تبدیلش کنیم به یک Abstraction.
مثلاً دو تا Service داشتیم که تقریباً کار مشابهی انجام میدادن.سریع میگفتیم:
«اینارو Generic کنیم که Duplicate Code نداشته باشیم.»
یک Interface. یک Base Class. چندتا Generic Method. چندتا Strategy. و تمام. 😅
روی کاغذ خیلی تمیز به نظر میرسید.
تا چند ماه بعد که Requirement یکی از اون Serviceها تغییر کرد. حالا باید یک رفتار خاص بهش اضافه میکردیم.
ولی چون با یک Abstraction مشترک بسته شده بود، تغییر ساده تبدیل شد به کلی شرط و Exception.
آخرش هم فهمیدیم:
ما دو چیز مشابه را فقط چون امروز شبیه هم بودند، یکی کرده بودیم.
در حالی که ممکن بود فردا مسیرشان کاملاً از هم جدا شود.
از اون موقع یک قانون ساده برای خودم دارم:
ءDuplicate Code همیشه دشمن ما نیست.
گاهی چند خط کد تکراری، از یک Abstraction اشتباه خیلی ارزانتره.
اول اجازه میدم الگو خودش را نشان بده.
بعد اگر واقعاً فهمیدیم این دو رفتار یک مفهوم مشترک دارند،Abstraction میسازیم.
نه صرفاً برای اینکه چند خط Code کمتر داشته باشیم.
چون هدف Refactoring این نیست که Code کمتر شود.
هدف اینه که مدل ذهنی ما از سیستم درستتر شود.
گاهی بهترین Abstraction...
همون Abstractionیه که هنوز نساختیم.
یه زمانی فکر میکردم هر چیزی که دوباره استفاده میشه، باید سریع تبدیلش کنیم به یک Abstraction.
مثلاً دو تا Service داشتیم که تقریباً کار مشابهی انجام میدادن.سریع میگفتیم:
«اینارو Generic کنیم که Duplicate Code نداشته باشیم.»
یک Interface. یک Base Class. چندتا Generic Method. چندتا Strategy. و تمام. 😅
روی کاغذ خیلی تمیز به نظر میرسید.
تا چند ماه بعد که Requirement یکی از اون Serviceها تغییر کرد. حالا باید یک رفتار خاص بهش اضافه میکردیم.
ولی چون با یک Abstraction مشترک بسته شده بود، تغییر ساده تبدیل شد به کلی شرط و Exception.
آخرش هم فهمیدیم:
ما دو چیز مشابه را فقط چون امروز شبیه هم بودند، یکی کرده بودیم.
در حالی که ممکن بود فردا مسیرشان کاملاً از هم جدا شود.
از اون موقع یک قانون ساده برای خودم دارم:
ءDuplicate Code همیشه دشمن ما نیست.
گاهی چند خط کد تکراری، از یک Abstraction اشتباه خیلی ارزانتره.
اول اجازه میدم الگو خودش را نشان بده.
بعد اگر واقعاً فهمیدیم این دو رفتار یک مفهوم مشترک دارند،Abstraction میسازیم.
نه صرفاً برای اینکه چند خط Code کمتر داشته باشیم.
چون هدف Refactoring این نیست که Code کمتر شود.
هدف اینه که مدل ذهنی ما از سیستم درستتر شود.
گاهی بهترین Abstraction...
همون Abstractionیه که هنوز نساختیم.
📌 200+ سوال مصاحبه واقعی (بخش 2️⃣)
[ BUCKET 1 — C# AND .NET ]
⚠️ فصل ۱۱ — مدیریت خطا در #C (۳ سؤال)
5️⃣3️⃣ تفاوت بین throw ex و throw داخل یک catch block چیست؟ ⚠️
6️⃣3️⃣ هزینهی Throw کردن Exception در NET. چقدر است و چرا نباید از Exceptionها برای Control Flow استفاده کنیم؟ 🚨
7️⃣3️⃣ وقتی یک Exception رخ میدهد، CLR چگونه Stack را Unwind میکند؟ و JIT در مرزهای try/catch چه کاری انجام میدهد؟ 🧠⚙️
⚡️ فصل ۱۲ — Async/Await و Taskها (۶ سؤال)
8️⃣3️⃣ تفاوت بین Task و ValueTask چیست و هرکدام را چه زمانی باید استفاده کنیم؟ ⚡️
9️⃣3️⃣ هدف ConfigureAwait(false) چیست و چه زمانی باید از آن استفاده کنیم؟ 🔄
0️⃣4️⃣ ءCompiler برای یک متد async چه State Machineای تولید میکند؟ این State Machine چه چیزهایی را Allocate میکند؟ 🧠
1️⃣4️⃣ ءSynchronizationContext چیست و چگونه روی Resume شدن یک await تأثیر میگذارد؟ 🔄
2️⃣4️⃣ تفاوت async void و async Task چیست و چرا async void خطرناک است؟ ⚠️
3️⃣4️⃣ چرا وقتی در Contextی که SynchronizationContext دارد روی یک Task از .Result یا .Wait() استفاده میکنیم، ممکن است Deadlock رخ دهد؟ 🔒
🧵 فصل ۱۳ — Threading و Synchronization (۴ سؤال)
4️⃣4️⃣ ءlock چیست و به چه چیزی Compile میشود؟ 🔐
5️⃣4️⃣ شیء جدید Lock در C# 13 چیست و چگونه نسبت به Lock کردن روی یک Object دلخواه بهتر عمل میکند؟ 🆕🔒
6️⃣4️⃣ ء<Channel<T در NET. چیست و در مقایسه با <BlockingCollection<T چه سناریوهایی را حل میکند؟ 📡
7️⃣4️⃣ وقتی Threadهای ThreadPool به دلیل sync-over-async یا Blocking روی عملیات I/O دچار Starvation شوند چه اتفاقی میافتد؟ چگونه آن را Diagnose میکنید؟ 🚨🧵
🧠 فصل ۱۴ — مدیریت حافظه و GC (۵ سؤال)
8️⃣4️⃣ ءGenerationهای 0، 1 و 2 در GC را توضیح دهید. Objectها چگونه بین این Generationها Promote میشوند؟ ♻️
9️⃣4️⃣ ءLarge Object Heap (LOH) چیست و چرا برای Performance اهمیت دارد؟ 🧠📦
0️⃣5️⃣ تفاوت Workstation GC و Server GC چیست؟ 🖥⚙️
1️⃣5️⃣ ءDispose Pattern چیست و چرا شامل Dispose(bool disposing) است؟ 🗑
2️⃣5️⃣ چگونه یک Memory Leak را در یک برنامهی NET. پیدا و Diagnose میکنید؟ از چه ابزارهایی استفاده میکنید؟ 🔍🧠
🔎 فصل ۱۵ — Reflection و Dynamic (۲ سؤال)
3️⃣5️⃣ هزینهی Performance مربوط به Reflection چیست و چگونه میتوان نتایج Reflection را Cache کرد؟ 🔍⚡️
4️⃣5️⃣ ءSource Generatorها در مقایسه با Reflection برای حل مسائل مشابه چه تفاوتی دارند؟ ⚙️
📐 فصل ۱۶ — Span، Memory و Pipelines (۳ سؤال)
5️⃣5️⃣ ء<Span<T چیست و چه مشکلی را حل میکند؟ 🚀
6️⃣5️⃣ چرا <Span<T نمیتواند بهعنوان یک Field در یک Class معمولی استفاده شود؟ راهکار چیست؟ 🧠
7️⃣5️⃣ ء<ArrayPool<T چیست و چه زمانی باید از آن استفاده کنید؟ ♻️📦
📦 فصل ۱۷ — Serialization (۲ سؤال)
8️⃣5️⃣ حالت Source Generator در System.Text.Json چیست و چه زمانی باید از آن استفاده کنیم؟ ⚡️
9️⃣5️⃣ چرا BinaryFormatter Deprecated شد و بهجای آن باید از چه چیزی استفاده کنیم؟ 🚫
🆕 فصل ۱۸ — قابلیتهای نسخههای #C (۲ سؤال)
0️⃣6️⃣ کلیدواژهی field در C# 14 چیست و چه مشکلی را در Setterهای Property حل میکند؟ 🆕✨
1️⃣6️⃣ ءCallerArgumentExpression چیست و چگونه در پیادهسازی Guard Clauseها کاربرد دارد؟ 🛡
⚙️ فصل ۱۹ — NET Runtime، CLR، JIT. و AOT (۳ سؤال)
6️⃣2️⃣ ءTiered Compilation در NET. چیست و چگونه بین Startup Performance و Steady-State Performance تعادل ایجاد میکند؟ 🚀
6️⃣3️⃣ ءNative AOT چیست و استفاده از آن چه Trade-offهایی دارد؟ ⚡️
6️⃣4️⃣ ءPGO (Profile-Guided Optimization) چیست و Dynamic PGO در NET. چگونه کار میکند؟ 🧠🚀
📊 فصل ۲۰ — Performance و Benchmarking (۲ سؤال)
6️⃣5️⃣ چرا نباید از Stopwatch و یک حلقهی for بهعنوان جایگزین BenchmarkDotNet استفاده کنیم؟ ⏱️
6️⃣6️⃣ ءMemoryDiagnoser چه چیزی را اندازهگیری میکند و چگونه باید تعداد Gen0، Gen1 و Gen2 را تفسیر کنیم؟ 🧠📊
📁 فصل ۲۱ — BCL و I/O (۲ سؤال)
6️⃣7️⃣ تفاوت بین Stream، MemoryStream و FileStream چیست؟ 📁
6️⃣8️⃣ ءRandomAccess که در NET 6. معرفی شد چیست و چه سناریویی را بهبود میدهد؟ ⚡️📂
📦 فصل ۲۲ — NuGet (۱ سؤال)
6️⃣9️⃣ ءCentral Package Management و فایل Directory.Packages.props چیستند؟ 📦
🛠 فصل ۲۳ — MSBuild و csproj (۲ سؤال)
7️⃣0️⃣ ءDirectory.Build.props و Directory.Build.targets چیستند و چه کاربردی دارند؟ 🛠
7️⃣1️⃣ ءMulti-Targeting چیست و چه زمانی از آن استفاده میکنید؟ 🎯
💻 فصل ۲۴ — NET CLI. (۲ سؤال)
7️⃣2️⃣ تفاوت dotnet build و dotnet publish چیست؟ 💻
7️⃣3️⃣ ءglobal.json چیست و چه مشکلی را در محیطهایی که چند نسخهی NET. دارند حل میکند؟ ⚙️
👨💻 دوستان وقتشه یه Community بسازیم! 🚀
از شما میخوام که بیاید توی گروه چت کنار هم باشیم؛ سؤال بپرسیم، تجربههامون رو به اشتراک بذاریم و درباره هر چیزی که به دنیای NET. مربوطه بحث کنیم و از تجربه همدیگه استفاده کنیم. 🔥
اینجا قرار نیست فقط چندتا پیام رد و بدل بشه؛ هدفمون ساختن یه Community فعال از مهندسهای NET. که هر کسی چیزی برای یاد دادن و یاد گرفتن داشته باشه. 🤝
اگه تجربهای دارید، حتماً به درد یکی دیگه میخوره.
پس بیاید کنار هم یه کامیونیتی خفن بسازیم. ❤️🔥
📌منتظرتونیم: [ C# Geeks (Chat) ]
از شما میخوام که بیاید توی گروه چت کنار هم باشیم؛ سؤال بپرسیم، تجربههامون رو به اشتراک بذاریم و درباره هر چیزی که به دنیای NET. مربوطه بحث کنیم و از تجربه همدیگه استفاده کنیم. 🔥
اینجا قرار نیست فقط چندتا پیام رد و بدل بشه؛ هدفمون ساختن یه Community فعال از مهندسهای NET. که هر کسی چیزی برای یاد دادن و یاد گرفتن داشته باشه. 🤝
اگه تجربهای دارید، حتماً به درد یکی دیگه میخوره.
پس بیاید کنار هم یه کامیونیتی خفن بسازیم. ❤️🔥
📌منتظرتونیم: [ C# Geeks (Chat) ]
C# Geeks (.NET) pinned «👨💻 دوستان وقتشه یه Community بسازیم! 🚀 از شما میخوام که بیاید توی گروه چت کنار هم باشیم؛ سؤال بپرسیم، تجربههامون رو به اشتراک بذاریم و درباره هر چیزی که به دنیای NET. مربوطه بحث کنیم و از تجربه همدیگه استفاده کنیم. 🔥 اینجا قرار نیست فقط چندتا پیام رد و بدل…»
📌 200+ سوال مصاحبه واقعی (بخش 3️⃣)
[ BUCKET 2 - ASP.NET Core AND EF Core ]
🌐 فصل 25 — انواع پروژههای وب در ASP.NET Core
📌 76. انواع اصلی پروژههای وب در ASP.NET Core چیستند؟
📌 77. چه زمانی Minimal APIs را بهجای یک پروژهی API مبتنی بر Controller انتخاب میکنید؟
🏠 فصل 26 — Application Host
⚙️ 78. ءWebApplicationBuilder چیست و چگونه پیکربندی Host و Application را سادهتر میکند؟
🔄 79. ءIHostedService چیست و یک کاربرد معمول آن چیست؟
🛑 80. ءIHost.StopAsync از چه مکانیزمهایی برای ارسال سیگنال Graceful Shutdown استفاده میکند؟
🎮 فصل 27 — Controllers
🔗 81. ءModel Binding چیست و در ASP.NET Core Controllers چگونه کار میکند؟
📥 82. تفاوت بین [FromBody]، [FromQuery]، [FromRoute] و [FromForm] چیست؟
🎯 83. هدف IActionResult چیست و چرا ممکن است آن را به یک Concrete Return Type ترجیح دهیم؟
♻️ 84. چرخهی حیات یک Controller در ASP.NET Core چگونه است؟ چه زمانی ساخته و چه زمانی Dispose میشود؟
🚨 85. چگونه میتوان Exceptionها را بهصورت سراسری برای تمام Controllerها مدیریت کرد؟
⚡️ فصل 28 — Minimal APIs
🔹 86. ءMinimal API چه تفاوتی با یک API سنتی مبتنی بر Controller دارد؟
🔐 87. چگونه Endpointهای Minimal API را با استفاده از Authentication و Authorization امن میکنید؟
🔄 88. چگونه در Minimal APIs، API Versioning را پیادهسازی میکنید؟
🧩 89. چه نوع Filterهایی توسط Minimal APIs پشتیبانی میشوند؟
🏢 90. استفاده از Minimal APIs در یک Application بزرگ و Enterprise چه مزایا و معایبی دارد؟
🔗 فصل 29 — Middlewareها
⛓️ 91. ترتیب اجرای Middlewareها چگونه است و چرا اهمیت دارد؟
🛠 92. تمام روشهای ایجاد Middleware در ASP.NET Core را نام ببرید.
⚙️ 93. تفاوت بین Convention-Based Middleware و Factory-Based Middleware چیست؟
🚨 94. چگونه میتوان Exceptionها را بهصورت سراسری با استفاده از Middleware مدیریت کرد؟
🎯 فصل 30 — Filterها
🧩 95. انواع اصلی Filterهای موجود در ASP.NET Core را نام ببرید.
🔢 96. چگونه میتوان ترتیب اجرای Filterها را کنترل کرد؟
⚙️ 97. تفاوت بین Resource Filter و Action Filter چیست؟
🌐 98. منظور از Filter Scopeهای Global، Controller و Action چیست و اولویت اجرای آنها چگونه تعیین میشود؟
🌍 فصل 31 — مبانی REST
📈 99. ءRichardson Maturity Model چیست و چه سطوحی دارد؟
🏗 100. شش Architectural Constraint در REST را نام ببرید و هرکدام را بهطور خلاصه توضیح دهید.
🔄 101. تفاوت بین PUT و PATCH چیست؟
🎯 102. ءIdempotency چیست؟ کدام HTTP Methodها Idempotent هستند؟
🔐 103. تفاوت بین 401 Unauthorized و 403 Forbidden چیست؟
🔗 104. ءHATEOAS چیست و چه ارتباطی با REST Level 3 دارد؟
📄 105. استراتژیهای رایج برای Pagination در REST APIها چیستند؟
🎛 106. ءData Shaping در REST APIها چیست و چرا مفید است؟
🔄 فصل 32 — API Versioning
🌐 107. تفاوت بین روشهای Versioning مبتنی بر URL، Query String، Header و Content Negotiation چیست؟
⚠️ 108. چگونه یک API Version را بهعنوان Deprecated علامتگذاری میکنید؟
🛡 109. هنگام معرفی یک API Version جدید، چگونه Backward Compatibility را حفظ میکنید؟
✅ فصل 33 — Validation
🧪 110. ءFluentValidation چیست و چرا ممکن است آن را به DataAnnotations ترجیح دهید؟
🌳 111. ءFluentValidation چگونه Complex Object Graphها یا Child Collectionها را اعتبارسنجی میکند؟
⏳ 112. چگونه در FluentValidation، Asynchronous Validation انجام میدهید؟
💉 113. چگونه میتوان سرویسهایی مانند دسترسی به Database را داخل یک FluentValidation Validator تزریق کرد؟
🚨 114. چگونه خطاهای FluentValidation را در APIها به شکل Problem Details برمیگردانید؟
🗺 فصل 34 — Mapping
🔄 115. ءAutoMapper چیست و در Solutionهای بزرگ چه مشکلات و اشتباهات رایجی ممکن است ایجاد کند؟
⚡️ 116. ءMapperly چیست و چگونه از Source Generatorها استفاده میکند؟
⚖️ 117. استفاده از Mapperly در مقایسه با Mapperهای Runtime مانند AutoMapper چه مزایا و معایبی دارد؟
🧑💻 118. چه زمانی Manual Mapping میتواند انتخاب بهتری نسبت به استفاده از یک Mapping Library باشد؟
یه اتفاق جالب با AI داره توی تیم های Software میافته.
قبلاً میگفتیم:
«این Code رو کی نوشته؟»
الان باید یه سوال دیگه هم بپرسیم:
«کی واقعاً میفهمتش؟»
قبلاً میگفتیم:
«این Code رو کی نوشته؟»
الان باید یه سوال دیگه هم بپرسیم:
«کی واقعاً میفهمتش؟»
#Engineering_Productivity
یه روز تصمیم گرفتم ببینم واقعاً چرا بعضی روزها ۸ ساعت کار میکنم، ولی آخر روز حس میکنم تقریباً هیچ کاری نکردم.
شروع کردم به نگاه کردن به کارهایی که اون روز انجام داده بودم:
۳۰ دقیقه روی یک Bug.
بعد یک پیام از تیم.
رفتم سراغ یک PR.
بعد یک سؤال از Product.
برگشتم روی Bug.
یک Meeting.
بعد CI شکست.
بعد دوباره PR.
آخر روز شاید ۶-۷ ساعت درگیر کار بودم...
ولی هیچکدوم واقعاً جلو نرفته بود.
مشکل کمکاری نبود. Context Switching بود.
هر بار که از یک مسئله خارج میشیم و وارد مسئلهی دیگری میشیم، بخشی از Context قبلی رو از دست میدیم.
و وقتی دوباره برمیگردیم، باید زمان بذاریم تا یادمون بیاد:
«کجا بودم؟»
«چی داشتم بررسی میکردم؟»
«چرا این تصمیم رو گرفتم؟»
برای همین گاهی:
حتی بدتر...
اگر چند نفر از یک تیم دائماً همدیگه رو Interrupt کنن، مشکل فقط فردی نیست.
کل تیم وارد یک چرخه میشه:
برای همین بعضی تیمها با اضافه کردن آدم بیشتر، الزاماً سریعتر نمیشن.
چون ممکنه فقط تعداد Interruptها رو بیشتر کنن.
این روزها سعی میکنم هر کاری که نیاز به تمرکز داره رو تا جای ممکن یکتکه انجام بدم.Notification کمتر. Meeting کمتر. Taskهای همزمان کمتر.
و مهمتر از همه:
کارهای نیمهتمام کمتر.
چون Productivity همیشه یعنی سریعتر کار کردن نیست.
گاهی یعنی:
اجازه بدی یک Engineer آنقدر Context داشته باشه که واقعاً یک مسئله رو تمام کنه.
یه روز تصمیم گرفتم ببینم واقعاً چرا بعضی روزها ۸ ساعت کار میکنم، ولی آخر روز حس میکنم تقریباً هیچ کاری نکردم.
شروع کردم به نگاه کردن به کارهایی که اون روز انجام داده بودم:
۳۰ دقیقه روی یک Bug.
بعد یک پیام از تیم.
رفتم سراغ یک PR.
بعد یک سؤال از Product.
برگشتم روی Bug.
یک Meeting.
بعد CI شکست.
بعد دوباره PR.
آخر روز شاید ۶-۷ ساعت درگیر کار بودم...
ولی هیچکدوم واقعاً جلو نرفته بود.
مشکل کمکاری نبود. Context Switching بود.
هر بار که از یک مسئله خارج میشیم و وارد مسئلهی دیگری میشیم، بخشی از Context قبلی رو از دست میدیم.
و وقتی دوباره برمیگردیم، باید زمان بذاریم تا یادمون بیاد:
«کجا بودم؟»
«چی داشتم بررسی میکردم؟»
«چرا این تصمیم رو گرفتم؟»
برای همین گاهی:
8 Hours Worked
≠
8 Hours of Progress
حتی بدتر...
اگر چند نفر از یک تیم دائماً همدیگه رو Interrupt کنن، مشکل فقط فردی نیست.
کل تیم وارد یک چرخه میشه:
Work
↓
Interrupt
↓
Context Switch
↓
Recovery
↓
Work
↓
Interrupt
برای همین بعضی تیمها با اضافه کردن آدم بیشتر، الزاماً سریعتر نمیشن.
چون ممکنه فقط تعداد Interruptها رو بیشتر کنن.
این روزها سعی میکنم هر کاری که نیاز به تمرکز داره رو تا جای ممکن یکتکه انجام بدم.Notification کمتر. Meeting کمتر. Taskهای همزمان کمتر.
و مهمتر از همه:
کارهای نیمهتمام کمتر.
چون Productivity همیشه یعنی سریعتر کار کردن نیست.
گاهی یعنی:
اجازه بدی یک Engineer آنقدر Context داشته باشه که واقعاً یک مسئله رو تمام کنه.
📌 200+ سوال مصاحبه واقعی (بخش 4️⃣)
[ BUCKET 2 - ASP.NET Core AND EF Core ]
🔧 فصل 35 — Configuration و Options Pattern
📌 119. ءOptions Pattern چیست و چرا استفاده از آن بهجای دسترسی مستقیم به Configuration ترجیح داده میشود؟
🔄 120. تفاوت بین IOptions<T>، IOptionsSnapshot<T و <IOptionsMonitor<T چیست؟
✅ 121. چگونه Configurationای را که به یک Class متصل شده است، با استفاده از DataAnnotations اعتبارسنجی میکنید؟
🔐 122. چگونه مقادیر حساس Configuration مانند API Keyها یا Connection Stringها را امن نگه میدارید؟
🚨 فصل 36 — Error Handling
🛑 123. ءMiddleware مربوط به UseExceptionHandler چیست و چگونه آن را پیکربندی میکنید؟
🆕 124. در NET 8. برای مدیریت سراسری خطاها چه قابلیت جدیدی با نام IExceptionHandler اضافه شده است؟
📋 125. چگونه در ASP.NET Core APIها، Problem Details (RFC 9457) را برمیگردانید؟
🔀 126. چگونه Exceptionهای سفارشی را بهصورت سراسری به HTTP Status Codeهای مشخص نگاشت میکنید؟
📝 فصل 37 — Logging
🔍 127. ءStructured Logging چیست و چرا باید از آن استفاده کنیم؟
🏷 128. ءScopeها در ASP.NET Core Logging چیستند و چگونه از آنها استفاده میکنید؟
🗄 129. چگونه Logging مربوط به Database Commandهای EF Core را فعال میکنید؟
📊 130. چگونه برای محیط Production، Log Aggregation و Monitoring را پیادهسازی میکنید؟
🔄 131. چگونه در Serilog حجم Logها و Log File Rotation را کنترل میکنید؟
📌 فصل 38 — Health Checks
🟢 132. تفاوت بین Liveness Probe و Readiness Probe چیست؟
🩺 133. چگونه یک Custom Health Check پیادهسازی میکنید؟
💉 فصل 39 — Dependency Injection (DI)
🔄 134. سه DI Lifetime رایج در ASP.NET Core کداماند؟
⚠️ 135. هنگام Inject کردن یک Scoped Service داخل یک Singleton Service چه مشکلاتی ممکن است ایجاد شود؟
🔧 136. چگونه یک Scoped Service را داخل یک Background Task یا Singleton Class Resolve میکنید؟
🔄 137. چگونه با Circular Dependencyها در DI برخورد میکنید؟
🎯 138. چگونه Conditional Dependency Resolution را پیادهسازی میکنید؛ مثلاً بر اساس Configuration؟
🗄 فصل 40 — Entity Framework Core
📦 139. تفاوت بین DbContext و DbSet چیست؟
🔗 140. تفاوت بین Eager Loading، Lazy Loading و Explicit Loading چیست؟
⚡️ 141. چه زمانی و چرا باید از ( )AsNoTracking. در Queryها استفاده کنید؟
📊 142. ءQuery Splitting (AsSplitQuery) چیست و چه مشکل Performanceای را حل میکند؟
♻️ 143. ءContext Pooling چیست و چگونه به Applicationهای با Throughput بالا کمک میکند؟
🔒 144. چگونه Optimistic Concurrency را با استفاده از RowVersion یا Concurrency Token پیادهسازی و مدیریت میکنید؟
⚡️ 145. چگونه عملیات Batch Update/Delete را در EF Core بدون Load کردن Entityها انجام میدهید؟
[ BUCKET 3 — CACHING, SCHEDULING, MESSAGING, AND SECURITY ]
🔐 فصل 41 — Authentication و Authorization
🆔 146. تفاوت بین Authentication و Authorization چیست؟
🍪 147. تفاوت بین Cookie Authentication و JWT Bearer Authentication چیست؟
📌 148. ءRefresh Token چیست؟ جریان Authentication با JWT + Refresh Token را توضیح دهید.
🛡 149. چگونه Policy-Based یا Claim-Based Authorization را پیادهسازی میکنید؟
📋 150. در مفهوم Authorization Policy، یک Requirement چیست؟
⚙️ 151. چگونه یک Custom Authorization Handler ایجاد میکنید؟
🔄 152. یک سناریو را توضیح دهید که در آن Claims Transformation ضروری است و نحوه پیادهسازی آن را بیان کنید.
👤 فصل 42 — ASP.NET Core Identity
🔑 153. چگونه قوانین Password مانند طول، پیچیدگی و سایر الزامات را در Identity پیکربندی میکنید؟
📱 154. چگونه با استفاده از Identity، Two-Factor Authentication (2FA) را پیادهسازی میکنید؟
🔒 155. چگونه میتوان یک User را پس از چند Login ناموفق Lockout کرد؟
🔗 156. چگونه Identity را با Authentication مبتنی بر JWT Token برای APIها یکپارچه میکنید؟
🗄 157. چگونه برای یک Database از نوع NoSQL، Custom User Store ایجاد و مدیریت میکنید؟
🛡 فصل 43 — ASP.NET Core Security
🌐 158. ءCORS چیست و اجازه دادن به دسترسی گسترده از طریق آن چه خطرات امنیتی دارد؟
✈️ 159. درخواستهای Preflight OPTIONS در CORS چگونه کار میکنند؟
🔐 160. چگونه Signature و Claims یک JWT را اعتبارسنجی میکنید؟
⚠️ 161. ءRefresh Tokenها چه خطرات امنیتیای دارند؟
🚫 162. چگونه Refresh Tokenها را مثلاً هنگام Logout یا تغییر Password Invalidate میکنید؟
🔑 163. ءOAuth 2.0 چیست و چگونه برای امنسازی APIها استفاده میشود؟
🆔 164. ءOpenID Connect (OIDC) چیست و چه تفاوتی با OAuth 2.0 دارد؟
📌 ءPagination رو باOffsetپیاده کنیم یاCursor؟
یکی از اون تصمیمهاییه که موقع ساختن API خیلی راحت از کنارش رد میشیم.
مثلاً میخوایم لیست سفارشها رو برگردونیم.
خب معلومه دیگه 😎
میزنیم:
SELECT *
FROM Orders
ORDER BY Id
OFFSET 100000
LIMIT 20;
یا توی EF Core:
var orders = await db.Orders
.OrderBy(x => x.Id)
.Skip(100000)
.Take(20)
.ToListAsync();
تموم شد رفت.
هم سادهست، هم خواناست، هم برای صفحهبندی خیلی راحت میتونیم بگیم:
page=1page=2page=3و الی آخر...
ولی یک لحظه صبر کن... 🤨
واقعاً فکر میکنی وقتی رسیدیم به صفحهی مثلاً 10,000، دیتابیس میگه:
«چشم قربان، دقیقاً 20 تا رکوردت رو از این وسط برمیدارم»؟ 😎
نه دقیقاً!
OFFSET به دیتابیس میگه:«این 100 هزار رکورد اول رو رد کن، بعد 20 تای بعدی رو بده.»
یعنی رکوردهایی که قرار نیست به Application برسن، باز هم باید در سمت دیتابیس پردازش بشن.
خود PostgreSQL هم صراحتاً میگه رکوردهایی که توسط
OFFSET رد میشن، همچنان باید توسط Server محاسبه بشن و OFFSETهای بزرگ میتونن inefficient باشن.پس اگر دیتاست کوچیکه؟
احتمالاً اصلاً مسئلهی خاصی نداری.
ولی اگر داری با میلیونها رکورد و Pagination عمیق سروکله میزنی، داستان فرق میکنه.
حالا بریم سراغ گزینهی دوم:
🎯 Cursor / Keyset Pagination
اینجا بهجای اینکه به دیتابیس بگیم:
«100 هزار تا رکورد رو رد کن»
میگیم:
«من تا اینجا اومدم؛ از بعدِ این رکورد ادامه بده.»
مثلاً:
SELECT *
FROM Orders
WHERE Id > 100000
ORDER BY Id
LIMIT 20;
یا در EF Core:
var orders = await db.Orders
.Where(x => x.Id > lastSeenId)
.OrderBy(x => x.Id)
.Take(20)
.ToListAsync();
اینجا دیگه مفهوم اصلی
page number نیست.مفهوم اصلی اینه:
🧠 من آخرین چیزی که دیدم چی بود؟
مثلاً Response اول:
{
"items": [...],
"nextCursor": "100020"
}Request بعدی:
GET /orders?cursor=100020
و دیتابیس میگه:
WHERE Id > 100020
ORDER BY Id
LIMIT 20
اگر روی
Id ایندکس داشته باشیم، دیتابیس میتونه خیلی مستقیمتر به محدودهی موردنظر برسه.ءMicrosoft هم در مستندات EF Core، برای Paginationهایی که فقط حرکت صفحهبهصفحه لازم دارند، Keyset Pagination را بهعنوان جایگزین مناسب
Skip/Take معرفی میکند.اما داستان فقط Performance نیست! 👀
فرض کن کاربر صفحهی 2 رو گرفته.
بعد وسط کار، یک Order جدید وارد سیستم میشه.
اگر از
OFFSET استفاده کنیم، موقع درخواست صفحهی بعدی ممکنه مجموعهی نتایج نسبت به درخواست قبلی جابهجا شده باشه و در شرایط تغییر همزمان دادهها، بعضی رکوردها دوباره دیده بشن یا بعضیها از دست برن.ولی Keyset میگه:
«من آخرین رکوردی که دیدم رو میدونم؛ از همون نقطه ادامه بده.»
به همین دلیل برای چیزهایی مثل:
📰 Feed
🛒 Order List
💬 Message List
📜 Activity Log
🔔 Notification List
و سیستمهایی که کاربر معمولاً فقط میخواد:
Next → Next → Nextبره جلو، Cursor Pagination خیلی جذاب میشه.
اماااااا... 😏
اینجا هم قرار نیست بگیم: Cursor > Offset
و تمام!
چون Cursor یک محدودیت مهم داره.
فرض کن کاربر میگه:
«برو صفحه 873!»
با Cursor این کار به اون سادگی Offset نیست.
چون Cursor اساساً برای حرکت ترتیبی روی یک Result Set طراحی شده، نه Jump کردن مستقیم به یک Page Number.
پس مثلاً برای یک: 👨💼 Admin Panel
که کاربر میخواد بگه:
Page 1 | 2 | 3 | ... | 50و مستقیماً بره صفحه 30...
Offset Paginationهنوز میتونه انتخاب کاملاً معقولی باشه.
اما برای یک: 📱 Infinite Scroll
که کاربر فقط میگه:
«بیشتر بیار» Cursor معمولاً انتخاب بهتریه.
پس اگر بخوام خیلی خلاصه تصمیم بگیرم:
🟢 Offset Pagination
وقتی:
▫️تعداد داده خیلی زیاد نیست
▫️کاربر باید مستقیماً به یک Page خاص بره
▫️ءUX بر اساس Page Number طراحی شده
▫️سادگی Implementation برات مهمه
🔵 Cursor / Keyset Pagination
وقتی:
▫️ءDataset بزرگه
▫️ءPagination عمیقه
▫️کاربر معمولاً Next/Previous میکنه
▫️ءInfinite Scroll داری
▫️دادهها مرتباً Insert/Delete میشن
▫️ءPerformance در صفحات عمیق مهمه
و یک نکتهی خیلی مهم:
اگر Pagination داری، Order باید deterministic و ترجیحاً unique باشه.
مثلاً فقط:
.OrderByDescending(x => x.CreatedAt)
ممکنه کافی نباشه، چون چند رکورد میتونن
CreatedAt یکسان داشته باشن.بهتره مثلاً:
.OrderByDescending(x => x.CreatedAt)
.ThenByDescending(x => x.Id)
داشته باشی تا ترتیب کاملاً مشخص باشه. Microsoft هم روی unique بودن ترتیب برای Pagination تأکید کرده.
🔖هشتگها:
#Pagination #OffsetPagination #CursorPagination #KeysetPagination
Forwarded from thisisnabi.dev [10x Developer]
سلام عزیزان
کمی بخاطر سر شلوغی این موضوع عقب افتاد اما می تونید جزئیات میت ها رو در سایت زیر ببینید.
https://thisisnabi.dev
برای پرداخت 10x developer همون طور که قول دادم 50% تخفیف بگیرید.
اما چون system design هنوز پیش ثبت نامه شرایط پرداخت 4 قسطه اسنپ پی رو اگر دارین می تونید باهاش پرداخت انجام بدید.
برای جزئیات پرداخت به @thisisnabi_admin پیام بدید.
کمی بخاطر سر شلوغی این موضوع عقب افتاد اما می تونید جزئیات میت ها رو در سایت زیر ببینید.
https://thisisnabi.dev
برای پرداخت 10x developer همون طور که قول دادم 50% تخفیف بگیرید.
اما چون system design هنوز پیش ثبت نامه شرایط پرداخت 4 قسطه اسنپ پی رو اگر دارین می تونید باهاش پرداخت انجام بدید.
برای جزئیات پرداخت به @thisisnabi_admin پیام بدید.
📌 200+ سوال مصاحبه واقعی (بخش 5️⃣)
[ BUCKET 3 — CACHING, SCHEDULING, MESSAGING, AND SECURITY ]
⚡️ فصل 44 — Caching
💾 165. ءIDistributedCache چیست و چه تفاوتی با Memory Cache دارد؟
⏳ 166. چگونه Cache Expiration و Eviction Policyها را برای Redis پیادهسازی میکنید؟
🚀 167.ءOutputCache در ASP.NET Core چیست و چگونه آن را برای Endpointها پیکربندی میکنید؟
🎯 168. چگونه میتوان OutputCache را بر اساس پارامترهای Request یا هویت کاربر (User Identity) تغییر داد؟
🔀 169. ءHybridCache چیست و چگونه In-Memory Cache و Distributed Cache را با یکدیگر ترکیب میکند؟
🏗 170. چگونه از HybridCache با یک استراتژی L1/L2 در ASP.NET Core استفاده میکنید؟
🔥 171. ءFusionCache چیست و چه مشکلی را که HybridCache دارد، حل میکند؟
⏰ فصل 49 — Task Scheduling
⚙️ 172. ءBackground Service در ASP.NET Core چیست؟ چه زمانی Start و چه زمانی Stop میشود؟
🔄 173. تفاوت بین Background Service و IHostedService چیست؟
🚨 174. اگر یک Unhandled Exception در یک Background Service رخ دهد، چه اتفاقی میافتد؟
📅 175. چگونه با استفاده از Quartz.NET و Cron Expressionها، Taskهای تکرارشونده (Recurring Tasks) را زمانبندی میکنید؟
💉 176. چگونه Dependencyها را داخل Quartz Jobها Inject میکنید؟
🛑 177. برای جلوگیری از اجرای چندباره یک Scheduled Job در چند Instance مختلف، از چه استراتژیهایی میتوانید استفاده کنید؟
🌐 178. چگونه یک راهکار Distributed Scheduling را برای اجرای Taskها روی چند Server معماری میکنید؟
📨 فصل 50 — Event Messaging
🔄 179. ءMediatR چیست و کدام Design Pattern را پیادهسازی میکند؟
📢 180. چگونه با استفاده از MediatR، Notification ارسال و Handle میکنید؟
⚠️ 181. استفاده بیش از حد (Overuse) از MediatR در یک پروژه چه معایب و مشکلاتی میتواند ایجاد کند؟
📨 182. ءMassTransit چیست و چه نقشی در Event-Driven Architecture دارد؟
🐇 183. چگونه MassTransit را با RabbitMQ یا یک Message Broker دیگر پیکربندی میکنید؟
📦 184. چگونه Messageها (Event / Command) را با استفاده از MassTransit تعریف و Consume میکنید؟
🚀 185. قابلیتهای پیشرفته MassTransit مانند Sagaها یا Message Retry Policyها چیستند؟
[ BUCKET 4 — SYSTEM DESIGN AND ARCHITECTURE ]
🌐 فصل 51 — APIs، SDKs و Resilience
⚠️ 186. اگر برای هر API Call یک HttpClient جدید ایجاد کنید، چه اتفاقی میافتد؟
🏭 187. ءHttpClientFactory چیست و چرا در ASP.NET Core معرفی شد؟
🎯 188. ءTyped Client چیست و چه تفاوتی با Named Client دارد؟
🔗 189. ءRefit چیست و چگونه با استفاده از آن یک API Interface تعریف میکنید؟
⛓️ 190. ءDelegatingHandler چیست و کاربردهای رایج آن چیستند؟
🛡 191. ءPolly چیست و چگونه در کنار HttpClientFactory استفاده میشود؟
🔄 192. یک مثال از اضافه کردن Retry Policy با استفاده از Polly به HttpClientFactory ارائه دهید.
🚨 193. چگونه استراتژی Circuit Breaker را با استفاده از Polly پیادهسازی میکنید؟
🛟 194. چگونه استراتژی Fallback را با استفاده از Polly پیادهسازی میکنید؟
🔐 195. چگونه Authentication و Token Refresh را برای Outgoing HTTP Requests مدیریت میکنید؟
🔭 فصل 52 — OpenTelemetry & Observability
📊 196. سه ستون اصلی (Three Pillars) مربوط به Observability در OpenTelemetry چیستند؟
🏗 197. ءOpenTelemetry Collector چیست و چه نقشی دارد؟
🔍 198. در مفهوم Distributed Tracing، یک Span و یک Trace چیستند؟
🔗 199. چگونه Distributed Context Propagation و Baggage را بین Microserviceها مدیریت میکنید؟
🎯 200. ءSampling در OpenTelemetry چیست و چرا از Strategyهای مختلف Sampling استفاده میکنید؟
📈 201. چگونه در دات نت، Custom Metrics مانند Counterها و Histogramها ایجاد میکنید؟
🔗 202. ءTrace Links در OpenTelemetry چیستند و چه زمانی مفید هستند؟
📊 203.چگونه OpenTelemetry را برای مدیریت دادههای High-Cardinality در Metricها پیکربندی میکنید؟
🐳 فصل 54 — Build & Deploy / Distributed Systems
📦 204.تفاوت بین Framework-Dependent Deployment و Self-Contained Deployment چیست؟
🎯 205.چگونه یک برنامه NET. را برای یک Runtime مشخص، مانند win-x64 یا linux-x64، Publish میکنید؟
⚙️ 206.چگونه فایلهای appsettings مخصوص هر Environment را در Publish Output پیکربندی میکنید؟
🐳 207.چگونه برای یک برنامه ASP.NET Core یک Dockerfile مینویسید؟
🏗 208.ءMulti-Stage Docker Build چیست و چرا باید از آن استفاده کنید؟
📦 209.چگونه حجم (Size) یک Docker Image را برای برنامههای NET. بهینه میکنید؟
🔐 210.چگونه Environment Variableها و Configuration را به یک Docker Container منتقل میکنید؟
📌 برایفرض کن داریم یک فروشگاه اینترنتی میسازیم وOrderفقط یکStatusداشته باشیم یا بریم سراغState Machine؟ 🤔
Orderمون چندتا وضعیت داره:Pending
Paid
Processing
Shipped
Delivered
Cancelled
خب معلومه دیگه 😎
یک
enum میسازیم:public enum OrderStatus
{
Pending,
Paid,
Processing,
Shipped,
Delivered,
Cancelled
}
بعد داخل
Order:public OrderStatus Status { get; private set; }هرجا هم خواستیم وضعیت رو عوض کنیم:
order.Status = OrderStatus.Paid;
تموم شد رفت. 😎
هم سادهست، هم خواناست، هم Database هم فقط یک ستون
Status داره.ولی یه لحظه صبر کن...
واقعاً هر
Statusای میتونه به هر Status دیگهای تبدیل بشه؟ 🤨مثلاً:
Pending → Paid
Paid → Processing
Processing → Shipped
Shipped → Delivered
اینها منطقی به نظر میرسن.
ولی این چی؟
Delivered → Pending
یا:
Shipped → Paid
یا حتی:
Cancelled → Shipped
احتمالاً نه!
پس مشکل از خود
Status نیست.مشکل اینجاست که اگر فقط یک
enum داشته باشیم، این enum بهتنهایی هیچ چیزی دربارهی قوانین انتقال بین وضعیتها نمیگه.یعنی این کد:
order.Status = OrderStatus.Delivered;
از نظر #C کاملاً معتبره.
ولی از نظر Business ممکنه کاملاً غیرمعتبر باشه.
اینجاست که معمولاً یکی میگه:
«پس قبلش if میذاریم.»
مثلاً:
if (order.Status != OrderStatus.Shipped)
throw new InvalidOperationException();
order.Status = OrderStatus.Delivered;
خب...
بعد یک ماه میشه:
if (status == OrderStatus.Pending)
{
...
}
else if (status == OrderStatus.Paid)
{
...
}
else if (status == OrderStatus.Processing)
{
...
}
بعد یک Requirement جدید میاد:
اگر Payment Failed شد، Order دوباره Payment بشه.
بعد یکی دیگه:
اگر Customer درخواست Cancellation داد، فقط قبل از Shipment اجازه بده.
بعد:
ءAdmin بتونه یک Order رو از حالت Processing به Cancelled ببره، ولی Customer نتونه.و ناگهان...💀 Business Ruleهای مربوط به Lifecycle سفارش پخش شدن توی:
Controller
Service
Handler
Domain
Background Job
...
و هرکس هم یک قانون متفاوت نوشته.
اینجا دقیقاً جاییه که State Machine میتونه ارزش پیدا کنه.
ءState Machine اساساً میگه:
«ءOrder فقط یک Status نداره؛ یک Lifecycle داره و فقط بعضی Transitionها مجاز هستند.»حالا بهجای اینکه هرجای سیستم بنویسیم:
order.Status = OrderStatus.Shipped;
میگیم:
order.Ship();
و خود Domain تصمیم میگیره آیا این Transition مجازه یا نه.
مثلاً:
public void Ship()
{
if (Status != OrderStatus.Processing)
throw new InvalidOperationException(
"Only processing orders can be shipped.");
Status = OrderStatus.Shipped;
}
حالا اگر کسی بگه:
order.Ship();
و Order هنوز
Pending باشه، خود Domain جلوش رو میگیره.این خیلی بهتر از اینه که امیدوار باشیم همهی Callerها قبلش
if درست نوشته باشن. 😏اماااا...
اینجا هم نباید سریع نتیجه بگیریم:
«پس State Machine همیشه بهتره!»
نه.
اگر سیستم ما یک Order خیلی ساده داره:
Pending → Completed
واقعاً لازم نیست برای دو وضعیت یک State Machine عظیم درست کنیم.
پس State Machine قرار نیست صرفاً چون اسمش خفنتره وارد پروژه بشه.
مسئله اینه که:
آیا Lifecycle موجودیت، خودش دارای پیچیدگی Business است؟
اینجا State Machine میتونه خیلی خواناتر و قابلکنترلتر باشه.
حتی میتونی Ruleهایی مثل این داشته باشی:
Customer فقط تا قبل از
Shippedمیتونه Cancellation درخواست کنه.
یا:
ءRefund فقط وقتی مجازه که Payment موفق بوده باشه.
یا:
ءShipment فقط بعد از Payment موفق ایجاد بشه.
اینها دیگه صرفاً
Status نیستن.اینها Business Rules مربوط به Transitionها هستن.
بعضیا فکر میکنن وقتی State Machine داریم، دیگه
Status لازم نیست.نه! State Machine و Status لزوماً رقیب هم نیستن.