JPoint 2019解析

图片

大家好!

JPoint 2019是最顽固的Java会议之一,它已第七次结束,并且一如既往地打破了出席记录,这次活动吸引了Java开发领域的1700多名专家。

Odnoklassniki参加了所有JPoint会议。 自2013年以来,我们一直在积极支持JPoint,在我们的展位上,我们为参与者组织了各种Java知识测试活动。 今年,我们从领先的OK.ru开发人员那里完成了著名的“无法解决”的任务。 正确回答问题的与会人员将获得奖品。

公平地说,我必须说,在完成我们分发的任务的600张传单中,返回的少于100张,平均分数约为0.25。

最好的解决方案是,满分为5分,满分为4分。

我们发布任务及其解决方案,以便您可以测试自己的力量。

节拍是


有40%的人通过了答案,从而解决了这个问题。

迈克尔创建了BitSet的线程安全类似物。 添加setBit()方法的实现。

为了简单起见,可以将BitSet大小视为常量。

 public class ConcurrentBitSet { private final AtomicLongArray bits; public ConcurrentBitSet(int size) { assert size >= 0; int words = (size + 63) / 64; bits = new AtomicLongArray(words); } public void setBit(int index) { // TODO: Implement me! } } 

解决方案
Java 8提供的使用updateAndGet() / getAndUpdate()的实现可能如下所示:

 public void setBit(int index) { int word = index >> 6; long mask = 1L << index; bits.updateAndGet(word, value -> value | mask); } 

好的旧的compareAndSet()的实现类似于:

 public void setBit(int index) { int word = index >> 6; long mask = 1L << index; long oldValue; long newValue; do { oldValue = bits.get(word); newValue = oldValue | mask; } while (!bits.compareAndSet(word, oldValue, newValue)); } 


枚举不一样


通过答案的45%的人解决了这个问题。

塔蒂亚娜(Tatiana)想检查两个对象是否是同一enum常量。 她没有考虑什么?

 boolean sameEnum(Object o1, Object o2) { return o1.getClass().isEnum() && o1.getClass() == o2.getClass(); } 

解决方案
提示位于Enum.getDeclaringClass()方法的文档中,例如,在Enum.compareTo():使用该方法Enum.compareTo():

 public final Class<E> getDeclaringClass() { Class<?> clazz = getClass(); Class<?> zuper = clazz.getSuperclass(); return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper; } 

对于具有非空主体的枚举常量,将创建中间类,因此正确答案可能如下所示:

 boolean sameEnum(Object o1, Object o2) { return o1 instanceof Enum && o2 instanceof Enum && ((Enum) o1).getDeclaringClass() == ((Enum) o2).getDeclaringClass(); } 


未编译的链接


有42%的人通过了答案,解决了这个问题。

提供以下界面:

 interface Link<T> { T next(); } 

更改getTail() )方法的签名(而不是正文),以便代码编译时没有错误和警告。

 Link getTail(Link head) { if (head.next() == null) { return head; } return getTail(head.next()); } 

解决方案
只有三个正确的最小答案:

 <T extends Link<T>> Link<T> getTail(Link<T> head) <T extends Link<T>> Link<T> getTail(T head) <T extends Link<T>> T getTail(T head) 

看起来很矛盾,对于Java编译器来说,这样的签名太难了:

 <T extends Link<T>> T getTail(Link<T> head) 


信使


通过此问题的14%的人解决了这个问题。

Kostya正在开发消息传递应用程序。 指示通过网络发送消息的方法中的错误。

 void send(SocketChannel ch, String message) throws IOException { byte[] bytes = message.getBytes(); ByteBuffer header = ByteBuffer.allocate(4); header.putInt(bytes.length); ch.write(header); ch.write(ByteBuffer.wrap(bytes)); } 

解决方案
此代码中至少存在三个错误:


这看起来像是固定版本:

 void send(SocketChannel ch, String message) throws IOException { byte[] bytes = message.getBytes(StandardCharsets.UTF_8); ByteBuffer header = ByteBuffer.allocate(4); header.putInt(bytes.length); header.flip(); while (header.hasRemaining()) { ch.write(header); } ByteBuffer body = ByteBuffer.wrap(bytes); while (body.hasRemaining()) { ch.write(body); } } 


容器中的Java


通过答案的7.5%的人解决了这个问题。

应该为Alexei规定JVM的哪些参数,以防止Linux由于超出分配给容器的内存限制而终止Java进程?

  • -Xmx
  • -XX:MaxMetaspaceSize
  • -XX:ReservedCodeCacheSize
  • -XX:+UseContainerSupport
  • -XX:MaxRAMPercentage
  • JVM内存不能限制

解决方案
Java进程消耗的内存远不限于臀部,元空间和代码缓存。 许多其他的JVM结构也占用内存,并且并非所有的JVM结构都由设置来控制。 除了虚拟Java机器之外,Java类库和用户代码还通过Direct ByteBuffers和Mapped ByteBuffers分配本机内存。

UseContainerSupport参数与MaxRAMPercentage一起MaxRAMPercentage影响堆的大小。 因此,没有保证的方法可以避免仅使用JVM标志超过限制,而最后的答案将是正确的答案。 有关进程对Java内存的使用的更多信息,请参阅Joker 2018上的Andrei Pangin的报告 Shelf Process Java Storage”

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


All Articles