क्रमबद्धता को समझना


38

मैं एक सॉफ्टवेयर इंजीनियर हूं और कुछ सहयोगियों के साथ चर्चा के बाद, मुझे एहसास हुआ कि मेरे पास अवधारणा धारावाहिक का एक अच्छा समझ नहीं है। जैसा कि मैं समझता हूं, सीरियलाइज़ेशन कुछ इकाई को बदलने की प्रक्रिया है, जैसे कि ओओपी में एक वस्तु, बाइट्स के एक क्रम में, ताकि उक्त इकाई को बाद की पहुंच ("डिसेरिएलाइज़ेशन" की प्रक्रिया) के लिए संग्रहीत या प्रेषित किया जा सके।

मेरे पास जो परेशानी है वह यह है: सभी वेरिएबल्स (जैसे कि यह intया समग्र वस्तुएं आदिम नहीं हैं ) पहले से ही बाइट्स के अनुक्रम द्वारा दर्शाए गए हैं? (बेशक वे हैं, क्योंकि वे रजिस्टरों, मेमोरी, डिस्क, आदि में संग्रहीत हैं)

तो क्या धारावाहिकीकरण इतना गहरा विषय बनाता है? एक चर को अनुक्रमित करने के लिए, क्या हम इन बाइट्स को स्मृति में नहीं ले जा सकते हैं, और उन्हें एक फाइल पर लिख सकते हैं? मुझे क्या याद आती है?


21
क्रमिककरण सन्निहित वस्तुओं के लिए तुच्छ हो सकता है । जब ऑब्जेक्ट वैल्यू को पॉइंटर ग्राफ के रूप में दर्शाया जाता है , तो चीजें बहुत अधिक मुश्किल हो जाती हैं, खासकर अगर कहा जाए कि ग्राफ़ में लूप हैं।
चि

1
@ उचि: आपका पहला वाक्य थोड़ा भ्रामक है जो दी गई आकस्मिकता अप्रासंगिक है। आपके पास एक ऐसा ग्राफ़ हो सकता है जो स्मृति में निरंतर होता है और यह अभी भी आपको इसे क्रमबद्ध करने में मदद नहीं करेगा क्योंकि आपको अभी भी (ए) यह पता लगाना है कि यह वास्तव में सन्निहित होने के लिए होता है, और (बी) अंदर बिंदुओं को ठीक करता है। मैं सिर्फ इतना कहूंगा कि आपने जो कहा है उसका दूसरा भाग।
मेहरदाद

@ मेहरदाद मैं मानता हूं कि मेरी टिप्पणी आपके द्वारा उल्लिखित कारणों के लिए पूरी तरह से सटीक नहीं है। शायद सूचक-मुक्त / पॉइंटर का उपयोग करना एक बेहतर अंतर है (भले ही पूरी तरह से सटीक नहीं है, या तो)
ची

7
आपको हार्डवेयर पर प्रतिनिधित्व के बारे में भी चिंता करनी होगी। अगर मैं 4 bytesअपने PDP-11 पर एक इंटिरियर को क्रमबद्ध करता हूं और फिर मेरी मैकबुक पर उन्हीं चार बाइट्स को मेमोरी में पढ़ने की कोशिश करता हूं तो वे एक ही नंबर (एंडियन की वजह से) नहीं हैं। तो आपको डेटा को एक प्रतिनिधित्व के लिए सामान्य करना होगा जिसे आप डी-कोड कर सकते हैं (यह क्रमांकन है)। आप डेटा को क्रमबद्ध कैसे करते हैं इसमें भी ट्रेडऑफ़ गति / लचीलापन मानव / मशीन पठनीय है।
मार्टिन यॉर्क

क्या होगा यदि आप कई गहराई से जुड़े नेविगेशन गुणों के साथ एंटिटी फ्रेमवर्क का उपयोग कर रहे हैं? एक मामले में, आप एक नेविगेशन संपत्ति को क्रमबद्ध करना चाह सकते हैं, लेकिन दूसरे में इसे शून्य छोड़ दें (क्योंकि आप उस धारावाहिक से डेटाबेस पर आधारित वास्तविक वस्तु को फिर से लोड करेंगे जो आपके क्रमबद्ध मूल ऑब्जेक्ट में है)। यह तो केवल एक उदाहरण है। वहां कई हैं।
एरिक

जवाबों:


40

यदि आपके पास एक जटिल डेटा संरचना है, तो मेमोरी में इसका प्रतिनिधित्व सामान्यतया पूरे मेमोरी में बिखरा हो सकता है। (उदाहरण के लिए, एक बाइनरी ट्री के बारे में सोचें।)

इसके विपरीत, जब आप इसे डिस्क पर लिखना चाहते हैं, तो आप शायद सन्निहित फल के एक (उम्मीद के मुताबिक) अनुक्रम के रूप में एक प्रतिनिधित्व करना चाहते हैं। यही क्रम आपके लिए करता है।


27

मेरे पास जो परेशानी है वह यह है: सभी वेरिएबल्स (जैसे कि यह इंटिमेट या कंपोजिट ऑब्जेक्ट्स की तरह प्रिमिटिव नहीं हैं) पहले से ही बाइट्स के अनुक्रम द्वारा दर्शाए गए हैं? (बेशक वे हैं, क्योंकि वे रजिस्टरों, मेमोरी, डिस्क, आदि में संग्रहीत हैं)

तो क्या धारावाहिकीकरण इतना गहरा विषय बनाता है? एक चर को अनुक्रमित करने के लिए, क्या हम इन बाइट्स को स्मृति में नहीं ले जा सकते हैं, और उन्हें एक फाइल पर लिख सकते हैं? मुझे क्या याद आती है?

इस रूप में परिभाषित नोड्स के साथ सी में एक वस्तु ग्राफ पर विचार करें:

struct Node {
    struct Node* parent;
    struct Node* someChild;
    struct Node* anotherLink;

    int value;
    char* label;
};

//

struct Node nodes[10] = {0};
nodes[5].parent = nodes[0];
nodes[0].someChild = calloc( 1, sizeof(struct Node) );
nodes[5].anotherLink = nodes[3];
for( size_t i = 3; i < 7; i++ ) {
    nodes[i].anotherLink = calloc( 1, sizeof(struct Node) );
}

रनटाइम के दौरान पूरे ऑब्जेक्ट Nodeग्राफ को मेमोरी स्पेस के आसपास बिखरा दिया जाएगा, और एक ही नोड को कई अलग-अलग नोड्स से इंगित किया जा सकता है।

आप बस किसी फ़ाइल / स्ट्रीम / डिस्क पर मेमोरी डंप नहीं कर सकते हैं और इसे क्रमबद्ध कह सकते हैं क्योंकि पॉइंटर मान (जो मेमोरी एड्रेस हैं) को डी-सीरीज़ नहीं किया जा सकता है (क्योंकि उन मेमोरी लोकेशन पर पहले से ही कब्जा हो सकता है जब आप डंप वापस लोड करते हैं स्मृति में)। मेमोरी डंप करने के साथ एक और समस्या यह है कि आप सभी प्रकार के अप्रासंगिक डेटा और अप्रयुक्त स्थान को समाप्त कर देंगे - x86 पर स्मृति अंतरिक्ष के 4GiB तक की प्रक्रिया होती है, और एक OS या MMU में केवल एक सामान्य विचार होता है कि मेमोरी वास्तव में क्या है। सार्थक या नहीं (एक प्रक्रिया को सौंपे गए मेमोरी पेजों के आधार पर), इसलिए Notepad.exeजब भी मैं किसी टेक्स्ट फ़ाइल को सहेजना चाहता हूं, मेरी डिस्क पर 4GB कच्ची बाइट्स डंप करना थोड़ा बेकार लगता है।

वर्जनिंग के साथ एक और समस्या है: क्या होता है यदि आप अपने Nodeग्राफ को 1 दिन पर क्रमबद्ध करते हैं, तो दिन 2 पर आप एक अन्य फ़ील्ड को जोड़ते हैं Node(जैसे कि एक अन्य पॉइंटर वैल्यू, या एक आदिम मूल्य), तो दिन 3 से आप अपनी फाइल को डी-सीरियल करते हैं। पहला दिन?

आपको अन्य चीजों पर भी विचार करना होगा, जैसे कि धीरज। 1980 और 1990 के दशक में MacOS और IBM / Windows / PC फाइलें एक-दूसरे के साथ असंगत होने के मुख्य कारणों में से एक ही कार्यक्रमों (वर्ड, फोटोशॉप, आदि) द्वारा अनायास संभव होने के बावजूद x86 / PC मल्टी-बायर्स पूर्णांक मानों पर आधारित थे। छोटे-एंडियन ऑर्डर में सहेजे गए थे, लेकिन मैक पर बड़े-एंडियन ऑर्डर - और सॉफ्टवेयर को क्रॉस-प्लेटफॉर्म पोर्टेबिलिटी को ध्यान में रखकर नहीं बनाया गया था। आजकल चीजें बेहतर हैं डेवलपर शिक्षा और हमारी बढ़ती विषम कंप्यूटिंग दुनिया के लिए धन्यवाद।


2
मेमोरी स्पेस में सब कुछ डंप करना सुरक्षा कारणों से भी भयानक होगा। एक प्रोग्राम नाइट में 1) कुछ पब्लिक डेटा और 2) पासवर्ड, सीक्रेट नॉन या प्राइवेट की दोनों मेमोरी होती है। पूर्व को क्रमबद्ध करते समय, कोई भी बाद की किसी भी जानकारी को प्रकट नहीं करना चाहता है।
ची

8
इस विषय पर एक बहुत ही दिलचस्प नोट: Microsoft Office फ़ाइल स्वरूप इतने जटिल क्यों हैं?
हड़ताली

15

मुश्किल वास्तव में पहले से ही शब्द में वर्णित है: " सीरियल ization"।

प्रश्न मूल रूप से है: मैं बाइट्स के रैखिक अनुक्रम के रूप में मनमाने ढंग से जटिल वस्तुओं के मनमाने ढंग से जटिल चक्रीय निर्देशित ग्राफ का प्रतिनिधित्व कैसे कर सकता हूं?

इसके बारे में सोचें: एक रेखीय अनुक्रम एक पतित डाइरेक्टेड ग्राफ की तरह है, जहां हर वर्टेक्स में एक इनकमिंग और आउटगोइंग एज होती है ("फर्स्ट वर्टेक्स" को छोड़कर जिसका कोई इनकमिंग एज नहीं है और "लास्ट वर्टेक्स" जिसका कोई आउटगोइंग एज नहीं है) । और एक बाइट स्पष्ट रूप से एक वस्तु की तुलना में कम जटिल है ।

इसलिए, यह उचित प्रतीत होता है कि जैसा कि हम एक मनमाने ढंग से जटिल ग्राफ से बहुत अधिक प्रतिबंधित "ग्राफ" (वास्तव में सिर्फ एक सूची) पर जाते हैं और मनमाने ढंग से जटिल वस्तुओं से साधारण बाइट्स तक, जानकारी खो जाएगी , अगर हम यह भोलेपन से करते हैं और ' t किसी तरह से "बाहरी" जानकारी को सांकेतिक शब्दों में बदलना। और यह वही है जो क्रमबद्धता करता है: जटिल जानकारी को एक सरल रैखिक प्रारूप में सांकेतिक शब्दों में बदलना।

यदि आप YAML से परिचित हैं , तो आप एंकर और अन्य उपनामों पर एक नज़र डाल सकते हैं जो आपको इस विचार का प्रतिनिधित्व करने की अनुमति देते हैं कि "एक ही वस्तु अलग-अलग स्थानों में दिखाई दे सकती है" एक क्रम में।

उदाहरण के लिए यदि आपके पास निम्नलिखित ग्राफ है:

A → B → D
↓       ↑
C ––––––+

आप इस तरह से YAML में रैखिक रास्तों की सूची के रूप में प्रतिनिधित्व कर सकते हैं:

- [&A A, B, &D D]
- [*A, C, *D]

आप इसे एक आसन्न सूची, या एक आसन्न मैट्रिक्स के रूप में भी दिखा सकते हैं, या एक जोड़ी के रूप में जिसका पहला तत्व नोड्स का एक सेट है और जिसका दूसरा तत्व नोड्स के जोड़े का एक सेट है, लेकिन उन सभी अभ्यावेदन में, आपके पास होना चाहिए मौजूदा नोड्स, यानी पॉइंटर्स के पीछे और आगे की ओर संदर्भित करने का एक तरीका , जो आपके पास आमतौर पर फ़ाइल या नेटवर्क स्ट्रीम में नहीं होता है। आपके पास अंत में बाइट्स है।

(कौन सा BTW का अर्थ है कि उपरोक्त YAML पाठ फ़ाइल को भी "सीरियलाइज्ड" होना चाहिए, यही है कि विभिन्न चरित्र एन्कोडिंग और यूनिकोड ट्रांसफर प्रारूप हैं ... यह सख्ती से "क्रमांकन" नहीं है, सिर्फ एन्कोडिंग है, क्योंकि टेक्स्ट फ़ाइल पहले से ही एक धारावाहिक है। / कोडपॉइंट्स की रैखिक सूची, लेकिन आप कुछ समानताएँ देख सकते हैं।)


13

अन्य उत्तर पहले से ही जटिल ऑब्जेक्ट ग्राफ़ को संबोधित करते हैं, लेकिन यह इंगित करने योग्य है कि प्राइमरी को क्रमबद्ध करना भी गैर-तुच्छ है।

संक्षिप्तता के लिए C आदिम प्रकार के नामों का उपयोग करना, विचार करें:

  1. मैं सीरियसली ए long। कुछ समय बाद मैं de-serialize यह है, लेकिन ... एक अलग मंच पर, और अब longहै int64_tबजाय int32_tमैं संग्रहीत। इसलिए, मुझे या तो हर प्रकार के सटीक आकार के बारे में बहुत सावधान रहना चाहिए जो मैं स्टोर करता हूं, या हर क्षेत्र के प्रकार और आकार का वर्णन करने वाले कुछ मेटाडेटा को संग्रहीत करता हूं।

    ध्यान दें कि यह विभिन्न प्लेटफ़ॉर्म भविष्य के recompile के बाद केवल एक ही प्लेटफ़ॉर्म हो सकता है।

  2. मैं सीरियसली ए int32_t। कुछ समय बाद मैं इसे डी-सीरियल करता हूं, लेकिन ... एक अलग मंच पर, और अब मूल्य भ्रष्ट है। अफसोस की बात है कि मैंने एक बड़े-एंडियन प्लेटफॉर्म पर मूल्य को बचाया, और इसे एक छोटे-एंडियन पर लोड किया। अब मुझे अपने प्रारूप के लिए एक सम्मेलन स्थापित करने की आवश्यकता है, या प्रत्येक फ़ाइल / स्ट्रीम / जो भी हो, की समाप्ति का वर्णन करते हुए अधिक मेटाडेटा जोड़ना होगा । और, ज़ाहिर है, वास्तव में उपयुक्त रूपांतरण करते हैं।

  3. मैं एक स्ट्रिंग को क्रमबद्ध करता हूं। इस समय एक प्लेटफ़ॉर्म उपयोग करता है charऔर UTF-8, और एक wchar_tऔर UTF-16।

इसलिए, मेरा दावा है कि उचित-गुणवत्ता वाले क्रमबद्धता को सन्निहित स्मृति में भी प्राथमिकताओं के लिए तुच्छ नहीं है। बहुत सारे एन्कोडिंग निर्णय हैं जिन्हें आपको या तो दस्तावेज़ की आवश्यकता है, या इनलाइन मेटाडेटा के साथ वर्णन करना है।

ऑब्जेक्ट रेखांकन जटिलता की एक और परत जोड़ते हैं।


6

इसके कई पहलू हैं:

एक ही कार्यक्रम द्वारा पठनीयता

आपके प्रोग्राम ने आपके डेटा को मेमोरी में बाइट्स के रूप में किसी तरह संग्रहीत किया है। लेकिन यह अलग-अलग रजिस्टरों में मनमाने ढंग से बिखरा हुआ हो सकता है, इसके छोटे टुकड़ों के बीच आगे और पीछे जाने वाले संकेत के साथ [संपादित करें: जैसा कि टिप्पणी की गई है, शारीरिक रूप से डेटा मुख्य मेमोरी में डेटा रजिस्टर की तुलना में अधिक संभावना है, लेकिन यह पॉइंटर समस्या को दूर नहीं करता है] । एक लिंक पूर्णांक सूची के बारे में सोचो। प्रत्येक सूची तत्व को पूरी तरह से अलग जगह पर संग्रहित किया जा सकता है और सूची को एक साथ रखने वाले सभी एक तत्व से दूसरे तक होते हैं। यदि आप उस डेटा को उसी रूप में लेना चाहते हैं और उसी प्रोग्राम को चलाने वाली किसी अन्य मशीन पर इसे कॉपी करने का प्रयास करते हैं, तो आप समस्याओं में भाग लेंगे:

  1. सबसे पहले और सबसे पहले, रजिस्टर मानता है कि आपका डेटा एक मशीन में संग्रहीत है पहले से ही किसी अन्य मशीन पर पूरी तरह से अलग के लिए इस्तेमाल किया जा सकता है (कोई व्यक्ति स्टैक एक्सचेंज ब्राउज़ कर रहा है और ब्राउज़र ने वह सभी मेमोरी पहले ही खा ली है)। तो अगर आप बस उन रजिस्टरों को ओवरराइड करते हैं, तो अलविदा ब्राउज़र। इस प्रकार, आपको दूसरी मशीन पर मुफ्त में दिए गए पतों को फिट करने के लिए संरचना में बिंदुओं को फिर से व्यवस्थित करने की आवश्यकता होगी। वही समस्या तब उत्पन्न होती है जब आप बाद में उसी मशीन पर डेटा को पुनः लोड करने का प्रयास करते हैं।
  2. क्या होगा यदि कुछ बाहरी घटक आपकी संरचना में इंगित करते हैं या आपकी संरचना में बाहरी डेटा के संकेत हैं, तो आपने संचारित नहीं किया? हर जगह Segfaults! यह एक बुरा सपना बन जाएगा।

एक अन्य कार्यक्रम द्वारा पठनीयता

मान लें कि आप अपने डेटा में फिट होने के लिए किसी अन्य मशीन पर सिर्फ सही पते आवंटित करने का प्रबंधन करते हैं। यदि आपके डेटा को उस मशीन (अलग भाषा) पर एक अलग प्रोग्राम द्वारा संसाधित किया जाता है, तो उस प्रोग्राम में डेटा की पूरी तरह से बुनियादी समझ हो सकती है। मान लें कि आपके पास पॉइंटर्स के साथ C ++ ऑब्जेक्ट्स हैं, लेकिन आपकी लक्षित भाषा उस स्तर पर पॉइंटर्स का समर्थन भी नहीं करती है। फिर, आप दूसरे प्रोग्राम में उस डेटा को संबोधित करने के लिए कोई साफ तरीका नहीं रखते हैं। आप स्मृति में कुछ बाइनरी डेटा के साथ समाप्त होते हैं, लेकिन फिर, आपको अतिरिक्त कोड लिखने की आवश्यकता होती है जो डेटा के चारों ओर लपेटता है और किसी तरह इसे कुछ ऐसी चीज़ों में अनुवाद करता है जो आपकी लक्षित भाषा के साथ काम कर सकती है। डिसेरिएलाइज़ेशन की तरह लगता है, बस यह कि आपका प्रारंभिक बिंदु अब आपकी मुख्य मेमोरी के आसपास बिखरी हुई अजीब वस्तु है, जो विभिन्न स्रोत भाषाओं के लिए अलग है, एक अच्छी तरह से परिभाषित संरचना के साथ एक फ़ाइल के बजाय। एक ही बात, निश्चित रूप से, यदि आप सीधे बाइनरी फ़ाइल की व्याख्या करने की कोशिश करते हैं जिसमें पॉइंटर्स शामिल हैं - आपको हर संभव तरीके के लिए पार्सर्स लिखने की आवश्यकता होती है एक और भाषा डेटा-इन-मेमोरी का प्रतिनिधित्व कर सकती है।

एक मानव द्वारा पठनीयता

वेब आधारित क्रमांकन (xml, json) के लिए सबसे प्रमुख आधुनिक धारावाहिक भाषाओं में से दो आसानी से एक मानव द्वारा आसानी से समझा जा सकता है। गू के बाइनरी ढेर के बजाय, डेटा को पढ़ने के लिए कार्यक्रम के बिना भी डेटा की वास्तविक संरचना और सामग्री स्पष्ट है। इसके कई फायदे हैं:

  • आसान डिबगिंग -> यदि आपकी सेवा पाइपलाइन में कोई समस्या है, तो आप बस उस डेटा को देखते हैं जो एक सेवा से निकलता है और जांचता है कि क्या यह समझ में आता है (पहले चरण के रूप में); आप यह भी सीधे देखते हैं कि क्या डेटा ऐसा लगता है जैसे आपको लगता है कि जब आपको अपना निर्यात इंटरफ़ेस लिखना चाहिए।
  • अभिलेखीयता: यदि आपके पास एक शुद्ध द्विआधारी goo ढेर के रूप में आपका डेटा है, और आप उस प्रोग्राम को ढीला करते हैं जो इसे व्याख्या करने के लिए है, तो आप डेटा को ढीला करते हैं (या आपको वास्तव में वहां कुछ खोजने के लिए काफी समय बिताना होगा); यदि आपका अनुक्रमित डेटा मानव पठनीय है, तो आप इसे एक संग्रह के रूप में आसानी से उपयोग कर सकते हैं या एक नए कार्यक्रम के लिए अपने स्वयं के आयातक को प्रोग्राम कर सकते हैं
  • इस तरह से क्रमबद्ध डेटा की घोषणात्मक प्रकृति, इसका मतलब यह भी है, यह कंप्यूटर सिस्टम और इसके हार्डवेयर से पूरी तरह से स्वतंत्र है; आप इसे पूरी तरह से अलग तरह से निर्मित क्वांटम कंप्यूटर में लोड कर सकते हैं या वैकल्पिक तथ्यों के साथ एक विदेशी AI को संक्रमित कर सकते हैं ताकि यह गलती से अगले सूरज में उड़ जाए (इमेरिच यदि आप इसे पढ़ते हैं, तो एक संदर्भ अच्छा होगा, यदि आप अगले 4 जुलाई के लिए उस विचार का उपयोग करते हैं चलचित्र)

मेरा डेटा शायद ज्यादातर मुख्य मेमोरी में है, रजिस्टरों में नहीं। यदि मेरा डेटा रजिस्टरों में फिट बैठता है, तो क्रमबद्धता मुश्किल से एक मुद्दा है। मुझे लगता है कि आपने गलत समझा है कि एक रजिस्टर क्या है।
डेविड रिचरबी

दरअसल, मैंने यहाँ बहुत ही सामान्य रूप से रजिस्टर शब्द का इस्तेमाल किया है। लेकिन मुख्य बिंदु यह है कि आपके डेटा में अपने स्वयं के घटकों की पहचान करने या अन्य डेटा को संदर्भित करने के लिए पता स्थान पर संकेत हो सकते हैं। इससे कोई फर्क नहीं पड़ता कि यह भौतिक रजिस्टर या मुख्य मेमोरी में वर्चुअल एड्रेस है।
फ्रैंक होपकिंस

नहीं, आपने "रजिस्टर" शब्द का पूरी तरह से गलत इस्तेमाल किया। आप जिन चीजों को रजिस्टर कह रहे हैं, वे वास्तविक रजिस्टरों को मेमोरी पदानुक्रम के एक पूरी तरह से अलग हिस्से में हैं।
डेविड रिचरबी

6

इसके अलावा अन्य उत्तरों में क्या कहा गया है:

कभी-कभी आप उन चीजों को क्रमबद्ध करना चाहते हैं जो शुद्ध डेटा नहीं हैं।

उदाहरण के लिए, फ़ाइल हैंडल या सर्वर से कनेक्शन के बारे में सोचें। भले ही फ़ाइल हैंडल या सॉकेट एक है int, यह संख्या अर्थहीन है जब अगली बार कार्यक्रम चलता है। ऐसी चीजों को हैंडल करने वाली वस्तुओं को अच्छी तरह से फिर से बनाने के लिए, आपको फ़ाइलों को फिर से खोलना होगा और कनेक्शनों को फिर से बनाना होगा, और यह तय करना होगा कि यह विफल हो जाए तो क्या करें।

इन दिनों कई भाषाओं में वस्तुओं के भीतर अनाम कार्यों को संग्रहीत करने का समर्थन किया जाता है, उदाहरण के लिए onBlah()जावास्क्रिप्ट में एक हैंडलर। यह चुनौतीपूर्ण है क्योंकि इस तरह के कोड में डेटा के अतिरिक्त टुकड़ों के संदर्भ हो सकते हैं जो बदले में क्रमबद्ध होने की आवश्यकता होती है। (और फिर एक क्रॉस-प्लेटफ़ॉर्म तरीके से कोडिंग कोड का मुद्दा है, जो स्पष्ट रूप से व्याख्या की गई भाषाओं के लिए आसान है।) फिर भी, भले ही भाषा का एक सबसेट समर्थन किया जा सकता है, फिर भी यह काफी उपयोगी साबित हो सकता है। कई क्रमांकन तंत्र क्रमबद्ध कोड करने का प्रयास नहीं करते हैं, लेकिन क्रमबद्ध-जावास्क्रिप्ट को देखते हैं ।

ऐसे मामलों में जहां आप किसी ऑब्जेक्ट को क्रमबद्ध करना चाहते हैं, लेकिन इसमें कुछ ऐसा होता है जो आपके क्रमांकन तंत्र द्वारा समर्थित नहीं होता है, आपको कोड को इस तरह से काम करने की आवश्यकता होती है, जो इस तरह से काम करता है। उदाहरण के लिए, आप अनाम कार्यों के स्थान पर एनम का उपयोग कर सकते हैं जब संभावित कार्यों की एक सीमित संख्या होती है।

अक्सर आप सिलसिलेवार डेटा को चखना चाहते हैं।

यदि आप नेटवर्क पर डेटा भेज रहे हैं या इसे डिस्क पर संग्रहीत कर रहे हैं, तो आकार छोटा रखना महत्वपूर्ण हो सकता है। इसे प्राप्त करने के लिए सबसे आसान तरीकों में से एक जानकारी है जिसे फिर से बनाया जा सकता है (उदाहरण के लिए, कैश, हैश टेबल और एक ही डेटा के वैकल्पिक प्रतिनिधित्व को त्यागना)।

बेशक, प्रोग्रामर को मैन्युअल रूप से चयन करना है कि क्या सहेजना है और क्या छोड़ना है, और सुनिश्चित करें कि ऑब्जेक्ट को फिर से बनाए जाने पर चीजों को फिर से बनाया जाए।

एक खेल को बचाने के कार्य के बारे में सोचो। ऑब्जेक्ट्स में ग्राफिक्स डेटा, साउंड डेटा और अन्य ऑब्जेक्ट्स के बहुत सारे पॉइंटर्स हो सकते हैं। लेकिन इस सामान को ज्यादातर गेम डेटा फाइलों से लोड किया जा सकता है और इसे सेव फाइल में स्टोर करने की जरूरत नहीं है। इसे त्यागना श्रमसाध्य हो सकता है इसलिए बहुत कम चीजें अक्सर बची रहती हैं। मैंने अपने समय में कुछ फाइलों को सहेजने के लिए हेक्स-एड किया है और ऐसे डेटा की खोज की है जो स्पष्ट रूप से निरर्थक थे, जैसे पाठ्य वस्तु विवरण।

कभी-कभी स्थान महत्वपूर्ण नहीं होता है लेकिन पठनीयता होती है - जिस स्थिति में आप इसके बजाय ASCII प्रारूप (संभवतः JSON या XML) का उपयोग कर सकते हैं।


3

आइए परिभाषित करें कि वास्तव में बाइट्स का एक क्रम क्या है। बाइट्स की एक अनुक्रम एक गैर नकारात्मक पूर्णांक कहा जाता है के होते हैं लंबाई और कुछ मनमाने ढंग से समारोह / पत्राचार कि किसी भी पूर्णांक नक्शे मैं यह है कि कम से कम शून्य और कम से कम लंबाई एक बाइट मूल्य (255 0 से एक पूर्णांक) करने के लिए।

एक विशिष्ट कार्यक्रम में आपके द्वारा व्यवहार की जाने वाली कई वस्तुएं उस रूप में नहीं होती हैं, क्योंकि वस्तुएं वास्तव में कई अलग-अलग मेमोरी आवंटन से बनी होती हैं, जो रैम में अलग-अलग जगहों पर होती हैं, और आपको प्रत्येक बाइट्स के लाखों बाइट्स से अलग किया जा सकता है। परवाह नहीं है। बस एक मूल लिंक की गई सूची के बारे में सोचें: सूची में प्रत्येक नोड बाइट्स का एक क्रम है, हां, लेकिन नोड आपके कंप्यूटर की मेमोरी में बहुत से विभिन्न स्थानों पर हैं, और वे संकेत के साथ जुड़े हुए हैं। या बस एक सरल संरचना के बारे में सोचें जिसमें एक चर-लंबाई स्ट्रिंग के लिए एक संकेतक है।

कारण यह है कि हम डेटा संरचनाओं को बाइट्स के अनुक्रम में क्रमबद्ध करना चाहते हैं, क्योंकि हम उन्हें डिस्क पर संग्रहीत करना चाहते हैं या उन्हें एक अलग सिस्टम (जैसे नेटवर्क पर) भेजना चाहते हैं। यदि आप एक पॉइंटर को डिस्क पर स्टोर करने का प्रयास करते हैं या इसे एक अलग सिस्टम पर भेजते हैं, तो यह बहुत बेकार हो जाएगा क्योंकि प्रोग्राम पढ़ने वाले पॉइंटर में मेमोरी क्षेत्रों का एक अलग सेट उपलब्ध होगा।


1
मुझे यकीन नहीं है कि यह एक अनुक्रम की एक महान परिभाषा है। ज्यादातर लोग अनुक्रम को परिभाषित करते हैं, ठीक है, एक अनुक्रम: चीजों की एक पंक्ति एक के बाद एक। आपकी परिभाषा के अनुसार, int seq(int i) { if (0 <= i < length) return i+1; else return -1;}एक अनुक्रम है। तो मैं उस डिस्क पर कैसे स्टोर करने जा रहा हूं?
डेविड रिचरबी

1
यदि लंबाई 4 है, तो मैं सामग्री के साथ एक चार बाइट फ़ाइल संग्रहीत करता हूं: 1, 2, 3, 4.
डेविड ग्रैसन

1
@DavidRicherby उनकी परिभाषा "एक के बाद एक चीजों की एक पंक्ति" के बराबर है, यह आपकी सहज परिभाषा की तुलना में सिर्फ अधिक गणितीय और सटीक परिभाषा है। ध्यान दें कि आपका फ़ंक्शन एक अनुक्रम नहीं है क्योंकि एक अनुक्रम होने के लिए आपको उस फ़ंक्शन और दूसरे पूर्णांक की आवश्यकता होती है जिसे लंबाई कहा जाता है।
user253751

1
@FreshAir मेरी बात यह है कि अनुक्रम 1, 2, 3, 4, 5 है। मैंने जो बात लिखी है वह एक फ़ंक्शन है । एक फ़ंक्शन एक अनुक्रम नहीं है।
डेविड रिचेर्बी

1
डिस्क पर फ़ंक्शन लिखने का एक सरल तरीका वह है जो मैंने पहले से ही प्रस्तावित किया था: हर संभव इनपुट के लिए, आउटपुट को स्टोर करें। मुझे लगता है कि शायद आप अभी भी इसे प्राप्त नहीं करते हैं, लेकिन मुझे यकीन नहीं है कि क्या कहना है। क्या आप जानते हैं कि एम्बेडेड सिस्टम में महंगे कार्यों sinको लुकअप टेबल में बदलना आम बात है , जो संख्याओं का एक क्रम है? क्या आप जानते हैं कि आपका फ़ंक्शन उसी के समान है जिस इनपुट की हम परवाह करते हैं? आप वास्तव मेंint seq(n) { int a[] = [1, 2, 3, 4]; return a[n]; } क्यों कहते हैं कि मेरी चार-बाइट फ़ाइल एक अपर्याप्त प्रतिनिधित्व है?
डेविड ग्रेसन

2

पेचीदगी डेटा और वस्तुओं की पेचीदगियों को स्वयं को दर्शाती है। ये ऑब्जेक्ट वास्तविक विश्व ऑब्जेक्ट या कंप्यूटर केवल ऑब्जेक्ट हो सकते हैं। जवाब नाम में है। सीरियलाइज़ेशन बहु आयामी वस्तुओं का रैखिक प्रतिनिधित्व है। खंडित रैम के अलावा कई मुद्दे हैं।

यदि आप 12 पांच आयामी सरणियों और कुछ प्रोग्राम कोड को समतल कर सकते हैं, तो क्रमबद्धता आपको संपूर्ण कंप्यूटर प्रोग्राम (और मशीनों के बीच डेटा) को स्थानांतरित करने की अनुमति देती है। RMI / CORBA जैसे वितरित कंप्यूटिंग प्रोटोकॉल डेटा और कार्यक्रमों को स्थानांतरित करने के लिए बड़े पैमाने पर क्रमांकन का उपयोग करते हैं।

अपने फोन बिल पर विचार करें। यह एक एकल वस्तु हो सकती है, जिसमें आपके सभी कॉल (तार की सूची), भुगतान करने के लिए राशि (पूर्णांक) और देश शामिल हैं। या आपके फोन का बिल ऊपर से अंदर हो सकता है और आपके नाम से जुड़े असतत आइटम वाले फोन कॉल से मिलकर सकते हैं। प्रत्येक चपटा अलग दिखाई देगा, यह दर्शाता है कि आपकी फ़ोन कंपनी ने इसके सॉफ़्टवेयर का वह संस्करण कैसे लिखा है और इसका कारण यह है कि ऑब्जेक्ट ओरिएंटेड डेटाबेस कभी भी बंद नहीं हुए।

एक संरचना के कुछ हिस्से स्मृति में भी नहीं हो सकते हैं। यदि आपके पास आलसी कैशिंग है, तो किसी ऑब्जेक्ट के कुछ हिस्सों को केवल एक डिस्क फ़ाइल के लिए संदर्भित किया जा सकता है, और केवल उस विशेष ऑब्जेक्ट के उस हिस्से तक पहुंचने पर लोड किया जाता है। यह गंभीर दृढ़ता के ढांचे में आम है। BLOB एक अच्छा उदाहरण हैं। गेटी इमेज में फिदेल कास्त्रो की एक विशाल बहु मेगाबाइट तस्वीर और छवि के नाम, किराये की लागत और छवि जैसे कुछ मेटा डेटा संग्रहीत हो सकते हैं। आप हर बार 200 एमबी की तस्वीर को मेमोरी में लोड नहीं करना चाह सकते, जब तक कि आप वास्तव में उसे नहीं देखते। सीरियलाइज्ड, संपूर्ण फ़ाइल को 200MB से अधिक संग्रहण की आवश्यकता होगी।

कुछ वस्तुओं को भी क्रमबद्ध नहीं किया जा सकता है। जावा प्रोग्रामिंग की भूमि में, आप ग्राफिक्स स्क्रीन या एक भौतिक सीरियल पोर्ट का प्रतिनिधित्व करने वाली प्रोग्रामिंग ऑब्जेक्ट रख सकते हैं। दोनों में से किसी को भी सीरियल करने की कोई वास्तविक अवधारणा नहीं है। आप नेटवर्क पर किसी और को अपना पोर्ट कैसे भेजेंगे?

पासवर्ड / एन्क्रिप्शन कुंजी जैसी कुछ चीजें संग्रहीत या प्रेषित नहीं की जानी चाहिए। उन्हें इस तरह (अस्थिर / क्षणिक आदि) के रूप में टैग किया जा सकता है और क्रमांकन प्रक्रिया उन्हें छोड़ देगी लेकिन वे रैम में रह सकते हैं। इन टैग्स को छोड़ना यह है कि एन्क्रिप्शन कुंजियों को अनजाने में सादे ASCII में कैसे भेजा / संग्रहीत किया जाता है।

यह और अन्य जवाब क्यों यह जटिल है।


2

मेरे पास जो परेशानी है वह यह है: सभी वेरिएबल्स (यह इंटिमेट या समग्र वस्तुओं की तरह आदिम नहीं हैं) पहले से ही बाइट्स के अनुक्रम द्वारा दर्शाए गए हैं?

हाँ वे हैं। यहाँ समस्या उन बाइट्स के लेआउट की है। एक साधारण int2, 4 या 8 बिट लंबा हो सकता है। यह बड़े या छोटे एंडियन में हो सकता है। यह अहस्ताक्षरित हो सकता है, 1 के पूरक के साथ हस्ताक्षरित या यहां तक ​​कि नकारात्मक जैसे कुछ सुपर विदेशी बिट कोडिंग में भी।

यदि आप केवल intमेमोरी से द्विपद को डंप करते हैं , और इसे "क्रमबद्ध" कहते हैं, तो आपको इसके लिए बहुत अधिक संपूर्ण कंप्यूटर, ऑपरेटिंग सिस्टम और आपके प्रोग्राम को अटैच करना होगा। या कम से कम, उनका एक सटीक विवरण।

तो क्या धारावाहिकीकरण इतना गहरा विषय बनाता है? एक चर को अनुक्रमित करने के लिए, क्या हम इन बाइट्स को स्मृति में नहीं ले जा सकते हैं, और उन्हें एक फाइल पर लिख सकते हैं? मुझे क्या याद आती है?

एक साधारण वस्तु का सीरियलाइजेशन बहुत कुछ नियमों के अनुसार इसे लिख रहा है। वे नियम काफी हैं और हमेशा स्पष्ट नहीं होते हैं। उदाहरण के लिए एक xs:integerXML में आधार -10 में लिखा है। बेस -16 नहीं, बेस -9 नहीं, लेकिन 10. यह कोई छिपी हुई धारणा नहीं है, यह एक वास्तविक नियम है। और ऐसे नियम क्रमबद्धता को क्रमबद्ध बनाते हैं। क्योंकि, बहुत अधिक, स्मृति में आपके कार्यक्रम के बिट लेआउट के बारे में कोई नियम नहीं हैं

वह सिर्फ एक हिमखंड का एक सिरा था। आइए उन सरलतम प्राथमिकताओं के अनुक्रम का एक उदाहरण लेते हैं: एक सी struct। आप ऐसा सोच सकते हैं

struct {
short width;
short height;
long count;
}

किसी दिए गए कंप्यूटर + ओएस पर एक परिभाषित मेमोरी लेआउट है? खैर, यह नहीं है। वर्तमान #pragma packसेटिंग के आधार पर , कंपाइलर फ़ील्ड को पैड करेगा। 32-बिट संकलन की डिफ़ॉल्ट सेटिंग्स पर, दोनों shortsको 4 बाइट्स में रखा structजाएगा, इसलिए वास्तव में मेमोरी में 4 बाइट्स के 3 फ़ील्ड होंगे। तो अब, आपको न केवल यह निर्दिष्ट करना होगा कि short16 बिट लंबा है, यह एक पूर्णांक है, जो 1 के पूरक में लिखा गया है नकारात्मक, बड़ा या छोटा एंडियन। आपको यह भी लिखना होगा कि आपके प्रोग्राम को सेट करने वाले स्ट्रक्चर की पैकिंग किसके साथ संकलित की गई थी।

यह बहुत अधिक है कि किस बारे में क्रमबद्धता है: नियमों का एक सेट बनाना, और उनसे चिपकना।

उन नियमों को और भी अधिक परिष्कृत संरचनाओं (जैसे कि वैरिएबल लेंथ लिस्ट या नॉनलाइनियर डेटा) को स्वीकार करने के लिए विस्तारित किया जा सकता है, इसमें मानव पठनीयता, वर्जनिंग, बैकवर्ड कम्पैटिबिलिटी और एरर करेक्शन इत्यादि जैसे फीचर्स जोड़े जा सकते हैं, लेकिन एक एकल लिखना भी intपहले से ही काफी जटिल है यदि आप केवल यह सुनिश्चित करना चाहते हैं कि आप इसे मज़बूती से पढ़ पाएंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.