小丑2018年同学的游戏分析


大家好! 几天前,我们发布了一篇有关2018年Joker大会上给出的谜题的帖子 ,但这还不是全部! 今年,特别是对于Joker来说,我们制作了一个完整的游戏,其中包含不少有趣的Java任务(不仅如此),今天我们将讨论这些任务。

例如在今年春季的JPoint之前,我们在会议上做了类似的游戏。 要制作游戏,我们必须:1)提出游戏机制,2)提出问题,3)意识到所有这些。

游戏机制应该非常简单,直观,但同时又不要太平庸,以免引起兴奋。 经过长期讨论,我们提出了以下游戏:


在回答问题时,我们必须尝试带领Duke(位于左上角)进入其他角落的一扇门。 对于一场比赛,分配了3分钟。 要打开该单元格,您需要正确回答该问题,该问题是根据类别随机选择的。 对于正确答案,将给予分数,对于错误答案,将给予分数,带有问题的单元格将被阻止,必须绕过该单元格。 结果,路径可能会变得很长甚至阻塞。 玩家可以选择不同的策略:尽快到达出口并获得额外的奖励; 在指定的时间内回答尽可能多的问题; 在简单的问题上走很长的路要走,或者在更复杂的问题上直接走,并获得更多积分。


我们处理了力学问题,现在我们需要提出问题。 它们必须具有三类复杂性,从最简单到最复杂。 问题的措词应该非常简短,没有时间阅读正文。 答案的选择应尽量避免提供太多线索。 好吧,问题本身应该是有趣且实用的。 而且,应该有很多这样的内容,以便它们不会很快重复。 经过共同努力,我们设法提出了130个关于数据结构,算法,“ java难题”,关于JVM内部的核心问题,甚至是关于Docker的问题。


有一个问题:游戏会显示在大屏幕上,而站在附近的人会记住几个游戏的大部分答案。 起初,似乎我们需要数百个问题才能最大程度地降低记忆的可能性。 但是,经过反思,他们意识到还有更简单的选择。 首先,删除鼠标控件,仅保留键盘。 现在,站在附近的人看到了问题,但看不到玩家选择了哪个答案。 添加了答案选项的混合,使记忆变得复杂。 对于每个问题,添加了几个相似但略有不同的措词。 当然,您仍然可以记住答案,这从会议第二天的明显改善中可以明显看出。 许多用户花了数十分钟来玩游戏,试图打破其他人的记录。 但是,这里的一切都像生活中一样-热情得到了回报。

从构思到问题的实现和实施已经过去了两个星期。 当然,一切都在Java中。 二手Spring Boot和Gradle。 WEB界面是在Angular上创建的。 作为存储,使用了内置的H2数据库,该数据库开箱即用,带有Web界面,非常方便。 支架配置为两台MacBook,两张电视上均复制了该图片。 为了易于设置,该应用程序已远程部署到我们的云( https://habr.com/company/odnoklassniki/blog/346868/ )。


我们很久以前就学到了:不收集统计信息就不会开发任何功能。 当然,我们还为游戏添加了详细的统计信息,我们可以共享这些统计信息。

总共,游戏在两天内播放了811次。 根据问题的复杂性统计答案:

困难
COUNT个
CORRECT_PERCENT
1个
3552
61
2
2031年
49
3
912
46

玩家到达哪个区域以及到达的频率:


字段的每个单元格上正确答案的百分比:


但是,最有趣的当然是问题的统计数据。 考虑按类别的分布来评估其复杂性并不是那么容易,评估始终是主观的,对于一个用户来说,一个简单的问题对另一个用户来说是困难的。 奥列格(Oleg)建议用“即使清洁工也知道”一词抛出一个问题,但事实证明,没有很多清洁工知道许多“简单”问题的正确答案,程序员也是如此。 我们向您提供游戏中的一些问题-领导者关于错误答案的问题,请尝试评估您的实力!

  1. 调用此代码的结果?

    System.out.println(1/0d) 

    • 引发ArithmeticException
    • 打印无限
    • 打印“ NaN”
    • 将列印0

    答案
    这似乎是一个非常简单的问题。 这是一个简单的算术运算,可能是成功的原因,为什么只有28%的玩家给出正确答案? 在Java中将整数除以0会导致ArithmeticException 。 但是这里有整数吗? 我们会仔细看的。 0之后的“ d”是什么? 该字母表示这不是整数常量0,而是double类型的值。 事实证明,该表达式等于1.0 / 0.0。 这是一个浮点数除以零的结果,其结果是Double.POSITIVE_INFINITY 。 因此正确的答案是“ b”。
  2. 调用此代码的结果?

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

    • 打印真实
    • 将打印错误
    • 引发ArithmeticException

    答案
    首先,您需要了解更多内容: Float.MAX_VALUELong.MAX_VALUE ? 尽管float的值范围小于double值,但其最大值超出了可能的long值范围约20个数量级。 但是在这种情况下,类型转换如何工作? 可以猜测,但是最好运行代码。 更好的是,打开Java语言规范中有关缩小基元转换的部分,并阅读到,如果浮点数的值太大并且超出整数类型的可用值范围,则转换结果等于可以使用整数类型表示的最大值。 即 转换结果是Long.MAX_VALUE 。 正确答案由27%的受访者给出。
  3. 哪一类是不可比的?

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

    答案
    这个看似简单的问题使许多回答者感到困惑,确切地说是76%。 自己猜猜哪个答案是正确的,哪个是最受欢迎的答案-61%的玩家选择了它。
  4. 相同的代码是什么?

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

    • 对象o = -1
    • 对象o = Double.MIN_VALUE
    • 对象o = -1.0

    答案
    最小double值肯定小于-1,又有什么问题呢? 当然,一切都不是那么简单,否则我们不会问。 事实证明,根据文档, Double.MIN_VALUE并不完全包含预期的内容,即“常数持有最小的非零正值”。 将其称为Double.MIN_POSITIVE_VALUEDouble.MIN_POSITIVE_VALUE正确。 双手指再次盘旋! 正确的答案是: Object o = -1.0 ,因此只有22%的玩家回答。
  5. 调用此代码会导致哪一行?

     Long.toHexString(0x1_0000_0000L + 0xcafe_babe) 

    • 1个咖啡厅
    • 咖啡宝贝
    • ffffffffcafebabe

    答案
    如果您选择了第二个答案,那么您是正确回答者中的22%。 这个问题摘自约书亚·布洛赫(Joshua Bloch)和尼尔·古夫特(Neal Gafter)撰写的《 Java拼图:陷阱,陷阱和困境》一书。 如果您回答不正确,请不要气,,并努力阅读这本书!
  6. JDK 8引入了对方法参数注释的支持。 是否可以在this方法的参数中添加注释?

    • 这是不可能的
    • 也许,但仅在字节码中
    • 也许通过将this明确定义为方法的第一个参数

    答案
    在JDK 8中添加了在方法参数上添加批注的功能时, this参数未被删除。 为此,现在可以在方法签名中明确指定:

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

    尽管您可以争论它的实际好处,但是现在它是该语言的功能。 32%的球员猜对了答案。
  7. 在JDK 8中, ConcurrentHashMap构造函数中的concurrencyLevel参数影响:

    • 读/写并发可用
    • 初始表格大小
    • 在两个参数上

    答案
    如果您选择选项2,那么您中有15%的人对这个游戏中最困难的问题给出了正确答案。 事实是,在JDK 8中,他们放弃了ConcurrentHashMap段,因此concurrencyLevel失去了其先前的含义。 它仅影响表的初始大小,甚至仅从下面限制initialCapacity值。

Source: https://habr.com/ru/post/zh-CN427735/


All Articles