Skip to content

Latest commit

 

History

History
191 lines (143 loc) · 16.8 KB

speech.md

File metadata and controls

191 lines (143 loc) · 16.8 KB

� Interview Preparation - Java Software Engineer (Mercado Libre)

🎤 Personal Speech / Introduction

"Soy desarrollador backend con una base sólida en PHP, pero en los últimos años me orienté fuertemente a arquitecturas de microservicios y al ecosistema Java.

*Arranqué mi carrera en el Ejército Argentino, desarrollando un sistema de gestión crítico para operaciones y logística (movimientos, geolocalización, personal). Trabajamos con PHP 8.0 y Laravel 8 como base, y MySQL como sistema de persistencia. Trabajé bastante en la versión web, pero después me aboqué completamente a hacer la APIs REST para la integración con la aplicación móvil que estaba hecha en flutter. Ahí adquirí conocimiento de buenas practicas, SOLID y di mis primeros pasos en arquitectura y patrones de diseño.

Después pasé a DeCampoACampo, donde trabajé directamente en la migración de un monolito a microservicios usando PHP 8.1 con Hyperf. Utilizabamos arquitectura basada en API Gateway, cada microservicio estaba hecho con arquitectura en capas, y patrones de diseño como service layer y repository. Teniamos caching con Redis, mensajería y mails con RabbitMQ y CI/CD con Jenkins. Y todo el entorno de desarrollo con Docker. Fue mi primer contacto real con una arquitectura distribuida, y terminé siendo parte del equipo core de la migración.

Después pasé al ICBC Mall, donde trabajé con PHP, Prestashop, MySQL con configuración maestro–esclavo, monitoreo con New Relic y CI/CD con GitLab.

Despues se abrió una oportunidad de pasar a un equipo nuevo de ICBC que era el de prevención de fraude, yo ya tenia experiencia con Java y microservicios, así que aproveché, me dieron 2 sprints de capacitacion y tenia que hacer una api utilizando Java 21 con spring boot, alguna arquitectura que nos sea comoda, patrones de diseño, Oracle SQL, JUnit y Mockito. Presenté la api, dije el porque de cada cosa y actualmente trabajo en el área de Prevención de Fraudes, ya 100% en Java 21 y microservicios. Dentro del banco usamos AppFlow, una plataforma similar a Fury, donde modelamos Endpoints, DTOs de entrada y salida y nos conectamos con otros servicios del banco. Trabajo con Spring, Kafka para eventos, Hazelcast5 como cache distribuido, Oracle SQL como base de datos y JUnit 5 y Mockito para test. Tenemos 4 ambientes, dev, fbd, qat y prod y utilizamos gitlab para pasar de un ambiente a otro mediante los pipelines


🌟 1. STAR Method Response: Complex Project

Case: Migration from Monolith to Microservices at DeCampoACampo

S — Situation

"En uno de mis trabajos anteriores, en DeCampoACampo, teníamos un monolito grande en PHP que llevaba varios años en producción. El sistema era crítico para operaciones de compra/venta de ganado, pero ya tenía problemas de rendimiento, escalabilidad y mantenibilidad: consultas enormes, una base de datos gigante compartida y despliegues muy riesgosos. Cualquier cambio pequeño podía romper otras partes del sistema."

T — Task

"Mi tarea fue participar en la migración a una arquitectura de microservicios. Al principio entré dando soporte, pero al mes ya estaba trabajando directamente en la extracción de funcionalidades del monolito hacia servicios independientes."

A — Action

"Las principales decisiones técnicas que tomamos fueron:

  • Tecnología: Adoptamos Hyperf sobre Swoole por su capacidad de correr PHP de forma asincrónica, similar a un servidor permanente.
  • Arquitectura: Diseñamos una arquitectura con API Gateway y microservicios con bases de datos separadas (database per service) para reducir el acoplamiento.
  • Performance: Implementé Redis como capa de cacheo para consultas masivas, con triggers en MySQL para invalidación controlada del cache.
  • Desacoplamiento: Usamos RabbitMQ para tareas como envío de correos, permitiendo manejar esos procesos de forma asincrónica y resiliente.
  • DevOps: Definimos un pipeline de CI/CD con Jenkins y reforzamos la calidad con PHPUnit, phpstan y migraciones controladas con nasgrate.
  • Diseño: Internamente seguimos una arquitectura en capas y principios de diseño para mantener código claro, predecible y fácil de extender."

R — Result

"La migración nos permitió realizar despliegues independientes, reducir significativamente el impacto de cambios, mejorar tiempos de respuesta en las consultas más pesadas y disminuir la deuda técnica del proyecto. Además, el sistema pasó a ser más resiliente y mucho más fácil de escalar. Para mí fue clave porque fue mi primer proyecto grande en arquitectura distribuida y me formó para el trabajo que hago hoy en Java."


� 2. "What was your biggest technical challenge?"

Note: This is a strong answer for Mercado Libre as it mixes fraud, microservices, events, caching, and Java.

Response: "Mi mayor desafío técnico lo tuve en mi rol actual en el equipo de Prevención de Fraudes de ICBC. Teníamos un caso donde ciertas reglas antifraude requerían consultar mucha información en distintos servicios internos del banco: datos de tarjetas, perfiles de cliente, límites, comportamiento transaccional, historial, etc. El problema era que en momentos de alto tráfico las validaciones se volvían lentas y generaban picos de latencia que impactaban en otros servicios.

El desafío era mejorar la performance sin comprometer exactitud ni la lógica de negocio. Lo abordé en tres frentes:

  1. Caching distribuido con Hazelcast 5: Identifiqué qué información podía cachearse sin riesgo (datos estáticos o semi-estáticos) y diseñé un esquema de expiraciones y claves consistente. El acceso pasó a ser in-memory distribuido en lugar de golpear Oracle para cada validación.
  2. Asincronía con Kafka: Parte de la información que no era crítica en tiempo real pasó a procesarse vía eventos. Un servicio publicaba en un topic y otro lo consumía para precalcular información, reduciendo la carga en el momento de la validación online.
  3. Optimización de consultas en Oracle: Trabajé con el equipo de DBAs para optimizar índices y revisar planes de ejecución. Algunas consultas las reescribimos para evitar full table scans y mejorar el throughput general.

Resultado: Al combinar estas tres estrategias, logramos bajar la latencia de la validación de fraude de cientos de milisegundos a tiempos estables y predecibles, incluso bajo carga alta. Además, redujimos el impacto sobre la base y aumentamos la resiliencia del flujo completo."


📌 General Technical Questions

1. “¿Qué es un microservicio y qué ventajas/desventajas tiene?”

"Un microservicio es una unidad pequeña y autónoma que expone una funcionalidad específica y que se despliega de manera independiente. En mi trabajo actual, por ejemplo, tenemos microservicios antifraude que solo hacen validaciones puntuales y otros que consultan datos específicos del cliente."

  • Ventajas:
    • Despliegues independientes.
    • Escalabilidad por componente.
    • Menor acoplamiento.
    • Facilidad para elegir tecnologías diferentes si es necesario.
  • Desventajas:
    • Complejidad en la comunicación entre servicios.
    • Necesidad de observabilidad (logs, tracing, métricas).
    • Más infraestructura: gateway, mensajería, cache distribuido, orquestación.

2. “¿Cómo manejarías la comunicación entre microservicios?”

"En general uso dos estilos:

  • Síncrono: Cuando la respuesta es necesaria en el momento (ej. validaciones antifraude online). Usamos HTTP vía el cliente que genera AppFlow.
  • Asíncrono: Cuando quiero desacoplar tiempos (ej. eventos de fraude, auditoría o precálculo de datos). Para eso usamos Kafka.

La mezcla de ambos es clave: síncrono para la experiencia de usuario y asíncrono para lograr resiliencia y throughput."

3. “¿Qué diferencias hay entre concurrencia y paralelismo?”

"Concurrencia es manejar múltiples tareas progresando al mismo tiempo, pero no necesariamente ejecutándose simultáneamente. Paralelismo es cuando esas tareas realmente corren en paralelo en múltiples núcleos.

En mi día a día lo veo cuando usamos Kafka: el procesamiento es concurrente, pero si escalo el número de consumers, ya estoy explotando paralelismo real en distintas particiones."

4. “¿Qué estrategias de caching usaste?”

"En ICBC usamos Hazelcast 5 como cache distribuido. Definimos claves consistentes, TTLs y condiciones de invalidación. Lo usamos para evitar golpear Oracle en validaciones antifraude que se repiten mucho.

También definimos qué datos son cacheables (semidinámicos: perfil básico del cliente, límites, parámetros) y cuáles no (transacciones recientes). En DeCampoACampo usé Redis para cacheo de consultas pesadas con triggers en MySQL para invalidación."

5. “¿Qué es Kafka y cuándo lo usarías?”

"Kafka es una plataforma de mensajería distribuida orientada a eventos. Lo usaría cuando necesito desacoplar servicios, manejar grandes volúmenes de datos o garantizar procesamiento asíncrono. En Fraude lo usamos para publicar eventos y precalcular información o alimentar otros servicios sin bloquear el flujo online."

6. “¿Cómo hacés test unitarios en Java?”

"Normalmente uso JUnit 5 y Mockito. Testeo reglas de negocio, casos límite, validaciones, errores esperados y comportamiento de dependencias mockeadas.

Un buen test no depende de infraestructura real: base de datos, Kafka o Hazelcast van mockeados. Y agrego tests de mappers y DTOs porque son fuente frecuente de errores en microservicios."

7. “Explicame un patrón de diseño que uses seguido.”

"Uso mucho el patrón Service Layer, especialmente cuando sigo arquitectura en capas. Mantengo la lógica de negocio desacoplada del controlador y del repositorio. También uso DTOs y mappers para separar claramente dominio de transporte, y Factory Methods para construir objetos complejos."

8. “¿Qué es un API Gateway y para qué sirve?”

"Es un punto único de entrada para todas las requests externas. Centraliza autenticación, rate limiting, logging y enrutamiento. En DeCampoACampo lo usamos para gestionar los microservicios que exponíamos. En el banco usamos DataPower en roles similares, aunque mucho más orientado a seguridad."

9. “¿Qué es una transacción distribuida y cómo la manejarías?”

"Una transacción distribuida es cuando más de un servicio o base tiene que mantener consistencia. La solución no suele ser un commit 2-phase, sino usar eventual consistency con eventos y estrategias como outbox o compensación. En Fraude preferimos no usar transacciones distribuidas; usamos eventos por Kafka, idempotencia y estados claros."

10. “¿Cómo manejás la observabilidad en un sistema distribuido?”

"Logs estructurados, trazas y métricas. En ICBC usamos Kibana, con traceId y logs enriquecidos por request. Esto permite seguir una request a través de múltiples servicios y ambientes. Es clave para debugging real."

11. “¿Qué diferencias hay entre escalado vertical y horizontal?”

"Escalado vertical es darle más recursos a una misma máquina. Horizontal es agregar más instancias. En microservicios y Kafka casi siempre preferimos horizontal, porque aprovecha particiones, consumers y clusters distribuidos."

12. “¿Cómo evitarías problemas de concurrencia en un servicio?”

"Depende del caso. En validaciones antifraude trabajamos con idempotencia, claves únicas, caching y control del orden de los eventos. En casos más extremos usé bloqueos optimistas en bases relacionales y estrategias de retry/backoff en los consumidores."


🔥 Advanced Architecture Questions (Mercado Libre Level)

1) ¿Cómo diseñarías un sistema de alta concurrencia que tiene picos impredecibles?

"Primero desacoplaría el sistema en microservicios orientados a dominio. Para absorber picos impredecibles, usaría un enfoque event-driven: Kafka como buffer natural, consumers escalables horizontalmente y particiones que permitan paralelismo real.

Para la parte online, pondría caching distribuido (Hazelcast o Redis) para quitar presión a la base. Y aseguraría idempotencia, timeouts y circuit breakers con patterns como retry/backoff. En Prevención de Fraudes trabajamos justamente con cargas variables por horarios bancarios, y lo resolvimos con Kafka + cache distribuido + escalado horizontal de consumers."

2) ¿Qué patrones aplicarías si un microservicio falla constantemente?

  1. Circuit Breaker: Para evitar cascadas.
  2. Retry con Backoff: Y límites.
  3. Fallback: Cuando aplique (ej. usar valores cacheados).
  4. Observabilidad: Logs estructurados + métricas + tracing para encontrar la causa real.

3) ¿Cómo manejarías la integridad de datos en un sistema distribuido sin usar transacciones distribuidas?

"Usaría eventual consistency. La clave es diseñar los eventos como fuentes de verdad, usar idempotencia, correlación de mensajes y un patrón outbox si necesito garantizar que un cambio en la base genere un evento."

4) ¿Cómo decidir si un microservicio merece ser síncrono o asíncrono?

"Si la respuesta es necesaria en el flujo de usuario, debe ser síncrono. Si el trabajo puede diferirse, escalar de forma independiente o amortiguar picos, lo hago asíncrono.

Ejemplo: En Fraude la validación online es síncrona. Pero el precálculo de indicadores lo hacemos por Kafka de forma asíncrona."

5) Explicame el teorema CAP y cómo influye en una arquitectura como la de Mercado Libre.

"CAP dice que en presencia de una partición de red, solo podés elegir entre Consistencia o Disponibilidad. Ningún sistema distribuido real garantiza las tres a la vez.

Mercado Libre suele priorizar Disponibilidad y Tolerancia a particiones, permitiendo consistencia eventual. Es el mismo enfoque que usamos con Kafka + caches distribuidos: preferimos servir rápido y converger después."

6) ¿Qué es idempotencia y cómo la aplicarías en un microservicio?

"Un servicio es idempotente cuando ejecutar la misma operación más de una vez produce el mismo resultado. Es esencial en sistemas con reintentos (Kafka, APIs). En Fraude lo aplico generando claves de operación, verificando estados previos, y asegurando que no se dupliquen validaciones."

7) ¿Cómo diseñarías particionamiento para un sistema de eventos con Kafka?

"El particionado define el paralelismo. Elegiría claves que garanticen distribución uniforme pero manteniendo orden cuando importa.

Ejemplo: En Fraude, los eventos se particionan por ID de cliente o tarjeta para preservar orden en flujos sensibles, pero garantizando escalabilidad horizontal en el resto."

8) ¿Qué técnicas de resiliencia implementarías en un sistema distribuido?

  • Circuit breakers.
  • Retry con backoff exponencial.
  • Timeouts.
  • Fallbacks.
  • Bulkheads (aislar componentes).
  • Caching (para reducir presión).
  • Dead-letter queues (DLQ).

☕ Java 21 & Spring Boot Questions

9) ¿Qué mejoras relevantes trae Java 21 que uses o conozcas?

  • Virtual Threads (Project Loom): Permiten manejar miles de requests sin necesidad de pools gigantes.
  • Records: DTOs inmutables, perfectos para APIs y modelos livianos.
  • Pattern Matching: Código más expresivo.
  • Switch mejorado: Más seguro y conciso.

10) ¿Cómo estructurás un proyecto en Spring Boot siguiendo buenas prácticas?

"Suelo usar arquitectura en capas:

  • Controller
  • Service
  • Repository

Y separo dominio / aplicación / infraestructura cuando el servicio escala. Además agrego DTOs para transporte, Mappers, Configurations, Exceptions centralizadas y Tests unitarios por capa."

11) ¿Cómo gestionás la configuración entre ambientes?

"Uso perfiles de Spring (dev, test, prod). Variables de entorno para secretos. En el banco usamos AppFlow + DataPower para separar comportamientos por ambientes. Y logs estructurados con traceId para rastrear problemas en cada entorno."

12) ¿Cómo implementás seguridad en un microservicio con Spring?

"En Spring Security suelo usar filtros, validación de tokens, roles, CORS y rate limiting del lado del gateway. En ICBC, la seguridad más fuerte viene desde AppFlow y DataPower: autenticación a nivel de gateway y certificados entre servicios."

13) ¿Qué consideraciones tenés al diseñar una API REST en Java?

  • DTOs claros.
  • Validaciones con @Valid.
  • Manejo centralizado de errores.
  • Idempotencia cuando aplica.
  • Logs estructurados.
  • Versionado (/v1/…).
  • Tests unitarios con mocks.
  • Documentación (OpenAPI / Swagger).