كيف تجتاز مقابلة Rust: أهم الأسئلة
Rust — واحدة من أكثر لغات البرمجة طلبًا في عام 2025. فهي تجمع بين أداء C/C++ وأمان الذاكرة، مما يجعلها خيارًا مثاليًا للبرمجة النظامية، وتجميع الويب (WebAssembly)، ومشاريع blockchain. ومع ذلك، غالبًا ما تخيف مقابلات Rust المرشحين بسبب نظام الملكية الصارم، والاقتراض، وأوقات الحياة. في هذه المقالة، سنحلل أهم 10 أسئلة سيتم طرحها عليك بالتأكيد، وسنعرض الإجابات الصحيحة مع أمثلة الكود.
1. ما هي الملكية (ownership) وكيف تعمل؟
الملكية هي أساس Rust. كل قيمة في Rust لها مالك واحد بالضبط. عندما يخرج المالك من النطاق، يتم حذف القيمة تلقائيًا.
fn main() { let s = String::from("hello"); // s — مالك السلسلة let t = s; // تنتقل الملكية إلى t // println!("{}", s); // خطأ: s لم يعد يملك القيمة println!("{}", t); // صحيح}ما يُسأل في المقابلة: اشرح الفرق بين النقل (move) والنسخ (copy). الأنواع التي تطبق الخاصية Copy (مثل i32، bool) تُنسخ، ولا تُنقل.
2. كيف يعمل الاقتراض (borrowing)؟
الاقتراض يسمح باستخدام القيمة مؤقتًا دون نقل الملكية. هناك نوعان من الاقتراض: غير قابل للتغيير (&T) وقابل للتغيير (&mut T).
fn main() { let mut s = String::from("hello"); let r1 = &s; // اقتراض غير قابل للتغيير let r2 = &s; // يمكن وجود عدة اقتراضات غير قابلة للتغيير // let r3 = &mut s; // خطأ: لا يمكن وجود اقتراض قابل للتغيير وغير قابل للتغيير معًا println!("{} {}", r1, r2); let r3 = &mut s; // صحيح: بعد خروج r1 و r2 من النطاق r3.push_str(" world"); println!("{}", r3);}القاعدة الأساسية: في أي لحظة، يمكن أن يكون هناك إما اقتراض واحد قابل للتغيير، أو أي عدد من الاقتراضات غير القابلة للتغيير.
3. ما هي أوقات الحياة (lifetimes)؟
أوقات الحياة هي تعليقات توضيحية يحتاجها مترجم Rust للتحقق من أن المراجع لا تصبح معلقة. غالبًا ما تُستخدم في الدوال التي تُرجع مراجع.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y }}
fn main() { let s1 = String::from("طويلة"); let s2 = "قصيرة"; let result = longest(&s1, s2); println!("أطول سلسلة نصية: {}", result);}نصيحة: في معظم الحالات، يستنتج المترجم وقت الحياة بنفسه (elision). التعليقات التوضيحية مطلوبة فقط للحالات المعقدة.
4. ما هي الخصائص (traits) وكيفية استخدامها؟
الخصائص (traits) هي ما يعادل الواجهات (interfaces) في اللغات الأخرى. إنها تحدد سلوكًا مشتركًا لأنواع مختلفة.
trait Summary { fn summarize(&self) -> String;}
struct Article { title: String, content: String,}
impl Summary for Article { fn summarize(&self) -> String { format!("{}: {}...", self.title, &self.content[..20]) }}
fn main() { let article = Article { title: String::from("Rust"), content: String::from("Rust — لغة آمنة وسريعة"), }; println!("{}", article.summarize());}مهم: يمكن أن تحتوي الخصائص على تطبيقات افتراضية ويمكن أن تكون معلمة (خصائص عامة).
5. ما الفرق بين String و &str؟
هذا أحد أكثر الأسئلة شيوعًا. String هي سلسلة نصية قابلة للتغيير ومملوكة، مخزنة في الكومة (heap). &str هو اقتراض غير قابل للتغيير لشريحة نصية، يمكن أن يشير إلى String، أو نص حرفي (string literal)، أو جزء من سلسلة نصية.
fn main() { let s1 = String::from("hello"); // String let s2: &st
```