SberTech ♥ Open Source, concurrence et opérations bancaires fiables - analyse des solutions aux problèmes avec Joker 2018

Ce week-end était Joker 2018 , c'était intéressant! Mais la conférence a été riche non seulement de discours. Toutes les sociétés sponsors ont essayé de se démarquer dans le contexte des «concurrents» et nous ne faisons pas exception.

Il y avait beaucoup de choses intéressantes sur le stand de Sberbank Technologies, mais je veux parler de ce pour quoi nous nous sommes démarqués. Notre équipe de développement Apache Ignite chez SberTech a préparé les tâches et a organisé un tirage au sort parmi ceux qui ont osé les résoudre.

Sous la coupe, vous trouverez les tâches, l'analyse des solutions et la possibilité de justifier votre propre version de la solution dans les commentaires.



Malheur aux commettants


Petya et Kolya commettent une fonctionnalité par jour dans Apache Ignite .

Masha teste rapidement chaque fonctionnalité et annule les validations contenant des erreurs.
Un troisième commit initial de Petit et un cinquième de Kolya contiennent une erreur.
Petya passe 2 jours supplémentaires pour corriger l'erreur, Kolya 3, et ils le font à nouveau
commettre.

Combien de fonctionnalités seront communiquées en 86 jours ouvrables si Masha aime Petya,
et elle ne remarque son erreur que ce jour-là alors que lui seul se trompe?

Solution
À partir du 13e jour, un cycle se forme qui permet à Petya de ne corriger qu'une erreur sur deux.

La réponse
64 + 54 = 118;

Villaribo et Villabaggio


Traitement d'une banque peu fiable lors d'opérations sur un groupe de clés de blocs de comptes
comptes dans l'ordre de leur déclaration dans l'opération, c'est-à-dire de gauche à droite.
Chaque impasse est résolue manuellement par les spécialistes de la banque et prend 10 fois plus.
temps que le fonctionnement normal.
Le traitement d'une banque fiable bloque toujours les clés dans l'ordre croissant, mais passe 2
fois plus qu'une transaction normale dans une banque peu fiable.
Les deux banques ont 10 comptes, les clés de compte sont des nombres de 1 à 10.
Le traitement de chaque banque nécessite 12 opérations.
Les opérations se déroulent en parallèle, deux à la fois. Chaque opération affecte jusqu'à 3
comptes:
- opération n ° 1 (comptes: A, B, C), où A = i, B = A + 1, C = (A + B)% 10,
- opération n ° 2 (comptes: D, E, F), où D = 11-i, E = D-1, F = (D + E)% 10,
i varie de 1 à 6.
L'exécution de la prochaine paire d'opérations ne commence qu'après l'achèvement complet
le précédent.
Les clés sont bloquées conformément à la politique de la banque, une dans chacune des opérations,
de l'opération numéro 1.
Si la clé est déjà verrouillée dans l'une des opérations, mais est nécessaire pour effectuer une autre,
puis d'abord la première opération est terminée, puis la seconde continue.
L'exécution forcée d'une paire d'opérations en mode séquentiel devrait se produire 2 fois plus lentement qu'en parallèle.
Quelle banque et combien de fois plus rapide terminera ses opérations?

Indice
Total:
- 6 itérations,
- 12 opérations
- dans toutes les opérations sauf une, 3 touches chacune.

Solution
Si toutes les clés sont différentes, l'exécution parallèle est possible.
Sinon, alors non, et un blocage est possible.

Calculs
Une banque peu fiable dépense pour une transaction 1 "tact", 2 en cas de "difficultés" et jusqu'à 10 en cas d'impasse.
Une banque fiable dépense sur la transaction 2 "mesures" et 4 en cas de "difficultés". Des blocages fiables n'existent pas.

La réponse
Terminez en même temps.

Risques liés aux référentiels publics


Serezha est une programmeuse très expérimentée, extrêmement joueuse et infiniment gourmande.
Une fois qu'il a trouvé le code source de son fourre-tout préféré sur un github.
Quelle est la mise minimale que Seryozha peut gagner?

Une liste simplifiée de fourre-tout est jointe:

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" -     } 

Astuce # 1
- 131072?
- Non, sortez du piège :)
Astuce n ° 2
Quelle est la mise minimale que Seryozha peut gagner?
Astuce n ° 3
 th1{ bid.restricted = true; bid.checked = true; } ... th2{ while (!bid.checked) { sleep(1); } assert bid.restricted; // 99.999% } 

Il n'y a aucune garantie de visibilité intuitivement attendue.

Vous pouvez les ajouter comme suit:

 volatile boolean checked; 

Astuce n ° 4
Quelle est la mise minimale que Seryozha peut gagner?
Solution

La réponse
 java.lang.Integer#MIN_VALUE 

Cependant, «0» et même «1» étaient considérés comme la bonne décision.

Les gagnants


Le meilleur de tous a résolu le problème
- Evgeny Zubenko
- Alexander Novikov
- Andrey Golikov

Les gars ont reçu des sacs à dos, des t-shirts et, bien sûr, des livres de marque.

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


All Articles