Por Que 0.1 + 0.2 Não É 0.3: Ponto Flutuante Explicado

Execute 0.1 + 0.2 em um shell Python e você não recebe 0.3. Recebe 0.30000000000000004. Tente em JavaScript, Java, Go, C ou Rust e aparece a mesma cauda de dezesseis dígitos. Cada uma dessas linguagens faz exatamente o que o padrão de hardware determina. Um número que precisaria de infinitos dígitos binários é comprimido em 64 bits, e algo precisa ser descartado. Por que 0.1 não pode ser guardado de forma exata em binário Computadores guardam números de ponto flutuante na base 2. Na base 2, a fração 1/10 tem uma expansão periódica, do mesmo jeito que 1/3 se repete para sempre na base 10 (0.3333...). Escrito por completo, 0.1 em binário começa assim: ...

6 de outubro de 2026 · 6 minutos · 1204 palavras · SpaghettiCoder

LocalStorage, SessionStorage ou Cookies: Qual Usar

Um endpoint de login devolve um JWT, e você tem três lugares para colocá-lo: um cookie, localStorage ou sessionStorage. Escolha errado, e ou um bug de XSS leva o token embora, ou o token nunca chega à sua API. Os três guardam strings no navegador. Eles diferem em quem pode lê-los, quanto tempo duram, e se o servidor chega a vê-los. Como localStorage, sessionStorage e cookies se diferenciam localStorage e sessionStorage são a mesma API, a interface Storage: setItem, getItem, removeItem, clear, chaves e valores em string. A diferença é o tempo de vida. localStorage sobrevive ao fechar o navegador e reiniciar a máquina, e permanece até algo limpá-lo. O Safari é a exceção: com a prevenção de rastreamento ativada, ele apaga o storage escrito por script de um site com o qual o usuário não interage há sete dias. sessionStorage pertence a uma aba e morre quando essa aba fecha. Digite a mesma URL em uma segunda aba e você recebe um sessionStorage novo e vazio; só “Duplicar aba” copia o conteúdo. ...

5 de outubro de 2026 · 8 minutos · 1505 palavras · SpaghettiCoder

Notação Big O Explicada com Exemplos de Código

Uma busca em um dicionário Python leva cerca de 100 nanossegundos, não importa se o dicionário tem 1.000 ou 1.000.000 de chaves. Um laço duplo que procura duplicatas em uma lista leva meio milissegundo com 200 itens e 136 milissegundos com 3.200. Dezesseis vezes a entrada, quase 280 vezes a espera. Mesma máquina, mesmo Python. A notação Big O é o nome dessa diferença. O que a notação Big O mede Big O descreve como o tempo de execução (ou o uso de memória) de um trecho de código cresce conforme a entrada aumenta. Não é uma leitura de cronômetro, e não importa se o seu notebook é rápido ou lento. O que importa é a forma da curva de crescimento: ao dobrar a entrada, o tempo dobra, quadruplica ou quase não muda? ...

4 de outubro de 2026 · 9 minutos · 1734 palavras · SpaghettiCoder

Git Reset vs Revert vs Restore: Como Desfazer Mudanças

Rode git reset --hard num commit que seu time já deu pull nele, e seu histórico passa a discordar do deles. Rode git revert num typo que você nem chegou a dar push nele, e acaba de acrescentar um commit inútil ao log. O Git tem quatro comandos para desfazer mudanças, restore, reset, commit --amend e revert, e eles não são intercambiáveis. Escolher o errado ou não faz nada, ou faz muito mais do que você queria. ...

3 de outubro de 2026 · 7 minutos · 1400 palavras · SpaghettiCoder

Tipos de JOIN em SQL Explicados com Exemplos

Um JOIN mal escrito não gera um erro. Ele executa, devolve um resultado, e as linhas estão erradas: clientes faltando, totais inflados, registros órfãos escondidos. Na maioria das vezes a consulta recebeu exatamente o que pediu, e quem a escreveu escolheu o tipo de join errado, ou filtrou no lugar errado. Um join combina linhas de duas tabelas com base numa condição que você escreve. Quais linhas sobrevivem depende do tipo de join, e os seis tipos abaixo dão seis respostas diferentes a partir das mesmas duas tabelas. ...

2 de outubro de 2026 · 9 minutos · 1917 palavras · SpaghettiCoder

O Que É Dependency Injection (Com Exemplos)

Aqui está uma classe que você não consegue testar com um teste unitário sem um banco de dados ativo e um servidor SMTP funcionando: 1 2 3 4 5 6 7 8 9 10 11 public class OrderService { private readonly SqlOrderRepository _repository = new SqlOrderRepository("Server=prod-db;Database=Orders;..."); private readonly SmtpEmailSender _emailSender = new SmtpEmailSender("smtp.company.com"); public void PlaceOrder(Order order) { _repository.Save(order); _emailSender.Send(order.CustomerEmail, "Order confirmed"); } } OrderService cria o próprio SqlOrderRepository e SmtpEmailSender com new, connection string e tudo mais. Todo teste que toca PlaceOrder precisa de um banco de dados Orders real e um servidor de e-mail real, ou falha antes mesmo da sua assertion rodar. A lógica que você quer testar tem duas linhas: salvar o pedido, enviar a confirmação. Ela está soldada a duas classes concretas que você não consegue trocar. ...

1 de outubro de 2026 · 8 minutos · 1591 palavras · SpaghettiCoder

Ambientes Virtuais Python: venv, pip e uv

Instale dois projetos Python na mesma máquina e o segundo pode quebrar o primeiro. Um precisa de requests==2.28, o outro de requests==2.32, e o pip tem exatamente um diretório site-packages global para escrever. A última instalação vence, em silêncio. Você descobre quando o outro projeto começa a lançar erros que não têm nada a ver com o código que você acabou de alterar. Um ambiente virtual dá a cada projeto o seu próprio site-packages. Nada global é tocado, e dois projetos podem depender de versões incompatíveis da mesma biblioteca sem que nenhum perceba o outro. ...

30 de setembro de 2026 · 7 minutos · 1489 palavras · SpaghettiCoder

Teste Unitário vs Teste de Integração vs End-to-End

Uma função pode ter 100% de cobertura de testes unitários e a página que a chama ainda assim pode retornar um 500 em produção. Isso não é uma contradição. Testes unitários, de integração e end-to-end verificam coisas diferentes, e uma suíte forte em um e fraca em outro tem um buraco específico e previsível. O que cada tipo de teste verifica: unitário, integração e end-to-end Pegue uma funcionalidade de cadastro: uma função valida a entrada, grava uma linha em um banco de dados e envia um email de boas-vindas. Três testes podem cobrir isso, e cada um responde a uma pergunta diferente. ...

29 de setembro de 2026 · 11 minutos · 2282 palavras · SpaghettiCoder

Async/Await e o Event Loop do JavaScript Explicados

Execute isto no Node ou no console do navegador: 1 2 3 4 console.log("1"); setTimeout(() => console.log("2"), 0); Promise.resolve().then(() => console.log("3")); console.log("4"); O resultado é 1 4 3 2. Um setTimeout com um delay de 0ms ainda é executado depois do callback da promise, e os dois esperam que todas as linhas de código síncrono abaixo deles terminem primeiro. O async/await é construído sobre essa ordem, não é algo novo. A maior parte do comportamento surpreendente do JavaScript assíncrono vem de tratar o await como se ele pausasse o programa inteiro, quando na verdade ele só pausa a função em que está. ...

28 de setembro de 2026 · 8 minutos · 1664 palavras · SpaghettiCoder

Como Funcionam os Índices de Banco de Dados

Em uma tabela com um milhão de linhas, a mesma SELECT pode levar cinquenta milissegundos ou bem menos de um. A única diferença é se o banco de dados lê cada linha para encontrar as que você pediu, ou pula direto até elas. Um índice é o que permite esse salto, e você paga por isso em cada escrita. Na prática, um índice é uma segunda cópia ordenada de uma ou mais colunas, guardada ao lado da tabela e atualizada automaticamente sempre que a tabela muda. O banco de dados usa essa cópia para chegar às linhas correspondentes sem tocar no resto. ...

27 de setembro de 2026 · 9 minutos · 1820 palavras · SpaghettiCoder