66 puntos por GN⁺ 2025-08-18 | Aún no hay comentarios. | Compartir por WhatsApp
  • Trampas poco intuitivas en las que suelen caer los desarrolladores: se presenta un resumen con las causas de bugs que aparecen con facilidad
  • Se abordan problemas frecuentes en distintas tecnologías como HTML, CSS, Unicode/codificación de texto, punto flotante y tiempo
  • Se enfatiza que las diferencias sutiles de sintaxis y comportamiento entre lenguajes y frameworks pueden causar malentendidos o errores
  • Se explican con ejemplos trampas que pueden aparecer en entornos reales de producción en áreas clave del backend como concurrencia, redes y bases de datos
  • A través de diversos ejemplos y enlaces de referencia, se muestran los problemas, las soluciones y mejoras para comportamientos inesperados

HTML y CSS

  • Valor predeterminado de min-width en Flexbox/Grid

    • min-width es auto por defecto
    • min-width: auto se determina por el tamaño del contenido y tiene prioridad sobre flex-shrink, overflow: hidden, width: 0, max-width: 100%
    • Recomendación: especificar min-width: 0
  • Diferencia entre horizontal y vertical en CSS

    • width: auto intenta llenar el espacio del padre, mientras que height: auto se ajusta al contenido
    • En elementos inline, inline-block y float, width: auto no se expande
    • margin: 0 auto centra horizontalmente; margin: auto 0 no permite centrar verticalmente (aunque con flex-direction: column sí es posible centrar verticalmente)
    • La fusión de márgenes solo ocurre en vertical
    • Si cambia la dirección del layout, como con writing-mode: vertical-rl, el comportamiento también se invierte
  • Block Formatting Context (BFC)

    • Se puede crear un BFC con display: flow-root (también con overflow: hidden/auto/scroll, display: table, etc., aunque con efectos secundarios)
    • Un BFC puede evitar que se superpongan márgenes verticales entre hermanos adyacentes o que el margen de un hijo se “escape” fuera del padre
    • Si un padre contiene solo hijos con float, su altura colapsa a 0 → se puede corregir con un BFC
    • Si hay border o padding, no ocurre la fusión de márgenes
  • Stacking Context

    • Condiciones que crean un nuevo stacking context
      • Propiedades de renderizado como transform, filter, perspective, mask, opacity, etc.
      • position: fixed o sticky
      • z-index especificado + posicionamiento absolute/relative
      • z-index especificado + elemento dentro de flexbox/grid
      • isolation: isolate
    • Características
      • z-index solo se aplica dentro del stacking context
      • Las coordenadas de position: absolute/fixed se basan en el ancestro posicionado más cercano
      • sticky no funciona atravesando un stacking context
      • Incluso overflow: visible se recorta por efecto del stacking context
      • background-attachment: fixed se posiciona con base en el stacking context
  • Unidades del viewport

    • En navegadores móviles, si la barra de direcciones o la barra de navegación desaparece al hacer scroll, el valor de 100vh cambia
    • Solución moderna: usar 100dvh
  • Referencia de Absolute Position

    • position: absolute no toma como referencia al padre, sino al ancestro relative/absolute o stacking context más cercano
  • Comportamiento de Blur

    • backdrop-filter: blur no toma en cuenta los elementos alrededor
  • Invalidación de float

    • Si el padre es flex o grid, el float de los hijos no tiene efecto
  • width/height en porcentaje

    • No funcionan si el tamaño del padre no está determinado de antemano (para evitar referencias circulares)
  • Características de los elementos inline

    • display: inline ignora width, height, margin-top y margin-bottom
  • Manejo de whitespace

    • Por defecto, los saltos de línea en HTML se tratan como espacios y los espacios consecutivos se reducen a uno solo
    • <pre> evita la reducción de espacios, pero tiene un comportamiento particular al inicio y al final
    • En la mayoría de los casos, los espacios al inicio o al final del contenido se ignoran, pero <a> es una excepción
    • Los espacios o saltos de línea entre inline-block se muestran como separación real (no ocurre en flex/grid)
  • text-align

    • Se aplica a la alineación de texto y elementos inline, pero no a la alineación de elementos block
  • box-sizing

    • El valor predeterminado es content-box → no incluye padding/border
    • Si se usa width: 100% junto con padding, puede desbordar el área del padre
    • Solución: box-sizing: border-box
  • Cumulative Layout Shift

    • Si no se especifican los atributos width y height en <img>, la carga tardía de la imagen puede provocar saltos de layout
    • Recomendación: especificar los atributos para evitar CLS
  • Solicitudes de red de descargas de archivos en Chrome

    • No aparecen en el panel Network de DevTools (se procesan en otra pestaña)
    • Si hace falta analizarlas, usar chrome://net-export/
  • Problemas de parsing de JavaScript dentro de HTML

    • En casos como <script>console.log('</script>')</script>, el primer </script> se interpreta como etiqueta de cierre
    • Referencia: Safe JSON in script tags

Unicode y codificación de texto

  • Code points y grapheme clusters

    • Un grapheme cluster es la “unidad de carácter” en la GUI
    • En caracteres ASCII visibles, 1 code point = 1 grapheme cluster
    • Un emoji puede ser un solo grapheme cluster compuesto por varios code points
    • En UTF-8, un code point ocupa de 1 a 4 bytes; la cantidad de bytes no coincide con la cantidad de code points
    • En UTF-16, un code point ocupa 2 o 4 bytes (surrogate pair)
    • El estándar no limita la cantidad de code points dentro de un cluster, pero las implementaciones sí suelen imponer límites por rendimiento
  • Diferencias en el comportamiento de strings según el lenguaje

    • Rust: internamente usa UTF-8 para strings, len() devuelve la cantidad de bytes, no permite indexación directa, chars().count() devuelve la cantidad de code points, valida estrictamente la validez de UTF-8
    • Golang: un string es en la práctica un arreglo de bytes, la longitud y la indexación son por bytes, normalmente usa UTF-8
    • Java, C#, JS: basados en UTF-16, miden la longitud en unidades de 2 bytes y también indexan en unidades de 2 bytes; existen surrogate pairs
    • Python: len() devuelve la cantidad de code points, y la indexación devuelve un string que contiene un code point
    • C++: std::string no impone restricciones de codificación, funciona como un vector de bytes y la longitud/indexación son por bytes
    • Entre los lenguajes mencionados, ninguno mide la longitud ni indexa por grapheme clusters
  • BOM (Byte Order Mark)

    • Algunos archivos de texto tienen BOM; por ejemplo, EF BB BF indica codificación UTF-8
    • Se usa principalmente en Windows, y el software no Windows puede no procesarlo correctamente
  • Otras consideraciones

    • Al convertir datos binarios a cadena, las partes inválidas se reemplazan por � (U+FFFD)
    • Existen confusable characters (caracteres que se ven parecidos entre sí)
    • Normalización (Normalization): por ejemplo, é puede representarse como U+00E9 (un solo code point) o U+0065+U+0301 (dos code points)
    • Existen zero-width characters e invisible characters
    • Diferencias de salto de línea: Windows usa CRLF \r\n, Linux/MacOS usa LF \n
    • Han unification: caracteres con formas ligeramente distintas según el idioma usan el mismo code point
      • La fuente renderiza correctamente incluyendo variantes por idioma
      • En internacionalización, es necesario elegir la variante de fuente correcta

Punto flotante (Floating point)

  • Propiedades de NaN

    • NaN no es igual a ningún valor, incluyendo a sí mismo (NaN == NaN siempre es false)
    • NaN != NaN siempre es true
    • El resultado de operaciones que incluyen NaN, en la mayoría de los casos, se propaga como NaN
  • Valores especiales

    • Existen +Inf y -Inf, y son distintos de NaN
    • -0.0 es un valor distinto de +0.0
      • En comparaciones son iguales, pero en algunos cálculos se comportan distinto
      • Ejemplo: 1.0 / +0.0 == +Inf, 1.0 / -0.0 == -Inf
  • Compatibilidad con JSON

    • El estándar JSON no permite NaN ni Inf
      • En JS, JSON.stringify convierte NaN e Inf a null
      • En Python, json.dumps(...) imprime NaN e Infinity tal cual (violando el estándar)
        • Si se usa la opción allow_nan=False, se produce ValueError cuando hay NaN/Inf
      • En Golang, json.Marshal devuelve error si existen NaN/Inf
  • Problemas de precisión

    • La comparación directa de punto flotante puede fallar → se recomienda una forma como abs(a - b) < ε
    • JS trata todos los números como punto flotante
      • El rango seguro de enteros es -(2^53 - 1) ~ 2^53 - 1
      • Fuera de ese rango, la representación de enteros es imprecisa
      • Se recomienda usar BigInt para enteros grandes
      • Si JSON incluye enteros fuera del rango seguro, el valor resultante de JSON.parse puede ser impreciso
      • Los timestamps en milisegundos son seguros hasta el año 287,396; en nanosegundos aparecen problemas
  • No aplicación de leyes algebraicas

    • Según el orden de las operaciones, por pérdida de precisión, la asociatividad y la distributividad no se cumplen estrictamente
    • Las operaciones paralelas (multiplicación de matrices, sumas, etc.) pueden producir resultados no deterministas
  • Rendimiento

    • La división es mucho más lenta que la multiplicación
    • Si se divide varias veces por el mismo número, se puede optimizar calculando primero su recíproco y multiplicando
  • Diferencias según el hardware

    • Compatibilidad con FMA (Fused Multiply-Add): algunos hardware hacen cálculos intermedios con mayor precisión
    • Manejo del subnormal range: el hardware moderno lo soporta, pero algunos equipos antiguos lo tratan como 0
    • Diferencias en los modos de redondeo
      • Existen RNTE (redondeo al par más cercano), RTZ (truncamiento hacia 0), etc.
      • En x86/ARM se pueden configurar como estado mutable local al hilo
      • En GPU, el modo de redondeo varía según la instrucción
    • Diferencias en el comportamiento de funciones matemáticas como trigonométricas y logaritmos
    • x86 tiene FPU legacy de 80 bits y per-core rounding mode → no se recomienda usarlo
    • Además de esto, varios factores pueden hacer que los resultados de punto flotante difieran según el hardware
  • Métodos para mejorar la precisión

    • Construir un grafo de cálculo poco profundo (reducir cadenas continuas de multiplicaciones)
    • Evitar casos donde los valores intermedios sean extremadamente grandes o pequeños
    • Aprovechar operaciones de hardware como FMA

Tiempo (Time)

  • Segundo intercalar (Leap second)

    • El timestamp Unix ignora los segundos intercalares
    • Cuando ocurre un segundo intercalar, el tiempo puede alargarse o acortarse en el tramo cercano (Leap smear)
  • Zona horaria (Time zone)

    • UTC y el timestamp Unix son comunes en todo el mundo
    • La hora legible para personas depende de la zona horaria local
    • Se recomienda guardar timestamps en la DB y convertirlos en la UI
  • Horario de verano (DST)

    • En algunas regiones el reloj se ajusta una hora durante el verano
  • Sincronización NTP

    • Durante la sincronización puede ocurrir que el tiempo "retroceda"
  • Configuración de zona horaria del servidor

    • Se recomienda configurar el servidor en UTC
    • En sistemas distribuidos, tener zonas horarias distintas por nodo puede causar problemas
    • Después de cambiar la zona horaria del sistema, es necesario reconfigurar o reiniciar la DB
  • Reloj de hardware vs reloj del sistema

    • El reloj de hardware no tiene concepto de zona horaria
    • Linux: trata el reloj de hardware como UTC
    • Windows: trata el reloj de hardware como hora local

Java

  • == compara referencias de objetos; para comparar el contenido del objeto hay que usar .equals
  • Si no se sobrescriben equals y hashcode, en map/set la identidad del objeto se evalúa por referencia
  • Si se modifica el contenido de un objeto usado como key de un map o como elemento de un set, el comportamiento del contenedor se rompe
  • Un método que devuelve List<T> puede retornar, según el caso, un ArrayList mutable o un Collections.emptyList() inmutable; si se modifica este último, ocurre UnsupportedOperationException
  • Existen métodos que devuelven Optional<T> pero retornan null (no recomendado)
  • Si se hace return en un bloque finally, una excepción ocurrida en try o catch se ignora y se aplica el valor de retorno de finally
  • Existen librerías que ignoran interrupt; el proceso de inicialización de clases, incluyendo IO, puede romperse por un interrupt
  • En un thread pool, las excepciones de una tarea enviada con .submit() no se imprimen en el log por defecto y solo pueden verificarse mediante el future; si se ignora el future, no hay forma de ver la excepción
    • Las tareas de scheduleAtFixedRate se detienen silenciosamente si ocurre una excepción
  • Si un literal numérico empieza con 0, se trata como octal (0123 → 83)
  • El debugger llama a .toString() de las variables locales; algunas clases tienen efectos secundarios en toString(), así que el comportamiento del código puede cambiar durante la depuración (se puede desactivar en el IDE)

Golang

  • append() reutiliza memoria cuando hay capacidad disponible; al hacer append sobre un subslice, incluso puede sobrescribir la memoria padre
  • defer se ejecuta al retornar de la función, no al salir del scope del bloque
  • defer captura variables mutables
  • Sobre nil
    • Un nil slice y un empty slice son distintos
    • Un string no puede ser nil; solo existe la cadena vacía
    • Un nil map permite lectura pero no escritura
    • Comportamiento particular de interface nil: si el data pointer es null pero la type info no es null, no es igual a nil
  • Dead wait: existen casos reales de bugs de concurrencia en Go
  • Hay varios tipos de timeout, tratados en detalle en net/http

C/C++

  • Si guardas un puntero a un elemento de std::vector y luego el vector crece, puede haber una reasignación y el puntero queda invalidado
  • Un std::string creado a partir de una cadena literal puede ser un objeto temporal; llamar a c_str() puede ser riesgoso
  • Si modificas un contenedor mientras iteras sobre él, se invalidan los iteradores
  • std::remove no elimina realmente; solo reordena los elementos, para borrar hace falta erase
  • Si un literal numérico empieza con 0, se interpreta como octal (0123 → 83)
  • Undefined behavior (UB): durante la optimización, el UB puede transformarse libremente, así que es peligroso depender de él
    • Acceder a memoria no inicializada es UB
    • Convertir char* a un puntero a struct y acceder antes de que comience la vida del objeto es UB; se recomienda inicializar con memcpy
    • El acceso inválido a memoria (como un puntero null) es UB
    • El overflow/underflow de enteros es UB (en unsigned puede haber underflow por debajo de 0)
    • Aliasing: si punteros de tipos distintos referencian la misma memoria, puede producirse UB por la strict aliasing rule
      • Excepciones: 1) tipos con relación de herencia 2) conversiones a char*, unsigned char*, std::byte* (la conversión inversa no aplica)
      • Para conversiones forzadas se recomienda memcpy o std::bit_cast
    • El acceso a memoria desalineada es UB
  • Alineación de memoria
    • Los enteros de 64 bits deben estar en direcciones divisibles entre 8
    • En ARM, el acceso desalineado puede provocar un crash
    • Interpretar directamente un buffer de bytes como una struct puede causar problemas de alineación
    • La alineación puede introducir padding en una struct y desperdiciar memoria
    • Algunas instrucciones SIMD (como AVX) solo pueden procesar datos alineados; normalmente requieren alineación de 32 bytes

Python

  • Los argumentos por defecto de una función no se crean de nuevo en cada llamada; se conserva el valor inicial

SQL Databases

  • Manejo de Null

    • x = null no funciona; hay que usar x is null
    • Null no es igual ni a sí mismo (similar a NaN)
    • Un unique index permite valores Null duplicados (excepto en Microsoft SQL Server)
    • En select distinct, la forma de tratar Null varía según la base de datos
    • count(x) y count(distinct x) ignoran las filas con valores Null
  • Comportamiento general

    • La conversión implícita de fechas puede depender de la timezone
    • Un join complejo + distinct puede ser más lento que una consulta anidada
    • En MySQL(InnoDB), si un campo string no es utf8mb4, insertar caracteres UTF-8 de 4 bytes produce error
    • MySQL(InnoDB) por defecto no distingue mayúsculas de minúsculas
    • MySQL(InnoDB) permite conversión implícita: select '123abc' + 1; → 124
    • El gap lock de MySQL(InnoDB) puede provocar deadlock
    • En MySQL(InnoDB), si group by y las columnas de select no coinciden, puede devolver resultados no deterministas
    • En SQLite, si no está en modo strict, el tipo del campo importa poco
    • Las foreign keys pueden generar locks implícitos y provocar deadlocks
    • El locking puede romper repeatable read isolation según la base de datos
    • Las bases de datos SQL distribuidas pueden no soportar locking o tener comportamientos particulares (depende de cada DB)
  • Rendimiento/operación

    • El problema de N+1 query no aparece en el slow query log porque cada consulta individual es rápida
    • Las transacciones de larga duración pueden causar problemas de locks, etc. → se recomienda terminarlas rápido
    • Casos de lock de tabla completa
      • En MySQL 8.0+, al agregar un unique index/foreign key normalmente se puede procesar de forma concurrente
      • En versiones antiguas de MySQL puede ocurrir un lock de tabla completa
      • Si mysqldump no lleva la opción --single-transaction, hace un read lock de toda la tabla
      • En PostgreSQL, create unique index o alter table ... add foreign key provocan un read lock de toda la tabla
        • Cómo evitarlo: usar create unique index concurrently
        • Para foreign key: usar ... not valid y luego validate constraint
  • Consultas por rango

    • Rangos no superpuestos:
      • La condición simple p >= start and p <= end es ineficiente (incluso con un índice compuesto)
      • Forma eficiente:
        select *   
        from (select ... from ranges where start <= p order by start desc limit 1)   
        where end >= p  
        
        (solo hace falta un índice en la columna start)
    • Rangos que pueden superponerse:
      • Con un índice B-tree normal es ineficiente
      • En MySQL se recomienda spatial index; en PostgreSQL, GiST

Concurrency and Parallelism

  • volatile

    • volatile no puede reemplazar un lock ni garantiza atomicity
    • Los datos protegidos por lock no necesitan volatile (el lock garantiza el memory order)
    • C/C++: volatile solo evita algunas optimizaciones; no agrega memory barriers
    • Java: el acceso volatile ofrece sequentially-consistent ordering (si hace falta, la JVM inserta memory barriers)
    • C#: el acceso volatile ofrece release-acquire ordering (si hace falta, el CLR inserta memory barriers)
    • Puede evitar optimizaciones incorrectas relacionadas con el reordenamiento de lecturas/escrituras de memoria
  • Problema TOCTOU (Time-of-check to time-of-use)

  • Manejo de restricciones en la capa de aplicación con SQL DB

    • Cuando se fuerzan en la aplicación restricciones que no pueden expresarse con un simple unique index (por ejemplo, unicidad entre dos tablas, unicidad condicional o unicidad dentro de un período):
      • MySQL(InnoDB): en nivel repeatable read, hacer select ... for update y luego insert; si la columna única tiene índice, funciona gracias al gap lock (aunque el gap lock puede provocar deadlocks con alta carga → hace falta detección de deadlocks y retry)
      • PostgreSQL: con la misma lógica en nivel repeatable read no es suficiente en escenarios concurrentes (problema de write skew)
        • Soluciones:
          • usar el nivel de aislamiento serializable
          • usar restricciones de DB en vez de la aplicación
            • unicidad condicional → partial unique index
            • unicidad entre dos tablas → insertar datos duplicados en una tabla separada y aplicar unique index
            • exclusividad por período → range type + exclude constraint
  • Conteo de referencias atómico

    • Si muchos hilos cambian con frecuencia el mismo contador, como en Arc o shared_ptr, el rendimiento se degrada
  • Read-write lock

    • Algunas implementaciones no permiten hacer upgrade de read lock a write lock
    • Intentar tomar un write lock mientras ya se posee un read lock puede provocar deadlock

Common in many languages

  • Omitir la verificación de null/None/nil es una causa común de errores
  • Al modificar un contenedor dentro de un bucle, puede producirse una condición de carrera de datos en un solo hilo
  • Error al compartir datos mutables: p. ej., en Python [[0] * 10] * 10 no crea correctamente un arreglo 2D
  • (low + high) / 2 puede causar overflow → la forma segura es low + (high - low) / 2
  • Evaluación de cortocircuito (short circuit): a() || b() no ejecuta b si a es true, a() && b() no ejecuta b si a es false
  • El valor predeterminado del profiler solo incluye CPU time → esperas de DB, etc., no aparecen en el flamegraph y pueden llevar a interpretaciones erróneas
  • El dialecto de expresiones regulares varía según el lenguaje → una regex que funciona en JS puede no funcionar en Java

Linux and bash

  • Después de cambiar de directorio, pwd muestra la ruta original; la ruta real se obtiene con pwd -P
  • cmd > file 2>&1 → stdout+stderr ambos al archivo, cmd 2>&1 > file → solo stdout al archivo, stderr queda igual
  • Los nombres de archivo distinguen mayúsculas y minúsculas (a diferencia de Windows)
  • Los ejecutables cuentan con un sistema de capabilities (se puede verificar con getcap)
  • Riesgo de variables unset: si DIR no está definido, rm -rf $DIR/ puede terminar ejecutando rm -rf / → se puede prevenir con set -u
  • Aplicar el entorno: para aplicar un script al shell actual, usar source script.sh → para aplicarlo de forma permanente, agregarlo a ~/.bashrc
  • Bash hace caché de comandos: si se mueve un archivo dentro de $PATH, puede aparecer ENOENT → actualizar la caché con hash -r
  • Si se usa una variable sin comillas, los saltos de línea se tratan como espacios
  • set -e: termina el script de inmediato ante errores, pero no funciona dentro de condicionales (||, &&, if)
  • Conflicto entre K8s livenessProbe y el depurador: un depurador con breakpoints puede detener toda la app y hacer que falle la respuesta al health check → el Pod puede terminarse

React

  • Modificar state directamente dentro del código de renderizado
  • Usar Hooks dentro de if/loop → viola las reglas
  • Omitir valores necesarios en el dependency array de useEffect
  • Omitir código de limpieza (clean up) en useEffect
  • Trampa de closure: se captura un state antiguo y eso provoca bugs
  • Modificar datos en el lugar incorrecto → componente impuro
  • Omitir useCallback → provoca rerenderizados innecesarios
  • Pasar valores no memorizados a componentes memorizados invalida la optimización de memo

Git

  • Rebase reescribe el historial

    • Después de un rebase, un push normal genera conflicto → es necesario hacer force push
    • Si cambia el historial de la rama remota, al hacer pull también se debe usar --rebase
    • --force-with-lease puede evitar en algunos casos sobrescribir commits de otros desarrolladores, pero si solo se hace fetch y no pull, no brinda esa protección
  • Problema con revert de merge

    • Hacer revert de un merge no revierte completamente sus efectos → al volver a hacer merge de la misma rama no habrá cambios
    • Solución: hacer revert del revert o usar un método más limpio (backup → reset → cherry-pick → force push)
  • Precauciones relacionadas con GitHub

    • Aunque se sobrescriba con force push un commit que contiene secretos como API keys, GitHub conserva el registro
    • Si B es un fork privado de un repo privado A, y A se vuelve público, el contenido de B también queda expuesto (puede seguir siendo accesible incluso después de eliminarlo)
  • git stash pop: si ocurre un conflicto, el stash no se elimina

  • .DS_Store lo genera macOS automáticamente → se recomienda agregar **/.DS_Store a .gitignore

Networking

  • Algunos routers y firewalls cierran silenciosamente conexiones TCP inactivas → pueden invalidar los pools de conexiones de clientes HTTP o DB → solución: configurar TCP keepalive
  • Los resultados de traceroute tienen baja confiabilidad → en algunos casos tcptraceroute puede ser más útil
  • TCP slow start puede aumentar la latencia → se puede resolver desactivando tcp_slow_start_after_idle
  • Problema de sticky packets en TCP: el algoritmo de Nagle retrasa el envío de paquetes → se puede resolver activando TCP_NODELAY
  • Al colocar un backend detrás de Nginx, hay que configurar la reutilización de conexiones → si no se configura, en alta carga pueden fallar conexiones por falta de puertos internos
  • Nginx hace buffering de paquetes por defecto → puede provocar retrasos en SSE (EventSource)
  • El estándar HTTP no prohíbe body en solicitudes GET o DELETE → algunos lo usan, pero muchas librerías y servidores no lo soportan
  • Se pueden alojar varios sitios web en una sola IP → la distinción la hacen el header HTTP Host y el SNI de TLS → hay sitios a los que no se puede acceder solo con la IP
  • CORS: cuando una solicitud se hace a otro origin, el navegador bloquea el acceso a la respuesta → el servidor debe configurar el header Access-Control-Allow-Origin
    • Si también se envían cookies, se requiere configuración adicional
    • Si frontend y backend usan el mismo dominio y puerto, no hay problema de CORS

Other

  • Precauciones con YAML

    • YAML es sensible a los espacioskey:value es un error, key: value es lo correcto
    • Si el código de país NO se escribe sin comillas, puede interpretarse como false
    • Si un hash de commit de Git se escribe sin comillas, puede convertirse en número
  • Problemas de Excel con CSV

    • Al abrir un CSV, Excel hace conversiones automáticas
      • Conversión de fechas: 1/2, 1-22-Jan
      • Conversión inexacta de números grandes: 1234567890123456789012345678901234500000
    • La causa es que Excel maneja internamente los números como floating point
    • Existe un caso en el que el nombre de un gen, SEPT1, fue modificado incorrectamente por este problema

Aún no hay comentarios.

Aún no hay comentarios.