... Di akhir posting - tentang strategi baru untuk mempekerjakan spesialis. Ada suatu masa ketika TI Alfa-Bank sebagian besar terkonsentrasi di tiga kota - Moskow, St. Petersburg, Yekaterinburg. Sekarang kita bisa melihat orang-orang dari seluruh negeri. Dan tidak hanya.
Terima kasih kepada semua orang yang menanggapi - ada lebih dari 1.500 orang seperti itu, 198 orang di antaranya mencapai final yang menunjukkan hasil terbaik. Ya, memang tidak mudah: tugas ternyata lebih sulit dari yang diharapkan banyak peserta, dan format kejuaraan online dengan aliran konferensi, sejujurnya, tegang. Tetap saja, 5 jam pemrograman online bukanlah pengalaman retro dalam sebuah tim.
Secara total - tiga pemenang yang menerima hadiah uang tunai, serta undangan untuk bekerja bersama kami dan mitra kejuaraan. Ini dia:
Juara 1: Mikhail Burshtein, Moskow (250.000 rubel)
Juara 2: Alexander Ilyushechkin, Moskow (150.000 rubel)
Juara 3: Pavel Lyubinsky, St. Petersburg (100.000 rubel)
Tugas
# 1 Dimana ATMnya
Detail tugas
-.
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
: GET IP:8080/atms/{deviceId}
:
— 200 AtmResponse
— 404 ErrorResponse ( )
:
:
18 .
- — .
3 ! -.
payments=true, (. - API ATMServices).
: GET IP:8080/atms/nearest?latitude=string&longitude=string&payments=boolean
: 200 AtmResponse
:
:
36 .
- .
, .
: GET IP:8080/atms/nearest-with-alfik?latitude=string&longitude=string&alfik=int
: 200 [AtmResponse]
, WebSocket STOMP .
:
( task1):
: ws://IP:8100
: { “deviceId”: 0 }
/topic/alfik: { “deviceId”: 0, “alfik”: 0 }
:
(.. 153463 — 383026 )
:
( , )
Kondisi
-.
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 Analisis itu
Detail tugas
Kafka RAW_PAYMENTS .
docker IP:29092 .
Kafka.
:
.
( task2):
* IP — IP .
* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task2
:
, key1 — .
.
:
RAW_PAYMENTS. .
, .
, Kafka .
.
, , . , ( , - ).
:
start.sh, . ,
Swagger- api-swagger.json .
:
( categoryId).
, .
.
200
:
:
analyticInfo Id .
— 200
— 404 + {«status»:”user not found"} ( )
:
:
40 .
. :
— 200
— 404 + {«status»:”user not found"} ( )
.
:
60
.
:
, .
— 200
— 404 + {«status»:”user not found"} ( )
, .
:
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 .
.
, , . , ( , - ).
:
- consumer-group-id. .
- 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 Meja kas gratis
Detail tugas
- .
REST API IP:8082.
API – api.json.
, , , , .
PostgreSQL.
PostgreSQL:
( task3):
: IP:5432
DB: alfa_battle
Auth: alfa_battle / qwe123
* IP — IP .
* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task3
: GET IP:8082/branches/{id}
:
— 200 Branches
— 404 ErrorResponse ( )
:
:
8 .
-, , 1.
.
, Latitude Longitude.
: GET IP:8082/branches/lat=string&lon=string
: 200 Branches
:
Distance — , , .
28 .
, — , , , , .
.
: GET IP:8082/branches/{id}/predict?dayOfWeek=int&hourOfDay=int
:
— 200 BranchesWithPredicting
— 404 ErrorResponse ( )
:
dayOfWeek — , 1, 7
hourOfDay — 0 23
Predicting — , , .
:
.
, , apache-commons-math3
- .
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 Pinjaman elastis
Detail tugas
1 2 JSON:
person.json — , :
, :
ID — ,
DocId — ( 9 )
FIO —
Birthday — MM/dd/yyyy
Salary — , , .. 201.02 20102 .
Gender —
loans.json — , :
, :
Loan — ,
PersonId —
Amount — , , .. 201.02 20 102
StartDate — MM/dd/yyyy
Period —
, ElasticSearch .
REST- ElasticSearch, . IP:8083
ElasticSearch:
ElasticSearch IP:9200
( task4):
* IP — IP .
* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task4
ElasticSearch :
persons
loans
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»}
400 ( )
{
«status»: «person not found»
}
400 ( )
, — Document.
, :
countLoan —
sumAmountLoans —
loans —
, ( ElasticSearch).
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 Di jarum promo
Detail tugas
.
- .
.
REST API IP:8084 :
: /promo, /receipt.
* IP — IP .
* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task5
- , -, .
-, - .
- , -, .
2 RoundingMode.HALF_EVEN.
!!! , code review !!!
:
: 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 .
/promo - “ ” (LoyaltyCardRule). , .
- , /receipt loyaltyCard=true - , id .
:
: POST IP:8084/promo
: 200
: POST IP:8084/receipt
16 .
/promo - LoyaltyCardRule ItemCountRule. , .
N+k , N ID k . N=3, k=2:
.
- .
.
REST API IP:8084 :
- /promo – POST - ( , ). .
- /receipt – , POST id , (, ), , , .
: /promo, /receipt.
* IP — IP .
* : github.com/evgenyshiryaev/alfa-battle-resources/tree/master/task5
- CSV :
- 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:
Rekaman video laporan
Semua 16 laporan dari orang-orang dan mitra kami dari Beeline dan X5 Retail Group dapat Anda lihat di situs web acara .
Jadi bagaimana dengan perekrutan?
Damir Battulin, direktur departemen kami untuk pengembangan saluran online, berbicara tentang perekrutan, tentang inisiatif strategis bank, prinsip kerja tim dalam proyek, dan kriteria untuk memilih spesialis baru untuk pengembangan digitalisasi.
: , - . , , , , . . , .
. , . , , . , . .
Anda dapat melihat semua lowongan kami saat ini (TI, pemasaran, SDM, dll.) Di halaman ini.
Untuk pecinta detail - seluruh wawancara
- 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. , . – , , . , . , - , , , .
— , . ?
— , , , . , , , . .
. , , .
— ?
— – . . . , , , .
– . , -, . , , . , .
, , , , , . — , , , . .
— -, 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. , . – , , . , . , - , , , .
— , . ?
— , , , . , , , . .
. , , .
— ?
— – . . . , , , .
– . , -, . , , . , .
, , , , , . — , , , . .