Hız Sınırlayıcı ve Twitter Akışı Tasarlama
Çerçeveyi iki temel tasarım problemine uygulayın: belirteç kovası/kayan pencere hız sınırlama ve yazma sırasında çoğaltma ile okuma sırasında çoğaltma yaklaşımlarından biriyle haber akışı oluşturma.
Hız Sınırlayıcı ve Twitter Akışı Tasarlama, CoddyKit'te ücretsiz bir Coding Interview Prep dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Coding Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Coding Interview Prep kursu toplamda 4 dersten oluşur.
Hız Sınırlama Neden Gereklidir
Hız sınırlama, bir istemcinin belirli bir süre penceresinde bir uygulama programlama arayüzüne gönderebileceği istek sayısını denetler. Bu sınırlama olmadan, tek bir sorunlu istemci (veya hizmet engelleme saldırısı) sunucu kaynaklarını tüketerek tüm kullanıcılar için hizmet kalitesini düşürebilir. Hız sınırlama ayrıca kaba kuvvet saldırılarına karşı koruma sağlar, uygulama programlama arayüzünden veri kazımayı önler ve paylaşılan kaynakların adil kullanımını zorunlu kılar.
Yaygın hız sınırlama ayrıntı düzeyleri şunlardır: kullanıcı ID'si başına, uygulama programlama arayüzü anahtarı başına, IP adresi başına, uç nokta başına veya bunların birleşimi. Tipik sınırlar kullanıcı başına dakikada 100 istek ve uygulama programlama arayüzü anahtarı başına saatte 1000 istektir. Hız sınırlayıcı hızlı olmalı (1 ms'den az ek yük oluşturmalı) ve dağıtık çalışmalıdır (tüm uygulama sunucusu kopyalarında tutarlı olmalıdır).
# Rate limiting scenarios
use_cases = [
('API authentication endpoint', '5 attempts per 15 min per IP', 'Brute-force protection'),
('Public search API', '100 requests per minute per key', 'Fair use enforcement'),
('Email sending', '50 emails per hour per user', 'Spam prevention'),
('Payment processing', '10 transactions per second per account', 'Fraud prevention'),
('File upload', '5 uploads per minute per user', 'Resource quota'),
('Notification service', '1000 pushes per second globally', 'Cost control'),
]
print(f'{'Endpoint/Feature':35s} {'Limit':40s} {'Reason'}')
print('-'*95)
for endpoint, limit, reason in use_cases:
print(f'{endpoint:35s} {limit:40s} {reason}')Hız Sınırlama Algoritması 1: Belirteç Kovası
Belirteç kovası algoritması, en fazla N belirteç alabilen bir kova tutar. Belirteçler sabit bir hızla eklenir (örneğin saniyede 10 tane). Her istek bir belirteç tüketir. Kova boşsa istek reddedilir. Kova kapasitesinin altındaysa istek kabul edilir ve belirteç tüketilir.
Belirteç kovası ani yoğunluklara izin verir: 5 saniye boyunca hiç istek gelmezse kova N belirtece kadar dolar ve ardından N istek hemen gelebilir. Bu, ara sıra oluşan ani yoğunlukların kabul edilebilir olduğu uygulama programlama arayüzleri için uygundur. İki parametre kapasite (ani yoğunluk boyutu) ve yenileme hızıdır.
import time
class TokenBucket:
def __init__(self, capacity, refill_rate):
self.capacity = capacity # max tokens (burst size)
self.refill_rate = refill_rate # tokens added per second
self.tokens = capacity # start full
self.last_refill = time.time()
def allow(self):
now = time.time()
elapsed = now - self.last_refill
# Refill tokens based on elapsed time
self.tokens = min(self.capacity,
self.tokens + elapsed * self.refill_rate)
self.last_refill = now
if self.tokens >= 1:
self.tokens -= 1
return True # request allowed
return False # rate limited
bucket = TokenBucket(capacity=5, refill_rate=2) # 2 tokens/sec, burst=5
for i in range(8):
allowed = bucket.allow()
print(f'Request {i+1}: {"ALLOWED" if allowed else "REJECTED"} (tokens={bucket.tokens:.1f})')
time.sleep(0.1) # 0.1s between requestsHız Sınırlama Algoritması 2: Kayan Pencere Günlüğü
Kayan pencere günlüğü, her istek için sıralı bir kümede zaman damgası saklar. Her yeni istek için önce pencere başlangıcından eski zaman damgalarını remove işlemiyle kaldırın, ardından kalan zaman damgalarının sayısının sınırın altında olup olmadığını denetleyin. Evetse geçerli zaman damgasını ekleyin ve allow işlemini uygulayın; aksi halde reddedin.
Bu yöntem kesin sonuç verir; son N saniyede gerçekleşen isteklerin tam sayısını hesaplar. Bunun karşılığında bellek kullanımı yüksektir (kullanıcı başına her istek için bir girdi). Dakikada 1000 istek sınırı ve 100 bin kullanıcı için en kötü durumda 100 milyon günlük girdisi oluşur. Parçalama ile birleştirilmediği sürece çok yüksek trafik için uygun değildir.
import time
from collections import deque
class SlidingWindowLog:
def __init__(self, limit, window_seconds):
self.limit = limit
self.window = window_seconds
self.logs = {} # user_id -> deque of timestamps
def allow(self, user_id):
now = time.time()
if user_id not in self.logs:
self.logs[user_id] = deque()
log = self.logs[user_id]
window_start = now - self.window
# Remove expired timestamps
while log and log[0] <= window_start:
log.popleft()
# Check limit
if len(log) < self.limit:
log.append(now)
return True
return False
limiter = SlidingWindowLog(limit=3, window_seconds=10)
for i in range(5):
allowed = limiter.allow('user123')
print(f'Request {i+1}: {"ALLOWED" if allowed else "REJECTED"}')
time.sleep(0.5)Hız Sınırlama Algoritması 3: Kayan Pencere Sayacı
Kayan pencere sayacı, kayan pencereyi iki kova kullanarak yaklaşıklar — içinde bulunulan dakika ve önceki dakika — ve bunları içinde bulunulan dakikada ne kadar ilerlediğimize göre ağırlıklandırır. Bu yöntem, bellek kullanımını kullanıcı başına O(istekler) değerinden O(1) değerine düşürürken kesin kayan pencere sayısını yakından yaklaşıklar.
Formül: estimated_count = prev_count × (1 - fraction_of_window_elapsed) + curr_count. Bu tahmini sayı sınırı aşarsa istek reddedilir. Bu algoritma, kullanıcı başına O(1) bellek kullanması ve yüksek doğruluğu nedeniyle Cloudflare ve Kong tarafından büyük ölçekte kullanılır.
import time
import math
class SlidingWindowCounter:
def __init__(self, limit, window_seconds=60):
self.limit = limit
self.window = window_seconds
self.buckets = {} # user_id -> {prev_count, curr_count, curr_window_start}
def allow(self, user_id):
now = time.time()
window_start = int(now // self.window) * self.window
if user_id not in self.buckets or self.buckets[user_id]['window'] < window_start - self.window:
self.buckets[user_id] = {'prev': 0, 'curr': 0, 'window': window_start}
elif self.buckets[user_id]['window'] < window_start:
self.buckets[user_id] = {'prev': self.buckets[user_id]['curr'], 'curr': 0, 'window': window_start}
b = self.buckets[user_id]
fraction = (now - window_start) / self.window
estimated = b['prev'] * (1 - fraction) + b['curr']
if estimated < self.limit:
b['curr'] += 1
return True
return False
limiter = SlidingWindowCounter(limit=5, window_seconds=10)
for i in range(7):
print(f'Request {i+1}: {"OK" if limiter.allow("user1") else "RATE LIMITED"}')
time.sleep(0.3)Redis ile Dağıtık Hız Sınırlama
Birden fazla uygulama sunucusuna sahip dağıtık bir sistemde hız sınırlama merkezî olmalıdır; aksi halde her sunucu kendi sayacını izler ve sınırlar sunucu sayısıyla etkili biçimde çarpılır. Atomik işlemlere sahip Redis standart çözümdür: sabit pencere sayacı için INCR ve EXPIRE, kayan pencere günlüğü içinse ZADD ve ZCOUNT kullanın.
Lua betiği yaklaşımı, birden fazla Redis işlemini atomik hâle getirerek iki sunucunun sınırın hemen altında aynı anda artırma yaptığı yarış koşullarını önler. Redis, Lua betiklerini tek bir komut olarak işler ve dağıtık kilitler olmadan atomikliği garanti eder.
# Distributed rate limiting with Redis (pseudocode / simulation)
# Fixed window counter using Redis INCR + EXPIRE
def redis_fixed_window(redis_client, user_id, limit, window_sec):
key = f'rl:{user_id}:{int(time.time() // window_sec)}'
count = redis_client.incr(key) # atomic increment
if count == 1:
redis_client.expire(key, window_sec) # set TTL on first request
return count <= limit
# Sliding window with sorted set
def redis_sliding_window(redis_client, user_id, limit, window_sec):
now = time.time()
key = f'rl:{user_id}'
# Remove old entries, count recent, add current
# Atomic with Lua: multi-step operation
lua_script = '''
local key = KEYS[1]
local now = ARGV[1]
local window = ARGV[2]
local limit = ARGV[3]
redis.call('ZREMRANGEBYSCORE', key, '-inf', now - window)
local count = redis.call('ZCARD', key)
if count < tonumber(limit) then
redis.call('ZADD', key, now, now)
redis.call('EXPIRE', key, window)
return 1 -- allowed
end
return 0 -- rejected
'''
print('Redis Lua script ensures atomicity across ZREM + ZCARD + ZADD')Twitter Akışı Tasarımı: Gereksinimler
Twitter benzeri bir haber akışı sistemi tasarlayalım. İşlevsel gereksinimler şunlardır: kullanıcılar 280 karaktere kadar paylaşım yapabilir, diğer kullanıcıları takip edebilir ve takip ettikleri kişilerin paylaşımlarından oluşan bir akışı yenilik sırasına göre görüntüleyebilir. İşlevsel olmayan gereksinimler şunlardır: günde 300 milyon etkin kullanıcı, günde 500 milyon paylaşım, akışın 2 saniyeden kısa sürede yüklenmesi ve yaklaşık 100:1 okuma-yazma oranı.
Kapasite tahminleri: günde 500 milyon paylaşım ÷ 86400 ≈ saniyede 5800 paylaşım. Okuma sayısı ≈ saniyede 580 bin. Her paylaşım yaklaşık 300 bayttır; 500 milyon × 300 B = günlük 150 GB yeni paylaşım depolaması. Akış toplama, temel mühendislik zorluğudur.
# Twitter feed requirements and estimates
reqs = {
'Functional': [
'Post tweet (text, image, video)',
'Follow/unfollow users',
'View home feed (tweets from followees, newest first)',
'View user timeline (all tweets by one user)',
'Like and retweet',
'Search tweets (basic keyword)',
],
'Non-functional': [
'300M DAU, 500M tweets/day => 5800 writes/sec',
'100:1 read:write => 580K feed reads/sec',
'Feed load < 2 seconds (p95)',
'99.99% availability',
'Tweets retained indefinitely (tweets never deleted by default)',
],
'Estimates': [
'Storage: 500M tweets * 300B = 150 GB/day, 54 TB/year',
'Media: separate object store (S3), CDN-served',
'Feed cache: 300M users * top-100-tweets * 100B = 3 TB (hot feeds in Redis)',
],
}
for category, items in reqs.items():
print(f'{category}:')
for item in items: print(f' - {item}')
print()Yazmada Yayılım: Önceden Hesaplanmış Akışlar
Yazmada yayılım yaklaşımında kullanıcı A bir paylaşım yaptığında sistem bunu hemen her takipçinin akışına dağıtır. Bir takipçi akışını istediğinde akış zaten Redis'te önceden hesaplanmış ve saklanmış olur; bu işlem, O(k) karmaşıklığında basit bir Redis liste okumasıdır; burada k akış boyutudur (genellikle 1000 paylaşımla sınırlandırılır).
Zorluk, milyonlarca takipçisi olan ünlü kullanıcıların büyük yayılım işlemleri oluşturmasıdır. Justin Bieber'ın bir paylaşım yapması, aynı anda 100 milyondan fazla takipçi akışına yazmayı gerektirir — bu, Twitter'ın karşılaştığı ve “ünlü kullanıcı problemi” adını verdiği gerçek bir sorundur. Yazma yayılımı hizmeti, bu ani yoğunlukları yönetmek için eşzamansız ve kuyruk tabanlı olmalıdır.
# Fan-out on write (push model)
fan_out_steps = [
'1. User posts tweet => write to tweets table (source of truth)',
'2. Publish event to message queue (Kafka topic: tweet-created)',
'3. Fan-out workers consume from queue:',
' a. Fetch list of followers from follows table',
' b. For each follower: LPUSH feed:{follower_id} tweet_id',
' c. Trim feed to last 1000 tweets: LTRIM feed:{follower_id} 0 999',
'4. Feed read: LRANGE feed:{user_id} 0 99 => hydrate tweet_ids => response',
]
for step in fan_out_steps:
print(step)
print('\nPros:')
print(' - Feed reads are O(1): just read from Redis list')
print(' - Feed is always sorted by recency automatically')
print('\nCons:')
print(' - Celebrities with 100M followers => 100M Redis writes per tweet')
print(' - Fan-out lag: followers may see tweet 10-30 seconds late at peak')
print(' - Inactive users waste Redis storage for precomputed feeds')Hibrit Yayılım: Ünlü Kullanıcı Problemini Çözme
Hibrit yaklaşım, normal kullanıcılar için yazmada yayılımı, ünlü kullanıcılar içinse okumada yayılımı birleştirir. Bir kullanıcının takipçi sayısı bir eşiği aşıyorsa (örneğin 1 milyon takipçi), kullanıcı ünlü olarak sınıflandırılır. Normal kullanıcıların paylaşımları, paylaşım sırasında tüm takipçi akışlarına gönderilir. Ünlü kullanıcıların paylaşımları ise takipçi akışlarına NOT olarak gönderilmez; bunun yerine bir takipçi akışını okuduğunda sistem ünlü kullanıcının son paylaşımlarını alır ve bunları önceden hesaplanmış akışla birleştirir.
Bu hibrit model, Twitter'ın gerçekte kullandığı modele yakındır. Ünlü kullanıcılar nadiren paylaşım yaptığı ve birleştirme işlemi O(f) olduğu için birleştirme adımı hızlıdır; burada f, kullanıcının takip ettiği ünlü hesapların sayısıdır (genellikle azdır).
# Hybrid fan-out implementation sketch
CELEBRITY_THRESHOLD = 1_000_000 # followers > 1M => celebrity
def on_post_tweet(user_id, tweet_id, follower_count):
if follower_count <= CELEBRITY_THRESHOLD:
# Fan-out to all followers (async via Kafka)
print(f'User {user_id}: fan-out tweet {tweet_id} to {follower_count} followers')
# => queue to fan-out workers
else:
print(f'Celebrity {user_id}: tweet {tweet_id} stored in timeline only')
# => only write to tweets table + user timeline
# => followers get it on demand when reading feed
def get_home_feed(user_id, followees):
# 1. Get precomputed feed (fan-out on write tweets)
precomputed = f'LRANGE feed:{user_id} 0 499' # up to 500 tweets
# 2. Find celebrity followees
celebrity_followees = [u for u in followees if is_celebrity(u)]
# 3. Fetch recent tweets from celebrities (fan-out on read)
celebrity_tweets = []
for celeb in celebrity_followees:
tweets = f'GET tweets WHERE user_id={celeb} ORDER BY created_at DESC LIMIT 20'
celebrity_tweets.extend(tweets)
# 4. Merge and sort by recency
combined = merge_and_sort(precomputed, celebrity_tweets)
return combined[:100]
print('on_post_tweet for regular user:')
on_post_tweet('user123', 'tweet_abc', 500)
print('on_post_tweet for celebrity:')
on_post_tweet('celebrity456', 'tweet_xyz', 50_000_000)Twitter Akışı: Eksiksiz Mimari
Eksiksiz Twitter akışı mimarisi birkaç sistemi birleştirir:
- Paylaşım hizmeti: paylaşımları Cassandra'ya yazar (yüksek yazma kapasitesi, zaman serileri)
- Yayılım hizmeti: paylaşım kimliklerini Redis'teki takipçi akışlarına gönderen eşzamansız çalışanlar (Kafka tüketicileri)
- Akış hizmeti: Redis akışından okur, paylaşım kimliklerini tam paylaşım nesnelerine dönüştürür ve ünlü kullanıcı paylaşımlarını birleştirir
- Takip hizmeti: sosyal grafiği (kimin kimi takip ettiğini) bir grafik veritabanında veya parçalanmış SQL'de yönetir
- Zaman akışı hizmeti: kullanıcının kendi paylaşımlarını sunar (ana akıştan ayrıdır)
# Twitter architecture summary
architecture = '''
[User] --> [API Gateway + Load Balancer]
|
+-----------+-----------+
| | |
[Tweet Svc] [Feed Svc] [Follow Svc]
| | |
[Cassandra] [Redis Feeds] [Graph DB]
| |
[Kafka] <-- [Fan-out
| Workers]
[S3 + CDN] (tweet_ids
(media) => follower
feed lists)
Key design choices:
- Tweets stored in Cassandra (PRIMARY KEY (user_id, created_at))
- Feed stored in Redis as list of tweet_ids per user (LPUSH/LTRIM/LRANGE)
- Fan-out via Kafka + workers (decoupled, retryable, scalable)
- Hybrid: regular users = push; celebrities = pull-on-read
- Hydration: tweet_ids -> full tweet objects via Cassandra read
'''
print(architecture)Hız Sınırlayıcı Üstbilgileri ve Hata Yanıtları
İyi tasarlanmış bir hız sınırlayıcı, sınırlarını istemcilere HTTP yanıt üstbilgileri aracılığıyla bildirir. Bu, istemcilerin yeniden deneme sonrası mantığını uygulamasını ve panoların kullanımı göstermesini sağlar. Standart üstbilgiler:
X-RateLimit-Limit: pencere içinde izin verilen en yüksek istek sayısıX-RateLimit-Remaining: geçerli pencerede kalan istek sayısıX-RateLimit-Reset: pencerenin sıfırlandığı Unix zaman damgasıRetry-After: yeniden denemeden önce beklenecek saniye sayısı (429 yanıtında)
Hız sınırlı yanıtlar için HTTP durum kodu 429 Çok Fazla İstek değeridir.
# Rate limit response headers
def build_rate_limit_headers(limit, remaining, reset_timestamp, retry_after=None):
headers = {
'X-RateLimit-Limit': str(limit),
'X-RateLimit-Remaining': str(max(0, remaining)),
'X-RateLimit-Reset': str(int(reset_timestamp)),
}
if retry_after is not None:
headers['Retry-After'] = str(retry_after)
return headers
import time
# Simulated response for allowed request
headers = build_rate_limit_headers(
limit=100,
remaining=73,
reset_timestamp=time.time() + 45
)
print('Allowed request headers:')
for k, v in headers.items():
print(f' {k}: {v}')
# Rate limited response
headers_429 = build_rate_limit_headers(
limit=100,
remaining=0,
reset_timestamp=time.time() + 30,
retry_after=30
)
print('\n429 Too Many Requests headers:')
for k, v in headers_429.items():
print(f' {k}: {v}')Hız Sınırlama Algoritmalarını Karşılaştırma
Mülakatlarda seçim yapmanıza yardımcı olacak tüm hız sınırlama algoritmalarının özet karşılaştırması:
- Belirteç Kovası: Ani istek artışlarına izin verir ve düzgün bir dolum hızı sağlar. Ara sıra oluşan ani artışların kabul edilebilir olduğu API'ler için en uygunudur (en yaygın seçim).
- Sızdıran Kova: Ani artışlardan bağımsız olarak istekleri sabit bir çıktı hızında işler. Trafiği sabit bir akışa dönüştürmek için en uygunudur.
- Sabit Pencere Sayacı: En basit seçenektir ve O(1) alan kullanır. Sorun: pencere sınırında limitin iki katı büyüklüğünde ani artış oluşabilir (örneğin 11:59'da 100 + 12:00'da 100).
- Kayan Pencere Günlüğü: En doğru seçenektir ve pencere sınırında ani artış oluşturmaz. Sorun: O(istek sayısı) miktarında bellek gerektirir.
- Kayan Pencere Sayacı: O(1) alan kullanarak kayan pencere günlüğünü yaklaşıklar. Cloudflare tarafından kullanılır.
# Algorithm comparison matrix
comparison = [
('Token Bucket', 'Allows bursts', 'O(1)', 'Most APIs, default choice'),
('Leaky Bucket', 'Smooth output rate', 'O(1)', 'Traffic shaping, message queues'),
('Fixed Window Counter', 'Very simple', 'O(1)', 'Low-traffic, approximate OK'),
('Sliding Window Log', 'Most accurate', 'O(requests)', 'High-accuracy, low traffic'),
('Sliding Window Counter','Approximate+fast', 'O(1)', 'High-traffic, Cloudflare-style'),
]
print(f'{'Algorithm':30s} {'Burst Handling':20s} {'Memory':15s} {'Use Case'}')
print('-'*85)
for name, burst, mem, use in comparison:
print(f'{name:30s} {burst:20s} {mem:15s} {use}')Hızlı Kontrol
Bu dersteki Veri Yapıları & Algoritmalar — Kodlama Mülakatına Hazırlık kavramlarını ne kadar anladığınızı sınayın.
Ders Özeti
Bu derste şunları öğrendiniz: hız sınırlayıcıları, istek hızlarını denetlemek için belirteç kovası (ani artışlara izin verir), kayan pencere sayacı (O(1) bellek) veya kayan pencere günlüğü (en doğru seçenek) kullanır ve Redis'in atomik işlemleri dağıtık hız sınırlamayı mümkün kılar; Twitter akışı, hızlı okumalar için takipçilerin akışlarını Redis'te önceden hesaplamak üzere yazma sırasında yayma yöntemini kullanır; ünlü hesaplarda büyük yazma çoğalmasını önlemek için de karma bir çekme modeli kullanılır. Sırada, problem ipuçlarını onları en hızlı çözen algoritma örüntüleriyle eşleyen bir örüntü tanıma kısa başvuru kılavuzunun yer aldığı bitirme bölümüne geçiyoruz.
Sıkça Sorulan Sorular
“Hız Sınırlayıcı ve Twitter Akışı Tasarlama” dersi ücretsiz mi?
Evet — “Hız Sınırlayıcı ve Twitter Akışı Tasarlama” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Coding Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Coding Interview Prep kursu toplamda 4 dersten oluşur.
“Hız Sınırlayıcı ve Twitter Akışı Tasarlama” dersinde ne öğreneceğim?
Çerçeveyi iki temel tasarım problemine uygulayın: belirteç kovası/kayan pencere hız sınırlama ve yazma sırasında çoğaltma ile okuma sırasında çoğaltma yaklaşımlarından biriyle haber akışı oluşturma. Coding Interview Prep ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Coding Interview Prep öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Coding Interview Prep, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“Hız Sınırlayıcı ve Twitter Akışı Tasarlama” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Coding Interview Prep dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Coding Interview Prep dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Sistem Tasarımı Mülakatı Çerçevesi
- Ölçeklenebilir Veri Depolama: SQL ve NoSQL
- Önbelleğe Alma, CDN’ler ve Yük Dengeleme
- Hız Sınırlayıcı ve Twitter Akışı Tasarlama