
Entre os desenvolvedores do Android,
Artyom Zinnatullin é tão respeitado que você pode compor um análogo de "fatos sobre Chuck Norris" sobre ele - algo como isto:
- Artyom é tão severo que, quando o vê, o próprio github fica verde (quem de nós pode se orgulhar de tal cronograma de contribuições?)
- Artyom é tão duro que, para ele, o git é um mensageiro .
- Artyom é tão severo que, no contexto de suas aplicações, é um podcast .
Quando o entrevistamos em nossa conferência Mobius, ele foi destinado a uma transmissão on-line. Mas, vendo como eles se referem a ele no bate-papo do Android, decidimos que também poderia ser do interesse de muitos no Habré, e fizemos uma versão em texto para você (também anexamos a gravação de vídeo).
Como viver com um projeto em um milhão de linhas de código? Qual é a desvantagem do corotin Kotlin? O que há de errado com o Google? Como o desenvolvimento em São Francisco é diferente do russo? Sobre o que o Mobius falou? Sob o corte - sobre tudo isso.
Evgeny Trifonov : Nesse Mobius, eu perdi sua palestra “Android constrói na Lyft”, mas depois vi uma multidão de pessoas desejando fazer uma pergunta na área de discussão. E eu queria esclarecer: mas, afinal, a maioria dos espectadores não está trabalhando em um projeto gigante como o Lyft, essa experiência foi relevante para eles?
Artyom : Isso é uma coisa interessante. O esboço original do relatório em minha cabeça e como eu o implementei são muito diferentes, graças ao seu elegante comitê de programa.
Inicialmente, eu ia contar como tudo começou na Lyft, por que chegamos a certas soluções técnicas. Ele conversou com Sergey Boishtyan, do comitê do programa, por duas horas, ouviu e disse: "Legal, é claro, mas você fez a palestra". E, no final, percebi que esse relatório, é claro, é interessante de ouvir, mas na verdade não é relevante para ninguém.
E então refiz, mudando a ênfase para abordagens fundamentais de engenharia para a escolha de sistemas de montagem, outros sistemas. Eu não tinha um objetivo de dizer quais ferramentas usamos especificamente. Não quero que alguém pegue e comece a usá-los às cegas e depois me escreva cartas formidáveis de que nem tudo funciona como eu lhe disse. Eu queria transmitir exatamente as práticas de engenharia sobre como fazer uma escolha e o que é importante na minha opinião (naturalmente, subjetiva). Portanto, espero que, no final, a experiência seja relevante para mais pessoas, e não apenas "o cara da Lyft apareceu e disse alguma coisa".
Oleg olegchir Chirukhin : Existem escolhas incomuns da Lyft que são difíceis de serem feitas por outras pessoas?
Artyom : Sim, claro. Temos dois sistemas de construção no projeto ao mesmo tempo, não recomendo absolutamente ninguém
(risos) .
É muito doloroso de manter: você constantemente persegue dois coelhos com uma cajadada, em ambos, algo não funciona até o fim. Mas esse é o nosso estado atual, tão historicamente, porque um sistema de construção começou a calar parte de tarefas, tivemos que iniciar um segundo. Eu falei sobre como evitar isso e migrar corretamente para um deles.
Oleg : E que tipo de construção de sistemas?
Artyom : Usamos Gradle e Buck, e eu falei sobre como chegar ao Bazel pelo Google.
Oleg : Esse é algum tipo de movimento em direção ao mal: do bonito Gradle a Bazel, no qual não existem dependências normais.
Artyom : Agora há mais ou menos. Bem, sim, é claro, existem trocas e, é claro, a Gradle tem seus méritos. Tudo depende do tipo de projeto. Alguns Gradle serão mais adequados que Buck e Bazel, porque eles têm alguns pontos fundamentais que não serão coletados gradualmente dentro do mesmo módulo, mas Gradle será, e para muitos isso é muito importante. E é legal que Gradle possa fazer isso.
Outra coisa é que, quando você adiciona módulos - mais, mais módulos, oitocentos, mil -, o Gradle é tão reprojetado que desacelera linearmente a montagem em alguns lugares. Mas parece-me que Gradle pode consertar tudo isso se a comunidade exercer pressão sobre eles - o que talvez eu esteja fazendo. Vamos ver
(nota: alguns dias após esta entrevista, Artyom escreveu um longo post sobre os problemas de Gradle)Oleg: Ou seja, Bazel apenas porque eu quero suportar um grande número de módulos?
Artyom : Digamos que, no nosso caso, não o "queremos", mas dividir o projeto em módulos permite que nossos negócios se movam mais rapidamente. Basicamente, pelo que entendi, isso é isolamento para que não funcione espaguete, o que é difícil de manter. Os módulos dão mais controle sobre quais partes do código interagem com as quais. Temos quase um milhão de linhas de código. Se estivesse em um módulo, eu teria que fazer espaguete. Porque no topo da linguagem - Java, Kotlin - será necessário encerrar algo para proibir chamadas entre pacotes, entre os quais ninguém esperava. Além disso, surgirá a questão de que Gradle não utilizará tanto código em um módulo. Ele não será coletado em paralelo, montado de forma incremental dentro do módulo.
Cada solução tem vantagens e desvantagens. No nosso caso, parece-me que esta é a solução certa, mas há um problema - no momento, oferecemos suporte a dois sistemas de compilação.
Oleg : E o que é melhor para centenas de módulos: monorepo ou muitos repositórios?
Artyom : Este é um ponto muito dolorido. Provavelmente, um repositório é melhor do ponto de vista de que você não precisa pensar em versão e não existe essa dependência quando você clona uma dúzia de repositórios para fazer uma alteração e, em seguida, abre uma solicitação pull e uma dúzia depois dela. O "atrito" é removido do sistema e as pessoas não têm medo de alterar o código. Para eles, surge uma atomicidade de mudanças: tudo é agrupado em um projeto, e as mudanças de um módulo são automaticamente transferidas para outros sem seu consentimento explícito. Ao mesmo tempo, todas as verificações que você escreveu automaticamente no IC serão executadas e verificarão se o código está compilado, testado e tudo isso.
Oleg : E se você não perceber que, como em algum Chrome, os galhos mudarão por dois minutos enquanto você bebe chá?
Artyom : Sim, claro, há uma possibilidade. Mas aqui, provavelmente, a questão já está no tamanho do produto: o Chrome precisa conter tanto código? Talvez valha a pena destacar algumas partes em instrumentos separados, que elas serão periodicamente reforçadas quando ocorrerem grandes mudanças neles? Esta é provavelmente uma pergunta para a organização do projeto. Exemplo legal, a propósito. Eu tenho uma pergunta semelhante: correspondência com os caras do Yandex.Browser, onde eles também têm plugues grandes.
O Chrome pode ser dividido em vários componentes, e se você usar um V8 - eu não sou um grande especialista, mas, pelo que entendi, poderia ser um projeto separado em geral, certo? E por que, então, a GUI deve saber sobre o mecanismo, remontá-lo toda vez e pensar no código-fonte em algum lugar próximo? Bazel, a propósito, também apóia isso.
Em geral, agora todos os grandes sistemas de compilação - que Gradle, que Buck, que Bazel - suportam coisas como compósitos quando você se refere, por exemplo, a outro assembly Bazel. Essa é uma situação complicada, mas, no entanto, isso funciona, permite remover parte dos arquivos do repositório e reduzir o tamanho. O IDE, por exemplo, enlouquecerá ao indexar todos esses arquivos, por isso quero separá-los de alguma forma do componente geral do projeto.
Mas estamos longe disso. Parece-me que podemos calcular com calma outros cinco anos. É improvável que cheguemos a um checkout de dois minutos ainda. Nós não temos muitas pessoas.
Eugene : O Lyft ainda tem suas especificidades, além de dois sistemas de construção?
Artyom : Sim, existem algumas histórias atípicas lá. Aconteceu que as pessoas que vieram para a empresa (do Google, Facebook, em todos os lugares) odeiam mono-repositórios. Como resultado, nós da Lyft temos três repositórios mono: Android, iOS e L5 (esses são nossos
carros autônomos ).
E tudo o resto tem mais de 1.500 repositórios git: para todos os microsserviços, para todas as bibliotecas separadamente. Este é historicamente o caso. Isso tem um preço enorme que pagamos: empurrar as mudanças através delas é realmente difícil. Por outro lado, ao trabalhar com cada um deles, você tem clone instantâneo do git, impulso instantâneo do git, tudo é muito rápido, o IDE indexa por segundo. Eu posso dizer que esta é realmente uma parte interessante. Dos caras de San Francisco, eu esperaria um único repositório.
Oleg : E quando um desses repositórios separados é atualizado - a API muda, por exemplo - como essa alteração se aplica ao restante da empresa?
Artyom: Dói.
(risos) Bem, eu não sou desenvolvedor de back-end no sentido de não escrever back-end de recursos, escrevo back-end de infraestrutura - eles geralmente são bastante autônomos nesse sentido.
Como regra, isso é apenas um monte de comícios, interação cruzada e planejamento.
Oleg: Então os comícios fazem parte do sistema de montagem? (risos)
Artyom : Sim, primeiro precisamos montar um comício, depois montar um repositório. Além disso, infelizmente, historicamente, temos muitos desses microsserviços - este é o Python, que também tem suas próprias piadas.
Oleg : Alguma antipatia por Python escorregou.
Artyom : Não gosto de digitação dinâmica. Python, não Python - não faz diferença, mas a digitação dinâmica é uma coisa dolorida.
Eugene : E escorregou "para uma empresa de São Francisco", e é curioso perguntar isso: mas em termos de desenvolvimento, as empresas de São Francisco diferem das empresas da Rússia, há uma diferença notável?
Artyom : Uma diferença muito grande. Não sou muito fã de classificar dessa maneira, mas parece-me que aqui é uma escola de engenharia mais correta.
Oleg : Aqui - onde está?
Artyom : Na Rússia, nos países da antiga URSS. As pessoas prestam mais atenção aos aspectos técnicos de como os componentes do sistema funcionam. E nos Estados Unidos, muitas vezes acontece que algumas bibliotecas resolvem um problema, e as pessoas nem olham como ela é implementada. Como regra, eles absolutamente não se importam com a redução da velocidade ou com o uso incorreto.
Vou entrevistar muitas pessoas lá, porque isso faz parte do trabalho, e o nível geral de conhecimento, talvez, ainda seja menor. Há algo para mudar. Toda vez que uma pessoa vem do Leste Europeu, torna-se mais interessante durante as entrevistas, porque as pessoas não têm medo de resistir, de discutir em algum lugar. Embora os candidatos dos EUA muitas vezes possam não responder a perguntas ou responder "Não me lembro quando o usei pela última vez". Para perguntas como "Como funciona uma solicitação HTTP?" ou "Qual formato de dados você escolherá?" eles não podem dar respostas normais de engenharia, mas dizem: "Bem, eu usei isso nos últimos cinco anos". Legal, é claro, mas o senhor não puxa.
Por outro lado, existem projetos que levaram anos para serem comparados com o que estamos fazendo aqui. As pessoas produzem mais produtos de massa e simplesmente há mais escala. Por exemplo, Chrome ou Uber - eles já têm mais de mil módulos lá. Esta é apenas a escala dos problemas. Digamos no Uber com menos de trezentos desenvolvedores do Android. Surge a pergunta: por que?
(risos) Mas, no entanto, eles conseguiram fazer esse colosso funcionar, constantemente liberado. Eu diria que esses problemas são resolvidos com menos frequência aqui.
Aqui o Yandex é um bom exemplo. Eu tenho um amigo no Yandex.Maps: dez pessoas fazem um aplicativo Android. No Google, provavelmente cem estão sentados. E, ao mesmo tempo, o Yandex.Mart tem mais funcionalidade. Essa é a diferença, na minha opinião.
Eugene : Além disso, o Valley também está associado a start-ups, e elas têm uma abordagem de "mova-se rápido e quebre as coisas", e parece que isso também deve afetar o desenvolvimento: viva no limite, use o mais recente. Isso é verdade?
Artyom : Eu não trabalhei em startups, Lyft é difícil chamar assim: já existem três mil e três pessoas, em algum lugar mais de mil delas são engenheiros. Ou seja, é uma empresa já formada.
É uma tecnologia de ponta que raramente é usada. Se a tecnologia é sensacionalista, então sim. Se a tecnologia é um nicho, mas legal, muitas vezes não. Até que todas as conferências falem sobre isso, poucas pessoas o usarão.
Mas, ao mesmo tempo, o que eu realmente amo (em San Francisco e em parte no Valley) - muitos problemas são resolvidos devido ao fato de as empresas estarem fisicamente próximas. Muitas vezes, você escreve para alguém em uma sala de bate-papo: “Vamos almoçar juntos em nossa casa ou em seu escritório e decidimos, faremos algumas perguntas”; e então uma vez - um projeto de código aberto ou solicitação de recebimento aparece em outro projeto, algo fixo.
O que é interessante: as pessoas frequentemente discutem coisas que realmente não devem ser discutidas na NDA. Mas é assim que todo o Vale se move, no final, todo mundo entende para onde o resto está se movendo, e todo o setor caminha junto. Digamos, os mobilistas da Lyft e da Uber falam constantemente sobre coisas técnicas, porque usamos código aberto da Uber. E, é claro, existem especialistas diretamente hardcore em algumas tecnologias. Isso também é legal: você pode simplesmente cruzar com eles.
Eu amo isso, e isso não foi suficiente para mim em algumas cidades onde eu morava. Aqui em São Petersburgo, havia um grupo de usuários Java muito legal (eu ainda não sei como é agora): você vem depois do trabalho, e Shipilev tira seu cérebro, e algo está bom!
E aí aparece novamente: por exemplo, também possui seu próprio Java User Group, e muitas vezes surgem caras, digamos, da Oracle, que filmou um novo JDBC Reativo. E você senta, argumenta, porque algum líder do Projeto Reator ou líder Reativo na Primavera está sentado no mesmo lugar, uma discussão quente está acontecendo, e isso é legal.
Oleg : Vou perguntar sobre outra coisa: olhei para
o repositório Mainframer e Rust é usado lá. Por que tudo isso está escrito não no Javka abençoado, mas em algum tipo de Ferrugem?
Artyom : Recentemente, passei a considerar que o programa deveria ter uma quantidade mínima de recursos. Ou seja, quero estar muito perto de como o ferro digere bytes. E em Java, muitas coisas estão acontecendo por aí (nem estou falando sobre coleta de lixo), ou seja, JIT e tudo isso. Eu realmente gosto que o Java agora esteja se movendo para o fato de que também haverá compilação antecipada. Parece-me que será muito legal, por exemplo, iniciar o lançamento de um microsserviço baixando do cache sua compilação antecipada, o que originalmente aconteceu em outras máquinas, e iniciando-o muito rapidamente, sem aquecimento. Isso é legal, mas o Java tem um preço. Não posso simplesmente pedir às pessoas que estão construindo um projeto iOS que tenham Java em seus sistemas.
O mainframer foi originalmente escrito no dialeto Bash. Mas eu queria reescrevê-lo em uma linguagem de sistema para obter multithreading normal, a capacidade de escrever testes de unidade normais e não apenas testes de integração no topo do utilitário ...
Oleg : E pode-se usar, por exemplo, Python.
Artyom : Sim. Mas então surge a questão com o fato de que, em primeiro lugar, é uma digitação dinâmica e, em segundo lugar ...
Oleg : Também no Bash, digitação dinâmica.
Artyom : Então, eu queria reescrevê-lo. Além disso, há um problema com o fato de o Python agora ter dois: no macOS, por padrão o segundo, e quase todo no Linux agora é o terceiro. Há todo tipo de piada. Se eu precisar de algum tipo de dependência para ligar, pedirei às pessoas que executem pip? Ou vou ter que bater nela?
Eu queria usar uma linguagem de sistema que requer zero dependências, para que eu possa colocar um binário que pesa, condicionalmente, menos de um megabyte e trabalhe com sobrecarga mínima.
Oleg : Você pode pegar Golang, pelo menos tem um coletor de lixo.
Artyom : É exatamente por isso que eu queria experimentar o Rust. E funcionou. Além disso, Golang está meio triste com os genéricos.
Eugene : Desde que começaram a discutir linguagens ... No contexto do desenvolvimento do Android, a pergunta "Kotlin ou Java" já está cansada, mas ainda assim eu vou perguntar para passar para a próxima pergunta.
Artyom : Bem, Kotlin, é claro.
Eugene : Agora a pergunta que realmente interessa. Recentemente, em Kotlin, as corotinas tornaram-se estáveis e as vozes "Hooray, vamos nos afastar do RxJava" são ouvidas. Portanto, quando vejo uma pessoa na minha frente que é muito próxima ao RxJava, quero imediatamente perguntar sua opinião sobre as corotinas.
Artyom : Eu fui muito negativo em relação às corotinas. Em princípio, ainda é principalmente negativo, mas isso mudou em parte a longa conversa com
Roma Elizarov , que está trabalhando neles.
Como usuário de programas, quero que eles sejam o menos bloqueadores possível, que usem os recursos da maneira mais correta possível. Por isso, quero dizer paralelismo e o fato de que eles usam as APIs corretas do sistema operacional para não bloquear o acesso à rede ou aos arquivos - há muitos problemas com isso nos sistemas operacionais, mas, no entanto, existem essas APIs. O que exatamente isso resolve? Como usuário, isso não importa para mim - se apenas os desenvolvedores resolverem esse problema de uma maneira que os torne confortáveis. Não tenho grandes problemas com isso. E esta é a visão de Roma Elizarov. Depois dessa conversa, eu de alguma forma deixei para lá.
Antes disso, como meu amigo
Arthur Dremov , parecia um retrocesso
para mim depois de vários anos usando Java na produção: o código novamente se torna imperativo, impuro, perde a compreensão do pipeline, novamente se torna uma bagunça, que o compilador se transforma em uma bagunça assíncrona para você.
Eu não uso corotinas, mas todos os exemplos que estou observando agora mudaram para uma abordagem estruturada, quando você nem vê qual trecho de código é corotina. Para ser sincero, estou com muito medo de olhar para isso. Como eu abro a solicitação pull no GitHub, alguns métodos são chamados para fazer upload da foto e do perfil, um deles vai para a rede e o outro para o SQLite local, e aqui o SQLite local pode ser facilmente bloqueado. Não vejo isso no código, porque as corotinas são feitas para que você não a veja. Talvez seja bom, mas para mim isso ainda é menos do design, porque nas abordagens de Rx é muito óbvio: você entende se isso faz parte do pipeline síncrono ou não.
Talvez essa seja minha única reclamação para as corotinas: quero ver quando ocorre a minha assincronia e quando não. Idealmente, quero que as pessoas escrevam um código mais funcional quando houver pequenas peças reutilizáveis ou pelo menos testáveis que combinem com outras. E voltamos ao fato de incorporar tudo na lógica e, em seguida, o compilador apenas o inverte.
Oleg : Deixe-me dar uma pequena oposição. O código legado é muito mais que novo. E se usarmos algumas coisas como trabalhar com uma rede, trabalhar com arquivos e assim por diante, ninguém reescreverá tudo isso rapidamente, por exemplo, usando o RxJava. E se tivermos rotinas automáticas, podemos, por exemplo, rastrear todos os syscalls, agrupá-los automaticamente e enviá-los para trancar lá, no estacionamento.
Artyom : É verdade que, em qualquer caso, você terá que chamar funções do contexto de corutin. Mas este é um pensamento interessante, sim.
Oleg : Talvez eles devam ser combinados de alguma forma? A API de nível superior estará no RxJava e a API de nível inferior nas corotinas.
Artyom : Sim, agora existem essas mudanças. Mas então surge a pergunta, porque, no momento, o RxJava pode fazer tudo o que as corotinas fazem, e as corotinas não podem fazer tudo o que o RxJava faz. , — . , , , - Rx Kotlin. . forEach - map, . , , Java- , . .
, Kotlin — . , Go , , API, , : . , , , , legacy, , . , Java Kotlin — legacy, , . , . - , .
, , . , , , — . .

: , . , , : Android-? , .
: … . , Android- . , . , : , . RxJava , : - . , , .
, iOS. , Lyft iOS- dependency injection RxSwift. 2019-. iOS-, , , clean, . , Android — .
, , — Google. « opinionated, , : , , ». — , , .
, «RxJava — , ...» : «, LiveData». , — RxJava, , . , , Google , .
: «, Google MVVM». , MVVM , , , MVVM . , Google.
, , scope . .
: , Room . - Architecture Components — , . Google , ? .
: , . , . !
: .
O próximo Mobius será realizado em São Petersburgo, de 22 a 23 de maio . Agora, seu programa ainda não foi anunciado, mas este é o momento mais lucrativo para comprar um ingresso: em 1º de fevereiro, os preços dos ingressos subirão. E também, como o programa ainda não foi concluído, o momento também é adequado para entrarmos nele: estamos em pleno andamento aceitando pedidos de relatórios. Todas as informações sobre a conferência e os ingressos estão no site .