Rust इंटरव्यू कैसे पास करें: एडवांस्ड लेवल के टॉप प्रश्न
\n\nRust एक सिस्टम प्रोग्रामिंग भाषा है जो अपनी सुरक्षा, प्रदर्शन और गार्बेज कलेक्टर की अनुपस्थिति के कारण लोकप्रिय हो रही है। अगर आपने बेसिक्स सीख लिए हैं और Senior या Middle Rust डेवलपर पद के लिए इंटरव्यू की तैयारी कर रहे हैं, तो आपको सामान्य सिंटैक्स से परे सवालों का सामना करना पड़ेगा। इस लेख में हम उन मुख्य एडवांस्ड टॉपिक्स पर चर्चा करेंगे जो तकनीकी इंटरव्यू में अक्सर पूछे जाते हैं।
\n\nहम चार भागों को कवर करेंगे: स्वामित्व और उधार (ownership & borrowing), जीवनकाल (lifetimes), असुरक्षित कोड (unsafe) और मैक्रोज़, साथ ही एडवांस्ड मल्टीथ्रेडिंग। प्रत्येक अनुभाग में वास्तविक प्रश्न और कोड उदाहरण शामिल हैं।
\n\n1. स्वामित्व, उधार और म्यूटेबिलिटी के नियम
\n\nप्रश्न: Rust में स्वामित्व तंत्र कैसे काम करता है? &T, &mut T और Box<T> में क्या अंतर है?
उत्तर: स्वामित्व Rust में मेमोरी सुरक्षा की नींव है। प्रत्येक मान का एक ही मालिक होता है। जब मालिक स्कोप से बाहर जाता है, तो मान नष्ट हो जाता है। उधार (&T) आपको स्वामित्व स्थानांतरित किए बिना अस्थायी रूप से डेटा का संदर्भ "उधार" लेने की अनुमति देता है। म्यूटेबल उधार (&mut T) डेटा को बदलने का अधिकार देता है, लेकिन केवल तब जब कोई अन्य संदर्भ मौजूद न हो।
Box<T> एक स्मार्ट पॉइंटर है जो हीप में मेमोरी आवंटित करता है। यह स्वामित्व स्थानांतरित करता है, जो इसे सामान्य संदर्भों से अलग करता है।
fn main() {\n let mut s = String::from("नमस्ते");\n let r1 = &s; // इम्यूटेबल संदर्भ\n let r2 = &mut s; // त्रुटि! &mut और & एक साथ नहीं हो सकते\n // println!("{}", r1);\n}\n\n\nप्रश्न: "एक म्यूटेबल उधार का नियम" क्या है?
\n\nउत्तर: किसी भी समय, किसी मान के लिए या तो एक म्यूटेबल संदर्भ हो सकता है, या कितने भी इम्यूटेबल संदर्भ हो सकते हैं, लेकिन दोनों एक साथ नहीं। यह कंपाइल टाइम पर डेटा रेस को रोकता है।
\n\n2. जीवनकाल (Lifetimes) — कंपाइलर कैसे समझता है कि संदर्भ जीवित है
\n\nप्रश्न: Lifetime एनोटेशन की आवश्यकता क्यों है? एक उदाहरण दें जब वे अनिवार्य हों।
\n\nउत्तर: Lifetime एनोटेशन ('a, 'b आदि) कंपाइलर को यह जांचने में मदद करते हैं कि सभी संदर्भ मान्य हैं। वे तब अनिवार्य होते हैं जब कोई फ़ंक्शन इनपुट पैरामीटर से जुड़ा संदर्भ लौटाता है और कंपाइलर स्वचालित रूप से जीवनकाल का अनुमान नहीं लगा सकता।
// फ़ंक्शन सबसे लंबी स्ट्रिंग लौटाता है\nfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n if x.len() > y.len() { x } else { y }\n}\n\nfn main() {\n let s1 = String::from("लंबा");\n let result;\n {\n let s2 = String::from("छोटा");\n result = longest(&s1, &s2); // ठीक है\n }\n // println!("{}", result); // त्रुटि: s2 मर गया\n}\n\n\nप्रश्न: "Lifetime Elision" क्या है?
\n\nउत्तर: कंपाइलर सरल मामलों में स्वचालित रूप से lifetime एनोटेशन जोड़ता है। उदाहरण के लिए, fn first_word(s: &str) -> &str विधि के लिए, कंपाइलर स्वयं समझ जाता है कि आउटपुट का जीवनकाल इनपुट के बराबर है। Elision Rust पुस्तक में वर्णित तीन नियमों के अनुसार काम करता है।
3. Unsafe Rust और मैक्रोज़
\n\nप्रश्न: unsafe का उपयोग कब उचित है? unsafe ब्लॉक के अंदर कौन से ऑपरेशन ही उपलब्ध हैं?
उत्तर: unsafe का उपयोग उन ऑपरेशनों के लिए किया जाता है जिन्हें कंपाइलर जांच नहीं सकता: कच्चे पॉइंटर्स को डीरेफरेंस करना, बाहरी फ़ंक्शन कॉल (FFI), म्यूटेबल स्टैटिक वेरिएबल्स तक पहुंच, और असुरक्षित ट्रेट्स को लागू करना। हालांकि, unsafe कोड का उपयोग सावधानी से करना चाहिए क्योंकि यह मेमोरी सुरक्षा की गारंटी को तोड़ सकता है।