“Não faz sentido usar Retrofit”: sobre o desenvolvimento do Android no Sberbank Online



Quantos aplicativos russos no Google Play dizem "mais de 50.000.000 de instalações"? Obviamente, cada um desses casos é uma história única, com suas próprias especificidades; portanto, seria interessante conversar com os desenvolvedores. E quando esse aplicativo também tem uma classificação de 4,6, isso fortalece o interesse.

Vladimir Tebloev é uma das pessoas que trabalha no aplicativo Android Sberbank Online . Na primavera, quando Sberbank Technologies participou de nossa conferência Mobius , ele fez um relatório lá e agora decidimos perguntar a Vladimir sobre as características de seu trabalho.


- Primeiro, diga-nos o que exatamente você está fazendo?

- No aplicativo Sberbank Online, estou envolvido no serviço Dialogs, que permite aos usuários transferir dinheiro com um clique e ver todo o histórico de transferências em exibição completa. O serviço está disponível para todos os usuários do aplicativo - agora são 37 milhões de pessoas.

Trabalho na SberTech desde o verão de 2016 - então, como parte do aplicativo, ainda não havia divisão em equipes separadas. E mais tarde, quando, como parte da transição para o ágil, eles começaram a designar equipes diferentes para separar os módulos de aplicativos, uma das primeiras foi a equipe de Diálogos, e desde então eu participei.

- Todo mundo tem as palavras "Sberbank" e "desenvolvimento móvel" associadas ao Sberbank Online. Mas em uma empresa tão grande, provavelmente há também desenvolvimento móvel interno? É diferente do lado de fora?

- Sim, também existem aplicativos para uso interno. Não tenho nada a ver com eles, mas sei que o React Native é usado ativamente lá. O desenvolvimento interno tem seus próprios requisitos: não há uma revisão estrita do projeto e animação sofisticada; o desenvolvimento é mais rápido usando uma solução de plataforma cruzada.

Quando a experiência aumentar, será possível aplicá-la em um aplicativo de "combate". Embora o Sberbank Online consiga usar ativamente o desenvolvimento de plataforma cruzada, duvido. Existem muitas dificuldades e, quando você tem dezenas de milhões de usuários, até um problema raro pode prejudicar muitas pessoas.

- E como esse “até um problema raro machuca muitos” afeta o trabalho? Você precisa lidar com alguns problemas exóticos que aplicativos menores podem passar sob o radar?

- Às vezes, existem problemas em alguns dispositivos "especiais". Em um firmware personalizado, mas generalizado, ele disparou bastante, e tivemos que descobrir por um longo tempo. Aconteceu que o problema estava no driver da placa-mãe do próprio dispositivo - ele tentou emular bibliotecas no ARMv5, embora o projeto fosse apenas para o ARMv7.

Quando há muitos usuários e o preço do erro é alto, isso leva ao fato de que tudo precisa ser implementado "um pouco", seguindo cuidadosamente os relatórios. Se algo acontecer, paramos imediatamente de rolar e fazemos um hotfix. Além de rolar “por uma determinada porcentagem de usuários”, também distribuímos geograficamente tudo em partes: o Sberbank tem o conceito de “banco territorial” e os recursos podem ser gradualmente distribuídos por região.



- Enquanto uma startup moderna pode colocar uma MinSdkVersion alta e dizer "todo mundo não é nosso público", você tem uma situação diferente, não pode acenar para as pessoas. Qual é o seu valor MinSdkVersion atual?

- Agora são 16, e nós a elevamos literalmente no ano passado, a partir de 14. Analisamos o número de clientes com um SDK específico e podemos aumentar a versão se ela for menor que 5%. Até agora, temos muitos usuários no Android 4.4 KitKat, cerca de 16% - precisamos apoiá-los.

- Existe alguma das novas versões que você está vendo agora e pensando: "Assim que aumentamos o MinSdkVersion, usamos imediatamente?"

- Claro, eu gostaria de aumentar nossa API mínima para o Android 5.0, a fim de fazer pleno uso de inovações como, por exemplo, animação de transição, que funcionará adequadamente e em qualquer lugar. Mas, em princípio, isso não se aplica à funcionalidade de gravação, lógica de negócios, portanto, isso não é crítico. Em geral, as animações são elaboradas por nossos designers, ou seja, podem ser implementadas manualmente. Portanto, esse problema não é crítico, ele se relaciona ao conforto, "tranquilidade" do desenvolvedor.

Há alguns casos em que verificamos a versão, por exemplo, fixação SSL. Como funciona de maneira diferente em diferentes versões do Android, implementamos duas versões do código, para dispositivos Android "até 4.4" e "de 4.4".

Claro, eu gostaria de “apenas desenvolver para o Android P e não pensar em nada” - mas esse é sempre o caso, não há como chegar a lugar nenhum.

- Para a fixação SSL mencionada. Obviamente, questões de segurança são muito importantes para o banco. E como isso afeta você, como o seu trabalho é diferente de trabalhar em um aplicativo não bancário?

- Apresenta uma abordagem muito rigorosa aos dados pessoais do usuário. Qualquer vazamento é um risco enorme. Temos um departamento de segurança que testa nosso aplicativo antes de cada lançamento. Se houver comentários, o trabalho neles será transmitido à equipe responsável pela funcionalidade com a vulnerabilidade descoberta.

Penso que nas pequenas empresas, muitas vezes, não existe um departamento de segurança que represte o aplicativo. Se algum cardume for encontrado, eles podem aparecer no w3bsit3-dns.com ou em um recurso semelhante.

Também relacionado à segurança é que nosso aplicativo usa um antivírus. Alguns usuários estão descontentes com sua presença, mas a introdução do antivírus nos deu uma redução muito perceptível na fraude. Por exemplo, em nosso banco de SMS, onde você pode escrever "quantia de transferência para o cartão X" do SMS com antivírus, o nível de fraude nessa direção foi reduzido ao mínimo.

- Por motivos de segurança, os bancos limitam sua funcionalidade no caso de smartphones com root. O que é proibido para o Sberbank Online para dispositivos com raiz?

- Em junho, abandonamos a funcionalidade limitada para proprietários de dispositivos com direitos de root. Agora todos os usuários do Sberbank Online no Android têm funcionalidade completa. Ao mesmo tempo, a proteção permanece no mesmo nível, graças ao sistema de monitoramento de fraudes.

- E em nome da segurança, era necessário restringir algo que não os usuários, mas a si mesmos como desenvolvedores, recusando-se a utilizá-lo?

- Quando, em 2015, queríamos apresentar o Retrofit, ele tinha problemas com a ofuscação, ele trabalhava torto com um ofuscador padrão. Nosso departamento de segurança apontou essa vulnerabilidade, repleta de ataques cibernéticos ao banco e os riscos de quebrar o código, conforme a API se destaca. Em seguida, abandonamos o Retrofit e ainda não o usamos. Até onde eu sei, agora os problemas com o ofuscador padrão já estão resolvidos lá. Mas desde que escrevemos nosso próprio cliente HTTP, ele funciona e satisfaz a todos, muitos wrappers já foram criados para diferentes equipes que trabalham com servidores diferentes. Não faz sentido alterá-lo para Retrofit.



- A pergunta inevitável: o que você tem com Kotlin?

- Estamos indo na direção dele, mas sem pressa. A dificuldade é que muitos desenvolvedores de Android de diferentes níveis estão trabalhando no aplicativo imediatamente, alguém conhece Kotlin perfeitamente, alguém não. Em geral, não há obstáculos intransponíveis para a implementação, mas agora temos uma escassez de revisores para observar o código Kotlin. Se todos começarmos a escrever abruptamente amanhã em Kotlin, as pessoas irão "rasgar" os pedidos. Além disso, no caso do Kotlin, há problemas com o analisador de código estático, usado em nosso pipeline.

Portanto, o Kotlin é implementado em pequenas etapas: por exemplo, escrevemos testes no Kotlin e usamos classes de dados (economizamos tempo para não escrever testes para getters, setters, equals (), hashCode () e assim por diante).

Agora ele está rodando lentamente e, na próxima etapa, queremos escrever nossa DSL para testes no Kotlin. E, paralelamente, queremos aumentar o nível de conhecimento da Kotlin na empresa: por exemplo, com a ajuda de mitaps.

- No caso de "Diálogos", você está envolvido em mensagens, mas não é um análogo direto do WhatsApp. E, portanto, é interessante: qual a utilidade das soluções de outras pessoas para você? Você usa mensageiros de código aberto no código?

- Foi útil quando queríamos adicionar emoticons. Tivemos uma pergunta sobre como fazer um painel com eles, e no código aberto vimos uma opção em que tudo é facilmente resolvido por pop-up acima do teclado. Então, tudo converge em altura e resulta perfeitamente para o usuário.

Mas, em geral, observar as decisões de outras pessoas nem sempre é bom, é mais eficiente formar a sua, levando em consideração a experiência de outras pessoas. Por exemplo, é melhor não olhar para o Telegram, porque, devido ao grande tamanho das classes no código fonte do aplicativo para Android, não é fácil descobrir. Estamos tentando seguir nosso próprio caminho, principalmente porque a interação com o servidor pode ser diferente: no mesmo telegrama é o MTProto, temos os WebSockets habituais.

- Como sou um entrevistador preguiçoso, decidi apenas fazer uma lista das coisas com as quais você está conectado no trabalho e perguntar sobre cada item "diga-nos exatamente como as coisas estão indo com isso".

O primeiro ponto: você está na "arquitetura do módulo de aplicativo". Já dissemos sobre o fato de o aplicativo ser dividido em módulos - o que mais você pode dizer sobre arquitetura?

- Ele está desenvolvendo iterativamente conosco, o versionamento está em andamento, agora chegamos à 17ª versão.

No dia 16, a Arquitetura Limpa foi introduzida. Concordamos em quem é responsável por quê (apresentação, domínio, camada de dados), quais entidades e onde devem ser usados, onde devem estar os conversores - em geral, eles pintaram todos os problemas de arquitetura e os implementaram.

Implementado da seguinte maneira: todos os novos recursos precisavam ser escritos em nossa nova arquitetura. Se na solicitação pull algo se desvia da norma definida, essa solicitação pull é revisada. Mas, ao mesmo tempo, eles não se apressaram em enxergar todas as funcionalidades antigas, pois isso pode causar muitos problemas.

Para a camada de apresentação, escolhemos o padrão MVP, mas algumas de nossas equipes usam o MVVM. Na camada de apresentação, não estamos limitados por nada. Por exemplo, vimos nosso bate-papo sobre MVI - mais precisamente, sobre nossa interessante implementação do MVI, que é fundamentalmente diferente do que o desenvolvedor Mosby escreveu.

Em seguida, mudamos para a versão 17 da arquitetura e implementamos o RxJava, que implicava mudanças na arquitetura. Se usarmos definições rígidas, agora nossa arquitetura acabou sendo hexagonal; do Clean, nós "bifurcamos". Mas eles são semelhantes, pois ambos funcionam de acordo com os princípios do SOLID, de modo que um flui para o outro sem problemas. Agora estamos trabalhando nisso.

Nas versões futuras da arquitetura, queremos abandonar a estrutura Moxy usada para implementar o MVP, porque isso causa algumas dificuldades. O projeto é grande, usa processamento de anotação e, ao fazer alterações nos módulos do "nível inferior", o tempo de construção é grande. E nos esforçamos para facilitar a vida de nossos desenvolvedores.

- O segundo ponto é "otimização do trabalho e consumo de memória". Quão aguda é essa pergunta, tenho que pensar constantemente para usuários com dispositivos mais antigos?

- Esse problema está no foco das equipes de plataforma, elas estão desenvolvendo ferramentas que caracterizam o uso das equipes. A necessidade de fazer isso surge como a necessidade de uma das equipes. Por exemplo, na equipe de Diálogos, nos estágios iniciais de desenvolvimento, o bate-papo era muito lento. Depois tive que arregaçar as mangas, começar com o criador de perfil, ver onde estavam os gargalos no aplicativo e descobrir os motivos de sua ocorrência.

Em termos de otimização, por exemplo, abandonamos o PNG e os limpamos gradualmente do projeto para usar apenas o vetor. A otimização do gráfico de dependência no Dagger está planejada para este ano para acelerar o início a frio do aplicativo.

- Passemos às perguntas do teste: como está acontecendo com você?

- Só posso falar sobre nossa equipe, em outros esse processo pode ser construído de maneira diferente.

Nossa equipe teve inicialmente um testador. Posteriormente, ele ficou entediado com apenas testes. E ele começou a nos pedir para ajudar a lidar com a escrita de testes de unidade. Mostramos a ele como escrever testes para o banco de dados, em essência, para análise - e dessa maneira ele nos descarregou, removeu parte do trabalho de nós. Isso é bom: ele está interessado, e nós.

Com o tempo, chegamos à conclusão de que precisamos automatizar a regressão, precisamos escrever testes de interface do usuário. Inicialmente, meu parceiro e eu trabalhamos nos testes de interface do usuário e, posteriormente, o departamento de qualidade se juntou a nós - nossos testadores que testaram o back-end no passado. Eles conhecem Java e agora estão conectados ao nosso projeto para automatizar toda a regressão. Sentamos e consideramos as soluções que são: Appium, Espresso, Selenium.

Paramos no Espresso e começamos a desenvolver abordagens juntos. Para facilitar os testes, desenvolvemos nossa própria estrutura, algo como Kakao. Iniciamos esse trabalho no início de 2017 e agora temos uma grande estrutura, e a maioria dos testes é montada como construtora, porque muitos match-ups e jogos de ação foram escritos para várias situações.

Agora, nossos testadores estão nos pedindo ativamente para ensiná-los a escrever testes de interface do usuário, porque é mais fácil escrever um teste uma vez do que "perfurar" as mesmas ações em cinco dispositivos. Mas, é claro, você não automatiza tudo, e alguns casos ainda precisam ser verificados manualmente.

Quanto aos desenvolvedores, uma retrospectiva é realizada em nossa equipe a cada duas semanas. Em um deles, chegamos à conclusão de que os desenvolvedores devem realizar pelo menos testes alfa depois de escreverem um recurso. Para não obter nenhum bug completamente básico do formulário "o aplicativo trava na inicialização". Assim, os desenvolvedores também se conectaram ao teste. Quando estamos preparando uma versão principal e precisamos testar rapidamente o recurso, todos se sentam para regressão e juntos passam nos testes de regressão. Quando um bug é detectado, os desenvolvedores se desconectam da regressão, corrigem rapidamente e novamente.



- Próximo item: revisão de código. Você tem algum detalhe, ou "como todo mundo"?

- Há uma especificidade causada pelo número de desenvolvedores. Quando há dez desenvolvedores de dispositivos móveis em uma empresa, duas ou três pessoas podem revisar tudo. E como revisar o código de centenas de pessoas? Desenvolvemos uma "matriz de revisão". 20 a 30 pessoas foram selecionadas, sobre as quais sabemos com certeza que podem divulgar, deixar comentários e resolver pontos controversos nos comentários. Eles pegaram essas pessoas e dividiram todas as equipes entre elas.

Por que uma matriz? Isso é para garantir que todos os revisores tenham a mesma carga. Como está indo a revisão? Nossa equipe exige pelo menos três avaliações. O primeiro é de alguém da equipe. O segundo - de alguém de fora, de uma equipe que não lida com essa funcionalidade. E o terceiro appruv - de alguém de uma equipe adjacente. No nosso caso, existem vários comandos relacionados e todos eles olham para o nosso código. Bem, portanto, todas as compilações devem ser coletadas: testes de unidade e testes de interface do usuário devem passar sem problemas. Assim, temos uma revisão de código.

- O próximo ponto é a refatoração do código legado. Como isso acontece sistematicamente: precisamente com as tarefas planejadas, ou "você precisava fazer alterações no código antigo - ao mesmo tempo, refatorá-lo"?

- Em geral, temos um “princípio olheiro” peculiar: se você tocou em algo antigo - tenha a gentileza de fazer o que é certo, agora é co-autor. Mas há uma refatoração planejada também. Por exemplo, para Diálogos, era necessária uma refatoração de duas direções: o catálogo de contatos que usamos e as traduções. O livro de contatos foi retirado, limpo e reescrito em todo o banco de dados no Room, realizado em um módulo separado. E nossos pagamentos foram escritos há muito tempo usando o RoboSpice, se você ainda se lembra disso, e isso nos machucou. Devo dizer que cortar isso foi uma tarefa desagradável, porque havia muitos laços. E você tinha que limpá-lo sutilmente, para não quebrar o restante da funcionalidade.

- Mesmo em Sbertekh, você está envolvido em treinar programadores. Como é o treinamento dentro da empresa?

- Desde setembro, está planejado realizar um programa como reciclagem de funcionários internos. Agora já definimos uma variedade de tópicos sobre Java e Android. Por exemplo, temos javascriptors, javists e analistas que desejam treinar novamente no Android. Essa escola será organizada para eles, onde haverá um estudo focado, de acordo com o cronograma e com palestras.

E agora mantemos mitaps regularmente. A escolha dos tópicos para eles não é a mesma das conferências, onde é necessário algo novo e exagero. Por exemplo, se sabemos que os desenvolvedores têm problemas com alguma coisa, é importante falar sobre isso. Recentemente - um de nossos desenvolvedores falou sobre gráficos vetoriais. Não apenas sobre uma biblioteca específica que desenha vetores lindamente no Android, mas começou com o modo como os gráficos vetoriais funcionam em geral e depois passou para o privado. Eles falaram sobre o Room e sobre a simultaneidade Java, com a qual muitos desenvolvedores têm problemas, e sobre o Dagger 2.

No ano passado, tínhamos uma escola de desenvolvimento para Android e contratamos aqueles que a concluíram com sucesso. Essas pessoas não devem ser imediatamente conectadas a alguns projetos e deixadas para cozinhar por conta própria. Portanto, um mentor é designado para cada funcionário recém-chegado e também para o júnior, que o guiará, desenvolverá e ajudará. Este é um aprendizado interno.

- Entrevistas: você as possui “como todo mundo”, ou há alguma especificidade?

- Eu costumava pensar que "como todo mundo", mas no fim das contas, eles ainda são um pouco especiais. Na minha experiência, existem três abordagens comuns no mercado. O primeiro é perguntado sobre três ou quatro tópicos e avaliado unicamente sobre eles. Por exemplo, vim para a empresa como desenvolvedor do Android e sou considerado uma pessoa que deve ter um excelente conhecimento de algoritmos e sincronização em Java e, ao mesmo tempo, não aprecia o que faço nas super bibliotecas. , , - . — , 30-40 . , , . — - . , , . , .

, : , OOD (Object Oriented Design, ), Java Core Android SDK. . , , . : , , - . . , , , Dagger 2, RxJava. , Kotlin. , . - , , , . , .

— « ». - , .

— — RxJava, , . , , . .

Retrofit, : , , . , — .

TinyMachine - — , , , . , «» , , . -, , - rocket science, .

— : . , , ?

Sim. — Java-. « »: Java- — - («» — Android-: , , , ). , , , — Java-. , . , , , , « payment? payment payment ? paymentTest?».

, Confluence. , material design , - , . , , Confluence. , , , , , , . : RxJava Confluence best practices — , , . : , .

, . Confluence 200 . . Confluence, , , .

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


All Articles