प्रॉम्प्ट और संदर्भ
एक सर्विस प्रति सेकंड कई छोटे संदेशों को पार्स करती है। इसका वर्तमान पथ std::string_view को std::istringstream में कॉपी करता है और std::ostringstream के साथ रिस्पॉन्स बनाता है, जिससे एलोकेशन और पीक-मेमोरी की लागत बढ़ती है। C++23 spanstream हेडर का मूल्यांकन करें और इनपुट, आउटपुट और पुराने टूलचेन पथ डिज़ाइन करें।
इंटरव्यूअर क्या मूल्यांकन करता है
- यह जानना कि spanstream कॉलर द्वारा प्रदान किए गए
std::spanका उपयोग करता है और स्टोरेज का मालिक नहीं होता है। - रीड-ओनली
ispanstream, राइटेबलospanstream, और फिक्स्ड-कैपेसिटी राइट विफलता के बीच अंतर करना। - व्यू लाइफटाइम, स्टेट बिट्स, ट्रंकेशन, और थ्रेड्स के बीच ओनरशिप को संभालना।
- फीचर टेस्ट और बेंचमार्क के माध्यम से प्रोटोकॉल सिमेंटिक्स को बदले बिना कम एलोकेशन को साबित करना।
स्पष्टीकरण के लिए प्रश्न
- क्या इनपुट बफर पार्सिंग के दौरान अपरिवर्तित और सक्रिय रहता है?
- आउटपुट सीमा क्या है, और क्या बफर भरने पर विफल होना चाहिए, ट्रंकेट होना चाहिए, या किसी अन्य बफर का अनुरोध करना चाहिए?
- क्या लक्षित कंपाइलर और मानक लाइब्रेरी
__cpp_lib_spanstreamको लागू करते हैं? - क्या पार्सिंग को प्रारूप त्रुटि, EOF, रेंज समाप्ति, और संख्यात्मक ओवरफ्लो में अंतर करना चाहिए?
- क्या बफर को थ्रेड्स में साझा किया जाता है या ज़ीरो-कॉपी डिलीवरी के लिए एसिंक्रोनस रूप से रखा जाता है?
30-सेकंड का उत्तर
spanstream एक स्ट्रीम बफर को मौजूदा कैरेक्टर स्टोरेज से जोड़ता है, इसलिए जब लाइफटाइम और कैपेसिटी स्पष्ट होती हैं तो यह एक मध्यवर्ती स्ट्रिंग से बच सकता है। इनपुट के लिए std::ispanstream और आउटपुट के लिए std::ospanstream का उपयोग करें; जब आउटपुट स्पैन भर जाए तो fail() या bad() की जांच करें क्योंकि कोई स्वचालित वृद्धि नहीं मानी जाती है। API स्टोरेज उधार लेता है और उसे डैंगलिंग व्यूज नहीं लौटाने चाहिए। __cpp_lib_spanstream का पता लगाएं, समान एरर अनुबंध के साथ कर्सर या नियंत्रित-स्ट्रिंग फ़ॉलबैक प्रदान करें, और एलोकेशन तथा थ्रूपुट को मापने के बाद ही स्वीकार करें।
गहराई से उत्तर
चरण 1: ओनरशिप को परिभाषित करें
Spanstream अपने ऐरे का मालिक नहीं होता है। कॉलर इनपुट स्पैन को तब तक सक्रिय रखता है जब तक कि स्ट्रीम और प्रत्येक पार्स किया गया व्यू समाप्त नहीं हो जाता। आउटपुट स्पैन राइटेबल होना चाहिए, इसके तत्व प्रकार के लिए सही ढंग से संरेखित होना चाहिए, और स्पष्ट रूप से आकार का होना चाहिए। कभी भी अस्थायी स्ट्रिंग का व्यू एसिंक्रोनस कार्य को न दें।
चरण 2: इनपुट पार्सिंग डिज़ाइन करें
std::ispanstream स्वरूपित निष्कर्षण प्रदान करता है लेकिन फिर भी स्ट्रीम स्थिति नियमों का पालन करता है। फ़ील्ड के बाद good(), eof(), fail(), और bad() की जांच करें ताकि फॉर्मेट विफलता को इनपुट के सामान्य अंत के साथ भ्रमित न किया जाए। व्यावसायिक सत्यापन अभी भी संख्यात्मक सीमाओं और फ़ील्ड की लंबाई को लागू करता है।
चरण 3: फिक्स्ड-कैपेसिटी आउटपुट डिज़ाइन करें
std::ospanstream कॉलर के स्पैन में लिखता है। ऊपरी सीमा का अनुमान लगाएं या काउंटिंग पास का उपयोग करें, फिर लिखने के बाद स्थिति का निरीक्षण करें। भरा हुआ बफर एक संरचित कैपेसिटी त्रुटि लौटाता है; इसे चुपचाप प्रोटोकॉल संदेश को ट्रंकेट नहीं करना चाहिए। यदि वृद्धि की आवश्यकता है, तो ओनर एक बड़ा स्पैन आवंटित करता है और संदेश को पुनर्जीवित करता है।
चरण 4: ज़ीरो-कॉपी व्यूज को संभालें
एक std::string_view परिणाम इनपुट स्पैन से जुड़ा होता है। कतार में लगाने या थ्रेड सीमा पार करने से पहले, आवश्यक फ़ील्ड कॉपी करें या ओनर ऑब्जेक्ट स्थानांतरित करें। आउटपुट के बाद, span() या इसके समकक्ष के माध्यम से लिखित क्षेत्र प्राप्त करें, और उपभोक्ताओं के लिए समान ओनर सीमा बनाए रखें।
चरण 5: त्रुटि और सुरक्षा सीमाएं निर्धारित करें
दुर्भावनापूर्ण स्कैन को रोकने के लिए प्रत्येक फ़ील्ड, पूर्णांक सीमा और कुल पार्स चरण को सीमित करें। स्ट्रीम स्थितियों को प्रोटोकॉल त्रुटियों में मैप करें और लॉग में संवेदनशील पेलोड की प्रतिलिपि बनाए बिना एक ऑफ़सेट और अनुरोध आईडी लॉग करें।
चरण 6: पुराने टूलचेन के लिए फ़ॉलबैक प्रदान करें
__cpp_lib_spanstream का पता लगाएं। सक्षम बिल्ड spanstream का उपयोग करते हैं; अन्य एक ऑडिट किए गए कर्सर पार्सर या एक नियंत्रित स्ट्रिंग बफर का उपयोग करते हैं। दोनों पथ फ़ील्ड सीमाएं, त्रुटि वर्ग और गोल्डन इनपुट साझा करते हैं ताकि केवल कार्यान्वयन बदले।
चरण 7: लाभ को सत्यापित करें
एलोकेशन, पीक आरएसएस, थ्रूपुट, टेल लेटेंसी, एरर रेट, और आउटपुट बाइट्स पर पुराने पथ, spanstream और फ़ॉलबैक की तुलना करें। खाली इनपुट, सटीक क्षमता, बड़े आकार के फ़ील्ड, गैर-ASCII डेटा, ट्रंकेशन, अपवाद निकास, और समवर्ती ओनरशिप का परीक्षण करें। प्रोटोकॉल जांच को कमजोर करके बेंचमार्क जीत हासिल न करें।
मॉडल उत्तर
मैं इनपुट और आउटपुट के स्वामित्व को कॉलर के पास रखता हूं। पार्सर const वर्णों के std::span को स्वीकार करता है और फ़ॉर्मेटर एक राइटेबल स्पैन स्वीकार करता है। इनपुट std::ispanstream का उपयोग करता है, प्रत्येक फ़ील्ड के बाद स्थिति की जांच करता है, और लंबाई तथा संख्यात्मक सीमाएं लागू करता है। आउटपुट std::ospanstream का उपयोग करता है; लिखने के बाद यह fail() की जांच करता है और ट्रंकेट करने के बजाय पुन: प्रयास करने योग्य कैपेसिटी त्रुटि लौटाता है। लौटाए गए व्यू तभी तक मान्य होते हैं जब तक ओनर जीवित रहता है, इसलिए एक कतारबद्ध संदेश फ़ील्ड को कॉपी करता है। __cpp_lib_spanstream कार्यान्वयन का चयन करता है, जबकि एक पुराना टूलचेन उसी अनुबंध के साथ कर्सर पथ का उपयोग करता है। मैं कैनरी से पहले एलोकेशन, p99 लेटेंसी और त्रुटियों की तुलना करता हूं।
सामान्य गलतियाँ
- यह मान लेना कि spanstream अंतर्निहित स्पैन का मालिक है या उसे बढ़ाता है।
- कॉलर द्वारा बफ़र नष्ट करने के बाद संदर्भ या स्ट्रिंग व्यू लौटाना।
- पूर्ण लेखन के बाद
fail()को अनदेखा करना और ट्रंकेट किया गया पैकेट उत्सर्जित करना। - सफलता घोषित करने के लिए केवल
eof()का उपयोग करना, जिससे प्रारूप और रेंज की विफलताएं छूट जाती हैं। - केवल नए लाइब्रेरी पथ का परीक्षण करना और फ़ॉलबैक सिमेंटिक्स को भटकने देना।
फॉलो-अप प्रश्न और उत्तर
फॉलो-अप 1: क्या spanstream हमेशा एलोकेशन-मुक्त होता है?
यह एक अतिरिक्त स्ट्रीम-बफर आवंटन से बचाता है, लेकिन फ़ॉर्मेटिंग, लोकेल और व्यावसायिक अस्थायी चीजें अभी भी आवंटित हो सकती हैं। प्रकार के नाम से अनुमान लगाने के बजाय वास्तविक कार्यभार के तहत आवंटन गणना को मापें।
फॉलो-अप 2: क्या होगा यदि आउटपुट स्पैन बहुत छोटा है?
प्रोटोकॉल सीमा का अनुमान लगाएं और लिखने के बाद स्थिति की जांच करें। एक स्पष्ट कैपेसिटी त्रुटि लौटाएं ताकि ओनर एक बड़ा बफ़र आवंटित कर सके और पुनर्जीवित कर सके; आंशिक रूप से न भेजें और बाद में न जोड़ें।
फॉलो-अप 3: पार्स किए गए परिणाम थ्रेड्स को सुरक्षित रूप से कैसे पार कर सकते हैं?
एक स्वामित्व वाला संदेश ऑब्जेक्ट ले जाएं या आवश्यक फ़ील्ड की प्रतिलिपि बनाएँ। केवल स्ट्रिंग व्यू पास करना इनपुट बफ़र लाइफटाइम को शेड्यूलिंग से जोड़ता है और असुरक्षित है।
फॉलो-अप 4: आप spanstream से कब बचेंगे?
डायनामिक वृद्धि, रैंडम एक्सेस, जटिल एसिंक्रोनस I/O, या लंबे समय तक रहने वाले परिणामों के लिए स्पष्ट स्ट्रिंग्स या कंटेनर चुनें। Spanstream को केवल तभी जोड़ें जब फिक्स्ड-बफर माप स्ट्रीम-स्थिति जटिलता को सही ठहराते हैं।
फॉलो-अप 5: आप फ़ॉलबैक तुल्यता का परीक्षण कैसे करते हैं?
समान गोल्डन इनपुट, सीमाओं और इंजेक्ट की गई विफलताओं के साथ दोनों पथ चलाएं। फ़ील्ड, त्रुटि वर्गों, उपभोग किए गए ऑफ़सेट और आउटपुट बाइट्स की तुलना करें; अंतरों को रिलीज़ अवरोधक के रूप में मानें।