
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) {
SolutionUne 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(); }
SolutionL'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()); }
SolutionIl 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)); }
SolutionIl 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
SolutionLa 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» .