Rust साक्षात्कार में उन्नत प्रश्न: विश्लेषण और उदाहरण

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Rust साक्षात्कार कैसे पास करें: उन्नत स्तर के शीर्ष प्रश्न

\n\n

Rust सबसे अधिक मांग वाली सिस्टम प्रोग्रामिंग भाषाओं में से एक है, और senior डेवलपर्स की मांग बढ़ती जा रही है। यदि आपने पहले से ही बुनियादी सिंटैक्स और स्वामित्व प्रणाली में महारत हासिल कर ली है, तो साक्षात्कार में आपसे ऐसे प्रश्न पूछे जाएंगे जो unsafe कोड, एसिंक्रोनसिटी, जटिल lifetimes और मेटाप्रोग्रामिंग की गहरी समझ की जांच करते हैं। इस लेख में, हम मुख्य विषयों का विश्लेषण करेंगे और कोड उदाहरण प्रस्तुत करेंगे जो आपको आत्मविश्वास से साक्षात्कार पास करने में मदद करेंगे।

\n\n

1. Unsafe Rust: कब और क्यों?

\n\n

उन्नत साक्षात्कार में सबसे आम प्रश्नों में से एक: "समझाइए कि आप unsafe का उपयोग कब करेंगे और इससे कौन सी गारंटी का उल्लंघन होता है।"

\n\n

उत्तर में चार मुख्य क्षमताएं शामिल होनी चाहिए जो unsafe प्रदान करता है:

\n\n
    \n
  • कच्चे पॉइंटर्स को डीरेफरेंस करना (*const T और *mut T)
  • \n
  • unsafe फ़ंक्शन को कॉल करना (उदाहरण के लिए, FFI)
  • \n
  • म्यूटेबल स्टैटिक वेरिएबल्स तक पहुंच
  • \n
  • unsafe ट्रेट्स को लागू करना
  • \n
\n\n

उदाहरण: मैन्युअल मेमोरी प्रबंधन के साथ एक सरल डायनामिक ऐरे का कार्यान्वयन।

\n\n
use std::alloc::{alloc, dealloc, Layout};\nuse std::ptr;\n\nstruct MyVec {\n    ptr: *mut i32,\n    len: usize,\n    cap: usize,\n}\n\nimpl MyVec {\n    fn new() -> Self {\n        MyVec {\n            ptr: ptr::null_mut(),\n            len: 0,\n            cap: 0,\n        }\n    }\n\n    fn push(&mut self, val: i32) {\n        if self.len == self.cap {\n            let new_cap = if self.cap == 0 { 1 } else { self.cap * 2 };\n            let new_layout = Layout::array::<i32>(new_cap).unwrap();\n            let new_ptr = unsafe { alloc(new_layout) as *mut i32 };\n            // पुराने डेटा को कॉपी करें\n            unsafe {\n                ptr::copy_nonoverlapping(self.ptr, new_ptr, self.len);\n                if !self.ptr.is_null() {\n                    let old_layout = Layout::array::<i32>(self.cap).unwrap();\n                    dealloc(self.ptr as *mut u8, old_layout);\n                }\n            }\n            self.ptr = new_ptr;\n            self.cap = new_cap;\n        }\n        unsafe {\n            ptr::write(self.ptr.add(self.len), val);\n        }\n        self.len += 1;\n    }\n}\n\nimpl Drop for MyVec {\n    fn drop(&mut self) {\n        if !self.ptr.is_null() {\n            unsafe {\n                let layout = Layout::array::<i32>(self.cap).unwrap();\n                dealloc(self.ptr as *mut u8, layout);\n            }\n        }\n    }\n}
\n\n

सुझाव: हमेशा इस बात पर जोर दें कि unsafe जांच को बंद करना नहीं है, बल्कि इनवेरिएंट्स की जिम्मेदारी लेना है।

\n\n

2. Lifetimes और variance: कंपाइलर रेफरेंस की जांच कैसे करता है

\n\n

उन्नत स्तर पर, आपसे lifetimes के संदर्भ में variance (कोवेरियंस, कॉन्ट्रावेरियंस, इनवेरियंस) समझाने के लिए कहा जाएगा। यह समझने की कुंजी है कि कुछ प्रकार संकलित क्यों नहीं होते हैं।

\n\n
    \n
  • कोवेरियंस: &'a T — यदि 'a, 'b से बड़ा है, तो &'a T को &'b T के रूप में उपयोग किया जा सकता है।
  • \n
  • कॉन्ट्रावेरियंस: fn(T) — यदि 'a, 'b से बड़ा है, तो fn(&'b T) को fn(&'a T) के रूप में उपयोग किया जा सकता है।
  • \n
  • इनवेरियंस: &mut T — lifetime बिल्कुल समान होनी चाहिए।
  • \n
\n\n

उदाहरण: निम्नलिखित कोड संकलित क्यों नहीं होगा?

\n\n
fn foo<'a>(x: &'a mut &'a str, y: &'a str) {\n    *x = y;\n}\n\nfn main() {\n    let mut s = "hello";\n    let r = &s;\n    foo(&mut s, r); // त्रुटि!\n}
\n\n

उत्तर: &mut T, T के संबंध में इनवेरिएंट है, इसलिए आंतरिक रेफरेंस का lifetime बाहरी रेफरेंस के lifetime से बिल्कुल मेल खाना चाहिए। कंपाइलर r के lifetime को "संकुचित" नहीं कर सकता।

\n\n

3. Async Rust: Pin, Unpin और Future

ब्लॉग

पुस्तक अनुशंसाएँ