SberTech ♥ Open Source, simultaneidade e operações bancárias confiáveis ​​- análise de soluções para problemas com o Joker 2018

Este fim de semana foi Joker 2018 , foi interessante! Mas a conferência foi rica não apenas em discursos. Todas as empresas patrocinadoras tentaram se destacar no contexto de “concorrentes” e não somos exceção.

Havia muitas coisas interessantes no estande da Sberbank Technologies, mas quero falar sobre o que nos destacamos. Nossa equipe de desenvolvimento Apache Ignite da SberTech preparou as tarefas e realizou um empate entre aqueles que ousaram resolvê-las.

Abaixo do corte, você encontrará tarefas, análises de soluções e a capacidade de justificar sua própria versão da solução nos comentários.



Ai de comissários


Petya e Kolya confirmam um recurso por dia no Apache Ignite .

O Masha testa rapidamente todos os recursos e reverte as confirmações que contêm erros.
Cada terceiro commit inicial do Petit e quinto do Kolya contém um erro.
Petya passa mais 2 dias para corrigir o erro, Kolya 3, e eles novamente
confirmar.

Quantos recursos serão comunicados em 86 dias úteis se Masha gostar de Petya,
e ela percebe o erro dele apenas naquele dia em que apenas ele está enganado?

Solução
A partir do 13º dia, é formado um ciclo que permite que Petya conserte apenas cada segundo erro.

A resposta
64 + 54 = 118;

Villaribo e Villabaggio


Processar um banco não confiável durante operações em um grupo de contas bloqueia chaves
contas na ordem de sua declaração na operação, ou seja, da esquerda para a direita.
Cada impasse é resolvido manualmente pelos especialistas do banco e leva 10 vezes mais.
tempo que a operação normal.
O processamento de um banco confiável sempre bloqueia as chaves ascendentes, mas gasta 2
vezes mais do que uma transação normal em um banco não confiável.
Ambos os bancos têm 10 contas, as chaves das contas são números de 1 a 10.
O processamento de cada banco requer 12 operações.
As operações são realizadas em paralelo, duas de cada vez. Cada operação afeta até 3
contas:
- operação no. 1 (contas: A, B, C), em que A = i, B = A + 1, C = (A + B)% 10,
- operação no. 2 (contas: D, E, F), em que D = 11-i, E = D-1, F = (D + E)% 10,
i varia de 1 a 6.
A execução do próximo par de operações começa apenas após a conclusão completa
o anterior.
As chaves são bloqueadas de acordo com a política do banco, uma em cada uma das operações, iniciando
da operação número 1.
Se a chave já estiver bloqueada em uma das operações, mas for necessária para executar outra,
depois primeiro a primeira operação é concluída, depois a segunda continua.
Espera-se que a execução forçada de um par de operações no modo seqüencial ocorra duas vezes mais lentamente que em paralelo.
Qual banco e quantas vezes mais rápido concluirá as operações?

Sugestão
Total:
- 6 iterações,
- 12 operações
- em todas as operações, exceto uma, 3 teclas cada.

Solução
Se todas as chaves forem diferentes, a execução paralela é possível.
Caso contrário, não, e o impasse é possível.

Cálculos
Um banco não confiável gasta em uma transação 1 "tato", 2 no caso de "dificuldades" e até 10 no caso de impasse.
Um banco confiável gasta na transação 2 "medidas" e 4 em caso de "dificuldades". Não existem deadlocks confiáveis.

A resposta
Conclua ao mesmo tempo.

Riscos do Repositório Público


Serezha é um programador muito experiente, extremamente apostador e infinitamente ganancioso.
Uma vez ele encontrou o código fonte de sua bolsa favorita no github.
Qual é a aposta mínima que Seryozha pode ganhar?

Uma lista de compras simplificada está anexada:

class Bid { //  int amount; boolean checked; boolean restricted; Bid(int amount) {this.amount = amount;} } ~~~ AtomicReference<Bid> ref = new AtomicReference<>(); volatile boolean winner = false; ~~~ Thread validator = new Thread(() -> { //  ! while (true) { Bid bid = ref.get(); if (bid == null) continue; if ((((bid.amount << 5) ^ 1_000_000) >>> 6) < (2 << 15)) bid.restricted = true; bid.checked = true; } }); Thread payer = new Thread(() -> { //  ! while (true) { Bid bid = ref.get(); if (bid == null) continue; if (bid.checked) { if (!bid.restricted) winner = true; // ! ref.set(null); } } }); ~~~ synchronized boolean makeMeRich(int amount){ //    ? if (winner) return false; //    -    ref.set(new Bid(amount)); while(ref.get() != null) sleep(1); return winner; //   "true" -     } 

Dica # 1
- 131072?
- Não, saia da armadilha :)
Dica 2
Qual é a aposta mínima que Seryozha pode ganhar?
Dica # 3
 th1{ bid.restricted = true; bid.checked = true; } ... th2{ while (!bid.checked) { sleep(1); } assert bid.restricted; // 99.999% } 

Não há garantias de visibilidade intuitivamente esperadas.

Você pode adicioná-los da seguinte maneira:

 volatile boolean checked; 

Dica # 4
Qual é a aposta mínima que Seryozha pode ganhar?
Solução

A resposta
 java.lang.Integer#MIN_VALUE 

No entanto, "0" e até "1" foram considerados como a decisão certa.

Vencedores


O melhor de tudo resolveu o problema
- Evgeny Zubenko
- Alexander Novikov
- Andrey Golikov

Os caras receberam mochilas de marca, camisetas e, claro, livros.

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


All Articles