
Hallo allerseits!
JPoint 2019, eine der härtesten Java-Konferenzen, endete, fand zum siebten Mal statt und brach wie immer den Besucherrekord. Diesmal zog die Veranstaltung mehr als 1700 Spezialisten auf dem Gebiet der Java-Entwicklung an.
Odnoklassniki nahm an allen JPoint-Konferenzen teil. Seit 2013 unterstützen wir JPoint aktiv und organisieren an unseren Ständen verschiedene Java-Wissenstestaktivitäten für unsere Teilnehmer. Dieses Jahr hatten wir die berühmten "unlösbaren" Aufgaben der führenden OK.ru-Entwickler. Konferenzteilnehmer, die die Fragen richtig beantwortet haben, erhielten Preise.
Fairerweise muss ich sagen, dass von 600 Flugblättern mit den von uns übergebenen Aufgaben weniger als 100 zurückgegeben wurden und die durchschnittliche Punktzahl ungefähr 0,25 beträgt.
Die beste Lösung war, 4 von 5 möglichen Punkten zu erzielen.
Wir veröffentlichen Aufgaben und deren Lösungen, damit Sie Ihre Stärke testen können.
Beats sein
Dieses Problem wurde von 40% gelöst, die die Antworten bestanden haben.
Michael erstellt ein thread-sicheres Analogon von
BitSet
. Fügen Sie eine Implementierung der
setBit()
-Methode hinzu.
Der Einfachheit halber kann die
BitSet
Größe als konstant angesehen werden.
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) {
LösungEine Implementierung mit
updateAndGet()
/
getAndUpdate()
, die mit Java 8 verfügbar ist, könnte folgendermaßen aussehen:
public void setBit(int index) { int word = index >> 6; long mask = 1L << index; bits.updateAndGet(word, value -> value | mask); }
Die Implementierung auf dem guten alten
compareAndSet()
sieht ähnlich aus:
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 ist nicht dasselbe
Dieses Problem wurde von 45% gelöst, die die Antworten bestanden haben.
Tatiana möchte überprüfen, ob zwei Objekte Konstanten derselben
enum
. Was hat sie nicht berücksichtigt?
boolean sameEnum(Object o1, Object o2) { return o1.getClass().isEnum() && o1.getClass() == o2.getClass(); }
LösungDer Hinweis liegt in der Dokumentation zur
Enum.getDeclaringClass () -Methode, die beispielsweise in
Enum.compareTo():
public final Class<E> getDeclaringClass() { Class<?> clazz = getClass(); Class<?> zuper = clazz.getSuperclass(); return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper; }
Für Enum-Konstanten mit nicht leeren Körpern werden Zwischenklassen erstellt, sodass die richtige Antwort folgendermaßen aussehen kann:
boolean sameEnum(Object o1, Object o2) { return o1 instanceof Enum && o2 instanceof Enum && ((Enum) o1).getDeclaringClass() == ((Enum) o2).getDeclaringClass(); }
Nicht kompilierte Links
Dieses Problem wurde von 42% gelöst, die die Antworten bestanden haben.
Die folgende Schnittstelle ist verfügbar:
interface Link<T> { T next(); }
Ändern Sie die Signatur (aber nicht den Hauptteil) der Methode
getTail()
) so, dass der Code ohne Fehler und Warnungen kompiliert wird.
Link getTail(Link head) { if (head.next() == null) { return head; } return getTail(head.next()); }
LösungEs gibt nur drei richtige Mindestantworten:
<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)
So paradox es auch scheinen mag, eine solche Signatur ist für den Java-Compiler zu schwierig:
<T extends Link<T>> T getTail(Link<T> head)
Messenger
Dieses Problem wurde von 14% gelöst, die die Antworten bestanden haben.
Kostya entwickelt eine Messaging-Anwendung. Geben Sie Fehler in der Methode zum Senden von Nachrichten über das Netzwerk an.
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)); }
LösungDieser Code enthält mindestens drei Fehler:
Dies kann wie eine feste Version aussehen:
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 im Container
Dieses Problem wurde von 7,5% gelöst, die die Antworten bestanden haben.
Welche Parameter der JVM sollten Alexei vorgeschrieben werden, um zu verhindern, dass das Linux-Betriebssystem den Java-Prozess beendet, weil das für den Container zugewiesene Speicherlimit überschritten wird?
-Xmx
-XX:MaxMetaspaceSize
-XX:ReservedCodeCacheSize
-XX:+UseContainerSupport
-XX:MaxRAMPercentage
- Der JVM-Speicher kann nicht eingeschränkt werden
LösungDer vom Java-Prozess verbrauchte Speicher ist keineswegs auf Hip, Metaspace und Code Cache beschränkt. Viele andere JVM-Strukturen belegen ebenfalls Speicher, und nicht alle werden durch Einstellungen reguliert. Zusätzlich zur virtuellen Java-Maschine wird der native Speicher von der Java-Klassenbibliothek und dem Benutzercode über Direct ByteBuffers und Mapped ByteBuffers zugewiesen.
Der Parameter
MaxRAMPercentage
wirkt sich zusammen mit
MaxRAMPercentage
nur auf die Größe des Heaps aus. Daher gibt es keine garantierte Möglichkeit, das Überschreiten des Grenzwerts nur mit JVM-Flags zu vermeiden, und die letzte Antwort ist die richtige. Weitere Informationen zur Verwendung von Java-Speicher durch einen Prozess finden Sie im Bericht von Andrei Pangin auf Joker 2018
„ Shelf
Process Java Storage“ .