Analyse JPoint 2019

image

Bonjour à tous!

L'une des conférences Java les plus hardcore a pris fin - JPoint 2019, elle s'est tenue pour la septième fois et, comme toujours, a battu le record de fréquentation, cette fois, l'événement a attiré plus de 1700 spécialistes dans le domaine du développement Java.

Odnoklassniki a participé à toutes les conférences JPoint. Depuis 2013, nous soutenons activement JPoint et, sur nos stands, nous organisons diverses activités de test de connaissances Java pour nos participants. Cette année, nous avons eu les fameuses tâches «insolubles» des principaux développeurs OK.ru. Les participants à la conférence qui ont répondu correctement aux questions ont reçu des prix.

Pour être honnête, je dois dire que sur 600 dépliants avec les tâches que nous avons distribuées, moins de 100 ont été retournés, le score moyen est d'environ 0,25.

La meilleure solution était de marquer 4 points sur 5 possibles.

Nous publions des tâches et leurs solutions afin que vous puissiez tester votre force.

Beats be


Ce problème a été résolu par 40% qui ont réussi les réponses.

Michael crée un analogue thread-safe de BitSet . Ajoutez une implémentation de la méthode setBit() .

Par souci de simplicité, la taille de BitSet peut être considérée comme constante.

 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! } } 

Solution
Une implémentation utilisant updateAndGet() / getAndUpdate() , disponible avec Java 8, pourrait ressembler à ceci:

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

L'implémentation sur le bon vieux compareAndSet() ressemble:

 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)); } 


Enum n'est pas pareil


Ce problème a été résolu par 45% des répondants qui ont réussi les réponses.

Tatiana veut vérifier si deux objets sont des constantes de la même enum . De quoi n'a-t-elle pas tenu compte?

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

Solution
L'astuce réside dans la documentation de la méthode Enum.getDeclaringClass () , qui est utilisée, par exemple, dans Enum.compareTo():

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

Pour les constantes enum avec des corps non vides, des classes intermédiaires sont créées, donc la bonne réponse pourrait ressembler à ceci:

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


Liens non compilés


Ce problème a été résolu par 42% qui ont réussi les réponses.

L'interface suivante est disponible:

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

Modifiez la signature (mais pas le corps) de la méthode getTail() ) afin que le code se compile sans erreurs ni avertissements.

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

Solution
Il n'y a que trois bonnes réponses minimales:

 <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) 

Aussi paradoxal que cela puisse paraître, une telle signature est trop difficile pour le compilateur Java:

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


Messenger


Ce problème a été résolu par 14% qui ont réussi les réponses.

Kostya développe une application de messagerie. Indiquez des erreurs dans la méthode d'envoi des messages sur le réseau.

 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)); } 

Solution
Il y a au moins trois erreurs dans ce code:


Cela peut ressembler à une version fixe:

 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 en conteneur


Ce problème a été résolu par 7,5% qui ont réussi les réponses.

Quels paramètres de la JVM doivent être prescrits à Alexei afin d'empêcher Linux de tuer le processus Java en raison du dépassement de la limite de mémoire allouée au conteneur?

  • -Xmx
  • -XX:MaxMetaspaceSize
  • -XX:ReservedCodeCacheSize
  • -XX:+UseContainerSupport
  • -XX:MaxRAMPercentage
  • La mémoire JVM ne peut pas être limitée

Solution
La mémoire consommée par le processus Java est loin d'être limitée à hip, Metaspace et Code Cache. De nombreuses autres structures JVM occupent également de la mémoire et elles ne sont pas toutes réglementées par des paramètres. En plus de la machine Java virtuelle, la mémoire native est allouée par la bibliothèque de classes Java et le code utilisateur via Direct ByteBuffers et Mapped ByteBuffers.

Le paramètre UseContainerSupport avec MaxRAMPercentage affecte uniquement la taille du MaxRAMPercentage de MaxRAMPercentage . Ainsi, il n'y a aucun moyen garanti d'éviter de dépasser la limite en utilisant uniquement des indicateurs JVM, et la dernière réponse sera la bonne. Pour plus d'informations sur l'utilisation de la mémoire Java par un processus, consultez le rapport d'Andrei Pangin au Joker 2018 « Shelf Process Java Storage» .

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


All Articles