Preguntas de entrevista en Google
El proceso de entrevista de Google es riguroso y de varias etapas, generalmente comienza con una entrevista telefónica seguida de 4-5 rondas presenciales que cubren codificación, diseño de sistemas y preguntas conductuales/liderazgo. Ponen un gran énfasis en la resolución de problemas, el pensamiento algorítmico y el ajuste cultural (Googleyness). Espera una alta dificultad, con preguntas diseñadas para evaluar tu profundidad de conocimiento y capacidad para escalar soluciones.
En qué se centran las entrevistas de Google
Estructuras de datos y algoritmos
Las entrevistas de codificación se centran en arreglos, cadenas, árboles, grafos, programación dinámica y tablas hash. Deberás escribir código eficiente y sin errores en una pizarra o documento compartido, explicando tu proceso de pensamiento.
Diseño de sistemas
Para roles más experimentados, las rondas de diseño de sistemas exploran cómo arquitectarías sistemas a gran escala como Google Search o YouTube. Espera preguntas abiertas sobre escalabilidad, confiabilidad y compensaciones.
Conductual / Principios de liderazgo
Google evalúa la googleyness a través de preguntas sobre proyectos pasados, conflictos, fracasos y liderazgo. Buscan colaboración, humildad y una mentalidad de crecimiento, a menudo alineados con sus principios de liderazgo.
Dominio y sentido del producto
Dependiendo del rol, puedes enfrentar preguntas específicas del dominio (por ejemplo, para un rol de aprendizaje automático: diseño de modelos). Las preguntas de sentido del producto evalúan cómo mejorarías productos existentes de Google o lanzarías nuevos.
Preguntas comunes en entrevistas de Google
- Dado un arreglo de enteros, devuelve los índices de los dos números que suman un objetivo específico. (Clásico two-sum, pero pide múltiples soluciones y discute la complejidad).Lo que cubre una buena respuesta
- HashMap de complementos O(n) tiempo y espacio
- Fuerza bruta O(n^2) sin espacio extra
- Ordenar + dos punteros O(n log n) para múltiples soluciones
- Manejo de duplicados y múltiples pares
Ver respuesta de ejemplo
Para el problema two-sum, el enfoque más eficiente es usar un hashmap que almacene cada elemento y su índice mientras recorremos el arreglo. Para cada número, calculamos el complemento (target - num) y verificamos si ya está en el mapa, lo que da O(n) tiempo y O(n) espacio. Si se requieren múltiples soluciones, podemos primero encontrar todos los pares usando ordenamiento (O(n log n)) y luego dos punteros, pero eso no retorna índices originales a menos que se almacenen. La fuerza bruta con dos bucles anidados es O(n^2) y solo útil para arreglos pequeños. Un error común es no manejar duplicados: si el complemento es igual al número actual, hay que verificar que sea un índice diferente. Para múltiples soluciones sin repetición de índices, podemos usar un mapa que almacene listas de índices. En una entrevista, es importante discutir estos tradeoffs.
Solución de referenciapython def two_sum(nums, target): """Retorna los índices de los dos números que suman target. Se asume exactamente una solución.""" complement_map = {} # valor -> índice for i, num in enumerate(nums): complement = target - num if complement in complement_map: return [complement_map[complement], i] complement_map[num] = i return [] - Diseña un acortador de URLs como bit.ly – discute esquema de base de datos, hashing, escalado y manejo de redirecciones.Lo que cubre una buena respuesta
- Generación de clave única: hash MD5 truncado o base62 con contador
- Esquema de BD: tabla urls con id, short_key, long_url, fecha_creacion, clicks
- Redirección 301 (permanente) vs 302 (temporal) para SEO y análisis
- Escalado: caché Redis de claves populares, sharding por short_key, balanceo de carga
- Evitar colisiones: verificar unicidad o usar ID incremental codificado
Ver respuesta de ejemplo
Un acortador de URLs debe recibir una URL larga y devolver una corta única que redirija a la original. El esquema de base de datos incluye una tabla principal con columnas: id (clave primaria autoincremental), short_key (índice único), long_url, created_at y opcionalmente contador de clics. Para generar la clave corta, una opción común es usar un hash criptográfico como MD5 truncado a 6-7 caracteres en base62, pero con riesgo de colisiones; se puede verificar contra la BD o usar un contador incremental codificado en base62. Para redirigir, se usa HTTP 301 (redirección permanente) para que los navegadores la cacheen, o 302 (temporal) si queremos recopilar análisis cada vez. El escalado requiere almacenar en caché (por ejemplo, Redis) las claves más populares, particionar la tabla por short_key (hash-based sharding), y balancear la carga con un servidor web distribuido. Los cuellos de botella típicos son la generación de claves únicas bajo alta concurrencia y la latencia de la BD; se solucionan con IDs precalculados o usando servicios como Snowflake.
- Cuéntame sobre una vez que tuviste un conflicto con un colega. ¿Cómo lo resolviste? (Conductual – enfócate en colaboración y resultado).Lo que cubre una buena respuesta
- STAR: Situación, Tarea, Acción, Resultado
- Ejemplo concreto: desacuerdo sobre deuda técnica vs nuevas funcionalidades
- Acción: recopilar datos, presentar argumentos técnicos, buscar compromiso
- Resultado: implementación de mejoras incrementales, mejora en relaciones
Ver respuesta de ejemplo
En un proyecto anterior, mi colega y yo teníamos opiniones opuestas sobre si priorizar el pago de deuda técnica o agregar nuevas funcionalidades para cumplir con el plazo del cliente. Yo defendía que sin refactorizar, la velocidad del equipo se ralentizaría, mientras que él argumentaba que el cliente necesitaba las funcionalidades para una demostración. Para resolverlo, organicé una reunión con datos concretos: mostré métricas de tiempo de compilación y tasa de errores que demostraban el impacto de la deuda técnica. Propusimos un compromiso: dedicar las primeras dos horas de cada sprint a refactorización crítica y el resto a nuevas funcionalidades. El resultado fue que el equipo cumplió el plazo, la calidad del código mejoró y la relación con mi colega se fortaleció porque aprendimos a equilibrar perspectivas. Esta experiencia me enseñó a usar datos para desbloquear conflictos y buscar soluciones colaborativas.
- Implementa una función para serializar y deserializar un árbol binario. (Prueba el manejo de nulos, recursión e iteración).Lo que cubre una buena respuesta
- Serialización: recorrido preorden con marcador nulo (e.g., '#' o None)
- Deserialización: reconstruir árbol recursivamente usando cola de valores
- Complejidad O(n) en tiempo y espacio para ambos procesos
- Alternativa iterativa con pila explícita para evitar recursión profunda
- Manejo de árboles sesgados y valores repetidos
Ver respuesta de ejemplo
La serialización de un árbol binario consiste en convertirlo en una cadena (o lista) que pueda almacenarse o transmitirse, y la deserialización reconstruye el árbol original. Un método común es usar un recorrido preorden que incluya marcadores para nodos nulos. Por ejemplo, para cada nodo, escribimos su valor o un carácter especial (como '#') si es None. Esto permite reconstruir el árbol de forma única. La implementación recursiva es sencilla: en serialización, concatenamos el valor actual, luego serializamos hijo izquierdo y derecho, separando por comas (o usando una lista). En deserialización, convertimos la cadena en una cola de strings, extraemos el primer elemento; si es '#', retornamos None, de lo contrario creamos un nodo y llamamos recursivamente para sus hijos. La complejidad es O(n) para ambos procesos porque visitamos cada nodo exactamente una vez. El espacio es O(n) debido a la cadena y a la pila de recursión. Un error común es no manejar árboles muy profundos que pueden desbordar la pila; en tal caso se requiere una versión iterativa con pila explícita. Otro detalle es cómo serializar valores que pueden contener el separador; se debe escapar o usar un formato como JSON.
Solución de referenciapython class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def serialize(root: TreeNode) -> str: """Serializa el árbol en preorden con '#' para nulos.""" def dfs(node): if not node: return ['#'] return [str(node.val)] + dfs(node.left) + dfs(node.right) return ','.join(dfs(root)) def deserialize(data: str) -> TreeNode: """Reconstruye el árbol desde la cadena serializada.""" values = data.split(',') idx = 0 def dfs(): nonlocal idx if idx >= len(values): return None val = values[idx] idx += 1 if val == '#': return None node = TreeNode(int(val)) node.left = dfs() node.right = dfs() return node return dfs() - Diseña la función de tráfico en tiempo real de Google Maps – ¿cómo recopilarías datos, actualizarías rutas y manejarías a millones de usuarios?Lo que cubre una buena respuesta
- Recolección de datos: GPS de dispositivos móviles, sensores viales, datos históricos
- Procesamiento: map matching, cálculo de velocidad promedio por segmento
- Actualización de rutas: algoritmo A* con pesos dinámicos y reoptimización periódica
- Escalado: partición geográfica, procesamiento en flujo (Kafka/Spark), caché de rutas frecuentes
Ver respuesta de ejemplo
Para diseñar el tráfico en tiempo real de Google Maps, primero se recopilan datos de múltiples fuentes: ubicaciones GPS anónimas de dispositivos móviles (con permiso), sensores en carreteras, informes de incidentes y datos históricos. Estos datos se envían a servidores donde se realiza map matching para asignar cada punto GPS a un segmento de carretera. Luego, se calcula la velocidad promedio en cada segmento mediante ventanas de tiempo deslizantes (por ejemplo, últimos 5 minutos). Para actualizar las rutas, se usa un algoritmo como A* (o su variante) con pesos que reflejan el tiempo de viaje basado en el tráfico actual. Las rutas se recalculan periódicamente o bajo demanda. Para escalar a millones de usuarios, se divide el mapa en regiones (sharding geográfico), se procesan los datos en tiempo real con un sistema de flujo como Apache Kafka y Spark Streaming, y se almacenan en una base de datos distribuida (Bigtable). Las rutas más populares se cachean en memoria (por ejemplo, Redis) para reducir latencia. Los cuellos de botella incluyen la ingesta masiva de datos y la actualización de grafos de rutas; se mitigan con particionamiento y precomputación de rutas en horas valle.
- Explica un proyecto del que estés más orgulloso. ¿Cuál fue tu rol, desafíos e impacto? (Conductual – evalúa propiedad e influencia).Lo que cubre una buena respuesta
- STAR: Situación, Tarea, Acción, Resultado
- Ejemplo: liderar migración de monolito a microservicios
- Rol: líder técnico, responsable de arquitectura y coordinación
- Desafíos: deuda técnica, coordinación entre equipos, migración sin downtime
- Impacto: reducción de tiempo de despliegue de horas a minutos, mejora en escalabilidad
Ver respuesta de ejemplo
El proyecto del que estoy más orgulloso fue la migración de un sistema monolítico a una arquitectura de microservicios en mi empresa anterior, donde fui el líder técnico. La situación inicial era un monolito que se había vuelto difícil de escalar y mantener, con implementaciones que requerían horas y causaban frecuentes interrupciones. Mi tarea era diseñar la arquitectura de microservicios, dividir el monolito en servicios cohesivos y coordinar a varios equipos para la migración sin afectar la disponibilidad del sistema. Como acción, primero mapeé las dependencias del monolito y propuse una estrategia de extracción incremental usando el patrón Strangler Fig: cada funcionalidad se extraía como un microservicio independiente, con un proxy que enrutaba el tráfico gradualmente. Enfrentamos desafíos como la gestión de transacciones distribuidas y la sincronización de datos, que resolvimos con un enfoque de eventos (event sourcing) y colas de mensajes. El resultado fue una reducción del tiempo de despliegue de varias horas a menos de 10 minutos, una mejora significativa en la escalabilidad (podíamos escalar servicios individuales) y un aumento en la moral del equipo por la autonomía ganada. Este proyecto me enseñó la importancia de la planificación cuidadosa y la comunicación entre equipos.
- Dado un flujo de enteros, encuentra la mediana en cualquier punto. (Usa dos montones – max-heap y min-heap).Lo que cubre una buena respuesta
- Estructura: max-heap para la mitad inferior, min-heap para la superior
- Inserción: mantener diferencia de tamaño <= 1, rebalancear si necesario
- Mediana: si tamaños iguales, promedio de raíces; si no, raíz del heap más grande
- Complejidad: O(log n) por inserción, O(1) para mediana
- Manejo de números duplicados y flujo continuo
Ver respuesta de ejemplo
Para encontrar la mediana de un flujo de enteros en tiempo real, se usan dos montones: un max-heap para la mitad inferior de los números y un min-heap para la mitad superior. Al insertar un número, primero se decide a qué heap agregarlo (por ejemplo, si es menor o igual que la raíz del max-heap, va al max-heap; si no, al min-heap). Luego se balancean para que la diferencia de tamaño no sea mayor a 1. Para obtener la mediana, si los heaps tienen el mismo tamaño, se devuelve el promedio de las dos raíces; si no, la raíz del heap más grande. En Python, los heaps son min-heap por defecto, por lo que el max-heap se implementa almacenando valores negativos. La complejidad de tiempo por inserción es O(log n) debido a las operaciones de heap, y la consulta de mediana es O(1). El espacio total es O(n). Un error común es no manejar correctamente el balance cuando se insertan muchos números iguales; la estrategia de inserción debe ser consistente para evitar desequilibrios.
Solución de referenciapython import heapq class MedianFinder: def __init__(self): # max-heap para la mitad inferior (almacenamos negativos) self.low = [] # max-heap # min-heap para la mitad superior self.high = [] # min-heap def addNum(self, num: int) -> None: # Insertar en el heap apropiado if not self.low or num <= -self.low[0]: heapq.heappush(self.low, -num) else: heapq.heappush(self.high, num) # Balancear para que |low| >= |high| y la diferencia <= 1 if len(self.low) < len(self.high): heapq.heappush(self.low, -heapq.heappop(self.high)) elif len(self.low) > len(self.high) + 1: heapq.heappush(self.high, -heapq.heappop(self.low)) def findMedian(self) -> float: if len(self.low) > len(self.high): return -self.low[0] else: return (-self.low[0] + self.high[0]) / 2.0 - ¿Por qué Google? ¿Qué te hace un buen ajuste para nuestra cultura? (Conductual – conecta valores personales con la misión de Google).Lo que cubre una buena respuesta
- Alineación con misión: organizar información y hacerla accesible universalmente
- Valores culturales: enfoque en el usuario, colaboración, innovación
- Ejemplos personales: pasión por productos que impactan a miles de millones
- Ajuste técnico: experiencia en sistemas distribuidos y escalabilidad
Ver respuesta de ejemplo
Quiero trabajar en Google porque su misión de 'organizar la información del mundo y hacerla universalmente accesible y útil' resuena profundamente conmigo. He admirado cómo Google ha creado productos que mejoran la vida de miles de millones de personas, desde la Búsqueda hasta Maps y Gmail. Creo que mi experiencia en sistemas distribuidos y mi pasión por construir software escalable y de alto rendimiento se alinean con los desafíos técnicos que Google enfrenta. Además, valoro la cultura de colaboración, transparencia y enfoque en el usuario que promueve la empresa. En mi rol anterior, prioricé siempre la experiencia del usuario final, incluso cuando implicaba sacrificar velocidad de desarrollo, y fomenté un ambiente de equipo donde las ideas se discutían abiertamente. Estoy convencido de que puedo contribuir a proyectos que tengan un impacto global y aprender de algunos de los mejores ingenieros del mundo. Google no solo resuelve problemas complejos a escala, sino que también invierte en el crecimiento de sus empleados, algo que valoro enormemente.
Consejos para prepararse
- Practica codificación en una pizarra o sin IDE: las entrevistas de Google a menudo requieren escribir código a mano, así que acostúmbrate a pensar y escribir en una superficie plana.
- Siempre piensa en voz alta: los entrevistadores quieren ver tu proceso de resolución de problemas, así que narra tu enfoque, compensaciones y pasos de depuración.
- Domina las estructuras de datos fundamentales: concéntrate en arreglos, cadenas, árboles, grafos y tablas hash – aparecen en la mayoría de los problemas de codificación. Prepárate para discutir complejidad temporal y espacial.
- Prepárate para diseño de sistemas estudiando escalabilidad: comprende caché, balanceo de carga, fragmentación y teorema CAP. Practica diseñar sistemas como YouTube, Twitter o un servicio de chat.
- Revisa historias conductuales con el método STAR: estructura tus respuestas en Situación, Tarea, Acción, Resultado, y adáptalas a los principios de liderazgo de Google (por ejemplo, 'Ten columna, discrepa y comprométete').
Preguntas frecuentes
¿Cuántas rondas de entrevista tiene Google?
Generalmente una entrevista telefónica (30-45 min de codificación) seguida de 4-5 rondas presenciales: 2-3 de codificación, 1 de diseño de sistemas (para roles senior) y 1 conductual/Googleyness.
¿Qué tan difíciles son las entrevistas de Google en comparación con otras grandes empresas tecnológicas?
Google es conocido por estar entre los más difíciles, con un fuerte énfasis en algoritmos y profundidad en resolución de problemas. Muchos candidatos lo consideran comparable a Facebook pero diferente del enfoque de Amazon en principios de liderazgo.
¿Cuánto dura el proceso de entrevista de Google?
Desde la solicitud hasta la oferta puede tomar de 1 a 3 meses, con 1-2 semanas para programar la entrevista telefónica, luego algunas semanas para la presencial, más tiempo adicional para el emparejamiento de equipo y aprobaciones.
¿Qué valora más Google en los candidatos?
Buscan fuertes habilidades de resolución de problemas, fluidez en codificación, conciencia de escala y ajuste cultural (Googleyness). Los principios de liderazgo como 'enfócate en el usuario' y 'piensa en grande' son clave.
¿Cómo puedo destacar en las entrevistas de Google?
Demuestra comprensión profunda explorando soluciones alternativas, discutiendo compensaciones y escribiendo código limpio y comprobable. Además, muestra pasión por los productos y la misión de Google en las respuestas conductuales.
Practica preguntas estilo Google con retroalimentación instantánea de IA
Sube tu currículum y Offersly realiza una entrevista simulada personalizada, evalúa tus respuestas en relevancia, profundidad, claridad y corrección, y te muestra exactamente qué mejorar.