JavaRush /مدونة جافا /Random-AR /جافا كور. أسئلة للمقابلة، الجزء 3
Vadim625
مستوى

جافا كور. أسئلة للمقابلة، الجزء 3

نشرت في المجموعة
ناقشنا في المقالتين السابقتين بعض الأسئلة المهمة التي يتم طرحها عليك غالبًا في المقابلات. حان الوقت للمضي قدمًا وإلقاء نظرة على بقية الأسئلة.
جافا كور.  أسئلة المقابلة، الجزء 3 - 1

النسخ العميق والنسخ السطحي

نسخة طبق الأصل من الأصل هي استنساخها. في Java، هذا يعني القدرة على إنشاء كائن ببنية مشابهة للكائن الأصلي. clone()توفر الطريقة هذه الوظيفة. نسخ النسخ الضحلة بأقل قدر ممكن من المعلومات. افتراضيًا، يكون الاستنساخ في Java سطحيًا، أي. Object classلا يعرف عن بنية الفصل الذي ينسخه. عند الاستنساخ، يقوم JVM بما يلي:
  1. إذا كانت الفئة تحتوي فقط على أعضاء من الأنواع البدائية، فسيتم إنشاء نسخة جديدة تمامًا من الكائن وسيتم إرجاع مرجع لذلك الكائن.
  2. إذا كانت الفئة لا تحتوي فقط على أعضاء من الأنواع البدائية، ولكن أيضًا على أعضاء من أي نوع فئة آخر، فسيتم نسخ المراجع إلى كائنات هذه الفئات. لذلك، سيكون لكلا الكائنين نفس المراجع.
النسخ العميق يكرر كل شيء. النسخ العميق عبارة عن مجموعتين، إحداهما تكرر جميع عناصر المجموعة الأصلية. نريد إنشاء نسخة بحيث لا يؤثر إجراء تغييرات على أي عنصر في النسخة على المجموعة الأصلية. يتطلب الاستنساخ العميق القواعد التالية:
  1. ليست هناك حاجة لنسخ البيانات البدائية بشكل منفصل؛
  2. يجب أن تدعم كافة فئات الأعضاء في الفئة الأصلية الاستنساخ. يجب استدعاء كل عضو في الفصل super.clone()عند تجاوز الطريقة clone()؛
  3. إذا كان أي عضو في فئة لا يدعم الاستنساخ، ففي طريقة الاستنساخ، تحتاج إلى إنشاء مثيل جديد لتلك الفئة ونسخ كل عضو من أعضائها بجميع السمات إلى كائن فئة جديد، واحدًا تلو الآخر.
تعرف على المزيد حول الاستنساخ هنا

ما هي المزامنة؟ قفل على مستوى الكائن وقفل على مستوى الفصل؟

يشير التزامن إلى تعدد العمليات. لا يمكن تنفيذ كتلة التعليمات البرمجية المتزامنة إلا بواسطة مؤشر ترابط واحد في المرة الواحدة. تتيح لك Java معالجة سلاسل رسائل متعددة في وقت واحد. قد يؤدي هذا إلى رغبة خيطين أو أكثر في الوصول إلى نفس الحقل. تساعد المزامنة على تجنب أخطاء الذاكرة التي تحدث عند استخدام موارد الذاكرة بشكل غير صحيح. عندما يتم الإعلان عن طريقة متزامنة، يحتفظ مؤشر الترابط بشاشته. إذا حاول مؤشر ترابط آخر الوصول إلى طريقة متزامنة في هذا الوقت، فسيتم حظر الخيط وينتظر حتى تصبح الشاشة حرة. تتم المزامنة في Java باستخدام الكلمة الأساسية المتزامنة الخاصة . يمكنك وضع علامة على الكتل أو الأساليب الفردية في صفك بهذه الطريقة. لا يمكن استخدام الكلمة الأساسية المتزامنة مع متغيرات الفئة أو سماتها. القفل على مستوى الكائن هو آلية عندما تريد مزامنة طريقة غير ثابتة أو كتلة تعليمات برمجية غير ثابتة بحيث يمكن لخيط واحد فقط تنفيذ كتلة التعليمات البرمجية على مثيل معين للفئة. يجب أن يتم ذلك دائمًا لجعل مؤشر ترابط مثيل الفئة آمنًا. يمنع القفل على مستوى الفئة سلاسل رسائل متعددة من الدخول إلى كتلة متزامنة لجميع المثيلات المتاحة للفئة. على سبيل المثال، إذا كان هناك 100 مثيل لفئة DemoClass، فسيكون مؤشر ترابط واحد فقط قادرًا على تنفيذ الديموMethod() باستخدام أحد المتغيرات في وقت معين. يجب أن يتم ذلك دائمًا لضمان سلامة الخيط الثابت. تعرف على المزيد حول المزامنة هنا.

ما الفرق بين النوم () والانتظار ()؟

Sleep()هي طريقة تستخدم لتأخير العملية لبضع ثوان. في حالة wait()، يكون الخيط في حالة انتظار حتى نستدعي الطريقة notify()أو notifyAll(). والفرق الرئيسي هو أنه wait()يحرر قفل الشاشة بينما sleep()لا يحرر القفل. Wait()يستخدم للتطبيقات متعددة الخيوط، sleep()ويستخدم ببساطة لإيقاف تنفيذ الخيط مؤقتًا. Thread.sleep()يضع مؤشر الترابط الحالي في حالة "غير قابل للتشغيل" لفترة معينة من الوقت. يحفظ الخيط حالة الشاشة التي كانت قبل استدعاء هذه الطريقة. إذا اتصل خيط آخر t.interrupt()، فإن الخيط الذي "نام" سوف يستيقظ. لاحظ أن هذه sleep()طريقة ثابتة، مما يعني أنها تؤثر دائمًا على الخيط الحالي (الذي ينفذ الطريقة sleep()). من الأخطاء الشائعة استدعاء t.sleep()أين tيوجد خيط آخر؛ sleep()حتى عندما لا يكون الخيط الحالي الذي يسمى الطريقة tخيطًا. Object.wait()يرسل مؤشر الترابط الحالي إلى الحالة "غير قابل للتشغيل" لفترة من الوقت، تمامًا مثل sleep(), ولكن مع بعض الفروق الدقيقة. Wait()يتم استدعاؤه على كائن، وليس على خيط؛ نحن نسمي هذا الكائن "كائن القفل". قبل الاتصال lock.wait()، يجب مزامنة مؤشر الترابط الحالي مع "كائن القفل"؛ wait()بعد ذلك، يقوم بتحرير هذا القفل، وإضافة الخيط إلى "قائمة الانتظار" المرتبطة بهذا القفل. لاحقًا، يمكن لخيط آخر المزامنة مع نفس كائن القفل واستدعاء lock.notify(). ستعمل هذه الطريقة على "تنشيط" الخيط الأصلي الذي لا يزال ينتظر. من حيث المبدأ، يمكن مقارنة wait()/ بـ / ، فقط الخيط النشط لا يحتاج إلى مؤشر مباشر إلى الخيط النائم، بل يحتاج فقط إلى معرفة كائن القفل المشترك. اقرأ الفرق التفصيلي هنا.notify()sleep()interrupt()

هل من الممكن تعيين قيمة فارغة لهذا لمتغير مرجعي؟

لا لا يمكنك. في Java، يجب أن يكون الجانب الأيسر من عامل التعيين متغيرًا. "هذه" هي كلمة أساسية خاصة توفر دائمًا المثيل الحالي للفئة. انها ليست مجرد أي متغير. وبالمثل، لا يمكن تعيين null لمتغير باستخدام الكلمة الأساسية "super" أو أي كلمة رئيسية أخرى مماثلة.

ما الفرق بين && و&؟

&- bitwise و- &&منطقيا.
  1. &يقيم جانبي العملية؛
  2. &&يقيم الجانب الأيسر من العملية. إذا كان هذا صحيحا، فإنه يستمر في تقييم الجانب الأيمن.
انظر هنا للحصول على فهم أعمق.

كيفية تجاوز أساليب يساوي () وhachCode ()؟

hashCode()ويتم equals()تعريف الأساليب في الفصل Object، وهو الفصل الأصلي لكائنات Java. لهذا السبب، ترث كافة كائنات Java التطبيق الافتراضي للطرق. يتم استخدام هذه الطريقة hashCode()للحصول على عدد صحيح فريد لكائن معين. يتم استخدام هذا العدد الصحيح لتحديد موقع الكائن عند الحاجة إلى تخزينه، على سبيل المثال إلى HashTable. افتراضيًا، hashCode()يتم إرجاع integerتمثيل لعنوان موقع الذاكرة حيث تم تخزين الكائن. تُستخدم الطريقة equls()، كما يوحي اسمها، لاختبار ما إذا كان جسمان متساويان أم لا. يتحقق التنفيذ الافتراضي من مراجع الكائنات لمعرفة ما إذا كانت متساوية. فيما يلي إرشادات مهمة لإعادة تحميل هذه الطرق:
  1. استخدم دائمًا نفس سمات الكائن عند إنشاء hashCode()و equals()؛
  2. تناظر. أولئك. xإذا أعاد صحيحًا لبعض الكائنات y x.equals(y)، y.equals(x)فيجب أن يعود صحيحًا؛
  3. الانعكاسية. لأن أي كائن x x.equals(x)يجب أن يعود صحيحًا؛
  4. تناسق. لأي كائنات xوإرجاع y x.equals(y)نفس الشيء إذا لم تتغير المعلومات المستخدمة في المقارنات؛
  5. عبورية. بالنسبة لأي كائن و x، إذا أعاد صحيحًا وأعاد صحيحًا، فيجب أن يعود صحيحًا؛yzx.equals(y)y.equals(z)x.equals(z)
  6. عندما يتم استدعاء أسلوب ما على نفس الكائن أثناء تنفيذ التطبيق، فإنه يجب أن يُرجع نفس الرقم ما لم تتغير المعلومات المستخدمة. hashCodeيمكن إرجاع قيم مختلفة لكائنات متطابقة في حالات تطبيق مختلفة؛
  7. إذا كان هناك كائنان متساويان، وفقًا لـ equals، فيجب عليهما hashCodeإرجاع نفس القيم؛
  8. والشرط المعاكس اختياري. يمكن لكائنين غير متساويين إرجاع نفس رمز التجزئة. ومع ذلك، لتحسين الأداء، من الأفضل أن تقوم كائنات مختلفة بإرجاع رموز مختلفة.
اقرأ حقائق مثيرة للاهتمام حول هذه الأساليب هنا.

أخبرنا عن معدّلات الوصول

يمكن أن تحتوي فئات Java والحقول والمنشئات والأساليب على واحد من أربعة معدلات وصول مختلفة: خاص إذا تم وضع علامة على أسلوب أو متغير على أنه خاص ، فيمكن فقط للتعليمات البرمجية الموجودة داخل نفس الفئة الوصول إلى المتغير أو استدعاء الطريقة. لا يمكن للكود الموجود داخل الفئات الفرعية الوصول إلى متغير أو طريقة، ولا يمكنه الوصول إليه من أي فئة أخرى. غالبًا ما يتم استخدام مُعدِّل الوصول الخاص للمُنشئين والأساليب والمتغيرات. الافتراضي يتم الإعلان عن معدل الوصول الافتراضي إذا لم يتم تحديد المعدل على الإطلاق. يعني هذا المعدل أنه يمكن الحصول على الوصول إلى الحقول والمنشئات والأساليب الخاصة بفئة معينة عن طريق التعليمات البرمجية داخل الفئة نفسها، والتعليمات البرمجية داخل الفئات في نفس الحزمة. لا يمكن للفئات الفرعية الوصول إلى الأساليب ومتغيرات الأعضاء الخاصة بالفئة الفائقة إذا تم تعريفها على أنها افتراضية ، ما لم تكن الفئة الفرعية في نفس الحزمة مثل الفئة الفائقة. محمي يعمل المعدل المحمي بنفس الطريقة الافتراضية ، باستثناء أن الفئات الفرعية يمكنها أيضًا الوصول إلى الأساليب والمتغيرات المحمية للفئة الفائقة. هذا البيان صحيح حتى لو لم تكن الفئة الفرعية في نفس الحزمة مثل الفئة الفائقة. عام يعني معدل الوصول العام أنه يمكن لجميع التعليمات البرمجية الوصول إلى الفئة أو متغيراتها أو منشئاتها أو أساليبها، بغض النظر عن مكان وجود هذا الرمز. جافا كور.  أسئلة للمقابلة، الجزء 3 - 2

ما هو جامع القمامة؟ هل يمكننا الاتصال به؟

جمع البيانات المهملة هي إحدى ميزات إدارة الذاكرة التلقائية في العديد من لغات البرمجة الحديثة، مثل Java ولغات NET.Framework. غالبًا ما تفسر اللغات التي تستخدم جمع البيانات المهملة جمع البيانات المهملة في جهاز افتراضي مثل JVM. جمع البيانات المهملة له غرضان: يجب تحرير أي ذاكرة غير مستخدمة، ويجب عدم تحرير الذاكرة إذا كان البرنامج لا يزال يستخدمها. هل يمكنك تشغيل جمع القمامة يدويًا؟ لا، System.gc()فهو يوفر لك أكبر قدر ممكن من الوصول. الخيار الأفضل هو استدعاء الطريقة System.gc()، والتي ستلمح إلى أداة تجميع البيانات المهملة التي تحتاج إلى تشغيلها. لا توجد طريقة لتشغيله على الفور نظرًا لأن أداة تجميع مجمعي البيانات المهملة غير حتمية. بالإضافة إلى ذلك، وفقًا للوثائق، OutOfMemoryErrorلن تتم إعادة توجيهه إذا فشل الجهاز الظاهري في تحرير الذاكرة بعد عملية تجميع البيانات المهملة بالكامل. تعلم المزيد عن جامع القمامة هنا.

ماذا تعني الكلمة الرئيسية الأصلية؟ شرح بالتفصيل

يتم استخدام الكلمة الأساسية الأصلية للإشارة إلى أن الطريقة يتم تنفيذها بلغة برمجة غير ملف Java. وقد تم استخدام الأساليب الأصلية في الماضي. في الإصدارات الحالية من Java، تكون هناك حاجة إلى هذا الأمر بشكل أقل. حاليًا، هناك حاجة إلى الأساليب الأصلية عندما:
  1. يجب عليك الاتصال بمكتبة من Java مكتوبة بلغة أخرى.
  2. أنت بحاجة إلى الوصول إلى موارد النظام أو الأجهزة التي لا يمكن الوصول إليها إلا باستخدام لغة أخرى (عادةً لغة C). في الواقع، لا يمكن استدعاء العديد من وظائف النظام التي تتفاعل مع الكمبيوتر الحقيقي (مثل الأقراص أو بيانات الشبكة) إلا من خلال الطريقة الأصلية.
تعتبر عيوب استخدام مكتبات الطريقة الأصلية مهمة أيضًا:
  1. يمكن لـ JNI/JNA زعزعة استقرار JVM، خاصة إذا حاولت القيام بشيء معقد. إذا كانت طريقتك الأصلية تفعل شيئًا خاطئًا، فهناك احتمالية تعطل JVM. أيضًا، يمكن أن تحدث أشياء سيئة إذا تم استدعاء طريقتك الأصلية من عدة سلاسل رسائل. وما إلى ذلك وهلم جرا.
  2. من الصعب تصحيح أخطاء البرنامج باستخدام التعليمات البرمجية الأصلية .
  3. تتطلب التعليمات البرمجية الأصلية إنشاء أطر عمل منفصلة، ​​مما قد يؤدي إلى حدوث مشكلات عند النقل إلى منصات أخرى.

ما هو التسلسل؟

في علوم الكمبيوتر، في سياق تخزين البيانات ونقلها، التسلسل هو عملية ترجمة بنية البيانات أو حالة الكائن إلى تنسيق يمكن تخزينه واسترجاعه لاحقًا في بيئة حاسوبية أخرى. بعد تلقي سلسلة من البتات، يتم إعادة حسابها وفقًا لتنسيق التسلسل، ويمكن استخدامها لإنشاء نسخة متطابقة لغويًا من الكائن الأصلي. توفر Java تسلسلًا تلقائيًا، الأمر الذي يتطلب من الكائن تنفيذ الواجهة java.io.Serializable. يقوم تطبيق الواجهة بوضع علامة على الفئة على أنها "قابلة للتسلسل". لا تحتوي واجهة java.io.Serializable على طرق تسلسل، ولكن يمكن للفئة القابلة للتسلسل تحديد الأساليب التي سيتم استدعاؤها بشكل اختياري كجزء من عملية التسلسل/إلغاء التسلسل. عند إجراء تغييرات على الفئات، عليك أن تفكر في أي منها سيكون متوافقًا مع التسلسل وأي منها لن يكون متوافقًا. يمكنك قراءة التعليمات الكاملة هنا. سأعطي أهم النقاط: التغييرات غير المتوافقة:
  1. حذف حقل؛
  2. نقل فئة لأعلى أو لأسفل في التسلسل الهرمي؛
  3. تغيير حقل غير ثابت إلى ثابت أو غير عابر إلى عابر؛
  4. تغيير نوع البيانات البدائية المعلنة؛
  5. تغيير الطريقة WriteObjectبحيث ReadObjectلا يكتبون أو يقرأون الحقول بشكل افتراضي؛
  6. تغيير الفئة Serializableإلى Externalizableأو العكس؛
  7. تغيير فئة التعداد إلى فئة غير التعداد أو العكس؛
  8. إزالة Serializableأو Externalizable;
  9. إضافة writeReplaceطريقة readResolveإلى فئة.
التغييرات المتوافقة:
  1. إضافة الحقول.
  2. إضافة/إزالة الفئات؛
  3. إضافة طرق WriteObject/ReadObject[طرق defaultReadObjectأو defaultWriteObjectيجب استدعاؤها في البداية]؛
  4. WriteObject/ReadObjectطرق الإزالة
  5. إضافة java.io.Serializable؛
  6. تغيير الوصول الميداني؛
  7. تغيير حقل ثابت إلى غير ثابت أو عابر إلى غير عابر .
روابط للأجزاء السابقة: Java Core. أسئلة المقابلة، الجزء 1 جافا الأساسية. أسئلة المقابلة، الجزء 2 المقال الأصلي دراسة سعيدة!
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION