كيف تجتاز مقابلة Kotlin: أهم الأسئلة
أصبحت Kotlin بقوة اللغة الرئيسية لتطوير Android وتُستخدم بنشاط في الواجهة الخلفية (Ktor, Spring Boot). المقابلة لوظيفة مطور Kotlin هي اختبار ليس فقط للقواعد النحوية، ولكن أيضًا لفهم فلسفة اللغة: null safety، coroutines، والمنهج الوظيفي. في هذه المقالة، قمنا بتحليل الأسئلة الأكثر شيوعًا التي تُطرح في المقابلات، مع أمثلة التعليمات البرمجية والشروحات.
1. Null Safety: كيف تحارب Kotlin NullPointerException
واحدة من المزايا الرئيسية لـ Kotlin هي الحماية المدمجة من null. على عكس Java، حيث يمكن أن يكون أي مرجع null، في Kotlin، تنقسم الأنواع إلى nullable و non-null.
سؤال: ما الفرق بين ? و !!؟
? هو عامل الاستدعاء الآمن. إذا كان الكائن null، فإن استدعاء الدالة أو الخاصية يعيد null ببساطة دون استثناء.
val name: String? = nullval length = name?.length // null, لا يوجد خطأ!! هو تأكيد non-null. أنت تضمن أن القيمة ليست null. إذا كانت null، فسيحدث NullPointerException.
val length = name!!.length // NPE عندما name == nullسؤال: ما هو عامل الإيلفيس ?:؟
يسمح لك بتعيين قيمة افتراضية إذا كان الجانب الأيسر null.
val name: String? = nullval display = name ?: "ضيف"سؤال: كيف يعمل let مع الأنواع nullable؟
let يتم تنفيذه فقط إذا لم يكن الكائن null. هذه هي الطريقة الاصطلاحية لمعالجة nullable.
name?.let { println("الاسم: $it")}2. الكوروتينات: البرمجة غير المتزامنة بدون ألم
الكوروتينات هي خيوط خفيفة الوزن تسمح لك بكتابة كود غير متزامن بأسلوب أمري. في المقابلة، يختبرون فهم النطاقات (scopes)، والموزعين (dispatchers)، ووظائف suspend.
سؤال: ما الفرق بين launch و async؟
launch— يبدأ كوروتين، ويعيد Job. لا يعيد نتيجة.async— يبدأ كوروتين، ويعيد Deferred (مشابه لـ Future). نحصل على النتيجة من خلال.await().
coroutineScope { val job = launch { delay(100) } val deferred = async { 42 } val result = deferred.await() // 42}سؤال: ما هو CoroutineContext والموزعون (dispatchers)؟
CoroutineContext هو مجموعة من العناصر التي تحدد سلوك الكوروتين (الموزع، Job، الاسم). الموزعون الرئيسيون:
Dispatchers.Main— لواجهة المستخدم (Android).Dispatchers.IO— للإدخال/الإخراج (الشبكة، الملفات).Dispatchers.Default— للمهام كثيفة الاستخدام لوحدة المعالجة المركزية (CPU).
سؤال: ما هو withContext؟
يسمح لك بتغيير الموزع داخل الكوروتين دون تغيير النطاق.
suspend fun loadData(): String = withContext(Dispatchers.IO) { // عملية طويلة "بيانات"}3. الفئات والكائنات: sealed, data, companion
تقدم Kotlin عدة أنواع خاصة من الفئات التي تبسط الأنماط النمطية.
سؤال: ما هي الفئة المختومة (sealed class) ومتى يتم استخدامها؟
Sealed class هي فئة مجردة مع مجموعة محدودة من الفئات الفرعية. جميع الورثة معروفون في وقت الترجمة. مثالية لتمثيل الحالات (UI State) أو نتائج العمليات.
sealed class Result { data class Success(val data: String) : Result() data class Error(val message: String) : Result() object Loading : Result()}
fun handleResult(result: Result) { when (result) { is Result.Success -> println(result.data) is Result.Error -> println(result.message) Result.Loading -> println("جارٍ التحميل...") }}ليست هناك حاجة لفرع else — المترجم يعرف جميع الخيارات.