En la mayoría de las empresas, las entrevistas de ingeniero de software siguen un patrón conocido: una llamada con reclutamiento, una o dos rondas de programación, una ronda de diseño de sistemas para puestos de nivel medio y senior, y una ronda conductual. A continuación encontrarás 20 preguntas de entrevista para ingeniero de software con respuestas, agrupadas por ronda. Cada ejemplo de código se probó contra una versión de fuerza bruta con miles de entradas aleatorias antes de publicarlo.
Qué evalúa cada ronda
| Ronda | Formato típico | Qué están evaluando |
|---|---|---|
| Filtro con reclutamiento | 20 a 30 minutos por teléfono | Trayectoria, motivación, rango salarial, logística |
| Programación | 45 a 60 minutos en un editor compartido | Resolución de problemas, código limpio, pruebas, hablar mientras trabajas |
| Fundamentos de CS | Integrada en programación o en una ronda aparte | Si entiendes los sistemas que usas |
| Diseño de sistemas | 45 a 60 minutos en una pizarra o documento | Compromisos, escala y comunicación clara |
| Conductual | 30 a 45 minutos | Responsabilidad, colaboración, cómo manejas los fallos |
Las entrevistas para recién graduados son sobre todo de programación y conductuales. Las entrevistas senior añaden más diseño de sistemas y esperan respuestas más profundas sobre proyectos anteriores. Para la llamada con reclutamiento, consulta nuestras preguntas de entrevista telefónica.
Preguntas de programación
En cada ronda de programación, explica tu enfoque antes de escribir, indica la complejidad de tiempo y de espacio, y prueba al final con un ejemplo pequeño. Nuestra hoja de referencia de Big O explica la parte de complejidad.
1. Suma de dos números: devuelve los índices de dos números que suman un objetivo
Guarda el índice de cada número en un mapa hash. Para cada número nuevo, comprueba si su complemento ya está en el mapa.
def two_sum(nums, target):
seen = {}
for i, x in enumerate(nums):
if target - x in seen:
return [seen[target - x], i]
seen[x] = i
return []
print(two_sum([2, 7, 11, 15], 9)) # [0, 1]
O(n) de tiempo y O(n) de espacio. La versión de fuerza bruta revisa cada par en O(n²), y los entrevistadores suelen querer que la menciones primero y luego la mejores.
2. Paréntesis válidos: comprueba que cada corchete se cierre en el orden correcto
Apila los corchetes de apertura en una pila. Al encontrar un corchete de cierre, el elemento superior de la pila debe ser su apertura correspondiente.
def is_valid(s):
pairs = {")": "(", "]": "[", "}": "{"}
stack = []
for ch in s:
if ch in pairs:
if not stack or stack.pop() != pairs[ch]:
return False
else:
stack.append(ch)
return not stack
print(is_valid("([]{})"), is_valid("(]")) # True False
O(n) de tiempo y O(n) de espacio. La última línea importa: una cadena como «((» deja elementos en la pila y no es válida.
3. Fusionar intervalos superpuestos
Ordena por hora de inicio y luego amplía el último intervalo fusionado o empieza uno nuevo.
def merge_intervals(intervals):
merged = []
for start, end in sorted(intervals):
if merged and start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return merged
print(merge_intervals([[1, 3], [2, 6], [8, 10], [15, 18]]))
# [[1, 6], [8, 10], [15, 18]]
O(n log n) de tiempo por la ordenación. Pregunta si los intervalos que se tocan, como [1, 2] y [2, 3], deben fusionarse. Esta versión sí los fusiona.
4. Invertir una lista enlazada
Recorre la lista una sola vez y haz que cada nodo apunte al anterior.
class ListNode:
def __init__(self, val, next=None):
self.val = val
self.next = next
def reverse_list(head):
prev = None
while head:
head.next, prev, head = prev, head, head.next
return prev
O(n) de tiempo y O(1) de espacio extra. Si la asignación múltiple parece demasiado ingeniosa para el entrevistador, escríbela en tres líneas con una variable temporal. La claridad vale más que la brevedad.
5. Devuelve los k elementos más frecuentes
Cuenta con un mapa hash y luego toma los k conteos más grandes con un montón (heap).
from collections import Counter
import heapq
def top_k_frequent(nums, k):
counts = Counter(nums)
return [x for x, _ in heapq.nlargest(k, counts.items(), key=lambda p: p[1])]
print(top_k_frequent([1, 1, 1, 2, 2, 3], 2)) # [1, 2]
O(n log k) de tiempo. Una pregunta de seguimiento es la ordenación por cubetas según la frecuencia, que llega a O(n).
6. Diseña una caché LRU con get y put en O(1)
Necesitas búsqueda rápida y reordenar rápido según el uso reciente. Un mapa hash más una lista doblemente enlazada hacen ambas cosas. En Python, OrderedDict es exactamente esa combinación.
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.capacity = capacity
self.data = OrderedDict()
def get(self, key):
if key not in self.data:
return -1
self.data.move_to_end(key)
return self.data[key]
def put(self, key, value):
if key in self.data:
self.data.move_to_end(key)
self.data[key] = value
if len(self.data) > self.capacity:
self.data.popitem(last=False)
Algunos entrevistadores te pedirán que construyas tú la lista enlazada. Explica primero la estructura: el mapa apunta a los nodos de la lista, el nodo más reciente está en un extremo y desalojas desde el otro.
7. Camino más corto en una cuadrícula con muros
La búsqueda en anchura encuentra el camino más corto cuando cada paso tiene el mismo costo.
from collections import deque
def shortest_path(grid):
rows, cols = len(grid), len(grid[0])
if grid[0][0] or grid[rows - 1][cols - 1]:
return -1
queue = deque([(0, 0, 0)])
seen = {(0, 0)}
while queue:
r, c, steps = queue.popleft()
if (r, c) == (rows - 1, cols - 1):
return steps
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and not grid[nr][nc] and (nr, nc) not in seen:
seen.add((nr, nc))
queue.append((nr, nc, steps + 1))
return -1
print(shortest_path([[0, 0, 0], [1, 1, 0], [0, 0, 0]])) # 4
O(rows × cols) de tiempo y espacio. Marca las celdas como vistas al añadirlas a la cola, no al sacarlas, o la misma celda acabará encolada muchas veces.
8. Encuentra la primera versión defectuosa
Las versiones de 1 a n son buenas hasta cierto punto y defectuosas a partir de ahí. La búsqueda binaria encuentra la primera defectuosa en O(log n) comprobaciones.
def first_bad_version(n, is_bad):
lo, hi = 1, n
while lo < hi:
mid = (lo + hi) // 2
if is_bad(mid):
hi = mid
else:
lo = mid + 1
return lo
El patrón sirve para cualquier pregunta de sí o no que cambia una sola vez, y aparece con frecuencia. Para una lista de problemas que cubren estos patrones, consulta el Blind 75.
Preguntas de fundamentos de CS
9. ¿Cuál es la diferencia entre un proceso y un hilo?
Un proceso es un programa en ejecución con su propio espacio de memoria. Los hilos se ejecutan dentro de un proceso y comparten su memoria. Son más baratos de crear y de cambiar entre ellos, y pueden compartir datos directamente, pero por eso necesitas bloqueos y aparecen las condiciones de carrera. Los procesos están aislados, así que un fallo en uno no tumba a los demás.
10. ¿Cuál es la diferencia entre TCP y UDP?
TCP establece una conexión y garantiza una entrega ordenada y fiable, con retransmisión y control de flujo. UDP envía paquetes independientes sin garantía de entrega ni de orden, y con menos sobrecarga. Usa TCP para páginas web, APIs y transferencia de archivos. UDP encaja en voz, video y juegos en directo, donde un paquete tardío no sirve de nada de todos modos. Nuestras preguntas de entrevista sobre redes informáticas llegan más lejos.
11. ¿Qué pasa cuando escribes una URL en el navegador y pulsas Enter?
El navegador resuelve el dominio a una dirección IP mediante DNS, abre una conexión TCP y, en HTTPS, realiza el handshake TLS. Envía una petición HTTP, y el servidor, que a menudo está detrás de un balanceador de carga, devuelve una respuesta. El navegador analiza el HTML, pide el CSS, el JavaScript y las imágenes a los que hace referencia, y renderiza la página. Profundiza en la parte que elija el entrevistador.
12. ¿Cómo funciona una tabla hash y cuál es su complejidad temporal?
Una función hash asigna cada clave a un cubo dentro de un arreglo. Las búsquedas, inserciones y eliminaciones son O(1) en promedio. Cuando dos claves caen en el mismo cubo, la tabla resuelve la colisión encadenando o sondeando otra posición, y se redimensiona cuando se llena demasiado. El peor caso es O(n) si muchas claves colisionan.
13. ¿Cuándo elegirías una base de datos SQL en lugar de una NoSQL?
Elige SQL cuando los datos sean relacionales, necesites joins y transacciones, y el esquema sea bastante estable: pedidos, pagos, cuentas de usuario. Elige un almacén de documentos o de clave-valor cuando los patrones de acceso sean simples, la forma de los datos varíe o necesites escalar escrituras en muchas máquinas. Muchos sistemas usan ambos. La respuesta que buscan los entrevistadores es el balance entre ventajas y desventajas, no un ganador. Nuestras preguntas de entrevista sobre APIs REST cubren la capa de API que normalmente va encima.
Preguntas de diseño de sistemas
14. Diseña un acortador de URL
Primero aclara los requisitos: cuántos enlaces nuevos al día, cuántas lecturas, si los enlaces caducan y si se permiten alias personalizados. Luego cubre la API (crear y redirigir), cómo generas los códigos cortos (un contador codificado en base 62, o un código aleatorio con comprobación de unicidad), el almacenamiento (un almacén de clave-valor de código a URL) y una caché para los enlaces populares, ya que las lecturas superan con mucho a las escrituras. Termina con analítica y prevención de abusos si queda tiempo. Recorremos el diseño completo en nuestra guía de diseño de sistemas.
15. Diseña un limitador de tasa
Empieza por dónde se ejecuta (en la puerta de enlace de la API, por usuario o por clave de API) y qué pasa cuando un cliente supera el límite (HTTP 429 con un tiempo de reintento). El token bucket es la opción habitual: cada cliente tiene un cubo que se rellena a un ritmo fijo y guarda un máximo de tokens, y cada petición consume uno. Permite ráfagas cortas mientras hace cumplir una tasa media. Con varios servidores, guarda los contadores en un almacén compartido como Redis para que todos vean el mismo número. Para practicar más, consulta nuestras preguntas de entrevista de diseño de sistemas.
Preguntas conductuales
Usa una estructura clara para cada historia: la situación, lo que hiciste y el resultado, con cifras cuando las tengas.
16. Háblame de ti
Da una versión de dos minutos de tu trayectoria que termine con por qué quieres este puesto. Menciona uno o dos proyectos con resultados concretos. Nuestra guía sobre cómo hablar de ti en una entrevista tiene ejemplos.
17. Háblame de un bug difícil que hayas corregido
Respuesta de ejemplo: «Nuestro servicio de pagos empezó a superar el tiempo de espera unas cuantas veces al día, sin ningún patrón. Añadí IDs de solicitud a los logs y descubrí que todos los casos venían de una sola consulta a la base de datos, que solo se ejecutaba cuando un carrito tenía más de 50 artículos. A la consulta le faltaba un índice en la columna del join. Añadí el índice, la consulta lenta pasó de unos 4 segundos a menos de 50 milisegundos, y añadí una alerta sobre la latencia de esa consulta para detectarlo antes la próxima vez.»
18. Háblame de un desacuerdo con un compañero de equipo
Respuesta de ejemplo: «Un compañero quería reescribir nuestro servicio de notificaciones con un framework nuevo, y yo pensaba que el riesgo era demasiado alto antes del lanzamiento. En lugar de discutirlo en la reunión, propuse que cada uno escribiera por escrito el costo y el riesgo. Acordamos corregir los dos problemas más graves del código actual antes del lanzamiento y planificar la reescritura para el trimestre siguiente. El lanzamiento salió a tiempo, y dos meses después hicimos la reescritura con un plan de pruebas adecuado.»
19. Háblame de un proyecto que fracasó
Elige un fracaso real en el que hayas tenido una parte de responsabilidad. Explica qué salió mal, qué harías de otra manera y qué cambiaste después. Los entrevistadores buscan honestidad y aprendizaje, no un historial perfecto.
20. ¿Por qué quieres trabajar aquí?
Conecta algo específico del producto o del trabajo de ingeniería de la empresa con tu propia experiencia. «Llevo dos años usando su API y me gustaría trabajar en la parte de plataforma» gana a «son una gran empresa».
Preguntas para hacer al entrevistador
- ¿Cómo es una semana típica para alguien de este equipo?
- ¿Cómo se planifica el trabajo y quién decide las prioridades?
- ¿Cómo funcionan aquí la revisión de código y el despliegue?
- ¿Cómo se vería el éxito en los primeros seis meses?
- ¿Cuál es el problema técnico más difícil en el que trabaja el equipo?
Consulta preguntas para hacer al final de una entrevista para más.
Cómo prepararte
- Elige un lenguaje y úsalo en todos los problemas de práctica. Python es la opción más común porque el código es corto. Nuestras preguntas de entrevista de Python cubren el lenguaje en sí.
- Practica por patrones, no por cantidad: mapas hash, dos punteros, ventana deslizante, búsqueda binaria, BFS y DFS, montones y programación dinámica.
- Resuelve problemas en voz alta con un temporizador. Una solución correcta pero silenciosa puntúa menos que una explicada con claridad.
- Practica en el editor que vas a usar. Muchas empresas usan CoderPad, que tiene un entorno de pruebas gratuito.
- Prepara cinco historias de tu trabajo que puedas adaptar a la mayoría de las preguntas conductuales.
- Para puestos de nivel medio y senior, haz al menos unas cuantas sesiones completas de práctica de diseño de sistemas con alguien que te haga preguntas de seguimiento.
Practica entrevistas de programación en voz alta
YesToTheOffer transcribe tus respuestas para que revises cómo explicaste tu solución, con ayuda de programación a partir de capturas de pantalla a 0.2x. 30 minutos gratis, sin suscripción.



