Analyse des Spiels von Classmates bei Joker 2018


Hallo allerseits! Vor ein paar Tagen haben wir einen Beitrag über die Rätsel veröffentlicht, die auf der Joker 2018-Konferenz gegeben wurden. Aber das ist noch nicht alles! Dieses Jahr haben wir speziell für Joker ein ganzes Spiel mit nicht weniger interessanten Java-Aufgaben (und nicht nur) erstellt, über die wir heute sprechen werden.

Wir haben ähnliche Spiele auf Konferenzen gemacht, zum Beispiel vor dem letzten JPoint in diesem Frühjahr. Um ein Spiel zu machen, mussten wir: 1) Spielmechaniken entwickeln, 2) Fragen stellen, 3) all dies realisieren.

Die Spielmechanik sollte sehr einfach, intuitiv und gleichzeitig nicht zu banal sein, um nicht der Aufregung zu berauben. Aufgrund langer Diskussionen haben wir folgendes Spiel entwickelt:


Bei der Beantwortung von Fragen müssen wir versuchen, Duke (in der oberen linken Ecke) in eine der Türen in anderen Ecken zu führen. Für eine Sitzung des Spiels sind 3 Minuten vorgesehen. Um die Zelle zu öffnen, müssen Sie die Frage richtig beantworten, die jedes Mal zufällig entsprechend der Kategorie ausgewählt wird. Punkte werden für richtige Antworten vergeben, eine Strafe für falsche Antworten, die Zelle mit der Frage ist blockiert und muss umgangen werden. Infolgedessen kann sich herausstellen, dass der Pfad ziemlich lang oder sogar blockiert ist. Die Spieler können verschiedene Strategien wählen: Gehen Sie so schnell wie möglich zum Ausgang und erhalten Sie einen zusätzlichen Bonus. Beantworten Sie so viele Fragen wie möglich in der vorgegebenen Zeit. Gehen Sie bei einfachen Fragen oder direkt bei komplexeren Fragen einen langen Weg und erhalten Sie mehr Punkte.


Wir haben uns mit der Mechanik befasst, jetzt müssen wir uns Fragen stellen. Sie müssen drei Kategorien von Komplexität aufweisen, von der einfachsten bis zur Hardcore-Kategorie. Der Wortlaut der Fragen sollte extrem kurz sein, es bleibt keine Zeit, die Textblätter zu lesen. Die Antwortmöglichkeiten sollten so sein, dass nicht zu viele Hinweise gegeben werden. Nun, die Fragen selbst sollten interessant und praktisch sein. Außerdem hätte es viele geben sollen, damit sie sich nicht zu schnell wiederholten. Dank gemeinsamer Bemühungen konnten wir 130 Fragen zu Datenstrukturen, Algorithmen, "Java-Puzzle", Hardcore-Fragen zu JVM-Interna und sogar einige Fragen zu Docker stellen.


Es gibt ein Problem: Das Spiel wird auf dem großen Bildschirm angezeigt, und diejenigen, die in der Nähe stehen, werden sich die meisten Antworten für mehrere Spiele merken. Zuerst schien es, als würden wir Hunderte von Fragen brauchen, um die Möglichkeit des Auswendiglernen zu minimieren. Beim Nachdenken stellten sie jedoch fest, dass es einfachere Optionen gibt. Entfernen Sie zu Beginn die Maussteuerung und lassen Sie nur die Tastatur übrig. Jetzt sehen diejenigen, die in der Nähe stehen, die Frage, aber nicht, welche Antwort der Spieler gewählt hat. Das Mischen von Antwortoptionen wurde hinzugefügt, was das Auswendiglernen erschwert. Für jede Frage wurden mehrere ähnliche, aber leicht unterschiedliche Formulierungen hinzugefügt. Natürlich können Sie sich noch an die Antworten erinnern, und dies zeigte sich an den deutlich verbesserten Ergebnissen am zweiten Tag der Konferenz. Viele Benutzer haben zehn Minuten damit verbracht, das Spiel zu spielen, um den Rekord anderer zu brechen. Aber hier ist alles wie im Leben - Eifer wird belohnt.

Von der Idee bis zur Realisierung der Fragen und der Umsetzung vergingen zwei Wochen. Natürlich ist alles in Java. Gebrauchte Spring Boot und Gradle. Die WEB-Schnittstelle wird auf Angular erstellt. Als Speicher wird die integrierte H2-Datenbank verwendet, die sofort mit einer Webschnittstelle geliefert wird, was sehr praktisch ist. Die Standkonfiguration besteht aus zwei MacBooks, deren Bild auf zwei Fernsehgeräten dupliziert wird. Zur Vereinfachung der Einrichtung wurde die Anwendung remote in unserer Cloud bereitgestellt ( https://habr.com/company/odnoklassniki/blog/346868/ ).


Wir haben vor langer Zeit gelernt: Ohne das Sammeln von Statistiken sollte keine Funktion entwickelt werden. Natürlich haben wir dem Spiel auch detaillierte Statistiken beigefügt, die wir teilen können.

Insgesamt wurde das Spiel in zwei Tagen 811 Mal gespielt. Statistik der Antworten in Abhängigkeit von der Komplexität der Frage:

SCHWIERIGKEIT
COUNT
CORRECT_PERCENT
1
3552
61
2
2031
49
3
912
46

Zu welchen Zellen des Feldes und wie oft haben die Spieler erreicht:


Der Prozentsatz der richtigen Antworten in jeder Zelle des Feldes:


Am interessantesten ist natürlich die Statistik der Fragen. Es war nicht so einfach, ihre Komplexität unter Berücksichtigung der Verteilung nach Kategorien zu bewerten, die Bewertung ist immer subjektiv und eine einfache Frage für einen Benutzer ist für einen anderen schwierig. Oleg schlug vor, eine der Fragen mit den Worten „Selbst die Reinigungskräfte wissen es“ zu verwerfen, aber es stellte sich heraus, dass nicht viele Reinigungskräfte die richtigen Antworten auf viele „einfache“ Fragen kennen, und auch Programmierer. Wir bieten Ihnen einige Fragen unserer Spielleiter zu falschen Antworten. Versuchen Sie, Ihre Stärke zu bewerten!

  1. Das Ergebnis des Aufrufs dieses Codes?

    System.out.println(1/0d) 

    • Löst eine ArithmeticException aus
    • Druckt Unendlichkeit
    • Druckt "NaN"
    • Gibt 0 aus

    Die Antwort
    Dies scheint eine sehr einfache Frage zu sein. Hier ist eine einfache Arithmetik: Was könnte der Haken sein, warum haben nur 28% der Spieler die richtige Antwort gegeben? Das Teilen einer Ganzzahl durch 0 in Java führt zu einer ArithmeticException . Aber gibt es hier ganze Zahlen? Wir werden genau hinschauen. Was ist das "d" nach 0? Dieser Buchstabe bedeutet, dass dies keine Ganzzahlkonstante 0 ist, sondern ein Wert vom Typ double . Und es stellt sich heraus, dass der Ausdruck mit 1.0 / 0.0 identisch ist. Und dies ist eine Division durch einen Gleitkomma durch Null, deren Ergebnis Double.POSITIVE_INFINITY . Die richtige Antwort lautet also "b".
  2. Das Ergebnis des Aufrufs dieses Codes?

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

    • print true
    • wird false drucken
    • löst eine ArithmeticException aus

    Die Antwort
    Zunächst müssen Sie verstehen, was mehr ist: Float.MAX_VALUE oder Long.MAX_VALUE ? Obwohl der float einen kleineren Wertebereich als das double , liegt sein Maximalwert ungefähr 20 Größenordnungen außerhalb des Bereichs möglicher long Werte. Aber wie funktioniert Typ Casting in diesem Fall? Man kann raten, aber es ist besser, den Code auszuführen. Öffnen Sie noch besser die Java-Sprachspezifikation, einen Abschnitt zum Eingrenzen der primitiven Konvertierung, und lesen Sie, dass das Konvertierungsergebnis dem Maximalwert entspricht, der mit einem Ganzzahltyp dargestellt werden kann, wenn der Wert einer Gleitkommazahl zu groß ist und außerhalb des Bereichs der verfügbaren Werte eines Ganzzahltyps liegt . Das heißt, Das Konvertierungsergebnis ist Long.MAX_VALUE . Die richtige Antwort wurde von 27% der Befragten gegeben.
  3. Welche Klasse ist nicht Comparable ?

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

    Die Antwort
    Diese scheinbar einfache Frage verwirrte viele oder vielmehr 76% derjenigen, die antworteten. Erraten Sie selbst, welche der Antworten hier richtig ist und welche die beliebteste Antwort war - 61% der Spieler haben sie gewählt.
  4. Womit ist der Code identisch?

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

    • Objekt o = -1
    • Objekt o = Double.MIN_VALUE
    • Objekt o = -1,0

    Die Antwort
    Der minimale double ist sicherlich kleiner als -1, was könnte wiederum falsch sein? Natürlich ist nicht alles so einfach, sonst würden wir nicht fragen. Es stellt sich heraus, dass Double.MIN_VALUE nicht genau das enthält, was erwartet wird, nämlich "Konstante mit dem kleinsten positiven Wert ungleich Null", so die Dokumentation. Es wäre richtiger, es Double.MIN_POSITIVE_VALUE zu nennen. Double umkreiste wieder seinen Finger! Die richtige Antwort lautet: Object o = -1.0 , und so antworteten nur 22% der Spieler.
  5. Welche Zeile ergibt sich aus dem Aufruf dieses Codes?

     Long.toHexString(0x1_0000_0000L + 0xcafe_babe) 

    • 1cafebabe
    • Cafebabe
    • ffffffffcafebabe

    Die Antwort
    Wenn Sie die zweite Antwort gewählt haben, gehören Sie zu 22% derjenigen, die richtig geantwortet haben. Diese Frage stammt aus dem Buch Java Puzzlers: Fallen, Fallstricke und Eckfälle, das von Joshua Bloch und Neal Gafter verfasst wurde. Wenn Sie falsch geantwortet haben, lassen Sie sich nicht entmutigen und lesen Sie dieses Buch!
  6. JDK 8 bietet Unterstützung für Anmerkungen zu Methodenparametern. Ist es möglich, dem Parameter this Methode eine Anmerkung hinzuzufügen?

    • Es ist unmöglich
    • Vielleicht, aber nur in Bytecode
    • Vielleicht indem Sie this explizit als ersten Parameter für die Methode definieren

    Die Antwort
    Wenn in JDK 8 die Möglichkeit hinzugefügt wurde, Anmerkungen zu Methodenparametern hinzuzufügen, wurde this Parameter nicht entzogen. Zu diesem Zweck kann this jetzt explizit in Methodensignaturen angegeben werden:

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

    Obwohl Sie über die praktischen Vorteile streiten können, ist es jetzt ein Merkmal der Sprache. 32% der Spieler haben die richtige Antwort erraten.
  7. In JDK 8 wirkt sich der Parameter concurrencyLevel im ConcurrentHashMap Konstruktor auf Folgendes aus:

    • Lese- / Schreib-Parallelität verfügbar
    • Anfängliche Tabellengröße
    • Auf beiden Parametern

    Die Antwort
    Wenn Sie Option 2 gewählt haben, gehören Sie zu den 15%, die die schwierigste Antwort auf diese schwierigste Frage des Spiels gegeben haben. Die Sache ist, dass sie in JDK 8 Segmente in ConcurrentHashMap aufgegeben haben, sodass concurrencyLevel seine vorherige Bedeutung verloren hat. initialCapacity wirkt sich nur auf die Anfangsgröße der Tabelle aus, und selbst das begrenzt nur den Wert für die initialCapacity von unten.

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


All Articles