Tema: java
-
Como escrever um teste unitário em JUnit 5 e xUnit.net: anotações, ciclo de vida e casos parametrizados lado a lado
O JUnit Jupiter marca testes com @Test, executa @BeforeEach e @AfterEach em torno de cada um, por padrão numa instância nova, e conduz casos baseados em dados com @ParameterizedTest mais uma anotação de fonte. O xUnit.net usa [Fact], o construtor e IDisposable para a preparação por teste numa instância nova, [Theory] com [InlineData] para os casos e fixtures para contexto compartilhado e caro. Escrever testes com a mesma estrutura nos dois mantém alinhadas as convenções de uma equipe poliglota.
-
Dimensionar uma JVM dentro de um contêiner: percentual de heap, memória fora do heap e número de CPUs
Por padrão, a JVM lê os limites do cgroup (UseContainerSupport) e dimensiona o heap como um percentual da memória do contêiner, não da do host. Como o heap é só parte do consumo total, defina MaxRAMPercentage deixando espaço para metaspace, pilhas de threads, buffers diretos e code cache, confira quantas CPUs a JVM enxerga e verifique com -Xlog:os+container e native memory tracking antes de confiar em um limite.
-
Maven versus Gradle: o que um iniciante precisa saber para compilar o projeto JVM de outra pessoa
O Maven descreve o projeto de forma declarativa no pom.xml e executa fases fixas do ciclo de vida (validate, compile, test, package, verify, install, deploy), às quais se associam goals de plugins; o Gradle executa um grafo de tarefas configurado por scripts build.gradle(.kts) e plugins. Ambos resolvem dependências transitivas, mas com regras de conflito diferentes (Maven: definição mais próxima; Gradle: versão mais alta), e ambos fornecem um script wrapper que fixa a versão da ferramenta de build.
-
Records, tipos selados e pattern matching em switch no Java
Records (JDK 16) são portadores de dados transparentes e imutáveis, com construtor canônico, acessores, equals, hashCode e toString gerados; tipos selados (JDK 17) restringem quais classes podem estendê-los ou implementá-los, de modo que um switch com padrões (JDK 21) sobre a hierarquia tenha a exaustividade verificada. Juntos, dão ao Java um tipo soma leve.
-
Coleta de lixo na JVM: os coletores, os padrões e as poucas flags que valem a pena configurar
O HotSpot inclui os coletores Serial, Parallel, G1 e ZGC; escolhe o G1 em máquinas que considera de classe servidor (dois ou mais processadores e pelo menos 1792 MB) e o Serial nas demais, com heap máximo padrão de um quarto da memória. Para a maioria dos serviços, vale configurar o heap máximo, o log de GC e, só depois de ler os logs, um coletor ou uma meta de tempo de pausa.
-
Desserialização de dados não confiáveis: pickle e serialização Java
Formatos nativos de serialização de objetos instruem o receptor a construir objetos arbitrários, e construir objetos executa código; a documentação do pickle em Python afirma abertamente que o módulo não é seguro. Nunca desserialize esses formatos a partir de entrada não confiável; se uma interface legada o impuser, restrinja as classes que o fluxo pode nomear e assine o payload.
-
Após migrar um serviço JVM para virtual threads: o que mudou em throughput, memória e incidentes de pinning, e o que precisou ser reescrito?
Pergunta em aberto: o JEP 444 afirma que o pinning não torna uma aplicação incorreta, mas pode prejudicar sua escalabilidade, e o JEP 491, entregue no JDK 24, elimina o pinning em blocos synchronized. Em serviços que passaram o tratamento de requisições para virtual threads, como ficaram throughput e memória, que incidentes de pinning ou de esgotamento de pools ocorreram e que código e bibliotecas tiveram de mudar?
-
Threads virtuais em Java em linhas gerais: o que muda e o que não muda
A JEP 444 (JDK 21) introduz threads virtuais: threads baratas, escalonadas pelo JDK sobre um pequeno conjunto de threads de plataforma (carriers). As threads virtuais são desmontadas enquanto bloqueiam na maior parte da E/S do JDK, de modo que o código no estilo thread por requisição escala sem estilo assíncrono. Elas não são mais rápidas, nunca devem ser colocadas em pool e, até a JEP 491 (JDK 24), bloquear dentro de synchronized fixava o carrier.
-
Tokens de formato de data e hora: strftime, Java, Go, .NET e Moment/date-fns lado a lado
A mesma letra significa coisas diferentes conforme a biblioteca de formatação: o Y maiúsculo do Java é o ano semanal, não o ano do calendário, e D é o dia do ano em Java e date-fns, mas o dia do mês no Moment. Esta tabela de tokens serve para conferir uma string de formato gerada antes de confiar nela.
-
Streams versus loops em Java: quando um pipeline é mais claro e quando não é
Um stream é um pipeline preguiçoso (lazy) de operações intermediárias encerrado por uma única operação terminal; lê-se bem em filter, map e collect sobre uma coleção. Mas a documentação do pacote desaconselha efeitos colaterais nas lambdas, um stream não pode ser reutilizado, exceções verificadas não se encaixam, e um loop é mais claro para saída antecipada com estado, trabalho baseado em índice e mutação.
-
Por que as aplicações ignoram o repositório de confiança do SO: Java cacerts, Python certifi, Node.js e curl
Adicionar uma CA ao repositório de confiança do sistema operacional não faz todas as aplicações passarem a confiar nela. Java, muitas instalações de Python, Node.js e builds do curl podem ter seu próprio bundle de CAs ou keystore, cada um com localização de arquivo e variável de ambiente próprias, então um erro de certificado pode persistir após a correção no nível do SO.
Legível por máquina: JSON