प्रांप्ट और संदर्भ
Google Calendar जैसे उत्पाद के लिए इवेंट कॉन्फ्लिक्ट हैंडलिंग डिज़ाइन करें। उपयोगकर्ता प्रतिभागियों, प्रारंभ और समाप्ति समय, समय क्षेत्र, पुनरावृत्ति नियमों (recurrence rules), रिमाइंडर्स, दृश्यता (visibility) और मीटिंग लिंक के साथ इवेंट बनाते, अपडेट करते और हटाते हैं। किसी निर्माण या अपडेट को टकरावों का पता लगाना चाहिए और अस्वीकार (reject), चेतावनी देकर आगे बढ़ना (warn-and-proceed), या ओवरराइड नीतियों का समर्थन करना चाहिए। यह मान लें कि खाली/व्यस्त (free/busy) पढ़ने के अनुरोध लिखने की तुलना में कहीं अधिक हैं, सामान्य जाँचों में कुछ दसियों मिलीसेकंड लगते हैं, और निजी कैलेंडर केवल व्यस्त स्थिति को उजागर करते हैं।
साक्षात्कारकर्ता क्या मूल्यांकन करता है
एक मजबूत उत्तर डेटाबेस का नाम लेने से पहले कॉन्फ्लिक्ट सेमेंटिक्स को परिभाषित करता है। मुख्य संकेत हैं: हाफ-ओपन इंटरवल नियम जो सीमाओं पर गलत टकरावों से बचाता है; ओवरलैप इंडेक्स से अलग एक विहित (canonical) इवेंट मॉडल; स्पष्ट RRULE, अपवाद और भौतिकीकरण (materialization) सीमाएं; स्थानीय समय नियमों से पूर्ण क्षणों (absolute instants) में रूपांतरण; व्युत्पन्न (derived) इंडेक्स के लिए एक आउटबॉक्स या CDC पथ; और एक ही संसाधन को आरक्षित करने वाले दो राइटर्स के लिए एक समवर्ती (concurrency) रणनीति। केवल "ओवरलैप के लिए डेटाबेस को क्वेरी करना" कहने से ये विफलता मोड अनुत्तरित रह जाते हैं।
स्पष्ट करने वाले प्रश्न
- क्या आसन्न (adjacent) अंतराल आपस में टकराते हैं? यदि नहीं, तो हाफ-ओपन इंटरवल
[start, end)का उपयोग करें। - एक आवर्ती श्रृंखला का विस्तार कितनी दूर तक किया जाना चाहिए? एक असीमित श्रृंखला के लिए रोलिंग विंडो या क्वेरी-टाइम विस्तार की आवश्यकता होती है।
- क्या कोई भी व्यस्त प्रतिभागी इवेंट को ब्लॉक करता है, या केवल आवश्यक प्रतिभागी या आयोजक? यह क्वेरी फैन-आउट और नीति निर्धारित करता है।
- क्या डबल बुकिंग को अस्वीकार किया जाता है, चेतावनी दी जाती है, या अनुमति दी जाती है? एक सम्मेलन कक्ष (conference room) और एक व्यक्तिगत कैलेंडर विभिन्न नीतियों का उपयोग कर सकते हैं।
- क्या किसी अन्य उपयोगकर्ता को पूरा विवरण, एक व्यस्त अंतराल, या कुछ भी नहीं देखना चाहिए? यह ACLs और प्रतिक्रिया का प्रारूप तय करता है।
30-सेकंड का उत्तर
"मैं विहित इवेंट और प्रतिभागी रिकॉर्ड के साथ-साथ कैलेंडर-विभाजित (calendar-partitioned) फ्री-बिज़ी इंडेक्स रखता हूँ। टकराव केवल तभी होता है जब existing.start < new.end और new.start < existing.end; खाली (free) इवेंट समय पर कब्जा नहीं करते हैं। मैं इवेंट के समय क्षेत्र में पुनरावृत्ति नियमों को संग्रहीत करता हूँ, एक सीमित क्षितिज को भौतिक रूप देता हूँ, और अपवादों को रिकॉर्ड करता हूँ। संस्करण जाँच या संसाधन लॉक लेखन की सुरक्षा करते हैं, और कमिट के बाद एक आउटबॉक्स व्युत्पन्न इंडेक्स को अपडेट करता है। प्रतिक्रियाएं केवल ACL-अनुमत व्यस्त जानकारी को उजागर करती हैं, जबकि निगरानी इंडेक्स ड्रिफ्ट, पुनर्निर्माण और अधिसूचना विलंब को कवर करती है।"
चरण-दर-चरण समाधान
1. समय और टकराव विधेय (Conflict Predicate) को परिभाषित करें
प्रत्येक घटना को [start_utc, end_utc) के रूप में दर्शाएं, जबकि प्रदर्शन और विस्तार के लिए मूल समय क्षेत्र और स्थानीय नियम को बनाए रखें। दो घटनाएं ठीक तभी टकराती हैं जब a.start < b.end और b.start < a.end। इस प्रकार 10:00–11:00 और 11:00–12:00 आसन्न हैं, ओवरलैपिंग नहीं; शून्य-लंबाई या उल्टे अंतरालों को अस्वीकार करें। समान विधेय लागू करने से पहले पूरे दिन के आयोजनों को कैलेंडर समय क्षेत्र में सीमाओं में बदलें।
2. विहित मॉडल को उपलब्धता इंडेक्स से अलग करें
विहित परत संपादन और ऑडिट के लिए इवेंट, प्रतिभागियों, RRULEs, अपवादों, ACLs और संस्करणों को संग्रहीत करती है। उपलब्धता इंडेक्स केवल calendar_id, घटना सीमाएं, अधिभोग स्थिति (occupancy state), इवेंट आईडी और एक दृश्यता लेबल संग्रहीत करता है, जिसे कैलेंडर और प्रारंभ समय द्वारा क्रमबद्ध किया जाता है। कॉन्फ्लिक्ट क्वेरी बड़े इवेंट JSON के बजाय अनुरोधित विंडो को स्कैन करती हैं। महीने या टेनेंट के आधार पर विभाजन करें; अत्यधिक उपयोग वाले कैलेंडरों को एक समर्पित शार्ड या कैश की आवश्यकता हो सकती है।
3. पुनरावृत्ति और अपवादों को संभालें
iCalendar-शैली के RRULEs संग्रहीत करें और अनुरोधित क्षितिज के लिए घटनाओं का विस्तार करें। एक रोलिंग भौतिकीकरण अगले 90 दिनों को उत्पन्न कर सकता है और सीमा के करीब आने पर इसका विस्तार कर सकता है; अधिक दूर की क्वेरी मांग पर विस्तार करती हैं और परिणाम को कैश करती हैं। this occurrence, this and future, और पूरी श्रृंखला के संपादन पिछली घटनाओं को फिर से लिखने के बजाय अपवाद रिकॉर्ड या एक नया श्रृंखला संस्करण बनाते हैं। प्रत्येक घटना कॉन्फ्लिक्ट जाँच और सूचनाओं में स्वतंत्र रूप से भाग लेती है।
4. राइट पाथ और समवर्ती नियंत्रण (Concurrency Control)
समय, ACLs और प्रतिभागी नीति को मान्य करें, फिर उसी लेनदेन में वर्तमान इंडेक्स संस्करण की जाँच करें। व्यक्तिगत कैलेंडर आशावादी (optimistic) संस्करणों का उपयोग कर सकते हैं और क्लाइंट्स से पुन: प्रयास करने के लिए कह सकते हैं; सख्त रूप से अनन्य (exclusive) कमरे या अपॉइंटमेंट स्लॉट प्रति-संसाधन लॉक या डेटाबेस एक्सक्लूजन बाधाओं (exclusion constraints) का उपयोग कर सकते हैं। इवेंट और आउटबॉक्स रिकॉर्ड को एक साथ कमिट करें; उपभोक्ता इंडेक्स को अपडेट करते हैं और सूचनाएं भेजते हैं। यदि इंडेक्स पिछड़ जाता है, तो विहित स्टोर से पढ़ें या उत्तर को अनिश्चित के रूप में चिह्नित करें—कभी भी चुपचाप यह दावा न करें कि कोई टकराव नहीं है।
5. गोपनीयता, क्वेरी और पैमाना (Scale)
ACL द्वारा प्रतिक्रियाओं को स्तरित करें: अधिकृत दर्शक शीर्षक और प्रतिभागियों को देखते हैं, जबकि अन्य केवल व्यस्त अंतराल देखते हैं और निजी कार्यक्रम अपारदर्शी ब्लॉक के रूप में दिखाई देते हैं। नीति के अनुसार खाली, अस्थायी (tentative), और कार्यालय से बाहर (out-of-office) की स्थितियों को अधिभोग या चेतावनियों पर मैप करें। अधिक पढ़ने वाले ट्रैफ़िक के लिए सामान्य विंडो को कैश करें; कुंजी में एक कैलेंडर संस्करण या अमान्यकरण वॉटरमार्क शामिल करें। क्रॉस-संगठन फ्री/बिज़ी कॉल्स के लिए टाइमआउट और आंशिक-परिणाम सेमेंटिक्स की आवश्यकता होती है ताकि एक बाहरी कैलेंडर प्रत्येक प्रतिभागी के प्रवाह को बाधित न कर सके।
6. निरंतरता, मरम्मत और विफलता पथ
विहित इवेंट सत्य का स्रोत (source of truth) है और इंडेक्स पुनर्निर्माण योग्य है। एक आउटबॉक्स या CDC गारंटी देता है कि एक सफल कमिट अंततः एक इंडेक्स अपडेट उत्पन्न करता है; उपभोक्ता संस्करणों को इडेम्पोटेंट रूप से संसाधित करते हैं ताकि कोई पुराना संदेश नए संदेश को अधिलेखित न कर सके। समय-समय पर विहित घटनाओं की तुलना इंडेक्स हैश या गणनाओं से करें, उनके भटकने (drift) पर कैलेंडर का पुनर्निर्माण करें, और प्रभावित सीमा को रिकॉर्ड करें। पहले से कमिट हो चुके इवेंट को रोलबैक किए बिना विफल सूचनाओं का पुन: प्रयास करें।
उच्च गुणवत्ता वाला नमूना उत्तर
मैं पहले [start, end) के साथ टकरावों को परिभाषित करूँगा: केवल सख्त प्रतिच्छेदन (intersection) में टकराव होता है, आसन्न आयोजनों में नहीं, और खाली आयोजन किसी भी उपलब्धता का उपभोग नहीं करते हैं। विहित इवेंट मॉडल मूल समय क्षेत्र, RRULE, अपवादों, प्रतिभागियों और ACLs को संग्रहीत करता है। एक अलग कैलेंडर-विभाजित घटना इंडेक्स तेज़ विंडो स्कैन के लिए केवल सीमाओं, अधिभोग और इवेंट आईडी को संग्रहीत करता है। RRULEs इवेंट के समय क्षेत्र में रहते हैं; मैं अगले 90 दिनों को भौतिक रूप देता हूँ, मांग पर आगे की सीमाओं का विस्तार करता हूँ, और एकल-घटना, भविष्य-घटना, और पूरी श्रृंखला के संपादनों को स्पष्ट अपवादों या संस्करणों के रूप में दर्शाता हूँ।
राइट पाथ अनुमतियों और नीति को मान्य करता है, फिर समवर्ती संपादनों के लिए एक आशावादी संस्करण या संसाधन लॉक का उपयोग करता है। इवेंट और आउटबॉक्स रिकॉर्ड एक साथ कमिट होते हैं; संस्करण-जागरूक उपभोक्ता इंडेक्स को इडेम्पोटेंट रूप से अपडेट करते हैं और सूचनाएं वितरित करते हैं। इंडेक्स व्युत्पन्न है और विहित डेटा से पुनर्निर्मित किया जा सकता है, और टकराव प्रतिक्रियाएं ACL-फ़िल्टर की जाती हैं। मैं एक व्यक्तिगत कैलेंडर पर डबल बुकिंग को ब्लॉक करने के बजाय चेतावनी दूंगा, लेकिन एक कमरे के लिए एक्सक्लूजन बाधा या लॉक का उपयोग करूंगा। मैं इंडेक्स ड्रिफ्ट, पुराने संस्करणों, क्वेरी विलंबता और बाहरी फ्री/बिज़ी टाइमआउट की निगरानी करूँगा।
सामान्य गलतियां
- गलती: ओवरलैप के लिए
start <= other.endका उपयोग करना → आसन्न इवेंट गलत टकराव बन जाते हैं → हाफ-ओपन इंटरवल नियम बताएं और अमान्य शून्य-लंबाई वाले इवेंट को अस्वीकार करें। - गलती: प्रत्येक अनुरोध पर एक असीमित आवर्ती श्रृंखला का विस्तार करना → विलंबता और कार्य की कोई ऊपरी सीमा नहीं होती → एक रोलिंग भौतिकीकरण क्षितिज और उससे परे मांग पर विस्तार का उपयोग करें।
- गलती: कॉन्फ्लिक्ट इंडेक्स के रूप में पूर्ण इवेंट JSON का उपयोग करना → रीड्स बड़े फ़ील्ड्स को स्कैन करते हैं और निजी विवरण लीक करते हैं → एक समय-और-अधिभोग प्रोजेक्शन बनाए रखें और ACL द्वारा संपादित करें।
- गलती: इंडेक्स अपडेट विफल होने पर इवेंट को रोलबैक करना → सत्य का स्रोत खोज और सूचनाओं के साथ जुड़ जाता है → एक आउटबॉक्स कमिट करें, एसिंक्रोनस रूप से पुन: प्रयास करें, और पुनर्निर्माण प्रदान करें।
- गलती: प्रत्येक कैलेंडर के लिए एक वैश्विक लॉक लेना → अत्यधिक उपयोग वाले कैलेंडर पूरी सेवा को धीमा कर देते हैं → केवल सख्त रूप से अनन्य संसाधनों को लॉक करें और सामान्य कैलेंडर के लिए संस्करण जाँच का उपयोग करें।
फॉलो-अप और प्रतिक्रियाएं
आप ऐसा समय कैसे खोजेंगे जब प्रत्येक प्रतिभागी खाली हो?
लक्षित विंडो के लिए प्रत्येक आवश्यक प्रतिभागी के व्यस्त अंतरालों को क्वेरी करें, एक सामान्य समयरेखा पर अंतरालों को मर्ज करें, और उनके संघ (union) का पूरक (complement) लें। प्रतिभागियों की संख्या के साथ फैन-आउट बढ़ता है, इसलिए समानांतर में क्वेरी चलाएं, विंडो को सीमित करें, और निजी विवरणों को उजागर करने के बजाय अनधिकृत या टाइम-आउट कैलेंडर के लिए आंशिक या अनिश्चित परिणाम लौटाएं।
एक आवर्ती बैठक DST परिवर्तन के बाद केवल कुछ तारीखों पर टकराती है। आप इसे कैसे डिबग करेंगे?
RRULE समय-क्षेत्र पहचानकर्ता, मूल स्थानीय समय, विस्तार-लाइब्रेरी संस्करण और अपवाद रिकॉर्ड का निरीक्षण करें। स्थानीय समय को UTC में परिवर्तित न करें और विस्तार करने से पहले ज़ोन को न हटाएं। DST सीमा को पार करने वाले एक फिक्सचर को फिर से चलाएं और विस्तार बग को इंडेक्स भौतिकीकरण बग से अलग करने के लिए प्रत्येक घटना के स्थानीय प्रदर्शन समय, UTC सीमाओं और ओवरलैप विधेय की तुलना करें।
जब किसी कमरे को कभी भी डबल-बुक नहीं किया जाना चाहिए तो क्या बदलता है?
दो अनुरोध दोनों कमरे को खाली देख सकते हैं। डेटाबेस एक्सक्लूजन बाधा, सीरियलाइज़ेबल लेनदेन, या शॉर्ट रिसोर्स लॉक के साथ संसाधन समय सीमा को सुरक्षित रखें, और विफलता पर परस्पर विरोधी घटना को लौटाएं। लॉक केवल कमिट विंडो को कवर करता है, कभी भी कैश को नहीं; अत्यधिक उपयोग वाले संसाधनों को शार्ड करें और पुन: प्रयासों को सीमित करें ताकि एक लॉक कतार अन्य कैलेंडरों को प्रभावित न करे।