- Armadilhas nada intuitivas em que desenvolvedores costumam cair são organizadas para apresentar as causas de bugs que tendem a ocorrer com facilidade
- Aborda problemas frequentes em várias tecnologias, como HTML, CSS, Unicode/codificação de texto, ponto flutuante e tempo
- Enfatiza que diferenças sutis de sintaxe e comportamento em cada linguagem e framework podem gerar mal-entendidos ou erros
- Explica com exemplos as armadilhas que podem surgir em ambientes reais de produção em áreas centrais de backend, como concorrência, redes e bancos de dados
- Por meio de vários exemplos e links de referência, orienta sobre situações problemáticas, formas de resolvê-las e melhorias para comportamentos inesperados
HTML e CSS
-
Valor padrão de min-width em Flexbox/Grid
min-widthéautopor padrãomin-width: autoé determinado pelo tamanho do conteúdo e tem precedência sobreflex-shrink,overflow: hidden,width: 0,max-width: 100%- Recomendação: declarar
min-width: 0
-
Diferença entre horizontal e vertical no CSS
width: autotenta preencher o espaço do elemento pai, enquantoheight: autose ajusta ao conteúdowidth: autode elementos inline, inline-block e float não se expandemargin: 0 autocentraliza na horizontal,margin: auto 0não centraliza na vertical (mas emflex-direction: column, a centralização vertical é possível)- Colapso de margem só ocorre na vertical
- Se a direção do layout mudar, como em
writing-mode: vertical-rl, o comportamento também se inverte
-
Block Formatting Context (BFC)
- É possível criar um BFC com
display: flow-root(também é possível comoverflow: hidden/auto/scroll,display: tableetc., mas há efeitos colaterais) - Um BFC pode evitar que margens verticais de irmãos adjacentes se sobreponham ou que a margem do filho “vaze” para fora do pai
- Se o pai contiver apenas filhos com float, sua altura colapsa para 0 → isso pode ser corrigido com BFC
- Se houver
borderoupadding, não ocorre colapso de margem
- É possível criar um BFC com
-
Stacking Context
- Condições que criam um novo stacking context
- Propriedades de renderização como
transform,filter,perspective,mask,opacityetc. position: fixedoustickyz-indexdefinido + posicionamentoabsolute/relativez-indexdefinido + elemento dentro de flexbox/gridisolation: isolate
- Propriedades de renderização como
- Características
z-indexsó se aplica dentro do stacking context- As coordenadas de
position: absolute/fixedse baseiam no ancestral posicionado mais próximo stickynão funciona atravessando o stacking context- Mesmo
overflow: visibleé recortado pelo stacking context background-attachment: fixedé posicionado com base no stacking context
- Condições que criam um novo stacking context
-
Unidades de viewport
- Em navegadores móveis, quando a barra de endereço/barra de navegação some da tela ao rolar, o valor de
100vhmuda - Solução mais recente: usar
100dvh
- Em navegadores móveis, quando a barra de endereço/barra de navegação some da tela ao rolar, o valor de
-
Referência para Absolute Position
position: absolutenão se baseia no pai, mas no ancestralrelative/absoluteou stacking context mais próximo
-
Comportamento do blur
backdrop-filter: blurnão leva em conta os elementos ao redor
-
Float sem efeito
- Se o pai for
flexougrid, ofloatdo filho não tem efeito
- Se o pai for
-
width/height em porcentagem
- Não funciona se o tamanho do pai não tiver sido definido previamente (para evitar referência circular)
-
Características de elementos inline
display: inlineignorawidth,height,margin-topemargin-bottom
-
Tratamento de whitespace
- Por padrão, quebras de linha em HTML são tratadas como espaço, e espaços consecutivos são reduzidos a um só
<pre>evita a redução de espaços, mas tem um comportamento peculiar no início/fim- Em geral, espaços no início/fim do conteúdo são ignorados, mas
<a>é uma exceção - Espaços/quebras de linha entre
inline-blockaparecem como espaçamento real (isso não ocorre em flex/grid)
-
text-align
- Aplica-se ao alinhamento de texto e elementos inline, mas não ao alinhamento de elementos block
-
box-sizing
- O valor padrão é
content-box→ não inclui padding/border - Com
width: 100%+padding, o elemento pode ultrapassar a área do pai - Solução:
box-sizing: border-box
- O valor padrão é
-
Cumulative Layout Shift
- Se
<img>não tiver os atributoswidtheheight, o atraso no carregamento da imagem pode causar instabilidade no layout - Recomendação: definir os atributos para evitar CLS
- Se
-
Requisições de rede de download de arquivos no Chrome
- Não aparecem no painel Network do DevTools (são processadas em outra aba)
- Se precisar analisar, use
chrome://net-export/
-
Problemas de parsing de JavaScript dentro de HTML
- Em casos como
<script>console.log('</script>')</script>, o primeiro</script>é interpretado como tag de fechamento - Referência: Safe JSON in script tags
- Em casos como
Unicode e codificação de texto
-
Code points e grapheme clusters
- Grapheme cluster é a “unidade de caractere” na GUI
- Em caracteres ASCII visíveis, 1 code point = 1 grapheme cluster
- Um emoji pode ser um único grapheme cluster composto por vários code points
- Em UTF-8, um code point ocupa de 1 a 4 bytes, e a quantidade de bytes não coincide com a de code points
- Em UTF-16, um code point ocupa 2 ou 4 bytes (par substituto, surrogate pair)
- O padrão não impõe limite ao número de code points dentro de um cluster, mas implementações costumam ter limites por desempenho
-
Diferenças no comportamento de strings por linguagem
- Rust: internamente usa strings UTF-8,
len()retorna número de bytes, indexação direta não é possível,chars().count()retorna o número de code points, valida rigorosamente a validade do UTF-8 - Golang: string é, na prática, um array de bytes; comprimento e indexação são em bytes; UTF-8 é o mais usado
- Java, C#, JS: baseados em UTF-16, medem comprimento em unidades de 2 bytes, e a indexação também é nessa base; há surrogate pairs
- Python:
len()retorna o número de code points, e a indexação retorna uma string contendo um code point - C++:
std::stringnão impõe restrições de codificação, funciona como um vetor de bytes, e comprimento/indexação são em bytes - Entre as linguagens mencionadas, nenhuma mede comprimento/faz indexação por grapheme cluster
- Rust: internamente usa strings UTF-8,
-
BOM (Byte Order Mark)
- Alguns arquivos de texto têm BOM; por exemplo, EF BB BF indica codificação UTF-8
- É usado principalmente no Windows, e softwares fora do ecossistema Windows podem não conseguir lidar com BOM
-
Outros cuidados
- Ao converter dados binários em string, partes inválidas são substituídas por � (U+FFFD)
- Existem confusable characters (caracteres que parecem muito semelhantes entre si)
- Normalização (Normalization): por exemplo,
épode ser representado como U+00E9 (um único code point) ou U+0065+U+0301 (dois code points) - Existem zero-width characters e invisible characters
- Diferença de quebra de linha: no Windows é CRLF
\r\n, no Linux/MacOS é LF\n - Unificação de Han (Han unification): caracteres com formas ligeiramente diferentes em cada idioma usam o mesmo code point
- A fonte renderiza corretamente incluindo variantes por idioma
- Em internacionalização, é necessário selecionar a variante de fonte correta
Ponto flutuante (Floating point)
-
Propriedades de NaN
- NaN não é igual a nenhum valor, incluindo ele mesmo (
NaN == NaNé sempre false) NaN != NaNé sempre true- O resultado de operações que incluem NaN geralmente se propaga como NaN
- NaN não é igual a nenhum valor, incluindo ele mesmo (
-
Valores especiais
- Existem +Inf e -Inf, diferentes de NaN
- -0.0 é um valor distinto de +0.0
- Em operações de comparação eles são iguais, mas em alguns cálculos se comportam de forma diferente
- Exemplo:
1.0 / +0.0 == +Inf,1.0 / -0.0 == -Inf
-
Compatibilidade com JSON
- O padrão JSON não permite NaN nem Inf
- Em JS,
JSON.stringifyconverte NaN e Inf emnull - Em Python,
json.dumps(...)imprime NaN e Infinity como estão (violando o padrão)- Com a opção
allow_nan=False, ocorreValueErrorse houver NaN/Inf
- Com a opção
- Em Golang,
json.Marshalretorna erro se houver NaN/Inf
- Em JS,
- O padrão JSON não permite NaN nem Inf
-
Problemas de precisão
- Comparação direta de ponto flutuante pode falhar → recomenda-se a forma
abs(a - b) < ε - Em JS, todos os números são tratados como ponto flutuante
- O intervalo seguro de inteiros é
-(2^53 - 1)~2^53 - 1 - Fora desse intervalo, a representação de inteiros fica imprecisa
- Para inteiros grandes, recomenda-se usar
BigInt - Se JSON contiver inteiros além do intervalo seguro, o valor resultante de
JSON.parsepode ser impreciso - Timestamps em milissegundos são seguros até o ano 287.396; em nanossegundos já causam problema
- O intervalo seguro de inteiros é
- Comparação direta de ponto flutuante pode falhar → recomenda-se a forma
-
Leis de operação que não se aplicam
- Dependendo da ordem das operações, por perda de precisão, associatividade e distributividade não valem estritamente
- Operações paralelas (multiplicação de matrizes, soma etc.) podem produzir resultados não determinísticos
-
Desempenho
- Divisão é muito mais lenta que multiplicação
- Ao dividir várias vezes pelo mesmo número, é possível otimizar calculando primeiro o recíproco e multiplicando
-
Diferenças conforme o hardware
- Suporte a FMA (Fused Multiply-Add): alguns hardwares fazem cálculos intermediários com maior precisão
- Tratamento de subnormal range: hardwares modernos suportam, mas alguns antigos tratam como 0
- Diferenças de modo de arredondamento
- Existem modos como RNTE (arredondar para o par mais próximo), RTZ (truncar para 0) etc.
- Em x86/ARM, isso pode ser configurado como estado mutável local à thread
- Em GPU, o modo de arredondamento varia por instrução
- Diferenças no comportamento de funções matemáticas como trigonométricas e logaritmos
- x86 tem FPU legada de 80 bits e rounding mode por núcleo → não recomendado usar
- Além disso, vários outros fatores podem fazer o resultado de ponto flutuante variar conforme o hardware
-
Como melhorar a precisão
- Montar um grafo de cálculo mais raso (reduzir cadeias longas de multiplicação)
- Evitar casos em que valores intermediários fiquem muito grandes ou muito pequenos
- Aproveitar operações de hardware como FMA
Tempo (Time)
-
Segundo intercalar (Leap second)
- O timestamp Unix ignora segundos intercalares
- Quando ocorre um segundo intercalar, o tempo pode se alongar ou encurtar na região ao redor (Leap smear)
-
Fuso horário (Time zone)
- UTC e timestamp Unix são comuns no mundo todo
- Horários legíveis por humanos dependem do fuso horário local
- Recomenda-se armazenar timestamps no banco de dados e converter na UI
-
Horário de verão (DST)
- Em algumas regiões, o relógio é ajustado em 1 hora durante o verão
-
Sincronização NTP
- Durante a sincronização, pode acontecer de o tempo “voltar para trás”
-
Configuração de fuso horário do servidor
- Recomenda-se configurar servidores em UTC
- Em sistemas distribuídos, diferenças de fuso entre nós causam problemas
- Após mudar o fuso do sistema, pode ser necessário reconfigurar ou reiniciar o banco de dados
-
Relógio de hardware vs relógio do sistema
- O relógio de hardware não tem conceito de fuso horário
- Linux: trata o relógio de hardware como UTC
- Windows: trata o relógio de hardware como horário local
Java
==compara referências de objetos; para comparar o conteúdo do objeto, é preciso usar.equals- Se
equalsehashcodenão forem sobrescritos, a identidade do objeto em map/set é julgada com base na referência - Se o conteúdo de um objeto usado como chave de map ou elemento de set for alterado, o comportamento do contêiner quebra
- Métodos que retornam
List<T>podem, dependendo do caso, retornar umArrayListmutável ouCollections.emptyList()imutável; ao modificar o segundo, ocorreUnsupportedOperationException - Existem métodos que retornam
Optional<T>mas devolvemnull(não recomendado) - Se houver
returnem um blocofinally, uma exceção ocorrida emtryoucatché ignorada e o valor retornado porfinallyprevalece - Existem bibliotecas que ignoram interrupt, e a inicialização de classes, incluindo IO, pode ser quebrada por interrupt
- Em thread pool, exceções de tasks passadas com
.submit()não são registradas em log por padrão e só podem ser verificadas via future; se o future for ignorado, não há como ver a exceção- Tarefas
scheduleAtFixedRateparam silenciosamente quando ocorre exceção
- Tarefas
- Se um literal numérico começa com 0, ele é tratado como octal (
0123→ 83) - O depurador chama
.toString()de variáveis locais, etoString()em algumas classes tem efeitos colaterais, então o comportamento do código pode mudar durante a depuração (pode ser desativado na IDE)
Golang
append()reutiliza memória quando há folga de capacity; ao fazer append em um subslice, é possível sobrescrever até a memória do paideferé executado quando a função retorna, não quando o escopo do bloco terminadefercaptura variáveis mutáveis- Sobre
nil- nil slice e empty slice são diferentes
- string não pode ser nil, só existe string vazia
- nil map permite leitura, mas não escrita
- comportamento peculiar de nil em interface: se o data pointer é null mas a type info não é null, então não é igual a
nil
- Dead wait: existem casos reais desse tipo de bug de concorrência em Go
- Existem vários tipos de timeout, tratados em detalhe em net/http
C/C++
- Ao armazenar ponteiros para elementos de
std::vector, se o vector crescer pode ocorrer realocação, invalidando os ponteiros - Um
std::stringcriado a partir de uma string literal pode ser um objeto temporário; chamarc_str()nesse caso é arriscado - Modificar um contêiner durante a iteração pode invalidar iterators
std::removenão remove de fato os elementos, apenas os reorganiza; para remover é preciso usarerase- Se um literal numérico começa com 0, ele é tratado como octal (
0123→ 83) - Undefined behavior (UB): durante a otimização, UB pode ser alterado livremente, então depender disso é perigoso
- Acesso a memória não inicializada é UB
- Ao converter
char*para ponteiro de struct, acessar antes do início da vida útil do objeto é UB; recomenda-se inicializar commemcpy - Acesso inválido à memória (como ponteiro nulo) é UB
- Overflow/underflow de inteiro é UB (tipos unsigned podem sofrer underflow abaixo de 0)
- Aliasing: se ponteiros de tipos diferentes referenciam a mesma memória, pode ocorrer UB pela strict aliasing rule
- Exceções: 1) tipos em relação de herança 2) conversão para
char*,unsigned char*,std::byte*(a conversão inversa não se aplica) - Para conversão forçada, recomenda-se
memcpyoustd::bit_cast
- Exceções: 1) tipos em relação de herança 2) conversão para
- Acesso a memória não alinhada é UB
- Alinhamento de memória
- Inteiros de 64 bits devem estar em endereços divisíveis por 8
- Em ARM, acesso não alinhado pode causar crash
- Interpretar diretamente um buffer de bytes como struct pode gerar problemas de alinhamento
- O alinhamento pode criar padding em structs e desperdiçar memória
- Algumas instruções SIMD (como AVX) só conseguem processar dados alinhados, normalmente exigindo alinhamento de 32 bytes
Python
- Argumentos padrão de função não são recriados a cada chamada; o valor inicial fica armazenado
SQL Databases
-
Tratamento de Null
x = nullnão funciona; deve-se usarx is null- Null não é igual a si mesmo (semelhante a NaN)
- Índices unique permitem Null duplicado (exceto no Microsoft SQL Server)
- Em
select distinct, a forma de tratar Null varia conforme o banco count(x)ecount(distinct x)ignoram linhas com valor Null
-
Comportamento geral
- Conversão implícita de datas pode depender de timezone
- Join complexo + distinct pode ser mais lento do que consulta aninhada
- No MySQL(InnoDB), se um campo string não estiver em
utf8mb4, inserir caracteres UTF-8 de 4 bytes causará erro - O MySQL(InnoDB) por padrão não diferencia maiúsculas de minúsculas
- O MySQL(InnoDB) permite conversão implícita:
select '123abc' + 1;→ 124 - Gap lock no MySQL(InnoDB) pode causar deadlock
- No MySQL(InnoDB), quando
group bye as colunas deselectnão batem, o resultado pode ser não determinístico - No SQLite, se não estiver em modo
strict, o tipo do campo tem pouca importância - Foreign key pode gerar locks implícitos e causar deadlock
- O locking pode quebrar o isolamento repeatable read dependendo do banco
- Bancos SQL distribuídos podem não oferecer suporte a locking ou ter comportamentos peculiares (varia conforme o banco)
-
Desempenho/operação
- O problema de N+1 query não aparece no slow query log porque cada query individual é rápida
- Transações de longa duração podem causar problemas de lock etc. → recomenda-se encerrá-las rapidamente
- Casos de lock na tabela inteira
- No MySQL 8.0+, ao adicionar unique index/foreign key, na maioria dos casos o processamento concorrente é possível
- Versões antigas do MySQL podem causar lock da tabela inteira
- Se
mysqldumpnão usar a opção--single-transaction, ocorre read lock na tabela inteira - No PostgreSQL,
create unique indexoualter table ... add foreign keycausam read lock na tabela inteira- Como evitar: usar
create unique index concurrently - Para foreign key, usar
... not valide depoisvalidate constraint
- Como evitar: usar
-
Consultas de intervalo
- Intervalos que não se sobrepõem:
- A condição simples
p >= start and p <= endé ineficiente (mesmo com índice composto) - Forma eficiente:
(apenas o índice da coluna start é necessário)select * from (select ... from ranges where start <= p order by start desc limit 1) where end >= p
- A condição simples
- Intervalos que podem se sobrepor:
- Com um índice B-tree comum, é ineficiente
- Recomenda-se spatial index no MySQL e GiST no PostgreSQL
- Intervalos que não se sobrepõem:
Concurrency and Parallelism
-
volatile
volatilenão substitui lock nem fornece atomicidade- Dados protegidos por lock não precisam de
volatile(o lock garante memory order) - C/C++:
volatilesó impede algumas otimizações; não adiciona memory barrier - Java: acesso a
volatilefornece sequentially-consistent ordering (quando necessário, a JVM insere memory barrier) - C#: acesso a
volatilefornece release-acquire ordering (quando necessário, o CLR insere memory barrier) - Pode evitar otimizações incorretas relacionadas à reordenação de leitura/escrita de memória
-
TOCTOU (Time-of-check to time-of-use) problema
-
Tratamento de restrições na camada de aplicação em bancos SQL
- Quando restrições que não podem ser expressas com um simples unique index (ex.: unicidade entre duas tabelas, unicidade condicional, unicidade dentro de um período) são impostas pela aplicação:
- MySQL(InnoDB): no nível repeatable read, fazer
select ... for updateantes do insert e, se houver índice na coluna única, isso funciona graças ao gap lock (mas gap lock pode causar deadlock sob alta carga → é preciso detecção de deadlock e retry) - PostgreSQL: no nível repeatable read, a mesma lógica é insuficiente em cenários concorrentes (problema de write skew)
- Soluções:
- usar nível de isolamento serializable
- usar restrições do banco em vez da aplicação
- unicidade condicional → partial unique index
- unicidade entre duas tabelas → inserir dados duplicados em uma tabela separada e aplicar unique index
- exclusividade por período → range type + exclude constraint
- Soluções:
- MySQL(InnoDB): no nível repeatable read, fazer
- Quando restrições que não podem ser expressas com um simples unique index (ex.: unicidade entre duas tabelas, unicidade condicional, unicidade dentro de um período) são impostas pela aplicação:
-
Contagem atômica de referências
- Se muitas threads alteram com frequência o mesmo contador, como em
Arceshared_ptr, pode haver queda de desempenho
- Se muitas threads alteram com frequência o mesmo contador, como em
-
Read-write lock
- Algumas implementações não suportam upgrade de read lock para write lock
- Tentar obter write lock enquanto se mantém um read lock pode causar deadlock
Comum em muitas linguagens
- Falta de verificação de Null/None/nil é uma causa comum de erros
- Ao modificar um contêiner durante um loop, pode ocorrer corrida de dados em thread única
- Erro ao compartilhar dados mutáveis: ex.) em Python,
[[0] * 10] * 10não cria corretamente um array 2D (low + high) / 2pode causar overflow → a forma segura élow + (high - low) / 2- Avaliação de curto-circuito (short circuit):
a() || b()não executa b se a for true;a() && b()não executa b se a for false - O padrão do profiler inclui apenas CPU time → esperas de DB etc. não aparecem no flamegraph, o que pode gerar interpretações erradas
- O dialeto de expressões regulares varia entre linguagens → uma regex que funciona em JS pode não funcionar em Java
Linux and bash
- Depois de mudar de diretório,
pwdmostra o caminho original; o caminho real é mostrado porpwd -P cmd > file 2>&1→ stdout+stderr vão para o arquivo;cmd 2>&1 > file→ só stdout vai para o arquivo, stderr permanece como está- Nomes de arquivo diferenciam maiúsculas de minúsculas (diferente do Windows)
- Arquivos executáveis têm um sistema de capabilities (
getcappara verificar) - Risco com variável unset: se
DIRestiver unset,rm -rf $DIR/pode virarrm -rf /→ dá para evitar comset -u - Aplicação do ambiente: para aplicar um script no shell atual, use
source script.sh→ para aplicar permanentemente, adicione em~/.bashrc - O Bash faz cache de comandos: ao mover arquivos dentro de
$PATH, pode ocorrerENOENT→ atualize o cache comhash -r - Ao usar variáveis sem aspas, quebras de linha são tratadas como espaços
set -e: encerra o script imediatamente em caso de erro, mas não funciona dentro de condicionais (||,&&,if)- Conflito entre livenessProbe do K8s e debugger: um debugger com breakpoint pode parar o app inteiro e fazer o health check falhar → o Pod pode ser encerrado
React
- Modificar state diretamente no código de renderização
- Usar Hook dentro de if/loop → violação das regras
- Omitir valores necessários no dependency array do
useEffect - Omitir o código de clean up no
useEffect - Armadilha de closure: bugs causados por capturar um state antigo
- Alterar dados no lugar errado → componente impuro
- Deixar de usar
useCallback→ rerenderizações desnecessárias - Passar valores não memoizados para componentes memoizados invalida a otimização de memo
Git
-
Rebase reescreve o histórico
- depois de um rebase, um push normal gera conflito → é necessário fazer force push
- ao mudar o histórico de uma branch remota, também use
pull --rebase --force-with-leasepode, em alguns casos, evitar sobrescrever commits de outros desenvolvedores, mas se você só fizer fetch e não pull, essa proteção não funciona
-
Problema ao reverter merge
- reverter um merge tem efeito incompleto → ao fazer merge da mesma branch novamente, pode não haver mudança alguma
- solução: reverter o revert ou usar um método mais limpo (backup → reset → cherry-pick → force push)
-
Cuidados relacionados ao GitHub
- mesmo que você sobrescreva com force push após commitar um secret como chave de API, o histórico continua no GitHub
- se um repositório privado B for fork de um privado A, e A virar público, o conteúdo de B também fica público (e continua acessível mesmo após a exclusão)
-
git stash pop: se houver conflito, o stash não é removido -
.DS_Storeé criado automaticamente pelo macOS → recomenda-se adicionar**/.DS_Storeao.gitignore
Networking
- Alguns roteadores e firewalls encerram silenciosamente conexões TCP ociosas → isso pode invalidar pools de conexão de clientes HTTP e DB → solução: configurar TCP keepalive
- O resultado do
traceroutetem baixa confiabilidade → em alguns casos,tcptracerouteé mais útil - TCP slow start pode aumentar a latência → pode ser resolvido desativando
tcp_slow_start_after_idle - Problema de sticky packet no TCP: o algoritmo de Nagle atrasa o envio de pacotes → pode ser resolvido ativando
TCP_NODELAY - Ao colocar um backend atrás do Nginx, é necessário configurar a reutilização de conexões → sem isso, em ambientes de alta carga, conexões podem falhar por falta de portas internas
- O Nginx faz buffering de pacotes por padrão → isso pode causar atraso em SSE (EventSource)
- O padrão HTTP não proíbe body em requisições GET e DELETE → alguns usam body, mas muitas bibliotecas e servidores não oferecem suporte
- É possível hospedar vários sites em um único IP → a distinção é feita pelo header HTTP
Hoste pelo SNI do TLS → há sites que não funcionam com acesso direto por IP - CORS: ao fazer requisições para outra origin, o navegador bloqueia o acesso à resposta → o servidor precisa definir o header
Access-Control-Allow-Origin- configurações adicionais são necessárias ao incluir envio de cookies
- se frontend e backend estiverem no mesmo domínio e porta, não há problema de CORS
Other
-
Cuidados com YAML
- YAML é sensível a espaços →
key:valueé erro;key: valueé o correto - o código de país
NO, se usado sem aspas, pode ser interpretado comofalse - um hash de commit do Git sem aspas pode ser convertido em número
- YAML é sensível a espaços →
-
Problemas de CSV no Excel
- ao abrir um CSV, o Excel faz conversões automáticas
- conversão de data:
1/2,1-2→2-Jan - conversão imprecisa de números grandes:
12345678901234567890→12345678901234500000
- conversão de data:
- isso acontece porque o Excel trata números internamente como floating point
- há casos em que isso alterou incorretamente o nome de gene SEPT1
- ao abrir um CSV, o Excel faz conversões automáticas
Ainda não há comentários.