سلام 👋
بعد از مدتی غیبت با یک مقاله ی کاربردی اومدم تا با خوندن این مقاله ذهنتون رو برای مصاحبه ی استخدامی System Design آماده کنید و البته اگر توی هر کدوم از موضوعات در خودتون ضعف دانش احساس کردید، حتما با سرچ کردن آن موضوع در سایت سکان آکادمی یا با استفاده از دستیارهای هوش مصنوعی، اون موضوع رو به خوبی یاد بگیرید.
من همیشه دوست دارم برای بهتر آموختن مطالب آنها را دسته بندی کنم، این مقاله هم شامل دسته بندی من از موضوعات مهم در حوزه ی سیستم دیزاین است و البته برای هر موضوع خاص، یک توضیح کوتاه هم آورده ام که میتواند به عنوان یک فهرست از مطالب برای شما مفید و کاربردی باشد.
در انتهای مقاله هم 3 نکته طلایی را گفتم که حتما در زمان مصاحبه رعایت کنید.
Fundamental
Scalability | مقیاسپذیری
در طراحی سیستمهای نرمافزاری، باید بتوانید پاسخگوی افزایش تعداد کاربران و درخواستها باشید. مقیاسپذیری دو نوع دارد:
Vertical Scaling (مقیاسپذیری عمودی): افزایش قدرت سختافزار (CPU، RAM، Disk) برای پردازش بهتر درخواستها در یک سرور.
Horizontal Scaling (مقیاسپذیری افقی): اضافه کردن سرورهای جدید برای تقسیم بار پردازشی بین آنها.
در مصاحبه، از شما انتظار میرود که توضیح دهید کدام روش برای شرایط مختلف مناسبتر است و چه چالشهایی در مقیاسپذیری وجود دارد (مثلاً مقایسه stateful در مقابل stateless بودن سرویسها).
Availability | در دسترس بودن
Availability یعنی سیستم شما چه میزان از زمان بهصورت پایدار و بدون قطعی در دسترس کاربران است. این مقدار معمولاً بهصورت درصدی (مانند 99.9% uptime) بیان میشود.
برای بهبود Availability، باید از روشهایی مانند:
Redundancy (افزونگی): داشتن نسخههای اضافی از سرورها یا دیتابیسها که در صورت خرابی یک بخش، سیستم همچنان فعال بماند.
Fault Tolerance (تحمل خطا): طراحی سیستم بهگونهای که در صورت وقوع خطا، همچنان سرویسدهی را ادامه دهد.
در مصاحبه، ممکن است از شما بخواهند که نحوهی افزایش Availability در طراحی خود را توضیح دهید، مثلاً با استفاده از active-passive یا active-active replication.
Reliability | شاخص اطمینان
Reliability یعنی سیستم شما چقدر میتواند بدون مشکل و مطابق انتظار کار کند. این مفهوم به میزان خرابیها و توانایی سیستم در بازیابی از آنها مربوط است.
برای بهبود Reliability، باید:
Recovery Mechanisms (مکانیزمهای بازیابی) داشته باشید تا در صورت خرابی، سیستم به حالت پایدار بازگردد.
Error Handling (مدیریت خطاها) را بهدرستی انجام دهید تا خرابیها از یک نقطه به کل سیستم گسترش پیدا نکنند.
در مصاحبه، از شما میخواهند که توضیح دهید چگونه از مکانیزمهای مانند circuit breaker یا retry policies برای بهبود Reliability استفاده میکنید.
Performance | عملکرد
Performance به کارایی و سرعت سیستم شما مربوط میشود و دو شاخص اصلی دارد:
Latency (تاخیر): مدت زمانی که طول میکشد تا سیستم به یک درخواست پاسخ دهد.
Throughput (توان عملیاتی): تعداد درخواستهایی که سیستم میتواند در یک بازهی زمانی مشخص پردازش کند.
برای بهبود عملکرد، میتوان از مواردی مانند caching، load balancing، و database indexing استفاده کرد. در مصاحبه، ممکن است از شما بخواهند که توضیح دهید چطور تعادل بین latency و throughput را در یک سیستم واقعی برقرار میکنید.
Consistency درمقابل Availability
طبق CAP Theorem، در سیستمهای توزیعشده، نمیتوان بهطور همزمان Consistency، Availability و Partition Tolerance را بهطور کامل تضمین کرد. بنابراین، هنگام طراحی سیستم، باید بین Consistency و Availability یکی را اولویت قرار دهید.
Consistency (ثبات): همهی نودهای سیستم همیشه دادههای یکسانی را نمایش دهند. (مانند SQL databases و strong consistency models).
Availability (دسترسیپذیری): سیستم همیشه به درخواستها پاسخ دهد، حتی اگر دادههای نمایشدادهشده کمی متفاوت باشند. (مانند NoSQL databases و eventual consistency).
Partition Tolerance (تحمل قطعی شبکه): سیستم حتی در صورت وجود مشکلات در ارتباط بین نودها، همچنان کار کند.
در مصاحبه، باید بتوانید توضیح دهید که سیستم شما چه تصمیمی در برابر CAP Theorem گرفته و چرا. مثلاً در سیستم های بانکی، معمولاً Consistency اولویت دارد، اما در صفحه ی اصلی شبکه های اجتماعی، Availability مهمتر است.
Eventual Consistency
در سیستمهای توزیعشده، Eventual Consistency به این معناست که اگر هیچ بهروزرسانی جدیدی روی دادهها انجام نشود، در نهایت تمام نودها یک مقدار مشابه خواهند داشت. که در مقابل Strong Consistency قرار دارد که تضمین میکند تمام نودها در هر لحظه مقدار یکسانی دارند. در مصاحبه، باید بتوانید توضیح دهید که چه زمانی Eventual Consistency را به Strong Consistency ترجیح میدهید، مثلاً در سیستمهایی مانند DNS که تاخیر کمی در همگامسازی دادهها قابلقبول است.
Latency درمقابل Throughput
Latency زمان پاسخگویی یک درخواست را نشان میدهد، درحالی که Throughput تعداد درخواستهایی است که یک سیستم در واحد زمان پردازش میکند. در مصاحبه، معمولاً از شما خواسته میشود بین کاهش Latency یا افزایش Throughput یکی را انتخاب کنید و دلیل آن را توضیح دهید. دانستن مفاهیمی مانند P99 Latency و Tail Latency میتواند شما را در بحث عمیقتری با مصاحبهکننده قرار دهد.
Building Block
Load Balancing | توازن بار
توازن بار (Load Balancing) یکی از مهمترین مفاهیم در طراحی سیستمهای مقیاسپذیر است. در این روش، ترافیک ورودی بین چندین سرور توزیع میشود تا از فشار بیشازحد روی یک سرور جلوگیری شود، عملکرد (Performance) بهبود یابد و سیستم در صورت خرابی یک سرور همچنان در دسترس (Available) باقی بماند.
در مصاحبه، از شما انتظار دارند که انواع Load Balancer مانند Layer 4 (TCP/UDP-based) و Layer 7 (HTTP/HTTPS-based) را بشناسید و الگوریتمهای رایج مانند Round Robin، Least Connections، IP Hash را توضیح دهید. همچنین، باید بتوانید تفاوت Load Balancer و Reverse Proxy را شرح دهید.
Caching
Caching یکی از روشهای بهینهسازی عملکرد سیستم است که با ذخیره نسخههایی از دادههای پرکاربرد در حافظههای سریعتر مانند RAM یا in-memory stores (مثل Redis) انجام میشود. این کار باعث کاهش بار روی دیتابیس و افزایش سرعت پاسخگویی میشود.
در مصاحبه، باید بتوانید استراتژیهای مختلف Caching را توضیح دهید، از جمله:
LRU (Least Recently Used): دادههایی که مدت زیادی استفاده نشدهاند حذف میشوند.
Write-through: دادهها همزمان در کش و پایگاه داده ذخیره میشوند.
Write-behind: دادهها ابتدا در کش ذخیره شده و سپس در زمان مناسب به دیتابیس نوشته میشوند.
همچنین، باید چالشهایی مانند Cache Invalidation، Cache Stampede و Cache Eviction را درک کنید.
Database Sharding | تقسیم بندی دیتابیس
شاردینگ یک روش برای تقسیم دادههای پایگاه داده به چند بخش کوچکتر است که هرکدام روی سرورهای جداگانه قرار دارند. این کار به بهبود Scalability و Performance کمک میکند.
در مصاحبه، باید انواع Sharding Strategies را بشناسید:
Range-based Sharding: دادهها بر اساس محدودهای از مقادیر تقسیم میشوند.
Hash-based Sharding: هر داده با یک الگوریتم هش به یک شارد اختصاص داده میشود.
Geo-based Sharding: دادهها بر اساس موقعیت جغرافیایی کاربران تقسیم میشوند.
باید توضیح دهید که چرا یک روش را به دیگری ترجیح میدهید و چگونه Shard Rebalancing را مدیریت میکنید.
Replication | تکرار
Replication فرآیند ایجاد نسخههای تکراری از دادهها روی سرورهای مختلف است. این کار معمولاً برای بهبود Availability، Reliability و Performance در خواندن دادهها انجام میشود.
در مصاحبه، باید تفاوت Leader-Follower Replication و Multi-Leader Replication را توضیح دهید، همچنین چالشهایی مانند Replication Lag و Eventual Consistency را درک کنید. مهم است که بتوانید Trade-off بین Consistency و Performance را تحلیل کنید.
Proxies
پروکسیها سرورهای واسطهای هستند که بین کاربران و سرورهای اصلی قرار میگیرند و اهداف مختلفی دارند، مانند:
Load Balancing برای توزیع ترافیک.
Security Filtering برای بررسی درخواستها.
Caching برای کاهش فشار روی سرورهای اصلی.
در مصاحبه، ممکن است تفاوت بین Forward Proxy و Reverse Proxy از شما پرسیده شود. همچنین، باید بدانید که ابزارهایی مانند NGINX، HAProxy و Envoy چگونه در معماری شما به کار میروند.
CDNs | شبکه های توزیع محتوا
CDNها شبکههایی از سرورهای پراکنده در نقاط مختلف جغرافیایی هستند که محتوا را به کاربران از نزدیکترین سرور ارائه میدهند. استفاده از CDN باعث:
- کاهش زمان بارگذاری صفحات (با سرو کردن محتوا از نزدیکترین موقعیت جغرافیایی).
- کاهش هزینههای پهنای باند (با کاهش درخواستهای مستقیم به سرور اصلی).
- افزایش Availability (چون درخواستها بین سرورهای مختلف تقسیم میشوند).
در مصاحبه، باید توضیح دهید چگونه CDNهایی مانند CDN آروان که نمونه ایرانی قابل استفاده برای ما هست یا نمونه های خارجی مثل Cloudflare، AWS CloudFront و Akamai میتوانند عملکرد و پایداری یک سیستم را بهبود بخشند. همچنین، باید چالشهایی مانند Cache Purging و Dynamic Content Handling را در نظر بگیرید.
Database
SQL vs. NoSQL | مقایسه پایگاه دادههای رابطهای و غیررابطهای
انتخاب بین SQL و NoSQL بستگی به نیازهای پروژه شما دارد.
SQL Databases (مانند MySQL، PostgreSQL، SQL Server):
- ACID-compliant: برای سیستمهایی که به Consistency و Data Integrity بالا نیاز دارند (مثل سیستمهای مالی).
- Schema-based: مناسب برای دادههای ساختاریافته و روابط پیچیده.
- Vertical Scalability: معمولاً از طریق افزایش توان سختافزاری مقیاسپذیر میشوند.
NoSQL Databases (مانند MongoDB، Cassandra، DynamoDB):
- BASE-compliant: مناسب برای مقیاسپذیری بالا و در دسترس بودن (مثلاً شبکههای اجتماعی).
- Flexible Schema: امکان ذخیره دادههای نیمه ساختار یافته و بدون ساختار.
- Horizontal Scalability: مناسب برای سیستمهای توزیعشده با حجم بالای داده.
📌 نکته مهم: بسیاری از سیستمهای بزرگ Hybrid Databases دارند و از هر دو نوع در بخشهای مختلف استفاده میکنند.
مقایسه بین ACID و BASE | الگوهای نگهداری دادهها
اینکه پایگاه داده شما باید Strongly Consistency (ACID) یا Eventual Consistency (BASE) داشته باشد، یک تصمیم کلیدی در طراحی سیستم است.
ACID (Atomicity, Consistency, Isolation, Durability):
مناسب برای تراکنشهای مالی، حسابداری، و دادههای حساس.
معایب: کاهش Scalability و افزایش Latency به دلیل نیاز به هماهنگی قوی.
BASE (Basically Available, Soft State, Eventually Consistent):
مناسب برای سیستمهایی مانند موتورهای جستجو، شبکههای اجتماعی، و سیستمهای توصیهگر (Recommendation Systems).
معایب: ممکن است Data Inconsistency موقتی رخ دهد، اما Performance بالاتر است.
سوالی که احتمال دارد مصاحبه کننده از شما در این موضوع بپرسد چیزی شبیه به این خواهد بود که در چه شرایطی حاضر هستید از ACID به BASE مهاجرت کنید؟
Database Indexing
Indexing باعث بهبود سرعت جستجوها در دیتابیس میشود اما فضای ذخیرهسازی بیشتری مصرف میکند.
روشهای Indexing:
B-tree Indexing: برای جستجوهای Range-based (مثلاً نامهایی که با "A" شروع میشوند).
Hash Indexing: برای جستجوهای دقیق (مثلاً جستجوی کلید اولیه).
Bitmap Indexing: برای دادههایی با مقدار کم اما تکرار زیاد (مثلاً جنسیت کاربر).
چالش این بخش در مصاحبه سوالی این چنینی است که آیا اضافه کردن Index همیشه عملکرد را بهبود میبخشد؟ که جواب دقیق آن خیر هست. زیرا برای عملیات نوشتن سنگین، داشتن ایندکس زیاد باعث کاهش Performance میشود.
Denormalization
Normalization برای کاهش افزونگی داده و جلوگیری از ناهماهنگی اطلاعات استفاده میشود.
Denormalization زمانی استفاده میشود که خواندن سریعتر از نوشتن مهمتر باشد (مثلاً در سیستمهای گزارشگیری).
مثال: در یک سیستم تحلیل داده، بهجای انجام JOINهای سنگین در هر درخواست، دادههای مرتبط را در یک جدول تکرار میکنیم تا سرعت خواندن بالا برود.
سوال مصاحبه ی شما و البته نقطه ی تصمیم گیری مهم تان در دیزاین سیستم این است که آیا Denormalization همیشه انتخاب خوبی است؟ که جواب این سوال خیر هست! زیرا افزایش دنرمالسازی باعث افزایش هزینههای Storage و مدیریت دادههای ناسازگار میشود.
Data Partitioning Strategies
تقسیمبندی دادهها (Partitioning) کمک میکند که مقیاسپذیری و Performance بهبود یابد.
روشهای Partitioning:
Horizontal Partitioning (Sharding): ردیفهای جدول را در سرورهای مختلف ذخیره میکند.
مثال: تقسیم کاربران بر اساس شناسه عددی (User ID Mod 10) در 10 سرور مختلف.
Vertical Partitioning: ستونهای جدول را بین سرورها تقسیم میکند.
مثال: اطلاعات کاربری حساس (مانند رمز عبور) روی یک سرور جداگانه ذخیره شود.
در مصاحبه نیاز دارید به این سوال پاسخ مناسبی بدهید که چگونه Rebalancing و Repartitioning را در صورت افزایش حجم دادهها مدیریت میکنید؟
Materialized Views
Materialized Views یک روش برای ذخیره نتایج یک Query بهصورت پیش محاسبه شده است تا اجرای کوئری های سنگین سریع تر انجام شود. این روش در سیستم هایی که داده ها بهندرت تغییر میکنند ولی نیاز به پاسخ سریع دارند (مانند داشبوردهای آنالیتیکس) بسیار مفید است. در مصاحبه، باید بدانید که چگونه آن را بهروزرسانی کنید (Refresh Strategies) و چه زمانی استفاده از آن بهینه است.
Multi-master درمقابل Single-master Replication
در Single-master Replication، تنها یک master وجود دارد که عملیات write را انجام میدهد و سایر replica ها فقط برای read استفاده میشوند، درحالیکه در Multi-master Replication، چندین نود میتوانند عملیات نوشتن را انجام دهند. این موضوع تأثیر زیادی بر conflict resolution و consistency model دارد و در مصاحبه باید بدانید که کدام روش برای چه سناریویی مناسب است.
Change Data Capture (CDC)
CDC یک تکنیک برای مانیتور کردن و ثبت تغییرات در دادههای یک دیتابیس است، که معمولاً برای real-time data sync بین سیستمها استفاده میشود. ابزارهایی مانند Debezium و Kafka Connect برای پیادهسازی CDC به کار میروند. دانستن تفاوت بین log-based و trigger-based CDC میتواند در مصاحبه به شما کمک کند.
Distributed Systems
Consensus Algorithms | الگوریتم های توافق
در سیستمهای توزیعشده، چالش بزرگی که وجود دارد این است که چندین نود باید با یکدیگر اطلاعات را به اشتراک بگذارند و تصمیمات مشترک بگیرند. این کار به دلیل عواملی مانند خرابی نودها، تأخیر شبکه، و ناپایداریها، پیچیده میشود. بنابراین، الگوریتمهای توافق برای اطمینان از اینکه تمامی نودها به یک نتیجه مشترک برسند، طراحی میشوند. دو الگوریتم معروف در این زمینه عبارتند از Paxos و Raft. این الگوریتمها به سیستم کمک میکنند تا حتی اگر برخی نودها دچار خرابی شوند یا با تأخیرهایی مواجه باشند، دادهها همچنان همزمان و هماهنگ باقی بمانند.
هنگام بحث در مورد الگوریتمهای توافق در مصاحبه، مهم است که بدانید چه زمانی این الگوریتمها استفاده میشوند و مزایای هرکدام چیست. مثلاً، Raft معمولاً سادهتر از Paxos است و برای درک بهتر و پیادهسازی راحتتر پیشنهاد میشود، در حالی که Paxos عملکرد بهتری در برخی سیستمها دارد که به مقیاسپذیری و تحمل خطاهای زیاد نیاز دارند. حتماً به تفاوتها و کاربردهای خاص هرکدام اشاره کنید.
Leader Election | انتخاب رهبر
در سیستمهای توزیعشده، معمولاً یکی از نودها باید بهعنوان رهبر یا هماهنگکننده شناخته شود. این نود مسئول مدیریت هماهنگی بین نودها، تصمیمگیری و نگهداری وضعیت سیستم است. انتخاب رهبر در این سیستمها مهم است زیرا باعث جلوگیری از تضادها و ناهماهنگیها میشود. انتخاب رهبر معمولاً از طریق الگوریتمهایی مانند Bully یا Ring انجام میشود.
در مصاحبه، باید بدانید که انتخاب رهبر در یک سیستم توزیعشده به شدت روی عملکرد سیستم تأثیر میگذارد. اگر الگوریتمهای انتخاب رهبر به درستی انتخاب نشوند، میتوانند باعث کاهش کارایی یا ایجاد مشکلات هماهنگی در سیستم شوند. برای مثال، الگوریتم Bully مناسب برای سیستمهایی است که تعداد نودها کم است، در حالی که Ring میتواند در مقیاسهای بزرگتر کارایی بهتری داشته باشد.
Distributed File Systems
سیستمهای فایل توزیعشده برای ذخیرهسازی و مدیریت دادهها در چندین نود طراحی شدهاند. هدف این است که کاربران بتوانند به دادهها دسترسی داشته باشند و مطمئن شوند که همه نودها نسخه یکسانی از دادهها دارند. این نوع سیستمها معمولاً شامل ویژگیهایی برای مدیریت نام فایلها و نسخههای مختلف دادهها بهطور همزمان هستند. از جمله معروفترین این سیستمها میتوان به HDFS (Hadoop Distributed File System) و Google File System اشاره کرد.
سیستمهای فایل توزیعشده میتوانند در مقیاسهای بزرگ باعث بهبود دسترسی و مقیاسپذیری شوند. باید درک خوبی از مزایای این سیستمها و چالشهایی که دارند مانند همگامسازی دادهها، مدیریت نام فایلها، و ایجاد نسخههای پشتیبان داشته باشید. مثلاً HDFS بیشتر برای پردازشهای توزیعشده در دادههای حجیم مناسب است.
Distributed Caching
در سیستمهای توزیعشده، کش توزیعشده برای ذخیرهسازی دادهها در چندین نود استفاده میشود تا سرعت دسترسی به اطلاعات بهبود یابد. این روش به ویژه در برنامههایی که بهشدت وابسته به دادهها هستند، مانند برنامههای وب و موبایل، مفید است. اما چالشهایی مانند همگامسازی دادههای کششده با دادههای اصلی و توزیع بار بهطور متوازن میان نودها باید در نظر گرفته شوند. ابزارهایی مانند Redis و Memcached در این زمینه کمک زیادی به پیادهسازی کش توزیعشده میکنند.
در مصاحبه، توضیح دهید که کش توزیعشده میتواند بهطور چشمگیری سرعت سیستم را افزایش دهد، اما مشکلات همگامسازی و تقسیم بار را هم به همراه دارد. بهویژه هنگام کار با Redis یا Memcached، باید درک خوبی از نحوه مدیریت کش، ذخیرهسازی دادهها و ضمانت دادن به صحت اطلاعات داشته باشید. در مقیاسهای بزرگ، این موضوع بسیار حیاتی است.
Service Discovery
در سیستمهای توزیعشده، کشف سرویسها فرآیندی است که به سرویسها کمک میکند تا یکدیگر را شناسایی و ارتباط برقرار کنند. این فرآیند معمولاً از طریق یک رجیستری مرکزی یا با استفاده از DNS انجام میشود. روشهای مختلفی مانند Centralized Registry یا DNS-based Solutions وجود دارد که به سیستمهای توزیعشده اجازه میدهند که بهطور خودکار سرویسها را شناسایی کنند و از آنها استفاده کنند.
Microservices Architecture
این معماری به توسعهدهندگان امکان میدهد تا برنامهها را به مجموعهای از سرویسهای کوچک و مستقل تقسیم کنند که هر کدام وظایف خاصی را انجام میدهند. برخی از معماری های اصلی که باید در این حوزه یاد بگیرید و بتوانید در مصاحبه دلیل انتخاب یکی و مزایا و معایب آن نسبت به بقیه را براساس سیستمی که از شما خواسته اند Design کنید را بگویید عبارتند از:
- Event-Driven Architecture: در این نوع معماری، میکروسرویسها به صورت مستقل عمل میکنند و تغییرات یا رویدادها را از دیگر سرویسها دریافت میکنند.
- API Gateway Architecture: در این معماری، یک Gateway به عنوان نقطه ورود اصلی برای تمام درخواستها عمل میکند و آنها را به سرویسهای مربوطه هدایت میکند.
- Service Mesh: این معماری به طور خاص برای مدیریت ارتباطات بین میکروسرویسها طراحی شده است و امکان نظارت، بررسی های امنیتی و مقیاسپذیری را فراهم میکند.
- CQRS (Command Query Responsibility Segregation): این نوع معماری Command ها و Query ها را از یکدیگر جدا میکند. CQRS خواندن و نوشتن را در دو مسیر جداگانه پردازش میکند تا مقیاسپذیری بهبود یابد. معمولاً در کنار Event Sourcing استفاده میشود.
- Microservices with Database per Service: در این معماری، هر میکروسرویس پایگاه داده خود را دارد.
- Backend for Frontend (BFF): این نوع معماری کارایی بهتری را برای برنامههای مختلف (وب، موبایل و ...) فراهم میکند.
معماران میکروسرویسها معمولاً از ابزارهایی مانند Docker و Kubernetes برای مدیریت این سرویسها استفاده میکنند.
Event Sourcing
در Event Sourcing، بهجای ذخیرهی وضعیت نهایی دادهها، تمام تغییرات بهصورت یک دنباله از events ذخیره میشوند. این روش امکان auditability و time travel را فراهم میکند. در مصاحبه، باید بتوانید توضیح دهید که چگونه event replay میتواند برای system recovery استفاده شود.
Saga Pattern
Saga Pattern برای مدیریت distributed transactions استفاده میشود، بهخصوص در معماری microservices که two-phase commit امکانپذیر نیست. این الگو از یک سری compensating transactions برای جبران شکست یک مرحله استفاده میکند. مصاحبهکنندگان ممکن است از شما بپرسند که چطور این الگو را با orchestration (مانند workflow engines مثل Camunda) یا choreography پیادهسازی میکنید.
Gossip Protocols
این پروتکلها برای پخش اطلاعات بین نودها در یک distributed system استفاده میشوند و در سرویسهایی مانند service discovery و failure detection کاربرد دارند. در مصاحبه، اگر در مورد peer-to-peer networks صحبت شود، دانستن این پروتکل میتواند امتیاز مثبتی باشد.
Service Mesh
Service Mesh مانند Istio و Linkerd لایهای است که ارتباط بین microservices را مدیریت میکند. مصاحبهکنندگان معمولاً از شما میخواهند تفاوت آن را با API Gateway توضیح دهید.
Communication Protocols | پروتکل های ارتباطی
HTTP/HTTPS
HTTP (Hypertext Transfer Protocol) پروتکلی است که برای انتقال دادهها در وب استفاده میشود. HTTPS (HTTP Secure) نسخه امن آن است که از رمزنگاری TLS/SSL برای حفاظت از دادهها در هنگام انتقال استفاده میکند.
Methodهای مختلف برای ارسال Request به شرح زیر است:
GET: برای درخواست دادهها از سرور.
POST: برای ارسال دادهها به سرور (مانند فرمهای وب).
PUT: برای بهروزرسانی یک منبع موجود.
DELETE: برای حذف یک منبع.
WebSockets
WebSockets یک پروتکل ارتباطی است که ارتباط دوطرفه و دائمی بین کلاینت و سرور برقرار میکند. برخلاف HTTP، WebSockets یک اتصال پایدار ایجاد میکند و این اتصال تا زمانی که نیاز باشد، برقرار میماند. این پروتکل بهویژه برای برنامههایی که نیاز به دادههای بلادرنگ دارند، مانند چتها، بازیهای آنلاین و اپلیکیشنهای اطلاعرسانی فوری، مفید است.
هنگام طراحی سیستمهای مقیاسپذیر با WebSockets، به چالشهایی مانند مدیریت اتصالهای فعال زیاد و توزیع بار بین سرورها توجه کنید.
WebSockets برای سیستمهایی که به تبادل اطلاعات بلادرنگ نیاز دارند، بهترین انتخاب است. در این مواقع WebSockets بر HTTP ارجحیت دارد، زیرا نیازی به ایجاد یک ارتباط جدید برای هر درخواست ندارد.
gRPC
gRPC یک فریمورک RPC (Remote Procedure Call) است که توسط Google توسعه یافته و برای برقراری ارتباط بین سرویسها استفاده میشود. این پروتکل از Protocol Buffers برای سریالیزیشن دادهها استفاده میکند که سرعت بالاتر و فشردهسازی بهتری نسبت به JSON دارد. gRPC برای ارتباط بین سرویسها در معماری میکروسرویسها بسیار مناسب است.
در مصاحبه، هنگام توضیح در مورد gRPC باید به این نکته اشاره کنید که gRPC برای ارتباط میان سرویسها با زبانها و پلتفرمهای مختلف بسیار کارآمد است.
gRPC معمولاً نسبت به REST و JSON از نظر سرعت و کارایی بهتر است و این نکته در مقیاسپذیری سیستمهای بزرگ اهمیت دارد.
باید تفاوتهای کلیدی مثل synchronous و asynchronous بودن gRPC را با سایر پروتکلها مانند REST توضیح دهید.
مقایسه بین REST و GraphQL
REST (Representational State Transfer) یک معماری برای طراحی سرویسهای وب است که از HTTP برای تعامل با سرورها استفاده میکند. در REST، هر درخواست معمولاً یک URL خاص دارد و منابع به صورت مستقل از هم دسترسی پیدا میکنند. این معماری به دلیل سادگی و مقیاسپذیری بالا در بسیاری از سیستمهای بزرگ استفاده میشود، اما ممکن است برای دریافت دادههای پیچیده نیاز به چندین درخواست باشد.
GraphQL یک زبان پرس و جو برای API است که به کلاینتها این امکان را میدهد که به طور دقیق مشخص کنند که چه دادههایی نیاز دارند. در مقابل REST که ممکن است نیاز به چندین درخواست برای دریافت دادههای مختلف باشد، با GraphQL میتوان تمام دادهها را در یک درخواست دریافت کرد. این ویژگی به کاهش ترافیک شبکه کمک میکند، ولی پیچیدگی بیشتری در طراحی API به همراه دارد.
در هنگام طراحی سیستم با REST یا GraphQL باید مزایا و معایب هرکدام را بر اساس نیازهای خاص سیستم مطرح کنید.برای سیستمهایی که نیاز به مقیاسپذیری و ساده بودن API دارند، REST ممکن است مناسبتر باشد، در حالی که برای سیستمهایی که نیاز به درخواستهای دقیقتر و کمتری از دادهها دارند، GraphQL مناسبتر است.
یکی از تفاوتهای اصلی بین REST و GraphQL این است که در GraphQL کلاینتها میتوانند دادهها را دقیقاً به شکل مورد نیاز خود درخواست کنند.
Pub/Sub Model
مدل Publish/Subscribe یک الگوی ارتباطی است که در آن Publishers (تولیدکنندگان پیام) پیامها را ارسال میکنند و Subscribers (دریافتکنندگان پیام) آنها را دریافت میکنند. در این مدل، تولیدکنندگان و دریافتکنندگان هیچ اطلاعات مستقیمی از هم ندارند. این مدل به ویژه در سیستمهایی که نیاز به انتشار و دریافت پیامها به صورت غیر همزمان دارند، بسیار مفید است، مثل سیستمهای اطلاعرسانی، نظارت و یا پردازشهای توزیعشده.
در سیستمهای بزرگ که نیاز به ارسال پیام به تعداد زیادی از کاربران یا سیستمها دارند، مدل Pub/Sub میتواند به خوبی مقیاسپذیر باشد.
هنگام طراحی سیستمهایی با Pub/Sub باید به موضوعاتی مانند message broker و delivery guarantees توجه کنید.
Pub/Sub به شما این امکان را میدهد که سیستمهایی را طراحی کنید که نیاز به ارتباط مستقیم بین تولیدکنندگان و دریافتکنندگان ندارند و به راحتی میتوانند مقیاسپذیر شوند.
Message Queues (Kafka, RabbitMQ, SQS)
سیستمهای Message Queue برای مدیریت ارتباطات ناهمگام استفاده میشوند. دانستن تفاوت بین pull-based (مانند Kafka) و push-based (مانند RabbitMQ) در مصاحبه ضروری است.
Long Polling
یک تکنیک برای پیادهسازی ارتباطات real-time در HTTP است که در نبود WebSockets کاربرد دارد. دانستن تفاوت آن با Server-Sent Events (SSE) و WebSockets میتواند در مصاحبه کمک کند.
System Design Patterns
Circuit Breaker
الگوی Circuit Breaker برای جلوگیری از خرابیهای زنجیرهای طراحی شده است. این الگو به یک سیستم کمک میکند که در صورت مشاهده تعداد زیادی خطا در یک سرویس، آن سرویس را از دسترس خارج کند و به کاربر اخطار دهد. این الگو سه حالت اصلی دارد: CLOSED (بسته) که درخواستها به سرویس فرستاده میشوند، OPEN (باز) که درخواستها متوقف میشوند و HALF-OPEN (نیمه باز) که چند درخواست محدود برای آزمایش سرویس به کار میروند.
Back Pressure
الگوی Back Pressure به تکنیکهایی اشاره دارد که کمک میکند اجزای مختلف سیستم با نرخ ورودی دادهها همگام باشند و از بار زیاد سیستم جلوگیری کنند. Back Pressure به اجزای مختلف سیستم کمک میکند تا با توجه به ظرفیت خود عمل کنند و بار اضافی را پس بزنند.
Bulkhead Pattern
الگوی Bulkhead به تفکیک اجزای سیستم و جلوگیری از انتقال خرابیها از یک بخش به بخش دیگر اشاره دارد. عملکرد Bulkhead اینگونه است که اجزا به صورت جداگانه مدیریت میشوند تا اگر یکی از آنها دچار مشکل شود، سایر اجزاء تحت تأثیر قرار نگیرند.
Retry with Exponential Backoff
این الگو به طور خودکار اقدام به تکرار عملیاتهایی که شکست خوردهاند میکند و زمان بین تلاشها به طور تصاعدی افزایش مییابد تا بار اضافه به سرویس های دیگر منتقل نکند. عملکرد این الگو هم به اینگونه است که زمان منتظر ماندن بین تلاشها به شکل تصاعدی (مثلاً ۱ ثانیه، ۲ ثانیه، ۴ ثانیه و ...) افزایش مییابد تا بار روی سرویس کاهش یابد.
Rate Limiting
الگوی Rate Limiting به کنترل تعداد درخواستهایی که یک کلاینت میتواند در یک بازه زمانی مشخص انجام دهد، اشاره دارد تا از بار زیاد بر روی سرویسها جلوگیری کند. این الگو معمولاً با استفاده از شمارش درخواستها در یک بازه زمانی مشخص کار میکند و در صورت تجاوز از حد مجاز، درخواستهای اضافی را رد میکند.
پیادهسازیهایی مانند Token Bucket و Leaky Bucket در مصاحبههای طراحی سیستم معمولاً مطرح میشوند.
Idempotency
در سیستمهای توزیعشده، درخواستهای تکراری ممکن است ناخواسته دوباره ارسال شوند. Idempotency تضمین میکند که حتی اگر یک عملیات چندین بار اجرا شود، نتیجه یکسان خواهد ماند. در مصاحبه، دانستن روشهای پیادهسازی مانند idempotency keys میتواند مفید باشد.
Strangler Pattern
این الگو برای مهاجرت از legacy systems استفاده میشود. در مصاحبه، دانستن این که چگونه میتوان آن را برای جایگزینی یک monolith با microservices به کار برد، اهمیت دارد.
ملاحظات عملی در طراحی و مدیریت سیستمها
Monitoring and Alerting
مانیتورینگ و آلرتینگ بخش حیاتی طراحی سیستمهای توزیعشده است که برای دنبال کردن عملکرد و سلامت اپلیکیشنها و سرویس ها استفاده میشود. برای پیادهسازی این فرآیند، باید متریکهای کلیدی مانند زمان پاسخدهی، بار سرور و نرخ خطا را در نظر بگیرید. ابزارهایی مانند Prometheus و Grafana برای جمعآوری و تجزیه و تحلیل دادههای نظارتی استفاده میشوند و میتوانند هشدارهایی را در مواقع بروز مشکلات ارسال کنند. همچنین، ELK Stack (Elasticsearch, Logstash, Kibana) به جمعآوری و تجزیه و تحلیل لاگها و متریکهای سیستم کمک میکند.
Logging and Tracing
Logging و Tracing به شما کمک میکند تا اتفاقات سیستم و مسیرهای درخواست را برای دیباگ و تحلیل عملکرد تشخیص و ذخیره کنید. برای این منظور، باید از ساختارهای لاگ مناسب و جزئیات کافی استفاده کنید تا بتوانید در صورت بروز مشکل، به راحتی مکان و علت خطا را شناسایی کنید. ابزارهایی مانند Logstash و Fluentd برای جمعآوری و پردازش لاگها و ابزارهایی مانند Jaeger و Zipkin برای پیادهسازی tracing توزیعشده در نظر گرفته میشوند.
Capacity Planning
برنامهریزی ظرفیت یک فرآیند مهم برای تعیین نیازهای آینده منابع است که شامل تجزیه و تحلیل دادههای تاریخی و پیشبینی روند تقاضا میشود. این اطلاعات باید برای مقیاسگذاری مناسب و اجتناب از کمبود منابع در سیستم مورد استفاده قرار گیرد. برای این منظور، Kubernetes Horizontal Pod Autoscaler میتواند در پیشبینی و مدیریت ظرفیت به کار گرفته شود. ولی در زمان مصاحبه شما نیاز دارید با سوالهای دقیقی از مصاحبه کننده اطلاعاتی بدست بیاورید که چه میزان منابع اولیه باید به سیستم اختصاص بدهید و با توجه به چشم انداز سیستم چه کارهایی باید انجام بدهید تا در شرایط مقتضی بتوانید سرویس هایتان را Scale کنید.
Cost Optimization
بهینهسازی هزینه به معنای تعادل بین نیازهای فنی و محدودیتهای مالی است. در طراحی سیستم، باید به استفاده بهینه از منابع و انتخاب خدمات با هزینه پایینتر توجه داشته باشید تا از صرف هزینههای اضافی جلوگیری شود. میتوانید از خدمات containerization مانند Docker برای کاهش هزینههای زیرساخت استفاده کنید.
دقت داشته باشید که یکی از اهداف از این بخش Cost Optimization و بخش Capacity Planning در مصاحبه های System Design تفکر مدیریتی شما و بررسی میزان Over Engineering فکر کردن شماست.
Security
امنیت به حفاظت سیستمها از دسترسیهای غیرمجاز و تهدیدات مختلف اشاره دارد که باید در تمام مراحل طراحی لحاظ شود. برای حفظ امنیت باید از اصولی مانند احراز هویت، مجوزدهی و رمزنگاری استفاده شود. ابزارهایی مانند OAuth و OpenID Connect برای مدیریت احراز هویت و Let’s Encrypt برای رمزنگاری (SSL/TLS) مفید هستند. همچنین، استفاده از firewallها و ابزارهای امنیتی مانند Intrusion Detection Systems (IDS) میتواند به حفاظت بیشتر کمک کند.
Feature Flags و Canary Releases
Feature Flags برای فعال یا غیرفعال کردن ویژگیها بدون نیاز به دیپلوی مجدد استفاده میشود. Canary Releases هم به شما امکان میدهد نسخهی جدید یک سرویس را ابتدا برای درصد کمی از کاربران منتشر کنید تا از صحت عملکرد آن مطمئن شوید.
Blue-Green Deployment & Rolling Updates
این تکنیکها برای دیپلوی بدون downtime استفاده میشوند. دانستن تفاوت آنها و چگونگی ترکیبشان با feature flags میتواند در مصاحبه مورد توجه قرار گیرد.
Failure Injection Testing (Chaos Engineering)
این روش برای بررسی میزان تحمل خطای سیستم به کار میرود. ابزارهایی مانند Chaos Monkey به شما امکان میدهند که خطاهای تصادفی در سیستم ایجاد کنید تا مقاومت آن را بسنجید.
Zero Downtime Deployment Strategies
در سیستمهای با مقیاس بالا، پیادهسازی دیپلوی بدون قطعی (مانند canary deployment و blue-green deployment) ضروری است.
دقت کنید که مسئله های سیستم دیزاین در مصاحبه های شغلی یک از بخش های بسیار مهم است که قصد مصاحبه کننده بررسی همه جانبه ی دانش شماست.
📌 نکته طلایی 1: ابتدای جلسه را به شفاف کردن نیازمندی مطرح شده و هم صحفه (Same Page) شدن خودتان و مصاحبه کننده روی موضوع سوال صرف کنید.
📌 نکته طلایی 2: برای اینکار هرچقدر که میتوانید سوالاتی مطرح کنید که به شما در انتخاب گزینه مناسب از بین موارد و ابزارهای مطرح شده در بالا کمک کند. اصلا احساس منفی نسبت به مطرح کردن سوالات بیشتر نداشته باشید.
📌 نکته طلایی 3: سپس سعی کنید این موضوعات را یکی بعد از دیگری مطرح کنید و درباره ی هرکدام یک راه حل بدهید. قرار نیست سیستمی که شما در جلسه ی مصاحبه طراحی میکنید را پیاده سازی کنند پس صرفا سعی کنید برای هر کدام از این موارد سطح و گستره دانش تان را بروز دهید و در فضای مسئله ی مطرح شده برای هر کدام راه حل و گزینه ای ارائه بدهید.
امیدوارم این مقاله بهتون کمک کند تا در مصاحبه تان بدرخشید.