
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) {
SoluçãoUma 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çãoA 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çãoExistem 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çãoHá 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çãoA 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" .