Perguntas para Entrevista de Desenvolvedor Backend (C#/.NET): Guia Completo

Milad Bonakdar
Autor
Domine o desenvolvimento backend em C# e .NET com perguntas essenciais para entrevistas, abrangendo ASP.NET Core, Entity Framework, Injeção de Dependência e design de sistemas.
Introdução
C# e .NET evoluíram significativamente, tornando-se um ecossistema poderoso e multiplataforma para a construção de sistemas de backend de alto desempenho. Com o advento do .NET Core (e agora apenas .NET 5+), é uma das principais escolhas para aplicações nativas da nuvem, microsserviços e soluções corporativas.
Este guia abrange as principais perguntas de entrevistas para Desenvolvedores Backend especializados em C# e .NET. Exploramos os fundamentos da linguagem, a arquitetura do ASP.NET Core, as interações com bancos de dados usando o Entity Framework e as melhores práticas para ajudá-lo a se preparar para sua próxima entrevista.
Fundamentos da Linguagem C#
1. Qual é a diferença entre struct e class em C#?
Resposta:
- Class (Classe): Um tipo de referência (alocado no heap). Quando você passa um objeto de classe para um método, está passando uma referência para o local da memória. As alterações dentro do método afetam o objeto original. Suporta herança.
- Struct (Estrutura): Um tipo de valor (alocado na stack). Quando você passa uma struct, uma cópia dos dados é passada. As alterações dentro do método não afetam a struct original. Não suporta herança (mas pode implementar interfaces).
- Uso: Use
structpara estruturas de dados pequenas e imutáveis que representam um único valor (comoPoint,Color). Useclasspara a maioria dos outros objetos.
Raridade: Comum Dificuldade: Fácil
2. Explique async e await. Como isso ajuda na escalabilidade?
Resposta:
async e await são palavras-chave usadas para programação assíncrona.
- Mecanismo: Quando uma palavra-chave
awaité encontrada, a execução do método é pausada e a thread é liberada de volta para o pool de threads para lidar com outras requisições. Quando a tarefa aguardada é concluída, a execução é retomada (potencialmente em uma thread diferente). - Escalabilidade: Em um servidor web (como o Kestrel), as threads são um recurso limitado. Se uma thread é bloqueada esperando por E/S (banco de dados, rede), ela não pode lidar com outras requisições. Async permite que o servidor lide com muito mais requisições simultâneas com menos threads, não as bloqueando durante as operações de E/S.
Raridade: Muito Comum Dificuldade: Média
3. O que é Injeção de Dependência (DI) e como ela é implementada em .NET?
Resposta: Injeção de Dependência é um padrão de projeto onde as dependências de uma classe são fornecidas de fora, em vez de serem criadas internamente.
- Em .NET: O ASP.NET Core possui um contêiner DI integrado. Você registra os serviços em
Program.cs(ouStartup.csem versões mais antigas) e os injeta via injeção de construtor. - Lifetimes (Tempos de Vida):
- Transient (Transitório): Criado toda vez que são solicitados.
- Scoped (Escopo): Criado uma vez por requisição do cliente (requisição HTTP).
- Singleton (Único): Criado na primeira vez que são solicitados e compartilhado por todas as requisições subsequentes.
Raridade: Muito Comum Dificuldade: Média
4. Qual é a diferença entre IEnumerable<T> e IQueryable<T>?
Resposta:
IEnumerable<T>: Executa a consulta na memória. Se usado com um banco de dados (EF Core), ele busca todos os dados do servidor para a memória do cliente e então os filtra. Bom para LINQ to Objects.IQueryable<T>: Executa a consulta remotamente (por exemplo, no servidor SQL). Ele constrói uma árvore de expressão que é traduzida em uma consulta SQL. A filtragem acontece no lado do banco de dados, o que é muito mais eficiente para grandes conjuntos de dados.
Raridade: Comum Dificuldade: Média
5. O que são Extension Methods (Métodos de Extensão)?
Resposta: Métodos de extensão permitem que você "adicione" métodos a tipos existentes sem criar um novo tipo derivado, recompilar ou modificar o tipo original.
- Sintaxe: Definidos como métodos estáticos em uma classe estática. O primeiro parâmetro especifica em qual tipo o método opera, precedido pela palavra-chave
this. - Exemplo: Adicionando um método
WordCount()à classestring.
Raridade: Comum Dificuldade: Fácil
ASP.NET Core & Arquitetura
6. O que é Middleware no ASP.NET Core?
Resposta: Middlewares são componentes de software que são montados em um pipeline de aplicação para lidar com requisições e respostas.
- Pipeline: Cada componente escolhe se deve passar a requisição para o próximo componente no pipeline e pode executar o trabalho antes e depois que o próximo componente é invocado.
- Exemplos: Autenticação, Autorização, Logging (Registro de Logs), Tratamento de Exceções, Servir Arquivos Estáticos.
- A Ordem Importa: A ordem em que o middleware é adicionado em
Program.csdefine a ordem de execução.
Raridade: Muito Comum Dificuldade: Média
7. Explique a diferença entre .NET Core e .NET Framework.
Resposta:
- .NET Framework: A implementação original, exclusiva para Windows. Maduro, mas vinculado ao Windows.
- .NET Core (agora apenas .NET): Uma implementação multiplataforma, de código aberto e modular. Ele é executado no Windows, Linux e macOS. É otimizado para alto desempenho e implantações na nuvem.
- Principais Diferenças: Suporte multiplataforma, amigável à arquitetura de microsserviços, maior desempenho, versionamento lado a lado.
Raridade: Comum Dificuldade: Fácil
8. O que é Kestrel?
Resposta: Kestrel é um servidor web multiplataforma, de código aberto e orientado a eventos que é incluído por padrão nos templates do ASP.NET Core.
- Papel: Ele escuta as requisições HTTP e as passa para a aplicação.
- Uso: Ele pode ser executado de forma independente (servidor de borda) ou atrás de um proxy reverso como IIS, Nginx ou Apache. Usar um proxy reverso é recomendado para produção para lidar com segurança, balanceamento de carga e terminação SSL.
Raridade: Média Dificuldade: Média
9. Como você lida com o Tratamento Global de Exceções no ASP.NET Core?
Resposta: Em vez de blocos try-catch em todos os controllers, você deve usar middleware para o tratamento global de exceções.
UseExceptionHandler: Middleware integrado que captura exceções, as registra e reexecuta a requisição em um pipeline alternativo (geralmente apontando para uma página de erro ou resposta da API).- Custom Middleware (Middleware Personalizado): Você pode escrever middleware personalizado para capturar exceções e retornar uma resposta de erro JSON padronizada (por exemplo,
ProblemDetails).
Raridade: Comum Dificuldade: Média
Banco de Dados & Entity Framework
10. O que é Entity Framework Core (EF Core)? Code-First vs. Database-First?
Resposta: EF Core é um Mapeador Objeto-Relacional (ORM) para .NET. Ele permite que os desenvolvedores trabalhem com um banco de dados usando objetos .NET.
- Code-First (Primeiro o Código): Você define suas classes de domínio (entidades) primeiro, e o EF Core cria/atualiza o schema do banco de dados com base nelas usando Migrations (Migrações). Preferido para novos projetos.
- Database-First (Primeiro o Banco de Dados): Você tem um banco de dados existente, e o EF Core gera as classes .NET (scaffolding) com base no schema.
Raridade: Comum Dificuldade: Fácil
11. O que é o problema N+1 no EF Core e como você o corrige?
Resposta: O problema N+1 ocorre quando você busca uma lista de entidades (1 consulta) e então acessa uma entidade relacionada para cada item em um loop, causando N consultas adicionais.
- Correção: Use Eager Loading (Carregamento Adiantado) com o método
.Include(). Isso gera umJOINSQL para buscar os dados relacionados em uma única consulta. - Exemplo:
context.Orders.Include(o => o.Customer).ToList();
Raridade: Muito Comum Dificuldade: Média
12. Explique o Repository Pattern (Padrão Repositório). Por que usá-lo com EF Core?
Resposta: O Repository Pattern medeia entre as camadas de domínio e mapeamento de dados, usando uma interface semelhante a uma coleção para acessar objetos de domínio.
- Prós: Desacopla a aplicação da tecnologia específica de acesso a dados (EF Core), facilita o teste de unidade (pode simular o repositório) e centraliza a lógica de acesso a dados.
- Contras/Debate: O
DbContextdo EF Core já é uma implementação do padrão Repository/Unit of Work. Adicionar outra camada pode às vezes ser redundante ("abstração sobre abstração").
Raridade: Comum Dificuldade: Difícil
APIs REST & Web Services
13. Quais são os HTTP Verbs (Verbos HTTP) e seu uso típico?
Resposta:
- GET: Recupera um recurso. Seguro e Idempotente.
- POST: Cria um novo recurso. Não Idempotente.
- PUT: Atualiza/Substitui um recurso existente. Idempotente.
- PATCH: Atualiza parcialmente um recurso. Não necessariamente Idempotente (mas geralmente é).
- DELETE: Remove um recurso. Idempotente.
Raridade: Comum Dificuldade: Fácil
14. Qual é a diferença entre 401 Unauthorized (Não Autorizado) e 403 Forbidden (Proibido)?
Resposta:
- 401 Unauthorized: O usuário não está autenticado. O cliente deve fazer login e tentar novamente. "Eu não sei quem você é."
- 403 Forbidden: O usuário está autenticado, mas não tem permissão para acessar o recurso. "Eu sei quem você é, mas você não pode fazer isso."
Raridade: Comum Dificuldade: Fácil
Testes & Melhores Práticas
15. Qual é a diferença entre Unit Tests (Testes de Unidade) e Integration Tests (Testes de Integração)?
Resposta:
- Unit Tests: Testam uma pequena unidade de código (geralmente um método) isoladamente. As dependências são simuladas (usando ferramentas como Moq). Rápidos e confiáveis.
- Integration Tests: Testam como diferentes partes da aplicação funcionam juntas (por exemplo, endpoint da API + Banco de Dados). Mais lentos, mas verificam o comportamento real do sistema.
Raridade: Comum Dificuldade: Fácil
16. Como você simula (Mock) dependências em Unit Tests?
Resposta: Frameworks de mocking como Moq ou NSubstitute são usados para criar implementações falsas de interfaces.
- Propósito: Isolar a classe em teste. Por exemplo, se estiver testando um
UserService, você simula oIUserRepositorypara não atingir o banco de dados real. - Exemplo (Moq):
Raridade: Comum Dificuldade: Média
17. O que são os princípios SOLID? Dê um exemplo de um deles.
Resposta: SOLID é um acrônimo para 5 princípios de design para tornar o software mais compreensível, flexível e fácil de manter.
- Single Responsibility Principle (Princípio da Responsabilidade Única) (SRP)
- Open/Closed Principle (Princípio Aberto/Fechado) (OCP)
- Liskov Substitution Principle (Princípio da Substituição de Liskov) (LSP)
- Interface Segregation Principle (Princípio da Segregação da Interface) (ISP)
- Dependency Inversion Principle (Princípio da Inversão de Dependência) (DIP)
- Exemplo (DIP): Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações. Esta é a base para a Injeção de Dependência.
Raridade: Comum Dificuldade: Difícil
18. O que é Boxing e Unboxing? Por que evitar isso?
Resposta:
- Boxing: Converter um tipo de valor (como
int) para um tipo de referência (object). Ele aloca memória no heap. - Unboxing: Converter o tipo de referência de volta para o tipo de valor.
- Performance: Ambas são operações caras (alocação de memória, verificação de tipo). Generics (
List<T>) ajudam a evitar boxing/unboxing em comparação com coleções mais antigas (ArrayList).
Raridade: Comum Dificuldade: Média
19. O que é a instrução using em C#?
Resposta:
A instrução using fornece uma sintaxe conveniente que garante o uso correto de objetos IDisposable.
- Mecanismo: Ele chama automaticamente o método
Dispose()no objeto quando o bloco é encerrado (mesmo que ocorra uma exceção). - Sintaxe Moderna:
using var file = File.OpenRead("path");(sem chaves necessárias, descartado no final do escopo).
Raridade: Comum Dificuldade: Fácil
20. Explique o conceito de Middleware no contexto do padrão "Chain of Responsibility" (Cadeia de Responsabilidade).
Resposta: O Middleware do ASP.NET Core é uma implementação clássica do padrão Chain of Responsibility.
- Padrão: Uma requisição é passada ao longo de uma cadeia de handlers (manipuladores). Cada handler decide se processa a requisição ou a passa para o próximo handler na cadeia.
- Aplicação: Em .NET, o
RequestDelegaterepresenta o próximo handler. Os componentes de middleware são encadeados para formar o pipeline de requisição.
Raridade: Incomum Dificuldade: Difícil


