Análise do JPoint 2019

imagem

Olá pessoal!

O JPoint 2019, uma das conferências Java mais graves, terminou, foi realizada pela sétima vez e, como sempre, quebrou o recorde de presença, desta vez o evento atraiu mais de 1700 especialistas na área de desenvolvimento Java.

Odnoklassniki participou de todas as conferências da JPoint. Desde 2013, apoiamos ativamente o JPoint e, em nossos estandes, organizamos várias atividades de teste de conhecimento de Java para nossos participantes. Este ano, tivemos as famosas tarefas "insolúveis" dos principais desenvolvedores do OK.ru. Os participantes da conferência que responderam às perguntas receberam os prêmios corretamente.

Para ser justo, devo dizer que, de 600 folhetos com as tarefas que entregamos, menos de 100 foram devolvidos, a pontuação média é de aproximadamente 0,25.

A melhor solução foi conseguir 4 pontos em 5 possíveis.

Publicamos tarefas e suas soluções para que você possa testar sua força.

Beats be


Este problema foi resolvido por 40% que passaram as respostas.

Michael cria um análogo seguro de BitSet do BitSet . Adicione uma implementação do método setBit() .

Para simplificar, o tamanho do BitSet pode ser considerado 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! } } 

Solução
Uma implementação usando updateAndGet() / getAndUpdate() , disponível no Java 8, pode ter a seguinte aparência:

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

A implementação no bom e velho compareAndSet() é semelhante:

 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ão é o mesmo


Esse problema foi resolvido por 45% que passaram nas respostas.

Tatiana deseja verificar se dois objetos são constantes do mesmo enum . O que ela não levou em consideração?

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

Solução
A dica está na documentação do método Enum.getDeclaringClass () , que é usado, por exemplo, em Enum.compareTo():

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

Para constantes enum com corpos não vazios, são criadas classes intermediárias; portanto, a resposta correta pode ser assim:

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


Links não compilados


Esse problema foi resolvido por 42% que passaram nas respostas.

A seguinte interface está disponível:

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

Altere a assinatura (mas não o corpo) do método getTail() ) para que o código seja compilado sem erros e avisos.

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

Solução
Existem apenas três respostas mínimas corretas:

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

Por mais paradoxal que pareça, essa assinatura é muito difícil para o compilador Java:

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


Messenger


Este problema foi resolvido por 14% que passaram nas respostas.

Kostya está desenvolvendo um aplicativo de mensagens. Indique erros no método para enviar mensagens pela rede.

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

Solução
Há pelo menos três erros neste código:


Pode parecer uma versão fixa:

 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 no contêiner


Esse problema foi resolvido por 7,5% que passaram nas respostas.

Quais parâmetros da JVM devem ser prescritos para Alexei para impedir que o Linux interrompa o processo Java devido a exceder o limite de memória alocado para o contêiner?

  • -Xmx
  • -XX:MaxMetaspaceSize
  • -XX:ReservedCodeCacheSize
  • -XX:+UseContainerSupport
  • -XX:MaxRAMPercentage
  • A memória JVM não pode ser limitada

Solução
A memória consumida pelo processo Java está longe de ser limitada a hip, Metaspace e Code Cache. Muitas outras estruturas da JVM também ocupam memória e nem todas são reguladas por configurações. Além da máquina Java virtual, a memória nativa é alocada pela Java Class Library e pelo código do usuário por meio de Direct ByteBuffers e Mapped ByteBuffers.

O parâmetro MaxRAMPercentage junto com MaxRAMPercentage afeta apenas o tamanho da pilha. Portanto, não há maneira garantida de evitar exceder o limite usando apenas os sinalizadores da JVM, e a última resposta será a correta. Para obter mais informações sobre o uso da memória Java por um processo, consulte o relatório de Andrei Pangin no Joker 2018 " Shelf Process Java Storage" .

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


All Articles