01मेरे stack में कौन दिखेगा यह क्या तय करता है — preferences, distance, या दोनों?
उपयोगकर्ता preferences (आयु सीमा, रुचियाँ) और एक अधिकतम distance सेट करते हैं; stack में केवल वे candidates होते हैं जो दोनों को संतुष्ट करते हैं।
मुफ़्त पूरी गाइड
Tinder डिज़ाइन करें। इसमें Swipe ingestion as a high-volume, append-only event write path (like/pass events) decoupled from match detection, Match detection: checking whether A likes B AND B likes A,...
Interview की लय संक्षिप्त रहती है, ताकि page असली design निर्णयों पर ध्यान लगा सके.
सिर्फ requirements मत बताइए — पूछिए। हर card एक design constraint को उस clarification सवाल से जोड़ता है जो आप architecture बनाने से पहले बोल सकते हैं.
01मेरे stack में कौन दिखेगा यह क्या तय करता है — preferences, distance, या दोनों?
उपयोगकर्ता preferences (आयु सीमा, रुचियाँ) और एक अधिकतम distance सेट करते हैं; stack में केवल वे candidates होते हैं जो दोनों को संतुष्ट करते हैं।
02क्या swiping एक-एक करके है, और क्या कोई profile कभी वापस आ सकता है?
उपयोगकर्ता एक बार में एक profile पर yes/no swipe करते हैं, और swipe किया गया profile फिर कभी नहीं आता — दोहराए गए profiles टूटे हुए जैसे लगते हैं।
03आपसी yes के पल में क्या होता है?
दोनों users को match notification तुरंत मिलती है — उसी पल जब दूसरी yes उतरती है, मिनटों बाद नहीं।
04क्या उपयोगकर्ता एक left swipe को undo कर सकता है (rewind)?
एक छोटी window के भीतर, हाँ — और rewound profile stack में दोबारा दिख सकता है।
05Unmatching क्या करती है?
Unmatch match को हटाता है और chat को एक ही action में बंद करता है — एक आधा-रद्द match (chat ज़िंदा, match गया) एक trust bug है।
06एक उपयोगकर्ता session के बीच में preferences बदलता है - उनके deck का क्या होता है?
New preferences तुरंत लागू हों — दिखाया जाने वाला अगला ही profile update किए गए filters को संतुष्ट करे, पुराने को नहीं।
Scope से बाहरPhoto upload pipeline · Match के बाद messaging · Premium features (super swipes, boosts)
01अगर दो लोग लगभग एक ही पल एक-दूसरे पर yes swipe करें, तो क्या ठीक एक match की गारंटी है — कभी zero नहीं, कभी दो नहीं?
ठीक एक match, तुरंत detected — कभी zero नहीं, कभी दो नहीं, timing चाहे कितनी भी नज़दीक हो।
02हम किस swipe volume के लिए size कर रहे हैं?
20M daily active users (DAU) × ~100 swipes ≈ 2B swipes/day — औसतन लगभग 23K swipes प्रति सेकंड।
03Stack को कितनी तेज़ी से दिखना चाहिए?
300 ms से नीचे।
04"कभी दो बार न दिखाओ" नियम कितना कठोर है?
कड़ा: यह sessions, devices, और reinstalls के आर-पार बना रहे — एक profile दो बार दिखाना एक candidate को चुपचाप skip कर देने से बुरा है।
05दूसरे उपयोगकर्ता कभी क्या location data देख सकते हैं?
केवल एक मोटा distance bucket ("~5 km दूर") — raw lat/lng किसी भी payload में backend नहीं छोड़ता।
असली interview एक साफ list से कहीं गहरा probe करते हैं. ये scope सवाल उन्हें अलग करते हैं जो problem को कुरेदते हैं बनाम जो रटते हैं.
हर estimate को एक दबाव मानिए जो किसी component को justify करता है: cache, queue, partition, replica, worker pool, या fallback path.
Swipe लिखने की दर
20M daily active users (DAU) × ~100 swipes/day2B ÷ 86,400 s ≈ 23K swipes/s औसत, शामों में ×3-5 ≈ 100K/s peak
Swipes को एक write-optimized store चाहिए; इस दर पर mutual check प्रति swipe O(1) रहना चाहिए।
Seen-profile memory
मान लें एक भारी उपयोगकर्ता जीवनभर में ~50K profiles swipe करता है1% false positives पर Bloom filter ≈ 10 bits/entry → 50K × 10 b ≈ प्रति उपयोगकर्ता 62 KB
पूरा "कभी दो बार न दिखाओ" गार्ड प्रति उपयोगकर्ता kilobytes में आ जाता है — सटीक swipe इतिहास disk पर रहता है।
Deck precompute लागत
मान लें प्रति सक्रिय उपयोगकर्ता ~200 candidates का deck, कम पड़ने पर refresh20M users × 200 IDs × 8 B ≈ 32 GB
हर सक्रिय उपयोगकर्ता के लिए precomputed decks एक cache tier में आ जाते हैं — यही <300 ms को संभव बनाता है।
Live query क्यों नहीं
एक घना शहर एक max-distance circle के अंदर 20M DAU का करीब 1% रख सकता है — करीब 200K users। हर एक को अब भी geo, age, preference, और not-seen filtering चाहिए।200K candidates × filters intersect करने और seen list check करने के लिए हर एक पर ~1-2 µs ≈ प्रति request 200-400 ms — ranking शुरू होने से पहले ही पूरा 300 ms budget जल गया
Feed budget request path पर live query चलाने को खारिज कर देता है। इसके बजाय, deck को precompute करो और background में उसे top up करते रहो।
Match check लागत
हर yes-swipe reverse direction check करता हैप्रति swipe 1 atomic read-modify-write ≈ memory में sub-ms
जोड़ी की swipe state को साथ (एक key) रखना ही check को एक operation बनाए रखता है।
निर्णय उदाहरण
peak पर एक लाख swipes प्रति सेकंड। जो एक पल गलत नहीं हो सकता वह है दो लोगों का एक ही समय पर एक-दूसरे को हाँ कहना।
मैं हर जोड़ी की swipe state को एक key के नीचे रखूँगा — दोनों user IDs, छोटा पहले। फिर मैं swipe record करता हूँ और उल्टी swipe check करता हूँ, एक ही atomic operation में। Redis में एक Lua script यह read-modify-write एक ही step में करता है, और उसके पीछे टिकाऊ copy swipe store में लिखी जाती है। Decks हर user के लिए precompute होते हैं और एक background geo query से top up होते हैं। हर user के देखे गए profiles एक Bloom filter में रहते हैं, इसलिए "दोबारा कभी न दिखाओ" की कीमत kilobytes है, एक history scan नहीं।
जो मैं नहीं करूँगा: swipe record करना और उल्टी swipe check करना दो अलग steps में। दो एक साथ हुई yes-swipes हर एक दूसरे को चूक जाती हैं, और match कभी fire नहीं होता। वह check-then-act का अंतराल वही race है जो concert seats को दो बार बेच देता है — check और write एक ही operation होने चाहिए। मैं feed को हर request पर एक live geo query के रूप में भी नहीं बनाऊँगा, क्योंकि वह पूरा 300 ms budget index lookups पर जला देता है।
अगर Redis bottleneck बन जाए, या cluster failover बहुत जटिल हो जाए, तो मैं atomicity को storage layer में ले जाऊँगा। एक compound partition key (smaller_id:larger_id) दोनों swipes को एक ही partition में उतार देता है। वहाँ, एक lightweight transaction उस जोड़ी को cover करती है — database का अपना compare-and-set, Redis से धीमा पर built-in। यह प्रति swipe ज़्यादा खर्चीला है, पर एक चलता-फिरता system बचा देता है।
पहले एक पूरी तस्वीर, फिर हर path को अपना अलग diagram — write path और read path अलग traffic ढोते हैं और अलग components justify करते हैं.
पूरी तस्वीर
Swipe path consistency-critical रीढ़ है; feed path read-optimized और precomputed है। Dashed = durable swipes से asynchronously बनाए रखा गया, cache loss के बाद फिर बनाया जा सकने वाला।
Path 1
एक atomic operation swipe record करता है और उल्टी swipe check करता है। टिकाऊ write उसके बाद आती है। अगर एक Redis node खो जाए, तो वह टिकाऊ store से replay करता है और ज़्यादा से ज़्यादा आख़िरी कुछ बिना flush की swipes खोता है — swipe-path speed के लिए एक स्वीकार्य trade।
Path 2
Request path केवल deck पढ़ता है। जब यह कम पड़ता है, background query इसे फिर भरती है, Bloom filter के ज़रिए seen profiles को बाहर रखते हुए — false positives एक candidate छोड़ते हैं, किसी को दोहराते कभी नहीं।
optimize करने से पहले contract को inspectable बनाइए: endpoints, entities, ownership, retries, और state.
POST/profile
req{ age_min, age_max, distance_km, interested_in }
res200 profile
पहचान session token से। Preference बदलाव precomputed deck को invalidate करते हैं।
GET/feed
res200 User[] (next slice of the deck)
Precomputed deck serve करता है; जब यह कम पड़ता है, एक ताज़ा geo+preference query इसे top up करती है। Location query parameters से नहीं, session context से आती है।
POST/swipe/{target_user_id}
req{ decision: yes | no }
res200 { matched: boolean } — matched:true fires both notifications
वह atomic कदम: swipe record करो और reverse swipe को एक ही operation में check करो।
Core entities
Useruser_id (PK) · profile · preferences · geo_cell (coarse)
Location matching के लिए एक मोटे geo cell के रूप में store होती है; सटीक coordinates कभी दूसरे clients को serve नहीं किए जाते।
Swipeswiping_user · target_user · decision: yes/no · swiped_at
Swipe store में durably लिखा जाता है; साथ ही swiper के seen profiles के Bloom filter में मोड़ा जाता है।
Matchmatch_id (PK) · user_a · user_b · matched_at
interview के आखिरी एक-तिहाई के लिए एक lane चुनें. हर lane आपको topic, वह interviewer सवाल जिसका जवाब देना है, और बचने वाला failure mode देती है.
दो उपयोगकर्ता एक ही 10 ms में एक-दूसरे पर yes swipe करते हैं। वे सटीक operations चलाओ जो एक match पैदा करें, शून्य नहीं।
इसे एक atomic operation बनाओ। दोनों users का swipe state एक ही key के नीचे store करो, दोनों IDs को छोटा पहले करके sort करके। Swipe record करो और reverse swipe के लिए check करो — एक ही Redis Lua script में। दूसरा swipe हमेशा पहले को देख लेता है, तो ठीक एक ही match fire होता है।
दो कदमों में read-then-write — दोनों swipes एक-दूसरे को चूक जाती हैं और match चुपचाप कभी नहीं होता।
आप इतिहास scan किए बिना हर deck refill से 50,000 पहले swipe किए profiles को कैसे बाहर रखते हैं?
हर user के लिए एक Bloom filter इस्तेमाल करो — हर profile का जिसे उन्होंने swipe किया। 50K entries पर यह करीब 62 KB है। हर deck candidate को उसके ख़िलाफ़ screen करो; एक false positive बस एक candidate छोड़ देता है और किसी को कभी दोहराता नहीं। Bloom filter unlearn नहीं कर सकता, तो आख़िरी कुछ swipes को एक छोटे exact buffer में रखो — यही rewind को चलाता है।
Bloom false positives को एक bug मानना — एक candidate छोड़ना डिज़ाइन की गई लागत है; एक को दोहराना विफलता है।
एक सक्रिय उपयोगकर्ता अपने पूरे precomputed deck को swipe कर जाता है। इसे क्या फिर भरता है, यह कितना fresh है, और वे कितनी latency देखते हैं?
हर request का जवाब precomputed deck cache से दो। Refills एक low-water mark पर asynchronously चलते हैं, तो एक background geo-and-preference query 200-candidate deck को दोबारा बना देती है — user के नीचे पहुँचने से पहले। यही precompute एक live multi-filter query को 300 ms path से बाहर रखता है। एक preference change deck को गिरा देता है और उसी तरह refill करता है।
खाली-deck request पर synchronously refill करना — query शुरू होने से पहले ही 300 ms budget चला जाता है।
Matching को distance चाहिए, उपयोगकर्ताओं को कभी coordinates नहीं देखने चाहिए। precision कहाँ गिराई जाती है, और API वास्तव में क्या लौटाता है?
Precise coordinates सिर्फ़ server-side रखो, candidate selection के लिए। Backend distance compute करता है और उसे किसी response में जाने से पहले एक coarse bucket में round कर देता है, जैसे "~5 km दूर"। कोई भी payload किसी field में lat/lng नहीं ले जाता। Client पर rounding करना दिखावा है — payload खुद ही leak है।
Clients को raw lat/lng भेजना और UI में round करना — payload ही लीक है।
एक बहुत लोकप्रिय profile लाखों decks में दिखता है। पहले क्या hot-spot होता है, और आप exposure कैसे संतुलित रखते हैं?
Profile की pair keys और swipe partitions सबसे पहले hot-spot होती हैं, तो उस state को shard या replicate करो। फिर profile को एक exposure budget दो: एक cap कि वह एक साथ कितने live decks घेर सकता है, जो swipes के उसे खाली करते ही refill होता रहे। इस तरह एक popular profile हर पास वाले deck को नहीं भर सकता और बाकी सबको views से वंचित नहीं कर सकता।
Exposure skew को नज़रअंदाज़ करना — बिना caps के, लोकप्रिय profiles हर deck पर हावी हो जाते हैं और engagement ढह जाता है।
Tinder को ज़ोर से समझाइए और अपनी व्याख्या पर AI scoring पाइए.