प्रतिनिधि इंटरव्यू विषय

सामान्य इंटरव्यू: Iterator.concat लेज़ी डेटा स्रोतों को कैसे संयोजित (compose) करता है?

सामान्यकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

एक लेज़ी इटेरेटर लागू करें जो एक ऐरे, एक Set, और एक जनरेटर को जोड़ता है, फिर Iterator.concat, Array.concat, Iterator.from और flatMap के बीच की सीमाओं को स्पष्ट करें।

1. प्रश्न और दायरा

एक लॉग एग्रीगेटर प्राथमिकता के क्रम में इन-मेमोरी ऐरे, एक डुप्लीकेट-रहित Set और एक पेजिनेटेड जनरेटर को पढ़ता है; उपभोक्ता को केवल पहले 100 रिकॉर्ड की आवश्यकता होती है। लेज़ीनेस (laziness) को बनाए रखते हुए Iterator.concat का उपयोग करें, और उपभोग समय से पहले रुकने पर अनंत इनपुट, अपवाद (exceptions) और क्लीनअप की व्याख्या करें।

2. इंटरव्यूअर क्या परख रहा है

  • Iterable को Iterator से अलग पहचानना और यह जानना कि Iterator.concat के लिए Iterable तर्कों (arguments) की आवश्यकता होती है।
  • यह समझाना कि परिणाम एक नया लेज़ी Iterator होता है जो उपभोग किए जाने पर ही इनपुट को क्रम में खींचता है।
  • यह पहचानना कि एक अनंत स्रोत बाद के प्रत्येक स्रोत को छिपा देता है और तर्क सूची सीमित (finite) रहनी चाहिए।
  • return क्लीनअप, TypeError के मामलों, अनुकूलता फ़ॉलबैक और अनावश्यक ऐरे भौतिकीकरण को संभालना।

3. पहले स्पष्ट करने योग्य सवाल

  1. क्या प्रत्येक इनपुट एक दोहराया जा सकने वाला Iterable है या पहले से आगे बढ़ चुका एकल-उपयोग (single-use) Iterator है?
  2. क्या उपभोक्ता को सीमा पर स्ट्रीमिंग इंटरफ़ेस चाहिए या ऐरे की आवश्यकता है?
  3. क्या किसी इनपुट के पास कोई फ़ाइल, नेटवर्क या डेटाबेस कर्सर है जिसे जल्दी रुकने पर बंद होना चाहिए?
  4. क्या लक्षित ब्राउज़र और Node नेटिव Iterator.concat प्रदान करते हैं, या पॉलीफ़िल की अनुमति है?

4. तीस सेकंड का उत्तर

मैं यह सत्यापित करूँगा कि प्रत्येक तर्क Symbol.iterator को लागू करता है, फिर Iterator.concat के साथ एक लेज़ी Iterator बनाऊँगा। यह प्रत्येक इनपुट को क्रम से प्राप्त करता है और मानों को केवल तभी पढ़ता है जब उपभोक्ता next, take को कॉल करता है, या परिणाम को स्प्रेड करता है। take(100) खींचना बंद कर देता है और अंतर्निहित इटेरेटर को बंद होने का अवसर देता है। अनंत इनपुट को अंत में रखें या उपभोग को सीमित करें; पुराने रनटाइम पर, समान लेज़ीनेस और क्लीनअप सेमेंटिक्स वाले जनरेटर फ़ॉलबैक का उपयोग करें।

5. चरण-दर-चरण गहन विश्लेषण

चरण 1: Iterable सीमा स्थापित करें

Iterator.concat केवल next वाले ऑब्जेक्ट्स को ही नहीं, बल्कि Iterables को स्वीकार करता है। ऐरे, Sets और जनरेटर ऑब्जेक्ट इसके योग्य हैं। एक सामान्य Iterator को पहले Iterator.from के साथ लपेटा जाना चाहिए; यह concat को प्रत्येक इनपुट इटेरेटर को प्राप्त करने और बंद करने का एक स्पष्ट तरीका देता है।

चरण 2: लेज़ी कंपोज़िशन बनाएँ

js
function* pages() {
  yield { source: "page", id: 1 };
  yield { source: "page", id: 2 };
}

const memory = [{ source: "memory", id: 1 }];
const unique = new Set([{ source: "set", id: 1 }, { source: "set", id: 2 }]);
const merged = Iterator.concat(memory, unique, pages());
const firstThree = merged.take(3).toArray();

merged बनाना किसी भी इनपुट को पार (traverse) नहीं करता है; toArray उपभोग शुरू करता है। मान मेमोरी, Set और पेजों के क्रम में उत्सर्जित होते हैं, और concat उन्हें डुप्लीकेट-मुक्त या रूपांतरित नहीं करता है।

चरण 3: उपभोग की स्थिति (consumption state) को समझें

लौटाया गया Iterator वर्तमान इनपुट और स्थिति को संग्रहीत करता है। एक उपभोक्ता द्वारा इसे आगे बढ़ाने के बाद, दूसरे उपभोक्ता को केवल शेष भाग ही दिखाई देता है। पुनः चलाने के लिए स्रोत Iterables से नए Iterators की आवश्यकता होती है। यदि केवल पहले N मानों की आवश्यकता है, तो पहले स्प्रेड करने के बजाय concat के बाद take लागू करें।

चरण 4: अनंत इनपुट को सीमित करें

कोई भी इनपुट अनंत हो सकता है, जिससे परिणाम अनंत हो जाता है। यदि पहला इनपुट कभी समाप्त नहीं होता है, तो बाद के इनपुट अगम्य हो जाते हैं; परिमित बैचों को पहले रखें या उपभोक्ता सीमा पर take, टाइमआउट और रद्दीकरण लागू करें। Iterator.concat(...infiniteIterables()) न लिखें, क्योंकि तर्क सूची को स्प्रेड करना कभी समाप्त नहीं होता है।

चरण 5: क्लीनअप, त्रुटियाँ और फ़ॉलबैक

जब उपभोग रुक जाता है या कोई त्रुटि आती है, तो वर्तमान इटेरेटर को return चलाने का अवसर मिलना चाहिए, जिससे कर्सर, फ़ाइल हैंडल या कनेक्शन मुक्त हो सकें। एक कस्टम इटेरेटर finally में क्लीनअप रिकॉर्ड कर सकता है। नेटिव समर्थन के बिना रनटाइम पर, एक जनरेटर इनपुट को क्रम में yield* कर सकता है और return का प्रसार कर सकता है; फ़ॉलबैक को प्रत्येक इनपुट को चुपचाप ऐरे में कॉपी नहीं करना चाहिए।

6. मॉडल उच्च-गुणवत्ता वाला उत्तर

मैं Iterable इनपुट को मान्य करूँगा, Iterator.concat के साथ एक लेज़ी कंपोज़िशन बनाऊँगा, और केवल उपभोक्ता सीमा पर take(100) या toArray को कॉल करूँगा। concat इनपुट को क्रम में प्राप्त करता है और उनके मानों को डुप्लीकेट-मुक्त नहीं करता है। एक अनंत पहला इनपुट बाद के स्रोतों को अगम्य बना देता है, इसलिए मैं उपभोग को सीमित करूँगा और return के माध्यम से जल्दी रुकने वाले क्लीनअप का परीक्षण करूँगा। पुराने रनटाइम के लिए, एक जनरेटर फ़ॉलबैक स्रोतों को भौतिक रूप दिए बिना लेज़ीनेस, ऑर्डरिंग, सिंगल-यूज़ स्थिति और क्लीनअप को बनाए रख सकता है।

7. सामान्य गलतियाँ

  • केवल next वाले ऑब्जेक्ट को पास करना → TypeError → इसे Iterator.from के साथ लपेटें या Symbol.iterator लागू करें।
  • यह मान लेना कि concat तुरंत निष्पादित होता है → छिपा हुआ I/O → याद रखें कि उपभोग मानों को खींचता है।
  • एक अनंत Iterable को पहले रखना → बाद के स्रोत कभी नहीं पहुँचते → क्रम बदलें और उपभोग को सीमित करें।
  • सब कुछ पहले स्प्रेड करना → मेमोरी और लेटेंसी स्पाइक्स → केवल एक स्पष्ट ऐरे सीमा पर toArray को कॉल करें।
  • जल्दी रुकने वाले return को अनदेखा करना → लीक हुए कर्सर → एक काउंटिंग Iterable का परीक्षण करें और क्लीनअप का दावा (assert) करें।

8. फ़ॉलो-अप सवाल

फ़ॉलो-अप 1: यह Array.concat से किस प्रकार भिन्न है?

ऐरे concat तुरंत भौतिकीकृत ऐरे को प्रोसेस करता है और एक ऐरे लौटाता है। Iterator.concat Iterables को स्वीकार करता है और एक लेज़ी Iterator लौटाता है जो जनरेटर और अनंत स्रोतों का प्रतिनिधित्व कर सकता है।

फ़ॉलो-अप 2: प्रत्येक Iterator को सीधे क्यों नहीं पास करते?

एक सामान्य Iterator जो Iterable नहीं है, वह उन इनपुट के स्वामित्व और बंद होने को अस्पष्ट छोड़ देता है जिन तक अभी तक नहीं पहुँचा गया है। Iterable सीमा स्थापित करने के लिए इसे Iterator.from के साथ लपेटें।

फ़ॉलो-अप 3: flatMap कब बेहतर होता है?

जब इनपुट स्वयं Iterables का एक बड़ा या असीमित क्रम होता है, तो flatMap उन्हें क्रमिक रूप से उत्पन्न और समतल (flatten) कर सकता है। इनपुट के एक परिमित, ज्ञात सेट के लिए concat अधिक स्पष्ट है।

फ़ॉलो-अप 4: आप क्लीनअप को कैसे सत्यापित करते हैं?

next और return को लागू करने वाले एक परीक्षण Iterable का उपयोग करें, पुल्स और क्लोज़ को रिकॉर्ड करें, और यह सुनिश्चित करें कि take, उपभोक्ता रुकावट और कॉलबैक त्रुटियाँ खींचना बंद कर दें और return को कॉल करें।

सार्वजनिक स्रोत

संबंधित प्रश्न