
大家好!
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) {
解决方案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” 。