Trampas con las que los desarrolladores deben tener cuidado
(qouteall.fun)- 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-widthen Flexbox/Gridmin-widthesautopor defectomin-width: autose determina por el tamaño del contenido y tiene prioridad sobreflex-shrink,overflow: hidden,width: 0,max-width: 100%- Recomendación: especificar
min-width: 0
-
Diferencia entre horizontal y vertical en CSS
width: autointenta llenar el espacio del padre, mientras queheight: autose ajusta al contenido- En elementos inline, inline-block y float,
width: autono se expande margin: 0 autocentra horizontalmente;margin: auto 0no permite centrar verticalmente (aunque conflex-direction: columnsí 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 conoverflow: 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
borderopadding, no ocurre la fusión de márgenes
- Se puede crear un BFC con
-
Stacking Context
- Condiciones que crean un nuevo stacking context
- Propiedades de renderizado como
transform,filter,perspective,mask,opacity, etc. position: fixedostickyz-indexespecificado + posicionamientoabsolute/relativez-indexespecificado + elemento dentro de flexbox/gridisolation: isolate
- Propiedades de renderizado como
- Características
z-indexsolo se aplica dentro del stacking context- Las coordenadas de
position: absolute/fixedse basan en el ancestro posicionado más cercano stickyno funciona atravesando un stacking context- Incluso
overflow: visiblese recorta por efecto del stacking context background-attachment: fixedse posiciona con base en el stacking context
- Condiciones que crean un nuevo 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
100vhcambia - Solución moderna: usar
100dvh
- En navegadores móviles, si la barra de direcciones o la barra de navegación desaparece al hacer scroll, el valor de
-
Referencia de Absolute Position
position: absoluteno toma como referencia al padre, sino al ancestrorelative/absoluteo stacking context más cercano
-
Comportamiento de Blur
backdrop-filter: blurno toma en cuenta los elementos alrededor
-
Invalidación de float
- Si el padre es
flexogrid, elfloatde los hijos no tiene efecto
- Si el padre es
-
width/heighten 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: inlineignorawidth,height,margin-topymargin-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-blockse 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 conpadding, puede desbordar el área del padre - Solución:
box-sizing: border-box
- El valor predeterminado es
-
Cumulative Layout Shift
- Si no se especifican los atributos
widthyheighten<img>, la carga tardía de la imagen puede provocar saltos de layout - Recomendación: especificar los atributos para evitar CLS
- Si no se especifican los atributos
-
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
- En casos como
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::stringno 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
- Rust: internamente usa UTF-8 para strings,
-
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 == NaNsiempre es false) NaN != NaNsiempre es true- El resultado de operaciones que incluyen NaN, en la mayoría de los casos, se propaga como NaN
- NaN no es igual a ningún valor, incluyendo a sí mismo (
-
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.stringifyconvierte NaN e Inf anull - En Python,
json.dumps(...)imprime NaN e Infinity tal cual (violando el estándar)- Si se usa la opción
allow_nan=False, se produceValueErrorcuando hay NaN/Inf
- Si se usa la opción
- En Golang,
json.Marshaldevuelve error si existen NaN/Inf
- En JS,
- El estándar JSON no permite NaN ni 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
BigIntpara enteros grandes - Si JSON incluye enteros fuera del rango seguro, el valor resultante de
JSON.parsepuede ser impreciso - Los timestamps en milisegundos son seguros hasta el año 287,396; en nanosegundos aparecen problemas
- El rango seguro de enteros es
- La comparación directa de punto flotante puede fallar → se recomienda una forma como
-
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
equalsyhashcode, 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, unArrayListmutable o unCollections.emptyList()inmutable; si se modifica este último, ocurreUnsupportedOperationException - Existen métodos que devuelven
Optional<T>pero retornannull(no recomendado) - Si se hace return en un bloque
finally, una excepción ocurrida entryocatchse ignora y se aplica el valor de retorno definally - 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
scheduleAtFixedRatese detienen silenciosamente si ocurre una excepción
- Las tareas de
- 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 entoString(), 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 padredeferse ejecuta al retornar de la función, no al salir del scope del bloquedefercaptura 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::vectory luego el vector crece, puede haber una reasignación y el puntero queda invalidado - Un
std::stringcreado a partir de una cadena literal puede ser un objeto temporal; llamar ac_str()puede ser riesgoso - Si modificas un contenedor mientras iteras sobre él, se invalidan los iteradores
std::removeno elimina realmente; solo reordena los elementos, para borrar hace faltaerase- 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 astructy acceder antes de que comience la vida del objeto es UB; se recomienda inicializar conmemcpy - 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
memcpyostd::bit_cast
- Excepciones: 1) tipos con relación de herencia 2) conversiones a
- 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
structpuede causar problemas de alineación - La alineación puede introducir padding en una
structy 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 = nullno funciona; hay que usarx 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)ycount(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 byy las columnas deselectno 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
mysqldumpno lleva la opción--single-transaction, hace un read lock de toda la tabla - En PostgreSQL,
create unique indexoalter table ... add foreign keyprovocan un read lock de toda la tabla- Cómo evitarlo: usar
create unique index concurrently - Para foreign key: usar
... not validy luegovalidate constraint
- Cómo evitarlo: usar
-
Consultas por rango
- Rangos no superpuestos:
- La condición simple
p >= start and p <= endes ineficiente (incluso con un índice compuesto) - Forma eficiente:
(solo hace falta un índice en la columna start)select * from (select ... from ranges where start <= p order by start desc limit 1) where end >= p
- La condición simple
- Rangos que pueden superponerse:
- Con un índice B-tree normal es ineficiente
- En MySQL se recomienda spatial index; en PostgreSQL, GiST
- Rangos no superpuestos:
Concurrency and Parallelism
-
volatile
volatileno puede reemplazar un lock ni garantiza atomicity- Los datos protegidos por lock no necesitan
volatile(el lock garantiza el memory order) - C/C++:
volatilesolo evita algunas optimizaciones; no agrega memory barriers - Java: el acceso
volatileofrece sequentially-consistent ordering (si hace falta, la JVM inserta memory barriers) - C#: el acceso
volatileofrece 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 updatey 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
- Soluciones:
- MySQL(InnoDB): en nivel repeatable read, hacer
- 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):
-
Conteo de referencias atómico
- Si muchos hilos cambian con frecuencia el mismo contador, como en
Arcoshared_ptr, el rendimiento se degrada
- Si muchos hilos cambian con frecuencia el mismo contador, como en
-
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] * 10no crea correctamente un arreglo 2D (low + high) / 2puede causar overflow → la forma segura eslow + (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,
pwdmuestra la ruta original; la ruta real se obtiene conpwd -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
DIRno está definido,rm -rf $DIR/puede terminar ejecutandorm -rf /→ se puede prevenir conset -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 aparecerENOENT→ actualizar la caché conhash -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-leasepuede 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_Storelo genera macOS automáticamente → se recomienda agregar**/.DS_Storea.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
traceroutetienen baja confiabilidad → en algunos casostcptraceroutepuede 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
Hosty 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 espacios →
key:valuees un error,key: valuees lo correcto - Si el código de país
NOse escribe sin comillas, puede interpretarse comofalse - Si un hash de commit de Git se escribe sin comillas, puede convertirse en número
- YAML es sensible a los espacios →
-
Problemas de Excel con CSV
- Al abrir un CSV, Excel hace conversiones automáticas
- Conversión de fechas:
1/2,1-2→2-Jan - Conversión inexacta de números grandes:
12345678901234567890→12345678901234500000
- Conversión de fechas:
- 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
- Al abrir un CSV, Excel hace conversiones automáticas
Aún no hay comentarios.