Alfa Battle - como foi, gravação da conferência e lista de tarefas

No início de junho, lançamos o Alfa Battle for Java Developers. É hora de falar sobre como tudo correu, compartilhar vídeos úteis dos palestrantes da conferência "Coding of the Future" (Alfa-Bank, Beeline, X5 Retail Group) e mostrar nossas tarefas. A propósito, sobre as tarefas. Ou exageramos e superestimamos os possíveis participantes, ou o tempo estava ruim, em geral, dos 1498 participantes de 50 cidades, ninguém resolveu completamente todos os problemas (5 peças). Portanto, abaixo do corte você encontrará todas as tarefas com uma descrição e, se quiser resolvê-las, pode fazê-lo sem prazos. Teremos o prazer de convidar aqueles que dominam







... No final do post - sobre uma nova estratégia para contratação de especialistas. Houve um tempo em que a TI do Alfa-Bank estava concentrada principalmente em três cidades - Moscou, São Petersburgo, Yekaterinburg. Agora podemos olhar para pessoas de todo o país. E não só.



Obrigado a todos que responderam - foram mais de 1.500 dessas pessoas, das quais 198 chegaram à final que mostraram os melhores resultados. Sim, não foi fácil: as tarefas acabaram sendo mais difíceis do que muitos participantes esperavam, e o formato do campeonato online com stream em conferência, francamente, foi tenso. Ainda assim, 5 horas de programação online não é uma experiência retro em uma equipe.



No total, são três vencedores que receberam um prêmio em dinheiro, além de convites para trabalhar para nós e para parceiros do campeonato. Aqui estão eles:



1Âş lugar: Mikhail Burshtein, Moscou (250.000 rublos)

2Âş lugar: Alexander Ilyushechkin, Moscou (150.000 rublos)

3Âş lugar: Pavel Lyubinsky, SĂŁo Petersburgo (100.000 rublos)



Tarefas



# 1 Onde fica o caixa eletrĂ´nico



Detalhes da tarefa

Doença



-.

REST API IP:8080.

API – api.json.



- API .

: api.alfabank.ru/node/238

API .

: api.alfabank.ru/start



* IP — IP .

* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task1





1. deviceId



: GET IP:8080/atms/{deviceId}

:

— 200 AtmResponse

— 404 ErrorResponse ( )



:



GET http://IP:8080/atms/153463
200
{
  "deviceId": 153463,
  "latitude": "55.6610213",
  "longitude": "37.6309405",
  "city": "",
  "location": " ., 4, . 10",
  "payments": false
}




:



GET http://IP:8080/atms/1
404
{
  “status”: “atm not found”
}




18 .



2. (-)



- — .

3 ! -.



payments=true, (. - API ATMServices).



: GET IP:8080/atms/nearest?latitude=string&longitude=string&payments=boolean

: 200 AtmResponse



:
GET http://IP:8080/atms/nearest?latitude=55.66&longitude=37.63
200
{
  "deviceId": 153463,
  "latitude": "55.6610213",
  "longitude": "37.6309405",
  "city": "",
  "location": " ., 4, . 10",
  "payments": false
}




:



GET http://IP:8080/atms/nearest?latitude=55.66&longitude=37.63&payments=true
200
{
  "deviceId": 210612,
  "latitude": "55.66442",
  "longitude": "37.628051",
  "city": "",
  "location": " , . 14",
  "payments": true
}




36 .



3.



- .

, .



: GET IP:8080/atms/nearest-with-alfik?latitude=string&longitude=string&alfik=int

: 200 [AtmResponse]



, WebSocket STOMP .



:



mkdir task1 ; cd task1

wget https://raw.githubusercontent.com/evgenyshiryaev/alfa-battle-resources/master/task1/docker-compose.yml

docker-compose up -d




( task1):

docker-compose down

: ws://IP:8100

: { “deviceId”: 0 }

/topic/alfik: { “deviceId”: 0, “alfik”: 0 }



:
 GET http://IP:8080/atms/nearest-with-alfik?latitude=55.66&longitude=37.63&alfik=300000
200
[{
  "deviceId": 153463,
  "latitude": "55.6610213",
  "longitude": "37.6309405",
  "city": "",
  "location": " ., 4, . 10",
  "payments": false
}]


(.. 153463 — 383026 )



:
GET http://IP:8080/atms/nearest-with-alfik?latitude=55.66&longitude=37.63&alfik=400000
200
[{
  "deviceId": 153463,
  "latitude": "55.6610213",
  "longitude": "37.6309405",
  "city": "",
  "location": " ., 4, . 10",
  "payments": false
},
{
  “deviceId": 153465,
  "latitude": "55.6602801",
  "longitude": "37.633823",
  "city": "",
  "location":"  ., 18",
  "payments": false
}]


( , )



# 2 Analise-o



Detalhes da tarefa



Kafka RAW_PAYMENTS .

docker IP:29092 .



Kafka.



:

mkdir task2 ; cd task2

wget https://raw.githubusercontent.com/evgenyshiryaev/alfa-battle-resources/master/task2/data.txt

wget https://raw.githubusercontent.com/evgenyshiryaev/alfa-battle-resources/master/task2/docker-compose.yml

wget https://raw.githubusercontent.com/evgenyshiryaev/alfa-battle-resources/master/task2/start.sh

bash start.sh


.



( task2):

docker-compose down



* IP — IP .

* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task2



:



key1:{"ref":"U030306190000188", "categoryId":1, "userId":"XAABAA", "recipientId":"XA3SZV", "desc":"  ", "amount":10.0}




, key1 — .

.



:

  • Kafka.
  • .
  • REST API . 8081.




RAW_PAYMENTS. .



, .



, Kafka .



.





, , . , ( , - ).



:

  1. consumer-group-id. .
  2. consumer-group. , , ,




docker exec -i broker kafka-consumer-groups --bootstrap-server broker:9092 --all-groups --all-topics --reset-offsets --to-earliest --execute



start.sh, . ,



Swagger-



Swagger- api-swagger.json .





:



key1:{"ref":"ref1", "categoryId":1, "userId":"User_1", "recipientId":"User_2", "desc":" _1", "amount":10.0}
key2:{"ref":"ref2", "categoryId":2, "userId":"User_1", "recipientId":"User_2", "desc":" _2", "amount":350.56}
key3:{"ref":"ref3", "categoryId":1, "userId":"User_1", "recipientId":"User_2", "desc":" _3", "amount":700.0}
key4:{"ref":"ref4", "categoryId":3, "userId":"User_1", "recipientId":"User_2", "desc":" _4", "amount":5.99}
key5:{"ref":"ref5", "categoryId":1, "userId":"User_1", "recipientId":"User_2", "desc":" _5", "amount":10.0}
key6:{"ref":"ref6", "categoryId":2, "userId":"User_2", "recipientId":"User_3", "desc":" _6", "amount":350.56}
key7:{"ref":"ref7", "categoryId":1, "userId":"User_1", "recipientId":"User_2", "desc":" _7", "amount":890.0}
key8:{"ref":"ref8", "categoryId":3, "userId":"User_3", "recipientId":"User_2", "desc":" _8", "amount":35.99}
key9:{"ref":"ref9", "categoryId":1, "userId":"User_1", "recipientId":"User_2", "desc":" _9", "amount":890.0}
key10:{"ref":"ref10", "categoryId":3, "userId":"User_3", "recipientId":"User_2", "desc":" _10", "amount":35.9910}
key11:{"ref":"ref11", "categoryId":1, "userId":"User_1", "recipientId":"User_2", "desc":" _11", "amount":10.0}
key12:{"ref":"ref12", "categoryId":2, "userId":"User_2", "recipientId":"User_3", "desc":" _12", "amount":350.56}
key13:{"ref":"ref13", "categoryId":1, "userId":"User_1", "recipientId":"User_2", "desc":" _13", "amount":10.0}
key14:{"ref":"ref14", "categoryId":2, "userId":"User_2", "recipientId":"User_3", "desc":" _14", "amount":350.56}
key15:{"ref":"ref15", "categoryId":4, "userId":"User_1", "recipientId":"User_4", "desc":" _15", "amount":15.00}




1.



( categoryId).

, .



.



GET IP:8081/admin/health



200



:

{"status":"UP"}

<h4>GET http://IP:8081/analytic</h4>
200








:

[
  {
    "userId": "User_3",
    "totalSum": 71.981,
    "analyticInfo": {
      "3": {
        "min": 35.99,
        "max": 35.991,
        "sum": 71.981
      }
    }
  },
  {
    "userId": "User_2",
    "totalSum": 1051.68,
    "analyticInfo": {
      "2": {
        "min": 350.56,
        "max": 350.56,
        "sum": 1051.68
      }
    }
  },
  {
    "userId": "User_1",
    "totalSum": 2891.55,
    "analyticInfo": {
      "1": {
        "min": 10,
        "max": 890,
        "sum": 2520
      },
      "2": {
        "min": 350.56,
        "max": 350.56,
        "sum": 350.56
      },
      "3": {
        "min": 5.99,
        "max": 5.99,
        "sum": 5.99
      },
      "4": {
        "min": 15,
        "max": 15,
        "sum": 15
      }
    }
  }
]




analyticInfo Id .



GET IP:8081/analytic/{userId}



— 200

— 404 + {«status»:”user not found"} ( )







:

GET http://IP:8081/analytic/User_1




:



{
  "userId": "User_1",
  "totalSum": 2891.55,
  "analyticInfo": {
    "1": {
      "min": 10,
      "max": 890,
      "sum": 2520
    },
    "2": {
      "min": 350.56,
      "max": 350.56,
      "sum": 350.56
    },
    "3": {
      "min": 5.99,
      "max": 5.99,
      "sum": 5.99
    },
    "4": {
      "min": 15,
      "max": 15,
      "sum": 15
    }
  }
}




40 .



2.



. :





GET IP:8081/analytic/{userId}/stats



— 200

— 404 + {«status»:”user not found"} ( )

.



:

GET http://IP:8081/analytic/User_1/stats
 :
{
  "oftenCategoryId": 1,
  "rareCategoryId": 2,
  "maxAmountCategoryId": 1,
  "minAmountCategoryId": 3
}




60



3.



.



:

  • , , (recipientId userId )




, .



GET IP:8081/analytic/{userId}/templates



— 200

— 404 + {«status»:”user not found"} ( )

, .



:

GET http://IP:8081/analytic/User_1/templates
 :
[
  {
    "recipientId": "User_2",
    "categoryId": 1,
    "amount": 10
  }
]




# 3 Caixa grátis



Detalhes da tarefa



- .

REST API IP:8082.

API – api.json.

, , , , .



PostgreSQL.

PostgreSQL:



mkdir task3 ; cd task3

wget https://raw.githubusercontent.com/evgenyshiryaev/alfa-battle-resources/master/task3/docker-compose.yml

wget https://raw.githubusercontent.com/evgenyshiryaev/alfa-battle-resources/master/task3/Dockerfile

wget https://raw.githubusercontent.com/evgenyshiryaev/alfa-battle-resources/master/task3/init_db.sql

docker-compose up -d


( task3):

docker-compose down

: IP:5432

DB: alfa_battle

Auth: alfa_battle / qwe123



* IP — IP .

* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task3





1. id



: GET IP:8082/branches/{id}

:

— 200 Branches

— 404 ErrorResponse ( )



:
GET http://IP:8082/branches/612
200
{
  "id": 612,
  "title": "",
  "lon": 37.6329,
  "lat": 55.7621,
  "address": " ., 13, . 1"
}




:
 GET http://IP:8082/branches/1
404
{
  “status”: “branch not found”
}




8 .



2. (-)



-, , 1.



.



, Latitude Longitude.



: GET IP:8082/branches/lat=string&lon=string

: 200 Branches



:
GET http://IP:8082/branches/lat=55.773284&lon=37.624125
200
{
  "id": 631,
  "title": " ",
  "lon": 37.6227,
  "lat": 55.7695,
  "address": " ., 16/1",
  "distance": 430
}




Distance — , , .



28 .



3.



, — , , , , .



.



: GET IP:8082/branches/{id}/predict?dayOfWeek=int&hourOfDay=int

:

— 200 BranchesWithPredicting

— 404 ErrorResponse ( )



:
GET http://IP:8082/branches/612/predict?dayOfWeek=1&hourOfDay=14
200
{
  "id": 612,
  "title": "",
  "lon": 37.6329,
  "lat": 55.7621,
  "address": " ., 13, . 1",
  "dayOfWeek": 1,
  "hourOfDay": 14,
  "predicting": 117
}




dayOfWeek — , 1, 7

hourOfDay — 0 23

Predicting — , , .



:
GET http://IP:8082/branches/1/predict?dayOfWeek=1&hourOfDay=14
404
{
  “status”: “branch not found”
}


.

, , apache-commons-math3



# 4 Empréstimos elásticos



Detalhes da tarefa



1 2 JSON:



person.json — , :

{
     "ID":"29",
     "DocId":"702821510",
     "FIO":"Phoebe Whitehouse",
     "Birthday":"7/12/1971",
     "Salary":"201.02",
     "Gender":"F"
}


, :

ID — ,

DocId — ( 9 )

FIO —

Birthday — MM/dd/yyyy

Salary — , , .. 201.02 20102 .

Gender —



loans.json — , :

{
     "Loan":"631553",
     "PersonId":"68",
     "Amount":"201.02",
     "StartDate":"6/1/2019",
     "Period":"1"
}


, :

Loan — ,

PersonId —

Amount — , , .. 201.02 20 102

StartDate — MM/dd/yyyy

Period —





, ElasticSearch .

REST- ElasticSearch, . IP:8083



ElasticSearch:

mkdir task4 ; cd task4

wget https://raw.githubusercontent.com/evgenyshiryaev/alfa-battle-resources/master/task4/docker-compose.yml

docker-compose up -d


ElasticSearch IP:9200



( task4):

docker-compose down



* IP — IP .

* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task4





ElasticSearch :



persons

  • Birthday — 1945-05-03
  • Salary — ,




loans

  • PersonId — , Document, DocId Persons.
  • Amount — , .
  • StartDate — , 1945-05-03
  • Period — ,








GET IP:8083/admin/health

200

{«status»:«UP»}





ElasicSearch.



POST IP:8083/loans/loadPersons

200

{«status»:«OK»}



ElasicSearch.

, Document, ElasticSearch .



POST IP:8083/loans/loadLoans

200

{«status»:«OK»}





GET http://IP:8083/loans/getPerson/855406656/
200
{
   "docid": "855406656",
   "fio": "Celina Jackson",
   "birthday": "1961-05-22",
   "salary": 69106.0,
   "gender": "F"
}




400 ( )

{

«status»: «person not found»

}





GET http://IP:8083/loans/getLoan/692826/
200
{
   "loan": "692826",
   "amount": 448900,
   "document": "027665876",
   "startdate": "2017-01-16",
   "period": 48
}


400 ( )

{
   "status": "loan not found"
}






, — Document.



GET http://IP:8083/loans/creditHistory/737767072/
200
{
   "countLoan": 4,
   "sumAmountLoans": 1058400.0,
   "loans": [
       {
           "loan": "434224",
           "amount": 7100,
           "document": "737767072",
           "startdate": "2019-09-18",
           "period": 12
       },
       {
           "loan": "917105",
           "amount": 283600,
           "document": "737767072",
           "startdate": "2019-12-22",
           "period": 12
       },
       {
           "loan": "692147",
           "amount": 300800,
           "document": "737767072",
           "startdate": "2016-08-01",
           "period": 24
       },
       {
           "loan": "145020",
           "amount": 466900,
           "document": "737767072",
           "startdate": "2017-01-16",
           "period": 36
       }
   ]
}




, :

countLoan —

sumAmountLoans —

loans —



,



GET http://IP:8083/loans/creditClosed
200
[
   {
       "loan": "222398",
       "amount": 265400,
       "document": "074658188",
       "startdate": "2017-09-22",
       "period": 12
   },
  
       "loan": "826942",
       "amount": 329400,
       "document": "788117788",
       "startdate": "2016-01-29",
       "period": 48
   },
...
]




, ( ElasticSearch).



GET http://IP:8083/loans/loansSortByPersonBirthday
200
[
   {
       "id": null,
       "docid": "840704451",
       "fio": "John Isaac",
       "birthday": "19.08.1989",
       "salary": 58295.0,
       "gender": "M",
       "loans": [
           {
               "loan": "771916",
               "amount": 337600,
               "document": "840704451",
               "startdate": "2019-11-09",
               "period": 48
           },
           {
               "loan": "504544",
               "amount": 358900,
               "document": "840704451",
               "startdate": "2018-06-10",
               "period": 36
           },
           {
               "loan": "699247",
               "amount": 464400,
               "document": "840704451",
               "startdate": "2018-10-30",
               "period": 36
           },
           {
               "loan": "783101",
               "amount": 139300,
               "document": "840704451",
               "startdate": "2017-02-19",
               "period": 36
           }
       ]
   },
   {
       "id": null,
       "docid": "023665566",
       "fio": "Denny Tanner",
       "birthday": "25.03.1989",
       "salary": 80713.0,
       "gender": "M",
       "loans": [
           {
               "loan": "631553",
               "amount": 403000,
               "document": "023665566",
               "startdate": "2019-06-01",
               "period": 12
           },
           {
               "loan": "598452",
               "amount": 198500,
               "document": "023665566",
               "startdate": "2015-09-28",
               "period": 36
           },
           {
               "loan": "151915",
               "amount": 13600,
               "document": "023665566",
               "startdate": "2019-06-15",
               "period": 12
           },
           {
               "loan": "368342",
               "amount": 350500,
               "document": "023665566",
               "startdate": "2017-02-06",
               "period": 48
           },
           {
               "loan": "633056",
               "amount": 482900,
               "document": "023665566",
               "startdate": "2016-07-01",
               "period": 12
           }
       ]
   },
...
]




# 5 Na agulha da promoção



Detalhes da tarefa



.

- .

.



REST API IP:8084 :



  • /promo – POST - ( , ). .
  • /receipt – , POST id , (, ), , , .




: /promo, /receipt.



* IP — IP .

* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task5





  1. CSV :
  2. API – api.yml






- , -, .

-, - .

- , -, .



2 RoundingMode.HALF_EVEN.



!!! , code review !!!





1. -



:

: POST IP:8084/promo

{}

: 200

: POST IP:8084/receipt

{

«shopId»: 1,

«loyaltyCard»: false,

«positions»:

[

{

«itemId»: «3432166»,

«quantity»: 1

}

]

}

: 200

{

«total»: 141.99,

«discount»: 0.00,

«positions»:

[

{

«id»: «3432166»,

«name»: «...G11 Green .1»,

«price»: 141.99,

«regularPrice»: 141.99

}

]

}



8 .



2. -



/promo - “ ” (LoyaltyCardRule). , .



- , /receipt loyaltyCard=true - , id .



:

: POST IP:8084/promo

{
  "loyaltyCardRules": 
  [
    {
      "shopId": -1,
      "discount": 0.03
    },
    {
      "shopId": 2,
      "discount": 0.05
    }
  ]
}


: 200



: POST IP:8084/receipt

{
  "shopId": 1,
  "loyaltyCard": false,
  "positions":
  [
    {
      "itemId": "3432166",
      "quantity": 1
    }
  ]
}
: 200
{
  "total": 137.73,
  "discount": 4.26,
  "positions":
  [
    {
      "id": "3432166",
      "name": "...G11 Green .1",
      "price": 137.73,
      "regularPrice": 141.99
    }
  ]
}


16 .



3. - N+k



/promo - LoyaltyCardRule ItemCountRule. , .

N+k , N ID k . N=3, k=2:



Gravações de vídeo de relatórios







Todos os 16 relatĂłrios de nossos caras e parceiros da Beeline e X5 Retail Group vocĂŞ pode ver no site do evento .



E quanto à contratação?



Damir Battulin, nosso diretor do departamento de desenvolvimento de canais online, falou sobre as contratações, sobre as iniciativas estratégicas do banco, os princípios do trabalho em equipe nos projetos e os critérios de escolha de novos especialistas para o desenvolvimento da digitalização.



: , - . , , , , . . , .



. , . , , . , . .




Você pode ver todas as nossas vagas atuais (TI, marketing, RH, etc.) nesta página.



Para os amantes dos detalhes - a entrevista completa
- 100 . . , , . , - -, , .



— -, 2021 . . , , — . 7 12 . , , .



, - , . , , , , . , , ( , ): — , , -. , .



— ?



— , -.



— , , .



— . , . , , , .



, , — smart branch. – 400 . , , .



? , . , . , . , . , , .



, . , , , .



, , -. . , , , . , , , .



— ?



— : , - . , , , , . . , .



. , . , , . , . .



— ?



— – time to market. . , . . , , .



, , . smart branch , .



— , ?



— -. , . , . .

. , . — , . , . - , . . , : iOS- Lead product manager iOS, Chief product owner .



. 56, . 60%, 100%.



— ?



— , . , .

, chief product owner. , . – , , . , . , - , , , .



— , . ?



— , , , . , , , . .

. , , .



— ?



— – . . . , , , .



– . , -, . , , . , .



, , , , , . — , , , . .




All Articles