- سأتخطى الأسئلة التي تتداخل مع هذه السلسلة من المقالات حتى لا أكرر المعلومات دون داع. أوصي بقراءة هذه المقالات لأنها تغطي الأسئلة الأكثر شيوعًا (الشعبية) لمقابلة Java Core.
- يمكنني أن أصف الإجابات بمزيد من التفصيل، لكنني لن أفعل ذلك، لأن كل إجابة يمكن أن تستمر في المقالة بأكملها. ولن يطلب منك أحد هذا المستوى من التفاصيل في أي مقابلة عمل.
11. قم بتسمية كافة أساليب فئة الكائن
تحتوي فئة الكائن على 11 طريقة:-
Class<?> getClass() — احصل على فئة الكائن الحالي؛
-
int hashCode() — الحصول على رمز التجزئة للكائن الحالي؛
-
منطقية يساوي (Object obj) - مقارنة الكائن الحالي مع كائن آخر؛
-
كائن استنساخ () - إنشاء وإرجاع نسخة من الكائن الحالي؛
-
String toString() — احصل على تمثيل السلسلة للكائن؛
-
void notify () — تنبيه خيط واحد ينتظر على شاشة هذا الكائن (اختيار الخيط عشوائي)؛
-
void notifyAll () - تنبيه كافة المواضيع المنتظرة على شاشة هذا الكائن؛
-
انتظار باطلة () - جعل الخيط الحالي ينتظر على الشاشة الحالية (تجميد الخيط الحالي) حتى يقوم استدعاء الإخطار أو notifyAll بإيقاظ الخيط (يعمل فقط في كتلة متزامنة)؛
-
انتظار باطلة (مهلة طويلة) - جعل الخيط الحالي ينتظر على الشاشة الحالية (على الكتلة المتزامنة الحالية)، ولكن مع مهلة للخروج من حالة الانتظار (أو مرة أخرى، حتى يستيقظ تنبيه أو مكالمة notifyAll الخيط)؛
-
الانتظار الفارغ (مهلة طويلة، int nanos) - تشبه هذه الطريقة الطريقة السابقة، ولكن مع مهلة أكثر دقة؛
-
void Finalize() - يتم استدعاء هذه الطريقة (أخيرًا) قبل أن تتم إزالة الكائن بواسطة أداة تجميع البيانات المهملة. يتم استخدامه لتنظيف الموارد المكتسبة.
12. ما الفرق بين تجربة الموارد ومحاولة الالتقاط أخيرًا عند العمل باستخدام الموارد؟
عادة، عند استخدام Try-catch-finally ، يتم استخدام الكتلة النهائية لإغلاق الموارد. يقدم Java 7 بيان المحاولة باستخدام الموارد الجديد . إنه مشابه لـ حاول الالتقاط أخيرًا لتحرير الموارد، ولكنه أكثر إحكاما وقابلية للقراءة. دعونا نتذكر كيف تبدو محاولة الالتقاط أخيرًا :String text = "some text......";
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(new FileWriter("someFileName"));
bufferedWriter.write(text);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
لنعد الآن كتابة هذا الكود، لكن باستخدام Try-with-resources :
String text = "some text......";
try(BufferedWriter bufferedWriter =new BufferedWriter(new FileWriter("someFileName"))) {
bufferedWriter.write(text);
} catch (IOException e) {
e.printStackTrace();
}
الآن أصبح الأمر أبسط إلى حدٍ ما، ألا تعتقد ذلك؟ بالإضافة إلى الكود الأبسط، هناك بعض النقاط الأخرى التي يجب ملاحظتها:
-
في Try-with-resources ، يجب أن تقوم الموارد المعلنة بين القوسين (الموارد التي سيتم إغلاقها) بتنفيذ الواجهة AutoCloseable وطريقة الإغلاق الوحيدة الخاصة بها .
يتم تنفيذ طريقة الإغلاق في كتلة ضمنية أخيرًا ، وإلا كيف سيكتشف البرنامج بالضبط كيفية إغلاق المورد؟
ولكن ربما نادرًا ما تكتب تطبيقاتك الخاصة للموارد وطريقة إغلاقها.
-
يتم تنفيذ الكتل بهذا الترتيب:
- كتلة المحاولة .
- الكتلة الضمنية أخيرًا .
- كتلة الالتقاط ، التي تلتقط الاستثناءات التي تحدث في الخطوات السابقة.
- الكتلة الصريحة أخيرًا .
كقاعدة عامة، الاستثناءات التي يتم طرحها في أسفل القائمة تقاطع تلك التي يتم طرحها في أعلى القائمة.
13. ما هي العمليات المتعلقة بالبت؟
عمليات Bitwise هي عمليات تتم على تسلسلات من البتات. وهي تشمل العمليات المنطقية والتحولات في اتجاه البت. العوامل المنطقية:-
bitwise AND - يقارن قيم البت. أي بت يتم ضبطه على 0 (خطأ) يضبط البت المقابل في النتيجة على 0. أي أنه إذا كان البت هو 1 (صحيح) في كلتا القيمتين المقارنة، فإن البت الناتج سيكون أيضًا 1.
يُشار إليه بـ AND أو &
مثال: 10111101 & 01100111 = 00100101
-
bitwise OR - هذه العملية هي عكس العملية السابقة. أي بت يتم ضبطه على 1 يؤدي إلى تعيين البت المقابل في النتيجة إلى 1. وبناءً على ذلك، إذا كانت البتة 0 في كلا القيمتين المقارنتين، فإن البت الناتج سيكون أيضًا 0.
يُشار إليه بـ OR أو |
مثال: 10100101 | 01100011 = 11100111
-
bitwise NOT — يتم تطبيق هذا العامل على قيمة واحدة. إنه يقلب (يقلب) البتات. أي أن البتات التي كانت 1 تصبح 0؛ وتلك التي كانت 0 تصبح 1.
يُشار إليه بـ NOT أو ~
مثال: ~10100101 = 01011010
-
حصريًا للبت OR — يقارن قيم البت. إذا كان كلا البتين 1، فإن البت الناتج هو 0. وإذا كان كلا البتين 0، فإن البت الناتج هو 0. وبعبارة أخرى، لكي يكون البت الناتج 1، يجب أن تكون واحدة فقط من البتات 1، و يجب أن يكون البت الآخر 0.
يُشار إليه بـ XOR أو ^
مثال: 10100101 ^ 01100011 = 11000110
- 01100011 >> 4 = 00000110
- 01100011 << 3 = 00011000
14. ما هي الكائنات القياسية غير القابلة للتغيير الموجودة في Java؟
يكون الكائن غير قابل للتغيير إذا لم يسمح بتغير قيمه الأصلية. قد تحتوي على طرق تُرجع كائنات جديدة من نفس النوع بقيم مختلفة. تتضمن بعض الكائنات القياسية غير القابلة للتغيير ما يلي:- مما لا شك فيه أن النوع الأكثر شهرة غير القابل للتغيير في Java هو String؛
- مثيلات فئات المجمع التي تغلف الأنواع القياسية: Boolean، Character، Byte، Short، Integer، Long، Double، Float؛
- كائنات BigInteger وBigDecimal، والتي تُستخدم عادةً للأرقام الكبيرة بشكل خاص؛
- كائنات StackTraceElement التي تشكل تتبع المكدس (على سبيل المثال، تتبع المكدس للاستثناء)؛
- كائن من فئة الملف - يمكنه تعديل الملفات، ولكن في نفس الوقت يظل الكائن نفسه دون تغيير؛
- UUIDs، والتي غالبًا ما تستخدم لتعريف العناصر بشكل فريد؛
- جميع كائنات الفئات في حزمة java.time؛
- الكائنات المحلية، والتي تستخدم لتحديد منطقة جغرافية أو سياسية أو ثقافية.
15. ما هي مميزات الأشياء غير القابلة للتغيير عن الأشياء العادية؟
-
تعتبر الكائنات غير القابلة للتغيير آمنة للاستخدام في بيئة متعددة مؤشرات الترابط . إنهم يقومون بذلك حتى لا تقلق بشأن فقدان البيانات بسبب ظروف السباق. وهذا يختلف عن العمل مع كائنات عادية. في هذه الحالة، عليك أن تفكر وتتوصل إلى آليات جيدة عند استخدام الكائن في بيئة موازية.
-
الكائنات غير القابلة للتغيير جيدة كمفاتيح في الخريطة. إذا كنت تستخدم كائنًا قابلاً للتغيير كمفتاح HashMap ثم تغيرت حالة الكائن، فقد يتم الخلط بين بنية البيانات: سيظل الكائن موجودًا، ولكن إذا كنت تستخدم يحتوي على Key()، فقد لا تجده.
-
تعتبر الكائنات غير القابلة للتغيير رائعة لتخزين البيانات غير القابلة للتغيير (الثابتة) التي لا ينبغي تغييرها أبدًا أثناء تشغيل البرنامج.
-
ميزة أخرى هي ذرية الفشل. إذا طرح كائن غير قابل للتغيير استثناءً، فلن يتم تركه في حالة غير مرغوب فيها (مكسورة).
-
من السهل اختبار هذه الفئات.
-
لا تحتاج إلى أي آليات إضافية مثل مُنشئ النسخ أو تنفيذ استنساخ الكائنات.
أسئلة حول OOP
16. ما هي مميزات OOP بشكل عام ومقارنتها بالبرمجة الإجرائية؟
حسنًا، مميزات OOP:-
تعد كتابة التطبيقات المعقدة باستخدام OOP أسهل من البرمجة الإجرائية حيث يتم تقسيم كل شيء إلى وحدات صغيرة - كائنات تتفاعل مع بعضها البعض - ونتيجة لذلك، يتم تقليل البرمجة إلى العلاقات بين الكائنات.
-
تعد التطبيقات المكتوبة باستخدام OOP أسهل بكثير في التعديل (عند مراعاة مبادئ التصميم بشكل صحيح).
-
نظرًا لأن كل من البيانات وعمليات البيانات تشكل كيانًا واحدًا، فلا يتم تلطيخها في جميع أنحاء التطبيق (وهو ما يحدث غالبًا في البرمجة الإجرائية).
-
مبدأ التغليف يحمي البيانات الأكثر أهمية من المستخدم.
-
يمكن إعادة استخدام نفس الكود مع بيانات مختلفة لأن الفئات تتيح لك إنشاء العديد من الكائنات، لكل منها قيمها الخاصة.
-
يتيح لك الوراثة وتعدد الأشكال أيضًا إعادة استخدام التعليمات البرمجية الموجودة وتوسيعها (بدلاً من تكرار وظائف مماثلة).
-
يعد توسيع الطلب أبسط من النهج الإجرائي.
-
يتيح نهج OOP استخلاص تفاصيل التنفيذ.
17. أخبرنا ما هي عيوب OOP
ولسوء الحظ، فهي موجودة أيضا:-
يتطلب OOP الكثير من المعرفة النظرية التي يجب إتقانها قبل أن تتمكن من كتابة أي شيء.
-
ليس من السهل فهم أفكار OOP وتطبيقها في الممارسة العملية (يجب أن تكون فيلسوفًا صغيرًا في القلب).
-
يؤدي OOP إلى تقليل أداء البرنامج قليلاً بسبب زيادة تعقيد النظام.
-
يتطلب أسلوب OOP ذاكرة أكبر نظرًا لأن كل شيء يتكون من فئات وواجهات وأساليب تشغل ذاكرة أكبر بكثير من المتغيرات العادية.
-
الوقت اللازم للتحليل الأولي أكبر من الوقت اللازم للنهج الإجرائي.
18. ما هو تعدد الأشكال الساكن مقابل تعدد الأشكال الديناميكي؟
يسمح تعدد الأشكال للكائنات من نفس الفئة أو الواجهة بالتصرف بشكل مختلف. هناك نوعان من تعدد الأشكال، المعروفين أيضًا بالربط المبكر والمتأخر. تعدد الأشكال الساكن، أو الارتباط المبكر:- يحدث في وقت الترجمة (في وقت مبكر من دورة حياة البرنامج)؛
- يقرر الطريقة التي سيتم تنفيذها في وقت الترجمة؛
- تعد طريقة التحميل الزائد مثالاً على تعدد الأشكال الساكن؛
- يتضمن الربط المبكر طرقًا خاصة وثابتة ونهائية؛
- لا يشارك الميراث في الارتباط المبكر؛
- لا يتضمن تعدد الأشكال الثابت كائنات محددة، بل معلومات حول نوع الفئة التي تظهر على يسار اسم المتغير.
- يحدث في وقت التشغيل (أثناء تشغيل البرنامج)؛
- يقرر تعدد الأشكال الديناميكي التنفيذ المحدد الذي ستطبقه الطريقة في وقت التشغيل؛
- يعد تجاوز الطريقة مثالاً على تعدد الأشكال الديناميكي؛
- الربط المتأخر يعني تعيين كائن محدد، أو مرجع من نوعه، أو فئته الفائقة؛
- يرتبط الميراث بتعدد الأشكال الديناميكي.
GO TO FULL VERSION