Olá pessoal, tudo bem? Hoje eu tenho o mega prazer de ter aqui comigo o Fernando Costa. O Fernando Costa, ele é Cloud Engineer na Google e é um cara que tem uma mega experiência com desenvolvimento e arquitetura de software e soluções. O Fernando, ele já passou por diversas empresas. Eu o conheci quando ele ainda trabalhava na Oracle e agora ele está na Google. E o mais interessante é que, quando você trabalha nesses tipos de empresa, você acaba trabalhando com muitos projetos grandes e você consegue ter um repertório muito grande. Então, hoje, a gente vai entender o que está aí, a black box, aí na cabeça do Fernando, para a gente entender mais como ele pensa e também muito de como que o Google segue, inclusive, para nesses standards, para system design. É muito interessante a gente citar isso porque cada empresa tem uma visão disso. Você olhar Microsoft, eles pensam de um jeito. Você olhar uma galera da AWS, eles vão trabalhar de outra forma. Google trabalha de formas diferentes. Mas eu acredito que existem alguns princípios que são os mesmos. Então eu acredito que a gente vai conseguir entender bastante dessa pegada aí com o Fernando. Fernando, novamente, cara, muito obrigado por dar essa aula aqui. E eu estou deixando o palco aqui para você, beleza? Beleza, maravilha. Obrigado pelo convite. Boa noite, pessoal. Então, vamos falar um pouco de design e me apresentar um pouco aí. O Wesley me apresentou, trabalha aqui, trabalha no Google e vim aqui compartilhar um pouco sobre System Design, uma das disciplinas que eu mais gosto, tirando o Kubernetes, não é Wesley? Então, usar um pouco da minha experiência de Dev para a gente discutir um pouco sobre isso. Estava conversando com o Wesley que estava fazendo um café da manhã recentemente e estava pensando na aula de hoje. Falei, cara, como a gente pode começar uma aula de System Design? Eu vi o material que vocês estavam trabalhando, as anotações pelas quais vocês passaram, o que vocês avaliaram. Eu falei, cara, como que eu posso contribuir para determinar algumas coisas aqui, para nortear algumas particularidades aqui da disciplina. E aí, eu estou trazendo para vocês, não sei se todo mundo conhece, mas aqui é uma pedaleira, um multiprocessador. Está vendo aí, Wesley? Sim. Está na mão. É um multiprocessador, beleza? O que esse cara faz, ele é um sintetizador de som. Então, quando a gente troca uma guitarra, por exemplo, a gente utiliza esse cara aqui para trazer o som mais próximo do que a gente precisaca uma guitarra, por exemplo, a gente utiliza esse cara aqui para trazer o som mais próximo do que a gente precisa. Para ele responder o que a gente, o guitarrista, ou vamos falar agora em computação, o que a gente como usuário em produto, eu como usuário, o que eu quero de requisito. Então, lógico, é isso que eu vou buscar o som. Só que que existe uma similaridade muito grande entre preparar um som para a gente tocar uma guitarra e desenvolver o System Design. Então, a primeira pergunta é Quais são as variáveis mais importantes para a gente entender sobre um requisito de software? Então, tem três variáveis, três constantes importantes nessa nossa avaliação. representantes nessa nossa avaliação. A primeira constante que a gente tem é o software, que é o que a gente vai colocar para ser executado em algum lugar. A segunda é o workload. O workload é o que vai estar sobre o software, a carga de trabalho que vai ser rodada sobre o software e que eu preciso de fato que ela seja processada para eu ter uma entrega que o usuário está esperando, então meu workload. E a terceira variável importante para mim aqui é o ambiente. Eu quero dizer, é o software onde ele vai executar, o workload que ele vai processar, o software que vai executar, o workload que ele vai processar, o software que vai executar, o workload que ele vai processar e a plataforma que ele vai executar. E essa plataforma hoje, para a gente, ela pode ser uma plataforma que é on-premises ou ela é cloud. Fernando, tem outros cenários? Tem. A gente pode falar que a gente tem multicloud e a gente tem ambientes híbridos. Se eu for considerar o que eu preciso entender para poder fazer um system design, primeiro eu preciso entender que tem essas três variáveis importantíssimas. E lógico, eu posso ter o mesmo software com o mesmo workload rodando no on-premise e eu ter um comportamento, eu posso ter o mesmo software rodando sobre cloud com o mesmo workload e ter outro comportamento, eu posso alterar o workload do mesmo software no mesmo ambiente, eu também ter comportamento distinto. Então, essas três variáveis, eu preciso ter em consideração para eu poder fazer qualquer system design. Para começar a falar de qualquer system design, antes de começar a escutar qualquer requisito de cliente, eu preciso entender que eu vou ter variações baseado, variações comportamentais baseado nessas variáveis. Software, workload e ambiente. Então, essas três variáveis acabam determinando a qualidade da experiência do usuário. da experiência do usuário. Isso é importante, então. Às vezes a gente começa a escutar alguns requisitos de qualidade, vou falar de alguns deles já já, e a gente fala, poxa, então essas qualidades são afetadas por essas três características aqui fixas que eu tenho em consideração. Outra regra para mim, pelo menos pessoal, quando eu vou começar a escutar sobre System Design, é outra premissa, vou até deixar aqui, premissas. Outra premissa importante para mim é que em grande escala tudo vai falhar. Fernando, você é pessimista, tudo vai falhar. Cara, eu tenho que ter isso em mente. Não precisa ser o usuário que vai trazer isso à tona como um requisito. Por exemplo, a Fernando Software precisa ser resiliente. A Fernando Software precisa... Cara, em grande escala, tudo vai ficar. Mas, assim, quando maiores as proporções de carga, piores as proporções de impacto. E o que a gente tem que entender? Quando isso acontece, tenha uma certeza muito clara. Sempre vai ser no momento menos adequado. Então, eu tenho que entender isso. A minha premissa é se eu começo as variáveis, em grande escala, tudo vai falhar e sempre vai acontecer no momento menos adequado. Se a gente estivesse reunido aqui, eu fizesse essa pergunta para você, Wesley, para a mesa e perguntasse, cara, isso é verdade? Eu tenho certeza que mais que um par de pessoas aqui traria esse exemplo para a minha mesa, falaria que já viram softwares e viriam ter condições não satisfatórias de execução nos momentos menos adequados. Então, para mim, é essa outra verdade importante, premissa importante, que eu sempre tenho em consideração antes de fazer qualquer dibu, qualquer rabisco, qualquer análise. Faz sentido, Wesley, o que eu estou falando? Você está no multe, está? Com certeza. Não tem jeito, né? As coisas falham, as coisas dão errada, por mais que você se planeje e se a gente partir do princípio, né, que tudo vai falhar, fica mais fácil a gente pensar, qual oípio que tudo vai falhar, fica mais fácil a gente pensar qual o meu plano B? Como que eu vou tentar contornar e tentar oferecer a melhor experiência mesmo que o meu sistema falhe? Acho que aí que é o grande pulo do gato. Exato. Então a gente precisa entender isso como deve, como arquiteto. Primeiro, vai falhar. Aí, a gente começa a falar de recursos. Que pré-requisitos, que premissas eu preciso entender prévio a fazer qualquer system design. Primeiro, naturalmente, o que a gente precisa ter em mente é uma regra de ouro. A regra de ouro, para mim, uma das primeiras regras de ouro é que eu não vou armazenar o que não é necessário. Então, por que eu não vou armazenar o que não é necessário, Fernando? Vou falar já já. Então, eu não vou armazenar o que não é necessário, Fernando? Vou falar já já. Então, eu não vou armazenar nada necessário. Por quê? Cara, porque recurso é escasso, processamento é escasso, por mais que pareça é. E alguns recursos são lentos. Memória RAM é um recurso lento. A gente precisa ter isso em consideração também. Então, a gente vai buscar armazenar em memória somente o que for significativo e armazenar da melhor maneira em memória. Então, já que a RAM, o processo de armazenamento em memória RAM é lento, eu preciso acessar a memória de forma previsível. dos requisitos que eu vejo tecnicamente. Mas eles são condições que impactam softwares em grande escala. Se eu não acesso um dado de forma previsível, significa que eu vou ter um processamento posterior para organizar esse dado que está em memória. Isso traz um custo desnecessário para o meu processamento de software. Então, não armazenar nada que é necessário, entender que a memória é um recurso lento e tudo que eu for armazenar tem que ser de forma presível. Deixa eu ver. Há outros recursos que a gente evita, eu não sei se todo mundo está familiarizado aqui, mas a gente evita recursos onde a gente faça também demais operações de lock e unlock sobre o design de aplicativo. Na verdade, a gente evita usar mutex em algumas condições. Por que isso? Porque quando a gente começa a perceber isso, a gente precisa entender que no design tudo é acumulativo. Então, isso é importante. Tudo é acumulativo. Se tudo é acumulativo. Se tudo é acumulativo, eu vou evitar coisas que me trazem degradação em escala. Isso é importante, porque quando eu vou colocar lá no papel uma solução, se eu entender que algumas operações de lock e unlock custam pelo menos 25 nanosegundos por operação, eu vou evitar de utilizar lock e unlock de algumas formas. Então, eu vou trabalhar com as threads, os recursos que eu tenho, os processos que eu tenho de bloqueio de forma mais inteligente, para evitar que esses bloqueios me levem à sobrecarga de tempo durante o meu processo completo. Então, tudo que é muito acumulativo, a gente acaba entendendo e escutando de uma maneira diferente. E é por isso que, como a gente entende que tudo é acumulativo, a gente precisa entender de um princípio básico, que é dividir essas responsabilidades.