Kotlin: إصابة في الصميم أم خارج الهدف؟
\nKotlin ليست مجرد "Java بدون كود روتيني". إنها لغة جعلت Google تقع في حبها، وتجاوزت Swift في معدلات النمو، وأصبحت بندًا إلزاميًا في وظائف مطوري التطبيقات المحمولة. لكن المفارقة: كثيرون يأتون إلى المقابلة بفكرة "أنا أعرف Java - سأتدبر الأمر"، ويغادرون بعيون حمراء. لأن Kotlin عالم مختلف: بدون null، مع الكوروتينات ودوال التوسيع التي تحطم الأنماط.
\nنحن في PythonLib (نعم، نحن عن Python، لكن Kotlin ضرورية للخلفية الحديثة والتطبيقات المحمولة) جمعنا حالة حقيقية: كيف تجتاز مقابلة Kotlin ببراعة. لا ماء - فقط كود ومنطق وحيل سرية لا تُذكر في الدورات.
\n\n1. لماذا Kotlin ليست مجرد "Java 2.0"؟
\nأول سؤال سيُطرح عليك: "ما الفرق الجوهري بين Kotlin وJava؟". إذا قلت "الصياغة أقصر" - سيُطلب منك المغادرة بأدب. الفرق الرئيسي هو null safety على مستوى الأنواع. في Java، يمكنك نسيان التحقق من الكائن null والحصول على NPE في وقت التشغيل. في Kotlin، لن يسمح لك المترجم حتى بتجميع الكود إذا كان هناك خطر null.
\n// Java\nString name = null;\nint length = name.length(); // NPE في وقت التشغيل\n\n// Kotlin\nvar name: String? = null\nval length = name?.length ?: 0 // آمن: length = 0\nلكن هذا أساسي. سيتعمق المحاور أكثر: سيسأل عن !! (تأكيد عدم null)، عامل إلفيس ?: والاستدعاءات الآمنة ?.. مهمتك هي إظهار أنك تفهم: !! شر، و ?: صديقك.
- \n
- استدعاء آمن (?.) - إذا كان الكائن null، يُرجع null. \n
- إلفيس (?:) - إذا كان اليسار null، نأخذ القيمة من اليمين. \n
- !! - استخدمه فقط إذا كنت متأكدًا 100%، وإلا - خطأ. \n
2. Extension functions: سحر يجب شرحه
\nسؤال: "كيف تضيف دالة إلى كلاس لا يمكنك تغييره؟". في Java - نمط Decorator أو كلاس Util. في Kotlin - extension functions. هذا ليس تغييرًا حقيقيًا للكلاس، بل سكر صياغة يجعل الكود قابلًا للقراءة.
\n// Extension function للـ String\nfun String.isEmail(): Boolean {\n return this.contains("@") && this.contains(".")\n}\n\n// الاستخدام\nval email = "user@pythonlib.ru"\nprintln(email.isEmail()) // true\nقد يسأل المحاور: "هل يمكن إعادة تعريف extension function؟". الإجابة: لا، هذا استدعاء ثابت، وليس ديناميكيًا. إذا أعلنت دالة بنفس الاسم في الكلاس، فالأولوية لدالة الكلاس.
\n\n3. Sealed class vs Enum: متى نستخدم أيهما؟
\nهذا سؤال كلاسيكي لمستوى متوسط. Enum - لمجموعة ثابتة من الثوابت (أيام الأسبوع، الحالات). Sealed class - لتسلسل هرمي محدود من الأنواع، حيث يمكن أن يكون لكل عنصر حالته الخاصة.
\nsealed class Result {\n data class Success(val data: String) : Result()\n data class Error(val code: Int, val message: String) : Result()\n object Loading : Result()\n}\n\nfun handleResult(result: Result) {\n when (result) {\n is Result.Success -> println("Data: ${result.data}")\n is Result.Error -> println("Error ${result.code}: ${result.message}")\n Result.Loading -> println("Loading...")\n }\n}\nلماذا هذا مهم؟ لأن when مع sealed class يضمن أنك عالجت جميع الحالات. لن يسمح لك المترجم بنسيان نوع جديد إذا أضفته إلى sealed class.
4. الكوروتينات: كيف لا تفشل في التعامل مع التزامن غير المتزامن
\nالموضوع الذي يفشل فيه 70% من المرشحين. الكوروتينات ليست خيوطًا. إنها "خيوط" خفيفة الوزن يمكنها التوقف مؤقتًا دون حظر الخيط.
\nsuspend fun fetchData(): String {\n delay(1000) // لا يحظر الخيط!\n return "Data from PythonLib"\n}\n\nfun main() = runBlocking {\n launch {\n val result = fetchData()\n