تحليل اللعبة من Classmates في جوكر 2018


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

لقد صنعنا ألعابًا مماثلة في المؤتمرات من قبل ، على سبيل المثال ، في JPoint الأخير هذا الربيع. لصنع لعبة ، كان علينا: 1) ابتكار آليات اللعبة ، 2) طرح الأسئلة ، 3) إدراك كل هذا.

يجب أن تكون ميكانيكا اللعبة بسيطة للغاية وبديهية ، ولكن في نفس الوقت ليست عادية للغاية ، حتى لا تحرم من الإثارة. نتيجة للمناقشات الطويلة ، توصلنا إلى اللعبة التالية:


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


تعاملنا مع الميكانيكا ، والآن نحتاج إلى طرح الأسئلة. يجب أن تكون من ثلاث فئات من التعقيد ، من أبسط إلى المتشددين. يجب أن تكون صياغة الأسئلة قصيرة للغاية ، ولن يكون هناك وقت لقراءة أوراق النص. يجب أن تكون خيارات الإجابة مثل عدم إعطاء الكثير من القرائن. حسنًا ، يجب أن تكون الأسئلة نفسها مثيرة للاهتمام وعملية. علاوة على ذلك ، كان يجب أن يكون هناك الكثير منهم حتى لا يتكرروا بسرعة كبيرة. نتيجة للجهود المشتركة ، تمكنا من طرح 130 سؤالًا حول هياكل البيانات ، والخوارزميات ، و "لغز جافا" ، والأسئلة المتشددة حول JVM الداخلية ، وحتى بعض الأسئلة حول Docker.


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

مرت أسبوعين من الفكرة إلى تحقيق الأسئلة والتنفيذ. بالطبع ، كل شيء في جافا. يستخدم التمهيد الربيع و Gradle. يرصد WEB- واجهة على الزاوي. كمخزن ، يتم استخدام قاعدة بيانات H2 المدمجة ، والتي تأتي من خارج الصندوق مع واجهة ويب ، وهي مريحة للغاية. تكوين الحامل هو جهازين MacBooks ، الصورة مكررة منها على جهازين تلفزيون. لسهولة الإعداد ، تم نشر التطبيق عن بعد على السحابة ( https://habr.com/company/odnoklassniki/blog/346868/ ).


تعلمنا منذ وقت طويل: لا ينبغي تطوير أي ميزة دون جمع الإحصاءات. بالطبع ، قمنا أيضًا بإرفاق إحصائيات مفصلة للعبة ، والتي يمكننا مشاركتها.

في المجموع ، لعبت اللعبة 811 مرة في يومين. إحصائيات الإجابات حسب درجة تعقيد السؤال:

الصعوبة
COUNT
CORRECT_PERCENT
1
3552
61
2
2031
49
3
912
46

ما هي خلايا الميدان وعدد المرات التي وصل فيها اللاعبون:


النسبة المئوية للإجابات الصحيحة في كل خلية من الحقول:


لكن الأكثر إثارة للاهتمام هو بالطبع إحصائيات الأسئلة. لم يكن من السهل تقييم مدى تعقيدها مع مراعاة التوزيع حسب الفئة ، والتقييم دائمًا غير موضوعي ، والسؤال البسيط لمستخدم صعب على مستخدم آخر. اقترح أوليغ التخلص من أحد الأسئلة بعبارة "حتى عمال النظافة يعرفون ذلك" ، ولكن اتضح أن العديد من عمال النظافة لا يعرفون الإجابات الصحيحة على العديد من الأسئلة "البسيطة" ، والمبرمجين أيضًا. نقدم لك بعض الأسئلة من لعبتنا - القادة على إجابات غير صحيحة ، حاول تقييم قوتك!

  1. نتيجة استدعاء هذا الرمز؟

    System.out.println(1/0d) 

    • يلقي استثناء حسابي
    • يطبع اللانهاية
    • طباعة "NaN"
    • ستطبع 0

    الجواب
    يبدو أن هذا سؤال بسيط للغاية. هنا حساب بسيط ، ما يمكن أن يكون الصيد ، لماذا قدم 28 ٪ فقط من اللاعبين الإجابة الصحيحة؟ قسمة عدد صحيح على 0 في Java ينتج ArithmeticException . ولكن هل هناك أعداد صحيحة هنا؟ سننظر بعناية. ما هذا "د" بعد 0؟ تعني هذه الرسالة أن هذا ليس عددًا صحيحًا ثابتًا 0 ، ولكنه قيمة من النوع double . وتبين أن التعبير مطابق لـ 1.0 / 0.0. وهذا قسمة على نقطة عائمة على صفر ، ونتيجة ذلك هي Double.POSITIVE_INFINITY . لذا فإن الإجابة الصحيحة هي "ب".
  2. نتيجة استدعاء هذا الرمز؟

     System.out.println( Long.MAX_VALUE==(long)Float.MAX_VALUE ); 

    • طباعة صحيح
    • ستطبع خطأ
    • يلقي استثناء حسابي

    الجواب
    أولاً ، تحتاج إلى فهم ما هو أكثر: Float.MAX_VALUE أو Long.MAX_VALUE ؟ على الرغم من أن float له نطاق قيم أقل من double ، إلا أن قيمته القصوى تقارب 20 أمرًا من الحجم يتجاوز نطاق القيم long المحتملة. ولكن كيف يعمل نوع الصب في هذه الحالة؟ يمكن للمرء أن يخمن ، ولكن من الأفضل تشغيل التعليمات البرمجية. والأفضل من ذلك ، افتح مواصفات لغة جافا ، قسم حول تضييق التحويل البدائي ، واقرأ أنه إذا كانت قيمة رقم الفاصلة العائمة كبيرة جدًا وتقع خارج نطاق القيم المتاحة لنوع صحيح ، فإن نتيجة التحويل تساوي الحد الأقصى للقيمة التي يمكن تمثيلها باستخدام نوع صحيح . على سبيل المثال نتيجة التحويل هي Long.MAX_VALUE . الجواب الصحيح قدمه 27٪ من المجيبين.
  3. أي فئة غير قابلة Comparable ؟

    • java.lang.String
    • java.util.TreeSet
    • java.io.File
    • java.lang.Enum

    الجواب
    هذا السؤال الذي يبدو بسيطًا حير الكثير أو بالأحرى 76٪ ممن أجابوا. خمن لنفسك أي من الإجابات هنا صحيحة وأيها كانت الإجابة الأكثر شيوعًا - اختارها 61٪ من اللاعبين.
  4. ما هو الرمز المطابق؟

     Object o = Math.min(-1, Double.MIN_VALUE) 

    • الكائن س = -1
    • الكائن o = Double.MIN_VALUE
    • الكائن س = -1.0

    الجواب
    القيمة double الدنيا هي بالتأكيد أقل من -1 ، فماذا يمكن أن يكون خطأ مرة أخرى؟ بالطبع ، كل شيء ليس بهذه البساطة ، وإلا فإننا لن نسأل. اتضح أن Double.MIN_VALUE لا يحتوي بالضبط على ما هو متوقع ، أي "الاحتفاظ المستمر Double.MIN_VALUE قيمة موجبة غير صفرية" ، وفقًا للوثائق. سيكون Double.MIN_POSITIVE_VALUE الأصح أن نسميها Double.MIN_POSITIVE_VALUE . Double مرة أخرى محاطة بإصبعه! الإجابة الصحيحة هي: Object o = -1.0 ، وبالتالي أجاب 22٪ فقط من اللاعبين.
  5. ما الخط الذي سينتج عن استدعاء هذا الرمز؟

     Long.toHexString(0x1_0000_0000L + 0xcafe_babe) 

    • 1 كافيه
    • مقهى
    • ffffffffcafebabe

    الجواب
    إذا اخترت الإجابة الثانية ، فأنت من بين 22٪ ممن أجابوا بشكل صحيح. هذا السؤال مأخوذ من كتاب Java Puzzlers: Traps و Pitfalls و Corner Cases الذي كتبه Joshua Bloch و Neal Gafter. إذا أجبت بشكل غير صحيح ، فلا تثبط عزيمتك ، وركض لقراءة هذا الكتاب!
  6. يقدم JDK 8 دعم التعليقات التوضيحية على معلمات الطريقة. هل من الممكن إضافة تعليق توضيحي إلى معلمة this الطريقة؟

    • هذا مستحيل
    • ربما ، ولكن فقط في البايت كود
    • ربما عن طريق تحديد this صراحة باعتباره المعلمة الأولى للطريقة

    الجواب
    عندما تمت إضافة القدرة على وضع التعليقات التوضيحية على معلمات الطريقة في JDK 8 ، لم يتم حرمان this المعلمة. لهذا الغرض ، يمكن الآن تحديد ذلك صراحة في توقيعات الطريقة:

     class Foo { public void test(@Annotated Foo this) {} } 

    على الرغم من أنه يمكنك الجدل حول فوائدها العملية ، إلا أنها الآن سمة من سمات اللغة. 32٪ من اللاعبين توقعوا الإجابة الصحيحة.
  7. في JDK 8 ، تؤثر المعلمة concurrencyLevel في مُنشئ ConcurrentHashMap على:

    • قراءة / كتابة التزامن المتاحة
    • حجم الجدول الأولي
    • على كلا المعلمتين

    الجواب
    إذا اخترت الخيار 2 ، فأنت من بين 15 ٪ ممن أعطوا الإجابة الصحيحة على هذا السؤال الأكثر صعوبة في اللعبة. الشيء هو أنه في JDK 8 تخلىوا عن الأجزاء في ConcurrentHashMap ، لذا فقد مستوى concurrencyLevel المعنى السابق. إنه يؤثر فقط على الحجم الأولي للجدول ، وحتى ذلك يحد فقط من القيمة initialCapacity من الأسفل.

Source: https://habr.com/ru/post/ar427735/


All Articles