Rust: एक भाषा जो आपको अलग तरह से सोचने पर मजबूर करती है
\n\nआपने Rust में महारत हासिल करने का फैसला किया है। बहुत अच्छा। यह सिर्फ एक और भाषा नहीं है - यह एक चुनौती है। Rust उन पैटर्न को तोड़ता है जिन्हें हम Python, JavaScript या C++ में देखने के आदी हैं। यह आपको मेमोरी, सुरक्षा और समवर्तीता के बारे में एक नए स्तर पर सोचने पर मजबूर करता है।
\n\nRust साक्षात्कार सिंटैक्स की परीक्षा नहीं है। यह एक जांच है कि आप कैसे सोचते हैं। साक्षात्कारकर्ता यह देखना चाहते हैं कि आप भाषा के दर्शन को समझते हैं: स्वामित्व, उधार, जीवनकाल। इस लेख में, हम वास्तविक विषयों और प्रश्नों का विश्लेषण करेंगे जो आपसे पूछे जाएंगे, और कोड उदाहरण दिखाएंगे जो साक्षात्कार पास करने में मदद करेंगे।
\n\nतैयार हैं? चलिए शुरू करते हैं।
\n\n1. स्वामित्व (Ownership) - नींव, जिसके बिना कुछ नहीं चलता
\n\nपहला और सबसे महत्वपूर्ण भाग। यदि आप स्वामित्व नहीं समझते हैं - तो आप Rust नहीं समझते हैं। साक्षात्कार में आपसे निश्चित रूप से यह समझाने के लिए कहा जाएगा कि स्वामित्व का हस्तांतरण कैसे काम करता है, और इसे प्रदर्शित करने वाला कोड लिखने के लिए कहा जाएगा।
\n\nस्वामित्व के प्रमुख नियम:
\n- \n
- Rust में प्रत्येक मान का ठीक एक मालिक होता है। \n
- जब मालिक दायरे से बाहर हो जाता है, तो मान हटा दिया जाता है। \n
- स्वामित्व को स्थानांतरित (move) या अस्थायी रूप से उधार (borrow) दिया जा सकता है। \n
उदाहरण: यह कोड क्या आउटपुट देगा?
\nfn main() {\n let s1 = String::from("hello");\n let s2 = s1;\n println!("{}", s1); // त्रुटि!\n}\n\nसही उत्तर: कंपाइलेशन त्रुटि। s1 को s2 में स्थानांतरित कर दिया गया है, और s1 अब मान्य नहीं है। साक्षात्कारकर्ता यह सुनना चाहता है कि आप move semantics समझते हैं और Rust इसके प्रति इतना सख्त क्यों है।
2. उधार और संदर्भ (Borrowing & References)
\n\nस्वामित्व के बाद - उधार लेना। स्वामित्व लिए बिना संदर्भ कैसे लें? और मुख्य बात - कंपाइलर के नियमों का उल्लंघन कैसे न करें।
\n\nउधार लेने के नियम:
\n- \n
- अपरिवर्तनीय संदर्भ (&T) की कोई भी संख्या हो सकती है। \n
- केवल एक परिवर्तनीय संदर्भ (&mut T) हो सकता है। \n
- एक ही मान पर एक साथ &T और &mut T नहीं हो सकते। \n
उदाहरण: त्रुटि खोजें
\nfn main() {\n let mut s = String::from("hello");\n let r1 = &s;\n let r2 = &mut s;\n println!("{} {}", r1, r2);\n}\n\nत्रुटि: हमने एक अपरिवर्तनीय संदर्भ r1 बनाया, और फिर एक परिवर्तनीय r2। कंपाइलर इसकी अनुमति नहीं देगा। स्पष्टीकरण: यह कंपाइलेशन चरण में डेटा रेस (data races) से सुरक्षा है।
3. जीवनकाल (Lifetimes) - वह विषय जो सभी को डराता है
\n\nLifetimes कोई जादू नहीं है। ये एनोटेशन हैं जो कंपाइलर को यह समझने में मदद करते हैं कि संदर्भ कितने समय तक मान्य रहते हैं। साक्षात्कार में आपसे यह समझाने के लिए कहा जाएगा कि इनकी आवश्यकता क्यों है, और स्पष्ट lifetime-पैरामीटर वाला एक फंक्शन लिखने के लिए कहा जाएगा।
\n\nविशिष्ट प्रश्न:
\nएक फंक्शन लिखें जो दो में से सबसे लंबी स्ट्रिंग लौटाता है। आप lifetimes कैसे निर्दिष्ट करेंगे?
\n\nfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n if x.len() > y.len() { x } else { y }\n}\n\nयहाँ 'a एक सामान्य जीवनकाल है जो गारंटी देता है कि लौटाया गया संदर्भ तब तक मान्य रहेगा जब तक दोनों इनपुट संदर्भ मान्य हैं। साक्षात्कारकर्ता इसकी सराहना करेगा यदि आप lifetime elision का उल्लेख करते हैं - जब Rust सरल मामलों के लिए स्वयं lifetimes का अनुमान लगाता है।
4. Enums और Pattern Matching - Rust की ताकत
\n\nRust में null नहीं है। इसके बजाय - Option<T> और Result<T, E>। साक्षात्कार में आपसे match का उपयोग करके त्रुटि प्रबंधन लिखने के लिए कहा जाएगा।
उदाहरण: सुरक्षित विभाजन
\nfn safe_divide(a: f64, b: f64) -> Option<f64> {\n if b == 0.0 { None } else { Some(a / b) }\n}\n\nfn main() {\n match safe_divide(10.0, 0.0) {\n Some(result) => println!("Result: {}", result),\n None => println!("Cannot divide by zero"),\n }\n}\n\nदिखाएँ