Cómo aprobar una entrevista de C#: las mejores preguntas de nivel avanzado

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Entrevista avanzada de C#: cómo sorprender al empleador y no fracasar

\n\n

La entrevista para un puesto de Senior o Middle .NET Developer no es solo una verificación de sintaxis. Los entrevistadores quieren ver una comprensión profunda del funcionamiento interno de la plataforma, la capacidad de escribir código eficiente y tomar decisiones arquitectónicas. En este artículo, analizaremos los temas clave y las preguntas de nivel avanzado que te ayudarán a superar una entrevista técnica de C#.

\n\n

1. Programación asíncrona: async/await y Task

\n\n

Este es, probablemente, el tema más popular en las entrevistas. No basta con decir que conoces async/await. Es necesario entender cómo funciona internamente.

\n\n

Pregunta: ¿Qué es SynchronizationContext y cómo afecta la ejecución de await?

\n

Una pregunta clásica. SynchronizationContext es una abstracción que permite planificar la ejecución del código en un contexto determinado (por ejemplo, en el hilo de UI de WPF o en el grupo de subprocesos de ASP.NET). Cuando usas await, después de completar la operación asíncrona, el código intenta por defecto volver al contexto original. En aplicaciones de consola, esto es el grupo de subprocesos, y en UI, es el hilo del despachador. Comprender este mecanismo ayuda a evitar interbloqueos.

\n\n

Pregunta: ¿Cuál es la diferencia entre Task.Run y Task.Factory.StartNew?

\n

A primera vista son similares, pero Task.Run es un envoltorio simplificado. Task.Factory.StartNew ofrece más control (por ejemplo, puedes establecer TaskCreationOptions o TaskScheduler). Sin embargo, por defecto, Task.Run usa TaskScheduler.Default (grupo de subprocesos), mientras que Task.Factory.StartNew puede usar el planificador actual, lo que a veces provoca un comportamiento inesperado.

\n\n
// Ejemplo de interbloqueo debido a SynchronizationContext (en una aplicación UI)\npublic async Task<string> GetDataAsync()\n{\n    var result = await SomeAsyncMethod(); // captura del contexto\n    return result.ToString(); // intenta volver al hilo de UI\n}\n\n// Si se llama a .Result o .Wait() en la tarea, se produce un deadlock\nvar data = GetDataAsync().Result; // ¡MAL!\n
\n\n

2. Gestión de memoria y Garbage Collector (GC)

\n\n

Un desarrollador avanzado debe entender cómo .NET gestiona la memoria para evitar fugas y optimizar el rendimiento.

\n\n

Pregunta: Explica las generaciones del GC (Gen 0, Gen 1, Gen 2) y el Large Object Heap (LOH).

\n

El GC en .NET utiliza un modelo generacional. Los objetos primero van a Gen 0 (la recolección ocurre con frecuencia). Si sobreviven a la recolección, pasan a Gen 1, luego a Gen 2. El LOH está destinado a objetos de más de 85 000 bytes. No se compacta por defecto (hasta .NET 4.5.1), lo que puede causar fragmentación. La pregunta puede complicarse: "¿Cómo funciona la recolección de basura en segundo plano?" o "¿Qué son los modos de GC: Workstation vs Server?"

\n\n

Pregunta: ¿Qué es la finalización (Finalization) y cómo evitar los problemas asociados?

\n

Los finalizadores (~Finalizer()) ralentizan la recolección de basura, ya que los objetos con finalizadores entran en la cola de finalización y requieren dos pasadas del GC. El patrón correcto es implementar IDisposable con el patrón Dispose.

\n\n
public class ResourceHolder : IDisposable\n{\n    private IntPtr _handle;\n    private bool _disposed = false;\n\n    public void Dispose()\n    {\n        Dispose(true);\n        GC.SuppressFinalize(this);\n    }\n\n    protected virtual void Dispose(bool disposing)\n    {\n        if (!_disposed)\n        {\n            if (disposing)\n            {\n                // Liberamos recursos administrados\n            }\n            // Liberamos recursos no administrados (handle)\n            _disposed = true;\n        }\n    }\n\n    ~ResourceHolder()\n    {\n        Dispose(false);\n    }\n}\n
\n\n

3. Delegados, eventos y LINQ: de la sintaxis a la comprensión

\n\n

Estos temas a menudo

Blogs

Book Recommendations