He recopilado una serie de posts con mi base de datos personal de preguntas de entrevista de Python. No es perfecta, no está completa, y no, no incluye respuestas. Algunas preguntas pueden parecer un poco raras o sacadas de la nada. Pero en mi experiencia, son muy buenas para ayudarte a descubrir quién está realmente listo para el puesto.
La serie está dividida en tres partes según el nivel de experiencia:
- Python Interview Questions for Beginners (Junior)
- Python Interview Questions for Mid-Level Developers
- Python Interview Questions for Experienced Developers (Senior)
¿Tienes una pregunta que crees que debería estar aquí? ¿O algo que siempre preguntas en las entrevistas? Cuéntamelo — me encantaría escuchar tu opinión.
Qué significa "middle" aquí
Empecemos por definir los niveles. Como yo lo veo: el junior conoce la sintaxis, el middle sabe qué se rompe en producción, el senior sabe qué no construir.
Algunas preguntas tienen una nota debajo sobre qué estoy buscando en la respuesta. Si eres tú quien entrevista, ahí es donde hay que profundizar. Si te estás preparando, eso es lo que separa una respuesta sólida de una memorizada, y lo que la persona al otro lado de la mesa suele querer escuchar.
Preguntas
1. Conceptos del lenguaje Python
Q: ¿Cuál es el resultado de -12 % 10?
Q: ¿Cuál es el resultado de -12 // 10?
Q: ¿Cómo se llama el orden de evaluación de los operadores en la expresión a * b * c?
Q: ¿Por qué no deberías usar un objeto mutable (por ejemplo, una lista vacía) como valor por defecto de un argumento en Python?
Q: ¿Qué hace la función id() en Python?
- Seguimiento: Dos cadenas iguales pueden compartir el mismo
id(). ¿Por qué?
Q: ¿Qué son las comprehensions en Python (list, dict, set)? ¿Cuándo conviene usarlas?
Q: Python 3.10 añadió structural pattern matching (match/case). ¿En qué se diferencia de una cadena de if/elif?
- Seguimiento: ¿Qué puede desestructurar
matchqueifno puede hacer de forma limpia?
Q: ¿Para qué se usa la palabra clave yield en Python?
Q: ¿Cómo diferencias los iteradores de los generadores en Python?
- Bonus: Escribe un ejemplo de cada uno.
Q: ¿Cuál es la diferencia entre los métodos __iter__ y __next__?
Q: ¿Cómo se crea un diccionario que preserve el orden de los pares clave-valor?
Q: ¿Cuándo usarías un dataclass en vez de un NamedTuple, un TypedDict o una clase normal?
Aquí no hay una respuesta incorrecta, así que no se puede memorizar. Quiero escuchar cómo se sopesa la mutabilidad frente a la hashability y el costo en tiempo de ejecución. Y quiero escuchar que TypedDict deja de ser una clase por completo en cuanto el programa se ejecuta.
- Seguimiento: ¿Qué te da
frozen=True, y qué cuesta?
Q: ¿Por qué usarías pathlib en vez de os.path y la concatenación de cadenas?
Q: ¿Qué son los bloques try, except, else y finally? Da ejemplos.
2. Gestores de contexto
Q: ¿Qué es un gestor de contexto, y en qué se diferencia de usar try...finally?
try/finally hace exactamente lo mismo, así que "es más pythonic" es una respuesta bastante floja. Lo que espero es __enter__/__exit__ y la idea detrás de ellos: el gestor se puede reutilizar. Con try/finally lo escribes de nuevo en cada punto de llamada, hasta que alguien tarde o temprano se olvida.
Q: ¿Qué métodos hay que implementar para crear una clase de gestor de contexto propia?
Q: Explica los bloques with. ¿Por qué se consideran más pythonic que try-finally?
Q: Describe un caso de uso donde los gestores de contexto pueden ser útiles.
3. Fundamentos de async
Q: ¿Qué es el código síncrono, y en qué se diferencia del código asíncrono?
Q: ¿En qué se diferencian las funciones async de las funciones normales de Python?
Q: ¿Qué son las palabras clave async y await en Python? Da un ejemplo simple.
- Seguimiento: ¿Qué hace
await, y cuándo debería usarse?
Q: ¿Cuál es el propósito de un event loop en Python, y cómo interactúa con él la función asyncio.run()?
Q: ¿Cómo manejas las excepciones en código Python asíncrono?
Q: Necesitas llamar a tres APIs async independientes. ¿Qué tiene de malo esperarlas una tras otra, y cómo lo arreglarías?
- Seguimiento: Una de las tres falla. ¿Qué pasa con las otras dos?
Q: ¿Puedes explicar el propósito de las construcciones async with y async for? Da ejemplos.
Q: ¿Cómo puedes hacer I/O de archivos de forma asíncrona en Python?
Q: ¿Cuándo elegirías programación asíncrona en vez de multithreading en Python?
4. Conceptos avanzados
Q: ¿Qué es el módulo unittest en Python? ¿Cómo se escriben tests en Python?
Q: Sintaxis moderna de type hints: ¿cuál es la diferencia entre List[int] y list[int], y entre Optional[str] y str | None? ¿Cuál escribirías hoy?
Nada difícil aquí. La pregunta simplemente los data: la respuesta muestra en qué Python han estado escribiendo los últimos años, y cuánto se mantienen al día con las mejores prácticas.
Q: Explica el type checking en Python. ¿Por qué se considera Python un lenguaje fuertemente tipado?
- Seguimiento: ¿Qué herramientas de análisis estático pondrías en el CI, y en qué orden?
Q: ¿Cómo aíslas el código Python de forma efectiva (por ejemplo, entornos virtuales)?
- Seguimiento: ¿Qué va en
pyproject.toml, y qué reemplazó asetup.pypara ti? - Seguimiento: ¿Cuál es la diferencia entre un lockfile y un archivo de requirements, y cuándo muerde esa diferencia?
Esto comprueba la diferencia entre intención e implementación. requirements.txt es lo que elegiste tú mismo. Las dependencias transitivas fijadas son lo que eligió el resolver por ti. pip freeze > requirements.txt borra esa línea: vuelca todo el grafo en un solo archivo y ya no recuerda qué parte fue decisión tuya.
Q: ¿Cómo se copia un objeto en Python? ¿Cuál es la diferencia entre una copia superficial (shallow) y una copia profunda (deep)?
Se relaciona con la pregunta de [[]] * 3 más abajo. Lo mismo dos veces, y tengo curiosidad por saber si conectan ambas.
Q: ¿Cómo se gestiona la memoria en Python?
- Seguimiento: ¿Por qué Python tiene un recolector de basura, y cómo funciona?
Q: ¿Cómo puedes compartir variables globales entre módulos? ¿Es buena idea hacerlo?
Q: ¿Qué es el atributo __slots__ de una clase? ¿Cuáles son sus ventajas y desventajas?
A estas alturas seguramente todos conocen las ventajas. La pregunta es más sobre las desventajas: sin __dict__, sin atributos que no declaraste, y la herencia deja de ser gratis.
Q: ¿Qué son las metaclases en Python?
- Bonus: ¿Cómo puedes crear una clase sin usar la sentencia class?
5. Retos de programación
Q: ¿Cómo comprobar que una tupla contiene todos los elementos de otra tupla?
Q: ¿Cuál será el resultado del siguiente código?
>>> list = ['a', 'b', 'c', 'd', 'e']
>>> print(list[10:])
Q: ¿Cómo puedo recargar un módulo previamente importado? (asumimos que el módulo es un archivo module.py)
Q: ¿Cuál será el resultado del siguiente código?
>>> a = [[]] * 3
>>> a[1].append(1)
>>> print(a)
Q: ¿Qué tiene de malo el siguiente código?
def foo():
from .module import *
print(f"{bar()}")
Q: El archivo está ubicado en /usr/lib/python/person.py. El programa se ejecuta con python /usr/lib/python/person.py. ¿Cuál será el resultado?
class Person:
def __init__(self, name):
__name__ = name
def getAge(self):
print(__name__)
p = Person("John")
p.getAge()
Q: Escribe un decorador timeit para medir el tiempo de ejecución de una función.
Q: Escribe un decorador que capture errores y repita la función un máximo de 3 veces (configurable).
Q: ¿Cuál es la salida del siguiente código?
class parent:
def __init__(self, param):
self.v1 = param
class child:
def __init__(self, param):
self.v2 = param
obj = child(11)
print(obj.v1 + " " + obj.v2)
Q: Corrige el siguiente código para que funcione.
class Repeater:
...
class RepeaterIterator:
...
repeater = Repeater("Hello")
for i in repeater:
print(i) # hello
Q: Escribe código para obtener valores únicos de una lista de tipos complejos (clases propias). Ejemplo: [A(1, "ab"), A(2, "ab"), A(2, "aa"), A(1, "ab")] -> [A(1, "ab"), A(2, "ab"), A(2, "aa")].
Q: Tenemos el siguiente código con la función desconocida f(). En f() no queremos usar un return, en cambio, quizás queramos usar un generador.
for x in f(5):
print(x,)
El resultado se ve así:
0 1 8 27 64
Escribe una función f() para que obtengamos el resultado de arriba.
Q: ¿Cuál es la salida del siguiente código?
x = [[0], [1]]
print(len(' '.join(list(map(str, x)))))
Q: Escribe una función para generar todas las permutaciones de una cadena.
Q: Implementa una caché LRU (Least Recently Used) básica.