System design ინტერვიუები აშინებს დეველოპერების უმეტესობას, რადგან პრობლემა შეუზღუდავია. „დააპროექტე Twitter”. „დააპროექტე URL-shortener”. „დააპროექტე distributed cache”. საიდან დავიწყოთ?
100+ ტექნიკური ინტერვიუს ჩატარებისა და FAANG/MAANG-ისთვის ინჟინრების მენტორობის შემდეგ პროცესი გამეორებად ფრეიმვორკში დავიყვანე. აი ის.
6-საფეხურიანი ფრეიმვორკი
ნაბიჯი 1: დააზუსტეთ მოთხოვნები (5 წუთი)
არასოდეს დაიწყოთ დიზაინი ამ კითხვების გარეშე:
- მასშტაბი: რამდენი მომხმარებელი? Read-heavy თუ write-heavy? მოსალოდნელი QPS?
- Consistency vs availability: ნორმალურია ცოტა ძველი მონაცემების მიწოდება? შეიძლება დავკარგოთ write?
- გეოგრაფია: ერთი რეგიონი თუ გლობალური?
- SLA: რა latency-ია მისაღები? Uptime მოთხოვნა?
კანდიდატების უმეტესობა ამას გამოტოვებს და კვადრატებს იწყებს. ინტერვიუერები ხედავენ. Senior ჯერ კითხვებს სვამს.
ნაბიჯი 2: განსაზღვრეთ API კონტრაქტი
ნებისმიერ ინფრასტრუქტურამდე — რას გასცემს სისტემა გარეთ:
POST /urls
Body: { "long_url": "https://example.com/very-long-path" }
Response: { "short_code": "abc123", "short_url": "https://short.ly/abc123" }
GET /{short_code}
Response: 301 Redirect to long_url
ეს გაიძულებთ იფიქროთ მომხმარებლის კონტრაქტზე იმპლემენტაციის დეტალებამდე.
ნაბიჯი 3: შეაფასეთ მასშტაბი (back-of-envelope)
ხმამაღლა ითვალეთ:
- „100M URL დღეში = ~1 200 write/წმ”
- „read/write 10:1 = 12 000 read/წმ”
- „საშუალო URL ~500 byte, 100M/დღე × 365 × 500 = ~18ТБ/წელი”
ზუსტი რიცხვები არ გჭირდებათ. გჭირდებათ აჩვენოთ, რომ სიდიდის რიგებში ფიქრობთ.
ნაბიჯი 4: დააპროექტეთ data model
SQL vs NoSQL — თითქმის ყოველთვის პირველი რეალური გადაწყვეტილება:
| ფაქტორი | SQL-ის სასარგებლოდ | NoSQL-ის სასარგებლოდ |
|---|---|---|
| Strong consistency საჭიროა | ✅ | ❌ |
| რთული join-ები / ანგარიშები | ✅ | ❌ |
| ჰორიზონტალური მასშტაბი 100M+ | რთული | ✅ |
| Schema სტაბილური | ✅ | ნებისმიერი |
| Access pattern — key-value | ნებისმიერი | ✅ |
URL-shortener-ისთვის მარტივი key-value (Redis ან DynamoDB) lookup-ისთვის სწორი არჩევანია. მეტამონაცემები (შექმნის დრო, click ანალიტიკა) — PostgreSQL-ში.
ნაბიჯი 5: სისტემის კომპონენტები
დახაზეთ კვადრატები და ახსენით თითოეული:
Client → CDN/Load Balancer → API Servers (stateless)
→ Redis (short_code → long_url cache)
→ PostgreSQL (მეტამონაცემები, ანალიტიკა)
შემდეგ რთული:
- short_code-ის გენერაცია: Base62 auto-increment ID-დან, ან hash + collision handling
- Cache invalidation: TTL Redis ჩანაწერებზე, write-through შექმნისას
- Rate limiting: per-IP, token bucket ალგორითმი
ნაბიჯი 6: Bottlenecks და trade-offs
აქ senior mid-ისგან გამოირჩევა. პროაქტიულად განიხილეთ:
- Single points of failure: „DB არის SPOF; დავამატოთ read-replicas და primary failover”
- ცხელი partitions: „თუ short URL ვირუსულია, ერთი Redis node იტვირთება; consistent hashing ანაწილებს”
- ღირებულება vs წარმადობა: „CDN cache 90% origin hit-ს ზოგავს, მაგრამ ამატებს stale redirect-ის რისკს წაშლილი URL-ებისთვის”
რას აფასებენ ინტერვიუერები რეალურად
- კომუნიკაცია: შეგიძლიათ თქვენი ფიქრი ხმამაღლა ახსნათ?
- სისტემური დეკომპოზიცია: ანაწილებთ პრობლემას ნაწილებად?
- Trade-off awareness: ხედავთ, რომ სრულყოფილი პასუხი არ არსებობს?
- Production-mindset: ფიქრობთ failure modes-ზე, არა მხოლოდ happy path-ზე?
არ ამოწმებენ, ხსოვს თუ არა არქიტექტურული დიაგრამები. ამოწმებენ, როგორ ფიქრობთ.
ერთადერთი პრაქტიკული სავარჯიშო, რომელიც მუშაობს
აიღეთ ნებისმიერი აპი, რომელსაც ყოველდღე იყენებთ (Slack, Netflix, თქვენი ბანკის მობილური). 20 წუთის განმავლობაში ქაღალდზე ჩაატარეთ:
- რა ძირითადი არსებები?
- რა read/write თანაფარდობა?
- სად არის bottlenecks?
- როგორ მასშტაბირდება 10x ამჟამინდელ დატვირთვაზე?
გააკეთეთ ეს 20-ჯერ. თეთრი დაფა შიშის გარეშე.
System design აზროვნებას განვიხილავთ კურსში Backend Architecture Foundations — სადაც გასწავლით senior-ად ფიქრს, სანამ senior გახდებით.