प्रॉम्प्ट और परिदृश्य
एक बड़ा C++ कोडबेस कई कंपाइलर्स, स्टैंडर्ड-लाइब्रेरी वर्जन्स और बिल्ड मोड्स का उपयोग करता है। टीम API प्रीकंडीशन और पोस्टकंडीशन के लिए C++26 Contracts चाहती है, लेकिन कंपाइलर के असमान सपोर्ट, वॉयलेशन के बाद ऑनलाइन-प्रोसेस व्यवहार और एक पुरानी बिल्ड फ्लीट जिसे अपग्रेड नहीं किया जा सकता, को लेकर चिंतित है। एक चरणबद्ध रोलआउट डिज़ाइन करें और वैलिडेशन तथा रोलबैक की व्याख्या करें।
इंटरव्यूअर क्या जांच रहा है
- क्या आप कॉन्ट्रैक्ट एक्सप्रेशन्स को टेस्ट असर्शन्स, एक्सेप्शन हैंडलिंग और अनडिफाइन्ड बिहेवियर से अलग पहचानते हैं।
- क्या आप स्टैंडर्ड, कंपाइलर, लिंकर, रनटाइम मोड और ABI के आर-पार कम्पैटिबिलिटी सीमाओं की पहचान करते हैं।
- क्या आप रिलीज़ डिज़ाइन में वॉयलेशन हैंडलिंग, परफॉर्मेंस कॉस्ट और प्रोडक्शन सेफ्टी को शामिल करते हैं।
- क्या आप वन-शॉट रीराइट के बजाय छोटे माइग्रेशन और अवलोकनीय साक्ष्यों के साथ किसी लैंग्वेज फीचर को आगे बढ़ा सकते हैं।
पहले पूछे जाने वाले स्पष्टीकरण प्रश्न
- कंपाइलर, स्टैंडर्ड-लाइब्रेरी, बिल्ड-सिस्टम और टारगेट-प्लेटफ़ॉर्म का कौन सा मैट्रिक्स मौजूद है, और किन टारगेट्स को पुराने वर्जन्स बनाए रखने होंगे?
- क्या कॉन्ट्रैक्ट्स पब्लिक APIs, इंटरनल मॉड्यूल सीमाओं या डेटा इनवेरिएंट्स के लिए हैं? क्या किसी वॉयलेशन पर टर्मिनेट होना चाहिए, लॉग होना चाहिए, डिबगिंग पॉज़ होनी चाहिए या जारी रहना चाहिए?
- कोर सर्विसेज के लिए ऑनलाइन परफॉर्मेंस बजट, इंसिडेंट रेट, रोलबैक मेथड और सिम्बॉलिकेशन क्षमता क्या हैं?
- क्या असर्शन्स, टेस्ट्स, स्टैटिक एनालिसिस और रिलीज़ गेट्स पहले से ही एक माइग्रेशन बेसलाइन प्रदान करते हैं?
30-सेकंड का उत्तर
मैं Contracts को इंटरफ़ेस सिमेंटिक्स और डायग्नोस्टिक्स के रूप में मानूँगा, न कि सभी टेस्ट्स या एक्सेप्शन हैंडलिंग के रिप्लेसमेंट के रूप में। सबसे पहले मैं कंपाइलर सपोर्ट को मैप करूँगा, फिर एक इंटरनल लाइब्रेरी पर पायलट टेस्ट करूँगा और इनेबल्ड, डिसेबल्ड और वॉयलेशन-हैंडलिंग मोड्स की तुलना करूँगा। पब्लिक हेडर्स को पुराने कंपाइलर्स द्वारा कंडीशनल या कॉन्ट्रैक्ट-डिसेबल्ड पाथ के ज़रिए इस्तेमाल योग्य बने रहना चाहिए। मैं इंटरनल APIs से क्रिटिकल सर्विसेज की ओर माइग्रेट करूँगा, जिसमें बिल्ड सक्सेस, वॉयलेशन्स, लेटेंसी और बाइनरी कम्पैटिबिलिटी को मापा जाएगा। हर ऑनलाइन वॉयलेशन के लिए एक स्पष्ट पॉज़ और रोलबैक पाथ की आवश्यकता होती है।
डीप डाइव
1. कॉन्ट्रैक्ट जिस समस्या को हल करता है उसे परिभाषित करें
प्रीकंडीशन्स इनपुट दायित्वों का वर्णन करती हैं, पोस्टकंडीशन्स यह बताती हैं कि रिटर्न पर क्या सत्य होना चाहिए, और इनवेरिएंट्स ऑब्जेक्ट की स्थिति को सीमित करते हैं। वे इंटरफ़ेस सीमा पर मान्यताओं को रखते हैं, लेकिन बिज़नेस-एरर हैंडलिंग, अस्पष्ट इनपुट के लिए ग्रेसफुल व्यवहार, या संपूर्ण टेस्ट्स की जगह नहीं लेते हैं। हर इम्प्लीमेंटेशन डिटेल को उजागर करने के बजाय उन क्रॉस-मॉड्यूल बाधाओं से शुरुआत करें जिनका अनुमान कॉलर्स आसानी से नहीं लगा सकते।
2. टूलचेन और ABI सीमा को मैप करें
कंपाइलर वर्जन्स, स्टैंडर्ड लाइब्रेरीज़, लैंग्वेज मोड्स, लिंकर्स, प्लेटफ़ॉर्म्स और बिल्ड कॉन्फ़िगरेशन्स की सूची बनाएं। प्रत्येक के लिए पार्सिंग, कोड जनरेशन, वॉयलेशन-हैंडलिंग सपोर्ट और डिबग जानकारी को सत्यापित करें। पब्लिक हेडर में नया सिंटैक्स पुराने कंपाइलर को तुरंत फेल कर सकता है; यहाँ तक कि सफल बिल्ड भी अलग-अलग रनटाइम मोड्स में अलग तरह से डायग्नोस कर सकते हैं। कंडीशनल-बिल्ड सीमाओं को चुनने से पहले कैपेबिलिटी डिटेक्शन और एक न्यूनतम सैंपल का उपयोग करें।
3. वॉयलेशन-हैंडलिंग रणनीति चुनें
वॉयलेशन हैंडलिंग सर्विस रिस्क से मेल खानी चाहिए। डेवलपमेंट बिल्ड्स स्टैक ट्रेस के साथ रुक सकते हैं; टेस्ट बिल्ड्स को टेस्ट फेल करना चाहिए; प्रोडक्शन बिल्ड्स कॉन्ट्रैक्ट की गंभीरता के आधार पर सुरक्षित रूप से टर्मिनेट हो सकते हैं, रिक्वेस्ट को आइसोलेट कर सकते हैं, या रिकॉर्ड करके जारी रख सकते हैं। जारी रखने से यह तथ्य नहीं छिपना चाहिए कि स्थिति अविश्वसनीय हो सकती है। रिकॉर्ड्स में संवेदनशील डेटा उजागर किए बिना कॉन्ट्रैक्ट लोकेशन, इनपुट सारांश और वर्ज़न शामिल होना चाहिए।
4. सिमेंटिक्स और साइड इफेक्ट्स का मूल्यांकन करें
कॉन्ट्रैक्ट एक्सप्रेशन्स साइड-इफेक्ट फ्री, दोहराए जाने योग्य और अनडिफाइन्ड इवैल्यूएशन ऑर्डर से स्वतंत्र होने चाहिए। टीम को यह पता होना चाहिए कि एक्सप्रेशन्स का मूल्यांकन इनेबल्ड, डिसेबल्ड या वैकल्पिक चेकिंग मोड्स में किया जा रहा है या नहीं और क्या हैंडलिंग कंट्रोल फ्लो को बदलती है। किसी कॉन्ट्रैक्ट में स्टेट म्यूटेशन, नेटवर्क कॉल्स या टाइमिंग डिपेंडेंसीज़ न डालें; उन व्यवहारों को इम्प्लीमेंटेशन और टेस्ट्स में रखें।
5. चरणबद्ध माइग्रेशन और कम्पैटिबिलिटी लेयर्स डिज़ाइन करें
एक कंपाइलर और CI टारगेट पर नॉन-पब्लिक लाइब्रेरीज़, प्योर फंक्शन्स और हाई-वैल्यू इनवेरिएंट्स से शुरुआत करें। पब्लिक APIs पुराने फ्लीट को कंपाइल रखने के लिए वर्जन्ड हेडर्स, कंडीशनल बिल्ड्स या मैक्रोज़ का उपयोग कर सकते हैं, लेकिन मैक्रोज़ को अलग-अलग बिज़नेस सिमेंटिक्स को छिपाने के बजाय कैपेबिलिटी अंतरों को हैंडल करना चाहिए। प्रत्येक विस्तार के लिए कवर्ड फंक्शन्स, सपोर्ट मैट्रिक्स और अन-माइग्रेटेड कॉलर्स को रिकॉर्ड करें।
6. विस्तार करने या रोल बैक करने के लिए साक्ष्य का उपयोग करें
बिल्ड टाइम, बाइनरी साइज, क्रिटिकल-पाथ लेटेंसी, कॉन्ट्रैक्ट वॉयलेशन्स, क्रैशेस और टेस्ट डिफेक्ट्स के लिए माइग्रेशन से पहले की बेसलाइन स्थापित करें। कैनरी के दौरान, पहले और बाद में समान ट्रैफ़िक और इनपुट डिस्ट्रीब्यूशन की तुलना करें, जिसमें वास्तविक इनपुट समस्याओं, कोड डिफेक्ट्स और टूलचेन फॉल्स पॉजिटिव्स को अलग किया जाए। यदि वॉयलेशन्स क्रिटिकल पाथ्स पर केंद्रित होते हैं, परफॉर्मेंस बजट से अधिक हो जाती है, या कोई पुराना टारगेट विश्वसनीयता से बिल्ड नहीं हो पाता है, तो माइग्रेशन रोकें, नए सिंटैक्स पाथ को डिसेबल करें, और पिछले बिल्ड आर्टिफैक्ट को रीस्टोर करें।
एक संपूर्ण और मजबूत उत्तर
मैं कंपाइलर्स, स्टैंडर्ड लाइब्रेरीज़, लैंग्वेज मोड्स, प्लेटफ़ॉर्म्स और रनटाइम मोड्स की इन्वेंट्री बनाऊँगा और प्रत्येक टारगेट के लिए C++26 Contracts पार्सिंग और वॉयलेशन हैंडलिंग को सत्यापित करूँगा। इंटरनल प्योर फंक्शन्स और स्पष्ट इनवेरिएंट्स से शुरुआत करें; कॉन्ट्रैक्ट्स का उपयोग इंटरफ़ेस डॉक्यूमेंटेशन और डायग्नोस्टिक्स के रूप में करें, न कि एक्सेप्शन्स, ग्रेसफुल डिग्रेडेशन या टेस्ट्स के रिप्लेसमेंट के रूप में। डेवलपमेंट और टेस्ट बिल्ड्स को जल्दी फेल (fail fast) होने दें, जबकि प्रोडक्शन जोखिम के आधार पर सेफ टर्मिनेशन, आइसोलेशन या लॉगिंग को चुने और सीक्रेट्स को रिकॉर्ड्स से बाहर रखे। कैपेबिलिटी डिटेक्शन और कंडीशनल बिल्ड्स के साथ पुरानी फ्लीट के कंपाइलेशन को सुरक्षित रखें। बिल्ड सक्सेस, लेटेंसी, बाइनरी चेंजेज, वॉयलेशन रेट और क्रैशेस के आधार पर कैनरी को गेट करें, और किसी भी हाई-रिस्क उल्लंघन पर रोकें और रोल बैक करें।
सामान्य विफलता मोड
- Contracts को असर्शन्स, एक्सेप्शन्स या टेस्ट्स के पूर्ण रिप्लेसमेंट के रूप में मानना।
- कंपाइलर, स्टैंडर्ड-लाइब्रेरी, लिंकर और ABI मैट्रिक्स के बिना केवल “C++26 में अपग्रेड करें” कहना।
- यह अनदेखा करना कि चेकिंग मोड्स और वॉयलेशन हैंडलिंग कंट्रोल फ्लो, परफॉर्मेंस और ऑनलाइन सुरक्षा को कैसे प्रभावित करते हैं।
- कॉन्ट्रैक्ट में साइड-इफेक्ट वाले ऑपरेशन्स डालना जिससे डायग्नोस्टिक्स प्रोग्राम के व्यवहार को बदल दें।
- बेसलाइन, कैनरी या रोलबैक के बिना केवल सफल कंपाइल के बाद विस्तार करना।
फॉलो-अप और विस्तार
फॉलो-अप 1: क्या कॉन्ट्रैक्ट वॉयलेशन पर एक्सेप्शन थ्रो होना चाहिए?
इसका कोई सार्वभौमिक उत्तर नहीं है। वॉयलेशन का अर्थ है कि प्रोग्राम स्टेट या कॉलिंग कन्वेंशन टूट गया था। सुरक्षित रिकवरी क्षमता, क्या एक्सेप्शन्स ABI सीमा को पार करते हैं, और टीम की एरर पॉलिसी के आधार पर चयन करें। अन-रिकवरेबल स्थिति के लिए, जारी रखना या सामान्य एक्सेप्शन का उपयोग करना किसी बड़ी विफलता को छिपा सकता है।
फॉलो-अप 2: आप पुराने कंपाइलर्स का सपोर्ट कैसे करते हैं?
पहले पुष्टि करें कि क्या पब्लिक हेडर्स को उनके द्वारा पार्स किया जाना आवश्यक है। कैपेबिलिटी डिटेक्शन, कंडीशनल बिल्ड्स या कम्पैटिबिलिटी मैक्रोज़ पुराने टारगेट्स को कॉन्ट्रैक्ट-डिसेबल्ड पाथ के ज़रिए भेज सकते हैं, लेकिन समकक्ष टेस्ट्स और डॉक्यूमेंटेशन बनाए रखें ताकि बिज़नेस सिमेंटिक्स में भिन्नता न आए।
फॉलो-अप 3: क्या कॉन्ट्रैक्ट्स प्रोडक्शन को धीमा कर देंगे?
अनुमान लगाने के बजाय मापें। चेकिंग मोड्स, ऑप्टिमाइज़ेशन लेवल्स और इनपुट डिस्ट्रीब्यूशन्स में CPU, लेटेंसी और बाइनरी परिवर्तनों की तुलना करें। महंगे चेक्स को डेवलपमेंट, टेस्ट्स या छोटे कैनरी तक सीमित रखें, जबकि क्रिटिकल इनवेरिएंट्स के लिए लो-कॉस्ट मॉनिटरिंग बनाए रखें।
फॉलो-अप 4: आप कॉन्ट्रैक्ट के दुरुपयोग को कैसे रोकते हैं?
नियम निर्धारित करें: केवल सत्यापन योग्य इनवेरिएंट्स और बाउंड्री मान्यताओं को व्यक्त करें, साइड इफेक्ट्स को प्रतिबंधित करें, वॉयलेशन और संवेदनशील डेटा हैंडलिंग को डॉक्यूमेंट करें, और कोड रिव्यू में उनकी समीक्षा करें। प्रत्येक कॉन्ट्रैक्ट के लिए टेस्ट्स, एक ओनर और हटाने या संशोधन की शर्त की आवश्यकता होती है।