Felipe Tófoli - São Paulo, São Paulo, Brazil | Professional Profile | LinkedIn (original) (raw)
- William Lima Begen • 12K followers Conhece o Docker Composer para Windows? Sentiu que o seu PC "ficou mais lento" após a instalação dele? 𝐄𝐮 𝐬𝐞𝐢 𝐨 𝐦𝐨𝐭𝐢𝐯𝐨! Creio que a maioria das pessoas que usam Windows como plataforma de desenvolvimento de software, uma hora ou outra acabam esbarrando no 𝐃𝐨𝐜𝐤𝐞𝐫 𝐟𝐨𝐫 𝐃𝐞𝐬𝐤𝐭𝐨𝐩. É sabido que durante o processo de instalação do 𝐃𝐨𝐜𝐤𝐞𝐫 𝐟𝐨𝐫 𝐃𝐞𝐬𝐤𝐭𝐨𝐩, ele recomenda que instalemos em conjunto o WSL 2 em vez de usar o Hyper-V. Para aqueles que não sabem, o WSL ou WSL2 (Windows Subsystem for Linux 2) nada mais é do que um app de Windows que te permite executar um ambiente Linux diretamente no seu Windows 10/11, tudo isso dentro de uma virtualização mais leve. Sendo assim, sempre quando você cria/roda um container no Docker, por de baixo dos panos, o WSL/WSL2 está rodando, e esse processo consome bastante memoria RAM da sua máquina. Enquanto você está programando e fazendo o uso do Docker, beleza! Isso é aceitável! Mas o problema começa quando desligamos o Docker, paramos de programar, e voltamos a ser um usuário comum do Windows, e é aí que pode morar um problema invisível. O WSL é conhecido por ser um pouco "fominha" com a memória RAM. Mesmo que o Docker pare, o Windows costuma manter uma parte da memória reservada para o WSL, isto é, caso você decida abrir ele novamente. Tanto é, que se você abrir o Gerenciador de Tarefas, é bem provável que exista um app chamado de Vmmem, que está consumindo bastante memoria RAM. Dito isso, aqui vai uma dica de amigo: Se você não usa o Docker o tempo todo, vale a pena ir nas configurações do Docker Desktop (Settings > General) e desmarcar a opção "Start Docker Desktop when you log in". Isso evita que o seu PC já acorde com o WSL ocupando memória. Terminou de usar o Docker? Vai jogar, ver séries, ou qualquer outra coisa? Não se esqueça de abrir o terminal e matar o WSL só por garantia. Para isso use o seguinte comando: 𝙬𝙨𝙡 --𝙨𝙝𝙪𝙩𝙙𝙤𝙬𝙣
- Lucas Faria PostHog • 49K followers O livro Clean Code pode ser a coisa mais perigosa na mão de um dev júnior. Eu sei, é heresia falar isso. Mas deixa eu explicar. A regra de ouro do Uncle Bob é: "uma função deve ter 3 ou 4 linhas". Se tem um "if", ele deve virar uma chamada de função. O resultado disso em mãos inexperientes? O que o John Ousterhout chama de "Classitis" ou "Shallow Modules". Você abre um projeto e, pra entender um fluxo simples, precisa pular por 15 arquivos diferentes com funções de 2 linhas que só chamam outras funções. Mano, isso não é código limpo. Isso é código espalhado. O livro que mudou minha forma de pensar arquitetura foi "A Philosophy of Software Design". O conceito matador: Deep Modules (Módulos Profundos). ✅ A interface deve ser simples (o "o quê" o módulo faz). ✅ A implementação deve ser profunda (o "como" ele faz, escondendo a complexidade). Um módulo bom é como um iceberg: você só vê a pontinha (a API), mas por baixo ele resolve um problema gigante sem te incomodar com os detalhes. Por que isso importa mais que nunca em 2026? Com IAs gerando milhares de linhas de código em segundos, o nosso trabalho mudou. O código virou commodity. A arquitetura e a manutenibilidade viraram o prêmio. Se você foca só em "funções curtas", você cria um emaranhado impossível de auditar. Se você foca em "módulos profundos", você cria sistemas que sobrevivem ao tempo. Menos regras arbitrárias de número de linhas. Mais foco em esconder complexidade. Qual desses dois livros mais influenciou seu jeito de codar? 👇 PS: Se você só leu Clean Code, faça um favor à sua senioridade e leia "A Philosophy of Software Design" este mês. É o melhor investimento de R$150 que você pode fazer.
- Miguel P. MPV Soluções • 2K followers Senioridade em arquitetura não é tentar forçar uma transação única onde ela não cabe. É entender que, em sistemas distribuídos, consistência precisa ser coordenada de outra forma. Um exemplo clássico é o Saga Pattern. Imagine um fluxo de pedido em microserviços: criar pedido. reservar estoque. processar pagamento. solicitar entrega. notificar o cliente. Em um monolito com um único banco, talvez você resolvesse isso com uma transação tradicional. Mas em microserviços, cada serviço pode ter seu próprio banco, sua própria regra, sua própria disponibilidade e seu próprio tempo de resposta. Não existe um BEGIN TRANSACTION mágico envolvendo tudo. E tentar simular isso de forma ingênua costuma criar acoplamento, lentidão e fragilidade. É aí que o Saga Pattern faz sentido. A ideia é dividir uma operação de negócio em várias etapas locais. Cada serviço executa sua parte e confirma sua própria transação. Se tudo dá certo, o processo avança. Se algo falha no meio, entram ações compensatórias. Exemplo: pedido criado. estoque reservado. pagamento falhou. Nesse caso, talvez a compensação seja cancelar o pedido e liberar o estoque. A Saga não “desfaz o tempo”. Ela executa novas ações para devolver o sistema a um estado aceitável. Esse detalhe é importante. Compensação não é rollback de banco. Compensação é regra de negócio. E é justamente por isso que Saga exige maturidade. Você precisa saber o que pode ser compensado, o que não pode, quais etapas são críticas, quais eventos devem ser rastreados, como lidar com duplicidade, timeout, retry, falha parcial e auditoria. Saga faz sentido quando existe um processo de negócio distribuído entre serviços, com várias etapas e necessidade de consistência eventual. Exemplos práticos: pedido, pagamento, estoque e entrega. abertura de conta com validação, cadastro e compliance. contratação de crédito com análise, proposta e formalização. workflow corporativo passando por serviços independentes. processamento financeiro com conciliação e eventos externos. Mas Saga também pode ser mal usada. Se tudo está no mesmo banco e a operação cabe em uma transação simples, usar Saga pode ser exagero. Se você não sabe definir as compensações, também não tem uma Saga. Tem só um fluxo quebrável com nome bonito. O ponto é simples: em sistema distribuído, falha parcial não é exceção. É cenário esperado. Saga Pattern existe para coordenar esse cenário sem fingir que todos os serviços fazem parte da mesma transação. Pattern sem propósito é decoração. Pattern bem aplicado é engenharia. #dotnet #csharp #backend #api #softwarearchitecture #sagapattern #microservices #eventdriven #distributedsystems #aws #azure #desenvolvimentodesoftware
- Felipe Fialho Juntos Somos Mais • 55K followers Código ruim, arquitetura inexistente, falha de processos, produção caótica cheia de bugs e decisões que ninguém entende: Poderia ser sobre vibe coding mas tô descrevendo como era programar antes de AI Vejo milhares de posts e memes preguiçosos dizendo que "vibe coding" destrói projetos, vamos precisar de gente pra corrigir tudo isso depois e blá-blá-blá, mas vamos ser honestos por um segundo: Quando foi que isso não rolava? Antes de AI a gente já lidava com projeto legado que ninguém escostava com medo de quebrar tudo, go horse institucionalizado como estratégia de entrega, senha hardcoded, query derrubando banco em produção e débito técnico que virou herança cultural do time Nada disso nasceu com LLM A diferença é que agora ficou mais rápido entregar porcaria. E também mais rápido perceber quem sabe o que tá fazendo E por isso precisamos ter controle do sistema ao redor disso: ➡️ Context engineering: configurar rules que definem padrões do projeto, skills especializadas por domínio e subagents com responsabilidades isoladas faz toda a diferença. LLM genérica vai tomar decisões genéricas e escolher abstrações genéricas. Isso precisa estar bem estabelecido e ser frequentemente refinado ➡️ Auditoria constante: output de LLM é ponto de partida, não entrega final. Revisar, rodar os testes, checar edge cases e questionar cada decisão que a ferramenta tomou silenciosamente ainda é trabalho seu. Skills, linters, análise estática e CI bem configurados ajudam, mas não substituem (ainda) seu olhar crítico ➡️ Code review bem definido: dá pra criar skills específicas pra revisar regras de negócio, segurança e performance antes do PR chegar no time. Checklist automatizado e agentes que apontam débito técnico antes do merge já existem e funcionam ➡️ Decisões técnicas: código que funciona e código que escala são coisas diferentes. Com AI ficou mais fácil introduzir padrões ruins que passam nos testes mas quebram a coesão da base. Mas também ficou mais fácil evitar isso, com arquitetura documentada no contexto e rules que forçam consistência. Entregar com débito técnico hoje simplesmente não faz mais sentido LLM não cria bagunça sozinho, só amplifica o que sempre existiu no time, no processo e na cultura. Se o ambiente é desorganizado, a desorganização escala de um jeito que nunca vimos antes. Se ninguém assume responsabilidade, vira caos mais rápido E tem um ponto que os críticos sobre vibe coding convenientemente ignoram: Bons profissionais já mitigavam tudo isso antes, com code review criterioso, arquitetura pensada e processos que respeitavam a complexidade do produto. Agora estão entregando ainda melhor, mais rápido e com mais eficiência e qualidade A régua subiu, não desceu No fim, a regra continua exatamente a mesma. A responsabilidade de entregar uma aplicação sempre foi sua e segue sendo sua Se ficou uma merda, a culpa não é da AI É só sua mesmo
- Ricardo Valencia Bradesco Insurance • 658 followers A AWS acabou de lançar o S3 Files. E, com isso, acabou de expor uma verdade incômoda: muita arquitetura ainda está presa a uma separação artificial entre file #storage e object storage. O novo serviço permite acessar dados do Amazon S3 como file system compartilhado, conectando recursos de computação diretamente aos dados no S3, com semântica completa de sistema de arquivos e sem tirar os dados do próprio S3. A própria AWS posiciona o S3 Files como o “primeiro e único cloud object store” com acesso a arquivos de alta performance e com recursos completos de file system. Isso não é só mais um lançamento. Isso é a AWS dizendo, de forma bem clara, que a fronteira entre armazenamento de objetos e consumo via sistema de arquivos está ficando irrelevante para boa parte dos workloads modernos. Mudanças feitas no file system são refletidas no bucket S3, e múltiplos recursos de computação podem compartilhar os mesmos dados sem duplicação desnecessária. A provocação real é outra: quantas arquiteturas ainda estão mais complexas do que deveriam só porque foram desenhadas em cima de limitações que a nuvem já começou a remover? Se você ainda trata storage como uma decisão puramente de custo, talvez esteja ignorando o impacto direto disso em produtividade, modernização de aplicações, pipelines de dados e workloads de IA. A documentação da AWS destaca acesso compartilhado, baixa latência, sincronização automática com o bucket e roteamento inteligente de leitura entre a camada de alta performance e o próprio S3. Para arquitetos, engenheiros de plataforma e líderes de tecnologia, o recado é simples: não basta mais discutir onde os dados ficam. Agora é preciso discutir como os dados podem ser consumidos sem forçar a arquitetura a contornar o storage. Quem entendeu isso cedo, simplifica. Quem não entendeu, continua empilhando serviço para compensar fricção arquitetural. E você, o que achou dessa novidade? Comenta aí.
- Rodrigo Vieira Pinto, MSc C6 Bank • 4K followers Kafka e Schema Registry Em arquiteturas orientadas a eventos, existe uma verdade que muita gente aprende tarde demais: dados evoluem, e sistemas quebram quando fingimos que isso não vai acontecer. Exemplo: times adotam Kafka para desacoplar sistemas, ganhar escala e velocidade. Os primeiros eventos são simples, tudo flui bem… até que o negócio muda. Surge um campo novo. Ou outro perde o sentido. Um tipo precisa evoluir. Nada fora do normal. Mas sem uma estratégia clara para lidar com essa evolução, o que era desacoplamento vira tensão constante: * produtores avançam mais rápido que consumidores * consumidores quebram de forma silenciosa * deploys passam a exigir alinhamento manual entre times e, com o tempo, surge o medo de mudar O Kafka continua funcionando. Mas o que falha é a ausência de contratos claros de dados. O Schema Registry existe exatamente para tratar dados como contratos vivos. Ele permite: * definir schemas explícitos para eventos * validar compatibilidade na evolução desses schemas * impedir mudanças que quebrariam consumidores em produção * e transformar evolução de dados em algo previsível e governável Mas usar Schema Registry não é só “ligar uma ferramenta”. Envolve decisões de modelagem, compatibilidade, ownership e responsabilidade. Foi por isso que escrevi o livro "Kafka e Schema Registry – modelagem de eventos com robustez e segurança". Não apenas para explicar o que é Schema Registry, mas para discutir como evoluir eventos sem quebrar sistemas e sem paralisar times. Porque, em sistemas distribuídos, a mudança é inevitável. Mas o caos não precisa ser. O link para ele está aqui: https://lnkd.in/dNFnJtix Bons estudos!
- Evandro Souza QuintoAndar • 2K followers Times não atrasam por falta de dev. Atrasam por falta de contratos. Já viu seu time assim? Várias tasks em andamento. Todo mundo ocupado. Pouca coisa realmente entregue. No início como Lead Software Engineer, vivi exatamente isso. Tínhamos vários devs, muitos PRs abertos… e quase nada chegando ao fim. O problema não era esforço. Era coordenação. E a solução não foi dividir mais o trabalho. Foi fazer o oposto: 👉 Colocar mais pessoas na MESMA story. Mas isso só funciona quando existe uma base clara. O verdadeiro gargalo não era gestão. Era arquitetura. Quando passamos a tratar contratos como prioridade zero, tudo mudou. E aqui, contratos não são ferramentas. São definições claras de: - APIs que estamos criando - Eventos que estamos publicando - Formatos de dados - Responsabilidades de cada parte Antes de codar, alinhávamos isso. Resultado: Enquanto o producer implementa sua parte, os consumers já desenvolvem em paralelo. E ao mesmo tempo: Enquanto o backend implementa, o frontend já desenvolve com mock. Sem bloqueios. Sem espera. Paralelismo real. Foi aí que percebi: 👉 Não era sobre processo. Era sobre especificação. Agora, olha o que está acontecendo com IA no dia a dia de dev. Muita gente usando Cursor, Claude Code, etc… mas ainda de forma sequencial. Uma tarefa por vez. Uma thread por vez. Mas dá pra ir além. 👉 Você pode rodar múltiplas sessões em paralelo. Enquanto uma sessão implementa uma API, outra já desenvolve o consumer. Enquanto uma mexe no backend, outra evolui o frontend com base no contrato. Só que isso só funciona se o contrato estiver claro. Sem isso? Você só troca gargalo humano por gargalo de contexto. A verdade continua a mesma: 👉 Sem contratos, não existe paralelismo. Só caos coordenado. Contratos não são burocracia. São o que permite velocidade. Seja entre pessoas ou entre sessões de IA. — E você? Já tentou trabalhar com múltiplas sessões em paralelo ou ainda está no modo sequencial? #SystemDesign #EngineeringPractices #AIForDevelopers #DeveloperProductivity #ClaudeCode #SoftwareEngineering
- Rodrigo Ribeiro Grupo OLX • 4K followers 🚫 Node.js e Python no Kubernetes: um erro comum de escalabilidade Um erro que vejo com muita frequência quando aplicações Node.js ou Python vão para Kubernetes é carregar padrões de deploy que faziam sentido em VMs, mas que não se encaixam bem no modelo de containers. Em ambientes mais tradicionais, é muito comum tentar extrair o máximo de uma única máquina. No Node.js, muita gente usa o módulo cluster para criar múltiplos workers e aproveitar todos os cores disponíveis. No Python, é comum subir a aplicação com Gunicorn usando vários workers. Não existe nada de errado com isso, em um servidor único, esse padrão funciona bem. O problema aparece quando levamos exatamente essa mesma lógica para dentro do Kubernetes. O Kubernetes foi pensado para escalar horizontalmente, não para concentrar vários processos dentro de um único container. A unidade de escala da plataforma é o pod. Quando colocamos vários workers dentro de um mesmo pod, acabamos indo contra essa lógica. Isso traz alguns efeitos colaterais que muitas vezes passam batidos. O primeiro é previsibilidade de recursos. O scheduler do Kubernetes trabalha com requests e limits de CPU e memória por container. Quando você coloca vários workers competindo dentro do mesmo container, fica muito mais difícil entender de fato como aquele pod consome recursos. Outro ponto é o autoscaling. Ferramentas como o Horizontal Pod Autoscaler tomam decisões baseadas em métricas agregadas do pod. Se você tem vários workers dentro dele, um deles pode estar saturado enquanto o consumo geral da CPU ainda parece aceitável. O resultado é que o autoscaling reage mais tarde do que deveria. Também existe uma questão de resiliência. Se um pod concentra vários workers e ele morre, você perde todos de uma vez. Quando cada pod roda um único processo, o impacto de uma falha tende a ser menor e a app se recupera de forma mais suave. Por isso, em muitos cenários de microserviços, uma abordagem mais alinhada com Kubernetes é ter um processo por container e escalar através de mais pods. No caso de Node.js, muitas vezes significa simplesmente rodar a aplicação sem cluster e deixar o HPA controlar o número de réplicas. Para aplicações Python usando Gunicorn, também é comum rodar com apenas um worker por container (ou poucos, dependendo do caso) e permitir que o cluster faça o trabalho de distribuir carga. Claro que existem exceções. Pods grandes, workloads muito CPU-bound ou ambientes sem autoscaling podem justificar múltiplos workers. Mas na maior parte das arquiteturas modernas, escalar pods costuma ser mais previsível, mais resiliente e mais alinhado com a forma como Kubernetes foi projetado para operar. É um detalhe pequeno, mas que faz bastante diferença quando a aplicação começa a crescer. #nodejs #python #developer #kubernetes #sre #dev #k8s #backend #software